static int send_buf(int ofd, const void *iobuf, int len, off_t pos, int is_pipe) { if (is_pipe) return remote_write(ofd, iobuf, len, pos); else return local_write(ofd, iobuf, len, pos); }
static int send_buf(struct ploop_copy_handle *h, const void *iobuf, int len, off_t pos) { if (h->cancelled) return SYSEXIT_WRITE; if (h->is_remote) return remote_write(h->ofd, PCOPY_PKT_DATA, iobuf, len, pos); else return local_write(h->ofd, iobuf, len, pos); }
void portmap_session::handle_local_write(boost::shared_ptr<std::vector<char> > buffer, size_t bytes_transferred, const boost::system::error_code& error) { if (!error) { // 继续发送未发送完成的数据. if (bytes_transferred != buffer->size()) { local_write(&(*(buffer->begin() + bytes_transferred)), buffer->size() - bytes_transferred); } } else { close(); } }
void portmap_session::handle_remote_read(const boost::system::error_code& error, int bytes_transferred) { if (!error) { // 发送到local. local_write(m_remote_buffer.data(), bytes_transferred); // 继续接收remote的数据. m_remote_socket.async_read_some(boost::asio::buffer(m_remote_buffer), make_custom_alloc_handler(m_allocator, boost::bind(&portmap_session::handle_remote_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred))); } else { close(); } }
void recvrequest(const char *cmd, char *volatile local, char *remote, const char *lmode, int printnames) { FILE *volatile fout, *volatile din = 0; int (*volatile closefunc)(FILE *); void (*volatile oldintp)(int); void (*volatile oldintr)(int); volatile int is_retr, tcrflag, bare_lfs = 0; static unsigned bufsize; static char *buf; volatile long bytes = 0, hashbytes = HASHBYTES; register int c, d; struct timeval start, stop; struct stat st; #if 0 printf("%s(%d): recvrequest(cmd=%s,local=%s,remote=%s)\n", __FILE__, __LINE__, cmd, local, remote); #endif is_retr = strcmp(cmd, "RETR") == 0; if (is_retr && ftpverbose && printnames) { if (local && *local != '-') printf("local: %s ", local); if (remote) printf("remote: %s\n", remote); } #if 0 if (proxy && is_retr) { proxtrans(cmd, local, remote); return; } #endif closefunc = NULL; oldintr = NULL; oldintp = NULL; tcrflag = !crflag && is_retr; if (sigsetjmp(recvabort, 1)) { while (cpend) { (void) getreply(0); } if (data >= 0) { (void) close(data); data = -1; } if (oldintr) (void) signal(SIGINT, oldintr); code = -1; return; } oldintr = signal(SIGINT, abortrecv); #if 0 if (strcmp(local, "-") && *local != '|') { if (access(local, W_OK) < 0) { char *dir = rindex(local, '/'); if (errno != ENOENT && errno != EACCES) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); (void) signal(SIGINT, oldintr); code = -1; return; } if (dir != NULL) *dir = 0; d = access(dir ? local : ".", W_OK); if (dir != NULL) *dir = '/'; if (d < 0) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); (void) signal(SIGINT, oldintr); code = -1; return; } if (!runique && errno == EACCES && chmod(local, 0600) < 0) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); /* * Believe it or not, this was actually * repeated in the original source. */ (void) signal(SIGINT, oldintr); /*(void) signal(SIGINT, oldintr);*/ code = -1; return; } if (runique && errno == EACCES && (local = gunique(local)) == NULL) { (void) signal(SIGINT, oldintr); code = -1; return; } } else if (runique && (local = gunique(local)) == NULL) { (void) signal(SIGINT, oldintr); code = -1; return; } } #endif if (!is_retr) { if (curtype != TYPE_A) changetype(TYPE_A, 0); } else if (curtype != type) { changetype(type, 0); } if (initconn()) { (void) signal(SIGINT, oldintr); code = -1; return; } if (sigsetjmp(recvabort, 1)) goto abort; if (is_retr && restart_point && command("REST %ld", (long) restart_point) != CONTINUE) return; if (remote) { if (command("%s %s", cmd, remote) != PRELIM) { (void) signal(SIGINT, oldintr); return; } } else { if (command("%s", cmd) != PRELIM) { (void) signal(SIGINT, oldintr); return; } } din = dataconn("r"); if (din == NULL) goto abort; if (strcmp(local, "-") == 0) fout = stdout; else if (*local == '|') { oldintp = signal(SIGPIPE, SIG_IGN); fout = popen(local + 1, "w"); if (fout == NULL) { perror(local+1); goto abort; } closefunc = pclose; } else { extern int local_fclose(); fout = local_fopen(local, lmode); if (fout == NULL) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); goto abort; } closefunc = local_fclose; } if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0) st.st_blksize = BUFSIZ; if (st.st_blksize > bufsize) { if (buf) (void) free(buf); buf = malloc((unsigned)st.st_blksize); if (buf == NULL) { perror("malloc"); bufsize = 0; goto abort; } bufsize = st.st_blksize; } (void) gettimeofday(&start, (struct timezone *)0); switch (curtype) { case TYPE_I: case TYPE_L: if (restart_point && lseek(fileno(fout), (long) restart_point, L_SET) < 0) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); if (closefunc != NULL) (*closefunc)(fout); return; } errno = d = 0; while ((c = read(fileno(din), buf, bufsize)) > 0) { if ((d = local_write(fileno(fout), buf, c)) != c) break; bytes += c; if (hash && is_retr) { while (bytes >= hashbytes) { (void) putchar('#'); hashbytes += HASHBYTES; } (void) fflush(stdout); } if (tick && (bytes >= hashbytes) && is_retr) { (void) printf("\rBytes transferred: %ld", bytes); (void) fflush(stdout); while (bytes >= hashbytes) hashbytes += TICKBYTES; } } if (hash && bytes > 0) { if (bytes < HASHBYTES) (void) putchar('#'); (void) putchar('\n'); (void) fflush(stdout); } if (tick && is_retr) { (void) printf("\rBytes transferred: %ld\n", bytes); (void) fflush(stdout); } if (c < 0) { if (errno != EPIPE) perror("netin"); bytes = -1; } if (d < c) { if (d < 0) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); else fprintf(stderr, "%s: short write\n", local); } break; case TYPE_A: #if 0 /* ascii mode not supported for netflash */ if (restart_point) { register int i, n, ch; if (fseek(fout, 0L, L_SET) < 0) goto done; n = restart_point; for (i = 0; i++ < n;) { if ((ch = getc(fout)) == EOF) goto done; if (ch == '\n') i++; } if (fseek(fout, 0L, L_INCR) < 0) { done: fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); if (closefunc != NULL) (*closefunc)(fout); return; } } while ((c = getc(din)) != EOF) { if (c == '\n') bare_lfs++; while (c == '\r') { while (hash && (bytes >= hashbytes) && is_retr) { (void) putchar('#'); (void) fflush(stdout); hashbytes += HASHBYTES; } if (tick && (bytes >= hashbytes) && is_retr) { printf("\rBytes transferred: %ld", bytes); fflush(stdout); while (bytes >= hashbytes) hashbytes += TICKBYTES; } bytes++; if ((c = getc(din)) != '\n' || tcrflag) { if (ferror(fout)) goto break2; (void) putc('\r', fout); if (c == '\0') { bytes++; goto contin2; } if (c == EOF) goto contin2; } } (void) putc(c, fout); bytes++; contin2: ; } break2: if (hash && is_retr) { if (bytes < hashbytes) (void) putchar('#'); (void) putchar('\n'); (void) fflush(stdout); } if (tick && is_retr) { (void) printf("\rBytes transferred: %ld\n", bytes); (void) fflush(stdout); } if (bare_lfs) { printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs); printf("File may not have transferred correctly.\n"); } if (ferror(din)) { if (errno != EPIPE) perror("netin"); bytes = -1; } if (ferror(fout)) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); #else printf("Netflash does not support ASCII downloads!\n"); bytes = -1; #endif 0 /* ascii mode not supported for netflash */ break; } if (closefunc != NULL) (*closefunc)(fout); (void) signal(SIGINT, oldintr); if (oldintp) (void) signal(SIGPIPE, oldintp); (void) gettimeofday(&stop, (struct timezone *)0); (void) fclose(din); /* closes data as well, so discard it */ data = -1; (void) getreply(0); if (bytes > 0 && is_retr) ptransfer("received", bytes, &start, &stop); return; abort: /* abort using RFC959 recommended IP,SYNC sequence */ (void) gettimeofday(&stop, (struct timezone *)0); if (oldintp) (void) signal(SIGPIPE, oldintp); (void) signal(SIGINT, SIG_IGN); if (!cpend) { code = -1; (void) signal(SIGINT, oldintr); return; } abort_remote(din); code = -1; if (closefunc != NULL && fout != NULL) (*closefunc)(fout); if (din) { (void) fclose(din); } if (data >= 0) { /* if it just got closed with din, again won't hurt */ (void) close(data); data = -1; } if (bytes > 0) ptransfer("received", bytes, &start, &stop); (void) signal(SIGINT, oldintr); }
void sendrequest(const char *cmd, char *local, char *remote, int printnames) { struct stat st; struct timeval start, stop; register int c, d; FILE *volatile fin, *volatile dout = 0; int (*volatile closefunc)(FILE *); void (*volatile oldintr)(int); void (*volatile oldintp)(int); volatile long bytes = 0, hashbytes = HASHBYTES; char buf[BUFSIZ], *bufp; const char *volatile lmode; #if 1 printf("%s(%d): sendrequest(cmd=%s,local=%s,remote=%s)\n", __FILE__, __LINE__, cmd, local, remote); #endif if (ftpverbose && printnames) { if (local && *local != '-') printf("local: %s ", local); if (remote) printf("remote: %s\n", remote); } #if 0 if (proxy) { proxtrans(cmd, local, remote); return; } #endif if (curtype != type) changetype(type, 0); closefunc = NULL; oldintr = NULL; oldintp = NULL; lmode = "w"; if (sigsetjmp(sendabort, 1)) { while (cpend) { (void) getreply(0); } if (data >= 0) { (void) close(data); data = -1; } if (oldintr) (void) signal(SIGINT,oldintr); if (oldintp) (void) signal(SIGPIPE,oldintp); code = -1; return; } oldintr = signal(SIGINT, abortsend); if (strcmp(local, "-") == 0) fin = stdin; else if (*local == '|') { oldintp = signal(SIGPIPE,SIG_IGN); fin = popen(local + 1, "r"); if (fin == NULL) { perror(local + 1); (void) signal(SIGINT, oldintr); (void) signal(SIGPIPE, oldintp); code = -1; return; } closefunc = pclose; } else { fin = fopen(local, "r"); if (fin == NULL) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); (void) signal(SIGINT, oldintr); code = -1; return; } closefunc = fclose; if (fstat(fileno(fin), &st) < 0 || (st.st_mode&S_IFMT) != S_IFREG) { fprintf(stdout, "%s: not a plain file.\n", local); (void) signal(SIGINT, oldintr); fclose(fin); code = -1; return; } } if (initconn()) { (void) signal(SIGINT, oldintr); if (oldintp) (void) signal(SIGPIPE, oldintp); code = -1; if (closefunc != NULL) (*closefunc)(fin); return; } if (sigsetjmp(sendabort, 1)) goto abort; if (restart_point && (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) { if (fseek(fin, (long) restart_point, 0) < 0) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); restart_point = 0; if (closefunc != NULL) (*closefunc)(fin); return; } if (command("REST %ld", (long) restart_point) != CONTINUE) { restart_point = 0; if (closefunc != NULL) (*closefunc)(fin); return; } restart_point = 0; lmode = "r+w"; } if (remote) { if (command("%s %s", cmd, remote) != PRELIM) { (void) signal(SIGINT, oldintr); if (oldintp) (void) signal(SIGPIPE, oldintp); if (closefunc != NULL) (*closefunc)(fin); return; } } else if (command("%s", cmd) != PRELIM) { (void) signal(SIGINT, oldintr); if (oldintp) (void) signal(SIGPIPE, oldintp); if (closefunc != NULL) (*closefunc)(fin); return; } dout = dataconn(lmode); if (dout == NULL) goto abort; (void) gettimeofday(&start, (struct timezone *)0); oldintp = signal(SIGPIPE, SIG_IGN); switch (curtype) { case TYPE_I: case TYPE_L: errno = d = 0; while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) { bytes += c; for (bufp = buf; c > 0; c -= d, bufp += d) if ((d = local_write(fileno(dout), bufp, c)) <= 0) break; if (hash) { while (bytes >= hashbytes) { (void) putchar('#'); hashbytes += HASHBYTES; } (void) fflush(stdout); } if (tick && (bytes >= hashbytes)) { printf("\rBytes transferred: %ld", bytes); (void) fflush(stdout); while (bytes >= hashbytes) hashbytes += TICKBYTES; } } if (hash && (bytes > 0)) { if (bytes < HASHBYTES) (void) putchar('#'); (void) putchar('\n'); (void) fflush(stdout); } if (tick) { (void) printf("\rBytes transferred: %ld\n", bytes); (void) fflush(stdout); } if (c < 0) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); if (d < 0) { if (errno != EPIPE) perror("netout"); bytes = -1; } break; case TYPE_A: while ((c = getc(fin)) != EOF) { if (c == '\n') { while (hash && (bytes >= hashbytes)) { (void) putchar('#'); (void) fflush(stdout); hashbytes += HASHBYTES; } if (tick && (bytes >= hashbytes)) { (void) printf("\rBytes transferred: %ld", bytes); (void) fflush(stdout); while (bytes >= hashbytes) hashbytes += TICKBYTES; } if (ferror(dout)) break; (void) putc('\r', dout); bytes++; } (void) putc(c, dout); bytes++; /* if (c == '\r') { */ /* (void) putc('\0', dout); (* this violates rfc */ /* bytes++; */ /* } */ } if (hash) { if (bytes < hashbytes) (void) putchar('#'); (void) putchar('\n'); (void) fflush(stdout); } if (tick) { (void) printf("\rBytes transferred: %ld\n", bytes); (void) fflush(stdout); } if (ferror(fin)) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); if (ferror(dout)) { if (errno != EPIPE) perror("netout"); bytes = -1; } break; } (void) gettimeofday(&stop, (struct timezone *)0); if (closefunc != NULL) (*closefunc)(fin); (void) fclose(dout); /* closes data as well, so discard it */ data = -1; (void) getreply(0); (void) signal(SIGINT, oldintr); if (oldintp) (void) signal(SIGPIPE, oldintp); if (bytes > 0) ptransfer("sent", bytes, &start, &stop); return; abort: (void) gettimeofday(&stop, (struct timezone *)0); (void) signal(SIGINT, oldintr); if (oldintp) (void) signal(SIGPIPE, oldintp); if (!cpend) { code = -1; return; } if (dout) { (void) fclose(dout); } if (data >= 0) { /* if it just got closed with dout, again won't hurt */ (void) close(data); data = -1; } (void) getreply(0); code = -1; if (closefunc != NULL && fin != NULL) (*closefunc)(fin); if (bytes > 0) ptransfer("sent", bytes, &start, &stop); }