]> git.ipfire.org Git - thirdparty/util-linux.git/blame - shlibs/blkid/src/probe.c
liblkid: export magic strings from raids
[thirdparty/util-linux.git] / shlibs / blkid / src / probe.c
CommitLineData
a0948ffe 1/*
4d72b337 2 * Low-level libblkid probing API
a0948ffe 3 *
4d72b337 4 * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
a0948ffe 5 *
a0948ffe
KZ
6 * This file may be redistributed under the terms of the
7 * GNU Lesser General Public License.
a0948ffe
KZ
8 */
9
4d72b337
KZ
10/**
11 * SECTION: lowprobe
12 * @title: Low-level probing
13 * @short_description: low-level prober initialization
14 *
15 * The low-level probing routines always and directly read information from
16 * the selected (see blkid_probe_set_device()) device.
17 *
18 * The probing routines are grouped together into separate chains. Currently,
19 * the librray provides superblocks, partitions and topology chains.
20 *
21 * The probing routines is possible to filter (enable/disable) by type (e.g.
22 * fstype "vfat" or partype "gpt") or by usage flags (e.g. BLKID_USAGE_RAID).
488e52be
KZ
23 * These filters are per-chain. Note that always when you touch the chain
24 * filter the current probing position is reseted and probing starts from
25 * scratch. It means that the chain filter should not be modified during
26 * probing, for example in loop where you call blkid_do_probe().
27 *
28 * For more details see the chain specific documentation.
4d72b337
KZ
29 *
30 * The low-level API provides two ways how access to probing results.
31 *
32 * 1. The NAME=value (tag) interface. This interface is older and returns all data
33 * as strings. This interface is generic for all chains.
34 *
35 * 2. The binary interfaces. These interfaces return data in the native formats.
36 * The interface is always specific to the probing chain.
488e52be 37 *
4d72b337
KZ
38 */
39
40/**
41 * SECTION: lowprobe-tags
42 * @title: Low-level tags
43 * @short_description: generic NAME=value interface.
44 *
45 * The probing routines inside the chain are mutually exclusive by default --
46 * only few probing routines are marked as "tolerant". The "tolerant" probing
47 * routines are used for filesystem which can share the same device with any
48 * other filesystem. The blkid_do_safeprobe() checks for the "tolerant" flag.
49 *
50 * The SUPERBLOCKS chain is enabled by default. The all others chains is
51 * necessary to enable by blkid_probe_enable_'CHAINNAME'(). See chains specific
488e52be 52 * documentation.
4d72b337
KZ
53 *
54 * The blkid_do_probe() function returns a result from only one probing
55 * routine, and the next call from the next probing routine. It means you need
56 * to call the function in loop, for example:
57 *
58 * <informalexample>
59 * <programlisting>
60 * while((blkid_do_probe(pr) == 0)
61 * ... use result ...
62 * </programlisting>
63 * </informalexample>
64 *
65 * The blkid_do_safeprobe() is the same as blkid_do_probe(), but returns only
66 * first probing result for every enabled chain. This function checks for
67 * ambivalent results (e.g. more "intolerant" filesystems superblocks on the
68 * device).
69 *
70 * The probing result is set of NAME=value pairs (the NAME is always unique).
71 */
72
a0948ffe
KZ
73#include <stdio.h>
74#include <string.h>
75#include <stdlib.h>
76#include <unistd.h>
77#include <fcntl.h>
78#include <ctype.h>
79#include <sys/types.h>
55113b15
C
80#ifdef HAVE_LINUX_CDROM_H
81#include <linux/cdrom.h>
82#endif
a0948ffe
KZ
83#ifdef HAVE_SYS_STAT_H
84#include <sys/stat.h>
85#endif
86#ifdef HAVE_SYS_MKDEV_H
87#include <sys/mkdev.h>
88#endif
a0948ffe
KZ
89#ifdef HAVE_ERRNO_H
90#include <errno.h>
91#endif
51410fc6 92#include <stdint.h>
8c0dc071
KZ
93#include <stdarg.h>
94
51410fc6 95#ifdef HAVE_LIBUUID
8c0dc071
KZ
96# ifdef HAVE_UUID_UUID_H
97# include <uuid/uuid.h>
e5127179
KZ
98# else
99# include <uuid.h>
8c0dc071 100# endif
51410fc6 101#endif
a0948ffe 102
dc61d909 103#include "blkdev.h"
51410fc6 104#include "blkidP.h"
219227c2 105
52448df8
KZ
106/* chains */
107extern const struct blkid_chaindrv superblocks_drv;
cc33d693 108extern const struct blkid_chaindrv topology_drv;
e4799a35 109extern const struct blkid_chaindrv partitions_drv;
52448df8
KZ
110
111/*
112 * All supported chains
113 */
114static const struct blkid_chaindrv *chains_drvs[] = {
115 [BLKID_CHAIN_SUBLKS] = &superblocks_drv,
cc33d693 116 [BLKID_CHAIN_TOPLGY] = &topology_drv,
e4799a35 117 [BLKID_CHAIN_PARTS] = &partitions_drv
52448df8
KZ
118};
119
120static void blkid_probe_reset_vals(blkid_probe pr);
15a8fb42 121static void blkid_probe_reset_buffer(blkid_probe pr);
52448df8 122
52448df8
KZ
123/**
124 * blkid_new_probe:
125 *
126 * Returns: a pointer to the newly allocated probe struct.
a0948ffe 127 */
51410fc6 128blkid_probe blkid_new_probe(void)
a0948ffe 129{
52448df8
KZ
130 int i;
131 blkid_probe pr;
132
7a458332 133 blkid_init_debug(0);
52448df8
KZ
134 pr = calloc(1, sizeof(struct blkid_struct_probe));
135 if (!pr)
136 return NULL;
137
138 /* initialize chains */
139 for (i = 0; i < BLKID_NCHAINS; i++) {
140 pr->chains[i].driver = chains_drvs[i];
141 pr->chains[i].flags = chains_drvs[i]->dflt_flags;
142 pr->chains[i].enabled = chains_drvs[i]->dflt_enabled;
143 }
15a8fb42 144 INIT_LIST_HEAD(&pr->buffers);
52448df8 145 return pr;
a0948ffe
KZ
146}
147
f38db0cf
KZ
148/**
149 * blkid_new_probe_from_filename:
150 * @filename: device or regular file
151 *
152 * This function is same as call open(filename), blkid_new_probe() and
153 * blkid_probe_set_device(pr, fd, 0, 0).
154 *
155 * The @filename is closed by blkid_free_probe() or by the
156 * blkid_probe_set_device() call.
157 *
158 * Returns: a pointer to the newly allocated probe struct or NULL in case of
159 * error.
160 */
161blkid_probe blkid_new_probe_from_filename(const char *filename)
162{
163 int fd = -1;
164 blkid_probe pr = NULL;
165
166 if (!filename)
167 return NULL;
168
169 fd = open(filename, O_RDONLY);
170 if (fd < 0)
171 return NULL;
172
173 pr = blkid_new_probe();
174 if (!pr)
175 goto err;
176
177 if (blkid_probe_set_device(pr, fd, 0, 0))
178 goto err;
179
180 pr->flags |= BLKID_PRIVATE_FD;
181 return pr;
182err:
183 if (fd >= 0)
184 close(fd);
185 blkid_free_probe(pr);
186 return NULL;
187}
188
52448df8
KZ
189/**
190 * blkid_free_probe:
191 * @pr: probe
192 *
193 * Deallocates the probe struct, buffers and all allocated
51410fc6 194 * data that are associated with this probing control struct.
a0948ffe 195 */
51410fc6 196void blkid_free_probe(blkid_probe pr)
a0948ffe 197{
52448df8
KZ
198 int i;
199
51410fc6
KZ
200 if (!pr)
201 return;
52448df8
KZ
202
203 for (i = 0; i < BLKID_NCHAINS; i++) {
204 struct blkid_chain *ch = &pr->chains[i];
205
206 if (ch->driver->free_data)
207 ch->driver->free_data(pr, ch->data);
208 free(ch->fltr);
209 }
f38db0cf
KZ
210
211 if ((pr->flags & BLKID_PRIVATE_FD) && pr->fd >= 0)
212 close(pr->fd);
15a8fb42 213 blkid_probe_reset_buffer(pr);
51410fc6 214 free(pr);
a0948ffe
KZ
215}
216
52448df8 217
9bdf6885
KZ
218/*
219 * Removes chain values from probing result.
220 */
221void blkid_probe_chain_reset_vals(blkid_probe pr, struct blkid_chain *chn)
222{
223 int nvals = pr->nvals;
224 int i, x;
225
226 for (x = 0, i = 0; i < pr->nvals; i++) {
227 struct blkid_prval *v = &pr->vals[i];
228
229 if (v->chain != chn && x == i) {
230 x++;
231 continue;
232 }
233 if (v->chain == chn) {
234 --nvals;
235 continue;
236 }
237 memcpy(&pr->vals[x++], v, sizeof(struct blkid_prval));
238 }
239 pr->nvals = nvals;
240}
241
9e0f7bda
KZ
242static void blkid_probe_chain_reset_position(struct blkid_chain *chn)
243{
244 if (chn)
245 chn->idx = -1;
246}
247
9bdf6885
KZ
248/*
249 * Copies chain values from probing result to @vals, the max size of @vals is
250 * @nvals and returns real number of values.
251 */
252int blkid_probe_chain_copy_vals(blkid_probe pr, struct blkid_chain *chn,
253 struct blkid_prval *vals, int nvals)
254{
255 int i, x;
256
257 for (x = 0, i = 0; i < pr->nvals && x < nvals; i++) {
258 struct blkid_prval *v = &pr->vals[i];
259
260 if (v->chain != chn)
261 continue;
262 memcpy(&vals[x++], v, sizeof(struct blkid_prval));
263 }
264 return x;
265}
266
267/*
268 * Appends values from @vals to the probing result
269 */
270void blkid_probe_append_vals(blkid_probe pr, struct blkid_prval *vals, int nvals)
271{
272 int i = 0;
273
274 while (i < nvals && pr->nvals < BLKID_NVALS) {
275 memcpy(&pr->vals[pr->nvals++], &vals[i++],
276 sizeof(struct blkid_prval));
277 }
278}
279
51410fc6 280static void blkid_probe_reset_vals(blkid_probe pr)
a0948ffe 281{
51410fc6
KZ
282 memset(pr->vals, 0, sizeof(pr->vals));
283 pr->nvals = 0;
a0948ffe
KZ
284}
285
1c1726a7
KZ
286struct blkid_chain *blkid_probe_get_chain(blkid_probe pr)
287{
288 return pr->cur_chain;
289}
290
22571ebb
KZ
291void *blkid_probe_get_binary_data(blkid_probe pr, struct blkid_chain *chn)
292{
293 int rc;
294
88923b08 295 if (!pr || !chn)
22571ebb
KZ
296 return NULL;
297
298 pr->cur_chain = chn;
299 chn->binary = TRUE;
9e0f7bda 300 blkid_probe_chain_reset_position(chn);
22571ebb
KZ
301
302 rc = chn->driver->probe(pr, chn);
303
304 chn->binary = FALSE;
305 pr->cur_chain = NULL;
9e0f7bda 306 blkid_probe_chain_reset_position(chn);
22571ebb 307
d7be1a74 308 if (rc != 0)
22571ebb
KZ
309 return NULL;
310
311 DBG(DEBUG_LOWPROBE,
312 printf("returning %s binary data\n", chn->driver->name));
313 return chn->data;
314}
315
316
52448df8
KZ
317/**
318 * blkid_reset_probe:
319 * @pr: probe
320 *
44ef90bc
KZ
321 * Zeroize probing results and resets the current probing (this has impact to
322 * blkid_do_probe() only). This function does not touch probing filters and
323 * keeps assigned device.
52448df8 324 */
51410fc6 325void blkid_reset_probe(blkid_probe pr)
a0948ffe 326{
52448df8
KZ
327 int i;
328
51410fc6
KZ
329 if (!pr)
330 return;
52448df8
KZ
331
332 blkid_probe_reset_buffer(pr);
51410fc6 333 blkid_probe_reset_vals(pr);
52448df8 334
44ef90bc
KZ
335 pr->cur_chain = NULL;
336
52448df8 337 for (i = 0; i < BLKID_NCHAINS; i++)
9e0f7bda 338 blkid_probe_chain_reset_position(&pr->chains[i]);
a0948ffe
KZ
339}
340
46a734fd
KZ
341/***
342static int blkid_probe_dump_filter(blkid_probe pr, int chain)
343{
344 struct blkid_chain *chn;
345 int i;
346
347 if (!pr || chain < 0 || chain >= BLKID_NCHAINS)
348 return -1;
349
350 chn = &pr->chains[chain];
351
352 if (!chn->fltr)
353 return -1;
354
355 for (i = 0; i < chn->driver->nidinfos; i++) {
356 const struct blkid_idinfo *id = chn->driver->idinfos[i];
357
358 DBG(DEBUG_LOWPROBE, printf("%d: %s: %s\n",
359 i,
360 id->name,
361 blkid_bmp_get_item(chn->fltr, i)
362 ? "disabled" : "enabled <--"));
46a734fd
KZ
363 }
364 return 0;
365}
366***/
367
368/*
369 * Returns properly initialized chain filter
370 */
371unsigned long *blkid_probe_get_filter(blkid_probe pr, int chain, int create)
372{
373 struct blkid_chain *chn;
374
375 if (!pr || chain < 0 || chain >= BLKID_NCHAINS)
376 return NULL;
377
378 chn = &pr->chains[chain];
379
380 /* always when you touch the chain filter all indexes are reseted and
381 * probing starts from scratch
382 */
9e0f7bda 383 blkid_probe_chain_reset_position(chn);
46a734fd
KZ
384 pr->cur_chain = NULL;
385
386 if (!chn->driver->has_fltr || (!chn->fltr && !create))
387 return NULL;
388
389 if (!chn->fltr)
390 chn->fltr = calloc(1, blkid_bmp_nbytes(chn->driver->nidinfos));
391 else
392 memset(chn->fltr, 0, blkid_bmp_nbytes(chn->driver->nidinfos));
393
394 /* blkid_probe_dump_filter(pr, chain); */
395 return chn->fltr;
396}
397
398/*
399 * Generic private functions for filter setting
400 */
401int __blkid_probe_invert_filter(blkid_probe pr, int chain)
402{
403 int i;
404 struct blkid_chain *chn;
405 unsigned long *fltr;
406
407 fltr = blkid_probe_get_filter(pr, chain, FALSE);
408 if (!fltr)
409 return -1;
410
411 chn = &pr->chains[chain];
412
413 for (i = 0; i < blkid_bmp_nwords(chn->driver->nidinfos); i++)
414 fltr[i] = ~fltr[i];
415
416 DBG(DEBUG_LOWPROBE, printf("probing filter inverted\n"));
417 /* blkid_probe_dump_filter(pr, chain); */
418 return 0;
419}
420
421int __blkid_probe_reset_filter(blkid_probe pr, int chain)
422{
423 return blkid_probe_get_filter(pr, chain, FALSE) ? 0 : -1;
424}
425
426int __blkid_probe_filter_types(blkid_probe pr, int chain, int flag, char *names[])
427{
428 unsigned long *fltr;
429 struct blkid_chain *chn;
430 int i;
431
432 fltr = blkid_probe_get_filter(pr, chain, TRUE);
433 if (!fltr)
434 return -1;
435
436 chn = &pr->chains[chain];
437
438 for (i = 0; i < chn->driver->nidinfos; i++) {
439 int has = 0;
440 const struct blkid_idinfo *id = chn->driver->idinfos[i];
441 char **n;
442
443 for (n = names; *n; n++) {
444 if (!strcmp(id->name, *n)) {
445 has = 1;
446 break;
447 }
448 }
449 if (flag & BLKID_FLTR_ONLYIN) {
450 if (!has)
451 blkid_bmp_set_item(fltr, i);
452 } else if (flag & BLKID_FLTR_NOTIN) {
453 if (has)
454 blkid_bmp_set_item(fltr, i);
455 }
456 }
457
458 DBG(DEBUG_LOWPROBE,
459 printf("%s: a new probing type-filter initialized\n",
460 chn->driver->name));
461 /* blkid_probe_dump_filter(pr, chain); */
462 return 0;
463}
464
15a8fb42 465unsigned char *blkid_probe_get_buffer(blkid_probe pr,
1ca17f91
KZ
466 blkid_loff_t off, blkid_loff_t len)
467{
15a8fb42
KZ
468 struct list_head *p;
469 struct blkid_bufinfo *bf = NULL;
470
88923b08
KZ
471 if (pr->size <= 0)
472 return NULL;
473
15a8fb42
KZ
474 list_for_each(p, &pr->buffers) {
475 struct blkid_bufinfo *x =
476 list_entry(p, struct blkid_bufinfo, bufs);
477
478 if (x->off <= off && off + len <= x->off + x->len) {
479 DBG(DEBUG_LOWPROBE,
480 printf("\treuse buffer: off=%jd len=%jd\n",
481 x->off, x->len));
482 bf = x;
483 break;
484 }
1ca17f91 485 }
15a8fb42
KZ
486 if (!bf) {
487 ssize_t ret;
1ca17f91 488
15a8fb42 489 if (blkid_llseek(pr->fd, pr->off + off, SEEK_SET) < 0)
1ca17f91
KZ
490 return NULL;
491
15a8fb42
KZ
492 /* allocate info and space for data by why call */
493 bf = calloc(1, sizeof(struct blkid_bufinfo) + len);
494 if (!bf)
1ca17f91 495 return NULL;
1ca17f91 496
15a8fb42
KZ
497 bf->data = ((unsigned char *) bf) + sizeof(struct blkid_bufinfo);
498 bf->len = len;
499 bf->off = off;
500 INIT_LIST_HEAD(&bf->bufs);
1ca17f91
KZ
501
502 DBG(DEBUG_LOWPROBE,
15a8fb42 503 printf("\tbuffer read: off=%jd len=%jd\n", off, len));
1ca17f91 504
15a8fb42
KZ
505 ret = read(pr->fd, bf->data, len);
506 if (ret != (ssize_t) len) {
507 free(bf);
1ca17f91 508 return NULL;
15a8fb42
KZ
509 }
510 list_add_tail(&bf->bufs, &pr->buffers);
1ca17f91 511 }
15a8fb42
KZ
512
513 return off ? bf->data + (off - bf->off) : bf->data;
1ca17f91
KZ
514}
515
516
15a8fb42 517static void blkid_probe_reset_buffer(blkid_probe pr)
a0948ffe 518{
15a8fb42
KZ
519 ssize_t read_ct = 0, len_ct = 0;
520
521 if (!pr || list_empty(&pr->buffers))
522 return;
523
524 DBG(DEBUG_LOWPROBE, printf("reseting probing buffers\n"));
525
526 while (!list_empty(&pr->buffers)) {
527 struct blkid_bufinfo *bf = list_entry(pr->buffers.next,
528 struct blkid_bufinfo, bufs);
529
530 read_ct++;
531 len_ct += bf->len;
532 list_del(&bf->bufs);
533 free(bf);
4884729a 534 }
15a8fb42
KZ
535
536 DBG(DEBUG_LOWPROBE,
537 printf("buffers summary: %jd bytes by %jd read() call(s)\n",
538 len_ct, read_ct));
539
540 INIT_LIST_HEAD(&pr->buffers);
a0948ffe
KZ
541}
542
108013b4
KZ
543/*
544 * Small devices need a special care.
545 */
546int blkid_probe_is_tiny(blkid_probe pr)
547{
d0465c3c 548 return pr && (pr->flags & BLKID_TINY_DEV);
108013b4
KZ
549}
550
55113b15
C
551/*
552 * CDROMs may fail when probed for RAID (last sector problem)
553 */
554int blkid_probe_is_cdrom(blkid_probe pr)
555{
556 return pr && (pr->flags & BLKID_CDROM_DEV);
557}
558
52448df8
KZ
559/**
560 * blkid_probe_set_device:
561 * @pr: probe
562 * @fd: device file descriptor
563 * @off: begin of probing area
f38db0cf 564 * @size: size of probing area (zero means whole device/file)
52448df8
KZ
565 *
566 * Assigns the device to probe control struct, resets internal buffers and
44ef90bc 567 * resets the current probing.
51410fc6 568 *
52448df8 569 * Returns: -1 in case of failure, or 0 on success.
51410fc6
KZ
570 */
571int blkid_probe_set_device(blkid_probe pr, int fd,
572 blkid_loff_t off, blkid_loff_t size)
a0948ffe 573{
90ec8d9c
KZ
574 struct stat sb;
575
51410fc6
KZ
576 if (!pr)
577 return -1;
a0948ffe 578
51410fc6 579 blkid_reset_probe(pr);
a0948ffe 580
f38db0cf
KZ
581 if ((pr->flags & BLKID_PRIVATE_FD) && pr->fd >= 0)
582 close(pr->fd);
583
584 pr->flags &= ~BLKID_PRIVATE_FD;
2b923637 585 pr->flags &= ~BLKID_TINY_DEV;
55113b15 586 pr->flags &= ~BLKID_CDROM_DEV;
51410fc6
KZ
587 pr->fd = fd;
588 pr->off = off;
bb6c6673 589 pr->size = 0;
52448df8
KZ
590 pr->devno = 0;
591 pr->mode = 0;
592 pr->blkssz = 0;
dc61d909 593
a67bb3bf
LT
594#if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE)
595 /* Disable read-ahead */
596 posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);
597#endif
90ec8d9c
KZ
598 if (fstat(fd, &sb))
599 goto err;
600
601 pr->mode = sb.st_mode;
602 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode))
603 pr->devno = sb.st_rdev;
604
bb6c6673 605 if (size)
dc61d909 606 pr->size = size;
bb6c6673 607 else {
30696241
KZ
608 if (S_ISBLK(sb.st_mode)) {
609 if (blkdev_get_size(fd, (unsigned long long *) &pr->size)) {
610 DBG(DEBUG_LOWPROBE, printf(
611 "failed to get device size\n"));
612 goto err;
613 }
614 } else if (S_ISCHR(sb.st_mode))
c1ba7962 615 pr->size = 1; /* UBI devices are char... */
0d17b1cf 616 else if (S_ISREG(sb.st_mode))
c1ba7962
CC
617 pr->size = sb.st_size; /* regular file */
618
108013b4
KZ
619 if (pr->off > pr->size)
620 goto err;
621
622 /* The probing area cannot be larger than whole device, pr->off
623 * is offset within the device */
624 pr->size -= pr->off;
bb6c6673 625 }
c1ba7962 626
eb84ba7c 627 DBG(DEBUG_LOWPROBE, printf("ready for low-probing, offset=%jd, size=%jd\n",
bb6c6673 628 pr->off, pr->size));
d0465c3c 629
90ec8d9c 630 if (pr->size <= 1440 * 1024 && !S_ISCHR(sb.st_mode))
d0465c3c
KZ
631 pr->flags |= BLKID_TINY_DEV;
632
55113b15 633#ifdef CDROM_GET_CAPABILITY
90ec8d9c 634 if (S_ISBLK(sb.st_mode) && ioctl(fd, CDROM_GET_CAPABILITY, NULL) >= 0)
55113b15
C
635 pr->flags |= BLKID_CDROM_DEV;
636#endif
a0948ffe 637 return 0;
0d17b1cf
KZ
638err:
639 DBG(DEBUG_LOWPROBE,
640 printf("failed to prepare a device for low-probing\n"));
641 return -1;
642
a0948ffe
KZ
643}
644
f319b5ca
KZ
645int blkid_probe_get_dimension(blkid_probe pr,
646 blkid_loff_t *off, blkid_loff_t *size)
647{
648 if (!pr)
649 return -1;
650
651 *off = pr->off;
652 *size = pr->size;
653 return 0;
654}
655
656int blkid_probe_set_dimension(blkid_probe pr,
657 blkid_loff_t off, blkid_loff_t size)
658{
659 if (!pr)
660 return -1;
661
662 DBG(DEBUG_LOWPROBE, printf(
663 "changing probing area: size=%llu, off=%llu "
664 "-to-> size=%llu, off=%llu\n",
665 (unsigned long long) pr->size,
666 (unsigned long long) pr->off,
667 (unsigned long long) size,
668 (unsigned long long) off));
669
670 pr->off = off;
671 pr->size = size;
88923b08
KZ
672 pr->flags &= ~BLKID_TINY_DEV;
673
674 if (pr->size <= 1440 * 1024 && !S_ISCHR(pr->mode))
675 pr->flags |= BLKID_TINY_DEV;
f319b5ca
KZ
676
677 blkid_probe_reset_buffer(pr);
678
679 return 0;
680}
681
0bffad47
KZ
682/**
683 * blkid_do_probe:
684 * @pr: prober
685 *
686 * Calls probing functions in all enabled chains. The superblocks chain is
687 * enabled by default. The blkid_do_probe() stores result from only one
688 * probing function. It's necessary to call this routine in a loop to get
44ef90bc
KZ
689 * results from all probing functions in all chains. The probing is reseted
690 * by blkid_reset_probe() or by filter functions.
a0fc685c 691 *
0bffad47
KZ
692 * This is string-based NAME=value interface only.
693 *
694 * <example>
695 * <title>basic case - use the first result only</title>
696 * <programlisting>
a0fc685c
KZ
697 *
698 * if (blkid_do_probe(pr) == 0) {
699 * int nvals = blkid_probe_numof_values(pr);
700 * for (n = 0; n < nvals; n++) {
701 * if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
702 * printf("%s = %s\n", name, data);
703 * }
704 * }
0bffad47
KZ
705 * </programlisting>
706 * </example>
a0fc685c 707 *
0bffad47
KZ
708 * <example>
709 * <title>advanced case - probe for all signatures</title>
710 * <programlisting>
a0fc685c
KZ
711 *
712 * while (blkid_do_probe(pr) == 0) {
713 * int nvals = blkid_probe_numof_values(pr);
714 * ...
715 * }
0bffad47
KZ
716 * </programlisting>
717 * </example>
a0fc685c 718 *
0bffad47 719 * See also blkid_reset_probe().
a0fc685c 720 *
0bffad47 721 * Returns: 0 on success, 1 when probing is done and -1 in case of error.
a0fc685c 722 */
51410fc6 723int blkid_do_probe(blkid_probe pr)
a0948ffe 724{
0bffad47 725 int rc = 1;
a0948ffe 726
0bffad47 727 if (!pr)
51410fc6 728 return -1;
a0948ffe 729
0bffad47 730 do {
44ef90bc
KZ
731 struct blkid_chain *chn = pr->cur_chain;
732
733 if (!chn)
734 chn = pr->cur_chain = &pr->chains[0];
735
736 /* we go to the next chain only when the previous probing
737 * result was nothing (rc == 1) and when the current chain is
738 * disabled or we are at end of the current chain (chain->idx +
046959cc
CW
739 * 1 == sizeof chain) or the current chain bailed out right at
740 * the start (chain->idx == -1)
44ef90bc
KZ
741 */
742 else if (rc == 1 && (chn->enabled == FALSE ||
046959cc
CW
743 chn->idx + 1 == chn->driver->nidinfos ||
744 chn->idx == -1)) {
a0948ffe 745
44ef90bc 746 int idx = chn->driver->id + 1;
bd635f86
KZ
747
748 if (idx < BLKID_NCHAINS)
44ef90bc 749 chn = pr->cur_chain = &pr->chains[idx];
bd635f86
KZ
750 else
751 return 1; /* all chains already probed */
752 }
a0fc685c 753
0bffad47 754 chn->binary = FALSE; /* for sure... */
6644688a 755
44ef90bc 756 DBG(DEBUG_LOWPROBE, printf("chain probe %s %s (idx=%d)\n",
0bffad47 757 chn->driver->name,
44ef90bc
KZ
758 chn->enabled? "ENABLED" : "DISABLED",
759 chn->idx));
a0948ffe 760
0bffad47 761 if (!chn->enabled)
51410fc6 762 continue;
a0948ffe 763
0bffad47
KZ
764 /* rc: -1 = error, 0 = success, 1 = no result */
765 rc = chn->driver->probe(pr, chn);
a0948ffe 766
0bffad47 767 } while (rc == 1);
a0948ffe 768
0bffad47
KZ
769 return rc;
770}
a0948ffe 771
0bffad47
KZ
772/**
773 * blkid_do_safeprobe:
774 * @pr: prober
775 *
776 * This function gathers probing results from all enabled chains and checks
777 * for ambivalent results (e.g. more filesystems on the device).
778 *
779 * This is string-based NAME=value interface only.
780 *
781 * Note about suberblocks chain -- the function does not check for filesystems
782 * when a RAID signature is detected. The function also does not check for
783 * collision between RAIDs. The first detected RAID is returned.
784 *
785 * Returns: 0 on success, 1 if nothing is detected, -2 if ambivalen result is
786 * detected and -1 on case of error.
787 */
788int blkid_do_safeprobe(blkid_probe pr)
789{
790 int i, count = 0, rc = 0;
a0948ffe 791
0bffad47
KZ
792 if (!pr)
793 return -1;
a0948ffe 794
0bffad47
KZ
795 for (i = 0; i < BLKID_NCHAINS; i++) {
796 struct blkid_chain *chn;
a0948ffe 797
0bffad47
KZ
798 chn = pr->cur_chain = &pr->chains[i];
799 chn->binary = FALSE; /* for sure... */
a0948ffe 800
0bffad47
KZ
801 DBG(DEBUG_LOWPROBE, printf("chain safeprobe %s %s\n",
802 chn->driver->name,
803 chn->enabled? "ENABLED" : "DISABLED"));
804
805 if (!chn->enabled)
806 continue;
807
9e0f7bda 808 blkid_probe_chain_reset_position(chn);
0bffad47 809
0bffad47 810 rc = chn->driver->safeprobe(pr, chn);
9e0f7bda
KZ
811
812 blkid_probe_chain_reset_position(chn);
813
814 /* rc: -2 ambivalent, -1 = error, 0 = success, 1 = no result */
0bffad47
KZ
815 if (rc < 0)
816 goto done; /* error */
817 if (rc == 0)
818 count++; /* success */
51410fc6 819 }
0bffad47
KZ
820
821done:
822 pr->cur_chain = NULL;
823 if (rc < 0)
824 return rc;
825 return count ? 0 : 1;
a0948ffe
KZ
826}
827
0bffad47
KZ
828/**
829 * blkid_do_fullprobe:
830 * @pr: prober
831 *
832 * This function gathers probing results from all enabled chains. Same as
833 * blkid_so_safeprobe() but does not check for collision between probing
834 * result.
835 *
836 * This is string-based NAME=value interface only.
7103157c 837 *
0bffad47 838 * Returns: 0 on success, 1 if nothing is detected or -1 on case of error.
a2f01a1c 839 */
0bffad47 840int blkid_do_fullprobe(blkid_probe pr)
a2f01a1c 841{
0bffad47 842 int i, count = 0, rc = 0;
7103157c 843
0bffad47
KZ
844 if (!pr)
845 return -1;
a2f01a1c 846
0bffad47
KZ
847 for (i = 0; i < BLKID_NCHAINS; i++) {
848 int rc;
849 struct blkid_chain *chn;
a2f01a1c 850
0bffad47
KZ
851 chn = pr->cur_chain = &pr->chains[i];
852 chn->binary = FALSE; /* for sure... */
853
854 DBG(DEBUG_LOWPROBE, printf("chain fullprobe %s: %s\n",
855 chn->driver->name,
856 chn->enabled? "ENABLED" : "DISABLED"));
857
858 if (!chn->enabled)
859 continue;
860
9e0f7bda 861 blkid_probe_chain_reset_position(chn);
0bffad47 862
0bffad47 863 rc = chn->driver->probe(pr, chn);
9e0f7bda
KZ
864
865 blkid_probe_chain_reset_position(chn);
866
867 /* rc: -1 = error, 0 = success, 1 = no result */
0bffad47
KZ
868 if (rc < 0)
869 goto done; /* error */
870 if (rc == 0)
871 count++; /* success */
872 }
873
874done:
875 pr->cur_chain = NULL;
876 if (rc < 0)
877 return rc;
878 return count ? 0 : 1;
a2f01a1c
KZ
879}
880
ce011388
KZ
881/* same sa blkid_probe_get_buffer() but works with 512-sectors */
882unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
883{
884 return pr ? blkid_probe_get_buffer(pr,
885 ((blkid_loff_t) sector) << 9, 0x200) : NULL;
886}
887
9bdf6885 888struct blkid_prval *blkid_probe_assign_value(
51410fc6 889 blkid_probe pr, const char *name)
a0948ffe 890{
51410fc6 891 struct blkid_prval *v;
a0948ffe 892
51410fc6
KZ
893 if (!name)
894 return NULL;
924fe747 895 if (pr->nvals >= BLKID_NVALS)
51410fc6 896 return NULL;
a0948ffe 897
51410fc6
KZ
898 v = &pr->vals[pr->nvals];
899 v->name = name;
9bdf6885 900 v->chain = pr->cur_chain;
51410fc6 901 pr->nvals++;
6644688a 902
9bdf6885
KZ
903 DBG(DEBUG_LOWPROBE,
904 printf("assigning %s [%s]\n", name, v->chain->driver->name));
51410fc6 905 return v;
a0948ffe
KZ
906}
907
cdd5bada
KZ
908int blkid_probe_reset_last_value(blkid_probe pr)
909{
910 struct blkid_prval *v;
911
912 if (pr == NULL || pr->nvals == 0)
913 return -1;
914
915 v = &pr->vals[pr->nvals - 1];
916
917 DBG(DEBUG_LOWPROBE,
918 printf("un-assigning %s [%s]\n", v->name, v->chain->driver->name));
919
920 memset(v, 0, sizeof(struct blkid_prval));
921 pr->nvals--;
922
923 return 0;
924
925}
926
51410fc6
KZ
927int blkid_probe_set_value(blkid_probe pr, const char *name,
928 unsigned char *data, size_t len)
a0948ffe 929{
51410fc6 930 struct blkid_prval *v;
a0948ffe 931
51410fc6
KZ
932 if (len > BLKID_PROBVAL_BUFSIZ)
933 len = BLKID_PROBVAL_BUFSIZ;
a0948ffe 934
51410fc6
KZ
935 v = blkid_probe_assign_value(pr, name);
936 if (!v)
937 return -1;
a0948ffe 938
51410fc6
KZ
939 memcpy(v->data, data, len);
940 v->len = len;
a0948ffe
KZ
941 return 0;
942}
943
51410fc6
KZ
944int blkid_probe_vsprintf_value(blkid_probe pr, const char *name,
945 const char *fmt, va_list ap)
a0948ffe 946{
51410fc6
KZ
947 struct blkid_prval *v;
948 size_t len;
a0948ffe 949
51410fc6
KZ
950 v = blkid_probe_assign_value(pr, name);
951 if (!v)
952 return -1;
a0948ffe 953
51410fc6 954 len = vsnprintf((char *) v->data, sizeof(v->data), fmt, ap);
a0948ffe 955
51410fc6 956 if (len <= 0) {
cdd5bada 957 blkid_probe_reset_last_value(pr);
51410fc6 958 return -1;
a0948ffe 959 }
51410fc6 960 v->len = len + 1;
a0948ffe
KZ
961 return 0;
962}
963
cc33d693
KZ
964int blkid_probe_sprintf_value(blkid_probe pr, const char *name,
965 const char *fmt, ...)
966{
967 int rc;
968 va_list ap;
969
970 va_start(ap, fmt);
971 rc = blkid_probe_vsprintf_value(pr, name, fmt, ap);
972 va_end(ap);
973
974 return rc;
975}
976
b3ee97a3
KZ
977/**
978 * blkid_probe_get_devno:
979 * @pr: probe
980 *
981 * Returns: block device number, or 0 for regilar files.
982 */
983dev_t blkid_probe_get_devno(blkid_probe pr)
984{
b3ee97a3
KZ
985 return pr->devno;
986}
987
601fb1c1
KZ
988/**
989 * blkid_probe_get_wholedisk_devno:
990 * @pr: probe
991 *
992 * Returns: device number of the wholedisk, or 0 for regilar files.
993 */
994dev_t blkid_probe_get_wholedisk_devno(blkid_probe pr)
995{
996 if (!pr->disk_devno) {
997 dev_t devno, disk_devno = 0;
998
999 devno = blkid_probe_get_devno(pr);
1000 if (!devno)
1001 return 0;
1002
1003 if (blkid_devno_to_wholedisk(devno, NULL, 0, &disk_devno) == 0)
1004 pr->disk_devno = disk_devno;
1005 }
1006 return pr->disk_devno;
1007}
1008
1009/**
1010 * blkid_probe_is_wholedisk:
1011 * @pr: probe
1012 *
1013 * Returns: 1 if the device is whole-disk or 0.
1014 */
1015int blkid_probe_is_wholedisk(blkid_probe pr)
1016{
1017 dev_t devno, disk_devno;
1018
1019 devno = blkid_probe_get_devno(pr);
1020 if (!devno)
1021 return 0;
1022
1023 disk_devno = blkid_probe_get_wholedisk_devno(pr);
1024 if (!disk_devno)
1025 return 0;
1026
1027 return devno == disk_devno;
1028}
1029
b3ee97a3
KZ
1030/**
1031 * blkid_probe_get_size:
1032 * @pr: probe
1033 *
30696241
KZ
1034 * This function returns size of probing area as defined by blkid_probe_set_device().
1035 * If the size of the probing area is unrestricted then this function returns
1036 * the real size of device. See also blkid_get_dev_size().
1037 *
1038 * Returns: size in bytes or -1 in case of error.
b3ee97a3
KZ
1039 */
1040blkid_loff_t blkid_probe_get_size(blkid_probe pr)
1041{
1042 return pr ? pr->size : -1;
1043}
1044
56e961e2
KZ
1045/**
1046 * blkid_probe_get_offset:
1047 * @pr: probe
1048 *
1049 * This function returns offset of probing area as defined by blkid_probe_set_device().
1050 *
1051 * Returns: offset in bytes or -1 in case of error.
1052 */
1053blkid_loff_t blkid_probe_get_offset(blkid_probe pr)
1054{
1055 return pr ? pr->off : -1;
1056}
1057
1058/**
1059 * blkid_probe_get_fd:
1060 * @pr: probe
1061 *
1062 * Returns: file descriptor for assigned device/file.
1063 */
1064int blkid_probe_get_fd(blkid_probe pr)
1065{
1066 return pr ? pr->fd : -1;
1067}
1068
b3ee97a3
KZ
1069/**
1070 * blkid_probe_get_sectorsize:
90ec8d9c 1071 * @pr: probe or NULL (for NULL returns 512)
b3ee97a3 1072 *
2a1dfbad 1073 * Returns: block device logical sector size (BLKSSZGET ioctl, default 512).
b3ee97a3
KZ
1074 */
1075unsigned int blkid_probe_get_sectorsize(blkid_probe pr)
1076{
1077 if (!pr)
1078 return DEFAULT_SECTOR_SIZE; /*... and good luck! */
90ec8d9c 1079
b3ee97a3
KZ
1080 if (pr->blkssz)
1081 return pr->blkssz;
b3ee97a3 1082
90ec8d9c
KZ
1083 if (S_ISBLK(pr->mode) &&
1084 blkdev_get_sector_size(pr->fd, (int *) &pr->blkssz) == 0)
1085 return pr->blkssz;
b3ee97a3 1086
b3ee97a3
KZ
1087 pr->blkssz = DEFAULT_SECTOR_SIZE;
1088 return pr->blkssz;
1089}
1090
4d72b337
KZ
1091/**
1092 * blkid_probe_numof_values:
1093 * @pr: probe
1094 *
1095 * Returns: number of values in probing result or -1 in case of error.
1096 */
1097int blkid_probe_numof_values(blkid_probe pr)
1098{
1099 if (!pr)
1100 return -1;
1101 return pr->nvals;
1102}
1103
81f73792
KZ
1104/**
1105 * blkid_probe_get_value:
1106 * @pr: probe
1107 * @num: wanted value in range 0..N, where N is blkid_probe_numof_values() - 1
1108 * @name: pointer to return value name or NULL
1109 * @data: pointer to return value data or NULL
1110 * @len: pointer to return value length or NULL
1111 *
c2dbd49b
KZ
1112 * Note, the @len returns length of the @data, including the terminating
1113 * '\0' character.
1114 *
81f73792
KZ
1115 * Returns: 0 on success, or -1 in case of error.
1116 */
51410fc6 1117int blkid_probe_get_value(blkid_probe pr, int num, const char **name,
6d042d0d 1118 const char **data, size_t *len)
a0948ffe 1119{
81f73792 1120 struct blkid_prval *v = __blkid_probe_get_value(pr, num);
a0948ffe 1121
81f73792 1122 if (!v)
51410fc6 1123 return -1;
51410fc6
KZ
1124 if (name)
1125 *name = v->name;
1126 if (data)
6d042d0d 1127 *data = (char *) v->data;
51410fc6
KZ
1128 if (len)
1129 *len = v->len;
6644688a
KZ
1130
1131 DBG(DEBUG_LOWPROBE, printf("returning %s value\n", v->name));
a0948ffe
KZ
1132 return 0;
1133}
a0948ffe 1134
81f73792
KZ
1135/**
1136 * blkid_probe_lookup_value:
1137 * @pr: probe
1138 * @name: name of value
1139 * @data: pointer to return value data or NULL
1140 * @len: pointer to return value length or NULL
1141 *
c2dbd49b
KZ
1142 * Note, the @len returns length of the @data, including the terminating
1143 * '\0' character.
1144 *
81f73792
KZ
1145 * Returns: 0 on success, or -1 in case of error.
1146 */
51410fc6 1147int blkid_probe_lookup_value(blkid_probe pr, const char *name,
6d042d0d 1148 const char **data, size_t *len)
a0948ffe 1149{
81f73792 1150 struct blkid_prval *v = __blkid_probe_lookup_value(pr, name);
a0948ffe 1151
81f73792 1152 if (!v)
51410fc6 1153 return -1;
81f73792
KZ
1154 if (data)
1155 *data = (char *) v->data;
1156 if (len)
1157 *len = v->len;
81f73792 1158 return 0;
a0948ffe
KZ
1159}
1160
81f73792
KZ
1161/**
1162 * blkid_probe_has_value:
1163 * @pr: probe
1164 * @name: name of value
1165 *
1166 * Returns: 1 if value exist in probing result, otherwise 0.
1167 */
51410fc6 1168int blkid_probe_has_value(blkid_probe pr, const char *name)
a0948ffe 1169{
51410fc6
KZ
1170 if (blkid_probe_lookup_value(pr, name, NULL, NULL) == 0)
1171 return 1;
a0948ffe
KZ
1172 return 0;
1173}
1174
1c1726a7
KZ
1175struct blkid_prval *__blkid_probe_get_value(blkid_probe pr, int num)
1176{
1177 if (pr == NULL || num < 0 || num >= pr->nvals)
1178 return NULL;
1179
1180 return &pr->vals[num];
1181}
1182
1183struct blkid_prval *__blkid_probe_lookup_value(blkid_probe pr, const char *name)
1184{
1185 int i;
1186
1187 if (pr == NULL || pr->nvals == 0 || name == NULL)
1188 return NULL;
1189
1190 for (i = 0; i < pr->nvals; i++) {
1191 struct blkid_prval *v = &pr->vals[i];
1192
1193 if (v->name && strcmp(name, v->name) == 0) {
1194 DBG(DEBUG_LOWPROBE, printf("returning %s value\n", v->name));
1195 return v;
1196 }
1197 }
1198 return NULL;
1199}
1200
201529bd
KZ
1201
1202/* converts DCE UUID (uuid[16]) to human readable string
1203 * - the @len should be always 37 */
1204void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len)
1205{
1206#ifdef HAVE_LIBUUID
1207 uuid_unparse(uuid, str);
1208#else
1209 snprintf(str, len,
1210 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1211 uuid[0], uuid[1], uuid[2], uuid[3],
1212 uuid[4], uuid[5],
1213 uuid[6], uuid[7],
1214 uuid[8], uuid[9],
1215 uuid[10], uuid[11], uuid[12], uuid[13], uuid[14],uuid[15]);
1216#endif
1217}
1218
c2dbd49b
KZ
1219
1220/* Removes whitespace from the right-hand side of a string (trailing
1221 * whitespace).
1222 *
1223 * Returns size of the new string (without \0).
1224 */
1225size_t blkid_rtrim_whitespace(unsigned char *str)
1226{
1227 size_t i = strlen((char *) str);
1228
1229 while (i--) {
1230 if (!isspace(str[i]))
1231 break;
1232 }
1233 str[++i] = '\0';
1234 return i;
1235}
1236