11219Skas # 21219Skas 31219Skas #include "rcv.h" 41219Skas #include <sys/stat.h> 51219Skas #include <ctype.h> 61219Skas 71219Skas /* 81219Skas * Mail -- a mail program 91219Skas * 101219Skas * Auxiliary functions. 111219Skas */ 121219Skas 13*7571Skurt static char *SccsId = "@(#)aux.c 2.6 07/28/82"; 141219Skas 151219Skas /* 161219Skas * Return a pointer to a dynamic copy of the argument. 171219Skas */ 181219Skas 191219Skas char * 201219Skas savestr(str) 211219Skas char *str; 221219Skas { 231219Skas register char *cp, *cp2, *top; 241219Skas 251219Skas for (cp = str; *cp; cp++) 261219Skas ; 271219Skas top = salloc(cp-str + 1); 281219Skas if (top == NOSTR) 291219Skas return(NOSTR); 301219Skas for (cp = str, cp2 = top; *cp; cp++) 311219Skas *cp2++ = *cp; 321219Skas *cp2 = 0; 331219Skas return(top); 341219Skas } 351219Skas 361219Skas /* 371219Skas * Copy the name from the passed header line into the passed 381219Skas * name buffer. Null pad the name buffer. 391219Skas */ 401219Skas 411219Skas copyname(linebuf, nbuf) 421219Skas char *linebuf, *nbuf; 431219Skas { 441219Skas register char *cp, *cp2; 451219Skas 461219Skas for (cp = linebuf + 5, cp2 = nbuf; *cp != ' ' && cp2-nbuf < 8; cp++) 471219Skas *cp2++ = *cp; 481219Skas while (cp2-nbuf < 8) 491219Skas *cp2++ = 0; 501219Skas } 511219Skas 521219Skas /* 531219Skas * Announce a fatal error and die. 541219Skas */ 551219Skas 561219Skas panic(str) 571219Skas char *str; 581219Skas { 591219Skas prs("panic: "); 601219Skas prs(str); 611219Skas prs("\n"); 621219Skas exit(1); 631219Skas } 641219Skas 651219Skas /* 661219Skas * Catch stdio errors and report them more nicely. 671219Skas */ 681219Skas 691219Skas _error(str) 701219Skas char *str; 711219Skas { 721219Skas prs("Stdio Error: "); 731219Skas prs(str); 741219Skas prs("\n"); 751219Skas abort(); 761219Skas } 771219Skas 781219Skas /* 791219Skas * Print a string on diagnostic output. 801219Skas */ 811219Skas 821219Skas prs(str) 831219Skas char *str; 841219Skas { 851219Skas register char *s; 861219Skas 871219Skas for (s = str; *s; s++) 881219Skas ; 891219Skas write(2, str, s-str); 901219Skas } 911219Skas 921219Skas /* 931219Skas * Touch the named message by setting its MTOUCH flag. 941219Skas * Touched messages have the effect of not being sent 951219Skas * back to the system mailbox on exit. 961219Skas */ 971219Skas 981219Skas touch(mesg) 991219Skas { 1001479Skas register struct message *mp; 1011479Skas 1021479Skas if (mesg < 1 || mesg > msgCount) 1031479Skas return; 1041479Skas mp = &message[mesg-1]; 1051479Skas mp->m_flag |= MTOUCH; 1061479Skas if ((mp->m_flag & MREAD) == 0) 1071479Skas mp->m_flag |= MREAD|MSTATUS; 1081219Skas } 1091219Skas 1101219Skas /* 1111219Skas * Test to see if the passed file name is a directory. 1121219Skas * Return true if it is. 1131219Skas */ 1141219Skas 1151219Skas isdir(name) 1161219Skas char name[]; 1171219Skas { 1181219Skas struct stat sbuf; 1191219Skas 1201219Skas if (stat(name, &sbuf) < 0) 1211219Skas return(0); 1221219Skas return((sbuf.st_mode & S_IFMT) == S_IFDIR); 1231219Skas } 1241219Skas 1251219Skas /* 1261219Skas * Compute the size in characters of the passed message 1271219Skas */ 1281219Skas 1291219Skas unsigned int 1301219Skas msize(messp) 1311219Skas struct message *messp; 1321219Skas { 1331219Skas register struct message *mp; 1341219Skas 1351219Skas mp = messp; 1361219Skas return(mp->m_size); 1371219Skas } 1381219Skas 1391219Skas /* 1401219Skas * Count the number of arguments in the given string raw list. 1411219Skas */ 1421219Skas 1431219Skas argcount(argv) 1441219Skas char **argv; 1451219Skas { 1461219Skas register char **ap; 1471219Skas 1481219Skas for (ap = argv; *ap != NOSTR; ap++) 1491219Skas ; 1501219Skas return(ap-argv); 1511219Skas } 1521219Skas 1531219Skas /* 1541219Skas * Given a file address, determine the 1551219Skas * block number it represents. 1561219Skas */ 1571219Skas 1581219Skas blockof(off) 1591219Skas off_t off; 1601219Skas { 1611219Skas off_t a; 1621219Skas 1631219Skas a = off >> 9; 1641219Skas a &= 077777; 1651219Skas return((int) a); 1661219Skas } 1671219Skas 1681219Skas /* 1691219Skas * Take a file address, and determine 1701219Skas * its offset in the current block. 1711219Skas */ 1721219Skas 1731219Skas offsetof(off) 1741219Skas off_t off; 1751219Skas { 1761219Skas off_t a; 1771219Skas 1781219Skas a = off & 0777; 1791219Skas return((int) a); 1801219Skas } 1811219Skas 1821219Skas /* 1831219Skas * Determine if the passed file is actually a tty, via a call to 1841219Skas * gtty. This is not totally reliable, but . . . 1851219Skas */ 1861219Skas 1871219Skas isatty(f) 1881219Skas { 1891219Skas struct sgttyb buf; 1901219Skas 1911219Skas if (gtty(f, &buf) < 0) 1921219Skas return(0); 1931219Skas return(1); 1941219Skas } 1951219Skas 1961219Skas /* 1971219Skas * Return the desired header line from the passed message 1981219Skas * pointer (or NOSTR if the desired header field is not available). 1991219Skas */ 2001219Skas 2011219Skas char * 2021219Skas hfield(field, mp) 2031219Skas char field[]; 2041219Skas struct message *mp; 2051219Skas { 2061219Skas register FILE *ibuf; 2071219Skas char linebuf[LINESIZE]; 2081219Skas register int lc; 2091219Skas 2101219Skas ibuf = setinput(mp); 2111219Skas if ((lc = mp->m_lines) <= 0) 2121219Skas return(NOSTR); 2131219Skas if (readline(ibuf, linebuf) < 0) 2141219Skas return(NOSTR); 2151219Skas lc--; 2161219Skas do { 2171219Skas lc = gethfield(ibuf, linebuf, lc); 2181219Skas if (lc == -1) 2191219Skas return(NOSTR); 2201219Skas if (ishfield(linebuf, field)) 2211219Skas return(savestr(hcontents(linebuf))); 2221219Skas } while (lc > 0); 2231219Skas return(NOSTR); 2241219Skas } 2251219Skas 2261219Skas /* 2271219Skas * Return the next header field found in the given message. 2281219Skas * Return > 0 if something found, <= 0 elsewise. 2291219Skas * Must deal with \ continuations & other such fraud. 2301219Skas */ 2311219Skas 2321219Skas gethfield(f, linebuf, rem) 2331219Skas register FILE *f; 2341219Skas char linebuf[]; 2351219Skas register int rem; 2361219Skas { 2371219Skas char line2[LINESIZE]; 2381219Skas long loc; 2391219Skas register char *cp, *cp2; 2401219Skas register int c; 2411219Skas 2421219Skas 2431219Skas for (;;) { 2441219Skas if (rem <= 0) 2451219Skas return(-1); 2461219Skas if (readline(f, linebuf) < 0) 2471219Skas return(-1); 2481219Skas rem--; 2491219Skas if (strlen(linebuf) == 0) 2501219Skas return(-1); 2511219Skas if (isspace(linebuf[0])) 2521219Skas continue; 2531219Skas if (linebuf[0] == '>') 2541219Skas continue; 2551219Skas cp = index(linebuf, ':'); 2561219Skas if (cp == NOSTR) 2571219Skas continue; 2581219Skas for (cp2 = linebuf; cp2 < cp; cp2++) 2591219Skas if (isdigit(*cp2)) 2601219Skas continue; 2611219Skas 2621219Skas /* 2631219Skas * I guess we got a headline. 2641219Skas * Handle wraparounding 2651219Skas */ 2661219Skas 2671219Skas for (;;) { 2681219Skas if (rem <= 0) 2691219Skas break; 2701219Skas #ifdef CANTELL 2711219Skas loc = ftell(f); 2721219Skas if (readline(f, line2) < 0) 2731219Skas break; 2741219Skas rem--; 2751219Skas if (!isspace(line2[0])) { 2761219Skas fseek(f, loc, 0); 2771219Skas rem++; 2781219Skas break; 2791219Skas } 2801219Skas #else 2811219Skas c = getc(f); 2821219Skas ungetc(c, f); 2831219Skas if (!isspace(c) || c == '\n') 2841219Skas break; 2851219Skas if (readline(f, line2) < 0) 2861219Skas break; 2871219Skas rem--; 2881219Skas #endif 2891219Skas cp2 = line2; 2901219Skas for (cp2 = line2; *cp2 != 0 && isspace(*cp2); cp2++) 2911219Skas ; 2921219Skas if (strlen(linebuf) + strlen(cp2) >= LINESIZE-2) 2931219Skas break; 2941219Skas cp = &linebuf[strlen(linebuf)]; 2951219Skas while (cp > linebuf && 2961219Skas (isspace(cp[-1]) || cp[-1] == '\\')) 2971219Skas cp--; 2981219Skas *cp++ = ' '; 2991219Skas for (cp2 = line2; *cp2 != 0 && isspace(*cp2); cp2++) 3001219Skas ; 3011219Skas strcpy(cp, cp2); 3021219Skas } 3031219Skas if ((c = strlen(linebuf)) > 0) { 3041219Skas cp = &linebuf[c-1]; 3051219Skas while (cp > linebuf && isspace(*cp)) 3061219Skas cp--; 3071219Skas *++cp = 0; 3081219Skas } 3091219Skas return(rem); 3101219Skas } 3111219Skas /* NOTREACHED */ 3121219Skas } 3131219Skas 3141219Skas /* 3151219Skas * Check whether the passed line is a header line of 3161219Skas * the desired breed. 3171219Skas */ 3181219Skas 3191219Skas ishfield(linebuf, field) 3201219Skas char linebuf[], field[]; 3211219Skas { 3221219Skas register char *cp; 3231219Skas register int c; 3241219Skas 3251219Skas if ((cp = index(linebuf, ':')) == NOSTR) 3261219Skas return(0); 3271219Skas if (cp == linebuf) 3281219Skas return(0); 3291219Skas cp--; 3301219Skas while (cp > linebuf && isspace(*cp)) 3311219Skas cp--; 3321219Skas c = *++cp; 3331219Skas *cp = 0; 3341219Skas if (icequal(linebuf ,field)) { 3351219Skas *cp = c; 3361219Skas return(1); 3371219Skas } 3381219Skas *cp = c; 3391219Skas return(0); 3401219Skas } 3411219Skas 3421219Skas /* 3431219Skas * Extract the non label information from the given header field 3441219Skas * and return it. 3451219Skas */ 3461219Skas 3471219Skas char * 3481219Skas hcontents(hfield) 3491219Skas char hfield[]; 3501219Skas { 3511219Skas register char *cp; 3521219Skas 3531219Skas if ((cp = index(hfield, ':')) == NOSTR) 3541219Skas return(NOSTR); 3551219Skas cp++; 3561219Skas while (*cp && isspace(*cp)) 3571219Skas cp++; 3581219Skas return(cp); 3591219Skas } 3601219Skas 3611219Skas /* 3621219Skas * Compare two strings, ignoring case. 3631219Skas */ 3641219Skas 3651219Skas icequal(s1, s2) 3661219Skas register char *s1, *s2; 3671219Skas { 3681219Skas 3691219Skas while (raise(*s1++) == raise(*s2)) 3701219Skas if (*s2++ == 0) 3711219Skas return(1); 3721219Skas return(0); 3731219Skas } 3741219Skas 3751219Skas /* 376*7571Skurt * Copy a string, lowercasing it as we go. 377*7571Skurt */ 378*7571Skurt istrcpy(dest, src) 379*7571Skurt char *dest, *src; 380*7571Skurt { 381*7571Skurt register char *cp, *cp2; 382*7571Skurt 383*7571Skurt cp2 = dest; 384*7571Skurt cp = src; 385*7571Skurt do { 386*7571Skurt *cp2++ = little(*cp); 387*7571Skurt } while (*cp++ != 0); 388*7571Skurt } 389*7571Skurt 390*7571Skurt /* 3911219Skas * The following code deals with input stacking to do source 3921219Skas * commands. All but the current file pointer are saved on 3931219Skas * the stack. 3941219Skas */ 3951219Skas 3961219Skas static int ssp = -1; /* Top of file stack */ 3971519Skas struct sstack { 3981519Skas FILE *s_file; /* File we were in. */ 3991519Skas int s_cond; /* Saved state of conditionals */ 4005785Skurt int s_loading; /* Loading .mailrc, etc. */ 4011519Skas } sstack[_NFILE]; 4021219Skas 4031219Skas /* 4041219Skas * Pushdown current input file and switch to a new one. 4051219Skas * Set the global flag "sourcing" so that others will realize 4061219Skas * that they are no longer reading from a tty (in all probability). 4071219Skas */ 4081219Skas 4091219Skas source(name) 4101219Skas char name[]; 4111219Skas { 4121219Skas register FILE *fi; 4133914Skurt register char *cp; 4141219Skas 4153914Skurt if ((cp = expand(name)) == NOSTR) 4161219Skas return(1); 4173914Skurt if ((fi = fopen(cp, "r")) == NULL) { 4183914Skurt perror(cp); 4193914Skurt return(1); 4201219Skas } 4211219Skas if (ssp >= _NFILE-2) { 4221219Skas printf("Too much \"sourcing\" going on.\n"); 4231219Skas fclose(fi); 4241219Skas return(1); 4251219Skas } 4261519Skas sstack[++ssp].s_file = input; 4271519Skas sstack[ssp].s_cond = cond; 4285785Skurt sstack[ssp].s_loading = loading; 4295785Skurt loading = 0; 4301519Skas cond = CANY; 4311219Skas input = fi; 4321219Skas sourcing++; 4331219Skas return(0); 4341219Skas } 4351219Skas 4361219Skas /* 4371219Skas * Source a file, but do nothing if the file cannot be opened. 4381219Skas */ 4391219Skas 4401219Skas source1(name) 4411219Skas char name[]; 4421219Skas { 4431219Skas register int f; 4441219Skas 4451219Skas if ((f = open(name, 0)) < 0) 4461219Skas return(0); 4471219Skas close(f); 4481219Skas source(name); 4491219Skas } 4501219Skas 4511219Skas /* 4521219Skas * Pop the current input back to the previous level. 4531219Skas * Update the "sourcing" flag as appropriate. 4541219Skas */ 4551219Skas 4561219Skas unstack() 4571219Skas { 4581219Skas if (ssp < 0) { 4591219Skas printf("\"Source\" stack over-pop.\n"); 4601219Skas sourcing = 0; 4611219Skas return(1); 4621219Skas } 4631219Skas fclose(input); 4641519Skas if (cond != CANY) 4651519Skas printf("Unmatched \"if\"\n"); 4661519Skas cond = sstack[ssp].s_cond; 4675785Skurt loading = sstack[ssp].s_loading; 4681519Skas input = sstack[ssp--].s_file; 4691219Skas if (ssp < 0) 4705785Skurt sourcing = loading; 4711219Skas return(0); 4721219Skas } 4731219Skas 4741219Skas /* 4751219Skas * Touch the indicated file. 4761219Skas * This is nifty for the shell. 4771219Skas * If we have the utime() system call, this is better served 4781219Skas * by using that, since it will work for empty files. 4791219Skas * On non-utime systems, we must sleep a second, then read. 4801219Skas */ 4811219Skas 4821219Skas alter(name) 4831219Skas char name[]; 4841219Skas { 4851219Skas #ifdef UTIME 4861219Skas struct stat statb; 4871219Skas long time(); 4881219Skas time_t time_p[2]; 4891219Skas #else 4901219Skas register int pid, f; 4911219Skas char w; 4921219Skas #endif UTIME 4931219Skas 4941219Skas #ifdef UTIME 4951219Skas if (stat(name, &statb) < 0) 4961219Skas return; 4971219Skas time_p[0] = time((long *) 0) + 1; 4981219Skas time_p[1] = statb.st_mtime; 4991219Skas utime(name, time_p); 5001219Skas #else 5011219Skas sleep(1); 5021219Skas if ((f = open(name, 0)) < 0) 5034389Skurt return; 5041219Skas read(f, &w, 1); 5051219Skas exit(0); 5061219Skas #endif 5071219Skas } 5081219Skas 5091219Skas /* 5101219Skas * Examine the passed line buffer and 5111219Skas * return true if it is all blanks and tabs. 5121219Skas */ 5131219Skas 5141219Skas blankline(linebuf) 5151219Skas char linebuf[]; 5161219Skas { 5171219Skas register char *cp; 5181219Skas 5191219Skas for (cp = linebuf; *cp; cp++) 5201219Skas if (!any(*cp, " \t")) 5211219Skas return(0); 5221219Skas return(1); 5231219Skas } 5241219Skas 5251219Skas /* 5263195Skas * Get sender's name from this message. If the message has 5273195Skas * a bunch of arpanet stuff in it, we may have to skin the name 5283195Skas * before returning it. 5293195Skas */ 5303195Skas char * 5313195Skas nameof(mp, reptype) 5323195Skas register struct message *mp; 5333195Skas { 5345237Skurt register char *cp, *cp2; 5353195Skas 5365237Skurt cp = skin(name1(mp, reptype)); 5375237Skurt if (reptype != 0 || charcount(cp, '!') < 2) 5385237Skurt return(cp); 5395237Skurt cp2 = rindex(cp, '!'); 5405237Skurt cp2--; 5415237Skurt while (cp2 > cp && *cp2 != '!') 5425237Skurt cp2--; 5435237Skurt if (*cp2 == '!') 5445237Skurt return(cp2 + 1); 5455237Skurt return(cp); 5463195Skas } 5473195Skas 5483195Skas /* 5493195Skas * Skin an arpa net address according to the RFC 733 interpretation 5503195Skas * of "host-phrase." 5513195Skas */ 5523195Skas char * 5533195Skas skin(name) 5543195Skas char *name; 5553195Skas { 5563195Skas register int c; 5573195Skas register char *cp, *cp2; 5583195Skas int gotlt, lastsp; 5593195Skas char nbuf[BUFSIZ]; 5603195Skas 5613195Skas if (name == NOSTR) 5623195Skas return(NOSTR); 5633195Skas if (index(name, '(') == NOSTR && index(name, '<') == NOSTR) 5643195Skas return(name); 5653195Skas gotlt = 0; 5663195Skas lastsp = 0; 5673195Skas for (cp = name, cp2 = nbuf, c = *cp++; *cp; c = *cp++) { 5683195Skas switch (c) { 5693195Skas case '(': 5703195Skas while (*cp != ')' && *cp != 0) 5713195Skas cp++; 5723195Skas if (*cp) 5733195Skas cp++; 5743195Skas break; 5753195Skas 5763195Skas case ' ': 5773195Skas lastsp = 1; 5783195Skas break; 5793195Skas 5803195Skas case '<': 5813195Skas cp2 = nbuf; 5823195Skas gotlt++; 5833195Skas lastsp = 0; 5843195Skas break; 5853195Skas 5863195Skas case '>': 5873195Skas if (gotlt) 5883195Skas goto done; 5893195Skas 5903195Skas /* Fall into . . . */ 5913195Skas 5923195Skas default: 5933195Skas if (lastsp) { 5943195Skas lastsp = 0; 5953195Skas *cp2++ = ' '; 5963195Skas } 5973195Skas *cp2++ = c; 5983195Skas break; 5993195Skas } 6003195Skas } 6013195Skas done: 6023195Skas *cp2 = 0; 6033195Skas 6043195Skas return(savestr(nbuf)); 6053195Skas } 6063195Skas 6073195Skas /* 6081219Skas * Fetch the sender's name from the passed message. 6093195Skas * Reptype can be 6103195Skas * 0 -- get sender's name for display purposes 6113195Skas * 1 -- get sender's name for reply 6123195Skas * 2 -- get sender's name for Reply 6131219Skas */ 6141219Skas 6151219Skas char * 6163195Skas name1(mp, reptype) 6171219Skas register struct message *mp; 6181219Skas { 6191219Skas char namebuf[LINESIZE]; 6201219Skas char linebuf[LINESIZE]; 6211219Skas register char *cp, *cp2; 6221219Skas register FILE *ibuf; 6231219Skas int first = 1; 6241219Skas 6253195Skas #ifndef DELIVERMAIL 6263195Skas if ((cp = hfield("from", mp)) != NOSTR) 6273195Skas return(cp); 6283195Skas if (reptype == 0 && (cp = hfield("sender", mp)) != NOSTR) 6293195Skas return(cp); 6303195Skas #endif 6311219Skas ibuf = setinput(mp); 6321219Skas copy("", namebuf); 6331219Skas if (readline(ibuf, linebuf) <= 0) 6341219Skas return(savestr(namebuf)); 6351219Skas newname: 6361219Skas for (cp = linebuf; *cp != ' '; cp++) 6371219Skas ; 6381219Skas while (any(*cp, " \t")) 6391219Skas cp++; 6401219Skas for (cp2 = &namebuf[strlen(namebuf)]; *cp && !any(*cp, " \t") && 6411219Skas cp2-namebuf < LINESIZE-1; *cp2++ = *cp++) 6421219Skas ; 6431219Skas *cp2 = '\0'; 6441219Skas if (readline(ibuf, linebuf) <= 0) 6451219Skas return(savestr(namebuf)); 6461219Skas if ((cp = index(linebuf, 'F')) == NULL) 6471219Skas return(savestr(namebuf)); 6481219Skas if (strncmp(cp, "From", 4) != 0) 6491219Skas return(savestr(namebuf)); 6501219Skas while ((cp = index(cp, 'r')) != NULL) { 6511219Skas if (strncmp(cp, "remote", 6) == 0) { 6521219Skas if ((cp = index(cp, 'f')) == NULL) 6531219Skas break; 6541219Skas if (strncmp(cp, "from", 4) != 0) 6551219Skas break; 6561219Skas if ((cp = index(cp, ' ')) == NULL) 6571219Skas break; 6581219Skas cp++; 6591219Skas if (first) { 6601219Skas copy(cp, namebuf); 6611219Skas first = 0; 6621219Skas } else 6631219Skas strcpy(rindex(namebuf, '!')+1, cp); 6641219Skas strcat(namebuf, "!"); 6651219Skas goto newname; 6661219Skas } 6671219Skas cp++; 6681219Skas } 6691219Skas return(savestr(namebuf)); 6701219Skas } 6711219Skas 6721219Skas /* 6735237Skurt * Count the occurances of c in str 6745237Skurt */ 6755237Skurt charcount(str, c) 6765237Skurt char *str; 6775237Skurt { 6785237Skurt register char *cp; 6795237Skurt register int i; 6805237Skurt 6815237Skurt for (i = 0, cp = str; *cp; cp++) 6825237Skurt if (*cp == c) 6835237Skurt i++; 6845237Skurt return(i); 6855237Skurt } 6865237Skurt 6875237Skurt /* 6881219Skas * Find the rightmost pointer to an instance of the 6891219Skas * character in the string and return it. 6901219Skas */ 6911219Skas char * 6921219Skas rindex(str, c) 6931219Skas char str[]; 6941219Skas register int c; 6951219Skas { 6961219Skas register char *cp, *cp2; 6971219Skas 6981219Skas for (cp = str, cp2 = NOSTR; *cp; cp++) 6991219Skas if (c == *cp) 7001219Skas cp2 = cp; 7011219Skas return(cp2); 7021219Skas } 7031219Skas 7041219Skas /* 7051219Skas * See if the string is a number. 7061219Skas */ 7071219Skas 7081219Skas numeric(str) 7091219Skas char str[]; 7101219Skas { 7111219Skas register char *cp = str; 7121219Skas 7131219Skas while (*cp) 7141219Skas if (!isdigit(*cp++)) 7151219Skas return(0); 7161219Skas return(1); 7171219Skas } 7181219Skas 7191219Skas /* 7201219Skas * Are any of the characters in the two strings the same? 7211219Skas */ 7221219Skas 7231219Skas anyof(s1, s2) 7241219Skas register char *s1, *s2; 7251219Skas { 7261219Skas register int c; 7271219Skas 7281219Skas while (c = *s1++) 7291219Skas if (any(c, s2)) 7301219Skas return(1); 7311219Skas return(0); 7321219Skas } 7331219Skas 7341219Skas /* 7351219Skas * Determine the leftmost index of the character 7361219Skas * in the string. 7371219Skas */ 7381219Skas 7391219Skas char * 7401219Skas index(str, ch) 7411219Skas char *str; 7421219Skas { 7431219Skas register char *cp; 7441219Skas register int c; 7451219Skas 7461219Skas for (c = ch, cp = str; *cp; cp++) 7471219Skas if (*cp == c) 7481219Skas return(cp); 7491219Skas return(NOSTR); 7501219Skas } 7511219Skas 7521219Skas /* 7531219Skas * String compare two strings of bounded length. 7541219Skas */ 7551219Skas 7561219Skas strncmp(as1, as2, an) 7571219Skas char *as1, *as2; 7581219Skas { 7591219Skas register char *s1, *s2; 7601219Skas register int n; 7611219Skas 7621219Skas s1 = as1; 7631219Skas s2 = as2; 7641219Skas n = an; 7651219Skas while (--n >= 0 && *s1 == *s2++) 7661219Skas if (*s1++ == '\0') 7671219Skas return(0); 7681219Skas return(n<0 ? 0 : *s1 - *--s2); 7691219Skas } 7701219Skas 7717538Skurt #ifndef SIGRETRO 7727538Skurt 7737538Skurt /* 7747538Skurt * This routine is used by the sigretro package to 7757538Skurt * reset held signals to ignored signals. If you're not 7767538Skurt * using sigretro, you don't need to do anything, but you DO 7777538Skurt * need this stub to keep everyone happy. 7787538Skurt */ 7797538Skurt sigchild() {} 7807538Skurt 7817538Skurt #endif SIGRETRO 782*7571Skurt 783*7571Skurt /* 784*7571Skurt * See if the given header field is supposed to be ignored. 785*7571Skurt */ 786*7571Skurt isign(field) 787*7571Skurt char *field; 788*7571Skurt { 789*7571Skurt char realfld[BUFSIZ]; 790*7571Skurt register int h; 791*7571Skurt register struct ignore *igp; 792*7571Skurt 793*7571Skurt istrcpy(realfld, field); 794*7571Skurt h = hash(realfld); 795*7571Skurt for (igp = ignore[h]; igp != 0; igp = igp->i_link) 796*7571Skurt if (strcmp(igp->i_field, realfld) == 0) 797*7571Skurt return(1); 798*7571Skurt return(0); 799*7571Skurt } 800