Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *   Copyright (C) International Business Machines Corp., 2000-2004
0004  */
0005 
0006 #include <linux/fs.h>
0007 #include <linux/slab.h>
0008 #include "jfs_incore.h"
0009 #include "jfs_filsys.h"
0010 #include "jfs_unicode.h"
0011 #include "jfs_debug.h"
0012 
0013 /*
0014  * NAME:    jfs_strfromUCS()
0015  *
0016  * FUNCTION:    Convert little-endian unicode string to character string
0017  *
0018  */
0019 int jfs_strfromUCS_le(char *to, const __le16 * from,
0020               int len, struct nls_table *codepage)
0021 {
0022     int i;
0023     int outlen = 0;
0024     static int warn_again = 5;  /* Only warn up to 5 times total */
0025     int warn = !!warn_again;    /* once per string */
0026 
0027     if (codepage) {
0028         for (i = 0; (i < len) && from[i]; i++) {
0029             int charlen;
0030             charlen =
0031                 codepage->uni2char(le16_to_cpu(from[i]),
0032                            &to[outlen],
0033                            NLS_MAX_CHARSET_SIZE);
0034             if (charlen > 0)
0035                 outlen += charlen;
0036             else
0037                 to[outlen++] = '?';
0038         }
0039     } else {
0040         for (i = 0; (i < len) && from[i]; i++) {
0041             if (unlikely(le16_to_cpu(from[i]) & 0xff00)) {
0042                 to[i] = '?';
0043                 if (unlikely(warn)) {
0044                     warn--;
0045                     warn_again--;
0046                     printk(KERN_ERR
0047             "non-latin1 character 0x%x found in JFS file name\n",
0048                            le16_to_cpu(from[i]));
0049                     printk(KERN_ERR
0050                 "mount with iocharset=utf8 to access\n");
0051                 }
0052 
0053             }
0054             else
0055                 to[i] = (char) (le16_to_cpu(from[i]));
0056         }
0057         outlen = i;
0058     }
0059     to[outlen] = 0;
0060     return outlen;
0061 }
0062 
0063 /*
0064  * NAME:    jfs_strtoUCS()
0065  *
0066  * FUNCTION:    Convert character string to unicode string
0067  *
0068  */
0069 static int jfs_strtoUCS(wchar_t * to, const unsigned char *from, int len,
0070         struct nls_table *codepage)
0071 {
0072     int charlen;
0073     int i;
0074 
0075     if (codepage) {
0076         for (i = 0; len && *from; i++, from += charlen, len -= charlen)
0077         {
0078             charlen = codepage->char2uni(from, len, &to[i]);
0079             if (charlen < 1) {
0080                 jfs_err("jfs_strtoUCS: char2uni returned %d.",
0081                     charlen);
0082                 jfs_err("charset = %s, char = 0x%x",
0083                     codepage->charset, *from);
0084                 return charlen;
0085             }
0086         }
0087     } else {
0088         for (i = 0; (i < len) && from[i]; i++)
0089             to[i] = (wchar_t) from[i];
0090     }
0091 
0092     to[i] = 0;
0093     return i;
0094 }
0095 
0096 /*
0097  * NAME:    get_UCSname()
0098  *
0099  * FUNCTION:    Allocate and translate to unicode string
0100  *
0101  */
0102 int get_UCSname(struct component_name * uniName, struct dentry *dentry)
0103 {
0104     struct nls_table *nls_tab = JFS_SBI(dentry->d_sb)->nls_tab;
0105     int length = dentry->d_name.len;
0106 
0107     if (length > JFS_NAME_MAX)
0108         return -ENAMETOOLONG;
0109 
0110     uniName->name =
0111         kmalloc_array(length + 1, sizeof(wchar_t), GFP_NOFS);
0112 
0113     if (uniName->name == NULL)
0114         return -ENOMEM;
0115 
0116     uniName->namlen = jfs_strtoUCS(uniName->name, dentry->d_name.name,
0117                        length, nls_tab);
0118 
0119     if (uniName->namlen < 0) {
0120         kfree(uniName->name);
0121         return uniName->namlen;
0122     }
0123 
0124     return 0;
0125 }