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