📄 scuzz.c
字号:
#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 + -