#include <u.h>
#include <libc.h>
#include <plumb.h>
#include <fcall.h>
#include <thread.h>
#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;
}
|