1 /* $Header: /src/pub/tcsh/tc.os.c,v 3.58 2005/01/18 20:24:51 christos Exp $ */ 2 /* 3 * tc.os.c: OS Dependent builtin functions 4 */ 5 /*- 6 * Copyright (c) 1980, 1991 The Regents of the University of California. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 #include "sh.h" 34 35 RCSID("$Id: tc.os.c,v 3.58 2005/01/18 20:24:51 christos Exp $") 36 37 #include "tw.h" 38 #include "ed.h" 39 #include "ed.defns.h" /* for the function names */ 40 #include "sh.decls.h" 41 42 #ifdef _UWIN 43 #define TIOCGPGRP TIOCGETPGRP 44 #define TIOCSPGRP TIOCSETPGRP 45 #endif 46 47 /*** 48 *** MACH 49 ***/ 50 51 #ifdef MACH 52 /* dosetpath -- setpath built-in command 53 * 54 ********************************************************************** 55 * HISTORY 56 * 08-May-88 Richard Draves (rpd) at Carnegie-Mellon University 57 * Major changes to remove artificial limits on sizes and numbers 58 * of paths. 59 * 60 ********************************************************************** 61 */ 62 63 #ifdef MACH 64 static Char STRCPATH[] = {'C', 'P', 'A', 'T', 'H', '\0'}; 65 static Char STRLPATH[] = {'L', 'P', 'A', 'T', 'H', '\0'}; 66 static Char STRMPATH[] = {'M', 'P', 'A', 'T', 'H', '\0'}; 67 # if EPATH 68 static Char STREPATH[] = {'E', 'P', 'A', 'T', 'H', '\0'}; 69 # endif 70 #endif /* MACH */ 71 static Char *syspaths[] = {STRKPATH, STRCPATH, STRLPATH, STRMPATH, 72 73 #if EPATH 74 STREPATH, 75 #endif 76 0}; 77 #define LOCALSYSPATH "/usr/local" 78 79 /*ARGSUSED*/ 80 void 81 dosetpath(arglist, c) 82 Char **arglist; 83 struct command *c; 84 { 85 extern char *getenv(); 86 sigmask_t omask; 87 Char **pathvars, **cmdargs; 88 char **spaths, **cpaths, **cmds; 89 char *tcp; 90 unsigned int npaths, ncmds; 91 int i, sysflag; 92 93 omask = sigsetmask(sigmask(SIGINT)); 94 95 /* 96 * setpath(3) uses stdio and we want 0, 1, 2 to work... 97 */ 98 if (!didfds) { 99 (void) dcopy(SHIN, 0); 100 (void) dcopy(SHOUT, 1); 101 (void) dcopy(SHDIAG, 2); 102 didfds = 1; 103 } 104 105 for (i = 1; arglist[i] && (arglist[i][0] != '-'); i++); 106 npaths = i - 1; 107 108 cmdargs = &arglist[i]; 109 for (; arglist[i]; i++); 110 ncmds = i - npaths - 1; 111 112 if (npaths) { 113 sysflag = 0; 114 pathvars = &arglist[1]; 115 } 116 else { 117 sysflag = 1; 118 npaths = (sizeof syspaths / sizeof *syspaths) - 1; 119 pathvars = syspaths; 120 } 121 122 /* note that npaths != 0 */ 123 124 spaths = (char **) xmalloc((size_t) npaths * sizeof *spaths); 125 setzero((char *) spaths, npaths * sizeof *spaths); 126 cpaths = (char **) xmalloc((size_t) (npaths + 1) * sizeof *cpaths); 127 setzero((char *) cpaths, (npaths + 1) * sizeof *cpaths); 128 cmds = (char **) xmalloc((size_t) (ncmds + 1) * sizeof *cmds); 129 setzero((char *) cmds, (ncmds + 1) * sizeof *cmds); 130 for (i = 0; i < npaths; i++) { 131 char *val = getenv(short2str(pathvars[i])); 132 133 if (val == NULL) 134 val = ""; 135 136 spaths[i] = (char *) xmalloc((size_t) (Strlen(pathvars[i]) + 137 strlen(val) + 2) * sizeof **spaths); 138 (void) strcpy(spaths[i], short2str(pathvars[i])); 139 (void) strcat(spaths[i], "="); 140 (void) strcat(spaths[i], val); 141 cpaths[i] = spaths[i]; 142 } 143 144 for (i = 0; i < ncmds; i++) { 145 Char *val = globone(cmdargs[i], G_ERROR); 146 147 if (val == NULL) 148 goto abortpath; 149 cmds[i] = (char *) xmalloc((size_t) Strlen(val) + 1); 150 (void) strcpy(cmds[i], short2str(val)); 151 } 152 153 154 if (setpath(cpaths, cmds, LOCALSYSPATH, sysflag, 1) < 0) { 155 abortpath: 156 if (spaths) { 157 for (i = 0; i < npaths; i++) 158 if (spaths[i]) 159 xfree((ptr_t) spaths[i]); 160 xfree((ptr_t) spaths); 161 } 162 if (cpaths) 163 xfree((ptr_t) cpaths); 164 if (cmds) { 165 for (i = 0; i < ncmds; i++) 166 if (cmds[i]) 167 xfree((ptr_t) cmds[i]); 168 xfree((ptr_t) cmds); 169 } 170 171 (void) sigsetmask(omask); 172 donefds(); 173 return; 174 } 175 176 for (i = 0; i < npaths; i++) { 177 Char *val, *name; 178 179 name = str2short(cpaths[i]); 180 for (val = str2short(cpaths[i]); val && *val && *val != '='; val++); 181 if (val && *val == '=') { 182 *val++ = '\0'; 183 184 tsetenv(name, val); 185 if (Strcmp(name, STRKPATH) == 0) { 186 importpath(val); 187 if (havhash) 188 dohash(NULL, NULL); 189 } 190 *--val = '='; 191 } 192 } 193 (void) sigsetmask(omask); 194 donefds(); 195 } 196 #endif /* MACH */ 197 198 /*** 199 *** AIX 200 ***/ 201 #ifdef TCF 202 /* ARGSUSED */ 203 void 204 dogetxvers(v, c) 205 Char **v; 206 struct command *c; 207 { 208 char xvers[MAXPATHLEN]; 209 210 if (getxvers(xvers, MAXPATHLEN) == -1) 211 stderror(ERR_SYSTEM, "getxvers", strerror(errno)); 212 xprintf("%s\n", xvers); 213 flush(); 214 } 215 216 /*ARGSUSED*/ 217 void 218 dosetxvers(v, c) 219 Char **v; 220 struct command *c; 221 { 222 char *xvers; 223 224 ++v; 225 if (!*v || *v[0] == '\0') 226 xvers = ""; 227 else 228 xvers = short2str(*v); 229 if (setxvers(xvers) == -1) 230 stderror(ERR_SYSTEM, "setxvers", strerror(errno)); 231 } 232 233 #include <sf.h> 234 #ifdef _AIXPS2 235 # define XC_PDP11 0x01 236 # define XC_23 0x02 237 # define XC_Z8K 0x03 238 # define XC_8086 0x04 239 # define XC_68K 0x05 240 # define XC_Z80 0x06 241 # define XC_VAX 0x07 242 # define XC_16032 0x08 243 # define XC_286 0x09 244 # define XC_386 0x0a 245 # define XC_S370 0x0b 246 #else 247 # include <sys/x.out.h> 248 #endif /* _AIXPS2 */ 249 250 static struct xc_cpu_t { 251 short xc_id; 252 char *xc_name; 253 } xcpu[] = 254 { 255 { XC_PDP11, "pdp11" }, 256 { XC_23, "i370" }, 257 { XC_Z8K, "z8000" }, 258 { XC_8086, "i86" }, 259 { XC_68K, "mc68000" }, 260 { XC_Z80, "x80" }, 261 { XC_VAX, "vax" }, 262 { XC_16032, "ns16032" }, 263 { XC_286, "i286" }, 264 { XC_386, "i386" }, 265 { XC_S370, "xa370" }, 266 { 0, NULL } 267 }; 268 269 /* 270 * our local hack table, stolen from x.out.h 271 */ 272 static char * 273 getxcode(xcid) 274 short xcid; 275 { 276 int i; 277 278 for (i = 0; xcpu[i].xc_name != NULL; i++) 279 if (xcpu[i].xc_id == xcid) 280 return (xcpu[i].xc_name); 281 return (NULL); 282 } 283 284 static short 285 getxid(xcname) 286 char *xcname; 287 { 288 int i; 289 290 for (i = 0; xcpu[i].xc_name != NULL; i++) 291 if (strcmp(xcpu[i].xc_name, xcname) == 0) 292 return (xcpu[i].xc_id); 293 return ((short) -1); 294 } 295 296 297 /*ARGSUSED*/ 298 void 299 dogetspath(v, c) 300 Char **v; 301 struct command *c; 302 { 303 int i, j; 304 sitepath_t p[MAXSITE]; 305 struct sf *st; 306 static char *local = "LOCAL "; 307 308 if ((j = getspath(p, MAXSITE)) == -1) 309 stderror(ERR_SYSTEM, "getspath", strerror(errno)); 310 for (i = 0; i < j && (p[i] & SPATH_CPU) != NOSITE; i++) { 311 if (p[i] & SPATH_CPU) { 312 if ((p[i] & SPATH_MASK) == NULLSITE) 313 xprintf(local); 314 else if ((st = sfxcode((short) (p[i] & SPATH_MASK))) != NULL) 315 xprintf("%s ", st->sf_ctype); 316 else { 317 char *xc = getxcode(p[i] & SPATH_MASK); 318 319 if (xc != NULL) 320 xprintf("%s ", xc); 321 else 322 xprintf("*cpu %d* ", (int) (p[i] & SPATH_MASK)); 323 /* 324 * BUG in the aix code... needs that cause if 325 * sfxcode fails once it fails for ever 326 */ 327 endsf(); 328 } 329 } 330 else { 331 if (p[i] == NULLSITE) 332 xprintf(local); 333 else if ((st = sfnum(p[i])) != NULL) 334 xprintf("%s ", st->sf_sname); 335 else 336 xprintf("*site %d* ", (int) (p[i] & SPATH_MASK)); 337 } 338 } 339 xputchar('\n'); 340 flush(); 341 } 342 343 /*ARGSUSED*/ 344 void 345 dosetspath(v, c) 346 Char **v; 347 struct command *c; 348 { 349 int i; 350 short j; 351 char *s; 352 sitepath_t p[MAXSITE]; 353 struct sf *st; 354 355 /* 356 * sfname() on AIX G9.9 at least, mallocs too pointers p, q 357 * then does the equivalent of while (*p++ == *q++) continue; 358 * and then tries to free(p,q) them! Congrats to the wizard who 359 * wrote that one. I bet he tested it really well too. 360 * Sooo, we set dont_free :-) 361 */ 362 dont_free = 1; 363 for (i = 0, v++; *v && *v[0] != '\0'; v++, i++) { 364 s = short2str(*v); 365 if (isdigit(*s)) 366 p[i] = atoi(s); 367 else if (strcmp(s, "LOCAL") == 0) 368 p[i] = NULLSITE; 369 else if ((st = sfctype(s)) != NULL) 370 p[i] = SPATH_CPU | st->sf_ccode; 371 else if ((j = getxid(s)) != -1) 372 p[i] = SPATH_CPU | j; 373 else if ((st = sfname(s)) != NULL) 374 p[i] = st->sf_id; 375 else { 376 setname(s); 377 stderror(ERR_NAME | ERR_STRING, CGETS(23, 1, "Bad cpu/site name")); 378 } 379 if (i == MAXSITE - 1) 380 stderror(ERR_NAME | ERR_STRING, CGETS(23, 2, "Site path too long")); 381 } 382 if (setspath(p, i) == -1) 383 stderror(ERR_SYSTEM, "setspath", strerror(errno)); 384 dont_free = 0; 385 } 386 387 /* sitename(): 388 * Return the site name where the process is running 389 */ 390 char * 391 sitename(pid) 392 pid_t pid; 393 { 394 siteno_t ss; 395 struct sf *st; 396 397 if ((ss = site(pid)) == -1 || (st = sfnum(ss)) == NULL) 398 return CGETS(23, 3, "unknown"); 399 else 400 return st->sf_sname; 401 } 402 403 static int 404 migratepid(pid, new_site) 405 pid_t pid; 406 siteno_t new_site; 407 { 408 struct sf *st; 409 int need_local; 410 411 need_local = (pid == 0) || (pid == getpid()); 412 413 if (kill3((pid_t) pid, SIGMIGRATE, new_site) < 0) { 414 xprintf("%d: %s\n", pid, strerror(errno)); 415 return (-1); 416 } 417 418 if (need_local) { 419 if ((new_site = site(0)) == -1) { 420 xprintf(CGETS(23, 4, "site: %s\n"), strerror(errno)); 421 return (-1); 422 } 423 if ((st = sfnum(new_site)) == NULL) { 424 xprintf(CGETS(23, 5, "%d: Site not found\n"), new_site); 425 return (-1); 426 } 427 if (setlocal(st->sf_local, strlen(st->sf_local)) == -1) { 428 xprintf(CGETS(23, 6, "setlocal: %s: %s\n"), 429 st->sf_local, strerror(errno)); 430 return (-1); 431 } 432 } 433 return (0); 434 } 435 436 /*ARGSUSED*/ 437 void 438 domigrate(v, c) 439 Char **v; 440 struct command *c; 441 { 442 struct sf *st; 443 char *s; 444 Char *cp; 445 struct process *pp; 446 int err1 = 0; 447 int pid = 0; 448 siteno_t new_site = 0; 449 sigmask_t omask; 450 451 #ifdef BSDSIGS 452 omask = sigmask(SIGCHLD); 453 if (setintr) 454 omask |= sigmask(SIGINT); 455 omask = sigblock(omask) & ~omask; 456 #else 457 if (setintr) 458 (void) sighold(SIGINT); 459 (void) sighold(SIGCHLD); 460 #endif /* BSDSIGS */ 461 462 ++v; 463 if (*v[0] == '-') { 464 /* 465 * Do the -site. 466 */ 467 s = short2str(&v[0][1]); 468 /* 469 * see comment in setspath() 470 */ 471 dont_free = 1; 472 if ((st = sfname(s)) == NULL) { 473 setname(s); 474 stderror(ERR_NAME | ERR_STRING, CGETS(23, 7, "Site not found")); 475 } 476 dont_free = 0; 477 new_site = st->sf_id; 478 ++v; 479 } 480 481 if (!*v || *v[0] == '\0') { 482 if (migratepid(0, new_site) == -1) 483 err1++; 484 } 485 else { 486 gflag = 0, tglob(v); 487 if (gflag) { 488 v = globall(v); 489 if (v == 0) 490 stderror(ERR_NAME | ERR_NOMATCH); 491 } 492 else { 493 v = gargv = saveblk(v); 494 trim(v); 495 } 496 497 while (v && (cp = *v)) { 498 if (*cp == '%') { 499 pp = pfind(cp); 500 if (kill3((pid_t) - pp->p_jobid, SIGMIGRATE, new_site) < 0) { 501 xprintf("%S: %s\n", cp, strerror(errno)); 502 err1++; 503 } 504 } 505 else if (!(Isdigit(*cp) || *cp == '-')) 506 stderror(ERR_NAME | ERR_JOBARGS); 507 else { 508 pid = atoi(short2str(cp)); 509 if (migratepid(pid, new_site) == -1) 510 err1++; 511 } 512 v++; 513 } 514 if (gargv) 515 blkfree(gargv), gargv = 0; 516 } 517 518 done: 519 #ifdef BSDSIGS 520 (void) sigsetmask(omask); 521 #else 522 (void) sigrelse(SIGCHLD); 523 if (setintr) 524 (void) sigrelse(SIGINT); 525 #endif /* BSDSIGS */ 526 if (err1) 527 stderror(ERR_SILENT); 528 } 529 530 #endif /* TCF */ 531 532 /*** 533 *** CRAY ddmode <velo@sesun3.epfl.ch> (Martin Ouwehand EPFL-SIC/SE) 534 ***/ 535 #if defined(_CRAY) && !defined(_CRAYMPP) 536 void 537 dodmmode(v, c) 538 Char **v; 539 struct command *c; 540 { 541 Char *cp = v[1]; 542 543 USE(c); 544 545 if ( !cp ) { 546 int mode; 547 548 mode = dmmode(0); 549 dmmode(mode); 550 xprintf("%d\n",mode); 551 } 552 else { 553 if (cp[1] != '\0') 554 stderror(ERR_NAME | ERR_STRING, 555 CGETS(23, 30, "Too many arguments")); 556 else 557 switch(*cp) { 558 case '0': 559 dmmode(0); 560 break; 561 case '1': 562 dmmode(1); 563 break; 564 default: 565 stderror(ERR_NAME | ERR_STRING, 566 CGETS(23, 31, "Invalid argument")); 567 } 568 } 569 } 570 #endif /* _CRAY && !_CRAYMPP */ 571 572 573 /*** 574 *** CONVEX Warps. 575 ***/ 576 577 #ifdef WARP 578 /* 579 * handle the funky warping of symlinks 580 */ 581 #include <warpdb.h> 582 #include <sys/warp.h> 583 584 static jmp_buf sigsys_buf; 585 586 static RETSIGTYPE 587 catch_sigsys() 588 { 589 longjmp(sigsys_buf, 1); 590 } 591 592 593 /*ARGSUSED*/ 594 void 595 dowarp(v, c) 596 Char **v; 597 struct command *c; 598 { 599 int warp, oldwarp; 600 struct warpent *we; 601 void (*old_sigsys_handler) () = 0; 602 char *newwarp; 603 604 if (setjmp(sigsys_buf)) { 605 signal(SIGSYS, old_sigsys_handler); 606 stderror(ERR_NAME | ERR_STRING, 607 CGETS(23, 8, "You're trapped in a universe you never made")); 608 return; 609 } 610 old_sigsys_handler = signal(SIGSYS, catch_sigsys); 611 612 warp = getwarp(); 613 614 v++; 615 if (*v == 0) { /* display warp value */ 616 if (warp < 0) 617 stderror(ERR_NAME | ERR_STRING, CGETS(23, 9, "Getwarp failed")); 618 we = getwarpbyvalue(warp); 619 if (we) 620 printf("%s\n", we->w_name); 621 else 622 printf("%d\n", warp); 623 } 624 else { /* set warp value */ 625 oldwarp = warp; 626 newwarp = short2str(*v); 627 if (Isdigit(*v[0])) 628 warp = atoi(newwarp); 629 else { 630 we = getwarpbyname(newwarp); 631 if (we) 632 warp = we->w_value; 633 else 634 warp = -1; 635 } 636 if ((warp < 0) || (warp >= WARP_MAXLINK)) 637 stderror(ERR_NAME | ERR_STRING, CGETS(23, 10, "Invalid warp")); 638 if ((setwarp(warp) < 0) || (getwarp() != warp)) { 639 (void) setwarp(oldwarp); 640 stderror(ERR_NAME | ERR_STRING, CGETS(23, 11, "Setwarp failed")); 641 } 642 } 643 signal(SIGSYS, old_sigsys_handler); 644 return; 645 } 646 #endif /* WARP */ 647 648 /*** 649 *** Masscomp or HCX 650 ***/ 651 /* Added, DAS DEC-90. */ 652 #if defined(masscomp) || defined(_CX_UX) 653 /*ARGSUSED*/ 654 void 655 douniverse(v, c) 656 Char **v; 657 struct command *c; 658 { 659 Char *cp = v[1]; 660 Char *cp2; /* dunno how many elements v comes in with */ 661 char ubuf[100]; 662 #ifdef BSDSIGS 663 sigmask_t omask = 0; 664 #endif /* BSDSIGS */ 665 666 if (cp == 0) { 667 (void) getuniverse(ubuf); 668 xprintf("%s\n", ubuf); 669 } 670 else { 671 cp2 = v[2]; 672 if (cp2 == 0) { 673 if (*cp == '\0' || setuniverse(short2str(cp)) != 0) 674 stderror(ERR_NAME | ERR_STRING, CGETS(23, 12, "Illegal universe")); 675 } 676 else { 677 (void) getuniverse(ubuf); 678 if (*cp == '\0' || setuniverse(short2str(cp)) != 0) 679 stderror(ERR_NAME | ERR_STRING, CGETS(23, 12, "Illegal universe")); 680 if (setintr) 681 #ifdef BSDSIGS 682 omask = sigblock(sigmask(SIGINT)) & ~sigmask(SIGINT); 683 #else /* !BSDSIGS */ 684 (void) sighold(SIGINT); 685 #endif /* BSDSIGS */ 686 lshift(v, 2); 687 if (setintr) 688 #ifdef BSDSIGS 689 (void) sigsetmask(omask); 690 #else /* !BSDSIGS */ 691 (void) sigrelse (SIGINT); 692 #endif /* BSDSIGS */ 693 reexecute(c); 694 (void) setuniverse(ubuf); 695 } 696 } 697 } 698 #endif /* masscomp || _CX_UX */ 699 700 /*** 701 *** BS2000/OSD POSIX (Fujitsu Siemens Computers) 702 ***/ 703 #if defined(_OSD_POSIX) 704 static int 705 bs2upcase(char *str) 706 { 707 enum { outside = ' ', singlequote='\'', doublequote='"'} string = outside; 708 709 char *white; 710 711 for (white = str + strlen(str) - 1; isspace(*white) && white > str; --white) 712 *white = '\0'; 713 714 for (; *str != '\0'; ++str) 715 { 716 if (string == outside) 717 { 718 *str = toupper (*str); 719 } 720 if (*str == '\'') 721 { 722 if (string == outside) 723 string = singlequote; 724 else if (string != doublequote) 725 string = outside; 726 } 727 else if (*str == '"') 728 { 729 if (string == outside) 730 string = doublequote; 731 else if (string != singlequote) 732 string = outside; 733 } 734 } 735 if (string != outside) 736 { 737 stderror(ERR_NAME | ERR_UNMATCHED, (Char) string); 738 return 1; 739 } 740 return 0; 741 } 742 static int 743 bs2cmdlist(char *str) 744 { 745 char *str_beg = NULL; 746 int ret = 0; 747 748 enum { outside = ' ', singlequote='\'', doublequote='"'} string = outside; 749 750 while (*str != '\0') 751 { 752 while (isspace(*str)) 753 ++str; 754 755 if (*str == '\0') 756 break; 757 758 str_beg = str; 759 760 for (; *str != '\0'; ++str) 761 { 762 if (string == outside && *str == ';') /* End of command */ 763 { 764 *str++ = '\0'; 765 break; /* continue with next command */ 766 } 767 if (*str == '\'') 768 { 769 if (string == outside) 770 string = singlequote; 771 else if (string != doublequote) 772 string = outside; 773 } 774 else if (*str == '"') 775 { 776 if (string == outside) 777 string = doublequote; 778 else if (string != singlequote) 779 string = outside; 780 } 781 } 782 if (strlen(str_beg) != 0) 783 { 784 ret = bs2system(str_beg); 785 flush(); 786 if (ret != 0 /*&& !option.err_ignore*/) 787 break; /* do not continue after errors */ 788 } 789 } 790 791 if (string != outside) 792 { 793 stderror(ERR_NAME | ERR_UNMATCHED, (Char) string); 794 return -1; 795 } 796 797 return ret; 798 } 799 /*ARGSUSED*/ 800 void 801 dobs2cmd(v, c) 802 Char **v; 803 struct command *c; 804 { 805 Char *cp; 806 int i = 0, len = 0; 807 char *cmd = NULL; 808 int pvec[2]; 809 struct command faket; 810 Char *fakecom[2]; 811 char tibuf[BUFSIZE]; 812 int icnt; 813 static const Char STRbs2cmd[] = { 'b','s','2','c','m','d','\0' }; 814 815 if (setintr) 816 #ifdef BSDSIGS 817 (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT)); 818 #else /* !BSDSIGS */ 819 (void) sigrelse (SIGINT); 820 #endif /* BSDSIGS */ 821 v++; 822 gflag = 0, tglob(v); 823 if (gflag) { 824 v = globall(v); 825 if (v == 0) 826 stderror(ERR_NAME | ERR_NOMATCH); 827 } 828 else { 829 v = gargv = saveblk(v); 830 trim(v); 831 } 832 833 /* First round: count the string lengths */ 834 for (i=0; v[i]; ++i) { 835 len += s_strlen(v[i]) + (v[i+1] != NULL); 836 } 837 838 cmd = xmalloc(len+1); /* 1 for the final '\0' */ 839 840 /* 2nd round: fill cmd buffer */ 841 i = 0; 842 while ((cp = *v++) != 0) { 843 int c; 844 while (c = *cp++) 845 cmd[i++] = (char)c; 846 if (*v) 847 cmd[i++] = ' '; 848 } 849 cmd[i] = '\0'; 850 851 /* Make upper case */ 852 bs2upcase(cmd); 853 854 faket.t_dtyp = NODE_COMMAND; 855 faket.t_dflg = F_BACKQ|F_STDERR; 856 faket.t_dlef = 0; 857 faket.t_drit = 0; 858 faket.t_dspr = 0; 859 faket.t_dcom = fakecom; 860 fakecom[0] = STRbs2cmd; 861 fakecom[1] = 0; 862 863 mypipe(pvec); 864 if (pfork(&faket, -1) == 0) { 865 /* child */ 866 (void) close(pvec[0]); 867 (void) dmove(pvec[1], 1); 868 (void) dmove(SHDIAG, 2); 869 initdesc(); 870 /* closem();*/ 871 #ifdef SIGTSTP 872 (void) sigignore(SIGTSTP); 873 #endif 874 #ifdef SIGTTIN 875 (void) sigignore(SIGTTIN); 876 #endif 877 #ifdef SIGTTOU 878 (void) sigignore(SIGTTOU); 879 #endif 880 xexit(bs2cmdlist(cmd)); 881 } 882 (void) close(pvec[1]); 883 for(;;) { 884 do 885 icnt = read(pvec[0], tibuf, BUFSIZE); 886 while (icnt == -1 && errno == EINTR); 887 if (icnt <= 0) 888 break; 889 for (i = 0; i < icnt; i++) 890 xputchar((unsigned char) tibuf[i]); 891 } 892 (void) close(pvec[0]); 893 pwait(); 894 895 flush(); 896 897 if (setintr) 898 #ifdef BSDSIGS 899 (void) sigblock(sigmask(SIGINT)); 900 #else /* !BSDSIGS */ 901 (void) sighold(SIGINT); 902 #endif /* BSDSIGS */ 903 if (gargv) 904 blkfree(gargv), gargv = 0; 905 } 906 #endif /* _OSD_POSIX */ 907 908 #if defined(_CX_UX) 909 /*ARGSUSED*/ 910 void 911 doatt(v, c) 912 Char **v; 913 struct command *c; 914 { 915 Char *cp = v[1]; 916 char ubuf[100]; 917 #ifdef BSDSIGS 918 sigmask_t omask = 0; 919 #endif /* BSDSIGS */ 920 921 if (cp == 0) 922 (void) setuniverse("att"); 923 else { 924 (void) getuniverse(ubuf); 925 (void) setuniverse("att"); 926 if (setintr) 927 #ifdef BSDSIGS 928 omask = sigblock(sigmask(SIGINT)) & ~sigmask(SIGINT); 929 #else /* !BSDSIGS */ 930 (void) sighold(SIGINT); 931 #endif /* BSDSIGS */ 932 lshift(v, 1); 933 if (setintr) 934 #ifdef BSDSIGS 935 (void) sigsetmask(omask); 936 #else /* !BSDSIGS */ 937 (void) sigrelse (SIGINT); 938 #endif /* BSDSIGS */ 939 reexecute(c); 940 (void) setuniverse(ubuf); 941 } 942 } 943 944 /*ARGSUSED*/ 945 void 946 doucb(v, c) 947 Char **v; 948 struct command *c; 949 { 950 Char *cp = v[1]; 951 char ubuf[100]; 952 #ifdef BSDSIGS 953 sigmask_t omask = 0; 954 #endif /* BSDSIGS */ 955 956 if (cp == 0) 957 (void) setuniverse("ucb"); 958 else { 959 (void) getuniverse(ubuf); 960 (void) setuniverse("ucb"); 961 if (setintr) 962 #ifdef BSDSIGS 963 omask = sigblock(sigmask(SIGINT)) & ~sigmask(SIGINT); 964 #else /* !BSDSIGS */ 965 (void) sighold(SIGINT); 966 #endif /* BSDSIGS */ 967 lshift(v, 1); 968 if (setintr) 969 #ifdef BSDSIGS 970 (void) sigsetmask(omask); 971 #else /* !BSDSIGS */ 972 (void) sigrelse (SIGINT); 973 #endif /* BSDSIGS */ 974 reexecute(c); 975 (void) setuniverse(ubuf); 976 } 977 } 978 #endif /* _CX_UX */ 979 980 #ifdef _SEQUENT_ 981 /* 982 * Compute the difference in process stats. 983 */ 984 void 985 pr_stat_sub(p2, p1, pr) 986 struct process_stats *p2, *p1, *pr; 987 { 988 pr->ps_utime.tv_sec = p2->ps_utime.tv_sec - p1->ps_utime.tv_sec; 989 pr->ps_utime.tv_usec = p2->ps_utime.tv_usec - p1->ps_utime.tv_usec; 990 if (pr->ps_utime.tv_usec < 0) { 991 pr->ps_utime.tv_sec -= 1; 992 pr->ps_utime.tv_usec += 1000000; 993 } 994 pr->ps_stime.tv_sec = p2->ps_stime.tv_sec - p1->ps_stime.tv_sec; 995 pr->ps_stime.tv_usec = p2->ps_stime.tv_usec - p1->ps_stime.tv_usec; 996 if (pr->ps_stime.tv_usec < 0) { 997 pr->ps_stime.tv_sec -= 1; 998 pr->ps_stime.tv_usec += 1000000; 999 } 1000 1001 pr->ps_maxrss = p2->ps_maxrss - p1->ps_maxrss; 1002 pr->ps_pagein = p2->ps_pagein - p1->ps_pagein; 1003 pr->ps_reclaim = p2->ps_reclaim - p1->ps_reclaim; 1004 pr->ps_zerofill = p2->ps_zerofill - p1->ps_zerofill; 1005 pr->ps_pffincr = p2->ps_pffincr - p1->ps_pffincr; 1006 pr->ps_pffdecr = p2->ps_pffdecr - p1->ps_pffdecr; 1007 pr->ps_swap = p2->ps_swap - p1->ps_swap; 1008 pr->ps_syscall = p2->ps_syscall - p1->ps_syscall; 1009 pr->ps_volcsw = p2->ps_volcsw - p1->ps_volcsw; 1010 pr->ps_involcsw = p2->ps_involcsw - p1->ps_involcsw; 1011 pr->ps_signal = p2->ps_signal - p1->ps_signal; 1012 pr->ps_lread = p2->ps_lread - p1->ps_lread; 1013 pr->ps_lwrite = p2->ps_lwrite - p1->ps_lwrite; 1014 pr->ps_bread = p2->ps_bread - p1->ps_bread; 1015 pr->ps_bwrite = p2->ps_bwrite - p1->ps_bwrite; 1016 pr->ps_phread = p2->ps_phread - p1->ps_phread; 1017 pr->ps_phwrite = p2->ps_phwrite - p1->ps_phwrite; 1018 } 1019 1020 #endif /* _SEQUENT_ */ 1021 1022 1023 #ifndef HAVE_MEMSET 1024 /* This is a replacement for a missing memset function */ 1025 ptr_t xmemset(loc, value, len) 1026 ptr_t loc; 1027 int len; 1028 size_t value; 1029 { 1030 char *ptr = (char *) loc; 1031 1032 while (len--) 1033 *ptr++ = value; 1034 return loc; 1035 } 1036 #endif /* !HAVE_MEMSET */ 1037 1038 1039 #ifndef HAVE_MEMMOVE 1040 /* memmove(): 1041 * This is the ANSI form of bcopy() with the arguments backwards... 1042 * Unlike memcpy(), it handles overlaps between source and 1043 * destination memory 1044 */ 1045 ptr_t 1046 xmemmove(vdst, vsrc, len) 1047 ptr_t vdst; 1048 const ptr_t vsrc; 1049 size_t len; 1050 { 1051 const char *src = (const char *) vsrc; 1052 char *dst = (char *) vdst; 1053 1054 if (src == dst) 1055 return vdst; 1056 1057 if (src > dst) { 1058 while (len--) 1059 *dst++ = *src++; 1060 } 1061 else { 1062 src += len; 1063 dst += len; 1064 while (len--) 1065 *--dst = *--src; 1066 } 1067 return vdst; 1068 } 1069 #endif /* HAVE_MEMMOVE */ 1070 1071 1072 #ifndef WINNT_NATIVE 1073 #ifdef NEEDtcgetpgrp 1074 int 1075 xtcgetpgrp(fd) 1076 int fd; 1077 { 1078 int pgrp; 1079 1080 /* ioctl will handle setting errno correctly. */ 1081 if (ioctl(fd, TIOCGPGRP, (ioctl_t) & pgrp) < 0) 1082 return (-1); 1083 return (pgrp); 1084 } 1085 1086 /* 1087 * XXX: tcsetpgrp is not a macro any more cause on some systems, 1088 * pid_t is a short, but the ioctl() takes a pointer to int (pyr) 1089 * Thanks to Simon Day (simon@pharaoh.cyborg.bt.co.uk) for pointing 1090 * this out. 1091 */ 1092 int 1093 xtcsetpgrp(fd, pgrp) 1094 int fd, pgrp; 1095 { 1096 return ioctl(fd, TIOCSPGRP, (ioctl_t) &pgrp); 1097 } 1098 1099 #endif /* NEEDtcgetpgrp */ 1100 #endif /* WINNT_NATIVE */ 1101 1102 1103 #ifdef YPBUGS 1104 void 1105 fix_yp_bugs() 1106 { 1107 char *mydomain; 1108 1109 extern int yp_get_default_domain __P((char **)); 1110 /* 1111 * PWP: The previous version assumed that yp domain was the same as the 1112 * internet name domain. This isn't allways true. (Thanks to Mat Landau 1113 * <mlandau@bbn.com> for the original version of this.) 1114 */ 1115 if (yp_get_default_domain(&mydomain) == 0) { /* if we got a name */ 1116 extern void yp_unbind __P((const char *)); 1117 1118 yp_unbind(mydomain); 1119 } 1120 } 1121 1122 #endif /* YPBUGS */ 1123 1124 #ifdef STRCOLLBUG 1125 void 1126 fix_strcoll_bug() 1127 { 1128 #if defined(NLS) && !defined(NOSTRCOLL) 1129 /* 1130 * SunOS4 checks the file descriptor from openlocale() for <= 0 1131 * instead of == -1. Someone should tell sun that file descriptor 0 1132 * is valid! Our portable hack: open one so we call it with 0 used... 1133 * We have to call this routine every time the locale changes... 1134 * 1135 * Of course it also tries to free the constant locale "C" it initially 1136 * had allocated, with the sequence 1137 * > setenv LANG "fr" 1138 * > ls^D 1139 * > unsetenv LANG 1140 * But we are smarter than that and just print a warning message. 1141 */ 1142 int fd = -1; 1143 static char *root = "/"; 1144 1145 if (!didfds) 1146 fd = open(root, O_RDONLY|O_LARGEFILE); 1147 1148 (void) strcoll(root, root); 1149 1150 if (fd != -1) 1151 (void) close(fd); 1152 #endif 1153 } 1154 #endif /* STRCOLLBUG */ 1155 1156 1157 #ifdef OREO 1158 #include <compat.h> 1159 #endif /* OREO */ 1160 1161 void 1162 osinit() 1163 { 1164 #ifdef OREO 1165 set42sig(); 1166 setcompat(getcompat() & ~COMPAT_EXEC); 1167 sigignore(SIGIO); /* ignore SIGIO */ 1168 #endif /* OREO */ 1169 1170 #ifdef aiws 1171 { 1172 struct sigstack inst; 1173 inst.ss_sp = (char *) xmalloc((size_t) 4192) + 4192; 1174 inst.ss_onstack = 0; 1175 sigstack(&inst, NULL); 1176 } 1177 #endif /* aiws */ 1178 1179 #ifdef apollo 1180 (void) isapad(); 1181 #endif 1182 1183 #ifdef _SX 1184 /* 1185 * kill(SIGCONT) problems, don't know what this syscall does 1186 * [schott@rzg.mpg.de] 1187 */ 1188 syscall(151, getpid(), getpid()); 1189 #endif /* _SX */ 1190 } 1191 1192 #ifndef HAVE_STRERROR 1193 char * 1194 xstrerror(i) 1195 int i; 1196 { 1197 static char errbuf[128]; 1198 1199 if (i >= 0 && i < sys_nerr) { 1200 return sys_errlist[i]; 1201 } else { 1202 (void) xsnprintf(errbuf, sizeof(errbuf), 1203 CGETS(23, 13, "Unknown Error: %d"), i); 1204 return errbuf; 1205 } 1206 } 1207 #endif /* !HAVE_STRERROR */ 1208 1209 #ifndef HAVE_GETHOSTNAME 1210 # if !defined(_MINIX) && !defined(__EMX__) && !defined(WINNT_NATIVE) 1211 # include <sys/utsname.h> 1212 # endif /* !_MINIX && !__EMX__ && !WINNT_NATIVE */ 1213 1214 int 1215 xgethostname(name, namlen) 1216 char *name; 1217 int namlen; 1218 { 1219 # if !defined(_MINIX) && !defined(__EMX__) && !defined(WINNT_NATIVE) 1220 int i, retval; 1221 struct utsname uts; 1222 1223 retval = uname(&uts); 1224 1225 # ifdef DEBUG 1226 xprintf(CGETS(23, 14, "sysname: %s\n"), uts.sysname); 1227 xprintf(CGETS(23, 15, "nodename: %s\n"), uts.nodename); 1228 xprintf(CGETS(23, 16, "release: %s\n"), uts.release); 1229 xprintf(CGETS(23, 17, "version: %s\n"), uts.version); 1230 xprintf(CGETS(23, 18, "machine: %s\n"), uts.machine); 1231 # endif /* DEBUG */ 1232 i = strlen(uts.nodename) + 1; 1233 (void) strncpy(name, uts.nodename, i < namlen ? i : namlen); 1234 1235 return retval; 1236 # else /* !_MINIX && !__EMX__ */ 1237 if (namlen > 0) { 1238 # ifdef __EMX__ 1239 (void) strncpy(name, "OS/2", namlen); 1240 # else /* _MINIX */ 1241 (void) strncpy(name, "minix", namlen); 1242 # endif /* __EMX__ */ 1243 name[namlen-1] = '\0'; 1244 } 1245 return(0); 1246 #endif /* _MINIX && !__EMX__ */ 1247 } /* end xgethostname */ 1248 #endif /* !HAVE_GETHOSTNAME */ 1249 1250 #ifndef HAVE_NICE 1251 # if defined(_MINIX) && defined(NICE) 1252 # undef _POSIX_SOURCE /* redefined in <lib.h> */ 1253 # undef _MINIX /* redefined in <lib.h> */ 1254 # undef HZ /* redefined in <minix/const.h> */ 1255 # include <lib.h> 1256 # endif /* _MINIX && NICE */ 1257 int 1258 xnice(incr) 1259 int incr; 1260 { 1261 #if defined(_MINIX) && defined(NICE) 1262 return callm1(MM, NICE, incr, 0, 0, NIL_PTR, NIL_PTR, NIL_PTR); 1263 #else 1264 return /* incr ? 0 : */ 0; 1265 #endif /* _MINIX && NICE */ 1266 } /* end xnice */ 1267 #endif /* !HAVE_NICE */ 1268 1269 #ifndef HAVE_GETCWD 1270 static char *strnrcpy __P((char *, char *, size_t)); 1271 1272 /* xgetcwd(): 1273 * Return the pathname of the current directory, or return 1274 * an error message in pathname. 1275 */ 1276 1277 # ifdef hp9000s500 1278 /* 1279 * From: Bernd Mohr <mohr@faui77.informatik.uni-erlangen.de> 1280 * I also ported the tcsh to the HP9000 Series 500. This computer 1281 * is a little bit different than the other HP 9000 computer. It has 1282 * a HP Chip instead of a Motorola CPU and it is no "real" UNIX. It runs 1283 * HP-UX which is emulated in top of a HP operating system. So, the last 1284 * supported version of HP-UX is 5.2 on the HP9000s500. This has two 1285 * consequences: it supports no job control and it has a filesystem 1286 * without "." and ".." !!! 1287 */ 1288 char * 1289 xgetcwd(pathname, pathlen) 1290 char *pathname; 1291 size_t pathlen; 1292 { 1293 char pathbuf[MAXNAMLEN]; /* temporary pathname buffer */ 1294 char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */ 1295 dev_t rdev; /* root device number */ 1296 DIR *dirp = NULL; /* directory stream */ 1297 ino_t rino; /* root inode number */ 1298 off_t rsize; /* root size */ 1299 struct direct *dir; /* directory entry struct */ 1300 struct stat d, dd; /* file status struct */ 1301 int serrno; 1302 1303 *pnptr = '\0'; 1304 (void) stat("/.", &d); 1305 rdev = d.st_dev; 1306 rino = d.st_ino; 1307 rsize = d.st_size; 1308 for (;;) { 1309 if (stat(".", &d) == -1) { 1310 (void) xsnprintf(pathname, pathlen, CGETS(23, 24, 1311 "getcwd: Cannot stat \".\" (%s)"), strerror(errno)); 1312 goto fail; 1313 } 1314 if (d.st_ino == rino && d.st_dev == rdev && d.st_size == rsize) 1315 break; /* reached root directory */ 1316 if ((dirp = opendir("..")) == NULL) { 1317 (void) xsnprintf(pathname, pathlen, CGETS(23, 19, 1318 "getcwd: Cannot open \"..\" (%s)"), strerror(errno)); 1319 goto fail; 1320 } 1321 if (chdir("..") == -1) { 1322 (void) xsnprintf(pathname, pathlen, CGETS(23, 20, 1323 "getcwd: Cannot chdir to \"..\" (%s)"), strerror(errno)); 1324 goto fail; 1325 } 1326 do { 1327 if ((dir = readdir(dirp)) == NULL) { 1328 (void) xsnprintf(pathname, pathlen, 1329 CGETS(23, 21, "getcwd: Read error in \"..\" (%s)"), 1330 strerror(errno)); 1331 goto fail; 1332 } 1333 if (stat(dir->d_name, &dd) == -1) { 1334 (void) xsnprintf(pathname, pathlen, 1335 CGETS(23, 25, "getcwd: Cannot stat directory \"%s\" (%s)"), 1336 dir->d_name, strerror(errno)); 1337 goto fail; 1338 } 1339 } while (dd.st_ino != d.st_ino || 1340 dd.st_dev != d.st_dev || 1341 dd.st_size != d.st_size); 1342 (void) closedir(dirp); 1343 dirp = NULL; 1344 pnptr = strnrcpy(dirp->d_name, pnptr, pnptr - pathbuf); 1345 pnptr = strnrcpy("/", pnptr, pnptr - pathbuf); 1346 } 1347 1348 if (*pnptr == '\0') /* current dir == root dir */ 1349 (void) strncpy(pathname, "/", pathlen); 1350 else { 1351 (void) strncpy(pathname, pnptr, pathlen); 1352 pathname[pathlen - 1] = '\0'; 1353 if (chdir(pnptr) == -1) { 1354 (void) xsnprintf(pathname, MAXPATHLEN, CGETS(23, 22, 1355 "getcwd: Cannot change back to \".\" (%s)"), 1356 strerror(errno)); 1357 return NULL; 1358 } 1359 } 1360 return pathname; 1361 1362 fail: 1363 serrno = errno; 1364 (void) chdir(strnrcpy(".", pnptr, pnptr - pathbuf)); 1365 errno = serrno; 1366 return NULL; 1367 } 1368 1369 # else /* ! hp9000s500 */ 1370 1371 1372 char * 1373 xgetcwd(pathname, pathlen) 1374 char *pathname; 1375 size_t pathlen; 1376 { 1377 DIR *dp; 1378 struct dirent *d; 1379 1380 struct stat st_root, st_cur, st_next, st_dotdot; 1381 char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2]; 1382 char *pathptr, *nextpathptr, *cur_name_add; 1383 int save_errno = 0; 1384 1385 /* find the inode of root */ 1386 if (stat("/", &st_root) == -1) { 1387 (void) xsnprintf(pathname, pathlen, CGETS(23, 23, 1388 "getcwd: Cannot stat \"/\" (%s)"), 1389 strerror(errno)); 1390 return NULL; 1391 } 1392 pathbuf[MAXPATHLEN - 1] = '\0'; 1393 pathptr = &pathbuf[MAXPATHLEN - 1]; 1394 nextpathbuf[MAXPATHLEN - 1] = '\0'; 1395 cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1]; 1396 1397 /* find the inode of the current directory */ 1398 if (lstat(".", &st_cur) == -1) { 1399 (void) xsnprintf(pathname, pathlen, CGETS(23, 24, 1400 "getcwd: Cannot stat \".\" (%s)"), 1401 strerror(errno)); 1402 return NULL; 1403 } 1404 nextpathptr = strnrcpy(nextpathptr, "../", nextpathptr - nextpathbuf); 1405 1406 /* Descend to root */ 1407 for (;;) { 1408 1409 /* look if we found root yet */ 1410 if (st_cur.st_ino == st_root.st_ino && 1411 DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) { 1412 (void) strncpy(pathname, *pathptr != '/' ? "/" : pathptr, pathlen); 1413 pathname[pathlen - 1] = '\0'; 1414 return pathname; 1415 } 1416 1417 /* open the parent directory */ 1418 if (stat(nextpathptr, &st_dotdot) == -1) { 1419 (void) xsnprintf(pathname, pathlen, CGETS(23, 25, 1420 "getcwd: Cannot stat directory \"%s\" (%s)"), 1421 nextpathptr, strerror(errno)); 1422 return NULL; 1423 } 1424 if ((dp = opendir(nextpathptr)) == NULL) { 1425 (void) xsnprintf(pathname, pathlen, CGETS(23, 26, 1426 "getcwd: Cannot open directory \"%s\" (%s)"), 1427 nextpathptr, strerror(errno)); 1428 return NULL; 1429 } 1430 1431 /* look in the parent for the entry with the same inode */ 1432 if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) { 1433 /* Parent has same device. No need to stat every member */ 1434 for (d = readdir(dp); d != NULL; d = readdir(dp)) { 1435 #ifdef __clipper__ 1436 if (((unsigned long)d->d_ino & 0xffff) == st_cur.st_ino) 1437 break; 1438 #else 1439 if (d->d_ino == st_cur.st_ino) 1440 break; 1441 #endif 1442 } 1443 } 1444 else { 1445 /* 1446 * Parent has a different device. This is a mount point so we 1447 * need to stat every member 1448 */ 1449 for (d = readdir(dp); d != NULL; d = readdir(dp)) { 1450 if (ISDOT(d->d_name) || ISDOTDOT(d->d_name)) 1451 continue; 1452 (void)strncpy(cur_name_add, d->d_name, 1453 (size_t) (&nextpathbuf[sizeof(nextpathbuf) - 1] - cur_name_add)); 1454 if (lstat(nextpathptr, &st_next) == -1) { 1455 /* 1456 * We might not be able to stat() some path components 1457 * if we are using afs, but this is not an error as 1458 * long as we find the one we need; we also save the 1459 * first error to report it if we don't finally succeed. 1460 */ 1461 if (save_errno == 0) 1462 save_errno = errno; 1463 continue; 1464 } 1465 /* check if we found it yet */ 1466 if (st_next.st_ino == st_cur.st_ino && 1467 DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev)) 1468 break; 1469 } 1470 } 1471 if (d == NULL) { 1472 (void) xsnprintf(pathname, pathlen, CGETS(23, 27, 1473 "getcwd: Cannot find \".\" in \"..\" (%s)"), 1474 strerror(save_errno ? save_errno : ENOENT)); 1475 (void) closedir(dp); 1476 return NULL; 1477 } 1478 else 1479 save_errno = 0; 1480 st_cur = st_dotdot; 1481 pathptr = strnrcpy(pathptr, d->d_name, pathptr - pathbuf); 1482 pathptr = strnrcpy(pathptr, "/", pathptr - pathbuf); 1483 nextpathptr = strnrcpy(nextpathptr, "../", nextpathptr - nextpathbuf); 1484 *cur_name_add = '\0'; 1485 (void) closedir(dp); 1486 } 1487 } /* end getcwd */ 1488 # endif /* hp9000s500 */ 1489 1490 /* strnrcpy(): 1491 * Like strncpy, going backwards and returning the new pointer 1492 */ 1493 static char * 1494 strnrcpy(ptr, str, siz) 1495 char *ptr, *str; 1496 size_t siz; 1497 { 1498 int len = strlen(str); 1499 if (siz == 0) 1500 return ptr; 1501 1502 while (len && siz--) 1503 *--ptr = str[--len]; 1504 1505 return (ptr); 1506 } /* end strnrcpy */ 1507 #endif /* !HAVE_GETCWD */ 1508 1509 #ifdef apollo 1510 /*** 1511 *** Domain/OS 1512 ***/ 1513 #include <apollo/base.h> 1514 #include <apollo/loader.h> 1515 #include <apollo/error.h> 1516 1517 1518 static char * 1519 apperr(st) 1520 status_$t *st; 1521 { 1522 static char buf[BUFSIZE]; 1523 short e_subl, e_modl, e_codel; 1524 error_$string_t e_sub, e_mod, e_code; 1525 1526 error_$get_text(*st, e_sub, &e_subl, e_mod, &e_modl, e_code, &e_codel); 1527 e_sub[e_subl] = '\0'; 1528 e_code[e_codel] = '\0'; 1529 e_mod[e_modl] = '\0'; 1530 (void) xsnprintf(buf, sizeof(buf), "%s (%s/%s)", e_code, e_sub, e_mod); 1531 1532 return(buf); 1533 } 1534 1535 static int 1536 llib(s) 1537 Char *s; 1538 { 1539 short len = Strlen(s); 1540 status_$t st; 1541 char *t; 1542 1543 loader_$inlib(t = short2str(s), len, &st); 1544 if (st.all != status_$ok) 1545 stderror(ERR_SYSTEM, t, apperr(&st)); 1546 } 1547 1548 /*ARGSUSED*/ 1549 void 1550 doinlib(v, c) 1551 Char **v; 1552 struct command *c; 1553 { 1554 setname(short2str(*v++)); 1555 gflag = 0, tglob(v); 1556 if (gflag) { 1557 v = globall(v); 1558 if (v == 0) 1559 stderror(ERR_NAME | ERR_NOMATCH); 1560 } 1561 else { 1562 v = gargv = saveblk(v); 1563 trim(v); 1564 } 1565 1566 while (v && *v) 1567 llib(*v++); 1568 if (gargv) 1569 blkfree(gargv), gargv = 0; 1570 } 1571 1572 int 1573 getv(v) 1574 Char *v; 1575 { 1576 if (eq(v, STRbsd43)) 1577 return(1); 1578 else if (eq(v, STRsys53)) 1579 return(0); 1580 else 1581 stderror(ERR_NAME | ERR_SYSTEM, short2str(v), 1582 CGETS(23, 28, "Invalid system type")); 1583 /*NOTREACHED*/ 1584 return(0); 1585 } 1586 1587 /*ARGSUSED*/ 1588 void 1589 dover(v, c) 1590 Char **v; 1591 struct command *c; 1592 { 1593 Char *p; 1594 1595 setname(short2str(*v++)); 1596 if (!*v) { 1597 if (!(p = tgetenv(STRSYSTYPE))) 1598 stderror(ERR_NAME | ERR_STRING, 1599 CGETS(23, 29, "System type is not set")); 1600 xprintf("%S\n", p); 1601 } 1602 else { 1603 tsetenv(STRSYSTYPE, getv(*v) ? STRbsd43 : STRsys53); 1604 dohash(NULL, NULL); 1605 } 1606 } 1607 1608 /* 1609 * Many thanks to rees@citi.umich.edu (Jim Rees) and 1610 * mathys@ssdt-tempe.sps.mot.com (Yves Mathys) 1611 * For figuring out how to do this... I could have never done 1612 * it without their help. 1613 */ 1614 typedef short enum { 1615 name_$wdir_type, 1616 name_$ndir_type, 1617 name_$node_dir_type, 1618 } name_$dir_type_t; 1619 1620 /*ARGSUSED*/ 1621 void 1622 dorootnode(v, c) 1623 Char **v; 1624 struct command *c; 1625 { 1626 name_$dir_type_t dirtype = name_$node_dir_type; 1627 uid_$t uid; 1628 status_$t st; 1629 char *name; 1630 short namelen; 1631 1632 setname(short2str(*v++)); 1633 1634 name = short2str(*v); 1635 namelen = strlen(name); 1636 1637 name_$resolve(name, &namelen, &uid, &st); 1638 if (st.all != status_$ok) 1639 stderror(ERR_SYSTEM, name, apperr(&st)); 1640 namelen = 0; 1641 name_$set_diru(&uid, "", &namelen, &dirtype, &st); 1642 if (st.all != status_$ok) 1643 stderror(ERR_SYSTEM, name, apperr(&st)); 1644 dohash(NULL, NULL); 1645 } 1646 1647 int 1648 isapad() 1649 { 1650 static int res = -1; 1651 static status_$t st; 1652 1653 if (res == -1) { 1654 int strm; 1655 if (isatty(0)) 1656 strm = 0; 1657 if (isatty(1)) 1658 strm = 1; 1659 if (isatty(2)) 1660 strm = 2; 1661 else { 1662 res = 0; 1663 st.all = status_$ok; 1664 return(res); 1665 } 1666 res = stream_$isavt(&strm, &st); 1667 res = res ? 1 : 0; 1668 } 1669 else { 1670 if (st.all != status_$ok) 1671 stderror(ERR_SYSTEM, "stream_$isavt", apperr(&st)); 1672 } 1673 return(res); 1674 } 1675 #endif 1676