X-Git-Url: https://git.saurik.com/apple/file_cmds.git/blobdiff_plain/4d0bb65183fe440451aacdcc675bede1ef4a4343..refs/heads/master:/mtree/verify.c diff --git a/mtree/verify.c b/mtree/verify.c index 4ad3202..4978098 100644 --- a/mtree/verify.c +++ b/mtree/verify.c @@ -45,29 +45,42 @@ __FBSDID("$FreeBSD: src/usr.sbin/mtree/verify.c,v 1.24 2005/08/11 15:43:55 brian #include #include #include +#include +#include "metrics.h" #include "mtree.h" #include "extern.h" static NODE *root; static char path[MAXPATHLEN]; -static void miss(NODE *, char *); +static int miss(NODE *, char *, size_t path_length); static int vwalk(void); int mtree_verifyspec(FILE *fi) { - int rval; + int rval, mval; + size_t path_length = 0; root = mtree_readspec(fi); rval = vwalk(); - miss(root, path); - return (rval); + mval = miss(root, path, path_length); + + if (rval != 0) { + RECORD_FAILURE(60, WARN_MISMATCH); + return rval; + } else { + if (mval != 0) { + RECORD_FAILURE(61, WARN_MISMATCH); + } + return mval; + } } static int vwalk(void) { + int error = 0; FTS *t; FTSENT *p; NODE *ep, *level; @@ -77,8 +90,11 @@ vwalk(void) argv[0] = dot; argv[1] = NULL; - if ((t = fts_open(argv, ftsoptions, NULL)) == NULL) - err(1, "line %d: fts_open", lineno); + if ((t = fts_open(argv, ftsoptions, NULL)) == NULL) { + error = errno; + RECORD_FAILURE(62, error); + errc(1, error, "line %d: fts_open", lineno); + } level = root; specdepth = rval = 0; while ((p = fts_read(t))) { @@ -91,6 +107,10 @@ vwalk(void) case FTS_SL: break; case FTS_DP: + if (level == NULL) { + RECORD_FAILURE(63, EINVAL); + errx(1 , "invalid root in vwalk"); + } if (specdepth > p->fts_level) { for (level = level->parent; level->prev; level = level->prev); @@ -115,8 +135,10 @@ vwalk(void) !strcmp(ep->name, p->fts_name)) { ep->flags |= F_VISIT; if ((ep->flags & F_NOCHANGE) == 0 && - compare(ep->name, ep, p)) + compare(ep->name, ep, p)) { + RECORD_FAILURE(64, WARN_MISMATCH); rval = MISMATCHEXIT; + } if (ep->flags & F_IGN) (void)fts_set(t, p, FTS_SKIP); else if (ep->child && ep->type == F_DIR && @@ -132,45 +154,92 @@ vwalk(void) extra: if (!eflag) { (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)); - } else - (void)printf(", removed"); + /* rflag implies: delete stuff if "extra" is observed" */ + if (mflag) { + /* -mflag is used for sealing & verification -- use removefile for recursive behavior */ + removefile_state_t rmstate; + rmstate = removefile_state_alloc(); + if (removefile(p->fts_accpath, rmstate, (REMOVEFILE_RECURSIVE))) { + error = errno; + RECORD_FAILURE(65, error); + errx (1, "\n error deleting item (or descendant) at path %s (%s)", RP(p), strerror(error)); + } + else { + /* removefile success */ + (void) printf(", removed"); + } + removefile_state_free(rmstate); + + } + else { + /* legacy: use rmdir/unlink if "-m" not specified */ + int syserr = 0; + + if (S_ISDIR(p->fts_statp->st_mode)){ + syserr = rmdir(p->fts_accpath); + } + else { + syserr = unlink(p->fts_accpath); + } + + /* log failures */ + if (syserr) { + error = errno; + RECORD_FAILURE(66, error); + (void) printf(", not removed :%s", strerror(error)); + } + } + } else if (mflag) { + RECORD_FAILURE(68956, WARN_MISMATCH); + errx(1, "cannot generate the XML dictionary"); } (void)putchar('\n'); } (void)fts_set(t, p, FTS_SKIP); } (void)fts_close(t); - if (sflag) + if (sflag) { + RECORD_FAILURE(67, WARN_CHECKSUM); warnx("%s checksum: %lu", fullpath, (unsigned long)crc_total); + } return (rval); } -static void -miss(NODE *p, char *tail) +static int +miss(NODE *p, char *tail, size_t path_length) { int create; char *tp; const char *type, *what; int serr; + int rval = 0; + int rrval = 0; + size_t file_name_length = 0; for (; p; p = p->next) { if (p->type != F_DIR && (dflag || p->flags & F_VISIT)) continue; + file_name_length = strnlen(p->name, MAXPATHLEN); + path_length += file_name_length; + if (path_length >= MAXPATHLEN) { + RECORD_FAILURE(61971, ENAMETOOLONG); + continue; + } (void)strcpy(tail, p->name); if (!(p->flags & F_VISIT)) { /* Don't print missing message if file exists as a symbolic link and the -q flag is set. */ struct stat statbuf; - if (qflag && stat(path, &statbuf) == 0) + if (qflag && stat(path, &statbuf) == 0) { p->flags |= F_VISIT; - else + } else { (void)printf("%s missing", path); + RECORD_FAILURE(68, WARN_MISMATCH); + rval = MISMATCHEXIT; + } } if (p->type != F_DIR && p->type != F_LINK) { putchar('\n'); @@ -183,16 +252,19 @@ miss(NODE *p, char *tail) else type = "directory"; if (!(p->flags & F_VISIT) && uflag) { - if (!(p->flags & (F_UID | F_UNAME))) + if (!(p->flags & (F_UID | F_UNAME))) { (void)printf(" (%s not created: user not specified)", type); - else if (!(p->flags & (F_GID | F_GNAME))) + } 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)) + } else if (p->type == F_LINK) { + if (symlink(p->slink, path)) { + serr = errno; + RECORD_FAILURE(69, serr); (void)printf(" (symlink not created: %s)\n", - strerror(errno)); - else + strerror(serr)); + } else { (void)printf(" (created)\n"); + } if (lchown(path, p->st_uid, p->st_gid) == -1) { serr = errno; if (p->st_uid == (uid_t)-1) @@ -204,16 +276,20 @@ miss(NODE *p, char *tail) what = "user"; errno = serr; } + serr = errno; + RECORD_FAILURE(70, serr); (void)printf("%s: %s not modified: %s" - "\n", path, what, strerror(errno)); + "\n", path, what, strerror(serr)); } continue; - } else if (!(p->flags & F_MODE)) + } else if (!(p->flags & F_MODE)) { (void)printf(" (directory not created: mode not specified)"); - else if (mkdir(path, S_IRWXU)) + } else if (mkdir(path, S_IRWXU)) { + serr = errno; + RECORD_FAILURE(71, serr); (void)printf(" (directory not created: %s)", - strerror(errno)); - else { + strerror(serr)); + } else { create = 1; (void)printf(" (created)"); } @@ -223,7 +299,13 @@ miss(NODE *p, char *tail) for (tp = tail; *tp; ++tp); *tp = '/'; - miss(p->child, tp + 1); + ++path_length; + rrval = miss(p->child, tp + 1, path_length); + if (rrval != 0) { + RECORD_FAILURE(72, WARN_MISMATCH); + rval = rrval; + } + path_length -= (file_name_length + 1); *tp = '\0'; if (!create) @@ -238,15 +320,24 @@ miss(NODE *p, char *tail) what = "user"; errno = serr; } + serr = errno; + RECORD_FAILURE(73, serr); (void)printf("%s: %s not modified: %s\n", - path, what, strerror(errno)); + path, what, strerror(serr)); } - if (chmod(path, p->st_mode)) + if (chmod(path, p->st_mode)) { + serr = errno; + RECORD_FAILURE(74, serr); (void)printf("%s: permissions not set: %s\n", - path, strerror(errno)); + path, strerror(serr)); + } if ((p->flags & F_FLAGS) && p->st_flags && - chflags(path, (u_int)p->st_flags)) + chflags(path, (u_int)p->st_flags)) { + serr = errno; + RECORD_FAILURE(75, serr); (void)printf("%s: file flags not set: %s\n", - path, strerror(errno)); + path, strerror(serr)); + } } + return rval; }