summaryrefslogtreecommitdiff
path: root/miscutils/strings.c (plain)
blob: edd0e667d4dec02c0ab5ff6e07ed23455f4cd56f
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"
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 c, status = EXIT_SUCCESS;
44 unsigned n, 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(string, stdout);
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