aboutsummaryrefslogtreecommitdiffstats
path: root/plpftp
diff options
context:
space:
mode:
authorFritz Elfert <felfert@to.com>2000-01-17 11:49:41 +0000
committerFritz Elfert <felfert@to.com>2000-01-17 11:49:41 +0000
commitab18114bfd38d4632c66401b5bc079241e27fab3 (patch)
tree14f9c1d5f020cf8ed2f205094ca9e2fc907bb969 /plpftp
parent6eceb82662300bf306e70bd943200665bc3c9bc3 (diff)
downloadplptools-ab18114bfd38d4632c66401b5bc079241e27fab3.tar.gz
plptools-ab18114bfd38d4632c66401b5bc079241e27fab3.tar.bz2
plptools-ab18114bfd38d4632c66401b5bc079241e27fab3.zip
Release of plptools-0.5
Diffstat (limited to 'plpftp')
-rw-r--r--plpftp/ftp.cc568
-rw-r--r--plpftp/ftp.h22
-rw-r--r--plpftp/main.cc36
3 files changed, 508 insertions, 118 deletions
diff --git a/plpftp/ftp.cc b/plpftp/ftp.cc
index 2341ce5..45ec2eb 100644
--- a/plpftp/ftp.cc
+++ b/plpftp/ftp.cc
@@ -32,10 +32,12 @@
#include <unistd.h>
#include <sys/time.h>
#include <sys/stat.h>
+#include <signal.h>
#include "defs.h"
#include "ftp.h"
-#include "rfsv32.h"
+#include "rfsv.h"
+#include "rpcs.h"
#include "bufferarray.h"
#include "bufferstore.h"
@@ -49,6 +51,12 @@ extern "C" {
}
#endif
+static char psionDir[1024];
+static rfsv *comp_a;
+static rpcs *comp_r;
+static int continueRunning;
+
+
void ftp::
resetUnixPwd()
{
@@ -59,8 +67,6 @@ resetUnixPwd()
ftp::ftp()
{
resetUnixPwd();
- strcpy(psionDir, DEFAULT_DRIVE);
- strcat(psionDir, DEFAULT_BASE_DIRECTORY);
}
ftp::~ftp()
@@ -68,29 +74,33 @@ ftp::~ftp()
}
void ftp::usage() {
- cerr << "Unknown command" << endl;
- cerr << " pwd" << endl;
- cerr << " ren <oldname> <newname>" << endl;
- cerr << " touch <psionfile>" << endl;
- cerr << " gtime <psionfile>" << endl;
- cerr << " test <psionfile>" << endl;
- cerr << " gattr <psionfile>" << endl;
- cerr << " sattr [[-|+]rhsa] <psionfile>" << endl;
- cerr << " devs" << endl;
- cerr << " dir|ls" << endl;
- cerr << " dircnt" << endl;
- cerr << " cd <dir>" << endl;
- cerr << " lcd <dir>" << endl;
- cerr << " !<system command>" << endl;
- cerr << " get <psionfile>" << endl;
- cerr << " put <unixfile>" << endl;
- cerr << " mget <shellpattern>" << endl;
- cerr << " mput <shellpattern>" << endl;
- cerr << " del|rm <psionfile>" << endl;
- cerr << " mkdir <psiondir>" << endl;
- cerr << " rmdir <psiondir>" << endl;
- cerr << " prompt" << endl;
- cerr << " bye" << endl;
+ cout << "Known FTP commands:" << endl << endl;
+ cout << " pwd" << endl;
+ cout << " ren <oldname> <newname>" << endl;
+ cout << " touch <psionfile>" << endl;
+ cout << " gtime <psionfile>" << endl;
+ cout << " test <psionfile>" << endl;
+ cout << " gattr <psionfile>" << endl;
+ cout << " sattr [[-|+]rhsa] <psionfile>" << endl;
+ cout << " devs" << endl;
+ cout << " dir|ls" << endl;
+ cout << " dircnt" << endl;
+ cout << " cd <dir>" << endl;
+ cout << " lcd <dir>" << endl;
+ cout << " !<system command>" << endl;
+ cout << " get <psionfile>" << endl;
+ cout << " put <unixfile>" << endl;
+ cout << " mget <shellpattern>" << endl;
+ cout << " mput <shellpattern>" << endl;
+ cout << " del|rm <psionfile>" << endl;
+ cout << " mkdir <psiondir>" << endl;
+ cout << " rmdir <psiondir>" << endl;
+ cout << " prompt" << endl;
+ cout << " hash" << endl;
+ cout << " bye" << endl;
+ cout << endl << "Known RPC commands:" << endl << endl;
+ cout << " ps" << endl;
+ cout << " kill <pid|'all'>" << endl;
}
static int Wildmat(const char *s, char *p);
@@ -146,8 +156,36 @@ Wildmat(const char *s, char *p)
return (*s == '\0');
}
+static int
+checkAbortNoHash(long)
+{
+ return continueRunning;
+}
+
+static int
+checkAbortHash(long)
+{
+ if (continueRunning) {
+ printf("#"); fflush(stdout);
+ }
+ return continueRunning;
+}
+
+static void
+sigint_handler(int i) {
+ continueRunning = 0;
+ signal(SIGINT, sigint_handler);
+}
+
+static void
+sigint_handler2(int i) {
+ continueRunning = 0;
+ fclose(stdin);
+ signal(SIGINT, sigint_handler2);
+}
+
int ftp::
-session(rfsv32 & a, int xargc, char **xargv)
+session(rfsv & a, rpcs & r, int xargc, char **xargv)
{
int argc;
char *argv[10];
@@ -155,6 +193,8 @@ session(rfsv32 & a, int xargc, char **xargv)
char f2[256];
long res;
bool prompt = true;
+ bool hash = false;
+ cpCallback_t cab = checkAbortNoHash;
bool once = false;
if (xargc > 1) {
@@ -163,15 +203,107 @@ session(rfsv32 & a, int xargc, char **xargv)
for (int i = 0; i < argc; i++)
argv[i] = xargv[i+1];
}
+ if (!once) {
+ bufferArray b;
+ if (!r.getOwnerInfo(b)) {
+ int machType;
+ r.getMachineType(machType);
+ cout << "Connected to ";
+ switch (machType) {
+ case rpcs::PSI_MACH_UNKNOWN:
+ cout << "an unknown Device";
+ break;
+ case rpcs::PSI_MACH_PC:
+ cout << "a PC";
+ break;
+ case rpcs::PSI_MACH_MC:
+ cout << "a MC";
+ break;
+ case rpcs::PSI_MACH_HC:
+ cout << "a HC";
+ break;
+ case rpcs::PSI_MACH_S3:
+ cout << "a Serie 3";
+ break;
+ case rpcs::PSI_MACH_S3A:
+ cout << "a Series 3a, 3c or 3mx";
+ break;
+ case rpcs::PSI_MACH_WORKABOUT:
+ cout << "a Workabout";
+ break;
+ case rpcs::PSI_MACH_SIENNA:
+ cout << "a Sienna";
+ break;
+ case rpcs::PSI_MACH_S3C:
+ cout << "a Series 3c";
+ break;
+ case rpcs::PSI_MACH_S5:
+ cout << "a Series 5";
+ break;
+ case rpcs::PSI_MACH_WINC:
+ cout << "a WinC";
+ break;
+ default:
+ cout << "an undefined Device";
+ break;
+ }
+ cout << ", OwnerInfo:" << endl;
+ while (!b.empty())
+ cout << " " << b.pop().getString() << endl;
+ cout << endl;
+ }
+ }
+
+ if (!strcmp(DDRIVE, "AUTO")) {
+ long devbits;
+ long vtotal, vfree, vattr, vuniqueid;
+ int i;
+
+ strcpy(defDrive, "::");
+ if (a.devlist(&devbits) == 0) {
+
+ for (i = 0; i < 26; i++) {
+ if ((devbits & 1) && a.devinfo(i, &vfree, &vtotal, &vattr, &vuniqueid)) {
+ defDrive[0] = 'A' + i;
+ break;
+ }
+ devbits >>= 1;
+ }
+ }
+ if (!strcmp(defDrive, "::")) {
+ cerr << "FATAL: Couln't find default Drive" << endl;
+ return -1;
+ }
+ } else
+ strcpy(defDrive, DDRIVE);
+ strcpy(psionDir, defDrive);
+ strcat(psionDir, DBASEDIR);
+ comp_a = &a;
+ if (!once) {
+ cout << "Psion dir is: \"" << psionDir << "\"" << endl;
+ initReadline();
+ }
+ continueRunning = 1;
+ signal(SIGINT, sigint_handler);
do {
if (!once)
getCommand(argc, argv);
+ if (!strcmp(argv[0], "help")) {
+ usage();
+ continue;
+ }
if (!strcmp(argv[0], "prompt")) {
prompt = !prompt;
cout << "Prompting now " << (prompt?"on":"off") << endl;
continue;
}
+ if (!strcmp(argv[0], "hash")) {
+ hash = !hash;
+ cout << "Hash printing now " << (hash?"on":"off") << endl;
+ cab = (hash) ? checkAbortHash : checkAbortNoHash;
+ continue;
+ }
if (!strcmp(argv[0], "pwd")) {
cout << "Local dir: \"" << localDir << "\"" << endl;
cout << "Psion dir: \"" << psionDir << "\"" << endl;
@@ -199,6 +331,17 @@ session(rfsv32 & a, int xargc, char **xargv)
strcat(f1, argv[1]);
if ((res = a.fgeteattr(f1, &attr, &size, &time)) != 0)
errprint(res, a);
+ else {
+ // never used to do this
+ char dateBuff[100];
+ struct tm *t;
+ t = localtime(&time);
+ strftime(dateBuff, 100, "%c", t);
+ cout << a.opAttr(attr);
+ cout << " " << dec << setw(10) << setfill(' ') << size;
+ cout << " " << dateBuff;
+ cout << " " << argv[1] << endl;
+ }
continue;
}
if (!strcmp(argv[0], "gattr") && (argc == 2)) {
@@ -207,11 +350,13 @@ session(rfsv32 & a, int xargc, char **xargv)
strcat(f1, argv[1]);
if ((res = a.fgetattr(f1, &attr)) != 0)
errprint(res, a);
- else
- cout << hex << setw(4) << setfill('0') << attr << endl;
+ else {
+ cout << hex << setw(4) << setfill('0') << attr;
+ cout << " (" << a.opAttr(attr) << ")" << endl;
+ }
continue;
}
- if (!strcmp(argv[0], "gtime")) {
+ if (!strcmp(argv[0], "gtime") && (argc == 2)) {
long mtime;
strcpy(f1, psionDir);
strcat(f1, argv[1]);
@@ -226,7 +371,7 @@ session(rfsv32 & a, int xargc, char **xargv)
}
continue;
}
- if (!strcmp(argv[0], "sattr")) {
+ if (!strcmp(argv[0], "sattr") && (argc == 2)) {
long attr[2];
int aidx = 0;
char *p = argv[1];
@@ -287,7 +432,8 @@ session(rfsv32 & a, int xargc, char **xargv)
if (vname != NULL) {
cout << (char) ('A' + i) << " " <<
hex << setw(4) << setfill('0') << vattr << " " <<
- setw(12) << setfill(' ') << setiosflags(ios::left) << vname << resetiosflags(ios::left) << dec << setw(9) <<
+ setw(12) << setfill(' ') << setiosflags(ios::left) <<
+ vname << resetiosflags(ios::left) << dec << setw(9) <<
vtotal << setw(9) << vfree << setw(10) << vuniqueid << endl;
free(vname);
}
@@ -298,14 +444,14 @@ session(rfsv32 & a, int xargc, char **xargv)
errprint(res, a);
continue;
}
- if ((!strcmp(argv[0], "ls")) || (!strcmp(argv[0], "dir"))) {
+ if (!strcmp(argv[0], "ls") || !strcmp(argv[0], "dir")) {
bufferArray files;
if ((res = a.dir(psionDir, &files)) != 0)
errprint(res, a);
else
while (!files.empty()) {
bufferStore s;
- s = files.popBuffer();
+ s = files.pop();
long date = s.getDWord(0);
long size = s.getDWord(4);
long attr = s.getDWord(8);
@@ -313,15 +459,7 @@ session(rfsv32 & a, int xargc, char **xargv)
struct tm *t;
t = localtime(&date);
strftime(dateBuff, 100, "%c", t);
- cout << ((attr & rfsv32::PSI_ATTR_DIRECTORY) ? "d" : "-");
- cout << ((attr & rfsv32::PSI_ATTR_RONLY) ? "-" : "w");
- cout << ((attr & rfsv32::PSI_ATTR_HIDDEN) ? "h" : "-");
- cout << ((attr & rfsv32::PSI_ATTR_SYSTEM) ? "s" : "-");
- cout << ((attr & rfsv32::PSI_ATTR_ARCHIVE) ? "a" : "-");
- cout << ((attr & rfsv32::PSI_ATTR_VOLUME) ? "v" : "-");
- cout << ((attr & rfsv32::PSI_ATTR_NORMAL) ? "n" : "-");
- cout << ((attr & rfsv32::PSI_ATTR_TEMPORARY) ? "t" : "-");
- cout << ((attr & rfsv32::PSI_ATTR_COMPRESSED) ? "c" : "-");
+ cout << a.opAttr(attr);
cout << " " << dec << setw(10) << setfill(' ') << size;
cout << " " << dateBuff;
cout << " " << s.getString(12) << endl;
@@ -332,9 +470,10 @@ session(rfsv32 & a, int xargc, char **xargv)
if (argc == 1)
resetUnixPwd();
else {
- if (chdir(argv[1]) == 0)
- strcpy(localDir, argv[1]);
- else
+ if (chdir(argv[1]) == 0) {
+ getcwd(localDir, sizeof(localDir));
+ strcat(localDir, "/");
+ } else
cerr << "No such directory" << endl
<< "Keeping original directory \"" << localDir << "\"" << endl;
}
@@ -342,8 +481,8 @@ session(rfsv32 & a, int xargc, char **xargv)
}
if (!strcmp(argv[0], "cd")) {
if (argc == 1) {
- strcpy(psionDir, DEFAULT_DRIVE);
- strcat(psionDir, DEFAULT_BASE_DIRECTORY);
+ strcpy(psionDir, defDrive);
+ strcat(psionDir, DBASEDIR);
} else {
long tmp;
if (!strcmp(argv[1], "..")) {
@@ -369,10 +508,16 @@ session(rfsv32 & a, int xargc, char **xargv)
}
if ((f1[strlen(f1) -1] != '/') && (f1[strlen(f1) -1] != '\\'))
strcat(f1,"\\");
- if ((res = a.dircount(f1, &tmp)) == 0)
+ if ((res = a.dircount(f1, &tmp)) == 0) {
+ for (char *p = f1; *p; p++)
+ if (*p == '/')
+ *p = '\\';
strcpy(psionDir, f1);
- else
+ }
+ else {
+ errprint(res, a);
cerr << "Keeping original directory \"" << psionDir << "\"" << endl;
+ }
}
continue;
}
@@ -389,9 +534,14 @@ session(rfsv32 & a, int xargc, char **xargv)
else
strcat(f2, argv[2]);
gettimeofday(&stime, 0L);
- if ((res = a.copyFromPsion(f1, f2)) != 0)
+ if ((res = a.copyFromPsion(f1, f2, cab)) != 0) {
+ if (hash)
+ cout << endl;
+ continueRunning = 1;
errprint(res, a);
- else {
+ } else {
+ if (hash)
+ cout << endl;
gettimeofday(&etime, 0L);
long dsec = etime.tv_sec - stime.tv_sec;
long dhse = (etime.tv_usec / 10000) -
@@ -419,7 +569,7 @@ session(rfsv32 & a, int xargc, char **xargv)
}
while (!files.empty()) {
bufferStore s;
- s = files.popBuffer();
+ s = files.pop();
char temp[100];
long attr = s.getDWord(8);
@@ -441,23 +591,29 @@ session(rfsv32 & a, int xargc, char **xargv)
} while (temp[1] != 0 || (temp[0] != 'y' && temp[0] != 'n'));
if (temp[0] != 'n') {
strcpy(f1, psionDir);
- strcat(f1, s.getString());
+ strcat(f1, s.getString(12));
strcpy(f2, localDir);
- strcat(f2, s.getString());
+ strcat(f2, s.getString(12));
if (temp[0] == 'l') {
for (char *p = f2; *p; p++)
*p = tolower(*p);
}
- if ((res = a.copyFromPsion(f1, f2)) != 0) {
+ if ((res = a.copyFromPsion(f1, f2, cab)) != 0) {
+ if (hash)
+ cout << endl;
+ continueRunning = 1;
errprint(res, a);
break;
- } else
+ } else {
+ if (hash)
+ cout << endl;
cout << "Transfer complete\n";
+ }
}
}
continue;
}
- if (!strcmp(argv[0], "put")) {
+ if (!strcmp(argv[0], "put") && (argc >= 2)) {
struct timeval stime;
struct timeval etime;
struct stat stbuf;
@@ -470,9 +626,14 @@ session(rfsv32 & a, int xargc, char **xargv)
else
strcat(f2, argv[2]);
gettimeofday(&stime, 0L);
- if ((res = a.copyToPsion(f1, f2)) != 0)
+ if ((res = a.copyToPsion(f1, f2, cab)) != 0) {
+ if (hash)
+ cout << endl;
+ continueRunning = 1;
errprint(res, a);
- else {
+ } else {
+ if (hash)
+ cout << endl;
gettimeofday(&etime, 0L);
long dsec = etime.tv_sec - stime.tv_sec;
long dhse = (etime.tv_usec / 10000) -
@@ -526,11 +687,17 @@ session(rfsv32 & a, int xargc, char **xargv)
if (temp[0] == 'y') {
strcpy(f2, psionDir);
strcat(f2, de->d_name);
- if ((res = a.copyToPsion(f1, f2)) != 0) {
+ if ((res = a.copyToPsion(f1, f2, cab)) != 0) {
+ if (hash)
+ cout << endl;
+ continueRunning = 1;
errprint(res, a);
break;
- } else
+ } else {
+ if (hash)
+ cout << endl;
cout << "Transfer complete\n";
+ }
}
}
} while (de);
@@ -539,22 +706,22 @@ session(rfsv32 & a, int xargc, char **xargv)
cerr << "Error in directory name \"" << localDir << "\"\n";
continue;
}
- if (!strcmp(argv[0], "del") ||
- !strcmp(argv[0], "rm")) {
+ if ((!strcmp(argv[0], "del") ||
+ !strcmp(argv[0], "rm")) && (argc == 2)) {
strcpy(f1, psionDir);
strcat(f1, argv[1]);
if ((res = a.remove(f1)) != 0)
errprint(res, a);
continue;
}
- if (!strcmp(argv[0], "mkdir")) {
+ if (!strcmp(argv[0], "mkdir") && (argc == 2)) {
strcpy(f1, psionDir);
strcat(f1, argv[1]);
if ((res = a.mkdir(f1)) != 0)
errprint(res, a);
continue;
}
- if (!strcmp(argv[0], "rmdir")) {
+ if (!strcmp(argv[0], "rmdir") && (argc == 2)) {
strcpy(f1, psionDir);
strcat(f1, argv[1]);
if ((res = a.rmdir(f1)) != 0)
@@ -568,79 +735,274 @@ session(rfsv32 & a, int xargc, char **xargv)
strcat(cmd, " ");
strcat(cmd, argv[i]);
}
- system(cmd);
+ if (strlen(cmd))
+ system(cmd);
+ else {
+ char *sh;
+ cout << "Starting subshell ...\n";
+ sh = getenv("SHELL");
+ if (!sh)
+ sh = "/bin/sh";
+ system(sh);
+ }
+ continue;
+ }
+ // RPCS commands
+ // if (!strcmp(argv[0], "xxx")) {
+ // r.configOpen();
+ // continue;
+ // }
+ if (!strcmp(argv[0], "run") && (argc >= 2)) {
+ char argbuf[1024];
+ char cmdbuf[1024];
+
+ argbuf[0] = 0;
+ for (int i = 2; i < argc; i++) {
+ if (i > 2) {
+ strcat(argbuf, " ");
+ strcat(argbuf, argv[i]);
+ } else
+ strcpy(argbuf, argv[i]);
+ }
+ if (argv[1][1] != ':') {
+ strcpy(cmdbuf, psionDir);
+ strcat(cmdbuf, argv[1]);
+ } else
+ strcpy(cmdbuf, argv[1]);
+ r.execProgram(cmdbuf, argbuf);
+ continue;
+ }
+ if (!strcmp(argv[0], "kill") && (argc >= 2)) {
+ bufferArray tmp, tmp2;
+ bool anykilled = false;
+ r.queryDrive('C', tmp);
+ tmp2 = tmp;
+ for (int i = 1; i < argc; i++) {
+ int kpid;
+ tmp = tmp2;
+ if (!strcmp(argv[i], "all"))
+ kpid = -1;
+ else
+ sscanf(argv[i], "%d", &kpid);
+ while (!tmp.empty()) {
+ bufferStore bs = tmp.pop();
+ tmp.pop();
+ int pid = bs.getWord(0);
+ const char *proc = bs.getString(2);
+ if (kpid == -1 || kpid == pid) {
+ char pbuf[128];
+ sprintf(pbuf, "%s.$%d", proc, pid);
+ r.stopProgram(pbuf);
+ anykilled = true;
+ }
+ }
+ if (kpid == -1)
+ break;
+ }
+ if (!anykilled)
+ cerr << "no such process" << endl;
+ continue;
+ }
+ if (!strcmp(argv[0], "ps")) {
+ bufferArray tmp;
+ r.queryDrive('C', tmp);
+ cout << "PID CMD ARGS" << endl;
+ while (!tmp.empty()) {
+ bufferStore bs = tmp.pop();
+ bufferStore bs2 = tmp.pop();
+ int pid = bs.getWord(0);
+ const char *proc = bs.getString(2);
+ const char *arg = bs2.getString();
+
+ printf("%5d %-12s %s\n", pid, proc, arg);
+ }
continue;
}
if (strcmp(argv[0], "bye") && strcmp(argv[0], "quit"))
- usage();
- } while (strcmp(argv[0], "bye") && strcmp(argv[0], "quit") && !once);
+ cerr << "syntax error. Try \"help\"" << endl;
+ } while (strcmp(argv[0], "bye") && strcmp(argv[0], "quit") && !once &&
+ continueRunning);
return a.getStatus();
}
void ftp::
-errprint(long errcode, rfsv32 & a) {
+errprint(long errcode, rfsv & a) {
cerr << "Error: " << a.opErr(errcode) << endl;
}
-int ftp::
-convertName(const char *orig, char *retVal)
+#if HAVE_LIBREADLINE
+static char *all_commands[] = {
+ "pwd", "ren", "touch", "gtime", "test", "gattr", "sattr", "devs",
+ "dir", "ls", "dircnt", "cd", "lcd", "get", "put", "mget", "mput",
+ "del", "rm", "mkdir", "rmdir", "prompt", "bye", "ps", "kill", "run", NULL
+};
+
+static char *localfile_commands[] = {
+ "lcd ", "put ", "mput ", NULL
+};
+
+static char *remote_dir_commands[] = {
+ "cd ", "rmdir ", NULL
+};
+
+static bufferArray *comp_files = NULL;
+static long maskAttr;
+
+static char*
+filename_generator(char *text, int state)
{
- int len = strlen(orig);
- char *temp = new char[len + 1];
-
- for (int i = 0; i <= len; i++) {
- if (orig[i] == '/')
- temp[i] = '\\';
- else
- temp[i] = orig[i];
+ static int len;
+
+
+ if (!state) {
+ long res;
+ len = strlen(text);
+ if (comp_files)
+ delete comp_files;
+ comp_files = new bufferArray();
+ if ((res = comp_a->dir(psionDir, comp_files)) != 0) {
+ cerr << "Error: " << comp_a->opErr(res) << endl;
+ return NULL;
+ }
}
- if (len == 0 || temp[1] != ':') {
- // We can automatically supply a drive letter
- strcpy(retVal, DEFAULT_DRIVE);
+ while (!comp_files->empty()) {
+ bufferStore s;
+ s = comp_files->pop();
+ long attr = s.getDWord(8);
- if (len == 0 || temp[0] != '\\') {
- strcat(retVal, DEFAULT_BASE_DIRECTORY);
- } else {
- retVal[strlen(retVal) - 1] = 0;
+ if ((attr & maskAttr) == 0)
+ continue;
+ if (!(strncmp(s.getString(12), text, len))) {
+ char fnbuf[512];
+ strcpy(fnbuf, s.getString(12));
+ if (attr & 0x10)
+ strcat(fnbuf, "/");
+ return (strdup(fnbuf));
}
+ }
+ return NULL;
+}
- strcat(retVal, temp);
- } else {
- strcpy(retVal, temp);
+static char *
+command_generator(char *text, int state)
+{
+ static int idx, len;
+ char *name;
+
+ if (!state) {
+ idx = 0;
+ len = strlen(text);
}
- delete[]temp;
+ while ((name = all_commands[idx])) {
+ idx++;
+ if (!strncmp(name, text, len))
+ return (strdup(name));
+ }
+ return NULL;
+}
+
+static int
+null_completion() {
return 0;
}
+static char **
+do_completion(char *text, int start, int end)
+{
+ char **matches = NULL;
+
+ rl_completion_entry_function = (Function *)null_completion;
+ if (start == 0)
+ matches = completion_matches(text, command_generator);
+ else {
+ int idx = 0;
+ char *name;
+
+ rl_filename_quoting_desired = 1;
+ while ((name = localfile_commands[idx])) {
+ idx++;
+ if (!strncmp(name, rl_line_buffer, strlen(name))) {
+ rl_completion_entry_function = NULL;
+ return NULL;
+ }
+ }
+ maskAttr = 0xffff;
+ idx = 0;
+ while ((name = remote_dir_commands[idx])) {
+ idx++;
+ if (!strncmp(name, rl_line_buffer, strlen(name)))
+ maskAttr = 0x0010;
+ }
+
+ matches = completion_matches(text, filename_generator);
+ }
+ return matches;
+}
+#endif
+
+void ftp::
+initReadline(void)
+{
+#if HAVE_LIBREADLINE
+ rl_readline_name = "plpftp";
+ rl_completion_entry_function = (Function *)null_completion;
+ rl_attempted_completion_function = (CPPFunction *)do_completion;
+#endif
+}
+
void ftp::
getCommand(int &argc, char **argv)
{
- int ws;
- char *bp;
+ int ws, quote;
static char buf[1024];
buf[0] = 0; argc = 0;
- while (!strlen(buf)) {
- bp = readline("> ");
+ while (!strlen(buf) && continueRunning) {
+ signal(SIGINT, sigint_handler2);
+#if HAVE_LIBREADLINE
+ char *bp = readline("> ");
if (!bp) {
strcpy(buf, "bye");
cout << buf << endl;
} else {
strcpy(buf, bp);
+#if HAVE_LIBHISTORY
add_history(buf);
+#endif
free(bp);
}
+#else
+ cout << "> ";
+ cout.flush();
+ cin.getline(buf, 1023);
+ if (cin.eof()) {
+ strcpy(buf, "bye");
+ cout << buf << endl;
+ }
+#endif
+ signal(SIGINT, sigint_handler);
}
- ws = 1;
+ ws = 1; quote = 0;
for (char *p = buf; *p; p++)
- if ((*p == ' ') || (*p == '\t')) {
- ws = 1;
- *p = 0;
- } else {
- if (ws)
- argv[argc++] = p;
- ws = 0;
+ switch (*p) {
+ case ' ':
+ case '\t':
+ if (!quote) {
+ ws = 1;
+ *p = 0;
+ }
+ break;
+ case '"':
+ quote = 1 - quote;
+ if (!quote)
+ *p = 0;
+ break;
+ default:
+ if (ws) {
+ argv[argc++] = p;
+ }
+ ws = 0;
}
}
diff --git a/plpftp/ftp.h b/plpftp/ftp.h
index 38edf40..a89fd62 100644
--- a/plpftp/ftp.h
+++ b/plpftp/ftp.h
@@ -27,33 +27,39 @@
#include "bool.h"
-class rfsv32;
+class rfsv;
+class rpcs;
class bufferStore;
class bufferArray;
-#define DEFAULT_DRIVE "C:"
-#define DEFAULT_BASE_DIRECTORY "\\"
-
class ftp {
public:
ftp();
~ftp();
- int session(rfsv32 & a, int xargc, char **xargv);
+ int session(rfsv & a, rpcs & r, int xargc, char **xargv);
private:
void getCommand(int &argc, char **argv);
+ void initReadline(void);
// utilities
bool unixDirExists(const char *dir);
void getUnixDir(bufferArray & files);
void resetUnixPwd();
void usage();
- void errprint(long errcode, rfsv32 & a);
+ void errprint(long errcode, rfsv & a);
void cd(const char *source, const char *cdto, char *dest);
- int convertName(const char *orig, char *retVal);
+ // MJG: note, this isn't actually used anywhere
+ int convertName(const char *orig, char *retVal);
+#ifdef HAVE_READLINE
+ char *filename_generator(char *, int);
+ char *command_generator(char *, int);
+ char **do_completion(char *, int, int);
+#endif
+ char defDrive[9];
char localDir[1024];
- char psionDir[1024];
+ // char psionDir[1024];
};
#endif
diff --git a/plpftp/main.cc b/plpftp/main.cc
index 816c58a..8d00574 100644
--- a/plpftp/main.cc
+++ b/plpftp/main.cc
@@ -31,7 +31,10 @@
#include "defs.h"
#include "bool.h"
#include "ppsocket.h"
-#include "rfsv32.h"
+#include "rfsv.h"
+#include "rfsvfactory.h"
+#include "rpcs.h"
+#include "rpcsfactory.h"
#include "ftp.h"
#include "bufferstore.h"
@@ -48,6 +51,7 @@ ftpHeader()
cout << "PLPFTP Version " << VERSION;
cout << " Copyright (C) 1999 Philip Proudman" << endl;
cout << " Additions Copyright (C) 1999 Fritz Elfert <felfert@to.com>" << endl;
+ cout << " & (C) 1999 Matt Gumbley <matt@gumbley.demon.co.uk>" << endl;
cout << "PLP comes with ABSOLUTELY NO WARRANTY;" << endl;
cout << "This is free software, and you are welcome to redistribute it" << endl;
cout << "under GPL conditions; see the COPYING file in the distribution." << endl;
@@ -59,7 +63,9 @@ int
main(int argc, char **argv)
{
ppsocket *skt;
- rfsv32 *a;
+ ppsocket *skt2;
+ rfsv *a;
+ rpcs *r;
ftp f;
int status = 0;
sigset_t sigset;
@@ -80,10 +86,26 @@ main(int argc, char **argv)
if (argc < 2)
ftpHeader();
skt = new ppsocket();
- skt->connect(NULL, sockNum);
- a = new rfsv32(skt);
- status = f.session(*a, argc, argv);
-
- delete a;
+ if (!skt->connect(NULL, sockNum)) {
+ cout << "plpftp: could not connect to ncpd" << endl;
+ return 1;
+ }
+ skt2 = new ppsocket();
+ if (!skt2->connect(NULL, sockNum)) {
+ cout << "plpftp: could not connect to ncpd" << endl;
+ return 1;
+ }
+ rfsvfactory *rf = new rfsvfactory(skt);
+ rpcsfactory *rp = new rpcsfactory(skt2);
+ a = rf->create(false);
+ r = rp->create(false);
+ if ((a != NULL) && (r != NULL)) {
+ status = f.session(*a, *r, argc, argv);
+ delete r;
+ delete a;
+ } else {
+ cout << "plpftp: could not create rfsv object" << endl;
+ status = 1;
+ }
return status;
}