~ubuntu-branches/ubuntu/trusty/grub2/trusty

« back to all changes in this revision

Viewing changes to util/grub-install-common.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2014-01-16 15:18:04 UTC
  • mfrom: (17.6.38 experimental)
  • Revision ID: package-import@ubuntu.com-20140116151804-3foouk7fpqcq3sxx
Tags: 2.02~beta2-2
* Convert patch handling to git-dpm.
* Add bi-endian support to ELF parser (Tomohiro B Berry).
* Adjust restore_mkdevicemap.patch to mark get_kfreebsd_version as static,
  to appease "gcc -Werror=missing-prototypes".
* Cherry-pick from upstream:
  - Change grub-macbless' manual page section to 8.
* Install grub-glue-efi, grub-macbless, grub-render-label, and
  grub-syslinux2cfg.
* grub-shell: Pass -no-pad to xorriso when building floppy images.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  GRUB  --  GRand Unified Bootloader
 
3
 *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
 
4
 *
 
5
 *  GRUB is free software: you can redistribute it and/or modify
 
6
 *  it under the terms of the GNU General Public License as published by
 
7
 *  the Free Software Foundation, either version 3 of the License, or
 
8
 *  (at your option) any later version.
 
9
 *
 
10
 *  GRUB is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 
17
 */
 
18
 
 
19
#include <config.h>
 
20
#include <grub/types.h>
 
21
#include <grub/emu/misc.h>
 
22
#include <grub/util/misc.h>
 
23
#include <grub/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/env.h>
 
29
#include <grub/term.h>
 
30
#include <grub/mm.h>
 
31
#include <grub/lib/hexdump.h>
 
32
#include <grub/crypto.h>
 
33
#include <grub/command.h>
 
34
#include <grub/i18n.h>
 
35
#include <grub/zfs/zfs.h>
 
36
#include <grub/util/install.h>
 
37
#include <grub/util/resolve.h>
 
38
#include <grub/emu/hostfile.h>
 
39
#include <grub/emu/config.h>
 
40
#include <grub/emu/hostfile.h>
 
41
 
 
42
#include <stdio.h>
 
43
#include <unistd.h>
 
44
#include <string.h>
 
45
#include <stdlib.h>
 
46
#include <errno.h>
 
47
 
 
48
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
 
49
 
 
50
char *
 
51
grub_install_help_filter (int key, const char *text,
 
52
                                 void *input __attribute__ ((unused)))
 
53
{
 
54
  switch (key)
 
55
    {
 
56
    case GRUB_INSTALL_OPTIONS_INSTALL_THEMES:
 
57
      return xasprintf(text, "starfield");
 
58
    case GRUB_INSTALL_OPTIONS_INSTALL_FONTS:
 
59
      return xasprintf(text, "unicode");
 
60
    case GRUB_INSTALL_OPTIONS_DIRECTORY:
 
61
    case GRUB_INSTALL_OPTIONS_DIRECTORY2:
 
62
      return xasprintf(text, grub_util_get_pkglibdir ());      
 
63
    case GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY:
 
64
      return xasprintf(text, grub_util_get_localedir ());
 
65
    case GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY:
 
66
      return grub_util_path_concat (2, grub_util_get_pkgdatadir (), "themes");
 
67
    default:
 
68
      return (char *) text;
 
69
    }
 
70
}
 
71
 
 
72
#pragma GCC diagnostic error "-Wformat-nonliteral"
 
73
 
 
74
static int (*compress_func) (const char *src, const char *dest) = NULL;
 
75
char *grub_install_copy_buffer;
 
76
 
 
77
int
 
78
grub_install_copy_file (const char *src,
 
79
                        const char *dst,
 
80
                        int is_needed)
 
81
{
 
82
  grub_util_fd_t in, out;  
 
83
  ssize_t r;
 
84
 
 
85
  grub_util_info ("copying `%s' -> `%s'", src, dst);
 
86
 
 
87
  in = grub_util_fd_open (src, GRUB_UTIL_FD_O_RDONLY);
 
88
  if (!GRUB_UTIL_FD_IS_VALID (in))
 
89
    {
 
90
      if (is_needed)
 
91
        grub_util_error (_("cannot open `%s': %s"), src, grub_util_fd_strerror ());
 
92
      else
 
93
        grub_util_info (_("cannot open `%s': %s"), src, grub_util_fd_strerror ());
 
94
      return 0;
 
95
    }
 
96
  out = grub_util_fd_open (dst, GRUB_UTIL_FD_O_WRONLY
 
97
                           | GRUB_UTIL_FD_O_CREATTRUNC);
 
98
  if (!GRUB_UTIL_FD_IS_VALID (out))
 
99
    {
 
100
      grub_util_error (_("cannot open `%s': %s"), dst,
 
101
                       grub_util_fd_strerror ());
 
102
      grub_util_fd_close (in);
 
103
      return 0;
 
104
    }
 
105
 
 
106
  if (!grub_install_copy_buffer)
 
107
    grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE);
 
108
 
 
109
  while (1)
 
110
    {
 
111
      r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE);
 
112
      if (r <= 0)
 
113
        break;
 
