From f3e248b6e75c7ce5beda577f5712915417313b0a Mon Sep 17 00:00:00 2001 From: Fritz Elfert Date: Tue, 29 Jun 1999 02:21:40 +0000 Subject: Initial import. --- plpftp/Makefile.am | 7 + plpftp/ftp.cc | 585 +++++++++++++++++++++++++++++++++++++++++++++++++++++ plpftp/ftp.h | 35 ++++ plpftp/main.cc | 120 +++++++++++ 4 files changed, 747 insertions(+) create mode 100644 plpftp/Makefile.am create mode 100644 plpftp/ftp.cc create mode 100644 plpftp/ftp.h create mode 100644 plpftp/main.cc (limited to 'plpftp') diff --git a/plpftp/Makefile.am b/plpftp/Makefile.am new file mode 100644 index 0000000..15dc197 --- /dev/null +++ b/plpftp/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES=-I../lib + +plpftp_LDADD = -L../lib -lutils + +bin_PROGRAMS = plpftp + +plpftp_SOURCES = ftp.cc main.cc diff --git a/plpftp/ftp.cc b/plpftp/ftp.cc new file mode 100644 index 0000000..3c915e3 --- /dev/null +++ b/plpftp/ftp.cc @@ -0,0 +1,585 @@ +// +// PLP - An implementation of the PSION link protocol +// +// Copyright (C) 1999 Philip Proudman +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// e-mail philip.proudman@btinternet.com + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defs.h" +#include "ftp.h" +#include "rfsv32.h" +#include "bufferarray.h" +#include "bufferstore.h" + +#if HAVE_LIBREADLINE +extern "C" { +#include +#include +#if HAVE_LIBHISTORY +#include +#endif +} +#endif + +void ftp:: +resetUnixPwd() +{ + getcwd(localDir, 500); + strcat(localDir, "/"); +} + +ftp::ftp() +{ + resetUnixPwd(); + strcpy(psionDir, DEFAULT_DRIVE); + strcat(psionDir, DEFAULT_BASE_DIRECTORY); +} + +ftp::~ftp() +{ +} + +void ftp::usage() { + cerr << "Unknown command" << endl; + cerr << " pwd" << endl; + cerr << " ren " << endl; + cerr << " touch " << endl; + cerr << " gtime " << endl; + cerr << " test " << endl; + cerr << " gattr " << endl; + cerr << " sattr [[-|+]rhsa] " << endl; + cerr << " devs" << endl; + cerr << " dir|ls" << endl; + cerr << " dircnt" << endl; + cerr << " cd " << endl; + cerr << " lcd " << endl; + cerr << " !" << endl; + cerr << " get " << endl; + cerr << " put " << endl; + cerr << " mget (works on whole directory, interactively, no wildcarding)" << endl; + cerr << " mput (works on whole directory, interactively, no wildcarding)" << endl; + cerr << " del|rm " << endl; + cerr << " mkdir " << endl; + cerr << " rmdir " << endl; + cerr << " bye" << endl; +} + +int ftp:: +session(rfsv32 & a, int xargc, char **xargv) +{ + int argc; + char *argv[10]; + char f1[256]; + char f2[256]; + long res; + int once = 0; + + if (xargc > 0) { + once = 1; + argc = (xargc<10)?xargc:10; + for (int i = 0; i < argc; i++) + argv[i] = xargv[i+1]; + } + do { + if (!once) + getCommand(argc, argv); + + if (!strcmp(argv[0], "pwd")) { + cout << "Local dir: \"" << localDir << "\"" << endl; + cout << "Psion dir: \"" << psionDir << "\"" << endl; + continue; + } + if (!strcmp(argv[0], "ren") && (argc == 3)) { + strcpy(f1, psionDir); + strcat(f1, argv[1]); + strcpy(f2, psionDir); + strcat(f2, argv[2]); + if ((res = a.rename(f1, f2)) != 0) + errprint(res, a); + continue; + } + if (!strcmp(argv[0], "touch") && (argc == 2)) { + strcpy(f1, psionDir); + strcat(f1, argv[1]); + if ((res = a.fsetmtime(f1, time(0))) != 0) + errprint(res, a); + continue; + } + if (!strcmp(argv[0], "test") && (argc == 2)) { + long attr, size, time; + strcpy(f1, psionDir); + strcat(f1, argv[1]); + if ((res = a.fgeteattr(f1, &attr, &size, &time)) != 0) + errprint(res, a); + continue; + } + if (!strcmp(argv[0], "gattr") && (argc == 2)) { + long attr; + strcpy(f1, psionDir); + strcat(f1, argv[1]); + if ((res = a.fgetattr(f1, &attr)) != 0) + errprint(res, a); + else + cout << hex << setw(4) << setfill('0') << attr << endl; + continue; + } + if (!strcmp(argv[0], "gtime")) { + long mtime; + strcpy(f1, psionDir); + strcat(f1, argv[1]); + if ((res = a.fgetmtime(f1, &mtime)) != 0) + errprint(res, a); + else { + char dateBuff[100]; + struct tm *t; + t = localtime(&mtime); + strftime(dateBuff, 100, "%c %Z", t); + cout << dateBuff << endl; + } + continue; + } + if (!strcmp(argv[0], "sattr")) { + long attr[2]; + int aidx = 0; + char *p = argv[1]; + + strcpy(f1, psionDir); + strcat(f1, argv[2]); + + attr[0] = attr[1] = 0; + while (*p) { + switch (*p) { + case '+': + aidx = 0; + break; + case '-': + aidx = 1; + break; + case 'r': + attr[aidx] |= 0x01; + attr[1 - aidx] &= ~0x01; + break; + case 'h': + attr[aidx] |= 0x02; + attr[1 - aidx] &= ~0x02; + break; + case 's': + attr[aidx] |= 0x04; + attr[1 - aidx] &= ~0x04; + break; + case 'a': + attr[aidx] |= 0x20; + attr[1 - aidx] &= ~0x20; + break; + } + p++; + } + if ((res = a.fsetattr(f1, attr[0], attr[1])) != 0) + errprint(res, a); + continue; + } + if (!strcmp(argv[0], "dircnt")) { + long cnt; + if ((res = a.dircount(psionDir, &cnt)) != 0) + errprint(res, a); + else + cout << cnt << " Entries" << endl; + continue; + } + if (!strcmp(argv[0], "devs")) { + long devbits; + if ((res = a.devlist(&devbits)) == 0) { + cout << "Drive Type Volname Total Free UniqueID" << endl; + for (int i = 0; i < 26; i++) { + char *vname; + long vtotal, vfree, vattr, vuniqueid; + + if ((devbits & 1) != 0) { + vname = a.devinfo(i, &vfree, &vtotal, &vattr, &vuniqueid); + if (vname != NULL) { + cout << (char) ('A' + i) << " " << + hex << setw(4) << setfill('0') << vattr << " " << + setw(12) << setfill(' ') << vname << dec << setw(9) << + vtotal << setw(9) << vfree << setw(10) << vuniqueid << endl; + free(vname); + } + } + devbits >>= 1; + } + } else + errprint(res, a); + continue; + } + if ((!strcmp(argv[0], "ls")) || (!strcmp(argv[0], "dir"))) { + if ((res = a.dir(psionDir, NULL)) != 0) + errprint(res, a); + continue; + } + if (!strcmp(argv[0], "lcd")) { + if (argc == 1) + resetUnixPwd(); + else { + if (chdir(argv[1]) == 0) + strcpy(localDir, argv[1]); + else + cerr << "No such directory" << endl + << "Keeping original directory \"" << localDir << "\"" << endl; + } + continue; + } + if (!strcmp(argv[0], "cd")) { + if (argc == 1) { + strcpy(psionDir, DEFAULT_DRIVE); + strcat(psionDir, DEFAULT_BASE_DIRECTORY); + } else { + long tmp; + if (!strcmp(argv[1], "..")) { + strcpy(f1, psionDir); + char *p = f1 + strlen(f1); + if (p > f1) + p--; + *p = '\0'; + while ((p > f1) && (*p != '/') && (*p != '\\')) + p--; + *(++p) = '\0'; + if (strlen(f1) < 3) { + strcpy(f1, psionDir); + f1[3] = '\0'; + } + } else { + if ((argv[1][0] != '/') && (argv[1][0] != '\\') && + (argv[1][1] != ':')) { + strcpy(f1, psionDir); + strcat(f1, argv[1]); + } else + strcpy(f1, argv[1]); + } + if ((f1[strlen(f1) -1] != '/') && (f1[strlen(f1) -1] != '\\')) + strcat(f1,"\\"); + if ((res = a.dircount(f1, &tmp)) == 0) + strcpy(psionDir, f1); + else + cerr << "Keeping original directory \"" << psionDir << "\"" << endl; + } + continue; + } + if (!strcmp(argv[0], "get")) { + struct timeval stime; + struct timeval etime; + struct stat stbuf; + + strcpy(f1, psionDir); + strcat(f1, argv[1]); + strcpy(f2, localDir); + if (argc == 2) + strcat(f2, argv[1]); + else + strcat(f2, argv[2]); + gettimeofday(&stime, 0L); + if ((res = a.copyFromPsion(f1, f2)) != 0) + errprint(res, a); + else { + gettimeofday(&etime, 0L); + long dsec = etime.tv_sec - stime.tv_sec; + long dhse = (etime.tv_usec / 10000) - + (stime.tv_usec /10000); + if (dhse < 0) { + dsec--; + dhse = 100 + dhse; + } + float dt = dhse; + dt /= 100.0; + dt += dsec; + stat(f2, &stbuf); + float cps = (float)(stbuf.st_size) / dt; + cout << "Transfer complete, (" << stbuf.st_size + << " bytes in " << dsec << "." + << dhse << " secs = " << cps << " cps)\n"; + } + continue; + } else if (!strcmp(argv[0], "mget")) { + bufferArray files; + if ((res = a.dir(psionDir, &files)) != 0) { + errprint(res, a); + continue; + } + while (!files.empty()) { + bufferStore s; + s = files.popBuffer(); + char temp[100]; + long attr = s.getDWord(8); + + if (attr & 0x10) + continue; + do { + cout << "Get \"" << s.getString(12) << "\" y,n, or l (lowercase filename): "; + cout.flush(); + cin.getline(temp, 100); + } while (temp[1] != 0 || (temp[0] != 'y' && temp[0] != 'n' && temp[0] != 'l')); + if (temp[0] != 'n') { + strcpy(f1, psionDir); + strcat(f1, s.getString()); + strcpy(f2, localDir); + strcat(f2, s.getString()); + if (temp[0] == 'l') { + for (char *p = f2; *p; p++) + *p = tolower(*p); + } + if ((res = a.copyFromPsion(f1, f2)) != 0) { + errprint(res, a); + break; + } else + cout << "Transfer complete\n"; + } + } + continue; + } + if (!strcmp(argv[0], "put")) { + struct timeval stime; + struct timeval etime; + struct stat stbuf; + + strcpy(f1, localDir); + strcat(f1, argv[1]); + strcpy(f2, psionDir); + if (argc == 2) + strcat(f2, argv[1]); + else + strcat(f2, argv[2]); + gettimeofday(&stime, 0L); + if ((res = a.copyToPsion(f1, f2)) != 0) + errprint(res, a); + else { + gettimeofday(&etime, 0L); + long dsec = etime.tv_sec - stime.tv_sec; + long dhse = (etime.tv_usec / 10000) - + (stime.tv_usec /10000); + if (dhse < 0) { + dsec--; + dhse = 100 + dhse; + } + float dt = dhse; + dt /= 100.0; + dt += dsec; + stat(f1, &stbuf); + float cps = (float)(stbuf.st_size) / dt; + cout << "Transfer complete, (" << stbuf.st_size + << " bytes in " << dsec << "." + << dhse << " secs = " << cps << " cps)\n"; + } + continue; + } + if (!strcmp(argv[0], "mput")) { + DIR *d = opendir(localDir); + if (d) { + struct dirent *de; + do { + de = readdir(d); + if (de) { + char temp[100]; + do { + cout << "Put \"" << de->d_name << "\" y,n: "; + cout.flush(); + cin.getline(temp, 100); + } while (temp[1] != 0 || (temp[0] != 'y' && temp[0] != 'n')); + if (temp[0] == 'y') { + strcpy(f1, localDir); + strcat(f1, de->d_name); + strcpy(f2, psionDir); + strcat(f2, de->d_name); + if ((res = a.copyToPsion(f1, f2)) != 0) { + errprint(res, a); + break; + } else + cout << "Transfer complete\n"; + } + } + } while (de); + closedir(d); + } + cerr << "Error in directory name \"" << localDir << "\"\n"; + continue; + } + if (!strcmp(argv[0], "del") || + !strcmp(argv[0], "rm")) { + strcpy(f1, psionDir); + strcat(f1, argv[1]); + if ((res = a.remove(f1)) != 0) + errprint(res, a); + continue; + } + if (!strcmp(argv[0], "mkdir")) { + strcpy(f1, psionDir); + strcat(f1, argv[1]); + if ((res = a.mkdir(f1)) != 0) + errprint(res, a); + continue; + } + if (!strcmp(argv[0], "rmdir")) { + strcpy(f1, psionDir); + strcat(f1, argv[1]); + if ((res = a.rmdir(f1)) != 0) + errprint(res, a); + continue; + } + if (argv[0][0] == '!') { + char cmd[1024]; + strcpy(cmd, &argv[0][1]); + for (int i=1; i "); + if (!bp) { + strcpy(buf, "bye"); + cout << buf << endl; + } else { + strcpy(buf, bp); + add_history(buf); + free(bp); + } + } + ws = 1; + for (char *p = buf; *p; p++) + if ((*p == ' ') || (*p == '\t')) { + ws = 1; + *p = 0; + } else { + if (ws) + argv[argc++] = p; + ws = 0; + } +} + + // Unix utilities +bool ftp:: +unixDirExists(const char *dir) +{ + return false; +} + +void ftp:: +getUnixDir(bufferArray & files) +{ +} + +void ftp:: +cd(const char *source, const char *cdto, char *dest) +{ + if (cdto[0] == '/' || cdto[0] == '\\' || cdto[1] == ':') { + strcpy(dest, cdto); + char cc = dest[strlen(dest) - 1]; + if (cc != '/' && cc != '\\') + strcat(dest, "/"); + } else { + char start[200]; + strcpy(start, source); + + while (*cdto) { + char bit[200]; + int j; + for (j = 0; cdto[j] && cdto[j] != '/' && cdto[j] != '\\'; j++) + bit[j] = cdto[j]; + bit[j] = 0; + cdto += j; + if (*cdto) + cdto++; + + if (!strcmp(bit, "..")) { + strcpy(dest, start); + int i; + for (i = strlen(dest) - 2; i >= 0; i--) { + if (dest[i] == '/' || dest[i] == '\\') { + dest[i + 1] = 0; + break; + } + } + } else { + strcpy(dest, start); + strcat(dest, bit); + strcat(dest, "/"); + } + strcpy(start, dest); + } + } +} diff --git a/plpftp/ftp.h b/plpftp/ftp.h new file mode 100644 index 0000000..1905b09 --- /dev/null +++ b/plpftp/ftp.h @@ -0,0 +1,35 @@ +#ifndef _ftp_h_ +#define _ftp_h_ + +#include "bool.h" + +class rfsv32; +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); + + private: + void getCommand(int &argc, char **argv); + + // utilities + bool unixDirExists(const char *dir); + void getUnixDir(bufferArray & files); + void resetUnixPwd(); + void usage(); + void errprint(long errcode, rfsv32 & a); + void cd(const char *source, const char *cdto, char *dest); + int convertName(const char *orig, char *retVal); + + char localDir[1024]; + char psionDir[1024]; +}; + +#endif diff --git a/plpftp/main.cc b/plpftp/main.cc new file mode 100644 index 0000000..fbb5976 --- /dev/null +++ b/plpftp/main.cc @@ -0,0 +1,120 @@ +// +// PLP - An implementation of the PSION link protocol +// +// Copyright (C) 1999 Philip Proudman +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// e-mail philip.proudman@btinternet.com + +#include +#include +#include +#include + +#include "defs.h" +#include "bool.h" +#include "ppsocket.h" +#include "rfsv32.h" +#include "ftp.h" +#include "bufferstore.h" + +void +usage() +{ + cout << "Version " << VERSION << endl; + cout << "Usage : plpftp -s \n"; +} + +void +ftpHeader() +{ + cout << "PLPFTP Version " << VERSION; + cout << " Copyright (C) 1999 Philip Proudman" << endl; + cout << " Additions Copyright (C) 1999 Fritz Elfert " << 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; + cout << endl; + cout << "FTP like interface started. Type \"?\" for help." << endl; +} + +int +main(int argc, char **argv) +{ + ppsocket *skt; + bool res; + + // Command line parameter processing + int sockNum = DPORT; + + if (!strcmp(argv[1], "-s") && (argc > 2)) { + sockNum = atoi(argv[2]); + argc -= 2; + for (int i=1; i < argc; i++) + argv[i] = argv[i+2]; + } + + skt = new ppsocket(); + skt->startup(); + res = skt->connect(NULL, sockNum); + if (!res) { + delete skt; + + // Let's try to start a daemon + char temp[200]; + sprintf(temp, "ncp -s %d > /dev/null &", sockNum); + system(temp); + + for (int retry = 0; !res && retry < 40; retry++) { + usleep(100000); + skt = new ppsocket(); + skt->startup(); + res = skt->connect(NULL, sockNum); + if (!res) + delete skt; + } + + if (!res) { + delete skt; + cout << "Can't connect to ncp daemon on socket " << sockNum << endl; + return 1; + } + sleep(2); // Let the psion connect + + } + rfsv32 *a; + while (true) { + a = new rfsv32(skt); + if (a->getStatus() == 0) + break; + delete a; + delete skt; + cerr << "No Link available, waiting 2 secs ..." << endl; + sleep(2); + skt = new ppsocket(); + skt->startup(); + skt->connect(NULL, sockNum); + } + + int status = 0; + ftp f; + status = f.session(*a, argc, argv); + + if (status != 0) + cerr << "Command failed\n"; + delete a; + return 0; +} -- cgit v1.2.3