b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100 1) // SPDX-License-Identifier: GPL-2.0
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3) * linux/fs/isofs/joliet.c
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 4) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 5) * (C) 1996 Gordon Chaffee
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 6) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 7) * Joliet: Microsoft's Unicode extensions to iso9660
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 8) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 9)
94f2f715771d0 (Al Viro 2005-04-25 18:32:12 -0700 10) #include <linux/types.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 11) #include <linux/nls.h>
94f2f715771d0 (Al Viro 2005-04-25 18:32:12 -0700 12) #include "isofs.h"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 13)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 14) /*
4de151d8cd255 (Alexey Dobriyan 2006-03-22 00:13:35 +0100 15) * Convert Unicode 16 to UTF-8 or ASCII.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 16) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 17) static int
d02d48d8650bf (Al Viro 2005-12-24 14:33:09 -0500 18) uni16_to_x8(unsigned char *ascii, __be16 *uni, int len, struct nls_table *nls)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 19) {
d02d48d8650bf (Al Viro 2005-12-24 14:33:09 -0500 20) __be16 *ip, ch;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 21) unsigned char *op;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 22)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 23) ip = uni;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 24) op = ascii;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 25)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 26) while ((ch = get_unaligned(ip)) && len) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 27) int llen;
d02d48d8650bf (Al Viro 2005-12-24 14:33:09 -0500 28) llen = nls->uni2char(be16_to_cpu(ch), op, NLS_MAX_CHARSET_SIZE);
d02d48d8650bf (Al Viro 2005-12-24 14:33:09 -0500 29) if (llen > 0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 30) op += llen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 31) else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 32) *op++ = '?';
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 33) ip++;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 34)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 35) len--;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 36) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 37) *op = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 38) return (op - ascii);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 39) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 40)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 41) int
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 42) get_joliet_filename(struct iso_directory_record * de, unsigned char *outname, struct inode * inode)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 43) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 44) unsigned char utf8;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 45) struct nls_table *nls;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 46) unsigned char len = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 47)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 48) utf8 = ISOFS_SB(inode->i_sb)->s_utf8;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 49) nls = ISOFS_SB(inode->i_sb)->s_nls_iocharset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 50)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 51) if (utf8) {
74675a58507e7 (Alan Stern 2009-04-30 10:08:18 -0400 52) len = utf16s_to_utf8s((const wchar_t *) de->name,
74675a58507e7 (Alan Stern 2009-04-30 10:08:18 -0400 53) de->name_len[0] >> 1, UTF16_BIG_ENDIAN,
74675a58507e7 (Alan Stern 2009-04-30 10:08:18 -0400 54) outname, PAGE_SIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 55) } else {
d02d48d8650bf (Al Viro 2005-12-24 14:33:09 -0500 56) len = uni16_to_x8(outname, (__be16 *) de->name,
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 57) de->name_len[0] >> 1, nls);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 58) }
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 59) if ((len > 2) && (outname[len-2] == ';') && (outname[len-1] == '1'))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 60) len -= 2;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 61)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 62) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 63) * Windows doesn't like periods at the end of a name,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 64) * so neither do we
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 65) */
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 66) while (len >= 2 && (outname[len-1] == '.'))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 67) len--;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 68)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 69) return len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 70) }