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