2003-01-25 Theodore Ts'o <tytso@mit.edu>
+ * cache.c, dev.c, devname.c, devno.c, getsize.c, llseek.c,
+ probe.c, probe.h, read.c, resolve.c, save.c, tag.c,
+ blkid.h, blkidP.h: Separate public and private
+ interfaces into separate header files. Start
+ separating internal implementation details from the
+ publically exported interface.
+
* devname.c: Add support for EVMS
* blkid.h, cache.c, dev.c, devname.c, devno.c, probe.c, probe.h,
all:: $(SMANPAGES)
+$(top_builddir)/lib/blkid/blkid_types.h: $(srcdir)/blkid_types.h.in $(top_builddir)/config.status
+ cd $(top_builddir); CONFIG_FILES=$(my_dir)/blkid_types.h ./config.status
+
libblkid.3: $(DEP_SUBSTITUTE) $(srcdir)/libblkid.3.in
$(SUBSTITUTE) $(srcdir)/libblkid.3.in libblkid.3
done
clean::
- $(RM) -f \#* *.s *.o *.orig *.a *~ *.bak tst_* core profiled/* checker/*
- $(RM) -f ../libblkid.a ../libblkid_p.a $(SMANPAGES)
+ $(RM) -f \#* *.s *.o *.orig *.a *~ *.bak tst_* core profiled/* \
+ checker/* blkid_types.h ../libblkid.a ../libblkid_p.a \
+ $(SMANPAGES)
mostlyclean:: clean
distclean:: clean
* blkid.h - Interface for libblkid, a library to identify block devices
*
* Copyright (C) 2001 Andreas Dilger
+ * Copyright (C) 2003 Theodore Ts'o
*
* %Begin-Header%
* This file may be redistributed under the terms of the
#ifndef _BLKID_BLKID_H
#define _BLKID_BLKID_H
-#include <sys/types.h>
-#include <stdio.h>
-
#ifdef __cplusplus
extern "C" {
#endif
#define BLKID_VERSION "1.2.0"
#define BLKID_DATE "22-Nov-2001"
-#include "blkid/list.h"
-#include "blkid/blkid_types.h"
-
-typedef __s64 blkid_loff_t;
-
-/*
- * This describes the attributes of a specific device.
- * We can traverse all of the tags by bid_tags (linking to the tag bit_names).
- * The bid_label and bid_uuid fields are shortcuts to the LABEL and UUID tag
- * values, if they exist.
- */
-typedef struct blkid_dev
-{
- struct list_head bid_devs; /* All devices in the cache */
- struct list_head bid_tags; /* All tags for this device */
- char *bid_name; /* Device inode pathname */
- char *bid_type; /* Preferred device TYPE */
- blkid_loff_t bid_size; /* Filesystem size in bytes */
- blkid_loff_t bid_free; /* Filesystem free in bytes */
- blkid_loff_t bid_devsize; /* Device size in bytes */
- dev_t bid_devno; /* Device major/minor number */
- time_t bid_time; /* Last update time of device */
- unsigned int bid_id; /* Unique cache id for device */
- unsigned int bid_flags; /* Device status bitflags */
- char *bid_label; /* Shortcut to device LABEL */
- char *bid_uuid; /* Shortcut to binary UUID */
- unsigned long bid_unused[13]; /* Fields for future use */
-} blkid_dev;
-
-#define BLKID_BID_FL_VERIFIED 0x0001 /* Device data validated from disk */
-#define BLKID_BID_FL_MTYPE 0x0002 /* Device has multiple type matches */
-
-/*
- * Each tag defines a NAME=value pair for a particular device. The tags
- * are linked via bit_names for a single device, so that traversing the
- * names list will get you a list of all tags associated with a device.
- * They are also linked via bit_values for all devices, so one can easily
- * search all tags with a given NAME for a specific value.
- */
-typedef struct blkid_tag
-{
- struct list_head bit_tags; /* All tags for this device */
- struct list_head bit_names; /* All tags with given NAME */
- char *bit_name; /* NAME of tag (shared) */
- char *bit_val; /* value of tag */
- struct blkid_dev *bit_dev; /* pointer to device */
- unsigned long bit_unused[9]; /* Fields for future use */
-} blkid_tag;
-
-/*
- * Minimum number of seconds between device probes, even when reading
- * from the cache. This is to avoid re-probing all devices which were
- * just probed by another program that does not share the cache.
- */
-#define BLKID_PROBE_MIN 2
-
-/*
- * Time in seconds an entry remains verified in the in-memory cache
- * before being reverified (in case of long-running processes that
- * keep a cache in memory and continue to use it for a long time).
- */
-#define BLKID_PROBE_INTERVAL 200
+typedef struct blkid_struct_dev *blkid_dev;
+typedef struct blkid_struct_tag *blkid_tag;
+typedef struct blkid_struct_cache *blkid_cache;
-/* This describes an entire blkid cache file and probed devices.
- * We can traverse all of the found devices via bic_list.
- * We can traverse all of the tag types by bic_tags, which hold empty tags
- * for each tag type. Those tags can be used as list_heads for iterating
- * through all devices with a specific tag type (e.g. LABEL).
- */
-typedef struct blkid_cache
-{
- struct list_head bic_devs; /* List head of all devices */
- struct list_head bic_tags; /* List head of all tag types */
- time_t bic_time; /* Last probe time */
- unsigned int bic_idmax; /* Highest ID assigned */
- unsigned int bic_flags; /* Status flags of the cache */
- unsigned long bic_unused[9]; /* Fields for future use */
-} blkid_cache;
+/* cache.c */
+extern void blkid_free_cache(blkid_cache cache);
-#define BLKID_BIC_FL_PARSED 0x0001 /* We parsed a cache file */
-#define BLKID_BIC_FL_PROBED 0x0002 /* We probed /proc/partition devices */
-#define BLKID_BIC_FL_CHANGED 0x0004 /* Cache has changed from disk */
-
-extern char *string_copy(const char *s);
-extern char *stringn_copy(const char *s, const int length);
-extern void string_free(char *s);
-extern blkid_cache *blkid_new_cache(void);
-extern void blkid_free_cache(blkid_cache *cache);
-
-#define BLKID_CACHE_FILE "/etc/blkid.tab"
-extern const char *devdirs[];
-
-#define BLKID_ERR_IO 5
-#define BLKID_ERR_PROC 9
-#define BLKID_ERR_MEM 12
-#define BLKID_ERR_CACHE 14
-#define BLKID_ERR_DEV 19
-#define BLKID_ERR_PARAM 22
-#define BLKID_ERR_BIG 27
-
-#ifdef DEBUG
-#define DEBUG_CACHE
-#define DEBUG_DUMP
-#define DEBUG_DEV
-#define DEBUG_DEVNAME
-#define DEBUG_DEVNO
-#define DEBUG_PROBE
-#define DEBUG_READ
-#define DEBUG_RESOLVE
-#define DEBUG_SAVE
-#define DEBUG_TAG
-#define CHECK_TAG
-#endif
-
-#if defined(TEST_PROGRAM) && !defined(DEBUG_DUMP)
-#define DEBUG_DUMP
-#endif
-
-#ifdef DEBUG_DUMP
-static inline void DEB_DUMP_TAG(blkid_tag *tag)
-{
- if (!tag) {
- printf(" tag: NULL\n");
- return;
- }
-
- printf(" tag: %s=\"%s\"\n", tag->bit_name, tag->bit_val);
-}
-
-static inline void DEB_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%0Lx\"\n", dev->bid_devno);
- printf(" dev: ID=\"%u\"\n", dev->bid_id);
- printf(" dev: TIME=\"%lu\"\n", dev->bid_time);
- printf(" dev: size = %Lu\n", dev->bid_size);
- printf(" dev: flags = 0x%08X\n", dev->bid_flags);
-
- list_for_each(p, &dev->bid_tags) {
- blkid_tag *tag = list_entry(p, blkid_tag, bit_tags);
- DEB_DUMP_TAG(tag);
- }
- printf("\n");
-}
+/* dev.c */
+extern const char *blkid_devname_name(blkid_dev dev);
-static inline void DEB_DUMP_CACHE(blkid_cache *cache)
-{
- struct list_head *p;
+typedef struct blkid_struct_dev_iterate *blkid_dev_iterate;
+extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache);
+extern int blkid_dev_next(blkid_dev_iterate iterate, blkid_dev *dev);
+extern void blkid_dev_iterate_end(blkid_dev_iterate iterate);
- if (!cache) {
- printf("cache: NULL\n");
- return;
- }
+/* devname.c */
+extern int blkid_probe_all(blkid_cache *cache);
+extern blkid_dev blkid_get_devname(blkid_cache cache, const char *devname);
- printf("cache: time = %lu\n", cache->bic_time);
- printf("cache: idmax = %u\n", cache->bic_idmax);
- printf("cache: flags = 0x%08X\n", cache->bic_flags);
+/* read.c */
+int blkid_read_cache(blkid_cache *cache, const char *filename);
- list_for_each(p, &cache->bic_devs) {
- blkid_dev *dev = list_entry(p, blkid_dev, bid_devs);
- DEB_DUMP_DEV(dev);
- }
-}
-#else
-#define DEB_DUMP_TAG(tag) do {} while (0)
-#define DEB_DUMP_DEV(dev) do {} while (0)
-#define DEB_DUMP_CACHE(cache) do {} while (0)
-#endif
-
-/*
- * Primitive disk functions: llseek.c, getsize.c
- */
-extern blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence);
-extern blkid_loff_t blkid_get_dev_size(int fd);
-
-/*
- * Getting data from the cache file: read.c
- */
-int blkid_read_cache_line(blkid_cache *cache, blkid_dev **dev_p, char *cp);
-int blkid_read_cache_file(blkid_cache **cache, FILE *file);
-int blkid_read_cache(blkid_cache **cache, const char *filename);
-
-/*
- * Save data to the cache file: save.c
- */
-int blkid_save_cache_file(blkid_cache *cache, FILE *file);
-int blkid_save_cache(blkid_cache *cache, const char *filename);
-
-/*
- * Identify a device by inode name: probe.c
- */
-extern blkid_dev *blkid_devname_to_dev(const char *devname,
- blkid_loff_t size);
-
-/*
- * Locate a device by inode name: devname.c
- */
-extern blkid_dev *blkid_find_devname(blkid_cache *cache, const char *devname);
-extern blkid_dev *blkid_verify_devname(blkid_cache *cache, blkid_dev *dev);
-extern blkid_dev *blkid_get_devname(blkid_cache *cache, const char *devname);
-extern int blkid_probe_all(blkid_cache **cache);
-
-/*
- * Locate a device by device major/minor number: devno.c
- */
-extern char *blkid_devno_to_devname(dev_t devno);
-extern blkid_dev *blkid_find_devno(blkid_cache *cache, dev_t devno);
-extern blkid_dev *blkid_get_devno(blkid_cache *cache, dev_t devno);
-
-/*
- * Functions to create and find a specific tag type: tag.c
- */
-extern blkid_tag *blkid_new_tag(void);
-extern void blkid_free_tag(blkid_tag *tag);
-extern int blkid_create_tag(blkid_dev *dev, blkid_tag **tag,
- const char *name, const char *value,
- const int vlength);
-extern blkid_tag *blkid_token_to_tag(const char *token);
-extern blkid_tag *blkid_find_tv_tags(blkid_tag *head, const char *value);
-extern blkid_tag *blkid_find_tag_dev(blkid_dev *dev, blkid_tag *tag);
-extern blkid_tag *blkid_find_head_cache(blkid_cache *cache, blkid_tag *tag);
-extern blkid_tag *blkid_find_tag_cache(blkid_cache *cache, blkid_tag *tag);
-extern blkid_tag *blkid_get_tag_cache(blkid_cache *cache, blkid_tag *tag);
-
-/*
- * Functions to create and find a specific tag type: dev.c
- */
-extern blkid_dev *blkid_new_dev(void);
-extern void blkid_free_dev(blkid_dev *dev);
-extern blkid_dev *blkid_add_dev_to_cache(blkid_cache *cache, blkid_dev *dev);
-
-/*
- * Helper functions for primarily single use: resolve.c
- */
-extern char *blkid_get_tagname_devname(blkid_cache *cache, const char *tagname,
+/* resolve.c */
+extern char *blkid_get_tagname_devname(blkid_cache cache, const char *tagname,
const char *devname);
-extern char *blkid_get_token(blkid_cache *cache, const char *token,
+extern char *blkid_get_token(blkid_cache cache, const char *token,
const char *value);
+/* save.c */
+extern int blkid_save_cache(blkid_cache cache, const char *filename);
+
+/* tag.c */
+typedef struct blkid_struct_tag_iterate *blkid_tag_iterate;
+extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev);
+extern int blkid_tag_next(blkid_tag_iterate iterate,
+ const char **type, const char **value);
+extern void blkid_tag_iterate_end(blkid_tag_iterate iterate);
+extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
+ const char *type,
+ const char *value);
+extern int blkid_parse_tag_string(const char *token, char **ret_type,
+ char **ret_val);
+
#ifdef __cplusplus
}
#endif
--- /dev/null
+/*
+ * blkidP.h - Internal interfaces for libblkid
+ *
+ * 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%
+ */
+
+#ifndef _BLKID_BLKIDP_H
+#define _BLKID_BLKIDP_H
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#include <blkid/blkid.h>
+
+#include <blkid/list.h>
+#include <blkid/blkid_types.h>
+
+typedef __s64 blkid_loff_t;
+
+/*
+ * This describes the attributes of a specific device.
+ * We can traverse all of the tags by bid_tags (linking to the tag bit_names).
+ * The bid_label and bid_uuid fields are shortcuts to the LABEL and UUID tag
+ * values, if they exist.
+ */
+struct blkid_struct_dev
+{
+ struct list_head bid_devs; /* All devices in the cache */
+ struct list_head bid_tags; /* All tags for this device */
+ char *bid_name; /* Device inode pathname */
+ char *bid_type; /* Preferred device TYPE */
+ blkid_loff_t bid_size; /* Filesystem size in bytes */
+ blkid_loff_t bid_free; /* Filesystem free in bytes */
+ blkid_loff_t bid_devsize; /* Device size in bytes */
+ dev_t bid_devno; /* Device major/minor number */
+ time_t bid_time; /* Last update time of device */
+ unsigned int bid_id; /* Unique cache id for device */
+ unsigned int bid_flags; /* Device status bitflags */
+ char *bid_label; /* Shortcut to device LABEL */
+ char *bid_uuid; /* Shortcut to binary UUID */
+};
+
+#define BLKID_BID_FL_VERIFIED 0x0001 /* Device data validated from disk */
+#define BLKID_BID_FL_MTYPE 0x0002 /* Device has multiple type matches */
+
+/*
+ * Each tag defines a NAME=value pair for a particular device. The tags
+ * are linked via bit_names for a single device, so that traversing the
+ * names list will get you a list of all tags associated with a device.
+ * They are also linked via bit_values for all devices, so one can easily
+ * search all tags with a given NAME for a specific value.
+ */
+struct blkid_struct_tag
+{
+ struct list_head bit_tags; /* All tags for this device */
+ struct list_head bit_names; /* All tags with given NAME */
+ char *bit_name; /* NAME of tag (shared) */
+ char *bit_val; /* value of tag */
+ blkid_dev bit_dev; /* pointer to device */
+};
+
+/*
+ * Minimum number of seconds between device probes, even when reading
+ * from the cache. This is to avoid re-probing all devices which were
+ * just probed by another program that does not share the cache.
+ */
+#define BLKID_PROBE_MIN 2
+
+/*
+ * Time in seconds an entry remains verified in the in-memory cache
+ * before being reverified (in case of long-running processes that
+ * keep a cache in memory and continue to use it for a long time).
+ */
+#define BLKID_PROBE_INTERVAL 200
+
+/* This describes an entire blkid cache file and probed devices.
+ * We can traverse all of the found devices via bic_list.
+ * We can traverse all of the tag types by bic_tags, which hold empty tags
+ * for each tag type. Those tags can be used as list_heads for iterating
+ * through all devices with a specific tag type (e.g. LABEL).
+ */
+struct blkid_struct_cache
+{
+ struct list_head bic_devs; /* List head of all devices */
+ struct list_head bic_tags; /* List head of all tag types */
+ time_t bic_time; /* Last probe time */
+ unsigned int bic_idmax; /* Highest ID assigned */
+ unsigned int bic_flags; /* Status flags of the cache */
+};
+
+#define BLKID_BIC_FL_PARSED 0x0001 /* We parsed a cache file */
+#define BLKID_BIC_FL_PROBED 0x0002 /* We probed /proc/partition devices */
+#define BLKID_BIC_FL_CHANGED 0x0004 /* Cache has changed from disk */
+
+extern char *string_copy(const char *s);
+extern char *stringn_copy(const char *s, const int length);
+extern void string_free(char *s);
+extern blkid_cache blkid_new_cache(void);
+
+#define BLKID_CACHE_FILE "/etc/blkid.tab"
+extern const char *devdirs[];
+
+#define BLKID_ERR_IO 5
+#define BLKID_ERR_PROC 9
+#define BLKID_ERR_MEM 12
+#define BLKID_ERR_CACHE 14
+#define BLKID_ERR_DEV 19
+#define BLKID_ERR_PARAM 22
+#define BLKID_ERR_BIG 27
+
+#ifdef DEBUG
+#define DEBUG_CACHE
+#define DEBUG_DUMP
+#define DEBUG_DEV
+#define DEBUG_DEVNAME
+#define DEBUG_DEVNO
+#define DEBUG_PROBE
+#define DEBUG_READ
+#define DEBUG_RESOLVE
+#define DEBUG_SAVE
+#define DEBUG_TAG
+#define CHECK_TAG
+#endif
+
+#if defined(TEST_PROGRAM) && !defined(DEBUG_DUMP)
+#define DEBUG_DUMP
+#endif
+
+#ifdef DEBUG_DUMP
+static inline void DEB_DUMP_TAG(blkid_tag tag)
+{
+ if (!tag) {
+ printf(" tag: NULL\n");
+ return;
+ }
+
+ printf(" tag: %s=\"%s\"\n", tag->bit_name, tag->bit_val);
+}
+
+static inline void DEB_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%0Lx\"\n", dev->bid_devno);
+ printf(" dev: ID=\"%u\"\n", dev->bid_id);
+ printf(" dev: TIME=\"%lu\"\n", dev->bid_time);
+ printf(" dev: size = %Lu\n", dev->bid_size);
+ printf(" dev: flags = 0x%08X\n", dev->bid_flags);
+
+ list_for_each(p, &dev->bid_tags) {
+ blkid_tag tag = list_entry(p, struct blkid_stuct_tag, bit_tags);
+ DEB_DUMP_TAG(tag);
+ }
+ printf("\n");
+}
+
+static inline void DEB_DUMP_CACHE(blkid_cache cache)
+{
+ struct list_head *p;
+
+ if (!cache) {
+ printf("cache: NULL\n");
+ return;
+ }
+
+ printf("cache: time = %lu\n", cache->bic_time);
+ printf("cache: idmax = %u\n", cache->bic_idmax);
+ 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);
+ DEB_DUMP_DEV(dev);
+ }
+}
+#else
+#define DEB_DUMP_TAG(tag) do {} while (0)
+#define DEB_DUMP_DEV(dev) do {} while (0)
+#define DEB_DUMP_CACHE(cache) do {} while (0)
+#endif
+
+/*
+ * Primitive disk functions: llseek.c, getsize.c
+ */
+extern blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence);
+extern blkid_loff_t blkid_get_dev_size(int fd);
+
+/*
+ * Getting data from the cache file: read.c
+ */
+int blkid_read_cache_line(blkid_cache cache, blkid_dev *dev_p, char *cp);
+int blkid_read_cache_file(blkid_cache *cache, FILE *file);
+
+/*
+ * Save data to the cache file: save.c
+ */
+int blkid_save_cache_file(blkid_cache cache, FILE *file);
+
+/*
+ * Identify a device by inode name: probe.c
+ */
+extern blkid_dev blkid_devname_to_dev(const char *devname,
+ blkid_loff_t size);
+
+/*
+ * Locate a device by inode name: devname.c
+ */
+extern blkid_dev blkid_find_devname(blkid_cache cache, const char *devname);
+extern blkid_dev blkid_verify_devname(blkid_cache cache, blkid_dev dev);
+extern blkid_dev blkid_get_devname(blkid_cache cache, const char *devname);
+
+/*
+ * Locate a device by device major/minor number: devno.c
+ */
+extern char *blkid_devno_to_devname(dev_t devno);
+extern blkid_dev blkid_find_devno(blkid_cache cache, dev_t devno);
+extern blkid_dev blkid_get_devno(blkid_cache cache, dev_t devno);
+
+/*
+ * Functions to create and find a specific tag type: tag.c
+ */
+extern blkid_tag blkid_new_tag(void);
+extern void blkid_free_tag(blkid_tag tag);
+extern int blkid_create_tag(blkid_dev dev, blkid_tag *tag,
+ const char *name, const char *value,
+ const int vlength);
+extern blkid_tag blkid_token_to_tag(const char *token);
+extern blkid_tag blkid_find_tv_tags(blkid_tag head, const char *value);
+extern blkid_tag blkid_find_tag_dev(blkid_dev dev, blkid_tag tag);
+extern blkid_tag blkid_find_head_cache(blkid_cache cache, blkid_tag tag);
+extern blkid_tag blkid_find_tag_cache(blkid_cache cache, blkid_tag tag);
+extern blkid_tag blkid_get_tag_cache(blkid_cache cache, blkid_tag tag);
+
+/*
+ * Functions to create and find a specific tag type: dev.c
+ */
+extern blkid_dev blkid_new_dev(void);
+extern void blkid_free_dev(blkid_dev dev);
+extern blkid_dev blkid_add_dev_to_cache(blkid_cache cache, blkid_dev dev);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLKID_BLKIDP_H */
*/
#include <stdlib.h>
-#include "blkid/blkid.h"
+#include "blkidP.h"
#ifdef DEBUG_CACHE
#include <stdio.h>
#define DBG(x)
#endif
-blkid_cache *blkid_new_cache(void)
+blkid_cache blkid_new_cache(void)
{
- blkid_cache *cache;
+ blkid_cache cache;
- if (!(cache = (blkid_cache *)calloc(1, sizeof(blkid_cache))))
+ if (!(cache = (blkid_cache) calloc(1, sizeof(struct blkid_struct_cache))))
return NULL;
INIT_LIST_HEAD(&cache->bic_devs);
return cache;
}
-void blkid_free_cache(blkid_cache *cache)
+void blkid_free_cache(blkid_cache cache)
{
if (!cache)
return;
/* DEB_DUMP_CACHE(cache); */
while (!list_empty(&cache->bic_devs)) {
- blkid_dev *dev = list_entry(cache->bic_devs.next, blkid_dev,
+ 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, blkid_tag,
- bit_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,
- blkid_tag, bit_names);
+ blkid_tag bad = list_entry(tag->bit_names.next,
+ struct blkid_struct_tag,
+ bit_names);
DBG(printf("warning: unfreed tag %s=%s\n",
bad->bit_name, bad->bit_val));
#ifdef TEST_PROGRAM
int main(int argc, char** argv)
{
- blkid_cache *cache = NULL;
+ blkid_cache cache = NULL;
int ret;
if ((argc > 2)) {
#include <stdlib.h>
#include <string.h>
-#include "blkid/blkid.h"
+#include "blkidP.h"
#ifdef DEBUG_DEV
#include <stdio.h>
#define DBG(x)
#endif
-blkid_dev *blkid_new_dev(void)
+blkid_dev blkid_new_dev(void)
{
- blkid_dev *dev;
+ blkid_dev dev;
- if (!(dev = (blkid_dev *)calloc(1, sizeof(blkid_dev))))
+ if (!(dev = (blkid_dev) calloc(1, sizeof(struct blkid_struct_dev))))
return NULL;
INIT_LIST_HEAD(&dev->bid_devs);
return dev;
}
-void blkid_free_dev(blkid_dev *dev)
+void blkid_free_dev(blkid_dev dev)
{
if (!dev)
return;
list_del(&dev->bid_devs);
while (!list_empty(&dev->bid_tags)) {
- blkid_tag *tag = list_entry(dev->bid_tags.next, blkid_tag,
- bit_tags);
+ blkid_tag tag = list_entry(dev->bid_tags.next,
+ struct blkid_struct_tag,
+ bit_tags);
blkid_free_tag(tag);
}
if (dev->bid_name)
/*
* Add a tag to the global cache tag list.
*/
-static int add_tag_to_cache(blkid_cache *cache, blkid_tag *tag)
+static int add_tag_to_cache(blkid_cache cache, blkid_tag tag)
{
- blkid_tag *head = NULL;
+ blkid_tag head = NULL;
if (!cache || !tag)
return 0;
}
/*
+ * Given a blkid device, return its name
+ */
+extern const char *blkid_devname_name(blkid_dev dev)
+{
+ return dev->bid_name;
+}
+
+/*
+ * 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 implemenation. 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;
+ 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;
+ }
+ return (iter);
+}
+
+/*
+ * Return 0 on success, -1 on error
+ */
+extern int blkid_dev_next(blkid_dev_iterate iter,
+ blkid_dev *dev)
+{
+ *dev = 0;
+ if (!iter || iter->magic != DEV_ITERATE_MAGIC ||
+ iter->p == &iter->cache->bic_devs)
+ return -1;
+ *dev = list_entry(iter->p, struct blkid_struct_dev, bid_devs);
+ iter->p = iter->p->next;
+ return 0;
+}
+
+extern void blkid_dev_iterate_end(blkid_dev_iterate iter)
+{
+ if (!iter || iter->magic != DEV_ITERATE_MAGIC)
+ return;
+ iter->magic = 0;
+ free(iter);
+}
+
+/*
* Add a device to the global cache list, along with all its tags.
*/
-blkid_dev *blkid_add_dev_to_cache(blkid_cache *cache, blkid_dev *dev)
+blkid_dev blkid_add_dev_to_cache(blkid_cache cache, blkid_dev dev)
{
struct list_head *p;
dev->bid_id = ++(cache->bic_idmax);
list_for_each(p, &cache->bic_devs) {
- blkid_dev *odev = list_entry(p, blkid_dev, bid_devs);
+ blkid_dev odev = list_entry(p, struct blkid_struct_dev, bid_devs);
int dup_uuid, dup_label, dup_name, dup_type;
dup_name = string_compare(odev->bid_name, dev->bid_name);
list_add_tail(&dev->bid_devs, &cache->bic_devs);
list_for_each(p, &dev->bid_tags) {
- blkid_tag *tag = list_entry(p, blkid_tag, bit_tags);
+ blkid_tag tag = list_entry(p, struct blkid_struct_tag,
+ bit_tags);
add_tag_to_cache(cache, tag);
}
return dev;
#ifdef TEST_PROGRAM
int main(int argc, char** argv)
{
- blkid_cache *cache;
- blkid_dev *dev, *newdev;
+ blkid_cache cache;
+ blkid_dev dev, newdev;
if ((argc != 3)) {
fprintf(stderr, "Usage:\t%s dev1 dev2\n"
#endif
#include <time.h>
-#include "blkid/blkid.h"
+#include "blkidP.h"
/* #define DEBUG_DEVNAME */
#ifdef DEBUG_DEVNAME
/*
* Find a dev struct in the cache by device name, if available.
*/
-blkid_dev *blkid_find_devname(blkid_cache *cache, const char *devname)
+blkid_dev blkid_find_devname(blkid_cache cache, const char *devname)
{
- blkid_dev *dev = NULL;
+ blkid_dev dev = NULL;
struct list_head *p;
if (!cache || !devname)
return NULL;
list_for_each(p, &cache->bic_devs) {
- blkid_dev *tmp = list_entry(p, blkid_dev, bid_devs);
+ blkid_dev tmp = list_entry(p, struct blkid_struct_dev, bid_devs);
if (strcmp(tmp->bid_name, devname))
continue;
/*
* Return a pointer to an dev struct, either from cache or by probing.
*/
-blkid_dev *blkid_get_devname(blkid_cache *cache, const char *devname)
+blkid_dev blkid_get_devname(blkid_cache cache, const char *devname)
{
- blkid_dev *dev;
+ blkid_dev dev;
if ((dev = blkid_find_devname(cache, devname)))
return dev;
* Probe a single block device to add to the device cache.
* If the size is not specified, it will be found in blkid_devname_to_dev().
*/
-static blkid_dev *probe_one(blkid_cache *cache, const char *ptname,
+static blkid_dev probe_one(blkid_cache cache, const char *ptname,
int major, int minor, unsigned long long size)
{
dev_t devno = makedev(major, minor);
- blkid_dev *dev;
+ blkid_dev dev;
const char **dir;
char *devname = NULL;
return ret;
}
-static void lvm_probe_all(blkid_cache **cache)
+static void lvm_probe_all(blkid_cache *cache)
{
DIR *vg_list;
struct dirent *vg_iter;
#define PROC_EVMS_VOLUMES "/proc/evms/volumes"
static int
-evms_probe_all(blkid_cache **cache)
+evms_probe_all(blkid_cache *cache)
{
char line[100];
int ma, mi, sz, num = 0;
/*
* Read the device data for all available block devices in the system.
*/
-int blkid_probe_all(blkid_cache **cache)
+int blkid_probe_all(blkid_cache *cache)
{
FILE *proc;
int firstPass;
#ifdef TEST_PROGRAM
int main(int argc, char **argv)
{
- blkid_cache *cache = NULL;
+ blkid_cache cache = NULL;
if (argc != 1) {
fprintf(stderr, "Usage: %s\n"
#include <sys/mkdev.h>
#endif
-#include "blkid/blkid.h"
+#include "blkidP.h"
#ifdef DEBUG_DEVNO
#define DBG(x) x
return devname;
}
-blkid_dev *blkid_find_devno(blkid_cache *cache, dev_t devno)
+blkid_dev blkid_find_devno(blkid_cache cache, dev_t devno)
{
- blkid_dev *dev = NULL;
+ blkid_dev dev = NULL;
struct list_head *p, *n;
if (!cache)
* would point to freed memory.
*/
list_for_each_safe(p, n, &cache->bic_devs) {
- blkid_dev *tmp = list_entry(p, blkid_dev, bid_devs);
+ blkid_dev tmp = list_entry(p, struct blkid_struct_dev, bid_devs);
if (tmp->bid_devno != devno)
continue;
return dev;
}
-blkid_dev *blkid_get_devno(blkid_cache *cache, dev_t devno)
+blkid_dev blkid_get_devno(blkid_cache cache, dev_t devno)
{
char *devname;
- blkid_dev *dev;
+ blkid_dev dev;
if (!(dev = blkid_find_devno(cache, devno)) &&
(devname = blkid_devno_to_devname(devno))) {
#include <sys/disklabel.h>
#endif /* HAVE_SYS_DISKLABEL_H */
-#include "blkid/blkid.h"
+#include "blkidP.h"
#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
#define BLKGETSIZE _IO(0x12,96) /* return device size */
#include <io.h>
#endif
-#include "blkid/blkid.h"
+#include "blkidP.h"
#ifdef __linux__
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
-#include "blkid/blkid.h"
+#include "blkidP.h"
#include "uuid/uuid.h"
#include "probe.h"
* The devname, dev_p, and id fields are required. The buf is
* a buffer to return superblock data in.
*/
-static int probe_default(int fd, blkid_dev **dev_p, const char *devname,
+static int probe_default(int fd, blkid_dev *dev_p, const char *devname,
struct blkid_magic *id, unsigned char *buf,
blkid_loff_t size)
{
blkid_loff_t offset;
- blkid_dev *dev;
+ blkid_dev dev;
struct stat st;
int ret;
return ret;
}
-static int probe_ext2(int fd, blkid_dev **dev_p, const char *devname,
+static int probe_ext2(int fd, blkid_dev *dev_p, const char *devname,
struct blkid_magic *id, unsigned char *buf,
blkid_loff_t size)
{
- blkid_dev *dev;
+ blkid_dev dev;
struct ext2_super_block *es;
int ret;
return 0;
}
-static int probe_jbd(int fd, blkid_dev **dev_p, const char *devname,
+static int probe_jbd(int fd, blkid_dev *dev_p, const char *devname,
struct blkid_magic *id, unsigned char *buf,
blkid_loff_t size)
{
- blkid_dev *dev;
+ blkid_dev dev;
struct ext2_super_block *es;
int ret;
return 0;
}
-static int probe_ext3(int fd, blkid_dev **dev_p, const char *devname,
+static int probe_ext3(int fd, blkid_dev *dev_p, const char *devname,
struct blkid_magic *id, unsigned char *buf,
blkid_loff_t size)
{
- blkid_dev *dev;
+ blkid_dev dev;
struct ext2_super_block *es;
int ret;
return 0;
}
-static int probe_vfat(int fd, blkid_dev **dev_p, const char *devname,
+static int probe_vfat(int fd, blkid_dev *dev_p, const char *devname,
struct blkid_magic *id, unsigned char *buf,
blkid_loff_t size)
{
- blkid_dev *dev;
+ blkid_dev dev;
struct vfat_super_block *vs;
char serno[10];
blkid_loff_t sectors;
return 0;
}
-static int probe_msdos(int fd, blkid_dev **dev_p, const char *devname,
+static int probe_msdos(int fd, blkid_dev *dev_p, const char *devname,
struct blkid_magic *id, unsigned char *buf,
blkid_loff_t size)
{
- blkid_dev *dev;
+ blkid_dev dev;
struct msdos_super_block *ms;
char serno[10];
int cluster_size;
return 0;
}
-static int probe_xfs(int fd, blkid_dev **dev_p, const char *devname,
+static int probe_xfs(int fd, blkid_dev *dev_p, const char *devname,
struct blkid_magic *id, unsigned char *buf,
blkid_loff_t size)
{
- blkid_dev *dev;
+ blkid_dev dev;
struct xfs_super_block *xs;
int ret;
return 0;
}
-static int probe_reiserfs(int fd, blkid_dev **dev_p, const char *devname,
+static int probe_reiserfs(int fd, blkid_dev *dev_p, const char *devname,
struct blkid_magic *id, unsigned char *buf,
blkid_loff_t size)
{
- blkid_dev *dev;
+ blkid_dev dev;
struct reiserfs_super_block *rs;
unsigned int blocksize;
int ret;
return 0;
}
-static int probe_minix(int fd, blkid_dev **dev_p, const char *devname,
+static int probe_minix(int fd, blkid_dev *dev_p, const char *devname,
struct blkid_magic *id, unsigned char *buf,
blkid_loff_t size)
{
- blkid_dev *dev;
+ blkid_dev dev;
struct minix_super_block *ms;
int ret;
return 0;
}
-static int probe_swap(int fd, blkid_dev **dev_p, const char *devname,
+static int probe_swap(int fd, blkid_dev *dev_p, const char *devname,
struct blkid_magic *id, unsigned char *buf,
blkid_loff_t size)
{
- blkid_dev *dev;
+ blkid_dev dev;
struct swap_header *sh;
int psize;
int ret;
return 0;
}
-static int probe_mdraid(int fd, blkid_dev **dev_p, const char *devname,
+static int probe_mdraid(int fd, blkid_dev *dev_p, const char *devname,
struct blkid_magic *id, unsigned char *buf,
blkid_loff_t size)
{
- blkid_dev *dev;
+ blkid_dev dev;
struct mdp_superblock_s *md;
int ret;
return 0;
}
-static int probe_hfs(int fd, blkid_dev **dev_p, const char *devname,
+static int probe_hfs(int fd, blkid_dev *dev_p, const char *devname,
struct blkid_magic *id, unsigned char *buf,
blkid_loff_t size)
{
- blkid_dev *dev;
+ blkid_dev dev;
struct hfs_super_block *hfs;
int ret;
* Return a blkid_dev with at least the device type and size set.
* If the passed-in size is zero, then we get the device size here.
*/
-blkid_dev *blkid_devname_to_dev(const char *devname, blkid_loff_t size)
+blkid_dev blkid_devname_to_dev(const char *devname, blkid_loff_t size)
{
unsigned char *buf_array[BLKID_BLK_OFFS * 2 + 1];
unsigned char **bufs = buf_array + BLKID_BLK_OFFS;
- blkid_dev *dev = NULL, *last = NULL;
+ blkid_dev dev = NULL, last = NULL;
unsigned char *sb_buf = NULL;
int sb_size = 0;
struct blkid_magic *id = NULL;
* If we are unable to revalidate the data, we return the old data and
* do not set the BLKID_BID_FL_VERIFIED flag on it.
*/
-blkid_dev *blkid_verify_devname(blkid_cache *cache, blkid_dev *dev)
+blkid_dev blkid_verify_devname(blkid_cache cache, blkid_dev dev)
{
blkid_loff_t size;
struct blkid_magic *id;
- blkid_dev *new = NULL;
+ blkid_dev new = NULL;
unsigned char *sb_buf = NULL;
int sb_size = 0;
time_t diff;
#ifdef TEST_PROGRAM
int main(int argc, char **argv)
{
- blkid_dev *dev;
+ blkid_dev dev;
if (argc != 2) {
fprintf(stderr, "Usage: %s device\n"
struct blkid_magic;
-typedef int (*blkid_probe_t)(int fd, blkid_dev **dev_p, const char *devname,
+typedef int (*blkid_probe_t)(int fd, blkid_dev *dev_p, const char *devname,
struct blkid_magic *id, unsigned char *buf,
blkid_loff_t size);
#include <errno.h>
#endif
-#include "blkid/blkid.h"
+#include "blkidP.h"
#include "uuid/uuid.h"
#ifdef DEBUG_CACHE
* <device foo=bar>devname</device>
* <device>devname<foo>bar</foo></device>
*/
-static int parse_dev(blkid_dev **dev, char **cp)
+static int parse_dev(blkid_dev *dev, char **cp)
{
char **name;
char *start, *tmp, *end;
* Return 0 if no tag found.
* Return -ve error code.
*/
-static int parse_tag(blkid_cache *cache, blkid_dev *dev, blkid_tag **tag,
+static int parse_tag(blkid_cache cache, blkid_dev dev, blkid_tag *tag,
char **cp)
{
char *name;
* 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)
+static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp)
{
- blkid_dev *dev;
- blkid_tag *tag;
+ blkid_dev dev;
+ blkid_tag tag;
int ret;
if (!cache || !dev_p)
*
* Returns 0 on success, or -ve error value.
*/
-int blkid_read_cache_file(blkid_cache **cache, FILE *file)
+int blkid_read_cache_file(blkid_cache *cache, FILE *file)
{
char buf[4096];
int lineno = 0;
return -BLKID_ERR_MEM;
while (fgets(buf, sizeof(buf), file)) {
- blkid_dev *dev;
+ blkid_dev dev;
int end = strlen(buf) - 1;
* a newly allocated cache struct. If the file doesn't exist, return a
* new empty cache struct.
*/
-int blkid_read_cache(blkid_cache **cache, const char *filename)
+int blkid_read_cache(blkid_cache *cache, const char *filename)
{
FILE *file;
int ret;
#ifdef TEST_PROGRAM
int main(int argc, char**argv)
{
- blkid_cache *cache = NULL;
+ blkid_cache cache = NULL;
int ret;
if (argc > 2) {
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include "blkid/blkid.h"
+#include "blkidP.h"
#include "probe.h"
#ifdef DEBUG_RESOLVE
/*
* Find a tagname (e.g. LABEL or UUID) on a specific device.
*/
-char *blkid_get_tagname_devname(blkid_cache *cache, const char *tagname,
+char *blkid_get_tagname_devname(blkid_cache cache, const char *tagname,
const char *devname)
{
- blkid_tag *tag, *found;
- blkid_dev *dev;
+ blkid_tag tag, found;
+ blkid_dev dev;
char *ret = NULL;
DBG(printf("looking for %s on %s\n", tagname, devname));
*
* The string returned must be freed with string_free().
*/
-char *blkid_get_token(blkid_cache *cache, const char *token,
+char *blkid_get_token(blkid_cache cache, const char *token,
const char *value)
{
- blkid_tag *tag = NULL, *found = NULL;
- blkid_cache *c = cache;
+ blkid_tag tag = NULL, found = NULL;
+ blkid_cache c = cache;
char *name = NULL;
DBG(printf("looking for %s%c%s %s\n", token, value ? '=' : ' ',
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
-#include "blkid/blkid.h"
+#include "blkidP.h"
#ifdef DEBUG_SAVE
#define DBG(x) x
#define DBG(x)
#endif
-static int save_dev(blkid_dev *dev, FILE *file)
+static int save_dev(blkid_dev dev, FILE *file)
{
struct list_head *p;
dev->bid_type, (unsigned long) dev->bid_devno,
dev->bid_id, dev->bid_time);
list_for_each(p, &dev->bid_tags) {
- blkid_tag *tag = list_entry(p, blkid_tag, bit_tags);
+ blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
if (strcmp(tag->bit_name, "TYPE"))
fprintf(file, " %s=\"%s\"", tag->bit_name,tag->bit_val);
}
return 0;
}
-int blkid_save_cache_file(blkid_cache *cache, FILE *file)
+int blkid_save_cache_file(blkid_cache cache, FILE *file)
{
struct list_head *p;
int ret = 0;
return 0;
list_for_each(p, &cache->bic_devs) {
- blkid_dev *dev = list_entry(p, blkid_dev, bid_devs);
+ blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
if ((ret = save_dev(dev, file)) < 0)
break;
}
/*
* Write out the cache struct to the cache file on disk.
*/
-int blkid_save_cache(blkid_cache *cache, const char *filename)
+int blkid_save_cache(blkid_cache cache, const char *filename)
{
char *tmp = NULL;
const char *opened = NULL;
#ifdef TEST_PROGRAM
int main(int argc, char **argv)
{
- blkid_cache *cache = NULL;
+ blkid_cache cache = NULL;
int ret;
if (argc > 2) {
#include <string.h>
#include <stdio.h>
-#include "blkid/blkid.h"
+#include "blkidP.h"
#ifdef DEBUG_TAG
#define DBG(x) x
#define DBG(x)
#endif
-blkid_tag *blkid_new_tag(void)
+blkid_tag blkid_new_tag(void)
{
- blkid_tag *tag;
+ blkid_tag tag;
- if (!(tag = (blkid_tag *)calloc(1, sizeof(blkid_tag))))
+ if (!(tag = (blkid_tag) calloc(1, sizeof(struct blkid_struct_tag))))
return NULL;
INIT_LIST_HEAD(&tag->bit_tags);
return tag;
}
-void blkid_free_tag(blkid_tag *tag)
+void blkid_free_tag(blkid_tag tag)
{
if (!tag)
return;
/*
* Find the desired tag on a list of tags with the same type.
*/
-blkid_tag *blkid_find_tv_tags(blkid_tag *head, const char *value)
+blkid_tag blkid_find_tv_tags(blkid_tag head, const char *value)
{
- struct blkid_tag *tag = NULL;
+ struct blkid_struct_tag *tag = NULL;
struct list_head *p;
if (!head || !value)
DBG(printf("looking for %s in %s list\n", value, head->bit_name));
list_for_each(p, &head->bit_names) {
- blkid_tag *tmp = list_entry(p, blkid_tag, bit_names);
+ blkid_tag tmp = list_entry(p, struct blkid_struct_tag,
+ bit_names);
if (!strcmp(tmp->bit_val, value)) {
tag = tmp;
* Find the desired tag on a device. If tag->bit_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, blkid_tag *tag)
+blkid_tag blkid_find_tag_dev(blkid_dev dev, blkid_tag tag)
{
- blkid_tag *found = NULL;
+ blkid_tag found = NULL;
struct list_head *p;
if (!dev || !tag)
return NULL;
list_for_each(p, &dev->bid_tags) {
- blkid_tag *tmp = list_entry(p, blkid_tag, bit_tags);
+ blkid_tag tmp = list_entry(p, struct blkid_struct_tag, bit_tags);
if (!strcmp(tmp->bit_name, tag->bit_name) &&
(!tag->bit_val || !strcmp(tmp->bit_val, tag->bit_val))){
* Find the desired tag type in the cache.
* We return the head tag for this tag type.
*/
-blkid_tag *blkid_find_head_cache(blkid_cache *cache, blkid_tag *tag)
+blkid_tag blkid_find_head_cache(blkid_cache cache, blkid_tag tag)
{
- blkid_tag *head = NULL;
+ blkid_tag head = NULL;
struct list_head *p;
if (!cache || !tag)
return NULL;
list_for_each(p, &cache->bic_tags) {
- blkid_tag *tmp = list_entry(p, blkid_tag, bit_tags);
+ blkid_tag tmp = list_entry(p, struct blkid_struct_tag,
+ bit_tags);
if (!strcmp(tmp->bit_name, tag->bit_name)) {
DBG(printf(" found cache tag head %s\n", tag->bit_name));
/*
* Find a specific tag value in the cache. If not found return NULL.
*/
-blkid_tag *blkid_find_tag_cache(blkid_cache *cache, blkid_tag *tag)
+blkid_tag blkid_find_tag_cache(blkid_cache cache, blkid_tag tag)
{
- blkid_tag *head;
+ blkid_tag head;
DBG(printf("looking for %s=%s in cache\n", tag->bit_name, tag->bit_val));
* Get a specific tag value in the cache. If not found return NULL.
* If we have not already probed the devices, do so and search again.
*/
-blkid_tag *blkid_get_tag_cache(blkid_cache *cache, blkid_tag *tag)
+blkid_tag blkid_get_tag_cache(blkid_cache cache, blkid_tag tag)
{
- blkid_tag *head, *found;
+ blkid_tag head, found;
if (!tag || !cache)
return NULL;
* the future it may be desirable to allow adding arbitrary tags to a device,
* and ensure that verify keeps all such tags (maybe lower case tag names?)
*/
-static void add_tag_to_dev(blkid_dev *dev, blkid_tag *tag)
+static void add_tag_to_dev(blkid_dev dev, blkid_tag tag)
{
if (!dev)
return;
* if an identical tag does not already exist.
* If tag is valid, the tag will be returned in this pointer.
*/
-int blkid_create_tag(blkid_dev *dev, blkid_tag **tag, const char *name,
+int blkid_create_tag(blkid_dev dev, blkid_tag *tag, const char *name,
const char *value, const int vlength)
{
- blkid_tag *t, *found;
+ blkid_tag t, found;
if (!tag && !dev)
return -BLKID_ERR_PARAM;
}
/*
- * Convert a NAME=value pair into a token. This is slightly different than
+ * 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 al alreay quoted string from the command-line we don't
- * have to both quote and escape quote so that the quotes make it to us).
+ * have to both quote and escape quote so that the quotes make it to
+ * us).
+ *
+ * Returns 0 on success, and -1 on failure.
*/
-blkid_tag *blkid_token_to_tag(const char *token)
+int blkid_parse_tag_string(const char *token, char **ret_type, char **ret_val)
{
char *name, *value, *cp;
- blkid_tag *tag = NULL;
- int len;
- DBG(printf("trying to make '%s' into a tag\n", token));
+ DBG(printf("trying to parse '%s' as a tag\n", token));
+
if (!token || !(cp = strchr(token, '=')))
- return NULL;
+ return -1;
name = string_copy(token);
+ if (!name)
+ return -1;
value = name + (cp - token);
*value++ = '\0';
if (*value == '"' || *value == '\'') {
char c = *value++;
- if (!(cp = strrchr(value, c))) {
- fprintf(stderr, "Missing close quote for %s\n", token);
- return NULL;
- }
+ if (!(cp = strrchr(value, c)))
+ goto errout; /* missing closing quote */
*cp = '\0';
- len = cp - value;
- } else
- len = strlen(value);
+ }
+ value = string_copy(value);
+ if (!value)
+ goto errout;
- blkid_create_tag(NULL, &tag, name, value, len);
+ *ret_type = name;
+ *ret_val = value;
+ return 0;
+
+errout:
string_free(name);
+ return -1;
+}
+
+/*
+ * Convert a NAME=value pair into a token.
+ */
+blkid_tag blkid_token_to_tag(const char *token)
+{
+ char *name, *value;
+ blkid_tag tag = NULL;
+
+ DBG(printf("trying to make '%s' into a tag\n", token));
+
+ if (blkid_parse_tag_string(token, &name, &value) != 0)
+ return NULL;
+
+ blkid_create_tag(NULL, &tag, name, value, sizeof(value));
+
+ string_free(name);
+ string_free(value);
return tag;
}
+
+
+/*
+ * 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 implemenation. 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. Its behaviour is currently undefined if there is
+ * more than one device which matches the search specification.
+ * In the future we may have some kind of preference scheme so that if
+ * there is more than one match for a given label/uuid (for example in
+ * the case of snapshots) we return the preferred device.
+ *
+ * XXX there should also be an interface which uses an iterator so we
+ * can get all of the devices which match a type/value search parameter.
+ */
+extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
+ const char *type,
+ const char *value)
+{
+ blkid_tag tag = NULL, found;
+
+ blkid_create_tag(NULL, &tag, type, value, strlen(value));
+ found = blkid_get_tag_cache(cache, tag);
+ blkid_free_tag(tag);
+ return (found ? found->bit_dev : NULL);
+}
+2003-01-26 Theodore Ts'o <tytso@mit.edu>
+
+ * blkid.c (main): Modify blkid to use the new libblkid public
+ interfaces.
+
2003-01-23 Theodore Ts'o <tytso@mit.edu>
* Makefile.in: Integrate in new blkid library.
*/
#include <stdio.h>
+#include <stdlib.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
#include "blkid/blkid.h"
-char *progname = "blkid";
-void print_version(FILE *out)
+const char *progname = "blkid";
+
+static void print_version(FILE *out)
{
fprintf(stderr, "%s %s (%s)\n", progname, BLKID_VERSION, BLKID_DATE);
}
-void usage(int error)
+static void usage(int error)
{
FILE *out = error ? stderr : stdout;
exit(error);
}
-#define PT_FL_START 0x0001
-#define PT_FL_TYPE 0x0002
-
-static void print_tag(blkid_dev *dev, blkid_tag *tag, int *flags)
-{
- /* Print only one "dev:" per device */
- if (!*flags & PT_FL_START) {
- printf("%s: ", dev->bid_name);
- *flags |= PT_FL_START;
- }
- /* Print only the primary TYPE per device */
- if (!strcmp(tag->bit_name, "TYPE")) {
- if (*flags & PT_FL_TYPE)
- return;
- *flags |= PT_FL_TYPE;
- }
- printf("%s=\"%s\" ", tag->bit_name, tag->bit_val);
-}
-
-void print_tags(blkid_dev *dev, char *show[], int numtag)
+static void print_tags(blkid_dev dev, char *show[], int numtag)
{
- struct list_head *p;
- int flags = 0;
+ blkid_tag_iterate iter;
+ const char *type, *value;
+ int i, first = 1, printed_type = 0;
if (!dev)
return;
- list_for_each(p, &dev->bid_tags) {
- blkid_tag *tag = list_entry(p, blkid_tag, bit_tags);
- int i;
-
- /* Print all tokens if none is specified */
- if (numtag == 0 || !show) {
- print_tag(dev, tag, &flags);
- /* Otherwise, only print specific tokens */
- } else for (i = 0; i < numtag; i++) {
- if (!strcmp(tag->bit_name, show[i]))
- print_tag(dev, tag, &flags);
+ iter = blkid_tag_iterate_begin(dev);
+ while (blkid_tag_next(iter, &type, &value) == 0) {
+ if (numtag && show) {
+ for (i=0; i < numtag; i++)
+ if (!strcmp(type, show[i]))
+ break;
+ if (i >= numtag)
+ continue;
+ }
+ if (first) {
+ printf("%s: ", blkid_devname_name(dev));
+ first = 0;
}
+ if (!strcmp(type, "TYPE")) {
+ if (printed_type)
+ return;
+ printed_type = 1;
+ }
+ printf("%s=\"%s\" ", type, value);
}
+ blkid_tag_iterate_end(iter);
- if (flags)
+ if (!first)
printf("\n");
}
int main(int argc, char **argv)
{
- blkid_cache *cache = NULL;
+ blkid_cache cache = NULL;
char *devices[128] = { NULL, };
char *show[128] = { NULL, };
- blkid_tag *tag = NULL;
+ char *search_type = NULL, *search_value = NULL;
char *read = NULL;
char *write = NULL;
int numdev = 0, numtag = 0;
show[numtag++] = optarg;
break;
case 't':
- if (tag) {
+ if (search_type) {
fprintf(stderr, "Can only search for "
"one NAME=value pair\n");
usage(err);
}
- if (!(tag = blkid_token_to_tag(optarg))) {
+ if (blkid_parse_tag_string(optarg,
+ &search_type,
+ &search_value)) {
fprintf(stderr, "-t needs NAME=value pair\n");
usage(err);
}
err = 2;
/* If looking for a specific NAME=value pair, print only that */
- if (tag) {
- blkid_tag *found = NULL;
+ if (search_type) {
+ blkid_dev dev;
/* Load any additional devices not in the cache */
for (i = 0; i < numdev; i++)
blkid_get_devname(cache, devices[i]);
- if ((found = blkid_get_tag_cache(cache, tag))) {
- print_tags(found->bit_dev, show, numtag);
+ if ((dev = blkid_find_dev_with_tag(cache, search_type,
+ search_value))) {
+ print_tags(dev, show, numtag);
err = 0;
}
/* If we didn't specify a single device, show all available devices */
} else if (!numdev) {
- struct list_head *p;
+ blkid_dev_iterate iter;
+ blkid_dev dev;
blkid_probe_all(&cache);
- list_for_each(p, &cache->bic_devs) {
- blkid_dev *dev = list_entry(p, blkid_dev, bid_devs);
+ iter = blkid_dev_iterate_begin(cache);
+ while (blkid_dev_next(iter, &dev) == 0) {
print_tags(dev, show, numtag);
err = 0;
}
+ blkid_dev_iterate_end(iter);
/* Add all specified devices to cache (optionally display tags) */
} else for (i = 0; i < numdev; i++) {
- blkid_dev *dev = blkid_get_devname(cache, devices[i]);
+ blkid_dev dev = blkid_get_devname(cache, devices[i]);
if (dev) {
print_tags(dev, show, numtag);
}
exit:
- blkid_free_tag(tag);
+ if (search_type)
+ free(search_type);
+ if (search_value)
+ free(search_value);
blkid_save_cache(cache, write);
blkid_free_cache(cache);
return err;