^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/isofs/joliet.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * (C) 1996 Gordon Chaffee
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Joliet: Microsoft's Unicode extensions to iso9660
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/nls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "isofs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Convert Unicode 16 to UTF-8 or ASCII.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) uni16_to_x8(unsigned char *ascii, __be16 *uni, int len, struct nls_table *nls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) __be16 *ip, ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) unsigned char *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) ip = uni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) op = ascii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) while ((ch = get_unaligned(ip)) && len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int llen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) llen = nls->uni2char(be16_to_cpu(ch), op, NLS_MAX_CHARSET_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (llen > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) op += llen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *op++ = '?';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ip++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *op = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return (op - ascii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) get_joliet_filename(struct iso_directory_record * de, unsigned char *outname, struct inode * inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct nls_table *nls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned char len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) nls = ISOFS_SB(inode->i_sb)->s_nls_iocharset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (!nls) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) len = utf16s_to_utf8s((const wchar_t *) de->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) de->name_len[0] >> 1, UTF16_BIG_ENDIAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) outname, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) len = uni16_to_x8(outname, (__be16 *) de->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) de->name_len[0] >> 1, nls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if ((len > 2) && (outname[len-2] == ';') && (outname[len-1] == '1'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * Windows doesn't like periods at the end of a name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * so neither do we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) while (len >= 2 && (outname[len-1] == '.'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }