58#include "ignore-value.h"
59#include "string-buffer.h"
61#include "xvasprintf.h"
68#if defined(HAVE_READLINE_READLINE_H)
69# include <readline/readline.h>
70#elif defined(HAVE_READLINE_H)
75#ifdef HAVE_READLINE_HISTORY
76# if defined(HAVE_READLINE_HISTORY_H)
77# include <readline/history.h>
78# elif defined(HAVE_HISTORY_H)
90#define CLIPFILE "C:/System/Data/Clpboard.cbd"
107 cout <<
_(
"FTP commands:") << endl << endl;
108 cout <<
" pwd" << endl;
109 cout <<
" ren <oldname> <newname>" << endl;
110 cout <<
" touch <psionfile>" << endl;
111 cout <<
" gtime <psionfile>" << endl;
112 cout <<
" test <psionfile>" << endl;
113 cout <<
" gattr <psionfile>" << endl;
114 cout <<
" sattr [[-|+]rwhsa] <psionfile>" << endl;
115 cout <<
" devs" << endl;
116 cout <<
" dir|ls" << endl;
117 cout <<
" dircnt" << endl;
118 cout <<
" cd <dir>" << endl;
119 cout <<
" lcd <dir>" << endl;
120 cout <<
" !<system command>" << endl;
121 cout <<
" get <psionfile>" << endl;
122 cout <<
" put <unixfile>" << endl;
123 cout <<
" mget <shellpattern>" << endl;
124 cout <<
" mput <shellpattern>" << endl;
125 cout <<
" cp <psionfile> <psionfile>" << endl;
126 cout <<
" del|rm <psionfile>" << endl;
127 cout <<
" mkdir <psiondir>" << endl;
128 cout <<
" rmdir <psiondir>" << endl;
129 cout <<
" volname <drive> <name>" << endl;
130 cout <<
" prompt" << endl;
131 cout <<
" hash" << endl;
132 cout <<
" bye" << endl;
133 cout << endl <<
_(
"RPC commands:") << endl << endl;
134 cout <<
" ps" << endl;
135 cout <<
" kill <pid|'all'>" << endl;
136 cout <<
" getclip <unixfile>" << endl;
137 cout <<
" putclip <unixfile>" << endl;
138 cout <<
" run <psionfile> [args]" << endl;
139 cout <<
" killsave <unixfile>" << endl;
140 cout <<
" runrestore <unixfile>" << endl;
141 cout <<
" machinfo" << endl;
142 cout <<
" ownerinfo" << endl;
143 cout <<
" settime" << endl;
144 cout <<
" setupinfo" << endl;
145 cout << endl <<
_(
"Device commands:") << endl << endl;
146 cout <<
" deviceid - get the device id used for backup and sync" << endl;
147 cout <<
" devicename - get the device name used for backup and sync" << endl;
148 cout <<
" setdevicename <name> - set the device name and persist the id used for backup and sync" << endl;
153 struct string_buffer sb;
155 int argc = argv.size();
156 for (
int i = 0; i < argc; i++) {
157 sb_append(&sb, argv[i]);
162 return sb_dupfree(&sb);
171 printf(
"#"); fflush(stdout);
190 FILE *fp = fopen(file,
"w");
193 cerr <<
_(
"Could not open command list file ") << file << endl;
196 fputs(
"#plpftp processlist\n", fp);
198 cerr <<
_(
"Could not get process list, Error: ") << res << endl;
201 for (processList::iterator i = tmp.begin(); i != tmp.end(); i++) {
202 fputs(i->getArgs(), fp);
206 time_t tstart = time(
nullptr) + 5;
207 while (!tmp.empty()) {
208 for (processList::iterator i = tmp.begin(); i != tmp.end(); i++) {
212 if (time(
nullptr) > tstart) {
213 cerr <<
_(
"Could not stop all processes. Please stop running\n"
214 "programs manually on the Psion, then hit return.") << flush;
215 cin.getline((
char *)&tstart, 1);
216 tstart = time(
nullptr) + 5;
219 cerr <<
_(
"Could not get process list, Error: ") << res << endl;
226static char *
get_upto(FILE *fp,
const char *term,
size_t *final_len) {
229 char *l = (
char *)malloc(len), *s = l;
232 for (c = getc(fp); c != EOF && strchr(term, c) == NULL; c = getc(fp)) {
234 l = (
char *)realloc(l, len * 2);
241 l = (
char *)realloc(l, len + 1);
249 l = (
char *)realloc(l, s - l);
260 FILE *fp = fopen(file,
"r");
264 cerr <<
_(
"Could not open command list file ") << file << endl;
267 cmd = string(
getln(fp));
268 if (strcmp(cmd.c_str(),
"#plpftp processlist")) {
270 cerr <<
_(
"Error: ") << file <<
271 _(
" is not a process list saved with killsave") << endl;
274 for (cmd =
string(
getln(fp)); cmd.length() > 0; cmd = string(
getln(fp))) {
275 int firstBlank = cmd.find(
' ');
276 string prog = string(cmd, 0, firstBlank);
277 string arg = string(cmd, firstBlank + 1);
283 if ((arg.size() > 2) && (arg[1] ==
':') && (arg[0] >=
'A') &&
294 if (prog.find(
'\\') == prog.npos) {
298 for (i = 0; i < 26; i++) {
299 if (devbits & (1 << i)) {
300 string tmp = string();
302 tmp +=
":\\System\\Apps\\" + prog +
"\\" + prog +
".app";
312 cerr <<
_(
"Could not start ") << cmd << endl;
313 cerr <<
_(
"Error: ") << res << endl;
322 cerr <<
_(
"Clipboard protocol not supported by Psion Series 3.") << endl;
330 cerr <<
_(
"Your Psion does not support the clipboard protocol.\n\
331 The reason for that is usually a missing server library.\n\
332 Make sure that C:\\System\\Libs\\clipsvr.rsy exists.\n\
333 This file is part of PsiWin and usually gets copied to\n\
334 your Psion when you enable CopyAnywhere in PsiWin.\n\
335 You can also get it from a PsiWin installation directory\n\
336 and copy it to your Psion manually.") << endl;
344 for (p = buf; len; len--, p++)
370 for (p = buf; len; len--, p++)
386static char *
slurp(FILE *fp,
size_t *final_len) {
394 const unsigned char *p;
403 if ((fp = fopen(file,
"r")) == NULL) {
408 data =
slurp(fp, &len);
431 p = (
const unsigned char *)b.
getString(0);
454 char *buf = (
char *)malloc(len);
457 cerr <<
"Out of memory in getClipData" << endl;
464 res =
a.
fread(fh, (
unsigned char *)buf, len, tmp);
470 uint32_t *ti = (uint32_t*)buf;
473 if (*ti++ != 0x10000037) {
477 if (*ti++ != 0x1000003b) {
485 if (*ti++ != 0x4739d53b) {
495 uint32_t *td = (uint32_t*)p;
497 uint32_t sType = *td++;
498 if (sType == 0x10000033) {
501 len = *((uint32_t*)p);
504 clipText += (
char *)p;
506 if (sType == 0x1000003d) {
519 FILE *fp = fopen(file,
"w");
523 fwrite(clipText.c_str(), 1, clipText.length(), fp);
536 if ((f1[strlen(f1) - 1] !=
'/') && (f1[strlen(f1) - 1] !=
'\\')) {
537 char *f2 = xasprintf(
"%s%s", f1,
"\\");
552 unsigned argc = argv.size();
558 auto name = deviceEndpoint.
name();
565 cout <<
_(
"Connected to '") << *name <<
_(
"', a ") << machType <<
_(
", at ")
566 << speed <<
_(
" baud.") << endl;
568 cout <<
_(
"Connected to a ") << machType <<
_(
", at ") << speed <<
_(
" baud.") << endl;
574 if (!strcmp(DDRIVE,
"AUTO")) {
584 cout <<
_(
"Psion dir is: \"") <<
psionDir <<
"\"" << endl;
598 if ((!strcmp(argv[0],
"help")) || (!strcmp(argv[0],
"?"))) {
602 if (!strcmp(argv[0],
"prompt")) {
604 cout <<
_(
"Prompting now ") << (prompt?
_(
"on") :
_(
"off")) << endl;
607 if (!strcmp(argv[0],
"hash")) {
609 cout <<
_(
"Hash printing now ") << (hash?
_(
"on") :
_(
"off")) << endl;
613 if (!strcmp(argv[0],
"pwd")) {
614 cout <<
_(
"Local dir: \"") <<
localDir <<
"\"" << endl;
615 cout <<
_(
"Psion dir: \"") <<
psionDir <<
"\"" << endl;
618 if (!strcmp(argv[0],
"volname") && (argc == 3) && (strlen(argv[1]) == 1)) {
620 cerr <<
_(
"Error: ") << res << endl;
624 if (!strcmp(argv[0],
"ren") && (argc == 3)) {
625 char *f1 = xasprintf(
"%s%s",
psionDir, argv[1]);
626 char *f2 = xasprintf(
"%s%s",
psionDir, argv[2]);
628 cerr <<
_(
"Error: ") << res << endl;
634 if (!strcmp(argv[0],
"cp") && (argc == 3)) {
635 char *f1 = xasprintf(
"%s%s",
psionDir, argv[1]);
636 char *f2 = xasprintf(
"%s%s",
psionDir, argv[2]);
638 cerr <<
_(
"Error: ") << res << endl;
644 if (!strcmp(argv[0],
"touch") && (argc == 2)) {
645 char *f1 = xasprintf(
"%s%s",
psionDir, argv[1]);
648 cerr <<
_(
"Error: ") << res << endl;
653 if (!strcmp(argv[0],
"test") && (argc == 2)) {
655 char *f1 = xasprintf(
"%s%s",
psionDir, argv[1]);
657 cerr <<
_(
"Error: ") << res << endl;
664 if (!strcmp(argv[0],
"gattr") && (argc == 2)) {
666 char *f1 = xasprintf(
"%s%s",
psionDir, argv[1]);
668 cerr <<
_(
"Error: ") << res << endl;
670 cout << hex << setw(4) << setfill(
'0') << attr;
671 cout <<
" (" << rfsv.
attr2String(attr) <<
")" << endl;
676 if (!strcmp(argv[0],
"gtime") && (argc == 2)) {
678 char *f1 = xasprintf(
"%s%s",
psionDir, argv[1]);
680 cerr <<
_(
"Error: ") << res << endl;
682 cout << mtime <<
"(" << hex
691 if (!strcmp(argv[0],
"sattr") && (argc == 3)) {
696 char *f1 = xasprintf(
"%s%s",
psionDir, argv[2]);
698 attr[0] = attr[1] = 0;
731 cerr <<
_(
"Error: ") << res << endl;
736 if (!strcmp(argv[0],
"deviceid") && (argc == 1)) {
737 cout << deviceEndpoint.
id() << endl;
739 cout <<
_(
"Warning: ") <<
_(
"device id not persistent; use setdevicename to persist the name and device id") << endl;
743 if (!strcmp(argv[0],
"devicename") && (argc == 1)) {
744 auto name = deviceEndpoint.
name();
746 cout << *name << endl;
748 cout <<
_(
"Error: ") <<
_(
"device name not set; use setdevicename to persist the name and device id") << endl;
752 if (!strcmp(argv[0],
"setdevicename") && (argc == 2)) {
753 std::string name = argv[1];
756 cerr <<
_(
"Error: ") <<
error << endl;
761 if (!strcmp(argv[0],
"dircnt")) {
764 cerr <<
_(
"Error: ") << res << endl;
766 cout << cnt <<
_(
" Entries") << endl;
770 if (!strcmp(argv[0],
"devs")) {
773 cout <<
_(
"Drive Type Volname Total Free UniqueID") << endl;
774 for (
int i = 0; i < 26; i++) {
777 if ((devbits & 1) != 0) {
779 cout << (char) (
'A' + i) <<
" " << hex
780 << setw(4) << setfill(
'0')
781 <<
static_cast<uint32_t
>(drive.
getMediaType()) <<
" " << setw(12)
782 << setfill(
' ') << setiosflags(ios::left)
784 << resetiosflags(ios::left) << dec << setw(9)
786 << drive.
getSpace() <<
" " << setw(8)
787 << setfill(
'0') << hex << drive.
getUID()
794 cerr <<
_(
"Error: ") << res << endl;
798 if (!strcmp(argv[0],
"ls") || !strcmp(argv[0],
"dir")) {
802 cerr <<
_(
"Error: ") << res << endl;
804 while (!files.empty()) {
805 cout << files[0] << endl;
812 if (!strcmp(argv[0],
"lcd")) {
816 if (chdir(argv[1]) == 0) {
819 cerr <<
_(
"No such directory") << endl
820 <<
_(
"Keeping original directory \"") <<
localDir <<
"\"" << endl;
825 if (!strcmp(argv[0],
"cd")) {
833 cerr <<
_(
"Error: ") << res << endl;
834 cerr <<
_(
"Keeping original directory \"") <<
psionDir <<
"\"" << endl;
843 if ((!strcmp(argv[0],
"get")) && (argc > 1)) {
844 struct timeval stime;
845 struct timeval etime;
850 char *f2 = xasprintf(
"%s%s%s",
localDir,
"/", argc == 2 ? basename.c_str() : argv[2]);
852 gettimeofday(&stime,
nullptr);
858 cerr <<
_(
"Error: ") << res << endl;
862 gettimeofday(&etime,
nullptr);
863 long dsec = etime.tv_sec - stime.tv_sec;
864 long dhse = (etime.tv_usec / 10000) -
865 (stime.tv_usec /10000);
874 float cps = (float)(stbuf.st_size) / dt;
875 cout <<
_(
"Transfer complete, (") << dec << stbuf.st_size
876 <<
_(
" bytes in ") << dsec <<
"."
877 << dhse <<
_(
" secs = ") << cps <<
" cps)\n";
882 }
else if ((!strcmp(argv[0],
"mget")) && (argc == 2)) {
883 char *pattern = argv[1];
886 cerr <<
_(
"Error: ") << res << endl;
889 for (
size_t i = 0; i < files.size(); i++) {
896 if (fnmatch(pattern, e.
getName(), FNM_NOESCAPE) == FNM_NOMATCH) {
899 cout <<
_(
"Get \"") << e.
getName() <<
"\" (y,n): ";
917 cerr <<
_(
"Error: ") << res << endl;
923 cout <<
_(
"Transfer complete\n");
931 if (!strcmp(argv[0],
"put") && (argc >= 2)) {
932 struct timeval stime;
933 struct timeval etime;
936 char *f1 = xasprintf(
"%s%s%s",
localDir,
"/", argv[1]);
937 char *f2 = xasprintf(
"%s%s",
psionDir, argc == 2 ? argv[1] : argv[2]);
938 gettimeofday(&stime,
nullptr);
944 cerr <<
_(
"Error: ") << res << endl;
948 gettimeofday(&etime,
nullptr);
949 long dsec = etime.tv_sec - stime.tv_sec;
950 long dhse = (etime.tv_usec / 10000) -
951 (stime.tv_usec /10000);
960 float cps = (float)(stbuf.st_size) / dt;
961 cout <<
_(
"Transfer complete, (") << dec << stbuf.st_size
962 <<
_(
" bytes in ") << dsec <<
"."
963 << dhse <<
_(
" secs = ") << cps <<
" cps)\n";
969 if ((!strcmp(argv[0],
"mput")) && (argc == 2)) {
970 char *pattern = argv[1];
979 if (fnmatch(pattern, de->d_name, FNM_NOESCAPE) == FNM_NOMATCH) {
982 char *f1 = xasprintf(
"%s%s%s",
localDir,
"/", de->d_name);
983 if (stat(f1, &st) == 0 && S_ISREG(st.st_mode)) {
984 cout <<
_(
"Put \"") << de->d_name <<
"\" y,n: ";
994 char *f2 = xasprintf(
"%s%s",
psionDir, de->d_name);
1000 cerr <<
_(
"Error: ") << res << endl;
1009 cout <<
_(
"Transfer complete\n");
1018 cerr <<
_(
"Error in directory name \"") <<
localDir <<
"\"\n";
1022 if ((!strcmp(argv[0],
"del") ||
1023 !strcmp(argv[0],
"rm")) && (argc == 2)) {
1024 char *f1 = xasprintf(
"%s%s",
psionDir, argv[1]);
1026 cerr <<
_(
"Error: ") << res << endl;
1031 if (!strcmp(argv[0],
"mkdir") && (argc == 2)) {
1032 char *f1 = xasprintf(
"%s%s",
psionDir, argv[1]);
1034 cerr <<
_(
"Error: ") << res << endl;
1039 if (!strcmp(argv[0],
"rmdir") && (argc == 2)) {
1040 char *f1 = xasprintf(
"%s%s",
psionDir, argv[1]);
1042 cerr <<
_(
"Error: ") << res << endl;
1047 if (argv[0][0] ==
'!') {
1050 ignore_value(system(cmd));
1053 cout <<
_(
"Starting subshell ...\n");
1054 sh = getenv(
"SHELL");
1058 ignore_value(system(sh));
1064 if (!strcmp(argv[0],
"settime")) {
1066 cerr <<
_(
"Error: ") << res << endl;
1070 if (!strcmp(argv[0],
"setupinfo")) {
1075 cerr <<
_(
"Error: ") << res << endl;
1078 if (db.
getLen() < 1152) {
1079 cerr <<
_(
"Unknown setup info received") << endl;
1082 cout <<
_(
"Setup information:") << endl;
1083 cout <<
_(
" Screen contrast: ") << dec
1085 cout <<
_(
" Keyboard click: ")
1087 (db.
getDWord(0x204) ?
_(
"high") :
_(
"low")) :
_(
"off")) << endl;
1088 cout <<
_(
" Screen click: ")
1090 (db.
getDWord(0x210) ?
_(
"high") :
_(
"low")) :
_(
"off")) << endl;
1091 cout <<
_(
" Error sound: ")
1093 (db.
getDWord(0x218) ?
_(
"high") :
_(
"low")) :
_(
"off")) << endl;
1094 cout <<
_(
" Auto-switch off: ");
1100 cout <<
_(
"if running on battery power");
1103 cout <<
_(
"always");
1108 cout <<
_(
" Switch off after: ") << dec
1109 << db.
getDWord(0x22c) <<
_(
" seconds") << endl;
1110 cout <<
_(
" Backlight off after: ") << dec
1111 << db.
getDWord(0x234) <<
_(
" seconds") << endl;
1112 cout <<
_(
" Switch on when tapping on screen: ")
1113 << (db.
getDWord(0x238) ?
_(
"yes") :
_(
"no")) << endl;
1114 cout <<
_(
" Switch on when opening: ")
1115 << (db.
getDWord(0x23c) ?
_(
"yes") :
_(
"no")) << endl;
1116 cout <<
_(
" Switch off when closing: ")
1117 << (db.
getDWord(0x23c) ?
_(
"yes") :
_(
"no")) << endl;
1118 cout <<
_(
" Ask for password on startup: ")
1119 << (db.
getDWord(0x29c) ?
_(
"yes") :
_(
"no")) << endl;
1120 cout <<
_(
" Show Owner info on startup: ");
1126 cout <<
_(
"once a day");
1129 cout <<
_(
"always");
1135 if (!strcmp(argv[0],
"run") && (argc >= 2)) {
1136 vector<char *> args = {argv.begin() + 1, argv.end()};
1139 if (!strchr(argv[1],
':')) {
1140 cmd = xasprintf(
"%s%s",
psionDir, argv[1]);
1142 cmd = xstrdup(argv[1]);
1149 if (!strcmp(argv[0],
"ownerinfo")) {
1152 cerr <<
_(
"Error: ") << res << endl;
1155 while (!b.
empty()) {
1160 if (!strcmp(argv[0],
"machinfo")) {
1163 cerr <<
_(
"Error: ") << res << endl;
1167 cout <<
_(
"General:") << endl;
1168 cout <<
_(
" Machine Type: ") << mi.
machineType << endl;
1169 cout <<
_(
" Machine Name: ") << mi.
machineName << endl;
1170 cout <<
_(
" Machine UID: ") << hex << mi.
machineUID << dec << endl;
1171 cout <<
_(
" UI Language: ") << mi.
uiLanguage << endl;
1172 cout <<
_(
"ROM:") << endl;
1173 cout <<
_(
" Version: ") << mi.
romMajor <<
"." << setw(2) << setfill(
'0') <<
1175 cout <<
_(
" Size: ") << mi.
romSize / 1024 <<
"k" << endl;
1176 cout <<
_(
" Programmable: ") <<
1178 cout <<
_(
"RAM:") << endl;
1179 cout <<
_(
" Size: ") << mi.
ramSize / 1024 <<
"k" << endl;
1180 cout <<
_(
" Free: ") << mi.
ramFree / 1024 <<
"k" << endl;
1181 cout <<
_(
" Free max: ") << mi.
ramMaxFree / 1024 <<
"k" << endl;
1182 cout <<
_(
"RAM disk size: ") << mi.
ramDiskSize / 1024 <<
"k" << endl;
1186 cout <<
_(
"Time:") << endl;
1188 cout <<
_(
" Current time: ") << pt << endl;
1189 cout <<
_(
" UTC offset: ") << mi.
tz.
utc_offset <<
_(
" seconds") << endl;
1190 cout <<
_(
" DST: ") <<
1193 cout <<
_(
" Country Code: ") << mi.
countryCode << endl;
1194 cout <<
_(
"Main battery:") << endl;
1196 cout <<
_(
" Changed at: ") << pt << endl;
1203 cout <<
_(
"Backup battery:") << endl;
1207 cout <<
_(
"External power:") << endl;
1208 cout <<
_(
" Supplied: ")
1213 if (!strcmp(argv[0],
"runrestore") && (argc == 2)) {
1217 if (!strcmp(argv[0],
"killsave") && (argc == 2)) {
1221 if (!strcmp(argv[0],
"putclip") && (argc == 2)) {
1223 cerr <<
_(
"Error setting clipboard") << endl;
1227 if (!strcmp(argv[0],
"getclip") && (argc == 2)) {
1229 cerr <<
_(
"Error getting clipboard") << endl;
1233 if (!strcmp(argv[0],
"kill") && (argc >= 2)) {
1235 bool anykilled =
false;
1237 cerr <<
_(
"Error: ") << res << endl;
1239 for (
unsigned int i = 1; i < argc; i++) {
1241 if (!strcmp(argv[i],
"all")) {
1244 sscanf(argv[i],
"%d", &kpid);
1246 processList::iterator j;
1247 for (j = tmp.begin(); j != tmp.end(); j++) {
1248 if (kpid == -1 || kpid == j->getPID()) {
1258 cerr <<
_(
"no such process") << endl;
1263 if (!strcmp(argv[0],
"ps")) {
1266 cerr <<
_(
"Error: ") << res << endl;
1268 cout <<
"PID CMD ARGS" << endl;
1269 for (processList::iterator i = tmp.begin(); i != tmp.end(); i++) {
1275 if (strcmp(argv[0],
"bye") == 0 || strcmp(argv[0],
"quit") == 0) {
1278 cerr <<
_(
"syntax error. Try \"help\"") << endl;
1284#define MATCHFUNCTION rl_completion_matches
1287 "pwd",
"ren",
"touch",
"gtime",
"test",
"gattr",
"sattr",
"devs",
1288 "dir",
"ls",
"dircnt",
"cd",
"lcd",
"get",
"put",
"mget",
"mput",
1289 "del",
"rm",
"mkdir",
"rmdir",
"prompt",
"bye",
"cp",
"volname",
1290 "ps",
"kill",
"killsave",
"runrestore",
"run",
"machinfo",
1291 "ownerinfo",
"help",
"settime",
"setupinfo",
"deviceid",
"devicename",
1292 "setdevicename", NULL
1296 "lcd ",
"put ",
"mput ",
"killsave ",
"runrestore ", NULL
1300 "cd ",
"rmdir ", NULL
1320 cerr <<
_(
"Error: ") << res << endl;
1334 if (!(strncmp(tmp.c_str(), text, len))) {
1336 rl_completion_append_character =
'\0';
1339 return (strdup(tmp.c_str()));
1346 static int idx, len;
1355 if (!strncmp(name, text, len)) {
1356 return (strdup(name));
1365 static char null[1] =
"";
1370 char **matches = NULL;
1373 rl_completion_append_character =
' ';
1374 rl_attempted_completion_over = 1;
1382 rl_filename_quoting_desired = 1;
1385 if (!strncmp(name, rl_line_buffer, strlen(name))) {
1386 rl_completion_entry_function = NULL;
1402 if (!strncmp(name, rl_line_buffer, strlen(name))) {
1415 rl_readline_name =
"plpftp";
1418 rl_basic_word_break_characters =
" \t\n\"\\'`@><=;|&{(";
1419 rl_completer_quote_characters =
"\"";
1425 vector<char *> argv;
1439 for (
char *p = buf; *p; p++)
1461 cout <<
"bye" << endl;
1462 buf = strdup(
"bye");
1463 argv.push_back(buf);
An array of BufferStores.
bool empty() const
Checks if this BufferArray is empty.
BufferStore pop(void)
Removes the first BufferStore.
A generic container for an array of bytes.
const char * getString(long pos=0) const
Retrieves the characters at index pos.
uint32_t getDWord(long pos=0) const
Retrieves the dword at index pos.
void addByte(unsigned char c)
Appends a byte to the content of this instance.
void addStringT(const char *s)
Appends a string to the content of this instance.
void addDWord(long dw)
Appends a dword to the content of this instance.
unsigned long getLen() const
Retrieves the length of a BufferStore.
unsigned char getByte(long pos=0) const
Retrieves the byte at index pos.
std::string id() const
Device identifier.
bool hasPersistentId() const
Enum< RFSV::errs > setName(const std::string &name)
Set the device name.
std::optional< std::string > name() const
Device name.
A class representing information about a Disk drive on the psion.
uint32_t getUID() const
Retrieve the UID of the drive.
MediaType getMediaType() const
Retrieve the media type of the drive.
uint64_t getSpace() const
Retrieve the free capacity on the drive.
uint64_t getSize() const
Retrieve the total capacity of the drive.
std::string getName() const
Retrieve the volume name of the drive.
Wrapper class featuring range-checking and string representation of enumerated values.
std::vector< char * > getCommand()
int session(DeviceEndpoint &deviceEndpoint, RFSV &rfsv, RPCS &rpcs, rclip &clipboard, std::vector< char * > argv)
int putClipText(RFSV &a, rclip &rc, const char *data)
bool checkClipConnection(RFSV &a, rclip &rc)
int getClipData(RFSV &a, rclip &rc, const char *file)
A class, representing a directory entry of the Psion.
uint32_t getAttr() const
Retrieves the file attributes of a directory entry.
const char * getName() const
Retrieve the file name of a directory entry.
uint32_t getSize() const
Retrieves the file size of a directory entry.
Psion time related utility class.
uint32_t getPsiTimeHi(void)
Retrieves the instance's current value in Psion time format, low 32 bits.
uint32_t getPsiTimeLo(void)
Retrieves the instance's current value in Psion time format, high 32 bits.
void setPsiTime(psi_timeval *_ptv)
Modifies the value of this instance.
Access remote file services of a Psion.
virtual Enum< errs > copyOnPsion(const char *const from, const char *const to, void *, cpCallback_t func)=0
Copies a file from the Psion to the Psion.
virtual Enum< errs > fwrite(const uint32_t handle, const unsigned char *const buffer, const uint32_t len, uint32_t &count)=0
Write to a file on the Psion.
virtual Enum< errs > fgetmtime(const char *const name, PsiTime &mtime)=0
Retrieves the modification time of a file on the Psion.
virtual uint32_t opMode(const uint32_t mode)=0
Converts an open-mode (A combination of the PSI_O_ constants.) from generic representation to the mac...
virtual Enum< errs > remove(const char *const name)=0
Removes a file on the Psion.
virtual Enum< errs > fopen(const uint32_t attr, const char *const name, uint32_t &handle)=0
Opens a file.
std::string attr2String(const uint32_t attr)
Converts a file attribute RFSV::file_attribs to human readable format, usable for showing them in dir...
virtual Enum< errs > setVolumeName(const char drive, const char *const name)=0
Set the name of a Psion Volume (Drive).
virtual Enum< errs > fread(const uint32_t handle, unsigned char *const buffer, const uint32_t len, uint32_t &count)=0
Reads from a file on the Psion.
virtual Enum< errs > fsetattr(const char *const name, const uint32_t seta, const uint32_t unseta)=0
virtual Enum< errs > copyToPsion(const char *const from, const char *const to, void *, cpCallback_t func)=0
Copies a file from local machine to the Psion.
virtual Enum< errs > fgeteattr(const char *const name, PlpDirent &e)=0
Retrieves attributes, size and modification time of a file on the Psion.
virtual Enum< errs > fsetmtime(const char *const name, const PsiTime mtime)=0
Sets the modification time of a file on the Psion.
virtual Enum< errs > mkdir(const char *const name)=0
Creates a directory on the Psion.
virtual char defaultInternalDriveLetter()=0
virtual Enum< errs > fclose(const uint32_t handle)=0
Close a file on the Psion whih was previously opened/created by using fopen , fcreatefile ,...
Enum< errs > getStatus()
Retrieves the current connection status.
virtual Enum< errs > fgetattr(const char *const name, uint32_t &attr)=0
Retrieves attributes of a file on the Psion.
virtual Enum< errs > dir(const char *const name, PlpDir &ret)=0
Reads a directory on the Psion.
virtual Enum< errs > dircount(const char *const name, uint32_t &count)=0
Counts number of entries in a directory.
virtual Enum< errs > freplacefile(const uint32_t attr, const char *const name, uint32_t &handle)=0
Creates an named file, overwriting an existing file.
virtual int getProtocolVersion()=0
Retrieves the protocol version.
virtual Enum< errs > rmdir(const char *const name)=0
Removes a directory on the Psion.
virtual Enum< errs > devlist(uint32_t &devbits)=0
Retrieves available drives on the Psion.
virtual Enum< errs > devinfo(const char drive, Drive &dinfo)=0
Retrieves details about a drive.
static std::string convertSlash(const std::string &name)
Utility method, converts '/' to '\'.
virtual Enum< errs > rename(const char *const oldname, const char *const newname)=0
Renames a file on the Psion.
int getSpeed()
Retrieve speed of serial link.
virtual Enum< errs > copyFromPsion(const char *from, const char *to, void *context, cpCallback_t func)=0
Copies a file from the Psion to the local machine.
@ PSI_A_READ
Attributes, valid on SIBO only.
@ PSI_A_RDONLY
Attributes, valid on both EPOC and SIBO.
Remote procedure call services via PLP.
virtual Enum< RFSV::errs > getOwnerInfo(BufferArray &owner)=0
Retrieve owner information of the remote machine.
Enum< RFSV::errs > queryPrograms(processList &ret)
Retrieves a list of all running Programs.
virtual Enum< RFSV::errs > getMachineInfo(machineInfo &machineInfo)
Retrieve general Information about the connected machine.
virtual Enum< RFSV::errs > configRead(uint32_t size, BufferStore &data)
Read from Series 5 scratch RAM.
Enum< RFSV::errs > stopProgram(const char *program)
Requests termination of a program running on the remote machine.
Enum< RFSV::errs > getMachineType(Enum< machs > &type)
Retrieves the type of machine on the remote side as defined in machs.
Enum< RFSV::errs > execProgram(const char *program, const char *args)
Starts execution of a program on the remote machine.
virtual Enum< RFSV::errs > setTime(time_t time)
Remote ClipBoard services via PLP.
Enum< RFSV::errs > initClipbd()
Send initialization frame.
static char ** do_completion(const char *text, int start, int)
static char * join_string_vector(vector< char * > argv, const char *sep)
static int checkAbortHash(void *, uint32_t)
static int checkAbortNoHash(void *, uint32_t)
static void ascii2PsiText(char *buf, int len)
static void psiText2ascii(char *buf, int len)
static char * null_completion(const char *, int)
static char * epoc_dir_from(const char *path)
Compute new directory from path, which may be absolute or relative, and cwd.
static char * command_generator(const char *text, int state)
static const char * remote_dir_commands[]
static int startPrograms(RPCS &r, RFSV &a, const char *file)
static char * getln(FILE *fp)
static const char * all_commands[]
static const char * localfile_commands[]
static void sigint_handler2(int)
static int continueRunning
static char * filename_generator(const char *text, int state)
static char * slurp(FILE *fp, size_t *final_len)
static char * get_upto(FILE *fp, const char *term, size_t *final_len)
static int stopPrograms(RPCS &rpcs, const char *file)
static void sigint_handler(int)
char * resolve_epoc_path(const char *path, const char *initialPath)
Returns a new absolute EPOC path, determined by resolving path relative to initialPath.
std::string epoc_basename(std::string path)
Returns the last path component of an EPOC path.
int(* cpCallback_t)(void *, uint32_t)
Defines the callback procedure for progress indication of copy operations.
std::deque< class PlpDirent > PlpDir
std::vector< PsiProcess > processList
static void error(int line)
This struct holds the data returned by RPCS::getMachineInfo.
unsigned long mainBatteryUsedPower
Enum< languages > uiLanguage
unsigned long displayHeight
unsigned long mainBatteryVoltage
psi_timeval externalPowerUsedTime
Enum< batterystates > backupBatteryStatus
psi_timeval mainBatteryInsertionTime
Enum< machs > machineType
unsigned long ramDiskSize
unsigned long mainBatteryCurrent
psi_timeval mainBatteryUsedTime
Enum< batterystates > mainBatteryStatus
unsigned long countryCode
unsigned long long machineUID
unsigned long backupBatteryMaxVoltage
unsigned long registrySize
unsigned long displayWidth
unsigned long mainBatteryMaxVoltage
unsigned long backupBatteryVoltage