Sep 242006
 

自从有了XGL这个东西,Linux下的3D桌面就开始疯狂起来,号称把VIsta的aero踩在脚下,更不把MacOS放在眼里,但是先进归先进,稳定性却不怎么样,这是我半年前在Ubuntu dagger下得出的痛苦结论。然而半年过去了,关于Linux 3D桌面发生了不小的变化,导致我这个小白鼠又一次冲在了前面,或许又是一个国内首创? Continue reading »

Jul 132006
 

此文讲解的是vim编辑多字节编码文档(中文)所要了解的一些基础知识,注意其没有涉及gvim,纯指字符终端下的vim。
vim编码方面的基础知识:

1,存在3个变量:
encoding—-该选项使用于缓冲的文本(你正在编辑的文件),寄存器,Vim 脚本文件等等。你可以把 ‘encoding’ 选项当作是对 Vim 内部运行机制的设定。
fileencoding—-该选项是vim写入文件时采用的编码类型。
termencoding—-该选项代表输出到客户终端(Term)采用的编码类型。
2,此3个变量的默认值:
encoding—-与系统当前locale相同,所以编辑文件的时候要考虑当前locale,否则要设置的东西就比较多了。
fileencoding—-vim打开文件时自动辨认其编码,fileencoding就为辨认的值。为空则保存文件时采用encoding的编码,如果没有修改encoding,那值就是系统当前locale了。
termencoding—-默认空值,也就是输出到终端不进行编码转换。

由此可见,编辑不同编码文件需要注意的地方不仅仅是这3个变量,还有系统当前locale、文件本身编码以及自动编码识别客户运行vim的终端所使用的编码类型3个关键点,这3个关键点影响着3个变量的设定。
如果有人问:为什么我用vim打开中文文档的时候出现乱码?
答案是不确定的,原因上面已经讲了,不搞清楚这3个关键点和这3个变量的设定值,出现乱码是正常的,倒是不出现乱码那反倒是凑巧的。

再来看一下常见情况下这三个关键点的值以及在这种情况下这3个变量的值:
1,locale—-目前大部分Linux系统已经将utf-8作为默认locale了,不过也有可能不是,例如有些系统使用中文locale zh_CN.GB18030。在locale为utf-8的情况下,启动vim后encoding将会设置为utf-8,这是兼容性最好的方式,因为内部处理使用utf-8的话,无论外部存储编码为何都可以进行无缺损转换。locale决定了vim内部处理数据的编码,也就是encoding。
2,文件的编码以及自动编码识别—-这方面牵扯到各种编码的规则,就不一一细讲了。但需要明白的是,文件编码类型并不是保存在文件内的,也就是说没有任何描述性的字段来记录文档是何种编码类型的。因此我们在编辑文档的时候,要么必须知道这文档保存时是以什么编码保存的,要么通过另外的一些手段来断定编码类型,这另外的手段,就是通过某些编码的码表特征来断定,例如每个字符占用的字节数,每个字符的ascii值是否都大于某个字段来断定这个文件属于何种编码。这种方式vim也使用了,这就是vim的自动编码识别机制了。但这种机制由于编码各式各样,不可能每种编码都有显著的特征来辨别,所以是不可能100%准确的。对于我们GB2312编码,由于其中文是使用了2个acsii值高于127的字符组成汉字字符的,因此不可能把gb2312编码的文件与latin1编码区分开来,因此自动识别编码的机制对于gb2312是不成功的,它只会将文件辨识为latin1编码。此问题同样出现在gbk,big5上等。因此我们在编辑此类文档时,需要手工设定encoding和fileencoding。如果文档编码为utf-8时,一般vim都能自动识别正确的编码。

