|
|
1.1 ! root 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: #include <sys/mtio.h> ! 36: #include <errno.h> ! 37: ! 38: int tape = -1; ! 39: ! 40: char *record; ! 41: int maxrecsize = -1; ! 42: char *checkbuf(); ! 43: ! 44: #define SSIZE 64 ! 45: char device[SSIZE]; ! 46: char count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE]; ! 47: ! 48: extern errno; ! 49: char *sys_errlist[]; ! 50: char resp[BUFSIZ]; ! 51: ! 52: long lseek(); ! 53: ! 54: FILE *debug; ! 55: #define DEBUG(f) if (debug) fprintf(debug, f) ! 56: #define DEBUG1(f,a) if (debug) fprintf(debug, f, a) ! 57: #define DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2) ! 58: ! 59: main(argc, argv) ! 60: int argc; ! 61: char **argv; ! 62: { ! 63: int rval; ! 64: char c; ! 65: int n, i, cc; ! 66: ! 67: argc--, argv++; ! 68: if (argc > 0) { ! 69: debug = fopen(*argv, "w"); ! 70: if (debug == 0) ! 71: exit(1); ! 72: (void) setbuf(debug, (char *)0); ! 73: } ! 74: top: ! 75: errno = 0; ! 76: rval = 0; ! 77: if (read(0, &c, 1) != 1) ! 78: exit(0); ! 79: switch (c) { ! 80: ! 81: case 'O': ! 82: if (tape >= 0) ! 83: (void) close(tape); ! 84: getstring(device); getstring(mode); ! 85: DEBUG2("rmtd: O %s %s\n", device, mode); ! 86: tape = open(device, atoi(mode)); ! 87: if (tape < 0) ! 88: goto ioerror; ! 89: goto respond; ! 90: ! 91: case 'C': ! 92: DEBUG("rmtd: C\n"); ! 93: getstring(device); /* discard */ ! 94: if (close(tape) < 0) ! 95: goto ioerror; ! 96: tape = -1; ! 97: goto respond; ! 98: ! 99: case 'L': ! 100: getstring(count); getstring(pos); ! 101: DEBUG2("rmtd: L %s %s\n", count, pos); ! 102: rval = lseek(tape, (long) atoi(count), atoi(pos)); ! 103: if (rval < 0) ! 104: goto ioerror; ! 105: goto respond; ! 106: ! 107: case 'W': ! 108: getstring(count); ! 109: n = atoi(count); ! 110: DEBUG1("rmtd: W %s\n", count); ! 111: record = checkbuf(record, n); ! 112: for (i = 0; i < n; i += cc) { ! 113: cc = read(0, &record[i], n - i); ! 114: if (cc <= 0) { ! 115: DEBUG("rmtd: premature eof\n"); ! 116: exit(2); ! 117: } ! 118: } ! 119: rval = write(tape, record, n); ! 120: if (rval < 0) ! 121: goto ioerror; ! 122: goto respond; ! 123: ! 124: case 'R': ! 125: getstring(count); ! 126: DEBUG1("rmtd: R %s\n", count); ! 127: n = atoi(count); ! 128: record = checkbuf(record, n); ! 129: rval = read(tape, record, n); ! 130: if (rval < 0) ! 131: goto ioerror; ! 132: (void) sprintf(resp, "A%d\n", rval); ! 133: (void) write(1, resp, strlen(resp)); ! 134: (void) write(1, record, rval); ! 135: goto top; ! 136: ! 137: case 'I': ! 138: getstring(op); getstring(count); ! 139: DEBUG2("rmtd: I %s %s\n", op, count); ! 140: { struct mtop mtop; ! 141: mtop.mt_op = atoi(op); ! 142: mtop.mt_count = atoi(count); ! 143: if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0) ! 144: goto ioerror; ! 145: rval = mtop.mt_count; ! 146: } ! 147: goto respond; ! 148: ! 149: case 'S': /* status */ ! 150: DEBUG("rmtd: S\n"); ! 151: { struct mtget mtget; ! 152: if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0) ! 153: goto ioerror; ! 154: rval = sizeof (mtget); ! 155: (void) sprintf(resp, "A%d\n", rval); ! 156: (void) write(1, resp, strlen(resp)); ! 157: (void) write(1, (char *)&mtget, sizeof (mtget)); ! 158: goto top; ! 159: } ! 160: ! 161: default: ! 162: DEBUG1("rmtd: garbage command %c\n", c); ! 163: exit(3); ! 164: } ! 165: respond: ! 166: DEBUG1("rmtd: A %d\n", rval); ! 167: (void) sprintf(resp, "A%d\n", rval); ! 168: (void) write(1, resp, strlen(resp)); ! 169: goto top; ! 170: ioerror: ! 171: error(errno); ! 172: goto top; ! 173: } ! 174: ! 175: getstring(bp) ! 176: char *bp; ! 177: { ! 178: int i; ! 179: char *cp = bp; ! 180: ! 181: for (i = 0; i < SSIZE; i++) { ! 182: if (read(0, cp+i, 1) != 1) ! 183: exit(0); ! 184: if (cp[i] == '\n') ! 185: break; ! 186: } ! 187: cp[i] = '\0'; ! 188: } ! 189: ! 190: char * ! 191: checkbuf(record, size) ! 192: char *record; ! 193: int size; ! 194: { ! 195: extern char *malloc(); ! 196: ! 197: if (size <= maxrecsize) ! 198: return (record); ! 199: if (record != 0) ! 200: free(record); ! 201: record = malloc(size); ! 202: if (record == 0) { ! 203: DEBUG("rmtd: cannot allocate buffer space\n"); ! 204: exit(4); ! 205: } ! 206: maxrecsize = size; ! 207: while (size > 1024 && ! 208: setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0) ! 209: size -= 1024; ! 210: return (record); ! 211: } ! 212: ! 213: error(num) ! 214: int num; ! 215: { ! 216: ! 217: DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]); ! 218: (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]); ! 219: (void) write(1, resp, strlen (resp)); ! 220: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.