]> git.ipfire.org Git - thirdparty/util-linux.git/blame_incremental - libblkid/src/superblocks/superblocks.c
taskset: Accept 0 pid for current process
[thirdparty/util-linux.git] / libblkid / src / superblocks / superblocks.c
... / ...
CommitLineData
1/*
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 <inttypes.h>
11#include <stdio.h>
12#include <string.h>
13#include <stdlib.h>
14#include <unistd.h>
15#include <fcntl.h>
16#include <ctype.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <errno.h>
20#include <stdint.h>
21#include <stdarg.h>
22
23#include "superblocks.h"
24
25/**
26 * SECTION:superblocks
27 * @title: Superblocks probing
28 * @short_description: filesystems and raids superblocks probing.
29 *
30 * The library API has been originally designed for superblocks probing only.
31 * This is reason why some *deprecated* superblock specific functions don't use
32 * '_superblocks_' namespace in the function name. Please, don't use these
33 * functions in new code.
34 *
35 * The 'superblocks' probers support NAME=value (tags) interface only. The
36 * superblocks probing is enabled by default (and controlled by
37 * blkid_probe_enable_superblocks()).
38 *
39 * Currently supported tags:
40 *
41 * @TYPE: filesystem type
42 *
43 * @SEC_TYPE: secondary filesystem type
44 *
45 * @LABEL: filesystem label
46 *
47 * @LABEL_RAW: raw label from FS superblock
48 *
49 * @UUID: filesystem UUID (lower case)
50 *
51 * @UUID_SUB: subvolume uuid (e.g. btrfs)
52 *
53 * @LOGUUID: external log UUID (e.g. xfs)
54 *
55 * @UUID_RAW: raw UUID from FS superblock
56 *
57 * @EXT_JOURNAL: external journal UUID
58 *
59 * @USAGE: usage string: "raid", "filesystem", ...
60 *
61 * @VERSION: filesystem version
62 *
63 * @MOUNT: cluster mount name (?) -- ocfs only
64 *
65 * @SBMAGIC: super block magic string
66 *
67 * @SBMAGIC_OFFSET: offset of SBMAGIC
68 *
69 * @FSSIZE: size of filesystem (implemented for XFS/BTRFS/Ext only)
70 *
71 * @FSLASTBLOCK: last fsblock/total number of fsblocks
72 *
73 * @FSBLOCKSIZE: file system block size
74 *
75 * @SYSTEM_ID: ISO9660 system identifier
76 *
77 * @PUBLISHER_ID: ISO9660 publisher identifier
78 *
79 * @APPLICATION_ID: ISO9660 application identifier
80 *
81 * @BOOT_SYSTEM_ID: ISO9660 boot system identifier
82 *
83 * @BLOCK_SIZE: minimal block size accessible by file system
84 */
85
86static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn);
87static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn);
88
89static int blkid_probe_set_usage(blkid_probe pr, int usage);
90
91
92/*
93 * Superblocks chains probing functions
94 */
95static const struct blkid_idinfo *idinfos[] =
96{
97 /* First, as access to locked OPAL region triggers IO errors */
98 &luks_opal_idinfo,
99
100 /* RAIDs */
101 &linuxraid_idinfo,
102 &ddfraid_idinfo,
103 &iswraid_idinfo,
104 &lsiraid_idinfo,
105 &viaraid_idinfo,
106 &silraid_idinfo,
107 &nvraid_idinfo,
108 &pdcraid_idinfo,
109 &highpoint45x_idinfo,
110 &highpoint37x_idinfo,
111 &adraid_idinfo,
112 &jmraid_idinfo,
113
114 &bcache_idinfo,
115 &bcachefs_idinfo,
116 &bluestore_idinfo,
117 &drbd_idinfo,
118 &drbdmanage_idinfo,
119 &drbdproxy_datalog_idinfo,
120 &lvm2_idinfo,
121 &lvm1_idinfo,
122 &snapcow_idinfo,
123 &verity_hash_idinfo,
124 &integrity_idinfo,
125 &luks_idinfo,
126 &vmfs_volume_idinfo,
127 &ubi_idinfo,
128 &vdo_idinfo,
129 &stratis_idinfo,
130 &bitlocker_idinfo,
131 &cs_fvault2_idinfo,
132
133 /* Filesystems */
134 &vfat_idinfo,
135 &swsuspend_idinfo,
136 &swap_idinfo,
137 &xfs_idinfo,
138 &xfs_log_idinfo,
139 &exfs_idinfo,
140 &ext4dev_idinfo,
141 &ext4_idinfo,
142 &ext3_idinfo,
143 &ext2_idinfo,
144 &jbd_idinfo,
145 &reiser_idinfo,
146 &reiser4_idinfo,
147 &jfs_idinfo,
148 &udf_idinfo,
149 &iso9660_idinfo,
150 &zfs_idinfo,
151 &hfsplus_idinfo,
152 &hfs_idinfo,
153 &ufs_idinfo,
154 &hpfs_idinfo,
155 &sysv_idinfo,
156 &xenix_idinfo,
157 &ntfs_idinfo,
158 &refs_idinfo,
159 &cramfs_idinfo,
160 &romfs_idinfo,
161 &scoutfs_meta_idinfo,
162 &scoutfs_data_idinfo,
163 &minix_idinfo,
164 &gfs_idinfo,
165 &gfs2_idinfo,
166 &ocfs_idinfo,
167 &ocfs2_idinfo,
168 &oracleasm_idinfo,
169 &vxfs_idinfo,
170 &squashfs_idinfo,
171 &squashfs3_idinfo,
172 &netware_idinfo,
173 &btrfs_idinfo,
174 &ubifs_idinfo,
175 &bfs_idinfo,
176 &vmfs_fs_idinfo,
177 &befs_idinfo,
178 &nilfs2_idinfo,
179 &exfat_idinfo,
180 &f2fs_idinfo,
181 &mpool_idinfo,
182 &apfs_idinfo,
183 &zonefs_idinfo,
184 &erofs_idinfo,
185};
186
187/*
188 * Driver definition
189 */
190const struct blkid_chaindrv superblocks_drv = {
191 .id = BLKID_CHAIN_SUBLKS,
192 .name = "superblocks",
193 .dflt_enabled = TRUE,
194 .dflt_flags = BLKID_SUBLKS_DEFAULT,
195 .idinfos = idinfos,
196 .nidinfos = ARRAY_SIZE(idinfos),
197 .has_fltr = TRUE,
198 .probe = superblocks_probe,
199 .safeprobe = superblocks_safeprobe,
200};
201
202/**
203 * blkid_probe_enable_superblocks:
204 * @pr: probe
205 * @enable: TRUE/FALSE
206 *
207 * Enables/disables the superblocks probing for non-binary interface.
208 *
209 * Returns: 0 on success, or -1 in case of error.
210 */
211int blkid_probe_enable_superblocks(blkid_probe pr, int enable)
212{
213 pr->chains[BLKID_CHAIN_SUBLKS].enabled = enable;
214 return 0;
215}
216
217/**
218 * blkid_probe_set_superblocks_flags:
219 * @pr: prober
220 * @flags: BLKID_SUBLKS_* flags
221 *
222 * Sets probing flags to the superblocks prober. This function is optional, the
223 * default are BLKID_SUBLKS_DEFAULTS flags.
224 *
225 * Returns: 0 on success, or -1 in case of error.
226 */
227int blkid_probe_set_superblocks_flags(blkid_probe pr, int flags)
228{
229 pr->chains[BLKID_CHAIN_SUBLKS].flags = flags;
230 return 0;
231}
232
233/**
234 * blkid_probe_reset_superblocks_filter:
235 * @pr: prober
236 *
237 * Resets superblocks probing filter
238 *
239 * Returns: 0 on success, or -1 in case of error.
240 */
241int blkid_probe_reset_superblocks_filter(blkid_probe pr)
242{
243 return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
244}
245
246/**
247 * blkid_probe_invert_superblocks_filter:
248 * @pr: prober
249 *
250 * Inverts superblocks probing filter
251 *
252 * Returns: 0 on success, or -1 in case of error.
253 */
254int blkid_probe_invert_superblocks_filter(blkid_probe pr)
255{
256 return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
257}
258
259/**
260 * blkid_probe_filter_superblocks_type:
261 * @pr: prober
262 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
263 * @names: NULL terminated array of probing function names (e.g. "vfat").
264 *
265 * %BLKID_FLTR_NOTIN - probe for all items which are NOT IN @names;
266 *
267 * %BLKID_FLTR_ONLYIN - probe for items which are IN @names
268 *
269 * Returns: 0 on success, or -1 in case of error.
270 */
271int blkid_probe_filter_superblocks_type(blkid_probe pr, int flag, char *names[])
272{
273 return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
274}
275
276/**
277 * blkid_probe_filter_superblocks_usage:
278 * @pr: prober
279 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
280 * @usage: BLKID_USAGE_* flags
281 *
282 * %BLKID_FLTR_NOTIN - probe for all items which are NOT IN @usage;
283 *
284 * %BLKID_FLTR_ONLYIN - probe for items which are IN @usage
285 *
286 * Returns: 0 on success, or -1 in case of error.
287 */
288int blkid_probe_filter_superblocks_usage(blkid_probe pr, int flag, int usage)
289{
290 unsigned long *fltr;
291 struct blkid_chain *chn;
292 size_t i;
293
294 fltr = blkid_probe_get_filter(pr, BLKID_CHAIN_SUBLKS, TRUE);
295 if (!fltr)
296 return -1;
297
298 chn = &pr->chains[BLKID_CHAIN_SUBLKS];
299
300 for (i = 0; i < chn->driver->nidinfos; i++) {
301 const struct blkid_idinfo *id = chn->driver->idinfos[i];
302
303 if (id->usage & usage) {
304 if (flag & BLKID_FLTR_NOTIN)
305 blkid_bmp_set_item(chn->fltr, i);
306 } else if (flag & BLKID_FLTR_ONLYIN)
307 blkid_bmp_set_item(chn->fltr, i);
308 }
309 DBG(LOWPROBE, ul_debug("a new probing usage-filter initialized"));
310 return 0;
311}
312
313/**
314 * blkid_known_fstype:
315 * @fstype: filesystem name
316 *
317 * Returns: 1 for known filesystems, or 0 for unknown filesystem.
318 */
319int blkid_known_fstype(const char *fstype)
320{
321 size_t i;
322
323 for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
324 const struct blkid_idinfo *id = idinfos[i];
325 if (strcmp(id->name, fstype) == 0)
326 return 1;
327 }
328 return 0;
329}
330
331/**
332 * blkid_superblocks_get_name:
333 * @idx: number >= 0
334 * @name: returns name of supported filesystem/raid (optional)
335 * @usage: returns BLKID_USAGE_* flags, (optional)
336 *
337 * Returns: -1 if @idx is out of range, or 0 on success.
338 */
339int blkid_superblocks_get_name(size_t idx, const char **name, int *usage)
340{
341 if (idx < ARRAY_SIZE(idinfos)) {
342 if (name)
343 *name = idinfos[idx]->name;
344 if (usage)
345 *usage = idinfos[idx]->usage;
346 return 0;
347 }
348 return -1;
349}
350
351/*
352 * The blkid_do_probe() backend.
353 */
354static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
355{
356 size_t i;
357 int rc = BLKID_PROBE_NONE;
358
359 if (chn->idx < -1)
360 return -EINVAL;
361
362 blkid_probe_chain_reset_values(pr, chn);
363
364 if (pr->flags & BLKID_FL_NOSCAN_DEV) {
365 DBG(LOWPROBE, ul_debug("*** ignore (noscan flag)"));
366 return BLKID_PROBE_NONE;
367 }
368
369 if (pr->size <= 0 || (pr->size <= 1024 && !S_ISCHR(pr->mode))) {
370 /* Ignore very very small block devices or regular files (e.g.
371 * extended partitions). Note that size of the UBI char devices
372 * is 1 byte */
373 DBG(LOWPROBE, ul_debug("*** ignore (size <= 1024)"));
374 return BLKID_PROBE_NONE;
375 }
376
377 DBG(LOWPROBE, ul_debug("--> starting probing loop [SUBLKS idx=%d]",
378 chn->idx));
379
380 i = chn->idx < 0 ? 0 : chn->idx + 1U;
381
382 for ( ; i < ARRAY_SIZE(idinfos); i++) {
383 const struct blkid_idinfo *id;
384 const struct blkid_idmag *mag = NULL;
385 uint64_t off = 0;
386
387 chn->idx = i;
388 id = idinfos[i];
389
390 if (chn->fltr && blkid_bmp_get_item(chn->fltr, i)) {
391 DBG(LOWPROBE, ul_debug("filter out: %s", id->name));
392 rc = BLKID_PROBE_NONE;
393 continue;
394 }
395
396 if (id->minsz && (unsigned)id->minsz > pr->size) {
397 rc = BLKID_PROBE_NONE;
398 continue; /* the device is too small */
399 }
400
401 /* don't probe for RAIDs, swap or journal on CD/DVDs */
402 if ((id->usage & (BLKID_USAGE_RAID | BLKID_USAGE_OTHER)) &&
403 blkid_probe_is_cdrom(pr)) {
404 rc = BLKID_PROBE_NONE;
405 continue;
406 }
407
408 /* don't probe for RAIDs on floppies */
409 if ((id->usage & BLKID_USAGE_RAID) && blkid_probe_is_tiny(pr)) {
410 rc = BLKID_PROBE_NONE;
411 continue;
412 }
413
414 DBG(LOWPROBE, ul_debug("[%zd] %s:", i, id->name));
415
416 rc = blkid_probe_get_idmag(pr, id, &off, &mag);
417 if (rc < 0)
418 break;
419 if (rc != BLKID_PROBE_OK)
420 continue;
421
422 /* final check by probing function */
423 if (id->probefunc) {
424 DBG(LOWPROBE, ul_debug("\tcall probefunc()"));
425 errno = 0;
426 rc = id->probefunc(pr, mag);
427 blkid_probe_prune_buffers(pr);
428 if (rc != BLKID_PROBE_OK) {
429 blkid_probe_chain_reset_values(pr, chn);
430 if (rc < 0)
431 break;
432 continue;
433 }
434 }
435
436 /* all checks passed */
437 if (chn->flags & BLKID_SUBLKS_TYPE)
438 rc = blkid_probe_set_value(pr, "TYPE",
439 (const unsigned char *) id->name,
440 strlen(id->name) + 1);
441
442 if (!rc)
443 rc = blkid_probe_set_usage(pr, id->usage);
444
445 if (!rc && mag)
446 rc = blkid_probe_set_magic(pr, off, mag->len,
447 (const unsigned char *) mag->magic);
448 if (rc) {
449 blkid_probe_chain_reset_values(pr, chn);
450 DBG(LOWPROBE, ul_debug("failed to set result -- ignore"));
451 continue;
452 }
453
454 DBG(LOWPROBE, ul_debug("<-- leaving probing loop (type=%s) [SUBLKS idx=%d]",
455 id->name, chn->idx));
456 return BLKID_PROBE_OK;
457 }
458
459 DBG(LOWPROBE, ul_debug("<-- leaving probing loop (failed=%d) [SUBLKS idx=%d]",
460 rc, chn->idx));
461 return rc;
462}
463
464/*
465 * This is the same function as blkid_do_probe(), but returns only one result
466 * (cannot be used in while()) and checks for ambivalent results (more
467 * filesystems on the device) -- in such case returns -2.
468 *
469 * The function does not check for filesystems when a RAID or crypto signature
470 * is detected. The function also does not check for collision between RAIDs
471 * and crypto devices. The first detected RAID or crypto device is returned.
472 *
473 * The function does not probe for ambivalent results on very small devices
474 * (e.g. floppies), on small devices the first detected filesystem is returned.
475 */
476static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn)
477{
478 struct list_head vals;
479 int idx = -1;
480 int count = 0;
481 int intol = 0;
482 int rc;
483
484 INIT_LIST_HEAD(&vals);
485
486 if (pr->flags & BLKID_FL_NOSCAN_DEV)
487 return BLKID_PROBE_NONE;
488
489 while ((rc = superblocks_probe(pr, chn)) == 0) {
490
491 if (blkid_probe_is_tiny(pr) && !count)
492 return BLKID_PROBE_OK; /* floppy or so -- returns the first result. */
493
494 count++;
495
496 if (chn->idx >= 0 &&
497 idinfos[chn->idx]->usage & (BLKID_USAGE_RAID | BLKID_USAGE_CRYPTO))
498 break;
499
500 if (chn->idx >= 0 &&
501 !(idinfos[chn->idx]->flags & BLKID_IDINFO_TOLERANT))
502 intol++;
503
504 if (count == 1) {
505 /* save the first result */
506 blkid_probe_chain_save_values(pr, chn, &vals);
507 idx = chn->idx;
508 }
509 }
510
511 if (rc < 0)
512 goto done; /* error */
513
514 if (count > 1 && intol) {
515 DBG(LOWPROBE, ul_debug("ERROR: superblocks chain: "
516 "ambivalent result detected (%d filesystems)!",
517 count));
518 rc = BLKID_PROBE_AMBIGUOUS; /* error, ambivalent result (more FS) */
519 goto done;
520 }
521 if (!count) {
522 rc = BLKID_PROBE_NONE;
523 goto done;
524 }
525
526 if (idx != -1) {
527 /* restore the first result */
528 blkid_probe_chain_reset_values(pr, chn);
529 blkid_probe_append_values_list(pr, &vals);
530 chn->idx = idx;
531 }
532
533 /*
534 * The RAID device could be partitioned. The problem are RAID1 devices
535 * where the partition table is visible from underlying devices. We
536 * have to ignore such partition tables.
537 */
538 if (chn->idx >= 0 && idinfos[chn->idx]->usage & BLKID_USAGE_RAID)
539 pr->prob_flags |= BLKID_PROBE_FL_IGNORE_PT;
540
541 rc = BLKID_PROBE_OK;
542done:
543 blkid_probe_free_values_list(&vals);
544 return rc;
545}
546
547int blkid_probe_set_version(blkid_probe pr, const char *version)
548{
549 struct blkid_chain *chn = blkid_probe_get_chain(pr);
550
551 if (chn->flags & BLKID_SUBLKS_VERSION)
552 return blkid_probe_set_value(pr, "VERSION",
553 (const unsigned char *) version,
554 strlen(version) + 1);
555 return 0;
556}
557
558
559int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
560{
561 struct blkid_chain *chn = blkid_probe_get_chain(pr);
562 int rc = 0;
563
564 if (chn->flags & BLKID_SUBLKS_VERSION) {
565 va_list ap;
566
567 va_start(ap, fmt);
568 rc = blkid_probe_vsprintf_value(pr, "VERSION", fmt, ap);
569 va_end(ap);
570 }
571 return rc;
572}
573
574int blkid_probe_set_block_size(blkid_probe pr, unsigned block_size)
575{
576 return blkid_probe_sprintf_value(pr, "BLOCK_SIZE", "%u", block_size);
577}
578
579static int blkid_probe_set_usage(blkid_probe pr, int usage)
580{
581 struct blkid_chain *chn = blkid_probe_get_chain(pr);
582 const char *u = NULL;
583
584 if (!(chn->flags & BLKID_SUBLKS_USAGE))
585 return 0;
586
587 if (usage & BLKID_USAGE_FILESYSTEM)
588 u = "filesystem";
589 else if (usage & BLKID_USAGE_RAID)
590 u = "raid";
591 else if (usage & BLKID_USAGE_CRYPTO)
592 u = "crypto";
593 else if (usage & BLKID_USAGE_OTHER)
594 u = "other";
595 else
596 u = "unknown";
597
598 return blkid_probe_set_value(pr, "USAGE",
599 (const unsigned char *) u, strlen(u) + 1);
600}
601
602/* size used by filesystem for data */
603int blkid_probe_set_fssize(blkid_probe pr, uint64_t size)
604{
605 struct blkid_chain *chn = blkid_probe_get_chain(pr);
606
607 if (!(chn->flags & BLKID_SUBLKS_FSINFO))
608 return 0;
609
610 return blkid_probe_sprintf_value(pr, "FSSIZE", "%" PRIu64, size);
611}
612
613int blkid_probe_set_fslastblock(blkid_probe pr, uint64_t lastblock)
614{
615 struct blkid_chain *chn = blkid_probe_get_chain(pr);
616
617 if (!(chn->flags & BLKID_SUBLKS_FSINFO))
618 return 0;
619
620 return blkid_probe_sprintf_value(pr, "FSLASTBLOCK", "%" PRIu64,
621 lastblock);
622}
623
624int blkid_probe_set_fsblocksize(blkid_probe pr, uint32_t block_size)
625{
626 struct blkid_chain *chn = blkid_probe_get_chain(pr);
627
628 if (!(chn->flags & BLKID_SUBLKS_FSINFO))
629 return 0;
630
631 return blkid_probe_sprintf_value(pr, "FSBLOCKSIZE", "%" PRIu32,
632 block_size);
633}
634
635int blkid_probe_set_fsendianness(blkid_probe pr, enum blkid_endianness endianness)
636{
637 struct blkid_chain *chn = blkid_probe_get_chain(pr);
638 const char *value;
639
640 if (!(chn->flags & BLKID_SUBLKS_FSINFO))
641 return 0;
642
643 switch (endianness) {
644 case BLKID_ENDIANNESS_LITTLE:
645 value = "LITTLE";
646 break;
647 case BLKID_ENDIANNESS_BIG:
648 value = "BIG";
649 break;
650 default:
651 return -EINVAL;
652 }
653
654 return blkid_probe_set_value(pr, "ENDIANNESS",
655 (const unsigned char *) value, strlen(value) + 1);
656
657}
658
659int blkid_probe_set_id_label(blkid_probe pr, const char *name,
660 const unsigned char *data, size_t len)
661{
662 struct blkid_chain *chn = blkid_probe_get_chain(pr);
663 struct blkid_prval *v;
664 int rc = 0;
665
666 if (!(chn->flags & BLKID_SUBLKS_LABEL))
667 return 0;
668
669 v = blkid_probe_assign_value(pr, name);
670 if (!v)
671 return -ENOMEM;
672
673 rc = blkid_probe_value_set_data(v, data, len);
674 if (!rc) {
675 /* remove white spaces */
676 v->len = blkid_rtrim_whitespace(v->data) + 1;
677 if (v->len > 1)
678 v->len = blkid_ltrim_whitespace(v->data) + 1;
679 if (v->len > 1)
680 return 0;
681 }
682
683 blkid_probe_free_value(v);
684 return rc;
685
686}
687
688int blkid_probe_set_utf8_id_label(blkid_probe pr, const char *name,
689 const unsigned char *data, size_t len, int enc)
690{
691 struct blkid_chain *chn = blkid_probe_get_chain(pr);
692 struct blkid_prval *v;
693 int rc = 0;
694
695 if (!(chn->flags & BLKID_SUBLKS_LABEL))
696 return 0;
697
698 v = blkid_probe_assign_value(pr, name);
699 if (!v)
700 return -ENOMEM;
701
702 v->len = (len * 3) + 1;
703 v->data = calloc(1, v->len);
704 if (!v->data)
705 rc = -ENOMEM;
706
707 if (!rc) {
708 ul_encode_to_utf8(enc, v->data, v->len, data, len);
709 v->len = blkid_rtrim_whitespace(v->data) + 1;
710 if (v->len > 1)
711 v->len = blkid_ltrim_whitespace(v->data) + 1;
712 if (v->len > 1)
713 return 0;
714 }
715
716 blkid_probe_free_value(v);
717 return rc;
718}
719
720int blkid_probe_set_label(blkid_probe pr, const unsigned char *label, size_t len)
721{
722 struct blkid_chain *chn = blkid_probe_get_chain(pr);
723 struct blkid_prval *v;
724 int rc = 0;
725
726 if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
727 (rc = blkid_probe_set_value(pr, "LABEL_RAW", label, len)) < 0)
728 return rc;
729
730 if (!(chn->flags & BLKID_SUBLKS_LABEL))
731 return 0;
732
733 v = blkid_probe_assign_value(pr, "LABEL");
734 if (!v)
735 return -ENOMEM;
736
737 rc = blkid_probe_value_set_data(v, label, len);
738 if (!rc) {
739 v->len = blkid_rtrim_whitespace(v->data) + 1;
740 if (v->len > 1)
741 return 0;
742 }
743
744 blkid_probe_free_value(v);
745 return rc;
746}
747
748int blkid_probe_set_utf8label(blkid_probe pr, const unsigned char *label,
749 size_t len, int enc)
750{
751 struct blkid_chain *chn = blkid_probe_get_chain(pr);
752 struct blkid_prval *v;
753 int rc = 0;
754
755 if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
756 (rc = blkid_probe_set_value(pr, "LABEL_RAW", label, len)) < 0)
757 return rc;
758
759 if (!(chn->flags & BLKID_SUBLKS_LABEL))
760 return 0;
761
762 v = blkid_probe_assign_value(pr, "LABEL");
763 if (!v)
764 return -ENOMEM;
765
766 v->len = (len * 3) + 1;
767 v->data = calloc(1, v->len);
768 if (!v->data)
769 rc = -ENOMEM;
770 if (!rc) {
771 ul_encode_to_utf8(enc, v->data, v->len, label, len);
772 v->len = blkid_rtrim_whitespace(v->data) + 1;
773 if (v->len > 1)
774 return 0;
775 }
776
777 blkid_probe_free_value(v);
778 return rc;
779}
780
781int blkid_probe_sprintf_uuid(blkid_probe pr, const unsigned char *uuid,
782 size_t len, const char *fmt, ...)
783{
784 struct blkid_chain *chn = blkid_probe_get_chain(pr);
785 va_list ap;
786 int rc = 0;
787
788 if (blkid_uuid_is_empty(uuid, len))
789 return 0;
790
791 if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
792 (rc = blkid_probe_set_value(pr, "UUID_RAW", uuid, len)) < 0)
793 return rc;
794
795 if (!(chn->flags & BLKID_SUBLKS_UUID))
796 return 0;
797
798 va_start(ap, fmt);
799 rc = blkid_probe_vsprintf_value(pr, "UUID", fmt, ap);
800 va_end(ap);
801
802 return rc;
803}
804
805/* function to set UUIDs that are in superblocks stored as strings */
806int blkid_probe_strncpy_uuid(blkid_probe pr, const unsigned char *str, size_t len)
807{
808 struct blkid_chain *chn = blkid_probe_get_chain(pr);
809 struct blkid_prval *v;
810 int rc = 0;
811
812 if (str == NULL || *str == '\0')
813 return -EINVAL;
814
815 if (!len)
816 len = strlen((const char *) str);
817
818 if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
819 (rc = blkid_probe_set_value(pr, "UUID_RAW", str, len)) < 0)
820 return rc;
821
822 if (!(chn->flags & BLKID_SUBLKS_UUID))
823 return 0;
824
825 v = blkid_probe_assign_value(pr, "UUID");
826 if (!v)
827 rc= -ENOMEM;
828 if (!rc)
829 rc = blkid_probe_value_set_data(v, str, len);
830 if (!rc) {
831 v->len = blkid_rtrim_whitespace(v->data) + 1;
832 if (v->len > 1)
833 return 0;
834 }
835
836 blkid_probe_free_value(v);
837 return rc;
838}
839
840/* default _set_uuid function to set DCE UUIDs */
841int blkid_probe_set_uuid_as(blkid_probe pr, const unsigned char *uuid, const char *name)
842{
843 struct blkid_chain *chn = blkid_probe_get_chain(pr);
844 struct blkid_prval *v;
845 int rc = 0;
846
847 if (blkid_uuid_is_empty(uuid, 16))
848 return 0;
849
850 if (!name) {
851 if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
852 (rc = blkid_probe_set_value(pr, "UUID_RAW", uuid, 16)) < 0)
853 return rc;
854
855 if (!(chn->flags & BLKID_SUBLKS_UUID))
856 return 0;
857
858 v = blkid_probe_assign_value(pr, "UUID");
859 } else
860 v = blkid_probe_assign_value(pr, name);
861
862 if (!v)
863 return -ENOMEM;
864
865 v->len = UUID_STR_LEN;
866 v->data = calloc(1, v->len);
867 if (!v->data)
868 rc = -ENOMEM;
869
870 if (!rc) {
871 blkid_unparse_uuid(uuid, (char *) v->data, v->len);
872 return 0;
873 }
874
875 blkid_probe_free_value(v);
876 return rc;
877}
878
879int blkid_probe_set_uuid(blkid_probe pr, const unsigned char *uuid)
880{
881 return blkid_probe_set_uuid_as(pr, uuid, NULL);
882}
883
884/**
885 * blkid_probe_set_request:
886 * @pr: probe
887 * @flags: BLKID_PROBREQ_* (deprecated) or BLKID_SUBLKS_* flags
888 *
889 * Returns: 0 on success, or -1 in case of error.
890 *
891 * Deprecated: Use blkid_probe_set_superblocks_flags().
892 */
893int blkid_probe_set_request(blkid_probe pr, int flags)
894{
895 return blkid_probe_set_superblocks_flags(pr, flags);
896}
897
898/**
899 * blkid_probe_reset_filter:
900 * @pr: prober
901 *
902 * Returns: 0 on success, or -1 in case of error.
903 *
904 * Deprecated: Use blkid_probe_reset_superblocks_filter().
905 */
906int blkid_probe_reset_filter(blkid_probe pr)
907{
908 return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
909}
910
911/**
912 * blkid_probe_invert_filter:
913 * @pr: prober
914 *
915 * Returns: 0 on success, or -1 in case of error.
916 *
917 * Deprecated: Use blkid_probe_invert_superblocks_filter().
918 */
919int blkid_probe_invert_filter(blkid_probe pr)
920{
921 return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
922}
923
924/**
925 * blkid_probe_filter_types
926 * @pr: prober
927 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
928 * @names: NULL terminated array of probing function names (e.g. "vfat").
929 *
930 * Returns: 0 on success, or -1 in case of error.
931 *
932 * Deprecated: Use blkid_probe_filter_superblocks_type().
933 */
934int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[])
935{
936 return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
937}
938
939/**
940 * blkid_probe_filter_usage
941 * @pr: prober
942 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
943 * @usage: BLKID_USAGE_* flags
944 *
945 * Returns: 0 on success, or -1 in case of error.
946 *
947 * Deprecated: Use blkid_probe_filter_superblocks_usage().
948 */
949int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage)
950{
951 return blkid_probe_filter_superblocks_usage(pr, flag, usage);
952}
953
954