Chinaunix首页 | 论坛 | 博客
  • 博客访问: 772150
  • 博文数量: 265
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 1985
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-13 12:33
文章分类

全部博文(265)

文章存档

2011年(1)

2010年(66)

2009年(198)

我的朋友

分类: LINUX

2010-02-08 15:33:20

昨天打算用把 kerneltravel上的深入分析Linux内核源码全部下载到本机,没想到使用下载到本地时文件名全部是乱码:

[cocobear@cocobear ~]$ -r -p -k -np 深入分析Linux内核源码.html
–19:52:02– %E6%B7%B1%E5%85%A5%E5%88%86%E6%9E%90Linux%E5%86%85%E6%A0%B8%E6%BA%90%E7%A0%81.html
=> `深�%85��%88%86�%9E%90Linux�%86%85核 ��%90��%81.html’
正在解析主机 … 202.75.211.215
Connecting to |202.75.211.215|:80… 已连接。
已发出 HTTP 请求,正在等待回应… 200 OK
长度:133,528 (130K) [text/html]

100%[====================================>] 133,528 60.71K/s

19:52:05 (60.57 KB/s) – `深�%85��%88%86�%9E%90Linux�%86%85核 ��%90��%81.html’ saved [133528/133528]

google了半天也没有找到解决方案,似乎也有不少人碰到这个问题。仔细想了想应该是在处理url时的问题,于是下载了最新的开 始找问题。

基本看完了这 个文件,后来在这 个文件里找到了如何处理保存的文件 名,url_file_name()这个函数。

url_file_name()在根据url的形式判断该保存为什么样的文件名,并进行了多方面的考虑,最终该函数调用了 append_uri_pathel(),该函数会判断url中的特殊字符,例如空格等,如果遇到这些字符把它进行转义,而问题就出在这 里,append_uri_pathel()函数是通过FILE_CHAR_TEST (*p, mask)这一句来判断该字符是否为特殊字符,而同时它会认为中文也是特殊字符,然后按照转换空格之类的方式对中文进行转义,这样就会造成中文乱码的情 况,知道了问题所在我在append_uri_pathel()函数对特殊字符的判断中排除了中文字符。

接下来重新编译,再试一次:

[cocobear@cocobear src]$ ./ -r -p -k -np 深入分析Linux内核源码.html
–2008-04-19 20:16:34– %E6%B7%B1%E5%85%A5%E5%88%86%E6%9E%90Linux%E5%86%85%E6%A0%B8%E6%BA%90%E7%A0%81.html
Resolving … 202.75.211.215
Connecting to |202.75.211.215|:80… connected.
HTTP request sent, awaiting response… 200 OK
Length: 133528 (130K) [text/html]
Saving to: `深入分析Linux内核源码.html’

74% [===========================> ] 98,832 79.7K/s

可以看到可以正确的把中文的 网页保存下来了:-)

我的locale是utf-8,如果使用gbk的话上 面的网页会得到404错误,因为gbk环境下发 出来GET请求是按照gbk编码的方式进行转义,而服务器对接收到的GET请求中的URL是按照UTF-8的方式进行“解码”,因此会得到404的错 误。(早上测试的时候还是这样的,但下这会写这篇文章的时候gbk环境下使用也正常了,郁闷)

以下是我修改后的url.c与原文的diff:
[cocobear@cocobear ~]$ diff -u -1.11.1/src/url.c Codes/-1.11.1/src/url.c
-1.11.1/src/url.c 2008-04-19 11:42:24.000000000 +0800
+++ Codes/-1.11.1/src/url.c 2008-04-19 11:56:49.000000000 +0800
@@ -1332,11 +1332,10 @@
/* Walk the PATHEL string and check how many characters we’ll need
to quote. */
quoted = 0;
- for (p = b; p < e; p++) {
- if (FILE_CHAR_TEST (*p, mask) && !((*p | 0×0fffffff) == 0xffffffff)) {
+ for (p = b; p < e; p++)
+ if (FILE_CHAR_TEST (*p, mask) && !((*p | 0×0fffffff) == 0xffffffff))
++quoted;
- }
- }
+
/* Calculate the length of the output string. e-b is the input
string length. Each quoted char introduces two additional
characters in the string, hence 2*quoted. */

以上仅仅是我自己对的一些分析、看法, 如有错误请路过的指正一下。

BTW:
(1):这个网站不错,有不少源代码在上面可以在线看。
(2):深入分析Linux内核源码这本书打包下载(html格式): /Understand_Linux_kernel.tar.bz2

Update1(08.4.20):
这个问题是对国际化的字符支持 不好,目前google summer code已经有人在这方面进行改进,期待。我的解决方案只是临时的,只能针对utf-8环境。


traceback:http://cocobear.info/blog/2008/04/19/wget-chinese-encode/

============================================

#!/usr/bin/php
# Author: hutuworm
# Date: 20031115

<?php
function traveldir($dirname)
{
    if($dirname[strlen($dirname)-1]!='/')
        $dirname.='/';
    $dirhandle=opendir($dirname);
    while($file=readdir($dirhandle))
    {
        if($file=='.'||$file=='..')
            continue;
        if(is_dir($dirname.$file)||is_file($dirname.$file))
        {
            $newname=quoted_printable_decode(ereg_replace("%","=",$dirname.$file));
            $realname='"'.$newname.'"';
            $oldname='"'.$dirname.$file.'"';
            if($$realname)
                system("mv $oldname $realname");
            if(is_dir($dirname.$file))
            {
                traveldir($newname.'/');
            }
        } else
            continue;
    }
    closedir($dirhandle);
}

if(isset($argv[1]) && is_dir($argv[1]))
{
    $targetdir=$argv[1];
    traveldir($targetdir);
} else
    echo "Usage: ./wget_chinese.php /path/to/dir \n";
?>


trackback: 

阅读(2118) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~