I am LAZY bones? AN ancient AND boring SITE

linux下架设个人电台的方法

两年前(基本上刚好是两年了),我还在用windows的时候,曾经写过一篇win下架电台的文章,后来不用windows了,基本上也就没搞过这个事情了,最近看到有个icecast,就忍不住试了一下,在这里汇报下结果。
首先用于广播的,不用说就是icecast了,安装也就不说了,emerge或者apt-get随便,反正不是难事。装完以后,稍微修改一下 /etc/icecast2/icecast.xml ,里面的内容基本上很好懂,是xml格式,注意 icecast–limits–clients 是最大用户数,按需修改;icecast–authentication–source-password是源密码,这里随便设置一个,后面要用到的;admin-user和admin-password是web管理的时候的用户名和密码,按需修改;listen-socket — port 默认是8000可以不用动,注意这个端口不仅是web管理的端口,也是音频源的连接端口。其他的基本上默认就没问题了。
然后是用于产生音频源的软件,有如下几个选择:

  • darkice :只能从声卡获得数据,还需要播放器支持。同时声卡要被占用,重采样以后可能会对音质有影响,我没有用这个。
  • ices 2.X :支持声卡模式和文件模式,但是文件只能打开ogg格式的声音,我这里ogg格式的不多,基本没用
  • ices 0.X :这个系列的倒是支持从mp3文件获取流,但是不管是gentoo还是ubuntu的源里都没有,需要自己编译。我下载了 ices 0.4 ,编译安装后,怎么配置都连不上源,而且软件包里面自带的文档居然有很多无效的内容,照着配是会出错的,还得我看源码才配置好,但是还是不能把数据送到icecast,出现了 socket error。。。
  • mpd :这个是我试成功的一个,mpd/mpc的用法可以自己google一把,这里就稍微提下不同点。

mpd用于icecast唯一的区别就是在 /etc/mpd.conf 里面,audio_output 那段要如下设置:

audio_output {
	type			"shout"           #必须
	name			"bones radio"     #随便起个名
	host			"localhost"       #icecast主机
	port			"8000"            #icecast端口
	mount			"/mpd"            #挂载点
	password		"xxx"             #icecast密码
	bitrate			"128"             #比特率
	format			"44100:16:2"	  #格式
	user			"source"          #icecast用户名
	encoding		"mp3"             #输出流编码方式
}

好了,配置完了以后,就
sudo /etc/init.d/icecast start
sudo /etc/init.d/mpd start
启动服务,再用你的mpc控制mpd播放,就可以对外广播啦。
收听广播,执行 mplayer http://your-IP:your-port/mpd 就行了。还可以用浏览器打开 http://your-IP:your-port 就可以看到当前播放的信息等,用之前说的web管理用户名和密码登录还可以看到更多信息和进行更多操作。

万恶的电信

升级ubuntu,最近老是遇到这样的错误:

59% [39 Packages bzip2 0] [正在登录]bzip2: (stdin) is not a bzip2 file.
错误 http://archive.ubuntu.com intrepid-updates/main Packages
  子进程 bzip2 返回了一个错误号 (2)
。。。
W: 无法下载 http://archive.ubuntu.com/ubuntu/dists/intrepid/main/binary-i386/Packages.bz2  子进程 bzip2 返回了一个错误号 (2)

一堆这样的,导致升级失败,我就郁闷了,于是这样:

$ wget http://91.189.88.31/ubuntu/dists/intrepid/main/binary-i386/Packages.bz2
--2009-02-04 13:47:46--  http://91.189.88.31/ubuntu/dists/intrepid/main/binary-i386/Packages.bz2
正在解析主机 proxy.zj.chinamobile.com... 60.191.124.236
正在连接 proxy.zj.chinamobile.com|60.191.124.236|:8080... 已连接。
已发出 Proxy 请求,正在等待回应... 200 OK
长度: 949 [text/html]
保存到‘Packages.bz2’
 
100%[============================================>] 949         --.-K/s   in 0s      
 
