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

📄 scuzz.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		break;	}	total = 0;	n = MIN(nbytes, maxiosize);	if((n = readn(fd, rwbuf, n)) == -1){		fprint(2, "file read failed %r\n");		close(fd);		return -1;	}	if((x = SRwtrack(rp, rwbuf, n, track, mode)) != n){		fprint(2, "wtrack: write incomplete: asked %ld, did %ld\n", n, x);		if(rp->status == STok)			rp->status = Status_SW;		close(fd);		return -1;	}	nbytes -= n;	total += n;	while(nbytes){		n = MIN(nbytes, maxiosize);		if((n = read(fd, rwbuf, n)) == -1){			break;		}		if((x = SRwrite(rp, rwbuf, n)) != n){			fprint(2, "write: write incomplete: asked %ld, did %ld\n", n, x);			if(rp->status == STok)				rp->status = Status_SW;			break;		}		nbytes -= n;		total += n;	}	close(fd);	if(pid >= 0 && waitfor(pid)){		rp->status = Status_SW;		return -1;	}	return total;}static longcmdload(ScsiReq *rp, int argc, char *argv[]){	USED(argc, argv);	return SRmload(rp, 0);}static longcmdunload(ScsiReq *rp, int argc, char *argv[]){	USED(argc, argv);	return SRmload(rp, 1);}static longcmdfixation(ScsiReq *rp, int argc, char *argv[]){	uchar type;	char *p;	type = 0;	if(argc && (type = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){		rp->status = Status_BADARG;		return -1;	}	return SRfixation(rp, type);}static longcmdeinit(ScsiReq *rp, int argc, char *argv[]){	USED(argc, argv);	return SReinitialise(rp);}static longcmdmmove(ScsiReq *rp, int argc, char *argv[]){	int transport, source, destination, invert;	char *p;	invert = 0;	switch(argc){	default:		rp->status = Status_BADARG;		return -1;	case 4:		if((invert = strtoul(argv[3], &p, 0)) == 0 && p == argv[3]){			rp->status = Status_BADARG;			return -1;		}		/*FALLTHROUGH*/	case 3:		if((transport = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){			rp->status = Status_BADARG;			return -1;		}		if((source = strtoul(argv[1], &p, 0)) == 0 && p == argv[1]){			rp->status = Status_BADARG;			return -1;		}		if((destination = strtoul(argv[2], &p, 0)) == 0 && p == argv[2]){			rp->status = Status_BADARG;			return -1;		}		break;	}	return SRmmove(rp, transport, source, destination, invert);}static longcmdestatus(ScsiReq *rp, int argc, char *argv[]){	uchar *list, *lp, type;	long d, i, n, nbytes, status;	char *p;	type = 0;	nbytes = 4096;	switch(argc){	default:		rp->status = Status_BADARG;		return -1;	case 2:		if((nbytes = strtoul(argv[1], &p, 0)) == 0 && p == argv[1]){			rp->status = Status_BADARG;			return -1;		}		/*FALLTHROUGH*/	case 1:		if((type = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){			rp->status = Status_BADARG;			return -1;		}		break;	case 0:		break;	}	list = malloc(nbytes);	if(list == 0){		rp->status = STnomem;		return -1;	}	status = SRestatus(rp, type, list, nbytes);	if(status == -1){		free(list);		return -1;	}	lp = list;	nbytes = ((lp[5]<<16)|(lp[6]<<8)|lp[7])-8;	Bprint(&bout, " Header\n   ");	for(i = 0; i < 8; i++){				/* header */		Bprint(&bout, " %2.2uX", *lp);		lp++;	}	Bputc(&bout, '\n');	while(nbytes > 0){				/* pages */		i = ((lp[5]<<16)|(lp[6]<<8)|lp[7]);		nbytes -= i+8;		Bprint(&bout, " Type");		for(n = 0; n < 8; n++)			/* header */			Bprint(&bout, " %2.2uX", lp[n]);		Bprint(&bout, "\n   ");		d = (lp[2]<<8)|lp[3];		lp += 8;		for(n = 0; n < i; n++){			if(n && (n % d) == 0)				Bprint(&bout, "\n   ");			Bprint(&bout, " %2.2uX", *lp);			lp++;		}		if(n && (n % d))			Bputc(&bout, '\n');	}	free(list);	return status;}static longcmdhelp(ScsiReq *rp, int argc, char *argv[]){	ScsiCmd *cp;	char *p;	USED(rp);	if(argc)		p = argv[0];	else		p = 0;	for(cp = scsicmd; cp->name; cp++){		if(p == 0 || strcmp(p, cp->name) == 0)			Bprint(&bout, "%s\n", cp->help);	}	return 0;}static int atatable[4] = {	'C', 'D', 'E', 'F',};static int scsitable[16] = {	'0', '1', '2', '3', '4', '5', '6', '7',	'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',};static int unittable[16] = {	'0', '1', '2', '3', '4', '5', '6', '7',	'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',};static longcmdprobe(ScsiReq *rp, int argc, char *argv[]){	char buf[32];	ScsiReq scsireq;	char *ctlr, *unit;	USED(argc, argv);	rp->status = STok;	scsireq.flags = 0;	for(ctlr="CDEF0123456789abcdef"; *ctlr; ctlr++) {		/*		 * I can guess how many units you have.		 */		if(*ctlr >= 'C' && *ctlr <= 'F')			unit = "01";		else if((*ctlr >= '0' && *ctlr <= '9')		     || (*ctlr >= 'a' && *ctlr <= 'f'))			unit = "0123456789abcdef";		else			unit = "012345678";		for(; *unit; unit++){			sprint(buf, "/dev/sd%c%c", *ctlr, *unit);			if(SRopenraw(&scsireq, buf) == -1)				/*				return -1;				 */				continue;			SRreqsense(&scsireq);			switch(scsireq.status){			default:				break;			case STok:			case Status_SD:				Bprint(&bout, "%s: ", buf);				cmdinquiry(&scsireq, 0, 0);				break;			}			SRclose(&scsireq);		}	}	return 0;}static longcmdclose(ScsiReq *rp, int argc, char *argv[]){	USED(argc, argv);	return SRclose(rp);}static longcmdopen(ScsiReq *rp, int argc, char *argv[]){	int raw;	long status;	raw = 0;	if(argc && strcmp("-r", argv[0]) == 0){		raw = 1;		argc--, argv++;	}	if(argc != 1){		rp->status = Status_BADARG;		return -1;	}	if(raw == 0){		if((status = SRopen(rp, argv[0])) != -1 && verbose)			Bprint(&bout, "%sblock size: %ld\n",				rp->flags&Fbfixed? "fixed ": "", rp->lbsize);	}	else {		status = SRopenraw(rp, argv[0]);		rp->lbsize = 512;	}	return status;}static ScsiCmd scsicmd[] = {	{ "ready",	cmdready,	1,		/*[0x00]*/	  "ready",	},	{ "rewind",	cmdrewind,	1,		/*[0x01]*/	  "rewind",	},	{ "rezero",	cmdrewind,	1,		/*[0x01]*/	  "rezero",	},	{ "reqsense",	cmdreqsense,	1,		/*[0x03]*/	  "reqsense",	},	{ "format",	cmdformat,	0,		/*[0x04]*/	  "format",	},	{ "rblimits",	cmdrblimits,	1,		/*[0x05]*/	  "rblimits",	},	{ "read",	cmdread,	1,		/*[0x08]*/	  "read [|]file [nbytes]",	},	{ "write",	cmdwrite,	1,		/*[0x0A]*/	  "write [|]file [nbytes]",	},	{ "seek",	cmdseek,	1,		/*[0x0B]*/	  "seek offset [whence]",	},	{ "filemark",	cmdfilemark,	1,		/*[0x10]*/	  "filemark [howmany]",	},	{ "space",	cmdspace,	1,		/*[0x11]*/	  "space [-f] [-b] [[--] howmany]",	},	{ "inquiry",	cmdinquiry,	1,		/*[0x12]*/	  "inquiry",	},	{ "modeselect6",cmdmodeselect6,	1,		/*[0x15] */	  "modeselect6 bytes...",	},	{ "modeselect",	cmdmodeselect10, 1,		/*[0x55] */	  "modeselect bytes...",	},	{ "modesense6",	cmdmodesense6,	1,		/*[0x1A]*/	  "modesense6 [page [nbytes]]",	},	{ "modesense",	cmdmodesense10, 1,		/*[0x5A]*/	  "modesense [page [nbytes]]",	},	{ "start",	cmdstart,	1,		/*[0x1B]*/	  "start [code]",	},	{ "stop",	cmdstop,	1,		/*[0x1B]*/	  "stop",	},	{ "eject",	cmdeject,	1,		/*[0x1B]*/	  "eject",	},	{ "ingest",	cmdingest,	1,		/*[0x1B]*/	  "ingest",	},	{ "capacity",	cmdcapacity,	1,		/*[0x25]*/	  "capacity",	},	{ "blank",	cmdblank,	1,		/*[0xA1]*/	  "blank [track/LBA [type]]",	},//	{ "synccache",	cmdsynccache,	1,		/*[0x35]*///	  "synccache",//	},	{ "rtoc",	cmdrtoc,	1,		/*[0x43]*/	  "rtoc [track/session-number [format]]",	},	{ "rdiscinfo",	cmdrdiscinfo,	1,		/*[0x51]*/	  "rdiscinfo",	},	{ "rtrackinfo",	cmdrtrackinfo,	1,		/*[0x52]*/	  "rtrackinfo [track]",	},	{ "cdpause",	cmdcdpause,	1,		/*[0x4B]*/	  "cdpause",	},	{ "cdresume",	cmdcdresume,	1,		/*[0x4B]*/	  "cdresume",	},	{ "cdstop",	cmdcdstop,	1,		/*[0x4E]*/	  "cdstop",	},	{ "cdplay",	cmdcdplay,	1,		/*[0xA5]*/	  "cdplay [track-number] or [-r [LBA [length]]]",	},	{ "cdload",	cmdcdload,	1,		/*[0xA6*/	  "cdload [slot]",	},	{ "cdunload",	cmdcdunload,	1,		/*[0xA6]*/	  "cdunload [slot]",	},	{ "cdstatus",	cmdcdstatus,	1,		/*[0xBD]*/	  "cdstatus",	},//	{ "getconf",	cmdgetconf,	1,		/*[0x46]*///	  "getconf",//	},//	{ "fwaddr",	cmdfwaddr,	1,		/*[0xE2]*///	  "fwaddr [track [mode [npa]]]",//	},//	{ "treserve",	cmdtreserve,	1,		/*[0xE4]*///	  "treserve nbytes",//	},//	{ "trackinfo",	cmdtrackinfo,	1,		/*[0xE5]*///	  "trackinfo [track]",//	},//	{ "wtrack",	cmdwtrack,	1,		/*[0xE6]*///	  "wtrack [|]file [nbytes [track [mode]]]",//	},//	{ "load",	cmdload,	1,		/*[0xE7]*///	  "load",//	},//	{ "unload",	cmdunload,	1,		/*[0xE7]*///	  "unload",//	},//	{ "fixation",	cmdfixation,	1,		/*[0xE9]*///	  "fixation [toc-type]",//	},	{ "einit",	cmdeinit,	1,		/*[0x07]*/	  "einit",	},	{ "estatus",	cmdestatus,	1,		/*[0xB8]*/	  "estatus",	},	{ "mmove",	cmdmmove,	1,		/*[0xA5]*/	  "mmove transport source destination [invert]",	},	{ "help",	cmdhelp,	0,	  "help",	},	{ "probe",	cmdprobe,	0,	  "probe",	},	{ "close",	cmdclose,	1,	  "close",	},	{ "open",	cmdopen,	0,	  "open [-r] sddev",	},	{ 0, 0 },};#define	SEP(c)	(((c)==' ')||((c)=='\t')||((c)=='\n'))static char *tokenise(char *s, char **start, char **end){	char *to;	Rune r;	int n;	while(*s && SEP(*s))				/* skip leading white space */		s++;	to = *start = s;	while(*s){		n = chartorune(&r, s);		if(SEP(r)){			if(to != *start)		/* we have data */				break;			s += n;				/* null string - keep looking */			while(*s && SEP(*s))				s++;			to = *start = s;		}		else if(r == '\''){			s += n;				/* skip leading quote */			while(*s){				n = chartorune(&r, s);				if(r == '\''){					if(s[1] != '\'')						break;					s++;		/* embedded quote */				}				while (n--)					*to++ = *s++;			}			if(!*s)				/* no trailing quote */				break;			s++;				/* skip trailing quote */		}		else  {			while(n--)				*to++ = *s++;		}	}	*end = to;	return s;}static intparse(char *s, char *fields[], int nfields){	int c, argc;	char *start, *end;	argc = 0;	c = *s;	while(c){		s = tokenise(s, &start, &end);		c = *s++;		if(*start == 0)			break;		if(argc >= nfields-1)			return -1;		*end = 0;		fields[argc++] = start;	}	fields[argc] = 0;	return argc;}static voidusage(void){	fprint(2, "usage: %s [-6eq] [-m maxiosize] [[-r] /dev/sdXX]\n", argv0);	exits("usage");}static struct {	int	status;	char*	description;} description[] = {	STnomem,	"buffer allocation failed",	STtimeout,	"bus timeout",	STharderr,	"controller error of some kind",	STok,		"good",	STcheck,	"check condition",	STcondmet,	"condition met/good",	STbusy,		"busy ",	STintok,	"intermediate/good",	STintcondmet,	"intermediate/condition met/good",	STresconf,	"reservation conflict",	STterminated,	"command terminated",	STqfull,	"queue full",	Status_SD,	"sense-data available",	Status_SW,	"internal software error",	Status_BADARG,	"bad argument to request",	0, 0,};voidmain(int argc, char *argv[]){	ScsiReq target;	char *ap, *av[256];	int ac, i, raw = 0;	ScsiCmd *cp;	long status;	ARGBEGIN {	case 'e':		exabyte = 1;		/* fallthrough */	case '6':		force6bytecmds = 1;		break;	case 'm':		ap = ARGF();		if(ap == nil)			usage();		maxiosize = atol(ap);		if(maxiosize < 512 || maxiosize > MaxIOsize)			sysfatal("max-xfer < 512 or > %d", MaxIOsize);		break;	case 'r':			/* must be last option and not bundled */		raw++;		break;	case 'q':		verbose = 0;		break;	default:		usage();	} ARGEND	if(Binit(&bin, 0, OREAD) == Beof || Binit(&bout, 1, OWRITE) == Beof){		fprint(2, "%s: can't init bio: %r\n", argv0);		exits("Binit");	}	memset(&target, 0, sizeof(target));	if (raw) {			/* hack for -r */		++argc;		--argv;	}	if(argc && cmdopen(&target, argc, argv) == -1) {		fprint(2, "open failed\n");		usage();	}	Bflush(&bout);	while(ap = Brdline(&bin, '\n')){		ap[Blinelen(&bin)-1] = 0;		switch(ac = parse(ap, av, nelem(av))){		default:			for(cp = scsicmd; cp->name; cp++){				if(strcmp(cp->name, av[0]) == 0)					break;			}			if(cp->name == 0){				Bprint(&bout, "eh?\n");				break;			}			if((target.flags & Fopen) == 0 && cp->open){				Bprint(&bout, "no current target\n");				break;			}			if((status = (*cp->f)(&target, ac-1, &av[1])) != -1){				if(verbose)					Bprint(&bout, "ok %ld\n", status);				break;			}			for(i = 0; description[i].description; i++){				if(target.status != description[i].status)					continue;				if(target.status == Status_SD)					makesense(&target);				else					Bprint(&bout, "%s\n", description[i].description);				break;			}			break;		case -1:			Bprint(&bout, "eh?\n");			break;		case 0:			break;		}		Bflush(&bout);	}	exits(0);}

⌨️ 快捷键说明

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