diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2023-01-31 11:21:30 +0100 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2023-01-31 13:51:49 +0100 |
commit | cdccc69c62579b0c13b35fad0728079652b8f3c9 (patch) | |
tree | 9fa54c710f73c5e08a9c8466e7a712eb63ee07ac /bin/sqfsdiff/src/node_compare.c | |
parent | 2182129c8f359c4fa1390eaba7a65b595ccd4182 (diff) |
Move library source into src sub-directory
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'bin/sqfsdiff/src/node_compare.c')
-rw-r--r-- | bin/sqfsdiff/src/node_compare.c | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/bin/sqfsdiff/src/node_compare.c b/bin/sqfsdiff/src/node_compare.c new file mode 100644 index 0000000..a0c99c7 --- /dev/null +++ b/bin/sqfsdiff/src/node_compare.c @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * node_compare.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#include "sqfsdiff.h" + +int node_compare(sqfsdiff_t *sd, sqfs_tree_node_t *a, sqfs_tree_node_t *b) +{ + sqfs_tree_node_t *ait, *bit; + bool promoted, demoted; + int ret, status = 0; + char *path; + + ret = sqfs_tree_node_get_path(a, &path); + if (ret != 0) { + sqfs_perror(NULL, "constructing absolute file path", ret); + return -1; + } + + if (a->inode->base.type != b->inode->base.type) { + promoted = demoted = false; + + switch (a->inode->base.type) { + case SQFS_INODE_DIR: + if (b->inode->base.type == SQFS_INODE_EXT_DIR) + promoted = true; + break; + case SQFS_INODE_FILE: + if (b->inode->base.type == SQFS_INODE_EXT_FILE) + promoted = true; + break; + case SQFS_INODE_SLINK: + if (b->inode->base.type == SQFS_INODE_EXT_SLINK) + promoted = true; + break; + case SQFS_INODE_BDEV: + if (b->inode->base.type == SQFS_INODE_EXT_BDEV) + promoted = true; + break; + case SQFS_INODE_CDEV: + if (b->inode->base.type == SQFS_INODE_EXT_CDEV) + promoted = true; + break; + case SQFS_INODE_FIFO: + if (b->inode->base.type == SQFS_INODE_EXT_FIFO) + promoted = true; + break; + case SQFS_INODE_SOCKET: + if (b->inode->base.type == SQFS_INODE_EXT_SOCKET) + promoted = true; + break; + case SQFS_INODE_EXT_DIR: + if (b->inode->base.type == SQFS_INODE_DIR) + demoted = true; + break; + case SQFS_INODE_EXT_FILE: + if (b->inode->base.type == SQFS_INODE_FILE) + demoted = true; + break; + case SQFS_INODE_EXT_SLINK: + if (b->inode->base.type == SQFS_INODE_SLINK) + demoted = true; + break; + case SQFS_INODE_EXT_BDEV: + if (b->inode->base.type == SQFS_INODE_BDEV) + demoted = true; + break; + case SQFS_INODE_EXT_CDEV: + if (b->inode->base.type == SQFS_INODE_CDEV) + demoted = true; + break; + case SQFS_INODE_EXT_FIFO: + if (b->inode->base.type == SQFS_INODE_FIFO) + demoted = true; + break; + case SQFS_INODE_EXT_SOCKET: + if (b->inode->base.type == SQFS_INODE_SOCKET) + demoted = true; + break; + default: + break; + } + + if (promoted) { + fprintf(stdout, "%s has an extended type\n", path); + status = 1; + } else if (demoted) { + fprintf(stdout, "%s has a basic type\n", path); + status = 1; + } else { + fprintf(stdout, "%s has a different type\n", path); + sqfs_free(path); + return 1; + } + } + + if (!(sd->compare_flags & COMPARE_NO_PERM)) { + if ((a->inode->base.mode & ~S_IFMT) != + (b->inode->base.mode & ~S_IFMT)) { + fprintf(stdout, "%s has different permissions\n", + path); + status = 1; + } + } + + if (!(sd->compare_flags & COMPARE_NO_OWNER)) { + if (a->uid != b->uid || a->gid != b->gid) { + fprintf(stdout, "%s has different ownership\n", path); + status = 1; + } + } + + if (sd->compare_flags & COMPARE_TIMESTAMP) { + if (a->inode->base.mod_time != b->inode->base.mod_time) { + fprintf(stdout, "%s has a different timestamp\n", path); + status = 1; + } + } + + if (sd->compare_flags & COMPARE_INODE_NUM) { + if (a->inode->base.inode_number != + b->inode->base.inode_number) { + fprintf(stdout, "%s has a different inode number\n", + path); + status = 1; + } + } + + switch (a->inode->base.type) { + case SQFS_INODE_SOCKET: + case SQFS_INODE_EXT_SOCKET: + case SQFS_INODE_FIFO: + case SQFS_INODE_EXT_FIFO: + break; + case SQFS_INODE_BDEV: + case SQFS_INODE_CDEV: + if (a->inode->data.dev.devno != b->inode->data.dev.devno) { + fprintf(stdout, "%s has different device number\n", + path); + status = 1; + } + break; + case SQFS_INODE_EXT_BDEV: + case SQFS_INODE_EXT_CDEV: + if (a->inode->data.dev_ext.devno != + b->inode->data.dev_ext.devno) { + fprintf(stdout, "%s has different device number\n", + path); + status = 1; + } + break; + case SQFS_INODE_SLINK: + case SQFS_INODE_EXT_SLINK: + if (strcmp((const char *)a->inode->extra, + (const char *)b->inode->extra)) { + fprintf(stdout, "%s has a different link target\n", + path); + } + break; + case SQFS_INODE_DIR: + case SQFS_INODE_EXT_DIR: + ret = compare_dir_entries(sd, a, b); + if (ret < 0) { + status = -1; + break; + } + if (ret > 0) + status = 1; + + sqfs_free(path); + path = NULL; + + ait = a->children; + bit = b->children; + + while (ait != NULL && bit != NULL) { + ret = node_compare(sd, ait, bit); + if (ret < 0) + return -1; + if (ret > 0) + status = 1; + + ait = ait->next; + bit = bit->next; + } + break; + case SQFS_INODE_FILE: + case SQFS_INODE_EXT_FILE: + ret = compare_files(sd, a->inode, b->inode, path); + if (ret < 0) { + status = -1; + } else if (ret > 0) { + fprintf(stdout, "regular file %s differs\n", path); + status = 1; + } + break; + default: + fprintf(stdout, "%s has unknown type, ignoring\n", path); + break; + } + + sqfs_free(path); + return status; +} |