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 2004 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 * Print mail entries 36*7c478bd9Sstevel@tonic-gate */ 37*7c478bd9Sstevel@tonic-gate void 38*7c478bd9Sstevel@tonic-gate printmail() 39*7c478bd9Sstevel@tonic-gate { 40*7c478bd9Sstevel@tonic-gate static char pn[] = "printmail"; 41*7c478bd9Sstevel@tonic-gate int flg, curlet, showlet, k, print, aret, stret, rc; 42*7c478bd9Sstevel@tonic-gate int nsmbox = 0; /* 1 ==> mailbox is in non-standard place */ 43*7c478bd9Sstevel@tonic-gate int sav_j = -1; 44*7c478bd9Sstevel@tonic-gate char *p, *getarg(); 45*7c478bd9Sstevel@tonic-gate struct stat stbuf; 46*7c478bd9Sstevel@tonic-gate struct stat *stbufp; 47*7c478bd9Sstevel@tonic-gate int ttyf = isatty(1) ? TTY : ORDINARY; 48*7c478bd9Sstevel@tonic-gate char readbuf[LSIZE]; /* holds user's response in interactive mode */ 49*7c478bd9Sstevel@tonic-gate char *resp; 50*7c478bd9Sstevel@tonic-gate gid_t savedegid; 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate stbufp = &stbuf; 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate /* 55*7c478bd9Sstevel@tonic-gate * create working directory mbox name 56*7c478bd9Sstevel@tonic-gate */ 57*7c478bd9Sstevel@tonic-gate if ((hmbox = malloc(strlen(home) + strlen(mbox) + 1)) == NULL) { 58*7c478bd9Sstevel@tonic-gate errmsg(E_MBOX, ""); 59*7c478bd9Sstevel@tonic-gate return; 60*7c478bd9Sstevel@tonic-gate } 61*7c478bd9Sstevel@tonic-gate cat(hmbox, home, mbox); 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate /* 64*7c478bd9Sstevel@tonic-gate * If we are not using an alternate mailfile, then get 65*7c478bd9Sstevel@tonic-gate * the $MAIL value and build the filename for the mailfile. 66*7c478bd9Sstevel@tonic-gate * If $MAIL is set, but is NOT the 'standard' place, then 67*7c478bd9Sstevel@tonic-gate * use it but set flgf to circumvent :saved processing. 68*7c478bd9Sstevel@tonic-gate */ 69*7c478bd9Sstevel@tonic-gate if (!flgf) { 70*7c478bd9Sstevel@tonic-gate if ((p = malloc(strlen(maildir) + strlen(my_name) + 1)) 71*7c478bd9Sstevel@tonic-gate == NULL) { 72*7c478bd9Sstevel@tonic-gate errmsg(E_MEM, ""); 73*7c478bd9Sstevel@tonic-gate return; 74*7c478bd9Sstevel@tonic-gate } 75*7c478bd9Sstevel@tonic-gate cat(p, maildir, my_name); 76*7c478bd9Sstevel@tonic-gate if (((mailfile = getenv("MAIL")) == NULL) || 77*7c478bd9Sstevel@tonic-gate (strlen(mailfile) == 0)) { 78*7c478bd9Sstevel@tonic-gate /* $MAIL not set, use standard path to mailfile */ 79*7c478bd9Sstevel@tonic-gate mailfile = p; 80*7c478bd9Sstevel@tonic-gate } else { 81*7c478bd9Sstevel@tonic-gate if (strcmp(mailfile, p) != 0) { 82*7c478bd9Sstevel@tonic-gate flgf = 1; 83*7c478bd9Sstevel@tonic-gate nsmbox = 1; 84*7c478bd9Sstevel@tonic-gate Dout(pn, 0, "$MAIL ('%s') != standard path\n", 85*7c478bd9Sstevel@tonic-gate mailfile); 86*7c478bd9Sstevel@tonic-gate Dout("", 0, "\tSetting flgf to 1.\n"); 87*7c478bd9Sstevel@tonic-gate } 88*7c478bd9Sstevel@tonic-gate free(p); 89*7c478bd9Sstevel@tonic-gate } 90*7c478bd9Sstevel@tonic-gate } 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gate /* 93*7c478bd9Sstevel@tonic-gate * Get ACCESS and MODIFICATION times of mailfile BEFORE we 94*7c478bd9Sstevel@tonic-gate * use it. This allows us to put them back when we are 95*7c478bd9Sstevel@tonic-gate * done. If we didn't, the shell would think NEW mail had 96*7c478bd9Sstevel@tonic-gate * arrived since the file times would have changed. 97*7c478bd9Sstevel@tonic-gate */ 98*7c478bd9Sstevel@tonic-gate stret = CERROR; 99*7c478bd9Sstevel@tonic-gate if (access(mailfile, A_EXIST) == A_OK) { 100*7c478bd9Sstevel@tonic-gate if ((stret = stat(mailfile, stbufp)) != A_OK) { 101*7c478bd9Sstevel@tonic-gate errmsg(E_FILE, "Cannot stat mailfile"); 102*7c478bd9Sstevel@tonic-gate return; 103*7c478bd9Sstevel@tonic-gate } 104*7c478bd9Sstevel@tonic-gate mf_gid = stbufp->st_gid; 105*7c478bd9Sstevel@tonic-gate mf_uid = stbufp->st_uid; 106*7c478bd9Sstevel@tonic-gate utimep->actime = stbufp->st_atime; 107*7c478bd9Sstevel@tonic-gate utimep->modtime = stbufp->st_mtime; 108*7c478bd9Sstevel@tonic-gate file_size = stbufp->st_size; 109*7c478bd9Sstevel@tonic-gate } 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate /* Open the file as the real gid */ 112*7c478bd9Sstevel@tonic-gate savedegid = getegid(); 113*7c478bd9Sstevel@tonic-gate (void) setegid(getgid()); 114*7c478bd9Sstevel@tonic-gate malf = fopen(mailfile, "r"); 115*7c478bd9Sstevel@tonic-gate (void) setegid(savedegid); 116*7c478bd9Sstevel@tonic-gate /* 117*7c478bd9Sstevel@tonic-gate * stat succeeded, but we cannot access the mailfile 118*7c478bd9Sstevel@tonic-gate */ 119*7c478bd9Sstevel@tonic-gate if (stret == CSUCCESS && malf == NULL) { 120*7c478bd9Sstevel@tonic-gate char buf[MAXFILENAME+50]; 121*7c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), 122*7c478bd9Sstevel@tonic-gate "Invalid permissions on %s", mailfile); 123*7c478bd9Sstevel@tonic-gate errmsg(E_PERM, buf); 124*7c478bd9Sstevel@tonic-gate return; 125*7c478bd9Sstevel@tonic-gate } else 126*7c478bd9Sstevel@tonic-gate /* 127*7c478bd9Sstevel@tonic-gate * using an alternate mailfile, but we failed on access 128*7c478bd9Sstevel@tonic-gate */ 129*7c478bd9Sstevel@tonic-gate if (!nsmbox && flgf && (malf == NULL)) { 130*7c478bd9Sstevel@tonic-gate errmsg(E_FILE, "Cannot open mailfile"); 131*7c478bd9Sstevel@tonic-gate return; 132*7c478bd9Sstevel@tonic-gate } 133*7c478bd9Sstevel@tonic-gate /* 134*7c478bd9Sstevel@tonic-gate * we failed to access OR the file is empty 135*7c478bd9Sstevel@tonic-gate */ 136*7c478bd9Sstevel@tonic-gate else if ((malf == NULL) || (stbuf.st_size == 0)) { 137*7c478bd9Sstevel@tonic-gate if (!flge && !flgE) { 138*7c478bd9Sstevel@tonic-gate printf("No mail.\n"); 139*7c478bd9Sstevel@tonic-gate } 140*7c478bd9Sstevel@tonic-gate error = E_FLGE; 141*7c478bd9Sstevel@tonic-gate Dout(pn, 0, "error set to %d\n", error); 142*7c478bd9Sstevel@tonic-gate return; 143*7c478bd9Sstevel@tonic-gate } 144*7c478bd9Sstevel@tonic-gate if (flge) 145*7c478bd9Sstevel@tonic-gate return; 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate if (flgE) { 148*7c478bd9Sstevel@tonic-gate if (utimep->modtime < utimep->actime) { 149*7c478bd9Sstevel@tonic-gate error = E_FLGE_OM; 150*7c478bd9Sstevel@tonic-gate Dout(pn, 0, "error set to %d\n", error); 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate return; 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate /* 155*7c478bd9Sstevel@tonic-gate * Secure the mailfile to guarantee integrity 156*7c478bd9Sstevel@tonic-gate */ 157*7c478bd9Sstevel@tonic-gate lock(my_name); 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate /* 160*7c478bd9Sstevel@tonic-gate * copy mail to temp file and mark each letter in the 161*7c478bd9Sstevel@tonic-gate * let array --- mailfile is still locked !!! 162*7c478bd9Sstevel@tonic-gate */ 163*7c478bd9Sstevel@tonic-gate mktmp(); 164*7c478bd9Sstevel@tonic-gate copymt(malf, tmpf); 165*7c478bd9Sstevel@tonic-gate onlet = nlet; 166*7c478bd9Sstevel@tonic-gate fclose(malf); 167*7c478bd9Sstevel@tonic-gate fclose(tmpf); 168*7c478bd9Sstevel@tonic-gate unlock(); /* All done, OK to unlock now */ 169*7c478bd9Sstevel@tonic-gate tmpf = doopen(lettmp, "r+", E_TMP); 170*7c478bd9Sstevel@tonic-gate changed = 0; 171*7c478bd9Sstevel@tonic-gate print = 1; 172*7c478bd9Sstevel@tonic-gate curlet = 0; 173*7c478bd9Sstevel@tonic-gate while (curlet < nlet) { 174*7c478bd9Sstevel@tonic-gate /* 175*7c478bd9Sstevel@tonic-gate * reverse order ? 176*7c478bd9Sstevel@tonic-gate */ 177*7c478bd9Sstevel@tonic-gate showlet = flgr ? curlet : nlet - curlet - 1; 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate if (setjmp(sjbuf) == 0 && print != 0) { 180*7c478bd9Sstevel@tonic-gate /* -h says to print the headers first */ 181*7c478bd9Sstevel@tonic-gate if (flgh) { 182*7c478bd9Sstevel@tonic-gate gethead(showlet, 0); 183*7c478bd9Sstevel@tonic-gate flgh = 0; /* Only once */ 184*7c478bd9Sstevel@tonic-gate /* set letter # to invalid # */ 185*7c478bd9Sstevel@tonic-gate curlet--; 186*7c478bd9Sstevel@tonic-gate showlet = 187*7c478bd9Sstevel@tonic-gate flgr ? curlet : nlet - curlet - 1; 188*7c478bd9Sstevel@tonic-gate } else { 189*7c478bd9Sstevel@tonic-gate if (showlet != sav_j) { 190*7c478bd9Sstevel@tonic-gate /* Looking at new message. */ 191*7c478bd9Sstevel@tonic-gate /* Reset flag to override */ 192*7c478bd9Sstevel@tonic-gate /* non-display of binary */ 193*7c478bd9Sstevel@tonic-gate /* contents */ 194*7c478bd9Sstevel@tonic-gate sav_j = showlet; 195*7c478bd9Sstevel@tonic-gate pflg = 0; 196*7c478bd9Sstevel@tonic-gate Pflg = flgP; 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate copylet(showlet, stdout, ttyf); 199*7c478bd9Sstevel@tonic-gate } 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate /* 203*7c478bd9Sstevel@tonic-gate * print only 204*7c478bd9Sstevel@tonic-gate */ 205*7c478bd9Sstevel@tonic-gate if (flgp) { 206*7c478bd9Sstevel@tonic-gate curlet++; 207*7c478bd9Sstevel@tonic-gate continue; 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate /* 210*7c478bd9Sstevel@tonic-gate * Interactive 211*7c478bd9Sstevel@tonic-gate */ 212*7c478bd9Sstevel@tonic-gate interactive = 1; 213*7c478bd9Sstevel@tonic-gate setjmp(sjbuf); 214*7c478bd9Sstevel@tonic-gate stat(mailfile, stbufp); 215*7c478bd9Sstevel@tonic-gate if (stbufp->st_size != file_size) { 216*7c478bd9Sstevel@tonic-gate /* 217*7c478bd9Sstevel@tonic-gate * New mail has arrived, load it 218*7c478bd9Sstevel@tonic-gate */ 219*7c478bd9Sstevel@tonic-gate k = nlet; 220*7c478bd9Sstevel@tonic-gate lock(my_name); 221*7c478bd9Sstevel@tonic-gate malf = doopen(mailfile, "r", E_FILE); 222*7c478bd9Sstevel@tonic-gate fclose(tmpf); 223*7c478bd9Sstevel@tonic-gate tmpf = doopen(lettmp, "a", E_TMP); 224*7c478bd9Sstevel@tonic-gate fseek(malf, let[nlet].adr, 0); 225*7c478bd9Sstevel@tonic-gate copymt(malf, tmpf); 226*7c478bd9Sstevel@tonic-gate file_size = stbufp->st_size; 227*7c478bd9Sstevel@tonic-gate fclose(malf); 228*7c478bd9Sstevel@tonic-gate fclose(tmpf); 229*7c478bd9Sstevel@tonic-gate unlock(); 230*7c478bd9Sstevel@tonic-gate tmpf = doopen(lettmp, "r+", E_TMP); 231*7c478bd9Sstevel@tonic-gate if (++k < nlet) 232*7c478bd9Sstevel@tonic-gate printf("New mail loaded into letters %d - %d\n", 233*7c478bd9Sstevel@tonic-gate k, nlet); 234*7c478bd9Sstevel@tonic-gate else 235*7c478bd9Sstevel@tonic-gate printf("New mail loaded into letter %d\n", 236*7c478bd9Sstevel@tonic-gate nlet); 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate /* read the command */ 240*7c478bd9Sstevel@tonic-gate printf("? "); 241*7c478bd9Sstevel@tonic-gate fflush(stdout); 242*7c478bd9Sstevel@tonic-gate fflush(stderr); 243*7c478bd9Sstevel@tonic-gate if (fgets(readbuf, sizeof (readbuf), stdin) == NULL) break; 244*7c478bd9Sstevel@tonic-gate resp = readbuf; 245*7c478bd9Sstevel@tonic-gate while (*resp == ' ' || *resp == '\t') resp++; 246*7c478bd9Sstevel@tonic-gate print = 1; 247*7c478bd9Sstevel@tonic-gate Dout(pn, 0, "resp = '%s'\n", resp); 248*7c478bd9Sstevel@tonic-gate if ((rc = atoi(resp)) != 0) { 249*7c478bd9Sstevel@tonic-gate if (!validmsg(rc)) print = 0; 250*7c478bd9Sstevel@tonic-gate else curlet = flgr ? rc - 1 : nlet - rc; 251*7c478bd9Sstevel@tonic-gate } else switch (resp[0]) { 252*7c478bd9Sstevel@tonic-gate default: 253*7c478bd9Sstevel@tonic-gate printf("Usage:\n"); 254*7c478bd9Sstevel@tonic-gate /* 255*7c478bd9Sstevel@tonic-gate * help 256*7c478bd9Sstevel@tonic-gate */ 257*7c478bd9Sstevel@tonic-gate case '?': 258*7c478bd9Sstevel@tonic-gate print = 0; 259*7c478bd9Sstevel@tonic-gate for (rc = 0; help[rc]; rc++) 260*7c478bd9Sstevel@tonic-gate printf("%s", help[rc]); 261*7c478bd9Sstevel@tonic-gate break; 262*7c478bd9Sstevel@tonic-gate /* 263*7c478bd9Sstevel@tonic-gate * print message number of current message 264*7c478bd9Sstevel@tonic-gate */ 265*7c478bd9Sstevel@tonic-gate case '#': 266*7c478bd9Sstevel@tonic-gate print = 0; 267*7c478bd9Sstevel@tonic-gate if ((showlet == nlet) || (showlet < 0)) { 268*7c478bd9Sstevel@tonic-gate printf("No message selected yet.\n"); 269*7c478bd9Sstevel@tonic-gate } else { 270*7c478bd9Sstevel@tonic-gate printf("Current message number is %d\n", 271*7c478bd9Sstevel@tonic-gate showlet+1); 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate break; 274*7c478bd9Sstevel@tonic-gate /* 275*7c478bd9Sstevel@tonic-gate * headers 276*7c478bd9Sstevel@tonic-gate */ 277*7c478bd9Sstevel@tonic-gate case 'h': 278*7c478bd9Sstevel@tonic-gate print = 0; 279*7c478bd9Sstevel@tonic-gate if (resp[2] != 'd' && 280*7c478bd9Sstevel@tonic-gate resp[2] != 'a' && 281*7c478bd9Sstevel@tonic-gate (rc = getnumbr(resp+1)) > 0) { 282*7c478bd9Sstevel@tonic-gate showlet = rc - 1; 283*7c478bd9Sstevel@tonic-gate curlet = flgr ? rc - 1 : nlet - rc- 1; 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate if (rc == -1 && resp[2] != 'a' && 286*7c478bd9Sstevel@tonic-gate resp[2] != 'd') 287*7c478bd9Sstevel@tonic-gate break; 288*7c478bd9Sstevel@tonic-gate if (resp[2] == 'a') rc = 1; 289*7c478bd9Sstevel@tonic-gate else if (resp[2] == 'd') rc = 2; 290*7c478bd9Sstevel@tonic-gate else rc = 0; 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate /* 293*7c478bd9Sstevel@tonic-gate * if (!validmsg(showlet)) break; 294*7c478bd9Sstevel@tonic-gate */ 295*7c478bd9Sstevel@tonic-gate gethead(showlet, rc); 296*7c478bd9Sstevel@tonic-gate break; 297*7c478bd9Sstevel@tonic-gate /* 298*7c478bd9Sstevel@tonic-gate * skip entry 299*7c478bd9Sstevel@tonic-gate */ 300*7c478bd9Sstevel@tonic-gate case '+': 301*7c478bd9Sstevel@tonic-gate case 'n': 302*7c478bd9Sstevel@tonic-gate case '\n': 303*7c478bd9Sstevel@tonic-gate curlet++; 304*7c478bd9Sstevel@tonic-gate break; 305*7c478bd9Sstevel@tonic-gate case 'P': 306*7c478bd9Sstevel@tonic-gate Pflg++; 307*7c478bd9Sstevel@tonic-gate break; 308*7c478bd9Sstevel@tonic-gate case 'p': 309*7c478bd9Sstevel@tonic-gate pflg++; 310*7c478bd9Sstevel@tonic-gate break; 311*7c478bd9Sstevel@tonic-gate case 'x': 312*7c478bd9Sstevel@tonic-gate changed = 0; 313*7c478bd9Sstevel@tonic-gate case 'q': 314*7c478bd9Sstevel@tonic-gate goto donep; 315*7c478bd9Sstevel@tonic-gate /* 316*7c478bd9Sstevel@tonic-gate * Previous entry 317*7c478bd9Sstevel@tonic-gate */ 318*7c478bd9Sstevel@tonic-gate case '^': 319*7c478bd9Sstevel@tonic-gate case '-': 320*7c478bd9Sstevel@tonic-gate if (--curlet < 0) curlet = 0; 321*7c478bd9Sstevel@tonic-gate break; 322*7c478bd9Sstevel@tonic-gate /* 323*7c478bd9Sstevel@tonic-gate * Save in file without header 324*7c478bd9Sstevel@tonic-gate */ 325*7c478bd9Sstevel@tonic-gate case 'y': 326*7c478bd9Sstevel@tonic-gate case 'w': 327*7c478bd9Sstevel@tonic-gate /* 328*7c478bd9Sstevel@tonic-gate * Save mail with header 329*7c478bd9Sstevel@tonic-gate */ 330*7c478bd9Sstevel@tonic-gate case 's': 331*7c478bd9Sstevel@tonic-gate print = 0; 332*7c478bd9Sstevel@tonic-gate if (!validmsg(curlet)) break; 333*7c478bd9Sstevel@tonic-gate if (resp[1] == '\n' || resp[1] == '\0') { 334*7c478bd9Sstevel@tonic-gate cat(resp+1, hmbox, ""); 335*7c478bd9Sstevel@tonic-gate } else if (resp[1] != ' ') { 336*7c478bd9Sstevel@tonic-gate printf("Invalid command\n"); 337*7c478bd9Sstevel@tonic-gate break; 338*7c478bd9Sstevel@tonic-gate } 339*7c478bd9Sstevel@tonic-gate umask(umsave); 340*7c478bd9Sstevel@tonic-gate flg = 0; 341*7c478bd9Sstevel@tonic-gate if (getarg(lfil, resp + 1) == NULL) { 342*7c478bd9Sstevel@tonic-gate cat(resp + 1, hmbox, ""); 343*7c478bd9Sstevel@tonic-gate } 344*7c478bd9Sstevel@tonic-gate malf = (FILE *)NULL; 345*7c478bd9Sstevel@tonic-gate p = resp + 1; 346*7c478bd9Sstevel@tonic-gate while ((p = getarg(lfil, p)) != NULL) { 347*7c478bd9Sstevel@tonic-gate if (flg) { 348*7c478bd9Sstevel@tonic-gate fprintf(stderr, 349*7c478bd9Sstevel@tonic-gate "%s: File '%s' skipped\n", 350*7c478bd9Sstevel@tonic-gate program, lfil); 351*7c478bd9Sstevel@tonic-gate continue; 352*7c478bd9Sstevel@tonic-gate } 353*7c478bd9Sstevel@tonic-gate malf = NULL; 354*7c478bd9Sstevel@tonic-gate if ((aret = legal(lfil))) { 355*7c478bd9Sstevel@tonic-gate malf = fopen(lfil, "a"); 356*7c478bd9Sstevel@tonic-gate } 357*7c478bd9Sstevel@tonic-gate if ((malf == NULL) || (aret == 0)) { 358*7c478bd9Sstevel@tonic-gate fprintf(stderr, 359*7c478bd9Sstevel@tonic-gate "%s: Cannot append to %s\n", 360*7c478bd9Sstevel@tonic-gate program, lfil); 361*7c478bd9Sstevel@tonic-gate flg++; 362*7c478bd9Sstevel@tonic-gate } else if (aret == 2) { 363*7c478bd9Sstevel@tonic-gate chown(lfil, my_euid, my_gid); 364*7c478bd9Sstevel@tonic-gate } 365*7c478bd9Sstevel@tonic-gate if (!flg && 366*7c478bd9Sstevel@tonic-gate copylet(showlet, malf, resp[0] == 367*7c478bd9Sstevel@tonic-gate 's'? ORDINARY: ZAP) == FALSE) { 368*7c478bd9Sstevel@tonic-gate fprintf(stderr, 369*7c478bd9Sstevel@tonic-gate "%s: Cannot save mail to '%s'\n", 370*7c478bd9Sstevel@tonic-gate program, lfil); 371*7c478bd9Sstevel@tonic-gate flg++; 372*7c478bd9Sstevel@tonic-gate } else 373*7c478bd9Sstevel@tonic-gate Dout(pn, 0, "!saved\n"); 374*7c478bd9Sstevel@tonic-gate if (malf != (FILE *)NULL) { 375*7c478bd9Sstevel@tonic-gate fclose(malf); 376*7c478bd9Sstevel@tonic-gate } 377*7c478bd9Sstevel@tonic-gate } 378*7c478bd9Sstevel@tonic-gate umask(7); 379*7c478bd9Sstevel@tonic-gate if (!flg) { 380*7c478bd9Sstevel@tonic-gate setletr(showlet, resp[0]); 381*7c478bd9Sstevel@tonic-gate print = 1; 382*7c478bd9Sstevel@tonic-gate curlet++; 383*7c478bd9Sstevel@tonic-gate } 384*7c478bd9Sstevel@tonic-gate break; 385*7c478bd9Sstevel@tonic-gate /* 386*7c478bd9Sstevel@tonic-gate * Reply to a letter 387*7c478bd9Sstevel@tonic-gate */ 388*7c478bd9Sstevel@tonic-gate case 'r': 389*7c478bd9Sstevel@tonic-gate print = 0; 390*7c478bd9Sstevel@tonic-gate if (!validmsg(curlet)) break; 391*7c478bd9Sstevel@tonic-gate replying = 1; 392*7c478bd9Sstevel@tonic-gate for (k = 1; resp[k] == ' ' || resp[k] == '\t'; 393*7c478bd9Sstevel@tonic-gate ++k); 394*7c478bd9Sstevel@tonic-gate resp[strlen(resp)-1] = '\0'; 395*7c478bd9Sstevel@tonic-gate (void) strlcpy(m_sendto, resp+k, 396*7c478bd9Sstevel@tonic-gate sizeof (m_sendto)); 397*7c478bd9Sstevel@tonic-gate goback(showlet); 398*7c478bd9Sstevel@tonic-gate replying = 0; 399*7c478bd9Sstevel@tonic-gate setletr(showlet, resp[0]); 400*7c478bd9Sstevel@tonic-gate break; 401*7c478bd9Sstevel@tonic-gate /* 402*7c478bd9Sstevel@tonic-gate * Undelete 403*7c478bd9Sstevel@tonic-gate */ 404*7c478bd9Sstevel@tonic-gate case 'u': 405*7c478bd9Sstevel@tonic-gate print = 0; 406*7c478bd9Sstevel@tonic-gate if ((k = getnumbr(resp+1)) <= 0) k = showlet; 407*7c478bd9Sstevel@tonic-gate else k--; 408*7c478bd9Sstevel@tonic-gate if (!validmsg(k)) break; 409*7c478bd9Sstevel@tonic-gate setletr(k, ' '); 410*7c478bd9Sstevel@tonic-gate break; 411*7c478bd9Sstevel@tonic-gate /* 412*7c478bd9Sstevel@tonic-gate * Mail letter to someone else 413*7c478bd9Sstevel@tonic-gate */ 414*7c478bd9Sstevel@tonic-gate case 'm': 415*7c478bd9Sstevel@tonic-gate { 416*7c478bd9Sstevel@tonic-gate reciplist list; 417*7c478bd9Sstevel@tonic-gate print = 0; 418*7c478bd9Sstevel@tonic-gate if (!validmsg(curlet)) break; 419*7c478bd9Sstevel@tonic-gate new_reciplist(&list); 420*7c478bd9Sstevel@tonic-gate flg = 0; 421*7c478bd9Sstevel@tonic-gate k = 0; 422*7c478bd9Sstevel@tonic-gate if (substr(resp, " -") != -1 || 423*7c478bd9Sstevel@tonic-gate substr(resp, "\t-") != -1) { 424*7c478bd9Sstevel@tonic-gate printf("Only users may be specified\n"); 425*7c478bd9Sstevel@tonic-gate break; 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate p = resp + 1; 428*7c478bd9Sstevel@tonic-gate while ((p = getarg(lfil, p)) != NULL) { 429*7c478bd9Sstevel@tonic-gate char *env; 430*7c478bd9Sstevel@tonic-gate if (lfil[0] == '$') { 431*7c478bd9Sstevel@tonic-gate if (!(env = getenv(&lfil[1]))) { 432*7c478bd9Sstevel@tonic-gate fprintf(stderr, 433*7c478bd9Sstevel@tonic-gate "%s: %s has no value or is not exported.\n", 434*7c478bd9Sstevel@tonic-gate program, lfil); 435*7c478bd9Sstevel@tonic-gate flg++; 436*7c478bd9Sstevel@tonic-gate } else 437*7c478bd9Sstevel@tonic-gate add_recip(&list, env, 438*7c478bd9Sstevel@tonic-gate FALSE); 439*7c478bd9Sstevel@tonic-gate k++; 440*7c478bd9Sstevel@tonic-gate } else if (lfil[0] != '\0') { 441*7c478bd9Sstevel@tonic-gate add_recip(&list, lfil, FALSE); 442*7c478bd9Sstevel@tonic-gate k++; 443*7c478bd9Sstevel@tonic-gate } 444*7c478bd9Sstevel@tonic-gate } 445*7c478bd9Sstevel@tonic-gate (void) strlcpy(Rpath, my_name, sizeof (Rpath)); 446*7c478bd9Sstevel@tonic-gate sending = TRUE; 447*7c478bd9Sstevel@tonic-gate flg += sendlist(&list, showlet, 0); 448*7c478bd9Sstevel@tonic-gate sending = FALSE; 449*7c478bd9Sstevel@tonic-gate if (k) { 450*7c478bd9Sstevel@tonic-gate if (!flg) { 451*7c478bd9Sstevel@tonic-gate setletr(showlet, 'm'); 452*7c478bd9Sstevel@tonic-gate print = 1; 453*7c478bd9Sstevel@tonic-gate curlet++; 454*7c478bd9Sstevel@tonic-gate } 455*7c478bd9Sstevel@tonic-gate } else 456*7c478bd9Sstevel@tonic-gate printf("Invalid command\n"); 457*7c478bd9Sstevel@tonic-gate del_reciplist(&list); 458*7c478bd9Sstevel@tonic-gate break; 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate /* 461*7c478bd9Sstevel@tonic-gate * Read new letters 462*7c478bd9Sstevel@tonic-gate */ 463*7c478bd9Sstevel@tonic-gate case 'a': 464*7c478bd9Sstevel@tonic-gate if (onlet == nlet) { 465*7c478bd9Sstevel@tonic-gate printf("No new mail\n"); 466*7c478bd9Sstevel@tonic-gate print = 0; 467*7c478bd9Sstevel@tonic-gate break; 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate curlet = 0; 470*7c478bd9Sstevel@tonic-gate print = 1; 471*7c478bd9Sstevel@tonic-gate break; 472*7c478bd9Sstevel@tonic-gate /* 473*7c478bd9Sstevel@tonic-gate * Escape to shell 474*7c478bd9Sstevel@tonic-gate */ 475*7c478bd9Sstevel@tonic-gate case '!': 476*7c478bd9Sstevel@tonic-gate systm(resp + 1); 477*7c478bd9Sstevel@tonic-gate printf("!\n"); 478*7c478bd9Sstevel@tonic-gate print = 0; 479*7c478bd9Sstevel@tonic-gate break; 480*7c478bd9Sstevel@tonic-gate /* 481*7c478bd9Sstevel@tonic-gate * Delete an entry 482*7c478bd9Sstevel@tonic-gate */ 483*7c478bd9Sstevel@tonic-gate case 'd': 484*7c478bd9Sstevel@tonic-gate print = 0; 485*7c478bd9Sstevel@tonic-gate k = 0; 486*7c478bd9Sstevel@tonic-gate if (strncmp("dq", resp, 2) != SAME && 487*7c478bd9Sstevel@tonic-gate strncmp("dp", resp, 2) != SAME) 488*7c478bd9Sstevel@tonic-gate if ((k = getnumbr(resp+1)) == -1) break; 489*7c478bd9Sstevel@tonic-gate if (k == 0) { 490*7c478bd9Sstevel@tonic-gate k = showlet; 491*7c478bd9Sstevel@tonic-gate if (!validmsg(curlet)) break; 492*7c478bd9Sstevel@tonic-gate print = 1; 493*7c478bd9Sstevel@tonic-gate curlet++; 494*7c478bd9Sstevel@tonic-gate } else k--; 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate setletr(k, 'd'); 497*7c478bd9Sstevel@tonic-gate if (resp[1] == 'p') print = 1; 498*7c478bd9Sstevel@tonic-gate else if (resp[1] == 'q') goto donep; 499*7c478bd9Sstevel@tonic-gate break; 500*7c478bd9Sstevel@tonic-gate } 501*7c478bd9Sstevel@tonic-gate } 502*7c478bd9Sstevel@tonic-gate /* 503*7c478bd9Sstevel@tonic-gate * Copy updated mailfile back 504*7c478bd9Sstevel@tonic-gate */ 505*7c478bd9Sstevel@tonic-gate donep: 506*7c478bd9Sstevel@tonic-gate if (changed) { 507*7c478bd9Sstevel@tonic-gate copyback(); 508*7c478bd9Sstevel@tonic-gate stamp(); 509*7c478bd9Sstevel@tonic-gate } 510*7c478bd9Sstevel@tonic-gate } 511