static Proc_t* runcmd(char** argv, int slave, int session) { long ops[4]; if (session) { ops[0] = PROC_FD_CTTY(slave); ops[1] = 0; } else { ops[0] = PROC_FD_DUP(slave, 0, PROC_FD_CHILD); ops[1] = PROC_FD_DUP(slave, 1, PROC_FD_CHILD); ops[2] = PROC_FD_DUP(slave, 2, PROC_FD_CHILD); ops[3] = 0; } return procopen(argv[0], argv, NiL, ops, 0); }
static int svc_connect(void* handle, int fd, Cs_id_t* id, int clone, char** argv) { Proc_t* p; int n; long ops[4]; static char* args[] = { "sh", "-i", 0 }; NoP(handle); NoP(clone); waitpid(-1, NiL, WNOHANG); n = 0; ops[n++] = PROC_FD_DUP(fd, 0, 0); ops[n++] = PROC_FD_DUP(fd, 1, 0); ops[n++] = PROC_FD_DUP(fd, 2, PROC_FD_CHILD); ops[n] = 0; if (!(p = procopen(NiL, args, NiL, ops, 0))) return(-1); procfree(p); csfd(fd, CS_POLL_CLOSE); return(0); }
void systrace(const char* id) { register int n; register char* out; char* s; char buf[PATH_MAX]; char* av[7]; long ov[2]; static char* trace[] = { "trace", "truss", "strace", "traces" }; if (!(s = getenv("HOME"))) return; if (!id && !(id = (const char*)error_info.id)) id = (const char*)trace[0]; out = buf; out += sfsprintf(out, sizeof(buf), "%s/.%s/%s", s, trace[0], id); if (access(buf, F_OK)) return; av[1] = trace[0]; av[2] = "-o"; av[3] = buf; av[4] = "-p"; av[5] = out + 1; av[6] = 0; ov[0] = PROC_FD_DUP(open("/dev/null", O_WRONLY), 2, PROC_FD_PARENT|PROC_FD_CHILD); ov[1] = 0; sfsprintf(out, &buf[sizeof(buf)] - out, ".%d", getpid()); for (n = 0; n < elementsof(trace); n++) if (!procfree(procopen(trace[n], av + 1, NiL, ov, PROC_ARGMOD|PROC_GID|PROC_UID|(n == (elementsof(trace) - 1) ? PROC_CLEANUP : 0)))) { sleep(1); break; } }
static int initiate(register Cs_t* state, char* user, char* path, char* service, char* name) { register char* s; char* on; char* local; Sfio_t* sp; Sfio_t* np; int n; char* av[REMOTE_ARGC]; char buf[PATH_MAX / 4]; local = csname(state, 0); s = service + strlen(service); *s++ = '/'; if (!(state->flags & CS_ADDR_SHARE)) { sfsprintf(buf, sizeof(buf), "%s\n", state->host); if (!(sp = tokline(buf, SF_STRING, NiL))) return -1; } else if (state->flags & CS_ADDR_LOCAL) { sfsprintf(buf, sizeof(buf), "%s\n", CS_HOST_LOCAL); if (!(sp = tokline(buf, SF_STRING, NiL))) return -1; } else { strcpy(s, CS_SVC_HOSTS); if (!(sp = tokline(service, SF_READ, NiL))) { if (streq(state->host, CS_HOST_SHARE)) sfsprintf(buf, sizeof(buf), "%s\n%s\n", CS_HOST_SHARE, CS_HOST_LOCAL); else sfsprintf(buf, sizeof(buf), "%s\n%s\n%s\n", state->host, CS_HOST_SHARE, CS_HOST_LOCAL); if (!(sp = tokline(buf, SF_STRING, NiL))) return -1; } } sfsprintf(s, PATH_MAX - (s - service) - 1, "%s%s", name, CS_SVC_SUFFIX); while (s = sfgetr(sp, '\n', 1)) if (tokscan(s, NiL, " %s ", &on) == 1) { if (streq(on, CS_HOST_LOCAL) || streq(on, local)) { sfclose(sp); av[0] = service; av[1] = path; av[2] = 0; return procclose(procopen(av[0], av, NiL, NiL, PROC_PRIVELEGED|PROC_ZOMBIE)) < 0 ? -1 : 0; } else if (!streq(on, CS_HOST_SHARE)) { Proc_t* proc; time_t otime; struct stat st; char fv[REMOTE_FLAGC]; long ov[3]; remote(state, on, user, path, 0, av, fv); otime = lstat(state->mount, &st) ? 0 : st.st_ctime; n = open("/dev/null", O_RDWR); ov[0] = PROC_FD_DUP(n, 0, 0); ov[1] = PROC_FD_DUP(n, 1, PROC_FD_PARENT|PROC_FD_CHILD); ov[2] = 0; if (proc = procopen(av[0], av, NiL, ov, PROC_PRIVELEGED|PROC_ZOMBIE)) { n = 1; for (;;) { if (!lstat(state->mount, &st) && st.st_ctime != otime) { if (!procclose(proc)) { sfclose(sp); return 0; } break; } /* * sleep() and MNT_TMP * hack around remote * fs cache delays */ if (n >= CS_REMOTE_DELAY) { procclose(proc); break; } if (n == 1) { *state->control = CS_MNT_TMP; if (remove(state->mount)) { close(open(state->mount, O_WRONLY|O_CREAT|O_TRUNC, 0)); remove(state->mount); } *state->control = CS_MNT_STREAM; } sleep(n); n <<= 1; } } } else if (!sfstacked(sp) && (np = csinfo(state, on, NiL))) sfstack(sp, np); } sfclose(sp); return -1; }
char* pathprobe_20100601(const char* lang, const char* tool, const char* aproc, int op, char* path, size_t pathsize, char* attr, size_t attrsize) { char* proc = (char*)aproc; register char* p; register char* k; register char* x; register char** ap; int n; int v; int force; ssize_t r; char* e; char* np; char* nx; char* probe; const char* dirs; const char* dir; Proc_t* pp; Sfio_t* sp; char buf[PATH_MAX]; char cmd[PATH_MAX]; char exe[PATH_MAX]; char lib[PATH_MAX]; char ver[PATH_MAX]; char key[16]; char* arg[8]; long ops[2]; unsigned long ptime; struct stat st; struct stat ps; if (*proc != '/') { if (p = strchr(proc, ' ')) { strncopy(buf, proc, p - proc + 1); proc = buf; } if (!(proc = pathpath(proc, NiL, PATH_ABSOLUTE|PATH_REGULAR|PATH_EXECUTE, cmd, sizeof(cmd)))) proc = (char*)aproc; else if (p) { n = strlen(proc); strncopy(proc + n, p, PATH_MAX - n - 1); } } if (!path) { path = buf; pathsize = sizeof(buf); } probe = PROBE; x = lib + sizeof(lib) - 1; k = lib + sfsprintf(lib, x - lib, "lib/%s/", probe); p = k + sfsprintf(k, x - k, "%s/%s/", lang, tool); pathkey(lang, tool, proc, key, sizeof(key), attr, attrsize); if (op >= -2) { strncopy(p, key, x - p); if (pathpath(lib, "", PATH_ABSOLUTE, path, pathsize) && !stat(path, &st) && (st.st_mode & S_IWUSR)) return path == buf ? strdup(path) : path; } e = strncopy(p, probe, x - p); if (!pathpath(lib, "", PATH_ABSOLUTE|PATH_EXECUTE, path, pathsize) || stat(path, &ps)) return 0; for (;;) { ptime = ps.st_mtime; n = strlen(path); if (n < (PATH_MAX - 5)) { strcpy(path + n, ".ini"); if (!stat(path, &st) && st.st_size && ptime < (unsigned long)st.st_mtime) ptime = st.st_mtime; path[n] = 0; } np = path + n - (e - k); nx = path + PATH_MAX - 1; strncopy(np, probe, nx - np); if (!stat(path, &st)) break; /* * yes lib/probe/<lang>/<proc>/probe * no lib/probe/probe * * do a manual pathaccess() to find a dir with both */ sfsprintf(exe, sizeof(exe), "lib/%s/%s", probe, probe); dirs = pathbin(); for (;;) { if (!(dir = dirs)) return 0; dirs = pathcat(dir, ':', "..", exe, path, pathsize); pathcanon(path, pathsize, 0); if (*path == '/' && pathexists(path, PATH_REGULAR|PATH_EXECUTE)) { pathcat(dir, ':', "..", lib, path, pathsize); pathcanon(path, pathsize, 0); if (*path == '/' && pathexists(path, PATH_REGULAR|PATH_EXECUTE) && !stat(path, &ps)) break; } } } strncopy(p, key, x - p); p = np; x = nx; strcpy(exe, path); if (op >= -1 && (!(st.st_mode & S_ISUID) && ps.st_uid != geteuid() || rofs(path))) { if (!(p = getenv("HOME"))) return 0; p = path + sfsprintf(path, PATH_MAX - 1, "%s/.%s/%s/", p, probe, HOSTTYPE); } strncopy(p, k, x - p); force = 0; if (op >= 0 && !stat(path, &st)) { if (ptime <= (unsigned long)st.st_mtime || ptime <= (unsigned long)st.st_ctime) { /* * verify (<sep><name><sep><option><sep><value>)* header */ if (sp = sfopen(NiL, path, "r")) { if (x = sfgetr(sp, '\n', 1)) { while (*x && *x != ' ') x++; while (*x == ' ') x++; if (n = *x++) for (;;) { for (k = x; *x && *x != n; x++); if (!*x) break; *x++ = 0; for (p = x; *x && *x != n; x++); if (!*x) break; *x++ = 0; for (e = x; *x && *x != n; x++); if (!*x) break; *x++ = 0; if (streq(k, "VERSION")) { ap = arg; *ap++ = proc; *ap++ = p; *ap = 0; ops[0] = PROC_FD_DUP(1, 2, 0); ops[1] = 0; if (pp = procopen(proc, arg, NiL, ops, PROC_READ)) { if ((v = x - e) >= sizeof(ver)) v = sizeof(ver) - 1; for (k = p = ver;; k++) { if (k >= p) { if (v <= 0 || (r = read(pp->rfd, k, v)) <= 0) break; v -= r; p = k + r; } if (*k == '\n' || *k == '\r') break; if (*k == n) *k = ' '; } *k = 0; if (strcmp(ver, e)) { force = 1; error(0, "probe processor %s version \"%s\" changed -- expected \"%s\"", proc, ver, e); } procclose(pp); } break; } } } sfclose(sp); } if (!force) op = -1; } if (op >= 0 && (st.st_mode & S_IWUSR)) { if (op == 0) error(0, "%s probe information for %s language processor %s must be manually regenerated", tool, lang, proc); op = -1; force = 0; } } if (op >= 0) { ap = arg; *ap++ = exe; if (force) *ap++ = "-f"; if (op > 0) *ap++ = "-s"; *ap++ = (char*)lang; *ap++ = (char*)tool; *ap++ = proc; *ap = 0; if (procrun(exe, arg, 0)) return 0; if (eaccess(path, R_OK)) return 0; } return path == buf ? strdup(path) : path; }