summaryrefslogtreecommitdiffstats
path: root/mbbsd/brc.c
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2007-12-02 12:02:48 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2007-12-02 12:02:48 +0800
commit23d973bd097f2ec285b0d4b1a08dd13f48d5dec1 (patch)
tree93bfc9f9517217df832ae14349a06b5d65d8b67e /mbbsd/brc.c
parent6dbbad9a294b007ec184b689a601ed8077f4d50b (diff)
downloadpttbbs-23d973bd097f2ec285b0d4b1a08dd13f48d5dec1.tar
pttbbs-23d973bd097f2ec285b0d4b1a08dd13f48d5dec1.tar.gz
pttbbs-23d973bd097f2ec285b0d4b1a08dd13f48d5dec1.tar.bz2
pttbbs-23d973bd097f2ec285b0d4b1a08dd13f48d5dec1.tar.lz
pttbbs-23d973bd097f2ec285b0d4b1a08dd13f48d5dec1.tar.xz
pttbbs-23d973bd097f2ec285b0d4b1a08dd13f48d5dec1.tar.zst
pttbbs-23d973bd097f2ec285b0d4b1a08dd13f48d5dec1.zip
*** IMPORTANT CHANGE ***
BRC v3, supporting local modification THINK TWICE BEFORE YOU APPLY TO YOUR SYSTEM. BRC v3 will double size of BRC v2. BRC v3 can allow notifying changes of comment (recommend) system BRC v3 may cause more syscall activities than v2 git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3608 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/brc.c')
-rw-r--r--mbbsd/brc.c225
1 files changed, 131 insertions, 94 deletions
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);
}