a956008bb71bed3ff650b27af9c116aa9be3cb7c
[jigit.git] / mkisofs-JTE-v1.4.gz
1 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/Makefile cdrtools-2.0+a30.pre1/mkisofs.steve/Makefile
2 --- cdrtools-2.0+a30.pre1/mkisofs/Makefile      2004-06-16 17:48:45.000000000 +0100
3 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/Makefile        2004-06-16 19:24:36.000000000 +0100
4 @@ -34,9 +34,10 @@
5  CPPOPTS +=     -DSORTING
6  CPPOPTS +=     -DUSE_ICONV
7  CPPOPTS +=     -I../libhfs_iso/
8 -CPPOPTS        +=      -DHAVE_CONFIG_H -DUSE_LIBSCHILY -DUSE_SCG \
9 +CPPOPTS        +=      -DHAVE_CONFIG_H -DUSE_LIBSCHILY -DUSE_SCG -DJIGDO_TEMPLATE \
10                 '-DAPPID_DEFAULT="MKISOFS ISO 9660/HFS FILESYSTEM BUILDER & CDRECORD CD-R/DVD CREATOR (C) 1993 E.YOUNGDALE (C) 1997 J.PEARSON/J.SCHILLING"' \
11                 -I../cdrecord
12 +CFLAGS  +=  -Wall -Werror -Wno-unused -g -O2 -fno-strict-aliasing
13  CFILES=                mkisofs.c tree.c write.c hash.c rock.c udf.c multi.c \
14                 joliet.c match.c name.c fnmatch.c eltorito.c boot.c \
15                 getopt.c getopt1.c \
16 @@ -45,14 +46,16 @@
17                 modes.c \
18                 apple.c volume.c desktop.c mac_label.c stream.c \
19                 ifo_read.c dvd_file.c dvd_reader.c \
20 -               defaults.c getnum.c
21 +               defaults.c getnum.c md5.c jte.c \
22 +               boot-alpha.c boot-hppa.c boot-mips.c \
23 +               boot-mipsel.c endian.c
24  HFILES=                apple.h bootinfo.h config.h defaults.h diskmbr.h exclude.h \
25                 fnmatch.h getopt.h iso9660.h mac_label.h mactypes.h match.h \
26                 mkisofs.h sunlabel.h udf.h udf_fs.h vms.h \
27                 ifo_read.h dvd_file.h dvd_reader.h bswap.h ifo_types.h \
28 -               ../cdrecord/defaults.h
29 +               ../cdrecord/defaults.h md5.h jte.h endian.h
30  
31 -LIBS=          -lhfs -lfile -lunls -lrscg -lscg $(LIB_VOLMGT) -ldeflt -lschily $(SCSILIB) $(LIB_SOCKET)
32 +LIBS=          -lz -lhfs -lfile -lunls -lrscg -lscg $(LIB_VOLMGT) -ldeflt -lschily $(SCSILIB) $(LIB_SOCKET)
33  XMK_FILE=      Makefile.man hybridman.mk
34  
35  ###########################################################################
36 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/boot-alpha.c cdrtools-2.0+a30.pre1/mkisofs.steve/boot-alpha.c
37 --- cdrtools-2.0+a30.pre1/mkisofs/boot-alpha.c  1970-01-01 01:00:00.000000000 +0100
38 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/boot-alpha.c    2004-06-16 19:24:36.000000000 +0100
39 @@ -0,0 +1,114 @@
40 +/*
41 + * Program boot-alpha.c - Handle Linux alpha boot extensions to iso9660.
42 + *
43 + * Written by Steve McIntyre <steve@einval.com> June 2004
44 + *
45 + * Heavily inspired by isomarkboot by David Mosberger in 1996.
46 + *
47 + * Copyright 2004 Steve McIntyre
48 + *
49 + * This program is free software; you can redistribute it and/or modify
50 + * it under the terms of the GNU General Public License as published by
51 + * the Free Software Foundation; either version 2, or (at your option)
52 + * any later version.
53 + *
54 + * This program is distributed in the hope that it will be useful,
55 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
56 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
57 + * GNU General Public License for more details.
58 + *
59 + * You should have received a copy of the GNU General Public License
60 + * along with this program; if not, write to the Free Software
61 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
62 + */
63 +
64 +#include <mconfig.h>
65 +#include "mkisofs.h"
66 +#include <fctldefs.h>
67 +#include <utypes.h>
68 +#include <intcvt.h>
69 +#include "match.h"
70 +#include "diskmbr.h"
71 +#include "bootinfo.h"
72 +#include <schily.h>
73 +#include "endian.h"
74 +
75 +        int     add_boot_alpha_filename   __PR((char *filename));
76 +static  int     boot_alpha_write          __PR((FILE *outfile));
77 +static  char   *boot_file_name = NULL;
78 +
79 +#define BOOT_STRING "Linux/Alpha aboot for ISO filesystem."
80 +
81 +/* Simple function: store the filename to be used later when we need
82 +   to find the boot file */
83 +extern int add_boot_alpha_filename(filename)
84 +    char *filename;
85 +{
86 +    boot_file_name = filename;
87 +    return 0;
88 +}
89 +
90 +static int boot_alpha_write(outfile)
91 +    FILE *outfile;
92 +{
93 +    unsigned long long boot_sector[256]; /* One (ISO) sector */
94 +    unsigned long long sum = 0;
95 +       struct directory_entry  *boot_file;     /* Boot file we need to search for */
96 +    unsigned long length = 0;
97 +    unsigned long extent = 0;
98 +    int i = 0;
99 +
100 +    memset(boot_sector, 0, sizeof(boot_sector));    
101 +
102 +    /* Write the text header into the boot sector */
103 +    strcpy((char *)boot_sector, BOOT_STRING);
104 +
105 +    /* Find the dir entry for the boot file by walking our file list */
106 +    boot_file = search_tree_file(root, boot_file_name);
107 +    if (!boot_file) {
108 +#ifdef USE_LIBSCHILY
109 +               comerrno(EX_BAD, "Uh oh, I cant find the Alpha boot file '%s'!\n",
110 +                                                       boot_file_name);
111 +#else
112 +               fprintf(stderr, "Uh oh, I cant find the Alpha boot file '%s'!\n",
113 +                                                       boot_file_name);
114 +               exit(1);
115 +#endif
116 +    }
117 +
118 +    /* Grab the ISO start sector and length from the dir entry. ISO
119 +       uses 2048-byte sectors, but we convert to 512-byte sectors here
120 +       for the sake of the firmware */
121 +    extent = get_733(boot_file->isorec.extent);
122 +    extent *= 4;
123 +    
124 +    length = get_733(boot_file->isorec.size);
125 +    length /= 512; /* I'm sure we should take account of any overlap
126 +                      here, but I'm copying what isomarkboot
127 +                      does. Maybe the boot files are specified to be
128 +                      exact multiples of 512 bytes? */
129 +
130 +    fprintf(stderr, "Found alpha boot image %s: using extent %lu, #blocks %lu\n",
131 +            boot_file_name, extent, length);
132 +
133 +    /* Now write those values into the appropriate area of the boot
134 +       sector in LITTLE ENDIAN format. */
135 +    write_le64(length, (unsigned char *)(unsigned long long *)&boot_sector[60]);
136 +    write_le64(extent, (unsigned char *)&boot_sector[61]);
137 +
138 +    /* Now generate a checksum of the first 504 bytes of the boot
139 +       sector and place it in boot_sector[63]. Isomarkboot currently
140 +       gets this wrong and will not work on big-endian systems! */
141 +    for (i = 0; i < 63; i++)
142 +        sum += read_le64((unsigned char *)&boot_sector[i]);
143 +
144 +    write_le64(sum, (unsigned char *)&boot_sector[63]);
145 +
146 +    jtwrite(boot_sector, sizeof(boot_sector), 1, 0, FALSE);
147 +    xfwrite(boot_sector, sizeof(boot_sector), 1, outfile, 0, FALSE);
148 +    last_extent_written++;
149 +
150 +    return 0;
151 +}
152 +
153 +struct output_fragment alphaboot_desc = {NULL, oneblock_size, NULL, boot_alpha_write, "alpha boot block"};
154 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/boot-hppa.c cdrtools-2.0+a30.pre1/mkisofs.steve/boot-hppa.c
155 --- cdrtools-2.0+a30.pre1/mkisofs/boot-hppa.c   1970-01-01 01:00:00.000000000 +0100
156 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/boot-hppa.c     2004-06-17 13:10:05.000000000 +0100
157 @@ -0,0 +1,203 @@
158 +/*
159 + * Program boot-hppa.c - Handle HPPA boot extensions to iso9660.
160 + *
161 + * Written by Steve McIntyre <steve@einval.com> June 2004.
162 + *
163 + * Heavily inspired by palo:
164 + *
165 + ****************************************************************************
166 + * This file is subject to the terms and conditions of the GNU General Public
167 + * License.  See the file "COPYING" in the main directory of this archive
168 + * for more details.
169 + *
170 + * Copyright (C) Hewlett-Packard (Paul Bame) paul_bame@hp.com
171 + *
172 + ****************************************************************************
173 + * Copyright 2004 Steve McIntyre
174 + *
175 + * This program is free software; you can redistribute it and/or modify
176 + * it under the terms of the GNU General Public License as published by
177 + * the Free Software Foundation; either version 2, or (at your option)
178 + * any later version.
179 + *
180 + * This program is distributed in the hope that it will be useful,
181 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
182 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
183 + * GNU General Public License for more details.
184 + *
185 + * You should have received a copy of the GNU General Public License
186 + * along with this program; if not, write to the Free Software
187 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
188 + */
189 +
190 +#include <mconfig.h>
191 +#include "mkisofs.h"
192 +#include <fctldefs.h>
193 +#include <utypes.h>
194 +#include <intcvt.h>
195 +#include "match.h"
196 +#include "diskmbr.h"
197 +#include "bootinfo.h"
198 +#include <schily.h>
199 +#include "endian.h"
200 +
201 +int     add_boot_hppa_cmdline     __PR((char *cmdline));
202 +int     add_boot_hppa_kernel_32   __PR((char *filename));
203 +int     add_boot_hppa_kernel_64   __PR((char *filename));
204 +int     add_boot_hppa_bootloader  __PR((char *filename));
205 +int     add_boot_hppa_ramdisk     __PR((char *filename));
206 +
207 +static  int     boot_hppa_write   __PR((FILE *outfile));
208 +
209 +static  char   *hppa_cmdline = NULL;
210 +static  char   *hppa_kernel_32 = NULL;
211 +static  char   *hppa_kernel_64 = NULL;
212 +static  char   *hppa_bootloader = NULL;
213 +static  char   *hppa_ramdisk = NULL;
214 +
215 +/* Simple function: store the filename to be used later when we need
216 +   to find the boot file */
217 +extern int add_boot_hppa_cmdline(cmdline)
218 +    char *cmdline;
219 +{
220 +    char *ptr = NULL;
221 +    hppa_cmdline = strdup(cmdline);
222 +    ptr = hppa_cmdline;
223 +    while (*ptr)
224 +    {
225 +        if (',' == *ptr)
226 +            *ptr = ' ';
227 +        ptr++;
228 +    }    
229 +    return 0;
230 +}
231 +
232 +/* Simple function: store the filename to be used later when we need
233 +   to find the boot file */
234 +extern int add_boot_hppa_kernel_32(filename)
235 +    char *filename;
236 +{
237 +    hppa_kernel_32 = filename;
238 +    return 0;
239 +}
240 +
241 +/* Simple function: store the filename to be used later when we need
242 +   to find the boot file */
243 +extern int add_boot_hppa_kernel_64(filename)
244 +    char *filename;
245 +{
246 +    hppa_kernel_64 = filename;
247 +    return 0;
248 +}
249 +
250 +/* Simple function: store the filename to be used later when we need
251 +   to find the boot file */
252 +extern int add_boot_hppa_bootloader(filename)
253 +    char *filename;
254 +{
255 +    hppa_bootloader = filename;
256 +    return 0;
257 +}
258 +
259 +/* Simple function: store the filename to be used later when we need
260 +   to find the boot file */
261 +extern int add_boot_hppa_ramdisk(filename)
262 +    char *filename;
263 +{
264 +    hppa_ramdisk = filename;
265 +    return 0;
266 +}
267 +
268 +static void exit_fatal(type, filename)
269 +    char *type;
270 +    char *filename;
271 +{
272 +#ifdef USE_LIBSCHILY
273 +    comerrno(EX_BAD, "Uh oh, I can't find the %s '%s'!\n",
274 +             type, filename);
275 +#else
276 +    fprintf(stderr, "Uh oh, I can't find the %s '%s'!\n",
277 +             type, filename);
278 +    exit(1);
279 +#endif
280 +}
281 +
282 +static int boot_hppa_write(outfile)
283 +    FILE *outfile;
284 +{
285 +    unsigned char boot_sector[2048]; /* One (ISO) sector */
286 +       struct directory_entry  *boot_file;     /* Boot file we need to search for */
287 +    unsigned long length = 0;
288 +    unsigned long extent = 0;
289 +    int i = 0;
290 +
291 +    memset(boot_sector, 0, sizeof(boot_sector));    
292 +
293 +    boot_sector[0] = 0x80;  /* magic */
294 +    boot_sector[1] = 0x00;  /* magic */
295 +    boot_sector[2] = 'P';
296 +    boot_sector[3] = 'A';
297 +    boot_sector[4] = 'L';
298 +    boot_sector[5] = 'O';
299 +    boot_sector[6] = 0x00;
300 +    boot_sector[7] = 0x04;  /* version */
301 +
302 +    /* Find the dir entry for the 32-bit kernel by walking our file list */
303 +    boot_file = search_tree_file(root, hppa_kernel_32);
304 +    if (!boot_file)
305 +        exit_fatal("HPPA 32-bit kernel", hppa_kernel_32);
306 +    extent = 2048 * get_733(boot_file->isorec.extent);
307 +    length = get_733(boot_file->isorec.size);
308 +    fprintf(stderr, "Found hppa 32-bit kernel %s: using extent %lu (0x%lX), size %lu (0x%lX)\n",
309 +            hppa_kernel_32, extent, extent, length, length);
310 +    write_be32(extent, &boot_sector[8]);
311 +    write_be32(length, &boot_sector[12]);
312 +
313 +    /* Find the dir entry for the ramdisk by walking our file list */
314 +    boot_file = search_tree_file(root, hppa_ramdisk);
315 +    if (!boot_file)
316 +        exit_fatal("HPPA ramdisk", hppa_ramdisk);
317 +    extent = 2048 * get_733(boot_file->isorec.extent);
318 +    length = get_733(boot_file->isorec.size);
319 +    fprintf(stderr, "Found hppa ramdisk %s: using extent %lu (0x%lX), size %lu (0x%lX)\n",
320 +            hppa_ramdisk, extent, extent, length, length);
321 +    write_be32(extent, &boot_sector[16]);
322 +    write_be32(length, &boot_sector[20]);
323 +
324 +    /* Now the commandline */
325 +    snprintf(&boot_sector[24], 127, "%s", hppa_cmdline);
326 +
327 +    /* Find the dir entry for the 64-bit kernel by walking our file list */
328 +    boot_file = search_tree_file(root, hppa_kernel_64);
329 +    if (!boot_file)
330 +        exit_fatal("HPPA 64-bit kernel", hppa_kernel_64);
331 +    extent = 2048 * get_733(boot_file->isorec.extent);
332 +    length = get_733(boot_file->isorec.size);
333 +    fprintf(stderr, "Found hppa 64-bit kernel %s: using extent %lu (0x%lX), size %lu (0x%lX)\n",
334 +            hppa_kernel_64, extent, extent, length, length);
335 +    write_be32(extent, &boot_sector[232]);
336 +    write_be32(length, &boot_sector[236]);
337 +
338 +    /* Find the dir entry for the IPL by walking our file list */
339 +    boot_file = search_tree_file(root, hppa_bootloader);
340 +    if (!boot_file)
341 +        exit_fatal("HPPA bootloader", hppa_bootloader);
342 +    extent = 2048 * get_733(boot_file->isorec.extent);
343 +    length = get_733(boot_file->isorec.size);
344 +    fprintf(stderr, "Found hppa bootloader %s: using extent %lu (0x%lX), size %lu (0x%lX)\n",
345 +            hppa_bootloader, extent, extent, length, length);
346 +    write_be32(extent, &boot_sector[240]);
347 +    write_be32(length, &boot_sector[244]);
348 +
349 +    jtwrite(boot_sector, sizeof(boot_sector), 1, 0, FALSE);
350 +    xfwrite(boot_sector, sizeof(boot_sector), 1, outfile, 0, FALSE);
351 +    last_extent_written++;
352 +
353 +    return 0;
354 +}
355 +
356 +struct output_fragment hppaboot_desc = {NULL, oneblock_size, NULL, boot_hppa_write, "hppa boot block"};
357 +
358 +
359 +
360 +
361 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/boot-mips.c cdrtools-2.0+a30.pre1/mkisofs.steve/boot-mips.c
362 --- cdrtools-2.0+a30.pre1/mkisofs/boot-mips.c   1970-01-01 01:00:00.000000000 +0100
363 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/boot-mips.c     2004-06-16 19:24:36.000000000 +0100
364 @@ -0,0 +1,328 @@
365 +/*
366 + * Program boot-mips.c - Handle big-endian boot extensions to iso9660.
367 + *
368 + * Written by Steve McIntyre <steve@einval.com> June 2004
369 + *
370 + * Heavily inspired by / borrowed from genisovh:
371 + *
372 + * Copyright: (C) 2002 by Florian Lohoff <flo@rfc822.org>
373 + *            (C) 2004 by Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
374 + *
375 + * This program is free software; you can redistribute it and/or modify it under
376 + * the terms of the GNU General Public License, Version 2, as published by the
377 + * Free Software Foundation.
378 + *
379 + * Format for volume header information
380 + *
381 + * The volume header is a block located at the beginning of all disk
382 + * media (sector 0).  It contains information pertaining to physical
383 + * device parameters and logical partition information.
384 + *
385 + * The volume header is manipulated by disk formatters/verifiers,
386 + * partition builders (e.g. fx, dvhtool, and mkfs), and disk drivers.
387 + *
388 + * Previous versions of IRIX wrote a copy of the volume header is
389 + * located at sector 0 of each track of cylinder 0.  These copies were
390 + * never used, and reduced the capacity of the volume header to hold large
391 + * files, so this practice was discontinued.
392 + * The volume header is constrained to be less than or equal to 512
393 + * bytes long.  A particular copy is assumed valid if no drive errors
394 + * are detected, the magic number is correct, and the 32 bit 2's complement
395 + * of the volume header is correct.  The checksum is calculated by initially
396 + * zeroing vh_csum, summing the entire structure and then storing the
397 + * 2's complement of the sum.  Thus a checksum to verify the volume header
398 + * should be 0.
399 + *
400 + * The error summary table, bad sector replacement table, and boot blocks are
401 + * located by searching the volume directory within the volume header.
402 + *
403 + * Tables are sized simply by the integral number of table records that
404 + * will fit in the space indicated by the directory entry.
405 + *
406 + * The amount of space allocated to the volume header, replacement blocks,
407 + * and other tables is user defined when the device is formatted.
408 + */
409 +
410 +#include <stdint.h>
411 +
412 +/*
413 + * device parameters are in the volume header to determine mapping
414 + * from logical block numbers to physical device addresses
415 + *
416 + * Linux doesn't care ...
417 + */
418 +struct device_parameters {
419 +       uint8_t dp_skew;        /* spiral addressing skew */
420 +       uint8_t dp_gap1;        /* words of 0 before header */
421 +       uint8_t dp_gap2;        /* words of 0 between hdr and data */
422 +       uint8_t dp_spares_cyl;  /* This is for drives (such as SCSI
423 +               that support zone oriented sparing, where the zone is larger
424 +               than one track.  It gets subracteded from the cylinder size
425 +               ( dp_trks0 * dp_sec) when doing partition size calculations */
426 +       uint16_t dp_cyls;       /* number of usable cylinders (i.e.,
427 +               doesn't include cylinders reserved by the drive for badblocks,
428 +               etc.). For drives with variable geometry, this number may be
429 +               decreased so that:
430 +               dp_cyls * ((dp_heads * dp_trks0) - dp_spares_cyl) <= actualcapacity
431 +               This happens on SCSI drives such as the Wren IV and Toshiba 156
432 +               Also see dp_cylshi below */
433 +       uint16_t dp_shd0;       /* starting head vol 0 */
434 +       uint16_t dp_trks0;      /* number of tracks / cylinder vol 0*/
435 +       uint8_t dp_ctq_depth;   /* Depth of CTQ queue */
436 +       uint8_t dp_cylshi;      /* high byte of 24 bits of cylinder count */
437 +       uint16_t dp_unused;     /* not used */
438 +       uint16_t dp_secs;       /* number of sectors/track */
439 +       uint16_t dp_secbytes;   /* length of sector in bytes */
440 +       uint16_t dp_interleave; /* sector interleave */
441 +       int32_t dp_flags;               /* controller characteristics */
442 +       int32_t dp_datarate;            /* bytes/sec for kernel stats */
443 +       int32_t dp_nretries;            /* max num retries on data error */
444 +       int32_t dp_mspw;                /* ms per word to xfer, for iostat */
445 +       uint16_t dp_xgap1;      /* Gap 1 for xylogics controllers */
446 +       uint16_t dp_xsync;    /* sync delay for xylogics controllers */
447 +       uint16_t dp_xrdly;    /* read delay for xylogics controllers */
448 +       uint16_t dp_xgap2;    /* gap 2 for xylogics controllers */
449 +       uint16_t dp_xrgate;   /* read gate for xylogics controllers */
450 +       uint16_t dp_xwcont;   /* write continuation for xylogics */
451 +};
452 +
453 +/*
454 + * Device characterization flags
455 + * (dp_flags)
456 + */
457 +#define        DP_SECTSLIP     0x00000001      /* sector slip to spare sector */
458 +#define        DP_SECTFWD      0x00000002      /* forward to replacement sector */
459 +#define        DP_TRKFWD       0x00000004      /* forward to replacement track */
460 +#define        DP_MULTIVOL     0x00000008      /* multiple volumes per spindle */
461 +#define        DP_IGNOREERRORS 0x00000010      /* transfer data regardless of errors */
462 +#define DP_RESEEK      0x00000020      /* recalibrate as last resort */
463 +#define        DP_CTQ_EN       0x00000040      /* enable command tag queueing */
464 +
465 +/*
466 + * Boot blocks, bad sector tables, and the error summary table, are located
467 + * via the volume_directory.
468 + */
469 +#define VDNAMESIZE     8
470 +
471 +struct volume_directory {
472 +       int8_t  vd_name[VDNAMESIZE];    /* name */
473 +       int32_t vd_lbn;                 /* logical block number */
474 +       int32_t vd_nbytes;              /* file length in bytes */
475 +};
476 +
477 +/*
478 + * partition table describes logical device partitions
479 + * (device drivers examine this to determine mapping from logical units
480 + * to cylinder groups, device formatters/verifiers examine this to determine
481 + * location of replacement tracks/sectors, etc)
482 + *
483 + * NOTE: pt_firstlbn SHOULD BE CYLINDER ALIGNED
484 + */
485 +struct partition_table {               /* one per logical partition */
486 +       int32_t pt_nblks;               /* # of logical blks in partition */
487 +       int32_t pt_firstlbn;            /* first lbn of partition */
488 +       int32_t pt_type;                /* use of partition */
489 +};
490 +
491 +#define        PTYPE_VOLHDR    0               /* partition is volume header */
492 +#define        PTYPE_TRKREPL   1               /* partition is used for repl trks */
493 +#define        PTYPE_SECREPL   2               /* partition is used for repl secs */
494 +#define        PTYPE_RAW       3               /* partition is used for data */
495 +#define        PTYPE_BSD42     4               /* partition is 4.2BSD file system */
496 +#define        PTYPE_BSD       4               /* partition is 4.2BSD file system */
497 +#define        PTYPE_SYSV      5               /* partition is SysV file system */
498 +#define        PTYPE_VOLUME    6               /* partition is entire volume */
499 +#define        PTYPE_EFS       7               /* partition is sgi EFS */
500 +#define        PTYPE_LVOL      8               /* partition is part of a logical vol */
501 +#define        PTYPE_RLVOL     9               /* part of a "raw" logical vol */
502 +#define        PTYPE_XFS       10              /* partition is sgi XFS */
503 +#define        PTYPE_XFSLOG    11              /* partition is sgi XFS log */
504 +#define        PTYPE_XLV       12              /* partition is part of an XLV vol */
505 +#define        PTYPE_XVM       13              /* partition is sgi XVM */
506 +#define        PTYPE_LSWAP     0x82            /* partition is Linux swap */
507 +#define        PTYPE_LINUX     0x83            /* partition is Linux native */
508 +#define NPTYPES                16
509 +
510 +#define        VHMAGIC         0xbe5a941       /* randomly chosen value */
511 +#define        NPARTAB         16              /* 16 unix partitions */
512 +#define        NVDIR           15              /* max of 15 directory entries */
513 +#define BFNAMESIZE     16              /* max 16 chars in boot file name */
514 +
515 +/* Partition types for ARCS */
516 +#define NOT_USED        0       /* Not used                            */
517 +#define FAT_SHORT       1       /* FAT filesystem, 12-bit FAT entries  */
518 +#define FAT_LONG        4       /* FAT filesystem, 16-bit FAT entries  */
519 +#define EXTENDED        5       /* extended partition                  */
520 +#define HUGE            6       /* huge partition- MS/DOS 4.0 and later */
521 +
522 +/* Active flags for ARCS */
523 +#define BOOTABLE        0x00;
524 +#define NOT_BOOTABLE    0x80;
525 +
526 +struct volume_header {
527 +       int32_t vh_magic; /* identifies volume header */
528 +       int16_t vh_rootpt; /* root partition number */
529 +       int16_t vh_swappt; /* swap partition number */
530 +       int8_t vh_bootfile[BFNAMESIZE]; /* name of file to boot */
531 +       struct device_parameters vh_dp; /* device parameters */
532 +       struct volume_directory vh_vd[NVDIR]; /* other vol hdr contents */
533 +       struct partition_table vh_pt[NPARTAB]; /* device partition layout */
534 +       int32_t vh_csum; /* volume header checksum */
535 +       int32_t vh_fill; /* fill out to 512 bytes */
536 +    char pad[1536];  /* pad out to 2048 */
537 +};
538 +
539 +#include <mconfig.h>
540 +#include "mkisofs.h"
541 +#include <fctldefs.h>
542 +#include <utypes.h>
543 +#include <intcvt.h>
544 +#include "match.h"
545 +#include "diskmbr.h"
546 +#include "bootinfo.h"
547 +#include <schily.h>
548 +#include "endian.h"
549 +
550 +int     add_boot_mips_filename    __PR((char *filename));
551 +
552 +static  int     boot_mips_write   __PR((FILE *outfile));
553 +
554 +#define MAX_NAMES 15
555 +static char *boot_mips_filename[MAX_NAMES] =
556 +{
557 +    NULL, NULL, NULL,
558 +    NULL, NULL, NULL,
559 +    NULL, NULL, NULL,
560 +    NULL, NULL, NULL,
561 +    NULL, NULL, NULL
562 +};
563 +
564 +static int boot_mips_num_files = 0;
565 +
566 +#define SECTORS_PER_TRACK      32
567 +#define BYTES_PER_SECTOR       512
568 +
569 +int add_boot_mips_filename(filename)
570 +    char *filename;
571 +{
572 +    if (boot_mips_num_files < MAX_NAMES)
573 +    {
574 +        boot_mips_filename[boot_mips_num_files] = filename;
575 +        boot_mips_num_files++;
576 +    }
577 +
578 +    else
579 +    {
580 +#ifdef USE_LIBSCHILY
581 +        comerrno(EX_BAD, "Too many MIPS boot files!\n");
582 +#else
583 +        fprintf(stderr, "Too many MIPS boot files!\n");
584 +        exit(1);
585 +#endif
586 +    }
587 +    return 0;
588 +}
589 +
590 +static void vh_calc_checksum(struct volume_header *vh)
591 +{
592 +       uint32_t newsum = 0;
593 +       unsigned char *buffer = (unsigned char *)vh;
594 +       unsigned int i;
595 +
596 +       vh->vh_csum = 0;
597 +
598 +       for(i = 0; i < sizeof(struct volume_header); i += 4)
599 +        newsum -= read_be32(&buffer[i]);
600 +
601 +    write_be32(newsum, (unsigned char *)&vh->vh_csum);
602 +}
603 +
604 +static char *file_base_name(char *path)
605 +{
606 +    char *endptr = path;
607 +    char *ptr = path;
608 +    
609 +    while (*ptr != '\0')
610 +    {
611 +        if ('/' == *ptr)
612 +            endptr = ++ptr;
613 +        else
614 +            ++ptr;
615 +    }
616 +    return endptr;
617 +}
618 +
619 +static int boot_mips_write(outfile)
620 +    FILE *outfile;
621 +{
622 +       struct directory_entry  *boot_file;     /* Boot file we need to search for */
623 +    unsigned long length = 0;
624 +    unsigned long extent = 0;
625 +       int i;
626 +       struct volume_header vh;
627 +    unsigned long long iso_size = 0;
628 +    char *filename = NULL;
629 +
630 +       memset(&vh, 0, sizeof(vh));
631 +
632 +    iso_size = last_extent * 2048;
633 +
634 +    write_be32(VHMAGIC, (unsigned char *)&vh.vh_magic);
635 +
636 +       /* Values from an IRIX cd */
637 +    write_be16(BYTES_PER_SECTOR, (unsigned char *)&vh.vh_dp.dp_secbytes);
638 +    write_be16(SECTORS_PER_TRACK, (unsigned char *)&vh.vh_dp.dp_secs);
639 +    write_be32(DP_RESEEK|DP_IGNOREERRORS|DP_TRKFWD, (unsigned char *)&vh.vh_dp.dp_flags);
640 +    write_be16(1, (unsigned char *)&vh.vh_dp.dp_trks0);
641 +
642 +    write_be16((iso_size + BYTES_PER_SECTOR - 1) / (SECTORS_PER_TRACK * BYTES_PER_SECTOR),
643 +               (unsigned char *)&vh.vh_dp.dp_cyls);
644 +
645 +       for(i = 0; i < boot_mips_num_files; i++)
646 +    {
647 +        boot_file = search_tree_file(root, boot_mips_filename[i]);
648 +        
649 +        if (!boot_file) {
650 +#ifdef USE_LIBSCHILY
651 +            comerrno(EX_BAD, "Uh oh, I cant find the MIPS boot file '%s'!\n",
652 +                     boot_mips_filename[i]);
653 +#else
654 +            fprintf(stderr, "Uh oh, I cant find the MIPS boot file '%s'!\n",
655 +                    boot_mips_filename[i]);
656 +            exit(1);
657 +#endif
658 +        }
659 +
660 +        extent = get_733(boot_file->isorec.extent) * 4;
661 +        length = ((get_733(boot_file->isorec.size) + 2047) / 2048) * 2048;
662 +        filename = file_base_name(boot_mips_filename[i]);
663 +
664 +        strncpy(vh.vh_vd[i].vd_name, filename, MIN(VDNAMESIZE, strlen(filename)));
665 +        write_be32(extent, (unsigned char *)&vh.vh_vd[i].vd_lbn);
666 +        write_be32(length, (unsigned char *)&vh.vh_vd[i].vd_nbytes);
667 +        
668 +        fprintf(stderr, "Found mips boot image %s, using extent %lu (0x%lX), #blocks %lu (0x%lX)\n",
669 +                filename, extent, extent, length, length);
670 +       }
671 +
672 +       /* Create volume partition on whole cd iso */
673 +    write_be32((iso_size + (BYTES_PER_SECTOR - 1))/ BYTES_PER_SECTOR, (unsigned char *)&vh.vh_pt[10].pt_nblks);
674 +    write_be32(0, (unsigned char *)&vh.vh_pt[10].pt_firstlbn);
675 +    write_be32(PTYPE_VOLUME, (unsigned char *)&vh.vh_pt[10].pt_type);
676 +
677 +       /* Create volume header partition, also on WHOLE cd iso */
678 +    write_be32((iso_size + (BYTES_PER_SECTOR - 1))/ BYTES_PER_SECTOR, (unsigned char *)&vh.vh_pt[8].pt_nblks);
679 +    write_be32(0, (unsigned char *)&vh.vh_pt[8].pt_firstlbn);
680 +    write_be32(PTYPE_VOLHDR, (unsigned char *)&vh.vh_pt[8].pt_type);
681 +
682 +       /* Create checksum */
683 +       vh_calc_checksum(&vh);
684 +
685 +    jtwrite(&vh, sizeof(vh), 1, 0, FALSE);
686 +    xfwrite(&vh, sizeof(vh), 1, outfile, 0, FALSE);
687 +    last_extent_written++;
688 +
689 +       return 0;
690 +}
691 +
692 +struct output_fragment mipsboot_desc = {NULL, oneblock_size, NULL, boot_mips_write, "MIPS boot block"};
693 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/boot-mipsel.c cdrtools-2.0+a30.pre1/mkisofs.steve/boot-mipsel.c
694 --- cdrtools-2.0+a30.pre1/mkisofs/boot-mipsel.c 1970-01-01 01:00:00.000000000 +0100
695 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/boot-mipsel.c   2004-06-17 11:36:06.000000000 +0100
696 @@ -0,0 +1,242 @@
697 +/*
698 + * Program boot-mipsel.c - Handle Mipsel boot extensions to iso9660.
699 + *
700 + *  Written by Steve McIntyre <steve@einval.com> (2004).
701 + *
702 + * Heavily inspired by / borrowed from delo:
703 + *
704 + * Copyright: (C) 2002 by Florian Lohoff <flo@rfc822.org>
705 + *            (C) 2004 by Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
706 + *
707 + * This program is free software; you can redistribute it and/or modify it under
708 + * the terms of the GNU General Public License, Version 2, as published by the
709 + * Free Software Foundation.
710 + *
711 + * Format for volume header information
712 + *
713 + * The volume header is a block located at the beginning of all disk
714 + * media (sector 0).  It contains information pertaining to physical
715 + * device parameters and logical partition information.
716 + *
717 + * The volume header is manipulated by disk formatters/verifiers,
718 + * partition builders (e.g. fx, dvhtool, and mkfs), and disk drivers.
719 + *
720 + * Previous versions of IRIX wrote a copy of the volume header is
721 + * located at sector 0 of each track of cylinder 0.  These copies were
722 + * never used, and reduced the capacity of the volume header to hold large
723 + * files, so this practice was discontinued.
724 + * The volume header is constrained to be less than or equal to 512
725 + * bytes long.  A particular copy is assumed valid if no drive errors
726 + * are detected, the magic number is correct, and the 32 bit 2's complement
727 + * of the volume header is correct.  The checksum is calculated by initially
728 + * zeroing vh_csum, summing the entire structure and then storing the
729 + * 2's complement of the sum.  Thus a checksum to verify the volume header
730 + * should be 0.
731 + *
732 + * The error summary table, bad sector replacement table, and boot blocks are
733 + * located by searching the volume directory within the volume header.
734 + *
735 + * Tables are sized simply by the integral number of table records that
736 + * will fit in the space indicated by the directory entry.
737 + *
738 + * The amount of space allocated to the volume header, replacement blocks,
739 + * and other tables is user defined when the device is formatted.
740 + */
741 +
742 +#include <mconfig.h>
743 +#include "mkisofs.h"
744 +#include <fctldefs.h>
745 +#include <utypes.h>
746 +#include <intcvt.h>
747 +#include "match.h"
748 +#include "diskmbr.h"
749 +#include "bootinfo.h"
750 +#include <schily.h>
751 +#include "endian.h"
752 +#include <errno.h>
753 +#include <elf.h>
754 +
755 +int             add_boot_mipsel_filename  __PR((char *filename));
756 +static  int     boot_mipsel_write         __PR((FILE *outfile));
757 +
758 +static  char   *boot_file_name = NULL;
759 +
760 +#define MAX_MAPS        51
761 +#define DEC_BOOT_MAGIC  0x02757a
762 +#define HD_SECTOR_SIZE  512
763 +
764 +/* Those were stolen from linux kernel headers. */
765 +
766 +struct extent {
767 +    uint32_t count;
768 +    uint32_t start;
769 +} __attribute__((packed));
770 +
771 +struct dec_bootblock {
772 +    int8_t pad[8];
773 +    int32_t magic;          /* We are a DEC BootBlock */
774 +    int32_t mode;           /* 0: Single extent, 1: Multi extent boot */
775 +    int32_t loadAddr;       /* Load below kernel */
776 +    int32_t execAddr;       /* And exec there */
777 +    struct extent bootmap[MAX_MAPS];
778 +} __attribute__((packed));
779 +
780 +static void swap_in_elf32_ehdr(Elf32_Ehdr *ehdr)
781 +{
782 +    ehdr->e_type = read_le16((unsigned char *)&ehdr->e_type);
783 +    ehdr->e_machine = read_le16((unsigned char *)&ehdr->e_machine);
784 +    ehdr->e_version = read_le32((unsigned char *)&ehdr->e_version);
785 +    ehdr->e_entry = read_le32((unsigned char *)&ehdr->e_entry);
786 +    ehdr->e_phoff = read_le32((unsigned char *)&ehdr->e_phoff);
787 +    ehdr->e_shoff = read_le32((unsigned char *)&ehdr->e_shoff);
788 +    ehdr->e_flags = read_le32((unsigned char *)&ehdr->e_flags);
789 +    ehdr->e_ehsize = read_le16((unsigned char *)&ehdr->e_ehsize);
790 +    ehdr->e_phentsize = read_le16((unsigned char *)&ehdr->e_phentsize);
791 +    ehdr->e_phnum = read_le16((unsigned char *)&ehdr->e_phnum);
792 +    ehdr->e_shentsize = read_le16((unsigned char *)&ehdr->e_shentsize);
793 +    ehdr->e_shnum = read_le16((unsigned char *)&ehdr->e_shnum);
794 +    ehdr->e_shstrndx = read_le16((unsigned char *)&ehdr->e_shstrndx);
795 +}
796 +
797 +static void swap_in_elf32_phdr(Elf32_Phdr *phdr)
798 +{
799 +    phdr->p_type = read_le32((unsigned char *)&phdr->p_type);
800 +    phdr->p_offset = read_le32((unsigned char *)&phdr->p_offset);
801 +    phdr->p_vaddr = read_le32((unsigned char *)&phdr->p_vaddr);
802 +    phdr->p_paddr = read_le32((unsigned char *)&phdr->p_paddr);
803 +    phdr->p_filesz = read_le32((unsigned char *)&phdr->p_filesz);
804 +    phdr->p_memsz = read_le32((unsigned char *)&phdr->p_memsz);
805 +    phdr->p_flags = read_le32((unsigned char *)&phdr->p_flags);
806 +    phdr->p_align = read_le32((unsigned char *)&phdr->p_align);
807 +}
808 +
809 +/* Simple function: store the filename to be used later when we need
810 +   to find the boot file */
811 +extern int add_boot_mipsel_filename(filename)
812 +    char *filename;
813 +{
814 +    boot_file_name = filename;
815 +    return 0;
816 +}
817 +
818 +/* Parse the ELF header of the boot loaded to work out the load
819 +   address and exec address */
820 +static int parse_boot_file(char *filename, int32_t *loadaddr, int32_t *execaddr, int32_t *offset, int32_t *count)
821 +{
822 +    int error = 0;
823 +    FILE *loader = NULL;
824 +    Elf32_Ehdr ehdr;
825 +    Elf32_Phdr phdr;
826 +    
827 +    loader = fopen(filename, "rb");
828 +    if (!loader)
829 +        return errno;
830 +    
831 +    error = fread(&ehdr, sizeof(ehdr), 1, loader);
832 +    if (1 != error)
833 +        return EIO;
834 +
835 +    swap_in_elf32_ehdr(&ehdr);
836 +    if (!(ehdr.e_ident[EI_MAG0] == ELFMAG0
837 +          && ehdr.e_ident[EI_MAG1] == ELFMAG1
838 +          && ehdr.e_ident[EI_MAG2] == ELFMAG2
839 +          && ehdr.e_ident[EI_MAG3] == ELFMAG3
840 +          && ehdr.e_ident[EI_CLASS] == ELFCLASS32
841 +          && ehdr.e_ident[EI_DATA] == ELFDATA2LSB
842 +          && ehdr.e_ident[EI_VERSION] == EV_CURRENT
843 +          && ehdr.e_type == ET_EXEC
844 +          && ehdr.e_machine == EM_MIPS
845 +          && ehdr.e_version == EV_CURRENT))
846 +    {
847 +        fprintf(stderr, "Sorry, %s is not a MIPS ELF32 little endian file", filename);        
848 +        return EINVAL;
849 +    }
850 +    if (ehdr.e_phnum != 1)
851 +    {
852 +        fprintf(stderr, "Sorry, %s has more than one ELF segment", filename);
853 +        return EINVAL;
854 +    }
855 +    fseek(loader, ehdr.e_phoff, SEEK_SET);
856 +    error = fread(&phdr, sizeof(phdr), 1, loader);
857 +    if (1 != error)
858 +        return EIO;
859 +
860 +    *loadaddr = phdr.p_vaddr;
861 +    *execaddr = ehdr.e_entry;
862 +       *offset = (phdr.p_offset + HD_SECTOR_SIZE - 1) / HD_SECTOR_SIZE;
863 +       *count = (phdr.p_filesz + HD_SECTOR_SIZE - 1) / HD_SECTOR_SIZE;
864 +
865 +    fprintf(stderr, "Parsed mipsel boot image %s: using loadaddr 0x%X, execaddr 0x%X, offset 0x%X, count 0x%X\n",
866 +            filename, *loadaddr, *execaddr, *offset, *count);
867 +
868 +    fclose(loader);
869 +    return 0;
870 +}
871 +
872 +static int boot_mipsel_write(outfile)
873 +    FILE *outfile;
874 +{
875 +    char sector[2048];
876 +    struct dec_bootblock *bb = (struct dec_bootblock *)sector;
877 +    int error = 0;
878 +    int offset = 0;
879 +    int count = 0;
880 +    struct directory_entry     *boot_file;     /* Boot file we need to search for in the image */
881 +    unsigned long length = 0;
882 +    unsigned long extent = 0;
883 +    int loadaddr = 0;
884 +    int execaddr = 0;
885 +
886 +    memset(sector, 0, sizeof(sector));
887 +
888 +    /* Fill in our values we care on */
889 +    write_le32(DEC_BOOT_MAGIC, (unsigned char *)&bb->magic);
890 +    write_le32(1, (unsigned char *)&bb->mode);
891 +
892 +    /* Find the file entry in the CD image */
893 +    boot_file = search_tree_file(root, boot_file_name);
894 +    if (!boot_file)
895 +    {
896 +#ifdef USE_LIBSCHILY
897 +               comerrno(EX_BAD, "Uh oh, unable to find the mipsel boot file '%s'!\n",
898 +                 boot_file_name);
899 +#else
900 +               fprintf(stderr, "Uh oh, unable to find the mipsel boot file '%s'!\n",
901 +                boot_file_name);
902 +               exit(1);
903 +#endif
904 +    }
905 +
906 +    extent = get_733(boot_file->isorec.extent);
907 +    length = get_733(boot_file->isorec.size);
908 +    fprintf(stderr, "Found mipsel boot loader %s: using extent %lu, #blocks %lu\n",
909 +            boot_file_name, extent, length);
910 +
911 +    /* Parse the ELF headers on the boot file */
912 +    error = parse_boot_file(boot_file->whole_name, &loadaddr, &execaddr, &offset, &count);
913 +    if (error)
914 +    {
915 +#ifdef USE_LIBSCHILY
916 +               comerrno(EX_BAD, "Uh oh, unable to parse the mipsel boot file '%s'!\n",
917 +                 boot_file->whole_name);
918 +#else
919 +               fprintf(stderr, "Uh oh, unable to parse the mipsel boot file '%s'!\n",
920 +                boot_file->whole_name);
921 +               exit(1);
922 +#endif
923 +    }
924 +
925 +    write_le32(loadaddr, (unsigned char *)&bb->loadAddr);
926 +    write_le32(execaddr, (unsigned char *)&bb->execAddr);
927 +    write_le32((extent * 4) + offset, (unsigned char *)&bb->bootmap[0].start);
928 +    write_le32(count, (unsigned char *)&bb->bootmap[0].count);
929 +    
930 +    jtwrite(sector, sizeof(sector), 1, 0, FALSE);
931 +    xfwrite(sector, sizeof(sector), 1, outfile, 0, FALSE);
932 +    last_extent_written++;
933 +
934 +    return 0;
935 +}
936 +
937 +struct output_fragment mipselboot_desc = {NULL, oneblock_size, NULL, boot_mipsel_write, "mipsel boot block"};
938 +
939 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/boot.c cdrtools-2.0+a30.pre1/mkisofs.steve/boot.c
940 --- cdrtools-2.0+a30.pre1/mkisofs/boot.c        2004-02-22 15:25:09.000000000 +0000
941 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/boot.c  2004-06-16 19:24:36.000000000 +0100
942 @@ -373,6 +373,7 @@
943          */
944         amt = roundup(last_extent_written, (CD_CYLSIZE/SECTOR_SIZE)) - last_extent_written;
945         for (n = 0; n < amt; n++) {
946 +        jtwrite(buffer, SECTOR_SIZE, 1, 0, FALSE);
947                 xfwrite(buffer, SECTOR_SIZE, 1, outfile, 0, FALSE);
948                 last_extent_written++;
949         }
950 @@ -403,6 +404,7 @@
951                         memset(buffer, 0, sizeof (buffer));
952                         if (read(f, buffer, SECTOR_SIZE) < 0)
953                                 comerr("Read error on '%s'.\n", boot_files[i]);
954 +            jtwrite(buffer, SECTOR_SIZE, 1, 0, FALSE);
955                         xfwrite(buffer, SECTOR_SIZE, 1, outfile, 0, FALSE);
956                         last_extent_written++;
957                 }
958 @@ -484,6 +486,7 @@
959                 memcpy(buffer, &cd_label, 512);
960         }
961  
962 +    jtwrite(buffer, SECTOR_SIZE, 1, 0, FALSE);
963         xfwrite(buffer, SECTOR_SIZE, 1, outfile, 0, FALSE);
964         last_extent_written++;
965         return (0);
966 @@ -523,6 +526,7 @@
967                         comerr("Read error on '%s'.\n", genboot_image);
968  
969                 if (i != 0 || last_extent_written == session_start) {
970 +                       jtwrite(buffer, SECTOR_SIZE, 1, 0, FALSE);
971                         xfwrite(buffer, SECTOR_SIZE, 1, outfile, 0, FALSE);
972                         last_extent_written++;
973                 }
974 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/eltorito.c cdrtools-2.0+a30.pre1/mkisofs.steve/eltorito.c
975 --- cdrtools-2.0+a30.pre1/mkisofs/eltorito.c    2004-03-04 22:39:29.000000000 +0000
976 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/eltorito.c      2004-06-16 19:24:36.000000000 +0100
977 @@ -666,6 +666,7 @@
978         }
979         /* Next we write out the boot volume descriptor for the disc */
980         get_torito_desc(&gboot_desc);
981 +       jtwrite(&gboot_desc, SECTOR_SIZE, 1, 0, FALSE);
982         xfwrite(&gboot_desc, SECTOR_SIZE, 1, outfile, 0, FALSE);
983         last_extent_written++;
984         return (0);
985 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/endian.c cdrtools-2.0+a30.pre1/mkisofs.steve/endian.c
986 --- cdrtools-2.0+a30.pre1/mkisofs/endian.c      1970-01-01 01:00:00.000000000 +0100
987 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/endian.c        2004-06-16 19:24:36.000000000 +0100
988 @@ -0,0 +1,188 @@
989 +#include <mconfig.h>
990 +#include "endian.h"
991 +
992 +/* Write a 64-bit quantity out into memory in BIG ENDIAN order */
993 +void write_be64(in, out)
994 +    unsigned long long in;
995 +    unsigned char *out;
996 +{
997 +    out[0] = (in >> 56) & 0xFF;
998 +    out[1] = (in >> 48) & 0xFF;
999 +    out[2] = (in >> 40) & 0xFF;
1000 +    out[3] = (in >> 32) & 0xFF;
1001 +    out[4] = (in >> 24) & 0xFF;
1002 +    out[5] = (in >> 16) & 0xFF;
1003 +    out[6] = (in >> 8) & 0xFF;
1004 +    out[7] = in & 0xFF;
1005 +}
1006 +
1007 +/* Read in a 64-bit BIG ENDIAN quantity */
1008 +unsigned long long read_be64(in)
1009 +    unsigned char *in;
1010 +{
1011 +    unsigned long long result = 0;
1012 +
1013 +    result |= (unsigned long long)in[0] << 56;
1014 +    result |= (unsigned long long)in[1] << 48;
1015 +    result |= (unsigned long long)in[2] << 40;
1016 +    result |= (unsigned long long)in[3] << 32;
1017 +    result |= (unsigned long long)in[4] << 24;
1018 +    result |= (unsigned long long)in[5] << 16;
1019 +    result |= (unsigned long long)in[6] << 8;
1020 +    result |= (unsigned long long)in[7];
1021 +    
1022 +    return result;
1023 +}
1024 +
1025 +/* Write a 64-bit quantity out into memory in LITTLE ENDIAN order */
1026 +void write_le64(in, out)
1027 +    unsigned long long in;
1028 +    unsigned char *out;
1029 +{
1030 +    out[0] = in & 0xFF;
1031 +    out[1] = (in >> 8) & 0xFF;
1032 +    out[2] = (in >> 16) & 0xFF;
1033 +    out[3] = (in >> 24) & 0xFF;
1034 +    out[4] = (in >> 32) & 0xFF;
1035 +    out[5] = (in >> 40) & 0xFF;
1036 +    out[6] = (in >> 48) & 0xFF;
1037 +    out[7] = (in >> 56) & 0xFF;
1038 +}
1039 +
1040 +/* Read in a 64-bit LITTLE ENDIAN quantity */
1041 +unsigned long long read_le64(in)
1042 +    unsigned char *in;
1043 +{
1044 +    unsigned long long result = 0;
1045 +
1046 +    result |= (unsigned long long)in[0];
1047 +    result |= (unsigned long long)in[1] << 8;
1048 +    result |= (unsigned long long)in[2] << 16;
1049 +    result |= (unsigned long long)in[3] << 24;
1050 +    result |= (unsigned long long)in[4] << 32;
1051 +    result |= (unsigned long long)in[5] << 40;
1052 +    result |= (unsigned long long)in[6] << 48;
1053 +    result |= (unsigned long long)in[7] << 56;
1054 +    
1055 +    return result;
1056 +}
1057 +
1058 +/* Write a 48-bit quantity out into memory in LITTLE ENDIAN order */
1059 +void write_le48(in, out)
1060 +    unsigned long long in;
1061 +    unsigned char *out;
1062 +{
1063 +    out[0] = in & 0xFF;
1064 +    out[1] = (in >> 8) & 0xFF;
1065 +    out[2] = (in >> 16) & 0xFF;
1066 +    out[3] = (in >> 24) & 0xFF;
1067 +    out[4] = (in >> 32) & 0xFF;
1068 +    out[5] = (in >> 40) & 0xFF;
1069 +}
1070 +
1071 +/* Read in a 48-bit LITTLE ENDIAN quantity */
1072 +unsigned long long read_le48(in)
1073 +    unsigned char *in;
1074 +{
1075 +    unsigned long long result = 0;
1076 +
1077 +    result |= (unsigned long long)in[0];
1078 +    result |= (unsigned long long)in[1] << 8;
1079 +    result |= (unsigned long long)in[2] << 16;
1080 +    result |= (unsigned long long)in[3] << 24;
1081 +    result |= (unsigned long long)in[4] << 32;
1082 +    result |= (unsigned long long)in[5] << 40;
1083 +    
1084 +    return result;
1085 +}
1086 +
1087 +/* Write a 32-bit quantity out into memory in BIG ENDIAN order */
1088 +void write_be32(in, out)
1089 +    unsigned long in;
1090 +    unsigned char *out;
1091 +{
1092 +    out[0] = (in >> 24) & 0xFF;
1093 +    out[1] = (in >> 16) & 0xFF;
1094 +    out[2] = (in >> 8) & 0xFF;
1095 +    out[3] = in & 0xFF;
1096 +}
1097 +
1098 +/* Read in a 32-bit BIG ENDIAN quantity */
1099 +unsigned long read_be32(in)
1100 +    unsigned char *in;
1101 +{
1102 +    unsigned long result = 0;
1103 +
1104 +    result |= (unsigned long)in[0] << 24;
1105 +    result |= (unsigned long)in[1] << 16;
1106 +    result |= (unsigned long)in[2] << 8;
1107 +    result |= (unsigned long)in[3];
1108 +    
1109 +    return result;
1110 +}
1111 +
1112 +/* Write a 32-bit quantity out into memory in LITTLE ENDIAN order */
1113 +void write_le32(in, out)
1114 +    unsigned long in;
1115 +    unsigned char *out;
1116 +{
1117 +    out[0] = in & 0xFF;
1118 +    out[1] = (in >> 8) & 0xFF;
1119 +    out[2] = (in >> 16) & 0xFF;
1120 +    out[3] = (in >> 24) & 0xFF;
1121 +}
1122 +
1123 +/* Read in a 32-bit LITTLE ENDIAN quantity */
1124 +unsigned long read_le32(in)
1125 +    unsigned char *in;
1126 +{
1127 +    unsigned long result = 0;
1128 +
1129 +    result |= (unsigned long)in[0];
1130 +    result |= (unsigned long)in[1] << 8;
1131 +    result |= (unsigned long)in[2] << 16;
1132 +    result |= (unsigned long)in[3] << 24;
1133 +    
1134 +    return result;
1135 +}
1136 +
1137 +/* Write a 16-bit quantity out into memory in BIG ENDIAN order */
1138 +void write_be16(in, out)
1139 +    unsigned short in;
1140 +    unsigned char *out;
1141 +{
1142 +    out[0] = (in >> 8) & 0xFF;
1143 +    out[1] = in & 0xFF;
1144 +}
1145 +    
1146 +/* Read in a 16-bit BIG ENDIAN quantity */
1147 +unsigned short read_be16(in)
1148 +    unsigned char *in;
1149 +{
1150 +    unsigned short result = 0;
1151 +    
1152 +    result |= (unsigned short)in[0] << 8;
1153 +    result |= (unsigned short)in[1];
1154 +    return result;
1155 +}
1156 +
1157 +/* Write a 16-bit quantity out into memory in LITTLE ENDIAN order */
1158 +void write_le16(in, out)
1159 +    unsigned short in;
1160 +    unsigned char *out;
1161 +{
1162 +    out[0] = in & 0xFF;
1163 +    out[1] = in & 0xFF >> 8;
1164 +}
1165 +    
1166 +/* Read in a 16-bit LITTLE ENDIAN quantity */
1167 +unsigned short read_le16(in)
1168 +    unsigned char *in;
1169 +{
1170 +    unsigned short result = 0;
1171 +    
1172 +    result |= (unsigned short)in[0];
1173 +    result |= (unsigned short)in[1] << 8;
1174 +    return result;
1175 +}
1176 +
1177 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/endian.h cdrtools-2.0+a30.pre1/mkisofs.steve/endian.h
1178 --- cdrtools-2.0+a30.pre1/mkisofs/endian.h      1970-01-01 01:00:00.000000000 +0100
1179 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/endian.h        2004-06-16 19:24:36.000000000 +0100
1180 @@ -0,0 +1,17 @@
1181 +void                  write_be64  __PR((unsigned long long in, unsigned char *out));
1182 +unsigned long long    read_be64   __PR((unsigned char *in));
1183 +void                  write_le64  __PR((unsigned long long in, unsigned char *out));
1184 +unsigned long long    read_le64   __PR((unsigned char *in));
1185 +
1186 +void                  write_le48  __PR((unsigned long long in, unsigned char *out));
1187 +unsigned long long    read_le48   __PR((unsigned char *in));
1188 +
1189 +void                  write_be32  __PR((unsigned long in, unsigned char *out));
1190 +unsigned long         read_be32   __PR((unsigned char *in));
1191 +void                  write_le32  __PR((unsigned long in, unsigned char *out));
1192 +unsigned long         read_le32   __PR((unsigned char *in));
1193 +
1194 +void                  write_be16  __PR((unsigned short in, unsigned char *out));
1195 +unsigned short        read_be16   __PR((unsigned char *in));
1196 +void                  write_le16  __PR((unsigned short in, unsigned char *out));
1197 +unsigned short        read_le16   __PR((unsigned char *in));
1198 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/joliet.c cdrtools-2.0+a30.pre1/mkisofs.steve/joliet.c
1199 --- cdrtools-2.0+a30.pre1/mkisofs/joliet.c      2004-06-16 17:48:45.000000000 +0100
1200 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/joliet.c        2004-06-16 19:24:37.000000000 +0100
1201 @@ -989,6 +989,7 @@
1202                         dir_index, dpnt->de_name);
1203  #endif
1204         }
1205 +       jtwrite(directory_buffer, total_size, 1, 0, FALSE);
1206         xfwrite(directory_buffer, total_size, 1, outfile, 0, FALSE);
1207         last_extent_written += total_size >> 11;
1208         free(directory_buffer);
1209 @@ -1393,9 +1394,12 @@
1210         FILE    *outfile;
1211  {
1212         /* Next we write the path tables */
1213 +       jtwrite(jpath_table_l, jpath_blocks << 11, 1, 0, FALSE);
1214         xfwrite(jpath_table_l, jpath_blocks << 11, 1, outfile, 0, FALSE);
1215 +       last_extent_written += jpath_blocks;
1216 +       jtwrite(jpath_table_m, jpath_blocks << 11, 1, 0, FALSE);
1217         xfwrite(jpath_table_m, jpath_blocks << 11, 1, outfile, 0, FALSE);
1218 -       last_extent_written += 2 * jpath_blocks;
1219 +       last_extent_written += jpath_blocks;
1220         free(jpath_table_l);
1221         free(jpath_table_m);
1222         jpath_table_l = NULL;
1223 @@ -1448,6 +1452,7 @@
1224         /* Next we write out the boot volume descriptor for the disc */
1225         jvol_desc = vol_desc;
1226         get_joliet_vol_desc(&jvol_desc);
1227 +       jtwrite(&jvol_desc, SECTOR_SIZE, 1, 0, FALSE);
1228         xfwrite(&jvol_desc, SECTOR_SIZE, 1, outfile, 0, FALSE);
1229         last_extent_written++;
1230         return (0);
1231 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/jte.c cdrtools-2.0+a30.pre1/mkisofs.steve/jte.c
1232 --- cdrtools-2.0+a30.pre1/mkisofs/jte.c 1970-01-01 01:00:00.000000000 +0100
1233 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/jte.c   2004-06-26 00:09:46.000000000 +0100
1234 @@ -0,0 +1,790 @@
1235 +#include <mconfig.h>
1236 +#include "mkisofs.h"
1237 +#include <timedefs.h>
1238 +#include <fctldefs.h>
1239 +#include <zlib.h>
1240 +#include <regex.h>
1241 +#ifdef SORTING
1242 +#include "match.h"
1243 +#endif /* SORTING */
1244 +#include <errno.h>
1245 +#include <schily.h>
1246 +#ifdef DVD_VIDEO
1247 +#include "dvd_reader.h"
1248 +#include "dvd_file.h"
1249 +#include "ifo_read.h"
1250 +#include "md5.h"
1251 +#include "endian.h"
1252 +#endif
1253 +#ifdef APPLE_HYB
1254 +#include <ctype.h>
1255 +#endif
1256 +
1257 +#ifdef VMS
1258 +#include "vms.h"
1259 +#endif
1260 +
1261 +/* Different types used in building our state list below */
1262 +#define JTET_FILE_MATCH 1
1263 +#define JTET_NOMATCH    2
1264 +
1265 +#define JTE_VER_MAJOR     0x0001
1266 +#define JTE_VER_MINOR     0x0004
1267 +#define JTE_NAME          "JTE"
1268 +#define JTE_COMMENT       "JTE at http://www.einval.com/~steve/software/JTE/ ; jigdo at http://atterer.net/jigdo/"
1269 +
1270 +#define JIGDO_TEMPLATE_VERSION "1.1"
1271 +
1272 +/* Simple list to hold the results of -jigdo-exclude command line
1273 +   options. Seems easiest to do this using regexps. We use 4 copies of
1274 +   each to allow us to emulate glob-style matching:
1275 +
1276 +   ^PATTERN$
1277 +   ^PATTERN/
1278 +   /PATTERN$
1279 +   /PATTERN/
1280 +
1281 +   We convert the patterns from the command-line into (simple) regular
1282 +   expressions (x4), then compile those regular expressions and store
1283 +   them raw here for speed.
1284 +*/
1285 +struct exclude_regex
1286 +{
1287 +    regex_t match_pattern[4];
1288 +    char *exclude_rule;
1289 +    struct exclude_regex *next;
1290 +};
1291 +
1292 +struct path_mapping
1293 +{
1294 +    char *from;
1295 +    char *to;
1296 +    struct path_mapping *next;
1297 +};
1298 +
1299 +FILE   *jtjigdo = NULL;
1300 +FILE   *jttemplate = NULL;
1301 +char    *jjigdo_out = NULL; /* Output name for jigdo .jigdo file; NULL means don't do it */
1302 +char    *jtemplate_out = NULL; /* Output name for jigdo template file; NULL means don't do it */
1303 +int      jte_min_size = 8192; /* 8KB seems a reasonable minimum */
1304 +struct  exclude_regex *exclude_list = NULL;
1305 +struct  path_mapping  *map_list = NULL;
1306 +unsigned long long template_size = 0;
1307 +unsigned long long image_size = 0;
1308 +
1309 +static struct mk_MD5Context iso_context;
1310 +static struct mk_MD5Context template_context;
1311 +
1312 +typedef struct _file_entry
1313 +{
1314 +    unsigned char md5[16];
1315 +    off_t file_length;
1316 +    char *filename;
1317 +} file_entry_t;
1318 +
1319 +typedef struct _unmatched_entry
1320 +{
1321 +    off_t uncompressed_length;
1322 +} unmatched_entry_t;    
1323 +
1324 +typedef struct _entry
1325 +{
1326 +    int entry_type; /* JTET_TYPE as above */
1327 +    struct _entry *next;
1328 +    union
1329 +    {
1330 +        file_entry_t      file;
1331 +        unmatched_entry_t chunk;
1332 +    } data;
1333 +} entry_t;
1334 +
1335 +typedef struct _jigdo_file_entry
1336 +{
1337 +    unsigned char type;
1338 +    unsigned char fileLen[6];
1339 +    unsigned char fileRsync[8];
1340 +    unsigned char fileMD5[16];
1341 +} jigdo_file_entry_t;
1342 +
1343 +typedef struct _jigdo_chunk_entry
1344 +{
1345 +    unsigned char type;
1346 +    unsigned char skipLen[6];
1347 +} jigdo_chunk_entry_t;
1348 +
1349 +typedef struct _jigdo_image_entry
1350 +{
1351 +    unsigned char type;
1352 +    unsigned char imageLen[6];
1353 +    unsigned char imageMD5[16];
1354 +    unsigned char blockLen[4];
1355 +} jigdo_image_entry_t;
1356 +
1357 +entry_t *entry_list = NULL;
1358 +entry_t *last_entry = NULL;
1359 +FILE    *t_file = NULL;
1360 +FILE    *j_file = NULL;
1361 +int      num_matches = 0;
1362 +int      num_chunks = 0;
1363 +
1364 +/* Convert a glob-style pattern to a regexp */
1365 +static void convert_pattern(char *converted, char *prefix, char *in, char *suffix)
1366 +{
1367 +    char *p = in;
1368 +    char *out = converted;
1369 +
1370 +    out += sprintf(out, prefix);    
1371 +    while (*p)
1372 +    {
1373 +        switch (*p)
1374 +        {
1375 +            case '*':
1376 +                out += sprintf(out, ".*");
1377 +                break;
1378 +            case '?':
1379 +                out += sprintf(out, ".");
1380 +                break;
1381 +            case '.':
1382 +            case '\\':
1383 +            case '^':
1384 +            case '$':
1385 +                out += sprintf(out, "\\");
1386 +                out += sprintf(out, "%c", *p);
1387 +                break;
1388 +            default:
1389 +                out += sprintf(out, "%c", *p);
1390 +                break;
1391 +        }
1392 +        p++;
1393 +    }
1394 +    out += sprintf(out, suffix);
1395 +}
1396 +
1397 +/* Build the list of exclusion regexps */
1398 +extern int jte_add_exclude(char *pattern)
1399 +{
1400 +    int size = 3 + (2 * strlen(pattern)); /* Worst case */
1401 +    char *conversion = NULL;
1402 +    struct exclude_regex *new = NULL;
1403 +    
1404 +    conversion = malloc(size);
1405 +    if (!conversion)
1406 +        return ENOMEM;
1407 +
1408 +    new = malloc(sizeof *new);
1409 +    if (!new)
1410 +        return ENOMEM;    
1411 +    
1412 +    memset(conversion, 0, size);
1413 +    convert_pattern(conversion, "^", pattern, "/");
1414 +    regcomp(&new->match_pattern[0], conversion, REG_NEWLINE);
1415 +
1416 +    memset(conversion, 0, size);
1417 +    convert_pattern(conversion, "^", pattern, "$");
1418 +    regcomp(&new->match_pattern[1], conversion, REG_NEWLINE);
1419 +
1420 +    memset(conversion, 0, size);
1421 +    convert_pattern(conversion, "/", pattern, "/");
1422 +    regcomp(&new->match_pattern[2], conversion, REG_NEWLINE);
1423 +
1424 +    memset(conversion, 0, size);
1425 +    convert_pattern(conversion, "/", pattern, "$");
1426 +    regcomp(&new->match_pattern[3], conversion, REG_NEWLINE);
1427 +
1428 +    new->exclude_rule = pattern;
1429 +    free(conversion);
1430 +
1431 +    /* Order on the exclude list doesn't matter! */
1432 +    if (NULL != exclude_list)
1433 +        new->next = exclude_list;
1434 +
1435 +    exclude_list = new;
1436 +    return 0;
1437 +}
1438 +
1439 +/* Check if the file should be excluded because of a filename match. 1
1440 +   means exclude, 0 means not */
1441 +static int check_exclude_by_name(char *filename, char **matched)
1442 +{
1443 +    struct exclude_regex *ptr = exclude_list;
1444 +    regmatch_t pmatch[1];
1445 +    int i = 0;
1446 +
1447 +    while (ptr)
1448 +    {
1449 +        for (i = 0; i < 4; i++)
1450 +        {
1451 +            if (!regexec(&ptr->match_pattern[i], filename, 1, pmatch, 0))
1452 +            {
1453 +                *matched = ptr->exclude_rule;
1454 +                return 1;
1455 +            }
1456 +        }
1457 +        ptr = ptr->next;
1458 +    }
1459 +    
1460 +    /* Not matched, so return 0 */
1461 +    return 0;
1462 +}
1463 +
1464 +/* Should we list a file separately in the jigdo output, or should we
1465 +   just dump it into the template file as binary data? Two common
1466 +   cases to look for here:
1467 +
1468 +   1. Small files are better simply folded in, as they take less space that way.
1469 +
1470 +   2. Files in /doc (for example) may change in the archive all the
1471 +      time and it's better to not have to fetch snapshot copies if we
1472 +      can avoid it.      
1473 +*/
1474 +extern int list_file_in_jigdo(char *filename, off_t size)
1475 +{
1476 +    char *matched_rule;
1477 +    
1478 +    /* Cheaper to check file size first */
1479 +    if (size < jte_min_size)
1480 +    {
1481 +        if (verbose > 0)
1482 +            fprintf(stderr, "Jigdo-ignoring file %s; it's too small\n", filename);
1483 +        return 0;
1484 +    }
1485 +    
1486 +    /* Now check the excluded list by name */
1487 +    if (check_exclude_by_name(filename, &matched_rule))
1488 +    {
1489 +        if (verbose > 0)
1490 +            fprintf(stderr, "Jigdo-ignoring file %s; it's covered in the exclude list by \"%s\"\n", filename, matched_rule);
1491 +        return 0;
1492 +    }
1493 +    
1494 +    /* else */
1495 +    return 1;
1496 +}
1497 +
1498 +/* Add a mapping of pathnames (e.g. Debian=/mirror/debian). We should
1499 +   be passed TO=FROM here */
1500 +extern int jte_add_mapping(char *arg)
1501 +{
1502 +    int error = 0;
1503 +    struct path_mapping *new = NULL;
1504 +    struct path_mapping *entry = NULL;
1505 +    char *p = arg;
1506 +    char *from = NULL;
1507 +    char *to = NULL;
1508 +
1509 +    /* Find the "=" in the string passed. Set it to NULL and we can
1510 +       use the string in-place */
1511 +    while (*p)
1512 +    {
1513 +        if ('=' == *p)
1514 +        {
1515 +            *p = 0;
1516 +            p++;
1517 +            to = arg;
1518 +            from = p;
1519 +        }
1520 +        p++;
1521 +    }
1522 +    if (!from || !strlen(from) || !to || !strlen(to))
1523 +        return EINVAL;
1524 +    
1525 +    new = malloc(sizeof(*new));
1526 +    if (!new)
1527 +        return ENOMEM;
1528 +    
1529 +    new->from = from;
1530 +    new->to = to;
1531 +    new->next = NULL;
1532 +
1533 +    if (verbose > 0)
1534 +        fprintf(stderr, "Adding mapping from %s to %s for the jigdo file\n", from, to);
1535 +    if (!map_list)
1536 +        map_list = new;
1537 +    else
1538 +    {
1539 +        /* Order is important; add to the end of the list */
1540 +        entry = map_list;
1541 +        while (NULL != entry->next)
1542 +            entry = entry->next;
1543 +        entry->next = new;
1544 +    }
1545 +    return 0;
1546 +}
1547 +
1548 +/* Check if the filename should be remapped; if so, map it otherwise
1549 +   return the original name. */
1550 +static char *remap_filename(char *filename)
1551 +{
1552 +    char *new_name = filename;
1553 +    struct path_mapping *entry = map_list;
1554 +    
1555 +    while (entry)
1556 +    {
1557 +        if (!strncmp(filename, entry->from, strlen(entry->from)))
1558 +        {
1559 +            new_name = calloc(1, 2 + strlen(filename) + strlen(entry->to) - strlen(entry->from));
1560 +            if (!new_name)
1561 +            {
1562 +                fprintf(stderr, "Failed to malloc new filename; abort!\n");
1563 +                exit(1);
1564 +            }
1565 +            sprintf(new_name, "%s:%s", entry->to, &filename[strlen(entry->from)]);
1566 +            return new_name;
1567 +        }
1568 +        entry = entry->next;
1569 +    }
1570 +
1571 +    /* No mapping in effect */
1572 +    return strdup(filename);
1573 +}    
1574 +
1575 +static size_t template_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
1576 +{
1577 +    mk_MD5Update(&template_context, ptr, size * nmemb);
1578 +    template_size += (unsigned long long)size * nmemb;
1579 +    return fwrite(ptr, size, nmemb, stream);
1580 +}
1581 +
1582 +static void write_template_header()
1583 +{
1584 +    char buf[2048];
1585 +    int i = 0;
1586 +    char *p = buf;
1587 +
1588 +    memset(buf, 0, sizeof(buf));
1589 +
1590 +    mk_MD5Init(&template_context);
1591 +    i += sprintf(p, "JigsawDownload template %s %s/%d.%d \r\n",
1592 +                 JIGDO_TEMPLATE_VERSION, JTE_NAME, JTE_VER_MAJOR, JTE_VER_MINOR);
1593 +    p = &buf[i];
1594 +
1595 +    i += sprintf(p, "%s \r\n", JTE_COMMENT);
1596 +    p = &buf[i];
1597 +
1598 +    i += sprintf(p, "\r\n");
1599 +    template_fwrite(buf, i, 1, t_file);
1600 +}
1601 +
1602 +/* Initialise state and start the jigdo template file */
1603 +void write_jt_header(FILE *template_file, FILE *jigdo_file)
1604 +{
1605 +    t_file = template_file;
1606 +    j_file = jigdo_file;
1607 +
1608 +    /* Start MD5 work for the image */
1609 +    mk_MD5Init(&iso_context);
1610 +
1611 +    /* Start the template file */
1612 +    write_template_header();
1613 +}
1614 +
1615 +static void flush_compressed_chunk(void *buffer, off_t size)
1616 +{
1617 +    z_stream c_stream; /* compression stream */
1618 +    unsigned char comp_size_out[6];
1619 +    unsigned char uncomp_size_out[6];
1620 +    off_t compressed_size_out = 0;
1621 +    int err = 0;
1622 +    unsigned char *comp_buf = NULL;
1623 +
1624 +    c_stream.zalloc = NULL;
1625 +    c_stream.zfree = NULL;
1626 +    c_stream.opaque = NULL;
1627 +
1628 +    err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
1629 +    comp_buf = malloc(2 * size); /* Worst case */
1630 +    c_stream.next_out = comp_buf;
1631 +    c_stream.avail_out = 2 * size;
1632 +    c_stream.next_in = buffer;
1633 +    c_stream.avail_in = size;
1634 +    
1635 +    err = deflate(&c_stream, Z_NO_FLUSH);
1636 +    err = deflate(&c_stream, Z_FINISH);
1637 +    
1638 +    compressed_size_out = c_stream.total_out + 16;
1639 +    err = deflateEnd(&c_stream);
1640 +
1641 +    template_fwrite("DATA", 4, 1, t_file);
1642 +
1643 +    write_le48(compressed_size_out, &comp_size_out[0]);
1644 +    template_fwrite(comp_size_out, sizeof(comp_size_out), 1, t_file);
1645 +
1646 +    write_le48(size, &uncomp_size_out[0]);
1647 +    template_fwrite(uncomp_size_out, sizeof(uncomp_size_out), 1, t_file);
1648 +    
1649 +    template_fwrite(comp_buf, c_stream.total_out, 1, t_file);
1650 +    free(comp_buf);
1651 +}
1652 +
1653 +static void write_compressed_chunk(unsigned char *buffer, size_t size)
1654 +{
1655 +    static unsigned char uncomp_buf[1024 * 1024];
1656 +    static size_t uncomp_buf_used = 0;
1657 +
1658 +    if ((uncomp_buf_used + size) > sizeof(uncomp_buf))
1659 +    {
1660 +        flush_compressed_chunk(uncomp_buf, uncomp_buf_used);
1661 +        uncomp_buf_used = 0;
1662 +    }
1663 +
1664 +    if (!size) /* Signal a flush before we start writing the DESC entry */
1665 +    {
1666 +        flush_compressed_chunk(uncomp_buf, uncomp_buf_used);
1667 +        return;
1668 +    }
1669 +    
1670 +    if (!uncomp_buf_used)
1671 +        memset(uncomp_buf, 0, sizeof(uncomp_buf));
1672 +
1673 +    while (size > sizeof(uncomp_buf))
1674 +    {
1675 +        flush_compressed_chunk(buffer, sizeof(uncomp_buf));
1676 +        buffer += sizeof(uncomp_buf);
1677 +        size -= sizeof(uncomp_buf);
1678 +    }
1679 +    memcpy(&uncomp_buf[uncomp_buf_used], buffer, size);
1680 +    uncomp_buf_used += size;
1681 +}
1682 +
1683 +static void write_template_desc_entries(off_t image_len, char *image_md5)
1684 +{
1685 +    entry_t *entry = entry_list;
1686 +    off_t desc_len = 0;
1687 +    unsigned char out_len[6];
1688 +    jigdo_image_entry_t jimage;
1689 +
1690 +    desc_len = 16 /* DESC + length twice */
1691 +        + (sizeof(jigdo_file_entry_t) * num_matches)
1692 +        + (sizeof(jigdo_chunk_entry_t) * num_chunks)
1693 +        + sizeof(jigdo_image_entry_t);
1694 +
1695 +    write_le48(desc_len, &out_len[0]);
1696 +    write_compressed_chunk(NULL, 0);
1697 +    template_fwrite("DESC", 4, 1, t_file);
1698 +    template_fwrite(out_len, sizeof(out_len), 1, t_file);
1699 +    
1700 +    while (entry)
1701 +    {
1702 +        switch (entry->entry_type)
1703 +        {
1704 +            case JTET_FILE_MATCH:
1705 +            {
1706 +                jigdo_file_entry_t jfile;
1707 +                jfile.type = 6; /* Matched file */
1708 +                write_le48(entry->data.file.file_length, &jfile.fileLen[0]);
1709 +                memset(jfile.fileRsync, 0, sizeof(jfile.fileRsync)); /* Write a blank rsyncsum; we don't use it */
1710 +                memcpy(jfile.fileMD5, entry->data.file.md5, sizeof(jfile.fileMD5));
1711 +                template_fwrite(&jfile, sizeof(jfile), 1, t_file);
1712 +                break;
1713 +            }
1714 +            case JTET_NOMATCH:
1715 +            {
1716 +                jigdo_chunk_entry_t jchunk;
1717 +                jchunk.type = 2; /* Raw data */
1718 +                write_le48(entry->data.chunk.uncompressed_length, &jchunk.skipLen[0]);
1719 +                template_fwrite(&jchunk, sizeof(jchunk), 1, t_file);
1720 +                break;
1721 +            }
1722 +        }
1723 +        entry = entry->next;
1724 +    }
1725 +
1726 +    jimage.type = 5;
1727 +    write_le48(image_len, &jimage.imageLen[0]);
1728 +    memcpy(jimage.imageMD5, image_md5, sizeof(jimage.imageMD5));
1729 +    memset(jimage.blockLen, 0, sizeof(jimage.blockLen)); /* Might work... */
1730 +    template_fwrite(&jimage, sizeof(jimage), 1, t_file);    
1731 +    template_fwrite(out_len, sizeof(out_len), 1, t_file);
1732 +}
1733 +
1734 +static char *base64_dump(unsigned char *buf, size_t buf_size)
1735 +{
1736 +    const char *b64_enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
1737 +    int value = 0;
1738 +    unsigned int i;
1739 +    int bits = 0;
1740 +    static char output_buffer[2048];
1741 +    char *p = output_buffer;
1742 +
1743 +    memset(output_buffer, 0, sizeof(output_buffer));
1744 +    if (buf_size >= (sizeof(output_buffer) * 6/8))
1745 +    {
1746 +        fprintf(stderr, "base64_dump: Buffer too small!\n");
1747 +        exit(1);
1748 +    }
1749 +
1750 +    for (i = 0; i < buf_size ; i++)
1751 +    {
1752 +        value = (value << 8) | buf[i];
1753 +        bits += 2;
1754 +        p += sprintf(p, "%c", b64_enc[(value >> bits) & 63U]);
1755 +        if (bits >= 8) {
1756 +            bits -= 6;
1757 +            p += sprintf(p, "%c", b64_enc[(value >> bits) & 63U]);
1758 +        }
1759 +    }
1760 +    if (bits > 0)
1761 +    {
1762 +        value <<= 8 - bits;
1763 +        p += sprintf(p, "%c", b64_enc[(value >> bits) & 63U]);
1764 +    }
1765 +    return output_buffer;
1766 +}
1767 +
1768 +static char *hex_dump(unsigned char *buf, size_t buf_size)
1769 +{
1770 +    unsigned int i;
1771 +    static char output_buffer[2048];
1772 +    char *p = output_buffer;
1773 +
1774 +    memset(output_buffer, 0, sizeof(output_buffer));
1775 +    if (buf_size >= (sizeof(output_buffer) / 2))
1776 +    {
1777 +        fprintf(stderr, "hex_dump: Buffer too small!\n");
1778 +        exit(1);
1779 +    }
1780 +
1781 +    for (i = 0; i < buf_size ; i++)
1782 +        p += sprintf(p, "%2.2x", buf[i]);
1783 +
1784 +    return output_buffer;
1785 +}
1786 +
1787 +static char *file_base_name(char *path)
1788 +{
1789 +    char *endptr = path;
1790 +    char *ptr = path;
1791 +    
1792 +    while (*ptr != '\0')
1793 +    {
1794 +        if ('/' == *ptr)
1795 +            endptr = ++ptr;
1796 +        else
1797 +            ++ptr;
1798 +    }
1799 +    return endptr;
1800 +}
1801 +
1802 +/* Write the .jigdo file to match the .template we've just finished. */
1803 +static void write_jigdo_file(void)
1804 +{
1805 +    unsigned char template_md5sum[16];
1806 +    entry_t *entry = entry_list;
1807 +    struct path_mapping *map = map_list;
1808 +
1809 +    mk_MD5Final(&template_md5sum[0], &template_context);
1810 +
1811 +    fprintf(j_file, "# JigsawDownload\n");
1812 +    fprintf(j_file, "# See <http://atterer.net/jigdo/> for details about jigdo\n");
1813 +    fprintf(j_file, "# See <http://www.einval.com/~steve/software/CD/JTE/> for details about JTE\n\n");
1814 +    
1815 +    fprintf(j_file, "[Jigdo]\n");
1816 +    fprintf(j_file, "Version=%s\n", JIGDO_TEMPLATE_VERSION);
1817 +    fprintf(j_file, "Generator=%s/%d.%d\n\n", JTE_NAME, JTE_VER_MAJOR, JTE_VER_MINOR);
1818 +
1819 +    fprintf(j_file, "[Image]\n");
1820 +    fprintf(j_file, "Filename=%s\n", file_base_name(outfile));
1821 +    fprintf(j_file, "Template=http://localhost/%s\n", jtemplate_out);
1822 +    fprintf(j_file, "Template-MD5Sum=%s \n",
1823 +            base64_dump(&template_md5sum[0], sizeof(template_md5sum)));
1824 +    fprintf(j_file, "# Template Hex MD5sum %s\n",
1825 +            hex_dump(&template_md5sum[0], sizeof(template_md5sum)));
1826 +    fprintf(j_file, "# Template size %lld bytes\n", template_size);
1827 +    fprintf(j_file, "# Image size %lld bytes\n\n", image_size);
1828 +
1829 +    fprintf(j_file, "[Parts]\n");
1830 +    while (entry)
1831 +    {
1832 +        if (JTET_FILE_MATCH == entry->entry_type)
1833 +        {
1834 +            char *new_name = remap_filename(entry->data.file.filename);
1835 +            fprintf(j_file, "%s=%s\n",
1836 +                    base64_dump(&entry->data.file.md5[0], sizeof(entry->data.file.md5)),
1837 +                    new_name);
1838 +            free(new_name);
1839 +        }
1840 +        entry = entry->next;
1841 +    }
1842 +
1843 +    fprintf(j_file, "\n[Servers]\n");
1844 +    while (map)
1845 +    {
1846 +        fprintf(j_file, "%s=%s\n", map->to, map->from);
1847 +        map = map->next;
1848 +    }
1849 +
1850 +    fflush(j_file);
1851 +}
1852 +
1853 +/* Finish and flush state; for now:
1854 +   
1855 +   1. Dump the DESC blocks and the footer information in the jigdo template file
1856 +   2. Write the jigdo .jigdo file containing file pointers
1857 +*/
1858 +void write_jt_footer(void)
1859 +{
1860 +    unsigned char md5[16]; /* MD5SUM of the entire image */
1861 +
1862 +    /* Finish calculating the image's checksum */
1863 +    mk_MD5Final(&md5[0], &iso_context);
1864 +
1865 +    /* And caclulate the image size */
1866 +    image_size = (unsigned long long)SECTOR_SIZE * last_extent_written;
1867 +
1868 +    write_template_desc_entries(image_size, md5);
1869 +
1870 +    write_jigdo_file();
1871 +}
1872 +
1873 +static void add_unmatched_entry(int uncompressed_length)
1874 +{
1875 +    entry_t *new_entry = NULL;
1876 +
1877 +    /* Can we extend a previous non-match entry? */
1878 +    if (last_entry && (JTET_NOMATCH == last_entry->entry_type))
1879 +    {
1880 +        last_entry->data.chunk.uncompressed_length += uncompressed_length;
1881 +        return;
1882 +    }
1883 +
1884 +    new_entry = calloc(1, sizeof(entry_t));
1885 +    new_entry->entry_type = JTET_NOMATCH;
1886 +    new_entry->next = NULL;
1887 +    new_entry->data.chunk.uncompressed_length = uncompressed_length;
1888 +
1889 +    /* Add to the end of the list */
1890 +    if (NULL == last_entry)
1891 +    {
1892 +        last_entry = new_entry;
1893 +        entry_list = new_entry;
1894 +    }
1895 +    else
1896 +    {
1897 +        last_entry->next = new_entry;
1898 +        last_entry = new_entry;
1899 +    }
1900 +    num_chunks++;
1901 +}
1902 +
1903 +static void add_file_entry(char *filename, off_t size, unsigned char *md5)
1904 +{
1905 +    entry_t *new_entry = NULL;
1906 +
1907 +    new_entry = calloc(1, sizeof(entry_t));
1908 +    new_entry->entry_type = JTET_FILE_MATCH;
1909 +    new_entry->next = NULL;
1910 +    memcpy(new_entry->data.file.md5, md5, sizeof(new_entry->data.file.md5));
1911 +    new_entry->data.file.file_length = size;
1912 +    new_entry->data.file.filename = strdup(filename);
1913 +
1914 +    /* Add to the end of the list */
1915 +    if (NULL == last_entry)
1916 +    {
1917 +        last_entry = new_entry;
1918 +        entry_list = new_entry;
1919 +    }
1920 +    else
1921 +    {
1922 +        last_entry->next = new_entry;
1923 +        last_entry = new_entry;
1924 +    }
1925 +    num_matches++;
1926 +}    
1927 +
1928 +/* Cope with an unmatched block in the .iso file:
1929 +
1930 +   1. Write a compressed data chunk in the jigdo template file
1931 +   2. Add an entry in our list of unmatched chunks for later */
1932 +void jtwrite(buffer, size, count, submode, islast)
1933 +       void    *buffer;
1934 +       int     size;
1935 +       int     count;
1936 +       int     submode;
1937 +       BOOL    islast;
1938 +{
1939 +#ifdef JTWRITE_DEBUG
1940 +       if (count != 1 || (size % 2048) != 0)
1941 +               error("Count: %d, size: %d\n", count, size);
1942 +#endif
1943 +
1944 +    /* Update the global image checksum */
1945 +    mk_MD5Update(&iso_context, buffer, size);
1946 +
1947 +    /* Write a compressed version of the data to the template file,
1948 +       and add a reference on the state list so we can write that
1949 +       later. */
1950 +    write_compressed_chunk(buffer, size);
1951 +    add_unmatched_entry(size);
1952 +}
1953 +
1954 +/* Cope with an file entry in the .iso file:
1955 +
1956 +   1. Read the file for the image's md5 checksum
1957 +   2. Add an entry in our list of files to be written into the .jigdo later
1958 +*/
1959 +void write_jt_match_record(char *filename, int sector_size, off_t size)
1960 +{
1961 +    unsigned long long tmp_size = 0;
1962 +    struct mk_MD5Context file_context;
1963 +    unsigned char md5[16];
1964 +    char buf[32768];
1965 +    off_t remain = size;
1966 +       FILE            *infile = NULL;
1967 +       int     use;
1968 +
1969 +    memset(buf, 0, sizeof(buf));
1970 +    mk_MD5Init(&file_context);
1971 +
1972 +    if ((infile = fopen(filename, "rb")) == NULL) {
1973 +#ifdef USE_LIBSCHILY
1974 +               comerr("cannot open '%s'\n", filename);
1975 +#else
1976 +#ifndef        HAVE_STRERROR
1977 +               fprintf(stderr, "cannot open '%s': (%d)\n",
1978 +                               filename, errno);
1979 +#else
1980 +               fprintf(stderr, "cannot open '%s': %s\n",
1981 +                               filename, strerror(errno));
1982 +#endif
1983 +               exit(1);
1984 +#endif
1985 +       }
1986 +
1987 +    while (remain > 0)
1988 +    {
1989 +        use = remain;
1990 +        if (remain > sizeof(buf))
1991 +            use = sizeof(buf);
1992 +               if (fread(buf, 1, use, infile) == 0) {
1993 +#ifdef USE_LIBSCHILY
1994 +                       comerr("cannot read from '%s'\n", filename);
1995 +#else
1996 +                       fprintf(stderr, "cannot read from '%s'\n", filename);
1997 +                       exit(1);
1998 +#endif
1999 +               }
2000 +        mk_MD5Update(&iso_context, buf, use);
2001 +        mk_MD5Update(&file_context, buf, use);
2002 +        remain -= use;
2003 +    }
2004 +
2005 +    fclose(infile);
2006 +    
2007 +    mk_MD5Final(&md5[0], &file_context);
2008 +
2009 +    /* Update the image checksum with any necessary padding data */
2010 +    if (size % sector_size)
2011 +    {
2012 +        int pad_size = sector_size - (size % sector_size);
2013 +        memset(buf, 0, pad_size);
2014 +        mk_MD5Update(&iso_context, buf, pad_size);
2015 +    }
2016 +    
2017 +    add_file_entry(filename, size, &md5[0]);
2018 +    if (size % sector_size)
2019 +    {
2020 +        int pad_size = sector_size - (size % sector_size);
2021 +        write_compressed_chunk(buf, pad_size);
2022 +        add_unmatched_entry(pad_size);
2023 +    }        
2024 +}
2025 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/jte.h cdrtools-2.0+a30.pre1/mkisofs.steve/jte.h
2026 --- cdrtools-2.0+a30.pre1/mkisofs/jte.h 1970-01-01 01:00:00.000000000 +0100
2027 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/jte.h   2004-06-16 19:24:37.000000000 +0100
2028 @@ -0,0 +1,14 @@
2029 +extern char *jtemplate_out;
2030 +extern char *jjigdo_out;
2031 +extern FILE    *jthelper;
2032 +extern FILE *jtjigdo;
2033 +extern FILE *jttemplate;
2034 +extern int  jte_min_size;
2035 +
2036 +extern void write_jt_header(FILE *template_file, FILE *jigdo_file);
2037 +extern void write_jt_footer(void);
2038 +extern void jtwrite(void *buffer, int size, int count, int submode, BOOL islast);
2039 +extern void write_jt_match_record(char *filename, int sector_size, off_t size);
2040 +extern int  list_file_in_jigdo(char *filename, off_t size);
2041 +extern int  jte_add_exclude(char *pattern);
2042 +extern int  jte_add_mapping(char *arg);
2043 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/md5.c cdrtools-2.0+a30.pre1/mkisofs.steve/md5.c
2044 --- cdrtools-2.0+a30.pre1/mkisofs/md5.c 1970-01-01 01:00:00.000000000 +0100
2045 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/md5.c   2004-06-16 19:24:37.000000000 +0100
2046 @@ -0,0 +1,326 @@
2047 +/*
2048 + * This code implements the MD5 message-digest algorithm.
2049 + * The algorithm is due to Ron Rivest.  This code was
2050 + * written by Colin Plumb in 1993, no copyright is claimed.
2051 + * This code is in the public domain; do with it what you wish.
2052 + *
2053 + * Equivalent code is available from RSA Data Security, Inc.
2054 + * This code has been tested against that, and is equivalent,
2055 + * except that you don't need to include two pages of legalese
2056 + * with every copy.
2057 + *
2058 + * To compute the message digest of a chunk of bytes, declare an
2059 + * MD5Context structure, pass it to MD5Init, call MD5Update as
2060 + * needed on buffers full of bytes, and then call MD5Final, which
2061 + * will fill a supplied 16-byte array with the digest.
2062 + */
2063 +
2064 +/* This code was modified in 1997 by Jim Kingdon of Cyclic Software to
2065 +   not require an integer type which is exactly 32 bits.  This work
2066 +   draws on the changes for the same purpose by Tatu Ylonen
2067 +   <ylo@cs.hut.fi> as part of SSH, but since I didn't actually use
2068 +   that code, there is no copyright issue.  I hereby disclaim
2069 +   copyright in any changes I have made; this code remains in the
2070 +   public domain.  */
2071 +
2072 +/* Note regarding cvs_* namespace: this avoids potential conflicts
2073 +   with libraries such as some versions of Kerberos.  No particular
2074 +   need to worry about whether the system supplies an MD5 library, as
2075 +   this file is only about 3k of object code.  */
2076 +
2077 +/* Steve McIntyre, 2004/05/31: borrowed this code from the CVS
2078 +   library. s/cvs_/mk_/ across the source */
2079 +
2080 +#ifdef HAVE_CONFIG_H
2081 +#include "config.h"
2082 +#endif
2083 +
2084 +#include <string.h>    /* for memcpy() and memset() */
2085 +
2086 +#include "md5.h"
2087 +
2088 +/* Little-endian byte-swapping routines.  Note that these do not
2089 +   depend on the size of datatypes such as mk_uint32, nor do they require
2090 +   us to detect the endianness of the machine we are running on.  It
2091 +   is possible they should be macros for speed, but I would be
2092 +   surprised if they were a performance bottleneck for MD5.  */
2093 +
2094 +static mk_uint32
2095 +getu32 (addr)
2096 +     const unsigned char *addr;
2097 +{
2098 +       return (((((unsigned long)addr[3] << 8) | addr[2]) << 8)
2099 +               | addr[1]) << 8 | addr[0];
2100 +}
2101 +
2102 +static void
2103 +putu32 (data, addr)
2104 +     mk_uint32 data;
2105 +     unsigned char *addr;
2106 +{
2107 +       addr[0] = (unsigned char)data;
2108 +       addr[1] = (unsigned char)(data >> 8);
2109 +       addr[2] = (unsigned char)(data >> 16);
2110 +       addr[3] = (unsigned char)(data >> 24);
2111 +}
2112 +
2113 +/*
2114 + * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
2115 + * initialization constants.
2116 + */
2117 +void
2118 +mk_MD5Init (ctx)
2119 +     struct mk_MD5Context *ctx;
2120 +{
2121 +       ctx->buf[0] = 0x67452301;
2122 +       ctx->buf[1] = 0xefcdab89;
2123 +       ctx->buf[2] = 0x98badcfe;
2124 +       ctx->buf[3] = 0x10325476;
2125 +
2126 +       ctx->bits[0] = 0;
2127 +       ctx->bits[1] = 0;
2128 +}
2129 +
2130 +/*
2131 + * Update context to reflect the concatenation of another buffer full
2132 + * of bytes.
2133 + */
2134 +void
2135 +mk_MD5Update (ctx, buf, len)
2136 +     struct mk_MD5Context *ctx;
2137 +     unsigned char const *buf;
2138 +     unsigned len;
2139 +{
2140 +       mk_uint32 t;
2141 +
2142 +       /* Update bitcount */
2143 +
2144 +       t = ctx->bits[0];
2145 +       if ((ctx->bits[0] = (t + ((mk_uint32)len << 3)) & 0xffffffff) < t)
2146 +               ctx->bits[1]++; /* Carry from low to high */
2147 +       ctx->bits[1] += len >> 29;
2148 +
2149 +       t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
2150 +
2151 +       /* Handle any leading odd-sized chunks */
2152 +
2153 +       if ( t ) {
2154 +               unsigned char *p = ctx->in + t;
2155 +
2156 +               t = 64-t;
2157 +               if (len < t) {
2158 +                       memcpy(p, buf, len);
2159 +                       return;
2160 +               }
2161 +               memcpy(p, buf, t);
2162 +               mk_MD5Transform (ctx->buf, ctx->in);
2163 +               buf += t;
2164 +               len -= t;
2165 +       }
2166 +
2167 +       /* Process data in 64-byte chunks */
2168 +
2169 +       while (len >= 64) {
2170 +               memcpy(ctx->in, buf, 64);
2171 +               mk_MD5Transform (ctx->buf, ctx->in);
2172 +               buf += 64;
2173 +               len -= 64;
2174 +       }
2175 +
2176 +       /* Handle any remaining bytes of data. */
2177 +
2178 +       memcpy(ctx->in, buf, len);
2179 +}
2180 +
2181 +/*
2182 + * Final wrapup - pad to 64-byte boundary with the bit pattern 
2183 + * 1 0* (64-bit count of bits processed, MSB-first)
2184 + */
2185 +void
2186 +mk_MD5Final (digest, ctx)
2187 +     unsigned char digest[16];
2188 +     struct mk_MD5Context *ctx;
2189 +{
2190 +       unsigned count;
2191 +       unsigned char *p;
2192 +
2193 +       /* Compute number of bytes mod 64 */
2194 +       count = (ctx->bits[0] >> 3) & 0x3F;
2195 +
2196 +       /* Set the first char of padding to 0x80.  This is safe since there is
2197 +          always at least one byte free */
2198 +       p = ctx->in + count;
2199 +       *p++ = 0x80;
2200 +
2201 +       /* Bytes of padding needed to make 64 bytes */
2202 +       count = 64 - 1 - count;
2203 +
2204 +       /* Pad out to 56 mod 64 */
2205 +       if (count < 8) {
2206 +               /* Two lots of padding:  Pad the first block to 64 bytes */
2207 +               memset(p, 0, count);
2208 +               mk_MD5Transform (ctx->buf, ctx->in);
2209 +
2210 +               /* Now fill the next block with 56 bytes */
2211 +               memset(ctx->in, 0, 56);
2212 +       } else {
2213 +               /* Pad block to 56 bytes */
2214 +               memset(p, 0, count-8);
2215 +       }
2216 +
2217 +       /* Append length in bits and transform */
2218 +       putu32(ctx->bits[0], ctx->in + 56);
2219 +       putu32(ctx->bits[1], ctx->in + 60);
2220 +
2221 +       mk_MD5Transform (ctx->buf, ctx->in);
2222 +       putu32(ctx->buf[0], digest);
2223 +       putu32(ctx->buf[1], digest + 4);
2224 +       putu32(ctx->buf[2], digest + 8);
2225 +       putu32(ctx->buf[3], digest + 12);
2226 +       memset(ctx, 0, sizeof(ctx));    /* In case it's sensitive */
2227 +}
2228 +
2229 +#ifndef ASM_MD5
2230 +
2231 +/* The four core functions - F1 is optimized somewhat */
2232 +
2233 +/* #define F1(x, y, z) (x & y | ~x & z) */
2234 +#define F1(x, y, z) (z ^ (x & (y ^ z)))
2235 +#define F2(x, y, z) F1(z, x, y)
2236 +#define F3(x, y, z) (x ^ y ^ z)
2237 +#define F4(x, y, z) (y ^ (x | ~z))
2238 +
2239 +/* This is the central step in the MD5 algorithm. */
2240 +#define MD5STEP(f, w, x, y, z, data, s) \
2241 +       ( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
2242 +
2243 +/*
2244 + * The core of the MD5 algorithm, this alters an existing MD5 hash to
2245 + * reflect the addition of 16 longwords of new data.  MD5Update blocks
2246 + * the data and converts bytes into longwords for this routine.
2247 + */
2248 +void
2249 +mk_MD5Transform (buf, inraw)
2250 +     mk_uint32 buf[4];
2251 +     const unsigned char inraw[64];
2252 +{
2253 +       register mk_uint32 a, b, c, d;
2254 +       mk_uint32 in[16];
2255 +       int i;
2256 +
2257 +       for (i = 0; i < 16; ++i)
2258 +               in[i] = getu32 (inraw + 4 * i);
2259 +
2260 +       a = buf[0];
2261 +       b = buf[1];
2262 +       c = buf[2];
2263 +       d = buf[3];
2264 +
2265 +       MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
2266 +       MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
2267 +       MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
2268 +       MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
2269 +       MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
2270 +       MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
2271 +       MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
2272 +       MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
2273 +       MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
2274 +       MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
2275 +       MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
2276 +       MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
2277 +       MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
2278 +       MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
2279 +       MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
2280 +       MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
2281 +
2282 +       MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
2283 +       MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
2284 +       MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
2285 +       MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
2286 +       MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
2287 +       MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
2288 +       MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
2289 +       MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
2290 +       MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
2291 +       MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
2292 +       MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
2293 +       MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
2294 +       MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
2295 +       MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
2296 +       MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
2297 +       MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
2298 +
2299 +       MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
2300 +       MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
2301 +       MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
2302 +       MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
2303 +       MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
2304 +       MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
2305 +       MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
2306 +       MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
2307 +       MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
2308 +       MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
2309 +       MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
2310 +       MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
2311 +       MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
2312 +       MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
2313 +       MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
2314 +       MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
2315 +
2316 +       MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
2317 +       MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
2318 +       MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
2319 +       MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
2320 +       MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
2321 +       MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
2322 +       MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
2323 +       MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
2324 +       MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
2325 +       MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
2326 +       MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
2327 +       MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
2328 +       MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
2329 +       MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
2330 +       MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
2331 +       MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
2332 +
2333 +       buf[0] += a;
2334 +       buf[1] += b;
2335 +       buf[2] += c;
2336 +       buf[3] += d;
2337 +}
2338 +#endif
2339 +
2340 +#ifdef TEST
2341 +/* Simple test program.  Can use it to manually run the tests from
2342 +   RFC1321 for example.  */
2343 +#include <stdio.h>
2344 +
2345 +int
2346 +main (int argc, char **argv)
2347 +{
2348 +       struct mk_MD5Context context;
2349 +       unsigned char checksum[16];
2350 +       int i;
2351 +       int j;
2352 +
2353 +       if (argc < 2)
2354 +       {
2355 +               fprintf (stderr, "usage: %s string-to-hash\n", argv[0]);
2356 +               exit (1);
2357 +       }
2358 +       for (j = 1; j < argc; ++j)
2359 +       {
2360 +               printf ("MD5 (\"%s\") = ", argv[j]);
2361 +               mk_MD5Init (&context);
2362 +               mk_MD5Update (&context, argv[j], strlen (argv[j]));
2363 +               mk_MD5Final (checksum, &context);
2364 +               for (i = 0; i < 16; i++)
2365 +               {
2366 +                       printf ("%02x", (unsigned int) checksum[i]);
2367 +               }
2368 +               printf ("\n");
2369 +       }
2370 +       return 0;
2371 +}
2372 +#endif /* TEST */
2373 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/md5.h cdrtools-2.0+a30.pre1/mkisofs.steve/md5.h
2374 --- cdrtools-2.0+a30.pre1/mkisofs/md5.h 1970-01-01 01:00:00.000000000 +0100
2375 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/md5.h   2004-06-16 19:24:37.000000000 +0100
2376 @@ -0,0 +1,26 @@
2377 +/* See md5.c for explanation and copyright information.  */
2378 +
2379 +#ifndef MD5_H
2380 +#define MD5_H
2381 +
2382 +/* Unlike previous versions of this code, uint32 need not be exactly
2383 +   32 bits, merely 32 bits or more.  Choosing a data type which is 32
2384 +   bits instead of 64 is not important; speed is considerably more
2385 +   important.  ANSI guarantees that "unsigned long" will be big enough,
2386 +   and always using it seems to have few disadvantages.  */
2387 +typedef unsigned long mk_uint32;
2388 +
2389 +struct mk_MD5Context {
2390 +       mk_uint32 buf[4];
2391 +       mk_uint32 bits[2];
2392 +       unsigned char in[64];
2393 +};
2394 +
2395 +void mk_MD5Init (struct mk_MD5Context *context);
2396 +void mk_MD5Update (struct mk_MD5Context *context,
2397 +                          unsigned char const *buf, unsigned len);
2398 +void mk_MD5Final (unsigned char digest[16],
2399 +                         struct mk_MD5Context *context);
2400 +void mk_MD5Transform (mk_uint32 buf[4], const unsigned char in[64]);
2401 +
2402 +#endif /* !MD5_H */
2403 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/mkisofs.c cdrtools-2.0+a30.pre1/mkisofs.steve/mkisofs.c
2404 --- cdrtools-2.0+a30.pre1/mkisofs/mkisofs.c     2004-06-16 17:48:45.000000000 +0100
2405 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/mkisofs.c       2004-06-17 09:55:21.000000000 +0100
2406 @@ -100,7 +100,11 @@
2407  int    load_addr = 0;
2408  int    load_size = 0;
2409  int    boot_info_table = 0;
2410 +int use_alphaboot = 0;
2411  int    use_sparcboot = 0;
2412 +int use_hppaboot = 0;
2413 +int use_mipsboot = 0;
2414 +int use_mipselboot = 0;
2415  int    use_sunx86boot = 0;
2416  int    use_genboot = 0;
2417  int    use_RockRidge = 0;
2418 @@ -373,6 +377,26 @@
2419  #define        OPTION_SUNX86BOOT               1068
2420  #define        OPTION_SUNX86LABEL              1069
2421  
2422 +#ifdef JIGDO_TEMPLATE
2423 +#define OPTION_JTT_OUTPUT       1101
2424 +#define OPTION_JTJ_OUTPUT       1102
2425 +#define OPTION_JT_MIN_SIZE      1103
2426 +#define OPTION_JT_EXCLUDE       1104
2427 +#define OPTION_JT_PATH_MAP      1105
2428 +#endif
2429 +
2430 +#define        OPTION_BOOTALPHA            1200
2431 +
2432 +#define        OPTION_HPPA_CMDLINE     1210
2433 +#define OPTION_HPPA_KERNEL_32   1211
2434 +#define OPTION_HPPA_KERNEL_64   1212
2435 +#define OPTION_HPPA_BOOTLOADER  1213
2436 +#define OPTION_HPPA_RAMDISK     1214
2437 +
2438 +#define        OPTION_BOOTMIPS         1220
2439 +
2440 +#define        OPTION_BOOTMIPSEL       1230
2441 +
2442  #ifdef UDF
2443  #define        OPTION_UDF                      1500
2444  #endif
2445 @@ -584,6 +608,39 @@
2446         {{"sectype", required_argument, NULL, 's'},
2447         's', "TYPE", "Set output sector type to e.g. data/xa1/raw", ONE_DASH},
2448  
2449 +       {{"alpha-boot", required_argument, NULL, OPTION_BOOTALPHA},
2450 +       '\0', "FILE", "Set alpha boot image name (relative to image root)", ONE_DASH},
2451 +
2452 +       {{"hppa-cmdline", required_argument, NULL, OPTION_HPPA_CMDLINE},
2453 +       '\0', "CMDLINE", "Set hppa boot command line (relative to image root)", ONE_DASH},
2454 +       {{"hppa-kernel-32", required_argument, NULL, OPTION_HPPA_KERNEL_32},
2455 +       '\0', "FILE", "Set hppa 32-bit image name (relative to image root)", ONE_DASH},
2456 +       {{"hppa-kernel-64", required_argument, NULL, OPTION_HPPA_KERNEL_64},
2457 +       '\0', "FILE", "Set hppa 64-bit image name (relative to image root)", ONE_DASH},
2458 +       {{"hppa-bootloader", required_argument, NULL, OPTION_HPPA_BOOTLOADER},
2459 +       '\0', "FILE", "Set hppa boot loader file name (relative to image root)", ONE_DASH},
2460 +       {{"hppa-ramdisk", required_argument, NULL, OPTION_HPPA_RAMDISK},
2461 +       '\0', "FILE", "Set hppa ramdisk file name (relative to image root)", ONE_DASH},
2462 +
2463 +       {{"mips-boot", required_argument, NULL, OPTION_BOOTMIPS},
2464 +       '\0', "FILE", "Set mips boot image name (relative to image root)", ONE_DASH},
2465 +
2466 +       {{"mipsel-boot", required_argument, NULL, OPTION_BOOTMIPSEL},
2467 +       '\0', "FILE", "Set mipsel boot image name (relative to image root)", ONE_DASH},
2468 +
2469 +#ifdef JIGDO_TEMPLATE
2470 +    {{"jigdo-jigdo", required_argument, NULL, OPTION_JTJ_OUTPUT},
2471 +     '\0', "FILE", "Produce a jigdo .jigdo file as well as the .iso", ONE_DASH },
2472 +    {{"jigdo-template", required_argument, NULL, OPTION_JTT_OUTPUT},
2473 +     '\0', "FILE", "Produce a jigdo .template file as well as the .iso", ONE_DASH },
2474 +    {{"jigdo-min-file-size", required_argument, NULL, OPTION_JT_MIN_SIZE},
2475 +     '\0', "SIZE", "Minimum size for a file to be listed in the jigdo file", ONE_DASH },
2476 +    {{"jigdo-exclude", required_argument, NULL, OPTION_JT_EXCLUDE},
2477 +     '\0', "PATTERN", "Pattern(s) to exclude from the jigdo file", ONE_DASH },
2478 +    {{"jigdo-map", required_argument, NULL, OPTION_JT_PATH_MAP},
2479 +     '\0', "PATTERN1=PATTERN2", "Pattern(s) to map paths (e.g. Debian=/mirror/debian)", ONE_DASH },
2480 +#endif
2481 +
2482  #ifdef SORTING
2483         { {"sort", required_argument, NULL, OPTION_SORT},
2484         '\0', "FILE", "Sort file content locations according to rules in FILE", ONE_DASH },
2485 @@ -1348,6 +1405,41 @@
2486                 case OPTION_OUTPUT_CHARSET:
2487                         ocharset = optarg;
2488                         break;
2489 +#ifdef JIGDO_TEMPLATE
2490 +        case OPTION_JTT_OUTPUT:
2491 +            jtemplate_out = optarg;
2492 +            break;
2493 +        case OPTION_JTJ_OUTPUT:
2494 +            jjigdo_out = optarg;
2495 +            break;
2496 +        case OPTION_JT_MIN_SIZE:
2497 +            jte_min_size = atoi(optarg);
2498 +            break;
2499 +        case OPTION_JT_EXCLUDE:
2500 +            if (jte_add_exclude(optarg)) {
2501 +#ifdef USE_LIBSCHILY
2502 +                               comerrno(EX_BAD,
2503 +                         "Failed to build jigdo-exclude list\n");
2504 +#else
2505 +                               fprintf(stderr,
2506 +                        "Failed to build jigdo-exclude list\n");
2507 +                               exit(1);
2508 +#endif
2509 +                       }    
2510 +            break;
2511 +        case OPTION_JT_PATH_MAP:
2512 +            if (jte_add_mapping(optarg)) {
2513 +#ifdef USE_LIBSCHILY
2514 +                               comerrno(EX_BAD,
2515 +                         "Failed to build jigdo mapping list\n");
2516 +#else
2517 +                               fprintf(stderr,
2518 +                        "Failed to build jigdo mapping list\n");
2519 +                               exit(1);
2520 +#endif
2521 +                       }    
2522 +            break;
2523 +#endif /* JIGDO_TEMPLATE */
2524                 case OPTION_NOBAK:
2525                         all_files = 0;
2526                         break;
2527 @@ -1374,6 +1466,41 @@
2528                          */
2529                         new_boot_entry();
2530                         break;
2531 +               case OPTION_BOOTALPHA:
2532 +                       use_alphaboot++;
2533 +                       /* list of pathnames of boot images */
2534 +                       add_boot_alpha_filename(optarg);
2535 +                       break;
2536 +               case OPTION_HPPA_CMDLINE:
2537 +                       use_hppaboot++;
2538 +                       add_boot_hppa_cmdline(optarg);
2539 +                       break;
2540 +               case OPTION_HPPA_KERNEL_32:
2541 +                       use_hppaboot++;
2542 +                       add_boot_hppa_kernel_32(optarg);
2543 +                       break;
2544 +               case OPTION_HPPA_KERNEL_64:
2545 +                       use_hppaboot++;
2546 +                       add_boot_hppa_kernel_64(optarg);
2547 +                       break;
2548 +               case OPTION_HPPA_BOOTLOADER:
2549 +                       use_hppaboot++;
2550 +                       add_boot_hppa_bootloader(optarg);
2551 +                       break;
2552 +               case OPTION_HPPA_RAMDISK:
2553 +                       use_hppaboot++;
2554 +                       /* list of pathnames of boot images */
2555 +                       add_boot_hppa_ramdisk(optarg);
2556 +                       break;
2557 +               case OPTION_BOOTMIPS:
2558 +                       use_mipsboot++;
2559 +                       /* list of pathnames of boot images */
2560 +                       add_boot_mips_filename(optarg);
2561 +                       break;
2562 +               case OPTION_BOOTMIPSEL:
2563 +                       use_mipselboot++;
2564 +                       add_boot_mipsel_filename(optarg);
2565 +                       break;
2566                 case 'B':
2567                         if (use_sunx86boot)
2568                                 comerrno(EX_BAD,
2569 @@ -3156,6 +3283,27 @@
2570                         exit(1);
2571  #endif
2572                 }
2573 +        if (jtemplate_out || jjigdo_out) {
2574 +            if (!jtemplate_out || !jjigdo_out) {
2575 +#ifdef        USE_LIBSCHILY
2576 +                comerr("Bad options - need to specify all jigdo output names!\n");
2577 +#else
2578 +                fprintf(stderr, "Bad options - need to specify all jigdo output names!\n");
2579 +                exit(1);
2580 +#endif
2581 +            }
2582 +            jtjigdo = fopen(jjigdo_out, "wb");
2583 +            jttemplate = fopen(jtemplate_out, "wb");
2584 +            if (!jtjigdo || !jttemplate) {
2585 +#ifdef        USE_LIBSCHILY
2586 +                comerr("Unable to open jigdo template image file\n");
2587 +#else
2588 +                fprintf(stderr, "Unable to open jigdo template image file\n");
2589 +                exit(1);
2590 +#endif
2591 +            }
2592 +            write_jt_header(jttemplate, jtjigdo);
2593 +        }
2594         } else {
2595                 discimage = stdout;
2596  
2597 @@ -3188,6 +3336,14 @@
2598  #endif /* APPLE_HYB */
2599         if (use_sparcboot || use_sunx86boot)
2600                 outputlist_insert(&sunlabel_desc);
2601 +    if (use_alphaboot)
2602 +        outputlist_insert(&alphaboot_desc);
2603 +    if (use_hppaboot)
2604 +        outputlist_insert(&hppaboot_desc);
2605 +    if (use_mipsboot)
2606 +        outputlist_insert(&mipsboot_desc);
2607 +    if (use_mipselboot)
2608 +        outputlist_insert(&mipselboot_desc);
2609         if (use_genboot)
2610                 outputlist_insert(&genboot_desc);
2611         outputlist_insert(&startpad_desc);
2612 @@ -3411,6 +3567,14 @@
2613                                 last_extent, last_extent_written);
2614         }
2615  
2616 +    if (jttemplate)
2617 +    {
2618 +        write_jt_footer();
2619 +        fclose(jttemplate);
2620 +    }
2621 +    if (jtjigdo)
2622 +        fclose(jtjigdo);
2623 +    
2624         if (verbose > 0) {
2625  #ifdef HAVE_SBRK
2626                 fprintf(stderr, "Max brk space used %x\n",
2627 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/mkisofs.h cdrtools-2.0+a30.pre1/mkisofs.steve/mkisofs.h
2628 --- cdrtools-2.0+a30.pre1/mkisofs/mkisofs.h     2004-06-16 17:48:45.000000000 +0100
2629 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/mkisofs.h       2004-06-17 09:55:47.000000000 +0100
2630 @@ -34,6 +34,9 @@
2631  #include <utypes.h>
2632  #include <standard.h>
2633  #include <libport.h>
2634 +#ifdef JIGDO_TEMPLATE
2635 +#include "jte.h"
2636 +#endif
2637  
2638  #ifdef DVD_VIDEO
2639  #ifndef        UDF
2640 @@ -189,6 +192,10 @@
2641  extern struct output_fragment strfile_desc;
2642  extern struct output_fragment strdir_desc;
2643  extern struct output_fragment strpath_desc;
2644 +extern struct output_fragment alphaboot_desc;
2645 +extern struct output_fragment hppaboot_desc;
2646 +extern struct output_fragment mipsboot_desc;
2647 +extern struct output_fragment mipselboot_desc;
2648  
2649  #ifdef APPLE_HYB
2650  extern struct output_fragment hfs_desc;
2651 @@ -357,6 +364,7 @@
2652  extern int     split_SL_component;
2653  extern int     split_SL_field;
2654  extern char    *trans_tbl;
2655 +char           *outfile;
2656  
2657  #define        JMAX            64      /* maximum Joliet file name length (spec) */
2658  #define        JLONGMAX        103     /* out of spec Joliet file name length */
2659 @@ -454,6 +462,22 @@
2660  extern int make_sun_label __PR((void));
2661  extern int make_sunx86_label __PR((void));
2662  
2663 +/* boot-alpha.c */
2664 +extern int add_boot_alpha_filename __PR((char *filename));
2665 +
2666 +/* boot-hppa.c */
2667 +extern int add_boot_hppa_cmdline    __PR((char *cmdline));
2668 +extern int add_boot_hppa_kernel_32  __PR((char *filename));
2669 +extern int add_boot_hppa_kernel_64  __PR((char *filename));
2670 +extern int add_boot_hppa_bootloader __PR((char *filename));
2671 +extern int add_boot_hppa_ramdisk    __PR((char *filename));
2672 +
2673 +/* boot-mips.c */
2674 +extern int add_boot_mips_filename __PR((char *filename));
2675 +
2676 +/* boot-mipsel.c */
2677 +extern int add_boot_mipsel_filename  __PR((char *filename));
2678 +
2679  /* write.c */
2680  extern int get_731 __PR((char *));
2681  extern int get_732 __PR((char *));
2682 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/stream.c cdrtools-2.0+a30.pre1/mkisofs.steve/stream.c
2683 --- cdrtools-2.0+a30.pre1/mkisofs/stream.c      2004-03-04 22:56:57.000000000 +0000
2684 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/stream.c        2004-06-16 19:24:37.000000000 +0100
2685 @@ -157,6 +157,7 @@
2686                         break;
2687                 }
2688                 idx += count;
2689 +               jtwrite(buf, count, 1, 0, FALSE);
2690                 xfwrite(buf, count, 1, outfile, 0, FALSE);
2691         }
2692  
2693 @@ -164,15 +165,23 @@
2694         iso_blocks = ISO_BLOCKS(idx);
2695         memset(buf, 0, SECTOR_SIZE);
2696         if (SECTOR_SIZE * iso_blocks - idx)
2697 +    {
2698 +               jtwrite(buf, SECTOR_SIZE * iso_blocks - idx, 1, 0, FALSE);
2699                 xfwrite(buf, SECTOR_SIZE * iso_blocks - idx, 1, outfile, 0, FALSE);
2700 +    }
2701         /*
2702          * If we didn't fill the available area, pad to directory block
2703          */
2704         for (count = 0; count < (avail_extent - iso_blocks); count++)
2705 +    {
2706 +               jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2707                 xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE);
2708 -
2709 +    }
2710         for (count = 0; count < stream_pad; count++)
2711 +    {
2712 +               jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2713                 xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE);
2714 +    }
2715  
2716         last_extent_written += avail_extent + stream_pad;
2717         return (0);
2718 @@ -201,7 +210,9 @@
2719         set_723((char *)s_dir.volume_sequence_number, volume_sequence_number);
2720         s_dir.name_len[0] = 1;
2721         s_dir.name[0] = 0;
2722 +       jtwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, 0, FALSE);
2723         xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, outfile, 0, FALSE);
2724 +       jtwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, 0, FALSE);
2725         xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, outfile, 0, FALSE);
2726         memset(&s_dir, 0, sizeof (struct iso_directory_record));
2727         s_dir.length[0] = 34 + strlen(stream_filename);
2728 @@ -214,6 +225,8 @@
2729         set_723((char *)s_dir.volume_sequence_number, volume_sequence_number);
2730         s_dir.name_len[0] = strlen(stream_filename);
2731         memcpy(s_dir.name, stream_filename, s_dir.name_len[0]);
2732 +       jtwrite(&s_dir, offsetof(struct iso_directory_record, name[0])
2733 +               + s_dir.name_len[0], 1, 0, FALSE);
2734         xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0])
2735                 + s_dir.name_len[0], 1, outfile, 0, FALSE);
2736  
2737 @@ -222,6 +235,8 @@
2738          * with filename length stream_filename + round up for even lenght count
2739          */
2740         to_write = (s_dir.name_len[0] % 2) ? 0 : 1;
2741 +       jtwrite(buf, SECTOR_SIZE - ((3 * 34) + s_dir.name_len[0]) +
2742 +               to_write, 1, 0, FALSE);
2743         xfwrite(buf, SECTOR_SIZE - ((3 * 34) + s_dir.name_len[0]) +
2744                 to_write, 1, outfile, 0, FALSE);
2745         free(buf);
2746 @@ -236,7 +251,9 @@
2747  write_str_path(outfile)
2748         FILE    *outfile;
2749  {
2750 +       jtwrite(l_path, SECTOR_SIZE, 1, 0, FALSE);
2751         xfwrite(l_path, SECTOR_SIZE, 1, outfile, 0, FALSE);
2752 +       jtwrite(m_path, SECTOR_SIZE, 1, 0, FALSE);
2753         xfwrite(m_path, SECTOR_SIZE, 1, outfile, 0, FALSE);
2754         last_extent_written += 2;
2755         free(l_path);
2756 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/udf.c cdrtools-2.0+a30.pre1/mkisofs.steve/udf.c
2757 --- cdrtools-2.0+a30.pre1/mkisofs/udf.c 2004-06-16 17:48:45.000000000 +0100
2758 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/udf.c   2004-06-16 19:24:37.000000000 +0100
2759 @@ -1045,6 +1045,7 @@
2760                 1,      /* is_directory */
2761                 directory_link_count(dpnt),
2762                 (dpnt == root) ? 0 : dpnt->self->udf_file_entry_sector);
2763 +       jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2764         xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE);
2765         last_extent_written++;
2766  
2767 @@ -1062,6 +1063,7 @@
2768                 1,
2769                 parent->self->udf_file_entry_sector - lba_udf_partition_start,
2770                 (parent == root) ? 0 : parent->self->udf_file_entry_sector);
2771 +       jtwrite(buf, ident_size, 1, 0, FALSE);
2772         xfwrite(buf, ident_size, 1, outfile, 0, FALSE);
2773         size_in_bytes = ident_size;
2774  
2775 @@ -1107,6 +1109,7 @@
2776                         !!(de1->isorec.flags[0] & ISO_DIRECTORY),
2777                         de1->udf_file_entry_sector - lba_udf_partition_start,
2778                         de1->udf_file_entry_sector);
2779 +               jtwrite(buf, ident_size, 1, 0, FALSE);
2780                 xfwrite(buf, ident_size, 1, outfile, 0, FALSE);
2781                 size_in_bytes += ident_size;
2782         }
2783 @@ -1114,6 +1117,7 @@
2784         padded_size_in_bytes = PAD(size_in_bytes, SECTOR_SIZE);
2785         if (size_in_bytes < padded_size_in_bytes) {
2786                 memset(buf, 0, padded_size_in_bytes - size_in_bytes);
2787 +               jtwrite(buf, padded_size_in_bytes - size_in_bytes, 1, 0, FALSE);
2788                 xfwrite(buf, padded_size_in_bytes - size_in_bytes, 1, outfile, 0, FALSE);
2789         }
2790  
2791 @@ -1168,6 +1172,7 @@
2792                                         0,      /* is_directory */
2793                                         1,      /* link_count */
2794                                         de->udf_file_entry_sector);
2795 +                               jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2796                                 xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE);
2797                         }
2798                 }
2799 @@ -1199,6 +1204,7 @@
2800         set8(&vsd->structure_version, 1);
2801         for (i = 0; i < 3; ++i) {
2802                 memcpy(vsd->standard_identifier, identifiers[i], 5);
2803 +               jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2804                 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
2805         }
2806         last_extent_written += 3;
2807 @@ -1225,30 +1231,37 @@
2808  
2809         memset(buf, 0, sizeof (buf));
2810         set_primary_vol_desc(buf, last_extent_written++);
2811 +       jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2812         xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
2813  
2814         memset(buf, 0, sizeof (buf));
2815         set_impl_use_vol_desc(buf, last_extent_written++);
2816 +       jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2817         xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
2818  
2819         memset(buf, 0, sizeof (buf));
2820         set_partition_desc(buf, last_extent_written++);
2821 +       jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2822         xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
2823  
2824         memset(buf, 0, sizeof (buf));
2825         set_logical_vol_desc(buf, last_extent_written++);
2826 +       jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2827         xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
2828  
2829         memset(buf, 0, sizeof (buf));
2830         set_unallocated_space_desc(buf, last_extent_written++);
2831 +       jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2832         xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
2833  
2834         memset(buf, 0, sizeof (buf));
2835         set_terminating_desc(buf, last_extent_written++);
2836 +       jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2837         xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
2838  
2839         memset(buf, 0, sizeof (buf));
2840         for (i = 6; i < UDF_MAIN_SEQ_LENGTH; ++i) {
2841 +        jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2842                 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
2843                 last_extent_written++;
2844         }
2845 @@ -1272,6 +1285,7 @@
2846                                                 last_extent_written++);
2847         set_terminating_desc(buf+1*SECTOR_SIZE, last_extent_written++);
2848  
2849 +       jtwrite(buf, SECTOR_SIZE, UDF_INTEG_SEQ_LENGTH, 0, FALSE);
2850         xfwrite(buf, SECTOR_SIZE, UDF_INTEG_SEQ_LENGTH, out, 0, FALSE);
2851         return (0);
2852  }
2853 @@ -1288,6 +1302,7 @@
2854  
2855         memset(buf, 0, sizeof (buf));
2856         set_anchor_volume_desc_pointer(buf, last_extent_written++);
2857 +       jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2858         xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
2859         return (0);
2860  }
2861 @@ -1309,6 +1324,7 @@
2862         set_terminating_desc(buf+1*SECTOR_SIZE,
2863                         (last_extent_written++) - lba_udf_partition_start);
2864  
2865 +       jtwrite(buf, SECTOR_SIZE, 2, 0, FALSE);
2866         xfwrite(buf, SECTOR_SIZE, 2, out, 0, FALSE);
2867  
2868         return (0);
2869 @@ -1350,6 +1366,7 @@
2870         char buf[SECTOR_SIZE];
2871         memset(buf, 0, sizeof (buf));
2872         while (last_extent_written < last_extent_to_write) {
2873 +               jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2874                 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
2875                 ++last_extent_written;
2876         }
2877 @@ -1395,6 +1412,7 @@
2878         memset(buf, 0, sizeof (buf));
2879         while (last_extent_written < last_extent_to_write) {
2880                 set_anchor_volume_desc_pointer(buf, last_extent_written++);
2881 +               jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
2882                 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
2883         }
2884         return (0);
2885 diff -urNb cdrtools-2.0+a30.pre1/mkisofs/write.c cdrtools-2.0+a30.pre1/mkisofs.steve/write.c
2886 --- cdrtools-2.0+a30.pre1/mkisofs/write.c       2004-06-16 17:48:45.000000000 +0100
2887 +++ cdrtools-2.0+a30.pre1/mkisofs.steve/write.c 2004-06-16 19:31:42.000000000 +0100
2888 @@ -289,6 +289,7 @@
2889  #endif
2890                 }
2891         }
2892 +
2893         while (count) {
2894                 int     got;
2895  
2896 @@ -459,7 +460,7 @@
2897         FILE            *infile;
2898         off_t           remain;
2899         int     use;
2900 -
2901 +    int include_in_jigdo = list_file_in_jigdo(filename, size);
2902  
2903         if ((infile = fopen(filename, "rb")) == NULL) {
2904  #ifdef USE_LIBSCHILY
2905 @@ -480,6 +481,9 @@
2906  #endif /* APPLE_HYB */
2907         remain = size;
2908  
2909 +    if (include_in_jigdo)
2910 +        write_jt_match_record(filename, SECTOR_SIZE, size);
2911 +
2912         while (remain > 0) {
2913                 use = (remain > SECTOR_SIZE * NSECT - 1 ?
2914                                 NSECT * SECTOR_SIZE : remain);
2915 @@ -494,6 +498,9 @@
2916                         exit(1);
2917  #endif
2918                 }
2919 +        if (!include_in_jigdo)
2920 +            jtwrite(buffer, use, 1,
2921 +                    XA_SUBH_DATA, remain <= (SECTOR_SIZE * NSECT));
2922                 xfwrite(buffer, use, 1, outfile,
2923                                 XA_SUBH_DATA, remain <= (SECTOR_SIZE * NSECT));
2924                 last_extent_written += use / SECTOR_SIZE;
2925 @@ -527,6 +534,7 @@
2926                 remain -= use;
2927         }
2928         fclose(infile);
2929 +
2930  }/* write_one_file(... */
2931  
2932  static void
2933 @@ -546,6 +554,7 @@
2934                                 (Llong)dwpnt->size, dwpnt->extent);
2935  #endif
2936                 if (dwpnt->table) {
2937 +                       jtwrite(dwpnt->table, ISO_ROUND_UP(dwpnt->size), 1, XA_SUBH_DATA, TRUE);
2938                         xfwrite(dwpnt->table, ISO_ROUND_UP(dwpnt->size), 1,
2939                                                         outfile,
2940                                                         XA_SUBH_DATA, TRUE);
2941 @@ -590,9 +599,11 @@
2942                         Uint    i;
2943  
2944                         for (i = 0; i < dwpnt->pad; i++)
2945 +            {
2946 +                               jtwrite(blk, SECTOR_SIZE, 1, 0, FALSE);
2947                                 xfwrite(blk, SECTOR_SIZE, 1, outfile, 0, FALSE);
2948 -
2949 -                       last_extent_written += dwpnt->pad;
2950 +                last_extent_written++;
2951 +            }
2952                 }
2953  #endif /* APPLE_HYB || DVD_VIDEO */
2954  
2955 @@ -804,10 +815,10 @@
2956         if (dcount < 2) {
2957  #ifdef USE_LIBSCHILY
2958                 errmsgno(EX_BAD,
2959 -                       "Directory size too small (. or .. missing ???)\n");
2960 +                       "Directory size too small (. or .. missing !)\n");
2961  #else
2962                 fprintf(stderr,
2963 -                       "Directory size too small (. or .. missing ???)\n");
2964 +                       "Directory size too small (. or .. missing !)\n");
2965  #endif
2966                 sort_goof = 1;
2967  
2968 @@ -1508,6 +1519,7 @@
2969                         dir_index, dpnt->de_name);
2970  #endif
2971         }
2972 +       jtwrite(directory_buffer, total_size, 1, 0, FALSE);
2973         xfwrite(directory_buffer, total_size, 1, outfile, 0, FALSE);
2974         last_extent_written += total_size >> 11;
2975         free(directory_buffer);
2976 @@ -1525,6 +1537,7 @@
2977                                 ce_index, dpnt->ce_bytes);
2978  #endif
2979                 }
2980 +               jtwrite(ce_buffer, ce_size, 1, 0, FALSE);
2981                 xfwrite(ce_buffer, ce_size, 1, outfile, 0, FALSE);
2982                 last_extent_written += ce_size >> 11;
2983                 free(ce_buffer);
2984 @@ -1759,9 +1772,11 @@
2985                  * write out padding to round up to HFS allocation block
2986                  */
2987                 for (i = 0; i < hfs_pad; i++)
2988 +        {
2989 +                       jtwrite(buffer, sizeof (buffer), 1, 0, FALSE);
2990                         xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE);
2991 -
2992 -               last_extent_written += hfs_pad;
2993 +            last_extent_written++;
2994 +        }
2995         }
2996  #endif /* APPLE_HYB */
2997  
2998 @@ -1798,11 +1813,15 @@
2999         /* write out extents/catalog/dt file */
3000         if (apple_hyb) {
3001  
3002 +               jtwrite(hce->hfs_ce, HFS_BLOCKSZ, hce->hfs_tot_size, 0, FALSE);
3003                 xfwrite(hce->hfs_ce, HFS_BLOCKSZ, hce->hfs_tot_size, outfile, 0, FALSE);
3004  
3005                 /* round up to a whole CD block */
3006                 if (HFS_ROUND_UP(hce->hfs_tot_size) -
3007                                         hce->hfs_tot_size * HFS_BLOCKSZ) {
3008 +                       jtwrite(buffer,
3009 +                               HFS_ROUND_UP(hce->hfs_tot_size) -
3010 +                               hce->hfs_tot_size * HFS_BLOCKSZ, 1, 0, FALSE);
3011                         xfwrite(buffer,
3012                                 HFS_ROUND_UP(hce->hfs_tot_size) -
3013                                 hce->hfs_tot_size * HFS_BLOCKSZ, 1, outfile, 0, FALSE);
3014 @@ -1980,6 +1999,7 @@
3015         }
3016  
3017         /* if not a bootable cd do it the old way */
3018 +       jtwrite(&vol_desc, SECTOR_SIZE, 1, 0, FALSE);
3019         xfwrite(&vol_desc, SECTOR_SIZE, 1, outfile, 0, FALSE);
3020         last_extent_written++;
3021         return (0);
3022 @@ -1997,6 +2017,7 @@
3023         vol_desc.file_structure_version[0] = 2;
3024  
3025         /* if not a bootable cd do it the old way */
3026 +       jtwrite(&vol_desc, SECTOR_SIZE, 1, 0, FALSE);
3027         xfwrite(&vol_desc, SECTOR_SIZE, 1, outfile, 0, FALSE);
3028         last_extent_written++;
3029         return (0);
3030 @@ -2019,6 +2040,7 @@
3031         evol_desc.type[0] = (unsigned char) ISO_VD_END;
3032         memcpy(evol_desc.id, ISO_STANDARD_ID, sizeof (ISO_STANDARD_ID));
3033         evol_desc.version[0] = 1;
3034 +       jtwrite(&evol_desc, SECTOR_SIZE, 1, 0, TRUE);
3035         xfwrite(&evol_desc, SECTOR_SIZE, 1, outfile, 0, TRUE);
3036         last_extent_written += 1;
3037         return (0);
3038 @@ -2074,10 +2096,16 @@
3039         cp[SECTOR_SIZE - 1] = '\0';
3040         /* Per default: keep privacy. Blackout the version and arguments. */
3041         if(getenv("ISODEBUG"))
3042 +    {
3043 +        jtwrite(vers, SECTOR_SIZE, 1, 0, TRUE);
3044                 xfwrite(vers, SECTOR_SIZE, 1, outfile, 0, TRUE);
3045 +    }
3046         else
3047 +    {
3048 +               jtwrite(calloc(SECTOR_SIZE, 1), SECTOR_SIZE, 1, 0, TRUE);
3049                 xfwrite(calloc(SECTOR_SIZE, 1), SECTOR_SIZE, 1, outfile, 0, TRUE);
3050 -       last_extent_written += 1;
3051 +    }
3052 +       last_extent_written ++;
3053         return (0);
3054  }
3055  
3056 @@ -2151,9 +2179,12 @@
3057         FILE    *outfile;
3058  {
3059         /* Next we write the path tables */
3060 +       jtwrite(path_table_l, path_blocks << 11, 1, 0, FALSE);
3061         xfwrite(path_table_l, path_blocks << 11, 1, outfile, 0, FALSE);
3062 +       last_extent_written += path_blocks;
3063 +       jtwrite(path_table_m, path_blocks << 11, 1, 0, FALSE);
3064         xfwrite(path_table_m, path_blocks << 11, 1, outfile, 0, FALSE);
3065 -       last_extent_written += 2 * path_blocks;
3066 +       last_extent_written += path_blocks;
3067         free(path_table_l);
3068         free(path_table_m);
3069         path_table_l = NULL;
3070 @@ -2165,6 +2196,7 @@
3071  exten_write(outfile)
3072         FILE    *outfile;
3073  {
3074 +       jtwrite(extension_record, SECTOR_SIZE, 1, 0, FALSE);
3075         xfwrite(extension_record, SECTOR_SIZE, 1, outfile, 0, FALSE);
3076         last_extent_written++;
3077         return (0);
3078 @@ -2348,10 +2380,11 @@
3079         npad = session_start + 16 - last_extent_written;
3080  
3081         for (i = 0; i < npad; i++) {
3082 +               jtwrite(buffer, sizeof (buffer), 1, 0, FALSE);
3083                 xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE);
3084 +        last_extent_written++;
3085         }
3086  
3087 -       last_extent_written += npad;
3088         return (0);
3089  }
3090  
3091 @@ -2372,10 +2405,11 @@
3092                 npad += 16 - i;
3093  
3094         for (i = 0; i < npad; i++) {
3095 +               jtwrite(buffer, sizeof (buffer), 1, 0, FALSE);
3096                 xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE);
3097 +        last_extent_written++;
3098         }
3099  
3100 -       last_extent_written += npad;
3101         return (0);
3102  }
3103  
3104 @@ -2389,10 +2423,11 @@
3105         memset(buffer, 0, sizeof (buffer));
3106  
3107         for (i = 0; i < 150; i++) {
3108 +               jtwrite(buffer, sizeof (buffer), 1, 0, FALSE);
3109                 xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE);
3110 +        last_extent_written++;
3111         }
3112  
3113 -       last_extent_written += 150;
3114         return (0);
3115  }
3116  
3117 @@ -2748,10 +2783,12 @@
3118         r = tot_size % HFS_BLK_CONV;
3119  
3120         /* write out HFS volume header info */
3121 +       jtwrite(hce->hfs_map, HFS_BLOCKSZ, tot_size, 0, FALSE);
3122         xfwrite(hce->hfs_map, HFS_BLOCKSZ, tot_size, outfile, 0, FALSE);
3123  
3124         /* fill up to a complete CD block */
3125         if (r) {
3126 +               jtwrite(buffer, HFS_BLOCKSZ, HFS_BLK_CONV - r, 0, FALSE);
3127                 xfwrite(buffer, HFS_BLOCKSZ, HFS_BLK_CONV - r, outfile, 0, FALSE);
3128                 n++;
3129         }