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: releng/11.0/usr.bin/from/from.c 258446 2013-11-21 21:19:01Z eadler $"); 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 54258446Seadlerstatic int 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) 84258446Seadler *p = tolower(*p); 851590Srgrimes break; 861590Srgrimes case '?': 871590Srgrimes default: 8827270Scharnier usage(); 891590Srgrimes } 9099143Sjmallett argc -= optind; 911590Srgrimes argv += optind; 921590Srgrimes 9399143Sjmallett if (file == NULL) { 9499143Sjmallett if (argc) { 9566590Sru (void)snprintf(buf, sizeof(buf), "%s/%s", _PATH_MAILDIR, *argv); 9618725Sjkh file = buf; 9718725Sjkh } else { 9818725Sjkh if (!(file = getenv("MAIL"))) { 9927270Scharnier if (!(pwd = getpwuid(getuid()))) 10027270Scharnier errx(1, "no password file entry for you"); 10118725Sjkh file = pwd->pw_name; 10266590Sru (void)snprintf(buf, sizeof(buf), 10318725Sjkh "%s/%s", _PATH_MAILDIR, file); 10418725Sjkh file = buf; 1051590Srgrimes } 1061590Srgrimes } 1071590Srgrimes } 10813678Swosch 10913678Swosch /* read from stdin */ 11013678Swosch if (strcmp(file, "-") == 0) { 11199143Sjmallett mbox = stdin; 11213678Swosch } 11399143Sjmallett else if ((mbox = fopen(file, "r")) == NULL) { 11427270Scharnier errx(1, "can't read %s", file); 1151590Srgrimes } 11699143Sjmallett for (newline = 1; fgets(buf, sizeof(buf), mbox);) { 1171590Srgrimes if (*buf == '\n') { 1181590Srgrimes newline = 1; 1191590Srgrimes continue; 1201590Srgrimes } 1211590Srgrimes if (newline && !strncmp(buf, "From ", 5) && 12249123Sgreen (!sender || match(buf + 5, sender))) { 12349123Sgreen if (count != -1) 12449123Sgreen count++; 12549123Sgreen else 12649123Sgreen printf("%s", buf); 12749123Sgreen } 1281590Srgrimes newline = 0; 1291590Srgrimes } 13049123Sgreen if (count != -1) 13149123Sgreen printf("There %s %d message%s in your incoming mailbox.\n", 13249123Sgreen count == 1 ? "is" : "are", count, count == 1 ? "" : "s"); 13399143Sjmallett fclose(mbox); 1341590Srgrimes exit(0); 1351590Srgrimes} 1361590Srgrimes 13727270Scharnierstatic void 13899143Sjmallettusage(void) 13927270Scharnier{ 14049123Sgreen fprintf(stderr, "usage: from [-c] [-f file] [-s sender] [user]\n"); 14127270Scharnier exit(1); 14227270Scharnier} 14327270Scharnier 144258446Seadlerstatic int 145102944Sdwmalonematch(const char *line, const char *sender) 1461590Srgrimes{ 147102944Sdwmalone char ch, pch, first; 148102944Sdwmalone const char *p, *t; 1491590Srgrimes 1501590Srgrimes for (first = *sender++;;) { 1511590Srgrimes if (isspace(ch = *line)) 1521590Srgrimes return(0); 1531590Srgrimes ++line; 154258446Seadler ch = tolower(ch); 1551590Srgrimes if (ch != first) 1561590Srgrimes continue; 1571590Srgrimes for (p = sender, t = line;;) { 1581590Srgrimes if (!(pch = *p++)) 1591590Srgrimes return(1); 160258446Seadler ch = tolower(*t); 161258446Seadler t++; 1621590Srgrimes if (ch != pch) 1631590Srgrimes break; 1641590Srgrimes } 1651590Srgrimes } 1661590Srgrimes /* NOTREACHED */ 1671590Srgrimes} 168