1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* 27*7c478bd9Sstevel@tonic-gate * Copyright 1985-2002 Sun Microsystems, Inc. All rights reserved. 28*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate /* 32*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 33*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 34*7c478bd9Sstevel@tonic-gate * All Rights Reserved 35*7c478bd9Sstevel@tonic-gate * 36*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 37*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 38*7c478bd9Sstevel@tonic-gate * contributors. 39*7c478bd9Sstevel@tonic-gate */ 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate #include "rcv.h" 44*7c478bd9Sstevel@tonic-gate #include <locale.h> 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate /* 47*7c478bd9Sstevel@tonic-gate * mailx -- a modified version of a University of California at Berkeley 48*7c478bd9Sstevel@tonic-gate * mail program 49*7c478bd9Sstevel@tonic-gate * 50*7c478bd9Sstevel@tonic-gate * Auxiliary functions. 51*7c478bd9Sstevel@tonic-gate */ 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate static char *phrase(char *name, int token, int comma); 54*7c478bd9Sstevel@tonic-gate static char *ripoff(register char *buf); 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* 57*7c478bd9Sstevel@tonic-gate * Return a pointer to a dynamic copy of the argument. 58*7c478bd9Sstevel@tonic-gate */ 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate char * 61*7c478bd9Sstevel@tonic-gate savestr(char *str) 62*7c478bd9Sstevel@tonic-gate { 63*7c478bd9Sstevel@tonic-gate register char *cp, *cp2, *top; 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate for (cp = str; *cp; cp++) 66*7c478bd9Sstevel@tonic-gate ; 67*7c478bd9Sstevel@tonic-gate top = (char *)salloc((unsigned)(cp-str + 1)); 68*7c478bd9Sstevel@tonic-gate if (top == NOSTR) 69*7c478bd9Sstevel@tonic-gate return(NOSTR); 70*7c478bd9Sstevel@tonic-gate for (cp = str, cp2 = top; *cp; cp++) 71*7c478bd9Sstevel@tonic-gate *cp2++ = *cp; 72*7c478bd9Sstevel@tonic-gate *cp2 = 0; 73*7c478bd9Sstevel@tonic-gate return(top); 74*7c478bd9Sstevel@tonic-gate } 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate /* 77*7c478bd9Sstevel@tonic-gate * Announce a fatal error and die. 78*7c478bd9Sstevel@tonic-gate */ 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate void 81*7c478bd9Sstevel@tonic-gate panic(char *str) 82*7c478bd9Sstevel@tonic-gate { 83*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("mailx: Panic - %s\n"), str); 84*7c478bd9Sstevel@tonic-gate exit(1); 85*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 86*7c478bd9Sstevel@tonic-gate } 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate /* 89*7c478bd9Sstevel@tonic-gate * Touch the named message by setting its MTOUCH flag. 90*7c478bd9Sstevel@tonic-gate * Touched messages have the effect of not being sent 91*7c478bd9Sstevel@tonic-gate * back to the system mailbox on exit. 92*7c478bd9Sstevel@tonic-gate */ 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate void 95*7c478bd9Sstevel@tonic-gate touch(int mesg) 96*7c478bd9Sstevel@tonic-gate { 97*7c478bd9Sstevel@tonic-gate register struct message *mp; 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate if (mesg < 1 || mesg > msgCount) 100*7c478bd9Sstevel@tonic-gate return; 101*7c478bd9Sstevel@tonic-gate mp = &message[mesg-1]; 102*7c478bd9Sstevel@tonic-gate mp->m_flag |= MTOUCH; 103*7c478bd9Sstevel@tonic-gate if ((mp->m_flag & MREAD) == 0) 104*7c478bd9Sstevel@tonic-gate mp->m_flag |= MREAD|MSTATUS; 105*7c478bd9Sstevel@tonic-gate } 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate /* 108*7c478bd9Sstevel@tonic-gate * Test to see if the passed file name is a directory. 109*7c478bd9Sstevel@tonic-gate * Return true if it is. 110*7c478bd9Sstevel@tonic-gate */ 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate int 113*7c478bd9Sstevel@tonic-gate isdir(char name[]) 114*7c478bd9Sstevel@tonic-gate { 115*7c478bd9Sstevel@tonic-gate struct stat sbuf; 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate if (stat(name, &sbuf) < 0) 118*7c478bd9Sstevel@tonic-gate return(0); 119*7c478bd9Sstevel@tonic-gate return((sbuf.st_mode & S_IFMT) == S_IFDIR); 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate /* 123*7c478bd9Sstevel@tonic-gate * Count the number of arguments in the given string raw list. 124*7c478bd9Sstevel@tonic-gate */ 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate int 127*7c478bd9Sstevel@tonic-gate argcount(char **argv) 128*7c478bd9Sstevel@tonic-gate { 129*7c478bd9Sstevel@tonic-gate register char **ap; 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate for (ap = argv; *ap != NOSTR; ap++) 132*7c478bd9Sstevel@tonic-gate ; 133*7c478bd9Sstevel@tonic-gate return(ap-argv); 134*7c478bd9Sstevel@tonic-gate } 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate /* 137*7c478bd9Sstevel@tonic-gate * Return the desired header line from the passed message 138*7c478bd9Sstevel@tonic-gate * pointer (or NOSTR if the desired header field is not available). 139*7c478bd9Sstevel@tonic-gate * Read all the header lines and concatenate multiple instances of 140*7c478bd9Sstevel@tonic-gate * the requested header. 141*7c478bd9Sstevel@tonic-gate */ 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate char * 144*7c478bd9Sstevel@tonic-gate hfield(char field[], struct message *mp, char *(*add)(char *, char *)) 145*7c478bd9Sstevel@tonic-gate { 146*7c478bd9Sstevel@tonic-gate register FILE *ibuf; 147*7c478bd9Sstevel@tonic-gate char linebuf[LINESIZE]; 148*7c478bd9Sstevel@tonic-gate register long lc; 149*7c478bd9Sstevel@tonic-gate char *r = NOSTR; 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate ibuf = setinput(mp); 152*7c478bd9Sstevel@tonic-gate if ((lc = mp->m_lines) <= 0) 153*7c478bd9Sstevel@tonic-gate return(NOSTR); 154*7c478bd9Sstevel@tonic-gate if (readline(ibuf, linebuf) < 0) 155*7c478bd9Sstevel@tonic-gate return(NOSTR); 156*7c478bd9Sstevel@tonic-gate lc--; 157*7c478bd9Sstevel@tonic-gate while ((lc = gethfield(ibuf, linebuf, lc)) >= 0) 158*7c478bd9Sstevel@tonic-gate if (ishfield(linebuf, field)) 159*7c478bd9Sstevel@tonic-gate r = (*add)(r, hcontents(linebuf)); 160*7c478bd9Sstevel@tonic-gate return r; 161*7c478bd9Sstevel@tonic-gate } 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate /* 164*7c478bd9Sstevel@tonic-gate * Return the next header field found in the given message. 165*7c478bd9Sstevel@tonic-gate * Return > 0 if something found, <= 0 elsewise. 166*7c478bd9Sstevel@tonic-gate * Must deal with \ continuations & other such fraud. 167*7c478bd9Sstevel@tonic-gate */ 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate int 170*7c478bd9Sstevel@tonic-gate gethfield( 171*7c478bd9Sstevel@tonic-gate register FILE *f, 172*7c478bd9Sstevel@tonic-gate char linebuf[], 173*7c478bd9Sstevel@tonic-gate register long rem) 174*7c478bd9Sstevel@tonic-gate { 175*7c478bd9Sstevel@tonic-gate char line2[LINESIZE]; 176*7c478bd9Sstevel@tonic-gate register char *cp, *cp2; 177*7c478bd9Sstevel@tonic-gate register int c; 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate for (;;) { 180*7c478bd9Sstevel@tonic-gate if (rem <= 0) 181*7c478bd9Sstevel@tonic-gate return(-1); 182*7c478bd9Sstevel@tonic-gate if (readline(f, linebuf) < 0) 183*7c478bd9Sstevel@tonic-gate return(-1); 184*7c478bd9Sstevel@tonic-gate rem--; 185*7c478bd9Sstevel@tonic-gate if (strlen(linebuf) == 0) 186*7c478bd9Sstevel@tonic-gate return(-1); 187*7c478bd9Sstevel@tonic-gate if (isspace(linebuf[0])) 188*7c478bd9Sstevel@tonic-gate continue; 189*7c478bd9Sstevel@tonic-gate if (!headerp(linebuf)) 190*7c478bd9Sstevel@tonic-gate return(-1); 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate /* 193*7c478bd9Sstevel@tonic-gate * I guess we got a headline. 194*7c478bd9Sstevel@tonic-gate * Handle wraparounding 195*7c478bd9Sstevel@tonic-gate */ 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate for (;;) { 198*7c478bd9Sstevel@tonic-gate if (rem <= 0) 199*7c478bd9Sstevel@tonic-gate break; 200*7c478bd9Sstevel@tonic-gate c = getc(f); 201*7c478bd9Sstevel@tonic-gate ungetc(c, f); 202*7c478bd9Sstevel@tonic-gate if (!isspace(c) || c == '\n') 203*7c478bd9Sstevel@tonic-gate break; 204*7c478bd9Sstevel@tonic-gate if (readline(f, line2) < 0) 205*7c478bd9Sstevel@tonic-gate break; 206*7c478bd9Sstevel@tonic-gate rem--; 207*7c478bd9Sstevel@tonic-gate cp2 = line2; 208*7c478bd9Sstevel@tonic-gate for (cp2 = line2; *cp2 != 0 && isspace(*cp2); cp2++) 209*7c478bd9Sstevel@tonic-gate ; 210*7c478bd9Sstevel@tonic-gate if (strlen(linebuf) + strlen(cp2) >= 211*7c478bd9Sstevel@tonic-gate (unsigned)LINESIZE-2) 212*7c478bd9Sstevel@tonic-gate break; 213*7c478bd9Sstevel@tonic-gate cp = &linebuf[strlen(linebuf)]; 214*7c478bd9Sstevel@tonic-gate while (cp > linebuf && 215*7c478bd9Sstevel@tonic-gate (isspace(cp[-1]) || cp[-1] == '\\')) 216*7c478bd9Sstevel@tonic-gate cp--; 217*7c478bd9Sstevel@tonic-gate *cp++ = ' '; 218*7c478bd9Sstevel@tonic-gate for (cp2 = line2; *cp2 != 0 && isspace(*cp2); cp2++) 219*7c478bd9Sstevel@tonic-gate ; 220*7c478bd9Sstevel@tonic-gate nstrcpy(cp, LINESIZE - (cp - linebuf), cp2); 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate if ((c = strlen(linebuf)) > 0) { 223*7c478bd9Sstevel@tonic-gate cp = &linebuf[c-1]; 224*7c478bd9Sstevel@tonic-gate while (cp > linebuf && isspace(*cp)) 225*7c478bd9Sstevel@tonic-gate cp--; 226*7c478bd9Sstevel@tonic-gate *++cp = 0; 227*7c478bd9Sstevel@tonic-gate } 228*7c478bd9Sstevel@tonic-gate return(rem); 229*7c478bd9Sstevel@tonic-gate } 230*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 231*7c478bd9Sstevel@tonic-gate } 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate /* 234*7c478bd9Sstevel@tonic-gate * Check whether the passed line is a header line of 235*7c478bd9Sstevel@tonic-gate * the desired breed. 236*7c478bd9Sstevel@tonic-gate */ 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate int 239*7c478bd9Sstevel@tonic-gate ishfield(char linebuf[], char field[]) 240*7c478bd9Sstevel@tonic-gate { 241*7c478bd9Sstevel@tonic-gate register char *cp; 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate if ((cp = strchr(linebuf, ':')) == NOSTR) 244*7c478bd9Sstevel@tonic-gate return(0); 245*7c478bd9Sstevel@tonic-gate if (cp == linebuf) 246*7c478bd9Sstevel@tonic-gate return(0); 247*7c478bd9Sstevel@tonic-gate *cp = 0; 248*7c478bd9Sstevel@tonic-gate if (icequal(linebuf, field)) { 249*7c478bd9Sstevel@tonic-gate *cp = ':'; 250*7c478bd9Sstevel@tonic-gate return(1); 251*7c478bd9Sstevel@tonic-gate } 252*7c478bd9Sstevel@tonic-gate *cp = ':'; 253*7c478bd9Sstevel@tonic-gate return(0); 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate /* 257*7c478bd9Sstevel@tonic-gate * Extract the non label information from the given header field 258*7c478bd9Sstevel@tonic-gate * and return it. 259*7c478bd9Sstevel@tonic-gate */ 260*7c478bd9Sstevel@tonic-gate 261*7c478bd9Sstevel@tonic-gate char * 262*7c478bd9Sstevel@tonic-gate hcontents(char hfield[]) 263*7c478bd9Sstevel@tonic-gate { 264*7c478bd9Sstevel@tonic-gate register char *cp; 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate if ((cp = strchr(hfield, ':')) == NOSTR) 267*7c478bd9Sstevel@tonic-gate return(NOSTR); 268*7c478bd9Sstevel@tonic-gate cp++; 269*7c478bd9Sstevel@tonic-gate while (*cp && isspace(*cp)) 270*7c478bd9Sstevel@tonic-gate cp++; 271*7c478bd9Sstevel@tonic-gate return(cp); 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate /* 275*7c478bd9Sstevel@tonic-gate * Compare two strings, ignoring case. 276*7c478bd9Sstevel@tonic-gate */ 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate int 279*7c478bd9Sstevel@tonic-gate icequal(register char *s1, register char *s2) 280*7c478bd9Sstevel@tonic-gate { 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate while (toupper(*s1++) == toupper(*s2)) 283*7c478bd9Sstevel@tonic-gate if (*s2++ == 0) 284*7c478bd9Sstevel@tonic-gate return(1); 285*7c478bd9Sstevel@tonic-gate return(0); 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate /* 289*7c478bd9Sstevel@tonic-gate * Copy a string, lowercasing it as we go. Here dstsize is the size of 290*7c478bd9Sstevel@tonic-gate * the destination buffer dst. 291*7c478bd9Sstevel@tonic-gate */ 292*7c478bd9Sstevel@tonic-gate void 293*7c478bd9Sstevel@tonic-gate istrcpy(char *dst, int dstsize, char *src) 294*7c478bd9Sstevel@tonic-gate { 295*7c478bd9Sstevel@tonic-gate register char *cp, *cp2; 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate cp2 = dst; 298*7c478bd9Sstevel@tonic-gate cp = src; 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate while (--dstsize > 0 && *cp != '\0') 301*7c478bd9Sstevel@tonic-gate *cp2++ = tolower(*cp++); 302*7c478bd9Sstevel@tonic-gate *cp2 = '\0'; 303*7c478bd9Sstevel@tonic-gate } 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate /* 306*7c478bd9Sstevel@tonic-gate * The following code deals with input stacking to do source 307*7c478bd9Sstevel@tonic-gate * commands. All but the current file pointer are saved on 308*7c478bd9Sstevel@tonic-gate * the stack. 309*7c478bd9Sstevel@tonic-gate */ 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate static int ssp = -1; /* Top of file stack */ 312*7c478bd9Sstevel@tonic-gate static struct sstack { 313*7c478bd9Sstevel@tonic-gate FILE *s_file; /* File we were in. */ 314*7c478bd9Sstevel@tonic-gate int s_cond; /* Saved state of conditionals */ 315*7c478bd9Sstevel@tonic-gate int s_loading; /* Loading .mailrc, etc. */ 316*7c478bd9Sstevel@tonic-gate } *sstack; 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate /* 319*7c478bd9Sstevel@tonic-gate * Pushdown current input file and switch to a new one. 320*7c478bd9Sstevel@tonic-gate * Set the global flag "sourcing" so that others will realize 321*7c478bd9Sstevel@tonic-gate * that they are no longer reading from a tty (in all probability). 322*7c478bd9Sstevel@tonic-gate */ 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate int 325*7c478bd9Sstevel@tonic-gate source(char name[]) 326*7c478bd9Sstevel@tonic-gate { 327*7c478bd9Sstevel@tonic-gate register FILE *fi; 328*7c478bd9Sstevel@tonic-gate register char *cp; 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate if ((cp = expand(name)) == NOSTR) 331*7c478bd9Sstevel@tonic-gate return(1); 332*7c478bd9Sstevel@tonic-gate if ((fi = fopen(cp, "r")) == NULL) { 333*7c478bd9Sstevel@tonic-gate printf(gettext("Unable to open %s\n"), cp); 334*7c478bd9Sstevel@tonic-gate return(1); 335*7c478bd9Sstevel@tonic-gate } 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate if (!maxfiles) { 338*7c478bd9Sstevel@tonic-gate if ((maxfiles = (int)ulimit(4, 0)) < 0) 339*7c478bd9Sstevel@tonic-gate #ifndef _NFILE 340*7c478bd9Sstevel@tonic-gate # define _NFILE 20 341*7c478bd9Sstevel@tonic-gate #endif 342*7c478bd9Sstevel@tonic-gate maxfiles = _NFILE; 343*7c478bd9Sstevel@tonic-gate sstack = (struct sstack *)calloc(maxfiles, sizeof(struct sstack)); 344*7c478bd9Sstevel@tonic-gate if (sstack == NULL) { 345*7c478bd9Sstevel@tonic-gate printf(gettext( 346*7c478bd9Sstevel@tonic-gate "Couldn't allocate memory for sourcing stack\n")); 347*7c478bd9Sstevel@tonic-gate fclose(fi); 348*7c478bd9Sstevel@tonic-gate return(1); 349*7c478bd9Sstevel@tonic-gate } 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate sstack[++ssp].s_file = input; 353*7c478bd9Sstevel@tonic-gate sstack[ssp].s_cond = cond; 354*7c478bd9Sstevel@tonic-gate sstack[ssp].s_loading = loading; 355*7c478bd9Sstevel@tonic-gate loading = 0; 356*7c478bd9Sstevel@tonic-gate cond = CANY; 357*7c478bd9Sstevel@tonic-gate input = fi; 358*7c478bd9Sstevel@tonic-gate sourcing++; 359*7c478bd9Sstevel@tonic-gate return(0); 360*7c478bd9Sstevel@tonic-gate } 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate /* 363*7c478bd9Sstevel@tonic-gate * Pop the current input back to the previous level. 364*7c478bd9Sstevel@tonic-gate * Update the "sourcing" flag as appropriate. 365*7c478bd9Sstevel@tonic-gate */ 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate int 368*7c478bd9Sstevel@tonic-gate unstack(void) 369*7c478bd9Sstevel@tonic-gate { 370*7c478bd9Sstevel@tonic-gate if (ssp < 0) { 371*7c478bd9Sstevel@tonic-gate printf(gettext("\"Source\" stack over-pop.\n")); 372*7c478bd9Sstevel@tonic-gate sourcing = 0; 373*7c478bd9Sstevel@tonic-gate return(1); 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate fclose(input); 376*7c478bd9Sstevel@tonic-gate if (cond != CANY) 377*7c478bd9Sstevel@tonic-gate printf(gettext("Unmatched \"if\"\n")); 378*7c478bd9Sstevel@tonic-gate cond = sstack[ssp].s_cond; 379*7c478bd9Sstevel@tonic-gate loading = sstack[ssp].s_loading; 380*7c478bd9Sstevel@tonic-gate input = sstack[ssp--].s_file; 381*7c478bd9Sstevel@tonic-gate if (ssp < 0) 382*7c478bd9Sstevel@tonic-gate sourcing = loading; 383*7c478bd9Sstevel@tonic-gate return(0); 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate /* 387*7c478bd9Sstevel@tonic-gate * Touch the indicated file. 388*7c478bd9Sstevel@tonic-gate * This is nifty for the shell. 389*7c478bd9Sstevel@tonic-gate * If we have the utime() system call, this is better served 390*7c478bd9Sstevel@tonic-gate * by using that, since it will work for empty files. 391*7c478bd9Sstevel@tonic-gate * On non-utime systems, we must sleep a second, then read. 392*7c478bd9Sstevel@tonic-gate */ 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate void 395*7c478bd9Sstevel@tonic-gate alter(char name[]) 396*7c478bd9Sstevel@tonic-gate { 397*7c478bd9Sstevel@tonic-gate int rc = utime(name, utimep); 398*7c478bd9Sstevel@tonic-gate extern int errno; 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate if (rc != 0) { 401*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Cannot utime %s in aux:alter\n"), 402*7c478bd9Sstevel@tonic-gate name); 403*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Errno: %d\n"), errno); 404*7c478bd9Sstevel@tonic-gate } 405*7c478bd9Sstevel@tonic-gate } 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate /* 408*7c478bd9Sstevel@tonic-gate * Examine the passed line buffer and 409*7c478bd9Sstevel@tonic-gate * return true if it is all blanks and tabs. 410*7c478bd9Sstevel@tonic-gate */ 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate int 413*7c478bd9Sstevel@tonic-gate blankline(const char linebuf[]) 414*7c478bd9Sstevel@tonic-gate { 415*7c478bd9Sstevel@tonic-gate register const char *cp; 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate for (cp = linebuf; *cp; cp++) 418*7c478bd9Sstevel@tonic-gate if (!any(*cp, " \t")) 419*7c478bd9Sstevel@tonic-gate return(0); 420*7c478bd9Sstevel@tonic-gate return(1); 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate /* 424*7c478bd9Sstevel@tonic-gate * Skin an arpa net address according to the RFC 822 interpretation 425*7c478bd9Sstevel@tonic-gate * of "host-phrase." 426*7c478bd9Sstevel@tonic-gate */ 427*7c478bd9Sstevel@tonic-gate static char * 428*7c478bd9Sstevel@tonic-gate phrase(char *name, int token, int comma) 429*7c478bd9Sstevel@tonic-gate { 430*7c478bd9Sstevel@tonic-gate register char c; 431*7c478bd9Sstevel@tonic-gate register char *cp, *cp2; 432*7c478bd9Sstevel@tonic-gate char *bufend, *nbufp; 433*7c478bd9Sstevel@tonic-gate int gotlt, lastsp, didq; 434*7c478bd9Sstevel@tonic-gate char nbuf[LINESIZE]; 435*7c478bd9Sstevel@tonic-gate int nesting; 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate if (name == NOSTR) 438*7c478bd9Sstevel@tonic-gate return(NOSTR); 439*7c478bd9Sstevel@tonic-gate if (strlen(name) >= (unsigned)LINESIZE) 440*7c478bd9Sstevel@tonic-gate nbufp = (char *)salloc(strlen(name)); 441*7c478bd9Sstevel@tonic-gate else 442*7c478bd9Sstevel@tonic-gate nbufp = nbuf; 443*7c478bd9Sstevel@tonic-gate gotlt = 0; 444*7c478bd9Sstevel@tonic-gate lastsp = 0; 445*7c478bd9Sstevel@tonic-gate bufend = nbufp; 446*7c478bd9Sstevel@tonic-gate for (cp = name, cp2 = bufend; (c = *cp++) != 0;) { 447*7c478bd9Sstevel@tonic-gate switch (c) { 448*7c478bd9Sstevel@tonic-gate case '(': 449*7c478bd9Sstevel@tonic-gate /* 450*7c478bd9Sstevel@tonic-gate Start of a comment, ignore it. 451*7c478bd9Sstevel@tonic-gate */ 452*7c478bd9Sstevel@tonic-gate nesting = 1; 453*7c478bd9Sstevel@tonic-gate while ((c = *cp) != 0) { 454*7c478bd9Sstevel@tonic-gate cp++; 455*7c478bd9Sstevel@tonic-gate switch(c) { 456*7c478bd9Sstevel@tonic-gate case '\\': 457*7c478bd9Sstevel@tonic-gate if (*cp == 0) goto outcm; 458*7c478bd9Sstevel@tonic-gate cp++; 459*7c478bd9Sstevel@tonic-gate break; 460*7c478bd9Sstevel@tonic-gate case '(': 461*7c478bd9Sstevel@tonic-gate nesting++; 462*7c478bd9Sstevel@tonic-gate break; 463*7c478bd9Sstevel@tonic-gate case ')': 464*7c478bd9Sstevel@tonic-gate --nesting; 465*7c478bd9Sstevel@tonic-gate break; 466*7c478bd9Sstevel@tonic-gate } 467*7c478bd9Sstevel@tonic-gate if (nesting <= 0) break; 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate outcm: 470*7c478bd9Sstevel@tonic-gate lastsp = 0; 471*7c478bd9Sstevel@tonic-gate break; 472*7c478bd9Sstevel@tonic-gate case '"': 473*7c478bd9Sstevel@tonic-gate /* 474*7c478bd9Sstevel@tonic-gate Start a quoted string. 475*7c478bd9Sstevel@tonic-gate Copy it in its entirety. 476*7c478bd9Sstevel@tonic-gate */ 477*7c478bd9Sstevel@tonic-gate didq = 0; 478*7c478bd9Sstevel@tonic-gate while ((c = *cp) != 0) { 479*7c478bd9Sstevel@tonic-gate cp++; 480*7c478bd9Sstevel@tonic-gate switch (c) { 481*7c478bd9Sstevel@tonic-gate case '\\': 482*7c478bd9Sstevel@tonic-gate if ((c = *cp) == 0) goto outqs; 483*7c478bd9Sstevel@tonic-gate cp++; 484*7c478bd9Sstevel@tonic-gate break; 485*7c478bd9Sstevel@tonic-gate case '"': 486*7c478bd9Sstevel@tonic-gate goto outqs; 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate if (gotlt == 0 || gotlt == '<') { 489*7c478bd9Sstevel@tonic-gate if (lastsp) { 490*7c478bd9Sstevel@tonic-gate lastsp = 0; 491*7c478bd9Sstevel@tonic-gate *cp2++ = ' '; 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate if (!didq) { 494*7c478bd9Sstevel@tonic-gate *cp2++ = '"'; 495*7c478bd9Sstevel@tonic-gate didq++; 496*7c478bd9Sstevel@tonic-gate } 497*7c478bd9Sstevel@tonic-gate *cp2++ = c; 498*7c478bd9Sstevel@tonic-gate } 499*7c478bd9Sstevel@tonic-gate } 500*7c478bd9Sstevel@tonic-gate outqs: 501*7c478bd9Sstevel@tonic-gate if (didq) 502*7c478bd9Sstevel@tonic-gate *cp2++ = '"'; 503*7c478bd9Sstevel@tonic-gate lastsp = 0; 504*7c478bd9Sstevel@tonic-gate break; 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate case ' ': 507*7c478bd9Sstevel@tonic-gate case '\t': 508*7c478bd9Sstevel@tonic-gate case '\n': 509*7c478bd9Sstevel@tonic-gate if (token && (!comma || c == '\n')) { 510*7c478bd9Sstevel@tonic-gate done: 511*7c478bd9Sstevel@tonic-gate cp[-1] = 0; 512*7c478bd9Sstevel@tonic-gate return cp; 513*7c478bd9Sstevel@tonic-gate } 514*7c478bd9Sstevel@tonic-gate lastsp = 1; 515*7c478bd9Sstevel@tonic-gate break; 516*7c478bd9Sstevel@tonic-gate 517*7c478bd9Sstevel@tonic-gate case ',': 518*7c478bd9Sstevel@tonic-gate *cp2++ = c; 519*7c478bd9Sstevel@tonic-gate if (gotlt != '<') { 520*7c478bd9Sstevel@tonic-gate if (token) 521*7c478bd9Sstevel@tonic-gate goto done; 522*7c478bd9Sstevel@tonic-gate bufend = cp2; 523*7c478bd9Sstevel@tonic-gate gotlt = 0; 524*7c478bd9Sstevel@tonic-gate } 525*7c478bd9Sstevel@tonic-gate break; 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate case '<': 528*7c478bd9Sstevel@tonic-gate cp2 = bufend; 529*7c478bd9Sstevel@tonic-gate gotlt = c; 530*7c478bd9Sstevel@tonic-gate lastsp = 0; 531*7c478bd9Sstevel@tonic-gate break; 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate case '>': 534*7c478bd9Sstevel@tonic-gate if (gotlt == '<') { 535*7c478bd9Sstevel@tonic-gate gotlt = c; 536*7c478bd9Sstevel@tonic-gate break; 537*7c478bd9Sstevel@tonic-gate } 538*7c478bd9Sstevel@tonic-gate 539*7c478bd9Sstevel@tonic-gate /* FALLTHROUGH . . . */ 540*7c478bd9Sstevel@tonic-gate 541*7c478bd9Sstevel@tonic-gate default: 542*7c478bd9Sstevel@tonic-gate if (gotlt == 0 || gotlt == '<') { 543*7c478bd9Sstevel@tonic-gate if (lastsp) { 544*7c478bd9Sstevel@tonic-gate lastsp = 0; 545*7c478bd9Sstevel@tonic-gate *cp2++ = ' '; 546*7c478bd9Sstevel@tonic-gate } 547*7c478bd9Sstevel@tonic-gate *cp2++ = c; 548*7c478bd9Sstevel@tonic-gate } 549*7c478bd9Sstevel@tonic-gate break; 550*7c478bd9Sstevel@tonic-gate } 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate *cp2 = 0; 553*7c478bd9Sstevel@tonic-gate return (token ? --cp : equal(name, nbufp) ? name : 554*7c478bd9Sstevel@tonic-gate nbufp == nbuf ? savestr(nbuf) : nbufp); 555*7c478bd9Sstevel@tonic-gate } 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate char * 558*7c478bd9Sstevel@tonic-gate skin(char *name) 559*7c478bd9Sstevel@tonic-gate { 560*7c478bd9Sstevel@tonic-gate return phrase(name, 0, 0); 561*7c478bd9Sstevel@tonic-gate } 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate /* 564*7c478bd9Sstevel@tonic-gate * Here sz is the buffer size of word. 565*7c478bd9Sstevel@tonic-gate */ 566*7c478bd9Sstevel@tonic-gate char * 567*7c478bd9Sstevel@tonic-gate yankword(char *name, char *word, int sz, int comma) 568*7c478bd9Sstevel@tonic-gate { 569*7c478bd9Sstevel@tonic-gate char *cp; 570*7c478bd9Sstevel@tonic-gate 571*7c478bd9Sstevel@tonic-gate if (name == 0) 572*7c478bd9Sstevel@tonic-gate return 0; 573*7c478bd9Sstevel@tonic-gate while (isspace(*name)) 574*7c478bd9Sstevel@tonic-gate name++; 575*7c478bd9Sstevel@tonic-gate if (*name == 0) 576*7c478bd9Sstevel@tonic-gate return 0; 577*7c478bd9Sstevel@tonic-gate cp = phrase(name, 1, comma); 578*7c478bd9Sstevel@tonic-gate nstrcpy(word, sz, name); 579*7c478bd9Sstevel@tonic-gate return cp; 580*7c478bd9Sstevel@tonic-gate } 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate int 583*7c478bd9Sstevel@tonic-gate docomma(char *s) 584*7c478bd9Sstevel@tonic-gate { 585*7c478bd9Sstevel@tonic-gate return s && strpbrk(s, "(<,"); 586*7c478bd9Sstevel@tonic-gate } 587*7c478bd9Sstevel@tonic-gate 588*7c478bd9Sstevel@tonic-gate /* 589*7c478bd9Sstevel@tonic-gate * Fetch the sender's name from the passed message. 590*7c478bd9Sstevel@tonic-gate */ 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate char * 593*7c478bd9Sstevel@tonic-gate nameof(register struct message *mp) 594*7c478bd9Sstevel@tonic-gate { 595*7c478bd9Sstevel@tonic-gate char namebuf[LINESIZE]; 596*7c478bd9Sstevel@tonic-gate char linebuf[LINESIZE]; 597*7c478bd9Sstevel@tonic-gate register char *cp, *cp2; 598*7c478bd9Sstevel@tonic-gate register FILE *ibuf; 599*7c478bd9Sstevel@tonic-gate int first = 1, wint = 0; 600*7c478bd9Sstevel@tonic-gate char *tmp; 601*7c478bd9Sstevel@tonic-gate 602*7c478bd9Sstevel@tonic-gate if (value("from") && (cp = hfield("from", mp, addto)) != NOSTR) 603*7c478bd9Sstevel@tonic-gate return ripoff(cp); 604*7c478bd9Sstevel@tonic-gate ibuf = setinput(mp); 605*7c478bd9Sstevel@tonic-gate copy("", namebuf); 606*7c478bd9Sstevel@tonic-gate if (readline(ibuf, linebuf) <= 0) 607*7c478bd9Sstevel@tonic-gate return(savestr(namebuf)); 608*7c478bd9Sstevel@tonic-gate newname: 609*7c478bd9Sstevel@tonic-gate for (cp = linebuf; *cp != ' '; cp++) 610*7c478bd9Sstevel@tonic-gate ; 611*7c478bd9Sstevel@tonic-gate while (any(*cp, " \t")) 612*7c478bd9Sstevel@tonic-gate cp++; 613*7c478bd9Sstevel@tonic-gate for (cp2 = &namebuf[strlen(namebuf)]; *cp && !any(*cp, " \t") && 614*7c478bd9Sstevel@tonic-gate cp2-namebuf < LINESIZE-1; *cp2++ = *cp++) 615*7c478bd9Sstevel@tonic-gate ; 616*7c478bd9Sstevel@tonic-gate *cp2 = '\0'; 617*7c478bd9Sstevel@tonic-gate for (;;) { 618*7c478bd9Sstevel@tonic-gate if (readline(ibuf, linebuf) <= 0) 619*7c478bd9Sstevel@tonic-gate break; 620*7c478bd9Sstevel@tonic-gate if (substr(linebuf,"forwarded by ") != -1) 621*7c478bd9Sstevel@tonic-gate continue; 622*7c478bd9Sstevel@tonic-gate if (linebuf[0] == 'F') 623*7c478bd9Sstevel@tonic-gate cp = linebuf; 624*7c478bd9Sstevel@tonic-gate else if (linebuf[0] == '>') 625*7c478bd9Sstevel@tonic-gate cp = linebuf + 1; 626*7c478bd9Sstevel@tonic-gate else 627*7c478bd9Sstevel@tonic-gate break; 628*7c478bd9Sstevel@tonic-gate if (strncmp(cp, "From ", 5) != 0) 629*7c478bd9Sstevel@tonic-gate break; 630*7c478bd9Sstevel@tonic-gate if ((wint = substr(cp, "remote from ")) != -1) { 631*7c478bd9Sstevel@tonic-gate cp += wint + 12; 632*7c478bd9Sstevel@tonic-gate if (first) { 633*7c478bd9Sstevel@tonic-gate copy(cp, namebuf); 634*7c478bd9Sstevel@tonic-gate first = 0; 635*7c478bd9Sstevel@tonic-gate } else { 636*7c478bd9Sstevel@tonic-gate tmp = strrchr(namebuf, '!') + 1; 637*7c478bd9Sstevel@tonic-gate nstrcpy(tmp, 638*7c478bd9Sstevel@tonic-gate sizeof (namebuf) - (tmp - namebuf), 639*7c478bd9Sstevel@tonic-gate cp); 640*7c478bd9Sstevel@tonic-gate } 641*7c478bd9Sstevel@tonic-gate nstrcat(namebuf, sizeof (namebuf), "!"); 642*7c478bd9Sstevel@tonic-gate goto newname; 643*7c478bd9Sstevel@tonic-gate } else 644*7c478bd9Sstevel@tonic-gate break; 645*7c478bd9Sstevel@tonic-gate } 646*7c478bd9Sstevel@tonic-gate for (cp = namebuf; *cp == '!'; cp++); 647*7c478bd9Sstevel@tonic-gate while (ishost(host, cp)) 648*7c478bd9Sstevel@tonic-gate cp = strchr(cp, '!') + 1; 649*7c478bd9Sstevel@tonic-gate if (value("mustbang") && !strchr(cp, '!')) { 650*7c478bd9Sstevel@tonic-gate snprintf(linebuf, sizeof (linebuf), "%s!%s", 651*7c478bd9Sstevel@tonic-gate host, cp); 652*7c478bd9Sstevel@tonic-gate cp = linebuf; 653*7c478bd9Sstevel@tonic-gate } 654*7c478bd9Sstevel@tonic-gate if (cp2 = hfield("from", mp, addto)) 655*7c478bd9Sstevel@tonic-gate return(splice(cp, cp2)); 656*7c478bd9Sstevel@tonic-gate else 657*7c478bd9Sstevel@tonic-gate return(savestr(cp)); 658*7c478bd9Sstevel@tonic-gate } 659*7c478bd9Sstevel@tonic-gate 660*7c478bd9Sstevel@tonic-gate /* 661*7c478bd9Sstevel@tonic-gate * Splice an address into a commented recipient header. 662*7c478bd9Sstevel@tonic-gate */ 663*7c478bd9Sstevel@tonic-gate char * 664*7c478bd9Sstevel@tonic-gate splice(char *addr, char *hdr) 665*7c478bd9Sstevel@tonic-gate { 666*7c478bd9Sstevel@tonic-gate char buf[LINESIZE]; 667*7c478bd9Sstevel@tonic-gate char *cp, *cp2; 668*7c478bd9Sstevel@tonic-gate 669*7c478bd9Sstevel@tonic-gate if (cp = strchr(hdr, '<')) { 670*7c478bd9Sstevel@tonic-gate cp2 = strchr(cp, '>'); 671*7c478bd9Sstevel@tonic-gate if (cp2 == NULL) { 672*7c478bd9Sstevel@tonic-gate nstrcpy(buf, sizeof (buf), addr); 673*7c478bd9Sstevel@tonic-gate } else { 674*7c478bd9Sstevel@tonic-gate snprintf(buf, sizeof (buf), "%.*s%s%s", 675*7c478bd9Sstevel@tonic-gate cp - hdr + 1, hdr, addr, cp2); 676*7c478bd9Sstevel@tonic-gate } 677*7c478bd9Sstevel@tonic-gate } else if (cp = strchr(hdr, '(')) { 678*7c478bd9Sstevel@tonic-gate snprintf(buf, sizeof (buf), "%s %s", 679*7c478bd9Sstevel@tonic-gate addr, cp); 680*7c478bd9Sstevel@tonic-gate } else 681*7c478bd9Sstevel@tonic-gate nstrcpy(buf, sizeof (buf), addr); 682*7c478bd9Sstevel@tonic-gate return savestr(ripoff(buf)); 683*7c478bd9Sstevel@tonic-gate } 684*7c478bd9Sstevel@tonic-gate 685*7c478bd9Sstevel@tonic-gate static char * 686*7c478bd9Sstevel@tonic-gate ripoff(register char *buf) 687*7c478bd9Sstevel@tonic-gate { 688*7c478bd9Sstevel@tonic-gate register char *cp; 689*7c478bd9Sstevel@tonic-gate 690*7c478bd9Sstevel@tonic-gate cp = buf + strlen(buf); 691*7c478bd9Sstevel@tonic-gate while (--cp >= buf && isspace(*cp)); 692*7c478bd9Sstevel@tonic-gate if (cp >= buf && *cp == ',') 693*7c478bd9Sstevel@tonic-gate cp--; 694*7c478bd9Sstevel@tonic-gate *++cp = 0; 695*7c478bd9Sstevel@tonic-gate return buf; 696*7c478bd9Sstevel@tonic-gate } 697*7c478bd9Sstevel@tonic-gate 698*7c478bd9Sstevel@tonic-gate /* 699*7c478bd9Sstevel@tonic-gate * Are any of the characters in the two strings the same? 700*7c478bd9Sstevel@tonic-gate */ 701*7c478bd9Sstevel@tonic-gate 702*7c478bd9Sstevel@tonic-gate int 703*7c478bd9Sstevel@tonic-gate anyof(register char *s1, register char *s2) 704*7c478bd9Sstevel@tonic-gate { 705*7c478bd9Sstevel@tonic-gate register int c; 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate while ((c = *s1++) != 0) 708*7c478bd9Sstevel@tonic-gate if (any(c, s2)) 709*7c478bd9Sstevel@tonic-gate return(1); 710*7c478bd9Sstevel@tonic-gate return(0); 711*7c478bd9Sstevel@tonic-gate } 712*7c478bd9Sstevel@tonic-gate 713*7c478bd9Sstevel@tonic-gate /* 714*7c478bd9Sstevel@tonic-gate * See if the given header field is supposed to be ignored. 715*7c478bd9Sstevel@tonic-gate * Fields of the form "Content-*" can't be ignored when saving. 716*7c478bd9Sstevel@tonic-gate */ 717*7c478bd9Sstevel@tonic-gate int 718*7c478bd9Sstevel@tonic-gate isign(char *field, int saving) 719*7c478bd9Sstevel@tonic-gate { 720*7c478bd9Sstevel@tonic-gate char realfld[BUFSIZ]; 721*7c478bd9Sstevel@tonic-gate 722*7c478bd9Sstevel@tonic-gate /* 723*7c478bd9Sstevel@tonic-gate * Lower-case the string, so that "Status" and "status" 724*7c478bd9Sstevel@tonic-gate * will hash to the same place. 725*7c478bd9Sstevel@tonic-gate */ 726*7c478bd9Sstevel@tonic-gate istrcpy(realfld, sizeof (realfld), field); 727*7c478bd9Sstevel@tonic-gate 728*7c478bd9Sstevel@tonic-gate if (saving && strncmp(realfld, "content-", 8) == 0) 729*7c478bd9Sstevel@tonic-gate return (0); 730*7c478bd9Sstevel@tonic-gate 731*7c478bd9Sstevel@tonic-gate if (nretained > 0) 732*7c478bd9Sstevel@tonic-gate return (!member(realfld, retain)); 733*7c478bd9Sstevel@tonic-gate else 734*7c478bd9Sstevel@tonic-gate return (member(realfld, ignore)); 735*7c478bd9Sstevel@tonic-gate } 736*7c478bd9Sstevel@tonic-gate 737*7c478bd9Sstevel@tonic-gate int 738*7c478bd9Sstevel@tonic-gate member(register char *realfield, register struct ignore **table) 739*7c478bd9Sstevel@tonic-gate { 740*7c478bd9Sstevel@tonic-gate register struct ignore *igp; 741*7c478bd9Sstevel@tonic-gate 742*7c478bd9Sstevel@tonic-gate for (igp = table[hash(realfield)]; igp != 0; igp = igp->i_link) 743*7c478bd9Sstevel@tonic-gate if (equal(igp->i_field, realfield)) 744*7c478bd9Sstevel@tonic-gate return (1); 745*7c478bd9Sstevel@tonic-gate 746*7c478bd9Sstevel@tonic-gate return (0); 747*7c478bd9Sstevel@tonic-gate } 748*7c478bd9Sstevel@tonic-gate 749*7c478bd9Sstevel@tonic-gate /* 750*7c478bd9Sstevel@tonic-gate * This routine looks for string2 in string1. 751*7c478bd9Sstevel@tonic-gate * If found, it returns the position string2 is found at, 752*7c478bd9Sstevel@tonic-gate * otherwise it returns a -1. 753*7c478bd9Sstevel@tonic-gate */ 754*7c478bd9Sstevel@tonic-gate int 755*7c478bd9Sstevel@tonic-gate substr(char *string1, char *string2) 756*7c478bd9Sstevel@tonic-gate { 757*7c478bd9Sstevel@tonic-gate int i, j, len1, len2; 758*7c478bd9Sstevel@tonic-gate 759*7c478bd9Sstevel@tonic-gate len1 = strlen(string1); 760*7c478bd9Sstevel@tonic-gate len2 = strlen(string2); 761*7c478bd9Sstevel@tonic-gate for (i = 0; i < len1 - len2 + 1; i++) { 762*7c478bd9Sstevel@tonic-gate for (j = 0; j < len2 && string1[i+j] == string2[j]; j++) 763*7c478bd9Sstevel@tonic-gate ; 764*7c478bd9Sstevel@tonic-gate if (j == len2) 765*7c478bd9Sstevel@tonic-gate return(i); 766*7c478bd9Sstevel@tonic-gate } 767*7c478bd9Sstevel@tonic-gate return(-1); 768*7c478bd9Sstevel@tonic-gate } 769*7c478bd9Sstevel@tonic-gate 770*7c478bd9Sstevel@tonic-gate /* 771*7c478bd9Sstevel@tonic-gate * Copies src to the dstsize buffer at dst. The copy will never 772*7c478bd9Sstevel@tonic-gate * overflow the destination buffer and the buffer will always be null 773*7c478bd9Sstevel@tonic-gate * terminated. 774*7c478bd9Sstevel@tonic-gate */ 775*7c478bd9Sstevel@tonic-gate char * 776*7c478bd9Sstevel@tonic-gate nstrcpy(char *dst, int dstsize, char *src) 777*7c478bd9Sstevel@tonic-gate { 778*7c478bd9Sstevel@tonic-gate char *cp, *cp2; 779*7c478bd9Sstevel@tonic-gate 780*7c478bd9Sstevel@tonic-gate cp2 = dst; 781*7c478bd9Sstevel@tonic-gate cp = src; 782*7c478bd9Sstevel@tonic-gate 783*7c478bd9Sstevel@tonic-gate while (--dstsize > 0 && *cp != '\0') 784*7c478bd9Sstevel@tonic-gate *cp2++ = *cp++; 785*7c478bd9Sstevel@tonic-gate *cp2 = '\0'; 786*7c478bd9Sstevel@tonic-gate return(dst); 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate /* 790*7c478bd9Sstevel@tonic-gate * Appends src to the dstsize buffer at dst. The append will never 791*7c478bd9Sstevel@tonic-gate * overflow the destination buffer and the buffer will always be null 792*7c478bd9Sstevel@tonic-gate * terminated. 793*7c478bd9Sstevel@tonic-gate */ 794*7c478bd9Sstevel@tonic-gate char * 795*7c478bd9Sstevel@tonic-gate nstrcat(char *dst, int dstsize, char *src) 796*7c478bd9Sstevel@tonic-gate { 797*7c478bd9Sstevel@tonic-gate char *cp, *cp2; 798*7c478bd9Sstevel@tonic-gate 799*7c478bd9Sstevel@tonic-gate cp2 = dst; 800*7c478bd9Sstevel@tonic-gate cp = src; 801*7c478bd9Sstevel@tonic-gate 802*7c478bd9Sstevel@tonic-gate while (*cp2 != '\0') { 803*7c478bd9Sstevel@tonic-gate cp2++; 804*7c478bd9Sstevel@tonic-gate dstsize--; 805*7c478bd9Sstevel@tonic-gate } 806*7c478bd9Sstevel@tonic-gate while (--dstsize > 0 && *cp != '\0') 807*7c478bd9Sstevel@tonic-gate *cp2++ = *cp++; 808*7c478bd9Sstevel@tonic-gate *cp2 = '\0'; 809*7c478bd9Sstevel@tonic-gate return(dst); 810*7c478bd9Sstevel@tonic-gate } 811