114
      grub_util_fd_write (out, grub_install_copy_buffer, r);
 
115
    }
 
116
  grub_util_fd_sync (out);
 
117
  grub_util_fd_close (in);
 
118
  grub_util_fd_close (out);
 
119
 
 
120
  if (r < 0)
 
121
    grub_util_error (_("cannot copy `%s' to `%s': %s"),
 
122
                     src, dst, grub_util_fd_strerror ());
 
123
 
 
124
  return 1;
 
125
}
 
126
 
 
127
static int
 
128
grub_install_compress_file (const char *in_name,
 
129
                            const char *out_name,
 
130
                            int is_needed)
 
131
{
 
132
  int ret;
 
133
 
 
134
  if (!compress_func)
 
135
    ret = grub_install_copy_file (in_name, out_name, is_needed);
 
136
  else
 
137
    {
 
138
      grub_util_info ("compressing `%s' -> `%s'", in_name, out_name);
 
139
      ret = !compress_func (in_name, out_name);
 
140
      if (!ret && is_needed)
 
141
        grub_util_warn (_("can't compress `%s' to `%s'"), in_name, out_name);
 
142
    }
 
143
 
 
144
  if (!ret && is_needed)
 
145
    grub_util_error (_("cannot copy `%s' to `%s': %s"),
 
146
                     in_name, out_name, grub_util_fd_strerror ());
 
147
 
 
148
  return ret;
 
149
}
 
150
 
 
151
static int
 
152
is_path_separator (char c)
 
153
{
 
154
#if defined (__MINGW32__) || defined (__CYGWIN__)
 
155
  if (c == '\\')
 
156
    return 1;
 
157
#endif
 
158
  if (c == '/')
 
159
    return 1;
 
160
  return 0;
 
161
}
 
162
 
 
163
void
 
164
grub_install_mkdir_p (const char *dst)
 
165
{
 
166
  char *t = xstrdup (dst);
 
167
  char *p;
 
168
  for (p = t; *p; p++)
 
169
    {
 
170
      if (is_path_separator (*p))
 
171
        {
 
172
          char s = *p;
 
173
          *p = '\0';
 
174
          grub_util_mkdir (t);
 
175
          *p = s;
 
176
        }
 
177
    }
 
178
  grub_util_mkdir (t);
 
179
  free (t);
 
180
}
 
181
 
 
182
static void
 
183
clean_grub_dir (const char *di)
 
184
{
 
185
  grub_util_fd_dir_t d;
 
186
  grub_util_fd_dirent_t de;
 
187
 
 
188
  d = grub_util_fd_opendir (di);
 
189
  if (!d)
 
190
    grub_util_error (_("cannot open directory `%s': %s"),
 
191
                     di, grub_util_fd_strerror ());
 
192
 
 
193
  while ((de = grub_util_fd_readdir (d)))
 
194
    {
 
195
      const char *ext = strrchr (de->d_name, '.');
 
196
      if ((ext && (strcmp (ext, ".mod") == 0
 
197
                   || strcmp (ext, ".lst") == 0
 
198
                   || strcmp (ext, ".img") == 0
 
199
                   || strcmp (ext, ".mo") == 0)
 
200
           && strcmp (de->d_name, "menu.lst") != 0)
 
201
          || strcmp (de->d_name, "efiemu32.o") == 0
 
202
          || strcmp (de->d_name, "efiemu64.o") == 0)
 
203
        {
 
204
          char *x = grub_util_path_concat (2, di, de->d_name);
 
205
          if (grub_util_unlink (x) < 0)
 
206
            grub_util_error (_("cannot delete `%s': %s"), x,
 
207
                             grub_util_fd_strerror ());
 
208
          free (x);
 
209
        }
 
210
    }
 
211
  grub_util_fd_closedir (d);
 
212
}
 
213
 
 
214
struct install_list
 
215
{
 
216
  int is_default;
 
217
  char **entries;
 
218
  size_t n_entries;
 
219
  size_t n_alloc;
 
220
};
 
221
 
 
222
struct install_list install_modules = { 1, 0, 0, 0 };
 
223
struct install_list modules = { 1, 0, 0, 0 };
 
224
struct install_list install_locales = { 1, 0, 0, 0 };
 
225
struct install_list install_fonts = { 1, 0, 0, 0 };
 
226
struct install_list install_themes = { 1, 0, 0, 0 };
 
227
char *grub_install_source_directory = NULL;
 
228
char *grub_install_locale_directory = NULL;
 
229
char *grub_install_themes_directory = NULL;
 
230
 
 
231
void
 
232
grub_install_push_module (const char *val)
 
233
{
 
234
  modules.is_default = 0;
 
235
  if (modules.n_entries + 1 >= modules.n_alloc)
 
236
    {
 
237
      modules.n_alloc <<= 1;
 
238
      if (modules.n_alloc < 16)
 
239
        modules.n_alloc = 16;
 
240
      modules.entries = xrealloc (modules.entries,
 
241
                                  modules.n_alloc * sizeof (modules.entries));
 
242
    }
 
243
  modules.entries[modules.n_entries++] = xstrdup (val);
 
244
  modules.entries[modules.n_entries] = NULL;
 
245
}
 
