1 1.17 lukem /* $NetBSD: from.c,v 1.17 2008/07/21 14:19:22 lukem Exp $ */ 2 1.6 jtc 3 1.1 cgd /* 4 1.6 jtc * Copyright (c) 1980, 1988, 1993 5 1.6 jtc * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.15 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 cgd * may be used to endorse or promote products derived from this software 17 1.1 cgd * without specific prior written permission. 18 1.1 cgd * 19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 cgd * SUCH DAMAGE. 30 1.1 cgd */ 31 1.1 cgd 32 1.8 lukem #include <sys/cdefs.h> 33 1.1 cgd #ifndef lint 34 1.17 lukem __COPYRIGHT("@(#) Copyright (c) 1980, 1988, 1993\ 35 1.17 lukem The Regents of the University of California. All rights reserved."); 36 1.1 cgd #endif /* not lint */ 37 1.1 cgd 38 1.1 cgd #ifndef lint 39 1.6 jtc #if 0 40 1.6 jtc static char sccsid[] = "@(#)from.c 8.1 (Berkeley) 6/6/93"; 41 1.6 jtc #endif 42 1.17 lukem __RCSID("$NetBSD: from.c,v 1.17 2008/07/21 14:19:22 lukem Exp $"); 43 1.1 cgd #endif /* not lint */ 44 1.1 cgd 45 1.1 cgd #include <sys/types.h> 46 1.1 cgd #include <ctype.h> 47 1.10 mjl #include <err.h> 48 1.8 lukem #include <paths.h> 49 1.1 cgd #include <pwd.h> 50 1.1 cgd #include <stdio.h> 51 1.3 deraadt #include <stdlib.h> 52 1.8 lukem #include <string.h> 53 1.3 deraadt #include <unistd.h> 54 1.1 cgd 55 1.11 mjl int main (int, char **); 56 1.11 mjl int match (const char *, const char *); 57 1.8 lukem 58 1.8 lukem int 59 1.11 mjl main(int argc, char **argv) 60 1.1 cgd { 61 1.1 cgd struct passwd *pwd; 62 1.1 cgd int ch, newline; 63 1.1 cgd char *file, *sender, *p; 64 1.1 cgd #if MAXPATHLEN > BUFSIZ 65 1.1 cgd char buf[MAXPATHLEN]; 66 1.1 cgd #else 67 1.1 cgd char buf[BUFSIZ]; 68 1.1 cgd #endif 69 1.1 cgd 70 1.1 cgd file = sender = NULL; 71 1.7 lukem while ((ch = getopt(argc, argv, "f:s:")) != -1) 72 1.1 cgd switch((char)ch) { 73 1.1 cgd case 'f': 74 1.1 cgd file = optarg; 75 1.1 cgd break; 76 1.1 cgd case 's': 77 1.1 cgd sender = optarg; 78 1.1 cgd for (p = sender; *p; ++p) 79 1.16 dsl *p = tolower((unsigned char)*p); 80 1.1 cgd break; 81 1.1 cgd default: 82 1.1 cgd fprintf(stderr, "usage: from [-f file] [-s sender] [user]\n"); 83 1.1 cgd exit(1); 84 1.1 cgd } 85 1.1 cgd argv += optind; 86 1.1 cgd 87 1.3 deraadt /* 88 1.3 deraadt * We find the mailbox by: 89 1.3 deraadt * 1 -f flag 90 1.3 deraadt * 2 user 91 1.3 deraadt * 2 MAIL environment variable 92 1.3 deraadt * 3 _PATH_MAILDIR/file 93 1.3 deraadt */ 94 1.1 cgd if (!file) { 95 1.1 cgd if (!(file = *argv)) { 96 1.3 deraadt if (!(file = getenv("MAIL"))) { 97 1.10 mjl if (!(pwd = getpwuid(getuid()))) 98 1.13 mjl errx(1, "no password file entry for you"); 99 1.14 kleink if ((file = getenv("LOGNAME")) != NULL || 100 1.14 kleink (file = getenv("USER")) != NULL) { 101 1.13 mjl (void)snprintf(buf, sizeof(buf), 102 1.13 mjl "%s/%s", _PATH_MAILDIR, file); 103 1.5 deraadt file = buf; 104 1.5 deraadt } else 105 1.13 mjl (void)snprintf(file = buf, sizeof(buf), 106 1.13 mjl "%s/%s", 107 1.5 deraadt _PATH_MAILDIR, pwd->pw_name); 108 1.1 cgd } 109 1.4 deraadt } else { 110 1.13 mjl (void)snprintf(buf, sizeof(buf), "%s/%s", 111 1.13 mjl _PATH_MAILDIR, file); 112 1.4 deraadt file = buf; 113 1.1 cgd } 114 1.1 cgd } 115 1.10 mjl if (!freopen(file, "r", stdin)) 116 1.13 mjl err(1, "can't read %s", file); 117 1.10 mjl 118 1.1 cgd for (newline = 1; fgets(buf, sizeof(buf), stdin);) { 119 1.1 cgd if (*buf == '\n') { 120 1.1 cgd newline = 1; 121 1.1 cgd continue; 122 1.1 cgd } 123 1.1 cgd if (newline && !strncmp(buf, "From ", 5) && 124 1.1 cgd (!sender || match(buf + 5, sender))) 125 1.1 cgd printf("%s", buf); 126 1.1 cgd newline = 0; 127 1.1 cgd } 128 1.1 cgd exit(0); 129 1.1 cgd } 130 1.1 cgd 131 1.8 lukem int 132 1.11 mjl match(const char *line, const char *sender) 133 1.1 cgd { 134 1.11 mjl char ch, pch, first; 135 1.11 mjl const char *p, *t; 136 1.1 cgd 137 1.1 cgd for (first = *sender++;;) { 138 1.9 christos if (isspace((unsigned char)(ch = *line))) 139 1.1 cgd return(0); 140 1.1 cgd ++line; 141 1.16 dsl ch = tolower((unsigned char)ch); 142 1.1 cgd if (ch != first) 143 1.1 cgd continue; 144 1.1 cgd for (p = sender, t = line;;) { 145 1.1 cgd if (!(pch = *p++)) 146 1.1 cgd return(1); 147 1.16 dsl ch = tolower((unsigned char)*t++); 148 1.1 cgd if (ch != pch) 149 1.1 cgd break; 150 1.1 cgd } 151 1.1 cgd } 152 1.1 cgd /* NOTREACHED */ 153 1.1 cgd } 154