935 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			935 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* file.c Copyright 1992-2000 by Michael Temari All Rights Reserved
 | 
						|
 *
 | 
						|
 * This file is part of ftp.
 | 
						|
 *
 | 
						|
 *
 | 
						|
 * 01/25/96 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 "file.h"
 | 
						|
#include "net.h"
 | 
						|
 | 
						|
_PROTOTYPE(static char *dir, (char *path, int full));
 | 
						|
_PROTOTYPE(static int asciisize, (int fd, off_t *filesize));
 | 
						|
_PROTOTYPE(static off_t asciisetsize, (int fd, off_t filesize));
 | 
						|
_PROTOTYPE(static int cloneit, (char *file, int mode));
 | 
						|
 | 
						|
#if (__WORD_SIZE == 4)
 | 
						|
static char buffer[8192];
 | 
						|
#else
 | 
						|
static char buffer[2048];
 | 
						|
#endif
 | 
						|
static char line2[512];
 | 
						|
 | 
						|
static char *dir(path, full)
 | 
						|
char *path;
 | 
						|
int full;
 | 
						|
{
 | 
						|
char cmd[128];
 | 
						|
static char name[32];
 | 
						|
 | 
						|
   tmpnam(name);
 | 
						|
 | 
						|
   if(full)
 | 
						|
	sprintf(cmd, "ls -l %s > %s", path, name);
 | 
						|
   else
 | 
						|
	sprintf(cmd, "ls -dA %s > %s", path, name);
 | 
						|
 | 
						|
   system(cmd);
 | 
						|
 | 
						|
   return(name);
 | 
						|
}
 | 
						|
 | 
						|
