Browse Source

add strings

K. Lange 2 years ago
parent
commit
9dee25e64a
1 changed files with 88 additions and 0 deletions
  1. 88 0
      apps/strings.c

+ 88 - 0
apps/strings.c

@@ -0,0 +1,88 @@
+/* vim: tabstop=4 shiftwidth=4 noexpandtab
+ * This file is part of ToaruOS and is released under the terms
+ * of the NCSA / University of Illinois License - see LICENSE.md
+ * Copyright (C) 2018 K. Lange
+ *
+ * strings - print printable character sequences found in a file
+ */
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+
+int main(int argc, char * argv[]) {
+	int opt;
+	char format = 0;
+	int min_chars = 4;
+	int ret_val = 0;
+
+	while ((opt = getopt(argc, argv, "an:t:")) != -1) {
+		switch (opt) {
+			case 'a':
+				/* TODO: With ELF support, read only the string table
+				 * by default, unless this option is specified. */
+				break;
+			case 'n':
+				min_chars = atoi(optarg);
+				break;
+			case 't':
+				format = optarg[0];
+				if (format != 'd' && format != 'x') {
+					fprintf(stderr, "%s: format '%c' is not supported\n", argv[0], format);
+					format = 0;
+				}
+				break;
+		}
+	}
+
+	for (int i = optind; i < argc; ++i) {
+		FILE * f = fopen(argv[i], "r");
+		if (!f) {
+			fprintf(stderr, "%s: %s: %s\n", argv[0], argv[i], strerror(errno));
+			ret_val = 1;
+			continue;
+		}
+
+		char buf[1024] = {0};
+		int  ind = 0;
+		size_t offset = 0;
+
+		while (!feof(f)) {
+			int c = fgetc(f);
+			if (c < 0) break;
+			if (c == '\n' || c == '\0') {
+				if (ind >= min_chars) {
+					switch (format) {
+						case 'x':
+							fprintf(stdout, "%lx ", offset - ind);
+							break;
+						case 'd':
+							fprintf(stdout, "%lu ", offset - ind);
+							break;
+						default:
+							break;
+					}
+					buf[ind] = '\0';
+					fprintf(stdout, "%s\n", buf);
+				}
+				ind = 0;
+				offset++;
+				continue;
+			}
+			if (!isprint(c)) {
+				ind = 0;
+			} else {
+				if (ind < 1024) {
+					buf[ind] = c;
+					ind++;
+				}
+			}
+			offset++;
+		}
+		fclose(f);
+	}
+
+	return ret_val;
+}