~ubuntu-branches/ubuntu/trusty/util-linux/trusty-proposed

« back to all changes in this revision

Viewing changes to shlibs/blkid/src/probe.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones
  • Date: 2011-11-03 15:38:23 UTC
  • mto: (4.5.5 sid) (1.6.4)
  • mto: This revision was merged to the branch mainline in revision 85.
  • Revision ID: package-import@ubuntu.com-20111103153823-10sx16jprzxlhkqf
ImportĀ upstreamĀ versionĀ 2.20.1

Show diffs side-by-side

added added

removed removed

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