1: /* 2: * Copyright (c) 1980 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: * Modified to handle pdp11 930707 /BQT 7: */ 8: 9: #if !defined(lint) && defined(DOSCCS) 10: char copyright[] = 11: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 12: All rights reserved.\n"; 13: 14: static char sccsid[] = "@(#)mt.c 2.2 (2.11BSD) 1999/3/20"; 15: #endif not lint 16: 17: /* 18: * mt -- 19: * magnetic tape manipulation program 20: */ 21: #include <stdio.h> 22: #include <ctype.h> 23: #include <sys/types.h> 24: #include <sys/mtio.h> 25: #include <sys/ioctl.h> 26: 27: #define equal(s1,s2) (strcmp(s1, s2) == 0) 28: 29: struct commands { 30: char *c_name; 31: int c_code; 32: int c_ronly; 33: } com[] = { 34: { "weof", MTWEOF, 0 }, 35: { "eof", MTWEOF, 0 }, 36: { "fsf", MTFSF, 1 }, 37: { "bsf", MTBSF, 1 }, 38: { "fsr", MTFSR, 1 }, 39: { "bsr", MTBSR, 1 }, 40: { "rewind", MTREW, 1 }, 41: { "offline", MTOFFL, 1 }, 42: { "rewoffl", MTOFFL, 1 }, 43: { "status", MTNOP, 1 }, 44: { "cacheon", MTCACHE, 1 }, 45: { "cacheoff", MTNOCACHE, 1 }, 46: { 0 } 47: }; 48: 49: int mtfd; 50: struct mtop mt_com; 51: struct mtget mt_status; 52: char *tape; 53: 54: main(argc, argv) 55: char **argv; 56: { 57: char line[80], *getenv(); 58: register char *cp; 59: register struct commands *comp; 60: 61: if (argc > 2 && (equal(argv[1], "-t") || equal(argv[1], "-f"))) { 62: argc -= 2; 63: tape = argv[2]; 64: argv += 2; 65: } else 66: if ((tape = getenv("TAPE")) == NULL) 67: tape = MT_DEF; 68: if (argc < 2) { 69: fprintf(stderr, "usage: mt [ -f device ] command [ count ]\n"); 70: exit(1); 71: } 72: cp = argv[1]; 73: for (comp = com; comp->c_name != NULL; comp++) 74: if (strncmp(cp, comp->c_name, strlen(cp)) == 0) 75: break; 76: if (comp->c_name == NULL) { 77: fprintf(stderr, "mt: don't grok \"%s\"\n", cp); 78: exit(1); 79: } 80: if ((mtfd = open(tape, comp->c_ronly ? 0 : 2)) < 0) { 81: perror(tape); 82: exit(1); 83: } 84: if (comp->c_code != MTNOP) { 85: mt_com.mt_op = comp->c_code; 86: mt_com.mt_count = (argc > 2 ? atoi(argv[2]) : 1); 87: if (mt_com.mt_count < 0) { 88: fprintf(stderr, "mt: negative repeat count\n"); 89: exit(1); 90: } 91: if (ioctl(mtfd, MTIOCTOP, &mt_com) < 0) { 92: fprintf(stderr, "%s %s %ld ", tape, comp->c_name, 93: mt_com.mt_count); 94: perror("failed"); 95: exit(2); 96: } 97: } else { 98: if (ioctl(mtfd, MTIOCGET, (char *)&mt_status) < 0) { 99: perror("mt"); 100: exit(2); 101: } 102: status(&mt_status); 103: } 104: } 105: 106: #ifdef vax 107: #include <vaxmba/mtreg.h> 108: #include <vaxmba/htreg.h> 109: 110: #include <vaxuba/utreg.h> 111: #include <vaxuba/tmreg.h> 112: #undef b_repcnt /* argh */ 113: #include <vaxuba/tsreg.h> 114: #endif 115: 116: #ifdef sun 117: #include <sundev/tmreg.h> 118: #include <sundev/arreg.h> 119: #endif 120: 121: #ifdef pdp11 122: #include <pdpuba/htreg.h> 123: #include <pdpuba/tmreg.h> 124: #undef b_repcnt /* argh */ 125: #include <pdpuba/tsreg.h> 126: #include <pdpuba/tmscpreg.h> 127: #endif 128: 129: struct tape_desc { 130: short t_type; /* type of magtape device */ 131: char *t_name; /* printing name */ 132: char *t_dsbits; /* "drive status" register */ 133: char *t_erbits; /* "error" register */ 134: } tapes[] = { 135: #ifdef vax 136: { MT_ISTS, "ts11", 0, TSXS0_BITS }, 137: { MT_ISHT, "tm03", HTDS_BITS, HTER_BITS }, 138: { MT_ISTM, "tm11", 0, TMER_BITS }, 139: { MT_ISMT, "tu78", MTDS_BITS, 0 }, 140: { MT_ISUT, "tu45", UTDS_BITS, UTER_BITS }, 141: #endif 142: #ifdef sun 143: { MT_ISCPC, "TapeMaster", TMS_BITS, 0 }, 144: { MT_ISAR, "Archive", ARCH_CTRL_BITS, ARCH_BITS }, 145: #endif 146: #ifdef pdp11 147: { MT_ISTS, "ts11", 0, TSXS0_BITS }, 148: { MT_ISHT, "tm03", HTFS_BITS, HTER_BITS }, 149: { MT_ISTM, "tm11", 0, TMER_BITS }, 150: { MT_ISTMSCP, "tmscp", 0, 0 }, 151: #endif 152: { 0 } 153: }; 154: 155: /* 156: * Interpret the status buffer returned 157: */ 158: status(bp) 159: register struct mtget *bp; 160: { 161: register struct tape_desc *mt; 162: 163: for (mt = tapes; mt->t_type; mt++) 164: if (mt->t_type == bp->mt_type) 165: break; 166: if (mt->t_type == 0) { 167: printf("unknown tape drive type (%d)\n", bp->mt_type); 168: return; 169: } 170: printf("%s tape drive, residual=%d\n", mt->t_name, bp->mt_resid); 171: printreg("ds", bp->mt_dsreg, mt->t_dsbits); 172: printreg("\ner", bp->mt_erreg, mt->t_erbits); 173: putchar('\n'); 174: } 175: 176: /* 177: * Print a register a la the %b format of the kernel's printf 178: */ 179: printreg(s, v, bits) 180: char *s; 181: register char *bits; 182: register unsigned short v; 183: { 184: register int i, any = 0; 185: register char c; 186: 187: if (bits && *bits == 8) 188: printf("%s=%o", s, v); 189: else 190: printf("%s=%x", s, v); 191: bits++; 192: if (v && bits) { 193: putchar('<'); 194: while (i = *bits++) { 195: if (v & (1 << (i-1))) { 196: if (any) 197: putchar(','); 198: any = 1; 199: for (; (c = *bits) > 32; bits++) 200: putchar(c); 201: } else 202: for (; *bits > 32; bits++) 203: ; 204: } 205: putchar('>'); 206: } 207: }