123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- #include <u.h>
- #include <libc.h>
- #include <auth.h>
- #include <fcall.h>
- #include "iotrack.h"
- #include "dat.h"
- #include "dosfs.h"
- #include "fns.h"
- #include "errstr.h"
- #define Reqsize (sizeof(Fcall)+Maxfdata)
- Fcall *req;
- Fcall *rep;
- uchar mdata[Maxiosize];
- char repdata[Maxfdata];
- uchar statbuf[STATMAX];
- int errno;
- char errbuf[ERRMAX];
- void rmservice(void);
- char srvfile[64];
- char *deffile;
- int doabort;
- int trspaces;
- void (*fcalls[])(void) = {
- [Tversion] rversion,
- [Tflush] rflush,
- [Tauth] rauth,
- [Tattach] rattach,
- [Twalk] rwalk,
- [Topen] ropen,
- [Tcreate] rcreate,
- [Tread] rread,
- [Twrite] rwrite,
- [Tclunk] rclunk,
- [Tremove] rremove,
- [Tstat] rstat,
- [Twstat] rwstat,
- };
- void
- usage(void)
- {
- fprint(2, "usage: %s [-v] [-s] [-f devicefile] [srvname]\n", argv0);
- exits("usage");
- }
- void
- main(int argc, char **argv)
- {
- int stdio, srvfd, pipefd[2];
- rep = malloc(sizeof(Fcall));
- req = malloc(Reqsize);
- if(rep == nil || req == nil)
- panic("out of memory");
- stdio = 0;
- ARGBEGIN{
- case ':':
- trspaces = 1;
- break;
- case 'r':
- readonly = 1;
- break;
- case 'v':
- ++chatty;
- break;
- case 'f':
- deffile = ARGF();
- break;
- case 's':
- stdio = 1;
- break;
- case 'p':
- doabort = 1;
- break;
- default:
- usage();
- }ARGEND
- if(argc == 0)
- strcpy(srvfile, "#s/dos");
- else if(argc == 1)
- snprint(srvfile, sizeof srvfile, "#s/%s", argv[0]);
- else
- usage();
- if(stdio){
- pipefd[0] = 0;
- pipefd[1] = 1;
- }else{
- close(0);
- close(1);
- open("/dev/null", OREAD);
- open("/dev/null", OWRITE);
- if(pipe(pipefd) < 0)
- panic("pipe");
- srvfd = create(srvfile, OWRITE|ORCLOSE, 0600);
- if(srvfd < 0)
- panic(srvfile);
- fprint(srvfd, "%d", pipefd[0]);
- close(pipefd[0]);
- atexit(rmservice);
- fprint(2, "%s: serving %s\n", argv0, srvfile);
- }
- srvfd = pipefd[1];
- switch(rfork(RFNOWAIT|RFNOTEG|RFFDG|RFPROC|RFNAMEG)){
- case -1:
- panic("fork");
- default:
- _exits(0);
- case 0:
- break;
- }
- iotrack_init();
- if(!chatty){
- close(2);
- open("#c/cons", OWRITE);
- }
- io(srvfd);
- exits(0);
- }
- void
- io(int srvfd)
- {
- int n, pid;
- pid = getpid();
- fmtinstall('F', fcallfmt);
- for(;;){
- /*
- * reading from a pipe or a network device
- * will give an error after a few eof reads.
- * however, we cannot tell the difference
- * between a zero-length read and an interrupt
- * on the processes writing to us,
- * so we wait for the error.
- */
- n = read9pmsg(srvfd, mdata, sizeof mdata);
- if(n < 0)
- break;
- if(n == 0)
- continue;
- if(convM2S(mdata, n, req) == 0)
- continue;
- if(chatty)
- fprint(2, "dossrv %d:<-%F\n", pid, req);
- errno = 0;
- if(!fcalls[req->type])
- errno = Ebadfcall;
- else
- (*fcalls[req->type])();
- if(errno){
- rep->type = Rerror;
- rep->ename = xerrstr(errno);
- }else{
- rep->type = req->type + 1;
- rep->fid = req->fid;
- }
- rep->tag = req->tag;
- if(chatty)
- fprint(2, "dossrv %d:->%F\n", pid, rep);
- n = convS2M(rep, mdata, sizeof mdata);
- if(n == 0)
- panic("convS2M error on write");
- if(write(srvfd, mdata, n) != n)
- panic("mount write");
- }
- chat("server shut down");
- }
- void
- rmservice(void)
- {
- remove(srvfile);
- }
- char *
- xerrstr(int e)
- {
- if (e < 0 || e >= sizeof errmsg/sizeof errmsg[0])
- return "no such error";
- if(e == Eerrstr){
- errstr(errbuf, sizeof errbuf);
- return errbuf;
- }
- return errmsg[e];
- }
- int
- eqqid(Qid q1, Qid q2)
- {
- return q1.path == q2.path && q1.type == q2.type && q1.vers == q2.vers;
- }
|