mt.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  4. */
  5. #include "busybox.h"
  6. #include <sys/mtio.h>
  7. struct mt_opcodes {
  8. char *name;
  9. short value;
  10. };
  11. /* missing: eod/seod, stoptions, stwrthreshold, densities */
  12. static const struct mt_opcodes opcodes[] = {
  13. {"bsf", MTBSF},
  14. {"bsfm", MTBSFM},
  15. {"bsr", MTBSR},
  16. {"bss", MTBSS},
  17. {"datacompression", MTCOMPRESSION},
  18. {"eom", MTEOM},
  19. {"erase", MTERASE},
  20. {"fsf", MTFSF},
  21. {"fsfm", MTFSFM},
  22. {"fsr", MTFSR},
  23. {"fss", MTFSS},
  24. {"load", MTLOAD},
  25. {"lock", MTLOCK},
  26. {"mkpart", MTMKPART},
  27. {"nop", MTNOP},
  28. {"offline", MTOFFL},
  29. {"rewoffline", MTOFFL},
  30. {"ras1", MTRAS1},
  31. {"ras2", MTRAS2},
  32. {"ras3", MTRAS3},
  33. {"reset", MTRESET},
  34. {"retension", MTRETEN},
  35. {"rewind", MTREW},
  36. {"seek", MTSEEK},
  37. {"setblk", MTSETBLK},
  38. {"setdensity", MTSETDENSITY},
  39. {"drvbuffer", MTSETDRVBUFFER},
  40. {"setpart", MTSETPART},
  41. {"tell", MTTELL},
  42. {"wset", MTWSM},
  43. {"unload", MTUNLOAD},
  44. {"unlock", MTUNLOCK},
  45. {"eof", MTWEOF},
  46. {"weof", MTWEOF},
  47. {0, 0}
  48. };
  49. int mt_main(int argc, char **argv)
  50. {
  51. const char *file = "/dev/tape";
  52. const struct mt_opcodes *code = opcodes;
  53. struct mtop op;
  54. struct mtpos position;
  55. int fd, mode;
  56. if (argc < 2) {
  57. bb_show_usage();
  58. }
  59. if (strcmp(argv[1], "-f") == 0) {
  60. if (argc < 4) {
  61. bb_show_usage();
  62. }
  63. file = argv[2];
  64. argv += 2;
  65. argc -= 2;
  66. }
  67. while (code->name != 0) {
  68. if (strcmp(code->name, argv[1]) == 0)
  69. break;
  70. code++;
  71. }
  72. if (code->name == 0) {
  73. bb_error_msg("unrecognized opcode %s", argv[1]);
  74. return EXIT_FAILURE;
  75. }
  76. op.mt_op = code->value;
  77. if (argc >= 3)
  78. op.mt_count = xatoi_u(argv[2]);
  79. else
  80. op.mt_count = 1; /* One, not zero, right? */
  81. switch (code->value) {
  82. case MTWEOF:
  83. case MTERASE:
  84. case MTWSM:
  85. case MTSETDRVBUFFER:
  86. mode = O_WRONLY;
  87. break;
  88. default:
  89. mode = O_RDONLY;
  90. break;
  91. }
  92. fd = xopen(file, mode);
  93. switch (code->value) {
  94. case MTTELL:
  95. if (ioctl(fd, MTIOCPOS, &position) < 0)
  96. bb_perror_msg_and_die("%s", file);
  97. printf("At block %d.\n", (int) position.mt_blkno);
  98. break;
  99. default:
  100. if (ioctl(fd, MTIOCTOP, &op) != 0)
  101. bb_perror_msg_and_die("%s", file);
  102. break;
  103. }
  104. return EXIT_SUCCESS;
  105. }