blob: fad656e956b448e89c1ed04950ae050dedca0699 [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
"Robert P. J. Day"801ab142006-07-12 07:56:04 +00002/*
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +02003 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
"Robert P. J. Day"801ab142006-07-12 07:56:04 +00004 */
Denys Vlasenkofb4da162016-11-22 23:14:24 +01005//config:config MT
Denys Vlasenko4eed2c62017-07-18 22:01:24 +02006//config: bool "mt (2.6 kb)"
Denys Vlasenkofb4da162016-11-22 23:14:24 +01007//config: default y
8//config: help
Denys Vlasenko72089cf2017-07-21 09:50:55 +02009//config: mt is used to control tape devices. You can use the mt utility
10//config: to advance or rewind a tape past a specified number of archive
11//config: files on the tape.
"Robert P. J. Day"801ab142006-07-12 07:56:04 +000012
Denys Vlasenkof88e3bf2016-11-22 23:54:17 +010013//applet:IF_MT(APPLET(mt, BB_DIR_BIN, BB_SUID_DROP))
14
15//kbuild:lib-$(CONFIG_MT) += mt.o
16
Pere Orga5bc8c002011-04-11 03:29:49 +020017//usage:#define mt_trivial_usage
18//usage: "[-f device] opcode value"
19//usage:#define mt_full_usage "\n\n"
20//usage: "Control magnetic tape drive operation\n"
21//usage: "\n"
22//usage: "Available Opcodes:\n"
23//usage: "\n"
24//usage: "bsf bsfm bsr bss datacompression drvbuffer eof eom erase\n"
25//usage: "fsf fsfm fsr fss load lock mkpart nop offline ras1 ras2\n"
26//usage: "ras3 reset retension rewind rewoffline seek setblk setdensity\n"
27//usage: "setpart tell unload unlock weof wset"
28
Denis Vlasenkob6adbf12007-05-26 19:00:18 +000029#include "libbb.h"
Eric Andersencc8ed391999-10-05 16:24:54 +000030#include <sys/mtio.h>
Eric Andersencc8ed391999-10-05 16:24:54 +000031
Denis Vlasenko8add0682007-10-11 19:38:59 +000032/* missing: eod/seod, stoptions, stwrthreshold, densities */
33static const short opcode_value[] = {
34 MTBSF,
35 MTBSFM,
36 MTBSR,
37 MTBSS,
38 MTCOMPRESSION,
39 MTEOM,
40 MTERASE,
41 MTFSF,
42 MTFSFM,
43 MTFSR,
44 MTFSS,
45 MTLOAD,
46 MTLOCK,
47 MTMKPART,
48 MTNOP,
49 MTOFFL,
50 MTOFFL,
51 MTRAS1,
52 MTRAS2,
53 MTRAS3,
54 MTRESET,
55 MTRETEN,
56 MTREW,
57 MTSEEK,
58 MTSETBLK,
59 MTSETDENSITY,
60 MTSETDRVBUFFER,
61 MTSETPART,
62 MTTELL,
63 MTWSM,
64 MTUNLOAD,
65 MTUNLOCK,
66 MTWEOF,
67 MTWEOF
Eric Andersencc8ed391999-10-05 16:24:54 +000068};
69
Denis Vlasenko8add0682007-10-11 19:38:59 +000070static const char opcode_name[] ALIGN1 =
71 "bsf" "\0"
72 "bsfm" "\0"
73 "bsr" "\0"
74 "bss" "\0"
75 "datacompression" "\0"
76 "eom" "\0"
77 "erase" "\0"
78 "fsf" "\0"
79 "fsfm" "\0"
80 "fsr" "\0"
81 "fss" "\0"
82 "load" "\0"
83 "lock" "\0"
84 "mkpart" "\0"
85 "nop" "\0"
86 "offline" "\0"
87 "rewoffline" "\0"
88 "ras1" "\0"
89 "ras2" "\0"
90 "ras3" "\0"
91 "reset" "\0"
92 "retension" "\0"
93 "rewind" "\0"
94 "seek" "\0"
95 "setblk" "\0"
96 "setdensity" "\0"
97 "drvbuffer" "\0"
98 "setpart" "\0"
99 "tell" "\0"
100 "wset" "\0"
101 "unload" "\0"
102 "unlock" "\0"
103 "eof" "\0"
104 "weof" "\0";
Eric Andersencc8ed391999-10-05 16:24:54 +0000105
Denis Vlasenko9b49a5e2007-10-11 10:05:36 +0000106int mt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denis Vlasenkoa60f84e2008-07-05 09:18:54 +0000107int mt_main(int argc UNUSED_PARAM, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +0000108{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000109 const char *file = "/dev/tape";
Erik Andersene49d5ec2000-02-08 19:58:47 +0000110 struct mtop op;
Matt Kraai73991ff2001-05-21 17:01:32 +0000111 struct mtpos position;
Denis Vlasenko8add0682007-10-11 19:38:59 +0000112 int fd, mode, idx;
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000113
Denis Vlasenko1d426652008-03-17 09:09:09 +0000114 if (!argv[1]) {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000115 bb_show_usage();
Erik Andersen5e1189e2000-04-15 16:34:54 +0000116 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000117
118 if (strcmp(argv[1], "-f") == 0) {
Denis Vlasenko1d426652008-03-17 09:09:09 +0000119 if (!argv[2] || !argv[3])
Manuel Novoa III cad53642003-03-19 09:13:01 +0000120 bb_show_usage();
Eric Andersencc8ed391999-10-05 16:24:54 +0000121 file = argv[2];
122 argv += 2;
Eric Andersencc8ed391999-10-05 16:24:54 +0000123 }
124
Denis Vlasenko8add0682007-10-11 19:38:59 +0000125 idx = index_in_strings(opcode_name, argv[1]);
Eric Andersencc8ed391999-10-05 16:24:54 +0000126
Denis Vlasenko8add0682007-10-11 19:38:59 +0000127 if (idx < 0)
128 bb_error_msg_and_die("unrecognized opcode %s", argv[1]);
Eric Andersencc8ed391999-10-05 16:24:54 +0000129
Denis Vlasenko8add0682007-10-11 19:38:59 +0000130 op.mt_op = opcode_value[idx];
Denis Vlasenko1d426652008-03-17 09:09:09 +0000131 if (argv[2])
Denys Vlasenko77832482010-08-12 14:14:45 +0200132 op.mt_count = xatoi_positive(argv[2]);
Eric Andersencc8ed391999-10-05 16:24:54 +0000133 else
Denys Vlasenkoe4dcba12010-10-28 18:57:19 +0200134 op.mt_count = 1; /* One, not zero, right? */
Eric Andersencc8ed391999-10-05 16:24:54 +0000135
Denis Vlasenko8add0682007-10-11 19:38:59 +0000136 switch (opcode_value[idx]) {
Matt Kraai13a70ac2001-05-21 15:00:39 +0000137 case MTWEOF:
138 case MTERASE:
139 case MTWSM:
140 case MTSETDRVBUFFER:
141 mode = O_WRONLY;
142 break;
143
144 default:
145 mode = O_RDONLY;
146 break;
147 }
148
Bernhard Reutner-Fischer64d7e932006-09-11 16:01:40 +0000149 fd = xopen(file, mode);
Eric Andersencc8ed391999-10-05 16:24:54 +0000150
Denis Vlasenko8add0682007-10-11 19:38:59 +0000151 switch (opcode_value[idx]) {
Matt Kraai73991ff2001-05-21 17:01:32 +0000152 case MTTELL:
Denis Vlasenkofb79a2e2007-07-14 22:07:14 +0000153 ioctl_or_perror_and_die(fd, MTIOCPOS, &position, "%s", file);
Denis Vlasenko8add0682007-10-11 19:38:59 +0000154 printf("At block %d\n", (int) position.mt_blkno);
Matt Kraai73991ff2001-05-21 17:01:32 +0000155 break;
156
157 default:
Denis Vlasenkofb79a2e2007-07-14 22:07:14 +0000158 ioctl_or_perror_and_die(fd, MTIOCTOP, &op, "%s", file);
Matt Kraai73991ff2001-05-21 17:01:32 +0000159 break;
160 }
Eric Andersencc8ed391999-10-05 16:24:54 +0000161
Matt Kraai3e856ce2000-12-01 02:55:13 +0000162 return EXIT_SUCCESS;
Eric Andersencc8ed391999-10-05 16:24:54 +0000163}