405 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			405 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* ftp.c Copyright 1992-2000 by Michael Temari All Rights Reserved
 | 
						|
 *
 | 
						|
 * ftp          An ftp client program for use with TNET.
 | 
						|
 *
 | 
						|
 * Usage:       ftp [host]
 | 
						|
 *
 | 
						|
 * Version:     0.10    06/21/92 (pre-release not yet completed)
 | 
						|
 *              0.20    07/01/92
 | 
						|
 *              0.30    01/15/96 (Minix 1.7.1 initial release)
 | 
						|
 *              0.40    08/27/96
 | 
						|
 *              0.50    03/08/00
 | 
						|
 *              1.00    12/12/03 (added ver command)
 | 
						|
 *              1.01    02/07/05
 | 
						|
 *
 | 
						|
 * Author:      Michael Temari, <Michael@TemWare.Com>
 | 
						|
 */
 | 
						|
 | 
						|
#include <sys/types.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <ctype.h>
 | 
						|
#include <string.h>
 | 
						|
#include <unistd.h>
 | 
						|
 | 
						|
#include "ftp.h"
 | 
						|
#include "local.h"
 | 
						|
#include "file.h"
 | 
						|
#include "other.h"
 | 
						|
#include "net.h"
 | 
						|
 | 
						|
char *FtpVersion = "1.01 02/07/05";
 | 
						|
 | 
						|
int linkopen;
 | 
						|
int loggedin;
 | 
						|
int type;
 | 
						|
int format;
 | 
						|
int mode;
 | 
						|
int structure;
 | 
						|
int passive;
 | 
						|
int atty;
 | 
						|
 | 
						|
int cmdargc;
 | 
						|
char *cmdargv[NUMARGS];
 | 
						|
 | 
						|
int printreply = 1;
 | 
						|
char reply[1024];
 | 
						|
 | 
						|
_PROTOTYPE(static void makeargs, (char *buff));
 | 
						|
_PROTOTYPE(int DOver,  (void));
 | 
						|
_PROTOTYPE(int DOhelp, (void));
 | 
						|
_PROTOTYPE(static int getline, (char *line, int len));
 | 
						|
_PROTOTYPE(int main, (int argc, char *argv[]));
 | 
						|
 | 
						|
 | 
						|
static void makeargs(buff)
 | 
						|
char *buff;
 | 
						|
{
 | 
						|
int i;
 | 
						|
char *p;
 | 
						|
 | 
						|
   for(i = 0; i < NUMARGS; i++)
 | 
						|
	cmdargv[i] = (char *)0;
 | 
						|
 | 
						|
   p = buff + strlen(buff) - 1;
 | 
						|
   while(p >= buff)
 | 
						|
	if(*p == '\r' || *p == '\n' || isspace(*p))
 | 
						|
		*p-- = '\0';
 | 
						|
	else
 | 
						|
		break;
 | 
						|
 | 
						|
   p = buff;
 | 
						|
   cmdargc = 0;
 | 
						|
   while(cmdargc < NUMARGS) {
 | 
						|
	while(*p && isspace(*p))
 | 
						|
		p++;
 | 
						|
	if(*p == '\0')
 | 
						|
		break;
 | 
						|
	cmdargv[cmdargc++] = p;
 | 
						|
	while(*p && !isspace(*p)) {
 | 
						|
		if(cmdargc == 1)
 | 
						|
			*p = tolower(*p);
 | 
						|
		p++;
 | 
						|
	}
 | 
						|
	if(*p == '\0')
 | 
						|
		break;
 | 
						|
	*p = '\0';
 | 
						|
	p++;
 | 
						|
   }
 | 
						|
}
 | 
						|
 | 
						|
int readline(prompt, buff, len)
 | 
						|
char *prompt;
 | 
						|
char *buff;
 | 
						|
int len;
 | 
						|
{
 | 
						|
char *p;
 | 
						|
 | 
						|
   printf(prompt); fflush(stdout);
 | 
						|
 | 
						|
   if(fgets(buff, len, stdin) == (char *)NULL) {
 | 
						|
	printf("\nEnd of file on input!\n");
 | 
						|
	return(-1);
 | 
						|
   }
 | 
						|
 | 
						|
   p = buff + strlen(buff) - 1;
 | 
						|
   while(p >= buff)
 | 
						|
	if(*p == '\r' || *p == '\n' || isspace(*p))
 | 
						|
		*p-- = '\0';
 | 
						|
	else
 | 
						|
		break;
 | 
						|
 | 
						|
   if(!atty) {
 | 
						|
	printf("%s\n", buff);
 | 
						|
	fflush(stdout);
 | 
						|
   }
 | 
						|
 | 
						|
   return(0);
 | 
						|
}
 | 
						|
 | 
						|
