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.2 (Berkeley) 1/7/86"; 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: maxrecsize = size; 197: while (size > 1024 && 198: setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0) 199: size -= 1024; 200: return (record); 201: } 202: 203: error(num) 204: int num; 205: { 206: 207: DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]); 208: (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]); 209: (void) write(1, resp, strlen (resp)); 210: }