~ubuntu-branches/ubuntu/utopic/grub2/utopic

« back to all changes in this revision

Viewing changes to .pc/probe-delimiter.patch/util/grub-probe.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson, Colin Watson, Jon Severinsson
  • Date: 2014-03-31 16:30:37 UTC
  • mfrom: (17.3.93 sid)
  • Revision ID: package-import@ubuntu.com-20140331163037-b7h7nc1lf6st1z87
Tags: 2.02~beta2-8
[ Colin Watson ]
* Backport from upstream:
  - ieee1275: check for IBM pseries emulated machine.
  - Fix partmap, cryptodisk, and abstraction handling in grub-mkconfig
    (closes: #735935).
  - btrfs: fix get_root key comparison failures due to endianness.
* Build-depend on automake (>= 1.10.1) to ensure that it meets configure's
  requirements (LP: #1299041).
* When installing an image for use with UEFI Secure Boot, generate a
  load.cfg even if there are no device abstractions in use (LP: #1298399).

[ Jon Severinsson ]
* Add Tanglu support, as in Debian except:
  - Enable splash screen by default (as Ubuntu)
  - Enable quiet and quick boot (as Ubuntu)
  - Enable the grub-common init script (as Ubuntu)
  - Enable dynamic gfxpayload (as Ubuntu)
  - Enable vt handover (as Ubuntu)
  - Use monochromatic theme by default (as Ubuntu)
  - Use Tanglu GRUB wallpaper by default.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* grub-probe.c - probe device information for a given path */
 
2
/*
 
3
 *  GRUB  --  GRand Unified Bootloader
 
4
 *  Copyright (C) 2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
 
5
 *
 
6
 *  GRUB is free software: you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation, either version 3 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  GRUB is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include <config.h>
 
21
#include <grub/types.h>
 
22
#include <grub/emu/misc.h>
 
23
#include <grub/util/misc.h>
 
24
#include <grub/device.h>
 
25
#include <grub/disk.h>
 
26
#include <grub/file.h>
 
27
#include <grub/fs.h>
 
28
#include <grub/partition.h>
 
29
#include <grub/msdos_partition.h>
 
30
#include <grub/gpt_partition.h>
 
31
#include <grub/emu/hostdisk.h>
 
32
#include <grub/emu/getroot.h>
 
33
#include <grub/term.h>
 
34
#include <grub/env.h>
 
35
#include <grub/diskfilter.h>
 
36
#include <grub/i18n.h>
 
37
#include <grub/emu/misc.h>
 
38
#include <grub/util/ofpath.h>
 
39
#include <grub/crypto.h>
 
40
#include <grub/cryptodisk.h>
 
41
 
 
42
#include <stdio.h>
 
43
#include <unistd.h>
 
44
#include <string.h>
 
45
#include <stdlib.h>
 
46
#include <assert.h>
 
47
 
 
48
#define _GNU_SOURCE     1
 
49
 
 
50
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
 
51
#pragma GCC diagnostic ignored "-Wmissing-declarations"
 
52
#include <argp.h>
 
53
#pragma GCC diagnostic error "-Wmissing-prototypes"
 
54
#pragma GCC diagnostic error "-Wmissing-declarations"
 
55
 
 
56
#include "progname.h"
 
57
 
 
58
enum {
 
59
  PRINT_FS,
 
60
  PRINT_FS_UUID,
 
61
  PRINT_FS_LABEL,
 
62
  PRINT_DRIVE,
 
63
  PRINT_DEVICE,
 
64
  PRINT_PARTMAP,
 
65
  PRINT_ABSTRACTION,
 
66
  PRINT_CRYPTODISK_UUID,
 
67
  PRINT_HINT_STR,
 
68
  PRINT_BIOS_HINT,
 
69
  PRINT_IEEE1275_HINT,
 
70
  PRINT_BAREMETAL_HINT,
 
71
  PRINT_EFI_HINT,
 
72
  PRINT_ARC_HINT,
 
73
  PRINT_COMPATIBILITY_HINT,
 
74
  PRINT_MSDOS_PARTTYPE,
 
75
  PRINT_GPT_PARTTYPE,
 
76
  PRINT_ZERO_CHECK,
 
77
  PRINT_DISK
 
78
};
 
79
 
 
80
static const char *targets[] =
 
81
  {
 
82
    [PRINT_FS]                 = "fs",
 
83
    [PRINT_FS_UUID]            = "fs_uuid",
 
84
    [PRINT_FS_LABEL]           = "fs_label",
 
85
    [PRINT_DRIVE]              = "drive",
 
86
    [PRINT_DEVICE]             = "device",
 
87
    [PRINT_PARTMAP]            = "partmap",
 
88
    [PRINT_ABSTRACTION]        = "abstraction",
 
89
    [PRINT_CRYPTODISK_UUID]    = "cryptodisk_uuid",
 
90
    [PRINT_HINT_STR]           = "hints_string",
 
91
    [PRINT_BIOS_HINT]          = "bios_hints",
 
92
    [PRINT_IEEE1275_HINT]      = "ieee1275_hints",
 
93
    [PRINT_BAREMETAL_HINT]     = "baremetal_hints",
 
94
    [PRINT_EFI_HINT]           = "efi_hints",
 
95
    [PRINT_ARC_HINT]           = "arc_hints",
 
96
    [PRINT_COMPATIBILITY_HINT] = "compatibility_hint",
 
97
    [PRINT_MSDOS_PARTTYPE]     = "msdos_parttype",
 
98
    [PRINT_GPT_PARTTYPE]       = "gpt_parttype",
 
99
    [PRINT_ZERO_CHECK]         = "zero_check",
 
100
    [PRINT_DISK]               = "disk",
 
101
  };
 
102
 
 
103
static int print = PRINT_FS;
 
104
static unsigned int argument_is_device = 0;
 
105
 
 
106
static char *
 
107
get_targets_string (void)
 
108
{
 
109
  char **arr = xmalloc (sizeof (targets));
 
110
  int len = 0;
 
111
  char *str;
 
112
  char *ptr;
 
113
  unsigned i;
 
114
 
 
115
  memcpy (arr, targets, sizeof (targets));
 
116
  qsort (arr, ARRAY_SIZE (targets), sizeof (char *), grub_qsort_strcmp);
 
117
  for (i = 0; i < ARRAY_SIZE (targets); i++)
 
118
    len += grub_strlen (targets[i]) + 2;
 
119
  ptr = str = xmalloc (len);
 
120
  for (i = 0; i < ARRAY_SIZE (targets); i++)
 
121
    {
 
122
      ptr = grub_stpcpy (ptr, arr[i]);
 
123
      *ptr++ = ',';
 
124
      *ptr++ = ' ';
 
125
    }
 
126
  ptr[-2] = '\0';
 
127
  free (arr);
 
128
 
 
129
  return str;
 
130
}
 
131
 
 
132
static void
 
133
do_print (const char *x)
 
134
{
 
135
  grub_printf ("%s ", x);
 
136
}
 
137
 
 
138
static void
 
139
probe_partmap (grub_disk_t disk)
 
140
{
 
141
  grub_partition_t part;
 
142
  grub_disk_memberlist_t list = NULL, tmp;
 
143
 
 
144
  if (disk->partition == NULL)
 
145
    {
 
146
      grub_util_info ("no partition map found for %s", disk->name);
 
147
    }
 
148
 
 
149
  for (part = disk->partition; part; part = part->parent)
 
150
    printf ("%s ", part->partmap->name);
 
151
 
 
152
  if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID)
 
153
    grub_diskfilter_get_partmap (disk, do_print);
 
154
 
 
155
  /* In case of LVM/RAID, check the member devices as well.  */
 
156
  if (disk->dev->memberlist)
 
157
    {
 
158
      list = disk->dev->memberlist (disk);
 
159
    }
 
160
  while (list)
 
161
    {
 
162
      probe_partmap (list->disk);
 
163
      tmp = list->next;
 
164
      free (list);
 
165
      list = tmp;
 
166
    }
 
167
}
 
168
 
 
169
static void
 
170
probe_cryptodisk_uuid (grub_disk_t disk)
 
171
{
 
172
  grub_disk_memberlist_t list = NULL, tmp;
 
173
 
 
174
  /* In case of LVM/RAID, check the member devices as well.  */
 
175
  if (disk->dev->memberlist)
 
176
    {
 
177
      list = disk->dev->memberlist (disk);
 
178
    }
 
179
  while (list)
 
180
    {
 
181
      probe_cryptodisk_uuid (list->disk);
 
182
      tmp = list->next;
 
183
      free (list);
 
184
      list = tmp;
 
185
    }
 
186
  if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
 
187
    {
 
188
      const char *uu = grub_util_cryptodisk_get_uuid (disk);
 
189
      grub_printf ("%s ", uu);
 
190
    }
 
191
}
 
192
 
 
193
static int
 
194
probe_raid_level (grub_disk_t disk)
 
195
{
 
196
  /* disk might be NULL in the case of a LVM physical volume with no LVM
 
197
     signature.  Ignore such cases here.  */
 
198
  if (!disk)
 
199
    return -1;
 
200
 
 
201
  if (disk->dev->id != GRUB_DISK_DEVICE_DISKFILTER_ID)
 
202
    return -1;
 
203
 
 
204
  if (disk->name[0] != 'm' || disk->name[1] != 'd')
 
205
    return -1;
 
206
 
 
207
  if (!((struct grub_diskfilter_lv *) disk->data)->segments)
 
208
    return -1;
 
209
  return ((struct grub_diskfilter_lv *) disk->data)->segments->type;
 
210
}
 
211
 
 
212
static void
 
213
probe_abstraction (grub_disk_t disk)
 
214
{
 
215
  grub_disk_memberlist_t list = NULL, tmp;
 
216
  int raid_level;
 
217
 
 
218
  if (disk->dev->memberlist)
 
219
    list = disk->dev->memberlist (disk);
 
220
  while (list)
 
221
    {
 
222
      probe_abstraction (list->disk);
 
223
 
 
224
      tmp = list->next;
 
225
      free (list);
 
226
      list = tmp;
 
227
    }
 
228
 
 
229
  if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID
 
230
      && (grub_memcmp (disk->name, "lvm/", sizeof ("lvm/") - 1) == 0 ||
 
231
          grub_memcmp (disk->name, "lvmid/", sizeof ("lvmid/") - 1) == 0))
 
232
    printf ("lvm ");
 
233
 
 
234
  if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID
 
235
      && grub_memcmp (disk->name, "ldm/", sizeof ("ldm/") - 1) == 0)
 
236
    printf ("ldm ");
 
237
 
 
238
  if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
 
239
    grub_util_cryptodisk_get_abstraction (disk, do_print);
 
240
 
 
241
  raid_level = probe_raid_level (disk);
 
242
  if (raid_level >= 0)
 
243
    {
 
244
      printf ("diskfilter ");
 
245
      if (disk->dev->raidname)
 
246
        printf ("%s ", disk->dev->raidname (disk));
 
247
    }
 
248
  if (raid_level == 5)
 
249
    printf ("raid5rec ");
 
250
  if (raid_level == 6)
 
251
    printf ("raid6rec ");
 
252
}
 
