Blame view

fs/hfs/trans.c 3.31 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
  /*
   *  linux/fs/hfs/trans.c
   *
   * Copyright (C) 1995-1997  Paul H. Hargrove
   * This file may be distributed under the terms of the GNU General Public License.
   *
   * This file contains routines for converting between the Macintosh
   * character set and various other encodings.  This includes dealing
   * with ':' vs. '/' as the path-element separator.
   */
328b92278   Roman Zippel   [PATCH] hfs: NLS ...
11
12
  #include <linux/types.h>
  #include <linux/nls.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
  #include "hfs_fs.h"
  
  /*================ Global functions ================*/
  
  /*
328b92278   Roman Zippel   [PATCH] hfs: NLS ...
18
   * hfs_mac2asc()
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
21
22
23
24
25
26
27
28
29
30
   *
   * Given a 'Pascal String' (a string preceded by a length byte) in
   * the Macintosh character set produce the corresponding filename using
   * the 'trivial' name-mangling scheme, returning the length of the
   * mangled filename.  Note that the output string is not NULL
   * terminated.
   *
   * The name-mangling works as follows:
   * The character '/', which is illegal in Linux filenames is replaced
   * by ':' which never appears in HFS filenames.	 All other characters
   * are passed unchanged from input to output.
   */
328b92278   Roman Zippel   [PATCH] hfs: NLS ...
31
  int hfs_mac2asc(struct super_block *sb, char *out, const struct hfs_name *in)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
  {
328b92278   Roman Zippel   [PATCH] hfs: NLS ...
33
34
35
36
37
38
39
40
41
42
43
44
  	struct nls_table *nls_disk = HFS_SB(sb)->nls_disk;
  	struct nls_table *nls_io = HFS_SB(sb)->nls_io;
  	const char *src;
  	char *dst;
  	int srclen, dstlen, size;
  
  	src = in->name;
  	srclen = in->len;
  	dst = out;
  	dstlen = HFS_MAX_NAMELEN;
  	if (nls_io) {
  		wchar_t ch;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45

328b92278   Roman Zippel   [PATCH] hfs: NLS ...
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
  		while (srclen > 0) {
  			if (nls_disk) {
  				size = nls_disk->char2uni(src, srclen, &ch);
  				if (size <= 0) {
  					ch = '?';
  					size = 1;
  				}
  				src += size;
  				srclen -= size;
  			} else {
  				ch = *src++;
  				srclen--;
  			}
  			if (ch == '/')
  				ch = ':';
  			size = nls_io->uni2char(ch, dst, dstlen);
  			if (size < 0) {
  				if (size == -ENAMETOOLONG)
  					goto out;
  				*dst = '?';
  				size = 1;
  			}
  			dst += size;
  			dstlen -= size;
  		}
  	} else {
  		char ch;
  
  		while (--srclen >= 0)
  			*dst++ = (ch = *src++) == '/' ? ':' : ch;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
  	}
328b92278   Roman Zippel   [PATCH] hfs: NLS ...
77
78
  out:
  	return dst - out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
80
81
  }
  
  /*
328b92278   Roman Zippel   [PATCH] hfs: NLS ...
82
   * hfs_asc2mac()
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
84
85
86
87
88
89
90
91
92
   *
   * Given an ASCII string (not null-terminated) and its length,
   * generate the corresponding filename in the Macintosh character set
   * using the 'trivial' name-mangling scheme, returning the length of
   * the mangled filename.  Note that the output string is not NULL
   * terminated.
   *
   * This routine is a inverse to hfs_mac2triv().
   * A ':' is replaced by a '/'.
   */
328b92278   Roman Zippel   [PATCH] hfs: NLS ...
93
  void hfs_asc2mac(struct super_block *sb, struct hfs_name *out, struct qstr *in)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
  {
328b92278   Roman Zippel   [PATCH] hfs: NLS ...
95
96
  	struct nls_table *nls_disk = HFS_SB(sb)->nls_disk;
  	struct nls_table *nls_io = HFS_SB(sb)->nls_io;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
  	const char *src;
328b92278   Roman Zippel   [PATCH] hfs: NLS ...
98
99
  	char *dst;
  	int srclen, dstlen, size;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
  	src = in->name;
328b92278   Roman Zippel   [PATCH] hfs: NLS ...
102
  	srclen = in->len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
  	dst = out->name;
328b92278   Roman Zippel   [PATCH] hfs: NLS ...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
  	dstlen = HFS_NAMELEN;
  	if (nls_io) {
  		wchar_t ch;
  
  		while (srclen > 0) {
  			size = nls_io->char2uni(src, srclen, &ch);
  			if (size < 0) {
  				ch = '?';
  				size = 1;
  			}
  			src += size;
  			srclen -= size;
  			if (ch == ':')
  				ch = '/';
  			if (nls_disk) {
  				size = nls_disk->uni2char(ch, dst, dstlen);
  				if (size < 0) {
  					if (size == -ENAMETOOLONG)
  						goto out;
  					*dst = '?';
  					size = 1;
  				}
  				dst += size;
  				dstlen -= size;
  			} else {
  				*dst++ = ch > 0xff ? '?' : ch;
  				dstlen--;
  			}
  		}
  	} else {
  		char ch;
  
  		if (dstlen > srclen)
  			dstlen = srclen;
  		while (--dstlen >= 0)
  			*dst++ = (ch = *src++) == ':' ? '/' : ch;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
  	}
328b92278   Roman Zippel   [PATCH] hfs: NLS ...
141
142
143
144
  out:
  	out->len = dst - (char *)out->name;
  	dstlen = HFS_NAMELEN - out->len;
  	while (--dstlen >= 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
  		*dst++ = 0;
  }