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