xref: /csrg-svn/usr.bin/mail/aux.c (revision 62083)
122444Sdist /*
2*62083Sbostic  * Copyright (c) 1980, 1993
3*62083Sbostic  *	The Regents of the University of California.  All rights reserved.
433499Sbostic  *
542741Sbostic  * %sccs.include.redist.c%
622444Sdist  */
722444Sdist 
834905Sbostic #ifndef lint
9*62083Sbostic static char sccsid[] = "@(#)aux.c	8.1 (Berkeley) 06/06/93";
1034905Sbostic #endif /* not lint */
111219Skas 
121219Skas #include "rcv.h"
1354505Sbostic #include "extern.h"
141219Skas 
151219Skas /*
161219Skas  * Mail -- a mail program
171219Skas  *
181219Skas  * Auxiliary functions.
191219Skas  */
201219Skas 
211219Skas /*
221219Skas  * Return a pointer to a dynamic copy of the argument.
231219Skas  */
241219Skas char *
savestr(str)251219Skas savestr(str)
261219Skas 	char *str;
271219Skas {
2834987Sedward 	char *new;
2934987Sedward 	int size = strlen(str) + 1;
301219Skas 
3134987Sedward 	if ((new = salloc(size)) != NOSTR)
3234987Sedward 		bcopy(str, new, size);
3334987Sedward 	return new;
341219Skas }
351219Skas 
361219Skas /*
3758012Sedward  * Make a copy of new argument incorporating old one.
3858012Sedward  */
3958012Sedward char *
save2str(str,old)4058012Sedward save2str(str, old)
4158012Sedward 	char *str, *old;
4258012Sedward {
4358012Sedward 	char *new;
4458012Sedward 	int newsize = strlen(str) + 1;
4558012Sedward 	int oldsize = old ? strlen(old) + 1 : 0;
4658012Sedward 
4758012Sedward 	if ((new = salloc(newsize + oldsize)) != NOSTR) {
4858012Sedward 		if (oldsize) {
4958012Sedward 			bcopy(old, new, oldsize);
5058012Sedward 			new[oldsize - 1] = ' ';
5158012Sedward 		}
5258012Sedward 		bcopy(str, new + oldsize, newsize);
5358012Sedward 	}
5458012Sedward 	return new;
5558012Sedward }
5658012Sedward 
5758012Sedward /*
581219Skas  * Announce a fatal error and die.
591219Skas  */
6054505Sbostic #if __STDC__
6154505Sbostic #include <stdarg.h>
6254505Sbostic #else
6354505Sbostic #include <varargs.h>
6454505Sbostic #endif
651219Skas 
6654505Sbostic void
6754505Sbostic #if __STDC__
panic(const char * fmt,...)6854505Sbostic panic(const char *fmt, ...)
6954505Sbostic #else
7054505Sbostic panic(fmt, va_alist)
7131142Sedward 	char *fmt;
7254505Sbostic         va_dcl
7354505Sbostic #endif
741219Skas {
7554505Sbostic 	va_list ap;
7654505Sbostic #if __STDC__
7754505Sbostic 	va_start(ap, fmt);
7854505Sbostic #else
7954505Sbostic 	va_start(ap);
8054505Sbostic #endif
8154505Sbostic 	(void)fprintf(stderr, "panic: ");
8254505Sbostic 	vfprintf(stderr, fmt, ap);
8354505Sbostic 	va_end(ap);
8454505Sbostic 	(void)fprintf(stderr, "\n");
8554505Sbostic 	fflush(stderr);
8643865Sedward 	abort();
871219Skas }
881219Skas 
891219Skas /*
901219Skas  * Touch the named message by setting its MTOUCH flag.
911219Skas  * Touched messages have the effect of not being sent
921219Skas  * back to the system mailbox on exit.
931219Skas  */
9454505Sbostic void
touch(mp)9534987Sedward touch(mp)
9634987Sedward 	register struct message *mp;
971219Skas {
981479Skas 
991479Skas 	mp->m_flag |= MTOUCH;
1001479Skas 	if ((mp->m_flag & MREAD) == 0)
1011479Skas 		mp->m_flag |= MREAD|MSTATUS;
1021219Skas }
1031219Skas 
1041219Skas /*
1051219Skas  * Test to see if the passed file name is a directory.
1061219Skas  * Return true if it is.
1071219Skas  */
10854505Sbostic int
isdir(name)1091219Skas isdir(name)
1101219Skas 	char name[];
1111219Skas {
1121219Skas 	struct stat sbuf;
1131219Skas 
1141219Skas 	if (stat(name, &sbuf) < 0)
1151219Skas 		return(0);
1161219Skas 	return((sbuf.st_mode & S_IFMT) == S_IFDIR);
1171219Skas }
1181219Skas 
1191219Skas /*
1201219Skas  * Count the number of arguments in the given string raw list.
1211219Skas  */
12254505Sbostic int
argcount(argv)1231219Skas argcount(argv)
1241219Skas 	char **argv;
1251219Skas {
1261219Skas 	register char **ap;
1271219Skas 
12831142Sedward 	for (ap = argv; *ap++ != NOSTR;)
1291219Skas 		;
13031142Sedward 	return ap - argv - 1;
1311219Skas }
1321219Skas 
1331219Skas /*
1341219Skas  * Return the desired header line from the passed message
1351219Skas  * pointer (or NOSTR if the desired header field is not available).
1361219Skas  */
1371219Skas char *
hfield(field,mp)1381219Skas hfield(field, mp)
1391219Skas 	char field[];
1401219Skas 	struct message *mp;
1411219Skas {
1421219Skas 	register FILE *ibuf;
1431219Skas 	char linebuf[LINESIZE];
1441219Skas 	register int lc;
14531142Sedward 	register char *hfield;
14658012Sedward 	char *colon, *oldhfield = NOSTR;
1471219Skas 
1481219Skas 	ibuf = setinput(mp);
14931142Sedward 	if ((lc = mp->m_lines - 1) < 0)
15031142Sedward 		return NOSTR;
15136478Sedward 	if (readline(ibuf, linebuf, LINESIZE) < 0)
15231142Sedward 		return NOSTR;
15331142Sedward 	while (lc > 0) {
15431142Sedward 		if ((lc = gethfield(ibuf, linebuf, lc, &colon)) < 0)
15558012Sedward 			return oldhfield;
15631142Sedward 		if (hfield = ishfield(linebuf, colon, field))
15758012Sedward 			oldhfield = save2str(hfield, oldhfield);
15831142Sedward 	}
15958012Sedward 	return oldhfield;
1601219Skas }
1611219Skas 
1621219Skas /*
1631219Skas  * Return the next header field found in the given message.
16431142Sedward  * Return >= 0 if something found, < 0 elsewise.
16531142Sedward  * "colon" is set to point to the colon in the header.
1661219Skas  * Must deal with \ continuations & other such fraud.
1671219Skas  */
16854505Sbostic int
gethfield(f,linebuf,rem,colon)16931142Sedward gethfield(f, linebuf, rem, colon)
1701219Skas 	register FILE *f;
1711219Skas 	char linebuf[];
1721219Skas 	register int rem;
17331142Sedward 	char **colon;
1741219Skas {
1751219Skas 	char line2[LINESIZE];
1761219Skas 	register char *cp, *cp2;
1771219Skas 	register int c;
1781219Skas 
1791219Skas 	for (;;) {
18031142Sedward 		if (--rem < 0)
18131142Sedward 			return -1;
18236478Sedward 		if ((c = readline(f, linebuf, LINESIZE)) <= 0)
18331142Sedward 			return -1;
18431142Sedward 		for (cp = linebuf; isprint(*cp) && *cp != ' ' && *cp != ':';
18531142Sedward 		     cp++)
18631142Sedward 			;
18731142Sedward 		if (*cp != ':' || cp == linebuf)
1881219Skas 			continue;
1891219Skas 		/*
1901219Skas 		 * I guess we got a headline.
1911219Skas 		 * Handle wraparounding
1921219Skas 		 */
19331142Sedward 		*colon = cp;
19431142Sedward 		cp = linebuf + c;
1951219Skas 		for (;;) {
19631142Sedward 			while (--cp >= linebuf && (*cp == ' ' || *cp == '\t'))
19731142Sedward 				;
19831142Sedward 			cp++;
1991219Skas 			if (rem <= 0)
2001219Skas 				break;
20131142Sedward 			ungetc(c = getc(f), f);
20231142Sedward 			if (c != ' ' && c != '\t')
2031219Skas 				break;
20436478Sedward 			if ((c = readline(f, line2, LINESIZE)) < 0)
2051219Skas 				break;
2061219Skas 			rem--;
20731142Sedward 			for (cp2 = line2; *cp2 == ' ' || *cp2 == '\t'; cp2++)
2081219Skas 				;
20931142Sedward 			c -= cp2 - line2;
21031142Sedward 			if (cp + c >= linebuf + LINESIZE - 2)
2111219Skas 				break;
2121219Skas 			*cp++ = ' ';
21331142Sedward 			bcopy(cp2, cp, c);
21431142Sedward 			cp += c;
2151219Skas 		}
21631142Sedward 		*cp = 0;
21731142Sedward 		return rem;
2181219Skas 	}
2191219Skas 	/* NOTREACHED */
2201219Skas }
2211219Skas 
2221219Skas /*
2231219Skas  * Check whether the passed line is a header line of
22431142Sedward  * the desired breed.  Return the field body, or 0.
2251219Skas  */
2261219Skas 
22731142Sedward char*
ishfield(linebuf,colon,field)22831142Sedward ishfield(linebuf, colon, field)
2291219Skas 	char linebuf[], field[];
23031142Sedward 	char *colon;
2311219Skas {
23231142Sedward 	register char *cp = colon;
2331219Skas 
2341219Skas 	*cp = 0;
23534987Sedward 	if (strcasecmp(linebuf, field) != 0) {
23631142Sedward 		*cp = ':';
23731142Sedward 		return 0;
2381219Skas 	}
23931142Sedward 	*cp = ':';
24031142Sedward 	for (cp++; *cp == ' ' || *cp == '\t'; cp++)
24131142Sedward 		;
24231142Sedward 	return cp;
2431219Skas }
2441219Skas 
2451219Skas /*
2467571Skurt  * Copy a string, lowercasing it as we go.
2477571Skurt  */
24854505Sbostic void
istrcpy(dest,src)2497571Skurt istrcpy(dest, src)
25031142Sedward 	register char *dest, *src;
2517571Skurt {
2527571Skurt 
2537571Skurt 	do {
25431142Sedward 		if (isupper(*src))
25531142Sedward 			*dest++ = tolower(*src);
25631142Sedward 		else
25731142Sedward 			*dest++ = *src;
25831142Sedward 	} while (*src++ != 0);
2597571Skurt }
2607571Skurt 
2617571Skurt /*
2621219Skas  * The following code deals with input stacking to do source
2631219Skas  * commands.  All but the current file pointer are saved on
2641219Skas  * the stack.
2651219Skas  */
2661219Skas 
26734965Sedward static	int	ssp;			/* Top of file stack */
2681519Skas struct sstack {
2691519Skas 	FILE	*s_file;		/* File we were in. */
2701519Skas 	int	s_cond;			/* Saved state of conditionals */
2715785Skurt 	int	s_loading;		/* Loading .mailrc, etc. */
27218661Sserge } sstack[NOFILE];
2731219Skas 
2741219Skas /*
2751219Skas  * Pushdown current input file and switch to a new one.
2761219Skas  * Set the global flag "sourcing" so that others will realize
2771219Skas  * that they are no longer reading from a tty (in all probability).
2781219Skas  */
27954505Sbostic int
source(arglist)28034966Sedward source(arglist)
28134966Sedward 	char **arglist;
2821219Skas {
28334966Sedward 	FILE *fi;
28434966Sedward 	char *cp;
2851219Skas 
28634966Sedward 	if ((cp = expand(*arglist)) == NOSTR)
2871219Skas 		return(1);
28843865Sedward 	if ((fi = Fopen(cp, "r")) == NULL) {
2893914Skurt 		perror(cp);
2903914Skurt 		return(1);
2911219Skas 	}
29234965Sedward 	if (ssp >= NOFILE - 1) {
2931219Skas 		printf("Too much \"sourcing\" going on.\n");
29443865Sedward 		Fclose(fi);
2951219Skas 		return(1);
2961219Skas 	}
29734965Sedward 	sstack[ssp].s_file = input;
2981519Skas 	sstack[ssp].s_cond = cond;
2995785Skurt 	sstack[ssp].s_loading = loading;
30034965Sedward 	ssp++;
3015785Skurt 	loading = 0;
3021519Skas 	cond = CANY;
3031219Skas 	input = fi;
3041219Skas 	sourcing++;
3051219Skas 	return(0);
3061219Skas }
3071219Skas 
3081219Skas /*
3091219Skas  * Pop the current input back to the previous level.
3101219Skas  * Update the "sourcing" flag as appropriate.
3111219Skas  */
31254505Sbostic int
unstack()3131219Skas unstack()
3141219Skas {
31534965Sedward 	if (ssp <= 0) {
3161219Skas 		printf("\"Source\" stack over-pop.\n");
3171219Skas 		sourcing = 0;
3181219Skas 		return(1);
3191219Skas 	}
32043865Sedward 	Fclose(input);
3211519Skas 	if (cond != CANY)
3221519Skas 		printf("Unmatched \"if\"\n");
32334965Sedward 	ssp--;
3241519Skas 	cond = sstack[ssp].s_cond;
3255785Skurt 	loading = sstack[ssp].s_loading;
32634965Sedward 	input = sstack[ssp].s_file;
32734965Sedward 	if (ssp == 0)
3285785Skurt 		sourcing = loading;
3291219Skas 	return(0);
3301219Skas }
3311219Skas 
3321219Skas /*
3331219Skas  * Touch the indicated file.
3341219Skas  * This is nifty for the shell.
3351219Skas  */
33654505Sbostic void
alter(name)3371219Skas alter(name)
33838078Sbostic 	char *name;
3391219Skas {
34038078Sbostic 	struct stat sb;
34138078Sbostic 	struct timeval tv[2];
34238078Sbostic 	time_t time();
3431219Skas 
34438078Sbostic 	if (stat(name, &sb))
3451219Skas 		return;
34638078Sbostic 	tv[0].tv_sec = time((time_t *)0) + 1;
34738078Sbostic 	tv[1].tv_sec = sb.st_mtime;
34838078Sbostic 	tv[0].tv_usec = tv[1].tv_usec = 0;
34938078Sbostic 	(void)utimes(name, tv);
3501219Skas }
3511219Skas 
3521219Skas /*
3531219Skas  * Examine the passed line buffer and
3541219Skas  * return true if it is all blanks and tabs.
3551219Skas  */
35654505Sbostic int
blankline(linebuf)3571219Skas blankline(linebuf)
3581219Skas 	char linebuf[];
3591219Skas {
3601219Skas 	register char *cp;
3611219Skas 
3621219Skas 	for (cp = linebuf; *cp; cp++)
36318661Sserge 		if (*cp != ' ' && *cp != '\t')
3641219Skas 			return(0);
3651219Skas 	return(1);
3661219Skas }
3671219Skas 
3681219Skas /*
3693195Skas  * Get sender's name from this message.  If the message has
3703195Skas  * a bunch of arpanet stuff in it, we may have to skin the name
3713195Skas  * before returning it.
3723195Skas  */
3733195Skas char *
nameof(mp,reptype)3743195Skas nameof(mp, reptype)
3753195Skas 	register struct message *mp;
37654505Sbostic 	int reptype;
3773195Skas {
3785237Skurt 	register char *cp, *cp2;
3793195Skas 
3805237Skurt 	cp = skin(name1(mp, reptype));
3815237Skurt 	if (reptype != 0 || charcount(cp, '!') < 2)
3825237Skurt 		return(cp);
3835237Skurt 	cp2 = rindex(cp, '!');
3845237Skurt 	cp2--;
3855237Skurt 	while (cp2 > cp && *cp2 != '!')
3865237Skurt 		cp2--;
3875237Skurt 	if (*cp2 == '!')
3885237Skurt 		return(cp2 + 1);
3895237Skurt 	return(cp);
3903195Skas }
3913195Skas 
3923195Skas /*
39339763Sedward  * Start of a "comment".
39439763Sedward  * Ignore it.
39539763Sedward  */
39639763Sedward char *
skip_comment(cp)39739763Sedward skip_comment(cp)
39839763Sedward 	register char *cp;
39939763Sedward {
40039763Sedward 	register nesting = 1;
40139763Sedward 
40239763Sedward 	for (; nesting > 0 && *cp; cp++) {
40339763Sedward 		switch (*cp) {
40439763Sedward 		case '\\':
40539763Sedward 			if (cp[1])
40639763Sedward 				cp++;
40739763Sedward 			break;
40839763Sedward 		case '(':
40939763Sedward 			nesting++;
41039763Sedward 			break;
41139763Sedward 		case ')':
41239763Sedward 			nesting--;
41339763Sedward 			break;
41439763Sedward 		}
41539763Sedward 	}
41639763Sedward 	return cp;
41739763Sedward }
41839763Sedward 
41939763Sedward /*
42025912Smckusick  * Skin an arpa net address according to the RFC 822 interpretation
4213195Skas  * of "host-phrase."
4223195Skas  */
4233195Skas char *
skin(name)4243195Skas skin(name)
4253195Skas 	char *name;
4263195Skas {
4273195Skas 	register int c;
4283195Skas 	register char *cp, *cp2;
42925912Smckusick 	char *bufend;
4303195Skas 	int gotlt, lastsp;
4313195Skas 	char nbuf[BUFSIZ];
4323195Skas 
4333195Skas 	if (name == NOSTR)
4343195Skas 		return(NOSTR);
43512819Sleres 	if (index(name, '(') == NOSTR && index(name, '<') == NOSTR
43631142Sedward 	    && index(name, ' ') == NOSTR)
4373195Skas 		return(name);
4383195Skas 	gotlt = 0;
4393195Skas 	lastsp = 0;
44025912Smckusick 	bufend = nbuf;
44125912Smckusick 	for (cp = name, cp2 = bufend; c = *cp++; ) {
4423195Skas 		switch (c) {
4433195Skas 		case '(':
44439763Sedward 			cp = skip_comment(cp);
44512819Sleres 			lastsp = 0;
4463195Skas 			break;
4473195Skas 
44825912Smckusick 		case '"':
44925912Smckusick 			/*
45025912Smckusick 			 * Start of a "quoted-string".
45125912Smckusick 			 * Copy it in its entirety.
45225912Smckusick 			 */
45339763Sedward 			while (c = *cp) {
45425912Smckusick 				cp++;
45539763Sedward 				if (c == '"')
45639763Sedward 					break;
45739763Sedward 				if (c != '\\')
45839763Sedward 					*cp2++ = c;
45939763Sedward 				else if (c = *cp) {
46039763Sedward 					*cp2++ = c;
46125912Smckusick 					cp++;
46225912Smckusick 				}
46325912Smckusick 			}
46425912Smckusick 			lastsp = 0;
46525912Smckusick 			break;
46625912Smckusick 
4673195Skas 		case ' ':
46812819Sleres 			if (cp[0] == 'a' && cp[1] == 't' && cp[2] == ' ')
46912819Sleres 				cp += 3, *cp2++ = '@';
47012819Sleres 			else
47112819Sleres 			if (cp[0] == '@' && cp[1] == ' ')
47212819Sleres 				cp += 2, *cp2++ = '@';
47312819Sleres 			else
47412819Sleres 				lastsp = 1;
4753195Skas 			break;
4763195Skas 
4773195Skas 		case '<':
47825912Smckusick 			cp2 = bufend;
4793195Skas 			gotlt++;
4803195Skas 			lastsp = 0;
4813195Skas 			break;
4823195Skas 
4833195Skas 		case '>':
48425912Smckusick 			if (gotlt) {
48525912Smckusick 				gotlt = 0;
48639763Sedward 				while ((c = *cp) && c != ',') {
48725912Smckusick 					cp++;
48839763Sedward 					if (c == '(')
48939763Sedward 						cp = skip_comment(cp);
49039763Sedward 					else if (c == '"')
49139763Sedward 						while (c = *cp) {
49239763Sedward 							cp++;
49339763Sedward 							if (c == '"')
49439763Sedward 								break;
49539763Sedward 							if (c == '\\' && *cp)
49639763Sedward 								cp++;
49739763Sedward 						}
49839763Sedward 				}
49939763Sedward 				lastsp = 0;
50025912Smckusick 				break;
50125912Smckusick 			}
5023195Skas 			/* Fall into . . . */
5033195Skas 
5043195Skas 		default:
5053195Skas 			if (lastsp) {
5063195Skas 				lastsp = 0;
5073195Skas 				*cp2++ = ' ';
5083195Skas 			}
5093195Skas 			*cp2++ = c;
51039763Sedward 			if (c == ',' && !gotlt) {
51139763Sedward 				*cp2++ = ' ';
51239763Sedward 				for (; *cp == ' '; cp++)
51339763Sedward 					;
51439763Sedward 				lastsp = 0;
51539763Sedward 				bufend = cp2;
51639763Sedward 			}
5173195Skas 		}
5183195Skas 	}
5193195Skas 	*cp2 = 0;
5203195Skas 
5213195Skas 	return(savestr(nbuf));
5223195Skas }
5233195Skas 
5243195Skas /*
5251219Skas  * Fetch the sender's name from the passed message.
5263195Skas  * Reptype can be
5273195Skas  *	0 -- get sender's name for display purposes
5283195Skas  *	1 -- get sender's name for reply
5293195Skas  *	2 -- get sender's name for Reply
5301219Skas  */
5311219Skas char *
name1(mp,reptype)5323195Skas name1(mp, reptype)
5331219Skas 	register struct message *mp;
53454505Sbostic 	int reptype;
5351219Skas {
5361219Skas 	char namebuf[LINESIZE];
5371219Skas 	char linebuf[LINESIZE];
5381219Skas 	register char *cp, *cp2;
5391219Skas 	register FILE *ibuf;
5401219Skas 	int first = 1;
5411219Skas 
5423195Skas 	if ((cp = hfield("from", mp)) != NOSTR)
54331142Sedward 		return cp;
5443195Skas 	if (reptype == 0 && (cp = hfield("sender", mp)) != NOSTR)
54531142Sedward 		return cp;
5461219Skas 	ibuf = setinput(mp);
54731142Sedward 	namebuf[0] = 0;
54836478Sedward 	if (readline(ibuf, linebuf, LINESIZE) < 0)
5491219Skas 		return(savestr(namebuf));
5501219Skas newname:
55131142Sedward 	for (cp = linebuf; *cp && *cp != ' '; cp++)
5521219Skas 		;
55331142Sedward 	for (; *cp == ' ' || *cp == '\t'; cp++)
5541219Skas 		;
55531142Sedward 	for (cp2 = &namebuf[strlen(namebuf)];
55631142Sedward 	     *cp && *cp != ' ' && *cp != '\t' && cp2 < namebuf + LINESIZE - 1;)
55731142Sedward 		*cp2++ = *cp++;
5581219Skas 	*cp2 = '\0';
55936478Sedward 	if (readline(ibuf, linebuf, LINESIZE) < 0)
5601219Skas 		return(savestr(namebuf));
5611219Skas 	if ((cp = index(linebuf, 'F')) == NULL)
5621219Skas 		return(savestr(namebuf));
5631219Skas 	if (strncmp(cp, "From", 4) != 0)
5641219Skas 		return(savestr(namebuf));
5651219Skas 	while ((cp = index(cp, 'r')) != NULL) {
5661219Skas 		if (strncmp(cp, "remote", 6) == 0) {
5671219Skas 			if ((cp = index(cp, 'f')) == NULL)
5681219Skas 				break;
5691219Skas 			if (strncmp(cp, "from", 4) != 0)
5701219Skas 				break;
5711219Skas 			if ((cp = index(cp, ' ')) == NULL)
5721219Skas 				break;
5731219Skas 			cp++;
5741219Skas 			if (first) {
57531142Sedward 				strcpy(namebuf, cp);
5761219Skas 				first = 0;
5771219Skas 			} else
5781219Skas 				strcpy(rindex(namebuf, '!')+1, cp);
5791219Skas 			strcat(namebuf, "!");
5801219Skas 			goto newname;
5811219Skas 		}
5821219Skas 		cp++;
5831219Skas 	}
5841219Skas 	return(savestr(namebuf));
5851219Skas }
5861219Skas 
5871219Skas /*
5885237Skurt  * Count the occurances of c in str
5895237Skurt  */
59054505Sbostic int
charcount(str,c)5915237Skurt charcount(str, c)
5925237Skurt 	char *str;
59354505Sbostic 	int c;
5945237Skurt {
5955237Skurt 	register char *cp;
5965237Skurt 	register int i;
5975237Skurt 
5985237Skurt 	for (i = 0, cp = str; *cp; cp++)
5995237Skurt 		if (*cp == c)
6005237Skurt 			i++;
6015237Skurt 	return(i);
6025237Skurt }
6035237Skurt 
6045237Skurt /*
60531142Sedward  * Are any of the characters in the two strings the same?
6061219Skas  */
60754505Sbostic int
anyof(s1,s2)60831142Sedward anyof(s1, s2)
60931142Sedward 	register char *s1, *s2;
6101219Skas {
6111219Skas 
61231142Sedward 	while (*s1)
61331142Sedward 		if (index(s2, *s1++))
61431142Sedward 			return 1;
61531142Sedward 	return 0;
6161219Skas }
6171219Skas 
6181219Skas /*
61931142Sedward  * Convert c to upper case
6201219Skas  */
62154505Sbostic int
raise(c)62231142Sedward raise(c)
62354505Sbostic 	register int c;
62431142Sedward {
62531142Sedward 
62631142Sedward 	if (islower(c))
62731142Sedward 		return toupper(c);
62831142Sedward 	return c;
62931142Sedward }
63031142Sedward 
63131142Sedward /*
63231142Sedward  * Copy s1 to s2, return pointer to null in s2.
63331142Sedward  */
63431142Sedward char *
copy(s1,s2)63531142Sedward copy(s1, s2)
6361219Skas 	register char *s1, *s2;
6371219Skas {
6381219Skas 
63931142Sedward 	while (*s2++ = *s1++)
64031142Sedward 		;
64131142Sedward 	return s2 - 1;
6421219Skas }
6431219Skas 
6441219Skas /*
6457571Skurt  * See if the given header field is supposed to be ignored.
6467571Skurt  */
64754505Sbostic int
isign(field,ignore)64834692Sedward isign(field, ignore)
6497571Skurt 	char *field;
65034692Sedward 	struct ignoretab ignore[2];
6517571Skurt {
6527571Skurt 	char realfld[BUFSIZ];
6537571Skurt 
65434969Sedward 	if (ignore == ignoreall)
65534969Sedward 		return 1;
65618661Sserge 	/*
65718661Sserge 	 * Lower-case the string, so that "Status" and "status"
65818661Sserge 	 * will hash to the same place.
65918661Sserge 	 */
6607571Skurt 	istrcpy(realfld, field);
66134692Sedward 	if (ignore[1].i_count > 0)
66234692Sedward 		return (!member(realfld, ignore + 1));
66318661Sserge 	else
66418661Sserge 		return (member(realfld, ignore));
6657571Skurt }
66618661Sserge 
66754505Sbostic int
member(realfield,table)66818661Sserge member(realfield, table)
66918661Sserge 	register char *realfield;
67034692Sedward 	struct ignoretab *table;
67118661Sserge {
67218661Sserge 	register struct ignore *igp;
67318661Sserge 
67434692Sedward 	for (igp = table->i_head[hash(realfield)]; igp != 0; igp = igp->i_link)
67531142Sedward 		if (*igp->i_field == *realfield &&
67631142Sedward 		    equal(igp->i_field, realfield))
67718661Sserge 			return (1);
67818661Sserge 	return (0);
67918661Sserge }
680