xref: /csrg-svn/usr.bin/mail/aux.c (revision 54505)
122444Sdist /*
222444Sdist  * Copyright (c) 1980 Regents of the University of California.
333499Sbostic  * All rights reserved.
433499Sbostic  *
542741Sbostic  * %sccs.include.redist.c%
622444Sdist  */
722444Sdist 
834905Sbostic #ifndef lint
9*54505Sbostic static char sccsid[] = "@(#)aux.c	5.21 (Berkeley) 06/26/92";
1034905Sbostic #endif /* not lint */
111219Skas 
121219Skas #include "rcv.h"
13*54505Sbostic #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 *
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 /*
371219Skas  * Announce a fatal error and die.
381219Skas  */
39*54505Sbostic #if __STDC__
40*54505Sbostic #include <stdarg.h>
41*54505Sbostic #else
42*54505Sbostic #include <varargs.h>
43*54505Sbostic #endif
441219Skas 
45*54505Sbostic void
46*54505Sbostic #if __STDC__
47*54505Sbostic panic(const char *fmt, ...)
48*54505Sbostic #else
49*54505Sbostic panic(fmt, va_alist)
5031142Sedward 	char *fmt;
51*54505Sbostic         va_dcl
52*54505Sbostic #endif
531219Skas {
54*54505Sbostic 	va_list ap;
55*54505Sbostic #if __STDC__
56*54505Sbostic 	va_start(ap, fmt);
57*54505Sbostic #else
58*54505Sbostic 	va_start(ap);
59*54505Sbostic #endif
60*54505Sbostic 	(void)fprintf(stderr, "panic: ");
61*54505Sbostic 	vfprintf(stderr, fmt, ap);
62*54505Sbostic 	va_end(ap);
63*54505Sbostic 	(void)fprintf(stderr, "\n");
64*54505Sbostic 	fflush(stderr);
6543865Sedward 	abort();
661219Skas }
671219Skas 
681219Skas /*
691219Skas  * Touch the named message by setting its MTOUCH flag.
701219Skas  * Touched messages have the effect of not being sent
711219Skas  * back to the system mailbox on exit.
721219Skas  */
73*54505Sbostic void
7434987Sedward touch(mp)
7534987Sedward 	register struct message *mp;
761219Skas {
771479Skas 
781479Skas 	mp->m_flag |= MTOUCH;
791479Skas 	if ((mp->m_flag & MREAD) == 0)
801479Skas 		mp->m_flag |= MREAD|MSTATUS;
811219Skas }
821219Skas 
831219Skas /*
841219Skas  * Test to see if the passed file name is a directory.
851219Skas  * Return true if it is.
861219Skas  */
87*54505Sbostic int
881219Skas isdir(name)
891219Skas 	char name[];
901219Skas {
911219Skas 	struct stat sbuf;
921219Skas 
931219Skas 	if (stat(name, &sbuf) < 0)
941219Skas 		return(0);
951219Skas 	return((sbuf.st_mode & S_IFMT) == S_IFDIR);
961219Skas }
971219Skas 
981219Skas /*
991219Skas  * Count the number of arguments in the given string raw list.
1001219Skas  */
101*54505Sbostic int
1021219Skas argcount(argv)
1031219Skas 	char **argv;
1041219Skas {
1051219Skas 	register char **ap;
1061219Skas 
10731142Sedward 	for (ap = argv; *ap++ != NOSTR;)
1081219Skas 		;
10931142Sedward 	return ap - argv - 1;
1101219Skas }
1111219Skas 
1121219Skas /*
1131219Skas  * Return the desired header line from the passed message
1141219Skas  * pointer (or NOSTR if the desired header field is not available).
1151219Skas  */
1161219Skas char *
1171219Skas hfield(field, mp)
1181219Skas 	char field[];
1191219Skas 	struct message *mp;
1201219Skas {
1211219Skas 	register FILE *ibuf;
1221219Skas 	char linebuf[LINESIZE];
1231219Skas 	register int lc;
12431142Sedward 	register char *hfield;
12531142Sedward 	char *colon;
1261219Skas 
1271219Skas 	ibuf = setinput(mp);
12831142Sedward 	if ((lc = mp->m_lines - 1) < 0)
12931142Sedward 		return NOSTR;
13036478Sedward 	if (readline(ibuf, linebuf, LINESIZE) < 0)
13131142Sedward 		return NOSTR;
13231142Sedward 	while (lc > 0) {
13331142Sedward 		if ((lc = gethfield(ibuf, linebuf, lc, &colon)) < 0)
13431142Sedward 			return NOSTR;
13531142Sedward 		if (hfield = ishfield(linebuf, colon, field))
13631142Sedward 			return savestr(hfield);
13731142Sedward 	}
13831142Sedward 	return NOSTR;
1391219Skas }
1401219Skas 
1411219Skas /*
1421219Skas  * Return the next header field found in the given message.
14331142Sedward  * Return >= 0 if something found, < 0 elsewise.
14431142Sedward  * "colon" is set to point to the colon in the header.
1451219Skas  * Must deal with \ continuations & other such fraud.
1461219Skas  */
147*54505Sbostic int
14831142Sedward gethfield(f, linebuf, rem, colon)
1491219Skas 	register FILE *f;
1501219Skas 	char linebuf[];
1511219Skas 	register int rem;
15231142Sedward 	char **colon;
1531219Skas {
1541219Skas 	char line2[LINESIZE];
1551219Skas 	register char *cp, *cp2;
1561219Skas 	register int c;
1571219Skas 
1581219Skas 	for (;;) {
15931142Sedward 		if (--rem < 0)
16031142Sedward 			return -1;
16136478Sedward 		if ((c = readline(f, linebuf, LINESIZE)) <= 0)
16231142Sedward 			return -1;
16331142Sedward 		for (cp = linebuf; isprint(*cp) && *cp != ' ' && *cp != ':';
16431142Sedward 		     cp++)
16531142Sedward 			;
16631142Sedward 		if (*cp != ':' || cp == linebuf)
1671219Skas 			continue;
1681219Skas 		/*
1691219Skas 		 * I guess we got a headline.
1701219Skas 		 * Handle wraparounding
1711219Skas 		 */
17231142Sedward 		*colon = cp;
17331142Sedward 		cp = linebuf + c;
1741219Skas 		for (;;) {
17531142Sedward 			while (--cp >= linebuf && (*cp == ' ' || *cp == '\t'))
17631142Sedward 				;
17731142Sedward 			cp++;
1781219Skas 			if (rem <= 0)
1791219Skas 				break;
18031142Sedward 			ungetc(c = getc(f), f);
18131142Sedward 			if (c != ' ' && c != '\t')
1821219Skas 				break;
18336478Sedward 			if ((c = readline(f, line2, LINESIZE)) < 0)
1841219Skas 				break;
1851219Skas 			rem--;
18631142Sedward 			for (cp2 = line2; *cp2 == ' ' || *cp2 == '\t'; cp2++)
1871219Skas 				;
18831142Sedward 			c -= cp2 - line2;
18931142Sedward 			if (cp + c >= linebuf + LINESIZE - 2)
1901219Skas 				break;
1911219Skas 			*cp++ = ' ';
19231142Sedward 			bcopy(cp2, cp, c);
19331142Sedward 			cp += c;
1941219Skas 		}
19531142Sedward 		*cp = 0;
19631142Sedward 		return rem;
1971219Skas 	}
1981219Skas 	/* NOTREACHED */
1991219Skas }
2001219Skas 
2011219Skas /*
2021219Skas  * Check whether the passed line is a header line of
20331142Sedward  * the desired breed.  Return the field body, or 0.
2041219Skas  */
2051219Skas 
20631142Sedward char*
20731142Sedward ishfield(linebuf, colon, field)
2081219Skas 	char linebuf[], field[];
20931142Sedward 	char *colon;
2101219Skas {
21131142Sedward 	register char *cp = colon;
2121219Skas 
2131219Skas 	*cp = 0;
21434987Sedward 	if (strcasecmp(linebuf, field) != 0) {
21531142Sedward 		*cp = ':';
21631142Sedward 		return 0;
2171219Skas 	}
21831142Sedward 	*cp = ':';
21931142Sedward 	for (cp++; *cp == ' ' || *cp == '\t'; cp++)
22031142Sedward 		;
22131142Sedward 	return cp;
2221219Skas }
2231219Skas 
2241219Skas /*
2257571Skurt  * Copy a string, lowercasing it as we go.
2267571Skurt  */
227*54505Sbostic void
2287571Skurt istrcpy(dest, src)
22931142Sedward 	register char *dest, *src;
2307571Skurt {
2317571Skurt 
2327571Skurt 	do {
23331142Sedward 		if (isupper(*src))
23431142Sedward 			*dest++ = tolower(*src);
23531142Sedward 		else
23631142Sedward 			*dest++ = *src;
23731142Sedward 	} while (*src++ != 0);
2387571Skurt }
2397571Skurt 
2407571Skurt /*
2411219Skas  * The following code deals with input stacking to do source
2421219Skas  * commands.  All but the current file pointer are saved on
2431219Skas  * the stack.
2441219Skas  */
2451219Skas 
24634965Sedward static	int	ssp;			/* Top of file stack */
2471519Skas struct sstack {
2481519Skas 	FILE	*s_file;		/* File we were in. */
2491519Skas 	int	s_cond;			/* Saved state of conditionals */
2505785Skurt 	int	s_loading;		/* Loading .mailrc, etc. */
25118661Sserge } sstack[NOFILE];
2521219Skas 
2531219Skas /*
2541219Skas  * Pushdown current input file and switch to a new one.
2551219Skas  * Set the global flag "sourcing" so that others will realize
2561219Skas  * that they are no longer reading from a tty (in all probability).
2571219Skas  */
258*54505Sbostic int
25934966Sedward source(arglist)
26034966Sedward 	char **arglist;
2611219Skas {
26234966Sedward 	FILE *fi;
26334966Sedward 	char *cp;
2641219Skas 
26534966Sedward 	if ((cp = expand(*arglist)) == NOSTR)
2661219Skas 		return(1);
26743865Sedward 	if ((fi = Fopen(cp, "r")) == NULL) {
2683914Skurt 		perror(cp);
2693914Skurt 		return(1);
2701219Skas 	}
27134965Sedward 	if (ssp >= NOFILE - 1) {
2721219Skas 		printf("Too much \"sourcing\" going on.\n");
27343865Sedward 		Fclose(fi);
2741219Skas 		return(1);
2751219Skas 	}
27634965Sedward 	sstack[ssp].s_file = input;
2771519Skas 	sstack[ssp].s_cond = cond;
2785785Skurt 	sstack[ssp].s_loading = loading;
27934965Sedward 	ssp++;
2805785Skurt 	loading = 0;
2811519Skas 	cond = CANY;
2821219Skas 	input = fi;
2831219Skas 	sourcing++;
2841219Skas 	return(0);
2851219Skas }
2861219Skas 
2871219Skas /*
2881219Skas  * Pop the current input back to the previous level.
2891219Skas  * Update the "sourcing" flag as appropriate.
2901219Skas  */
291*54505Sbostic int
2921219Skas unstack()
2931219Skas {
29434965Sedward 	if (ssp <= 0) {
2951219Skas 		printf("\"Source\" stack over-pop.\n");
2961219Skas 		sourcing = 0;
2971219Skas 		return(1);
2981219Skas 	}
29943865Sedward 	Fclose(input);
3001519Skas 	if (cond != CANY)
3011519Skas 		printf("Unmatched \"if\"\n");
30234965Sedward 	ssp--;
3031519Skas 	cond = sstack[ssp].s_cond;
3045785Skurt 	loading = sstack[ssp].s_loading;
30534965Sedward 	input = sstack[ssp].s_file;
30634965Sedward 	if (ssp == 0)
3075785Skurt 		sourcing = loading;
3081219Skas 	return(0);
3091219Skas }
3101219Skas 
3111219Skas /*
3121219Skas  * Touch the indicated file.
3131219Skas  * This is nifty for the shell.
3141219Skas  */
315*54505Sbostic void
3161219Skas alter(name)
31738078Sbostic 	char *name;
3181219Skas {
31938078Sbostic 	struct stat sb;
32038078Sbostic 	struct timeval tv[2];
32138078Sbostic 	time_t time();
3221219Skas 
32338078Sbostic 	if (stat(name, &sb))
3241219Skas 		return;
32538078Sbostic 	tv[0].tv_sec = time((time_t *)0) + 1;
32638078Sbostic 	tv[1].tv_sec = sb.st_mtime;
32738078Sbostic 	tv[0].tv_usec = tv[1].tv_usec = 0;
32838078Sbostic 	(void)utimes(name, tv);
3291219Skas }
3301219Skas 
3311219Skas /*
3321219Skas  * Examine the passed line buffer and
3331219Skas  * return true if it is all blanks and tabs.
3341219Skas  */
335*54505Sbostic int
3361219Skas blankline(linebuf)
3371219Skas 	char linebuf[];
3381219Skas {
3391219Skas 	register char *cp;
3401219Skas 
3411219Skas 	for (cp = linebuf; *cp; cp++)
34218661Sserge 		if (*cp != ' ' && *cp != '\t')
3431219Skas 			return(0);
3441219Skas 	return(1);
3451219Skas }
3461219Skas 
3471219Skas /*
3483195Skas  * Get sender's name from this message.  If the message has
3493195Skas  * a bunch of arpanet stuff in it, we may have to skin the name
3503195Skas  * before returning it.
3513195Skas  */
3523195Skas char *
3533195Skas nameof(mp, reptype)
3543195Skas 	register struct message *mp;
355*54505Sbostic 	int reptype;
3563195Skas {
3575237Skurt 	register char *cp, *cp2;
3583195Skas 
3595237Skurt 	cp = skin(name1(mp, reptype));
3605237Skurt 	if (reptype != 0 || charcount(cp, '!') < 2)
3615237Skurt 		return(cp);
3625237Skurt 	cp2 = rindex(cp, '!');
3635237Skurt 	cp2--;
3645237Skurt 	while (cp2 > cp && *cp2 != '!')
3655237Skurt 		cp2--;
3665237Skurt 	if (*cp2 == '!')
3675237Skurt 		return(cp2 + 1);
3685237Skurt 	return(cp);
3693195Skas }
3703195Skas 
3713195Skas /*
37239763Sedward  * Start of a "comment".
37339763Sedward  * Ignore it.
37439763Sedward  */
37539763Sedward char *
37639763Sedward skip_comment(cp)
37739763Sedward 	register char *cp;
37839763Sedward {
37939763Sedward 	register nesting = 1;
38039763Sedward 
38139763Sedward 	for (; nesting > 0 && *cp; cp++) {
38239763Sedward 		switch (*cp) {
38339763Sedward 		case '\\':
38439763Sedward 			if (cp[1])
38539763Sedward 				cp++;
38639763Sedward 			break;
38739763Sedward 		case '(':
38839763Sedward 			nesting++;
38939763Sedward 			break;
39039763Sedward 		case ')':
39139763Sedward 			nesting--;
39239763Sedward 			break;
39339763Sedward 		}
39439763Sedward 	}
39539763Sedward 	return cp;
39639763Sedward }
39739763Sedward 
39839763Sedward /*
39925912Smckusick  * Skin an arpa net address according to the RFC 822 interpretation
4003195Skas  * of "host-phrase."
4013195Skas  */
4023195Skas char *
4033195Skas skin(name)
4043195Skas 	char *name;
4053195Skas {
4063195Skas 	register int c;
4073195Skas 	register char *cp, *cp2;
40825912Smckusick 	char *bufend;
4093195Skas 	int gotlt, lastsp;
4103195Skas 	char nbuf[BUFSIZ];
4113195Skas 
4123195Skas 	if (name == NOSTR)
4133195Skas 		return(NOSTR);
41412819Sleres 	if (index(name, '(') == NOSTR && index(name, '<') == NOSTR
41531142Sedward 	    && index(name, ' ') == NOSTR)
4163195Skas 		return(name);
4173195Skas 	gotlt = 0;
4183195Skas 	lastsp = 0;
41925912Smckusick 	bufend = nbuf;
42025912Smckusick 	for (cp = name, cp2 = bufend; c = *cp++; ) {
4213195Skas 		switch (c) {
4223195Skas 		case '(':
42339763Sedward 			cp = skip_comment(cp);
42412819Sleres 			lastsp = 0;
4253195Skas 			break;
4263195Skas 
42725912Smckusick 		case '"':
42825912Smckusick 			/*
42925912Smckusick 			 * Start of a "quoted-string".
43025912Smckusick 			 * Copy it in its entirety.
43125912Smckusick 			 */
43239763Sedward 			while (c = *cp) {
43325912Smckusick 				cp++;
43439763Sedward 				if (c == '"')
43539763Sedward 					break;
43639763Sedward 				if (c != '\\')
43739763Sedward 					*cp2++ = c;
43839763Sedward 				else if (c = *cp) {
43939763Sedward 					*cp2++ = c;
44025912Smckusick 					cp++;
44125912Smckusick 				}
44225912Smckusick 			}
44325912Smckusick 			lastsp = 0;
44425912Smckusick 			break;
44525912Smckusick 
4463195Skas 		case ' ':
44712819Sleres 			if (cp[0] == 'a' && cp[1] == 't' && cp[2] == ' ')
44812819Sleres 				cp += 3, *cp2++ = '@';
44912819Sleres 			else
45012819Sleres 			if (cp[0] == '@' && cp[1] == ' ')
45112819Sleres 				cp += 2, *cp2++ = '@';
45212819Sleres 			else
45312819Sleres 				lastsp = 1;
4543195Skas 			break;
4553195Skas 
4563195Skas 		case '<':
45725912Smckusick 			cp2 = bufend;
4583195Skas 			gotlt++;
4593195Skas 			lastsp = 0;
4603195Skas 			break;
4613195Skas 
4623195Skas 		case '>':
46325912Smckusick 			if (gotlt) {
46425912Smckusick 				gotlt = 0;
46539763Sedward 				while ((c = *cp) && c != ',') {
46625912Smckusick 					cp++;
46739763Sedward 					if (c == '(')
46839763Sedward 						cp = skip_comment(cp);
46939763Sedward 					else if (c == '"')
47039763Sedward 						while (c = *cp) {
47139763Sedward 							cp++;
47239763Sedward 							if (c == '"')
47339763Sedward 								break;
47439763Sedward 							if (c == '\\' && *cp)
47539763Sedward 								cp++;
47639763Sedward 						}
47739763Sedward 				}
47839763Sedward 				lastsp = 0;
47925912Smckusick 				break;
48025912Smckusick 			}
4813195Skas 			/* Fall into . . . */
4823195Skas 
4833195Skas 		default:
4843195Skas 			if (lastsp) {
4853195Skas 				lastsp = 0;
4863195Skas 				*cp2++ = ' ';
4873195Skas 			}
4883195Skas 			*cp2++ = c;
48939763Sedward 			if (c == ',' && !gotlt) {
49039763Sedward 				*cp2++ = ' ';
49139763Sedward 				for (; *cp == ' '; cp++)
49239763Sedward 					;
49339763Sedward 				lastsp = 0;
49439763Sedward 				bufend = cp2;
49539763Sedward 			}
4963195Skas 		}
4973195Skas 	}
4983195Skas 	*cp2 = 0;
4993195Skas 
5003195Skas 	return(savestr(nbuf));
5013195Skas }
5023195Skas 
5033195Skas /*
5041219Skas  * Fetch the sender's name from the passed message.
5053195Skas  * Reptype can be
5063195Skas  *	0 -- get sender's name for display purposes
5073195Skas  *	1 -- get sender's name for reply
5083195Skas  *	2 -- get sender's name for Reply
5091219Skas  */
5101219Skas char *
5113195Skas name1(mp, reptype)
5121219Skas 	register struct message *mp;
513*54505Sbostic 	int reptype;
5141219Skas {
5151219Skas 	char namebuf[LINESIZE];
5161219Skas 	char linebuf[LINESIZE];
5171219Skas 	register char *cp, *cp2;
5181219Skas 	register FILE *ibuf;
5191219Skas 	int first = 1;
5201219Skas 
5213195Skas 	if ((cp = hfield("from", mp)) != NOSTR)
52231142Sedward 		return cp;
5233195Skas 	if (reptype == 0 && (cp = hfield("sender", mp)) != NOSTR)
52431142Sedward 		return cp;
5251219Skas 	ibuf = setinput(mp);
52631142Sedward 	namebuf[0] = 0;
52736478Sedward 	if (readline(ibuf, linebuf, LINESIZE) < 0)
5281219Skas 		return(savestr(namebuf));
5291219Skas newname:
53031142Sedward 	for (cp = linebuf; *cp && *cp != ' '; cp++)
5311219Skas 		;
53231142Sedward 	for (; *cp == ' ' || *cp == '\t'; cp++)
5331219Skas 		;
53431142Sedward 	for (cp2 = &namebuf[strlen(namebuf)];
53531142Sedward 	     *cp && *cp != ' ' && *cp != '\t' && cp2 < namebuf + LINESIZE - 1;)
53631142Sedward 		*cp2++ = *cp++;
5371219Skas 	*cp2 = '\0';
53836478Sedward 	if (readline(ibuf, linebuf, LINESIZE) < 0)
5391219Skas 		return(savestr(namebuf));
5401219Skas 	if ((cp = index(linebuf, 'F')) == NULL)
5411219Skas 		return(savestr(namebuf));
5421219Skas 	if (strncmp(cp, "From", 4) != 0)
5431219Skas 		return(savestr(namebuf));
5441219Skas 	while ((cp = index(cp, 'r')) != NULL) {
5451219Skas 		if (strncmp(cp, "remote", 6) == 0) {
5461219Skas 			if ((cp = index(cp, 'f')) == NULL)
5471219Skas 				break;
5481219Skas 			if (strncmp(cp, "from", 4) != 0)
5491219Skas 				break;
5501219Skas 			if ((cp = index(cp, ' ')) == NULL)
5511219Skas 				break;
5521219Skas 			cp++;
5531219Skas 			if (first) {
55431142Sedward 				strcpy(namebuf, cp);
5551219Skas 				first = 0;
5561219Skas 			} else
5571219Skas 				strcpy(rindex(namebuf, '!')+1, cp);
5581219Skas 			strcat(namebuf, "!");
5591219Skas 			goto newname;
5601219Skas 		}
5611219Skas 		cp++;
5621219Skas 	}
5631219Skas 	return(savestr(namebuf));
5641219Skas }
5651219Skas 
5661219Skas /*
5675237Skurt  * Count the occurances of c in str
5685237Skurt  */
569*54505Sbostic int
5705237Skurt charcount(str, c)
5715237Skurt 	char *str;
572*54505Sbostic 	int c;
5735237Skurt {
5745237Skurt 	register char *cp;
5755237Skurt 	register int i;
5765237Skurt 
5775237Skurt 	for (i = 0, cp = str; *cp; cp++)
5785237Skurt 		if (*cp == c)
5795237Skurt 			i++;
5805237Skurt 	return(i);
5815237Skurt }
5825237Skurt 
5835237Skurt /*
58431142Sedward  * Are any of the characters in the two strings the same?
5851219Skas  */
586*54505Sbostic int
58731142Sedward anyof(s1, s2)
58831142Sedward 	register char *s1, *s2;
5891219Skas {
5901219Skas 
59131142Sedward 	while (*s1)
59231142Sedward 		if (index(s2, *s1++))
59331142Sedward 			return 1;
59431142Sedward 	return 0;
5951219Skas }
5961219Skas 
5971219Skas /*
59831142Sedward  * Convert c to upper case
5991219Skas  */
600*54505Sbostic int
60131142Sedward raise(c)
602*54505Sbostic 	register int c;
60331142Sedward {
60431142Sedward 
60531142Sedward 	if (islower(c))
60631142Sedward 		return toupper(c);
60731142Sedward 	return c;
60831142Sedward }
60931142Sedward 
61031142Sedward /*
61131142Sedward  * Copy s1 to s2, return pointer to null in s2.
61231142Sedward  */
61331142Sedward char *
61431142Sedward copy(s1, s2)
6151219Skas 	register char *s1, *s2;
6161219Skas {
6171219Skas 
61831142Sedward 	while (*s2++ = *s1++)
61931142Sedward 		;
62031142Sedward 	return s2 - 1;
6211219Skas }
6221219Skas 
6231219Skas /*
6247571Skurt  * See if the given header field is supposed to be ignored.
6257571Skurt  */
626*54505Sbostic int
62734692Sedward isign(field, ignore)
6287571Skurt 	char *field;
62934692Sedward 	struct ignoretab ignore[2];
6307571Skurt {
6317571Skurt 	char realfld[BUFSIZ];
6327571Skurt 
63334969Sedward 	if (ignore == ignoreall)
63434969Sedward 		return 1;
63518661Sserge 	/*
63618661Sserge 	 * Lower-case the string, so that "Status" and "status"
63718661Sserge 	 * will hash to the same place.
63818661Sserge 	 */
6397571Skurt 	istrcpy(realfld, field);
64034692Sedward 	if (ignore[1].i_count > 0)
64134692Sedward 		return (!member(realfld, ignore + 1));
64218661Sserge 	else
64318661Sserge 		return (member(realfld, ignore));
6447571Skurt }
64518661Sserge 
646*54505Sbostic int
64718661Sserge member(realfield, table)
64818661Sserge 	register char *realfield;
64934692Sedward 	struct ignoretab *table;
65018661Sserge {
65118661Sserge 	register struct ignore *igp;
65218661Sserge 
65334692Sedward 	for (igp = table->i_head[hash(realfield)]; igp != 0; igp = igp->i_link)
65431142Sedward 		if (*igp->i_field == *realfield &&
65531142Sedward 		    equal(igp->i_field, realfield))
65618661Sserge 			return (1);
65718661Sserge 	return (0);
65818661Sserge }
659