aboutsummaryrefslogtreecommitdiffstats
path: root/plpftp
diff options
context:
space:
mode:
authorReuben Thomas <rrt@sc3d.org>2007-11-20 21:07:16 +0000
committerReuben Thomas <rrt@sc3d.org>2007-11-20 21:07:16 +0000
commitdb5455164865b4ad34868567e210523535a0f402 (patch)
tree659c3624d752299ec070f0de50f00c33392a9ed7 /plpftp
parent7defe9c60914726ee4916b92c5890dfc4ca41ad9 (diff)
downloadplptools-db5455164865b4ad34868567e210523535a0f402.tar.gz
plptools-db5455164865b4ad34868567e210523535a0f402.tar.bz2
plptools-db5455164865b4ad34868567e210523535a0f402.zip
Add "putclip" command to set the clipboard, using code from klipsi.
Diffstat (limited to 'plpftp')
-rw-r--r--plpftp/ftp.cc164
-rw-r--r--plpftp/ftp.h8
-rw-r--r--plpftp/main.cc15
3 files changed, 182 insertions, 5 deletions
diff --git a/plpftp/ftp.cc b/plpftp/ftp.cc
index 69d6709..3571c91 100644
--- a/plpftp/ftp.cc
+++ b/plpftp/ftp.cc
@@ -31,6 +31,8 @@
#include <plpintl.h>
#include <rfsv.h>
#include <rpcs.h>
+#include <rclip.h>
+#include <ppsocket.h>
#include <bufferarray.h>
#include <bufferstore.h>
#include <Enum.h>
@@ -50,6 +52,7 @@
#include <sys/time.h>
#include <sys/stat.h>
#include <signal.h>
+#include <netdb.h>
#include "ftp.h"
@@ -68,6 +71,8 @@ static char psionDir[1024];
static rfsv *comp_a;
static int continueRunning;
+#define CLIPFILE "C:/System/Data/Clpboard.cbd"
+
void ftp::
resetUnixPwd()
@@ -115,6 +120,7 @@ void ftp::usage() {
cout << endl << _("Known RPC commands:") << endl << endl;
cout << " ps" << endl;
cout << " kill <pid|'all'>" << endl;
+ cout << " putclip <unixfile>" << endl;
cout << " run <psionfile> [args]" << endl;
cout << " killsave <unixfile>" << endl;
cout << " runrestore <unixfile>" << endl;
@@ -337,8 +343,159 @@ startPrograms(rpcs & r, rfsv & a, const char *file) {
return 0;
}
+bool
+ftp::checkClipConnection(rfsv &a, rclip & rc, ppsocket & rclipSocket)
+{
+ if (canClip == false)
+ return false;
+
+ if (a.getProtocolVersion() == 3) {
+ cerr << _("Clipboard protocol not supported by Psion Series 3.") << endl;
+ return false;
+ }
+
+ Enum<rfsv::errs> ret;
+ if ((ret = rc.initClipbd()) == rfsv::E_PSI_GEN_NONE)
+ return true;
+ else if (ret == rfsv::E_PSI_GEN_NSUP)
+ cerr << _("Your Psion does not support the clipboard protocol.\n\
+ The reason for that is usually a missing server library.\n\
+ Make sure that C:\\System\\Libs\\clipsvr.rsy exists.\n\
+ This file is part of PsiWin and usually gets copied to\n\
+ your Psion when you enable CopyAnywhere in PsiWin.\n\
+ You can also get it from a PsiWin installation directory\n\
+ and copy it to your Psion manually.") << endl;
+ return false;
+}
+
+static void
+psiText2ascii(char *buf, int len) {
+ char *p;
+
+ for (p = buf; len; len--, p++)
+ switch (*p) {
+ case 6:
+ case 7:
+ *p = '\n';
+ break;
+ case 8:
+ *p = '\f';
+ break;
+ case 10:
+ *p = '\t';
+ break;
+ case 11:
+ case 12:
+ *p = '-';
+ break;
+ case 15:
+ case 16:
+ *p = ' ';
+ break;
+ }
+}
+
+static void
+ascii2PsiText(char *buf, int len) {
+ char *p;
+
+ for (p = buf; len; len--, p++)
+ switch (*p) {
+ case '\0':
+ *p = ' ';
+ case '\n':
+ *p = 6;
+ break;
+ case '\f':
+ *p = 8;
+ break;
+ case '-':
+ *p = 11;
+ break;
+ }
+}
+
+// FIXME: This is almost the same as getln. Ugh.
+static char *
+slurp(FILE *fp, size_t *final_len)
+{
+ size_t len = 256;
+ int c;
+ char *l = (char *)malloc(len), *s = l;
+
+ assert(l);
+ for (c = getc(fp); c != EOF; c = getc(fp)) {
+ if (s == l + len) {
+ l = (char *)realloc(l, len * 2);
+ assert(l);
+ len *= 2;
+ }
+ *s++ = c;
+ }
+ if (s == l + len) {
+ l = (char *)realloc(l, len + 1);
+ assert(l);
+ }
+ *s++ = '\0';
+
+ *final_len = s - l;
+ l = (char *)realloc(l, s - l);
+ assert(l);
+ return l;
+}
+
+int
+ftp::putClipText(rpcs & r, rfsv & a, rclip & rc, ppsocket & rclipSocket, const char *file)
+{
+ Enum<rfsv::errs> res;
+ u_int32_t fh;
+ u_int32_t l;
+ const unsigned char *p;
+ bufferStore b;
+ char *data;
+ FILE *fp;
+
+ if (!checkClipConnection(a, rc, rclipSocket))
+ return 1;
+
+ if ((fp = fopen(file, "r")) == NULL)
+ return 1;
+
+ size_t len;
+ data = slurp(fp, &len);
+ fclose(fp);
+ ascii2PsiText(data, len);
+
+ res = a.freplacefile(0x200, CLIPFILE, fh);
+ if (res == rfsv::E_PSI_GEN_NONE) {
+ // Base Header
+ b.addDWord(0x10000037); // @00 UID 0
+ b.addDWord(0x1000003b); // @04 UID 1
+ b.addDWord(0); // @08 UID 3
+ b.addDWord(0x4739d53b); // @0c Checksum the above
+
+ // Section Table
+ b.addDWord(0x00000014); // @10 Offset of Section Table
+ b.addByte(2); // @14 Section Table, length in DWords
+ b.addDWord(0x10000033); // @15 Section Type (ASCII)
+ b.addDWord(0x0000001d); // @19 Section Offset
+
+ // Data
+ b.addDWord(strlen(data)); // @1e Section (String) length
+ b.addStringT(data); // @22 Data (Psion Word seems to need a
+ // terminating 0.
+
+ p = (const unsigned char *)b.getString(0);
+ a.fwrite(fh, p, b.getLen(), l);
+ a.fclose(fh);
+ a.fsetattr(CLIPFILE, 0x20, 0x07);
+ }
+
+ return 0;
+}
+
int ftp::
-session(rfsv & a, rpcs & r, int xargc, char **xargv)
+session(rfsv & a, rpcs & r, rclip & rc, ppsocket & rclipSocket, int xargc, char **xargv)
{
int argc;
char *argv[10];
@@ -1075,6 +1232,11 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv)
stopPrograms(r, argv[1]);
continue;
}
+ if (!strcmp(argv[0], "putclip") && (argc == 2)) {
+ if (putClipText(r, a, rc, rclipSocket, argv[1]))
+ cerr << _("Error setting clipboard") << endl;
+ continue;
+ }
if (!strcmp(argv[0], "kill") && (argc >= 2)) {
processList tmp;
bool anykilled = false;
diff --git a/plpftp/ftp.h b/plpftp/ftp.h
index aabdf23..73e0586 100644
--- a/plpftp/ftp.h
+++ b/plpftp/ftp.h
@@ -38,11 +38,14 @@ class ftp {
public:
ftp();
~ftp();
- int session(rfsv & a, rpcs & r, int xargc, char **xargv);
+ int session(rfsv & a, rpcs & r, rclip & rc, ppsocket & rclipSocket, int xargc, char **xargv);
+ bool canClip;
- private:
+ private:
void getCommand(int &argc, char **argv);
void initReadline(void);
+ int putClipText(rpcs & r, rfsv & a, rclip & rc, ppsocket & rclipSocket, const char *data);
+ bool checkClipConnection(rfsv &a, rclip & rc, ppsocket & rclipSocket);
// utilities
bool unixDirExists(const char *dir);
@@ -60,7 +63,6 @@ class ftp {
#endif
char defDrive[9];
char localDir[1024];
- // char psionDir[1024];
};
#endif
diff --git a/plpftp/main.cc b/plpftp/main.cc
index a8a809a..bde68bc 100644
--- a/plpftp/main.cc
+++ b/plpftp/main.cc
@@ -31,6 +31,8 @@
#include <rfsvfactory.h>
#include <rpcs.h>
#include <rpcsfactory.h>
+#include <rclip.h>
+#include <ppsocket.h>
#include <bufferstore.h>
#include <iostream>
@@ -132,6 +134,8 @@ main(int argc, char **argv)
ppsocket *skt2;
rfsv *a;
rpcs *r;
+ ppsocket *rclipSocket;
+ rclip *rc;
ftp f;
const char *host = "127.0.0.1";
int status = 0;
@@ -183,12 +187,21 @@ main(int argc, char **argv)
rpcsfactory *rp = new rpcsfactory(skt2);
a = rf->create(false);
r = rp->create(false);
+ rclipSocket = new ppsocket();
+ rclipSocket->connect(NULL, sockNum);
+ if (rclipSocket)
+ rc = new rclip(rclipSocket);
+ f.canClip = rclipSocket && rc ? true : false;
if ((a != NULL) && (r != NULL)) {
- status = f.session(*a, *r, argc - optind, &argv[optind]);
+ status = f.session(*a, *r, *rc, *rclipSocket, argc - optind, &argv[optind]);
delete r;
delete a;
delete skt;
delete skt2;
+ if (rclipSocket)
+ delete rclipSocket;
+ if (rc)
+ delete rc;
} else {
cerr << "plpftp: " << X_(rf->getError()) << endl;
status = 1;