hush: trivial buglet found by randomconfig testing
[oweals/busybox.git] / miscutils / mt.c
index 087819e72af6f0e859151e17b146cb80fbaa5d30..2971421eff2b23889b9f04a5bb7d2f8c9d204034 100644 (file)
@@ -1,11 +1,13 @@
 /* vi: set sw=4 ts=4: */
-#include "internal.h"
-#include <stdio.h>
+/*
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "libbb.h"
 #include <sys/mtio.h>
-#include <sys/fcntl.h>
 
 struct mt_opcodes {
-       char *name;
+       const char *name;
        short value;
 };
 
@@ -33,7 +35,7 @@ static const struct mt_opcodes opcodes[] = {
        {"ras3", MTRAS3},
        {"reset", MTRESET},
        {"retension", MTRETEN},
-       {"rew", MTREW},
+       {"rewind", MTREW},
        {"seek", MTSEEK},
        {"setblk", MTSETBLK},
        {"setdensity", MTSETDENSITY},
@@ -48,20 +50,22 @@ static const struct mt_opcodes opcodes[] = {
        {0, 0}
 };
 
-extern int mt_main(int argc, char **argv)
+int mt_main(int argc, char **argv);
+int mt_main(int argc, 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;
+
+       if (argc < 2) {
+               bb_show_usage();
        }
 
        if (strcmp(argv[1], "-f") == 0) {
                if (argc < 4) {
-                       usage(mt_usage);
+                       bb_show_usage();
                }
                file = argv[2];
                argv += 2;
@@ -75,25 +79,43 @@ extern int mt_main(int argc, char **argv)
        }
 
        if (code->name == 0) {
-               errorMsg("unrecognized opcode %s.\n", argv[1]);
-               exit (FALSE);
+               bb_error_msg("unrecognized opcode %s", argv[1]);
+               return EXIT_FAILURE;
        }
 
        op.mt_op = code->value;
        if (argc >= 3)
-               op.mt_count = atoi(argv[2]);
+               op.mt_count = xatoi_u(argv[2]);
        else
                op.mt_count = 1;                /* One, not zero, right? */
 
-       if ((fd = open(file, O_RDONLY, 0)) < 0) {
-               perror(file);
-               exit (FALSE);
+       switch (code->value) {
+               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 (code->value) {
+               case MTTELL:
+                       if (ioctl(fd, MTIOCPOS, &position) < 0)
+                               bb_perror_msg_and_die("%s", file);
+                       printf("At block %d.\n", (int) position.mt_blkno);
+                       break;
+
+               default:
+                       if (ioctl(fd, MTIOCTOP, &op) != 0)
+                               bb_perror_msg_and_die("%s", file);
+                       break;
        }
 
-       return (TRUE);
+       return EXIT_SUCCESS;
 }