253
 
 
254
static void
 
255
probe (const char *path, char **device_names, char delim)
 
256
{
 
257
  char **drives_names = NULL;
 
258
  char **curdev, **curdrive;
 
259
  char *grub_path = NULL;
 
260
  int ndev = 0;
 
261
 
 
262
  if (path != NULL)
 
263
    {
 
264
      grub_path = canonicalize_file_name (path);
 
265
      if (! grub_path)
 
266
        grub_util_error (_("failed to get canonical path of `%s'"), path);
 
267
      device_names = grub_guess_root_devices (grub_path);
 
268
      free (grub_path);
 
269
    }
 
270
 
 
271
  if (! device_names)
 
272
    grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), path);
 
273
 
 
274
  if (print == PRINT_DEVICE)
 
275
    {
 
276
      for (curdev = device_names; *curdev; curdev++)
 
277
        {
 
278
          printf ("%s", *curdev);
 
279
          putchar (delim);
 
280
        }
 
281
      return;
 
282
    }
 
283
 
 
284
  if (print == PRINT_DISK)
 
285
    {
 
286
      for (curdev = device_names; *curdev; curdev++)
 
287
        {
 
288
          char *disk;
 
289
          disk = grub_util_get_os_disk (*curdev);
 
290
          if (!disk)
 
291
            {
 
292
              grub_print_error ();
 
293
              continue;
 
294
            }
 
295
          printf ("%s", disk);
 
296
          putchar (delim);
 
297
        }
 
298
      return;
 
299
    }
 
