minix/commands/ftp101/xfer.c
2006-06-19 14:55:09 +00:00

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