With the -9 flag, we can run drawterm on a remote system over ssh, and have it export the remotes namespace. Thru the /cmd interface (see os(1)), one can launch native programs on the remote host and access the remote file system.
Unified · Split
| @@ -27,6 +27,7 @@ static int aanto = 3600 * 24; · 26 unmodified lines | ||
| 27 | 27 | static int norcpu; |
| 28 | 28 | static int nokbd; |
| 29 | 29 | static int nogfx; |
| 30 | +static int nineflag; | |
| 30 | 31 | |
| 31 | 32 | static char *ealgs = "rc4_256 sha1"; |
| 32 | 33 | |
| @@ -176,7 +177,7 @@ rcpu(char *host, char *cmd) · 143 unmodified lines | ||
| 176 | 177 | atexit(rcpuexit); |
| 177 | 178 | |
| 178 | 179 | /* Begin serving the namespace */ |
| 179 | − exportfs(fd); | |
| 180 | + exportfs(fd, fd); | |
| 180 | 181 | } |
| 181 | 182 | |
| 182 | 183 | void |
| @@ -236,13 +237,13 @@ ncpu(char *host, char *cmd) · 53 unmodified lines | ||
| 236 | 237 | write(fd, "OK", 2); |
| 237 | 238 | |
| 238 | 239 | /* Begin serving the gnot namespace */ |
| 239 | − exportfs(fd); | |
| 240 | + exportfs(fd, fd); | |
| 240 | 241 | } |
| 241 | 242 | |
| 242 | 243 | void |
| 243 | 244 | usage(void) |
| 244 | 245 | { |
| 245 | − fprint(2, "usage: %s [-GBO] " | |
| 246 | + fprint(2, "usage: %s [-9GBO] " | |
| 246 | 247 | "[-h host] [-u user] [-a authserver] [-s secstore] " |
| 247 | 248 | "[-e 'crypt hash'] [-k keypattern] " |
| 248 | 249 | "[-p] [-t timeout] " |
| @@ -262,12 +263,13 @@ cpumain(int argc, char **argv) · 13 unmodified lines | ||
| 262 | 263 | char *s; |
| 263 | 264 | |
| 264 | 265 | user = getenv("USER"); |
| 265 | − if((pass = getenv("PASS")) != nil) | |
| 266 | − remove("/env/PASS"); | |
| 267 | 266 | host = getenv("cpu"); |
| 268 | 267 | authserver = getenv("auth"); |
| 269 | 268 | |
| 270 | 269 | ARGBEGIN{ |
| 270 | + case '9': | |
| 271 | + nineflag = 1; | |
| 272 | + /* wet floor */ | |
| 271 | 273 | case 'G': |
| 272 | 274 | nogfx = 1; |
| 273 | 275 | /* wet floor */ |
| @@ -320,8 +322,8 @@ cpumain(int argc, char **argv) · 46 unmodified lines | ||
| 320 | 322 | break; |
| 321 | 323 | case 'g': |
| 322 | 324 | /* X11 geometry string |
| 323 | − [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>] | |
| 324 | − */ | |
| 325 | + * [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>] | |
| 326 | + */ | |
| 325 | 327 | geometry = EARGF(usage()); |
| 326 | 328 | break; |
| 327 | 329 | default: |
| @@ -331,6 +333,14 @@ cpumain(int argc, char **argv) · 3 unmodified lines | ||
| 331 | 333 | if(argc != 0) |
| 332 | 334 | usage(); |
| 333 | 335 | |
| 336 | + if(nineflag){ | |
| 337 | + exportfs(lfdfd(0), lfdfd(1)); | |
| 338 | + return; | |
| 339 | + } | |
| 340 | + | |
| 341 | + if((pass = getenv("PASS")) != nil) | |
| 342 | + remove("/env/PASS"); | |
| 343 | + | |
| 334 | 344 | if(!nogfx) |
| 335 | 345 | guimain(); |
| 336 | 346 | else |
| @@ -6,7 +6,7 @@ drawterm \- connection to cpu, fs, and auth servers · 5 unmodified lines | ||
| 6 | 6 | .SH SYNOPSIS |
| 7 | 7 | .B drawterm |
| 8 | 8 | [ |
| 9 | −.B -GBO | |
| 9 | +.B -9GBO | |
| 10 | 10 | ] [ |
| 11 | 11 | .B -h |
| 12 | 12 | .I host |
| @@ -50,6 +50,12 @@ The goal of drawterm is to provide an abstraction layer from the client operatin · 37 unmodified lines | ||
| 50 | 50 | The options are: |
| 51 | 51 | .PD |
| 52 | 52 | |
| 53 | +.TP | |
| 54 | +.B -9 | |
| 55 | +Start drawterm in 9P mode; | |
| 56 | +exporting the namespace over 9P on standard input and output. | |
| 57 | +Graphics and keyboard input are disabled. | |
| 58 | + | |
| 53 | 59 | .TP |
| 54 | 60 | .B -G |
| 55 | 61 | Start drawterm in text-only mode (no graphics). |
| @@ -2,7 +2,7 @@ extern int havesecstore(char *addr, char *owner); · 1 unmodified line | ||
| 2 | 2 | extern char *secstore; |
| 3 | 3 | extern char *secstorefetch(char *addr, char *owner, char *passwd); |
| 4 | 4 | extern char *authserver; |
| 5 | −extern int exportfs(int); | |
| 5 | +extern int exportfs(int, int); | |
| 6 | 6 | extern int dialfactotum(void); |
| 7 | 7 | extern char *getuser(void); |
| 8 | 8 | extern void cpumain(int, char**); |
| @@ -9,7 +9,6 @@ · 8 unmodified lines | ||
| 9 | 9 | #define Extern |
| 10 | 10 | #include "exportfs.h" |
| 11 | 11 | |
| 12 | −/* #define QIDPATH ((1LL<<48)-1) */ | |
| 13 | 12 | #define QIDPATH ((((vlong)1)<<48)-1) |
| 14 | 13 | vlong newqid = 0; |
| 15 | 14 | |
| @@ -21,15 +20,16 @@ int freecnt; · 5 unmodified lines | ||
| 21 | 20 | int qidcnt; |
| 22 | 21 | int qfreecnt; |
| 23 | 22 | int ncollision; |
| 24 | −int netfd; | |
| 23 | +int netfd[2]; | |
| 25 | 24 | |
| 26 | 25 | int |
| 27 | −exportfs(int fd) | |
| 26 | +exportfs(int rfd, int wfd) | |
| 28 | 27 | { |
| 29 | 28 | char buf[ERRMAX], ebuf[ERRMAX]; |
| 30 | 29 | Fsrpc *r; |
| 31 | 30 | int i, n; |
| 32 | 31 | |
| 32 | + | |
| 33 | 33 | fcalls[Tversion] = Xversion; |
| 34 | 34 | fcalls[Tauth] = Xauth; |
| 35 | 35 | fcalls[Tflush] = Xflush; |
| @@ -45,22 +45,18 @@ exportfs(int fd) · 9 unmodified lines | ||
| 45 | 45 | fcalls[Twstat] = Xwstat; |
| 46 | 46 | |
| 47 | 47 | srvfd = -1; |
| 48 | − netfd = fd; | |
| 49 | − //dbg = 1; | |
| 48 | + netfd[0] = rfd; | |
| 49 | + netfd[1] = wfd; | |
| 50 | 50 | |
| 51 | 51 | strcpy(buf, "this is buf"); |
| 52 | 52 | strcpy(ebuf, "this is ebuf"); |
| 53 | 53 | DEBUG(DFD, "exportfs: started\n"); |
| 54 | 54 | |
| 55 | −// rfork(RFNOTEG); | |
| 56 | − | |
| 57 | − messagesize = iounit(netfd); | |
| 55 | + messagesize = iounit(rfd); | |
| 58 | 56 | if(messagesize == 0) |
| 59 | 57 | messagesize = IOUNIT+IOHDRSZ; |
| 60 | 58 | |
| 61 | 59 | Workq = emallocz(sizeof(Fsrpc)*Nr_workbufs); |
| 62 | −// for(i=0; i<Nr_workbufs; i++) | |
| 63 | −// Workq[i].buf = emallocz(messagesize); | |
| 64 | 60 | fhash = emallocz(sizeof(Fid*)*FHASHSIZE); |
| 65 | 61 | |
| 66 | 62 | fmtinstall('F', fcallfmt); |
| @@ -78,7 +74,7 @@ exportfs(int fd) · 11 unmodified lines | ||
| 78 | 74 | fatal("Out of service buffers"); |
| 79 | 75 | |
| 80 | 76 | DEBUG(DFD, "read9p..."); |
| 81 | − n = read9pmsg(netfd, r->buf, messagesize); | |
| 77 | + n = read9pmsg(netfd[0], r->buf, messagesize); | |
| 82 | 78 | if(n <= 0) |
| 83 | 79 | fatal(nil); |
| 84 | 80 | |
| @@ -122,7 +118,7 @@ if(0) iprint("-> %F\n", t); · 37 unmodified lines | ||
| 122 | 118 | if(data == nil) |
| 123 | 119 | fatal(Enomem); |
| 124 | 120 | n = convS2M(t, data, messagesize); |
| 125 | − if((m=write(netfd, data, n))!=n){ | |
| 121 | + if((m=write(netfd[1], data, n))!=n){ | |
| 126 | 122 | iprint("wrote %d got %d (%r)\n", n, m); |
| 127 | 123 | fatal("write"); |
| 128 | 124 | } |
| @@ -15,7 +15,7 @@ char Enomem[] = "No memory"; · 14 unmodified lines | ||
| 15 | 15 | char Eversion[] = "Bad 9P2000 version"; |
| 16 | 16 | |
| 17 | 17 | void* |
| 18 | −emallocz(ulong n) | |
| 18 | +emallocz(uint n) | |
| 19 | 19 | { |
| 20 | 20 | void *v; |
| 21 | 21 | |
| @@ -23,6 +23,26 @@ lfdchan(void *fd) · 22 unmodified lines | ||
| 23 | 23 | return c; |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | +/* | |
| 27 | + * only good for stdin/stdout/stderr | |
| 28 | + */ | |
| 29 | +int | |
| 30 | +lfdfd(int fd) | |
| 31 | +{ | |
| 32 | + HANDLE h; | |
| 33 | + | |
| 34 | + switch(fd){ | |
| 35 | + case 0: h = GetStdHandle(STD_INPUT_HANDLE); break; | |
| 36 | + case 1: h = GetStdHandle(STD_OUTPUT_HANDLE); break; | |
| 37 | + case 2: h = GetStdHandle(STD_ERROR_HANDLE); break; | |
| 38 | + default: | |
| 39 | + return -1; | |
| 40 | + } | |
| 41 | + if(h == INVALID_HANDLE_VALUE) | |
| 42 | + return -1; | |
| 43 | + return newfd(lfdchan((void*)h)); | |
| 44 | +} | |
| 45 | + | |
| 26 | 46 | static Chan* |
| 27 | 47 | lfdattach(char *x) |
| 28 | 48 | { |