|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)rmt.c 5.6 (Berkeley) 6/1/90";
28: #endif /* not lint */
29:
30: /*
31: * rmt
32: */
33: #include <stdio.h>
34: #include <sgtty.h>
35: #include <sys/types.h>
36: #include <sys/socket.h>
37: #include <sys/mtio.h>
38: #include <errno.h>
39: #include <string.h>
40:
41: int tape = -1;
42:
43: char *record;
44: int maxrecsize = -1;
45: char *checkbuf();
46:
47: #define SSIZE 64
48: char device[SSIZE];
49: char count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
50:
51: char resp[BUFSIZ];
52:
53: long lseek();
54:
55: FILE *debug;
56: #define DEBUG(f) if (debug) fprintf(debug, f)
57: #define DEBUG1(f,a) if (debug) fprintf(debug, f, a)
58: #define DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2)
59:
60: main(argc, argv)
61: int argc;
62: char **argv;
63: {
64: int rval;
65: char c;
66: int n, i, cc;
67:
68: argc--, argv++;
69: if (argc > 0) {
70: debug = fopen(*argv, "w");
71: if (debug == 0)
72: exit(1);
73: (void) setbuf(debug, (char *)0);
74: }
75: top:
76: errno = 0;
77: rval = 0;
78: if (read(0, &c, 1) != 1)
79: exit(0);
80: switch (c) {
81:
82: case 'O':
83: if (tape >= 0)
84: (void) close(tape);
85: getstring(device); getstring(mode);
86: DEBUG2("rmtd: O %s %s\n", device, mode);
87: tape = open(device, atoi(mode));
88: if (tape < 0)
89: goto ioerror;
90: goto respond;
91:
92: case 'C':
93: DEBUG("rmtd: C\n");
94: getstring(device); /* discard */
95: if (close(tape) < 0)
96: goto ioerror;
97: tape = -1;
98: goto respond;
99:
100: case 'L':
101: getstring(count); getstring(pos);
102: DEBUG2("rmtd: L %s %s\n", count, pos);
103: rval = lseek(tape, (long) atoi(count), atoi(pos));
104: if (rval < 0)
105: goto ioerror;
106: goto respond;
107:
108: case 'W':
109: getstring(count);
110: n = atoi(count);
111: DEBUG1("rmtd: W %s\n", count);
112: record = checkbuf(record, n);
113: for (i = 0; i < n; i += cc) {
114: cc = read(0, &record[i], n - i);
115: if (cc <= 0) {
116: DEBUG("rmtd: premature eof\n");
117: exit(2);
118: }
119: }
120: rval = write(tape, record, n);
121: if (rval < 0)
122: goto ioerror;
123: goto respond;
124:
125: case 'R':
126: getstring(count);
127: DEBUG1("rmtd: R %s\n", count);
128: n = atoi(count);
129: record = checkbuf(record, n);
130: rval = read(tape, record, n);
131: if (rval < 0)
132: goto ioerror;
133: (void) sprintf(resp, "A%d\n", rval);
134: (void) write(1, resp, strlen(resp));
135: (void) write(1, record, rval);
136: goto top;
137:
138: case 'I':
139: getstring(op); getstring(count);
140: DEBUG2("rmtd: I %s %s\n", op, count);
141: { struct mtop mtop;
142: mtop.mt_op = atoi(op);
143: mtop.mt_count = atoi(count);
144: if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
145: goto ioerror;
146: rval = mtop.mt_count;
147: }
148: goto respond;
149:
150: case 'S': /* status */
151: DEBUG("rmtd: S\n");
152: { struct mtget mtget;
153: if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
154: goto ioerror;
155: rval = sizeof (mtget);
156: (void) sprintf(resp, "A%d\n", rval);
157: (void) write(1, resp, strlen(resp));
158: (void) write(1, (char *)&mtget, sizeof (mtget));
159: goto top;
160: }
161:
162: default:
163: DEBUG1("rmtd: garbage command %c\n", c);
164: exit(3);
165: }
166: respond:
167: DEBUG1("rmtd: A %d\n", rval);
168: (void) sprintf(resp, "A%d\n", rval);
169: (void) write(1, resp, strlen(resp));
170: goto top;
171: ioerror:
172: error(errno);
173: goto top;
174: }
175:
176: getstring(bp)
177: char *bp;
178: {
179: int i;
180: char *cp = bp;
181:
182: for (i = 0; i < SSIZE; i++) {
183: if (read(0, cp+i, 1) != 1)
184: exit(0);
185: if (cp[i] == '\n')
186: break;
187: }
188: cp[i] = '\0';
189: }
190:
191: char *
192: checkbuf(record, size)
193: char *record;
194: int size;
195: {
196: extern char *malloc();
197:
198: if (size <= maxrecsize)
199: return (record);
200: if (record != 0)
201: free(record);
202: record = malloc(size);
203: if (record == 0) {
204: DEBUG("rmtd: cannot allocate buffer space\n");
205: exit(4);
206: }
207: maxrecsize = size;
208: while (size > 1024 &&
209: setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0)
210: size -= 1024;
211: return (record);
212: }
213:
214: error(num)
215: int num;
216: {
217:
218: DEBUG2("rmtd: E %d (%s)\n", num, strerror(num));
219: (void) sprintf(resp, "E%d\n%s\n", num, strerror(num));
220: (void) write(1, resp, strlen(resp));
221: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.