xref: /csrg-svn/usr.bin/tcopy/tcopy.c (revision 30873)
124973Sbloom /*
230870Skarels  * Copyright (c) 1985, 1987 Regents of the University of California.
324973Sbloom  * All rights reserved.  The Berkeley software License Agreement
424973Sbloom  * specifies the terms and conditions for redistribution.
524973Sbloom  */
624973Sbloom 
724973Sbloom #ifndef lint
824973Sbloom char copyright[] =
930870Skarels "@(#) Copyright (c) 1985, 1987 Regents of the University of California.\n\
1024973Sbloom  All rights reserved.\n";
1124973Sbloom #endif not lint
1224973Sbloom 
1324973Sbloom #ifndef lint
14*30873Skarels static char sccsid[] = "@(#)tcopy.c	5.5 (Berkeley) 04/09/87";
1524973Sbloom #endif not lint
1624973Sbloom 
1724973Sbloom #include <stdio.h>
1825590Sbloom #include <signal.h>
1924973Sbloom #include <sys/file.h>
2024973Sbloom #include <sys/types.h>
2124973Sbloom #include <sys/ioctl.h>
2224973Sbloom #include <sys/mtio.h>
23*30873Skarels #include <sys/errno.h>
2424973Sbloom 
2530870Skarels #define MAXREC	(64 * 1024)
2630870Skarels #define NOCOUNT	(-2)
2730870Skarels #undef DEFTAPE
2830870Skarels #define	DEFTAPE	"/dev/rmt0"
2924973Sbloom 
3030870Skarels char	*buff;
3130870Skarels char	*inf = DEFTAPE;
3230870Skarels int	maxblk = MAXREC;
3330870Skarels int	filen;
3430870Skarels long	record, lastrec;
3530870Skarels int	intr();
3630870Skarels long	itol();
3730870Skarels char	*malloc();
3830870Skarels long	size, tsize;
3930870Skarels int	nfile;
4030870Skarels int	lastread;
4130870Skarels int	copy;
42*30873Skarels extern	int errno;
4324973Sbloom 
4424973Sbloom main(argc, argv)
4524973Sbloom char **argv;
4624973Sbloom {
4730870Skarels 	register nread, nw, inp, outp;
4824973Sbloom 	struct mtop op;
4930870Skarels 	int needeof = 0, guesslen = 1;
5024973Sbloom 
5130870Skarels 	while (argc > 1 && *argv[1] == '-') {
5230870Skarels 		switch (*++argv[1]) {
5330870Skarels 		case 's':
5430870Skarels 			if (argc < 3)
5530870Skarels 				goto usage;
5630870Skarels 			maxblk = atoi(argv[2]);
5730870Skarels 			if (maxblk <= 0) {
5830870Skarels 				fprintf(stderr, "illegal block size\n");
5930870Skarels 				goto usage;
6030870Skarels 			}
6130870Skarels 			argc--;
6230870Skarels 			argv++;
6330870Skarels 			guesslen = 0;
6430870Skarels 			break;
6530870Skarels 		}
6630870Skarels 		argc--;
6730870Skarels 		argv++;
6830870Skarels 	}
6930870Skarels 	if (argc < 1 || argc > 3) {
7030870Skarels usage:
7130870Skarels 		fprintf(stderr, "Usage: tcopy [-s maxblk] src [dest]\n");
7224973Sbloom 		exit(1);
7324973Sbloom 	}
7430870Skarels 	if (argc > 1)
7530870Skarels 		inf = argv[1];
7630870Skarels 	if ((inp = open(inf, O_RDONLY, 0)) < 0) {
7730870Skarels 		perror(inf);
7830870Skarels 		exit(1);
7930870Skarels 	}
8025590Sbloom 	if (argc == 3) {
8125590Sbloom 		copy = 1;
8230870Skarels 		if ((outp = open(argv[2], O_WRONLY, 0666)) < 0) {
8330870Skarels 			perror(argv[2]);
8425590Sbloom 			exit(3);
8525590Sbloom 		}
8624973Sbloom 	}
8725590Sbloom 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
8830870Skarels 		(void) signal(SIGINT, intr);
8930870Skarels 	buff = malloc(maxblk);
9030870Skarels 	if (buff == NULL) {
9130870Skarels 		fprintf("tcopy: no memory\n");
9230870Skarels 		exit(11);
9330870Skarels 	}
9430870Skarels 	lastread = NOCOUNT;
9524973Sbloom 	for (;;) {
9630870Skarels 		nread = read(inp, buff, maxblk);
9730870Skarels 		if (nread == -1) {
98*30873Skarels 			if (errno == EINVAL && guesslen &&
99*30873Skarels 			    maxblk > MAXREC / 2) {
10030870Skarels 				maxblk -= 1024;
10130870Skarels 				continue;
10230870Skarels 			}
10330870Skarels 			fprintf(stderr, "read error, file %d, record %d: ",
10430870Skarels 			    filen, record);
10530870Skarels 			perror("");
10630870Skarels 		} else if (nread != lastread) {
10730870Skarels 			if (lastread != 0 && lastread != NOCOUNT) {
10830870Skarels 				if (lastrec == 0 && nread == 0)
10930870Skarels 					printf("%d records\n", record);
11030870Skarels 				else if (record - lastrec > 1)
11130870Skarels 					printf("records %ld to %ld\n",
11230870Skarels 					    lastrec, record);
11330870Skarels 				else
11430870Skarels 					printf("record %ld\n", lastrec);
11530870Skarels 			}
11630870Skarels 			if (nread != 0)
11730870Skarels 				printf("file %d: block size %d: ",
11830870Skarels 				    filen, nread);
11930870Skarels 			fflush(stdout);
12030870Skarels 			lastrec = record;
12124973Sbloom 		}
12230870Skarels 		guesslen = 0;
12330870Skarels 		if (nread > 0) {
12430870Skarels 			if (copy) {
12530870Skarels 				if (needeof) {
12630870Skarels 				    op.mt_op = MTWEOF;
12730870Skarels 				    op.mt_count = (daddr_t) 1;
12830870Skarels 				    if (ioctl(outp, MTIOCTOP, (char *)&op) < 0) {
12930870Skarels 					    perror("write tape mark");
13030870Skarels 					    exit(6);
13130870Skarels 				    }
13230870Skarels 				    needeof = 0;
13330870Skarels 				}
13430870Skarels 				nw = write(outp, buff, nread);
13530870Skarels 				if (nw != nread) {
13630870Skarels 				    fprintf(stderr,
13730870Skarels 					"write error, file %d, record %d: ",
13830870Skarels 					filen, record);
13930870Skarels 				    if (nw == -1)
14030870Skarels 					perror("");
14130870Skarels 				    else
14230870Skarels 					fprintf(stderr,
14330870Skarels 					    "write (%d) != read (%d)\n",
14430870Skarels 					    nw, nread);
14530870Skarels 				    fprintf(stderr, "copy aborted\n");
14630870Skarels 				    exit(5);
14730870Skarels 				}
14830870Skarels 			}
14930870Skarels 			size += nread;
15030870Skarels 			record++;
15130870Skarels 		} else {
15230870Skarels 			if (lastread <= 0 && lastread != NOCOUNT) {
15324973Sbloom 				printf("eot\n");
15424973Sbloom 				break;
15524973Sbloom 			}
15624973Sbloom 			printf("file %d: eof after %ld records: %ld bytes\n",
15730870Skarels 				filen, record, size);
15830870Skarels 			needeof = 1;
15924973Sbloom 			filen++;
16024973Sbloom 			tsize += size;
16130870Skarels 			record = 0;
16230870Skarels 			lastrec = 0;
16330870Skarels 			lastread = 0;
16424973Sbloom 			size = 0;
16524973Sbloom 			if (nfile && filen > nfile)
16624973Sbloom 				break;
16724973Sbloom 		}
16830870Skarels 		lastread = nread;
16924973Sbloom 	}
17025590Sbloom 	if (copy)
17125590Sbloom 		(void) close(outp);
17224973Sbloom 	printf("total length: %ld bytes\n", tsize);
17324973Sbloom }
17424973Sbloom 
17530870Skarels intr()
17624973Sbloom {
17730870Skarels 	if (record)
17830870Skarels 		if (record - lastrec > 1)
17930870Skarels 			printf("records %ld to %ld\n", lastrec, record);
18024973Sbloom 		else
18130870Skarels 			printf("record %ld\n", lastrec);
18230870Skarels 	printf("interrupt at file %d: record %ld\n", filen, record);
18324973Sbloom 	printf("total length: %ld bytes\n", tsize+size);
18424973Sbloom 	exit(1);
18524973Sbloom }
186