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