1 /* 2 * Copyright (c) 1980 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1980 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)mt.c 5.6 (Berkeley) 06/06/91"; 16 #endif /* not lint */ 17 18 /* 19 * mt -- 20 * magnetic tape manipulation program 21 */ 22 #include <sys/types.h> 23 #include <sys/ioctl.h> 24 #include <sys/mtio.h> 25 #include <fcntl.h> 26 #include <stdio.h> 27 #include <ctype.h> 28 29 #define equal(s1,s2) (strcmp(s1, s2) == 0) 30 31 struct commands { 32 char *c_name; 33 int c_code; 34 int c_ronly; 35 } com[] = { 36 { "weof", MTWEOF, 0 }, 37 { "eof", MTWEOF, 0 }, 38 { "fsf", MTFSF, 1 }, 39 { "bsf", MTBSF, 1 }, 40 { "fsr", MTFSR, 1 }, 41 { "bsr", MTBSR, 1 }, 42 { "rewind", MTREW, 1 }, 43 { "offline", MTOFFL, 1 }, 44 { "rewoffl", MTOFFL, 1 }, 45 { "status", MTNOP, 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 = DEFTAPE; 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 ? O_RDONLY : O_RDWR)) < 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 %d ", 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 tahoe 122 #include <tahoe/vba/cyreg.h> 123 #endif 124 125 struct tape_desc { 126 short t_type; /* type of magtape device */ 127 char *t_name; /* printing name */ 128 char *t_dsbits; /* "drive status" register */ 129 char *t_erbits; /* "error" register */ 130 } tapes[] = { 131 #ifdef vax 132 { MT_ISTS, "ts11", 0, TSXS0_BITS }, 133 { MT_ISHT, "tm03", HTDS_BITS, HTER_BITS }, 134 { MT_ISTM, "tm11", 0, TMER_BITS }, 135 { MT_ISMT, "tu78", MTDS_BITS, 0 }, 136 { MT_ISUT, "tu45", UTDS_BITS, UTER_BITS }, 137 #endif 138 #ifdef sun 139 { MT_ISCPC, "TapeMaster", TMS_BITS, 0 }, 140 { MT_ISAR, "Archive", ARCH_CTRL_BITS, ARCH_BITS }, 141 #endif 142 #ifdef tahoe 143 { MT_ISCY, "cipher", CYS_BITS, CYCW_BITS }, 144 #endif 145 { 0 } 146 }; 147 148 /* 149 * Interpret the status buffer returned 150 */ 151 status(bp) 152 register struct mtget *bp; 153 { 154 register struct tape_desc *mt; 155 156 for (mt = tapes; mt->t_type; mt++) 157 if (mt->t_type == bp->mt_type) 158 break; 159 if (mt->t_type == 0) { 160 printf("unknown tape drive type (%d)\n", bp->mt_type); 161 return; 162 } 163 printf("%s tape drive, residual=%d\n", mt->t_name, bp->mt_resid); 164 printreg("ds", bp->mt_dsreg, mt->t_dsbits); 165 printreg("\ner", bp->mt_erreg, mt->t_erbits); 166 putchar('\n'); 167 } 168 169 /* 170 * Print a register a la the %b format of the kernel's printf 171 */ 172 printreg(s, v, bits) 173 char *s; 174 register char *bits; 175 register unsigned short v; 176 { 177 register int i, any = 0; 178 register char c; 179 180 if (bits && *bits == 8) 181 printf("%s=%o", s, v); 182 else 183 printf("%s=%x", s, v); 184 bits++; 185 if (v && bits) { 186 putchar('<'); 187 while (i = *bits++) { 188 if (v & (1 << (i-1))) { 189 if (any) 190 putchar(','); 191 any = 1; 192 for (; (c = *bits) > 32; bits++) 193 putchar(c); 194 } else 195 for (; *bits > 32; bits++) 196 ; 197 } 198 putchar('>'); 199 } 200 } 201