mt.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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 "libbb.h"
  6. #include <sys/mtio.h>
  7. struct mt_opcodes {
  8. const 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. int mt_main(int argc, char **argv)
  51. {
  52. const char *file = "/dev/tape";
  53. const struct mt_opcodes *code = opcodes;
  54. struct mtop op;
  55. struct mtpos position;
  56. int fd, mode;
  57. if (argc < 2) {
  58. bb_show_usage();
  59. }
  60. if (strcmp(argv[1], "-f") == 0) {
  61. if (argc < 4) {
  62. bb_show_usage();
  63. }
  64. file = argv[2];
  65. argv += 2;
  66. argc -= 2;
  67. }
  68. while (code->name != 0) {
  69. if (strcmp(code->name, argv[1]) == 0)
  70. break;
  71. code++;
  72. }
  73. if (code->name == 0) {
  74. bb_error_msg("unrecognized opcode %s", argv[1]);
  75. return EXIT_FAILURE;
  76. }
  77. op.mt_op = code->value;
  78. if (argc >= 3)
  79. op.mt_count = xatoi_u(argv[2]);
  80. else
  81. op.mt_count = 1; /* One, not zero, right? */
  82. switch (code->value) {
  83. case MTWEOF:
  84. case MTERASE:
  85. case MTWSM:
  86. case MTSETDRVBUFFER:
  87. mode = O_WRONLY;
  88. break;
  89. default:
  90. mode = O_RDONLY;
  91. break;
  92. }
  93. fd = xopen(file, mode);
  94. switch (code->value) {
  95. case MTTELL:
  96. ioctl_or_perror_and_die(fd, MTIOCPOS, &position, "%s", file);
  97. printf("At block %d.\n", (int) position.mt_blkno);
  98. break;
  99. default:
  100. ioctl_or_perror_and_die(fd, MTIOCTOP, &op, "%s", file);
  101. break;
  102. }
  103. return EXIT_SUCCESS;
  104. }