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