static int getline(line, len)
 | 
						|
char *line;
 | 
						|
int len;
 | 
						|
{
 | 
						|
int s;
 | 
						|
int gotcr;
 | 
						|
 | 
						|
   /* leave room for at end for null */
 | 
						|
   len--;
 | 
						|
 | 
						|
   /* got to be able to put in at least 1 character */
 | 
						|
   if(len < 1)
 | 
						|
   	return(-1);
 | 
						|
 | 
						|
   gotcr = 0;
 | 
						|
   while(len-- > 0) {
 | 
						|
   	s = read(ftpcomm_fd, line, 1);
 | 
						|
   	if(s != 1)
 | 
						|
   		return(-1);
 | 
						|
   	if(*line == '\n')
 | 
						|
   		break;
 | 
						|
   	gotcr = (*line == '\r');
 | 
						|
   	line++;
 | 
						|
   }
 | 
						|
   if(gotcr)
 | 
						|
   	--line;
 | 
						|
 | 
						|
   *line = '\0';
 | 
						|
 | 
						|
   return(0);
 | 
						|
}
 | 
						|
 | 
						|
int DOgetreply()
 | 
						|
{
 | 
						|
int firsttime;
 | 
						|
int s;
 | 
						|
char code[4];
 | 
						|
 | 
						|
   do {
 | 
						|
	firsttime = 1;
 | 
						|
	do {
 | 
						|
		if((s = getline(reply, sizeof(reply))) < 0)
 | 
						|
			return(s);
 | 
						|
		if(printreply) {
 | 
						|
			printf("%s\n", reply);
 | 
						|
			fflush(stdout);
 | 
						|
		}
 | 
						|
		if(firsttime) {
 | 
						|
			firsttime = 0;
 | 
						|
			strncpy(code, reply, 3);
 | 
						|
			code[3] = '\0';
 | 
						|
		}
 | 
						|
	   } while(strncmp(reply, code, 3) || reply[3] == '-');
 | 
						|
	   s = atoi(code);
 | 
						|
   } while(s < 200 && s != 125 && s != 150);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOcmdcheck()
 | 
						|
{
 | 
						|
   if(!linkopen) {
 | 
						|
	printf("You must \"OPEN\" a connection first.\n");
 | 
						|
	return(1);
 | 
						|
   }
 | 
						|
 | 
						|
   if(!loggedin) {
 | 
						|
	printf("You must login first.\n");
 | 
						|
	return(1);
 | 
						|
   }
 | 
						|
 | 
						|
   return(0);
 | 
						|
}
 | 
						|
 | 
						|
int DOcommand(ftpcommand, ftparg)
 | 
						|
char *ftpcommand;
 | 
						|
char *ftparg;
 | 
						|
{
 | 
						|
int s;
 | 
						|
#if 1
 | 
						|
static char ss[64];
 | 
						|
   if(*ftparg)
 | 
						|
   	sprintf(ss, "%s %s\r\n", ftpcommand, ftparg);
 | 
						|
   else
 | 
						|
   	sprintf(ss, "%s\r\n", ftpcommand);
 | 
						|
 | 
						|
   s = write(ftpcomm_fd, ss, strlen(ss));
 | 
						|
   if(s != strlen(ss))
 | 
						|
   	return(-1);
 | 
						|
 | 
						|
#else
 | 
						|
   s = write(ftpcomm_fd, ftpcommand, strlen(ftpcommand));
 | 
						|
   if(s != strlen(ftpcommand))
 | 
						|
   	return(-1);
 | 
						|
 | 
						|
   if(*ftparg) {
 | 
						|
	s = write(ftpcomm_fd, " ", 1);
 | 
						|
	if(s != 1)
 | 
						|
		return(-1);
 | 
						|
 | 
						|
	s = write(ftpcomm_fd, ftparg, strlen(ftparg));
 | 
						|
	if(s != strlen(ftparg))
 | 
						|
		return(-1);
 | 
						|
   }
 | 
						|
 | 
						|
   s = write(ftpcomm_fd, "\r\n", 2);
 | 
						|
   if(s != 2)
 | 
						|
   	return(-1);
 | 
						|
#endif
 | 
						|
 | 
						|
   return(DOgetreply());
 | 
						|
}
 | 
						|
 | 
						|
int DOver()
 | 
						|
{
 | 
						|
   printf("FTP Version %s\n", FtpVersion);
 | 
						|
   return(0);
 | 
						|
}
 | 
						|
 | 
						|
int DOhelp()
 | 
						|
{
 | 
						|
char junk[10];
 | 
						|
 | 
						|
   printf("Command:      Description\n");
 | 
						|
   printf("!             Escape to a shell\n");
 | 
						|
   printf("append        Append a file to remote host\n");
 | 
						|
   printf("ascii         Set file transfer type to ascii\n");
 | 
						|
   printf("binary        Set file transfer type to binary\n");
 | 
						|
   printf("block         Set file transfer mode to block\n");
 | 
						|
   printf("bye           Close connection and exit\n");
 | 
						|
   printf("cd            Change directory on remote host\n");
 | 
						|
   printf("close         Close connection\n");
 | 
						|
   printf("clone         Clone a file\n");
 | 
						|
   printf("del           Remove file on remote host\n");
 | 
						|
   printf("dir           Display long form remote host directory listing\n");
 | 
						|
   printf("exit          Close connection and exit\n");
 | 
						|
   printf("get           Retrieve a file from remote host\n");
 | 
						|
   printf("help          Display this text\n");
 | 
						|
 | 
						|
   if(readline("Press ENTER to continue... ", junk, sizeof(junk)))
 | 
						|
   	return(-1);
 | 
						|
 | 
						|
   printf("lcd           Change directory on local host\n");
 | 
						|
   printf("ldir          Display long form local host directory listing\n");
 | 
						|
   printf("lls           Display local host directory listing\n");
 | 
						|
   printf("lmkdir        Create directory on local host\n");
 | 
						|
   printf("lpwd          Display current directory on local host\n");
 | 
						|
   printf("lrmdir        Remove directory on local host\n");
 | 
						|
   printf("ls            Display remote host directory listing\n");
 | 
						|
   printf("mget          Retrieve multiple files from remote host\n");
 | 
						|
   printf("mkdir         Create directory on remote host\n");
 | 
						|
   printf("mod           Get file modification time\n");
 | 
						|
   printf("mput          Send multiple files to remote host\n");
 | 
						|
   printf("noop          Send the ftp NOOP command\n");
 | 
						|
 | 
						|
   if(readline("Press ENTER to continue... ", junk, sizeof(junk)))
 | 
						|
   	return(-1);
 | 
						|
 | 
						|
   printf("open          Open connection to remote host\n");
 | 
						|
   printf("pass          Enter remote user password\n");
 | 
						|
   printf("passive       Toggle passive mode\n");
 | 
						|
   printf("put           Send a file to remote host\n");
 | 
						|
   printf("putu          Send a file to remote host(unique)\n");
 | 
						|
   printf("pwd           Display current directory on remote host\n");
 | 
						|
   printf("quit          Close connection and exit\n");
 | 
						|
   printf("quote         Send raw ftp command to remote host\n");
 | 
						|
   printf("reget         Restart a partial file retrieve from remote host\n");
 | 
						|
   printf("remotehelp    Display ftp commands implemented on remote host\n");
 | 
						|
   printf("reput         Restart a partial file send to remote host\n");
 | 
						|
   printf("rm            Remove file on remote host\n");
 | 
						|
   printf("rmdir         Remove directory on remote host\n");
 | 
						|
 | 
						|
   if(readline("Press ENTER to continue... ", junk, sizeof(junk)))
 | 
						|
   	return(-1);
 | 
						|
 | 
						|
   printf("site          Send a site specific command\n");
 | 
						|
   printf("size          Get file size information\n");
 | 
						|
   printf("status        Get connection/file status information\n");
 | 
						|
   printf("stream        Set file transfer mode to stream\n");
 | 
						|
   printf("system        Get remote system type information\n");
 | 
						|
   printf("user          Enter remote user information\n");
 | 
						|
   printf("ver           Display client version information\n");
 | 
						|
 | 
						|
   return(0);
 | 
						|
}
 | 
						|
 | 
						|
struct commands {
 | 
						|
	char *name;
 | 
						|
	_PROTOTYPE(int (*func), (void));
 | 
						|
};
 | 
						|
 | 
						|
static struct commands commands[] = {
 | 
						|
        "!",            DOlshell,
 | 
						|
	"append",	DOappe,
 | 
						|
	"ascii",        DOascii,
 | 
						|
	"binary",       DObinary,
 | 
						|
	"block",        DOblock,
 | 
						|
	"bye",          DOquit,
 | 
						|
	"cd",           DOcd,
 | 
						|
	"close",        DOclose,
 | 
						|
	"clone",        DOclone,
 | 
						|
	"del",          DOdelete,
 | 
						|
	"dir",          DOlist,
 | 
						|
	"exit",         DOquit,
 | 
						|
	"get",          DOretr,
 | 
						|
	"help",         DOhelp,
 | 
						|
	"lcd",          DOlcd,
 | 
						|
        "ldir",         DOllist,
 | 
						|
        "lls",          DOlnlst,
 | 
						|
	"lmkdir",       DOlmkdir,
 | 
						|
	"lpwd",         DOlpwd,
 | 
						|
	"lrmdir",       DOlrmdir,
 | 
						|
	"ls",           DOnlst,
 | 
						|
	"mget",         DOMretr,
 | 
						|
	"mkdir",        DOmkdir,
 | 
						|
	"mod",		DOmdtm,
 | 
						|
	"mput",         DOMstor,
 | 
						|
	"noop",         DOnoop,
 | 
						|
	"open",         DOopen,
 | 
						|
	"pass",		DOpass,
 | 
						|
	"passive",      DOpassive,
 | 
						|
	"put",          DOstor,
 | 
						|
	"putu",		DOstou,
 | 
						|
	"pwd",          DOpwd,
 | 
						|
	"quit",         DOquit,
 | 
						|
	"quote",        DOquote,
 | 
						|
	"reget",	DOrretr,
 | 
						|
	"remotehelp",   DOremotehelp,
 | 
						|
	"reput",	DOrstor,
 | 
						|
	"rm",           DOdelete,
 | 
						|
	"rmdir",        DOrmdir,
 | 
						|
	"site",		DOsite,
 | 
						|
	"size",		DOsize,
 | 
						|
	"status",	DOstat,
 | 
						|
	"stream",	DOstream,
 | 
						|
	"system",	DOsyst,
 | 
						|
	"user",         DOuser,
 | 
						|
	"ver",          DOver,
 | 
						|
	"",     (int (*)())0
 | 
						|
};
 | 
						|
 | 
						|
int main(argc, argv)
 | 
						|
int argc;
 | 
						|
char *argv[];
 | 
						|
{
 | 
						|
int s;
 | 
						|
struct commands *cmd;
 | 
						|
static char buffer[128];
 | 
						|
 | 
						|
   if(NETinit())
 | 
						|
   	return(-1);
 | 
						|
 | 
						|
   FTPinit();
 | 
						|
 | 
						|
   s = 0;
 | 
						|
 | 
						|
   if(argc > 1) {
 | 
						|
	sprintf(buffer, "open %s ", argv[1]);
 | 
						|
	makeargs(buffer);
 | 
						|
	s = DOopen();
 | 
						|
	if(atty && s > 0) {
 | 
						|
		sprintf(buffer, "user");
 | 
						|
		makeargs(buffer);
 | 
						|
		s = DOuser();
 | 
						|
	}
 | 
						|
   }
 | 
						|
 | 
						|
   while(s >= 0) {
 | 
						|
	s = readline("ftp>", buffer, sizeof(buffer));
 | 
						|
	if(s < 0) break;
 | 
						|
	makeargs(buffer);
 | 
						|
	if(cmdargc == 0) continue;
 | 
						|
	for(cmd = commands; *cmd->name != '\0'; cmd++)
 | 
						|
		if(!strcmp(cmdargv[0], cmd->name))
 | 
						|
			break;
 | 
						|
	if(*cmd->name != '\0')
 | 
						|
		s = (*cmd->func)();
 | 
						|
	else {
 | 
						|
		s = 0;
 | 
						|
		printf("Command \"%s\" not recognized.\n", cmdargv[0]);
 | 
						|
	}
 | 
						|
   }
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 |