/* * Simulate the opening of a directory */ RST_DIR * rst_opendir(const char *name) { struct inotab *itp; RST_DIR *dirp; ino_t ino; if ((ino = dirlookup(name)) > 0 && (itp = inotablookup(ino)) != NULL) { dirp = opendirfile(dirfile); rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); return (dirp); } return (NULL); }
/* * Extract directory contents, building up a directory structure * on disk for extraction by name. * If genmode is requested, save mode, owner, and times for all * directories on the tape. */ void extractdirs(int genmode) { int i; struct inotab *itp; struct direct nulldir; int fd; Vprintf(stdout, "Extract directories from tape\n"); (void)snprintf(dirfile, sizeof(dirfile), "%s/rstdir%d", tmpdir, dumpdate); if (command != 'r' && command != 'R') { strlcat(dirfile, "-XXXXXXXXXX", sizeof(dirfile)); fd = mkstemp(dirfile); } else fd = open(dirfile, O_RDWR|O_CREAT|O_EXCL, 0666); if (fd == -1 || (df = fdopen(fd, "w")) == NULL) { if (fd != -1) close(fd); err(1, "cannot create directory temporary %s", dirfile); } if (genmode != 0) { (void)snprintf(modefile, sizeof(modefile), "%s/rstmode%d", tmpdir, dumpdate); if (command != 'r' && command != 'R') { strlcat(modefile, "-XXXXXXXXXX", sizeof(modefile)); fd = mkstemp(modefile); } else fd = open(modefile, O_RDWR|O_CREAT|O_EXCL, 0666); if (fd == -1 || (mf = fdopen(fd, "w")) == NULL) { if (fd != -1) close(fd); err(1, "cannot create modefile %s", modefile); } } nulldir.d_ino = 0; nulldir.d_type = DT_DIR; nulldir.d_namlen = 1; nulldir.d_name[0] = '/'; nulldir.d_name[1] = '\0'; nulldir.d_reclen = DIRSIZ(0, &nulldir); for (;;) { curfile.name = "<directory file - name unknown>"; curfile.action = USING; if (curfile.mode == 0 || (curfile.mode & IFMT) != IFDIR) { (void)fclose(df); dirp = opendirfile(dirfile); if (dirp == NULL) warn("opendirfile"); if (mf != NULL) (void)fclose(mf); i = dirlookup(dot); if (i == 0) panic("Root directory is not on tape\n"); return; } itp = allocinotab(mf, &curfile, seekpt); getfile(putdir, xtrnull); putent(&nulldir); flushent(); itp->t_size = seekpt - itp->t_seekpt; } }
static void sopen(Srv *srv, Req *r) { int p; if((r->fid = lookupfid(srv->fpool, r->ifcall.fid)) == nil){ respond(r, Eunknownfid); return; } if(r->fid->omode != -1){ respond(r, Ebotch); return; } if((r->fid->qid.type&QTDIR) && (r->ifcall.mode&~ORCLOSE) != OREAD){ respond(r, Eisdir); return; } r->ofcall.qid = r->fid->qid; switch(r->ifcall.mode&3){ default: assert(0); case OREAD: p = AREAD; break; case OWRITE: p = AWRITE; break; case ORDWR: p = AREAD|AWRITE; break; case OEXEC: p = AEXEC; break; } if(r->ifcall.mode&OTRUNC) p |= AWRITE; if((r->fid->qid.type&QTDIR) && p!=AREAD){ respond(r, Eperm); return; } if(r->fid->file){ if(!hasperm(r->fid->file, r->fid->uid, p)){ respond(r, Eperm); return; } /* BUG RACE */ if((r->ifcall.mode&ORCLOSE) && !hasperm(r->fid->file->parent, r->fid->uid, AWRITE)){ respond(r, Eperm); return; } r->ofcall.qid = r->fid->file->qid; if((r->ofcall.qid.type&QTDIR) && (r->fid->rdir = opendirfile(r->fid->file)) == nil){ respond(r, "opendirfile failed"); return; } } if(srv->open) srv->open(r); else respond(r, nil); }
/* * Extract directory contents, building up a directory structure * on disk for extraction by name. * If genmode is requested, save mode, owner, and times for all * directories on the tape. */ void extractdirs(int genmode) { int i; struct ufs1_dinode *ip; struct inotab *itp; struct direct nulldir; int fd; const char *tmpdir; vprintf(stdout, "Extract directories from tape\n"); if ((tmpdir = getenv("TMPDIR")) == NULL || tmpdir[0] == '\0') tmpdir = _PATH_TMP; sprintf(dirfile, "%s/rstdir%ld", tmpdir, (long)dumpdate); if (command != 'r' && command != 'R') { (void *) strcat(dirfile, "-XXXXXX"); fd = mkstemp(dirfile); } else fd = open(dirfile, O_RDWR|O_CREAT|O_EXCL, 0666); if (fd == -1 || (df = fdopen(fd, "w")) == NULL) { if (fd != -1) close(fd); warn("%s - cannot create directory temporary\nfopen", dirfile); done(1); } if (genmode != 0) { sprintf(modefile, "%s/rstmode%ld", tmpdir, (long)dumpdate); if (command != 'r' && command != 'R') { (void *) strcat(modefile, "-XXXXXX"); fd = mkstemp(modefile); } else fd = open(modefile, O_RDWR|O_CREAT|O_EXCL, 0666); if (fd == -1 || (mf = fdopen(fd, "w")) == NULL) { if (fd != -1) close(fd); warn("%s - cannot create modefile\nfopen", modefile); done(1); } } nulldir.d_ino = 0; nulldir.d_type = DT_DIR; nulldir.d_namlen = 1; strcpy(nulldir.d_name, "/"); nulldir.d_reclen = DIRSIZ(0, &nulldir); for (;;) { curfile.name = "<directory file - name unknown>"; curfile.action = USING; ip = curfile.dip; if (ip == NULL || (ip->di_mode & IFMT) != IFDIR) { fclose(df); dirp = opendirfile(dirfile); if (dirp == NULL) fprintf(stderr, "opendirfile: %s\n", strerror(errno)); if (mf != NULL) fclose(mf); i = dirlookup(dot); if (i == 0) panic("Root directory is not on tape\n"); return; } itp = allocinotab(curfile.ino, ip, seekpt); getfile(putdir, xtrnull); putent(&nulldir); flushent(); itp->t_size = seekpt - itp->t_seekpt; } }
/* * Note: openinfo is a function for reading info files, and putting * uncompressed content into a temporary filename. For a flexibility, there * are two temporary files supported, i.e. one for keeping opened info file, * and second for i.e. regexp search across info nodes, which are in other * info-subfiles. The temporary file 1 is refrenced by number=0, and file 2 by * number=1 Openinfo by default first tries the path stored in char * *filenameprefix and then in the rest of userdefined paths. */ FILE * openinfo(char *filename, int number) { FILE *id = NULL; #define BUF_LEN 1024 char *buf = xmalloc(BUF_LEN); /* holds local copy of filename */ char *bufend; /* points at the trailing 0 of initial name */ char command[1128]; /* holds command to evaluate for decompression of file */ int i, j; char *tmpfilename; if ((strncmp(filename, "dir", 3)==0) && !isalnum(filename[3])) { xfree(buf); return opendirfile(number); } if (number == 0) /* initialize tmp filename for file 1 */ { if (tmpfilename1) { unlink(tmpfilename1); /* erase old tmpfile */ free(tmpfilename1); } tmpfilename1 = make_tempfile(); tmpfilename = tmpfilename1; /* later we will refere only to tmp1 */ } else /* initialize tmp filename for file 2 */ { if (tmpfilename2) { unlink(tmpfilename2); /* erase old tmpfile */ free(tmpfilename2); } tmpfilename2 = make_tempfile(); tmpfilename = tmpfilename2; /* later we will refere only to tmp2 */ } for (i = -2; i < infopathcount; i++) /* go through all paths */ { if (i < 0) { /* * no filenameprefix, we don't navigate around any specific * infopage set, so simply scan all directories for a hit */ if (!filenameprefix) continue; /* build a filename: First (i == -2) try filenameprefix/filename, * then try with a .info appended */ if (i == -2) snprintf(buf, BUF_LEN, "%s/%s", filenameprefix, basename(filename)); else snprintf(buf, BUF_LEN, "%s/%s.info", filenameprefix, basename(filename)); } else { /* build a filename */ strcpy(buf, infopaths[i]); /* no match found in this directory */ if (! matchfile(&buf, filename)) continue; } bufend = buf; /* remember the bufend to make it possible later to glue compression * suffixes. */ bufend += strlen(buf); for (j = 0; j < SuffixesNumber; j++) /* go through all suffixes */ { strcat(buf, suffixes[j].suffix); if ((id = fopen(buf, "r")) != NULL) { fclose(id); clearfilenameprefix(); filenameprefix = strdup(buf); { /* small scope for removal of filename */ int prefixi, prefixlen = strlen(filenameprefix); for (prefixi = prefixlen; prefixi > 0; prefixi--) if (filenameprefix[prefixi] == '/') { filenameprefix[prefixi] = 0; break; } } buildcommand(command, suffixes[j].command, buf, tmpfilename); xsystem(command); id = fopen(tmpfilename, "r"); if (id) { xfree(buf); return id; } } (*bufend) = 0; } /* if we have a nonzero filename prefix, that is we view a set of * infopages, we don't want to search for a page in all * directories, but only in the prefix directory. Therefore break * here. */ if ((i == -1) &&(filenameprefix)) break; } xfree(buf); return 0; #undef BUF_LEN }
FILE * dirpage_lookup(char **type, char ***message, unsigned long *lines, char *filename, char **first_node) { #define Type (*type) #define Message (*message) #define Lines (*lines) FILE *id = 0; int filenamelen = strlen(filename); int goodHit = 0; char name[256]; char file[256]; char *nameend, *filestart, *fileend, *dot; id = opendirfile(0); if (!id) return NULL; read_item(id, type, message, lines); /* search for node-links in every line */ for (unsigned long i = 1; i < Lines; i++) { if ( (Message[i][0] == '*') && (Message[i][1] == ' ') && ( nameend = strchr(Message[i], ':') ) && (*(nameend + 1) != ':') /* form: `* name:(file)node.' */ && (filestart = strchr(nameend, '(') ) && (fileend = strchr(filestart, ')') ) && (dot = strchr(fileend, '.') ) && (strncasecmp(filename, Message[i] + 2, filenamelen) == 0) ) { char *tmp; /* skip this hit if it is not a perfect match and * we have already found a previous partial match */ if ( ! ( (nameend - Message[i]) - 2 == filenamelen ) && goodHit ) { continue; } /* find the name of the node link */ tmp = name; strncpy(file, filestart + 1, fileend - filestart - 1); file[fileend - filestart - 1] = 0; strncpy(name, fileend + 1, dot - fileend - 1); name[dot - fileend - 1] = 0; while (isspace(*tmp)) tmp++; if (strlen(name)) { *first_node = xmalloc(strlen(tmp) + 1); strcpy((*first_node), tmp); } /* close the previously opened file */ if (id) { fclose(id); id = 0; } /* see if this info file exists */ id = openinfo(file, 0); if (id) { goodHit = 1; } } } /* if we haven't found anything, clean up and exit */ if (id && !goodHit) { fclose(id); id = 0; } /* return file we found */ return id; #undef Lines #undef Message #undef Type }
/* * Extract directory contents, building up a directory structure * on disk for extraction by name. * If genmode is requested, save mode, owner, and times for all * directories on the tape. */ void extractdirs(int genmode) { struct inotab *itp; struct direct nulldir; int i, fd; const char *tmpdir; vprintf(stdout, "Extract directories from tape\n"); if ((tmpdir = getenv("TMPDIR")) == NULL || tmpdir[0] == '\0') tmpdir = _PATH_TMP; (void) sprintf(dirfile, "%s/rstdir%jd", tmpdir, (intmax_t)dumpdate); if (command != 'r' && command != 'R') { (void) strcat(dirfile, "-XXXXXX"); fd = mkstemp(dirfile); } else fd = open(dirfile, O_RDWR|O_CREAT|O_EXCL, 0666); if (fd == -1 || (df = fdopen(fd, "w")) == NULL) { if (fd != -1) close(fd); warn("%s: cannot create directory database", dirfile); done(1); } if (genmode != 0) { (void) sprintf(modefile, "%s/rstmode%jd", tmpdir, (intmax_t)dumpdate); if (command != 'r' && command != 'R') { (void) strcat(modefile, "-XXXXXX"); fd = mkstemp(modefile); } else fd = open(modefile, O_RDWR|O_CREAT|O_EXCL, 0666); if (fd == -1 || (mf = fdopen(fd, "w")) == NULL) { if (fd != -1) close(fd); warn("%s: cannot create modefile", modefile); done(1); } } nulldir.d_ino = 0; nulldir.d_type = DT_DIR; nulldir.d_namlen = 1; (void) strcpy(nulldir.d_name, "/"); nulldir.d_reclen = DIRSIZ(0, &nulldir); for (;;) { curfile.name = "<directory file - name unknown>"; curfile.action = USING; if (curfile.mode == 0 || (curfile.mode & IFMT) != IFDIR) break; itp = allocinotab(&curfile, seekpt); getfile(putdir, putdirattrs, xtrnull); putent(&nulldir); flushent(); itp->t_size = seekpt - itp->t_seekpt; } if (fclose(df) != 0) fail_dirtmp(dirfile); dirp = opendirfile(dirfile); if (dirp == NULL) fprintf(stderr, "opendirfile: %s\n", strerror(errno)); if (mf != NULL && fclose(mf) != 0) fail_dirtmp(modefile); i = dirlookup(dot); if (i == 0) panic("Root directory is not on tape\n"); }