246
 
 
247
void
 
248
grub_install_pop_module (void)
 
249
{
 
250
  modules.n_entries--;
 
251
  free (modules.entries[modules.n_entries]);
 
252
  modules.entries[modules.n_entries] = NULL;
 
253
}
 
254
 
 
255
 
 
256
static void
 
257
handle_install_list (struct install_list *il, const char *val,
 
258
                     int default_all)
 
259
{
 
260
  const char *ptr;
 
261
  char **ce;
 
262
  il->is_default = 0;
 
263
  free (il->entries);
 
264
  il->entries = NULL;
 
265
  il->n_entries = 0;
 
266
  if (strcmp (val, "all") == 0 && default_all)
 
267
    {
 
268
      il->is_default = 1;
 
269
      return;
 
270
    }
 
271
  ptr = val;
 
272
  while (1)
 
273
    {
 
274
      while (*ptr && grub_isspace (*ptr))
 
275
        ptr++;
 
276
      if (!*ptr)
 
277
        break;
 
278
      while (*ptr && !grub_isspace (*ptr))
 
279
        ptr++;
 
280
      il->n_entries++;
 
281
    }
 
282
  il->n_alloc = il->n_entries + 1;
 
283
  il->entries = xmalloc (il->n_alloc * sizeof (il->entries[0]));
 
284
  ptr = val;
 
285
  for (ce = il->entries; ; ce++)
 
286
    {
 
287
      const char *bptr;
 
288
      while (*ptr && grub_isspace (*ptr))
 
289
        ptr++;
 
290
      if (!*ptr)
 
291
        break;
 
292
      bptr = ptr;
 
293
      while (*ptr && !grub_isspace (*ptr))
 
294
        ptr++;
 
295
      *ce = xmalloc (ptr - bptr + 1);
 
296
      memcpy (*ce, bptr, ptr - bptr);
 
297
      (*ce)[ptr - bptr] = '\0';
 
298
    }
 
299
  *ce = NULL;
 
300
}
 
301
 
 
302
static char **pubkeys;
 
303
static size_t npubkeys;
 
304
static grub_compression_t compression;
 
305
 
 
306
int
 
307
grub_install_parse (int key, char *arg)
 
308
{
 
309
  switch (key)
 
310
    {
 
311
    case 'C':
 
312
      if (grub_strcmp (arg, "xz") == 0)
 
313
        {
 
314
#ifdef HAVE_LIBLZMA
 
315
          compression = GRUB_COMPRESSION_XZ;
 
316
#else
 
317
          grub_util_error ("%s",
 
318
                           _("grub-mkimage is compiled without XZ support"));
 
319
#endif
 
320
        }
 
321
      else if (grub_strcmp (arg, "none") == 0)
 
322
        compression = GRUB_COMPRESSION_NONE;
 
323
      else if (grub_strcmp (arg, "auto") == 0)
 
324
        compression = GRUB_COMPRESSION_AUTO;
 
325
      else
 
326
        grub_util_error (_("Unknown compression format %s"), arg);
 
327
      return 1;
 
328
    case 'k':
 
329
      pubkeys = xrealloc (pubkeys,
 
330
                          sizeof (pubkeys[0])
 
331
                          * (npubkeys + 1));
 
332
      pubkeys[npubkeys++] = xstrdup (arg);
 
333
      return 1;
 
334
 
 
335
    case GRUB_INSTALL_OPTIONS_VERBOSITY:
 
336
      verbosity++;
 
337
      return 1;
 
338
 
 
339
    case GRUB_INSTALL_OPTIONS_DIRECTORY:
 
340
    case GRUB_INSTALL_OPTIONS_DIRECTORY2:
 
341
      free (grub_install_source_directory);
 
342
      grub_install_source_directory = xstrdup (arg);
 
343
      return 1;
 
344
    case GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY:
 
345
      free (grub_install_locale_directory);
 
346
      grub_install_locale_directory = xstrdup (arg);
 
347
      return 1;
 
348
    case GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY:
 
349
      free (grub_install_themes_directory);
 
350
      grub_install_themes_directory = xstrdup (arg);
 
351
      return 1;
 
352
    case GRUB_INSTALL_OPTIONS_INSTALL_MODULES:
 
353
      handle_install_list (&install_modules, arg, 0);
 
354
      return 1;
 
355
    case GRUB_INSTALL_OPTIONS_MODULES:
 
356
      handle_install_list (&modules, arg, 0);
 
357
      return 1;
 
358
    case GRUB_INSTALL_OPTIONS_INSTALL_LOCALES:
 
359
      handle_install_list (&install_locales, arg, 0);
 
360
      return 1;
 
361
    case GRUB_INSTALL_OPTIONS_INSTALL_THEMES:
 
362
      handle_install_list (&install_themes, arg, 0);
 
363
      return 1;
 
364
    case GRUB_INSTALL_OPTIONS_INSTALL_FONTS:
 
365
      handle_install_list (&install_fonts, arg, 0);
 
366
      return 1;
 
367
    case GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS:
 
368
      if (strcmp (arg, "no") == 0
 
369
          || strcmp (arg, "none") == 0)
 
370
        {
 
371
          compress_func = NULL;
 
372
          return 1;
 
373
        }
 
374
      if (strcmp (arg, "gz") == 0)
 
375
        {
 
376
          compress_func = grub_install_compress_gzip;
 
377
          return 1;
 
378
        }
 
379
      if (strcmp (arg, "xz") == 0)
 
380
        {
 
381
          compress_func = grub_install_compress_xz;
 
382
          return 1;
 
383
        }
 
384
      if (strcmp (arg, "lzo") == 0)
 
385
        {
 
386
          compress_func = grub_install_compress_lzop;
 
387
          return 1;
 
388
        }
 
389
      grub_util_error (_("Unrecognized compression `%s'"), arg);
 
390
    case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE:
 
391
      return 1;
 
392
    default:
 
393
      return 0;
 
394
    }
 
395
}
 
