libblkid-tiny: use separated buffer for each block device read
[project/fstools.git] / libblkid-tiny / libblkid-tiny.c
index f66f3a1dc16ef3d8d75e8b4092494b0510fb5fb2..05b4b99ef9dc2ac40dc891792b548e90e72cc724 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <sys/utsname.h>
 
+#include "libblkid-tiny.h"
 #include "superblocks.h"
 #include "linux_version.h"
 
@@ -12,9 +13,6 @@
 
 int blkid_debug_mask = 0;
 
-static unsigned char *probe_buffer;
-static unsigned int probe_buffer_size = 0;
-
 int get_linux_version (void)
 {
        static int kver = -1;
@@ -80,32 +78,27 @@ int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
 unsigned char *blkid_probe_get_buffer(blkid_probe pr,
                                blkid_loff_t off, blkid_loff_t len)
 {
+       struct blkid_bufinfo *bf;
        int ret;
-       unsigned char *buf;
-
-       if (len > probe_buffer_size) {
-               buf = realloc(probe_buffer, len);
-
-               if (!buf) {
-                       fprintf(stderr, "failed to allocate %d byte buffer\n",
-                               (int)len);
 
-                       return NULL;
-               }
-
-               probe_buffer = buf;
-               probe_buffer_size = len;
-       }
-
-       memset(probe_buffer, 0, probe_buffer_size);
+       bf = malloc(sizeof(*bf) + len);
+       if (!bf)
+               return NULL;
+       memset(bf, 0, sizeof(*bf));
+       bf->data = ((unsigned char *)bf) + sizeof(*bf);
 
        lseek(pr->fd, off, SEEK_SET);
-       ret = read(pr->fd, probe_buffer, len);
+       ret = read(pr->fd, bf->data, len);
 
-       if (ret != len)
+       if (ret != len) {
                fprintf(stderr, "faile to read blkid\n");
+               free(bf);
+               return NULL;
+       }
+
+       list_add_tail(&bf->bufs, &pr->buffers);
 
-       return probe_buffer;
+       return bf->data;
 }
 
 int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len)
@@ -120,17 +113,31 @@ int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len)
        return 0;
 }
 
+int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label,
+                               size_t len, int enc)
+{
+       if (len > (sizeof(pr->label) - 1)) {
+               fprintf(stderr, "label buffer too small %d > %d\n",
+                       (int) len, (int) sizeof(pr->label) - 1);
+               return -1;
+       }
+
+       blkid_encode_to_utf8(enc,(unsigned char*) pr->label, len,
+                       label, len+1);
+
+       return 0;
+}
+
 int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *name)
 {
        short unsigned int*u = (short unsigned int*) uuid;
 
-       if (u[0])
+       if (u[0] && (!name || !strcmp(name, "UUID"))) {
                sprintf(pr->uuid,
                        "%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
                        be16_to_cpu(u[0]), be16_to_cpu(u[1]), be16_to_cpu(u[2]), be16_to_cpu(u[3]),
                        be16_to_cpu(u[4]), be16_to_cpu(u[5]), be16_to_cpu(u[6]), be16_to_cpu(u[7]));
-       if (name)
-               strncpy(pr->name, name, sizeof(pr->name));
+       }
 
        return 0;
 }
@@ -162,12 +169,15 @@ static const struct blkid_idinfo *idinfos[] =
        &ext3_idinfo,
        &ext2_idinfo,
        &jbd_idinfo,
+       &ntfs_idinfo,
        &squashfs_idinfo,
+       &ubi_idinfo,
        &ubifs_idinfo,
        &jffs2_idinfo,
        &hfsplus_idinfo,
        &hfs_idinfo,
        &btrfs_idinfo,
+       &f2fs_idinfo,
 };
 
 int probe_block(char *block, struct blkid_struct_probe *pr)