1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* 27*7c478bd9Sstevel@tonic-gate * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 28*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include "mail.h" 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #define MAXHDRSIZE 100 /* Maximum length of header line */ 36*7c478bd9Sstevel@tonic-gate #define MAXUNAME 20 /* Maximum length of user name */ 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate /* 39*7c478bd9Sstevel@tonic-gate * display headers, indicating current and status 40*7c478bd9Sstevel@tonic-gate * 41*7c478bd9Sstevel@tonic-gate * current is the displacement into the mailfile of the 42*7c478bd9Sstevel@tonic-gate * current letter 43*7c478bd9Sstevel@tonic-gate * 44*7c478bd9Sstevel@tonic-gate * all indicates how many headers should be shown. 45*7c478bd9Sstevel@tonic-gate * 0 -> show window +/-6 around current 46*7c478bd9Sstevel@tonic-gate * 1 -> show all messages 47*7c478bd9Sstevel@tonic-gate * 2 -> show deleted messages 48*7c478bd9Sstevel@tonic-gate * 49*7c478bd9Sstevel@tonic-gate * Only 100 characters of the From (first) header line will 50*7c478bd9Sstevel@tonic-gate * be read in. This line is assumed to be in the following 51*7c478bd9Sstevel@tonic-gate * format: 52*7c478bd9Sstevel@tonic-gate * From <sender address> <date> 53*7c478bd9Sstevel@tonic-gate * where 54*7c478bd9Sstevel@tonic-gate * <sender address> is either a UUCP-style (sysa!sysb!user) 55*7c478bd9Sstevel@tonic-gate * or domain-style address (user@host). 56*7c478bd9Sstevel@tonic-gate * 57*7c478bd9Sstevel@tonic-gate * If the sender address contains a UUCP-style address, then 58*7c478bd9Sstevel@tonic-gate * the user name displayed is made up of the characters following 59*7c478bd9Sstevel@tonic-gate * the final '!' in the sender address, otherwise the sender 60*7c478bd9Sstevel@tonic-gate * address is considered to be the user name. 61*7c478bd9Sstevel@tonic-gate * 62*7c478bd9Sstevel@tonic-gate * The maximum number of characters of a user name displayed 63*7c478bd9Sstevel@tonic-gate * is 19. 64*7c478bd9Sstevel@tonic-gate * 65*7c478bd9Sstevel@tonic-gate */ 66*7c478bd9Sstevel@tonic-gate int 67*7c478bd9Sstevel@tonic-gate gethead(int current, int all) 68*7c478bd9Sstevel@tonic-gate { 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate int displayed = 0; 71*7c478bd9Sstevel@tonic-gate FILE *file; 72*7c478bd9Sstevel@tonic-gate char *hold; 73*7c478bd9Sstevel@tonic-gate char holdval[MAXHDRSIZE]; 74*7c478bd9Sstevel@tonic-gate char *wline; 75*7c478bd9Sstevel@tonic-gate char wlineval[MAXHDRSIZE]; 76*7c478bd9Sstevel@tonic-gate int ln; 77*7c478bd9Sstevel@tonic-gate char mark; 78*7c478bd9Sstevel@tonic-gate int rc, size, start, stop, ix; 79*7c478bd9Sstevel@tonic-gate char userval[MAXUNAME]; 80*7c478bd9Sstevel@tonic-gate char *uucpptr; 81*7c478bd9Sstevel@tonic-gate int uucpstart; 82*7c478bd9Sstevel@tonic-gate int unamechars = MAXUNAME - 1; 83*7c478bd9Sstevel@tonic-gate int sender_size; 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate hold = holdval; 86*7c478bd9Sstevel@tonic-gate wline = wlineval; 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate printf("%d letters found in %s, %d scheduled for deletion, " 89*7c478bd9Sstevel@tonic-gate "%d newly arrived\n", nlet, mailfile, changed, nlet - onlet); 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate if (all == 2 && !changed) 92*7c478bd9Sstevel@tonic-gate return (0); 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate file = doopen(lettmp, "r", E_TMP); 95*7c478bd9Sstevel@tonic-gate if (!flgr) { 96*7c478bd9Sstevel@tonic-gate stop = current - 6; 97*7c478bd9Sstevel@tonic-gate if (stop < -1) stop = -1; 98*7c478bd9Sstevel@tonic-gate start = current + 5; 99*7c478bd9Sstevel@tonic-gate if (start > nlet - 1) start = nlet - 1; 100*7c478bd9Sstevel@tonic-gate if (all) { 101*7c478bd9Sstevel@tonic-gate start = nlet -1; 102*7c478bd9Sstevel@tonic-gate stop = -1; 103*7c478bd9Sstevel@tonic-gate } 104*7c478bd9Sstevel@tonic-gate } else { 105*7c478bd9Sstevel@tonic-gate stop = current + 6; 106*7c478bd9Sstevel@tonic-gate if (stop > nlet) stop = nlet; 107*7c478bd9Sstevel@tonic-gate start = current - 5; 108*7c478bd9Sstevel@tonic-gate if (start < 0) start = 0; 109*7c478bd9Sstevel@tonic-gate if (all) { 110*7c478bd9Sstevel@tonic-gate start = 0; 111*7c478bd9Sstevel@tonic-gate stop = nlet; 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate } 114*7c478bd9Sstevel@tonic-gate for (ln = start; ln != stop; ln = flgr ? ln + 1 : ln - 1) { 115*7c478bd9Sstevel@tonic-gate size = let[ln+1].adr - let[ln].adr; 116*7c478bd9Sstevel@tonic-gate if ((rc = fseek(file, let[ln].adr, 0)) != 0) { 117*7c478bd9Sstevel@tonic-gate errmsg(E_FILE, "Cannot seek header"); 118*7c478bd9Sstevel@tonic-gate fclose(file); 119*7c478bd9Sstevel@tonic-gate return (1); 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate if (fgets(wline, MAXHDRSIZE, file) == NULL) { 122*7c478bd9Sstevel@tonic-gate errmsg(E_FILE, "Cannot read header"); 123*7c478bd9Sstevel@tonic-gate fclose(file); 124*7c478bd9Sstevel@tonic-gate return (1); 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate if ((rc = strncmp(wline, header[H_FROM].tag, 5)) != SAME) { 127*7c478bd9Sstevel@tonic-gate errmsg(E_FILE, "Invalid header encountered"); 128*7c478bd9Sstevel@tonic-gate fclose(file); 129*7c478bd9Sstevel@tonic-gate return (1); 130*7c478bd9Sstevel@tonic-gate } 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate /* skip past trailing white space after header tag */ 133*7c478bd9Sstevel@tonic-gate for (rc = 5; wline[rc] == ' ' || wline[rc] == '\t'; ++rc); 134*7c478bd9Sstevel@tonic-gate (void) strlcpy(hold, wline + rc, MAXHDRSIZE); 135*7c478bd9Sstevel@tonic-gate fgets(wline, MAXHDRSIZE, file); 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate while (((rc = strncmp(wline, 138*7c478bd9Sstevel@tonic-gate header[H_FROM1].tag, 6)) == SAME) && 139*7c478bd9Sstevel@tonic-gate (substr(wline, "remote from ") != -1)) { 140*7c478bd9Sstevel@tonic-gate (void) strlcpy(hold, wline + 6, MAXHDRSIZE); 141*7c478bd9Sstevel@tonic-gate fgets(wline, MAXHDRSIZE, file); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate /* 146*7c478bd9Sstevel@tonic-gate * If UUCP-style sender address, then read past 147*7c478bd9Sstevel@tonic-gate * last "!" to get the start of the user name. 148*7c478bd9Sstevel@tonic-gate */ 149*7c478bd9Sstevel@tonic-gate sender_size = strcspn(hold, " \t"); 150*7c478bd9Sstevel@tonic-gate uucpstart = 0; 151*7c478bd9Sstevel@tonic-gate if ((uucpptr = strrchr(hold, '!')) != NULL) { 152*7c478bd9Sstevel@tonic-gate uucpstart = uucpptr - hold + 1; 153*7c478bd9Sstevel@tonic-gate if (uucpstart > sender_size) { 154*7c478bd9Sstevel@tonic-gate uucpstart = 0; 155*7c478bd9Sstevel@tonic-gate } 156*7c478bd9Sstevel@tonic-gate } 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate /* Get the user name out of the sender address. */ 159*7c478bd9Sstevel@tonic-gate for (ix = 0, rc = uucpstart; ix < unamechars && 160*7c478bd9Sstevel@tonic-gate hold[rc] != ' ' && hold[rc] != '\t' && 161*7c478bd9Sstevel@tonic-gate rc < sender_size; ++rc) { 162*7c478bd9Sstevel@tonic-gate userval[ix++] = hold[rc]; 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate if ((ix > 0) && (userval[ix - 1] == '\n')) { 165*7c478bd9Sstevel@tonic-gate userval[ix - 1] = '\0'; 166*7c478bd9Sstevel@tonic-gate } else { 167*7c478bd9Sstevel@tonic-gate userval[ix] = '\0'; 168*7c478bd9Sstevel@tonic-gate } 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate /* 171*7c478bd9Sstevel@tonic-gate * Skip past the rest of the sender address, and 172*7c478bd9Sstevel@tonic-gate * delimiting white space. 173*7c478bd9Sstevel@tonic-gate */ 174*7c478bd9Sstevel@tonic-gate for (; hold[rc] != '\0' && hold[rc] != ' ' && 175*7c478bd9Sstevel@tonic-gate hold[rc] != '\t'; ++rc); 176*7c478bd9Sstevel@tonic-gate for (; hold[rc] == ' ' || hold[rc] == '\t'; ++rc); 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate /* Get the date information. */ 179*7c478bd9Sstevel@tonic-gate (void) strlcpy(wline, hold + rc, MAXHDRSIZE); 180*7c478bd9Sstevel@tonic-gate for (rc = 0; wline[rc] != '\0' && wline[rc] != '\n'; ++rc); 181*7c478bd9Sstevel@tonic-gate wline[rc] = '\0'; 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate if (!flgh && current == ln) mark = '>'; 184*7c478bd9Sstevel@tonic-gate else mark = ' '; 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate if (all == 2) { 187*7c478bd9Sstevel@tonic-gate if (displayed >= changed) { 188*7c478bd9Sstevel@tonic-gate fclose(file); 189*7c478bd9Sstevel@tonic-gate return (0); 190*7c478bd9Sstevel@tonic-gate } 191*7c478bd9Sstevel@tonic-gate if (let[ln].change == ' ') continue; 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate printf("%c %3d %c %-5d %-10s %s\n", mark, ln + 1, 195*7c478bd9Sstevel@tonic-gate let[ln].change, size, userval, wline); 196*7c478bd9Sstevel@tonic-gate displayed++; 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate fclose(file); 199*7c478bd9Sstevel@tonic-gate return (0); 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate void 203*7c478bd9Sstevel@tonic-gate tmperr() 204*7c478bd9Sstevel@tonic-gate { 205*7c478bd9Sstevel@tonic-gate fclose(tmpf); 206*7c478bd9Sstevel@tonic-gate errmsg(E_TMP, ""); 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate /* 210*7c478bd9Sstevel@tonic-gate * Write a string out to tmp file, with error checking. 211*7c478bd9Sstevel@tonic-gate * Return 1 on success, else 0 212*7c478bd9Sstevel@tonic-gate */ 213*7c478bd9Sstevel@tonic-gate wtmpf(str, length) 214*7c478bd9Sstevel@tonic-gate char *str; 215*7c478bd9Sstevel@tonic-gate { 216*7c478bd9Sstevel@tonic-gate if (fwrite(str, 1, length, tmpf) != length) { 217*7c478bd9Sstevel@tonic-gate tmperr(); 218*7c478bd9Sstevel@tonic-gate return (0); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate return (1); 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate /* 224*7c478bd9Sstevel@tonic-gate * Read a line from stdin, assign it to line and 225*7c478bd9Sstevel@tonic-gate * return number of bytes in length 226*7c478bd9Sstevel@tonic-gate */ 227*7c478bd9Sstevel@tonic-gate int 228*7c478bd9Sstevel@tonic-gate getline(ptr2line, max, f) 229*7c478bd9Sstevel@tonic-gate char *ptr2line; 230*7c478bd9Sstevel@tonic-gate int max; 231*7c478bd9Sstevel@tonic-gate FILE *f; 232*7c478bd9Sstevel@tonic-gate { 233*7c478bd9Sstevel@tonic-gate int i, ch; 234*7c478bd9Sstevel@tonic-gate for (i = 0; i < max-1 && (ch = getc(f)) != EOF; ) 235*7c478bd9Sstevel@tonic-gate if ((ptr2line[i++] = ch) == '\n') break; 236*7c478bd9Sstevel@tonic-gate ptr2line[i] = '\0'; 237*7c478bd9Sstevel@tonic-gate return (i); 238*7c478bd9Sstevel@tonic-gate } 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate /* 241*7c478bd9Sstevel@tonic-gate * Make temporary file for letter 242*7c478bd9Sstevel@tonic-gate */ 243*7c478bd9Sstevel@tonic-gate void 244*7c478bd9Sstevel@tonic-gate mktmp() 245*7c478bd9Sstevel@tonic-gate { 246*7c478bd9Sstevel@tonic-gate static char tmpl[] = "/var/tmp/mailXXXXXX"; 247*7c478bd9Sstevel@tonic-gate int fd = mkstemp(lettmp = tmpl); 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate if (fd < 0 || (tmpf = fdopen(fd, "w+")) == NULL) { 250*7c478bd9Sstevel@tonic-gate fprintf(stderr, 251*7c478bd9Sstevel@tonic-gate "%s: Can't open '%s', type: w+\n", program, lettmp); 252*7c478bd9Sstevel@tonic-gate done(0); 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate /* 257*7c478bd9Sstevel@tonic-gate * Get a number from user's reply, 258*7c478bd9Sstevel@tonic-gate * return its value or zero if none present, -1 on error 259*7c478bd9Sstevel@tonic-gate */ 260*7c478bd9Sstevel@tonic-gate getnumbr(s) 261*7c478bd9Sstevel@tonic-gate char *s; 262*7c478bd9Sstevel@tonic-gate { 263*7c478bd9Sstevel@tonic-gate int k = 0; 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate while (*s == ' ' || *s == '\t') s++; 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate if (*s != '\0') { 268*7c478bd9Sstevel@tonic-gate if ((k = atoi(s)) != 0) 269*7c478bd9Sstevel@tonic-gate if (!validmsg(k)) 270*7c478bd9Sstevel@tonic-gate return (-1); 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate for (; *s >= '0' && *s <= '9'; ) s++; 273*7c478bd9Sstevel@tonic-gate if (*s != '\0' && *s != '\n') { 274*7c478bd9Sstevel@tonic-gate printf("Illegal numeric\n"); 275*7c478bd9Sstevel@tonic-gate return (-1); 276*7c478bd9Sstevel@tonic-gate } 277*7c478bd9Sstevel@tonic-gate return (k); 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate return (0); 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate /* 283*7c478bd9Sstevel@tonic-gate * If valid msgnum return 1, 284*7c478bd9Sstevel@tonic-gate * else print message and return 0 285*7c478bd9Sstevel@tonic-gate */ 286*7c478bd9Sstevel@tonic-gate validmsg(i) 287*7c478bd9Sstevel@tonic-gate { 288*7c478bd9Sstevel@tonic-gate if ((i < 0) || (i > nlet)) { 289*7c478bd9Sstevel@tonic-gate printf("No such message\n"); 290*7c478bd9Sstevel@tonic-gate return (0); 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate return (1); 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate /* 296*7c478bd9Sstevel@tonic-gate * Set letter to passed status, and adjust changed as necessary 297*7c478bd9Sstevel@tonic-gate */ 298*7c478bd9Sstevel@tonic-gate void 299*7c478bd9Sstevel@tonic-gate setletr(letter, status) 300*7c478bd9Sstevel@tonic-gate int letter; 301*7c478bd9Sstevel@tonic-gate int status; 302*7c478bd9Sstevel@tonic-gate { 303*7c478bd9Sstevel@tonic-gate if (status == ' ') { 304*7c478bd9Sstevel@tonic-gate if (let[letter].change != ' ') 305*7c478bd9Sstevel@tonic-gate if (changed) changed--; 306*7c478bd9Sstevel@tonic-gate } else { 307*7c478bd9Sstevel@tonic-gate if (let[letter].change == ' ') changed++; 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate let[letter].change = status; 310*7c478bd9Sstevel@tonic-gate } 311