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