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