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