3,客户运行vim的终端所使用的编码类型—-同第二条一样,这也是一个比较难以断定的关键点。第二个关键点决定着从文件读取内容和写入内容到文件时使用的编码,而此关键点则决定vim输出内容到终端时使用的编码,如果此编码类型和终端认为它收到的数据的编码类型不同,则又会产生乱码问题。在linux本地X环境下,一般终端都认为其接收的数据的编码类型和系统locale类型相符,因此不需关心此方面是否存在问题。但如果牵涉到远程终端,例如ssh登录服务器,则问题就有可能出现了。例如从1台locale为GB2310的系统(称作客户机)ssh到locale为utf-8的系统(称作服务器)并开启vim编辑文档,在不加任何改动的情况下,服务器返回的数据为utf-8的,但客户机认为服务器返回的数据是gb2312的,按照gb2312来解释数据,则肯定就是乱码了,这时就需要设置termencoding为gb2312来解决这个问题。此问题更多出现在我们的windows desktop机远程ssh登录服务器的情况下,这里牵扯到不同系统的编码转换问题。所以又与windows本身以及ssh客户端有很大相关性。在windows下存在两种编码类型的软件,一种是本身就为unicode编码方式编写的软件,一种是ansi软件,也就是程序处理数据直接采用字节流,不关心编码。前一种程序可以在任何语言的windows上正确显示多国语言,而后一种则编写在何种语言的系统上则只能在何种语言的系统上显示正确的文字。对于这两种类型的程序,我们需要区别对待。以ssh客户端为例,我们使用的putty是unicode软件,而secure CRT则是ansi 软件。对于前者,我们要正确处理中文,只要保证vim输出到终端的编码为utf-8即可,就是termencoding=utf-8。但对于后者,一方面我们要确认我们的windows系统默认代码页为cp936(中文windows默认值),另一方面要确认vim设置的termencoding=cp936。

最后来看看处理中文文档最典型的几种情况和设置方式:

1,系统locale是utf-8(很多linux系统默认的locale形式),编辑的文档是GB2312或GBK形式的(Windows记事本默认保存形式,大部分编辑器也默认保存为这个形式,所以最常见),终端类型utf-8(也就是假定客户端是putty类的unicode软件)
则vim打开文档后,encoding=utf-8(locale决定的),fileencoding=latin1(自动编码判断机制不准导致的),termencoding=空(默认无需转换term编码),显示文件为乱码。
解决方案1:首先要修正fileencoding为cp936或者euc-cn(二者一样的,只不过叫法不同),注意修正的方法不是:set fileencoding=cp936,这只是将文件保存为cp936,正确的方法是重新以cp936的编码方式加载文件为:edit ++enc=cp936,可以简写为:e ++enc=cp936。
解决方案2:临时改变vim运行的locale环境,方法是以LANG=zh_CN vim abc.txt的方式来启动vim,则此时encoding=euc-cn(locale决定的),fileencoding=空(此locale下文件编码自动判别功能不启用,所以fileencoding为文件本身编码方式不变,也就是euc-cn),termencoding=空(默认值,为空则等于encoding)此时还是乱码的,因为我们的ssh终端认为接受的数据为utf-8,但vim发送数据为euc-cn,所以还是不对。此时再用命令:set termencoding=utf-8将终端数据输出为utf-8,则显示正常。

2,情况与1基本相同,只是使用的ssh软件为secure CRT类ansi类软件。

vim打开文档后,encoding=utf-8(locale决定的),fileencoding=latin1(自动编码判断机制不准导致的),termencoding=空(默认无需转换term编码),显示文件为乱码。

解决方案1:首先要保证运行secure CRT的windows机器的默认代码页为CP936,这一点中文windows已经是默认设置了。其他的与上面方案1相同,只是要增加一步,:set termencoding=cp936

解决方案2:与上面方案2类似,不过最后一步修改termencoding省略即可,在此情况下需要的修改最少,只要以locale为zh_CN开启vim,则encoding=euc-cn,fileencoding和termencoding都为空即为encoding的值,是最理想的一种情况。

