diff options
-rw-r--r-- | ColaBBS_to_PttBBS/README | 36 | ||||
-rw-r--r-- | ColaBBS_to_PttBBS/cntDIR.c | 40 | ||||
-rw-r--r-- | ColaBBS_to_PttBBS/cntarticle.pl | 22 | ||||
-rw-r--r-- | ColaBBS_to_PttBBS/cntbrd.c | 114 | ||||
-rw-r--r-- | ColaBBS_to_PttBBS/cnthomeDIR.c | 45 | ||||
-rw-r--r-- | ColaBBS_to_PttBBS/cnthomedir.pl | 12 | ||||
-rw-r--r-- | ColaBBS_to_PttBBS/cntmail.pl | 23 | ||||
-rw-r--r-- | ColaBBS_to_PttBBS/cntpasswd.c | 35 |
8 files changed, 327 insertions, 0 deletions
diff --git a/ColaBBS_to_PttBBS/README b/ColaBBS_to_PttBBS/README new file mode 100644 index 00000000..9e6a2588 --- /dev/null +++ b/ColaBBS_to_PttBBS/README @@ -0,0 +1,36 @@ +There're some tools for transfering data from ColaBBS +(http://lh.twbbs.org/) to PttBBS (http://ptt.cc). Since ColaBBS +doesn't provide its source code or any file spec, there's no good way +to do this. I hacked the data structures with only VERY LITTLE +information directly from files, and these may NOT work. You sould NOT +use if you don't have programming background, or contact(make a +offer?) me in2 _AT_ in2home.org. + +please follow the step: +1. backup your ColaBBS. +2. install a new PttBBS + (see https://opensvn.csie.org/pttbbs/trunk/pttbbs/docs/INSTALL for + details) + please do NOT do the following to a existed bbs! +3. shutdown the bbs and clean all shared-memory if it's running. +4. copy all .c and .pl programs into your ~bbs/pttbbs/util/. then + compile them: `make cntDIR cntbrd cnthomeDIR cntpasswd` +5. transfer boards: + cd _COLABBS_/boards/; \ + perl -e "system('mv $_ ~/boards/'. + substr($_, 0, 1).'/'.$_) foreach( <*> )" + + cd /home/bbs/boards; perl cntarticle.pl boards/*/*; \ + apply "mv %1/.DIR %1/.DIR.colabbs; cntDIR < %1/.DIR.colabbs > + %1/.DIR" */* + cntbrd < _COLABBS_/boards/.BOARDS > ~/.BRD +6. transfer password file: + cntpasswd < _COLABBS_/.PASSWDS > ~/.PASSWDS +7. transfer mails + cd _COLABBS_/home; cnthomedir.pl + cd ~/home/; + apply "mv %1/mail/* %1/" */*; \ + apply "mv %1/mail/.DIR %1/.DIR.colabbs" */*; \ + apply "rmdir %1/mail" */*; \ + apply "cnthomeDIR < %1/.DIR.colabbs > %1/.DIR"; \ + cntarticle.pl */* diff --git a/ColaBBS_to_PttBBS/cntDIR.c b/ColaBBS_to_PttBBS/cntDIR.c new file mode 100644 index 00000000..f71aa706 --- /dev/null +++ b/ColaBBS_to_PttBBS/cntDIR.c @@ -0,0 +1,40 @@ +#include "bbs.h" +/* + usage: apply "mv %1/.DIR %1/.DIR.colabbs; + ./cntDIR < %1/.DIR.colabbs > %1/.DIR; + rm %1/.DIR.colabbs" + ~/boards/ * / * + ^ ^ ^ <- please ignore the spaces +*/ + +typedef struct { + char filename[FNLEN]; /* M.9876543210.A */ + char pad0[78-FNLEN]; + char owner[IDLEN + 2]; /* uid[.] */ + char pad1[68]; + char title[65]; + char pad2[31]; +} ffh_t; +int main(int argc, char **argv) +{ + ffh_t ffh; + fileheader_t fh; + + time_t t; + struct tm *tm; + + memset(&fh, 0, sizeof(fh)); + while( read(0, &ffh, sizeof(ffh)) == sizeof(ffh) ){ + if( !ffh.filename[0] ) + continue; + strlcpy(fh.filename, ffh.filename, sizeof(fh.filename)); + strlcpy(fh.title, ffh.title, sizeof(fh.title)); + strlcpy(fh.owner, ffh.owner, sizeof(fh.owner)); + + t = atoi(&fh.filename[2]); + tm = localtime(&t); + sprintf(fh.date, "%2d/%02d", tm->tm_mon + 1, tm->tm_mday); + write(1, &fh, sizeof(fh)); + } + return 0; +} diff --git a/ColaBBS_to_PttBBS/cntarticle.pl b/ColaBBS_to_PttBBS/cntarticle.pl new file mode 100644 index 00000000..0567d378 --- /dev/null +++ b/ColaBBS_to_PttBBS/cntarticle.pl @@ -0,0 +1,22 @@ +#!/usr/bin/perl +use IO::All; +die "usage: cntarticle.pl [base dir]" + if( !@ARGV ); + +foreach( @ARGV ){ + print "converting: $_\n"; + convert($_) + foreach( <$_/M.*.A> ); +} + +sub convert +{ + my($fn) = @_; + $content < io($fn); + $content =~ s/\r//gs; + $content =~ s/^.*?m 作者 .*?m (.*\))\s+\S+? 信區 .*?m (\S+).*/作者: $1 看板: $2/m; + $content =~ s/^.*?m 標題 .*?m (.*?)\s+\S+m/標題: $1/m; + $content =~ s/^.*?m 時間 .*?m (.*?)\s+\S+m/時間: $1/m; + $content =~ s/^\e\[36m────────────────────────────────────────\e\[m\n//m; + "$content\n" > io($fn); +} diff --git a/ColaBBS_to_PttBBS/cntbrd.c b/ColaBBS_to_PttBBS/cntbrd.c new file mode 100644 index 00000000..23f28849 --- /dev/null +++ b/ColaBBS_to_PttBBS/cntbrd.c @@ -0,0 +1,114 @@ +#include "bbs.h" +/* usage: ./cntbrd < ColaBBS/.BOARDS > ~/.BRD */ + +typedef struct { + char brdname[13]; + char pad[148]; + char title[49]; + char pad2[46]; +} fbrd_t; + +int main(int argc, char **argv) +{ + fbrd_t fbh; + boardheader_t bh; +#if 0 + int i; + read(0, &fbh, sizeof(fbh)); + for( i = 0 ; i < sizeof(fbh) ; ++i ) + printf("%03d: %d(%c)\n", i, fbh.pad[i], fbh.pad[i]); + return 0; +#endif + + memset(&bh, 0, sizeof(bh)); + strcpy(bh.brdname, "SYSOP"); + strcpy(bh.title, "嘰哩 ◎站長好!"); + bh.brdattr = BRD_POSTMASK | BRD_NOTRAN | BRD_NOZAP; + bh.level = 0; + bh.gid = 2; + write(1, &bh, sizeof(bh)); + + strcpy(bh.brdname, "1..........."); + strcpy(bh.title, ".... Σ中央政府 《高壓危險,非人可敵》"); + bh.brdattr = BRD_GROUPBOARD; + bh.level = PERM_SYSOP; + bh.gid = 1; + write(1, &bh, sizeof(bh)); + + strcpy(bh.brdname, "junk"); + strcpy(bh.title, "發電 ◎雜七雜八的垃圾"); + bh.brdattr = BRD_NOTRAN; + bh.level = PERM_SYSOP; + bh.gid = 2; + write(1, &bh, sizeof(bh)); + + strcpy(bh.brdname, "Security"); + strcpy(bh.title, "發電 ◎站內系統安全"); + bh.brdattr = BRD_NOTRAN; + bh.level = PERM_SYSOP; + bh.gid = 2; + write(1, &bh, sizeof(bh)); + + strcpy(bh.brdname, "2..........."); + strcpy(bh.title, ".... Σ市民廣場 報告 站長 ㄜ!"); + bh.brdattr = BRD_GROUPBOARD; + bh.level = 0; + bh.gid = 1; + write(1, &bh, sizeof(bh)); + + strcpy(bh.brdname, "ALLPOST"); + strcpy(bh.title, "嘰哩 ◎跨板式LOCAL新文章"); + bh.brdattr = BRD_POSTMASK | BRD_NOTRAN; + bh.level = PERM_SYSOP; + bh.gid = 5; + write(1, &bh, sizeof(bh)); + + strcpy(bh.brdname, "deleted"); + strcpy(bh.title, "嘰哩 ◎資源回收筒"); + bh.brdattr = BRD_NOTRAN; + bh.level = PERM_BM; + bh.gid = 5; + write(1, &bh, sizeof(bh)); + + strcpy(bh.brdname, "Note"); + strcpy(bh.title, "嘰哩 ◎動態看板及歌曲投稿"); + bh.brdattr = BRD_NOTRAN; + bh.level = 0; + bh.gid = 5; + write(1, &bh, sizeof(bh)); + + strcpy(bh.brdname, "Record"); + strcpy(bh.title, "嘰哩 ◎我們的成果"); + bh.brdattr = BRD_NOTRAN | BRD_POSTMASK; + bh.level = 0; + bh.gid = 5; + write(1, &bh, sizeof(bh)); + + strcpy(bh.brdname, "WhoAmI"); + strcpy(bh.title, "嘰哩 ◎呵呵,猜猜我是誰!"); + bh.brdattr = BRD_NOTRAN; + bh.level = 0; + bh.gid = 5; + write(1, &bh, sizeof(bh)); + + strcpy(bh.brdname, "EditExp"); + strcpy(bh.title, "嘰哩 ◎範本精靈投稿區"); + bh.brdattr = BRD_NOTRAN; + bh.level = 0; + bh.gid = 5; + write(1, &bh, sizeof(bh)); + + while( read(0, &fbh, sizeof(fbh)) == sizeof(fbh) ){ + if( !fbh.brdname[0] || strcasecmp(fbh.brdname, "sysop") == 0 ) + continue; + memset(&bh, 0, sizeof(bh)); + strlcpy(bh.brdname, fbh.brdname, sizeof(bh.brdname)); + strlcpy(bh.title, "轉換 ◎", sizeof(bh.title)); + strlcpy(&bh.title[7], fbh.title, sizeof(bh.title)); + bh.brdattr = BRD_NOTRAN; + bh.level = 0; + bh.gid = 2; + write(1, &bh, sizeof(bh)); + } + return 0; +} diff --git a/ColaBBS_to_PttBBS/cnthomeDIR.c b/ColaBBS_to_PttBBS/cnthomeDIR.c new file mode 100644 index 00000000..a0ca6c8d --- /dev/null +++ b/ColaBBS_to_PttBBS/cnthomeDIR.c @@ -0,0 +1,45 @@ +#include "bbs.h" +/* please run cnthomedir.pl first! + cd home/; apply "mv %1/mail/* %1/" * / * + apply "mv %1/mail/.DIR %1/.DIR.colabbs" * / * + apply "rmdir %1/mail" * / * + apply "cnthomeDIR < %1/.DIR.colabbs > %1/.DIR" * / * +*/ + +typedef struct { + char filename[FNLEN]; /* M.9876543210.A */ + char pad0[80-FNLEN]; + char owner[IDLEN + 2]; /* uid[.] */ + char pad1[66]; + char title[65]; + char pad2[31]; +} ffh_t; +int main(int argc, char **argv) +{ + ffh_t ffh; + fileheader_t fh; + + time_t t; + struct tm *tm; + int i; + + memset(&fh, 0, sizeof(fh)); + while( read(0, &ffh, sizeof(ffh)) == sizeof(ffh) ){ + if( !ffh.filename[0] ) + continue; + strlcpy(fh.filename, ffh.filename, sizeof(fh.filename)); + strlcpy(fh.title, ffh.title, sizeof(fh.title)); + strlcpy(fh.owner, ffh.owner, sizeof(fh.owner)); + for( i = 0 ; i < sizeof(fh.owner) ; ++i ) + if( fh.owner[i] == ' ' ){ + fh.owner[i] = 0; + break; + } + + t = atoi(&fh.filename[2]); + tm = localtime(&t); + sprintf(fh.date, "%2d/%02d", tm->tm_mon + 1, tm->tm_mday); + write(1, &fh, sizeof(fh)); + } + return 0; +} diff --git a/ColaBBS_to_PttBBS/cnthomedir.pl b/ColaBBS_to_PttBBS/cnthomedir.pl new file mode 100644 index 00000000..acb6fd28 --- /dev/null +++ b/ColaBBS_to_PttBBS/cnthomedir.pl @@ -0,0 +1,12 @@ +#!/usr/bin/perl +# usage: cd ColaBBS/home; perl cnthomedir.pl +use IO::All; +foreach( <*> ){ + next if( !-d $_ || /\./ ); + $USERDATA < io("$_/USERDATA.DAT"); + ($userid) = $USERDATA =~ /^(\w+)/; + $c = substr($userid, 0, 1); + + `mv ~/home/$c/$userid ~/tmp/; mv $_ ~/home/$c/$userid`; + print "$_ => $userid\n"; +} diff --git a/ColaBBS_to_PttBBS/cntmail.pl b/ColaBBS_to_PttBBS/cntmail.pl new file mode 100644 index 00000000..a5d6396f --- /dev/null +++ b/ColaBBS_to_PttBBS/cntmail.pl @@ -0,0 +1,23 @@ +#!/usr/bin/perl +use IO::All; +die "usage: cntarticle.pl [base dir]" + if( !@ARGV ); + +foreach( @ARGV ){ + print "converting: $_\n"; + convert($_) + foreach( <$_/M.*.A> ); +} + +sub convert +{ + my($fn) = @_; + $content < io($fn); + $content =~ s/\r//gs; + $content =~ s/\^R//gs; + $content =~ s/^.*?m 作者 .*?m (.*\))\s+$/作者: $1/m; + $content =~ s/^.*?m 標題 .*?m (.*?)\s+\S+m/標題: $1/m; + $content =~ s/^.*?m 時間 .*?m (.*?)\s+\S+m/時間: $1/m; + $content =~ s/^\e\[36m────────────────────────────────────────\e\[m\n//m; + "$content\n" > io($fn); +} diff --git a/ColaBBS_to_PttBBS/cntpasswd.c b/ColaBBS_to_PttBBS/cntpasswd.c new file mode 100644 index 00000000..ca0f419e --- /dev/null +++ b/ColaBBS_to_PttBBS/cntpasswd.c @@ -0,0 +1,35 @@ +#include "bbs.h" +/* usage: ./cntpasswd < ColaBBS/.PASSWDS > ~/.PASSWDS */ + +typedef struct { + char userid[IDLEN + 1]; + char pad0[1]; + char passwd[PASSLEN]; + char nick[24]; + char pad1[16]; + char name[20]; + char pad2[424]; +} fuserect_t; + +int main(int argc, char **argv) +{ + fuserect_t fu; + userec_t u; + memset(&u, 0, sizeof(u)); + while( read(0, &fu, sizeof(fu)) == sizeof(fu) ){ +#if 0 + printf("(%s), (%s), (%s), (%s)\n", + fu.userid, fu.passwd, fu.nick, fu.name); +#endif + if( !fu.userid[0] ) + continue; + + memset(&u, 0, sizeof(u)); + strlcpy(u.userid, fu.userid, sizeof(u.userid)); + strlcpy(u.passwd, fu.passwd, sizeof(u.passwd)); + strlcpy(u.realname, fu.name, sizeof(u.realname)); + strlcpy(u.username, fu.nick, sizeof(u.username)); + write(1, &u, sizeof(u)); + } + return 0; +} |