From 450ad26421aa1c38700dddc8899a3522e1cc5442 Mon Sep 17 00:00:00 2001 From: ptt Date: Sat, 26 Jun 2004 02:03:37 +0000 Subject: Merge bbs merge module usage: make -D BBSMERGE to enable this module git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@2091 63ad8ddf-47c3-0310-b6dd-a9e9d9715204 --- include/fpg.h | 136 +++++++++++++++++++++++++++++++++++++ include/proto.h | 7 ++ mbbsd/Makefile | 6 ++ mbbsd/admin.c | 89 ++++++++++++++++++++++-- mbbsd/announce.c | 2 +- mbbsd/mail.c | 11 ++- mbbsd/menu.c | 3 + mbbsd/merge.c | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ mbbsd/record.c | 24 +++---- mbbsd/user.c | 1 + util/merge_dir.c | 2 +- 11 files changed, 459 insertions(+), 25 deletions(-) create mode 100644 include/fpg.h create mode 100644 mbbsd/merge.c diff --git a/include/fpg.h b/include/fpg.h new file mode 100644 index 00000000..8014c5b4 --- /dev/null +++ b/include/fpg.h @@ -0,0 +1,136 @@ + + +#define STRLEN 80 /* Length of most string data */ +#define BTLEN 48 /* Length of board title */ +#define FTTLEN 72 /* Length of title */ +#define NAMELEN 40 /* Length of username/realname */ +#define FNLEN 33 /* Length of filename */ +#define IDLEN 12 /* Length of bid/uid */ +#define PASSLEN 14 /* Length of encrypted passwd field */ +#define REGLEN 38 /* Length of registration data */ + +typedef unsigned char uschar; /* length = 1 */ +typedef unsigned int usint; /* length = 4 */ + + +typedef struct +{ + uschar id; + char broken; +} WEAPONARMOR; + +typedef struct +{ + char id; + char name[IDLEN + 1]; + char lv; + short lp; + ushort mlp; + short hp; + ushort mhp; + uschar po; + uschar st; + uschar ag; + uschar lu; + int ex; + char emotion; + char moral; + char wisdom; + char will; + char charm; + WEAPONARMOR weapon; + WEAPONARMOR armor[4]; + uschar flag; + char hungry; + char sick; + char angry; +} PET; + +typedef struct +{ + char userid[IDLEN + 1]; + char realname[20]; + char username[24]; + char passwd[PASSLEN]; + ushort uflag; + usint userlevel; + ushort numlogins; + ushort numposts; + time_t firstlogin; + time_t lastlogin; + char lasthost[16]; + char email[50]; + char address[50]; + char justify[REGLEN + 1]; + uschar month; + uschar day; + uschar year; + uschar sex; + uschar state; + ushort mailk; + ushort keepmail; + int money; + ushort totalday; + uschar totalhour; + uschar totalmin; + int market[10]; + short locate; + char action; + char direct; + char speed; + char count; + uschar landnum; + uschar tool[10]; + char NAME[IDLEN + 1]; + char LV; + short HP; + short MHP; + short MP; + short MMP; + short WC; + short AC; + short PO; + short ST; + short AG; + short LU; + int EX; + char EVENT; + uschar WA[6]; + uschar USE[10]; + uschar MAGIC[5]; + uschar NOWOCCUPATION; + short OCCUPATION[4]; + uschar cardfightnum; + uschar cardfight[20]; + uschar dragon[5]; + PET pet; + char left[40]; +} ACCT; + +struct fileheader +{ + char filename[FNLEN]; /* M.9876543210.A */ + char savemode; /* file save mode */ + char owner[IDLEN + 2]; /* uid[.] */ + char date[6]; /* [02/02] or space(5) */ + char title[FTTLEN + 1]; + uschar filemode; /* must be last field @ boards.c */ +}; +typedef struct fileheader fileheader; + +struct boardheader +{ + char brdname[IDLEN + 1]; /* bid */ + char title[BTLEN + 1]; + char BM[IDLEN * 3 + 3]; /* BMs' uid, token '/' */ + char group[9]; /* ¬ÝªO¤ÀÃþ */ + char type; /* ¬ÝªO©Ê½è: Âà«H¡H¥Ø¿ý¡H */ + char pad[1]; + time_t bupdate; /* note update time */ + char pad2[3]; + uschar bvote; /* Vote flags */ + time_t vtime; /* Vote close time */ + usint level; +}; +typedef struct boardheader boardheader; + diff --git a/include/proto.h b/include/proto.h index 25439698..c439b708 100644 --- a/include/proto.h +++ b/include/proto.h @@ -24,6 +24,7 @@ void setup_man(boardheader_t * board); void delete_symbolic_link(boardheader_t *bh, int bid); int make_symbolic_link(char *bname, int gid); int make_symbolic_link_interactively(int gid); +void merge_dir(char *dir1, char *dir2); /* announce */ int a_menu(char *maintitle, char *path, int lastlevel); @@ -339,6 +340,12 @@ int Xyz(void); int Play_Play(void); int Name_Menu(void); +#ifdef MERGEBBS +/* merge */ +int m_fpg(void); +void m_fpg_brd(char *bname,char *fromdir); +#endif + /* more */ int more(char *fpath, int promptend); diff --git a/mbbsd/Makefile b/mbbsd/Makefile index 1a078380..c60550f3 100644 --- a/mbbsd/Makefile +++ b/mbbsd/Makefile @@ -7,6 +7,7 @@ CFLAGS+= -DBLOG LDFLAGS+= -L/usr/local/lib/mysql -lmysqlclient .endif + PROG= mbbsd OBJS= admin.o announce.o args.o assess.o bbs.o board.o cache.o cal.o card.o\ chat.o chc.o chicken.o convert.o dark.o edit.o fav.o friend.o gamble.o\ @@ -15,6 +16,11 @@ OBJS= admin.o announce.o args.o assess.o bbs.o board.o cache.o cal.o card.o\ register.o screen.o stuff.o talk.o term.o topsong.o user.o brc.o\ vice.o vote.o xyz.o voteboard.o syspost.o var.o passwd.o calendar.o +.if defined(MERGEBBS) +CFLAGS+= -DMERGEBBS +OBJS+= merge.o +.endif + .SUFFIXES: .c .o .c.o: ../include/var.h $(CCACHE) $(CC) $(CFLAGS) -c $*.c diff --git a/mbbsd/admin.c b/mbbsd/admin.c index 96b65ccd..d9211c74 100644 --- a/mbbsd/admin.c +++ b/mbbsd/admin.c @@ -32,8 +32,7 @@ m_loginmsg() int m_user() { - userec_t muser; - int id; + userec_t muser; int id; char genbuf[200]; stand_title("¨Ï¥ÎªÌ³]©w"); @@ -266,6 +265,58 @@ void delete_symbolic_link(boardheader_t *bh, int bid) log_usies("DelLink", bh->brdname); } +int dir_cmp(const void *a, const void *b) +{ + return (atoi( &((fileheader_t *)a)->filename[2] ) - + atoi( &((fileheader_t *)b)->filename[2] )); +} + +void merge_dir(char *dir1, char *dir2) +{ + int i, pn, sn; + fileheader_t *fh; + char *p1, *p2, bakdir[128], file1[128], file2[128]; + strcpy(file1,dir1); + strcpy(file2,dir2); + if((p1=strrchr(file1,'/'))) + p1 ++; + else + p1 = file1; + if((p2=strrchr(file2,'/'))) + p2 ++; + else + p2 = file2; + + pn=get_num_records(dir1, sizeof(fileheader_t)); + sn=get_num_records(dir2, sizeof(fileheader_t)); + if(!sn) return; + fh= (fileheader_t *)malloc( (pn+sn)*sizeof(fileheader_t)); + get_records(dir1, fh, sizeof(fileheader_t), 1, pn); + get_records(dir2, fh+pn, sizeof(fileheader_t), 1, sn); + qsort(fh, pn+sn, sizeof(fileheader_t), dir_cmp); + sprintf(bakdir,"%s.bak", dir1); + Rename(dir1, bakdir); + for(i=1; iBnumber, + completeboard_compar, + completeboard_permission, + completeboard_getname); + if (frombname[0] == '\0' || !getbnum(frombname) || + !strcmp(frombname,bname)) + break; + setbdir(genbuf, bname); + setbdir(fromdir, frombname); +#ifdef MERGEBBS + } +#endif + merge_dir(genbuf, fromdir); + touchbtotal(bid); + } + break; case 'b': if (HAS_PERM(PERM_SYSOP)) { char bvotebuf[10]; @@ -711,7 +791,6 @@ m_newbrd(int recover) getbcache(class_bid)->childcount = 0; pressanykey(); setup_man(&newboard); - outs("\n·sªO¦¨¥ß"); post_newboard(newboard.title, newboard.brdname, newboard.BM); log_usies("NewBoard", newboard.title); diff --git a/mbbsd/announce.c b/mbbsd/announce.c index 3d1e3d9d..a1fc9d41 100644 --- a/mbbsd/announce.c +++ b/mbbsd/announce.c @@ -303,7 +303,7 @@ a_newitem(menu_t * pm, int mode) a_additem(pm, &item); } -static void +void a_pasteitem(menu_t * pm, int mode) { char newpath[PATHLEN]; diff --git a/mbbsd/mail.c b/mbbsd/mail.c index bb98674c..506d8c38 100644 --- a/mbbsd/mail.c +++ b/mbbsd/mail.c @@ -743,6 +743,7 @@ read_new_mail(fileheader_t * fptr) if (genbuf[0] == 'y') { unlink(fname); delmsgs[delcnt++] = idc; // FIXME ¤@¦¸§R¤Ó¦h«H out of array boundary + mailsum = mailkeep = 0; } } clear(); @@ -838,6 +839,7 @@ mail_del(int ent, fileheader_t * fhdr, char *direct) setupmailusage(); setdirpath(genbuf, direct, fhdr->filename); unlink(genbuf); + mailsum = mailkeep = 0; return DIRCHANGED; } } @@ -1122,18 +1124,15 @@ int mail_man() { char buf[64], buf1[64]; - if (HAS_PERM(PERM_MAILLIMIT)) { - int mode0 = currutmp->mode; - int stat0 = currstat; + int mode0 = currutmp->mode; + int stat0 = currstat; sethomeman(buf, cuser.userid); snprintf(buf1, sizeof(buf1), "%s ªº«H¥ó§¨", cuser.userid); - a_menu(buf1, buf, 1); + a_menu(buf1, buf, HAS_PERM(PERM_MAILLIMIT)); currutmp->mode = mode0; currstat = stat0; return FULLUPDATE; - } - return DONOTHING; } static int diff --git a/mbbsd/menu.c b/mbbsd/menu.c index 407206cf..fc75a145 100644 --- a/mbbsd/menu.c +++ b/mbbsd/menu.c @@ -394,6 +394,9 @@ const static commands_t userlist[] = { #endif {u_register, PERM_BASIC, "RRegister ¶ñ¼g¡mµù¥U¥Ó½Ð³æ¡n"}, {u_list, PERM_SYSOP, "UUsers ¦C¥Xµù¥U¦W³æ"}, +#ifdef MERGEBBS + {m_fpg, PERM_LOGINOK, "FFPG Import ªá¶éÅܨ­³N"}, +#endif {NULL, 0, NULL} }; diff --git a/mbbsd/merge.c b/mbbsd/merge.c new file mode 100644 index 00000000..6a75328c --- /dev/null +++ b/mbbsd/merge.c @@ -0,0 +1,203 @@ +/* $Id: merge.c 2060 2004-06-11 17:18:06Z Ptt $ */ +#define _XOPEN_SOURCE +#define _ISOC99_SOURCE +/* this is a interface provided when we merge BBS */ +#include "bbs.h" +#include "fpg.h" + +int +m_fpg() +{ + char genbuf[256], buf[256], userid[25], passbuf[24], msg[2048]=""; + int count=0, i; + FILE *fp; + ACCT man; + time_t d; + + clear(); + move(1,0); + + outs( + " ¤p³½ªºµµ¦âªá¶é,\n" + " Åýªá¶éªº¨Ï¥ÎªÌÂಾ­Ó¤H¸ê²£¥H¤Î­«­n«H¥Î¸ê®Æ, ¨É¦³¥­µ¥¦w¥þªºÀô¹Ò.\n" + " ¦pªG±z¤£»Ý­n, ½Ðª½±µ«ö[Enter]Â÷¶}.\n" + " -----------------------------------------------------------------\n" + " ¯S§O¥mÀ{:\n" + " ¬°¤F±b¸¹¦w¥þ,±z¥u¦³³sÄò¤T¦¸±K½X¿ù»~ªº¾÷·|,½Ð¤p¤ß¿é¤J.\n" + " ³sÄò¤T¦¸¿ù»~±zªºÅܨ­¥\\¯à´N·|³Q¶}»@³æ¨Ãª½±µ³qª¾¯¸ªø.\n" + " ½Ð¤£­n¦bÅܨ­¹Lµ{¤¤¤£¥¿±`Â_½u, ¨è·NÂ_½uÅÜ¥bÃ~¤H¯¸ªø¤£±Ï­ò.\n" + ); + + + if(search_ulistn(usernum,2)) + {vmsg("½Ðµn¥X¨ä¥Lµøµ¡, ¥H§KÅܨ­¥¢±Ñ"); return 0;} + do + { + if(!getdata(10,0, " ¤p³½ªºID [­^¤å¤j¤p¼g­n§¹¥þ¥¿½T]:", userid, 20, + DOECHO)) return 0; + if(bad_user_id(userid)) continue; + sprintf(genbuf, "/home/bbs/fpg/home/%c/%s.ACT",userid[0], userid); + if(!(fp=fopen(genbuf, "r"))) + { + vmsg("¬dµL¦¹¤H©Î¤w¸g¶×¤J¹L..½Ðª`·N¤j¤p¼g "); + continue; + } + count = fread(&man, sizeof(man), 1, fp); + fclose(fp); + }while(!count); + count = 0; + do{ + getdata(11,0, " ¤p³½ªº±K½X:", passbuf, sizeof(passbuf), + NOECHO); + if(++count>=3) + { + cuser.userlevel |= PERM_VIOLATELAW; + cuser.vl_count++; + passwd_update(usernum, &cuser); + post_violatelaw(cuser.userid, "[PTTĵ¹î]", "´ú¸Õ¤p³½±b¸¹¿ù»~¤T¦¸", + "¹HªkÆ[¹î"); + mail_violatelaw(cuser.userid, "[PTTĵ¹î]", "´ú¸Õ¤p³½±b¸¹¿ù»~¤T¦¸", + "¹HªkÆ[¹î"); + + return 0; + } + } while(!checkpasswd(man.passwd, passbuf)); + if(!dashf(genbuf)) // avoid multi-login + { + vmsg("¬dµL¦¹¤H©Î¤w¸g¶×¤J¹L..½Ðª`·N¤j¤p¼g "); + return 0; + } + sprintf(buf,"%s.done",genbuf); + rename(genbuf,buf); + move(12,0); + clrtobot(); +#ifdef MERGEMONEY + reload_money(); + sprintf(buf, + "±zªºªá¶é¹ô¦³ %d ´«ºâ¦¨ Ptt ¹ô¬° %d (¶×²v 155:1), \n" + " ­ì¦³ %d ¶×¤J«á¦@¦³ %d\n", + man.money, man.money/155, cuser.money, cuser.money + man.money/155); + demoney(man.money/155); + strcat(msg, buf); +#endif + + i = cuser.exmailbox + man.mailk + man.keepmail; + if (i > 1000) i = 1000; + sprintf(buf, "±zªºªá¶é«H½c¦³ %d : %d, ­ì¦³ %d ¶×¤J«á¦@¦³ %d\n", + man.mailk, man.keepmail, cuser.exmailbox, cuser.exmailbox ); + strcat(msg, buf); + cuser.exmailbox = i; + + if(cuser.firstlogin > man.firstlogin) d = man.firstlogin; + else d = cuser.firstlogin; + sprintf(buf, "ªá¶éµù¥U¤é´Á %s ", Cdatedate(&(man.firstlogin))); + strcat(msg,buf); + sprintf(buf, "¦¹±b¸¹µù¥U¤é´Á %s ±N¨ú ",Cdatedate(&(cuser.firstlogin))); + strcat(msg,buf); + sprintf(buf, "±N¨ú %s\n", Cdatedate(&d) ); + strcat(msg,buf); + cuser.firstlogin = d; + + if(cuser.numlogins < man.numlogins) i = man.numlogins; + else i = cuser.numlogins; + + sprintf(buf, "ªá¶é¶i¯¸¦¸¼Æ %d ¦¹±b¸¹ %d ±N¨ú %d \n", man.numlogins, + cuser.numlogins, i); + strcat(msg,buf); + cuser.numlogins = i; + + if(cuser.numposts < man.numposts ) i = man.numposts; + else i = cuser.numposts; + sprintf(buf, "ªá¶é¤å³¹¦¸¼Æ %d ¦¹±b¸¹ %d ±N¨ú %d\n", + man.numposts,cuser.numposts,i); + strcat(msg,buf); + cuser.numposts = i; + outs(msg); + while(search_ulistn(usernum,2)) + {vmsg("½Ð±N­«ÂФW¯¸¨ä¥L½uÃö³¬! ¦AÄ~Äò");} + passwd_update(usernum, &cuser); + sethomeman(genbuf, cuser.userid); + mkdir(genbuf, 0600); + sprintf(buf, "tar zxvf home/%c/%s.tgz>/dev/null", + userid[0], userid); + chdir("fpg"); + system(buf); + chdir(BBSHOME); + + if (getans("¬O§_¶×¤J­Ó¤H«H½c? (Y/n)")!='n') + { + sethomedir(buf, cuser.userid); + sprintf(genbuf, "fpg/home/bbs/home/%c/%s/.DIR", + userid[0], userid); + merge_dir(buf, genbuf); + strcat(msg, "¶×¤J­Ó¤H«H½c\n"); + } + if(getans("¬O§_¶×¤J­Ó¤H«H½cºëµØ°Ï? (Y/n)")!='n') + { + sprintf(buf, + "mv fpg/home/bbs/home/%c/%s/man home/%c/%s/man", + userid[0], userid, + cuser.userid[0], cuser.userid); + system(buf); + strcat(msg, "¶×¤J­Ó¤H«H½cºëµØ°Ï\n"); + } + if(getans("¬O§_¶×¤J¦n¤Í¦W³æ? (·|Âл\\²{¦³³]©w, ID¥i¯à¬O¤£¦P¤H)? (y/N)")=='y') + { + sethomefile(genbuf, cuser.userid, "overrides"); + sprintf(buf, "fpg/home/bbs/home/%c/%s/overrides",userid[0],userid); + Copy(buf, genbuf); + strcat(buf, genbuf); + friend_load(FRIEND_OVERRIDE); + strcat(msg, "¶×¤J¦n¦³¤Íͳææ\n"); + } + sprintf(buf, "±b¸¹¶×¤J³ø§i %s -> %s ", userid, cuser.userid); + post_msg("Security", buf, msg, "[¨t²Î¦w¥þ§½]"); + sprintf(buf, "fpg/home/bbs/home/%c/%s/PttID", userid[0],userid); + if((fp = fopen(buf, "w"))) + { + fprintf(fp, "%s\n", cuser.userid); + fprintf(fp, "%s", msg); + fclose(fp); + } + + vmsg("®¥³ß±z§¹¦¨±b¸¹Åܨ­.."); + return 0; +} + +void +m_fpg_brd(char *bname, char *fromdir) +{ + char fbname[25], buf[256]; + fileheader_t fh; + + fromdir[0]=0; + do{ + + if(!getdata(20,0, "¤p³½ªºªO¦W [­^¤å¤j¤p¼g­n§¹¥þ¥¿½T]:", fbname, 20, + DOECHO)) return; + } + while(invalid_brdname(fbname)); + + sprintf(buf, "fpg/boards/%s.inf", fbname); + if(!dashf(buf)) + { + vmsg("µL¦¹¬ÝªO"); + return; + } + chdir("fpg"); + sprintf(buf, "tar zxf boards/%s.tgz >/dev/null",fbname); + system(buf); + sprintf(buf, "tar zxf boards/%s.man.tgz >/dev/null", fbname); + system(buf); + chdir(BBSHOME); + sprintf(buf, "mv fpg/home/bbs/man/boards/%s man/boards/%c/%s", fbname, + bname[0], bname); + system(buf); + sprintf(fh.title, "¡» %s ºëµØ°Ï", fbname); + sprintf(fh.filename, fbname); + sprintf(fh.owner, cuser.userid); + sprintf(buf, "man/boards/%c/%s/.DIR", bname[0], bname); + append_record(buf, &fh, sizeof(fh)); + sprintf(fromdir, "fpg/home/bbs/boards/%s/.DIR", fbname); + vmsg("§Y±N¶×¤J %s ª©¸ê®Æ..«öÁä«á»Ý­n¤@ÂI®É¶¡",fbname); +} diff --git a/mbbsd/record.c b/mbbsd/record.c index a11b3a56..3551ebad 100644 --- a/mbbsd/record.c +++ b/mbbsd/record.c @@ -36,24 +36,25 @@ get_sum_records(char *fpath, int size) { struct stat st; long ans = 0; - FILE *fp; + int fp; fileheader_t fhdr; char buf[200], *p; - - if (!(fp = fopen(fpath, "r"))) + + // Ptt : should avoid big loop + if ((fp = open(fpath, O_RDONLY))==-1) return -1; - + strlcpy(buf, fpath, sizeof(buf)); p = strrchr(buf, '/'); assert(p); p++; - while (fread(&fhdr, size, 1, fp) == 1) { + while (read(fp, &fhdr, size) == size) { strcpy(p, fhdr.filename); if (stat(buf, &st) == 0 && S_ISREG(st.st_mode) && st.st_nlink == 1) ans += st.st_size; } - fclose(fp); + close(fp); return ans / 1024; } @@ -426,17 +427,16 @@ safe_article_delete_range(char *direct, int from, int to) int apply_record(char *fpath, int (*fptr) (), int size){ char abuf[BUFSIZE]; - FILE *fp; + int fp; - if (!(fp = fopen(fpath, "r"))) - return -1; + if((fp=open(fpath, O_RDONLY, 0))) return -1; - while (fread(abuf, 1, size, fp) == (size_t)size) + while (read(fp, abuf, size) == (size_t)size) if ((*fptr) (abuf) == QUIT) { - fclose(fp); + close(fp); return QUIT; } - fclose(fp); + close(fp); return 0; } diff --git a/mbbsd/user.c b/mbbsd/user.c index 12fe24e4..b9f459ae 100644 --- a/mbbsd/user.c +++ b/mbbsd/user.c @@ -1589,3 +1589,4 @@ u_list() igetch(); return 0; } + diff --git a/util/merge_dir.c b/util/merge_dir.c index 304f0927..b2044050 100644 --- a/util/merge_dir.c +++ b/util/merge_dir.c @@ -12,7 +12,7 @@ fileheader_t *fh; int dir_cmp(const void *a, const void *b) { return (atoi( &((fileheader_t *)a)->filename[2] ) - - atoi( &((fileheader_t *)a)->filename[2] )); + atoi( &((fileheader_t *)b)->filename[2] )); } int main(int argc, char **argv) { -- cgit v1.2.3