可见理解这3个关键点和3个参数的意义,对于编码问题有很大助力,以后就可以随心所欲的处理文档了,同时不仅仅是应用于vim,在其他需要编码转换的环境里,都可以应用类似的思路来处理问题解决问题。

最后推荐一款功能强大的windows下的ssh客户端—-xshell,它具有类似secure CRT一样的多tab 的ssh窗口的能力,但最为方便的是这款工具还有改变Term编码的功能,这样我们就可以不用频繁调整termencoding,只需在ssh软件里切换编码即可,这是我用过的最为方便的ssh工具。它是商业软件,但非注册用户使用没有任何限制,只是30天试用期超出后会每次启动都提示注册,对于功能没有丝毫影响。

Jun 172006
 

好久没有玩Linux桌面了,记得以前还是在90年代末在国内媒体对Linux近乎狂热的宣传大潮下我开始对Linux桌面的研究的。那个时候的所谓Linux发行版,从安装开始,步步都是地雷,安装好之后也只是看上去很美,连个汉字都显示不好,更别说应用了。就是在那时候,一方面舆论误导,另一方面自己天真的天真的以为会玩Linux就是高手(想必现在的菜鸟们还是这么想得吧),我学会了怎么分区,怎么装rpm,怎么汉化,怎么用simsun替换字体,怎么让声卡发声,怎么拨号上网等,足足花了有2年的时间吧。现在想来,那个时候真是精力旺盛,想不佩服自己都不行。
工作以后,才知道自己学的那点破东西基本没什么用,那些真正可以称作Linux精华的东西,其实在传统Unix中都可以找到,例如vi,例如shell脚本,例如apache,mysql等等等等,这才幡然醒悟----当年被人坑了。
怎奈Linux还是潮流,那就要继续跟,于是乎在后来的时间,一方面加紧学习Linux在服务器方面的应用,另一方面经手了无数其他的操作系统,知名的和不知名的。以至于相当长一段时间,都会在做某些操作的时候,在想此操作在XXX系统上可通过何种方法实现。
再后来,终于悟出了,这么多花花绿绿的东西基本上都是同源的,甚至当年Windows95都包含了BSD的代码,还有什么不能混血的?所以开始研究内核,研究操作系统实现。到最后,发现不论是何种实现,最后要达到的目标是相同的,大家不过是在这数种实现方法中取长补短,共同进化而已。
直到这时,才感觉自己真正能够抓住些东西了,所以现在的研究重点不过是Posix标准,RFC,等等等等,然后再去看内核代码这些个东西是怎么实现的。当然新操作系统还是要玩的,不玩怎么知道以后的潮流是什么哦。

扯远了,今天的目标是Ubuntu Linux。这东西属于Linux发行版的后起之秀了,是Debian的一种fork。同时就继承了Debian的所有优点,比如apt,比如良好的桌面环境。据说Ubuntu的作者是某个亿万富翁,这家伙某天突然迷上了Linux,因此自己出钱搞了一批人,搞出了这样一个系统,为了迅速推广它,作者到目前为止Ubuntu还提全世界范围的供免费的光盘邮寄服务,其强大财力不得不让人叹服。

废话不说了,开搞。

