访问人数统计

今天想看看lilac的访问统计,数据在http://lilacbbs.com/bbsstat/。
结果发现所有的图都是一样的,ft

原来没有开启dayuserlog程序,这个程序每小时运行10次左右,然后由alluserlog统计平均人数,最后由脚本调用gnuplot画出图来。

现在启动,希望会有变化的。

————————————–
现在貌似正常了,嗯 -2008-02-29

日志啊日志

开发和调试有时候真的是一件很灵异的事情,所以如果你胆小就不要做软件了。

前两天deem向我要一些lilac的用户日志,当时我看了一下,发现用户日志只有去年7月份的……

用户日志只有去年7月份的……
用户日志只有去年7月份的……
用户日志只有去年7月份的……

更诡异的是boardusage日志都没有问题,这就说明bbslogd和bbsd运行都没有问题,而且日志文件权限也没错,ft啊。

在bbsd跟踪了一下,日志信息是通过共享内存的message queue实现的,直到最后一步msd_send都没有问题。但是此时ipcs的msg queue中始终为0,灵异啊!

今天deem又问了一下,讲了他的一些想法,不过我觉得都不可能。于是下决心用gdb attach那个bbslogd。

从msg recv到写到msg队列中都没有问题,剩下的就是定时的flush了。迷糊了,detach一下,回头发现所有的日志文件都出现了……

所有的日志文件都出现了!!
所有的日志文件都出现了!!
所有的日志文件都出现了!!

ft
———————–ft的分界线——————
为什么嘞?

想了一下,可能是这样的,其实日志rotate需要给bbslogd发一个USR1的信号,这个需要手动在crontab设置一下。一直没有发信号,所以一直没有rotate。

但是问题为什么文件会小时呢?这个我就不知道了……

bbs web启动问题

安装好系统之后,启动apache,此时使用浏览器访问,但是firefox是提示下载一个空的文件,而konqueror老是说broken connection,我抓包之后感觉是客户端向服务器发送完请求,服务器段由于内部处理失败,结果整个apache的子进程就退出了,所以这个连接就断了。于是出现了上述现象。
我觉得原因应该是apache的子进程在运行php扩展模块的时候,出现了segment fault。
我遇到的更具体原因有:
1 apache的属主不为bbs,此时运行bbs的程序,内部因为权限不对而发生异常。
2 客户端调用功能的时候没有初始化,此时共享内存没有被解析,如果访问共享内存,则会发生异常。

kbs系统phplib开发简介

写这篇文章的原因是向lilac dev组介绍一下如何入门 lilac bbs web 的开发,由于lilac bbs 是基于kbs系统的,所以我主要讲的也是基于kbs系统的web开发。

kbs系统的web主要分为三个部分:php页面开发,php扩展和底层的c语言函数库。

php页面开发主要涉及的就是我们常用的php常规开发,其实就是一个php的解释器解释运行php页面,再加上css、js和html那些东西。

php扩展是使用zend的特性,它可以将c语言编写的代码编译成二进制文件,然后将这个二进制文件加载为一个php的库文件(.so格式),由apache启动的时候检查注册,然后在上层的php页面中被动态载入、调用和释放。

至于底层的C语言函数库,其实就是用C语言写的函数的集合,可以供php扩展中的C语言代码调用的。仅此而已。

我打算用自底向上的方法讲,就举一个最简单的实例吧:用户登录。

首先,我们先看一个用C语言编写的验证用户信息的函数checkpasswd2,这个函数在libBBS/pass.c中:

71 int checkpasswd2(const char *passwd, const struct userec *user)
72 {
73 #ifdef CONV_PASS
74 if (user->passwd[0]) {
75 return checkpasswd(user->passwd, passwd);
76 } else
77 #endif
78 {
79 unsigned char md5passwd[MD5_DIGEST_LENGTH];
80
81 igenpass(passwd, user->userid, md5passwd);
82 /*
83 if (memcmp(md5passwd,user->md5passwd,MD5_DIGEST_LENGTH)) {
84 unsigned char w_md5passwd[MD5_DIGEST_LENGTH];
85 w_igenpass(passwd,user->userid,w_md5passwd);
86 if (memcmp(w_md5passwd,user->md5passwd,MD5_DIGEST_LENGTH)) return 0;
87 memcpy(user->md5passwd,md5passwd,MD5_DIGEST_LENGTH);
88 bbslog("5system","Convert %s password.",user->userid);
89 }
90 return 1;
91 */
92 return !(memcmp(md5passwd, user->md5passwd, MD5_DIGEST_LENGTH));
93 }
94 }

