toybox/toys/posix/strings.c
<<
>>
Prefs
   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
  15USE_STRINGS(NEWTOY(strings, "t:an#=4<1fo", TOYFLAG_USR|TOYFLAG_BIN))
  16
  17config 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
  34GLOBALS(
  35  long num;
  36  char *t;
  37)
  38
  39static 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    }
  77flush:
  78    // End of previous string
  79    if (count == wlen) xputc('\n');
  80    count = 0;
  81  }
  82  xclose(fd);
  83  free(string);
  84}
  85
  86void strings_main(void)
  87{
  88  loopfiles(toys.optargs, do_strings);
  89}
  90