305 lines
5.2 KiB
C
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);
|
|
}
|