123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433 |
- #include "mk.h"
- char *shell = "/bin/rc";
- char *shellname = "rc";
- static Word *encodenulls(char*, int);
- void
- readenv(void)
- {
- char *p;
- int envf, f;
- Dir *e;
- char nam[1024];
- int i, n, len;
- Word *w;
- rfork(RFENVG); /* use copy of the current environment variables */
- envf = open("/env", OREAD);
- if(envf < 0)
- return;
- while((n = dirread(envf, &e)) > 0){
- for(i = 0; i < n; i++){
- len = e[i].length;
- /* don't import funny names, NULL values,
- * or internal mk variables
- */
- if(len <= 0 || *shname(e[i].name) != '\0')
- continue;
- if (symlook(e[i].name, S_INTERNAL, 0))
- continue;
- snprint(nam, sizeof nam, "/env/%s", e[i].name);
- f = open(nam, OREAD);
- if(f < 0)
- continue;
- p = Malloc(len+1);
- if(read(f, p, len) != len){
- perror(nam);
- close(f);
- continue;
- }
- close(f);
- if (p[len-1] == 0)
- len--;
- else
- p[len] = 0;
- w = encodenulls(p, len);
- free(p);
- p = strdup(e[i].name);
- setvar(p, (void *) w);
- symlook(p, S_EXPORTED, (void*)"")->u.ptr = "";
- }
- free(e);
- }
- close(envf);
- }
- /* break string of values into words at 01's or nulls*/
- static Word *
- encodenulls(char *s, int n)
- {
- Word *w, *head;
- char *cp;
- head = w = 0;
- while (n-- > 0) {
- for (cp = s; *cp && *cp != '\0'; cp++)
- n--;
- *cp = 0;
- if (w) {
- w->next = newword(s);
- w = w->next;
- } else
- head = w = newword(s);
- s = cp+1;
- }
- if (!head)
- head = newword("");
- return head;
- }
- /* as well as 01's, change blanks to nulls, so that rc will
- * treat the words as separate arguments
- */
- void
- exportenv(Envy *e)
- {
- int f, n, hasvalue, first;
- Word *w;
- Symtab *sy;
- char nam[256];
- for(;e->name; e++){
- sy = symlook(e->name, S_VAR, 0);
- if (e->values == 0 || e->values->s == 0 || e->values->s[0] == 0)
- hasvalue = 0;
- else
- hasvalue = 1;
- if(sy == 0 && !hasvalue) /* non-existant null symbol */
- continue;
- snprint(nam, sizeof nam, "/env/%s", e->name);
- if (sy != 0 && !hasvalue) { /* Remove from environment */
- /* we could remove it from the symbol table
- * too, but we're in the child copy, and it
- * would still remain in the parent's table.
- */
- remove(nam);
- delword(e->values);
- e->values = 0; /* memory leak */
- continue;
- }
-
- f = create(nam, OWRITE, 0666L);
- if(f < 0) {
- fprint(2, "can't create %s, f=%d\n", nam, f);
- perror(nam);
- continue;
- }
- first = 1;
- for (w = e->values; w; w = w->next) {
- n = strlen(w->s);
- if (n) {
- if(first)
- first = 0;
- else{
- if (write (f, "\0", 1) != 1)
- perror(nam);
- }
- if (write(f, w->s, n) != n)
- perror(nam);
- }
- }
- close(f);
- }
- }
- int
- waitfor(char *msg)
- {
- Waitmsg *w;
- int pid;
- if((w=wait()) == nil)
- return -1;
- strecpy(msg, msg+ERRMAX, w->msg);
- pid = w->pid;
- free(w);
- return pid;
- }
- void
- expunge(int pid, char *msg)
- {
- postnote(PNPROC, pid, msg);
- }
- int
- execsh(char *args, char *cmd, Bufblock *buf, Envy *e)
- {
- char *p;
- int tot, n, pid, in[2], out[2];
- if(buf && pipe(out) < 0){
- perror("pipe");
- Exit();
- }
- pid = rfork(RFPROC|RFFDG|RFENVG);
- if(pid < 0){
- perror("mk rfork");
- Exit();
- }
- if(pid == 0){
- if(buf)
- close(out[0]);
- if(pipe(in) < 0){
- perror("pipe");
- Exit();
- }
- pid = fork();
- if(pid < 0){
- perror("mk fork");
- Exit();
- }
- if(pid != 0){
- dup(in[0], 0);
- if(buf){
- dup(out[1], 1);
- close(out[1]);
- }
- close(in[0]);
- close(in[1]);
- if (e)
- exportenv(e);
- if(shflags)
- execl(shell, shellname, shflags, args, nil);
- else
- execl(shell, shellname, args, nil);
- perror(shell);
- _exits("exec");
- }
- close(out[1]);
- close(in[0]);
- p = cmd+strlen(cmd);
- while(cmd < p){
- n = write(in[1], cmd, p-cmd);
- if(n < 0)
- break;
- cmd += n;
- }
- close(in[1]);
- _exits(0);
- }
- if(buf){
- close(out[1]);
- tot = 0;
- for(;;){
- if (buf->current >= buf->end)
- growbuf(buf);
- n = read(out[0], buf->current, buf->end-buf->current);
- if(n <= 0)
- break;
- buf->current += n;
- tot += n;
- }
- if (tot && buf->current[-1] == '\n')
- buf->current--;
- close(out[0]);
- }
- return pid;
- }
- int
- pipecmd(char *cmd, Envy *e, int *fd)
- {
- int pid, pfd[2];
- if(DEBUG(D_EXEC))
- fprint(1, "pipecmd='%s'\n", cmd);/**/
- if(fd && pipe(pfd) < 0){
- perror("pipe");
- Exit();
- }
- pid = rfork(RFPROC|RFFDG|RFENVG);
- if(pid < 0){
- perror("mk fork");
- Exit();
- }
- if(pid == 0){
- if(fd){
- close(pfd[0]);
- dup(pfd[1], 1);
- close(pfd[1]);
- }
- if(e)
- exportenv(e);
- if(shflags)
- execl(shell, shellname, shflags, "-c", cmd, nil);
- else
- execl(shell, shellname, "-c", cmd, nil);
- perror(shell);
- _exits("exec");
- }
- if(fd){
- close(pfd[1]);
- *fd = pfd[0];
- }
- return pid;
- }
- void
- Exit(void)
- {
- while(waitpid() >= 0)
- ;
- exits("error");
- }
- int
- notifyf(void *a, char *msg)
- {
- static int nnote;
- USED(a);
- if(++nnote > 100){ /* until andrew fixes his program */
- fprint(2, "mk: too many notes\n");
- notify(0);
- abort();
- }
- if(strcmp(msg, "interrupt")!=0 && strcmp(msg, "hangup")!=0)
- return 0;
- killchildren(msg);
- return -1;
- }
- void
- catchnotes()
- {
- atnotify(notifyf, 1);
- }
- char*
- maketmp(void)
- {
- static char temp[] = "/tmp/mkargXXXXXX";
- mktemp(temp);
- return temp;
- }
- int
- chgtime(char *name)
- {
- Dir sbuf;
- if(access(name, AEXIST) >= 0) {
- nulldir(&sbuf);
- sbuf.mtime = time((long *)0);
- return dirwstat(name, &sbuf);
- }
- return close(create(name, OWRITE, 0666));
- }
- void
- rcopy(char **to, Resub *match, int n)
- {
- int c;
- char *p;
- *to = match->sp; /* stem0 matches complete target */
- for(to++, match++; --n > 0; to++, match++){
- if(match->sp && match->ep){
- p = match->ep;
- c = *p;
- *p = 0;
- *to = strdup(match->sp);
- *p = c;
- }
- else
- *to = 0;
- }
- }
- void
- dirtime(char *dir, char *path)
- {
- int i, fd, n;
- Dir *d;
- char buf[4096];
- fd = open(dir, OREAD);
- if(fd >= 0){
- while((n = dirread(fd, &d)) > 0){
- for(i=0; i<n; i++){
- if(d[i].mtime == 0) /* yeah, this is likely */
- continue;
- sprint(buf, "%s%s", path, d[i].name);
- if(symlook(buf, S_TIME, 0))
- continue;
- symlook(strdup(buf), S_TIME, (void*)d[i].mtime)->u.value = d[i].mtime;
- }
- free(d);
- }
- close(fd);
- }
- }
- void
- bulkmtime(char *dir)
- {
- char buf[4096];
- char *ss, *s, *sym;
- if(dir){
- sym = dir;
- s = dir;
- if(strcmp(dir, "/") == 0)
- strcpy(buf, dir);
- else
- sprint(buf, "%s/", dir);
- }else{
- s = ".";
- sym = "";
- buf[0] = 0;
- }
- if(symlook(sym, S_BULKED, 0))
- return;
- ss = strdup(sym);
- symlook(ss, S_BULKED, (void*)ss);
- dirtime(s, buf);
- }
- ulong
- mkmtime(char *name, int force)
- {
- Dir *d;
- char *s, *ss, carry;
- ulong t;
- Symtab *sym;
- char buf[4096];
- strcpy(buf, name);
- cleanname(buf);
- name = buf;
- s = utfrrune(name, '/');
- if(s == name)
- s++;
- if(s){
- ss = name;
- carry = *s;
- *s = 0;
- }else{
- ss = 0;
- carry = 0;
- }
- bulkmtime(ss);
- if(carry)
- *s = carry;
- if(!force){
- sym = symlook(name, S_TIME, 0);
- if(sym)
- return sym->u.value;
- return 0;
- }
- if((d = dirstat(name)) == nil)
- return 0;
- t = d->mtime;
- free(d);
- return t;
- }
|