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