9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* Re: [9fans] 9p(1) rdwr, but return all records? con?
@ 2006-03-09  4:52 erik quanstrom
  0 siblings, 0 replies; 3+ messages in thread
From: erik quanstrom @ 2006-03-09  4:52 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 1280 bytes --]

perhaps, i rolled this up with an old version of 9p:

	echo google.com ip | ./9p wrrd dns/dns

dns/dns returns 1 record per read. i needed this so i could get
all the records.

i have not integrated this version of 9p with russ' current version.
that, as they say, is an exercize left to the reader.

- erik


"Anthony Sorace" <anothy@gmail.com> writes

|
| I need something very much like '9p rdwr', but that (minimally)
| returns all the records the serving resource spits out. No requirement
| that it be line-oriented; in fact, having it not be would probably be
| better in the long run, although it doesn't matter for the application
| at hand.
|
| I've seen the question asked here before, but in the archives only,
| and i figured i may have missed something: does anyone have such a
| beast?
|
| In examining 9p.c in preparation to roll my own, i came across an
| undocumented command: con. This seems to be very close (if not
| exactly) what i'd like. I've not been able to test it successfully
| yet, but i'm pretty sure i don't currently have any served resources
| that *don't* do what cs and friends do regarding looking for
| outstanding request on a fd. Does this sound plausible? Might con be
| what i (and others) are looking for?

[-- Attachment #2: 9p.c --]
[-- Type: text/plain, Size: 9061 bytes --]

#include <u.h>
#include <signal.h>
#include <libc.h>
#include <bio.h>
#include <fcall.h>
#include <9pclient.h>
#include <auth.h>
#include <thread.h>

char *addr;

void
usage(void)
{
	fprint(2, "usage: 9p [-a address] [-A aname] cmd args...\n");
	fprint(2, "possible cmds:\n");
	fprint(2, "	read name\n");
	fprint(2, "	readfd name\n");
	fprint(2, "	write [-l] name\n");
	fprint(2, "	writefd name\n");
	fprint(2, "	stat name\n");
	fprint(2, "	rdwr name\n");
	fprint(2, "	ls [-ld] name\n");
	fprint(2, "without -a, name elem/path means /path on server unix!$ns/elem\n");
	threadexitsall("usage");
}

char *aname;
void xread(int, char**);
void xwrite(int, char**);
void xreadfd(int, char**);
void xwritefd(int, char**);
void xstat(int, char**);
void xls(int, char**);
void xrdwr(int, char**);
void xcon(int, char**);

struct {
	char *s;
	void (*f)(int, char**);
} cmds[] = {
	"con", xcon,
	"read", xread,
	"write", xwrite,
	"readfd", xreadfd,
	"writefd", xwritefd,
	"stat", xstat,
	"rdwr", xrdwr,
	"ls", xls,
};

void
threadmain(int argc, char **argv)
{
	char *cmd;
	int i;

	ARGBEGIN{
	case 'A':
		aname = EARGF(usage());
		break;
	case 'a':
		addr = EARGF(usage());
		if(strchr(addr, '!') == nil)
			addr = netmkaddr(addr, "tcp", "9fs");
		break;
	case 'D':
		chatty9pclient = 1;
		break;
	default:
		usage();
	}ARGEND

	signal(SIGINT, SIG_DFL);

	if(argc < 1)
		usage();

	cmd = argv[0];
	for(i=0; i<nelem(cmds); i++){
		if(strcmp(cmds[i].s, cmd) == 0){
			cmds[i].f(argc, argv);
			threadexitsall(0);
		}
	}
	usage();
}

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 = nsamount(name, aname);
		if(fs == nil)
			sysfatal("mount: %r");
	}else{
		*path = name;
		if((fd = dial(addr, nil, nil, nil)) < 0)
			sysfatal("dial: %r");
		if((fs = fsamount(fd, aname)) == nil)
			sysfatal("fsamount: %r");
	}
	return fs;
}

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;
}

