joliet.c 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. struct nls_table *nls;
  39. unsigned char len = 0;
  40. nls = ISOFS_SB(inode->i_sb)->s_nls_iocharset;
  41. if (!nls) {
  42. len = utf16s_to_utf8s((const wchar_t *) de->name,
  43. de->name_len[0] >> 1, UTF16_BIG_ENDIAN,
  44. outname, PAGE_SIZE);
  45. } else {
  46. len = uni16_to_x8(outname, (__be16 *) de->name,
  47. de->name_len[0] >> 1, nls);
  48. }
  49. if ((len > 2) && (outname[len-2] == ';') && (outname[len-1] == '1'))
  50. len -= 2;
  51. /*
  52. * Windows doesn't like periods at the end of a name,
  53. * so neither do we
  54. */
  55. while (len >= 2 && (outname[len-1] == '.'))
  56. len--;
  57. return len;
  58. }