123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- #include "stdinc.h"
- #include "dat.h"
- #include "fns.h"
- #include <disk.h>
- typedef struct Label Label;
- struct Label {
- ulong ver;
- ulong trailer;
- ulong tape;
- ulong slot;
- };
- static void usage(void);
- static void verifyArena(void);
- static int writeBlock(uchar *buf);
- static int writeLabel(Label*);
- static int readBlock(uchar *buf);
- static int readLabel(Label*);
- static int writeMark(void);
- static int rewind(int);
- static int space(int);
- int tape;
- int slot;
- int pos;
- Scsi *dev;
- enum {
- LabelMagic = 0x4b5474d2,
- BlockSize = 16*1024,
- Version = 1,
- };
- void
- main(int argc, char *argv[])
- {
- char *p;
- int overwrite = 0;
- fmtregister('V', vtScoreFmt);
- fmtregister('R', vtErrFmt);
- vtAttach();
- statsInit();
- ARGBEGIN{
- default:
- usage();
- break;
- case 's':
- p = ARGF();
- if(p == nil)
- usage();
- slot = atoi(p);
- break;
- case 't':
- p = ARGF();
- if(p == nil)
- usage();
- tape = atoi(p);
- break;
- case 'o':
- overwrite++;
- break;
- case '
- }ARGEND
- readonly = 1;
- if(argc != 1)
- usage();
- dev = openscsi(argv[0]);
- if(dev == nil)
- fatal("could not open scsi device: %r");
- if(!initPos() && !rewind())
- fatal("could not rewind: %r");
- fprint(2, "pos = %d\n", pos);
- if(pos != 0) {
- if(!movetoSlot(slot)) {
- if(!rewind())
- fatal("could not rewind: %r");
- pos = 0;
- }
- }
- if(pos != slot && !movetoSlot(slot))
- fatal("could not seek to slot: %r");
- if(!overwrite) {
- if(readLabel(&lb))
- fatal("tape not empty: tape=%d", lb->tape);
- }
- memset(&lb, 0, sizeof(lb));
- lb.ver = Version;
- lb.tape = tape;
- lb.slot = slot;
-
- if(!writeLabel(&lb))
- fatal("could not write header: %r");
-
- if(!writeArena(score))
- fatal("could not write arena: %r");
-
- lb.trailer = 1;
- if(!writeLabel(&lb))
- fatal("could not write header: %r");
- if(!writeArena(score))
- fatal("could not write arena: %r");
-
- exits(0);
- }
- static void
- usage(void)
- {
- fprint(2, "usage: dumparena [-o] [-t tape] [-s slot] device\n");
- exits("usage");
- }
- static int
- initPos(void)
- {
- Label lb;
- int i;
- for(i=0; i<4; i++) {
- slot(-2);
- if(space(1))
- if(readLabel(&lb))
- if(lb->tape == tape && lb->trailer) {
- pos = lb->slot;
- return 1;
- }
- }
- return 0;
- }
- static void
- readBlock(uchar *buf, int n)
- {
- int nr, m;
- for(nr = 0; nr < n; nr += m){
- m = n - nr;
- m = read(0, &buf[nr], m);
- if(m <= 0)
- fatal("can't read arena from standard input: %r");
- }
- }
- static void
- verifyArena(void)
- {
- Arena arena;
- ArenaHead head;
- ZBlock *b;
- VtSha1 *s;
- u64int n, e;
- u32int bs;
- u8int score[VtScoreSize];
- memset(&arena, 0, sizeof arena);
- fprint(2, "verify arena from standard input\n");
- s = vtSha1Alloc();
- if(s == nil)
- fatal("can't initialize sha1 state");
- vtSha1Init(s);
- /*
- * read the little bit, which will included the header
- */
- bs = MaxIoSize;
- b = allocZBlock(bs, 0);
- readBlock(b->data, HeadSize);
- vtSha1Update(s, b->data, HeadSize);
- if(!unpackArenaHead(&head, b->data))
- fatal("corrupted arena header: %R");
- if(head.version != ArenaVersion)
- fatal("unknown arena version %d", head.version);
- /*
- * now we know how much to read
- * read everything but the last block, which is special
- */
- e = head.size - head.blockSize;
- for(n = HeadSize; n < e; n += bs){
- if(n + bs > e)
- bs = e - n;
- readBlock(b->data, bs);
- vtSha1Update(s, b->data, bs);
- }
- /*
- * read the last block update the sum.
- * the sum is calculated assuming the slot for the sum is zero.
- */
- bs = head.blockSize;
- readBlock(b->data, bs);
- vtSha1Update(s, b->data, bs - VtScoreSize);
- vtSha1Update(s, zeroScore, VtScoreSize);
- vtSha1Final(s, score);
- vtSha1Free(s);
- /*
- * validity check on the trailer
- */
- arena.blockSize = head.blockSize;
- if(!unpackArena(&arena, b->data))
- fatal("corrupted arena trailer: %R");
- scoreCp(arena.score, &b->data[arena.blockSize - VtScoreSize]);
- if(!nameEq(arena.name, head.name))
- fatal("arena header and trailer names clash: %s vs. %s\n", head.name, arena.name);
- if(arena.version != head.version)
- fatal("arena header and trailer versions clash: %d vs. %d\n", head.version, arena.version);
- arena.size = head.size - 2 * head.blockSize;
- /*
- * check for no checksum or the same
- */
- if(!scoreEq(score, arena.score)){
- if(!scoreEq(zeroScore, arena.score))
- fprint(2, "warning: mismatched checksums for arena=%s, found=%V calculated=%V",
- arena.name, arena.score, score);
- scoreCp(arena.score, score);
- }else
- fprint(2, "matched score\n");
- printArena(2, &arena);
- }
- static int
- writeBlock(uchar *buf)
- {
- uchar cmd[6];
- memset(cmd, 0, sizeof(cmd));
- cmd[0] = 0x0a;
- cmd[2] = BlockSize>>16;
- cmd[3] = BlockSize>>8;
- cmd[4] = BlockSize;
- if(scsi(dev, cmd, 6, buf, BlockSize, Swrite) < 0)
- return 0;
- return 1;
- }
- static int
- readBlock(uchar *buf)
- {
- uchar cmd[6];
- memset(cmd, 0, sizeof(cmd));
- cmd[0] = 0x08;
- cmd[2] = BlockSize>>16;
- cmd[3] = BlockSize>>8;
- cmd[4] = BlockSize;
- if(scsi(dev, cmd, 6, buf, BlockSize, Sread) < 0)
- return 0;
- return 1;
- }
- static int
- writeMark(void)
- {
- uchar cmd[6];
- memset(cmd, 0, sizeof(cmd));
- cmd[0] = 0x10;
- if(scsi(dev, cmd, 6, buf, BlockSize, Sread) < 0)
- return 0;
- return 1;
- }
- static int
- rewind(int n)
- {
- uchar cmd[6];
- if(n > 225)
- n = 255;
- memset(cmd, 0, sizeof(cmd));
- cmd[0] = 0x01;
- cmd[4] = n;
- if(scsi(dev, cmd, 6, buf, BlockSize, Sread) < 0)
- return 0;
- return 1;
- }
- static int
- space(int off)
- {
- uchar cmd[6];
- memset(cmd, 0, sizeof(cmd));
- cmd[0] = 0x11;
- cmd[1] = 0x01; /* file marks */
- cmd[2] = off>>16;
- cmd[3] = off>>8;
- cmd[4] = off;
-
- if(scsi(dev, cmd, 6, buf, BlockSize, Sread) < 0)
- return 0;
- return 1;
- }
- static int
- writeLabel(Label *lb)
- {
- uchar block[BlockSize];
-
- if(lb->ver != Version) {
- vtSerError("unknown header version");
- return 0;
- }
- memset(block, 0, blockSize);
- vtPutUint32(block+0, Magic);
- vtPutUint32(block+4, lb->ver);
- vtPutUint32(block+8, lb->trailer);
- vtPutUint32(block+12, lb->tape);
- vtPutUint32(block+16, lb->slot);
- if(!writeBlock(block))
- return 0;
- if(!writeMark(1))
- return 0;
- return 1;
- }
- static int
- readLabel(Label *lb)
- {
- uchar block[BlockSize];
- if(!readBlock(block))
- return 0;
- if(vtGetUint32(block+0) != Magic) {
- vtSetError("bad magic in header");
- return 0;
- }
- lb->ver = vtGetUint32(block+4);
- if(lb->ver != Version) {
- vtSerError("unknown header version");
- return 0;
- }
- lb->trailer = vtPutUint32(block+8);
- lb->tape = vtGetUint32(block+12);
- lb->slot = vtGetUint32(block+16);
- return 1;
- }
|