diff options
author | Phillip Lougher <phillip@squashfs.org.uk> | 2014-07-31 04:16:13 +0100 |
---|---|---|
committer | Phillip Lougher <phillip@squashfs.org.uk> | 2014-07-31 04:16:13 +0100 |
commit | 5038b13adc0b5a6ab96b9cf64852ab6cc0b979a7 (patch) | |
tree | c5bab22dae64fc6b3a8e1874f52a79b6657baffb | |
parent | b792207c0eb7fa9eb318d0ab04e516a46c91e84c (diff) | |
download | squashfs-tools-5038b13adc0b5a6ab96b9cf64852ab6cc0b979a7.tar.gz |
action: implement readlink test operation
Dereference the symlink and evaluate the expression in the
context of the file pointed to by the symlink.
All attributes are updated to refer to the file that is pointed to.
Thus the inode attributes, pathname, name and depth all refer to
the dereferenced file, and not the symlink
Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
-rw-r--r-- | squashfs-tools/action.c | 44 | ||||
-rw-r--r-- | squashfs-tools/mksquashfs.c | 2 |
2 files changed, 43 insertions, 3 deletions
diff --git a/squashfs-tools/action.c b/squashfs-tools/action.c index 7c10b54..e9998dc 100644 --- a/squashfs-tools/action.c +++ b/squashfs-tools/action.c @@ -2438,7 +2438,7 @@ static int absolute_fn(struct atom *atom, struct action_data *action_data) } -static int parse_stat_arg(struct test_entry *test, struct atom *atom) +static int parse_expr_arg(struct test_entry *test, struct atom *atom) { /* Call parse_expr to parse argument, which should be an expression */ @@ -2498,6 +2498,45 @@ static int stat_fn(struct atom *atom, struct action_data *action_data) } +static int readlink_fn(struct atom *atom, struct action_data *action_data) +{ + struct dir_ent *dir_ent; + + /* Dereference the symlink and evaluate the expression in the + * context of the file pointed to by the symlink. + * All attributes are updated to refer to the file that is pointed to. + * Thus the inode attributes, pathname, name and depth all refer to + * the dereferenced file, and not the symlink. + * + * If the symlink cannot be dereferenced because it doesn't exist in + * the output filesystem, or due to some other failure to + * walk the pathname (see follow_path above), then FALSE is returned. + * + * If you wish to evaluate the inode attributes of symlinks which + * exist in the source filestem (but not in the output filesystem then + * use stat instead (see above). + * + * readlink operates on symlinks only */ + if (!file_type_match(action_data->buf->st_mode, ACTION_LNK)) + return 0; + + /* dereference the symlink, and get the directory entry it points to */ + dir_ent = follow_path(action_data->dir_ent->our_dir, + action_data->dir_ent->inode->symlink); + if(dir_ent == NULL) + return 0; + + action_data->name = dir_ent->name; + action_data->pathname = pathname(dir_ent); + action_data->subpath = subpathname(dir_ent); + action_data->buf = &dir_ent->inode->buf; + action_data->depth = dir_ent->our_dir->depth; + action_data->dir_ent = dir_ent; + + return eval_expr(atom->data, action_data); +} + + #ifdef SQUASHFS_TRACE static void dump_parse_tree(struct expr *expr) { @@ -2596,7 +2635,8 @@ static struct test_entry test_table[] = { { "exec", 1, exec_fn, NULL, 1}, { "exists", 0, exists_fn, NULL, 0}, { "absolute", 0, absolute_fn, NULL, 0}, - { "stat", 1, stat_fn, parse_stat_arg, 1}, + { "stat", 1, stat_fn, parse_expr_arg, 1}, + { "readlink", 1, readlink_fn, parse_expr_arg, 0}, { "", -1 } }; diff --git a/squashfs-tools/mksquashfs.c b/squashfs-tools/mksquashfs.c index a103939..ba3646c 100644 --- a/squashfs-tools/mksquashfs.c +++ b/squashfs-tools/mksquashfs.c @@ -5080,7 +5080,7 @@ void calculate_queue_sizes(int mem, int *readq, int *fragq, int *bwriteq, #define VERSION() \ - printf("mksquashfs version 4.3-git (2014/07/29)\n");\ + printf("mksquashfs version 4.3-git (2014/07/30)\n");\ printf("copyright (C) 2014 Phillip Lougher "\ "<phillip@squashfs.org.uk>\n\n"); \ printf("This program is free software; you can redistribute it and/or"\ |