/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1990-2011 AT&T Intellectual Property * * and is licensed under the * * Common Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.opensource.org/licenses/cpl1.0.txt * * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ #pragma prototyped /* * Glenn Fowler * AT&T Research * * return job initialization commands */ #if _WIN32 #undef _BLD_DLL #define _BLD_DLL 1 #endif #include "colib.h" #include #include /* * add n to the export list * old!=0 formats in old style * coex!=0 for CO_ENV_EXPORT * if n prefixed by % then coquote conversion enabled */ static void putexport(Coshell_t* co, Sfio_t* sp, char* n, int old, int coex, int flags) { int cvt; char* v; Coexport_t* ex; if (cvt = *n == '%') n++; if (!co->export || !dtmatch(co->export, n)) { if (old) cvt = 0; if ((v = getenv(n)) && *v || coex && ((flags & CO_EXPORT) || co->export && dtsize(co->export) > 0)) { if (!old) sfprintf(sp, "\\\n"); sfprintf(sp, " %s='", n); if (coex && (flags & CO_EXPORT)) v = "(*)"; if (v) coquote(sp, v, cvt); if (coex && !(flags & CO_EXPORT)) { v = v ? ":" : ""; for (ex = (Coexport_t*)dtfirst(co->export); ex; ex = (Coexport_t*)dtnext(co->export, ex)) { sfprintf(sp, "%s%s", v, ex->name); v = ":"; } } sfputc(sp, '\''); if (old) sfprintf(sp, "\nexport %s\n", n); } } } /* * return job initialization commands */ char* coinitialize(Coshell_t* co, int flags) { register char* s; int n; int m; int old; int sync; char* t; long p; Coexport_t* ex; Sfio_t* sp; Sfio_t* tp; struct stat st; sync = co->init.sync; co->init.sync = 0; /* * pwd */ if (stat(".", &st)) return 0; if (!state.pwd || st.st_ino != co->init.pwd_ino || st.st_dev != co->init.pwd_dev) { co->init.pwd_dev = st.st_dev; co->init.pwd_ino = st.st_ino; if (state.pwd) free(state.pwd); if (!(state.pwd = getcwd(NiL, 0))) { if (errno != EINVAL || !(state.pwd = newof(0, char, PATH_MAX, 0))) return 0; if (!getcwd(state.pwd, PATH_MAX)) { free(state.pwd); state.pwd = 0; return 0; } } if (!(flags & CO_INIT)) sync = 1; } /* * umask */ umask(n = umask(co->init.mask)); if (co->init.mask != n) { co->init.mask = n; if (!(flags & CO_INIT)) sync = 1; } if (!co->init.script || sync) { /* * co_export[] vars */ if (!(sp = sfstropen())) return 0; tp = 0; old = !(flags & (CO_KSH|CO_SERVER)); if (!old) sfprintf(sp, "export"); if (sync) { if (flags & CO_EXPORT) s = "(*)"; else { for (n = 0; s = co_export[n]; n++) putexport(co, sp, s, old, !n, flags); s = getenv(co_export[0]); } if (s) { if (*s == '(') { register char** ep = environ; register char* e; char* v; char* es; char* xs; if (v = strchr(s, ':')) *v = 0; while (e = *ep++) if ((t = strsubmatch(e, s, 1)) && (*t == '=' || !*t && (t = strchr(e, '=')))) { m = t - e; if (!strneq(e, "PATH=", 5) && !strneq(e, "_=", 2)) { for (n = 0; xs = co_export[n]; n++) { es = e; while (*xs && *es == *xs) { es++; xs++; } if (*es == '=' && !*xs) break; } if (!xs) { if (!old) sfprintf(sp, "\\\n"); sfprintf(sp, " %-.*s='", m, e); coquote(sp, e + m + 1, 0); sfputc(sp, '\''); if (old) sfprintf(sp, "\nexport %-.*s\n", m, e); } } } if (v) { *v++ = ':'; s = v; } } if (*s) for (;;) { if (t = strchr(s, ':')) *t = 0; putexport(co, sp, s, old, 0, 0); if (!(s = t)) break; *s++ = ':'; } } if (co->export) for (ex = (Coexport_t*)dtfirst(co->export); ex; ex = (Coexport_t*)dtnext(co->export, ex)) { if (!old) sfprintf(sp, "\\\n"); sfprintf(sp, " %s='", ex->name); coquote(sp, ex->value, 0); sfputc(sp, '\''); if (old) sfprintf(sp, "\nexport %s\n", ex->name); } } /* * PATH */ if (!old) sfprintf(sp, "\\\n"); sfprintf(sp, " PATH='"); n = PATH_MAX; if (!(t = sfstrrsrv(sp, n))) { bad: sfstrclose(sp); if (tp) sfstrclose(tp); return 0; } t += n / 2; if (!(flags & CO_CROSS) && !pathpath("ignore", NiL, PATH_ABSOLUTE|PATH_REGULAR|PATH_EXECUTE, t, n / 2) && pathpath("bin/ignore", "", PATH_ABSOLUTE|PATH_REGULAR|PATH_EXECUTE, t, n / 2)) { *strrchr(t, '/') = 0; sfputc(sp, ':'); coquote(sp, t, !old); sfputc(sp, ':'); s = pathbin(); } else { s = pathbin(); if (!(flags & CO_CROSS)) { if (!sync && (*s == ':' || *s == '.' && *(s + 1) == ':')) { sfstrseek(sp, 0, SEEK_SET); goto done; } sfputc(sp, ':'); } } for (;;) { if (*s == ':') s++; else if (*s == '.' && *(s + 1) == ':') s += 2; else break; } if (!(flags & CO_CROSS)) tp = 0; else if (!(tp = sfstropen())) goto bad; else { while (n = *s++) { if (n == ':') { while (*s == ':') s++; if (!*s) break; if (*s == '.') { if (!*(s + 1)) break; if (*(s + 1) == ':') { s++; continue; } } } sfputc(tp, n); } if (!(s = costash(tp))) goto bad; } coquote(sp, s, !old); if (tp) sfstrclose(tp); sfputc(sp, '\''); if (old) sfprintf(sp, "\nexport PATH"); sfputc(sp, '\n'); if (sync) { /* * VPATH */ p = sfstrtell(sp); sfprintf(sp, "vpath "); n = PATH_MAX; if (fs3d(FS3D_TEST)) for (;;) { if (!(t = sfstrrsrv(sp, n))) goto bad; if ((m = mount(NiL, t, FS3D_GET|FS3D_ALL|FS3D_SIZE(n), NiL)) > 0) m = n; else { if (!m) sfstrseek(sp, strlen(t), SEEK_CUR); break; } } else { m = 0; sfprintf(sp, "- /#option/2d"); } if (m) sfstrseek(sp, p, SEEK_SET); else sfprintf(sp, " 2>/dev/null || :\n"); sfprintf(sp, "umask 0%o\ncd '%s'\n", co->init.mask, state.pwd); } done: if (!(flags & CO_SERVER)) { sfprintf(sp, "%s%s=%05d${!%s-$$}\n", old ? "" : "export ", CO_ENV_TEMP, getpid(), (flags & CO_OSH) ? "" : ":"); if (old) sfprintf(sp, "export %s\n", CO_ENV_TEMP); } sfputc(sp, 0); n = sfstrtell(sp); if (co->vm) { if (co->init.script) vmfree(co->vm, co->init.script); if (!(co->init.script = vmnewof(co->vm, 0, char, n, 1))) goto bad; } else { if (co->init.script) free(co->init.script); if (!(co->init.script = newof(0, char, n, 1))) goto bad; } memcpy(co->init.script, sfstrbase(sp), n); sfstrclose(sp); } else if (!co->init.script) { if (co->init.script = co->vm ? vmnewof(co->vm, 0, char, 1, 0) : newof(0, char, 1, 0)) *co->init.script = 0; } return co->init.script; } /* * return generic job initialization commands */ char* coinit(int flags) { if (!state.generic) { if (!(state.generic = newof(0, Coshell_t, 1, 0))) return 0; state.generic->init.sync = 1; } return coinitialize(state.generic, flags); }