Bump to version 1.22.1
[platform/upstream/busybox.git] / miscutils / mt.c
index b9bc2a1..20afd3a 100644 (file)
 /* vi: set sw=4 ts=4: */
 /*
- * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  */
 
+//usage:#define mt_trivial_usage
+//usage:       "[-f device] opcode value"
+//usage:#define mt_full_usage "\n\n"
+//usage:       "Control magnetic tape drive operation\n"
+//usage:       "\n"
+//usage:       "Available Opcodes:\n"
+//usage:       "\n"
+//usage:       "bsf bsfm bsr bss datacompression drvbuffer eof eom erase\n"
+//usage:       "fsf fsfm fsr fss load lock mkpart nop offline ras1 ras2\n"
+//usage:       "ras3 reset retension rewind rewoffline seek setblk setdensity\n"
+//usage:       "setpart tell unload unlock weof wset"
+
 #include "libbb.h"
 #include <sys/mtio.h>
 
-struct mt_opcodes {
-       const char *name;
-       short value;
-};
-
 /* missing: eod/seod, stoptions, stwrthreshold, densities */
-static const struct mt_opcodes opcodes[] = {
-       {"bsf", MTBSF},
-       {"bsfm", MTBSFM},
-       {"bsr", MTBSR},
-       {"bss", MTBSS},
-       {"datacompression", MTCOMPRESSION},
-       {"eom", MTEOM},
-       {"erase", MTERASE},
-       {"fsf", MTFSF},
-       {"fsfm", MTFSFM},
-       {"fsr", MTFSR},
-       {"fss", MTFSS},
-       {"load", MTLOAD},
-       {"lock", MTLOCK},
-       {"mkpart", MTMKPART},
-       {"nop", MTNOP},
-       {"offline", MTOFFL},
-       {"rewoffline", MTOFFL},
-       {"ras1", MTRAS1},
-       {"ras2", MTRAS2},
-       {"ras3", MTRAS3},
-       {"reset", MTRESET},
-       {"retension", MTRETEN},
-       {"rewind", MTREW},
-       {"seek", MTSEEK},
-       {"setblk", MTSETBLK},
-       {"setdensity", MTSETDENSITY},
-       {"drvbuffer", MTSETDRVBUFFER},
-       {"setpart", MTSETPART},
-       {"tell", MTTELL},
-       {"wset", MTWSM},
-       {"unload", MTUNLOAD},
-       {"unlock", MTUNLOCK},
-       {"eof", MTWEOF},
-       {"weof", MTWEOF},
-       {0, 0}
+static const short opcode_value[] = {
+       MTBSF,
+       MTBSFM,
+       MTBSR,
+       MTBSS,
+       MTCOMPRESSION,
+       MTEOM,
+       MTERASE,
+       MTFSF,
+       MTFSFM,
+       MTFSR,
+       MTFSS,
+       MTLOAD,
+       MTLOCK,
+       MTMKPART,
+       MTNOP,
+       MTOFFL,
+       MTOFFL,
+       MTRAS1,
+       MTRAS2,
+       MTRAS3,
+       MTRESET,
+       MTRETEN,
+       MTREW,
+       MTSEEK,
+       MTSETBLK,
+       MTSETDENSITY,
+       MTSETDRVBUFFER,
+       MTSETPART,
+       MTTELL,
+       MTWSM,
+       MTUNLOAD,
+       MTUNLOCK,
+       MTWEOF,
+       MTWEOF
 };
 
-int mt_main(int argc, char **argv);
-int mt_main(int argc, char **argv)
+static const char opcode_name[] ALIGN1 =
+       "bsf"             "\0"
+       "bsfm"            "\0"
+       "bsr"             "\0"
+       "bss"             "\0"
+       "datacompression" "\0"
+       "eom"             "\0"
+       "erase"           "\0"
+       "fsf"             "\0"
+       "fsfm"            "\0"
+       "fsr"             "\0"
+       "fss"             "\0"
+       "load"            "\0"
+       "lock"            "\0"
+       "mkpart"          "\0"
+       "nop"             "\0"
+       "offline"         "\0"
+       "rewoffline"      "\0"
+       "ras1"            "\0"
+       "ras2"            "\0"
+       "ras3"            "\0"
+       "reset"           "\0"
+       "retension"       "\0"
+       "rewind"          "\0"
+       "seek"            "\0"
+       "setblk"          "\0"
+       "setdensity"      "\0"
+       "drvbuffer"       "\0"
+       "setpart"         "\0"
+       "tell"            "\0"
+       "wset"            "\0"
+       "unload"          "\0"
+       "unlock"          "\0"
+       "eof"             "\0"
+       "weof"            "\0";
+
+int mt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int mt_main(int argc UNUSED_PARAM, char **argv)
 {
        const char *file = "/dev/tape";
-       const struct mt_opcodes *code = opcodes;
        struct mtop op;
        struct mtpos position;
-       int fd, mode;
+       int fd, mode, idx;
 
-       if (argc < 2) {
+       if (!argv[1]) {
                bb_show_usage();
        }
 
        if (strcmp(argv[1], "-f") == 0) {
-               if (argc < 4) {
+               if (!argv[2] || !argv[3])
                        bb_show_usage();
-               }
                file = argv[2];
                argv += 2;
-               argc -= 2;
        }
 
-       while (code->name != 0) {
-               if (strcmp(code->name, argv[1]) == 0)
-                       break;
-               code++;
-       }
+       idx = index_in_strings(opcode_name, argv[1]);
 
-       if (code->name == 0) {
-               bb_error_msg("unrecognized opcode %s", argv[1]);
-               return EXIT_FAILURE;
-       }
+       if (idx < 0)
+               bb_error_msg_and_die("unrecognized opcode %s", argv[1]);
 
-       op.mt_op = code->value;
-       if (argc >= 3)
-               op.mt_count = xatoi_u(argv[2]);
+       op.mt_op = opcode_value[idx];
+       if (argv[2])
+               op.mt_count = xatoi_positive(argv[2]);
        else
-               op.mt_count = 1;                /* One, not zero, right? */
+               op.mt_count = 1;  /* One, not zero, right? */
 
-       switch (code->value) {
+       switch (opcode_value[idx]) {
                case MTWEOF:
                case MTERASE:
                case MTWSM:
@@ -104,10 +137,10 @@ int mt_main(int argc, char **argv)
 
        fd = xopen(file, mode);
 
-       switch (code->value) {
+       switch (opcode_value[idx]) {
                case MTTELL:
                        ioctl_or_perror_and_die(fd, MTIOCPOS, &position, "%s", file);
-                       printf("At block %d.\n", (int) position.mt_blkno);
+                       printf("At block %d\n", (int) position.mt_blkno);
                        break;
 
                default: