17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*23a1cceaSRoger A. Faulkner * Common Development and Distribution License (the "License").
6*23a1cceaSRoger A. Faulkner * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21*23a1cceaSRoger A. Faulkner
227c478bd9Sstevel@tonic-gate /*
23*23a1cceaSRoger A. Faulkner * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
26b7d62af5Sceastha /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27b7d62af5Sceastha /* All Rights Reserved */
28b7d62af5Sceastha
297c478bd9Sstevel@tonic-gate #include "mail.h"
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate #define MAXHDRSIZE 100 /* Maximum length of header line */
327c478bd9Sstevel@tonic-gate #define MAXUNAME 20 /* Maximum length of user name */
337c478bd9Sstevel@tonic-gate
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate * display headers, indicating current and status
367c478bd9Sstevel@tonic-gate *
377c478bd9Sstevel@tonic-gate * current is the displacement into the mailfile of the
387c478bd9Sstevel@tonic-gate * current letter
397c478bd9Sstevel@tonic-gate *
407c478bd9Sstevel@tonic-gate * all indicates how many headers should be shown.
417c478bd9Sstevel@tonic-gate * 0 -> show window +/-6 around current
427c478bd9Sstevel@tonic-gate * 1 -> show all messages
437c478bd9Sstevel@tonic-gate * 2 -> show deleted messages
447c478bd9Sstevel@tonic-gate *
457c478bd9Sstevel@tonic-gate * Only 100 characters of the From (first) header line will
467c478bd9Sstevel@tonic-gate * be read in. This line is assumed to be in the following
477c478bd9Sstevel@tonic-gate * format:
487c478bd9Sstevel@tonic-gate * From <sender address> <date>
497c478bd9Sstevel@tonic-gate * where
507c478bd9Sstevel@tonic-gate * <sender address> is either a UUCP-style (sysa!sysb!user)
517c478bd9Sstevel@tonic-gate * or domain-style address (user@host).
527c478bd9Sstevel@tonic-gate *
537c478bd9Sstevel@tonic-gate * If the sender address contains a UUCP-style address, then
547c478bd9Sstevel@tonic-gate * the user name displayed is made up of the characters following
557c478bd9Sstevel@tonic-gate * the final '!' in the sender address, otherwise the sender
567c478bd9Sstevel@tonic-gate * address is considered to be the user name.
577c478bd9Sstevel@tonic-gate *
587c478bd9Sstevel@tonic-gate * The maximum number of characters of a user name displayed
597c478bd9Sstevel@tonic-gate * is 19.
607c478bd9Sstevel@tonic-gate *
617c478bd9Sstevel@tonic-gate */
627c478bd9Sstevel@tonic-gate int
gethead(int current,int all)637c478bd9Sstevel@tonic-gate gethead(int current, int all)
647c478bd9Sstevel@tonic-gate {
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate int displayed = 0;
677c478bd9Sstevel@tonic-gate FILE *file;
687c478bd9Sstevel@tonic-gate char *hold;
697c478bd9Sstevel@tonic-gate char holdval[MAXHDRSIZE];
707c478bd9Sstevel@tonic-gate char *wline;
717c478bd9Sstevel@tonic-gate char wlineval[MAXHDRSIZE];
727c478bd9Sstevel@tonic-gate int ln;
737c478bd9Sstevel@tonic-gate char mark;
747c478bd9Sstevel@tonic-gate int rc, size, start, stop, ix;
757c478bd9Sstevel@tonic-gate char userval[MAXUNAME];
767c478bd9Sstevel@tonic-gate char *uucpptr;
777c478bd9Sstevel@tonic-gate int uucpstart;
787c478bd9Sstevel@tonic-gate int unamechars = MAXUNAME - 1;
797c478bd9Sstevel@tonic-gate int sender_size;
807c478bd9Sstevel@tonic-gate
817c478bd9Sstevel@tonic-gate hold = holdval;
827c478bd9Sstevel@tonic-gate wline = wlineval;
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate printf("%d letters found in %s, %d scheduled for deletion, "
857c478bd9Sstevel@tonic-gate "%d newly arrived\n", nlet, mailfile, changed, nlet - onlet);
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate if (all == 2 && !changed)
887c478bd9Sstevel@tonic-gate return (0);
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate file = doopen(lettmp, "r", E_TMP);
917c478bd9Sstevel@tonic-gate if (!flgr) {
927c478bd9Sstevel@tonic-gate stop = current - 6;
937c478bd9Sstevel@tonic-gate if (stop < -1) stop = -1;
947c478bd9Sstevel@tonic-gate start = current + 5;
957c478bd9Sstevel@tonic-gate if (start > nlet - 1) start = nlet - 1;
967c478bd9Sstevel@tonic-gate if (all) {
977c478bd9Sstevel@tonic-gate start = nlet -1;
987c478bd9Sstevel@tonic-gate stop = -1;
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate } else {
1017c478bd9Sstevel@tonic-gate stop = current + 6;
1027c478bd9Sstevel@tonic-gate if (stop > nlet) stop = nlet;
1037c478bd9Sstevel@tonic-gate start = current - 5;
1047c478bd9Sstevel@tonic-gate if (start < 0) start = 0;
1057c478bd9Sstevel@tonic-gate if (all) {
1067c478bd9Sstevel@tonic-gate start = 0;
1077c478bd9Sstevel@tonic-gate stop = nlet;
1087c478bd9Sstevel@tonic-gate }
1097c478bd9Sstevel@tonic-gate }
1107c478bd9Sstevel@tonic-gate for (ln = start; ln != stop; ln = flgr ? ln + 1 : ln - 1) {
1117c478bd9Sstevel@tonic-gate size = let[ln+1].adr - let[ln].adr;
1127c478bd9Sstevel@tonic-gate if ((rc = fseek(file, let[ln].adr, 0)) != 0) {
1137c478bd9Sstevel@tonic-gate errmsg(E_FILE, "Cannot seek header");
1147c478bd9Sstevel@tonic-gate fclose(file);
1157c478bd9Sstevel@tonic-gate return (1);
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate if (fgets(wline, MAXHDRSIZE, file) == NULL) {
1187c478bd9Sstevel@tonic-gate errmsg(E_FILE, "Cannot read header");
1197c478bd9Sstevel@tonic-gate fclose(file);
1207c478bd9Sstevel@tonic-gate return (1);
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate if ((rc = strncmp(wline, header[H_FROM].tag, 5)) != SAME) {
1237c478bd9Sstevel@tonic-gate errmsg(E_FILE, "Invalid header encountered");
1247c478bd9Sstevel@tonic-gate fclose(file);
1257c478bd9Sstevel@tonic-gate return (1);
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate /* skip past trailing white space after header tag */
129*23a1cceaSRoger A. Faulkner for (rc = 5; wline[rc] == ' ' || wline[rc] == '\t'; ++rc)
130*23a1cceaSRoger A. Faulkner ;
1317c478bd9Sstevel@tonic-gate (void) strlcpy(hold, wline + rc, MAXHDRSIZE);
1327c478bd9Sstevel@tonic-gate fgets(wline, MAXHDRSIZE, file);
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate while (((rc = strncmp(wline,
1357c478bd9Sstevel@tonic-gate header[H_FROM1].tag, 6)) == SAME) &&
1367c478bd9Sstevel@tonic-gate (substr(wline, "remote from ") != -1)) {
1377c478bd9Sstevel@tonic-gate (void) strlcpy(hold, wline + 6, MAXHDRSIZE);
1387c478bd9Sstevel@tonic-gate fgets(wline, MAXHDRSIZE, file);
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate
1417c478bd9Sstevel@tonic-gate
1427c478bd9Sstevel@tonic-gate /*
1437c478bd9Sstevel@tonic-gate * If UUCP-style sender address, then read past
1447c478bd9Sstevel@tonic-gate * last "!" to get the start of the user name.
1457c478bd9Sstevel@tonic-gate */
1467c478bd9Sstevel@tonic-gate sender_size = strcspn(hold, " \t");
1477c478bd9Sstevel@tonic-gate uucpstart = 0;
1487c478bd9Sstevel@tonic-gate if ((uucpptr = strrchr(hold, '!')) != NULL) {
1497c478bd9Sstevel@tonic-gate uucpstart = uucpptr - hold + 1;
1507c478bd9Sstevel@tonic-gate if (uucpstart > sender_size) {
1517c478bd9Sstevel@tonic-gate uucpstart = 0;
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate }
1547c478bd9Sstevel@tonic-gate
1557c478bd9Sstevel@tonic-gate /* Get the user name out of the sender address. */
1567c478bd9Sstevel@tonic-gate for (ix = 0, rc = uucpstart; ix < unamechars &&
1577c478bd9Sstevel@tonic-gate hold[rc] != ' ' && hold[rc] != '\t' &&
1587c478bd9Sstevel@tonic-gate rc < sender_size; ++rc) {
1597c478bd9Sstevel@tonic-gate userval[ix++] = hold[rc];
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate if ((ix > 0) && (userval[ix - 1] == '\n')) {
1627c478bd9Sstevel@tonic-gate userval[ix - 1] = '\0';
1637c478bd9Sstevel@tonic-gate } else {
1647c478bd9Sstevel@tonic-gate userval[ix] = '\0';
1657c478bd9Sstevel@tonic-gate }
1667c478bd9Sstevel@tonic-gate
1677c478bd9Sstevel@tonic-gate /*
1687c478bd9Sstevel@tonic-gate * Skip past the rest of the sender address, and
1697c478bd9Sstevel@tonic-gate * delimiting white space.
1707c478bd9Sstevel@tonic-gate */
1717c478bd9Sstevel@tonic-gate for (; hold[rc] != '\0' && hold[rc] != ' ' &&
172*23a1cceaSRoger A. Faulkner hold[rc] != '\t'; ++rc)
173*23a1cceaSRoger A. Faulkner ;
174*23a1cceaSRoger A. Faulkner for (; hold[rc] == ' ' || hold[rc] == '\t'; ++rc)
175*23a1cceaSRoger A. Faulkner ;
1767c478bd9Sstevel@tonic-gate
1777c478bd9Sstevel@tonic-gate /* Get the date information. */
1787c478bd9Sstevel@tonic-gate (void) strlcpy(wline, hold + rc, MAXHDRSIZE);
179*23a1cceaSRoger A. Faulkner for (rc = 0; wline[rc] != '\0' && wline[rc] != '\n'; ++rc)
180*23a1cceaSRoger A. Faulkner ;
1817c478bd9Sstevel@tonic-gate wline[rc] = '\0';
1827c478bd9Sstevel@tonic-gate
1837c478bd9Sstevel@tonic-gate if (!flgh && current == ln) mark = '>';
1847c478bd9Sstevel@tonic-gate else mark = ' ';
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate if (all == 2) {
1877c478bd9Sstevel@tonic-gate if (displayed >= changed) {
1887c478bd9Sstevel@tonic-gate fclose(file);
1897c478bd9Sstevel@tonic-gate return (0);
1907c478bd9Sstevel@tonic-gate }
1917c478bd9Sstevel@tonic-gate if (let[ln].change == ' ') continue;
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate
1947c478bd9Sstevel@tonic-gate printf("%c %3d %c %-5d %-10s %s\n", mark, ln + 1,
1957c478bd9Sstevel@tonic-gate let[ln].change, size, userval, wline);
1967c478bd9Sstevel@tonic-gate displayed++;
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate fclose(file);
1997c478bd9Sstevel@tonic-gate return (0);
2007c478bd9Sstevel@tonic-gate }
2017c478bd9Sstevel@tonic-gate
2027c478bd9Sstevel@tonic-gate void
tmperr(void)203b7d62af5Sceastha tmperr(void)
2047c478bd9Sstevel@tonic-gate {
2057c478bd9Sstevel@tonic-gate fclose(tmpf);
2067c478bd9Sstevel@tonic-gate errmsg(E_TMP, "");
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate
2097c478bd9Sstevel@tonic-gate /*
2107c478bd9Sstevel@tonic-gate * Write a string out to tmp file, with error checking.
2117c478bd9Sstevel@tonic-gate * Return 1 on success, else 0
2127c478bd9Sstevel@tonic-gate */
213b7d62af5Sceastha int
wtmpf(char * str,int length)214b7d62af5Sceastha wtmpf(char *str, int length)
2157c478bd9Sstevel@tonic-gate {
2167c478bd9Sstevel@tonic-gate if (fwrite(str, 1, length, tmpf) != length) {
2177c478bd9Sstevel@tonic-gate tmperr();
2187c478bd9Sstevel@tonic-gate return (0);
2197c478bd9Sstevel@tonic-gate }
2207c478bd9Sstevel@tonic-gate return (1);
2217c478bd9Sstevel@tonic-gate }
2227c478bd9Sstevel@tonic-gate
2237c478bd9Sstevel@tonic-gate /*
2247c478bd9Sstevel@tonic-gate * Read a line from stdin, assign it to line and
2257c478bd9Sstevel@tonic-gate * return number of bytes in length
2267c478bd9Sstevel@tonic-gate */
2277c478bd9Sstevel@tonic-gate int
getaline(char * ptr2line,int max,FILE * f)228*23a1cceaSRoger A. Faulkner getaline(char *ptr2line, int max, FILE *f)
2297c478bd9Sstevel@tonic-gate {
2307c478bd9Sstevel@tonic-gate int i, ch;
2317c478bd9Sstevel@tonic-gate for (i = 0; i < max-1 && (ch = getc(f)) != EOF; )
2327c478bd9Sstevel@tonic-gate if ((ptr2line[i++] = ch) == '\n') break;
2337c478bd9Sstevel@tonic-gate ptr2line[i] = '\0';
2347c478bd9Sstevel@tonic-gate return (i);
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate
2377c478bd9Sstevel@tonic-gate /*
2387c478bd9Sstevel@tonic-gate * Make temporary file for letter
2397c478bd9Sstevel@tonic-gate */
2407c478bd9Sstevel@tonic-gate void
mktmp(void)241b7d62af5Sceastha mktmp(void)
2427c478bd9Sstevel@tonic-gate {
2437c478bd9Sstevel@tonic-gate static char tmpl[] = "/var/tmp/mailXXXXXX";
2447c478bd9Sstevel@tonic-gate int fd = mkstemp(lettmp = tmpl);
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate if (fd < 0 || (tmpf = fdopen(fd, "w+")) == NULL) {
2477c478bd9Sstevel@tonic-gate fprintf(stderr,
2487c478bd9Sstevel@tonic-gate "%s: Can't open '%s', type: w+\n", program, lettmp);
2497c478bd9Sstevel@tonic-gate done(0);
2507c478bd9Sstevel@tonic-gate }
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate
2537c478bd9Sstevel@tonic-gate /*
2547c478bd9Sstevel@tonic-gate * Get a number from user's reply,
2557c478bd9Sstevel@tonic-gate * return its value or zero if none present, -1 on error
2567c478bd9Sstevel@tonic-gate */
257b7d62af5Sceastha int
getnumbr(char * s)258b7d62af5Sceastha getnumbr(char *s)
2597c478bd9Sstevel@tonic-gate {
2607c478bd9Sstevel@tonic-gate int k = 0;
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate while (*s == ' ' || *s == '\t') s++;
2637c478bd9Sstevel@tonic-gate
2647c478bd9Sstevel@tonic-gate if (*s != '\0') {
2657c478bd9Sstevel@tonic-gate if ((k = atoi(s)) != 0)
2667c478bd9Sstevel@tonic-gate if (!validmsg(k))
2677c478bd9Sstevel@tonic-gate return (-1);
2687c478bd9Sstevel@tonic-gate
2697c478bd9Sstevel@tonic-gate for (; *s >= '0' && *s <= '9'; ) s++;
2707c478bd9Sstevel@tonic-gate if (*s != '\0' && *s != '\n') {
2717c478bd9Sstevel@tonic-gate printf("Illegal numeric\n");
2727c478bd9Sstevel@tonic-gate return (-1);
2737c478bd9Sstevel@tonic-gate }
2747c478bd9Sstevel@tonic-gate return (k);
2757c478bd9Sstevel@tonic-gate }
2767c478bd9Sstevel@tonic-gate return (0);
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate
2797c478bd9Sstevel@tonic-gate /*
2807c478bd9Sstevel@tonic-gate * If valid msgnum return 1,
2817c478bd9Sstevel@tonic-gate * else print message and return 0
2827c478bd9Sstevel@tonic-gate */
283b7d62af5Sceastha int
validmsg(int i)284b7d62af5Sceastha validmsg(int i)
2857c478bd9Sstevel@tonic-gate {
2867c478bd9Sstevel@tonic-gate if ((i < 0) || (i > nlet)) {
2877c478bd9Sstevel@tonic-gate printf("No such message\n");
2887c478bd9Sstevel@tonic-gate return (0);
2897c478bd9Sstevel@tonic-gate }
2907c478bd9Sstevel@tonic-gate return (1);
2917c478bd9Sstevel@tonic-gate }
2927c478bd9Sstevel@tonic-gate
2937c478bd9Sstevel@tonic-gate /*
2947c478bd9Sstevel@tonic-gate * Set letter to passed status, and adjust changed as necessary
2957c478bd9Sstevel@tonic-gate */
2967c478bd9Sstevel@tonic-gate void
setletr(int letter,int status)297b7d62af5Sceastha setletr(int letter, int status)
2987c478bd9Sstevel@tonic-gate {
2997c478bd9Sstevel@tonic-gate if (status == ' ') {
3007c478bd9Sstevel@tonic-gate if (let[letter].change != ' ')
3017c478bd9Sstevel@tonic-gate if (changed) changed--;
3027c478bd9Sstevel@tonic-gate } else {
3037c478bd9Sstevel@tonic-gate if (let[letter].change == ' ') changed++;
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate let[letter].change = status;
3067c478bd9Sstevel@tonic-gate }
307