fix endianess bug inside libbklid-tiny
[project/ubox.git] / libblkid-tiny / libblkid-tiny.c
1 #include <stdio.h>
2 #include <sys/utsname.h>
3
4 #include "superblocks.h"
5 #include "linux_version.h"
6
7 #if 0
8 #define DEBUG(fmt, ...) printf(fmt, __VA_ARGS__)
9 #else
10 #define DEBUG(fmt, ...)
11 #endif
12
13 int blkid_debug_mask = 0;
14
15 static unsigned char *probe_buffer;
16
17 int get_linux_version (void)
18 {
19         static int kver = -1;
20         struct utsname uts;
21         int major = 0;
22         int minor = 0;
23         int teeny = 0;
24         int n;
25
26         if (kver != -1)
27                 return kver;
28         if (uname (&uts))
29                 return kver = 0;
30
31         n = sscanf(uts.release, "%d.%d.%d", &major, &minor, &teeny);
32         if (n < 1 || n > 3)
33                 return kver = 0;
34
35         return kver = KERNEL_VERSION(major, minor, teeny);
36 }
37
38 int blkid_probe_is_tiny(blkid_probe pr)
39 {
40         /* never true ? */
41         return 0;
42 }
43
44 int blkid_probe_set_value(blkid_probe pr, const char *name,
45                 unsigned char *data, size_t len)
46 {
47         /* empty stub */
48         return 0;
49 }
50
51 int blkid_probe_set_version(blkid_probe pr, const char *version)
52 {
53         int len = strlen(version);
54         if (len > (sizeof(pr->version) - 1)) {
55                 fprintf(stderr, "version buffer too small %d\n", len);
56                 return -1;
57         }
58
59         strncpy(pr->version, version, sizeof(pr->version));
60
61         return 0;
62 }
63
64 int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
65 {
66         va_list ap;
67         int n;
68
69         va_start(ap, fmt);
70         n = vsnprintf(pr->version, sizeof(pr->version), fmt, ap);
71         va_end(ap);
72
73         if (n >= sizeof(pr->version))
74                 fprintf(stderr, "version buffer too small %d\n", n);
75
76         return 0;
77 }
78
79 unsigned char *blkid_probe_get_buffer(blkid_probe pr,
80                                 blkid_loff_t off, blkid_loff_t len)
81 {
82         int ret;
83
84         if (len > 4096) {
85                 fprintf(stderr, "probe buffer too small %d\n", (int) len);
86                 return NULL;
87         }
88
89         if (!probe_buffer) {
90                 probe_buffer = malloc(4096);
91                 memset(probe_buffer, 0, 4096);
92         }
93
94         lseek(pr->fd, off, SEEK_SET);
95         ret = read(pr->fd, probe_buffer, len);
96
97         if (ret != len)
98                 fprintf(stderr, "faile to read blkid\n");
99
100         return probe_buffer;
101 }
102
103 int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len)
104 {
105         if (len > (sizeof(pr->label) - 1)) {
106                 fprintf(stderr, "label buffer too small %d > %d\n",
107                         (int) len, (int) sizeof(pr->label) - 1);
108                 return -1;
109         }
110         memcpy(pr->label, label, len + 1);
111
112         return 0;
113 }
114
115 int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *name)
116 {
117         short unsigned int*u = (short unsigned int*) uuid;
118
119         if (u[0])
120                 sprintf(pr->uuid,
121                         "%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
122                         be16_to_cpu(u[0]), be16_to_cpu(u[1]), be16_to_cpu(u[2]), be16_to_cpu(u[3]),
123                         be16_to_cpu(u[4]), be16_to_cpu(u[5]), be16_to_cpu(u[6]), be16_to_cpu(u[7]));
124         if (name)
125                 strncpy(pr->name, name, sizeof(pr->name));
126
127         return 0;
128 }
129
130 int blkid_probe_set_uuid(blkid_probe pr, unsigned char *uuid)
131 {
132         return blkid_probe_set_uuid_as(pr, uuid, NULL);
133 }
134
135 int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid,
136                              size_t len, const char *fmt, ...)
137 {
138         va_list ap;
139
140         va_start(ap, fmt);
141         vsnprintf(pr->uuid, sizeof(pr->uuid), fmt, ap);
142         va_end(ap);
143
144         return 0;
145 }
146
147 static const struct blkid_idinfo *idinfos[] =
148 {
149         &vfat_idinfo,
150         &swsuspend_idinfo,
151         &swap_idinfo,
152         &ext4dev_idinfo,
153         &ext4_idinfo,
154         &ext3_idinfo,
155         &ext2_idinfo,
156         &jbd_idinfo,
157         &squashfs_idinfo,
158         &jffs2_idinfo,
159 };
160
161 int probe_block(char *block, struct blkid_struct_probe *pr)
162 {
163         struct stat s;
164         int i;
165
166         if (stat(block, &s) || !S_ISBLK(s.st_mode))
167                 return -1;
168
169         pr->err = -1;
170         pr->fd = open(block, O_RDONLY);
171         if (!pr->fd)
172                 return -1;
173
174         for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
175                 /* loop over all magic handlers */
176                 const struct blkid_idmag *mag;
177
178                 /* loop over all probe handlers */
179                 DEBUG("scanning %s\n", idinfos[i]->name);
180
181                 mag = &idinfos[i]->magics[0];
182
183                 while (mag->magic) {
184                         int off = (mag->kboff * 1024) + mag->sboff;
185                         char magic[32] = { 0 };
186
187                         lseek(pr->fd, off, SEEK_SET);
188                         read(pr->fd, magic, mag->len);
189
190                         DEBUG("magic: %s %s %d\n", mag->magic, magic, mag->len);
191                         if (!memcmp(mag->magic, magic, mag->len))
192                                 break;
193                         mag++;
194                 }
195
196                 if (mag && mag->magic) {
197                         DEBUG("probing %s\n", idinfos[i]->name);
198                         pr->err = idinfos[i]->probefunc(pr, mag);
199                         pr->id = idinfos[i];
200                         strcpy(pr->dev, block);
201                         if (!pr->err)
202                                 break;
203                 }
204         }
205
206         close(pr->fd);
207
208         return 0;
209 }
210