- add libbb function str_tolower to convert a string to lowercase.
[oweals/busybox.git] / miscutils / strings.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * strings implementation for busybox
4  *
5  * Copyright Tito Ragusa <farmatito@tiscali.it>
6  *
7  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
8  */
9
10 #include "busybox.h"
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <getopt.h>
14 #include <ctype.h>
15
16 #define WHOLE_FILE              1
17 #define PRINT_NAME              2
18 #define PRINT_OFFSET    4
19 #define SIZE                    8
20
21 int strings_main(int argc, char **argv);
22 int strings_main(int argc, char **argv)
23 {
24         int n, c, i = 0, status = EXIT_SUCCESS;
25         unsigned opt;
26         unsigned long count;
27         FILE *file = stdin;
28         char *string;
29         const char *fmt = "%s: ";
30         const char *n_arg = "4";
31
32         opt = getopt32(argc, argv, "afon:", &n_arg);
33         /* -a is our default behaviour */
34
35         argc -= optind;
36         argv += optind;
37
38         n = xatoul_range(n_arg, 1, INT_MAX);
39         string = xzalloc(n + 1);
40         n--;
41
42         if (argc == 0) {
43                 fmt = "{%s}: ";
44                 *argv = (char *)bb_msg_standard_input;
45                 goto PIPE;
46         }
47
48         do {
49                 file = fopen_or_warn(*argv, "r");
50                 if (file) {
51 PIPE:
52                         count = 0;
53                         do {
54                                 c = fgetc(file);
55                                 if (isprint(c) || c == '\t') {
56                                         if (i <= n) {
57                                                 string[i] = c;
58                                         } else {
59                                                 putchar(c);
60                                         }
61                                         if (i == n) {
62                                                 if (opt & PRINT_NAME) {
63                                                         printf(fmt, *argv);
64                                                 }
65                                                 if (opt & PRINT_OFFSET) {
66                                                         printf("%7lo ", count - n);
67                                                 }
68                                                 printf("%s", string);
69                                         }
70                                         i++;
71                                 } else {
72                                         if (i > n) {
73                                                 putchar('\n');
74                                         }
75                                         i = 0;
76                                 }
77                                 count++;
78                         } while (c != EOF);
79                         fclose_if_not_stdin(file);
80                 } else {
81                         status = EXIT_FAILURE;
82                 }
83         } while (--argc > 0);
84
85         if (ENABLE_FEATURE_CLEAN_UP)
86                 free(string);
87
88         fflush_stdout_and_exit(status);
89 }