【 以下文字转载自 atpppWorking 讨论区 】
发信人: atppp (Big Mouse), 信区: atpppWorking
标 题: xxx2smth 一般论坛数据转换到 smthbbs 系统
发信站: 牧场物语 (Thu Aug 12 00:43:46 2004), 站内
被逼写这个东西嘿嘿...先开个头再说...希望对大家理解 smthbbs 系统也有作用。
如果有什么写错的地方,容我日后慢慢改...
xxx2smth 一般论坛数据转换到 smthbbs 系统
0. 序
0.1 为什么要转换成 smthbbs 系统?
你在看我这个文章就说明你觉得 smthbbs 系统还是有可取之处的。所以我就不具体说了
...
0.2 转换之前都需要做些什么工作?
你必须相当的熟悉你要转换的那个老系统的结构,特别是用户数据(如果你打算转换用户
帐号的话)和版面文章数据的结构。
然后你要装一个 smthbbs 系统稳定运行起来。代码方面,你需要熟悉 src/site.h
src/site.c src/default.h src/default.c 这 4 个文件是怎么配合工作的,一些重要的
参数比如最多允许的版面数量如何修改。站务方面,你必须相当熟悉一般的管理操作,可
以参考 doc/README.SYSOP 文档。
0.3 共享内存
共享内存在 smthbbs 系统中主要用于进程间通信。比方,你在 web 注册了之后,马上就
能在 telnet 下登录了,这是因为 web 注册的那个程序修改了相应的共享内存数据,当
你在 telnet 试图登录的时候,telnet 程序就能在共享内存中发现你的信息。当然,这
些工作完全可以用文件系统来做,但是用共享内存来做进程间通信效率就会高很多。BBS
的很多重要数据都在共享内存里面,比如转换数据会碰到两个重要的系统文件:
~bbs/.PASSWDS 这个是用户的帐号信息,包括密码。
~bbs/.BOARDS 所有版面的信息。
当系统正常启动之后,这两个文件的信息在共享内存里面,系统会定时写磁盘同步数据。
当系统正常运行的时候,直接打开这两个文件修改是不对的!转换数据或者修改数据之前
,一般必须要停掉 BBS 服务,清除掉共享内存数据。如果不会请看 ipcs 和 ipcrm 的
man page。
0.4 静态转换和动态转换
静态转换的意思是,把所有的重要文件都写好了,然后一次性启动系统。动态转换的意思
是,在系统正常运行的情况下,尽可能利用 BBS 已有的函数一点一点的转换数据。动态
转换需要你对系统共享内存和 BBS 函数有相当程度的了解,下面基本不使用动态转换的
方法。
1. 转换版面及文章
1.1 版面文章的数据结构
每个版面都是一个目录。比如 SYSOP 版的目录是 ~bbs/boards/SYSOP/。在这个目录下面
有一个 .DIR 文件,这是所有帖子的索引。然后有一大堆类似 M.1085385291.w0 这样文
件名的文件,每一个这样的文件就是一个帖子。这个文件名的规则是:前两个字符是 M.
,紧跟着一个 10 位数的 timestamp,是帖子发表的时间,然后是 .??,这里问号可以随
便填什么,推荐就用 .A0 好了,如果同一个时间点有两个帖子,可以把最后两个字符换
成 .B0 等依次推类。转换程序转换版面文章的核心,应该就是从老的系统里面读取这个
版面每个帖子的标题、内容、发表时间,然后按照 BBS 帖子的样板写成相应的文件。
注:smthbbs 也可以采用版面目录下 52 个子目录分散储存帖子的方法。一般站点不会使
用这种方法,我就不具体写了。
1.2 最简单的转换办法
最简单的办法可能是,先正常开启相应的讨论区,接着用一个自制转换程序转换所有的帖
子。然后,使用 local_utl/fixdir 程序产生相应的帖子索引 .DIR;最后用
local_utl/gen_title 程序同步 .DIR 里面的帖子主题。这个方法最简单,不过会有各种
各样的问题,可以作为转换程序入门练习用。
1.3 产生 .BOARDS 文件
~bbs/.BOARDS 文件是所有版面的信息,实际上是 MAXBOARD 个 boardheader 结构。这个
结构定义在 src/struct.h 里面,具体解释如下,转换不需要关心的字段我就不解释了:
struct boardheader {
char filename[STRLEN];
版面的英文名称,STRLEN 是 80
char BM[BM_LEN];
版主列表,BM_LEN 是 60。多个版主用空格隔开
char title[STRLEN];
版面的说明,就是开启讨论区的时候输入的那些东西,比方:
0[站务] 测试用版
unsigned level;
版面存取权限。设置成 0 就好了,转换完了再修改讨论区也不迟。
unsigned int idseq;
和 bcache 里面的 nowid 同步,这个 nowid 的问题后面会详细说。
unsigned int clubnum;
俱乐部相关,转换的时候设置成 0 就好了。
unsigned int flag;
版面的一些属性比方是否参与转信。转换的时候设置成 0 就好了。
union {
unsigned int adv_club; 设置成 0
unsigned int group_total; 设置成 0
} board_data;
time_t createtime;
版面创建时间,“新开启的讨论区”会用到。设置成 0 也没事。
int unused;
char ann_path[128];
精华区路径,这个以后再说吧,先全设置成 '\0' 也可以。
int group;
所属目录,设置成 0 就好了。
char title_level;
设定用户需要什么 title 可见这个版面,设置成 0。
char des[195];
版面描述,用于 www 的版面说明和 search,可以以后再加。
#ifdef FLOWBANNER
下面这两个用于版面底部流动信息。如果编译加入就全设置为 '\0' 好了。
int bannercount;
char banners[MAXBANNER][BANNERSIZE];
#endif
};
转换程序需要做什么呢?就是从老的系统里面取出所有版面的信息,参考上面的说明转换
出一个 .BOARDS 文件来。版面数量不到 MAXBOARD 的话,剩下的部分全部填 0 就好了。
我推荐直接在 BBS 系统里面开版然后转换版面文章,这样 .BOARDS 由系统自动产生。如
果老系统版面实在太多,考虑用程序自动产生 .BOARDS 才比较有意义。
1.4 转换版面文章
具体的帖子转换已经在上面的 1.1 节说过。现在说一下最关键的 .DIR 文件。这个文件
是 n 个 fileheader 结构,n = 版面帖子数量。这个 fileheader 定义在
src/default.h 或者 src/site.h 里面,具体解释如下:
typedef struct fileheader {
char filename[FILENAME_LEN];
帖子的文件名,比方 1.1 节那个例子,这个字段就是 M.1085385291.w0,注意第
3 个字节到第 12 个字节是帖子的发表时间戳,这个非常重要,一定要搞对。
unsigned int id, groupid, reid;
这三个变量非常重要,下面一节具体说明。
int o_bid;
unsigned int o_id;
unsigned int o_groupid;
unsigned int o_reid;
上面四个变量在转换时可以全部设置成 0。
char innflag[2];
帖子是否转信,两个字节都设置成 'L' 就可以了。
char owner[OWNER_LEN];
发文作者。注意最后一个字节要留一个 '\0' 字符。
unsigned int eff_size;
帖子的有效字节数,转换的时候设置成 0 就好了,转换完了以后可以用
local_utl/calc_effsize 程序同步。
time_t posttime;
帖子发表时间的 timestamp,最好设置一下。
long attachment;
附件偏移量,设置成 0 就可以了。
char title[ARTICLE_TITLE_LEN];
帖子的标题。注意最后要留一个 '\0' 字符,长标题需要截短。
unsigned char accessed[4];
一些帖子的属性,设置成 0 就可以了。
} fileheader;
转换程序可以自己产生 .DIR 文件而不是依赖 fixdir 程序。
1.5 id, groupid, reid 三个字段
这三个字段是帖子的索引 ID 和同主题信息。在 .DIR 里面的 fileheader 结构,id 字
段依次严格递增,注意一定是严格递增,否则 web 下浏览会不正常!另外两个字段的作
用举例如下:
有人新发表了帖子 A,这个帖子系统自动给了 id = 10
然后有人回复帖子 A,我们叫它帖子 B;
再有人回复了帖子 B,我们叫它帖子 C;
最后有人回复帖子 A,称为帖子 D。这四个帖子的三个字段会是这样:
帖子 id groupid reid
================================
A 10 10 10
B 11 10 10
C 12 10 11
D 13 10 10
具体不用多解释了吧。groupid 就是用来判断帖子同主题的,注意,帖子同主题和帖子标
题无关。reid 主要用来产生回复树结构,目前只在 wForum 里面用到。如果老的系统支
持这些结构,可以想办法转换过来。另外,gen_title 程序的原理是根据帖子标题来产生
groupid,用来同步主题信息。
1.6 boardheader 里面的 idseq
这个字段就是当前最后一篇帖子的 id 值,和 boardstatus 共享内存里面相应的 nowid
同步。发表帖子的时候系统会自动根据 nowid 分配下一个 id 值。如果用静态转换,可
以先转换所有的版面文章,获得各个版面最后一片帖子的 id 值,然后再产生 .BOARDS,
写入相应的 idseq 值。如果使用动态转换或者版面已经建立,可以参考 gen_title 程序
的办法,启动 BBS 系统然后用一个外部程序遍历所有的 boardstatus 写入 nowid 值。
1.7 同主题模式的文章列表
同主题模式依赖于版面目录下面的一个 .ORIGIN 文件。这个文件就是 .DIR 文件里面
id==groupid 的 fileheaders。你可以写一个简单的程序自动产生 .ORIGIN 文件,或者
等待系统自动更新。
1.8 帖子有附件怎么办?
等我以后慢慢写...
1.9 还是觉得无从下手,怎么办?
去 smth.org BBSMan_Dev 版讨论吧。
2. 转换用户
转换版面和文章可能是整个转换程序中最简单的部分,而且一般转换只保留文章就大功告
成了,用户反正可以让忠实用户再注册一遍。不过还是讨论一下自动转换用户的可能性。
我以后再写吧...感谢 only4bbs。
--
修改:atppp FROM 127.0.0.*
FROM 127.0.0.*