16448Swnj #ifndef lint 2*18475Smckusick static char sccsid[] = "@(#)rmt.c 4.7 (Berkeley) 85/03/20"; 36448Swnj #endif 46448Swnj 56448Swnj /* 66448Swnj * rmt 76448Swnj */ 86448Swnj #include <stdio.h> 96448Swnj #include <sgtty.h> 106448Swnj #include <sys/types.h> 1117537Sralph #include <sys/socket.h> 126448Swnj #include <sys/mtio.h> 136448Swnj #include <errno.h> 146448Swnj 156448Swnj int tape = -1; 166448Swnj 17*18475Smckusick char *record; 18*18475Smckusick int maxrecsize = -1; 19*18475Smckusick char *checkbuf(); 206448Swnj 216448Swnj #define SSIZE 64 226448Swnj char device[SSIZE]; 236448Swnj char count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE]; 246448Swnj 256448Swnj extern errno; 266448Swnj char *sys_errlist[]; 276448Swnj char resp[BUFSIZ]; 286448Swnj 296448Swnj char *sprintf(); 306448Swnj long lseek(); 316448Swnj 326448Swnj FILE *debug; 3317370Ssam #define DEBUG(f) if (debug) fprintf(debug, f) 3417370Ssam #define DEBUG1(f,a) if (debug) fprintf(debug, f, a) 3517370Ssam #define DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2) 366448Swnj 376448Swnj main(argc, argv) 386448Swnj int argc; 396448Swnj char **argv; 406448Swnj { 416560Smckusick int rval; 426448Swnj char c; 436448Swnj int n, i, cc; 446448Swnj 456448Swnj argc--, argv++; 466448Swnj if (argc > 0) { 476448Swnj debug = fopen(*argv, "w"); 486448Swnj if (debug == 0) 496448Swnj exit(1); 506448Swnj (void) setbuf(debug, (char *)0); 516448Swnj } 526448Swnj top: 536448Swnj errno = 0; 546448Swnj rval = 0; 556448Swnj if (read(0, &c, 1) != 1) 566448Swnj exit(0); 576448Swnj switch (c) { 586448Swnj 596448Swnj case 'O': 606448Swnj if (tape >= 0) 616448Swnj (void) close(tape); 6217370Ssam getstring(device); getstring(mode); 6317370Ssam DEBUG2("rmtd: O %s %s\n", device, mode); 646448Swnj tape = open(device, atoi(mode)); 656448Swnj if (tape < 0) 666448Swnj goto ioerror; 676841Smckusick goto respond; 686448Swnj 696448Swnj case 'C': 7017370Ssam DEBUG("rmtd: C\n"); 7117370Ssam getstring(device); /* discard */ 726448Swnj if (close(tape) < 0) 736448Swnj goto ioerror; 746448Swnj tape = -1; 756841Smckusick goto respond; 766448Swnj 776448Swnj case 'L': 7817370Ssam getstring(count); getstring(pos); 7917370Ssam DEBUG2("rmtd: L %s %s\n", count, pos); 806448Swnj rval = lseek(tape, (long) atoi(count), atoi(pos)); 816448Swnj if (rval < 0) 826448Swnj goto ioerror; 836841Smckusick goto respond; 846448Swnj 856448Swnj case 'W': 8617370Ssam getstring(count); 876448Swnj n = atoi(count); 8817370Ssam DEBUG1("rmtd: W %s\n", count); 89*18475Smckusick record = checkbuf(record, n); 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"); 94*18475Smckusick exit(2); 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); 106*18475Smckusick record = checkbuf(record, n); 1076448Swnj rval = read(tape, record, n); 1086448Swnj if (rval < 0) 1096448Swnj goto ioerror; 1106841Smckusick (void) sprintf(resp, "A%d\n", rval); 1116841Smckusick (void) write(1, resp, strlen(resp)); 1126841Smckusick (void) write(1, record, rval); 1136841Smckusick goto top; 1146448Swnj 1156448Swnj case 'I': 11617370Ssam getstring(op); getstring(count); 11717370Ssam DEBUG2("rmtd: I %s %s\n", op, count); 1186448Swnj { struct mtop mtop; 1196448Swnj mtop.mt_op = atoi(op); 1206448Swnj mtop.mt_count = atoi(count); 1216448Swnj if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0) 1226448Swnj goto ioerror; 1236448Swnj rval = mtop.mt_count; 1246448Swnj } 1256841Smckusick goto respond; 1266448Swnj 1276448Swnj case 'S': /* status */ 12817370Ssam DEBUG("rmtd: S\n"); 1296448Swnj { struct mtget mtget; 1306448Swnj if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0) 1316448Swnj goto ioerror; 1326448Swnj rval = sizeof (mtget); 13317854Sralph (void) sprintf(resp, "A%d\n", rval); 13417854Sralph (void) write(1, resp, strlen(resp)); 1356448Swnj (void) write(1, (char *)&mtget, sizeof (mtget)); 13617854Sralph goto top; 1376448Swnj } 1386448Swnj 1396448Swnj default: 14017370Ssam DEBUG1("rmtd: garbage command %c\n", c); 141*18475Smckusick exit(3); 1426448Swnj } 1436841Smckusick respond: 14417370Ssam DEBUG1("rmtd: A %d\n", rval); 1456448Swnj (void) sprintf(resp, "A%d\n", rval); 1466448Swnj (void) write(1, resp, strlen(resp)); 1476448Swnj goto top; 1486448Swnj ioerror: 1496448Swnj error(errno); 1506448Swnj goto top; 1516448Swnj } 1526448Swnj 15317370Ssam getstring(bp) 1546448Swnj char *bp; 1556448Swnj { 1566448Swnj int i; 1576448Swnj char *cp = bp; 1586448Swnj 1596448Swnj for (i = 0; i < SSIZE; i++) { 1606448Swnj if (read(0, cp+i, 1) != 1) 1616448Swnj exit(0); 1626448Swnj if (cp[i] == '\n') 1636448Swnj break; 1646448Swnj } 1656448Swnj cp[i] = '\0'; 1666448Swnj } 1676448Swnj 168*18475Smckusick char * 169*18475Smckusick checkbuf(record, size) 170*18475Smckusick char *record; 171*18475Smckusick int size; 172*18475Smckusick { 173*18475Smckusick extern char *malloc(); 174*18475Smckusick 175*18475Smckusick if (size <= maxrecsize) 176*18475Smckusick return (record); 177*18475Smckusick if (record != 0) 178*18475Smckusick free(record); 179*18475Smckusick record = malloc(size); 180*18475Smckusick if (record == 0) { 181*18475Smckusick DEBUG("rmtd: cannot allocate buffer space\n"); 182*18475Smckusick exit(4); 183*18475Smckusick } 184*18475Smckusick (void) setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)); 185*18475Smckusick return (record); 186*18475Smckusick } 187*18475Smckusick 1886448Swnj error(num) 1896448Swnj int num; 1906448Swnj { 1916448Swnj 19217370Ssam DEBUG2("rmtd: E %d (%s)\n", num, sys_errlist[num]); 1936448Swnj (void) sprintf(resp, "E%d\n%s\n", num, sys_errlist[num]); 1946448Swnj (void) write(1, resp, strlen (resp)); 1956448Swnj } 196