Author: hbelusca
Date: Sun Feb 21 03:00:16 2016
New Revision: 70762

URL: http://svn.reactos.org/svn/reactos?rev=70762&view=rev
Log:
[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.

Modified:
    trunk/reactos/tools/cdmake/cdmake.c
    trunk/reactos/tools/cdmake/llmsort.c

Modified: trunk/reactos/tools/cdmake/cdmake.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/cdmake/cdmake.c?rev=70762&r1=70761&r2=70762&view=diff
==============================================================================
--- trunk/reactos/tools/cdmake/cdmake.c [iso-8859-1] (original)
+++ trunk/reactos/tools/cdmake/cdmake.c [iso-8859-1] Sun Feb 21 03:00:16 2016
@@ -3,6 +3,11 @@
  * by Philip J. Erdelsky
  * [email protected]
  * 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
@@ -13,6 +18,7 @@
  *                  Casper S. Hornstrup
  *                  Filip Navara
  *                  Magnus Olsen
+ *                  Hermes Belusca-Maito
  *
  * HISTORY:
  *
@@ -33,8 +39,6 @@
  * Convert long filename to ISO9660 file name by Magnus Olsen
  * [email protected]
  */
-
-/* According to his website, this file was released into the public domain by 
Philip J. Erdelsky */
 
 #include <stdio.h>
 #include <fcntl.h>
@@ -176,13 +180,21 @@
 static char DIRECTORY_TIMESTAMP[] = "~Y$'KOR$.3K&";
 
 static struct cd_image cd;
+DIR_RECORD root;
 
 char volume_label[32];
-DIR_RECORD root;
 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;
 
@@ -190,12 +202,23 @@
 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;
@@ -203,12 +226,19 @@
 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;
 
-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
@@ -685,7 +715,7 @@
         if (d->extension[0] != 0)
         {
             if (!joliet)
-                error_exit("Directory with extension %s", filename);
+                error_exit("Directory with extension '%s'", filename);
         }
         d->flags = DIRECTORY_FLAG;
     } else
@@ -993,7 +1023,7 @@
     }
     else
     {
-        error_exit("Cannot open %s\n", source);
+        error_exit("Cannot open '%s'\n", source);
         return;
     }
 
@@ -1053,7 +1083,7 @@
     }
     else
     {
-        error_exit("Cannot open %s\n", source);
+        error_exit("Cannot open '%s'\n", source);
         return;
     }
 
@@ -1136,7 +1166,7 @@
     }
     else
     {
-        error_exit("Cannot open %s\n", source);
+        error_exit("Cannot open '%s'\n", source);
         return;
     }
 
@@ -1221,18 +1251,18 @@
                                          FILE_ATTRIBUTE_NORMAL,
                                          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))
             {
-                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);
 #else
             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);
 #endif
@@ -1257,15 +1287,15 @@
                                          FILE_ATTRIBUTE_NORMAL,
                                          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))
             {
-                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))
             {
-                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->orig_name = file->source_name;
@@ -1378,14 +1408,17 @@
 
 static void pass(void)
 {
-    PDIR_RECORD d;
-    PDIR_RECORD q;
+    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);
@@ -1395,46 +1428,47 @@
 
 
     // Primary Volume Descriptor
-
-    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();
-
+    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)
@@ -1492,17 +1526,17 @@
     }
 
     // Volume Descriptor Set Terminator
-    write_string("\377CD001\1");
-    fill_sector();
-
-    // Boot Catalog and Images
+    if (make_bridged_udf)
+    {
+        write_string("\377CD001\1");
+        fill_sector();
+    }
+
+    // TODO: Add UDF support!
+
+    // Boot Catalog
     if (eltorito)
     {
-        PBOOT_HEADER header;
-        PBOOT_ENTRY  entry;
-
-        // Boot Catalog
-
         boot_catalog_sector = cd.sector;
 
         // Validation entry header
@@ -1552,15 +1586,17 @@
         }
 
         fill_sector();
-
-
-        // Boot Images
-
+    }
+
+
+    // 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);
+            error_exit("Cannot open '%s'\n", default_boot_entry.bootimage);
         fseek(file, 0, SEEK_END);
         size = ftell(file);
         if (size == 0 || (size % 2048))
@@ -1573,7 +1609,7 @@
         if (!write_from_file(file, size))
         {
             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);
 
@@ -1589,7 +1625,7 @@
 
                 file = fopen(entry->bootimage, "rb");
                 if (file == NULL)
-                    error_exit("Cannot open %s\n", entry->bootimage);
+                    error_exit("Cannot open '%s'\n", entry->bootimage);
                 fseek(file, 0, SEEK_END);
                 size = ftell(file);
                 if (size == 0 || (size % 2048))
@@ -1602,7 +1638,7 @@
                 if (!write_from_file(file, size))
                 {
                     fclose(file);
-                    error_exit("Read error in file %s\n", entry->bootimage);
+                    error_exit("Read error in file '%s'\n", entry->bootimage);
                 }
                 fclose(file);
 
@@ -1615,7 +1651,9 @@
 //      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
@@ -1643,6 +1681,7 @@
                        SECTOR_SIZE + cd.offset;
     fill_sector();
 
