/* xfer.c Copyright 1992-2000 by Michael Temari All Rights Reserved * * This file is part of ftp. * * * 03/14/00 Initial Release Michael Temari, * */ #include #include #include #include #include #include #include #include #include #include #include #include "ftp.h" #include "xfer.h" _PROTOTYPE(static int asciisend, (int fd, int fdout)); _PROTOTYPE(static int binarysend, (int fd, int fdout)); _PROTOTYPE(static int asciirecv, (int fd, int fdin)); _PROTOTYPE(static int binaryrecv, (int fd, int fdin)); #if (__WORD_SIZE == 4) static char buffer[8192]; static char bufout[8192]; #else static char buffer[2048]; static char bufout[2048]; #endif static int asciisend(fd, fdout) int fd; int fdout; { int s, len; char c; char *p; char *op, *ope; unsigned long total=0L; char block[3]; if(atty) { printf("Sent "); fflush(stdout); } op = bufout; ope = bufout + sizeof(bufout) - 3; while((s = read(fd, buffer, sizeof(buffer))) > 0) { total += (long)s; p = buffer; while(s-- > 0) { c = *p++; if(c == '\n') { *op++ = '\r'; total++; } *op++ = c; if(op >= ope) { if(mode == MODE_B) { block[0] = '\0'; *(u16_t *)&block[1] = htons(op - bufout); write(fdout, block, sizeof(block)); } write(fdout, bufout, op - bufout); op = bufout; } } if(atty) { printf("%8lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total); fflush(stdout); } } if(op > bufout) { if(mode == MODE_B) { block[0] = MODE_B_EOF; *(u16_t *)&block[1] = htons(op - bufout); write(fdout, block, sizeof(block)); } write(fdout, bufout, op - bufout); } else if(mode == MODE_B) { block[0] = MODE_B_EOF; *(u16_t *)&block[1] = htons(0); write(fdout, block, sizeof(block)); s = 0; } if(atty) { printf("\n"); fflush(stdout); } return(s); } static int binarysend(fd, fdout) int fd; int fdout; { int s; unsigned long total=0L; char block[3]; if(atty) { printf("Sent "); fflush(stdout); } while((s = read(fd, buffer, sizeof(buffer))) > 0) { if(mode == MODE_B) { block[0] = MODE_B_EOF; *(u16_t *)&block[1] = htons(s); write(fdout, block, sizeof(block)); } write(fdout, buffer, s); total += (long)s; if(atty) { printf("%8lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total); fflush(stdout); } } if(mode == MODE_B) { block[0] = MODE_B_EOF; *(u16_t *)&block[1] = htons(0); write(fdout, block, sizeof(block)); s = 0; } if(atty) { printf("\n"); fflush(stdout); } return(s); } int sendfile(fd, fdout) int fd; int fdout; { int s; switch(type) { case TYPE_A: s = asciisend(fd, fdout); break; default: s = binarysend(fd, fdout); } if(s < 0) return(-1); else return(0); } static int asciirecv(fd, fdin) int fd; int fdin; { int s, len; int gotcr; char c; char *p; char *op, *ope; unsigned long total=0L; char block[3]; unsigned short cnt; if(isatty && fd > 2) { printf("Received "); fflush(stdout); } gotcr = 0; op = bufout; ope = bufout + sizeof(bufout) - 3; cnt = 0; while(1) { if(mode != MODE_B) cnt = sizeof(buffer); else if(cnt == 0) { s = read(fdin, block, sizeof(block)); cnt = ntohs(*(u16_t *)&block[1]); s = 0; if(cnt == 0 && block[0] & MODE_B_EOF) break; } s = read(fdin, buffer, cnt > sizeof(buffer) ? sizeof(buffer) : cnt); if(s <= 0) break; cnt -= s; total += (long)s; p = buffer; while(s-- > 0) { c = *p++; if(gotcr) { gotcr = 0; if(c != '\n') *op++ = '\r'; } if(c == '\r') gotcr = 1; else *op++ = c; if(op >= ope) { write(fd, bufout, op - bufout); op = bufout; } } if(atty && fd > 2) { printf("%8lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total); fflush(stdout); } if(cnt == 0 && mode == MODE_B && block[0] & MODE_B_EOF) { s = 0; break; } } if(gotcr) *op++ = '\r'; if(op > bufout) write(fd, bufout, op - bufout); if(atty && fd > 2) { printf("\n"); fflush(stdout); } if((mode == MODE_B && cnt != 0) || s != 0) return(-1); else return(0); } static binaryrecv(fd, fdin) int fd; int fdin; { int s; unsigned long total=0L; char block[3]; unsigned short cnt; if(atty && fd > 2) { printf("Received "); fflush(stdout); } cnt = 0; while(1) { if(mode != MODE_B) cnt = sizeof(buffer); else if(cnt == 0) { s = read(fdin, block, sizeof(block)); cnt = ntohs(*(u16_t *)&block[1]); s = 0; if(cnt == 0 && block[0] & MODE_B_EOF) break; } s = read(fdin, buffer, cnt > sizeof(buffer) ? sizeof(buffer) : cnt); if(s <= 0) break; cnt -= s; total += (long)s; write(fd, buffer, s); if(atty && fd > 2) { printf("%8lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total); fflush(stdout); } if(cnt == 0 && mode == MODE_B && block[0] & MODE_B_EOF) { s = 0; break; } } if(atty && fd > 2) { printf("\n"); fflush(stdout); } if((mode == MODE_B && cnt != 0) || s != 0) return(-1); else return(0); } int recvfile(fd, fdin) int fd; int fdin; { int s; switch(type) { case TYPE_A: s = asciirecv(fd, fdin); break; default: s = binaryrecv(fd, fdin); } if(s < 0) return(-1); else return(0); }