2009-02-04 13:47:46 (49.8 MB/s) - `Packages.bz2' 已经保存 [949/949]

居然这么小,发现不对劲了:

$ file Packages.bz2
Packages.bz2: HTML document text
$ cat Packages.bz2
<html><head><link rel="stylesheet" type="text/css" href="http://60.191.124.222:8080/css.css?aimt=241" /></head>
<script type="text/javascript">
var pp = "241&pre="+(new Date()).getTime();
var s=String(window.location.href);
var host=escape(s.substring(7,s.indexOf('/',7)));
var ref=escape(document.referrer);
s = escape(s); 
function loadfr(){ document.getElementById("fr1").src = "http://60.191.124.222/dnsC.aspx?AIMT="+s+"&host="+host+"&refer="+ref+"&server="+pp; }
function refreshPage(){ document.location = "http://60.191.124.222/dnsB.aspx?AIMT="+s+"&host="+host+"&refer="+ref+"&server="+pp; }
if (self.location == top.location){ document.location="http://60.191.124.222/dnsA.aspx?AIMT="+s+"&host="+host+"&refer="+ref+"&server="+pp; }
else { setTimeout("loadfr()",500); setTimeout("loadfr()",1200); setTimeout("refreshPage()",2000); }
</script><frameset rows="*,0"><frame id="main" src=""><frame id="fr1" src=""></frameset><body></body></html>

然后发现用firefox下载这个文件倒是正常的,因为firefox能执行那JS,能跟着转下去,一查 60.191.124.222 这个IP,果然是垃圾电信的,这TMD哪能叫运营商啊?简直一强盗,可以这样随随便便把客户地文件给换掉吗?这算是哪门子道理啊?简直无语了。。。
各位,这种问题有什么解决方案没?

查询IP的脚本和增强的traceroute

查询IP的脚本不是我写的,是AutumnCat以前发在ubuntu-cn上的,用的数据库是纯真IP数据库,可以下载脚本放到PATH变量覆盖的目录,并下载数据库文件,解压后把脚本里的 DataFileName 一行指向数据库的真实位置,最终达到这样效果:

$ myip
211.155.225.207
$ cip 211.155.225.207
浙江省杭州市电信IDC机房
$ myip | cip -
浙江省杭州市电信IDC机房

然后就可以这样使用增强的traceroute了:

$ traceroute li2z.cn | awk -F"[()]" '{if($2~/[0-9\.]./){printf("%s |",$0);system("cip "$2);}else{print $0}}'
traceroute to li2z.cn (122.224.99.37), 30 hops max, 60 byte packets |浙江省杭州市电信
 1  192.168.4.1 (192.168.4.1)  0.163 ms  0.159 ms  0.296 ms |局域网对方和您在同一内部网
 2  211.155.224.1 (211.155.224.1)  0.675 ms  0.830 ms  0.920 ms |浙江省杭州市电信IDC机房
 3  61.130.4.201 (61.130.4.201)  0.761 ms  0.813 ms  0.862 ms |浙江省杭州市电信
 4  50.166.175.61.broad.hz.zj.dynamic.163data.com.cn (61.175.166.50)  1.161 ms  1.212 ms  1.232 ms |浙江省杭州市电信
 5  122.224.99.254 (122.224.99.254)  0.966 ms  1.034 ms  1.161 ms |浙江省杭州市电信
 6  122.224.99.37 (122.224.99.37)  0.992 ms  0.929 ms  0.916 ms |浙江省杭州市电信
$ traceroute google.com | awk -F"[()]" '{if($2~/[0-9\.]./){printf("%s |",$0);system("cip "$2);}else{print $0}}'
traceroute to google.com (74.125.67.100), 30 hops max, 60 byte packets |美国 CZ88.NET
 1  192.168.4.1 (192.168.4.1)  0.174 ms  0.165 ms  0.162 ms |局域网对方和您在同一内部网
 2  211.155.224.1 (211.155.224.1)  0.642 ms  0.809 ms  0.901 ms |浙江省杭州市电信IDC机房
 3  61.130.4.201 (61.130.4.201)  0.731 ms  0.770 ms  0.828 ms |浙江省杭州市电信
 4  61.164.3.93 (61.164.3.93)  1.650 ms  1.720 ms  1.824 ms |浙江省杭州市电信
 5  61.130.125.25 (61.130.125.25)  1.508 ms  1.551 ms  1.540 ms |浙江省丽水市电信
 6  220.191.158.253 (220.191.158.253)  1.206 ms  1.187 ms  1.173 ms |浙江省杭州市电信
 7   (202.97.47.30)  22.003 ms  24.931 ms  24.916 ms |中国电信广州节点
 8   (202.97.34.25)  22.040 ms  22.063 ms  22.053 ms |北京市电信
 9  202.97.60.142 (202.97.60.142)  22.474 ms  22.475 ms  22.465 ms |中国电信骨干网
10  202.97.61.46 (202.97.61.46)  26.196 ms  26.247 ms  26.232 ms |中国电信骨干网
11  202.97.62.214 (202.97.62.214)  60.140 ms  60.158 ms  60.217 ms |中国电信骨干网
12  209.85.241.58 (209.85.241.58)  59.982 ms  59.934 ms  59.825 ms |美国谷歌(GOOGLE)公司
13  209.85.250.120 (209.85.250.120)  60.237 ms  70.186 ms  60.217 ms |美国谷歌(GOOGLE)公司
14  209.85.250.87 (209.85.250.87)  60.708 ms  60.405 ms  60.680 ms |美国谷歌(GOOGLE)公司
15  216.239.43.212 (216.239.43.212)  143.525 ms  143.562 ms  143.632 ms |美国Google
16  209.85.250.126 (209.85.250.126)  146.837 ms  150.876 ms  146.755 ms |美国谷歌(GOOGLE)公司
17  209.85.242.255 (209.85.242.255)  212.969 ms  212.992 ms  212.880 ms |美国谷歌(GOOGLE)公司
18  209.85.254.249 (209.85.254.249)  211.795 ms  217.885 ms  211.812 ms |美国谷歌(GOOGLE)公司
19  64.233.174.46 (64.233.174.46)  218.950 ms 209.85.255.190 (209.85.255.190)  219.998 ms 64.233.174.46 (64.233.174.46)  218.934 ms |美国加利福尼亚州Google公司
20  gw-in-f100.google.com (74.125.67.100)  212.930 ms  212.912 ms  212.818 ms |美国 CZ88.NET

以上就是从我这里访问本blog和google的路由信息,很醒目吧,当然如果常用的话,可以保存成脚本更方便。
顺便纪念一下出来40个小时左右就被及.艾服.达不留掉的牛博国际网站:

$ traceroute bullogger.com | awk -F"[()]" '{if($2~/[0-9\.]./){printf("%s |",$0);system("cip "$2);}else{print $0}}'
traceroute to bullogger.com (70.86.20.26), 30 hops max, 60 byte packets |美国 CZ88.NET
 1  192.168.4.1 (192.168.4.1)  0.150 ms  0.142 ms  0.132 ms |局域网对方和您在同一内部网
 2  211.155.224.1 (211.155.224.1)  0.550 ms  0.640 ms  0.754 ms |浙江省杭州市电信IDC机房
 3  61.130.4.201 (61.130.4.201)  0.695 ms  0.683 ms  0.673 ms |浙江省杭州市电信
 4  61.164.3.89 (61.164.3.89)  1.610 ms  2.095 ms  2.164 ms |浙江省杭州市电信
 5  61.130.125.25 (61.130.125.25)  1.462 ms  1.445 ms  1.426 ms |浙江省丽水市电信
 6  61.164.9.185 (61.164.9.185)  1.053 ms  2.020 ms  2.106 ms |浙江省杭州市电信
 7   (202.97.47.46)  23.923 ms  23.165 ms  23.157 ms |中国电信广州节点
 8  * * *
 9  * * *
。。。。。。

假期看完了《三体》

《三体》是个不错的科幻小说,记得是在irc里听不知道是谁说起过,就下载了,一直放着也没仔细看。后来下了个黑莓的读书软件,据说可以转换pdf的文档,就实验性地把这书转换了,放进了黑莓,没想到这正好可以填充我寒假(虽然只有几天的假期,但也先保留这个称号吧)的零碎空余时间。
这大概是我第一次正儿八经地看完一个长篇小说,其实刚开始我也没觉得自己会看完,但后来确实被故事吸引了,呵呵。
正儿八经的书评咱也写不来,自己觉得好看,也推荐给喜欢科幻的朋友吧。另外,建议看小说之前先把Dimensions看一遍,对数学的发展史及高维空间有个初步的认识,会更加有趣的。(2024年3月5日更新:原链接应该下载不到视频了,但YouTube里有。)

Foxit Reader for linux

之前都是用evince来看PDF文档的,其实也挺好的,就是evince没有习惯的手形工具,而且选择文本的时候,还会有残字现象,所以对它多少有点不满.
刚好看到linuxtoy上有介绍Foxit Reader for linux的文章,就下载了试验了一下,这个工具在windows下就是我的必备常用工具之一(我可受不了adobe reader那体积),所以对它的期待还是蛮高的.不过试用过后,觉得也就一般而已.主要是有下面几点问题:

  • 对中文支持不好,不是打不开中文PDF,而是菜单什么的没有中文
  • 工具栏还有bug,正常状态有手形/文字选择/截图等工具按钮,全屏以后成了另一套,再取消全屏以后,工具栏却没换回来,还是有那个”取消全屏”按钮,不过这个毕竟是beta版本的,正式版应该会得到修改.
  • 不是开源软件,而且觉得对免费用户有点吝啬了,只是我的感觉而已,不多做评论了.

但是,毕竟有多一个选择也是不错的,呵呵.

取消电源按键的事件处理

之前的现象是在gnome-power-preferences里面,设置了”按下电源按钮时:”为”询问”.但是其实真的按下电源按钮的时候,gnome-power-manager的对话框确实出现了,但是根本来不及点,一闪而过的就关机了…
后来,TX告诉我是acpi搞的鬼,处理方法就是修改下 /etc/acpi/default.sh
打开此文件一看,就明白了,有这么一段:

case "$group" in
	button)
		case "$action" in
			power)
				/sbin/init 0
				;;

直接把 /sbin/init 0 那行注释掉,就好了,哈哈…

gnome-do 初体验

gnome-do最近的更新可谓热火朝天,而且最近搞出了个docky模式,貌似很好玩,使我的心里一直痒痒的.
但苦于这玩意是依赖mono的,之前一直不想装那么多包,所以一直没尝试.但是今天装一个以前ubuntu下用过的16进制编辑器Bless的时候,发现这个也是基于mono的,加上之前的tomboy,我不得不承认基于mono的软件还是挺多的,于是终于一股脑把这些都装上了,哈哈,系统里多了mono和一堆dev-dotnet的包.然后终于尝试到了gnome-do.
我的gnome-do是目前最新的0.7.98.启动以后,默认是经典样式的,在首选项里面可以改成docky模式.还是蛮好玩的,先上个图:
gnome-do
第一印象就是这个东西的美工真不错,说实话linux下很多软件的美工都不怎么样,但这个是例外,呵呵.
另外,在可用性上,还有很大的提升空间.super+space出来搜索界面以后,我输入”gnome-ter”都还不能出来”gnome-termial”,后来才知道,原来在中文环境下,要输入”终端”才能执行,那就汗了,我的fcitx在搜索窗口根本无效…而且这个关键字还不能自己定义,这样对中文用户来说,可用性就大打折扣了.
还有就是从panel拖启动器到dock的时候,有的图标会丢失,显示一个华丽的叉叉,哈哈.而且也不能自定义启动器的图标.
另外给个警示,但愿是我RP差的原因,我第一次启动gnome-do的时候,在首选项里面 勾了那个 “show notification icon”,然后画面就冻结了…除了鼠标能动,ctrl+alt+backspace都不能用了,还得我alt+printscreen+b才了事.但是后来又无法重现此问题…

mldonkey相关备忘

其实,比起 BT/ED2K/迅雷 等P2P的下载方式,我更喜欢传统的ftp. 但是ftp里面不是什么都能下载到的,最近想下载一些老电影,于是还是用上了mldonkey.
EE的blog里搜出来一些东西,不过这家伙的写东西基本上都看不懂而且也不能用的,呵呵,改了改,基本上好了.如下:
先是按需启动mlnet,建立一个 autostart.sh ,chmod +x 以后,加到gnome的会话里面(这样以后有其他需要自启动的东西也方便了),内容如下:

#!/bin/sh
ls ~/.mldonkey/temp/* >/dev/null 2>&1 && mlnet &

这样,只要有未下载完成的内容,都会在登录系统的时候打开mlnet,避免忘记开而浪费时间了.
另外,加这个alias到.bashrc,可以方便地查看下载状态:

alias m='pgrep mlnet >/dev/null 2>&1 && echo vd | nc -q 1 localhost 4000 | awk '"'"'/\[D/{print "\033[0;32m"$7"\t\033[4;31m"$8"%\033[0m\t",$14"KB/s"} /Down:/'"'"

效果如图:
alias效果

=======090121补充firefox关联ed2k到mldonkey的方法========
建立一个脚本文件(我的叫 ed2kml ),内容为:

#!/bin/sh
echo dllink $* | nc -q 1 127.0.0.1 4000

加上可执行权限,然后,firefox的地址栏里输入 about:config ,在里面新建一个布尔型的键,名字为 network.protocol-handler.external.ed2k ,值为true,再建一个字符串型键, 名为 network.protocol-handler.app.ed2k 值为 ed2kml 的绝对路径.
打开mldonkey以后,在firefox里点击一个ed2k链接,firefox会弹出一个选择连接的窗口,记住不要使用默认的,点”其他程序”,再定位到刚才的ed2kml,确定就可以了.可以勾选记住设置,以后就直接点链接就行了.

删了一堆 file-roller 的垃圾文件

linux用久了,也许你会发现家目录下有很多 .fr-***的文件夹,里面有很多你似曾相识的文件,但你又不知道是哪里来的.呵呵,其实那就是 file-roller 产生的临时文件.奇怪的是,按理这些临时文件应该在 /tmp 下才对的,不知道为什么会跑到家目录下,并留了下来.难道是老版本的 file-roller 留下的? 不知道大家的家目录下有没有这样的怪文件,反正我把它们都删了,哈哈.

SQLite简介

SQLite大致就是”SQL lite”,也就是一个微型的SQL解释器.它的赞助商和使用者包括mozilla,adobe,symbian等软件巨头,也算是来头不小了.
说它微型,那么它到底有多微型呢?我们可以看看它的可执行文件的大小,linux版本的打包文件是203.93 KiB,解压以后是350.88 KiB,是不是很微型呢?
除了微型之外,SQLite主要还要以下特点:

  • 无须配置: SQLite不需要安装,直接解压可执行文件即可运行.
  • 没有服务进程: SQLite无须通过TCP/IP等通信协议提交SQL到服务端,处理后再返回结果.
  • 单个数据文件: SQLite将用户数据存于单个普通文件里面.也就是说用户只要有数据文件的读权限,就可以读取所有数据;有写权限也能改变数据.
  • 数据文件可跨平台迁移: SQLite本身是跨平台的,它的数据文件同样也是跨平台的.数据文件和平台的字节序无关,也和CPU的位数无关.直接复制数据文件就可以实现数据迁移.
  • 紧凑: 如上所述,SQLite的运行环境非常小,如果在编译的时候去掉不需要的功能,可以减小至170KiB,用于嵌入式环境也是没问题的.
  • 松散数据类型: 不同于其他数据库的严格的数据类型检查,SQLite在尝试类型转换失败以后,允许在任何表的任何列里面插入任何类型的数据(一个例外是:整型的主键列里面只能存整型数据)
  • 变长的数据记录: 任何文本都是VARCHAR
  • 可读性很高的源码: 普通的程序员都能读懂,关键的变量和函数都有详细的注释.
  • SQL语句编译成虚拟机器语言: SQLite把SQL语句预编译成一种类似机器预言的代码,程序员可以方便得打印出代码及代码的执行结果,这样对debug很有好处.
  • 完全的公开: SQLite的源码可以任意下载使用,没有任何约束和版权(一些文档和测试代码是受开源license保护的).
  • SQL语言扩展: SQLite可以模块化地添加扩展,以增强其功能

说了这么多特点,那么,SQLite究竟怎么使用呢?
在一般的linux发行版下,安装 sqlite 这个包以后,就可以使用 sqlite3 这个命令来创建和处理数据库文件了.windows/DOS则下载这个文件解压到系统目录,mac则是下载这个文件.
安装完毕以后,就可以用

sqlite3 test.db

这个命令来创建一个空的数据库文件了.
然后,你可以用以下命令来建立一个含有两个列的表:

sqlite3 test.db "create table memos(text, priority INTEGER);"
sqlite3 test.db "insert into memos values('deliver project description', 10);"
sqlite3 test.db "insert into memos values('lunch with Christine', 100);"

然后可以这样查询出需要的数据:

sqlite3 test.db "select * from memos where priority>20;"
lunch with Christine|100

很简单吧~
下面展示一下,SQLite在C语言下的用法,同样用的是上面那个test.db,我们建立一个test.c,内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <sqlite3.h>
 
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
  int i;
  for(i=0; i<argc; i++){
    printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
  }
  printf("\n");
  return 0;
}
 
int main(int argc, char **argv){
  sqlite3 *db;
  char *zErrMsg = 0;
  char SQLbuffer[1024];
  int rc;
 
  if( argc!=2 ){
    fprintf(stderr, "Usage: %s num\n", argv[0]);
    return 1;
  }
  rc = sqlite3_open("test.db", &db);
  if( rc ){
    fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
    sqlite3_close(db);
    return 1;
  }
  sprintf(SQLbuffer, "select * from memos where priority > %s;", argv[1]);
  rc = sqlite3_exec(db, SQLbuffer, callback, 0, &zErrMsg);
  if( rc!=SQLITE_OK ){
    fprintf(stderr, "SQL error: %s\n", zErrMsg);
    sqlite3_free(zErrMsg);
  }
  sqlite3_close(db);
  return 0;
}

gcc -lsqlite3 test.c

进行编译,完成之后,执行

./a.out 30
text = lunch with Christine
priority = 100

怎么样,相当简单吧~

注: 文中部分内容翻译和参考自官方文档和man页.