"Fossies" - the Fresh Open Source Software Archive 
Member "cryptsetup-2.4.3/lib/utils_blkid.c" (13 Jan 2022, 6561 Bytes) of package /linux/misc/cryptsetup-2.4.3.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "utils_blkid.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 * blkid probe utilities
3 *
4 * Copyright (C) 2018-2021 Red Hat, Inc. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26
27 #include "utils_blkid.h"
28 #include "utils_io.h"
29
30 #ifdef HAVE_BLKID
31 #include <blkid/blkid.h>
32 /* make bad checksums flag optional */
33 #ifndef BLKID_SUBLKS_BADCSUM
34 #define BLKID_SUBLKS_BADCSUM 0
35 #endif
36 struct blkid_handle {
37 int fd;
38 blkid_probe pr;
39 };
40 #ifndef HAVE_BLKID_WIPE
41 static size_t crypt_getpagesize(void)
42 {
43 long r = sysconf(_SC_PAGESIZE);
44 return r <= 0 ? 4096 : (size_t)r;
45 }
46 #endif
47 #endif
48
49 void blk_set_chains_for_wipes(struct blkid_handle *h)
50 {
51 #ifdef HAVE_BLKID
52 blkid_probe_enable_partitions(h->pr, 1);
53 blkid_probe_set_partitions_flags(h->pr, 0
54 #ifdef HAVE_BLKID_WIPE
55 | BLKID_PARTS_MAGIC
56 #endif
57 );
58
59 blkid_probe_enable_superblocks(h->pr, 1);
60 blkid_probe_set_superblocks_flags(h->pr, BLKID_SUBLKS_LABEL |
61 BLKID_SUBLKS_UUID |
62 BLKID_SUBLKS_TYPE |
63 BLKID_SUBLKS_USAGE |
64 BLKID_SUBLKS_VERSION |
65 BLKID_SUBLKS_MAGIC |
66 BLKID_SUBLKS_BADCSUM);
67 #endif
68 }
69
70 void blk_set_chains_for_full_print(struct blkid_handle *h)
71 {
72 blk_set_chains_for_wipes(h);
73 }
74
75 void blk_set_chains_for_fast_detection(struct blkid_handle *h)
76 {
77 #ifdef HAVE_BLKID
78 blkid_probe_enable_partitions(h->pr, 1);
79 blkid_probe_set_partitions_flags(h->pr, 0);
80
81 blkid_probe_enable_superblocks(h->pr, 1);
82 blkid_probe_set_superblocks_flags(h->pr, BLKID_SUBLKS_TYPE);
83 #endif
84 }
85
86 int blk_init_by_path(struct blkid_handle **h, const char *path)
87 {
88 int r = -ENOTSUP;
89 #ifdef HAVE_BLKID
90 struct blkid_handle *tmp = malloc(sizeof(*tmp));
91 if (!tmp)
92 return -ENOMEM;
93
94 tmp->fd = -1;
95
96 tmp->pr = blkid_new_probe_from_filename(path);
97 if (!tmp->pr) {
98 free(tmp);
99 return -EINVAL;
100 }
101
102 *h = tmp;
103
104 r = 0;
105 #endif
106 return r;
107 }
108
109 int blk_init_by_fd(struct blkid_handle **h, int fd)
110 {
111 int r = -ENOTSUP;
112 #ifdef HAVE_BLKID
113 struct blkid_handle *tmp = malloc(sizeof(*tmp));
114 if (!tmp)
115 return -ENOMEM;
116
117 tmp->pr = blkid_new_probe();
118 if (!tmp->pr) {
119 free(tmp);
120 return -EINVAL;
121 }
122
123 if (blkid_probe_set_device(tmp->pr, fd, 0, 0)) {
124 blkid_free_probe(tmp->pr);
125 free(tmp);
126 return -EINVAL;
127 }
128
129 tmp->fd = fd;
130
131 *h = tmp;
132
133 r = 0;
134 #endif
135 return r;
136 }
137
138 int blk_superblocks_filter_luks(struct blkid_handle *h)
139 {
140 int r = -ENOTSUP;
141 #ifdef HAVE_BLKID
142 char luks[] = "crypto_LUKS";
143 char *luks_filter[] = {
144 luks,
145 NULL
146 };
147 r = blkid_probe_filter_superblocks_type(h->pr, BLKID_FLTR_NOTIN, luks_filter);
148 #endif
149 return r;
150 }
151
152 blk_probe_status blk_probe(struct blkid_handle *h)
153 {
154 blk_probe_status pr = PRB_FAIL;
155 #ifdef HAVE_BLKID
156 int r = blkid_do_probe(h->pr);
157
158 if (r == 0)
159 pr = PRB_OK;
160 else if (r == 1)
161 pr = PRB_EMPTY;
162 #endif
163 return pr;
164 }
165
166 blk_probe_status blk_safeprobe(struct blkid_handle *h)
167 {
168 int r = -1;
169 #ifdef HAVE_BLKID
170 r = blkid_do_safeprobe(h->pr);
171 #endif
172 switch (r) {
173 case -2:
174 return PRB_AMBIGUOUS;
175 case 1:
176 return PRB_EMPTY;
177 case 0:
178 return PRB_OK;
179 default:
180 return PRB_FAIL;
181 }
182 }
183
184 int blk_is_partition(struct blkid_handle *h)
185 {
186 int r = 0;
187 #ifdef HAVE_BLKID
188 r = blkid_probe_has_value(h->pr, "PTTYPE");
189 #endif
190 return r;
191 }
192
193 int blk_is_superblock(struct blkid_handle *h)
194 {
195 int r = 0;
196 #ifdef HAVE_BLKID
197 r = blkid_probe_has_value(h->pr, "TYPE");
198 #endif
199 return r;
200 }
201
202 const char *blk_get_partition_type(struct blkid_handle *h)
203 {
204 const char *value = NULL;
205 #ifdef HAVE_BLKID
206 (void) blkid_probe_lookup_value(h->pr, "PTTYPE", &value, NULL);
207 #endif
208 return value;
209 }
210
211 const char *blk_get_superblock_type(struct blkid_handle *h)
212 {
213 const char *value = NULL;
214 #ifdef HAVE_BLKID
215 (void) blkid_probe_lookup_value(h->pr, "TYPE", &value, NULL);
216 #endif
217 return value;
218 }
219
220 void blk_free(struct blkid_handle *h)
221 {
222 #ifdef HAVE_BLKID
223 if (!h)
224 return;
225
226 if (h->pr)
227 blkid_free_probe(h->pr);
228
229 free(h);
230 #endif
231 }
232
233 #ifdef HAVE_BLKID
234 #ifndef HAVE_BLKID_WIPE
235 static int blk_step_back(struct blkid_handle *h)
236 {
237 #ifdef HAVE_BLKID_STEP_BACK
238 return blkid_probe_step_back(h->pr);
239 #else
240 blkid_reset_probe(h->pr);
241 blkid_probe_set_device(h->pr, h->fd, 0, 0);
242 return 0;
243 #endif
244 }
245 #endif /* not HAVE_BLKID_WIPE */
246 #endif /* HAVE_BLKID */
247
248 int blk_do_wipe(struct blkid_handle *h)
249 {
250 #ifdef HAVE_BLKID
251 #ifdef HAVE_BLKID_WIPE
252 return blkid_do_wipe(h->pr, 0);
253 #else
254 const char *offset;
255 off_t offset_val;
256 void *buf;
257 ssize_t ret;
258 size_t alignment, len, bsize = blkid_probe_get_sectorsize(h->pr);
259
260 if (h->fd < 0 || !bsize)
261 return -EINVAL;
262
263 if (blk_is_partition(h)) {
264 if (blkid_probe_lookup_value(h->pr, "PTMAGIC_OFFSET", &offset, NULL))
265 return -EINVAL;
266 if (blkid_probe_lookup_value(h->pr, "PTMAGIC", NULL, &len))
267 return -EINVAL;
268 } else if (blk_is_superblock(h)) {
269 if (blkid_probe_lookup_value(h->pr, "SBMAGIC_OFFSET", &offset, NULL))
270 return -EINVAL;
271 if (blkid_probe_lookup_value(h->pr, "SBMAGIC", NULL, &len))
272 return -EINVAL;
273 } else
274 return 0;
275
276 alignment = crypt_getpagesize();
277
278 if (posix_memalign(&buf, alignment, len))
279 return -EINVAL;
280 memset(buf, 0, len);
281
282 offset_val = strtoll(offset, NULL, 10);
283
284 /* TODO: missing crypt_wipe_fd() */
285 ret = write_lseek_blockwise(h->fd, bsize, alignment, buf, len, offset_val);
286 free(buf);
287 if (ret < 0)
288 return -EIO;
289
290 if ((size_t)ret == len) {
291 blk_step_back(h);
292 return 0;
293 }
294
295 return -EIO;
296 #endif
297 #else /* HAVE_BLKID */
298 return -ENOTSUP;
299 #endif
300 }
301
302 int blk_supported(void)
303 {
304 int r = 0;
305 #ifdef HAVE_BLKID
306 r = 1;
307 #endif
308 return r;
309 }
310
311 off_t blk_get_offset(struct blkid_handle *h)
312 {
313 off_t offset_value = -1;
314 #ifdef HAVE_BLKID
315 const char *offset;
316 if (blk_is_superblock(h)) {
317 if (!blkid_probe_lookup_value(h->pr, "SBMAGIC_OFFSET", &offset, NULL))
318 offset_value = strtoll(offset, NULL, 10);
319 } else if (blk_is_partition(h) && !blkid_probe_lookup_value(h->pr, "PTMAGIC_OFFSET", &offset, NULL))
320 offset_value = strtoll(offset, NULL, 10);
321 #endif
322 return offset_value;
323 }