xref: /original-bsd/usr.sbin/rmt/rmt.c (revision 24f1d79f)
1 #ifndef lint
2 static char sccsid[] = "@(#)rmt.c	4.3 82/05/19";
3 #endif
4 
5 /*
6  * rmt
7  */
8 #include <stdio.h>
9 #include <sgtty.h>
10 #include <sys/types.h>
11 #include <sys/mtio.h>
12 #include <errno.h>
13 
14 int	tape = -1;
15 
16 #define	MAXRECSIZ	(10*1024)	/* small enuf for pdp-11's too */
17 char	record[MAXRECSIZ];
18 
19 #define	SSIZE	64
20 char	device[SSIZE];
21 char	count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
22 
23 extern	errno;
24 char	*sys_errlist[];
25 char	resp[BUFSIZ];
26 
27 char	*sprintf();
28 long	lseek();
29 
30 FILE	*debug;
31 
32 main(argc, argv)
33 	int argc;
34 	char **argv;
35 {
36 	int rval;
37 	char c;
38 	int n, i, cc;
39 
40 	argc--, argv++;
41 	if (argc > 0) {
42 		debug = fopen(*argv, "w");
43 		if (debug == 0)
44 			exit(1);
45 		(void) setbuf(debug, (char *)0);
46 	}
47 top:
48 	errno = 0;
49 	rval = 0;
50 	if (read(0, &c, 1) != 1)
51 		exit(0);
52 	switch (c) {
53 
54 	case 'O':
55 		if (tape >= 0)
56 			(void) close(tape);
57 		gets(device); gets(mode);
58 if (debug) fprintf(debug, "rmtd: O %s %s\n", device, mode);
59 		tape = open(device, atoi(mode));
60 		if (tape < 0)
61 			goto ioerror;
62 		goto respond;
63 
64 	case 'C':
65 if (debug) fprintf(debug, "rmtd: C\n");
66 		gets(device);		/* discard */
67 		if (close(tape) < 0)
68 			goto ioerror;
69 		tape = -1;
70 		goto respond;
71 
72 	case 'L':
73 		gets(count); gets(pos);
74 if (debug) fprintf(debug, "rmtd: L %s %s\n", count, pos);
75 		rval = lseek(tape, (long) atoi(count), atoi(pos));
76 		if (rval < 0)
77 			goto ioerror;
78 		goto respond;
79 
80 	case 'W':
81 		gets(count);
82 		n = atoi(count);
83 if (debug) fprintf(debug, "rmtd: W %s\n", count);
84 		for (i = 0; i < n; i += cc) {
85 			cc = read(0, &record[i], n - i);
86 			if (cc <= 0) {
87 if (debug) fprintf(debug, "rmtd: premature eof\n");
88 				exit(1);
89 			}
90 		}
91 		rval = write(tape, record, n);
92 		if (rval < 0)
93 			goto ioerror;
94 		goto respond;
95 
96 	case 'R':
97 		gets(count);
98 if (debug) fprintf(debug, "rmtd: R %s\n", count);
99 		n = atoi(count);
100 		if (n > sizeof (record))
101 			n = sizeof (record);
102 		rval = read(tape, record, n);
103 		if (rval < 0)
104 			goto ioerror;
105 		(void) sprintf(resp, "A%d\n", rval);
106 		(void) write(1, resp, strlen(resp));
107 		(void) write(1, record, rval);
108 		goto top;
109 
110 	case 'I':
111 		gets(op); gets(count);
112 if (debug) fprintf(debug, "rmtd: I %s %s\n", op, count);
113 		{ struct mtop mtop;
114 		  mtop.mt_op = atoi(op);
115 		  mtop.mt_count = atoi(count);
116 		  if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
117 			goto ioerror;
118 		  rval = mtop.mt_count;
119 		}
120 		goto respond;
121 
122 	case 'S':		/* status */
123 if (debug) fprintf(debug, "rmtd: S\n");
124 		{ struct mtget mtget;
125 		  if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
126 			goto ioerror;
127 		  rval = sizeof (mtget);
128 		  (void) write(1, (char *)&mtget, sizeof (mtget));
129 		  goto respond;
130 		}
131 
132 	default:
133 if (debug) fprintf(debug, "rmtd: garbage command %c\n", c);
134 		exit(1);
135 	}
136 respond:
137 if (debug) fprintf(debug, "rmtd: A %d\n", rval);
138 	(void) sprintf(resp, "A%d\n", rval);
139 	(void) write(1, resp, strlen(resp));
140 	goto top;
141 ioerror:
142 	error(errno);
143 	goto top;
144 }
145 
146 gets(bp)
147 	char *bp;
148 {
149 	int i;
150 	char *cp = bp;
151 
152 	for (i = 0; i < SSIZE; i++) {
153 		if (read(0, cp+i, 1) != 1)
154 			exit(0);
155 		if (cp[i] == '\n')
156 			break;
157 	}
158 	cp[i] = '\0';
159 }
160 
161 error(num)
162 	int num;
163 {
164 
165 if (debug) fprintf(debug, "rmtd: E %d (%s)\n", num, sys_errlist[num]);
166 	(void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]);
167 	(void) write(1, resp, strlen (resp));
168 }
169 
170