1/*********************************************************************** 2* * 3* This software is part of the ast package * 4* Copyright (c) 1990-2011 AT&T Intellectual Property * 5* and is licensed under the * 6* Common Public License, Version 1.0 * 7* by AT&T Intellectual Property * 8* * 9* A copy of the License is available at * 10* http://www.opensource.org/licenses/cpl1.0.txt * 11* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12* * 13* Information and Software Systems Research * 14* AT&T Research * 15* Florham Park NJ * 16* * 17* Glenn Fowler <gsf@research.att.com> * 18* * 19***********************************************************************/ 20#pragma prototyped 21/* 22 * Glenn Fowler 23 * AT&T Research 24 * 25 * return job initialization commands 26 */ 27 28#if _WIN32 29#undef _BLD_DLL 30#define _BLD_DLL 1 31#endif 32 33#include "colib.h" 34 35#include <fs3d.h> 36#include <ls.h> 37 38/* 39 * add n to the export list 40 * old!=0 formats in old style 41 * coex!=0 for CO_ENV_EXPORT 42 * if n prefixed by % then coquote conversion enabled 43 */ 44 45static void 46putexport(Coshell_t* co, Sfio_t* sp, char* n, int old, int coex, int flags) 47{ 48 int cvt; 49 char* v; 50 Coexport_t* ex; 51 52 if (cvt = *n == '%') 53 n++; 54 if (!co->export || !dtmatch(co->export, n)) 55 { 56 if (old) 57 cvt = 0; 58 if ((v = getenv(n)) && *v || coex && ((flags & CO_EXPORT) || co->export && dtsize(co->export) > 0)) 59 { 60 if (!old) 61 sfprintf(sp, "\\\n"); 62 sfprintf(sp, " %s='", n); 63 if (coex && (flags & CO_EXPORT)) 64 v = "(*)"; 65 if (v) 66 coquote(sp, v, cvt); 67 if (coex && !(flags & CO_EXPORT)) 68 { 69 v = v ? ":" : ""; 70 for (ex = (Coexport_t*)dtfirst(co->export); ex; ex = (Coexport_t*)dtnext(co->export, ex)) 71 { 72 sfprintf(sp, "%s%s", v, ex->name); 73 v = ":"; 74 } 75 } 76 sfputc(sp, '\''); 77 if (old) 78 sfprintf(sp, "\nexport %s\n", n); 79 } 80 } 81} 82 83/* 84 * return job initialization commands 85 */ 86 87char* 88coinitialize(Coshell_t* co, int flags) 89{ 90 register char* s; 91 int n; 92 int m; 93 int old; 94 int sync; 95 char* t; 96 long p; 97 Coexport_t* ex; 98 Sfio_t* sp; 99 Sfio_t* tp; 100 struct stat st; 101 102 sync = co->init.sync; 103 co->init.sync = 0; 104 105 /* 106 * pwd 107 */ 108 109 if (stat(".", &st)) 110 return 0; 111 if (!state.pwd || st.st_ino != co->init.pwd_ino || st.st_dev != co->init.pwd_dev) 112 { 113 co->init.pwd_dev = st.st_dev; 114 co->init.pwd_ino = st.st_ino; 115 if (state.pwd) 116 free(state.pwd); 117 if (!(state.pwd = getcwd(NiL, 0))) 118 { 119 if (errno != EINVAL || !(state.pwd = newof(0, char, PATH_MAX, 0))) 120 return 0; 121 if (!getcwd(state.pwd, PATH_MAX)) 122 { 123 free(state.pwd); 124 state.pwd = 0; 125 return 0; 126 } 127 } 128 if (!(flags & CO_INIT)) 129 sync = 1; 130 } 131 132 /* 133 * umask 134 */ 135 136 umask(n = umask(co->init.mask)); 137 if (co->init.mask != n) 138 { 139 co->init.mask = n; 140 if (!(flags & CO_INIT)) 141 sync = 1; 142 } 143 if (!co->init.script || sync) 144 { 145 /* 146 * co_export[] vars 147 */ 148 149 if (!(sp = sfstropen())) 150 return 0; 151 tp = 0; 152 old = !(flags & (CO_KSH|CO_SERVER)); 153 if (!old) 154 sfprintf(sp, "export"); 155 if (sync) 156 { 157 if (flags & CO_EXPORT) 158 s = "(*)"; 159 else 160 { 161 for (n = 0; s = co_export[n]; n++) 162 putexport(co, sp, s, old, !n, flags); 163 s = getenv(co_export[0]); 164 } 165 if (s) 166 { 167 if (*s == '(') 168 { 169 register char** ep = environ; 170 register char* e; 171 char* v; 172 char* es; 173 char* xs; 174 175 if (v = strchr(s, ':')) 176 *v = 0; 177 while (e = *ep++) 178 if ((t = strsubmatch(e, s, 1)) && (*t == '=' || !*t && (t = strchr(e, '=')))) 179 { 180 m = t - e; 181 if (!strneq(e, "PATH=", 5) && !strneq(e, "_=", 2)) 182 { 183 for (n = 0; xs = co_export[n]; n++) 184 { 185 es = e; 186 while (*xs && *es == *xs) 187 { 188 es++; 189 xs++; 190 } 191 if (*es == '=' && !*xs) 192 break; 193 } 194 if (!xs) 195 { 196 if (!old) 197 sfprintf(sp, "\\\n"); 198 sfprintf(sp, " %-.*s='", m, e); 199 coquote(sp, e + m + 1, 0); 200 sfputc(sp, '\''); 201 if (old) 202 sfprintf(sp, "\nexport %-.*s\n", m, e); 203 } 204 } 205 } 206 if (v) 207 { 208 *v++ = ':'; 209 s = v; 210 } 211 } 212 if (*s) 213 for (;;) 214 { 215 if (t = strchr(s, ':')) 216 *t = 0; 217 putexport(co, sp, s, old, 0, 0); 218 if (!(s = t)) 219 break; 220 *s++ = ':'; 221 } 222 } 223 if (co->export) 224 for (ex = (Coexport_t*)dtfirst(co->export); ex; ex = (Coexport_t*)dtnext(co->export, ex)) 225 { 226 if (!old) 227 sfprintf(sp, "\\\n"); 228 sfprintf(sp, " %s='", ex->name); 229 coquote(sp, ex->value, 0); 230 sfputc(sp, '\''); 231 if (old) 232 sfprintf(sp, "\nexport %s\n", ex->name); 233 } 234 } 235 236 /* 237 * PATH 238 */ 239 240 if (!old) 241 sfprintf(sp, "\\\n"); 242 sfprintf(sp, " PATH='"); 243 n = PATH_MAX; 244 if (!(t = sfstrrsrv(sp, n))) 245 { 246 bad: 247 sfstrclose(sp); 248 if (tp) 249 sfstrclose(tp); 250 return 0; 251 } 252 t += n / 2; 253 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)) 254 { 255 *strrchr(t, '/') = 0; 256 sfputc(sp, ':'); 257 coquote(sp, t, !old); 258 sfputc(sp, ':'); 259 s = pathbin(); 260 } 261 else 262 { 263 s = pathbin(); 264 if (!(flags & CO_CROSS)) 265 { 266 if (!sync && (*s == ':' || *s == '.' && *(s + 1) == ':')) 267 { 268 sfstrseek(sp, 0, SEEK_SET); 269 goto done; 270 } 271 sfputc(sp, ':'); 272 } 273 } 274 for (;;) 275 { 276 if (*s == ':') 277 s++; 278 else if (*s == '.' && *(s + 1) == ':') 279 s += 2; 280 else 281 break; 282 } 283 if (!(flags & CO_CROSS)) 284 tp = 0; 285 else if (!(tp = sfstropen())) 286 goto bad; 287 else 288 { 289 while (n = *s++) 290 { 291 if (n == ':') 292 { 293 while (*s == ':') 294 s++; 295 if (!*s) 296 break; 297 if (*s == '.') 298 { 299 if (!*(s + 1)) 300 break; 301 if (*(s + 1) == ':') 302 { 303 s++; 304 continue; 305 } 306 } 307 } 308 sfputc(tp, n); 309 } 310 if (!(s = costash(tp))) 311 goto bad; 312 } 313 coquote(sp, s, !old); 314 if (tp) 315 sfstrclose(tp); 316 sfputc(sp, '\''); 317 if (old) 318 sfprintf(sp, "\nexport PATH"); 319 sfputc(sp, '\n'); 320 if (sync) 321 { 322 /* 323 * VPATH 324 */ 325 326 p = sfstrtell(sp); 327 sfprintf(sp, "vpath "); 328 n = PATH_MAX; 329 if (fs3d(FS3D_TEST)) 330 for (;;) 331 { 332 if (!(t = sfstrrsrv(sp, n))) 333 goto bad; 334 if ((m = mount(NiL, t, FS3D_GET|FS3D_ALL|FS3D_SIZE(n), NiL)) > 0) 335 m = n; 336 else 337 { 338 if (!m) 339 sfstrseek(sp, strlen(t), SEEK_CUR); 340 break; 341 } 342 } 343 else 344 { 345 m = 0; 346 sfprintf(sp, "- /#option/2d"); 347 } 348 if (m) 349 sfstrseek(sp, p, SEEK_SET); 350 else 351 sfprintf(sp, " 2>/dev/null || :\n"); 352 sfprintf(sp, "umask 0%o\ncd '%s'\n", co->init.mask, state.pwd); 353 } 354 done: 355 if (!(flags & CO_SERVER)) 356 { 357 sfprintf(sp, "%s%s=%05d${!%s-$$}\n", old ? "" : "export ", CO_ENV_TEMP, getpid(), (flags & CO_OSH) ? "" : ":"); 358 if (old) 359 sfprintf(sp, "export %s\n", CO_ENV_TEMP); 360 } 361 sfputc(sp, 0); 362 n = sfstrtell(sp); 363 if (co->vm) 364 { 365 if (co->init.script) 366 vmfree(co->vm, co->init.script); 367 if (!(co->init.script = vmnewof(co->vm, 0, char, n, 1))) 368 goto bad; 369 } 370 else 371 { 372 if (co->init.script) 373 free(co->init.script); 374 if (!(co->init.script = newof(0, char, n, 1))) 375 goto bad; 376 } 377 memcpy(co->init.script, sfstrbase(sp), n); 378 sfstrclose(sp); 379 } 380 else if (!co->init.script) 381 { 382 if (co->init.script = co->vm ? vmnewof(co->vm, 0, char, 1, 0) : newof(0, char, 1, 0)) 383 *co->init.script = 0; 384 } 385 return co->init.script; 386} 387 388/* 389 * return generic job initialization commands 390 */ 391 392char* 393coinit(int flags) 394{ 395 if (!state.generic) 396 { 397 if (!(state.generic = newof(0, Coshell_t, 1, 0))) 398 return 0; 399 state.generic->init.sync = 1; 400 } 401 return coinitialize(state.generic, flags); 402} 403