Bump to version 1.22.1
[platform/upstream/busybox.git] / miscutils / mt.c
index 28922f8..20afd3a 100644 (file)
 /* vi: set sw=4 ts=4: */
-#include "internal.h"
-#include <stdio.h>
-#include <sys/mtio.h>
-#include <sys/fcntl.h>
+/*
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
 
-static const char mt_usage[] = "mt [-f device] opcode value\n"
-#ifndef BB_FEATURE_TRIVIAL_HELP
-                       "\nControl magnetic tape drive operation\n"
-#endif
-                       ;
+//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"
 
-struct mt_opcodes {
-       char *name;
-       short value;
-};
+#include "libbb.h"
+#include <sys/mtio.h>
 
 /* 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},
-       {"rew", 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
 };
 
-extern 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;
-       int fd;
-       
-       if ((argc != 2 && argc != 3) || **(argv + 1) == '-') {
-               usage(mt_usage);
+       struct mtpos position;
+       int fd, mode, idx;
+
+       if (!argv[1]) {
+               bb_show_usage();
        }
 
        if (strcmp(argv[1], "-f") == 0) {
-               if (argc < 4) {
-                       usage(mt_usage);
-               }
+               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) {
-               fprintf(stderr, "mt: unrecognized opcode %s.\n", argv[1]);
-               exit (FALSE);
-       }
+       if (idx < 0)
+               bb_error_msg_and_die("unrecognized opcode %s", argv[1]);
 
-       op.mt_op = code->value;
-       if (argc >= 3)
-               op.mt_count = atoi(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? */
 
-       if ((fd = open(file, O_RDONLY, 0)) < 0) {
-               perror(file);
-               exit (FALSE);
+       switch (opcode_value[idx]) {
+               case MTWEOF:
+               case MTERASE:
+               case MTWSM:
+               case MTSETDRVBUFFER:
+                       mode = O_WRONLY;
+                       break;
+
+               default:
+                       mode = O_RDONLY;
+                       break;
        }
 
-       if (ioctl(fd, MTIOCTOP, &op) != 0) {
-               perror(file);
-               exit (FALSE);
+       fd = xopen(file, mode);
+
+       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);
+                       break;
+
+               default:
+                       ioctl_or_perror_and_die(fd, MTIOCTOP, &op, "%s", file);
+                       break;
        }
 
-       exit (TRUE);
+       return EXIT_SUCCESS;
 }