⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
{	int mode;	char *err;	err = 0;	mode = job->request.mode;	if(mf->qid.type & QTDIR){		if(mode)			err = "permission denied";	}	job->reply.qid = mf->qid;	job->reply.iounit = 0;	sendmsg(job, err);}voidrcreate(Job *job, Mfile *mf){	USED(mf);	sendmsg(job, "creation permission denied");}voidrread(Job *job, Mfile *mf){	int i, n, cnt;	long off, toff, clock;	Dir dir;	uchar buf[Maxfdata];	char *err;	n = 0;	err = 0;	off = job->request.offset;	cnt = job->request.count;	if(mf->qid.type & QTDIR){		clock = time(0);		if(off == 0){			dir.name = "cs";			dir.qid.type = QTFILE;			dir.qid.vers = vers;			dir.qid.path = Qcs;			dir.mode = 0666;			dir.length = 0;			dir.uid = mf->user;			dir.gid = mf->user;			dir.muid = mf->user;			dir.atime = clock;	/* wrong */			dir.mtime = clock;	/* wrong */			n = convD2M(&dir, buf, sizeof buf);		}		job->reply.data = (char*)buf;	} else {		for(;;){			/* look for an answer at the right offset */			toff = 0;			for(i = 0; mf->reply[i] && i < mf->nreply; i++){				n = mf->replylen[i];				if(off < toff + n)					break;				toff += n;			}			if(i < mf->nreply)				break;		/* got something to return */			/* try looking up more answers */			if(lookup(mf) == 0){				/* no more */				n = 0;				goto send;			}		}		/* give back a single reply (or part of one) */		job->reply.data = mf->reply[i] + (off - toff);		if(cnt > toff - off + n)			n = toff - off + n;		else			n = cnt;	}send:	job->reply.count = n;	sendmsg(job, err);}voidcleanmf(Mfile *mf){	int i;	if(mf->net != nil){		free(mf->net);		mf->net = nil;	}	if(mf->host != nil){		free(mf->host);		mf->host = nil;	}	if(mf->serv != nil){		free(mf->serv);		mf->serv = nil;	}	if(mf->rem != nil){		free(mf->rem);		mf->rem = nil;	}	for(i = 0; i < mf->nreply; i++){		free(mf->reply[i]);		mf->reply[i] = nil;		mf->replylen[i] = 0;	}	mf->nreply = 0;	mf->nextnet = netlist;}voidrwrite(Job *job, Mfile *mf){	int cnt, n;	char *err;	char *field[4];	char curerr[64];	err = 0;	cnt = job->request.count;	if(mf->qid.type & QTDIR){		err = "can't write directory";		goto send;	}	if(cnt >= Maxrequest){		err = "request too long";		goto send;	}	job->request.data[cnt] = 0;	/*	 *  toggle debugging	 */	if(strncmp(job->request.data, "debug", 5)==0){		debug ^= 1;		syslog(1, logfile, "debug %d", debug);		goto send;	}	/*	 *  toggle debugging	 */	if(strncmp(job->request.data, "paranoia", 8)==0){		paranoia ^= 1;		syslog(1, logfile, "paranoia %d", paranoia);		goto send;	}	/*	 *  add networks to the default list	 */	if(strncmp(job->request.data, "add ", 4)==0){		if(job->request.data[cnt-1] == '\n')			job->request.data[cnt-1] = 0;		netadd(job->request.data+4);		readipinterfaces();		goto send;	}	/*	 *  refresh all state	 */	if(strncmp(job->request.data, "refresh", 7)==0){		netinit(1);		goto send;	}	/* start transaction with a clean slate */	cleanmf(mf);	/*	 *  look for a general query	 */	if(*job->request.data == '!'){		err = genquery(mf, job->request.data+1);		goto send;	}	if(debug)		syslog(0, logfile, "write %s", job->request.data);	if(paranoia)		syslog(0, paranoiafile, "write %s by %s", job->request.data, mf->user);	/*	 *  break up name	 */	n = getfields(job->request.data, field, 4, 1, "!");	switch(n){	case 1:		mf->net = strdup("net");		mf->host = strdup(field[0]);		break;	case 4:		mf->rem = strdup(field[3]);		/* fall through */	case 3:		mf->serv = strdup(field[2]);		/* fall through */	case 2:		mf->host = strdup(field[1]);		mf->net = strdup(field[0]);		break;	}	/*	 *  do the first net worth of lookup	 */	if(lookup(mf) == 0){		rerrstr(curerr, sizeof curerr);		err = curerr;	}send:	job->reply.count = cnt;	sendmsg(job, err);}voidrclunk(Job *job, Mfile *mf){	cleanmf(mf);	free(mf->user);	mf->user = 0;	mf->busy = 0;	mf->fid = 0;	sendmsg(job, 0);}voidrremove(Job *job, Mfile *mf){	USED(mf);	sendmsg(job, "remove permission denied");}voidrstat(Job *job, Mfile *mf){	Dir dir;	uchar buf[IOHDRSZ+Maxfdata];	if(mf->qid.type & QTDIR){		dir.name = ".";		dir.mode = DMDIR|0555;	} else {		dir.name = "cs";		dir.mode = 0666;	}	dir.qid = mf->qid;	dir.length = 0;	dir.uid = mf->user;	dir.gid = mf->user;	dir.muid = mf->user;	dir.atime = dir.mtime = time(0);	job->reply.nstat = convD2M(&dir, buf, sizeof buf);	job->reply.stat = buf;	sendmsg(job, 0);}voidrwstat(Job *job, Mfile *mf){	USED(mf);	sendmsg(job, "wstat permission denied");}voidsendmsg(Job *job, char *err){	int n;	uchar mdata[IOHDRSZ + Maxfdata];	char ename[ERRMAX];	if(err){		job->reply.type = Rerror;		snprint(ename, sizeof(ename), "cs: %s", err);		job->reply.ename = ename;	}else{		job->reply.type = job->request.type+1;	}	job->reply.tag = job->request.tag;	n = convS2M(&job->reply, mdata, sizeof mdata);	if(n == 0){		syslog(1, logfile, "sendmsg convS2M of %F returns 0", &job->reply);		abort();	}	lock(&joblock);	if(job->flushed == 0)		if(write(mfd[1], mdata, n)!=n)			error("mount write");	unlock(&joblock);	if(debug)		syslog(0, logfile, "%F %d", &job->reply, n);}voiderror(char *s){	syslog(1, "cs", "%s: %r", s);	_exits(0);}static intisvalidip(uchar *ip){	return ipcmp(ip, IPnoaddr) != 0 && ipcmp(ip, v4prefix) != 0;}static uchar loopbacknet[IPaddrlen] = {	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0xff, 0xff,	127, 0, 0, 0};static uchar loopbackmask[IPaddrlen] = {	0xff, 0xff, 0xff, 0xff,	0xff, 0xff, 0xff, 0xff,	0xff, 0xff, 0xff, 0xff,	0xff, 0, 0, 0};voidreadipinterfaces(void){	if(myipaddr(ipa, mntpt) != 0)		ipmove(ipa, IPnoaddr);	sprint(ipaddr, "%I", ipa);	if (debug)		syslog(0, "dns", "ipaddr is %s\n", ipaddr);}/* *  get the system name */voidipid(void){	uchar addr[6];	Ndbtuple *t, *tt;	char *p, *attr;	Ndbs s;	int f;	char buf[Maxpath];	/* use environment, ether addr, or ipaddr to get system name */	if(mysysname == 0){		/*		 *  environment has priority.		 *		 *  on the sgi power the default system name		 *  is the ip address.  ignore that.		 *		 */		p = getenv("sysname");		if(p && *p){			attr = ipattr(p);			if(strcmp(attr, "ip") != 0)				mysysname = strdup(p);		}		/*		 *  the /net/ndb contains what the network		 *  figured out from DHCP.  use that name if		 *  there is one. 		 */		if(mysysname == 0 && netdb != nil){			ndbreopen(netdb);			for(tt = t = ndbparse(netdb); t != nil; t = t->entry){				if(strcmp(t->attr, "sys") == 0){					mysysname = strdup(t->val);					break;				}			}			ndbfree(tt);		}		/* next network database, ip address, and ether address to find a name */		if(mysysname == 0){			t = nil;			if(isvalidip(ipa))				free(ndbgetvalue(db, &s, "ip", ipaddr, "sys", &t));			if(t == nil){				for(f = 0; f < 3; f++){					snprint(buf, sizeof buf, "%s/ether%d", mntpt, f);					if(myetheraddr(addr, buf) >= 0){						snprint(eaddr, sizeof(eaddr), "%E", addr);						free(ndbgetvalue(db, &s, "ether", eaddr, "sys", &t));						if(t != nil)							break;					}				}			}			for(tt = t; tt != nil; tt = tt->entry){				if(strcmp(tt->attr, "sys") == 0){					mysysname = strdup(tt->val);					break;				}			}			ndbfree(t);		}		/* nothing else worked, use the ip address */		if(mysysname == 0 && isvalidip(ipa))			mysysname = strdup(ipaddr);							/* set /dev/sysname if we now know it */		if(mysysname){			f = open("/dev/sysname", OWRITE);			if(f >= 0){				write(f, mysysname, strlen(mysysname));				close(f);			}		}	}}/* *  Set up a list of default networks by looking for *  /net/ * /clone. */voidnetinit(int background){	char clone[Maxpath];	Network *np;	static int working;	if(background){		switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){		case 0:			break;		default:			return;		}		lock(&netlock);	}	/* add the mounted networks to the default list */	for(np = network; np->net; np++){		if(np->considered)			continue;		snprint(clone, sizeof(clone), "%s/%s/clone", mntpt, np->net);		if(access(clone, AEXIST) < 0)			continue;		if(netlist)			last->next = np;		else			netlist = np;		last = np;		np->next = 0;		np->considered = 1;	}	/* find out what our ip address is */	readipinterfaces();	/* set the system name if we need to, these says ip is all we have */	ipid();	if(debug)		syslog(0, logfile, "mysysname %s eaddr %s ipaddr %s ipa %I\n",			mysysname?mysysname:"???", eaddr, ipaddr, ipa);	if(background){		unlock(&netlock);		_exits(0);	}}/* *  add networks to the standard list */voidnetadd(char *p){	Network *np;	char *field[12];	int i, n;	n = getfields(p, field, 12, 1, " ");	for(i = 0; i < n; i++){		for(np = network; np->net; np++){			if(strcmp(field[i], np->net) != 0)				continue;			if(np->considered)				break;			if(netlist)				last->next = np;			else				netlist = np;			last = np;			np->next = 0;			np->considered = 1;		}	}}intlookforproto(Ndbtuple *t, char *proto){	for(; t != nil; t = t->entry)		if(strcmp(t->attr, "proto") == 0 && strcmp(t->val, proto) == 0)			return 1;	return 0;}/* *  lookup a request.  the network "net" means we should pick the *  best network to get there. */intlookup(Mfile *mf){	Network *np;	char *cp;	Ndbtuple *nt, *t;	char reply[Maxreply];	int i, rv;	int hack;	/* open up the standard db files */	if(db == 0)		ndbinit();	if(db == 0)		error("can't open mf->network database\n");	rv = 0;	if(mf->net == nil)		return 0;	/* must have been a genquery */	if(strcmp(mf->net, "net") == 0){ 		/*		 *  go through set of default nets		 */		for(np = mf->nextnet; np; np = np->next){			nt = (*np->lookup)(np, mf->host, mf->serv, 1);			if(nt == nil)				continue;			hack = np->fasttimeouthack && !lookforproto(nt, np->net);			for(t = nt; mf->nreply < Nreply && t; t = t->entry){				cp = (*np->trans)(t, np, mf->serv, mf->rem, hack);				if(cp){					/* avoid duplicates */					for(i = 0; i < mf->nreply; i++)						if(strcmp(mf->reply[i], cp) == 0)							break;					if(i == mf->nreply){						/* save the reply */						mf->replylen[mf->nreply] = strlen(cp);						mf->reply[mf->nreply++] = cp;						rv++;					}				}			}			ndbfree(nt);			np = np->next;			break;		}		mf->nextnet = np;		return rv;	}	/*	 *  if not /net, we only get one lookup	 */	if(mf->nreply != 0)		return 0;	/*	 *  look for a specific network	 */	for(np = netlist; np && np->net != nil; np++){		if(np->fasttimeouthack)			continue;		if(strcmp(np->net, mf->net) == 0)			break;	}	if(np && np->net != nil){		/*		 *  known network		 */		nt = (*np->lookup)(np, mf->host, mf->serv, 1);		for(t = nt; mf->nreply < Nreply && t; t = t->entry){			cp = (*np->trans)(t, np, mf->serv, mf->rem, 0);			if(cp){				mf->replylen[mf->nreply] = strlen(cp);				mf->reply[mf->nreply++] = cp;				rv++;			}		}		ndbfree(nt);		return rv;	} else {		/*		 *  not a known network, don't translate host or service		 */		if(mf->serv)			snprint(reply, sizeof(reply), "%s/%s/clone %s!%s",				mntpt, mf->net, mf->host, mf->serv);		else			snprint(reply, sizeof(reply), "%s/%s/clone %s",				mntpt, mf->net, mf->host);		mf->reply[0] = strdup(reply);		mf->replylen[0] = strlen(reply);		mf->nreply = 1;		return 1;	}}/* *  translate an ip service name into a port number.  If it's a numeric port *  number, look for restricted access. *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -