summaryrefslogtreecommitdiffstats
path: root/mbbsd/brc.c
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-03-20 19:33:49 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-03-20 19:33:49 +0800
commit6c7b18b32d87c2a835f7e5c48faac4a8ad44668b (patch)
treee88e1b2b1007f4ddcd348a4a1bf1d13c515c4564 /mbbsd/brc.c
parentf59699c22c130373cda3cc4cb6fab5bae510bd5a (diff)
downloadpttbbs-6c7b18b32d87c2a835f7e5c48faac4a8ad44668b.tar
pttbbs-6c7b18b32d87c2a835f7e5c48faac4a8ad44668b.tar.gz
pttbbs-6c7b18b32d87c2a835f7e5c48faac4a8ad44668b.tar.bz2
pttbbs-6c7b18b32d87c2a835f7e5c48faac4a8ad44668b.tar.lz
pttbbs-6c7b18b32d87c2a835f7e5c48faac4a8ad44668b.tar.xz
pttbbs-6c7b18b32d87c2a835f7e5c48faac4a8ad44668b.tar.zst
pttbbs-6c7b18b32d87c2a835f7e5c48faac4a8ad44668b.zip
- (internal/exp) first draft of new layoutpiaip.newlayout
git-svn-id: http://opensvn.csie.org/pttbbs/branches/piaip.newlayout@4013 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/brc.c')
-rw-r--r--mbbsd/brc.c596
1 files changed, 0 insertions, 596 deletions
diff --git a/mbbsd/brc.c b/mbbsd/brc.c
deleted file mode 100644
index 4317dfd1..00000000
--- a/mbbsd/brc.c
+++ /dev/null
@@ -1,596 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-/**
- * 關於本檔案的細節,請見 docs/brc.txt。
- * v3: add last modified time for comment system. double max size.
- * original time_t as 'create'.
- */
-
-// WARNING: Check ../pttbbs.conf, you may have overide these value there
-// TODO MAXSIZE may be better smaller to fit into memory page.
-#ifndef BRC_MAXNUM
-#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
-
-#define BRC_BLOCKSIZE 1024
-
-// Note: BRC v3 should already support MAX_BOARD > 65535 and BRC_MAXSIZE > 65535,
-// but not widely tested yet.
-#if MAX_BOARD > 65535 || BRC_MAXSIZE > 65535
-#error Max number of boards or BRC_MAXSIZE cannot fit in unsigned short, \
-please rewrite brc.c (v2)
-#endif
-
-typedef uint32_t brcbid_t;
-typedef uint16_t 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(brc_rec) bytes */
-
-static char brc_initialized = 0;
-static time4_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; /**< brc_list/brc_num changed */
-/* 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;
-
-// read records for currbid
-static int brc_currbid;
-static int brc_num;
-static brc_rec brc_list[BRC_MAXNUM];
-
-static char * const fn_brc2= ".brc2";
-static char * const fn_brc = ".brc3";
-
-/**
- * find read records of bid in given buffer region
- *
- * @param[in] begin
- * @param[in] endp
- * @param bid
- * @param[out] num number of records, which could be written for \a bid
- * = brc_num if found
- * = 0 or dangling size if not found
- *
- * @return address of record. \a begin <= addr < \a endp.
- * 0 if not found
- */
-/* 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(brc_rec); /* 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;
-}
-
-static brc_rec *
-brc_find_record(int bid, int *num)
-{
- char *p;
- brcnbrd_t tnum;
- p = brc_findrecord_in(brc_buf, brc_buf + brc_size, bid, &tnum);
- *num = tnum;
- if (p)
- 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 brc_rec *list)
-{
- char * tmp;
- if (num > 0 && list[0].create > brc_expire_time &&
- ptr + sizeof(brcbid_t) + sizeof(brcnbrd_t) < endp) {
- if (num > BRC_MAXNUM)
- num = BRC_MAXNUM;
-
- 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(brc_rec);
- if (tmp <= endp)
- memcpy(ptr, list, num * sizeof(brc_rec)); /* write in brc_list */
- ptr = tmp;
- }
- return ptr;
-}
-
-static inline int
-brc_enlarge_buf(void)
-{
- char *buffer;
- if (brc_alloc >= BRC_MAXSIZE)
- return 0;
-
-#ifdef CRITICAL_MEMORY
-#define THE_MALLOC(X) MALLOC(X)
-#define THE_FREE(X) FREE(X)
-#else
-#define THE_MALLOC(X) alloca(X)
-#define THE_FREE(X) (void)(X)
- /* alloca get memory from stack and automatically freed when
- * function returns. */
-#endif
-
- buffer = (char*)THE_MALLOC(brc_alloc);
- assert(buffer);
-
- memcpy(buffer, brc_buf, brc_alloc);
- free(brc_buf);
- brc_alloc += BRC_BLOCKSIZE;
- brc_buf = (char*)malloc(brc_alloc);
- assert(brc_buf);
- memcpy(brc_buf, buffer, brc_alloc - BRC_BLOCKSIZE);
-
-#ifdef DEBUG
- vmsgf("brc enlarged to %d bytes", brc_alloc);
-#endif
-
- THE_FREE(buffer);
- return 1;
-
-#undef THE_MALLOC
-#undef THE_FREE
-}
-
-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);
- assert(brc_buf);
-}
-
-static inline void
-brc_insert_record(brcbid_t bid, brcnbrd_t num, const brc_rec* list)
-{
- char *ptr;
- int new_size, end_size;
- brcnbrd_t tnum;
-
- ptr = brc_findrecord_in(brc_buf, brc_buf + brc_size, bid, &tnum);
-
- while (num > 0 && list[num - 1].create < brc_expire_time)
- num--; /* don't write the times before brc_expire_time */
-
- if (!ptr) {
- brc_size -= (int)tnum;
-
- /* put on the beginning */
- if (num){
- new_size = sizeof(brcbid_t) + sizeof(brcnbrd_t)
- + num * sizeof(brc_rec);
- 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). */
- 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(brc_rec));
- brc_size += new_size - len;
- if (brc_size > brc_alloc) {
- if (brc_enlarge_buf()) {
- ptr = brc_buf + sindex;
- tmpp = ptr + len;
- } else {
- 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 -= len;
- }
- }
-
- brc_changed = 0;
-}
-
-/**
- * write \a brc_num and \a brc_list back to \a brc_buf.
- */
-void
-brc_update(){
- if (brc_currbid && brc_changed && cuser.userlevel && brc_num > 0) {
- brc_initialize();
- brc_insert_record(brc_currbid, brc_num, brc_list);
- }
-}
-
-void
-read_brc2(void)
-{
- char brcfile[STRLEN];
- int fd;
- size_t sz2 = 0, sz3 = 0;
- char *cvt = NULL, *cvthead = NULL;
-
- // brc v2 is using 16 bit for brcbid_t and brcnbrd_t.
- uint16_t bid2, num2;
-
- 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);
- memset(cvthead, 0, sz3);
- // now calculate real sz3
-
- while (read(fd, &bid2, sizeof(bid2)) > 0)
- {
- if (read(fd, &num2, sizeof(num2)) < 1)
- break;
-
- bid = bid2;
- num = num2;
-
- // some brc v2 contains bad structure.
- // check pointer here.
- if (cvt + sizeof(brcbid_t) + sizeof(brcnbrd_t) - cvthead >= sz3)
- break;
-
- *(brcbid_t*) cvt = bid; cvt += sizeof(brcbid_t);
- *(brcnbrd_t*)cvt = num; cvt += sizeof(brcnbrd_t);
-
- // some brc v2 contains bad structure.
- // check pointer here.
- for (; num > 0 && (cvt + sizeof(brc_rec) - cvthead) <= sz3 ; num--)
- {
- if (read(fd, &create, sizeof(create)) < 1)
- break;
-
- rec.create = create;
- rec.modified = create;
-
- *(brc_rec*)cvt = rec; cvt += sizeof(brc_rec);
- }
- }
- close(fd);
-
- // now cvthead is ready for v3.
- sz3 = cvt - cvthead;
- brc_get_buf(sz3);
- // new size maybe smaller, check brc_alloc instead
- if (sz3 > brc_alloc)
- sz3 = brc_alloc;
- brc_size = sz3;
- memcpy(brc_buf, cvthead, sz3);
-
- free(cvthead);
-}
-
-inline static void
-read_brc_buf(void)
-{
- 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
- *
- * Do not destory brc_currbid, brc_num, brc_list.
- */
-void
-brc_release()
-{
- if (brc_buf) {
- free(brc_buf);
- brc_buf = NULL;
- }
- brc_changed = 0;
- brc_size = brc_alloc = 0;
-}
-
-void
-brc_finalize(){
- char brcfile[STRLEN];
- char tmpfile[STRLEN];
-
- if(!brc_initialized)
- return;
-
- brc_update();
- setuserfile(brcfile, fn_brc);
- snprintf(tmpfile, sizeof(tmpfile), "%s.tmp.%x", brcfile, getpid());
- if (brc_buf != NULL) {
- int fd = open(tmpfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
- if (fd != -1) {
- int ok=0;
- if(write(fd, brc_buf, brc_size)==brc_size)
- ok=1;
- close(fd);
- if(ok)
- Rename(tmpfile, brcfile);
- else
- unlink(tmpfile);
- }
- }
-
- brc_release();
- brc_initialized = 0;
-}
-
-int
-brc_initialize(){
- if (brc_initialized)
- return 1;
- brc_initialized = 1;
- brc_expire_time = login_start_time - 365 * 86400;
- read_brc_buf();
- return 0;
-}
-
-/**
- * get the read records for bid
- *
- * @param bid
- * @param[out] num number of record for \a bid. 1 <= \a num <= \a BRC_MAXNUM
- * \a num = 1 if no records.
- * @param[out] list the list of records, length \a num
- *
- * @return number of read record, 0 if no records
- */
-static int
-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);
- *num = tnum;
- if ( ptr ){
- assert(0 <= *num && *num <= BRC_MAXNUM);
- memcpy(list, ptr + sizeof(brcbid_t) + sizeof(brcnbrd_t),
- *num * sizeof(brc_rec));
- return *num;
- }
- list[0].create = *num = 1;
- return 0;
-}
-
-/**
- * @return number of records in \a boardname
- */
-int
-brc_initial_board(const char *boardname)
-{
- brc_initialize();
-
- if (strcmp(currboard, boardname) == 0) {
- assert(currbid == brc_currbid);
- return brc_num;
- }
-
- brc_update(); /* write back first */
- currbid = getbnum(boardname);
- if( currbid == 0 )
- currbid = getbnum(DEFAULT_BOARD);
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- brc_currbid = currbid;
- currboard = bcache[currbid - 1].brdname;
- currbrdattr = bcache[currbid - 1].brdattr;
-
- return brc_read_record(brc_currbid, &brc_num, brc_list);
-}
-
-static void
-brc_trunc(int bid, time4_t 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] = r;
- brc_changed = 0;
- }
-}
-
-void
-brc_toggle_all_read(int bid, int is_all_read)
-{
- brc_initialize();
- if (is_all_read)
- brc_trunc(bid, now);
- else
- brc_trunc(bid, 1);
-}
-
-void
-brc_addlist(const char *fname, time4_t modified)
-{
- int n, i;
- brc_rec frec;
-
- assert(currbid == brc_currbid);
- if (!cuser.userlevel)
- return;
- brc_initialize();
-
- 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] = frec;
- brc_num = 1;
- brc_changed = 1;
- return;
- }
- 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 (frec.create == brc_list[n].create) {
- // check if we got bad value.
- if (modified == (time4_t)-1)
- return;
-
- if (brc_list[n].modified == (time4_t)-1)
- brc_list[n].modified = 0;
-
- // special case here:
- // in order to support special system like 'always bottom',
- // they may share same create time and different time.
- if (brc_list[n].modified < modified)
- {
- brc_list[n].modified = modified;
- brc_changed = 1;
- }
- return;
- } else if (frec.create > brc_list[n].create) {
- if (brc_num < BRC_MAXNUM)
- brc_num++;
- /* insert frec into brc_list */
- for (i = brc_num - 1; --i >= n; brc_list[i + 1] = brc_list[i]);
- 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, time4_t modified)
-{
- int i;
- int bnum;
- const brc_rec *blist;
-
- brc_initialize();
- if (ftime <= brc_expire_time) /* too old */
- return 0;
-
- if (brc_currbid && bid == brc_currbid) {
- blist = brc_list;
- bnum = brc_num;
- } else {
- blist = brc_find_record(bid, &bnum);
- }
-
- if (bnum <= 0)
- return 1;
-
- for (i = 0; i < bnum; i++) { /* using linear search */
- if (ftime > blist[i].create)
- return 1;
- 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;
-
- // one case is, some special file headers (ex,
- // always bottom) may cause issue. They share create
- // time (filename) and apply different modify time.
- // so let's back to 'greater'.
- return modified > brcm ? 2 : 0;
- }
- }
- return 0;
-}
-
-int
-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, modified);
-}