1 /* $NetBSD: rmt.c,v 1.15 2008/07/21 13:36:59 lukem Exp $ */
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
34 __COPYRIGHT("@(#) Copyright (c) 1983, 1993\
35 The Regents of the University of California. All rights reserved.");
40 static char sccsid
[] = "@(#)rmt.c 8.1 (Berkeley) 6/6/93";
42 __RCSID("$NetBSD: rmt.c,v 1.15 2008/07/21 13:36:59 lukem Exp $");
49 #include <sys/types.h>
50 #include <sys/ioctl.h>
52 #include <sys/socket.h>
68 char count
[SSIZE
], mode
[SSIZE
], pos
[SSIZE
], op
[SSIZE
];
73 #define DEBUG(f) if (debug) fprintf(debug, f)
74 #define DEBUG1(f,a) if (debug) fprintf(debug, f, a)
75 #define DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2)
77 char *checkbuf
__P((char *, int));
78 void error
__P((int));
79 int main
__P((int, char **));
80 void getstring
__P((char *, size_t));
94 debug
= fopen(*argv
, "w");
97 (void)setbuf(debug
, (char *)0);
102 if (read(STDIN_FILENO
, &c
, 1) != 1)
109 getstring(device
, sizeof(device
));
110 getstring(mode
, sizeof(mode
));
111 DEBUG2("rmtd: O %s %s\n", device
, mode
);
112 tape
= open(device
, atoi(mode
),
113 S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IWGRP
|S_IROTH
|S_IWOTH
);
120 getstring(device
, sizeof(device
)); /* discard */
127 getstring(count
, sizeof(count
));
128 getstring(pos
, sizeof(pos
));
129 DEBUG2("rmtd: L %s %s\n", count
, pos
);
130 rval
= lseek(tape
, (off_t
)strtoll(count
, NULL
, 10), atoi(pos
));
136 getstring(count
, sizeof(count
));
138 DEBUG1("rmtd: W %s\n", count
);
139 record
= checkbuf(record
, n
);
140 for (i
= 0; i
< n
; i
+= cc
) {
141 cc
= read(STDIN_FILENO
, &record
[i
], n
- i
);
143 DEBUG("rmtd: premature eof\n");
147 rval
= write(tape
, record
, n
);
153 getstring(count
, sizeof(count
));
154 DEBUG1("rmtd: R %s\n", count
);
156 record
= checkbuf(record
, n
);
157 rval
= read(tape
, record
, n
);
160 (void)snprintf(resp
, sizeof(resp
), "A%d\n", rval
);
161 (void)write(STDOUT_FILENO
, resp
, strlen(resp
));
162 (void)write(STDOUT_FILENO
, record
, rval
);
166 getstring(op
, sizeof(op
));
167 getstring(count
, sizeof(count
));
168 DEBUG2("rmtd: I %s %s\n", op
, count
);
172 mtop
.mt_op
= atoi(op
);
173 mtop
.mt_count
= atoi(count
);
174 if (ioctl(tape
, MTIOCTOP
, (char *)&mtop
) < 0)
176 rval
= mtop
.mt_count
;
180 case 'S': /* status */
185 if (ioctl(tape
, MTIOCGET
, (char *)&mtget
) < 0)
187 rval
= sizeof (mtget
);
188 /* limit size to 'original' mtget size */
191 (void)snprintf(resp
, sizeof(resp
), "A%d\n", rval
);
192 (void)write(STDOUT_FILENO
, resp
, strlen(resp
));
193 (void)write(STDOUT_FILENO
, (char *)&mtget
, rval
);
198 DEBUG1("rmtd: garbage command %c\n", c
);
202 DEBUG1("rmtd: A %d\n", rval
);
203 (void)snprintf(resp
, sizeof(resp
), "A%d\n", rval
);
204 (void)write(STDOUT_FILENO
, resp
, strlen(resp
));
217 char *ep
= bp
+ size
- 1;
220 if (read(STDIN_FILENO
, cp
, 1) != 1)
222 } while (*cp
!= '\n' && ++cp
< ep
);
227 checkbuf(record
, size
)
232 if (size
<= maxrecsize
)
236 record
= malloc(size
);
238 DEBUG("rmtd: cannot allocate buffer space\n");
242 while (size
> 1024 &&
243 setsockopt(0, SOL_SOCKET
, SO_RCVBUF
, &size
, sizeof (size
)) < 0)
253 DEBUG2("rmtd: E %d (%s)\n", num
, strerror(num
));
254 (void)snprintf(resp
, sizeof(resp
), "E%d\n%s\n", num
, strerror(num
));
255 (void)write(STDOUT_FILENO
, resp
, strlen(resp
));