xref: /csrg-svn/usr.sbin/rmt/rmt.c (revision 17537)
16448Swnj #ifndef lint
2*17537Sralph static char sccsid[] = "@(#)rmt.c	4.5 (Berkeley) 84/12/19";
36448Swnj #endif
46448Swnj 
56448Swnj /*
66448Swnj  * rmt
76448Swnj  */
86448Swnj #include <stdio.h>
96448Swnj #include <sgtty.h>
106448Swnj #include <sys/types.h>
11*17537Sralph #include <sys/socket.h>
126448Swnj #include <sys/mtio.h>
136448Swnj #include <errno.h>
146448Swnj 
156448Swnj int	tape = -1;
166448Swnj 
176560Smckusick #define	MAXRECSIZ	(10*1024)	/* small enuf for pdp-11's too */
186448Swnj char	record[MAXRECSIZ];
196448Swnj 
206448Swnj #define	SSIZE	64
216448Swnj char	device[SSIZE];
226448Swnj char	count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
236448Swnj 
246448Swnj extern	errno;
256448Swnj char	*sys_errlist[];
266448Swnj char	resp[BUFSIZ];
276448Swnj 
286448Swnj char	*sprintf();
296448Swnj long	lseek();
306448Swnj 
316448Swnj FILE	*debug;
3217370Ssam #define	DEBUG(f)	if (debug) fprintf(debug, f)
3317370Ssam #define	DEBUG1(f,a)	if (debug) fprintf(debug, f, a)
3417370Ssam #define	DEBUG2(f,a1,a2)	if (debug) fprintf(debug, f, a1, a2)
356448Swnj 
366448Swnj main(argc, argv)
376448Swnj 	int argc;
386448Swnj 	char **argv;
396448Swnj {
406560Smckusick 	int rval;
416448Swnj 	char c;
426448Swnj 	int n, i, cc;
436448Swnj 
446448Swnj 	argc--, argv++;
456448Swnj 	if (argc > 0) {
466448Swnj 		debug = fopen(*argv, "w");
476448Swnj 		if (debug == 0)
486448Swnj 			exit(1);
496448Swnj 		(void) setbuf(debug, (char *)0);
506448Swnj 	}
51*17537Sralph 	n = MAXRECSIZ;
52*17537Sralph 	(void) setsockopt(0, SOL_SOCKET, SO_RCVBUF, &n, sizeof (n));
536448Swnj top:
546448Swnj 	errno = 0;
556448Swnj 	rval = 0;
566448Swnj 	if (read(0, &c, 1) != 1)
576448Swnj 		exit(0);
586448Swnj 	switch (c) {
596448Swnj 
606448Swnj 	case 'O':
616448Swnj 		if (tape >= 0)
626448Swnj 			(void) close(tape);
6317370Ssam 		getstring(device); getstring(mode);
6417370Ssam 		DEBUG2("rmtd: O %s %s\n", device, mode);
656448Swnj 		tape = open(device, atoi(mode));
666448Swnj 		if (tape < 0)
676448Swnj 			goto ioerror;
686841Smckusick 		goto respond;
696448Swnj 
706448Swnj 	case 'C':
7117370Ssam 		DEBUG("rmtd: C\n");
7217370Ssam 		getstring(device);		/* discard */
736448Swnj 		if (close(tape) < 0)
746448Swnj 			goto ioerror;
756448Swnj 		tape = -1;
766841Smckusick 		goto respond;
776448Swnj 
786448Swnj 	case 'L':
7917370Ssam 		getstring(count); getstring(pos);
8017370Ssam 		DEBUG2("rmtd: L %s %s\n", count, pos);
816448Swnj 		rval = lseek(tape, (long) atoi(count), atoi(pos));
826448Swnj 		if (rval < 0)
836448Swnj 			goto ioerror;
846841Smckusick 		goto respond;
856448Swnj 
866448Swnj 	case 'W':
8717370Ssam 		getstring(count);
886448Swnj 		n = atoi(count);
8917370Ssam 		DEBUG1("rmtd: W %s\n", count);
906448Swnj 		for (i = 0; i < n; i += cc) {
916448Swnj 			cc = read(0, &record[i], n - i);
926448Swnj 			if (cc <= 0) {
9317370Ssam 				DEBUG("rmtd: premature eof\n");
946448Swnj 				exit(1);
956448Swnj 			}
966448Swnj 		}
976448Swnj 		rval = write(tape, record, n);
986448Swnj 		if (rval < 0)
996448Swnj 			goto ioerror;
1006841Smckusick 		goto respond;
1016448Swnj 
1026448Swnj 	case 'R':
10317370Ssam 		getstring(count);
10417370Ssam 		DEBUG1("rmtd: R %s\n", count);
1056448Swnj 		n = atoi(count);
1066448Swnj 		if (n > sizeof (record))
1076448Swnj 			n = sizeof (record);
1086448Swnj 		rval = read(tape, record, n);
1096448Swnj 		if (rval < 0)
1106448Swnj 			goto ioerror;
1116841Smckusick 		(void) sprintf(resp, "A%d\n", rval);
1126841Smckusick 		(void) write(1, resp, strlen(resp));
1136841Smckusick 		(void) write(1, record, rval);
1146841Smckusick 		goto top;
1156448Swnj 
1166448Swnj 	case 'I':
11717370Ssam 		getstring(op); getstring(count);
11817370Ssam 		DEBUG2("rmtd: I %s %s\n", op, count);
1196448Swnj 		{ struct mtop mtop;
1206448Swnj 		  mtop.mt_op = atoi(op);
1216448Swnj 		  mtop.mt_count = atoi(count);
1226448Swnj 		  if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
1236448Swnj 			goto ioerror;
1246448Swnj 		  rval = mtop.mt_count;
1256448Swnj 		}
1266841Smckusick 		goto respond;
1276448Swnj 
1286448Swnj 	case 'S':		/* status */
12917370Ssam 		DEBUG("rmtd: S\n");
1306448Swnj 		{ struct mtget mtget;
1316448Swnj 		  if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
1326448Swnj 			goto ioerror;
1336448Swnj 		  rval = sizeof (mtget);
1346448Swnj 		  (void) write(1, (char *)&mtget, sizeof (mtget));
1356841Smckusick 		  goto respond;
1366448Swnj 		}
1376448Swnj 
1386448Swnj 	default:
13917370Ssam 		DEBUG1("rmtd: garbage command %c\n", c);
1406448Swnj 		exit(1);
1416448Swnj 	}
1426841Smckusick respond:
14317370Ssam 	DEBUG1("rmtd: A %d\n", rval);
1446448Swnj 	(void) sprintf(resp, "A%d\n", rval);
1456448Swnj 	(void) write(1, resp, strlen(resp));
1466448Swnj 	goto top;
1476448Swnj ioerror:
1486448Swnj 	error(errno);
1496448Swnj 	goto top;
1506448Swnj }
1516448Swnj 
15217370Ssam getstring(bp)
1536448Swnj 	char *bp;
1546448Swnj {
1556448Swnj 	int i;
1566448Swnj 	char *cp = bp;
1576448Swnj 
1586448Swnj 	for (i = 0; i < SSIZE; i++) {
1596448Swnj 		if (read(0, cp+i, 1) != 1)
1606448Swnj 			exit(0);
1616448Swnj 		if (cp[i] == '\n')
1626448Swnj 			break;
1636448Swnj 	}
1646448Swnj 	cp[i] = '\0';
1656448Swnj }
1666448Swnj 
1676448Swnj error(num)
1686448Swnj 	int num;
1696448Swnj {
1706448Swnj 
17117370Ssam 	DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]);
1726448Swnj 	(void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]);
1736448Swnj 	(void) write(1, resp, strlen (resp));
1746448Swnj }
1756560Smckusick 
176