blob: 80bd6e596f3d0d42465acd17c353340256259e46 [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,
158 &f2fs_idinfo
159};
160
161/*
162 * Driver definition
163 */
164const struct blkid_chaindrv superblocks_drv = {
165 .id = BLKID_CHAIN_SUBLKS,
166 .name = "superblocks",
167 .dflt_enabled = TRUE,
168 .dflt_flags = BLKID_SUBLKS_DEFAULT,
169 .idinfos = idinfos,
170 .nidinfos = ARRAY_SIZE(idinfos),
171 .has_fltr = TRUE,
172 .probe = superblocks_probe,
173 .safeprobe = superblocks_safeprobe,
174};
175
176/**
177 * blkid_probe_enable_superblocks:
178 * @pr: probe
179 * @enable: TRUE/FALSE
180 *
181 * Enables/disables the superblocks probing for non-binary interface.
182 *
183 * Returns: 0 on success, or -1 in case of error.
184 */
185int blkid_probe_enable_superblocks(blkid_probe pr, int enable)
186{
187 if (!pr)
188 return -1;
189 pr->chains[BLKID_CHAIN_SUBLKS].enabled = enable;
190 return 0;
191}
192
193/**
194 * blkid_probe_set_superblocks_flags:
195 * @pr: prober
196 * @flags: BLKID_SUBLKS_* flags
197 *
198 * Sets probing flags to the superblocks prober. This function is optional, the
199 * default are BLKID_SUBLKS_DEFAULTS flags.
200 *
201 * Returns: 0 on success, or -1 in case of error.
202 */
203int blkid_probe_set_superblocks_flags(blkid_probe pr, int flags)
204{
205 if (!pr)
206 return -1;
207
208 pr->chains[BLKID_CHAIN_SUBLKS].flags = flags;
209 return 0;
210}
211
212/**
213 * blkid_probe_reset_superblocks_filter:
214 * @pr: prober
215 *
216 * Resets superblocks probing filter
217 *
218 * Returns: 0 on success, or -1 in case of error.
219 */
220int blkid_probe_reset_superblocks_filter(blkid_probe pr)
221{
222 return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
223}
224
225/**
226 * blkid_probe_invert_superblocks_filter:
227 * @pr: prober
228 *
229 * Inverts superblocks probing filter
230 *
231 * Returns: 0 on success, or -1 in case of error.
232 */
233int blkid_probe_invert_superblocks_filter(blkid_probe pr)
234{
235 return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
236}
237
238/**
239 * blkid_probe_filter_superblocks_type:
240 * @pr: prober
241 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
242 * @names: NULL terminated array of probing function names (e.g. "vfat").
243 *
244 * %BLKID_FLTR_NOTIN - probe for all items which are NOT IN @names;
245 *
246 * %BLKID_FLTR_ONLYIN - probe for items which are IN @names
247 *
248 * Returns: 0 on success, or -1 in case of error.
249 */
250int blkid_probe_filter_superblocks_type(blkid_probe pr, int flag, char *names[])
251{
252 return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
253}
254
255/**
256 * blkid_probe_filter_superblocks_usage:
257 * @pr: prober
258 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
259 * @usage: BLKID_USAGE_* flags
260 *
261 * %BLKID_FLTR_NOTIN - probe for all items which are NOT IN @usage;
262 *
263 * %BLKID_FLTR_ONLYIN - probe for items which are IN @usage
264 *
265 * Returns: 0 on success, or -1 in case of error.
266 */
267int blkid_probe_filter_superblocks_usage(blkid_probe pr, int flag, int usage)
268{
269 unsigned long *fltr;
270 struct blkid_chain *chn;
271 size_t i;
272
273 fltr = blkid_probe_get_filter(pr, BLKID_CHAIN_SUBLKS, TRUE);
274 if (!fltr)
275 return -1;
276
277 chn = &pr->chains[BLKID_CHAIN_SUBLKS];
278
279 for (i = 0; i < chn->driver->nidinfos; i++) {
280 const struct blkid_idinfo *id = chn->driver->idinfos[i];
281
282 if (id->usage & usage) {
283 if (flag & BLKID_FLTR_NOTIN)
284 blkid_bmp_set_item(chn->fltr, i);
285 } else if (flag & BLKID_FLTR_ONLYIN)
286 blkid_bmp_set_item(chn->fltr, i);
287 }
bigbiff7b4c7a62015-01-01 19:44:14 -0500288 DBG(LOWPROBE, ul_debug("a new probing usage-filter initialized"));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500289 return 0;
290}
291
292/**
293 * blkid_known_fstype:
294 * @fstype: filesystem name
295 *
296 * Returns: 1 for known filesytems, or 0 for unknown filesystem.
297 */
298int blkid_known_fstype(const char *fstype)
299{
300 size_t i;
301
302 if (!fstype)
303 return 0;
304
305 for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
306 const struct blkid_idinfo *id = idinfos[i];
307 if (strcmp(id->name, fstype) == 0)
308 return 1;
309 }
310 return 0;
311}
312
313/**
314 * blkid_superblocks_get_name:
315 * @idx: number >= 0
316 * @name: returns name of supported filesystem/raid (optional)
317 * @usage: returns BLKID_USAGE_* flags, (optional)
318 *
319 * Returns: -1 if @idx is out of range, or 0 on success.
320 */
321int blkid_superblocks_get_name(size_t idx, const char **name, int *usage)
322{
323 if (idx < ARRAY_SIZE(idinfos)) {
324 if (name)
325 *name = idinfos[idx]->name;
326 if (usage)
327 *usage = idinfos[idx]->usage;
328 return 0;
329 }
330 return -1;
331}
332
333/*
334 * The blkid_do_probe() backend.
335 */
336static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
337{
338 size_t i;
bigbiff7b4c7a62015-01-01 19:44:14 -0500339 int rc = BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500340
341 if (!pr || chn->idx < -1)
bigbiff7b4c7a62015-01-01 19:44:14 -0500342 return -EINVAL;
343
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500344 blkid_probe_chain_reset_vals(pr, chn);
345
bigbiff7b4c7a62015-01-01 19:44:14 -0500346 if (pr->flags & BLKID_FL_NOSCAN_DEV)
347 return BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500348
349 if (pr->size <= 0 || (pr->size <= 1024 && !S_ISCHR(pr->mode)))
350 /* Ignore very very small block devices or regular files (e.g.
351 * extended partitions). Note that size of the UBI char devices
352 * is 1 byte */
bigbiff7b4c7a62015-01-01 19:44:14 -0500353 return BLKID_PROBE_NONE;
354
355 DBG(LOWPROBE, ul_debug("--> starting probing loop [SUBLKS idx=%d]",
356 chn->idx));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500357
358 i = chn->idx < 0 ? 0 : chn->idx + 1U;
359
360 for ( ; i < ARRAY_SIZE(idinfos); i++) {
361 const struct blkid_idinfo *id;
362 const struct blkid_idmag *mag = NULL;
363 blkid_loff_t off = 0;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500364
365 chn->idx = i;
366 id = idinfos[i];
367
368 if (chn->fltr && blkid_bmp_get_item(chn->fltr, i)) {
bigbiff7b4c7a62015-01-01 19:44:14 -0500369 DBG(LOWPROBE, ul_debug("filter out: %s", id->name));
370 rc = BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500371 continue;
372 }
373
bigbiff7b4c7a62015-01-01 19:44:14 -0500374 if (id->minsz && id->minsz > pr->size) {
375 rc = BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500376 continue; /* the device is too small */
bigbiff7b4c7a62015-01-01 19:44:14 -0500377 }
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500378
379 /* don't probe for RAIDs, swap or journal on CD/DVDs */
380 if ((id->usage & (BLKID_USAGE_RAID | BLKID_USAGE_OTHER)) &&
bigbiff7b4c7a62015-01-01 19:44:14 -0500381 blkid_probe_is_cdrom(pr)) {
382 rc = BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500383 continue;
bigbiff7b4c7a62015-01-01 19:44:14 -0500384 }
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500385
386 /* don't probe for RAIDs on floppies */
bigbiff7b4c7a62015-01-01 19:44:14 -0500387 if ((id->usage & BLKID_USAGE_RAID) && blkid_probe_is_tiny(pr)) {
388 rc = BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500389 continue;
bigbiff7b4c7a62015-01-01 19:44:14 -0500390 }
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500391
bigbiff7b4c7a62015-01-01 19:44:14 -0500392 DBG(LOWPROBE, ul_debug("[%zd] %s:", i, id->name));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500393
bigbiff7b4c7a62015-01-01 19:44:14 -0500394 rc = blkid_probe_get_idmag(pr, id, &off, &mag);
395 if (rc < 0)
396 break;
397 if (rc != BLKID_PROBE_OK)
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500398 continue;
399
400 /* final check by probing function */
401 if (id->probefunc) {
bigbiff7b4c7a62015-01-01 19:44:14 -0500402 DBG(LOWPROBE, ul_debug("\tcall probefunc()"));
403 rc = id->probefunc(pr, mag);
404 if (rc != BLKID_PROBE_OK) {
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500405 blkid_probe_chain_reset_vals(pr, chn);
bigbiff7b4c7a62015-01-01 19:44:14 -0500406 if (rc < 0)
407 break;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500408 continue;
409 }
410 }
411
412 /* all cheks passed */
413 if (chn->flags & BLKID_SUBLKS_TYPE)
414 rc = blkid_probe_set_value(pr, "TYPE",
415 (unsigned char *) id->name,
416 strlen(id->name) + 1);
417
418 if (!rc)
419 rc = blkid_probe_set_usage(pr, id->usage);
420
421 if (!rc && mag)
422 rc = blkid_probe_set_magic(pr, off, mag->len,
423 (unsigned char *) mag->magic);
424 if (rc) {
425 blkid_probe_chain_reset_vals(pr, chn);
bigbiff7b4c7a62015-01-01 19:44:14 -0500426 DBG(LOWPROBE, ul_debug("failed to set result -- ignore"));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500427 continue;
428 }
429
bigbiff7b4c7a62015-01-01 19:44:14 -0500430 DBG(LOWPROBE, ul_debug("<-- leaving probing loop (type=%s) [SUBLKS idx=%d]",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500431 id->name, chn->idx));
bigbiff7b4c7a62015-01-01 19:44:14 -0500432 return BLKID_PROBE_OK;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500433 }
434
bigbiff7b4c7a62015-01-01 19:44:14 -0500435 DBG(LOWPROBE, ul_debug("<-- leaving probing loop (failed=%d) [SUBLKS idx=%d]",
436 rc, chn->idx));
437 return rc;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500438}
439
440/*
441 * This is the same function as blkid_do_probe(), but returns only one result
442 * (cannot be used in while()) and checks for ambivalen results (more
443 * filesystems on the device) -- in such case returns -2.
444 *
445 * The function does not check for filesystems when a RAID or crypto signature
446 * is detected. The function also does not check for collision between RAIDs
447 * and crypto devices. The first detected RAID or crypto device is returned.
448 *
449 * The function does not probe for ambivalent results on very small devices
450 * (e.g. floppies), on small devices the first detected filesystem is returned.
451 */
452static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn)
453{
454 struct blkid_prval vals[BLKID_NVALS_SUBLKS];
455 int nvals = BLKID_NVALS_SUBLKS;
456 int idx = -1;
457 int count = 0;
458 int intol = 0;
459 int rc;
460
bigbiff7b4c7a62015-01-01 19:44:14 -0500461 if (pr->flags & BLKID_FL_NOSCAN_DEV)
462 return BLKID_PROBE_NONE;
463
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500464 while ((rc = superblocks_probe(pr, chn)) == 0) {
465
466 if (blkid_probe_is_tiny(pr) && !count)
bigbiff7b4c7a62015-01-01 19:44:14 -0500467 return BLKID_PROBE_OK; /* floppy or so -- returns the first result. */
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500468
469 count++;
470
471 if (chn->idx >= 0 &&
472 idinfos[chn->idx]->usage & (BLKID_USAGE_RAID | BLKID_USAGE_CRYPTO))
473 break;
474
475 if (chn->idx >= 0 &&
476 !(idinfos[chn->idx]->flags & BLKID_IDINFO_TOLERANT))
477 intol++;
478
479 if (count == 1) {
480 /* save the first result */
481 nvals = blkid_probe_chain_copy_vals(pr, chn, vals, nvals);
482 idx = chn->idx;
483 }
484 }
485
486 if (rc < 0)
487 return rc; /* error */
488
489 if (count > 1 && intol) {
bigbiff7b4c7a62015-01-01 19:44:14 -0500490 DBG(LOWPROBE, ul_debug("ERROR: superblocks chain: "
491 "ambivalent result detected (%d filesystems)!",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500492 count));
493 return -2; /* error, ambivalent result (more FS) */
494 }
495 if (!count)
bigbiff7b4c7a62015-01-01 19:44:14 -0500496 return BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500497
498 if (idx != -1) {
499 /* restore the first result */
500 blkid_probe_chain_reset_vals(pr, chn);
501 blkid_probe_append_vals(pr, vals, nvals);
502 chn->idx = idx;
503 }
504
505 /*
506 * The RAID device could be partitioned. The problem are RAID1 devices
507 * where the partition table is visible from underlaying devices. We
508 * have to ignore such partition tables.
509 */
510 if (chn->idx >= 0 && idinfos[chn->idx]->usage & BLKID_USAGE_RAID)
511 pr->prob_flags |= BLKID_PROBE_FL_IGNORE_PT;
512
bigbiff7b4c7a62015-01-01 19:44:14 -0500513 return BLKID_PROBE_OK;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500514}
515
516int blkid_probe_set_version(blkid_probe pr, const char *version)
517{
518 struct blkid_chain *chn = blkid_probe_get_chain(pr);
519
520 if (chn->flags & BLKID_SUBLKS_VERSION)
521 return blkid_probe_set_value(pr, "VERSION",
522 (unsigned char *) version, strlen(version) + 1);
523 return 0;
524}
525
526
527int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
528{
529 struct blkid_chain *chn = blkid_probe_get_chain(pr);
530 int rc = 0;
531
532 if (chn->flags & BLKID_SUBLKS_VERSION) {
533 va_list ap;
534
535 va_start(ap, fmt);
536 rc = blkid_probe_vsprintf_value(pr, "VERSION", fmt, ap);
537 va_end(ap);
538 }
539 return rc;
540}
541
542static int blkid_probe_set_usage(blkid_probe pr, int usage)
543{
544 struct blkid_chain *chn = blkid_probe_get_chain(pr);
545 char *u = NULL;
546
547 if (!(chn->flags & BLKID_SUBLKS_USAGE))
548 return 0;
549
550 if (usage & BLKID_USAGE_FILESYSTEM)
551 u = "filesystem";
552 else if (usage & BLKID_USAGE_RAID)
553 u = "raid";
554 else if (usage & BLKID_USAGE_CRYPTO)
555 u = "crypto";
556 else if (usage & BLKID_USAGE_OTHER)
557 u = "other";
558 else
559 u = "unknown";
560
561 return blkid_probe_set_value(pr, "USAGE", (unsigned char *) u, strlen(u) + 1);
562}
563
564int blkid_probe_set_id_label(blkid_probe pr, const char *name,
565 unsigned char *data, size_t len)
566{
567 struct blkid_chain *chn = blkid_probe_get_chain(pr);
568 struct blkid_prval *v;
569
570 if (!(chn->flags & BLKID_SUBLKS_LABEL))
571 return 0;
572
573 v = blkid_probe_assign_value(pr, name);
574 if (!v)
575 return -1;
576
577 if (len >= BLKID_PROBVAL_BUFSIZ)
578 len = BLKID_PROBVAL_BUFSIZ - 1; /* make a space for \0 */
579
580 memcpy(v->data, data, len);
581 v->data[len] = '\0';
582
583 /* remove white spaces */
584 v->len = blkid_rtrim_whitespace(v->data) + 1;
585 if (v->len > 1)
586 v->len = blkid_ltrim_whitespace(v->data) + 1;
587
588 if (v->len <= 1)
589 blkid_probe_reset_last_value(pr); /* ignore empty */
590 return 0;
591}
592
593int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len)
594{
595 struct blkid_chain *chn = blkid_probe_get_chain(pr);
596 struct blkid_prval *v;
597 if (len > BLKID_PROBVAL_BUFSIZ)
598 len = BLKID_PROBVAL_BUFSIZ;
599
600 if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
601 blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0)
602 return -1;
603 if (!(chn->flags & BLKID_SUBLKS_LABEL))
604 return 0;
605 v = blkid_probe_assign_value(pr, "LABEL");
606 if (!v)
607 return -1;
608
609 if (len == BLKID_PROBVAL_BUFSIZ)
610 len--; /* make a space for \0 */
611
612 memcpy(v->data, label, len);
613 v->data[len] = '\0';
614
615 v->len = blkid_rtrim_whitespace(v->data) + 1;
616 if (v->len == 1)
617 blkid_probe_reset_last_value(pr);
618 return 0;
619}
620
621int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label,
622 size_t len, int enc)
623{
624 struct blkid_chain *chn = blkid_probe_get_chain(pr);
625 struct blkid_prval *v;
626
627 if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
628 blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0)
629 return -1;
630 if (!(chn->flags & BLKID_SUBLKS_LABEL))
631 return 0;
632 v = blkid_probe_assign_value(pr, "LABEL");
633 if (!v)
634 return -1;
635
636 blkid_encode_to_utf8(enc, v->data, sizeof(v->data), label, len);
637 v->len = blkid_rtrim_whitespace(v->data) + 1;
638 if (v->len == 1)
639 blkid_probe_reset_last_value(pr);
640 return 0;
641}
642
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500643int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid,
644 size_t len, const char *fmt, ...)
645{
646 struct blkid_chain *chn = blkid_probe_get_chain(pr);
647 int rc = -1;
648 va_list ap;
649
650 if (len > BLKID_PROBVAL_BUFSIZ)
651 len = BLKID_PROBVAL_BUFSIZ;
652
bigbiff7b4c7a62015-01-01 19:44:14 -0500653 if (blkid_uuid_is_empty(uuid, len))
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500654 return 0;
655
656 if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
657 blkid_probe_set_value(pr, "UUID_RAW", uuid, len) < 0)
658 return -1;
659 if (!(chn->flags & BLKID_SUBLKS_UUID))
660 return 0;
661
662 va_start(ap, fmt);
663 rc = blkid_probe_vsprintf_value(pr, "UUID", fmt, ap);
664 va_end(ap);
665
666 /* convert to lower case (..be paranoid) */
667 if (!rc) {
668 size_t i;
669 struct blkid_prval *v = __blkid_probe_get_value(pr,
670 blkid_probe_numof_values(pr));
671 if (v) {
672 for (i = 0; i < v->len; i++)
673 if (v->data[i] >= 'A' && v->data[i] <= 'F')
674 v->data[i] = (v->data[i] - 'A') + 'a';
675 }
676 }
677 return rc;
678}
679
680/* function to set UUIDs that are in suberblocks stored as strings */
681int blkid_probe_strncpy_uuid(blkid_probe pr, unsigned char *str, size_t len)
682{
683 struct blkid_chain *chn = blkid_probe_get_chain(pr);
684 struct blkid_prval *v;
685
686 if (str == NULL || *str == '\0')
687 return -1;
688 if (!len)
689 len = strlen((char *) str);
690 if (len > BLKID_PROBVAL_BUFSIZ)
691 len = BLKID_PROBVAL_BUFSIZ;
692
693 if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
694 blkid_probe_set_value(pr, "UUID_RAW", str, len) < 0)
695 return -1;
696 if (!(chn->flags & BLKID_SUBLKS_UUID))
697 return 0;
698
699 v = blkid_probe_assign_value(pr, "UUID");
700 if (v) {
701 if (len == BLKID_PROBVAL_BUFSIZ)
702 len--; /* make a space for \0 */
703
704 memcpy((char *) v->data, str, len);
705 v->data[len] = '\0';
706 v->len = len + 1;
707 return 0;
708 }
709 return -1;
710}
711
712/* default _set_uuid function to set DCE UUIDs */
713int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *name)
714{
715 struct blkid_chain *chn = blkid_probe_get_chain(pr);
716 struct blkid_prval *v;
717
bigbiff7b4c7a62015-01-01 19:44:14 -0500718 if (blkid_uuid_is_empty(uuid, 16))
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500719 return 0;
720
721 if (!name) {
722 if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
723 blkid_probe_set_value(pr, "UUID_RAW", uuid, 16) < 0)
724 return -1;
725 if (!(chn->flags & BLKID_SUBLKS_UUID))
726 return 0;
727
728 v = blkid_probe_assign_value(pr, "UUID");
729 } else
730 v = blkid_probe_assign_value(pr, name);
731
732 blkid_unparse_uuid(uuid, (char *) v->data, sizeof(v->data));
733 v->len = 37;
734
735 return 0;
736}
737
738int blkid_probe_set_uuid(blkid_probe pr, unsigned char *uuid)
739{
740 return blkid_probe_set_uuid_as(pr, uuid, NULL);
741}
742
743/**
744 * blkid_probe_set_request:
745 * @pr: probe
746 * @flags: BLKID_PROBREQ_* (deprecated) or BLKID_SUBLKS_* flags
747 *
748 * Returns: 0 on success, or -1 in case of error.
749 *
750 * Deprecated: Use blkid_probe_set_superblocks_flags().
751 */
752int blkid_probe_set_request(blkid_probe pr, int flags)
753{
754 return blkid_probe_set_superblocks_flags(pr, flags);
755}
756
757/**
758 * blkid_probe_reset_filter:
759 * @pr: prober
760 *
761 * Returns: 0 on success, or -1 in case of error.
762 *
763 * Deprecated: Use blkid_probe_reset_superblocks_filter().
764 */
765int blkid_probe_reset_filter(blkid_probe pr)
766{
767 return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
768}
769
770/**
771 * blkid_probe_invert_filter:
772 * @pr: prober
773 *
774 * Returns: 0 on success, or -1 in case of error.
775 *
776 * Deprecated: Use blkid_probe_invert_superblocks_filter().
777 */
778int blkid_probe_invert_filter(blkid_probe pr)
779{
780 return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
781}
782
783/**
784 * blkid_probe_filter_types
785 * @pr: prober
786 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
787 * @names: NULL terminated array of probing function names (e.g. "vfat").
788 *
789 * Returns: 0 on success, or -1 in case of error.
790 *
791 * Deprecated: Use blkid_probe_filter_superblocks_types().
792 */
793int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[])
794{
795 return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
796}
797
798/**
799 * blkid_probe_filter_usage
800 * @pr: prober
801 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
802 * @usage: BLKID_USAGE_* flags
803 *
804 * Returns: 0 on success, or -1 in case of error.
805 *
806 * Deprecated: Use blkid_probe_filter_superblocks_usage().
807 */
808int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage)
809{
810 return blkid_probe_filter_superblocks_usage(pr, flag, usage);
811}
812
813