Initial revision
This commit is contained in:
Executable
+31
@@ -0,0 +1,31 @@
|
||||
# Makefile for ftp
|
||||
#
|
||||
# 01/25/96 Initial Release Michael Temari, <temari@ix.netcom.com>
|
||||
#
|
||||
|
||||
CFLAGS= -O -D_MINIX -D_POSIX_SOURCE
|
||||
LDFLAGS=-i
|
||||
BINDIR=/usr/bin
|
||||
PROG= ftp
|
||||
|
||||
OBJS= ftp.o local.o file.o other.o net.o
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
$(PROG): $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJS)
|
||||
install -S 8kw $@
|
||||
|
||||
clean:
|
||||
rm -f $(PROG) $(OBJS)
|
||||
|
||||
install: $(BINDIR)/$(PROG)
|
||||
|
||||
$(BINDIR)/$(PROG): $(PROG)
|
||||
install -cs -o bin $? $@
|
||||
|
||||
ftp.o: ftp.c ftp.h local.h file.h other.h net.h
|
||||
local.o: local.c ftp.h local.h
|
||||
file.o: file.c ftp.h file.h net.h
|
||||
other.o: other.c ftp.h other.h
|
||||
net.o: net.c ftp.h file.h net.h
|
||||
Executable
+922
@@ -0,0 +1,922 @@
|
||||
/* file.c
|
||||
*
|
||||
* This file is part of ftp.
|
||||
*
|
||||
*
|
||||
* 01/25/96 Initial Release Michael Temari, <temari@ix.netcom.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 "ftp.h"
|
||||
#include "file.h"
|
||||
#include "net.h"
|
||||
|
||||
_PROTOTYPE(static char *dir, (char *path, int full));
|
||||
_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));
|
||||
_PROTOTYPE(static int asciisize, (int fd, off_t *filesize));
|
||||
_PROTOTYPE(static off_t asciisetsize, (int fd, off_t filesize));
|
||||
|
||||
static char buffer[512 << sizeof(char *)];
|
||||
static char bufout[512 << sizeof(char *)];
|
||||
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 %s > %s", path, name);
|
||||
|
||||
system(cmd);
|
||||
|
||||
return(name);
|
||||
}
|
||||
|
||||
static int asciisend(fd, fdout)
|
||||
int fd;
|
||||
int fdout;
|
||||
{
|
||||
int s, len;
|
||||
char c;
|
||||
char *p;
|
||||
char *op, *ope;
|
||||
unsigned long total=0L;
|
||||
|
||||
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 == '\r') {
|
||||
*op++ = '\r';
|
||||
total++;
|
||||
}
|
||||
*op++ = c;
|
||||
if(op >= ope) {
|
||||
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)
|
||||
write(fdout, bufout, op - bufout);
|
||||
if(atty) {
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
return(s);
|
||||
}
|
||||
|
||||
static int binarysend(fd, fdout)
|
||||
int fd;
|
||||
int fdout;
|
||||
{
|
||||
int s;
|
||||
unsigned long total=0L;
|
||||
|
||||
if(atty) {
|
||||
printf("Sent ");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
while((s = read(fd, buffer, sizeof(buffer))) > 0) {
|
||||
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(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;
|
||||
|
||||
if(isatty && fd > 2) {
|
||||
printf("Received ");
|
||||
fflush(stdout);
|
||||
}
|
||||
gotcr = 0;
|
||||
op = bufout; ope = bufout + sizeof(bufout) - 3;
|
||||
while((s = read(fdin, buffer, sizeof(buffer))) > 0) {
|
||||
p = buffer;
|
||||
total += (long)s;
|
||||
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(gotcr)
|
||||
*op++ = '\r';
|
||||
if(op > bufout)
|
||||
write(fd, bufout, op - bufout);
|
||||
if(atty && fd > 2) {
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
return(s);
|
||||
}
|
||||
|
||||
static binaryrecv(fd, fdin)
|
||||
int fd;
|
||||
int fdin;
|
||||
{
|
||||
int s;
|
||||
unsigned long total=0L;
|
||||
|
||||
if(atty && fd > 2) {
|
||||
printf("Received ");
|
||||
fflush(stdout);
|
||||
}
|
||||
while((s = read(fdin, buffer, sizeof(buffer))) > 0) {
|
||||
write(fd, buffer, s);
|
||||
total += (long)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(atty && fd > 2) {
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
return(s);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 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) {
|
||||
readline("Path: ", line2, sizeof(line2));
|
||||
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) {
|
||||
readline("Directory: ", line2, sizeof(line2));
|
||||
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) {
|
||||
readline("Directory: ", line2, sizeof(line2));
|
||||
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) {
|
||||
readline("File: ", line2, sizeof(line2));
|
||||
file = line2;
|
||||
}
|
||||
|
||||
return(DOcommand("DELE", file));
|
||||
}
|
||||
|
||||
int DOmdtm()
|
||||
{
|
||||
char *file;
|
||||
|
||||
if(DOcmdcheck())
|
||||
return(0);
|
||||
|
||||
file = cmdargv[1];
|
||||
|
||||
if(cmdargc < 2) {
|
||||
readline("File: ", line2, sizeof(line2));
|
||||
file = line2;
|
||||
}
|
||||
|
||||
return(DOcommand("MDTM", file));
|
||||
}
|
||||
|
||||
int DOsize()
|
||||
{
|
||||
char *file;
|
||||
|
||||
if(DOcmdcheck())
|
||||
return(0);
|
||||
|
||||
file = cmdargv[1];
|
||||
|
||||
if(cmdargc < 2) {
|
||||
readline("File: ", line2, sizeof(line2));
|
||||
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) {
|
||||
readline("File: ", line2, sizeof(line2));
|
||||
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) {
|
||||
readline("Remote File: ", line2, sizeof(line2));
|
||||
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) {
|
||||
readline("Remote File: ", line2, sizeof(line2));
|
||||
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);
|
||||
}
|
||||
|
||||
int DOMretr()
|
||||
{
|
||||
char *files;
|
||||
int fd, s;
|
||||
FILE *fp;
|
||||
char name[32];
|
||||
|
||||
if(DOcmdcheck())
|
||||
return(0);
|
||||
|
||||
files = cmdargv[1];
|
||||
|
||||
if(cmdargc < 2) {
|
||||
readline("Files: ", line2, sizeof(line2));
|
||||
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) {
|
||||
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) {
|
||||
line2[strlen(line2)-1] = '\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) {
|
||||
readline("Local File: ", line2, sizeof(line2));
|
||||
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) {
|
||||
readline("Local File: ", line2, sizeof(line2));
|
||||
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) {
|
||||
readline("Local File: ", line2, sizeof(line2));
|
||||
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) {
|
||||
readline("Local File: ", line2, sizeof(line2));
|
||||
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;
|
||||
int fd, s;
|
||||
FILE *fp;
|
||||
|
||||
if(DOcmdcheck())
|
||||
return(0);
|
||||
|
||||
files = cmdargv[1];
|
||||
|
||||
if(cmdargc < 2) {
|
||||
readline("Files: ", line2, sizeof(line2));
|
||||
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) {
|
||||
line2[strlen(line2)-1] = '\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);
|
||||
}
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
/* file.h
|
||||
*
|
||||
* This file is part of ftp.
|
||||
*
|
||||
*
|
||||
* 01/25/96 Initial Release Michael Temari, <temari@ix.netcom.com>
|
||||
*/
|
||||
|
||||
_PROTOTYPE(int recvfile, (int fd, int fdin));
|
||||
_PROTOTYPE(int sendfile, (int fd, int fdout));
|
||||
_PROTOTYPE(int DOascii, (void));
|
||||
_PROTOTYPE(int DObinary, (void));
|
||||
_PROTOTYPE(int DOpwd, (void));
|
||||
_PROTOTYPE(int DOcd, (void));
|
||||
_PROTOTYPE(int DOmkdir, (void));
|
||||
_PROTOTYPE(int DOrmdir, (void));
|
||||
_PROTOTYPE(int DOdelete, (void));
|
||||
_PROTOTYPE(int DOmdtm, (void));
|
||||
_PROTOTYPE(int DOsize, (void));
|
||||
_PROTOTYPE(int DOstat, (void));
|
||||
_PROTOTYPE(int DOlist, (void));
|
||||
_PROTOTYPE(int DOnlst, (void));
|
||||
_PROTOTYPE(int DOretr, (void));
|
||||
_PROTOTYPE(int DOrretr, (void));
|
||||
_PROTOTYPE(int DOMretr, (void));
|
||||
_PROTOTYPE(int DOappe, (void));
|
||||
_PROTOTYPE(int DOstor, (void));
|
||||
_PROTOTYPE(int DOrstor, (void));
|
||||
_PROTOTYPE(int DOstou, (void));
|
||||
_PROTOTYPE(int DOMstor, (void));
|
||||
Executable
+312
@@ -0,0 +1,312 @@
|
||||
/* ftp.c by Michael Temari 06/21/92
|
||||
*
|
||||
* ftp An ftp client program for use with TNET.
|
||||
*
|
||||
* Usage: ftp [[host] [port]]
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Author: Michael Temari, <temari@ix.netcom.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ftp.h"
|
||||
#include "local.h"
|
||||
#include "file.h"
|
||||
#include "other.h"
|
||||
#include "net.h"
|
||||
|
||||
FILE *fpcommin;
|
||||
FILE *fpcommout;
|
||||
|
||||
int linkopen;
|
||||
int loggedin;
|
||||
int type;
|
||||
int format;
|
||||
int mode;
|
||||
int structure;
|
||||
int passive;
|
||||
int atty;
|
||||
|
||||
int cmdargc;
|
||||
char *cmdargv[NUMARGS];
|
||||
|
||||
char reply[1024];
|
||||
|
||||
_PROTOTYPE(static int makeargs, (char *buff));
|
||||
_PROTOTYPE(int DOhelp, (void));
|
||||
_PROTOTYPE(int main, (int argc, char *argv[]));
|
||||
|
||||
static int makeargs(buff)
|
||||
char *buff;
|
||||
{
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
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;
|
||||
{
|
||||
printf(prompt); fflush(stdout);
|
||||
|
||||
if(fgets(buff, len, stdin) == (char *)NULL) {
|
||||
printf("\nEnd of file on input!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
*strchr(buff, '\n') = 0;
|
||||
|
||||
if(!atty) {
|
||||
printf("%s\n", buff);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int DOgetreply()
|
||||
{
|
||||
char *p;
|
||||
char buff[6];
|
||||
int s;
|
||||
int firsttime;
|
||||
|
||||
do {
|
||||
firsttime = 1;
|
||||
do {
|
||||
if(fgets(reply, sizeof(reply), fpcommin) == (char *)0)
|
||||
return(-1);
|
||||
p = reply + strlen(reply) - 1;
|
||||
while(p != reply)
|
||||
if(*p == '\r' || *p == '\n' || isspace(*p))
|
||||
*p-- = '\0';
|
||||
else
|
||||
break;
|
||||
printf("%s\n", reply); fflush(stdout);
|
||||
if(firsttime) {
|
||||
firsttime = 0;
|
||||
strncpy(buff, reply, 4);
|
||||
buff[3] = ' ';
|
||||
}
|
||||
} while(strncmp(reply, buff, 3) || reply[3] == '-');
|
||||
s = atoi(buff);
|
||||
} 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;
|
||||
{
|
||||
if(*ftparg)
|
||||
fprintf(fpcommout, "%s %s\r\n", ftpcommand, ftparg);
|
||||
else
|
||||
fprintf(fpcommout, "%s\r\n", ftpcommand);
|
||||
|
||||
fflush(fpcommout);
|
||||
|
||||
return(DOgetreply());
|
||||
}
|
||||
|
||||
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 mode to ascii\n");
|
||||
printf("binary Set file transfer mode to binary\n");
|
||||
printf("bye Close connection and exit\n");
|
||||
printf("cd Change directory on remote host\n");
|
||||
printf("close Close connection\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");
|
||||
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");
|
||||
|
||||
readline("Press ENTER to continue... ", junk, sizeof(junk));
|
||||
|
||||
printf("mput Send multiple files to remote host\n");
|
||||
printf("noop Send the ftp NOOP command\n");
|
||||
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");
|
||||
printf("site Send a site specific command\n");
|
||||
printf("size Get file size information\n");
|
||||
printf("status Get connection/file status information\n");
|
||||
printf("system Get remote system type information\n");
|
||||
printf("user Enter remote user information\n");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
struct commands {
|
||||
char *name;
|
||||
_PROTOTYPE(int (*func), (void));
|
||||
};
|
||||
|
||||
static struct commands commands[] = {
|
||||
"!", DOlshell,
|
||||
"append", DOappe,
|
||||
"ascii", DOascii,
|
||||
"binary", DObinary,
|
||||
"bin", DObinary,
|
||||
"bye", DOquit,
|
||||
"cd", DOcd,
|
||||
"close", DOclose,
|
||||
"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,
|
||||
"system", DOsyst,
|
||||
"user", DOuser,
|
||||
"", (int (*)())0
|
||||
};
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int s;
|
||||
struct commands *cmd;
|
||||
static char buffer[128];
|
||||
|
||||
NETinit();
|
||||
|
||||
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) {
|
||||
readline("ftp>", buffer, sizeof(buffer));
|
||||
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(0);
|
||||
}
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
/* ftp.h
|
||||
*
|
||||
* This file is part of ftp.
|
||||
*
|
||||
*
|
||||
* 01/25/96 Initial Release Michael Temari, <temari@ix.netcom.com>
|
||||
*/
|
||||
|
||||
extern FILE *fpcommin;
|
||||
extern FILE *fpcommout;
|
||||
|
||||
extern int linkopen;
|
||||
extern int loggedin;
|
||||
extern int type;
|
||||
extern int format;
|
||||
extern int mode;
|
||||
extern int structure;
|
||||
extern int passive;
|
||||
extern int atty;
|
||||
|
||||
#define NUMARGS 10
|
||||
extern int cmdargc;
|
||||
extern char *cmdargv[NUMARGS];
|
||||
|
||||
extern char reply[1024];
|
||||
|
||||
#define RETR 0
|
||||
#define STOR 1
|
||||
|
||||
#define TYPE_A 0
|
||||
#define TYPE_I 1
|
||||
|
||||
_PROTOTYPE(int readline, (char *prompt, char *buff, int len));
|
||||
_PROTOTYPE(int DOgetreply, (void));
|
||||
_PROTOTYPE(int DOcmdcheck, (void));
|
||||
_PROTOTYPE(int DOcommand, (char *ftpcommand, char *ftparg));
|
||||
Executable
+128
@@ -0,0 +1,128 @@
|
||||
/* local.c
|
||||
*
|
||||
* This file is part of ftp.
|
||||
*
|
||||
*
|
||||
* 01/25/96 Initial Release Michael Temari, <temari@ix.netcom.com>
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "ftp.h"
|
||||
#include "local.h"
|
||||
|
||||
static char line2[512];
|
||||
|
||||
_PROTOTYPE(static void dodir, (char *path, int full));
|
||||
|
||||
int DOlpwd()
|
||||
{
|
||||
if(getcwd(line2, sizeof(line2)) == (char *)NULL)
|
||||
printf("Could not determine local directory. %s\n", strerror(errno));
|
||||
else
|
||||
printf("Current local directory: %s\n", line2);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int DOlcd()
|
||||
{
|
||||
char *path;
|
||||
int s;
|
||||
|
||||
path = cmdargv[1];
|
||||
|
||||
if(cmdargc < 2) {
|
||||
readline("Path: ", line2, sizeof(line2));
|
||||
path = line2;
|
||||
}
|
||||
|
||||
if(chdir(path))
|
||||
printf("Could not change local directory. %s\n", strerror(errno));
|
||||
else
|
||||
DOlpwd();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int DOlmkdir()
|
||||
{
|
||||
char *path;
|
||||
int s;
|
||||
|
||||
path = cmdargv[1];
|
||||
|
||||
if(cmdargc < 2) {
|
||||
readline("Directory: ", line2, sizeof(line2));
|
||||
path = line2;
|
||||
}
|
||||
|
||||
if(mkdir(path, 0777))
|
||||
printf("Could not make directory %s. %s\n", path, strerror(errno));
|
||||
else
|
||||
printf("Directory created.\n");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int DOlrmdir()
|
||||
{
|
||||
char *path;
|
||||
int s;
|
||||
|
||||
path = cmdargv[1];
|
||||
|
||||
if(cmdargc < 2) {
|
||||
readline("Directory: ", line2, sizeof(line2));
|
||||
path = line2;
|
||||
}
|
||||
|
||||
if(rmdir(path))
|
||||
printf("Could not remove directory %s. %s\n", path, strerror(errno));
|
||||
else
|
||||
printf("Directory removed.\n");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int DOllist(void)
|
||||
{
|
||||
dodir(".", 1);
|
||||
}
|
||||
|
||||
int DOlnlst(void)
|
||||
{
|
||||
dodir(".", 0);
|
||||
}
|
||||
|
||||
int DOlshell(void)
|
||||
{
|
||||
system("$SHELL");
|
||||
}
|
||||
|
||||
static void dodir(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 %s > %s", path, name);
|
||||
|
||||
system(cmd);
|
||||
sprintf(cmd, "more %s", name);
|
||||
system(cmd);
|
||||
sprintf(cmd, "rm %s", name);
|
||||
system(cmd);
|
||||
}
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
/* local.h
|
||||
*
|
||||
* This file is part of ftp.
|
||||
*
|
||||
*
|
||||
* 01/25/96 Initial Release Michael Temari, <temari@ix.netcom.com>
|
||||
*/
|
||||
|
||||
_PROTOTYPE(int DOlpwd, (void));
|
||||
_PROTOTYPE(int DOlcd, (void));
|
||||
_PROTOTYPE(int DOlmkdir, (void));
|
||||
_PROTOTYPE(int DOlrmdir, (void));
|
||||
_PROTOTYPE(int DOllist, (void));
|
||||
_PROTOTYPE(int DOlnlst, (void));
|
||||
_PROTOTYPE(int DOlshell, (void));
|
||||
Executable
+421
@@ -0,0 +1,421 @@
|
||||
/* net.c
|
||||
*
|
||||
* This file is part of ftp.
|
||||
*
|
||||
*
|
||||
* 01/25/96 Initial Release Michael Temari, <temari@ix.netcom.com>
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <net/netlib.h>
|
||||
#include <net/hton.h>
|
||||
#include <net/gen/netdb.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/inet.h>
|
||||
#include <net/gen/tcp.h>
|
||||
#include <net/gen/tcp_io.h>
|
||||
|
||||
#include "ftp.h"
|
||||
#include "file.h"
|
||||
#include "net.h"
|
||||
|
||||
_PROTOTYPE(void donothing, (int sig));
|
||||
|
||||
static int ftpcomm_fd;
|
||||
static ipaddr_t myip;
|
||||
static ipaddr_t hostip;
|
||||
static char host[256];
|
||||
static int lpid;
|
||||
|
||||
void NETinit()
|
||||
{
|
||||
int s;
|
||||
char *tcp_device;
|
||||
int tcp_fd;
|
||||
nwio_tcpconf_t nwio_tcpconf;
|
||||
|
||||
/* All this just to get our ip address */
|
||||
|
||||
if((tcp_device = getenv("TCP_DEVICE")) == (char *)NULL)
|
||||
tcp_device = TCP_DEVICE;
|
||||
|
||||
tcp_fd = open(tcp_device, O_RDWR);
|
||||
if(tcp_fd < 0) {
|
||||
perror("ftp: Could not open tcp_device");
|
||||
exit(-1);
|
||||
}
|
||||
s = ioctl(tcp_fd, NWIOGTCPCONF, &nwio_tcpconf);
|
||||
if(s < 0) {
|
||||
perror("ftp: Could not get tcp configuration");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
myip = nwio_tcpconf.nwtc_locaddr;
|
||||
|
||||
close(tcp_fd);
|
||||
}
|
||||
|
||||
int DOopen()
|
||||
{
|
||||
nwio_tcpconf_t tcpconf;
|
||||
nwio_tcpcl_t tcpcopt;
|
||||
char *tcp_device;
|
||||
tcpport_t port;
|
||||
int s;
|
||||
struct hostent *hp;
|
||||
struct servent *servent;
|
||||
|
||||
if(linkopen) {
|
||||
printf("Use \"CLOSE\" to close the connection first.\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(cmdargc < 2)
|
||||
readline("Host: ", host, sizeof(host));
|
||||
else
|
||||
strncpy(host, cmdargv[1], sizeof(host));
|
||||
|
||||
if((servent = getservbyname("ftp", "tcp")) == (struct servent *)NULL) {
|
||||
fprintf(stderr, "ftp: Could not find ftp tcp service\n");
|
||||
return(-1);
|
||||
}
|
||||
port = (tcpport_t)servent->s_port;
|
||||
|
||||
hp = gethostbyname(host);
|
||||
if (hp == (struct hostent *)NULL) {
|
||||
hostip = (ipaddr_t)0;
|
||||
printf("Unresolved host %s\n", host);
|
||||
return(0);
|
||||
} else
|
||||
memcpy((char *) &hostip, (char *) hp->h_addr, hp->h_length);
|
||||
|
||||
/* This HACK allows the server to establish data connections correctly */
|
||||
/* when using the loopback device to talk to ourselves */
|
||||
if(hostip == inet_addr("127.0.0.1"))
|
||||
hostip = myip;
|
||||
|
||||
if((tcp_device = getenv("TCP_DEVICE")) == NULL)
|
||||
tcp_device = "/dev/tcp";
|
||||
|
||||
if((ftpcomm_fd = open(tcp_device, O_RDWR)) < 0) {
|
||||
perror("ftp: open error on tcp device");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
tcpconf.nwtc_flags = NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP;
|
||||
tcpconf.nwtc_remaddr = hostip;
|
||||
tcpconf.nwtc_remport = port;
|
||||
|
||||
s = ioctl(ftpcomm_fd, NWIOSTCPCONF, &tcpconf);
|
||||
if(s < 0) {
|
||||
perror("ftp: ioctl error on NWIOSTCPCONF");
|
||||
close(ftpcomm_fd);
|
||||
return(s);
|
||||
}
|
||||
|
||||
tcpcopt.nwtcl_flags = 0;
|
||||
|
||||
s = ioctl(ftpcomm_fd, NWIOTCPCONN, &tcpcopt);
|
||||
if(s < 0) {
|
||||
perror("ftp: ioctl error on NWIOTCPCONN");
|
||||
close(ftpcomm_fd);
|
||||
return(s);
|
||||
}
|
||||
|
||||
s = ioctl(ftpcomm_fd, NWIOGTCPCONF, &tcpconf);
|
||||
if(s < 0) {
|
||||
perror("ftp: ioctl error on NWIOGTCPCONF");
|
||||
close(ftpcomm_fd);
|
||||
return(s);
|
||||
}
|
||||
|
||||
fpcommin = fdopen(ftpcomm_fd, "r");
|
||||
fpcommout = fdopen(ftpcomm_fd, "w");
|
||||
|
||||
s = DOgetreply();
|
||||
|
||||
if(s < 0) {
|
||||
fclose(fpcommin);
|
||||
fclose(fpcommout);
|
||||
close(ftpcomm_fd);
|
||||
return(s);
|
||||
}
|
||||
|
||||
if(s != 220) {
|
||||
fclose(fpcommin);
|
||||
fclose(fpcommout);
|
||||
close(ftpcomm_fd);
|
||||
return(0);
|
||||
}
|
||||
|
||||
linkopen = 1;
|
||||
|
||||
return(s);
|
||||
}
|
||||
|
||||
int DOclose()
|
||||
{
|
||||
if(!linkopen) {
|
||||
printf("You can't close a connection that isn't open.\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
fclose(fpcommin);
|
||||
fclose(fpcommout);
|
||||
close(ftpcomm_fd);
|
||||
|
||||
linkopen = 0;
|
||||
loggedin = 0;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int DOquit()
|
||||
{
|
||||
int s;
|
||||
|
||||
if(linkopen) {
|
||||
s = DOcommand("QUIT", "");
|
||||
s = DOclose();
|
||||
}
|
||||
|
||||
printf("FTP done.\n");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void donothing(sig)
|
||||
int sig;
|
||||
{
|
||||
}
|
||||
|
||||
int DOdata(datacom, file, direction, fd)
|
||||
char *datacom;
|
||||
char *file;
|
||||
int direction; /* RETR or STOR */
|
||||
int fd;
|
||||
{
|
||||
nwio_tcpconf_t tcpconf;
|
||||
nwio_tcpcl_t tcplopt, tcpcopt;
|
||||
char *tcp_device;
|
||||
int ftpdata_fd;
|
||||
char *buff;
|
||||
ipaddr_t ripaddr;
|
||||
tcpport_t rport;
|
||||
static tcpport_t lport = HTONS(0xF000);
|
||||
int s;
|
||||
int i;
|
||||
int cs;
|
||||
int pfd[2];
|
||||
char dummy;
|
||||
char port[32];
|
||||
|
||||
ripaddr = hostip;
|
||||
rport = HTONS(20);
|
||||
|
||||
/* here we set up a connection to listen on if not passive mode */
|
||||
/* otherwise we use this to connect for passive mode */
|
||||
|
||||
if((tcp_device = getenv("TCP_DEVICE")) == NULL)
|
||||
tcp_device = "/dev/tcp";
|
||||
|
||||
if((ftpdata_fd = open(tcp_device, O_RDWR)) < 0) {
|
||||
perror("ftp: open error on tcp device");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if(passive) {
|
||||
s = DOcommand("PASV", "");
|
||||
if(s != 227) {
|
||||
close(ftpdata_fd);
|
||||
return(s);
|
||||
}
|
||||
/* decode host and port */
|
||||
buff = reply;
|
||||
while(*buff && (*buff != '(')) buff++;
|
||||
buff++;
|
||||
ripaddr = (ipaddr_t)0;
|
||||
for(i = 0; i < 4; i++) {
|
||||
ripaddr = (ripaddr << 8) + (ipaddr_t)atoi(buff);
|
||||
if((buff = strchr(buff, ',')) == (char *)0) {
|
||||
printf("Could not parse PASV reply\n");
|
||||
return(-1);
|
||||
}
|
||||
buff++;
|
||||
}
|
||||
rport = (tcpport_t)atoi(buff);
|
||||
if((buff = strchr(buff, ',')) == (char *)0) {
|
||||
printf("Could not parse PASV reply\n");
|
||||
return(-1);
|
||||
}
|
||||
buff++;
|
||||
rport = (rport << 8) + (tcpport_t)atoi(buff);
|
||||
ripaddr = ntohl(ripaddr);
|
||||
rport = ntohs(rport);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
tcpconf.nwtc_flags = NWTC_SET_RA | NWTC_SET_RP;
|
||||
if (passive || ntohs(lport) >= 0xF000) {
|
||||
tcpconf.nwtc_flags |= NWTC_LP_SEL;
|
||||
} else {
|
||||
/* For no good reason Sun hosts don't like it if they have to
|
||||
* connect to the same port twice in a short time...
|
||||
*/
|
||||
lport = htons(ntohs(lport) + 1);
|
||||
tcpconf.nwtc_flags |= NWTC_LP_SET;
|
||||
tcpconf.nwtc_locport = lport;
|
||||
}
|
||||
|
||||
tcpconf.nwtc_remaddr = ripaddr;
|
||||
tcpconf.nwtc_remport = rport;
|
||||
|
||||
s = ioctl(ftpdata_fd, NWIOSTCPCONF, &tcpconf);
|
||||
if(s < 0) {
|
||||
if (errno == EADDRINUSE) continue;
|
||||
perror("ftp: ioctl error on NWIOSTCPCONF");
|
||||
close(ftpdata_fd);
|
||||
return(s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
s = ioctl(ftpdata_fd, NWIOGTCPCONF, &tcpconf);
|
||||
if(s < 0) {
|
||||
perror("ftp: ioctl error on NWIOGTCPCONF");
|
||||
close(ftpdata_fd);
|
||||
return(s);
|
||||
}
|
||||
lport = tcpconf.nwtc_locport;
|
||||
|
||||
if(passive) {
|
||||
tcplopt.nwtcl_flags = 0;
|
||||
s = ioctl(ftpdata_fd, NWIOTCPCONN, &tcpcopt);
|
||||
if(s < 0) {
|
||||
perror("ftp: error on ioctl NWIOTCPCONN");
|
||||
close(ftpdata_fd);
|
||||
return(0);
|
||||
}
|
||||
s = ioctl(ftpdata_fd, NWIOGTCPCONF, &tcpconf);
|
||||
if(s < 0) {
|
||||
perror("ftp: error on ioctl NWIOGTCPCONF");
|
||||
close(ftpdata_fd);
|
||||
return(0);
|
||||
}
|
||||
} else {
|
||||
tcplopt.nwtcl_flags = 0;
|
||||
|
||||
if (pipe(pfd) < 0) {
|
||||
perror("ftp: could not create a pipe");
|
||||
return(s);
|
||||
}
|
||||
lpid = fork();
|
||||
if(lpid < 0) {
|
||||
perror("ftp: could not fork listener");
|
||||
close(ftpdata_fd);
|
||||
close(pfd[0]);
|
||||
close(pfd[1]);
|
||||
return(s);
|
||||
} else if(lpid == 0) {
|
||||
close(pfd[0]);
|
||||
signal(SIGALRM, donothing);
|
||||
alarm(15);
|
||||
close(pfd[1]);
|
||||
s = ioctl(ftpdata_fd, NWIOTCPLISTEN, &tcplopt);
|
||||
alarm(0);
|
||||
if(s < 0)
|
||||
if(errno == EINTR)
|
||||
exit(1); /* timed out */
|
||||
else
|
||||
exit(-1); /* error */
|
||||
else
|
||||
exit(0); /* connection made */
|
||||
}
|
||||
/* Wait for the pipe to close, then the listener is ready (almost). */
|
||||
close(pfd[1]);
|
||||
(void) read(pfd[0], &dummy, 1);
|
||||
close(pfd[0]);
|
||||
while(1) {
|
||||
signal(SIGALRM, donothing);
|
||||
alarm(1);
|
||||
s = ioctl(ftpdata_fd, NWIOGTCPCONF, &tcpconf);
|
||||
alarm(0);
|
||||
if(s == -1) break;
|
||||
}
|
||||
}
|
||||
|
||||
#define hiword(x) ((u16_t)((x) >> 16))
|
||||
#define loword(x) ((u16_t)(x & 0xffff))
|
||||
#define hibyte(x) (((x) >> 8) & 0xff)
|
||||
#define lobyte(x) ((x) & 0xff)
|
||||
|
||||
if(!passive) {
|
||||
sprintf(port, "%u,%u,%u,%u,%u,%u",
|
||||
hibyte(hiword(ntohl(myip))), lobyte(hiword(ntohl(myip))),
|
||||
hibyte(loword(ntohl(myip))), lobyte(loword(ntohl(myip))),
|
||||
hibyte(ntohs(lport)), lobyte(ntohs(lport)));
|
||||
s = DOcommand("PORT", port);
|
||||
if(s != 200) {
|
||||
close(ftpdata_fd);
|
||||
kill(lpid, SIGKILL);
|
||||
return(s);
|
||||
}
|
||||
}
|
||||
|
||||
s = DOcommand(datacom, file);
|
||||
if(s == 125 || s == 150) {
|
||||
if(!passive) {
|
||||
while(1) {
|
||||
s = wait(&cs);
|
||||
if(s < 0 || s == lpid)
|
||||
break;
|
||||
}
|
||||
if(s < 0) {
|
||||
perror("wait error:");
|
||||
close(ftpdata_fd);
|
||||
kill(lpid, SIGKILL);
|
||||
return(s);
|
||||
}
|
||||
if((cs & 0x00ff)) {
|
||||
printf("Child listener failed %04x\n", cs);
|
||||
close(ftpdata_fd);
|
||||
return(-1);
|
||||
}
|
||||
cs = (cs >> 8) & 0x00ff;
|
||||
if(cs == 1) {
|
||||
printf("Child listener timed out\n");
|
||||
return(DOgetreply());
|
||||
} else if(cs) {
|
||||
printf("Child listener returned %02x\n", cs);
|
||||
close(ftpdata_fd);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
switch(direction) {
|
||||
case RETR:
|
||||
s = recvfile(fd, ftpdata_fd);
|
||||
break;
|
||||
case STOR:
|
||||
s = sendfile(fd, ftpdata_fd);
|
||||
break;
|
||||
}
|
||||
close(ftpdata_fd);
|
||||
s = DOgetreply();
|
||||
} else {
|
||||
if(!passive)
|
||||
kill(lpid, SIGKILL);
|
||||
close(ftpdata_fd);
|
||||
}
|
||||
|
||||
return(s);
|
||||
}
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
/* net.h
|
||||
*
|
||||
* This file is part of ftp.
|
||||
*
|
||||
*
|
||||
* 01/25/96 Initial Release Michael Temari, <temari@ix.netcom.com>
|
||||
*/
|
||||
|
||||
_PROTOTYPE(void NETinit, (void));
|
||||
_PROTOTYPE(int DOopen, (void));
|
||||
_PROTOTYPE(int DOclose, (void));
|
||||
_PROTOTYPE(int DOquit, (void));
|
||||
_PROTOTYPE(int DOdata, (char *datacom, char *file, int direction, int fd));
|
||||
Executable
+163
@@ -0,0 +1,163 @@
|
||||
/* other.c by Michael Temari 06/21/92
|
||||
*
|
||||
* ftp An ftp client program for use with TNET.
|
||||
*
|
||||
* Author: Michael Temari, <temari@ix.netcom.com>
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "ftp.h"
|
||||
#include "other.h"
|
||||
|
||||
void FTPinit()
|
||||
{
|
||||
linkopen = 0;
|
||||
loggedin = 0;
|
||||
type = TYPE_A;
|
||||
format = 0;
|
||||
mode = 0;
|
||||
structure = 0;
|
||||
passive = 0;
|
||||
atty = isatty(0);
|
||||
}
|
||||
|
||||
int DOpass()
|
||||
{
|
||||
int s;
|
||||
struct termios oldtty, newtty;
|
||||
char *pass;
|
||||
char password[64];
|
||||
|
||||
if(!linkopen) {
|
||||
printf("You must \"OPEN\" a connection first.\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
pass = cmdargv[1];
|
||||
|
||||
if(cmdargc < 2) {
|
||||
tcgetattr(fileno(stdout), &oldtty);
|
||||
newtty = oldtty;
|
||||
newtty.c_lflag &= ~ECHO;
|
||||
tcsetattr(fileno(stdout), TCSANOW, &newtty);
|
||||
readline("Password: ", password, sizeof(password));
|
||||
tcsetattr(fileno(stdout), TCSANOW, &oldtty);
|
||||
printf("\n");
|
||||
pass = password;
|
||||
}
|
||||
|
||||
s = DOcommand("PASS", pass);
|
||||
|
||||
if(s == 230)
|
||||
loggedin = 1;
|
||||
|
||||
return(s);
|
||||
}
|
||||
|
||||
int DOuser()
|
||||
{
|
||||
char *user;
|
||||
int s;
|
||||
char username[64];
|
||||
|
||||
if(!linkopen) {
|
||||
printf("You must \"OPEN\" a connection first.\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
loggedin = 0;
|
||||
|
||||
user = cmdargv[1];
|
||||
|
||||
if(cmdargc < 2) {
|
||||
readline("Username: ", username, sizeof(username));
|
||||
user = username;
|
||||
}
|
||||
|
||||
s = DOcommand("USER", user);
|
||||
|
||||
if(atty && s == 331) {
|
||||
cmdargv[0] = "password";
|
||||
cmdargc = 1;
|
||||
return(DOpass());
|
||||
}
|
||||
|
||||
if(s == 230)
|
||||
loggedin = 1;
|
||||
|
||||
return(s);
|
||||
}
|
||||
|
||||
int DOnoop()
|
||||
{
|
||||
if(DOcmdcheck())
|
||||
return(0);
|
||||
|
||||
return(DOcommand("NOOP", ""));
|
||||
}
|
||||
|
||||
int DOpassive()
|
||||
{
|
||||
passive = 1 - passive;
|
||||
|
||||
printf("Passive mode is now %s\n", (passive ? "ON" : "OFF"));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int DOsyst()
|
||||
{
|
||||
if(DOcmdcheck())
|
||||
return(0);
|
||||
|
||||
return(DOcommand("SYST", ""));
|
||||
}
|
||||
|
||||
int DOremotehelp()
|
||||
{
|
||||
if(!linkopen) {
|
||||
printf("You must \"OPEN\" a connection first.\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(DOcommand("HELP", ""));
|
||||
}
|
||||
|
||||
int DOquote()
|
||||
{
|
||||
int i;
|
||||
static char args[512];
|
||||
|
||||
args[0] = '\0';
|
||||
|
||||
for(i = 2; i < cmdargc; i++) {
|
||||
if(i != 2)
|
||||
strcat(args, " ");
|
||||
strcat(args, cmdargv[i]);
|
||||
}
|
||||
|
||||
return(DOcommand(cmdargv[1], args));
|
||||
}
|
||||
|
||||
int DOsite()
|
||||
{
|
||||
int i;
|
||||
static char args[512];
|
||||
|
||||
args[0] = '\0';
|
||||
|
||||
for(i = 1; i < cmdargc; i++) {
|
||||
if(i != 1)
|
||||
strcat(args, " ");
|
||||
strcat(args, cmdargv[i]);
|
||||
}
|
||||
|
||||
return(DOcommand("SITE", args));
|
||||
}
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
/* other.h
|
||||
*
|
||||
* This file is part of ftp.
|
||||
*
|
||||
*
|
||||
* 01/25/96 Initial Release Michael Temari, <temari@ix.netcom.com>
|
||||
*/
|
||||
|
||||
_PROTOTYPE(void FTPinit, (void));
|
||||
_PROTOTYPE(int DOpass, (void));
|
||||
_PROTOTYPE(int DOuser, (void));
|
||||
_PROTOTYPE(int DOnoop, (void));
|
||||
_PROTOTYPE(int DOpassive, (void));
|
||||
_PROTOTYPE(int DOsyst, (void));
|
||||
_PROTOTYPE(int DOremotehelp, (void));
|
||||
_PROTOTYPE(int DOquote, (void));
|
||||
_PROTOTYPE(int DOsite, (void));
|
||||
Reference in New Issue
Block a user