V10/cmd/backup.old/wormupd.c
#include <libc.h>
#include "worm.h"
#include "sym.h"
#include <fio.h>
#include "backup.h"
int nb = 0;
typedef struct
{
long b, t;
} tb;
tb *allblks;
long nallblk;
extern long numinodes;
char *timenow();
#define N 63
tb blks[N];
cmp(a, b)
tb *a, *b;
{
return(a->b - b->b);
}
main(argc, argv)
char **argv;
{
char *dev = "/dev/worm0", *e, *vol_id;
int c, i, j;
Superblock sb;
void blkfn();
extern char *optarg;
extern int optind;
extern long atol();
while((c = getopt(argc, argv, "f:")) != -1)
switch(c)
{
case 'f': dev = optarg; break;
case '?': usage();
}
if(optind != argc-1)
usage();
vol_id = argv[optind];
dev = mapdev(dev);
if((sb.fd = open(dev, 0)) < 0){
perror(dev);
exit(1);
}
fprint(2, "%s: reading inodes\n", timenow());
if(e = openinode(&sb, DO_INODE|SPIN_DOWN)){
fprint(2, "%s: %s\n", dev, e);
exit(1);
}
if(strcmp(vol_id, sb.vol_id)){
fprint(2, "wanted volid '%s'; got '%s'\n", vol_id, sb.vol_id);
exit(1);
}
if((allblks = (tb *)malloc(sizeof(tb)*(int)numinodes)) == 0){
fprint(2, "out of memory (%d)\n", numinodes);
exit(1);
}
nallblk = 0;
inodetraverse(blkfn);
fprint(2, "%s: sorting inodes\n", timenow());
qsort((char *)allblks, (int)nallblk, sizeof allblks[0], cmp);
fprint(2, "%s: reading blocks\n", timenow());
for(j = 0; j < nallblk;){
for(i = 0; (i < N) && (j < nallblk); i++){
blks[i] = allblks[j++];
if(blks[i].b >= blks[0].b+N){
block(sb.fd, i);
blks[0] = blks[i];
i = 0;
}
}
block(sb.fd, i);
}
fprint(2, "%ld blocks\n", nb);
fprint(2, "%s: done reading blocks\n", timenow());
exit(0);
}
usage()
{
fprint(2, "Usage: wormupd [-fdevice] vol_id\n");
exit(2);
}
block(fd, n)
{
register i;
register struct backfile *h;
long t;
int nr;
int zero = 0;
struct backfile buf[N];
nb++;
lseek(fd, blks[0].b*1024, 0);
i = 1024*(int)(blks[n-1].b-blks[0].b+1);
nr = read(fd, (char *)buf, i);
if(nr < 0){
perror("wormupd read");
fprint(2, "trying for %d blocks:", n);
for(i = 0; i < n; i++) fprint(2, " %ld", blks[i].b);
fprint(2, "\n");
return;
}
nr /= 1024;
for(i = 0; i < n; i++){
t = blks[i].b-blks[0].b;
if(t >= nr){
fprint(2, "read short(%ld) for block %ld\n", nr, blks[i].b);
continue;
}
h = &buf[t];
t = blks[i].t;
#ifdef USR1_USR2
{
register char *p;
p = strchr(h->oname, '/'); /* / */
if (p) p = strchr(p+1, '/'); /* /n/ */
if (p) p = strchr(p+1, '/'); /* /n/system/ */
if (p && (strncmp(p+1, "usr1", 4) == 0 || strncmp(p+1, "usr2", 4) == 0))
strcpy(p+4, p+5);
}
#endif /* USR1_USR2 */
Fprint(1, "%s%c%s%c%ld%c%d%c%ld%c%s%c%s%c%ld\n", h->oname, 0, h->bname,
0, h->sbuf.st_ctime, 0, h->sbuf.st_mode, 0, h->sbuf.st_size,
0, h->uname, 0, h->gname, 0, t);
if((h->sbuf.st_mode&S_IFMT) == S_IFDIR)
Fwrite(1, (char *)&zero, 4L); /* cop out for now */
}
}
void
blkfn(i)
Inode *i;
{
if(strchr(i->name.n, '/')){
allblks[nallblk].t = i->ctime;
allblks[nallblk].b = i->block;
nallblk++;
}
}
char *
timenow()
{
long tim;
char *tims;
time(&tim);
tims = ctime(&tim);
tims[19] = 0;
return(tims);
}