Some updates for better portability.
[oweals/busybox.git] / miscutils / mt.c
1 /* vi: set sw=4 ts=4: */
2 #include "internal.h"
3 #include <stdio.h>
4 #include <sys/mtio.h>
5 #include <sys/fcntl.h>
6
7 static const char mt_usage[] = "mt [-f device] opcode value\n"
8 #ifndef BB_FEATURE_TRIVIAL_HELP
9                         "\nControl magnetic tape drive operation\n"
10 #endif
11                         ;
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         {"rew", 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 extern 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         int fd;
63         
64         if ((argc != 2 && argc != 3) && **(argv + 1) != '-') {
65                 usage(mt_usage);
66         }
67
68         if (strcmp(argv[1], "-f") == 0) {
69                 if (argc < 4) {
70                         usage(mt_usage);
71                 }
72                 file = argv[2];
73                 argv += 2;
74                 argc -= 2;
75         }
76
77         while (code->name != 0) {
78                 if (strcmp(code->name, argv[1]) == 0)
79                         break;
80                 code++;
81         }
82
83         if (code->name == 0) {
84                 fprintf(stderr, "mt: unrecognized opcode %s.\n", argv[1]);
85                 exit (FALSE);
86         }
87
88         op.mt_op = code->value;
89         if (argc >= 3)
90                 op.mt_count = atoi(argv[2]);
91         else
92                 op.mt_count = 1;                /* One, not zero, right? */
93
94         if ((fd = open(file, O_RDONLY, 0)) < 0) {
95                 perror(file);
96                 exit (FALSE);
97         }
98
99         if (ioctl(fd, MTIOCTOP, &op) != 0) {
100                 perror(file);
101                 exit (FALSE);
102         }
103
104         exit (TRUE);
105 }