summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Jansa <djansa@redhat.com>2005-09-02 15:48:09 +0000
committerDean Jansa <djansa@redhat.com>2005-09-02 15:48:09 +0000
commit89f8670f4e60cfafbb153bef681b6ada593ea626 (patch)
treef80b84102fd5ce8ff4bb487567d8c1d1173fa7d1
parent4cf615dd407191c966ac60c999a16e1ce94f55d6 (diff)
downloadqarsh-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.c96
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);
}