1 /* $OpenBSD: misc.c,v 1.15 2015/02/08 06:09:50 tedu 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/types.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 = xreallocarray(NULL, (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(* av); 128 xfree(av0); 129 } 130 131 Char ** 132 saveblk(Char **v) 133 { 134 Char **newv = xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 135 Char **onewv = newv; 136 137 while (*v) 138 *newv++ = Strsave(*v++); 139 return (onewv); 140 } 141 142 #ifdef NOTUSED 143 char * 144 strstr(char *s, char *t) 145 { 146 do { 147 char *ss = s; 148 char *tt = t; 149 150 do 151 if (*tt == '\0') 152 return (s); 153 while (*ss++ == *tt++); 154 } while (*s++ != '\0'); 155 return (NULL); 156 } 157 158 #endif /* NOTUSED */ 159 160 #ifndef SHORT_STRINGS 161 char * 162 strspl(char *cp, char *dp) 163 { 164 char *ep; 165 char *p, *q; 166 167 if (!cp) 168 cp = ""; 169 if (!dp) 170 dp = ""; 171 for (p = cp; *p++;) 172 continue; 173 for (q = dp; *q++;) 174 continue; 175 ep = xreallocarray(NULL, ((p - cp) + (q - dp) - 1), sizeof(char)); 176 for (p = ep, q = cp; *p++ = *q++;) 177 continue; 178 for (p--, q = dp; *p++ = *q++;) 179 continue; 180 return (ep); 181 } 182 183 #endif 184 185 Char ** 186 blkspl(Char **up, Char **vp) 187 { 188 Char **wp = xcalloc((size_t) (blklen(up) + blklen(vp) + 1), 189 sizeof(Char **)); 190 191 (void) blkcpy(wp, up); 192 return (blkcat(wp, vp)); 193 } 194 195 Char 196 lastchr(Char *cp) 197 { 198 199 if (!cp) 200 return (0); 201 if (!*cp) 202 return (0); 203 while (cp[1]) 204 cp++; 205 return (*cp); 206 } 207 208 /* 209 * This routine is called after an error to close up 210 * any units which may have been left open accidentally. 211 */ 212 void 213 closem(void) 214 { 215 int f; 216 217 for (f = 0; f < sysconf(_SC_OPEN_MAX); f++) 218 if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD && 219 f != FSHTTY) 220 (void) close(f); 221 } 222 223 void 224 donefds(void) 225 { 226 (void) close(0); 227 (void) close(1); 228 (void) close(2); 229 230 didfds = 0; 231 } 232 233 /* 234 * Move descriptor i to j. 235 * If j is -1 then we just want to get i to a safe place, 236 * i.e. to a unit > 2. This also happens in dcopy. 237 */ 238 int 239 dmove(int i, int j) 240 { 241 242 if (i == j || i < 0) 243 return (i); 244 if (j >= 0) { 245 (void) dup2(i, j); 246 if (j != i) 247 (void) close(i); 248 return (j); 249 } 250 j = dcopy(i, j); 251 if (j != i) 252 (void) close(i); 253 return (j); 254 } 255 256 int 257 dcopy(int i, int j) 258 { 259 260 if (i == j || i < 0 || (j < 0 && i > 2)) 261 return (i); 262 if (j >= 0) { 263 (void) dup2(i, j); 264 return (j); 265 } 266 (void) close(j); 267 return (renum(i, j)); 268 } 269 270 static int 271 renum(int i, int j) 272 { 273 int k = dup(i); 274 275 if (k < 0) 276 return (-1); 277 if (j == -1 && k > 2) 278 return (k); 279 if (k != j) { 280 j = renum(k, j); 281 (void) close(k); 282 return (j); 283 } 284 return (k); 285 } 286 287 /* 288 * Left shift a command argument list, discarding 289 * the first c arguments. Used in "shift" commands 290 * as well as by commands like "repeat". 291 */ 292 void 293 lshift(Char **v, int c) 294 { 295 Char **u; 296 297 for (u = v; *u && --c >= 0; u++) 298 xfree(*u); 299 (void) blkcpy(v, u); 300 } 301 302 int 303 number(Char *cp) 304 { 305 if (!cp) 306 return(0); 307 if (*cp == '-') { 308 cp++; 309 if (!Isdigit(*cp)) 310 return (0); 311 cp++; 312 } 313 while (*cp && Isdigit(*cp)) 314 cp++; 315 return (*cp == 0); 316 } 317 318 Char ** 319 copyblk(Char **v) 320 { 321 Char **nv = xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 322 323 return (blkcpy(nv, v)); 324 } 325 326 #ifndef SHORT_STRINGS 327 char * 328 strend(char *cp) 329 { 330 if (!cp) 331 return (cp); 332 while (*cp) 333 cp++; 334 return (cp); 335 } 336 337 #endif /* SHORT_STRINGS */ 338 339 Char * 340 strip(Char *cp) 341 { 342 Char *dp = cp; 343 344 if (!cp) 345 return (cp); 346 while ((*dp++ &= TRIM) != '\0') 347 continue; 348 return (cp); 349 } 350 351 Char * 352 quote(Char *cp) 353 { 354 Char *dp = cp; 355 356 if (!cp) 357 return (cp); 358 while (*dp != '\0') 359 *dp++ |= QUOTE; 360 return (cp); 361 } 362 363 void 364 udvar(Char *name) 365 { 366 367 setname(vis_str(name)); 368 stderror(ERR_NAME | ERR_UNDVAR); 369 } 370 371 int 372 prefix(Char *sub, Char *str) 373 { 374 375 for (;;) { 376 if (*sub == 0) 377 return (1); 378 if (*str == 0) 379 return (0); 380 if (*sub++ != *str++) 381 return (0); 382 } 383 } 384