11590Srgrimes/* 21590Srgrimes * Copyright (c) 1980, 1988, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 4. Neither the name of the University nor the names of its contributors 141590Srgrimes * may be used to endorse or promote products derived from this software 151590Srgrimes * without specific prior written permission. 161590Srgrimes * 171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271590Srgrimes * SUCH DAMAGE. 281590Srgrimes */ 291590Srgrimes 301590Srgrimes#ifndef lint 3127270Scharnierstatic const char copyright[] = 321590Srgrimes"@(#) Copyright (c) 1980, 1988, 1993\n\ 331590Srgrimes The Regents of the University of California. All rights reserved.\n"; 341590Srgrimes#endif /* not lint */ 351590Srgrimes 361590Srgrimes#ifndef lint 3727270Scharnier#if 0 381590Srgrimesstatic char sccsid[] = "@(#)from.c 8.1 (Berkeley) 6/6/93"; 3927270Scharnier#endif 401590Srgrimes#endif /* not lint */ 4199112Sobrien#include <sys/cdefs.h> 4299112Sobrien__FBSDID("$FreeBSD$"); 431590Srgrimes 441590Srgrimes#include <sys/types.h> 451590Srgrimes#include <ctype.h> 4627270Scharnier#include <err.h> 471590Srgrimes#include <pwd.h> 481590Srgrimes#include <stdio.h> 4918725Sjkh#include <stdlib.h> 5027270Scharnier#include <paths.h> 5113678Swosch#include <string.h> 5227270Scharnier#include <unistd.h> 531590Srgrimes 54102944Sdwmaloneint match(const char *, const char *); 5592920Simpstatic void usage(void); 5627270Scharnier 5727270Scharnierint 5899143Sjmallettmain(int argc, char **argv) 591590Srgrimes{ 6099143Sjmallett FILE *mbox; 611590Srgrimes struct passwd *pwd; 6249123Sgreen int ch, count, newline; 63102944Sdwmalone const char *file; 64102944Sdwmalone char *sender, *p; 651590Srgrimes#if MAXPATHLEN > BUFSIZ 661590Srgrimes char buf[MAXPATHLEN]; 671590Srgrimes#else 681590Srgrimes char buf[BUFSIZ]; 691590Srgrimes#endif 701590Srgrimes 711590Srgrimes file = sender = NULL; 7249123Sgreen count = -1; 7349123Sgreen while ((ch = getopt(argc, argv, "cf:s:")) != -1) 7449123Sgreen switch (ch) { 7549123Sgreen case 'c': 7649123Sgreen count = 0; 7749123Sgreen break; 781590Srgrimes case 'f': 791590Srgrimes file = optarg; 801590Srgrimes break; 811590Srgrimes case 's': 821590Srgrimes sender = optarg; 831590Srgrimes for (p = sender; *p; ++p) 841590Srgrimes if (isupper(*p)) 851590Srgrimes *p = tolower(*p); 861590Srgrimes break; 871590Srgrimes case '?': 881590Srgrimes default: 8927270Scharnier usage(); 901590Srgrimes } 9199143Sjmallett argc -= optind; 921590Srgrimes argv += optind; 931590Srgrimes 9499143Sjmallett if (file == NULL) { 9599143Sjmallett if (argc) { 9666590Sru (void)snprintf(buf, sizeof(buf), "%s/%s", _PATH_MAILDIR, *argv); 9718725Sjkh file = buf; 9818725Sjkh } else { 9918725Sjkh if (!(file = getenv("MAIL"))) { 10027270Scharnier if (!(pwd = getpwuid(getuid()))) 10127270Scharnier errx(1, "no password file entry for you"); 10218725Sjkh file = pwd->pw_name; 10366590Sru (void)snprintf(buf, sizeof(buf), 10418725Sjkh "%s/%s", _PATH_MAILDIR, file); 10518725Sjkh file = buf; 1061590Srgrimes } 1071590Srgrimes } 1081590Srgrimes } 10913678Swosch 11013678Swosch /* read from stdin */ 11113678Swosch if (strcmp(file, "-") == 0) { 11299143Sjmallett mbox = stdin; 11313678Swosch } 11499143Sjmallett else if ((mbox = fopen(file, "r")) == NULL) { 11527270Scharnier errx(1, "can't read %s", file); 1161590Srgrimes } 11799143Sjmallett for (newline = 1; fgets(buf, sizeof(buf), mbox);) { 1181590Srgrimes if (*buf == '\n') { 1191590Srgrimes newline = 1; 1201590Srgrimes continue; 1211590Srgrimes } 1221590Srgrimes if (newline && !strncmp(buf, "From ", 5) && 12349123Sgreen (!sender || match(buf + 5, sender))) { 12449123Sgreen if (count != -1) 12549123Sgreen count++; 12649123Sgreen else 12749123Sgreen printf("%s", buf); 12849123Sgreen } 1291590Srgrimes newline = 0; 1301590Srgrimes } 13149123Sgreen if (count != -1) 13249123Sgreen printf("There %s %d message%s in your incoming mailbox.\n", 13349123Sgreen count == 1 ? "is" : "are", count, count == 1 ? "" : "s"); 13499143Sjmallett fclose(mbox); 1351590Srgrimes exit(0); 1361590Srgrimes} 1371590Srgrimes 13827270Scharnierstatic void 13999143Sjmallettusage(void) 14027270Scharnier{ 14149123Sgreen fprintf(stderr, "usage: from [-c] [-f file] [-s sender] [user]\n"); 14227270Scharnier exit(1); 14327270Scharnier} 14427270Scharnier 14527270Scharnierint 146102944Sdwmalonematch(const char *line, const char *sender) 1471590Srgrimes{ 148102944Sdwmalone char ch, pch, first; 149102944Sdwmalone const char *p, *t; 1501590Srgrimes 1511590Srgrimes for (first = *sender++;;) { 1521590Srgrimes if (isspace(ch = *line)) 1531590Srgrimes return(0); 1541590Srgrimes ++line; 1551590Srgrimes if (isupper(ch)) 1561590Srgrimes ch = tolower(ch); 1571590Srgrimes if (ch != first) 1581590Srgrimes continue; 1591590Srgrimes for (p = sender, t = line;;) { 1601590Srgrimes if (!(pch = *p++)) 1611590Srgrimes return(1); 1621590Srgrimes if (isupper(ch = *t++)) 1631590Srgrimes ch = tolower(ch); 1641590Srgrimes if (ch != pch) 1651590Srgrimes break; 1661590Srgrimes } 1671590Srgrimes } 1681590Srgrimes /* NOTREACHED */ 1691590Srgrimes} 170