Whamcloud - gitweb
AOSP: Android: consolidate addition of include/mingw/
[tools/e2fsprogs.git] / lib / blkid / dev.c
index 01ca2ea..1d62dd8 100644 (file)
  * %End-Header%
  */
 
+#include "config.h"
 #include <stdlib.h>
 #include <string.h>
+#include <stdint.h>
 
 #include "blkidP.h"
 
-#ifdef DEBUG_DEV
-#include <stdio.h>
-#define DBG(x) x
-#else
-#define DBG(x)
-#endif
-
 blkid_dev blkid_new_dev(void)
 {
        blkid_dev dev;
@@ -40,8 +35,10 @@ void blkid_free_dev(blkid_dev dev)
        if (!dev)
                return;
 
-       DBG(printf("  freeing dev %s (%s)\n", dev->bid_name, dev->bid_type));
-       DEB_DUMP_DEV(dev);
+       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)) {
@@ -50,8 +47,7 @@ void blkid_free_dev(blkid_dev dev)
                                           bit_tags);
                blkid_free_tag(tag);
        }
-       if (dev->bid_name)
-               free(dev->bid_name);
+       free(dev->bid_name);
        free(dev);
 }
 
@@ -63,12 +59,40 @@ 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 implemenation.  I'm not convinced I want
+ * 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
@@ -79,10 +103,12 @@ extern const char *blkid_dev_devname(blkid_dev dev)
  * 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;
 };
 
@@ -95,23 +121,58 @@ extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache)
                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 *dev)
+                         blkid_dev *ret_dev)
 {
-       *dev = 0;
-       if (!iter || iter->magic != DEV_ITERATE_MAGIC ||
-           iter->p == &iter->cache->bic_devs)
+       blkid_dev               dev;
+
+       *ret_dev = 0;
+       if (!iter || iter->magic != DEV_ITERATE_MAGIC)
                return -1;
-       *dev = list_entry(iter->p, struct blkid_struct_dev, bid_devs);
-       iter->p = iter->p->next;
-       return 0;
+       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)
@@ -122,3 +183,72 @@ extern void blkid_dev_iterate_end(blkid_dev_iterate iter)
        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