// ImportSpec = ["." | PackageName] ImportPath Node* Parser::importspec() { Node* result = new Node("ImportSpec"); Node* tmp_node; if (tmp_node = accept_terminal("Token", Symboltable::dot)) { result->add_child(tmp_node); result->add_child(importpath()); return result; } else if (tmp_node = accept_terminal("Identifier", Symboltable::ident)) { result->add_child(tmp_node); result->add_child(importpath()); return result; } else { result->add_child(importpath()); return result; } }
char *E_spooldir = "c:\uupc\spool"; /*--------------------------------------------------------------------*/ /* m a i n */ /* */ /* Main program to test importpath() */ /*--------------------------------------------------------------------*/ void main( int argc , char **argv ) { char canon[FILENAME_MAX]; char host[FILENAME_MAX]; size_t count; banner( argv ); /* Out of habit, I guess */ assert( argc > 2 ); for( count = 2; count < argc; count++) { printf("main: Processing arg[%d]=\"%s\"\n", count, argv[count] ); importpath( canon, argv[count], argv[1] ); printf("import remote(%s)\thost(%s)\t yields canon(%s)\n", argv[1], argv[count] , canon); fflush( stdout ); if ( strchr( argv[count], '/' ) == NULL ) { exportpath( host, canon, argv[ 1 ] ); printf("export remote(%s)\tcanon(%s)\t yields host(%s)\n", argv[1], canon, host ); } /* if */ } /* for */ } /* main */
int main(int argc, char *argv[]) { struct sigaction oact; Char *cp; char *tcp, **tempv; const char *ecp; sigset_t nsigset; int f; cshin = stdin; cshout = stdout; csherr = stderr; setprogname(argv[0]); settimes(); /* Immed. estab. timing base */ /* * Initialize non constant strings */ #ifdef _PATH_BSHELL STR_BSHELL = SAVE(_PATH_BSHELL); #endif #ifdef _PATH_CSHELL STR_SHELLPATH = SAVE(_PATH_CSHELL); #endif STR_environ = blk2short(environ); environ = short2blk(STR_environ); /* So that we can free it */ STR_WORD_CHARS = SAVE(WORD_CHARS); HIST = '!'; HISTSUB = '^'; word_chars = STR_WORD_CHARS; tempv = argv; if (eq(str2short(tempv[0]), STRaout)) /* A.out's are quittable */ quitit = 1; uid = getuid(); gid = getgid(); euid = geteuid(); egid = getegid(); /* * We are a login shell if: 1. we were invoked as -<something> and we had * no arguments 2. or we were invoked only with the -l flag */ loginsh = (**tempv == '-' && argc == 1) || (argc == 2 && tempv[1][0] == '-' && tempv[1][1] == 'l' && tempv[1][2] == '\0'); if (loginsh && **tempv != '-') { /* * Mangle the argv space */ tempv[1][0] = '\0'; tempv[1][1] = '\0'; tempv[1] = NULL; for (tcp = *tempv; *tcp++;) continue; for (tcp--; tcp >= *tempv; tcp--) tcp[1] = tcp[0]; *++tcp = '-'; argc--; } if (loginsh) (void)time(&chktim); AsciiOnly = 1; #ifdef NLS (void)setlocale(LC_ALL, ""); { int k; for (k = 0200; k <= 0377 && !Isprint(k); k++) continue; AsciiOnly = k > 0377; } #else AsciiOnly = getenv("LANG") == NULL && getenv("LC_CTYPE") == NULL; #endif /* NLS */ /* * Move the descriptors to safe places. The variable didfds is 0 while we * have only FSH* to work with. When didfds is true, we have 0,1,2 and * prefer to use these. */ initdesc(); /* * XXX: This is to keep programs that use stdio happy. * what we really want is freunopen() .... * Closing cshin cshout and csherr (which are really stdin stdout * and stderr at this point and then reopening them in the same order * gives us again stdin == cshin stdout == cshout and stderr == csherr. * If that was not the case builtins like printf that use stdio * would break. But in any case we could fix that with memcpy and * a bit of pointer manipulation... * Fortunately this is not needed under the current implementation * of stdio. */ (void)fclose(cshin); (void)fclose(cshout); (void)fclose(csherr); if (!(cshin = funopen2((void *) &SHIN, readf, writef, seekf, NULL, closef))) exit(1); if (!(cshout = funopen2((void *) &SHOUT, readf, writef, seekf, NULL, closef))) exit(1); if (!(csherr = funopen2((void *) &SHERR, readf, writef, seekf, NULL, closef))) exit(1); (void)setvbuf(cshin, NULL, _IOLBF, 0); (void)setvbuf(cshout, NULL, _IOLBF, 0); (void)setvbuf(csherr, NULL, _IOLBF, 0); /* * Initialize the shell variables. ARGV and PROMPT are initialized later. * STATUS is also munged in several places. CHILD is munged when * forking/waiting */ set(STRstatus, Strsave(STR0)); if ((ecp = getenv("HOME")) != NULL) cp = quote(SAVE(ecp)); else cp = NULL; if (cp == NULL) fast = 1; /* No home -> can't read scripts */ else set(STRhome, cp); dinit(cp); /* dinit thinks that HOME == cwd in a login * shell */ /* * Grab other useful things from the environment. Should we grab * everything?? */ if ((ecp = getenv("LOGNAME")) != NULL || (ecp = getenv("USER")) != NULL) set(STRuser, quote(SAVE(ecp))); if ((ecp = getenv("TERM")) != NULL) set(STRterm, quote(SAVE(ecp))); /* * Re-initialize path if set in environment */ if ((ecp = getenv("PATH")) == NULL) { #ifdef _PATH_DEFPATH importpath(str2short(_PATH_DEFPATH)); #else setq(STRpath, defaultpath(), &shvhed); #endif } else { importpath(str2short(ecp)); } set(STRshell, Strsave(STR_SHELLPATH)); doldol = putn((int) getpid()); /* For $$ */ shtemp = Strspl(STRtmpsh, doldol); /* For << */ /* * Record the interrupt states from the parent process. If the parent is * non-interruptible our hand must be forced or we (and our children) won't * be either. Our children inherit termination from our parent. We catch it * only if we are the login shell. */ /* parents interruptibility */ (void)sigaction(SIGINT, NULL, &oact); parintr = oact.sa_handler; (void)sigaction(SIGTERM, NULL, &oact); parterm = oact.sa_handler; /* catch these all, login shell or not */ (void)signal(SIGHUP, phup); /* exit processing on HUP */ (void)signal(SIGXCPU, phup); /* ...and on XCPU */ (void)signal(SIGXFSZ, phup); /* ...and on XFSZ */ /* * Process the arguments. * * Note that processing of -v/-x is actually delayed till after script * processing. * * We set the first character of our name to be '-' if we are a shell * running interruptible commands. Many programs which examine ps'es * use this to filter such shells out. */ argc--, tempv++; while (argc > 0 && (tcp = tempv[0])[0] == '-' && *++tcp != '\0' && !batch) { do switch (*tcp++) { case 0: /* - Interruptible, no prompt */ prompt = 0; setintr = 1; nofile = 1; break; case 'b': /* -b Next arg is input file */ batch = 1; break; case 'c': /* -c Command input from arg */ if (argc == 1) xexit(0); argc--, tempv++; arginp = SAVE(tempv[0]); prompt = 0; nofile = 1; break; case 'e': /* -e Exit on any error */ exiterr = 1; break; case 'f': /* -f Fast start */ fast = 1; break; case 'i': /* -i Interactive, even if !intty */ intact = 1; nofile = 1; break; case 'm': /* -m read .cshrc (from su) */ mflag = 1; break; case 'n': /* -n Don't execute */ noexec = 1; break; case 'q': /* -q (Undoc'd) ... die on quit */ quitit = 1; break; case 's': /* -s Read from std input */ nofile = 1; break; case 't': /* -t Read one line from input */ onelflg = 2; prompt = 0; nofile = 1; break; case 'v': /* -v Echo hist expanded input */ nverbose = 1; /* ... later */ break; case 'x': /* -x Echo just before execution */ nexececho = 1; /* ... later */ break; case 'V': /* -V Echo hist expanded input */ setNS(STRverbose); /* NOW! */ break; case 'X': /* -X Echo just before execution */ setNS(STRecho); /* NOW! */ break; } while (*tcp); tempv++, argc--; } if (quitit) /* With all due haste, for debugging */ (void)signal(SIGQUIT, SIG_DFL); /* * Unless prevented by -, -c, -i, -s, or -t, if there are remaining * arguments the first of them is the name of a shell file from which to * read commands. */ if (nofile == 0 && argc > 0) { nofile = open(tempv[0], O_RDONLY); if (nofile < 0) { child = 1; /* So this doesn't return */ stderror(ERR_SYSTEM, tempv[0], strerror(errno)); } ffile = SAVE(tempv[0]); /* * Replace FSHIN. Handle /dev/std{in,out,err} specially * since once they are closed we cannot open them again. * In that case we use our own saved descriptors */ if ((SHIN = dmove(nofile, FSHIN)) < 0) switch(nofile) { case 0: SHIN = FSHIN; break; case 1: SHIN = FSHOUT; break; case 2: SHIN = FSHERR; break; default: stderror(ERR_SYSTEM, tempv[0], strerror(errno)); /* NOTREACHED */ } (void)ioctl(SHIN, FIOCLEX, NULL); prompt = 0; /* argc not used any more */ tempv++; } intty = isatty(SHIN); intty |= intact; if (intty || (intact && isatty(SHOUT))) { if (!batch && (uid != euid || gid != egid)) { errno = EACCES; child = 1; /* So this doesn't return */ stderror(ERR_SYSTEM, "csh", strerror(errno)); } } /* * Decide whether we should play with signals or not. If we are explicitly * told (via -i, or -) or we are a login shell (arg0 starts with -) or the * input and output are both the ttys("csh", or "csh</dev/ttyx>/dev/ttyx") * Note that in only the login shell is it likely that parent may have set * signals to be ignored */ if (loginsh || intact || (intty && isatty(SHOUT))) setintr = 1; settell(); /* * Save the remaining arguments in argv. */ setq(STRargv, blk2short(tempv), &shvhed); /* * Set up the prompt. */ if (prompt) { set(STRprompt, Strsave(uid == 0 ? STRsymhash : STRsymcent)); /* that's a meta-questionmark */ set(STRprompt2, Strsave(STRmquestion)); } /* * If we are an interactive shell, then start fiddling with the signals; * this is a tricky game. */ shpgrp = getpgrp(); opgrp = tpgrp = -1; if (setintr) { **argv = '-'; if (!quitit) /* Wary! */ (void)signal(SIGQUIT, SIG_IGN); (void)signal(SIGINT, pintr); sigemptyset(&nsigset); (void)sigaddset(&nsigset, SIGINT); (void)sigprocmask(SIG_BLOCK, &nsigset, NULL); (void)signal(SIGTERM, SIG_IGN); if (quitit == 0 && arginp == 0) { (void)signal(SIGTSTP, SIG_IGN); (void)signal(SIGTTIN, SIG_IGN); (void)signal(SIGTTOU, SIG_IGN); /* * Wait till in foreground, in case someone stupidly runs csh & * dont want to try to grab away the tty. */ if (isatty(FSHERR)) f = FSHERR; else if (isatty(FSHOUT)) f = FSHOUT; else if (isatty(OLDSTD)) f = OLDSTD; else f = -1; retry: if ((tpgrp = tcgetpgrp(f)) != -1) { if (tpgrp != shpgrp) { sig_t old = signal(SIGTTIN, SIG_DFL); (void)kill(0, SIGTTIN); (void)signal(SIGTTIN, old); goto retry; } opgrp = shpgrp; shpgrp = getpid(); tpgrp = shpgrp; /* * Setpgid will fail if we are a session leader and * mypid == mypgrp (POSIX 4.3.3) */ if (opgrp != shpgrp) if (setpgid(0, shpgrp) == -1) goto notty; /* * We do that after we set our process group, to make sure * that the process group belongs to a process in the same * session as the tty (our process and our group) (POSIX 7.2.4) */ if (tcsetpgrp(f, shpgrp) == -1) goto notty; (void)ioctl(dcopy(f, FSHTTY), FIOCLEX, NULL); } if (tpgrp == -1) { notty: (void)fprintf(csherr, "Warning: no access to tty (%s).\n", strerror(errno)); (void)fprintf(csherr, "Thus no job control in this shell.\n"); } } } if ((setintr == 0) && (parintr == SIG_DFL)) setintr = 1; (void)signal(SIGCHLD, pchild); /* while signals not ready */ /* * Set an exit here in case of an interrupt or error reading the shell * start-up scripts. */ reenter = setexit(); /* PWP */ haderr = 0; /* In case second time through */ if (!fast && reenter == 0) { /* Will have value(STRhome) here because set fast if don't */ { sig_t oparintr; sigset_t osigset; int osetintr; oparintr = parintr; osetintr = setintr; sigemptyset(&nsigset); (void)sigaddset(&nsigset, SIGINT); (void)sigprocmask(SIG_BLOCK, &nsigset, &osigset); setintr = 0; parintr = SIG_IGN; /* Disable onintr */ #ifdef _PATH_DOTCSHRC (void)srcfile(_PATH_DOTCSHRC, 0, 0); #endif if (!fast && !arginp && !onelflg) dohash(NULL, NULL); #ifdef _PATH_DOTLOGIN if (loginsh) (void)srcfile(_PATH_DOTLOGIN, 0, 0); #endif (void)sigprocmask(SIG_SETMASK, &osigset, NULL); setintr = osetintr; parintr = oparintr; } (void)srccat(value(STRhome), STRsldotcshrc); if (!fast && !arginp && !onelflg && !havhash) dohash(NULL, NULL); /* * Source history before .login so that it is available in .login */ if ((cp = value(STRhistfile)) != STRNULL) tildehist[2] = cp; dosource(tildehist, NULL); if (loginsh) (void)srccat(value(STRhome), STRsldotlogin); } /* * Now are ready for the -v and -x flags */ if (nverbose) setNS(STRverbose); if (nexececho) setNS(STRecho); /* * All the rest of the world is inside this call. The argument to process * indicates whether it should catch "error unwinds". Thus if we are a * interactive shell our call here will never return by being blown past on * an error. */ process(setintr); /* * Mop-up. */ if (intty) { if (loginsh) { (void)fprintf(cshout, "logout\n"); (void)close(SHIN); child = 1; goodbye(); } else { (void)fprintf(cshout, "exit\n"); } } rechist(); exitstat(); /* NOTREACHED */ }
void exportpath(char *canon, const char *host, const char *remote) { const char *xhost; char *copy; char tempname[FILENAME_MAX]; unsigned subscript; unsigned char number[MAX_DIGITS]; char *token, *out; static size_t range = UNIX_END_C - UNIX_START_C + 1; /* Determine unique number characters in the UNIX file names we are mapping */ size_t charsetsize; /* Number of allowed characters in MS-DOS file names */ #ifdef UDEBUG printmsg(5,"Exporting %s for %s", host, remote ); #endif /*--------------------------------------------------------------------*/ /* Define our character set */ /*--------------------------------------------------------------------*/ if ( E_charset == NULL ) E_charset = DOSCHARS; charsetsize = strlen( E_charset ); /*--------------------------------------------------------------------*/ /* Drop leading spool directory, if any */ /*--------------------------------------------------------------------*/ if (equalni(host, E_spooldir, strlen( E_spooldir ))) xhost = host + strlen( E_spooldir ) + 1; else xhost = host; copy = strdup( xhost ); checkref( copy ); /*--------------------------------------------------------------------*/ /* Drop the remote name */ /*--------------------------------------------------------------------*/ token = strtok( copy, "/"); if ((token == NULL) || !equaln( token, remote, strlen( token ))) { printmsg(0,"exportpath: Badly formed host name \"%s\"",xhost); panic(); } /*--------------------------------------------------------------------*/ /* Get the character leading the name */ /*--------------------------------------------------------------------*/ token = strtok( NULL, "/"); if ( (token == NULL) || (strlen(token) != 1)) { printmsg(0,"exportpath: Badly formed host name \"%s\"",xhost); panic(); } strcpy(canon, token); strcat(canon, "."); /*--------------------------------------------------------------------*/ /* Create a binary number which represents our file name */ /*--------------------------------------------------------------------*/ for (subscript = 0; subscript < MAX_DIGITS; subscript++ ) number[subscript] = 0; /* Initialize number to zero */ token = strtok( NULL, "/"); /* Get variable part of name */ while( (*token != '\0') && (*number == '\0')) { unsigned char digit; mult(number, charsetsize, MAX_DIGITS); /* Shift the number over */ digit = (unsigned char) (strchr( E_charset , *token++) - E_charset); add(number, digit , MAX_DIGITS); /* Add in new low order */ if (*token == '.') /* Next character a period? */ token ++; /* Yes --> Ignore it */ } /* while */ out = &tempname[FILENAME_MAX]; *--out = '\0'; /* Terminate the string we will build */ /*--------------------------------------------------------------------*/ /* Here's the loop to actually do the base conversion */ /*--------------------------------------------------------------------*/ while(adiv( number, range, &subscript, MAX_DIGITS)) *--out = (char) (subscript + UNIX_START_C); /*--------------------------------------------------------------------*/ /* We sort of lied above; the first character out of the */ /* conversion is not a character at all, but bits which say how */ /* many characters the remote and local file names get prefixed */ /* to the converted name. Retrieve that information now */ /*--------------------------------------------------------------------*/ subscript = (unsigned) (*out - UNIX_START_C); /* Convert back to pure number */ token = canon + strlen( canon ); /* Remember end of string */ if (subscript > HOSTLEN) { subscript /= HOSTLEN; strcat( canon, remote ); } else strcat( canon, E_nodename ); token[ subscript ] = '\0'; /* Only use the length we were told */ /*--------------------------------------------------------------------*/ /* Add in the variable name and we're done */ /*--------------------------------------------------------------------*/ strcat( canon, ++out ); free( copy ); /*--------------------------------------------------------------------*/ /* Check the result */ /*--------------------------------------------------------------------*/ importpath( tempname, canon, remote ); if ( !equal( tempname, xhost )) { printmsg(0, "exportpath: **mapping error** input \"%s\"," " result \"%s\", import \"%s\"", xhost, canon, tempname ); panic(); } /* if */ } /* exportpath */
int fromuupcspool(void) { time_t timer; static DIR *dd; struct dirent *df; char * p; FILE * fin; int r, lck, savein; static char lckname[SSIZE]; strcpy(lckname, spool_dir); strcat(lckname, "locks.lck"); mkdir(lckname); strcat(lckname, PATHSTR); strcat(lckname, remote); strcat(lckname, ".lck"); if (access(lckname, 0)==0) { if (unlink(lckname)) { logwrite('!', "System %s locked!\n", remote); return 1; } else logwrite('!', "Old lck-flag for %s deleted\n", remote); } lck=open(lckname, O_BINARY|O_CREAT|O_RDWR|O_EXCL, S_IREAD|S_IWRITE); if ((lck==-1) && (errno==EACCES)) { /* access denied */ logwrite('!', "System %s locked!\n", remote); return 1; } funix=1; if (lck==-1) logwrite('!', "Can't create %s: %s!\n", lckname, strerror(errno)); else { time(&timer); sprintf(str, "Locked by " NAZVA " PID %u since %s", getpid(), ctime(&timer)); write(lck, str, strlen(str)); /* flush */ r=lck; lck=dup(r); close(r); } strcpy(str, spool_dir); strcpy(named, str); strcat(str, remote); debug(5, "GetSpool started, spooldir is %s", str); strcat(str, "\\c"); namec[0]=0; dd=opendir(str); if (dd==NULL) { debug(2, "GetSpool: can't opendir %s: %s", str, strerror(errno)); if (lck!=-1) { close(lck); unlink(lckname); } return 0; } while ((df=readdir(dd))!=NULL) { if (df->d_name[0]=='.') continue; strcpy(str, spool_dir); strcat(str, remote); strcat(str, "\\c\\"); strcat(str, df->d_name); fin=myfopen(str, "r"); if (fin==NULL) { logwrite('?', "Can't open %s: %s!\n", str, strerror(errno)); continue; } strcpy(namec, str); /* там должно быть 2 строки */ if (!fgets(str, sizeof(str), fin)) { badc: fclose(fin); badc1:strcpy(str, spool_dir); strcat(str, "bad.job"); mkdir(str); strcat(str, strrchr(namec,'\\')); if (rename(namec, str)) { logwrite('?',"Can't move %s to %s: %s!\n",namec,str,strerror(errno)); unlink(namec); } else logwrite('?',"Incorrect spool-file %s, moved to bad.job!\n",namec); namec[0]=0; continue; } if (strncmp(str, "S ", 2)) goto badc; /* потом идут имена файлов здесь и там */ p=strchr(str+2,' '); if (p==NULL) goto badc; *p=0; if (*(p+1)!='D') goto badc; strcpy(named, spool_dir); importpath(named+strlen(named),str+2,remote); if (!fgets(str,sizeof(str),fin)) goto badc; if (strncmp(str, "S ", 2)) /* начинаться должно с "S " */ goto badc; p=strchr(str+2,' '); if (p==NULL) goto badc; *p=0; if (*(p+1)!='X') goto badc; strcpy(namex, spool_dir); importpath(namex+strlen(namex),str+2,remote); if (access(named,0)) { logwrite('?',"Can't find %s!\n",named); goto badc; } if (access(namex,0)) { logwrite('?',"Can't find %s!\n",namex); goto badc; } fclose(fin); debug(4,"GetSpool: namec=%s, named=%s, namex=%s",namec,named,namex); fromaddr[0]=0; packnews=0; if (fout) { if (packmail) begdel=ftell(fout); else { closeout(); begdel=0; } } else begdel=0; fin=myfopen(namex,"rb"); if (fin==NULL) { logwrite('?',"Can't open %s: %s!\n",namex,strerror(errno)); if (lck!=-1) { close(lck); unlink(lckname); } return 2; } while (fgets(str,sizeof(str),fin)) if (strncmp(str,"C ",2)==0) break; if (feof(fin)) goto badc; fclose(fin); p=strchr(str, '\n'); if (p) *p='\0'; r=open(named, O_BINARY|O_RDONLY); if (r==-1) { logwrite('?', "Can't open %s: %s!\n", named, strerror(errno)); goto badc1; } savein=dup(fileno(stdin)); dup2(r, fileno(stdin)); close(r); if (strncmp(str+2, "rmail ", 6)==0) { char *addrlist; if (nonet) continue; addrlist=strdup(str+8); if (addrlist==NULL) { logwrite('?',"Not enough memory!\n"); r=-1; } else { if (conf) { closeout(); begdel=packnews=0; } r=rmailfunc(addrlist); } } else if (strcmp(str+2, "rbmail")==0) { if (nonet) continue; if (conf) { closeout(); begdel=packnews=0; } r=rbmail(); } else if (strcmp(str+2, "rcbmail")==0 || strcmp(str+2, "rzbmail")==0) { if (nonet) continue; if (conf) { closeout(); begdel=packnews=0; } r=rcbmail(); } else if (strcmp(str+2, "rnews")==0) { if (noecho) continue; if (!conf) { closeout(); begdel=packnews=0; } r=rnews(); } else { logwrite('?', "Unknown command '%s' in spool-file!\n", str); dup2(savein, fileno(stdin)); close(savein); goto badc1; } dup2(savein, fileno(stdin)); close(savein); if (r==0) { unlink(named); unlink(namex); unlink(namec); } else { badnews(); /* goto badc; */ continue; } } debug(4,"GetSpool: no more jobs in spool"); closedir(dd); if (lck!=-1) { close(lck); unlink(lckname); } if (!conf) closeout(); return 0; }
/*ARGSUSED*/ void dosetpath(Char **arglist, struct command *c) { extern char *getenv(); Char **pathvars, **cmdargs; char **spaths, **cpaths, **cmds; char *tcp; unsigned int npaths, ncmds; int i, sysflag; pintr_disabled++; cleanup_push(&pintr_disabled, disabled_cleanup); /* * setpath(3) uses stdio and we want 0, 1, 2 to work... */ if (!didfds) { (void) dcopy(SHIN, 0); (void) dcopy(SHOUT, 1); (void) dcopy(SHDIAG, 2); didfds = 1; } for (i = 1; arglist[i] && (arglist[i][0] != '-'); i++); npaths = i - 1; cmdargs = &arglist[i]; for (; arglist[i]; i++); ncmds = i - npaths - 1; if (npaths) { sysflag = 0; pathvars = &arglist[1]; } else { sysflag = 1; npaths = (sizeof syspaths / sizeof *syspaths) - 1; pathvars = syspaths; } /* note that npaths != 0 */ spaths = xmalloc(npaths * sizeof *spaths); setzero(spaths, npaths * sizeof *spaths); cpaths = xmalloc((npaths + 1) * sizeof *cpaths); setzero(cpaths, (npaths + 1) * sizeof *cpaths); cmds = xmalloc((ncmds + 1) * sizeof *cmds); setzero(cmds, (ncmds + 1) * sizeof *cmds); for (i = 0; i < npaths; i++) { char *val = getenv(short2str(pathvars[i])); if (val == NULL) val = ""; spaths[i] = xmalloc((Strlen(pathvars[i]) + strlen(val) + 2) * sizeof **spaths); (void) strcpy(spaths[i], short2str(pathvars[i])); (void) strcat(spaths[i], "="); (void) strcat(spaths[i], val); cpaths[i] = spaths[i]; } for (i = 0; i < ncmds; i++) { Char *val = globone(cmdargs[i], G_ERROR);/*FIXRESET*/ if (val == NULL) goto abortpath; cmds[i] = strsave(short2str(val)); } if (setpath(cpaths, cmds, LOCALSYSPATH, sysflag, 1) < 0) { abortpath: if (spaths) { for (i = 0; i < npaths; i++) xfree(spaths[i]); xfree(spaths); } xfree(cpaths); if (cmds) { for (i = 0; i < ncmds; i++) xfree(cmds[i]); xfree(cmds); } cleanup_until(&pintr_disabled); donefds(); return; } for (i = 0; i < npaths; i++) { Char *val, *name; name = str2short(cpaths[i]); for (val = str2short(cpaths[i]); val && *val && *val != '='; val++); if (val && *val == '=') { *val++ = '\0'; tsetenv(name, val);/*FIXRESET*/ if (Strcmp(name, STRKPATH) == 0) { importpath(val);/*FIXRESET*/ if (havhash) dohash(NULL, NULL);/*FIXRESET*/ } *--val = '='; } } cleanup_until(&pintr_disabled); donefds(); }