Line data Source code
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 : 10 : #include <linux/types.h> 11 : #include <linux/nls.h> 12 : #include "isofs.h" 13 : 14 : /* 15 : * Convert Unicode 16 to UTF-8 or ASCII. 16 : */ 17 : static int 18 0 : uni16_to_x8(unsigned char *ascii, __be16 *uni, int len, struct nls_table *nls) 19 : { 20 0 : __be16 *ip, ch; 21 0 : unsigned char *op; 22 : 23 0 : ip = uni; 24 0 : op = ascii; 25 : 26 0 : while ((ch = get_unaligned(ip)) && len) { 27 0 : int llen; 28 0 : llen = nls->uni2char(be16_to_cpu(ch), op, NLS_MAX_CHARSET_SIZE); 29 0 : if (llen > 0) 30 0 : op += llen; 31 : else 32 0 : *op++ = '?'; 33 0 : ip++; 34 : 35 0 : len--; 36 : } 37 0 : *op = 0; 38 0 : return (op - ascii); 39 : } 40 : 41 : int 42 0 : get_joliet_filename(struct iso_directory_record * de, unsigned char *outname, struct inode * inode) 43 : { 44 0 : unsigned char utf8; 45 0 : struct nls_table *nls; 46 0 : unsigned char len = 0; 47 : 48 0 : utf8 = ISOFS_SB(inode->i_sb)->s_utf8; 49 0 : nls = ISOFS_SB(inode->i_sb)->s_nls_iocharset; 50 : 51 0 : if (utf8) { 52 0 : len = utf16s_to_utf8s((const wchar_t *) de->name, 53 0 : de->name_len[0] >> 1, UTF16_BIG_ENDIAN, 54 : outname, PAGE_SIZE); 55 : } else { 56 0 : len = uni16_to_x8(outname, (__be16 *) de->name, 57 0 : de->name_len[0] >> 1, nls); 58 : } 59 0 : if ((len > 2) && (outname[len-2] == ';') && (outname[len-1] == '1')) 60 0 : len -= 2; 61 : 62 : /* 63 : * Windows doesn't like periods at the end of a name, 64 : * so neither do we 65 : */ 66 0 : while (len >= 2 && (outname[len-1] == '.')) 67 0 : len--; 68 : 69 0 : return len; 70 : }