diff options
-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; } |