xref: /titanic_53/usr/src/cmd/mailx/lex.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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 1998-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 /*
32*7c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
33*7c478bd9Sstevel@tonic-gate  * The Regents of the University of California
34*7c478bd9Sstevel@tonic-gate  * All Rights Reserved
35*7c478bd9Sstevel@tonic-gate  *
36*7c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
37*7c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
38*7c478bd9Sstevel@tonic-gate  * contributors.
39*7c478bd9Sstevel@tonic-gate  */
40*7c478bd9Sstevel@tonic-gate 
41*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate #include "rcv.h"
44*7c478bd9Sstevel@tonic-gate #include <locale.h>
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate /*
47*7c478bd9Sstevel@tonic-gate  * mailx -- a modified version of a University of California at Berkeley
48*7c478bd9Sstevel@tonic-gate  *	mail program
49*7c478bd9Sstevel@tonic-gate  *
50*7c478bd9Sstevel@tonic-gate  * Lexical processing of commands.
51*7c478bd9Sstevel@tonic-gate  */
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate #ifdef SIGCONT
54*7c478bd9Sstevel@tonic-gate static void		contin(int);
55*7c478bd9Sstevel@tonic-gate #endif
56*7c478bd9Sstevel@tonic-gate static int		isprefix(char *as1, char *as2);
57*7c478bd9Sstevel@tonic-gate static const struct cmd	*lex(char word[]);
58*7c478bd9Sstevel@tonic-gate static int		Passeren(void);
59*7c478bd9Sstevel@tonic-gate static void		setmsize(int sz);
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate /*
62*7c478bd9Sstevel@tonic-gate  * Set up editing on the given file name.
63*7c478bd9Sstevel@tonic-gate  * If isedit is true, we are considered to be editing the file,
64*7c478bd9Sstevel@tonic-gate  * otherwise we are reading our mail which has signficance for
65*7c478bd9Sstevel@tonic-gate  * mbox and so forth.
66*7c478bd9Sstevel@tonic-gate  */
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate int
69*7c478bd9Sstevel@tonic-gate setfile(char *name, int isedit)
70*7c478bd9Sstevel@tonic-gate {
71*7c478bd9Sstevel@tonic-gate 	FILE *ibuf;
72*7c478bd9Sstevel@tonic-gate 	int i;
73*7c478bd9Sstevel@tonic-gate 	static int shudclob;
74*7c478bd9Sstevel@tonic-gate 	static char efile[PATHSIZE];
75*7c478bd9Sstevel@tonic-gate 	char fortest[128];
76*7c478bd9Sstevel@tonic-gate 	struct stat stbuf;
77*7c478bd9Sstevel@tonic-gate 	int exrc = 1;
78*7c478bd9Sstevel@tonic-gate 	int rc = -1;
79*7c478bd9Sstevel@tonic-gate 	int fd = -1;
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate 	if (!isedit && issysmbox)
82*7c478bd9Sstevel@tonic-gate 		lockmail();
83*7c478bd9Sstevel@tonic-gate 	if (stat(name, &stbuf) < 0 && errno == EOVERFLOW) {
84*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("mailbox %s is too large to"
85*7c478bd9Sstevel@tonic-gate 		    " accept incoming mail\n"), name);
86*7c478bd9Sstevel@tonic-gate 		goto doret;
87*7c478bd9Sstevel@tonic-gate 	}
88*7c478bd9Sstevel@tonic-gate 	if ((ibuf = fopen(name, "r")) == NULL) {
89*7c478bd9Sstevel@tonic-gate 		extern int errno;
90*7c478bd9Sstevel@tonic-gate 		int sverrno = errno;
91*7c478bd9Sstevel@tonic-gate 		int filethere = (access(name,0) == 0);
92*7c478bd9Sstevel@tonic-gate 		errno = sverrno;
93*7c478bd9Sstevel@tonic-gate 		if (exitflg)
94*7c478bd9Sstevel@tonic-gate 			goto doexit;	/* no mail, return error */
95*7c478bd9Sstevel@tonic-gate 		if (isedit || filethere)
96*7c478bd9Sstevel@tonic-gate 			perror(name);
97*7c478bd9Sstevel@tonic-gate 		else if (!Hflag) {
98*7c478bd9Sstevel@tonic-gate 			char *f = strrchr(name,'/');
99*7c478bd9Sstevel@tonic-gate 			if (f == NOSTR)
100*7c478bd9Sstevel@tonic-gate 				fprintf(stderr, gettext("No mail.\n"));
101*7c478bd9Sstevel@tonic-gate 			else
102*7c478bd9Sstevel@tonic-gate 				fprintf(stderr, gettext("No mail for %s\n"),
103*7c478bd9Sstevel@tonic-gate f+1);
104*7c478bd9Sstevel@tonic-gate 		}
105*7c478bd9Sstevel@tonic-gate 		goto doret;
106*7c478bd9Sstevel@tonic-gate 	}
107*7c478bd9Sstevel@tonic-gate 	fstat(fileno(ibuf), &stbuf);
108*7c478bd9Sstevel@tonic-gate 	if (stbuf.st_size == 0L || (stbuf.st_mode&S_IFMT) != S_IFREG) {
109*7c478bd9Sstevel@tonic-gate 		if (exitflg)
110*7c478bd9Sstevel@tonic-gate 			goto doexit;	/* no mail, return error */
111*7c478bd9Sstevel@tonic-gate 		if (isedit)
112*7c478bd9Sstevel@tonic-gate 			if (stbuf.st_size == 0L)
113*7c478bd9Sstevel@tonic-gate 				fprintf(stderr, gettext("%s: empty file\n"),
114*7c478bd9Sstevel@tonic-gate name);
115*7c478bd9Sstevel@tonic-gate 			else
116*7c478bd9Sstevel@tonic-gate 				fprintf(stderr,
117*7c478bd9Sstevel@tonic-gate 				    gettext("%s: not a regular file\n"), name);
118*7c478bd9Sstevel@tonic-gate 		else if (!Hflag) {
119*7c478bd9Sstevel@tonic-gate 			if (strrchr(name,'/') == NOSTR)
120*7c478bd9Sstevel@tonic-gate 				fprintf(stderr, gettext("No mail.\n"));
121*7c478bd9Sstevel@tonic-gate 			else
122*7c478bd9Sstevel@tonic-gate 				fprintf(stderr, gettext("No mail for %s\n"),
123*7c478bd9Sstevel@tonic-gate strrchr(name, '/') + 1);
124*7c478bd9Sstevel@tonic-gate 		}
125*7c478bd9Sstevel@tonic-gate 		fclose(ibuf);
126*7c478bd9Sstevel@tonic-gate 		goto doret;
127*7c478bd9Sstevel@tonic-gate 	}
128*7c478bd9Sstevel@tonic-gate 
129*7c478bd9Sstevel@tonic-gate 	fgets(fortest, sizeof fortest, ibuf);
130*7c478bd9Sstevel@tonic-gate 	fseek(ibuf, (long)(BUFSIZ+1), 0);	/* flush input buffer */
131*7c478bd9Sstevel@tonic-gate 	fseek(ibuf, 0L, 0);
132*7c478bd9Sstevel@tonic-gate 	if (strncmp(fortest, "Forward to ", 11) == 0) {
133*7c478bd9Sstevel@tonic-gate 		if (exitflg)
134*7c478bd9Sstevel@tonic-gate 			goto doexit;	/* no mail, return error */
135*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Your mail is being forwarded to %s"),
136*7c478bd9Sstevel@tonic-gate fortest+11);
137*7c478bd9Sstevel@tonic-gate 		fclose(ibuf);
138*7c478bd9Sstevel@tonic-gate 		goto doret;
139*7c478bd9Sstevel@tonic-gate 	}
140*7c478bd9Sstevel@tonic-gate 	if (exitflg) {
141*7c478bd9Sstevel@tonic-gate 		exrc = 0;
142*7c478bd9Sstevel@tonic-gate 		goto doexit;	/* there is mail, return success */
143*7c478bd9Sstevel@tonic-gate 	}
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate 	/*
146*7c478bd9Sstevel@tonic-gate 	 * Looks like all will be well. Must hold signals
147*7c478bd9Sstevel@tonic-gate 	 * while we are reading the new file, else we will ruin
148*7c478bd9Sstevel@tonic-gate 	 * the message[] data structure.
149*7c478bd9Sstevel@tonic-gate 	 * Copy the messages into /tmp and set pointers.
150*7c478bd9Sstevel@tonic-gate 	 */
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate 	holdsigs();
153*7c478bd9Sstevel@tonic-gate 	if (shudclob) {
154*7c478bd9Sstevel@tonic-gate 		/*
155*7c478bd9Sstevel@tonic-gate 		 * Now that we know we can switch to the new file
156*7c478bd9Sstevel@tonic-gate 		 * it's safe to close out the current file.
157*7c478bd9Sstevel@tonic-gate 		 *
158*7c478bd9Sstevel@tonic-gate 		 * If we're switching to the file we are currently
159*7c478bd9Sstevel@tonic-gate 		 * editing, don't allow it to be removed as a side
160*7c478bd9Sstevel@tonic-gate 		 * effect of closing it out.
161*7c478bd9Sstevel@tonic-gate 		 */
162*7c478bd9Sstevel@tonic-gate 		if (edit)
163*7c478bd9Sstevel@tonic-gate 			edstop(strcmp(editfile, name) == 0);
164*7c478bd9Sstevel@tonic-gate 		else {
165*7c478bd9Sstevel@tonic-gate 			quit(strcmp(editfile, name) == 0);
166*7c478bd9Sstevel@tonic-gate 			if (issysmbox)
167*7c478bd9Sstevel@tonic-gate 				Verhogen();
168*7c478bd9Sstevel@tonic-gate 		}
169*7c478bd9Sstevel@tonic-gate 		fflush(stdout);
170*7c478bd9Sstevel@tonic-gate 		fclose(itf);
171*7c478bd9Sstevel@tonic-gate 		fclose(otf);
172*7c478bd9Sstevel@tonic-gate 		free(message);
173*7c478bd9Sstevel@tonic-gate 		space=0;
174*7c478bd9Sstevel@tonic-gate 	}
175*7c478bd9Sstevel@tonic-gate 	readonly = 0;
176*7c478bd9Sstevel@tonic-gate 	if (!isedit && issysmbox && !Hflag)
177*7c478bd9Sstevel@tonic-gate 		readonly = Passeren()==-1;
178*7c478bd9Sstevel@tonic-gate 	lock(ibuf, "r", 1);
179*7c478bd9Sstevel@tonic-gate 	fstat(fileno(ibuf), &stbuf);
180*7c478bd9Sstevel@tonic-gate 	utimep->actime = stbuf.st_atime;
181*7c478bd9Sstevel@tonic-gate 	utimep->modtime = stbuf.st_mtime;
182*7c478bd9Sstevel@tonic-gate 
183*7c478bd9Sstevel@tonic-gate 	if (!readonly)
184*7c478bd9Sstevel@tonic-gate 		if ((i = open(name, O_WRONLY)) < 0)
185*7c478bd9Sstevel@tonic-gate 			readonly++;
186*7c478bd9Sstevel@tonic-gate 		else
187*7c478bd9Sstevel@tonic-gate 			close(i);
188*7c478bd9Sstevel@tonic-gate 	shudclob = 1;
189*7c478bd9Sstevel@tonic-gate 	edit = isedit;
190*7c478bd9Sstevel@tonic-gate 	nstrcpy(efile, PATHSIZE, name);
191*7c478bd9Sstevel@tonic-gate 	editfile = efile;
192*7c478bd9Sstevel@tonic-gate #ifdef notdef
193*7c478bd9Sstevel@tonic-gate 	if (name != mailname)
194*7c478bd9Sstevel@tonic-gate 		nstrcpy(mailname, PATHSIZE, name);
195*7c478bd9Sstevel@tonic-gate #endif
196*7c478bd9Sstevel@tonic-gate 	mailsize = fsize(ibuf);
197*7c478bd9Sstevel@tonic-gate 	if ((fd = open(tempMesg, O_RDWR|O_CREAT|O_EXCL, 0600)) < 0 ||
198*7c478bd9Sstevel@tonic-gate 	(otf = fdopen(fd, "w")) == NULL) {
199*7c478bd9Sstevel@tonic-gate 		perror(tempMesg);
200*7c478bd9Sstevel@tonic-gate 		if (!edit && issysmbox)
201*7c478bd9Sstevel@tonic-gate 			Verhogen();
202*7c478bd9Sstevel@tonic-gate 		goto doexit;
203*7c478bd9Sstevel@tonic-gate 	}
204*7c478bd9Sstevel@tonic-gate 	if ((itf = fopen(tempMesg, "r")) == NULL) {
205*7c478bd9Sstevel@tonic-gate 		perror(tempMesg);
206*7c478bd9Sstevel@tonic-gate 		if (!edit && issysmbox)
207*7c478bd9Sstevel@tonic-gate 			Verhogen();
208*7c478bd9Sstevel@tonic-gate 		goto doexit;
209*7c478bd9Sstevel@tonic-gate 	}
210*7c478bd9Sstevel@tonic-gate 	removefile(tempMesg);
211*7c478bd9Sstevel@tonic-gate 	setptr(ibuf);
212*7c478bd9Sstevel@tonic-gate 	setmsize(msgCount);
213*7c478bd9Sstevel@tonic-gate 	fclose(ibuf);
214*7c478bd9Sstevel@tonic-gate 	relsesigs();
215*7c478bd9Sstevel@tonic-gate 	sawcom = 0;
216*7c478bd9Sstevel@tonic-gate 	rc = 0;
217*7c478bd9Sstevel@tonic-gate 
218*7c478bd9Sstevel@tonic-gate     doret:
219*7c478bd9Sstevel@tonic-gate 	if (!isedit && issysmbox)
220*7c478bd9Sstevel@tonic-gate 		unlockmail();
221*7c478bd9Sstevel@tonic-gate 	return(rc);
222*7c478bd9Sstevel@tonic-gate 
223*7c478bd9Sstevel@tonic-gate     doexit:
224*7c478bd9Sstevel@tonic-gate 	if (!isedit && issysmbox)
225*7c478bd9Sstevel@tonic-gate 		unlockmail();
226*7c478bd9Sstevel@tonic-gate 	exit(exrc ? exrc : rpterr);
227*7c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
228*7c478bd9Sstevel@tonic-gate }
229*7c478bd9Sstevel@tonic-gate 
230*7c478bd9Sstevel@tonic-gate /* global to semaphores */
231*7c478bd9Sstevel@tonic-gate static char semfn[128];
232*7c478bd9Sstevel@tonic-gate static FILE *semfp = NULL;
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate /*
235*7c478bd9Sstevel@tonic-gate  *  return -1 if file is already being read, 0 otherwise
236*7c478bd9Sstevel@tonic-gate  */
237*7c478bd9Sstevel@tonic-gate static int
238*7c478bd9Sstevel@tonic-gate Passeren(void)
239*7c478bd9Sstevel@tonic-gate {
240*7c478bd9Sstevel@tonic-gate 	char *home;
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate 	if ((home = getenv("HOME")) == NULL)
243*7c478bd9Sstevel@tonic-gate 		return 0;
244*7c478bd9Sstevel@tonic-gate 	snprintf(semfn, sizeof (semfn), "%s%s", home, "/.Maillock");
245*7c478bd9Sstevel@tonic-gate 	if ((semfp = fopen(semfn, "w")) == NULL) {
246*7c478bd9Sstevel@tonic-gate 		fprintf(stderr,
247*7c478bd9Sstevel@tonic-gate 	    gettext("WARNING: Can't open mail lock file (%s).\n"), semfn);
248*7c478bd9Sstevel@tonic-gate 		fprintf(stderr,
249*7c478bd9Sstevel@tonic-gate 	    gettext("\t Assuming you are not already reading mail.\n"));
250*7c478bd9Sstevel@tonic-gate 		return 0;
251*7c478bd9Sstevel@tonic-gate 	}
252*7c478bd9Sstevel@tonic-gate 	if (lock(semfp, "w", 0) < 0) {
253*7c478bd9Sstevel@tonic-gate 		if (errno == ENOLCK) {
254*7c478bd9Sstevel@tonic-gate 			fprintf(stderr,
255*7c478bd9Sstevel@tonic-gate gettext("WARNING: Unable to acquire mail lock, no record locks available.\n"));
256*7c478bd9Sstevel@tonic-gate 			fprintf(stderr,
257*7c478bd9Sstevel@tonic-gate 		    gettext("\t Assuming you are not already reading mail.\n"));
258*7c478bd9Sstevel@tonic-gate 			return 0;
259*7c478bd9Sstevel@tonic-gate 		}
260*7c478bd9Sstevel@tonic-gate 		fprintf(stderr,
261*7c478bd9Sstevel@tonic-gate 		    gettext("WARNING: You are already reading mail.\n"));
262*7c478bd9Sstevel@tonic-gate 		fprintf(stderr,
263*7c478bd9Sstevel@tonic-gate 		    gettext("\t This instance of mail is read only.\n"));
264*7c478bd9Sstevel@tonic-gate 		fclose(semfp);
265*7c478bd9Sstevel@tonic-gate 		semfp = NULL;
266*7c478bd9Sstevel@tonic-gate 		return -1;
267*7c478bd9Sstevel@tonic-gate 	}
268*7c478bd9Sstevel@tonic-gate 	return 0;
269*7c478bd9Sstevel@tonic-gate }
270*7c478bd9Sstevel@tonic-gate 
271*7c478bd9Sstevel@tonic-gate void
272*7c478bd9Sstevel@tonic-gate Verhogen(void)
273*7c478bd9Sstevel@tonic-gate {
274*7c478bd9Sstevel@tonic-gate 	if (semfp != NULL) {
275*7c478bd9Sstevel@tonic-gate 		unlink(semfn);
276*7c478bd9Sstevel@tonic-gate 		fclose(semfp);
277*7c478bd9Sstevel@tonic-gate 	}
278*7c478bd9Sstevel@tonic-gate }
279*7c478bd9Sstevel@tonic-gate 
280*7c478bd9Sstevel@tonic-gate /*
281*7c478bd9Sstevel@tonic-gate  * Interpret user commands one by one.  If standard input is not a tty,
282*7c478bd9Sstevel@tonic-gate  * print no prompt.
283*7c478bd9Sstevel@tonic-gate  */
284*7c478bd9Sstevel@tonic-gate 
285*7c478bd9Sstevel@tonic-gate static int	*msgvec;
286*7c478bd9Sstevel@tonic-gate static int	shudprompt;
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate void
289*7c478bd9Sstevel@tonic-gate commands(void)
290*7c478bd9Sstevel@tonic-gate {
291*7c478bd9Sstevel@tonic-gate 	int eofloop;
292*7c478bd9Sstevel@tonic-gate 	register int n;
293*7c478bd9Sstevel@tonic-gate 	char linebuf[LINESIZE];
294*7c478bd9Sstevel@tonic-gate 	char line[LINESIZE];
295*7c478bd9Sstevel@tonic-gate 	struct stat minfo;
296*7c478bd9Sstevel@tonic-gate 	FILE *ibuf;
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate #ifdef SIGCONT
299*7c478bd9Sstevel@tonic-gate 	sigset(SIGCONT, SIG_DFL);
300*7c478bd9Sstevel@tonic-gate #endif
301*7c478bd9Sstevel@tonic-gate 	if (rcvmode && !sourcing) {
302*7c478bd9Sstevel@tonic-gate 		if (sigset(SIGINT, SIG_IGN) != SIG_IGN)
303*7c478bd9Sstevel@tonic-gate 			sigset(SIGINT, stop);
304*7c478bd9Sstevel@tonic-gate 		if (sigset(SIGHUP, SIG_IGN) != SIG_IGN)
305*7c478bd9Sstevel@tonic-gate 			sigset(SIGHUP, hangup);
306*7c478bd9Sstevel@tonic-gate 	}
307*7c478bd9Sstevel@tonic-gate 	for (;;) {
308*7c478bd9Sstevel@tonic-gate 		setjmp(srbuf);
309*7c478bd9Sstevel@tonic-gate 
310*7c478bd9Sstevel@tonic-gate 		/*
311*7c478bd9Sstevel@tonic-gate 		 * Print the prompt, if needed.  Clear out
312*7c478bd9Sstevel@tonic-gate 		 * string space, and flush the output.
313*7c478bd9Sstevel@tonic-gate 		 */
314*7c478bd9Sstevel@tonic-gate 
315*7c478bd9Sstevel@tonic-gate 		if (!rcvmode && !sourcing)
316*7c478bd9Sstevel@tonic-gate 			return;
317*7c478bd9Sstevel@tonic-gate 		eofloop = 0;
318*7c478bd9Sstevel@tonic-gate top:
319*7c478bd9Sstevel@tonic-gate 		if ((shudprompt = (intty && !sourcing)) != 0) {
320*7c478bd9Sstevel@tonic-gate 			if (prompt==NOSTR) {
321*7c478bd9Sstevel@tonic-gate 				if ((int)value("bsdcompat"))
322*7c478bd9Sstevel@tonic-gate 					prompt = "& ";
323*7c478bd9Sstevel@tonic-gate 				else
324*7c478bd9Sstevel@tonic-gate 				        prompt = "";
325*7c478bd9Sstevel@tonic-gate 			}
326*7c478bd9Sstevel@tonic-gate #ifdef SIGCONT
327*7c478bd9Sstevel@tonic-gate 			sigset(SIGCONT, contin);
328*7c478bd9Sstevel@tonic-gate #endif
329*7c478bd9Sstevel@tonic-gate 			if (intty && value("autoinc") &&
330*7c478bd9Sstevel@tonic-gate 			    stat(editfile, &minfo) >=0 &&
331*7c478bd9Sstevel@tonic-gate 			    minfo.st_size > mailsize) {
332*7c478bd9Sstevel@tonic-gate 				int OmsgCount, i;
333*7c478bd9Sstevel@tonic-gate 
334*7c478bd9Sstevel@tonic-gate 				OmsgCount = msgCount;
335*7c478bd9Sstevel@tonic-gate 				fseek(otf, 0L, 2);
336*7c478bd9Sstevel@tonic-gate 				holdsigs();
337*7c478bd9Sstevel@tonic-gate 				if (!edit && issysmbox)
338*7c478bd9Sstevel@tonic-gate 					lockmail();
339*7c478bd9Sstevel@tonic-gate 				if ((ibuf = fopen(editfile, "r")) == NULL ) {
340*7c478bd9Sstevel@tonic-gate 					fprintf(stderr,
341*7c478bd9Sstevel@tonic-gate 					    gettext("Can't reopen %s\n"),
342*7c478bd9Sstevel@tonic-gate 					    editfile);
343*7c478bd9Sstevel@tonic-gate 					if (!edit && issysmbox)
344*7c478bd9Sstevel@tonic-gate 						unlockmail();
345*7c478bd9Sstevel@tonic-gate 					exit(1);
346*7c478bd9Sstevel@tonic-gate 					/* NOTREACHED */
347*7c478bd9Sstevel@tonic-gate 				}
348*7c478bd9Sstevel@tonic-gate 				if (edit || !issysmbox)
349*7c478bd9Sstevel@tonic-gate 					lock(ibuf, "r", 1);
350*7c478bd9Sstevel@tonic-gate 				fseek(ibuf, mailsize, 0);
351*7c478bd9Sstevel@tonic-gate 				mailsize = fsize(ibuf);
352*7c478bd9Sstevel@tonic-gate 				setptr(ibuf);
353*7c478bd9Sstevel@tonic-gate 				setmsize(msgCount);
354*7c478bd9Sstevel@tonic-gate 				fclose(ibuf);
355*7c478bd9Sstevel@tonic-gate 				if (!edit && issysmbox)
356*7c478bd9Sstevel@tonic-gate 					unlockmail();
357*7c478bd9Sstevel@tonic-gate 				if (msgCount-OmsgCount > 0) {
358*7c478bd9Sstevel@tonic-gate 					printf(gettext(
359*7c478bd9Sstevel@tonic-gate 					    "New mail has arrived.\n"));
360*7c478bd9Sstevel@tonic-gate 					if (msgCount - OmsgCount == 1)
361*7c478bd9Sstevel@tonic-gate 						printf(gettext(
362*7c478bd9Sstevel@tonic-gate 						    "Loaded 1 new message\n"));
363*7c478bd9Sstevel@tonic-gate 					else
364*7c478bd9Sstevel@tonic-gate 						printf(gettext(
365*7c478bd9Sstevel@tonic-gate 						    "Loaded %d new messages\n"),
366*7c478bd9Sstevel@tonic-gate 						    msgCount-OmsgCount);
367*7c478bd9Sstevel@tonic-gate 					if (value("header") != NOSTR)
368*7c478bd9Sstevel@tonic-gate 						for (i = OmsgCount+1;
369*7c478bd9Sstevel@tonic-gate 						     i <= msgCount; i++) {
370*7c478bd9Sstevel@tonic-gate 							printhead(i);
371*7c478bd9Sstevel@tonic-gate 							sreset();
372*7c478bd9Sstevel@tonic-gate 						}
373*7c478bd9Sstevel@tonic-gate 				}
374*7c478bd9Sstevel@tonic-gate 				relsesigs();
375*7c478bd9Sstevel@tonic-gate 			}
376*7c478bd9Sstevel@tonic-gate 			printf("%s", prompt);
377*7c478bd9Sstevel@tonic-gate 		}
378*7c478bd9Sstevel@tonic-gate 		flush();
379*7c478bd9Sstevel@tonic-gate 		sreset();
380*7c478bd9Sstevel@tonic-gate 
381*7c478bd9Sstevel@tonic-gate 		/*
382*7c478bd9Sstevel@tonic-gate 		 * Read a line of commands from the current input
383*7c478bd9Sstevel@tonic-gate 		 * and handle end of file specially.
384*7c478bd9Sstevel@tonic-gate 		 */
385*7c478bd9Sstevel@tonic-gate 
386*7c478bd9Sstevel@tonic-gate 		n = 0;
387*7c478bd9Sstevel@tonic-gate 		linebuf[0] = '\0';
388*7c478bd9Sstevel@tonic-gate 		for (;;) {
389*7c478bd9Sstevel@tonic-gate 			if (readline(input, line) <= 0) {
390*7c478bd9Sstevel@tonic-gate 				if (n != 0)
391*7c478bd9Sstevel@tonic-gate 					break;
392*7c478bd9Sstevel@tonic-gate 				if (loading)
393*7c478bd9Sstevel@tonic-gate 					return;
394*7c478bd9Sstevel@tonic-gate 				if (sourcing) {
395*7c478bd9Sstevel@tonic-gate 					unstack();
396*7c478bd9Sstevel@tonic-gate 					goto more;
397*7c478bd9Sstevel@tonic-gate 				}
398*7c478bd9Sstevel@tonic-gate 				if (value("ignoreeof") != NOSTR && shudprompt) {
399*7c478bd9Sstevel@tonic-gate 					if (++eofloop < 25) {
400*7c478bd9Sstevel@tonic-gate 						printf(gettext(
401*7c478bd9Sstevel@tonic-gate 						    "Use \"quit\" to quit.\n"));
402*7c478bd9Sstevel@tonic-gate 						goto top;
403*7c478bd9Sstevel@tonic-gate 					}
404*7c478bd9Sstevel@tonic-gate 				}
405*7c478bd9Sstevel@tonic-gate 				return;
406*7c478bd9Sstevel@tonic-gate 			}
407*7c478bd9Sstevel@tonic-gate 			if ((n = strlen(line)) == 0)
408*7c478bd9Sstevel@tonic-gate 				break;
409*7c478bd9Sstevel@tonic-gate 			n--;
410*7c478bd9Sstevel@tonic-gate 			if (line[n] != '\\')
411*7c478bd9Sstevel@tonic-gate 				break;
412*7c478bd9Sstevel@tonic-gate 			line[n++] = ' ';
413*7c478bd9Sstevel@tonic-gate 			if (n > LINESIZE - (int)strlen(linebuf) - 1)
414*7c478bd9Sstevel@tonic-gate 				break;
415*7c478bd9Sstevel@tonic-gate 			strcat(linebuf, line);
416*7c478bd9Sstevel@tonic-gate 		}
417*7c478bd9Sstevel@tonic-gate 		n = LINESIZE - strlen(linebuf) - 1;
418*7c478bd9Sstevel@tonic-gate 		if ((int)strlen(line) > n) {
419*7c478bd9Sstevel@tonic-gate 			printf(gettext(
420*7c478bd9Sstevel@tonic-gate 		"Line plus continuation line too long:\n\t%s\n\nplus\n\t%s\n"),
421*7c478bd9Sstevel@tonic-gate 			    linebuf, line);
422*7c478bd9Sstevel@tonic-gate 			if (loading)
423*7c478bd9Sstevel@tonic-gate 				return;
424*7c478bd9Sstevel@tonic-gate 			if (sourcing) {
425*7c478bd9Sstevel@tonic-gate 				unstack();
426*7c478bd9Sstevel@tonic-gate 				goto more;
427*7c478bd9Sstevel@tonic-gate 			}
428*7c478bd9Sstevel@tonic-gate 			return;
429*7c478bd9Sstevel@tonic-gate 		}
430*7c478bd9Sstevel@tonic-gate 		strncat(linebuf, line, n);
431*7c478bd9Sstevel@tonic-gate #ifdef SIGCONT
432*7c478bd9Sstevel@tonic-gate 		sigset(SIGCONT, SIG_DFL);
433*7c478bd9Sstevel@tonic-gate #endif
434*7c478bd9Sstevel@tonic-gate 		if (execute(linebuf, 0))
435*7c478bd9Sstevel@tonic-gate 			return;
436*7c478bd9Sstevel@tonic-gate more:		;
437*7c478bd9Sstevel@tonic-gate 	}
438*7c478bd9Sstevel@tonic-gate }
439*7c478bd9Sstevel@tonic-gate 
440*7c478bd9Sstevel@tonic-gate /*
441*7c478bd9Sstevel@tonic-gate  * Execute a single command.  If the command executed
442*7c478bd9Sstevel@tonic-gate  * is "quit," then return non-zero so that the caller
443*7c478bd9Sstevel@tonic-gate  * will know to return back to main, if he cares.
444*7c478bd9Sstevel@tonic-gate  * Contxt is non-zero if called while composing mail.
445*7c478bd9Sstevel@tonic-gate  */
446*7c478bd9Sstevel@tonic-gate 
447*7c478bd9Sstevel@tonic-gate int
448*7c478bd9Sstevel@tonic-gate execute(char linebuf[], int contxt)
449*7c478bd9Sstevel@tonic-gate {
450*7c478bd9Sstevel@tonic-gate 	char word[LINESIZE];
451*7c478bd9Sstevel@tonic-gate 	char *arglist[MAXARGC];
452*7c478bd9Sstevel@tonic-gate 	const struct cmd *com;
453*7c478bd9Sstevel@tonic-gate 	register char *cp, *cp2;
454*7c478bd9Sstevel@tonic-gate 	register int c, e;
455*7c478bd9Sstevel@tonic-gate 	int muvec[2];
456*7c478bd9Sstevel@tonic-gate 
457*7c478bd9Sstevel@tonic-gate 	/*
458*7c478bd9Sstevel@tonic-gate 	 * Strip the white space away from the beginning
459*7c478bd9Sstevel@tonic-gate 	 * of the command, then scan out a word, which
460*7c478bd9Sstevel@tonic-gate 	 * consists of anything except digits and white space.
461*7c478bd9Sstevel@tonic-gate 	 *
462*7c478bd9Sstevel@tonic-gate 	 * Handle |, ! and # differently to get the correct
463*7c478bd9Sstevel@tonic-gate 	 * lexical conventions.
464*7c478bd9Sstevel@tonic-gate 	 */
465*7c478bd9Sstevel@tonic-gate 
466*7c478bd9Sstevel@tonic-gate 	cp = linebuf;
467*7c478bd9Sstevel@tonic-gate 	while (any(*cp, " \t"))
468*7c478bd9Sstevel@tonic-gate 		cp++;
469*7c478bd9Sstevel@tonic-gate 	cp2 = word;
470*7c478bd9Sstevel@tonic-gate 	if (any(*cp, "!|#"))
471*7c478bd9Sstevel@tonic-gate 		*cp2++ = *cp++;
472*7c478bd9Sstevel@tonic-gate 	else
473*7c478bd9Sstevel@tonic-gate 		while (*cp && !any(*cp, " \t0123456789$^.:/-+*'\""))
474*7c478bd9Sstevel@tonic-gate 			*cp2++ = *cp++;
475*7c478bd9Sstevel@tonic-gate 	*cp2 = '\0';
476*7c478bd9Sstevel@tonic-gate 
477*7c478bd9Sstevel@tonic-gate 	/*
478*7c478bd9Sstevel@tonic-gate 	 * Look up the command; if not found, complain.
479*7c478bd9Sstevel@tonic-gate 	 * Normally, a blank command would map to the
480*7c478bd9Sstevel@tonic-gate 	 * first command in the table; while sourcing,
481*7c478bd9Sstevel@tonic-gate 	 * however, we ignore blank lines to eliminate
482*7c478bd9Sstevel@tonic-gate 	 * confusion.
483*7c478bd9Sstevel@tonic-gate 	 */
484*7c478bd9Sstevel@tonic-gate 
485*7c478bd9Sstevel@tonic-gate 	if (sourcing && equal(word, ""))
486*7c478bd9Sstevel@tonic-gate 		return(0);
487*7c478bd9Sstevel@tonic-gate 	com = lex(word);
488*7c478bd9Sstevel@tonic-gate 	if (com == NONE) {
489*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Unknown command: \"%s\"\n"), word);
490*7c478bd9Sstevel@tonic-gate 		if (loading) {
491*7c478bd9Sstevel@tonic-gate 			cond = CANY;
492*7c478bd9Sstevel@tonic-gate 			return(1);
493*7c478bd9Sstevel@tonic-gate 		}
494*7c478bd9Sstevel@tonic-gate 		if (sourcing) {
495*7c478bd9Sstevel@tonic-gate 			cond = CANY;
496*7c478bd9Sstevel@tonic-gate 			unstack();
497*7c478bd9Sstevel@tonic-gate 		}
498*7c478bd9Sstevel@tonic-gate 		return(0);
499*7c478bd9Sstevel@tonic-gate 	}
500*7c478bd9Sstevel@tonic-gate 
501*7c478bd9Sstevel@tonic-gate 	/*
502*7c478bd9Sstevel@tonic-gate 	 * See if we should execute the command -- if a conditional
503*7c478bd9Sstevel@tonic-gate 	 * we always execute it, otherwise, check the state of cond.
504*7c478bd9Sstevel@tonic-gate 	 */
505*7c478bd9Sstevel@tonic-gate 
506*7c478bd9Sstevel@tonic-gate 	if ((com->c_argtype & F) == 0)
507*7c478bd9Sstevel@tonic-gate 		if (cond == CRCV && !rcvmode || cond == CSEND && rcvmode ||
508*7c478bd9Sstevel@tonic-gate 		    cond == CTTY && !intty || cond == CNOTTY && intty)
509*7c478bd9Sstevel@tonic-gate 			return(0);
510*7c478bd9Sstevel@tonic-gate 
511*7c478bd9Sstevel@tonic-gate 	/*
512*7c478bd9Sstevel@tonic-gate 	 * Special case so that quit causes a return to
513*7c478bd9Sstevel@tonic-gate 	 * main, who will call the quit code directly.
514*7c478bd9Sstevel@tonic-gate 	 * If we are in a source file, just unstack.
515*7c478bd9Sstevel@tonic-gate 	 */
516*7c478bd9Sstevel@tonic-gate 
517*7c478bd9Sstevel@tonic-gate 	if (com->c_func == (int (*)(void *))edstop) {
518*7c478bd9Sstevel@tonic-gate 		if (sourcing) {
519*7c478bd9Sstevel@tonic-gate 			if (loading)
520*7c478bd9Sstevel@tonic-gate 				return(1);
521*7c478bd9Sstevel@tonic-gate 			unstack();
522*7c478bd9Sstevel@tonic-gate 			return(0);
523*7c478bd9Sstevel@tonic-gate 		}
524*7c478bd9Sstevel@tonic-gate 		return(1);
525*7c478bd9Sstevel@tonic-gate 	}
526*7c478bd9Sstevel@tonic-gate 
527*7c478bd9Sstevel@tonic-gate 	/*
528*7c478bd9Sstevel@tonic-gate 	 * Process the arguments to the command, depending
529*7c478bd9Sstevel@tonic-gate 	 * on the type he expects.  Default to an error.
530*7c478bd9Sstevel@tonic-gate 	 * If we are sourcing an interactive command, it's
531*7c478bd9Sstevel@tonic-gate 	 * an error.
532*7c478bd9Sstevel@tonic-gate 	 */
533*7c478bd9Sstevel@tonic-gate 
534*7c478bd9Sstevel@tonic-gate 	if (!rcvmode && (com->c_argtype & M) == 0) {
535*7c478bd9Sstevel@tonic-gate 		fprintf(stderr,
536*7c478bd9Sstevel@tonic-gate 		    gettext("May not execute \"%s\" while sending\n"),
537*7c478bd9Sstevel@tonic-gate 		    com->c_name);
538*7c478bd9Sstevel@tonic-gate 		if (loading)
539*7c478bd9Sstevel@tonic-gate 			return(1);
540*7c478bd9Sstevel@tonic-gate 		if (sourcing)
541*7c478bd9Sstevel@tonic-gate 			unstack();
542*7c478bd9Sstevel@tonic-gate 		return(0);
543*7c478bd9Sstevel@tonic-gate 	}
544*7c478bd9Sstevel@tonic-gate 	if (sourcing && com->c_argtype & I) {
545*7c478bd9Sstevel@tonic-gate 		fprintf(stderr,
546*7c478bd9Sstevel@tonic-gate 		    gettext("May not execute \"%s\" while sourcing\n"),
547*7c478bd9Sstevel@tonic-gate 		    com->c_name);
548*7c478bd9Sstevel@tonic-gate 		rpterr = 1;
549*7c478bd9Sstevel@tonic-gate 		if (loading)
550*7c478bd9Sstevel@tonic-gate 			return(1);
551*7c478bd9Sstevel@tonic-gate 		unstack();
552*7c478bd9Sstevel@tonic-gate 		return(0);
553*7c478bd9Sstevel@tonic-gate 	}
554*7c478bd9Sstevel@tonic-gate 	if (readonly && com->c_argtype & W) {
555*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext(
556*7c478bd9Sstevel@tonic-gate 		    "May not execute \"%s\" -- message file is read only\n"),
557*7c478bd9Sstevel@tonic-gate 		    com->c_name);
558*7c478bd9Sstevel@tonic-gate 		if (loading)
559*7c478bd9Sstevel@tonic-gate 			return(1);
560*7c478bd9Sstevel@tonic-gate 		if (sourcing)
561*7c478bd9Sstevel@tonic-gate 			unstack();
562*7c478bd9Sstevel@tonic-gate 		return(0);
563*7c478bd9Sstevel@tonic-gate 	}
564*7c478bd9Sstevel@tonic-gate 	if (contxt && com->c_argtype & R) {
565*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Cannot recursively invoke \"%s\"\n"),
566*7c478bd9Sstevel@tonic-gate 		    com->c_name);
567*7c478bd9Sstevel@tonic-gate 		return(0);
568*7c478bd9Sstevel@tonic-gate 	}
569*7c478bd9Sstevel@tonic-gate 	e = 1;
570*7c478bd9Sstevel@tonic-gate 	switch (com->c_argtype & ~(F|P|I|M|T|W|R)) {
571*7c478bd9Sstevel@tonic-gate 	case MSGLIST:
572*7c478bd9Sstevel@tonic-gate 		/*
573*7c478bd9Sstevel@tonic-gate 		 * A message list defaulting to nearest forward
574*7c478bd9Sstevel@tonic-gate 		 * legal message.
575*7c478bd9Sstevel@tonic-gate 		 */
576*7c478bd9Sstevel@tonic-gate 		if (msgvec == 0) {
577*7c478bd9Sstevel@tonic-gate 			fprintf(stderr,
578*7c478bd9Sstevel@tonic-gate 			    gettext("Illegal use of \"message list\"\n"));
579*7c478bd9Sstevel@tonic-gate 			return(-1);
580*7c478bd9Sstevel@tonic-gate 		}
581*7c478bd9Sstevel@tonic-gate 		if ((c = getmsglist(cp, msgvec, com->c_msgflag)) < 0)
582*7c478bd9Sstevel@tonic-gate 			break;
583*7c478bd9Sstevel@tonic-gate 		if (c  == 0)
584*7c478bd9Sstevel@tonic-gate 			if (msgCount == 0)
585*7c478bd9Sstevel@tonic-gate 				*msgvec = NULL;
586*7c478bd9Sstevel@tonic-gate 			else {
587*7c478bd9Sstevel@tonic-gate 				*msgvec = first(com->c_msgflag,
588*7c478bd9Sstevel@tonic-gate 					com->c_msgmask);
589*7c478bd9Sstevel@tonic-gate 				msgvec[1] = NULL;
590*7c478bd9Sstevel@tonic-gate 			}
591*7c478bd9Sstevel@tonic-gate 		if (*msgvec == NULL) {
592*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, gettext("No applicable messages\n"));
593*7c478bd9Sstevel@tonic-gate 			break;
594*7c478bd9Sstevel@tonic-gate 		}
595*7c478bd9Sstevel@tonic-gate 		e = (*com->c_func)(msgvec);
596*7c478bd9Sstevel@tonic-gate 		break;
597*7c478bd9Sstevel@tonic-gate 
598*7c478bd9Sstevel@tonic-gate 	case NDMLIST:
599*7c478bd9Sstevel@tonic-gate 		/*
600*7c478bd9Sstevel@tonic-gate 		 * A message list with no defaults, but no error
601*7c478bd9Sstevel@tonic-gate 		 * if none exist.
602*7c478bd9Sstevel@tonic-gate 		 */
603*7c478bd9Sstevel@tonic-gate 		if (msgvec == 0) {
604*7c478bd9Sstevel@tonic-gate 			fprintf(stderr,
605*7c478bd9Sstevel@tonic-gate 			    gettext("Illegal use of \"message list\"\n"));
606*7c478bd9Sstevel@tonic-gate 			return(-1);
607*7c478bd9Sstevel@tonic-gate 		}
608*7c478bd9Sstevel@tonic-gate 		if (getmsglist(cp, msgvec, com->c_msgflag) < 0)
609*7c478bd9Sstevel@tonic-gate 			break;
610*7c478bd9Sstevel@tonic-gate 		e = (*com->c_func)(msgvec);
611*7c478bd9Sstevel@tonic-gate 		break;
612*7c478bd9Sstevel@tonic-gate 
613*7c478bd9Sstevel@tonic-gate 	case STRLIST:
614*7c478bd9Sstevel@tonic-gate 		/*
615*7c478bd9Sstevel@tonic-gate 		 * Just the straight string, with
616*7c478bd9Sstevel@tonic-gate 		 * leading blanks removed.
617*7c478bd9Sstevel@tonic-gate 		 */
618*7c478bd9Sstevel@tonic-gate 		while (any(*cp, " \t"))
619*7c478bd9Sstevel@tonic-gate 			cp++;
620*7c478bd9Sstevel@tonic-gate 		e = (*com->c_func)(cp);
621*7c478bd9Sstevel@tonic-gate 		break;
622*7c478bd9Sstevel@tonic-gate 
623*7c478bd9Sstevel@tonic-gate 	case RAWLIST:
624*7c478bd9Sstevel@tonic-gate 		/*
625*7c478bd9Sstevel@tonic-gate 		 * A vector of strings, in shell style.
626*7c478bd9Sstevel@tonic-gate 		 */
627*7c478bd9Sstevel@tonic-gate 		if ((c = getrawlist(cp, arglist,
628*7c478bd9Sstevel@tonic-gate 				sizeof arglist / sizeof *arglist)) < 0)
629*7c478bd9Sstevel@tonic-gate 			break;
630*7c478bd9Sstevel@tonic-gate 		if (c < com->c_minargs) {
631*7c478bd9Sstevel@tonic-gate 			fprintf(stderr,
632*7c478bd9Sstevel@tonic-gate 			    gettext("%s requires at least %d arg(s)\n"),
633*7c478bd9Sstevel@tonic-gate 			    com->c_name, com->c_minargs);
634*7c478bd9Sstevel@tonic-gate 			break;
635*7c478bd9Sstevel@tonic-gate 		}
636*7c478bd9Sstevel@tonic-gate 		if (c > com->c_maxargs) {
637*7c478bd9Sstevel@tonic-gate 			fprintf(stderr,
638*7c478bd9Sstevel@tonic-gate 			    gettext("%s takes no more than %d arg(s)\n"),
639*7c478bd9Sstevel@tonic-gate 			    com->c_name, com->c_maxargs);
640*7c478bd9Sstevel@tonic-gate 			break;
641*7c478bd9Sstevel@tonic-gate 		}
642*7c478bd9Sstevel@tonic-gate 		e = (*com->c_func)(arglist);
643*7c478bd9Sstevel@tonic-gate 		break;
644*7c478bd9Sstevel@tonic-gate 
645*7c478bd9Sstevel@tonic-gate 	case NOLIST:
646*7c478bd9Sstevel@tonic-gate 		/*
647*7c478bd9Sstevel@tonic-gate 		 * Just the constant zero, for exiting,
648*7c478bd9Sstevel@tonic-gate 		 * eg.
649*7c478bd9Sstevel@tonic-gate 		 */
650*7c478bd9Sstevel@tonic-gate 		e = (*com->c_func)(0);
651*7c478bd9Sstevel@tonic-gate 		break;
652*7c478bd9Sstevel@tonic-gate 
653*7c478bd9Sstevel@tonic-gate 	default:
654*7c478bd9Sstevel@tonic-gate 		panic("Unknown argtype");
655*7c478bd9Sstevel@tonic-gate 	}
656*7c478bd9Sstevel@tonic-gate 
657*7c478bd9Sstevel@tonic-gate 	/*
658*7c478bd9Sstevel@tonic-gate 	 * Exit the current source file on
659*7c478bd9Sstevel@tonic-gate 	 * error.
660*7c478bd9Sstevel@tonic-gate 	 */
661*7c478bd9Sstevel@tonic-gate 
662*7c478bd9Sstevel@tonic-gate 	if (e && loading)
663*7c478bd9Sstevel@tonic-gate 		return(1);
664*7c478bd9Sstevel@tonic-gate 	if (e && sourcing)
665*7c478bd9Sstevel@tonic-gate 		unstack();
666*7c478bd9Sstevel@tonic-gate 	if (com->c_func == (int (*)(void *))edstop)
667*7c478bd9Sstevel@tonic-gate 		return(1);
668*7c478bd9Sstevel@tonic-gate 	if (value("autoprint") != NOSTR && com->c_argtype & P)
669*7c478bd9Sstevel@tonic-gate 		if ((dot->m_flag & MDELETED) == 0) {
670*7c478bd9Sstevel@tonic-gate 			muvec[0] = dot - &message[0] + 1;
671*7c478bd9Sstevel@tonic-gate 			muvec[1] = 0;
672*7c478bd9Sstevel@tonic-gate 			type(muvec);
673*7c478bd9Sstevel@tonic-gate 		}
674*7c478bd9Sstevel@tonic-gate 	if (!sourcing && (com->c_argtype & T) == 0)
675*7c478bd9Sstevel@tonic-gate 		sawcom = 1;
676*7c478bd9Sstevel@tonic-gate 	return(0);
677*7c478bd9Sstevel@tonic-gate }
678*7c478bd9Sstevel@tonic-gate 
679*7c478bd9Sstevel@tonic-gate #ifdef SIGCONT
680*7c478bd9Sstevel@tonic-gate /*
681*7c478bd9Sstevel@tonic-gate  * When we wake up after ^Z, reprint the prompt.
682*7c478bd9Sstevel@tonic-gate  */
683*7c478bd9Sstevel@tonic-gate static void
684*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
685*7c478bd9Sstevel@tonic-gate contin(int)
686*7c478bd9Sstevel@tonic-gate #else
687*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
688*7c478bd9Sstevel@tonic-gate contin(int s)
689*7c478bd9Sstevel@tonic-gate #endif
690*7c478bd9Sstevel@tonic-gate {
691*7c478bd9Sstevel@tonic-gate 	if (shudprompt)
692*7c478bd9Sstevel@tonic-gate 		printf("%s", prompt);
693*7c478bd9Sstevel@tonic-gate 	fflush(stdout);
694*7c478bd9Sstevel@tonic-gate }
695*7c478bd9Sstevel@tonic-gate #endif
696*7c478bd9Sstevel@tonic-gate 
697*7c478bd9Sstevel@tonic-gate /*
698*7c478bd9Sstevel@tonic-gate  * Branch here on hangup signal and simulate quit.
699*7c478bd9Sstevel@tonic-gate  */
700*7c478bd9Sstevel@tonic-gate void
701*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
702*7c478bd9Sstevel@tonic-gate hangup(int)
703*7c478bd9Sstevel@tonic-gate #else
704*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
705*7c478bd9Sstevel@tonic-gate hangup(int s)
706*7c478bd9Sstevel@tonic-gate #endif
707*7c478bd9Sstevel@tonic-gate {
708*7c478bd9Sstevel@tonic-gate 
709*7c478bd9Sstevel@tonic-gate 	holdsigs();
710*7c478bd9Sstevel@tonic-gate # ifdef OLD_BSD_SIGS
711*7c478bd9Sstevel@tonic-gate 	sigignore(SIGHUP);
712*7c478bd9Sstevel@tonic-gate # endif
713*7c478bd9Sstevel@tonic-gate 	if (edit) {
714*7c478bd9Sstevel@tonic-gate 		if (setjmp(srbuf))
715*7c478bd9Sstevel@tonic-gate 			exit(rpterr);
716*7c478bd9Sstevel@tonic-gate 		edstop(0);
717*7c478bd9Sstevel@tonic-gate 	} else {
718*7c478bd9Sstevel@tonic-gate 		if (issysmbox)
719*7c478bd9Sstevel@tonic-gate 			Verhogen();
720*7c478bd9Sstevel@tonic-gate 		if (value("exit") != NOSTR)
721*7c478bd9Sstevel@tonic-gate 			exit(1);
722*7c478bd9Sstevel@tonic-gate 		else
723*7c478bd9Sstevel@tonic-gate 			quit(0);
724*7c478bd9Sstevel@tonic-gate 	}
725*7c478bd9Sstevel@tonic-gate 	exit(rpterr);
726*7c478bd9Sstevel@tonic-gate }
727*7c478bd9Sstevel@tonic-gate 
728*7c478bd9Sstevel@tonic-gate /*
729*7c478bd9Sstevel@tonic-gate  * Set the size of the message vector used to construct argument
730*7c478bd9Sstevel@tonic-gate  * lists to message list functions.
731*7c478bd9Sstevel@tonic-gate  */
732*7c478bd9Sstevel@tonic-gate 
733*7c478bd9Sstevel@tonic-gate static void
734*7c478bd9Sstevel@tonic-gate setmsize(int sz)
735*7c478bd9Sstevel@tonic-gate {
736*7c478bd9Sstevel@tonic-gate 
737*7c478bd9Sstevel@tonic-gate 	if (msgvec != (int *) 0)
738*7c478bd9Sstevel@tonic-gate 		free(msgvec);
739*7c478bd9Sstevel@tonic-gate 	if (sz < 1)
740*7c478bd9Sstevel@tonic-gate 		sz = 1; /* need at least one cell for terminating 0 */
741*7c478bd9Sstevel@tonic-gate 	if ((msgvec = (int *)
742*7c478bd9Sstevel@tonic-gate 	    calloc((unsigned)(sz + 1), sizeof (*msgvec))) == NULL)
743*7c478bd9Sstevel@tonic-gate 		panic("Failed to allocate memory for message vector");
744*7c478bd9Sstevel@tonic-gate }
745*7c478bd9Sstevel@tonic-gate 
746*7c478bd9Sstevel@tonic-gate /*
747*7c478bd9Sstevel@tonic-gate  * Find the correct command in the command table corresponding
748*7c478bd9Sstevel@tonic-gate  * to the passed command "word"
749*7c478bd9Sstevel@tonic-gate  */
750*7c478bd9Sstevel@tonic-gate 
751*7c478bd9Sstevel@tonic-gate static const struct cmd *
752*7c478bd9Sstevel@tonic-gate lex(char word[])
753*7c478bd9Sstevel@tonic-gate {
754*7c478bd9Sstevel@tonic-gate 	register const struct cmd *cp;
755*7c478bd9Sstevel@tonic-gate 
756*7c478bd9Sstevel@tonic-gate 	for (cp = &cmdtab[0]; cp->c_name != NOSTR; cp++)
757*7c478bd9Sstevel@tonic-gate 		if (isprefix(word, cp->c_name))
758*7c478bd9Sstevel@tonic-gate 			return(cp);
759*7c478bd9Sstevel@tonic-gate 	return(NONE);
760*7c478bd9Sstevel@tonic-gate }
761*7c478bd9Sstevel@tonic-gate 
762*7c478bd9Sstevel@tonic-gate /*
763*7c478bd9Sstevel@tonic-gate  * Determine if as1 is a valid prefix of as2.
764*7c478bd9Sstevel@tonic-gate  */
765*7c478bd9Sstevel@tonic-gate static int
766*7c478bd9Sstevel@tonic-gate isprefix(char *as1, char *as2)
767*7c478bd9Sstevel@tonic-gate {
768*7c478bd9Sstevel@tonic-gate 	register char *s1, *s2;
769*7c478bd9Sstevel@tonic-gate 
770*7c478bd9Sstevel@tonic-gate 	s1 = as1;
771*7c478bd9Sstevel@tonic-gate 	s2 = as2;
772*7c478bd9Sstevel@tonic-gate 	while (*s1++ == *s2)
773*7c478bd9Sstevel@tonic-gate 		if (*s2++ == '\0')
774*7c478bd9Sstevel@tonic-gate 			return(1);
775*7c478bd9Sstevel@tonic-gate 	return(*--s1 == '\0');
776*7c478bd9Sstevel@tonic-gate }
777*7c478bd9Sstevel@tonic-gate 
778*7c478bd9Sstevel@tonic-gate /*
779*7c478bd9Sstevel@tonic-gate  * The following gets called on receipt of a rubout.  This is
780*7c478bd9Sstevel@tonic-gate  * to abort printout of a command, mainly.
781*7c478bd9Sstevel@tonic-gate  * Dispatching here when command() is inactive crashes rcv.
782*7c478bd9Sstevel@tonic-gate  * Close all open files except 0, 1, 2, and the temporary.
783*7c478bd9Sstevel@tonic-gate  * The special call to getuserid() is needed so it won't get
784*7c478bd9Sstevel@tonic-gate  * annoyed about losing its open file.
785*7c478bd9Sstevel@tonic-gate  * Also, unstack all source files.
786*7c478bd9Sstevel@tonic-gate  */
787*7c478bd9Sstevel@tonic-gate 
788*7c478bd9Sstevel@tonic-gate static int	inithdr;		/* am printing startup headers */
789*7c478bd9Sstevel@tonic-gate 
790*7c478bd9Sstevel@tonic-gate void
791*7c478bd9Sstevel@tonic-gate stop(int s)
792*7c478bd9Sstevel@tonic-gate {
793*7c478bd9Sstevel@tonic-gate 	register NODE *head;
794*7c478bd9Sstevel@tonic-gate 
795*7c478bd9Sstevel@tonic-gate 	noreset = 0;
796*7c478bd9Sstevel@tonic-gate 	if (!inithdr)
797*7c478bd9Sstevel@tonic-gate 		sawcom++;
798*7c478bd9Sstevel@tonic-gate 	inithdr = 0;
799*7c478bd9Sstevel@tonic-gate 	while (sourcing)
800*7c478bd9Sstevel@tonic-gate 		unstack();
801*7c478bd9Sstevel@tonic-gate 	getuserid((char *) 0);
802*7c478bd9Sstevel@tonic-gate 	for (head = fplist; head != (NODE *)NULL; head = head->next) {
803*7c478bd9Sstevel@tonic-gate 		if (head->fp == stdin || head->fp == stdout)
804*7c478bd9Sstevel@tonic-gate 			continue;
805*7c478bd9Sstevel@tonic-gate 		if (head->fp == itf || head->fp == otf)
806*7c478bd9Sstevel@tonic-gate 			continue;
807*7c478bd9Sstevel@tonic-gate 		if (head->fp == stderr)
808*7c478bd9Sstevel@tonic-gate 			continue;
809*7c478bd9Sstevel@tonic-gate 		if (head->fp == semfp)
810*7c478bd9Sstevel@tonic-gate 			continue;
811*7c478bd9Sstevel@tonic-gate 		if (head->fp == pipef) {
812*7c478bd9Sstevel@tonic-gate 			npclose(pipef);
813*7c478bd9Sstevel@tonic-gate 			pipef = NULL;
814*7c478bd9Sstevel@tonic-gate 			continue;
815*7c478bd9Sstevel@tonic-gate 		}
816*7c478bd9Sstevel@tonic-gate 		fclose(head->fp);
817*7c478bd9Sstevel@tonic-gate 	}
818*7c478bd9Sstevel@tonic-gate 	if (image >= 0) {
819*7c478bd9Sstevel@tonic-gate 		close(image);
820*7c478bd9Sstevel@tonic-gate 		image = -1;
821*7c478bd9Sstevel@tonic-gate 	}
822*7c478bd9Sstevel@tonic-gate 	if (s) {
823*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Interrupt\n"));
824*7c478bd9Sstevel@tonic-gate 		fflush(stderr);
825*7c478bd9Sstevel@tonic-gate # ifdef OLD_BSD_SIGS
826*7c478bd9Sstevel@tonic-gate 		sigrelse(s);
827*7c478bd9Sstevel@tonic-gate # endif
828*7c478bd9Sstevel@tonic-gate 	}
829*7c478bd9Sstevel@tonic-gate 	longjmp(srbuf, 1);
830*7c478bd9Sstevel@tonic-gate }
831*7c478bd9Sstevel@tonic-gate 
832*7c478bd9Sstevel@tonic-gate /*
833*7c478bd9Sstevel@tonic-gate  * Announce the presence of the current mailx version,
834*7c478bd9Sstevel@tonic-gate  * give the message count, and print a header listing.
835*7c478bd9Sstevel@tonic-gate  */
836*7c478bd9Sstevel@tonic-gate 
837*7c478bd9Sstevel@tonic-gate #define	GREETING	"%s  Type ? for help.\n"
838*7c478bd9Sstevel@tonic-gate 
839*7c478bd9Sstevel@tonic-gate void
840*7c478bd9Sstevel@tonic-gate announce(void)
841*7c478bd9Sstevel@tonic-gate {
842*7c478bd9Sstevel@tonic-gate 	int vec[2], mdot;
843*7c478bd9Sstevel@tonic-gate 	extern const char *const version;
844*7c478bd9Sstevel@tonic-gate 
845*7c478bd9Sstevel@tonic-gate 	if (!Hflag && value("quiet")==NOSTR)
846*7c478bd9Sstevel@tonic-gate 		printf(gettext(GREETING), version);
847*7c478bd9Sstevel@tonic-gate 	mdot = newfileinfo(1);
848*7c478bd9Sstevel@tonic-gate 	vec[0] = mdot;
849*7c478bd9Sstevel@tonic-gate 	vec[1] = 0;
850*7c478bd9Sstevel@tonic-gate 	dot = &message[mdot - 1];
851*7c478bd9Sstevel@tonic-gate 	if (msgCount > 0 && !noheader) {
852*7c478bd9Sstevel@tonic-gate 		inithdr++;
853*7c478bd9Sstevel@tonic-gate 		headers(vec);
854*7c478bd9Sstevel@tonic-gate 		inithdr = 0;
855*7c478bd9Sstevel@tonic-gate 	}
856*7c478bd9Sstevel@tonic-gate }
857*7c478bd9Sstevel@tonic-gate 
858*7c478bd9Sstevel@tonic-gate /*
859*7c478bd9Sstevel@tonic-gate  * Announce information about the file we are editing.
860*7c478bd9Sstevel@tonic-gate  * Return a likely place to set dot.
861*7c478bd9Sstevel@tonic-gate  */
862*7c478bd9Sstevel@tonic-gate int
863*7c478bd9Sstevel@tonic-gate newfileinfo(int start)
864*7c478bd9Sstevel@tonic-gate {
865*7c478bd9Sstevel@tonic-gate 	register struct message *mp;
866*7c478bd9Sstevel@tonic-gate 	register int u, n, mdot, d, s;
867*7c478bd9Sstevel@tonic-gate 	char fname[BUFSIZ], zname[BUFSIZ], *ename;
868*7c478bd9Sstevel@tonic-gate 
869*7c478bd9Sstevel@tonic-gate 	if (Hflag)
870*7c478bd9Sstevel@tonic-gate 		return(1);		/* fake it--return message 1 */
871*7c478bd9Sstevel@tonic-gate 	for (mp = &message[start - 1]; mp < &message[msgCount]; mp++)
872*7c478bd9Sstevel@tonic-gate 		if ((mp->m_flag & (MNEW|MREAD)) == MNEW)
873*7c478bd9Sstevel@tonic-gate 			break;
874*7c478bd9Sstevel@tonic-gate 	if (mp >= &message[msgCount])
875*7c478bd9Sstevel@tonic-gate 		for (mp = &message[start - 1]; mp < &message[msgCount]; mp++)
876*7c478bd9Sstevel@tonic-gate 			if ((mp->m_flag & MREAD) == 0)
877*7c478bd9Sstevel@tonic-gate 				break;
878*7c478bd9Sstevel@tonic-gate 	if (mp < &message[msgCount])
879*7c478bd9Sstevel@tonic-gate 		mdot = mp - &message[0] + 1;
880*7c478bd9Sstevel@tonic-gate 	else
881*7c478bd9Sstevel@tonic-gate 		mdot = 1;
882*7c478bd9Sstevel@tonic-gate 	n = u = d = s = 0;
883*7c478bd9Sstevel@tonic-gate 	for (mp = &message[start - 1]; mp < &message[msgCount]; mp++) {
884*7c478bd9Sstevel@tonic-gate 		if (mp->m_flag & MNEW)
885*7c478bd9Sstevel@tonic-gate 			n++;
886*7c478bd9Sstevel@tonic-gate 		if ((mp->m_flag & MREAD) == 0)
887*7c478bd9Sstevel@tonic-gate 			u++;
888*7c478bd9Sstevel@tonic-gate 		if (mp->m_flag & MDELETED)
889*7c478bd9Sstevel@tonic-gate 			d++;
890*7c478bd9Sstevel@tonic-gate 		if (mp->m_flag & MSAVED)
891*7c478bd9Sstevel@tonic-gate 			s++;
892*7c478bd9Sstevel@tonic-gate 	}
893*7c478bd9Sstevel@tonic-gate 	ename=origname;
894*7c478bd9Sstevel@tonic-gate 	if (getfold(fname) >= 0) {
895*7c478bd9Sstevel@tonic-gate 		nstrcat(fname, sizeof (fname), "/");
896*7c478bd9Sstevel@tonic-gate 		if (strncmp(fname, editfile, strlen(fname)) == 0) {
897*7c478bd9Sstevel@tonic-gate 			snprintf(zname, sizeof (zname),
898*7c478bd9Sstevel@tonic-gate 				"+%s", editfile + strlen(fname));
899*7c478bd9Sstevel@tonic-gate 			ename = zname;
900*7c478bd9Sstevel@tonic-gate 		}
901*7c478bd9Sstevel@tonic-gate 	}
902*7c478bd9Sstevel@tonic-gate 	printf("\"%s\": ", ename);
903*7c478bd9Sstevel@tonic-gate 	if (msgCount == 1)
904*7c478bd9Sstevel@tonic-gate 		printf(gettext("1 message"));
905*7c478bd9Sstevel@tonic-gate 	else
906*7c478bd9Sstevel@tonic-gate 		printf(gettext("%d messages"), msgCount);
907*7c478bd9Sstevel@tonic-gate 	if (n > 0)
908*7c478bd9Sstevel@tonic-gate 		printf(gettext(" %d new"), n);
909*7c478bd9Sstevel@tonic-gate 	if (u-n > 0)
910*7c478bd9Sstevel@tonic-gate 		printf(gettext(" %d unread"), u);
911*7c478bd9Sstevel@tonic-gate 	if (d > 0)
912*7c478bd9Sstevel@tonic-gate 		printf(gettext(" %d deleted"), d);
913*7c478bd9Sstevel@tonic-gate 	if (s > 0)
914*7c478bd9Sstevel@tonic-gate 		printf(gettext(" %d saved"), s);
915*7c478bd9Sstevel@tonic-gate 	if (readonly)
916*7c478bd9Sstevel@tonic-gate 		printf(gettext(" [Read only]"));
917*7c478bd9Sstevel@tonic-gate 	printf("\n");
918*7c478bd9Sstevel@tonic-gate 	return(mdot);
919*7c478bd9Sstevel@tonic-gate }
920*7c478bd9Sstevel@tonic-gate 
921*7c478bd9Sstevel@tonic-gate /*
922*7c478bd9Sstevel@tonic-gate  * Print the current version number.
923*7c478bd9Sstevel@tonic-gate  */
924*7c478bd9Sstevel@tonic-gate 
925*7c478bd9Sstevel@tonic-gate int
926*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
927*7c478bd9Sstevel@tonic-gate pversion(char *)
928*7c478bd9Sstevel@tonic-gate #else
929*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
930*7c478bd9Sstevel@tonic-gate pversion(char *s)
931*7c478bd9Sstevel@tonic-gate #endif
932*7c478bd9Sstevel@tonic-gate {
933*7c478bd9Sstevel@tonic-gate 	printf("%s\n", version);
934*7c478bd9Sstevel@tonic-gate 	return(0);
935*7c478bd9Sstevel@tonic-gate }
936*7c478bd9Sstevel@tonic-gate 
937*7c478bd9Sstevel@tonic-gate /*
938*7c478bd9Sstevel@tonic-gate  * Load a file of user definitions.
939*7c478bd9Sstevel@tonic-gate  */
940*7c478bd9Sstevel@tonic-gate void
941*7c478bd9Sstevel@tonic-gate load(char *name)
942*7c478bd9Sstevel@tonic-gate {
943*7c478bd9Sstevel@tonic-gate 	register FILE *in, *oldin;
944*7c478bd9Sstevel@tonic-gate 
945*7c478bd9Sstevel@tonic-gate 	if ((in = fopen(name, "r")) == NULL)
946*7c478bd9Sstevel@tonic-gate 		return;
947*7c478bd9Sstevel@tonic-gate 	oldin = input;
948*7c478bd9Sstevel@tonic-gate 	input = in;
949*7c478bd9Sstevel@tonic-gate 	loading = 1;
950*7c478bd9Sstevel@tonic-gate 	sourcing = 1;
951*7c478bd9Sstevel@tonic-gate 	commands();
952*7c478bd9Sstevel@tonic-gate 	loading = 0;
953*7c478bd9Sstevel@tonic-gate 	sourcing = 0;
954*7c478bd9Sstevel@tonic-gate 	input = oldin;
955*7c478bd9Sstevel@tonic-gate 	fclose(in);
956*7c478bd9Sstevel@tonic-gate }
957*7c478bd9Sstevel@tonic-gate 
958*7c478bd9Sstevel@tonic-gate /*
959*7c478bd9Sstevel@tonic-gate  * Incorporate any new mail into the current session.
960*7c478bd9Sstevel@tonic-gate  *
961*7c478bd9Sstevel@tonic-gate  * XXX - Since autoinc works on "edited" files as well as the
962*7c478bd9Sstevel@tonic-gate  * system mailbox, this probably ought to as well.
963*7c478bd9Sstevel@tonic-gate  */
964*7c478bd9Sstevel@tonic-gate 
965*7c478bd9Sstevel@tonic-gate int
966*7c478bd9Sstevel@tonic-gate inc(void)
967*7c478bd9Sstevel@tonic-gate {
968*7c478bd9Sstevel@tonic-gate 	FILE *ibuf;
969*7c478bd9Sstevel@tonic-gate 	int mdot;
970*7c478bd9Sstevel@tonic-gate 	struct stat stbuf;
971*7c478bd9Sstevel@tonic-gate 	int firstnewmsg = msgCount + 1;
972*7c478bd9Sstevel@tonic-gate 
973*7c478bd9Sstevel@tonic-gate 	if (edit) {
974*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Not in system mailbox\n"));
975*7c478bd9Sstevel@tonic-gate 		return(-1);
976*7c478bd9Sstevel@tonic-gate 	}
977*7c478bd9Sstevel@tonic-gate 	if (((ibuf = fopen(mailname, "r")) == NULL) ||
978*7c478bd9Sstevel@tonic-gate 	    (fstat(fileno(ibuf), &stbuf) < 0) || stbuf.st_size == 0L ||
979*7c478bd9Sstevel@tonic-gate 	    stbuf.st_size == mailsize || (stbuf.st_mode&S_IFMT) != S_IFREG) {
980*7c478bd9Sstevel@tonic-gate 		if (strrchr(mailname, '/') == NOSTR)
981*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, gettext("No new mail.\n"));
982*7c478bd9Sstevel@tonic-gate 		else
983*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, gettext("No new mail for %s\n"),
984*7c478bd9Sstevel@tonic-gate 			    strrchr(mailname, '/')+1);
985*7c478bd9Sstevel@tonic-gate 		if (ibuf != NULL)
986*7c478bd9Sstevel@tonic-gate 			fclose(ibuf);
987*7c478bd9Sstevel@tonic-gate 		return(-1);
988*7c478bd9Sstevel@tonic-gate 	}
989*7c478bd9Sstevel@tonic-gate 
990*7c478bd9Sstevel@tonic-gate 	fseek(otf, 0L, 2);
991*7c478bd9Sstevel@tonic-gate 	holdsigs();
992*7c478bd9Sstevel@tonic-gate 	if (issysmbox)
993*7c478bd9Sstevel@tonic-gate 		lockmail();
994*7c478bd9Sstevel@tonic-gate 	fseek(ibuf, mailsize, 0);
995*7c478bd9Sstevel@tonic-gate 	mailsize = fsize(ibuf);
996*7c478bd9Sstevel@tonic-gate 	setptr(ibuf);
997*7c478bd9Sstevel@tonic-gate 	setmsize(msgCount);
998*7c478bd9Sstevel@tonic-gate 	fclose(ibuf);
999*7c478bd9Sstevel@tonic-gate 	if (issysmbox)
1000*7c478bd9Sstevel@tonic-gate 		unlockmail();
1001*7c478bd9Sstevel@tonic-gate 	relsesigs();
1002*7c478bd9Sstevel@tonic-gate 	mdot = newfileinfo(firstnewmsg);
1003*7c478bd9Sstevel@tonic-gate 	dot = &message[mdot - 1];
1004*7c478bd9Sstevel@tonic-gate 	sawcom = 0;
1005*7c478bd9Sstevel@tonic-gate 	return(0);
1006*7c478bd9Sstevel@tonic-gate }
1007