~ubuntu-branches/ubuntu/hoary/cdrtools/hoary

« back to all changes in this revision

Viewing changes to mkisofs/silo.c

  • Committer: Bazaar Package Importer
  • Author(s): Eduard Bloch
  • Date: 2002-04-09 10:03:06 UTC
  • Revision ID: james.westby@ubuntu.com-20020409100306-0mibp3jcbifarjue
Tags: 4:1.10-7
* The seventh-time-lucky release. This should go into Woody.
* Simplified the old crap^h^h^h^hdebconf interaction part, moved makedev
  calls to cdrecord.postinst, since makedev != essential. Closes: #141905

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Program silo.c - Handle SILO bootable iso9660 CD-ROMs.
 
3
 *
 
4
 
 
5
   Copyright (C) 1999 Jakub Jelinek <jakub@redhat.com>.
 
6
 
 
7
   This program is free software; you can redistribute it and/or modify
 
8
   it under the terms of the GNU General Public License as published by
 
9
   the Free Software Foundation; either version 2, or (at your option)
 
10
   any later version.
 
11
 
 
12
   This program is distributed in the hope that it will be useful,
 
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
   GNU General Public License for more details.
 
16
 
 
17
   You should have received a copy of the GNU General Public License
 
18
   along with this program; if not, write to the Free Software
 
19
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */
 
20
 
 
21
 
 
22
static char rcsid[] ="$Id:$";
 
23
 
 
24
#include <mconfig.h>
 
25
#include <stdio.h>
 
26
#include <sys/types.h>
 
27
#include <sys/stat.h>
 
28
#include <unistd.h>
 
29
#include <fcntl.h>
 
30
#include <stdlib.h>
 
31
 
 
32
#include "mkisofs.h"
 
33
#include "iso9660.h"
 
34
#include <schily.h>
 
35
 
 
36
/* used by Win32 for opening binary file - not used by Unix */
 
37
#ifndef O_BINARY
 
38
#define O_BINARY 0
 
39
#endif /* O_BINARY */
 
40
 
 
41
struct sun_disklabel {
 
42
    char       info[128];      /* Informative text string */
 
43
    char       spare0[14];
 
44
    struct sun_info {
 
45
       char    spare1;
 
46
       char    id;
 
47
       char    spare2;
 
48
       char    flags;
 
49
    } infos[8];
 
50
    char       spare1[246];    /* Boot information etc. */
 
51
    char       rspeed[2];      /* 722 - Disk rotational speed */
 
52
    char       pcylcount[2];   /* 722 - Physical cylinder count */
 
53
    char       sparecyl[2];    /* 722 - extra sects per cylinder */
 
54
    char       spare2[4];      /* More magic... */
 
55
    char       ilfact[2];      /* 722 - Interleave factor */
 
56
    char       ncyl[2];        /* 722 - Data cylinder count */
 
57
    char       nacyl[2];       /* 722 - Alt. cylinder count */
 
58
    char       ntrks[2];       /* 722 - Tracks per cylinder */
 
59
    char       nsect[2];       /* 722 - Sectors per track */
 
60
    char       spare3[4];      /* Even more magic... */
 
61
    struct sun_partition {
 
62
        char start_cylinder[4];        /* 732 */
 
63
       char num_sectors[4];    /* 732 */
 
64
    } partitions[8];
 
65
    char       magic[2];       /* 722 - Magic number */
 
66
    char       csum[2];        /* 722 - Label xor'd checksum */
 
67
    struct bootblock_header {
 
68
       char    magic[4];       /* 732 */
 
69
       char    aout[20];
 
70
       char    siloid[8];
 
71
       char    insn[16];
 
72
       char    extent[4];      /* 732 */
 
73
       char    size[4];        /* 732 */
 
74
       char    text[2048-512-56];
 
75
    } bootblock;
 
76
};
 
