ubiupdatevol: fix bug with -sSIZE: was ignoring IMAGE_FILE
[oweals/busybox.git] / miscutils / strings.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * strings implementation for busybox
4  *
5  * Copyright 2003 Tito Ragusa <farmatito@tiscali.it>
6  *
7  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8  */
9 //config:config STRINGS
10 //config:       bool "strings (4.3 kb)"
11 //config:       default y
12 //config:       help
13 //config:       strings prints the printable character sequences for each file
14 //config:       specified.
15
16 //applet:IF_STRINGS(APPLET(strings, BB_DIR_USR_BIN, BB_SUID_DROP))
17
18 //kbuild:lib-$(CONFIG_STRINGS) += strings.o
19
20 //usage:#define strings_trivial_usage
21 //usage:       "[-fo] [-t o/d/x] [-n LEN] [FILE]..."
22 //usage:#define strings_full_usage "\n\n"
23 //usage:       "Display printable strings in a binary file\n"
24 //We usually don't bother user with "nop" options. They work, but are not shown:
25 ////usage:     "\n      -a              Scan whole file (default)"
26 //unimplemented alternative is -d: Only strings from initialized, loaded data sections
27 //usage:     "\n        -f              Precede strings with filenames"
28 //usage:     "\n        -o              Precede strings with octal offsets"
29 //usage:     "\n        -t o/d/x        Precede strings with offsets in base 8/10/16"
30 //usage:     "\n        -n LEN          At least LEN characters form a string (default 4)"
31
32 #include "libbb.h"
33
34 #define WHOLE_FILE    1
35 #define PRINT_NAME    2
36 #define PRINT_OFFSET  4
37 #define SIZE          8
38 #define PRINT_RADIX  16
39
40 int strings_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
41 int strings_main(int argc UNUSED_PARAM, char **argv)
42 {
43         int n, c, status = EXIT_SUCCESS;
44         unsigned count;
45         off_t offset;
46         FILE *file;
47         char *string;
48         const char *fmt = "%s: ";
49         const char *n_arg = "4";
50         /* default for -o */
51         const char *radix = "o";
52         char *radix_fmt;
53
54         getopt32(argv, "afon:t:", &n_arg, &radix);
55         /* -a is our default behaviour */
56         /*argc -= optind;*/
57         argv += optind;
58
59         n = xatou_range(n_arg, 1, INT_MAX);
60         string = xzalloc(n + 1);
61         n--;
62
63         if ((radix[0] != 'd' && radix[0] != 'o' && radix[0] != 'x') || radix[1] != 0)
64                 bb_show_usage();
65
66         radix_fmt = xasprintf("%%7"OFF_FMT"%s ", radix);
67
68         if (!*argv) {
69                 fmt = "{%s}: ";
70                 *--argv = (char *)bb_msg_standard_input;
71         }
72
73         do {
74                 file = fopen_or_warn_stdin(*argv);
75                 if (!file) {
76                         status = EXIT_FAILURE;
77                         continue;
78                 }
79                 offset = 0;
80                 count = 0;
81                 do {
82                         c = fgetc(file);
83                         if (isprint_asciionly(c) || c == '\t') {
84                                 if (count > n) {
85                                         bb_putchar(c);
86                                 } else {
87                                         string[count] = c;
88                                         if (count == n) {
89                                                 if (option_mask32 & PRINT_NAME) {
90                                                         printf(fmt, *argv);
91                                                 }
92                                                 if (option_mask32 & (PRINT_OFFSET | PRINT_RADIX)) {
93                                                         printf(radix_fmt, offset - n);
94                                                 }
95                                                 fputs(string, stdout);
96                                         }
97                                         count++;
98                                 }
99                         } else {
100                                 if (count > n) {
101                                         bb_putchar('\n');
102                                 }
103                                 count = 0;
104                         }
105                         offset++;
106                 } while (c != EOF);
107                 fclose_if_not_stdin(file);
108         } while (*++argv);
109
110         if (ENABLE_FEATURE_CLEAN_UP) {
111                 free(string);
112                 free(radix_fmt);
113         }
114
115         fflush_stdout_and_exit(status);
116 }