396
 
 
397
static int
 
398
decompressors (void)
 
399
{
 
400
  if (compress_func == grub_install_compress_gzip)
 
401
    {
 
402
      grub_install_push_module ("gzio");
 
403
      return 1;
 
404
    }
 
405
  if (compress_func == grub_install_compress_xz)
 
406
    {
 
407
      grub_install_push_module ("xzio");
 
408
      grub_install_push_module ("gcry_crc");
 
409
      return 2;
 
410
    }
 
411
  if (compress_func == grub_install_compress_lzop)
 
412
    {
 
413
      grub_install_push_module ("lzopio");
 
414
      grub_install_push_module ("adler32");
 
415
      grub_install_push_module ("gcry_crc");
 
416
      return 3;
 
417
    }
 
418
  return 0;
 
419
}
 
420
 
 
421
void
 
422
grub_install_make_image_wrap_file (const char *dir, const char *prefix,
 
423
                                   FILE *fp, const char *outname,
 
424
                                   char *memdisk_path,
 
425
                                   char *config_path,
 
426
                                   const char *mkimage_target, int note)
 
427
{
 
428
  const struct grub_install_image_target_desc *tgt;
 
429
  const char *const compnames[] = 
 
430
    {
 
431
      [GRUB_COMPRESSION_AUTO] = "auto",
 
432
      [GRUB_COMPRESSION_NONE] = "none",
 
433
      [GRUB_COMPRESSION_XZ] = "xz",
 
434
      [GRUB_COMPRESSION_LZMA] = "lzma",
 
435
    };
 
436
  grub_size_t slen = 1;
 
437
  char *s, *p;
 
438
  char **pk, **md;
 
439
  int dc = decompressors ();
 
440
 
 
441
  if (memdisk_path)
 
442
    slen += 20 + grub_strlen (memdisk_path);
 
443
  if (config_path)
 
444
    slen += 20 + grub_strlen (config_path);
 
445
 
 
446
  for (pk = pubkeys; pk < pubkeys + npubkeys; pk++)
 
447
    slen += 20 + grub_strlen (*pk);
 
448
 
 
449
  for (md = modules.entries; *md; md++)
 
450
    {
 
451
      slen += 10 + grub_strlen (*md);
 
452
    }
 
453
 
 
454
  p = s = xmalloc (slen);
 
455
  if (memdisk_path)
 
456
    {
 
457
      p = grub_stpcpy (p, "--memdisk '");
 
458
      p = grub_stpcpy (p, memdisk_path);
 
459
      *p++ = '\'';
 
460
      *p++ = ' ';
 
461
    }
 
462
  if (config_path)
 
463
    {
 
464
      p = grub_stpcpy (p, "--config '");
 
465
      p = grub_stpcpy (p, config_path);
 
466
      *p++ = '\'';
 
467
      *p++ = ' ';
 
468
    }
 
469
  for (pk = pubkeys; pk < pubkeys + npubkeys; pk++)
 
470
    {
 
471
      p = grub_stpcpy (p, "--pubkey '");
 
472
      p = grub_stpcpy (p, *pk);
 
473
      *p++ = '\'';
 
474
      *p++ = ' ';
 
475
    }
 
476
 
 
477
  for (md = modules.entries; *md; md++)
 
478
    {
 
479
      *p++ = '\'';
 
480
      p = grub_stpcpy (p, *md);
 
481
      *p++ = '\'';
 
482
      *p++ = ' ';
 
483
    }
 
484
 
 
485
  *p = '\0';
 
486
 
 
487
  grub_util_info ("grub-mkimage --directory '%s' --prefix '%s'"
 
488
                  " --output '%s' "
 
489
                  "--format '%s' --compression '%s' %s %s\n",
 
490
                  dir, prefix,
 
491
                  outname, mkimage_target,
 
492
                  compnames[compression], note ? "--note" : "", s);
 
493
 
 
494
  tgt = grub_install_get_image_target (mkimage_target);
 
495
  if (!tgt)
 
496
    grub_util_error (_("unknown target format %s\n"), mkimage_target);
 
497
 
 
498
  grub_install_generate_image (dir, prefix, fp, outname,
 
499
                               modules.entries, memdisk_path,
 
500
                               pubkeys, npubkeys, config_path, tgt,
 
501
                               note, compression);
 
502
  while (dc--)
 
503
    grub_install_pop_module ();
 
504
}
 
