Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "stdinc.h"
#include "dat.h"
#include "fns.h"

static int verbose, quiet;

void
usage(void)
{
        fprint(2, "usage: rdarena [-v] arenapart arena\n");
        threadexitsall(0);
}

static void
rdarena(Arena *arena)
{
        ZBlock *b;
        u64int a, e;
        u32int bs;

        if (!quiet) {
                fprint(2, "copying %s to standard output\n", arena->name);
                printarena(2, arena);
        }

        bs = MaxIoSize;
        if(bs < arena->blocksize)
                bs = arena->blocksize;

        b = alloczblock(bs, 0, arena->blocksize);
        e = arena->base + arena->size + arena->blocksize;
        for(a = arena->base - arena->blocksize; a + arena->blocksize <= e; a += bs){
                if(a + bs > e)
                        bs = arena->blocksize;
                if(readpart(arena->part, a, b->data, bs) < 0)
                        fprint(2, "can't copy %s, read at %lld failed: %r\n", arena->name, a);  
                if(write(1, b->data, bs) != bs)
                        sysfatal("can't copy %s, write at %lld failed: %r", arena->name, a);
        }

        freezblock(b);
}

void
threadmain(int argc, char *argv[])
{
        ArenaPart *ap;
        Part *part;
        char *file, *aname;
        int i;

        ventifmtinstall();
        statsinit();

        ARGBEGIN{
        case 'q':
                quiet++;
                break;
        case 'v':
                verbose++;
                break;
        default:
                usage();
                break;
        }ARGEND

        readonly = 1;

        if(argc != 2)
                usage();

        file = argv[0];
        aname = argv[1];

        part = initpart(file, OREAD|ODIRECT);
        if(part == nil)
                sysfatal("can't open partition %s: %r", file);

        ap = initarenapart(part);
        if(ap == nil)
                sysfatal("can't initialize arena partition in %s: %r", file);

        if(verbose)
                printarenapart(2, ap);

        initdcache(8 * MaxDiskBlock);

        for(i = 0; i < ap->narenas; i++){
                if(strcmp(ap->arenas[i]->name, aname) == 0){
                        rdarena(ap->arenas[i]);
                        threadexitsall(0);
                }
        }

        sysfatal("couldn't find arena %s", aname);
}