1/* vi: set sw=4 ts=4: */ 2/* 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 4 */ 5 6#include "libbb.h" 7#include <sys/mtio.h> 8 9struct mt_opcodes { 10 const char *name; 11 short value; 12}; 13 14/* missing: eod/seod, stoptions, stwrthreshold, densities */ 15static const struct mt_opcodes opcodes[] = { 16 {"bsf", MTBSF}, 17 {"bsfm", MTBSFM}, 18 {"bsr", MTBSR}, 19 {"bss", MTBSS}, 20 {"datacompression", MTCOMPRESSION}, 21 {"eom", MTEOM}, 22 {"erase", MTERASE}, 23 {"fsf", MTFSF}, 24 {"fsfm", MTFSFM}, 25 {"fsr", MTFSR}, 26 {"fss", MTFSS}, 27 {"load", MTLOAD}, 28 {"lock", MTLOCK}, 29 {"mkpart", MTMKPART}, 30 {"nop", MTNOP}, 31 {"offline", MTOFFL}, 32 {"rewoffline", MTOFFL}, 33 {"ras1", MTRAS1}, 34 {"ras2", MTRAS2}, 35 {"ras3", MTRAS3}, 36 {"reset", MTRESET}, 37 {"retension", MTRETEN}, 38 {"rewind", MTREW}, 39 {"seek", MTSEEK}, 40 {"setblk", MTSETBLK}, 41 {"setdensity", MTSETDENSITY}, 42 {"drvbuffer", MTSETDRVBUFFER}, 43 {"setpart", MTSETPART}, 44 {"tell", MTTELL}, 45 {"wset", MTWSM}, 46 {"unload", MTUNLOAD}, 47 {"unlock", MTUNLOCK}, 48 {"eof", MTWEOF}, 49 {"weof", MTWEOF}, 50 {0, 0} 51}; 52 53int mt_main(int argc, char **argv); 54int mt_main(int argc, char **argv) 55{ 56 const char *file = "/dev/tape"; 57 const struct mt_opcodes *code = opcodes; 58 struct mtop op; 59 struct mtpos position; 60 int fd, mode; 61 62 if (argc < 2) { 63 bb_show_usage(); 64 } 65 66 if (strcmp(argv[1], "-f") == 0) { 67 if (argc < 4) { 68 bb_show_usage(); 69 } 70 file = argv[2]; 71 argv += 2; 72 argc -= 2; 73 } 74 75 while (code->name != 0) { 76 if (strcmp(code->name, argv[1]) == 0) 77 break; 78 code++; 79 } 80 81 if (code->name == 0) { 82 bb_error_msg("unrecognized opcode %s", argv[1]); 83 return EXIT_FAILURE; 84 } 85 86 op.mt_op = code->value; 87 if (argc >= 3) 88 op.mt_count = xatoi_u(argv[2]); 89 else 90 op.mt_count = 1; /* One, not zero, right? */ 91 92 switch (code->value) { 93 case MTWEOF: 94 case MTERASE: 95 case MTWSM: 96 case MTSETDRVBUFFER: 97 mode = O_WRONLY; 98 break; 99 100 default: 101 mode = O_RDONLY; 102 break; 103 } 104 105 fd = xopen(file, mode); 106 107 switch (code->value) { 108 case MTTELL: 109 ioctl_or_perror_and_die(fd, MTIOCPOS, &position, "%s", file); 110 printf("At block %d.\n", (int) position.mt_blkno); 111 break; 112 113 default: 114 ioctl_or_perror_and_die(fd, MTIOCTOP, &op, "%s", file); 115 break; 116 } 117 118 return EXIT_SUCCESS; 119} 120