#include #include #include #include #include #include <9pclient.h> char *addr; char *aname; void xread(int, char**); CFid* xopen(char*, int); CFsys* xparse(char*, char**); /* * TODO: add authentication (for plumber? really?) make sure we're not assuming atomicity unsafely */ /* Format of a plumbing message, from plumb(7): src application/service generating message dst destination `port' for message wdir working directory (used if data is a file name) type form of the data, e.g. text attr attributes of the message, in name=value pairs separated by white space (the value must follow the usual quoting convention if it contains white space or quote characters or equal signs; it cannot contain a newline) ndata number of bytes of data data the data itself */ void usage(void) { fprint(2, "usage: plumbread address\n"); threadexits("usage"); } void threadmain(int argc, char **argv) { xread(argc, argv); } /* Adapted from 9p.c */ void xread(int argc, char **argv) { char buf[4096]; char *fields[7]; int n, m; CFid *fid; ARGBEGIN{ default: usage(); }ARGEND if(argc != 1) usage(); quotefmtinstall(); doquote = needsrcquote; fid = xopen(argv[0], OREAD); // while((n = fsread(fid, buf, sizeof buf)) > 0) n = fsread(fid, buf, sizeof buf); // if(write(1, buf, n) < 0) // sysfatal("write error: %r"); m = gettokens(buf, fields, nelem(fields), "\r\n"); print("source=%s destination=%s workdir=%s type=%s attr=%q ndata=%s data=%s",\ fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6]); fsclose(fid); if(n < 0) sysfatal("read error: %r"); threadexitsall(0); } /* Below taken from 9p.c */ CFid* xopen(char *name, int mode) { CFid *fid; CFsys *fs; fs = xparse(name, &name); fid = fsopen(fs, name, mode); if(fid == nil) sysfatal("fsopen %s: %r", name); return fid; } CFsys* xparse(char *name, char **path) { int fd; char *p; CFsys *fs; if(addr == nil){ p = strchr(name, '/'); if(p == nil) p = name+strlen(name); else *p++ = 0; *path = p; fs = nsmount(name, aname); if(fs == nil) sysfatal("mount: %r"); }else{ *path = name; if((fd = dial(addr, nil, nil, nil)) < 0) sysfatal("dial: %r"); if((fs = fsmount(fd, aname)) == nil) sysfatal("mount: %r"); } return fs; }