17dd7cddfSDavid du Colombier /*
27dd7cddfSDavid du Colombier * Remote debugging file system
37dd7cddfSDavid du Colombier */
47dd7cddfSDavid du Colombier
57dd7cddfSDavid du Colombier #include <u.h>
67dd7cddfSDavid du Colombier #include <libc.h>
77dd7cddfSDavid du Colombier #include <auth.h>
87dd7cddfSDavid du Colombier #include <fcall.h>
97dd7cddfSDavid du Colombier #include <bio.h>
109a747e4fSDavid du Colombier #include <thread.h>
119a747e4fSDavid du Colombier #include <9p.h>
127dd7cddfSDavid du Colombier
137dd7cddfSDavid du Colombier int dbg = 0;
147dd7cddfSDavid du Colombier #define DBG if(dbg)fprint
157dd7cddfSDavid du Colombier
167dd7cddfSDavid du Colombier enum {
177dd7cddfSDavid du Colombier NHASH = 4096,
187dd7cddfSDavid du Colombier Readlen = 4,
197dd7cddfSDavid du Colombier Pagequantum = 1024,
207dd7cddfSDavid du Colombier };
217dd7cddfSDavid du Colombier
227dd7cddfSDavid du Colombier /* caching memory pages: a lot of space to avoid serial communications */
237dd7cddfSDavid du Colombier Lock pglock;
247dd7cddfSDavid du Colombier typedef struct Page Page;
257dd7cddfSDavid du Colombier struct Page { /* cached memory contents */
267dd7cddfSDavid du Colombier Page *link;
277dd7cddfSDavid du Colombier ulong len;
287dd7cddfSDavid du Colombier ulong addr;
299a747e4fSDavid du Colombier int count;
307dd7cddfSDavid du Colombier uchar val[Readlen];
317dd7cddfSDavid du Colombier };
327dd7cddfSDavid du Colombier
337dd7cddfSDavid du Colombier Page *pgtab[NHASH];
347dd7cddfSDavid du Colombier
357dd7cddfSDavid du Colombier Page *freelist;
367dd7cddfSDavid du Colombier
377dd7cddfSDavid du Colombier /* called with pglock locked */
387dd7cddfSDavid du Colombier Page*
newpg(void)397dd7cddfSDavid du Colombier newpg(void)
407dd7cddfSDavid du Colombier {
417dd7cddfSDavid du Colombier int i;
427dd7cddfSDavid du Colombier Page *p, *q;
437dd7cddfSDavid du Colombier
447dd7cddfSDavid du Colombier if(freelist == nil){
457dd7cddfSDavid du Colombier p = malloc(sizeof(Page)*Pagequantum);
467dd7cddfSDavid du Colombier if(p == nil)
477dd7cddfSDavid du Colombier sysfatal("out of memory");
487dd7cddfSDavid du Colombier
497dd7cddfSDavid du Colombier for(i=0, q=p; i<Pagequantum-1; i++, q++)
507dd7cddfSDavid du Colombier q->link = q+1;
517dd7cddfSDavid du Colombier q->link = nil;
527dd7cddfSDavid du Colombier
537dd7cddfSDavid du Colombier freelist = p;
547dd7cddfSDavid du Colombier }
557dd7cddfSDavid du Colombier p = freelist;
567dd7cddfSDavid du Colombier freelist = freelist->link;
577dd7cddfSDavid du Colombier return p;
587dd7cddfSDavid du Colombier }
597dd7cddfSDavid du Colombier
607dd7cddfSDavid du Colombier #define PHIINV 0.61803398874989484820
617dd7cddfSDavid du Colombier uint
ahash(ulong addr)627dd7cddfSDavid du Colombier ahash(ulong addr)
637dd7cddfSDavid du Colombier {
647dd7cddfSDavid du Colombier return (uint)floor(NHASH*fmod(addr*PHIINV, 1.0));
657dd7cddfSDavid du Colombier }
667dd7cddfSDavid du Colombier
677dd7cddfSDavid du Colombier int
lookup(ulong addr,uchar * val,ulong count)689a747e4fSDavid du Colombier lookup(ulong addr, uchar *val, ulong count)
697dd7cddfSDavid du Colombier {
707dd7cddfSDavid du Colombier Page *p;
717dd7cddfSDavid du Colombier
727dd7cddfSDavid du Colombier lock(&pglock);
737dd7cddfSDavid du Colombier for(p=pgtab[ahash(addr)]; p; p=p->link){
749a747e4fSDavid du Colombier if(p->addr == addr && p->count == count){
759a747e4fSDavid du Colombier memmove(val, p->val, count);
767dd7cddfSDavid du Colombier unlock(&pglock);
777dd7cddfSDavid du Colombier return 1;
787dd7cddfSDavid du Colombier }
797dd7cddfSDavid du Colombier }
807dd7cddfSDavid du Colombier unlock(&pglock);
817dd7cddfSDavid du Colombier return 0;
827dd7cddfSDavid du Colombier }
837dd7cddfSDavid du Colombier
847dd7cddfSDavid du Colombier void
insert(ulong addr,uchar * val,int count)859a747e4fSDavid du Colombier insert(ulong addr, uchar *val, int count)
867dd7cddfSDavid du Colombier {
877dd7cddfSDavid du Colombier Page *p;
887dd7cddfSDavid du Colombier uint h;
897dd7cddfSDavid du Colombier
907dd7cddfSDavid du Colombier lock(&pglock);
917dd7cddfSDavid du Colombier p = newpg();
927dd7cddfSDavid du Colombier p->addr = addr;
939a747e4fSDavid du Colombier p->count = count;
949a747e4fSDavid du Colombier memmove(p->val, val, count);
957dd7cddfSDavid du Colombier h = ahash(addr);
967dd7cddfSDavid du Colombier p->link = pgtab[h];
977dd7cddfSDavid du Colombier p->len = pgtab[h] ? pgtab[h]->len+1 : 1;
987dd7cddfSDavid du Colombier pgtab[h] = p;
997dd7cddfSDavid du Colombier unlock(&pglock);
1007dd7cddfSDavid du Colombier }
1017dd7cddfSDavid du Colombier
1027dd7cddfSDavid du Colombier void
flushcache(void)1037dd7cddfSDavid du Colombier flushcache(void)
1047dd7cddfSDavid du Colombier {
1057dd7cddfSDavid du Colombier int i;
1067dd7cddfSDavid du Colombier Page *p;
1077dd7cddfSDavid du Colombier
1087dd7cddfSDavid du Colombier lock(&pglock);
1097dd7cddfSDavid du Colombier for(i=0; i<NHASH; i++){
1107dd7cddfSDavid du Colombier if(p=pgtab[i]){
1117dd7cddfSDavid du Colombier for(;p->link; p=p->link)
1127dd7cddfSDavid du Colombier ;
1137dd7cddfSDavid du Colombier p->link = freelist;
1147dd7cddfSDavid du Colombier freelist = p;
1157dd7cddfSDavid du Colombier }
1167dd7cddfSDavid du Colombier pgtab[i] = nil;
1177dd7cddfSDavid du Colombier }
1187dd7cddfSDavid du Colombier unlock(&pglock);
1197dd7cddfSDavid du Colombier }
1207dd7cddfSDavid du Colombier
1217dd7cddfSDavid du Colombier enum
1227dd7cddfSDavid du Colombier {
1239a747e4fSDavid du Colombier Xctl = 1,
1249a747e4fSDavid du Colombier Xfpregs,
1259a747e4fSDavid du Colombier Xkregs,
1269a747e4fSDavid du Colombier Xmem,
1279a747e4fSDavid du Colombier Xproc,
1289a747e4fSDavid du Colombier Xregs,
1299a747e4fSDavid du Colombier Xtext,
1309a747e4fSDavid du Colombier Xstatus,
1317dd7cddfSDavid du Colombier
1327dd7cddfSDavid du Colombier };
1337dd7cddfSDavid du Colombier
1347dd7cddfSDavid du Colombier int textfd;
1357dd7cddfSDavid du Colombier int rfd;
1367dd7cddfSDavid du Colombier Biobuf rfb;
1377dd7cddfSDavid du Colombier char* portname = "/dev/eia0";
1387dd7cddfSDavid du Colombier char* textfile = "/386/9pc";
1397dd7cddfSDavid du Colombier char* procname = "1";
140*062a8c88SDavid du Colombier char* srvname;
1419a747e4fSDavid du Colombier Channel* rchan;
1427dd7cddfSDavid du Colombier
1437dd7cddfSDavid du Colombier void
usage(void)1447dd7cddfSDavid du Colombier usage(void)
1457dd7cddfSDavid du Colombier {
146*062a8c88SDavid du Colombier fprint(2, "usage: rdbfs [-p procnum] [-s srvname] [-t textfile] [serialport]\n");
1477dd7cddfSDavid du Colombier exits("usage");
1487dd7cddfSDavid du Colombier }
1497dd7cddfSDavid du Colombier
1507dd7cddfSDavid du Colombier void
noalarm(void *,char * msg)1517dd7cddfSDavid du Colombier noalarm(void*, char *msg)
1527dd7cddfSDavid du Colombier {
1537dd7cddfSDavid du Colombier if(strstr(msg, "alarm"))
1547dd7cddfSDavid du Colombier noted(NCONT);
1557dd7cddfSDavid du Colombier noted(NDFLT);
1567dd7cddfSDavid du Colombier }
1577dd7cddfSDavid du Colombier
1587dd7cddfSDavid du Colombier /*
1597dd7cddfSDavid du Colombier * send and receive responses on the serial line
1607dd7cddfSDavid du Colombier */
1617dd7cddfSDavid du Colombier void
eiaread(void *)1629a747e4fSDavid du Colombier eiaread(void*)
1637dd7cddfSDavid du Colombier {
1649a747e4fSDavid du Colombier Req *r;
1657dd7cddfSDavid du Colombier char *p;
1667dd7cddfSDavid du Colombier uchar *data;
1679a747e4fSDavid du Colombier char err[ERRMAX];
1687dd7cddfSDavid du Colombier char buf[1000];
1697dd7cddfSDavid du Colombier int i, tries;
1707dd7cddfSDavid du Colombier
1717dd7cddfSDavid du Colombier notify(noalarm);
1729a747e4fSDavid du Colombier while(r = recvp(rchan)){
1739a747e4fSDavid du Colombier DBG(2, "got %F: here goes...", &r->ifcall);
1749a747e4fSDavid du Colombier if(r->ifcall.count > Readlen)
1759a747e4fSDavid du Colombier r->ifcall.count = Readlen;
1769a747e4fSDavid du Colombier r->ofcall.count = r->ifcall.count;
1779a747e4fSDavid du Colombier if(r->type == Tread && lookup(r->ifcall.offset, (uchar*)r->ofcall.data, r->ofcall.count)){
1789a747e4fSDavid du Colombier respond(r, nil);
1797dd7cddfSDavid du Colombier continue;
1807dd7cddfSDavid du Colombier }
1817dd7cddfSDavid du Colombier for(tries=0; tries<5; tries++){
1827dd7cddfSDavid du Colombier if(r->type == Twrite){
1839a747e4fSDavid du Colombier DBG(2, "w%.8lux %.8lux...", (ulong)r->ifcall.offset, *(ulong*)r->ifcall.data);
1849a747e4fSDavid du Colombier fprint(rfd, "w%.8lux %.8lux\n", (ulong)r->ifcall.offset, *(ulong*)r->ifcall.data);
1857dd7cddfSDavid du Colombier }else if(r->type == Tread){
1869a747e4fSDavid du Colombier DBG(2, "r%.8lux...", (ulong)r->ifcall.offset);
1879a747e4fSDavid du Colombier fprint(rfd, "r%.8lux\n", (ulong)r->ifcall.offset);
1887dd7cddfSDavid du Colombier }else{
1899a747e4fSDavid du Colombier respond(r, "oops");
1907dd7cddfSDavid du Colombier break;
1917dd7cddfSDavid du Colombier }
1927dd7cddfSDavid du Colombier for(;;){
1937dd7cddfSDavid du Colombier werrstr("");
1947dd7cddfSDavid du Colombier alarm(500);
1957dd7cddfSDavid du Colombier p=Brdline(&rfb, '\n');
1967dd7cddfSDavid du Colombier alarm(0);
1977dd7cddfSDavid du Colombier if(p == nil){
1989a747e4fSDavid du Colombier rerrstr(err, sizeof err);
1997dd7cddfSDavid du Colombier DBG(2, "error %s\n", err);
2007dd7cddfSDavid du Colombier if(strstr(err, "alarm") || strstr(err, "interrupted"))
2017dd7cddfSDavid du Colombier break;
2027dd7cddfSDavid du Colombier if(Blinelen(&rfb) == 0) // true eof
2037dd7cddfSDavid du Colombier sysfatal("eof on serial line?");
2047dd7cddfSDavid du Colombier Bread(&rfb, buf, Blinelen(&rfb)<sizeof buf ? Blinelen(&rfb) : sizeof buf);
2057dd7cddfSDavid du Colombier continue;
2067dd7cddfSDavid du Colombier }
2077dd7cddfSDavid du Colombier p[Blinelen(&rfb)-1] = 0;
2087dd7cddfSDavid du Colombier if(p[0] == '\r')
2097dd7cddfSDavid du Colombier p++;
2107dd7cddfSDavid du Colombier DBG(2, "serial %s\n", p);
2117dd7cddfSDavid du Colombier if(p[0] == 'R'){
2129a747e4fSDavid du Colombier if(strtoul(p+1, 0, 16) == (ulong)r->ifcall.offset){
2139a747e4fSDavid du Colombier /* we know that data can handle Readlen bytes */
2149a747e4fSDavid du Colombier data = (uchar*)r->ofcall.data;
2159a747e4fSDavid du Colombier for(i=0; i<r->ifcall.count; i++)
2167dd7cddfSDavid du Colombier data[i] = strtol(p+1+8+1+3*i, 0, 16);
2179a747e4fSDavid du Colombier insert(r->ifcall.offset, data, r->ifcall.count);
2189a747e4fSDavid du Colombier respond(r, nil);
2197dd7cddfSDavid du Colombier goto Break2;
2207dd7cddfSDavid du Colombier }else
2219a747e4fSDavid du Colombier DBG(2, "%.8lux ≠ %.8lux\n", strtoul(p+1, 0, 16), (ulong)r->ifcall.offset);
2227dd7cddfSDavid du Colombier }else if(p[0] == 'W'){
2239a747e4fSDavid du Colombier respond(r, nil);
2247dd7cddfSDavid du Colombier goto Break2;
2257dd7cddfSDavid du Colombier }else{
2267dd7cddfSDavid du Colombier DBG(2, "unknown message\n");
2277dd7cddfSDavid du Colombier }
2287dd7cddfSDavid du Colombier }
2297dd7cddfSDavid du Colombier }
2307dd7cddfSDavid du Colombier Break2:;
2317dd7cddfSDavid du Colombier }
2327dd7cddfSDavid du Colombier }
2337dd7cddfSDavid du Colombier
2347dd7cddfSDavid du Colombier void
attachremote(char * name)2357dd7cddfSDavid du Colombier attachremote(char* name)
2367dd7cddfSDavid du Colombier {
2377dd7cddfSDavid du Colombier int fd;
2387dd7cddfSDavid du Colombier char buf[128];
2397dd7cddfSDavid du Colombier
2407dd7cddfSDavid du Colombier print("attach %s\n", name);
2417dd7cddfSDavid du Colombier rfd = open(name, ORDWR);
2427dd7cddfSDavid du Colombier if(rfd < 0)
2437dd7cddfSDavid du Colombier sysfatal("can't open remote %s", name);
2447dd7cddfSDavid du Colombier
2457dd7cddfSDavid du Colombier sprint(buf, "%sctl", name);
2467dd7cddfSDavid du Colombier fd = open(buf, OWRITE);
2477dd7cddfSDavid du Colombier if(fd < 0)
2487dd7cddfSDavid du Colombier sysfatal("can't set baud rate on %s", buf);
2497dd7cddfSDavid du Colombier write(fd, "B9600", 6);
2507dd7cddfSDavid du Colombier close(fd);
2517dd7cddfSDavid du Colombier Binit(&rfb, rfd, OREAD);
2527dd7cddfSDavid du Colombier }
2537dd7cddfSDavid du Colombier
2547dd7cddfSDavid du Colombier void
fsopen(Req * r)2559a747e4fSDavid du Colombier fsopen(Req *r)
2567dd7cddfSDavid du Colombier {
2579a747e4fSDavid du Colombier char buf[ERRMAX];
2587dd7cddfSDavid du Colombier
2594de34a7eSDavid du Colombier switch((uintptr)r->fid->file->aux){
2609a747e4fSDavid du Colombier case Xtext:
2617dd7cddfSDavid du Colombier close(textfd);
2627dd7cddfSDavid du Colombier textfd = open(textfile, OREAD);
2637dd7cddfSDavid du Colombier if(textfd < 0) {
2649a747e4fSDavid du Colombier snprint(buf, sizeof buf, "text: %r");
2659a747e4fSDavid du Colombier respond(r, buf);
2667dd7cddfSDavid du Colombier return;
2677dd7cddfSDavid du Colombier }
2687dd7cddfSDavid du Colombier break;
2697dd7cddfSDavid du Colombier }
2709a747e4fSDavid du Colombier respond(r, nil);
2717dd7cddfSDavid du Colombier }
2727dd7cddfSDavid du Colombier
2737dd7cddfSDavid du Colombier void
fsread(Req * r)2749a747e4fSDavid du Colombier fsread(Req *r)
2757dd7cddfSDavid du Colombier {
2767dd7cddfSDavid du Colombier int i, n;
2779a747e4fSDavid du Colombier char buf[512];
2787dd7cddfSDavid du Colombier
2794de34a7eSDavid du Colombier switch((uintptr)r->fid->file->aux) {
2809a747e4fSDavid du Colombier case Xfpregs:
2819a747e4fSDavid du Colombier case Xproc:
2829a747e4fSDavid du Colombier case Xregs:
2839a747e4fSDavid du Colombier respond(r, "Egreg");
2847dd7cddfSDavid du Colombier break;
2859a747e4fSDavid du Colombier case Xkregs:
2869a747e4fSDavid du Colombier case Xmem:
2879a747e4fSDavid du Colombier if(sendp(rchan, r) != 1){
2889a747e4fSDavid du Colombier snprint(buf, sizeof buf, "rdbfs sendp: %r");
2899a747e4fSDavid du Colombier respond(r, buf);
2907dd7cddfSDavid du Colombier return;
2917dd7cddfSDavid du Colombier }
2927dd7cddfSDavid du Colombier break;
2939a747e4fSDavid du Colombier case Xtext:
2949a747e4fSDavid du Colombier n = pread(textfd, r->ofcall.data, r->ifcall.count, r->ifcall.offset);
2957dd7cddfSDavid du Colombier if(n < 0) {
2969a747e4fSDavid du Colombier rerrstr(buf, sizeof buf);
2979a747e4fSDavid du Colombier respond(r, buf);
2987dd7cddfSDavid du Colombier break;
2997dd7cddfSDavid du Colombier }
3009a747e4fSDavid du Colombier r->ofcall.count = n;
3019a747e4fSDavid du Colombier respond(r, nil);
3027dd7cddfSDavid du Colombier break;
3039a747e4fSDavid du Colombier case Xstatus:
3047dd7cddfSDavid du Colombier n = sprint(buf, "%-28s%-28s%-28s", "remote", "system", "New");
3057dd7cddfSDavid du Colombier for(i = 0; i < 9; i++)
3067dd7cddfSDavid du Colombier n += sprint(buf+n, "%-12d", 0);
3079a747e4fSDavid du Colombier readstr(r, buf);
3089a747e4fSDavid du Colombier respond(r, nil);
3097dd7cddfSDavid du Colombier break;
3107dd7cddfSDavid du Colombier default:
3119a747e4fSDavid du Colombier respond(r, "unknown read");
3127dd7cddfSDavid du Colombier }
3137dd7cddfSDavid du Colombier }
3147dd7cddfSDavid du Colombier
3157dd7cddfSDavid du Colombier void
fswrite(Req * r)3169a747e4fSDavid du Colombier fswrite(Req *r)
3177dd7cddfSDavid du Colombier {
3189a747e4fSDavid du Colombier char buf[ERRMAX];
3199a747e4fSDavid du Colombier
3204de34a7eSDavid du Colombier switch((uintptr)r->fid->file->aux) {
3219a747e4fSDavid du Colombier case Xctl:
3229a747e4fSDavid du Colombier if(strncmp(r->ifcall.data, "kill", 4) == 0 ||
3239a747e4fSDavid du Colombier strncmp(r->ifcall.data, "exit", 4) == 0) {
3249a747e4fSDavid du Colombier respond(r, nil);
3259a747e4fSDavid du Colombier postnote(PNGROUP, getpid(), "umount");
3267dd7cddfSDavid du Colombier exits(nil);
3279a747e4fSDavid du Colombier }else if(strncmp(r->ifcall.data, "refresh", 7) == 0){
3287dd7cddfSDavid du Colombier flushcache();
3299a747e4fSDavid du Colombier respond(r, nil);
3309a747e4fSDavid du Colombier }else if(strncmp(r->ifcall.data, "hashstats", 9) == 0){
3317dd7cddfSDavid du Colombier int i;
3327dd7cddfSDavid du Colombier lock(&pglock);
3337dd7cddfSDavid du Colombier for(i=0; i<NHASH; i++)
3347dd7cddfSDavid du Colombier if(pgtab[i])
3357dd7cddfSDavid du Colombier print("%lud ", pgtab[i]->len);
3367dd7cddfSDavid du Colombier print("\n");
3377dd7cddfSDavid du Colombier unlock(&pglock);
3389a747e4fSDavid du Colombier respond(r, nil);
3397dd7cddfSDavid du Colombier }else
3409a747e4fSDavid du Colombier respond(r, "permission denied");
3417dd7cddfSDavid du Colombier break;
3429a747e4fSDavid du Colombier case Xkregs:
3439a747e4fSDavid du Colombier case Xmem:
3449a747e4fSDavid du Colombier if(sendp(rchan, r) != 1) {
3459a747e4fSDavid du Colombier snprint(buf, sizeof buf, "rdbfs sendp: %r");
3469a747e4fSDavid du Colombier respond(r, buf);
3477dd7cddfSDavid du Colombier return;
3487dd7cddfSDavid du Colombier }
3497dd7cddfSDavid du Colombier break;
3507dd7cddfSDavid du Colombier default:
3519a747e4fSDavid du Colombier respond(r, "Egreg");
3527dd7cddfSDavid du Colombier break;
3537dd7cddfSDavid du Colombier }
3547dd7cddfSDavid du Colombier }
3557dd7cddfSDavid du Colombier
3569a747e4fSDavid du Colombier struct {
3579a747e4fSDavid du Colombier char *s;
3589a747e4fSDavid du Colombier int id;
3599a747e4fSDavid du Colombier int mode;
3609a747e4fSDavid du Colombier } tab[] = {
3619a747e4fSDavid du Colombier "ctl", Xctl, 0222,
3629a747e4fSDavid du Colombier "fpregs", Xfpregs, 0666,
3639a747e4fSDavid du Colombier "kregs", Xkregs, 0666,
3649a747e4fSDavid du Colombier "mem", Xmem, 0666,
3659a747e4fSDavid du Colombier "proc", Xproc, 0444,
3669a747e4fSDavid du Colombier "regs", Xregs, 0666,
3679a747e4fSDavid du Colombier "text", Xtext, 0444,
3689a747e4fSDavid du Colombier "status", Xstatus, 0444,
3699a747e4fSDavid du Colombier };
3709a747e4fSDavid du Colombier
3719a747e4fSDavid du Colombier void
killall(Srv *)3729a747e4fSDavid du Colombier killall(Srv*)
3739a747e4fSDavid du Colombier {
3747dd7cddfSDavid du Colombier postnote(PNGROUP, getpid(), "kill");
3757dd7cddfSDavid du Colombier }
3769a747e4fSDavid du Colombier
3779a747e4fSDavid du Colombier Srv fs = {
3789a747e4fSDavid du Colombier .open= fsopen,
3799a747e4fSDavid du Colombier .read= fsread,
3809a747e4fSDavid du Colombier .write= fswrite,
3819a747e4fSDavid du Colombier .end= killall,
3829a747e4fSDavid du Colombier };
3837dd7cddfSDavid du Colombier
3847dd7cddfSDavid du Colombier void
threadmain(int argc,char ** argv)3859a747e4fSDavid du Colombier threadmain(int argc, char **argv)
3867dd7cddfSDavid du Colombier {
3879a747e4fSDavid du Colombier int i, p[2];
3889a747e4fSDavid du Colombier File *dir;
3897dd7cddfSDavid du Colombier
3909a747e4fSDavid du Colombier rfork(RFNOTEG);
3919a747e4fSDavid du Colombier ARGBEGIN{
3929a747e4fSDavid du Colombier case 'D':
3939a747e4fSDavid du Colombier chatty9p++;
3949a747e4fSDavid du Colombier break;
3959a747e4fSDavid du Colombier case 'd':
3969a747e4fSDavid du Colombier dbg = 1;
3979a747e4fSDavid du Colombier break;
3989a747e4fSDavid du Colombier case 'p':
3999a747e4fSDavid du Colombier procname = EARGF(usage());
4009a747e4fSDavid du Colombier break;
401*062a8c88SDavid du Colombier case 's':
402*062a8c88SDavid du Colombier srvname = EARGF(usage());
403*062a8c88SDavid du Colombier break;
4049a747e4fSDavid du Colombier case 't':
4059a747e4fSDavid du Colombier textfile = EARGF(usage());
4069a747e4fSDavid du Colombier break;
4079a747e4fSDavid du Colombier default:
4089a747e4fSDavid du Colombier usage();
4099a747e4fSDavid du Colombier }ARGEND;
4109a747e4fSDavid du Colombier
4119a747e4fSDavid du Colombier switch(argc){
4129a747e4fSDavid du Colombier case 0:
4139a747e4fSDavid du Colombier break;
4149a747e4fSDavid du Colombier case 1:
4159a747e4fSDavid du Colombier portname = argv[0];
4169a747e4fSDavid du Colombier break;
4179a747e4fSDavid du Colombier default:
4189a747e4fSDavid du Colombier usage();
4197dd7cddfSDavid du Colombier }
4207dd7cddfSDavid du Colombier
4219a747e4fSDavid du Colombier rchan = chancreate(sizeof(Req*), 10);
4229a747e4fSDavid du Colombier attachremote(portname);
4239a747e4fSDavid du Colombier if(pipe(p) < 0)
4249a747e4fSDavid du Colombier sysfatal("pipe: %r");
4259a747e4fSDavid du Colombier
4269a747e4fSDavid du Colombier fmtinstall('F', fcallfmt);
4279a747e4fSDavid du Colombier proccreate(eiaread, nil, 8192);
4289a747e4fSDavid du Colombier
4299a747e4fSDavid du Colombier fs.tree = alloctree("rdbfs", "rdbfs", DMDIR|0555, nil);
4309a747e4fSDavid du Colombier dir = createfile(fs.tree->root, procname, "rdbfs", DMDIR|0555, 0);
4319a747e4fSDavid du Colombier for(i=0; i<nelem(tab); i++)
4329a747e4fSDavid du Colombier closefile(createfile(dir, tab[i].s, "rdbfs", tab[i].mode, (void*)tab[i].id));
4339a747e4fSDavid du Colombier closefile(dir);
434*062a8c88SDavid du Colombier threadpostmountsrv(&fs, srvname, "/proc", MBEFORE);
4359a747e4fSDavid du Colombier exits(0);
4367dd7cddfSDavid du Colombier }
4377dd7cddfSDavid du Colombier
438