cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

trans.c (3448B)


      1/*
      2 *  linux/fs/hfs/trans.c
      3 *
      4 * Copyright (C) 1995-1997  Paul H. Hargrove
      5 * This file may be distributed under the terms of the GNU General Public License.
      6 *
      7 * This file contains routines for converting between the Macintosh
      8 * character set and various other encodings.  This includes dealing
      9 * with ':' vs. '/' as the path-element separator.
     10 */
     11
     12#include <linux/types.h>
     13#include <linux/nls.h>
     14
     15#include "hfs_fs.h"
     16
     17/*================ Global functions ================*/
     18
     19/*
     20 * hfs_mac2asc()
     21 *
     22 * Given a 'Pascal String' (a string preceded by a length byte) in
     23 * the Macintosh character set produce the corresponding filename using
     24 * the 'trivial' name-mangling scheme, returning the length of the
     25 * mangled filename.  Note that the output string is not NULL
     26 * terminated.
     27 *
     28 * The name-mangling works as follows:
     29 * The character '/', which is illegal in Linux filenames is replaced
     30 * by ':' which never appears in HFS filenames.	 All other characters
     31 * are passed unchanged from input to output.
     32 */
     33int hfs_mac2asc(struct super_block *sb, char *out, const struct hfs_name *in)
     34{
     35	struct nls_table *nls_disk = HFS_SB(sb)->nls_disk;
     36	struct nls_table *nls_io = HFS_SB(sb)->nls_io;
     37	const char *src;
     38	char *dst;
     39	int srclen, dstlen, size;
     40
     41	src = in->name;
     42	srclen = in->len;
     43	if (srclen > HFS_NAMELEN)
     44		srclen = HFS_NAMELEN;
     45	dst = out;
     46	dstlen = HFS_MAX_NAMELEN;
     47	if (nls_io) {
     48		wchar_t ch;
     49
     50		while (srclen > 0) {
     51			if (nls_disk) {
     52				size = nls_disk->char2uni(src, srclen, &ch);
     53				if (size <= 0) {
     54					ch = '?';
     55					size = 1;
     56				}
     57				src += size;
     58				srclen -= size;
     59			} else {
     60				ch = *src++;
     61				srclen--;
     62			}
     63			if (ch == '/')
     64				ch = ':';
     65			size = nls_io->uni2char(ch, dst, dstlen);
     66			if (size < 0) {
     67				if (size == -ENAMETOOLONG)
     68					goto out;
     69				*dst = '?';
     70				size = 1;
     71			}
     72			dst += size;
     73			dstlen -= size;
     74		}
     75	} else {
     76		char ch;
     77
     78		while (--srclen >= 0)
     79			*dst++ = (ch = *src++) == '/' ? ':' : ch;
     80	}
     81out:
     82	return dst - out;
     83}
     84
     85/*
     86 * hfs_asc2mac()
     87 *
     88 * Given an ASCII string (not null-terminated) and its length,
     89 * generate the corresponding filename in the Macintosh character set
     90 * using the 'trivial' name-mangling scheme, returning the length of
     91 * the mangled filename.  Note that the output string is not NULL
     92 * terminated.
     93 *
     94 * This routine is a inverse to hfs_mac2triv().
     95 * A ':' is replaced by a '/'.
     96 */
     97void hfs_asc2mac(struct super_block *sb, struct hfs_name *out, const struct qstr *in)
     98{
     99	struct nls_table *nls_disk = HFS_SB(sb)->nls_disk;
    100	struct nls_table *nls_io = HFS_SB(sb)->nls_io;
    101	const char *src;
    102	char *dst;
    103	int srclen, dstlen, size;
    104
    105	src = in->name;
    106	srclen = in->len;
    107	dst = out->name;
    108	dstlen = HFS_NAMELEN;
    109	if (nls_io) {
    110		wchar_t ch;
    111
    112		while (srclen > 0) {
    113			size = nls_io->char2uni(src, srclen, &ch);
    114			if (size < 0) {
    115				ch = '?';
    116				size = 1;
    117			}
    118			src += size;
    119			srclen -= size;
    120			if (ch == ':')
    121				ch = '/';
    122			if (nls_disk) {
    123				size = nls_disk->uni2char(ch, dst, dstlen);
    124				if (size < 0) {
    125					if (size == -ENAMETOOLONG)
    126						goto out;
    127					*dst = '?';
    128					size = 1;
    129				}
    130				dst += size;
    131				dstlen -= size;
    132			} else {
    133				*dst++ = ch > 0xff ? '?' : ch;
    134				dstlen--;
    135			}
    136		}
    137	} else {
    138		char ch;
    139
    140		if (dstlen > srclen)
    141			dstlen = srclen;
    142		while (--dstlen >= 0)
    143			*dst++ = (ch = *src++) == ':' ? '/' : ch;
    144	}
    145out:
    146	out->len = dst - (char *)out->name;
    147	dstlen = HFS_NAMELEN - out->len;
    148	while (--dstlen >= 0)
    149		*dst++ = 0;
    150}