int
xopenfd(char *name, int mode)
{
	CFsys *fs;

	fs = xparse(name, &name);
	return fsopenfd(fs, name, mode);
}

void
xread(int argc, char **argv)
{
	char buf[4*4096];
	int n;
	CFid *fid;
	uvlong s;

	s=0;
	ARGBEGIN{
	case 's':
		s=strtoull(EARGF(usage), 0, 0);
		break;
	default:
		usage();
	}ARGEND

	if(argc != 1)
		usage();

	fid = xopen(argv[0], OREAD);
	if (s && s != fsseek(fid, s, 0))
		sysfatal("can't seek to offset %lld\n", s);

	while((n = fsread(fid, buf, sizeof buf)) > 0)
		write(1, buf, n);
	fsclose(fid);
	if(n < 0)
		sysfatal("read error: %r");
	threadexitsall(0);
}

void
xreadfd(int argc, char **argv)
{
	char buf[4096];
	int n;
	int fd;

	ARGBEGIN{
	default:
		usage();
	}ARGEND

	if(argc != 1)
		usage();

	fd = xopenfd(argv[0], OREAD);
	while((n = read(fd, buf, sizeof buf)) > 0)
		write(1, buf, n);
	if(n < 0)
		sysfatal("read error: %r");
	threadexitsall(0);
}

void
xwrite(int argc, char **argv)
{
	char buf[4096];
	int n, did;
	CFid *fid;
	Biobuf *b;
	char *p;
	int byline;

	byline = 0;
	ARGBEGIN{
	case 'l':
		byline = 1;
		break;
	default:
		usage();
	}ARGEND

	if(argc != 1)
		usage();

	did = 0;
	fid = xopen(argv[0], OWRITE|OTRUNC);
	if(byline){
		n = 0;
		b = malloc(sizeof *b);
		if(b == nil)
			sysfatal("out of memory");
		Binit(b, 0, OREAD);
		while((p = Brdstr(b, '\n', 0)) != nil){
			n = strlen(p);
			did = 1;
			if(fswrite(fid, p, n) != n)
				fprint(2, "write: %r\n");
		}
		free(b);
	}else{
		while((n = read(0, buf, sizeof buf)) > 0){
			did = 1;
			if(fswrite(fid, buf, n) != n)
				sysfatal("write error: %r");
		}
	}
	if(n == 0 && !did){
		if(fswrite(fid, buf, 0) != 0)
			sysfatal("write error: %r");
	}
	if(n < 0)
		sysfatal("read error: %r");
	fsclose(fid);
	threadexitsall(0);
}

void
xwritefd(int argc, char **argv)
{
	char buf[4096];
	int n;
	int fd;

	ARGBEGIN{
	default:
		usage();
	}ARGEND

	if(argc != 1)
		usage();

	fd = xopenfd(argv[0], OWRITE|OTRUNC);
	while((n = read(0, buf, sizeof buf)) > 0)
		if(write(fd, buf, n) != n)
			sysfatal("write error: %r");
	if(n < 0)
		sysfatal("read error: %r");
	threadexitsall(0);
}

void
xstat(int argc, char **argv)
{
	Dir *d;
	CFsys *fs;
	char *name;

	ARGBEGIN{
	default:
		usage();
	}ARGEND

	if(argc != 1)
		usage();

	name = argv[0];
	fs = xparse(name, &name);
	if((d = fsdirstat(fs, name)) == 0)
		sysfatal("dirstat: %r");
	fmtinstall('D', dirfmt);
	fmtinstall('M', dirmodefmt);
	print("%D\n", d);
	threadexitsall(0);
}