int DOascii()
 | 
						|
{
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   s = DOcommand("TYPE", "A");
 | 
						|
 | 
						|
   type = TYPE_A;
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DObinary()
 | 
						|
{
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   s = DOcommand("TYPE", "I");
 | 
						|
 | 
						|
   type = TYPE_I;
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOblock()
 | 
						|
{
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   s = DOcommand("MODE", "B");
 | 
						|
 | 
						|
   mode = MODE_B;
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOstream()
 | 
						|
{
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   s = DOcommand("MODE", "S");
 | 
						|
 | 
						|
   mode = MODE_S;
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOpwd()
 | 
						|
{
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   s = DOcommand("PWD", "");
 | 
						|
 | 
						|
   if(s == 500 || s == 502)
 | 
						|
	s = DOcommand("XPWD", "");
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOcd()
 | 
						|
{
 | 
						|
char *path;
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   path = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("Path: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	path = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   if(!strcmp(path, ".."))
 | 
						|
   	s = DOcommand("CDUP", "");
 | 
						|
   else
 | 
						|
   	s = DOcommand("CWD", path);
 | 
						|
 | 
						|
   if(s == 500 || s == 502) {
 | 
						|
	if(!strcmp(path, ".."))
 | 
						|
		s = DOcommand("XCUP", "");
 | 
						|
	else
 | 
						|
		s = DOcommand("XCWD", path);
 | 
						|
   }
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOmkdir()
 | 
						|
{
 | 
						|
char *path;
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   path = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("Directory: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	path = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   s = DOcommand("MKD", path);
 | 
						|
 | 
						|
   if(s == 500 || s == 502)
 | 
						|
	s = DOcommand("XMKD", path);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOrmdir()
 | 
						|
{
 | 
						|
char *path;
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   path = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("Directory: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	path = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   s = DOcommand("RMD", path);
 | 
						|
 | 
						|
   if(s == 500 || s == 502)
 | 
						|
	s = DOcommand("XRMD", path);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOdelete()
 | 
						|
{
 | 
						|
char *file;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   file = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("File: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	file = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   return(DOcommand("DELE", file));
 | 
						|
}
 | 
						|
 | 
						|
int DOmdtm()
 | 
						|
{
 | 
						|
char *file;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   file = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("File: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	file = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   return(DOcommand("MDTM", file));
 | 
						|
}
 | 
						|
 | 
						|
int DOsize()
 | 
						|
{
 | 
						|
char *file;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   file = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("File: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	file = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   return(DOcommand("SIZE", file));
 | 
						|
}
 | 
						|
 | 
						|
int DOstat()
 | 
						|
{
 | 
						|
char *file;
 | 
						|
 | 
						|
   if(cmdargc < 2)
 | 
						|
	if(!linkopen) {
 | 
						|
		printf("You must \"OPEN\" a connection first.\n");
 | 
						|
		return(0);
 | 
						|
	} else
 | 
						|
		return(DOcommand("STAT", ""));
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   file = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("File: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	file = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   return(DOcommand("STAT", file));
 | 
						|
}
 | 
						|
 | 
						|
int DOlist()
 | 
						|
{
 | 
						|
char *path;
 | 
						|
char *local;
 | 
						|
int fd;
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   path = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2)
 | 
						|
	path = "";
 | 
						|
 | 
						|
   if(cmdargc < 3)
 | 
						|
	local = "";
 | 
						|
   else
 | 
						|
	local = cmdargv[2];
 | 
						|
 | 
						|
   if(*local == '\0')
 | 
						|
	fd = 1;
 | 
						|
   else
 | 
						|
	fd = open(local, O_WRONLY | O_CREAT | O_TRUNC, 0666);
 | 
						|
 | 
						|
   if(fd < 0) {
 | 
						|
	printf("Could not open local file %s. Error %s\n", local, strerror(errno));
 | 
						|
	return(0);
 | 
						|
   }
 | 
						|
 | 
						|
   s = DOdata("LIST", path, RETR, fd);
 | 
						|
 | 
						|
   if(fd > 2)
 | 
						|
	close(fd);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOnlst()
 | 
						|
{
 | 
						|
char *path;
 | 
						|
char *local;
 | 
						|
int fd;
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   path = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2)
 | 
						|
	path = "";
 | 
						|
 | 
						|
   if(cmdargc < 3)
 | 
						|
	local = "";
 | 
						|
   else
 | 
						|
	local = cmdargv[2];
 | 
						|
 | 
						|
   if(*local == '\0')
 | 
						|
	fd = 1;
 | 
						|
   else
 | 
						|
	fd = open(local, O_WRONLY | O_CREAT | O_TRUNC, 0666);
 | 
						|
 | 
						|
   if(fd < 0) {
 | 
						|
	printf("Could not open local file %s. Error %s\n", local, strerror(errno));
 | 
						|
	return(0);
 | 
						|
   }
 | 
						|
 | 
						|
   s = DOdata("NLST", path, RETR, fd);
 | 
						|
 | 
						|
   if(fd > 2)
 | 
						|
	close(fd);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOretr()
 | 
						|
{
 | 
						|
char *file, *localfile;
 | 
						|
int fd;
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   file = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("Remote File: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	file = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   if(cmdargc < 3)
 | 
						|
	localfile = file;
 | 
						|
   else
 | 
						|
	localfile = cmdargv[2];
 | 
						|
 | 
						|
   fd = open(localfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
 | 
						|
 | 
						|
   if(fd < 0) {
 | 
						|
	printf("Could not open local file %s. Error %s\n", localfile, strerror(errno));
 | 
						|
	return(0);
 | 
						|
   }
 | 
						|
 | 
						|
   s = DOdata("RETR", file, RETR, fd);
 | 
						|
 | 
						|
   close(fd);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOrretr()
 | 
						|
{
 | 
						|
char *file, *localfile;
 | 
						|
int fd;
 | 
						|
int s;
 | 
						|
off_t filesize;
 | 
						|
char restart[16];
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   file = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("Remote File: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	file = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   if(cmdargc < 3)
 | 
						|
	localfile = file;
 | 
						|
   else
 | 
						|
	localfile = cmdargv[2];
 | 
						|
 | 
						|
   fd = open(localfile, O_RDWR);
 | 
						|
 | 
						|
   if(fd < 0) {
 | 
						|
	printf("Could not open local file %s. Error %s\n", localfile, strerror(errno));
 | 
						|
	return(0);
 | 
						|
   }
 | 
						|
 | 
						|
   if(type == TYPE_A) {
 | 
						|
   	if(asciisize(fd, &filesize)) {
 | 
						|
   		printf("Could not determine ascii file size of %s\n", localfile);
 | 
						|
   		close(fd);
 | 
						|
   		return(0);
 | 
						|
   	}
 | 
						|
   } else
 | 
						|
	filesize = lseek(fd, 0, SEEK_END);
 | 
						|
 | 
						|
   sprintf(restart, "%lu", filesize);
 | 
						|
 | 
						|
   s = DOcommand("REST", restart);
 | 
						|
 | 
						|
   if(s != 350) {
 | 
						|
   	close(fd);
 | 
						|
   	return(s);
 | 
						|
   }
 | 
						|
 | 
						|
   s = DOdata("RETR", file, RETR, fd);
 | 
						|
 | 
						|
   close(fd);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
char *ttime(time_t t)
 | 
						|
{
 | 
						|
struct tm *tm;
 | 
						|
static char tbuf[16];
 | 
						|
 | 
						|
   tm = localtime(&t);
 | 
						|
 | 
						|
   sprintf(tbuf, "%04d%02d%02d%02d%02d.%02d",
 | 
						|
	tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
 | 
						|
	tm->tm_hour, tm->tm_min, tm->tm_sec);
 | 
						|
 | 
						|
   return(tbuf);
 | 
						|
}
 | 
						|
 | 
						|
static int cloneit(file, mode)
 | 
						|
char *file;
 | 
						|
int mode;
 | 
						|
{
 | 
						|
int opr;
 | 
						|
int s;
 | 
						|
int ss;
 | 
						|
struct stat st;
 | 
						|
static unsigned short lcrc;
 | 
						|
static unsigned short ccrc;
 | 
						|
static unsigned long csize;
 | 
						|
static char ft;
 | 
						|
static unsigned long maj;
 | 
						|
static unsigned long min;
 | 
						|
static unsigned long uid;
 | 
						|
static unsigned long gid;
 | 
						|
static unsigned long fmode;
 | 
						|
static unsigned long size;
 | 
						|
static unsigned long mtime;
 | 
						|
struct utimbuf ut;
 | 
						|
unsigned short crc(char *fname);
 | 
						|
 | 
						|
   if(mode == 1) {
 | 
						|
	/* see if file exists locally */
 | 
						|
	ss = stat(file, &st);
 | 
						|
 | 
						|
	opr = printreply;
 | 
						|
	printreply = 0;
 | 
						|
	s = DOcommand("SITE FDET", file);
 | 
						|
	printreply = opr;
 | 
						|
 | 
						|
	if((s / 100) != 2)
 | 
						|
   		return(-1);
 | 
						|
 | 
						|
   	sscanf(reply, "%*d %c%lu%lu%lu%lu%lu%lu%lu",
 | 
						|
   		&ft, &maj, &min, &uid, &gid, &fmode, &size, &mtime);
 | 
						|
 | 
						|
   	if(ft == 'f') {
 | 
						|
		opr = printreply;
 | 
						|
		printreply = 0;
 | 
						|
		s = DOcommand("SITE CCRC", file);
 | 
						|
		printreply = opr;
 | 
						|
		if((s / 100) != 2)
 | 
						|
   			return(-1);
 | 
						|
 | 
						|
   		sscanf(reply, "%*d %*s%u%lu", &ccrc, &csize);
 | 
						|
   		if(ss < 0) return(-1);
 | 
						|
   		lcrc = crc(file);
 | 
						|
   		if(size != csize || size != st.st_size || ccrc != lcrc)
 | 
						|
   			return(-1);
 | 
						|
   	} else
 | 
						|
   	if(ss < 0 && ft == 'd') {
 | 
						|
   		s = mkdir(file, fmode);
 | 
						|
   		printf("mkdir %s\n", file);
 | 
						|
   	} else
 | 
						|
	if((ss < 0) && (ft == 'b' || ft == 'c' || ft == 'p')) {
 | 
						|
		s = mknod(file, fmode, maj << 8 | min);
 | 
						|
		printf("mknod %c %u %u\n", file, maj, min);
 | 
						|
	} else
 | 
						|
		return(0);
 | 
						|
   }
 | 
						|
   ss = stat(file, &st);
 | 
						|
   if(ss < 0)
 | 
						|
   	return(-1);
 | 
						|
   if(st.st_uid != uid || st.st_gid != gid) {
 | 
						|
   	s = chown(file, uid, gid);
 | 
						|
   	printf("chown %u:%u %s\n", uid, gid, file);
 | 
						|
   }
 | 
						|
   if(st.st_mode != fmode) {
 | 
						|
   	s = chmod(file, fmode);
 | 
						|
   	printf("chmod %04o %s\n", fmode, file);
 | 
						|
   }
 | 
						|
   if(st.st_mtime != mtime) {
 | 
						|
   	ut.actime = mtime;
 | 
						|
   	ut.modtime = mtime;
 | 
						|
   	s = utime(file, &ut);
 | 
						|
   	printf("touch -m -t %s %s\n", ttime(mtime), file);
 | 
						|
   }
 | 
						|
 | 
						|
   return(0);
 | 
						|
}
 | 
						|
 | 
						|
int DOMretr()
 | 
						|
{
 | 
						|
char *files;
 | 
						|
int fd, s;
 | 
						|
char *p;
 | 
						|
FILE *fp;
 | 
						|
char name[32];
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   files = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("Files: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	files = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   tmpnam(name);
 | 
						|
 | 
						|
   fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
 | 
						|
 | 
						|
   if(fd < 0) {
 | 
						|
	printf("Could not open local file %s. Error %s\n", name, strerror(errno));
 | 
						|
	return(0);
 | 
						|
   }
 | 
						|
 | 
						|
   s = DOdata("NLST", files, RETR, fd);
 | 
						|
 | 
						|
   close(fd);
 | 
						|
 | 
						|
   if(s == 226 || s == 250) {
 | 
						|
	fp = fopen(name, "r");
 | 
						|
	unlink(name);
 | 
						|
	if(fp == (FILE *)NULL) {
 | 
						|
		printf("Unable to open file listing.\n");
 | 
						|
		return(0);
 | 
						|
	}
 | 
						|
	while(fgets(line2, sizeof(line2), fp) != (char *)NULL) {
 | 
						|
		p = line2 + strlen(line2) - 1;
 | 
						|
		if(p >= line2 && (*p == '\r' || *p == '\n')) *p-- = '\0';
 | 
						|
		if(p >= line2 && (*p == '\r' || *p == '\n')) *p-- = '\0';
 | 
						|
		printf("Retrieving file: %s\n", line2); fflush(stdout);
 | 
						|
		fd = open(line2, O_WRONLY | O_CREAT | O_TRUNC, 0666);
 | 
						|
		if(fd < 0)
 | 
						|
			printf("Unable to open local file %s\n", line2);
 | 
						|
		else {
 | 
						|
			s = DOdata("RETR", line2, RETR, fd);
 | 
						|
			close(fd);
 | 
						|
			if(s < 0) break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	fclose(fp);
 | 
						|
   } else
 | 
						|
	unlink(name);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOappe()
 | 
						|
{
 | 
						|
char *file, *remotefile;
 | 
						|
int fd;
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   file = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("Local File: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	file = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   if(cmdargc < 3)
 | 
						|
	remotefile = file;
 | 
						|
   else
 | 
						|
	remotefile = cmdargv[2];
 | 
						|
 | 
						|
   fd = open(file, O_RDONLY);
 | 
						|
 | 
						|
   if(fd < 0) {
 | 
						|
	printf("Could not open local file %s. Error %s\n", file, strerror(errno));
 | 
						|
	return(0);
 | 
						|
   }
 | 
						|
 | 
						|
   s = DOdata("APPE", remotefile, STOR, fd);
 | 
						|
 | 
						|
   close(fd);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOstor()
 | 
						|
{
 | 
						|
char *file, *remotefile;
 | 
						|
int fd;
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   file = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("Local File: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	file = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   if(cmdargc < 3)
 | 
						|
	remotefile = file;
 | 
						|
   else
 | 
						|
	remotefile = cmdargv[2];
 | 
						|
 | 
						|
   fd = open(file, O_RDONLY);
 | 
						|
 | 
						|
   if(fd < 0) {
 | 
						|
	printf("Could not open local file %s. Error %s\n", file, strerror(errno));
 | 
						|
	return(0);
 | 
						|
   }
 | 
						|
 | 
						|
   s = DOdata("STOR", remotefile, STOR, fd);
 | 
						|
 | 
						|
   close(fd);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOrstor()
 | 
						|
{
 | 
						|
char *file, *remotefile;
 | 
						|
int fd;
 | 
						|
int s;
 | 
						|
off_t filesize, rmtsize;
 | 
						|
char restart[16];
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   file = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("Local File: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	file = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   if(cmdargc < 3)
 | 
						|
	remotefile = file;
 | 
						|
   else
 | 
						|
	remotefile = cmdargv[2];
 | 
						|
 | 
						|
   s = DOcommand("SIZE", remotefile);
 | 
						|
 | 
						|
   if(s != 215)
 | 
						|
   	return(s);
 | 
						|
 | 
						|
   rmtsize = atol(reply+4);
 | 
						|
 | 
						|
   fd = open(file, O_RDONLY);
 | 
						|
 | 
						|
   if(fd < 0) {
 | 
						|
	printf("Could not open local file %s. Error %s\n", file, strerror(errno));
 | 
						|
	return(0);
 | 
						|
   }
 | 
						|
 | 
						|
   if(type == TYPE_A)
 | 
						|
   	filesize = asciisetsize(fd, rmtsize);
 | 
						|
   else
 | 
						|
	filesize = lseek(fd, rmtsize, SEEK_SET);
 | 
						|
 | 
						|
   if(filesize != rmtsize) {
 | 
						|
	printf("Could not set file start of %s\n", file);
 | 
						|
   	close(fd);
 | 
						|
   	return(0);
 | 
						|
   }
 | 
						|
 | 
						|
   sprintf(restart, "%lu", rmtsize);
 | 
						|
 | 
						|
   s = DOcommand("REST", restart);
 | 
						|
 | 
						|
   if(s != 350) {
 | 
						|
   	close(fd);
 | 
						|
   	return(s);
 | 
						|
   }
 | 
						|
 | 
						|
   s = DOdata("STOR", remotefile, STOR, fd);
 | 
						|
 | 
						|
   close(fd);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOstou()
 | 
						|
{
 | 
						|
char *file, *remotefile;
 | 
						|
int fd;
 | 
						|
int s;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   file = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("Local File: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	file = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   if(cmdargc < 3)
 | 
						|
	remotefile = file;
 | 
						|
   else
 | 
						|
	remotefile = cmdargv[2];
 | 
						|
 | 
						|
   fd = open(file, O_RDONLY);
 | 
						|
 | 
						|
   if(fd < 0) {
 | 
						|
	printf("Could not open local file %s. Error %s\n", file, strerror(errno));
 | 
						|
	return(0);
 | 
						|
   }
 | 
						|
 | 
						|
   s = DOdata("STOU", remotefile, STOR, fd);
 | 
						|
 | 
						|
   close(fd);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
int DOMstor()
 | 
						|
{
 | 
						|
char *files;
 | 
						|
char *name;
 | 
						|
char *p;
 | 
						|
int fd, s;
 | 
						|
FILE *fp;
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   files = cmdargv[1];
 | 
						|
 | 
						|
   if(cmdargc < 2) {
 | 
						|
	if(readline("Files: ", line2, sizeof(line2)) < 0)
 | 
						|
		return(-1);
 | 
						|
	files = line2;
 | 
						|
   }
 | 
						|
 | 
						|
   name = dir(files, 0);
 | 
						|
 | 
						|
   fp = fopen(name, "r");
 | 
						|
 | 
						|
   if(fp == (FILE *)NULL) {
 | 
						|
	printf("Unable to open listing file.\n");
 | 
						|
	return(0);
 | 
						|
   }
 | 
						|
 | 
						|
   while(fgets(line2, sizeof(line2), fp) != (char *)NULL) {
 | 
						|
	p = line2 + strlen(line2) - 1;
 | 
						|
	if(p >= line2 && (*p == '\r' || *p == '\n')) *p-- = '\0';
 | 
						|
	if(p >= line2 && (*p == '\r' || *p == '\n')) *p-- = '\0';
 | 
						|
	printf("Sending file: %s\n", line2); fflush(stdout);
 | 
						|
	fd = open(line2, O_RDONLY);
 | 
						|
	if(fd < 0)
 | 
						|
		printf("Unable to open local file %s\n", line2);
 | 
						|
	else {
 | 
						|
		s = DOdata("STOR", line2, STOR, fd);
 | 
						|
		close(fd);
 | 
						|
		if(s < 0) break;
 | 
						|
	}
 | 
						|
   }
 | 
						|
   fclose(fp);
 | 
						|
   unlink(name);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 | 
						|
 | 
						|
static int asciisize(fd, filesize)
 | 
						|
int fd;
 | 
						|
off_t *filesize;
 | 
						|
{
 | 
						|
unsigned long count;
 | 
						|
char *p, *pp;
 | 
						|
int cnt;
 | 
						|
 | 
						|
   count = 0;
 | 
						|
 | 
						|
   while((cnt = read(fd, buffer, sizeof(buffer))) > 0) {
 | 
						|
	p = buffer; pp = buffer + cnt;
 | 
						|
	count += cnt;
 | 
						|
	while(p < pp)
 | 
						|
		if(*p++ == '\n')
 | 
						|
			count++;
 | 
						|
   }
 | 
						|
 | 
						|
   if(cnt == 0) {
 | 
						|
	*filesize = count;
 | 
						|
	return(0);
 | 
						|
   }
 | 
						|
 | 
						|
   return(-1);
 | 
						|
}
 | 
						|
 | 
						|
static off_t asciisetsize(fd, filesize)
 | 
						|
int fd;
 | 
						|
off_t filesize;
 | 
						|
{
 | 
						|
off_t sp;
 | 
						|
int s;
 | 
						|
 | 
						|
   sp = 0;
 | 
						|
 | 
						|
   while(sp < filesize) {
 | 
						|
	s = read(fd, buffer, 1);
 | 
						|
	if(s < 0)
 | 
						|
		return(-1);
 | 
						|
	if(s == 0) break;
 | 
						|
	sp++;
 | 
						|
	if(*buffer == '\n')
 | 
						|
		sp++;
 | 
						|
   }
 | 
						|
 | 
						|
   return(sp);
 | 
						|
}
 | 
						|
 | 
						|
int DOclone()
 | 
						|
{
 | 
						|
char *files;
 | 
						|
int fd, s;
 | 
						|
char *p;
 | 
						|
FILE *fp;
 | 
						|
char name[32];
 | 
						|
 | 
						|
   if(DOcmdcheck())
 | 
						|
	return(0);
 | 
						|
 | 
						|
   files = cmdargv[1];
 | 
						|
 | 
						|
   tmpnam(name);
 | 
						|
 | 
						|
   fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
 | 
						|
 | 
						|
   if(fd < 0) {
 | 
						|
	printf("Could not open local file %s. Error %s\n", name, strerror(errno));
 | 
						|
	return(0);
 | 
						|
   }
 | 
						|
 | 
						|
   s = DOdata("NLST", files, RETR, fd);
 | 
						|
 | 
						|
   close(fd);
 | 
						|
 | 
						|
   if(s == 226 || s == 250) {
 | 
						|
	fp = fopen(name, "r");
 | 
						|
	unlink(name);
 | 
						|
	if(fp == (FILE *)NULL) {
 | 
						|
		printf("Unable to open file listing.\n");
 | 
						|
		return(0);
 | 
						|
	}
 | 
						|
	while(fgets(line2, sizeof(line2), fp) != (char *)NULL) {
 | 
						|
		p = line2 + strlen(line2) - 1;
 | 
						|
		if(p >= line2 && (*p == '\r' || *p == '\n')) *p-- = '\0';
 | 
						|
		if(p >= line2 && (*p == '\r' || *p == '\n')) *p-- = '\0';
 | 
						|
		cmdargv[1] = line2;
 | 
						|
		if(cloneit(line2, 1)) {
 | 
						|
			printf("Retrieving file: %s\n", line2); fflush(stdout);
 | 
						|
			fd = open(line2, O_WRONLY | O_CREAT | O_TRUNC, 0666);
 | 
						|
			if(fd < 0)
 | 
						|
				printf("Unable to open local file %s\n", line2);
 | 
						|
			else {
 | 
						|
				s = DOdata("RETR", line2, RETR, fd);
 | 
						|
				close(fd);
 | 
						|
				if(s < 0) break;
 | 
						|
			}
 | 
						|
			s = cloneit(line2, 2);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	fclose(fp);
 | 
						|
   } else
 | 
						|
	unlink(name);
 | 
						|
 | 
						|
   return(s);
 | 
						|
}
 |