about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--README1
-rw-r--r--magrep.c116
-rw-r--r--man/mblaze.72
4 files changed, 121 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 1b7e012..f2ed500 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,11 @@
 CFLAGS=-g -O2 -Wall -Wno-switch -Wextra -fstack-protector-strong -D_FORTIFY_SOURCE=2
 
-ALL = maddr mdeliver mdirs mflag mgenmid mhdr minc mlist mmime mpick mscan msed mseq mshow msort mthread
+ALL = maddr magrep mdeliver mdirs mflag mgenmid mhdr minc mlist mmime mpick mscan msed mseq mshow msort mthread
 
 all: $(ALL)
 
 maddr: maddr.o blaze822.o seq.o rfc2047.o mymemmem.o
+magrep: magrep.o blaze822.o seq.o rfc2047.o mymemmem.o
 mdeliver: mdeliver.o blaze822.o mymemmem.o
 mdirs: mdirs.o
 mflag: mflag.o blaze822.o seq.o mymemmem.o
diff --git a/README b/README
index 412ef2d..364a694 100644
--- a/README
+++ b/README
@@ -12,6 +12,7 @@ DESCRIPTION
 
      mblaze consists of a set of Unix tools that each do one job:
      maddr(1)     to extract addresses from mail
+     magrep(1)    to find mails matching a pattern
      mcomp(1)     to write and send mail
      mdeliver(1)  to deliver messages or import mailboxes
      mdirs(1)     to find Maildirs
diff --git a/magrep.c b/magrep.c
new file mode 100644
index 0000000..7b6a7a4
--- /dev/null
+++ b/magrep.c
@@ -0,0 +1,116 @@
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "blaze822.h"
+
+static int aflag;
+static int cflag;
+static int dflag;
+static int iflag;
+static int qflag;
+static int vflag;
+static long matches;
+
+static regex_t pattern;
+static char *header;
+
+int
+match(char *file, char *s)
+{
+	if (vflag ^ (regexec(&pattern, s, 0, 0, 0) == 0)) {
+		if (qflag)
+			exit(0);
+		if (!cflag)
+			printf("%s\n", file);
+		matches++;
+		return 1;
+	}
+
+	return 0;
+}
+
+void
+magrep(char *file)
+{
+	char *filename = file;
+	while (*filename == ' ' || *filename == '\t')
+                filename++;
+
+	struct message *msg = blaze822(filename);
+	if (!msg)
+		return;
+
+	char *v = blaze822_chdr(msg, header);
+	if (v) {
+		if (dflag) {
+			char d[4096];
+			blaze822_decode_rfc2047(d, v, sizeof d, "UTF-8");
+			match(file, d);
+		} else if (aflag) {
+			char *disp, *addr;
+                        while ((v = blaze822_addr(v, &disp, &addr))) {
+				if (addr && match(file, addr))
+					break;
+			}
+		} else {
+			match(file, v);
+		}
+	}
+
+	blaze822_free(msg);
+}
+
+int
+main(int argc, char *argv[])
+{
+	int c;
+	while ((c = getopt(argc, argv, "acdiqv")) != -1)
+		switch(c) {
+                case 'a': aflag = 1; break;
+                case 'c': cflag = 1; break;
+                case 'd': dflag = 1; break;
+                case 'i': iflag = REG_ICASE; break;
+                case 'q': qflag = 1; break;
+                case 'v': vflag = 1; break;
+		default:
+		usage:
+			fprintf(stderr,
+"Usage: magrep [-c|-q] [-v] [-i] [-a|-d] header:regex [msgs...]\n");
+			exit(2);
+		}
+
+	if (argc == optind)
+		goto usage;
+	header = argv[optind++];
+
+	char *rx = strchr(header, ':');
+	if (!rx)
+		goto usage;
+
+	*rx++ = 0;
+	int r = regcomp(&pattern, rx, REG_EXTENDED | iflag);
+	if (r != 0) {
+		char buf[256];
+		regerror(r, &pattern, buf, sizeof buf);
+		fprintf(stderr, "magrep: regex error: %s\n", buf);
+		exit(2);
+	}
+
+	if (argc == optind && isatty(0))
+		blaze822_loop1(":", magrep);
+	else
+		blaze822_loop(argc-optind, argv+optind, magrep);
+	
+	if (cflag)
+		printf("%ld\n", matches);
+
+	return !matches;
+}
diff --git a/man/mblaze.7 b/man/mblaze.7
index 64f51d5..2f3133c 100644
--- a/man/mblaze.7
+++ b/man/mblaze.7
@@ -18,6 +18,8 @@ consists of a set of Unix tools that each do one job:
 .Bl -tag -width 11n -compact
 .It Xr maddr 1
 to extract addresses from mail
+.It Xr magrep 1
+to find mails matching a pattern
 .It Xr mcomp 1
 to write and send mail
 .It Xr mdeliver 1