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