1/* vi: set sw=4 ts=4: */
2/*
3 * strings implementation for busybox
4 *
5 * Copyright Tito Ragusa <farmatito@tiscali.it>
6 *
7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
8 */
9
10#include <getopt.h>
11
12#include "libbb.h"
13
14#define WHOLE_FILE		1
15#define PRINT_NAME		2
16#define PRINT_OFFSET	4
17#define SIZE			8
18
19int strings_main(int argc, char **argv);
20int strings_main(int argc, char **argv)
21{
22	int n, c, status = EXIT_SUCCESS;
23	unsigned opt;
24	unsigned count;
25	off_t offset;
26	FILE *file = stdin;
27	char *string;
28	const char *fmt = "%s: ";
29	const char *n_arg = "4";
30
31	opt = getopt32(argv, "afon:", &n_arg);
32	/* -a is our default behaviour */
33	/*argc -= optind;*/
34	argv += optind;
35
36	n = xatou_range(n_arg, 1, INT_MAX);
37	string = xzalloc(n + 1);
38	n--;
39
40	if (!*argv) {
41		fmt = "{%s}: ";
42		*--argv = (char *)bb_msg_standard_input;
43		goto PIPE;
44	}
45
46	do {
47		file = fopen_or_warn(*argv, "r");
48		if (!file) {
49			status = EXIT_FAILURE;
50			continue;
51		}
52 PIPE:
53		offset = 0;
54		count = 0;
55		do {
56			c = fgetc(file);
57			if (isprint(c) || c == '\t') {
58				if (count > n) {
59					putchar(c);
60				} else {
61					string[count] = c;
62					if (count == n) {
63						if (opt & PRINT_NAME) {
64							printf(fmt, *argv);
65						}
66						if (opt & PRINT_OFFSET) {
67							printf("%7"OFF_FMT"o ", offset - n);
68						}
69						fputs(string, stdout);
70					}
71					count++;
72				}
73			} else {
74				if (count > n) {
75					putchar('\n');
76				}
77				count = 0;
78			}
79			offset++;
80		} while (c != EOF);
81		fclose_if_not_stdin(file);
82	} while (*++argv);
83
84	if (ENABLE_FEATURE_CLEAN_UP)
85		free(string);
86
87	fflush_stdout_and_exit(status);
88}
89