在Google Talk中显示foobar 2000正在播放的音乐

Goole Talk不支持显示foobar 2000正在播放的音乐的功能,而只支持Windows Media Player和WinAMP等几种播放软件。幸好foobar的插件是如此的丰富,总能找到一个可能的解决方案。

解决方案一:

使用AMIP插件,这是一个功能强的插件,通 常foobar支持Live Messenger的”Now Playing”功能也是用这个插件。下载安装这个插件后,还需要下载安装它的一个配置工具,只有用那个配置工具才可以方便的打开它的GTalk的支持。 不过这个插件的实现原理是直接去操作GTalk的界面,相当于是把曲目信息自动输入到GTalk的个人签名栏中,所以并不能完美的实现”Now Playing”的功能。这个插件适合已经使用它为Live Messager显示”Now Playing”功能的用户。

既然主动告诉GTalk曲目信息不是那么完美的解决方案,那就只让GTalk自己来找曲目信息才完美了,可以GTalk不认识foobar啊,最简单的解决方案就是让foobar“冒充”WinAmp,这就是解决方案二。

解决方案二:

下载安装foo_winamp_spam插件。在注册表中添加:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Winamp]
@="d:\\Program Files\\Foobar2000"

其中的路径就是你的foobar 2000的安装目录,同时在这个目录下建一个名字为winamp.m3u的空文件。

启动foobar试一下吧,曲名是不是已经可以显示在GTalk中了?

装了一下Ubuntu 7.04

一直听说Ubuntu是一个很好用的Linux发行版,但没有机会去体验,如今7.04新版发布,打算装一下试试。没想到Ubuntu用光盘启动很好用很好装,想用硬盘上的ISO来安装就没有这样简单了。

对于Red Hat之类的发行版来说,把ISO文件放在硬盘上然后通过硬盘安装是非常简单的,总的来说,只要把安装光盘的镜象放在硬盘某个分区的根目录中,并把光盘中 isolinux目录下的vmlinuz和initrd文件拿出来,用grub之类(DOS/Windows下可以用WinGrub)的引导程序进行引导 就可以了。

拿到了Ubuntu 7.04 LiveCD的iso,首先遇到的难题就是它的isolinux目录下根本没有我们需要的内核文件,后来找到了在capser目录下,可是拿出来以后按 Red Hat的方法并不能正确的安装。幸好有搜索引擎帮忙,查到了不少的资料,总结在这里。

1.使用Alternate镜象

从官方下载alternate版的镜象文件,不能用我们常用的desktop版的镜象(也就是Live CD)。并从http://archive.ubuntu.com/ubuntu/dists/feisty/main/中选择合适的目录(对于大多数人来说应该是在http://archive.ubuntu.com/ubuntu/dists/feisty/main/installer-i386/current/images/hd-media/)中下载启动用的内核文件(vmlinuz和initrd.img,或者打包后的boot.img.gz),再用与Red Hat相似的办法来安装。

