jfs_unicode.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) International Business Machines Corp., 2000-2004
  4. */
  5. #include <linux/fs.h>
  6. #include <linux/slab.h>
  7. #include "jfs_incore.h"
  8. #include "jfs_filsys.h"
  9. #include "jfs_unicode.h"
  10. #include "jfs_debug.h"
  11. /*
  12. * NAME: jfs_strfromUCS()
  13. *
  14. * FUNCTION: Convert little-endian unicode string to character string
  15. *
  16. */
  17. int jfs_strfromUCS_le(char *to, const __le16 * from,
  18. int len, struct nls_table *codepage)
  19. {
  20. int i;
  21. int outlen = 0;
  22. static int warn_again = 5; /* Only warn up to 5 times total */
  23. int warn = !!warn_again; /* once per string */
  24. if (codepage) {
  25. for (i = 0; (i < len) && from[i]; i++) {
  26. int charlen;
  27. charlen =
  28. codepage->uni2char(le16_to_cpu(from[i]),
  29. &to[outlen],
  30. NLS_MAX_CHARSET_SIZE);
  31. if (charlen > 0)
  32. outlen += charlen;
  33. else
  34. to[outlen++] = '?';
  35. }
  36. } else {
  37. for (i = 0; (i < len) && from[i]; i++) {
  38. if (unlikely(le16_to_cpu(from[i]) & 0xff00)) {
  39. to[i] = '?';
  40. if (unlikely(warn)) {
  41. warn--;
  42. warn_again--;
  43. printk(KERN_ERR
  44. "non-latin1 character 0x%x found in JFS file name\n",
  45. le16_to_cpu(from[i]));
  46. printk(KERN_ERR
  47. "mount with iocharset=utf8 to access\n");
  48. }
  49. }
  50. else
  51. to[i] = (char) (le16_to_cpu(from[i]));
  52. }
  53. outlen = i;
  54. }
  55. to[outlen] = 0;
  56. return outlen;
  57. }
  58. /*
  59. * NAME: jfs_strtoUCS()
  60. *
  61. * FUNCTION: Convert character string to unicode string
  62. *
  63. */
  64. static int jfs_strtoUCS(wchar_t * to, const unsigned char *from, int len,
  65. struct nls_table *codepage)
  66. {
  67. int charlen;
  68. int i;
  69. if (codepage) {
  70. for (i = 0; len && *from; i++, from += charlen, len -= charlen)
  71. {
  72. charlen = codepage->char2uni(from, len, &to[i]);
  73. if (charlen < 1) {
  74. jfs_err("jfs_strtoUCS: char2uni returned %d.",
  75. charlen);
  76. jfs_err("charset = %s, char = 0x%x",
  77. codepage->charset, *from);
  78. return charlen;
  79. }
  80. }
  81. } else {
  82. for (i = 0; (i < len) && from[i]; i++)
  83. to[i] = (wchar_t) from[i];
  84. }
  85. to[i] = 0;
  86. return i;
  87. }
  88. /*
  89. * NAME: get_UCSname()
  90. *
  91. * FUNCTION: Allocate and translate to unicode string
  92. *
  93. */
  94. int get_UCSname(struct component_name * uniName, struct dentry *dentry)
  95. {
  96. struct nls_table *nls_tab = JFS_SBI(dentry->d_sb)->nls_tab;
  97. int length = dentry->d_name.len;
  98. if (length > JFS_NAME_MAX)
  99. return -ENAMETOOLONG;
  100. uniName->name =
  101. kmalloc_array(length + 1, sizeof(wchar_t), GFP_NOFS);
  102. if (uniName->name == NULL)
  103. return -ENOMEM;
  104. uniName->namlen = jfs_strtoUCS(uniName->name, dentry->d_name.name,
  105. length, nls_tab);
  106. if (uniName->namlen < 0) {
  107. kfree(uniName->name);
  108. return uniName->namlen;
  109. }
  110. return 0;
  111. }