|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: char copyright[] =
9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif not lint
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)rmt.c 5.2 (Berkeley) 1/7/86";
15: #endif not lint
16:
17: /*
18: * rmt
19: */
20: #include <stdio.h>
21: #include <sgtty.h>
22: #include <sys/types.h>
23: #include <sys/socket.h>
24: #include <sys/mtio.h>
25: #include <errno.h>
26:
27: int tape = -1;
28:
29: char *record;
30: int maxrecsize = -1;
31: char *checkbuf();
32:
33: #define SSIZE 64
34: char device[SSIZE];
35: char count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
36:
37: extern errno;
38: char *sys_errlist[];
39: char resp[BUFSIZ];
40:
41: char *sprintf();
42: long lseek();
43:
44: FILE *debug;
45: #define DEBUG(f) if (debug) fprintf(debug, f)
46: #define DEBUG1(f,a) if (debug) fprintf(debug, f, a)
47: #define DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2)
48:
49: main(argc, argv)
50: int argc;
51: char **argv;
52: {
53: int rval;
54: char c;
55: int n, i, cc;
56:
57: argc--, argv++;
58: if (argc > 0) {
59: debug = fopen(*argv, "w");
60: if (debug == 0)
61: exit(1);
62: (void) setbuf(debug, (char *)0);
63: }
64: top:
65: errno = 0;
66: rval = 0;
67: if (read(0, &c, 1) != 1)
68: exit(0);
69: switch (c) {
70:
71: case 'O':
72: if (tape >= 0)
73: (void) close(tape);
74: getstring(device); getstring(mode);
75: DEBUG2("rmtd: O %s %s\n", device, mode);
76: tape = open(device, atoi(mode));
77: if (tape < 0)
78: goto ioerror;
79: goto respond;
80:
81: case 'C':
82: DEBUG("rmtd: C\n");
83: getstring(device); /* discard */
84: if (close(tape) < 0)
85: goto ioerror;
86: tape = -1;
87: goto respond;
88:
89: case 'L':
90: getstring(count); getstring(pos);
91: DEBUG2("rmtd: L %s %s\n", count, pos);
92: rval = lseek(tape, (long) atoi(count), atoi(pos));
93: if (rval < 0)
94: goto ioerror;
95: goto respond;
96:
97: case 'W':
98: getstring(count);
99: n = atoi(count);
100: DEBUG1("rmtd: W %s\n", count);
101: record = checkbuf(record, n);
102: for (i = 0; i < n; i += cc) {
103: cc = read(0, &record[i], n - i);
104: if (cc <= 0) {
105: DEBUG("rmtd: premature eof\n");
106: exit(2);
107: }
108: }
109: rval = write(tape, record, n);
110: if (rval < 0)
111: goto ioerror;
112: goto respond;
113:
114: case 'R':
115: getstring(count);
116: DEBUG1("rmtd: R %s\n", count);
117: n = atoi(count);
118: record = checkbuf(record, n);
119: rval = read(tape, record, n);
120: if (rval < 0)
121: goto ioerror;
122: (void) sprintf(resp, "A%d\n", rval);
123: (void) write(1, resp, strlen(resp));
124: (void) write(1, record, rval);
125: goto top;
126:
127: case 'I':
128: getstring(op); getstring(count);
129: DEBUG2("rmtd: I %s %s\n", op, count);
130: { struct mtop mtop;
131: mtop.mt_op = atoi(op);
132: mtop.mt_count = atoi(count);
133: if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
134: goto ioerror;
135: rval = mtop.mt_count;
136: }
137: goto respond;
138:
139: case 'S': /* status */
140: DEBUG("rmtd: S\n");
141: { struct mtget mtget;
142: if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
143: goto ioerror;
144: rval = sizeof (mtget);
145: (void) sprintf(resp, "A%d\n", rval);
146: (void) write(1, resp, strlen(resp));
147: (void) write(1, (char *)&mtget, sizeof (mtget));
148: goto top;
149: }
150:
151: default:
152: DEBUG1("rmtd: garbage command %c\n", c);
153: exit(3);
154: }
155: respond:
156: DEBUG1("rmtd: A %d\n", rval);
157: (void) sprintf(resp, "A%d\n", rval);
158: (void) write(1, resp, strlen(resp));
159: goto top;
160: ioerror:
161: error(errno);
162: goto top;
163: }
164:
165: getstring(bp)
166: char *bp;
167: {
168: int i;
169: char *cp = bp;
170:
171: for (i = 0; i < SSIZE; i++) {
172: if (read(0, cp+i, 1) != 1)
173: exit(0);
174: if (cp[i] == '\n')
175: break;
176: }
177: cp[i] = '\0';
178: }
179:
180: char *
181: checkbuf(record, size)
182: char *record;
183: int size;
184: {
185: extern char *malloc();
186:
187: if (size <= maxrecsize)
188: return (record);
189: if (record != 0)
190: free(record);
191: record = malloc(size);
192: if (record == 0) {
193: DEBUG("rmtd: cannot allocate buffer space\n");
194: exit(4);
195: }
196: maxrecsize = size;
197: while (size > 1024 &&
198: setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0)
199: size -= 1024;
200: return (record);
201: }
202:
203: error(num)
204: int num;
205: {
206:
207: DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]);
208: (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]);
209: (void) write(1, resp, strlen (resp));
210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.