iconv-unix_unix_c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. $OpenBSD: iconv-unix_unix_c,v 1.1 2015/05/11 21:19:23 czarkoff Exp $
  2. --- unix/unix.c.orig Sat Jan 24 00:31:26 2009
  3. +++ unix/unix.c Sat May 9 13:31:19 2015
  4. @@ -30,6 +30,9 @@
  5. #define UNZIP_INTERNAL
  6. #include "unzip.h"
  7. +#include <iconv.h>
  8. +#include <langinfo.h>
  9. +
  10. #ifdef SCO_XENIX
  11. # define SYSNDIR
  12. #else /* SCO Unix, AIX, DNIX, TI SysV, Coherent 4.x, ... */
  13. @@ -1874,3 +1877,102 @@ static void qlfix(__G__ ef_ptr, ef_len)
  14. }
  15. }
  16. #endif /* QLZIP */
  17. +
  18. +
  19. +typedef struct {
  20. + char *local_charset;
  21. + char *archive_charset;
  22. +} CHARSET_MAP;
  23. +
  24. +/* A mapping of local <-> archive charsets used by default to convert filenames
  25. + * of DOS/Windows Zip archives. Currently very basic. */
  26. +static CHARSET_MAP dos_charset_map[] = {
  27. + { "ANSI_X3.4-1968", "CP850" },
  28. + { "ISO-8859-1", "CP850" },
  29. + { "CP1252", "CP850" },
  30. + { "UTF-8", "CP866" },
  31. + { "KOI8-R", "CP866" },
  32. + { "KOI8-U", "CP866" },
  33. + { "ISO-8859-5", "CP866" }
  34. +};
  35. +
  36. +char OEM_CP[MAX_CP_NAME] = "";
  37. +char ISO_CP[MAX_CP_NAME] = "";
  38. +
  39. +/* Try to guess the default value of OEM_CP based on the current locale.
  40. + * ISO_CP is left alone for now. */
  41. +void init_conversion_charsets()
  42. +{
  43. + const char *local_charset;
  44. + int i;
  45. +
  46. + /* Make a guess only if OEM_CP not already set. */
  47. + if(*OEM_CP == '\0') {
  48. + local_charset = nl_langinfo(CODESET);
  49. + for(i = 0; i < sizeof(dos_charset_map)/sizeof(CHARSET_MAP); i++)
  50. + if(!strcasecmp(local_charset, dos_charset_map[i].local_charset)) {
  51. + strncpy(OEM_CP, dos_charset_map[i].archive_charset,
  52. + sizeof(OEM_CP));
  53. + break;
  54. + }
  55. + }
  56. +}
  57. +
  58. +/* Convert a string from one encoding to the current locale using iconv().
  59. + * Be as non-intrusive as possible. If error is encountered during covertion
  60. + * just leave the string intact. */
  61. +static void charset_to_intern(char *string, char *from_charset)
  62. +{
  63. + iconv_t cd;
  64. + char *s,*d, *buf;
  65. + size_t slen, dlen, buflen;
  66. + const char *local_charset;
  67. +
  68. + if(*from_charset == '\0')
  69. + return;
  70. +
  71. + buf = NULL;
  72. + local_charset = nl_langinfo(CODESET);
  73. +
  74. + if((cd = iconv_open(local_charset, from_charset)) == (iconv_t)-1)
  75. + return;
  76. +
  77. + slen = strlen(string);
  78. + s = string;
  79. +
  80. + /* Make sure OUTBUFSIZ + 1 never ends up smaller than FILNAMSIZ
  81. + * as this function also gets called with G.outbuf in fileio.c
  82. + */
  83. + buflen = FILNAMSIZ;
  84. + if (OUTBUFSIZ + 1 < FILNAMSIZ)
  85. + {
  86. + buflen = OUTBUFSIZ + 1;
  87. + }
  88. +
  89. + d = buf = malloc(buflen);
  90. + if(!d)
  91. + goto cleanup;
  92. +
  93. + bzero(buf,buflen);
  94. + dlen = buflen - 1;
  95. +
  96. + if(iconv(cd, &s, &slen, &d, &dlen) == (size_t)-1)
  97. + goto cleanup;
  98. + strncpy(string, buf, buflen);
  99. +
  100. + cleanup:
  101. + free(buf);
  102. + iconv_close(cd);
  103. +}
  104. +
  105. +/* Convert a string from OEM_CP to the current locale charset. */
  106. +inline void oem_intern(char *string)
  107. +{
  108. + charset_to_intern(string, OEM_CP);
  109. +}
  110. +
  111. +/* Convert a string from ISO_CP to the current locale charset. */
  112. +inline void iso_intern(char *string)
  113. +{
  114. + charset_to_intern(string, ISO_CP);
  115. +}