BSD 4_3_Tahoe release
[unix-history] / usr / src / etc / rmt.c
CommitLineData
8c5eec2f
DF
1/*
2 * Copyright (c) 1983 Regents of the University of California.
a4fb2c81
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
8c5eec2f
DF
16 */
17
18#ifndef lint
19char copyright[] =
20"@(#) Copyright (c) 1983 Regents of the University of California.\n\
21 All rights reserved.\n";
a4fb2c81 22#endif /* not lint */
8c5eec2f 23
ca880174 24#ifndef lint
ca67e7b4 25static char sccsid[] = "@(#)rmt.c 5.4 (Berkeley) 6/29/88";
a4fb2c81 26#endif /* not lint */
ca880174
BJ
27
28/*
29 * rmt
30 */
31#include <stdio.h>
32#include <sgtty.h>
33#include <sys/types.h>
2622d866 34#include <sys/socket.h>
ca880174
BJ
35#include <sys/mtio.h>
36#include <errno.h>
37
38int tape = -1;
39
d2f2b385
KM
40char *record;
41int maxrecsize = -1;
42char *checkbuf();
ca880174
BJ
43
44#define SSIZE 64
45char device[SSIZE];
46char count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
47
48extern errno;
49char *sys_errlist[];
50char resp[BUFSIZ];
51
ca880174
BJ
52long lseek();
53
54FILE *debug;
70cb830c
SL
55#define DEBUG(f) if (debug) fprintf(debug, f)
56#define DEBUG1(f,a) if (debug) fprintf(debug, f, a)
57#define DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2)
ca880174
BJ
58
59main(argc, argv)
60 int argc;
61 char **argv;
62{
09b7833f 63 int rval;
ca880174
BJ
64 char c;
65 int n, i, cc;
66
67 argc--, argv++;
68 if (argc > 0) {
69 debug = fopen(*argv, "w");
70 if (debug == 0)
71 exit(1);
72 (void) setbuf(debug, (char *)0);
73 }
74top:
75 errno = 0;
76 rval = 0;
77 if (read(0, &c, 1) != 1)
78 exit(0);
79 switch (c) {
80
81 case 'O':
82 if (tape >= 0)
83 (void) close(tape);
70cb830c
SL
84 getstring(device); getstring(mode);
85 DEBUG2("rmtd: O %s %s\n", device, mode);
ca880174
BJ
86 tape = open(device, atoi(mode));
87 if (tape < 0)
88 goto ioerror;
beb54976 89 goto respond;
ca880174
BJ
90
91 case 'C':
70cb830c
SL
92 DEBUG("rmtd: C\n");
93 getstring(device); /* discard */
ca880174
BJ
94 if (close(tape) < 0)
95 goto ioerror;
96 tape = -1;
beb54976 97 goto respond;
ca880174
BJ
98
99 case 'L':
70cb830c
SL
100 getstring(count); getstring(pos);
101 DEBUG2("rmtd: L %s %s\n", count, pos);
ca880174
BJ
102 rval = lseek(tape, (long) atoi(count), atoi(pos));
103 if (rval < 0)
104 goto ioerror;
beb54976 105 goto respond;
ca880174
BJ
106
107 case 'W':
70cb830c 108 getstring(count);
ca880174 109 n = atoi(count);
70cb830c 110 DEBUG1("rmtd: W %s\n", count);
d2f2b385 111 record = checkbuf(record, n);
ca880174
BJ
112 for (i = 0; i < n; i += cc) {
113 cc = read(0, &record[i], n - i);
114 if (cc <= 0) {
70cb830c 115 DEBUG("rmtd: premature eof\n");
d2f2b385 116 exit(2);
ca880174
BJ
117 }
118 }
119 rval = write(tape, record, n);
120 if (rval < 0)
121 goto ioerror;
beb54976 122 goto respond;
ca880174
BJ
123
124 case 'R':
70cb830c
SL
125 getstring(count);
126 DEBUG1("rmtd: R %s\n", count);
ca880174 127 n = atoi(count);
d2f2b385 128 record = checkbuf(record, n);
ca880174
BJ
129 rval = read(tape, record, n);
130 if (rval < 0)
131 goto ioerror;
beb54976
KM
132 (void) sprintf(resp, "A%d\n", rval);
133 (void) write(1, resp, strlen(resp));
134 (void) write(1, record, rval);
135 goto top;
ca880174
BJ
136
137 case 'I':
70cb830c
SL
138 getstring(op); getstring(count);
139 DEBUG2("rmtd: I %s %s\n", op, count);
ca880174
BJ
140 { struct mtop mtop;
141 mtop.mt_op = atoi(op);
142 mtop.mt_count = atoi(count);
143 if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
144 goto ioerror;
145 rval = mtop.mt_count;
146 }
beb54976 147 goto respond;
ca880174
BJ
148
149 case 'S': /* status */
70cb830c 150 DEBUG("rmtd: S\n");
ca880174
BJ
151 { struct mtget mtget;
152 if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
153 goto ioerror;
154 rval = sizeof (mtget);
40b76363
RC
155 (void) sprintf(resp, "A%d\n", rval);
156 (void) write(1, resp, strlen(resp));
ca880174 157 (void) write(1, (char *)&mtget, sizeof (mtget));
40b76363 158 goto top;
ca880174
BJ
159 }
160
161 default:
70cb830c 162 DEBUG1("rmtd: garbage command %c\n", c);
d2f2b385 163 exit(3);
ca880174 164 }
beb54976 165respond:
70cb830c 166 DEBUG1("rmtd: A %d\n", rval);
ca880174
BJ
167 (void) sprintf(resp, "A%d\n", rval);
168 (void) write(1, resp, strlen(resp));
169 goto top;
170ioerror:
171 error(errno);
172 goto top;
173}
174
70cb830c 175getstring(bp)
ca880174
BJ
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
d2f2b385
KM
190char *
191checkbuf(record, size)
192 char *record;
193 int size;
194{
195 extern char *malloc();
196
197 if (size <= maxrecsize)
198 return (record);
199 if (record != 0)
200 free(record);
201 record = malloc(size);
202 if (record == 0) {
203 DEBUG("rmtd: cannot allocate buffer space\n");
204 exit(4);
205 }
eacc5e23 206 maxrecsize = size;
c18a7664
KM
207 while (size > 1024 &&
208 setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0)
209 size -= 1024;
d2f2b385
KM
210 return (record);
211}
212
ca880174
BJ
213error(num)
214 int num;
215{
216
70cb830c 217 DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]);
ca880174
BJ
218 (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]);
219 (void) write(1, resp, strlen (resp));
220}