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 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 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 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 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 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 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 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 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