diff options
-rw-r--r-- | docs/brc.txt | 19 | ||||
-rw-r--r-- | include/pttstruct.h | 4 | ||||
-rw-r--r-- | mbbsd/bbs.c | 127 | ||||
-rw-r--r-- | mbbsd/board.c | 8 | ||||
-rw-r--r-- | mbbsd/brc.c | 225 | ||||
-rw-r--r-- | sample/pttbbs.conf | 3 |
6 files changed, 213 insertions, 173 deletions
diff --git a/docs/brc.txt b/docs/brc.txt index 315a1fbc..d64f7918 100644 --- a/docs/brc.txt +++ b/docs/brc.txt @@ -1,6 +1,7 @@ - BRC documentation by scw 08/05/2003 + BRC (v2) documentation by scw 08/05/2003 06/12/2007 revised by kcwu + 12/02/2007 v3 by piaip 源起: 這篇文章主要是介紹 brc_* 的函式,這組函式是 pttbbs 用來紀錄文章已讀/未讀 @@ -43,8 +44,22 @@ BRC 是什麼?如何運作? 個人看的板太多,讓 .brc2 大小超過 BRC_MAXSIZE 有些板的紀錄就會不見( 24576 bytes 最少可以存 73 個板的資料,這還是用全部板 brc_num 都是 80 計算的)。但這 三個小缺點影響應該不大吧? + +v3 說明 + + Dec 2007 開始 ptt brc 引入 v3 格式,與前板不相容。所謂的 v3 是由於 BBS + 「推文」系統被濫用而產生的需求。推文的形式是在原文後附加新的一行文,但舊 + BRC 系統無法分辨此類更動;若想讓人分辨是否有新推文各家作法不一,常見的是比 + 照 edit_post 把檔案改名。這種方式除了效率不彰外,還有並非每個人都想看新推文 + 的問題。 + 考量許久後,從 BRC 下手還是正解。 在每個 BRC 記錄上多新增一個 modified + time 即可。 此方法可同時適用於分離檔案與原文附加的推文系統。代價是 BRC 大小 + 加倍成長,不過這似乎不是什麼大問題。 + 由於 v2 v3 實際差異並不大,這裡的說明保留以 v2 為主。 麻煩自己查 svn + 就知道 v3 改了哪邊了。 + -BRC 實作 +BRC v2 實作 interface: (in proto.h) diff --git a/include/pttstruct.h b/include/pttstruct.h index ee0512fc..dfc6dc2f 100644 --- a/include/pttstruct.h +++ b/include/pttstruct.h @@ -253,8 +253,8 @@ typedef struct boardheader_t { #define FNLEN 28 /* Length of filename */ typedef struct fileheader_t { - char filename[FNLEN]; /* M.1120582370.A.1EA [19+1] */ - int textlen; /* main text length in post */ + char filename[FNLEN]; /* M.1120582370.A.1EA [19+1], create time */ + time4_t modified; /* last modified time */ char pad; /* padding, not used */ char recommend; /* important level */ char owner[IDLEN + 2]; /* uid[.] */ diff --git a/mbbsd/bbs.c b/mbbsd/bbs.c index 86fc5d79..80a7bec2 100644 --- a/mbbsd/bbs.c +++ b/mbbsd/bbs.c @@ -317,10 +317,23 @@ readtitle(void) static void readdoent(int num, fileheader_t * ent) { - int type; + int type = ' '; char *mark, *title, color, special = 0, isonline = 0, recom[8]; - type = brc_unread(currbid, ent->filename) ? '+' : ' '; + + // type = brc_unread(currbid, ent->filename) ? '+' : ' '; + switch (brc_unread(currbid, ent->filename, ent->modified)) + { + case 1: // unread + type = '+'; + break; + case 2: // unread (modified) + type = '~'; + break; + default: + break; + } + if ((currmode & MODE_BOARD) && (ent->filemode & FILE_DIGEST)) type = (type == ' ') ? '*' : '#'; else if (currmode & MODE_BOARD || HasUserPerm(PERM_LOGINOK)) { @@ -921,15 +934,7 @@ do_general(int isbid) else if(!isbid) { /* general article */ -#ifdef USE_TEXTLEN - struct stat st; - - if (stat(fpath, &st) != -1) - { - /* put original file (text) length. */ - postfile.textlen = st.st_size; - } -#endif + postfile.modified = dasht(fpath); postfile.multi.money = aborted; } @@ -978,7 +983,7 @@ do_general(int isbid) #endif outgo_post(&postfile, currboard, cuser.userid, cuser.nickname); } - brc_addlist(postfile.filename); + brc_addlist(postfile.filename, postfile.modified); if( !bp->level || (currbrdattr & BRD_POSTMASK)) { @@ -1261,7 +1266,6 @@ edit_post(int ent, fileheader_t * fhdr, const char *direct) char genbuf[200]; fileheader_t postfile; boardheader_t *bp = getbcache(currbid); - struct stat oldstat, newstat; int isSysop = 0, recordTouched = 0; assert(0<=currbid-1 && currbid-1<MAX_BOARD); @@ -1291,60 +1295,19 @@ edit_post(int ent, fileheader_t * fhdr, const char *direct) setdirpath(genbuf, direct, fhdr->filename); local_article = fhdr->filemode & FILE_LOCAL; -#ifdef USE_TEXTLEN - if(fhdr->textlen > 0) - { - /* TODO SYSOP may need some function to edit entire file. */ - CopyN(genbuf, fpath, fhdr->textlen); - } - else -#endif - { - Copy(genbuf, fpath); - } - + Copy(genbuf, fpath); strlcpy(save_title, fhdr->title, sizeof(save_title)); do { - stat(genbuf, &oldstat); + time4_t oldmt, newmt; + oldmt = dasht(genbuf); if (vedit(fpath, 0, NULL) == -1) break; - stat(genbuf, &newstat); - - /* check textlen */ - if(fhdr->textlen > 0) - { - int gotnewstat = -1; - -#ifdef USE_TEXTLEN - /* TODO should we reload textlen info? - * multiple editing will make textlen invalid. */ - if(fhdr->textlen != newstat.st_size) - { -#ifdef DEBUG - vmsg("textlen != st_size, append tail."); -#endif - gotnewstat = stat(fpath, &newstat); - - /* copy from old content. */ - AppendTail(genbuf, fpath, fhdr->textlen); - } else { - gotnewstat = stat(fpath, &newstat); - } -#endif - - /* now update the record. */ - if(gotnewstat != -1) - fhdr->textlen = newstat.st_size; - else - fhdr->textlen = 0; - - recordTouched = 1; + newmt = dasht(genbuf); - } else /* old flavor, no textlen info */ - if (oldstat.st_mtime != newstat.st_mtime) + if (oldmt != newmt) { if (tolower(getans( "檔案已被別人修改過,要覆蓋\掉它嗎 [Y/n]?")) == 'n') @@ -1370,11 +1333,10 @@ edit_post(int ent, fileheader_t * fhdr, const char *direct) { int c = 0; struct tm *ptime; - time4_t xt = (time4_t)newstat.st_mtime; fprintf(fp, MSG_SEPERATOR "\n"); fprintf(fp, "以下為被別人修改過的最新內容: "); - ptime = localtime4(&xt); + ptime = localtime4(&newmt); fprintf(fp, " (%02d/%02d %02d:%02d)\n", ptime->tm_mon + 1, ptime->tm_mday, @@ -1391,6 +1353,14 @@ edit_post(int ent, fileheader_t * fhdr, const char *direct) Rename(fpath, genbuf); + // this is almost always true... + // whatever. + { + time4_t oldm = fhdr->modified; + fhdr->modified = dasht(genbuf); + recordTouched = (oldm == fhdr->modified) ? 1 : 0; + } + if(strcmp(save_title, fhdr->title)){ // Ptt: here is the black hole problem // (try getindex) @@ -1661,7 +1631,7 @@ read_post(int ent, fileheader_t * fhdr, const char *direct) else STATINC(STAT_READPOST_OLD); } - brc_addlist(fhdr->filename); + brc_addlist(fhdr->filename, fhdr->modified); strlcpy(currtitle, subject(fhdr->title), sizeof(currtitle)); switch(more_result) @@ -2094,24 +2064,37 @@ do_add_recommend(const char *direct, fileheader_t *fhdr, /* This is a solution to avoid most racing (still some), but cost four * system calls. */ + if(type == 0 && fhdr->recommend < 100 ) update = 1; else if(type == 1 && fhdr->recommend > -100) update = -1; + + // since we want to do 'modification'... + fhdr->modified = dasht(path); - if( update ){ + if( /* update */ 1){ int fd; + //Ptt: update only necessary if( (fd = open(direct, O_RDWR)) < 0 ) return -1; - if( lseek(fd, (sizeof(fileheader_t) * (ent - 1) + - (char *)&fhdr->recommend - (char *)fhdr), - SEEK_SET) >= 0 ){ + + if (lseek(fd, (sizeof(fileheader_t) * (ent-1) + + (char*)&fhdr->modified - (char*)fhdr), SEEK_SET) >= 0) + { + write(fd, &fhdr->modified, sizeof(fhdr->modified)); + } + + if( update && + lseek(fd, (sizeof(fileheader_t) * (ent - 1) + + (char *)&fhdr->recommend - (char *)fhdr), + SEEK_SET) >= 0 ){ // 如果 lseek 失敗就不會 write - read(fd, &fhdr->recommend, sizeof(char)); + read(fd, &fhdr->recommend, sizeof(fhdr->recommend)); fhdr->recommend += update; lseek(fd, -1, SEEK_CUR); - write(fd, &fhdr->recommend, sizeof(char)); + write(fd, &fhdr->recommend, sizeof(fhdr->recommend)); } close(fd); } @@ -2419,7 +2402,12 @@ recommend(int ent, fileheader_t * fhdr, const char *direct) // owner recommend type = 2; move(b_lines-1, 0); clrtoeol(); +#ifndef OLDRECOMMEND + outs("作者本人, 使用 → 加註方式\n"); +#else outs("作者本人首推, 使用 → 加註方式\n"); +#endif + } #ifndef DEBUG else if (!(currmode & MODE_BOARD) && @@ -3662,7 +3650,8 @@ const onekey_t read_comms[] = { { 1, push_bottom }, // Ctrl('Z') 26 { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, - { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, + { 1, recommend }, // '%' (m3itoc style) + { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, diff --git a/mbbsd/board.c b/mbbsd/board.c index 7338b85a..85103397 100644 --- a/mbbsd/board.c +++ b/mbbsd/board.c @@ -200,7 +200,7 @@ check_newpost(boardstat_t * ptr) if (ftime > now + 10) ftime = B_LASTPOSTTIME(ptr) = now - 1; - if ( brc_unread_time(ptr->bid, ftime) ) + if ( brc_unread_time(ptr->bid, ftime, 0) ) ptr->myattr |= NBRD_UNREAD; return 1; @@ -243,6 +243,7 @@ addnewbrdstat(int n, int state) { boardstat_t *ptr; + // if(n == -32769) return 0; // ptt 2 local modification XXX who wrote this? and why? 請自首! assert(0<=n && n<MAX_BOARD); assert(0<=brdnum && brdnum<nbrdsize); ptr = &nbrd[brdnum++]; @@ -353,6 +354,7 @@ load_boards(char *key) state |= NBRD_TAG; if (is_set_attr(&fav->favh[i], FAVH_ADM_TAG)) state |= NBRD_TAG; + // 有些人 某些 bid < 0 Orzz // ptt2 local modification if (fav_getid(&fav->favh[i]) < 1) continue; addnewbrdstat(fav_getid(&fav->favh[i]) - 1, NBRD_FAV | state); @@ -497,7 +499,7 @@ unread_position(char *dirfile, boardstat_t * ptr) while (num > 0) { lseek(fd, (off_t) (num * sizeof(fh)), SEEK_SET); if (read(fd, fname, FNLEN) <= 0 || - !brc_unread(ptr->bid, fname)) + !brc_unread(ptr->bid, fname, 0)) break; num -= step; if (step < 32) @@ -508,7 +510,7 @@ unread_position(char *dirfile, boardstat_t * ptr) while (num < total) { lseek(fd, (off_t) (num * sizeof(fh)), SEEK_SET); if (read(fd, fname, FNLEN) <= 0 || - brc_unread(ptr->bid, fname)) + brc_unread(ptr->bid, fname, 0)) break; num++; } diff --git a/mbbsd/brc.c b/mbbsd/brc.c index 6e069449..da18c2a0 100644 --- a/mbbsd/brc.c +++ b/mbbsd/brc.c @@ -3,11 +3,13 @@ /** * 關於本檔案的細節,請見 docs/brc.txt。 + * v3: add last modified time for comment system. double max size. + * original time_t as 'create'. */ #ifndef BRC_MAXNUM #define BRC_STRLEN 15 /* Length of board name, for old brc */ -#define BRC_MAXSIZE 24576 /* Effective size of brc rc file, 8192 * 3 */ +#define BRC_MAXSIZE 49152 /* Effective size of brc rc file, 8192 * 3 * 2 */ #define BRC_MAXNUM 80 /* Upper bound of brc_num, size of brc_list */ #endif @@ -21,10 +23,15 @@ please rewrite brc.c typedef unsigned short brcbid_t; typedef unsigned short brcnbrd_t; +typedef struct { + time4_t create; + time4_t modified; +} brc_rec; + /* 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) */ + * brc_list brc_num * sizeof(brc_rec) bytes */ static char brc_initialized = 0; static time4_t brc_expire_time; @@ -40,10 +47,10 @@ static int brc_alloc; // read records for currbid static int brc_currbid; static int brc_num; -static time4_t brc_list[BRC_MAXNUM]; +static brc_rec brc_list[BRC_MAXNUM]; -static char * const fn_oldboardrc = ".boardrc"; -static char * const fn_brc = ".brc2"; +static char * const fn_brc2= ".brc2"; +static char * const fn_brc = ".brc3"; /** * find read records of bid in given buffer region @@ -74,7 +81,7 @@ brc_findrecord_in(char *begin, char *endp, brcbid_t bid, brcnbrd_t *num) tbid = *(brcbid_t*)tmpp; tmpp += sizeof(brcbid_t); *num = *(brcnbrd_t*)tmpp; - tmpp += sizeof(brcnbrd_t) + *num * sizeof(time4_t); /* end of record */ + tmpp += sizeof(brcnbrd_t) + *num * sizeof(brc_rec); /* end of record */ if ( tmpp > endp ){ /* dangling, ignore the trailing data */ @@ -90,7 +97,7 @@ brc_findrecord_in(char *begin, char *endp, brcbid_t bid, brcnbrd_t *num) return 0; } -static time4_t * +static brc_rec * brc_find_record(int bid, int *num) { char *p; @@ -98,17 +105,17 @@ brc_find_record(int bid, int *num) p = brc_findrecord_in(brc_buf, brc_buf + brc_size, bid, &tnum); *num = tnum; if (p) - return (time4_t*)(p + sizeof(brcbid_t) + sizeof(brcnbrd_t)); + return (brc_rec*)(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 time4_t *list) + brcnbrd_t num, const brc_rec *list) { char * tmp; - if (num > 0 && list[0] > brc_expire_time && + if (num > 0 && list[0].create > brc_expire_time && ptr + sizeof(brcbid_t) + sizeof(brcnbrd_t) < endp) { if (num > BRC_MAXNUM) num = BRC_MAXNUM; @@ -119,9 +126,9 @@ brc_putrecord(char *ptr, char *endp, brcbid_t bid, ptr += sizeof(brcbid_t); *(brcnbrd_t*)ptr = num; /* write in brc_num */ ptr += sizeof(brcnbrd_t); - tmp = ptr + num * sizeof(time4_t); + tmp = ptr + num * sizeof(brc_rec); if (tmp <= endp) - memcpy(ptr, list, num * sizeof(time4_t)); /* write in brc_list */ + memcpy(ptr, list, num * sizeof(brc_rec)); /* write in brc_list */ ptr = tmp; } return ptr; @@ -178,7 +185,7 @@ brc_get_buf(int size){ } static inline void -brc_insert_record(brcbid_t bid, brcnbrd_t num, const time4_t* list) +brc_insert_record(brcbid_t bid, brcnbrd_t num, const brc_rec* list) { char *ptr; int new_size, end_size; @@ -186,7 +193,7 @@ brc_insert_record(brcbid_t bid, brcnbrd_t num, const time4_t* list) ptr = brc_findrecord_in(brc_buf, brc_buf + brc_size, bid, &tnum); - while (num > 0 && list[num - 1] < brc_expire_time) + while (num > 0 && list[num - 1].create < brc_expire_time) num--; /* don't write the times before brc_expire_time */ if (!ptr) { @@ -195,7 +202,7 @@ brc_insert_record(brcbid_t bid, brcnbrd_t num, const time4_t* list) /* put on the beginning */ if (num){ new_size = sizeof(brcbid_t) + sizeof(brcnbrd_t) - + num * sizeof(time4_t); + + num * sizeof(brc_rec); brc_size += new_size; if (brc_size > brc_alloc && !brc_enlarge_buf()) brc_size = BRC_MAXSIZE; @@ -206,13 +213,13 @@ brc_insert_record(brcbid_t bid, brcnbrd_t num, const time4_t* list) } else { /* ptr points to the old current brc list. * tmpp is the end of it (exclusive). */ - int len = sizeof(brcbid_t) + sizeof(brcnbrd_t) + tnum * sizeof(time4_t); + int len = sizeof(brcbid_t) + sizeof(brcnbrd_t) + tnum * sizeof(brc_rec); char *tmpp = ptr + len; end_size = brc_buf + brc_size - tmpp; if (num) { int sindex = ptr - brc_buf; new_size = (sizeof(brcbid_t) + sizeof(brcnbrd_t) - + num * sizeof(time4_t)); + + num * sizeof(brc_rec)); brc_size += new_size - len; if (brc_size > brc_alloc) { if (brc_enlarge_buf()) { @@ -246,72 +253,78 @@ brc_update(){ } } -/* return 1 if successfully read from old .boardrc file. - * otherwise, return 0. */ -inline static void -read_old_brc(int fd) +static void +read_brc2(void) { - 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; + char brcfile[STRLEN]; + int fd; + size_t sz2 = 0, sz3 = 0; + char *cvt = NULL, *cvthead = NULL; - *(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) + brcbid_t bid; + brcnbrd_t num; + time4_t create; + brc_rec rec; + + setuserfile(brcfile, fn_brc2); + + if ((fd = open(brcfile, O_RDONLY)) == -1) + return; + + sz2 = dashs(brcfile); + sz3 = sz2 * 2; // max double size + + cvthead = cvt = malloc (sz3); + // now calculate real sz3 + + while (read(fd, &bid, sizeof(bid)) > 0) + { + if (read(fd, &num, sizeof(num)) < 1) break; - brc_size += sizeof(brcbid_t) + sizeof(brcnbrd_t) - + sizeof(time4_t) * num; - ptr += sizeof(time4_t) * num; + *(brcbid_t*)cvt = bid; cvt += sizeof(brcbid_t); + *(brcnbrd_t*)cvt = num;cvt += sizeof(brcnbrd_t); + for (; num > 0; num--) + { + read(fd, &create, sizeof(create)); + rec.create = create; + rec.modified = create; + *(brc_rec*)cvt = rec; cvt += sizeof(brc_rec); + } } + close(fd); + + // now cvthead is ready for v3. + brc_get_buf(sz3); + brc_size = sz3; + memcpy(brc_buf, cvthead, sz3); + + free(cvthead); } inline static void read_brc_buf(void) { - 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; - } + char brcfile[STRLEN]; + int fd; + struct stat brcstat; + + if (brc_buf != NULL) + return; + + brc_size = 0; + setuserfile(brcfile, fn_brc); + + if ((fd = open(brcfile, O_RDONLY)) == -1) + { + read_brc2(); + return; } + + fstat(fd, &brcstat); + brc_get_buf(brcstat.st_size); + brc_size = read(fd, brc_buf, brc_alloc); + close(fd); } /* release allocated memory @@ -379,7 +392,7 @@ brc_initialize(){ * @return number of read record, 0 if no records */ static int -brc_read_record(int bid, int *num, time4_t *list){ +brc_read_record(int bid, int *num, brc_rec *list){ char *ptr; brcnbrd_t tnum; ptr = brc_findrecord_in(brc_buf, brc_buf + brc_size, bid, &tnum); @@ -387,10 +400,10 @@ brc_read_record(int bid, int *num, time4_t *list){ if ( ptr ){ assert(0 <= *num && *num <= BRC_MAXNUM); memcpy(list, ptr + sizeof(brcbid_t) + sizeof(brcnbrd_t), - *num * sizeof(time4_t)); + *num * sizeof(brc_rec)); return *num; } - list[0] = *num = 1; + list[0].create = *num = 1; return 0; } @@ -421,10 +434,14 @@ brc_initial_board(const char *boardname) static void brc_trunc(int bid, time4_t ftime){ - brc_insert_record(bid, 1, &ftime); + brc_rec r; + + r.create = ftime; + r.modified = ftime; + brc_insert_record(bid, 1, &r); if ( bid == brc_currbid ){ brc_num = 1; - brc_list[0] = ftime; + brc_list[0] = r; brc_changed = 0; } } @@ -440,50 +457,61 @@ brc_toggle_all_read(int bid, int is_all_read) } void -brc_addlist(const char *fname) +brc_addlist(const char *fname, time4_t modified) { int n, i; - time4_t ftime; + brc_rec frec; assert(currbid == brc_currbid); if (!cuser.userlevel) return; brc_initialize(); - ftime = atoi(&fname[2]); - if (ftime <= brc_expire_time /* too old, don't do any thing */ + frec.create = atoi(&fname[2]); + frec.modified = modified; + + if (frec.create <= 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_list[0] = frec; brc_num = 1; brc_changed = 1; return; } - if ((brc_num == 1) && (ftime < brc_list[0])) /* most when after 'v' */ + if ((brc_num == 1) && (frec.create < brc_list[0].create)) /* most when after 'v' */ return; for (n = 0; n < brc_num; n++) { /* using linear search */ - if (ftime == brc_list[n]) { + if (frec.create == brc_list[n].create) { + if (brc_list[n].modified < modified) + { + brc_list[n].modified = modified; + brc_changed = 1; + } return; - } else if (ftime > brc_list[n]) { + } else if (frec.create > brc_list[n].create) { if (brc_num < BRC_MAXNUM) brc_num++; - /* insert ftime into brc_list */ + /* insert frec into brc_list */ for (i = brc_num - 1; --i >= n; brc_list[i + 1] = brc_list[i]); - brc_list[n] = ftime; + brc_list[n] = frec; brc_changed = 1; return; } } } +// return: +// 0 - read +// 1 - unread (by create) +// 2 - unread (by modified) int -brc_unread_time(int bid, time4_t ftime) +brc_unread_time(int bid, time4_t ftime, time4_t modified) { int i; int bnum; - const time4_t *blist; + const brc_rec *blist; brc_initialize(); if (ftime <= brc_expire_time) /* too old */ @@ -498,21 +526,30 @@ brc_unread_time(int bid, time4_t ftime) if (bnum <= 0) return 1; + for (i = 0; i < bnum; i++) { /* using linear search */ - if (ftime > blist[i]) + if (ftime > blist[i].create) return 1; - else if (ftime == blist[i]) - return 0; + else if (ftime == blist[i].create) + { + time4_t brcm = blist[i].modified; + if (modified == 0 || brcm == 0) + return 0; + // bad case... seems like that someone is making -1. + if (modified == (time4_t)-1 || brcm == (time4_t)-1) + return 0; + return modified > brcm ? 2 : 0; + } } return 0; } int -brc_unread(int bid, const char *fname) +brc_unread(int bid, const char *fname, time4_t modified) { int ftime; ftime = atoi(&fname[2]); /* this will get the time of the file created */ - return brc_unread_time(bid, ftime); + return brc_unread_time(bid, ftime, modified); } diff --git a/sample/pttbbs.conf b/sample/pttbbs.conf index 6541dbd1..e0e3db06 100644 --- a/sample/pttbbs.conf +++ b/sample/pttbbs.conf @@ -142,9 +142,6 @@ /* "不"使用新式的 pmore (piaip's more) 代替舊式 bug 抓不完的 more */ //#define USE_TRADITIONAL_MORE -/* 使用 textlen 欄位來確定文章實際長度,避免蓋掉推文等。 */ -// #define USE_TEXTLEN - /* 使用 rfork()取代 fork() . 目前只在 FreeBSD上有效 */ //#define USE_RFORK |