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

📄 scuzz.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include "scsireq.h"#define MIN(a, b)	((a) < (b) ? (a): (b))static char rwbuf[MaxIOsize];static int verbose = 1;Biobuf bin, bout;long maxiosize = MaxIOsize;int exabyte = 0;int force6bytecmds = 0;typedef struct {	char *name;	long (*f)(ScsiReq *, int, char *[]);	int open;	char *help;} ScsiCmd;static ScsiCmd scsicmd[];static vlongvlmin(vlong a, vlong b){	if (a < b)		return a;	else		return b;}static longcmdready(ScsiReq *rp, int argc, char *argv[]){	USED(argc, argv);	return SRready(rp);}static longcmdrewind(ScsiReq *rp, int argc, char *argv[]){	USED(argc, argv);	return SRrewind(rp);}static longcmdreqsense(ScsiReq *rp, int argc, char *argv[]){	long nbytes;	USED(argc, argv);	if((nbytes = SRreqsense(rp)) != -1)		makesense(rp);	return nbytes;}static longcmdformat(ScsiReq *rp, int argc, char *argv[]){	USED(argc, argv);	return SRformat(rp);}static longcmdrblimits(ScsiReq *rp, int argc, char *argv[]){	uchar l[6];	long n;	USED(argc, argv);	if((n = SRrblimits(rp, l)) == -1)		return -1;	Bprint(&bout, " %2.2uX %2.2uX %2.2uX %2.2uX %2.2uX %2.2uX\n",		l[0], l[1], l[2], l[3], l[4], l[5]);	return n;}static intmkfile(char *file, int omode, int *pid){	int fd[2];	if(*file != '|'){		*pid = -1;		if(omode == OWRITE)			return create(file, OWRITE, 0666);		else if(omode == OREAD)			return open(file, OREAD);		return -1;	}	file++;	if(*file == 0 || pipe(fd) == -1)		return -1;	if((*pid = fork()) == -1){		close(fd[0]);		close(fd[1]);		return -1;	}	if(*pid == 0){		switch(omode){		case OREAD:			dup(fd[0], 1);			break;		case OWRITE:			dup(fd[0], 0);			break;		}		close(fd[0]);		close(fd[1]);		execl("/bin/rc", "rc", "-c", file, nil);		exits("exec");	}	close(fd[0]);	return fd[1];}intwaitfor(int pid){	int msg;	Waitmsg *w;	while((w = wait()) != nil){		if(w->pid != pid){			free(w);			continue;		}		msg = (w->msg[0] != '\0');		free(w);		return msg;	}	return -1;}static longcmdread(ScsiReq *rp, int argc, char *argv[]){	long n, iosize, prevsize = 0;	vlong nbytes, total;	int fd, pid;	char *p;	iosize = maxiosize;	nbytes = ~0ULL >> 1;	switch(argc){	default:		rp->status = Status_BADARG;		return -1;	case 2:		nbytes = strtoll(argv[1], &p, 0);		if(nbytes == 0 && p == argv[1]){			rp->status = Status_BADARG;			return -1;		}		/*FALLTHROUGH*/	case 1:		if((fd = mkfile(argv[0], OWRITE, &pid)) == -1){			rp->status = Status_BADARG;			return -1;		}		break;	}	print("bsize=%lud\n", rp->lbsize);	total = 0;	while(nbytes){		n = vlmin(nbytes, iosize);		if((n = SRread(rp, rwbuf, n)) == -1){			if(total == 0)				total = -1;			break;		}		if (n == 0)			break;		if (prevsize != n) {			print("tape block size=%ld\n", n);			prevsize = n;		}		if(write(fd, rwbuf, n) != n){			if(total == 0)				total = -1;			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 longcmdwrite(ScsiReq *rp, int argc, char *argv[]){	long n, prevsize = 0;	vlong nbytes, total;	int fd, pid;	char *p;	nbytes = ~0ULL >> 1;	switch(argc){	default:		rp->status = Status_BADARG;		return -1;	case 2:		nbytes = strtoll(argv[1], &p, 0);		if(nbytes == 0 && p == argv[1]){			rp->status = Status_BADARG;			return -1;		}		/*FALLTHROUGH*/	case 1:		if((fd = mkfile(argv[0], OREAD, &pid)) == -1){			rp->status = Status_BADARG;			return -1;		}		break;	}	total = 0;	while(nbytes){		n = vlmin(nbytes, maxiosize);		if((n = read(fd, rwbuf, n)) == -1){			if(total == 0)				total = -1;			break;		}		if (n == 0)			break;		if (prevsize != n) {			print("tape block size=%ld\n", n);			prevsize = n;		}		if(SRwrite(rp, rwbuf, n) != n){			if(total == 0)				total = -1;			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 longcmdseek(ScsiReq *rp, int argc, char *argv[]){	char *p;	long offset;	int type;	type = 0;	switch(argc){	default:		rp->status = Status_BADARG;		return -1;	case 2:		if((type = strtol(argv[1], &p, 0)) == 0 && p == argv[1]){			rp->status = Status_BADARG;			return -1;		}		/*FALLTHROUGH*/	case 1:		if((offset = strtol(argv[0], &p, 0)) == 0 && p == argv[0]){			rp->status = Status_BADARG;			return -1;		}		break;	}	return SRseek(rp, offset, type);}static longcmdfilemark(ScsiReq *rp, int argc, char *argv[]){	char *p;	ulong howmany;	howmany = 1;	if(argc && (howmany = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){		rp->status = Status_BADARG;		return -1;	}	return SRfilemark(rp, howmany);}static longcmdspace(ScsiReq *rp, int argc, char *argv[]){	uchar code;	long howmany;	char option, *p;	code = 0x00;	howmany = 1;	while(argc && (*argv)[0] == '-'){		while(option = *++argv[0]){			switch(option){			case '-':				break;			case 'b':				code = 0x00;				break;			case 'f':				code = 0x01;				break;			default:				rp->status = Status_BADARG;				return -1;			}			break;		}		argc--; argv++;		if(option == '-')			break;	}	if(argc && ((howmany = strtol(argv[0], &p, 0)) == 0 && p == argv[0])){		rp->status = Status_BADARG;		return -1;	}	return SRspace(rp, code, howmany);}static longcmdinquiry(ScsiReq *rp, int argc, char *argv[]){	long status;	int i, n;	uchar *p;	USED(argc, argv);	if((status = SRinquiry(rp)) != -1){		n = rp->inquiry[4]+4;		for(i = 0; i < MIN(8, n); i++)			Bprint(&bout, " %2.2uX", rp->inquiry[i]);		p = &rp->inquiry[8];		n = MIN(n, sizeof(rp->inquiry)-8);		while(n && (*p == ' ' || *p == '\t' || *p == '\n')){			n--;			p++;		}		Bprint(&bout, "\t%.*s\n", n, (char*)p);	}	return status;}static longcmdmodeselect6(ScsiReq *rp, int argc, char *argv[]){	uchar list[MaxDirData];	long nbytes, ul;	char *p;	memset(list, 0, sizeof(list));	for(nbytes = 0; argc; argc--, argv++, nbytes++){		if((ul = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){			rp->status = Status_BADARG;			return -1;		}		list[nbytes] = ul;	}	if(!(rp->flags & Finqok) && SRinquiry(rp) == -1)		Bprint(&bout, "warning: couldn't determine whether SCSI-1/SCSI-2 mode");	return SRmodeselect6(rp, list, nbytes);}static longcmdmodeselect10(ScsiReq *rp, int argc, char *argv[]){	uchar list[MaxDirData];	long nbytes, ul;	char *p;	memset(list, 0, sizeof(list));	for(nbytes = 0; argc; argc--, argv++, nbytes++){		if((ul = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){			rp->status = Status_BADARG;			return -1;		}		list[nbytes] = ul;	}	if(!(rp->flags & Finqok) && SRinquiry(rp) == -1)		Bprint(&bout, "warning: couldn't determine whether SCSI-1/SCSI-2 mode");	return SRmodeselect10(rp, list, nbytes);}static longcmdmodesense6(ScsiReq *rp, int argc, char *argv[]){	uchar list[MaxDirData], *lp, page;	long i, n, nbytes, status;	char *p;	nbytes = sizeof(list);	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((page = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){			rp->status = Status_BADARG;			return -1;		}		break;	case 0:		page = 0x3F;		break;	}	if((status = SRmodesense6(rp, page, list, nbytes)) == -1)		return -1;	lp = list;	nbytes = list[0];	Bprint(&bout, " Header\n   ");	for(i = 0; i < 4; i++){				/* header */		Bprint(&bout, " %2.2uX", *lp);		lp++;	}	Bputc(&bout, '\n');	if(list[3]){					/* block descriptors */		for(n = 0; n < list[3]/8; n++){			Bprint(&bout, " Block %ld\n   ", n);			for(i = 0; i < 8; i++)				Bprint(&bout, " %2.2uX", lp[i]);			Bprint(&bout, "    (density %2.2uX", lp[0]);			Bprint(&bout, " blocks %d", (lp[1]<<16)|(lp[2]<<8)|lp[3]);			Bprint(&bout, " length %d)", (lp[5]<<16)|(lp[6]<<8)|lp[7]);			lp += 8;			nbytes -= 8;			Bputc(&bout, '\n');		}	}	while(nbytes > 0){				/* pages */		i = *(lp+1);		nbytes -= i+2;		Bprint(&bout, " Page %2.2uX %d\n   ", *lp & 0x3F, *(lp+1));		lp += 2;		for(n = 0; n < i; n++){			if(n && ((n & 0x0F) == 0))				Bprint(&bout, "\n   ");			Bprint(&bout, " %2.2uX", *lp);			lp++;		}		if(n && (n & 0x0F))			Bputc(&bout, '\n');	}	return status;}static longcmdmodesense10(ScsiReq *rp, int argc, char *argv[]){	uchar *list, *lp, page;	long blen, i, n, nbytes, status;	char *p;	nbytes = MaxDirData;	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((page = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){			rp->status = Status_BADARG;			return -1;		}		break;	case 0:		page = 0x3F;		break;	}	list = malloc(nbytes);	if(list == 0){		rp->status = STnomem;		return -1;	}	if((status = SRmodesense10(rp, page, list, nbytes)) == -1)		return -1;	lp = list;	nbytes = ((list[0]<<8)|list[1]);	Bprint(&bout, " Header\n   ");	for(i = 0; i < 8; i++){				/* header */		Bprint(&bout, " %2.2uX", *lp);		lp++;	}	Bputc(&bout, '\n');	blen = (list[6]<<8)|list[7];	if(blen){					/* block descriptors */		for(n = 0; n < blen/8; n++){			Bprint(&bout, " Block %ld\n   ", n);			for(i = 0; i < 8; i++)				Bprint(&bout, " %2.2uX", lp[i]);			Bprint(&bout, "    (density %2.2uX", lp[0]);			Bprint(&bout, " blocks %d", (lp[1]<<16)|(lp[2]<<8)|lp[3]);			Bprint(&bout, " length %d)", (lp[5]<<16)|(lp[6]<<8)|lp[7]);			lp += 8;			nbytes -= 8;			Bputc(&bout, '\n');		}	}	/*	 * Special for ATA drives, page 0 is the drive info in 16-bit	 * chunks, little-endian, 256 in total. No decoding for now.	 */	if(page == 0){		for(n = 0; n < nbytes; n += 2){			if(n && ((n & 0x1F) == 0))				Bprint(&bout, "\n");			Bprint(&bout, " %4.4uX", (*(lp+1)<<8)|*lp);			lp += 2;		}		Bputc(&bout, '\n');	}	else while(nbytes > 0){				/* pages */		i = *(lp+1);		nbytes -= i+2;		Bprint(&bout, " Page %2.2uX %d\n   ", *lp & 0x3F, *(lp+1));		lp += 2;		for(n = 0; n < i; n++){			if(n && ((n & 0x0F) == 0))				Bprint(&bout, "\n   ");			Bprint(&bout, " %2.2uX", *lp);			lp++;		}		if(n && (n & 0x0F))			Bputc(&bout, '\n');	}	free(list);	return status;}static longstart(ScsiReq *rp, int argc, char *argv[], uchar code){	char *p;	if(argc && (code = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){		rp->status = Status_BADARG;		return -1;	}	return SRstart(rp, code);}static longcmdstart(ScsiReq *rp, int argc, char *argv[]){	return start(rp, argc, argv, 1);}static longcmdstop(ScsiReq *rp, int argc, char *argv[]){	return start(rp, argc, argv, 0);}static longcmdeject(ScsiReq *rp, int argc, char *argv[]){	return start(rp, argc, argv, 2);}static longcmdingest(ScsiReq *rp, int argc, char *argv[]){	return start(rp, argc, argv, 3);}static longcmdcapacity(ScsiReq *rp, int argc, char *argv[]){	uchar d[8];	long n;	USED(argc, argv);	if((n = SRrcapacity(rp, d)) == -1)		return -1;	Bprint(&bout, " %ud %ud\n",		d[0]<<24|d[1]<<16|d[2]<<8|d[3],		d[4]<<24|d[5]<<16|d[6]<<8|d[7]);	return n;}static longcmdblank(ScsiReq *rp, int argc, char *argv[]){	uchar type, track;	char *sp;	type = track = 0;	switch(argc){	default:		rp->status = Status_BADARG;		return -1;	case 2:		if((type = strtoul(argv[1], &sp, 0)) == 0 && sp == argv[1]){			rp->status = Status_BADARG;			return -1;		}

⌨️ 快捷键说明

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