这个方法显然不适合我:(,这样做的话我下载的Live CD就派不出用场了,得重新下载近700M的镜象,不划算,所以还得找其它的方法。

2.用修改过的启动内核

终于从Ubuntu中文论坛上找到了从Live CD镜象安装的方法,对应的贴子地址是:http://forum.ubuntu.org.cn/about26167.html。具体的作法是:

下载Live CD硬盘引导包http://ftp.ubuntu.org.cn/gnix_oag/boot_livecd_from_hd/feisty/bhd_i386_2.6.20-15g-ntfs-aufs.tar.gz,用户名密码是ubuntu和ubuntuftp。解包后的boot/feisty中有我们需要的启动内核文件。

然后在任意盘的根目录中建一个名为feisty的文件夹,把下载的Ubuntu的Live CD镜象文件放在里面。

有了内核文件,也放好了iso,下面就很简单了,跟装Red Hat类似,在grub中用下面的参数来引导系统就可以了(vmlinuz和initrd.gz按你实际文件所在位置要做相应的修改):

kernel (hd0,0)/boot/feisty/vmlinuz boot=gnix_oag
ramdisk_size=1048576 root=/dev/ram rw quiet splash
debian-installer/locale=zh_CN fd_dir=feisty
initrd (hd0,0)/boot/feisty/initrd.gz

经过这样的步骤,Ubuntu的Live CD就顺利启动起来,启动完了你就可以直接使用了,如果要安装,只需在Live CD的桌面上点击“安装”就可以了。如果你的机器上有Windows,安装程序会检测出来,并提供一个向导来帮助迁移数据。

简单使用了一下,感觉确实是很好用的,可用性比FC强了不少。Live CD自带的软件不多,只能满足最基本的上网和办公的功能。但是安装软件真是太简单了,可以说是比Windows还方便,根本不用自己到处找,你只要知道所 需要的软件的名字,然后打开终端,运行一下sudo apt-get install 软件名,回车后一切就等系统帮你搞定了。

强烈推荐对Linux有兴趣但又有点望而生畏的朋友体验一下Ubuntu,不要被我上面的文字吓坏了,非要用iso文件从硬盘安装是我自讨苦吃了。你要做的只是下载Ubuntu的安装镜象,刻录成光盘,或者直接申请领取免费的安装光盘,用光盘引导电脑后就可以直接使用了。这样的直接使用是不会影响你电脑中原来的数据的,一切都只存在光盘和内存中。如果这样试用让你对它产生了兴趣,你可以把它安装到硬盘上,安装也是很简单的,只要看清了硬盘分区情况,小心不要把有用的数据删除了就行了。

What is free software?

盖茨访华,虽然已经是第十次,但还是一件挺吸引眼球的事情。而就在今天,当微软遭遇开源抗议,事情就变得更吸引眼球了。

中午从看到这条消息,第一反应是又是哪位开源斗士开始发奋图强了,不会是Bill Xu继《致招商银行的公开信》活动后又一重大举措吧,新闻里照片上的人物并不清晰,不过看起来不像是Bill,倒像是另外一位我才认识不久的人。

下午的消息很快证实了我的猜想,这位勇士就是LPI中国首席代表——王开源

认识王开源还算是个巧合,月初参加CSDN英雄会时在会议结束去微软研发集团参观的车上遇到他。给人的第一印象是相当的热情,所以一路上也跟他聊了不少有关开源的话题。他打趣的说,一会儿到了微软,他要把名片发遍每一角落,在微软宣传开源的理念。

我和王开源在微软中国研发中心的照片,王开源把这张照片命名为“开源人士在微软”

我和王开源在微软中国研发中心的照片,王开源把这张照片命名为“开源人士在微软”

参观完微软,晚上与中科院自由软件协会的负责人之一于仕琪聊天,谈到王开源,他说是在协会组织的Ubuntu Edgy Eft北京发布会上见过面。说王开源在那次发布会上跳上讲台,涛涛不绝讲了N久开源的理念。

所以,当今天的消息确认是他在盖茨演讲会现场高呼“Free Software, Open Source”,也就觉得并不是那么惊讶了。

从去年的《致招商银行的公开信》到这次的”搅局”微软创新活动会议,在中国,我们越来越多的听到自由软件声音,这是一件好事。但是事件的背后, 却也带来了很多的争议。在Web 2.0时代,两次事件无一例外的通过互联网迅速到传到每个人的耳边,同时,大众对事件的看法也很快在互连网上散播开来。

一些人支持这样的活动,因为这样的活动有助于自由软件理念在国内的传播,在平淡的生活中,需要一些刺激的事件来吸引大众的目光;一些人支持自由 软件事业,但不支持这样的过激行为,因为它们会给人们留下开源就是偏激的印象;更多的人也许并不知道自由、免费和开源这三个词语的意义和区别,用自己的体 会去理解这样的事情,评价自然是负面的居多。

开源是一种行为,指的就是把软件的源代码开放,但是开放源代码也有很多的形式,简单的说,不同的开源协议决定了开源形式的不同。协议可以有很多 种,可以是GPL、LGPL、FreeBSD、Apache这类广泛使用的协议,也可以是你自己定义的协议,它们的共同点在于规定了把源代码公开这样行 为,但具体的在拿到源代码之后用户可以做的事情是范围,各种协议的规定是不尽相同的。比如,如果使用GPL协议,则意味着从开源代码上产生的任何衍生产品 都需要以GPL协议开源。而FreeBSD的协议则没有这样的严格。

免费,这个词也许就是从Free Software或freeware中翻译而来。也是大部分人对自由软件的最初认识。如果说freeware可以认为是免费软件的话,把Free Software翻译成免费软件就是大错特错了。

Free Software,正确的翻译应该是自由软件。我的Blog标题借用了GNU网站标题上的一句话:Free as in Freedom (GNU网站中文翻译成”自由自在”,虽然意义已经完全变了,不过我觉得意境倒是差不多,挺欣赏这个翻译的)。Free Software中的Free应该是Freedom中的Free,也就是自由。自由软件含义不在于是免费还是收费,它的含义是在于保证使用软件的每一个都 享有同等自由的权利。你可以任意的使用、修改、分发自由软件,你唯一”不自由”的地方就是你必须保证这个软件的其它用户享有与你一样的自由的权利。自由软 件没有规定收费与否,但由于规定了权利的对等,所以即使你收费了,别人一样可以收费或不收费的分发你的软件,所以软件免费而服务收费已经成为现在自由软件 的主要商业模式。值得注意的是自由与版权的关系,在GNU,Copyleft(中文没有标准翻译,我觉得翻译成”著左权”或”对称版权”比较好)这个词形 象的表明了对版权的认识。自由不是放弃版权,而是在保留版权的前提下提供他人自由。

FSF的GNU作为自由软件的最主要的倡导者,已经成为自由软件的标准。GPL也是使用最为广泛的开源协议之一。Richard Stallman是自由软件运动中教父级的人物。在他们的眼中自由软件的意义已经超出了软件的含义,更多的是成为了一种信仰。

自从我去年真正接触到自由软件以来,它也已经成为我日常生活中不可却少的一部分。但是我就个人而言,自由软件更多的是一种理想,而不是信仰。我 不喜欢Richard Stallman的带有宗教气息的自由软件运动,同样也不赞同以过激的方式来宣传自由软件的理念。自由软件中所折射出的黑客(注意区分这个词与”骇客”的 区别,在此不赘述了)的精神和崇尚自由的理念才是吸引我的地方。对于”坚决支持自由软件,说服教育开源软件,打击报复专有软件”这种所谓”自由软件人士应 有的态度”我实在不敢苟同,就像自由软件精神所倡导的那样,人人应该享有自由,自然也应该允许他人拥有选择专有软件的自由。也许自由软件需要一些领袖型的 主导人物、革命家,但是过激和盲目的宣传自由的理念实在不是值得鼓励的方式。

Google Apps与撞墙

没事打开Gmail的设置,想挖挖看有没有实用的功能没有发现,Gmail没发现什么新鲜的配置,却看到了Google Apps服务。以前就听说过Google Apps服务,不过那时自己没有域名也就没有具体去关注过它,如今有了自己域名倒是可以尝试一下。

虽然是Gmail页面上提示我的尝试这个服务,但注册倒是并没有那么顺利。不管我怎么填写注册信息,总是提示我”你所在的地区没有开通这项服务”。还好这样的问题相信不会是我一个人遇到,搜索了一下,很快就找到了解决的方案

Google Apps提供的主要服务就是在你自己的域名下提供简单的网页、邮件、聊天、日历、文档与表格处理的功能。其实也没有什么新奇的东西,只是Google几个 常见应用的整合。既然已经注册了,也就不管什么新不新奇了,一项项的开通吧。先是验证域名,然后就是一堆设置啦。嗯,以前一直不懂什么DNS的A记录啊C记录啊MX记录什么的,这次一折腾就全都明白了,原来一点也不深奥。开开心心辛辛苦苦改了一通域名的CNAME解析设置(C记录就是 把*.yourdomain.com解析到另一个域名上,而A记录就是指解析到IP上), 激活了docs.freemindworld.com/mail.freemindworld.com /calendar.freemindworld.com/start.freemindworld.com 这些服务。然后又改了DNS的MX解析(用于SMTP给你的@ yourdomain.com邮箱发邮件时查找你的接收邮件服务器),把邮件指向Google的邮件服务。Google的Wizard做的还不错,可以提 供很多国外域名注册商的操作步骤,我的域名是在Yahoo!注册的,Google也提供了准确的设置方法。

一切大功告成,就待享用了……咦?为什么一个都不能访问?嗯,大概是DNS的解析更新没有么快。nslookup一下,果然是还没有更新过来。那就等吧……

CNAME的更新还是很快的,不多久就可以nslookup到正确的解析结果了,可是还是不能访问上面列的那些网址。无奈中tracert了一下,看看结果,心里明白了一半,再上网一搜,终于确认:我撞墙了。如果你不知道什么是”撞墙”,就请点击前面的链接通过Google.com寻找答案。不要试图用Google.cn或Baidu来查找它的含义,这个词在它们身上已经被”拨毛“了。

心中颇为遗憾,但也实在无可奈何,怏怏的把改了半天的CNAME记录一个个复原,看来是只能用Google直接提供的长长的URL来访问这些服 务了。不过不幸中还是有万幸,那就是最有用的邮件功能(在免费邮箱满天飞的时代,这个功能其实也没有多少吸引力了)还是可以正常工作的。我的Google Apps帐号可以开通一百个@freemindworld.com的邮箱,每个大小2G,嗯,先给自己开一个 webmaster@freemindworld.com用用,自我感觉良好一下:-) 这个服务放在国内那些服务商里可又是要花一大笔银子才可以得到的。

