1 /* 2 * dev.c - allocation/initialization/free routines for dev 3 * 4 * Copyright (C) 2001 Andreas Dilger 5 * Copyright (C) 2003 Theodore Ts'o 6 * 7 * %Begin-Header% 8 * This file may be redistributed under the terms of the 9 * GNU Lesser General Public License. 10 * %End-Header% 11 */ 12 13 #include "config.h" 14 #include <stdlib.h> 15 #include <string.h> 16 #include <stdint.h> 17 18 #include "blkidP.h" 19 20 blkid_dev blkid_new_dev(void) 21 { 22 blkid_dev dev; 23 24 if (!(dev = (blkid_dev) calloc(1, sizeof(struct blkid_struct_dev)))) 25 return NULL; 26 27 INIT_LIST_HEAD(&dev->bid_devs); 28 INIT_LIST_HEAD(&dev->bid_tags); 29 30 return dev; 31 } 32 33 void blkid_free_dev(blkid_dev dev) 34 { 35 if (!dev) 36 return; 37 38 DBG(DEBUG_DEV, 39 printf(" freeing dev %s (%s)\n", dev->bid_name, dev->bid_type ? 40 dev->bid_type : "(null)")); 41 DBG(DEBUG_DEV, blkid_debug_dump_dev(dev)); 42 43 list_del(&dev->bid_devs); 44 while (!list_empty(&dev->bid_tags)) { 45 blkid_tag tag = list_entry(dev->bid_tags.next, 46 struct blkid_struct_tag, 47 bit_tags); 48 blkid_free_tag(tag); 49 } 50 free(dev->bid_name); 51 free(dev); 52 } 53 54 /* 55 * Given a blkid device, return its name 56 */ 57 extern const char *blkid_dev_devname(blkid_dev dev) 58 { 59 return dev->bid_name; 60 } 61 62 #ifdef CONFIG_BLKID_DEBUG 63 void blkid_debug_dump_dev(blkid_dev dev) 64 { 65 struct list_head *p; 66 67 if (!dev) { 68 printf(" dev: NULL\n"); 69 return; 70 } 71 72 printf(" dev: name = %s\n", dev->bid_name); 73 printf(" dev: DEVNO=\"0x%0llx\"\n", (long long)dev->bid_devno); 74 printf(" dev: TIME=\"%ld\"\n", (long)dev->bid_time); 75 printf(" dev: PRI=\"%d\"\n", dev->bid_pri); 76 printf(" dev: flags = 0x%08X\n", dev->bid_flags); 77 78 list_for_each(p, &dev->bid_tags) { 79 blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags); 80 if (tag) 81 printf(" tag: %s=\"%s\"\n", tag->bit_name, 82 tag->bit_val); 83 else 84 printf(" tag: NULL\n"); 85 } 86 printf("\n"); 87 } 88 #endif 89 90 /* 91 * dev iteration routines for the public libblkid interface. 92 * 93 * These routines do not expose the list.h implementation, which are a 94 * contamination of the namespace, and which force us to reveal far, far 95 * too much of our internal implementation. I'm not convinced I want 96 * to keep list.h in the long term, anyway. It's fine for kernel 97 * programming, but performance is not the #1 priority for this 98 * library, and I really don't like the tradeoff of type-safety for 99 * performance for this application. [tytso:20030125.2007EST] 100 */ 101 102 /* 103 * This series of functions iterate over all devices in a blkid cache 104 */ 105 #define DEV_ITERATE_MAGIC 0x01a5284c 106 107 struct blkid_struct_dev_iterate { 108 int magic; 109 blkid_cache cache; 110 char *search_type; 111 char *search_value; 112 struct list_head *p; 113 }; 114 115 extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache) 116 { 117 blkid_dev_iterate iter; 118 119 iter = malloc(sizeof(struct blkid_struct_dev_iterate)); 120 if (iter) { 121 iter->magic = DEV_ITERATE_MAGIC; 122 iter->cache = cache; 123 iter->p = cache->bic_devs.next; 124 iter->search_type = 0; 125 iter->search_value = 0; 126 } 127 return (iter); 128 } 129 130 extern int blkid_dev_set_search(blkid_dev_iterate iter, 131 char *search_type, char *search_value) 132 { 133 char *new_type, *new_value; 134 135 if (!iter || iter->magic != DEV_ITERATE_MAGIC || !search_type || 136 !search_value) 137 return -1; 138 new_type = malloc(strlen(search_type)+1); 139 new_value = malloc(strlen(search_value)+1); 140 if (!new_type || !new_value) { 141 free(new_type); 142 free(new_value); 143 return -1; 144 } 145 strcpy(new_type, search_type); 146 strcpy(new_value, search_value); 147 free(iter->search_type); 148 free(iter->search_value); 149 iter->search_type = new_type; 150 iter->search_value = new_value; 151 return 0; 152 } 153 154 /* 155 * Return 0 on success, -1 on error 156 */ 157 extern int blkid_dev_next(blkid_dev_iterate iter, 158 blkid_dev *ret_dev) 159 { 160 blkid_dev dev; 161 162 *ret_dev = 0; 163 if (!iter || iter->magic != DEV_ITERATE_MAGIC) 164 return -1; 165 while (iter->p != &iter->cache->bic_devs) { 166 dev = list_entry(iter->p, struct blkid_struct_dev, bid_devs); 167 iter->p = iter->p->next; 168 if (iter->search_type && 169 !blkid_dev_has_tag(dev, iter->search_type, 170 iter->search_value)) 171 continue; 172 *ret_dev = dev; 173 return 0; 174 } 175 return -1; 176 } 177 178 extern void blkid_dev_iterate_end(blkid_dev_iterate iter) 179 { 180 if (!iter || iter->magic != DEV_ITERATE_MAGIC) 181 return; 182 iter->magic = 0; 183 free(iter); 184 } 185 186 #ifdef TEST_PROGRAM 187 #ifdef HAVE_GETOPT_H 188 #include <getopt.h> 189 #else 190 extern char *optarg; 191 extern int optind; 192 #endif 193 194 void usage(char *prog) 195 { 196 fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask]\n", prog); 197 fprintf(stderr, "\tList all devices and exit\n"); 198 exit(1); 199 } 200 201 int main(int argc, char **argv) 202 { 203 blkid_dev_iterate iter; 204 blkid_cache cache = NULL; 205 blkid_dev dev; 206 int c, ret; 207 char *tmp; 208 char *file = NULL; 209 char *search_type = NULL; 210 char *search_value = NULL; 211 212 while ((c = getopt (argc, argv, "m:f:")) != EOF) 213 switch (c) { 214 case 'f': 215 file = optarg; 216 break; 217 case 'm': 218 blkid_debug_mask = strtoul (optarg, &tmp, 0); 219 if (*tmp) { 220 fprintf(stderr, "Invalid debug mask: %s\n", 221 optarg); 222 exit(1); 223 } 224 break; 225 case '?': 226 usage(argv[0]); 227 } 228 if (argc >= optind+2) { 229 search_type = argv[optind]; 230 search_value = argv[optind+1]; 231 optind += 2; 232 } 233 if (argc != optind) 234 usage(argv[0]); 235 236 if ((ret = blkid_get_cache(&cache, file)) != 0) { 237 fprintf(stderr, "%s: error creating cache (%d)\n", 238 argv[0], ret); 239 exit(1); 240 } 241 242 iter = blkid_dev_iterate_begin(cache); 243 if (search_type) 244 blkid_dev_set_search(iter, search_type, search_value); 245 while (blkid_dev_next(iter, &dev) == 0) { 246 printf("Device: %s\n", blkid_dev_devname(dev)); 247 } 248 blkid_dev_iterate_end(iter); 249 250 251 blkid_put_cache(cache); 252 return (0); 253 } 254 #endif