12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- /*strings.c - print the strings of printable characters in files.
- *
- * Copyright 2014 Kyung-su Kim <kaspyx@gmail.com>
- * Copyright 2014 Kyungwan Han <asura321@gmail.com>
- *
- * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/strings.html
- *
- * Deviations from posix: we don't readahead to the end of the string to see
- * if it ends with NUL or newline before printing. Add -o. We always do -a
- * (and accept but don't document the flag), but that's sort of conformant.
- * Posix' STDOUT section says things like "%o %s" and we support 64 bit offsets.
- *
- * TODO: utf8 strings
- USE_STRINGS(NEWTOY(strings, "t:an#=4<1fo", TOYFLAG_USR|TOYFLAG_BIN))
- config STRINGS
- bool "strings"
- default y
- help
- usage: strings [-fo] [-t oxd] [-n LEN] [FILE...]
- Display printable strings in a binary file
- -f Show filename
- -n At least LEN characters form a string (default 4)
- -o Show offset (ala -t d)
- -t Show offset type (o=octal, d=decimal, x=hexadecimal)
- */
- #define FOR_strings
- #include "toys.h"
- GLOBALS(
- long n;
- char *t;
- )
- static void do_strings(int fd, char *filename)
- {
- int nread, i, wlen = TT.n, count = 0;
- off_t offset = 0;
- char *string = 0, pattern[8];
- if (TT.t) if (!(string = strchr("oxd", *TT.t))) error_exit("-t needs oxd");
- sprintf(pattern, "%%7ll%c ", string ? *string : 'd');
- // input buffer can wrap before we have enough data to output, so
- // copy start of string to temporary buffer until enough to output
- string = xzalloc(wlen+1);
- for (i = nread = 0; ;i++) {
- if (i >= nread) {
- nread = read(fd, toybuf, sizeof(toybuf));
- i = 0;
- if (nread < 0) perror_msg_raw(filename);
- if (nread < 1) {
- if (count) goto flush;
- break;
- }
- }
- offset++;
- if ((toybuf[i]>=32 && toybuf[i]<=126) || toybuf[i]=='\t') {
- if (count == wlen) fputc(toybuf[i], stdout);
- else {
- string[count++] = toybuf[i];
- if (count == wlen) {
- if (FLAG(f)) printf("%s: ", filename);
- if (FLAG(o) || FLAG(t)) printf(pattern, (long long)(offset - wlen));
- printf("%s", string);
- }
- }
- continue;
- }
- flush:
- // End of previous string
- if (count == wlen) xputc('\n');
- count = 0;
- }
- xclose(fd);
- free(string);
- }
- void strings_main(void)
- {
- loopfiles(toys.optargs, do_strings);
- }
|