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.13 (Berkeley) 06/27/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 if (j != i) 253 (void) close(i); 254 return (j); 255 } 256 j = dcopy(i, j); 257 if (j != i) 258 (void) close(i); 259 return (j); 260 } 261 262 int 263 dcopy(i, j) 264 register int i, j; 265 { 266 267 if (i == j || i < 0 || j < 0 && i > 2) 268 return (i); 269 if (j >= 0) { 270 (void) dup2(i, j); 271 return (j); 272 } 273 (void) close(j); 274 return (renum(i, j)); 275 } 276 277 static int 278 renum(i, j) 279 register int i, j; 280 { 281 register int k = dup(i); 282 283 if (k < 0) 284 return (-1); 285 if (j == -1 && k > 2) 286 return (k); 287 if (k != j) { 288 j = renum(k, j); 289 (void) close(k); 290 return (j); 291 } 292 return (k); 293 } 294 295 /* 296 * Left shift a command argument list, discarding 297 * the first c arguments. Used in "shift" commands 298 * as well as by commands like "repeat". 299 */ 300 void 301 lshift(v, c) 302 register Char **v; 303 register int c; 304 { 305 register Char **u = v; 306 307 while (*u && --c >= 0) 308 xfree((ptr_t) * u++); 309 (void) blkcpy(v, u); 310 } 311 312 int 313 number(cp) 314 Char *cp; 315 { 316 if (!cp) 317 return(0); 318 if (*cp == '-') { 319 cp++; 320 if (!Isdigit(*cp)) 321 return (0); 322 cp++; 323 } 324 while (*cp && Isdigit(*cp)) 325 cp++; 326 return (*cp == 0); 327 } 328 329 Char ** 330 copyblk(v) 331 register Char **v; 332 { 333 Char **nv = (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 334 335 return (blkcpy(nv, v)); 336 } 337 338 #ifndef SHORT_STRINGS 339 char * 340 strend(cp) 341 register char *cp; 342 { 343 if (!cp) 344 return (cp); 345 while (*cp) 346 cp++; 347 return (cp); 348 } 349 350 #endif /* SHORT_STRINGS */ 351 352 Char * 353 strip(cp) 354 Char *cp; 355 { 356 register Char *dp = cp; 357 358 if (!cp) 359 return (cp); 360 while (*dp++ &= TRIM) 361 continue; 362 return (cp); 363 } 364 365 void 366 udvar(name) 367 Char *name; 368 { 369 370 setname(short2str(name)); 371 stderror(ERR_NAME | ERR_UNDVAR); 372 } 373 374 int 375 prefix(sub, str) 376 register Char *sub, *str; 377 { 378 379 for (;;) { 380 if (*sub == 0) 381 return (1); 382 if (*str == 0) 383 return (0); 384 if (*sub++ != *str++) 385 return (0); 386 } 387 } 388