xref: /csrg-svn/usr.bin/tcopy/tcopy.c (revision 30870)
124973Sbloom /*
2*30870Skarels  * 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[] =
9*30870Skarels "@(#) 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*30870Skarels static char sccsid[] = "@(#)tcopy.c	5.4 (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>
2324973Sbloom 
24*30870Skarels #define MAXREC	(64 * 1024)
25*30870Skarels #define NOCOUNT	(-2)
26*30870Skarels #undef DEFTAPE
27*30870Skarels #define	DEFTAPE	"/dev/rmt0"
2824973Sbloom 
29*30870Skarels char	*buff;
30*30870Skarels char	*inf = DEFTAPE;
31*30870Skarels int	maxblk = MAXREC;
32*30870Skarels int	filen;
33*30870Skarels long	record, lastrec;
34*30870Skarels int	intr();
35*30870Skarels long	itol();
36*30870Skarels char	*malloc();
37*30870Skarels long	size, tsize;
38*30870Skarels int	nfile;
39*30870Skarels int	lastread;
40*30870Skarels int	copy;
4124973Sbloom 
4224973Sbloom main(argc, argv)
4324973Sbloom char **argv;
4424973Sbloom {
45*30870Skarels 	register nread, nw, inp, outp;
4624973Sbloom 	struct mtop op;
47*30870Skarels 	int needeof = 0, guesslen = 1;
4824973Sbloom 
49*30870Skarels 	while (argc > 1 && *argv[1] == '-') {
50*30870Skarels 		switch (*++argv[1]) {
51*30870Skarels 		case 's':
52*30870Skarels 			if (argc < 3)
53*30870Skarels 				goto usage;
54*30870Skarels 			maxblk = atoi(argv[2]);
55*30870Skarels 			if (maxblk <= 0) {
56*30870Skarels 				fprintf(stderr, "illegal block size\n");
57*30870Skarels 				goto usage;
58*30870Skarels 			}
59*30870Skarels 			argc--;
60*30870Skarels 			argv++;
61*30870Skarels 			guesslen = 0;
62*30870Skarels 			break;
63*30870Skarels 		}
64*30870Skarels 		argc--;
65*30870Skarels 		argv++;
66*30870Skarels 	}
67*30870Skarels 	if (argc < 1 || argc > 3) {
68*30870Skarels usage:
69*30870Skarels 		fprintf(stderr, "Usage: tcopy [-s maxblk] src [dest]\n");
7024973Sbloom 		exit(1);
7124973Sbloom 	}
72*30870Skarels 	if (argc > 1)
73*30870Skarels 		inf = argv[1];
74*30870Skarels 	if ((inp = open(inf, O_RDONLY, 0)) < 0) {
75*30870Skarels 		perror(inf);
76*30870Skarels 		exit(1);
77*30870Skarels 	}
7825590Sbloom 	if (argc == 3) {
7925590Sbloom 		copy = 1;
80*30870Skarels 		if ((outp = open(argv[2], O_WRONLY, 0666)) < 0) {
81*30870Skarels 			perror(argv[2]);
8225590Sbloom 			exit(3);
8325590Sbloom 		}
8424973Sbloom 	}
8525590Sbloom 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
86*30870Skarels 		(void) signal(SIGINT, intr);
87*30870Skarels 	buff = malloc(maxblk);
88*30870Skarels 	if (buff == NULL) {
89*30870Skarels 		fprintf("tcopy: no memory\n");
90*30870Skarels 		exit(11);
91*30870Skarels 	}
92*30870Skarels 	lastread = NOCOUNT;
9324973Sbloom 	for (;;) {
94*30870Skarels 		nread = read(inp, buff, maxblk);
95*30870Skarels 		if (nread == -1) {
96*30870Skarels 			if (guesslen && maxblk > MAXREC / 2) {
97*30870Skarels 				maxblk -= 1024;
98*30870Skarels 				continue;
99*30870Skarels 			}
100*30870Skarels 			fprintf(stderr, "read error, file %d, record %d: ",
101*30870Skarels 			    filen, record);
102*30870Skarels 			perror("");
103*30870Skarels 		} else if (nread != lastread) {
104*30870Skarels 			if (lastread != 0 && lastread != NOCOUNT) {
105*30870Skarels 				if (lastrec == 0 && nread == 0)
106*30870Skarels 					printf("%d records\n", record);
107*30870Skarels 				else if (record - lastrec > 1)
108*30870Skarels 					printf("records %ld to %ld\n",
109*30870Skarels 					    lastrec, record);
110*30870Skarels 				else
111*30870Skarels 					printf("record %ld\n", lastrec);
112*30870Skarels 			}
113*30870Skarels 			if (nread != 0)
114*30870Skarels 				printf("file %d: block size %d: ",
115*30870Skarels 				    filen, nread);
116*30870Skarels 			fflush(stdout);
117*30870Skarels 			lastrec = record;
11824973Sbloom 		}
119*30870Skarels 		guesslen = 0;
120*30870Skarels 		if (nread > 0) {
121*30870Skarels 			if (copy) {
122*30870Skarels 				if (needeof) {
123*30870Skarels 				    op.mt_op = MTWEOF;
124*30870Skarels 				    op.mt_count = (daddr_t) 1;
125*30870Skarels 				    if (ioctl(outp, MTIOCTOP, (char *)&op) < 0) {
126*30870Skarels 					    perror("write tape mark");
127*30870Skarels 					    exit(6);
128*30870Skarels 				    }
129*30870Skarels 				    needeof = 0;
130*30870Skarels 				}
131*30870Skarels 				nw = write(outp, buff, nread);
132*30870Skarels 				if (nw != nread) {
133*30870Skarels 				    fprintf(stderr,
134*30870Skarels 					"write error, file %d, record %d: ",
135*30870Skarels 					filen, record);
136*30870Skarels 				    if (nw == -1)
137*30870Skarels 					perror("");
138*30870Skarels 				    else
139*30870Skarels 					fprintf(stderr,
140*30870Skarels 					    "write (%d) != read (%d)\n",
141*30870Skarels 					    nw, nread);
142*30870Skarels 				    fprintf(stderr, "copy aborted\n");
143*30870Skarels 				    exit(5);
144*30870Skarels 				}
145*30870Skarels 			}
146*30870Skarels 			size += nread;
147*30870Skarels 			record++;
148*30870Skarels 		} else {
149*30870Skarels 			if (lastread <= 0 && lastread != NOCOUNT) {
15024973Sbloom 				printf("eot\n");
15124973Sbloom 				break;
15224973Sbloom 			}
15324973Sbloom 			printf("file %d: eof after %ld records: %ld bytes\n",
154*30870Skarels 				filen, record, size);
155*30870Skarels 			needeof = 1;
15624973Sbloom 			filen++;
15724973Sbloom 			tsize += size;
158*30870Skarels 			record = 0;
159*30870Skarels 			lastrec = 0;
160*30870Skarels 			lastread = 0;
16124973Sbloom 			size = 0;
16224973Sbloom 			if (nfile && filen > nfile)
16324973Sbloom 				break;
16424973Sbloom 		}
165*30870Skarels 		lastread = nread;
16624973Sbloom 	}
16725590Sbloom 	if (copy)
16825590Sbloom 		(void) close(outp);
16924973Sbloom 	printf("total length: %ld bytes\n", tsize);
17024973Sbloom }
17124973Sbloom 
172*30870Skarels intr()
17324973Sbloom {
174*30870Skarels 	if (record)
175*30870Skarels 		if (record - lastrec > 1)
176*30870Skarels 			printf("records %ld to %ld\n", lastrec, record);
17724973Sbloom 		else
178*30870Skarels 			printf("record %ld\n", lastrec);
179*30870Skarels 	printf("interrupt at file %d: record %ld\n", filen, record);
18024973Sbloom 	printf("total length: %ld bytes\n", tsize+size);
18124973Sbloom 	exit(1);
18224973Sbloom }
183