diff options
author | Tobias Stoeckmann <tobias@cvs.openbsd.org> | 2008-01-31 19:39:00 +0000 |
---|---|---|
committer | Tobias Stoeckmann <tobias@cvs.openbsd.org> | 2008-01-31 19:39:00 +0000 |
commit | 95c582e01e68abd6c0603d53e88d5f26c36d0146 (patch) | |
tree | 6bb874bb2601f7260ef8d303d6bc7bda7dd897ed | |
parent | ab57f145c57e0a720fcb9c14a5019650e2207a7b (diff) |
We have to carefully check if a checkout command is run with a valid
directory or file. When it comes to files, check if there is a file
available ending in ,v or if it is in Attic. Everything else in invalid.
OK joris@, xsa@
-rw-r--r-- | usr.bin/cvs/checkout.c | 67 |
1 files changed, 50 insertions, 17 deletions
diff --git a/usr.bin/cvs/checkout.c b/usr.bin/cvs/checkout.c index f0d8f1074fe..41b7d9a5edf 100644 --- a/usr.bin/cvs/checkout.c +++ b/usr.bin/cvs/checkout.c @@ -1,4 +1,4 @@ -/* $OpenBSD: checkout.c,v 1.112 2008/01/31 10:15:05 tobias Exp $ */ +/* $OpenBSD: checkout.c,v 1.113 2008/01/31 19:38:59 tobias Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * @@ -30,6 +30,7 @@ #include "remote.h" static void checkout_check_repository(int, char **); +static int checkout_classify(const char *, const char *); static void checkout_repository(const char *, const char *); extern int print_stdout; @@ -146,7 +147,6 @@ checkout_check_repository(int argc, char **argv) { int i; char repo[MAXPATHLEN]; - struct stat st; struct cvs_recursion cr; build_dirs = print_stdout ? 0 : 1; @@ -199,31 +199,64 @@ checkout_check_repository(int argc, char **argv) (void)xsnprintf(repo, sizeof(repo), "%s/%s", current_cvsroot->cr_dir, argv[i]); - if (stat(repo, &st) == -1) { - /* check if a single file was requested */ - strlcat(repo, RCS_FILE_EXT, MAXPATHLEN); - - if (stat(repo, &st) == -1) { - cvs_log(LP_ERR, - "cannot find module `%s' - ignored", - argv[i]); - continue; - } - + switch (checkout_classify(repo, argv[i])) { + case CVS_FILE: cr.fileproc = cvs_update_local; cr.flags = flags; if (build_dirs == 1) cvs_mkpath(dirname(argv[i]), cvs_specified_tag); cvs_file_run(1, &(argv[i]), &cr); + break; + case CVS_DIR: + if (build_dirs == 1) + cvs_mkpath(argv[i], cvs_specified_tag); + checkout_repository(repo, argv[i]); + break; + default: + break; + } + } +} + +static int +checkout_classify(const char *repo, const char *arg) +{ + char *d, *f, fpath[MAXPATHLEN]; + struct stat sb; + + if (stat(repo, &sb) == 0) { + if (!S_ISDIR(sb.st_mode)) { + cvs_log(LP_ERR, "ignoring %s: not a directory", arg); + return 0; + } + return CVS_DIR; + } + + d = dirname(repo); + f = basename(repo); - continue; + (void)xsnprintf(fpath, sizeof(fpath), "%s/%s%s", d, f, RCS_FILE_EXT); + if (stat(fpath, &sb) == 0) { + if (!S_ISREG(sb.st_mode)) { + cvs_log(LP_ERR, "ignoring %s: not a regular file", arg); + return 0; } + return CVS_FILE; + } - if (build_dirs == 1) - cvs_mkpath(argv[i], cvs_specified_tag); - checkout_repository(repo, argv[i]); + (void)xsnprintf(fpath, sizeof(fpath), "%s/%s/%s%s", + d, CVS_PATH_ATTIC, f, RCS_FILE_EXT); + if (stat(fpath, &sb) == 0) { + if (!S_ISREG(sb.st_mode)) { + cvs_log(LP_ERR, "ignoring %s: not a regular file", arg); + return 0; + } + return CVS_FILE; } + + cvs_log(LP_ERR, "cannot find module `%s' - ignored", arg); + return 0; } static void |