[转载]
说起BBS,当然有很多的fan了.但要说起搞BBS程序的,可是不多. 本人一向对编程情有独衷,从当年的MUD巫巫到今天的BBS巫巫,对我的编程 生涯有了很大的帮助. 由于目前国内关于BBS程序设计的文章太少,几乎是没有,这对于想学BBS程 序设计,而又没有教程的人很是烦恼.我当年就是这样,不得不自己一点一点的 看程序,来了解BBS的框架结构.(唉,很久同上网,五笔都生的很了). 也不多说了,现在开始吧. BBS源程序是用C语言写的,如果你懂C++那就更好了. 初学BBS编程,您要了解BBS的源程序在与BBS系统目录的同一级bbsadm目录 内(一般是这样,当然也可以改噻). 本教学就以一般的安装目录来讲解: BBS系统目录--> /home/bbs BBS源程序目录--> /home/bbsadm 在bbsadm目录下,一般有个你解开BBS安装包的目录bbs_src,一般只有这个 目录.在bbs_src目录下有很多的东东了,这些都是做什么用的,你看BBS的安装 内(一般是这样,当然也可以改噻). 管理就会知道了.我不再多说.我们编程用到的只有: /home/bbsadm/bbs_src/include --> BBS源程序的库文件目录 /home/bbsadm/bbs_src/src --> BBS源程序目录 有这两个目录就够了. /*记住,我们以后所说的include目录和src目录就是指上面的*/ 从现在开始,我一一讲解... (* 多说一句,本人由于水平有限,所以写出的东东也不一定很正确,请大家 发现错误及时指正 *) 我先说说include-->BBS库文件目录 在FB7.0的版本里,include目录下一般有: bbs.h chat.h config.h edit.h permissions.h struch.h vote.h bbsgopher.h modes.h screen.h tmachine.h 对于初学,不需要你们全部了解.只要求你们懂几个常用的就可以了.下面我 把几个常用到的讲解一下.其它的我在后面的章节再介绍. config.h --> 定义BBS各种设置,如:最大上站人数,缺省的BBS目录,BBS程 序使用的最长的字符串长度,最长发呆时间,最长的密码位数 以及各种标识等等... chat.h --> 是关于聊天室的一些设置.如:各种聊天室的名称,聊天室使用 代号的最大长度,聊天室最多进入人数,最多可以开几个房间, 代号的最大长度,聊天室最多进入人数,最多可以开几个房间, 以及程序中所要使用到的全局定义. config.h --> 里面定义了BBS的站名,ID,IP地址,域名,BBS端口号,还有普通 用户的最长发呆时间,高级用户的最长发呆时间,最多注册人数 等等.. edit.h --> 里面的内容很少.一些是定义MARK,都是程序中用到的了解就行. 还有一个结构textline,这是用来保留您发表文章时所写的各行 字符(说明:当你正在写文章时,其时你所写的没有保留到文件中, 而是暂时放入缓冲区内,等你正式发表后,才保存到文件中) permissions.h --> 学过英语,您就知道这里是设置权限的,当然这里也就是 您最应该了解的.(*记住,您要仔细的看这里的设置,以后 的编程要经常的用到*) BBS的权限定义,是用的数据标识(1,2,4),我详细讲一下: 最前面你可以看到很多的数字如: #define PERM_BASIC 000001 #define PERM_CHAT 000002 #define PERM_POST 000004 ........ 如果我(loveyou)只有基本权限那它的权限记录就是: loveyou.userlevel = 000001 (*其实这里只写1就行,前面 加0也是为了容易看!写程序 要养成良好的习惯*) (* 对了,再说明一下,基本权限就是进站的权限,如没有就进不了站 *) (* 对了,再说明一下,基本权限就是进站的权限,如没有就进不了站 *) 如果我有基本权限和聊天权限,那就: loveyou.userlevel = 000003 (* 这里是000001+000002 *) 这样定义,那我就有了这两样的权限. 以下同,那是这样, 权限标识有: 1,2,4,10,20,40,100,200,400.... 设计者还为开发BBS留了些没有用到的权限: SPECIAL1,SPECIAL2... 如果您想给BBS再加些权限功能,那就要先在这里设置,如我要加个聊天 室的总管,那我就把PERM_SPECIAL1改成PERM_CHATGOD,然后我还要在后 面您要加的权限名就是第一步,加上后还要在后面设定它的中文名: 后面有这个设置的地方,都是汉字你一下就能找到,然后在SPECIAL1所 在的那一行把"特殊权限 1"改成"聊天室总管"就可以了. 这样,在BBS程序中您就可以使用PERM_CHATGOD权限了,如: 有这个权限的人可以在聊天室内踢人,那你就在chat.c里踢人函数加 上判断语句 HAS_PERM(PERM_CHATGOD) 就可以了,如果你不知道在哪 里加,那就慢慢学,我以后在讲到chat.c文件时会说明的. 上面讲了权限的定义,在这里还有就是用户参数的定义.基本意思同上. 只不过您要填加一参数,可不要忘记改一下: #define NUMDEFINES 26 这一行,如果你加了一个参数,那就把26改为27.依此类推. struct.h --> 这个库文件也很重要,所以您也要好好看一下,我也在这里多讲解一些. 这里首先定义的是userec结构.这个结构是为每个用户保存各种记录用 这里首先定义的是userec结构.这个结构是为每个用户保存各种记录用 的.如,用户的代号,上次联线地址,上次进站时间,发表文章数,上站次 数等,还有我前面提到的权限userlevel记录. 下在还有一个结构,就是user_info也是用来记录用户信息的.它们记录 的内容不同,而且user_info是在UTMP文件中使用的(* 如果您不懂,那 就不管它了,反正您主要了解userec结构就可以了 *) 在程序设计时,如果您要取某一用户的权限,那就这样: loveyou.userlevel 取上站次数就: loveyou.numlogins 等等等....您要用的时间可以到struct.h文件里查找,不用全记住. 这个库文件里还定义了文件的结构树等一些东东,不用管了,等用到时 再来看吧.:PP modes.h --> 这个也是很重要的. 里面定义的是用户的各种状态,只有在这里定义了状态,您才能在程序 中使用.如果您想加一个状态,如下围棋,那就在后面依次加上: #define GO 56 这个56是依最后面一个数再依次加. 定义后您就可以使用这个了,如在程序用户开始下围棋时写上: modify_user_mode( GO ); 就可以了,您要是问,这是定义了哪位用户的状态是GO呀? BBS程序一般指当前用户(currentuser) (* 说到这里要说一句,这个currentuser您要一定一定一定要记住, 定义后您就可以使用这个了,如在程序用户开始下围棋时写上: 它在程序的任何角落里都可以使用,它是一个全局常量,指代当前 用户.如您要得到当前用户的ID,就这样:currentuser.userid 它得到的就是当前用户的ID *) 还有一些其它的,也不是没用,而是不常用,一般不需要做改到,只是在看程序时有 时不懂就来看看.先别花精力来看了. 当您来到src目录里,您的头一定大了一倍.呵呵,别怕,这里有很多不用的东东. 首先是*.o文件,它是编译BBS时产生的输入文件(* 注意,编译BBS时并不是对于 每一个文件都产生一个可执行文件 *) 如FB7.0是产生bbsd的可执行文件,它是 BBS驱动程式.这里也不多说了.反正*.o的东东您不要管. 不说没有用的了,就说有用的吧,告诉你*.c的文件都是BBS的源程序.它们是有用 的,这么说直接了吧.:PP 才开始学,您只要看*.C文件就行了. 下面,我开始一一讲.(* 工程确实很大,唉,慢慢来吧,我尽量用易懂的方法讲 *) 用户一开始登陆,首先系统调用的是bbsd.c程序,里面一般您不要改,除非您对 操作系统很熟,对BBS程序很熟.它能被用户看到的只有进站画面前面的一行: 当前系统负荷 .....(我记不清了:PP) 当前系统负荷 .....(我记不清了:PP) 一一讲实在太多,我拿常用到的讲讲吧,那些不常用的,以后我有时间再说. ====================================================================== 说这些之前,我先告诉大家一些BBS编程中常常用到的函数. ====================================================================== currentuser 这是一个全局的常量.它是一个userec结构.你在编程中可以随时的使用,而不 需要定义.它个各种属性您可以在include目录的struct.h文件里查到.我在这里给 大家贴出来讲一下: struct userec { char userid[IDLEN+2]; //用户代号 // char fill[30]; time_t firstlogin; //用户第一次上站的时间 char lasthost[16]; //用户最后一次上站的地址 unsigned int numlogins; //上次次数 unsigned int numposts; //发表文章数 char flags[2]; //好象定义标识的(我也不太清楚) char passwd[PASSLEN]; //用户的密码 char username[NAMELEN]; //用户的妮称 char ident[NAMELEN]; //在main.c中设置的.不用管它. char termtype[STRLEN]; //用户的终端类型 char termtype[STRLEN]; //用户的终端类型 unsigned userlevel; //用户的权限 time_t lastlogin; //用户最后一次上站时间 time_t stay; //用户在站的总共停留的时间 char realname[NAMELEN]; //真实姓名 char address[STRLEN]; //真实住址 char email[STRLEN]; //真实E-mail int signature; //目前使用的签名档 unsigned int userdefine; //用户的参数设置 time_t notedate; //用户上次看留言板的时间 int noteline; //看过留言板的行数 int notemode; //用户看留言板的模式(全看,只看没 看过的,都不看) // int unuse1;/* no use*/ //为以后填加更多的属性而设置的,没用 // int unuse3;/* no use*/ }; 这些属性的用法前面我已经说过,我再说一次: 如果你想得到当前用户的上站次数就是currentuser.numlogins 它的返回值就是. 你不用全都记住,用到时再来查,慢慢的你就会记住了. =========================================================================== =========================================================================== HAS_PERM() 这个函数也是常用的,是判断当前用户是否具有某个权限. 如当某用户在文章前按下d时,系统要判断这个用户是否具有板主的 权限,如果没有,就马上返回: if ( !HAS_PERM(PERM_BOARDER) ) return; PERM_BOARDER是在权限设置里设置好了的,你可以到include目录下的 permissions.h文件里查找。下面我例出来讲解一下: "基本权力", /* PERM_BASIC */ "进入聊天室", /* PERM_CHAT */ "呼叫他人聊天", /* PERM_PAGE */ "发表文章", /* PERM_POST */ "使用者资料正确", /* PERM_LOGINOK */ "禁止发表文章", /* PERM_DENYPOST */ "隐身术", /* PERM_CLOAK */ "看穿隐身术", /* PERM_SEECLOAK */ "帐号永久保留", /* PERM_XEMPT */ "编辑进站画面", /* PERM_WELCOME */ "板主", /* PERM_BOARDS */ "帐号管理员", /* PERM_ACCOUNTS */ "本站智囊团", /* PERM_CHATCLOAK */ "投票管理员", /* PERM_OVOTE */ "系统维护管理员", /* PERM_SYSOP */ "系统维护管理员", /* PERM_SYSOP */ "Read/Post 限制", /* PERM_POSTMASK */ "精华区总管", /* PERM_ANNOUNCE*/ "讨论区总管", /* PERM_OBOARDS*/ "活动看版总管", /* PERM_ACBOARD*/ "不能 ZAP(讨论区专用)", /* PERM_NOZAP*/ "强制呼叫", /* PERM_FORCEPAGE*/ "延长发呆时间", /* PERM_EXT_IDLE*/ "特殊权限 1", /* PERM_SPECIAL1*/ ..... 以下还有几个特殊权限是没用的。 ===================================================================== DEFINE() 这个函数是判断用户个人参数里是否设置为YES 如在发信息的程序里要判断这个用户是否收到信息时发出声音: if ( DEFINE(DEF_SOUNDMSG) ) beep(1); 这些参数在permissions.h里定义了,我例出如下: "呼叫器关闭时可让好友呼叫", /* DEF_FRIENDCALL */ "接受所有人的讯息", /* DEF_ALLMSG */ "接受好友的讯息", /* DEF_FRIENDMSG */ "收到讯息发出声音", /* DEF_SOUNDMSG */ "收到讯息发出声音", /* DEF_SOUNDMSG */ "使用彩色", /* DEF_COLOR */ "显示活动看版", /* DEF_ACBOARD */ "显示选单的讯息栏", /* DEF_ENDLINE */ "编辑时显示状态栏", /* DEF_EDITMSG */ "讯息栏采用一般/精简模式", /* DEF_NOTMSGFRIEND */ "选单采用一般/精简模式", /* DEF_NORMALSCR */ "分类讨论区以 New 显示", /* DEF_NEWPOST */ "阅读文章是否使用绕卷选择", /* DEF_CIRCLE */ "阅读文章游标停于第一篇未读", /* DEF_FIRSTNEW */ "进站时显示好友名单", /* DEF_LOGFRIEND */ "进站时显示备忘录", /* DEF_INNOTE */ "离站时显示备忘录", /* DEF_OUTNOTE */ "离站时询问寄回所有讯息", /* DEF_MAILMSG */ "使用自己的离站画面", /* DEF_LOGOUT */ "我是这个组织的成员", /* DEF_SEEWELC1 */ "好友上站通知", /* DEF_LOGINFROM */ "观看留言版", /* DEF_NOTEPAD*/ "不要送出上站通知给好友", /* DEF_NOLOGINSEND */ "主题式看版", /* DEF_THESIS */ "收到讯息等候回应或清除", /* DEF_MSGGETKEY */ "汉字整字删除", /* DEF_DELDBLCHAR */ "使用GB码阅读" /* DEF_USEGB */ "使用GB码阅读" /* DEF_USEGB */ ==================================================================== move(x,y) 将当前光标移到屏幕(x,y)点处。 ==================================================================== clear() 与 clrtoeol() 两上函数都为清屏。 是有区别的,clear()是指清除当前屏幕所有,也就是全清。 clrtoeol()是清除当前行,这个函数你只要记住一般常与move()联用。 如你想在用户屏幕第一行第一例显示一行信息: move(1,1); clrtoeol(); prints("看到这行了嘛?"); 这个clrtoeol()函数的目的就是把用户的这一行以前的字符清除,然后 再把"看到这..."这串字符显示上去. 所以,当你要清屏时就用clear(),当你要清除当前行时就用clrtoeol() ==================================================================== prints() 在当前光标处显示某字符串。 如: prints("HI,你好!"); 也可以带变量: prints("hi %s,welcome!",currentuser.userid); 假如当前用户是我,则对我显示: hi loveyou,welcome! 假如当前用户是我,则对我显示: hi loveyou,welcome! 根据这个,您可以灵活运用之! =================================================================== printf() 把一些字符串保存到某字符串变量里。 如要把当前用户的BBSE-mail保存到usermail字符串内: char usermail[30]; printf(&usermail,"%s.bbs@%s",currentuser.userid,MY_BBS_DOMAIN); 则如果当前用户是我,那usermail字符串变量里保存的是: loveyou.bbs@bbs.swjtu.edu.cn 那个MY_BBS_DOMAIN是在include目录下config.h文件内定义的全局常量,还 有很多有用的,你可以去看看。 说到编程的思维方法,可不是一天两天能学好的。首先你要保证 良好的编程方法,在应该空格的地方空格,在应该断行的地方断行。 如果你只想学BBS编程,而对其它编程不感兴趣那就应该看看本文 以下内容了。 BBS编程其实一般不需要对它的程序很了解,因为我们一般对 BBS程序的改动不大,也就是在它的基础上进行的改动。你应该多 看看BBS的源程序,尽量记下常常用到的函数,对于不常用的不记 也罢,用到时,再到程序中用到这个函数的地方去看看源程序是怎么 调用这个函数的。 假如您要用prints()函数,但又不知道它的用法。那您可以这样 查找: grep 'prints' * |more 它将查找*.C文件里用到prints的 地方,然后你就 会 找到用到这个函数的某个文件,用VE编辑器编辑 这个文件,进入 后用ESC+S查找这个函数的具体位置。如果您喜欢用 VI编辑器,那可以用/来查找。 还有一种,假如进站时,显示了“请输入密码:”,这段程序在 这个文件,进入 后用ESC+S查找这个函数的具体位置。如果您喜欢用 哪里呢?您可以这样找,在源程序目录内,用: grep '请输入密码' * |more 这样就可以找到这个程序的位置了。 还有就是BBS的源程序一般是用英语取的名字,如关于讨论区 的程序就在boards.c内,聊天的程序就在talk.c内,聊天室的程序一 般就在chat.c内等等。 好了,我也不是什么专家,有些话不敢乱说,只能说这些了,具 体的就请您自己去慢慢了解了。:PP
|