| /* |
| * superblocks.c - reads information from filesystem and raid superblocks |
| * |
| * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com> |
| * |
| * This file may be redistributed under the terms of the |
| * GNU Lesser General Public License. |
| */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <fcntl.h> |
| #include <ctype.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <errno.h> |
| #include <stdint.h> |
| #include <stdarg.h> |
| |
| #include "superblocks.h" |
| |
| /** |
| * SECTION:superblocks |
| * @title: Superblocks probing |
| * @short_description: filesystems and raids superblocks probing. |
| * |
| * The library API has been originally designed for superblocks probing only. |
| * This is reason why some *deprecated* superblock specific functions don't use |
| * '_superblocks_' namespace in the function name. Please, don't use these |
| * functions in new code. |
| * |
| * The 'superblocks' probers support NAME=value (tags) interface only. The |
| * superblocks probing is enabled by default (and controlled by |
| * blkid_probe_enable_superblocks()). |
| * |
| * Currently supported tags: |
| * |
| * @TYPE: filesystem type |
| * |
| * @SEC_TYPE: secondary filesystem type |
| * |
| * @LABEL: filesystem label |
| * |
| * @LABEL_RAW: raw label from FS superblock |
| * |
| * @UUID: filesystem UUID (lower case) |
| * |
| * @UUID_SUB: subvolume uuid (e.g. btrfs) |
| * |
| * @LOGUUID: external log UUID (e.g. xfs) |
| * |
| * @UUID_RAW: raw UUID from FS superblock |
| * |
| * @EXT_JOURNAL: external journal UUID |
| * |
| * @USAGE: usage string: "raid", "filesystem", ... |
| * |
| * @VERSION: filesystem version |
| * |
| * @MOUNT: cluster mount name (?) -- ocfs only |
| * |
| * @SBMAGIC: super block magic string |
| * |
| * @SBMAGIC_OFFSET: offset of SBMAGIC |
| * |
| * @FSSIZE: size of filessystem [not-implemented yet] |
| * |
| * @SYSTEM_ID: ISO9660 system identifier |
| * |
| * @PUBLISHER_ID: ISO9660 publisher identifier |
| * |
| * @APPLICATION_ID: ISO9660 application identifier |
| * |
| * @BOOT_SYSTEM_ID: ISO9660 boot system identifier |
| */ |
| |
| static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn); |
| static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn); |
| |
| static int blkid_probe_set_usage(blkid_probe pr, int usage); |
| |
| |
| /* |
| * Superblocks chains probing functions |
| */ |
| static const struct blkid_idinfo *idinfos[] = |
| { |
| /* RAIDs */ |
| &linuxraid_idinfo, |
| &ddfraid_idinfo, |
| &iswraid_idinfo, |
| &lsiraid_idinfo, |
| &viaraid_idinfo, |
| &silraid_idinfo, |
| &nvraid_idinfo, |
| &pdcraid_idinfo, |
| &highpoint45x_idinfo, |
| &highpoint37x_idinfo, |
| &adraid_idinfo, |
| &jmraid_idinfo, |
| |
| &bcache_idinfo, |
| &drbd_idinfo, |
| &drbdproxy_datalog_idinfo, |
| &lvm2_idinfo, |
| &lvm1_idinfo, |
| &snapcow_idinfo, |
| &verity_hash_idinfo, |
| &luks_idinfo, |
| &vmfs_volume_idinfo, |
| |
| /* Filesystems */ |
| &vfat_idinfo, |
| &swsuspend_idinfo, |
| &swap_idinfo, |
| &xfs_idinfo, |
| &xfs_log_idinfo, |
| &ext4dev_idinfo, |
| &ext4_idinfo, |
| &ext3_idinfo, |
| &ext2_idinfo, |
| &jbd_idinfo, |
| &reiser_idinfo, |
| &reiser4_idinfo, |
| &jfs_idinfo, |
| &udf_idinfo, |
| &iso9660_idinfo, |
| &zfs_idinfo, |
| &hfsplus_idinfo, |
| &hfs_idinfo, |
| &ufs_idinfo, |
| &hpfs_idinfo, |
| &sysv_idinfo, |
| &xenix_idinfo, |
| &ntfs_idinfo, |
| &refs_idinfo, |
| &cramfs_idinfo, |
| &romfs_idinfo, |
| &minix_idinfo, |
| &gfs_idinfo, |
| &gfs2_idinfo, |
| &ocfs_idinfo, |
| &ocfs2_idinfo, |
| &oracleasm_idinfo, |
| &vxfs_idinfo, |
| &squashfs_idinfo, |
| &squashfs3_idinfo, |
| &netware_idinfo, |
| &btrfs_idinfo, |
| &ubifs_idinfo, |
| &bfs_idinfo, |
| &vmfs_fs_idinfo, |
| &befs_idinfo, |
| &nilfs2_idinfo, |
| &exfat_idinfo, |
| &f2fs_idinfo, |
| &erofs_idinfo |
| }; |
| |
| /* |
| * Driver definition |
| */ |
| const struct blkid_chaindrv superblocks_drv = { |
| .id = BLKID_CHAIN_SUBLKS, |
| .name = "superblocks", |
| .dflt_enabled = TRUE, |
| .dflt_flags = BLKID_SUBLKS_DEFAULT, |
| .idinfos = idinfos, |
| .nidinfos = ARRAY_SIZE(idinfos), |
| .has_fltr = TRUE, |
| .probe = superblocks_probe, |
| .safeprobe = superblocks_safeprobe, |
| }; |
| |
| /** |
| * blkid_probe_enable_superblocks: |
| * @pr: probe |
| * @enable: TRUE/FALSE |
| * |
| * Enables/disables the superblocks probing for non-binary interface. |
| * |
| * Returns: 0 on success, or -1 in case of error. |
| */ |
| int blkid_probe_enable_superblocks(blkid_probe pr, int enable) |
| { |
| if (!pr) |
| return -1; |
| pr->chains[BLKID_CHAIN_SUBLKS].enabled = enable; |
| return 0; |
| } |
| |
| /** |
| * blkid_probe_set_superblocks_flags: |
| * @pr: prober |
| * @flags: BLKID_SUBLKS_* flags |
| * |
| * Sets probing flags to the superblocks prober. This function is optional, the |
| * default are BLKID_SUBLKS_DEFAULTS flags. |
| * |
| * Returns: 0 on success, or -1 in case of error. |
| */ |
| int blkid_probe_set_superblocks_flags(blkid_probe pr, int flags) |
| { |
| if (!pr) |
| return -1; |
| |
| pr->chains[BLKID_CHAIN_SUBLKS].flags = flags; |
| return 0; |
| } |
| |
| /** |
| * blkid_probe_reset_superblocks_filter: |
| * @pr: prober |
| * |
| * Resets superblocks probing filter |
| * |
| * Returns: 0 on success, or -1 in case of error. |
| */ |
| int blkid_probe_reset_superblocks_filter(blkid_probe pr) |
| { |
| return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS); |
| } |
| |
| /** |
| * blkid_probe_invert_superblocks_filter: |
| * @pr: prober |
| * |
| * Inverts superblocks probing filter |
| * |
| * Returns: 0 on success, or -1 in case of error. |
| */ |
| int blkid_probe_invert_superblocks_filter(blkid_probe pr) |
| { |
| return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS); |
| } |
| |
| /** |
| * blkid_probe_filter_superblocks_type: |
| * @pr: prober |
| * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag |
| * @names: NULL terminated array of probing function names (e.g. "vfat"). |
| * |
| * %BLKID_FLTR_NOTIN - probe for all items which are NOT IN @names; |
| * |
| * %BLKID_FLTR_ONLYIN - probe for items which are IN @names |
| * |
| * Returns: 0 on success, or -1 in case of error. |
| */ |
| int blkid_probe_filter_superblocks_type(blkid_probe pr, int flag, char *names[]) |
| { |
| return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names); |
| } |
| |
| /** |
| * blkid_probe_filter_superblocks_usage: |
| * @pr: prober |
| * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag |
| * @usage: BLKID_USAGE_* flags |
| * |
| * %BLKID_FLTR_NOTIN - probe for all items which are NOT IN @usage; |
| * |
| * %BLKID_FLTR_ONLYIN - probe for items which are IN @usage |
| * |
| * Returns: 0 on success, or -1 in case of error. |
| */ |
| int blkid_probe_filter_superblocks_usage(blkid_probe pr, int flag, int usage) |
| { |
| unsigned long *fltr; |
| struct blkid_chain *chn; |
| size_t i; |
| |
| fltr = blkid_probe_get_filter(pr, BLKID_CHAIN_SUBLKS, TRUE); |
| if (!fltr) |
| return -1; |
| |
| chn = &pr->chains[BLKID_CHAIN_SUBLKS]; |
| |
| for (i = 0; i < chn->driver->nidinfos; i++) { |
| const struct blkid_idinfo *id = chn->driver->idinfos[i]; |
| |
| if (id->usage & usage) { |
| if (flag & BLKID_FLTR_NOTIN) |
| blkid_bmp_set_item(chn->fltr, i); |
| } else if (flag & BLKID_FLTR_ONLYIN) |
| blkid_bmp_set_item(chn->fltr, i); |
| } |
| DBG(LOWPROBE, ul_debug("a new probing usage-filter initialized")); |
| return 0; |
| } |
| |
| /** |
| * blkid_known_fstype: |
| * @fstype: filesystem name |
| * |
| * Returns: 1 for known filesytems, or 0 for unknown filesystem. |
| */ |
| int blkid_known_fstype(const char *fstype) |
| { |
| size_t i; |
| |
| if (!fstype) |
| return 0; |
| |
| for (i = 0; i < ARRAY_SIZE(idinfos); i++) { |
| const struct blkid_idinfo *id = idinfos[i]; |
| if (strcmp(id->name, fstype) == 0) |
| return 1; |
| } |
| return 0; |
| } |
| |
| /** |
| * blkid_superblocks_get_name: |
| * @idx: number >= 0 |
| * @name: returns name of supported filesystem/raid (optional) |
| * @usage: returns BLKID_USAGE_* flags, (optional) |
| * |
| * Returns: -1 if @idx is out of range, or 0 on success. |
| */ |
| int blkid_superblocks_get_name(size_t idx, const char **name, int *usage) |
| { |
| if (idx < ARRAY_SIZE(idinfos)) { |
| if (name) |
| *name = idinfos[idx]->name; |
| if (usage) |
| *usage = idinfos[idx]->usage; |
| return 0; |
| } |
| return -1; |
| } |
| |
| /* |
| * The blkid_do_probe() backend. |
| */ |
| static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn) |
| { |
| size_t i; |
| int rc = BLKID_PROBE_NONE; |
| |
| if (!pr || chn->idx < -1) |
| return -EINVAL; |
| |
| blkid_probe_chain_reset_vals(pr, chn); |
| |
| if (pr->flags & BLKID_FL_NOSCAN_DEV) |
| return BLKID_PROBE_NONE; |
| |
| if (pr->size <= 0 || (pr->size <= 1024 && !S_ISCHR(pr->mode))) |
| /* Ignore very very small block devices or regular files (e.g. |
| * extended partitions). Note that size of the UBI char devices |
| * is 1 byte */ |
| return BLKID_PROBE_NONE; |
| |
| DBG(LOWPROBE, ul_debug("--> starting probing loop [SUBLKS idx=%d]", |
| chn->idx)); |
| |
| i = chn->idx < 0 ? 0 : chn->idx + 1U; |
| |
| for ( ; i < ARRAY_SIZE(idinfos); i++) { |
| const struct blkid_idinfo *id; |
| const struct blkid_idmag *mag = NULL; |
| blkid_loff_t off = 0; |
| |
| chn->idx = i; |
| id = idinfos[i]; |
| |
| if (chn->fltr && blkid_bmp_get_item(chn->fltr, i)) { |
| DBG(LOWPROBE, ul_debug("filter out: %s", id->name)); |
| rc = BLKID_PROBE_NONE; |
| continue; |
| } |
| |
| if (id->minsz && id->minsz > pr->size) { |
| rc = BLKID_PROBE_NONE; |
| continue; /* the device is too small */ |
| } |
| |
| /* don't probe for RAIDs, swap or journal on CD/DVDs */ |
| if ((id->usage & (BLKID_USAGE_RAID | BLKID_USAGE_OTHER)) && |
| blkid_probe_is_cdrom(pr)) { |
| rc = BLKID_PROBE_NONE; |
| continue; |
| } |
| |
| /* don't probe for RAIDs on floppies */ |
| if ((id->usage & BLKID_USAGE_RAID) && blkid_probe_is_tiny(pr)) { |
| rc = BLKID_PROBE_NONE; |
| continue; |
| } |
| |
| DBG(LOWPROBE, ul_debug("[%zd] %s:", i, id->name)); |
| |
| rc = blkid_probe_get_idmag(pr, id, &off, &mag); |
| if (rc < 0) |
| break; |
| if (rc != BLKID_PROBE_OK) |
| continue; |
| |
| /* final check by probing function */ |
| if (id->probefunc) { |
| DBG(LOWPROBE, ul_debug("\tcall probefunc()")); |
| rc = id->probefunc(pr, mag); |
| if (rc != BLKID_PROBE_OK) { |
| blkid_probe_chain_reset_vals(pr, chn); |
| if (rc < 0) |
| break; |
| continue; |
| } |
| } |
| |
| /* all cheks passed */ |
| if (chn->flags & BLKID_SUBLKS_TYPE) |
| rc = blkid_probe_set_value(pr, "TYPE", |
| (unsigned char *) id->name, |
| strlen(id->name) + 1); |
| |
| if (!rc) |
| rc = blkid_probe_set_usage(pr, id->usage); |
| |
| if (!rc && mag) |
| rc = blkid_probe_set_magic(pr, off, mag->len, |
| (unsigned char *) mag->magic); |
| if (rc) { |
| blkid_probe_chain_reset_vals(pr, chn); |
| DBG(LOWPROBE, ul_debug("failed to set result -- ignore")); |
| continue; |
| } |
| |
| DBG(LOWPROBE, ul_debug("<-- leaving probing loop (type=%s) [SUBLKS idx=%d]", |
| id->name, chn->idx)); |
| return BLKID_PROBE_OK; |
| } |
| |
| DBG(LOWPROBE, ul_debug("<-- leaving probing loop (failed=%d) [SUBLKS idx=%d]", |
| rc, chn->idx)); |
| return rc; |
| } |
| |
| /* |
| * This is the same function as blkid_do_probe(), but returns only one result |
| * (cannot be used in while()) and checks for ambivalen results (more |
| * filesystems on the device) -- in such case returns -2. |
| * |
| * The function does not check for filesystems when a RAID or crypto signature |
| * is detected. The function also does not check for collision between RAIDs |
| * and crypto devices. The first detected RAID or crypto device is returned. |
| * |
| * The function does not probe for ambivalent results on very small devices |
| * (e.g. floppies), on small devices the first detected filesystem is returned. |
| */ |
| static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn) |
| { |
| struct blkid_prval vals[BLKID_NVALS_SUBLKS]; |
| int nvals = BLKID_NVALS_SUBLKS; |
| int idx = -1; |
| int count = 0; |
| int intol = 0; |
| int rc; |
| |
| if (pr->flags & BLKID_FL_NOSCAN_DEV) |
| return BLKID_PROBE_NONE; |
| |
| while ((rc = superblocks_probe(pr, chn)) == 0) { |
| |
| if (blkid_probe_is_tiny(pr) && !count) |
| return BLKID_PROBE_OK; /* floppy or so -- returns the first result. */ |
| |
| count++; |
| |
| if (chn->idx >= 0 && |
| idinfos[chn->idx]->usage & (BLKID_USAGE_RAID | BLKID_USAGE_CRYPTO)) |
| break; |
| |
| if (chn->idx >= 0 && |
| !(idinfos[chn->idx]->flags & BLKID_IDINFO_TOLERANT)) |
| intol++; |
| |
| if (count == 1) { |
| /* save the first result */ |
| nvals = blkid_probe_chain_copy_vals(pr, chn, vals, nvals); |
| idx = chn->idx; |
| } |
| } |
| |
| if (rc < 0) |
| return rc; /* error */ |
| |
| if (count > 1 && intol) { |
| DBG(LOWPROBE, ul_debug("ERROR: superblocks chain: " |
| "ambivalent result detected (%d filesystems)!", |
| count)); |
| return -2; /* error, ambivalent result (more FS) */ |
| } |
| if (!count) |
| return BLKID_PROBE_NONE; |
| |
| if (idx != -1) { |
| /* restore the first result */ |
| blkid_probe_chain_reset_vals(pr, chn); |
| blkid_probe_append_vals(pr, vals, nvals); |
| chn->idx = idx; |
| } |
| |
| /* |
| * The RAID device could be partitioned. The problem are RAID1 devices |
| * where the partition table is visible from underlaying devices. We |
| * have to ignore such partition tables. |
| */ |
| if (chn->idx >= 0 && idinfos[chn->idx]->usage & BLKID_USAGE_RAID) |
| pr->prob_flags |= BLKID_PROBE_FL_IGNORE_PT; |
| |
| return BLKID_PROBE_OK; |
| } |
| |
| int blkid_probe_set_version(blkid_probe pr, const char *version) |
| { |
| struct blkid_chain *chn = blkid_probe_get_chain(pr); |
| |
| if (chn->flags & BLKID_SUBLKS_VERSION) |
| return blkid_probe_set_value(pr, "VERSION", |
| (unsigned char *) version, strlen(version) + 1); |
| return 0; |
| } |
| |
| |
| int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...) |
| { |
| struct blkid_chain *chn = blkid_probe_get_chain(pr); |
| int rc = 0; |
| |
| if (chn->flags & BLKID_SUBLKS_VERSION) { |
| va_list ap; |
| |
| va_start(ap, fmt); |
| rc = blkid_probe_vsprintf_value(pr, "VERSION", fmt, ap); |
| va_end(ap); |
| } |
| return rc; |
| } |
| |
| static int blkid_probe_set_usage(blkid_probe pr, int usage) |
| { |
| struct blkid_chain *chn = blkid_probe_get_chain(pr); |
| char *u = NULL; |
| |
| if (!(chn->flags & BLKID_SUBLKS_USAGE)) |
| return 0; |
| |
| if (usage & BLKID_USAGE_FILESYSTEM) |
| u = "filesystem"; |
| else if (usage & BLKID_USAGE_RAID) |
| u = "raid"; |
| else if (usage & BLKID_USAGE_CRYPTO) |
| u = "crypto"; |
| else if (usage & BLKID_USAGE_OTHER) |
| u = "other"; |
| else |
| u = "unknown"; |
| |
| return blkid_probe_set_value(pr, "USAGE", (unsigned char *) u, strlen(u) + 1); |
| } |
| |
| int blkid_probe_set_id_label(blkid_probe pr, const char *name, |
| unsigned char *data, size_t len) |
| { |
| struct blkid_chain *chn = blkid_probe_get_chain(pr); |
| struct blkid_prval *v; |
| |
| if (!(chn->flags & BLKID_SUBLKS_LABEL)) |
| return 0; |
| |
| v = blkid_probe_assign_value(pr, name); |
| if (!v) |
| return -1; |
| |
| if (len >= BLKID_PROBVAL_BUFSIZ) |
| len = BLKID_PROBVAL_BUFSIZ - 1; /* make a space for \0 */ |
| |
| memcpy(v->data, data, len); |
| v->data[len] = '\0'; |
| |
| /* remove white spaces */ |
| v->len = blkid_rtrim_whitespace(v->data) + 1; |
| if (v->len > 1) |
| v->len = blkid_ltrim_whitespace(v->data) + 1; |
| |
| if (v->len <= 1) |
| blkid_probe_reset_last_value(pr); /* ignore empty */ |
| return 0; |
| } |
| |
| int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len) |
| { |
| struct blkid_chain *chn = blkid_probe_get_chain(pr); |
| struct blkid_prval *v; |
| if (len > BLKID_PROBVAL_BUFSIZ) |
| len = BLKID_PROBVAL_BUFSIZ; |
| |
| if ((chn->flags & BLKID_SUBLKS_LABELRAW) && |
| blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0) |
| return -1; |
| if (!(chn->flags & BLKID_SUBLKS_LABEL)) |
| return 0; |
| v = blkid_probe_assign_value(pr, "LABEL"); |
| if (!v) |
| return -1; |
| |
| if (len == BLKID_PROBVAL_BUFSIZ) |
| len--; /* make a space for \0 */ |
| |
| memcpy(v->data, label, len); |
| v->data[len] = '\0'; |
| |
| v->len = blkid_rtrim_whitespace(v->data) + 1; |
| if (v->len == 1) |
| blkid_probe_reset_last_value(pr); |
| return 0; |
| } |
| |
| int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label, |
| size_t len, int enc) |
| { |
| struct blkid_chain *chn = blkid_probe_get_chain(pr); |
| struct blkid_prval *v; |
| |
| if ((chn->flags & BLKID_SUBLKS_LABELRAW) && |
| blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0) |
| return -1; |
| if (!(chn->flags & BLKID_SUBLKS_LABEL)) |
| return 0; |
| v = blkid_probe_assign_value(pr, "LABEL"); |
| if (!v) |
| return -1; |
| |
| blkid_encode_to_utf8(enc, v->data, sizeof(v->data), label, len); |
| v->len = blkid_rtrim_whitespace(v->data) + 1; |
| if (v->len == 1) |
| blkid_probe_reset_last_value(pr); |
| return 0; |
| } |
| |
| int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid, |
| size_t len, const char *fmt, ...) |
| { |
| struct blkid_chain *chn = blkid_probe_get_chain(pr); |
| int rc = -1; |
| va_list ap; |
| |
| if (len > BLKID_PROBVAL_BUFSIZ) |
| len = BLKID_PROBVAL_BUFSIZ; |
| |
| if (blkid_uuid_is_empty(uuid, len)) |
| return 0; |
| |
| if ((chn->flags & BLKID_SUBLKS_UUIDRAW) && |
| blkid_probe_set_value(pr, "UUID_RAW", uuid, len) < 0) |
| return -1; |
| if (!(chn->flags & BLKID_SUBLKS_UUID)) |
| return 0; |
| |
| va_start(ap, fmt); |
| rc = blkid_probe_vsprintf_value(pr, "UUID", fmt, ap); |
| va_end(ap); |
| |
| /* convert to lower case (..be paranoid) */ |
| if (!rc) { |
| size_t i; |
| struct blkid_prval *v = __blkid_probe_get_value(pr, |
| blkid_probe_numof_values(pr)); |
| if (v) { |
| for (i = 0; i < v->len; i++) |
| if (v->data[i] >= 'A' && v->data[i] <= 'F') |
| v->data[i] = (v->data[i] - 'A') + 'a'; |
| } |
| } |
| return rc; |
| } |
| |
| /* function to set UUIDs that are in suberblocks stored as strings */ |
| int blkid_probe_strncpy_uuid(blkid_probe pr, unsigned char *str, size_t len) |
| { |
| struct blkid_chain *chn = blkid_probe_get_chain(pr); |
| struct blkid_prval *v; |
| |
| if (str == NULL || *str == '\0') |
| return -1; |
| if (!len) |
| len = strlen((char *) str); |
| if (len > BLKID_PROBVAL_BUFSIZ) |
| len = BLKID_PROBVAL_BUFSIZ; |
| |
| if ((chn->flags & BLKID_SUBLKS_UUIDRAW) && |
| blkid_probe_set_value(pr, "UUID_RAW", str, len) < 0) |
| return -1; |
| if (!(chn->flags & BLKID_SUBLKS_UUID)) |
| return 0; |
| |
| v = blkid_probe_assign_value(pr, "UUID"); |
| if (v) { |
| if (len == BLKID_PROBVAL_BUFSIZ) |
| len--; /* make a space for \0 */ |
| |
| memcpy((char *) v->data, str, len); |
| v->data[len] = '\0'; |
| v->len = len + 1; |
| return 0; |
| } |
| return -1; |
| } |
| |
| /* default _set_uuid function to set DCE UUIDs */ |
| int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *name) |
| { |
| struct blkid_chain *chn = blkid_probe_get_chain(pr); |
| struct blkid_prval *v; |
| |
| if (blkid_uuid_is_empty(uuid, 16)) |
| return 0; |
| |
| if (!name) { |
| if ((chn->flags & BLKID_SUBLKS_UUIDRAW) && |
| blkid_probe_set_value(pr, "UUID_RAW", uuid, 16) < 0) |
| return -1; |
| if (!(chn->flags & BLKID_SUBLKS_UUID)) |
| return 0; |
| |
| v = blkid_probe_assign_value(pr, "UUID"); |
| } else |
| v = blkid_probe_assign_value(pr, name); |
| |
| blkid_unparse_uuid(uuid, (char *) v->data, sizeof(v->data)); |
| v->len = 37; |
| |
| return 0; |
| } |
| |
| int blkid_probe_set_uuid(blkid_probe pr, unsigned char *uuid) |
| { |
| return blkid_probe_set_uuid_as(pr, uuid, NULL); |
| } |
| |
| /** |
| * blkid_probe_set_request: |
| * @pr: probe |
| * @flags: BLKID_PROBREQ_* (deprecated) or BLKID_SUBLKS_* flags |
| * |
| * Returns: 0 on success, or -1 in case of error. |
| * |
| * Deprecated: Use blkid_probe_set_superblocks_flags(). |
| */ |
| int blkid_probe_set_request(blkid_probe pr, int flags) |
| { |
| return blkid_probe_set_superblocks_flags(pr, flags); |
| } |
| |
| /** |
| * blkid_probe_reset_filter: |
| * @pr: prober |
| * |
| * Returns: 0 on success, or -1 in case of error. |
| * |
| * Deprecated: Use blkid_probe_reset_superblocks_filter(). |
| */ |
| int blkid_probe_reset_filter(blkid_probe pr) |
| { |
| return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS); |
| } |
| |
| /** |
| * blkid_probe_invert_filter: |
| * @pr: prober |
| * |
| * Returns: 0 on success, or -1 in case of error. |
| * |
| * Deprecated: Use blkid_probe_invert_superblocks_filter(). |
| */ |
| int blkid_probe_invert_filter(blkid_probe pr) |
| { |
| return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS); |
| } |
| |
| /** |
| * blkid_probe_filter_types |
| * @pr: prober |
| * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag |
| * @names: NULL terminated array of probing function names (e.g. "vfat"). |
| * |
| * Returns: 0 on success, or -1 in case of error. |
| * |
| * Deprecated: Use blkid_probe_filter_superblocks_types(). |
| */ |
| int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[]) |
| { |
| return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names); |
| } |
| |
| /** |
| * blkid_probe_filter_usage |
| * @pr: prober |
| * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag |
| * @usage: BLKID_USAGE_* flags |
| * |
| * Returns: 0 on success, or -1 in case of error. |
| * |
| * Deprecated: Use blkid_probe_filter_superblocks_usage(). |
| */ |
| int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage) |
| { |
| return blkid_probe_filter_superblocks_usage(pr, flag, usage); |
| } |
| |
| |