16448Swnj #ifndef lint 2*17537Sralph static char sccsid[] = "@(#)rmt.c 4.5 (Berkeley) 84/12/19"; 36448Swnj #endif 46448Swnj 56448Swnj /* 66448Swnj * rmt 76448Swnj */ 86448Swnj #include <stdio.h> 96448Swnj #include <sgtty.h> 106448Swnj #include <sys/types.h> 11*17537Sralph #include <sys/socket.h> 126448Swnj #include <sys/mtio.h> 136448Swnj #include <errno.h> 146448Swnj 156448Swnj int tape = -1; 166448Swnj 176560Smckusick #define MAXRECSIZ (10*1024) /* small enuf for pdp-11's too */ 186448Swnj char record[MAXRECSIZ]; 196448Swnj 206448Swnj #define SSIZE 64 216448Swnj char device[SSIZE]; 226448Swnj char count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE]; 236448Swnj 246448Swnj extern errno; 256448Swnj char *sys_errlist[]; 266448Swnj char resp[BUFSIZ]; 276448Swnj 286448Swnj char *sprintf(); 296448Swnj long lseek(); 306448Swnj 316448Swnj FILE *debug; 3217370Ssam #define DEBUG(f) if (debug) fprintf(debug, f) 3317370Ssam #define DEBUG1(f,a) if (debug) fprintf(debug, f, a) 3417370Ssam #define DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2) 356448Swnj 366448Swnj main(argc, argv) 376448Swnj int argc; 386448Swnj char **argv; 396448Swnj { 406560Smckusick int rval; 416448Swnj char c; 426448Swnj int n, i, cc; 436448Swnj 446448Swnj argc--, argv++; 456448Swnj if (argc > 0) { 466448Swnj debug = fopen(*argv, "w"); 476448Swnj if (debug == 0) 486448Swnj exit(1); 496448Swnj (void) setbuf(debug, (char *)0); 506448Swnj } 51*17537Sralph n = MAXRECSIZ; 52*17537Sralph (void) setsockopt(0, SOL_SOCKET, SO_RCVBUF, &n, sizeof (n)); 536448Swnj top: 546448Swnj errno = 0; 556448Swnj rval = 0; 566448Swnj if (read(0, &c, 1) != 1) 576448Swnj exit(0); 586448Swnj switch (c) { 596448Swnj 606448Swnj case 'O': 616448Swnj if (tape >= 0) 626448Swnj (void) close(tape); 6317370Ssam getstring(device); getstring(mode); 6417370Ssam DEBUG2("rmtd: O %s %s\n", device, mode); 656448Swnj tape = open(device, atoi(mode)); 666448Swnj if (tape < 0) 676448Swnj goto ioerror; 686841Smckusick goto respond; 696448Swnj 706448Swnj case 'C': 7117370Ssam DEBUG("rmtd: C\n"); 7217370Ssam getstring(device); /* discard */ 736448Swnj if (close(tape) < 0) 746448Swnj goto ioerror; 756448Swnj tape = -1; 766841Smckusick goto respond; 776448Swnj 786448Swnj case 'L': 7917370Ssam getstring(count); getstring(pos); 8017370Ssam DEBUG2("rmtd: L %s %s\n", count, pos); 816448Swnj rval = lseek(tape, (long) atoi(count), atoi(pos)); 826448Swnj if (rval < 0) 836448Swnj goto ioerror; 846841Smckusick goto respond; 856448Swnj 866448Swnj case 'W': 8717370Ssam getstring(count); 886448Swnj n = atoi(count); 8917370Ssam DEBUG1("rmtd: W %s\n", count); 906448Swnj for (i = 0; i < n; i += cc) { 916448Swnj cc = read(0, &record[i], n - i); 926448Swnj if (cc <= 0) { 9317370Ssam DEBUG("rmtd: premature eof\n"); 946448Swnj exit(1); 956448Swnj } 966448Swnj } 976448Swnj rval = write(tape, record, n); 986448Swnj if (rval < 0) 996448Swnj goto ioerror; 1006841Smckusick goto respond; 1016448Swnj 1026448Swnj case 'R': 10317370Ssam getstring(count); 10417370Ssam DEBUG1("rmtd: R %s\n", count); 1056448Swnj n = atoi(count); 1066448Swnj if (n > sizeof (record)) 1076448Swnj n = sizeof (record); 1086448Swnj rval = read(tape, record, n); 1096448Swnj if (rval < 0) 1106448Swnj goto ioerror; 1116841Smckusick (void) sprintf(resp, "A%d\n", rval); 1126841Smckusick (void) write(1, resp, strlen(resp)); 1136841Smckusick (void) write(1, record, rval); 1146841Smckusick goto top; 1156448Swnj 1166448Swnj case 'I': 11717370Ssam getstring(op); getstring(count); 11817370Ssam DEBUG2("rmtd: I %s %s\n", op, count); 1196448Swnj { struct mtop mtop; 1206448Swnj mtop.mt_op = atoi(op); 1216448Swnj mtop.mt_count = atoi(count); 1226448Swnj if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0) 1236448Swnj goto ioerror; 1246448Swnj rval = mtop.mt_count; 1256448Swnj } 1266841Smckusick goto respond; 1276448Swnj 1286448Swnj case 'S': /* status */ 12917370Ssam DEBUG("rmtd: S\n"); 1306448Swnj { struct mtget mtget; 1316448Swnj if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0) 1326448Swnj goto ioerror; 1336448Swnj rval = sizeof (mtget); 1346448Swnj (void) write(1, (char *)&mtget, sizeof (mtget)); 1356841Smckusick goto respond; 1366448Swnj } 1376448Swnj 1386448Swnj default: 13917370Ssam DEBUG1("rmtd: garbage command %c\n", c); 1406448Swnj exit(1); 1416448Swnj } 1426841Smckusick respond: 14317370Ssam DEBUG1("rmtd: A %d\n", rval); 1446448Swnj (void) sprintf(resp, "A%d\n", rval); 1456448Swnj (void) write(1, resp, strlen(resp)); 1466448Swnj goto top; 1476448Swnj ioerror: 1486448Swnj error(errno); 1496448Swnj goto top; 1506448Swnj } 1516448Swnj 15217370Ssam getstring(bp) 1536448Swnj char *bp; 1546448Swnj { 1556448Swnj int i; 1566448Swnj char *cp = bp; 1576448Swnj 1586448Swnj for (i = 0; i < SSIZE; i++) { 1596448Swnj if (read(0, cp+i, 1) != 1) 1606448Swnj exit(0); 1616448Swnj if (cp[i] == '\n') 1626448Swnj break; 1636448Swnj } 1646448Swnj cp[i] = '\0'; 1656448Swnj } 1666448Swnj 1676448Swnj error(num) 1686448Swnj int num; 1696448Swnj { 1706448Swnj 17117370Ssam DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]); 1726448Swnj (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]); 1736448Swnj (void) write(1, resp, strlen (resp)); 1746448Swnj } 1756560Smckusick 176