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