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

📄 devsd.c

📁 在x86平台上运行不可信任代码的sandbox。
💻 C
📖 第 1 页 / 共 3 页
字号:
		return n;	case Qtopdir:	case Qunitdir:		return devdirread(c, a, n, 0, 0, sdgen);	case Qctl:		sdev = sdgetdev(DEV(c->qid));		if(sdev == nil)			error(Enonexist);		unit = sdev->unit[UNIT(c->qid)];		m = 16*1024;	/* room for register dumps */		p = malloc(m);		l = snprint(p, m, "inquiry %.48s\n",			(char*)unit->inquiry+8);		qlock(&unit->ctl);		/*		 * If there's a device specific routine it must		 * provide all information pertaining to night geometry		 * and the garscadden trains.		 */		if(unit->dev->ifc->rctl)			l += unit->dev->ifc->rctl(unit, p+l, m-l);		if(unit->sectors == 0)			sdinitpart(unit);		if(unit->sectors){			if(unit->dev->ifc->rctl == nil)				l += snprint(p+l, m-l,					"geometry %llud %lud\n",					unit->sectors, unit->secsize);			pp = unit->part;			for(i = 0; i < unit->npart; i++){				if(pp->valid)					l += snprint(p+l, m-l,						"part %s %llud %llud\n",						pp->perm.name, pp->start, pp->end);				pp++;			}		}		qunlock(&unit->ctl);		decref(&sdev->r);		l = readstr(offset, a, n, p);		free(p);		return l;	case Qraw:		sdev = sdgetdev(DEV(c->qid));		if(sdev == nil)			error(Enonexist);		unit = sdev->unit[UNIT(c->qid)];		qlock(&unit->raw);		if(waserror()){			qunlock(&unit->raw);			decref(&sdev->r);			nexterror();		}		if(unit->state == Rawdata){			unit->state = Rawstatus;			i = sdrio(unit->req, a, n);		}		else if(unit->state == Rawstatus){			status = unit->req->status;			unit->state = Rawcmd;			free(unit->req);			unit->req = nil;			i = readnum(0, a, n, status, NUMSIZE);		} else			i = 0;		qunlock(&unit->raw);		decref(&sdev->r);		poperror();		return i;	case Qpart:		return sdbio(c, 0, a, n, off);	}}static void legacytopctl(Cmdbuf*);static longsdwrite(Chan* c, void* a, long n, vlong off){	char *f0;	int i;	uvlong end, start;	Cmdbuf *cb;	SDifc *ifc;	SDreq *req;	SDunit *unit;	SDev *sdev;	switch(TYPE(c->qid)){	default:		error(Eperm);	case Qtopctl:		cb = parsecmd(a, n);		if(waserror()){			free(cb);			nexterror();		}		if(cb->nf == 0)			error("empty control message");		f0 = cb->f[0];		cb->f++;		cb->nf--;		if(strcmp(f0, "config") == 0){			/* wormhole into ugly legacy interface */			legacytopctl(cb);			poperror();			free(cb);			break;		}		/*		 * "ata arg..." invokes sdifc[i]->wtopctl(nil, cb),		 * where sdifc[i]->name=="ata" and cb contains the args.		 */		ifc = nil;		sdev = nil;		for(i=0; sdifc[i]; i++){			if(strcmp(sdifc[i]->name, f0) == 0){				ifc = sdifc[i];				sdev = nil;				goto subtopctl;			}		}		/*		 * "sd1 arg..." invokes sdifc[i]->wtopctl(sdev, cb),		 * where sdifc[i] and sdev match controller letter "1",		 * and cb contains the args.		 */		if(f0[0]=='s' && f0[1]=='d' && f0[2] && f0[3] == 0){			if((sdev = sdgetdev(f0[2])) != nil){				ifc = sdev->ifc;				goto subtopctl;			}		}		error("unknown interface");	subtopctl:		if(waserror()){			if(sdev)				decref(&sdev->r);			nexterror();		}		if(ifc->wtopctl)			ifc->wtopctl(sdev, cb);		else			error(Ebadctl);		poperror();		poperror();		if (sdev)			decref(&sdev->r);		free(cb);		break;	case Qctl:		cb = parsecmd(a, n);		sdev = sdgetdev(DEV(c->qid));		if(sdev == nil)			error(Enonexist);		unit = sdev->unit[UNIT(c->qid)];		qlock(&unit->ctl);		if(waserror()){			qunlock(&unit->ctl);			decref(&sdev->r);			free(cb);			nexterror();		}		if(unit->vers != c->qid.vers)			error(Echange);		if(cb->nf < 1)			error(Ebadctl);		if(strcmp(cb->f[0], "part") == 0){			if(cb->nf != 4)				error(Ebadctl);			if(unit->sectors == 0 && !sdinitpart(unit))				error(Eio);			start = strtoull(cb->f[2], 0, 0);			end = strtoull(cb->f[3], 0, 0);			sdaddpart(unit, cb->f[1], start, end);		}		else if(strcmp(cb->f[0], "delpart") == 0){			if(cb->nf != 2 || unit->part == nil)				error(Ebadctl);			sddelpart(unit, cb->f[1]);		}		else if(unit->dev->ifc->wctl)			unit->dev->ifc->wctl(unit, cb);		else			error(Ebadctl);		qunlock(&unit->ctl);		decref(&sdev->r);		poperror();		free(cb);		break;	case Qraw:		sdev = sdgetdev(DEV(c->qid));		if(sdev == nil)			error(Enonexist);		unit = sdev->unit[UNIT(c->qid)];		qlock(&unit->raw);		if(waserror()){			qunlock(&unit->raw);			decref(&sdev->r);			nexterror();		}		switch(unit->state){		case Rawcmd:			if(n < 6 || n > sizeof(req->cmd))				error(Ebadarg);			if((req = malloc(sizeof(SDreq))) == nil)				error(Enomem);			req->unit = unit;			memmove(req->cmd, a, n);			req->clen = n;			req->flags = SDnosense;			req->status = ~0;			unit->req = req;			unit->state = Rawdata;			break;		case Rawstatus:			unit->state = Rawcmd;			free(unit->req);			unit->req = nil;			error(Ebadusefd);		case Rawdata:			unit->state = Rawstatus;			unit->req->write = 1;			n = sdrio(unit->req, a, n);		}		qunlock(&unit->raw);		decref(&sdev->r);		poperror();		break;	case Qpart:		return sdbio(c, 1, a, n, off);	}	return n;}static intsdwstat(Chan* c, uchar* dp, int n){	Dir *d;	SDpart *pp;	SDperm *perm;	SDunit *unit;	SDev *sdev;	if(c->qid.type & QTDIR)		error(Eperm);	sdev = sdgetdev(DEV(c->qid));	if(sdev == nil)		error(Enonexist);	unit = sdev->unit[UNIT(c->qid)];	qlock(&unit->ctl);	d = nil;	if(waserror()){		free(d);		qunlock(&unit->ctl);		decref(&sdev->r);		nexterror();	}	switch(TYPE(c->qid)){	default:		error(Eperm);	case Qctl:		perm = &unit->ctlperm;		break;	case Qraw:		perm = &unit->rawperm;		break;	case Qpart:		pp = &unit->part[PART(c->qid)];		if(unit->vers+pp->vers != c->qid.vers)			error(Enonexist);		perm = &pp->perm;		break;	}	if(strcmp(up->user, perm->user) && !iseve())		error(Eperm);	d = smalloc(sizeof(Dir)+n);	n = convM2D(dp, n, &d[0], (char*)&d[1]);	if(n == 0)		error(Eshortstat);	if(!emptystr(d[0].uid))		kstrdup(&perm->user, d[0].uid);	if(d[0].mode != ~0UL)		perm->perm = (perm->perm & ~0777) | (d[0].mode & 0777);	free(d);	qunlock(&unit->ctl);	decref(&sdev->r);	poperror();	return n;}static intconfigure(char* spec, DevConf* cf){	SDev *s, *sdev;	char *p;	int i;	if(sdindex(*spec) < 0)		error("bad sd spec");	if((p = strchr(cf->type, '/')) != nil)		*p++ = '\0';	for(i = 0; sdifc[i] != nil; i++)		if(strcmp(sdifc[i]->name, cf->type) == 0)			break;	if(sdifc[i] == nil)		error("sd type not found");	if(p)		*(p-1) = '/';	if(sdifc[i]->probe == nil)		error("sd type cannot probe");	sdev = sdifc[i]->probe(cf);	for(s=sdev; s; s=s->next)		s->idno = *spec;	sdadddevs(sdev);	return 0;}static intunconfigure(char* spec){	int i;	SDev *sdev;	SDunit *unit;	if((i = sdindex(*spec)) < 0)		error(Enonexist);	qlock(&devslock);	if((sdev = devs[i]) == nil){		qunlock(&devslock);		error(Enonexist);	}	if(sdev->r.ref){		qunlock(&devslock);		error(Einuse);	}	devs[i] = nil;	qunlock(&devslock);	/* make sure no interrupts arrive anymore before removing resources */	if(sdev->enabled && sdev->ifc->disable)		sdev->ifc->disable(sdev);	for(i = 0; i != sdev->nunit; i++){		if((unit = sdev->unit[i])){			free(unit->perm.name);			free(unit->perm.user);			free(unit);		}	}	if(sdev->ifc->clear)		sdev->ifc->clear(sdev);	free(sdev);	return 0;}static intsdconfig(int on, char* spec, DevConf* cf){	if(on)		return configure(spec, cf);	return unconfigure(spec);}Dev sddevtab = {	'S',	"sd",	sdreset,	devinit,	devshutdown,	sdattach,	sdwalk,	sdstat,	sdopen,	devcreate,	sdclose,	sdread,	devbread,	sdwrite,	devbwrite,	devremove,	sdwstat,	devpower,	sdconfig,};/* * This is wrong for so many reasons.  This code must go. */typedef struct Confdata Confdata;struct Confdata {	int	on;	char*	spec;	DevConf	cf;};static voidparseswitch(Confdata* cd, char* option){	if(!strcmp("on", option))		cd->on = 1;	else if(!strcmp("off", option))		cd->on = 0;	else		error(Ebadarg);}static voidparsespec(Confdata* cd, char* option){	if(strlen(option) > 1)		error(Ebadarg);	cd->spec = option;}static Devport*getnewport(DevConf* dc){	Devport *p;	p = (Devport *)malloc((dc->nports + 1) * sizeof(Devport));	if(dc->nports > 0){		memmove(p, dc->ports, dc->nports * sizeof(Devport));		free(dc->ports);	}	dc->ports = p;	p = &dc->ports[dc->nports++];	p->size = -1;	p->port = (ulong)-1;	return p;}static voidparseport(Confdata* cd, char* option){	char *e;	Devport *p;	if(cd->cf.nports == 0 || cd->cf.ports[cd->cf.nports-1].port != (ulong)-1)		p = getnewport(&cd->cf);	else		p = &cd->cf.ports[cd->cf.nports-1];	p->port = strtol(option, &e, 0);	if(e == nil || *e != '\0')		error(Ebadarg);}static voidparsesize(Confdata* cd, char* option){	char *e;	Devport *p;	if(cd->cf.nports == 0 || cd->cf.ports[cd->cf.nports-1].size != -1)		p = getnewport(&cd->cf);	else		p = &cd->cf.ports[cd->cf.nports-1];	p->size = (int)strtol(option, &e, 0);	if(e == nil || *e != '\0')		error(Ebadarg);}static voidparseirq(Confdata* cd, char* option){	char *e;	cd->cf.intnum = strtoul(option, &e, 0);	if(e == nil || *e != '\0')		error(Ebadarg);}static voidparsetype(Confdata* cd, char* option){	cd->cf.type = option;}static struct {	char	*name;	void	(*parse)(Confdata*, char*);} options[] = {	"switch",	parseswitch,	"spec",		parsespec,	"port",		parseport,	"size",		parsesize,	"irq",		parseirq,	"type",		parsetype,};static voidlegacytopctl(Cmdbuf *cb){	char *opt;	int i, j;	Confdata cd;	memset(&cd, 0, sizeof cd);	cd.on = -1;	for(i=0; i<cb->nf; i+=2){		if(i+2 > cb->nf)			error(Ebadarg);		opt = cb->f[i];		for(j=0; j<nelem(options); j++)			if(strcmp(opt, options[j].name) == 0){				options[j].parse(&cd, cb->f[i+1]);				break;			}		if(j == nelem(options))			error(Ebadarg);	}	/* this has been rewritten to accomodate sdaoe */	if(cd.on < 0 || cd.spec == 0)		error(Ebadarg);	if(cd.on && cd.cf.type == nil)		error(Ebadarg);	sdconfig(cd.on, cd.spec, &cd.cf);}

⌨️ 快捷键说明

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