mountpoint.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * mountpoint implementation for busybox
  4. *
  5. * Copyright (C) 2005 Bernhard Reutner-Fischer
  6. *
  7. * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
  8. *
  9. * Based on sysvinit's mountpoint
  10. */
  11. #include "libbb.h"
  12. int mountpoint_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  13. int mountpoint_main(int argc UNUSED_PARAM, char **argv)
  14. {
  15. struct stat st;
  16. const char *msg;
  17. char *arg;
  18. int rc, opt;
  19. opt_complementary = "=1"; /* must have one argument */
  20. opt = getopt32(argv, "qdxn");
  21. #define OPT_q (1)
  22. #define OPT_d (2)
  23. #define OPT_x (4)
  24. #define OPT_n (8)
  25. arg = argv[optind];
  26. msg = "%s";
  27. rc = (opt & OPT_x) ? stat(arg, &st) : lstat(arg, &st);
  28. if (rc != 0)
  29. goto err;
  30. if (opt & OPT_x) {
  31. if (S_ISBLK(st.st_mode)) {
  32. printf("%u:%u\n", major(st.st_rdev),
  33. minor(st.st_rdev));
  34. return EXIT_SUCCESS;
  35. }
  36. errno = 0; /* make perror_msg work as error_msg */
  37. msg = "%s: not a block device";
  38. goto err;
  39. }
  40. errno = ENOTDIR;
  41. if (S_ISDIR(st.st_mode)) {
  42. dev_t st_dev = st.st_dev;
  43. ino_t st_ino = st.st_ino;
  44. char *p = xasprintf("%s/..", arg);
  45. if (stat(p, &st) == 0) {
  46. //int is_mnt = (st_dev != st.st_dev) || (st_dev == st.st_dev && st_ino == st.st_ino);
  47. int is_not_mnt = (st_dev == st.st_dev) && (st_ino != st.st_ino);
  48. if (opt & OPT_d)
  49. printf("%u:%u\n", major(st_dev), minor(st_dev));
  50. if (opt & OPT_n) {
  51. const char *d = find_block_device(arg);
  52. /* name is undefined, but device is mounted -> anonymous superblock! */
  53. /* happens with btrfs */
  54. if (!d) {
  55. d = "UNKNOWN";
  56. /* TODO: iterate /proc/mounts, or /proc/self/mountinfo
  57. * to find out the device name */
  58. }
  59. printf("%s %s\n", d, arg);
  60. }
  61. if (!(opt & (OPT_q | OPT_d | OPT_n)))
  62. printf("%s is %sa mountpoint\n", arg, is_not_mnt ? "not " : "");
  63. return is_not_mnt;
  64. }
  65. arg = p;
  66. /* else: stat had set errno, just fall through */
  67. }
  68. err:
  69. if (!(opt & OPT_q))
  70. bb_perror_msg(msg, arg);
  71. return EXIT_FAILURE;
  72. }