blob: 9d0d2cb1809ee5a6c15f989044af340233f7485c [file] [log] [blame]
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001/*
2 * superblocks.c - reads information from filesystem and raid superblocks
3 *
4 * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
5 *
6 * This file may be redistributed under the terms of the
7 * GNU Lesser General Public License.
8 */
9
10#include <stdio.h>
11#include <string.h>
12#include <stdlib.h>
13#include <unistd.h>
14#include <fcntl.h>
15#include <ctype.h>
16#include <sys/types.h>
17#include <sys/stat.h>
18#include <errno.h>
19#include <stdint.h>
20#include <stdarg.h>
21
22#include "superblocks.h"
23
24/**
25 * SECTION:superblocks
26 * @title: Superblocks probing
27 * @short_description: filesystems and raids superblocks probing.
28 *
29 * The library API has been originally designed for superblocks probing only.
30 * This is reason why some *deprecated* superblock specific functions don't use
31 * '_superblocks_' namespace in the function name. Please, don't use these
32 * functions in new code.
33 *
34 * The 'superblocks' probers support NAME=value (tags) interface only. The
35 * superblocks probing is enabled by default (and controlled by
36 * blkid_probe_enable_superblocks()).
37 *
38 * Currently supported tags:
39 *
40 * @TYPE: filesystem type
41 *
42 * @SEC_TYPE: secondary filesystem type
43 *
44 * @LABEL: filesystem label
45 *
46 * @LABEL_RAW: raw label from FS superblock
47 *
48 * @UUID: filesystem UUID (lower case)
49 *
50 * @UUID_SUB: subvolume uuid (e.g. btrfs)
51 *
bigbiff7b4c7a62015-01-01 19:44:14 -050052 * @LOGUUID: external log UUID (e.g. xfs)
53 *
bigbiff bigbiffe60683a2013-02-22 20:55:50 -050054 * @UUID_RAW: raw UUID from FS superblock
55 *
56 * @EXT_JOURNAL: external journal UUID
57 *
58 * @USAGE: usage string: "raid", "filesystem", ...
59 *
60 * @VERSION: filesystem version
61 *
62 * @MOUNT: cluster mount name (?) -- ocfs only
63 *
64 * @SBMAGIC: super block magic string
65 *
66 * @SBMAGIC_OFFSET: offset of SBMAGIC
67 *
68 * @FSSIZE: size of filessystem [not-implemented yet]
69 *
70 * @SYSTEM_ID: ISO9660 system identifier
71 *
72 * @PUBLISHER_ID: ISO9660 publisher identifier
73 *
74 * @APPLICATION_ID: ISO9660 application identifier
75 *
76 * @BOOT_SYSTEM_ID: ISO9660 boot system identifier
77 */
78
79static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn);
80static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn);
81
82static int blkid_probe_set_usage(blkid_probe pr, int usage);
83
84
85/*
86 * Superblocks chains probing functions
87 */
88static const struct blkid_idinfo *idinfos[] =
89{
90 /* RAIDs */
91 &linuxraid_idinfo,
92 &ddfraid_idinfo,
93 &iswraid_idinfo,
94 &lsiraid_idinfo,
95 &viaraid_idinfo,
96 &silraid_idinfo,
97 &nvraid_idinfo,
98 &pdcraid_idinfo,
99 &highpoint45x_idinfo,
100 &highpoint37x_idinfo,
101 &adraid_idinfo,
102 &jmraid_idinfo,
103
bigbiff7b4c7a62015-01-01 19:44:14 -0500104 &bcache_idinfo,
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500105 &drbd_idinfo,
106 &drbdproxy_datalog_idinfo,
107 &lvm2_idinfo,
108 &lvm1_idinfo,
109 &snapcow_idinfo,
110 &verity_hash_idinfo,
111 &luks_idinfo,
112 &vmfs_volume_idinfo,
113
114 /* Filesystems */
115 &vfat_idinfo,
116 &swsuspend_idinfo,
117 &swap_idinfo,
118 &xfs_idinfo,
bigbiff7b4c7a62015-01-01 19:44:14 -0500119 &xfs_log_idinfo,
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500120 &ext4dev_idinfo,
121 &ext4_idinfo,
122 &ext3_idinfo,
123 &ext2_idinfo,
124 &jbd_idinfo,
125 &reiser_idinfo,
126 &reiser4_idinfo,
127 &jfs_idinfo,
128 &udf_idinfo,
129 &iso9660_idinfo,
130 &zfs_idinfo,
131 &hfsplus_idinfo,
132 &hfs_idinfo,
133 &ufs_idinfo,
134 &hpfs_idinfo,
135 &sysv_idinfo,
136 &xenix_idinfo,
137 &ntfs_idinfo,
bigbiff7b4c7a62015-01-01 19:44:14 -0500138 &refs_idinfo,
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500139 &cramfs_idinfo,
140 &romfs_idinfo,
141 &minix_idinfo,
142 &gfs_idinfo,
143 &gfs2_idinfo,
144 &ocfs_idinfo,
145 &ocfs2_idinfo,
146 &oracleasm_idinfo,
147 &vxfs_idinfo,
148 &squashfs_idinfo,
bigbiff7b4c7a62015-01-01 19:44:14 -0500149 &squashfs3_idinfo,
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500150 &netware_idinfo,
151 &btrfs_idinfo,
152 &ubifs_idinfo,
153 &bfs_idinfo,
154 &vmfs_fs_idinfo,
155 &befs_idinfo,
156 &nilfs2_idinfo,
157 &exfat_idinfo,
Gao Xiang48028c32021-11-22 22:46:43 +0800158 &f2fs_idinfo,
159 &erofs_idinfo
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500160};
161
162/*
163 * Driver definition
164 */
165const struct blkid_chaindrv superblocks_drv = {
166 .id = BLKID_CHAIN_SUBLKS,
167 .name = "superblocks",
168 .dflt_enabled = TRUE,
169 .dflt_flags = BLKID_SUBLKS_DEFAULT,
170 .idinfos = idinfos,
171 .nidinfos = ARRAY_SIZE(idinfos),
172 .has_fltr = TRUE,
173 .probe = superblocks_probe,
174 .safeprobe = superblocks_safeprobe,
175};
176
177/**
178 * blkid_probe_enable_superblocks:
179 * @pr: probe
180 * @enable: TRUE/FALSE
181 *
182 * Enables/disables the superblocks probing for non-binary interface.
183 *
184 * Returns: 0 on success, or -1 in case of error.
185 */
186int blkid_probe_enable_superblocks(blkid_probe pr, int enable)
187{
188 if (!pr)
189 return -1;
190 pr->chains[BLKID_CHAIN_SUBLKS].enabled = enable;
191 return 0;
192}
193
194/**
195 * blkid_probe_set_superblocks_flags:
196 * @pr: prober
197 * @flags: BLKID_SUBLKS_* flags
198 *
199 * Sets probing flags to the superblocks prober. This function is optional, the
200 * default are BLKID_SUBLKS_DEFAULTS flags.
201 *
202 * Returns: 0 on success, or -1 in case of error.
203 */
204int blkid_probe_set_superblocks_flags(blkid_probe pr, int flags)
205{
206 if (!pr)
207 return -1;
208
209 pr->chains[BLKID_CHAIN_SUBLKS].flags = flags;
210 return 0;
211}
212
213/**
214 * blkid_probe_reset_superblocks_filter:
215 * @pr: prober
216 *
217 * Resets superblocks probing filter
218 *
219 * Returns: 0 on success, or -1 in case of error.
220 */
221int blkid_probe_reset_superblocks_filter(blkid_probe pr)
222{
223 return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
224}
225
226/**
227 * blkid_probe_invert_superblocks_filter:
228 * @pr: prober
229 *
230 * Inverts superblocks probing filter
231 *
232 * Returns: 0 on success, or -1 in case of error.
233 */
234int blkid_probe_invert_superblocks_filter(blkid_probe pr)
235{
236 return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
237}
238
239/**
240 * blkid_probe_filter_superblocks_type:
241 * @pr: prober
242 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
243 * @names: NULL terminated array of probing function names (e.g. "vfat").
244 *
245 * %BLKID_FLTR_NOTIN - probe for all items which are NOT IN @names;
246 *
247 * %BLKID_FLTR_ONLYIN - probe for items which are IN @names
248 *
249 * Returns: 0 on success, or -1 in case of error.
250 */
251int blkid_probe_filter_superblocks_type(blkid_probe pr, int flag, char *names[])
252{
253 return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
254}
255
256/**
257 * blkid_probe_filter_superblocks_usage:
258 * @pr: prober
259 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
260 * @usage: BLKID_USAGE_* flags
261 *
262 * %BLKID_FLTR_NOTIN - probe for all items which are NOT IN @usage;
263 *
264 * %BLKID_FLTR_ONLYIN - probe for items which are IN @usage
265 *
266 * Returns: 0 on success, or -1 in case of error.
267 */
268int blkid_probe_filter_superblocks_usage(blkid_probe pr, int flag, int usage)
269{
270 unsigned long *fltr;
271 struct blkid_chain *chn;
272 size_t i;
273
274 fltr = blkid_probe_get_filter(pr, BLKID_CHAIN_SUBLKS, TRUE);
275 if (!fltr)
276 return -1;
277
278 chn = &pr->chains[BLKID_CHAIN_SUBLKS];
279
280 for (i = 0; i < chn->driver->nidinfos; i++) {
281 const struct blkid_idinfo *id = chn->driver->idinfos[i];
282
283 if (id->usage & usage) {
284 if (flag & BLKID_FLTR_NOTIN)
285 blkid_bmp_set_item(chn->fltr, i);
286 } else if (flag & BLKID_FLTR_ONLYIN)
287 blkid_bmp_set_item(chn->fltr, i);
288 }
bigbiff7b4c7a62015-01-01 19:44:14 -0500289 DBG(LOWPROBE, ul_debug("a new probing usage-filter initialized"));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500290 return 0;
291}
292
293/**
294 * blkid_known_fstype:
295 * @fstype: filesystem name
296 *
297 * Returns: 1 for known filesytems, or 0 for unknown filesystem.
298 */
299int blkid_known_fstype(const char *fstype)
300{
301 size_t i;
302
303 if (!fstype)
304 return 0;
305
306 for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
307 const struct blkid_idinfo *id = idinfos[i];
308 if (strcmp(id->name, fstype) == 0)
309 return 1;
310 }
311 return 0;
312}
313
314/**
315 * blkid_superblocks_get_name:
316 * @idx: number >= 0
317 * @name: returns name of supported filesystem/raid (optional)
318 * @usage: returns BLKID_USAGE_* flags, (optional)
319 *
320 * Returns: -1 if @idx is out of range, or 0 on success.
321 */
322int blkid_superblocks_get_name(size_t idx, const char **name, int *usage)
323{
324 if (idx < ARRAY_SIZE(idinfos)) {
325 if (name)
326 *name = idinfos[idx]->name;
327 if (usage)
328 *usage = idinfos[idx]->usage;
329 return 0;
330 }
331 return -1;
332}
333
334/*
335 * The blkid_do_probe() backend.
336 */
337static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
338{
339 size_t i;
bigbiff7b4c7a62015-01-01 19:44:14 -0500340 int rc = BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500341
342 if (!pr || chn->idx < -1)
bigbiff7b4c7a62015-01-01 19:44:14 -0500343 return -EINVAL;
344
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500345 blkid_probe_chain_reset_vals(pr, chn);
346
bigbiff7b4c7a62015-01-01 19:44:14 -0500347 if (pr->flags & BLKID_FL_NOSCAN_DEV)
348 return BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500349
350 if (pr->size <= 0 || (pr->size <= 1024 && !S_ISCHR(pr->mode)))
351 /* Ignore very very small block devices or regular files (e.g.
352 * extended partitions). Note that size of the UBI char devices
353 * is 1 byte */
bigbiff7b4c7a62015-01-01 19:44:14 -0500354 return BLKID_PROBE_NONE;
355
356 DBG(LOWPROBE, ul_debug("--> starting probing loop [SUBLKS idx=%d]",
357 chn->idx));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500358
359 i = chn->idx < 0 ? 0 : chn->idx + 1U;
360
361 for ( ; i < ARRAY_SIZE(idinfos); i++) {
362 const struct blkid_idinfo *id;
363 const struct blkid_idmag *mag = NULL;
364 blkid_loff_t off = 0;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500365
366 chn->idx = i;
367 id = idinfos[i];
368
369 if (chn->fltr && blkid_bmp_get_item(chn->fltr, i)) {
bigbiff7b4c7a62015-01-01 19:44:14 -0500370 DBG(LOWPROBE, ul_debug("filter out: %s", id->name));
371 rc = BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500372 continue;
373 }
374
bigbiff7b4c7a62015-01-01 19:44:14 -0500375 if (id->minsz && id->minsz > pr->size) {
376 rc = BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500377 continue; /* the device is too small */
bigbiff7b4c7a62015-01-01 19:44:14 -0500378 }
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500379
380 /* don't probe for RAIDs, swap or journal on CD/DVDs */
381 if ((id->usage & (BLKID_USAGE_RAID | BLKID_USAGE_OTHER)) &&
bigbiff7b4c7a62015-01-01 19:44:14 -0500382 blkid_probe_is_cdrom(pr)) {
383 rc = BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500384 continue;
bigbiff7b4c7a62015-01-01 19:44:14 -0500385 }
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500386
387 /* don't probe for RAIDs on floppies */
bigbiff7b4c7a62015-01-01 19:44:14 -0500388 if ((id->usage & BLKID_USAGE_RAID) && blkid_probe_is_tiny(pr)) {
389 rc = BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500390 continue;
bigbiff7b4c7a62015-01-01 19:44:14 -0500391 }
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500392
bigbiff7b4c7a62015-01-01 19:44:14 -0500393 DBG(LOWPROBE, ul_debug("[%zd] %s:", i, id->name));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500394
bigbiff7b4c7a62015-01-01 19:44:14 -0500395 rc = blkid_probe_get_idmag(pr, id, &off, &mag);
396 if (rc < 0)
397 break;
398 if (rc != BLKID_PROBE_OK)
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500399 continue;
400
401 /* final check by probing function */
402 if (id->probefunc) {
bigbiff7b4c7a62015-01-01 19:44:14 -0500403 DBG(LOWPROBE, ul_debug("\tcall probefunc()"));
404 rc = id->probefunc(pr, mag);
405 if (rc != BLKID_PROBE_OK) {
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500406 blkid_probe_chain_reset_vals(pr, chn);
bigbiff7b4c7a62015-01-01 19:44:14 -0500407 if (rc < 0)
408 break;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500409 continue;
410 }
411 }
412
413 /* all cheks passed */
414 if (chn->flags & BLKID_SUBLKS_TYPE)
415 rc = blkid_probe_set_value(pr, "TYPE",
416 (unsigned char *) id->name,
417 strlen(id->name) + 1);
418
419 if (!rc)
420 rc = blkid_probe_set_usage(pr, id->usage);
421
422 if (!rc && mag)
423 rc = blkid_probe_set_magic(pr, off, mag->len,
424 (unsigned char *) mag->magic);
425 if (rc) {
426 blkid_probe_chain_reset_vals(pr, chn);
bigbiff7b4c7a62015-01-01 19:44:14 -0500427 DBG(LOWPROBE, ul_debug("failed to set result -- ignore"));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500428 continue;
429 }
430
bigbiff7b4c7a62015-01-01 19:44:14 -0500431 DBG(LOWPROBE, ul_debug("<-- leaving probing loop (type=%s) [SUBLKS idx=%d]",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500432 id->name, chn->idx));
bigbiff7b4c7a62015-01-01 19:44:14 -0500433 return BLKID_PROBE_OK;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500434 }
435
bigbiff7b4c7a62015-01-01 19:44:14 -0500436 DBG(LOWPROBE, ul_debug("<-- leaving probing loop (failed=%d) [SUBLKS idx=%d]",
437 rc, chn->idx));
438 return rc;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500439}
440
441/*
442 * This is the same function as blkid_do_probe(), but returns only one result
443 * (cannot be used in while()) and checks for ambivalen results (more
444 * filesystems on the device) -- in such case returns -2.
445 *
446 * The function does not check for filesystems when a RAID or crypto signature
447 * is detected. The function also does not check for collision between RAIDs
448 * and crypto devices. The first detected RAID or crypto device is returned.
449 *
450 * The function does not probe for ambivalent results on very small devices
451 * (e.g. floppies), on small devices the first detected filesystem is returned.
452 */
453static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn)
454{
455 struct blkid_prval vals[BLKID_NVALS_SUBLKS];
456 int nvals = BLKID_NVALS_SUBLKS;
457 int idx = -1;
458 int count = 0;
459 int intol = 0;
460 int rc;
461
bigbiff7b4c7a62015-01-01 19:44:14 -0500462 if (pr->flags & BLKID_FL_NOSCAN_DEV)
463 return BLKID_PROBE_NONE;
464
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500465 while ((rc = superblocks_probe(pr, chn)) == 0) {
466
467 if (blkid_probe_is_tiny(pr) && !count)
bigbiff7b4c7a62015-01-01 19:44:14 -0500468 return BLKID_PROBE_OK; /* floppy or so -- returns the first result. */
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500469
470 count++;
471
472 if (chn->idx >= 0 &&
473 idinfos[chn->idx]->usage & (BLKID_USAGE_RAID | BLKID_USAGE_CRYPTO))
474 break;
475
476 if (chn->idx >= 0 &&
477 !(idinfos[chn->idx]->flags & BLKID_IDINFO_TOLERANT))
478 intol++;
479
480 if (count == 1) {
481 /* save the first result */
482 nvals = blkid_probe_chain_copy_vals(pr, chn, vals, nvals);
483 idx = chn->idx;
484 }
485 }
486
487 if (rc < 0)
488 return rc; /* error */
489
490 if (count > 1 && intol) {
bigbiff7b4c7a62015-01-01 19:44:14 -0500491 DBG(LOWPROBE, ul_debug("ERROR: superblocks chain: "
492 "ambivalent result detected (%d filesystems)!",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500493 count));
494 return -2; /* error, ambivalent result (more FS) */
495 }
496 if (!count)
bigbiff7b4c7a62015-01-01 19:44:14 -0500497 return BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500498
499 if (idx != -1) {
500 /* restore the first result */
501 blkid_probe_chain_reset_vals(pr, chn);
502 blkid_probe_append_vals(pr, vals, nvals);
503 chn->idx = idx;
504 }
505
506 /*
507 * The RAID device could be partitioned. The problem are RAID1 devices
508 * where the partition table is visible from underlaying devices. We
509 * have to ignore such partition tables.
510 */
511 if (chn->idx >= 0 && idinfos[chn->idx]->usage & BLKID_USAGE_RAID)
512 pr->prob_flags |= BLKID_PROBE_FL_IGNORE_PT;
513
bigbiff7b4c7a62015-01-01 19:44:14 -0500514 return BLKID_PROBE_OK;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500515}
516
517int blkid_probe_set_version(blkid_probe pr, const char *version)
518{
519 struct blkid_chain *chn = blkid_probe_get_chain(pr);
520
521 if (chn->flags & BLKID_SUBLKS_VERSION)
522 return blkid_probe_set_value(pr, "VERSION",
523 (unsigned char *) version, strlen(version) + 1);
524 return 0;
525}
526
527
528int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
529{
530 struct blkid_chain *chn = blkid_probe_get_chain(pr);
531 int rc = 0;
532
533 if (chn->flags & BLKID_SUBLKS_VERSION) {
534 va_list ap;
535
536 va_start(ap, fmt);
537 rc = blkid_probe_vsprintf_value(pr, "VERSION", fmt, ap);
538 va_end(ap);
539 }
540 return rc;
541}
542
543static int blkid_probe_set_usage(blkid_probe pr, int usage)
544{
545 struct blkid_chain *chn = blkid_probe_get_chain(pr);
546 char *u = NULL;
547
548 if (!(chn->flags & BLKID_SUBLKS_USAGE))
549 return 0;
550
551 if (usage & BLKID_USAGE_FILESYSTEM)
552 u = "filesystem";
553 else if (usage & BLKID_USAGE_RAID)
554 u = "raid";
555 else if (usage & BLKID_USAGE_CRYPTO)
556 u = "crypto";
557 else if (usage & BLKID_USAGE_OTHER)
558 u = "other";
559 else
560 u = "unknown";
561
562 return blkid_probe_set_value(pr, "USAGE", (unsigned char *) u, strlen(u) + 1);
563}
564
565int blkid_probe_set_id_label(blkid_probe pr, const char *name,
566 unsigned char *data, size_t len)
567{
568 struct blkid_chain *chn = blkid_probe_get_chain(pr);
569 struct blkid_prval *v;
570
571 if (!(chn->flags & BLKID_SUBLKS_LABEL))
572 return 0;
573
574 v = blkid_probe_assign_value(pr, name);
575 if (!v)
576 return -1;
577
578 if (len >= BLKID_PROBVAL_BUFSIZ)
579 len = BLKID_PROBVAL_BUFSIZ - 1; /* make a space for \0 */
580
581 memcpy(v->data, data, len);
582 v->data[len] = '\0';
583
584 /* remove white spaces */
585 v->len = blkid_rtrim_whitespace(v->data) + 1;
586 if (v->len > 1)
587 v->len = blkid_ltrim_whitespace(v->data) + 1;
588
589 if (v->len <= 1)
590 blkid_probe_reset_last_value(pr); /* ignore empty */
591 return 0;
592}
593
594int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len)
595{
596 struct blkid_chain *chn = blkid_probe_get_chain(pr);
597 struct blkid_prval *v;
598 if (len > BLKID_PROBVAL_BUFSIZ)
599 len = BLKID_PROBVAL_BUFSIZ;
600
601 if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
602 blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0)
603 return -1;
604 if (!(chn->flags & BLKID_SUBLKS_LABEL))
605 return 0;
606 v = blkid_probe_assign_value(pr, "LABEL");
607 if (!v)
608 return -1;
609
610 if (len == BLKID_PROBVAL_BUFSIZ)
611 len--; /* make a space for \0 */
612
613 memcpy(v->data, label, len);
614 v->data[len] = '\0';
615
616 v->len = blkid_rtrim_whitespace(v->data) + 1;
617 if (v->len == 1)
618 blkid_probe_reset_last_value(pr);
619 return 0;
620}
621
622int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label,
623 size_t len, int enc)
624{
625 struct blkid_chain *chn = blkid_probe_get_chain(pr);
626 struct blkid_prval *v;
627
628 if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
629 blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0)
630 return -1;
631 if (!(chn->flags & BLKID_SUBLKS_LABEL))
632 return 0;
633 v = blkid_probe_assign_value(pr, "LABEL");
634 if (!v)
635 return -1;
636
637 blkid_encode_to_utf8(enc, v->data, sizeof(v->data), label, len);
638 v->len = blkid_rtrim_whitespace(v->data) + 1;
639 if (v->len == 1)
640 blkid_probe_reset_last_value(pr);
641 return 0;
642}
643
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500644int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid,
645 size_t len, const char *fmt, ...)
646{
647 struct blkid_chain *chn = blkid_probe_get_chain(pr);
648 int rc = -1;
649 va_list ap;
650
651 if (len > BLKID_PROBVAL_BUFSIZ)
652 len = BLKID_PROBVAL_BUFSIZ;
653
bigbiff7b4c7a62015-01-01 19:44:14 -0500654 if (blkid_uuid_is_empty(uuid, len))
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500655 return 0;
656
657 if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
658 blkid_probe_set_value(pr, "UUID_RAW", uuid, len) < 0)
659 return -1;
660 if (!(chn->flags & BLKID_SUBLKS_UUID))
661 return 0;
662
663 va_start(ap, fmt);
664 rc = blkid_probe_vsprintf_value(pr, "UUID", fmt, ap);
665 va_end(ap);
666
667 /* convert to lower case (..be paranoid) */
668 if (!rc) {
669 size_t i;
670 struct blkid_prval *v = __blkid_probe_get_value(pr,
671 blkid_probe_numof_values(pr));
672 if (v) {
673 for (i = 0; i < v->len; i++)
674 if (v->data[i] >= 'A' && v->data[i] <= 'F')
675 v->data[i] = (v->data[i] - 'A') + 'a';
676 }
677 }
678 return rc;
679}
680
681/* function to set UUIDs that are in suberblocks stored as strings */
682int blkid_probe_strncpy_uuid(blkid_probe pr, unsigned char *str, size_t len)
683{
684 struct blkid_chain *chn = blkid_probe_get_chain(pr);
685 struct blkid_prval *v;
686
687 if (str == NULL || *str == '\0')
688 return -1;
689 if (!len)
690 len = strlen((char *) str);
691 if (len > BLKID_PROBVAL_BUFSIZ)
692 len = BLKID_PROBVAL_BUFSIZ;
693
694 if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
695 blkid_probe_set_value(pr, "UUID_RAW", str, len) < 0)
696 return -1;
697 if (!(chn->flags & BLKID_SUBLKS_UUID))
698 return 0;
699
700 v = blkid_probe_assign_value(pr, "UUID");
701 if (v) {
702 if (len == BLKID_PROBVAL_BUFSIZ)
703 len--; /* make a space for \0 */
704
705 memcpy((char *) v->data, str, len);
706 v->data[len] = '\0';
707 v->len = len + 1;
708 return 0;
709 }
710 return -1;
711}
712
713/* default _set_uuid function to set DCE UUIDs */
714int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *name)
715{
716 struct blkid_chain *chn = blkid_probe_get_chain(pr);
717 struct blkid_prval *v;
718
bigbiff7b4c7a62015-01-01 19:44:14 -0500719 if (blkid_uuid_is_empty(uuid, 16))
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500720 return 0;
721
722 if (!name) {
723 if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
724 blkid_probe_set_value(pr, "UUID_RAW", uuid, 16) < 0)
725 return -1;
726 if (!(chn->flags & BLKID_SUBLKS_UUID))
727 return 0;
728
729 v = blkid_probe_assign_value(pr, "UUID");
730 } else
731 v = blkid_probe_assign_value(pr, name);
732
733 blkid_unparse_uuid(uuid, (char *) v->data, sizeof(v->data));
734 v->len = 37;
735
736 return 0;
737}
738
739int blkid_probe_set_uuid(blkid_probe pr, unsigned char *uuid)
740{
741 return blkid_probe_set_uuid_as(pr, uuid, NULL);
742}
743
744/**
745 * blkid_probe_set_request:
746 * @pr: probe
747 * @flags: BLKID_PROBREQ_* (deprecated) or BLKID_SUBLKS_* flags
748 *
749 * Returns: 0 on success, or -1 in case of error.
750 *
751 * Deprecated: Use blkid_probe_set_superblocks_flags().
752 */
753int blkid_probe_set_request(blkid_probe pr, int flags)
754{
755 return blkid_probe_set_superblocks_flags(pr, flags);
756}
757
758/**
759 * blkid_probe_reset_filter:
760 * @pr: prober
761 *
762 * Returns: 0 on success, or -1 in case of error.
763 *
764 * Deprecated: Use blkid_probe_reset_superblocks_filter().
765 */
766int blkid_probe_reset_filter(blkid_probe pr)
767{
768 return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
769}
770
771/**
772 * blkid_probe_invert_filter:
773 * @pr: prober
774 *
775 * Returns: 0 on success, or -1 in case of error.
776 *
777 * Deprecated: Use blkid_probe_invert_superblocks_filter().
778 */
779int blkid_probe_invert_filter(blkid_probe pr)
780{
781 return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
782}
783
784/**
785 * blkid_probe_filter_types
786 * @pr: prober
787 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
788 * @names: NULL terminated array of probing function names (e.g. "vfat").
789 *
790 * Returns: 0 on success, or -1 in case of error.
791 *
792 * Deprecated: Use blkid_probe_filter_superblocks_types().
793 */
794int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[])
795{
796 return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
797}
798
799/**
800 * blkid_probe_filter_usage
801 * @pr: prober
802 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
803 * @usage: BLKID_USAGE_* flags
804 *
805 * Returns: 0 on success, or -1 in case of error.
806 *
807 * Deprecated: Use blkid_probe_filter_superblocks_usage().
808 */
809int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage)
810{
811 return blkid_probe_filter_superblocks_usage(pr, flag, usage);
812}
813
814