From a97e96c604527dd02aa60cb9e736651876675866 Mon Sep 17 00:00:00 2001 From: Mario Danic Date: Sat, 12 May 2007 00:30:04 +0000 Subject: [PATCH] Implemented complete iso PVM and workaround charset problems --- libisofs/ecma119.c | 30 +++++++++++++++-- libisofs/libisofs.h | 33 +++++++++++++++++++ libisofs/util.c | 78 +++++++++++++++++++++++++++++++++++++++------ libisofs/volume.c | 30 +++++++++++++++++ libisofs/volume.h | 6 ++++ test/iso.c | 4 +++ 6 files changed, 169 insertions(+), 12 deletions(-) diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index 8de00dd..017680d 100755 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -442,11 +442,21 @@ write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf) char *pub_id = str2ascii(volume->publisher_id); char *data_id = str2ascii(volume->data_preparer_id); char *volset_id = str2ascii(t->volset->volset_id); - + + char *system_id = str2ascii(volume->system_id); + char *application_id = str2ascii(volume->application_id); + char *copyright_file_id = str2ascii(volume->copyright_file_id); + char *abstract_file_id = str2ascii(volume->abstract_file_id); + char *biblio_file_id = str2ascii(volume->biblio_file_id); + vol->vol_desc_type[0] = 1; memcpy(vol->std_identifier, "CD001", 5); vol->vol_desc_version[0] = 1; - memcpy(vol->system_id, "SYSID", 5); + if (system_id) + strncpy((char*)vol->system_id, system_id, 32); + else + /* put linux by default? */ + memcpy(vol->system_id, "LINUX", 5); if (vol_id) strncpy((char*)vol->volume_id, vol_id, 32); iso_bb(vol->vol_space_size, t->vol_space_size, 4); @@ -459,10 +469,19 @@ write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf) write_one_dir_record(t, t->root, 3, vol->root_dir_record); + /* mmm, why not check for null? */ strncpy((char*)vol->vol_set_id, volset_id, 128); strncpy((char*)vol->publisher_id, pub_id, 128); strncpy((char*)vol->data_prep_id, data_id, 128); - strncpy((char*)vol->application_id, "APPID", 128); + + if (application_id) + strncpy((char*)vol->application_id, application_id, 128); + if (copyright_file_id) + strncpy((char*)vol->copyright_file_id, copyright_file_id, 37); + if (abstract_file_id) + strncpy((char*)vol->abstract_file_id, abstract_file_id, 37); + if (biblio_file_id) + strncpy((char*)vol->bibliographic_file_id, biblio_file_id, 37); iso_datetime_17(vol->vol_creation_time, t->now); iso_datetime_17(vol->vol_modification_time, t->now); @@ -473,6 +492,11 @@ write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf) free(volset_id); free(pub_id); free(data_id); + free(system_id); + free(application_id); + free(copyright_file_id); + free(abstract_file_id); + free(biblio_file_id); } static void diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 0d29cad..088a2ca 100755 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -84,6 +84,39 @@ void iso_volume_set_publisher_id(struct iso_volume *volume, void iso_volume_set_data_preparer_id(struct iso_volume *volume, const char *data_preparer_id); +/** + * Fill in the system id for a volume. Up to 32 characters. + */ +void iso_volume_set_system_id(struct iso_volume *volume, + const char *system_id); + +/** + * Fill in the application id for a volume. Up to 128 chars. + */ +void iso_volume_set_application_id(struct iso_volume *volume, + const char *application_id); + +/** + * Fill copyright information for the volume. Usually this refers + * to a file on disc. Up to 37 characters. + */ +void iso_volume_set_copyright_file_id(struct iso_volume *volume, + const char *copyright_file_id); + +/** + * Fill abstract information for the volume. Usually this refers + * to a file on disc. Up to 37 characters. + */ +void iso_volume_set_abstract_file_id(struct iso_volume *volume, + const char *abstract_file_id); + +/** + * Fill biblio information for the volume. Usually this refers + * to a file on disc. Up to 37 characters. + */ +void iso_volume_set_biblio_file_id(struct iso_volume *volume, + const char *biblio_file_id); + /** * Locate a node by its path on disc. * diff --git a/libisofs/util.c b/libisofs/util.c index 2187b6f..bfa9610 100755 --- a/libisofs/util.c +++ b/libisofs/util.c @@ -35,16 +35,63 @@ int round_up(int n, int mul) return div_up(n, mul) * mul; } +/** + * Convert a str in a specified codeset to WCHAR_T. + * The result must be free() when no more needed + */ +static wchar_t *str2wchar(const char *str, const char *codeset) +{ + iconv_t conv; + size_t inbytes; + size_t outbytes; + char *ret; + char *src; + wchar_t *wstr; + size_t n; + + conv = iconv_open("WCHAR_T", codeset); + if (conv == (iconv_t)-1) { + perror("Invalid encodings\n"); + return NULL; + } + + inbytes = strlen(str); + outbytes = (inbytes + 1) * sizeof(wchar_t); + + /* we are sure that numchars <= inbytes */ + wstr = malloc(outbytes); + ret = (char *)wstr; + src = (char *)str; + + n = iconv(conv, &src, &inbytes, &ret, &outbytes); + if (n == -1) { + /* error, should never occur */ + /* + * FIXME + * The above assumption is not always true, because the str could + * actually not be encoded in specified codeset. This can lead to + * problems if, for example, a file is not in UTF-8. You should + * take care about this in a way like str2ascii + */ + perror("Convert error\n"); + return NULL; + } + iconv_close(conv); + + //TODO is needed this?? + *( (wchar_t *)ret )='\0'; + return wstr; +} + /* this function must always return a name * since the caller never checks if a NULL * is returned. It also avoids some warnings. */ char *str2ascii(const char *src_arg) { - wchar_t wsrc_[NAME_BUFFER_SIZE]; - char *src = (char*)wsrc_; - char *ret_; + wchar_t *wsrc_; char *ret; - mbstate_t state; + char *ret_; + char *src; iconv_t conv; size_t numchars; size_t outbytes; @@ -56,11 +103,20 @@ char *str2ascii(const char *src_arg) /* convert the string to a wide character string. Note: outbytes * is in fact the number of characters in the string and doesn't - * include the last NULL character. */ - memset(&state, 0, sizeof(state)); - numchars = mbsrtowcs(wsrc_, &src_arg, NAME_BUFFER_SIZE-1, &state); - if (numchars < 0) + * include the last NULL character. + * + * For now, just assume input to be in UTF-8, we can change + * this later. + */ + + wsrc_ = str2wchar(src_arg, "UTF-8"); + + if (!wsrc_) return NULL; + + src = (char *)wsrc_; + numchars = wcslen(wsrc_); + inbytes = numchars * sizeof(wchar_t); @@ -70,8 +126,10 @@ char *str2ascii(const char *src_arg) /* initialize iconv */ conv = iconv_open("ASCII", "WCHAR_T"); - if (conv == (iconv_t)-1) + if (conv == (iconv_t)-1) { + free(wsrc_); return NULL; + } n = iconv(conv, &src, &inbytes, &ret, &outbytes); while(n == -1) { @@ -109,6 +167,8 @@ char *str2ascii(const char *src_arg) iconv_close(conv); *ret='\0'; + free(wsrc_); + return ret_; } diff --git a/libisofs/volume.c b/libisofs/volume.c index 23f22b4..d87b7d1 100755 --- a/libisofs/volume.c +++ b/libisofs/volume.c @@ -109,6 +109,36 @@ void iso_volume_set_data_preparer_id(struct iso_volume *volume, volume->data_preparer_id = strdup(data_preparer_id); } +void iso_volume_set_system_id(struct iso_volume *volume, + const char *system_id) +{ + volume->system_id = strdup(system_id); +} + +void iso_volume_set_application_id(struct iso_volume *volume, + const char *application_id) +{ + volume->application_id = strdup(application_id); +} + +void iso_volume_set_copyright_file_id(struct iso_volume *volume, + const char *copyright_file_id) +{ + volume->copyright_file_id = strdup(copyright_file_id); +} + +void iso_volume_set_abstract_file_id(struct iso_volume *volume, + const char *abstract_file_id) +{ + volume->abstract_file_id = strdup(abstract_file_id); +} + +void iso_volume_set_biblio_file_id(struct iso_volume *volume, + const char *biblio_file_id) +{ + volume->biblio_file_id = strdup(biblio_file_id); +} + struct iso_tree_node * iso_tree_volume_path_to_node(struct iso_volume *volume, const char *path) { diff --git a/libisofs/volume.h b/libisofs/volume.h index 8903186..79178b5 100755 --- a/libisofs/volume.h +++ b/libisofs/volume.h @@ -24,6 +24,12 @@ struct iso_volume char *volume_id; /**< Volume identifier. */ char *publisher_id; /**< Volume publisher. */ char *data_preparer_id; /**< Volume data preparer. */ + + char *system_id; /**< Volume system identifier. */ + char *application_id; /**< Volume application id */ + char *copyright_file_id; + char *abstract_file_id; + char *biblio_file_id; }; /** diff --git a/test/iso.c b/test/iso.c index afa9cf2..0c09fa8 100644 --- a/test/iso.c +++ b/test/iso.c @@ -95,6 +95,10 @@ int main(int argc, char **argv) } volume = iso_volume_new_with_root( "VOLID", "PUBID", "PREPID", root ); volset = iso_volset_new( volume, "VOLSETID" ); + + //some tests + iso_volume_set_application_id(volume, "Libburnia"); + iso_volume_set_copyright_file_id(volume, "LICENSE"); src = iso_source_new_ecma119(volset, 0, level, flags);