https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c24e09401be57fa270802…
commit c24e09401be57fa2708021fbe995c8bfa651d7f6
Author: Stanislav Motylkov <x86corez(a)gmail.com>
AuthorDate: Sat Jun 25 14:52:03 2022 +0300
Commit: Stanislav Motylkov <x86corez(a)gmail.com>
CommitDate: Mon Jun 27 15:14:03 2022 +0300
[CDMAKE] Remove module
We've been using mkisofs for 5 years now and are not looking back.
- Colin Finck
---
.../applications/devutils/cdmake/CMakeLists.txt | 2 -
.../rosapps/applications/devutils/cdmake/cdmake.c | 2446 --------------------
.../rosapps/applications/devutils/cdmake/config.h | 15 -
.../rosapps/applications/devutils/cdmake/dirhash.c | 238 --
.../rosapps/applications/devutils/cdmake/dirhash.h | 50 -
.../rosapps/applications/devutils/cdmake/llmsort.c | 113 -
.../applications/devutils/cdmake/readme.txt | 96 -
7 files changed, 2960 deletions(-)
diff --git a/modules/rosapps/applications/devutils/cdmake/CMakeLists.txt
b/modules/rosapps/applications/devutils/cdmake/CMakeLists.txt
deleted file mode 100644
index caaeb070884..00000000000
--- a/modules/rosapps/applications/devutils/cdmake/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-
-add_host_tool(cdmake cdmake.c dirhash.c llmsort.c)
diff --git a/modules/rosapps/applications/devutils/cdmake/cdmake.c
b/modules/rosapps/applications/devutils/cdmake/cdmake.c
deleted file mode 100644
index dd05ed51ec6..00000000000
--- a/modules/rosapps/applications/devutils/cdmake/cdmake.c
+++ /dev/null
@@ -1,2446 +0,0 @@
-/*
- * CD-ROM Maker
- * by Philip J. Erdelsky
- * pje(a)acm.org
- *
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
- * PROJECT: ReactOS CD-ROM Maker
- * FILE: tools/cdmake/cdmake.c
- * PURPOSE: CD-ROM Premastering Utility
- * PROGRAMMERS: Eric Kohl
- * Casper S. Hornstrup
- * Filip Navara
- * Magnus Olsen
- * Hermes Belusca-Maito
- *
- * HISTORY:
- *
- * ElTorito-Support
- * by Eric Kohl
- *
- * Linux port
- * by Casper S. Hornstrup
- * chorns(a)users.sourceforge.net
- *
- * Joliet support
- * by Filip Navara
- * xnavara(a)volny.cz
- * Limitations:
- * - No Joliet file name validations
- * - Very bad ISO file name generation
- *
- * Convert long filename to ISO9660 file name by Magnus Olsen
- * magnus(a)greatlord.com
- */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef _WIN32
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-# include <io.h>
-# include <dos.h>
-# ifdef _MSC_VER
-# define R_OK 4
-# endif
-#else
-# if defined(__FreeBSD__) || defined(__APPLE__)
-# include <sys/uio.h>
-# else
-# include <sys/io.h>
-# endif // __FreeBSD__
-# include <errno.h>
-# include <sys/types.h>
-# include <dirent.h>
-# include <unistd.h>
-# define TRUE 1
-# define FALSE 0
-#endif // _WIN32
-#include <ctype.h>
-#include <time.h>
-#include "config.h"
-#include "dirhash.h"
-
-// FIXME! FIXME! Do it in a portable way!!
-typedef unsigned char BYTE;
-typedef unsigned short WORD;
-typedef unsigned long DWORD;
-typedef int BOOL;
-
-// file system parameters
-
-#define MAX_LEVEL 8
-#define MAX_NAME_LENGTH 64
-#define MAX_CDNAME_LENGTH 8
-#define MAX_EXTENSION_LENGTH 10
-#define MAX_CDEXTENSION_LENGTH 3
-#define SECTOR_SIZE 2048
-#define BUFFER_SIZE (8 * SECTOR_SIZE)
-
-#define HIDDEN_FLAG 1
-#define DIRECTORY_FLAG 2
-
-
-struct cd_image
-{
- FILE *file;
- DWORD sector; // sector to receive next byte
- int offset; // offset of next byte in sector
- int count; // number of bytes in buffer
- char filespecs[128];
- BYTE *buffer;
-};
-
-typedef struct _boot_validation_header
-{
- BYTE header_id;
- BYTE platform_id;
-} BOOT_VALIDATION_HEADER, *PBOOT_VALIDATION_HEADER;
-
-typedef struct boot_entry
-{
- struct boot_entry *next_entry;
- BYTE boot_id;
- BYTE boot_emu_type;
- WORD load_segment;
- BYTE system_type;
- WORD sector_count; // boot_image_size
- DWORD load_rba; // boot_image_sector
- // BYTE unused[20];
- char bootimage[512];
-} BOOT_ENTRY, *PBOOT_ENTRY;
-
-typedef struct boot_header
-{
- struct boot_header *next_header;
- BYTE header_id;
- BYTE platform_id;
- WORD num_entries;
- // char id_string[28];
- PBOOT_ENTRY entry_list;
-} BOOT_HEADER, *PBOOT_HEADER;
-
-typedef struct date_and_time
-{
- BYTE second;
- BYTE minute;
- BYTE hour;
- BYTE day;
- BYTE month;
- WORD year;
-} DATE_AND_TIME, *PDATE_AND_TIME;
-
-typedef struct directory_record
-{
- struct directory_record *next_in_directory;
- struct directory_record *next_in_path_table; /* directory record only */
- struct directory_record *next_in_memory;
- struct directory_record *first_record; /* directory record only */
- struct directory_record *parent;
- BYTE flags;
- char name[MAX_NAME_LENGTH+1];
- char name_on_cd[MAX_CDNAME_LENGTH+1];
- char extension[MAX_EXTENSION_LENGTH+1];
- char extension_on_cd[MAX_CDEXTENSION_LENGTH+1];
- char *joliet_name;
- const char *orig_name;
- DATE_AND_TIME date_and_time;
- DWORD sector;
- DWORD size;
- DWORD joliet_sector;
- DWORD joliet_size;
- unsigned level; /* directory record only */
- WORD path_table_index; /* directory record only */
-} DIR_RECORD, *PDIR_RECORD;
-
-typedef enum directory_record_type
-{
- DOT_RECORD,
- DOT_DOT_RECORD,
- SUBDIRECTORY_RECORD,
- FILE_RECORD
-} DIR_RECORD_TYPE, *PDIR_RECORD_TYPE;
-
-
-PDIR_RECORD sort_linked_list(PDIR_RECORD,
- unsigned, int (*)(PDIR_RECORD, PDIR_RECORD));
-
-
-static char DIRECTORY_TIMESTAMP[] = "~Y$'KOR$.3K&";
-
-static struct cd_image cd;
-DIR_RECORD root;
-
-char volume_label[32];
-char source[512];
-char *end_source;
-
-enum {QUIET, NORMAL, VERBOSE} verbosity;
-BOOL show_progress;
-
-BOOL scan_files_only = FALSE;
-// BOOL compute_crc = FALSE;
-
-/*
- * ISO 9660 information
- */
-DWORD size_limit;
-BOOL accept_punctuation_marks;
-
-DWORD total_sectors;
-DWORD path_table_size;
-DWORD little_endian_path_table_sector;
-DWORD big_endian_path_table_sector;
-
-
-/*
- * Stats
- */
-DWORD number_of_files;
-DWORD bytes_in_files;
-DWORD unused_bytes_at_ends_of_files;
-DWORD number_of_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 multi_boot; // TRUE/FALSE: multi/single-boot CD-ROM
-DWORD boot_catalog_sector;
-BOOT_VALIDATION_HEADER boot_validation_header;
-BOOT_ENTRY default_boot_entry;
-PBOOT_HEADER boot_header_list;
-
-/*
- * Joliet information
- */
-BOOL joliet;
-DWORD joliet_path_table_size;
-DWORD joliet_little_endian_path_table_sector;
-DWORD joliet_big_endian_path_table_sector;
-
-/*
- * 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
-as 4,294,967,295 for the largest possible number, and returns a pointer to a
-static buffer containing the result. It suppresses leading zeros and commas,
-but optionally pads the result with blanks at the left so the result is always
-exactly 13 characters long (excluding the terminating zero).
-
-CAUTION: A statement containing more than one call on this function, such as
-printf("%s, %s", edit_with_commas(a), edit_with_commas(b)), will produce
-incorrect results because all calls use the same static bufffer.
------------------------------------------------------------------------------*/
-
-static char *edit_with_commas(DWORD x, BOOL pad)
-{
- static char s[14];
- unsigned i = 13;
- do
- {
- if (i % 4 == 2) s[--i] = ',';
- s[--i] = (char)(x % 10 + '0');
- } while ((x/=10) != 0);
- if (pad)
- {
- while (i > 0) s[--i] = ' ';
- }
- return s + i;
-}
-
-/*-----------------------------------------------------------------------------
-This function releases all allocated memory blocks.
------------------------------------------------------------------------------*/
-
-static void release_memory(void)
-{
- while (boot_header_list)
- {
- PBOOT_HEADER next_header = boot_header_list->next_header;
-
- while (boot_header_list->entry_list)
- {
- PBOOT_ENTRY next_entry = boot_header_list->entry_list->next_entry;
- free(boot_header_list->entry_list);
- boot_header_list->entry_list = next_entry;
- }
-
- free(boot_header_list);
- boot_header_list = next_header;
- }
-
- while (root.next_in_memory != NULL)
- {
- PDIR_RECORD next = root.next_in_memory->next_in_memory;
- if (joliet)
- free(root.next_in_memory->joliet_name);
- free(root.next_in_memory);
- root.next_in_memory = next;
- }
- if (joliet)
- free(root.joliet_name);
-
- if (cd.buffer != NULL)
- {
- free(cd.buffer);
- cd.buffer = NULL;
- }
-}
-
-/*-----------------------------------------------------------------------------
-This function edits and displays an error message and then jumps back to the
-error exit point in main().
------------------------------------------------------------------------------*/
-
-static
-DECLSPEC_NORETURN
-void error_exit(const char* fmt, ...)
-{
- va_list arg;
-
- va_start(arg, fmt);
- vprintf(fmt, arg);
- va_end(arg);
- printf("\n");
- if (cd.file != NULL)
- fclose(cd.file);
- release_memory();
- exit(1);
-}
-
-/*-----------------------------------------------------------------------------
-This function, which is called only on the second pass, and only when the
-buffer is not empty, flushes the buffer to the CD-ROM image.
------------------------------------------------------------------------------*/
-
-static void flush_buffer(void)
-{
- if (fwrite(cd.buffer, cd.count, 1, cd.file) < 1)
- error_exit("File write error");
- cd.count = 0;
- if (show_progress)
- {
- printf("\r%s ",
- edit_with_commas((total_sectors - cd.sector) * SECTOR_SIZE, TRUE));
- }
-}
-
-/*-----------------------------------------------------------------------------
-This function writes a single byte to the CD-ROM image. On the first pass (in
-which cd.handle < 0), it does not actually write anything but merely updates
-the file pointer as though the byte had been written.
------------------------------------------------------------------------------*/
-
-static void write_byte(BYTE x)
-{
- if (cd.file != NULL)
- {
- cd.buffer[cd.count] = x;
- if (++cd.count == BUFFER_SIZE)
- flush_buffer();
- }
- if (++cd.offset == SECTOR_SIZE)
- {
- cd.sector++;
- cd.offset = 0;
- }
-}
-
-/*-----------------------------------------------------------------------------
-These functions write a word or double word to the CD-ROM image with the
-specified endianity.
------------------------------------------------------------------------------*/
-
-static void write_little_endian_word(WORD x)
-{
- write_byte((BYTE)x);
- write_byte((BYTE)(x >> 8));
-}
-
-static void write_big_endian_word(WORD x)
-{
- write_byte((BYTE)(x >> 8));
- write_byte((BYTE)x);
-}
-
-static void write_both_endian_word(WORD x)
-{
- write_little_endian_word(x);
- write_big_endian_word(x);
-}
-
-static void write_little_endian_dword(DWORD x)
-{
- write_byte((BYTE)x);
- write_byte((BYTE)(x >> 8));
- write_byte((BYTE)(x >> 16));
- write_byte((BYTE)(x >> 24));
-}
-
-static void write_big_endian_dword(DWORD x)
-{
- write_byte((BYTE)(x >> 24));
- write_byte((BYTE)(x >> 16));
- write_byte((BYTE)(x >> 8));
- write_byte((BYTE)x);
-}
-
-static void write_both_endian_dword(DWORD x)
-{
- write_little_endian_dword(x);
- write_big_endian_dword(x);
-}
-
-/*-----------------------------------------------------------------------------
-This function writes enough zeros to fill out the end of a sector, and leaves
-the file pointer at the beginning of the next sector. If the file pointer is
-already at the beginning of a sector, it writes nothing.
------------------------------------------------------------------------------*/
-
-static void fill_sector(void)
-{
- while (cd.offset != 0)
- write_byte(0);
-}
-
-/*-----------------------------------------------------------------------------
-This function writes a string to the CD-ROM image. The terminating \0 is not
-written.
------------------------------------------------------------------------------*/
-
-static void write_string(char *s)
-{
- while (*s != 0)
- write_byte(*s++);
-}
-
-static void write_bytecounted_string(unsigned bytecount, char *s, char padding)
-{
- while (*s != 0 && bytecount != 0)
- {
- write_byte(*s++);
- bytecount--;
- }
- while (bytecount != 0)
- {
- write_byte(padding);
- bytecount--;
- }
-}
-
-/*-----------------------------------------------------------------------------
-This function writes a ansi string as a big endian unicode string to the CD-ROM
-image. The terminating \0 is not written.
------------------------------------------------------------------------------*/
-
-static void write_string_as_big_endian_unicode(char *s)
-{
- while (*s != 0)
- {
- write_big_endian_word(*s++);
- }
-}
-
-static void write_bytecounted_string_as_big_endian_unicode(unsigned bytecount, char *s,
char padding)
-{
- unsigned wordcount = bytecount / 2;
-
- while (*s != 0 && wordcount != 0)
- {
- write_big_endian_word(*s++);
- wordcount--;
- }
- while (wordcount != 0)
- {
- write_big_endian_word(padding);
- wordcount--;
- }
-
- if (bytecount % 2 != 0)
- write_byte(padding);
-}
-
-/*-----------------------------------------------------------------------------
-This function writes a block of identical bytes to the CD-ROM image.
------------------------------------------------------------------------------*/
-
-static void write_block(unsigned count, BYTE value)
-{
- while (count != 0)
- {
- write_byte(value);
- count--;
- }
-}
-
-/*-----------------------------------------------------------------------------
-This function writes a block of identical big endian words to the CD-ROM image.
------------------------------------------------------------------------------*/
-
-static void write_word_block(unsigned count, WORD value)
-{
- while (count != 0)
- {
- write_big_endian_word(value);
- count--;
- }
-}
-
-/*-----------------------------------------------------------------------------
-This function writes a directory record to the CD_ROM image.
------------------------------------------------------------------------------*/
-
-static void
-write_directory_record(PDIR_RECORD d,
- DIR_RECORD_TYPE DirType,
- BOOL joliet)
-{
- unsigned identifier_size;
- unsigned record_size;
-
- if (joliet)
- {
- if (DirType == DOT_RECORD || DirType == DOT_DOT_RECORD)
- identifier_size = 1;
- else
- identifier_size = strlen(d->joliet_name) * 2;
- }
- else
- {
- switch (DirType)
- {
- case DOT_RECORD:
- case DOT_DOT_RECORD:
- identifier_size = 1;
- break;
- case SUBDIRECTORY_RECORD:
- /*printf("Subdir: %s\n", d->name_on_cd);*/
- identifier_size = strlen(d->name_on_cd);
- break;
- case FILE_RECORD:
- /*printf("File: %s.%s -> %s.%s\n", d->name,
d->extension, d->name_on_cd, d->extension_on_cd);*/
- identifier_size = strlen(d->name_on_cd) + 2;
- if (d->extension_on_cd[0] != 0)
- identifier_size += 1 + strlen(d->extension_on_cd);
- break;
- default:
- identifier_size = 1;
- break;
- }
- }
- record_size = 33 + identifier_size;
- if ((identifier_size & 1) == 0)
- record_size++;
- if (cd.offset + record_size > SECTOR_SIZE)
- fill_sector();
- write_byte((BYTE)record_size);
- write_byte(0); // number of sectors in extended attribute record
- if (joliet)
- {
- write_both_endian_dword(d->joliet_sector);
- write_both_endian_dword(d->joliet_size);
- }
- else
- {
- write_both_endian_dword(d->sector);
- write_both_endian_dword(d->size);
- }
- write_byte((BYTE)(d->date_and_time.year - 1900));
- write_byte(d->date_and_time.month);
- write_byte(d->date_and_time.day);
- write_byte(d->date_and_time.hour);
- write_byte(d->date_and_time.minute);
- write_byte(d->date_and_time.second);
- write_byte(0); // GMT offset
- write_byte(d->flags);
- write_byte(0); // file unit size for an interleaved file
- write_byte(0); // interleave gap size for an interleaved file
- write_both_endian_word(1); // volume sequence number
- write_byte((BYTE)identifier_size);
- switch (DirType)
- {
- case DOT_RECORD:
- write_byte(0);
- break;
- case DOT_DOT_RECORD:
- write_byte(1);
- break;
- case SUBDIRECTORY_RECORD:
- if (joliet)
- write_string_as_big_endian_unicode(d->joliet_name);
- else
- write_string(d->name_on_cd);
- break;
- case FILE_RECORD:
- if (joliet)
- {
- write_string_as_big_endian_unicode(d->joliet_name);
- }
- else
- {
- write_string(d->name_on_cd);
- if (d->extension_on_cd[0] != 0)
- {
- write_byte('.');
- write_string(d->extension_on_cd);
- }
- write_string(";1");
- }
- break;
- }
- if ((identifier_size & 1) == 0)
- write_byte(0);
-}
-
-/*-----------------------------------------------------------------------------
-This function converts the date and time words from an ffblk structure and
-puts them into a date_and_time structure.
------------------------------------------------------------------------------*/
-
-static void convert_date_and_time(PDATE_AND_TIME dt, time_t *time)
-{
- struct tm *timedef;
- timedef = gmtime(time);
-
- dt->second = timedef->tm_sec;
- dt->minute = timedef->tm_min;
- dt->hour = timedef->tm_hour;
- dt->day = timedef->tm_mday;
- dt->month = timedef->tm_mon + 1;
- dt->year = timedef->tm_year + 1900;
-}
-
-/*-----------------------------------------------------------------------------
-This function checks the specified character, if necessary, and
-generates an error if it is a punctuation mark other than an underscore.
-It also converts small letters to capital letters and returns the
-result.
------------------------------------------------------------------------------*/
-
-static int check_for_punctuation(int c, const char *name)
-{
- c = toupper(c & 0xFF);
- if (!accept_punctuation_marks && !isalnum(c) && c != '_')
- error_exit("Punctuation mark in %s", name);
- return c;
-}
-
-/*-----------------------------------------------------------------------------
-This function checks to see if there's a cdname conflict.
------------------------------------------------------------------------------*/
-
-#if defined(_WIN32) && !defined(strcasecmp)
-#define strcasecmp stricmp
-#endif // _WIN32
-
-static BOOL cdname_exists(PDIR_RECORD d)
-{
- PDIR_RECORD p = d->parent->first_record;
- while (p)
- {
- if ( p != d
- && !strcasecmp(p->name_on_cd, d->name_on_cd)
- && !strcasecmp(p->extension_on_cd, d->extension_on_cd) )
- return TRUE;
- p = p->next_in_directory;
- }
- return FALSE;
-}
-
-static void parse_filename_into_dirrecord(const char* filename, PDIR_RECORD d, BOOL dir)
-{
- const char *s = filename;
- char *t = d->name_on_cd;
- char *n = d->name;
- int joliet_length;
- int filename_counter;
- filename_counter = 1;
- while (*s != 0)
- {
- if (*s == '.')
- {
- s++;
- break;
- }
-
- if ((size_t)(t-d->name_on_cd) < sizeof(d->name_on_cd)-1)
- *t++ = check_for_punctuation(*s, filename);
- else if (!joliet)
- error_exit("'%s' is not ISO-9660, aborting...", filename);
-
- if ((size_t)(n-d->name) < sizeof(d->name)-1)
- *n++ = *s;
- else if (!joliet)
- error_exit("'%s' is not ISO-9660, aborting...", filename);
- s++;
- }
- // Check for extension length
- if (!joliet && strlen(s) > MAX_EXTENSION_LENGTH)
- {
- error_exit("'%s' has too long extension, aborting...",
filename);
- }
- *t = 0;
- strcpy(d->extension, s);
- t = d->extension_on_cd;
- while (*s != 0)
- {
- if ((size_t)(t-d->extension_on_cd) < sizeof(d->extension_on_cd)-1)
- *t++ = check_for_punctuation(*s, filename);
- else if (!joliet)
- error_exit("'%s' is not ISO-9660, aborting...", filename);
- s++;
- }
- *t = 0;
- *n = 0;
-
- if (dir)
- {
- if (d->extension[0] != 0)
- {
- if (!joliet)
- error_exit("Directory with extension '%s'", filename);
- }
- d->flags = DIRECTORY_FLAG;
- } else
- {
- d->flags = 0;
- }
-
- filename_counter = 1;
- while (cdname_exists(d))
- {
- // the file name must be at least 8 chars long
- if (strlen(d->name_on_cd)<8)
- error_exit("'%s' is a duplicate file name, aborting...",
filename);
-
- if ((d->name_on_cd[8] == '.') && (strlen(d->name_on_cd)
< 13))
- error_exit("'%s' is a duplicate file name, aborting...",
filename);
-
- // max 255 times for equal short filename
- if (filename_counter>255)
- error_exit("'%s' is a duplicate file name, aborting...",
filename);
-
- d->name_on_cd[8] = '~';
- memset(&d->name_on_cd[9],0,5);
- sprintf(&d->name_on_cd[9],"%d",filename_counter);
- filename_counter++;
- }
-
- if (joliet)
- {
- joliet_length = strlen(filename);
- if (joliet_length > 64)
- error_exit("'%s' is not Joliet, aborting...", filename);
- d->joliet_name = malloc(joliet_length + 1);
- if (d->joliet_name == NULL)
- error_exit("Insufficient memory");
- strcpy(d->joliet_name, filename);
- }
-}
-
-/*-----------------------------------------------------------------------------
-This function creates a new directory record with the information from the
-specified ffblk. It links it into the beginning of the directory list
-for the specified parent and returns a pointer to the new record.
------------------------------------------------------------------------------*/
-
-#ifdef _WIN32
-
-/* Win32 version */
-PDIR_RECORD
-new_directory_record(struct _finddata_t *f,
- PDIR_RECORD parent)
-{
- PDIR_RECORD d;
-
- d = calloc(1, sizeof(*d));
- if (d == NULL)
- error_exit("Insufficient memory");
- d->next_in_memory = root.next_in_memory;
- root.next_in_memory = d;
-
- /* I need the parent set before calling parse_filename_into_dirrecord(),
- because that functions checks for duplicate file names*/
- d->parent = parent;
- parse_filename_into_dirrecord(f->name, d, f->attrib & _A_SUBDIR);
-
- convert_date_and_time(&d->date_and_time, &f->time_write);
- d->flags |= f->attrib & _A_HIDDEN ? HIDDEN_FLAG : 0;
- d->size = d->joliet_size = f->size;
- d->next_in_directory = parent->first_record;
- parent->first_record = d;
- return d;
-}
-
-#else
-
-/* Linux version */
-PDIR_RECORD
-new_directory_record(struct dirent *entry,
- struct stat *stbuf,
- PDIR_RECORD parent)
-{
- PDIR_RECORD d;
-
- d = calloc(1, sizeof(*d));
- if (d == NULL)
- error_exit("Insufficient memory");
- d->next_in_memory = root.next_in_memory;
- root.next_in_memory = d;
-
- /* I need the parent set before calling parse_filename_into_dirrecord(),
- because that functions checks for duplicate file names*/
- d->parent = parent;
-#ifdef HAVE_D_TYPE
- parse_filename_into_dirrecord(entry->d_name, d, entry->d_type == DT_DIR);
-#else
- parse_filename_into_dirrecord(entry->d_name, d, S_ISDIR(stbuf->st_mode));
-#endif
-
- convert_date_and_time(&d->date_and_time, &stbuf->st_mtime);
- d->flags |= entry->d_name[0] == '.' ? HIDDEN_FLAG : 0;
- d->size = d->joliet_size = stbuf->st_size;
- d->next_in_directory = parent->first_record;
- parent->first_record = d;
- return d;
-}
-
-#endif
-
-/*-----------------------------------------------------------------------------
-This function compares two directory records according to the ISO9660 rules
-for directory sorting and returns a negative value if p is before q, or a
-positive value if p is after q.
------------------------------------------------------------------------------*/
-
-static int compare_directory_order(PDIR_RECORD p, PDIR_RECORD q)
-{
- int n = strcmp(p->name_on_cd, q->name_on_cd);
- if (n == 0)
- n = strcmp(p->extension_on_cd, q->extension_on_cd);
- return n;
-}
-
-/*-----------------------------------------------------------------------------
-This function compares two directory records (which must represent
-directories) according to the ISO9660 rules for path table sorting and returns
-a negative value if p is before q, or a positive vlaue if p is after q.
------------------------------------------------------------------------------*/
-
-static int compare_path_table_order(PDIR_RECORD p, PDIR_RECORD q)
-{
- int n = p->level - q->level;
- if (p == q)
- return 0;
- if (n == 0)
- {
- n = compare_path_table_order(p->parent, q->parent);
- if (n == 0)
- n = compare_directory_order(p, q);
- }
- return n;
-}
-
-/*-----------------------------------------------------------------------------
-This function appends the specified string to the buffer source[].
------------------------------------------------------------------------------*/
-
-static void append_string_to_source(char *s)
-{
- while (*s != 0)
- *end_source++ = *s++;
-}
-
-/*-----------------------------------------------------------------------------
-This function scans all files from the current source[] (which must end in \,
-and represents a directory already in the database as d),
-and puts the appropriate directory records into the database in memory, with
-the specified root. It calls itself recursively to scan all subdirectories.
------------------------------------------------------------------------------*/
-
-#ifdef _WIN32
-
-static void
-make_directory_records(PDIR_RECORD d)
-{
- PDIR_RECORD new_d;
- struct _finddata_t f;
- char *old_end_source;
- int findhandle;
-
- d->first_record = NULL;
- strcpy(end_source, "*.*");
-
- findhandle = _findfirst(source, &f);
- if (findhandle != 0)
- {
- do
- {
- if ((f.attrib & (_A_HIDDEN | _A_SUBDIR)) == 0 && f.name[0] !=
'.')
- {
- if (strcmp(f.name, DIRECTORY_TIMESTAMP) == 0)
- {
- convert_date_and_time(&d->date_and_time, &f.time_write);
- }
- else
- {
- if (verbosity == VERBOSE)
- {
- old_end_source = end_source;
- strcpy(end_source, f.name);
- printf("%d: file %s\n", d->level, source);
- end_source = old_end_source;
- }
- (void) new_directory_record(&f, d);
- }
- }
- }
- while (_findnext(findhandle, &f) == 0);
-
- _findclose(findhandle);
- }
-
- strcpy(end_source, "*.*");
- findhandle = _findfirst(source, &f);
- if (findhandle)
- {
- do
- {
- if (f.attrib & _A_SUBDIR && f.name[0] != '.')
- {
- old_end_source = end_source;
- append_string_to_source(f.name);
- *end_source++ = DIR_SEPARATOR_CHAR;
- if (verbosity == VERBOSE)
- {
- *end_source = 0;
- printf("%d: directory %s\n", d->level + 1, source);
- }
- if (d->level < MAX_LEVEL)
- {
- new_d = new_directory_record(&f, d);
- new_d->next_in_path_table = root.next_in_path_table;
- root.next_in_path_table = new_d;
- new_d->level = d->level + 1;
- make_directory_records(new_d);
- }
- else
- {
- error_exit("Directory is nested too deep");
- }
- end_source = old_end_source;
- }
- }
- while (_findnext(findhandle, &f) == 0);
-
- _findclose(findhandle);
- }
-
- // sort directory
- d->first_record = sort_linked_list(d->first_record, 0,
compare_directory_order);
-}
-
-#else
-
-/* Linux version */
-static void
-make_directory_records(PDIR_RECORD d)
-{
- PDIR_RECORD new_d;
- DIR *dirp;
- struct dirent *entry;
- char *old_end_source;
- struct stat stbuf;
- char buf[MAX_PATH];
-
- d->first_record = NULL;
-
-#ifdef HAVE_D_TYPE
- dirp = opendir(source);
- if (dirp != NULL)
- {
- while ((entry = readdir(dirp)) != NULL)
- {
- if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name,
"..") == 0)
- continue; // skip self and parent
-
- if (entry->d_type == DT_REG) // normal file
- {
- // Check for an absolute path
- if (source[0] == DIR_SEPARATOR_CHAR)
- {
- strcpy(buf, source);
- strcat(buf, DIR_SEPARATOR_STRING);
- strcat(buf, entry->d_name);
- }
- else
- {
- if (!getcwd(buf, sizeof(buf)))
- error_exit("Cannot get CWD: %s\n", strerror(errno));
- strcat(buf, DIR_SEPARATOR_STRING);
- strcat(buf, source);
- strcat(buf, entry->d_name);
- }
-
- if (stat(buf, &stbuf) == -1)
- {
- error_exit("Cannot access '%s' (%s)\n", buf,
strerror(errno));
- return;
- }
-
- if (strcmp(entry->d_name, DIRECTORY_TIMESTAMP) == 0)
- {
- convert_date_and_time(&d->date_and_time,
&stbuf.st_ctime);
- }
- else
- {
- if (verbosity == VERBOSE)
- {
- printf("%d: file %s\n", d->level, buf);
- }
- (void) new_directory_record(entry, &stbuf, d);
- }
- }
- }
- closedir(dirp);
- }
- else
- {
- error_exit("Cannot open '%s'\n", source);
- return;
- }
-
- dirp = opendir(source);
- if (dirp != NULL)
- {
- while ((entry = readdir(dirp)) != NULL)
- {
- if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name,
"..") == 0)
- continue; // skip self and parent
-
- if (entry->d_type == DT_DIR) // directory
- {
- old_end_source = end_source;
- append_string_to_source(entry->d_name);
- *end_source++ = DIR_SEPARATOR_CHAR;
- *end_source = 0;
- if (verbosity == VERBOSE)
- {
- printf("%d: directory %s\n", d->level + 1, source);
- }
- if (d->level < MAX_LEVEL)
- {
- // Check for an absolute path
- if (source[0] == DIR_SEPARATOR_CHAR)
- {
- strcpy(buf, source);
- }
- else
- {
- if (!getcwd(buf, sizeof(buf)))
- error_exit("Cannot get CWD: %s\n",
strerror(errno));
- strcat(buf, DIR_SEPARATOR_STRING);
- strcat(buf, source);
- }
-
- if (stat(buf, &stbuf) == -1)
- {
- error_exit("Cannot access '%s' (%s)\n", buf,
strerror(errno));
- return;
- }
- new_d = new_directory_record(entry, &stbuf, d);
- new_d->next_in_path_table = root.next_in_path_table;
- root.next_in_path_table = new_d;
- new_d->level = d->level + 1;
- make_directory_records(new_d);
- }
- else
- {
- error_exit("Directory is nested too deep");
- }
- end_source = old_end_source;
- *end_source = 0;
- }
- }
- closedir(dirp);
- }
- else
- {
- error_exit("Cannot open '%s'\n", source);
- return;
- }
-
-#else
-
- dirp = opendir(source);
- if (dirp != NULL)
- {
- while ((entry = readdir(dirp)) != NULL)
- {
- if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name,
"..") == 0)
- continue; // skip self and parent
-
- // Check for an absolute path
- if (source[0] == DIR_SEPARATOR_CHAR)
- {
- strcpy(buf, source);
- strcat(buf, DIR_SEPARATOR_STRING);
- strcat(buf, entry->d_name);
- }
- else
- {
- if (!getcwd(buf, sizeof(buf)))
- error_exit("Cannot get CWD: %s\n", strerror(errno));
- strcat(buf, DIR_SEPARATOR_STRING);
- strcat(buf, source);
- strcat(buf, entry->d_name);
- }
-
- if (stat(buf, &stbuf) == -1)
- {
- error_exit("Cannot access '%s' (%s)\n", buf,
strerror(errno));
- return;
- }
-
- if (S_ISDIR(stbuf.st_mode))
- {
- old_end_source = end_source;
- append_string_to_source(entry->d_name);
- *end_source++ = DIR_SEPARATOR_CHAR;
- *end_source = 0;
- if (verbosity == VERBOSE)
- {
- printf("%d: directory %s\n", d->level + 1, source);
- }
-
- if (d->level < MAX_LEVEL)
- {
- new_d = new_directory_record(entry, &stbuf, d);
- new_d->next_in_path_table = root.next_in_path_table;
- root.next_in_path_table = new_d;
- new_d->level = d->level + 1;
- make_directory_records(new_d);
- }
- else
- {
- error_exit("Directory is nested too deep");
- }
-
- end_source = old_end_source;
- *end_source = 0;
- }
- else if (S_ISREG(stbuf.st_mode))
- {
- if (strcmp(entry->d_name, DIRECTORY_TIMESTAMP) == 0)
- {
- convert_date_and_time(&d->date_and_time,
&stbuf.st_ctime);
- }
- else
- {
- if (verbosity == VERBOSE)
- {
- printf("%d: file %s\n", d->level, buf);
- }
- (void) new_directory_record(entry, &stbuf, d);
- }
- }
- }
- closedir(dirp);
- }
- else
- {
- error_exit("Cannot open '%s'\n", source);
- return;
- }
-
-#endif
-
- // sort directory
- d->first_record = sort_linked_list(d->first_record, 0,
compare_directory_order);
-}
-
-#endif
-
-static PDIR_RECORD
-new_empty_dirrecord(PDIR_RECORD d, BOOL directory)
-{
- PDIR_RECORD new_d;
- new_d = calloc(1, sizeof(*new_d));
- new_d->parent = d;
- new_d->level = d->level + 1;
- new_d->next_in_directory = d->first_record;
- d->first_record = new_d;
- new_d->next_in_memory = root.next_in_memory;
- root.next_in_memory = new_d;
- new_d->date_and_time = d->date_and_time;
- if (directory)
- {
- new_d->flags |= DIRECTORY_FLAG;
- new_d->next_in_path_table = root.next_in_path_table;
- root.next_in_path_table = new_d;
- }
- return new_d;
-}
-
-#ifdef _WIN32
-static BOOL
-get_cd_file_time(HANDLE handle, PDATE_AND_TIME cd_time_info)
-{
- FILETIME file_time;
- SYSTEMTIME sys_time;
-
- if (!GetFileTime(handle, NULL, NULL, &file_time))
- return FALSE;
-
- FileTimeToSystemTime(&file_time, &sys_time);
- memset(cd_time_info, 0, sizeof(*cd_time_info));
-
- cd_time_info->year = sys_time.wYear;
- cd_time_info->month = sys_time.wMonth;
- cd_time_info->day = sys_time.wDay;
- cd_time_info->hour = sys_time.wHour;
- cd_time_info->minute = sys_time.wMinute;
- cd_time_info->second = sys_time.wSecond;
-
- return TRUE;
-}
-#endif
-
-static void
-scan_specified_files(PDIR_RECORD d, struct target_dir_entry *dir)
-{
- PDIR_RECORD new_d;
-#ifdef _WIN32
- HANDLE open_file;
- LARGE_INTEGER file_size;
-#else
- struct stat stbuf;
-#endif
- struct target_file *file;
- struct target_dir_entry *child;
-
- d->first_record = NULL;
-
- for (file = dir->head; file; file = file->next)
- {
- if (strcmp(file->target_name, DIRECTORY_TIMESTAMP) == 0)
- {
-#ifdef _WIN32
- if ((open_file = CreateFileA(file->source_name,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL)) == INVALID_HANDLE_VALUE)
- {
- error_exit("Cannot open timestamp file '%s'\n",
file->source_name);
- }
-
- if (!get_cd_file_time(open_file, &d->date_and_time))
- {
- error_exit("Cannot stat timestamp file '%s'\n",
file->source_name);
- }
- CloseHandle(open_file);
-#else
- if (stat(file->target_name, &stbuf) == -1)
- {
- error_exit("Cannot stat timestamp file '%s'\n",
file->source_name);
- }
- convert_date_and_time(&d->date_and_time, &stbuf.st_ctime);
-#endif
- }
- else
- {
- if (verbosity == VERBOSE)
- {
- printf("%d: file %s (from %s)\n",
- d->level,
- file->target_name,
- file->source_name);
- }
- new_d = new_empty_dirrecord(d, FALSE);
- parse_filename_into_dirrecord(file->target_name, new_d, FALSE);
-#ifdef _WIN32
- if ((open_file = CreateFileA(file->source_name,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL)) == INVALID_HANDLE_VALUE)
- {
- error_exit("Cannot open file '%s'\n",
file->source_name);
- }
- if (!get_cd_file_time(open_file, &new_d->date_and_time))
- {
- error_exit("Cannot stat file '%s'\n",
file->source_name);
- }
- if (!GetFileSizeEx(open_file, &file_size))
- {
- error_exit("Cannot get file size of '%s'\n",
file->source_name);
- }
- new_d->size = new_d->joliet_size = file_size.QuadPart;
- new_d->orig_name = file->source_name;
- CloseHandle(open_file);
-#else
- if (stat(file->source_name, &stbuf) == -1)
- {
- error_exit("Cannot find '%s' (target '%s')\n",
- file->source_name,
- file->target_name);
- }
- convert_date_and_time(&new_d->date_and_time, &stbuf.st_mtime);
- new_d->size = new_d->joliet_size = stbuf.st_size;
- new_d->orig_name = file->source_name;
-#endif
- }
- }
-
- for (child = dir->child; child; child = child->next)
- {
- if (verbosity == VERBOSE)
- {
- printf("%d: directory %s\n", d->level, child->case_name);
- }
- new_d = new_empty_dirrecord(d, TRUE);
- parse_filename_into_dirrecord(child->case_name, new_d, TRUE);
- scan_specified_files(new_d, child);
- }
-
- /* sort directory */
- d->first_record = sort_linked_list(d->first_record,
- 0,
- compare_directory_order);
- source[0] = 0;
- end_source = source;
-}
-
-/*-----------------------------------------------------------------------------
-This function loads the file specifications for the file or directory
-corresponding to the specified directory record into the source[] buffer. It
-is recursive.
------------------------------------------------------------------------------*/
-
-static void get_file_specifications(PDIR_RECORD d)
-{
- if (d != &root)
- {
- get_file_specifications(d->parent);
- if (d->joliet_name == NULL)
- append_string_to_source(d->name);
- else
- append_string_to_source(d->joliet_name);
-
- if (((d->flags & DIRECTORY_FLAG) == 0 || joliet) &&
d->extension[0] != 0)
- {
- if (d->joliet_name == NULL)
- {
- *end_source++ = '.';
- append_string_to_source(d->extension);
- }
- }
- if (d->flags & DIRECTORY_FLAG)
- *end_source++ = DIR_SEPARATOR_CHAR;
- }
-}
-
-static void get_time_string(char *str)
-{
- sprintf(str, "%04d%02d%02d%02d%02d%02d00",
- root.date_and_time.year,
- root.date_and_time.month,
- root.date_and_time.day,
- root.date_and_time.hour,
- root.date_and_time.minute,
- root.date_and_time.second);
-}
-
-static BOOL write_from_file(FILE *file, DWORD size)
-{
- if (cd.file != NULL)
- {
- int n;
-
- fseek(file, 0, SEEK_SET);
- while (size > 0)
- {
- n = BUFFER_SIZE - cd.count;
- if ((DWORD)n > size)
- n = size;
-
- if (fread(cd.buffer + cd.count, n, 1, file) < 1)
- return FALSE;
-
- cd.count += n;
- if (cd.count == BUFFER_SIZE)
- flush_buffer();
- cd.sector += n / SECTOR_SIZE;
- cd.offset += n % SECTOR_SIZE;
- size -= n;
- }
- }
- else
- {
- cd.sector += size / SECTOR_SIZE;
- cd.offset += size % SECTOR_SIZE;
- }
-
- return TRUE;
-}
-
-static void pass(void)
-{
- PDIR_RECORD d, q;
- unsigned int index;
- unsigned int name_length;
- DWORD size;
- DWORD number_of_sectors;
- char *old_end_source;
- FILE *file;
-
- PBOOT_HEADER header;
- PBOOT_ENTRY entry;
-
- char timestring[17];
-
- get_time_string(timestring);
-
- // first 16 sectors are zeros
- write_block(16 * SECTOR_SIZE, 0);
-
-
- // Primary Volume Descriptor
- if (make_bridged_udf)
- {
- write_string("\1CD001\1");
- write_byte(0);
- write_bytecounted_string(32, "", ' '); // system
identifier
- write_bytecounted_string(32, volume_label, ' '); // volume label
-
- write_block(8, 0);
- write_both_endian_dword(total_sectors);
- write_block(32, 0);
- write_both_endian_word(1); // volume set size
- write_both_endian_word(1); // volume sequence number
- write_both_endian_word(2048); // sector size
- write_both_endian_dword(path_table_size);
- write_little_endian_dword(little_endian_path_table_sector);
- write_little_endian_dword(0); // second little endian path table
- write_big_endian_dword(big_endian_path_table_sector);
- write_big_endian_dword(0); // second big endian path table
- write_directory_record(&root, DOT_RECORD, FALSE);
-
- write_bytecounted_string(128, volume_label, ' '); // volume set
identifier
- write_bytecounted_string(128, PUBLISHER_ID, ' '); // publisher
identifier
- write_bytecounted_string(128, DATA_PREP_ID, ' '); // data preparer
identifier
- write_bytecounted_string(128, APP_ID, ' '); // application
identifier
-
- write_bytecounted_string(37, "", ' '); // copyright file
identifier
- write_bytecounted_string(37, "", ' '); // abstract file
identifier
- write_bytecounted_string(37, "", ' '); // bibliographic file
identifier
-
- write_string(timestring); // volume creation
- write_byte(0);
- write_string(timestring); // most recent modification
- write_byte(0);
- write_string("0000000000000000"); // volume expires
- write_byte(0);
- write_string("0000000000000000"); // volume is effective
- write_byte(0);
- write_byte(1);
- write_byte(0);
- fill_sector();
- }
-
- // Boot Volume Descriptor
- if (eltorito)
- {
- write_byte(0); // Boot record ID
- write_string("CD001\1");
- write_bytecounted_string(32, "EL TORITO SPECIFICATION", 0); //
El-Torito identifier
- write_block(32, 0); // unused
- write_little_endian_dword(boot_catalog_sector); // pointer to boot catalog
- fill_sector();
- }
-
- // Supplementary Volume Descriptor
- if (joliet)
- {
- write_string("\2CD001\1");
- write_byte(0);
- write_bytecounted_string_as_big_endian_unicode(32, "", ' ');
// system identifier
- write_bytecounted_string_as_big_endian_unicode(32, volume_label, ' '); //
volume label
-
- write_block(8, 0);
- write_both_endian_dword(total_sectors);
- write_string("%/E");
- write_block(29, 0);
- write_both_endian_word(1); // volume set size
- write_both_endian_word(1); // volume sequence number
- write_both_endian_word(2048); // sector size
- write_both_endian_dword(joliet_path_table_size);
- write_little_endian_dword(joliet_little_endian_path_table_sector);
- write_little_endian_dword(0); // second little endian path table
- write_big_endian_dword(joliet_big_endian_path_table_sector);
- write_big_endian_dword(0); // second big endian path table
- write_directory_record(&root, DOT_RECORD, TRUE);
-
- write_bytecounted_string_as_big_endian_unicode(128, volume_label, ' ');
// volume set identifier
- write_bytecounted_string_as_big_endian_unicode(128, PUBLISHER_ID, ' ');
// publisher identifier
- write_bytecounted_string_as_big_endian_unicode(128, DATA_PREP_ID, ' ');
// data preparer identifier
- write_bytecounted_string_as_big_endian_unicode(128, APP_ID, ' ');
// application identifier
-
- write_bytecounted_string_as_big_endian_unicode(37, "", ' '); //
copyright file identifier
- write_bytecounted_string_as_big_endian_unicode(37, "", ' '); //
abstract file identifier
- write_bytecounted_string_as_big_endian_unicode(37, "", ' '); //
bibliographic file identifier
-
- write_string(timestring); // volume creation
- write_byte(0);
- write_string(timestring); // most recent modification
- write_byte(0);
- write_string("0000000000000000"); // volume expires
- write_byte(0);
- write_string("0000000000000000"); // volume is effective
- write_byte(0);
- write_byte(1);
- write_byte(0);
- fill_sector();
- }
-
- // Volume Descriptor Set Terminator
- if (make_bridged_udf)
- {
- write_string("\377CD001\1");
- fill_sector();
- }
-
- // TODO: Add UDF support!
-
- // Boot Catalog
- if (eltorito)
- {
- boot_catalog_sector = cd.sector;
-
- // Validation entry header
- write_byte(boot_validation_header.header_id);
- write_byte(boot_validation_header.platform_id);
- write_little_endian_word(0); // reserved
- write_bytecounted_string(24, MANUFACTURER_ID, 0); // Manufacturer identifier
- write_little_endian_word(0x62E); // checksum // FIXME: This is hardcoded!!
- write_little_endian_word(0xAA55); // signature
-
- // Default entry
- write_byte(default_boot_entry.boot_id);
- write_byte(default_boot_entry.boot_emu_type);
- write_little_endian_word(default_boot_entry.load_segment);
- write_byte(0); // partition type
- write_byte(0); // unused
- write_little_endian_word(default_boot_entry.sector_count);
- write_little_endian_dword(default_boot_entry.load_rba);
- write_block(20, 0); // unused
-
- // Loop through each boot header
- header = boot_header_list;
- while (header)
- {
- write_byte(header->header_id);
- write_byte(header->platform_id);
- write_little_endian_word(header->num_entries);
- write_block(28, 0); // Identifier string (unused)
-
- // Loop through each boot entry
- entry = header->entry_list;
- while (entry)
- {
- write_byte(entry->boot_id);
- write_byte(entry->boot_emu_type);
- write_little_endian_word(entry->load_segment);
- write_byte(0); // partition type
- write_byte(0); // unused
- write_little_endian_word(entry->sector_count);
- write_little_endian_dword(entry->load_rba);
- write_block(20, 0); // Selection criteria (unused)
-
- entry = entry->next_entry;
- }
-
- header = header->next_header;
- }
-
- fill_sector();
- }
-
-
- // Boot Images
- if (eltorito)
- {
- default_boot_entry.load_rba = cd.sector;
-
- file = fopen(default_boot_entry.bootimage, "rb");
- if (file == NULL)
- error_exit("Cannot open '%s'\n",
default_boot_entry.bootimage);
- fseek(file, 0, SEEK_END);
- size = ftell(file);
- if (size == 0 || (size % 2048))
- {
- fclose(file);
- error_exit("Invalid boot image size (%lu bytes)\n", size);
- }
- // Sector count in 512 byte sectors and rounded up
- default_boot_entry.sector_count = (size + 511) / 512;
- if (!write_from_file(file, size))
- {
- fclose(file);
- error_exit("Read error in file '%s'\n",
default_boot_entry.bootimage);
- }
- fclose(file);
-
- // Loop through each boot header
- header = boot_header_list;
- while (header)
- {
- // Loop through each boot entry
- entry = header->entry_list;
- while (entry)
- {
- entry->load_rba = cd.sector;
-
- file = fopen(entry->bootimage, "rb");
- if (file == NULL)
- error_exit("Cannot open '%s'\n",
entry->bootimage);
- fseek(file, 0, SEEK_END);
- size = ftell(file);
- if (size == 0 || (size % 2048))
- {
- fclose(file);
- error_exit("Invalid boot image size (%lu bytes)\n", size);
- }
- // Sector count in 512 byte sectors and rounded up
- entry->sector_count = (size + 511) / 512;
- if (!write_from_file(file, size))
- {
- fclose(file);
- error_exit("Read error in file '%s'\n",
entry->bootimage);
- }
- fclose(file);
-
- entry = entry->next_entry;
- }
-
- header = header->next_header;
- }
-
-// fill_sector();
- }
-
-
- // Little Endian Path Table
-
- little_endian_path_table_sector = cd.sector;
- write_byte(1);
- write_byte(0); // number of sectors in extended attribute record
- write_little_endian_dword(root.sector);
- write_little_endian_word(1);
- write_byte(0);
- write_byte(0);
-
- index = 1;
- root.path_table_index = 1;
- for (d = root.next_in_path_table; d != NULL; d = d->next_in_path_table)
- {
- name_length = strlen(d->name_on_cd);
- write_byte((BYTE)name_length);
- write_byte(0); // number of sectors in extended attribute record
- write_little_endian_dword(d->sector);
- write_little_endian_word(d->parent->path_table_index);
- write_string(d->name_on_cd);
- if (name_length & 1)
- write_byte(0);
- d->path_table_index = ++index;
- }
-
- path_table_size = (cd.sector - little_endian_path_table_sector) *
- SECTOR_SIZE + cd.offset;
- fill_sector();
-
-
- // Big Endian Path Table
-
- big_endian_path_table_sector = cd.sector;
- write_byte(1);
- write_byte(0); // number of sectors in extended attribute record
- write_big_endian_dword(root.sector);
- write_big_endian_word(1);
- write_byte(0);
- write_byte(0);
-
- for (d = root.next_in_path_table; d != NULL; d = d->next_in_path_table)
- {
- name_length = strlen(d->name_on_cd);
- write_byte((BYTE)name_length);
- write_byte(0); // number of sectors in extended attribute record
- write_big_endian_dword(d->sector);
- write_big_endian_word(d->parent->path_table_index);
- write_string(d->name_on_cd);
- if (name_length & 1)
- write_byte(0);
- }
- fill_sector();
-
- if (joliet)
- {
- // Little Endian Path Table
-
- joliet_little_endian_path_table_sector = cd.sector;
- write_byte(1);
- write_byte(0); // number of sectors in extended attribute record
- write_little_endian_dword(root.joliet_sector);
- write_little_endian_word(1);
- write_byte(0);
- write_byte(0);
-
- for (d = root.next_in_path_table; d != NULL; d = d->next_in_path_table)
- {
- name_length = strlen(d->joliet_name) * 2;
- write_byte((BYTE)name_length);
- write_byte(0); // number of sectors in extended attribute record
- write_little_endian_dword(d->joliet_sector);
- write_little_endian_word(d->parent->path_table_index);
- write_string_as_big_endian_unicode(d->joliet_name);
- }
-
- joliet_path_table_size = (cd.sector - joliet_little_endian_path_table_sector) *
- SECTOR_SIZE + cd.offset;
- fill_sector();
-
- // Big Endian Path Table
-
- joliet_big_endian_path_table_sector = cd.sector;
- write_byte(1);
- write_byte(0); // number of sectors in extended attribute record
- write_big_endian_dword(root.joliet_sector);
- write_big_endian_word(1);
- write_byte(0);
- write_byte(0);
-
- for (d = root.next_in_path_table; d != NULL; d = d->next_in_path_table)
- {
- name_length = strlen(d->joliet_name) * 2;
- write_byte((BYTE)name_length);
- write_byte(0); // number of sectors in extended attribute record
- write_big_endian_dword(d->joliet_sector);
- write_big_endian_word(d->parent->path_table_index);
- write_string_as_big_endian_unicode(d->joliet_name);
- }
- fill_sector();
- }
-
- // TODO: Add UDF support!
-
-#if 0
- // Boot Images ??
-#endif
-
- // TODO: Add CRC block for header!
-
- // Directories and files
- for (d = &root; d != NULL; d = d->next_in_path_table)
- {
- // write directory
- d->sector = cd.sector;
- write_directory_record(d, DOT_RECORD, FALSE);
- write_directory_record(d == &root ? d : d->parent, DOT_DOT_RECORD,
FALSE);
- for (q = d->first_record; q != NULL; q = q->next_in_directory)
- {
- write_directory_record(q,
- q->flags & DIRECTORY_FLAG ? SUBDIRECTORY_RECORD
: FILE_RECORD,
- FALSE);
- }
- fill_sector();
- d->size = (cd.sector - d->sector) * SECTOR_SIZE;
-
- // write directory for joliet
- if (joliet)
- {
- d->joliet_sector = cd.sector;
- write_directory_record(d, DOT_RECORD, TRUE);
- write_directory_record(d == &root ? d : d->parent, DOT_DOT_RECORD,
TRUE);
- for (q = d->first_record; q != NULL; q = q->next_in_directory)
- {
- write_directory_record(q,
- q->flags & DIRECTORY_FLAG ?
SUBDIRECTORY_RECORD : FILE_RECORD,
- TRUE);
- }
- fill_sector();
- d->joliet_size = (cd.sector - d->joliet_sector) * SECTOR_SIZE;
- bytes_in_directories += d->joliet_size;
- }
-
- number_of_directories++;
- bytes_in_directories += d->size;
-
- // write file data
- for (q = d->first_record; q != NULL; q = q->next_in_directory)
- {
- if ((q->flags & DIRECTORY_FLAG) == 0)
- {
- q->sector = q->joliet_sector = cd.sector;
- size = q->size;
- if (cd.file == NULL)
- {
- number_of_sectors = (size + SECTOR_SIZE - 1) / SECTOR_SIZE;
- cd.sector += number_of_sectors;
- number_of_files++;
- bytes_in_files += size;
- unused_bytes_at_ends_of_files +=
- number_of_sectors * SECTOR_SIZE - size;
- }
- else
- {
- const char *file_source;
- old_end_source = end_source;
- if (!q->orig_name)
- {
- get_file_specifications(q);
- *end_source = 0;
- file_source = source;
- }
- else
- {
- file_source = q->orig_name;
- }
- if (verbosity == VERBOSE)
- printf("Writing contents of %s\n", file_source);
- file = fopen(file_source, "rb");
- if (file == NULL)
- error_exit("Cannot open '%s'\n", file_source);
- if (!write_from_file(file, size))
- {
- fclose(file);
- error_exit("Read error in file '%s'\n",
file_source);
- }
- fclose(file);
- end_source = old_end_source;
- fill_sector();
- }
- }
- }
- }
-
- // TODO: Add final CRC block!
-
- total_sectors = (DWORD)cd.sector;
-}
-
-static char HELP[] =
- "\n"
- "CDMAKE CD-ROM Premastering Utility\n"
- "Copyright (C) 1997 Philip J. Erdelsky\n"
- "Copyright (C) 2003-2016 ReactOS Team\n"
- "\n\n"
- "CDMAKE [-vN] [-p] [-s N] [-m] [-j] [-q] "
- // "[-x] "
- "[-pN] [-eN] [-b bootimage]\n"
- "
[-bootdata:N#<defaultBootEntry>#<bootEntry1>#...#<bootEntryN>]\n"
- " source volume image\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
'(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"
- " 0: Quiet mode - display nothing but error
messages.\n"
- " 1: Normal mode (default).\n"
- " 2: Verbose mode - display file information as files
are\n"
- " scanned and written. Overrides the -p option.\n"
- " -p Show progress while writing.\n"
- " -s N Abort operation before beginning write if image will be
larger\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"
- " extensions.\n"
- " -j Generate Joliet filename records.\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"
- " -eN Boot media emulation. Valid values for 'N'
are:\n"
- " 0 (or nothing): No emulation.\n"
- " 1: 1.2 MB diskette.\n"
- " 2: 1.44MB diskette.\n"
- " 3: 2.88MB diskette.\n"
- " 4: Hard disk.\n"
- " -b bootimage Create a single-boot El-Torito image.\n"
- " -bootdata: Create a multi-boot El-Torito image. This option cannot
be\n"
- " combined with the -b option.\n"
- " Syntax:\n"
- "
-bootdata:N#<defaultBootEntry>#<bootEntry2>#...#<bootEntryN>\n"
- " 'N': number of boot entries following.\n"
- " defaultBootEntry: The default boot entry, needed in all
cases.\n"
- " Used by BIOSes which do not support additional boot
entries.\n"
- " bootEntryX: Additional boot entries.\n"
- " - Do not use spaces.\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 boot entry must specify the platform ID.\n";
-
-/*-----------------------------------------------------------------------------
-Program execution starts here.
------------------------------------------------------------------------------*/
-
-#if (defined(__GNUC__) || (_MSC_VER < 1900))
-char* strtok_s(char *str, const char *delim, char **ctx)
-{
- if (delim == NULL || ctx == NULL || (str == NULL && *ctx == NULL))
- {
- return NULL;
- }
-
- if (!str)
- str = *ctx;
-
- while (*str && strchr(delim, *str))
- str++;
- if (!*str)
- {
- *ctx = str;
- return NULL;
- }
-
- *ctx = str + 1;
- while (**ctx && !strchr(delim, **ctx))
- (*ctx)++;
- if (**ctx)
- *(*ctx)++ = '\0';
-
- return str;
-}
-#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)
-{
- time_t timestamp = time(NULL);
- int i;
- char *t;
-
- if (argc < 2)
- {
- puts(HELP);
- return 1;
- }
-
- // Initialize CD-ROM write buffer
-
- cd.file = NULL;
- cd.filespecs[0] = 0;
-
- cd.buffer = malloc(BUFFER_SIZE);
- if (cd.buffer == NULL)
- error_exit("Insufficient memory");
-
- // Initialize root directory
-
- memset(&root, 0, sizeof(root));
- root.level = 1;
- root.flags = DIRECTORY_FLAG;
- convert_date_and_time(&root.date_and_time, ×tamp);
-
- // Initialize parameters
-
- scan_files_only = FALSE;
- make_bridged_udf = TRUE;
- // compute_crc = FALSE;
-
- verbosity = NORMAL;
- show_progress = FALSE;
- size_limit = 0;
- accept_punctuation_marks = FALSE;
- source[0] = 0;
- volume_label[0] = 0;
-
- // Initialize boot information
- eltorito = FALSE;
- multi_boot = FALSE;
- boot_validation_header.header_id = 1; // Validation header ID
- boot_validation_header.platform_id = 0; // x86/64 BIOS system
- init_boot_entry(&default_boot_entry,
- 0, // No emulation
- 0, // Use default 0x07C0
- "");
- default_boot_entry.sector_count = 0;
- default_boot_entry.load_rba = 0;
- boot_header_list = NULL;
-
- // Scan command line arguments
-
- for (i = 1; i < argc; i++)
- {
- if (strncmp(argv[i], "-v", 2) == 0)
- {
- t = argv[i] + 2;
- if (*t == 0) // Normal verbosity level.
- verbosity = NORMAL;
- else // Verbosity level in decimal
- verbosity = strtoul(t, NULL, 10);
-
- // Check for validity
- if (verbosity > VERBOSE)
- verbosity = NORMAL;
-
- // Disable by default, unless we are in normal verbosity level.
- // If progress is still wanted, use '-p'.
- if (verbosity == QUIET || verbosity == VERBOSE)
- show_progress = FALSE;
- }
- else if (strcmp(argv[i], "-p") == 0)
- show_progress = TRUE;
- else if (strncmp(argv[i], "-s", 2) == 0)
- {
- t = argv[i] + 2;
- if (*t == 0)
- {
- if (++i < argc)
- t = argv[i];
- else
- error_exit("Missing size limit parameter");
- }
- // size_limit = strtoul(t, NULL, 10);
- while (isdigit(*t))
- size_limit = size_limit * 10 + *t++ - '0';
- if (size_limit < 1 || size_limit > 800)
- error_exit("Invalid size limit");
- size_limit <<= 9; // convert megabyte to sector count
- }
- else if (strcmp(argv[i], "-m") == 0)
- accept_punctuation_marks = TRUE;
- else if (strcmp(argv[i], "-j") == 0)
- joliet = TRUE;
- else if (strncmp(argv[i], "-e", 2) == 0)
- {
- // Check whether the multi-boot option '-bootdata:' was already set.
- // If so, print an error and bail out.
- if (eltorito && multi_boot)
- error_exit("Single-boot and multi-boot entries cannot be
combined");
-
- eltorito = TRUE;
- multi_boot = FALSE;
-
- t = argv[i] + 2;
- if (*t == 0) // No emulation
- default_boot_entry.boot_emu_type = 0;
- else // ID in decimal
- default_boot_entry.boot_emu_type = (BYTE)strtoul(t, NULL, 10);
- }
- else if (strncmp(argv[i], "-p", 2) == 0)
- {
- // Check whether the multi-boot option '-bootdata:' was already set.
- // If so, print an error and bail out.
- if (eltorito && multi_boot)
- error_exit("Single-boot and multi-boot entries cannot be
combined");
-
- eltorito = TRUE;
- multi_boot = FALSE;
-
- // Platform ID in hexadecimal
- boot_validation_header.platform_id = (BYTE)strtoul(argv[i] + 2, NULL, 16);
- }
- else if (strcmp(argv[i], "-b") == 0)
- {
- // Check whether the multi-boot option '-bootdata:' was already set.
- // If so, print an error and bail out.
- if (eltorito && multi_boot)
- error_exit("Single-boot and multi-boot entries cannot be
combined");
-
- eltorito = TRUE;
- multi_boot = FALSE;
-
- strncpy(default_boot_entry.bootimage, argv[++i],
sizeof(default_boot_entry.bootimage));
- default_boot_entry.bootimage[sizeof(default_boot_entry.bootimage)-1] =
'\0';
- }
- else if (strncmp(argv[i], "-bootdata:", sizeof("-bootdata:")
- 1) == 0)
- {
- char *bootdata, *entry_ctx, *option_ctx;
- DWORD num_boot_entries = 0;
-
- BOOL default_entry = TRUE; // Start by setting the default boot entry
- PBOOT_HEADER boot_header = NULL; // Current boot header
- PBOOT_ENTRY boot_entry = NULL; // The last boot entry in the current boot
header
- BYTE platform_id, old_platform_id = 0;
- BYTE boot_emu_type;
- WORD load_segment;
- char bootimage[512];
-
- // Check whether the single-boot option '-b' was already set.
- // If so, print an error and bail out.
- if (eltorito && !multi_boot)
- error_exit("Single-boot and multi-boot entries cannot be
combined");
-
- t = argv[i] + (sizeof("-bootdata:") - 1);
- bootdata = strdup(t);
- if (bootdata == NULL)
- error_exit("Insufficient memory");
-
- eltorito = TRUE;
- multi_boot = TRUE;
-
- // FIXME: Paths containing '#' or ',' or ' ' are not
yet supported!!
-
- // Start parsing...
- t = strtok_s(bootdata, "#", &entry_ctx);
- if (t == NULL)
- {
- free(bootdata);
- error_exit("Malformed bootdata command");
- }
-
- num_boot_entries = strtoul(t, NULL, 10);
-
- while (num_boot_entries--)
- {
- // Reset to default values
- platform_id = 0; // x86/64 BIOS system
- boot_emu_type = 0; // No emulation
- load_segment = 0; // Use default 0x07C0
- bootimage[0] = '\0';
-
- t = strtok_s(NULL, "#", &entry_ctx);
- if (t == NULL)
- {
- free(bootdata);
- error_exit("Malformed bootdata command");
- }
-
- t = strtok_s(t, ",", &option_ctx);
- while (t != NULL)
- {
- switch (*t++)
- {
- case 'b': // Boot sector file
- {
- char *q;
-
- // Searches for any of the valid separators:
- // '#' starts a new boot entry;
- // ',' starts a new boot option;
- // ' ' finishes the bootdata command.
- q = strpbrk(t, "#, ");
- if (!q) q = t + strlen(t);
- strncpy(bootimage, t, q - t + 1);
- break;
- }
-
- case 'p': // Platform ID
- {
- // Platform ID in hexadecimal
- platform_id = (BYTE)strtoul(t, NULL, 16);
- break;
- }
-
- case 'e': // No floppy-disk emulation
- {
- if (*t == 0) // No emulation
- boot_emu_type = 0;
- else // ID in decimal
- boot_emu_type = (BYTE)strtoul(t, NULL, 10);
-
- break;
- }
-
- case 't': // Loading segment
- {
- if (*t == 0) // Not specified: use default 0x07C0
- load_segment = 0;
- else // Segment in hexadecimal
- load_segment = (BYTE)strtoul(t, NULL, 16);
-
- break;
- }
-
- default:
- free(bootdata);
- error_exit("Malformed bootdata command");
- }
-
- t = strtok_s(NULL, ",", &option_ctx);
- }
-
- // Create a new entry and possibly a boot header
- if (default_entry)
- {
- // Initialize the default boot entry and header
-
- boot_validation_header.header_id = 1; // Validation header ID
- boot_validation_header.platform_id = platform_id;
-
- init_boot_entry(&default_boot_entry, boot_emu_type, load_segment,
bootimage);
-
- // Default entry is now initialized.
- default_entry = FALSE;
- }
- else
- {
- // Initialize a new boot entry
- PBOOT_ENTRY old_boot_entry = boot_entry;
-
- boot_entry = calloc(1, sizeof(*boot_entry));
- if (boot_entry == NULL)
- error_exit("Insufficient memory");
- // boot_entry->next_entry = NULL;
-
- init_boot_entry(boot_entry, boot_emu_type, load_segment, bootimage);
-
- // Create a new boot header if we don't have one yet
- if (boot_header == NULL)
- {
- boot_header = calloc(1, sizeof(*boot_header));
- if (boot_header == NULL)
- error_exit("Insufficient memory");
-
- boot_header->header_id = 0x91; // So far this is the last
boot header
- boot_header->platform_id = platform_id;
- // boot_header->next_header = NULL;
- // boot_header->num_entries = 0;
- // boot_header->entry_list = NULL;
-
- old_boot_entry = NULL;
- old_platform_id = platform_id;
-
- boot_header_list = boot_header;
- }
- else
- {
- // Create a new boot header if we change the platform ID
- if (old_platform_id != platform_id)
- {
- PBOOT_HEADER prev_boot_header = boot_header;
-
- boot_header = calloc(1, sizeof(*boot_header));
- if (boot_header == NULL)
- error_exit("Insufficient memory");
-
- boot_header->header_id = 0x91; // So far this is the
last boot header
- boot_header->platform_id = platform_id;
- // boot_header->next_header = NULL;
- // boot_header->num_entries = 0;
- // boot_header->entry_list = NULL;
-
- old_boot_entry = NULL;
- old_platform_id = platform_id;
-
- // Link into the header list
- prev_boot_header->header_id = 0x90; // The previous boot
header was not the last one
- prev_boot_header->next_header = boot_header;
- }
- }
-
- // Add the entry into the header
- ++boot_header->num_entries;
- if (old_boot_entry == NULL)
- boot_header->entry_list = boot_entry;
- else
- old_boot_entry->next_entry = boot_entry;
- }
- }
-
- 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)
- {
- strcpy(source, argv[i++]);
- strncpy(volume_label, argv[i++], sizeof(volume_label) - 1);
- strcpy(cd.filespecs, argv[i]);
- }
- else
- error_exit("Missing command line argument");
- }
-
- if (source[0] == 0)
- error_exit("Missing source directory");
- if (volume_label[0] == 0)
- error_exit("Missing volume label");
- if (cd.filespecs[0] == 0)
- error_exit("Missing image file specifications");
-
- if (source[0] != '@')
- {
- /* set source[] and end_source to source directory,
- * with a terminating directory separator */
- end_source = source + strlen(source);
- if (end_source[-1] == ':')
- *end_source++ = '.';
- if (end_source[-1] != DIR_SEPARATOR_CHAR)
- *end_source++ = DIR_SEPARATOR_CHAR;
-
- /* scan all files and create directory structure in memory */
- make_directory_records(&root);
- }
- else
- {
- char *trimmedline, *targetname, *normdir, *srcname, *eq;
- char lineread[1024];
-
- FILE *f = fopen(source+1, "r");
- if (!f)
- {
- error_exit("Cannot open CD-ROM file description '%s'\n",
source+1);
- }
- while (fgets(lineread, sizeof(lineread), f))
- {
- /* We treat these characters as line endings */
- trimmedline = strtok(lineread, "\t\r\n;");
- eq = strchr(trimmedline, '=');
- if (!eq)
- {
- /* Treat this as a directory name */
- targetname = trimmedline;
- normdir = strdup(targetname);
- normalize_dirname(normdir);
- dir_hash_create_dir(&specified_files, targetname, normdir);
- free(normdir);
- }
- else
- {
- targetname = strtok(lineread, "=");
- srcname = strtok(NULL, "");
-
-#ifdef _WIN32
- if (_access(srcname, R_OK) == 0)
-#else
- if (access(srcname, R_OK) == 0)
-#endif
- {
- if (!dir_hash_add_file(&specified_files, srcname, targetname))
- error_exit("Target '%s' (file '%s') is
invalid\n", targetname, srcname);
- }
- else
- error_exit("Cannot access file '%s' (target
'%s')\n", srcname, targetname);
- }
- }
- fclose(f);
-
- /* scan all files and create directory structure in memory */
- scan_specified_files(&root, &specified_files.root);
- }
-
- /* sort path table entries */
- root.next_in_path_table = sort_linked_list(root.next_in_path_table,
- 1,
- compare_path_table_order);
-
- // initialize CD-ROM write buffer
-
- cd.file = NULL;
- cd.sector = 0;
- cd.offset = 0;
- cd.count = 0;
-
- // make non-writing pass over directory structure to obtain the proper
- // sector numbers and offsets and to determine the size of the image
-
- number_of_files = bytes_in_files = number_of_directories =
- bytes_in_directories = unused_bytes_at_ends_of_files = 0;
- pass();
-
- if (verbosity >= NORMAL)
- {
- printf("%s bytes ", edit_with_commas(bytes_in_files, TRUE));
- printf("in %s files\n", edit_with_commas(number_of_files, FALSE));
- printf("%s unused bytes at ends of files\n",
- edit_with_commas(unused_bytes_at_ends_of_files, TRUE));
- printf("%s bytes ", edit_with_commas(bytes_in_directories, TRUE));
- printf("in %s directories\n",
- edit_with_commas(number_of_directories, FALSE));
- printf("%s other bytes\n", edit_with_commas(root.sector * SECTOR_SIZE,
TRUE));
- puts("-------------");
- printf("%s total bytes\n",
- edit_with_commas(total_sectors * SECTOR_SIZE, TRUE));
- puts("=============");
- }
-
- if (size_limit != 0 && total_sectors > size_limit)
- error_exit("Size limit exceeded");
-
- if (!scan_files_only)
- {
- // re-initialize CD-ROM write buffer
-
- cd.file = fopen(cd.filespecs, "w+b");
- if (cd.file == NULL)
- error_exit("Cannot open image file '%s'", cd.filespecs);
- cd.sector = 0;
- cd.offset = 0;
- cd.count = 0;
-
-
- // make writing pass over directory structure
-
- pass();
-
- if (cd.count > 0)
- flush_buffer();
- if (show_progress)
- printf("\r \n");
- if (fclose(cd.file) != 0)
- {
- cd.file = NULL;
- error_exit("File write error in image file '%s'",
cd.filespecs);
- }
-
- if (verbosity >= NORMAL)
- puts("CD-ROM image made successfully");
- }
-
- dir_hash_destroy(&specified_files);
- release_memory();
- return 0;
-}
-
-/* EOF */
diff --git a/modules/rosapps/applications/devutils/cdmake/config.h
b/modules/rosapps/applications/devutils/cdmake/config.h
deleted file mode 100644
index ffb5dabb1f6..00000000000
--- a/modules/rosapps/applications/devutils/cdmake/config.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _WIN32
-#ifndef MAX_PATH
-#define MAX_PATH 260
-#endif
-#define DIR_SEPARATOR_CHAR '/'
-#define DIR_SEPARATOR_STRING "/"
-#else
-#define DIR_SEPARATOR_CHAR '\\'
-#define DIR_SEPARATOR_STRING "\\"
-#endif
-
-#define MANUFACTURER_ID "ReactOS Foundation"
-#define PUBLISHER_ID "ReactOS Foundation"
-#define DATA_PREP_ID "ReactOS Foundation"
-#define APP_ID "CDMAKE CD-ROM Premastering Utility"
diff --git a/modules/rosapps/applications/devutils/cdmake/dirhash.c
b/modules/rosapps/applications/devutils/cdmake/dirhash.c
deleted file mode 100644
index a44bad57e01..00000000000
--- a/modules/rosapps/applications/devutils/cdmake/dirhash.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CD-ROM Maker
- * FILE: tools/cdmake/dirhash.c
- * PURPOSE: CD-ROM Premastering Utility - Directory names hashing
- * PROGRAMMERS: Art Yerkes
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include "config.h"
-#include "dirhash.h"
-
-#ifndef max
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#endif
-
-/* This is the famous DJB hash */
-static unsigned int
-djb_hash(const char *name)
-{
- unsigned int val = 5381;
- int i = 0;
-
- for (i = 0; name[i]; i++)
- {
- val = (33 * val) + name[i];
- }
-
- return val;
-}
-
-static void
-split_path(const char *path, char **dirname, char **filename /* OPTIONAL */)
-{
- const char *result;
-
- /* Retrieve the file name */
- char *last_slash_1 = strrchr(path, '/');
- char *last_slash_2 = strrchr(path, '\\');
-
- if (last_slash_1 || last_slash_2)
- result = max(last_slash_1, last_slash_2) + 1;
- else
- result = path;
-
- /* Duplicate the file name for the user if needed */
- if (filename)
- *filename = strdup(result);
-
- /* Remove any trailing directory separators */
- while (result > path && (*(result-1) == '/' || *(result-1) ==
'\\'))
- result--;
-
- /* Retrieve and duplicate the directory */
- *dirname = malloc(result - path + 1);
- if (result > path)
- memcpy(*dirname, path, result - path);
- (*dirname)[result - path] = '\0'; // NULL-terminate
-}
-
-void normalize_dirname(char *filename)
-{
- int i, tgt;
- int slash = 1;
-
- for (i = 0, tgt = 0; filename[i]; i++)
- {
- if (slash)
- {
- if (filename[i] != '/' && filename[i] != '\\')
- {
- filename[tgt++] = toupper(filename[i]);
- slash = 0;
- }
- }
- else
- {
- if (filename[i] == '/' || filename[i] == '\\')
- {
- slash = 1;
- filename[tgt++] = DIR_SEPARATOR_CHAR;
- }
- else
- {
- filename[tgt++] = toupper(filename[i]);
- }
- }
- }
- filename[tgt] = '\0'; // NULL-terminate
-}
-
-static struct target_dir_entry *
-get_entry_by_normname(struct target_dir_hash *dh, const char *norm)
-{
- unsigned int hashcode;
- struct target_dir_entry *de;
- hashcode = djb_hash(norm);
- de = dh->buckets[hashcode % NUM_DIR_HASH_BUCKETS];
- while (de && strcmp(de->normalized_name, norm))
- de = de->next_dir_hash_entry;
- return de;
-}
-
-static void
-delete_entry(struct target_dir_hash *dh, struct target_dir_entry *de)
-{
- struct target_dir_entry **ent;
- ent = &dh->buckets[de->hashcode % NUM_DIR_HASH_BUCKETS];
- while (*ent && ((*ent) != de))
- ent = &(*ent)->next_dir_hash_entry;
- if (*ent)
- *ent = (*ent)->next_dir_hash_entry;
-}
-
-struct target_dir_entry *
-dir_hash_create_dir(struct target_dir_hash *dh, const char *casename, const char
*targetnorm)
-{
- struct target_dir_entry *de, *parent_de;
- char *parentcase = NULL;
- char *case_name = NULL;
- char *parentname = NULL;
- struct target_dir_entry **ent;
-
- if (!dh->root.normalized_name)
- {
- dh->root.normalized_name = strdup("");
- dh->root.case_name = strdup("");
- dh->root.hashcode = djb_hash("");
- dh->buckets[dh->root.hashcode % NUM_DIR_HASH_BUCKETS] = &dh->root;
- }
-
- /* Check whether the directory was already created and just return it if so */
- de = get_entry_by_normname(dh, targetnorm);
- if (de)
- return de;
-
- /*
- * If *case_name == '\0' after the following call to split_path(...),
- * for example in the case where casename == "subdir/dir/", then just
- * create the directories "subdir" and "dir" by a recursive call
to
- * dir_hash_create_dir(...) and return 'parent_de' instead (see after).
- * We do not (and we never) create a no-name directory inside it.
- */
- split_path(casename, &parentcase, &case_name);
- split_path(targetnorm, &parentname, NULL);
- parent_de = dir_hash_create_dir(dh, parentcase, parentname);
- free(parentname);
- free(parentcase);
-
- /* See the remark above */
- if (!*case_name)
- {
- free(case_name);
- return parent_de;
- }
-
- /* Now create the directory */
- de = calloc(1, sizeof(*de));
- de->parent = parent_de;
- de->normalized_name = strdup(targetnorm);
- de->case_name = case_name;
- de->hashcode = djb_hash(targetnorm);
-
- de->next = parent_de->child;
- parent_de->child = de;
-
- ent = &dh->buckets[de->hashcode % NUM_DIR_HASH_BUCKETS];
- while (*ent)
- ent = &(*ent)->next_dir_hash_entry;
- *ent = de;
-
- return de;
-}
-
-struct target_file *
-dir_hash_add_file(struct target_dir_hash *dh, const char *source, const char *target)
-{
- struct target_file *tf;
- struct target_dir_entry *de;
- char *targetdir = NULL;
- char *targetfile = NULL;
- char *targetnorm;
-
- /* First create the directory; check whether the file name is valid and bail out if
not */
- split_path(target, &targetdir, &targetfile);
- if (!*targetfile)
- {
- free(targetdir);
- free(targetfile);
- return NULL;
- }
- targetnorm = strdup(targetdir);
- normalize_dirname(targetnorm);
- de = dir_hash_create_dir(dh, targetdir, targetnorm);
- free(targetnorm);
- free(targetdir);
-
- /* Now add the file */
- tf = calloc(1, sizeof(*tf));
- tf->next = de->head;
- de->head = tf;
- tf->source_name = strdup(source);
- tf->target_name = targetfile;
-
- return tf;
-}
-
-static void
-dir_hash_destroy_dir(struct target_dir_hash *dh, struct target_dir_entry *de)
-{
- struct target_file *tf;
- struct target_dir_entry *te;
-
- while ((te = de->child))
- {
- de->child = te->next;
- dir_hash_destroy_dir(dh, te);
- free(te);
- }
- while ((tf = de->head))
- {
- de->head = tf->next;
- free(tf->source_name);
- free(tf->target_name);
- free(tf);
- }
-
- delete_entry(dh, de);
- free(de->normalized_name);
- free(de->case_name);
-}
-
-void dir_hash_destroy(struct target_dir_hash *dh)
-{
- dir_hash_destroy_dir(dh, &dh->root);
-}
diff --git a/modules/rosapps/applications/devutils/cdmake/dirhash.h
b/modules/rosapps/applications/devutils/cdmake/dirhash.h
deleted file mode 100644
index d06427f0401..00000000000
--- a/modules/rosapps/applications/devutils/cdmake/dirhash.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CD-ROM Maker
- * FILE: tools/cdmake/dirhash.h
- * PURPOSE: CD-ROM Premastering Utility - Directory names hashing
- * PROGRAMMERS: Art Yerkes
- */
-
-#ifndef _DIRHASH_H_
-#define _DIRHASH_H_
-
-#define NUM_DIR_HASH_BUCKETS 1024
-
-struct target_file
-{
- struct target_file *next;
- char *source_name;
- char *target_name;
-};
-
-struct target_dir_entry
-{
- unsigned int hashcode;
- struct target_dir_entry *next_dir_hash_entry;
-
- struct target_dir_entry *next;
- struct target_dir_entry *parent;
- struct target_dir_entry *child;
- struct target_file *head;
- char *normalized_name;
- char *case_name;
-};
-
-struct target_dir_hash
-{
- struct target_dir_entry *buckets[NUM_DIR_HASH_BUCKETS];
- struct target_dir_entry root;
-};
-
-void normalize_dirname(char *filename);
-
-struct target_dir_entry *
-dir_hash_create_dir(struct target_dir_hash *dh, const char *casename, const char
*targetnorm);
-
-struct target_file *
-dir_hash_add_file(struct target_dir_hash *dh, const char *source, const char *target);
-
-void dir_hash_destroy(struct target_dir_hash *dh);
-
-#endif // _DIRHASH_H_
diff --git a/modules/rosapps/applications/devutils/cdmake/llmsort.c
b/modules/rosapps/applications/devutils/cdmake/llmsort.c
deleted file mode 100644
index 004b9caaa9f..00000000000
--- a/modules/rosapps/applications/devutils/cdmake/llmsort.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * A Linked-List Memory Sort
- * by Philip J. Erdelsky
- * pje(a)acm.org
- * pje(a)efgh.com
- *
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.
- */
-
-#include <stdio.h>
-
-void *sort_linked_list(void *p, unsigned index, int (*compare)(void *, void *))
-{
- unsigned base;
- unsigned long block_size;
-
- struct record
- {
- struct record *next[1];
- /* other members not directly accessed by this function */
- };
-
- struct tape
- {
- struct record *first, *last;
- unsigned long count;
- } tape[4];
-
- /* Distribute the records alternately to tape[0] and tape[1]. */
-
- tape[0].count = tape[1].count = 0L;
- tape[0].first = NULL;
- base = 0;
- while (p != NULL)
- {
- struct record *next = ((struct record *)p)->next[index];
- ((struct record *)p)->next[index] = tape[base].first;
- tape[base].first = ((struct record *)p);
- tape[base].count++;
- p = next;
- base ^= 1;
- }
-
- /* If the list is empty or contains only a single record, then */
- /* tape[1].count == 0L and this part is vacuous. */
-
- for (base = 0, block_size = 1L; tape[base+1].count != 0L;
- base ^= 2, block_size <<= 1)
- {
- int dest;
- struct tape *tape0, *tape1;
- tape0 = tape + base;
- tape1 = tape + base + 1;
- dest = base ^ 2;
- tape[dest].count = tape[dest+1].count = 0;
- for (; tape0->count != 0; dest ^= 1)
- {
- unsigned long n0, n1;
- struct tape *output_tape = tape + dest;
- n0 = n1 = block_size;
- while (1)
- {
- struct record *chosen_record;
- struct tape *chosen_tape;
- if (n0 == 0 || tape0->count == 0)
- {
- if (n1 == 0 || tape1->count == 0)
- break;
- chosen_tape = tape1;
- n1--;
- }
- else if (n1 == 0 || tape1->count == 0)
- {
- chosen_tape = tape0;
- n0--;
- }
- else if ((*compare)(tape0->first, tape1->first) > 0)
- {
- chosen_tape = tape1;
- n1--;
- }
- else
- {
- chosen_tape = tape0;
- n0--;
- }
- chosen_tape->count--;
- chosen_record = chosen_tape->first;
- chosen_tape->first = chosen_record->next[index];
- if (output_tape->count == 0)
- output_tape->first = chosen_record;
- else
- output_tape->last->next[index] = chosen_record;
- output_tape->last = chosen_record;
- output_tape->count++;
- }
- }
- }
-
- if (tape[base].count > 1L)
- tape[base].last->next[index] = NULL;
- return tape[base].first;
-}
-
-/* EOF */
diff --git a/modules/rosapps/applications/devutils/cdmake/readme.txt
b/modules/rosapps/applications/devutils/cdmake/readme.txt
deleted file mode 100644
index 4ddb07389eb..00000000000
--- a/modules/rosapps/applications/devutils/cdmake/readme.txt
+++ /dev/null
@@ -1,96 +0,0 @@
- CD-ROM Maker
- Philip J. Erdelsky
-
-The CDMAKE utility converts files from DOS/Windows format to ISO9660
-(CD-ROM) format.
-
-First, gather all the files to be converted and put them into a single
-base directory and its subdirectories, arranged just the way you want
-them on the CD-ROM. Remember that ISO9660 allows subdirectories to be
-nested only eight levels deep. Therefore, if the base directory is
-C:\CDROM,
-
- C:\CDROM\D2\D3\D4\D5\D6\D7\D8\FOO.TXT is permitted, but
-
- C:\CDROM\D2\D3\D4\D5\D6\D7\D8\D9\FOO.TXT is forbidden.
-
-Also, ISO9660 does not allow directories to have extensions, although
-DOS does.
-
-Finally, the characters in file and directory names and file extensions
-must be letters, digits or underscores. Other punctuation marks
-permitted by DOS/Windows are forbidden by ISO9660. You can use the -c
-option to override this restriction, but the resulting CD-ROM may not be
-readable on systems other than DOS/Windows.
-
-Files in the base directory will be written to the root directory of the
-CD-ROM image. All subdirectories of the base directory will appear as
-subdirectories of the root directory of the CD-ROM image. Their
-contents, and the contents of their subdirectories, down to the eighth
-level, will be faithfully copied to the CD-ROM image.
-
-System files will not be written to the CD-ROM image. Hidden files will
-be written to the CD-ROM image, and will retain their hidden attributes.
-Read-only files will be written, and will remain read-only on the
-CD-ROM, but this does not distinguish them in any way, because on a
-CD-ROM all files are read-only. The archive attribute will be lost.
-
-File and directory date and time stamps will be preserved in the CD-ROM
-image.
-
-The utility is called up by a command line of the following form:
-
- CDMAKE [-q] [-v] [-p] [-s N] [-m] [-j] [-b bootimage] source volume image
-
- source specifications of base directory containing all files to
- be written to CD-ROM image
-
- volume volume label
-
- image image file or device
-
- -q quiet mode - display nothing but error messages
-
- -v verbose mode - display file information as files are
- scanned and written - overrides -p option
-
- -p show progress while writing
-
- -s N abort operation before beginning write if image will be
- larger than N megabytes (i.e. 1024*1024*N bytes)
-
- -m accept punctuation marks other than underscores in
- names and extensions
-
- -j generates Joliet filename records
-
- -b bootimage create bootable ElTorito CD-ROM using 'no emulation' mode
-
-
-The utility makes three passes over the source files:
-
- (1) The scanning pass, in which the names and extensions are
- checked for validity, and the names, extensions, sizes, dates,
- times and attributes are recorded internally. The files are not
- actually read during this pass.
-
- (2) The layout pass, in which the sizes and positions of
- directories, files and other items in the CD-ROM image are
- determined.
-
- (3) The writing pass, in which the files are actually read and the
- CD-ROM image is actually written to the specified file or
- device. The image is always written sequentially.
-
-If neither the -q nor the -v option is used, CDMAKE will display the
-volume label, size, number of files and directories and the total bytes
-in each at the end of the layout pass.
-
-If the -p option is used, and is not overridden by the -v option, then
-during the writing pass, CDMAKE will display the number of bytes still
-to be written to the CD-ROM image, updating it frequently. The number
-will decrease as the operation progresses, and will reach zero when the
-operation is complete.
-
-The operation of CDMAKE can be aborted by typing Ctrl-C when the utility
-is displaying text of any kind.