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