summaryrefslogtreecommitdiffstats
path: root/mbbsd/brc.c
diff options
context:
space:
mode:
authorscw <scw@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2004-04-02 16:57:16 +0800
committerscw <scw@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2004-04-02 16:57:16 +0800
commitd0bf075fc92611fa0bc82d4368dd82d15edf6536 (patch)
tree4e8b8b54078d5eae9c48f61d3fdeaf95a00dbe44 /mbbsd/brc.c
parentce50463a745c2a9af1f4310de6a12a2a461c97f1 (diff)
downloadpttbbs-d0bf075fc92611fa0bc82d4368dd82d15edf6536.tar
pttbbs-d0bf075fc92611fa0bc82d4368dd82d15edf6536.tar.gz
pttbbs-d0bf075fc92611fa0bc82d4368dd82d15edf6536.tar.bz2
pttbbs-d0bf075fc92611fa0bc82d4368dd82d15edf6536.tar.lz
pttbbs-d0bf075fc92611fa0bc82d4368dd82d15edf6536.tar.xz
pttbbs-d0bf075fc92611fa0bc82d4368dd82d15edf6536.tar.zst
pttbbs-d0bf075fc92611fa0bc82d4368dd82d15edf6536.zip
Changing interface, extracting code to brc.c.
(Not able to compile yet). git-svn-id: http://opensvn.csie.org/pttbbs/branches/scw.brc2@1683 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/brc.c')
-rw-r--r--mbbsd/brc.c303
1 files changed, 303 insertions, 0 deletions
diff --git a/mbbsd/brc.c b/mbbsd/brc.c
new file mode 100644
index 00000000..636b8dbe
--- /dev/null
+++ b/mbbsd/brc.c
@@ -0,0 +1,303 @@
+#include "bbs.h"
+
+#ifndef BRC_MAXNUM
+#define BRC_MAXSIZE 24576 /* Effective size of brc rc file, 8192 * 3 */
+#define BRC_ITEMSIZE ((BRC_MAXNUM + 2) * sizeof( int ))
+ /* Maximum size of each record */
+#define BRC_MAXNUM 80 /* Upper bound of brc_num, size of brc_list */
+#endif
+
+/* 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 int *brc_buf = NULL;
+static int brc_size;
+
+static char * const fn_oldboardrc = ".boardrc";
+static char * const fn_brc = ".brc2";
+
+static int *
+brc_getrecord(int *ptr, int *endp, int *bid, int *pnum, int *list)
+{
+ int num;
+ int *tmp;
+
+ if (ptr + 2 > endp)
+ return endp + 1; /* dangling, ignoring it */
+ *bid = *ptr++; /* bid */
+ num = *ptr++; /* brc_num */
+ tmp = ptr + num; /* end of this record */
+ if (tmp <= endp){
+ memcpy(list, ptr, num * sizeof(int)); /* brc_list */
+ if (num > BRC_MAXNUM)
+ num = BRC_MAXNUM;
+ *pnum = num;
+ }
+ return tmp;
+}
+
+static int *
+brc_putrecord(int *ptr, int *endp, int bid, int num, const int *list)
+{
+ if (num > 0 && list[0] > brc_expire_time &&
+ ptr + 2 <= endp) {
+ if (num > BRC_MAXNUM)
+ num = BRC_MAXNUM;
+
+ while (num > 1 && list[num - 1] < brc_expire_time)
+ num--; /* don't write the times before brc_expire_time */
+
+ if( num == 0 ) return ptr;
+
+ *ptr++ = bid; /* write in bid */
+ *ptr++ = num; /* write in brc_num */
+ if (ptr + num <= endp)
+ memcpy(ptr, list, num * sizeof(int)); /* write in brc_list */
+ ptr += num;
+ }
+ return ptr;
+}
+
+#error "Below not changed yet"
+static inline void
+brc_insert_record(const char* board, int num, int* list)
+{
+ int *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_old_brc()
+{
+ /* XXX: read from old brc file */
+}
+
+inline static void
+read_brc_buf()
+{
+ if( brc_buf == NULL ){
+ char dirfile[STRLEN];
+ int fd;
+
+ brc_buf = malloc(BRC_MAXSIZE);
+ setuserfile(dirfile, fn_brc);
+ if ((fd = open(dirfile, O_RDONLY)) != -1) {
+ brc_size = read(fd, brc_buf, BRC_MAXSIZE);
+ close(fd);
+ } else {
+ read_old_brc();
+ }
+ }
+}
+
+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 */
+ currbid = getbnum(boardname);
+ currboard = bcache[currbid - 1].brdname;
+ currbrdattr = bcache[currbid - 1].brdattr;
+
+ return brc_read_record(boardname, &brc_num, brc_list);
+}
+
+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;
+ }
+ }
+}
+
+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;
+}