busybox/miscutils/strings.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * strings implementation for busybox
   4 *
   5 * Copyright 2003 Tito Ragusa <farmatito@tiscali.it>
   6 *
   7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   8 */
   9//config:config STRINGS
  10//config:       bool "strings (4.6 kb)"
  11//config:       default y
  12//config:       help
  13//config:       strings prints the printable character sequences for each file
  14//config:       specified.
  15
  16//applet:IF_STRINGS(APPLET(strings, BB_DIR_USR_BIN, BB_SUID_DROP))
  17
  18//kbuild:lib-$(CONFIG_STRINGS) += strings.o
  19
  20//usage:#define strings_trivial_usage
  21//usage:       "[-fo] [-t o|d|x] [-n LEN] [FILE]..."
  22//usage:#define strings_full_usage "\n\n"
  23//usage:       "Display printable strings in a binary file\n"
  24//We usually don't bother user with "nop" options. They work, but are not shown:
  25////usage:     "\n      -a              Scan whole file (default)"
  26//unimplemented alternative is -d: Only strings from initialized, loaded data sections
  27//usage:     "\n        -f              Precede strings with filenames"
  28//usage:     "\n        -o              Precede strings with octal offsets"
  29//usage:     "\n        -t o|d|x        Precede strings with offsets in base 8/10/16"
  30//usage:     "\n        -n LEN          At least LEN characters form a string (default 4)"
  31
  32#include "libbb.h"
  33
  34#define WHOLE_FILE    1
  35#define PRINT_NAME    2
  36#define PRINT_OFFSET  4
  37#define SIZE          8
  38#define PRINT_RADIX  16
  39
  40int strings_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  41int strings_main(int argc UNUSED_PARAM, char **argv)
  42{
  43        int n, c, status = EXIT_SUCCESS;
  44        unsigned count;
  45        off_t offset;
  46        FILE *file;
  47        char *string;
  48        const char *fmt = "%s: ";
  49        const char *n_arg = "4";
  50        /* default for -o */
  51        const char *radix = "o";
  52        char *radix_fmt;
  53
  54        getopt32(argv, "afon:t:", &n_arg, &radix);
  55        /* -a is our default behaviour */
  56        /*argc -= optind;*/
  57        argv += optind;
  58
  59        n = xatou_range(n_arg, 1, INT_MAX);
  60        string = xzalloc(n + 1);
  61        n--;
  62
  63        if ((radix[0] != 'd' && radix[0] != 'o' && radix[0] != 'x') || radix[1] != 0)
  64                bb_show_usage();
  65
  66        radix_fmt = xasprintf("%%7"OFF_FMT"%s ", radix);
  67
  68        if (!*argv) {
  69                fmt = "{%s}: ";
  70                *--argv = (char *)bb_msg_standard_input;
  71        }
  72
  73        do {
  74                file = fopen_or_warn_stdin(*argv);
  75                if (!file) {
  76                        status = EXIT_FAILURE;
  77                        continue;
  78                }
  79                offset = 0;
  80                count = 0;
  81                do {
  82                        c = fgetc(file);
  83                        if (isprint_asciionly(c) || c == '\t') {
  84                                if (count > n) {
  85                                        bb_putchar(c);
  86                                } else {
  87                                        string[count] = c;
  88                                        if (count == n) {
  89                                                if (option_mask32 & PRINT_NAME) {
  90                                                        printf(fmt, *argv);
  91                                                }
  92                                                if (option_mask32 & (PRINT_OFFSET | PRINT_RADIX)) {
  93                                                        printf(radix_fmt, offset - n);
  94                                                }
  95                                                fputs_stdout(string);
  96                                        }
  97                                        count++;
  98                                }
  99                        } else {
 100                                if (count > n) {
 101                                        bb_putchar('\n');
 102                                }
 103                                count = 0;
 104                        }
 105                        offset++;
 106                } while (c != EOF);
 107                fclose_if_not_stdin(file);
 108        } while (*++argv);
 109
 110        if (ENABLE_FEATURE_CLEAN_UP) {
 111                free(string);
 112                free(radix_fmt);
 113        }
 114
 115        fflush_stdout_and_exit(status);
 116}
 117