From 95aac572f68a5424bb88ab82f4272bc2716a079d Mon Sep 17 00:00:00 2001 From: millert Date: Tue, 2 Jun 2015 15:44:17 +0000 Subject: [PATCH] Modernize from(1) a bit. Use getline() to support longer lines and document the environment variables used. OK deraadt@ --- usr.bin/from/from.1 | 17 +++++++- usr.bin/from/from.c | 95 +++++++++++++++++++++++++-------------------- 2 files changed, 67 insertions(+), 45 deletions(-) diff --git a/usr.bin/from/from.1 b/usr.bin/from/from.1 index 3f2c589e387..8026e4d37df 100644 --- a/usr.bin/from/from.1 +++ b/usr.bin/from/from.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: from.1,v 1.12 2013/08/12 14:19:53 jmc Exp $ +.\" $OpenBSD: from.1,v 1.13 2015/06/02 15:44:17 millert Exp $ .\" $NetBSD: from.1,v 1.4 1995/09/01 01:39:09 jtc Exp $ .\" .\" Copyright (c) 1980, 1990, 1993 @@ -30,7 +30,7 @@ .\" .\" @(#)from.1 8.2 (Berkeley) 12/30/93 .\" -.Dd $Mdocdate: August 12 2013 $ +.Dd $Mdocdate: June 2 2015 $ .Dt FROM 1 .Os .Sh NAME @@ -68,6 +68,19 @@ is given, the .Ar user Ns 's mailbox is examined instead of the invoker's own mailbox. (Privileges are required.) +.Sh ENVIRONMENT +.Nm +utilizes the +.Ev LOGNAME , +.Ev MAIL , +and +.Ev USER +environment variables. +.Pp +If the +.Ev MAIL +environment variable is set, its value is used as the path to the +user's mail spool. .Sh FILES .Bl -tag -width /var/mail/* -compact .It Pa /var/mail/* diff --git a/usr.bin/from/from.c b/usr.bin/from/from.c index 07abc2ce74e..da2230fd8cf 100644 --- a/usr.bin/from/from.c +++ b/usr.bin/from/from.c @@ -1,4 +1,4 @@ -/* $OpenBSD: from.c,v 1.17 2015/01/16 06:40:07 deraadt Exp $ */ +/* $OpenBSD: from.c,v 1.18 2015/06/02 15:44:17 millert Exp $ */ /* $NetBSD: from.c,v 1.6 1995/09/01 01:39:10 jtc Exp $ */ /* @@ -41,21 +41,19 @@ #include int match(char *, char *); +FILE *open_mbox(const char *file, const char *user); int main(int argc, char *argv[]) { - struct passwd *pwd; int ch, newline; - char *file, *sender, *p; -#if PATH_MAX > BUFSIZ - char buf[PATH_MAX]; -#else - char buf[BUFSIZ]; -#endif + char *file, *line, *sender, *p; + size_t linesize = 0; + ssize_t linelen; + FILE *fp; - file = sender = NULL; - while ((ch = getopt(argc, argv, "f:s:")) != -1) + file = line = sender = NULL; + while ((ch = getopt(argc, argv, "f:s:")) != -1) { switch(ch) { case 'f': file = optarg; @@ -66,54 +64,65 @@ main(int argc, char *argv[]) if (isupper((unsigned char)*p)) *p = tolower((unsigned char)*p); break; - case '?': default: fprintf(stderr, "usage: from [-f file] [-s sender] [user]\n"); - exit(1); + exit(EXIT_FAILURE); } + } argv += optind; + if ((fp = open_mbox(file, *argv)) == NULL) + err(1, "%s", file); + for (newline = 1; (linelen = getline(&line, &linesize, fp)) != -1;) { + if (*line == '\n') { + newline = 1; + continue; + } + if (newline && !strncmp(line, "From ", 5) && + (!sender || match(line + 5, sender))) + printf("%s", line); + newline = 0; + } + free(line); + exit(EXIT_SUCCESS); +} + +FILE * +open_mbox(const char *file, const char *user) +{ + struct passwd *pwd; + char *buf = NULL; + FILE *fp; + /* * We find the mailbox by: * 1 -f flag - * 2 user + * 2 _PATH_MAILDIR/user (from argv) * 2 MAIL environment variable - * 3 _PATH_MAILDIR/file + * 3 _PATH_MAILDIR/user (from environment or passwd db) */ - if (!file) { - if (!(file = *argv)) { - if (!(file = getenv("MAIL"))) { - if (!(pwd = getpwuid(getuid()))) - errx(1, "no password file entry for you"); - if ((file = getenv("USER"))) { - (void)snprintf(buf, sizeof(buf), - "%s/%s", _PATH_MAILDIR, file); - file = buf; - } else - (void)snprintf(file = buf, sizeof(buf), - "%s/%s", _PATH_MAILDIR, - pwd->pw_name); + if (file == NULL) { + if (user == NULL) { + if ((file = getenv("MAIL")) == NULL) { + if ((user = getenv("LOGNAME")) == NULL && + (user = getenv("USER")) == NULL) { + if (!(pwd = getpwuid(getuid()))) + errx(1, "no password file " + "entry for you"); + user = pwd->pw_name; + } } - } else { - (void)snprintf(buf, sizeof(buf), "%s/%s", - _PATH_MAILDIR, file); - file = buf; } - } - if (!freopen(file, "r", stdin)) - err(1, "%s", file); - for (newline = 1; fgets(buf, sizeof(buf), stdin);) { - if (*buf == '\n') { - newline = 1; - continue; + if (file == NULL) { + if (asprintf(&buf, "%s/%s", _PATH_MAILDIR, user) == -1) + err(1, NULL); + file = buf; } - if (newline && !strncmp(buf, "From ", 5) && - (!sender || match(buf + 5, sender))) - printf("%s", buf); - newline = 0; } - exit(0); + fp = fopen(file, "r"); + free(buf); + return(fp); } int -- 2.20.1