summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/config.h3
-rw-r--r--include/proto.h19
-rw-r--r--mbbsd/Makefile2
-rw-r--r--mbbsd/board.c307
-rw-r--r--mbbsd/brc.c423
-rw-r--r--mbbsd/cache.c2
-rw-r--r--mbbsd/var.c6
-rw-r--r--pttbbs.mk4
8 files changed, 453 insertions, 313 deletions
diff --git a/include/config.h b/include/config.h
index 038cf992..a08bc4f7 100644
--- a/include/config.h
+++ b/include/config.h
@@ -214,9 +214,8 @@
#define ALLPOST "ALLPOST"
#define MAXTAGS 256
-#define BRC_STRLEN 15 /* Length of board name */
+#define BRC_STRLEN 15 /* Length of board name */
#define BRC_MAXSIZE 24576
-#define BRC_ITEMSIZE (BRC_STRLEN + 1 + BRC_MAXNUM * sizeof( int ))
#define BRC_MAXNUM 80
#define WRAPMARGIN (511)
diff --git a/include/proto.h b/include/proto.h
index 9851a9e0..46eab16c 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -74,10 +74,6 @@ int board_digest();
/* board */
#define setutmpbid(bid) currutmp->brc_id=bid;
-int brc_unread(const char *fname, int bnum, const int *blist);
-int brc_initial_board(const char *boardname);
-void brc_update();
-void brc_finalize();
int HasPerm(boardheader_t *bptr);
int New();
int Boards();
@@ -89,12 +85,24 @@ int validboard(int bid);
void sigfree(int);
#endif
+/* brc */
+int brc_initialize();
+void brc_finalize();
+int brc_unread(const char *fname, int bnum, const time_t *blist);
+int brc_unread_time(time_t ftime, int bnum, const time_t *blist);
+int brc_initial_board(const char *boardname);
+void brc_update();
+int brc_read_record(int bid, int *num, time_t *list);
+time_t * brc_find_record(int bid, int *num);
+void brc_trunc(int bid, time_t ftime);
+void brc_addlist(const char* fname);
+
/* cache */
int moneyof(int uid);
int getuser(char *userid);
void setuserid(int num, char *userid);
int searchuser(char *userid);
-int getbnum(char *bname);
+int getbnum(const char *bname);
void reset_board(int bid);
void touch_boards();
void addbrd_touchcache();
@@ -105,7 +113,6 @@ boardheader_t *getbcache(int bid);
int apply_boards(int (*func)(boardheader_t *));
int haspostperm(char *bname);
void inbtotal(int bid, int add);
-void brc_addlist(const char *fname);
void setbtotal(int bid);
unsigned int safe_sleep(unsigned int seconds);
int apply_ulist(int (*fptr)(userinfo_t *));
diff --git a/mbbsd/Makefile b/mbbsd/Makefile
index 7c3b6996..1a078380 100644
--- a/mbbsd/Makefile
+++ b/mbbsd/Makefile
@@ -12,7 +12,7 @@ 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\
gomo.o guess.o indict.o io.o kaede.o lovepaper.o mail.o mbbsd.o menu.o\
more.o name.o osdep.o othello.o page.o read.o record.o\
- register.o screen.o stuff.o talk.o term.o topsong.o user.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
.SUFFIXES: .c .o
diff --git a/mbbsd/board.c b/mbbsd/board.c
index 200376eb..446f1103 100644
--- a/mbbsd/board.c
+++ b/mbbsd/board.c
@@ -1,298 +1,5 @@
/* $Id$ */
#include "bbs.h"
-#define BRC_STRLEN 15 /* Length of board name */
-#define BRC_MAXSIZE 24576 /* Effective size of brc rc file */
-#define BRC_ITEMSIZE (BRC_STRLEN + 1 + BRC_MAXNUM * sizeof( int ))
- /* Maximum size of each record */
-#define BRC_MAXNUM 80 /* Upper bound of brc_num, size of brc_list */
-
-/* brc rc file form:
- * board_name 15 bytes
- * brc_num 1 byte, binary integer
- * brc_list brc_num * sizeof(int) bytes, brc_num binary integer(s) */
-
-static time_t brc_expire_time;
- /* Will be set to the time one year before login. All the files created
- * before then will be recognized read. */
-
-static int brc_changed = 0;
-/* The below two will be filled by read_brc_buf() and brc_update() */
-static char *brc_buf = NULL;
-static int brc_size;
-
-static char * const fn_boardrc = ".boardrc";
-
-static char *
-brc_getrecord(char *ptr, char *endp, char *name, int *pnum, int *list)
-{
- int num;
- char *tmp;
-
- if (ptr + BRC_STRLEN + 1 > endp) return endp + 1;
- strncpy(name, ptr, BRC_STRLEN); /* board_name */
- ptr += BRC_STRLEN;
- num = (*ptr++) & 0xff; /* brc_num */
- tmp = ptr + num * sizeof(int); /* end of this record */
- if (tmp <= endp){
- if (num > BRC_MAXNUM) /* FIXME if this happens... may crash next time. */
- num = BRC_MAXNUM;
- *pnum = num;
- memcpy(list, ptr, num * sizeof(int)); /* brc_list */
- }
- return tmp;
-}
-
-static char *
-brc_putrecord(char *ptr, char *endp, const char *name, int num, const int *list)
-{
- if (num > 0 && list[0] > brc_expire_time &&
- ptr + BRC_STRLEN + 1 <= endp) {
- if (num > BRC_MAXNUM)
- num = BRC_MAXNUM;
-
- while (num > 1 && list[num - 1] < brc_expire_time)
- num--; /* not to write the times before brc_expire_time */
-
- if( num == 0 ) return ptr;
-
- strncpy(ptr, name, BRC_STRLEN); /* write in board_name */
- ptr += BRC_STRLEN;
- *ptr++ = num; /* write in brc_num */
- if (ptr + num * sizeof(int) <= endp)
- memcpy(ptr, list, num * sizeof(int)); /* write in brc_list */
- ptr += num * sizeof(int);
- }
- return ptr;
-}
-
-static inline void
-brc_insert_record(const char* board, int num, int* list)
-{
- char *ptr, *endp, *tmpp = 0;
- char tmp_buf[BRC_ITEMSIZE];
- char tmp_name[BRC_STRLEN];
- int tmp_list[BRC_MAXNUM];
- int new_size, end_size, tmp_num;
- int found = 0;
-
- ptr = brc_buf;
- endp = &brc_buf[brc_size];
- while (ptr < endp && (*ptr >= ' ' && *ptr <= 'z')) {
- /* for each available records */
- tmpp = brc_getrecord(ptr, endp, tmp_name, &tmp_num, tmp_list);
-
- if ( tmpp > endp ){
- /* dangling, ignore the trailing data */
- brc_size = (int)(ptr - brc_buf);
- break;
- }
- if ( strncmp(tmp_name, board, BRC_STRLEN) == 0 ){
- found = 1;
- break;
- }
- ptr = tmpp;
- }
-
- if( ! found ){
- /* put on the beginning */
- ptr = brc_putrecord(tmp_buf, tmp_buf + BRC_MAXSIZE,
- board, num, list);
- new_size = (int)(ptr - tmp_buf);
- if( new_size ){
- brc_size += new_size;
- if ( brc_size > BRC_MAXSIZE )
- brc_size = BRC_MAXSIZE;
- memmove(brc_buf + new_size, brc_buf, brc_size);
- memmove(brc_buf, tmp_buf, new_size);
- }
- }else{
- /* ptr points to the old current brc list.
- * tmpp is the end of it (exclusive). */
- end_size = endp - tmpp;
- new_size = (int)(brc_putrecord(tmp_buf, tmp_buf + BRC_ITEMSIZE,
- board, num, list) - tmp_buf);
- if( new_size ){
- brc_size += new_size - (tmpp - ptr);
- if ( brc_size > BRC_MAXSIZE ){
- end_size -= brc_size - BRC_MAXSIZE;
- brc_size = BRC_MAXSIZE;
- }
- if ( end_size > 0 && ptr + new_size != tmpp )
- memmove(ptr + new_size, tmpp, end_size);
- memmove(ptr, tmp_buf, new_size);
- }else
- memmove(ptr, tmpp, brc_size - (tmpp - brc_buf));
- }
-
- brc_changed = 0;
-}
-
-void
-brc_update(){
- if (brc_changed && cuser->userlevel && brc_num > 0)
- brc_insert_record(currboard, brc_num, brc_list);
-}
-
-inline static void
-read_brc_buf()
-{
- if( brc_buf == NULL ){
- char dirfile[STRLEN];
- int fd;
-
- brc_buf = malloc(BRC_MAXSIZE);
- setuserfile(dirfile, fn_boardrc);
- if ((fd = open(dirfile, O_RDONLY)) != -1) {
- brc_size = read(fd, brc_buf, BRC_MAXSIZE);
- close(fd);
- } else {
- brc_size = 0;
- }
- }
-}
-
-void
-brc_finalize(){
- char brcfile[STRLEN];
- int fd;
- brc_update();
- setuserfile(brcfile, fn_boardrc);
- if (brc_buf != NULL &&
- (fd = open(brcfile, O_WRONLY | O_CREAT | O_TRUNC, 0644)) != -1) {
- write(fd, brc_buf, brc_size);
- close(fd);
- }
-}
-
-void
-brc_initialize(){
- static char done = 0;
- if( done )
- return;
- done = 1;
- brc_expire_time = login_start_time - 365 * 86400;
- read_brc_buf();
-}
-
-int
-brc_read_record(const char* bname, int* num, int* list){
- char *ptr;
- char *endp;
- char tmp_name[BRC_STRLEN];
- ptr = brc_buf;
- endp = &brc_buf[brc_size];
- while (ptr < endp && (*ptr >= ' ' && *ptr <= 'z')) {
- /* for each available records */
- ptr = brc_getrecord(ptr, endp, tmp_name, num, list);
- if (strncmp(tmp_name, bname, BRC_STRLEN) == 0)
- return *num;
- }
- *num = list[0] = 1;
- return 0;
-}
-
-int
-brc_initial_board(const char *boardname)
-{
- brc_initialize();
-
- if (strcmp(currboard, boardname) == 0) {
- return brc_num;
- }
-
- brc_update(); /* write back first */
- strlcpy(currboard, boardname, sizeof(currboard));
- currbid = getbnum(currboard);
- currbrdattr = bcache[currbid - 1].brdattr;
-
- return brc_read_record(boardname, &brc_num, brc_list);
-}
-
-static void
-brc_trunc(const char* brdname, int ftime){
- brc_insert_record(brdname, 1, &ftime);
- if (strncmp(brdname, currboard, BRC_STRLEN) == 0){
- brc_num = 1;
- brc_list[0] = ftime;
- brc_changed = 0;
- }
-}
-
-void
-brc_addlist(const char *fname)
-{
- int ftime, n, i;
-
- if (!cuser->userlevel)
- return;
-
- ftime = atoi(&fname[2]);
- if (ftime <= brc_expire_time /* too old, don't do any thing */
- /* || fname[0] != 'M' || fname[1] != '.' */ ) {
- return;
- }
- if (brc_num <= 0) { /* uninitialized */
- brc_list[0] = ftime;
- brc_num = 1;
- brc_changed = 1;
- return;
- }
- if ((brc_num == 1) && (ftime < brc_list[0])) /* most when after 'v' */
- return;
- for (n = 0; n < brc_num; n++) { /* using linear search */
- if (ftime == brc_list[n]) {
- return;
- } else if (ftime > brc_list[n]) {
- if (brc_num < BRC_MAXNUM)
- brc_num++;
- /* insert ftime in to brc_list */
- for (i = brc_num - 1; --i >= n; brc_list[i + 1] = brc_list[i]);
- brc_list[n] = ftime;
- brc_changed = 1;
- return;
- }
- }
-}
-
-static int
-brc_unread_time(time_t ftime, int bnum, const int *blist)
-{
- int n;
-
- if (ftime <= brc_expire_time) /* too old */
- return 0;
-
- if (brc_num <= 0)
- return 1;
- for (n = 0; n < bnum; n++) { /* using linear search */
- if (ftime > blist[n])
- return 1;
- else if (ftime == blist[n])
- return 0;
- }
- return 0;
-}
-
-int
-brc_unread(const char *fname, int bnum, const int *blist)
-{
- int ftime, n;
-
- ftime = atoi(&fname[2]); /* this will get the time of the file created */
-
- if (ftime <= brc_expire_time) /* too old */
- return 0;
-
- if (brc_num <= 0)
- return 1;
- for (n = 0; n < bnum; n++) { /* using linear search */
- if (ftime > blist[n])
- return 1;
- else if (ftime == blist[n])
- return 0;
- }
- return 0;
-}
/* personal board state
* 相對於看板的 attr (BRD_* in ../include/pttstruct.h),
@@ -343,7 +50,8 @@ void imovefav(int old)
void
init_brdbuf()
{
- brc_initialize();
+ if (brc_initialize())
+ return;
brc_initial_board(DEFAULT_BOARD);
set_board();
}
@@ -411,8 +119,9 @@ have_author(char *brdname)
static int
check_newpost(boardstat_t * ptr)
{ /* Ptt 改 */
- int tbrc_list[BRC_MAXNUM], tbrc_num;
+ int tbrc_num;
time_t ftime;
+ time_t *tbrc_list;
ptr->myattr &= ~NBRD_UNREAD;
if (B_BH(ptr)->brdattr & BRD_GROUPBOARD)
@@ -426,8 +135,8 @@ check_newpost(boardstat_t * ptr)
if (ftime > now)
ftime = B_LASTPOSTTIME(ptr) = now - 1;
- if ( brc_read_record(B_BH(ptr)->brdname, &tbrc_num, tbrc_list) == 0 ||
- brc_unread_time(ftime, tbrc_num, tbrc_list) )
+ tbrc_list = brc_find_record(ptr->bid, &tbrc_num);
+ if ( brc_unread_time(ftime, tbrc_num, tbrc_list) )
ptr->myattr |= NBRD_UNREAD;
return 1;
@@ -1298,10 +1007,10 @@ choose_board(int newflag)
break;
if (ch == 'v') {
ptr->myattr &= ~NBRD_UNREAD;
- brc_trunc(B_BH(ptr)->brdname, now);
+ brc_trunc(ptr->bid, now);
setbrdtime(ptr->bid, now);
} else {
- brc_trunc(B_BH(ptr)->brdname, 1);
+ brc_trunc(ptr->bid, 1);
setbrdtime(ptr->bid, 1);
ptr->myattr |= NBRD_UNREAD;
}
diff --git a/mbbsd/brc.c b/mbbsd/brc.c
new file mode 100644
index 00000000..cb5432cc
--- /dev/null
+++ b/mbbsd/brc.c
@@ -0,0 +1,423 @@
+#include "bbs.h"
+
+#ifndef BRC_MAXNUM
+#define BRC_STRLEN 15 /* Length of board name */
+#define BRC_MAXSIZE 24576 /* Effective size of brc rc file, 8192 * 3 */
+#define BRC_MAXNUM 80 /* Upper bound of brc_num, size of brc_list */
+#endif
+
+#define BRC_BLOCKSIZE 1024
+
+#if MAX_BOARD > 32767 || BRC_MAXSIZE > 32767
+#error Max number of boards or BRC_MAXSIZE cannot fit in unsighed short, \
+please rewrite brc.c
+#endif
+
+typedef unsigned short brcbid_t;
+typedef unsigned short brcnbrd_t;
+
+/* old brc rc file form:
+ * board_name 15 bytes
+ * brc_num 1 byte, binary integer
+ * brc_list brc_num * sizeof(int) bytes, brc_num binary integer(s) */
+
+static time_t brc_expire_time;
+ /* Will be set to the time one year before login. All the files created
+ * before then will be recognized read. */
+
+static int brc_changed = 0;
+/* The below two will be filled by read_brc_buf() and brc_update() */
+static char *brc_buf = NULL;
+static int brc_size;
+static int brc_alloc;
+
+static char * const fn_oldboardrc = ".boardrc";
+static char * const fn_brc = ".brc2";
+
+#if 0
+/* unused after brc2 */
+static char *
+brc_getrecord(char *ptr, char *endp, brcbid_t *bid, brcnbrd_t *pnum, time_t *list)
+{
+ brcnbrd_t num;
+ char *tmp;
+
+ if (ptr + sizeof(brcbid_t) + sizeof(brcnbrd_t) > endp)
+ return endp + 1; /* dangling, ignoring it */
+ *bid = *(brcbid_t*)ptr; /* bid */
+ ptr += sizeof(brcbid_t);
+ num = *(brcnbrd_t*)ptr; /* brc_num */
+ ptr += sizeof(brcnbrd_t);
+ tmp = ptr + num * sizeof(time_t); /* end of this record */
+ if (tmp <= endp){
+ memcpy(list, ptr, num * sizeof(time_t)); /* brc_list */
+ if (num > BRC_MAXNUM)
+ num = BRC_MAXNUM;
+ *pnum = num;
+ }
+ return tmp;
+}
+#endif
+
+/* Returns the address of the record strictly between begin and endp with
+ * bid equal to the parameter. Returns 0 if not found.
+ * brcnbrd_t *num is an output parameter which will filled with brc_num
+ * if the record is found. If not found the record, *num will be the number
+ * of dangling bytes. */
+static char *
+brc_findrecord_in(char *begin, char *endp, brcbid_t bid, brcnbrd_t *num)
+{
+ char *tmpp, *ptr = begin;
+ brcbid_t tbid;
+ while (ptr + sizeof(brcbid_t) + sizeof(brcnbrd_t) < endp) {
+ /* for each available records */
+ tmpp = ptr;
+ tbid = *(brcbid_t*)tmpp;
+ tmpp += sizeof(brcbid_t);
+ *num = *(brcnbrd_t*)tmpp;
+ tmpp += sizeof(brcnbrd_t) + *num * sizeof(time_t); /* end of record */
+
+ if ( tmpp > endp ){
+ /* dangling, ignore the trailing data */
+ *num = (brcnbrd_t)(endp - ptr); /* for brc_insert_record() */
+ return 0;
+ }
+ if ( tbid == bid )
+ return ptr;
+ ptr = tmpp;
+ }
+
+ *num = 0;
+ return 0;
+}
+
+time_t *
+brc_find_record(int bid, int *num)
+{
+ char *p;
+ *num = 0;
+ p = brc_findrecord_in(brc_buf, brc_buf + brc_size, bid, (brcnbrd_t*)num);
+ if (p)
+ return (time_t*)(p + sizeof(brcbid_t) + sizeof(brcnbrd_t));
+ *num = 0;
+ return 0;
+}
+
+static char *
+brc_putrecord(char *ptr, char *endp, brcbid_t bid, brcnbrd_t num, const time_t *list)
+{
+ char * tmp;
+ if (num > 0 && list[0] > brc_expire_time &&
+ ptr + sizeof(brcbid_t) + sizeof(brcnbrd_t) <= endp) {
+ if (num > BRC_MAXNUM)
+ num = BRC_MAXNUM;
+
+ while (num > 0 && list[num - 1] < brc_expire_time)
+ num--; /* don't write the times before brc_expire_time */
+
+ if (num == 0) return ptr;
+
+ *(brcbid_t*)ptr = bid; /* write in bid */
+ ptr += sizeof(brcbid_t);
+ *(brcnbrd_t*)ptr = num; /* write in brc_num */
+ ptr += sizeof(brcnbrd_t);
+ tmp = ptr + num * sizeof(time_t);
+ if (tmp <= endp)
+ memcpy(ptr, list, num * sizeof(time_t)); /* write in brc_list */
+ ptr = tmp;
+ }
+ return ptr;
+}
+
+static inline int
+brc_enlarge_buf()
+{
+ char buffer[BRC_MAXSIZE - BRC_BLOCKSIZE];
+ if (brc_alloc >= BRC_MAXSIZE)
+ return 0;
+ memcpy(buffer, brc_buf, brc_alloc);
+ free(brc_buf);
+ brc_alloc += BRC_BLOCKSIZE;
+ brc_buf = (char*)malloc(brc_alloc);
+ memcpy(brc_buf, buffer, brc_alloc - BRC_BLOCKSIZE);
+ return 1;
+}
+
+static inline void
+brc_get_buf(int size){
+ if (!size)
+ brc_alloc = BRC_BLOCKSIZE;
+ else
+ brc_alloc = (size + BRC_BLOCKSIZE - 1) / BRC_BLOCKSIZE * BRC_BLOCKSIZE;
+ if (brc_alloc > BRC_MAXSIZE)
+ brc_alloc = BRC_MAXSIZE;
+ brc_buf = (char*)malloc(brc_alloc);
+}
+
+static inline void
+brc_insert_record(brcbid_t bid, brcnbrd_t num, time_t* list)
+{
+ char *ptr;
+ int new_size, end_size;
+ brcnbrd_t tnum;
+
+ ptr = brc_findrecord_in(brc_buf, brc_buf + brc_size, bid, &tnum);
+
+ /* FIXME: this loop is copied from brc_putrecord() */
+ while (num > 0 && list[num - 1] < brc_expire_time)
+ num--; /* don't write the times before brc_expire_time */
+
+ if (!ptr) {
+ brc_size -= tnum;
+
+ /* put on the beginning */
+ if (num && (new_size =
+ sizeof(brcbid_t) + sizeof(brcnbrd_t) + num * sizeof(time_t))){
+ brc_size += new_size;
+ if (brc_size > brc_alloc && !brc_enlarge_buf())
+ brc_size = BRC_MAXSIZE;
+ if (brc_size > new_size)
+ memmove(brc_buf + new_size, brc_buf, brc_size - new_size);
+ brc_putrecord(brc_buf, brc_buf + new_size, bid, num, list);
+ }
+ } else {
+ /* ptr points to the old current brc list.
+ * tmpp is the end of it (exclusive). */
+ char *tmpp = ptr + sizeof(brcbid_t) + sizeof(brcnbrd_t)
+ + tnum * sizeof(time_t);
+ end_size = brc_buf + brc_size - tmpp;
+ if (num) {
+ new_size = sizeof(brcbid_t) + sizeof(brcnbrd_t)
+ + num * sizeof(time_t);
+ brc_size += new_size - (tmpp - ptr);
+ if (brc_size > brc_alloc && ! brc_enlarge_buf() ) {
+ end_size -= brc_size - BRC_MAXSIZE;
+ brc_size = BRC_MAXSIZE;
+ }
+ if (end_size > 0 && ptr + new_size != tmpp)
+ memmove(ptr + new_size, tmpp, end_size);
+ brc_putrecord(ptr, brc_buf + brc_alloc, bid, num, list);
+ } else { /* deleting record */
+ memmove(ptr, tmpp, end_size);
+ brc_size -= (tmpp - ptr);
+ }
+ }
+
+ brc_changed = 0;
+}
+
+void
+brc_update(){
+ if (brc_changed && cuser->userlevel && brc_num > 0)
+ brc_insert_record(currbid, brc_num, brc_list);
+}
+
+/* return 1 if successfully read from old .boardrc file.
+ * otherwise, return 0. */
+inline static void
+read_old_brc(int fd)
+{
+ char brdname[BRC_STRLEN + 1];
+ char *ptr;
+ brcnbrd_t num;
+ brcbid_t bid;
+ brcbid_t read_brd[512];
+ int nRead = 0, i;
+
+ ptr = brc_buf;
+ brc_size = 0;
+ while (read(fd, brdname, BRC_STRLEN + 1) == BRC_STRLEN + 1) {
+ num = brdname[BRC_STRLEN];
+ brdname[BRC_STRLEN] = 0;
+ bid = getbnum(brdname);
+
+ for (i = 0; i < nRead; ++i)
+ if (read_brd[i] == bid)
+ break;
+ if (i != nRead){
+ lseek(fd, num * sizeof(int), SEEK_CUR);
+ continue;
+ }
+ read_brd[nRead >= 512 ? nRead = 0 : nRead++] = bid;
+
+ *(brcbid_t*)ptr = bid;
+ ptr += sizeof(brcbid_t);
+ *(brcnbrd_t*)ptr = num;
+ ptr += sizeof(brcnbrd_t);
+ if (read(fd, ptr, sizeof(int) * num) != sizeof(int) * num)
+ break;
+
+ brc_size += sizeof(brcbid_t) + sizeof(brcnbrd_t)
+ + sizeof(time_t) * num;
+ ptr += sizeof(time_t) * num;
+ }
+}
+
+inline static void
+read_brc_buf()
+{
+ if (brc_buf == NULL) {
+ char brcfile[STRLEN];
+ int fd;
+ struct stat brcstat;
+
+ setuserfile(brcfile, fn_brc);
+ if ((fd = open(brcfile, O_RDONLY)) != -1) {
+ fstat(fd, &brcstat);
+ brc_get_buf(brcstat.st_size);
+ brc_size = read(fd, brc_buf, brc_alloc);
+ close(fd);
+ } else {
+ setuserfile(brcfile, fn_oldboardrc);
+ if ((fd = open(brcfile, O_RDONLY)) != -1) {
+ fstat(fd, &brcstat);
+ brc_get_buf(brcstat.st_size);
+ read_old_brc(fd);
+ close(fd);
+ } else
+ brc_size = 0;
+ }
+ }
+}
+
+void
+brc_finalize(){
+ char brcfile[STRLEN];
+ int fd;
+ brc_update();
+ setuserfile(brcfile, fn_brc);
+ if (brc_buf != NULL &&
+ (fd = open(brcfile, O_WRONLY | O_CREAT | O_TRUNC, 0644)) != -1) {
+ write(fd, brc_buf, brc_size);
+ close(fd);
+ }
+}
+
+int
+brc_initialize(){
+ static char done = 0;
+ if (done)
+ return 1;
+ done = 1;
+ brc_expire_time = login_start_time - 365 * 86400;
+ read_brc_buf();
+ return 0;
+}
+
+int
+brc_read_record(int bid, int *num, time_t *list){
+ char *ptr;
+ *num = 0;
+ ptr = brc_findrecord_in(brc_buf, brc_buf + brc_size, bid, (brcnbrd_t*)num);
+ if ( ptr ){
+ memcpy(list, ptr + sizeof(brcbid_t) + sizeof(brcnbrd_t),
+ *num * sizeof(time_t));
+ return *num;
+ }
+ list[0] = *num = 1;
+ return 0;
+}
+
+int
+brc_initial_board(const char *boardname)
+{
+ brc_initialize();
+
+ if (strcmp(currboard, boardname) == 0) {
+ return brc_num;
+ }
+
+ brc_update(); /* write back first */
+ currbid = getbnum(boardname);
+ currboard = bcache[currbid - 1].brdname;
+ currbrdattr = bcache[currbid - 1].brdattr;
+
+ return brc_read_record(currbid, &brc_num, brc_list);
+}
+
+void
+brc_trunc(int bid, time_t ftime){
+ brc_insert_record(bid, 1, &ftime);
+ if ( bid == currbid ){
+ brc_num = 1;
+ brc_list[0] = ftime;
+ brc_changed = 0;
+ }
+}
+
+void
+brc_addlist(const char *fname)
+{
+ int n, i;
+ time_t ftime;
+
+ if (!cuser->userlevel)
+ return;
+
+ ftime = atoi(&fname[2]);
+ if (ftime <= brc_expire_time /* too old, don't do any thing */
+ /* || fname[0] != 'M' || fname[1] != '.' */ ) {
+ return;
+ }
+ if (brc_num <= 0) { /* uninitialized */
+ brc_list[0] = ftime;
+ brc_num = 1;
+ brc_changed = 1;
+ return;
+ }
+ if ((brc_num == 1) && (ftime < brc_list[0])) /* most when after 'v' */
+ return;
+ for (n = 0; n < brc_num; n++) { /* using linear search */
+ if (ftime == brc_list[n]) {
+ return;
+ } else if (ftime > brc_list[n]) {
+ if (brc_num < BRC_MAXNUM)
+ brc_num++;
+ /* insert ftime into brc_list */
+ for (i = brc_num - 1; --i >= n; brc_list[i + 1] = brc_list[i]);
+ brc_list[n] = ftime;
+ brc_changed = 1;
+ return;
+ }
+ }
+}
+
+int
+brc_unread_time(time_t ftime, int bnum, const time_t *blist)
+{
+ int n;
+
+ if (ftime <= brc_expire_time) /* too old */
+ return 0;
+
+ if (bnum <= 0)
+ return 1;
+ for (n = 0; n < bnum; n++) { /* using linear search */
+ if (ftime > blist[n])
+ return 1;
+ else if (ftime == blist[n])
+ return 0;
+ }
+ return 0;
+}
+
+int
+brc_unread(const char *fname, int bnum, const time_t *blist)
+{
+ int ftime, n;
+
+ ftime = atoi(&fname[2]); /* this will get the time of the file created */
+
+ if (ftime <= brc_expire_time) /* too old */
+ return 0;
+
+ if (bnum <= 0)
+ return 1;
+ for (n = 0; n < bnum; n++) { /* using linear search */
+ if (ftime > blist[n])
+ return 1;
+ else if (ftime == blist[n])
+ return 0;
+ }
+ return 0;
+}
diff --git a/mbbsd/cache.c b/mbbsd/cache.c
index bac961cb..67a405d3 100644
--- a/mbbsd/cache.c
+++ b/mbbsd/cache.c
@@ -733,7 +733,7 @@ touchbpostnum(int bid, int delta)
}
int
-getbnum(char *bname)
+getbnum(const char *bname)
{
register int i = 0, j, start = 0, end = SHM->Bnumber - 1;
register boardheader_t **bhdr;
diff --git a/mbbsd/var.c b/mbbsd/var.c
index 4c7a29dc..526f5824 100644
--- a/mbbsd/var.c
+++ b/mbbsd/var.c
@@ -87,7 +87,7 @@ char vetitle[TTLEN + 1] = "\0";
char currowner[IDLEN + 2] = "\0";
char currauthor[IDLEN + 2] = "\0";
char currfile[FNLEN];/* current file name @ bbs.c mail.c */
-char currboard[IDLEN + 2];
+char *currboard = "\0";
char currBM[IDLEN * 3 + 10];
char reset_color[4] = "\033[m";
char margs[64] = "\0"; /* main argv list */
@@ -361,8 +361,10 @@ userinfo_t *currutmp;
/* board.c */
int class_bid = 0;
+
+/* brc.c */
int brc_num;
-int brc_list[BRC_MAXNUM];
+time_t brc_list[BRC_MAXNUM];
/* read.c */
int TagNum; /* tag's number */
diff --git a/pttbbs.mk b/pttbbs.mk
index 3149af23..1c44aed7 100644
--- a/pttbbs.mk
+++ b/pttbbs.mk
@@ -7,7 +7,7 @@ CC?= gcc
CCACHE!= which ccache|sed -e 's/^.*\///'
PTT_CFLAGS= -Wall -pipe -DBBSHOME='"$(BBSHOME)"' -I../include
PTT_LDFLAGS= -pipe -Wall -L/usr/local/lib
-PTT_LIBS= -lcrypt -lhz -liconv
+PTT_LIBS= -lcrypt -lhz
# enable assert()
#PTT_CFLAGS+= -DNDEBUG
@@ -15,7 +15,7 @@ PTT_LIBS= -lcrypt -lhz -liconv
# FreeBSD特有的環境
CFLAGS_FreeBSD= -DHAVE_SETPROCTITLE -DFreeBSD -I/usr/local/include
LDFLAGS_FreeBSD=
-LIBS_FreeBSD= -lkvm
+LIBS_FreeBSD= -lkvm -liconv
# Linux特有的環境
# CFLAGS_linux= -DHAVE_DES_CRYPT -DLinux