]> Dogcows Code - chaz/tar/blob - src/rmt.c
*** empty log message ***
[chaz/tar] / src / rmt.c
1 /*
2 * Copyright (c) 1983 Regents of the University of California.
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.
16 */
17
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1983 Regents of the University of California.\n\
21 All rights reserved.\n";
22 #endif /* not lint */
23
24 #ifndef lint
25 static char sccsid[] = "@(#)rmt.c 5.4 (Berkeley) 6/29/88";
26 #endif /* not lint */
27
28 /*
29 * rmt
30 */
31 #include <stdio.h>
32 #include <sgtty.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #ifdef GENTAPE /* e.g. ISC UNIX */
36 #include <sys/gentape.h>
37 #else
38 #include <sys/mtio.h>
39 #endif
40 #include <errno.h>
41
42 #if defined (i386) && defined (AIX)
43 #include <fcntl.h>
44 #endif
45
46 int tape = -1;
47
48 char *record;
49 int maxrecsize = -1;
50 char *checkbuf();
51
52 #define SSIZE 64
53 char device[SSIZE];
54 char count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
55
56 extern errno;
57 extern char *sys_errlist[];
58 char resp[BUFSIZ];
59
60 long lseek();
61
62 FILE *debug;
63 #define DEBUG(f) if (debug) fprintf(debug, f)
64 #define DEBUG1(f,a) if (debug) fprintf(debug, f, a)
65 #define DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2)
66
67 main(argc, argv)
68 int argc;
69 char **argv;
70 {
71 int rval;
72 char c;
73 int n, i, cc;
74
75 argc--, argv++;
76 if (argc > 0) {
77 debug = fopen(*argv, "w");
78 if (debug == 0)
79 exit(1);
80 (void) setbuf(debug, (char *)0);
81 }
82 top:
83 errno = 0;
84 rval = 0;
85 if (read(0, &c, 1) != 1)
86 exit(0);
87 switch (c) {
88
89 case 'O':
90 if (tape >= 0)
91 (void) close(tape);
92 getstring(device); getstring(mode);
93 DEBUG2("rmtd: O %s %s\n", device, mode);
94 #if defined (i386) && defined (AIX)
95 /* This is alleged to fix a byte ordering problem. */
96 /* I'm quite suspicious if it's right. -- mib */
97 {
98 int oflag = atoi (mode);
99 int nflag = 0;
100 if ((oflag & 3) == 0)
101 nflag |= O_RDONLY;
102 if (oflag & 1)
103 nflag |= O_WRONLY;
104 if (oflag & 2)
105 nflag |= O_RDWR;
106 if (oflag & 0x0008)
107 nflag |= O_APPEND;
108 if (oflag & 0x0200)
109 nflag |= O_CREAT;
110 if (oflag & 0x0400)
111 nflag |= O_TRUNC;
112 if (oflag & 0x0800)
113 nflag |= O_EXCL;
114 tape = open (device, nflag, 0666);
115 }
116 #else
117 tape = open(device, atoi(mode),0666);
118 #endif
119 if (tape < 0)
120 goto ioerror;
121 goto respond;
122
123 case 'C':
124 DEBUG("rmtd: C\n");
125 getstring(device); /* discard */
126 if (close(tape) < 0)
127 goto ioerror;
128 tape = -1;
129 goto respond;
130
131 case 'L':
132 getstring(count); getstring(pos);
133 DEBUG2("rmtd: L %s %s\n", count, pos);
134 rval = lseek(tape, (long) atoi(count), atoi(pos));
135 if (rval < 0)
136 goto ioerror;
137 goto respond;
138
139 case 'W':
140 getstring(count);
141 n = atoi(count);
142 DEBUG1("rmtd: W %s\n", count);
143 record = checkbuf(record, n);
144 for (i = 0; i < n; i += cc) {
145 cc = read(0, &record[i], n - i);
146 if (cc <= 0) {
147 DEBUG("rmtd: premature eof\n");
148 exit(2);
149 }
150 }
151 rval = write(tape, record, n);
152 if (rval < 0)
153 goto ioerror;
154 goto respond;
155
156 case 'R':
157 getstring(count);
158 DEBUG1("rmtd: R %s\n", count);
159 n = atoi(count);
160 record = checkbuf(record, n);
161 rval = read(tape, record, n);
162 if (rval < 0)
163 goto ioerror;
164 (void) sprintf(resp, "A%d\n", rval);
165 (void) write(1, resp, strlen(resp));
166 (void) write(1, record, rval);
167 goto top;
168
169 case 'I':
170 getstring(op); getstring(count);
171 DEBUG2("rmtd: I %s %s\n", op, count);
172 #ifdef MTIOCTOP
173 { struct mtop mtop;
174 mtop.mt_op = atoi(op);
175 mtop.mt_count = atoi(count);
176 if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
177 goto ioerror;
178 rval = mtop.mt_count;
179 }
180 #endif
181 goto respond;
182
183 case 'S': /* status */
184 DEBUG("rmtd: S\n");
185 {
186 #ifdef MTIOCGET
187 struct mtget mtget;
188 if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
189 goto ioerror;
190 rval = sizeof (mtget);
191 (void) sprintf(resp, "A%d\n", rval);
192 (void) write(1, resp, strlen(resp));
193 (void) write(1, (char *)&mtget, sizeof (mtget));
194 #endif
195 goto top;
196 }
197
198 default:
199 DEBUG1("rmtd: garbage command %c\n", c);
200 exit(3);
201 }
202 respond:
203 DEBUG1("rmtd: A %d\n", rval);
204 (void) sprintf(resp, "A%d\n", rval);
205 (void) write(1, resp, strlen(resp));
206 goto top;
207 ioerror:
208 error(errno);
209 goto top;
210 }
211
212 getstring(bp)
213 char *bp;
214 {
215 int i;
216 char *cp = bp;
217
218 for (i = 0; i < SSIZE; i++) {
219 if (read(0, cp+i, 1) != 1)
220 exit(0);
221 if (cp[i] == '\n')
222 break;
223 }
224 cp[i] = '\0';
225 }
226
227 char *
228 checkbuf(record, size)
229 char *record;
230 int size;
231 {
232 extern char *malloc();
233
234 if (size <= maxrecsize)
235 return (record);
236 if (record != 0)
237 free(record);
238 record = malloc(size);
239 if (record == 0) {
240 DEBUG("rmtd: cannot allocate buffer space\n");
241 exit(4);
242 }
243 maxrecsize = size;
244 #ifdef SO_RCVBUF
245 while (size > 1024 &&
246 setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0)
247 size -= 1024;
248 #else
249 size= 1+((size-1)%1024);
250 #endif
251 return (record);
252 }
253
254 error(num)
255 int num;
256 {
257
258 DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]);
259 (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]);
260 (void) write(1, resp, strlen (resp));
261 }
This page took 0.04694 seconds and 5 git commands to generate.