DDSconverter_t *DDSloadconverter ( DDSschema_t *ischemap, DDSschema_t *oschemap, char *sostr ) { DDSconverter_t *converterp; char file[PATH_MAX]; if (!(converterp = vmalloc (Vmheap, sizeof (DDSconverter_t)))) { SUwarning (1, "DDSloadconverter", "vmalloc failed for converterp"); return NULL; } if (access (sostr, R_OK) == 0) { if (strchr (sostr, '/') == NULL) file[0] = '.', file[1] = '/', strcpy (file + 2, sostr); else strcpy (file, sostr); } else if ( !pathaccess (getenv ("PATH"), "../lib/dds", sostr, R_OK, file, PATH_MAX) ) { SUwarning (1, "DDSloadconverter", "access failed for %s", sostr); return NULL; } if (loadconverterso (ischemap, oschemap, file, FALSE, converterp) == -1) { SUwarning (1, "DDSloadconverter", "loadconverterso failed"); return NULL; } return converterp; }
char* pathpath_20100601(const char* p, const char* a, int mode, register char* path, size_t size) { register char* s; char* x; char buf[PATH_MAX]; static char* cmd; if (!path) path = buf; if (!p) { if (cmd) free(cmd); cmd = a ? strdup(a) : (char*)0; return 0; } if (strlen(p) < size) { strcpy(path, p); if (pathexists(path, mode)) { if (*p != '/' && (mode & PATH_ABSOLUTE)) { getcwd(buf, sizeof(buf)); s = buf + strlen(buf); sfsprintf(s, sizeof(buf) - (s - buf), "/%s", p); if (path != buf) strcpy(path, buf); } return (path == buf) ? strdup(path) : path; } } if (*p == '/') a = 0; else if (s = (char*)a) { x = s; if (strchr(p, '/')) { a = p; p = ".."; } else a = 0; if ((!cmd || *cmd) && (strchr(s, '/') || (s = cmd))) { if (!cmd && *s == '/') cmd = strdup(s); if (strlen(s) < (sizeof(buf) - 6)) { s = strcopy(path, s); for (;;) { do if (s <= path) goto normal; while (*--s == '/'); do if (s <= path) goto normal; while (*--s != '/'); strcpy(s + 1, "bin"); if (pathexists(path, PATH_EXECUTE)) { if (s = pathaccess(path, p, a, mode, path, size)) return path == buf ? strdup(s) : s; goto normal; } } normal: ; } } } x = !a && strchr(p, '/') ? "" : pathbin(); if (!(s = pathaccess(x, p, a, mode, path, size)) && !*x && (x = getenv("FPATH"))) s = pathaccess(x, p, a, mode, path, size); return (s && path == buf) ? strdup(s) : s; }
int main (int argc, char **argv) { int norun; char *mapnamep, mapmode, *onamep, *classp; int keytype, keylen, valtype, vallen, dictincr, itemincr; AGGRfile_t *iafp, *oafp; char file[PATH_MAX]; Sfio_t *fp; AGGRreaggr_t *reaggrs; int reaggrn, reaggrl; int count, rejcount; char *line, *s; unsigned char *ikeyp, *okeyp; char *avs[10]; int avn; int ret; if (AGGRinit () == -1) SUerror ("aggrreaggr", "init failed"); mapnamep = NULL, mapmode = 0; onamep = "reaggr.aggr"; classp = "aggrreaggr"; keytype = AGGR_TYPE_STRING; keylen = -1; valtype = -1, vallen = -1; dictincr = 1, itemincr = 1; norun = 0; for (;;) { switch (optget (argv, usage)) { case -100: onamep = opt_info.arg; continue; case -101: classp = opt_info.arg; continue; case -102: if (AGGRparsetype (opt_info.arg, &keytype, &keylen) == -1) SUerror ("aggrreaggr", "bad argument for -kt option"); continue; case -103: if (AGGRparsetype (opt_info.arg, &valtype, &vallen) == -1) SUerror ("aggrreaggr", "bad argument for -vt option"); continue; case -104: dictincr = opt_info.num; continue; case -105: itemincr = opt_info.num; continue; case -114: mapnamep = opt_info.arg; mapmode = 'a'; continue; case -115: mapnamep = opt_info.arg; mapmode = 'b'; continue; case -999: SUwarnlevel++; continue; case '?': SUusage (0, "aggrreaggr", opt_info.arg); norun = 1; continue; case ':': SUusage (1, "aggrreaggr", opt_info.arg); norun = 2; continue; } break; } if (norun) return norun - 1; argc -= opt_info.index, argv += opt_info.index; if (argc != 1) SUerror ("aggrreaggr", "no input file name specified"); if (!mapnamep) SUerror ("aggrreaggr", "no map file name specified"); if (!(iafp = AGGRopen (argv[0], AGGR_RWMODE_RD, 1, TRUE))) SUerror ("aggrreaggr", "open failed"); if (valtype == -1) { valtype = AGGR_TYPE_FLOAT; vallen = ( iafp->hdr.vallen / AGGRtypelens[iafp->hdr.valtype] ) * AGGRtypelens[valtype]; } if (!(oafp = AGGRcreate ( onamep, 1, 1, keytype, valtype, classp, keylen, vallen, dictincr, itemincr, 1, TRUE ))) SUerror ("aggrreaggr", "create failed"); if (strcmp (mapnamep, "-") == 0) fp = sfstdin; else { if (access (mapnamep, R_OK) == 0) strcpy (file, mapnamep); else if (!pathaccess ( getenv ("PATH"), "../lib/aggr", mapnamep, R_OK, file, PATH_MAX )) SUerror ("aggrreaggr", "cannot find map file"); if (!(fp = sfopen (NULL, file, "r"))) SUerror ("aggrreaggr", "sfopen failed"); } sfsetbuf (fp, NULL, 1048576); if (iafp->ad.keylen != -1) if (!(ikeyp = vmalloc (Vmheap, iafp->ad.keylen))) SUerror ("aggrreaggr", "vmalloc failed"); if (oafp->ad.keylen != -1) if (!(okeyp = vmalloc (Vmheap, oafp->ad.keylen))) SUerror ("aggrreaggr", "vmalloc failed"); if (!(reaggrs = vmalloc (Vmheap, 100 * sizeof (AGGRreaggr_t)))) SUerror ("aggrreaggr", "vmalloc failed"); reaggrn = 100, reaggrl = 0; count = 0, rejcount = 0; switch (mapmode) { case 'a': while ((line = sfgetr (fp, '\n', 1))) { count++; if ((avn = tokscan (line, &s, " %v ", avs, 10)) < 1 || avn > 2) { SUwarning (1, "aggrreaggr", "bad line %d", count); rejcount++; continue; } if (reaggrl >= reaggrn) { if (!(reaggrs = vmresize ( Vmheap, reaggrs, reaggrn * 2 * sizeof (AGGRreaggr_t), VM_RSCOPY ))) SUerror ("aggrreaggr", "vmresize failed"); reaggrn *= 2; } if (_aggrdictscankey (iafp, avs[0], &ikeyp) == -1) { SUwarning (1, "aggrreaggr", "bad key at line %d", count); rejcount++; continue; } reaggrs[reaggrl].okeyp = copy (iafp, ikeyp); if (_aggrdictscankey (oafp, avs[1], &okeyp) == -1) { SUwarning (1, "aggrreaggr", "bad key at line %d", count); rejcount++; continue; } reaggrs[reaggrl].nkeyp = copy (oafp, okeyp); if (avn == 3) reaggrs[reaggrl].nitemi = atoi (avs[2]); else reaggrs[reaggrl].nitemi = -1; reaggrl++; if (count % 10000 == 0) SUmessage ( 1, "aggrreaggr", "processed %d lines, dropped %d", count, rejcount ); } break; case 'b': while (1) { if (reaggrl >= reaggrn) { if (!(reaggrs = vmresize ( Vmheap, reaggrs, reaggrn * 2 * sizeof (AGGRreaggr_t), VM_RSCOPY ))) SUerror ("aggrreaggr", "vmresize failed"); reaggrn *= 2; } if (iafp->ad.keylen == -1) { if (!(ikeyp = (unsigned char *) sfgetr (fp, 0, 1))) { if (sfvalue (fp) != 0) SUerror ("aggrreaggr", "bad entry %d", reaggrl); else break; } } else { if ((ret = sfread (fp, ikeyp, iafp->ad.keylen)) == 0) break; else if (ret != iafp->ad.keylen) SUerror ("aggrreaggr", "bad entry %d", reaggrl); SWAPKEY (ikeyp, iafp->hdr.keytype, iafp->ad.keylen); } reaggrs[reaggrl].okeyp = copy (iafp, ikeyp); if (oafp->ad.keylen == -1) { if (!(okeyp = (unsigned char *) sfgetr (fp, 0, 1))) { if (sfvalue (fp) != 0) SUerror ("aggrreaggr", "bad entry %d", reaggrl); else break; } } else { if ((ret = sfread (fp, okeyp, oafp->ad.keylen)) == 0) break; else if (ret != oafp->ad.keylen) SUerror ("aggrreaggr", "bad entry %d", reaggrl); } reaggrs[reaggrl].nkeyp = copy (oafp, okeyp); count++; reaggrs[reaggrl].nitemi = -1; reaggrl++; if (count % 10000 == 0) SUmessage ( 1, "aggrreaggr", "processed %d lines, dropped %d", count, rejcount ); } break; } SUmessage ( rejcount > 0 ? 0 : 1, "aggrreaggr", "processed %d lines, dropped %d", count, rejcount ); if (AGGRreaggr (iafp, reaggrs, reaggrl, oafp) == -1) SUerror ("aggrreaggr", "reaggr failed"); if (AGGRminmax (oafp, TRUE) == -1) SUerror ("aggrreaggr", "minmax failed"); if (AGGRclose (oafp) == -1) SUerror ("aggrreaggr", "close failed"); if (AGGRterm () == -1) SUerror ("aggrreaggr", "term failed"); return 0; }
int csopen(register Cs_t* state, const char* apath, int op) { register char* path = (char*)apath; register char* b; register char* s; register int n; int fd; char* t; char* u; char* type; char* endtype; char* host; char* endhost; char* serv; char* endserv; char* qual; char* endqual; char* opath; char* user = 0; char* group = 0; char* trust = 0; char* arg = 0; int nfd = -1; int uid = -1; int gid = -1; int sid = -1; int auth = 1; int mode; unsigned long addr; unsigned long port = 0; struct stat st; char buf[PATH_MAX]; char tmp[PATH_MAX]; if (!path) { errno = EFAULT; return -1; } csprotect(&cs); if (op < 0) op = CS_OPEN_TEST; messagef((state->id, NiL, -8, "open(%s,%o) call", path, op)); /* * blast out the parts */ opath = path; if (pathgetlink(path, buf, sizeof(buf)) <= 0) { if (strlen(path) >= sizeof(buf)) return -1; strcpy(buf, path); } else if ((state->flags & CS_ADDR_LOCAL) && (s = strrchr(buf, '/'))) { /* * dynamic ip assignment can change the addr * underfoot in some implementations so we * double check the local ip here */ strcpy(tmp, buf); if (tokscan(tmp, NiL, "/dev/%s/%s/%s", &type, NiL, &serv) == 3) sfsprintf(buf, sizeof(buf), "/dev/%s/%s/%s", type, csntoa(state, 0), serv); } path = buf; pathcanon(path, 0, 0); errno = ENOENT; strcpy(state->path, path); b = path; if ((*b++ != '/') || !(s = strchr(b, '/'))) return -1; *s++ = 0; if (!streq(b, "dev")) return -1; if (b = strchr(s, '/')) *b++ = 0; if (streq(s, "fdp")) { #if !( CS_LIB_SOCKET_UN || CS_LIB_STREAM || CS_LIB_V10 ) if (access(CS_PROC_FD_TST, F_OK)) { errno = ENODEV; messagef((state->id, NiL, -1, "open: %s: %s: not supported", state->path, s)); return -1; } #endif } else if (!streq(s, "tcp") && !streq(s, "udp")) { messagef((state->id, NiL, -1, "open: %s: %s: invalid type", state->path, s)); return -1; } #if !( CS_LIB_SOCKET || CS_LIB_STREAM || CS_LIB_V10 ) else { errno = ENODEV; messagef((state->id, NiL, -1, "open: %s: %s: not supported", state->path, s)); return -1; } #endif type = s; qual = state->qual; if (!b) host = serv = 0; else { host = b; if (!(s = strchr(b, '/'))) serv = 0; else { *s++ = 0; serv = s; /* * grab the next fd to preserve open semantics */ for (n = 0; n < 10; n++) if ((nfd = dup(n)) >= 0) break; /* * get qual, perm and arg */ mode = S_IRWXU|S_IRWXG|S_IRWXO; if (b = strchr(s, '/')) { *b++ = 0; do { if (*b == '#') { arg = b + 1; break; } if (u = strchr(b, '/')) *u++ = 0; if (s = strchr(b, '=')) *s++ = 0; for (n = 0, t = b; *t; n = HASHKEYPART(n, *t++)); switch (n) { case HASHKEY5('g','r','o','u','p'): group = s ? s : ""; break; case HASHKEY5('l','o','c','a','l'): op |= CS_OPEN_LOCAL; break; case HASHKEY3('n','o','w'): op |= CS_OPEN_NOW; break; case HASHKEY5('o','t','h','e','r'): auth = 0; break; case HASHKEY6('r','e','m','o','t','e'): op |= CS_OPEN_REMOTE; break; case HASHKEY5('s','h','a','r','e'): op |= CS_OPEN_SHARE; break; case HASHKEY5('s','l','a','v','e'): op |= CS_OPEN_SLAVE; break; case HASHKEY4('t','e','s','t'): op |= CS_OPEN_TEST; break; case HASHKEY5('t','r','u','s','t'): op |= CS_OPEN_TRUST; trust = s; break; case HASHKEY4('u','s','e','r'): user = s ? s : ""; break; default: qual += sfsprintf(qual, sizeof(state->qual) - (qual - state->qual) - 1, "%s%s", qual == state->qual ? "" : "-", b); if (s) *(s - 1) = '='; break; } } while (b = u); } } } if (*type != 't') auth = 0; strncpy(state->type, type, sizeof(state->type) - 1); qual = (qual == state->qual) ? (char*)0 : state->qual; messagef((state->id, NiL, -8, "open: type=%s host=%s serv=%s qual=%s", type, host, serv, qual)); if (host) { /* * validate host */ if (!(state->addr = addr = csaddr(state, host))) { if (serv && !(op & CS_OPEN_CREATE) && *type == 't' && (port = csport(state, type, serv)) >= CS_PORT_MIN && port <= CS_PORT_MAX) { /* * attempt proxy connection */ if (nfd >= 0) { close(nfd); nfd = -1; } if ((fd = state->proxy.addr ? csbind(state, type, state->proxy.addr, state->proxy.port, 0L) : reopen(state, csvar(state, CS_VAR_PROXY, 0))) >= 0) { state->proxy.addr = state->addr; state->proxy.port = state->port; n = sfsprintf(tmp, sizeof(tmp), "\n%s!%s!%d\n\n%s\n%s\n0\n-1\n-1\n", type, host, port, csname(state, 0), error_info.id ? error_info.id : state->id); if (cswrite(state, fd, tmp, n) == n && (n = csread(state, fd, tmp, sizeof(tmp), CS_LINE)) >= 2) { if (tmp[0] == '0' && tmp[1] == '\n') return fd; if (error_info.trace <= -4 && n > 2) { s = tmp; s[n - 1] = 0; while (*s && *s++ != '\n'); messagef((state->id, NiL, -4, "%s error message `%s'", csvar(state, CS_VAR_PROXY, 0), s)); } } close(fd); } } #ifdef EADDRNOTAVAIL errno = EADDRNOTAVAIL; #else errno = ENOENT; #endif goto bad; } if (op & CS_OPEN_LOCAL) { state->flags |= CS_ADDR_LOCAL; state->flags &= ~CS_ADDR_REMOTE; } if (op & CS_OPEN_NOW) state->flags |= CS_ADDR_NOW; if ((op & (CS_OPEN_AGENT|CS_OPEN_REMOTE)) == CS_OPEN_REMOTE) { state->flags |= CS_ADDR_REMOTE; state->flags &= ~CS_ADDR_LOCAL; } if (op & CS_OPEN_SHARE) state->flags |= CS_ADDR_SHARE; if (op & CS_OPEN_SLAVE) state->flags |= CS_DAEMON_SLAVE; if (op & CS_OPEN_TEST) state->flags |= CS_ADDR_TEST; if (op & CS_OPEN_TRUST) state->flags |= CS_ADDR_TRUST; if ((state->flags & CS_ADDR_REMOTE) && (!serv || !strneq(serv, CS_SVC_INET, sizeof(CS_SVC_INET) - 1) && (strtol(serv, &t, 0), *t))) return agent(state, state->host, state->user, state->path); if (s = user) { n = geteuid(); if (*s) { if ((uid = struid(s)) < 0) { uid = strtol(s, &t, 0); if (*t) { errno = EACCES; goto bad; } } if (n && uid != n) { errno = EACCES; goto bad; } } else uid = n; mode &= ~(S_IRWXG|S_IRWXO); } if (s = group) { n = getegid(); if (*s) { if ((gid = strgid(s)) < 0) { gid = strtol(s, &t, 0); if (*t) { errno = EACCES; goto bad; } } if (geteuid() && gid != n) { gid_t* groups; int g; if ((g = getgroups(0, NiL)) <= 0) g = getconf("NGROUPS_MAX"); if (groups = newof(0, gid_t, g, 0)) { for (n = getgroups(g, groups); n >= 0; n--) if (gid == groups[n]) break; free(groups); } else n = -1; if (n < 0) { errno = EACCES; goto bad; } } } else gid = n; mode &= ~S_IRWXO; } if (s = trust) { if (!*s) sid = geteuid(); else if ((sid = struid(s)) < 0) { sid = strtol(s, &t, 0); if (*t) { errno = EACCES; goto bad; } } } if (state->flags & CS_ADDR_SHARE) host = CS_HOST_SHARE; else { host = state->host; if (!(state->flags & CS_ADDR_LOCAL)) { if (*type == 'f') { errno = ENODEV; goto bad; } if (op & CS_OPEN_CREATE) { errno = EROFS; goto bad; } } if (serv && !qual && *type != 'f' && (port = csport(state, type, serv)) != CS_PORT_INVALID) { if (op & CS_OPEN_CREATE) addr = 0; else if (port == CS_PORT_RESERVED || port == CS_PORT_NORMAL) goto bad; if (nfd >= 0) { close(nfd); nfd = -1; } state->control = 0; if ((fd = csbind(state, type, addr, port, 0L)) >= 0) { if (mode != (S_IRWXU|S_IRWXG|S_IRWXO) && csauth(state, fd, NiL, NiL)) { close(fd); return -1; } return fd; } } } } /* * get the mount dir prefix */ if (opath == (b = path = state->mount)) { #ifdef ELOOP errno = ELOOP; #else errno = EINVAL; #endif goto bad; } if (*type == 'f') { if (host && !(state->flags & CS_ADDR_LOCAL)) { errno = ENODEV; goto bad; } b += sfsprintf(b, sizeof(state->mount) - (b - path), "%s", csvar(state, CS_VAR_LOCAL, 0)); if ((op & CS_OPEN_CREATE) && eaccess(path, X_OK) && (mkdir(path, S_IRWXU|S_IRWXG|S_IRWXO) || chmod(path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO))) goto bad; } else { if (op & CS_OPEN_TRUST) { if (!pathaccess(csvar(state, CS_VAR_TRUST, 1), csvar(state, CS_VAR_SHARE, 1), NiL, PATH_EXECUTE, b, sizeof(state->mount) - (b - state->mount))) goto bad; } else if (!pathpath(csvar(state, CS_VAR_SHARE, 0), "", PATH_EXECUTE, b, sizeof(state->mount) - (b - state->mount))) goto bad; b += strlen(b); } /* * add the type */ b += sfsprintf(b, sizeof(state->mount) - (b - path), "/%s", type); if (!host) { *(state->control = b + 1) = 0; if (nfd >= 0) close(nfd); if ((fd = open(path, O_RDONLY)) < 0) { mkmount(state, S_IRWXU|S_IRWXG|S_IRWXO, -1, -1, NiL, NiL, NiL); fd = open(path, O_RDONLY); } if (fd < 0) messagef((state->id, NiL, -1, "open: %s: %s: open error", state->path, path)); return fd; } endtype = b; /* * add the host */ if (strlen(host) <= CS_MNT_MAX) b += sfsprintf(b, sizeof(state->mount) - (b - path), "/%s", host); else { s = csntoa(state, addr); if (strlen(s) <= CS_MNT_MAX) b += sfsprintf(b, sizeof(state->mount) - (b - path), "/%s", s); else { unsigned char* a = (unsigned char*)&addr; b += sfsprintf(b, sizeof(state->mount) - (b - path), "/0x%X.%X.%X.%X", a[0], a[1], a[2], a[3]); } } messagef((state->id, NiL, -8, "%s:%d host=`%s' path=`%s'", __FILE__, __LINE__, host, path)); if (!serv) { *(state->control = b + 1) = 0; if (nfd >= 0) close(nfd); if ((fd = open(path, O_RDONLY)) < 0) messagef((state->id, NiL, -1, "open: %s: %s: open error", state->path, path)); return fd; } endhost = b; /* * add the service */ sfsprintf(b, sizeof(state->mount) - (b - path), "%s/%s/%s/%s%s", CS_SVC_DIR, type, serv, serv, CS_SVC_SUFFIX); if (!pathpath(b, "", PATH_ABSOLUTE|PATH_EXECUTE, tmp, sizeof(tmp)) || stat(tmp, &st)) op |= CS_OPEN_TEST; else { *strrchr(tmp, '/') = 0; if (!(op & CS_OPEN_TRUST)) sid = st.st_uid; if (!st.st_size) op |= CS_OPEN_TEST; } b += sfsprintf(b, sizeof(state->mount) - (b - path), "/%s", serv); endserv = b; /* * add the qualifier and perm */ if (sid >= 0) b += sfsprintf(b, sizeof(state->mount) - (b - path), "/%d-", sid); else b += sfsprintf(b, sizeof(state->mount) - (b - path), "/-"); if (uid >= 0) b += sfsprintf(b, sizeof(state->mount) - (b - path), "%d-", uid); else if (gid >= 0) b += sfsprintf(b, sizeof(state->mount) - (b - path), "-%d", gid); else b += sfsprintf(b, sizeof(state->mount) - (b - path), "-"); #if limit_qualifier_length endqual = endserv + CS_MNT_MAX + 1; #else endqual = state->mount + sizeof(state->mount) - 1; #endif if (qual) { if (b < endqual) *b++ = '-'; while (b < endqual && *qual) *b++ = *qual++; } if (*type == 't' && !auth) { if (b >= endqual) b--; *b++ = CS_MNT_OTHER; } /* * add in the connect stream control */ *b++ = '/'; *b = CS_MNT_STREAM; strcpy(b + 1, CS_MNT_TAIL); messagef((state->id, NiL, -8, "%s:%d %s", __FILE__, __LINE__, state->mount)); state->control = b; /* * create the mount subdirs if necessary */ if ((op & CS_OPEN_CREATE) && mkmount(state, mode, uid, gid, endserv, endhost, endtype)) goto bad; mode &= S_IRWXU|S_IRWXG|S_IRWXO; if (nfd >= 0) { close(nfd); nfd = -1; } if (op & CS_OPEN_MOUNT) { messagef((state->id, NiL, -1, "open(%s,%o) = %d, mount = %s", state->path, op, state->mount)); return 0; } if (*type == 'f') { /* * {fdp} */ if ((fd = doattach(state, path, op, mode, user, opath, tmp, serv, b)) < 0) return -1; } else { /* * {tcp,udp} */ messagef((state->id, NiL, -8, "%s:%d %s", __FILE__, __LINE__, state->mount)); if ((fd = reopen(state, path)) < 0) { /* * check for old single char cs mount */ *(state->control + 1) = 0; if ((fd = reopen(state, path)) < 0) messagef((state->id, NiL, -1, "open: %s: %s: reopen error", state->path, path)); *(state->control + 1) = CS_MNT_TAIL[0]; } if (op & CS_OPEN_CREATE) { if (fd >= 0) { close(fd); errno = EEXIST; return -1; } if (errno != ENOENT && errno != ENOTDIR) return -1; sigcritical(1); *state->control = CS_MNT_LOCK; if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0)) < 0) { if (stat(path, &st)) { messagef((state->id, NiL, -1, "open: %s: %s: creat error", state->path, path)); goto unblock; } if ((CSTIME() - (unsigned long)st.st_ctime) < 2 * 60) { errno = EEXIST; messagef((state->id, NiL, -1, "open: %s: %s: another server won the race", state->path, path)); goto unblock; } if (remove(path)) { messagef((state->id, NiL, -1, "open: %s: %s: remove error", state->path, path)); goto unblock; } if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0)) < 0) { messagef((state->id, NiL, -1, "open: %s: %s: creat error", state->path, path)); goto unblock; } } close(fd); if (!port && (n = strtol(serv, &t, 0)) && t > serv && !*t) port = n; else if (geteuid()) port = CS_NORMAL; else port = CS_RESERVED; if ((fd = csbind(state, type, 0L, port, 0L)) >= 0) { *state->control = CS_MNT_STREAM; remove(path); if (pathsetlink(cspath(state, fd, 0), path)) { messagef((state->id, NiL, -1, "open: %s: %s: link error", cspath(state, fd, 0), path)); close(fd); fd = -1; } } unblock: *state->control = CS_MNT_LOCK; remove(path); sigcritical(0); *state->control = CS_MNT_STREAM; if (fd < 0) return -1; } else if (fd < 0 && ((op & CS_OPEN_TEST) || initiate(state, user, opath, tmp, serv) || (fd = reopen(state, path)) < 0)) { messagef((state->id, NiL, -1, "open: %s: %s: reopen/initiate error", state->path, path)); return -1; } else if (!(op & CS_OPEN_AGENT)) { *state->control = CS_MNT_AUTH; n = csauth(state, fd, path, arg); *state->control = CS_MNT_STREAM; if (n) { close(fd); messagef((state->id, NiL, -1, "open: %s: %s: authentication error", state->path, path)); return -1; } } } /* * fd is open at this point * make sure its not a bogus mount */ if (mode != (S_IRWXU|S_IRWXG|S_IRWXO)) { *state->control = 0; n = stat(path, &st); *state->control = CS_MNT_STREAM; if (n) { messagef((state->id, NiL, -1, "open: %s: %s: stat error", state->path, path)); close(fd); return -1; } if (uid >= 0 && st.st_uid != uid || gid >= 0 && st.st_gid != gid) { close(fd); errno = EPERM; messagef((state->id, NiL, -1, "open: %s: %s: uid/gid error", state->path, path)); return -1; } } return fd; bad: if (nfd >= 0) close(nfd); return -1; }
char *pathpath(register char *path, const char *p, const char *a, int mode) { register char *s; char *x; char buf[PATH_MAX]; static char *cmd; if (!path) path = buf; if (!p) { if (cmd) free(cmd); cmd = a ? strdup(a) : (char *) 0; return 0; } if (strlen(p) < PATH_MAX) { strcpy(path, p); if (pathexists(path, mode)) return (path == buf) ? strdup(path) : path; } if (*p == '/') a = 0; else if ((s = (char *) a)) { x = s; if (strchr(p, '/')) { a = p; p = ".."; } else a = 0; if ((!cmd || *cmd) && (strchr(s, '/') || (((s = cmd) || (opt_info_argv && (s = *opt_info_argv))) && strchr(s, '/') && !strchr(s, '\n') && !access(s, F_OK)) || (environ && (s = *environ) && *s++ == '_' && *s++ == '=' && strchr(s, '/') && !strneq(s, "/bin/", 5) && !strneq(s, "/usr/bin/", 9)) || (*x && !access(x, F_OK) && (s = getenv("PWD")) && *s == '/') ) ) { if (!cmd) cmd = strdup(s); if (strlen(s) < (sizeof(buf) - 6)) { s = strcopy(path, s); for (;;) { do if (s <= path) goto normal; while (*--s == '/'); do if (s <= path) goto normal; while (*--s != '/'); strcpy(s + 1, "bin"); if (pathexists(path, PATH_EXECUTE)) { if ((s = pathaccess(path, path, p, a, mode))) return path == buf ? strdup(s) : s; goto normal; } } normal:; } } } x = !a && strchr(p, '/') ? "" : pathbin(); if (!(s = pathaccess(path, x, p, a, mode)) && !*x && (x = getenv("FPATH"))) s = pathaccess(path, x, p, a, mode); return (s && path == buf) ? strdup(s) : s; }
static int exists(int op, char* pred, register char* args) { register int c; register int type; char* pptoken; long state; char file[MAXTOKEN + 1]; state = (pp.state & ~DISABLE); PUSH_STRING(args); pptoken = pp.token; pp.token = file; pp.state |= HEADER|PASSEOF; type = pplex(); pp.state &= ~HEADER; pp.token = pptoken; switch (type) { case T_STRING: case T_HEADER: break; default: error(1, "%s: \"...\" or <...> argument expected", pred); c = 0; goto done; } if (op == X_EXISTS) { if ((c = pplex()) == ',') { while ((c = pplex()) == T_STRING) { if (pathaccess(pp.token, file, NiL, 0, pp.path, MAXTOKEN + 1)) { pathcanon(pp.path, 0, 0); message((-2, "%s: %s found", pred, pp.path)); c = 1; goto done; } if ((c = pplex()) != ',') break; } if (c) error(1, "%s: \"...\" arguments expected", pred); strcpy(pp.path, file); message((-2, "%s: %s not found", pred, file)); c = 0; } else c = ppsearch(file, type, SEARCH_EXISTS) >= 0; } else { register struct ppfile* fp; fp = ppsetfile(file); c = fp->flags || fp->guard == INC_IGNORE; } done: while (pplex()); pp.state = state; return c; }