diff options
author | Dean Jansa <djansa@redhat.com> | 2005-09-02 15:48:09 +0000 |
---|---|---|
committer | Dean Jansa <djansa@redhat.com> | 2005-09-02 15:48:09 +0000 |
commit | 89f8670f4e60cfafbb153bef681b6ada593ea626 (patch) | |
tree | f80b84102fd5ce8ff4bb487567d8c1d1173fa7d1 | |
parent | 4cf615dd407191c966ac60c999a16e1ce94f55d6 (diff) | |
download | qarsh-89f8670f4e60cfafbb153bef681b6ada593ea626.tar.gz qarsh-89f8670f4e60cfafbb153bef681b6ada593ea626.tar.xz qarsh-89f8670f4e60cfafbb153bef681b6ada593ea626.zip |
Use rstat to help construct the remote pathname of the copied file.
-rw-r--r-- | qarsh/qacp.c | 96 |
1 files changed, 72 insertions, 24 deletions
diff --git a/qarsh/qacp.c b/qarsh/qacp.c index 495d613..aa3f22e 100644 --- a/qarsh/qacp.c +++ b/qarsh/qacp.c @@ -166,6 +166,38 @@ qacp_recvonefile(const char *host, const char *srcfile, const char *destfile) return; } + +struct qp_rstat_pkt * +qacp_rstat(const char *rmtpath, int *rstaterrno) +{ + struct qa_packet *qp; + struct qp_rstat_pkt *rstatp; + + qp = make_qp_rstat(rmtpath, NULL); + send_packet(qacp_fd, qp); + qpfree(qp); + + qp = recv_packet(qacp_fd); + if (qp) { + if (qp->qp_type == QP_RSTAT) { + rstatp = malloc(sizeof *rstatp); + rstatp->qp_path = strdup(qp->qp_rstat.qp_path); + rstatp->qp_st_mode = qp->qp_rstat.qp_st_mode; + rstatp->qp_st_uid = qp->qp_rstat.qp_st_uid; + rstatp->qp_st_gid = qp->qp_rstat.qp_st_gid; + rstatp->qp_st_size = qp->qp_rstat.qp_st_size; + *rstaterrno = 0; + } else if (qp->qp_type == QP_RETURNCODE) { + rstatp = NULL; + *rstaterrno = qp->qp_returncode.qp_errno; + } + + qpfree(qp); + } + + return rstatp; +} + int recvfiles(char **argv, int argc, short recursive, short quiet) { @@ -187,9 +219,10 @@ sendfiles(char **argv, int argc, short recursive, short quiet) char *destpath; char *tmpstr; char *lbnp; /* local file basename */ - char *ldnp; /* local file dirname */ - char *rbnp; /* remote file basename */ - char *rdnp; /* remote file dirname */ + char *rdnp; /* remote path dirname */ + struct qp_rstat_pkt *rstatp; + int rstaterrno; + if (strchr(argv[argc-1], ':') == NULL) { fprintf(stderr, "%s is not a valid remote host:file string\n", @@ -241,33 +274,47 @@ sendfiles(char **argv, int argc, short recursive, short quiet) cp++; rmtpath = strdup(cp); - tmpstr = strdup(rmtpath); - rdnp = strdup(dirname(tmpstr)); - free(tmpstr); - - tmpstr = strdup(rmtpath); - rbnp = strdup(basename(tmpstr)); - free(tmpstr); - + rstatp = qacp_rstat(rmtpath, &rstaterrno); for (file = optind; file < (argc - 1); file++) { tmpstr = strdup(argv[file]); lbnp = strdup(basename(tmpstr)); free(tmpstr); - tmpstr = strdup(argv[file]); - ldnp = strdup(dirname(tmpstr)); - free(tmpstr); - - if (strcmp(lbnp, rbnp)) { - /* Tack on our lbnp to rmtpath */ - destpath = malloc(strlen(rmtpath) + strlen(lbnp) + 2); - memset(destpath, 0, strlen(destpath)); - strcpy(destpath, rmtpath); - strcat(destpath, "/"); - strcat(destpath, lbnp); + 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); + 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); + } } else { - destpath = strdup(rmtpath); + /* rmtpath does not exist, check if the dirname does */ + tmpstr = strdup(rmtpath); + rdnp = strdup(dirname(tmpstr)); + free(tmpstr); + + rstatp = qacp_rstat(rdnp, &rstaterrno); + if (rstatp) { + /* 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); + } else { + fprintf(stderr, "%s:%s - %s\n", rhost, rmtpath, + strerror(rstaterrno)); + return -1; + } } if (!quiet) { @@ -275,7 +322,8 @@ sendfiles(char **argv, int argc, short recursive, short quiet) } qacp_sendonefile(rhost, argv[file], destpath); - + + free(lbnp); free(destpath); } |