300
 
 
301
  for (curdev = device_names; *curdev; curdev++)
 
302
    {
 
303
      grub_util_pull_device (*curdev);
 
304
      ndev++;
 
305
    }
 
306
  
 
307
  drives_names = xmalloc (sizeof (drives_names[0]) * (ndev + 1)); 
 
308
 
 
309
  for (curdev = device_names, curdrive = drives_names; *curdev; curdev++,
 
310
       curdrive++)
 
311
    {
 
312
      *curdrive = grub_util_get_grub_dev (*curdev);
 
313
      if (! *curdrive)
 
314
        grub_util_error (_("cannot find a GRUB drive for %s.  Check your device.map"),
 
315
                         *curdev);
 
316
    }
 
317
  *curdrive = 0;
 
318
 
 
319
  if (print == PRINT_DRIVE)
 
320
    {
 
321
      for (curdrive = drives_names; *curdrive; curdrive++)
 
322
        {
 
323
          printf ("(%s)", *curdrive);
 
324
          putchar (delim);
 
325
        }
 
326
      goto end;
 
327
    }
 
328
 
 
329
  if (print == PRINT_ZERO_CHECK)
 
330
    {
 
331
      for (curdev = drives_names; *curdev; curdev++)
 
332
        {
 
333
          grub_device_t dev = NULL;
 
334
          grub_uint32_t buffer[32768];
 
335
          grub_disk_addr_t addr;
 
336
          grub_disk_addr_t dsize;
 
337
 
 
338
          grub_util_info ("opening %s", *curdev);
 
339
          dev = grub_device_open (*curdev);
 
340
          if (! dev || !dev->disk)
 
341
            grub_util_error ("%s", grub_errmsg);
 
342
 
 
343
          dsize = grub_disk_get_size (dev->disk);
 
344
          for (addr = 0; addr < dsize;
 
345
               addr += sizeof (buffer) / GRUB_DISK_SECTOR_SIZE)
 
346
            {
 
347
              grub_size_t sz = sizeof (buffer);
 
348
              grub_uint32_t *ptr;
 
349
 
 
350
              if (sizeof (buffer) / GRUB_DISK_SECTOR_SIZE > dsize - addr)
 
351
                sz = (dsize - addr) * GRUB_DISK_SECTOR_SIZE;
 
352
              grub_disk_read (dev->disk, addr, 0, sz, buffer);
 
353
 
 
354
              for (ptr = buffer; ptr < buffer + sz / sizeof (*buffer); ptr++)
 
355
                if (*ptr)
 
356
                  {
 
357
                    grub_printf ("false\n");
 
358
                    grub_device_close (dev);
 
359
                    goto end;
 
360
                  }
 
361
            }
 
362
 
 
363
          grub_device_close (dev);
 
364
        }
 
365
      grub_printf ("true\n");
 
366
    }
 