void
xrdwr(int argc, char **argv)
{
	char buf[4096];
	int n;
	CFid *fid;

	ARGBEGIN{
	default:
		usage();
	}ARGEND

	if(argc != 1)
		usage();

	fid = xopen(argv[0], ORDWR);
	for(;;){
		if((n = fsread(fid, buf, sizeof buf)) < 0)
			fprint(2, "read: %r\n");
		else{
			write(1, buf, n);
			write(1, "\n", 1);
		}
		n = read(0, buf, sizeof buf);
		if(n <= 0)
			break;
		if(buf[n-1] == '\n')
			n--;
		if(fswrite(fid, buf, n) != n)
			fprint(2, "write: %r\n");
	}
	fsclose(fid);
	threadexitsall(0);
}

void
rdcon(void *v)
{
	int n;
	char buf[4096];
	CFid *fid;

	fid = v;
	for(;;){
		n = read(0, buf, sizeof buf);
		if(n <= 0)
			threadexitsall(0);
		if(buf[0] == 'R'-'A'+1)
			threadexitsall(0);
		if(fswrite(fid, buf, n) != n)
			fprint(2, "write: %r\n");
	}
}

void
wrcon(CFid* fid)
{
	int n;
	char buf[4096];

	for(;;){
		n = read(0, buf, sizeof buf);
		if(n <= 0)
			return;
		if(fswrite(fid, buf, n) != n)
			fprint(2, "write: %r\n");
	}
}

void
xcon(int argc, char **argv)
{
	char buf[4096], *r, *w, *e;
	int n, nocr, sync, nl;
	CFid *fid;

	nocr = 1;
	sync = 0;
	nl = 0;

	ARGBEGIN{
	case 'n':
		nl=1;
		break;
	case 'r':
		nocr = 0;
		break;
	case 's':
		sync = 1;
		break;
	default:
		usage();
	}ARGEND

	if(argc != 1)
		usage();

	fid = xopen(argv[0], ORDWR);
	if (!sync)
		proccreate(rdcon, fid, 32768);
	else
		wrcon(fid);

	for(;;){
		n = fsread(fid, buf, sizeof buf);
		if(n <= 0)
			break;
		if(nocr){
			for(r=w=buf, e=buf+n; r<e; r++)
				if(*r != '\r')
					*w++ = *r;
			n = w-buf;
		}
		if(write(1, buf, n) != n)
			break;
		if (nl)
			write(1, "\n", 1);
	}
	fsclose(fid);
	threadexitsall(0);
}

static char *mon[] =
{
	"Jan", "Feb", "Mar", "Apr", "May", "Jun",
	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};


int
timefmt(Fmt *fmt)
{
	ulong u;
	static ulong time0;
	Tm *tm;

	if(time0 == 0)
		time0 = time(0);
	u = va_arg(fmt->args, ulong);
	tm = localtime(u);
	if((long)(time0-u) < 6*30*86400)
		return fmtprint(fmt, "%s %2d %02d:%02d",
			mon[tm->mon], tm->mday, tm->hour, tm->min);
	return fmtprint(fmt, "%s %2d %5d",
		mon[tm->mon], tm->mday, tm->year+1900);
}

static int
dircmp(const void *va, const void *vb)
{
	Dir *a, *b;

	a = (Dir*)va;
	b = (Dir*)vb;
	return strcmp(a->name, b->name);
}

