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