367
 
 
368
  if (print == PRINT_FS || print == PRINT_FS_UUID
 
369
      || print == PRINT_FS_LABEL)
 
370
    {
 
371
      grub_device_t dev = NULL;
 
372
      grub_fs_t fs;
 
373
 
 
374
      grub_util_info ("opening %s", drives_names[0]);
 
375
      dev = grub_device_open (drives_names[0]);
 
376
      if (! dev)
 
377
        grub_util_error ("%s", grub_errmsg);
 
378
      
 
379
      fs = grub_fs_probe (dev);
 
380
      if (! fs)
 
381
        grub_util_error ("%s", grub_errmsg);
 
382
 
 
383
      if (print == PRINT_FS)
 
384
        {
 
385
          printf ("%s", fs->name);
 
386
          putchar (delim);
 
387
        }
 
388
      else if (print == PRINT_FS_UUID)
 
389
        {
 
390
          char *uuid;
 
391
          if (! fs->uuid)
 
392
            grub_util_error (_("%s does not support UUIDs"), fs->name);
 
393
 
 
394
          if (fs->uuid (dev, &uuid) != GRUB_ERR_NONE)
 
395
            grub_util_error ("%s", grub_errmsg);
 
396
 
 
397
          printf ("%s", uuid);
 
398
          putchar (delim);
 
399
        }
 
400
      else if (print == PRINT_FS_LABEL)
 
401
        {
 
402
          char *label;
 
403
          if (! fs->label)
 
404
            grub_util_error (_("filesystem `%s' does not support labels"),
 
405
                             fs->name);
 
406
 
 
407
          if (fs->label (dev, &label) != GRUB_ERR_NONE)
 
408
            grub_util_error ("%s", grub_errmsg);
 
409
 
 
410
          printf ("%s", label);
 
411
          putchar (delim);
 
412
        }
 
413
      grub_device_close (dev);
 
414
      goto end;
 
415
    }
 
416
 
 
417
  for (curdrive = drives_names, curdev = device_names; *curdrive;
 
418
       curdrive++, curdev++)
 
