306 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			306 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* xfer.c Copyright 1992-2000 by Michael Temari All Rights Reserved
 | |
|  *
 | |
|  * This file is part of ftp.
 | |
|  *
 | |
|  *
 | |
|  * 03/14/00 Initial Release	Michael Temari, <Michael@TemWare.Com>
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #include <sys/types.h>
 | |
| #include <sys/stat.h>
 | |
| #include <stdio.h>
 | |
| #include <unistd.h>
 | |
| #include <string.h>
 | |
| #include <stdlib.h>
 | |
| #include <fcntl.h>
 | |
| #include <errno.h>
 | |
| #include <time.h>
 | |
| #include <utime.h>
 | |
| #include <net/hton.h>
 | |
| 
 | |
| #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);
 | |
| }
 | 
