Added CONFIG_CLEAR and CONFIG_RESET to config.maemo
[busybox4maemo] / coreutils / head.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * head implementation for busybox
4  *
5  * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
6  *
7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8  */
9
10 /* BB_AUDIT SUSv3 compliant */
11 /* BB_AUDIT GNU compatible -c, -q, and -v options in 'fancy' configuration. */
12 /* http://www.opengroup.org/onlinepubs/007904975/utilities/head.html */
13
14 #include "libbb.h"
15
16 static const char head_opts[] ALIGN1 =
17         "n:"
18 #if ENABLE_FEATURE_FANCY_HEAD
19         "c:qv"
20 #endif
21         ;
22
23 #if ENABLE_FEATURE_FANCY_HEAD
24 static const struct suffix_mult head_suffixes[] = {
25         { "b", 512 },
26         { "k", 1024 },
27         { "m", 1024*1024 },
28         { }
29 };
30 #endif
31
32 static const char header_fmt_str[] ALIGN1 = "\n==> %s <==\n";
33
34 int head_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
35 int head_main(int argc, char **argv)
36 {
37         unsigned long count = 10;
38         unsigned long i;
39 #if ENABLE_FEATURE_FANCY_HEAD
40         int count_bytes = 0;
41         int header_threshhold = 1;
42 #endif
43
44         FILE *fp;
45         const char *fmt;
46         char *p;
47         int opt;
48         int c;
49         int retval = EXIT_SUCCESS;
50
51 #if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_HEAD
52         /* Allow legacy syntax of an initial numeric option without -n. */
53         if (argc > 1 && argv[1][0] == '-'
54          && isdigit(argv[1][1])
55         ) {
56                 --argc;
57                 ++argv;
58                 p = (*argv) + 1;
59                 goto GET_COUNT;
60         }
61 #endif
62
63         /* No size benefit in converting this to getopt32 */
64         while ((opt = getopt(argc, argv, head_opts)) > 0) {
65                 switch (opt) {
66 #if ENABLE_FEATURE_FANCY_HEAD
67                 case 'q':
68                         header_threshhold = INT_MAX;
69                         break;
70                 case 'v':
71                         header_threshhold = -1;
72                         break;
73                 case 'c':
74                         count_bytes = 1;
75                         /* fall through */
76 #endif
77                 case 'n':
78                         p = optarg;
79 #if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_HEAD
80  GET_COUNT:
81 #endif
82
83 #if !ENABLE_FEATURE_FANCY_HEAD
84                         count = xatoul(p);
85 #else
86                         count = xatoul_sfx(p, head_suffixes);
87 #endif
88                         break;
89                 default:
90                         bb_show_usage();
91                 }
92         }
93
94         argc -= optind;
95         argv += optind;
96         if (!*argv)
97                 *--argv = (char*)"-";
98
99         fmt = header_fmt_str + 1;
100 #if ENABLE_FEATURE_FANCY_HEAD
101         if (argc <= header_threshhold) {
102                 header_threshhold = 0;
103         }
104 #else
105         if (argc <= 1) {
106                 fmt += 11; /* "" */
107         }
108         /* Now define some things here to avoid #ifdefs in the code below.
109          * These should optimize out of the if conditions below. */
110 #define header_threshhold   1
111 #define count_bytes         0
112 #endif
113
114         do {
115                 fp = fopen_or_warn_stdin(*argv);
116                 if (fp) {
117                         if (fp == stdin) {
118                                 *argv = (char *) bb_msg_standard_input;
119                         }
120                         if (header_threshhold) {
121                                 printf(fmt, *argv);
122                         }
123                         i = count;
124                         while (i && ((c = getc(fp)) != EOF)) {
125                                 if (count_bytes || (c == '\n')) {
126                                         --i;
127                                 }
128                                 putchar(c);
129                         }
130                         if (fclose_if_not_stdin(fp)) {
131                                 bb_simple_perror_msg(*argv);    /* Avoid multibyte problems. */
132                                 retval = EXIT_FAILURE;
133                         }
134                         die_if_ferror_stdout();
135                 }
136                 fmt = header_fmt_str;
137         } while (*++argv);
138
139         fflush_stdout_and_exit(retval);
140 }