xref: /freebsd/usr.bin/mail/cmd2.c (revision 0c3a8314c00f58f16823e8cd6186757d5e8bcdcc)
19b50d902SRodney W. Grimes /*
29b50d902SRodney W. Grimes  * Copyright (c) 1980, 1993
39b50d902SRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
49b50d902SRodney W. Grimes  *
59b50d902SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
69b50d902SRodney W. Grimes  * modification, are permitted provided that the following conditions
79b50d902SRodney W. Grimes  * are met:
89b50d902SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
99b50d902SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
109b50d902SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
119b50d902SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
129b50d902SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
139b50d902SRodney W. Grimes  * 3. All advertising materials mentioning features or use of this software
149b50d902SRodney W. Grimes  *    must display the following acknowledgement:
159b50d902SRodney W. Grimes  *	This product includes software developed by the University of
169b50d902SRodney W. Grimes  *	California, Berkeley and its contributors.
179b50d902SRodney W. Grimes  * 4. Neither the name of the University nor the names of its contributors
189b50d902SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
199b50d902SRodney W. Grimes  *    without specific prior written permission.
209b50d902SRodney W. Grimes  *
219b50d902SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
229b50d902SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
239b50d902SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
249b50d902SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
259b50d902SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
269b50d902SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
279b50d902SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
289b50d902SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
299b50d902SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
309b50d902SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
319b50d902SRodney W. Grimes  * SUCH DAMAGE.
329b50d902SRodney W. Grimes  */
339b50d902SRodney W. Grimes 
349b50d902SRodney W. Grimes #ifndef lint
350c3a8314SMike Heffner #if 0
369b50d902SRodney W. Grimes static char sccsid[] = "@(#)cmd2.c	8.1 (Berkeley) 6/6/93";
370c3a8314SMike Heffner #endif
380c3a8314SMike Heffner static const char rcsid[] =
390c3a8314SMike Heffner   "$FreeBSD$";
409b50d902SRodney W. Grimes #endif /* not lint */
419b50d902SRodney W. Grimes 
429b50d902SRodney W. Grimes #include "rcv.h"
439b50d902SRodney W. Grimes #include <sys/wait.h>
449b50d902SRodney W. Grimes #include "extern.h"
459b50d902SRodney W. Grimes 
469b50d902SRodney W. Grimes /*
479b50d902SRodney W. Grimes  * Mail -- a mail program
489b50d902SRodney W. Grimes  *
499b50d902SRodney W. Grimes  * More user commands.
509b50d902SRodney W. Grimes  */
519b50d902SRodney W. Grimes 
529b50d902SRodney W. Grimes /*
539b50d902SRodney W. Grimes  * If any arguments were given, go to the next applicable argument
549b50d902SRodney W. Grimes  * following dot, otherwise, go to the next applicable message.
559b50d902SRodney W. Grimes  * If given as first command with no arguments, print first message.
569b50d902SRodney W. Grimes  */
579b50d902SRodney W. Grimes int
589b50d902SRodney W. Grimes next(msgvec)
599b50d902SRodney W. Grimes 	int *msgvec;
609b50d902SRodney W. Grimes {
619b50d902SRodney W. Grimes 	register struct message *mp;
629b50d902SRodney W. Grimes 	register int *ip, *ip2;
639b50d902SRodney W. Grimes 	int list[2], mdot;
649b50d902SRodney W. Grimes 
65d030d2d2SPoul-Henning Kamp 	if (*msgvec != 0) {
669b50d902SRodney W. Grimes 
679b50d902SRodney W. Grimes 		/*
689b50d902SRodney W. Grimes 		 * If some messages were supplied, find the
699b50d902SRodney W. Grimes 		 * first applicable one following dot using
709b50d902SRodney W. Grimes 		 * wrap around.
719b50d902SRodney W. Grimes 		 */
729b50d902SRodney W. Grimes 
739b50d902SRodney W. Grimes 		mdot = dot - &message[0] + 1;
749b50d902SRodney W. Grimes 
759b50d902SRodney W. Grimes 		/*
769b50d902SRodney W. Grimes 		 * Find the first message in the supplied
779b50d902SRodney W. Grimes 		 * message list which follows dot.
789b50d902SRodney W. Grimes 		 */
799b50d902SRodney W. Grimes 
80d030d2d2SPoul-Henning Kamp 		for (ip = msgvec; *ip != 0; ip++)
819b50d902SRodney W. Grimes 			if (*ip > mdot)
829b50d902SRodney W. Grimes 				break;
83d030d2d2SPoul-Henning Kamp 		if (*ip == 0)
849b50d902SRodney W. Grimes 			ip = msgvec;
859b50d902SRodney W. Grimes 		ip2 = ip;
869b50d902SRodney W. Grimes 		do {
879b50d902SRodney W. Grimes 			mp = &message[*ip2 - 1];
889b50d902SRodney W. Grimes 			if ((mp->m_flag & MDELETED) == 0) {
899b50d902SRodney W. Grimes 				dot = mp;
909b50d902SRodney W. Grimes 				goto hitit;
919b50d902SRodney W. Grimes 			}
92d030d2d2SPoul-Henning Kamp 			if (*ip2 != 0)
939b50d902SRodney W. Grimes 				ip2++;
94d030d2d2SPoul-Henning Kamp 			if (*ip2 == 0)
959b50d902SRodney W. Grimes 				ip2 = msgvec;
969b50d902SRodney W. Grimes 		} while (ip2 != ip);
979b50d902SRodney W. Grimes 		printf("No messages applicable\n");
989b50d902SRodney W. Grimes 		return(1);
999b50d902SRodney W. Grimes 	}
1009b50d902SRodney W. Grimes 
1019b50d902SRodney W. Grimes 	/*
1029b50d902SRodney W. Grimes 	 * If this is the first command, select message 1.
1039b50d902SRodney W. Grimes 	 * Note that this must exist for us to get here at all.
1049b50d902SRodney W. Grimes 	 */
1059b50d902SRodney W. Grimes 
1069b50d902SRodney W. Grimes 	if (!sawcom)
1079b50d902SRodney W. Grimes 		goto hitit;
1089b50d902SRodney W. Grimes 
1099b50d902SRodney W. Grimes 	/*
1109b50d902SRodney W. Grimes 	 * Just find the next good message after dot, no
1119b50d902SRodney W. Grimes 	 * wraparound.
1129b50d902SRodney W. Grimes 	 */
1139b50d902SRodney W. Grimes 
1149b50d902SRodney W. Grimes 	for (mp = dot+1; mp < &message[msgCount]; mp++)
1159b50d902SRodney W. Grimes 		if ((mp->m_flag & (MDELETED|MSAVED)) == 0)
1169b50d902SRodney W. Grimes 			break;
1179b50d902SRodney W. Grimes 	if (mp >= &message[msgCount]) {
1189b50d902SRodney W. Grimes 		printf("At EOF\n");
1199b50d902SRodney W. Grimes 		return(0);
1209b50d902SRodney W. Grimes 	}
1219b50d902SRodney W. Grimes 	dot = mp;
1229b50d902SRodney W. Grimes hitit:
1239b50d902SRodney W. Grimes 	/*
1249b50d902SRodney W. Grimes 	 * Print dot.
1259b50d902SRodney W. Grimes 	 */
1269b50d902SRodney W. Grimes 
1279b50d902SRodney W. Grimes 	list[0] = dot - &message[0] + 1;
128d030d2d2SPoul-Henning Kamp 	list[1] = 0;
1299b50d902SRodney W. Grimes 	return(type(list));
1309b50d902SRodney W. Grimes }
1319b50d902SRodney W. Grimes 
1329b50d902SRodney W. Grimes /*
1339b50d902SRodney W. Grimes  * Save a message in a file.  Mark the message as saved
1349b50d902SRodney W. Grimes  * so we can discard when the user quits.
1359b50d902SRodney W. Grimes  */
1369b50d902SRodney W. Grimes int
1379b50d902SRodney W. Grimes save(str)
1389b50d902SRodney W. Grimes 	char str[];
1399b50d902SRodney W. Grimes {
1409b50d902SRodney W. Grimes 
1419b50d902SRodney W. Grimes 	return save1(str, 1, "save", saveignore);
1429b50d902SRodney W. Grimes }
1439b50d902SRodney W. Grimes 
1449b50d902SRodney W. Grimes /*
1459b50d902SRodney W. Grimes  * Copy a message to a file without affected its saved-ness
1469b50d902SRodney W. Grimes  */
1479b50d902SRodney W. Grimes int
1489b50d902SRodney W. Grimes copycmd(str)
1499b50d902SRodney W. Grimes 	char str[];
1509b50d902SRodney W. Grimes {
1519b50d902SRodney W. Grimes 
1529b50d902SRodney W. Grimes 	return save1(str, 0, "copy", saveignore);
1539b50d902SRodney W. Grimes }
1549b50d902SRodney W. Grimes 
1559b50d902SRodney W. Grimes /*
1569b50d902SRodney W. Grimes  * Save/copy the indicated messages at the end of the passed file name.
1579b50d902SRodney W. Grimes  * If mark is true, mark the message "saved."
1589b50d902SRodney W. Grimes  */
1599b50d902SRodney W. Grimes int
1609b50d902SRodney W. Grimes save1(str, mark, cmd, ignore)
1619b50d902SRodney W. Grimes 	char str[];
1629b50d902SRodney W. Grimes 	int mark;
1639b50d902SRodney W. Grimes 	char *cmd;
1649b50d902SRodney W. Grimes 	struct ignoretab *ignore;
1659b50d902SRodney W. Grimes {
1669b50d902SRodney W. Grimes 	register int *ip;
1679b50d902SRodney W. Grimes 	register struct message *mp;
1689b50d902SRodney W. Grimes 	char *file, *disp;
1699b50d902SRodney W. Grimes 	int f, *msgvec;
1709b50d902SRodney W. Grimes 	FILE *obuf;
1719b50d902SRodney W. Grimes 
1729b50d902SRodney W. Grimes 	msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec);
1739b50d902SRodney W. Grimes 	if ((file = snarf(str, &f)) == NOSTR)
1749b50d902SRodney W. Grimes 		return(1);
1759b50d902SRodney W. Grimes 	if (!f) {
1769b50d902SRodney W. Grimes 		*msgvec = first(0, MMNORM);
177d030d2d2SPoul-Henning Kamp 		if (*msgvec == 0) {
1789b50d902SRodney W. Grimes 			printf("No messages to %s.\n", cmd);
1799b50d902SRodney W. Grimes 			return(1);
1809b50d902SRodney W. Grimes 		}
181d030d2d2SPoul-Henning Kamp 		msgvec[1] = 0;
1829b50d902SRodney W. Grimes 	}
1839b50d902SRodney W. Grimes 	if (f && getmsglist(str, msgvec, 0) < 0)
1849b50d902SRodney W. Grimes 		return(1);
1859b50d902SRodney W. Grimes 	if ((file = expand(file)) == NOSTR)
1869b50d902SRodney W. Grimes 		return(1);
1879b50d902SRodney W. Grimes 	printf("\"%s\" ", file);
1889b50d902SRodney W. Grimes 	fflush(stdout);
1899b50d902SRodney W. Grimes 	if (access(file, 0) >= 0)
1909b50d902SRodney W. Grimes 		disp = "[Appended]";
1919b50d902SRodney W. Grimes 	else
1929b50d902SRodney W. Grimes 		disp = "[New file]";
1939b50d902SRodney W. Grimes 	if ((obuf = Fopen(file, "a")) == NULL) {
1940c3a8314SMike Heffner 		warn(NOSTR);
1959b50d902SRodney W. Grimes 		return(1);
1969b50d902SRodney W. Grimes 	}
1979b50d902SRodney W. Grimes 	for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
1989b50d902SRodney W. Grimes 		mp = &message[*ip - 1];
1999b50d902SRodney W. Grimes 		touch(mp);
2000c3a8314SMike Heffner 		if (sendmessage(mp, obuf, ignore, NOSTR) < 0) {
2010c3a8314SMike Heffner 			warnx("%s", file);
2029b50d902SRodney W. Grimes 			Fclose(obuf);
2039b50d902SRodney W. Grimes 			return(1);
2049b50d902SRodney W. Grimes 		}
2059b50d902SRodney W. Grimes 		if (mark)
2069b50d902SRodney W. Grimes 			mp->m_flag |= MSAVED;
2079b50d902SRodney W. Grimes 	}
2089b50d902SRodney W. Grimes 	fflush(obuf);
2099b50d902SRodney W. Grimes 	if (ferror(obuf))
2100c3a8314SMike Heffner 		warn("%s", file);
2119b50d902SRodney W. Grimes 	Fclose(obuf);
2129b50d902SRodney W. Grimes 	printf("%s\n", disp);
2139b50d902SRodney W. Grimes 	return(0);
2149b50d902SRodney W. Grimes }
2159b50d902SRodney W. Grimes 
2169b50d902SRodney W. Grimes /*
2179b50d902SRodney W. Grimes  * Write the indicated messages at the end of the passed
2189b50d902SRodney W. Grimes  * file name, minus header and trailing blank line.
2199b50d902SRodney W. Grimes  */
2209b50d902SRodney W. Grimes int
2219b50d902SRodney W. Grimes swrite(str)
2229b50d902SRodney W. Grimes 	char str[];
2239b50d902SRodney W. Grimes {
2249b50d902SRodney W. Grimes 
2259b50d902SRodney W. Grimes 	return save1(str, 1, "write", ignoreall);
2269b50d902SRodney W. Grimes }
2279b50d902SRodney W. Grimes 
2289b50d902SRodney W. Grimes /*
2299b50d902SRodney W. Grimes  * Snarf the file from the end of the command line and
2309b50d902SRodney W. Grimes  * return a pointer to it.  If there is no file attached,
2319b50d902SRodney W. Grimes  * just return NOSTR.  Put a null in front of the file
2329b50d902SRodney W. Grimes  * name so that the message list processing won't see it,
2339b50d902SRodney W. Grimes  * unless the file name is the only thing on the line, in
2349b50d902SRodney W. Grimes  * which case, return 0 in the reference flag variable.
2359b50d902SRodney W. Grimes  */
2369b50d902SRodney W. Grimes 
2379b50d902SRodney W. Grimes char *
2389b50d902SRodney W. Grimes snarf(linebuf, flag)
2399b50d902SRodney W. Grimes 	char linebuf[];
2409b50d902SRodney W. Grimes 	int *flag;
2419b50d902SRodney W. Grimes {
2429b50d902SRodney W. Grimes 	register char *cp;
2439b50d902SRodney W. Grimes 
2449b50d902SRodney W. Grimes 	*flag = 1;
2459b50d902SRodney W. Grimes 	cp = strlen(linebuf) + linebuf - 1;
2469b50d902SRodney W. Grimes 
2479b50d902SRodney W. Grimes 	/*
2489b50d902SRodney W. Grimes 	 * Strip away trailing blanks.
2499b50d902SRodney W. Grimes 	 */
2509b50d902SRodney W. Grimes 
2519b50d902SRodney W. Grimes 	while (cp > linebuf && isspace(*cp))
2529b50d902SRodney W. Grimes 		cp--;
2539b50d902SRodney W. Grimes 	*++cp = 0;
2549b50d902SRodney W. Grimes 
2559b50d902SRodney W. Grimes 	/*
2569b50d902SRodney W. Grimes 	 * Now search for the beginning of the file name.
2579b50d902SRodney W. Grimes 	 */
2589b50d902SRodney W. Grimes 
2599b50d902SRodney W. Grimes 	while (cp > linebuf && !isspace(*cp))
2609b50d902SRodney W. Grimes 		cp--;
2619b50d902SRodney W. Grimes 	if (*cp == '\0') {
2629b50d902SRodney W. Grimes 		printf("No file specified.\n");
2639b50d902SRodney W. Grimes 		return(NOSTR);
2649b50d902SRodney W. Grimes 	}
2659b50d902SRodney W. Grimes 	if (isspace(*cp))
2669b50d902SRodney W. Grimes 		*cp++ = 0;
2679b50d902SRodney W. Grimes 	else
2689b50d902SRodney W. Grimes 		*flag = 0;
2699b50d902SRodney W. Grimes 	return(cp);
2709b50d902SRodney W. Grimes }
2719b50d902SRodney W. Grimes 
2729b50d902SRodney W. Grimes /*
2739b50d902SRodney W. Grimes  * Delete messages.
2749b50d902SRodney W. Grimes  */
2759b50d902SRodney W. Grimes int
2769b50d902SRodney W. Grimes delete(msgvec)
2779b50d902SRodney W. Grimes 	int msgvec[];
2789b50d902SRodney W. Grimes {
2799b50d902SRodney W. Grimes 	delm(msgvec);
2809b50d902SRodney W. Grimes 	return 0;
2819b50d902SRodney W. Grimes }
2829b50d902SRodney W. Grimes 
2839b50d902SRodney W. Grimes /*
2849b50d902SRodney W. Grimes  * Delete messages, then type the new dot.
2859b50d902SRodney W. Grimes  */
2869b50d902SRodney W. Grimes int
2879b50d902SRodney W. Grimes deltype(msgvec)
2889b50d902SRodney W. Grimes 	int msgvec[];
2899b50d902SRodney W. Grimes {
2909b50d902SRodney W. Grimes 	int list[2];
2919b50d902SRodney W. Grimes 	int lastdot;
2929b50d902SRodney W. Grimes 
2939b50d902SRodney W. Grimes 	lastdot = dot - &message[0] + 1;
2949b50d902SRodney W. Grimes 	if (delm(msgvec) >= 0) {
2959b50d902SRodney W. Grimes 		list[0] = dot - &message[0] + 1;
2969b50d902SRodney W. Grimes 		if (list[0] > lastdot) {
2979b50d902SRodney W. Grimes 			touch(dot);
298d030d2d2SPoul-Henning Kamp 			list[1] = 0;
2999b50d902SRodney W. Grimes 			return(type(list));
3009b50d902SRodney W. Grimes 		}
3019b50d902SRodney W. Grimes 		printf("At EOF\n");
3029b50d902SRodney W. Grimes 	} else
3039b50d902SRodney W. Grimes 		printf("No more messages\n");
3049b50d902SRodney W. Grimes 	return(0);
3059b50d902SRodney W. Grimes }
3069b50d902SRodney W. Grimes 
3079b50d902SRodney W. Grimes /*
3089b50d902SRodney W. Grimes  * Delete the indicated messages.
3099b50d902SRodney W. Grimes  * Set dot to some nice place afterwards.
3109b50d902SRodney W. Grimes  * Internal interface.
3119b50d902SRodney W. Grimes  */
3129b50d902SRodney W. Grimes int
3139b50d902SRodney W. Grimes delm(msgvec)
3149b50d902SRodney W. Grimes 	int *msgvec;
3159b50d902SRodney W. Grimes {
3169b50d902SRodney W. Grimes 	register struct message *mp;
3179b50d902SRodney W. Grimes 	register *ip;
3189b50d902SRodney W. Grimes 	int last;
3199b50d902SRodney W. Grimes 
320d030d2d2SPoul-Henning Kamp 	last = 0;
321d030d2d2SPoul-Henning Kamp 	for (ip = msgvec; *ip != 0; ip++) {
3229b50d902SRodney W. Grimes 		mp = &message[*ip - 1];
3239b50d902SRodney W. Grimes 		touch(mp);
3249b50d902SRodney W. Grimes 		mp->m_flag |= MDELETED|MTOUCH;
3259b50d902SRodney W. Grimes 		mp->m_flag &= ~(MPRESERVE|MSAVED|MBOX);
3269b50d902SRodney W. Grimes 		last = *ip;
3279b50d902SRodney W. Grimes 	}
328d030d2d2SPoul-Henning Kamp 	if (last != 0) {
3299b50d902SRodney W. Grimes 		dot = &message[last-1];
3309b50d902SRodney W. Grimes 		last = first(0, MDELETED);
331d030d2d2SPoul-Henning Kamp 		if (last != 0) {
3329b50d902SRodney W. Grimes 			dot = &message[last-1];
3339b50d902SRodney W. Grimes 			return(0);
3349b50d902SRodney W. Grimes 		}
3359b50d902SRodney W. Grimes 		else {
3369b50d902SRodney W. Grimes 			dot = &message[0];
3379b50d902SRodney W. Grimes 			return(-1);
3389b50d902SRodney W. Grimes 		}
3399b50d902SRodney W. Grimes 	}
3409b50d902SRodney W. Grimes 
3419b50d902SRodney W. Grimes 	/*
3429b50d902SRodney W. Grimes 	 * Following can't happen -- it keeps lint happy
3439b50d902SRodney W. Grimes 	 */
3449b50d902SRodney W. Grimes 
3459b50d902SRodney W. Grimes 	return(-1);
3469b50d902SRodney W. Grimes }
3479b50d902SRodney W. Grimes 
3489b50d902SRodney W. Grimes /*
3499b50d902SRodney W. Grimes  * Undelete the indicated messages.
3509b50d902SRodney W. Grimes  */
3519b50d902SRodney W. Grimes int
352c05b924fSBruce Evans undelete_messages(msgvec)
3539b50d902SRodney W. Grimes 	int *msgvec;
3549b50d902SRodney W. Grimes {
3559b50d902SRodney W. Grimes 	register struct message *mp;
3569b50d902SRodney W. Grimes 	register *ip;
3579b50d902SRodney W. Grimes 
3589b50d902SRodney W. Grimes 	for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
3599b50d902SRodney W. Grimes 		mp = &message[*ip - 1];
3609b50d902SRodney W. Grimes 		touch(mp);
3619b50d902SRodney W. Grimes 		dot = mp;
3629b50d902SRodney W. Grimes 		mp->m_flag &= ~MDELETED;
3639b50d902SRodney W. Grimes 	}
3649b50d902SRodney W. Grimes 	return 0;
3659b50d902SRodney W. Grimes }
3669b50d902SRodney W. Grimes 
3679b50d902SRodney W. Grimes /*
3689b50d902SRodney W. Grimes  * Interactively dump core on "core"
3699b50d902SRodney W. Grimes  */
3709b50d902SRodney W. Grimes int
3719b50d902SRodney W. Grimes core()
3729b50d902SRodney W. Grimes {
3739b50d902SRodney W. Grimes 	int pid;
3740c3a8314SMike Heffner 	extern int wait_status;
3759b50d902SRodney W. Grimes 
37646ccc3e9SBruce Evans 	switch (pid = fork()) {
3779b50d902SRodney W. Grimes 	case -1:
3780c3a8314SMike Heffner 		warn("fork");
3799b50d902SRodney W. Grimes 		return(1);
3809b50d902SRodney W. Grimes 	case 0:
3819b50d902SRodney W. Grimes 		abort();
3829b50d902SRodney W. Grimes 		_exit(1);
3839b50d902SRodney W. Grimes 	}
3849b50d902SRodney W. Grimes 	printf("Okie dokie");
3859b50d902SRodney W. Grimes 	fflush(stdout);
3869b50d902SRodney W. Grimes 	wait_child(pid);
3870c3a8314SMike Heffner 	if (WIFSIGNALED(wait_status) && WCOREDUMP(wait_status))
3889b50d902SRodney W. Grimes 		printf(" -- Core dumped.\n");
3899b50d902SRodney W. Grimes 	else
3909b50d902SRodney W. Grimes 		printf(" -- Can't dump core.\n");
3919b50d902SRodney W. Grimes 	return 0;
3929b50d902SRodney W. Grimes }
3939b50d902SRodney W. Grimes 
3949b50d902SRodney W. Grimes /*
3959b50d902SRodney W. Grimes  * Clobber as many bytes of stack as the user requests.
3969b50d902SRodney W. Grimes  */
3979b50d902SRodney W. Grimes int
3989b50d902SRodney W. Grimes clobber(argv)
3999b50d902SRodney W. Grimes 	char **argv;
4009b50d902SRodney W. Grimes {
4019b50d902SRodney W. Grimes 	register int times;
4029b50d902SRodney W. Grimes 
4039b50d902SRodney W. Grimes 	if (argv[0] == 0)
4049b50d902SRodney W. Grimes 		times = 1;
4059b50d902SRodney W. Grimes 	else
4069b50d902SRodney W. Grimes 		times = (atoi(argv[0]) + 511) / 512;
4079b50d902SRodney W. Grimes 	clob1(times);
4089b50d902SRodney W. Grimes 	return 0;
4099b50d902SRodney W. Grimes }
4109b50d902SRodney W. Grimes 
4119b50d902SRodney W. Grimes /*
4129b50d902SRodney W. Grimes  * Clobber the stack.
4139b50d902SRodney W. Grimes  */
4149b50d902SRodney W. Grimes void
4159b50d902SRodney W. Grimes clob1(n)
4169b50d902SRodney W. Grimes 	int n;
4179b50d902SRodney W. Grimes {
4189b50d902SRodney W. Grimes 	char buf[512];
4199b50d902SRodney W. Grimes 	register char *cp;
4209b50d902SRodney W. Grimes 
4219b50d902SRodney W. Grimes 	if (n <= 0)
4229b50d902SRodney W. Grimes 		return;
4239b50d902SRodney W. Grimes 	for (cp = buf; cp < &buf[512]; *cp++ = 0xFF)
4249b50d902SRodney W. Grimes 		;
4259b50d902SRodney W. Grimes 	clob1(n - 1);
4269b50d902SRodney W. Grimes }
4279b50d902SRodney W. Grimes 
4289b50d902SRodney W. Grimes /*
4299b50d902SRodney W. Grimes  * Add the given header fields to the retained list.
4309b50d902SRodney W. Grimes  * If no arguments, print the current list of retained fields.
4319b50d902SRodney W. Grimes  */
4329b50d902SRodney W. Grimes int
4339b50d902SRodney W. Grimes retfield(list)
4349b50d902SRodney W. Grimes 	char *list[];
4359b50d902SRodney W. Grimes {
4369b50d902SRodney W. Grimes 
4379b50d902SRodney W. Grimes 	return ignore1(list, ignore + 1, "retained");
4389b50d902SRodney W. Grimes }
4399b50d902SRodney W. Grimes 
4409b50d902SRodney W. Grimes /*
4419b50d902SRodney W. Grimes  * Add the given header fields to the ignored list.
4429b50d902SRodney W. Grimes  * If no arguments, print the current list of ignored fields.
4439b50d902SRodney W. Grimes  */
4449b50d902SRodney W. Grimes int
4459b50d902SRodney W. Grimes igfield(list)
4469b50d902SRodney W. Grimes 	char *list[];
4479b50d902SRodney W. Grimes {
4489b50d902SRodney W. Grimes 
4499b50d902SRodney W. Grimes 	return ignore1(list, ignore, "ignored");
4509b50d902SRodney W. Grimes }
4519b50d902SRodney W. Grimes 
4529b50d902SRodney W. Grimes int
4539b50d902SRodney W. Grimes saveretfield(list)
4549b50d902SRodney W. Grimes 	char *list[];
4559b50d902SRodney W. Grimes {
4569b50d902SRodney W. Grimes 
4579b50d902SRodney W. Grimes 	return ignore1(list, saveignore + 1, "retained");
4589b50d902SRodney W. Grimes }
4599b50d902SRodney W. Grimes 
4609b50d902SRodney W. Grimes int
4619b50d902SRodney W. Grimes saveigfield(list)
4629b50d902SRodney W. Grimes 	char *list[];
4639b50d902SRodney W. Grimes {
4649b50d902SRodney W. Grimes 
4659b50d902SRodney W. Grimes 	return ignore1(list, saveignore, "ignored");
4669b50d902SRodney W. Grimes }
4679b50d902SRodney W. Grimes 
4689b50d902SRodney W. Grimes int
4699b50d902SRodney W. Grimes ignore1(list, tab, which)
4709b50d902SRodney W. Grimes 	char *list[];
4719b50d902SRodney W. Grimes 	struct ignoretab *tab;
4729b50d902SRodney W. Grimes 	char *which;
4739b50d902SRodney W. Grimes {
4740c3a8314SMike Heffner 	char field[LINESIZE];
4759b50d902SRodney W. Grimes 	register int h;
4769b50d902SRodney W. Grimes 	register struct ignore *igp;
4779b50d902SRodney W. Grimes 	char **ap;
4789b50d902SRodney W. Grimes 
4799b50d902SRodney W. Grimes 	if (*list == NOSTR)
4809b50d902SRodney W. Grimes 		return igshow(tab, which);
4819b50d902SRodney W. Grimes 	for (ap = list; *ap != 0; ap++) {
4820c3a8314SMike Heffner 		istrncpy(field, *ap, sizeof(field));
4839b50d902SRodney W. Grimes 		if (member(field, tab))
4849b50d902SRodney W. Grimes 			continue;
4859b50d902SRodney W. Grimes 		h = hash(field);
4869b50d902SRodney W. Grimes 		igp = (struct ignore *) calloc(1, sizeof (struct ignore));
4879b50d902SRodney W. Grimes 		igp->i_field = calloc((unsigned) strlen(field) + 1,
4889b50d902SRodney W. Grimes 			sizeof (char));
4899b50d902SRodney W. Grimes 		strcpy(igp->i_field, field);
4909b50d902SRodney W. Grimes 		igp->i_link = tab->i_head[h];
4919b50d902SRodney W. Grimes 		tab->i_head[h] = igp;
4929b50d902SRodney W. Grimes 		tab->i_count++;
4939b50d902SRodney W. Grimes 	}
4949b50d902SRodney W. Grimes 	return 0;
4959b50d902SRodney W. Grimes }
4969b50d902SRodney W. Grimes 
4979b50d902SRodney W. Grimes /*
4989b50d902SRodney W. Grimes  * Print out all currently retained fields.
4999b50d902SRodney W. Grimes  */
5009b50d902SRodney W. Grimes int
5019b50d902SRodney W. Grimes igshow(tab, which)
5029b50d902SRodney W. Grimes 	struct ignoretab *tab;
5039b50d902SRodney W. Grimes 	char *which;
5049b50d902SRodney W. Grimes {
5059b50d902SRodney W. Grimes 	register int h;
5069b50d902SRodney W. Grimes 	struct ignore *igp;
5079b50d902SRodney W. Grimes 	char **ap, **ring;
5089b50d902SRodney W. Grimes 	int igcomp();
5099b50d902SRodney W. Grimes 
5109b50d902SRodney W. Grimes 	if (tab->i_count == 0) {
5119b50d902SRodney W. Grimes 		printf("No fields currently being %s.\n", which);
5129b50d902SRodney W. Grimes 		return 0;
5139b50d902SRodney W. Grimes 	}
5149b50d902SRodney W. Grimes 	ring = (char **) salloc((tab->i_count + 1) * sizeof (char *));
5159b50d902SRodney W. Grimes 	ap = ring;
5169b50d902SRodney W. Grimes 	for (h = 0; h < HSHSIZE; h++)
5179b50d902SRodney W. Grimes 		for (igp = tab->i_head[h]; igp != 0; igp = igp->i_link)
5189b50d902SRodney W. Grimes 			*ap++ = igp->i_field;
5199b50d902SRodney W. Grimes 	*ap = 0;
5209b50d902SRodney W. Grimes 	qsort(ring, tab->i_count, sizeof (char *), igcomp);
5219b50d902SRodney W. Grimes 	for (ap = ring; *ap != 0; ap++)
5229b50d902SRodney W. Grimes 		printf("%s\n", *ap);
5239b50d902SRodney W. Grimes 	return 0;
5249b50d902SRodney W. Grimes }
5259b50d902SRodney W. Grimes 
5269b50d902SRodney W. Grimes /*
5279b50d902SRodney W. Grimes  * Compare two names for sorting ignored field list.
5289b50d902SRodney W. Grimes  */
5299b50d902SRodney W. Grimes int
5309b50d902SRodney W. Grimes igcomp(l, r)
5319b50d902SRodney W. Grimes 	const void *l, *r;
5329b50d902SRodney W. Grimes {
5339b50d902SRodney W. Grimes 	return (strcmp(*(char **)l, *(char **)r));
5349b50d902SRodney W. Grimes }
535