void
xls(int argc, char **argv)
{
	char *err, *name, *xname, *f[4], buf[4096];
	int nf, i, j, l;
	int lflag, dflag, n, len[4];
	Dir *d;
	CFid *fid;
	CFsys *fs;

	err = nil;
	lflag = dflag = 0;
	ARGBEGIN{
	case 'l':
		lflag = 1;
		break;
	case 'd':
		dflag = 1;
		break;
	}ARGEND

	fmtinstall('D', dirfmt);
	fmtinstall('M', dirmodefmt);
	quotefmtinstall();
	fmtinstall('T', timefmt);

	for(i=0; i<argc; i++){
		name = argv[i];
		fs = xparse(name, &xname);
		if((d = fsdirstat(fs, xname)) == nil){
			fprint(2, "dirstat %s: %r\n", name);
			fsunmount(fs);
			err = "errors";
			continue;
		}
		if((d->mode&DMDIR) && !dflag){
			if((fid = fsopen(fs, xname, OREAD)) == nil){
				fprint(2, "open %s: %r\n", name);
				fsunmount(fs);
				free(d);
				err = "errors";
				continue;
			}
			free(d);
			n = fsdirreadall(fid, &d);
			fsclose(fid);
			if(n < 0){
				fprint(2, "dirreadall %s: %r\n", name);
				fsunmount(fs);
				err = "errors";
				continue;
			}
			qsort(d, n, sizeof d[0], dircmp);
			for(j=0; j<5; j++)
				len[j] = 0;
			for(i=0; i<n; i++){
				d[i].type = 'M';
				d[i].dev = 0;
				snprint(buf, sizeof buf, "%d %s %s %lld",
					d[i].dev, d[i].uid, d[i].gid, d[i].length);
				nf = getfields(buf, f, 4, 0, " ");
				for(j=0; j<4; j++){
					l = strlen(f[j]);
					if(l > len[j])
						len[j] = l;
				}
			}
			for(i=0; i<n; i++)
				print("%M %C %*d %*s %*s %*lld %T %q\n",
					d[i].mode, d[i].type, len[0], d[i].dev,
					-len[1], d[i].uid, -len[2], d[i].gid,
					len[3], d[i].length, d[i].mtime, d[i].name);

		}else{
			d->type = 'M';
			d->dev = 0;
			print("%M %C %d %s %s %lld %T %q\n",
				d->mode, d->type, d->dev,
				d->uid, d->gid, d->length, d->mtime, d->name);
		}
		free(d);
	}
	threadexitsall(err);
}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [9fans] 9p(1) rdwr, but return all records? con?
  2006-03-09  2:38 Anthony Sorace
@ 2006-03-09  2:46 ` Russ Cox
  0 siblings, 0 replies; 3+ messages in thread
From: Russ Cox @ 2006-03-09  2:46 UTC (permalink / raw)
  To: 9fans

> In examining 9p.c in preparation to roll my own, i came across an
> undocumented command: con. This seems to be very close (if not
> exactly) what i'd like. I've not been able to test it successfully
> yet, but i'm pretty sure i don't currently have any served resources
> that *don't* do what cs and friends do regarding looking for
> outstanding request on a fd. Does this sound plausible? Might con be
> what i (and others) are looking for?

Why not try it and find out?
Surely you could answer this question better than anyone else.

Russ



^ permalink raw reply	[flat|nested] 3+ messages in thread

* [9fans] 9p(1) rdwr, but return all records? con?
@ 2006-03-09  2:38 Anthony Sorace
  2006-03-09  2:46 ` Russ Cox
  0 siblings, 1 reply; 3+ messages in thread
From: Anthony Sorace @ 2006-03-09  2:38 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

I need something very much like '9p rdwr', but that (minimally)
returns all the records the serving resource spits out. No requirement
that it be line-oriented; in fact, having it not be would probably be
better in the long run, although it doesn't matter for the application
at hand.

I've seen the question asked here before, but in the archives only,
and i figured i may have missed something: does anyone have such a
beast?

In examining 9p.c in preparation to roll my own, i came across an
undocumented command: con. This seems to be very close (if not
exactly) what i'd like. I've not been able to test it successfully
yet, but i'm pretty sure i don't currently have any served resources
that *don't* do what cs and friends do regarding looking for
outstanding request on a fd. Does this sound plausible? Might con be
what i (and others) are looking for?

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-03-09  4:52 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-03-09  4:52 [9fans] 9p(1) rdwr, but return all records? con? erik quanstrom
  -- strict thread matches above, loose matches on Subject: below --
2006-03-09  2:38 Anthony Sorace
2006-03-09  2:46 ` Russ Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).