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