probe-libblkid.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright (C) 2016 Jo-Philipp Wich <jo@mein.io>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License version 2.1
  6. * as published by the Free Software Foundation
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <dlfcn.h>
  14. #include <string.h>
  15. #include <stdbool.h>
  16. #include <blkid/blkid.h>
  17. #include <libubox/utils.h>
  18. #include "probe.h"
  19. static struct {
  20. bool loaded;
  21. blkid_probe (*alloc)(const char *);
  22. int (*probe)(blkid_probe);
  23. int (*lookup)(blkid_probe, const char *, const char **, size_t *);
  24. void (*free)(blkid_probe);
  25. } libblkid = { };
  26. static bool
  27. load_libblkid(void)
  28. {
  29. void *lib;
  30. if (!libblkid.loaded) {
  31. lib = dlopen("libblkid.so", RTLD_GLOBAL);
  32. if (lib == NULL)
  33. lib = dlopen("libblkid.so.1", RTLD_GLOBAL);
  34. if (lib) {
  35. libblkid.alloc = dlsym(lib, "blkid_new_probe_from_filename");
  36. libblkid.probe = dlsym(lib, "blkid_do_probe");
  37. libblkid.lookup = dlsym(lib, "blkid_probe_lookup_value");
  38. libblkid.free = dlsym(lib, "blkid_free_probe");
  39. }
  40. libblkid.loaded = true;
  41. }
  42. return (libblkid.alloc && libblkid.probe && libblkid.lookup && libblkid.free);
  43. }
  44. struct probe_info *
  45. probe_path_libblkid(const char *path)
  46. {
  47. blkid_probe pr;
  48. struct probe_info *info = NULL;
  49. size_t type_len, uuid_len, label_len, version_len;
  50. char *dev_ptr, *type_ptr, *uuid_ptr, *label_ptr, *version_ptr;
  51. const char *type_val, *uuid_val, *label_val, *version_val;
  52. if (!load_libblkid())
  53. return NULL;
  54. pr = libblkid.alloc(path);
  55. if (!pr)
  56. return NULL;
  57. if (libblkid.probe(pr) == 0) {
  58. if (libblkid.lookup(pr, "TYPE", &type_val, &type_len))
  59. type_len = 0;
  60. if (libblkid.lookup(pr, "UUID", &uuid_val, &uuid_len))
  61. uuid_len = 0;
  62. if (libblkid.lookup(pr, "LABEL", &label_val, &label_len))
  63. label_len = 0;
  64. if (libblkid.lookup(pr, "VERSION", &version_val, &version_len))
  65. version_len = 0;
  66. if (type_len) {
  67. info = calloc_a(sizeof(*info),
  68. &dev_ptr, strlen(path) + 1,
  69. &type_ptr, type_len,
  70. &uuid_ptr, uuid_len,
  71. &label_ptr, label_len,
  72. &version_ptr, version_len);
  73. if (info) {
  74. info->dev = strcpy(dev_ptr, path);
  75. info->type = strcpy(type_ptr, type_val);
  76. if (uuid_len)
  77. info->uuid = strcpy(uuid_ptr, uuid_val);
  78. if (label_len)
  79. info->label = strcpy(label_ptr, label_val);
  80. if (version_len)
  81. info->version = strcpy(version_ptr, version_val);
  82. }
  83. }
  84. }
  85. libblkid.free(pr);
  86. return info;
  87. }