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