1implement Collabsrv; 2 3include "sys.m"; 4 sys: Sys; 5 6include "draw.m"; 7 8include "keyring.m"; 9include "security.m"; 10 auth: Auth; 11 12include "srvmgr.m"; 13include "proxy.m"; 14 15include "arg.m"; 16 17Collabsrv: module 18{ 19 init: fn (ctxt: ref Draw->Context, args: list of string); 20}; 21 22authinfo: ref Keyring->Authinfo; 23 24stderr: ref Sys->FD; 25Srvreq, Srvreply: import Srvmgr; 26 27usage() 28{ 29 sys->fprint(stderr, "usage: collabsrv [-k keyfile] [-n netaddress] [dir]\n"); 30 raise "fail:usage"; 31} 32 33init(nil: ref Draw->Context, args: list of string) 34{ 35 sys = load Sys Sys->PATH; 36 sys->pctl(Sys->NEWPGRP, nil); 37 stderr = sys->fildes(2); 38 39 (err, user) := user(); 40 if (err != nil) 41 error(err); 42 43 netaddr := "tcp!*!9999"; 44 keyfile := "/usr/" + user + "/keyring/default"; 45 root := "/services/collab"; 46 47 arg := load Arg Arg->PATH; 48 arg->init(args); 49 while ((opt := arg->opt()) != 0) 50 case opt { 51 'k' => 52 keyfile = arg->arg(); 53 if (keyfile == nil) 54 usage(); 55 if (keyfile[0] != '/' && (len keyfile < 2 || keyfile[0:2] != "./")) 56 keyfile = "/usr/" + user + "/keyring/" + keyfile; 57 'n' => 58 netaddr = arg->arg(); 59 if (netaddr == nil) 60 usage(); 61 * => 62 usage(); 63 } 64 args = arg->argv(); 65 arg = nil; 66 if(args != nil) 67 root = hd args; 68 69 auth = load Auth Auth->PATH; 70 if (auth == nil) 71 badmodule(Auth->PATH); 72 73 kr := load Keyring Keyring->PATH; 74 if (kr == nil) 75 badmodule(Keyring->PATH); 76 77 srvmgr := load Srvmgr Srvmgr->PATH; 78 if (srvmgr == nil) 79 badmodule(Srvmgr->PATH); 80 81 err = auth->init(); 82 if (err != nil) 83 error(sys->sprint("failed to init Auth: %s", err)); 84 85 authinfo = kr->readauthinfo(keyfile); 86 kr = nil; 87 if (authinfo == nil) 88 error(sys->sprint("cannot read %s: %r", keyfile)); 89 90 netaddr = netmkaddr(netaddr, "tcp", "9999"); 91 (ok, c) := sys->announce(netaddr); 92 if (ok < 0) 93 error(sys->sprint("cannot announce %s: %r", netaddr)); 94 95 rc: chan of ref Srvreq; 96 (err, rc) = srvmgr->init(root); 97 if (err != nil) 98 error(err); 99 100 sys->print("Srvmgr started\n"); 101 102 for (;;) { 103 (okl, nc) := sys->listen(c); 104 if (okl < 0) { 105 sys->print("listen failed: %r\n"); 106 sys->sleep(1000); 107 return; 108 } 109 fd := sys->open(nc.dir+"/data", Sys->ORDWR); 110 if(nc.cfd != nil) 111 sys->fprint(nc.cfd, "keepalive"); 112 nc.cfd = nil; 113 if (fd != nil) 114 spawn newclient(rc, fd, root); 115 fd = nil; 116 } 117} 118 119badmodule(path: string) 120{ 121 error(sys->sprint("cannot load module %s: %r", path)); 122} 123 124error(s: string) 125{ 126 sys->fprint(stderr, "collabsrv: %s\n", s); 127 raise "fail:error"; 128} 129 130user(): (string, string) 131{ 132 sys = load Sys Sys->PATH; 133 fd := sys->open("/dev/user", sys->OREAD); 134 if(fd == nil) 135 return (sys->sprint("can't open /dev/user: %r"), nil); 136 buf := array[128] of byte; 137 n := sys->read(fd, buf, len buf); 138 if(n <= 0) 139 return (sys->sprint("failed to read /dev/user: %r"), nil); 140 return (nil, string buf[0:n]); 141} 142 143newclient(rc: chan of ref Srvreq, fd: ref Sys->FD, root: string) 144{ 145 algs := "none" :: "clear" :: "md4" :: "md5" :: nil; 146 sys->print("new client\n"); 147 proxy := load Proxy Proxy->PATH; 148 if (proxy == nil) { 149 sys->fprint(stderr, "collabsrv: cannot load %s: %r\n", Proxy->PATH); 150 return; 151 } 152 sys->pctl(Sys->NEWPGRP|Sys->FORKNS|Sys->FORKENV, nil); 153 s := ""; 154 (fd, s) = auth->server(algs, authinfo, fd, 1); 155 if (fd == nil){ 156 sys->fprint(stderr, "collabsrv: cannot authenticate: %s\n", s); 157 return; 158 } 159 sys->fprint(stderr, "uname: %s\n", s); 160 spawn proxy->init(root, fd, rc, s); 161} 162 163netmkaddr(addr, net, svc: string): string 164{ 165 if(net == nil) 166 net = "net"; 167 (n, l) := sys->tokenize(addr, "!"); 168 if(n <= 1){ 169 if(svc== nil) 170 return sys->sprint("%s!%s", net, addr); 171 return sys->sprint("%s!%s!%s", net, addr, svc); 172 } 173 if(svc == nil || n > 2) 174 return addr; 175 return sys->sprint("%s!%s", addr, svc); 176} 177