V10/cmd/chuck/main.c
#include "fs.h"
#include "sys/ttyio.h"
#include "ctype.h"
char *options = "ivwI:B:b:M:";
int bsize = 4096;
main(argc, argv)
char **argv;
{ int c;
extern char *optarg;
extern int optind;
timer(0);
while((c = getopt(argc, argv, options)) != -1)
switch(c) {
default:
flags[c]++;
continue;
case '?':
fatal("unknown arg %c (%s)\n", c, options);
case 'b':
bsize = atoi(optarg);
continue;
case 'M':
flags[c]++;
pblk = atoi(optarg);
continue;
case 'I':
for(optind--; optind < argc && isdigit(argv[optind][0]); optind++)
addi(atoi(argv[optind]));
continue;
case 'B':
for(optind--; optind < argc && isdigit(argv[optind][0]); optind++)
addb(atoi(argv[optind]));
continue;
}
if(optind >= argc)
fatal("no file?\n");
if(optind < argc-1)
fatal("too many files %s\n", argv[optind]);
if(flags['i'])
flags['w']++;
file = argv[optind];
if(flags['M'])
mknew();
doit(file);
}
doit(file)
{
fd = -1;
if(flags['w']) {
fd = open(file, 2);
if(fd < 0) {
pmesg("no write\n");
flags['w'] = 0;
}
}
if(fd < 0)
fd = open(file, 0);
if(fd < 0) {
perror(file);
fatal("can't open file system\n");
}
firstsuper(); /* read it, sanity check, allocate imap, bmap */
timer("read");
scaninodes(); /* read all the inode blocks */
timer("inodes");
if(blkcnts[Ind3])
indblocks(Ind3, Ind2);
if(blkcnts[Ind2]) /* cope with indirect blocks */
indblocks(Ind2, Ind);
if(blkcnts[Ind])
indblocks(Ind, Data);
timer("indir");
dirblocks(); /* read all the directory blocks */
timer("dirs");
dochecks(); /* tree structure etc */
checksuper(); /* is the super block ok? */
repairs();
report(); /* say what happened somewhere */
timer("done");
if (exitcode)
pmesg("exit %d\n", exitcode);
exit(exitcode);
}
pmesg(s, a, b, c, d, e, f, g, h, i)
char *s;
{ static char *p;
if(!p)
p = mbuf;
if(p == mbuf && file) {
sprintf(mbuf, "%s: ", file);
p = mbuf + strlen(mbuf);
}
sprintf(p, s, a, b, c, d, e, f, g, h, i);
write(2, mbuf, strlen(mbuf));
}
fatal(s, a, b, c, d, e, f, g, h, i)
char *s;
{
pmesg(s, a, b, c, d, e, f, g, h, i);
exit(1);
}
bread(loc, buf, cnt)
char *buf;
{ int i;
i = bsize *cnt;
if(lseek(fd, bsize*loc, 0) < 0 || read(fd, buf, i) != i)
return(-1);
return(0);
}
bwrite(loc, buf, cnt)
char *buf;
{ int i = bsize * cnt;
if(lseek(fd, bsize*loc, 0) < 0 || write(fd, buf, i) != i)
return(-1);
return(0);
}
char *
itype(n)
{
switch(n) {
default:
sprintf(xbuf, "?%d?", n);
return(xbuf);
case Unalloc: return("Unalloc");
case Dir: return("Dir");
case Lnk: return("Lnk");
case Chr: return("Chr");
case Blk: return("Blk");
case Reg: return("Reg");
case Weird: return("Weird");
}
}
char *
btype(n)
{
switch(n) {
default:
sprintf(xbuf, "?%d?", n);
return(xbuf);
case Unk: return("Unk");
case Sblock: return("Sblock");
case Inode: return("Inode");
case Free: return("Free");
case Data: return("Data");
case Ind: return("Ind");
case Ind2: return("Ind2");
case Ind3: return("Ind3");
case First: return("First");
case Other: return("Otherdir");
case Bits: return("Bits");
case Ioerr: return("Ioerr");
case Boot: return("Boot");
case Bad: return("Bad");
}
}
addi(n)
{
if(!ilen)
iarg = (int *) malloc((ilen = 10) * sizeof(int));
else if(iptr >= ilen) {
ilen *= 3;
iarg = (int *) realloc((char *)iarg, ilen * sizeof(int));
}
if(!iarg) {
pmesg("can't alloc iarg %d\n", n);
return;
}
iarg[iptr++] = n;
}
addb(n)
{
if(!blen)
barg = (int *) malloc((blen = 10) * sizeof(int));
else if(bptr >= blen) {
blen *= 3;
barg = (int *) realloc((char *)barg, blen * sizeof(int));
}
if(!barg) {
pmesg("can't alloc barg %d\n", n);
return;
}
barg[bptr++] = n;
}
/* how do we flush stdin? */
qry(s)
char *s;
{ int n;
pmesg(s);
ioctl(0, TIOCFLUSH, 0);
n = read(0, mbuf+40, 128-40);
if(n <= 0)
return(n);
return(mbuf[40]);
}
#include "sys/times.h"
long ot, nt;
struct tms otm, ntm;
timer(s)
char *s;
{
if(ot == nt && nt == 0 || !flags['v']) {
(void) time(&ot);
times(&otm);
return;
}
(void) time(&nt);
times(&ntm);
pmesg("(time)%s %d %.3fu %.3fs\n", s, nt-ot,
(ntm.tms_utime-otm.tms_utime)/60.,
(ntm.tms_stime-otm.tms_stime)/60.);
ot=nt;
otm = ntm;
}