less: optionally query terminal size via "ESC [ 6 n". Closes bug 2659.
[platform/upstream/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
10 //usage:#define strings_trivial_usage
11 //usage:       "[-afo] [-n LEN] [FILE]..."
12 //usage:#define strings_full_usage "\n\n"
13 //usage:       "Display printable strings in a binary file\n"
14 //usage:     "\n        -a      Scan whole file (default)"
15 //usage:     "\n        -f      Precede strings with filenames"
16 //usage:     "\n        -n LEN  At least LEN characters form a string (default 4)"
17 //usage:     "\n        -o      Precede strings with decimal offsets"
18
19 #include "libbb.h"
20
21 #define WHOLE_FILE    1
22 #define PRINT_NAME    2
23 #define PRINT_OFFSET  4
24 #define SIZE          8
25
26 int strings_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
27 int strings_main(int argc UNUSED_PARAM, char **argv)
28 {
29         int n, c, status = EXIT_SUCCESS;
30         unsigned count;
31         off_t offset;
32         FILE *file;
33         char *string;
34         const char *fmt = "%s: ";
35         const char *n_arg = "4";
36
37         getopt32(argv, "afon:", &n_arg);
38         /* -a is our default behaviour */
39         /*argc -= optind;*/
40         argv += optind;
41
42         n = xatou_range(n_arg, 1, INT_MAX);
43         string = xzalloc(n + 1);
44         n--;
45
46         if (!*argv) {
47                 fmt = "{%s}: ";
48                 *--argv = (char *)bb_msg_standard_input;
49         }
50
51         do {
52                 file = fopen_or_warn_stdin(*argv);
53                 if (!file) {
54                         status = EXIT_FAILURE;
55                         continue;
56                 }
57                 offset = 0;
58                 count = 0;
59                 do {
60                         c = fgetc(file);
61                         if (isprint_asciionly(c) || c == '\t') {
62                                 if (count > n) {
63                                         bb_putchar(c);
64                                 } else {
65                                         string[count] = c;
66                                         if (count == n) {
67                                                 if (option_mask32 & PRINT_NAME) {
68                                                         printf(fmt, *argv);
69                                                 }
70                                                 if (option_mask32 & PRINT_OFFSET) {
71                                                         printf("%7"OFF_FMT"o ", offset - n);
72                                                 }
73                                                 fputs(string, stdout);
74                                         }
75                                         count++;
76                                 }
77                         } else {
78                                 if (count > n) {
79                                         bb_putchar('\n');
80                                 }
81                                 count = 0;
82                         }
83                         offset++;
84                 } while (c != EOF);
85                 fclose_if_not_stdin(file);
86         } while (*++argv);
87
88         if (ENABLE_FEATURE_CLEAN_UP)
89                 free(string);
90
91         fflush_stdout_and_exit(status);
92 }