summaryrefslogtreecommitdiffstats
path: root/qacp.c
diff options
context:
space:
mode:
authorNathan Straz <nstraz@redhat.com>2013-10-02 11:22:22 -0400
committerNathan Straz <nstraz@redhat.com>2013-10-02 14:11:34 -0400
commitb1c21ed4dc79b4250d604570c7516e267a521792 (patch)
treee85a3ad73ac0670d1213c11ed15db9c2c883540f /qacp.c
parent6ce608b05e3f811b25122ce4048ab0f07f3a30ed (diff)
downloadqarsh-b1c21ed4dc79b4250d604570c7516e267a521792.tar.gz
qarsh-b1c21ed4dc79b4250d604570c7516e267a521792.tar.xz
qarsh-b1c21ed4dc79b4250d604570c7516e267a521792.zip
Handle errors better in qacp
Pass errors up from the transfer functions so we can keep track of errors and continue trying to transfer all files. Make output more consistent and all on stderr.
Diffstat (limited to 'qacp.c')
-rw-r--r--qacp.c107
1 files changed, 65 insertions, 42 deletions
diff --git a/qacp.c b/qacp.c
index cf76652..b2f4535 100644
--- a/qacp.c
+++ b/qacp.c
@@ -134,7 +134,7 @@ free_rstat(struct qp_rstat_pkt *p)
free(p);
}
-void
+int
qacp_sendonefile(const char *host, const char *srcfile, const char *destfile)
{
struct qa_packet *qp;
@@ -149,22 +149,28 @@ qacp_sendonefile(const char *host, const char *srcfile, const char *destfile)
int dallow;
int complete;
+ if (!quiet) {
+ fprintf(stderr, "%s -> ", srcfile);
+ }
if ((fd = open(srcfile, O_RDONLY)) <0) {
fprintf(stderr, "Could not open %s: %s\n", srcfile, strerror(errno));
- close(qacp_fd);
- exit(errno);
+ return -1;
}
if (fstat(fd, &sb) < 0) {
fprintf(stderr, "Could not stat %s: %s\n", srcfile, strerror(errno));
- close(qacp_fd);
- exit(errno);
+ return -1;
}
if (S_ISDIR(sb.st_mode)) {
fprintf(stderr, "Skipping directory %s, recursive not supported, use rsync.\n", srcfile);
- return;
+ return -1;
+ }
+
+ if (!S_ISREG(sb.st_mode)) {
+ fprintf(stderr, "Skipping %s, not a regular file.\n", srcfile);
+ return -1;
}
/* Packet types are qarshd-centric, so if we want to send a file to the
@@ -210,7 +216,7 @@ qacp_sendonefile(const char *host, const char *srcfile, const char *destfile)
} else if (qp->qp_returncode.qp_rc == -1) {
fprintf(stderr, "Transfer failed: %s\n",
qp->qp_returncode.qp_strerror);
- exit(125);
+ return -1;
}
} else {
fprintf(stderr, "Received unexpected packet\n");
@@ -241,15 +247,15 @@ qacp_sendonefile(const char *host, const char *srcfile, const char *destfile)
}
close(fd);
- if (!quiet) {
- printf("%-30.30s -> %s:%s\n", srcfile, host, destfile);
+ if (!quiet && complete) {
+ fprintf(stderr, "%s:%s\n", host, destfile);
}
- return;
+ return 0;
}
-void
+int
qacp_recvonefile(const char *host, const char *srcfile, const char *destfile)
{
struct qa_packet *qp;
@@ -261,17 +267,21 @@ qacp_recvonefile(const char *host, const char *srcfile, const char *destfile)
fd_set rfds;
int nfd;
struct timeval timeout;
+ int fail = 0;
+
+ if (!quiet) {
+ fprintf(stderr, "%s:%s -> ", host, srcfile);
+ }
rstatp = qacp_rstat(srcfile, &rstaterrno);
if (!rstatp) {
fprintf(stderr, "%s: %s\n", srcfile, strerror(rstaterrno));
- return;
+ return 1;
}
if ((outfd = open(destfile, O_TRUNC|O_CREAT|O_WRONLY)) < 0) {
fprintf(stderr, "Could not open %s: %s\n", destfile, strerror(errno));
- close(qacp_fd);
- exit(errno);
+ return 1;
}
fchmod(outfd, rstatp->qp_st_mode);
@@ -301,6 +311,8 @@ qacp_recvonefile(const char *host, const char *srcfile, const char *destfile)
continue;
} else {
fprintf(stderr, "select errno %d, %s\n", errno, strerror(errno));
+ fail = 1;
+ break;
}
} else if (nfd > 0) {
if (nfd && FD_ISSET(qacp_fd, &rfds)) {
@@ -326,20 +338,27 @@ qacp_recvonefile(const char *host, const char *srcfile, const char *destfile)
nwrote += ret;
} while (nwrote < qp->qp_data.qp_count);
- rp = make_qp_data_allow(0, nwrote);
- send_packet(qacp_fd, rp);
- qpfree(rp);
+ if (nwrote == qp->qp_data.qp_count) {
+ rp = make_qp_data_allow(0, nwrote);
+ send_packet(qacp_fd, rp);
+ qpfree(rp);
+ } else {
+ fail = 1;
+ break;
+ }
} else if (qp->qp_type == QP_RETURNCODE) {
if (qp->qp_returncode.qp_rc == 0) { /* success */
break;
} else if (qp->qp_returncode.qp_rc == -1) {
fprintf(stderr, "Transfer failed: %s\n",
qp->qp_returncode.qp_strerror);
- exit(125);
+ fail = 1;
+ break;
}
} else {
fprintf(stderr, "Received unexpected packet\n");
dump_qp(qp);
+ fail = 1;
break;
}
qpfree(qp);
@@ -348,11 +367,11 @@ qacp_recvonefile(const char *host, const char *srcfile, const char *destfile)
}
close(outfd);
- if (!quiet) {
- printf("%s:%s -> %30.30s\n", host, srcfile, destfile);
+ if (!quiet && !fail) {
+ fprintf(stderr, "%s\n", destfile);
}
- return;
+ return fail;
}
@@ -373,12 +392,7 @@ recvfiles(char **argv, int argc, int fileidx)
struct qp_rstat_pkt *rstatp;
struct stat sb;
int rstaterrno;
-
- if (strchr(argv[argc-1], ':') != NULL) {
- fprintf(stderr, "%s is not a valid local file string\n",
- argv[argc-1]);
- return -1;
- }
+ int eflag = 0;
destpath = strdup(argv[argc-1]);
@@ -467,6 +481,15 @@ recvfiles(char **argv, int argc, int fileidx)
ruser = pw->pw_name;
}
+
+ if (strchr(rmtpath, '*')
+ || strchr(rmtpath, '?')
+ || strchr(rmtpath, '[')) {
+ fprintf(stderr, "globs are not supported on remote paths\n");
+ eflag |= 1;
+ continue;
+ }
+
qacp_fd = connect_to_host(rhost, QARSHD_CONTROL_PORT, &qarsh_ss_family);
if (qacp_fd == -1) {
if (errno == 0) {
@@ -489,33 +512,30 @@ recvfiles(char **argv, int argc, int fileidx)
cp = malloc(strlen(destpath) + strlen(rbnp) + 2);
strcpy(cp, destpath);
- strcat(cp, "/");
+ if (cp[strlen(cp)-1] != '/') strcat(cp, "/");
strcat(cp, rbnp);
- qacp_recvonefile(rhost, rmtpath, cp);
+ eflag |= qacp_recvonefile(rhost, rmtpath, cp);
free(cp);
} else {
- qacp_recvonefile(rhost, rmtpath, destpath);
+ eflag |= qacp_recvonefile(rhost, rmtpath, destpath);
}
}
if (S_ISDIR(rstatp->qp_st_mode)) {
- fprintf(stderr, "%s: Not a regular file\n", argv[file]);
- free(destpath);
- free(rmtpath);
- free_rstat(rstatp);
- return -1;
+ fprintf(stderr, "%s:%s -> Not a regular file\n", rhost, rmtpath);
+ eflag |= 1;
}
free_rstat(rstatp);
} else {
- fprintf(stderr, "%s: %s\n", argv[file], strerror(rstaterrno));
- goto error_free_destpath;
+ fprintf(stderr, "%s:%s -> %s\n", rhost, rmtpath, strerror(rstaterrno));
+ eflag |= 1;
}
close(qacp_fd);
} /* for file */
free(destpath);
- return 0;
+ return eflag ? -1 : 0;
error_free_destpath:
free(destpath);
@@ -539,6 +559,7 @@ sendfiles(char **argv, int argc, int fileidx)
char *rdnp; /* remote path dirname */
struct qp_rstat_pkt *rstatp;
int rstaterrno;
+ int fail = 0;
if ((rmtpath = strchr(argv[argc-1], ':')) == NULL) {
@@ -598,7 +619,7 @@ sendfiles(char **argv, int argc, int fileidx)
if (S_ISDIR(rstatp->qp_st_mode)) {
destpath = malloc(strlen(rmtpath) + strlen(lbnp) + 2);
strcpy(destpath, rmtpath);
- strcat(destpath, "/");
+ if (destpath[strlen(destpath)-1] != '/') strcat(destpath, "/");
strcat(destpath, lbnp);
}
@@ -631,7 +652,9 @@ sendfiles(char **argv, int argc, int fileidx)
}
}
- qacp_sendonefile(rhost, argv[file], destpath);
+ if (qacp_sendonefile(rhost, argv[file], destpath) < 0) {
+ fail = 1;
+ }
free(destpath);
}
@@ -641,7 +664,7 @@ sendfiles(char **argv, int argc, int fileidx)
}
close(qacp_fd);
- return 0;
+ return fail ? -1 : 0;
}
@@ -660,7 +683,7 @@ main(int argc, char *argv[])
case 'h':
default:
usage();
- exit(1);
+ exit(2);
}
}