blob: 2720f7eab8057cd8434e076c87a006c78118f0f8 [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/*
3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
4 */
5
Bernhard Reutner-Fischerc89982d2006-06-03 19:49:21 +00006#include "busybox.h"
Eric Andersencc8ed391999-10-05 16:24:54 +00007#include <stdio.h>
Eric Andersened3ef502001-01-27 08:24:39 +00008#include <stdlib.h>
Eric Anderseneba8ed72001-03-09 14:36:42 +00009#include <string.h>
Eric Andersencc8ed391999-10-05 16:24:54 +000010#include <sys/mtio.h>
Mike Frysinger59c6bae2006-04-29 04:43:50 +000011#include <fcntl.h>
Eric Andersencc8ed391999-10-05 16:24:54 +000012
Eric Andersencc8ed391999-10-05 16:24:54 +000013struct mt_opcodes {
Erik Andersene49d5ec2000-02-08 19:58:47 +000014 char *name;
15 short value;
Eric Andersencc8ed391999-10-05 16:24:54 +000016};
17
18/* missing: eod/seod, stoptions, stwrthreshold, densities */
Erik Andersene49d5ec2000-02-08 19:58:47 +000019static 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},
Matt Kraai1eb4acf2001-05-22 14:32:35 +000042 {"rewind", MTREW},
Erik Andersene49d5ec2000-02-08 19:58:47 +000043 {"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}
Eric Andersencc8ed391999-10-05 16:24:54 +000055};
56
Rob Landleydfba7412006-03-06 20:47:33 +000057int mt_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000058{
Erik Andersene49d5ec2000-02-08 19:58:47 +000059 const char *file = "/dev/tape";
60 const struct mt_opcodes *code = opcodes;
61 struct mtop op;
Matt Kraai73991ff2001-05-21 17:01:32 +000062 struct mtpos position;
Matt Kraai13a70ac2001-05-21 15:00:39 +000063 int fd, mode;
Eric Andersenc7bda1c2004-03-15 08:29:22 +000064
Eric Andersen1eec89d2000-09-05 18:21:53 +000065 if (argc < 2) {
Manuel Novoa III cad53642003-03-19 09:13:01 +000066 bb_show_usage();
Erik Andersen5e1189e2000-04-15 16:34:54 +000067 }
Erik Andersene49d5ec2000-02-08 19:58:47 +000068
69 if (strcmp(argv[1], "-f") == 0) {
70 if (argc < 4) {
Manuel Novoa III cad53642003-03-19 09:13:01 +000071 bb_show_usage();
Eric Andersencc8ed391999-10-05 16:24:54 +000072 }
73 file = argv[2];
74 argv += 2;
75 argc -= 2;
76 }
77
Erik Andersene49d5ec2000-02-08 19:58:47 +000078 while (code->name != 0) {
79 if (strcmp(code->name, argv[1]) == 0)
Eric Andersencc8ed391999-10-05 16:24:54 +000080 break;
81 code++;
82 }
83
Erik Andersene49d5ec2000-02-08 19:58:47 +000084 if (code->name == 0) {
Manuel Novoa III cad53642003-03-19 09:13:01 +000085 bb_error_msg("unrecognized opcode %s.", argv[1]);
Matt Kraai3e856ce2000-12-01 02:55:13 +000086 return EXIT_FAILURE;
Eric Andersencc8ed391999-10-05 16:24:54 +000087 }
88
89 op.mt_op = code->value;
Erik Andersene49d5ec2000-02-08 19:58:47 +000090 if (argc >= 3)
91 op.mt_count = atoi(argv[2]);
Eric Andersencc8ed391999-10-05 16:24:54 +000092 else
Erik Andersene49d5ec2000-02-08 19:58:47 +000093 op.mt_count = 1; /* One, not zero, right? */
Eric Andersencc8ed391999-10-05 16:24:54 +000094
Matt Kraai13a70ac2001-05-21 15:00:39 +000095 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
Bernhard Reutner-Fischerc2cb0f32006-04-13 12:45:04 +0000108 fd = bb_xopen3(file, mode, 0);
Eric Andersencc8ed391999-10-05 16:24:54 +0000109
Matt Kraai73991ff2001-05-21 17:01:32 +0000110 switch (code->value) {
111 case MTTELL:
112 if (ioctl(fd, MTIOCPOS, &position) < 0)
Manuel Novoa III cad53642003-03-19 09:13:01 +0000113 bb_perror_msg_and_die("%s", file);
Matt Kraai73991ff2001-05-21 17:01:32 +0000114 printf ("At block %d.\n", (int) position.mt_blkno);
115 break;
116
117 default:
118 if (ioctl(fd, MTIOCTOP, &op) != 0)
Manuel Novoa III cad53642003-03-19 09:13:01 +0000119 bb_perror_msg_and_die("%s", file);
Matt Kraai73991ff2001-05-21 17:01:32 +0000120 break;
121 }
Eric Andersencc8ed391999-10-05 16:24:54 +0000122
Matt Kraai3e856ce2000-12-01 02:55:13 +0000123 return EXIT_SUCCESS;
Eric Andersencc8ed391999-10-05 16:24:54 +0000124}