joliet.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /*
  2. * linux/fs/isofs/joliet.c
  3. *
  4. * (C) 1996 Gordon Chaffee
  5. *
  6. * Joliet: Microsoft's Unicode extensions to iso9660
  7. */
  8. #include <linux/types.h>
  9. #include <linux/nls.h>
  10. #include "isofs.h"
  11. /*
  12. * Convert Unicode 16 to UTF-8 or ASCII.
  13. */
  14. static int
  15. uni16_to_x8(unsigned char *ascii, __be16 *uni, int len, struct nls_table *nls)
  16. {
  17. __be16 *ip, ch;
  18. unsigned char *op;
  19. ip = uni;
  20. op = ascii;
  21. while ((ch = get_unaligned(ip)) && len) {
  22. int llen;
  23. llen = nls->uni2char(be16_to_cpu(ch), op, NLS_MAX_CHARSET_SIZE);
  24. if (llen > 0)
  25. op += llen;
  26. else
  27. *op++ = '?';
  28. ip++;
  29. len--;
  30. }
  31. *op = 0;
  32. return (op - ascii);
  33. }
  34. int
  35. get_joliet_filename(struct iso_directory_record * de, unsigned char *outname, struct inode * inode)
  36. {
  37. unsigned char utf8;
  38. struct nls_table *nls;
  39. unsigned char len = 0;
  40. utf8 = ISOFS_SB(inode->i_sb)->s_utf8;
  41. nls = ISOFS_SB(inode->i_sb)->s_nls_iocharset;
  42. if (utf8) {
  43. len = utf16s_to_utf8s((const wchar_t *) de->name,
  44. de->name_len[0] >> 1, UTF16_BIG_ENDIAN,
  45. outname, PAGE_SIZE);
  46. } else {
  47. len = uni16_to_x8(outname, (__be16 *) de->name,
  48. de->name_len[0] >> 1, nls);
  49. }
  50. if ((len > 2) && (outname[len-2] == ';') && (outname[len-1] == '1'))
  51. len -= 2;
  52. /*
  53. * Windows doesn't like periods at the end of a name,
  54. * so neither do we
  55. */
  56. while (len >= 2 && (outname[len-1] == '.'))
  57. len--;
  58. return len;
  59. }