From 8ca5b74eaf0a15248578d4eaf19762d57b44099e Mon Sep 17 00:00:00 2001 From: Nathan Straz Date: Wed, 2 Oct 2013 14:09:14 -0400 Subject: Prevent copying multiple files over one remote file Also drop the rstat of the parent directory, just let the remote side send us an error. --- qacp.c | 55 +++++++++++++++---------------------------------------- 1 file changed, 15 insertions(+), 40 deletions(-) diff --git a/qacp.c b/qacp.c index b2f4535..4e75a1e 100644 --- a/qacp.c +++ b/qacp.c @@ -554,12 +554,11 @@ sendfiles(char **argv, int argc, int fileidx) int file; char *rmtpath; char *destpath; - char *tmpstr; char *lbnp; /* local file basename */ - char *rdnp; /* remote path dirname */ struct qp_rstat_pkt *rstatp; int rstaterrno; int fail = 0; + int destisdir = 0; if ((rmtpath = strchr(argv[argc-1], ':')) == NULL) { @@ -608,48 +607,24 @@ sendfiles(char **argv, int argc, int fileidx) rstatp = qacp_rstat(rmtpath, &rstaterrno); + if (rstatp && S_ISDIR(rstatp->qp_st_mode)) { + destisdir = 1; + } else if ((argc - fileidx) > 2) { + fprintf(stderr, "Will not copy multiple files to the same remote file\n"); + close(qacp_fd); + return -1; + } + for (file = fileidx; file < (argc - 1); file++) { lbnp = basename(argv[file]); - if (rstatp) { - /* - * If rmtpath is a dir, then we tack on the - * local files basename. - */ - if (S_ISDIR(rstatp->qp_st_mode)) { - destpath = malloc(strlen(rmtpath) + strlen(lbnp) + 2); - strcpy(destpath, rmtpath); - if (destpath[strlen(destpath)-1] != '/') strcat(destpath, "/"); - strcat(destpath, lbnp); - } - - /* It rmtpath is a file, then we leave it as is */ - if (S_ISREG(rstatp->qp_st_mode)) { - destpath = strdup(rmtpath); - } + if (destisdir) { + destpath = malloc(strlen(rmtpath) + strlen(lbnp) + 2); + strcpy(destpath, rmtpath); + if (destpath[strlen(destpath)-1] != '/') strcat(destpath, "/"); + strcat(destpath, lbnp); } else { - struct qp_rstat_pkt *tmprstatp; - - /* rmtpath does not exist, check if the dirname does */ - tmpstr = strdup(rmtpath); - rdnp = strdup(dirname(tmpstr)); - free(tmpstr); - - tmprstatp = qacp_rstat(rdnp, &rstaterrno); - free(rdnp); - - if (tmprstatp) { - /* Ok, the dir exists, i.e. rmtpath is /tmp/foo - * and the first rstat was an error. Now we know - * that /tmp exists, we leave destpath == rmtpath. - */ - destpath = strdup(rmtpath); - free_rstat(tmprstatp); - } else { - fprintf(stderr, "%s:%s - %s\n", rhost, rmtpath, - strerror(rstaterrno)); - return -1; - } + destpath = strdup(rmtpath); } if (qacp_sendonefile(rhost, argv[file], destpath) < 0) { -- cgit