+#endif
+ }
+ }
+ if (ferror(mf))
+ panic("error setting directory modes\n");
+ (void) fclose(mf);
+}
+
+/*
+ * In restore -C mode, tests the attributes for all directories
+ */
+void
+comparedirmodes(void)
+{
+ FILE *mf;
+ struct modeinfo node;
+ struct entry *ep;
+ char *cp;
+
+ Vprintf(stdout, "Compare directories modes, owner, attributes.\n");
+ if (modefile[0] == '#') {
+ panic("modefile not defined\n");
+ fprintf(stderr, "directory mode, owner, and times not set\n");
+ return;
+ }
+ mf = FOPEN(modefile, "r");
+ if (mf == NULL) {
+ warn("fopen");
+ fprintf(stderr, "cannot open mode file %s\n", modefile);
+ fprintf(stderr, "directory mode, owner, and times not set\n");
+ return;
+ }
+ clearerr(mf);
+ for (;;) {
+ char xattr[XATTR_MAXSIZE];
+ if (fread((char *)&node, sizeof(struct modeinfo), 1, mf) != 1) {
+ if (feof(mf))
+ break;
+ err(1, "fread");
+ }
+ if (node.xattr) {
+ if (fread(xattr, XATTR_MAXSIZE, 1, mf) != 1) {
+ if (feof(mf))
+ break;
+ err(1, "fread");
+ }
+ }
+ ep = lookupino(node.ino);
+ if (ep == NULL) {
+ panic("cannot find directory inode %d\n", node.ino);
+ } else {
+ struct STAT sb;
+ unsigned long newflags;
+
+ cp = myname(ep);
+ if (LSTAT(cp, &sb) < 0) {
+ warn("unable to stat %s", cp);
+ do_compare_error;
+ continue;
+ }
+
+ Vprintf(stdout, "comparing directory %s\n", cp);
+
+ if (sb.st_mode != node.mode) {
+ fprintf(stderr, "%s: mode changed from 0%o to 0%o.\n",
+ cp, node.mode & 07777, sb.st_mode & 07777);
+ do_compare_error;
+ }
+ if (sb.st_uid != node.uid) {
+ fprintf(stderr, "%s: uid changed from %d to %d.\n",
+ cp, node.uid, sb.st_uid);
+ do_compare_error;
+ }
+ if (sb.st_gid != node.gid) {
+ fprintf(stderr, "%s: gid changed from %d to %d.\n",
+ cp, node.gid, sb.st_gid);
+ do_compare_error;
+ }
+#ifdef __linux__
+ if (lgetflags(cp, &newflags) < 0) {
+ if (node.flags != 0) {
+ warn("%s: lgetflags failed", cp);
+ do_compare_error;
+ }
+ }
+ else {
+ if (newflags != node.flags) {
+ fprintf(stderr, "%s: flags changed from 0x%08x to 0x%08lx.\n",
+ cp, node.flags, newflags);
+ do_compare_error;
+ }
+ }
+#endif
+ if (node.xattr) {
+ if (xattr_compare(cp, xattr) == FAIL)
+ do_compare_error;
+ }
+ else {
+ if (xattr_compare(cp, NULL) == FAIL)
+ do_compare_error;
+ }