xref: /csrg-svn/usr.bin/tcopy/tcopy.c (revision 32759)
124973Sbloom /*
230870Skarels  * Copyright (c) 1985, 1987 Regents of the University of California.
3*32759Sbostic  * All rights reserved.
4*32759Sbostic  *
5*32759Sbostic  * Redistribution and use in source and binary forms are permitted
6*32759Sbostic  * provided that this notice is preserved and that due credit is given
7*32759Sbostic  * to the University of California at Berkeley. The name of the University
8*32759Sbostic  * may not be used to endorse or promote products derived from this
9*32759Sbostic  * software without specific written prior permission. This software
10*32759Sbostic  * is provided ``as is'' without express or implied warranty.
1124973Sbloom  */
1224973Sbloom 
1324973Sbloom #ifndef lint
1424973Sbloom char copyright[] =
1530870Skarels "@(#) Copyright (c) 1985, 1987 Regents of the University of California.\n\
1624973Sbloom  All rights reserved.\n";
17*32759Sbostic #endif /* not lint */
1824973Sbloom 
1924973Sbloom #ifndef lint
20*32759Sbostic static char sccsid[] = "@(#)tcopy.c	5.6 (Berkeley) 12/04/87";
21*32759Sbostic #endif /* not lint */
2224973Sbloom 
2324973Sbloom #include <stdio.h>
2425590Sbloom #include <signal.h>
2524973Sbloom #include <sys/file.h>
2624973Sbloom #include <sys/types.h>
2724973Sbloom #include <sys/ioctl.h>
2824973Sbloom #include <sys/mtio.h>
2930873Skarels #include <sys/errno.h>
3024973Sbloom 
3130870Skarels #define MAXREC	(64 * 1024)
3230870Skarels #define NOCOUNT	(-2)
3330870Skarels #undef DEFTAPE
3430870Skarels #define	DEFTAPE	"/dev/rmt0"
3524973Sbloom 
3630870Skarels char	*buff;
3730870Skarels char	*inf = DEFTAPE;
3830870Skarels int	maxblk = MAXREC;
3930870Skarels int	filen;
4030870Skarels long	record, lastrec;
4130870Skarels int	intr();
4230870Skarels char	*malloc();
4330870Skarels long	size, tsize;
4430870Skarels int	nfile;
4530870Skarels int	lastread;
4630870Skarels int	copy;
4730873Skarels extern	int errno;
4824973Sbloom 
4924973Sbloom main(argc, argv)
50*32759Sbostic 	int argc;
51*32759Sbostic 	char **argv;
5224973Sbloom {
5330870Skarels 	register nread, nw, inp, outp;
5424973Sbloom 	struct mtop op;
5530870Skarels 	int needeof = 0, guesslen = 1;
5624973Sbloom 
5730870Skarels 	while (argc > 1 && *argv[1] == '-') {
5830870Skarels 		switch (*++argv[1]) {
5930870Skarels 		case 's':
6030870Skarels 			if (argc < 3)
6130870Skarels 				goto usage;
6230870Skarels 			maxblk = atoi(argv[2]);
6330870Skarels 			if (maxblk <= 0) {
6430870Skarels 				fprintf(stderr, "illegal block size\n");
6530870Skarels 				goto usage;
6630870Skarels 			}
6730870Skarels 			argc--;
6830870Skarels 			argv++;
6930870Skarels 			guesslen = 0;
7030870Skarels 			break;
7130870Skarels 		}
7230870Skarels 		argc--;
7330870Skarels 		argv++;
7430870Skarels 	}
7530870Skarels 	if (argc < 1 || argc > 3) {
7630870Skarels usage:
7730870Skarels 		fprintf(stderr, "Usage: tcopy [-s maxblk] src [dest]\n");
7824973Sbloom 		exit(1);
7924973Sbloom 	}
8030870Skarels 	if (argc > 1)
8130870Skarels 		inf = argv[1];
8230870Skarels 	if ((inp = open(inf, O_RDONLY, 0)) < 0) {
8330870Skarels 		perror(inf);
8430870Skarels 		exit(1);
8530870Skarels 	}
8625590Sbloom 	if (argc == 3) {
8725590Sbloom 		copy = 1;
8830870Skarels 		if ((outp = open(argv[2], O_WRONLY, 0666)) < 0) {
8930870Skarels 			perror(argv[2]);
9025590Sbloom 			exit(3);
9125590Sbloom 		}
9224973Sbloom 	}
9325590Sbloom 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
9430870Skarels 		(void) signal(SIGINT, intr);
95*32759Sbostic 	buff = malloc((u_int)maxblk);
9630870Skarels 	if (buff == NULL) {
97*32759Sbostic 		fprintf(stderr, "tcopy: no memory\n");
9830870Skarels 		exit(11);
9930870Skarels 	}
10030870Skarels 	lastread = NOCOUNT;
10124973Sbloom 	for (;;) {
10230870Skarels 		nread = read(inp, buff, maxblk);
10330870Skarels 		if (nread == -1) {
10430873Skarels 			if (errno == EINVAL && guesslen &&
10530873Skarels 			    maxblk > MAXREC / 2) {
10630870Skarels 				maxblk -= 1024;
10730870Skarels 				continue;
10830870Skarels 			}
109*32759Sbostic 			fprintf(stderr, "read error, file %d, record %ld: ",
11030870Skarels 			    filen, record);
11130870Skarels 			perror("");
11230870Skarels 		} else if (nread != lastread) {
11330870Skarels 			if (lastread != 0 && lastread != NOCOUNT) {
11430870Skarels 				if (lastrec == 0 && nread == 0)
115*32759Sbostic 					printf("%ld records\n", record);
11630870Skarels 				else if (record - lastrec > 1)
11730870Skarels 					printf("records %ld to %ld\n",
11830870Skarels 					    lastrec, record);
11930870Skarels 				else
12030870Skarels 					printf("record %ld\n", lastrec);
12130870Skarels 			}
12230870Skarels 			if (nread != 0)
12330870Skarels 				printf("file %d: block size %d: ",
12430870Skarels 				    filen, nread);
125*32759Sbostic 			(void) fflush(stdout);
12630870Skarels 			lastrec = record;
12724973Sbloom 		}
12830870Skarels 		guesslen = 0;
12930870Skarels 		if (nread > 0) {
13030870Skarels 			if (copy) {
13130870Skarels 				if (needeof) {
13230870Skarels 				    op.mt_op = MTWEOF;
13330870Skarels 				    op.mt_count = (daddr_t) 1;
13430870Skarels 				    if (ioctl(outp, MTIOCTOP, (char *)&op) < 0) {
13530870Skarels 					    perror("write tape mark");
13630870Skarels 					    exit(6);
13730870Skarels 				    }
13830870Skarels 				    needeof = 0;
13930870Skarels 				}
14030870Skarels 				nw = write(outp, buff, nread);
14130870Skarels 				if (nw != nread) {
14230870Skarels 				    fprintf(stderr,
143*32759Sbostic 					"write error, file %d, record %ld: ",
14430870Skarels 					filen, record);
14530870Skarels 				    if (nw == -1)
14630870Skarels 					perror("");
14730870Skarels 				    else
14830870Skarels 					fprintf(stderr,
14930870Skarels 					    "write (%d) != read (%d)\n",
15030870Skarels 					    nw, nread);
15130870Skarels 				    fprintf(stderr, "copy aborted\n");
15230870Skarels 				    exit(5);
15330870Skarels 				}
15430870Skarels 			}
15530870Skarels 			size += nread;
15630870Skarels 			record++;
15730870Skarels 		} else {
15830870Skarels 			if (lastread <= 0 && lastread != NOCOUNT) {
15924973Sbloom 				printf("eot\n");
16024973Sbloom 				break;
16124973Sbloom 			}
16224973Sbloom 			printf("file %d: eof after %ld records: %ld bytes\n",
16330870Skarels 				filen, record, size);
16430870Skarels 			needeof = 1;
16524973Sbloom 			filen++;
16624973Sbloom 			tsize += size;
16730870Skarels 			record = 0;
16830870Skarels 			lastrec = 0;
16930870Skarels 			lastread = 0;
17024973Sbloom 			size = 0;
17124973Sbloom 			if (nfile && filen > nfile)
17224973Sbloom 				break;
17324973Sbloom 		}
17430870Skarels 		lastread = nread;
17524973Sbloom 	}
17625590Sbloom 	if (copy)
17725590Sbloom 		(void) close(outp);
17824973Sbloom 	printf("total length: %ld bytes\n", tsize);
17924973Sbloom }
18024973Sbloom 
18130870Skarels intr()
18224973Sbloom {
18330870Skarels 	if (record)
18430870Skarels 		if (record - lastrec > 1)
18530870Skarels 			printf("records %ld to %ld\n", lastrec, record);
18624973Sbloom 		else
18730870Skarels 			printf("record %ld\n", lastrec);
18830870Skarels 	printf("interrupt at file %d: record %ld\n", filen, record);
18924973Sbloom 	printf("total length: %ld bytes\n", tsize+size);
19024973Sbloom 	exit(1);
19124973Sbloom }
192