make sleep spin-wait during autoconfiguration
[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
eacc5e23 14static char sccsid[] = "@(#)rmt.c 5.2 (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
41char *sprintf();
42long lseek();
43
44FILE *debug;
70cb830c
SL
45#define DEBUG(f) if (debug) fprintf(debug, f)
46#define DEBUG1(f,a) if (debug) fprintf(debug, f, a)
47#define DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2)
ca880174
BJ
48
49main(argc, argv)
50 int argc;
51 char **argv;
52{
09b7833f 53 int rval;
ca880174
BJ
54 char c;
55 int n, i, cc;
56
57 argc--, argv++;
58 if (argc > 0) {
59 debug = fopen(*argv, "w");
60 if (debug == 0)
61 exit(1);
62 (void) setbuf(debug, (char *)0);
63 }
64top:
65 errno = 0;
66 rval = 0;
67 if (read(0, &c, 1) != 1)
68 exit(0);
69 switch (c) {
70
71 case 'O':
72 if (tape >= 0)
73 (void) close(tape);
70cb830c
SL
74 getstring(device); getstring(mode);
75 DEBUG2("rmtd: O %s %s\n", device, mode);
ca880174
BJ
76 tape = open(device, atoi(mode));
77 if (tape < 0)
78 goto ioerror;
beb54976 79 goto respond;
ca880174
BJ
80
81 case 'C':
70cb830c
SL
82 DEBUG("rmtd: C\n");
83 getstring(device); /* discard */
ca880174
BJ
84 if (close(tape) < 0)
85 goto ioerror;
86 tape = -1;
beb54976 87 goto respond;
ca880174
BJ
88
89 case 'L':
70cb830c
SL
90 getstring(count); getstring(pos);
91 DEBUG2("rmtd: L %s %s\n", count, pos);
ca880174
BJ
92 rval = lseek(tape, (long) atoi(count), atoi(pos));
93 if (rval < 0)
94 goto ioerror;
beb54976 95 goto respond;
ca880174
BJ
96
97 case 'W':
70cb830c 98 getstring(count);
ca880174 99 n = atoi(count);
70cb830c 100 DEBUG1("rmtd: W %s\n", count);
d2f2b385 101 record = checkbuf(record, n);
ca880174
BJ
102 for (i = 0; i < n; i += cc) {
103 cc = read(0, &record[i], n - i);
104 if (cc <= 0) {
70cb830c 105 DEBUG("rmtd: premature eof\n");
d2f2b385 106 exit(2);
ca880174
BJ
107 }
108 }
109 rval = write(tape, record, n);
110 if (rval < 0)
111 goto ioerror;
beb54976 112 goto respond;
ca880174
BJ
113
114 case 'R':
70cb830c
SL
115 getstring(count);
116 DEBUG1("rmtd: R %s\n", count);
ca880174 117 n = atoi(count);
d2f2b385 118 record = checkbuf(record, n);
ca880174
BJ
119 rval = read(tape, record, n);
120 if (rval < 0)
121 goto ioerror;
beb54976
KM
122 (void) sprintf(resp, "A%d\n", rval);
123 (void) write(1, resp, strlen(resp));
124 (void) write(1, record, rval);
125 goto top;
ca880174
BJ
126
127 case 'I':
70cb830c
SL
128 getstring(op); getstring(count);
129 DEBUG2("rmtd: I %s %s\n", op, count);
ca880174
BJ
130 { struct mtop mtop;
131 mtop.mt_op = atoi(op);
132 mtop.mt_count = atoi(count);
133 if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
134 goto ioerror;
135 rval = mtop.mt_count;
136 }
beb54976 137 goto respond;
ca880174
BJ
138
139 case 'S': /* status */
70cb830c 140 DEBUG("rmtd: S\n");
ca880174
BJ
141 { struct mtget mtget;
142 if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
143 goto ioerror;
144 rval = sizeof (mtget);
40b76363
RC
145 (void) sprintf(resp, "A%d\n", rval);
146 (void) write(1, resp, strlen(resp));
ca880174 147 (void) write(1, (char *)&mtget, sizeof (mtget));
40b76363 148 goto top;
ca880174
BJ
149 }
150
151 default:
70cb830c 152 DEBUG1("rmtd: garbage command %c\n", c);
d2f2b385 153 exit(3);
ca880174 154 }
beb54976 155respond:
70cb830c 156 DEBUG1("rmtd: A %d\n", rval);
ca880174
BJ
157 (void) sprintf(resp, "A%d\n", rval);
158 (void) write(1, resp, strlen(resp));
159 goto top;
160ioerror:
161 error(errno);
162 goto top;
163}
164
70cb830c 165getstring(bp)
ca880174
BJ
166 char *bp;
167{
168 int i;
169 char *cp = bp;
170
171 for (i = 0; i < SSIZE; i++) {
172 if (read(0, cp+i, 1) != 1)
173 exit(0);
174 if (cp[i] == '\n')
175 break;
176 }
177 cp[i] = '\0';
178}
179
d2f2b385
KM
180char *
181checkbuf(record, size)
182 char *record;
183 int size;
184{
185 extern char *malloc();
186
187 if (size <= maxrecsize)
188 return (record);
189 if (record != 0)
190 free(record);
191 record = malloc(size);
192 if (record == 0) {
193 DEBUG("rmtd: cannot allocate buffer space\n");
194 exit(4);
195 }
eacc5e23 196 maxrecsize = size;
c18a7664
KM
197 while (size > 1024 &&
198 setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0)
199 size -= 1024;
d2f2b385
KM
200 return (record);
201}
202
ca880174
BJ
203error(num)
204 int num;
205{
206
70cb830c 207 DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]);
ca880174
BJ
208 (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]);
209 (void) write(1, resp, strlen (resp));
210}