mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 20:36:35 +00:00
[CDMAKE]
- Update source file headers. - Improve some error output. - Factorize code that creates El-Torito boot entries. - Start thinking how to add UDF and AutoCRC support. svn path=/trunk/; revision=70762
This commit is contained in:
parent
8d665c9085
commit
76f949716c
2 changed files with 217 additions and 131 deletions
|
@ -3,6 +3,11 @@
|
||||||
* by Philip J. Erdelsky
|
* by Philip J. Erdelsky
|
||||||
* pje@acm.org
|
* pje@acm.org
|
||||||
* http://alumnus.caltech.edu/~pje/
|
* http://alumnus.caltech.edu/~pje/
|
||||||
|
*
|
||||||
|
* http://alumnus.caltech.edu/~pje/cdmake.txt
|
||||||
|
*
|
||||||
|
* According to his website, this file was released into the public domain
|
||||||
|
* by Philip J. Erdelsky.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
@ -13,6 +18,7 @@
|
||||||
* Casper S. Hornstrup
|
* Casper S. Hornstrup
|
||||||
* Filip Navara
|
* Filip Navara
|
||||||
* Magnus Olsen
|
* Magnus Olsen
|
||||||
|
* Hermes Belusca-Maito
|
||||||
*
|
*
|
||||||
* HISTORY:
|
* HISTORY:
|
||||||
*
|
*
|
||||||
|
@ -34,8 +40,6 @@
|
||||||
* magnus@greatlord.com
|
* magnus@greatlord.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* According to his website, this file was released into the public domain by Philip J. Erdelsky */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -176,13 +180,21 @@ PDIR_RECORD sort_linked_list(PDIR_RECORD,
|
||||||
static char DIRECTORY_TIMESTAMP[] = "~Y$'KOR$.3K&";
|
static char DIRECTORY_TIMESTAMP[] = "~Y$'KOR$.3K&";
|
||||||
|
|
||||||
static struct cd_image cd;
|
static struct cd_image cd;
|
||||||
|
DIR_RECORD root;
|
||||||
|
|
||||||
char volume_label[32];
|
char volume_label[32];
|
||||||
DIR_RECORD root;
|
|
||||||
char source[512];
|
char source[512];
|
||||||
char *end_source;
|
char *end_source;
|
||||||
|
|
||||||
enum {QUIET, NORMAL, VERBOSE} verbosity;
|
enum {QUIET, NORMAL, VERBOSE} verbosity;
|
||||||
BOOL show_progress;
|
BOOL show_progress;
|
||||||
|
|
||||||
|
BOOL scan_files_only = FALSE;
|
||||||
|
// BOOL compute_crc = FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ISO 9660 information
|
||||||
|
*/
|
||||||
DWORD size_limit;
|
DWORD size_limit;
|
||||||
BOOL accept_punctuation_marks;
|
BOOL accept_punctuation_marks;
|
||||||
|
|
||||||
|
@ -190,12 +202,23 @@ DWORD total_sectors;
|
||||||
DWORD path_table_size;
|
DWORD path_table_size;
|
||||||
DWORD little_endian_path_table_sector;
|
DWORD little_endian_path_table_sector;
|
||||||
DWORD big_endian_path_table_sector;
|
DWORD big_endian_path_table_sector;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stats
|
||||||
|
*/
|
||||||
DWORD number_of_files;
|
DWORD number_of_files;
|
||||||
DWORD bytes_in_files;
|
DWORD bytes_in_files;
|
||||||
DWORD unused_bytes_at_ends_of_files;
|
DWORD unused_bytes_at_ends_of_files;
|
||||||
DWORD number_of_directories;
|
DWORD number_of_directories;
|
||||||
DWORD bytes_in_directories;
|
DWORD bytes_in_directories;
|
||||||
|
|
||||||
|
struct target_dir_hash specified_files;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* El-Torito boot information
|
||||||
|
*/
|
||||||
BOOL eltorito; // TRUE/FALSE: bootable/non-bootable CD-ROM
|
BOOL eltorito; // TRUE/FALSE: bootable/non-bootable CD-ROM
|
||||||
BOOL multi_boot; // TRUE/FALSE: multi/single-boot CD-ROM
|
BOOL multi_boot; // TRUE/FALSE: multi/single-boot CD-ROM
|
||||||
DWORD boot_catalog_sector;
|
DWORD boot_catalog_sector;
|
||||||
|
@ -203,12 +226,19 @@ BOOT_VALIDATION_HEADER boot_validation_header;
|
||||||
BOOT_ENTRY default_boot_entry;
|
BOOT_ENTRY default_boot_entry;
|
||||||
PBOOT_HEADER boot_header_list;
|
PBOOT_HEADER boot_header_list;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Joliet information
|
||||||
|
*/
|
||||||
BOOL joliet;
|
BOOL joliet;
|
||||||
DWORD joliet_path_table_size;
|
DWORD joliet_path_table_size;
|
||||||
DWORD joliet_little_endian_path_table_sector;
|
DWORD joliet_little_endian_path_table_sector;
|
||||||
DWORD joliet_big_endian_path_table_sector;
|
DWORD joliet_big_endian_path_table_sector;
|
||||||
|
|
||||||
struct target_dir_hash specified_files;
|
/*
|
||||||
|
* UDF information
|
||||||
|
*/
|
||||||
|
BOOL make_bridged_udf = TRUE; // TRUE for "UDF-Bridge" (aka. UDF/ISO); FALSE for pure UDF.
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
This function edits a 32-bit unsigned number into a comma-delimited form, such
|
This function edits a 32-bit unsigned number into a comma-delimited form, such
|
||||||
|
@ -685,7 +715,7 @@ static void parse_filename_into_dirrecord(const char* filename, PDIR_RECORD d, B
|
||||||
if (d->extension[0] != 0)
|
if (d->extension[0] != 0)
|
||||||
{
|
{
|
||||||
if (!joliet)
|
if (!joliet)
|
||||||
error_exit("Directory with extension %s", filename);
|
error_exit("Directory with extension '%s'", filename);
|
||||||
}
|
}
|
||||||
d->flags = DIRECTORY_FLAG;
|
d->flags = DIRECTORY_FLAG;
|
||||||
} else
|
} else
|
||||||
|
@ -993,7 +1023,7 @@ make_directory_records(PDIR_RECORD d)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_exit("Cannot open %s\n", source);
|
error_exit("Cannot open '%s'\n", source);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1053,7 +1083,7 @@ make_directory_records(PDIR_RECORD d)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_exit("Cannot open %s\n", source);
|
error_exit("Cannot open '%s'\n", source);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1136,7 +1166,7 @@ make_directory_records(PDIR_RECORD d)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_exit("Cannot open %s\n", source);
|
error_exit("Cannot open '%s'\n", source);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1221,18 +1251,18 @@ scan_specified_files(PDIR_RECORD d, struct target_dir_entry *dir)
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
NULL)) == INVALID_HANDLE_VALUE)
|
NULL)) == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
error_exit("Cannot open timestamp file %s\n", file->source_name);
|
error_exit("Cannot open timestamp file '%s'\n", file->source_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_cd_file_time(open_file, &d->date_and_time))
|
if (!get_cd_file_time(open_file, &d->date_and_time))
|
||||||
{
|
{
|
||||||
error_exit("Cannot stat timestamp file %s\n", file->source_name);
|
error_exit("Cannot stat timestamp file '%s'\n", file->source_name);
|
||||||
}
|
}
|
||||||
CloseHandle(open_file);
|
CloseHandle(open_file);
|
||||||
#else
|
#else
|
||||||
if (stat(file->target_name, &stbuf) == -1)
|
if (stat(file->target_name, &stbuf) == -1)
|
||||||
{
|
{
|
||||||
error_exit("Cannot stat timestamp file %s\n", file->source_name);
|
error_exit("Cannot stat timestamp file '%s'\n", file->source_name);
|
||||||
}
|
}
|
||||||
convert_date_and_time(&d->date_and_time, &stbuf.st_ctime);
|
convert_date_and_time(&d->date_and_time, &stbuf.st_ctime);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1257,15 +1287,15 @@ scan_specified_files(PDIR_RECORD d, struct target_dir_entry *dir)
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
NULL)) == INVALID_HANDLE_VALUE)
|
NULL)) == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
error_exit("Cannot open file %s\n", file->source_name);
|
error_exit("Cannot open file '%s'\n", file->source_name);
|
||||||
}
|
}
|
||||||
if (!get_cd_file_time(open_file, &new_d->date_and_time))
|
if (!get_cd_file_time(open_file, &new_d->date_and_time))
|
||||||
{
|
{
|
||||||
error_exit("Cannot stat file %s\n", file->source_name);
|
error_exit("Cannot stat file '%s'\n", file->source_name);
|
||||||
}
|
}
|
||||||
if (!GetFileSizeEx(open_file, &file_size))
|
if (!GetFileSizeEx(open_file, &file_size))
|
||||||
{
|
{
|
||||||
error_exit("Cannot get file size of %s\n", file->source_name);
|
error_exit("Cannot get file size of '%s'\n", file->source_name);
|
||||||
}
|
}
|
||||||
new_d->size = new_d->joliet_size = file_size.QuadPart;
|
new_d->size = new_d->joliet_size = file_size.QuadPart;
|
||||||
new_d->orig_name = file->source_name;
|
new_d->orig_name = file->source_name;
|
||||||
|
@ -1378,14 +1408,17 @@ static BOOL write_from_file(FILE *file, DWORD size)
|
||||||
|
|
||||||
static void pass(void)
|
static void pass(void)
|
||||||
{
|
{
|
||||||
PDIR_RECORD d;
|
PDIR_RECORD d, q;
|
||||||
PDIR_RECORD q;
|
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
unsigned int name_length;
|
unsigned int name_length;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
DWORD number_of_sectors;
|
DWORD number_of_sectors;
|
||||||
char *old_end_source;
|
char *old_end_source;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
|
||||||
|
PBOOT_HEADER header;
|
||||||
|
PBOOT_ENTRY entry;
|
||||||
|
|
||||||
char timestring[17];
|
char timestring[17];
|
||||||
|
|
||||||
get_time_string(timestring);
|
get_time_string(timestring);
|
||||||
|
@ -1395,7 +1428,8 @@ static void pass(void)
|
||||||
|
|
||||||
|
|
||||||
// Primary Volume Descriptor
|
// Primary Volume Descriptor
|
||||||
|
if (make_bridged_udf)
|
||||||
|
{
|
||||||
write_string("\1CD001\1");
|
write_string("\1CD001\1");
|
||||||
write_byte(0);
|
write_byte(0);
|
||||||
write_bytecounted_string(32, "", ' '); // system identifier
|
write_bytecounted_string(32, "", ' '); // system identifier
|
||||||
|
@ -1434,7 +1468,7 @@ static void pass(void)
|
||||||
write_byte(1);
|
write_byte(1);
|
||||||
write_byte(0);
|
write_byte(0);
|
||||||
fill_sector();
|
fill_sector();
|
||||||
|
}
|
||||||
|
|
||||||
// Boot Volume Descriptor
|
// Boot Volume Descriptor
|
||||||
if (eltorito)
|
if (eltorito)
|
||||||
|
@ -1492,17 +1526,17 @@ static void pass(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Volume Descriptor Set Terminator
|
// Volume Descriptor Set Terminator
|
||||||
|
if (make_bridged_udf)
|
||||||
|
{
|
||||||
write_string("\377CD001\1");
|
write_string("\377CD001\1");
|
||||||
fill_sector();
|
fill_sector();
|
||||||
|
}
|
||||||
|
|
||||||
// Boot Catalog and Images
|
// TODO: Add UDF support!
|
||||||
if (eltorito)
|
|
||||||
{
|
|
||||||
PBOOT_HEADER header;
|
|
||||||
PBOOT_ENTRY entry;
|
|
||||||
|
|
||||||
// Boot Catalog
|
// Boot Catalog
|
||||||
|
if (eltorito)
|
||||||
|
{
|
||||||
boot_catalog_sector = cd.sector;
|
boot_catalog_sector = cd.sector;
|
||||||
|
|
||||||
// Validation entry header
|
// Validation entry header
|
||||||
|
@ -1552,15 +1586,17 @@ static void pass(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
fill_sector();
|
fill_sector();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Boot Images
|
// Boot Images
|
||||||
|
if (eltorito)
|
||||||
|
{
|
||||||
default_boot_entry.load_rba = cd.sector;
|
default_boot_entry.load_rba = cd.sector;
|
||||||
|
|
||||||
file = fopen(default_boot_entry.bootimage, "rb");
|
file = fopen(default_boot_entry.bootimage, "rb");
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
error_exit("Cannot open %s\n", default_boot_entry.bootimage);
|
error_exit("Cannot open '%s'\n", default_boot_entry.bootimage);
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
size = ftell(file);
|
size = ftell(file);
|
||||||
if (size == 0 || (size % 2048))
|
if (size == 0 || (size % 2048))
|
||||||
|
@ -1573,7 +1609,7 @@ static void pass(void)
|
||||||
if (!write_from_file(file, size))
|
if (!write_from_file(file, size))
|
||||||
{
|
{
|
||||||
fclose(file);
|
fclose(file);
|
||||||
error_exit("Read error in file %s\n", default_boot_entry.bootimage);
|
error_exit("Read error in file '%s'\n", default_boot_entry.bootimage);
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
|
@ -1589,7 +1625,7 @@ static void pass(void)
|
||||||
|
|
||||||
file = fopen(entry->bootimage, "rb");
|
file = fopen(entry->bootimage, "rb");
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
error_exit("Cannot open %s\n", entry->bootimage);
|
error_exit("Cannot open '%s'\n", entry->bootimage);
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
size = ftell(file);
|
size = ftell(file);
|
||||||
if (size == 0 || (size % 2048))
|
if (size == 0 || (size % 2048))
|
||||||
|
@ -1602,7 +1638,7 @@ static void pass(void)
|
||||||
if (!write_from_file(file, size))
|
if (!write_from_file(file, size))
|
||||||
{
|
{
|
||||||
fclose(file);
|
fclose(file);
|
||||||
error_exit("Read error in file %s\n", entry->bootimage);
|
error_exit("Read error in file '%s'\n", entry->bootimage);
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
|
@ -1615,7 +1651,9 @@ static void pass(void)
|
||||||
// fill_sector();
|
// fill_sector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Little Endian Path Table
|
// Little Endian Path Table
|
||||||
|
|
||||||
little_endian_path_table_sector = cd.sector;
|
little_endian_path_table_sector = cd.sector;
|
||||||
write_byte(1);
|
write_byte(1);
|
||||||
write_byte(0); // number of sectors in extended attribute record
|
write_byte(0); // number of sectors in extended attribute record
|
||||||
|
@ -1643,6 +1681,7 @@ static void pass(void)
|
||||||
SECTOR_SIZE + cd.offset;
|
SECTOR_SIZE + cd.offset;
|
||||||
fill_sector();
|
fill_sector();
|
||||||
|
|
||||||
|
|
||||||
// Big Endian Path Table
|
// Big Endian Path Table
|
||||||
|
|
||||||
big_endian_path_table_sector = cd.sector;
|
big_endian_path_table_sector = cd.sector;
|
||||||
|
@ -1714,6 +1753,14 @@ static void pass(void)
|
||||||
fill_sector();
|
fill_sector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add UDF support!
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Boot Images ??
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO: Add CRC block for header!
|
||||||
|
|
||||||
// Directories and files
|
// Directories and files
|
||||||
for (d = &root; d != NULL; d = d->next_in_path_table)
|
for (d = &root; d != NULL; d = d->next_in_path_table)
|
||||||
{
|
{
|
||||||
|
@ -1784,11 +1831,11 @@ static void pass(void)
|
||||||
printf("Writing contents of %s\n", file_source);
|
printf("Writing contents of %s\n", file_source);
|
||||||
file = fopen(file_source, "rb");
|
file = fopen(file_source, "rb");
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
error_exit("Cannot open %s\n", file_source);
|
error_exit("Cannot open '%s'\n", file_source);
|
||||||
if (!write_from_file(file, size))
|
if (!write_from_file(file, size))
|
||||||
{
|
{
|
||||||
fclose(file);
|
fclose(file);
|
||||||
error_exit("Read error in file %s\n", file_source);
|
error_exit("Read error in file '%s'\n", file_source);
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
end_source = old_end_source;
|
end_source = old_end_source;
|
||||||
|
@ -1798,19 +1845,31 @@ static void pass(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add final CRC block!
|
||||||
|
|
||||||
total_sectors = (DWORD)cd.sector;
|
total_sectors = (DWORD)cd.sector;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char HELP[] =
|
static char HELP[] =
|
||||||
"\n"
|
"\n"
|
||||||
"CDMAKE CD-ROM Premastering Utility\n"
|
"CDMAKE CD-ROM Premastering Utility\n"
|
||||||
"Copyright (C) Philip J. Erdelsky\n"
|
"Copyright (C) 1997 Philip J. Erdelsky\n"
|
||||||
"Copyright (C) 2003-2015 ReactOS Team\n"
|
"Copyright (C) 2003-2016 ReactOS Team\n"
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"CDMAKE [-vN] [-p] [-s N] [-m] [-j] [-pN] [-eN] [-b bootimage]\n"
|
"CDMAKE [-vN] [-p] [-s N] [-m] [-j] [-q] "
|
||||||
|
// "[-x] "
|
||||||
|
"[-pN] [-eN] [-b bootimage]\n"
|
||||||
" [-bootdata:N#<defaultBootEntry>#<bootEntry1>#...#<bootEntryN>]\n"
|
" [-bootdata:N#<defaultBootEntry>#<bootEntry1>#...#<bootEntryN>]\n"
|
||||||
" source volume image\n"
|
" source volume image\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
"Mandatory options:\n"
|
||||||
|
" source Specifications of base directory containing all files to be\n"
|
||||||
|
" written to CD-ROM image. Can be a directory, or a path to a\n"
|
||||||
|
" file list (in which case the path must start with a '@').\n"
|
||||||
|
" volume Volume label.\n"
|
||||||
|
" image Image file or device.\n"
|
||||||
|
"\n"
|
||||||
|
"General options:\n"
|
||||||
" -vN Verbosity level. Valid values for 'N' are:\n"
|
" -vN Verbosity level. Valid values for 'N' are:\n"
|
||||||
" 0: Quiet mode - display nothing but error messages.\n"
|
" 0: Quiet mode - display nothing but error messages.\n"
|
||||||
" 1: Normal mode (default).\n"
|
" 1: Normal mode (default).\n"
|
||||||
|
@ -1819,16 +1878,24 @@ static char HELP[] =
|
||||||
" -p Show progress while writing.\n"
|
" -p Show progress while writing.\n"
|
||||||
" -s N Abort operation before beginning write if image will be larger\n"
|
" -s N Abort operation before beginning write if image will be larger\n"
|
||||||
" than N megabytes (i.e. 1024*1024*N bytes).\n"
|
" than N megabytes (i.e. 1024*1024*N bytes).\n"
|
||||||
|
" -q Only scan the source files; do not create an image.\n"
|
||||||
|
// " -x Compute and encode the AutoCRC value in the image.\n"
|
||||||
|
"\n"
|
||||||
|
"ISO 9660 and Joliet options:\n"
|
||||||
" -m Accept punctuation marks other than underscores in names and\n"
|
" -m Accept punctuation marks other than underscores in names and\n"
|
||||||
" extensions.\n"
|
" extensions.\n"
|
||||||
" -j Generate Joliet filename records.\n"
|
" -j Generate Joliet filename records.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
// "UDF options:\n"
|
||||||
|
// " Not implemented yet!\n"
|
||||||
|
// "\n"
|
||||||
|
"El-Torito boot options:\n"
|
||||||
" -pN Boot platform ID in hex format (default: 00 for a BIOS system).\n"
|
" -pN Boot platform ID in hex format (default: 00 for a BIOS system).\n"
|
||||||
" -eN Boot media emulation. Valid values for 'N' are:\n"
|
" -eN Boot media emulation. Valid values for 'N' are:\n"
|
||||||
" 0 (or nothing): No emulation.\n"
|
" 0 (or nothing): No emulation.\n"
|
||||||
" 1: 1.2Mb diskette.\n"
|
" 1: 1.2 MB diskette.\n"
|
||||||
" 2: 1.44Mb diskette.\n"
|
" 2: 1.44MB diskette.\n"
|
||||||
" 3: 2.88Mb diskette.\n"
|
" 3: 2.88MB diskette.\n"
|
||||||
" 4: Hard disk.\n"
|
" 4: Hard disk.\n"
|
||||||
" -b bootimage Create a single-boot El-Torito image.\n"
|
" -b bootimage Create a single-boot El-Torito image.\n"
|
||||||
" -bootdata: Create a multi-boot El-Torito image. This option cannot be\n"
|
" -bootdata: Create a multi-boot El-Torito image. This option cannot be\n"
|
||||||
|
@ -1842,12 +1909,7 @@ static char HELP[] =
|
||||||
" - Do not use spaces.\n"
|
" - Do not use spaces.\n"
|
||||||
" - Each multi-boot entry must be delimited with a hash symbol (#).\n"
|
" - Each multi-boot entry must be delimited with a hash symbol (#).\n"
|
||||||
" - Each option for a boot entry must be delimited with a comma (,).\n"
|
" - Each option for a boot entry must be delimited with a comma (,).\n"
|
||||||
" - Each boot entry must specify the platform ID.\n"
|
" - Each boot entry must specify the platform ID.\n";
|
||||||
"\n"
|
|
||||||
" source Specifications of base directory containing all files to be\n"
|
|
||||||
" written to CD-ROM image.\n"
|
|
||||||
" volume Volume label.\n"
|
|
||||||
" image Image file or device.\n";
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
Program execution starts here.
|
Program execution starts here.
|
||||||
|
@ -1879,6 +1941,20 @@ char* strtok_s(char *str, const char *delim, char **ctx)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_boot_entry(PBOOT_ENTRY boot_entry,
|
||||||
|
BYTE boot_emu_type, WORD load_segment,
|
||||||
|
char* bootimage)
|
||||||
|
{
|
||||||
|
boot_entry->boot_id = 0x88; // Bootable entry
|
||||||
|
boot_entry->boot_emu_type = boot_emu_type; // 0: No emulation, etc...
|
||||||
|
boot_entry->load_segment = load_segment; // If 0 then use default 0x07C0
|
||||||
|
|
||||||
|
boot_entry->bootimage[0] = '\0';
|
||||||
|
strncpy(boot_entry->bootimage, bootimage, sizeof(boot_entry->bootimage));
|
||||||
|
boot_entry->bootimage[sizeof(boot_entry->bootimage)-1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
time_t timestamp = time(NULL);
|
time_t timestamp = time(NULL);
|
||||||
|
@ -1891,24 +1967,28 @@ int main(int argc, char **argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize root directory
|
// Initialize CD-ROM write buffer
|
||||||
|
|
||||||
|
cd.file = NULL;
|
||||||
|
cd.filespecs[0] = 0;
|
||||||
|
|
||||||
cd.buffer = malloc(BUFFER_SIZE);
|
cd.buffer = malloc(BUFFER_SIZE);
|
||||||
if (cd.buffer == NULL)
|
if (cd.buffer == NULL)
|
||||||
error_exit("Insufficient memory");
|
error_exit("Insufficient memory");
|
||||||
|
|
||||||
|
// Initialize root directory
|
||||||
|
|
||||||
memset(&root, 0, sizeof(root));
|
memset(&root, 0, sizeof(root));
|
||||||
root.level = 1;
|
root.level = 1;
|
||||||
root.flags = DIRECTORY_FLAG;
|
root.flags = DIRECTORY_FLAG;
|
||||||
convert_date_and_time(&root.date_and_time, ×tamp);
|
convert_date_and_time(&root.date_and_time, ×tamp);
|
||||||
|
|
||||||
// Initialize CD-ROM write buffer
|
|
||||||
|
|
||||||
cd.file = NULL;
|
|
||||||
cd.filespecs[0] = 0;
|
|
||||||
|
|
||||||
// Initialize parameters
|
// Initialize parameters
|
||||||
|
|
||||||
|
scan_files_only = FALSE;
|
||||||
|
make_bridged_udf = TRUE;
|
||||||
|
// compute_crc = FALSE;
|
||||||
|
|
||||||
verbosity = NORMAL;
|
verbosity = NORMAL;
|
||||||
show_progress = FALSE;
|
show_progress = FALSE;
|
||||||
size_limit = 0;
|
size_limit = 0;
|
||||||
|
@ -1921,12 +2001,12 @@ int main(int argc, char **argv)
|
||||||
multi_boot = FALSE;
|
multi_boot = FALSE;
|
||||||
boot_validation_header.header_id = 1; // Validation header ID
|
boot_validation_header.header_id = 1; // Validation header ID
|
||||||
boot_validation_header.platform_id = 0; // x86/64 BIOS system
|
boot_validation_header.platform_id = 0; // x86/64 BIOS system
|
||||||
default_boot_entry.boot_id = 0x88; // Bootable entry
|
init_boot_entry(&default_boot_entry,
|
||||||
default_boot_entry.boot_emu_type = 0; // No emulation
|
0, // No emulation
|
||||||
default_boot_entry.load_segment = 0; // 0 --> use default 0x07C0
|
0, // Use default 0x07C0
|
||||||
|
"");
|
||||||
default_boot_entry.sector_count = 0;
|
default_boot_entry.sector_count = 0;
|
||||||
default_boot_entry.load_rba = 0;
|
default_boot_entry.load_rba = 0;
|
||||||
default_boot_entry.bootimage[0] = '\0';
|
|
||||||
boot_header_list = NULL;
|
boot_header_list = NULL;
|
||||||
|
|
||||||
// Scan command line arguments
|
// Scan command line arguments
|
||||||
|
@ -2041,7 +2121,7 @@ int main(int argc, char **argv)
|
||||||
eltorito = TRUE;
|
eltorito = TRUE;
|
||||||
multi_boot = TRUE;
|
multi_boot = TRUE;
|
||||||
|
|
||||||
// FIXME: Paths with '#' or ',' or ' ' inside are not yet supported!!
|
// FIXME: Paths containing '#' or ',' or ' ' are not yet supported!!
|
||||||
|
|
||||||
// Start parsing...
|
// Start parsing...
|
||||||
t = strtok_s(bootdata, "#", &entry_ctx);
|
t = strtok_s(bootdata, "#", &entry_ctx);
|
||||||
|
@ -2058,7 +2138,7 @@ int main(int argc, char **argv)
|
||||||
// Reset to default values
|
// Reset to default values
|
||||||
platform_id = 0; // x86/64 BIOS system
|
platform_id = 0; // x86/64 BIOS system
|
||||||
boot_emu_type = 0; // No emulation
|
boot_emu_type = 0; // No emulation
|
||||||
load_segment = 0; // 0 --> use default 0x07C0
|
load_segment = 0; // Use default 0x07C0
|
||||||
bootimage[0] = '\0';
|
bootimage[0] = '\0';
|
||||||
|
|
||||||
t = strtok_s(NULL, "#", &entry_ctx);
|
t = strtok_s(NULL, "#", &entry_ctx);
|
||||||
|
@ -2106,7 +2186,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
case 't': // Loading segment
|
case 't': // Loading segment
|
||||||
{
|
{
|
||||||
if (*t == 0) // Not specified --> use default 0x07C0
|
if (*t == 0) // Not specified: use default 0x07C0
|
||||||
load_segment = 0;
|
load_segment = 0;
|
||||||
else // Segment in hexadecimal
|
else // Segment in hexadecimal
|
||||||
load_segment = (BYTE)strtoul(t, NULL, 16);
|
load_segment = (BYTE)strtoul(t, NULL, 16);
|
||||||
|
@ -2129,12 +2209,8 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
boot_validation_header.header_id = 1; // Validation header ID
|
boot_validation_header.header_id = 1; // Validation header ID
|
||||||
boot_validation_header.platform_id = platform_id;
|
boot_validation_header.platform_id = platform_id;
|
||||||
default_boot_entry.boot_id = 0x88; // Bootable entry
|
|
||||||
default_boot_entry.boot_emu_type = boot_emu_type;
|
|
||||||
default_boot_entry.load_segment = load_segment;
|
|
||||||
|
|
||||||
strncpy(default_boot_entry.bootimage, bootimage, sizeof(default_boot_entry.bootimage));
|
init_boot_entry(&default_boot_entry, boot_emu_type, load_segment, bootimage);
|
||||||
default_boot_entry.bootimage[sizeof(default_boot_entry.bootimage)-1] = '\0';
|
|
||||||
|
|
||||||
// Default entry is now initialized.
|
// Default entry is now initialized.
|
||||||
default_entry = FALSE;
|
default_entry = FALSE;
|
||||||
|
@ -2149,12 +2225,7 @@ int main(int argc, char **argv)
|
||||||
error_exit("Insufficient memory");
|
error_exit("Insufficient memory");
|
||||||
// boot_entry->next_entry = NULL;
|
// boot_entry->next_entry = NULL;
|
||||||
|
|
||||||
boot_entry->boot_id = 0x88; // Bootable entry
|
init_boot_entry(boot_entry, boot_emu_type, load_segment, bootimage);
|
||||||
boot_entry->boot_emu_type = boot_emu_type;
|
|
||||||
boot_entry->load_segment = load_segment;
|
|
||||||
|
|
||||||
strncpy(boot_entry->bootimage, bootimage, sizeof(boot_entry->bootimage));
|
|
||||||
boot_entry->bootimage[sizeof(boot_entry->bootimage)-1] = '\0';
|
|
||||||
|
|
||||||
// Create a new boot header if we don't have one yet
|
// Create a new boot header if we don't have one yet
|
||||||
if (boot_header == NULL)
|
if (boot_header == NULL)
|
||||||
|
@ -2211,6 +2282,10 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
free(bootdata);
|
free(bootdata);
|
||||||
}
|
}
|
||||||
|
else if (strcmp(argv[i], "-q") == 0)
|
||||||
|
scan_files_only = TRUE;
|
||||||
|
// else if (strcmp(argv[i], "-x") == 0)
|
||||||
|
// compute_crc = TRUE;
|
||||||
else if (i + 2 < argc)
|
else if (i + 2 < argc)
|
||||||
{
|
{
|
||||||
strcpy(source, argv[i++]);
|
strcpy(source, argv[i++]);
|
||||||
|
@ -2249,7 +2324,7 @@ int main(int argc, char **argv)
|
||||||
FILE *f = fopen(source+1, "r");
|
FILE *f = fopen(source+1, "r");
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
error_exit("Cannot open CD-ROM file description %s\n", source+1);
|
error_exit("Cannot open CD-ROM file description '%s'\n", source+1);
|
||||||
}
|
}
|
||||||
while (fgets(lineread, sizeof(lineread), f))
|
while (fgets(lineread, sizeof(lineread), f))
|
||||||
{
|
{
|
||||||
|
@ -2327,11 +2402,13 @@ int main(int argc, char **argv)
|
||||||
if (size_limit != 0 && total_sectors > size_limit)
|
if (size_limit != 0 && total_sectors > size_limit)
|
||||||
error_exit("Size limit exceeded");
|
error_exit("Size limit exceeded");
|
||||||
|
|
||||||
|
if (!scan_files_only)
|
||||||
|
{
|
||||||
// re-initialize CD-ROM write buffer
|
// re-initialize CD-ROM write buffer
|
||||||
|
|
||||||
cd.file = fopen(cd.filespecs, "w+b");
|
cd.file = fopen(cd.filespecs, "w+b");
|
||||||
if (cd.file == NULL)
|
if (cd.file == NULL)
|
||||||
error_exit("Cannot open image file %s", cd.filespecs);
|
error_exit("Cannot open image file '%s'", cd.filespecs);
|
||||||
cd.sector = 0;
|
cd.sector = 0;
|
||||||
cd.offset = 0;
|
cd.offset = 0;
|
||||||
cd.count = 0;
|
cd.count = 0;
|
||||||
|
@ -2348,11 +2425,12 @@ int main(int argc, char **argv)
|
||||||
if (fclose(cd.file) != 0)
|
if (fclose(cd.file) != 0)
|
||||||
{
|
{
|
||||||
cd.file = NULL;
|
cd.file = NULL;
|
||||||
error_exit("File write error in image file %s", cd.filespecs);
|
error_exit("File write error in image file '%s'", cd.filespecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbosity >= NORMAL)
|
if (verbosity >= NORMAL)
|
||||||
puts("CD-ROM image made successfully");
|
puts("CD-ROM image made successfully");
|
||||||
|
}
|
||||||
|
|
||||||
dir_hash_destroy(&specified_files);
|
dir_hash_destroy(&specified_files);
|
||||||
release_memory();
|
release_memory();
|
||||||
|
|
|
@ -2,11 +2,19 @@
|
||||||
* A Linked-List Memory Sort
|
* A Linked-List Memory Sort
|
||||||
* by Philip J. Erdelsky
|
* by Philip J. Erdelsky
|
||||||
* pje@acm.org
|
* pje@acm.org
|
||||||
|
* pje@efgh.com
|
||||||
* http://alumnus.caltech.edu/~pje/
|
* http://alumnus.caltech.edu/~pje/
|
||||||
|
*
|
||||||
|
* Version taken from:
|
||||||
|
* http://alumnus.caltech.edu/~pje/cdmake.txt
|
||||||
|
*
|
||||||
|
* An extended version can be found at:
|
||||||
|
* http://alumnus.caltech.edu/~pje/llmsort.html
|
||||||
|
* http://www.efgh.com/software/llmsort.htm
|
||||||
|
*
|
||||||
|
* Public domain; no restrictions on use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* According to his website, this file was released into the public domain by Philip J. Erdelsky */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void *sort_linked_list(void *p, unsigned index, int (*compare)(void *, void *))
|
void *sort_linked_list(void *p, unsigned index, int (*compare)(void *, void *))
|
||||||
|
|
Loading…
Reference in a new issue