Exemplo n.º 1
0
ssize_t read(int socket, void *buf, size_t count)
{
	int fd;
	init_preload();
	return (fd_fork_get(socket, &fd) == fd_rsocket) ?
		rread(fd, buf, count) : real.read(fd, buf, count);
}
Exemplo n.º 2
0
static void
rnfs3(void *v)
{
	SunMsg *m;

	m = v;
	switch(m->call->type){
	default:
		abort();
	case Nfs3CallTNull:
		rnull0(m);
		break;
	case Nfs3CallTGetattr:
		rgetattr(m);
		break;
	case Nfs3CallTLookup:
		rlookup(m);
		break;
	case Nfs3CallTAccess:
		raccess(m);
		break;
	case Nfs3CallTReadlink:
		rreadlink(m);
		break;
	case Nfs3CallTRead:
		rread(m);
		break;
	case Nfs3CallTReadDir:
		rreaddir(m);
		break;
	case Nfs3CallTReadDirPlus:
		rreaddirplus(m);
		break;
	case Nfs3CallTFsStat:
		rfsstat(m);
		break;
	case Nfs3CallTFsInfo:
		rfsinfo(m);
		break;
	case Nfs3CallTPathconf:
		rpathconf(m);
		break;
	case Nfs3CallTSetattr:
	case Nfs3CallTWrite:
	case Nfs3CallTCreate:
	case Nfs3CallTMkdir:
	case Nfs3CallTSymlink:
	case Nfs3CallTMknod:
	case Nfs3CallTRemove:
	case Nfs3CallTRmdir:
	case Nfs3CallTLink:
	case Nfs3CallTCommit:
		rrofs(m);
		break;
	}
}
Exemplo n.º 3
0
Arquivo: lzf.c Projeto: malaise/c
static int
compress_fd (int from, int to)
{
  ssize_t us, cs, len;
  u8 buf1[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16];
  u8 buf2[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16];
  u8 *header;

  nr_read = nr_written = 0;
  while ((us = rread (from, &buf1[MAX_HDR_SIZE], blocksize)) > 0)
    {
      cs = lzf_compress (&buf1[MAX_HDR_SIZE], us, &buf2[MAX_HDR_SIZE], us > 4 ? us - 4 : us);
      if (cs)
        {
          header = &buf2[MAX_HDR_SIZE - TYPE1_HDR_SIZE];
          header[0] = 'Z';
          header[1] = 'V';
          header[2] = 1;
          header[3] = cs >> 8;
          header[4] = cs & 0xff;
          header[5] = us >> 8;
          header[6] = us & 0xff;
          len = cs + TYPE1_HDR_SIZE;
        }
      else
        {                       // write uncompressed
          header = &buf1[MAX_HDR_SIZE - TYPE0_HDR_SIZE];
          header[0] = 'Z';
          header[1] = 'V';
          header[2] = 0;
          header[3] = us >> 8;
          header[4] = us & 0xff;
          len = us + TYPE0_HDR_SIZE;
        }
      if (raw)
        {
          header = &buf2[MAX_HDR_SIZE]; 
          len = cs;
        }
      if (wwrite (to, header, len) == -1)
        return -1;
    }
/*
void
testbitmask(void) {

    setmaskbit(31); setmaskbit(95); setmaskbit(159);setmaskbit(223);
    setmaskbit(287); setmaskbit(351); setmaskbit(415);setmaskbit(479);
    setmaskbit(90); setmaskbit(154);setmaskbit(218); setmaskbit(282);
    setmaskbit(346); setmaskbit(347); setmaskbit(348); setmaskbit(349);
    setmaskbit(350); setmaskbit(100); setmaskbit(164);setmaskbit(228);
    setmaskbit(292); setmaskbit(356); setmaskbit(355); setmaskbit(354);
    setmaskbit(353); setmaskbit(352);
    
    printfreemask();

    clearmaskbit(31); clearmaskbit(95); clearmaskbit(159);clearmaskbit(223);
    clearmaskbit(287); clearmaskbit(351); clearmaskbit(415);clearmaskbit(479);
    clearmaskbit(90); clearmaskbit(154);clearmaskbit(218); clearmaskbit(282);
    clearmaskbit(346); clearmaskbit(347); clearmaskbit(348); clearmaskbit(349);
    clearmaskbit(350); clearmaskbit(100); clearmaskbit(164);clearmaskbit(228);
    clearmaskbit(292); clearmaskbit(356); clearmaskbit(355); clearmaskbit(354);
    clearmaskbit(353); clearmaskbit(352);

    printfreemask();

}

*/
void test_fs(void){

int fd1, fd2; //File descriptors
fd1 = fcreat("Test File", 0); //Creating a new file
printf("Helo %d\n", fd1);
//fd2 = fcreat("Sample", 0); //Creating a new file

fd1 = fopen("Test File", 1);//Opening a file in write-only mode
printf("file opened in write only mode..%d\n",fd1);
wwrite(fd1);
fclose(fd1);
//fwrite(fd1, )
fd1 = fopen("Test File", 0); //Opening the same file in Read only mode
rread(fd1);
//fclose(fd1);

//fd2 = fopen("Sample", 1); //Opening a file in write only mode
//fwrite(fd2, )
//fseek(fd2, 2);
//fd2 = fopen("Sample", 0); //Opening a file in read only mode
//rread(fd2);
//fclose(fd2);

}
Exemplo n.º 5
0
static void
service(int cfd, int sfd, int dfd)
{
	Fcall	f;
	int	r;
	Fid*	fp;

	fidpool = allocfidpool(nop);
	for(;;){
		fp = nil;
		r = getfcall(cfd, &f);
		if (r <= 0){
			fprint(dfd, "trfs: getfcall %r\n");
			break;
		}
		if(verbose)
			fprint(dfd , "c→s %F\n", &f);
		switch(f.type){
		case Tclunk:
		case Tremove:
			// BUG in lib9p? removefid leaks fid.
			// is that what it should do?
			fp = lookupfid(fidpool, f.fid);
			if (fp != nil){
				removefid(fidpool, f.fid);
				closefid(fp);
				closefid(fp);
				fp = nil;
			}
			break;
		case Tcreate:
			tcreate(&f);
			// and also...
		case Topen:
			fp = allocfid(fidpool, f.fid);
			fp->aux = 0;
			break;
		case Tread:
			tread(&f);
			break;
		case Twalk:
			twalk(&f);
			break;
		case Twstat:
			twstat(&f);
			break;
		}
		if(verbose && debug)
			fprint(dfd , "c→s %F\n", &f);
		if (putfcall(sfd, &f) < 0)
			fprint(dfd , "can't putfcall: %r\n");
		

		r = getfcall(sfd, &f);
		if (r <= 0){
			fprint(dfd, "trfs: 2nd getfcall %r\n");
			break;
		}
		if (verbose)
			fprint(dfd, "c←s %F\n", &f);
		switch(f.type){
		case Ropen:
		case Rcreate:
			fp->qid = f.qid;
			break;
		case Rread:
			rread(&f);
			break;
		case Rstat:
			rstat(&f);
			break;
		}
		if(verbose && debug)
			fprint(dfd , "c←s %F\n", &f);
		if (putfcall(cfd, &f) < 0)
			fprint(dfd , "can't 2n dputfcall: %r\n");
		if (fp != nil)
			closefid(fp);
	}
}
Exemplo n.º 6
0
void
rfServ_(int acceptSock)
{
    static char          fname[] = "rfServ_()";
    struct LSFHeader     msgHdr;
    struct LSFHeader     buf;
    struct sockaddr_in   from;
    socklen_t            fromLen = sizeof(from);
    int                  sock;
    XDR                  xdrs;

    sock = accept(acceptSock, (struct sockaddr *)&from, &fromLen);
    if (sock < 0) {
        ls_errlog(stderr, I18N_FUNC_FAIL_MM, fname, "readDecodeHdr_");
        closesocket(acceptSock);
        return;
    }

    xdrmem_create(&xdrs, (char *) &buf, sizeof(buf), XDR_DECODE);

    for (;;) {

        XDR_SETPOS(&xdrs, 0);
        if (readDecodeHdr_(sock,
                           (char *)&buf,
                           SOCK_READ_FIX,
                           &xdrs,
                           &msgHdr) < 0) {
            ls_errlog(stderr, I18N_FUNC_FAIL_MM, fname, "readDecodeHdr_");
            closesocket(sock);
            xdr_destroy(&xdrs);
            return;
        }

        switch (msgHdr.opCode) {
            case RF_OPEN:
                ropen(sock, &msgHdr);
                break;

            case RF_CLOSE:
                rclose(sock, &msgHdr);
                break;

            case RF_WRITE:
                rwrite(sock, &msgHdr);
                break;

            case RF_READ:
                rread(sock, &msgHdr);
                break;

            case RF_STAT:
                rstat(sock, &msgHdr);
                break;

            case RF_GETMNTHOST:
                rgetmnthost(sock, &msgHdr);
                break;

            case RF_FSTAT:
                rfstat(sock, &msgHdr);
                break;

            case RF_LSEEK:
                rlseek(sock, &msgHdr);
                break;

            case RF_UNLINK:
                runlink(sock, &msgHdr);
                break;

            case RF_TERMINATE:
                closesocket(sock);
                return;

            default:
                ls_errlog(stderr, _i18n_msg_get(ls_catd, NL_SETN, 602,
                                                "%s: Unknown opcode %d"),
                          fname, msgHdr.opCode);
                xdr_destroy(&xdrs);
                break;
        }
    }

}
Exemplo n.º 7
0
Arquivo: srv.c Projeto: 99years/plan9
void
respond(Req *r, char *error)
{
	int i, m, n;
	char errbuf[ERRMAX];
	Srv *srv;

	srv = r->srv;
	assert(srv != nil);

	if(r->responded){
		assert(r->pool);
		goto free;
	}
		
	assert(r->responded == 0);
	r->error = error;

	switch(r->ifcall.type){
	default:
		assert(0);
	/*
	 * Flush is special.  If the handler says so, we return
	 * without further processing.  Respond will be called
	 * again once it is safe.
	 */
	case Tflush:
		if(rflush(r, error)<0)
			return;
		break;
	case Tversion:	rversion(r, error);	break;
	case Tauth:	rauth(r, error);	break;
	case Tattach:	rattach(r, error);	break;
	case Twalk:	rwalk(r, error);	break;
	case Topen:	ropen(r, error);	break;
	case Tcreate:	rcreate(r, error);	break;
	case Tread:	rread(r, error);	break;
	case Twrite:	rwrite(r, error);	break;
	case Tclunk:	rclunk(r, error);	break;
	case Tremove:	rremove(r, error, errbuf);	break;
	case Tstat:	rstat(r, error);	break;
	case Twstat:	rwstat(r, error);	break;
	}

	r->ofcall.tag = r->ifcall.tag;
	r->ofcall.type = r->ifcall.type+1;
	if(r->error)
		setfcallerror(&r->ofcall, r->error);

if(chatty9p)
	fprint(2, "-%d-> %F\n", srv->outfd, &r->ofcall);

	qlock(&srv->wlock);
	n = convS2M(&r->ofcall, srv->wbuf, srv->msize);
	if(n <= 0){
		fprint(2, "n = %d %F\n", n, &r->ofcall);
		abort();
	}
	assert(n > 2);
	/*
	 * There is a race here - we must remove the entry before
	 * the write, so that if the client is very fast and reuses the
	 * tag, the read loop won't think it is still in use.
	 * 
	 * By removing the entry before the write, we open up a 
	 * race with incoming Tflush messages.  Specifically, an
	 * incoming Tflush might not see r even though it has not
	 * yet been responded to.  It would then send an Rflush
	 * immediately, potentially before we do the write.  This can't
	 * happen because we already old srv->wlock, so nothing
	 * is going out on the wire before this write.
	 */
	if(r->pool)	/* not a fake */
		closereq(removereq(r->pool, r->ifcall.tag));

	qlock(&r->lk);
	r->responded = 1;
	if(r->pool)
	if(r->ref.ref == 1+r->nflush)
	if(r->fid){
		/*
		 * There are no references other than in our r->flush array,
		 * so no one else should be accessing r concurrently.
		 * Close the fid now, before responding to the message.
		 * 
		 * If the client is behaving (there are no outstanding T-messages
		 * that reference r->fid) and the message is a Tclunk or Tremove,
		 * then this closefid will call destroyfid.  
		 * 
		 * This means destroyfid can't piddle around 
		 * indefinitely (we're holding srv->wlock!), but it provides
		 * for tighter semantics as to when destroyfid is called.
		 *
		 * LANL has observed cases where waiting until after the write
		 * can delay a closefid on a Twrite for many 9P transactions,
		 * so that a handful of transactions can happen including a Tclunk
		 * and a Topen, and the original fid will still not be destroyed.
		 */
		closefid(r->fid);
		r->fid = nil;
	}
	qunlock(&r->lk);
	m = write(srv->outfd, srv->wbuf, n);
	if(m != n)
		sysfatal("lib9p srv: write %d returned %d on fd %d: %r", n, m, srv->outfd);
	qunlock(&srv->wlock);

free:
	qlock(&r->lk);	/* no one will add flushes now */

	for(i=0; i<r->nflush; i++){
		r->flush[i]->oldreq = nil;	/* so it doesn't try to lock us! */
		respond(r->flush[i], nil);
	}
	free(r->flush);
	r->flush = nil;
	r->nflush = 0;
	qunlock(&r->lk);

	if(r->pool)
		closereq(r);
	else
		free(r);
}
Exemplo n.º 8
0
Arquivo: srv.c Projeto: npe9/harvey
void
respond(Req *r, char *error)
{
	int i, m, n;
	char errbuf[ERRMAX];
	Srv *srv;

	srv = r->srv;
	assert(srv != nil);

	assert(r->responded == 0);
	r->error = error;

	switch(r->ifcall.type){
	default:
		assert(0);
	/*
	 * Flush is special.  If the handler says so, we return
	 * without further processing.  Respond will be called
	 * again once it is safe.
	 */
	case Tflush:
		if(rflush(r, error)<0)
			return;
		break;
	case Tversion:	rversion(r, error);	break;
	case Tauth:	rauth(r, error);	break;
	case Tattach:	rattach(r, error);	break;
	case Twalk:	rwalk(r, error);	break;
	case Topen:	ropen(r, error);	break;
	case Tcreate:	rcreate(r, error);	break;
	case Tread:	rread(r, error);	break;
	case Twrite:	rwrite(r, error);	break;
	case Tclunk:	rclunk(r, error);	break;
	case Tremove:	rremove(r, error, errbuf);	break;
	case Tstat:	rstat(r, error);	break;
	case Twstat:	rwstat(r, error);	break;
	}

	r->ofcall.tag = r->ifcall.tag;
	r->ofcall.type = r->ifcall.type+1;
	if(r->error)
		setfcallerror(&r->ofcall, r->error);

if(chatty9p)
	fprint(2, "-%d-> %F\n", srv->outfd, &r->ofcall);

	qlock(&srv->wlock);
	n = convS2M(&r->ofcall, srv->wbuf, srv->msize);
	if(n <= 0){
		fprint(2, "n = %d %F\n", n, &r->ofcall);
		abort();
	}
	assert(n > 2);
	if(r->pool)	/* not a fake */
		closereq(removereq(r->pool, r->ifcall.tag));
	m = write(srv->outfd, srv->wbuf, n);
	if(m != n)
		sysfatal("lib9p srv: write %d returned %d on fd %d: %r", n, m, srv->outfd);
	qunlock(&srv->wlock);

	qlock(&r->lk);	/* no one will add flushes now */
	r->responded = 1;
	qunlock(&r->lk);

	for(i=0; i<r->nflush; i++)
		respond(r->flush[i], nil);
	free(r->flush);
	r->flush = nil;
	r->nflush = 0;

	if(r->pool)
		closereq(r);
	else
		free(r);
}
Exemplo n.º 9
0
Arquivo: cs.c Projeto: brho/akaros
static void *job_thread(void *arg)
{
	struct mfile *mf;
	struct job *job = arg;

	spinlock_lock(&dblock);
	mf = newfid(job->request.fid);

	if (debug)
		fprintf(stderr, "CS:%F", &job->request);
	switch (job->request.type) {
	default:
		fprintf(stderr, "CS:unknown request type %d", job->request.type);
		break;
	case Tversion:
		rversion(job);
		break;
	case Tauth:
		rauth(job);
		break;
	case Tflush:
		rflush(job);
		break;
	case Tattach:
		rattach(job, mf);
		break;
	case Twalk:
		rwalk(job, mf);
		break;
	case Topen:
		ropen(job, mf);
		break;
	case Tcreate:
		rcreate(job, mf);
		break;
	case Tread:
		rread(job, mf);
		break;
	case Twrite:
		rwrite(job, mf);
		break;
	case Tclunk:
		rclunk(job, mf);
		break;
	case Tremove:
		rremove(job, mf);
		break;
	case Tstat:
		rstat(job, mf);
		break;
	case Twstat:
		rwstat(job, mf);
		break;
	}
	spinlock_unlock(&dblock);

	freejob(job);

	if (debug)
		fprintf(stderr, "CS:Job done\n");
	return 0;
}
Exemplo n.º 10
0
void
io(void)
{
	volatile long n;
	volatile uchar mdata[IOHDRSZ + Maxfdata];
	Job *volatile job;
	Mfile *volatile mf;
	volatile Request req;

	memset(&req, 0, sizeof req);
	/*
	 *  a slave process is sometimes forked to wait for replies from other
	 *  servers.  The master process returns immediately via a longjmp
	 *  through 'mret'.
	 */
	if(setjmp(req.mret))
		putactivity(0);
	req.isslave = 0;
	stop = 0;
	while(!stop){
		procsetname("%d %s/dns Twrites of %d 9p rpcs read; %d alarms",
			stats.qrecvd9p, mntpt, stats.qrecvd9prpc, stats.alarms);
		n = read9pmsg(mfd[0], mdata, sizeof mdata);
		if(n<=0){
			dnslog("error reading 9P from %s: %r", mntpt);
			sleep(2000);	/* don't thrash after read error */
			return;
		}

		stats.qrecvd9prpc++;
		job = newjob();
		if(convM2S(mdata, n, &job->request) != n){
			freejob(job);
			continue;
		}
		mf = newfid(job->request.fid, 0);
		if(debug)
			dnslog("%F", &job->request);

		getactivity(&req, 0);
		req.aborttime = timems() + Maxreqtm;
		req.from = "9p";

		switch(job->request.type){
		default:
			warning("unknown request type %d", job->request.type);
			break;
		case Tversion:
			rversion(job);
			break;
		case Tauth:
			rauth(job);
			break;
		case Tflush:
			rflush(job);
			break;
		case Tattach:
			rattach(job, mf);
			break;
		case Twalk:
			rwalk(job, mf);
			break;
		case Topen:
			ropen(job, mf);
			break;
		case Tcreate:
			rcreate(job, mf);
			break;
		case Tread:
			rread(job, mf);
			break;
		case Twrite:
			/* &req is handed to dnresolve() */
			rwrite(job, mf, &req);
			break;
		case Tclunk:
			rclunk(job, mf);
			break;
		case Tremove:
			rremove(job, mf);
			break;
		case Tstat:
			rstat(job, mf);
			break;
		case Twstat:
			rwstat(job, mf);
			break;
		}

		freejob(job);

		/*
		 *  slave processes die after replying
		 */
		if(req.isslave){
			putactivity(0);
			_exits(0);
		}

		putactivity(0);
	}
	/* kill any udp server, notifier, etc. processes */
	postnote(PNGROUP, getpid(), "die");
	sleep(1000);
}
Exemplo n.º 11
0
Arquivo: main.c Projeto: dbrooke/wsrdr
//! List a range of SAVED records.
//! Checks that the time specified is not later than device time
//
void listRecordsSince(const char* since) {
    struct weatherRecord record;
    char datestr[17];

    // convert date/time given to time_t
    time_t since_t = cvtStr2Time_t(since);

    // get current date and time - getDateTime() found in header.h
    char* devtimestr = (char*) getDateTime();

    //printf("DEBUG: device date = %s\n", devtimestr);
    
    time_t devtime = cvtStr2Time_t(devtimestr);

    // check for since date in the future
    if (since_t > devtime) {
        printf("Date %s is in the future, date now is %s\n", since, getDateTime());
        exit(1);
    }

    // maximum number of records, getRecordsStored() in header.h
    int guard = getRecordsStored();

    //printf("DEBUG: (main.c) there are %d records stored\n", guard);

    int headings = (options.verbose == 1) ? 1 : 0;

    // Record 0 is the current reading, it is continually overwritten until the
    // polling period is reached, at which time a new current record is started
    // with a 0 second delay.
    int recordidx = 0;

    // skip the 0 record as it is the current value and should be read using
    // -r 0
    // (rread() found in wrecord.h)
    weatherRecordPtr p = rread(&record, recordidx++);

    // calculate time of the first saved record
    time_t tmptime = devtime - (record.interval * 60);

    // starting with the first saved record (recordidx == 1)
    // while the record time is greater than the time since (and there are records!)
    // output the result
    while((tmptime > since_t) && (recordidx < guard)) {
        // read the record
        p = rread(&record, recordidx++);
        // calculate its date/time
        tmptime -= (record.interval * 60);
        // if it is later than since then print it
        if (tmptime > since_t) {
            cvtTime2Str(datestr, 17, &tmptime);
            // tell getDateTime() to use our date/time (usedate is external, see header.h)
            usedate = datestr;
            if (options.verbose == 0) {
                rprints(&record, recordPrintSpecification, fieldseparator);
            }
            else {
                rprintv(&record, recordPrintSpecification, fieldseparator, headings);
            }
            // reset getDateTime() to use device time
            usedate = NULL;
            // no more headings for this list
            headings = 0;
        }
    }
}
Exemplo n.º 12
0
Arquivo: main.c Projeto: dbrooke/wsrdr
//! List a range of records.
//! Checks that the end is not greater than the number of records stored
//
void listRecords(int start, int end) {
    struct weatherRecord record;

    //printf("DEBUG: -r %d:%d\n", start, end);

    if (end < start) {
        end = start;
    }

    int numrecs = getRecordsStored();

    //printf("DEBUG: (main.c) there are %d records stored\n", numrecs);

    if (end >= numrecs) {
        printf("invalid end record number %d\n", end);
        return;
    }

    // set up for storing the time of readings
    // convert date/time given to time_t

    // get current date and time using getDateTime() (see header.h)
    char* devtimestr = (char*) getDateTime();
    //printf("DEBUG: device date = %s\n", devtimestr);
    time_t devtime = cvtStr2Time_t(devtimestr);

    // prepare, get a record pointer and a record counter and temp time
    weatherRecordPtr p = NULL;
    int recordidx = 0;
    time_t tmptime = devtime;

    if (daterequired()) {
    // read up to the starting record, adjusting time
        while(recordidx < start) {
            // calculate time of the first stored record using rread() (see wrecord.h)
            p = rread(&record, recordidx++);
            tmptime -= (record.interval * 60);
        }
    }
    else {
        recordidx = start;
    }

    // now recordidx is pointing at the first record to be listed
    // and tmptime is holding the time of that record

    // get date string storage
    char datestr[17];

    // see if headings are to be printed, for options see cmdline.h
    int headings = (options.verbose == 1) ? 1 : 0;

    // loop through the records to be listed
    while(recordidx <= end) {
        // read the record (see wrecord.h)
        p = rread(&record, recordidx++);
        // convert the date to a string
        cvtTime2Str(datestr, 17, &tmptime);
        // tell getDateTime() to use our date/time (usedate is external, see header.h)
        usedate = datestr;

        // print the record using functions specified in wrecord.h
        if (options.verbose == 0) {
            rprints(&record, recordPrintSpecification, fieldseparator);
        }
        else {
            rprintv(&record, recordPrintSpecification, fieldseparator, headings);
        }

        // calculate date/time of next saved record
        tmptime -= (record.interval * 60);

        // reset getDateTime() to use device time
        usedate = NULL;
        // no more headings for this list
        headings = 0;
    }

    /*
    int headings = (options.verbose == 1) ? 1 : 0;
    for(int i = end; i >= 0 && i >= start; i--) {
        rread(&record, i);
        if (options.verbose == 0) {
            rprints(&record, recordPrintSpecification, fieldseparator);
        }
        else {
            rprintv(&record, recordPrintSpecification, fieldseparator, headings);
        }
        headings = 0;
    }
    */
}
Exemplo n.º 13
0
void
ioproc0(void *v)
{
	long n;
	Mfile *mf;
	uchar mdata[IOHDRSZ + Maxfdata];
	Request req;
	Job *job;

	USED(v);

	for(;;){
		n = read9pmsg(mfd[0], mdata, sizeof mdata);
		if(n <= 0){
			syslog(0, logfile, "error reading mntpt: %r");
			break;
		}
		job = newjob();
		if(convM2S(mdata, n, &job->request) != n){
			freejob(job);
			continue;
		}
		if(debug)
			syslog(0, logfile, "%F", &job->request);

		getactivity(&req);
		req.aborttime = now + 60;	/* don't spend more than 60 seconds */

		mf = nil;
		switch(job->request.type){
		case Tversion:
		case Tauth:
		case Tflush:
			break;
		case Tattach:
			mf = newfid(job->request.fid, 1);
			if(mf == nil){
				sendmsg(job, "fid in use");
				goto skip;
			}
			break;
		default:
			mf = newfid(job->request.fid, 0);
			if(mf == nil){
				sendmsg(job, "unknown fid");
				goto skip;
			}
			break;
		}

		switch(job->request.type){
		default:
			syslog(1, logfile, "unknown request type %d", job->request.type);
			break;
		case Tversion:
			rversion(job);
			break;
		case Tauth:
			rauth(job);
			break;
		case Tflush:
			rflush(job);
			break;
		case Tattach:
			rattach(job, mf);
			break;
		case Twalk:
			rwalk(job, mf);
			break;
		case Topen:
			ropen(job, mf);
			break;
		case Tcreate:
			rcreate(job, mf);
			break;
		case Tread:
			rread(job, mf);
			break;
		case Twrite:
			rwrite(job, mf, &req);
			break;
		case Tclunk:
			rclunk(job, mf);
			break;
		case Tremove:
			rremove(job, mf);
			break;
		case Tstat:
			rstat(job, mf);
			break;
		case Twstat:
			rwstat(job, mf);
			break;
		}
skip:
		freejob(job);
		putactivity();
	}
}