diff --git a/README.md b/README.md index f2ed997..ff293ce 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # ebiso UEFI bootable ISO image creator -Primary intention of ebiso was to create simple bootable UEFI ISO image for [ReaR](https://github.com/rear/rear) on SLES11. It should however work on other Linux based platforms as well. +Primary intention of ebiso was to create simple bootable UEFI ISO image for [ReaR](https://github.com/rear/rear) on SLES11. It should however work on other Linux based distributions as well. - no additional dependencies - released under GPL - - supports 8.3 file name and RRIP (Rock Ridge Interchange Protocol) + - supports 8.3 and long file names (up to 255 characters) formats - more info can be found in [ebiso wiki](https://github.com/gozora/ebiso/wiki) - tested with rear on SLES11 SP3 and Centos 6.7 - basic [usage](https://github.com/gozora/ebiso/wiki/Usage) diff --git a/ebiso.c b/ebiso.c index f15d51b..70b7b5b 100644 --- a/ebiso.c +++ b/ebiso.c @@ -1,9 +1,9 @@ /* * ebiso.c * - * Version: 0.1.3 + * Version: 0.1.4 * - * Release date: 21.10.2015 + * Release date: 25.10.2015 * * Copyright 2015 Vladimir (sodoma) Gozora * @@ -129,6 +129,7 @@ int main(int argc, char *argv[]) { list->dir_id = 1; list->parent_id = 1; list->next = (struct file_list_t*) malloc(sizeof(struct file_list_t)); + ISO_data.dir_count = 1; rr_list = list->next; memset(rr_list, 0, sizeof(struct file_list_t)); @@ -162,7 +163,7 @@ int main(int argc, char *argv[]) { } /* Create initial file structure */ - if ((rv = list_create(ISO_data.work_dir, &rr_list)) != E_OK) + if ((rv = list_create(ISO_data.work_dir, &rr_list, &ISO_data)) != E_OK) goto cleanup; /* Remove possible duplicates */ @@ -233,11 +234,16 @@ int main(int argc, char *argv[]) { cleanup: list_clean(list); - free(terminator); - free(path_table_LSB); - free(path_table_MSB); - free(header); - free(boot_descriptor); + if (terminator != NULL) + free(terminator); + if (path_table_LSB != NULL) + free(path_table_LSB); + if (path_table_MSB != NULL) + free(path_table_MSB); + if (header != NULL) + free(header); + if (boot_descriptor != NULL) + free(boot_descriptor); return rv; } diff --git a/include/ebiso.h b/include/ebiso.h index cbead44..19f23dd 100644 --- a/include/ebiso.h +++ b/include/ebiso.h @@ -1,9 +1,9 @@ /* * ebiso.h * - * Version: 0.1.3 + * Version: 0.1.4 * - * Release date: 21.10.2015 + * Release date: 25.10.2015 * * Copyright 2015 Vladimir (sodoma) Gozora * @@ -33,7 +33,7 @@ #include #define PROGNAME "ebiso" -#define VERSION "0.1.3" +#define VERSION "0.1.4" #ifdef DEBUG static void disp_level(struct file_list_t *list_to_display, int level); @@ -57,7 +57,7 @@ enum msg_l { extern void filename_rename_duplicates(struct file_list_t *list); -extern int list_create(const char *dirname, struct file_list_t **flist); +extern int list_create(const char *dirname, struct file_list_t **flist, struct ISO_data_t *ISO_data); extern void list_clean(struct file_list_t *list_to_clean); extern uint32_t iso9660_header(void **header, struct file_list_t file_list, struct ISO_data_t ISO_data); diff --git a/include/globals.h b/include/globals.h index 9882841..5d663fe 100644 --- a/include/globals.h +++ b/include/globals.h @@ -1,9 +1,9 @@ /* * globals.h * - * Version: 0.4.0 + * Version: 0.4.1 * - * Release date: 20.10.2015 + * Release date: 25.10.2015 * * Copyright 2015 Vladimir (sodoma) Gozora * @@ -44,8 +44,9 @@ #define PT_RECORD_LEN 0x8 #define ARR_PREALLOC 20 #define RRIP_INIT_FIELDS rrip_RR | rrip_PX | rrip_TF | rrip_NM -//#define RRIP_INIT_FIELDS rrip_RR | rrip_PX | rrip_TF +//#define RRIP_INIT_FIELDS rrip_RR //#define RRIP_INIT_FIELDS rrip_NM +//#define RRIP_INIT_FIELDS rrip_TF | rrip_PX #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) diff --git a/include/iso9660.h b/include/iso9660.h index f1af2ad..86ee4c5 100644 --- a/include/iso9660.h +++ b/include/iso9660.h @@ -1,9 +1,9 @@ /* * iso9660.h * - * Version: 0.2.0 + * Version: 0.2.1 * - * Release date: 20.10.2015 + * Release date: 25.10.2015 * * Copyright 2015 Vladimir (sodoma) Gozora * @@ -47,9 +47,19 @@ enum rrip_fields_t { rrip_NM = 1 << 4 } rrip_fields_t; +struct iso9660_data_t { + char mdate_time[7]; + uint64_t LBA; + uint64_t data_len; + uint32_t volume_seq_number; + uint8_t flags; + uint8_t name_len; + uint8_t ext_attr_record; +} iso9660_data_t; + extern int option_on_off(uint32_t option2check, enum opt_l option); extern int write_files(struct file_list_t *file_list, FILE *dest); -extern struct file_list_t *list_search(struct file_list_t *file_list, char *needle); +extern struct file_list_t *list_search_name(struct file_list_t *file_list, char *needle); extern int CE_assign_LBA(struct CE_list_t *CE_list, struct file_list_t *file_list, uint32_t *LBA); extern int CEarr_init_list(struct CE_list_t *CE_list, int arr_prealloc); extern void CEarr_destroy_list(struct CE_list_t *CE_list); @@ -65,7 +75,8 @@ uint8_t do_pad(uint8_t len, enum pad_list_t type); /* el_torito.c */ void iso9660_cp2heap(void **dest, const void *source, long int size, uint32_t *dest_size); -static uint32_t construct_dir_record(struct file_list_t *file_list, void **directory_table_output, enum segment_list_t type); +static uint32_t construct_dir_record(struct file_list_t *file_list, struct file_list_t **parent_index, void **directory_table_output, enum segment_list_t type); +static int construct_iso9660_record(void **output, struct iso9660_data_t data, uint32_t *size); static uint64_t get_int32_LSB_MSB(uint64_t input); static uint32_t get_int16_LSB_MSB(uint32_t input); static int blocks_count(int size); diff --git a/include/list.h b/include/list.h index 4f34e39..1d9d9ce 100644 --- a/include/list.h +++ b/include/list.h @@ -1,9 +1,9 @@ /* * list.h * - * Version: 0.1.1 + * Version: 0.1.2 * - * Release date: 20.09.2015 + * Release date: 25.09.2015 * * Copyright 2015 Vladimir (sodoma) Gozora * @@ -30,9 +30,8 @@ extern uint8_t filename_convert_name(char *input, char *output, enum conv_type_l type); /* ebiso.c */ -int list_create(const char *dirname, struct file_list_t **flist); +int list_create(const char *dirname, struct file_list_t **flist, struct ISO_data_t *ISO_data); void list_clean(struct file_list_t *list_to_clean); /* iso9660.c */ -struct file_list_t *list_search(struct file_list_t *file_list, char *needle); - +struct file_list_t *list_search_name(struct file_list_t *file_list, char *needle); diff --git a/lib/iso9660.c b/lib/iso9660.c index f602d29..3fa905c 100644 --- a/lib/iso9660.c +++ b/lib/iso9660.c @@ -1,9 +1,9 @@ /* * iso9660.c * - * Version: 0.2.1 + * Version: 0.2.2 * - * Release date: 20.10.2015 + * Release date: 25.10.2015 * * Copyright 2015 Vladimir (sodoma) Gozora * @@ -135,7 +135,7 @@ uint32_t iso9660_header(void **header, struct file_list_t file_list, struct ISO_ iso9660_cp2heap(&rr_header, &opath_table_LBA_BE, sizeof(uint32_t), &header_size); // LBA of type-M optional path table (big endian) /* Create root directory record for header */ - construct_dir_record(&file_list, &rr_header, ROOT_HEADER); + construct_dir_record(&file_list, NULL, &rr_header, ROOT_HEADER); iso9660_cp2heap(&rr_header, volume_set_id, sizeof(volume_set_id), &header_size); iso9660_cp2heap(&rr_header, publisher_id, sizeof(publisher_id), &header_size); @@ -257,7 +257,7 @@ int iso9660_assign_LBA(struct file_list_t *file_list, struct ISO_data_t *ISO_dat } /* Initialize CE_list for directory records */ - if ((rv = CEarr_init_list(&CE_list, CE_LIST_PREALLOC)) != E_OK) { + if (rock_ridge_on == TRUE && (rv = CEarr_init_list(&CE_list, CE_LIST_PREALLOC)) != E_OK) { CEarr_destroy_list(&CE_list); return rv; } @@ -387,15 +387,15 @@ int iso9660_assign_LBA(struct file_list_t *file_list, struct ISO_data_t *ISO_dat } } - ISO_data->dir_count++; } rr_file_list = rr_file_list->next; } - CEarr_destroy_list(&CE_list); + if (rock_ridge_on == TRUE) + CEarr_destroy_list(&CE_list); /* Initialize CE_list for non-directory records */ - if ((rv = CEarr_init_list(&CE_list, CE_LIST_PREALLOC)) != E_OK) { + if (rock_ridge_on == TRUE && (rv = CEarr_init_list(&CE_list, CE_LIST_PREALLOC)) != E_OK) { CEarr_destroy_list(&CE_list); return rv; } @@ -417,15 +417,17 @@ int iso9660_assign_LBA(struct file_list_t *file_list, struct ISO_data_t *ISO_dat rr_file_list = rr_file_list->next; } - CEarr_destroy_list(&CE_list); + + if (rock_ridge_on == TRUE) + CEarr_destroy_list(&CE_list); /* Assign first 2 file LBAs for BOOT.CAT and UEFI boot image (virtual image) */ - search_result = list_search(file_list, ISO_data->boot_cat_file); + search_result = list_search_name(file_list, ISO_data->boot_cat_file); search_result->LBA = LBA; ISO_data->boot_cat_LBA = LBA; LBA += blocks_count(search_result->size); - search_result = list_search(file_list, ISO_data->efi_boot_file_full); + search_result = list_search_name(file_list, ISO_data->efi_boot_file_full); search_result->LBA = LBA; search_result->blocks = blocks_count(search_result->size); LBA += search_result->blocks; @@ -454,12 +456,14 @@ int iso9660_directory_record(struct file_list_t *file_list, FILE *dest, struct I void *rr_save_ptr = NULL; struct file_list_t *rr_file_list = file_list; struct file_list_t *tmp_file_list = NULL; + struct file_list_t **parent_index = NULL; int directory_table_size = BLOCK_SIZE * ISO_data->largest_cont_block; - int rv = 0; + int parent_index_size = sizeof(struct file_list_t *) * ISO_data->dir_count; + int rv = E_OK; int entry_len = 0; int bytes_written = 0; - uint8_t rock_ridge_on = FALSE; int offset = 0; + uint8_t rock_ridge_on = FALSE; enum segment_list_t type = 0; if (option_on_off(ISO_data->options, OPT_R) == E_OK) @@ -467,9 +471,18 @@ int iso9660_directory_record(struct file_list_t *file_list, FILE *dest, struct I if ((directory_table_start = (void *) malloc(directory_table_size)) == NULL) { printf("Error: iso9660_path_table(): Memory allocation failed\n"); - return E_MALLOC; + rv = E_MALLOC; + goto cleanup; } + if ((parent_index = (struct file_list_t **) malloc(parent_index_size)) == NULL ) { + printf("Error: iso9660_path_table(): Memory allocation failed.\n"); + rv = E_MALLOC; + goto cleanup; + } + else + memset(parent_index, 0, parent_index_size); + while(rr_file_list->next != NULL) { /* Skip files */ @@ -482,15 +495,19 @@ int iso9660_directory_record(struct file_list_t *file_list, FILE *dest, struct I memset(directory_table_start, 0, directory_table_size); /* - * Entry for absolute root will be a bit different - * Create ROOT record for CURRENT directory + * Entry for ABS root will be a bit different + * Create records for '.' & '..' */ if (strncmp(rr_file_list->name_path, ".", 2) == 0) type = (rock_ridge_on == TRUE) ? RRIP_ABS_ROOT : ISO9660_ROOT; else type = (rock_ridge_on == TRUE) ? RRIP_ROOT : ISO9660_ROOT; - bytes_written = construct_dir_record(rr_file_list, &directory_table, type); + /* Create index of parent directory data */ + if (parent_index[rr_file_list->dir_id - 1] == NULL) + parent_index[rr_file_list->dir_id - 1] = rr_file_list; + + bytes_written = construct_dir_record(rr_file_list, parent_index, &directory_table, type); /* * Search whole file list from beginning @@ -512,7 +529,7 @@ int iso9660_directory_record(struct file_list_t *file_list, FILE *dest, struct I type = (rock_ridge_on == TRUE) ? RRIP : ISO9660; - entry_len = construct_dir_record(tmp_file_list, &directory_table, type); + entry_len = construct_dir_record(tmp_file_list, NULL, &directory_table, type); bytes_written += entry_len; /* Create CE record if needed */ @@ -559,6 +576,7 @@ int iso9660_directory_record(struct file_list_t *file_list, FILE *dest, struct I bytes_written -= entry_len; directory_table += tmp_file_list->ISO9660_len; bytes_written += tmp_file_list->ISO9660_len; + entry_len = tmp_file_list->ISO9660_len; tmp_file_list->CE_offset = CE_offset; CE_offset += (tmp_file_list->full_len - tmp_file_list->ISO9660_len); @@ -594,8 +612,13 @@ int iso9660_directory_record(struct file_list_t *file_list, FILE *dest, struct I /* Write files */ rv = write_files(file_list, dest); - free(directory_table_start); - free(NM); +cleanup: + if (directory_table_start != NULL) + free(directory_table_start); + if (NM != NULL) + free(NM); + if (parent_index != NULL) + free(parent_index); return rv; } @@ -609,9 +632,11 @@ uint8_t do_pad(uint8_t len, enum pad_list_t type) { return pad_len; } -static uint32_t construct_dir_record(struct file_list_t *file_list, void **directory_table_output, enum segment_list_t type) { +static uint32_t construct_dir_record(struct file_list_t *file_list, struct file_list_t **parent_index, void **directory_table_output, enum segment_list_t type) { struct file_list_t *rr_file_list = file_list; + struct file_list_t *parent = NULL; struct tm *ts = NULL; + struct iso9660_data_t iso9660_data; void *rr_directory_table = *directory_table_output; void *rr_directory_table_start = rr_directory_table; void *rr_save_ptr = NULL; @@ -621,24 +646,21 @@ static uint32_t construct_dir_record(struct file_list_t *file_list, void **direc char cdate_time[7]; int terminator_len = 0; int rr_save_size = 0; - int iso9660_original_size = 0; - uint64_t data_len = 0; - uint64_t LBA = 0; uint64_t mode = get_int32_LSB_MSB(rr_file_list->st_mode); uint64_t nlinks = get_int32_LSB_MSB(rr_file_list->st_nlink); uint64_t uid = get_int32_LSB_MSB(rr_file_list->st_uid); uint64_t gid = get_int32_LSB_MSB(rr_file_list->st_gid); uint64_t ino = get_int32_LSB_MSB(rr_file_list->st_ino); uint32_t directory_table_size = 0; - uint32_t volume_seq_number = get_int16_LSB_MSB(one); - uint8_t name_len = 0; - uint8_t ext_attr_record = 0; - uint8_t flags = 0; // Will be adjusted in future, 0x02 indicates directory uint8_t pad_len = 0; memset(mdate_time, 0, sizeof(mdate_time)); memset(adate_time, 0, sizeof(adate_time)); memset(cdate_time, 0, sizeof(cdate_time)); + memset(&iso9660_data, 0, sizeof(iso9660_data_t)); + + iso9660_data.volume_seq_number = get_int16_LSB_MSB(one); + iso9660_data.ext_attr_record = 0; /* Assign modify date/time values */ ts = localtime(&file_list->mtime); @@ -670,42 +692,35 @@ static uint32_t construct_dir_record(struct file_list_t *file_list, void **direc cdate_time[5] = ts->tm_sec; cdate_time[6] = ts->tm_gmtoff / 60 / 15; - LBA = get_int32_LSB_MSB(rr_file_list->LBA); + iso9660_data.LBA = get_int32_LSB_MSB(rr_file_list->LBA); + strncpy(iso9660_data.mdate_time, mdate_time, sizeof(iso9660_data.mdate_time)); pad_len = do_pad(rr_file_list->name_conv_len, PAD_EVEN); if (S_ISDIR(rr_file_list->st_mode)) { - flags = 0x02; terminator_len = 0; - data_len = get_int32_LSB_MSB(rr_file_list->blocks * BLOCK_SIZE); + iso9660_data.data_len = get_int32_LSB_MSB(rr_file_list->blocks * BLOCK_SIZE); + iso9660_data.flags = 0x02; } else { - flags = 0x00; terminator_len = 2; - data_len = get_int32_LSB_MSB(rr_file_list->size); + iso9660_data.data_len = get_int32_LSB_MSB(rr_file_list->size); + iso9660_data.flags = 0x00; } if (type == ISO9660_ROOT || type == ROOT_HEADER || type == RRIP_ROOT) { - name_len = 1; // Lenght of roor dir name is always 1 pad_len = 0; + iso9660_data.name_len = 1; // Lenght of roor dir name is always 1 + } + else { + iso9660_data.name_len = rr_file_list->name_conv_len + terminator_len; } - else - name_len = rr_file_list->name_conv_len + terminator_len; /* Create basic ISO9660 structure */ - iso9660_cp2heap(&rr_directory_table, &zero, sizeof(uint8_t), &directory_table_size); // Lenght of whole entry will be added at the end - iso9660_cp2heap(&rr_directory_table, &ext_attr_record, sizeof(uint8_t), &directory_table_size); // Ext. attr. record - iso9660_cp2heap(&rr_directory_table, &LBA, sizeof(uint64_t), &directory_table_size); // LBA - iso9660_cp2heap(&rr_directory_table, &data_len, sizeof(uint64_t), &directory_table_size); // Size of file/dir - iso9660_cp2heap(&rr_directory_table, mdate_time, sizeof(mdate_time), &directory_table_size); // Recording date/time - iso9660_cp2heap(&rr_directory_table, &flags, sizeof(uint8_t), &directory_table_size); // Flags - iso9660_cp2heap(&rr_directory_table, &zero, sizeof(uint8_t), &directory_table_size); // Interleaving - iso9660_cp2heap(&rr_directory_table, &zero, sizeof(uint8_t), &directory_table_size); // Interleaving - iso9660_cp2heap(&rr_directory_table, &volume_seq_number, sizeof(uint32_t), &directory_table_size); // Volume sequence number - iso9660_cp2heap(&rr_directory_table, &name_len, sizeof(uint8_t), &directory_table_size); // File name len + construct_iso9660_record(&rr_directory_table, iso9660_data, &directory_table_size); /* Add file name */ if (type == ISO9660_ROOT || type == ROOT_HEADER || type == RRIP_ROOT) - iso9660_cp2heap(&rr_directory_table, &zero, name_len, &directory_table_size); + iso9660_cp2heap(&rr_directory_table, &zero, iso9660_data.name_len, &directory_table_size); else iso9660_cp2heap(&rr_directory_table, rr_file_list->name_conv, rr_file_list->name_conv_len, &directory_table_size); @@ -717,22 +732,35 @@ static uint32_t construct_dir_record(struct file_list_t *file_list, void **direc if (pad_len == 1) iso9660_cp2heap(&rr_directory_table, &zero, pad_len, &directory_table_size); - /* Save size of iso9660 basic entry */ - iso9660_original_size = directory_table_size; - /* This one is called only during header creation */ if (type == ROOT_HEADER) { iso9660_cp2heap(&rr_directory_table_start, &directory_table_size, sizeof(uint8_t), NULL); } - /* Create root dir entry one more time, with name 0x01 ... */ + + /* Add record for directory '..' */ else if (type == ISO9660_ROOT) { - iso9660_cp2heap(&rr_directory_table_start, &directory_table_size, sizeof(uint8_t), NULL); + parent = parent_index[rr_file_list->parent_id - 1]; + iso9660_cp2heap(&rr_directory_table_start, &directory_table_size, sizeof(uint8_t), NULL); // Write size of '.' rr_save_ptr = rr_directory_table; rr_save_size = directory_table_size; - iso9660_cp2heap(&rr_directory_table, rr_directory_table_start, iso9660_original_size - 1, &directory_table_size); - iso9660_cp2heap(&rr_directory_table, &one, sizeof(uint8_t), &directory_table_size); + /* Assign modify date/time values */ + ts = localtime(&parent->mtime); + mdate_time[0] = ts->tm_year; + mdate_time[1] = ts->tm_mon + 1; + mdate_time[2] = ts->tm_mday; + mdate_time[3] = ts->tm_hour; + mdate_time[4] = ts->tm_min; + mdate_time[5] = ts->tm_sec; + mdate_time[6] = ts->tm_gmtoff / 60 / 15; + + iso9660_data.LBA = get_int32_LSB_MSB(parent->LBA); + iso9660_data.data_len = get_int32_LSB_MSB(parent->blocks * BLOCK_SIZE); + strncpy(iso9660_data.mdate_time, mdate_time, sizeof(iso9660_data.mdate_time)); + + construct_iso9660_record(&rr_directory_table, iso9660_data, &directory_table_size); + iso9660_cp2heap(&rr_directory_table, &one, iso9660_data.name_len, &directory_table_size); rr_save_size = directory_table_size - rr_save_size; iso9660_cp2heap(&rr_save_ptr, &rr_save_size, sizeof(uint8_t), NULL); @@ -750,6 +778,7 @@ static uint32_t construct_dir_record(struct file_list_t *file_list, void **direc if ((init_fields & rrip_TF) != 0) RR[4] |= 1 << 7; // TF record in use + /* Record directory '.' */ if (type == RRIP_ABS_ROOT) { void *rr_CE = CE + 4; uint64_t CE_size = get_int32_LSB_MSB(rr_file_list->CE_LBA); @@ -763,11 +792,11 @@ static uint32_t construct_dir_record(struct file_list_t *file_list, void **direc iso9660_cp2heap(&rr_directory_table, CE, sizeof(CE), &directory_table_size); } - /* Write RR record*/ + /* Add RR record*/ if ((init_fields & rrip_RR) != 0) iso9660_cp2heap(&rr_directory_table, RR, sizeof(RR), &directory_table_size); - /* Write PX record */ + /* Add PX record */ if ((init_fields & rrip_PX) != 0) { iso9660_cp2heap(&rr_directory_table, PX, 4, &directory_table_size); iso9660_cp2heap(&rr_directory_table, &mode, sizeof(mode), &directory_table_size); @@ -777,7 +806,7 @@ static uint32_t construct_dir_record(struct file_list_t *file_list, void **direc iso9660_cp2heap(&rr_directory_table, &ino, sizeof(ino), &directory_table_size); } - /* Write TF record */ + /* Add TF record */ if ((init_fields & rrip_TF) != 0) { iso9660_cp2heap(&rr_directory_table, TF, 5, &directory_table_size); iso9660_cp2heap(&rr_directory_table, mdate_time, sizeof(mdate_time), &directory_table_size); // Modify date/time @@ -795,19 +824,58 @@ static uint32_t construct_dir_record(struct file_list_t *file_list, void **direc rr_save_size = directory_table_size; rr_save_ptr = rr_directory_table; - /* - * RECORD 2 - * All the circus one more time, this time with '1' - */ - iso9660_cp2heap(&rr_directory_table, rr_directory_table_start, iso9660_original_size - 1, &directory_table_size); - iso9660_cp2heap(&rr_directory_table, &one, sizeof(uint8_t), &directory_table_size); + /* Add record for directory '..' */ + parent = parent_index[rr_file_list->parent_id - 1]; + + /* Assign modify date/time values */ + ts = localtime(&parent->mtime); + mdate_time[0] = ts->tm_year; + mdate_time[1] = ts->tm_mon + 1; + mdate_time[2] = ts->tm_mday; + mdate_time[3] = ts->tm_hour; + mdate_time[4] = ts->tm_min; + mdate_time[5] = ts->tm_sec; + mdate_time[6] = ts->tm_gmtoff / 60 / 15; + + /* Assign access date/time values */ + ts = localtime(&parent->atime); + adate_time[0] = ts->tm_year; + adate_time[1] = ts->tm_mon + 1; + adate_time[2] = ts->tm_mday; + adate_time[3] = ts->tm_hour; + adate_time[4] = ts->tm_min; + adate_time[5] = ts->tm_sec; + adate_time[6] = ts->tm_gmtoff / 60 / 15; + + /* Assign status change date/time values */ + ts = localtime(&parent->ctime); + cdate_time[0] = ts->tm_year; + cdate_time[1] = ts->tm_mon + 1; + cdate_time[2] = ts->tm_mday; + cdate_time[3] = ts->tm_hour; + cdate_time[4] = ts->tm_min; + cdate_time[5] = ts->tm_sec; + cdate_time[6] = ts->tm_gmtoff / 60 / 15; + + iso9660_data.LBA = get_int32_LSB_MSB(parent->LBA); + iso9660_data.data_len = get_int32_LSB_MSB(parent->blocks * BLOCK_SIZE); + strncpy(iso9660_data.mdate_time, mdate_time, sizeof(iso9660_data.mdate_time)); + construct_iso9660_record(&rr_directory_table, iso9660_data, &directory_table_size); + iso9660_cp2heap(&rr_directory_table, &one, iso9660_data.name_len, &directory_table_size); // File name len + + /* Add RR record */ if ((init_fields & rrip_RR) != 0) iso9660_cp2heap(&rr_directory_table, RR, sizeof(RR), &directory_table_size); - /* Write PX record */ + /* Add PX record */ if ((init_fields & rrip_PX) != 0) { - RR[4] |= 1 << 0; // PX record in use + mode = get_int32_LSB_MSB(parent->st_mode); + nlinks = get_int32_LSB_MSB(parent->st_nlink); + uid = get_int32_LSB_MSB(parent->st_uid); + gid = get_int32_LSB_MSB(parent->st_gid); + ino = get_int32_LSB_MSB(parent->st_ino); + iso9660_cp2heap(&rr_directory_table, PX, 4, &directory_table_size); iso9660_cp2heap(&rr_directory_table, &mode, sizeof(mode), &directory_table_size); iso9660_cp2heap(&rr_directory_table, &nlinks, sizeof(nlinks), &directory_table_size); @@ -816,15 +884,15 @@ static uint32_t construct_dir_record(struct file_list_t *file_list, void **direc iso9660_cp2heap(&rr_directory_table, &ino, sizeof(ino), &directory_table_size); } - /* Write TF record */ + /* Add TF record */ if ((init_fields & rrip_TF) != 0) { - RR[4] |= 1 << 7; // TF record in use iso9660_cp2heap(&rr_directory_table, TF, 5, &directory_table_size); iso9660_cp2heap(&rr_directory_table, mdate_time, sizeof(mdate_time), &directory_table_size); // Modify date/time iso9660_cp2heap(&rr_directory_table, adate_time, sizeof(adate_time), &directory_table_size); // Access date/time iso9660_cp2heap(&rr_directory_table, cdate_time, sizeof(cdate_time), &directory_table_size); // status change date/time } + /* Do padding if needed */ if (directory_table_size % 2 == 1) iso9660_cp2heap(&rr_directory_table, &zero, 1, &directory_table_size); @@ -839,22 +907,22 @@ static uint32_t construct_dir_record(struct file_list_t *file_list, void **direc if ((init_fields & rrip_PX) != 0) RR[4] |= 1 << 0; // PX record in use - if ((init_fields & rrip_NM) != 0) - RR[4] |= 1 << 3; // NM record in use if ((init_fields & rrip_TF) != 0) RR[4] |= 1 << 7; // TF record in use + if ((init_fields & rrip_NM) != 0) { + RR[4] |= 1 << 3; // NM record in use + memset(NM + 5, 0, BLOCK_SIZE - 5); - memset(NM + 5, 0, BLOCK_SIZE - 5); - - /* Prepare for another possible NM entry */ - if (rr_file_list->name_short_len >= 250) { - rest = rr_file_list->name_short_len - 250; - rr_file_list->name_short_len = 250; + /* Prepare for another possible NM entry */ + if (rr_file_list->name_short_len >= 250) { + rest = rr_file_list->name_short_len - 250; + rr_file_list->name_short_len = 250; + } + + NM[2] = 5 + rr_file_list->name_short_len; + strncpy((char *)NM + 5, rr_file_list->name_short, rr_file_list->name_short_len); } - NM[2] = 5 + rr_file_list->name_short_len; - strncpy((char *)NM + 5, rr_file_list->name_short, rr_file_list->name_short_len); - if ((init_fields & rrip_RR) != 0) iso9660_cp2heap(&rr_directory_table, RR, sizeof(RR), &directory_table_size); @@ -905,6 +973,22 @@ static uint32_t construct_dir_record(struct file_list_t *file_list, void **direc return directory_table_size; } +static int construct_iso9660_record(void **output, struct iso9660_data_t data, uint32_t *size) { + + iso9660_cp2heap(output, &zero, sizeof(uint8_t), size); // Lenght of whole entry will be added at the end + iso9660_cp2heap(output, &data.ext_attr_record, sizeof(uint8_t), size); // Ext. attr. record + iso9660_cp2heap(output, &data.LBA, sizeof(uint64_t), size); // LBA + iso9660_cp2heap(output, &data.data_len, sizeof(uint64_t), size); // Size of file/dir + iso9660_cp2heap(output, &data.mdate_time, sizeof(data.mdate_time), size); // Recording date/time + iso9660_cp2heap(output, &data.flags, sizeof(uint8_t), size); // Flags + iso9660_cp2heap(output, &zero, sizeof(uint8_t), size); // Interleaving + iso9660_cp2heap(output, &zero, sizeof(uint8_t), size); // Interleaving + iso9660_cp2heap(output, &data.volume_seq_number, sizeof(uint32_t), size); // Volume sequence number + iso9660_cp2heap(output, &data.name_len, sizeof(uint8_t), size); // File name len + + return E_OK; +} + static int blocks_count(int size) { int blocks = 0; @@ -1085,4 +1169,3 @@ static void shift_mem(void *var, int offset, int ammount) { static uint8_t set_terminator_len(mode_t mode) { return (S_ISDIR(mode)) ? 0 : 2; } - diff --git a/lib/list.c b/lib/list.c index 6b10896..07db98f 100644 --- a/lib/list.c +++ b/lib/list.c @@ -1,9 +1,9 @@ /* * list.c * - * Version: 0.1.1 + * Version: 0.1.2 * - * Release date: 20.09.2015 + * Release date: 25.09.2015 * * Copyright 2015 Vladimir (sodoma) Gozora * @@ -29,7 +29,7 @@ #include #include -int list_create(const char *dirname, struct file_list_t **flist) { +int list_create(const char *dirname, struct file_list_t **flist, struct ISO_data_t *ISO_data) { FILE *read_test = NULL; DIR *cur_dir = NULL; struct dirent *dir_content = NULL; @@ -41,7 +41,7 @@ int list_create(const char *dirname, struct file_list_t **flist) { static int level = 0; int rr_dir = 0; int path_len = 0; - int rv = 0; + int rv = E_OK; memset(tmp_conv, 0, sizeof(tmp_conv)); @@ -108,13 +108,14 @@ int list_create(const char *dirname, struct file_list_t **flist) { } /* Recursion to child directory */ - if ( !(dir_content->d_type ^ DT_DIR) && (rv == 0) ) { + if ( !(dir_content->d_type ^ DT_DIR) && (rv == E_OK) ) { rr_dir = parent_id; parent_id = dir_id; - rv = list_create(path, flist); + rv = list_create(path, flist, ISO_data); parent_id = rr_dir; + ISO_data->dir_count++; } } @@ -140,7 +141,7 @@ void list_clean(struct file_list_t *list_to_clean) { free(list_to_clean); } -struct file_list_t *list_search(struct file_list_t *file_list, char *needle) { +struct file_list_t *list_search_name(struct file_list_t *file_list, char *needle) { struct file_list_t *rv = NULL; size_t needle_len = strlen(needle); @@ -161,4 +162,3 @@ struct file_list_t *list_search(struct file_list_t *file_list, char *needle) { return rv; } - diff --git a/packaging/SLES11/.spec/ebiso-0.1.4.x86_64.spec b/packaging/SLES11/.spec/ebiso-0.1.4.x86_64.spec new file mode 100644 index 0000000..fed4d3b --- /dev/null +++ b/packaging/SLES11/.spec/ebiso-0.1.4.x86_64.spec @@ -0,0 +1,31 @@ +Name: ebiso +Version: 0.1.4 +Release: 0 +Summary: UEFI bootable ISO image creator +License: GPL +Group: Productivity/Multimedia/CD/Record +Source: ebiso-0.1.4.tgz +URL: https://github.com/gozora/ebiso +Distribution: SuSE Linux Enterprise Server 11 +Vendor: Vladimir (sodoma) Gozora +Packager: Vladimir (sodoma) Gozora +BuildArch: x86_64 + +%description +UEFI bootable ISO image creator + + +%prep +%setup + +%build +make + +%install +make install + +%files +/usr/local/bin/ebiso + +%post +%postun diff --git a/packaging/SLES11/ebiso-0.1.4-0.x86_64.rpm b/packaging/SLES11/ebiso-0.1.4-0.x86_64.rpm new file mode 100644 index 0000000..824ccd9 Binary files /dev/null and b/packaging/SLES11/ebiso-0.1.4-0.x86_64.rpm differ