安装过程跟以往Linux发行版有不小区别,竟然是先启动一个LiveCD的版本给你尝鲜,然后再安装的。安装过程非常简单,给人的选择就只有用户名密码,和计算机名而已,连安装组件都不能定制。安装完成后看了下是往硬盘塞了1G多的东西,还好不算太臃肿了。
第一次启动发现grub被搞到mbr了,还好还能切换到longhorn的ntldr,有惊无险。启动过程不长不段,平均水平吧,启动的图形界面比较粗糙,只能说聊胜于无吧。
启动成功后进入的应该是gdm,session只有gnome一个可选,语言可选的倒是很多,做得似乎很漂亮,选中文试试看。输入用户名密码进入gnome。完全启动成功后发现基本就是最普通的gnome,只是壁纸换过而已。
惯例首先检查硬件,发现声卡能出声,网卡通过dhcp也成功驱动,直接进入在线状态。所有硬盘分区都已经直接挂载好了,连ntfs分区都搞定。并且中文显示完全正常,只是默认的楷体字不很习惯。看到这里不禁嘘唏不已,花了近半年才基本搞定的东西,现在默认都能给配好了。再看中文输入,竟然默认已经安装了scim并启用,使用起来非常顺手。再加上openoffic,基本上windows下需要的普通上网和办公工作都能完成了。真是非常不错的桌面系统,比当年所谓的那些Linux不知好了多少倍。也许Linux被普通用户接受不再是遥遥无期的事情了??
再来看多媒体,默认的movie player基本上什么都放不了,连mp3都不行,意料之中,linux发行版不可能将有版权的东西作为默认组件,不过现在不能不代表不可以,来试试看起源自debian的强大apt管理机制!从菜单里找到一个Synaptic package manager ,应该属于apt前端,发现search功能,直接敲xine,不出所料找到一些包,选中,确认,果然自动开始下载并安装,所有依赖包自动安装,不错!完成后实验一下,mp3能放了,普通无压缩avi也可以了,wmv和rm还有div等还不行,简单,装解码包!继续找w32codecs,竟然也有apt源,装了,顺手找到了mplayer,一并装了,中间下载时间长了些,但还是基本满意的。装好后实验,完全可用!想当年为了折腾个mplayer从autoconfig学到gcc,声卡驱动换了好几茬,历时无数次系统重装,跨越n个发行版,历时1年才第一次成功,基本见证了从linux盲到基本合格的linux user的过程,想想真是心酸。仔细一看放电影速度不甚满意,一检查发现显卡驱动用的竟然是vesa,立刻想到到nvidia.com下载,转念一想我还要试试apt,竟然又顺利找到apt源并安装好,只是后来配置不是自动完成,还要修改xorg.conf,完成后直接ctrl+alt+backspace,gdm一起来就瞅见nvidia大大的徽标,登入再放视频,一切ok!

没想到几年没有关心,linux桌面的可用程度有了如此大的提高,看来普通用户的选择会越来越多了,有意思的玩具也会越来越多了,幸也!

下个目标,看看传说中的XGL!待续…..

May 152006
 

今天研究了下pcap,简单写了段代码,能嗅探到混杂模式网卡接收到的所有包了,贴一下以备以后使用:

#include
#include
#include
#include
#include
#include
#include
#include
#include

#include

int main()
{
char *dev, errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t * alldevsp;
dev = pcap_lookupdev(errbuf);
printf(“Device used: %sn”, dev);
int x=pcap_findalldevs(&alldevsp,errbuf);
pcap_if_t * ifdev;
for(ifdev=alldevsp;ifdev;ifdev=ifdev->next)
{
printf(“Device: %sn”,ifdev->name);
}

struct bpf_program filter;
char filter_app[] = “host 10.0.0″;
bpf_u_int32 mask;
bpf_u_int32 net;

pcap_t* adhandle;

adhandle = pcap_open_live(dev,100,1,1000,errbuf);
pcap_lookupnet(dev, &net, &mask, errbuf);
pcap_compile(adhandle, &filter, filter_app, 0, net);

pcap_setfilter(adhandle, &filter);

pcap_dumper_t* dumpfile;
dumpfile=pcap_dump_open(adhandle, “packet.dat”);
int re;
struct pcap_pkthdr* header;
u_char* pkt_data;
while((re=pcap_next_ex(adhandle,&header,(const u_char**)&pkt_data))>=0)
{
pcap_dump((unsigned char*)dumpfile,header,pkt_data);
}

pcap_freealldevs(alldevsp);
return(0);
}

May 112006
 

