* [PATCH] Full NLS support for HFS (classic) filesystem
@ 2005-05-30 14:05 Pavel Fedin
0 siblings, 0 replies; 22+ messages in thread
From: Pavel Fedin @ 2005-05-30 14:05 UTC (permalink / raw)
To: linux-fsdevel; +Cc: zippel
[-- Attachment #1: Type: text/plain, Size: 2271 bytes --]
Hello, all! After a long thnking i implemented full NLS support for
MacHFS filesystem. This is the patch for 2.6.11.1 kernel.
Add "iocharset" and "hfscodepage" mount options to fstab for it to work.
"hfscodepage" option is also introduced to iso9660 and udf
filesystems. They ignore it. Both options are also added to hfsplus
filesystem. It also ignores them. This is done in order to enable user
to put one line into fstab like:
/dev/cdrom /mnt/cdrom iso9660,udf,hfsplus,hfs
user,noauto,iocharset=koi8-r,hfscodepage=10007 0 0
This allows you to have one mount point for all CD formats at last.
Codepage option is called "hfscodepage", not "codepage" because in
future "codepage" option might be added to iso9660 filesystem in order
to enable translation of 8-bit names and in many countries ISO codepage
differs from HFS codepage.
cp10007 nls table is also added by this patch. This codepage is used
on russian macintoshes.
Some technical details on the implementation:
HFS filesystem by nature requires filenames in Mac encoding to be
supplied to file search algorythm, otherwise it will not work. So two
different algorythms are used depending on used iocharset:
a) if iocharset=utf8 - all characters are reverse-convertable in this
case. NLS table is loaded for the specified codepage and conversion is
done using it.
b) if iocharset is not utf8 - not every character can be
reverse-translated in this case. To override this two tables are
composed on the fly from two supplied NLS pages using a tricky
algorythm. A 256 byte table is created and filled with characters taken
from NLS->NLS conversion. Those characters from 256-byte destination set
which were used are marked. After this all remaining entries in the
table (characters which had no equivalent in the destination NLS table)
are filled with characters which remained unused. Then resulting table
is reversed in order to provide a second table for reverse translation.
This implementation is rather tricky and probably sometimes it can
fail (i hope it won't, at least i tested it with hfscodepage=10007) so i
left a simple possibility to disable conversion by simply removing
iocharset and hfscodepage from hfs mount options.
--
Kind regards, Pavel Fedin
[-- Attachment #2: hfs-nls-2.6.11.1.diff --]
[-- Type: text/x-patch, Size: 38054 bytes --]
--- linux-2.6.11.1/fs/hfs/catalog.c.orig 2005-03-18 00:34:30.000000000 +0300
+++ linux-2.6.11.1/fs/hfs/catalog.c 2005-03-30 23:55:02.000000000 +0400
@@ -20,12 +20,12 @@
*
* Given the ID of the parent and the name build a search key.
*/
-void hfs_cat_build_key(btree_key *key, u32 parent, struct qstr *name)
+void hfs_cat_build_key(btree_key *key, u32 parent, struct qstr *name, struct hfs_sb_info *sbi)
{
key->cat.reserved = 0;
key->cat.ParID = cpu_to_be32(parent);
if (name) {
- hfs_triv2mac(&key->cat.CName, name);
+ hfs_triv2mac(&key->cat.CName, name, sbi->unix2mac, sbi->nls);
key->key_len = 6 + key->cat.CName.len;
} else {
memset(&key->cat.CName, 0, sizeof(struct hfs_name));
@@ -63,12 +63,12 @@
}
static int hfs_cat_build_thread(hfs_cat_rec *rec, int type,
- u32 parentid, struct qstr *name)
+ u32 parentid, struct qstr *name, struct hfs_sb_info *sbi)
{
rec->type = type;
memset(rec->thread.reserved, 0, sizeof(rec->thread.reserved));
rec->thread.ParID = cpu_to_be32(parentid);
- hfs_triv2mac(&rec->thread.CName, name);
+ hfs_triv2mac(&rec->thread.CName, name, sbi->unix2mac, sbi->nls);
return sizeof(struct hfs_cat_thread);
}
@@ -93,10 +93,10 @@
sb = dir->i_sb;
hfs_find_init(HFS_SB(sb)->cat_tree, &fd);
- hfs_cat_build_key(fd.search_key, cnid, NULL);
+ hfs_cat_build_key(fd.search_key, cnid, NULL, HFS_SB(sb));
entry_size = hfs_cat_build_thread(&entry, S_ISDIR(inode->i_mode) ?
HFS_CDR_THD : HFS_CDR_FTH,
- dir->i_ino, str);
+ dir->i_ino, str, HFS_SB(sb));
err = hfs_brec_find(&fd);
if (err != -ENOENT) {
if (!err)
@@ -107,7 +107,7 @@
if (err)
goto err2;
- hfs_cat_build_key(fd.search_key, dir->i_ino, str);
+ hfs_cat_build_key(fd.search_key, dir->i_ino, str, HFS_SB(sb));
entry_size = hfs_cat_build_record(&entry, cnid, inode);
err = hfs_brec_find(&fd);
if (err != -ENOENT) {
@@ -127,7 +127,7 @@
return 0;
err1:
- hfs_cat_build_key(fd.search_key, cnid, NULL);
+ hfs_cat_build_key(fd.search_key, cnid, NULL, HFS_SB(sb));
if (!hfs_brec_find(&fd))
hfs_brec_remove(&fd);
err2:
@@ -176,7 +176,7 @@
hfs_cat_rec rec;
int res, len, type;
- hfs_cat_build_key(fd->search_key, cnid, NULL);
+ hfs_cat_build_key(fd->search_key, cnid, NULL, HFS_SB(sb));
res = hfs_brec_read(fd, &rec, sizeof(rec));
if (res)
return res;
@@ -211,7 +211,7 @@
sb = dir->i_sb;
hfs_find_init(HFS_SB(sb)->cat_tree, &fd);
- hfs_cat_build_key(fd.search_key, dir->i_ino, str);
+ hfs_cat_build_key(fd.search_key, dir->i_ino, str, HFS_SB(sb));
res = hfs_brec_find(&fd);
if (res)
goto out;
@@ -239,7 +239,7 @@
if (res)
goto out;
- hfs_cat_build_key(fd.search_key, cnid, NULL);
+ hfs_cat_build_key(fd.search_key, cnid, NULL, HFS_SB(sb));
res = hfs_brec_find(&fd);
if (!res) {
res = hfs_brec_remove(&fd);
@@ -280,7 +280,7 @@
dst_fd = src_fd;
/* find the old dir entry and read the data */
- hfs_cat_build_key(src_fd.search_key, src_dir->i_ino, src_name);
+ hfs_cat_build_key(src_fd.search_key, src_dir->i_ino, src_name, HFS_SB(sb));
err = hfs_brec_find(&src_fd);
if (err)
goto out;
@@ -289,7 +289,7 @@
src_fd.entrylength);
/* create new dir entry with the data from the old entry */
- hfs_cat_build_key(dst_fd.search_key, dst_dir->i_ino, dst_name);
+ hfs_cat_build_key(dst_fd.search_key, dst_dir->i_ino, dst_name, HFS_SB(sb));
err = hfs_brec_find(&dst_fd);
if (err != -ENOENT) {
if (!err)
@@ -305,7 +305,7 @@
mark_inode_dirty(dst_dir);
/* finally remove the old entry */
- hfs_cat_build_key(src_fd.search_key, src_dir->i_ino, src_name);
+ hfs_cat_build_key(src_fd.search_key, src_dir->i_ino, src_name, HFS_SB(sb));
err = hfs_brec_find(&src_fd);
if (err)
goto out;
@@ -321,7 +321,7 @@
goto out;
/* remove old thread entry */
- hfs_cat_build_key(src_fd.search_key, cnid, NULL);
+ hfs_cat_build_key(src_fd.search_key, cnid, NULL, HFS_SB(sb));
err = hfs_brec_find(&src_fd);
if (err)
goto out;
@@ -330,9 +330,9 @@
goto out;
/* create new thread entry */
- hfs_cat_build_key(dst_fd.search_key, cnid, NULL);
+ hfs_cat_build_key(dst_fd.search_key, cnid, NULL, HFS_SB(sb));
entry_size = hfs_cat_build_thread(&entry, type == HFS_CDR_FIL ? HFS_CDR_FTH : HFS_CDR_THD,
- dst_dir->i_ino, dst_name);
+ dst_dir->i_ino, dst_name, HFS_SB(sb));
err = hfs_brec_find(&dst_fd);
if (err != -ENOENT) {
if (!err)
--- linux-2.6.11.1/fs/hfs/dir.c.orig 2005-03-18 00:34:30.000000000 +0300
+++ linux-2.6.11.1/fs/hfs/dir.c 2005-05-28 22:15:01.000000000 +0400
@@ -28,7 +28,7 @@
dentry->d_op = &hfs_dentry_operations;
hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd);
- hfs_cat_build_key(fd.search_key, dir->i_ino, &dentry->d_name);
+ hfs_cat_build_key(fd.search_key, dir->i_ino, &dentry->d_name, HFS_SB(dir->i_sb));
res = hfs_brec_read(&fd, &rec, sizeof(rec));
if (res) {
hfs_find_exit(&fd);
@@ -56,17 +56,19 @@
struct inode *inode = filp->f_dentry->d_inode;
struct super_block *sb = inode->i_sb;
int len, err;
- char strbuf[HFS_NAMELEN + 1];
+ char strbuf[129];
union hfs_cat_rec entry;
struct hfs_find_data fd;
struct hfs_readdir_data *rd;
+ unsigned char *mac2unix = HFS_SB(sb)->mac2unix;
+ struct nls_table *nls = HFS_SB(sb)->nls;
u16 type;
if (filp->f_pos >= inode->i_size)
return 0;
hfs_find_init(HFS_SB(sb)->cat_tree, &fd);
- hfs_cat_build_key(fd.search_key, inode->i_ino, NULL);
+ hfs_cat_build_key(fd.search_key, inode->i_ino, NULL, HFS_SB(sb));
err = hfs_brec_find(&fd);
if (err)
goto out;
@@ -111,7 +113,7 @@
}
hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength);
type = entry.type;
- len = hfs_mac2triv(strbuf, &fd.key->cat.CName);
+ len = hfs_mac2triv(strbuf, &fd.key->cat.CName, mac2unix, nls);
if (type == HFS_CDR_DIR) {
if (fd.entrylength < sizeof(struct hfs_cat_dir)) {
printk("HFS: small dir entry\n");
@@ -308,7 +310,7 @@
new_dir, &new_dentry->d_name);
if (!res)
hfs_cat_build_key((btree_key *)&HFS_I(old_dentry->d_inode)->cat_key,
- new_dir->i_ino, &new_dentry->d_name);
+ new_dir->i_ino, &new_dentry->d_name, HFS_SB(new_dentry->d_sb));
return res;
}
--- linux-2.6.11.1/fs/hfs/hfs_fs.h.orig 2005-03-18 00:34:30.000000000 +0300
+++ linux-2.6.11.1/fs/hfs/hfs_fs.h 2005-03-30 23:53:27.000000000 +0400
@@ -138,6 +138,8 @@
permissions on all dirs */
uid_t s_uid; /* The uid of all files */
gid_t s_gid; /* The gid of all files */
+ char *iocharset; /* I/O Character set */
+ int codepage; /* Disk codepage */
int session, part;
@@ -150,6 +152,9 @@
int fs_div;
struct hlist_head rsrc_inodes;
+ unsigned char *mac2unix;
+ unsigned char *unix2mac;
+ struct nls_table *nls;
};
#define HFS_FLG_BITMAP_DIRTY 0
@@ -168,7 +173,7 @@
extern int hfs_cat_delete(u32, struct inode *, struct qstr *);
extern int hfs_cat_move(u32, struct inode *, struct qstr *,
struct inode *, struct qstr *);
-extern void hfs_cat_build_key(btree_key *, u32, struct qstr *);
+extern void hfs_cat_build_key(btree_key *, u32, struct qstr *, struct hfs_sb_info *);
/* dir.c */
extern struct file_operations hfs_dir_operations;
@@ -232,8 +237,10 @@
extern int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
/* trans.c */
-extern void hfs_triv2mac(struct hfs_name *, struct qstr *);
-extern int hfs_mac2triv(char *, const struct hfs_name *);
+extern unsigned char *hfs_load_charset(char *iocharset, int codepage);
+extern unsigned char *hfs_revert_charset(unsigned char *mac2unix);
+extern void hfs_triv2mac(struct hfs_name *, struct qstr *, unsigned char *, struct nls_table *);
+extern int hfs_mac2triv(char *, const struct hfs_name *, unsigned char *, struct nls_table *);
extern struct timezone sys_tz;
--- linux-2.6.11.1/fs/hfs/inode.c.orig 2005-03-18 00:34:30.000000000 +0300
+++ linux-2.6.11.1/fs/hfs/inode.c 2005-03-18 00:35:51.000000000 +0300
@@ -163,7 +163,7 @@
init_MUTEX(&HFS_I(inode)->extents_lock);
INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list);
- hfs_cat_build_key((btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name);
+ hfs_cat_build_key((btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name, HFS_SB(sb));
inode->i_ino = HFS_SB(sb)->next_id++;
inode->i_mode = mode;
inode->i_uid = current->fsuid;
--- linux-2.6.11.1/fs/hfs/super.c.orig 2005-03-18 00:34:30.000000000 +0300
+++ linux-2.6.11.1/fs/hfs/super.c 2005-05-28 23:53:31.000000000 +0400
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/init.h>
+#include <linux/nls.h>
#include <linux/vfs.h>
#include "hfs_fs.h"
@@ -64,9 +65,30 @@
*/
static void hfs_put_super(struct super_block *sb)
{
+ struct hfs_sb_info *hsb = HFS_SB(sb);
hfs_mdb_close(sb);
/* release the MDB's resources */
hfs_mdb_put(sb);
+ if (hsb->nls)
+ {
+ unload_nls(hsb->nls);
+ hsb->nls = NULL;
+ }
+ if (hsb->mac2unix)
+ {
+ kfree(hsb->mac2unix);
+ hsb->mac2unix = NULL;
+ }
+ if (hsb->unix2mac)
+ {
+ kfree(hsb->unix2mac);
+ hsb->unix2mac = NULL;
+ }
+ if (hsb->iocharset)
+ {
+ kfree(hsb->iocharset);
+ hsb->iocharset = NULL;
+ }
}
/*
@@ -155,6 +177,8 @@
hsb->s_quiet = 0;
hsb->part = -1;
hsb->session = -1;
+ hsb->iocharset = NULL;
+ hsb->codepage = CONFIG_HFS_DEFAULT_CODEPAGE;
if (!options)
return 1;
@@ -210,6 +234,12 @@
hsb->session = simple_strtoul(value, &value, 0);
if (*value)
return 0;
+ } else if (!strcmp(this_char, "hfscodepage")) {
+ if (!value || !*value)
+ return 0;
+ hsb->codepage = simple_strtoul(value, &value, 0);
+ if (*value)
+ return 0;
/* String-valued options */
} else if (!strcmp(this_char, "type") && value) {
if (strlen(value) != 4)
@@ -219,6 +249,13 @@
if (strlen(value) != 4)
return 0;
memcpy(&hsb->s_creator, value, 4);
+ } else if (!strcmp(this_char, "iocharset") && value) {
+ if (hsb->iocharset)
+ kfree(hsb->iocharset);
+ hsb->iocharset = kmalloc(strlen(value)+1, GFP_KERNEL);
+ if (!hsb->iocharset)
+ return -ENOMEM;
+ strcpy(hsb->iocharset, value);
/* Boolean-valued options */
} else if (!strcmp(this_char, "quiet")) {
if (value)
@@ -252,6 +289,7 @@
hfs_cat_rec rec;
struct inode *root_inode;
int res;
+ char buf[256];
sbi = kmalloc(sizeof(struct hfs_sb_info), GFP_KERNEL);
if (!sbi)
@@ -279,6 +317,27 @@
goto bail2;
}
+ res = -EINVAL;
+ if (sbi->iocharset)
+ {
+ if (strcmp(sbi->iocharset, "utf8"))
+ {
+ sbi->mac2unix = hfs_load_charset(sbi->iocharset, sbi->codepage);
+ if (!sbi->mac2unix)
+ goto bail1;
+ sbi->unix2mac = hfs_revert_charset(sbi->mac2unix);
+ if (!sbi->unix2mac)
+ goto bail0;
+ }
+ else
+ {
+ sprintf(buf, "cp%d", sbi->codepage);
+ sbi->nls = load_nls(buf);
+ if (!sbi->nls)
+ goto bail1;
+ }
+ }
+
/* try to get the root inode */
hfs_find_init(HFS_SB(sb)->cat_tree, &fd);
res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd);
@@ -306,6 +365,10 @@
iput(root_inode);
bail_no_root:
hfs_warn("hfs_fs: get root inode failed.\n");
+ kfree(sbi->unix2mac);
+bail0:
+ kfree(sbi->mac2unix);
+bail1:
hfs_mdb_put(sb);
bail2:
bail3:
--- linux-2.6.11.1/fs/hfs/trans.c.orig 2005-03-18 00:34:30.000000000 +0300
+++ linux-2.6.11.1/fs/hfs/trans.c 2005-05-28 23:29:12.000000000 +0400
@@ -9,10 +9,116 @@
* with ':' vs. '/' as the path-element separator.
*/
+#include <linux/types.h>
+#include <linux/nls.h>
#include "hfs_fs.h"
+/*
+ * Define this if you want to enable verification that your table does not contain
+ * duplicated characters
+ */
+#undef NLS_SANITY_CHECK
+
/*================ Global functions ================*/
+/* hfs_load_charset()
+ *
+ * Creates table for converting characters from Macintosh character set to Linux character set
+ * from two given NLS modules (I/O and disk character sets). This is necessary because
+ * translation must be 100% reversible otherwise we won't be able to lock a file even if it's
+ * found.
+ */
+unsigned char *hfs_load_charset(char *iocharset, int codepage)
+{
+ struct nls_table *nls_io, *nls_disk;
+ int i, j, clen;
+ char c8;
+ wchar_t c16;
+ unsigned char *mac2unix;
+ char buf[256];
+
+ sprintf(buf,"cp%d",codepage);
+ nls_disk = load_nls(buf);
+ if (!nls_disk) {
+ hfs_warn("hfs_fs: codepage %s not found\n", buf);
+ return NULL;
+ }
+ nls_io = load_nls(iocharset);
+ if (!nls_io) {
+ hfs_warn("hfs_fs: IO charset %s not found\n", iocharset);
+ unload_nls(nls_disk);
+ return NULL;
+ }
+ mac2unix = kmalloc(256, GFP_KERNEL);
+ if (mac2unix) {
+ memset (mac2unix, 0, 256);
+ memset (buf, 0, sizeof(buf));
+ for(i=0; i<256; i++) {
+ c8 = (char)i;
+ clen = nls_disk->char2uni(&c8, 1, &c16);
+ if (clen > 0) {
+ /* FIXME: To enable UTF-8 support you'll need to:
+ 1. Replace the following '1' with NLS_MAX_CHARSET_SIZE;
+ 2. Increase size of the translation table;
+ 3. Rework reverse translation routine (reverse translation table would
+ be huge for Unicode)
+ */
+ clen = nls_io->uni2char(c16, &mac2unix[i], 1);
+ if (clen > 0)
+ {
+#ifdef NLS_SANITY_CHECK
+ if (buf[mac2unix[i]]) {
+ hfs_warn ("hfs_fs: duplicating character %02X (translated for second time from %02X) in NLS tables!\n", mac2unix[i], i);
+ kfree (mac2unix);
+ mac2unix = NULL;
+ goto fault;
+ }
+#endif
+ buf[mac2unix[i]] = 1;
+ }
+ }
+ }
+ j = 0;
+ for(i=1; i<256; i++) {
+ if (!mac2unix[i]) {
+ while (buf[j]) {
+ j++;
+#ifdef NLS_SANITY_CHECK
+ if (j > 255) {
+ hfs_warn ("hfs_fs: weird, extra untranslated characters appear! Kernel BUG!\n");
+ kfree (mac2unix);
+ mac2unix = NULL;
+ goto fault;
+ }
+#endif
+ }
+ mac2unix[i] = j++;
+ }
+ }
+ }
+fault:
+ unload_nls(nls_io);
+ unload_nls(nls_disk);
+ return mac2unix;
+}
+
+/* hfs_revert_charset()
+ *
+ * Initialises reverse translation table from forward translation table.
+ * Optionally can check table's consistency (verify that there are no duplicated values in it)
+ */
+unsigned char *hfs_revert_charset(unsigned char *mac2unix)
+{
+ unsigned char *unix2mac;
+ int i;
+
+ unix2mac = kmalloc(256, GFP_KERNEL);
+ if (unix2mac)
+ for(i=0; i<256; i++)
+ unix2mac[mac2unix[i]] = i;
+ return unix2mac;
+};
+
/*
* hfs_mac2triv()
*
@@ -27,19 +133,50 @@
* by ':' which never appears in HFS filenames. All other characters
* are passed unchanged from input to output.
*/
-int hfs_mac2triv(char *out, const struct hfs_name *in)
+int hfs_mac2triv(char *out, const struct hfs_name *in, unsigned char *table, struct nls_table *nls)
{
const char *p;
char c;
- int i, len;
+ int i, l, len;
+ wchar_t uni;
+ int dl = 0;
len = in->len;
p = in->name;
- for (i = 0; i < len; i++) {
- c = *p++;
- *out++ = c == '/' ? ':' : c;
+ if (nls) {
+ for (i = 0; i < len;) {
+ l = nls->char2uni(&p[i], len-i, &uni);
+ if (l > 0)
+ {
+ uni = uni == '/' ? ':' : uni;
+ i += l;
+ l = utf8_wctomb(out, uni, NLS_MAX_CHARSET_SIZE);
+ if (l > 0) {
+ out += l;
+ dl += l;
+ }
+ }
+ else
+ i++;
+ if (l < 0)
+ {
+ *out++ = '?';
+ dl++;
+ hfs_warn("hfs_fs/hfs_mac2triv(): weird, non-translatable character appear! KERNEL BUG!\n");
+ }
+ }
+ return dl;
+ } else {
+ for (i = 0; i < len; i++)
+ {
+ c = *p++;
+ c = c == '/' ? ':' : c;
+ if (table)
+ c = table[(unsigned char)c];
+ *out++ = c;
+ }
+ return i;
}
- return i;
}
/*
@@ -54,18 +191,53 @@
* This routine is a inverse to hfs_mac2triv().
* A ':' is replaced by a '/'.
*/
-void hfs_triv2mac(struct hfs_name *out, struct qstr *in)
+void hfs_triv2mac(struct hfs_name *out, struct qstr *in, unsigned char *table, struct nls_table *nls)
{
const char *src;
char *dst, c;
- int i, len;
+ wchar_t uni;
+ int i, l, len;
+ int dl = 0;
+ int limit = HFS_NAMELEN;
- out->len = len = min((unsigned int)HFS_NAMELEN, in->len);
src = in->name;
dst = out->name;
- for (i = 0; i < len; i++) {
- c = *src++;
- *dst++ = c == ':' ? '/' : c;
+ if (nls) {
+ len = in->len;
+ for (i = 0; i < len && limit > 0;) {
+ l = utf8_mbtowc(&uni, &src[i], len-i);
+ if (l > 0)
+ {
+ uni = uni == ':' ? '/' : uni;
+ i += l;
+ l = nls->uni2char(uni, dst, limit);
+ if (l > 0)
+ {
+ dst += l;
+ dl += l;
+ limit -= l;
+ }
+ }
+ else
+ i++;
+ if (l < 0)
+ {
+ *dst++ = '?';
+ dl++;
+ limit--;
+ hfs_warn("hfs_fs/hfs_triv2mac(): weird, non-translatable character appear! KERNEL BUG!\n");
+ }
+ }
+ out->len = dl;
+ } else {
+ out->len = len = min((unsigned int)HFS_NAMELEN, in->len);
+ for (i = 0; i < len; i++) {
+ c = *src++;
+ c = c == ':' ? '/' : c;
+ if (table)
+ c = table[(unsigned char)c];
+ *dst++ = c;
+ }
}
for (; i < HFS_NAMELEN; i++)
*dst++ = 0;
--- linux-2.6.11.1/fs/hfsplus/options.c.orig 2005-03-18 00:34:30.000000000 +0300
+++ linux-2.6.11.1/fs/hfsplus/options.c 2005-03-18 00:35:51.000000000 +0300
@@ -117,6 +117,8 @@
printk("HFS+-fs: session requires an argument\n");
return 0;
}
+ } else if (!strcmp(curropt, "iocharset")) {
+ } else if (!strcmp(curropt, "hfscodepage")) {
} else {
printk("HFS+-fs: unknown option %s\n", curropt);
return 0;
--- linux-2.6.11.1/fs/isofs/inode.c.orig 2005-03-18 00:34:30.000000000 +0300
+++ linux-2.6.11.1/fs/isofs/inode.c 2005-03-18 00:35:51.000000000 +0300
@@ -364,6 +364,7 @@
{Opt_ignore, "conv=auto"},
{Opt_ignore, "conv=a"},
{Opt_nocompress, "nocompress"},
+ {Opt_ignore, "hfscodepage=%s"},
{Opt_err, NULL}
};
--- linux-2.6.11.1/fs/nls/Kconfig.orig 2005-03-18 00:34:30.000000000 +0300
+++ linux-2.6.11.1/fs/nls/Kconfig 2005-03-18 00:35:51.000000000 +0300
@@ -332,6 +332,19 @@
say Y here if you want to include the DOS codepage for Russian and
Bulgarian and Belarusian.
+config NLS_CODEPAGE_10007
+ tristate "Macintosh CP10007 (Russian, Ukrainian)"
+ depends on NLS
+ help
+ The Macintosh HFS file system family can deal with filenames in
+ native language character sets. These character sets are stored in
+ so-called codepages. You need to include the appropriate codepage
+ if you want to be able to read/write these filenames on HFS
+ partitions correctly. This does apply to the filenames
+ only, not to the file contents. You can include several codepages;
+ say Y here if you want to include the Macintosh codepage for Russian
+ and Ukrainian.
+
config NLS_ASCII
tristate "ASCII (United States)"
depends on NLS
--- linux-2.6.11.1/fs/nls/Makefile.orig 2005-03-18 00:34:30.000000000 +0300
+++ linux-2.6.11.1/fs/nls/Makefile 2005-03-18 00:35:51.000000000 +0300
@@ -26,6 +26,7 @@
obj-$(CONFIG_NLS_CODEPAGE_950) += nls_cp950.o
obj-$(CONFIG_NLS_CODEPAGE_1250) += nls_cp1250.o
obj-$(CONFIG_NLS_CODEPAGE_1251) += nls_cp1251.o
+obj-$(CONFIG_NLS_CODEPAGE_10007) += nls_cp10007.o
obj-$(CONFIG_NLS_ASCII) += nls_ascii.o
obj-$(CONFIG_NLS_ISO8859_1) += nls_iso8859-1.o
obj-$(CONFIG_NLS_ISO8859_2) += nls_iso8859-2.o
--- linux-2.6.11.1/fs/nls/nls_cp10007.c.orig 2005-03-18 00:35:51.000000000 +0300
+++ linux-2.6.11.1/fs/nls/nls_cp10007.c 2005-03-18 00:35:51.000000000 +0300
@@ -0,0 +1,351 @@
+/*
+ * linux/fs/nls_cp10007.c
+ *
+ * Charset cp10007 translation tables.
+ * Written by Pavel Fedin <sonic_amiga@rambler.ru>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/nls.h>
+#include <linux/errno.h>
+
+static wchar_t charset2uni[256] = {
+ /* 0x00*/
+ 0x0000, 0x0001, 0x0002, 0x0003,
+ 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x000a, 0x000b,
+ 0x000c, 0x000d, 0x000e, 0x000f,
+ /* 0x10*/
+ 0x0010, 0x0011, 0x0012, 0x0013,
+ 0x0014, 0x0015, 0x0016, 0x0017,
+ 0x0018, 0x0019, 0x001a, 0x001b,
+ 0x001c, 0x001d, 0x001e, 0x001f,
+ /* 0x20*/
+ 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027,
+ 0x0028, 0x0029, 0x002a, 0x002b,
+ 0x002c, 0x002d, 0x002e, 0x002f,
+ /* 0x30*/
+ 0x0030, 0x0031, 0x0032, 0x0033,
+ 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003a, 0x003b,
+ 0x003c, 0x003d, 0x003e, 0x003f,
+ /* 0x40*/
+ 0x0040, 0x0041, 0x0042, 0x0043,
+ 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b,
+ 0x004c, 0x004d, 0x004e, 0x004f,
+ /* 0x50*/
+ 0x0050, 0x0051, 0x0052, 0x0053,
+ 0x0054, 0x0055, 0x0056, 0x0057,
+ 0x0058, 0x0059, 0x005a, 0x005b,
+ 0x005c, 0x005d, 0x005e, 0x005f,
+ /* 0x60*/
+ 0x0060, 0x0061, 0x0062, 0x0063,
+ 0x0064, 0x0065, 0x0066, 0x0067,
+ 0x0068, 0x0069, 0x006a, 0x006b,
+ 0x006c, 0x006d, 0x006e, 0x006f,
+ /* 0x70*/
+ 0x0070, 0x0071, 0x0072, 0x0073,
+ 0x0074, 0x0075, 0x0076, 0x0077,
+ 0x0078, 0x0079, 0x007a, 0x007b,
+ 0x007c, 0x007d, 0x007e, 0x007f,
+ /* 0x80*/
+ 0x0410, 0x0411, 0x0412, 0x0413,
+ 0x0414, 0x0415, 0x0416, 0x0417,
+ 0x0418, 0x0419, 0x041a, 0x041b,
+ 0x041c, 0x041d, 0x041e, 0x041f,
+ /* 0x90*/
+ 0x0420, 0x0421, 0x0422, 0x0423,
+ 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042a, 0x042b,
+ 0x042c, 0x042d, 0x042e, 0x042f,
+ /* 0xa0*/
+ 0x2020, 0x00b0, 0x0490, 0x00a3,
+ 0x00a7, 0x2022, 0x00b6, 0x0406,
+ 0x00ae, 0x00a9, 0x2122, 0x0402,
+ 0x0452, 0x2260, 0x0403, 0x0453,
+ /* 0xb0*/
+ 0x221e, 0x00b1, 0x2264, 0x2265,
+ 0x0456, 0x00b5, 0x0491, 0x0408,
+ 0x0404, 0x0454, 0x0407, 0x0457,
+ 0x0409, 0x0459, 0x040a, 0x045a,
+ /* 0xc0*/
+ 0x0458, 0x0405, 0x00ac, 0x221a,
+ 0x0192, 0x2248, 0x2206, 0x00ab,
+ 0x00bb, 0x2026, 0x00a0, 0x040b,
+ 0x045b, 0x040c, 0x045c, 0x0455,
+ /* 0xd0*/
+ 0x2013, 0x2014, 0x201c, 0x201d,
+ 0x2018, 0x2019, 0x00f7, 0x201e,
+ 0x040e, 0x045e, 0x040f, 0x045f,
+ 0x2116, 0x0401, 0x0451, 0x044f,
+ /* 0xe0*/
+ 0x0430, 0x0431, 0x0432, 0x0433,
+ 0x0434, 0x0435, 0x0436, 0x0437,
+ 0x0438, 0x0439, 0x043a, 0x043b,
+ 0x043c, 0x043d, 0x043e, 0x043f,
+ /* 0xf0*/
+ 0x0440, 0x0441, 0x0442, 0x0443,
+ 0x0444, 0x0445, 0x0446, 0x0447,
+ 0x0448, 0x0449, 0x044a, 0x044b,
+ 0x044c, 0x044d, 0x044e, 0x20ac,
+};
+
+static unsigned char page00[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+ 0xca, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xa4, /* 0xa0-0xa7 */
+ 0x00, 0xa9, 0x00, 0xc7, 0xc2, 0x00, 0xa8, 0x00, /* 0xa8-0xaf */
+ 0xa1, 0xb1, 0x00, 0x00, 0x00, 0xb5, 0xa6, 0x00, /* 0xb0-0xb7 */
+ 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, /* 0xf0-0xf7 */
+};
+
+static unsigned char page01[256] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, /* 0x18-0x1f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+ 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+};
+
+static unsigned char page04[256] = {
+ 0x00, 0xdd, 0xab, 0xae, 0xb8, 0xc1, 0xa7, 0xba, /* 0x00-0x07 */
+ 0xb7, 0xbc, 0xbe, 0xcb, 0xcd, 0x00, 0xd8, 0xda, /* 0x08-0x0f */
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x10-0x17 */
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x18-0x1f */
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x20-0x27 */
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x28-0x2f */
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x30-0x37 */
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x38-0x3f */
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x40-0x47 */
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf, /* 0x48-0x4f */
+ 0x00, 0xde, 0xac, 0xaf, 0xb9, 0xcf, 0xb4, 0xbb, /* 0x50-0x57 */
+ 0xc0, 0xbd, 0xbf, 0xcc, 0xce, 0x00, 0xd9, 0xdb, /* 0x58-0x5f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+ 0xa2, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+};
+
+static unsigned char page20[256] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+ 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+ 0xd4, 0xd5, 0x00, 0x00, 0xd2, 0xd3, 0xd7, 0x00, /* 0x18-0x1f */
+ 0xa0, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
+};
+
+static unsigned char page21[256] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, /* 0x10-0x17 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
+ 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+};
+
+static unsigned char page22[256] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, /* 0x00-0x07 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+ 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xb0, 0x00, /* 0x18-0x1f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+ 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+ 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */
+};
+
+static unsigned char *page_uni2charset[256] = {
+ page00, page01, NULL, NULL, page04, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ page20, page21, page22, NULL, NULL, NULL, NULL, NULL,
+};
+
+static unsigned char charset2lower[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+ 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */
+ 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x80-0x87 */
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x88-0x8f */
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x90-0x97 */
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf, /* 0x98-0x9f */
+ 0xa0, 0xa1, 0xb6, 0xa3, 0xa4, 0xa5, 0xa6, 0xb4, /* 0xa0-0xa7 */
+ 0xa8, 0xa9, 0xaa, 0xac, 0xac, 0xad, 0xaf, 0xaf, /* 0xa8-0xaf */
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xc0, /* 0xb0-0xb7 */
+ 0xb9, 0xb9, 0xbb, 0xbb, 0xbd, 0xbd, 0xbf, 0xbf, /* 0xb8-0xbf */
+ 0xc0, 0xcf, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */
+ 0xc8, 0xc9, 0xca, 0xcc, 0xcc, 0xce, 0xce, 0xcf, /* 0xc8-0xcf */
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */
+ 0xd9, 0xd9, 0xdb, 0xdb, 0xdc, 0xde, 0xde, 0xdf, /* 0xd8-0xdf */
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
+};
+
+static unsigned char charset2upper[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+ 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */
+ 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+ 0x80, 0x81, 0x82, 0x81, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */
+ 0x80, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */
+ 0xa0, 0xa1, 0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
+ 0xa8, 0xa9, 0xaa, 0xab, 0xab, 0xad, 0xae, 0xae, /* 0xa8-0xaf */
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xa7, 0xb5, 0xa2, 0xb7, /* 0xb0-0xb7 */
+ 0xb8, 0xb8, 0xba, 0xba, 0xbc, 0xbc, 0xbe, 0xbe, /* 0xb8-0xbf */
+ 0xb7, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcd, 0xcd, 0xc1, /* 0xc8-0xcf */
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */
+ 0xd8, 0xd8, 0xda, 0xda, 0xdc, 0xdd, 0xdd, 0x9f, /* 0xd8-0xdf */
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0xe0-0xe7 */
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0xe8-0xef */
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0xf0-0xf7 */
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0xff, /* 0xf8-0xff */
+};
+
+static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
+{
+ unsigned char *uni2charset;
+ unsigned char cl = uni & 0x00ff;
+ unsigned char ch = (uni & 0xff00) >> 8;
+
+ if (boundlen <= 0)
+ return -ENAMETOOLONG;
+
+ uni2charset = page_uni2charset[ch];
+ if (uni2charset && uni2charset[cl])
+ out[0] = uni2charset[cl];
+ else
+ return -EINVAL;
+ return 1;
+}
+
+static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
+{
+ *uni = charset2uni[*rawstring];
+ if (*uni == 0x0000)
+ return -EINVAL;
+ return 1;
+}
+
+static struct nls_table table = {
+ .charset = "cp10007",
+ .uni2char = uni2char,
+ .char2uni = char2uni,
+ .charset2lower = charset2lower,
+ .charset2upper = charset2upper,
+ .owner = THIS_MODULE,
+};
+
+static int __init init_nls_cp10007(void)
+{
+ return register_nls(&table);
+}
+
+static void __exit exit_nls_cp10007(void)
+{
+ unregister_nls(&table);
+}
+
+module_init(init_nls_cp10007)
+module_exit(exit_nls_cp10007)
+
+MODULE_LICENSE("Dual BSD/GPL");
--- linux-2.6.11.1/fs/nls/nls_cp10007.mod.c.orig 2005-03-18 00:35:51.000000000 +0300
+++ linux-2.6.11.1/fs/nls/nls_cp10007.mod.c 2005-03-18 00:35:51.000000000 +0300
@@ -0,0 +1,21 @@
+#include <linux/module.h>
+#include <linux/vermagic.h>
+#include <linux/compiler.h>
+
+MODULE_INFO(vermagic, VERMAGIC_STRING);
+
+#undef unix
+struct module __this_module
+__attribute__((section(".gnu.linkonce.this_module"))) = {
+ .name = __stringify(KBUILD_MODNAME),
+ .init = init_module,
+#ifdef CONFIG_MODULE_UNLOAD
+ .exit = cleanup_module,
+#endif
+};
+
+static const char __module_depends[]
+__attribute_used__
+__attribute__((section(".modinfo"))) =
+"depends=nls_base";
+
--- linux-2.6.11.1/fs/udf/super.c.orig 2005-03-18 00:34:31.000000000 +0300
+++ linux-2.6.11.1/fs/udf/super.c 2005-03-18 00:35:51.000000000 +0300
@@ -274,7 +274,7 @@
Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
Opt_rootdir, Opt_utf8, Opt_iocharset,
- Opt_err
+ Opt_err, Opt_ignore
};
static match_table_t tokens = {
@@ -299,6 +299,7 @@
{Opt_rootdir, "rootdir=%u"},
{Opt_utf8, "utf8"},
{Opt_iocharset, "iocharset=%s"},
+ {Opt_ignore, "hfscodepage=%s"},
{Opt_err, NULL}
};
@@ -412,6 +413,7 @@
break;
case Opt_utf8:
uopt->flags |= (1 << UDF_FLAG_UTF8);
+ case Opt_ignore:
break;
#ifdef CONFIG_UDF_NLS
case Opt_iocharset:
--- linux-2.6.11.1/fs/Kconfig.orig 2005-03-17 21:47:24.000000000 +0300
+++ linux-2.6.11.1/fs/Kconfig 2005-05-28 23:53:13.000000000 +0400
@@ -980,6 +980,14 @@
To compile this file system support as a module, choose M here: the
module will be called hfs.
+config HFS_DEFAULT_CODEPAGE
+ string "Default codepage for HFS"
+ depends on HFS_FS
+ default "437"
+ help
+ This option should be set to the codepage of your HFS filesystems.
+ It can be overridden with the 'codepage' mount option.
+
config HFSPLUS_FS
tristate "Apple Extended HFS file system support"
select NLS
--- linux-2.6.11.1/Documentation/filesystems/hfs.txt.orig 2005-03-04 20:26:37.000000000 +0300
+++ linux-2.6.11.1/Documentation/filesystems/hfs.txt 2005-05-28 23:57:52.000000000 +0400
@@ -41,6 +41,20 @@
quiet
Ignore invalid mount options instead of complaining.
+ iocharset=name
+ Character set to use for converting file names. Specifies character
+ set used by your Linux system. Currently only HFS supports character
+ set translation, HFS+ simply ignores this argument.
+
+ Character set conversion needs excessive testing so it gets enabled
+ only when you specify this argument in mount options. If you have
+ any problems, remove it, this will restore old behavour of the
+ filesystem (no translation is done).
+
+ hfscodepage=###
+ Set the codepage number for converting file names. Specifies
+ character set used by Macintoshes in your country. Also ignored by
+ HFS+.
Writing to HFS Filesystems
==========================
^ permalink raw reply [flat|nested] 22+ messages in thread[parent not found: <429B1E35.2040905@rambler.ru>]
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
[not found] <429B1E35.2040905@rambler.ru>
@ 2005-05-30 11:50 ` Roman Zippel
2005-05-31 13:37 ` Pavel Fedin
2005-06-09 23:47 ` George Anzinger
0 siblings, 2 replies; 22+ messages in thread
From: Roman Zippel @ 2005-05-30 11:50 UTC (permalink / raw)
To: Pavel Fedin; +Cc: linux-kernel, linux-fsdevel
Hi,
On Mon, 30 May 2005, Pavel Fedin wrote:
> Codepage option is called "hfscodepage", not "codepage" because in
> future "codepage" option might be added to iso9660 filesystem in order
> to enable translation of 8-bit names and in many countries ISO codepage
> differs from HFS codepage.
If the codepage differs, you simply use different arguments for that
option. Is there a _technical_ reason why "hfscodepage" and "codepage"
might behave differently? Otherwise I'd prefer to use the same name for
the option.
Why do you build the extra translation tables? I'm not relly convinced
this is a kernel problem at all, but doing it more like fat would be more
acceptable (maybe just with some more sane defaults).
(BTW please try to inline the patch otherwise it's rather difficult to
quote from it.)
> + if (hsb->nls)
> + {
Please fix the coding style.
> +extern void hfs_triv2mac(struct hfs_name *, struct qstr *, unsigned char *, struct nls_table *);
If you add a new argument, use "struct superblock *sb" as the first
argument.
bye, Roman
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-05-30 11:50 ` Roman Zippel
@ 2005-05-31 13:37 ` Pavel Fedin
2005-05-31 10:45 ` Roman Zippel
2005-06-09 23:47 ` George Anzinger
1 sibling, 1 reply; 22+ messages in thread
From: Pavel Fedin @ 2005-05-31 13:37 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-fsdevel
Roman Zippel wrote:
>> Codepage option is called "hfscodepage", not "codepage" because in
>>future "codepage" option might be added to iso9660 filesystem in order
>>to enable translation of 8-bit names and in many countries ISO codepage
>>differs from HFS codepage.
>
>
> If the codepage differs, you simply use different arguments for that
> option. Is there a _technical_ reason why "hfscodepage" and "codepage"
> might behave differently? Otherwise I'd prefer to use the same name for
> the option.
Yes, there is one reason. It is my personal idea but i guess many
people would agree. There are ISO CDs and HFS CDs. Using two different
names allows to use one line in /etc/fstab file for all types of CDs.
For example:
/dev/cdrom /mnt/cdrom iso9660,udf,hfsplus,hfs
user,noauto,iocharset=koi8-r,hfscodepage=10007 0 0
This is my line. If "codepage" option is added in the future then the
line would look like:
/dev/cdrom /mnt/cdrom iso9660,udf,hfsplus,hfs
user,noauto,iocharset=koi8-r,codepage=866,hfscodepage=10007 0 0
You see, noone recompiles the kernel in order to specify codepages
used. Instead mount options are used.
> Why do you build the extra translation tables? I'm not relly convinced
> this is a kernel problem at all, but doing it more like fat would be more
> acceptable (maybe just with some more sane defaults).
I tried this in the beginning of my work and failed. As i can see some
special tricky algorythm is used in order to find a file by name which
depends on actual character code values (there are "<" and ">"
conditions). It does not use string comparison at all. This algorythm
requires the filename to be translated back from UNIX encoding to Mac
encoding. I just can't apply another algorythm like "list all names in
the directory, convert every name to UNIX encoding and compare", HFS
simply does not behave this way.
When using non-utf8 iocharset not all characters in "codepage" have
their equivalents in "iocharset". There are some unmapped characters. In
other implementations they all are replaced by "?". Here this will not
work because this "?" can't be translated back to original character.
Extra tables built on the fly ensure that every character in
"codepage" has its own unique equivalent in "iocharset", some
equivalents are "invented" by marking all unmapped characters in
"codepage" all unused characters in "iocharset" (those to which no one
of "codepage"'s characters is mapped) and then maps unmapped characters
to those unused characters. This works perfectly. I used this approach
in my first attempt which introduced koi8-r only and were rejected by
you several months ago.
> (BTW please try to inline the patch otherwise it's rather difficult to
> quote from it.)
Ok, next time.
>>+extern void hfs_triv2mac(struct hfs_name *, struct qstr *, unsigned char *, struct nls_table *);
>
>
> If you add a new argument, use "struct superblock *sb" as the first
> argument.
Instead of two arguments (unsigned char *table, struct nls_table *nls)
? May be struct hfs_sb_info *sbi instead in order to avoid additional
HFS_SB() macro?
--
Kind regards, Pavel Fedin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-05-31 13:37 ` Pavel Fedin
@ 2005-05-31 10:45 ` Roman Zippel
2005-05-31 19:35 ` Pavel Fedin
0 siblings, 1 reply; 22+ messages in thread
From: Roman Zippel @ 2005-05-31 10:45 UTC (permalink / raw)
To: Pavel Fedin; +Cc: linux-fsdevel
Hi,
On Tue, 31 May 2005, Pavel Fedin wrote:
> This is my line. If "codepage" option is added in the future then the line
> would look like:
>
> /dev/cdrom /mnt/cdrom iso9660,udf,hfsplus,hfs
> user,noauto,iocharset=koi8-r,codepage=866,hfscodepage=10007 0 0
Use different mount points. This is not a reason to create a lot of
different options all doing the same.
> > Why do you build the extra translation tables? I'm not relly convinced this
> > is a kernel problem at all, but doing it more like fat would be more
> > acceptable (maybe just with some more sane defaults).
>
> I tried this in the beginning of my work and failed. As i can see some
> special tricky algorythm is used in order to find a file by name which depends
> on actual character code values (there are "<" and ">" conditions). It does
> not use string comparison at all. This algorythm requires the filename to be
> translated back from UNIX encoding to Mac encoding. I just can't apply another
> algorythm like "list all names in the directory, convert every name to UNIX
> encoding and compare", HFS simply does not behave this way.
This is not HFS specific problem, you have this problem with any fs using
nls. fat does the comparison using the translated names, but that just
means it may find the wrong file instead of no file.
> Extra tables built on the fly ensure that every character in "codepage" has
> its own unique equivalent in "iocharset", some equivalents are "invented" by
> marking all unmapped characters in "codepage" all unused characters in
> "iocharset" (those to which no one of "codepage"'s characters is mapped) and
> then maps unmapped characters to those unused characters. This works
> perfectly. I used this approach in my first attempt which introduced koi8-r
> only and were rejected by you several months ago.
Again, this is not HFS-specific. Create a dynamic nls translation module
and use this from HFS, this code does not belong in HFS.
I would accept a translation similiar to fat, anything else has to be done
at the nls layer.
> Instead of two arguments (unsigned char *table, struct nls_table *nls) ? May
> be struct hfs_sb_info *sbi instead in order to avoid additional HFS_SB()
> macro?
No, superblock info is passed as "struct superblock *".
bye, Roman
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-05-31 10:45 ` Roman Zippel
@ 2005-05-31 19:35 ` Pavel Fedin
2005-05-31 12:13 ` Roman Zippel
0 siblings, 1 reply; 22+ messages in thread
From: Pavel Fedin @ 2005-05-31 19:35 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-fsdevel
Roman Zippel wrote:
>>/dev/cdrom /mnt/cdrom iso9660,udf,hfsplus,hfs
>>user,noauto,iocharset=koi8-r,codepage=866,hfscodepage=10007 0 0
>
>
> Use different mount points. This is not a reason to create a lot of
> different options all doing the same.
Why??? It's incomfortable for the user!
>> I tried this in the beginning of my work and failed. As i can see some
>>special tricky algorythm is used in order to find a file by name which depends
>>on actual character code values (there are "<" and ">" conditions). It does
>>not use string comparison at all. This algorythm requires the filename to be
>>translated back from UNIX encoding to Mac encoding. I just can't apply another
>>algorythm like "list all names in the directory, convert every name to UNIX
>>encoding and compare", HFS simply does not behave this way.
>
>
> This is not HFS specific problem, you have this problem with any fs using
> nls. fat does the comparison using the translated names, but that just
> means it may find the wrong file instead of no file.
Yes, it may find wrong file. But i mean here that HFS does not use
string comparison at all for finding a file but some specific hashing (i
tried to understand how it actually works and was unable to, too
difficult). So it just will not find many files at all, even if names
are translated correctly. As i say, i tried this, it completely failed.
>> Extra tables built on the fly ensure that every character in "codepage" has
>>its own unique equivalent in "iocharset", some equivalents are "invented" by
>>marking all unmapped characters in "codepage" all unused characters in
>>"iocharset" (those to which no one of "codepage"'s characters is mapped) and
>>then maps unmapped characters to those unused characters. This works
>>perfectly. I used this approach in my first attempt which introduced koi8-r
>>only and were rejected by you several months ago.
> Again, this is not HFS-specific. Create a dynamic nls translation module
> and use this from HFS, this code does not belong in HFS.
This (if you mean that not all characters can be translated) is really
not HFS-specific. But the fact that all characters MUST be
reverse-translatable is HFS-specific.
Don't understand about dynamic NLS module. What code should it contain?
> I would accept a translation similiar to fat, anything else has to be done
> at the nls layer.
Translation similar to FAT is unusable. Even files with correctly
translated names will be not found.
File searching at the end relies on hfs_strcmp() function which
produces correct results only if supplied strings are in Mac encoding.
I thought for a while and decided that dynamically created reversible
translation table is the best and the simplest approach.
Well, probably it's possible to rewrite hfs_strcmp() to use some
dynamically created table. But... Again, it will be dynamically created.
And it requires many time of additional research but the result will
be nearly the same.
> No, superblock info is passed as "struct superblock *".
Ok, it's not a problem.
P.S. I think you know the HFS implementation better than me. Why don't
you beleive me that there is no other solution?
--
Kind regards, Pavel Fedin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-05-31 19:35 ` Pavel Fedin
@ 2005-05-31 12:13 ` Roman Zippel
2005-05-31 21:21 ` Pavel Fedin
0 siblings, 1 reply; 22+ messages in thread
From: Roman Zippel @ 2005-05-31 12:13 UTC (permalink / raw)
To: Pavel Fedin; +Cc: linux-fsdevel
Hi,
On Tue, 31 May 2005, Pavel Fedin wrote:
> > > /dev/cdrom /mnt/cdrom iso9660,udf,hfsplus,hfs
> > > user,noauto,iocharset=koi8-r,codepage=866,hfscodepage=10007 0 0
> >
> > Use different mount points. This is not a reason to create a lot of
> > different options all doing the same.
>
> Why??? It's incomfortable for the user!
Because it's a user space problem, if you want to use different codepages
for different cd's tell it to mount. The kernel only provides the
functionality, giving the same functionality several different names is
not an option.
> > This is not HFS specific problem, you have this problem with any fs using
> > nls. fat does the comparison using the translated names, but that just means
> > it may find the wrong file instead of no file.
>
> Yes, it may find wrong file. But i mean here that HFS does not use string
> comparison at all for finding a file but some specific hashing (i tried to
> understand how it actually works and was unable to, too difficult). So it just
> will not find many files at all, even if names are translated correctly. As i
> say, i tried this, it completely failed.
If the names were translated correctly, HFS would have found them. You
need to give me an example, which should have worked, but failed.
> Don't understand about dynamic NLS module. What code should it contain?
Create the tables in a nls module and you can do whatever you want in the
uni2char/char2uni functions.
> P.S. I think you know the HFS implementation better than me. Why don't you
> beleive me that there is no other solution?
Why don't you believe me there is a better solution? :)
bye, Roman
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-05-31 12:13 ` Roman Zippel
@ 2005-05-31 21:21 ` Pavel Fedin
2005-05-31 13:59 ` Roman Zippel
2005-06-01 0:26 ` Roman Zippel
0 siblings, 2 replies; 22+ messages in thread
From: Pavel Fedin @ 2005-05-31 21:21 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-fsdevel
Roman Zippel wrote:
>>>Use different mount points. This is not a reason to create a lot of
>>>different options all doing the same.
>>
>> Why??? It's incomfortable for the user!
>
>
> Because it's a user space problem, if you want to use different codepages
> for different cd's tell it to mount. The kernel only provides the
> functionality, giving the same functionality several different names is
> not an option.
How is it possible (except using different mount points)?
Besides, using different mount points is problematic with
automounters, only first fstab entry is taken into account by them.
Second point won't be mounted automatically by, for example, magicdev.
Well, if you really don't care about users opinion and listen only to
yourself, we can find a compromise. iso9660 currently does not use
"codepage" option, udf will never use it because stores names in
Unicode. So we can rename this option to "codepage". There seem to be no
ISO discs with national 8-bit names so probably iso9660 will never need it.
>> Yes, it may find wrong file. But i mean here that HFS does not use string
>>comparison at all for finding a file but some specific hashing (i tried to
>>understand how it actually works and was unable to, too difficult). So it just
>>will not find many files at all, even if names are translated correctly. As i
>>say, i tried this, it completely failed.
>
>
> If the names were translated correctly, HFS would have found them. You
> need to give me an example, which should have worked, but failed.
I can't produce exact russian string (don't remember), but it was
about 50% of all russian names.
>> Don't understand about dynamic NLS module. What code should it contain?
>
>
> Create the tables in a nls module and you can do whatever you want in the
> uni2char/char2uni functions.
Huh...
The problem is: when using 8-bit iocharset and 8-bit codepage char2uni
from codepage always gives the result but AFTER THIS uni2char to
iocharset does NOT necessarily gives the result. There are characters in
codepage which have no equivalents in iocharset. They will be lost, you
suggest to turn them into '?'. But how to reverse this in order to
supply to hfs_strcmp()?
If i leave it unreversed, convert second hfs_strcmp() argument to
iocharset too, then hfs_strcmp() gives wrong results. It can return 1
for the cases where it would return -1 if names are supplied in original
Mac encoding. Look for example at KOI8-R and CP10007 (Mac Cyrillic)
pages. Note that order of the characters is completely different. For
example 'X'>'Y' in Mac encoding and 'X'<'Y' in koi8 (here 'X' and 'Y'
are just substitutions, i assume some two russian characters there.
There's no way to get around this. B-Tree scanning in __hfs_brec_find()
routine just works wrong.
> Why don't you believe me there is a better solution? :)
I just know that the usual algorythm used for example in FAT will not
work. I totally broke my brain when tried to find a solution. Well, the
whole B-Tree scanning routine can be totally rewritten in order to check
every name in B-tree against the requested name, without using that '<'
and '>' magic. But i guess it will be much slower. In addidion i'm just
unable to rewrite this. HFS is a total mess and i have not enough spare
time to put into its understanding. I wouldn't even try to rewrite such
deep things, i'm afraid of breaking something. I completely don't
understand HFS structure.
Or, lexical order table in hfs/string.h can be regenerated dynamically
correspondingly to used iocharset. But this will break hfs_hash_dentry()
function which relies on this particular table too. Probably two tables
can be used: original one and dynamically created one. But this requires
the time i don't have. In addition, i guess you wouldn't like it too.
--
Kind regards, Pavel Fedin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-05-31 21:21 ` Pavel Fedin
@ 2005-05-31 13:59 ` Roman Zippel
2005-05-31 14:49 ` Anton Altaparmakov
2005-06-01 0:26 ` Roman Zippel
1 sibling, 1 reply; 22+ messages in thread
From: Roman Zippel @ 2005-05-31 13:59 UTC (permalink / raw)
To: Pavel Fedin; +Cc: linux-fsdevel
Hi,
On Tue, 31 May 2005, Pavel Fedin wrote:
> > Because it's a user space problem, if you want to use different codepages
> > for different cd's tell it to mount. The kernel only provides the
> > functionality, giving the same functionality several different names is not
> > an option.
>
> How is it possible (except using different mount points)?
> Besides, using different mount points is problematic with automounters, only
> first fstab entry is taken into account by them. Second point won't be mounted
> automatically by, for example, magicdev.
So fix your tools, really, you are complaining to the wrong guy.
> > If the names were translated correctly, HFS would have found them. You need
> > to give me an example, which should have worked, but failed.
>
> I can't produce exact russian string (don't remember), but it was about 50%
> of all russian names.
Without an example I can't reproduce, what you're trying to say here (at
least the "HFS doesn't find the file, even though it's correctly
translated" part).
> > Create the tables in a nls module and you can do whatever you want in the
> > uni2char/char2uni functions.
>
> Huh...
> The problem is: when using 8-bit iocharset and 8-bit codepage char2uni from
> codepage always gives the result but AFTER THIS uni2char to iocharset does NOT
> necessarily gives the result. There are characters in codepage which have no
> equivalents in iocharset. They will be lost, you suggest to turn them into
> '?'. But how to reverse this in order to supply to hfs_strcmp()?
So create two functions uni2char/char2uni, which provide perfect reverse
mapping. Sorry, but I don't understand what your problem is here.
It seems you're making it more complex than it really is.
bye, Roman
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-05-31 13:59 ` Roman Zippel
@ 2005-05-31 14:49 ` Anton Altaparmakov
2005-05-31 15:28 ` Roman Zippel
2005-06-02 13:34 ` Pavel Fedin
0 siblings, 2 replies; 22+ messages in thread
From: Anton Altaparmakov @ 2005-05-31 14:49 UTC (permalink / raw)
To: Roman Zippel; +Cc: Pavel Fedin, linux-fsdevel
Hi,
On Tue, 2005-05-31 at 15:59 +0200, Roman Zippel wrote:
> On Tue, 31 May 2005, Pavel Fedin wrote:
> > > If the names were translated correctly, HFS would have found them. You need
> > > to give me an example, which should have worked, but failed.
> >
> > I can't produce exact russian string (don't remember), but it was about 50%
> > of all russian names.
>
> Without an example I can't reproduce, what you're trying to say here (at
> least the "HFS doesn't find the file, even though it's correctly
> translated" part).
There are lost of characters that cannot be translated. I have this
problem with NTFS, too. My solution is to just ignore file names that
cannot be translated. If a user complains they cannot see some
filenames, I tell them to use utf8 for their encoding which always works
for translation.
NLS is fundamentally broken so there is no point in trying to use clever
dynamic tables to do it. Just ignore it is IMO the correct way.
btw. not having mappings is not even the biggest problem. It gets much
worse and even Pavel's dynamic mappings are not actually going to work.
For example there are some characters in asian languages which when
translated will give a character but when you then reverse translate
this character you end up with something that is not the same as the
starting character.
This is a fundamental flaw with the whole NLS codepages approach because
there are symbols in Unicode which have identical meaning but two
different Unicode values. You get this for the "exact" ideographs and
the "simplified" ideographs (e.g. CJK and compatibility ideographs - see
Unicode standard and various NLS pages for details). If you don't
believe me I can dig out the old emails which have concrete examples of
how you convert a CJK ideograph to some codepage and then back and you
end up with a compatibility CJK ideograph instead of the original one.
Of course if you start with the compatibility CJK ideograph and do the
translation + reverse translation you end up with the same compatibility
ideograph but that doesn't help you when you use the "real" ideograph as
for example Windows seems to do as a lot of asian people have complained
to me about ntfs when used with codepages. All of them went away happy
when I told them to tell the ntfs driver to use utf8...
So unless you use UTF8, any other conversion using NLS/code pages will
always have failure cases...
(btw. I first suspected bugs in the code pages but I verified them on
the MS website and they were correct...)
> > > Create the tables in a nls module and you can do whatever you want in the
> > > uni2char/char2uni functions.
> >
> > Huh...
> > The problem is: when using 8-bit iocharset and 8-bit codepage char2uni from
> > codepage always gives the result but AFTER THIS uni2char to iocharset does NOT
> > necessarily gives the result. There are characters in codepage which have no
> > equivalents in iocharset. They will be lost, you suggest to turn them into
> > '?'. But how to reverse this in order to supply to hfs_strcmp()?
>
> So create two functions uni2char/char2uni, which provide perfect reverse
> mapping. Sorry, but I don't understand what your problem is here.
> It seems you're making it more complex than it really is.
That is impossible due to the problems with compatibility characters I
explained above which why I would agree with you that such magic
conversions should never happen, just put "use utf8 if you have
problems" in the mount man page...
Best regards,
Anton
--
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-05-31 14:49 ` Anton Altaparmakov
@ 2005-05-31 15:28 ` Roman Zippel
2005-06-02 13:34 ` Pavel Fedin
1 sibling, 0 replies; 22+ messages in thread
From: Roman Zippel @ 2005-05-31 15:28 UTC (permalink / raw)
To: Anton Altaparmakov; +Cc: Pavel Fedin, linux-fsdevel
Hi,
On Tue, 31 May 2005, Anton Altaparmakov wrote:
> So unless you use UTF8, any other conversion using NLS/code pages will
> always have failure cases...
No suprise. :)
Anyone working with different encodings and doesn't use utf8, simply has
to expect problems.
> > So create two functions uni2char/char2uni, which provide perfect reverse
> > mapping. Sorry, but I don't understand what your problem is here.
> > It seems you're making it more complex than it really is.
>
> That is impossible due to the problems with compatibility characters I
> explained above which why I would agree with you that such magic
> conversions should never happen, just put "use utf8 if you have
> problems" in the mount man page...
He only wants to convert from one 8-bit encoding to another 8-bit
encoding. It's a hack, but it's a hack which can be done transparently via
the nls layer, so it doesn't has to be done in the filesystem.
bye, Roman
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-05-31 14:49 ` Anton Altaparmakov
2005-05-31 15:28 ` Roman Zippel
@ 2005-06-02 13:34 ` Pavel Fedin
2005-06-02 9:24 ` Anton Altaparmakov
1 sibling, 1 reply; 22+ messages in thread
From: Pavel Fedin @ 2005-06-02 13:34 UTC (permalink / raw)
To: Anton Altaparmakov; +Cc: Roman Zippel, linux-fsdevel
Anton Altaparmakov wrote:
> NLS is fundamentally broken so there is no point in trying to use clever
> dynamic tables to do it. Just ignore it is IMO the correct way.
>
> btw. not having mappings is not even the biggest problem. It gets much
> worse and even Pavel's dynamic mappings are not actually going to work.
> For example there are some characters in asian languages which when
> translated will give a character but when you then reverse translate
> this character you end up with something that is not the same as the
> starting character.
Did you verify this or just suggest? My dynamic mapping should work
because reverse translation table is created by reversing "direct"
translation dynamic table, which is built from two NLSes.
> a lot of asian people have complained
> to me about ntfs when used with codepages. All of them went away happy
> when I told them to tell the ntfs driver to use utf8...
Yes, with utf8 everything really works because every character is
reverse-translatable in this case. With HFS too - look at my
implementation, it handles iocharset=utf8 as a special case where direct
and reverse translation is done directly via NLS module and there's no
need for dynamic tables.
But in Russia UTF-8 is not widely used because of no need to. We
prefer direct compatibility with ASCII files from other systems.
--
Kind regards, Pavel Fedin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-06-02 13:34 ` Pavel Fedin
@ 2005-06-02 9:24 ` Anton Altaparmakov
2005-06-03 13:34 ` Pavel Fedin
0 siblings, 1 reply; 22+ messages in thread
From: Anton Altaparmakov @ 2005-06-02 9:24 UTC (permalink / raw)
To: Pavel Fedin; +Cc: Roman Zippel, linux-fsdevel
On Thu, 2005-06-02 at 09:34 -0400, Pavel Fedin wrote:
> Anton Altaparmakov wrote:
> > NLS is fundamentally broken so there is no point in trying to use clever
> > dynamic tables to do it. Just ignore it is IMO the correct way.
> >
> > btw. not having mappings is not even the biggest problem. It gets much
> > worse and even Pavel's dynamic mappings are not actually going to work.
> > For example there are some characters in asian languages which when
> > translated will give a character but when you then reverse translate
> > this character you end up with something that is not the same as the
> > starting character.
>
> Did you verify this or just suggest? My dynamic mapping should work
> because reverse translation table is created by reversing "direct"
> translation dynamic table, which is built from two NLSes.
No, I have not verified it. I do not use HFS at all. But your direct
translation dynamic table will already be ambiguous if the "right" NLS
pages were used to create it. Or what do you do when two different
characters in on NLS page are translated to the _sam_ character in the
other NLS page?
> > a lot of asian people have complained
> > to me about ntfs when used with codepages. All of them went away happy
> > when I told them to tell the ntfs driver to use utf8...
>
> Yes, with utf8 everything really works because every character is
> reverse-translatable in this case. With HFS too - look at my
> implementation, it handles iocharset=utf8 as a special case where direct
> and reverse translation is done directly via NLS module and there's no
> need for dynamic tables.
> But in Russia UTF-8 is not widely used because of no need to. We
> prefer direct compatibility with ASCII files from other systems.
Where is the problem with compatibility? Any sane application will
translate files on the fly. On my SUSE 9.3 box (uses UTF8) when I open
a text file in vim (my editor of choice) and the text file contained
characters in a codepage, vim translates it to the corresponding UTF8
character and then translates it back into the original codepage when I
save the file. (It shows a "[translated]" message at the bottom of the
screen after I open such a file so I know this has happened.)
Best regards,
Anton
--
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-06-02 9:24 ` Anton Altaparmakov
@ 2005-06-03 13:34 ` Pavel Fedin
2005-06-03 8:09 ` Anton Altaparmakov
0 siblings, 1 reply; 22+ messages in thread
From: Pavel Fedin @ 2005-06-03 13:34 UTC (permalink / raw)
To: Anton Altaparmakov; +Cc: linux-fsdevel
Anton Altaparmakov wrote:
> No, I have not verified it. I do not use HFS at all. But your direct
> translation dynamic table will already be ambiguous if the "right" NLS
> pages were used to create it.
What do you mean under "right"?
> Or what do you do when two different
> characters in on NLS page are translated to the _sam_ character in the
> other NLS page?
Didn't meet such cases. Well, you're right, in this case dynamic table
building will fail. But at least dynamic table solves problems with
non-translatable characters.
> Where is the problem with compatibility? Any sane application will
> translate files on the fly. On my SUSE 9.3 box (uses UTF8) when I open
> a text file in vim (my editor of choice) and the text file contained
> characters in a codepage, vim translates it to the corresponding UTF8
> character and then translates it back into the original codepage when I
> save the file. (It shows a "[translated]" message at the bottom of the
> screen after I open such a file so I know this has happened.)
Well, what will you tell me to do with all my files on my EXT3 with
russian names? How can i convert them?
Well, we've just got used to koi8-r. Why can't i continue to use it?
It satisfies me at 100%. AFAIK Linux is free system where everything is
a choice. So why do you force me and argue that i'm completely wrong?
--
Kind regards, Pavel Fedin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-06-03 13:34 ` Pavel Fedin
@ 2005-06-03 8:09 ` Anton Altaparmakov
2005-06-06 13:15 ` Pavel Fedin
0 siblings, 1 reply; 22+ messages in thread
From: Anton Altaparmakov @ 2005-06-03 8:09 UTC (permalink / raw)
To: Pavel Fedin; +Cc: linux-fsdevel
On Fri, 3 Jun 2005, Pavel Fedin wrote:
> Anton Altaparmakov wrote:
> > No, I have not verified it. I do not use HFS at all. But your direct
> > translation dynamic table will already be ambiguous if the "right" NLS
> > pages were used to create it.
>
> What do you mean under "right"?
Well only some codepages have this problem. If you use say KOI-8R and
Latin9 or something then you would be fine. But use CP936 or Big5 and you
are screwed.
> > Or what do you do when two different
> > characters in on NLS page are translated to the _sam_ character in the
> > other NLS page?
>
> Didn't meet such cases. Well, you're right, in this case dynamic table
> building will fail. But at least dynamic table solves problems with
> non-translatable characters.
That's because you are using KOI-8R which suggests to me that you don't
often use chineese or other asian characters...
> > Where is the problem with compatibility? Any sane application will
> > translate files on the fly. On my SUSE 9.3 box (uses UTF8) when I open
> > a text file in vim (my editor of choice) and the text file contained
> > characters in a codepage, vim translates it to the corresponding UTF8
> > character and then translates it back into the original codepage when I
> > save the file. (It shows a "[translated]" message at the bottom of the
> > screen after I open such a file so I know this has happened.)
>
> Well, what will you tell me to do with all my files on my EXT3 with russian
> names? How can i convert them?
> Well, we've just got used to koi8-r. Why can't i continue to use it? It
> satisfies me at 100%. AFAIK Linux is free system where everything is a choice.
> So why do you force me and argue that i'm completely wrong?
I agree with filenames like that you have a problem. But it is EXT3's
design fault that this happens. It should have stored the names in UTF8
or Unicode or whatever to start with then you could have used anything on
the system and it would have always worked...
Best regards,
Anton
--
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-06-03 8:09 ` Anton Altaparmakov
@ 2005-06-06 13:15 ` Pavel Fedin
2005-06-06 12:44 ` Roman Zippel
0 siblings, 1 reply; 22+ messages in thread
From: Pavel Fedin @ 2005-06-06 13:15 UTC (permalink / raw)
To: Anton Altaparmakov; +Cc: linux-fsdevel, Roman Zippel
Anton Altaparmakov wrote:
> Well only some codepages have this problem. If you use say KOI-8R and
> Latin9 or something then you would be fine. But use CP936 or Big5 and you
> are screwed.
Understand.
>> Didn't meet such cases. Well, you're right, in this case dynamic table
>>building will fail. But at least dynamic table solves problems with
>>non-translatable characters.
>
>
> That's because you are using KOI-8R which suggests to me that you don't
> often use chineese or other asian characters...
Yes, i don't use them at all.
> I agree with filenames like that you have a problem. But it is EXT3's
> design fault that this happens. It should have stored the names in UTF8
> or Unicode or whatever to start with then you could have used anything on
> the system and it would have always worked...
Well, anyway i don't have time to write EXT4 :-)
P.S. Okay, as Roman suggested i will:
1. Replace "hfscodepage" with "codepage".
2. Fix coding style.
But i would strongly suggest to leave dynamic table algorythm as is.
Please beleive me, i wrote it because it's really needed.
Roman, is it okay?
--
Kind regards, Pavel Fedin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-06-06 13:15 ` Pavel Fedin
@ 2005-06-06 12:44 ` Roman Zippel
2005-06-06 21:44 ` Pavel Fedin
0 siblings, 1 reply; 22+ messages in thread
From: Roman Zippel @ 2005-06-06 12:44 UTC (permalink / raw)
To: Pavel Fedin; +Cc: Anton Altaparmakov, linux-fsdevel
Hi,
On Mon, 6 Jun 2005, Pavel Fedin wrote:
> But i would strongly suggest to leave dynamic table algorythm as is. Please
> beleive me, i wrote it because it's really needed.
> Roman, is it okay?
No, the dynamic table is not acceptable within the HFS code.
Do whatever you want in a separate nls module.
bye, Roman
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-06-06 12:44 ` Roman Zippel
@ 2005-06-06 21:44 ` Pavel Fedin
2005-06-06 14:44 ` Roman Zippel
0 siblings, 1 reply; 22+ messages in thread
From: Pavel Fedin @ 2005-06-06 21:44 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-fsdevel
Roman Zippel wrote:
> No, the dynamic table is not acceptable within the HFS code.
> Do whatever you want in a separate nls module.
Well, it's really bad that you say so IMHO. But it's just my opinion.
In fact, i agree, probably i'm alone who uses HFS in Russia so this is
only my problem and you don't want to take care about the minority of users.
In this case i can just say "ok" about integrating your version of the
patch (which you already presented here). I will test 2.6.12 with it
when it becomes stable and probably introduce another NLS module which
will actually make this working for me. I see no sense in mere
duplication of your work.
--
Kind regards, Pavel Fedin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-06-06 21:44 ` Pavel Fedin
@ 2005-06-06 14:44 ` Roman Zippel
2005-06-08 18:08 ` Pavel Fedin
0 siblings, 1 reply; 22+ messages in thread
From: Roman Zippel @ 2005-06-06 14:44 UTC (permalink / raw)
To: Pavel Fedin; +Cc: linux-fsdevel
Hi,
On Mon, 6 Jun 2005, Pavel Fedin wrote:
> Well, it's really bad that you say so IMHO. But it's just my opinion. In
> fact, i agree, probably i'm alone who uses HFS in Russia so this is only my
> problem and you don't want to take care about the minority of users.
Could you please stop this nonsense? You have two perfectly valid
alternatives, so you have to come up with something better, why you want
to insist on your prefered solution.
bye, Roman
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-06-06 14:44 ` Roman Zippel
@ 2005-06-08 18:08 ` Pavel Fedin
0 siblings, 0 replies; 22+ messages in thread
From: Pavel Fedin @ 2005-06-08 18:08 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-fsdevel
Roman Zippel wrote:
> Could you please stop this nonsense?
I've already stopped it. Sorry if something hurts you, i really didn't
want to.
> You have two perfectly valid
> alternatives, so you have to come up with something better,
Use utf-8 or some custon NLS module koi8-r-mac ? I already said: okay.
> why you want
> to insist on your prefered solution.
I think my solution is the best. This is why i implemented it. And i
tried to defend it. Well, you're the boss here and of course your
opinion has a weight over my one. Well, i agree. I will write one more
new NLS.
--
Kind regards, Pavel Fedin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-05-31 21:21 ` Pavel Fedin
2005-05-31 13:59 ` Roman Zippel
@ 2005-06-01 0:26 ` Roman Zippel
[not found] ` <429F0869.4010805@rambler.ru>
1 sibling, 1 reply; 22+ messages in thread
From: Roman Zippel @ 2005-06-01 0:26 UTC (permalink / raw)
To: Pavel Fedin; +Cc: linux-fsdevel
Hi,
Ok, before it's going on forever, here is an acceptable patch to add nls
support to HFS. It's based on your patch and the nls support already in
HFS+.
You can now do whatever translation you like in a nls module and use it
from HFS via "iocharset=..."
The patch is only compile tested, I'll test it a bit more soon.
bye, Roman
Index: linux-2.6-mm/fs/hfs/catalog.c
===================================================================
--- linux-2.6-mm.orig/fs/hfs/catalog.c 2005-06-01 01:54:17.000000000 +0200
+++ linux-2.6-mm/fs/hfs/catalog.c 2005-06-01 01:56:17.000000000 +0200
@@ -20,12 +20,12 @@
*
* Given the ID of the parent and the name build a search key.
*/
-void hfs_cat_build_key(btree_key *key, u32 parent, struct qstr *name)
+void hfs_cat_build_key(struct super_block *sb, btree_key *key, u32 parent, struct qstr *name)
{
key->cat.reserved = 0;
key->cat.ParID = cpu_to_be32(parent);
if (name) {
- hfs_triv2mac(&key->cat.CName, name);
+ hfs_asc2mac(sb, &key->cat.CName, name);
key->key_len = 6 + key->cat.CName.len;
} else {
memset(&key->cat.CName, 0, sizeof(struct hfs_name));
@@ -62,13 +62,14 @@ static int hfs_cat_build_record(hfs_cat_
}
}
-static int hfs_cat_build_thread(hfs_cat_rec *rec, int type,
+static int hfs_cat_build_thread(struct super_block *sb,
+ hfs_cat_rec *rec, int type,
u32 parentid, struct qstr *name)
{
rec->type = type;
memset(rec->thread.reserved, 0, sizeof(rec->thread.reserved));
rec->thread.ParID = cpu_to_be32(parentid);
- hfs_triv2mac(&rec->thread.CName, name);
+ hfs_asc2mac(sb, &rec->thread.CName, name);
return sizeof(struct hfs_cat_thread);
}
@@ -93,8 +94,8 @@ int hfs_cat_create(u32 cnid, struct inod
sb = dir->i_sb;
hfs_find_init(HFS_SB(sb)->cat_tree, &fd);
- hfs_cat_build_key(fd.search_key, cnid, NULL);
- entry_size = hfs_cat_build_thread(&entry, S_ISDIR(inode->i_mode) ?
+ hfs_cat_build_key(sb, fd.search_key, cnid, NULL);
+ entry_size = hfs_cat_build_thread(sb, &entry, S_ISDIR(inode->i_mode) ?
HFS_CDR_THD : HFS_CDR_FTH,
dir->i_ino, str);
err = hfs_brec_find(&fd);
@@ -107,7 +108,7 @@ int hfs_cat_create(u32 cnid, struct inod
if (err)
goto err2;
- hfs_cat_build_key(fd.search_key, dir->i_ino, str);
+ hfs_cat_build_key(sb, fd.search_key, dir->i_ino, str);
entry_size = hfs_cat_build_record(&entry, cnid, inode);
err = hfs_brec_find(&fd);
if (err != -ENOENT) {
@@ -127,7 +128,7 @@ int hfs_cat_create(u32 cnid, struct inod
return 0;
err1:
- hfs_cat_build_key(fd.search_key, cnid, NULL);
+ hfs_cat_build_key(sb, fd.search_key, cnid, NULL);
if (!hfs_brec_find(&fd))
hfs_brec_remove(&fd);
err2:
@@ -176,7 +177,7 @@ int hfs_cat_find_brec(struct super_block
hfs_cat_rec rec;
int res, len, type;
- hfs_cat_build_key(fd->search_key, cnid, NULL);
+ hfs_cat_build_key(sb, fd->search_key, cnid, NULL);
res = hfs_brec_read(fd, &rec, sizeof(rec));
if (res)
return res;
@@ -211,7 +212,7 @@ int hfs_cat_delete(u32 cnid, struct inod
sb = dir->i_sb;
hfs_find_init(HFS_SB(sb)->cat_tree, &fd);
- hfs_cat_build_key(fd.search_key, dir->i_ino, str);
+ hfs_cat_build_key(sb, fd.search_key, dir->i_ino, str);
res = hfs_brec_find(&fd);
if (res)
goto out;
@@ -239,7 +240,7 @@ int hfs_cat_delete(u32 cnid, struct inod
if (res)
goto out;
- hfs_cat_build_key(fd.search_key, cnid, NULL);
+ hfs_cat_build_key(sb, fd.search_key, cnid, NULL);
res = hfs_brec_find(&fd);
if (!res) {
res = hfs_brec_remove(&fd);
@@ -280,7 +281,7 @@ int hfs_cat_move(u32 cnid, struct inode
dst_fd = src_fd;
/* find the old dir entry and read the data */
- hfs_cat_build_key(src_fd.search_key, src_dir->i_ino, src_name);
+ hfs_cat_build_key(sb, src_fd.search_key, src_dir->i_ino, src_name);
err = hfs_brec_find(&src_fd);
if (err)
goto out;
@@ -289,7 +290,7 @@ int hfs_cat_move(u32 cnid, struct inode
src_fd.entrylength);
/* create new dir entry with the data from the old entry */
- hfs_cat_build_key(dst_fd.search_key, dst_dir->i_ino, dst_name);
+ hfs_cat_build_key(sb, dst_fd.search_key, dst_dir->i_ino, dst_name);
err = hfs_brec_find(&dst_fd);
if (err != -ENOENT) {
if (!err)
@@ -305,7 +306,7 @@ int hfs_cat_move(u32 cnid, struct inode
mark_inode_dirty(dst_dir);
/* finally remove the old entry */
- hfs_cat_build_key(src_fd.search_key, src_dir->i_ino, src_name);
+ hfs_cat_build_key(sb, src_fd.search_key, src_dir->i_ino, src_name);
err = hfs_brec_find(&src_fd);
if (err)
goto out;
@@ -321,7 +322,7 @@ int hfs_cat_move(u32 cnid, struct inode
goto out;
/* remove old thread entry */
- hfs_cat_build_key(src_fd.search_key, cnid, NULL);
+ hfs_cat_build_key(sb, src_fd.search_key, cnid, NULL);
err = hfs_brec_find(&src_fd);
if (err)
goto out;
@@ -330,8 +331,8 @@ int hfs_cat_move(u32 cnid, struct inode
goto out;
/* create new thread entry */
- hfs_cat_build_key(dst_fd.search_key, cnid, NULL);
- entry_size = hfs_cat_build_thread(&entry, type == HFS_CDR_FIL ? HFS_CDR_FTH : HFS_CDR_THD,
+ hfs_cat_build_key(sb, dst_fd.search_key, cnid, NULL);
+ entry_size = hfs_cat_build_thread(sb, &entry, type == HFS_CDR_FIL ? HFS_CDR_FTH : HFS_CDR_THD,
dst_dir->i_ino, dst_name);
err = hfs_brec_find(&dst_fd);
if (err != -ENOENT) {
Index: linux-2.6-mm/fs/hfs/dir.c
===================================================================
--- linux-2.6-mm.orig/fs/hfs/dir.c 2005-06-01 01:54:17.000000000 +0200
+++ linux-2.6-mm/fs/hfs/dir.c 2005-06-01 02:02:44.000000000 +0200
@@ -28,7 +28,7 @@ static struct dentry *hfs_lookup(struct
dentry->d_op = &hfs_dentry_operations;
hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd);
- hfs_cat_build_key(fd.search_key, dir->i_ino, &dentry->d_name);
+ hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name);
res = hfs_brec_read(&fd, &rec, sizeof(rec));
if (res) {
hfs_find_exit(&fd);
@@ -56,7 +56,7 @@ static int hfs_readdir(struct file *filp
struct inode *inode = filp->f_dentry->d_inode;
struct super_block *sb = inode->i_sb;
int len, err;
- char strbuf[HFS_NAMELEN + 1];
+ char strbuf[HFS_MAX_NAMELEN];
union hfs_cat_rec entry;
struct hfs_find_data fd;
struct hfs_readdir_data *rd;
@@ -66,7 +66,7 @@ static int hfs_readdir(struct file *filp
return 0;
hfs_find_init(HFS_SB(sb)->cat_tree, &fd);
- hfs_cat_build_key(fd.search_key, inode->i_ino, NULL);
+ hfs_cat_build_key(sb, fd.search_key, inode->i_ino, NULL);
err = hfs_brec_find(&fd);
if (err)
goto out;
@@ -111,7 +111,7 @@ static int hfs_readdir(struct file *filp
}
hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength);
type = entry.type;
- len = hfs_mac2triv(strbuf, &fd.key->cat.CName);
+ len = hfs_mac2asc(sb, strbuf, &fd.key->cat.CName);
if (type == HFS_CDR_DIR) {
if (fd.entrylength < sizeof(struct hfs_cat_dir)) {
printk("HFS: small dir entry\n");
@@ -307,7 +307,8 @@ static int hfs_rename(struct inode *old_
old_dir, &old_dentry->d_name,
new_dir, &new_dentry->d_name);
if (!res)
- hfs_cat_build_key((btree_key *)&HFS_I(old_dentry->d_inode)->cat_key,
+ hfs_cat_build_key(old_dir->i_sb,
+ (btree_key *)&HFS_I(old_dentry->d_inode)->cat_key,
new_dir->i_ino, &new_dentry->d_name);
return res;
}
Index: linux-2.6-mm/fs/hfs/hfs.h
===================================================================
--- linux-2.6-mm.orig/fs/hfs/hfs.h 2005-06-01 01:54:17.000000000 +0200
+++ linux-2.6-mm/fs/hfs/hfs.h 2005-06-01 02:02:44.000000000 +0200
@@ -25,6 +25,7 @@
#define HFS_SECTOR_SIZE 512 /* size of an HFS sector */
#define HFS_SECTOR_SIZE_BITS 9 /* log_2(HFS_SECTOR_SIZE) */
#define HFS_NAMELEN 31 /* maximum length of an HFS filename */
+#define HFS_MAX_NAMELEN 128
#define HFS_MAX_VALENCE 32767U
/* Meanings of the drAtrb field of the MDB,
Index: linux-2.6-mm/fs/hfs/hfs_fs.h
===================================================================
--- linux-2.6-mm.orig/fs/hfs/hfs_fs.h 2005-06-01 01:54:17.000000000 +0200
+++ linux-2.6-mm/fs/hfs/hfs_fs.h 2005-06-01 01:56:17.000000000 +0200
@@ -141,6 +141,8 @@ struct hfs_sb_info {
int session, part;
+ struct nls_table *nls_io, *nls_disk;
+
struct semaphore bitmap_lock;
unsigned long flags;
@@ -168,7 +170,7 @@ extern int hfs_cat_create(u32, struct in
extern int hfs_cat_delete(u32, struct inode *, struct qstr *);
extern int hfs_cat_move(u32, struct inode *, struct qstr *,
struct inode *, struct qstr *);
-extern void hfs_cat_build_key(btree_key *, u32, struct qstr *);
+extern void hfs_cat_build_key(struct super_block *, btree_key *, u32, struct qstr *);
/* dir.c */
extern struct file_operations hfs_dir_operations;
@@ -222,8 +224,8 @@ extern int hfs_strcmp(const unsigned cha
extern int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
/* trans.c */
-extern void hfs_triv2mac(struct hfs_name *, struct qstr *);
-extern int hfs_mac2triv(char *, const struct hfs_name *);
+extern void hfs_asc2mac(struct super_block *, struct hfs_name *, struct qstr *);
+extern int hfs_mac2asc(struct super_block *, char *, const struct hfs_name *);
extern struct timezone sys_tz;
Index: linux-2.6-mm/fs/hfs/inode.c
===================================================================
--- linux-2.6-mm.orig/fs/hfs/inode.c 2005-06-01 01:54:17.000000000 +0200
+++ linux-2.6-mm/fs/hfs/inode.c 2005-06-01 01:56:17.000000000 +0200
@@ -160,7 +160,7 @@ struct inode *hfs_new_inode(struct inode
init_MUTEX(&HFS_I(inode)->extents_lock);
INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list);
- hfs_cat_build_key((btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name);
+ hfs_cat_build_key(sb, (btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name);
inode->i_ino = HFS_SB(sb)->next_id++;
inode->i_mode = mode;
inode->i_uid = current->fsuid;
Index: linux-2.6-mm/fs/hfs/mdb.c
===================================================================
--- linux-2.6-mm.orig/fs/hfs/mdb.c 2005-06-01 01:54:17.000000000 +0200
+++ linux-2.6-mm/fs/hfs/mdb.c 2005-06-01 01:56:17.000000000 +0200
@@ -10,6 +10,7 @@
#include <linux/cdrom.h>
#include <linux/genhd.h>
+#include <linux/nls.h>
#include "hfs_fs.h"
#include "btree.h"
@@ -343,6 +344,11 @@ void hfs_mdb_put(struct super_block *sb)
brelse(HFS_SB(sb)->mdb_bh);
brelse(HFS_SB(sb)->alt_mdb_bh);
+ if (HFS_SB(sb)->nls_io)
+ unload_nls(HFS_SB(sb)->nls_io);
+ if (HFS_SB(sb)->nls_disk)
+ unload_nls(HFS_SB(sb)->nls_disk);
+
kfree(HFS_SB(sb));
sb->s_fs_info = NULL;
}
Index: linux-2.6-mm/fs/hfs/super.c
===================================================================
--- linux-2.6-mm.orig/fs/hfs/super.c 2005-06-01 01:54:17.000000000 +0200
+++ linux-2.6-mm/fs/hfs/super.c 2005-06-01 01:56:17.000000000 +0200
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/init.h>
+#include <linux/nls.h>
#include <linux/parser.h>
#include <linux/vfs.h>
@@ -138,6 +139,7 @@ static struct super_operations hfs_super
enum {
opt_uid, opt_gid, opt_umask, opt_file_umask, opt_dir_umask,
opt_part, opt_session, opt_type, opt_creator, opt_quiet,
+ opt_codepage, opt_iocharset,
opt_err
};
@@ -152,6 +154,8 @@ static match_table_t tokens = {
{ opt_type, "type=%s" },
{ opt_creator, "creator=%s" },
{ opt_quiet, "quiet" },
+ { opt_codepage, "codepage=%s" },
+ { opt_iocharset, "iocharset=%s" },
{ opt_err, NULL }
};
@@ -257,11 +261,46 @@ static int parse_options(char *options,
case opt_quiet:
hsb->s_quiet = 1;
break;
+ case opt_codepage:
+ if (hsb->nls_disk) {
+ printk("HFS+-fs: unable to change codepage\n");
+ return 0;
+ }
+ p = match_strdup(&args[0]);
+ hsb->nls_disk = load_nls(p);
+ if (!hsb->nls_disk) {
+ printk("HFS+-fs: unable to load codepage \"%s\"\n", p);
+ kfree(p);
+ return 0;
+ }
+ kfree(p);
+ break;
+ case opt_iocharset:
+ if (hsb->nls_io) {
+ printk("HFS: unable to change iocharset\n");
+ return 0;
+ }
+ p = match_strdup(&args[0]);
+ hsb->nls_io = load_nls(p);
+ if (!hsb->nls_io) {
+ printk("HFS: unable to load iocharset \"%s\"\n", p);
+ kfree(p);
+ return 0;
+ }
+ kfree(p);
+ break;
default:
return 0;
}
}
+ if (hsb->nls_disk && !hsb->nls_io) {
+ hsb->nls_io = load_nls_default();
+ if (!hsb->nls_io) {
+ printk("HFS: unable to load default iocharset\n");
+ return 0;
+ }
+ }
hsb->s_dir_umask &= 0777;
hsb->s_file_umask &= 0577;
Index: linux-2.6-mm/fs/hfs/trans.c
===================================================================
--- linux-2.6-mm.orig/fs/hfs/trans.c 2005-06-01 01:54:17.000000000 +0200
+++ linux-2.6-mm/fs/hfs/trans.c 2005-06-01 02:02:44.000000000 +0200
@@ -9,12 +9,15 @@
* with ':' vs. '/' as the path-element separator.
*/
+#include <linux/types.h>
+#include <linux/nls.h>
+
#include "hfs_fs.h"
/*================ Global functions ================*/
/*
- * hfs_mac2triv()
+ * hfs_mac2asc()
*
* Given a 'Pascal String' (a string preceded by a length byte) in
* the Macintosh character set produce the corresponding filename using
@@ -27,23 +30,58 @@
* by ':' which never appears in HFS filenames. All other characters
* are passed unchanged from input to output.
*/
-int hfs_mac2triv(char *out, const struct hfs_name *in)
+int hfs_mac2asc(struct super_block *sb, char *out, const struct hfs_name *in)
{
- const char *p;
- char c;
- int i, len;
-
- len = in->len;
- p = in->name;
- for (i = 0; i < len; i++) {
- c = *p++;
- *out++ = c == '/' ? ':' : c;
+ 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;
+
+ 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;
}
- return i;
+out:
+ return dst - out;
}
/*
- * hfs_triv2mac()
+ * hfs_asc2mac()
*
* Given an ASCII string (not null-terminated) and its length,
* generate the corresponding filename in the Macintosh character set
@@ -54,19 +92,56 @@ int hfs_mac2triv(char *out, const struct
* This routine is a inverse to hfs_mac2triv().
* A ':' is replaced by a '/'.
*/
-void hfs_triv2mac(struct hfs_name *out, struct qstr *in)
+void hfs_asc2mac(struct super_block *sb, struct hfs_name *out, struct qstr *in)
{
+ 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, c;
- int i, len;
+ char *dst;
+ int srclen, dstlen, size;
- out->len = len = min((unsigned int)HFS_NAMELEN, in->len);
src = in->name;
+ srclen = in->len;
dst = out->name;
- for (i = 0; i < len; i++) {
- c = *src++;
- *dst++ = c == ':' ? '/' : c;
+ 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;
}
- for (; i < HFS_NAMELEN; i++)
+out:
+ dstlen = HFS_NAMELEN - (dst - (char *)out->name);
+ while (--dstlen >= 0)
*dst++ = 0;
}
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] Full NLS support for HFS (classic) filesystem
2005-05-30 11:50 ` Roman Zippel
2005-05-31 13:37 ` Pavel Fedin
@ 2005-06-09 23:47 ` George Anzinger
1 sibling, 0 replies; 22+ messages in thread
From: George Anzinger @ 2005-06-09 23:47 UTC (permalink / raw)
To: Roman Zippel; +Cc: Pavel Fedin, linux-kernel, linux-fsdevel
Roman Zippel wrote:
> Hi,
>
> On Mon, 30 May 2005, Pavel Fedin wrote:
>
>
> (BTW please try to inline the patch otherwise it's rather difficult to
> quote from it.)
I, for one, fine the attachment better. Especially as he has a signature mark
at the end of his comments. On my mailer (Mozilla) the attachment is inlined
after the message and comes up in the reply window. If it is inlined after the
signature mark it is both half bright in the original message and does NOT come
up in the reply. So confusing as to how and which mailer to use...
--
George Anzinger george@mvista.com
HRT (High-res-timers): http://sourceforge.net/projects/high-res-timers/
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2005-06-09 23:48 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-30 14:05 [PATCH] Full NLS support for HFS (classic) filesystem Pavel Fedin
[not found] <429B1E35.2040905@rambler.ru>
2005-05-30 11:50 ` Roman Zippel
2005-05-31 13:37 ` Pavel Fedin
2005-05-31 10:45 ` Roman Zippel
2005-05-31 19:35 ` Pavel Fedin
2005-05-31 12:13 ` Roman Zippel
2005-05-31 21:21 ` Pavel Fedin
2005-05-31 13:59 ` Roman Zippel
2005-05-31 14:49 ` Anton Altaparmakov
2005-05-31 15:28 ` Roman Zippel
2005-06-02 13:34 ` Pavel Fedin
2005-06-02 9:24 ` Anton Altaparmakov
2005-06-03 13:34 ` Pavel Fedin
2005-06-03 8:09 ` Anton Altaparmakov
2005-06-06 13:15 ` Pavel Fedin
2005-06-06 12:44 ` Roman Zippel
2005-06-06 21:44 ` Pavel Fedin
2005-06-06 14:44 ` Roman Zippel
2005-06-08 18:08 ` Pavel Fedin
2005-06-01 0:26 ` Roman Zippel
[not found] ` <429F0869.4010805@rambler.ru>
[not found] ` <Pine.LNX.4.61.0506021130290.3728@scrub.home>
2005-06-03 14:00 ` Pavel Fedin
2005-06-09 23:47 ` George Anzinger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).