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