diff options
author | Nathan Straz <nstraz@redhat.com> | 2013-10-02 11:22:22 -0400 |
---|---|---|
committer | Nathan Straz <nstraz@redhat.com> | 2013-10-02 14:11:34 -0400 |
commit | b1c21ed4dc79b4250d604570c7516e267a521792 (patch) | |
tree | e85a3ad73ac0670d1213c11ed15db9c2c883540f | |
parent | 6ce608b05e3f811b25122ce4048ab0f07f3a30ed (diff) | |
download | qarsh-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.c | 107 | ||||
-rw-r--r-- | sockutil.c | 2 |
2 files changed, 65 insertions, 44 deletions
@@ -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); } } @@ -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; } |