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