体验了Google Apps,虽然不是很顺利,不过倒又让我想起了Microsoft类似的Live Custom Domains的服务,赶紧也去体验一下。可惜居然第一步就是要求把mx记录全部指向Live Mail。虽然我是最早一批试用Live Mail的,不过对它的印象并不好,它跟Gmail相比差距实在是有点大,于是乎就Byebye了Live Custom Domains.

作为变通,其实C记录不指向Google也一样可以用它的服务,只是地址栏显示的ugly一点,这可以通过在自己的虚拟主机网页空间中用程序对来访的域名进行解析和重定向。不过这个需要改动与虚拟主机所绑定的域名列表,我的主机的配置页面好像有点故障,明天再试着解决一下。

小函数,大问题

对于strcpy,sprintf,strcat这些不安全的函数的讨论应该算是不少了,大家都知道可以用strncpy,snprintf和strncat来替换它们。但实际工作中似乎这些“安全版”的函数带来的疑惑还是不小,总结了一下,列在这里。

1.sprintf(char * str, const char * format, …) -> snprintf(char * str, size_t size, const char * format, …)

vsprintf(char * str, const char * format, va_list ap) -> vsnprintf(char * str, size_t size, const char * format, va_list ap)

按照C/C++标准,snprintf和vsnprintf永远不会往str中输出多于size所指定的字节数的字符(包括结尾的’/0’),它们也保证了一定会在str中写入’/0’,所以在使用这个函数后不用担心结尾的问题。

