/* $Id: board.c,v 1.13 2002/05/24 18:34:22 ptt Exp $ */ #include #include #include #include #include #include #include #include #include "config.h" #include "pttstruct.h" #include "perm.h" #include "modes.h" #include "common.h" #include "proto.h" #define BRC_STRLEN 15 /* Length of board name */ #define BRC_MAXSIZE 24576 #define BRC_ITEMSIZE (BRC_STRLEN + 1 + BRC_MAXNUM * sizeof( int )) #define BRC_MAXNUM 80 extern userinfo_t *currutmp; extern time_t now; static char *brc_getrecord(char *ptr, char *name, int *pnum, int *list) { int num; char *tmp; strncpy(name, ptr, BRC_STRLEN); ptr += BRC_STRLEN; num = (*ptr++) & 0xff; tmp = ptr + num * sizeof(int); if (num > BRC_MAXNUM) num = BRC_MAXNUM; *pnum = num; memcpy(list, ptr, num * sizeof(int)); return tmp; } static time_t brc_expire_time; static char *brc_putrecord(char *ptr, char *name, int num, int *list) { if(num > 0 && list[0] > brc_expire_time) { if (num > BRC_MAXNUM) num = BRC_MAXNUM; while(num > 1 && list[num - 1] < brc_expire_time) num--; strncpy(ptr, name, BRC_STRLEN); ptr += BRC_STRLEN; *ptr++ = num; memcpy(ptr, list, num * sizeof(int)); ptr += num * sizeof(int); } return ptr; } extern userec_t cuser; extern char currboard[]; /* name of currently selected board */ static int brc_changed = 0; static char brc_buf[BRC_MAXSIZE]; int brc_num; static char brc_name[BRC_STRLEN]; int brc_list[BRC_MAXNUM]; static char *fn_boardrc = ".boardrc"; static int brc_size; void brc_update() { if(brc_changed && cuser.userlevel) { char dirfile[STRLEN], *ptr; char tmp_buf[BRC_MAXSIZE - BRC_ITEMSIZE], *tmp; char tmp_name[BRC_STRLEN]; int tmp_list[BRC_MAXNUM], tmp_num; int fd, tmp_size; ptr = brc_buf; if(brc_num > 0) ptr = brc_putrecord(ptr, brc_name, brc_num, brc_list); setuserfile(dirfile, fn_boardrc); if((fd = open(dirfile, O_RDONLY)) != -1) { tmp_size = read(fd, tmp_buf, sizeof(tmp_buf)); close(fd); } else { tmp_size = 0; } tmp = tmp_buf; while(tmp < &tmp_buf[tmp_size] && (*tmp >= ' ' && *tmp <= 'z')) { tmp = brc_getrecord(tmp, tmp_name, &tmp_num, tmp_list); if(strncmp(tmp_name, currboard, BRC_STRLEN)) ptr = brc_putrecord(ptr, tmp_name, tmp_num, tmp_list); } brc_size = (int)(ptr - brc_buf); if((fd = open(dirfile, O_WRONLY | O_CREAT, 0644)) != -1) { ftruncate(fd, 0); write(fd, brc_buf, brc_size); close(fd); } brc_changed = 0; } } static void read_brc_buf() { char dirfile[STRLEN]; int fd; if(brc_buf[0] == '\0') { setuserfile(dirfile, fn_boardrc); if((fd = open(dirfile, O_RDONLY)) != -1) { brc_size = read(fd, brc_buf, sizeof(brc_buf)); close(fd); } else { brc_size = 0; } } } extern int currbid; extern unsigned int currbrdattr; extern boardheader_t *bcache; int brc_initial(char *boardname) { char *ptr; if(strcmp(currboard, boardname) == 0) { return brc_num; } brc_update(); strcpy(currboard, boardname); currbid = getbnum(currboard); currbrdattr = bcache[currbid - 1].brdattr; read_brc_buf(); ptr = brc_buf; while(ptr < &brc_buf[brc_size] && (*ptr >= ' ' && *ptr <= 'z')) { ptr = brc_getrecord(ptr, brc_name, &brc_num, brc_list); if (strncmp(brc_name, currboard, BRC_STRLEN) == 0) return brc_num; } strncpy(brc_name, boardname, BRC_STRLEN); brc_num = brc_list[0] = 1; return 0; } void brc_addlist(char *fname) { int ftime, n, i; if(!cuser.userlevel) return; ftime = atoi(&fname[2]); if(ftime <= brc_expire_time /* || fname[0] != 'M' || fname[1] != '.' */ ) { return; } if(brc_num <= 0) { brc_list[brc_num++] = ftime; brc_changed = 1; return; } if((brc_num == 1) && (ftime < brc_list[0])) return; for(n = 0; n < brc_num; n++) { if(ftime == brc_list[n]) { return; } else if(ftime > brc_list[n]) { if(brc_num < BRC_MAXNUM) brc_num++; for(i = brc_num - 1; --i >= n; brc_list[i + 1] = brc_list[i]); brc_list[n] = ftime; brc_changed = 1; return; } } if(brc_num < BRC_MAXNUM) { brc_list[brc_num++] = ftime; brc_changed = 1; } } static int brc_unread_time(time_t ftime, int bnum, int *blist) { int n; if(ftime <= brc_expire_time ) return 0; if(brc_num <= 0) return 1; for(n = 0; n < bnum; n++) { if(ftime > blist[n]) return 1; else if(ftime == blist[n]) return 0; } return 0; } int brc_unread(char *fname, int bnum, int *blist) { int ftime, n; ftime = atoi(&fname[2]); if(ftime <= brc_expire_time ) return 0; if(brc_num <= 0) return 1; for(n = 0; n < bnum; n++) { if(ftime > blist[n]) return 1; else if(ftime == blist[n]) return 0; } return 0; } #define BRD_UNREAD 1 #define BRD_FAV 2 #define BRD_ZAP 4 #define BRD_TAG 8 typedef struct { int bid, *total; time_t *lastposttime; boardheader_t *bh; unsigned int myattr; } boardstat_t; extern time_t login_start_time; extern int numboards; static int *zapbuf=NULL,*favbuf; static boardstat_t *nbrd=NULL; #define STR_BBSRC ".bbsrc" #define STR_FAV ".fav" void init_brdbuf() { register int n, size; char fname[60]; /* MAXBOARDS ==> ¦Ü¦h¬Ý±o¨£ 32 ­Ó·sªO */ n = numboards + 32; size = n * sizeof(int); zapbuf = (int *) malloc(size); favbuf = (int *) malloc(size + sizeof(int)); favbuf[0] = 0x5c4d3e; /* for check memory */ ++favbuf; memset(favbuf,0,size); while(n) zapbuf[--n] = login_start_time; setuserfile(fname, STR_BBSRC); if((n = open(fname, O_RDONLY, 0600)) != -1) { read(n, zapbuf, size); close(n); } setuserfile(fname, STR_FAV); if((n = open(fname, O_RDONLY, 0600)) != -1) { read(n, favbuf, size); close(n); } brc_expire_time = login_start_time - 365 * 86400; } void save_brdbuf() { int fd, size; char fname[60]; if(!zapbuf) return; setuserfile(fname, STR_BBSRC); if((fd = open(fname, O_WRONLY | O_CREAT, 0600)) != -1) { size = numboards * sizeof(int); write(fd, zapbuf, size); close(fd); } if( favbuf[-1] != 0x5c4d3e ){ FILE *fp = fopen(BBSHOME "/log/memorybad", "a"); fprintf(fp, "%s %s %d\n", cuser.userid, Cdatelite(&now), favbuf[-1]); fclose(fp); return; } setuserfile(fname, STR_FAV); if((fd = open(fname, O_WRONLY | O_CREAT, 0600)) != -1) { size = numboards * sizeof(int); write(fd, favbuf, size); close(fd); } } extern char *fn_visable; int Ben_Perm(boardheader_t *bptr) { register int level,brdattr; register char *ptr; level = bptr->level; brdattr = bptr->brdattr; if(HAS_PERM(PERM_SYSOP)) return 1; ptr = bptr->BM; if(is_BM(ptr)) return 1; /* ¯¦±K¬ÝªO¡G®Ö¹ï­º®uªO¥Dªº¦n¤Í¦W³æ */ if(brdattr & BRD_HIDE) { /* ÁôÂà */ if( hbflcheck((int)(bptr-bcache) + 1, currutmp->uid) ){ if(brdattr & BRD_POSTMASK) return 0; else return 2; } else return 1; } /* ­­¨î¾\ŪÅv­­ */ if(level && !(brdattr & BRD_POSTMASK) && !HAS_PERM(level)) return 0; return 1; } extern char currauthor[]; extern int b_lines; extern char currowner[]; #if 0 static int have_author(char* brdname) { char dirname[100]; sprintf(dirname, "¥¿¦b·j´M§@ªÌ%s ¬ÝªO:%s.....", currauthor,brdname); move(b_lines, 0); clrtoeol(); outs(dirname); refresh(); setbdir(dirname, brdname); str_lower(currowner, currauthor); return search_rec(dirname, cmpfowner); } #endif static int check_newpost(boardstat_t *ptr) { /* Ptt §ï */ int tbrc_list[BRC_MAXNUM], tbrc_num; char bname[BRC_STRLEN]; char *po; time_t ftime; ptr->myattr &= ~BRD_UNREAD; if(ptr->bh->brdattr & BRD_GROUPBOARD) return 0; if(*(ptr->total) == 0) setbtotal(ptr->bid); if(*(ptr->total) == 0) return 0; ftime = *(ptr->lastposttime); read_brc_buf(); po = brc_buf; while(po < &brc_buf[brc_size] && (*po >= ' ' && *po <= 'z')) { po = brc_getrecord(po, bname, &tbrc_num, tbrc_list); if(strncmp(bname, ptr->bh->brdname, BRC_STRLEN) == 0) { if(brc_unread_time(ftime,tbrc_num,tbrc_list)) { ptr->myattr |= BRD_UNREAD; } return 1; } } ptr->myattr |= BRD_UNREAD; return 1; } extern int currmode; extern struct bcache_t *brdshm; static int brdnum; int class_bid = 0; static int yank_flag = 1; static void load_uidofgid(const int gid, const int type){ boardheader_t *bptr,*currbptr; int n, childcount=0; currbptr = &bcache[gid-1]; for(n=0;nsorted[type][n]; if(bptr->brdname[0]=='\0') continue; if(bptr->gid == gid) { if(currbptr == &bcache[gid-1]) currbptr->firstchild[type]=bptr; else { currbptr->next[type]=bptr; currbptr->parent=&bcache[gid-1]; } childcount++; currbptr=bptr; } } bcache[gid-1].childcount=childcount; if(currbptr == &bcache[gid-1]) currbptr->firstchild[type]=(boardheader_t *) ~0; else currbptr->next[type]=(boardheader_t *) ~0; } static boardstat_t * addnewbrdstat(int n, int state) { boardstat_t *ptr=&nbrd[brdnum++]; boardheader_t *bptr = &bcache[n]; ptr->total = &(brdshm->total[n]); ptr->lastposttime = &(brdshm->lastposttime[n]); ptr->bid = n+1; ptr->myattr=0; ptr->myattr=(favbuf[n]&~BRD_ZAP); if(zapbuf[n] == 0) ptr->myattr|=BRD_ZAP; ptr->bh = bptr; if((bptr->brdattr & BRD_HIDE) && state == 1) bptr->brdattr |= BRD_POSTMASK; check_newpost(ptr); return ptr; } static void load_boards(char *key) { boardheader_t *bptr = NULL; int type=cuser.uflag & BRDSORT_FLAG?1:0; register int i,n; register int state ; if(class_bid>0) { bptr = &bcache[class_bid-1]; if(bptr->firstchild[type]==NULL || bptr->childcount<=0) load_uidofgid(class_bid,type); } brdnum = 0; if(class_bid==0) { nbrd = (boardstat_t *)malloc(numboards * sizeof(boardstat_t)); for(i=0 ; i < numboards; i++) { if( (bptr = brdshm->sorted[type][i]) == NULL ) continue; n = (int)( bptr - bcache); if(!bptr->brdname[0] || bptr->brdattr & BRD_GROUPBOARD || !((state = Ben_Perm(bptr)) || (currmode & MODE_MENU)) || (yank_flag == 0 && !(favbuf[n]&BRD_FAV)) || (yank_flag == 1 && !zapbuf[n]) || (key[0] && !strcasestr(bptr->title, key)) ) continue; addnewbrdstat(n, state); } } else { nbrd = (boardstat_t *)malloc( bptr->childcount * sizeof(boardstat_t)); for(bptr=bptr->firstchild[type]; bptr!=(boardheader_t *)~0; bptr=bptr->next[type]) { n = (int)( bptr - bcache); if(!((state = Ben_Perm(bptr)) || (currmode & MODE_MENU)) ||(yank_flag == 0 && !(favbuf[n]&BRD_FAV)) ||(yank_flag == 1 && !zapbuf[n]) || (key[0] && !strcasestr(bptr->title, key))) continue; addnewbrdstat(n, state); } } } static int search_board() { int num; char genbuf[IDLEN + 2]; move(0, 0); clrtoeol(); CreateNameList(); for(num = 0; num < brdnum; num++) AddNameList(nbrd[num].bh->brdname); namecomplete(MSG_SELECT_BOARD, genbuf); for (num = 0; num < brdnum; num++) if (!strcasecmp(nbrd[num].bh->brdname, genbuf)) return num; return -1; } static int unread_position(char *dirfile, boardstat_t *ptr) { fileheader_t fh; char fname[FNLEN]; register int num, fd, step, total; total = *(ptr->total); num = total + 1; if((ptr->myattr&BRD_UNREAD) &&(fd = open(dirfile, O_RDWR)) > 0) { if(!brc_initial(ptr->bh->brdname)) { num = 1; } else { num = total - 1; step = 4; while(num > 0) { lseek(fd, (off_t)(num * sizeof(fh)), SEEK_SET); if(read(fd, fname, FNLEN) <= 0 || !brc_unread(fname,brc_num,brc_list)) break; num -= step; if(step < 32) step += step >> 1; } if(num < 0) num = 0; while(num < total) { lseek(fd, (off_t)(num * sizeof(fh)), SEEK_SET); if(read(fd, fname, FNLEN) <= 0 || brc_unread(fname,brc_num,brc_list)) break; num++; } } close(fd); } if(num < 0) num = 0; return num; } static void brdlist_foot() { prints("\033[34;46m ¿ï¾Ü¬ÝªO \033[31;47m (c)\033[30m·s¤å³¹¼Ò¦¡ " "\033[31m(v/V)\033[30m¼Ð°O¤wŪ/¥¼Åª \033[31m(y)\033[30m¿z¿ï%s" " \033[31m(z)\033[30m¤Á´«¿ï¾Ü \033[m", yank_flag==0 ? "³Ì·R" : yank_flag==1 ? "³¡¥÷" : "¥þ³¡"); } extern unsigned int currstat; extern char *BBSName; static void show_brdlist(int head, int clsflag, int newflag) { int myrow = 2; if(class_bid == 1) { currstat = CLASS; myrow = 6; showtitle("¤ÀÃþ¬ÝªO", BBSName); movie(0); move(1, 0); prints( " " "¢© ¢~¡X\033[33m¡´\n" " ùá¡X \033[m " "¢¨¢i\033[47m¡ó\033[40m¢i¢i¢©ùç\n"); prints( " \033[44m ¡s¡s¡s¡s¡s¡s¡s¡s " "\033[33mùø\033[m\033[44m ¢©¢¨¢i¢i¢i¡¿¡¿¡¿ùø \033[m\n" " \033[44m " "\033[33m \033[m\033[44m ¢«¢ª¢i¢i¢i¡¶¡¶¡¶ ùø\033[m\n" " ¡s¡s¡s¡s¡s¡s¡s¡s \033[33m" "¢x\033[m ¢ª¢i¢i¢i¢i¢« ùø\n" " \033[33mùó" "¡X¡X\033[m ¢« ¡X¡Ï\033[m"); } else if (clsflag) { showtitle("¬ÝªO¦Cªí", BBSName); prints("[¡ö]¥D¿ï³æ [¡÷]¾\\Ū [¡ô¡õ]¿ï¾Ü [y]¸ü¤J [S]±Æ§Ç [/]·j´M " "[TAB]¤åºK¡E¬ÝªO [h]¨D§U\n" "\033[7m%-20s Ãþ§O Âà«H%-31s¤H®ð ªO ¥D \033[m", newflag ? "Á`¼Æ ¥¼Åª ¬Ý ªO" : " ½s¸¹ ¬Ý ªO", " ¤¤ ¤å ±Ô ­z"); move(b_lines, 0); brdlist_foot(); } if(brdnum > 0) { boardstat_t *ptr; static char *color[8]={"","\033[32m", "\033[33m","\033[36m","\033[34m","\033[1m", "\033[1;32m","\033[1;33m"}; static char *unread[2]={"\33[37m \033[m","\033[1;31m£¾\033[m"}; while(++myrow < b_lines) { move(myrow, 0); clrtoeol(); if(head < brdnum) { ptr = &nbrd[head++]; if(class_bid == 1) prints(" "); if(!newflag) { prints("%5d%c%s", head, !(ptr->bh->brdattr & BRD_HIDE) ? ' ': (ptr->bh->brdattr & BRD_POSTMASK) ? ')' : '-', (ptr->myattr & BRD_TAG) ? "D " : (ptr->myattr & BRD_ZAP) ? "- " : (ptr->bh->brdattr & BRD_GROUPBOARD) ? " " : unread[ptr->myattr&BRD_UNREAD]); } else if(ptr->myattr&BRD_ZAP) { ptr->myattr &= ~BRD_UNREAD; prints(" ¡ß ¡ß"); } else { if(newflag) { if((ptr->bh->brdattr & BRD_GROUPBOARD)) prints(" "); else prints("%6d%s", (int)(*(ptr->total)), unread[ptr->myattr&BRD_UNREAD]); } } if(class_bid != 1) { prints("%s%-13s\033[m%s%5.5s\033[0;37m%2.2s\033[m" "%-34.34s", (ptr->myattr & BRD_FAV)?"\033[1;36m":"", ptr->bh->brdname, color[(unsigned int) (ptr->bh->title[1] + ptr->bh->title[2] + ptr->bh->title[3] + ptr->bh->title[0]) & 07], ptr->bh->title, ptr->bh->title+5, ptr->bh->title+7); if (ptr->bh->brdattr & BRD_BAD) prints(" X "); else if(ptr->bh->nuser>30) prints("\033[31mHOT\033[m"); else if(ptr->bh->nuser) prints("\033[31m%2d\033[m ",ptr->bh->nuser); else prints(" %c ", ptr->bh->bvote? 'V':' '); prints("%.13s", ptr->bh->BM); refresh(); } else { prints("%-40.40s %.13s", ptr->bh->title + 7, ptr->bh->BM); } } clrtoeol(); } } } static char *choosebrdhelp[] = { "\0¬ÝªO¿ï³æ»²§U»¡©ú", "\01°ò¥»«ü¥O", "(p)(¡ô)/(n)(¡õ)¤W¤@­Ó¬ÝªO / ¤U¤@­Ó¬ÝªO", "(P)(^B)(PgUp) ¤W¤@­¶¬ÝªO", "(N)(^F)(PgDn) ¤U¤@­¶¬ÝªO", "($)/(s)/(/) ³Ì«á¤@­Ó¬ÝªO / ·j´M¬ÝªO / ¥H¤¤¤å·j´M¬ÝªOÃöÁä¦r", "(¼Æ¦r) ¸õ¦Ü¸Ó¶µ¥Ø", "\01¶i¶¥«ü¥O", "(^W) °g¸ô¤F §Ú¦b­þ¸Ì", "(r)(¡÷)(Rtn) ¶i¤J¦h¥\\¯à¾\\Ū¿ï³æ", "(q)(¡ö) ¦^¨ì¥D¿ï³æ", "(z)(Z) ­q¾\\/¤Ï­q¾\\¬ÝªO ­q¾\\/¤Ï­q¾\\©Ò¦³¬ÝªO", "(y) §Úªº³Ì·R/­q¾\\¬ÝªO/¥X©Ò¦³¬ÝªO", "(v/V) ³q³q¬Ý§¹/¥þ³¡¥¼Åª", "(S) «ö·Ó¦r¥À/¤ÀÃþ±Æ§Ç", "(t/^T/^A/^D) ¼Ð°O¬ÝªO/¨ú®ø©Ò¦³¼Ð°O/¤w¼Ð°Oªº¥[¤J§Úªº³Ì·R/¨ú®ø§Úªº³Ì·R", "(m) §â¬ÝªO¥[¤J§Úªº³Ì·R", "\01¤p²Õªø«ü¥O", "(E/W/B) ³]©w¬ÝªO/³]©w¤p²Õ³Æ§Ñ/¶}·s¬ÝªO", "(^P) ²¾°Ê¤w¼Ð°O¬ÝªO¨ì¦¹¤ÀÃþ", NULL }; static void set_menu_BM(char *BM) { if(HAS_PERM(PERM_ALLBOARD) || is_BM(BM)) { currmode |= MODE_MENU; cuser.userlevel |= PERM_SYSSUBOP; } } extern int p_lines; /* a Page of Screen line numbers: tlines-4 */ extern int t_lines; extern char *fn_notes; static char *privateboard = "\n\n\n\n ¹ï¤£°_ ¦¹ªO¥Ø«e¥u­ã¬ÝªO¦n¤Í¶i¤J ½Ð¥ý¦VªO¥D¥Ó½Ð¤J¹Ò³\\¥i"; static void dozap(int num){ boardstat_t *ptr; ptr = &nbrd[num]; ptr->myattr ^= BRD_ZAP; if(ptr->bh->brdattr & BRD_NOZAP) ptr->myattr &= ~BRD_ZAP; if(!(ptr->myattr & BRD_ZAP) ) check_newpost(ptr); zapbuf[ptr->bid-1] = (ptr->myattr&BRD_ZAP?0:login_start_time); } void setutmpbid(int bid) { int id=currutmp->brc_id; userinfo_t *u; if(id) { if (brdshm->busystate!=1 && brdshm->busystate_b[id-1]!=1) { brdshm->busystate_b[id-1]=1; u=bcache[id-1].u; if(u!=(void*)currutmp) for(;u && u->nextbfriend != (void*)currutmp; u=u->nextbfriend); else bcache[bid-1].u=NULL; if(u) { bcache[id-1].nuser--; u->nextbfriend = currutmp->nextbfriend; } brdshm->busystate_b[id-1]=0; } } if(bid) { bcache[bid-1].nuser++; currutmp->nextbfriend=bcache[bid-1].u; bcache[bid-1].u=(void*)currutmp; } else { currutmp->nextbfriend=0; } currutmp->brc_id=bid; } static void choose_board(int newflag) { static int num = 0; boardstat_t *ptr; int head = -1, ch = 0, currmodetmp, tmp,tmp1, bidtmp; char keyword[13]=""; #if HAVE_SEARCH_ALL char genbuf[200]; #endif extern time_t board_visit_time; setutmpmode(newflag ? READNEW : READBRD); brdnum = 0; if(!cuser.userlevel) /* guest yank all boards */ yank_flag = 2; do { if(brdnum <= 0) { load_boards(keyword); if(brdnum <= 0) { if(keyword[0]!=0) { mprints(b_lines-1,0,"¨S¦³¥ô¦ó¬ÝªO¼ÐÃD¦³¦¹ÃöÁä¦r " "(ª©¥DÀ³ª`·N¬ÝªO¼ÐÃD©R¦W)"); pressanykey(); keyword[0]=0; brdnum = -1; continue; } if(yank_flag<2) { brdnum = -1; yank_flag++; continue; } if(HAS_PERM(PERM_SYSOP) || (currmode & MODE_MENU)) { if(m_newbrd(0) == -1) break; brdnum = -1; continue; } else break; } head = -1; } if(num < 0) num = 0; else if(num >= brdnum) num = brdnum - 1; if(head < 0) { if(newflag) { tmp = num; while(num < brdnum) { ptr = &nbrd[num]; if(ptr->myattr&BRD_UNREAD) break; num++; } if(num >= brdnum) num = tmp; } head = (num / p_lines) * p_lines; show_brdlist(head, 1, newflag); } else if(num < head || num >= head + p_lines) { head = (num / p_lines) * p_lines; show_brdlist(head, 0, newflag); } if(class_bid == 1) ch = cursor_key(7 + num - head, 10); else ch = cursor_key(3 + num - head, 0); switch(ch) { case Ctrl('W'): whereami(0,NULL,NULL); head=-1; break; case 'e': case KEY_LEFT: case EOF: ch = 'q'; case 'q': if(keyword[0]) { keyword[0]=0; brdnum=-1; ch=' '; } break; case 'c': show_brdlist(head, 1, newflag ^= 1); break; case KEY_PGUP: case 'P': case 'b': case Ctrl('B'): if(num) { num -= p_lines; break; } case KEY_END: case '$': num = brdnum - 1; break; case ' ': case KEY_PGDN: case 'N': case Ctrl('F'): if(num == brdnum - 1) num = 0; else num += p_lines; break; case Ctrl('C'): cal(); show_brdlist(head, 1, newflag); break; case Ctrl('I'): t_idle(); show_brdlist(head, 1, newflag); break; case KEY_UP: case 'p': case 'k': if (num-- <= 0) num = brdnum - 1; break; case 't': ptr = &nbrd[num]; ptr->myattr ^= BRD_TAG; favbuf[ptr->bid-1]=ptr->myattr; head = 9999; case KEY_DOWN: case 'n': case 'j': if (++num < brdnum) break; case '0': case KEY_HOME: num = 0; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if((tmp = search_num(ch, brdnum)) >= 0) num = tmp; brdlist_foot(); break; case 'F': case 'f': if(class_bid && HAS_PERM(PERM_SYSOP)) { bcache[class_bid-1].firstchild[cuser.uflag&BRDSORT_FLAG?1:0] =NULL; brdnum = -1; } break; case 'h': show_help(choosebrdhelp); show_brdlist(head, 1, newflag); break; case '/': getdata_buf(b_lines-1,0,"½Ð¿é¤J¬ÝªO¤¤¤åÃöÁä¦r:", keyword, sizeof(keyword), DOECHO); brdnum=-1; break; case 'S': cuser.uflag ^= BRDSORT_FLAG; brdnum = -1; break; case 'y': if(class_bid==0) yank_flag = (yank_flag+1)%3; else yank_flag = yank_flag%2+1; brdnum = -1; break; case Ctrl('D'): for(tmp = 0; tmp < numboards; tmp++) { if(favbuf[tmp] & BRD_TAG) { favbuf[tmp] &= ~BRD_FAV; favbuf[tmp] &= ~BRD_TAG; } } brdnum = -1; break; case Ctrl('A'): for(tmp = 0; tmp < numboards; tmp++) { if(favbuf[tmp] & BRD_TAG) { favbuf[tmp] |= BRD_FAV; favbuf[tmp] &= ~BRD_TAG; } } brdnum = -1; break; case Ctrl('T'): for(tmp = 0; tmp < numboards; tmp++) favbuf[tmp] &= ~BRD_TAG; brdnum = -1; break; case Ctrl('P'): if(class_bid!=0 && (HAS_PERM(PERM_SYSOP) || (currmode & MODE_MENU))) { for(tmp = 0; tmp < numboards; tmp++) { boardheader_t *bh=&bcache[tmp]; if(!(favbuf[tmp]&BRD_TAG) || bh->gid==class_bid) continue; favbuf[tmp] &= ~BRD_TAG; if(bh->gid != class_bid) { bh->gid = class_bid; substitute_record(FN_BOARD, bh, sizeof(boardheader_t), tmp+1); reset_board(tmp+1); log_usies("SetBoardGID", bh->brdname); } } brdnum = -1; } break; case 'm': if(HAS_PERM(PERM_BASIC)) { ptr = &nbrd[num]; ptr->myattr ^= BRD_FAV; favbuf[ptr->bid-1]=ptr->myattr; head = 9999; } break; case 'z': if(HAS_PERM(PERM_BASIC)) { dozap(num); head = 9999; } break; case 'Z': /* Ptt */ if(HAS_PERM(PERM_BASIC)) { for(tmp = 0; tmp < brdnum; tmp++) { dozap(tmp); } head = 9999; } break; case 'v': case 'V': ptr = &nbrd[num]; brc_initial(ptr->bh->brdname); if(ch == 'v') { ptr->myattr &= ~BRD_UNREAD; zapbuf[ptr->bid-1] = brc_list[0]=now; } else { zapbuf[ptr->bid-1] = brc_list[0] = 1; ptr->myattr |= BRD_UNREAD; } brc_num = brc_changed = 1; brc_update(); show_brdlist(head, 0, newflag); break; case 's': if((tmp = search_board()) == -1) { show_brdlist(head, 1, newflag); break; } num = tmp; case 'E': if(HAS_PERM(PERM_SYSOP) || (currmode & MODE_MENU)) { ptr = &nbrd[num]; move(1,1); clrtobot(); m_mod_board(ptr->bh->brdname); brdnum = -1; } break; case 'R': if(HAS_PERM(PERM_SYSOP) || (currmode & MODE_MENU)) { m_newbrd(1); brdnum = -1; } break; case 'B': if(HAS_PERM(PERM_SYSOP) || (currmode & MODE_MENU)) { m_newbrd(0); brdnum = -1; } break; case 'W': if(class_bid > 0 && (HAS_PERM(PERM_SYSOP) || (currmode & MODE_MENU))) { b_note_edit_bname(class_bid); brdnum = -1; } break; case KEY_RIGHT: case '\n': case '\r': case 'r': { char buf[STRLEN]; ptr = &nbrd[num]; if(!(ptr->bh->brdattr & BRD_GROUPBOARD)) { /* «Dsub class */ if(!(ptr->bh->brdattr & BRD_HIDE) || (ptr->bh->brdattr & BRD_POSTMASK)) { brc_initial(ptr->bh->brdname); if(newflag) { setbdir(buf, currboard); tmp = unread_position(buf, ptr); head = tmp - t_lines / 2; getkeep(buf, head > 1 ? head : 1, tmp + 1); } board_visit_time = zapbuf[ptr->bid-1]; if(!(ptr->myattr&BRD_ZAP)) zapbuf[ptr->bid-1]=now; Read(); check_newpost(ptr); head = -1; setutmpmode(newflag ? READNEW : READBRD); } else { setbfile(buf, ptr->bh->brdname, FN_APPLICATION); if(more(buf,YEA)==-1) { move(1,0); clrtobot(); outs(privateboard); pressanykey(); } head = -1; } } else { /* sub class */ move(12,1); bidtmp = class_bid; currmodetmp =currmode; tmp1=num; num=0; class_bid = ptr->bid; if (!(currmode & MODE_MENU))/*¦pªGÁÙ¨S¦³¤p²ÕªøÅv­­ */ set_menu_BM(ptr->bh->BM); if(now < ptr->bh->bupdate) { setbfile(buf, ptr->bh->brdname, fn_notes); if(more(buf, NA) != -1) pressanykey(); } tmp=currutmp->brc_id; setutmpbid(ptr->bid); free(nbrd); choose_board(0); currmode = currmodetmp; /* Â÷¶}ª©ª©«á´N§âÅv­­®³±¼³á */ num=tmp1; class_bid = bidtmp; setutmpbid(tmp); brdnum = -1; } } } } while(ch != 'q'); free(nbrd); } int root_board() { class_bid = 1; yank_flag = 1; choose_board(0); return 0; } int Boards() { class_bid = 0; yank_flag = 0; choose_board(0); return 0; } int New() { int mode0 = currutmp->mode; int stat0 = currstat; class_bid = 0; choose_board(1); currutmp->mode = mode0; currstat = stat0; return 0; } /* int v_favorite(){ char fname[256]; char inbuf[2048]; FILE* fp; int nGroup; char* strtmp; setuserfile(fname,str_favorite); if (!(fp=fopen(fname,"r"))) return -1; move(0,0); clrtobot(); fgets(inbuf,sizeof(inbuf),fp); nGroup=atoi(inbuf); currutmp->nGroup=0; currutmp->ninRoot=0; while(nGroup!=currutmp->nGroup+1){ fgets(inbuf,sizeof(inbuf),fp); prints("%s\n",strtmp=strtok(inbuf," \n")); strcpy(currutmp->gfavorite[currutmp->nGroup++],strtmp); while((strtmp=strtok(NULL, " \n"))){ prints(" %s %d\n",strtmp,getbnum(strtmp)); } currutmp->nGroup++; } prints("+++%d+++\n",currutmp->nGroup); fgets(inbuf,sizeof(inbuf),fp); for(strtmp=strtok(inbuf, " \n");strtmp;strtmp=strtok(NULL, " \n")){ if (strtmp[0]!='#') prints("*** %s %d\n",strtmp, getbnum(strtmp)); else prints("*** %s %d\n",strtmp+1, -1); currutmp->ninRoot++; } fclose(fp); pressanykey(); return 0; } */