77
 
 
78
static struct {
 
79
    char id;
 
80
    char conf_part;
 
81
    char part;
 
82
    char pad;
 
83
    char conf_file[256];
 
84
} silo_info;
 
85
 
 
86
static int silo_size(int starting_extent)
 
87
{
 
88
    last_extent += 16;
 
89
    return 0;
 
90
}
 
91
 
 
92
static int silo_filter(char * buffer, int size, int offset)
 
93
{
 
94
    if (offset < 0x808 + sizeof(silo_info)
 
95
       && offset + size > 0x808)
 
96
    {
 
97
       int i;
 
98
       if (offset < 0x808)
 
99
       {
 
100
           offset = 0x808 - offset;
 
101
           size -= offset;
 
102
           buffer += offset;
 
103
           offset = 0;
 
104
       }
 
105
       else
 
106
           offset -= 0x808;
 
107
       i = sizeof(silo_info) - offset;
 
108
       if (i > size) i = size;
 
109
       memcpy (buffer, ((char *)&silo_info) + offset, i);
 
110
    }
 
111
    return 0;
 
112
}
 
113
 
 
114
static int silo_write(FILE * outfile)
 
115
{
 
116
    struct directory_entry      * de;
 
117
    struct directory_entry      * de2;
 
118
    struct deferred_write      * dwpnt;
 
119
    int bootblock, i, should_write;
 
120
    struct sun_disklabel       silo_bb;
 
121
   
 
122
    memset (&silo_bb, 0, sizeof (silo_bb));
 
123
   
 
124
    if (*silo_bootblock == '/') silo_bootblock++;
 
125
    if (*silo_boot_image == '/') silo_boot_image++;
 
126
 
 
127
    /*
 
128
     * search from root of iso fs to find boot catalog
 
129
     */
 
130
    de2 = search_tree_file(root, silo_bootblock);
 
131
    if (!de2)
 
132
    {
 
133
       fprintf(stderr,"Uh oh, I cant find the SILO bootblock!\n");
 
134
       exit(1);
 
135
    }
 
136
 
 
137
    /*
 
138
     * now read it from disk
 
139
     */
 
140
    bootblock = open(de2->whole_name, O_RDWR | O_BINARY);
 
141
    if (bootblock == -1)
 
142
    {
 
143
       fprintf(stderr,"Error opening SILO bootblock for reading.\n");
 
144
       perror("");
 
145
       exit(1);
 
146
    }
 
147
   
 
148
    if (read (bootblock, (char *)&silo_bb.bootblock, 1024) != 1024)
 
149
    {
 
150
       fprintf(stderr,"Error reading SILO bootblock.\n");
 
151
       perror("");
 
152
       exit(1);
 
153
    }
 
154
 
 
155
    close (bootblock);
 
156
 
 
157
    if (get_732 (silo_bb.bootblock.magic) != 0x01030107
 
158
       || strncmp (silo_bb.bootblock.siloid, "SILO", 4)
 
159
       || silo_bb.bootblock.siloid[5] != '.'
 
160
       || silo_bb.bootblock.siloid[4] < '0'
 
161
       || silo_bb.bootblock.siloid[4] > '9'
 
162
       || silo_bb.bootblock.siloid[6] < '0'
 
163
       || silo_bb.bootblock.siloid[6] > '9'
 
164
       || silo_bb.bootblock.siloid[7] < '0'
 
165
       || silo_bb.bootblock.siloid[7] > '9')
 
166
    {
 
167
       fprintf(stderr,"Error: the file %s is not a valid SILO bootblock.\n", silo_bootblock);
 
168
       perror("");
 
169
       exit(1);
 
170
    }
 
171
   
 
172
    /* Check version number. Only SILO 0.87 and up is valid. */
 
173
    if (silo_bb.bootblock.siloid[4] == '0'
 
174
       && (silo_bb.bootblock.siloid[6] < '8'
 
175
           || (silo_bb.bootblock.siloid[6] == '8'
 
176
               && silo_bb.bootblock.siloid[7] <= '6')))
 
177
    {
 
178
       fprintf(stderr,"Error: SILO bootblock is too old. Must be at least 0.8.7.\n");
 
179
       perror("");
 
180
       exit(1);
 
181
    }
 
182
 
 
183
    /*
 
184
     * search from root of iso fs to find boot catalog
 
185
     */
 
186
    de = search_tree_file(root, silo_boot_image);
 
187
    if (!de)
 
188
    {
 
189
       fprintf(stderr,"Uh oh, I cant find the SILO boot image!\n");
 
190
       exit(1);
 
191
    }
 
192
 
 
193
    /*
 
194
     * need to filter second.b, so that we can seed
 
195
     * silo.conf location and other stuff.
 
196
     * We could write it into the de->whole_name file,
 
197
     * but I prefer filtering it like this because
 
198
     * then the tree can be e.g. read only NFS mounted.
 
199
     */
 
200
    for (dwpnt = dw_head; dwpnt; dwpnt = dwpnt->next)
 
201
    {
 
202
       if (!dwpnt->name) continue;
 
203
       if (!strcmp (dwpnt->name, de->whole_name))
 
204
           dwpnt->filter = silo_filter;
 
205
    }
 
206
 
 
207
    set_732 (silo_bb.bootblock.extent, de->starting_block);
 
208
    set_732 (silo_bb.bootblock.size, de->size);
 
209
 
 
210
    strcpy (silo_bb.info, "SPARC bootable CD-ROM: ");
 
211
    strcat (silo_bb.info, volume_id);
 
212
 
 
213
    should_write = (last_extent - session_start) << 2;
 
214
 
 
215
    /* Now some magic */
 
216
    silo_bb.spare0[3] = 1;
 
217
    silo_bb.spare0[13] = 8;
 
218
    for (i = 0; i < 8; i++) {
 
219
       silo_bb.infos[i].id = 0x83;
 
220
       silo_bb.infos[i].flags = 0x18;
 
221
    }
 
222
    set_732 (silo_bb.spare1 + 14, 0x600ddeee);
 
223
    set_722 (silo_bb.rspeed, 0x15e);
 
224
    set_722 (silo_bb.pcylcount, (should_write + 639) / 640);
 
225
    set_722 (silo_bb.ilfact, 1);
 
226
    set_722 (silo_bb.ncyl, (should_write + 639) / 640);
 
227
    set_722 (silo_bb.ntrks, 1);
 
228
    set_722 (silo_bb.nsect, 640);
 
229
    set_732 (silo_bb.partitions[0].num_sectors, should_write);
 
230
    set_722 (silo_bb.magic, 0xdabe);
 
231
    for (i = 0; i < 510; i+=2) {
 
232
       silo_bb.csum[0] ^= silo_bb.info[i];
 
233
       silo_bb.csum[1] ^= silo_bb.info[i+1];
 
234
    }
 
235
 
 
236
    xfwrite(&silo_bb, 1, sizeof(silo_bb), outfile);
 
237
    memset (&silo_bb, 0, sizeof(silo_bb));
 
238
 
 
239
    for(i=1; i<16; i++)
 
240
    {
 
241
       xfwrite(&silo_bb, 1, sizeof(silo_bb), outfile);
 
242
    }
 
243
 
 
244
    memset (&silo_info, 0, sizeof(silo_info));
 
245
    silo_info.id = 'L';
 
246
    silo_info.conf_part = 1;
 
247
    strncpy (silo_info.conf_file, silo_conf_file, 256);
 
248
    silo_info.conf_file[259] = '\0';
 
249
 
 
250
    last_extent_written += 16;
 
251
   
 
252
    return 0;
 
253
}
 
254
 
 
255
struct output_fragment silo_desc  = {NULL, silo_size, NULL,     silo_write};