RedHat企业版自从AS4开始,桌面版本自从FC3开始,不再单独提供kernel-sourcecode的rpm安装包,原因是RedHat认为没有必要维护单独的kernel-sourcecode包,因为所有的源代码包都应该包含在.src.rpm中而不是rpm中。所以在这些高版本的RedHat Linux上,我们如果需要定制内核的话,没有直接的源代码rpm可以安装,只能通过kernel.org下载的tar.gz的包手工安装,或者通过kernel-*.src.rpm编译出kernel-source包再来安装。后面一种方法可以享受到RedHat针对内核的某些参数和代码的优化,因此对使用RedHat发行版特别是企业版本的,是有一定好处的。
但是目前很多人至今分不清内核,内核开发,内核源代码一些包之间的关系,因此在编译内核的时候经常走弯路,同时RedHat官方对于如果得到kernel-source也没有明确的指示,导致很多人不得要领。

首先认清楚各rpm包的内容和用途
kernel-*.rpm ————- 内核二进制包,没有的话系统都起不来
kernel-sourcecode-*.rpm——————- 内核源代码包,安装到/usr/src/linux-*下面的,包含内核源代码,编译内核必须(当然是不考虑用kernel.tar.gz编译的情况),但高版本RedHat Linux不再提供此rpm,原因参见官方Release Note,这篇文章的最终目的就是要我们自己把这个包搞出来。
kernel-devel-*.rpm—————-内核开发包,安装到/usr/src/kernels,用于内核模块开发,组织形式跟内核源代码包类似,包含了部分内核源代码。注意很多人误认为这个就是内核源代码包,直接拿它来编译内核,当然不可能成功。这个包只是用于内核模块一级开发,例如驱动程序等,虽然也可以make menuconfig make dep等,但make bzImage是不可能成功的,因为缺失了核心源代码。
kernel-*.src.rpm—————RedHat提供的用于建立rpm的源代码包,安装到/usr/src/redhat中,使用rpmbuild可以从这个包中build出上面所说的所有包。

现在就来从src.rpm编译出上面的所有的包,除了sourcecode这个包其他的包都可以在不用修改任何地方的情况下直接rpmbuild出来,唯有sourcecode这个比较麻烦,一定要按照下面的步骤来做,我以RedHat AS4 所带的版本为例,其他版本相同。

#首先安装src.rpm
rpm -ivh kernel-2.6.9-5.EL.src.rpm
#进入相应目录,要修改spec文件
cd /usr/src/redhat/SPECS
vi kernel-2.6.spec
#主要修改如下地方:
1,define buildsource 0————我的这个在第8行,改为1,这就是为什么没有源代码包的原因,因为默认不生成源代码包
2, Requires: qt-devel, gtk2-devel readline-devel ncurses-devel——-我的在572行,如果没用用X的话,把这句注释掉,这样编译出来的包就不依赖于X-window的某些包,因为内核配置是可以make xconfig的,所以默认依赖X-window,我没装X-window,因此这个就去掉了。
#保存退出
touch /etc/beehive-root
#这句命令非必须,如果不做的话,最后编译出来的包都会变成kernel-*.*-root.rpm,多了个root,据说是为了标示包的编译人的,如果touch了这个文件,就没有这个问题了,命名和官方rpm一样。
rpmbuild -ba –target=i686 ./kernel-2.6.spec
#编译i686平台的所有包,这样上面介绍的所有包都会生成,或者换成rpmbuild -bb –target=i686 ./kernel-2.6.spec只编译非src.rpm。
#所有包就会生成到/usr/src/redhat/RPMS/i686下面

#如果只需要sourcecode而并非所有rpm包,那在修改spec文件时还要修改如下行:

48 %ifarch noarch
49 %define builddoc 1
50 %define buildsource 0—————-这里0修改为1
在编译的时候使用rpmbuild -ba –target=noarch ./kernel-2.6.spec,这样仅仅编译soucecode和doc包,会节省很多时间。

注意,此篇文章所讲所有内容仅适用于使用2.6内核的新版本RedHat Linux,2.4版本内核代码组织方式不同,不适用此文章。