[net.sources] fscopy: raw filesystem copy for 4.2BSD

dmmartindale@watcgl.UUCP (Dave Martindale) (01/06/85)

This is a simple "front-end" for the double-buffered disk copy program
called "dbcopy" that I just posted.  Dbcopy understands only about copying
so many bytes using buffers of a certain size.  Fscopy looks at the superblock
of the "input" filesystem to calculate the size of one track of the disk
and the total size of the filesystem, and then calls dbcopy with these
numbers to do the actual work.

We use this run from the cron every night to make a backup copy of the
root filesystem to a spare disk partition so we have something to boot
from if the main root gets trashed.

	Dave Martindale

------------------------------------------------------------------------
/*
 * fscopy input output
 * 
 * Look at the superblock to see how much needs to be copied,
 * then call dbcopy to do the real work.
 */

#include <stdio.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/fs.h>
#include <errno.h>

struct	fs	sblock;

main(argc, argv)
char **argv;
{
	int input;
	off_t nbytes, n;
	off_t bufsize;

	char cmd[100];

	--argc;
	++argv;
	if (argc != 2) {
		fprintf(stderr, "Usage: fscopy input output\n");
		exit(1);
	}
	check(argv[0]);
	check(argv[1]);
	if ((input = open(argv[0], 0))<0) {
		fprintf(stderr, "fscopy: can't open %s\n", argv[0]);
		exit(1);
	}
	lseek(input, (long) SBLOCK * DEV_BSIZE, 0);
	if (read(input, (char *)&sblock, sizeof sblock) != sizeof sblock) {
		fprintf(stderr, "fscopy: ");
		perror("super block");
		exit(1);
	}
	close(input);
	nbytes = sblock.fs_size*sblock.fs_fsize;
	bufsize = sblock.fs_nsect*DEV_BSIZE;	/* one track */
	printf("%ld blocks of %ld bytes\n", nbytes/bufsize, bufsize);
	if ((n = nbytes%bufsize) != 0)
		printf("1 block of %ld bytes\n", n);
	sprintf(cmd, "/etc/dbcopy -b %ld -l %ld '%s' '%s'",
		bufsize, nbytes, argv[0], argv[1]);
	printf("fscopy: %s\n", cmd);
	exit(system(cmd));
}

check(s)
char *s;
{
	struct	stat	statb;

	if (stat(s, &statb)<0) {
		fprintf(stderr, "fscopy: can't stat %s\n", s);
		exit(1);
	}
	if ((statb.st_mode&S_IFMT)!=S_IFCHR) {
		fprintf(stderr, "fscopy: %s is not a raw device\n", s);
		exit(1);
	}
}