Date: Sun, 10 Mar 2002 02:30:49 +0300 (MSK) From: "Andrew L. Neporada" <andr@dgap.mipt.ru> To: freebsd-bugs@freebsd.org Cc: freebsd-hackers@freebsd.org Subject: [PATCH] exit status of mtree(1) Message-ID: <20020310015221.J11778-200000@nas.dgap.mipt.ru>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
According to man page, mtree should exit with a status of 0 on success
(directory matches spec.), 1 if any error occurred and 2 in the case of
directory with spec. mismatch. But our mtree(1) is badly broken here
(see f.e. bin/28424).
Attached patch solves (I hope) this problem. This patch also introduces
slightly enhanced exit status reporting:
0 - directory matches spec, success
1 - "hard error" -- spec/dir not found, wrong options, etc.
2 - directory/spec mismatch that was fixed successfully
3 - unfixed directory/spec mismatch
Please comment/review.
Andrew.
[-- Attachment #2 --]
Index: compare.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/mtree/compare.c,v
retrieving revision 1.20
diff -u -r1.20 compare.c
--- compare.c 6 Oct 2000 12:48:55 -0000 1.20
+++ compare.c 7 Mar 2002 22:56:25 -0000
@@ -62,6 +62,7 @@
extern int uflag;
extern int lineno;
+extern int rval;
static char *ftype __P((u_int));
@@ -115,6 +116,7 @@
typeerr: LABEL;
(void)printf("\ttype expected %s found %s\n",
ftype(s->type), inotype(p->fts_statp->st_mode));
+ FAILED;
return (label);
}
break;
@@ -124,11 +126,13 @@
LABEL;
(void)printf("%suser expected %lu found %lu",
tab, (u_long)s->st_uid, (u_long)p->fts_statp->st_uid);
+ FIXED;
if (uflag)
- if (chown(p->fts_accpath, s->st_uid, -1))
+ if (chown(p->fts_accpath, s->st_uid, -1)) {
(void)printf(" not modified: %s\n",
strerror(errno));
- else
+ FAILED;
+ } else
(void)printf(" modified\n");
else
(void)printf("\n");
@@ -138,11 +142,13 @@
LABEL;
(void)printf("%sgid expected %lu found %lu",
tab, (u_long)s->st_gid, (u_long)p->fts_statp->st_gid);
+ FIXED;
if (uflag)
- if (chown(p->fts_accpath, -1, s->st_gid))
+ if (chown(p->fts_accpath, -1, s->st_gid)) {
(void)printf(" not modified: %s\n",
strerror(errno));
- else
+ FAILED;
+ } else
(void)printf(" modified\n");
else
(void)printf("\n");
@@ -154,11 +160,13 @@
LABEL;
(void)printf("%spermissions expected %#o found %#o",
tab, s->st_mode, p->fts_statp->st_mode & MBITS);
+ FIXED;
if (uflag)
- if (chmod(p->fts_accpath, s->st_mode))
+ if (chmod(p->fts_accpath, s->st_mode)) {
(void)printf(" not modified: %s\n",
strerror(errno));
- else
+ FAILED;
+ } else
(void)printf(" modified\n");
else
(void)printf("\n");
@@ -169,6 +177,7 @@
LABEL;
(void)printf("%slink_count expected %u found %u\n",
tab, s->st_nlink, p->fts_statp->st_nlink);
+ FAILED;
tab = "\t";
}
if (s->flags & F_SIZE && s->st_size != p->fts_statp->st_size &&
@@ -176,6 +185,7 @@
LABEL;
(void)printf("%ssize expected %qd found %qd\n",
tab, s->st_size, p->fts_statp->st_size);
+ FAILED;
tab = "\t";
}
/*
@@ -190,6 +200,7 @@
tab, ctime(&s->st_mtimespec.tv_sec));
(void)printf("found %.24s\n",
ctime(&p->fts_statp->st_mtimespec.tv_sec));
+ FAILED;
tab = "\t";
}
if (s->flags & F_CKSUM) {
@@ -197,12 +208,14 @@
LABEL;
(void)printf("%scksum: %s: %s\n",
tab, p->fts_accpath, strerror(errno));
+ FAILED;
tab = "\t";
} else if (crc(fd, &val, &len)) {
(void)close(fd);
LABEL;
(void)printf("%scksum: %s: %s\n",
tab, p->fts_accpath, strerror(errno));
+ FAILED;
tab = "\t";
} else {
(void)close(fd);
@@ -210,6 +223,7 @@
LABEL;
(void)printf("%scksum expected %lu found %lu\n",
tab, s->cksum, val);
+ FAILED;
}
tab = "\t";
}
@@ -229,12 +243,14 @@
fflags = flags_to_string(p->fts_statp->st_flags);
(void)printf(" found \"%s\"", fflags);
free(fflags);
+ FIXED;
if (uflag)
- if (chflags(p->fts_accpath, s->st_flags))
+ if (chflags(p->fts_accpath, s->st_flags)) {
(void)printf(" not modified: %s\n",
strerror(errno));
- else
+ FAILED;
+ } else
(void)printf(" modified\n");
else
(void)printf("\n");
@@ -249,11 +265,13 @@
LABEL;
printf("%sMD5: %s: %s\n", tab, p->fts_accpath,
strerror(errno));
+ FAILED;
tab = "\t";
} else if (strcmp(new_digest, s->md5digest)) {
LABEL;
printf("%sMD5 expected %s found %s\n", tab, s->md5digest,
new_digest);
+ FAILED;
tab = "\t";
}
}
@@ -267,11 +285,13 @@
LABEL;
printf("%sSHA-1: %s: %s\n", tab, p->fts_accpath,
strerror(errno));
+ FAILED;
tab = "\t";
} else if (strcmp(new_digest, s->sha1digest)) {
LABEL;
printf("%sSHA-1 expected %s found %s\n",
tab, s->sha1digest, new_digest);
+ FAILED;
tab = "\t";
}
}
@@ -285,11 +305,13 @@
LABEL;
printf("%sRIPEMD160: %s: %s\n", tab,
p->fts_accpath, strerror(errno));
+ FAILED;
tab = "\t";
} else if (strcmp(new_digest, s->rmd160digest)) {
LABEL;
printf("%sRIPEMD160 expected %s found %s\n",
tab, s->rmd160digest, new_digest);
+ FAILED;
tab = "\t";
}
}
@@ -300,6 +322,7 @@
LABEL;
(void)printf("%slink_ref expected %s found %s\n",
tab, cp, s->slink);
+ FAILED;
}
return (label);
}
Index: extern.h
===================================================================
RCS file: /home/ncvs/src/usr.sbin/mtree/extern.h,v
retrieving revision 1.5
diff -u -r1.5 extern.h
--- extern.h 17 Jun 2000 14:19:33 -0000 1.5
+++ extern.h 7 Mar 2002 22:56:25 -0000
@@ -43,7 +43,7 @@
u_int parsekey __P((char *, int *));
char *rlink __P((char *));
NODE *spec __P((void));
-int verify __P((void));
+void verify __P((void));
int check_excludes __P((const char *, const char *));
void init_excludes __P((void));
Index: mtree.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/mtree/mtree.c,v
retrieving revision 1.18
diff -u -r1.18 mtree.c
--- mtree.c 25 Sep 2000 16:24:22 -0000 1.18
+++ mtree.c 9 Mar 2002 21:06:47 -0000
@@ -59,6 +59,7 @@
int ftsoptions = FTS_PHYSICAL;
int cflag, dflag, eflag, iflag, nflag, qflag, rflag, sflag, uflag, Uflag;
+int rval;
u_int keys;
char fullpath[MAXPATHLEN];
@@ -71,7 +72,6 @@
{
int ch;
char *dir, *p;
- int status;
dir = NULL;
keys = KEYDEFAULT;
@@ -164,10 +164,10 @@
cwalk();
exit(0);
}
- status = verify();
- if (Uflag & (status == MISMATCHEXIT))
- status = 0;
- exit(status);
+ verify();
+ if (Uflag & (rval == MISMATCHFIXED))
+ rval = 0;
+ exit(rval);
}
static void
Index: mtree.h
===================================================================
RCS file: /home/ncvs/src/usr.sbin/mtree/mtree.h,v
retrieving revision 1.5
diff -u -r1.5 mtree.h
--- mtree.h 9 Dec 1999 20:38:35 -0000 1.5
+++ mtree.h 9 Mar 2002 20:47:08 -0000
@@ -40,7 +40,10 @@
#define KEYDEFAULT \
(F_GID | F_MODE | F_NLINK | F_SIZE | F_SLINK | F_TIME | F_UID | F_FLAGS)
-#define MISMATCHEXIT 2
+#define MISMATCHFIXED 2
+#define FIXFAILED 3
+#define FIXED if (rval != FIXFAILED) rval = MISMATCHFIXED;
+#define FAILED rval = FIXFAILED;
typedef struct _node {
struct _node *parent, *child; /* up, down */
Index: verify.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/mtree/verify.c,v
retrieving revision 1.15
diff -u -r1.15 verify.c
--- verify.c 3 Oct 2000 13:13:47 -0000 1.15
+++ verify.c 9 Mar 2002 20:39:41 -0000
@@ -56,31 +56,29 @@
extern int dflag, eflag, qflag, rflag, sflag, uflag;
extern char fullpath[MAXPATHLEN];
extern int lineno;
+extern int rval;
static NODE *root;
static char path[MAXPATHLEN];
static void miss __P((NODE *, char *));
-static int vwalk __P((void));
+static void vwalk __P((void));
-int
+void
verify()
{
- int rval;
-
root = spec();
- rval = vwalk();
+ vwalk();
miss(root, path);
- return (rval);
}
-static int
+void
vwalk()
{
register FTS *t;
register FTSENT *p;
register NODE *ep, *level;
- int specdepth, rval;
+ int specdepth;
char *argv[2];
argv[0] = ".";
@@ -122,9 +120,8 @@
!fnmatch(ep->name, p->fts_name, FNM_PATHNAME)) ||
!strcmp(ep->name, p->fts_name)) {
ep->flags |= F_VISIT;
- if ((ep->flags & F_NOCHANGE) == 0 &&
- compare(ep->name, ep, p))
- rval = MISMATCHEXIT;
+ if ((ep->flags & F_NOCHANGE) == 0)
+ (void)compare(ep->name, ep, p);
if (ep->flags & F_IGN)
(void)fts_set(t, p, FTS_SKIP);
else if (ep->child && ep->type == F_DIR &&
@@ -139,15 +136,18 @@
continue;
extra:
if (!eflag) {
+ FIXED;
(void)printf("%s extra", RP(p));
if (rflag) {
if ((S_ISDIR(p->fts_statp->st_mode)
? rmdir : unlink)(p->fts_accpath)) {
(void)printf(", not removed: %s",
strerror(errno));
+ FAILED;
} else
(void)printf(", removed");
- }
+ } else
+ FAILED;
(void)putchar('\n');
}
(void)fts_set(t, p, FTS_SKIP);
@@ -155,7 +155,6 @@
(void)fts_close(t);
if (sflag)
warnx("%s checksum: %lu", fullpath, crc_total);
- return (rval);
}
static void
@@ -178,8 +177,10 @@
if (qflag && stat(path, &statbuf) == 0)
p->flags |= F_VISIT;
- else
+ else {
(void)printf("%s missing", path);
+ FIXED;
+ }
}
if (p->type != F_DIR && p->type != F_LINK) {
putchar('\n');
@@ -197,14 +198,17 @@
else if (!(p->flags & (F_GID | F_GNAME)))
(void)printf(" (%s not created: group not specified)", type);
else if (p->type == F_LINK) {
- if (symlink(p->slink, path))
+ if (symlink(p->slink, path)) {
(void)printf(" (symlink not created: %s)\n",
strerror(errno));
- else
+ FAILED;
+ } else
(void)printf(" (created)\n");
- if (lchown(path, p->st_uid, p->st_gid))
+ if (lchown(path, p->st_uid, p->st_gid)) {
(void)printf("%s: user/group not modified: %s\n",
path, strerror(errno));
+ FAILED;
+ }
continue;
} else if (!(p->flags & F_MODE))
(void)printf(" (directory not created: mode not specified)");
@@ -215,6 +219,8 @@
create = 1;
(void)printf(" (created)");
}
+ if (!create)
+ FAILED;
}
if (!(p->flags & F_VISIT))
(void)putchar('\n');
@@ -231,14 +237,19 @@
path, strerror(errno));
(void)printf("%s: warning: file mode %snot set\n", path,
(p->flags & F_FLAGS) ? "and file flags " : "");
+ FAILED;
continue;
}
- if (chmod(path, p->st_mode))
+ if (chmod(path, p->st_mode)) {
(void)printf("%s: permissions not set: %s\n",
path, strerror(errno));
+ FAILED;
+ }
if ((p->flags & F_FLAGS) && p->st_flags &&
- chflags(path, p->st_flags))
+ chflags(path, p->st_flags)) {
(void)printf("%s: file flags not set: %s\n",
path, strerror(errno));
+ FAILED;
+ }
}
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020310015221.J11778-200000>
