FILE *os_path_open(const char *name, const char *mode) { FILE *fp; char buf[FILENAME_MAX + 1]; char *p; /* Let's see if the file is in the currect directory */ /* or if the user gave us a full path. */ if ((fp = fopen(name, mode))) { return fp; } /* If zcodepath is defined in a config file, check that path. */ /* If we find the file a match in that path, great. */ /* Otherwise, check some environmental variables. */ if (f_setup.zcode_path != NULL) { if ((fp = pathopen(name, f_setup.zcode_path, mode, buf)) != NULL) { strncpy(f_setup.story_name, buf, FILENAME_MAX); return fp; } } if ( (p = getenv(PATH1) ) == NULL) p = getenv(PATH2); if (p != NULL) { fp = pathopen(name, p, mode, buf); strncpy(f_setup.story_name, buf, FILENAME_MAX); return fp; } return NULL; /* give up */ } /* os_path_open() */
int main(int c, char *v[], char *e[]) { int rflag = ttyflg; int rsflag = 1; /* local restricted flag */ unsigned char *flagc = flagadr; struct namnod *n; mypid = getpid(); mypgid = getpgid(mypid); mysid = getsid(mypid); /* * Do locale processing only if /usr is mounted. */ localedir_exists = (access(localedir, F_OK) == 0); /* * initialize storage allocation */ if (stakbot == 0) { addblok((unsigned)0); } /* * If the first character of the last path element of v[0] is "-" * (ex. -sh, or /bin/-sh), this is a login shell */ if (*simple(v[0]) == '-') { signal(SIGXCPU, SIG_DFL); signal(SIGXFSZ, SIG_DFL); /* * As the previous comment states, this is a login shell. * Therefore, we set the login_shell flag to explicitly * indicate this condition. */ login_shell = TRUE; } stdsigs(); /* * set names from userenv */ setup_env(); /* * LC_MESSAGES is set here so that early error messages will * come out in the right style. * Note that LC_CTYPE is done later on and is *not* * taken from the previous environ */ /* * Do locale processing only if /usr is mounted. */ if (localedir_exists) (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ #endif (void) textdomain(TEXT_DOMAIN); /* * 'rsflag' is zero if SHELL variable is * set in environment and * the simple file part of the value. * is rsh */ if (n = findnam("SHELL")) { if (eq("rsh", simple(n->namval))) rsflag = 0; } /* * a shell is also restricted if the simple name of argv(0) is * rsh or -rsh in its simple name */ #ifndef RES if (c > 0 && (eq("rsh", simple(*v)) || eq("-rsh", simple(*v)))) rflag = 0; #endif if (eq("jsh", simple(*v)) || eq("-jsh", simple(*v))) flags |= monitorflg; hcreate(); set_dotpath(); /* * look for options * dolc is $# */ dolc = options(c, v); if (dolc < 2) { flags |= stdflg; { while (*flagc) flagc++; *flagc++ = STDFLG; *flagc = 0; } } if ((flags & stdflg) == 0) dolc--; if ((flags & privflg) == 0) { uid_t euid; gid_t egid; uid_t ruid; gid_t rgid; /* * Determine all of the user's id #'s for this process and * then decide if this shell is being entered as a result * of a fork/exec. * If the effective uid/gid do NOT match and the euid/egid * is < 100 and the egid is NOT 1, reset the uid and gid to * the user originally calling this process. */ euid = geteuid(); ruid = getuid(); egid = getegid(); rgid = getgid(); if ((euid != ruid) && (euid < 100)) setuid(ruid); /* reset the uid to the orig user */ if ((egid != rgid) && ((egid < 100) && (egid != 1))) setgid(rgid); /* reset the gid to the orig user */ } dolv = (unsigned char **)v + c - dolc; dolc--; /* * return here for shell file execution * but not for parenthesis subshells */ if (setjmp(subshell)) { freejobs(); flags |= subsh; } /* * number of positional parameters */ replace(&cmdadr, dolv[0]); /* cmdadr is $0 */ /* * set pidname '$$' */ assnum(&pidadr, (long)mypid); /* * set up temp file names */ settmp(); /* * default internal field separators * Do not allow importing of IFS from parent shell. * setup_env() may have set anything from parent shell to IFS. * Always set the default ifs to IFS. */ assign(&ifsnod, (unsigned char *)sptbnl); dfault(&mchknod, MAILCHECK); mailchk = stoi(mchknod.namval); /* initialize OPTIND for getopt */ n = lookup("OPTIND"); assign(n, (unsigned char *)"1"); /* * make sure that option parsing starts * at first character */ _sp = 1; if ((beenhere++) == FALSE) /* ? profile */ { if ((login_shell == TRUE) && (flags & privflg) == 0) { /* system profile */ #ifndef RES if ((input = pathopen(nullstr, sysprofile)) >= 0) exfile(rflag); /* file exists */ #endif /* user profile */ if ((input = pathopen(homenod.namval, profile)) >= 0) { exfile(rflag); flags &= ~ttyflg; } } if (rsflag == 0 || rflag == 0) { if ((flags & rshflg) == 0) { while (*flagc) flagc++; *flagc++ = 'r'; *flagc = '\0'; } flags |= rshflg; } /* * open input file if specified */ if (comdiv) { estabf(comdiv); input = -1; } else { if (flags & stdflg) { input = 0; } else { /* * If the command file specified by 'cmdadr' * doesn't exist, chkopen() will fail calling * exitsh(). If this is a login shell and * the $HOME/.profile file does not exist, the * above statement "flags &= ~ttyflg" does not * get executed and this makes exitsh() call * longjmp() instead of exiting. longjmp() will * return to the location specified by the last * active jmpbuffer, which is the one set up in * the function exfile() called after the system * profile file is executed (see lines above). * This would cause an infinite loop, because * chkopen() will continue to fail and exitsh() * to call longjmp(). To make exitsh() exit instead * of calling longjmp(), we then set the flag forcexit * at this stage. */ flags |= forcexit; input = chkopen(cmdadr, 0); flags &= ~forcexit; } #ifdef ACCT if (input != 0) preacct(cmdadr); #endif comdiv--; } } #ifdef pdp11 else *execargs = (char *)dolv; /* for `ps' cmd */ #endif exfile(0); done(0); }
int ast_openat(int cwd, const char* path, int flags, ...) { int r; #if _ast_O_LOCAL && O_CLOEXEC >= _ast_O_LOCAL int o_cloexec; #endif #if _ast_O_LOCAL && O_DIRECTORY >= _ast_O_LOCAL int o_directory; #endif mode_t mode; va_list ap; va_start(ap, flags); mode = (flags & O_CREAT) ? (mode_t)va_arg(ap, int) : (mode_t)0; va_end(ap); #if _ast_O_LOCAL && O_CLOEXEC >= _ast_O_LOCAL if (flags & O_CLOEXEC) { flags &= ~O_CLOEXEC; o_cloexec = 1; } else o_cloexec = 0; #endif #if _ast_O_LOCAL && O_DIRECTORY >= _ast_O_LOCAL if (flags & O_DIRECTORY) { flags &= ~O_DIRECTORY; o_directory = 1; } else o_directory = 0; #endif if (!path) path = dot; if (flags & O_INTERCEPT) { flags &= ~O_INTERCEPT; RESTART(r, openat(cwd, path, flags&~O_INTERCEPT, mode)); #ifdef O_ASYNC if (r >= 0 && (flags & O_ASYNC)) { int x; int f; RESTART(f, fcntl(r, F_GETFL, 0)); if (f >= 0 && !(f & O_ASYNC)) { f |= O_ASYNC; RESTART(x, fcntl(r, F_SETFL, f)); } #ifdef F_SETOWN RESTART(x, fcntl(r, F_SETOWN, getuid())); #endif } #endif } else RESTART(r, pathopen(cwd, path, NiL, 0, 0, flags|O_INTERCEPT, mode)); #if _ast_O_LOCAL && O_CLOEXEC >= _ast_O_LOCAL if (o_cloexec && r >= 0) RESTART(o_cloexec, fcntl(r, F_SETFD, FD_CLOEXEC)); #endif #if _ast_O_LOCAL && O_DIRECTORY >= _ast_O_LOCAL if (o_directory && r >= 0) { struct stat st; if (fstat(r, &st) || !S_ISDIR(st.st_mode) && (errno = ENOTDIR)) { close(r); r = -1; } } #endif return r; }
int execute(TREPTR argt, int execflg, int *pf1, int *pf2) { /* `stakbot' is preserved by this routine */ register TREPTR t; STKPTR sav = savstak(); sigchk(); if ((t = argt) && execbrk == 0) { register int treeflgs; int oldexit, type; register char **com; treeflgs = t->tretyp; type = treeflgs & COMMSK; oldexit = exitval; exitval = 0; switch (type) { case TCOM: { STRING a1; int argn, internal; ARGPTR schain = gchain; IOPTR io = t->treio; gchain = 0; argn = getarg((void *)t);/*FIXME*/ com = scan(argn); a1 = com[1]; gchain = schain; if ((internal = syslook(com[0], commands)) || argn == 0) setlist(((COMPTR) t)->comset, 0); if (argn && (flags & noexec) == 0) { /* print command if execpr */ if (flags & execpr) { argn = 0; prs(execpmsg); while (com[argn] != ENDARGS) { prs(com[argn++]); blank(); } newline(); } switch (internal) { case SYSDOT: if (a1) { register int f; if ((f = pathopen(getpath(a1), a1)) < 0) failed(a1, notfound); else execexp(0, f); } break; case SYSTIMES: { struct tms t; times(&t); prt(t.tms_cutime); blank(); prt(t.tms_cstime); newline(); } break; case SYSEXIT: exitsh(a1 ? stoi(a1) : oldexit); case SYSNULL: io = 0; break; case SYSCONT: execbrk = -loopcnt; break; case SYSBREAK: if ((execbrk = loopcnt) && a1) breakcnt = stoi(a1); break; case SYSTRAP: if (a1) { BOOL clear; if ((clear = digit(*a1)) == 0) ++com; while (*++com) { int i; if ((i = stoi(*com)) >= MAXTRAP || i < MINTRAP) failed(*com, badtrap); else if (clear) clrsig(i); else { replace(&trapcom[i], a1); if (*a1) getsig(i); else ignsig(i); } } } else { /* print out current traps */ int i; for (i = 0; i < MAXTRAP; i++) { if (trapcom[i]) { prn(i); prs(colon); prs(trapcom[i]); newline(); } } } break; case SYSEXEC: com++; initio(io); ioset = 0; io = 0; if (a1 == 0) break; case SYSLOGIN: flags |= forked; oldsigs(); execa((const char **)com); done(); case SYSCD: if (flags & rshflg) failed(com[0], restricted); else if ((a1 == 0 && (a1 = (char *)homenod.namval) == 0) || chdir(a1) < 0) /* FIXME */ failed(a1, baddir); break; case SYSSHFT: if (dolc < 1) error(badshift); else { dolv++; dolc--; } assnum(&dolladr, dolc); break; case SYSWAIT: await(-1); break; case SYSREAD: exitval = readvar(&com[1]); break; /* case SYSTST: exitval=testcmd(com); break; */ case SYSSET: if (a1) { int argc; argc = options(argn, (const char **)com); if (argc > 1) setargs((const char **)com + argn - argc); } else if (((COMPTR) t)->comset == 0) /* Scan name chain and print */ namscan(printnam); break; case SYSRDONLY: exitval = N_RDONLY; case SYSXPORT: if (exitval == 0) exitval = N_EXPORT;; if (a1) { while (*++com) attrib(lookup(*com), exitval); } else { namscan(printflg); } exitval = 0; break; case SYSEVAL: if (a1) execexp(a1, (UFD)&com[2]); /* FIXME */ break; case SYSUMASK: if (a1) { int c, i; i = 0; while ((c = *a1++) >= '0' && c <= '7') i = (i << 3) + c - '0'; umask(i); } else { int i, j; umask(i = umask(0)); prc('0'); for (j = 6; j >= 0; j -= 3) prc(((i >> j) & 07) + '0'); newline(); } break; default: internal = builtin(argn, com); } if (internal) { if (io) error(illegal); chktrap(); break; } } else if (t->treio == 0) break; } case TFORK: if (execflg && (treeflgs & (FAMP | FPOU)) == 0) parent = 0; else { while ((parent = fork()) == -1) { sigchk(); alarm(10); pause(); } } if (parent) { /* This is the parent branch of fork; */ /* it may or may not wait for the child. */ if (treeflgs & FPRS && flags & ttyflg) { prn(parent); newline(); } if (treeflgs & FPCL) closepipe(pf1); if ((treeflgs & (FAMP | FPOU)) == 0) await(parent); else if ((treeflgs & FAMP) == 0) post(parent); else assnum(&pcsadr, parent); chktrap(); break; } else { /* this is the forked branch (child) of execute */ flags |= forked; iotemp = 0; postclr(); settmp(); /* Turn off INTR and QUIT if `FINT' */ /* Reset ramaining signals to parent */ /* except for those `lost' by trap */ oldsigs(); if (treeflgs & FINT) { signal(INTR, SIG_IGN); signal(QUIT, SIG_IGN); } /* pipe in or out */ if (treeflgs & FPIN) { sh_rename(pf1[INPIPE], 0); close(pf1[OTPIPE]); } if (treeflgs & FPOU) { sh_rename(pf2[OTPIPE], 1); close(pf2[INPIPE]); } /* default std input for & */ if (treeflgs & FINT && ioset == 0) sh_rename(chkopen(devnull), 0); /* io redirection */ initio(t->treio); if (type != TCOM) execute(((FORKPTR) t)->forktre, 1, NULL, NULL); else if (com[0] != ENDARGS) { setlist(((COMPTR) t)->comset, N_EXPORT); execa((const char **)com); } done(); } case TPAR: sh_rename(dup(2), output); execute(((PARPTR) t)->partre, execflg, NULL, NULL); done(); case TFIL: { int pv[2]; chkpipe(pv); if (execute(((LSTPTR) t)->lstlef, 0, pf1, pv) == 0) execute(((LSTPTR) t)->lstrit, execflg, pv, pf2); else closepipe(pv); break; } case TLST: execute(((LSTPTR) t)->lstlef, 0, NULL, NULL); execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL); break; case TAND: if (execute(((LSTPTR) t)->lstlef, 0, NULL, NULL) == 0) execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL); break; case TORF: if (execute(((LSTPTR) t)->lstlef, 0, NULL, NULL) != 0) execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL); break; case TFOR: { NAMPTR n = lookup(((FORPTR) t)->fornam); char **args; DOLPTR argsav = 0; if (((FORPTR) t)->forlst == 0) { args = (char **)dolv + 1; argsav = useargs(); } else { ARGPTR schain = gchain; gchain = 0; trim((args = scan(getarg(((FORPTR) t)->forlst)))[0]); gchain = schain; } loopcnt++; while (*args != ENDARGS && execbrk == 0) { assign(n, *args++); execute(((FORPTR) t)->fortre, 0, NULL, NULL); if (execbrk < 0) { execbrk = 0; } } if (breakcnt) breakcnt--; execbrk = breakcnt; loopcnt--; argfor = freeargs(argsav); break; } case TWH: case TUN: { int i = 0; loopcnt++; while (execbrk == 0 && (execute(((WHPTR) t)->whtre, 0, NULL, NULL) == 0) == (type == TWH)) { i = execute(((WHPTR) t)->dotre, 0, NULL, NULL); if (execbrk < 0) execbrk = 0; } if (breakcnt) breakcnt--; execbrk = breakcnt; loopcnt--; exitval = i; break; } case TIF: if (execute(((IFPTR) t)->iftre, 0, NULL, NULL) == 0) execute(((IFPTR) t)->thtre, execflg, NULL, NULL); else execute(((IFPTR) t)->eltre, execflg, NULL, NULL); break; case TSW: { register char *r = mactrim(((SWPTR) t)->swarg); t = (TREPTR) ((SWPTR) t)->swlst; while (t) { ARGPTR rex = ((REGPTR) t)->regptr; while (rex) { register char *s; if (gmatch(r, s = macro(rex->argval)) || (trim(s), eq(r, s))) { execute(((REGPTR)t)->regcom, 0, NULL, NULL); t = 0; break; } else rex = ((ARGPTR)rex)->argnxt; } if (t) t = (TREPTR) ((REGPTR) t)->regnxt; } } break; } exitset(); }
int main(int c, const char *v[]) { register int rflag = ttyflg; /* initialise storage allocation */ blokinit(); stdsigs(); setbrk(BRKINCR); addblok((POS) 0); /* set names from userenv */ sh_getenv(); /* look for restricted */ /* if(c>0 && any('r', *v) ) { rflag=0 ;} */ /* look for options */ dolc = options(c, v); if (dolc < 2) flags |= stdflg; if ((flags & stdflg) == 0) dolc--; dolv = v + c - dolc; dolc--; /* return here for shell file execution */ setjmp(subshell); /* number of positional parameters */ assnum(&dolladr, dolc); cmdadr = (char *)dolv[0]; /* set pidname */ assnum(&pidadr, getpid()); /* set up temp file names */ settmp(); /* default ifs */ dfault(&ifsnod, sptbnl); if ((beenhere++) == FALSE) { /* ? profile */ if (*cmdadr == '-' && (input = pathopen(nullstr, profile)) >= 0) { exfile(rflag); flags &= ~ttyflg; ; } if (rflag == 0) { flags |= rshflg; } /* open input file if specified */ if (comdiv) { estabf(comdiv); input = -1; } else { input = ((flags & stdflg) ? 0 : chkopen(cmdadr)); comdiv--; ; } // } else { *execargs=(char *)dolv; /* for `ps' cmd */ ; } exfile(0); done(); }