Commit | Line | Data |
---|---|---|
d0aeaf5a DF |
1 | /* |
2 | * Copyright (c) 1980 Regents of the University of California. | |
0c5f72fb KB |
3 | * All rights reserved. |
4 | * | |
5 | * Redistribution and use in source and binary forms are permitted | |
6 | * provided that this notice is preserved and that due credit is given | |
7 | * to the University of California at Berkeley. The name of the University | |
8 | * may not be used to endorse or promote products derived from this | |
9 | * software without specific prior written permission. This software | |
10 | * is provided ``as is'' without express or implied warranty. | |
d0aeaf5a DF |
11 | */ |
12 | ||
0c5f72fb | 13 | #ifdef notdef |
9c226cb6 | 14 | static char sccsid[] = "@(#)aux.c 5.9 (Berkeley) %G%"; |
0c5f72fb | 15 | #endif /* notdef */ |
6447a23f KS |
16 | |
17 | #include "rcv.h" | |
18 | #include <sys/stat.h> | |
6447a23f KS |
19 | |
20 | /* | |
21 | * Mail -- a mail program | |
22 | * | |
23 | * Auxiliary functions. | |
24 | */ | |
25 | ||
6447a23f KS |
26 | /* |
27 | * Return a pointer to a dynamic copy of the argument. | |
28 | */ | |
29 | ||
30 | char * | |
31 | savestr(str) | |
32 | char *str; | |
33 | { | |
34 | register char *cp, *cp2, *top; | |
35 | ||
36 | for (cp = str; *cp; cp++) | |
37 | ; | |
38 | top = salloc(cp-str + 1); | |
39 | if (top == NOSTR) | |
40 | return(NOSTR); | |
41 | for (cp = str, cp2 = top; *cp; cp++) | |
42 | *cp2++ = *cp; | |
43 | *cp2 = 0; | |
44 | return(top); | |
45 | } | |
46 | ||
6447a23f KS |
47 | /* |
48 | * Announce a fatal error and die. | |
49 | */ | |
50 | ||
828615a1 EW |
51 | /*VARARGS1*/ |
52 | panic(fmt, a, b) | |
53 | char *fmt; | |
6447a23f | 54 | { |
828615a1 EW |
55 | fprintf(stderr, "panic: "); |
56 | fprintf(stderr, fmt, a, b); | |
57 | putc('\n', stderr); | |
6447a23f KS |
58 | exit(1); |
59 | } | |
60 | ||
6447a23f KS |
61 | /* |
62 | * Touch the named message by setting its MTOUCH flag. | |
63 | * Touched messages have the effect of not being sent | |
64 | * back to the system mailbox on exit. | |
65 | */ | |
66 | ||
67 | touch(mesg) | |
68 | { | |
dffe7e4f KS |
69 | register struct message *mp; |
70 | ||
71 | if (mesg < 1 || mesg > msgCount) | |
72 | return; | |
73 | mp = &message[mesg-1]; | |
74 | mp->m_flag |= MTOUCH; | |
75 | if ((mp->m_flag & MREAD) == 0) | |
76 | mp->m_flag |= MREAD|MSTATUS; | |
6447a23f KS |
77 | } |
78 | ||
79 | /* | |
80 | * Test to see if the passed file name is a directory. | |
81 | * Return true if it is. | |
82 | */ | |
83 | ||
84 | isdir(name) | |
85 | char name[]; | |
86 | { | |
87 | struct stat sbuf; | |
88 | ||
89 | if (stat(name, &sbuf) < 0) | |
90 | return(0); | |
91 | return((sbuf.st_mode & S_IFMT) == S_IFDIR); | |
92 | } | |
93 | ||
6447a23f KS |
94 | /* |
95 | * Count the number of arguments in the given string raw list. | |
96 | */ | |
97 | ||
98 | argcount(argv) | |
99 | char **argv; | |
100 | { | |
101 | register char **ap; | |
102 | ||
828615a1 | 103 | for (ap = argv; *ap++ != NOSTR;) |
6447a23f | 104 | ; |
828615a1 | 105 | return ap - argv - 1; |
6447a23f KS |
106 | } |
107 | ||
6447a23f KS |
108 | /* |
109 | * Return the desired header line from the passed message | |
110 | * pointer (or NOSTR if the desired header field is not available). | |
111 | */ | |
112 | ||
113 | char * | |
114 | hfield(field, mp) | |
115 | char field[]; | |
116 | struct message *mp; | |
117 | { | |
118 | register FILE *ibuf; | |
119 | char linebuf[LINESIZE]; | |
120 | register int lc; | |
828615a1 EW |
121 | register char *hfield; |
122 | char *colon; | |
6447a23f KS |
123 | |
124 | ibuf = setinput(mp); | |
828615a1 EW |
125 | if ((lc = mp->m_lines - 1) < 0) |
126 | return NOSTR; | |
6447a23f | 127 | if (readline(ibuf, linebuf) < 0) |
828615a1 EW |
128 | return NOSTR; |
129 | while (lc > 0) { | |
130 | if ((lc = gethfield(ibuf, linebuf, lc, &colon)) < 0) | |
131 | return NOSTR; | |
132 | if (hfield = ishfield(linebuf, colon, field)) | |
133 | return savestr(hfield); | |
134 | } | |
135 | return NOSTR; | |
6447a23f KS |
136 | } |
137 | ||
138 | /* | |
139 | * Return the next header field found in the given message. | |
828615a1 EW |
140 | * Return >= 0 if something found, < 0 elsewise. |
141 | * "colon" is set to point to the colon in the header. | |
6447a23f KS |
142 | * Must deal with \ continuations & other such fraud. |
143 | */ | |
144 | ||
828615a1 | 145 | gethfield(f, linebuf, rem, colon) |
6447a23f KS |
146 | register FILE *f; |
147 | char linebuf[]; | |
148 | register int rem; | |
828615a1 | 149 | char **colon; |
6447a23f KS |
150 | { |
151 | char line2[LINESIZE]; | |
6447a23f KS |
152 | register char *cp, *cp2; |
153 | register int c; | |
154 | ||
6447a23f | 155 | for (;;) { |
828615a1 EW |
156 | if (--rem < 0) |
157 | return -1; | |
158 | if ((c = readline(f, linebuf)) <= 0) | |
159 | return -1; | |
160 | for (cp = linebuf; isprint(*cp) && *cp != ' ' && *cp != ':'; | |
161 | cp++) | |
162 | ; | |
163 | if (*cp != ':' || cp == linebuf) | |
6447a23f | 164 | continue; |
6447a23f KS |
165 | /* |
166 | * I guess we got a headline. | |
167 | * Handle wraparounding | |
168 | */ | |
828615a1 EW |
169 | *colon = cp; |
170 | cp = linebuf + c; | |
6447a23f | 171 | for (;;) { |
828615a1 EW |
172 | while (--cp >= linebuf && (*cp == ' ' || *cp == '\t')) |
173 | ; | |
174 | cp++; | |
6447a23f KS |
175 | if (rem <= 0) |
176 | break; | |
828615a1 EW |
177 | ungetc(c = getc(f), f); |
178 | if (c != ' ' && c != '\t') | |
6447a23f | 179 | break; |
828615a1 | 180 | if ((c = readline(f, line2)) < 0) |
6447a23f KS |
181 | break; |
182 | rem--; | |
828615a1 | 183 | for (cp2 = line2; *cp2 == ' ' || *cp2 == '\t'; cp2++) |
6447a23f | 184 | ; |
828615a1 EW |
185 | c -= cp2 - line2; |
186 | if (cp + c >= linebuf + LINESIZE - 2) | |
6447a23f | 187 | break; |
6447a23f | 188 | *cp++ = ' '; |
828615a1 EW |
189 | bcopy(cp2, cp, c); |
190 | cp += c; | |
6447a23f | 191 | } |
828615a1 EW |
192 | *cp = 0; |
193 | return rem; | |
6447a23f KS |
194 | } |
195 | /* NOTREACHED */ | |
196 | } | |
197 | ||
198 | /* | |
199 | * Check whether the passed line is a header line of | |
828615a1 | 200 | * the desired breed. Return the field body, or 0. |
6447a23f KS |
201 | */ |
202 | ||
828615a1 EW |
203 | char* |
204 | ishfield(linebuf, colon, field) | |
6447a23f | 205 | char linebuf[], field[]; |
828615a1 | 206 | char *colon; |
6447a23f | 207 | { |
828615a1 | 208 | register char *cp = colon; |
6447a23f | 209 | |
6447a23f | 210 | *cp = 0; |
828615a1 EW |
211 | if (!icequal(linebuf, field)) { |
212 | *cp = ':'; | |
213 | return 0; | |
6447a23f | 214 | } |
828615a1 EW |
215 | *cp = ':'; |
216 | for (cp++; *cp == ' ' || *cp == '\t'; cp++) | |
217 | ; | |
218 | return cp; | |
6447a23f KS |
219 | } |
220 | ||
221 | /* | |
222 | * Compare two strings, ignoring case. | |
223 | */ | |
224 | ||
225 | icequal(s1, s2) | |
226 | register char *s1, *s2; | |
227 | { | |
828615a1 | 228 | register c1, c2; |
6447a23f | 229 | |
828615a1 EW |
230 | for (;;) { |
231 | if ((c1 = (unsigned char)*s1++) != | |
232 | (c2 = (unsigned char)*s2++)) { | |
233 | if (isupper(c1)) | |
234 | c1 = tolower(c1); | |
235 | if (c1 != c2) | |
236 | return 0; | |
237 | } | |
238 | if (c1 == 0) | |
239 | return 1; | |
240 | } | |
241 | /*NOTREACHED*/ | |
6447a23f KS |
242 | } |
243 | ||
da0d3a6d KS |
244 | /* |
245 | * Copy a string, lowercasing it as we go. | |
246 | */ | |
247 | istrcpy(dest, src) | |
828615a1 | 248 | register char *dest, *src; |
da0d3a6d | 249 | { |
da0d3a6d | 250 | |
da0d3a6d | 251 | do { |
828615a1 EW |
252 | if (isupper(*src)) |
253 | *dest++ = tolower(*src); | |
254 | else | |
255 | *dest++ = *src; | |
256 | } while (*src++ != 0); | |
da0d3a6d KS |
257 | } |
258 | ||
6447a23f KS |
259 | /* |
260 | * The following code deals with input stacking to do source | |
261 | * commands. All but the current file pointer are saved on | |
262 | * the stack. | |
263 | */ | |
264 | ||
265 | static int ssp = -1; /* Top of file stack */ | |
e48b42f1 KS |
266 | struct sstack { |
267 | FILE *s_file; /* File we were in. */ | |
268 | int s_cond; /* Saved state of conditionals */ | |
f4aa38b5 | 269 | int s_loading; /* Loading .mailrc, etc. */ |
46053c99 | 270 | } sstack[NOFILE]; |
6447a23f KS |
271 | |
272 | /* | |
273 | * Pushdown current input file and switch to a new one. | |
274 | * Set the global flag "sourcing" so that others will realize | |
275 | * that they are no longer reading from a tty (in all probability). | |
276 | */ | |
277 | ||
278 | source(name) | |
279 | char name[]; | |
280 | { | |
281 | register FILE *fi; | |
5c7ba847 | 282 | register char *cp; |
6447a23f | 283 | |
5c7ba847 KS |
284 | if ((cp = expand(name)) == NOSTR) |
285 | return(1); | |
286 | if ((fi = fopen(cp, "r")) == NULL) { | |
287 | perror(cp); | |
6447a23f KS |
288 | return(1); |
289 | } | |
46053c99 | 290 | if (ssp >= NOFILE - 2) { |
6447a23f KS |
291 | printf("Too much \"sourcing\" going on.\n"); |
292 | fclose(fi); | |
293 | return(1); | |
294 | } | |
e48b42f1 KS |
295 | sstack[++ssp].s_file = input; |
296 | sstack[ssp].s_cond = cond; | |
f4aa38b5 KS |
297 | sstack[ssp].s_loading = loading; |
298 | loading = 0; | |
e48b42f1 | 299 | cond = CANY; |
6447a23f KS |
300 | input = fi; |
301 | sourcing++; | |
302 | return(0); | |
303 | } | |
304 | ||
6447a23f KS |
305 | /* |
306 | * Pop the current input back to the previous level. | |
307 | * Update the "sourcing" flag as appropriate. | |
308 | */ | |
309 | ||
310 | unstack() | |
311 | { | |
312 | if (ssp < 0) { | |
313 | printf("\"Source\" stack over-pop.\n"); | |
314 | sourcing = 0; | |
315 | return(1); | |
316 | } | |
317 | fclose(input); | |
e48b42f1 KS |
318 | if (cond != CANY) |
319 | printf("Unmatched \"if\"\n"); | |
320 | cond = sstack[ssp].s_cond; | |
f4aa38b5 | 321 | loading = sstack[ssp].s_loading; |
e48b42f1 | 322 | input = sstack[ssp--].s_file; |
6447a23f | 323 | if (ssp < 0) |
f4aa38b5 | 324 | sourcing = loading; |
6447a23f KS |
325 | return(0); |
326 | } | |
327 | ||
328 | /* | |
329 | * Touch the indicated file. | |
330 | * This is nifty for the shell. | |
6447a23f KS |
331 | */ |
332 | ||
333 | alter(name) | |
334 | char name[]; | |
335 | { | |
6447a23f KS |
336 | struct stat statb; |
337 | long time(); | |
338 | time_t time_p[2]; | |
6447a23f | 339 | |
6447a23f KS |
340 | if (stat(name, &statb) < 0) |
341 | return; | |
342 | time_p[0] = time((long *) 0) + 1; | |
343 | time_p[1] = statb.st_mtime; | |
344 | utime(name, time_p); | |
6447a23f KS |
345 | } |
346 | ||
347 | /* | |
348 | * Examine the passed line buffer and | |
349 | * return true if it is all blanks and tabs. | |
350 | */ | |
351 | ||
352 | blankline(linebuf) | |
353 | char linebuf[]; | |
354 | { | |
355 | register char *cp; | |
356 | ||
357 | for (cp = linebuf; *cp; cp++) | |
46053c99 | 358 | if (*cp != ' ' && *cp != '\t') |
6447a23f KS |
359 | return(0); |
360 | return(1); | |
361 | } | |
362 | ||
12388009 KS |
363 | /* |
364 | * Get sender's name from this message. If the message has | |
365 | * a bunch of arpanet stuff in it, we may have to skin the name | |
366 | * before returning it. | |
367 | */ | |
368 | char * | |
369 | nameof(mp, reptype) | |
370 | register struct message *mp; | |
371 | { | |
8bcfa450 | 372 | register char *cp, *cp2; |
12388009 | 373 | |
8bcfa450 KS |
374 | cp = skin(name1(mp, reptype)); |
375 | if (reptype != 0 || charcount(cp, '!') < 2) | |
376 | return(cp); | |
377 | cp2 = rindex(cp, '!'); | |
378 | cp2--; | |
379 | while (cp2 > cp && *cp2 != '!') | |
380 | cp2--; | |
381 | if (*cp2 == '!') | |
382 | return(cp2 + 1); | |
383 | return(cp); | |
12388009 KS |
384 | } |
385 | ||
386 | /* | |
b4817aab | 387 | * Skin an arpa net address according to the RFC 822 interpretation |
12388009 KS |
388 | * of "host-phrase." |
389 | */ | |
390 | char * | |
391 | skin(name) | |
392 | char *name; | |
393 | { | |
394 | register int c; | |
395 | register char *cp, *cp2; | |
b4817aab | 396 | char *bufend; |
12388009 KS |
397 | int gotlt, lastsp; |
398 | char nbuf[BUFSIZ]; | |
46053c99 | 399 | int nesting; |
12388009 KS |
400 | |
401 | if (name == NOSTR) | |
402 | return(NOSTR); | |
e557a09a | 403 | if (index(name, '(') == NOSTR && index(name, '<') == NOSTR |
828615a1 | 404 | && index(name, ' ') == NOSTR) |
12388009 KS |
405 | return(name); |
406 | gotlt = 0; | |
407 | lastsp = 0; | |
b4817aab KM |
408 | bufend = nbuf; |
409 | for (cp = name, cp2 = bufend; c = *cp++; ) { | |
12388009 KS |
410 | switch (c) { |
411 | case '(': | |
b4817aab KM |
412 | /* |
413 | * Start of a "comment". | |
414 | * Ignore it. | |
415 | */ | |
46053c99 | 416 | nesting = 1; |
b4817aab KM |
417 | while ((c = *cp) != 0) { |
418 | cp++; | |
419 | switch (c) { | |
420 | case '\\': | |
421 | if (*cp == 0) | |
422 | goto outcm; | |
423 | cp++; | |
424 | break; | |
46053c99 S |
425 | case '(': |
426 | nesting++; | |
427 | break; | |
428 | ||
429 | case ')': | |
430 | --nesting; | |
431 | break; | |
432 | } | |
433 | ||
434 | if (nesting <= 0) | |
435 | break; | |
436 | } | |
b4817aab KM |
437 | outcm: |
438 | lastsp = 0; | |
439 | break; | |
440 | ||
441 | case '"': | |
442 | /* | |
443 | * Start of a "quoted-string". | |
444 | * Copy it in its entirety. | |
445 | */ | |
446 | while ((c = *cp) != 0) { | |
447 | cp++; | |
448 | switch (c) { | |
449 | case '\\': | |
450 | if ((c = *cp) == 0) | |
451 | goto outqs; | |
452 | cp++; | |
453 | break; | |
454 | case '"': | |
455 | goto outqs; | |
456 | } | |
457 | *cp2++ = c; | |
458 | } | |
459 | outqs: | |
e557a09a | 460 | lastsp = 0; |
12388009 KS |
461 | break; |
462 | ||
463 | case ' ': | |
e557a09a CL |
464 | if (cp[0] == 'a' && cp[1] == 't' && cp[2] == ' ') |
465 | cp += 3, *cp2++ = '@'; | |
466 | else | |
467 | if (cp[0] == '@' && cp[1] == ' ') | |
468 | cp += 2, *cp2++ = '@'; | |
469 | else | |
470 | lastsp = 1; | |
12388009 KS |
471 | break; |
472 | ||
473 | case '<': | |
b4817aab | 474 | cp2 = bufend; |
12388009 KS |
475 | gotlt++; |
476 | lastsp = 0; | |
477 | break; | |
478 | ||
479 | case '>': | |
b4817aab KM |
480 | if (gotlt) { |
481 | gotlt = 0; | |
482 | while (*cp != ',' && *cp != 0) | |
483 | cp++; | |
484 | if (*cp == 0 ) | |
485 | goto done; | |
486 | *cp2++ = ','; | |
487 | *cp2++ = ' '; | |
488 | bufend = cp2; | |
489 | break; | |
490 | } | |
12388009 KS |
491 | |
492 | /* Fall into . . . */ | |
493 | ||
494 | default: | |
495 | if (lastsp) { | |
496 | lastsp = 0; | |
497 | *cp2++ = ' '; | |
498 | } | |
499 | *cp2++ = c; | |
500 | break; | |
501 | } | |
502 | } | |
503 | done: | |
504 | *cp2 = 0; | |
505 | ||
506 | return(savestr(nbuf)); | |
507 | } | |
508 | ||
6447a23f KS |
509 | /* |
510 | * Fetch the sender's name from the passed message. | |
12388009 KS |
511 | * Reptype can be |
512 | * 0 -- get sender's name for display purposes | |
513 | * 1 -- get sender's name for reply | |
514 | * 2 -- get sender's name for Reply | |
6447a23f KS |
515 | */ |
516 | ||
517 | char * | |
12388009 | 518 | name1(mp, reptype) |
6447a23f KS |
519 | register struct message *mp; |
520 | { | |
521 | char namebuf[LINESIZE]; | |
522 | char linebuf[LINESIZE]; | |
523 | register char *cp, *cp2; | |
524 | register FILE *ibuf; | |
525 | int first = 1; | |
526 | ||
12388009 | 527 | if ((cp = hfield("from", mp)) != NOSTR) |
828615a1 | 528 | return cp; |
12388009 | 529 | if (reptype == 0 && (cp = hfield("sender", mp)) != NOSTR) |
828615a1 | 530 | return cp; |
6447a23f | 531 | ibuf = setinput(mp); |
828615a1 EW |
532 | namebuf[0] = 0; |
533 | if (readline(ibuf, linebuf) < 0) | |
6447a23f KS |
534 | return(savestr(namebuf)); |
535 | newname: | |
828615a1 | 536 | for (cp = linebuf; *cp && *cp != ' '; cp++) |
6447a23f | 537 | ; |
828615a1 | 538 | for (; *cp == ' ' || *cp == '\t'; cp++) |
6447a23f | 539 | ; |
828615a1 EW |
540 | for (cp2 = &namebuf[strlen(namebuf)]; |
541 | *cp && *cp != ' ' && *cp != '\t' && cp2 < namebuf + LINESIZE - 1;) | |
542 | *cp2++ = *cp++; | |
6447a23f | 543 | *cp2 = '\0'; |
828615a1 | 544 | if (readline(ibuf, linebuf) < 0) |
6447a23f KS |
545 | return(savestr(namebuf)); |
546 | if ((cp = index(linebuf, 'F')) == NULL) | |
547 | return(savestr(namebuf)); | |
548 | if (strncmp(cp, "From", 4) != 0) | |
549 | return(savestr(namebuf)); | |
550 | while ((cp = index(cp, 'r')) != NULL) { | |
551 | if (strncmp(cp, "remote", 6) == 0) { | |
552 | if ((cp = index(cp, 'f')) == NULL) | |
553 | break; | |
554 | if (strncmp(cp, "from", 4) != 0) | |
555 | break; | |
556 | if ((cp = index(cp, ' ')) == NULL) | |
557 | break; | |
558 | cp++; | |
559 | if (first) { | |
828615a1 | 560 | strcpy(namebuf, cp); |
6447a23f KS |
561 | first = 0; |
562 | } else | |
563 | strcpy(rindex(namebuf, '!')+1, cp); | |
564 | strcat(namebuf, "!"); | |
565 | goto newname; | |
566 | } | |
567 | cp++; | |
568 | } | |
569 | return(savestr(namebuf)); | |
570 | } | |
571 | ||
8bcfa450 KS |
572 | /* |
573 | * Count the occurances of c in str | |
574 | */ | |
575 | charcount(str, c) | |
576 | char *str; | |
577 | { | |
578 | register char *cp; | |
579 | register int i; | |
580 | ||
581 | for (i = 0, cp = str; *cp; cp++) | |
582 | if (*cp == c) | |
583 | i++; | |
584 | return(i); | |
585 | } | |
586 | ||
6447a23f | 587 | /* |
828615a1 | 588 | * Are any of the characters in the two strings the same? |
6447a23f KS |
589 | */ |
590 | ||
828615a1 EW |
591 | anyof(s1, s2) |
592 | register char *s1, *s2; | |
6447a23f | 593 | { |
6447a23f | 594 | |
828615a1 EW |
595 | while (*s1) |
596 | if (index(s2, *s1++)) | |
597 | return 1; | |
598 | return 0; | |
6447a23f KS |
599 | } |
600 | ||
601 | /* | |
828615a1 | 602 | * Convert c to upper case |
6447a23f KS |
603 | */ |
604 | ||
828615a1 EW |
605 | raise(c) |
606 | register c; | |
607 | { | |
608 | ||
609 | if (islower(c)) | |
610 | return toupper(c); | |
611 | return c; | |
612 | } | |
613 | ||
614 | /* | |
615 | * Copy s1 to s2, return pointer to null in s2. | |
616 | */ | |
617 | ||
618 | char * | |
619 | copy(s1, s2) | |
6447a23f KS |
620 | register char *s1, *s2; |
621 | { | |
6447a23f | 622 | |
828615a1 EW |
623 | while (*s2++ = *s1++) |
624 | ; | |
625 | return s2 - 1; | |
626 | } | |
627 | ||
628 | /* | |
629 | * Add a single character onto a string. | |
630 | */ | |
631 | ||
632 | stradd(str, c) | |
633 | register char *str; | |
634 | { | |
635 | ||
636 | while (*str++) | |
637 | ; | |
638 | str[-1] = c; | |
639 | *str = 0; | |
6447a23f KS |
640 | } |
641 | ||
da0d3a6d KS |
642 | /* |
643 | * See if the given header field is supposed to be ignored. | |
644 | */ | |
887efe38 | 645 | isign(field, ignore) |
da0d3a6d | 646 | char *field; |
887efe38 | 647 | struct ignoretab ignore[2]; |
da0d3a6d KS |
648 | { |
649 | char realfld[BUFSIZ]; | |
da0d3a6d | 650 | |
46053c99 S |
651 | /* |
652 | * Lower-case the string, so that "Status" and "status" | |
653 | * will hash to the same place. | |
654 | */ | |
da0d3a6d | 655 | istrcpy(realfld, field); |
887efe38 EW |
656 | if (ignore[1].i_count > 0) |
657 | return (!member(realfld, ignore + 1)); | |
46053c99 S |
658 | else |
659 | return (member(realfld, ignore)); | |
660 | } | |
661 | ||
662 | member(realfield, table) | |
663 | register char *realfield; | |
887efe38 | 664 | struct ignoretab *table; |
46053c99 S |
665 | { |
666 | register struct ignore *igp; | |
667 | ||
887efe38 | 668 | for (igp = table->i_head[hash(realfield)]; igp != 0; igp = igp->i_link) |
828615a1 EW |
669 | if (*igp->i_field == *realfield && |
670 | equal(igp->i_field, realfield)) | |
46053c99 | 671 | return (1); |
46053c99 | 672 | return (0); |
da0d3a6d | 673 | } |