xref: /csrg-svn/usr.sbin/rmt/rmt.c (revision 6841)
16448Swnj #ifndef lint
2*6841Smckusick static char sccsid[] = "@(#)rmt.c	4.3 82/05/19";
36448Swnj #endif
46448Swnj 
56448Swnj /*
66448Swnj  * rmt
76448Swnj  */
86448Swnj #include <stdio.h>
96448Swnj #include <sgtty.h>
106448Swnj #include <sys/types.h>
116448Swnj #include <sys/mtio.h>
126448Swnj #include <errno.h>
136448Swnj 
146448Swnj int	tape = -1;
156448Swnj 
166560Smckusick #define	MAXRECSIZ	(10*1024)	/* small enuf for pdp-11's too */
176448Swnj char	record[MAXRECSIZ];
186448Swnj 
196448Swnj #define	SSIZE	64
206448Swnj char	device[SSIZE];
216448Swnj char	count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
226448Swnj 
236448Swnj extern	errno;
246448Swnj char	*sys_errlist[];
256448Swnj char	resp[BUFSIZ];
266448Swnj 
276448Swnj char	*sprintf();
286448Swnj long	lseek();
296448Swnj 
306448Swnj FILE	*debug;
316448Swnj 
326448Swnj main(argc, argv)
336448Swnj 	int argc;
346448Swnj 	char **argv;
356448Swnj {
366560Smckusick 	int rval;
376448Swnj 	char c;
386448Swnj 	int n, i, cc;
396448Swnj 
406448Swnj 	argc--, argv++;
416448Swnj 	if (argc > 0) {
426448Swnj 		debug = fopen(*argv, "w");
436448Swnj 		if (debug == 0)
446448Swnj 			exit(1);
456448Swnj 		(void) setbuf(debug, (char *)0);
466448Swnj 	}
476448Swnj top:
486448Swnj 	errno = 0;
496448Swnj 	rval = 0;
506448Swnj 	if (read(0, &c, 1) != 1)
516448Swnj 		exit(0);
526448Swnj 	switch (c) {
536448Swnj 
546448Swnj 	case 'O':
556448Swnj 		if (tape >= 0)
566448Swnj 			(void) close(tape);
576448Swnj 		gets(device); gets(mode);
586448Swnj if (debug) fprintf(debug, "rmtd: O %s %s\n", device, mode);
596448Swnj 		tape = open(device, atoi(mode));
606448Swnj 		if (tape < 0)
616448Swnj 			goto ioerror;
62*6841Smckusick 		goto respond;
636448Swnj 
646448Swnj 	case 'C':
656448Swnj if (debug) fprintf(debug, "rmtd: C\n");
666448Swnj 		gets(device);		/* discard */
676448Swnj 		if (close(tape) < 0)
686448Swnj 			goto ioerror;
696448Swnj 		tape = -1;
70*6841Smckusick 		goto respond;
716448Swnj 
726448Swnj 	case 'L':
736448Swnj 		gets(count); gets(pos);
746448Swnj if (debug) fprintf(debug, "rmtd: L %s %s\n", count, pos);
756448Swnj 		rval = lseek(tape, (long) atoi(count), atoi(pos));
766448Swnj 		if (rval < 0)
776448Swnj 			goto ioerror;
78*6841Smckusick 		goto respond;
796448Swnj 
806448Swnj 	case 'W':
816448Swnj 		gets(count);
826448Swnj 		n = atoi(count);
836448Swnj if (debug) fprintf(debug, "rmtd: W %s\n", count);
846448Swnj 		for (i = 0; i < n; i += cc) {
856448Swnj 			cc = read(0, &record[i], n - i);
866448Swnj 			if (cc <= 0) {
876448Swnj if (debug) fprintf(debug, "rmtd: premature eof\n");
886448Swnj 				exit(1);
896448Swnj 			}
906448Swnj 		}
916448Swnj 		rval = write(tape, record, n);
926448Swnj 		if (rval < 0)
936448Swnj 			goto ioerror;
94*6841Smckusick 		goto respond;
956448Swnj 
966448Swnj 	case 'R':
976448Swnj 		gets(count);
986448Swnj if (debug) fprintf(debug, "rmtd: R %s\n", count);
996448Swnj 		n = atoi(count);
1006448Swnj 		if (n > sizeof (record))
1016448Swnj 			n = sizeof (record);
1026448Swnj 		rval = read(tape, record, n);
1036448Swnj 		if (rval < 0)
1046448Swnj 			goto ioerror;
105*6841Smckusick 		(void) sprintf(resp, "A%d\n", rval);
106*6841Smckusick 		(void) write(1, resp, strlen(resp));
107*6841Smckusick 		(void) write(1, record, rval);
108*6841Smckusick 		goto top;
1096448Swnj 
1106448Swnj 	case 'I':
1116448Swnj 		gets(op); gets(count);
1126448Swnj if (debug) fprintf(debug, "rmtd: I %s %s\n", op, count);
1136448Swnj 		{ struct mtop mtop;
1146448Swnj 		  mtop.mt_op = atoi(op);
1156448Swnj 		  mtop.mt_count = atoi(count);
1166448Swnj 		  if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
1176448Swnj 			goto ioerror;
1186448Swnj 		  rval = mtop.mt_count;
1196448Swnj 		}
120*6841Smckusick 		goto respond;
1216448Swnj 
1226448Swnj 	case 'S':		/* status */
1236448Swnj if (debug) fprintf(debug, "rmtd: S\n");
1246448Swnj 		{ struct mtget mtget;
1256448Swnj 		  if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
1266448Swnj 			goto ioerror;
1276448Swnj 		  rval = sizeof (mtget);
1286448Swnj 		  (void) write(1, (char *)&mtget, sizeof (mtget));
129*6841Smckusick 		  goto respond;
1306448Swnj 		}
1316448Swnj 
1326448Swnj 	default:
1336448Swnj if (debug) fprintf(debug, "rmtd: garbage command %c\n", c);
1346448Swnj 		exit(1);
1356448Swnj 	}
136*6841Smckusick respond:
1376560Smckusick if (debug) fprintf(debug, "rmtd: A %d\n", rval);
1386448Swnj 	(void) sprintf(resp, "A%d\n", rval);
1396448Swnj 	(void) write(1, resp, strlen(resp));
1406448Swnj 	goto top;
1416448Swnj ioerror:
1426448Swnj 	error(errno);
1436448Swnj 	goto top;
1446448Swnj }
1456448Swnj 
1466448Swnj gets(bp)
1476448Swnj 	char *bp;
1486448Swnj {
1496448Swnj 	int i;
1506448Swnj 	char *cp = bp;
1516448Swnj 
1526448Swnj 	for (i = 0; i < SSIZE; i++) {
1536448Swnj 		if (read(0, cp+i, 1) != 1)
1546448Swnj 			exit(0);
1556448Swnj 		if (cp[i] == '\n')
1566448Swnj 			break;
1576448Swnj 	}
1586448Swnj 	cp[i] = '\0';
1596448Swnj }
1606448Swnj 
1616448Swnj error(num)
1626448Swnj 	int num;
1636448Swnj {
1646448Swnj 
1656560Smckusick if (debug) fprintf(debug, "rmtd: E %d (%s)\n", num, sys_errlist[num]);
1666448Swnj 	(void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]);
1676448Swnj 	(void) write(1, resp, strlen (resp));
1686448Swnj }
1696560Smckusick 
170