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: 7: #ifndef lint 8: char copyright[] = 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10: All rights reserved.\n"; 11: #endif not lint 12: 13: #ifndef lint 14: static char sccsid[] = "@(#)mt.c 5.1 (Berkeley) 4/30/85"; 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: { 0 } 45: }; 46: 47: int mtfd; 48: struct mtop mt_com; 49: struct mtget mt_status; 50: char *tape; 51: 52: main(argc, argv) 53: char **argv; 54: { 55: char line[80], *getenv(); 56: register char *cp; 57: register struct commands *comp; 58: 59: if (argc > 2 && (equal(argv[1], "-t") || equal(argv[1], "-f"))) { 60: argc -= 2; 61: tape = argv[2]; 62: argv += 2; 63: } else 64: if ((tape = getenv("TAPE")) == NULL) 65: tape = DEFTAPE; 66: if (argc < 2) { 67: fprintf(stderr, "usage: mt [ -f device ] command [ count ]\n"); 68: exit(1); 69: } 70: cp = argv[1]; 71: for (comp = com; comp->c_name != NULL; comp++) 72: if (strncmp(cp, comp->c_name, strlen(cp)) == 0) 73: break; 74: if (comp->c_name == NULL) { 75: fprintf(stderr, "mt: don't grok \"%s\"\n", cp); 76: exit(1); 77: } 78: if ((mtfd = open(tape, comp->c_ronly ? 0 : 2)) < 0) { 79: perror(tape); 80: exit(1); 81: } 82: if (comp->c_code != MTNOP) { 83: mt_com.mt_op = comp->c_code; 84: mt_com.mt_count = (argc > 2 ? atoi(argv[2]) : 1); 85: if (mt_com.mt_count < 0) { 86: fprintf(stderr, "mt: negative repeat count\n"); 87: exit(1); 88: } 89: if (ioctl(mtfd, MTIOCTOP, &mt_com) < 0) { 90: fprintf(stderr, "%s %s %d ", tape, comp->c_name, 91: mt_com.mt_count); 92: perror("failed"); 93: exit(2); 94: } 95: } else { 96: if (ioctl(mtfd, MTIOCGET, (char *)&mt_status) < 0) { 97: perror("mt"); 98: exit(2); 99: } 100: status(&mt_status); 101: } 102: } 103: 104: #ifdef vax 105: #include <vaxmba/mtreg.h> 106: #include <vaxmba/htreg.h> 107: 108: #include <vaxuba/utreg.h> 109: #include <vaxuba/tmreg.h> 110: #undef b_repcnt /* argh */ 111: #include <vaxuba/tsreg.h> 112: #endif 113: 114: #ifdef sun 115: #include <sundev/tmreg.h> 116: #include <sundev/arreg.h> 117: #endif 118: 119: struct tape_desc { 120: short t_type; /* type of magtape device */ 121: char *t_name; /* printing name */ 122: char *t_dsbits; /* "drive status" register */ 123: char *t_erbits; /* "error" register */ 124: } tapes[] = { 125: #ifdef vax 126: { MT_ISTS, "ts11", 0, TSXS0_BITS }, 127: { MT_ISHT, "tm03", HTDS_BITS, HTER_BITS }, 128: { MT_ISTM, "tm11", 0, TMER_BITS }, 129: { MT_ISMT, "tu78", MTDS_BITS, 0 }, 130: { MT_ISUT, "tu45", UTDS_BITS, UTER_BITS }, 131: #endif 132: #ifdef sun 133: { MT_ISCPC, "TapeMaster", TMS_BITS, 0 }, 134: { MT_ISAR, "Archive", ARCH_CTRL_BITS, ARCH_BITS }, 135: #endif 136: { 0 } 137: }; 138: 139: /* 140: * Interpret the status buffer returned 141: */ 142: status(bp) 143: register struct mtget *bp; 144: { 145: register struct tape_desc *mt; 146: 147: for (mt = tapes; mt->t_type; mt++) 148: if (mt->t_type == bp->mt_type) 149: break; 150: if (mt->t_type == 0) { 151: printf("unknown tape drive type (%d)\n", bp->mt_type); 152: return; 153: } 154: printf("%s tape drive, residual=%d\n", mt->t_name, bp->mt_resid); 155: printreg("ds", bp->mt_dsreg, mt->t_dsbits); 156: printreg("\ner", bp->mt_erreg, mt->t_erbits); 157: putchar('\n'); 158: } 159: 160: /* 161: * Print a register a la the %b format of the kernel's printf 162: */ 163: printreg(s, v, bits) 164: char *s; 165: register char *bits; 166: register unsigned short v; 167: { 168: register int i, any = 0; 169: register char c; 170: 171: if (bits && *bits == 8) 172: printf("%s=%o", s, v); 173: else 174: printf("%s=%x", s, v); 175: bits++; 176: if (v && bits) { 177: putchar('<'); 178: while (i = *bits++) { 179: if (v & (1 << (i-1))) { 180: if (any) 181: putchar(','); 182: any = 1; 183: for (; (c = *bits) > 32; bits++) 184: putchar(c); 185: } else 186: for (; *bits > 32; bits++) 187: ; 188: } 189: putchar('>'); 190: } 191: }