+
     // Big Endian Path Table
 
     big_endian_path_table_sector = cd.sector;
@@ -1713,6 +1752,14 @@
         }
         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)
@@ -1784,11 +1831,11 @@
                         printf("Writing contents of %s\n", file_source);
                     file = fopen(file_source, "rb");
                     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))
                     {
                         fclose(file);
-                        error_exit("Read error in file %s\n", file_source);
+                        error_exit("Read error in file '%s'\n", file_source);
                     }
                     fclose(file);
                     end_source = old_end_source;
@@ -1798,19 +1845,31 @@
         }
     }
 
+    // TODO: Add final CRC block!
+
     total_sectors = (DWORD)cd.sector;
 }
 
 static char HELP[] =
     "\n"
     "CDMAKE CD-ROM Premastering Utility\n"
-    "Copyright (C) Philip J. Erdelsky\n"
-    "Copyright (C) 2003-2015 ReactOS Team\n"
+    "Copyright (C) 1997 Philip J. Erdelsky\n"
+    "Copyright (C) 2003-2016 ReactOS Team\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"
     "       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 
'@').\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"
@@ -1819,16 +1878,24 @@
     "  -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.2Mb  diskette.\n"
-    "                    2: 1.44Mb diskette.\n"
-    "                    3: 2.88Mb diskette.\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"
@@ -1842,12 +1909,7 @@
     "            - 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"
-    "\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";
+    "            - Each boot entry must specify the platform ID.\n";
 
 /*-----------------------------------------------------------------------------
 Program execution starts here.
@@ -1879,6 +1941,20 @@
 }
 #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);
@@ -1891,23 +1967,27 @@
         return 1;
     }
 
-    // Initialize root directory
+    // 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, &timestamp);
 
-    // Initialize CD-ROM write buffer
-
-    cd.file = NULL;
-    cd.filespecs[0] = 0;
-
     // Initialize parameters
+
+    scan_files_only = FALSE;
+    make_bridged_udf = TRUE;
+    // compute_crc = FALSE;
 
     verbosity = NORMAL;
     show_progress = FALSE;
@@ -1921,12 +2001,12 @@
     multi_boot = FALSE;
     boot_validation_header.header_id   = 1;  // Validation header ID
     boot_validation_header.platform_id = 0;  // x86/64 BIOS system
-    default_boot_entry.boot_id       = 0x88; // Bootable entry
-    default_boot_entry.boot_emu_type = 0;    // No emulation
-    default_boot_entry.load_segment  = 0;    // 0 --> use default 0x07C0
+    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;
-    default_boot_entry.bootimage[0]  = '\0';
     boot_header_list = NULL;
 
     // Scan command line arguments
@@ -2041,7 +2121,7 @@
             eltorito   = 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...
             t = strtok_s(bootdata, "#", &entry_ctx);
@@ -2058,7 +2138,7 @@
                 // Reset to default values
                 platform_id   = 0;  // x86/64 BIOS system
                 boot_emu_type = 0;  // No emulation
-                load_segment  = 0;  // 0 --> use default 0x07C0
+                load_segment  = 0;  // Use default 0x07C0
                 bootimage[0]  = '\0';
 
                 t = strtok_s(NULL, "#", &entry_ctx);
@@ -2106,7 +2186,7 @@
 
                         case 't': // Loading segment
                         {
-                            if (*t == 0) // Not specified --> use default 
0x07C0
+                            if (*t == 0) // Not specified: use default 0x07C0
                                 load_segment = 0;
                             else // Segment in hexadecimal
                                 load_segment = (BYTE)strtoul(t, NULL, 16);
@@ -2129,12 +2209,8 @@
 
                     boot_validation_header.header_id   = 1;  // Validation 
header 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));
-                    
default_boot_entry.bootimage[sizeof(default_boot_entry.bootimage)-1] = '\0';
+
+                    init_boot_entry(&default_boot_entry, boot_emu_type, 
load_segment, bootimage);
 
                     // Default entry is now initialized.
                     default_entry = FALSE;
@@ -2149,12 +2225,7 @@
                         error_exit("Insufficient memory");
                     // boot_entry->next_entry = NULL;
 
-                    boot_entry->boot_id       = 0x88;   // Bootable entry
-                    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';
+                    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)
@@ -2211,6 +2282,10 @@
 
             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++]);
@@ -2249,7 +2324,7 @@
         FILE *f = fopen(source+1, "r");
         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))
         {
@@ -2327,32 +2402,35 @@
     if (size_limit != 0 && total_sectors > size_limit)
         error_exit("Size limit exceeded");
 
-    // 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");
+    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();

Modified: trunk/reactos/tools/cdmake/llmsort.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/cdmake/llmsort.c?rev=70762&r1=70761&r2=70762&view=diff
==============================================================================
--- trunk/reactos/tools/cdmake/llmsort.c        [iso-8859-1] (original)
+++ trunk/reactos/tools/cdmake/llmsort.c        [iso-8859-1] Sun Feb 21 
03:00:16 2016
@@ -2,10 +2,18 @@
  * A Linked-List Memory Sort
  * by Philip J. Erdelsky
  * [email protected]
+ * [email protected]
  * 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>
 


Reply via email to