505
 
 
506
void
 
507
grub_install_make_image_wrap (const char *dir, const char *prefix,
 
508
                              const char *outname, char *memdisk_path,
 
509
                              char *config_path,
 
510
                              const char *mkimage_target, int note)
 
511
{
 
512
  FILE *fp;
 
513
 
 
514
  fp = grub_util_fopen (outname, "wb");
 
515
  if (! fp)
 
516
    grub_util_error (_("cannot open `%s': %s"), outname,
 
517
                     strerror (errno));
 
518
  grub_install_make_image_wrap_file (dir, prefix, fp, outname,
 
519
                                     memdisk_path, config_path,
 
520
                                     mkimage_target, note);
 
521
  grub_util_file_sync (fp);
 
522
  fclose (fp);
 
523
}
 
524
 
 
525
static void
 
526
copy_by_ext (const char *srcd,
 
527
             const char *dstd,
 
528
             const char *extf,
 
529
             int req)
 
530
{
 
531
  grub_util_fd_dir_t d;
 
532
  grub_util_fd_dirent_t de;
 
533
 
 
534
  d = grub_util_fd_opendir (srcd);
 
535
  if (!d && !req)
 
536
    return;
 
537
  if (!d)
 
538
    grub_util_error (_("cannot open directory `%s': %s"),
 
539
                     srcd, grub_util_fd_strerror ());
 
540
 
 
541
  while ((de = grub_util_fd_readdir (d)))
 
542
    {
 
543
      const char *ext = strrchr (de->d_name, '.');
 
544
      if (ext && strcmp (ext, extf) == 0)
 
545
        {
 
546
          char *srcf = grub_util_path_concat (2, srcd, de->d_name);
 
547
          char *dstf = grub_util_path_concat (2, dstd, de->d_name);
 
548
          grub_install_compress_file (srcf, dstf, 1);
 
549
          free (srcf);
 
550
          free (dstf);
 
551
        }
 
552
    }
 
553
  grub_util_fd_closedir (d);
 
554
}
 
555
 
 
556
static void
 
557
copy_all (const char *srcd,
 
558
             const char *dstd)
 
559
{
 
560
  grub_util_fd_dir_t d;
 
561
  grub_util_fd_dirent_t de;
 
562
 
 
563
  d = grub_util_fd_opendir (srcd);
 
564
  if (!d)
 
565
    grub_util_error (_("cannot open directory `%s': %s"),
 
566
                     srcd, grub_util_fd_strerror ());
 
567
 
 
568
  while ((de = grub_util_fd_readdir (d)))
 
569
    {
 
570
      char *srcf;
 
571
      char *dstf;
 
572
      if (strcmp (de->d_name, ".") == 0
 
573
          || strcmp (de->d_name, "..") == 0)
 
574
        continue;
 
575
      srcf = grub_util_path_concat (2, srcd, de->d_name);
 
576
      if (grub_util_is_special_file (srcf)
 
577
          || grub_util_is_directory (srcf))
 
578
        continue;
 
579
      dstf = grub_util_path_concat (2, dstd, de->d_name);
 
580
      grub_install_compress_file (srcf, dstf, 1);
 
581
      free (srcf);
 
582
      free (dstf);
 
583
    }
 
584
  grub_util_fd_closedir (d);
 
585
}
 
586
 
 
587
static const char *
 
588
get_localedir (void)
 
589
{
 
590
  if (grub_install_locale_directory)
 
591
    return grub_install_locale_directory;
 
592
  else
 
593
    return grub_util_get_localedir ();
 
594
}
 
595
 
 
596
static void
 
597
copy_locales (const char *dstd, int langpack)
 
598
{
 
599
  grub_util_fd_dir_t d;
 
600
  grub_util_fd_dirent_t de;
 
601
  const char *locale_dir = get_localedir ();
 
602
  char *dir;
 
603
 
 
604
  if (langpack)
 
605
    dir = xasprintf ("%s-langpack", locale_dir);
 
606
  else
 
607
    dir = xstrdup (locale_dir);
 
608
 
 
609
  d = grub_util_fd_opendir (dir);
 
610
  if (!d)
 
611
    {
 
612
      if (!langpack)
 
613
        grub_util_warn (_("cannot open directory `%s': %s"),
 
614
                        dir, grub_util_fd_strerror ());
 
615
      free (dir);
 
616
      return;
 
617
    }
 
618
 
 
619
  while ((de = grub_util_fd_readdir (d)))
 
620
    {
 
621
      char *srcf;
 
622
      char *dstf;
 
623
      char *ext;
 
624
      if (strcmp (de->d_name, ".") == 0)
 
625
        continue;
 
626
      if (strcmp (de->d_name, "..") == 0)
 
627
        continue;
 
628
      ext = grub_strrchr (de->d_name, '.');
 
629
      if (ext && (grub_strcmp (ext, ".mo") == 0
 
630
                  || grub_strcmp (ext, ".gmo") == 0))
 
631
        {
 
632
          srcf = grub_util_path_concat (2, dir, de->d_name);
 
633
          dstf = grub_util_path_concat (2, dstd, de->d_name);
 
634
          ext = grub_strrchr (dstf, '.');
 
635
          grub_strcpy (ext, ".mo");
 
636
        }
 
637
      else
 
638
        {
 
639
          srcf = grub_util_path_concat_ext (4, dir, de->d_name,
 
640
                                            "LC_MESSAGES", PACKAGE, ".mo");
 
641
          dstf = grub_util_path_concat_ext (2, dstd, de->d_name, ".mo");
 
642
        }
 
643
      grub_install_compress_file (srcf, dstf, 0);
 
644
      free (srcf);
 
645
      free (dstf);
 
646
    }
 
647
  grub_util_fd_closedir (d);
 
648
  free (dir);
 
649
}
 
