xref: /csrg-svn/usr.sbin/rmt/rmt.c (revision 18475)
16448Swnj #ifndef lint
2*18475Smckusick static char sccsid[] = "@(#)rmt.c	4.7 (Berkeley) 85/03/20";
36448Swnj #endif
46448Swnj 
56448Swnj /*
66448Swnj  * rmt
76448Swnj  */
86448Swnj #include <stdio.h>
96448Swnj #include <sgtty.h>
106448Swnj #include <sys/types.h>
1117537Sralph #include <sys/socket.h>
126448Swnj #include <sys/mtio.h>
136448Swnj #include <errno.h>
146448Swnj 
156448Swnj int	tape = -1;
166448Swnj 
17*18475Smckusick char	*record;
18*18475Smckusick int	maxrecsize = -1;
19*18475Smckusick char	*checkbuf();
206448Swnj 
216448Swnj #define	SSIZE	64
226448Swnj char	device[SSIZE];
236448Swnj char	count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
246448Swnj 
256448Swnj extern	errno;
266448Swnj char	*sys_errlist[];
276448Swnj char	resp[BUFSIZ];
286448Swnj 
296448Swnj char	*sprintf();
306448Swnj long	lseek();
316448Swnj 
326448Swnj FILE	*debug;
3317370Ssam #define	DEBUG(f)	if (debug) fprintf(debug, f)
3417370Ssam #define	DEBUG1(f,a)	if (debug) fprintf(debug, f, a)
3517370Ssam #define	DEBUG2(f,a1,a2)	if (debug) fprintf(debug, f, a1, a2)
366448Swnj 
376448Swnj main(argc, argv)
386448Swnj 	int argc;
396448Swnj 	char **argv;
406448Swnj {
416560Smckusick 	int rval;
426448Swnj 	char c;
436448Swnj 	int n, i, cc;
446448Swnj 
456448Swnj 	argc--, argv++;
466448Swnj 	if (argc > 0) {
476448Swnj 		debug = fopen(*argv, "w");
486448Swnj 		if (debug == 0)
496448Swnj 			exit(1);
506448Swnj 		(void) setbuf(debug, (char *)0);
516448Swnj 	}
526448Swnj top:
536448Swnj 	errno = 0;
546448Swnj 	rval = 0;
556448Swnj 	if (read(0, &c, 1) != 1)
566448Swnj 		exit(0);
576448Swnj 	switch (c) {
586448Swnj 
596448Swnj 	case 'O':
606448Swnj 		if (tape >= 0)
616448Swnj 			(void) close(tape);
6217370Ssam 		getstring(device); getstring(mode);
6317370Ssam 		DEBUG2("rmtd: O %s %s\n", device, mode);
646448Swnj 		tape = open(device, atoi(mode));
656448Swnj 		if (tape < 0)
666448Swnj 			goto ioerror;
676841Smckusick 		goto respond;
686448Swnj 
696448Swnj 	case 'C':
7017370Ssam 		DEBUG("rmtd: C\n");
7117370Ssam 		getstring(device);		/* discard */
726448Swnj 		if (close(tape) < 0)
736448Swnj 			goto ioerror;
746448Swnj 		tape = -1;
756841Smckusick 		goto respond;
766448Swnj 
776448Swnj 	case 'L':
7817370Ssam 		getstring(count); getstring(pos);
7917370Ssam 		DEBUG2("rmtd: L %s %s\n", count, pos);
806448Swnj 		rval = lseek(tape, (long) atoi(count), atoi(pos));
816448Swnj 		if (rval < 0)
826448Swnj 			goto ioerror;
836841Smckusick 		goto respond;
846448Swnj 
856448Swnj 	case 'W':
8617370Ssam 		getstring(count);
876448Swnj 		n = atoi(count);
8817370Ssam 		DEBUG1("rmtd: W %s\n", count);
89*18475Smckusick 		record = checkbuf(record, n);
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");
94*18475Smckusick 				exit(2);
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);
106*18475Smckusick 		record = checkbuf(record, n);
1076448Swnj 		rval = read(tape, record, n);
1086448Swnj 		if (rval < 0)
1096448Swnj 			goto ioerror;
1106841Smckusick 		(void) sprintf(resp, "A%d\n", rval);
1116841Smckusick 		(void) write(1, resp, strlen(resp));
1126841Smckusick 		(void) write(1, record, rval);
1136841Smckusick 		goto top;
1146448Swnj 
1156448Swnj 	case 'I':
11617370Ssam 		getstring(op); getstring(count);
11717370Ssam 		DEBUG2("rmtd: I %s %s\n", op, count);
1186448Swnj 		{ struct mtop mtop;
1196448Swnj 		  mtop.mt_op = atoi(op);
1206448Swnj 		  mtop.mt_count = atoi(count);
1216448Swnj 		  if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
1226448Swnj 			goto ioerror;
1236448Swnj 		  rval = mtop.mt_count;
1246448Swnj 		}
1256841Smckusick 		goto respond;
1266448Swnj 
1276448Swnj 	case 'S':		/* status */
12817370Ssam 		DEBUG("rmtd: S\n");
1296448Swnj 		{ struct mtget mtget;
1306448Swnj 		  if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
1316448Swnj 			goto ioerror;
1326448Swnj 		  rval = sizeof (mtget);
13317854Sralph 		  (void) sprintf(resp, "A%d\n", rval);
13417854Sralph 		  (void) write(1, resp, strlen(resp));
1356448Swnj 		  (void) write(1, (char *)&mtget, sizeof (mtget));
13617854Sralph 		  goto top;
1376448Swnj 		}
1386448Swnj 
1396448Swnj 	default:
14017370Ssam 		DEBUG1("rmtd: garbage command %c\n", c);
141*18475Smckusick 		exit(3);
1426448Swnj 	}
1436841Smckusick respond:
14417370Ssam 	DEBUG1("rmtd: A %d\n", rval);
1456448Swnj 	(void) sprintf(resp, "A%d\n", rval);
1466448Swnj 	(void) write(1, resp, strlen(resp));
1476448Swnj 	goto top;
1486448Swnj ioerror:
1496448Swnj 	error(errno);
1506448Swnj 	goto top;
1516448Swnj }
1526448Swnj 
15317370Ssam getstring(bp)
1546448Swnj 	char *bp;
1556448Swnj {
1566448Swnj 	int i;
1576448Swnj 	char *cp = bp;
1586448Swnj 
1596448Swnj 	for (i = 0; i < SSIZE; i++) {
1606448Swnj 		if (read(0, cp+i, 1) != 1)
1616448Swnj 			exit(0);
1626448Swnj 		if (cp[i] == '\n')
1636448Swnj 			break;
1646448Swnj 	}
1656448Swnj 	cp[i] = '\0';
1666448Swnj }
1676448Swnj 
168*18475Smckusick char *
169*18475Smckusick checkbuf(record, size)
170*18475Smckusick 	char *record;
171*18475Smckusick 	int size;
172*18475Smckusick {
173*18475Smckusick 	extern char *malloc();
174*18475Smckusick 
175*18475Smckusick 	if (size <= maxrecsize)
176*18475Smckusick 		return (record);
177*18475Smckusick 	if (record != 0)
178*18475Smckusick 		free(record);
179*18475Smckusick 	record = malloc(size);
180*18475Smckusick 	if (record == 0) {
181*18475Smckusick 		DEBUG("rmtd: cannot allocate buffer space\n");
182*18475Smckusick 		exit(4);
183*18475Smckusick 	}
184*18475Smckusick 	(void) setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size));
185*18475Smckusick 	return (record);
186*18475Smckusick }
187*18475Smckusick 
1886448Swnj error(num)
1896448Swnj 	int num;
1906448Swnj {
1916448Swnj 
19217370Ssam 	DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]);
1936448Swnj 	(void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]);
1946448Swnj 	(void) write(1, resp, strlen (resp));
1956448Swnj }
196