Commit | Line | Data |
---|---|---|
8c5eec2f | 1 | /* |
b42768a6 KB |
2 | * Copyright (c) 1983 The Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms are permitted | |
6 | * provided that the above copyright notice and this paragraph are | |
7 | * duplicated in all such forms and that any documentation, | |
8 | * advertising materials, and other materials related to such | |
9 | * distribution and use acknowledge that the software was developed | |
10 | * by the University of California, Berkeley. The name of the | |
11 | * University may not be used to endorse or promote products derived | |
12 | * from this software without specific prior written permission. | |
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
15 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
8c5eec2f | 16 | */ |
f743fc86 | 17 | |
8c5eec2f | 18 | #ifndef lint |
7abf8d65 | 19 | static char sccsid[] = "@(#)dirs.c 5.7 (Berkeley) %G%"; |
b42768a6 | 20 | #endif /* not lint */ |
ebd1f727 | 21 | |
f743fc86 | 22 | #include "restore.h" |
d9127117 | 23 | #include <protocols/dumprestore.h> |
9f13f26d | 24 | #include <sys/file.h> |
7abf8d65 | 25 | #include "pathnames.h" |
f743fc86 | 26 | |
7432ff81 KM |
27 | /* |
28 | * Symbol table of directories read from tape. | |
29 | */ | |
f743fc86 | 30 | #define HASHSIZE 1000 |
f743fc86 KM |
31 | #define INOHASH(val) (val % HASHSIZE) |
32 | struct inotab { | |
33 | struct inotab *t_next; | |
34 | ino_t t_ino; | |
35 | daddr_t t_seekpt; | |
36 | long t_size; | |
9f13f26d KM |
37 | }; |
38 | static struct inotab *inotab[HASHSIZE]; | |
39 | extern struct inotab *inotablookup(); | |
9730f69a | 40 | extern struct inotab *allocinotab(); |
f743fc86 | 41 | |
7432ff81 KM |
42 | /* |
43 | * Information retained about directories. | |
44 | */ | |
f743fc86 KM |
45 | struct modeinfo { |
46 | ino_t ino; | |
47 | time_t timep[2]; | |
48 | short mode; | |
49 | short uid; | |
50 | short gid; | |
51 | }; | |
52 | ||
7432ff81 KM |
53 | /* |
54 | * Global variables for this file. | |
55 | */ | |
9f13f26d KM |
56 | static daddr_t seekpt; |
57 | static FILE *df, *mf; | |
58 | static DIR *dirp; | |
7432ff81 KM |
59 | static char dirfile[32] = "#"; /* No file */ |
60 | static char modefile[32] = "#"; /* No file */ | |
9f13f26d | 61 | extern ino_t search(); |
e9e7ecc4 KM |
62 | struct direct *rst_readdir(); |
63 | extern void rst_seekdir(); | |
f743fc86 | 64 | |
7432ff81 KM |
65 | /* |
66 | * Format of old style directories. | |
67 | */ | |
f743fc86 KM |
68 | #define ODIRSIZ 14 |
69 | struct odirect { | |
70 | u_short d_ino; | |
71 | char d_name[ODIRSIZ]; | |
72 | }; | |
73 | ||
74 | /* | |
75 | * Extract directory contents, building up a directory structure | |
76 | * on disk for extraction by name. | |
7432ff81 | 77 | * If genmode is requested, save mode, owner, and times for all |
f743fc86 KM |
78 | * directories on the tape. |
79 | */ | |
7432ff81 KM |
80 | extractdirs(genmode) |
81 | int genmode; | |
f743fc86 KM |
82 | { |
83 | register int i; | |
84 | register struct dinode *ip; | |
9730f69a | 85 | struct inotab *itp; |
f743fc86 KM |
86 | struct direct nulldir; |
87 | int putdir(), null(); | |
88 | ||
89 | vprintf(stdout, "Extract directories from tape\n"); | |
7abf8d65 | 90 | (void) sprintf(dirfile, "%s/rstdir%d", _PATH_TMP, dumpdate); |
f743fc86 KM |
91 | df = fopen(dirfile, "w"); |
92 | if (df == 0) { | |
93 | fprintf(stderr, | |
97b06931 | 94 | "restore: %s - cannot create directory temporary\n", |
f743fc86 KM |
95 | dirfile); |
96 | perror("fopen"); | |
97 | done(1); | |
98 | } | |
7432ff81 | 99 | if (genmode != 0) { |
7abf8d65 | 100 | (void) sprintf(modefile, "%s/rstmode%d", _PATH_TMP, dumpdate); |
f743fc86 | 101 | mf = fopen(modefile, "w"); |
9f13f26d | 102 | if (mf == 0) { |
f743fc86 | 103 | fprintf(stderr, |
97b06931 | 104 | "restore: %s - cannot create modefile \n", |
f743fc86 KM |
105 | modefile); |
106 | perror("fopen"); | |
107 | done(1); | |
108 | } | |
109 | } | |
9730f69a | 110 | nulldir.d_ino = 0; |
f743fc86 | 111 | nulldir.d_namlen = 1; |
93d90477 | 112 | (void) strcpy(nulldir.d_name, "/"); |
f743fc86 KM |
113 | nulldir.d_reclen = DIRSIZ(&nulldir); |
114 | for (;;) { | |
115 | curfile.name = "<directory file - name unknown>"; | |
116 | curfile.action = USING; | |
117 | ip = curfile.dip; | |
58ee757a | 118 | if (ip == NULL || (ip->di_mode & IFMT) != IFDIR) { |
82d46726 | 119 | (void) fclose(df); |
f743fc86 KM |
120 | dirp = opendir(dirfile); |
121 | if (dirp == NULL) | |
122 | perror("opendir"); | |
123 | if (mf != NULL) | |
82d46726 | 124 | (void) fclose(mf); |
7432ff81 KM |
125 | i = dirlookup("."); |
126 | if (i == 0) | |
7851e15d | 127 | panic("Root directory is not on tape\n"); |
f743fc86 KM |
128 | return; |
129 | } | |
9730f69a | 130 | itp = allocinotab(curfile.ino, ip, seekpt); |
f743fc86 KM |
131 | getfile(putdir, null); |
132 | putent(&nulldir); | |
133 | flushent(); | |
9730f69a KM |
134 | itp->t_size = seekpt - itp->t_seekpt; |
135 | } | |
136 | } | |
137 | ||
138 | /* | |
139 | * skip over all the directories on the tape | |
140 | */ | |
141 | skipdirs() | |
142 | { | |
143 | ||
144 | while ((curfile.dip->di_mode & IFMT) == IFDIR) { | |
145 | skipfile(); | |
f743fc86 KM |
146 | } |
147 | } | |
148 | ||
149 | /* | |
150 | * Recursively find names and inumbers of all files in subtree | |
151 | * pname and pass them off to be processed. | |
152 | */ | |
153 | treescan(pname, ino, todo) | |
154 | char *pname; | |
155 | ino_t ino; | |
314ac756 | 156 | long (*todo)(); |
f743fc86 KM |
157 | { |
158 | register struct inotab *itp; | |
93d90477 KM |
159 | register struct direct *dp; |
160 | register struct entry *np; | |
f743fc86 KM |
161 | int namelen; |
162 | daddr_t bpt; | |
4796d2a4 | 163 | char locname[MAXPATHLEN + 1]; |
f743fc86 KM |
164 | |
165 | itp = inotablookup(ino); | |
166 | if (itp == NULL) { | |
167 | /* | |
168 | * Pname is name of a simple file or an unchanged directory. | |
169 | */ | |
314ac756 | 170 | (void) (*todo)(pname, ino, LEAF); |
f743fc86 KM |
171 | return; |
172 | } | |
173 | /* | |
174 | * Pname is a dumped directory name. | |
175 | */ | |
314ac756 KM |
176 | if ((*todo)(pname, ino, NODE) == FAIL) |
177 | return; | |
f743fc86 KM |
178 | /* |
179 | * begin search through the directory | |
180 | * skipping over "." and ".." | |
181 | */ | |
7432ff81 KM |
182 | (void) strncpy(locname, pname, MAXPATHLEN); |
183 | (void) strncat(locname, "/", MAXPATHLEN); | |
f743fc86 | 184 | namelen = strlen(locname); |
e9e7ecc4 KM |
185 | rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); |
186 | dp = rst_readdir(dirp); /* "." */ | |
329dd5fb | 187 | if (dp != NULL && strcmp(dp->d_name, ".") == 0) |
e9e7ecc4 | 188 | dp = rst_readdir(dirp); /* ".." */ |
329dd5fb KM |
189 | else |
190 | fprintf(stderr, "Warning: `.' missing from directory %s\n", | |
191 | pname); | |
192 | if (dp != NULL && strcmp(dp->d_name, "..") == 0) | |
e9e7ecc4 | 193 | dp = rst_readdir(dirp); /* first real entry */ |
329dd5fb KM |
194 | else |
195 | fprintf(stderr, "Warning: `..' missing from directory %s\n", | |
196 | pname); | |
f743fc86 KM |
197 | bpt = telldir(dirp); |
198 | /* | |
93d90477 | 199 | * a zero inode signals end of directory |
f743fc86 | 200 | */ |
93d90477 | 201 | while (dp != NULL && dp->d_ino != 0) { |
f743fc86 | 202 | locname[namelen] = '\0'; |
4796d2a4 | 203 | if (namelen + dp->d_namlen >= MAXPATHLEN) { |
f743fc86 | 204 | fprintf(stderr, "%s%s: name exceeds %d char\n", |
4796d2a4 | 205 | locname, dp->d_name, MAXPATHLEN); |
f743fc86 | 206 | } else { |
7432ff81 | 207 | (void) strncat(locname, dp->d_name, (int)dp->d_namlen); |
f743fc86 | 208 | treescan(locname, dp->d_ino, todo); |
e9e7ecc4 | 209 | rst_seekdir(dirp, bpt, itp->t_seekpt); |
f743fc86 | 210 | } |
e9e7ecc4 | 211 | dp = rst_readdir(dirp); |
f743fc86 KM |
212 | bpt = telldir(dirp); |
213 | } | |
214 | if (dp == NULL) | |
215 | fprintf(stderr, "corrupted directory: %s.\n", locname); | |
216 | } | |
217 | ||
218 | /* | |
219 | * Search the directory tree rooted at inode ROOTINO | |
220 | * for the path pointed at by n | |
221 | */ | |
222 | ino_t | |
223 | psearch(n) | |
224 | char *n; | |
225 | { | |
226 | register char *cp, *cp1; | |
227 | ino_t ino; | |
228 | char c; | |
229 | ||
230 | ino = ROOTINO; | |
231 | if (*(cp = n) == '/') | |
232 | cp++; | |
233 | next: | |
234 | cp1 = cp + 1; | |
235 | while (*cp1 != '/' && *cp1) | |
236 | cp1++; | |
237 | c = *cp1; | |
238 | *cp1 = 0; | |
239 | ino = search(ino, cp); | |
240 | if (ino == 0) { | |
241 | *cp1 = c; | |
242 | return(0); | |
243 | } | |
244 | *cp1 = c; | |
245 | if (c == '/') { | |
246 | cp = cp1+1; | |
247 | goto next; | |
248 | } | |
249 | return(ino); | |
250 | } | |
251 | ||
252 | /* | |
253 | * search the directory inode ino | |
254 | * looking for entry cp | |
255 | */ | |
256 | ino_t | |
257 | search(inum, cp) | |
258 | ino_t inum; | |
259 | char *cp; | |
260 | { | |
261 | register struct direct *dp; | |
262 | register struct inotab *itp; | |
263 | int len; | |
264 | ||
265 | itp = inotablookup(inum); | |
266 | if (itp == NULL) | |
267 | return(0); | |
e9e7ecc4 | 268 | rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); |
f743fc86 KM |
269 | len = strlen(cp); |
270 | do { | |
e9e7ecc4 | 271 | dp = rst_readdir(dirp); |
93d90477 KM |
272 | if (dp == NULL || dp->d_ino == 0) |
273 | return (0); | |
7432ff81 | 274 | } while (dp->d_namlen != len || strncmp(dp->d_name, cp, len) != 0); |
f743fc86 KM |
275 | return(dp->d_ino); |
276 | } | |
277 | ||
278 | /* | |
279 | * Put the directory entries in the directory file | |
280 | */ | |
281 | putdir(buf, size) | |
282 | char *buf; | |
283 | int size; | |
284 | { | |
285 | struct direct cvtbuf; | |
286 | register struct odirect *odp; | |
287 | struct odirect *eodp; | |
288 | register struct direct *dp; | |
289 | long loc, i; | |
10462cc1 | 290 | extern int Bcvt; |
f743fc86 KM |
291 | |
292 | if (cvtflag) { | |
293 | eodp = (struct odirect *)&buf[size]; | |
294 | for (odp = (struct odirect *)buf; odp < eodp; odp++) | |
295 | if (odp->d_ino != 0) { | |
296 | dcvt(odp, &cvtbuf); | |
297 | putent(&cvtbuf); | |
298 | } | |
299 | } else { | |
300 | for (loc = 0; loc < size; ) { | |
301 | dp = (struct direct *)(buf + loc); | |
10462cc1 KS |
302 | if (Bcvt) { |
303 | swabst("l2s", (char *) dp); | |
304 | } | |
f743fc86 KM |
305 | i = DIRBLKSIZ - (loc & (DIRBLKSIZ - 1)); |
306 | if (dp->d_reclen == 0 || dp->d_reclen > i) { | |
307 | loc += i; | |
308 | continue; | |
309 | } | |
310 | loc += dp->d_reclen; | |
311 | if (dp->d_ino != 0) { | |
312 | putent(dp); | |
313 | } | |
314 | } | |
315 | } | |
316 | } | |
317 | ||
318 | /* | |
319 | * These variables are "local" to the following two functions. | |
320 | */ | |
321 | char dirbuf[DIRBLKSIZ]; | |
322 | long dirloc = 0; | |
323 | long prev = 0; | |
324 | ||
325 | /* | |
326 | * add a new directory entry to a file. | |
327 | */ | |
328 | putent(dp) | |
329 | struct direct *dp; | |
330 | { | |
9730f69a | 331 | dp->d_reclen = DIRSIZ(dp); |
f743fc86 KM |
332 | if (dirloc + dp->d_reclen > DIRBLKSIZ) { |
333 | ((struct direct *)(dirbuf + prev))->d_reclen = | |
334 | DIRBLKSIZ - prev; | |
82d46726 | 335 | (void) fwrite(dirbuf, 1, DIRBLKSIZ, df); |
f743fc86 KM |
336 | dirloc = 0; |
337 | } | |
338 | bcopy((char *)dp, dirbuf + dirloc, (long)dp->d_reclen); | |
339 | prev = dirloc; | |
340 | dirloc += dp->d_reclen; | |
341 | } | |
342 | ||
343 | /* | |
344 | * flush out a directory that is finished. | |
345 | */ | |
346 | flushent() | |
347 | { | |
348 | ||
349 | ((struct direct *)(dirbuf + prev))->d_reclen = DIRBLKSIZ - prev; | |
82d46726 | 350 | (void) fwrite(dirbuf, (int)dirloc, 1, df); |
f743fc86 KM |
351 | seekpt = ftell(df); |
352 | dirloc = 0; | |
353 | } | |
354 | ||
355 | dcvt(odp, ndp) | |
356 | register struct odirect *odp; | |
357 | register struct direct *ndp; | |
358 | { | |
359 | ||
360 | bzero((char *)ndp, (long)(sizeof *ndp)); | |
361 | ndp->d_ino = odp->d_ino; | |
7432ff81 | 362 | (void) strncpy(ndp->d_name, odp->d_name, ODIRSIZ); |
f743fc86 KM |
363 | ndp->d_namlen = strlen(ndp->d_name); |
364 | ndp->d_reclen = DIRSIZ(ndp); | |
f743fc86 KM |
365 | } |
366 | ||
367 | /* | |
368 | * Seek to an entry in a directory. | |
e9e7ecc4 | 369 | * Only values returned by ``telldir'' should be passed to rst_seekdir. |
82d46726 KM |
370 | * This routine handles many directories in a single file. |
371 | * It takes the base of the directory in the file, plus | |
372 | * the desired seek offset into it. | |
f743fc86 KM |
373 | */ |
374 | void | |
e9e7ecc4 | 375 | rst_seekdir(dirp, loc, base) |
f743fc86 KM |
376 | register DIR *dirp; |
377 | daddr_t loc, base; | |
378 | { | |
379 | ||
380 | if (loc == telldir(dirp)) | |
381 | return; | |
382 | loc -= base; | |
383 | if (loc < 0) | |
e9e7ecc4 | 384 | fprintf(stderr, "bad seek pointer to rst_seekdir %d\n", loc); |
f743fc86 KM |
385 | (void) lseek(dirp->dd_fd, base + (loc & ~(DIRBLKSIZ - 1)), 0); |
386 | dirp->dd_loc = loc & (DIRBLKSIZ - 1); | |
387 | if (dirp->dd_loc != 0) | |
388 | dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ); | |
389 | } | |
390 | ||
391 | /* | |
392 | * get next entry in a directory. | |
393 | */ | |
394 | struct direct * | |
e9e7ecc4 | 395 | rst_readdir(dirp) |
f743fc86 KM |
396 | register DIR *dirp; |
397 | { | |
398 | register struct direct *dp; | |
399 | ||
400 | for (;;) { | |
401 | if (dirp->dd_loc == 0) { | |
402 | dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, | |
403 | DIRBLKSIZ); | |
93d90477 KM |
404 | if (dirp->dd_size <= 0) { |
405 | dprintf(stderr, "error reading directory\n"); | |
f743fc86 | 406 | return NULL; |
93d90477 | 407 | } |
f743fc86 KM |
408 | } |
409 | if (dirp->dd_loc >= dirp->dd_size) { | |
410 | dirp->dd_loc = 0; | |
411 | continue; | |
412 | } | |
413 | dp = (struct direct *)(dirp->dd_buf + dirp->dd_loc); | |
414 | if (dp->d_reclen == 0 || | |
93d90477 KM |
415 | dp->d_reclen > DIRBLKSIZ + 1 - dirp->dd_loc) { |
416 | dprintf(stderr, "corrupted directory: bad reclen %d\n", | |
417 | dp->d_reclen); | |
f743fc86 | 418 | return NULL; |
93d90477 | 419 | } |
f743fc86 | 420 | dirp->dd_loc += dp->d_reclen; |
93d90477 KM |
421 | if (dp->d_ino == 0 && strcmp(dp->d_name, "/") != 0) |
422 | continue; | |
e9e7ecc4 | 423 | if (dp->d_ino >= maxino) { |
93d90477 KM |
424 | dprintf(stderr, "corrupted directory: bad inum %d\n", |
425 | dp->d_ino); | |
426 | continue; | |
427 | } | |
f743fc86 KM |
428 | return (dp); |
429 | } | |
430 | } | |
431 | ||
f97d7036 KM |
432 | /* |
433 | * Simulate the opening of a directory | |
434 | */ | |
435 | DIR * | |
436 | rst_opendir(name) | |
437 | char *name; | |
438 | { | |
439 | struct inotab *itp; | |
440 | ino_t ino; | |
441 | ||
442 | if ((ino = dirlookup(name)) > 0 && | |
443 | (itp = inotablookup(ino)) != NULL) { | |
444 | rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); | |
445 | return (dirp); | |
446 | } | |
447 | return (0); | |
448 | } | |
449 | ||
f743fc86 KM |
450 | /* |
451 | * Set the mode, owner, and times for all new or changed directories | |
452 | */ | |
7432ff81 | 453 | setdirmodes() |
f743fc86 KM |
454 | { |
455 | FILE *mf; | |
456 | struct modeinfo node; | |
457 | struct entry *ep; | |
458 | char *cp; | |
459 | ||
460 | vprintf(stdout, "Set directory mode, owner, and times.\n"); | |
7abf8d65 | 461 | (void) sprintf(modefile, "%s/rstmode%d", _PATH_TMP, dumpdate); |
f743fc86 KM |
462 | mf = fopen(modefile, "r"); |
463 | if (mf == NULL) { | |
464 | perror("fopen"); | |
97b06931 KM |
465 | fprintf(stderr, "cannot open mode file %s\n", modefile); |
466 | fprintf(stderr, "directory mode, owner, and times not set\n"); | |
467 | return; | |
f743fc86 KM |
468 | } |
469 | clearerr(mf); | |
9f13f26d | 470 | for (;;) { |
82d46726 | 471 | (void) fread((char *)&node, 1, sizeof(struct modeinfo), mf); |
9f13f26d KM |
472 | if (feof(mf)) |
473 | break; | |
f743fc86 | 474 | ep = lookupino(node.ino); |
47769c2e KM |
475 | if (command == 'i' || command == 'x') { |
476 | if (ep == NIL) | |
477 | continue; | |
a7d37956 KM |
478 | if (ep->e_flags & EXISTED) { |
479 | ep->e_flags &= ~NEW; | |
480 | continue; | |
481 | } | |
47769c2e KM |
482 | if (node.ino == ROOTINO && |
483 | reply("set owner/mode for '.'") == FAIL) | |
9f13f26d | 484 | continue; |
9f13f26d | 485 | } |
47769c2e KM |
486 | if (ep == NIL) |
487 | panic("cannot find directory inode %d\n", node.ino); | |
f743fc86 | 488 | cp = myname(ep); |
82d46726 KM |
489 | (void) chown(cp, node.uid, node.gid); |
490 | (void) chmod(cp, node.mode); | |
f743fc86 | 491 | utime(cp, node.timep); |
7432ff81 | 492 | ep->e_flags &= ~NEW; |
f743fc86 KM |
493 | } |
494 | if (ferror(mf)) | |
495 | panic("error setting directory modes\n"); | |
82d46726 | 496 | (void) fclose(mf); |
f743fc86 KM |
497 | } |
498 | ||
499 | /* | |
500 | * Generate a literal copy of a directory. | |
501 | */ | |
502 | genliteraldir(name, ino) | |
503 | char *name; | |
504 | ino_t ino; | |
505 | { | |
506 | register struct inotab *itp; | |
507 | int ofile, dp, i, size; | |
508 | char buf[BUFSIZ]; | |
509 | ||
510 | itp = inotablookup(ino); | |
511 | if (itp == NULL) | |
9730f69a | 512 | panic("Cannot find directory inode %d named %s\n", ino, name); |
15aeb519 | 513 | if ((ofile = creat(name, 0666)) < 0) { |
e9e7ecc4 KM |
514 | fprintf(stderr, "%s: ", name); |
515 | (void) fflush(stderr); | |
516 | perror("cannot create file"); | |
f743fc86 KM |
517 | return (FAIL); |
518 | } | |
e9e7ecc4 | 519 | rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); |
f743fc86 KM |
520 | dp = dup(dirp->dd_fd); |
521 | for (i = itp->t_size; i > 0; i -= BUFSIZ) { | |
522 | size = i < BUFSIZ ? i : BUFSIZ; | |
523 | if (read(dp, buf, (int) size) == -1) { | |
524 | fprintf(stderr, | |
525 | "write error extracting inode %d, name %s\n", | |
526 | curfile.ino, curfile.name); | |
527 | perror("read"); | |
528 | done(1); | |
529 | } | |
414c4f09 | 530 | if (!Nflag && write(ofile, buf, (int) size) == -1) { |
f743fc86 KM |
531 | fprintf(stderr, |
532 | "write error extracting inode %d, name %s\n", | |
533 | curfile.ino, curfile.name); | |
534 | perror("write"); | |
535 | done(1); | |
536 | } | |
537 | } | |
82d46726 KM |
538 | (void) close(dp); |
539 | (void) close(ofile); | |
f743fc86 KM |
540 | return (GOOD); |
541 | } | |
542 | ||
7432ff81 KM |
543 | /* |
544 | * Determine the type of an inode | |
545 | */ | |
546 | inodetype(ino) | |
547 | ino_t ino; | |
548 | { | |
549 | struct inotab *itp; | |
550 | ||
551 | itp = inotablookup(ino); | |
552 | if (itp == NULL) | |
553 | return (LEAF); | |
554 | return (NODE); | |
555 | } | |
556 | ||
f743fc86 KM |
557 | /* |
558 | * Allocate and initialize a directory inode entry. | |
559 | * If requested, save its pertinent mode, owner, and time info. | |
560 | */ | |
9730f69a | 561 | struct inotab * |
f743fc86 KM |
562 | allocinotab(ino, dip, seekpt) |
563 | ino_t ino; | |
564 | struct dinode *dip; | |
565 | daddr_t seekpt; | |
566 | { | |
567 | register struct inotab *itp; | |
568 | struct modeinfo node; | |
f743fc86 KM |
569 | |
570 | itp = (struct inotab *)calloc(1, sizeof(struct inotab)); | |
ad4fabdf KM |
571 | if (itp == 0) |
572 | panic("no memory directory table\n"); | |
f743fc86 KM |
573 | itp->t_next = inotab[INOHASH(ino)]; |
574 | inotab[INOHASH(ino)] = itp; | |
575 | itp->t_ino = ino; | |
576 | itp->t_seekpt = seekpt; | |
f743fc86 | 577 | if (mf == NULL) |
9730f69a | 578 | return(itp); |
f743fc86 KM |
579 | node.ino = ino; |
580 | node.timep[0] = dip->di_atime; | |
581 | node.timep[1] = dip->di_mtime; | |
582 | node.mode = dip->di_mode; | |
583 | node.uid = dip->di_uid; | |
584 | node.gid = dip->di_gid; | |
82d46726 | 585 | (void) fwrite((char *)&node, 1, sizeof(struct modeinfo), mf); |
9730f69a | 586 | return(itp); |
f743fc86 KM |
587 | } |
588 | ||
589 | /* | |
590 | * Look up an inode in the table of directories | |
591 | */ | |
592 | struct inotab * | |
593 | inotablookup(ino) | |
594 | ino_t ino; | |
595 | { | |
596 | register struct inotab *itp; | |
597 | ||
598 | for (itp = inotab[INOHASH(ino)]; itp != NULL; itp = itp->t_next) | |
599 | if (itp->t_ino == ino) | |
600 | return(itp); | |
601 | return ((struct inotab *)0); | |
602 | } | |
603 | ||
604 | /* | |
605 | * Clean up and exit | |
606 | */ | |
607 | done(exitcode) | |
608 | int exitcode; | |
609 | { | |
610 | ||
611 | closemt(); | |
7432ff81 KM |
612 | if (modefile[0] != '#') |
613 | (void) unlink(modefile); | |
614 | if (dirfile[0] != '#') | |
615 | (void) unlink(dirfile); | |
f743fc86 KM |
616 | exit(exitcode); |
617 | } |