losetup.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Mini losetup implementation for busybox
  4. *
  5. * Copyright (C) 2002 Matt Kraai.
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  8. */
  9. //usage:#define losetup_trivial_usage
  10. //usage: "[-r] [-o OFS] {-f|LOOPDEV} FILE - associate loop devices\n"
  11. //usage: " losetup -d LOOPDEV - disassociate\n"
  12. //usage: " losetup -a - show status\n"
  13. //usage: " losetup -f - show next free loop device"
  14. //usage:#define losetup_full_usage "\n\n"
  15. //usage: " -o OFS Start OFS bytes into FILE"
  16. //usage: "\n -r Read-only"
  17. //usage: "\n -f Show/use next free loop device"
  18. //usage:
  19. //usage:#define losetup_notes_usage
  20. //usage: "One argument (losetup /dev/loop1) will display the current association\n"
  21. //usage: "(if any), or disassociate it (with -d). The display shows the offset\n"
  22. //usage: "and filename of the file the loop device is currently bound to.\n\n"
  23. //usage: "Two arguments (losetup /dev/loop1 file.img) create a new association,\n"
  24. //usage: "with an optional offset (-o 12345). Encryption is not yet supported.\n"
  25. //usage: "losetup -f will show the first loop free loop device\n\n"
  26. #include "libbb.h"
  27. /* 1048575 is a max possible minor number in Linux circa 2010 */
  28. /* for now use something less extreme */
  29. #define MAX_LOOP_NUM 1023
  30. int losetup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  31. int losetup_main(int argc UNUSED_PARAM, char **argv)
  32. {
  33. unsigned opt;
  34. char *opt_o;
  35. char dev[LOOP_NAMESIZE];
  36. enum {
  37. OPT_d = (1 << 0),
  38. OPT_o = (1 << 1),
  39. OPT_f = (1 << 2),
  40. OPT_a = (1 << 3),
  41. OPT_r = (1 << 4), /* must be last */
  42. };
  43. opt_complementary = "?2:d--ofar:a--ofr";
  44. opt = getopt32(argv, "do:far", &opt_o);
  45. argv += optind;
  46. /* LOOPDEV */
  47. if (!opt && argv[0] && !argv[1]) {
  48. char *s;
  49. s = query_loop(argv[0]);
  50. if (!s)
  51. bb_simple_perror_msg_and_die(argv[0]);
  52. printf("%s: %s\n", argv[0], s);
  53. if (ENABLE_FEATURE_CLEAN_UP)
  54. free(s);
  55. return EXIT_SUCCESS;
  56. }
  57. /* -d LOOPDEV */
  58. if (opt == OPT_d && argv[0]) {
  59. if (del_loop(argv[0]))
  60. bb_simple_perror_msg_and_die(argv[0]);
  61. return EXIT_SUCCESS;
  62. }
  63. /* -a */
  64. if (opt == OPT_a) {
  65. int n;
  66. for (n = 0; n < MAX_LOOP_NUM; n++) {
  67. char *s;
  68. sprintf(dev, LOOP_FORMAT, n);
  69. s = query_loop(dev);
  70. if (s) {
  71. printf("%s: %s\n", dev, s);
  72. free(s);
  73. }
  74. }
  75. return EXIT_SUCCESS;
  76. }
  77. /* contains -f */
  78. if (opt & OPT_f) {
  79. char *s;
  80. int n = 0;
  81. do {
  82. if (n > MAX_LOOP_NUM)
  83. bb_error_msg_and_die("no free loop devices");
  84. sprintf(dev, LOOP_FORMAT, n++);
  85. s = query_loop(dev);
  86. free(s);
  87. } while (s);
  88. /* now: dev is next free "/dev/loopN" */
  89. if ((opt == OPT_f) && !argv[0]) {
  90. puts(dev);
  91. return EXIT_SUCCESS;
  92. }
  93. }
  94. /* [-r] [-o OFS] {-f|LOOPDEV} FILE */
  95. if (argv[0] && ((opt & OPT_f) || argv[1])) {
  96. unsigned long long offset = 0;
  97. char *d = dev;
  98. if (opt & OPT_o)
  99. offset = xatoull(opt_o);
  100. if (!(opt & OPT_f))
  101. d = *argv++;
  102. if (argv[0]) {
  103. if (set_loop(&d, argv[0], offset, (opt & OPT_r)) < 0)
  104. bb_simple_perror_msg_and_die(argv[0]);
  105. return EXIT_SUCCESS;
  106. }
  107. }
  108. bb_show_usage(); /* does not return */
  109. /*return EXIT_FAILURE;*/
  110. }