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