commit 0ed2a550037fdd96af7756639cf3210a20deb852
parent cd592c9f23ba822f506775c3bbd8d2185a089161
Author: sin <sin@2f30.org>
Date: Wed, 14 Aug 2013 10:41:55 +0100
Add strings(1)
Diffstat:
3 files changed, 67 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -70,6 +70,7 @@ SRC = \
sort.c \
split.c \
sponge.c \
+ strings.c \
sync.c \
tail.c \
tar.c \
diff --git a/strings.1 b/strings.1
@@ -0,0 +1,10 @@
+.TH STRINGS 1 sbase\-VERSION
+.SH NAME
+strings \- print the strings of printable characters in files
+.SH SYNOPSIS
+.B strings
+.IR [file...]
+.SH DESCRIPTION
+.B strings
+prints the printable character sequences that are at least 6 characters
+long. If no files are given then it uses stdin.
diff --git a/strings.c b/strings.c
@@ -0,0 +1,56 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "util.h"
+
+static void dostrings(FILE *fp, const char *fname);
+
+static void
+usage(void)
+{
+ eprintf("usage: %s file\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ FILE *fp;
+
+ ARGBEGIN {
+ default:
+ usage();
+ } ARGEND;
+
+ if (argc > 0) {
+ if (!(fp = fopen(argv[0], "r")))
+ eprintf("open %s:", argv[0]);
+ dostrings(fp, argv[0]);
+ fclose(fp);
+ } else {
+ dostrings(stdin, "<stdin>");
+ }
+
+ return 0;
+}
+
+static void
+dostrings(FILE *fp, const char *fname)
+{
+ unsigned char buf[BUFSIZ];
+ int c, i = 0;
+ off_t offset = 0;
+
+ do {
+ offset++;
+ if (isprint(c = getc(fp)))
+ buf[i++] = c;
+ if ((!isprint(c) && i >= 6) || i == sizeof(buf) - 1) {
+ buf[i] = '\0';
+ printf("%8ld: %s\n", (long)offset - i - 1, buf);
+ i = 0;
+ }
+ } while (c != EOF);
+ if (ferror(fp))
+ eprintf("%s: read error:", fname);
+}