diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/ratfs/main.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/ratfs/main.c')
-rwxr-xr-x | sys/src/cmd/ratfs/main.c | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/sys/src/cmd/ratfs/main.c b/sys/src/cmd/ratfs/main.c new file mode 100755 index 000000000..7c83c892d --- /dev/null +++ b/sys/src/cmd/ratfs/main.c @@ -0,0 +1,318 @@ +#include "ratfs.h" + +#define SRVFILE "/srv/ratify" +#define MOUNTPOINT "/mail/ratify" +#define CTLFILE "/mail/lib/blocked" +#define CONFFILE "/mail/lib/smtpd.conf.ext" + +typedef struct Filetree Filetree; + + /* prototype file tree */ +struct Filetree +{ + int level; + char *name; + ushort type; + int mode; + ulong qid; +}; + + /* names of first-level directories - must be in order of level*/ +Filetree filetree[] = +{ + 0, "/", Directory, 0555|DMDIR, Qroot, + 1, "allow", Addrdir, 0555|DMDIR, Qallow, + 1, "delay", Addrdir, 0555|DMDIR, Qdelay, + 1, "block", Addrdir, 0555|DMDIR, Qblock, + 1, "dial", Addrdir, 0555|DMDIR, Qdial, + 1, "deny", Addrdir, 0555|DMDIR, Qdeny, + 1, "trusted", Trusted, 0777|DMDIR, Qtrusted, /* creation allowed */ + 1, "ctl", Ctlfile, 0222, Qctl, + 2, "ip", IPaddr, 0555|DMDIR, Qaddr, + 2, "account", Acctaddr, 0555|DMDIR, Qaddr, + 0, 0, 0, 0, 0, + +}; + +int debugfd = -1; +int trustedqid = Qtrustedfile; +char *ctlfile = CTLFILE; +char *conffile = CONFFILE; + +#pragma varargck type "I" Cidraddr* + +static int ipconv(Fmt*); +static void post(int, char*); +static void setroot(void); + +void +usage(void) +{ + fprint(2, "ratfs [-d] [-c conffile] [-f ctlfile] [-m mountpoint]\n"); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + char *mountpoint = MOUNTPOINT; + int p[2]; + + ARGBEGIN { + case 'c': + conffile = ARGF(); + break; + case 'd': + debugfd = 2; /* stderr*/ + break; + case 'f': + ctlfile = ARGF(); + break; + case 'm': + mountpoint = ARGF(); + break; + } ARGEND + if(argc != 0) + usage(); + + fmtinstall('I', ipconv); + setroot(); + getconf(); + reload(); + + /* get a pipe and mount it in /srv */ + if(pipe(p) < 0) + fatal("pipe failed: %r"); + srvfd = p[0]; + post(p[1], mountpoint); + + /* start the 9fs protocol */ + switch(rfork(RFPROC|RFNAMEG|RFENVG|RFFDG|RFNOTEG|RFREND)){ + case -1: + fatal("fork: %r"); + case 0: + /* seal off standard input/output */ + close(0); + open("/dev/null", OREAD); + close(1); + open("/dev/null", OWRITE); + + close(p[1]); + fmtinstall('F', fcallfmt); /* debugging */ + io(); + fprint(2, "ratfs dying\n"); + break; + default: + close(p[0]); + if(mount(p[1], -1, mountpoint, MREPL|MCREATE, "") < 0) + fatal("mount failed: %r"); + } + exits(0); +} + +static void +setroot(void) +{ + Filetree *fp; + Node *np; + int qid; + + root = 0; + qid = Qaddr; + for(fp = filetree; fp->name; fp++) { + switch(fp->level) { + case 0: /* root */ + case 1: /* second level directory */ + newnode(root, fp->name, fp->type, fp->mode, fp->qid); + break; + case 2: /* lay down the Ipaddr and Acctaddr subdirectories */ + for (np = root->children; np; np = np->sibs){ + if(np->d.type == Addrdir) + newnode(np, fp->name, fp->type, fp->mode, qid++); + } + break; + default: + fatal("bad filetree"); + } + } + dummy.d.type = Dummynode; + dummy.d.mode = 0444; + dummy.d.uid = "upas"; + dummy.d.gid = "upas"; + dummy.d.atime = dummy.d.mtime = time(0); + dummy.d.qid.path = Qdummy; /* for now */ +} + +static void +post(int fd, char *mountpoint) +{ + + int f; + char buf[128]; + + if(access(SRVFILE,0) >= 0){ + /* + * If we can open and mount the /srv node, + * another server is already running, so just exit. + */ + f = open(SRVFILE, ORDWR); + if(f >= 0 && mount(f, -1, mountpoint, MREPL|MCREATE, "") >= 0){ + unmount(0, mountpoint); + close(f); + exits(0); + } + remove(SRVFILE); + } + + /* + * create the server node and post our pipe to it + */ + f = create(SRVFILE, OWRITE, 0666); + if(f < 0) + fatal("can't create %s", SRVFILE); + + sprint(buf, "%d", fd); + if(write(f, buf, strlen(buf)) != strlen(buf)) + fatal("can't write %s", SRVFILE); + + close(f); +} + +/* + * print message and die + */ +void +fatal(char *fmt, ...) +{ + va_list arg; + char buf[8*1024]; + + va_start(arg, fmt); + vseprint(buf, buf + (sizeof(buf)-1) / sizeof(*buf), fmt, arg); + va_end(arg); + + fprint(2, "%s: %s\n", argv0, buf); + exits(buf); +} + +/* + * create a new directory node + */ +Node* +newnode(Node *parent, char *name, ushort type, int mode, ulong qid) +{ + Node *np; + + np = mallocz(sizeof(Node), 1); + if(np == 0) + fatal("out of memory"); + np->d.name = atom(name); + np->d.type = type; + np->d.mode = mode; + np->d.mtime = np->d.atime = time(0); + np->d.uid = atom("upas"); + np->d.gid = atom("upas"); + np->d.muid = atom("upas"); + if(np->d.mode&DMDIR) + np->d.qid.type = QTDIR; + np->d.qid.path = qid; + np->d.qid.vers = 0; + if(parent){ + np->parent = parent; + np->sibs = parent->children; + parent->children = np; + parent->count++; + } else { + /* the root node */ + root = np; + np->parent = np; + np->children = 0; + np->sibs = 0; + } + return np; +} + +void +printnode(Node *np) +{ + fprint(debugfd, "Node at %p: %s (%s %s)", np, np->d.name, np->d.uid, np->d.gid); + if(np->d.qid.type&QTDIR) + fprint(debugfd, " QTDIR"); + fprint(debugfd, "\n"); + fprint(debugfd,"\tQID: %llud.%lud Mode: %lo Type: %d\n", np->d.qid.path, + np->d.qid.vers, np->d.mode, np->d.type); + fprint(debugfd, "\tMod: %.15s Acc: %.15s Count: %d\n", ctime(np->d.mtime)+4, + ctime(np->d.atime)+4, np->count); + switch(np->d.type) + { + case Directory: + fprint(debugfd, "\tDirectory Child: %p", np->children); + break; + case Addrdir: + fprint(debugfd, "\tAddrdir Child: %p", np->children); + break; + case IPaddr: + fprint(debugfd, "\tIPaddr Base: %p Alloc: %d BaseQid %lud", np->addrs, + np->allocated, np->baseqid); + break; + case Acctaddr: + fprint(debugfd, "\tAcctaddr Base: %p Alloc: %d BaseQid %lud", np->addrs, + np->allocated, np->baseqid); + break; + case Trusted: + fprint(debugfd, "\tTrusted Child: %p", np->children); + break; + case Trustedperm: + fprint(debugfd, "\tPerm Trustedfile: %I", &np->ip); + break; + case Trustedtemp: + fprint(debugfd, "\tTemp Trustedfile: %I", &np->ip); + break; + case Ctlfile: + fprint(debugfd, "\tCtlfile"); + break; + case Dummynode: + fprint(debugfd, "\tDummynode"); + break; + default: + fprint(debugfd, "\tUnknown Node Type\n\n"); + return; + } + fprint(debugfd, " Parent %p Sib: %p\n\n", np->parent, np->sibs); +} + +void +printfid(Fid *fp) +{ + fprint(debugfd, "FID: %d (%s %s) Busy: %d Open: %d\n", fp->fid, fp->name, + fp->uid, fp->busy, fp->open); + printnode(fp->node); +} + +void +printtree(Node *np) +{ + printnode(np); + if(np->d.type == IPaddr + || np->d.type == Acctaddr + || np->d.type == Trustedperm + || np->d.type == Trustedtemp) + return; + for (np = np->children; np; np = np->sibs) + printtree(np); +} + +static int +ipconv(Fmt *f) +{ + Cidraddr *ip; + int i, j; + char *p; + + ip = va_arg(f->args, Cidraddr*); + p = (char*)&ip->ipaddr; + i = 0; + for (j = ip->mask; j; j <<= 1) + i++; + return fmtprint(f, "%d.%d.%d.%d/%d", p[3]&0xff, p[2]&0xff, p[1]&0xff, p[0]&0xff, i); +} |