2
* Program silo.c - Handle SILO bootable iso9660 CD-ROMs.
5
Copyright (C) 1999 Jakub Jelinek <jakub@redhat.com>.
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)
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.
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. */
22
static char rcsid[] ="$Id:$";
26
#include <sys/types.h>
36
/* used by Win32 for opening binary file - not used by Unix */
41
struct sun_disklabel {
42
char info[128]; /* Informative text string */
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 */
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 */
72
char extent[4]; /* 732 */
73
char size[4]; /* 732 */
74
char text[2048-512-56];
86
static int silo_size(int starting_extent)
92
static int silo_filter(char * buffer, int size, int offset)
94
if (offset < 0x808 + sizeof(silo_info)
95
&& offset + size > 0x808)
100
offset = 0x808 - offset;
107
i = sizeof(silo_info) - offset;
108
if (i > size) i = size;
109
memcpy (buffer, ((char *)&silo_info) + offset, i);
114
static int silo_write(FILE * outfile)
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;
122
memset (&silo_bb, 0, sizeof (silo_bb));
124
if (*silo_bootblock == '/') silo_bootblock++;
125
if (*silo_boot_image == '/') silo_boot_image++;
128
* search from root of iso fs to find boot catalog
130
de2 = search_tree_file(root, silo_bootblock);
133
fprintf(stderr,"Uh oh, I cant find the SILO bootblock!\n");
138
* now read it from disk
140
bootblock = open(de2->whole_name, O_RDWR | O_BINARY);
143
fprintf(stderr,"Error opening SILO bootblock for reading.\n");
148
if (read (bootblock, (char *)&silo_bb.bootblock, 1024) != 1024)
150
fprintf(stderr,"Error reading SILO bootblock.\n");
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')
167
fprintf(stderr,"Error: the file %s is not a valid SILO bootblock.\n", silo_bootblock);
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')))
178
fprintf(stderr,"Error: SILO bootblock is too old. Must be at least 0.8.7.\n");
184
* search from root of iso fs to find boot catalog
186
de = search_tree_file(root, silo_boot_image);
189
fprintf(stderr,"Uh oh, I cant find the SILO boot image!\n");
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.
200
for (dwpnt = dw_head; dwpnt; dwpnt = dwpnt->next)
202
if (!dwpnt->name) continue;
203
if (!strcmp (dwpnt->name, de->whole_name))
204
dwpnt->filter = silo_filter;
207
set_732 (silo_bb.bootblock.extent, de->starting_block);
208
set_732 (silo_bb.bootblock.size, de->size);
210
strcpy (silo_bb.info, "SPARC bootable CD-ROM: ");
211
strcat (silo_bb.info, volume_id);
213
should_write = (last_extent - session_start) << 2;
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;
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];
236
xfwrite(&silo_bb, 1, sizeof(silo_bb), outfile);
237
memset (&silo_bb, 0, sizeof(silo_bb));
241
xfwrite(&silo_bb, 1, sizeof(silo_bb), outfile);
244
memset (&silo_info, 0, sizeof(silo_info));
246
silo_info.conf_part = 1;
247
strncpy (silo_info.conf_file, silo_conf_file, 256);
248
silo_info.conf_file[259] = '\0';
250
last_extent_written += 16;
255
struct output_fragment silo_desc = {NULL, silo_size, NULL, silo_write};