henesyinit from p9fd787fda5 years agoHistory
1821 lines · 31.6 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <auth.h>#include <fcall.h>#include <bio.h>#include <ctype.h>#include <ndb.h>#include <ip.h> enum{	Nreply=			20,	Maxreply=		256,	Maxrequest=		128,	Maxpath=		128,	Maxfdata=		8192, 	Qdir=			0,	Qcs=			1,}; typedef struct Mfile	Mfile;typedef struct Mlist	Mlist;typedef struct Network	Network;typedef struct Flushreq	Flushreq;typedef struct Job	Job; int vers;		/* incremented each clone/attach */ struct Mfile{	int		busy; 	char		*user;	Qid		qid;	int		fid; 	/*	 *  current request	 */	char		*net;	char		*host;	char		*serv;	char		*rem; 	/*	 *  result of the last lookup	 */	Network		*nextnet;	int		nreply;	char		*reply[Nreply];	int		replylen[Nreply];}; struct Mlist{	Mlist	*next;	Mfile	mf;};  ////  active requests//struct Job{	Job	*next;	int	flushed;	Fcall	request;	Fcall	reply;};Lock	joblock;Job	*joblist; Mlist	*mlist;int	mfd[2];int	debug;int	paranoia;jmp_buf	masterjmp;	/* return through here after a slave process has been created */int	*isslave;	/* *isslave non-zero means this is a slave process */char	*dbfile;Ndb	*db, *netdb; void	rversion(Job*);void	rflush(Job*);void	rattach(Job*, Mfile*);char*	rwalk(Job*, Mfile*);void	ropen(Job*, Mfile*);void	rcreate(Job*, Mfile*);void	rread(Job*, Mfile*);void	rwrite(Job*, Mfile*);void	rclunk(Job*, Mfile*);void	rremove(Job*, Mfile*);void	rstat(Job*, Mfile*);void	rwstat(Job*, Mfile*);void	rauth(Job*);void	sendmsg(Job*, char*);void	error(char*);void	mountinit(char*, char*);void	io(void);void	ndbinit(void);void	netinit(int);void	netadd(char*);char	*genquery(Mfile*, char*);char*	ipinfoquery(Mfile*, char**, int);int	needproto(Network*, Ndbtuple*);int	lookup(Mfile*);Ndbtuple*	reorder(Ndbtuple*, Ndbtuple*);void	ipid(void);void	readipinterfaces(void);void*	emalloc(int);char*	estrdup(char*);Job*	newjob(void);void	freejob(Job*);void	setext(char*, int, char*);void	cleanmf(Mfile*); extern void	paralloc(void); Lock	dblock;		/* mutex on database operations */Lock	netlock;	/* mutex for netinit() */ char	*logfile = "cs";char	*paranoiafile = "cs.paranoia"; char	mntpt[Maxpath];char	netndb[Maxpath]; /* *  Network specific translators */Ndbtuple*	iplookup(Network*, char*, char*, int);char*		iptrans(Ndbtuple*, Network*, char*, char*, int);Ndbtuple*	telcolookup(Network*, char*, char*, int);char*		telcotrans(Ndbtuple*, Network*, char*, char*, int);Ndbtuple*	dnsiplookup(char*, Ndbs*); struct Network{	char		*net;	Ndbtuple	*(*lookup)(Network*, char*, char*, int);	char		*(*trans)(Ndbtuple*, Network*, char*, char*, int);	int		considered;	int		fasttimeouthack;	Network		*next;}; enum{	Nilfast,	Ntcp,	Nil,	Nudp,	Nicmp,	Nrudp,	Ntelco,}; /* *  net doesn't apply to udp, icmp, or telco (for speed) */Network network[] = {[Nilfast]	{ "il",		iplookup,	iptrans,	0, 1 },[Ntcp]		{ "tcp",	iplookup,	iptrans,	0, 0 },[Nil]		{ "il",		iplookup,	iptrans,	0, 0 },[Nudp]		{ "udp",	iplookup,	iptrans,	1, 0 },[Nicmp]		{ "icmp",	iplookup,	iptrans,	1, 0 },[Nrudp]		{ "rudp",	iplookup,	iptrans,	1, 0 },[Ntelco]	{ "telco",	telcolookup,	telcotrans,	1, 0 },		{ 0 },}; Lock ipifclock;Ipifc *ipifcs; char	eaddr[Ndbvlen];		/* ascii ethernet address */char	ipaddr[Ndbvlen];	/* ascii internet address */uchar	ipa[IPaddrlen];		/* binary internet address */char	mysysname[Ndbvlen]; Network *netlist;		/* networks ordered by preference */Network *last; voidusage(void){	fprint(2, "usage: %s [-d] [-f ndb-file] [-x netmtpt] [-n]\n", argv0);	exits("usage");} voidmain(int argc, char *argv[]){	char servefile[Maxpath];	int justsetname;	char *p;	char ext[Maxpath]; 	justsetname = 0;	setnetmtpt(mntpt, sizeof(mntpt), nil);	ext[0] = 0;	ARGBEGIN{	case 'd':		debug = 1;		break;	case 'f':		p = ARGF();		if(p == nil)			usage();		dbfile = p;		break;	case 'x':		p = ARGF();		if(p == nil)			usage();		setnetmtpt(mntpt, sizeof(mntpt), p);		setext(ext, sizeof(ext), mntpt);		break;	case 'n':		justsetname = 1;		break;	}ARGEND	USED(argc);	USED(argv); 	rfork(RFREND|RFNOTEG); 	snprint(servefile, sizeof(servefile), "#s/cs%s", ext);	snprint(netndb, sizeof(netndb), "%s/ndb", mntpt);	unmount(servefile, mntpt);	remove(servefile); 	fmtinstall('E', eipfmt);	fmtinstall('I', eipfmt);	fmtinstall('M', eipfmt);	fmtinstall('F', fcallfmt); 	ndbinit();	netinit(0); 	if(!justsetname){		mountinit(servefile, mntpt);		io();	}	exits(0);} /* *  if a mount point is specified, set the cs extention to be the mount point *  with '_'s replacing '/'s */voidsetext(char *ext, int n, char *p){	int i, c; 	n--;	for(i = 0; i < n; i++){		c = p[i];		if(c == 0)			break;		if(c == '/')			c = '_';		ext[i] = c;	}	ext[i] = 0;} voidmountinit(char *service, char *mntpt){	int f;	int p[2];	char buf[32]; 	if(pipe(p) < 0)		error("pipe failed");	switch(rfork(RFFDG|RFPROC|RFNAMEG)){	case 0:		close(p[1]);		break;	case -1:		error("fork failed\n");	default:		/*		 *  make a /srv/cs		 */		f = create(service, 1, 0666);		if(f < 0)			error(service);		snprint(buf, sizeof(buf), "%d", p[1]);		if(write(f, buf, strlen(buf)) != strlen(buf))			error("write /srv/cs");		close(f); 		/*		 *  put ourselves into the file system		 */		close(p[0]);		if(mount(p[1], -1, mntpt, MAFTER, "") < 0)			error("mount failed\n");		_exits(0);	}	mfd[0] = mfd[1] = p[0];} voidndbinit(void){	db = ndbopen(dbfile);	if(db == nil)		error("can't open network database"); 	netdb = ndbopen(netndb);	if(netdb != nil){		netdb->nohash = 1;		db = ndbcat(netdb, db);	}} Mfile*newfid(int fid){	Mlist *f, *ff;	Mfile *mf; 	ff = 0;	for(f = mlist; f; f = f->next)		if(f->mf.busy && f->mf.fid == fid)			return &f->mf;		else if(!ff && !f->mf.busy)			ff = f;	if(ff == 0){		ff = emalloc(sizeof *f);		ff->next = mlist;		mlist = ff;	}	mf = &ff->mf;	memset(mf, 0, sizeof *mf);	mf->fid = fid;	return mf;} Job*newjob(void){	Job *job; 	job = mallocz(sizeof(Job), 1);	lock(&joblock);	job->next = joblist;	joblist = job;	job->request.tag = -1;	unlock(&joblock);	return job;} voidfreejob(Job *job){	Job **l; 	lock(&joblock);	for(l = &joblist; *l; l = &(*l)->next){		if((*l) == job){			*l = job->next;			free(job);			break;		}	}	unlock(&joblock);} voidflushjob(int tag){	Job *job; 	lock(&joblock);	for(job = joblist; job; job = job->next){		if(job->request.tag == tag && job->request.type != Tflush){			job->flushed = 1;			break;		}	}	unlock(&joblock);} voidio(void){	long n;	Mfile *mf;	int slaveflag;	uchar mdata[IOHDRSZ + Maxfdata];	Job *job; 	/*	 *  if we ask dns to fulfill requests,	 *  a slave process is created to wait for replies.  The	 *  master process returns immediately via a longjmp	 *  through 'masterjmp'.	 *	 *  *isslave is a pointer into the call stack to a variable	 *  that tells whether or not the current process is a slave.	 */	slaveflag = 0;		/* init slave variable */	isslave = &slaveflag;	setjmp(masterjmp); 	for(;;){		n = read9pmsg(mfd[0], mdata, sizeof mdata);		if(n<=0)			error("mount read");		job = newjob();		if(convM2S(mdata, n, &job->request) != n){			syslog(1, logfile, "format error %ux %ux %ux %ux %ux", mdata[0], mdata[1], mdata[2], mdata[3], mdata[4]);			freejob(job);			continue;		}		if(job->request.fid<0)			error("fid out of range");		lock(&dblock);		mf = newfid(job->request.fid);		if(debug)			syslog(0, logfile, "%F", &job->request);				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);			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;		}		unlock(&dblock); 		freejob(job); 		/*		 *  slave processes die after replying		 */		if(*isslave){			if(debug)				syslog(0, logfile, "slave death %d", getpid());			_exits(0);		}	}} voidrversion(Job *job){	if(job->request.msize > IOHDRSZ + Maxfdata)		job->reply.msize = IOHDRSZ + Maxfdata;	else		job->reply.msize = job->request.msize;	if(strncmp(job->request.version, "9P2000", 6) != 0)		sendmsg(job, "unknown 9P version");	else{		job->reply.version = "9P2000";		sendmsg(job, 0);	}

Lines 1–500 of 1821.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t