home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 3
/
PDCD_3.iso
/
internet
/
tcpipsrc
/
FTP
/
c
/
ftp
next >
Wrap
Text File
|
1995-02-22
|
7KB
|
337 lines
/* Stuff common to both the FTP server and client */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "global.h"
#include "mbuf.h"
#include "netuser.h"
#include "timer.h"
#include "tcp.h"
#include "ftp.h"
#include "session.h"
#include "misc.h"
#include "alarm.h"
/* FTP Data channel Receive upcall handler */
void ftpdr(struct tcb *tcb, int16 cnt)
{
struct session *current;
register struct ftp *ftp;
struct mbuf *bp;
register char *s;
register char *t;
register int i;
char *line;
ftp = (struct ftp *)tcb->user;
if (ftp->state != RECEIVING_STATE)
{
close_tcp(tcb);
return;
}
for (i = 0; i < nsessions; i++)
{
if(sessions[i].type == FTP && sessions[i].cb.ftp == ftp)
{
current = sessions + i;
break;
}
}
/* This will likely also generate an ACK with window rotation */
if (recv_tcp(tcb, &bp, cnt) > 0)
{
/*
if ((line = s = malloc(len_mbuf(bp) + 1)) == NULL)
{
cwprintf(ftp->window, "Out of memory in FTP\r\n");
free_p(bp);
return;
}
while (bp != NULLBUF)
{
t = bp->data;
while (bp->cnt-- > 0)
{
if (ftp->type == ASCII_TYPE)
{
if (*t != '\r')
*s++ = *t;
}
else
{
*s++ = *t;
}
t++;
}
bp = free_mbuf(bp);
}
*s = '\0';
if (ftp->fp == stdout)
{
cwputs(ftp->window, line);
}
else
*/
if (ftp->type == IMAGE_TYPE && ftp->fp != stdout)
{
while (bp != NULLBUF)
{
fwrite(bp->data, 1, bp->cnt, ftp->fp);
bp = free_mbuf(bp);
}
}
else
{
if ((line = s = malloc(len_mbuf(bp) + 1)) == NULL)
{
cwprintf(ftp->window, "Out of memory in FTP\r\n");
free_p(bp);
return;
}
while (bp != NULLBUF)
{
t = bp->data;
while (bp->cnt-- > 0)
{
if (*t != '\r' || ftp->type==IMAGE_TYPE)
*s++ = *t;
t++;
}
bp = free_mbuf(bp);
}
*s = '\0';
if (ftp->fp == stdout)
cwputs(ftp->window, line);
else
fwrite(line, 1, s - line, ftp->fp);
free(line);
}
if (ftp->fp != stdout)
{
if (ftp->hash == 1)
{
int a = alarm_timedifference(ftp->start_time, alarm_timenow()) / 100 ;
long b = ftell(ftp->fp);
cwprintf(ftp->window, "ftp receive: %lu " , b ) ;
if ( ftp->expected_size > 0 )
cwprintf(ftp->window, "%.1f%% ", (b * 100.0) / ftp->expected_size ) ;
if (a > 0)
cwprintf(ftp->window, "(%lu cps)" , (b-ftp->restart)/a );
cwputchar(ftp->window, '\r');
}
else
{
while (ftp->hash && (ftell(ftp->fp) - ftp->last > ftp->hash))
{
ftp->last += ftp->hash;
cwputchar(ftp->window, '#');
}
}
}
}
}
/* FTP Data channel Transmit upcall handler */
void ftpdt(struct tcb *tcb, int16 cnt)
{
struct ftp *ftp;
struct mbuf *bp;
register char *cp;
register int c;
int eof_flag;
ftp = (struct ftp *)tcb->user;
if(ftp->state != SENDING_FILE_STATE && ftp->state != SENDING_DATA_STATE)
{
close_tcp(tcb);
return;
}
if((bp = alloc_mbuf(cnt)) == NULLBUF)
{
/* Hard to know what to do here */
return;
}
eof_flag = 0;
if (ftp->state == SENDING_FILE_STATE)
{
if(ftp->type == IMAGE_TYPE)
{
bp->cnt = fread(bp->data,1,cnt,ftp->fp);
if(bp->cnt != cnt)
eof_flag = 1;
if ( ftp->hash == 1 )
{
int a = alarm_timedifference(ftp->start_time, alarm_timenow()) / 100;
long b = ftell(ftp->fp) ;
cwprintf(ftp->window, "ftp send: %lu " , b);
if (ftp->expected_size > 0)
cwprintf(ftp->window, "%.1f%% ", b * 100.0 / ftp->expected_size);
if ( a > 0 )
cwprintf(ftp->window, "(%lu cps)" , b/a);
cwputchar(ftp->window, '\r');
}
else
{
while (ftp->hash && (ftell(ftp->fp) - ftp->last > ftp->hash))
{
ftp->last += ftp->hash;
cwputchar(ftp->window, '#');
}
}
}
else
{
cp = bp->data;
while(cnt > 1)
{
if((c = getc(ftp->fp)) == EOF)
{
eof_flag=1;
break;
}
if(c == '\n')
{
*cp++ = '\r';
bp->cnt++;
cnt--;
}
*cp++ = c;
bp->cnt++;
cnt--;
}
if ( ftp->hash == 1 )
{
int a = alarm_timedifference(ftp->start_time, alarm_timenow()) / 100;
long b = ftell(ftp->fp) ;
cwprintf(ftp->window, "ftp send: %lu " , b );
if (ftp->expected_size > 0)
cwprintf(ftp->window, "%.1f%% ", b * 100.0 / ftp->expected_size );
if ( a > 0 )
cwprintf(ftp->window, "(%lu cps)", b/a);
cwputchar(ftp->window, '\r');
}
else
{
while (ftp->hash && (ftell(ftp->fp) - ftp->last > ftp->hash))
{
ftp->last += ftp->hash;
cwputchar(ftp->window, '#');
}
}
}
if(bp->cnt != 0)
send_tcp(tcb,bp);
else
free_p(bp);
if(eof_flag)
{ /* EOF seen */
fclose(ftp->fp);
ftp->fp = NULLFILE;
close_tcp(tcb);
}
}
else
{ /* SENDING_DATA_STATE */
if (ftp->type == IMAGE_TYPE)
{
if ((bp->cnt = strlen(ftp->cp)) < cnt)
eof_flag = 1;
else
bp->cnt = cnt;
strncpy(bp->data, ftp->cp, bp->cnt);
bp->data[bp->cnt] = '\0';
ftp->cp += bp->cnt;
}
else
{
cp = bp->data;
while(cnt > 1)
{
if((c = *ftp->cp++) == '\0')
{
c = EOF;
eof_flag=1;
break;
}
if(c == '\n')
{
*cp++ = '\r';
bp->cnt++;
cnt--;
}
*cp++ = c;
bp->cnt++;
cnt--;
}
}
if(bp->cnt != 0)
send_tcp(tcb,bp);
else
free_p(bp);
if(eof_flag)
{ /* EOF seen */
free(ftp->p);
ftp->p = ftp->cp = NULLCHAR;
close_tcp(tcb);
}
}
}
/* Allocate an FTP control block */
struct ftp *ftp_create(unsigned int bufsize)
{
register struct ftp *ftp;
if((ftp = (struct ftp *)calloc(1,sizeof (struct ftp))) == NULLFTP)
return NULLFTP;
if(bufsize != 0 && (ftp->buf = malloc(bufsize)) == NULLCHAR)
{
ftp_delete(ftp);
return NULLFTP;
}
ftp->state = COMMAND_STATE;
ftp->type = ASCII_TYPE; /* Default transfer type */
ftp->batch = NULL;
ftp->mfp = NULL;
ftp->margv = NULL;
ftp->mtemp = NULL;
ftp->mpstate = FTPM_IDLE;
ftp->pathopts = PATH_OFF;
return ftp;
}
/* Free resources, delete control block */
void ftp_delete(register struct ftp *ftp)
{
int i;
extern void ftp_mpcleanup(struct ftp *ftp);
delpathent(ftp->pathopts);
ftp_mpcleanup(ftp);
if(ftp->batch != NULLFILE)
fclose(ftp->batch);
if(ftp->fp != NULLFILE && ftp->fp != stdout)
fclose(ftp->fp);
if(ftp->p != NULLCHAR)
free(ftp->p);
if(ftp->data != NULLTCB)
del_tcp(ftp->data);
if(ftp->username != NULLCHAR)
free(ftp->username);
for (i = 0; i < MAXPATH; i++)
if(ftp->path[i] != NULLCHAR)
free(ftp->path[i]);
if(ftp->buf != NULLCHAR)
free(ftp->buf);
if(ftp->cd != NULLCHAR)
free(ftp->cd);
if(ftp->session != NULLSESSION)
freesession(ftp->session);
free((char *)ftp);
}