650
 
 
651
static struct
 
652
{
 
653
  const char *cpu;
 
654
  const char *platform;
 
655
} platforms[GRUB_INSTALL_PLATFORM_MAX] =
 
656
  {
 
657
    [GRUB_INSTALL_PLATFORM_I386_PC] =          { "i386",    "pc"        },
 
658
    [GRUB_INSTALL_PLATFORM_I386_EFI] =         { "i386",    "efi"       },
 
659
    [GRUB_INSTALL_PLATFORM_I386_QEMU] =        { "i386",    "qemu"      },
 
660
    [GRUB_INSTALL_PLATFORM_I386_COREBOOT] =    { "i386",    "coreboot"  },
 
661
    [GRUB_INSTALL_PLATFORM_I386_MULTIBOOT] =   { "i386",    "multiboot" },
 
662
    [GRUB_INSTALL_PLATFORM_I386_IEEE1275] =    { "i386",    "ieee1275"  },
 
663
    [GRUB_INSTALL_PLATFORM_X86_64_EFI] =       { "x86_64",  "efi"       },
 
664
    [GRUB_INSTALL_PLATFORM_I386_XEN] =         { "i386",    "xen"       },
 
665
    [GRUB_INSTALL_PLATFORM_X86_64_XEN] =       { "x86_64",  "xen"       },
 
666
    [GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] =  { "mipsel",  "loongson"  },
 
667
    [GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel",  "qemu_mips" },
 
668
    [GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] =   { "mips",    "qemu_mips" },
 
669
    [GRUB_INSTALL_PLATFORM_MIPSEL_ARC] =       { "mipsel",  "arc"       },
 
670
    [GRUB_INSTALL_PLATFORM_MIPS_ARC] =         { "mips",    "arc"       },
 
671
    [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64", "ieee1275"  },
 
672
    [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275"  },
 
673
    [GRUB_INSTALL_PLATFORM_IA64_EFI] =         { "ia64",    "efi"       },
 
674
    [GRUB_INSTALL_PLATFORM_ARM_EFI] =          { "arm",     "efi"       },
 
675
    [GRUB_INSTALL_PLATFORM_ARM64_EFI] =        { "arm64",   "efi"       },
 
676
    [GRUB_INSTALL_PLATFORM_ARM_UBOOT] =        { "arm",     "uboot"     },
 
677
  }; 
 
678
 
 
679
char *
 
680
grub_install_get_platform_name (enum grub_install_plat platid)
 
681
{
 
682
  return xasprintf ("%s-%s", platforms[platid].cpu,
 
683
                    platforms[platid].platform);
 
684
}
 
685
 
 
686
const char *
 
687
grub_install_get_platform_cpu (enum grub_install_plat platid)
 
688
{
 
689
  return platforms[platid].cpu;
 
690
}
 
691
 
 
692
const char *
 
693
grub_install_get_platform_platform (enum grub_install_plat platid)
 
694
{
 
695
  return platforms[platid].platform;
 
696
}
 
697
 
 
698
 
 
699
void
 
700
grub_install_copy_files (const char *src,
 
701
                         const char *dst,
 
702
                         enum grub_install_plat platid)
 
703
{
 
704
  char *dst_platform, *dst_locale, *dst_fonts;
 
705
  const char *pkgdatadir = grub_util_get_pkgdatadir ();
 
706
  char *themes_dir;
 
707
 
 
708
  {
 
709
    char *platform;
 
710
    platform = xasprintf ("%s-%s", platforms[platid].cpu,
 
711
                          platforms[platid].platform);
 
712
    dst_platform = grub_util_path_concat (2, dst, platform);
 
713
    free (platform);
 
714
  }
 
715
  dst_locale = grub_util_path_concat (2, dst, "locale");
 
716
  dst_fonts = grub_util_path_concat (2, dst, "fonts");
 
717
  grub_install_mkdir_p (dst_platform);
 
718
  grub_install_mkdir_p (dst_locale);
 
719
  clean_grub_dir (dst);
 
720
  clean_grub_dir (dst_platform);
 
721
  clean_grub_dir (dst_locale);
 
722
 
 
723
  if (install_modules.is_default)
 
724
    copy_by_ext (src, dst_platform, ".mod", 1);
 
725
  else
 
726
    {
 
727
      struct grub_util_path_list *path_list, *p;
 
728
 
 
729
      path_list = grub_util_resolve_dependencies (src, "moddep.lst",
 
730
                                                  install_modules.entries);
 
731
      for (p = path_list; p; p = p->next)
 
732
        {
 
733
          const char *srcf = p->name;
 
734
          const char *dir;
 
735
          char *dstf;
 
736
 
 
737
          dir = grub_strrchr (srcf, '/');
 
738
          if (dir)
 
739
            dir++;
 
740
          else
 
741
            dir = srcf;
 
742
          dstf = grub_util_path_concat (2, dst_platform, dir);
 
743
          grub_install_compress_file (srcf, dstf, 1);
 
744
          free (dstf);
 
745
        }
 
746
    }
 
747
 
 
748
  const char *pkglib_DATA[] = {"efiemu32.o", "efiemu64.o",
 
749
                               "moddep.lst", "command.lst",
 
750
                               "fs.lst", "partmap.lst",
 
751
                               "parttool.lst",
 
752
                               "video.lst", "crypto.lst",
 
753
                               "terminal.lst", "modinfo.sh" };
 
754
  size_t i;
 
755
 
 
756
  for (i = 0; i < ARRAY_SIZE (pkglib_DATA); i++)
 
757
    {
 
758
      char *srcf = grub_util_path_concat (2, src, pkglib_DATA[i]);
 
759
      char *dstf = grub_util_path_concat (2, dst_platform, pkglib_DATA[i]);
 
760
      if (i == 0 || i == 1)
 
761
        grub_install_compress_file (srcf, dstf, 0);
 
762
      else
 
763
        grub_install_compress_file (srcf, dstf, 1);
 
764
      free (srcf);
 
765
      free (dstf);
 
766
    }
 
767
 
 
768
  if (install_locales.is_default)
 
769
    {
 
770
      char *srcd = grub_util_path_concat (2, src, "po");
 
771
      copy_by_ext (srcd, dst_locale, ".mo", 0);
 
772
      copy_locales (dst_locale, 0);
 
773
      copy_locales (dst_locale, 1);
 
774
      free (srcd);
 
775
    }
 
776
  else
 
777
    {
 
778
      const char *locale_dir = get_localedir ();
 
779
      char *locale_langpack_dir = xasprintf ("%s-langpack", locale_dir);
 
780
 
 
781
      for (i = 0; i < install_locales.n_entries; i++)
 
782
        {
 
783
          char *srcf = grub_util_path_concat_ext (3, src,
 
784
                                                "po",
 
785
                                                install_locales.entries[i],
 
786
                                                ".mo");
 
787
          char *dstf = grub_util_path_concat_ext (2, dst_locale,
 
788
                                                install_locales.entries[i],
 
789
                                                ".mo");
 
790
          if (grub_install_compress_file (srcf, dstf, 0))
 
791
            {
 
792
              free (srcf);
 
793
              free (dstf);
 
794
              continue;
 
795
            }
 
796
          free (srcf);
 
797
          srcf = grub_util_path_concat_ext (4,
 
798
                                                 locale_langpack_dir,
 
799
                                                 install_locales.entries[i],
 
800
                                                 "LC_MESSAGES",
 
801
                                                 PACKAGE,
 
802
                                                 ".mo");
 
803
          if (grub_install_compress_file (srcf, dstf, 0))
 
804
            {
 
805
              free (srcf);
 
806
              free (dstf);
 
807
              continue;
 
808
            }
 
809
          free (srcf);
 
810
          srcf = grub_util_path_concat_ext (4,
 
811
                                                 locale_dir,
 
812
                                                 install_locales.entries[i],
 
813
                                                 "LC_MESSAGES",
 
814
                                                 PACKAGE,
 
815
                                                 ".mo");
 
816
          if (grub_install_compress_file (srcf, dstf, 0))
 
817
            {
 
818
              free (srcf);
 
819
              free (dstf);
 
820
              continue;
 
821
            }
 
822
          grub_util_error (_("cannot find locale `%s'"),
 
823
                           install_locales.entries[i]);
 
824
        }
 
825
 
 
826
      free (locale_langpack_dir);
 
827
    }
 
828
 
 
829
  if (install_themes.is_default)
 
830
    {
 
831
      install_themes.is_default = 0;
 
832
      install_themes.n_entries = 1;
 
833
      install_themes.entries = xmalloc (2 * sizeof (install_themes.entries[0]));
 
834
      install_themes.entries[0] = xstrdup ("starfield");
 
835
      install_themes.entries[1] = NULL;
 
836
    }
 
837
 
 
838
  if (grub_install_themes_directory)
 
839
    themes_dir = xstrdup (grub_install_themes_directory);
 
840
  else
 
841
    themes_dir = grub_util_path_concat (2, grub_util_get_pkgdatadir (),
 
842
                                        "themes");
 
843
 
 
844
  for (i = 0; i < install_themes.n_entries; i++)
 
845
    {
 
846
      char *srcf = grub_util_path_concat (3, themes_dir,
 
847
                                        install_themes.entries[i],
 
848
                                        "theme.txt");
 
849
      if (grub_util_is_regular (srcf))
 
850
        {
 
851
          char *srcd = grub_util_path_concat (2, themes_dir,
 
852
                                            install_themes.entries[i]);
 
853
          char *dstd = grub_util_path_concat (3, dst, "themes",
 
854
                                            install_themes.entries[i]);
 
855
          grub_install_mkdir_p (dstd);
 
856
          copy_all (srcd, dstd);
 
857
          free (srcd);
 
858
          free (dstd);
 
859
        }
 
860
      free (srcf);
 
861
    }
 
862
 
 
863
  free (themes_dir);
 
864
 
 
865
  if (install_fonts.is_default)
 
866
    {
 
867
      install_fonts.is_default = 0;
 
868
      install_fonts.n_entries = 1;
 
869
      install_fonts.entries = xmalloc (2 * sizeof (install_fonts.entries[0]));
 
870
      install_fonts.entries[0] = xstrdup ("unicode");
 
871
      install_fonts.entries[1] = NULL;
 
872
    }
 
873
 
 
874
  grub_install_mkdir_p (dst_fonts);
 
875
 
 
876
  for (i = 0; i < install_fonts.n_entries; i++)
 
877
    {
 
878
      char *srcf = grub_util_path_concat_ext (2, pkgdatadir,
 
879
                                                   install_fonts.entries[i],
 
880
                                                   ".pf2");
 
881
      char *dstf = grub_util_path_concat_ext (2, dst_fonts,
 
882
                                                   install_fonts.entries[i],
 
883
                                                   ".pf2");
 
884
 
 
885
      grub_install_compress_file (srcf, dstf, 0);
 
886
      free (srcf);
 
887
      free (dstf);
 
888
    }
 
889
 
 
890
  free (dst_platform);
 
891
  free (dst_locale);
 
892
  free (dst_fonts);
 
893
}
 
894
 
 
895
enum grub_install_plat
 
896
grub_install_get_target (const char *src)
 
897
{
 
898
  char *fn;
 
899
  grub_util_fd_t f;
 
900
  char buf[2048];
 
901
  size_t r;
 
902
  char *c, *pl, *p;
 
903
  size_t i;
 
904
  fn = grub_util_path_concat (2, src, "modinfo.sh");
 
905
  f = grub_util_fd_open (fn, GRUB_UTIL_FD_O_RDONLY);
 
906
  if (!GRUB_UTIL_FD_IS_VALID (f))
 
907
    grub_util_error (_("%s doesn't exist. Please specify --target or --directory"), 
 
908
                     fn);
 
909
  r = grub_util_fd_read (f, buf, sizeof (buf) - 1);
 
910
  grub_util_fd_close (f);
 
911
  buf[r] = '\0';
 
912
  c = strstr (buf, "grub_modinfo_target_cpu=");
 
913
  if (!c || (c != buf && !grub_isspace (*(c-1))))
 
914
    grub_util_error (_("invalid modinfo file `%s'"), fn);
 
915
  pl = strstr (buf, "grub_modinfo_platform=");
 
916
  if (!pl || (pl != buf && !grub_isspace (*(pl-1))))
 
917
    grub_util_error (_("invalid modinfo file `%s'"), fn);
 
918
  c += sizeof ("grub_modinfo_target_cpu=") - 1;
 
919
  pl += sizeof ("grub_modinfo_platform=") - 1;
 
920
  for (p = c; *p && !grub_isspace (*p); p++);
 
921
  *p = '\0';
 
922
  for (p = pl; *p && !grub_isspace (*p); p++);
 
923
  *p = '\0';
 
924
 
 
925
  for (i = 0; i < ARRAY_SIZE (platforms); i++)
 
926
    if (strcmp (platforms[i].cpu, c) == 0
 
927
        && strcmp (platforms[i].platform, pl) == 0)
 
928
      {
 
929
        free (fn);
 
930
        return i;
 
931
      }
 
932
  grub_util_error (_("Unknown platform `%s-%s'"), c, pl);
 
933
}
 
934
 
 
935
 
 
936
void
 
937
grub_util_unlink_recursive (const char *name)
 
938
{
 
939
  grub_util_fd_dir_t d;
 
940
  grub_util_fd_dirent_t de;
 
941
 
 
942
  d = grub_util_fd_opendir (name);
 
943
 
 
944
  while ((de = grub_util_fd_readdir (d)))
 
945
    {
 
946
      char *fp;
 
947
      if (strcmp (de->d_name, ".") == 0)
 
948
        continue;
 
949
      if (strcmp (de->d_name, "..") == 0)
 
950
        continue;
 
951
      fp = grub_util_path_concat (2, name, de->d_name);
 
952
      if (grub_util_is_special_file (fp))
 
953
        {
 
954
          free (fp);
 
955
          continue;
 
956
        }
 
957
      if (grub_util_is_regular (fp))
 
958
        grub_util_unlink (fp);
 
959
      else if (grub_util_is_directory (fp))
 
960
        grub_util_unlink_recursive (fp);
 
961
      free (fp);
 
962
    }
 
963
  grub_util_rmdir (name);
 
964
  grub_util_fd_closedir (d);
 
965
}