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