Bump to version 1.22.1
[platform/upstream/busybox.git] / miscutils / mt.c
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 */
22 static 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
59 static 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
95 int mt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
96 int 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 }