/* * Recursively find names and inumbers of all files in subtree * pname and pass them off to be processed. */ void treescan(char *pname, ufs1_ino_t ino, long (*todo) (char *, ufs1_ino_t, int)) { struct inotab *itp; struct direct *dp; int namelen; long bpt; char locname[MAXPATHLEN + 1]; itp = inotablookup(ino); if (itp == NULL) { /* * Pname is name of a simple file or an unchanged directory. */ (*todo)(pname, ino, LEAF); return; } /* * Pname is a dumped directory name. */ if ((*todo)(pname, ino, NODE) == FAIL) return; /* * begin search through the directory * skipping over "." and ".." */ strncpy(locname, pname, sizeof(locname) - 1); locname[sizeof(locname) - 1] = '\0'; strncat(locname, "/", sizeof(locname) - strlen(locname)); namelen = strlen(locname); rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); dp = rst_readdir(dirp); /* "." */ if (dp != NULL && strcmp(dp->d_name, ".") == 0) dp = rst_readdir(dirp); /* ".." */ else fprintf(stderr, "Warning: `.' missing from directory %s\n", pname); if (dp != NULL && strcmp(dp->d_name, "..") == 0) dp = rst_readdir(dirp); /* first real entry */ else fprintf(stderr, "Warning: `..' missing from directory %s\n", pname); bpt = rst_telldir(dirp); /* * a zero inode signals end of directory */ while (dp != NULL) { locname[namelen] = '\0'; if (namelen + dp->d_namlen >= sizeof(locname)) { fprintf(stderr, "%s%s: name exceeds %d char\n", locname, dp->d_name, sizeof(locname) - 1); } else { strncat(locname, dp->d_name, (int)dp->d_namlen); treescan(locname, dp->d_ino, todo); rst_seekdir(dirp, bpt, itp->t_seekpt); } dp = rst_readdir(dirp); bpt = rst_telldir(dirp); } }
struct dirent * glob_readdir(RST_DIR *dirp) { enum { ADIRENT_STORAGE_LEN = _DIRENT_RECLEN(NAME_MAX), }; static union { uint8_t storage[ADIRENT_STORAGE_LEN]; struct dirent alignment; } adirent; struct direct *dp; struct dirent *adp; while ((dp = rst_readdir(dirp)) != NULL) { if (!vflag && dp->d_ino == UFS_WINO) continue; if (dflag || TSTINO(dp->d_ino, dumpmap)) break; } if (dp == NULL) return (NULL); adp = (struct dirent *)&adirent; adp->d_fileno = dp->d_ino; adp->d_namlen = dp->d_namlen; strcpy(adp->d_name, dp->d_name); return (adp); }
struct dirent * glob_readdir(RST_DIR *dirp) { struct direct *dp; static struct dirent adirent; while ((dp = rst_readdir(dirp)) != NULL) { if (dflag || TSTINO(dp->d_ino, dumpmap)) break; } if (dp == NULL) return (NULL); adirent.d_fileno = dp->d_ino; adirent.d_namlen = dp->d_namlen; memcpy(adirent.d_name, dp->d_name, dp->d_namlen + 1); return (&adirent); }
/* * Lookup the requested name in directory inum. * Return its inode number if found, zero if it does not exist. */ static struct direct * searchdir(ino_t inum, char *name) { struct direct *dp; struct inotab *itp; int len; itp = inotablookup(inum); if (itp == NULL) return (NULL); rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); len = strlen(name); do { dp = rst_readdir(dirp); if (dp == NULL) return (NULL); } while (dp->d_namlen != len || strncmp(dp->d_name, name, len) != 0); return (dp); }
struct dirent * glob_readdir(void *dirp) { struct direct *dp; static struct dirent adirent; while ((dp = rst_readdir(dirp)) != NULL) { if (!vflag && dp->d_ino == UFS_WINO) continue; if (dflag || TSTINO(dp->d_ino, dumpmap)) break; } if (dp == NULL) return (NULL); adirent.d_fileno = dp->d_ino; adirent.d_namlen = dp->d_namlen; memmove(adirent.d_name, dp->d_name, dp->d_namlen + 1); return (&adirent); }
/* * Do an "ls" style listing of a directory */ static void printlist(const char *name, char *basename) { struct afile *fp, *list, *listp = NULL; struct direct *dp; struct afile single; RST_DIR *dirp; int entries, len, namelen; char locname[MAXPATHLEN + 1]; dp = pathsearch(name); if (dp == NULL || (!dflag && TSTINO(dp->d_ino, dumpmap) == 0) || (!vflag && dp->d_ino == UFS_WINO)) return; if ((dirp = rst_opendir(name)) == NULL) { entries = 1; list = &single; mkentry(name, dp, list); len = strlen(basename) + 1; if (strlen(name) - len > (unsigned short)single.len) { freename(single.fname); single.fname = savename(&name[len]); single.len = strlen(single.fname); } } else { entries = 0; while ((dp = rst_readdir(dirp))) entries++; rst_closedir(dirp); list = (struct afile *)malloc(entries * sizeof(struct afile)); if (list == NULL) { fprintf(stderr, "ls: out of memory\n"); return; } if ((dirp = rst_opendir(name)) == NULL) panic("directory reopen failed\n"); fprintf(stderr, "%s:\n", name); entries = 0; listp = list; strncpy(locname, name, MAXPATHLEN); strncat(locname, "/", MAXPATHLEN); namelen = strlen(locname); while ((dp = rst_readdir(dirp))) { if (dp == NULL) break; if (!dflag && TSTINO(dp->d_ino, dumpmap) == 0) continue; if (!vflag && (dp->d_ino == UFS_WINO || strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)) continue; locname[namelen] = '\0'; if (namelen + dp->d_namlen >= MAXPATHLEN) { fprintf(stderr, "%s%s: name exceeds %d char\n", locname, dp->d_name, MAXPATHLEN); } else { strncat(locname, dp->d_name, (int)dp->d_namlen); mkentry(locname, dp, listp++); entries++; } } rst_closedir(dirp); if (entries == 0) { fprintf(stderr, "\n"); free(list); return; } qsort((char *)list, entries, sizeof(struct afile), fcmp); } formatf(list, entries); if (dirp != NULL) { for (fp = listp - 1; fp >= list; fp--) freename(fp->fname); fprintf(stderr, "\n"); free(list); } }