aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/apk_database.h2
-rw-r--r--src/audit.c46
-rw-r--r--src/database.c5
3 files changed, 27 insertions, 26 deletions
diff --git a/src/apk_database.h b/src/apk_database.h
index 7b1d20d..235030c 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -173,6 +173,8 @@ struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name);
struct apk_name *apk_db_query_name(struct apk_database *db, apk_blob_t name);
int apk_db_get_tag_id(struct apk_database *db, apk_blob_t tag);
+struct apk_db_dir *apk_db_dir_ref(struct apk_db_dir *dir);
+void apk_db_dir_unref(struct apk_database *db, struct apk_db_dir *dir, int allow_rmdir);
struct apk_db_dir *apk_db_dir_get(struct apk_database *db, apk_blob_t name);
struct apk_db_dir *apk_db_dir_query(struct apk_database *db, apk_blob_t name);
struct apk_db_file *apk_db_file_query(struct apk_database *db,
diff --git a/src/audit.c b/src/audit.c
index 3a7cd3c..a3382a3 100644
--- a/src/audit.c
+++ b/src/audit.c
@@ -62,6 +62,7 @@ static int audit_parse(void *ctx, struct apk_db_options *dbopts,
struct audit_tree_ctx {
struct audit_ctx *actx;
struct apk_database *db;
+ struct apk_db_dir *dir;
size_t pathlen;
char path[PATH_MAX];
};
@@ -144,17 +145,13 @@ static int audit_directory_tree_item(void *ctx, int dirfd, const char *name)
apk_blob_t bfull;
struct audit_ctx *actx = atctx->actx;
struct apk_database *db = atctx->db;
- struct apk_db_dir *dbd;
+ struct apk_db_dir *dir = atctx->dir, *child = NULL;
struct apk_file_info fi;
int reason = 0;
if (bdir.len + bent.len + 1 >= sizeof(atctx->path))
return -ENOMEM;
- dbd = apk_db_dir_get(db, bdir);
- if (dbd == NULL)
- return -ENOMEM;
-
if (apk_file_get_info(dirfd, name, APK_FI_NOFOLLOW, &fi) < 0)
return -EPERM;
@@ -163,26 +160,20 @@ static int audit_directory_tree_item(void *ctx, int dirfd, const char *name)
bfull = APK_BLOB_PTR_LEN(atctx->path, atctx->pathlen);
if (S_ISDIR(fi.mode)) {
- struct apk_db_dir *child;
int recurse = TRUE;
- child = apk_db_dir_query(db, bfull);
- if (child != NULL) {
- if (actx->mode == MODE_BACKUP) {
- if (!child->has_protected_children)
- recurse = FALSE;
- if (!child->protected)
- goto recurse_check;
- }
+ if (actx->mode == MODE_BACKUP) {
+ child = apk_db_dir_get(db, bfull);
+ if (!child->has_protected_children)
+ recurse = FALSE;
+ if (!child->protected)
+ goto recurse_check;
} else {
- if (actx->mode == MODE_BACKUP) {
- if (!dbd->has_protected_children)
- recurse = FALSE;
- if (!dbd->protected)
- goto recurse_check;
- } else {
+ child = apk_db_dir_query(db, bfull);
+ if (child == NULL)
recurse = FALSE;
- }
+ else
+ child = apk_db_dir_ref(child);
}
reason = audit_directory(actx, db, child, &fi);
@@ -200,16 +191,18 @@ recurse_check:
bfull.len++;
report_audit(actx, reason, bfull, NULL);
if (recurse) {
+ atctx->dir = child;
reason = apk_dir_foreach_file(
openat(dirfd, name, O_RDONLY|O_CLOEXEC),
audit_directory_tree_item, atctx);
+ atctx->dir = dir;
}
bfull.len--;
atctx->pathlen--;
} else {
struct apk_db_file *dbf;
- struct apk_protected_path_array *ppaths = dbd->protected_paths;
- int i, protected = dbd->protected, symlinks_only = dbd->symlinks_only;
+ struct apk_protected_path_array *ppaths = dir->protected_paths;
+ int i, protected = dir->protected, symlinks_only = dir->symlinks_only;
/* inherit file's protection mask */
for (i = 0; i < ppaths->num; i++) {
@@ -243,6 +236,9 @@ recurse_check:
}
done:
+ if (child)
+ apk_db_dir_unref(db, child, FALSE);
+
atctx->pathlen -= bent.len;
return reason < 0 ? reason : 0;
}
@@ -258,7 +254,9 @@ static int audit_main(void *ctx, struct apk_database *db, int argc, char **argv)
atctx.path[0] = 0;
if (argc == 0) {
+ atctx.dir = apk_db_dir_get(db, APK_BLOB_PTR_LEN(atctx.path, atctx.pathlen));
r = apk_dir_foreach_file(dup(db->root_fd), audit_directory_tree_item, &atctx);
+ apk_db_dir_unref(db, atctx.dir, FALSE);
} else {
for (i = 0; i < argc; i++) {
if (argv[i][0] != '/') {
@@ -272,9 +270,11 @@ static int audit_main(void *ctx, struct apk_database *db, int argc, char **argv)
if (atctx.path[atctx.pathlen-1] != '/')
atctx.path[atctx.pathlen++] = '/';
+ atctx.dir = apk_db_dir_get(db, APK_BLOB_PTR_LEN(atctx.path, atctx.pathlen));
r |= apk_dir_foreach_file(
openat(db->root_fd, argv[i], O_RDONLY|O_CLOEXEC),
audit_directory_tree_item, &atctx);
+ apk_db_dir_unref(db, atctx.dir, FALSE);
}
}
return r;
diff --git a/src/database.c b/src/database.c
index bcc707f..efff29f 100644
--- a/src/database.c
+++ b/src/database.c
@@ -240,8 +240,7 @@ static void apk_db_dir_mkdir(struct apk_database *db, struct apk_db_dir *dir)
;
}
-static void apk_db_dir_unref(struct apk_database *db, struct apk_db_dir *dir,
- int allow_rmdir)
+void apk_db_dir_unref(struct apk_database *db, struct apk_db_dir *dir, int allow_rmdir)
{
dir->refs--;
if (dir->refs > 0) {
@@ -274,7 +273,7 @@ static void apk_db_dir_unref(struct apk_database *db, struct apk_db_dir *dir,
apk_db_dir_unref(db, dir->parent, allow_rmdir);
}
-static struct apk_db_dir *apk_db_dir_ref(struct apk_db_dir *dir)
+struct apk_db_dir *apk_db_dir_ref(struct apk_db_dir *dir)
{
dir->refs++;
return dir;