convert to understand dynamic file systems
[unix-history] / usr / src / usr.sbin / rmt / rmt.c
CommitLineData
8c5eec2f
DF
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
8char copyright[] =
9"@(#) Copyright (c) 1983 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
ca880174 13#ifndef lint
9bd38ba8 14static char sccsid[] = "@(#)rmt.c 5.3 (Berkeley) %G%";
8c5eec2f 15#endif not lint
ca880174
BJ
16
17/*
18 * rmt
19 */
20#include <stdio.h>
21#include <sgtty.h>
22#include <sys/types.h>
2622d866 23#include <sys/socket.h>
ca880174
BJ
24#include <sys/mtio.h>
25#include <errno.h>
26
27int tape = -1;
28
d2f2b385
KM
29char *record;
30int maxrecsize = -1;
31char *checkbuf();
ca880174
BJ
32
33#define SSIZE 64
34char device[SSIZE];
35char count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
36
37extern errno;
38char *sys_errlist[];
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
70cb830c 206 DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]);
ca880174
BJ
207 (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]);
208 (void) write(1, resp, strlen (resp));
209}