举例:

char buf[5];
snprintf(buf, 5, "This is a test string."); // buf becomes "This", buf[4] is '/0'
snprintf(buf, 6, "This is a test string."); // ERROR: buffer overflow
snprintf(buf, 5, "abc"); // buf becomes "abc", the value of buf[3] is '/0', buf[4] is undefined.

然而,VC中的_snprintf函数并没有按照这样的规定来做,它在输出缓冲区不够大时就不会输出结尾的’/0′(跟strncpy的行为类似)。所以要让上面的程序工作正常,必须做相应的修改。

char buf[5];
_snprintf(buf, 5, "This is a test string.");// buf becomes "This ", buf[4] is ' '
buf[4] = 0; // buf[4] is '/0' now.
_snprintf(buf, 6, "This is a test string."); // ERROR: buffer overflow
_snprintf(buf, 5, "abc"); // buf becomes "abc", the value of buf[3] is '/0', buf[4] is undefined.

如果要保证可移植性,就得按VC的写法,做一次对于标准来说很多余的“填0”的操作,再通过定义宏来区别平台分别选用snprintf或_snprintf。

2. strcat(char * dest, const char * src) -> strncat(char * dest, const char * src, size_t n);

这个函数比较简单,它保证不会写入多于n+1个字符,并且保证最后一定以’/0’结束。

举例:

char dest[5] = "abc";
strncat(dest, "defghijklmn", 5 - 3 - 1); // dest becomes "abcd", dest[4] is '/0',
// always minus the buffer length by 1 as the value of n.
strncat(dest, "defghijklmn", 5 - 3); // ERROR: buffer overflow

3. strcpy(char * dest, const char * src) -> strncpy(char * dest, const char * src, size_t n);

strncpy是一个比较容易出错的函数,它保证复制src中不多于n字节的内容,但是如果src的前n个字节中没有包含’/0’,就会导致 dest没有正常的以’/0’终止。另外,它还保证如果src的长度小于n,则dest剩余的部分都会以’/0’填充。在用这个函数时,有一个最佳实践就 是先把dest以0填充,并传入dest的长度减1的值作为n,这样可以确保安全。

举例:

  char buf[5] = {0}; // Always zero-fill the buffer,
// always use this form to initialize the stack arrays to get
//better performance over memset.
char * buf2 = new char[5];
memset(buf2, 0, 5); // Always zero-fill the buffer
strncpy(buf, "abcde", 5); // ERROR: buf is not null-terminated.
strncpy(buf2, "abcde", 5 - 1); // Right, always minus the buffer length by 1
//as the value of n. buf becomes "abcd", buf[4]
//is '/0' by initilization;
// This is a common error in the existing code.
char buf3[5];
const char * str = "Test";
strncpy(buf3, str, strlen(str)); // Wrong, buf may not null-terminated,
// potential buffer-overflow
strncpy(buf3, str, strlen(str)+1); // Wrong, potential buffer-overflow.
//No difference with using strcpy.