10f66f451Sopenharmony_ci/*strings.c - print the strings of printable characters in files. 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2014 Kyung-su Kim <kaspyx@gmail.com> 40f66f451Sopenharmony_ci * Copyright 2014 Kyungwan Han <asura321@gmail.com> 50f66f451Sopenharmony_ci * 60f66f451Sopenharmony_ci * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/strings.html 70f66f451Sopenharmony_ci * 80f66f451Sopenharmony_ci * Deviations from posix: we don't readahead to the end of the string to see 90f66f451Sopenharmony_ci * if it ends with NUL or newline before printing. Add -o. We always do -a 100f66f451Sopenharmony_ci * (and accept but don't document the flag), but that's sort of conformant. 110f66f451Sopenharmony_ci * Posix' STDOUT section says things like "%o %s" and we support 64 bit offsets. 120f66f451Sopenharmony_ci * 130f66f451Sopenharmony_ci * TODO: utf8 strings 140f66f451Sopenharmony_ci 150f66f451Sopenharmony_ciUSE_STRINGS(NEWTOY(strings, "t:an#=4<1fo", TOYFLAG_USR|TOYFLAG_BIN)) 160f66f451Sopenharmony_ci 170f66f451Sopenharmony_ciconfig STRINGS 180f66f451Sopenharmony_ci bool "strings" 190f66f451Sopenharmony_ci default y 200f66f451Sopenharmony_ci help 210f66f451Sopenharmony_ci usage: strings [-fo] [-t oxd] [-n LEN] [FILE...] 220f66f451Sopenharmony_ci 230f66f451Sopenharmony_ci Display printable strings in a binary file 240f66f451Sopenharmony_ci 250f66f451Sopenharmony_ci -f Show filename 260f66f451Sopenharmony_ci -n At least LEN characters form a string (default 4) 270f66f451Sopenharmony_ci -o Show offset (ala -t d) 280f66f451Sopenharmony_ci -t Show offset type (o=octal, d=decimal, x=hexadecimal) 290f66f451Sopenharmony_ci*/ 300f66f451Sopenharmony_ci 310f66f451Sopenharmony_ci#define FOR_strings 320f66f451Sopenharmony_ci#include "toys.h" 330f66f451Sopenharmony_ci 340f66f451Sopenharmony_ciGLOBALS( 350f66f451Sopenharmony_ci long n; 360f66f451Sopenharmony_ci char *t; 370f66f451Sopenharmony_ci) 380f66f451Sopenharmony_ci 390f66f451Sopenharmony_cistatic void do_strings(int fd, char *filename) 400f66f451Sopenharmony_ci{ 410f66f451Sopenharmony_ci int nread, i, wlen = TT.n, count = 0; 420f66f451Sopenharmony_ci off_t offset = 0; 430f66f451Sopenharmony_ci char *string = 0, pattern[8]; 440f66f451Sopenharmony_ci 450f66f451Sopenharmony_ci if (TT.t) if (!(string = strchr("oxd", *TT.t))) error_exit("-t needs oxd"); 460f66f451Sopenharmony_ci sprintf(pattern, "%%7ll%c ", string ? *string : 'd'); 470f66f451Sopenharmony_ci 480f66f451Sopenharmony_ci // input buffer can wrap before we have enough data to output, so 490f66f451Sopenharmony_ci // copy start of string to temporary buffer until enough to output 500f66f451Sopenharmony_ci string = xzalloc(wlen+1); 510f66f451Sopenharmony_ci 520f66f451Sopenharmony_ci for (i = nread = 0; ;i++) { 530f66f451Sopenharmony_ci if (i >= nread) { 540f66f451Sopenharmony_ci nread = read(fd, toybuf, sizeof(toybuf)); 550f66f451Sopenharmony_ci i = 0; 560f66f451Sopenharmony_ci if (nread < 0) perror_msg_raw(filename); 570f66f451Sopenharmony_ci if (nread < 1) { 580f66f451Sopenharmony_ci if (count) goto flush; 590f66f451Sopenharmony_ci break; 600f66f451Sopenharmony_ci } 610f66f451Sopenharmony_ci } 620f66f451Sopenharmony_ci 630f66f451Sopenharmony_ci offset++; 640f66f451Sopenharmony_ci if ((toybuf[i]>=32 && toybuf[i]<=126) || toybuf[i]=='\t') { 650f66f451Sopenharmony_ci if (count == wlen) fputc(toybuf[i], stdout); 660f66f451Sopenharmony_ci else { 670f66f451Sopenharmony_ci string[count++] = toybuf[i]; 680f66f451Sopenharmony_ci if (count == wlen) { 690f66f451Sopenharmony_ci if (FLAG(f)) printf("%s: ", filename); 700f66f451Sopenharmony_ci if (FLAG(o) || FLAG(t)) printf(pattern, (long long)(offset - wlen)); 710f66f451Sopenharmony_ci printf("%s", string); 720f66f451Sopenharmony_ci } 730f66f451Sopenharmony_ci } 740f66f451Sopenharmony_ci continue; 750f66f451Sopenharmony_ci } 760f66f451Sopenharmony_ciflush: 770f66f451Sopenharmony_ci // End of previous string 780f66f451Sopenharmony_ci if (count == wlen) xputc('\n'); 790f66f451Sopenharmony_ci count = 0; 800f66f451Sopenharmony_ci } 810f66f451Sopenharmony_ci free(string); 820f66f451Sopenharmony_ci} 830f66f451Sopenharmony_ci 840f66f451Sopenharmony_civoid strings_main(void) 850f66f451Sopenharmony_ci{ 860f66f451Sopenharmony_ci loopfiles(toys.optargs, do_strings); 870f66f451Sopenharmony_ci} 88