Date: Wed, 20 Sep 1995 19:37:08 +0200 From: Wolfram Schneider <wosch@cs.tu-berlin.de> To: current@freebsd.org Subject: from(1) Message-ID: <199509201737.TAA03936@caramba.cs.tu-berlin.de>
next in thread | raw e-mail | index | archive | help
Changes: - add missing includes files - minimal support for content-length - allow reading input from stdin (-f -) - Option '-c' print a count of matching lines - Option '-F' use 'From:' instead 'From' line - Option '-t' don't change access time - Option '-v' Invert the sense of matching, to select nonmatching lines. Examples: count mails in archive: $ zcat hack.gz | from -c -f - 47 count non-freebsd mails in your mailbox: $ from -cvs freebsd.org 3 mails from Berlin: $ from -F -s berlin -f mbox From: Thomas Graichen <graichen@omega.physik.fu-berlin.de> From: Thomas Graichen <graichen@omega.physik.fu-berlin.de> From: Wolfram Schneider <wosch@cs.tu-berlin.de> From: Wolfram Schneider <wosch@cs.tu-berlin.de> From: Wolfram Schneider <wosch@cs.tu-berlin.de> From: Wolfram Schneider <wosch@cs.tu-berlin.de> --- /usr/src/usr.bin/from/from.c Fri May 27 14:31:22 1994 +++ from.c Wed Sep 20 17:03:44 1995 @@ -42,41 +42,90 @@ #endif /* not lint */ #include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> #include <ctype.h> #include <pwd.h> #include <stdio.h> #include <paths.h> +#include <string.h> +#include <stdlib.h> -main(argc, argv) +#define CLEN "content-length:" +#define FROM "From:" + +int f_from = 0; /* use `From:' field instead 'From' */ +int f_count = 0; /* don't print from lines, print count only */ +int f_invert = 0; /* invert searching */ +int f_atime = 0; /* modify access time */ +int counter = 0; + +int match __P((char *line, char *sender)); +int match2 __P((char *line, char *sender)); +void print_from __P((char *buf)); + + +void main(argc, argv) int argc; char **argv; { extern char *optarg; extern int optind; + struct passwd *pwd; - int ch, newline; + struct stat sb; + struct timeval tv[2]; + + int ch, newline, header, body; char *file, *sender, *p; #if MAXPATHLEN > BUFSIZ char buf[MAXPATHLEN]; + char buf2[MAXPATHLEN]; #else char buf[BUFSIZ]; + char buf2[BUFSIZ]; #endif file = sender = NULL; - while ((ch = getopt(argc, argv, "f:s:")) != EOF) + + while ((ch = getopt(argc, argv, "?Fcf:s:tv")) != EOF) switch((char)ch) { + + /* use `From:' field instead 'From' */ + case 'F': + f_from = 1; + break; + + /* don't print from lines, print count only */ + case 'c': + f_count = 1; + break; + + /* use file as mailbox */ case 'f': file = optarg; break; + + /* use only mails from sender */ case 's': sender = optarg; for (p = sender; *p; ++p) if (isupper(*p)) *p = tolower(*p); break; + + /* don't modify access time */ + case 't': + f_atime = 1; + break; + + case 'v': + f_invert = 1; + break; + case '?': default: - fprintf(stderr, "usage: from [-f file] [-s sender] [user]\n"); + fprintf(stderr, "usage: from [-Fctv] [-f file] [-s sender] [user]\n"); exit(1); } argv += optind; @@ -90,34 +139,104 @@ } file = pwd->pw_name; } - (void)sprintf(buf, "%s/%s", _PATH_MAILDIR, file); - file = buf; + (void)sprintf(buf2, "%s/%s", _PATH_MAILDIR, file); + file = buf2; } - if (!freopen(file, "r", stdin)) { + + /* stdin */ + if (!strcmp(file, "-")) { + f_atime = 0; /* don't stat stdin */ + } + + /* redirect file to stdin */ + else if (!freopen(file, "r", stdin)) { fprintf(stderr, "from: can't read %s.\n", file); exit(1); + } + + /* save atime */ + else if (f_atime) { + if (stat(file, &sb) < 0) { + perror("stat"); + exit(1); + } + tv[0].tv_sec = sb.st_atime; + tv[0].tv_usec = sb.st_atime * 1000; + tv[1].tv_sec = sb.st_mtime; + tv[1].tv_usec = sb.st_mtime * 1000; } + + header = body = 0; for (newline = 1; fgets(buf, sizeof(buf), stdin);) { + + /* + * newline + * begin (next line) or end of header + */ if (*buf == '\n') { newline = 1; - continue; + + /* skip bytes in body (content-length) */ + if (header && body > 0) { + while(body--) + getc(stdin); + } + header = 0; + body = 0; + } + + /* begin of header */ + else if (newline && !strncmp(buf, "From ", 5)) { + if (!f_from) + if (!sender || match(buf + 5, sender)) + print_from(buf); + + header = 1; + newline = 0; + } + + /* found "^content-length: <bytes>" in header */ + else if (header && + !strncasecmp(buf, CLEN, sizeof(CLEN) - 1) && + isblank(*(buf + sizeof(CLEN) - 1))) { + + body = atoi(buf + sizeof(CLEN)); + } + + /* From: */ + else if (header && f_from && + !strncasecmp(buf, FROM, sizeof(FROM) - 1) && + isblank(*(buf + sizeof(FROM) - 1))) { + + if (!sender || match2(buf + sizeof(FROM), sender)) + print_from(buf); + } + + + } + + /* print number (of matching or non-matching) mails */ + if (f_count) + fprintf(stdout, "%d\n", counter); + + /* reset access time */ + if (f_atime) { + if (utimes(file, tv) < 0) { + perror("utimes"); + exit(1); } - if (newline && !strncmp(buf, "From ", 5) && - (!sender || match(buf + 5, sender))) - printf("%s", buf); - newline = 0; } exit(0); } -match(line, sender) +int match(line, sender) register char *line, *sender; { register char ch, pch, first, *p, *t; for (first = *sender++;;) { if (isspace(ch = *line)) - return(0); + return(f_invert); ++line; if (isupper(ch)) ch = tolower(ch); @@ -125,7 +244,7 @@ continue; for (p = sender, t = line;;) { if (!(pch = *p++)) - return(1); + return(!f_invert); if (isupper(ch = *t++)) ch = tolower(ch); if (ch != pch) @@ -133,4 +252,27 @@ } } /* NOTREACHED */ +} + +int match2(line, sender) + register char *line, *sender; +{ + register char *p, *s; + + for (; *line; line++) { + for (p = line, s = sender; tolower(*p) == *s; p++, s++); + + if (*s == NULL) + return(!f_invert); + } + return(f_invert); +} + +void print_from(buf) + char *buf; +{ + if (f_count) + counter++; + else + printf("%s", buf); } --- /usr/src/usr.bin/from/from.1 Fri May 27 14:31:22 1994 +++ from.1 Wed Sep 20 16:52:01 1995 @@ -39,6 +39,7 @@ .Nd print names of those who have sent mail .Sh SYNOPSIS .Nm from +.Op Fl Fctv .Op Fl s Ar sender .Op Fl f Ar file .Op Ar user @@ -49,6 +50,14 @@ .Pp Options: .Bl -tag -width Fl + +.It Fl F +Use 'From:' field instead 'From'. + +.It Fl c +Suppress normal output; instead print a count of +matching lines. + .It Fl f Ar file The supplied file is examined instead of the invoker's mailbox. @@ -61,6 +70,13 @@ Only mail from addresses containing the supplied string are printed. + +.It Fl t +Don't change access time of mailbox. + +.It Fl v +Invert the sense of matching, to select nonmatching lines. + .El .Pp If
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199509201737.TAA03936>