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