1 /* 2 * Copyright (c) 1980 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 char copyright[] = 20 "@(#) Copyright (c) 1980 The Regents of the University of California.\n\ 21 All rights reserved.\n"; 22 #endif /* not lint */ 23 24 #ifndef lint 25 static char sccsid[] = "@(#)mt.c 5.3 (Berkeley) 08/31/88"; 26 #endif /* not lint */ 27 28 /* 29 * mt -- 30 * magnetic tape manipulation program 31 */ 32 #include <stdio.h> 33 #include <ctype.h> 34 #include <sys/types.h> 35 #include <sys/mtio.h> 36 #include <sys/ioctl.h> 37 38 #define equal(s1,s2) (strcmp(s1, s2) == 0) 39 40 struct commands { 41 char *c_name; 42 int c_code; 43 int c_ronly; 44 } com[] = { 45 { "weof", MTWEOF, 0 }, 46 { "eof", MTWEOF, 0 }, 47 { "fsf", MTFSF, 1 }, 48 { "bsf", MTBSF, 1 }, 49 { "fsr", MTFSR, 1 }, 50 { "bsr", MTBSR, 1 }, 51 { "rewind", MTREW, 1 }, 52 { "offline", MTOFFL, 1 }, 53 { "rewoffl", MTOFFL, 1 }, 54 { "status", MTNOP, 1 }, 55 { 0 } 56 }; 57 58 int mtfd; 59 struct mtop mt_com; 60 struct mtget mt_status; 61 char *tape; 62 63 main(argc, argv) 64 char **argv; 65 { 66 char line[80], *getenv(); 67 register char *cp; 68 register struct commands *comp; 69 70 if (argc > 2 && (equal(argv[1], "-t") || equal(argv[1], "-f"))) { 71 argc -= 2; 72 tape = argv[2]; 73 argv += 2; 74 } else 75 if ((tape = getenv("TAPE")) == NULL) 76 tape = DEFTAPE; 77 if (argc < 2) { 78 fprintf(stderr, "usage: mt [ -f device ] command [ count ]\n"); 79 exit(1); 80 } 81 cp = argv[1]; 82 for (comp = com; comp->c_name != NULL; comp++) 83 if (strncmp(cp, comp->c_name, strlen(cp)) == 0) 84 break; 85 if (comp->c_name == NULL) { 86 fprintf(stderr, "mt: don't grok \"%s\"\n", cp); 87 exit(1); 88 } 89 if ((mtfd = open(tape, comp->c_ronly ? 0 : 2)) < 0) { 90 perror(tape); 91 exit(1); 92 } 93 if (comp->c_code != MTNOP) { 94 mt_com.mt_op = comp->c_code; 95 mt_com.mt_count = (argc > 2 ? atoi(argv[2]) : 1); 96 if (mt_com.mt_count < 0) { 97 fprintf(stderr, "mt: negative repeat count\n"); 98 exit(1); 99 } 100 if (ioctl(mtfd, MTIOCTOP, &mt_com) < 0) { 101 fprintf(stderr, "%s %s %d ", tape, comp->c_name, 102 mt_com.mt_count); 103 perror("failed"); 104 exit(2); 105 } 106 } else { 107 if (ioctl(mtfd, MTIOCGET, (char *)&mt_status) < 0) { 108 perror("mt"); 109 exit(2); 110 } 111 status(&mt_status); 112 } 113 } 114 115 #ifdef vax 116 #include <vaxmba/mtreg.h> 117 #include <vaxmba/htreg.h> 118 119 #include <vaxuba/utreg.h> 120 #include <vaxuba/tmreg.h> 121 #undef b_repcnt /* argh */ 122 #include <vaxuba/tsreg.h> 123 #endif 124 125 #ifdef sun 126 #include <sundev/tmreg.h> 127 #include <sundev/arreg.h> 128 #endif 129 130 #ifdef tahoe 131 #include <tahoevba/cyreg.h> 132 #endif 133 134 struct tape_desc { 135 short t_type; /* type of magtape device */ 136 char *t_name; /* printing name */ 137 char *t_dsbits; /* "drive status" register */ 138 char *t_erbits; /* "error" register */ 139 } tapes[] = { 140 #ifdef vax 141 { MT_ISTS, "ts11", 0, TSXS0_BITS }, 142 { MT_ISHT, "tm03", HTDS_BITS, HTER_BITS }, 143 { MT_ISTM, "tm11", 0, TMER_BITS }, 144 { MT_ISMT, "tu78", MTDS_BITS, 0 }, 145 { MT_ISUT, "tu45", UTDS_BITS, UTER_BITS }, 146 #endif 147 #ifdef sun 148 { MT_ISCPC, "TapeMaster", TMS_BITS, 0 }, 149 { MT_ISAR, "Archive", ARCH_CTRL_BITS, ARCH_BITS }, 150 #endif 151 #ifdef tahoe 152 { MT_ISCY, "cipher", CYS_BITS, CYCW_BITS }, 153 #endif 154 { 0 } 155 }; 156 157 /* 158 * Interpret the status buffer returned 159 */ 160 status(bp) 161 register struct mtget *bp; 162 { 163 register struct tape_desc *mt; 164 165 for (mt = tapes; mt->t_type; mt++) 166 if (mt->t_type == bp->mt_type) 167 break; 168 if (mt->t_type == 0) { 169 printf("unknown tape drive type (%d)\n", bp->mt_type); 170 return; 171 } 172 printf("%s tape drive, residual=%d\n", mt->t_name, bp->mt_resid); 173 printreg("ds", bp->mt_dsreg, mt->t_dsbits); 174 printreg("\ner", bp->mt_erreg, mt->t_erbits); 175 putchar('\n'); 176 } 177 178 /* 179 * Print a register a la the %b format of the kernel's printf 180 */ 181 printreg(s, v, bits) 182 char *s; 183 register char *bits; 184 register unsigned short v; 185 { 186 register int i, any = 0; 187 register char c; 188 189 if (bits && *bits == 8) 190 printf("%s=%o", s, v); 191 else 192 printf("%s=%x", s, v); 193 bits++; 194 if (v && bits) { 195 putchar('<'); 196 while (i = *bits++) { 197 if (v & (1 << (i-1))) { 198 if (any) 199 putchar(','); 200 any = 1; 201 for (; (c = *bits) > 32; bits++) 202 putchar(c); 203 } else 204 for (; *bits > 32; bits++) 205 ; 206 } 207 putchar('>'); 208 } 209 } 210