probe: add full libblkid support
[project/fstools.git] / probe-libblkid.c
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
14 #include <dlfcn.h>
15 #include <string.h>
16 #include <stdbool.h>
17 #include <blkid/blkid.h>
18 #include <libubox/utils.h>
19
20 #include "probe.h"
21
22
23 static struct {
24 bool loaded;
25 blkid_probe (*alloc)(const char *);
26 int (*probe)(blkid_probe);
27 int (*lookup)(blkid_probe, const char *, const char **, size_t *);
28 void (*free)(blkid_probe);
29 } libblkid = { };
30
31
32 static bool
33 load_libblkid(void)
34 {
35 void *lib;
36
37 if (!libblkid.loaded) {
38 lib = dlopen("libblkid.so", RTLD_GLOBAL);
39
40 if (lib) {
41 libblkid.alloc = dlsym(lib, "blkid_new_probe_from_filename");
42 libblkid.probe = dlsym(lib, "blkid_do_probe");
43 libblkid.lookup = dlsym(lib, "blkid_probe_lookup_value");
44 libblkid.free = dlsym(lib, "blkid_free_probe");
45 }
46
47 libblkid.loaded = true;
48 }
49
50 return (libblkid.alloc && libblkid.probe && libblkid.lookup && libblkid.free);
51 }
52
53 struct probe_info *
54 probe_path_libblkid(const char *path)
55 {
56 blkid_probe pr;
57 struct probe_info *info = NULL;
58 size_t type_len, uuid_len, label_len, name_len, version_len;
59 char *dev_ptr, *type_ptr, *uuid_ptr, *label_ptr, *name_ptr, *version_ptr;
60 const char *type_val, *uuid_val, *label_val, *name_val, *version_val;
61
62 if (!load_libblkid())
63 return NULL;
64
65 pr = libblkid.alloc(path);
66
67 if (!pr)
68 return NULL;
69
70 if (libblkid.probe(pr) == 0) {
71 if (libblkid.lookup(pr, "TYPE", &type_val, &type_len))
72 type_len = 0;
73
74 if (libblkid.lookup(pr, "UUID", &uuid_val, &uuid_len))
75 uuid_len = 0;
76
77 if (libblkid.lookup(pr, "LABEL", &label_val, &label_len))
78 label_len = 0;
79
80 if (libblkid.lookup(pr, "NAME", &name_val, &name_len))
81 name_len = 0;
82
83 if (libblkid.lookup(pr, "VERSION", &version_val, &version_len))
84 version_len = 0;
85
86 if (type_len) {
87 info = calloc_a(sizeof(*info),
88 &dev_ptr, strlen(path) + 1,
89 &type_ptr, type_len,
90 &uuid_ptr, uuid_len,
91 &label_ptr, label_len,
92 &name_ptr, name_len,
93 &version_ptr, version_len);
94
95 if (info) {
96 info->dev = strcpy(dev_ptr, path);
97 info->type = strcpy(type_ptr, type_val);
98
99 if (uuid_len)
100 info->uuid = strcpy(uuid_ptr, uuid_val);
101
102 if (label_len)
103 info->label = strcpy(label_ptr, label_val);
104
105 if (name_len)
106 info->name = strcpy(name_ptr, name_val);
107
108 if (version_len)
109 info->version = strcpy(version_ptr, version_val);
110 }
111 }
112 }
113
114 libblkid.free(pr);
115
116 return info;
117 }