免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3217 | 回复: 5
打印 上一主题 下一主题

[NetBSD] 如何在挂载磁盘时支持中文? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-03 13:45 |只看该作者 |倒序浏览
netbsd的mount命令没有-C,也没有-L。然后我也找不到netbsd下的gbfs。

哪位知道的高手帮下忙,谢了!

论坛徽章:
0
2 [报告]
发表于 2009-11-09 22:22 |只看该作者
同问,我也想知道。
以前问过,没人回,呵呵!

论坛徽章:
0
3 [报告]
发表于 2009-11-09 23:56 |只看该作者
编码转换的kiconv 好象最早出现在 netbsd 的哦。不过还是使用UTF-8比较方便。假如有测试环境的话,倒是可以写个UTF-8支持的patch。

  1. diff -rupd src/sys/fs/msdosfs/direntry.h ../src/sys/fs/msdosfs/direntry.h
  2. --- src/sys/fs/msdosfs/direntry.h        Sun Dec  4 01:34:44 2005
  3. +++ ../src/sys/fs/msdosfs/direntry.h        Wed Nov 11 20:17:28 2009
  4. @@ -133,6 +133,7 @@ int        unix2winfn(const u_char *un, int unl
  5. int        winChkName(const u_char *un, int unlen, struct winentry *wep,
  6.             int chksum);
  7. int        win2unixfn(struct winentry *wep, struct dirent *dp, int chksum);
  8. +int        fn_utf8_conv(struct dirent *dp, int chksum);
  9. u_int8_t winChksum(u_int8_t *name);
  10. int        winSlotCnt(const u_char *un, int unlen);
  11. #endif        /* _KERNEL */
  12. diff -rupd src/sys/fs/msdosfs/msdosfs_conv.c ../src/sys/fs/msdosfs/msdosfs_conv.c
  13. --- src/sys/fs/msdosfs/msdosfs_conv.c        Mon Mar 16 01:15:58 2009
  14. +++ ../src/sys/fs/msdosfs/msdosfs_conv.c        Wed Nov 11 20:34:24 2009
  15. @@ -703,7 +703,7 @@ win2unixfn(struct winentry *wep, struct
  16.         u_int8_t *np, *ep = dp->d_name + WIN_MAXLEN;
  17.         int i;

  18. -        if ((wep->weCnt&WIN_CNT) > howmany(WIN_MAXLEN, WIN_CHARS)
  19. +        if ((wep->weCnt&WIN_CNT) > howmany(WIN_MAXLEN, (WIN_CHARS*2))
  20.             || !(wep->weCnt&WIN_CNT))
  21.                 return -1;

  22. @@ -725,8 +725,16 @@ win2unixfn(struct winentry *wep, struct
  23.          * Offset of this entry
  24.          */
  25.         i = ((wep->weCnt&WIN_CNT) - 1) * WIN_CHARS;
  26. -        np = (u_int8_t *)dp->d_name + i;
  27. +        np = (u_int8_t *)dp->d_name + i*2;

  28. +        memcpy(np, wep->wePart1, sizeof(wep->wePart1));
  29. +        np += sizeof(wep->wePart1);
  30. +        memcpy(np, wep->wePart2, sizeof(wep->wePart2));
  31. +        np += sizeof(wep->wePart2);
  32. +        memcpy(np, wep->wePart3, sizeof(wep->wePart3));
  33. +        np += sizeof(wep->wePart3);
  34. +
  35. +#ifdef UTF8_SUPPORT
  36.         /*
  37.          * Convert the name parts
  38.          */
  39. @@ -793,6 +801,7 @@ win2unixfn(struct winentry *wep, struct
  40.                 if (*cp++)
  41.                         return -1;
  42.         }
  43. +#endif
  44.         return chksum;
  45. }

  46. @@ -822,4 +831,143 @@ winSlotCnt(const u_char *un, int unlen)
  47.         if (unlen > WIN_MAXLEN)
  48.                 return 0;
  49.         return howmany(unlen, WIN_CHARS);
  50. +}
  51. +
  52. +static int iconv_u2w(const char **inbuf, size_t *inbytes,
  53. +        char **outbuf, size_t *outbytes)
  54. +{   
  55. +    u_int8_t mark;
  56. +    u_int16_t uc = 0;
  57. +    char * obuf  = NULL;
  58. +    const char *ibuf, *ibuf_end, *obuf_end;
  59. +    if ((inbuf&&inbytes&&outbuf&&outbytes)
  60. +            && (*inbuf&&*inbytes&&*outbuf&&*outbytes)){
  61. +        ibuf = *inbuf;
  62. +        ibuf_end = *inbuf+*inbytes;
  63. +        obuf = *outbuf;
  64. +        obuf_end = *outbuf+*outbytes;
  65. +        int follow = 0;
  66. +        while(ibuf<ibuf_end && &obuf[1]<obuf_end){
  67. +            mark = (u_int8_t)*ibuf++;
  68. +            if (mark<0xF0 && mark>0xE0){
  69. +                /* 1110XXXX */
  70. +                uc = mark&0x0F;
  71. +                follow = 2;
  72. +            }else if (mark<0xE0 && mark>0xC0){
  73. +                /* 110XXXXX */
  74. +                uc = mark&0x1F;
  75. +                follow = 1;
  76. +            }else if (mark<0x80){
  77. +                /* 0XXXXXXX */
  78. +                uc = mark;
  79. +                follow = 0;
  80. +            }else{
  81. +                /* convert fail: 0xF0 0xE0 should NOT in UTF-8 seq */
  82. +                printf("convert fail 0xF0 0xE0\n");
  83. +                break;
  84. +            }
  85. +            if (&ibuf[follow] > ibuf_end){
  86. +                /* unexpect input end */
  87. +                break;
  88. +            }
  89. +            for (; follow>0; follow--){
  90. +                /* 10XX.XXXX 0x80-0xBF*/
  91. +                if ((*ibuf&0xC0) != 0x80){
  92. +                    *outbytes = obuf_end - *outbuf;
  93. +                    *inbytes = ibuf_end - *inbuf;
  94. +                    printf("convert fail SEQ\n");
  95. +                    return 0;
  96. +                }
  97. +                uc = (uc<<6)|(*ibuf++&0x3F);
  98. +            }
  99. +            *obuf++ = (uc>>8);
  100. +            *obuf++ = uc;
  101. +            *outbuf = obuf;
  102. +            *inbuf = ibuf;
  103. +        }
  104. +        *outbytes = obuf_end - *outbuf;
  105. +        *inbytes = ibuf_end - *inbuf;
  106. +    }
  107. +    return 0;
  108. +}
  109. +
  110. +static int iconv_w2u(const char **inbuf, size_t *inbytes,
  111. +        char **outbuf, size_t *outbytes)
  112. +{
  113. +    u_int16_t uc = 0;
  114. +    char *obuf  = NULL;
  115. +    const char *ibuf, *ibuf_end, *obuf_end;
  116. +    if ((inbuf&&inbytes&&outbuf&&outbytes)
  117. +            && (*inbuf&&*inbytes&&*outbuf&&*outbytes)){
  118. +        ibuf = *inbuf;
  119. +        ibuf_end = *inbuf+*inbytes;
  120. +        obuf = *outbuf;
  121. +        obuf_end = *outbuf+*outbytes;
  122. +        int follow = 0;
  123. +        while(&ibuf[1]<ibuf_end && obuf<obuf_end){
  124. +            uc = (0xFF&*ibuf++);
  125. +            uc = (0xFF&*ibuf++)|(uc<<8);
  126. +            if (uc < 0x80){
  127. +                *obuf++ = (uc);
  128. +                follow = 0;
  129. +            }else if (uc < 0x800){
  130. +                *obuf++ = (uc>>6)|0xC0;
  131. +                follow = 1;
  132. +            }else {
  133. +                /* assert(uc<=0xFFFF); */
  134. +                *obuf++ = (uc>>12)|0xE0;
  135. +                follow = 2;
  136. +            }
  137. +            if (&obuf[follow] > obuf_end){
  138. +                /*no output buffer */
  139. +                break;
  140. +            }
  141. +            for (follow--;follow>=0;follow--){
  142. +                int shift = follow*6;
  143. +                u_int8_t ch = uc>>shift;
  144. +                *obuf++ = (ch&0x3F)|0x80;
  145. +            }
  146. +            *outbuf = obuf;
  147. +            *inbuf = ibuf;
  148. +        }
  149. +        *outbytes = obuf_end - *outbuf;
  150. +        *inbytes = ibuf_end - *inbuf;
  151. +    }
  152. +    return 0;
  153. +}
  154. +
  155. +int        fn_utf8_conv(struct dirent *dp, int chksum)
  156. +{
  157. +    size_t ucs2len, utf8len;
  158. +    u_int8_t *ucs2buf, *utf8buf, *cp;
  159. +
  160. +    u_int8_t buff[WIN_MAXLEN];
  161. +
  162. +    utf8buf = buff;
  163. +    utf8len = sizeof(buff)-1;
  164. +
  165. +    ucs2buf = dp->d_name;
  166. +    ucs2len = dp->d_namlen;
  167. +
  168. +    iconv_w2u(&ucs2buf, &ucs2len, &utf8buf, &utf8len);
  169. +
  170. +    /* utf-8 name too long, just return */
  171. +    if (ucs2len > 0)
  172. +        return -1;
  173. +
  174. +    cp = dp->d_name;
  175. +    /* notice: WIN_MAXLEN < sizeof(dp->d_name), so sizeof(buff)-utf8len+1 < sizeof(dp->d_name) */
  176. +    for (utf8buf=buff; utf8len<sizeof(buff)-1; utf8len++) {
  177. +        switch (*cp++ = *utf8buf++) {
  178. +            case '0':
  179. +                dp->d_namlen = (cp-dp->d_name);
  180. +                return chksum;
  181. +            case '/':
  182. +                *(cp-1) = 0;
  183. +                return -1;
  184. +        }
  185. +    }
  186. +
  187. +    dp->d_namlen = (cp-dp->d_name);
  188. +    return chksum;
  189. }
  190. diff -rupd src/sys/fs/msdosfs/msdosfs_vnops.c ../src/sys/fs/msdosfs/msdosfs_vnops.c
  191. --- src/sys/fs/msdosfs/msdosfs_vnops.c        Sat Jul  4 05:17:40 2009
  192. +++ ../src/sys/fs/msdosfs/msdosfs_vnops.c        Wed Nov 11 20:16:04 2009
  193. @@ -1634,6 +1634,7 @@ msdosfs_readdir(void *v)
  194.                                     offset / sizeof(struct direntry);
  195.                                 dirbuf->d_type = DT_REG;
  196.                         }
  197. +            chksum = fn_utf8_conv(dirbuf, chksum);
  198.                         if (chksum != winChksum(dentp->deName))
  199.                                 dirbuf->d_namlen = dos2unixfn(dentp->deName,
  200.                                     (u_char *)dirbuf->d_name,

复制代码


打上这个补丁,应该可以看到中文文件名(当然了不能写入)。netbsd_msdosfs_utf8_patch.diff

[ 本帖最后由 pagx 于 2009-11-11 23:26 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2009-11-18 23:43 |只看该作者
一直不知道如何在 NetBSD 与 OpenBSD 中 mount 上含有中文字符的 FAT 与 NTFS 分区,也在几个 BSD 坛子中问过,但都没找到答案,楼上达人能多说几句、指点一二吗?不胜感激!

论坛徽章:
0
5 [报告]
发表于 2009-11-19 11:16 |只看该作者
FAT32的长文件名是UCS2编码的。文件系统把 > 128的码位过滤掉了,所以是不可能看到中文名的。想看到中文,要么打patch, 要么可以使用其他的驱动,比如ntfs-3g。

论坛徽章:
0
6 [报告]
发表于 2009-11-19 22:25 |只看该作者
原来如此,多谢。
唉!什么时候能象 freebsd 一样简单的用 -L 和 -C 搞定就好了!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP