pmt: e2fsprogs: cleanup
This commit is contained in:
@@ -1,209 +0,0 @@
|
||||
/*
|
||||
* cache.c - allocation/initialization/free routines for cache
|
||||
*
|
||||
* Copyright (C) 2001 Andreas Dilger
|
||||
* Copyright (C) 2003 Theodore Ts'o
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_SYS_PRCTL_H
|
||||
#include <sys/prctl.h>
|
||||
#else
|
||||
#define PR_GET_DUMPABLE 3
|
||||
#endif
|
||||
#if (!defined(HAVE_PRCTL) && defined(linux))
|
||||
#include <sys/syscall.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include "blkidP.h"
|
||||
|
||||
int blkid_debug_mask = 0;
|
||||
|
||||
|
||||
static char *safe_getenv(const char *arg)
|
||||
{
|
||||
if ((getuid() != geteuid()) || (getgid() != getegid()))
|
||||
return NULL;
|
||||
#if HAVE_PRCTL
|
||||
if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
|
||||
return NULL;
|
||||
#else
|
||||
#if (defined(linux) && defined(SYS_prctl))
|
||||
if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
|
||||
return NULL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SECURE_GETENV)
|
||||
return secure_getenv(arg);
|
||||
#elif defined(HAVE___SECURE_GETENV)
|
||||
return __secure_getenv(arg);
|
||||
#else
|
||||
return getenv(arg);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0 /* ifdef CONFIG_BLKID_DEBUG */
|
||||
static blkid_debug_dump_cache(int mask, blkid_cache cache)
|
||||
{
|
||||
struct list_head *p;
|
||||
|
||||
if (!cache) {
|
||||
printf("cache: NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("cache: time = %lu\n", cache->bic_time);
|
||||
printf("cache: flags = 0x%08X\n", cache->bic_flags);
|
||||
|
||||
list_for_each(p, &cache->bic_devs) {
|
||||
blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
|
||||
blkid_debug_dump_dev(dev);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int blkid_get_cache(blkid_cache *ret_cache, const char *filename)
|
||||
{
|
||||
blkid_cache cache;
|
||||
|
||||
#ifdef CONFIG_BLKID_DEBUG
|
||||
if (!(blkid_debug_mask & DEBUG_INIT)) {
|
||||
char *dstr = getenv("BLKID_DEBUG");
|
||||
|
||||
if (dstr)
|
||||
blkid_debug_mask = strtoul(dstr, 0, 0);
|
||||
blkid_debug_mask |= DEBUG_INIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
DBG(DEBUG_CACHE, printf("creating blkid cache (using %s)\n",
|
||||
filename ? filename : "default cache"));
|
||||
|
||||
if (!(cache = (blkid_cache) calloc(1, sizeof(struct blkid_struct_cache))))
|
||||
return -BLKID_ERR_MEM;
|
||||
|
||||
INIT_LIST_HEAD(&cache->bic_devs);
|
||||
INIT_LIST_HEAD(&cache->bic_tags);
|
||||
|
||||
if (filename && !strlen(filename))
|
||||
filename = 0;
|
||||
if (!filename)
|
||||
filename = safe_getenv("BLKID_FILE");
|
||||
if (!filename)
|
||||
filename = BLKID_CACHE_FILE;
|
||||
cache->bic_filename = blkid_strdup(filename);
|
||||
|
||||
blkid_read_cache(cache);
|
||||
|
||||
*ret_cache = cache;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void blkid_put_cache(blkid_cache cache)
|
||||
{
|
||||
if (!cache)
|
||||
return;
|
||||
|
||||
(void) blkid_flush_cache(cache);
|
||||
|
||||
DBG(DEBUG_CACHE, printf("freeing cache struct\n"));
|
||||
|
||||
/* DBG(DEBUG_CACHE, blkid_debug_dump_cache(cache)); */
|
||||
|
||||
while (!list_empty(&cache->bic_devs)) {
|
||||
blkid_dev dev = list_entry(cache->bic_devs.next,
|
||||
struct blkid_struct_dev,
|
||||
bid_devs);
|
||||
blkid_free_dev(dev);
|
||||
}
|
||||
|
||||
while (!list_empty(&cache->bic_tags)) {
|
||||
blkid_tag tag = list_entry(cache->bic_tags.next,
|
||||
struct blkid_struct_tag,
|
||||
bit_tags);
|
||||
|
||||
while (!list_empty(&tag->bit_names)) {
|
||||
blkid_tag bad = list_entry(tag->bit_names.next,
|
||||
struct blkid_struct_tag,
|
||||
bit_names);
|
||||
|
||||
DBG(DEBUG_CACHE, printf("warning: unfreed tag %s=%s\n",
|
||||
bad->bit_name, bad->bit_val));
|
||||
blkid_free_tag(bad);
|
||||
}
|
||||
blkid_free_tag(tag);
|
||||
}
|
||||
free(cache->bic_filename);
|
||||
|
||||
free(cache);
|
||||
}
|
||||
|
||||
void blkid_gc_cache(blkid_cache cache)
|
||||
{
|
||||
struct list_head *p, *pnext;
|
||||
struct stat st;
|
||||
|
||||
if (!cache)
|
||||
return;
|
||||
|
||||
list_for_each_safe(p, pnext, &cache->bic_devs) {
|
||||
blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
|
||||
if (stat(dev->bid_name, &st) < 0) {
|
||||
DBG(DEBUG_CACHE,
|
||||
printf("freeing %s\n", dev->bid_name));
|
||||
blkid_free_dev(dev);
|
||||
cache->bic_flags |= BLKID_BIC_FL_CHANGED;
|
||||
} else {
|
||||
DBG(DEBUG_CACHE,
|
||||
printf("Device %s exists\n", dev->bid_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
blkid_cache cache = NULL;
|
||||
int ret;
|
||||
|
||||
blkid_debug_mask = DEBUG_ALL;
|
||||
if ((argc > 2)) {
|
||||
fprintf(stderr, "Usage: %s [filename] \n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((ret = blkid_get_cache(&cache, argv[1])) < 0) {
|
||||
fprintf(stderr, "error %d parsing cache file %s\n", ret,
|
||||
argv[1] ? argv[1] : BLKID_CACHE_FILE);
|
||||
exit(1);
|
||||
}
|
||||
if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
|
||||
fprintf(stderr, "%s: error creating cache (%d)\n",
|
||||
argv[0], ret);
|
||||
exit(1);
|
||||
}
|
||||
if ((ret = blkid_probe_all(cache) < 0))
|
||||
fprintf(stderr, "error probing devices\n");
|
||||
|
||||
blkid_put_cache(cache);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
Binary file not shown.
@@ -1,254 +0,0 @@
|
||||
/*
|
||||
* dev.c - allocation/initialization/free routines for dev
|
||||
*
|
||||
* Copyright (C) 2001 Andreas Dilger
|
||||
* Copyright (C) 2003 Theodore Ts'o
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "blkidP.h"
|
||||
|
||||
blkid_dev blkid_new_dev(void)
|
||||
{
|
||||
blkid_dev dev;
|
||||
|
||||
if (!(dev = (blkid_dev) calloc(1, sizeof(struct blkid_struct_dev))))
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(&dev->bid_devs);
|
||||
INIT_LIST_HEAD(&dev->bid_tags);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
void blkid_free_dev(blkid_dev dev)
|
||||
{
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
DBG(DEBUG_DEV,
|
||||
printf(" freeing dev %s (%s)\n", dev->bid_name, dev->bid_type ?
|
||||
dev->bid_type : "(null)"));
|
||||
DBG(DEBUG_DEV, blkid_debug_dump_dev(dev));
|
||||
|
||||
list_del(&dev->bid_devs);
|
||||
while (!list_empty(&dev->bid_tags)) {
|
||||
blkid_tag tag = list_entry(dev->bid_tags.next,
|
||||
struct blkid_struct_tag,
|
||||
bit_tags);
|
||||
blkid_free_tag(tag);
|
||||
}
|
||||
free(dev->bid_name);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a blkid device, return its name
|
||||
*/
|
||||
extern const char *blkid_dev_devname(blkid_dev dev)
|
||||
{
|
||||
return dev->bid_name;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLKID_DEBUG
|
||||
void blkid_debug_dump_dev(blkid_dev dev)
|
||||
{
|
||||
struct list_head *p;
|
||||
|
||||
if (!dev) {
|
||||
printf(" dev: NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" dev: name = %s\n", dev->bid_name);
|
||||
printf(" dev: DEVNO=\"0x%0llx\"\n", (long long)dev->bid_devno);
|
||||
printf(" dev: TIME=\"%ld\"\n", (long)dev->bid_time);
|
||||
printf(" dev: PRI=\"%d\"\n", dev->bid_pri);
|
||||
printf(" dev: flags = 0x%08X\n", dev->bid_flags);
|
||||
|
||||
list_for_each(p, &dev->bid_tags) {
|
||||
blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
|
||||
if (tag)
|
||||
printf(" tag: %s=\"%s\"\n", tag->bit_name,
|
||||
tag->bit_val);
|
||||
else
|
||||
printf(" tag: NULL\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dev iteration routines for the public libblkid interface.
|
||||
*
|
||||
* These routines do not expose the list.h implementation, which are a
|
||||
* contamination of the namespace, and which force us to reveal far, far
|
||||
* too much of our internal implementation. I'm not convinced I want
|
||||
* to keep list.h in the long term, anyway. It's fine for kernel
|
||||
* programming, but performance is not the #1 priority for this
|
||||
* library, and I really don't like the tradeoff of type-safety for
|
||||
* performance for this application. [tytso:20030125.2007EST]
|
||||
*/
|
||||
|
||||
/*
|
||||
* This series of functions iterate over all devices in a blkid cache
|
||||
*/
|
||||
#define DEV_ITERATE_MAGIC 0x01a5284c
|
||||
|
||||
struct blkid_struct_dev_iterate {
|
||||
int magic;
|
||||
blkid_cache cache;
|
||||
char *search_type;
|
||||
char *search_value;
|
||||
struct list_head *p;
|
||||
};
|
||||
|
||||
extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache)
|
||||
{
|
||||
blkid_dev_iterate iter;
|
||||
|
||||
iter = malloc(sizeof(struct blkid_struct_dev_iterate));
|
||||
if (iter) {
|
||||
iter->magic = DEV_ITERATE_MAGIC;
|
||||
iter->cache = cache;
|
||||
iter->p = cache->bic_devs.next;
|
||||
iter->search_type = 0;
|
||||
iter->search_value = 0;
|
||||
}
|
||||
return (iter);
|
||||
}
|
||||
|
||||
extern int blkid_dev_set_search(blkid_dev_iterate iter,
|
||||
char *search_type, char *search_value)
|
||||
{
|
||||
char *new_type, *new_value;
|
||||
|
||||
if (!iter || iter->magic != DEV_ITERATE_MAGIC || !search_type ||
|
||||
!search_value)
|
||||
return -1;
|
||||
new_type = malloc(strlen(search_type)+1);
|
||||
new_value = malloc(strlen(search_value)+1);
|
||||
if (!new_type || !new_value) {
|
||||
free(new_type);
|
||||
free(new_value);
|
||||
return -1;
|
||||
}
|
||||
strcpy(new_type, search_type);
|
||||
strcpy(new_value, search_value);
|
||||
free(iter->search_type);
|
||||
free(iter->search_value);
|
||||
iter->search_type = new_type;
|
||||
iter->search_value = new_value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 0 on success, -1 on error
|
||||
*/
|
||||
extern int blkid_dev_next(blkid_dev_iterate iter,
|
||||
blkid_dev *ret_dev)
|
||||
{
|
||||
blkid_dev dev;
|
||||
|
||||
*ret_dev = 0;
|
||||
if (!iter || iter->magic != DEV_ITERATE_MAGIC)
|
||||
return -1;
|
||||
while (iter->p != &iter->cache->bic_devs) {
|
||||
dev = list_entry(iter->p, struct blkid_struct_dev, bid_devs);
|
||||
iter->p = iter->p->next;
|
||||
if (iter->search_type &&
|
||||
!blkid_dev_has_tag(dev, iter->search_type,
|
||||
iter->search_value))
|
||||
continue;
|
||||
*ret_dev = dev;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern void blkid_dev_iterate_end(blkid_dev_iterate iter)
|
||||
{
|
||||
if (!iter || iter->magic != DEV_ITERATE_MAGIC)
|
||||
return;
|
||||
iter->magic = 0;
|
||||
free(iter);
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#else
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
#endif
|
||||
|
||||
void usage(char *prog)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask]\n", prog);
|
||||
fprintf(stderr, "\tList all devices and exit\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
blkid_dev_iterate iter;
|
||||
blkid_cache cache = NULL;
|
||||
blkid_dev dev;
|
||||
int c, ret;
|
||||
char *tmp;
|
||||
char *file = NULL;
|
||||
char *search_type = NULL;
|
||||
char *search_value = NULL;
|
||||
|
||||
while ((c = getopt (argc, argv, "m:f:")) != EOF)
|
||||
switch (c) {
|
||||
case 'f':
|
||||
file = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
blkid_debug_mask = strtoul (optarg, &tmp, 0);
|
||||
if (*tmp) {
|
||||
fprintf(stderr, "Invalid debug mask: %s\n",
|
||||
optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
usage(argv[0]);
|
||||
}
|
||||
if (argc >= optind+2) {
|
||||
search_type = argv[optind];
|
||||
search_value = argv[optind+1];
|
||||
optind += 2;
|
||||
}
|
||||
if (argc != optind)
|
||||
usage(argv[0]);
|
||||
|
||||
if ((ret = blkid_get_cache(&cache, file)) != 0) {
|
||||
fprintf(stderr, "%s: error creating cache (%d)\n",
|
||||
argv[0], ret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
iter = blkid_dev_iterate_begin(cache);
|
||||
if (search_type)
|
||||
blkid_dev_set_search(iter, search_type, search_value);
|
||||
while (blkid_dev_next(iter, &dev) == 0) {
|
||||
printf("Device: %s\n", blkid_dev_devname(dev));
|
||||
}
|
||||
blkid_dev_iterate_end(iter);
|
||||
|
||||
|
||||
blkid_put_cache(cache);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
Binary file not shown.
@@ -1,561 +0,0 @@
|
||||
/*
|
||||
* devname.c - get a dev by its device inode name
|
||||
*
|
||||
* Copyright (C) Andries Brouwer
|
||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003 Theodore Ts'o
|
||||
* Copyright (C) 2001 Andreas Dilger
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <dirent.h>
|
||||
#if HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#if HAVE_SYS_MKDEV_H
|
||||
#include <sys/mkdev.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SYSMACROS_H
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
#include "blkidP.h"
|
||||
|
||||
/*
|
||||
* Find a dev struct in the cache by device name, if available.
|
||||
*
|
||||
* If there is no entry with the specified device name, and the create
|
||||
* flag is set, then create an empty device entry.
|
||||
*/
|
||||
blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags)
|
||||
{
|
||||
blkid_dev dev = NULL, tmp;
|
||||
struct list_head *p, *pnext;
|
||||
|
||||
if (!cache || !devname)
|
||||
return NULL;
|
||||
|
||||
list_for_each(p, &cache->bic_devs) {
|
||||
tmp = list_entry(p, struct blkid_struct_dev, bid_devs);
|
||||
if (strcmp(tmp->bid_name, devname))
|
||||
continue;
|
||||
|
||||
DBG(DEBUG_DEVNAME,
|
||||
printf("found devname %s in cache\n", tmp->bid_name));
|
||||
dev = tmp;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!dev && (flags & BLKID_DEV_CREATE)) {
|
||||
if (access(devname, F_OK) < 0)
|
||||
return NULL;
|
||||
dev = blkid_new_dev();
|
||||
if (!dev)
|
||||
return NULL;
|
||||
dev->bid_time = INT_MIN;
|
||||
dev->bid_name = blkid_strdup(devname);
|
||||
dev->bid_cache = cache;
|
||||
list_add_tail(&dev->bid_devs, &cache->bic_devs);
|
||||
cache->bic_flags |= BLKID_BIC_FL_CHANGED;
|
||||
}
|
||||
|
||||
if (flags & BLKID_DEV_VERIFY) {
|
||||
dev = blkid_verify(cache, dev);
|
||||
if (!dev || !(dev->bid_flags & BLKID_BID_FL_VERIFIED))
|
||||
return dev;
|
||||
/*
|
||||
* If the device is verified, then search the blkid
|
||||
* cache for any entries that match on the type, uuid,
|
||||
* and label, and verify them; if a cache entry can
|
||||
* not be verified, then it's stale and so we remove
|
||||
* it.
|
||||
*/
|
||||
list_for_each_safe(p, pnext, &cache->bic_devs) {
|
||||
blkid_dev dev2;
|
||||
dev2 = list_entry(p, struct blkid_struct_dev, bid_devs);
|
||||
if (dev2->bid_flags & BLKID_BID_FL_VERIFIED)
|
||||
continue;
|
||||
if (!dev->bid_type || !dev2->bid_type ||
|
||||
strcmp(dev->bid_type, dev2->bid_type))
|
||||
continue;
|
||||
if (dev->bid_label && dev2->bid_label &&
|
||||
strcmp(dev->bid_label, dev2->bid_label))
|
||||
continue;
|
||||
if (dev->bid_uuid && dev2->bid_uuid &&
|
||||
strcmp(dev->bid_uuid, dev2->bid_uuid))
|
||||
continue;
|
||||
if ((dev->bid_label && !dev2->bid_label) ||
|
||||
(!dev->bid_label && dev2->bid_label) ||
|
||||
(dev->bid_uuid && !dev2->bid_uuid) ||
|
||||
(!dev->bid_uuid && dev2->bid_uuid))
|
||||
continue;
|
||||
dev2 = blkid_verify(cache, dev2);
|
||||
if (dev2 && !(dev2->bid_flags & BLKID_BID_FL_VERIFIED))
|
||||
blkid_free_dev(dev2);
|
||||
}
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
|
||||
/* Directories where we will try to search for device names */
|
||||
static const char *dirlist[] = { "/dev", "/devfs", "/devices", NULL };
|
||||
|
||||
static int is_dm_leaf(const char *devname)
|
||||
{
|
||||
struct dirent *de, *d_de;
|
||||
DIR *dir, *d_dir;
|
||||
char path[300];
|
||||
int ret = 1;
|
||||
|
||||
if ((dir = opendir("/sys/block")) == NULL)
|
||||
return 0;
|
||||
while ((de = readdir(dir)) != NULL) {
|
||||
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") ||
|
||||
!strcmp(de->d_name, devname) ||
|
||||
strncmp(de->d_name, "dm-", 3) ||
|
||||
strlen(de->d_name) > sizeof(path)-32)
|
||||
continue;
|
||||
sprintf(path, "/sys/block/%s/slaves", de->d_name);
|
||||
if ((d_dir = opendir(path)) == NULL)
|
||||
continue;
|
||||
while ((d_de = readdir(d_dir)) != NULL) {
|
||||
if (!strcmp(d_de->d_name, devname)) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
closedir(d_dir);
|
||||
if (!ret)
|
||||
break;
|
||||
}
|
||||
closedir(dir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs
|
||||
* provides the real DM device names in /sys/block/<ptname>/dm/name
|
||||
*/
|
||||
static char *get_dm_name(const char *ptname)
|
||||
{
|
||||
FILE *f;
|
||||
size_t sz;
|
||||
char path[300], name[256], *res = NULL;
|
||||
|
||||
snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname);
|
||||
if ((f = fopen(path, "r")) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* read "<name>\n" from sysfs */
|
||||
if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) {
|
||||
name[sz - 1] = '\0';
|
||||
snprintf(path, sizeof(path), "/dev/mapper/%s", name);
|
||||
res = blkid_strdup(path);
|
||||
}
|
||||
fclose(f);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe a single block device to add to the device cache.
|
||||
*/
|
||||
static void probe_one(blkid_cache cache, const char *ptname,
|
||||
dev_t devno, int pri, int only_if_new)
|
||||
{
|
||||
blkid_dev dev = NULL;
|
||||
struct list_head *p, *pnext;
|
||||
const char **dir;
|
||||
char *devname = NULL;
|
||||
|
||||
/* See if we already have this device number in the cache. */
|
||||
list_for_each_safe(p, pnext, &cache->bic_devs) {
|
||||
blkid_dev tmp = list_entry(p, struct blkid_struct_dev,
|
||||
bid_devs);
|
||||
if (tmp->bid_devno == devno) {
|
||||
if (only_if_new && !access(tmp->bid_name, F_OK))
|
||||
return;
|
||||
dev = blkid_verify(cache, tmp);
|
||||
if (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED))
|
||||
break;
|
||||
dev = 0;
|
||||
}
|
||||
}
|
||||
if (dev && dev->bid_devno == devno)
|
||||
goto set_pri;
|
||||
|
||||
/* Try to translate private device-mapper dm-<N> names
|
||||
* to standard /dev/mapper/<name>.
|
||||
*/
|
||||
if (!strncmp(ptname, "dm-", 3) && isdigit(ptname[3])) {
|
||||
devname = get_dm_name(ptname);
|
||||
if (!devname)
|
||||
blkid__scan_dir("/dev/mapper", devno, 0, &devname);
|
||||
if (devname)
|
||||
goto get_dev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Take a quick look at /dev/ptname for the device number. We check
|
||||
* all of the likely device directories. If we don't find it, or if
|
||||
* the stat information doesn't check out, use blkid_devno_to_devname()
|
||||
* to find it via an exhaustive search for the device major/minor.
|
||||
*/
|
||||
for (dir = dirlist; *dir; dir++) {
|
||||
struct stat st;
|
||||
char device[256];
|
||||
|
||||
sprintf(device, "%s/%s", *dir, ptname);
|
||||
if ((dev = blkid_get_dev(cache, device, BLKID_DEV_FIND)) &&
|
||||
dev->bid_devno == devno)
|
||||
goto set_pri;
|
||||
|
||||
if (stat(device, &st) == 0 &&
|
||||
blkidP_is_disk_device(st.st_mode) &&
|
||||
st.st_rdev == devno) {
|
||||
devname = blkid_strdup(device);
|
||||
goto get_dev;
|
||||
}
|
||||
}
|
||||
/* Do a short-cut scan of /dev/mapper first */
|
||||
if (!devname)
|
||||
devname = get_dm_name(ptname);
|
||||
if (!devname)
|
||||
blkid__scan_dir("/dev/mapper", devno, 0, &devname);
|
||||
if (!devname) {
|
||||
devname = blkid_devno_to_devname(devno);
|
||||
if (!devname)
|
||||
return;
|
||||
}
|
||||
get_dev:
|
||||
dev = blkid_get_dev(cache, devname, BLKID_DEV_NORMAL);
|
||||
free(devname);
|
||||
set_pri:
|
||||
if (dev) {
|
||||
if (pri)
|
||||
dev->bid_pri = pri;
|
||||
else if (!strncmp(dev->bid_name, "/dev/mapper/", 11)) {
|
||||
dev->bid_pri = BLKID_PRI_DM;
|
||||
if (is_dm_leaf(ptname))
|
||||
dev->bid_pri += 5;
|
||||
} else if (!strncmp(ptname, "md", 2))
|
||||
dev->bid_pri = BLKID_PRI_MD;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#define PROC_PARTITIONS "/proc/partitions"
|
||||
#define VG_DIR "/proc/lvm/VGs"
|
||||
|
||||
/*
|
||||
* This function initializes the UUID cache with devices from the LVM
|
||||
* proc hierarchy. We currently depend on the names of the LVM
|
||||
* hierarchy giving us the device structure in /dev. (XXX is this a
|
||||
* safe thing to do?)
|
||||
*/
|
||||
#ifdef VG_DIR
|
||||
static dev_t lvm_get_devno(const char *lvm_device)
|
||||
{
|
||||
FILE *lvf;
|
||||
char buf[1024];
|
||||
int ma, mi;
|
||||
dev_t ret = 0;
|
||||
|
||||
DBG(DEBUG_DEVNAME, printf("opening %s\n", lvm_device));
|
||||
if ((lvf = fopen(lvm_device, "r")) == NULL) {
|
||||
DBG(DEBUG_DEVNAME, printf("%s: (%d) %s\n", lvm_device, errno,
|
||||
strerror(errno)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (fgets(buf, sizeof(buf), lvf)) {
|
||||
if (sscanf(buf, "device: %d:%d", &ma, &mi) == 2) {
|
||||
ret = makedev(ma, mi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(lvf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lvm_probe_all(blkid_cache cache, int only_if_new)
|
||||
{
|
||||
DIR *vg_list;
|
||||
struct dirent *vg_iter;
|
||||
int vg_len = strlen(VG_DIR);
|
||||
dev_t dev;
|
||||
|
||||
if ((vg_list = opendir(VG_DIR)) == NULL)
|
||||
return;
|
||||
|
||||
DBG(DEBUG_DEVNAME, printf("probing LVM devices under %s\n", VG_DIR));
|
||||
|
||||
while ((vg_iter = readdir(vg_list)) != NULL) {
|
||||
DIR *lv_list;
|
||||
char *vdirname;
|
||||
char *vg_name;
|
||||
struct dirent *lv_iter;
|
||||
|
||||
vg_name = vg_iter->d_name;
|
||||
if (!strcmp(vg_name, ".") || !strcmp(vg_name, ".."))
|
||||
continue;
|
||||
vdirname = malloc(vg_len + strlen(vg_name) + 8);
|
||||
if (!vdirname)
|
||||
goto exit;
|
||||
sprintf(vdirname, "%s/%s/LVs", VG_DIR, vg_name);
|
||||
|
||||
lv_list = opendir(vdirname);
|
||||
free(vdirname);
|
||||
if (lv_list == NULL)
|
||||
continue;
|
||||
|
||||
while ((lv_iter = readdir(lv_list)) != NULL) {
|
||||
char *lv_name, *lvm_device;
|
||||
|
||||
lv_name = lv_iter->d_name;
|
||||
if (!strcmp(lv_name, ".") || !strcmp(lv_name, ".."))
|
||||
continue;
|
||||
|
||||
lvm_device = malloc(vg_len + strlen(vg_name) +
|
||||
strlen(lv_name) + 8);
|
||||
if (!lvm_device) {
|
||||
closedir(lv_list);
|
||||
goto exit;
|
||||
}
|
||||
sprintf(lvm_device, "%s/%s/LVs/%s", VG_DIR, vg_name,
|
||||
lv_name);
|
||||
dev = lvm_get_devno(lvm_device);
|
||||
sprintf(lvm_device, "%s/%s", vg_name, lv_name);
|
||||
DBG(DEBUG_DEVNAME, printf("LVM dev %s: devno 0x%04X\n",
|
||||
lvm_device,
|
||||
(unsigned int) dev));
|
||||
probe_one(cache, lvm_device, dev, BLKID_PRI_LVM,
|
||||
only_if_new);
|
||||
free(lvm_device);
|
||||
}
|
||||
closedir(lv_list);
|
||||
}
|
||||
exit:
|
||||
closedir(vg_list);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define PROC_EVMS_VOLUMES "/proc/evms/volumes"
|
||||
|
||||
static int
|
||||
evms_probe_all(blkid_cache cache, int only_if_new)
|
||||
{
|
||||
char line[100];
|
||||
int ma, mi, sz, num = 0;
|
||||
FILE *procpt;
|
||||
char device[110];
|
||||
|
||||
procpt = fopen(PROC_EVMS_VOLUMES, "r");
|
||||
if (!procpt)
|
||||
return 0;
|
||||
while (fgets(line, sizeof(line), procpt)) {
|
||||
if (sscanf (line, " %d %d %d %*s %*s %[^\n ]",
|
||||
&ma, &mi, &sz, device) != 4)
|
||||
continue;
|
||||
|
||||
DBG(DEBUG_DEVNAME, printf("Checking partition %s (%d, %d)\n",
|
||||
device, ma, mi));
|
||||
|
||||
probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS,
|
||||
only_if_new);
|
||||
num++;
|
||||
}
|
||||
fclose(procpt);
|
||||
return num;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the device data for all available block devices in the system.
|
||||
*/
|
||||
static int probe_all(blkid_cache cache, int only_if_new)
|
||||
{
|
||||
FILE *proc;
|
||||
char line[1024];
|
||||
char ptname0[129], ptname1[129], *ptname = 0;
|
||||
char *ptnames[2];
|
||||
dev_t devs[2];
|
||||
int ma, mi;
|
||||
unsigned long long sz;
|
||||
int lens[2] = { 0, 0 };
|
||||
int which = 0, last = 0;
|
||||
struct list_head *p, *pnext;
|
||||
|
||||
ptnames[0] = ptname0;
|
||||
ptnames[1] = ptname1;
|
||||
|
||||
if (!cache)
|
||||
return -BLKID_ERR_PARAM;
|
||||
|
||||
if (cache->bic_flags & BLKID_BIC_FL_PROBED &&
|
||||
time(0) - cache->bic_time < BLKID_PROBE_INTERVAL)
|
||||
return 0;
|
||||
|
||||
blkid_read_cache(cache);
|
||||
evms_probe_all(cache, only_if_new);
|
||||
#ifdef VG_DIR
|
||||
lvm_probe_all(cache, only_if_new);
|
||||
#endif
|
||||
|
||||
proc = fopen(PROC_PARTITIONS, "r");
|
||||
if (!proc)
|
||||
return -BLKID_ERR_PROC;
|
||||
|
||||
while (fgets(line, sizeof(line), proc)) {
|
||||
last = which;
|
||||
which ^= 1;
|
||||
ptname = ptnames[which];
|
||||
|
||||
if (sscanf(line, " %d %d %llu %128[^\n ]",
|
||||
&ma, &mi, &sz, ptname) != 4)
|
||||
continue;
|
||||
devs[which] = makedev(ma, mi);
|
||||
|
||||
DBG(DEBUG_DEVNAME, printf("read partition name %s\n", ptname));
|
||||
|
||||
/* Skip whole disk devs unless they have no partitions.
|
||||
* If base name of device has changed, also
|
||||
* check previous dev to see if it didn't have a partn.
|
||||
* heuristic: partition name ends in a digit, & partition
|
||||
* names contain whole device name as substring.
|
||||
*
|
||||
* Skip extended partitions.
|
||||
* heuristic: size is 1
|
||||
*
|
||||
* FIXME: skip /dev/{ida,cciss,rd} whole-disk devs
|
||||
*/
|
||||
|
||||
lens[which] = strlen(ptname);
|
||||
|
||||
/* ends in a digit, clearly a partition, so check */
|
||||
if (isdigit(ptname[lens[which] - 1])) {
|
||||
DBG(DEBUG_DEVNAME,
|
||||
printf("partition dev %s, devno 0x%04X\n",
|
||||
ptname, (unsigned int) devs[which]));
|
||||
|
||||
if (sz > 1)
|
||||
probe_one(cache, ptname, devs[which], 0,
|
||||
only_if_new);
|
||||
lens[which] = 0; /* mark as checked */
|
||||
}
|
||||
|
||||
/*
|
||||
* If last was a whole disk and we just found a partition
|
||||
* on it, remove the whole-disk dev from the cache if
|
||||
* it exists.
|
||||
*/
|
||||
if (lens[last] && !strncmp(ptnames[last], ptname, lens[last])) {
|
||||
list_for_each_safe(p, pnext, &cache->bic_devs) {
|
||||
blkid_dev tmp;
|
||||
|
||||
/* find blkid dev for the whole-disk devno */
|
||||
tmp = list_entry(p, struct blkid_struct_dev,
|
||||
bid_devs);
|
||||
if (tmp->bid_devno == devs[last]) {
|
||||
DBG(DEBUG_DEVNAME,
|
||||
printf("freeing %s\n",
|
||||
tmp->bid_name));
|
||||
blkid_free_dev(tmp);
|
||||
cache->bic_flags |= BLKID_BIC_FL_CHANGED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lens[last] = 0;
|
||||
}
|
||||
/*
|
||||
* If last was not checked because it looked like a whole-disk
|
||||
* dev, and the device's base name has changed,
|
||||
* check last as well.
|
||||
*/
|
||||
if (lens[last] && strncmp(ptnames[last], ptname, lens[last])) {
|
||||
DBG(DEBUG_DEVNAME,
|
||||
printf("whole dev %s, devno 0x%04X\n",
|
||||
ptnames[last], (unsigned int) devs[last]));
|
||||
probe_one(cache, ptnames[last], devs[last], 0,
|
||||
only_if_new);
|
||||
lens[last] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle the last device if it wasn't partitioned */
|
||||
if (lens[which])
|
||||
probe_one(cache, ptname, devs[which], 0, only_if_new);
|
||||
|
||||
fclose(proc);
|
||||
blkid_flush_cache(cache);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blkid_probe_all(blkid_cache cache)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBG(DEBUG_PROBE, printf("Begin blkid_probe_all()\n"));
|
||||
ret = probe_all(cache, 0);
|
||||
cache->bic_time = time(0);
|
||||
cache->bic_flags |= BLKID_BIC_FL_PROBED;
|
||||
DBG(DEBUG_PROBE, printf("End blkid_probe_all()\n"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int blkid_probe_all_new(blkid_cache cache)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBG(DEBUG_PROBE, printf("Begin blkid_probe_all_new()\n"));
|
||||
ret = probe_all(cache, 1);
|
||||
DBG(DEBUG_PROBE, printf("End blkid_probe_all_new()\n"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
blkid_cache cache = NULL;
|
||||
int ret;
|
||||
|
||||
blkid_debug_mask = DEBUG_ALL;
|
||||
if (argc != 1) {
|
||||
fprintf(stderr, "Usage: %s\n"
|
||||
"Probe all devices and exit\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
|
||||
fprintf(stderr, "%s: error creating cache (%d)\n",
|
||||
argv[0], ret);
|
||||
exit(1);
|
||||
}
|
||||
if (blkid_probe_all(cache) < 0)
|
||||
printf("%s: error probing devices\n", argv[0]);
|
||||
|
||||
blkid_put_cache(cache);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
Binary file not shown.
@@ -1,242 +0,0 @@
|
||||
/*
|
||||
* devno.c - find a particular device by its device number (major/minor)
|
||||
*
|
||||
* Copyright (C) 2000, 2001, 2003 Theodore Ts'o
|
||||
* Copyright (C) 2001 Andreas Dilger
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <dirent.h>
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#if HAVE_SYS_MKDEV_H
|
||||
#include <sys/mkdev.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SYSMACROS_H
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
#include "blkidP.h"
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 8
|
||||
/* gcc incorrectly thinks the destination string is not being null-terminated */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-truncation"
|
||||
#endif
|
||||
|
||||
char *blkid_strndup(const char *s, int length)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
if (!length)
|
||||
length = strlen(s);
|
||||
|
||||
ret = malloc(length + 1);
|
||||
if (ret) {
|
||||
strncpy(ret, s, length);
|
||||
ret[length] = '\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 8
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
char *blkid_strdup(const char *s)
|
||||
{
|
||||
return blkid_strndup(s, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function adds an entry to the directory list
|
||||
*/
|
||||
static void add_to_dirlist(const char *name, struct dir_list **list)
|
||||
{
|
||||
struct dir_list *dp;
|
||||
|
||||
dp = malloc(sizeof(struct dir_list));
|
||||
if (!dp)
|
||||
return;
|
||||
dp->name = blkid_strdup(name);
|
||||
if (!dp->name) {
|
||||
free(dp);
|
||||
return;
|
||||
}
|
||||
dp->next = *list;
|
||||
*list = dp;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function frees a directory list
|
||||
*/
|
||||
static void free_dirlist(struct dir_list **list)
|
||||
{
|
||||
struct dir_list *dp, *next;
|
||||
|
||||
for (dp = *list; dp; dp = next) {
|
||||
next = dp->next;
|
||||
free(dp->name);
|
||||
free(dp);
|
||||
}
|
||||
*list = NULL;
|
||||
}
|
||||
|
||||
void blkid__scan_dir(const char *dirname, dev_t devno, struct dir_list **list,
|
||||
char **devname)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *dp;
|
||||
char path[1024];
|
||||
int dirlen;
|
||||
struct stat st;
|
||||
|
||||
if ((dir = opendir(dirname)) == NULL)
|
||||
return;
|
||||
dirlen = strlen(dirname) + 2;
|
||||
while ((dp = readdir(dir)) != 0) {
|
||||
if (dirlen + strlen(dp->d_name) >= sizeof(path))
|
||||
continue;
|
||||
|
||||
if (dp->d_name[0] == '.' &&
|
||||
((dp->d_name[1] == 0) ||
|
||||
((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
|
||||
continue;
|
||||
|
||||
sprintf(path, "%s/%s", dirname, dp->d_name);
|
||||
if (stat(path, &st) < 0)
|
||||
continue;
|
||||
|
||||
if (blkidP_is_disk_device(st.st_mode) && st.st_rdev == devno) {
|
||||
*devname = blkid_strdup(path);
|
||||
DBG(DEBUG_DEVNO,
|
||||
printf("found 0x%llx at %s (%p)\n", (long long)devno,
|
||||
path, *devname));
|
||||
break;
|
||||
}
|
||||
if (list && S_ISDIR(st.st_mode) && !lstat(path, &st) &&
|
||||
S_ISDIR(st.st_mode))
|
||||
add_to_dirlist(path, list);
|
||||
}
|
||||
closedir(dir);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Directories where we will try to search for device numbers */
|
||||
static const char *devdirs[] = { "/devices", "/devfs", "/dev", NULL };
|
||||
|
||||
/*
|
||||
* This function finds the pathname to a block device with a given
|
||||
* device number. It returns a pointer to allocated memory to the
|
||||
* pathname on success, and NULL on failure.
|
||||
*/
|
||||
char *blkid_devno_to_devname(dev_t devno)
|
||||
{
|
||||
struct dir_list *list = NULL, *new_list = NULL;
|
||||
char *devname = NULL;
|
||||
const char **dir;
|
||||
|
||||
/*
|
||||
* Add the starting directories to search in reverse order of
|
||||
* importance, since we are using a stack...
|
||||
*/
|
||||
for (dir = devdirs; *dir; dir++)
|
||||
add_to_dirlist(*dir, &list);
|
||||
|
||||
while (list) {
|
||||
struct dir_list *current = list;
|
||||
|
||||
list = list->next;
|
||||
DBG(DEBUG_DEVNO, printf("directory %s\n", current->name));
|
||||
blkid__scan_dir(current->name, devno, &new_list, &devname);
|
||||
free(current->name);
|
||||
free(current);
|
||||
if (devname)
|
||||
break;
|
||||
/*
|
||||
* If we're done checking at this level, descend to
|
||||
* the next level of subdirectories. (breadth-first)
|
||||
*/
|
||||
if (list == NULL) {
|
||||
list = new_list;
|
||||
new_list = NULL;
|
||||
}
|
||||
}
|
||||
free_dirlist(&list);
|
||||
free_dirlist(&new_list);
|
||||
|
||||
if (!devname) {
|
||||
DBG(DEBUG_DEVNO,
|
||||
printf("blkid: couldn't find devno 0x%04lx\n",
|
||||
(unsigned long) devno));
|
||||
} else {
|
||||
DBG(DEBUG_DEVNO,
|
||||
printf("found devno 0x%04llx as %s\n", (long long)devno, devname));
|
||||
}
|
||||
|
||||
|
||||
return devname;
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
char *devname, *tmp;
|
||||
int major, minor;
|
||||
dev_t devno;
|
||||
const char *errmsg = "Couldn't parse %s: %s\n";
|
||||
|
||||
blkid_debug_mask = DEBUG_ALL;
|
||||
if ((argc != 2) && (argc != 3)) {
|
||||
fprintf(stderr, "Usage:\t%s device_number\n\t%s major minor\n"
|
||||
"Resolve a device number to a device name\n",
|
||||
argv[0], argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if (argc == 2) {
|
||||
devno = strtoul(argv[1], &tmp, 0);
|
||||
if (*tmp) {
|
||||
fprintf(stderr, errmsg, "device number", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
major = strtoul(argv[1], &tmp, 0);
|
||||
if (*tmp) {
|
||||
fprintf(stderr, errmsg, "major number", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
minor = strtoul(argv[2], &tmp, 0);
|
||||
if (*tmp) {
|
||||
fprintf(stderr, errmsg, "minor number", argv[2]);
|
||||
exit(1);
|
||||
}
|
||||
devno = makedev(major, minor);
|
||||
}
|
||||
printf("Looking for device 0x%04llx\n", (long long)devno);
|
||||
devname = blkid_devno_to_devname(devno);
|
||||
free(devname);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
Binary file not shown.
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
* getsize.c --- get the size of a partition.
|
||||
*
|
||||
* Copyright (C) 1995, 1995 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#ifndef _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE_SOURCE
|
||||
#endif
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "blkidP.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_LINUX_FD_H
|
||||
#include <linux/fd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_DISKLABEL_H
|
||||
#include <sys/disklabel.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_DISK_H
|
||||
#include <sys/disk.h>
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
#if HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
|
||||
#define BLKGETSIZE _IO(0x12,96) /* return device size */
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
|
||||
#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */
|
||||
#endif
|
||||
|
||||
#ifdef APPLE_DARWIN
|
||||
#define BLKGETSIZE DKIOCGETBLOCKCOUNT32
|
||||
#endif /* APPLE_DARWIN */
|
||||
|
||||
static int valid_offset(int fd, blkid_loff_t offset)
|
||||
{
|
||||
char ch;
|
||||
|
||||
if (blkid_llseek(fd, offset, 0) < 0)
|
||||
return 0;
|
||||
if (read(fd, &ch, 1) < 1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the number of bytes in a partition
|
||||
*/
|
||||
blkid_loff_t blkid_get_dev_size(int fd)
|
||||
{
|
||||
unsigned long long size64 __BLKID_ATTR((unused));
|
||||
blkid_loff_t high, low;
|
||||
|
||||
#if defined DKIOCGETBLOCKCOUNT && defined DKIOCGETBLOCKSIZE /* For Apple Darwin */
|
||||
unsigned int size;
|
||||
|
||||
if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0 &&
|
||||
ioctl(fd, DKIOCGETBLOCKSIZE, &size) >= 0) {
|
||||
if (sizeof(blkid_loff_t) < sizeof(unsigned long long) &&
|
||||
(size64 * size) > 0xFFFFFFFF)
|
||||
return 0; /* EFBIG */
|
||||
return (blkid_loff_t)size64 * size;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BLKGETSIZE64
|
||||
{
|
||||
int valid_blkgetsize64 = 1;
|
||||
#ifdef __linux__
|
||||
struct utsname ut;
|
||||
|
||||
if ((uname(&ut) == 0) &&
|
||||
((ut.release[0] == '2') && (ut.release[1] == '.') &&
|
||||
(ut.release[2] < '6') && (ut.release[3] == '.')))
|
||||
valid_blkgetsize64 = 0;
|
||||
#endif
|
||||
if (valid_blkgetsize64 &&
|
||||
ioctl(fd, BLKGETSIZE64, &size64) >= 0) {
|
||||
if (sizeof(blkid_loff_t) < sizeof(unsigned long long) &&
|
||||
(size64 > 0xFFFFFFFF))
|
||||
return 0; /* EFBIG */
|
||||
return size64;
|
||||
}
|
||||
}
|
||||
#endif /* BLKGETSIZE64 */
|
||||
|
||||
#ifdef BLKGETSIZE
|
||||
{
|
||||
unsigned long size;
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE, &size) >= 0)
|
||||
return (blkid_loff_t)size << 9;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* tested on FreeBSD 6.1-RELEASE i386 */
|
||||
#ifdef DIOCGMEDIASIZE
|
||||
if (ioctl(fd, DIOCGMEDIASIZE, &size64) >= 0)
|
||||
return (off_t)size64;
|
||||
#endif /* DIOCGMEDIASIZE */
|
||||
|
||||
#ifdef FDGETPRM
|
||||
{
|
||||
struct floppy_struct this_floppy;
|
||||
|
||||
if (ioctl(fd, FDGETPRM, &this_floppy) >= 0)
|
||||
return (blkid_loff_t)this_floppy.size << 9;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_SYS_DISKLABEL_H) && defined(DIOCGDINFO)
|
||||
{
|
||||
int part = -1;
|
||||
struct disklabel lab;
|
||||
struct partition *pp;
|
||||
char ch;
|
||||
struct stat st;
|
||||
|
||||
/*
|
||||
* This code works for FreeBSD 4.11 i386, except for the full
|
||||
* device (such as /dev/ad0). It doesn't work properly for
|
||||
* newer FreeBSD though. FreeBSD >= 5.0 should be covered by
|
||||
* the DIOCGMEDIASIZE above however.
|
||||
*
|
||||
* Note that FreeBSD >= 4.0 has disk devices as unbuffered (raw,
|
||||
* character) devices, so we need to check for S_ISCHR, too.
|
||||
*/
|
||||
if (fstat(fd, &st) >= 0 &&
|
||||
blkidP_is_disk_device(st.st_mode))
|
||||
part = st.st_rdev & 7;
|
||||
|
||||
if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
|
||||
pp = &lab.d_partitions[part];
|
||||
if (pp->p_size)
|
||||
return pp->p_size << 9;
|
||||
}
|
||||
}
|
||||
#endif /* defined(HAVE_SYS_DISKLABEL_H) && defined(DIOCGDINFO) */
|
||||
{
|
||||
#if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
|
||||
struct stat64 st;
|
||||
if (fstat64(fd, &st) == 0)
|
||||
#else
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == 0)
|
||||
#endif
|
||||
if (S_ISREG(st.st_mode))
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, we couldn't figure it out by using a specialized ioctl,
|
||||
* which is generally the best way. So do binary search to
|
||||
* find the size of the partition.
|
||||
*/
|
||||
low = 0;
|
||||
for (high = 1024; valid_offset(fd, high); high *= 2)
|
||||
low = high;
|
||||
while (low < high - 1) {
|
||||
const blkid_loff_t mid = (low + high) / 2;
|
||||
|
||||
if (valid_offset(fd, mid))
|
||||
low = mid;
|
||||
else
|
||||
high = mid;
|
||||
}
|
||||
return low + 1;
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
long long bytes;
|
||||
int fd;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s device\n"
|
||||
"Determine the size of a device\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((fd = open(argv[1], O_RDONLY)) < 0)
|
||||
perror(argv[0]);
|
||||
|
||||
bytes = blkid_get_dev_size(fd);
|
||||
printf("Device %s has %lld 1k blocks.\n", argv[1],
|
||||
(unsigned long long)bytes >> 10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
Binary file not shown.
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* llseek.c -- stub calling the llseek system call
|
||||
*
|
||||
* Copyright (C) 1994, 1995, 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#ifndef _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE_SOURCE
|
||||
#endif
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef __MSDOS__
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include "blkidP.h"
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE)
|
||||
|
||||
#define my_llseek lseek64
|
||||
|
||||
#elif defined(HAVE_LLSEEK)
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#ifndef HAVE_LLSEEK_PROTOTYPE
|
||||
extern long long llseek(int fd, long long offset, int origin);
|
||||
#endif
|
||||
|
||||
#define my_llseek llseek
|
||||
|
||||
#else /* ! HAVE_LLSEEK */
|
||||
|
||||
#if SIZEOF_LONG == SIZEOF_LONG_LONG
|
||||
|
||||
#define llseek lseek
|
||||
|
||||
#else /* SIZEOF_LONG != SIZEOF_LONG_LONG */
|
||||
|
||||
#include <linux/unistd.h>
|
||||
|
||||
#ifndef __NR__llseek
|
||||
#define __NR__llseek 140
|
||||
#endif
|
||||
|
||||
#ifndef __i386__
|
||||
static int _llseek(unsigned int, unsigned long, unsigned long,
|
||||
blkid_loff_t *, unsigned int);
|
||||
|
||||
static _syscall5(int, _llseek, unsigned int, fd, unsigned long, offset_high,
|
||||
unsigned long, offset_low, blkid_loff_t *, result,
|
||||
unsigned int, origin)
|
||||
#endif
|
||||
|
||||
static blkid_loff_t my_llseek(int fd, blkid_loff_t offset, int origin)
|
||||
{
|
||||
blkid_loff_t result;
|
||||
int retval;
|
||||
|
||||
#ifndef __i386__
|
||||
retval = _llseek(fd, ((unsigned long long) offset) >> 32,
|
||||
((unsigned long long)offset) & 0xffffffff,
|
||||
&result, origin);
|
||||
#else
|
||||
retval = syscall(__NR__llseek, fd, ((unsigned long long) offset) >> 32,
|
||||
((unsigned long long)offset) & 0xffffffff,
|
||||
&result, origin);
|
||||
#endif
|
||||
return (retval == -1 ? (blkid_loff_t) retval : result);
|
||||
}
|
||||
|
||||
#endif /* __alpha__ || __ia64__ */
|
||||
|
||||
#endif /* HAVE_LLSEEK */
|
||||
|
||||
blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence)
|
||||
{
|
||||
blkid_loff_t result;
|
||||
static int do_compat = 0;
|
||||
|
||||
if ((sizeof(off_t) >= sizeof(blkid_loff_t)) ||
|
||||
(offset < ((blkid_loff_t) 1 << ((sizeof(off_t)*8) -1))))
|
||||
return lseek(fd, (off_t) offset, whence);
|
||||
|
||||
if (do_compat) {
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = my_llseek(fd, offset, whence);
|
||||
if (result == -1 && errno == ENOSYS) {
|
||||
/*
|
||||
* Just in case this code runs on top of an old kernel
|
||||
* which does not support the llseek system call
|
||||
*/
|
||||
do_compat++;
|
||||
errno = EOVERFLOW;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#else /* !linux */
|
||||
|
||||
#ifndef EOVERFLOW
|
||||
#ifdef EXT2_ET_INVALID_ARGUMENT
|
||||
#define EOVERFLOW EXT2_ET_INVALID_ARGUMENT
|
||||
#else
|
||||
#define EOVERFLOW 112
|
||||
#endif
|
||||
#endif
|
||||
|
||||
blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int origin)
|
||||
{
|
||||
#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE)
|
||||
return lseek64 (fd, offset, origin);
|
||||
#else
|
||||
if ((sizeof(off_t) < sizeof(blkid_loff_t)) &&
|
||||
(offset >= ((blkid_loff_t) 1 << ((sizeof(off_t)*8) - 1)))) {
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
return lseek(fd, (off_t) offset, origin);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* linux */
|
||||
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,494 +0,0 @@
|
||||
/*
|
||||
* read.c - read the blkid cache from disk, to avoid scanning all devices
|
||||
*
|
||||
* Copyright (C) 2001, 2003 Theodore Y. Ts'o
|
||||
* Copyright (C) 2001 Andreas Dilger
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 600 /* for inclusion of strtoull */
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "blkidP.h"
|
||||
#include "uuid/uuid.h"
|
||||
|
||||
#ifdef HAVE_STRTOULL
|
||||
#define STRTOULL strtoull /* defined in stdlib.h if you try hard enough */
|
||||
#else
|
||||
/* FIXME: need to support real strtoull here */
|
||||
#define STRTOULL strtoul
|
||||
#endif
|
||||
|
||||
#if HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
#define blkid_debug_dump_dev(dev) (debug_dump_dev(dev))
|
||||
static void debug_dump_dev(blkid_dev dev);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* File format:
|
||||
*
|
||||
* <device [<NAME="value"> ...]>device_name</device>
|
||||
*
|
||||
* The following tags are required for each entry:
|
||||
* <ID="id"> unique (within this file) ID number of this device
|
||||
* <TIME="time"> (ascii time_t) time this entry was last read from disk
|
||||
* <TYPE="type"> (detected) type of filesystem/data for this partition
|
||||
*
|
||||
* The following tags may be present, depending on the device contents
|
||||
* <LABEL="label"> (user supplied) label (volume name, etc)
|
||||
* <UUID="uuid"> (generated) universally unique identifier (serial no)
|
||||
*/
|
||||
|
||||
static char *skip_over_blank(char *cp)
|
||||
{
|
||||
while (*cp && isspace(*cp))
|
||||
cp++;
|
||||
return cp;
|
||||
}
|
||||
|
||||
static char *skip_over_word(char *cp)
|
||||
{
|
||||
char ch;
|
||||
|
||||
while ((ch = *cp)) {
|
||||
/* If we see a backslash, skip the next character */
|
||||
if (ch == '\\') {
|
||||
cp++;
|
||||
if (*cp == '\0')
|
||||
break;
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (isspace(ch) || ch == '<' || ch == '>')
|
||||
break;
|
||||
cp++;
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
|
||||
static char *strip_line(char *line)
|
||||
{
|
||||
char *p;
|
||||
|
||||
line = skip_over_blank(line);
|
||||
|
||||
p = line + strlen(line) - 1;
|
||||
|
||||
while (*line) {
|
||||
if (isspace(*p))
|
||||
*p-- = '\0';
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static char *parse_word(char **buf)
|
||||
{
|
||||
char *word, *next;
|
||||
|
||||
word = *buf;
|
||||
if (*word == '\0')
|
||||
return NULL;
|
||||
|
||||
word = skip_over_blank(word);
|
||||
next = skip_over_word(word);
|
||||
if (*next) {
|
||||
char *end = next - 1;
|
||||
if (*end == '"' || *end == '\'')
|
||||
*end = '\0';
|
||||
*next++ = '\0';
|
||||
}
|
||||
*buf = next;
|
||||
|
||||
if (*word == '"' || *word == '\'')
|
||||
word++;
|
||||
return word;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start parsing a new line from the cache.
|
||||
*
|
||||
* line starts with "<device" return 1 -> continue parsing line
|
||||
* line starts with "<foo", empty, or # return 0 -> skip line
|
||||
* line starts with other, return -BLKID_ERR_CACHE -> error
|
||||
*/
|
||||
static int parse_start(char **cp)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = strip_line(*cp);
|
||||
|
||||
/* Skip comment or blank lines. We can't just NUL the first '#' char,
|
||||
* in case it is inside quotes, or escaped.
|
||||
*/
|
||||
if (*p == '\0' || *p == '#')
|
||||
return 0;
|
||||
|
||||
if (!strncmp(p, "<device", 7)) {
|
||||
DBG(DEBUG_READ, printf("found device header: %8s\n", p));
|
||||
p += 7;
|
||||
|
||||
*cp = p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (*p == '<')
|
||||
return 0;
|
||||
|
||||
return -BLKID_ERR_CACHE;
|
||||
}
|
||||
|
||||
/* Consume the remaining XML on the line (cosmetic only) */
|
||||
static int parse_end(char **cp)
|
||||
{
|
||||
*cp = skip_over_blank(*cp);
|
||||
|
||||
if (!strncmp(*cp, "</device>", 9)) {
|
||||
DBG(DEBUG_READ, printf("found device trailer %9s\n", *cp));
|
||||
*cp += 9;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -BLKID_ERR_CACHE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new device struct with device name filled in. Will handle
|
||||
* finding the device on lines of the form:
|
||||
* <device foo=bar>devname</device>
|
||||
* <device>devname<foo>bar</foo></device>
|
||||
*/
|
||||
static int parse_dev(blkid_cache cache, blkid_dev *dev, char **cp)
|
||||
{
|
||||
char *start, *tmp, *end, *name;
|
||||
int ret;
|
||||
|
||||
if ((ret = parse_start(cp)) <= 0)
|
||||
return ret;
|
||||
|
||||
start = tmp = strchr(*cp, '>');
|
||||
if (!start) {
|
||||
DBG(DEBUG_READ,
|
||||
printf("blkid: short line parsing dev: %s\n", *cp));
|
||||
return -BLKID_ERR_CACHE;
|
||||
}
|
||||
start = skip_over_blank(start + 1);
|
||||
end = skip_over_word(start);
|
||||
|
||||
DBG(DEBUG_READ, printf("device should be %.*s\n",
|
||||
(int)(end - start), start));
|
||||
|
||||
if (**cp == '>')
|
||||
*cp = end;
|
||||
else
|
||||
(*cp)++;
|
||||
|
||||
*tmp = '\0';
|
||||
|
||||
if (!(tmp = strrchr(end, '<')) || parse_end(&tmp) < 0) {
|
||||
DBG(DEBUG_READ,
|
||||
printf("blkid: missing </device> ending: %s\n", end));
|
||||
} else if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
if (end - start <= 1) {
|
||||
DBG(DEBUG_READ, printf("blkid: empty device name: %s\n", *cp));
|
||||
return -BLKID_ERR_CACHE;
|
||||
}
|
||||
|
||||
name = blkid_strndup(start, end-start);
|
||||
if (name == NULL)
|
||||
return -BLKID_ERR_MEM;
|
||||
|
||||
DBG(DEBUG_READ, printf("found dev %s\n", name));
|
||||
|
||||
if (!(*dev = blkid_get_dev(cache, name, BLKID_DEV_CREATE))) {
|
||||
free(name);
|
||||
return -BLKID_ERR_MEM;
|
||||
}
|
||||
|
||||
free(name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract a tag of the form NAME="value" from the line.
|
||||
*/
|
||||
static int parse_token(char **name, char **value, char **cp)
|
||||
{
|
||||
char *end;
|
||||
|
||||
if (!name || !value || !cp)
|
||||
return -BLKID_ERR_PARAM;
|
||||
|
||||
if (!(*value = strchr(*cp, '=')))
|
||||
return 0;
|
||||
|
||||
**value = '\0';
|
||||
*name = strip_line(*cp);
|
||||
*value = skip_over_blank(*value + 1);
|
||||
|
||||
if (**value == '"') {
|
||||
end = strchr(*value + 1, '"');
|
||||
if (!end) {
|
||||
DBG(DEBUG_READ,
|
||||
printf("unbalanced quotes at: %s\n", *value));
|
||||
*cp = *value;
|
||||
return -BLKID_ERR_CACHE;
|
||||
}
|
||||
(*value)++;
|
||||
*end = '\0';
|
||||
end++;
|
||||
} else {
|
||||
end = skip_over_word(*value);
|
||||
if (*end) {
|
||||
*end = '\0';
|
||||
end++;
|
||||
}
|
||||
}
|
||||
*cp = end;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract a tag of the form <NAME>value</NAME> from the line.
|
||||
*/
|
||||
/*
|
||||
static int parse_xml(char **name, char **value, char **cp)
|
||||
{
|
||||
char *end;
|
||||
|
||||
if (!name || !value || !cp)
|
||||
return -BLKID_ERR_PARAM;
|
||||
|
||||
*name = strip_line(*cp);
|
||||
|
||||
if ((*name)[0] != '<' || (*name)[1] == '/')
|
||||
return 0;
|
||||
|
||||
FIXME: finish this.
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* Extract a tag from the line.
|
||||
*
|
||||
* Return 1 if a valid tag was found.
|
||||
* Return 0 if no tag found.
|
||||
* Return -ve error code.
|
||||
*/
|
||||
static int parse_tag(blkid_cache cache, blkid_dev dev, char **cp)
|
||||
{
|
||||
char *name;
|
||||
char *value;
|
||||
int ret;
|
||||
|
||||
if (!cache || !dev)
|
||||
return -BLKID_ERR_PARAM;
|
||||
|
||||
if ((ret = parse_token(&name, &value, cp)) <= 0 /* &&
|
||||
(ret = parse_xml(&name, &value, cp)) <= 0 */)
|
||||
return ret;
|
||||
|
||||
/* Some tags are stored directly in the device struct */
|
||||
if (!strcmp(name, "DEVNO"))
|
||||
dev->bid_devno = STRTOULL(value, 0, 0);
|
||||
else if (!strcmp(name, "PRI"))
|
||||
dev->bid_pri = strtol(value, 0, 0);
|
||||
else if (!strcmp(name, "TIME"))
|
||||
dev->bid_time = STRTOULL(value, 0, 0);
|
||||
else
|
||||
ret = blkid_set_tag(dev, name, value, strlen(value));
|
||||
|
||||
DBG(DEBUG_READ, printf(" tag: %s=\"%s\"\n", name, value));
|
||||
|
||||
return ret < 0 ? ret : 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a single line of data, and return a newly allocated dev struct.
|
||||
* Add the new device to the cache struct, if one was read.
|
||||
*
|
||||
* Lines are of the form <device [TAG="value" ...]>/dev/foo</device>
|
||||
*
|
||||
* Returns -ve value on error.
|
||||
* Returns 0 otherwise.
|
||||
* If a valid device was read, *dev_p is non-NULL, otherwise it is NULL
|
||||
* (e.g. comment lines, unknown XML content, etc).
|
||||
*/
|
||||
static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp)
|
||||
{
|
||||
blkid_dev dev;
|
||||
int ret;
|
||||
|
||||
if (!cache || !dev_p)
|
||||
return -BLKID_ERR_PARAM;
|
||||
|
||||
*dev_p = NULL;
|
||||
|
||||
DBG(DEBUG_READ, printf("line: %s\n", cp));
|
||||
|
||||
if ((ret = parse_dev(cache, dev_p, &cp)) <= 0)
|
||||
return ret;
|
||||
|
||||
dev = *dev_p;
|
||||
|
||||
while ((ret = parse_tag(cache, dev, &cp)) > 0) {
|
||||
;
|
||||
}
|
||||
|
||||
if (dev->bid_type == NULL) {
|
||||
DBG(DEBUG_READ,
|
||||
printf("blkid: device %s has no TYPE\n",dev->bid_name));
|
||||
blkid_free_dev(dev);
|
||||
}
|
||||
|
||||
DBG(DEBUG_READ, blkid_debug_dump_dev(dev));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the specified filename, and return the data in the supplied or
|
||||
* a newly allocated cache struct. If the file doesn't exist, return a
|
||||
* new empty cache struct.
|
||||
*/
|
||||
void blkid_read_cache(blkid_cache cache)
|
||||
{
|
||||
FILE *file;
|
||||
char buf[4096];
|
||||
int fd, lineno = 0;
|
||||
struct stat st;
|
||||
|
||||
if (!cache)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If the file doesn't exist, then we just return an empty
|
||||
* struct so that the cache can be populated.
|
||||
*/
|
||||
if ((fd = open(cache->bic_filename, O_RDONLY)) < 0)
|
||||
return;
|
||||
if (fstat(fd, &st) < 0)
|
||||
goto errout;
|
||||
if ((st.st_mtime == cache->bic_ftime) ||
|
||||
(cache->bic_flags & BLKID_BIC_FL_CHANGED)) {
|
||||
DBG(DEBUG_CACHE, printf("skipping re-read of %s\n",
|
||||
cache->bic_filename));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
DBG(DEBUG_CACHE, printf("reading cache file %s\n",
|
||||
cache->bic_filename));
|
||||
|
||||
file = fdopen(fd, "r");
|
||||
if (!file)
|
||||
goto errout;
|
||||
|
||||
while (fgets(buf, sizeof(buf), file)) {
|
||||
blkid_dev dev;
|
||||
unsigned int end;
|
||||
|
||||
lineno++;
|
||||
if (buf[0] == 0)
|
||||
continue;
|
||||
end = strlen(buf) - 1;
|
||||
/* Continue reading next line if it ends with a backslash */
|
||||
while (buf[end] == '\\' && end < sizeof(buf) - 2 &&
|
||||
fgets(buf + end, sizeof(buf) - end, file)) {
|
||||
end = strlen(buf) - 1;
|
||||
lineno++;
|
||||
}
|
||||
|
||||
if (blkid_parse_line(cache, &dev, buf) < 0) {
|
||||
DBG(DEBUG_READ,
|
||||
printf("blkid: bad format on line %d\n", lineno));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
/*
|
||||
* Initially we do not need to write out the cache file.
|
||||
*/
|
||||
cache->bic_flags &= ~BLKID_BIC_FL_CHANGED;
|
||||
cache->bic_ftime = st.st_mtime;
|
||||
|
||||
return;
|
||||
errout:
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
static void debug_dump_dev(blkid_dev dev)
|
||||
{
|
||||
struct list_head *p;
|
||||
|
||||
if (!dev) {
|
||||
printf(" dev: NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" dev: name = %s\n", dev->bid_name);
|
||||
printf(" dev: DEVNO=\"0x%0llx\"\n", (long long)dev->bid_devno);
|
||||
printf(" dev: TIME=\"%lld\"\n", (long long)dev->bid_time);
|
||||
printf(" dev: PRI=\"%d\"\n", dev->bid_pri);
|
||||
printf(" dev: flags = 0x%08X\n", dev->bid_flags);
|
||||
|
||||
list_for_each(p, &dev->bid_tags) {
|
||||
blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
|
||||
if (tag)
|
||||
printf(" tag: %s=\"%s\"\n", tag->bit_name,
|
||||
tag->bit_val);
|
||||
else
|
||||
printf(" tag: NULL\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char**argv)
|
||||
{
|
||||
blkid_cache cache = NULL;
|
||||
int ret;
|
||||
|
||||
blkid_debug_mask = DEBUG_ALL;
|
||||
if (argc > 2) {
|
||||
fprintf(stderr, "Usage: %s [filename]\n"
|
||||
"Test parsing of the cache (filename)\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if ((ret = blkid_get_cache(&cache, argv[1])) < 0)
|
||||
fprintf(stderr, "error %d reading cache file %s\n", ret,
|
||||
argv[1] ? argv[1] : BLKID_CACHE_FILE);
|
||||
|
||||
blkid_put_cache(cache);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
Binary file not shown.
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* resolve.c - resolve names and tags into specific devices
|
||||
*
|
||||
* Copyright (C) 2001, 2003 Theodore Ts'o.
|
||||
* Copyright (C) 2001 Andreas Dilger
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "blkidP.h"
|
||||
|
||||
/*
|
||||
* Find a tagname (e.g. LABEL or UUID) on a specific device.
|
||||
*/
|
||||
char *blkid_get_tag_value(blkid_cache cache, const char *tagname,
|
||||
const char *devname)
|
||||
{
|
||||
blkid_tag found;
|
||||
blkid_dev dev;
|
||||
blkid_cache c = cache;
|
||||
char *ret = NULL;
|
||||
|
||||
DBG(DEBUG_RESOLVE, printf("looking for %s on %s\n", tagname, devname));
|
||||
|
||||
if (!devname)
|
||||
return NULL;
|
||||
|
||||
if (!cache) {
|
||||
if (blkid_get_cache(&c, NULL) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((dev = blkid_get_dev(c, devname, BLKID_DEV_NORMAL)) &&
|
||||
(found = blkid_find_tag_dev(dev, tagname)))
|
||||
ret = blkid_strdup(found->bit_val);
|
||||
|
||||
if (!cache)
|
||||
blkid_put_cache(c);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate a device name from a token (NAME=value string), or (name, value)
|
||||
* pair. In the case of a token, value is ignored. If the "token" is not
|
||||
* of the form "NAME=value" and there is no value given, then it is assumed
|
||||
* to be the actual devname and a copy is returned.
|
||||
*/
|
||||
char *blkid_get_devname(blkid_cache cache, const char *token,
|
||||
const char *value)
|
||||
{
|
||||
blkid_dev dev;
|
||||
blkid_cache c = cache;
|
||||
char *t = 0, *v = 0;
|
||||
char *ret = NULL;
|
||||
|
||||
if (!token)
|
||||
return NULL;
|
||||
|
||||
if (!cache) {
|
||||
if (blkid_get_cache(&c, NULL) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DBG(DEBUG_RESOLVE,
|
||||
printf("looking for %s%s%s %s\n", token, value ? "=" : "",
|
||||
value ? value : "", cache ? "in cache" : "from disk"));
|
||||
|
||||
if (!value) {
|
||||
if (!strchr(token, '=')) {
|
||||
ret = blkid_strdup(token);
|
||||
goto out;
|
||||
}
|
||||
blkid_parse_tag_string(token, &t, &v);
|
||||
if (!t || !v)
|
||||
goto out;
|
||||
token = t;
|
||||
value = v;
|
||||
}
|
||||
|
||||
dev = blkid_find_dev_with_tag(c, token, value);
|
||||
if (!dev)
|
||||
goto out;
|
||||
|
||||
ret = blkid_strdup(blkid_dev_devname(dev));
|
||||
|
||||
out:
|
||||
free(t);
|
||||
free(v);
|
||||
if (!cache) {
|
||||
blkid_put_cache(c);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *value;
|
||||
blkid_cache cache;
|
||||
|
||||
blkid_debug_mask = DEBUG_ALL;
|
||||
if (argc != 2 && argc != 3) {
|
||||
fprintf(stderr, "Usage:\t%s tagname=value\n"
|
||||
"\t%s tagname devname\n"
|
||||
"Find which device holds a given token or\n"
|
||||
"Find what the value of a tag is in a device\n",
|
||||
argv[0], argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if (blkid_get_cache(&cache, "/dev/null") < 0) {
|
||||
fprintf(stderr, "Couldn't get blkid cache\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (argv[2]) {
|
||||
value = blkid_get_tag_value(cache, argv[1], argv[2]);
|
||||
printf("%s has tag %s=%s\n", argv[2], argv[1],
|
||||
value ? value : "<missing>");
|
||||
} else {
|
||||
value = blkid_get_devname(cache, argv[1], NULL);
|
||||
printf("%s has tag %s\n", value ? value : "<none>", argv[1]);
|
||||
}
|
||||
blkid_put_cache(cache);
|
||||
return value ? 0 : 1;
|
||||
}
|
||||
#endif
|
||||
Binary file not shown.
@@ -1,213 +0,0 @@
|
||||
/*
|
||||
* save.c - write the cache struct to disk
|
||||
*
|
||||
* Copyright (C) 2001 by Andreas Dilger
|
||||
* Copyright (C) 2003 Theodore Ts'o
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_MKDEV_H
|
||||
#include <sys/mkdev.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include "blkidP.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows.h"
|
||||
#endif
|
||||
|
||||
static int save_dev(blkid_dev dev, FILE *file)
|
||||
{
|
||||
struct list_head *p;
|
||||
|
||||
if (!dev || dev->bid_name[0] != '/')
|
||||
return 0;
|
||||
|
||||
DBG(DEBUG_SAVE,
|
||||
printf("device %s, type %s\n", dev->bid_name, dev->bid_type ?
|
||||
dev->bid_type : "(null)"));
|
||||
|
||||
fprintf(file,
|
||||
"<device DEVNO=\"0x%04lx\" TIME=\"%ld\"",
|
||||
(unsigned long) dev->bid_devno, (long) dev->bid_time);
|
||||
if (dev->bid_pri)
|
||||
fprintf(file, " PRI=\"%d\"", dev->bid_pri);
|
||||
list_for_each(p, &dev->bid_tags) {
|
||||
blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
|
||||
fprintf(file, " %s=\"%s\"", tag->bit_name,tag->bit_val);
|
||||
}
|
||||
fprintf(file, ">%s</device>\n", dev->bid_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write out the cache struct to the cache file on disk.
|
||||
*/
|
||||
int blkid_flush_cache(blkid_cache cache)
|
||||
{
|
||||
struct list_head *p;
|
||||
char *tmp = NULL;
|
||||
const char *opened = NULL;
|
||||
const char *filename;
|
||||
FILE *file = NULL;
|
||||
int fd, ret = 0;
|
||||
struct stat st;
|
||||
|
||||
if (!cache)
|
||||
return -BLKID_ERR_PARAM;
|
||||
|
||||
if (list_empty(&cache->bic_devs) ||
|
||||
!(cache->bic_flags & BLKID_BIC_FL_CHANGED)) {
|
||||
DBG(DEBUG_SAVE, printf("skipping cache file write\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
filename = cache->bic_filename ? cache->bic_filename: BLKID_CACHE_FILE;
|
||||
|
||||
/* If we can't write to the cache file, then don't even try */
|
||||
if (((ret = stat(filename, &st)) < 0 && errno != ENOENT) ||
|
||||
(ret == 0 && access(filename, W_OK) < 0)) {
|
||||
DBG(DEBUG_SAVE,
|
||||
printf("can't write to cache file %s\n", filename));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try and create a temporary file in the same directory so
|
||||
* that in case of error we don't overwrite the cache file.
|
||||
* If the cache file doesn't yet exist, it isn't a regular
|
||||
* file (e.g. /dev/null or a socket), or we couldn't create
|
||||
* a temporary file then we open it directly.
|
||||
*/
|
||||
if (ret == 0 && S_ISREG(st.st_mode)) {
|
||||
tmp = malloc(strlen(filename) + 8);
|
||||
if (tmp) {
|
||||
mode_t save_umask = umask(022);
|
||||
sprintf(tmp, "%s-XXXXXX", filename);
|
||||
fd = mkstemp(tmp);
|
||||
umask(save_umask);
|
||||
if (fd >= 0) {
|
||||
file = fdopen(fd, "w");
|
||||
opened = tmp;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
fchmod(fd, 0644);
|
||||
#else
|
||||
chmod(tmp, 0644);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
file = fopen(filename, "w");
|
||||
opened = filename;
|
||||
}
|
||||
|
||||
DBG(DEBUG_SAVE,
|
||||
printf("writing cache file %s (really %s)\n",
|
||||
filename, opened));
|
||||
|
||||
if (!file) {
|
||||
ret = errno;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
list_for_each(p, &cache->bic_devs) {
|
||||
blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
|
||||
if (!dev->bid_type)
|
||||
continue;
|
||||
if ((ret = save_dev(dev, file)) < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
cache->bic_flags &= ~BLKID_BIC_FL_CHANGED;
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
if (opened != filename) {
|
||||
if (ret < 0) {
|
||||
(void) unlink(opened);
|
||||
DBG(DEBUG_SAVE,
|
||||
printf("unlinked temp cache %s\n", opened));
|
||||
} else {
|
||||
char *backup;
|
||||
|
||||
backup = malloc(strlen(filename) + 5);
|
||||
if (backup) {
|
||||
sprintf(backup, "%s.old", filename);
|
||||
unlink(backup);
|
||||
#if defined(__GNUC__) && __GNUC__ >= 5
|
||||
/* explicit (void) cast is not enough with glibc and _FORTIFY_SOURCE */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-result"
|
||||
#endif
|
||||
(void) link(filename, backup);
|
||||
#if defined(__GNUC__) && __GNUC__ >= 5
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
free(backup);
|
||||
}
|
||||
if (rename(opened, filename) < 0)
|
||||
(void) unlink(opened);
|
||||
DBG(DEBUG_SAVE,
|
||||
printf("moved temp cache %s\n", opened));
|
||||
}
|
||||
}
|
||||
|
||||
errout:
|
||||
free(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
blkid_cache cache = NULL;
|
||||
int ret;
|
||||
|
||||
blkid_debug_mask = DEBUG_ALL;
|
||||
if (argc > 2) {
|
||||
fprintf(stderr, "Usage: %s [filename]\n"
|
||||
"Test loading/saving a cache (filename)\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
|
||||
fprintf(stderr, "%s: error creating cache (%d)\n",
|
||||
argv[0], ret);
|
||||
exit(1);
|
||||
}
|
||||
if ((ret = blkid_probe_all(cache)) < 0) {
|
||||
fprintf(stderr, "error (%d) probing devices\n", ret);
|
||||
exit(1);
|
||||
}
|
||||
cache->bic_filename = blkid_strdup(argv[1]);
|
||||
|
||||
if ((ret = blkid_flush_cache(cache)) < 0) {
|
||||
fprintf(stderr, "error (%d) saving cache\n", ret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
blkid_put_cache(cache);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
Binary file not shown.
@@ -1,471 +0,0 @@
|
||||
/*
|
||||
* tag.c - allocation/initialization/free routines for tag structs
|
||||
*
|
||||
* Copyright (C) 2001 Andreas Dilger
|
||||
* Copyright (C) 2003 Theodore Ts'o
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "blkidP.h"
|
||||
|
||||
static blkid_tag blkid_new_tag(void)
|
||||
{
|
||||
blkid_tag tag;
|
||||
|
||||
if (!(tag = (blkid_tag) calloc(1, sizeof(struct blkid_struct_tag))))
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(&tag->bit_tags);
|
||||
INIT_LIST_HEAD(&tag->bit_names);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLKID_DEBUG
|
||||
void blkid_debug_dump_tag(blkid_tag tag)
|
||||
{
|
||||
if (!tag) {
|
||||
printf(" tag: NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" tag: %s=\"%s\"\n", tag->bit_name, tag->bit_val);
|
||||
}
|
||||
#endif
|
||||
|
||||
void blkid_free_tag(blkid_tag tag)
|
||||
{
|
||||
if (!tag)
|
||||
return;
|
||||
|
||||
DBG(DEBUG_TAG, printf(" freeing tag %s=%s\n", tag->bit_name,
|
||||
tag->bit_val ? tag->bit_val : "(NULL)"));
|
||||
DBG(DEBUG_TAG, blkid_debug_dump_tag(tag));
|
||||
|
||||
list_del(&tag->bit_tags); /* list of tags for this device */
|
||||
list_del(&tag->bit_names); /* list of tags with this type */
|
||||
|
||||
free(tag->bit_name);
|
||||
free(tag->bit_val);
|
||||
|
||||
free(tag);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the desired tag on a device. If value is NULL, then the
|
||||
* first such tag is returned, otherwise return only exact tag if found.
|
||||
*/
|
||||
blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type)
|
||||
{
|
||||
struct list_head *p;
|
||||
|
||||
if (!dev || !type)
|
||||
return NULL;
|
||||
|
||||
list_for_each(p, &dev->bid_tags) {
|
||||
blkid_tag tmp = list_entry(p, struct blkid_struct_tag,
|
||||
bit_tags);
|
||||
|
||||
if (!strcmp(tmp->bit_name, type))
|
||||
return tmp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern int blkid_dev_has_tag(blkid_dev dev, const char *type,
|
||||
const char *value)
|
||||
{
|
||||
blkid_tag tag;
|
||||
|
||||
if (!dev || !type)
|
||||
return -1;
|
||||
|
||||
tag = blkid_find_tag_dev(dev, type);
|
||||
if (!value)
|
||||
return (tag != NULL);
|
||||
if (!tag || strcmp(tag->bit_val, value))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the desired tag type in the cache.
|
||||
* We return the head tag for this tag type.
|
||||
*/
|
||||
static blkid_tag blkid_find_head_cache(blkid_cache cache, const char *type)
|
||||
{
|
||||
blkid_tag head = NULL, tmp;
|
||||
struct list_head *p;
|
||||
|
||||
if (!cache || !type)
|
||||
return NULL;
|
||||
|
||||
list_for_each(p, &cache->bic_tags) {
|
||||
tmp = list_entry(p, struct blkid_struct_tag, bit_tags);
|
||||
if (!strcmp(tmp->bit_name, type)) {
|
||||
DBG(DEBUG_TAG,
|
||||
printf(" found cache tag head %s\n", type));
|
||||
head = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a tag on an existing device.
|
||||
*
|
||||
* If value is NULL, then delete the tagsfrom the device.
|
||||
*/
|
||||
int blkid_set_tag(blkid_dev dev, const char *name,
|
||||
const char *value, const int vlength)
|
||||
{
|
||||
blkid_tag t = 0, head = 0;
|
||||
char *val = 0;
|
||||
char **dev_var = 0;
|
||||
|
||||
if (!dev || !name)
|
||||
return -BLKID_ERR_PARAM;
|
||||
|
||||
if (!(val = blkid_strndup(value, vlength)) && value)
|
||||
return -BLKID_ERR_MEM;
|
||||
|
||||
/*
|
||||
* Certain common tags are linked directly to the device struct
|
||||
* We need to know what they are before we do anything else because
|
||||
* the function name parameter might get freed later on.
|
||||
*/
|
||||
if (!strcmp(name, "TYPE"))
|
||||
dev_var = &dev->bid_type;
|
||||
else if (!strcmp(name, "LABEL"))
|
||||
dev_var = &dev->bid_label;
|
||||
else if (!strcmp(name, "UUID"))
|
||||
dev_var = &dev->bid_uuid;
|
||||
|
||||
t = blkid_find_tag_dev(dev, name);
|
||||
if (!value) {
|
||||
if (t)
|
||||
blkid_free_tag(t);
|
||||
} else if (t) {
|
||||
if (!strcmp(t->bit_val, val)) {
|
||||
/* Same thing, exit */
|
||||
free(val);
|
||||
return 0;
|
||||
}
|
||||
free(t->bit_val);
|
||||
t->bit_val = val;
|
||||
} else {
|
||||
/* Existing tag not present, add to device */
|
||||
if (!(t = blkid_new_tag()))
|
||||
goto errout;
|
||||
t->bit_name = blkid_strdup(name);
|
||||
t->bit_val = val;
|
||||
t->bit_dev = dev;
|
||||
|
||||
list_add_tail(&t->bit_tags, &dev->bid_tags);
|
||||
|
||||
if (dev->bid_cache) {
|
||||
head = blkid_find_head_cache(dev->bid_cache,
|
||||
t->bit_name);
|
||||
if (!head) {
|
||||
head = blkid_new_tag();
|
||||
if (!head)
|
||||
goto errout;
|
||||
|
||||
DBG(DEBUG_TAG,
|
||||
printf(" creating new cache tag head %s\n", name));
|
||||
head->bit_name = blkid_strdup(name);
|
||||
if (!head->bit_name)
|
||||
goto errout;
|
||||
list_add_tail(&head->bit_tags,
|
||||
&dev->bid_cache->bic_tags);
|
||||
}
|
||||
list_add_tail(&t->bit_names, &head->bit_names);
|
||||
}
|
||||
}
|
||||
|
||||
/* Link common tags directly to the device struct */
|
||||
if (dev_var)
|
||||
*dev_var = val;
|
||||
|
||||
if (dev->bid_cache)
|
||||
dev->bid_cache->bic_flags |= BLKID_BIC_FL_CHANGED;
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
if (t)
|
||||
blkid_free_tag(t);
|
||||
else free(val);
|
||||
if (head)
|
||||
blkid_free_tag(head);
|
||||
return -BLKID_ERR_MEM;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse a "NAME=value" string. This is slightly different than
|
||||
* parse_token, because that will end an unquoted value at a space, while
|
||||
* this will assume that an unquoted value is the rest of the token (e.g.
|
||||
* if we are passed an already quoted string from the command-line we don't
|
||||
* have to both quote and escape quote so that the quotes make it to
|
||||
* us).
|
||||
*
|
||||
* Returns 0 on success, and -1 on failure.
|
||||
*/
|
||||
int blkid_parse_tag_string(const char *token, char **ret_type, char **ret_val)
|
||||
{
|
||||
char *name, *value, *cp;
|
||||
|
||||
DBG(DEBUG_TAG, printf("trying to parse '%s' as a tag\n", token));
|
||||
|
||||
if (!token || !(cp = strchr(token, '=')))
|
||||
return -1;
|
||||
|
||||
name = blkid_strdup(token);
|
||||
if (!name)
|
||||
return -1;
|
||||
value = name + (cp - token);
|
||||
*value++ = '\0';
|
||||
if (*value == '"' || *value == '\'') {
|
||||
char c = *value++;
|
||||
if (!(cp = strrchr(value, c)))
|
||||
goto errout; /* missing closing quote */
|
||||
*cp = '\0';
|
||||
}
|
||||
value = blkid_strdup(value);
|
||||
if (!value)
|
||||
goto errout;
|
||||
|
||||
*ret_type = name;
|
||||
*ret_val = value;
|
||||
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
free(name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tag iteration routines for the public libblkid interface.
|
||||
*
|
||||
* These routines do not expose the list.h implementation, which are a
|
||||
* contamination of the namespace, and which force us to reveal far, far
|
||||
* too much of our internal implementation. I'm not convinced I want
|
||||
* to keep list.h in the long term, anyway. It's fine for kernel
|
||||
* programming, but performance is not the #1 priority for this
|
||||
* library, and I really don't like the tradeoff of type-safety for
|
||||
* performance for this application. [tytso:20030125.2007EST]
|
||||
*/
|
||||
|
||||
/*
|
||||
* This series of functions iterate over all tags in a device
|
||||
*/
|
||||
#define TAG_ITERATE_MAGIC 0x01a5284c
|
||||
|
||||
struct blkid_struct_tag_iterate {
|
||||
int magic;
|
||||
blkid_dev dev;
|
||||
struct list_head *p;
|
||||
};
|
||||
|
||||
extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev)
|
||||
{
|
||||
blkid_tag_iterate iter;
|
||||
|
||||
iter = malloc(sizeof(struct blkid_struct_tag_iterate));
|
||||
if (iter) {
|
||||
iter->magic = TAG_ITERATE_MAGIC;
|
||||
iter->dev = dev;
|
||||
iter->p = dev->bid_tags.next;
|
||||
}
|
||||
return (iter);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 0 on success, -1 on error
|
||||
*/
|
||||
extern int blkid_tag_next(blkid_tag_iterate iter,
|
||||
const char **type, const char **value)
|
||||
{
|
||||
blkid_tag tag;
|
||||
|
||||
*type = 0;
|
||||
*value = 0;
|
||||
if (!iter || iter->magic != TAG_ITERATE_MAGIC ||
|
||||
iter->p == &iter->dev->bid_tags)
|
||||
return -1;
|
||||
tag = list_entry(iter->p, struct blkid_struct_tag, bit_tags);
|
||||
*type = tag->bit_name;
|
||||
*value = tag->bit_val;
|
||||
iter->p = iter->p->next;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void blkid_tag_iterate_end(blkid_tag_iterate iter)
|
||||
{
|
||||
if (!iter || iter->magic != TAG_ITERATE_MAGIC)
|
||||
return;
|
||||
iter->magic = 0;
|
||||
free(iter);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns a device which matches a particular
|
||||
* type/value pair. If there is more than one device that matches the
|
||||
* search specification, it returns the one with the highest priority
|
||||
* value. This allows us to give preference to EVMS or LVM devices.
|
||||
*/
|
||||
extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
|
||||
const char *type,
|
||||
const char *value)
|
||||
{
|
||||
blkid_tag head;
|
||||
blkid_dev dev;
|
||||
int pri;
|
||||
struct list_head *p;
|
||||
int probe_new = 0;
|
||||
|
||||
if (!cache || !type || !value)
|
||||
return NULL;
|
||||
|
||||
blkid_read_cache(cache);
|
||||
|
||||
DBG(DEBUG_TAG, printf("looking for %s=%s in cache\n", type, value));
|
||||
|
||||
try_again:
|
||||
pri = -1;
|
||||
dev = 0;
|
||||
head = blkid_find_head_cache(cache, type);
|
||||
|
||||
if (head) {
|
||||
list_for_each(p, &head->bit_names) {
|
||||
blkid_tag tmp = list_entry(p, struct blkid_struct_tag,
|
||||
bit_names);
|
||||
|
||||
if (!strcmp(tmp->bit_val, value) &&
|
||||
(tmp->bit_dev->bid_pri > pri) &&
|
||||
!access(tmp->bit_dev->bid_name, F_OK)) {
|
||||
dev = tmp->bit_dev;
|
||||
pri = dev->bid_pri;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dev && !(dev->bid_flags & BLKID_BID_FL_VERIFIED)) {
|
||||
dev = blkid_verify(cache, dev);
|
||||
if (!dev || (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED)))
|
||||
goto try_again;
|
||||
}
|
||||
|
||||
if (!dev && !probe_new) {
|
||||
if (blkid_probe_all_new(cache) < 0)
|
||||
return NULL;
|
||||
probe_new++;
|
||||
goto try_again;
|
||||
}
|
||||
|
||||
if (!dev && !(cache->bic_flags & BLKID_BIC_FL_PROBED)) {
|
||||
if (blkid_probe_all(cache) < 0)
|
||||
return NULL;
|
||||
goto try_again;
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#else
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
#endif
|
||||
|
||||
void usage(char *prog)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask] device "
|
||||
"[type value]\n",
|
||||
prog);
|
||||
fprintf(stderr, "\tList all tags for a device and exit\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
blkid_tag_iterate iter;
|
||||
blkid_cache cache = NULL;
|
||||
blkid_dev dev;
|
||||
int c, ret, found;
|
||||
int flags = BLKID_DEV_FIND;
|
||||
char *tmp;
|
||||
char *file = NULL;
|
||||
char *devname = NULL;
|
||||
char *search_type = NULL;
|
||||
char *search_value = NULL;
|
||||
const char *type, *value;
|
||||
|
||||
while ((c = getopt (argc, argv, "m:f:")) != EOF)
|
||||
switch (c) {
|
||||
case 'f':
|
||||
file = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
blkid_debug_mask = strtoul (optarg, &tmp, 0);
|
||||
if (*tmp) {
|
||||
fprintf(stderr, "Invalid debug mask: %s\n",
|
||||
optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
usage(argv[0]);
|
||||
}
|
||||
if (argc > optind)
|
||||
devname = argv[optind++];
|
||||
if (argc > optind)
|
||||
search_type = argv[optind++];
|
||||
if (argc > optind)
|
||||
search_value = argv[optind++];
|
||||
if (!devname || (argc != optind))
|
||||
usage(argv[0]);
|
||||
|
||||
if ((ret = blkid_get_cache(&cache, file)) != 0) {
|
||||
fprintf(stderr, "%s: error creating cache (%d)\n",
|
||||
argv[0], ret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
dev = blkid_get_dev(cache, devname, flags);
|
||||
if (!dev) {
|
||||
fprintf(stderr, "%s: Can not find device in blkid cache\n",
|
||||
devname);
|
||||
exit(1);
|
||||
}
|
||||
if (search_type) {
|
||||
found = blkid_dev_has_tag(dev, search_type, search_value);
|
||||
printf("Device %s: (%s, %s) %s\n", blkid_dev_devname(dev),
|
||||
search_type, search_value ? search_value : "NULL",
|
||||
found ? "FOUND" : "NOT FOUND");
|
||||
return(!found);
|
||||
}
|
||||
printf("Device %s...\n", blkid_dev_devname(dev));
|
||||
|
||||
iter = blkid_tag_iterate_begin(dev);
|
||||
while (blkid_tag_next(iter, &type, &value) == 0) {
|
||||
printf("\tTag %s has value %s\n", type, value);
|
||||
}
|
||||
blkid_tag_iterate_end(iter);
|
||||
|
||||
blkid_put_cache(cache);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
Binary file not shown.
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* version.c --- Return the version of the blkid library
|
||||
*
|
||||
* Copyright (C) 2004 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <blkid/blkid_local.h>
|
||||
#include "version.h"
|
||||
|
||||
static const char *lib_version = E2FSPROGS_VERSION;
|
||||
static const char *lib_date = E2FSPROGS_DATE;
|
||||
|
||||
int blkid_parse_version_string(const char *ver_string)
|
||||
{
|
||||
const char *cp;
|
||||
int version = 0;
|
||||
|
||||
for (cp = ver_string; *cp; cp++) {
|
||||
if (*cp == '.')
|
||||
continue;
|
||||
if (!isdigit(*cp))
|
||||
break;
|
||||
version = (version * 10) + (*cp - '0');
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
int blkid_get_library_version(const char **ver_string,
|
||||
const char **date_string)
|
||||
{
|
||||
if (ver_string)
|
||||
*ver_string = lib_version;
|
||||
if (date_string)
|
||||
*date_string = lib_date;
|
||||
|
||||
return blkid_parse_version_string(lib_version);
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user