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