看起来应该很简单,比较明了。这就是一个最基本的kbs函数,几乎没有什么依赖项。这个函数可以被ssh、telnet和www这些上层的应用调用,但是底层就是这一个函数。

做完验证函数之后,我们需要编写一个php扩展。要使php页面能够用到这个checkpasswd2函数,那么我们需要有一个php扩展,其中有一个函数bbs_checkpasswd,这个函数其实是一个适配器,连接php页面的调用和checkpasswd2函数。这个函数在bbs2www/phplib/phpbbs.user.c:

PHP_FUNCTION(bbs_checkpasswd)
114 {
115 char *s;
116 int s_len;
117 char *pw;
118 int pw_len;
119 long ret;
120 int unum = 0;
121 long ismd5 = 0;
122 struct userec *user;
123 int ac = ZEND_NUM_ARGS();
124
125 if (ac != 2 || zend_parse_parameters(2 TSRMLS_CC, "ss", &s, &s_len, &pw, &pw_len) != SUCCESS) {
126 if (ac!= 3 || zend_parse_parameters(3 TSRMLS_CC, "ssl", &s, &s_len, &pw, &pw_len, &ismd5) != SUCCESS) {
127 WRONG_PARAM_COUNT;
128 }
129 }
130 if (s_len > IDLEN)
131 s[IDLEN] = 0;
132 if (pw_len > PASSLEN)
133 pw[PASSLEN] = 0;
134 if (pw[0] == '')
135 ret = 1;
136 else if ((s[0] != 0) && !(unum = getuser(s, &user)))
137 ret = 2;
138 else {
139 if (s[0] == 0)
140 user = getCurrentUser();
141 if (user) {
142 if (ismd5) {
143 ismd5 = !(memcmp(pw, user->md5passwd, MD5PASSLEN));
144 } else {
145 ismd5 = checkpasswd2(pw, user);
146 }
147 if (ismd5) {
148 ret = 0;
149 if (s[0] != 0)
150 setcurrentuser(user, unum);
151 } else {
152 ret = 1;
153 logattempt(user->userid, getSession()->fromhost, "www");
154 }
155 } else {
156 ret = 1;
157 }
158 }
159 RETURN_LONG(ret);
160 }

可以看出,这个函数与php密切相关,php zend会解析上层php页面调用变量,然后处理这些变量,而我们要做的,就是检查这些变量的合法性,然后将其传到checkpasswd2即可。

用户登陆的时候,首先会使用js检查输入信息合法性,然后转到bbslogin.php这个页面。我们可以发现有这么一句:

2 require("www2-funcs.php");

也就是说这个页面需要加载www2-funcs.php,那么我们再看看www2-funcs.php,发现


11 if (BUILD_PHP_EXTENSION==0)
12 @dl("$topdir/../libexec/bbs/libphpbbslib.so");

其实就是这句话,php使用了dl调用了我们编写的php扩展libphpbbslib.so,这个类似于C#中的dllimport调用COM一样。

好,我们回到bbslogin.php,加载之后,即可使用libphpbbslib.so的函数了。

24 if (($id!="guest")&&bbs_checkpasswd($id,$passwd)!=0) error_alert("用户密码错误,请重新登录!");

OK,就是这样的,php页面调用bbs_checkpasswd,然后得到返回值,就可以判断用户密码了。

开放注册和guest

紫丁香终于开放了,现在估计lilacbbs的page rank会大幅度上升。记住哦,http://lilacbbs.com

今天和lanslot去看了看代理服务器,都是学校做的恶心事,还让我们来买单,sigh。今天网通的代理搞定了,基本上用网通的朋友们是可以较快的访问了,电信的如果不出意外的话,明天就能搞定。再记住哦
网通的代理: http://proxy.lilacbbs.com
电信的代理: http://tele.lilacbbs.com

改路由

这几天关于学校对紫丁香社区改路由的说法越演越烈,看来不是空穴来风。现在校园网里面的用户上lilac都很卡,有人说tracert的结果发现是到北京绕了一圈回来的。

虽然不知道具体的情况,考虑到很多人也在看着这里,我也不好多说,lanslot 说开发之后会写出来,我想大家到时候再看就心里有数了。

看着网友的声讨,想起了一句话:水至清则无鱼,人至贱则无敌。