18fae3551SRodney W. Grimes /* 28fae3551SRodney W. Grimes * Copyright (c) 1983, 1993 38fae3551SRodney W. Grimes * The Regents of the University of California. All rights reserved. 48fae3551SRodney W. Grimes * (c) UNIX System Laboratories, Inc. 58fae3551SRodney W. Grimes * All or some portions of this file are derived from material licensed 68fae3551SRodney W. Grimes * to the University of California by American Telephone and Telegraph 78fae3551SRodney W. Grimes * Co. or Unix System Laboratories, Inc. and are reproduced herein with 88fae3551SRodney W. Grimes * the permission of UNIX System Laboratories, Inc. 98fae3551SRodney W. Grimes * 108fae3551SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 118fae3551SRodney W. Grimes * modification, are permitted provided that the following conditions 128fae3551SRodney W. Grimes * are met: 138fae3551SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 148fae3551SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 158fae3551SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 168fae3551SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 178fae3551SRodney W. Grimes * documentation and/or other materials provided with the distribution. 188fae3551SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 198fae3551SRodney W. Grimes * must display the following acknowledgement: 208fae3551SRodney W. Grimes * This product includes software developed by the University of 218fae3551SRodney W. Grimes * California, Berkeley and its contributors. 228fae3551SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 238fae3551SRodney W. Grimes * may be used to endorse or promote products derived from this software 248fae3551SRodney W. Grimes * without specific prior written permission. 258fae3551SRodney W. Grimes * 268fae3551SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 278fae3551SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 288fae3551SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 298fae3551SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 308fae3551SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 318fae3551SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 328fae3551SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 338fae3551SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 348fae3551SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 358fae3551SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 368fae3551SRodney W. Grimes * SUCH DAMAGE. 378fae3551SRodney W. Grimes */ 388fae3551SRodney W. Grimes 398fae3551SRodney W. Grimes #ifndef lint 40d87d79aeSPeter Wemm static char sccsid[] = "@(#)dirs.c 8.7 (Berkeley) 5/1/95"; 418fae3551SRodney W. Grimes #endif /* not lint */ 428fae3551SRodney W. Grimes 438fae3551SRodney W. Grimes #include <sys/param.h> 448fae3551SRodney W. Grimes #include <sys/file.h> 458fae3551SRodney W. Grimes #include <sys/stat.h> 468fae3551SRodney W. Grimes #include <sys/time.h> 478fae3551SRodney W. Grimes 488fae3551SRodney W. Grimes #include <ufs/ufs/dinode.h> 498fae3551SRodney W. Grimes #include <ufs/ufs/dir.h> 50d87d79aeSPeter Wemm #include <ufs/ffs/fs.h> 518fae3551SRodney W. Grimes #include <protocols/dumprestore.h> 528fae3551SRodney W. Grimes 538fae3551SRodney W. Grimes #include <errno.h> 548fae3551SRodney W. Grimes #include <stdio.h> 558fae3551SRodney W. Grimes #include <stdlib.h> 568fae3551SRodney W. Grimes #include <string.h> 578fae3551SRodney W. Grimes #include <unistd.h> 588fae3551SRodney W. Grimes 59a7ab72edSPaul Traina #include <machine/endian.h> 60a7ab72edSPaul Traina 618fae3551SRodney W. Grimes #include "pathnames.h" 628fae3551SRodney W. Grimes #include "restore.h" 638fae3551SRodney W. Grimes #include "extern.h" 648fae3551SRodney W. Grimes 658fae3551SRodney W. Grimes /* 668fae3551SRodney W. Grimes * Symbol table of directories read from tape. 678fae3551SRodney W. Grimes */ 688fae3551SRodney W. Grimes #define HASHSIZE 1000 698fae3551SRodney W. Grimes #define INOHASH(val) (val % HASHSIZE) 708fae3551SRodney W. Grimes struct inotab { 718fae3551SRodney W. Grimes struct inotab *t_next; 728fae3551SRodney W. Grimes ino_t t_ino; 738fae3551SRodney W. Grimes long t_seekpt; 748fae3551SRodney W. Grimes long t_size; 758fae3551SRodney W. Grimes }; 768fae3551SRodney W. Grimes static struct inotab *inotab[HASHSIZE]; 778fae3551SRodney W. Grimes 788fae3551SRodney W. Grimes /* 798fae3551SRodney W. Grimes * Information retained about directories. 808fae3551SRodney W. Grimes */ 818fae3551SRodney W. Grimes struct modeinfo { 828fae3551SRodney W. Grimes ino_t ino; 838fae3551SRodney W. Grimes struct timeval timep[2]; 84d87d79aeSPeter Wemm mode_t mode; 85d87d79aeSPeter Wemm uid_t uid; 86d87d79aeSPeter Wemm gid_t gid; 87d87d79aeSPeter Wemm int flags; 888fae3551SRodney W. Grimes }; 898fae3551SRodney W. Grimes 908fae3551SRodney W. Grimes /* 918fae3551SRodney W. Grimes * Definitions for library routines operating on directories. 928fae3551SRodney W. Grimes */ 938fae3551SRodney W. Grimes #undef DIRBLKSIZ 948fae3551SRodney W. Grimes #define DIRBLKSIZ 1024 958fae3551SRodney W. Grimes struct rstdirdesc { 968fae3551SRodney W. Grimes int dd_fd; 978fae3551SRodney W. Grimes long dd_loc; 988fae3551SRodney W. Grimes long dd_size; 998fae3551SRodney W. Grimes char dd_buf[DIRBLKSIZ]; 1008fae3551SRodney W. Grimes }; 1018fae3551SRodney W. Grimes 1028fae3551SRodney W. Grimes /* 1038fae3551SRodney W. Grimes * Global variables for this file. 1048fae3551SRodney W. Grimes */ 1058fae3551SRodney W. Grimes static long seekpt; 1068fae3551SRodney W. Grimes static FILE *df, *mf; 1078fae3551SRodney W. Grimes static RST_DIR *dirp; 108335524b9SWarner Losh static char dirfile[MAXPATHLEN] = "#"; /* No file */ 109335524b9SWarner Losh static char modefile[MAXPATHLEN] = "#"; /* No file */ 1108fae3551SRodney W. Grimes static char dot[2] = "."; /* So it can be modified */ 1118fae3551SRodney W. Grimes 1128fae3551SRodney W. Grimes /* 1138fae3551SRodney W. Grimes * Format of old style directories. 1148fae3551SRodney W. Grimes */ 1158fae3551SRodney W. Grimes #define ODIRSIZ 14 1168fae3551SRodney W. Grimes struct odirect { 1178fae3551SRodney W. Grimes u_short d_ino; 1188fae3551SRodney W. Grimes char d_name[ODIRSIZ]; 1198fae3551SRodney W. Grimes }; 1208fae3551SRodney W. Grimes 1218fae3551SRodney W. Grimes static struct inotab *allocinotab __P((ino_t, struct dinode *, long)); 1228fae3551SRodney W. Grimes static void dcvt __P((struct odirect *, struct direct *)); 1238fae3551SRodney W. Grimes static void flushent __P((void)); 1248fae3551SRodney W. Grimes static struct inotab *inotablookup __P((ino_t)); 1258fae3551SRodney W. Grimes static RST_DIR *opendirfile __P((const char *)); 1268fae3551SRodney W. Grimes static void putdir __P((char *, long)); 1278fae3551SRodney W. Grimes static void putent __P((struct direct *)); 1288fae3551SRodney W. Grimes static void rst_seekdir __P((RST_DIR *, long, long)); 1298fae3551SRodney W. Grimes static long rst_telldir __P((RST_DIR *)); 1308fae3551SRodney W. Grimes static struct direct *searchdir __P((ino_t, char *)); 1318fae3551SRodney W. Grimes 1328fae3551SRodney W. Grimes /* 1338fae3551SRodney W. Grimes * Extract directory contents, building up a directory structure 1348fae3551SRodney W. Grimes * on disk for extraction by name. 1358fae3551SRodney W. Grimes * If genmode is requested, save mode, owner, and times for all 1368fae3551SRodney W. Grimes * directories on the tape. 1378fae3551SRodney W. Grimes */ 1388fae3551SRodney W. Grimes void 1398fae3551SRodney W. Grimes extractdirs(genmode) 1408fae3551SRodney W. Grimes int genmode; 1418fae3551SRodney W. Grimes { 1428fae3551SRodney W. Grimes register int i; 1438fae3551SRodney W. Grimes register struct dinode *ip; 1448fae3551SRodney W. Grimes struct inotab *itp; 1458fae3551SRodney W. Grimes struct direct nulldir; 146335524b9SWarner Losh int fd; 1478fae3551SRodney W. Grimes 1488fae3551SRodney W. Grimes vprintf(stdout, "Extract directories from tape\n"); 149335524b9SWarner Losh (void) sprintf(dirfile, "%srstdir%d", _PATH_TMP, dumpdate); 150335524b9SWarner Losh if (command != 'r' && command != 'R') { 151335524b9SWarner Losh (void *) strcat(dirfile, "-XXXXXX"); 152335524b9SWarner Losh fd = mkstemp(dirfile); 153335524b9SWarner Losh } else 154335524b9SWarner Losh fd = open(dirfile, O_RDWR|O_CREAT|O_EXCL, 0666); 155335524b9SWarner Losh if (fd == -1 || (df = fdopen(fd, "w")) == NULL) { 156335524b9SWarner Losh if (fd != -1) 157335524b9SWarner Losh close(fd); 1588fae3551SRodney W. Grimes fprintf(stderr, 1598fae3551SRodney W. Grimes "restore: %s - cannot create directory temporary\n", 1608fae3551SRodney W. Grimes dirfile); 1618fae3551SRodney W. Grimes fprintf(stderr, "fopen: %s\n", strerror(errno)); 1628fae3551SRodney W. Grimes done(1); 1638fae3551SRodney W. Grimes } 1648fae3551SRodney W. Grimes if (genmode != 0) { 165335524b9SWarner Losh (void) sprintf(modefile, "%srstmode%d", _PATH_TMP, dumpdate); 166335524b9SWarner Losh if (command != 'r' && command != 'R') { 167335524b9SWarner Losh (void *) strcat(modefile, "-XXXXXX"); 168335524b9SWarner Losh fd = mkstemp(modefile); 169335524b9SWarner Losh } else 170335524b9SWarner Losh fd = open(modefile, O_RDWR|O_CREAT|O_EXCL, 0666); 171335524b9SWarner Losh if (fd == -1 || (mf = fdopen(fd, "w")) == NULL) { 172335524b9SWarner Losh if (fd != -1) 173335524b9SWarner Losh close(fd); 1748fae3551SRodney W. Grimes fprintf(stderr, 1758fae3551SRodney W. Grimes "restore: %s - cannot create modefile \n", 1768fae3551SRodney W. Grimes modefile); 1778fae3551SRodney W. Grimes fprintf(stderr, "fopen: %s\n", strerror(errno)); 1788fae3551SRodney W. Grimes done(1); 1798fae3551SRodney W. Grimes } 1808fae3551SRodney W. Grimes } 1818fae3551SRodney W. Grimes nulldir.d_ino = 0; 1828fae3551SRodney W. Grimes nulldir.d_type = DT_DIR; 1838fae3551SRodney W. Grimes nulldir.d_namlen = 1; 1848fae3551SRodney W. Grimes (void) strcpy(nulldir.d_name, "/"); 1858fae3551SRodney W. Grimes nulldir.d_reclen = DIRSIZ(0, &nulldir); 1868fae3551SRodney W. Grimes for (;;) { 1878fae3551SRodney W. Grimes curfile.name = "<directory file - name unknown>"; 1888fae3551SRodney W. Grimes curfile.action = USING; 1898fae3551SRodney W. Grimes ip = curfile.dip; 1908fae3551SRodney W. Grimes if (ip == NULL || (ip->di_mode & IFMT) != IFDIR) { 1918fae3551SRodney W. Grimes (void) fclose(df); 1928fae3551SRodney W. Grimes dirp = opendirfile(dirfile); 1938fae3551SRodney W. Grimes if (dirp == NULL) 1948fae3551SRodney W. Grimes fprintf(stderr, "opendirfile: %s\n", 1958fae3551SRodney W. Grimes strerror(errno)); 1968fae3551SRodney W. Grimes if (mf != NULL) 1978fae3551SRodney W. Grimes (void) fclose(mf); 1988fae3551SRodney W. Grimes i = dirlookup(dot); 1998fae3551SRodney W. Grimes if (i == 0) 2008fae3551SRodney W. Grimes panic("Root directory is not on tape\n"); 2018fae3551SRodney W. Grimes return; 2028fae3551SRodney W. Grimes } 2038fae3551SRodney W. Grimes itp = allocinotab(curfile.ino, ip, seekpt); 2048fae3551SRodney W. Grimes getfile(putdir, xtrnull); 2058fae3551SRodney W. Grimes putent(&nulldir); 2068fae3551SRodney W. Grimes flushent(); 2078fae3551SRodney W. Grimes itp->t_size = seekpt - itp->t_seekpt; 2088fae3551SRodney W. Grimes } 2098fae3551SRodney W. Grimes } 2108fae3551SRodney W. Grimes 2118fae3551SRodney W. Grimes /* 2128fae3551SRodney W. Grimes * skip over all the directories on the tape 2138fae3551SRodney W. Grimes */ 2148fae3551SRodney W. Grimes void 2158fae3551SRodney W. Grimes skipdirs() 2168fae3551SRodney W. Grimes { 2178fae3551SRodney W. Grimes 2184d14a290SJoerg Wunsch while (curfile.dip && (curfile.dip->di_mode & IFMT) == IFDIR) { 2198fae3551SRodney W. Grimes skipfile(); 2208fae3551SRodney W. Grimes } 2218fae3551SRodney W. Grimes } 2228fae3551SRodney W. Grimes 2238fae3551SRodney W. Grimes /* 2248fae3551SRodney W. Grimes * Recursively find names and inumbers of all files in subtree 2258fae3551SRodney W. Grimes * pname and pass them off to be processed. 2268fae3551SRodney W. Grimes */ 2278fae3551SRodney W. Grimes void 2288fae3551SRodney W. Grimes treescan(pname, ino, todo) 2298fae3551SRodney W. Grimes char *pname; 2308fae3551SRodney W. Grimes ino_t ino; 2318fae3551SRodney W. Grimes long (*todo) __P((char *, ino_t, int)); 2328fae3551SRodney W. Grimes { 2338fae3551SRodney W. Grimes register struct inotab *itp; 2348fae3551SRodney W. Grimes register struct direct *dp; 2358fae3551SRodney W. Grimes int namelen; 2368fae3551SRodney W. Grimes long bpt; 2378fae3551SRodney W. Grimes char locname[MAXPATHLEN + 1]; 2388fae3551SRodney W. Grimes 2398fae3551SRodney W. Grimes itp = inotablookup(ino); 2408fae3551SRodney W. Grimes if (itp == NULL) { 2418fae3551SRodney W. Grimes /* 2428fae3551SRodney W. Grimes * Pname is name of a simple file or an unchanged directory. 2438fae3551SRodney W. Grimes */ 2448fae3551SRodney W. Grimes (void) (*todo)(pname, ino, LEAF); 2458fae3551SRodney W. Grimes return; 2468fae3551SRodney W. Grimes } 2478fae3551SRodney W. Grimes /* 2488fae3551SRodney W. Grimes * Pname is a dumped directory name. 2498fae3551SRodney W. Grimes */ 2508fae3551SRodney W. Grimes if ((*todo)(pname, ino, NODE) == FAIL) 2518fae3551SRodney W. Grimes return; 2528fae3551SRodney W. Grimes /* 2538fae3551SRodney W. Grimes * begin search through the directory 2548fae3551SRodney W. Grimes * skipping over "." and ".." 2558fae3551SRodney W. Grimes */ 256335524b9SWarner Losh (void) strncpy(locname, pname, sizeof(locname) - 1); 257335524b9SWarner Losh locname[sizeof(locname) - 1] = '\0'; 258335524b9SWarner Losh (void) strncat(locname, "/", sizeof(locname) - strlen(locname)); 2598fae3551SRodney W. Grimes namelen = strlen(locname); 2608fae3551SRodney W. Grimes rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); 2618fae3551SRodney W. Grimes dp = rst_readdir(dirp); /* "." */ 2628fae3551SRodney W. Grimes if (dp != NULL && strcmp(dp->d_name, ".") == 0) 2638fae3551SRodney W. Grimes dp = rst_readdir(dirp); /* ".." */ 2648fae3551SRodney W. Grimes else 2658fae3551SRodney W. Grimes fprintf(stderr, "Warning: `.' missing from directory %s\n", 2668fae3551SRodney W. Grimes pname); 2678fae3551SRodney W. Grimes if (dp != NULL && strcmp(dp->d_name, "..") == 0) 2688fae3551SRodney W. Grimes dp = rst_readdir(dirp); /* first real entry */ 2698fae3551SRodney W. Grimes else 2708fae3551SRodney W. Grimes fprintf(stderr, "Warning: `..' missing from directory %s\n", 2718fae3551SRodney W. Grimes pname); 2728fae3551SRodney W. Grimes bpt = rst_telldir(dirp); 2738fae3551SRodney W. Grimes /* 2748fae3551SRodney W. Grimes * a zero inode signals end of directory 2758fae3551SRodney W. Grimes */ 276d87d79aeSPeter Wemm while (dp != NULL) { 2778fae3551SRodney W. Grimes locname[namelen] = '\0'; 278335524b9SWarner Losh if (namelen + dp->d_namlen >= sizeof(locname)) { 2798fae3551SRodney W. Grimes fprintf(stderr, "%s%s: name exceeds %d char\n", 280335524b9SWarner Losh locname, dp->d_name, sizeof(locname) - 1); 2818fae3551SRodney W. Grimes } else { 2828fae3551SRodney W. Grimes (void) strncat(locname, dp->d_name, (int)dp->d_namlen); 2838fae3551SRodney W. Grimes treescan(locname, dp->d_ino, todo); 2848fae3551SRodney W. Grimes rst_seekdir(dirp, bpt, itp->t_seekpt); 2858fae3551SRodney W. Grimes } 2868fae3551SRodney W. Grimes dp = rst_readdir(dirp); 2878fae3551SRodney W. Grimes bpt = rst_telldir(dirp); 2888fae3551SRodney W. Grimes } 2898fae3551SRodney W. Grimes } 2908fae3551SRodney W. Grimes 2918fae3551SRodney W. Grimes /* 2928fae3551SRodney W. Grimes * Lookup a pathname which is always assumed to start from the ROOTINO. 2938fae3551SRodney W. Grimes */ 2948fae3551SRodney W. Grimes struct direct * 2958fae3551SRodney W. Grimes pathsearch(pathname) 2968fae3551SRodney W. Grimes const char *pathname; 2978fae3551SRodney W. Grimes { 2988fae3551SRodney W. Grimes ino_t ino; 2998fae3551SRodney W. Grimes struct direct *dp; 3008fae3551SRodney W. Grimes char *path, *name, buffer[MAXPATHLEN]; 3018fae3551SRodney W. Grimes 3028fae3551SRodney W. Grimes strcpy(buffer, pathname); 3038fae3551SRodney W. Grimes path = buffer; 3048fae3551SRodney W. Grimes ino = ROOTINO; 3058fae3551SRodney W. Grimes while (*path == '/') 3068fae3551SRodney W. Grimes path++; 3078fae3551SRodney W. Grimes dp = NULL; 3088fae3551SRodney W. Grimes while ((name = strsep(&path, "/")) != NULL && *name != NULL) { 3098fae3551SRodney W. Grimes if ((dp = searchdir(ino, name)) == NULL) 3108fae3551SRodney W. Grimes return (NULL); 3118fae3551SRodney W. Grimes ino = dp->d_ino; 3128fae3551SRodney W. Grimes } 3138fae3551SRodney W. Grimes return (dp); 3148fae3551SRodney W. Grimes } 3158fae3551SRodney W. Grimes 3168fae3551SRodney W. Grimes /* 3178fae3551SRodney W. Grimes * Lookup the requested name in directory inum. 3188fae3551SRodney W. Grimes * Return its inode number if found, zero if it does not exist. 3198fae3551SRodney W. Grimes */ 3208fae3551SRodney W. Grimes static struct direct * 3218fae3551SRodney W. Grimes searchdir(inum, name) 3228fae3551SRodney W. Grimes ino_t inum; 3238fae3551SRodney W. Grimes char *name; 3248fae3551SRodney W. Grimes { 3258fae3551SRodney W. Grimes register struct direct *dp; 3268fae3551SRodney W. Grimes register struct inotab *itp; 3278fae3551SRodney W. Grimes int len; 3288fae3551SRodney W. Grimes 3298fae3551SRodney W. Grimes itp = inotablookup(inum); 3308fae3551SRodney W. Grimes if (itp == NULL) 3318fae3551SRodney W. Grimes return (NULL); 3328fae3551SRodney W. Grimes rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); 3338fae3551SRodney W. Grimes len = strlen(name); 3348fae3551SRodney W. Grimes do { 3358fae3551SRodney W. Grimes dp = rst_readdir(dirp); 336d87d79aeSPeter Wemm if (dp == NULL) 3378fae3551SRodney W. Grimes return (NULL); 3388fae3551SRodney W. Grimes } while (dp->d_namlen != len || strncmp(dp->d_name, name, len) != 0); 3398fae3551SRodney W. Grimes return (dp); 3408fae3551SRodney W. Grimes } 3418fae3551SRodney W. Grimes 3428fae3551SRodney W. Grimes /* 3438fae3551SRodney W. Grimes * Put the directory entries in the directory file 3448fae3551SRodney W. Grimes */ 3458fae3551SRodney W. Grimes static void 3468fae3551SRodney W. Grimes putdir(buf, size) 3478fae3551SRodney W. Grimes char *buf; 3488fae3551SRodney W. Grimes long size; 3498fae3551SRodney W. Grimes { 3508fae3551SRodney W. Grimes struct direct cvtbuf; 3518fae3551SRodney W. Grimes register struct odirect *odp; 3528fae3551SRodney W. Grimes struct odirect *eodp; 3538fae3551SRodney W. Grimes register struct direct *dp; 3548fae3551SRodney W. Grimes long loc, i; 3558fae3551SRodney W. Grimes 3568fae3551SRodney W. Grimes if (cvtflag) { 3578fae3551SRodney W. Grimes eodp = (struct odirect *)&buf[size]; 3588fae3551SRodney W. Grimes for (odp = (struct odirect *)buf; odp < eodp; odp++) 3598fae3551SRodney W. Grimes if (odp->d_ino != 0) { 3608fae3551SRodney W. Grimes dcvt(odp, &cvtbuf); 3618fae3551SRodney W. Grimes putent(&cvtbuf); 3628fae3551SRodney W. Grimes } 3638fae3551SRodney W. Grimes } else { 3648fae3551SRodney W. Grimes for (loc = 0; loc < size; ) { 3658fae3551SRodney W. Grimes dp = (struct direct *)(buf + loc); 366a7ab72edSPaul Traina if (Bcvt) 3678fae3551SRodney W. Grimes swabst((u_char *)"ls", (u_char *) dp); 368a7ab72edSPaul Traina if (oldinofmt && dp->d_ino != 0) { 369a7ab72edSPaul Traina # if BYTE_ORDER == BIG_ENDIAN 370a7ab72edSPaul Traina if (Bcvt) 371d87d79aeSPeter Wemm dp->d_namlen = dp->d_type; 372a7ab72edSPaul Traina # else 373a7ab72edSPaul Traina if (!Bcvt) 374a7ab72edSPaul Traina dp->d_namlen = dp->d_type; 375d87d79aeSPeter Wemm # endif 376a7ab72edSPaul Traina dp->d_type = DT_UNKNOWN; 3778fae3551SRodney W. Grimes } 3788fae3551SRodney W. Grimes i = DIRBLKSIZ - (loc & (DIRBLKSIZ - 1)); 3798fae3551SRodney W. Grimes if ((dp->d_reclen & 0x3) != 0 || 3808fae3551SRodney W. Grimes dp->d_reclen > i || 3818fae3551SRodney W. Grimes dp->d_reclen < DIRSIZ(0, dp) || 3828fae3551SRodney W. Grimes dp->d_namlen > NAME_MAX) { 3838fae3551SRodney W. Grimes vprintf(stdout, "Mangled directory: "); 3848fae3551SRodney W. Grimes if ((dp->d_reclen & 0x3) != 0) 3858fae3551SRodney W. Grimes vprintf(stdout, 3868fae3551SRodney W. Grimes "reclen not multiple of 4 "); 3878fae3551SRodney W. Grimes if (dp->d_reclen < DIRSIZ(0, dp)) 3888fae3551SRodney W. Grimes vprintf(stdout, 3898fae3551SRodney W. Grimes "reclen less than DIRSIZ (%d < %d) ", 3908fae3551SRodney W. Grimes dp->d_reclen, DIRSIZ(0, dp)); 3918fae3551SRodney W. Grimes if (dp->d_namlen > NAME_MAX) 3928fae3551SRodney W. Grimes vprintf(stdout, 3938fae3551SRodney W. Grimes "reclen name too big (%d > %d) ", 3948fae3551SRodney W. Grimes dp->d_namlen, NAME_MAX); 3958fae3551SRodney W. Grimes vprintf(stdout, "\n"); 3968fae3551SRodney W. Grimes loc += i; 3978fae3551SRodney W. Grimes continue; 3988fae3551SRodney W. Grimes } 3998fae3551SRodney W. Grimes loc += dp->d_reclen; 4008fae3551SRodney W. Grimes if (dp->d_ino != 0) { 4018fae3551SRodney W. Grimes putent(dp); 4028fae3551SRodney W. Grimes } 4038fae3551SRodney W. Grimes } 4048fae3551SRodney W. Grimes } 4058fae3551SRodney W. Grimes } 4068fae3551SRodney W. Grimes 4078fae3551SRodney W. Grimes /* 4088fae3551SRodney W. Grimes * These variables are "local" to the following two functions. 4098fae3551SRodney W. Grimes */ 4108fae3551SRodney W. Grimes char dirbuf[DIRBLKSIZ]; 4118fae3551SRodney W. Grimes long dirloc = 0; 4128fae3551SRodney W. Grimes long prev = 0; 4138fae3551SRodney W. Grimes 4148fae3551SRodney W. Grimes /* 4158fae3551SRodney W. Grimes * add a new directory entry to a file. 4168fae3551SRodney W. Grimes */ 4178fae3551SRodney W. Grimes static void 4188fae3551SRodney W. Grimes putent(dp) 4198fae3551SRodney W. Grimes struct direct *dp; 4208fae3551SRodney W. Grimes { 4218fae3551SRodney W. Grimes dp->d_reclen = DIRSIZ(0, dp); 4228fae3551SRodney W. Grimes if (dirloc + dp->d_reclen > DIRBLKSIZ) { 4238fae3551SRodney W. Grimes ((struct direct *)(dirbuf + prev))->d_reclen = 4248fae3551SRodney W. Grimes DIRBLKSIZ - prev; 4258fae3551SRodney W. Grimes (void) fwrite(dirbuf, 1, DIRBLKSIZ, df); 4268fae3551SRodney W. Grimes dirloc = 0; 4278fae3551SRodney W. Grimes } 428d87d79aeSPeter Wemm memmove(dirbuf + dirloc, dp, (long)dp->d_reclen); 4298fae3551SRodney W. Grimes prev = dirloc; 4308fae3551SRodney W. Grimes dirloc += dp->d_reclen; 4318fae3551SRodney W. Grimes } 4328fae3551SRodney W. Grimes 4338fae3551SRodney W. Grimes /* 4348fae3551SRodney W. Grimes * flush out a directory that is finished. 4358fae3551SRodney W. Grimes */ 4368fae3551SRodney W. Grimes static void 4378fae3551SRodney W. Grimes flushent() 4388fae3551SRodney W. Grimes { 4398fae3551SRodney W. Grimes ((struct direct *)(dirbuf + prev))->d_reclen = DIRBLKSIZ - prev; 4408fae3551SRodney W. Grimes (void) fwrite(dirbuf, (int)dirloc, 1, df); 4418fae3551SRodney W. Grimes seekpt = ftell(df); 4428fae3551SRodney W. Grimes dirloc = 0; 4438fae3551SRodney W. Grimes } 4448fae3551SRodney W. Grimes 4458fae3551SRodney W. Grimes static void 4468fae3551SRodney W. Grimes dcvt(odp, ndp) 4478fae3551SRodney W. Grimes register struct odirect *odp; 4488fae3551SRodney W. Grimes register struct direct *ndp; 4498fae3551SRodney W. Grimes { 4508fae3551SRodney W. Grimes 451d87d79aeSPeter Wemm memset(ndp, 0, (long)(sizeof *ndp)); 4528fae3551SRodney W. Grimes ndp->d_ino = odp->d_ino; 4538fae3551SRodney W. Grimes ndp->d_type = DT_UNKNOWN; 4548fae3551SRodney W. Grimes (void) strncpy(ndp->d_name, odp->d_name, ODIRSIZ); 4558fae3551SRodney W. Grimes ndp->d_namlen = strlen(ndp->d_name); 4568fae3551SRodney W. Grimes ndp->d_reclen = DIRSIZ(0, ndp); 4578fae3551SRodney W. Grimes } 4588fae3551SRodney W. Grimes 4598fae3551SRodney W. Grimes /* 4608fae3551SRodney W. Grimes * Seek to an entry in a directory. 4618fae3551SRodney W. Grimes * Only values returned by rst_telldir should be passed to rst_seekdir. 4628fae3551SRodney W. Grimes * This routine handles many directories in a single file. 4638fae3551SRodney W. Grimes * It takes the base of the directory in the file, plus 4648fae3551SRodney W. Grimes * the desired seek offset into it. 4658fae3551SRodney W. Grimes */ 4668fae3551SRodney W. Grimes static void 4678fae3551SRodney W. Grimes rst_seekdir(dirp, loc, base) 4688fae3551SRodney W. Grimes register RST_DIR *dirp; 4698fae3551SRodney W. Grimes long loc, base; 4708fae3551SRodney W. Grimes { 4718fae3551SRodney W. Grimes 4728fae3551SRodney W. Grimes if (loc == rst_telldir(dirp)) 4738fae3551SRodney W. Grimes return; 4748fae3551SRodney W. Grimes loc -= base; 4758fae3551SRodney W. Grimes if (loc < 0) 4768fae3551SRodney W. Grimes fprintf(stderr, "bad seek pointer to rst_seekdir %d\n", loc); 4778fae3551SRodney W. Grimes (void) lseek(dirp->dd_fd, base + (loc & ~(DIRBLKSIZ - 1)), SEEK_SET); 4788fae3551SRodney W. Grimes dirp->dd_loc = loc & (DIRBLKSIZ - 1); 4798fae3551SRodney W. Grimes if (dirp->dd_loc != 0) 4808fae3551SRodney W. Grimes dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ); 4818fae3551SRodney W. Grimes } 4828fae3551SRodney W. Grimes 4838fae3551SRodney W. Grimes /* 4848fae3551SRodney W. Grimes * get next entry in a directory. 4858fae3551SRodney W. Grimes */ 4868fae3551SRodney W. Grimes struct direct * 4878fae3551SRodney W. Grimes rst_readdir(dirp) 4888fae3551SRodney W. Grimes register RST_DIR *dirp; 4898fae3551SRodney W. Grimes { 4908fae3551SRodney W. Grimes register struct direct *dp; 4918fae3551SRodney W. Grimes 4928fae3551SRodney W. Grimes for (;;) { 4938fae3551SRodney W. Grimes if (dirp->dd_loc == 0) { 4948fae3551SRodney W. Grimes dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, 4958fae3551SRodney W. Grimes DIRBLKSIZ); 4968fae3551SRodney W. Grimes if (dirp->dd_size <= 0) { 4978fae3551SRodney W. Grimes dprintf(stderr, "error reading directory\n"); 4988fae3551SRodney W. Grimes return (NULL); 4998fae3551SRodney W. Grimes } 5008fae3551SRodney W. Grimes } 5018fae3551SRodney W. Grimes if (dirp->dd_loc >= dirp->dd_size) { 5028fae3551SRodney W. Grimes dirp->dd_loc = 0; 5038fae3551SRodney W. Grimes continue; 5048fae3551SRodney W. Grimes } 5058fae3551SRodney W. Grimes dp = (struct direct *)(dirp->dd_buf + dirp->dd_loc); 5068fae3551SRodney W. Grimes if (dp->d_reclen == 0 || 5078fae3551SRodney W. Grimes dp->d_reclen > DIRBLKSIZ + 1 - dirp->dd_loc) { 5088fae3551SRodney W. Grimes dprintf(stderr, "corrupted directory: bad reclen %d\n", 5098fae3551SRodney W. Grimes dp->d_reclen); 5108fae3551SRodney W. Grimes return (NULL); 5118fae3551SRodney W. Grimes } 5128fae3551SRodney W. Grimes dirp->dd_loc += dp->d_reclen; 513d87d79aeSPeter Wemm if (dp->d_ino == 0 && strcmp(dp->d_name, "/") == 0) 514d87d79aeSPeter Wemm return (NULL); 5158fae3551SRodney W. Grimes if (dp->d_ino >= maxino) { 5168fae3551SRodney W. Grimes dprintf(stderr, "corrupted directory: bad inum %d\n", 5178fae3551SRodney W. Grimes dp->d_ino); 5188fae3551SRodney W. Grimes continue; 5198fae3551SRodney W. Grimes } 5208fae3551SRodney W. Grimes return (dp); 5218fae3551SRodney W. Grimes } 5228fae3551SRodney W. Grimes } 5238fae3551SRodney W. Grimes 5248fae3551SRodney W. Grimes /* 5258fae3551SRodney W. Grimes * Simulate the opening of a directory 5268fae3551SRodney W. Grimes */ 5278fae3551SRodney W. Grimes RST_DIR * 5288fae3551SRodney W. Grimes rst_opendir(name) 5298fae3551SRodney W. Grimes const char *name; 5308fae3551SRodney W. Grimes { 5318fae3551SRodney W. Grimes struct inotab *itp; 5328fae3551SRodney W. Grimes RST_DIR *dirp; 5338fae3551SRodney W. Grimes ino_t ino; 5348fae3551SRodney W. Grimes 5358fae3551SRodney W. Grimes if ((ino = dirlookup(name)) > 0 && 5368fae3551SRodney W. Grimes (itp = inotablookup(ino)) != NULL) { 5378fae3551SRodney W. Grimes dirp = opendirfile(dirfile); 5388fae3551SRodney W. Grimes rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); 5398fae3551SRodney W. Grimes return (dirp); 5408fae3551SRodney W. Grimes } 5418fae3551SRodney W. Grimes return (NULL); 5428fae3551SRodney W. Grimes } 5438fae3551SRodney W. Grimes 5448fae3551SRodney W. Grimes /* 5458fae3551SRodney W. Grimes * In our case, there is nothing to do when closing a directory. 5468fae3551SRodney W. Grimes */ 5478fae3551SRodney W. Grimes void 5488fae3551SRodney W. Grimes rst_closedir(dirp) 5498fae3551SRodney W. Grimes RST_DIR *dirp; 5508fae3551SRodney W. Grimes { 5518fae3551SRodney W. Grimes 5528fae3551SRodney W. Grimes (void)close(dirp->dd_fd); 5538fae3551SRodney W. Grimes free(dirp); 5548fae3551SRodney W. Grimes return; 5558fae3551SRodney W. Grimes } 5568fae3551SRodney W. Grimes 5578fae3551SRodney W. Grimes /* 5588fae3551SRodney W. Grimes * Simulate finding the current offset in the directory. 5598fae3551SRodney W. Grimes */ 5608fae3551SRodney W. Grimes static long 5618fae3551SRodney W. Grimes rst_telldir(dirp) 5628fae3551SRodney W. Grimes RST_DIR *dirp; 5638fae3551SRodney W. Grimes { 5648fae3551SRodney W. Grimes return ((long)lseek(dirp->dd_fd, 5658fae3551SRodney W. Grimes (off_t)0, SEEK_CUR) - dirp->dd_size + dirp->dd_loc); 5668fae3551SRodney W. Grimes } 5678fae3551SRodney W. Grimes 5688fae3551SRodney W. Grimes /* 5698fae3551SRodney W. Grimes * Open a directory file. 5708fae3551SRodney W. Grimes */ 5718fae3551SRodney W. Grimes static RST_DIR * 5728fae3551SRodney W. Grimes opendirfile(name) 5738fae3551SRodney W. Grimes const char *name; 5748fae3551SRodney W. Grimes { 5758fae3551SRodney W. Grimes register RST_DIR *dirp; 5768fae3551SRodney W. Grimes register int fd; 5778fae3551SRodney W. Grimes 5788fae3551SRodney W. Grimes if ((fd = open(name, O_RDONLY)) == -1) 5798fae3551SRodney W. Grimes return (NULL); 5808fae3551SRodney W. Grimes if ((dirp = malloc(sizeof(RST_DIR))) == NULL) { 5818fae3551SRodney W. Grimes (void)close(fd); 5828fae3551SRodney W. Grimes return (NULL); 5838fae3551SRodney W. Grimes } 5848fae3551SRodney W. Grimes dirp->dd_fd = fd; 5858fae3551SRodney W. Grimes dirp->dd_loc = 0; 5868fae3551SRodney W. Grimes return (dirp); 5878fae3551SRodney W. Grimes } 5888fae3551SRodney W. Grimes 5898fae3551SRodney W. Grimes /* 5908fae3551SRodney W. Grimes * Set the mode, owner, and times for all new or changed directories 5918fae3551SRodney W. Grimes */ 5928fae3551SRodney W. Grimes void 5938fae3551SRodney W. Grimes setdirmodes(flags) 5948fae3551SRodney W. Grimes int flags; 5958fae3551SRodney W. Grimes { 5968fae3551SRodney W. Grimes FILE *mf; 5978fae3551SRodney W. Grimes struct modeinfo node; 5988fae3551SRodney W. Grimes struct entry *ep; 5998fae3551SRodney W. Grimes char *cp; 6008fae3551SRodney W. Grimes 6018fae3551SRodney W. Grimes vprintf(stdout, "Set directory mode, owner, and times.\n"); 602335524b9SWarner Losh if (command == 'r' || command == 'R') 603335524b9SWarner Losh (void) sprintf(modefile, "%srstmode%d", _PATH_TMP, dumpdate); 604335524b9SWarner Losh if (modefile[0] == '#') { 605335524b9SWarner Losh panic("modefile not defined\n"); 606335524b9SWarner Losh fprintf(stderr, "directory mode, owner, and times not set\n"); 607335524b9SWarner Losh return; 608335524b9SWarner Losh } 6098fae3551SRodney W. Grimes mf = fopen(modefile, "r"); 6108fae3551SRodney W. Grimes if (mf == NULL) { 6118fae3551SRodney W. Grimes fprintf(stderr, "fopen: %s\n", strerror(errno)); 6128fae3551SRodney W. Grimes fprintf(stderr, "cannot open mode file %s\n", modefile); 6138fae3551SRodney W. Grimes fprintf(stderr, "directory mode, owner, and times not set\n"); 6148fae3551SRodney W. Grimes return; 6158fae3551SRodney W. Grimes } 6168fae3551SRodney W. Grimes clearerr(mf); 6178fae3551SRodney W. Grimes for (;;) { 6188fae3551SRodney W. Grimes (void) fread((char *)&node, 1, sizeof(struct modeinfo), mf); 6198fae3551SRodney W. Grimes if (feof(mf)) 6208fae3551SRodney W. Grimes break; 6218fae3551SRodney W. Grimes ep = lookupino(node.ino); 6228fae3551SRodney W. Grimes if (command == 'i' || command == 'x') { 6238fae3551SRodney W. Grimes if (ep == NULL) 6248fae3551SRodney W. Grimes continue; 6258fae3551SRodney W. Grimes if ((flags & FORCE) == 0 && ep->e_flags & EXISTED) { 6268fae3551SRodney W. Grimes ep->e_flags &= ~NEW; 6278fae3551SRodney W. Grimes continue; 6288fae3551SRodney W. Grimes } 6298fae3551SRodney W. Grimes if (node.ino == ROOTINO && 6308fae3551SRodney W. Grimes reply("set owner/mode for '.'") == FAIL) 6318fae3551SRodney W. Grimes continue; 6328fae3551SRodney W. Grimes } 6338fae3551SRodney W. Grimes if (ep == NULL) { 6348fae3551SRodney W. Grimes panic("cannot find directory inode %d\n", node.ino); 6358fae3551SRodney W. Grimes } else { 6368fae3551SRodney W. Grimes cp = myname(ep); 6378fae3551SRodney W. Grimes (void) chown(cp, node.uid, node.gid); 6388fae3551SRodney W. Grimes (void) chmod(cp, node.mode); 639d87d79aeSPeter Wemm (void) chflags(cp, node.flags); 6408fae3551SRodney W. Grimes utimes(cp, node.timep); 6418fae3551SRodney W. Grimes ep->e_flags &= ~NEW; 6428fae3551SRodney W. Grimes } 6438fae3551SRodney W. Grimes } 6448fae3551SRodney W. Grimes if (ferror(mf)) 6458fae3551SRodney W. Grimes panic("error setting directory modes\n"); 6468fae3551SRodney W. Grimes (void) fclose(mf); 6478fae3551SRodney W. Grimes } 6488fae3551SRodney W. Grimes 6498fae3551SRodney W. Grimes /* 6508fae3551SRodney W. Grimes * Generate a literal copy of a directory. 6518fae3551SRodney W. Grimes */ 6528fae3551SRodney W. Grimes int 6538fae3551SRodney W. Grimes genliteraldir(name, ino) 6548fae3551SRodney W. Grimes char *name; 6558fae3551SRodney W. Grimes ino_t ino; 6568fae3551SRodney W. Grimes { 6578fae3551SRodney W. Grimes register struct inotab *itp; 6588fae3551SRodney W. Grimes int ofile, dp, i, size; 6598fae3551SRodney W. Grimes char buf[BUFSIZ]; 6608fae3551SRodney W. Grimes 6618fae3551SRodney W. Grimes itp = inotablookup(ino); 6628fae3551SRodney W. Grimes if (itp == NULL) 6638fae3551SRodney W. Grimes panic("Cannot find directory inode %d named %s\n", ino, name); 664335524b9SWarner Losh if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { 6658fae3551SRodney W. Grimes fprintf(stderr, "%s: ", name); 6668fae3551SRodney W. Grimes (void) fflush(stderr); 6678fae3551SRodney W. Grimes fprintf(stderr, "cannot create file: %s\n", strerror(errno)); 6688fae3551SRodney W. Grimes return (FAIL); 6698fae3551SRodney W. Grimes } 6708fae3551SRodney W. Grimes rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); 6718fae3551SRodney W. Grimes dp = dup(dirp->dd_fd); 6728fae3551SRodney W. Grimes for (i = itp->t_size; i > 0; i -= BUFSIZ) { 6738fae3551SRodney W. Grimes size = i < BUFSIZ ? i : BUFSIZ; 6748fae3551SRodney W. Grimes if (read(dp, buf, (int) size) == -1) { 6758fae3551SRodney W. Grimes fprintf(stderr, 6768fae3551SRodney W. Grimes "write error extracting inode %d, name %s\n", 6778fae3551SRodney W. Grimes curfile.ino, curfile.name); 6788fae3551SRodney W. Grimes fprintf(stderr, "read: %s\n", strerror(errno)); 6798fae3551SRodney W. Grimes done(1); 6808fae3551SRodney W. Grimes } 6818fae3551SRodney W. Grimes if (!Nflag && write(ofile, buf, (int) size) == -1) { 6828fae3551SRodney W. Grimes fprintf(stderr, 6838fae3551SRodney W. Grimes "write error extracting inode %d, name %s\n", 6848fae3551SRodney W. Grimes curfile.ino, curfile.name); 6858fae3551SRodney W. Grimes fprintf(stderr, "write: %s\n", strerror(errno)); 6868fae3551SRodney W. Grimes done(1); 6878fae3551SRodney W. Grimes } 6888fae3551SRodney W. Grimes } 6898fae3551SRodney W. Grimes (void) close(dp); 6908fae3551SRodney W. Grimes (void) close(ofile); 6918fae3551SRodney W. Grimes return (GOOD); 6928fae3551SRodney W. Grimes } 6938fae3551SRodney W. Grimes 6948fae3551SRodney W. Grimes /* 6958fae3551SRodney W. Grimes * Determine the type of an inode 6968fae3551SRodney W. Grimes */ 6978fae3551SRodney W. Grimes int 6988fae3551SRodney W. Grimes inodetype(ino) 6998fae3551SRodney W. Grimes ino_t ino; 7008fae3551SRodney W. Grimes { 7018fae3551SRodney W. Grimes struct inotab *itp; 7028fae3551SRodney W. Grimes 7038fae3551SRodney W. Grimes itp = inotablookup(ino); 7048fae3551SRodney W. Grimes if (itp == NULL) 7058fae3551SRodney W. Grimes return (LEAF); 7068fae3551SRodney W. Grimes return (NODE); 7078fae3551SRodney W. Grimes } 7088fae3551SRodney W. Grimes 7098fae3551SRodney W. Grimes /* 7108fae3551SRodney W. Grimes * Allocate and initialize a directory inode entry. 7118fae3551SRodney W. Grimes * If requested, save its pertinent mode, owner, and time info. 7128fae3551SRodney W. Grimes */ 7138fae3551SRodney W. Grimes static struct inotab * 7148fae3551SRodney W. Grimes allocinotab(ino, dip, seekpt) 7158fae3551SRodney W. Grimes ino_t ino; 7168fae3551SRodney W. Grimes struct dinode *dip; 7178fae3551SRodney W. Grimes long seekpt; 7188fae3551SRodney W. Grimes { 7198fae3551SRodney W. Grimes register struct inotab *itp; 7208fae3551SRodney W. Grimes struct modeinfo node; 7218fae3551SRodney W. Grimes 7228fae3551SRodney W. Grimes itp = calloc(1, sizeof(struct inotab)); 7238fae3551SRodney W. Grimes if (itp == NULL) 7248fae3551SRodney W. Grimes panic("no memory directory table\n"); 7258fae3551SRodney W. Grimes itp->t_next = inotab[INOHASH(ino)]; 7268fae3551SRodney W. Grimes inotab[INOHASH(ino)] = itp; 7278fae3551SRodney W. Grimes itp->t_ino = ino; 7288fae3551SRodney W. Grimes itp->t_seekpt = seekpt; 7298fae3551SRodney W. Grimes if (mf == NULL) 7308fae3551SRodney W. Grimes return (itp); 7318fae3551SRodney W. Grimes node.ino = ino; 732d87d79aeSPeter Wemm node.timep[0].tv_sec = dip->di_atime; 733d87d79aeSPeter Wemm node.timep[0].tv_usec = dip->di_atimensec / 1000; 734d87d79aeSPeter Wemm node.timep[1].tv_sec = dip->di_mtime; 735d87d79aeSPeter Wemm node.timep[1].tv_usec = dip->di_mtimensec / 1000; 7368fae3551SRodney W. Grimes node.mode = dip->di_mode; 737d87d79aeSPeter Wemm node.flags = dip->di_flags; 7388fae3551SRodney W. Grimes node.uid = dip->di_uid; 7398fae3551SRodney W. Grimes node.gid = dip->di_gid; 7408fae3551SRodney W. Grimes (void) fwrite((char *)&node, 1, sizeof(struct modeinfo), mf); 7418fae3551SRodney W. Grimes return (itp); 7428fae3551SRodney W. Grimes } 7438fae3551SRodney W. Grimes 7448fae3551SRodney W. Grimes /* 7458fae3551SRodney W. Grimes * Look up an inode in the table of directories 7468fae3551SRodney W. Grimes */ 7478fae3551SRodney W. Grimes static struct inotab * 7488fae3551SRodney W. Grimes inotablookup(ino) 7498fae3551SRodney W. Grimes ino_t ino; 7508fae3551SRodney W. Grimes { 7518fae3551SRodney W. Grimes register struct inotab *itp; 7528fae3551SRodney W. Grimes 7538fae3551SRodney W. Grimes for (itp = inotab[INOHASH(ino)]; itp != NULL; itp = itp->t_next) 7548fae3551SRodney W. Grimes if (itp->t_ino == ino) 7558fae3551SRodney W. Grimes return (itp); 7568fae3551SRodney W. Grimes return (NULL); 7578fae3551SRodney W. Grimes } 7588fae3551SRodney W. Grimes 7598fae3551SRodney W. Grimes /* 7608fae3551SRodney W. Grimes * Clean up and exit 7618fae3551SRodney W. Grimes */ 762eaa86f9dSBruce Evans void 7638fae3551SRodney W. Grimes done(exitcode) 7648fae3551SRodney W. Grimes int exitcode; 7658fae3551SRodney W. Grimes { 7668fae3551SRodney W. Grimes 7678fae3551SRodney W. Grimes closemt(); 7688fae3551SRodney W. Grimes if (modefile[0] != '#') 7698fae3551SRodney W. Grimes (void) unlink(modefile); 7708fae3551SRodney W. Grimes if (dirfile[0] != '#') 7718fae3551SRodney W. Grimes (void) unlink(dirfile); 7728fae3551SRodney W. Grimes exit(exitcode); 7738fae3551SRodney W. Grimes } 774