summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--qacp.c107
-rw-r--r--sockutil.c2
2 files changed, 65 insertions, 44 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);
}
}
diff --git a/sockutil.c b/sockutil.c
index 87a718b..c180eb3 100644
--- a/sockutil.c
+++ b/sockutil.c
@@ -56,8 +56,6 @@ connect_to_host(char *hostname, int port, unsigned short *ss_family)
snprintf(portstr, NI_MAXSERV, "%d", port);
if ((err = getaddrinfo(hostname, portstr, &hints, &ail)) != 0) {
- lprintf(LOG_ERR, "Could not resolve hostname %s: %s\n",
- hostname, gai_strerror(err));
return -1;
}