diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index bcf3734..86c8209 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -419,7 +419,11 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer) } static +#ifdef Libisofs_use_parent_for_dot_doT +int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent) +#else int write_one_dir(Ecma119Image *t, Ecma119Node *dir) +#endif { int ret; uint8_t buffer[BLOCK_SIZE]; @@ -462,7 +466,11 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir) } } len = 34 + info.suf_len; +#ifdef Libisofs_use_parent_for_dot_doT + write_one_dir_record(t, parent, 1, buf, 1, &info, 0); +#else write_one_dir_record(t, dir, 1, buf, 1, &info, 0); +#endif buf += len; for (i = 0; i < dir->info.dir->nchildren; i++) { @@ -519,13 +527,24 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir) } static +#ifdef Libisofs_use_parent_for_dot_doT + +/* ts A90309 : todo ? : rename parameter "root" to "dir" */ + +int write_dirs(Ecma119Image *t, Ecma119Node *root, Ecma119Node *parent) +#else int write_dirs(Ecma119Image *t, Ecma119Node *root) +#endif { int ret; size_t i; /* write all directory entries for this dir */ +#ifdef Libisofs_use_parent_for_dot_doT + ret = write_one_dir(t, root, parent); +#else ret = write_one_dir(t, root); +#endif if (ret < 0) { return ret; } @@ -534,7 +553,11 @@ int write_dirs(Ecma119Image *t, Ecma119Node *root) for (i = 0; i < root->info.dir->nchildren; i++) { Ecma119Node *child = root->info.dir->children[i]; if (child->type == ECMA119_DIR) { +#ifdef Libisofs_use_parent_for_dot_doT + ret = write_dirs(t, child, root); +#else ret = write_dirs(t, child); +#endif if (ret < 0) { return ret; } @@ -653,7 +676,11 @@ int ecma119_writer_write_data(IsoImageWriter *writer) t = writer->target; /* first of all, we write the directory structure */ +#ifdef Libisofs_use_parent_for_dot_doT + ret = write_dirs(t, t->root, t->root); +#else ret = write_dirs(t, t->root); +#endif if (ret < 0) { return ret; } diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index ea0a2e7..9cb05bb 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -4771,23 +4771,60 @@ struct burn_source { #endif /* LIBISOFS_WITHOUT_LIBBURN */ +/* ----------------------------- Bug Fixes ----------------------------- */ + + +/* Bug Fix : Augment ecma119.c:write_dirs() by parameter parent + and use that one for the second directory entry 001 = "..". + + Everything else seems wrong. +*/ +#define Libisofs_use_parent_for_dot_doT yes + + +/* Bug fix : Use correct size of 237 if the ER of RRIP-1.10 shal be written + (rather than size 182 of RRIP-1.12) + +*/ +#define Libisofs_rrip_1_10_er_bugfiX yes + + +/* ---------------------------- Experiments ---------------------------- */ -/* Attempt to fix several issues about inode numbers from ISO images */ /* Experiment: Ignore PX inode numbers, have boot image inode number counted by fs_give_ino_number() */ #define Libisofs_new_fs_image_inO yes + /* Experiment: Trying to avoid the risk of losing file content by duplicate inodes. iso_file_src_cmp() shall compare sizes too. */ #define Libisofs_file_src_cmp_sizE yes + /* Experiment: Revoke Ticket 144, use data file LBAs again. (will work only if not Libisofs_new_fs_image_inO and wll only be safe with Libisofs_file_src_cmp_sizE) #define Libisofs_ino_from_lbA yes */ + +/* Experiment: Write obsolete RR entries with Rock Ridge. + I suspect Solaris wants to see them. + DID NOT HELP: Solaris knows only RRIP_1991A. + + #define Libisofs_with_rrip_rR yes +*/ + + +/* Experiment: Use iso_iconv*() wrappers. + They can print errno messages and they + can avoid iconv() if the identical mapping is desired. + One could install own simple conversion capabilities. +*/ +#define Libisofs_with_iso_iconV yes + + #endif /*LIBISO_LIBISOFS_H_*/ diff --git a/libisofs/rockridge.c b/libisofs/rockridge.c index 368b008..674d513 100644 --- a/libisofs/rockridge.c +++ b/libisofs/rockridge.c @@ -381,6 +381,38 @@ int rrip_SL_append_comp(size_t *n, uint8_t ***comps, char *s, int size, char fl) return ISO_SUCCESS; } + +#ifdef Libisofs_with_rrip_rR + +/* ts A90307 */ +/** + * Add to the given tree node a RR System Use Entry. This is an obsolete + * entry from before RRIP-1.10. Nevertheless mkisofs produces it and there + * is the suspicion that Solaris takes it as indication for Rock Ridge. + * + * I once saw a copy of a RRIP spec which mentioned RR. Here i just use + * the same constant 5 bytes as produced by mkisofs. + */ +static +int rrip_add_RR(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp) +{ + uint8_t *RR; + RR = malloc(5); + if (RR == NULL) { + return ISO_OUT_OF_MEM; + } + + RR[0] = 'R'; + RR[1] = 'R'; + RR[2] = 5; + RR[3] = 1; + RR[4] = 0201; + return susp_append(t, susp, RR); +} + +#endif /* Libisofs_with_rrip_rR */ + + /** * Add a SL System Use Entry to the given tree node. This is used to store * the content of a symbolic link, and is mandatory if the tree node @@ -496,7 +528,6 @@ int aaip_add_AA(Ecma119Image *t, struct susp_info *susp, if (ret < 0) return ret; } - aapt = *data; if (!(aapt[4] & 1)) { /* Single field can be handed over directly */ @@ -554,6 +585,7 @@ int rrip_add_ER(Ecma119Image *t, struct susp_info *susp) decrease by 1." So "IEEE_P1282" would be the new form, "RRIP_1991A" is the old form. */ + ER = malloc(182); if (ER == NULL) { return ISO_OUT_OF_MEM; @@ -958,6 +990,11 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space, if (t->aaip && !t->aaip_susp_1_10) su_size += 5; +#ifdef Libisofs_with_rrip_rR + /* obsolete RR field (once in AAIP-1.09) */ + su_size += 5; +#endif + /* PX and TF, we are sure they always fit in SUA */ if (!t->rrip_version_1_10) { su_size += 44 + 26; @@ -996,7 +1033,9 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space, } else { /* "." or ".." entry */ + su_size += 5; /* NM field */ + if (type == 1 && n->parent == NULL) { /* * "." for root directory @@ -1004,7 +1043,20 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space, * ER needs a Continuation Area, thus we also need a CE entry */ su_size += 7 + 28; /* SP + CE */ - *ce = 182; /* ER of RRIP */ + +#ifdef Libisofs_rrip_1_10_er_bugfiX + + /* ER of RRIP */ + if (t->rrip_version_1_10) { + *ce = 237; + } else { + *ce = 182; + } + +#else + *ce = 182; +#endif + if (t->aaip) { *ce += 160; /* ER of AAIP */ } @@ -1095,6 +1147,11 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type, char *name = NULL; char *dest = NULL; size_t aaip_er_len= 0; + +#ifdef Libisofs_rrip_1_10_er_bugfiX + size_t rrip_er_len= 182; +#endif + size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */ int ce_is_predicted = 0; size_t aaip_sua_free= 0, aaip_len= 0; @@ -1138,6 +1195,14 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type, goto add_susp_cleanup; } +#ifdef Libisofs_with_rrip_rR + /* ts A90307 */ + ret = rrip_add_RR(t, node, info); + if (ret < 0) { + goto add_susp_cleanup; + } +#endif /* Libisofs_with_rrip_rR */ + /* PX and TF, we are sure they always fit in SUA */ ret = rrip_add_PX(t, node, info); if (ret < 0) { @@ -1448,6 +1513,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type, if (ret < 0) { goto add_susp_cleanup; } + if (type == 1 && n->parent == NULL) { /* * "." for root directory @@ -1456,6 +1522,28 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type, * Note that SP entry was already added above */ +#ifdef Libisofs_rrip_1_10_er_bugfiX + + if (t->rrip_version_1_10) { + rrip_er_len = 237; + } else { + rrip_er_len = 182; + } + if (t->aaip && !t->aaip_susp_1_10) { + aaip_er_len = 160; + } + + /* Compute length of AAIP string of root node */ + aaip_sua_free= 0; + ret = add_aa_string(t, n, info, &aaip_sua_free, &aaip_len, 1); + if (ret < 0) + goto add_susp_cleanup; + + /* Allocate the necessary CE space */ + ret = susp_add_CE(t, rrip_er_len + aaip_er_len + aaip_len, info); + +#else /* Libisofs_rrip_1_10_er_bugfiX */ + if (t->aaip && !t->aaip_susp_1_10) { aaip_er_len = 160; } @@ -1469,6 +1557,9 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type, /* Allocate the necessary CE space */ ret = susp_add_CE(t, 182 + aaip_er_len + aaip_len, info); /* 182 is RRIP-ER length */ + +#endif /* ! Libisofs_rrip_1_10_er_bugfiX */ + if (ret < 0) { goto add_susp_cleanup; } diff --git a/libisofs/util.c b/libisofs/util.c index 0e64ff2..45b687f 100644 --- a/libisofs/util.c +++ b/libisofs/util.c @@ -24,7 +24,7 @@ #include -/* if we don't have eaccess, we check file access by openning it */ +/* if we don't have eaccess, we check file access by opening it */ #ifndef HAVE_EACCESS #include #include @@ -32,6 +32,118 @@ #endif +#ifdef Libisofs_with_iso_iconV + + +/* Produce possibly inflationary error messages directly to stderr */ +static int iso_iconv_debug = 0; + + +struct iso_iconv_handle { + int status; /* bit0= open , bit1= identical mapping */ + iconv_t descr; +}; + + +/* + @param flag bit0= shortcut by identical mapping is not allowed +*/ +static +int iso_iconv_open(struct iso_iconv_handle *handle, + char *tocode, char *fromcode, int flag) +{ + handle->status = 0; + handle->descr = (iconv_t) -1; + + if (strcmp(tocode, fromcode) == 0 && !(flag & 1)) { + handle->status = 1 | 2; + return 1; + } + handle->descr = iconv_open(tocode, fromcode); + if (handle->descr == (iconv_t) -1) { + if (strlen(tocode) + strlen(fromcode) <= 160 && iso_iconv_debug) + fprintf(stderr, + "libisofs_DEBUG: iconv_open(\"%s\", \"%s\") failed: errno= %d %s\n", + tocode, fromcode, errno, strerror(errno)); + return 0; + } + handle->status = 1; + return 1; +} + + +static +size_t iso_iconv(struct iso_iconv_handle *handle, + char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft, int flag) +{ + size_t ret; + + if (!(handle->status & 1)) { + if (iso_iconv_debug) + fprintf(stderr, + "libisofs_DEBUG: iso_iconv(): iso_iconv_handle not in open state\n"); + return (size_t) -1; + } + if (handle->status & 2) { + if (inbuf == NULL || outbuf == NULL) { +null_buf:; + if (iso_iconv_debug) + fprintf(stderr, +"libisofs_DEBUG: iso_iconv(): NULL buffers not allowed in shortcut mapping\n"); + return (size_t) -1; + } + if (*inbuf == NULL || *outbuf == NULL) + goto null_buf; + while (*inbytesleft > 0 && *outbytesleft > 0) { + *((*outbuf)++) = *((*inbuf)++); + (*inbytesleft)--; + (*outbytesleft)--; + } + if (*inbytesleft > 0 && *outbytesleft <= 0) + return (size_t) -1; + return (size_t) 0; + } + ret = iconv(handle->descr, inbuf, inbytesleft, outbuf, outbytesleft); + if (ret == (size_t) -1) { + if (iso_iconv_debug) + fprintf(stderr, "libisofs_DEBUG: iconv() failed: errno= %d %s\n", + errno, strerror(errno)); + return (size_t) -1; + } + return ret; +} + + +static +int iso_iconv_close(struct iso_iconv_handle *handle, int flag) +{ + int ret; + + if (!(handle->status & 1)) { + if (iso_iconv_debug) + fprintf(stderr, + "libisofs_DEBUG: iso_iconv_close(): iso_iconv_handle not in open state\n"); + return -1; + } + handle->status &= ~1; + if (handle->status & 2) + return 0; + + ret = iconv_close(handle->descr); + if (ret == -1) { + if (iso_iconv_debug) + fprintf(stderr, + "libisofs_DEBUG: iconv_close() failed: errno= %d %s\n", + errno, strerror(errno)); + return -1; + } + return ret; +} + +#endif /* Libisofs_with_iso_iconV */ + + int int_pow(int base, int power) { int result = 1; @@ -71,7 +183,14 @@ int strconv(const char *str, const char *icharset, const char *ocharset, size_t inbytes; size_t outbytes; size_t n; + +#ifdef Libisofs_with_iso_iconV + struct iso_iconv_handle conv; + int conv_ret; +#else iconv_t conv; +#endif + char *out; char *src; char *ret; @@ -83,21 +202,41 @@ int strconv(const char *str, const char *icharset, const char *ocharset, return ISO_OUT_OF_MEM; } +#ifdef Libisofs_with_iso_iconV + conv_ret = iso_iconv_open(&conv, (char *) ocharset, (char *) icharset, 0); + if (conv_ret <= 0) { +#else conv = iconv_open(ocharset, icharset); if (conv == (iconv_t)(-1)) { +#endif + return ISO_CHARSET_CONV_ERROR; } + src = (char *)str; ret = (char *)out; +#ifdef Libisofs_with_iso_iconV + n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0); + if (n == -1) { + /* error */ + iso_iconv_close(&conv, 0); +#else n = iconv(conv, &src, &inbytes, &ret, &outbytes); if (n == -1) { /* error */ iconv_close(conv); +#endif + return ISO_CHARSET_CONV_ERROR; } *ret = '\0'; + +#ifdef Libisofs_with_iso_iconV + iso_iconv_close(&conv, 0); +#else iconv_close(conv); +#endif *output = malloc(ret - out + 1); if (*output == NULL) { @@ -113,7 +252,14 @@ int strnconv(const char *str, const char *icharset, const char *ocharset, size_t inbytes; size_t outbytes; size_t n; + +#ifdef Libisofs_with_iso_iconV + struct iso_iconv_handle conv; + int conv_ret; +#else iconv_t conv; +#endif + char *out; char *src; char *ret; @@ -125,21 +271,40 @@ int strnconv(const char *str, const char *icharset, const char *ocharset, return ISO_OUT_OF_MEM; } +#ifdef Libisofs_with_iso_iconV + conv_ret = iso_iconv_open(&conv, (char *) ocharset, (char *) icharset, 0); + if (conv_ret <= 0) { +#else conv = iconv_open(ocharset, icharset); if (conv == (iconv_t)(-1)) { +#endif + return ISO_CHARSET_CONV_ERROR; } src = (char *)str; ret = (char *)out; +#ifdef Libisofs_with_iso_iconV + n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0); + if (n == -1) { + /* error */ + iso_iconv_close(&conv, 0); +#else n = iconv(conv, &src, &inbytes, &ret, &outbytes); if (n == -1) { /* error */ iconv_close(conv); +#endif + return ISO_CHARSET_CONV_ERROR; } *ret = '\0'; + +#ifdef Libisofs_with_iso_iconV + iso_iconv_close(&conv, 0); +#else iconv_close(conv); +#endif *output = malloc(ret - out + 1); if (*output == NULL) { @@ -159,7 +324,17 @@ int strnconv(const char *str, const char *icharset, const char *ocharset, static int str2wchar(const char *icharset, const char *input, wchar_t **output) { + +#ifdef Libisofs_with_iso_iconV + struct iso_iconv_handle conv; + int conv_ret; +#else iconv_t conv; +#endif + + /* ts A90308 : that while loop smells like a potential show stopper */ + size_t loop_counter = 0, loop_limit = 3; + size_t inbytes; size_t outbytes; char *ret; @@ -171,12 +346,20 @@ int str2wchar(const char *icharset, const char *input, wchar_t **output) return ISO_NULL_POINTER; } + +#ifdef Libisofs_with_iso_iconV + conv_ret = iso_iconv_open(&conv, "WCHAR_T", (char *) icharset, 0); + if (conv_ret <= 0) { +#else conv = iconv_open("WCHAR_T", icharset); if (conv == (iconv_t)-1) { +#endif + return ISO_CHARSET_CONV_ERROR; } inbytes = strlen(input); + loop_limit = inbytes + 3; outbytes = (inbytes + 1) * sizeof(wchar_t); /* we are sure that numchars <= inbytes */ @@ -187,14 +370,18 @@ int str2wchar(const char *icharset, const char *input, wchar_t **output) ret = (char *)wstr; src = (char *)input; + +#ifdef Libisofs_with_iso_iconV + n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0); +#else n = iconv(conv, &src, &inbytes, &ret, &outbytes); +#endif + while (n == -1) { if (errno == E2BIG) { /* error, should never occur */ - iconv_close(conv); - free(wstr); - return ISO_CHARSET_CONV_ERROR; + goto conv_error; } else { wchar_t *wret; @@ -214,14 +401,41 @@ int str2wchar(const char *icharset, const char *input, wchar_t **output) if (!inbytes) break; + + /* Just to appease my remorse about unclear loop ends */ + loop_counter++; + if (loop_counter > loop_limit) + goto conv_error; + +#ifdef Libisofs_with_iso_iconV + n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0); +#else n = iconv(conv, &src, &inbytes, &ret, &outbytes); +#endif + } } + +#ifdef Libisofs_with_iso_iconV + iso_iconv_close(&conv, 0); +#else iconv_close(conv); +#endif *( (wchar_t *)ret )='\0'; *output = wstr; return ISO_SUCCESS; + +conv_error:; + +#ifdef Libisofs_with_iso_iconV + iso_iconv_close(&conv, 0); +#else + iconv_close(conv); +#endif + + free(wstr); + return ISO_CHARSET_CONV_ERROR; } int str2ascii(const char *icharset, const char *input, char **output) @@ -231,12 +445,26 @@ int str2ascii(const char *icharset, const char *input, char **output) char *ret; char *ret_; char *src; + +#ifdef Libisofs_with_iso_iconV + struct iso_iconv_handle conv; + int conv_ret; +#else iconv_t conv; +#endif + + /* ts A90308 : that while loop smells like a potential show stopper */ + size_t loop_counter = 0, loop_limit = 3; + + /* ts A90308 : fallback in case that iconv() is too demanding for system */ + unsigned char *cpt; + size_t numchars; size_t outbytes; size_t inbytes; size_t n; + if (icharset == NULL || input == NULL || output == NULL) { return ISO_NULL_POINTER; } @@ -247,12 +475,13 @@ int str2ascii(const char *icharset, const char *input, char **output) */ result = str2wchar(icharset, input, &wsrc_); if (result < 0) { - return result; + goto fallback; } src = (char *)wsrc_; numchars = wcslen(wsrc_); inbytes = numchars * sizeof(wchar_t); + loop_limit = inbytes + 3; ret_ = malloc(numchars + 1); if (ret_ == NULL) { @@ -262,14 +491,27 @@ int str2ascii(const char *icharset, const char *input, char **output) ret = ret_; /* initialize iconv */ + +#ifdef Libisofs_with_iso_iconV + conv_ret = iso_iconv_open(&conv, "ASCII", "WCHAR_T", 0); + if (conv_ret <= 0) { +#else conv = iconv_open("ASCII", "WCHAR_T"); if (conv == (iconv_t)-1) { +#endif + free(wsrc_); free(ret_); - return ISO_CHARSET_CONV_ERROR; + goto fallback; } + +#ifdef Libisofs_with_iso_iconV + n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0); +#else n = iconv(conv, &src, &inbytes, &ret, &outbytes); +#endif + while (n == -1) { /* The destination buffer is too small. Stops here. */ if (errno == E2BIG) @@ -299,16 +541,41 @@ int str2ascii(const char *icharset, const char *input, char **output) if (!inbytes) break; + /* Just to appease my remorse about unclear loop ends */ + loop_counter++; + if (loop_counter > loop_limit) + break; + +#ifdef Libisofs_with_iso_iconV + n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0); +#else n = iconv(conv, &src, &inbytes, &ret, &outbytes); +#endif + } +#ifdef Libisofs_with_iso_iconV + iso_iconv_close(&conv, 0); +#else iconv_close(conv); +#endif *ret='\0'; free(wsrc_); *output = ret_; return ISO_SUCCESS; + +fallback:; + /* Assume to have a single byte charset with ASCII as core. + Anything suspicious will be mapped to '_'. + */ + *output = strdup(input); + for (cpt = (unsigned char *) *output; *cpt; cpt++) { + if (*cpt < 32 || *cpt > 126) + *cpt = '_'; + } + return ISO_SUCCESS; } static @@ -343,7 +610,17 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output) char *src; char *ret; char *ret_; + +#ifdef Libisofs_with_iso_iconV + struct iso_iconv_handle conv; + int conv_ret; +#else iconv_t conv; +#endif + + /* ts A90308 : that while loop smells like a potential show stopper */ + size_t loop_counter = 0, loop_limit = 3; + size_t numchars; size_t outbytes; size_t inbytes; @@ -365,6 +642,7 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output) numchars = wcslen(wsrc_); inbytes = numchars * sizeof(wchar_t); + loop_limit = inbytes + 3; ret_ = malloc((numchars+1) * sizeof(uint16_t)); if (ret_ == NULL) { @@ -374,14 +652,27 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output) ret = ret_; /* initialize iconv */ + +#ifdef Libisofs_with_iso_iconV + conv_ret = iso_iconv_open(&conv, "UCS-2BE", "WCHAR_T", 0); + if (conv_ret <= 0) { +#else conv = iconv_open("UCS-2BE", "WCHAR_T"); if (conv == (iconv_t)-1) { +#endif + free(wsrc_); free(ret_); return ISO_CHARSET_CONV_ERROR; } + +#ifdef Libisofs_with_iso_iconV + n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0); +#else n = iconv(conv, &src, &inbytes, &ret, &outbytes); +#endif + while (n == -1) { /* The destination buffer is too small. Stops here. */ if (errno == E2BIG) @@ -411,10 +702,24 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output) if (!inbytes) break; + /* Just to appease my remorse about unclear loop ends */ + loop_counter++; + if (loop_counter > loop_limit) + break; + +#ifdef Libisofs_with_iso_iconV + n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0); +#else n = iconv(conv, &src, &inbytes, &ret, &outbytes); +#endif + } +#ifdef Libisofs_with_iso_iconV + iso_iconv_close(&conv, 0); +#else iconv_close(conv); +#endif /* close the ucs string */ set_ucsbe((uint16_t*) ret, '\0'); @@ -1233,7 +1538,14 @@ char *ucs2str(const char *buf, size_t len) { size_t outbytes, inbytes; char *str, *src, *out; + +#ifdef Libisofs_with_iso_iconV + struct iso_iconv_handle conv; + int conv_ret; +#else iconv_t conv; +#endif + size_t n; inbytes = len; @@ -1250,20 +1562,32 @@ char *ucs2str(const char *buf, size_t len) */ setlocale(LC_CTYPE, ""); +#ifdef Libisofs_with_iso_iconV + conv_ret = iso_iconv_open(&conv, iso_get_local_charset(0), "UCS-2BE", 0); + if (conv_ret <= 0) { +#else conv = iconv_open(iso_get_local_charset(0), "UCS-2BE"); if (conv == (iconv_t)(-1)) { +#endif + return NULL; } src = (char *)buf; str = (char *)out; + +#ifdef Libisofs_with_iso_iconV + n = iso_iconv(&conv, &src, &inbytes, &str, &outbytes, 0); + iso_iconv_close(&conv, 0); +#else n = iconv(conv, &src, &inbytes, &str, &outbytes); + iconv_close(conv); +#endif + if (n == -1) { /* error */ - iconv_close(conv); return NULL; } - iconv_close(conv); *str = '\0'; /* remove trailing spaces */ @@ -1292,3 +1616,4 @@ int iso_lib_is_compatible(int major, int minor, int micro) && (cminor > minor || (cminor == minor && cmicro >= micro))); } +