• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*strings.c - print the strings of printable characters in files.
2  *
3  * Copyright 2014 Kyung-su Kim <kaspyx@gmail.com>
4  * Copyright 2014 Kyungwan Han <asura321@gmail.com>
5  *
6  * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/strings.html
7  *
8  * Deviations from posix: we don't readahead to the end of the string to see
9  * if it ends with NUL or newline before printing. Add -o. We always do -a
10  * (and accept but don't document the flag), but that's sort of conformant.
11  * Posix' STDOUT section says things like "%o %s" and we support 64 bit offsets.
12  *
13  * TODO: utf8 strings
14 
15 USE_STRINGS(NEWTOY(strings, "t:an#=4<1fo", TOYFLAG_USR|TOYFLAG_BIN))
16 
17 config STRINGS
18   bool "strings"
19   default y
20   help
21     usage: strings [-fo] [-t oxd] [-n LEN] [FILE...]
22 
23     Display printable strings in a binary file
24 
25     -f	Show filename
26     -n	At least LEN characters form a string (default 4)
27     -o	Show offset (ala -t d)
28     -t	Show offset type (o=octal, d=decimal, x=hexadecimal)
29 */
30 
31 #define FOR_strings
32 #include "toys.h"
33 
GLOBALS(long num;char * t;)34 GLOBALS(
35   long num;
36   char *t;
37 )
38 
39 static void do_strings(int fd, char *filename)
40 {
41   int nread, i, wlen = TT.num, count = 0;
42   off_t offset = 0;
43   char *string = 0, pattern[8];
44 
45   if (TT.t) if (!(string = strchr("oxd", *TT.t))) error_exit("-t needs oxd");
46   sprintf(pattern, "%%7ll%c ", string ? *string : 'd');
47 
48   // input buffer can wrap before we have enough data to output, so
49   // copy start of string to temporary buffer until enough to output
50   string = xzalloc(wlen+1);
51 
52   for (i = nread = 0; ;i++) {
53     if (i >= nread) {
54       nread = read(fd, toybuf, sizeof(toybuf));
55       i = 0;
56       if (nread < 0) perror_msg_raw(filename);
57       if (nread < 1) {
58         if (count) goto flush;
59         break;
60       }
61     }
62 
63     offset++;
64     if ((toybuf[i]>=32 && toybuf[i]<=126) || toybuf[i]=='\t') {
65       if (count == wlen) fputc(toybuf[i], stdout);
66       else {
67         string[count++] = toybuf[i];
68         if (count == wlen) {
69           if (toys.optflags & FLAG_f) printf("%s: ", filename);
70           if (toys.optflags & (FLAG_o|FLAG_t))
71             printf(pattern, (long long)(offset - wlen));
72           printf("%s", string);
73         }
74       }
75       continue;
76     }
77 flush:
78     // End of previous string
79     if (count == wlen) xputc('\n');
80     count = 0;
81   }
82   xclose(fd);
83   free(string);
84 }
85 
strings_main(void)86 void strings_main(void)
87 {
88   loopfiles(toys.optargs, do_strings);
89 }
90