17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * CDDL HEADER START
37c478bdstevel@tonic-gate *
47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bdstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bdstevel@tonic-gate * (the "License").  You may not use this file except in compliance
77c478bdstevel@tonic-gate * with the License.
87c478bdstevel@tonic-gate *
97c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bdstevel@tonic-gate * See the License for the specific language governing permissions
127c478bdstevel@tonic-gate * and limitations under the License.
137c478bdstevel@tonic-gate *
147c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bdstevel@tonic-gate *
207c478bdstevel@tonic-gate * CDDL HEADER END
217c478bdstevel@tonic-gate */
227c478bdstevel@tonic-gate/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
237c478bdstevel@tonic-gate/*	  All Rights Reserved  	*/
247c478bdstevel@tonic-gate
257c478bdstevel@tonic-gate
267c478bdstevel@tonic-gate/*
277c478bdstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
287c478bdstevel@tonic-gate * Use is subject to license terms.
297c478bdstevel@tonic-gate */
307c478bdstevel@tonic-gate
317c478bdstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
327c478bdstevel@tonic-gate
337c478bdstevel@tonic-gate#include "mail.h"
347c478bdstevel@tonic-gate/*
357c478bdstevel@tonic-gate *	Print mail entries
367c478bdstevel@tonic-gate */
377c478bdstevel@tonic-gatevoid
387c478bdstevel@tonic-gateprintmail()
397c478bdstevel@tonic-gate{
407c478bdstevel@tonic-gate	static char pn[] = "printmail";
417c478bdstevel@tonic-gate	int	flg, curlet, showlet, k, print, aret, stret, rc;
427c478bdstevel@tonic-gate	int	nsmbox = 0;	/* 1 ==> mailbox is in non-standard place */
437c478bdstevel@tonic-gate	int	sav_j = -1;
447c478bdstevel@tonic-gate	char	*p, *getarg();
457c478bdstevel@tonic-gate	struct	stat stbuf;
467c478bdstevel@tonic-gate	struct	stat *stbufp;
477c478bdstevel@tonic-gate	int ttyf = isatty(1) ? TTY : ORDINARY;
487c478bdstevel@tonic-gate	char	readbuf[LSIZE];	/* holds user's response in interactive mode */
497c478bdstevel@tonic-gate	char	*resp;
507c478bdstevel@tonic-gate	gid_t	savedegid;
517c478bdstevel@tonic-gate
527c478bdstevel@tonic-gate	stbufp = &stbuf;
537c478bdstevel@tonic-gate
547c478bdstevel@tonic-gate	/*
557c478bdstevel@tonic-gate	 *	create working directory mbox name
567c478bdstevel@tonic-gate	 */
577c478bdstevel@tonic-gate	if ((hmbox = malloc(strlen(home) + strlen(mbox) + 1)) == NULL) {
587c478bdstevel@tonic-gate		errmsg(E_MBOX, "");
597c478bdstevel@tonic-gate		return;
607c478bdstevel@tonic-gate	}
617c478bdstevel@tonic-gate	cat(hmbox, home, mbox);
627c478bdstevel@tonic-gate
637c478bdstevel@tonic-gate	/*
647c478bdstevel@tonic-gate	 *	If we are not using an alternate mailfile, then get
657c478bdstevel@tonic-gate	 *	the $MAIL value and build the filename for the mailfile.
667c478bdstevel@tonic-gate	 *	If $MAIL is set, but is NOT the 'standard' place, then
677c478bdstevel@tonic-gate	 *	use it but set flgf to circumvent :saved processing.
687c478bdstevel@tonic-gate	 */
697c478bdstevel@tonic-gate	if (!flgf) {
707c478bdstevel@tonic-gate		if ((p = malloc(strlen(maildir) + strlen(my_name) + 1))
717c478bdstevel@tonic-gate								== NULL) {
727c478bdstevel@tonic-gate			errmsg(E_MEM, "");
737c478bdstevel@tonic-gate			return;
747c478bdstevel@tonic-gate		}
757c478bdstevel@tonic-gate		cat(p, maildir, my_name);
767c478bdstevel@tonic-gate		if (((mailfile = getenv("MAIL")) == NULL) ||
777c478bdstevel@tonic-gate		    (strlen(mailfile) == 0)) {
787c478bdstevel@tonic-gate			/* $MAIL not set, use standard path to mailfile */
797c478bdstevel@tonic-gate			mailfile = p;
807c478bdstevel@tonic-gate		} else {
817c478bdstevel@tonic-gate			if (strcmp(mailfile, p) != 0) {
827c478bdstevel@tonic-gate			    flgf = 1;
837c478bdstevel@tonic-gate			    nsmbox = 1;
847c478bdstevel@tonic-gate			    Dout(pn, 0, "$MAIL ('%s') != standard path\n",
857c478bdstevel@tonic-gate				mailfile);
867c478bdstevel@tonic-gate			    Dout("", 0, "\tSetting flgf to 1.\n");
877c478bdstevel@tonic-gate			}
887c478bdstevel@tonic-gate			free(p);
897c478bdstevel@tonic-gate		}
907c478bdstevel@tonic-gate	}
917c478bdstevel@tonic-gate
927c478bdstevel@tonic-gate	/*
937c478bdstevel@tonic-gate	 *	Get ACCESS and MODIFICATION times of mailfile BEFORE we
947c478bdstevel@tonic-gate	 *	use it. This allows us to put them back when we are
957c478bdstevel@tonic-gate	 *	done. If we didn't, the shell would think NEW mail had
967c478bdstevel@tonic-gate	 *	arrived since the file times would have changed.
977c478bdstevel@tonic-gate	 */
987c478bdstevel@tonic-gate	stret = CERROR;
997c478bdstevel@tonic-gate	if (access(mailfile, A_EXIST) == A_OK) {
1007c478bdstevel@tonic-gate		if ((stret = stat(mailfile, stbufp)) != A_OK) {
1017c478bdstevel@tonic-gate			errmsg(E_FILE, "Cannot stat mailfile");
1027c478bdstevel@tonic-gate			return;
1037c478bdstevel@tonic-gate		}
1047c478bdstevel@tonic-gate		mf_gid = stbufp->st_gid;
1057c478bdstevel@tonic-gate		mf_uid = stbufp->st_uid;
1067c478bdstevel@tonic-gate		utimep->actime = stbufp->st_atime;
1077c478bdstevel@tonic-gate		utimep->modtime = stbufp->st_mtime;
1087c478bdstevel@tonic-gate		file_size = stbufp->st_size;
1097c478bdstevel@tonic-gate	}
1107c478bdstevel@tonic-gate
1117c478bdstevel@tonic-gate	/* Open the file as the real gid */
1127c478bdstevel@tonic-gate	savedegid = getegid();
1137c478bdstevel@tonic-gate	(void) setegid(getgid());
1147c478bdstevel@tonic-gate	malf = fopen(mailfile, "r");
1157c478bdstevel@tonic-gate	(void) setegid(savedegid);
1167c478bdstevel@tonic-gate	/*
1177c478bdstevel@tonic-gate	 *	stat succeeded, but we cannot access the mailfile
1187c478bdstevel@tonic-gate	 */
1197c478bdstevel@tonic-gate	if (stret == CSUCCESS && malf == NULL) {
1207c478bdstevel@tonic-gate		char buf[MAXFILENAME+50];
1217c478bdstevel@tonic-gate		(void) snprintf(buf, sizeof (buf),
1227c478bdstevel@tonic-gate		    "Invalid permissions on %s", mailfile);
1237c478bdstevel@tonic-gate		errmsg(E_PERM, buf);
1247c478bdstevel@tonic-gate		return;
1257c478bdstevel@tonic-gate	} else
1267c478bdstevel@tonic-gate	/*
1277c478bdstevel@tonic-gate	 *	using an alternate mailfile, but we failed on access
1287c478bdstevel@tonic-gate	 */
1297c478bdstevel@tonic-gate	if (!nsmbox && flgf && (malf == NULL)) {
1307c478bdstevel@tonic-gate		errmsg(E_FILE, "Cannot open mailfile");
1317c478bdstevel@tonic-gate		return;
1327c478bdstevel@tonic-gate	}
1337c478bdstevel@tonic-gate	/*
1347c478bdstevel@tonic-gate	 *	we failed to access OR the file is empty
1357c478bdstevel@tonic-gate	 */
1367c478bdstevel@tonic-gate	else if ((malf == NULL) || (stbuf.st_size == 0)) {
1377c478bdstevel@tonic-gate		if (!flge && !flgE) {
1387c478bdstevel@tonic-gate			printf("No mail.\n");
1397c478bdstevel@tonic-gate		}
1407c478bdstevel@tonic-gate		error = E_FLGE;
1417c478bdstevel@tonic-gate		Dout(pn, 0, "error set to %d\n", error);
1427c478bdstevel@tonic-gate		return;
1437c478bdstevel@tonic-gate	}
1447c478bdstevel@tonic-gate	if (flge)
1457c478bdstevel@tonic-gate		return;
1467c478bdstevel@tonic-gate
1477c478bdstevel@tonic-gate	if (flgE) {
1487c478bdstevel@tonic-gate		if (utimep->modtime < utimep->actime) {
1497c478bdstevel@tonic-gate			error = E_FLGE_OM;
1507c478bdstevel@tonic-gate			Dout(pn, 0, "error set to %d\n", error);
1517c478bdstevel@tonic-gate		}
1527c478bdstevel@tonic-gate		return;
1537c478bdstevel@tonic-gate	}
1547c478bdstevel@tonic-gate	/*
1557c478bdstevel@tonic-gate	 *	Secure the mailfile to guarantee integrity
1567c478bdstevel@tonic-gate	 */
1577c478bdstevel@tonic-gate	lock(my_name);
1587c478bdstevel@tonic-gate
1597c478bdstevel@tonic-gate	/*
1607c478bdstevel@tonic-gate	 *	copy mail to temp file and mark each letter in the
1617c478bdstevel@tonic-gate	 *	let array --- mailfile is still locked !!!
1627c478bdstevel@tonic-gate	 */
1637c478bdstevel@tonic-gate	mktmp();
1647c478bdstevel@tonic-gate	copymt(malf, tmpf);
1657c478bdstevel@tonic-gate	onlet = nlet;
1667c478bdstevel@tonic-gate	fclose(malf);
1677c478bdstevel@tonic-gate	fclose(tmpf);
1687c478bdstevel@tonic-gate	unlock();	/* All done, OK to unlock now */
1697c478bdstevel@tonic-gate	tmpf = doopen(lettmp, "r+", E_TMP);
1707c478bdstevel@tonic-gate	changed = 0;
1717c478bdstevel@tonic-gate	print = 1;
1727c478bdstevel@tonic-gate	curlet = 0;
1737c478bdstevel@tonic-gate	while (curlet < nlet) {
1747c478bdstevel@tonic-gate		/*
1757c478bdstevel@tonic-gate		 *	reverse order ?
1767c478bdstevel@tonic-gate		 */
1777c478bdstevel@tonic-gate		showlet = flgr ? curlet : nlet - curlet - 1;
1787c478bdstevel@tonic-gate
1797c478bdstevel@tonic-gate		if (setjmp(sjbuf) == 0 && print != 0) {
1807c478bdstevel@tonic-gate				/* -h says to print the headers first */
1817c478bdstevel@tonic-gate				if (flgh) {
1827c478bdstevel@tonic-gate					gethead(showlet, 0);
1837c478bdstevel@tonic-gate					flgh = 0;	/* Only once */
1847c478bdstevel@tonic-gate					/* set letter # to invalid # */
1857c478bdstevel@tonic-gate					curlet--;
1867c478bdstevel@tonic-gate					showlet =
1877c478bdstevel@tonic-gate					    flgr ? curlet : nlet - curlet - 1;
1887c478bdstevel@tonic-gate				} else {
1897c478bdstevel@tonic-gate					if (showlet != sav_j) {
1907c478bdstevel@tonic-gate						/* Looking at new message. */
1917c478bdstevel@tonic-gate						/* Reset flag to override */
1927c478bdstevel@tonic-gate						/* non-display of binary */
1937c478bdstevel@tonic-gate						/* contents */
1947c478bdstevel@tonic-gate						sav_j = showlet;
1957c478bdstevel@tonic-gate						pflg = 0;
1967c478bdstevel@tonic-gate						Pflg = flgP;
1977c478bdstevel@tonic-gate					}
1987c478bdstevel@tonic-gate					copylet(showlet, stdout, ttyf);
1997c478bdstevel@tonic-gate				}
2007c478bdstevel@tonic-gate		}
2017c478bdstevel@tonic-gate
2027c478bdstevel@tonic-gate		/*
2037c478bdstevel@tonic-gate		 *	print only
2047c478bdstevel@tonic-gate		 */
2057c478bdstevel@tonic-gate		if (flgp) {
2067c478bdstevel@tonic-gate			curlet++;
2077c478bdstevel@tonic-gate			continue;
2087c478bdstevel@tonic-gate		}
2097c478bdstevel@tonic-gate		/*
2107c478bdstevel@tonic-gate		 *	Interactive
2117c478bdstevel@tonic-gate		 */
2127c478bdstevel@tonic-gate		interactive = 1;
2137c478bdstevel@tonic-gate		setjmp(sjbuf);
2147c478bdstevel@tonic-gate		stat(mailfile, stbufp);
2157c478bdstevel@tonic-gate		if (stbufp->st_size != file_size) {
2167c478bdstevel@tonic-gate			/*
2177c478bdstevel@tonic-gate			 *	New mail has arrived, load it
2187c478bdstevel@tonic-gate			 */
2197c478bdstevel@tonic-gate			k = nlet;
2207c478bdstevel@tonic-gate			lock(my_name);
2217c478bdstevel@tonic-gate			malf = doopen(mailfile, "r", E_FILE);
2227c478bdstevel@tonic-gate			fclose(tmpf);
2237c478bdstevel@tonic-gate			tmpf = doopen(lettmp, "a", E_TMP);
2247c478bdstevel@tonic-gate			fseek(malf, let[nlet].adr, 0);
2257c478bdstevel@tonic-gate			copymt(malf, tmpf);
2267c478bdstevel@tonic-gate			file_size = stbufp->st_size;
2277c478bdstevel@tonic-gate			fclose(malf);
2287c478bdstevel@tonic-gate			fclose(tmpf);
2297c478bdstevel@tonic-gate			unlock();
2307c478bdstevel@tonic-gate			tmpf = doopen(lettmp, "r+", E_TMP);
2317c478bdstevel@tonic-gate			if (++k < nlet)
2327c478bdstevel@tonic-gate				printf("New mail loaded into letters %d - %d\n",
2337c478bdstevel@tonic-gate				    k, nlet);
2347c478bdstevel@tonic-gate			else
2357c478bdstevel@tonic-gate				printf("New mail loaded into letter %d\n",
2367c478bdstevel@tonic-gate				    nlet);
2377c478bdstevel@tonic-gate		}
2387c478bdstevel@tonic-gate
2397c478bdstevel@tonic-gate		/* read the command */
2407c478bdstevel@tonic-gate		printf("? ");
2417c478bdstevel@tonic-gate		fflush(stdout);
2427c478bdstevel@tonic-gate		fflush(stderr);
2437c478bdstevel@tonic-gate		if (fgets(readbuf, sizeof (readbuf), stdin) == NULL) break;
2447c478bdstevel@tonic-gate		resp = readbuf;
2457c478bdstevel@tonic-gate		while (*resp == ' ' || *resp == '\t') resp++;
2467c478bdstevel@tonic-gate		print = 1;
2477c478bdstevel@tonic-gate		Dout(pn, 0, "resp = '%s'\n", resp);
2487c478bdstevel@tonic-gate		if ((rc = atoi(resp)) != 0) {
2497c478bdstevel@tonic-gate			if (!validmsg(rc)) print = 0;
2507c478bdstevel@tonic-gate			else curlet = flgr ? rc - 1 : nlet - rc;
2517c478bdstevel@tonic-gate		} else switch (resp[0]) {
2527c478bdstevel@tonic-gate			default:
2537c478bdstevel@tonic-gate				printf("Usage:\n");
2547c478bdstevel@tonic-gate			/*
2557c478bdstevel@tonic-gate			 *	help
2567c478bdstevel@tonic-gate			 */
2577c478bdstevel@tonic-gate			case '?':
2587c478bdstevel@tonic-gate				print = 0;
2597c478bdstevel@tonic-gate				for (rc = 0; help[rc]; rc++)
2607c478bdstevel@tonic-gate					printf("%s", help[rc]);
2617c478bdstevel@tonic-gate				break;
2627c478bdstevel@tonic-gate			/*
2637c478bdstevel@tonic-gate			 *	print message number of current message
2647c478bdstevel@tonic-gate			 */
2657c478bdstevel@tonic-gate			case '#':
2667c478bdstevel@tonic-gate				print = 0;
2677c478bdstevel@tonic-gate				if ((showlet == nlet) || (showlet < 0)) {
2687c478bdstevel@tonic-gate					printf("No message selected yet.\n");
2697c478bdstevel@tonic-gate				} else {
2707c478bdstevel@tonic-gate					printf("Current message number is %d\n",
2717c478bdstevel@tonic-gate					    showlet+1);
2727c478bdstevel@tonic-gate				}
2737c478bdstevel@tonic-gate				break;
2747c478bdstevel@tonic-gate			/*
2757c478bdstevel@tonic-gate			 *	headers
2767c478bdstevel@tonic-gate			 */
2777c478bdstevel@tonic-gate			case 'h':
2787c478bdstevel@tonic-gate				print = 0;
2797c478bdstevel@tonic-gate				if (resp[2] != 'd' &&
2807c478bdstevel@tonic-gate				    resp[2] != 'a' &&
2817c478bdstevel@tonic-gate				    (rc = getnumbr(resp+1)) > 0) {
2827c478bdstevel@tonic-gate					showlet = rc - 1;
2837c478bdstevel@tonic-gate					curlet = flgr ? rc - 1 : nlet - rc- 1;
2847c478bdstevel@tonic-gate				}
2857c478bdstevel@tonic-gate				if (rc == -1 && resp[2] != 'a' &&
2867c478bdstevel@tonic-gate				    resp[2] != 'd')
2877c478bdstevel@tonic-gate					break;
2887c478bdstevel@tonic-gate				if (resp[2] == 'a') rc = 1;
2897c478bdstevel@tonic-gate				else if (resp[2] == 'd') rc = 2;
2907c478bdstevel@tonic-gate					else rc = 0;
2917c478bdstevel@tonic-gate
2927c478bdstevel@tonic-gate/*
2937c478bdstevel@tonic-gate *				if (!validmsg(showlet)) break;
2947c478bdstevel@tonic-gate */
2957c478bdstevel@tonic-gate				gethead(showlet, rc);
2967c478bdstevel@tonic-gate				break;
2977c478bdstevel@tonic-gate			/*
2987c478bdstevel@tonic-gate			 *	skip entry
2997c478bdstevel@tonic-gate			 */
3007c478bdstevel@tonic-gate			case '+':
3017c478bdstevel@tonic-gate			case 'n':
3027c478bdstevel@tonic-gate			case '\n':
3037c478bdstevel@tonic-gate				curlet++;
3047c478bdstevel@tonic-gate				break;
3057c478bdstevel@tonic-gate			case 'P':
3067c478bdstevel@tonic-gate				Pflg++;
3077c478bdstevel@tonic-gate				break;
3087c478bdstevel@tonic-gate			case 'p':
3097c478bdstevel@tonic-gate				pflg++;
3107c478bdstevel@tonic-gate				break;
3117c478bdstevel@tonic-gate			case 'x':
3127c478bdstevel@tonic-gate				changed = 0;
3137c478bdstevel@tonic-gate			case 'q':
3147c478bdstevel@tonic-gate				goto donep;
3157c478bdstevel@tonic-gate			/*
3167c478bdstevel@tonic-gate			 *	Previous entry
3177c478bdstevel@tonic-gate			 */
3187c478bdstevel@tonic-gate			case '^':
3197c478bdstevel@tonic-gate			case '-':
3207c478bdstevel@tonic-gate				if (--curlet < 0) curlet = 0;
3217c478bdstevel@tonic-gate				break;
3227c478bdstevel@tonic-gate			/*
3237c478bdstevel@tonic-gate			 *	Save in file without header
3247c478bdstevel@tonic-gate			 */
3257c478bdstevel@tonic-gate			case 'y':
3267c478bdstevel@tonic-gate			case 'w':
3277c478bdstevel@tonic-gate			/*
3287c478bdstevel@tonic-gate			 *	Save mail with header
3297c478bdstevel@tonic-gate			 */
3307c478bdstevel@tonic-gate			case 's':
3317c478bdstevel@tonic-gate				print = 0;
3327c478bdstevel@tonic-gate				if (!validmsg(curlet)) break;
3337c478bdstevel@tonic-gate				if (resp[1] == '\n' || resp[1] == '\0') {
3347c478bdstevel@tonic-gate					cat(resp+1, hmbox, "");
3357c478bdstevel@tonic-gate				} else if (resp[1] != ' ') {
3367c478bdstevel@tonic-gate					printf("Invalid command\n");
3377c478bdstevel@tonic-gate					break;
3387c478bdstevel@tonic-gate				}
3397c478bdstevel@tonic-gate				umask(umsave);
3407c478bdstevel@tonic-gate				flg = 0;
3417c478bdstevel@tonic-gate				if (getarg(lfil, resp + 1) == NULL) {
3427c478bdstevel@tonic-gate					cat(resp + 1, hmbox, "");
3437c478bdstevel@tonic-gate				}
3447c478bdstevel@tonic-gate				malf = (FILE *)NULL;
3457c478bdstevel@tonic-gate				p = resp + 1;
3467c478bdstevel@tonic-gate				while ((p = getarg(lfil, p)) != NULL) {
3477c478bdstevel@tonic-gate					if (flg) {
3487c478bdstevel@tonic-gate					    fprintf(stderr,
3497c478bdstevel@tonic-gate						"%s: File '%s' skipped\n",
3507c478bdstevel@tonic-gate						program, lfil);
3517c478bdstevel@tonic-gate					    continue;
3527c478bdstevel@tonic-gate					}
3537c478bdstevel@tonic-gate					malf = NULL;
3547c478bdstevel@tonic-gate					if ((aret = legal(lfil))) {
3557c478bdstevel@tonic-gate						malf = fopen(lfil, "a");
3567c478bdstevel@tonic-gate					}
3577c478bdstevel@tonic-gate					if ((malf == NULL) || (aret == 0)) {
3587c478bdstevel@tonic-gate					    fprintf(stderr,
3597c478bdstevel@tonic-gate						"%s: Cannot append to %s\n",
3607c478bdstevel@tonic-gate						program, lfil);
3617c478bdstevel@tonic-gate					    flg++;
3627c478bdstevel@tonic-gate					} else if (aret == 2) {
3637c478bdstevel@tonic-gate						chown(lfil, my_euid, my_gid);
3647c478bdstevel@tonic-gate					}
3657c478bdstevel@tonic-gate					if (!flg &&
3667c478bdstevel@tonic-gate					    copylet(showlet, malf, resp[0] ==
3677c478bdstevel@tonic-gate					    's'? ORDINARY: ZAP) == FALSE) {
3687c478bdstevel@tonic-gate						fprintf(stderr,
3697c478bdstevel@tonic-gate					    "%s: Cannot save mail to '%s'\n",
3707c478bdstevel@tonic-gate						    program, lfil);
3717c478bdstevel@tonic-gate						flg++;
3727c478bdstevel@tonic-gate					} else
3737c478bdstevel@tonic-gate						Dout(pn, 0, "!saved\n");
3747c478bdstevel@tonic-gate					if (malf != (FILE *)NULL) {
3757c478bdstevel@tonic-gate						fclose(malf);
3767c478bdstevel@tonic-gate					}
3777c478bdstevel@tonic-gate				}
3787c478bdstevel@tonic-gate				umask(7);
3797c478bdstevel@tonic-gate				if (!flg) {
3807c478bdstevel@tonic-gate					setletr(showlet, resp[0]);
3817c478bdstevel@tonic-gate					print = 1;
3827c478bdstevel@tonic-gate					curlet++;
3837c478bdstevel@tonic-gate				}
3847c478bdstevel@tonic-gate				break;
3857c478bdstevel@tonic-gate			/*
3867c478bdstevel@tonic-gate			 *	Reply to a letter
3877c478bdstevel@tonic-gate			 */
3887c478bdstevel@tonic-gate			case 'r':
3897c478bdstevel@tonic-gate				print = 0;
3907c478bdstevel@tonic-gate				if (!validmsg(curlet)) break;
3917c478bdstevel@tonic-gate				replying = 1;
3927c478bdstevel@tonic-gate				for (k = 1; resp[k] == ' ' || resp[k] == '\t';
3937c478bdstevel@tonic-gate				    ++k);
3947c478bdstevel@tonic-gate				resp[strlen(resp)-1] = '\0';
3957c478bdstevel@tonic-gate				(void) strlcpy(m_sendto, resp+k,
3967c478bdstevel@tonic-gate				    sizeof (m_sendto));
3977c478bdstevel@tonic-gate				goback(showlet);
3987c478bdstevel@tonic-gate				replying = 0;
3997c478bdstevel@tonic-gate				setletr(showlet, resp[0]);
4007c478bdstevel@tonic-gate				break;
4017c478bdstevel@tonic-gate			/*
4027c478bdstevel@tonic-gate			 *	Undelete
4037c478bdstevel@tonic-gate			 */
4047c478bdstevel@tonic-gate			case 'u':
4057c478bdstevel@tonic-gate				print = 0;
4067c478bdstevel@tonic-gate				if ((k = getnumbr(resp+1)) <= 0) k = showlet;
4077c478bdstevel@tonic-gate				else k--;
4087c478bdstevel@tonic-gate				if (!validmsg(k)) break;
4097c478bdstevel@tonic-gate				setletr(k, ' ');
4107c478bdstevel@tonic-gate				break;
4117c478bdstevel@tonic-gate			/*
4127c478bdstevel@tonic-gate			 *	Mail letter to someone else
4137c478bdstevel@tonic-gate			 */
4147c478bdstevel@tonic-gate			case 'm':
4157c478bdstevel@tonic-gate				{
4167c478bdstevel@tonic-gate				reciplist list;
4177c478bdstevel@tonic-gate				print = 0;
4187c478bdstevel@tonic-gate				if (!validmsg(curlet)) break;
4197c478bdstevel@tonic-gate				new_reciplist(&list);
4207c478bdstevel@tonic-gate				flg = 0;
4217c478bdstevel@tonic-gate				k = 0;
4227c478bdstevel@tonic-gate				if (substr(resp, " -") != -1 ||
4237c478bdstevel@tonic-gate					substr(resp, "\t-") != -1) {
4247c478bdstevel@tonic-gate					printf("Only users may be specified\n");
4257c478bdstevel@tonic-gate					break;
4267c478bdstevel@tonic-gate				}
4277c478bdstevel@tonic-gate				p = resp + 1;
4287c478bdstevel@tonic-gate				while ((p = getarg(lfil, p)) != NULL) {
4297c478bdstevel@tonic-gate					char *env;
4307c478bdstevel@tonic-gate					if (lfil[0] == '$') {
4317c478bdstevel@tonic-gate						if (!(env = getenv(&lfil[1]))) {
4327c478bdstevel@tonic-gate							fprintf(stderr,
4337c478bdstevel@tonic-gate				"%s: %s has no value or is not exported.\n",
4347c478bdstevel@tonic-gate							    program, lfil);
4357c478bdstevel@tonic-gate							flg++;
4367c478bdstevel@tonic-gate						} else
4377c478bdstevel@tonic-gate							add_recip(&list, env,
4387c478bdstevel@tonic-gate							    FALSE);
4397c478bdstevel@tonic-gate						k++;
4407c478bdstevel@tonic-gate					} else if (lfil[0] != '\0') {
4417c478bdstevel@tonic-gate						add_recip(&list, lfil, FALSE);
4427c478bdstevel@tonic-gate						k++;
4437c478bdstevel@tonic-gate					}
4447c478bdstevel@tonic-gate				}
4457c478bdstevel@tonic-gate				(void) strlcpy(Rpath, my_name, sizeof (Rpath));
4467c478bdstevel@tonic-gate				sending = TRUE;
4477c478bdstevel@tonic-gate				flg += sendlist(&list, showlet, 0);
4487c478bdstevel@tonic-gate				sending = FALSE;
4497c478bdstevel@tonic-gate				if (k) {
4507c478bdstevel@tonic-gate					if (!flg) {
4517c478bdstevel@tonic-gate						setletr(showlet, 'm');
4527c478bdstevel@tonic-gate						print = 1;
4537c478bdstevel@tonic-gate						curlet++;
4547c478bdstevel@tonic-gate					}
4557c478bdstevel@tonic-gate				} else
4567c478bdstevel@tonic-gate					printf("Invalid command\n");
4577c478bdstevel@tonic-gate				del_reciplist(&list);
4587c478bdstevel@tonic-gate				break;
4597c478bdstevel@tonic-gate				}
4607c478bdstevel@tonic-gate			/*
4617c478bdstevel@tonic-gate			 *	Read new letters
4627c478bdstevel@tonic-gate			 */
4637c478bdstevel@tonic-gate			case 'a':
4647c478bdstevel@tonic-gate				if (onlet == nlet) {
4657c478bdstevel@tonic-gate					printf("No new mail\n");
4667c478bdstevel@tonic-gate					print = 0;
4677c478bdstevel@tonic-gate					break;
4687c478bdstevel@tonic-gate				}
4697c478bdstevel@tonic-gate				curlet = 0;
4707c478bdstevel@tonic-gate				print = 1;
4717c478bdstevel@tonic-gate				break;
4727c478bdstevel@tonic-gate			/*
4737c478bdstevel@tonic-gate			 *	Escape to shell
4747c478bdstevel@tonic-gate			 */
4757c478bdstevel@tonic-gate			case '!':
4767c478bdstevel@tonic-gate				systm(resp + 1);
4777c478bdstevel@tonic-gate				printf("!\n");
4787c478bdstevel@tonic-gate				print = 0;
4797c478bdstevel@tonic-gate				break;
4807c478bdstevel@tonic-gate			/*
4817c478bdstevel@tonic-gate			 *	Delete an entry
4827c478bdstevel@tonic-gate			 */
4837c478bdstevel@tonic-gate			case 'd':
4847c478bdstevel@tonic-gate				print = 0;
4857c478bdstevel@tonic-gate				k = 0;
4867c478bdstevel@tonic-gate				if (strncmp("dq", resp, 2) != SAME &&
4877c478bdstevel@tonic-gate					strncmp("dp", resp, 2) != SAME)
4887c478bdstevel@tonic-gate					if ((k = getnumbr(resp+1)) == -1) break;
4897c478bdstevel@tonic-gate				if (k == 0) {
4907c478bdstevel@tonic-gate					k = showlet;
4917c478bdstevel@tonic-gate					if (!validmsg(curlet)) break;
4927c478bdstevel@tonic-gate					print = 1;
4937c478bdstevel@tonic-gate					curlet++;
4947c478bdstevel@tonic-gate				} else	k--;
4957c478bdstevel@tonic-gate
4967c478bdstevel@tonic-gate				setletr(k, 'd');
4977c478bdstevel@tonic-gate				if (resp[1] == 'p') print = 1;
4987c478bdstevel@tonic-gate				else if (resp[1] == 'q') goto donep;
4997c478bdstevel@tonic-gate				break;
5007c478bdstevel@tonic-gate		}
5017c478bdstevel@tonic-gate	}
5027c478bdstevel@tonic-gate	/*
5037c478bdstevel@tonic-gate	 *	Copy updated mailfile back
5047c478bdstevel@tonic-gate	 */
5057c478bdstevel@tonic-gatedonep:
5067c478bdstevel@tonic-gate	if (changed) {
5077c478bdstevel@tonic-gate		copyback();
5087c478bdstevel@tonic-gate		stamp();
5097c478bdstevel@tonic-gate	}
5107c478bdstevel@tonic-gate}
511