|
|
1.1 root 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: /*------------------------------------------------------------------------
33: * Changes to this file:
34: *
35: * a. Change algotrithm of 'S' command to return the A code before
36: * returning anything else. Otherwise, the requester will not
37: * recognize the return code and consider this as a loss of con-
38: * nection. (Peter Pham 09/04/85)
39: *
40: * b. Add 'N' command to allow creation of dev if it doesn't exist.
41: * (This function is neccessary for rtar) (Peter Pham 09/04/85)
42: *
43: * c. Add test to remove newline char of previous command, if any,
44: * Otherwise, the left newline char would be treat as a new command.
45: *----------------------------------------------------------------------*/
46: main(argc, argv)
47: int argc;
48: char **argv;
49: {
50: int rval;
51: char c;
52: int n, i, cc;
53:
54: argc--, argv++;
55: if (argc > 0) {
56: debug = fopen(*argv, "w");
57: if (debug == 0)
58: exit(1);
59: (void) setbuf(debug, (char *)0);
60: }
61: top:
62: errno = 0;
63: rval = 0;
64: if (read(0, &c, 1) != 1)
65: exit(0);
66: if (c == '\n') /* cleanup newline char from previous command */
67: goto top;
68: switch (c) {
69:
70: case 'O':
71: if (tape >= 0)
72: (void) close(tape);
73: gets(device); gets(mode);
74: if (debug) fprintf(debug, "rmtd: O %s %s\n", device, mode);
75: tape = open(device, atoi(mode));
76: if (tape < 0)
77: goto ioerror;
78: goto respond;
79:
80: case 'N':
81: if (tape >= 0)
82: (void) close(tape);
83: gets(device); gets(mode);
84: if (debug) fprintf(debug, "rmtd: N %s %s\n", device, mode);
85: tape = creat(device, atoi(mode));
86: if (tape < 0)
87: goto ioerror;
88: goto respond;
89:
90: case 'C':
91: if (debug) fprintf(debug, "rmtd: C\n");
92: gets(device); /* discard */
93: if (close(tape) < 0)
94: goto ioerror;
95: tape = -1;
96: goto respond;
97:
98: case 'L':
99: gets(count); gets(pos);
100: if (debug) fprintf(debug, "rmtd: L %s %s\n", count, pos);
101: rval = lseek(tape, (long) atoi(count), atoi(pos));
102: if (rval < 0)
103: goto ioerror;
104: goto respond;
105:
106: case 'W':
107: gets(count);
108: n = atoi(count);
109: if (debug) fprintf(debug, "rmtd: W %s\n", count);
110: for (i = 0; i < n; i += cc) {
111: cc = read(0, &record[i], n - i);
112: if (cc <= 0) {
113: if (debug) fprintf(debug, "rmtd: premature eof\n");
114: exit(1);
115: }
116: }
117: rval = write(tape, record, n);
118: if (rval < 0)
119: goto ioerror;
120: goto respond;
121:
122: case 'R':
123: gets(count);
124: if (debug) fprintf(debug, "rmtd: R %s\n", count);
125: n = atoi(count);
126: if (n > sizeof (record))
127: n = sizeof (record);
128: rval = read(tape, record, n);
129: if (rval < 0)
130: goto ioerror;
131: (void) sprintf(resp, "A%d\n", rval);
132: (void) write(1, resp, strlen(resp));
133: (void) write(1, record, rval);
134: goto top;
135:
136: case 'I':
137: gets(op); gets(count);
138: if (debug) fprintf(debug, "rmtd: I %s %s\n", op, count);
139: { struct mtop mtop;
140: mtop.mt_op = atoi(op);
141: mtop.mt_count = atoi(count);
142: if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
143: goto ioerror;
144: rval = mtop.mt_count;
145: }
146: goto respond;
147:
148: case 'S': /* status */
149: if (debug) fprintf(debug, "rmtd: S\n");
150: { struct mtget mtget;
151: if ((rval=ioctl(tape, MTIOCGET, (char *)&mtget)) < 0)
152: goto ioerror;
153: (void) sprintf(resp, "A%d\n", rval);
154: (void) write(1, resp, strlen(resp));
155: (void) write(1, (char *)&mtget, sizeof (mtget));
156: goto top;
157: }
158:
159: default:
160: if (debug) fprintf(debug, "rmtd: garbage command %x\n", c);
161: (void) sprintf(resp, "rmtd: garbage command: %x.\n", c);
162: (void) write(1, resp, strlen (resp));
163: exit(1);
164: }
165: respond:
166: if (debug) fprintf(debug, "rmtd: A %d\n", rval);
167: (void) sprintf(resp, "A%d\n", rval);
168: (void) write(1, resp, strlen(resp));
169: goto top;
170: ioerror:
171: error(errno);
172: goto top;
173: }
174:
175: gets(bp)
176: char *bp;
177: {
178: int i;
179: char *cp = bp;
180:
181: for (i = 0; i < SSIZE; i++) {
182: if (read(0, cp+i, 1) != 1)
183: exit(0);
184: if (cp[i] == '\n')
185: break;
186: }
187: cp[i] = '\0';
188: }
189:
190: error(num)
191: int num;
192: {
193:
194: if (debug) fprintf(debug, "rmtd: E %d (%s)\n", num, sys_errlist[num]);
195: (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]);
196: (void) write(1, resp, strlen (resp));
197: }
198:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.