~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to util/mkisofs/eltorito.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Robert Millan, Updated translations
  • Date: 2010-11-22 12:24:56 UTC
  • mfrom: (1.26.4 upstream) (17.3.36 sid)
  • mto: (17.3.43 sid)
  • mto: This revision was merged to the branch mainline in revision 89.
  • Revision ID: james.westby@ubuntu.com-20101122122456-y82z3sfb7k4zfdcc
Tags: 1.99~20101122-1
[ Colin Watson ]
* New Bazaar snapshot.  Too many changes to list in full, but some of the
  more user-visible ones are as follows:
  - GRUB script:
    + Function parameters, "break", "continue", "shift", "setparams",
      "return", and "!".
    + "export" command supports multiple variable names.
    + Multi-line quoted strings support.
    + Wildcard expansion.
  - sendkey support.
  - USB hotunplugging and USB serial support.
  - Rename CD-ROM to cd on BIOS.
  - Add new --boot-directory option to grub-install, grub-reboot, and
    grub-set-default; the old --root-directory option is still accepted
    but was often confusing.
  - Basic btrfs detection/UUID support (but no file reading yet).
  - bash-completion for utilities.
  - If a device is listed in device.map, always assume that it is
    BIOS-visible rather than using extra layers such as LVM or RAID.
  - Add grub-mknetdir script (closes: #550658).
  - Remove deprecated "root" command.
  - Handle RAID devices containing virtio components.
  - GRUB Legacy configuration file support (via grub-menulst2cfg).
  - Keyboard layout support (via grub-mklayout and grub-kbdcomp).
  - Check generated grub.cfg for syntax errors before saving.
  - Pause execution for at most ten seconds if any errors are displayed,
    so that the user has a chance to see them.
  - Support submenus.
  - Write embedding zone using Reed-Solomon, so that it's robust against
    being partially overwritten (closes: #550702, #591416, #593347).
  - GRUB_DISABLE_LINUX_RECOVERY and GRUB_DISABLE_NETBSD_RECOVERY merged
    into a single GRUB_DISABLE_RECOVERY variable.
  - Fix loader memory allocation failure (closes: #551627).
  - Don't call savedefault on recovery entries (closes: #589325).
  - Support triple-indirect blocks on ext2 (closes: #543924).
  - Recognise DDF1 fake RAID (closes: #603354).

[ Robert Millan ]
* Use dpkg architecture wildcards.

[ Updated translations ]
* Slovenian (Vanja Cvelbar).  Closes: #604003
* Dzongkha (dawa pemo via Tenzin Dendup).  Closes: #604102

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Program eltorito.c - Handle El Torito specific extensions to iso9660.
3
 
 *
4
 
 
5
 
   Written by Michael Fulbright <msf@redhat.com> (1996).
6
 
 
7
 
   Copyright 1996 RedHat Software, Incorporated
8
 
 
9
 
   Copyright (C) 2009  Free Software Foundation, Inc.
10
 
 
11
 
   Boot Info Table generation based on code from genisoimage.c
12
 
   (from cdrkit 1.1.9), which was originally licensed under GPLv2+.
13
 
 
14
 
   This program is free software; you can redistribute it and/or modify
15
 
   it under the terms of the GNU General Public License as published by
16
 
   the Free Software Foundation; either version 3, or (at your option)
17
 
   any later version.
18
 
 
19
 
   This program is distributed in the hope that it will be useful,
20
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 
   GNU General Public License for more details.
23
 
 
24
 
   You should have received a copy of the GNU General Public License
25
 
   along with this program; if not, see <http://www.gnu.org/licenses/>.
26
 
 */
27
 
 
28
 
 
29
 
#include <stdio.h>
30
 
#include <sys/types.h>
31
 
#include <sys/stat.h>
32
 
#include <unistd.h>
33
 
#include <fcntl.h>
34
 
#include <stdlib.h>
35
 
#include <errno.h>
36
 
 
37
 
#include "config.h"
38
 
#include "mkisofs.h"
39
 
#include "iso9660.h"
40
 
 
41
 
/* used by Win32 for opening binary file - not used by Unix */
42
 
#ifndef O_BINARY
43
 
#define O_BINARY 0
44
 
#endif /* O_BINARY */
45
 
 
46
 
#undef MIN
47
 
#define MIN(a, b) (((a) < (b))? (a): (b))
48
 
 
49
 
static struct eltorito_validation_entry valid_desc;
50
 
static struct eltorito_defaultboot_entry default_desc;
51
 
static struct eltorito_boot_descriptor gboot_desc;
52
 
 
53
 
static int tvd_write    __PR((FILE * outfile));
54
 
 
55
 
/*
56
 
 * Check for presence of boot catalog. If it does not exist then make it
57
 
 */
58
 
void FDECL1(init_boot_catalog, const char *, path)
59
 
{
60
 
    FILE *bcat;
61
 
    char                * bootpath;                /* filename of boot catalog */
62
 
    char                * buf;
63
 
    struct stat   statbuf;
64
 
   
65
 
    bootpath = (char *) e_malloc(strlen(boot_catalog)+strlen(path)+2);
66
 
    strcpy(bootpath, path);
67
 
    if (bootpath[strlen(bootpath)-1] != '/')
68
 
    {
69
 
        strcat(bootpath,"/");
70
 
    }
71
 
   
72
 
    strcat(bootpath, boot_catalog);
73
 
   
74
 
    /*
75
 
     * check for the file existing
76
 
     */
77
 
#ifdef DEBUG_TORITO
78
 
    fprintf(stderr,"Looking for boot catalog file %s\n",bootpath);
79
 
#endif
80
 
   
81
 
    if (!stat_filter(bootpath, &statbuf))
82
 
    {
83
 
        /*
84
 
         * make sure its big enough to hold what we want
85
 
         */
86
 
        if (statbuf.st_size == 2048)
87
 
        {
88
 
            /*
89
 
             * printf("Boot catalog exists, so we do nothing\n");
90
 
             */
91
 
            free(bootpath);
92
 
            return;
93
 
        }
94
 
        else
95
 
        {
96
 
          fprintf (stderr, _("A boot catalog exists and appears corrupted.\n"));
97
 
          fprintf (stderr, _("Please check the following file: %s.\n"), bootpath);
98
 
          fprintf (stderr, _("This file must be removed before a bootable CD can be done.\n"));
99
 
          free (bootpath);
100
 
          exit (1);
101
 
        }
102
 
    }
103
 
   
104
 
    /*
105
 
     * file does not exist, so we create it
106
 
     * make it one CD sector long
107
 
     */
108
 
    bcat = fopen (bootpath, "wb");
109
 
    if (bcat == NULL)
110
 
      error (1, errno, _("Error creating boot catalog (%s)"), bootpath);
111
 
   
112
 
    buf = (char *) e_malloc( 2048 );
113
 
    if (fwrite (buf, 1, 2048, bcat) != 2048)
114
 
      error (1, errno, _("Error writing to boot catalog (%s)"), bootpath);
115
 
    fclose (bcat);
116
 
    chmod (bootpath, S_IROTH | S_IRGRP | S_IRWXU);
117
 
 
118
 
    free(bootpath);
119
 
} /* init_boot_catalog(... */
120
 
 
121
 
void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc)
122
 
{
123
 
    FILE *bootcat;
124
 
    int                         checksum;
125
 
    unsigned char                     * checksum_ptr;
126
 
    struct directory_entry      * de;
127
 
    struct directory_entry      * de2;
128
 
    unsigned int                i;
129
 
    int                         nsectors;
130
 
   
131
 
    memset(boot_desc, 0, sizeof(*boot_desc));
132
 
    boot_desc->id[0] = 0;
133
 
    memcpy(boot_desc->id2, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID));
134
 
    boot_desc->version[0] = 1;
135
 
   
136
 
    memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof(EL_TORITO_ID));
137
 
   
138
 
    /*
139
 
     * search from root of iso fs to find boot catalog
140
 
     */
141
 
    de2 = search_tree_file(root, boot_catalog);
142
 
    if (!de2)
143
 
    {
144
 
      fprintf (stderr, _("Boot catalog cannot be found!\n"));
145
 
      exit (1);
146
 
    }
147
 
   
148
 
    set_731(boot_desc->bootcat_ptr,
149
 
            (unsigned int) get_733(de2->isorec.extent));
150
 
   
151
 
    /*
152
 
     * now adjust boot catalog
153
 
     * lets find boot image first
154
 
     */
155
 
    de=search_tree_file(root, boot_image);
156
 
    if (!de)
157
 
    {
158
 
      fprintf (stderr, _("Boot image cannot be found!\n"));
159
 
      exit (1);
160
 
    }
161
 
   
162
 
    /*
163
 
     * we have the boot image, so write boot catalog information
164
 
     * Next we write out the primary descriptor for the disc
165
 
     */
166
 
    memset(&valid_desc, 0, sizeof(valid_desc));
167
 
    valid_desc.headerid[0] = 1;
168
 
    valid_desc.arch[0] = EL_TORITO_ARCH_x86;
169
 
   
170
 
    /*
171
 
     * we'll shove start of publisher id into id field, may get truncated
172
 
     * but who really reads this stuff!
173
 
     */
174
 
    if (publisher)
175
 
        memcpy_max(valid_desc.id,  publisher, MIN(23, strlen(publisher)));
176
 
   
177
 
    valid_desc.key1[0] = 0x55;
178
 
    valid_desc.key2[0] = 0xAA;
179
 
   
180
 
    /*
181
 
     * compute the checksum
182
 
     */
183
 
    checksum=0;
184
 
    checksum_ptr = (unsigned char *) &valid_desc;
185
 
    for (i=0; i<sizeof(valid_desc); i+=2)
186
 
    {
187
 
        /*
188
 
         * skip adding in ckecksum word, since we dont have it yet!
189
 
         */
190
 
        if (i == 28)
191
 
        {
192
 
            continue;
193
 
        }
194
 
        checksum += (unsigned int)checksum_ptr[i];
195
 
        checksum += ((unsigned int)checksum_ptr[i+1])*256;
196
 
    }
197
 
   
198
 
    /*
199
 
     * now find out the real checksum
200
 
     */
201
 
    checksum = -checksum;
202
 
    set_721(valid_desc.cksum, (unsigned int) checksum);
203
 
   
204
 
    /*
205
 
     * now make the initial/default entry for boot catalog
206
 
     */
207
 
    memset(&default_desc, 0, sizeof(default_desc));
208
 
    default_desc.boot_id[0] = EL_TORITO_BOOTABLE;
209
 
   
210
 
    /*
211
 
     * use default BIOS loadpnt
212
 
     */
213
 
    set_721(default_desc.loadseg, 0);
214
 
    default_desc.arch[0] = EL_TORITO_ARCH_x86;
215
 
   
216
 
    /*
217
 
     * figure out size of boot image in sectors, for now hard code to
218
 
     * assume 512 bytes/sector on a bootable floppy
219
 
     */
220
 
    nsectors = ((de->size + 511) & ~(511))/512;
221
 
    fprintf (stderr, _("\nSize of boot image is %d sectors"), nsectors);
222
 
    fprintf (stderr, " -> ");
223
 
 
224
 
    if (! use_eltorito_emul_floppy)
225
 
      {
226
 
        default_desc.boot_media[0] = EL_TORITO_MEDIA_NOEMUL;
227
 
        fprintf (stderr, _("No emulation\n"));
228
 
      }
229
 
    else if (nsectors == 2880 )
230
 
      /*
231
 
       * choose size of emulated floppy based on boot image size
232
 
       */
233
 
      {
234
 
        default_desc.boot_media[0] = EL_TORITO_MEDIA_144FLOP;
235
 
        fprintf (stderr, _("Emulating a 1.44 meg floppy\n"));
236
 
      }
237
 
    else if (nsectors == 5760 )
238
 
      {
239
 
        default_desc.boot_media[0] = EL_TORITO_MEDIA_288FLOP;
240
 
        fprintf (stderr, _("Emulating a 2.88 meg floppy\n"));
241
 
      }
242
 
    else if (nsectors == 2400 )
243
 
      {
244
 
        default_desc.boot_media[0] = EL_TORITO_MEDIA_12FLOP;
245
 
        fprintf (stderr, _("Emulating a 1.2 meg floppy\n"));
246
 
      }
247
 
    else
248
 
      {
249
 
        fprintf (stderr, _("\nError - boot image is not the an allowable size.\n"));
250
 
        exit (1);
251
 
      }
252
 
   
253
 
    /*
254
 
     * FOR NOW LOAD 1 SECTOR, JUST LIKE FLOPPY BOOT!!!
255
 
     */
256
 
    nsectors = 1;
257
 
    set_721(default_desc.nsect, (unsigned int) nsectors );
258
 
#ifdef DEBUG_TORITO
259
 
    fprintf(stderr,"Extent of boot images is %d\n",get_733(de->isorec.extent));
260
 
#endif
261
 
    set_731(default_desc.bootoff,
262
 
            (unsigned int) get_733(de->isorec.extent));
263
 
   
264
 
    /*
265
 
     * now write it to disk
266
 
     */
267
 
    bootcat = fopen (de2->whole_name, "r+b");
268
 
    if (bootcat == NULL)
269
 
      error (1, errno, _("Error opening boot catalog for update"));
270
 
 
271
 
    /*
272
 
     * write out
273
 
     */
274
 
    if (fwrite (&valid_desc, 1, 32, bootcat) != 32)
275
 
      error (1, errno, _("Error writing to boot catalog"));
276
 
    if (fwrite (&default_desc, 1, 32, bootcat) != 32)
277
 
      error (1, errno, _("Error writing to boot catalog"));
278
 
    fclose (bootcat);
279
 
 
280
 
    /* If the user has asked for it, patch the boot image */
281
 
    if (use_boot_info_table)
282
 
      {
283
 
        FILE *bootimage;
284
 
        uint32_t bi_checksum;
285
 
        unsigned int total_len;
286
 
        static char csum_buffer[SECTOR_SIZE];
287
 
        int len;
288
 
        struct eltorito_boot_info bi_table;
289
 
        bootimage = fopen (de->whole_name, "r+b");
290
 
        if (bootimage == NULL)
291
 
          error (1, errno, _("Error opening boot image file `%s' for update"),
292
 
                 de->whole_name);
293
 
        /* Compute checksum of boot image, sans 64 bytes */
294
 
        total_len = 0;
295
 
        bi_checksum = 0;
296
 
        while ((len = fread (csum_buffer, 1, SECTOR_SIZE, bootimage)) > 0)
297
 
          {
298
 
            if (total_len & 3)
299
 
              error (1, 0, _("Odd alignment at non-end-of-file in boot image `%s'"),
300
 
                     de->whole_name);
301
 
            if (total_len < 64)
302
 
              memset (csum_buffer, 0, 64 - total_len);
303
 
            if (len < SECTOR_SIZE)
304
 
              memset (csum_buffer + len, 0, SECTOR_SIZE - len);
305
 
            for (i = 0; i < SECTOR_SIZE; i += 4)
306
 
              bi_checksum += get_731 (&csum_buffer[i]);
307
 
            total_len += len;
308
 
          }
309
 
 
310
 
        if (total_len != de->size)
311
 
          error (1, 0, _("Boot image file `%s' changed unexpectedly"),
312
 
                 de->whole_name);
313
 
        /* End of file, set position to byte 8 */
314
 
        fseeko (bootimage, (off_t) 8, SEEK_SET);
315
 
        memset (&bi_table, 0, sizeof (bi_table));
316
 
        /* Is it always safe to assume PVD is at session_start+16? */
317
 
        set_731 (bi_table.pvd_addr, session_start + 16);
318
 
        set_731 (bi_table.file_addr, de->starting_block);
319
 
        set_731 (bi_table.file_length, de->size);
320
 
        set_731 (bi_table.file_checksum, bi_checksum);
321
 
 
322
 
        if (fwrite (&bi_table, 1, sizeof (bi_table), bootimage) != sizeof (bi_table))
323
 
          error (1, errno, _("Error writing to boot image (%s)"), bootimage);
324
 
        fclose (bootimage);
325
 
      }
326
 
 
327
 
} /* get_torito_desc(... */
328
 
 
329
 
/*
330
 
 * Function to write the EVD for the disc.
331
 
 */
332
 
static int FDECL1(tvd_write, FILE *, outfile)
333
 
{
334
 
  /*
335
 
   * Next we write out the boot volume descriptor for the disc
336
 
   */
337
 
  get_torito_desc(&gboot_desc);
338
 
  xfwrite(&gboot_desc, 1, 2048, outfile);
339
 
  last_extent_written ++;
340
 
  return 0;
341
 
}
342
 
 
343
 
struct output_fragment torito_desc    = {NULL, oneblock_size, NULL,     tvd_write};