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);
 | 
						|
}
 |