summaryrefslogtreecommitdiffstats
path: root/mbbsd/brc.c
diff options
context:
space:
mode:
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);
}