1 /* 2 * Copyright 2000 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 7 /* All Rights Reserved */ 8 9 /* 10 * Copyright (c) 1980 Regents of the University of California. 11 * All rights reserved. The Berkeley Software License Agreement 12 * specifies the terms and conditions for redistribution. 13 */ 14 15 #pragma ident "%Z%%M% %I% %E% SMI" 16 17 #include "sh.h" 18 #include "sh.tconst.h" 19 #include <fcntl.h> 20 #include <unistd.h> 21 22 /* 23 * C Shell 24 */ 25 26 any(c, s) 27 register int c; 28 register tchar *s; 29 { 30 31 while (s && *s) 32 if (*s++ == c) 33 return (1); 34 return (0); 35 } 36 37 onlyread(cp) 38 tchar *cp; 39 { 40 extern char end[]; 41 42 return ((char *)cp < end); 43 } 44 45 46 /* 47 * WARNING: changes here also need to occur in the XFREE macro in sh.h. 48 */ 49 50 xfree(cp) 51 char *cp; 52 { 53 extern char end[]; 54 55 #if defined(sparc) 56 if ((char *)cp >= end && (char *)cp < (char *)&cp) 57 free(cp); 58 #elif defined(i386) 59 if ((char *)cp >= end) 60 free(cp); 61 #else 62 #error xfree function is machine dependent and no machine type is recognized 63 #endif 64 } 65 66 tchar * 67 savestr(s) 68 register tchar *s; 69 { 70 tchar *n; 71 register tchar *p; 72 73 if (s == 0) 74 s = S_ /* "" */; 75 #ifndef m32 76 for (p = s; *p++; ) 77 ; 78 n = p = (tchar *)xalloc((unsigned) (p - s)*sizeof (tchar)); 79 while (*p++ = *s++) 80 ; 81 return (n); 82 #else 83 p = (tchar *) xalloc((strlen_(s) + 1)*sizeof (tchar)); 84 strcpy_(p, s); 85 return (p); 86 #endif 87 } 88 89 void * 90 calloc(i, j) 91 register unsigned i; 92 unsigned j; 93 { 94 register char *cp; 95 96 i *= j; 97 cp = (char *)xalloc(i); 98 bzero(cp, (int)i); 99 return (cp); 100 } 101 102 nomem(i) 103 unsigned i; 104 { 105 #ifdef debug 106 static tchar *av[2] = {0, 0}; 107 #endif 108 109 child++; 110 #ifndef debug 111 error("Out of memory"); 112 #ifdef lint 113 i = i; 114 #endif 115 #else 116 showall(av); 117 printf("i=%d: Out of memory\n", i); 118 chdir("/usr/bill/cshcore"); 119 abort(); 120 #endif 121 return (0); /* fool lint */ 122 } 123 124 tchar ** 125 blkend(up) 126 register tchar **up; 127 { 128 129 while (*up) 130 up++; 131 return (up); 132 } 133 134 blkpr(av) 135 register tchar **av; 136 { 137 138 for (; *av; av++) { 139 printf("%t", *av); 140 if (av[1]) 141 printf(" "); 142 } 143 } 144 145 blklen(av) 146 register tchar **av; 147 { 148 register int i = 0; 149 150 while (*av++) 151 i++; 152 return (i); 153 } 154 155 tchar ** 156 blkcpy(oav, bv) 157 tchar **oav; 158 register tchar **bv; 159 { 160 register tchar **av = oav; 161 162 while (*av++ = *bv++) 163 continue; 164 return (oav); 165 } 166 167 tchar ** 168 blkcat(up, vp) 169 tchar **up, **vp; 170 { 171 172 (void) blkcpy(blkend(up), vp); 173 return (up); 174 } 175 176 blkfree(av0) 177 tchar **av0; 178 { 179 register tchar **av = av0; 180 181 for (; *av; av++) 182 XFREE(*av) 183 XFREE((tchar *)av0) 184 } 185 186 tchar ** 187 saveblk(v) 188 register tchar **v; 189 { 190 register tchar **newv = 191 (tchar **) calloc((unsigned) (blklen(v) + 1), 192 sizeof (tchar **)); 193 tchar **onewv = newv; 194 195 while (*v) 196 *newv++ = savestr(*v++); 197 return (onewv); 198 } 199 200 tchar * 201 strspl(cp, dp) 202 tchar *cp, *dp; 203 { 204 tchar *ep; 205 register tchar *p, *q; 206 207 #ifndef m32 208 for (p = cp; *p++; ) 209 ; 210 for (q = dp; *q++; ) 211 ; 212 ep = (tchar *) xalloc((unsigned) (((p - cp) + 213 (q - dp) - 1))*sizeof (tchar)); 214 for (p = ep, q = cp; *p++ = *q++; ) 215 ; 216 for (p--, q = dp; *p++ = *q++; ) 217 ; 218 #else 219 int len1 = strlen_(cp); 220 int len2 = strlen_(dp); 221 222 ep = (tchar *)xalloc((unsigned) (len1 + len2 + 1)*sizeof (tchar)); 223 strcpy_(ep, cp); 224 strcat_(ep, dp); 225 #endif 226 return (ep); 227 } 228 229 tchar ** 230 blkspl(up, vp) 231 register tchar **up, **vp; 232 { 233 register tchar **wp = 234 (tchar **) calloc((unsigned) (blklen(up) + blklen(vp) + 1), 235 sizeof (tchar **)); 236 237 (void) blkcpy(wp, up); 238 return (blkcat(wp, vp)); 239 } 240 241 lastchr(cp) 242 register tchar *cp; 243 { 244 245 if (!*cp) 246 return (0); 247 while (cp[1]) 248 cp++; 249 return (*cp); 250 } 251 252 donefds() 253 { 254 (void) close(0); 255 (void) close(1); 256 (void) close(2); 257 258 /* 259 * To avoid NIS+ functions to get hold of 0/1/2, 260 * use descriptor 0, and dup it to 1 and 2. 261 */ 262 open("/dev/null", 0); 263 dup(0); dup(0); 264 didfds = 0; 265 } 266 267 /* 268 * Move descriptor i to j. 269 * If j is -1 then we just want to get i to a safe place, 270 * i.e. to a unit > 2. This also happens in dcopy. 271 */ 272 dmove(i, j) 273 register int i, j; 274 { 275 int fd; 276 277 if (i == j || i < 0) 278 return (i); 279 if (j >= 0) { 280 fd = dup2(i, j); 281 if (fd != -1) 282 setfd(fd); 283 } else 284 j = dcopy(i, j); 285 if (j != i) { 286 (void) close(i); 287 unsetfd(i); 288 } 289 return (j); 290 } 291 292 dcopy(i, j) 293 register int i, j; 294 { 295 296 int fd; 297 298 if (i == j || i < 0 || j < 0 && i > 2) 299 return (i); 300 if (j >= 0) { 301 fd = dup2(i, j); 302 if (fd != -1) 303 setfd(fd); 304 return (j); 305 } 306 (void) close(j); 307 unsetfd(j); 308 return (renum(i, j)); 309 } 310 311 renum(i, j) 312 register int i, j; 313 { 314 register int k = dup(i); 315 316 if (k < 0) 317 return (-1); 318 if (j == -1 && k > 2) { 319 setfd(k); 320 return (k); 321 } 322 if (k != j) { 323 j = renum(k, j); 324 (void) close(k); /* no need ofr unsetfd() */ 325 return (j); 326 } 327 return (k); 328 } 329 330 #ifndef copy 331 copy(to, from, size) 332 register tchar *to, *from; 333 register int size; 334 { 335 336 if (size) 337 do 338 *to++ = *from++; 339 while (--size != 0); 340 } 341 #endif 342 343 /* 344 * Left shift a command argument list, discarding 345 * the first c arguments. Used in "shift" commands 346 * as well as by commands like "repeat". 347 */ 348 lshift(v, c) 349 register tchar **v; 350 register int c; 351 { 352 register tchar **u = v; 353 354 while (*u && --c >= 0) 355 xfree(*u++); 356 (void) blkcpy(v, u); 357 } 358 359 number(cp) 360 tchar *cp; 361 { 362 363 if (*cp == '-') { 364 cp++; 365 if (!digit(*cp++)) 366 return (0); 367 } 368 while (*cp && digit(*cp)) 369 cp++; 370 return (*cp == 0); 371 } 372 373 tchar ** 374 copyblk(v) 375 register tchar **v; 376 { 377 register tchar **nv = 378 (tchar **) calloc((unsigned) (blklen(v) + 1), 379 sizeof (tchar **)); 380 381 return (blkcpy(nv, v)); 382 } 383 384 tchar * 385 strend(cp) 386 register tchar *cp; 387 { 388 389 while (*cp) 390 cp++; 391 return (cp); 392 } 393 394 tchar * 395 strip(cp) 396 tchar *cp; 397 { 398 register tchar *dp = cp; 399 400 while (*dp++ &= TRIM) 401 continue; 402 return (cp); 403 } 404 405 udvar(name) 406 tchar *name; 407 { 408 409 setname(name); 410 bferr("Undefined variable"); 411 } 412 413 prefix(sub, str) 414 register tchar *sub, *str; 415 { 416 417 for (;;) { 418 if (*sub == 0) 419 return (1); 420 if (*str == 0) 421 return (0); 422 if (*sub++ != *str++) 423 return (0); 424 } 425 } 426 427 /* 428 * blk*_ routines 429 */ 430 431 char ** 432 blkend_(up) 433 register char **up; 434 { 435 436 while (*up) 437 up++; 438 return (up); 439 } 440 441 blklen_(av) 442 register char **av; 443 { 444 register int i = 0; 445 446 while (*av++) 447 i++; 448 return (i); 449 } 450 451 char ** 452 blkcpy_(oav, bv) 453 char **oav; 454 register char **bv; 455 { 456 register char **av = oav; 457 458 while (*av++ = *bv++) 459 continue; 460 return (oav); 461 } 462 463 char ** 464 blkcat_(up, vp) 465 char **up, **vp; 466 { 467 468 (void) blkcpy_(blkend_(up), vp); 469 return (up); 470 } 471 472 char ** 473 blkspl_(up, vp) 474 register char **up, **vp; 475 { 476 register char **wp = 477 (char **) calloc((unsigned) (blklen_(up) + blklen_(vp) + 1), 478 sizeof (char **)); 479 480 (void) blkcpy_(wp, up); 481 return (blkcat_(wp, vp)); 482 } 483