From 01aebbdd9d6b9e949c00cc23797b480231ee396b Mon Sep 17 00:00:00 2001 From: Casper Hornstrup Date: Sat, 12 Apr 2003 14:53:56 +0000 Subject: [PATCH] 2003-04-12 Casper S. Hornstrup * tools/cdmake/Makefile: Use HOST_CC. * tools/cdmake/cdmake.c (MAX_PATH, DIR_SEPARATOR_CHAR, DIR_SEPARATOR_STRING): Define. (directory_record): Add fields name_on_cd and extension_on_cd. (error_exit): Make a macro. Avoid using vfprintf and fprintf. (write_directory_record, new_directory_record, compare_directory_order, pass): Use name_on_cd and extension_on_cd. (make_directory_records, get_file_specifications): Use DIR_SEPARATOR_CHAR. (new_directory_record, make_directory_records): Linux implementations. (main): Use DIR_SEPARATOR_CHAR. svn path=/trunk/; revision=4524 --- reactos/ChangeLog | 13 ++ reactos/tools/cdmake/Makefile | 13 +- reactos/tools/cdmake/cdmake.c | 292 ++++++++++++++++++++++++++++++---- 3 files changed, 280 insertions(+), 38 deletions(-) diff --git a/reactos/ChangeLog b/reactos/ChangeLog index 4a71489ac16..00c8d8fc2a7 100644 --- a/reactos/ChangeLog +++ b/reactos/ChangeLog @@ -1,3 +1,16 @@ +2003-04-12 Casper S. Hornstrup + + * tools/cdmake/Makefile: Use HOST_CC. + * tools/cdmake/cdmake.c (MAX_PATH, DIR_SEPARATOR_CHAR, + DIR_SEPARATOR_STRING): Define. + (directory_record): Add fields name_on_cd and extension_on_cd. + (error_exit): Make a macro. Avoid using vfprintf and fprintf. + (write_directory_record, new_directory_record, compare_directory_order, + pass): Use name_on_cd and extension_on_cd. + (make_directory_records, get_file_specifications): Use DIR_SEPARATOR_CHAR. + (new_directory_record, make_directory_records): Linux implementations. + (main): Use DIR_SEPARATOR_CHAR. + 2003-04-06 Casper S. Hornstrup * lib/freetype/.cvsignore: Ignore nul. diff --git a/reactos/tools/cdmake/Makefile b/reactos/tools/cdmake/Makefile index aa602bfc331..34dc6cfed8c 100644 --- a/reactos/tools/cdmake/Makefile +++ b/reactos/tools/cdmake/Makefile @@ -11,13 +11,16 @@ OBJECTS = cdmake.o llmosrt.o CLEAN_FILES = *.o cdmake$(EXE_POSTFIX) -cdmake$(EXE_POSTFIX): $(OBJECTS) - $(HOST_CC) $(OBJECTS) -o cdmake$(EXE_POSTFIX) - HOST_CFLAGS = -I. -#create_nls.o: create_nls.c -# $(HOST_CC) $(HOST_CFLAGS) -c create_nls.c -o create_nls.o +cdmake.o: cdmake.c + $(HOST_CC) $(HOST_CFLAGS) -c cdmake.c -o cdmake.o + +llmosrt.o: llmosrt.c + $(HOST_CC) $(HOST_CFLAGS) -c llmosrt.c -o llmosrt.o + +cdmake$(EXE_POSTFIX): $(OBJECTS) + $(HOST_CC) $(OBJECTS) -o cdmake$(EXE_POSTFIX) ifeq ($(HOST),mingw32-linux) clean: diff --git a/reactos/tools/cdmake/cdmake.c b/reactos/tools/cdmake/cdmake.c index 92f28aad612..7385ce18e98 100644 --- a/reactos/tools/cdmake/cdmake.c +++ b/reactos/tools/cdmake/cdmake.c @@ -1,4 +1,4 @@ -/* $Id: cdmake.c,v 1.2 2003/04/11 21:02:21 phreak Exp $ */ +/* $Id: cdmake.c,v 1.3 2003/04/12 14:53:56 chorns Exp $ */ /* CD-ROM Maker by Philip J. Erdelsky pje@acm.org @@ -7,20 +7,41 @@ ElTorito-Support by Eric Kohl ekohl@rz-online.de + + Linux port + by Casper S. Hornstrup + chorns@users.sourceforge.net */ /* According to his website, this file was released into the public domain by Phillip J. Erdelsky */ #include #include -#include +#include #include #include -#include +#ifdef WIN32 +#include #include +#else +#include +#include +#include +#include +#endif #include #include #include +#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 typedef unsigned char BYTE; @@ -72,7 +93,9 @@ typedef struct directory_record struct directory_record *parent; BYTE flags; char name[MAX_NAME_LENGTH+1]; + char name_on_cd[MAX_NAME_LENGTH+1]; char extension[MAX_EXTENSION_LENGTH+1]; + char extension_on_cd[MAX_EXTENSION_LENGTH+1]; DATE_AND_TIME date_and_time; DWORD sector; DWORD size; @@ -176,14 +199,14 @@ This function edits and displays an error message and then jumps back to the error exit point in main(). -----------------------------------------------------------------------------*/ -static void error_exit(const char *format, ...) -{ - vfprintf(stderr, format, (char*)&format + 1); - fprintf(stderr, "\n"); - if (cd.file != NULL) - fclose(cd.file); - release_memory(); - longjmp(error, 1); +#define error_exit(fmt,args...) \ +{ \ + printf(fmt,##args); \ + printf("\n"); \ + if (cd.file != NULL) \ + fclose(cd.file); \ + release_memory(); \ + exit(1); \ } /*----------------------------------------------------------------------------- @@ -323,12 +346,12 @@ write_directory_record(PDIR_RECORD d, identifier_size = 1; break; case SUBDIRECTORY_RECORD: - identifier_size = strlen(d->name); + identifier_size = strlen(d->name_on_cd); break; case FILE_RECORD: - identifier_size = strlen(d->name) + 2; - if (d->extension[0] != 0) - identifier_size += 1 + strlen(d->extension); + identifier_size = strlen(d->name_on_cd) + 2; + if (d->extension_on_cd[0] != 0) + identifier_size += 1 + strlen(d->extension_on_cd); break; } record_size = 33 + identifier_size; @@ -361,14 +384,14 @@ write_directory_record(PDIR_RECORD d, write_byte(1); break; case SUBDIRECTORY_RECORD: - write_string(d->name); + write_string(d->name_on_cd); break; case FILE_RECORD: - write_string(d->name); - if (d->extension[0] != 0) + write_string(d->name_on_cd); + if (d->extension_on_cd[0] != 0) { write_byte('.'); - write_string(d->extension); + write_string(d->extension_on_cd); } write_string(";1"); break; @@ -417,6 +440,9 @@ specified ffblk. It links it into the beginning of the directory list for the specified parent and returns a pointer to the new record. -----------------------------------------------------------------------------*/ +#if WIN32 + +/* Win32 version */ PDIR_RECORD new_directory_record (struct _finddata_t *f, PDIR_RECORD parent) @@ -424,6 +450,7 @@ new_directory_record (struct _finddata_t *f, PDIR_RECORD d; char *s; char *t; + char *n; d = malloc(sizeof(DIR_RECORD)); if (d == NULL) @@ -432,7 +459,9 @@ new_directory_record (struct _finddata_t *f, root.next_in_memory = d; { s = f->name; - t = d->name; + t = d->name_on_cd; + n = d->name; + while (*s != 0) { if (*s == '.') @@ -440,13 +469,19 @@ new_directory_record (struct _finddata_t *f, s++; break; } - *t++ = check_for_punctuation(*s++, f->name); + + *t++ = check_for_punctuation(*s, f->name); + *n = *s; + s++; + n++; } *t = 0; - t = d->extension; + strcpy(d->extension, s); + t = d->extension_on_cd; while (*s != 0) *t++ = check_for_punctuation(*s++, f->name); *t = 0; + *n = 0; } convert_date_and_time(&d->date_and_time, &f->time_create); if (f->attrib & _A_SUBDIR) @@ -464,6 +499,69 @@ new_directory_record (struct _finddata_t *f, return d; } +#else + +/* Linux version */ +PDIR_RECORD +new_directory_record (struct dirent *entry, + struct stat *stbuf, + PDIR_RECORD parent) +{ + PDIR_RECORD d; + char *s; + char *t; + char *n; + + d = malloc(sizeof(DIR_RECORD)); + if (d == NULL) + error_exit("Insufficient memory"); + d->next_in_memory = root.next_in_memory; + root.next_in_memory = d; + { + s = entry->d_name; + t = d->name_on_cd; + n = d->name; + + while (*s != 0) + { + if (*s == '.') + { + s++; + break; + } + + *t++ = check_for_punctuation(*s, entry->d_name); + *n = *s; + s++; + n++; + } + *t = 0; + strcpy(d->extension, s); + t = d->extension_on_cd; + while (*s != 0) + *t++ = check_for_punctuation(*s++, entry->d_name); + *t = 0; + *n = 0; + } + + convert_date_and_time(&d->date_and_time, &stbuf->st_mtime); + if (entry->d_type == DT_DIR) + { + if (d->extension[0] != 0) + error_exit("Directory with extension %s", entry->d_name); + d->flags = DIRECTORY_FLAG; + } + else + d->flags = entry->d_name[0] == '.' ? HIDDEN_FLAG : 0; + d->size = stbuf->st_size; + d->next_in_directory = parent->first_record; + parent->first_record = d; + d->parent = parent; + 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 @@ -472,9 +570,9 @@ positive value if p is after q. static int compare_directory_order(PDIR_RECORD p, PDIR_RECORD q) { - int n = strcmp(p->name, q->name); + int n = strcmp(p->name_on_cd, q->name_on_cd); if (n == 0) - n = strcmp(p->extension, q->extension); + n = strcmp(p->extension_on_cd, q->extension_on_cd); return n; } @@ -515,6 +613,8 @@ 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) { @@ -565,7 +665,7 @@ make_directory_records (PDIR_RECORD d) { old_end_source = end_source; append_string_to_source(f.name); - *end_source++ = '\\'; + *end_source++ = DIR_SEPARATOR_CHAR; if (verbosity == VERBOSE) { *end_source = 0; @@ -595,6 +695,132 @@ make_directory_records (PDIR_RECORD d) 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; + + 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 + { + getcwd(buf, sizeof(buf)); + strcat(buf, DIR_SEPARATOR_STRING); + strcat(buf, source); + strcat(buf, entry->d_name); + } + if (stat(buf, &stbuf) == -1) + { + error_exit("Can't 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_size); + } + else + { + if (verbosity == VERBOSE) + { + printf("%d: file %s\n", d->level, buf); + } + (void) new_directory_record(entry, &stbuf, d); + } + } + } + closedir (dirp); + } + else + { + error_exit("Can't 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; + if (verbosity == VERBOSE) + { + *end_source = 0; + 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 + { + getcwd(buf, sizeof(buf)); + strcat(buf, DIR_SEPARATOR_STRING); + strcat(buf, source); + } + if (stat(buf, &stbuf) == -1) + { + error_exit("Can't 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; + } + } + closedir (dirp); + } + + // sort directory + d->first_record = sort_linked_list(d->first_record, 0, compare_directory_order); +} + +#endif + /*----------------------------------------------------------------------------- This function loads the file specifications for the file or directory corresponding to the specified directory record into the source[] buffer. It @@ -613,7 +839,7 @@ static void get_file_specifications(PDIR_RECORD d) append_string_to_source(d->extension); } if (d->flags & DIRECTORY_FLAG) - *end_source++ = '\\'; + *end_source++ = DIR_SEPARATOR_CHAR; } } @@ -773,12 +999,12 @@ static void pass(void) 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); + name_length = strlen(d->name_on_cd); write_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); + write_string(d->name_on_cd); if (name_length & 1) write_byte(0); d->path_table_index = ++index; @@ -800,12 +1026,12 @@ static void pass(void) for (d = root.next_in_path_table; d != NULL; d = d->next_in_path_table) { - name_length = strlen(d->name); + name_length = strlen(d->name_on_cd); write_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); + write_string(d->name_on_cd); if (name_length & 1) write_byte(0); } @@ -1010,13 +1236,13 @@ int main(int argc, char **argv) error_exit("Missing image file specifications"); - // set source[] and end_source to source directory, with a terminating \ + // 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] != '\\') - *end_source++ = '\\'; + if (end_source[-1] != DIR_SEPARATOR_CHAR) + *end_source++ = DIR_SEPARATOR_CHAR; // scan all files and create directory structure in memory