From aa6862a4cf8948a6ea7deece72545897549ed7a3 Mon Sep 17 00:00:00 2001 From: Thomas Nikolajsen Date: Mon, 26 Sep 2011 21:20:27 +0200 Subject: [PATCH] hammer(8): fix snaprm argument parsing Parse arguments according to SYNOPSIS. snaprm didn't parse arguments fully: e.g. PFS symlink was deleted if given as only argument. DragonFly-bug: Submitted-by: fix based on patch from "sgaerner@gmx.net" --- sbin/hammer/cmd_snapshot.c | 49 +++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/sbin/hammer/cmd_snapshot.c b/sbin/hammer/cmd_snapshot.c index ef45e05f21..50c7321aa0 100644 --- a/sbin/hammer/cmd_snapshot.c +++ b/sbin/hammer/cmd_snapshot.c @@ -212,8 +212,15 @@ hammer_cmd_snaprm(char **av, int ac) intmax_t tid; int fsfd = -1; int i; + int delete; + enum snaprm_mode { none_m, path_m, tid_m } mode = none_m; char *dirpath; - char *ptr; + char *ptr, *ptr2; + + if (ac == 0) { + snapshot_usage(1); + /* not reached */ + } for (i = 0; i < ac; ++i) { if (lstat(av[i], &st) < 0) { @@ -223,10 +230,19 @@ hammer_cmd_snaprm(char **av, int ac) av[i]); /* not reached */ } + if (mode == path_m) { + snapshot_usage(1); + /* not reached */ + } + mode = tid_m; if (fsfd < 0) fsfd = open(".", O_RDONLY); snapshot_del(fsfd, tid); } else if (S_ISDIR(st.st_mode)) { + if (i != 0 || ac < 2) { + snapshot_usage(1); + /* not reached */ + } if (fsfd >= 0) close(fsfd); fsfd = open(av[i], O_RDONLY); @@ -235,6 +251,7 @@ hammer_cmd_snaprm(char **av, int ac) av[i]); /* not reached */ } + mode = tid_m; } else if (S_ISLNK(st.st_mode)) { dirpath = dirpart(av[i]); bzero(linkbuf, sizeof(linkbuf)); @@ -261,12 +278,32 @@ hammer_cmd_snaprm(char **av, int ac) /* not reached */ } - if ((ptr = strrchr(linkbuf, '@')) && - ptr > linkbuf && ptr[-1] == '@') { - tid = strtoull(ptr + 1, NULL, 16); - snapshot_del(fsfd, tid); + delete = 1; + if (i == 0 && ac > 1) { + mode = path_m; + if (lstat(av[1], &st) < 0) { + tid = strtoull(av[1], &ptr, 16); + if (*ptr == '\0') { + delete = 0; + mode = tid_m; + } + } + } else { + if (mode == tid_m) { + snapshot_usage(1); + /* not reached */ + } + mode = path_m; + } + if (delete && (ptr = strrchr(linkbuf, '@')) && + ptr > linkbuf && ptr[-1] == '@' && + ptr + 1 < linkbuf + sizeof(linkbuf) - 1) { + tid = strtoull(ptr + 1, &ptr2, 16); + if (*ptr2 == '\0') { + snapshot_del(fsfd, tid); + remove(av[i]); + } } - remove(av[i]); free(dirpath); } else { err(2, "hammer snaprm: not directory or snapshot " -- 2.41.0