-.\" $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
.\"
.\" @(#)from.1 8.2 (Berkeley) 12/30/93
.\"
-.Dd $Mdocdate: August 12 2013 $
+.Dd $Mdocdate: June 2 2015 $
.Dt FROM 1
.Os
.Sh NAME
.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/*
-/* $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 $ */
/*
#include <err.h>
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;
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