mt.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  4. */
  5. //config:config MT
  6. //config: bool "mt"
  7. //config: default y
  8. //config: help
  9. //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.
  12. //applet:IF_MT(APPLET(mt, BB_DIR_BIN, BB_SUID_DROP))
  13. //kbuild:lib-$(CONFIG_MT) += mt.o
  14. //usage:#define mt_trivial_usage
  15. //usage: "[-f device] opcode value"
  16. //usage:#define mt_full_usage "\n\n"
  17. //usage: "Control magnetic tape drive operation\n"
  18. //usage: "\n"
  19. //usage: "Available Opcodes:\n"
  20. //usage: "\n"
  21. //usage: "bsf bsfm bsr bss datacompression drvbuffer eof eom erase\n"
  22. //usage: "fsf fsfm fsr fss load lock mkpart nop offline ras1 ras2\n"
  23. //usage: "ras3 reset retension rewind rewoffline seek setblk setdensity\n"
  24. //usage: "setpart tell unload unlock weof wset"
  25. #include "libbb.h"
  26. #include <sys/mtio.h>
  27. /* missing: eod/seod, stoptions, stwrthreshold, densities */
  28. static const short opcode_value[] = {
  29. MTBSF,
  30. MTBSFM,
  31. MTBSR,
  32. MTBSS,
  33. MTCOMPRESSION,
  34. MTEOM,
  35. MTERASE,
  36. MTFSF,
  37. MTFSFM,
  38. MTFSR,
  39. MTFSS,
  40. MTLOAD,
  41. MTLOCK,
  42. MTMKPART,
  43. MTNOP,
  44. MTOFFL,
  45. MTOFFL,
  46. MTRAS1,
  47. MTRAS2,
  48. MTRAS3,
  49. MTRESET,
  50. MTRETEN,
  51. MTREW,
  52. MTSEEK,
  53. MTSETBLK,
  54. MTSETDENSITY,
  55. MTSETDRVBUFFER,
  56. MTSETPART,
  57. MTTELL,
  58. MTWSM,
  59. MTUNLOAD,
  60. MTUNLOCK,
  61. MTWEOF,
  62. MTWEOF
  63. };
  64. static const char opcode_name[] ALIGN1 =
  65. "bsf" "\0"
  66. "bsfm" "\0"
  67. "bsr" "\0"
  68. "bss" "\0"
  69. "datacompression" "\0"
  70. "eom" "\0"
  71. "erase" "\0"
  72. "fsf" "\0"
  73. "fsfm" "\0"
  74. "fsr" "\0"
  75. "fss" "\0"
  76. "load" "\0"
  77. "lock" "\0"
  78. "mkpart" "\0"
  79. "nop" "\0"
  80. "offline" "\0"
  81. "rewoffline" "\0"
  82. "ras1" "\0"
  83. "ras2" "\0"
  84. "ras3" "\0"
  85. "reset" "\0"
  86. "retension" "\0"
  87. "rewind" "\0"
  88. "seek" "\0"
  89. "setblk" "\0"
  90. "setdensity" "\0"
  91. "drvbuffer" "\0"
  92. "setpart" "\0"
  93. "tell" "\0"
  94. "wset" "\0"
  95. "unload" "\0"
  96. "unlock" "\0"
  97. "eof" "\0"
  98. "weof" "\0";
  99. int mt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  100. int mt_main(int argc UNUSED_PARAM, char **argv)
  101. {
  102. const char *file = "/dev/tape";
  103. struct mtop op;
  104. struct mtpos position;
  105. int fd, mode, idx;
  106. if (!argv[1]) {
  107. bb_show_usage();
  108. }
  109. if (strcmp(argv[1], "-f") == 0) {
  110. if (!argv[2] || !argv[3])
  111. bb_show_usage();
  112. file = argv[2];
  113. argv += 2;
  114. }
  115. idx = index_in_strings(opcode_name, argv[1]);
  116. if (idx < 0)
  117. bb_error_msg_and_die("unrecognized opcode %s", argv[1]);
  118. op.mt_op = opcode_value[idx];
  119. if (argv[2])
  120. op.mt_count = xatoi_positive(argv[2]);
  121. else
  122. op.mt_count = 1; /* One, not zero, right? */
  123. switch (opcode_value[idx]) {
  124. case MTWEOF:
  125. case MTERASE:
  126. case MTWSM:
  127. case MTSETDRVBUFFER:
  128. mode = O_WRONLY;
  129. break;
  130. default:
  131. mode = O_RDONLY;
  132. break;
  133. }
  134. fd = xopen(file, mode);
  135. switch (opcode_value[idx]) {
  136. case MTTELL:
  137. ioctl_or_perror_and_die(fd, MTIOCPOS, &position, "%s", file);
  138. printf("At block %d\n", (int) position.mt_blkno);
  139. break;
  140. default:
  141. ioctl_or_perror_and_die(fd, MTIOCTOP, &op, "%s", file);
  142. break;
  143. }
  144. return EXIT_SUCCESS;
  145. }