419
    {
 
420
      grub_device_t dev = NULL;
 
421
 
 
422
      grub_util_info ("opening %s", *curdrive);
 
423
      dev = grub_device_open (*curdrive);
 
424
      if (! dev)
 
425
        grub_util_error ("%s", grub_errmsg);
 
426
 
 
427
      if (print == PRINT_HINT_STR)
 
428
        {
 
429
          const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
 
430
          const char *ofpath = osdev ? grub_util_devname_to_ofpath (osdev) : 0;
 
431
          char *biosname, *bare, *efi;
 
432
          const char *map;
 
433
 
 
434
          if (ofpath)
 
435
            {
 
436
              char *tmp = xmalloc (strlen (ofpath) + sizeof ("ieee1275/"));
 
437
              char *p;
 
438
              p = grub_stpcpy (tmp, "ieee1275/");
 
439
              strcpy (p, ofpath);
 
440
              printf ("--hint-ieee1275='");
 
441
              grub_util_fprint_full_disk_name (stdout, tmp, dev);
 
442
              printf ("' ");
 
443
              free (tmp);
 
444
            }
 
445
 
 
446
          biosname = grub_util_guess_bios_drive (*curdev);
 
447
          if (biosname)
 
448
            {
 
449
              printf ("--hint-bios=");
 
450
              grub_util_fprint_full_disk_name (stdout, biosname, dev);
 
451
              printf (" ");
 
452
            }
 
453
          free (biosname);
 
454
 
 
455
          efi = grub_util_guess_efi_drive (*curdev);
 
456
          if (efi)
 
457
            {
 
458
              printf ("--hint-efi=");
 
459
              grub_util_fprint_full_disk_name (stdout, efi, dev);
 
460
              printf (" ");
 
461
            }
 
462
          free (efi);
 
463
 
 
464
          bare = grub_util_guess_baremetal_drive (*curdev);
 
465
          if (bare)
 
466
            {
 
467
              printf ("--hint-baremetal=");
 
468
              grub_util_fprint_full_disk_name (stdout, bare, dev);
 
469
              printf (" ");
 
470
            }
 
471
          free (bare);
 
472
 
 
473
          /* FIXME: Add ARC hint.  */
 
474
 
 
475
          map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
 
476
          if (map)
 
477
            {
 
478
              printf ("--hint='");
 
479
              grub_util_fprint_full_disk_name (stdout, map, dev);
 
480
              printf ("' ");
 
481
            }
 
482
          if (curdrive[1])
 
483
            printf (" ");
 
484
          else
 
485
            printf ("\n");
 
486
 
 
487
          grub_device_close (dev);
 
488
          continue;
 
489
        }
 
490
      
 
491
      if ((print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT
 
492
           || print == PRINT_IEEE1275_HINT || print == PRINT_BAREMETAL_HINT
 
493
           || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
 
494
          && dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
 
495
        {
 
496
          grub_util_fprint_full_disk_name (stdout, dev->disk->name, dev);
 
497
          putchar (delim);
 
498
          continue;
 
499
        }
 
500
 
 
501
      if (print == PRINT_COMPATIBILITY_HINT)
 
502
        {
 
503
          const char *map;
 
504
          char *biosname;
 
505
          map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
 
506
          if (map)
 
507
            {
 
508
              grub_util_fprint_full_disk_name (stdout, map, dev);
 
509
              putchar (delim);
 
510
              grub_device_close (dev);
 
511
              /* Compatibility hint is one device only.  */
 
512
              break;
 
513
            }
 
514
          biosname = grub_util_guess_bios_drive (*curdev);
 
515
          if (biosname)
 
516
            {
 
517
              grub_util_fprint_full_disk_name (stdout, biosname, dev);
 
518
              putchar (delim);
 
519
            }
 
520
          free (biosname);
 
521
          grub_device_close (dev);
 
522
          /* Compatibility hint is one device only.  */
 
523
          if (biosname)
 
524
            break;
 
525
          continue;
 
526
        }
 
527
 
 
528
      if (print == PRINT_BIOS_HINT)
 
529
        {
 
530
          char *biosname;
 
531
          biosname = grub_util_guess_bios_drive (*curdev);
 
532
          if (biosname)
 
533
            {
 
534
              grub_util_fprint_full_disk_name (stdout, biosname, dev);
 
535
              putchar (delim);
 
536
            }
 
537
          free (biosname);
 
538
          grub_device_close (dev);
 
539
          continue;
 
540
        }
 
541
      if (print == PRINT_IEEE1275_HINT)
 
542
        {
 
543
          const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
 
544
          const char *ofpath = grub_util_devname_to_ofpath (osdev);
 
545
          const char *map;
 
546
 
 
547
          map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
 
548
          if (map)
 
549
            {
 
550
              grub_util_fprint_full_disk_name (stdout, map, dev);
 
551
              putchar (delim);
 
552
            }
 
553
 
 
554
          if (ofpath)
 
555
            {
 
556
              char *tmp = xmalloc (strlen (ofpath) + sizeof ("ieee1275/"));
 
557
              char *p;
 
558
              p = grub_stpcpy (tmp, "ieee1275/");
 
559
              strcpy (p, ofpath);
 
560
              grub_util_fprint_full_disk_name (stdout, tmp, dev);
 
561
              free (tmp);
 
562
              putchar (delim);
 
563
            }
 
564
 
 
565
          grub_device_close (dev);
 
566
          continue;
 
567
        }
 
568
      if (print == PRINT_EFI_HINT)
 
569
        {
 
570
          char *biosname;
 
571
          const char *map;
 
572
          biosname = grub_util_guess_efi_drive (*curdev);
 
573
 
 
574
          map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
 
575
          if (map)
 
576
            {
 
577
              grub_util_fprint_full_disk_name (stdout, map, dev);
 
578
              putchar (delim);
 
579
            }
 
580
          if (biosname)
 
581
            {
 
582
              grub_util_fprint_full_disk_name (stdout, biosname, dev);
 
583
              putchar (delim);
 
584
            }
 
585
 
 
586
          free (biosname);
 
587
          grub_device_close (dev);
 
588
          continue;
 
589
        }
 
590
 
 
591
      if (print == PRINT_BAREMETAL_HINT)
 
592
        {
 
593
          char *biosname;
 
594
          const char *map;
 
595
 
 
596
          biosname = grub_util_guess_baremetal_drive (*curdev);
 
597
 
 
598
          map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
 
599
          if (map)
 
600
            {
 
601
              grub_util_fprint_full_disk_name (stdout, map, dev);
 
602
              putchar (delim);
 
603
            }
 
604
          if (biosname)
 
605
            {
 
606
              grub_util_fprint_full_disk_name (stdout, biosname, dev);
 
607
              putchar (delim);
 
608
            }
 
609
 
 
610
          free (biosname);
 
611
          grub_device_close (dev);
 
612
          continue;
 
613
        }
 
614
 
 
615
      if (print == PRINT_ARC_HINT)
 
616
        {
 
617
          const char *map;
 
618
 
 
619
          map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
 
620
          if (map)
 
621
            {
 
622
              grub_util_fprint_full_disk_name (stdout, map, dev);
 
623
              putchar (delim);
 
624
            }
 
625
 
 
626
          /* FIXME */
 
627
          grub_device_close (dev);
 
628
          continue;
 
629
        }
 
630
 
 
631
      if (print == PRINT_ABSTRACTION)
 
632
        {
 
633
          probe_abstraction (dev->disk);
 
634
          putchar (delim);
 
635
          grub_device_close (dev);
 
636
          continue;
 
637
        }
 
638
 
 
639
      if (print == PRINT_CRYPTODISK_UUID)
 
640
        {
 
641
          probe_cryptodisk_uuid (dev->disk);
 
642
          putchar (delim);
 
643
          grub_device_close (dev);
 
644
          continue;
 
645
        }
 
646
 
 
647
      if (print == PRINT_PARTMAP)
 
648
        {
 
649
          /* Check if dev->disk itself is contained in a partmap.  */
 
650
          probe_partmap (dev->disk);
 
651
          putchar (delim);
 
652
          grub_device_close (dev);
 
653
          continue;
 
654
        }
 
655
 
 
656
      if (print == PRINT_MSDOS_PARTTYPE)
 
657
        {
 
658
          if (dev->disk->partition
 
659
              && strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
 
660
            printf ("%02x", dev->disk->partition->msdostype);
 
661
 
 
662
          putchar (delim);
 
663
          grub_device_close (dev);
 
664
          continue;
 
665
        }
 
666
 
 
667
      if (print == PRINT_GPT_PARTTYPE)
 
668
        {
 
669
          if (dev->disk->partition
 
670
              && strcmp (dev->disk->partition->partmap->name, "gpt") == 0)
 
671
            {
 
672
              struct grub_gpt_partentry gptdata;
 
673
              grub_partition_t p = dev->disk->partition;
 
674
              dev->disk->partition = dev->disk->partition->parent;
 
675
 
 
676
              if (grub_disk_read (dev->disk, p->offset, p->index,
 
677
                                  sizeof (gptdata), &gptdata) == 0)
 
678
                {
 
679
                  grub_gpt_part_type_t gpttype;
 
680
                  gpttype.data1 = grub_le_to_cpu32 (gptdata.type.data1);
 
681
                  gpttype.data2 = grub_le_to_cpu16 (gptdata.type.data2);
 
682
                  gpttype.data3 = grub_le_to_cpu16 (gptdata.type.data3);
 
683
                  grub_memcpy (gpttype.data4, gptdata.type.data4, 8);
 
684
 
 
685
                  grub_printf ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
 
686
                               gpttype.data1, gpttype.data2,
 
687
                               gpttype.data3, gpttype.data4[0], 
 
688
                               gpttype.data4[1], gpttype.data4[2],
 
689
                               gpttype.data4[3], gpttype.data4[4],
 
690
                               gpttype.data4[5], gpttype.data4[6],
 
691
                               gpttype.data4[7]);
 
692
                }
 
693
              dev->disk->partition = p;
 
694
            }
 
695
          putchar (delim);
 
696
          grub_device_close (dev);
 
697
          continue;
 
698
        }
 
699
    }
 
700
 
 
701
 end:
 
702
  for (curdrive = drives_names; *curdrive; curdrive++)
 
703
    free (*curdrive);
 
704
  free (drives_names);
 
705
}
 
706
 
 
707
static struct argp_option options[] = {
 
708
  {"device",  'd', 0, 0,
 
709
   N_("given argument is a system device, not a path"), 0},
 
710
  {"device-map",  'm', N_("FILE"), 0,
 
711
   N_("use FILE as the device map [default=%s]"), 0},
 
712
  {"target",  't', N_("TARGET"), 0, 0, 0},
 
713
  {"verbose",     'v', 0,      0, N_("print verbose messages."), 0},
 
714
  { 0, 0, 0, 0, 0, 0 }
 
715
};
 
716
 
 
717
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
 
718
 
 
719
static char *
 
720
help_filter (int key, const char *text, void *input __attribute__ ((unused)))
 
721
{
 
722
  switch (key)
 
723
    {
 
724
      case 'm':
 
725
        return xasprintf (text, DEFAULT_DEVICE_MAP);
 
726
 
 
727
      case 't':
 
728
        {
 
729
          char *ret, *t = get_targets_string ();
 
730
 
 
731
          ret = xasprintf ("%s\n%s %s [default=%s]", _("print TARGET"),
 
732
                            _("available targets:"), t, targets[print]);
 
733
          free (t);
 
734
          return ret;
 
735
        }
 
736
 
 
737
      default:
 
738
        return (char *) text;
 
739
    }
 
740
}
 
741
 
 
742
#pragma GCC diagnostic error "-Wformat-nonliteral"
 
743
 
 
744
struct arguments
 
745
{
 
746
  char **devices;
 
747
  size_t device_max;
 
748
  size_t ndevices;
 
749
  char *dev_map;
 
750
  int zero_delim;
 
751
};
 
752
 
 
753
static error_t
 
754
argp_parser (int key, char *arg, struct argp_state *state)
 
755
{
 
756
  /* Get the input argument from argp_parse, which we
 
757
     know is a pointer to our arguments structure. */
 
758
  struct arguments *arguments = state->input;
 
759
 
 
760
  switch (key)
 
761
    {
 
762
    case 'd':
 
763
      argument_is_device = 1;
 
764
      break;
 
765
 
 
766
    case 'm':
 
767
      if (arguments->dev_map)
 
768
        free (arguments->dev_map);
 
769
 
 
770
      arguments->dev_map = xstrdup (arg);
 
771
      break;
 
772
 
 
773
    case 't':
 
774
      {
 
775
        int i;
 
776
 
 
777
        for (i = PRINT_FS; i < ARRAY_SIZE (targets); i++)
 
778
          if (strcmp (arg, targets[i]) == 0)
 
779
            {
 
780
              print = i;
 
781
              break;
 
782
            }
 
783
        if (i == ARRAY_SIZE (targets))
 
784
          argp_usage (state);
 
785
      }
 
786
      break;
 
787
 
 
788
    case '0':
 
789
      arguments->zero_delim = 1;
 
790
      break;
 
791
 
 
792
    case 'v':
 
793
      verbosity++;
 
794
      break;
 
795
 
 
796
    case ARGP_KEY_NO_ARGS:
 
797
      fprintf (stderr, "%s", _("No path or device is specified.\n"));
 
798
      argp_usage (state);
 
799
      break;
 
800
 
 
801
    case ARGP_KEY_ARG:
 
802
      assert (arguments->ndevices < arguments->device_max);
 
803
      arguments->devices[arguments->ndevices++] = xstrdup(arg);
 
804
      break;
 
805
 
 
806
    default:
 
807
      return ARGP_ERR_UNKNOWN;
 
808
    }
 
809
  return 0;
 
810
}
 
811
 
 
812
static struct argp argp = {
 
813
  options, argp_parser, N_("[OPTION]... [PATH|DEVICE]"),
 
814
  N_("\
 
815
Probe device information for a given path (or device, if the -d option is given)."),
 
816
  NULL, help_filter, NULL
 
817
};
 
818
 
 
819
int
 
820
main (int argc, char *argv[])
 
821
{
 
822
  char delim;
 
823
  struct arguments arguments;
 
824
 
 
825
  grub_util_host_init (&argc, &argv);
 
826
 
 
827
  memset (&arguments, 0, sizeof (struct arguments));
 
828
  arguments.device_max = argc + 1;
 
829
  arguments.devices = xmalloc ((arguments.device_max + 1)
 
830
                               * sizeof (arguments.devices[0]));
 
831
  memset (arguments.devices, 0, (arguments.device_max + 1)
 
832
          * sizeof (arguments.devices[0]));
 
833
 
 
834
  /* Parse our arguments */
 
835
  if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
 
836
    {
 
837
      fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
 
838
      exit(1);
 
839
    }
 
840
 
 
841
  if (verbosity > 1)
 
842
    grub_env_set ("debug", "all");
 
843
 
 
844
  /* Obtain ARGUMENT.  */
 
845
  if (arguments.ndevices != 1 && !argument_is_device)
 
846
    {
 
847
      char *program = xstrdup(program_name);
 
848
      fprintf (stderr, _("Unknown extra argument `%s'."), arguments.devices[1]);
 
849
      fprintf (stderr, "\n");
 
850
      argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program);
 
851
      free (program);
 
852
      exit(1);
 
853
    }
 
854
 
 
855
  /* Initialize the emulated biosdisk driver.  */
 
856
  grub_util_biosdisk_init (arguments.dev_map ? : DEFAULT_DEVICE_MAP);
 
857
 
 
858
  /* Initialize all modules. */
 
859
  grub_init_all ();
 
860
  grub_gcry_init_all ();
 
861
 
 
862
  grub_lvm_fini ();
 
863
  grub_mdraid09_fini ();
 
864
  grub_mdraid1x_fini ();
 
865
  grub_diskfilter_fini ();
 
866
  grub_diskfilter_init ();
 
867
  grub_mdraid09_init ();
 
868
  grub_mdraid1x_init ();
 
869
  grub_lvm_init ();
 
870
 
 
871
  if (print == PRINT_BIOS_HINT
 
872
      || print == PRINT_IEEE1275_HINT || print == PRINT_BAREMETAL_HINT
 
873
      || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
 
874
    delim = ' ';
 
875
  else
 
876
    delim = '\n';
 
877
 
 
878
  if (arguments.zero_delim)
 
879
    delim = '\0';
 
880
 
 
881
  /* Do it.  */
 
882
  if (argument_is_device)
 
883
    probe (NULL, arguments.devices, delim);
 
884
  else
 
885
    probe (arguments.devices[0], NULL, delim);
 
886
 
 
887
  if (!arguments.zero_delim && (print == PRINT_BIOS_HINT
 
888
                                || print == PRINT_IEEE1275_HINT
 
889
                                || print == PRINT_BAREMETAL_HINT
 
890
                                || print == PRINT_EFI_HINT
 
891
                                || print == PRINT_ARC_HINT))
 
892
    putchar ('\n');
 
893
 
 
894
  /* Free resources.  */
 
895
  grub_gcry_fini_all ();
 
896
  grub_fini_all ();
 
897
  grub_util_biosdisk_fini ();
 
898
 
 
899
  {
 
900
    size_t i;
 
901
    for (i = 0; i < arguments.ndevices; i++)
 
902
      free (arguments.devices[i]);
 
903
  }
 
904
  free (arguments.devices);
 
905
 
 
906
  free (arguments.dev_map);
 
907
 
 
908
  return 0;
 
909
}