home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 3
/
PDCD_3.iso
/
internet
/
tcpipsrc
/
FTP
/
c
/
ftpcli
< prev
next >
Wrap
Text File
|
1995-02-02
|
38KB
|
1,625 lines
/* FTP client (interactive user) code */
#define LINELEN 128 /* Length of command buffer */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdarg.h>
#include <ctype.h>
#include "alarm.h"
#include "global.h"
#include "mbuf.h"
#include "domain.h"
#include "netuser.h"
#include "icmp.h"
#include "timer.h"
#include "tcp.h"
#include "ftp.h"
#include "session.h"
#include "cmdparse.h"
#include "misc.h"
#include "Terminal.h"
#include "vterm.h"
#include "bbc.h"
#include "files.h"
#include "pathent.h"
#include "var.h"
extern varlist global_vars;
extern os_error *create_path(char *path, int size, int type);
extern char *fttoa(int t);
extern struct session *current;
struct session *current_ftp;
extern char nospace[];
extern char badhost[];
static char notsess[] = "Not an FTP session!\r\n";
static char cantwrite[] = "Can't write %s\r\n";
static char cantread[] = "Can't read %s\r\n";
static char nomemforop[] = "Insufficient memory for this operation\r\n";
static int donothing(int, char **);
static int doftpquit(int, char **);
static int dowinclose(int, char **);
static int dowinopen(int, char **);
static int doftpcd(int, char **);
static int domkdir(int, char **);
static int dormdir(int, char **);
static int doascii(int, char **);
static int dobinary(int, char **);
static int dotype(int, char **);
static int doget(int, char **);
static int doreget(int, char **);
static int domget(int, char **);
static int dobatch(int, char **);
static int dopath(int, char **);
static int doquote(int, char **);
static int doview(int, char **);
static int dohash(int, char **);
static int dolist(int, char **);
static int dols(int, char **);
static int doput(int, char **);
static void doreply(struct ftp *);
static void ftpsetup(struct ftp *, void (*)(), void (*)(), void (*)());
static void ftpccs(struct tcb *, char, char);
static void ftpcds(struct tcb *, char, char);
static int sndftpmsg(struct ftp *, char *, ...);
static void prompt(struct ftp *ftp);
static int batch_ftp(struct ftp *ftp);
static int mprocess(struct ftp *ftp);
void ftp_mpcleanup(struct ftp *ftp);
struct cmds ftpabort[] = {
"", donothing, 0, NULLCHAR, NULLCHAR,
"abort", doabort, 0, NULLCHAR, NULLCHAR,
"hash", dohash, 2, "hash lumpsize", NULLCHAR,
NULLCHAR, NULLFP, 0, "Only valid command is \"abort\"", NULLCHAR,
};
struct cmds ftpcmds[] = {
"", donothing, 0, NULLCHAR, NULLCHAR,
"ascii", doascii, 0, NULLCHAR, NULLCHAR,
"abort", doabort, 0, NULLCHAR, NULLCHAR,
"binary", dobinary, 0, NULLCHAR, NULLCHAR,
"cd", doftpcd, 2, "cd <directory>", NULLCHAR,
"dir", dolist, 0, NULLCHAR, NULLCHAR,
"list", dolist, 0, NULLCHAR, NULLCHAR,
"get", doget, 2, "get remotefile <localfile>", NULLCHAR,
"hash", dohash, 2, "hash lumpsize", NULLCHAR,
"image", dobinary, 0, NULLCHAR, NULLCHAR,
"ls", dols, 0, NULLCHAR, NULLCHAR,
"mget", domget, 2, "mget <filelist>", NULLCHAR,
"mkdir", domkdir, 2, "mkdir <directory>", NULLCHAR,
"nlst", dols, 0, NULLCHAR, NULLCHAR,
"path", dopath, 0, "path [<path process options>|off|default]", NULLCHAR,
"put", doput, 2, "put localfile <remotefile>", NULLCHAR,
"quote", doquote, 0, "quote <command>", NULLCHAR,
"reget", doreget, 2, "reget remotefile <localfile>", NULLCHAR,
"rmdir", dormdir, 2, "rmdir <directory>", NULLCHAR,
"source", dobatch, 0, "source <ftp command file>", NULLCHAR,
"type", dotype, 0, NULLCHAR, NULLCHAR,
"view", doview, 1, "view remotefile", NULLCHAR,
"winclose", dowinclose, 0, "winclose", NULLCHAR,
"winopen", dowinopen, 0, "winopen", NULLCHAR,
"quit", doftpquit, 0, "quit", NULLCHAR,
"bye", doftpquit, 0, "bye", NULLCHAR,
NULLCHAR, NULLFP, 0, NULLCHAR, NULLCHAR,
};
/* Handle top-level FTP command */
int doftp(int argc, char **argv)
{
int used_args;
struct session *s;
struct ftp *ftp;
struct tcb *tcb;
struct socket lsocket,fsocket;
lsocket.address = ip_addr;
lsocket.port = lport++;
if ((fsocket.address = resolve(argv[1])) == 0)
{
cwprintf(NULL, badhost,argv[1]);
return 1;
}
if (argc<3)
{
fsocket.port = FTP_PORT;
used_args = 2;
}
else
{
if (*argv[2]!='\\')
{
fsocket.port = atoi(argv[2]);
used_args = 3;
}
else
{
fsocket.port = FTP_PORT;
used_args = 2;
}
}
/* Allocate a session control block */
if ((s = newsession()) == NULLSESSION)
{
cwprintf(NULL, "Too many sessions\r\n");
return 1;
}
if ((s->name = malloc((unsigned)strlen(argv[1])+1)) != NULLCHAR)
strcpy(s->name,argv[1]);
s->type = FTP;
s->parse = (void(*)())ftpparse;
/* Allocate an FTP control block */
if ((ftp = ftp_create(LINELEN)) == NULLFTP)
{
s->type = FREE;
cwprintf(NULL, nospace);
return 1;
}
ftp->window = Window_Open(s, "FTP", term_SIXTEEN | term_CARET);
vterm_parse(ftp->window->vt, argc-used_args, &argv[used_args]);
current = s;
ftp->state = STARTUP_STATE;
s->cb.ftp = ftp; /* Downward link */
ftp->session = s; /* Upward link */
s->window = ftp->window;
ftp->session->echo = TRUE;
/* Now open the control connection */
tcb = open_tcp(&lsocket, &fsocket, TCP_ACTIVE, 0, (void(*)())ftpccr, NULLVFP, (void(*)())ftpccs, 0,( char *)ftp);
ftp->control = tcb;
go(s);
return 0;
}
/* Parse user FTP commands */
void ftpparse(struct session *active, char *line, int16 len)
{
struct mbuf *bp;
extern struct cmds cmds[];
if (active == NULL)
active = current;
current_ftp = active;
/* direct '*' prefixed commands to main command window */
if (*line=='*')
{
cmdparse(cmds, line+1, NULL);
prompt(active->cb.ftp);
return;
}
switch(active->cb.ftp->state)
{
case RECEIVING_STATE:
case SENDING_FILE_STATE:
/* The only command allowed in data transfer state is ABORT */
if (cmdparse(ftpabort, line, active->window) == -1)
{
cwprintf(active->window, "Transfer in progress; only ABORT is acceptable\r\n");
}
break;
case COMMAND_STATE:
/* Save it now because cmdparse modifies the original */
bp = qdata(line,len);
if (cmdparse(ftpcmds, line, active->window) == -1)
{
/* Send it direct */
if (bp != NULLBUF)
send_tcp(active->cb.ftp->control,bp);
else
cwprintf(active->window, nospace);
}
else
{
free_p(bp);
}
break;
case STARTUP_STATE: /* Startup up autologin */
cwprintf(active->window, "Not connected yet, ignoring %s\r\n",line);
break;
case USER_STATE: /* Got the user name */
line[len] = '\0';
sndftpmsg(active->cb.ftp,"USER %s",line);
break;
case PASS_STATE: /* Got the password */
cooked();
active->raw = FALSE;
vterm_setflags(active->window->vt,
/* Clear */ VTSW_CHAT|VTSW_LINE|VTSW_NEWLINE|VTSW_WRAP|VTSW_ECHO,
/* Set */ VTSW_LINE|VTSW_NEWLINE|VTSW_WRAP|VTSW_ECHO );
line[len] = '\0';
sndftpmsg(active->cb.ftp,"PASS %s",line);
break;
}
}
/* Handle null line to avoid trapping on first command in table */
static int donothing(int argc, char **argv)
{
argc = argc;
argv = argv;
return 0;
}
static int dowinclose(int argc, char **argv)
{
register struct ftp *ftp;
argc = argc;
argv = argv;
ftp = current_ftp->cb.ftp;
vterm_close(current_ftp->window->vt);
current_ftp->window->Flags.flags.closing = 1;
prompt(ftp);