busybox/miscutils/mt.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   4 */
   5
   6//usage:#define mt_trivial_usage
   7//usage:       "[-f device] opcode value"
   8//usage:#define mt_full_usage "\n\n"
   9//usage:       "Control magnetic tape drive operation\n"
  10//usage:       "\n"
  11//usage:       "Available Opcodes:\n"
  12//usage:       "\n"
  13//usage:       "bsf bsfm bsr bss datacompression drvbuffer eof eom erase\n"
  14//usage:       "fsf fsfm fsr fss load lock mkpart nop offline ras1 ras2\n"
  15//usage:       "ras3 reset retension rewind rewoffline seek setblk setdensity\n"
  16//usage:       "setpart tell unload unlock weof wset"
  17
  18#include "libbb.h"
  19#include <sys/mtio.h>
  20
  21/* missing: eod/seod, stoptions, stwrthreshold, densities */
  22static const short opcode_value[] = {
  23        MTBSF,
  24        MTBSFM,
  25        MTBSR,
  26        MTBSS,
  27        MTCOMPRESSION,
  28        MTEOM,
  29        MTERASE,
  30        MTFSF,
  31        MTFSFM,
  32        MTFSR,
  33        MTFSS,
  34        MTLOAD,
  35        MTLOCK,
  36        MTMKPART,
  37        MTNOP,
  38        MTOFFL,
  39        MTOFFL,
  40        MTRAS1,
  41        MTRAS2,
  42        MTRAS3,
  43        MTRESET,
  44        MTRETEN,
  45        MTREW,
  46        MTSEEK,
  47        MTSETBLK,
  48        MTSETDENSITY,
  49        MTSETDRVBUFFER,
  50        MTSETPART,
  51        MTTELL,
  52        MTWSM,
  53        MTUNLOAD,
  54        MTUNLOCK,
  55        MTWEOF,
  56        MTWEOF
  57};
  58
  59static const char opcode_name[] ALIGN1 =
  60        "bsf"             "\0"
  61        "bsfm"            "\0"
  62        "bsr"             "\0"
  63        "bss"             "\0"
  64        "datacompression" "\0"
  65        "eom"             "\0"
  66        "erase"           "\0"
  67        "fsf"             "\0"
  68        "fsfm"            "\0"
  69        "fsr"             "\0"
  70        "fss"             "\0"
  71        "load"            "\0"
  72        "lock"            "\0"
  73        "mkpart"          "\0"
  74        "nop"             "\0"
  75        "offline"         "\0"
  76        "rewoffline"      "\0"
  77        "ras1"            "\0"
  78        "ras2"            "\0"
  79        "ras3"            "\0"
  80        "reset"           "\0"
  81        "retension"       "\0"
  82        "rewind"          "\0"
  83        "seek"            "\0"
  84        "setblk"          "\0"
  85        "setdensity"      "\0"
  86        "drvbuffer"       "\0"
  87        "setpart"         "\0"
  88        "tell"            "\0"
  89        "wset"            "\0"
  90        "unload"          "\0"
  91        "unlock"          "\0"
  92        "eof"             "\0"
  93        "weof"            "\0";
  94
  95int mt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  96int mt_main(int argc UNUSED_PARAM, char **argv)
  97{
  98        const char *file = "/dev/tape";
  99        struct mtop op;
 100        struct mtpos position;
 101        int fd, mode, idx;
 102
 103        if (!argv[1]) {
 104                bb_show_usage();
 105        }
 106
 107        if (strcmp(argv[1], "-f") == 0) {
 108                if (!argv[2] || !argv[3])
 109                        bb_show_usage();
 110                file = argv[2];
 111                argv += 2;
 112        }
 113
 114        idx = index_in_strings(opcode_name, argv[1]);
 115
 116        if (idx < 0)
 117                bb_error_msg_and_die("unrecognized opcode %s", argv[1]);
 118
 119        op.mt_op = opcode_value[idx];
 120        if (argv[2])
 121                op.mt_count = xatoi_positive(argv[2]);
 122        else
 123                op.mt_count = 1;  /* One, not zero, right? */
 124
 125        switch (opcode_value[idx]) {
 126                case MTWEOF:
 127                case MTERASE:
 128                case MTWSM:
 129                case MTSETDRVBUFFER:
 130                        mode = O_WRONLY;
 131                        break;
 132
 133                default:
 134                        mode = O_RDONLY;
 135                        break;
 136        }
 137
 138        fd = xopen(file, mode);
 139
 140        switch (opcode_value[idx]) {
 141                case MTTELL:
 142                        ioctl_or_perror_and_die(fd, MTIOCPOS, &position, "%s", file);
 143                        printf("At block %d\n", (int) position.mt_blkno);
 144                        break;
 145
 146                default:
 147                        ioctl_or_perror_and_die(fd, MTIOCTOP, &op, "%s", file);
 148                        break;
 149        }
 150
 151        return EXIT_SUCCESS;
 152}
 153