misc.c revision 1.5 1 /*-
2 * Copyright (c) 1980, 1991, 1993
3 * The Regents of the University of California. 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[] = "from: @(#)misc.c 8.1 (Berkeley) 5/31/93";*/
36 static char *rcsid = "$Id: misc.c,v 1.5 1994/09/21 00:11:03 mycroft Exp $";
37 #endif /* not lint */
38
39 #include <sys/param.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #if __STDC__
43 # include <stdarg.h>
44 #else
45 # include <varargs.h>
46 #endif
47
48 #include "csh.h"
49 #include "extern.h"
50
51 static int renum __P((int, int));
52
53 int
54 any(s, c)
55 register char *s;
56 register int c;
57 {
58 if (!s)
59 return (0); /* Check for nil pointer */
60 while (*s)
61 if (*s++ == c)
62 return (1);
63 return (0);
64 }
65
66 void
67 setzero(cp, i)
68 char *cp;
69 int i;
70 {
71 if (i != 0)
72 do
73 *cp++ = 0;
74 while (--i);
75 }
76
77 char *
78 strsave(s)
79 register char *s;
80 {
81 char *n;
82 register char *p;
83
84 if (s == NULL)
85 s = "";
86 for (p = s; *p++;)
87 continue;
88 n = p = (char *) xmalloc((size_t) ((p - s) * sizeof(char)));
89 while ((*p++ = *s++) != '\0')
90 continue;
91 return (n);
92 }
93
94 Char **
95 blkend(up)
96 register Char **up;
97 {
98
99 while (*up)
100 up++;
101 return (up);
102 }
103
104
105 void
106 blkpr(fp, av)
107 FILE *fp;
108 register Char **av;
109 {
110
111 for (; *av; av++) {
112 (void) fprintf(fp, "%s", vis_str(*av));
113 if (av[1])
114 (void) fprintf(fp, " ");
115 }
116 }
117
118 int
119 blklen(av)
120 register Char **av;
121 {
122 register int i = 0;
123
124 while (*av++)
125 i++;
126 return (i);
127 }
128
129 Char **
130 blkcpy(oav, bv)
131 Char **oav;
132 register Char **bv;
133 {
134 register Char **av = oav;
135
136 while ((*av++ = *bv++) != NULL)
137 continue;
138 return (oav);
139 }
140
141 Char **
142 blkcat(up, vp)
143 Char **up, **vp;
144 {
145
146 (void) blkcpy(blkend(up), vp);
147 return (up);
148 }
149
150 void
151 blkfree(av0)
152 Char **av0;
153 {
154 register Char **av = av0;
155
156 if (!av0)
157 return;
158 for (; *av; av++)
159 xfree((ptr_t) * av);
160 xfree((ptr_t) av0);
161 }
162
163 Char **
164 saveblk(v)
165 register Char **v;
166 {
167 register Char **newv =
168 (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
169 Char **onewv = newv;
170
171 while (*v)
172 *newv++ = Strsave(*v++);
173 return (onewv);
174 }
175
176 #ifdef NOTUSED
177 char *
178 strstr(s, t)
179 register char *s, *t;
180 {
181 do {
182 register char *ss = s;
183 register char *tt = t;
184
185 do
186 if (*tt == '\0')
187 return (s);
188 while (*ss++ == *tt++);
189 } while (*s++ != '\0');
190 return (NULL);
191 }
192
193 #endif /* NOTUSED */
194
195 #ifndef SHORT_STRINGS
196 char *
197 strspl(cp, dp)
198 char *cp, *dp;
199 {
200 char *ep;
201 register char *p, *q;
202
203 if (!cp)
204 cp = "";
205 if (!dp)
206 dp = "";
207 for (p = cp; *p++;)
208 continue;
209 for (q = dp; *q++;)
210 continue;
211 ep = (char *) xmalloc((size_t) (((p - cp) + (q - dp) - 1) * sizeof(char)));
212 for (p = ep, q = cp; *p++ = *q++;)
213 continue;
214 for (p--, q = dp; *p++ = *q++;)
215 continue;
216 return (ep);
217 }
218
219 #endif
220
221 Char **
222 blkspl(up, vp)
223 register Char **up, **vp;
224 {
225 register Char **wp =
226 (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1),
227 sizeof(Char **));
228
229 (void) blkcpy(wp, up);
230 return (blkcat(wp, vp));
231 }
232
233 Char
234 lastchr(cp)
235 register Char *cp;
236 {
237
238 if (!cp)
239 return (0);
240 if (!*cp)
241 return (0);
242 while (cp[1])
243 cp++;
244 return (*cp);
245 }
246
247 /*
248 * This routine is called after an error to close up
249 * any units which may have been left open accidentally.
250 */
251 void
252 closem()
253 {
254 register int f;
255
256 for (f = 0; f < NOFILE; f++)
257 if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD &&
258 f != FSHTTY)
259 (void) close(f);
260 }
261
262 void
263 donefds()
264 {
265 (void) close(0);
266 (void) close(1);
267 (void) close(2);
268
269 didfds = 0;
270 }
271
272 /*
273 * Move descriptor i to j.
274 * If j is -1 then we just want to get i to a safe place,
275 * i.e. to a unit > 2. This also happens in dcopy.
276 */
277 int
278 dmove(i, j)
279 register int i, j;
280 {
281
282 if (i == j || i < 0)
283 return (i);
284 if (j >= 0) {
285 (void) dup2(i, j);
286 if (j != i)
287 (void) close(i);
288 return (j);
289 }
290 j = dcopy(i, j);
291 if (j != i)
292 (void) close(i);
293 return (j);
294 }
295
296 int
297 dcopy(i, j)
298 register int i, j;
299 {
300
301 if (i == j || i < 0 || (j < 0 && i > 2))
302 return (i);
303 if (j >= 0) {
304 (void) dup2(i, j);
305 return (j);
306 }
307 (void) close(j);
308 return (renum(i, j));
309 }
310
311 static int
312 renum(i, j)
313 register int i, j;
314 {
315 register int k = dup(i);
316
317 if (k < 0)
318 return (-1);
319 if (j == -1 && k > 2)
320 return (k);
321 if (k != j) {
322 j = renum(k, j);
323 (void) close(k);
324 return (j);
325 }
326 return (k);
327 }
328
329 /*
330 * Left shift a command argument list, discarding
331 * the first c arguments. Used in "shift" commands
332 * as well as by commands like "repeat".
333 */
334 void
335 lshift(v, c)
336 register Char **v;
337 register int c;
338 {
339 register Char **u;
340
341 for (u = v; *u && --c >= 0; u++)
342 xfree((ptr_t) *u);
343 (void) blkcpy(v, u);
344 }
345
346 int
347 number(cp)
348 Char *cp;
349 {
350 if (!cp)
351 return(0);
352 if (*cp == '-') {
353 cp++;
354 if (!Isdigit(*cp))
355 return (0);
356 cp++;
357 }
358 while (*cp && Isdigit(*cp))
359 cp++;
360 return (*cp == 0);
361 }
362
363 Char **
364 copyblk(v)
365 register Char **v;
366 {
367 Char **nv = (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
368
369 return (blkcpy(nv, v));
370 }
371
372 #ifndef SHORT_STRINGS
373 char *
374 strend(cp)
375 register char *cp;
376 {
377 if (!cp)
378 return (cp);
379 while (*cp)
380 cp++;
381 return (cp);
382 }
383
384 #endif /* SHORT_STRINGS */
385
386 Char *
387 strip(cp)
388 Char *cp;
389 {
390 register Char *dp = cp;
391
392 if (!cp)
393 return (cp);
394 while ((*dp++ &= TRIM) != '\0')
395 continue;
396 return (cp);
397 }
398
399 void
400 udvar(name)
401 Char *name;
402 {
403
404 setname(vis_str(name));
405 stderror(ERR_NAME | ERR_UNDVAR);
406 }
407
408 int
409 prefix(sub, str)
410 register Char *sub, *str;
411 {
412
413 for (;;) {
414 if (*sub == 0)
415 return (1);
416 if (*str == 0)
417 return (0);
418 if (*sub++ != *str++)
419 return (0);
420 }
421 }
422