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 8 char copyright[] = 9 "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10 All rights reserved.\n"; 11 #endif not lint 12 13 #ifndef lint 14 static char sccsid[] = "@(#)rmt.c 5.1 (Berkeley) 05/28/85"; 15 #endif not lint 16 17 /* 18 * rmt 19 */ 20 #include <stdio.h> 21 #include <sgtty.h> 22 #include <sys/types.h> 23 #include <sys/socket.h> 24 #include <sys/mtio.h> 25 #include <errno.h> 26 27 int tape = -1; 28 29 char *record; 30 int maxrecsize = -1; 31 char *checkbuf(); 32 33 #define SSIZE 64 34 char device[SSIZE]; 35 char count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE]; 36 37 extern errno; 38 char *sys_errlist[]; 39 char resp[BUFSIZ]; 40 41 char *sprintf(); 42 long lseek(); 43 44 FILE *debug; 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) 48 49 main(argc, argv) 50 int argc; 51 char **argv; 52 { 53 int rval; 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 } 64 top: 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); 74 getstring(device); getstring(mode); 75 DEBUG2("rmtd: O %s %s\n", device, mode); 76 tape = open(device, atoi(mode)); 77 if (tape < 0) 78 goto ioerror; 79 goto respond; 80 81 case 'C': 82 DEBUG("rmtd: C\n"); 83 getstring(device); /* discard */ 84 if (close(tape) < 0) 85 goto ioerror; 86 tape = -1; 87 goto respond; 88 89 case 'L': 90 getstring(count); getstring(pos); 91 DEBUG2("rmtd: L %s %s\n", count, pos); 92 rval = lseek(tape, (long) atoi(count), atoi(pos)); 93 if (rval < 0) 94 goto ioerror; 95 goto respond; 96 97 case 'W': 98 getstring(count); 99 n = atoi(count); 100 DEBUG1("rmtd: W %s\n", count); 101 record = checkbuf(record, n); 102 for (i = 0; i < n; i += cc) { 103 cc = read(0, &record[i], n - i); 104 if (cc <= 0) { 105 DEBUG("rmtd: premature eof\n"); 106 exit(2); 107 } 108 } 109 rval = write(tape, record, n); 110 if (rval < 0) 111 goto ioerror; 112 goto respond; 113 114 case 'R': 115 getstring(count); 116 DEBUG1("rmtd: R %s\n", count); 117 n = atoi(count); 118 record = checkbuf(record, n); 119 rval = read(tape, record, n); 120 if (rval < 0) 121 goto ioerror; 122 (void) sprintf(resp, "A%d\n", rval); 123 (void) write(1, resp, strlen(resp)); 124 (void) write(1, record, rval); 125 goto top; 126 127 case 'I': 128 getstring(op); getstring(count); 129 DEBUG2("rmtd: I %s %s\n", op, count); 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 } 137 goto respond; 138 139 case 'S': /* status */ 140 DEBUG("rmtd: S\n"); 141 { struct mtget mtget; 142 if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0) 143 goto ioerror; 144 rval = sizeof (mtget); 145 (void) sprintf(resp, "A%d\n", rval); 146 (void) write(1, resp, strlen(resp)); 147 (void) write(1, (char *)&mtget, sizeof (mtget)); 148 goto top; 149 } 150 151 default: 152 DEBUG1("rmtd: garbage command %c\n", c); 153 exit(3); 154 } 155 respond: 156 DEBUG1("rmtd: A %d\n", rval); 157 (void) sprintf(resp, "A%d\n", rval); 158 (void) write(1, resp, strlen(resp)); 159 goto top; 160 ioerror: 161 error(errno); 162 goto top; 163 } 164 165 getstring(bp) 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 180 char * 181 checkbuf(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 } 196 while (size > 1024 && 197 setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0) 198 size -= 1024; 199 return (record); 200 } 201 202 error(num) 203 int num; 204 { 205 206 DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]); 207 (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]); 208 (void) write(1, resp, strlen (resp)); 209 } 210