[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Переход на UTF8: проблема с именами файлов на DVD



On Mon, 04 Jan 2010 00:05:44 +0200
Serhiy Storchaka <storchaka@gmail.com> wrote:

> Yuri Kozlov wrote:
> > Для решения проблемы топикстартера достаточно заставить mount(2)
> > считаться с iocharset (только наоборот) и для rockridge.
> 
> fuse-convmvfs, как уже и посоветовали.

Да, как-то более универсальнее.

Тем не менее (быстрее надо было про fuse-convmvfs написать :) ), по
аналогии с перекодировкой из joliet слепил патчик к isofs. То есть для
дисков с rockridge, у которых имена файлов записаны в
koi8-r (тестировал iso, созданную с параметры из первого письма), будет всё
нормально с именами файлов в локали с кодировкой utf8.

sudo mount -t iso9660 -o ro,iocharset=koi8-r /dev/cdrom /mnt

Если не указан iocharset поломаться, вроде, ничего не должно.


-- 
Best Regards,
Yuri Kozlov

--- /usr/src/linux-source-2.6.30/fs/isofs/rock.c	2009-06-10 07:05:27.000000000 +0400
+++ isofs/rock.c	2010-01-04 10:22:57.000000000 +0300
@@ -10,6 +10,8 @@
 #include <linux/pagemap.h>
 #include <linux/smp_lock.h>
 
+#include <linux/nls.h>
+
 #include "isofs.h"
 #include "rock.h"
 
@@ -199,6 +201,12 @@
 	int truncate = 0;
 	int ret = 0;
 
+	struct nls_table *nls;
+	wchar_t *op;
+	int llen, len;
+	wchar_t *tmpname;
+	char *ip;
+
 	if (!ISOFS_SB(inode->i_sb)->s_rock)
 		return 0;
 	*retname = 0;
@@ -279,8 +287,35 @@
 	ret = rock_continue(&rs);
 	if (ret == 0)
 		goto repeat;
-	if (ret == 1)
+	if (ret == 1) {
+		nls = ISOFS_SB(inode->i_sb)->s_nls_iocharset;
+		if (nls) {
+			tmpname = kmalloc(retnamlen*(sizeof(wchar_t)+1), GFP_KERNEL);
+			if(!tmpname){
+				printk("isofs_rock: Can not allocate memory\n");
+				ret = -1; /* FIXME */
+				goto out;
+			}
+			len = retnamlen;
+			retnamlen = 0;
+			ip = retname;
+			op = tmpname;
+			while (len) {
+				llen = nls->char2uni(ip, NLS_MAX_CHARSET_SIZE, op);
+				if (llen > 0)
+					retnamlen += llen;
+				else
+					*op = '?';
+				ip++;
+				op++;
+				len--;
+			}
+			*op = 0;
+			retnamlen = utf8_wcstombs(retname, tmpname, retnamlen*sizeof(wchar_t));
+			kfree(tmpname);
+		}
 		return retnamlen; /* If 0, this file did not have a NM field */
+	}
 out:
 	kfree(rs.buffer);
 	return ret;

Reply to: