X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lib%2Fblkid%2Fread.c;h=efc348b941b23ae5d0400bada869f87a35eba7c1;hb=7270fbe7fa51cbce01a07d031f03872f314206d1;hp=9d09b686b780ea64a15118e34c5f6e6ba2f819f2;hpb=98999c399d563c248728bf217467a788cb0c1aad;p=tools%2Fe2fsprogs.git diff --git a/lib/blkid/read.c b/lib/blkid/read.c index 9d09b68..efc348b 100644 --- a/lib/blkid/read.c +++ b/lib/blkid/read.c @@ -10,11 +10,16 @@ * %End-Header% */ +#define _XOPEN_SOURCE 600 /* for inclusion of strtoull */ + +#include "config.h" #include #include #include #include +#include #include +#include #include #if HAVE_ERRNO_H #include @@ -23,14 +28,7 @@ #include "blkidP.h" #include "uuid/uuid.h" -#ifdef DEBUG_CACHE -#define DBG(x) x -#else -#define DBG(x) -#endif - #ifdef HAVE_STRTOULL -#define __USE_ISOC9X #define STRTOULL strtoull /* defined in stdlib.h if you try hard enough */ #else /* FIXME: need to support real strtoull here */ @@ -41,6 +39,11 @@ #include #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: * @@ -146,7 +149,7 @@ static int parse_start(char **cp) return 0; if (!strncmp(p, "", 9)) { - DBG(printf("found device trailer %9s\n", *cp)); + DBG(DEBUG_READ, printf("found device trailer %9s\n", *cp)); *cp += 9; return 0; } @@ -189,13 +192,15 @@ static int parse_dev(blkid_cache cache, blkid_dev *dev, char **cp) start = tmp = strchr(*cp, '>'); if (!start) { - DBG(printf("blkid: short line parsing dev: %s\n", *cp)); + 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(printf("device should be %*s\n", end - start, start)); + DBG(DEBUG_READ, printf("device should be %*s\n", + (int)(end - start), start)); if (**cp == '>') *cp = end; @@ -204,13 +209,14 @@ static int parse_dev(blkid_cache cache, blkid_dev *dev, char **cp) *tmp = '\0'; - if (!(tmp = strrchr(end, '<')) || parse_end(&tmp) < 0) - DBG(printf("blkid: missing ending: %s\n", end)); - else if (tmp) + if (!(tmp = strrchr(end, '<')) || parse_end(&tmp) < 0) { + DBG(DEBUG_READ, + printf("blkid: missing ending: %s\n", end)); + } else if (tmp) *tmp = '\0'; if (end - start <= 1) { - DBG(printf("blkid: empty device name: %s\n", *cp)); + DBG(DEBUG_READ, printf("blkid: empty device name: %s\n", *cp)); return -BLKID_ERR_CACHE; } @@ -218,10 +224,12 @@ static int parse_dev(blkid_cache cache, blkid_dev *dev, char **cp) if (name == NULL) return -BLKID_ERR_MEM; - DBG(printf("found dev %s\n", name)); + DBG(DEBUG_READ, printf("found dev %s\n", name)); - if (!(*dev = blkid_get_dev(cache, name, BLKID_DEV_CREATE))) + if (!(*dev = blkid_get_dev(cache, name, BLKID_DEV_CREATE))) { + free(name); return -BLKID_ERR_MEM; + } free(name); return 1; @@ -247,7 +255,8 @@ static int parse_token(char **name, char **value, char **cp) if (**value == '"') { end = strchr(*value + 1, '"'); if (!end) { - DBG(printf("unbalanced quotes at: %s\n", *value)); + DBG(DEBUG_READ, + printf("unbalanced quotes at: %s\n", *value)); *cp = *value; return -BLKID_ERR_CACHE; } @@ -307,17 +316,16 @@ static int parse_tag(blkid_cache cache, blkid_dev dev, char **cp) return ret; /* Some tags are stored directly in the device struct */ - if (!strcmp(name, "DEVNO")) + 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")) - /* FIXME: need to parse a long long eventually */ - dev->bid_time = strtol(value, 0, 0); + dev->bid_time = STRTOULL(value, 0, 0); else - ret = blkid_set_tag(dev, name, value, strlen(value), 0); + ret = blkid_set_tag(dev, name, value, strlen(value)); - DBG(printf(" tag: %s=\"%s\"\n", name, value)); + DBG(DEBUG_READ, printf(" tag: %s=\"%s\"\n", name, value)); return ret < 0 ? ret : 1; } @@ -343,7 +351,7 @@ static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp) *dev_p = NULL; - DBG(printf("line: %s\n", cp)); + DBG(DEBUG_READ, printf("line: %s\n", cp)); if ((ret = parse_dev(cache, dev_p, &cp)) <= 0) return ret; @@ -355,11 +363,12 @@ static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp) } if (dev->bid_type == NULL) { - DBG(printf("blkid: device %s has no TYPE\n",dev->bid_name)); + DBG(DEBUG_READ, + printf("blkid: device %s has no TYPE\n",dev->bid_name)); blkid_free_dev(dev); } - DEB_DUMP_DEV(dev); + DBG(DEBUG_READ, blkid_debug_dump_dev(dev)); return ret; } @@ -369,75 +378,106 @@ static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp) * a newly allocated cache struct. If the file doesn't exist, return a * new empty cache struct. */ -int blkid_get_cache(blkid_cache *cache, const char *filename) +void blkid_read_cache(blkid_cache cache) { FILE *file; char buf[4096]; - int lineno = 0; + int fd, lineno = 0; + struct stat st; if (!cache) - return -BLKID_ERR_PARAM; - - if ((*cache = blkid_new_cache()) == NULL) - return -BLKID_ERR_MEM; + return; - if (!filename || !strlen(filename)) - filename = BLKID_CACHE_FILE; - else - (*cache)->bic_filename = blkid_strdup(filename); - - DBG(printf("cache file %s\n", filename)); - - if (!strcmp(filename, "-")) - file = stdin; - else { - /* - * If the file doesn't exist, then we just return an empty - * struct so that the cache can be populated. - */ - if (access(filename, R_OK) < 0) - return 0; - - file = fopen(filename, "r"); - if (!file) - return errno; /* Should never happen */ + /* + * 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; - - int end = strlen(buf) - 1; + 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, stdin)) { + fgets(buf + end, sizeof(buf) - end, file)) { end = strlen(buf) - 1; lineno++; } - if (blkid_parse_line(*cache, &dev, buf) < 0) { - DBG(printf("blkid: bad format on line %d\n", 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; - - if (file != stdin) - fclose(file); + cache->bic_flags &= ~BLKID_BIC_FL_CHANGED; + cache->bic_ftime = st.st_mtime; - return 0; + 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]);