"formated" -> "formatted" throughout the code base.
[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 "busybox.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <sys/mtio.h>
11 #include <fcntl.h>
12
13 struct mt_opcodes {
14         char *name;
15         short value;
16 };
17
18 /* missing: eod/seod, stoptions, stwrthreshold, densities */
19 static const struct mt_opcodes opcodes[] = {
20         {"bsf", MTBSF},
21         {"bsfm", MTBSFM},
22         {"bsr", MTBSR},
23         {"bss", MTBSS},
24         {"datacompression", MTCOMPRESSION},
25         {"eom", MTEOM},
26         {"erase", MTERASE},
27         {"fsf", MTFSF},
28         {"fsfm", MTFSFM},
29         {"fsr", MTFSR},
30         {"fss", MTFSS},
31         {"load", MTLOAD},
32         {"lock", MTLOCK},
33         {"mkpart", MTMKPART},
34         {"nop", MTNOP},
35         {"offline", MTOFFL},
36         {"rewoffline", MTOFFL},
37         {"ras1", MTRAS1},
38         {"ras2", MTRAS2},
39         {"ras3", MTRAS3},
40         {"reset", MTRESET},
41         {"retension", MTRETEN},
42         {"rewind", MTREW},
43         {"seek", MTSEEK},
44         {"setblk", MTSETBLK},
45         {"setdensity", MTSETDENSITY},
46         {"drvbuffer", MTSETDRVBUFFER},
47         {"setpart", MTSETPART},
48         {"tell", MTTELL},
49         {"wset", MTWSM},
50         {"unload", MTUNLOAD},
51         {"unlock", MTUNLOCK},
52         {"eof", MTWEOF},
53         {"weof", MTWEOF},
54         {0, 0}
55 };
56
57 int mt_main(int argc, char **argv)
58 {
59         const char *file = "/dev/tape";
60         const struct mt_opcodes *code = opcodes;
61         struct mtop op;
62         struct mtpos position;
63         int fd, mode;
64
65         if (argc < 2) {
66                 bb_show_usage();
67         }
68
69         if (strcmp(argv[1], "-f") == 0) {
70                 if (argc < 4) {
71                         bb_show_usage();
72                 }
73                 file = argv[2];
74                 argv += 2;
75                 argc -= 2;
76         }
77
78         while (code->name != 0) {
79                 if (strcmp(code->name, argv[1]) == 0)
80                         break;
81                 code++;
82         }
83
84         if (code->name == 0) {
85                 bb_error_msg("unrecognized opcode %s.", argv[1]);
86                 return EXIT_FAILURE;
87         }
88
89         op.mt_op = code->value;
90         if (argc >= 3)
91                 op.mt_count = atoi(argv[2]);
92         else
93                 op.mt_count = 1;                /* One, not zero, right? */
94
95         switch (code->value) {
96                 case MTWEOF:
97                 case MTERASE:
98                 case MTWSM:
99                 case MTSETDRVBUFFER:
100                         mode = O_WRONLY;
101                         break;
102
103                 default:
104                         mode = O_RDONLY;
105                         break;
106         }
107
108         fd = bb_xopen3(file, mode, 0);
109
110         switch (code->value) {
111                 case MTTELL:
112                         if (ioctl(fd, MTIOCPOS, &position) < 0)
113                                 bb_perror_msg_and_die("%s", file);
114                         printf ("At block %d.\n", (int) position.mt_blkno);
115                         break;
116
117                 default:
118                         if (ioctl(fd, MTIOCTOP, &op) != 0)
119                                 bb_perror_msg_and_die("%s", file);
120                         break;
121         }
122
123         return EXIT_SUCCESS;
124 }