X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=miscutils%2Fmt.c;h=fad656e956b448e89c1ed04950ae050dedca0699;hb=d72e804e6db1bd6eb2417961004b4fe33aba9384;hp=7d75fbd3d50d9a298b0937cf07c6149a23735370;hpb=cc8ed39b240180b58810784f844e253263594ac3;p=oweals%2Fbusybox.git diff --git a/miscutils/mt.c b/miscutils/mt.c index 7d75fbd3d..fad656e95 100644 --- a/miscutils/mt.c +++ b/miscutils/mt.c @@ -1,98 +1,163 @@ -#include "internal.h" -#include -#include -#include +/* vi: set sw=4 ts=4: */ +/* + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ +//config:config MT +//config: bool "mt (2.6 kb)" +//config: default y +//config: help +//config: mt is used to control tape devices. You can use the mt utility +//config: to advance or rewind a tape past a specified number of archive +//config: files on the tape. -const char mt_usage[] = "mt [-f device] opcode value\n"; +//applet:IF_MT(APPLET(mt, BB_DIR_BIN, BB_SUID_DROP)) -struct mt_opcodes { - char * name; - short value; -}; +//kbuild:lib-$(CONFIG_MT) += mt.o + +//usage:#define mt_trivial_usage +//usage: "[-f device] opcode value" +//usage:#define mt_full_usage "\n\n" +//usage: "Control magnetic tape drive operation\n" +//usage: "\n" +//usage: "Available Opcodes:\n" +//usage: "\n" +//usage: "bsf bsfm bsr bss datacompression drvbuffer eof eom erase\n" +//usage: "fsf fsfm fsr fss load lock mkpart nop offline ras1 ras2\n" +//usage: "ras3 reset retension rewind rewoffline seek setblk setdensity\n" +//usage: "setpart tell unload unlock weof wset" + +#include "libbb.h" +#include /* missing: eod/seod, stoptions, stwrthreshold, densities */ -static const struct mt_opcodes opcodes[] = { - { "bsf", MTBSF }, - { "bsfm", MTBSFM }, - { "bsr", MTBSR }, - { "bss", MTBSS }, - { "datacompression", MTCOMPRESSION }, - { "eom", MTEOM }, - { "erase", MTERASE }, - { "fsf", MTFSF }, - { "fsfm", MTFSFM }, - { "fsr", MTFSR }, - { "fss", MTFSS }, - { "load", MTLOAD }, - { "lock", MTLOCK }, - { "mkpart", MTMKPART }, - { "nop", MTNOP }, - { "offline",MTOFFL }, - { "rewoffline",MTOFFL }, - { "ras1", MTRAS1 }, - { "ras2", MTRAS2 }, - { "ras3", MTRAS3 }, - { "reset", MTRESET }, - { "retension", MTRETEN }, - { "rew", MTREW }, - { "seek", MTSEEK }, - { "setblk", MTSETBLK }, - { "setdensity", MTSETDENSITY }, - { "drvbuffer", MTSETDRVBUFFER }, - { "setpart", MTSETPART }, - { "tell", MTTELL }, - { "wset", MTWSM }, - { "unload", MTUNLOAD }, - { "unlock", MTUNLOCK }, - { "eof", MTWEOF }, - { "weof", MTWEOF }, - { 0, 0 } +static const short opcode_value[] = { + MTBSF, + MTBSFM, + MTBSR, + MTBSS, + MTCOMPRESSION, + MTEOM, + MTERASE, + MTFSF, + MTFSFM, + MTFSR, + MTFSS, + MTLOAD, + MTLOCK, + MTMKPART, + MTNOP, + MTOFFL, + MTOFFL, + MTRAS1, + MTRAS2, + MTRAS3, + MTRESET, + MTRETEN, + MTREW, + MTSEEK, + MTSETBLK, + MTSETDENSITY, + MTSETDRVBUFFER, + MTSETPART, + MTTELL, + MTWSM, + MTUNLOAD, + MTUNLOCK, + MTWEOF, + MTWEOF }; -extern int -mt_main(struct FileInfo * i, int argc, char * * argv) +static const char opcode_name[] ALIGN1 = + "bsf" "\0" + "bsfm" "\0" + "bsr" "\0" + "bss" "\0" + "datacompression" "\0" + "eom" "\0" + "erase" "\0" + "fsf" "\0" + "fsfm" "\0" + "fsr" "\0" + "fss" "\0" + "load" "\0" + "lock" "\0" + "mkpart" "\0" + "nop" "\0" + "offline" "\0" + "rewoffline" "\0" + "ras1" "\0" + "ras2" "\0" + "ras3" "\0" + "reset" "\0" + "retension" "\0" + "rewind" "\0" + "seek" "\0" + "setblk" "\0" + "setdensity" "\0" + "drvbuffer" "\0" + "setpart" "\0" + "tell" "\0" + "wset" "\0" + "unload" "\0" + "unlock" "\0" + "eof" "\0" + "weof" "\0"; + +int mt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int mt_main(int argc UNUSED_PARAM, char **argv) { - const char * file = "/dev/tape"; - const struct mt_opcodes * code = opcodes; - struct mtop op; - int fd; - - if ( strcmp(argv[1], "-f") == 0 ) { - if ( argc < 4 ) { - usage(mt_usage); - return 1; - } + const char *file = "/dev/tape"; + struct mtop op; + struct mtpos position; + int fd, mode, idx; + + if (!argv[1]) { + bb_show_usage(); + } + + if (strcmp(argv[1], "-f") == 0) { + if (!argv[2] || !argv[3]) + bb_show_usage(); file = argv[2]; argv += 2; - argc -= 2; } - while ( code->name != 0 ) { - if ( strcmp(code->name, argv[1]) == 0 ) - break; - code++; - } + idx = index_in_strings(opcode_name, argv[1]); - if ( code->name == 0 ) { - fprintf(stderr, "mt: unrecognized opcode %s.\n", argv[1]); - return 1; - } + if (idx < 0) + bb_error_msg_and_die("unrecognized opcode %s", argv[1]); - op.mt_op = code->value; - if ( argc >= 3 ) - op.mt_count = atoi(argv[2]); + op.mt_op = opcode_value[idx]; + if (argv[2]) + op.mt_count = xatoi_positive(argv[2]); else - op.mt_count = 1; /* One, not zero, right? */ + op.mt_count = 1; /* One, not zero, right? */ - if ( (fd = open(file, O_RDONLY, 0)) < 0 ) { - name_and_error(file); - return 1; + switch (opcode_value[idx]) { + case MTWEOF: + case MTERASE: + case MTWSM: + case MTSETDRVBUFFER: + mode = O_WRONLY; + break; + + default: + mode = O_RDONLY; + break; } - if ( ioctl(fd, MTIOCTOP, &op) != 0 ) { - name_and_error(file); - return 1; + fd = xopen(file, mode); + + switch (opcode_value[idx]) { + case MTTELL: + ioctl_or_perror_and_die(fd, MTIOCPOS, &position, "%s", file); + printf("At block %d\n", (int) position.mt_blkno); + break; + + default: + ioctl_or_perror_and_die(fd, MTIOCTOP, &op, "%s", file); + break; } - return 0; + return EXIT_SUCCESS; }