1 /*strings.c - print the strings of printable characters in files. 2 * 3 * Copyright 2014 Kyung-su Kim <kaspyx (at) gmail.com> 4 * Copyright 2014 Kyungwan Han <asura321 (at) 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 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 86 void strings_main(void) 87 { 88 loopfiles(toys.optargs, do_strings); 89 } 90