1 /*-
2 * Copyright (c) 1980, 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #ifndef lint
35 static char sccsid[] = "@(#)misc.c 5.13 (Berkeley) 6/27/91";
36 #endif /* not lint */
37
38 #include <sys/param.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41 #if __STDC__
42 # include <stdarg.h>
43 #else
44 # include <varargs.h>
45 #endif
46
47 #include "csh.h"
48 #include "extern.h"
49
50 static int renum __P((int, int));
51
52 int
any(s,c)53 any(s, c)
54 register char *s;
55 register int c;
56 {
57 if (!s)
58 return (0); /* Check for nil pointer */
59 while (*s)
60 if (*s++ == c)
61 return (1);
62 return (0);
63 }
64
65 void
setzero(cp,i)66 setzero(cp, i)
67 char *cp;
68 int i;
69 {
70 if (i != 0)
71 do
72 *cp++ = 0;
73 while (--i);
74 }
75
76 char *
strsave(s)77 strsave(s)
78 register char *s;
79 {
80 char *n;
81 register char *p;
82
83 if (s == NULL)
84 s = "";
85 for (p = s; *p++;);
86 n = p = (char *) xmalloc((size_t) ((p - s) * sizeof(char)));
87 while (*p++ = *s++);
88 return (n);
89 }
90
91 Char **
blkend(up)92 blkend(up)
93 register Char **up;
94 {
95
96 while (*up)
97 up++;
98 return (up);
99 }
100
101
102 void
blkpr(av)103 blkpr(av)
104 register Char **av;
105 {
106
107 for (; *av; av++) {
108 xprintf("%s", short2str(*av));
109 if (av[1])
110 xprintf(" ");
111 }
112 }
113
114 int
blklen(av)115 blklen(av)
116 register Char **av;
117 {
118 register int i = 0;
119
120 while (*av++)
121 i++;
122 return (i);
123 }
124
125 Char **
blkcpy(oav,bv)126 blkcpy(oav, bv)
127 Char **oav;
128 register Char **bv;
129 {
130 register Char **av = oav;
131
132 while (*av++ = *bv++)
133 continue;
134 return (oav);
135 }
136
137 Char **
blkcat(up,vp)138 blkcat(up, vp)
139 Char **up, **vp;
140 {
141
142 (void) blkcpy(blkend(up), vp);
143 return (up);
144 }
145
146 void
blkfree(av0)147 blkfree(av0)
148 Char **av0;
149 {
150 register Char **av = av0;
151
152 if (!av0)
153 return;
154 for (; *av; av++)
155 xfree((ptr_t) * av);
156 xfree((ptr_t) av0);
157 }
158
159 Char **
saveblk(v)160 saveblk(v)
161 register Char **v;
162 {
163 register Char **newv =
164 (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
165 Char **onewv = newv;
166
167 while (*v)
168 *newv++ = Strsave(*v++);
169 return (onewv);
170 }
171
172 #ifdef NOTUSED
173 char *
strstr(s,t)174 strstr(s, t)
175 register char *s, *t;
176 {
177 do {
178 register char *ss = s;
179 register char *tt = t;
180
181 do
182 if (*tt == '\0')
183 return (s);
184 while (*ss++ == *tt++);
185 } while (*s++ != '\0');
186 return (NULL);
187 }
188
189 #endif /* NOTUSED */
190
191 #ifndef SHORT_STRINGS
192 char *
strspl(cp,dp)193 strspl(cp, dp)
194 char *cp, *dp;
195 {
196 char *ep;
197 register char *p, *q;
198
199 if (!cp)
200 cp = "";
201 if (!dp)
202 dp = "";
203 for (p = cp; *p++;);
204 for (q = dp; *q++;);
205 ep = (char *) xmalloc((size_t) (((p - cp) + (q - dp) - 1) * sizeof(char)));
206 for (p = ep, q = cp; *p++ = *q++;);
207 for (p--, q = dp; *p++ = *q++;);
208 return (ep);
209 }
210
211 #endif
212
213 Char **
blkspl(up,vp)214 blkspl(up, vp)
215 register Char **up, **vp;
216 {
217 register Char **wp =
218 (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1),
219 sizeof(Char **));
220
221 (void) blkcpy(wp, up);
222 return (blkcat(wp, vp));
223 }
224
225 Char
lastchr(cp)226 lastchr(cp)
227 register Char *cp;
228 {
229
230 if (!cp)
231 return (0);
232 if (!*cp)
233 return (0);
234 while (cp[1])
235 cp++;
236 return (*cp);
237 }
238
239 /*
240 * This routine is called after an error to close up
241 * any units which may have been left open accidentally.
242 */
243 void
closem()244 closem()
245 {
246 register int f;
247
248 for (f = 0; f < OPEN_MAX; f++)
249 if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD &&
250 f != FSHTTY)
251 (void) close(f);
252 }
253
254 void
donefds()255 donefds()
256 {
257
258 (void) close(0);
259 (void) close(1);
260 (void) close(2);
261 didfds = 0;
262 }
263
264 /*
265 * Move descriptor i to j.
266 * If j is -1 then we just want to get i to a safe place,
267 * i.e. to a unit > 2. This also happens in dcopy.
268 */
269 int
dmove(i,j)270 dmove(i, j)
271 register int i, j;
272 {
273
274 if (i == j || i < 0)
275 return (i);
276 if (j >= 0) {
277 (void) dup2(i, j);
278 if (j != i)
279 (void) close(i);
280 return (j);
281 }
282 j = dcopy(i, j);
283 if (j != i)
284 (void) close(i);
285 return (j);
286 }
287
288 int
dcopy(i,j)289 dcopy(i, j)
290 register int i, j;
291 {
292
293 if (i == j || i < 0 || j < 0 && i > 2)
294 return (i);
295 if (j >= 0) {
296 (void) dup2(i, j);
297 return (j);
298 }
299 (void) close(j);
300 return (renum(i, j));
301 }
302
303 static int
renum(i,j)304 renum(i, j)
305 register int i, j;
306 {
307 register int k = dup(i);
308
309 if (k < 0)
310 return (-1);
311 if (j == -1 && k > 2)
312 return (k);
313 if (k != j) {
314 j = renum(k, j);
315 (void) close(k);
316 return (j);
317 }
318 return (k);
319 }
320
321 /*
322 * Left shift a command argument list, discarding
323 * the first c arguments. Used in "shift" commands
324 * as well as by commands like "repeat".
325 */
326 void
lshift(v,c)327 lshift(v, c)
328 register Char **v;
329 register int c;
330 {
331 register Char **u = v;
332
333 while (*u && --c >= 0)
334 xfree((ptr_t) * u++);
335 (void) blkcpy(v, u);
336 }
337
338 int
number(cp)339 number(cp)
340 Char *cp;
341 {
342 if (!cp)
343 return(0);
344 if (*cp == '-') {
345 cp++;
346 if (!Isdigit(*cp))
347 return (0);
348 cp++;
349 }
350 while (*cp && Isdigit(*cp))
351 cp++;
352 return (*cp == 0);
353 }
354
355 Char **
copyblk(v)356 copyblk(v)
357 register Char **v;
358 {
359 Char **nv = (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
360
361 return (blkcpy(nv, v));
362 }
363
364 #ifndef SHORT_STRINGS
365 char *
strend(cp)366 strend(cp)
367 register char *cp;
368 {
369 if (!cp)
370 return (cp);
371 while (*cp)
372 cp++;
373 return (cp);
374 }
375
376 #endif /* SHORT_STRINGS */
377
378 Char *
strip(cp)379 strip(cp)
380 Char *cp;
381 {
382 register Char *dp = cp;
383
384 if (!cp)
385 return (cp);
386 while (*dp++ &= TRIM)
387 continue;
388 return (cp);
389 }
390
391 void
udvar(name)392 udvar(name)
393 Char *name;
394 {
395
396 setname(short2str(name));
397 stderror(ERR_NAME | ERR_UNDVAR);
398 }
399
400 int
prefix(sub,str)401 prefix(sub, str)
402 register Char *sub, *str;
403 {
404
405 for (;;) {
406 if (*sub == 0)
407 return (1);
408 if (*str == 0)
409 return (0);
410 if (*sub++ != *str++)
411 return (0);
412 }
413 }
414