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