joliet.c 1.4 KB

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