summaryrefslogtreecommitdiffstats
path: root/console/board.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 /console/board.c
parentf59699c22c130373cda3cc4cb6fab5bae510bd5a (diff)
downloadpttbbs-piaip.newlayout.tar
pttbbs-piaip.newlayout.tar.gz
pttbbs-piaip.newlayout.tar.bz2
pttbbs-piaip.newlayout.tar.lz
pttbbs-piaip.newlayout.tar.xz
pttbbs-piaip.newlayout.tar.zst
pttbbs-piaip.newlayout.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 'console/board.c')
-rw-r--r--console/board.c1960
1 files changed, 1960 insertions, 0 deletions
diff --git a/console/board.c b/console/board.c
new file mode 100644
index 00000000..f5cfe0de
--- /dev/null
+++ b/console/board.c
@@ -0,0 +1,1960 @@
+/* $Id$ */
+#include "bbs.h"
+
+/* personal board state
+ * ¬Û¹ï©ó¬ÝªOªº attr (BRD_* in ../include/pttstruct.h),
+ * ³o¨Ç¬O¥Î¦b user interface ªº flag */
+#define NBRD_FAV 1
+#define NBRD_BOARD 2
+#define NBRD_LINE 4
+#define NBRD_FOLDER 8
+#define NBRD_TAG 16
+#define NBRD_UNREAD 32
+#define NBRD_SYMBOLIC 64
+
+#define TITLE_MATCH(bptr, key) ((key)[0] && !strcasestr((bptr)->title, (key)))
+
+
+#define B_TOTAL(bptr) (SHM->total[(bptr)->bid - 1])
+#define B_LASTPOSTTIME(bptr) (SHM->lastposttime[(bptr)->bid - 1])
+#define B_BH(bptr) (&bcache[(bptr)->bid - 1])
+
+#define HasFavEditPerm() HasUserPerm(PERM_BASIC)
+
+typedef struct {
+ int bid;
+ unsigned char myattr;
+} __attribute__ ((packed)) boardstat_t;
+
+/**
+ * class_bid ªº·N¸q
+ * class_bid < 0 ¼öªù¬ÝªO
+ * class_bid = 0 §Úªº³Ì·R
+ * class_bid = 1 ¤ÀÃþ¬ÝªO
+ * class_bid > 1 ¨ä¥L¥Ø¿ý
+ */
+#define IN_HOTBOARD() (class_bid < 0)
+#define IN_FAVORITE() (class_bid == 0)
+#define IN_CLASSROOT() (class_bid == 1)
+#define IN_SUBCLASS() (class_bid > 1)
+#define IN_CLASS() (class_bid > 0)
+static int class_bid = 0;
+
+static int nbrdsize = 0;
+static boardstat_t *nbrd = NULL;
+static char choose_board_depth = 0;
+static int brdnum;
+static char yank_flag = 1;
+
+static time4_t last_save_fav_and_brc;
+
+/* These are all the states yank_flag may be. */
+// XXX IS_LISTING_FAV() does not mean we are in favorite.
+// That is controlled by IN_FAVORITE().
+#define LIST_FAV() (yank_flag = 0)
+#define LIST_BRD() (yank_flag = 1)
+#define IS_LISTING_FAV() (yank_flag == 0)
+#define IS_LISTING_BRD() (yank_flag == 1)
+
+inline int getbid(const boardheader_t *fh)
+{
+ return (fh - bcache);
+}
+inline boardheader_t *getparent(const boardheader_t *fh)
+{
+ if(fh->parent>0)
+ return getbcache(fh->parent);
+ else
+ return NULL;
+}
+
+/**
+ * @param[in] boardname board name, case insensitive
+ * @return 0 if success
+ * -1 if not found
+ * -2 permission denied
+ * -3 error
+ * @note enter board:
+ * 1. setup brc (currbid, currboard, currbrdattr)
+ * 2. set currbid, currBM, currmode, currdirect
+ * 3. utmp brc_id
+ */
+int enter_board(const char *boardname)
+{
+ boardheader_t *bh;
+ int bid;
+ char bname[IDLEN+1];
+ char bpath[60];
+ struct stat st;
+
+ /* checking ... */
+ if (boardname[0] == '\0' || !(bid = getbnum(boardname)))
+ return -1;
+ assert(0<=bid-1 && bid-1<MAX_BOARD);
+ bh = getbcache(bid);
+ if (!HasBoardPerm(bh))
+ return -2;
+
+ strlcpy(bname, bh->brdname, sizeof(bname));
+ if (bname[0] == '\0')
+ return -3;
+
+ setbpath(bpath, bname);
+ if (stat(bpath, &st) == -1) {
+ return -3;
+ }
+
+ /* really enter board */
+ brc_update();
+ brc_initial_board(bname);
+ setutmpbid(currbid);
+
+ set_board();
+ setbdir(currdirect, currboard);
+ curredit &= ~EDIT_MAIL;
+
+ return 0;
+}
+
+
+void imovefav(int old)
+{
+ char buf[5];
+ int new;
+
+ getdata(b_lines - 1, 0, "½Ð¿é¤J·s¦¸§Ç:", buf, sizeof(buf), DOECHO);
+ new = atoi(buf) - 1;
+ if (new < 0 || brdnum <= new){
+ vmsg("¿é¤J½d³ò¦³»~!");
+ return;
+ }
+ move_in_current_folder(old, new);
+}
+
+void
+init_brdbuf(void)
+{
+ if (brc_initialize())
+ return;
+}
+
+void
+save_brdbuf(void)
+{
+ fav_save();
+ fav_free();
+}
+
+int
+HasBoardPerm(boardheader_t *bptr)
+{
+ register int level, brdattr;
+
+ level = bptr->level;
+ brdattr = bptr->brdattr;
+
+ if (HasUserPerm(PERM_SYSOP))
+ return 1;
+
+ /* ªO¥D */
+ if( is_BM_cache(bptr - bcache + 1) ) /* XXXbid */
+ return 1;
+
+ /* ¯¦±K¬ÝªO¡G®Ö¹ï­º®uªO¥Dªº¦n¤Í¦W³æ */
+ if (brdattr & BRD_HIDE) { /* ÁôÂÃ */
+ if (!is_hidden_board_friend((int)(bptr - bcache) + 1, currutmp->uid)) {
+ if (brdattr & BRD_POSTMASK)
+ return 0;
+ else
+ return 2;
+ } else
+ return 1;
+ }
+
+ /* ¤Q¤K¸T¬ÝªO */
+ if( (brdattr & BRD_OVER18) && !over18 )
+ return 0;
+
+ /* ­­¨î¾\ŪÅv­­ */
+ if (level && !(brdattr & BRD_POSTMASK) && !HasUserPerm(level))
+ return 0;
+
+ return 1;
+}
+
+// board configuration utilities
+
+static int
+b_post_note(void)
+{
+ char buf[200], yn[3];
+
+ // if(!(currmode & MODE_BOARD)) return DONOTHING;
+ stand_title("¦Û­qª`·N¨Æ¶µ");
+
+ setbfile(buf, currboard, FN_POST_NOTE);
+ move(b_lines-2, 0); clrtobot();
+
+ if (more(buf, NA) == -1)
+ more("etc/" FN_POST_NOTE, NA);
+ getdata(b_lines - 2, 0, "¬O§_­n¥Î¦Û­qµo¤åª`·N¨Æ¶µ? [y/N]",
+ yn, sizeof(yn), LCECHO);
+ if (yn[0] == 'y')
+ vedit(buf, NA, NULL);
+ else
+ unlink(buf);
+
+ setbfile(buf, currboard, FN_POST_BID);
+ if (more(buf, NA) == -1)
+ more("etc/" FN_POST_BID, NA);
+ getdata(b_lines - 2, 0, "¬O§_­n¥Î¦Û­qÄv¼Ð¤å³¹ª`·N¨Æ¶µ? [y/N]",
+ yn, sizeof(yn), LCECHO);
+ if (yn[0] == 'y')
+ vedit(buf, NA, NULL);
+ else
+ unlink(buf);
+
+ return FULLUPDATE;
+}
+
+static int
+b_posttype()
+{
+ boardheader_t *bp;
+ int i, aborted;
+ char filepath[PATHLEN], genbuf[60], title[5], posttype_f, posttype[33]="";
+
+ // if(!(currmode & MODE_BOARD)) return DONOTHING;
+
+ assert(0<=currbid-1 && currbid-1<MAX_BOARD);
+ bp = getbcache(currbid);
+ stand_title("³]©w¤å³¹Ãþ§O");
+
+ move(2,0);
+ clrtobot();
+ posttype_f = bp->posttype_f;
+ for( i = 0 ; i < 8 ; ++i ){
+ move(2+i,0);
+ outs("¤å³¹ºØÃþ: ");
+ strlcpy(genbuf, bp->posttype + i * 4, 5);
+ sprintf(title, "%d.", i + 1);
+ if( !getdata_buf(2+i, 11, title, genbuf, 5, DOECHO) )
+ break;
+ sprintf(posttype + i * 4, "%-4.4s", genbuf);
+ if( posttype_f & (1<<i) ){
+ if( getdata(2+i, 20, "³]©w½d¥»®æ¦¡¡H(Y/n)", genbuf, 3, LCECHO) &&
+ genbuf[0]=='n' ){
+ posttype_f &= ~(1<<i);
+ continue;
+ }
+ }
+ else if ( !getdata(2+i, 20, "³]©w½d¥»®æ¦¡¡H(y/N)", genbuf, 3, LCECHO) ||
+ genbuf[0] != 'y' )
+ continue;
+
+ setbnfile(filepath, bp->brdname, "postsample", i);
+ aborted = vedit(filepath, NA, NULL);
+ if (aborted == -1) {
+ clear();
+ posttype_f &= ~(1<<i);
+ continue;
+ }
+ posttype_f |= (1<<i);
+ }
+ bp->posttype_f = posttype_f;
+ strlcpy(bp->posttype, posttype, sizeof(bp->posttype)); /* ³oÃäÀ³¸Ó­n¨¾race condition */
+
+ assert(0<=currbid-1 && currbid-1<MAX_BOARD);
+ substitute_record(fn_board, bp, sizeof(boardheader_t), currbid);
+ return FULLUPDATE;
+}
+
+// integrated board config
+int
+b_config(void)
+{
+ boardheader_t *bp=NULL;
+ int touched = 0, finished = 0;
+ bp = getbcache(currbid);
+ int i = 0, attr = 0, ipostres;
+ char isBM = (currmode & MODE_BOARD) || HasUserPerm(PERM_SYSOP);
+
+#define LNBOARDINFO (17)
+#define LNPOSTRES (12)
+#define COLPOSTRES (50)
+
+ int ytitle = b_lines - LNBOARDINFO;
+
+#ifdef OLDRECOMMEND
+ ytitle ++;
+#endif // OLDRECOMMEND
+
+ grayout(0, ytitle-2, GRAYOUT_DARK);
+
+ // available hotkeys yet:
+ // a b d j k p q z
+ // 2 3 4 5 6 7 9
+ // better not: l 0
+
+ while(!finished) {
+ move(ytitle-1, 0); clrtobot();
+ // outs(MSG_SEPERATOR); // deprecated by grayout
+ move(ytitle, 0);
+ outs(ANSI_COLOR(7) " " ); outs(bp->brdname); outs(" ¬ÝªO³]©w");
+ i = t_columns - strlen(bp->brdname) - strlen(" ¬ÝªO³]©w") - 2;
+ for (; i>0; i--)
+ outc(' ');
+ outs(ANSI_RESET);
+
+ move(ytitle +2, 0);
+ clrtobot();
+
+ prints(" ¤¤¤å±Ô­z: %s\n", bp->title);
+ prints(" ªO¥D¦W³æ: %s\n", (bp->BM[0] > ' ')? bp->BM : "(µL)");
+
+ outs(" \n"); // at least one character, for move_ansi.
+
+ prints( " " ANSI_COLOR(1;36) "h" ANSI_RESET
+ " - ¤½¶}ª¬ºA(¬O§_Áô§Î): %s " ANSI_RESET "\n",
+ (bp->brdattr & BRD_HIDE) ?
+ ANSI_COLOR(1)"Áô§Î":"¤½¶}");
+
+ prints( " " ANSI_COLOR(1;36) "g" ANSI_RESET
+ " - ÁôªO®É %s ¶i¤J¤Q¤j±Æ¦æº]" ANSI_RESET "\n",
+ (bp->brdattr & BRD_BMCOUNT) ?
+ ANSI_COLOR(1)"¥i¥H" ANSI_RESET:
+ "¤£¥i");
+
+ prints( " " ANSI_COLOR(1;36) "r" ANSI_RESET
+ " - %s " ANSI_RESET "±ÀÂˤ峹\n",
+ (bp->brdattr & BRD_NORECOMMEND) ?
+ ANSI_COLOR(31)"¤£¥i":"¥i¥H");
+
+#ifndef OLDRECOMMEND
+ prints( " " ANSI_COLOR(1;36) "b" ANSI_RESET
+ " - %s " ANSI_RESET "¼N¤å\n",
+ ((bp->brdattr & BRD_NORECOMMEND) || (bp->brdattr & BRD_NOBOO))
+ ? ANSI_COLOR(1)"¤£¥i":"¥i¥H");
+#endif
+ {
+ int d = 0;
+
+ if(bp->brdattr & BRD_NORECOMMEND)
+ {
+ d = -1;
+ } else {
+ if ((bp->brdattr & BRD_NOFASTRECMD) &&
+ (bp->fastrecommend_pause > 0))
+ d = bp->fastrecommend_pause;
+ }
+
+ prints( " " ANSI_COLOR(1;36) "f" ANSI_RESET
+ " - %s " ANSI_RESET "§Ö³t³s±À¤å³¹",
+ d != 0 ?
+ ANSI_COLOR(1)"­­¨î": "¥i¥H");
+ if(d > 0)
+ prints(", ³Ì§C¶¡¹j®É¶¡: %d ¬í", d);
+ outs("\n");
+ }
+
+ prints( " " ANSI_COLOR(1;36) "i" ANSI_RESET
+ " - ±À¤å®É %s" ANSI_RESET " °O¿ý¨Ó·½ IP\n",
+ (bp->brdattr & BRD_IPLOGRECMD) ?
+ ANSI_COLOR(1)"­n":"¤£¥Î");
+
+#ifdef USE_AUTOCPLOG
+ prints( " " ANSI_COLOR(1;36) "x" ANSI_RESET
+ " - Âà¿ý¤å³¹ %s " ANSI_RESET "¦Û°Ê°O¿ý¡A¥B %s "
+ ANSI_RESET "µo¤åÅv­­\n",
+ (bp->brdattr & BRD_CPLOG) ?
+ ANSI_COLOR(1)"·|" : "¤£·|" ,
+ (bp->brdattr & BRD_CPLOG) ?
+ ANSI_COLOR(1)"»Ý­n" : "¤£»Ý"
+ );
+#endif
+
+ prints( " " ANSI_COLOR(1;36) "L" ANSI_RESET
+ " - ­Y¦³Âà«H«hµo¤å®É¹w³] %s " ANSI_RESET "\n",
+ (bp->brdattr & BRD_LOCALSAVE) ?
+ "¯¸¤º¦sÀÉ(¤£Âà¥X)" : ANSI_COLOR(1)"¯¸»Ú¦sÀÉ(Âà¥X)" );
+
+ // use '8' instead of '1', to prevent 'l'/'1' confusion
+ prints( " " ANSI_COLOR(1;36) "8" ANSI_RESET
+ " - ¥¼º¡¤Q¤K·³ %s " ANSI_RESET
+ "¶i¤J\n", (bp->brdattr & BRD_OVER18) ?
+ ANSI_COLOR(1) "¤£¥i¥H" : "¥i¥H" );
+
+ prints( " " ANSI_COLOR(1;36) "y" ANSI_RESET
+ " - %s" ANSI_RESET
+ " ¦^¤å\n",
+ (bp->brdattr & BRD_NOREPLY) ?
+ ANSI_COLOR(1)"¤£¥i¥H" : "¥i¥H" );
+
+ prints( " " ANSI_COLOR(1;36) "e" ANSI_RESET
+ " - µo¤åÅv­­: %s" ANSI_RESET "\n",
+ (bp->brdattr & BRD_RESTRICTEDPOST) ?
+ ANSI_COLOR(1)"¥u¦³ªO¤Í¤~¥iµo¤å" : "µL¯S§O³]©w" );
+
+ ipostres = b_lines - LNPOSTRES;
+ move_ansi(ipostres++, COLPOSTRES-2);
+
+ if (CheckPostPerm() && CheckPostRestriction(currbid))
+ outs(ANSI_COLOR(1;32));
+ else
+ outs(ANSI_COLOR(1;31));
+ outs("µo¤å»P±À¤å­­¨î" ANSI_RESET);
+
+#define POSTRESTRICTION(msg,utag) \
+ prints(msg, attr ? ANSI_COLOR(1) : "", i, attr ? ANSI_RESET : "")
+
+ if (bp->post_limit_logins)
+ {
+ move_ansi(ipostres++, COLPOSTRES);
+ i = (int)bp->post_limit_logins * 10;
+ attr = (cuser.numlogins < i) ? 1 : 0;
+ if (attr) outs(ANSI_COLOR(31));
+ prints("¤W¯¸¦¸¼Æ %d ¦¸¥H¤W", i);
+ if (attr) outs(ANSI_RESET);
+ }
+
+ if (bp->post_limit_posts)
+ {
+ move_ansi(ipostres++, COLPOSTRES);
+ i = (int)bp->post_limit_posts * 10;
+ attr = (cuser.numposts < i) ? 1 : 0;
+ if (attr) outs(ANSI_COLOR(31));
+ prints("¤å³¹½g¼Æ %d ½g¥H¤W", i);
+ if (attr) outs(ANSI_RESET);
+ }
+
+ if (bp->post_limit_regtime)
+ {
+ move_ansi(ipostres++, COLPOSTRES);
+ i = bp->post_limit_regtime;
+ attr = (cuser.firstlogin >
+ (now - (time4_t)bp->post_limit_regtime * 2592000)) ? 1 : 0;
+ if (attr) outs(ANSI_COLOR(31));
+ prints("µù¥U®É¶¡ %d ­Ó¤ë¥H¤W",i);
+ if (attr) outs(ANSI_RESET);
+ }
+
+ // if (bp->post_limit_badpost)
+ {
+ move_ansi(ipostres++, COLPOSTRES);
+ i = 255 - bp->post_limit_badpost;
+ attr = (cuser.badpost > i) ? 1 : 0;
+ if (attr) outs(ANSI_COLOR(31));
+ prints("¦H¤å½g¼Æ %d ½g¥H¤U", i);
+ if (attr) outs(ANSI_RESET);
+ }
+
+ if (!CheckPostPerm())
+ {
+ const char *msg = postperm_msg(bp->brdname);
+ if (msg) // some reasons
+ {
+ move_ansi(ipostres++, COLPOSTRES);
+ outs(ANSI_COLOR(1;31));
+ outs(msg);
+ outs(ANSI_RESET);
+ }
+ }
+
+ // show BM commands
+ {
+ const char *aCat = ANSI_COLOR(1;32);
+ const char *aHot = ANSI_COLOR(1;36);
+ const char *aRst = ANSI_RESET;
+
+ if (!isBM)
+ {
+ aCat = ANSI_COLOR(1;30;40);
+ aHot = "";
+ aRst = "";
+ }
+
+ ipostres ++;
+ move_ansi(ipostres++, COLPOSTRES-2);
+ outs(aCat);
+ outs("¦W³æ½s¿è»P¨ä¥¦:");
+ if (!isBM) outs(" (»ÝªO¥DÅv­­)");
+ outs(aRst);
+ move_ansi(ipostres++, COLPOSTRES);
+ prints("%sv%s)¥i¨£¦W³æ %sw%s)¤ô±í¦W³æ ",
+ aHot, aRst, aHot, aRst);
+ move_ansi(ipostres++, COLPOSTRES);
+ prints("%sm%s)Á|¿ì§ë²¼ %so%s)§ë²¼¦W³æ ",
+ aHot, aRst, aHot, aRst);
+ move_ansi(ipostres++, COLPOSTRES);
+ prints("%sc%s)¤å³¹Ãþ§O %sn%s)µo¤åª`·N¨Æ¶µ ",
+ aHot, aRst, aHot, aRst);
+ outs(ANSI_RESET);
+ }
+
+ move(b_lines, 0);
+ if (!isBM)
+ {
+ vmsg("±z¹ï¦¹ªOµLºÞ²zÅv­­");
+ return FULLUPDATE;
+ }
+
+ switch(tolower(getans("½Ð¿é¤J­n§ïÅܪº³]©w, ¨ä¥¦Áäµ²§ô: ")))
+ {
+#ifdef USE_AUTOCPLOG
+ case 'x':
+ bp->brdattr ^= BRD_CPLOG;
+ touched = 1;
+ break;
+#endif
+ case 'l':
+ bp->brdattr ^= BRD_LOCALSAVE;
+ touched = 1;
+ break;
+
+ case 'e':
+ if(HasUserPerm(PERM_SYSOP))
+ {
+ bp->brdattr ^= BRD_RESTRICTEDPOST;
+ touched = 1;
+ } else {
+ vmsg("¦¹¶µ³]©w»Ý­n¯¸ªøÅv­­");
+ }
+ break;
+
+ case 'h':
+#ifndef BMCHS
+ if (!HasUserPerm(PERM_SYSOP))
+ {
+ vmsg("¦¹¶µ³]©w»Ý­n¯¸ªøÅv­­");
+ break;
+ }
+#endif
+ if(bp->brdattr & BRD_HIDE)
+ {
+ bp->brdattr &= ~BRD_HIDE;
+ bp->brdattr &= ~BRD_POSTMASK;
+ hbflreload(currbid);
+ } else {
+ bp->brdattr |= BRD_HIDE;
+ bp->brdattr |= BRD_POSTMASK;
+ }
+ touched = 1;
+ break;
+
+ case 'g':
+#ifndef BMCHS
+ if (!HasUserPerm(PERM_SYSOP))
+ {
+ vmsg("¦¹¶µ³]©w»Ý­n¯¸ªøÅv­­");
+ break;
+ }
+#endif
+ bp->brdattr ^= BRD_BMCOUNT;
+ touched = 1;
+ break;
+
+ case 'r':
+ bp->brdattr ^= BRD_NORECOMMEND;
+ touched = 1;
+ break;
+
+ case 'i':
+ bp->brdattr ^= BRD_IPLOGRECMD;
+ touched = 1;
+ break;
+
+ case 'f':
+ bp->brdattr &= ~BRD_NORECOMMEND;
+ bp->brdattr ^= BRD_NOFASTRECMD;
+ touched = 1;
+
+ if(bp->brdattr & BRD_NOFASTRECMD)
+ {
+ char buf[8] = "";
+
+ if(bp->fastrecommend_pause > 0)
+ sprintf(buf, "%d", bp->fastrecommend_pause);
+ getdata_str(b_lines-1, 0,
+ "½Ð¿é¤J³s±À®É¶¡­­¨î(³æ¦ì: ¬í) [5~240]: ",
+ buf, 4, ECHO, buf);
+ if(buf[0] >= '0' && buf[0] <= '9')
+ bp->fastrecommend_pause = atoi(buf);
+
+ if( bp->fastrecommend_pause < 5 ||
+ bp->fastrecommend_pause > 240)
+ {
+ if(buf[0])
+ {
+ vmsg("¿é¤J®É¶¡µL®Ä¡A½Ð¨Ï¥Î 5~240 ¤§¶¡ªº¼Æ¦r¡C");
+ }
+ bp->fastrecommend_pause = 0;
+ bp->brdattr &= ~BRD_NOFASTRECMD;
+ }
+ }
+ break;
+#ifndef OLDRECOMMEND
+ case 'b':
+ if(bp->brdattr & BRD_NORECOMMEND)
+ bp->brdattr |= BRD_NOBOO;
+ bp->brdattr ^= BRD_NOBOO;
+ touched = 1;
+ if (!(bp->brdattr & BRD_NOBOO))
+ bp->brdattr &= ~BRD_NORECOMMEND;
+ break;
+#endif
+ case '8':
+ if (!over18)
+ {
+ vmsg("ªO¥D¥»¨­¥¼º¡ 18 ·³¡C");
+ } else {
+ bp->brdattr ^= BRD_OVER18;
+ touched = 1;
+ }
+ break;
+
+ case 'v':
+ clear();
+ friend_edit(BOARD_VISABLE);
+ assert(0<=currbid-1 && currbid-1<MAX_BOARD);
+ hbflreload(currbid);
+ clear();
+ break;
+
+ case 'w':
+ clear();
+ friend_edit(BOARD_WATER);
+ clear();
+ break;
+
+ case 'o':
+ clear();
+ friend_edit(FRIEND_CANVOTE);
+ clear();
+
+ case 'm':
+ clear();
+ b_vote_maintain();
+ clear();
+ break;
+
+ case 'n':
+ clear();
+ b_post_note();
+ clear();
+ break;
+
+ case 'c':
+ clear();
+ b_posttype();
+ clear();
+ break;
+
+ case 'y':
+ if (!(HasUserPerm(PERM_SYSOP) || (HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP()) ) ) {
+ vmsg("¦¹¶µ³]©w»Ý­n¸s²Õªø©Î¯¸ªøÅv­­");
+ break;
+ }
+ bp->brdattr ^= BRD_NOREPLY;
+ touched = 1;
+ break;
+
+ default:
+ finished = 1;
+ break;
+ }
+ }
+ if(touched)
+ {
+ assert(0<=currbid-1 && currbid-1<MAX_BOARD);
+ substitute_record(fn_board, bp, sizeof(boardheader_t), currbid);
+ log_usies("SetBoard", bp->brdname);
+ vmsg("¤wÀx¦s·s³]©w");
+ }
+ else
+ vmsg("¥¼§ïÅÜ¥ô¦ó³]©w");
+
+ return FULLUPDATE;
+}
+
+static int
+check_newpost(boardstat_t * ptr)
+{ /* Ptt §ï */
+ time4_t ftime;
+
+ ptr->myattr &= ~NBRD_UNREAD;
+ if (B_BH(ptr)->brdattr & (BRD_GROUPBOARD | BRD_SYMBOLIC))
+ return 0;
+
+ if (B_TOTAL(ptr) == 0)
+ {
+ setbtotal(ptr->bid);
+ setbottomtotal(ptr->bid);
+ }
+ if (B_TOTAL(ptr) == 0)
+ return 0;
+ ftime = B_LASTPOSTTIME(ptr);
+
+ /* ¦³¨Ç util, ¤×¨ä¬O innbbsd, ·|¥Î¨ì¤ñ¸û·sªº time stamp,
+ * ¥u­n¤£¤Ó¸Ø±i´N ok */
+ if (ftime > now + 10)
+ ftime = B_LASTPOSTTIME(ptr) = now - 1;
+
+ if ( brc_unread_time(ptr->bid, ftime, 0) )
+ ptr->myattr |= NBRD_UNREAD;
+
+ return 1;
+}
+
+static void
+load_uidofgid(const int gid, const int type)
+{
+ boardheader_t *bptr, *currbptr, *parent;
+ int bid, n, childcount = 0;
+ assert(0<=type && type<2);
+ assert(0<= gid-1 && gid-1<MAX_BOARD);
+ currbptr = parent = &bcache[gid - 1];
+ assert(0<=numboards && numboards<=MAX_BOARD);
+ for (n = 0; n < numboards; ++n) {
+ bid = SHM->bsorted[type][n]+1;
+ if( bid<=0 || !(bptr = getbcache(bid))
+ || bptr->brdname[0] == '\0' )
+ continue;
+ if (bptr->gid == gid) {
+ if (currbptr == parent)
+ currbptr->firstchild[type] = bid;
+ else {
+ currbptr->next[type] = bid;
+ currbptr->parent = gid;
+ }
+ childcount++;
+ currbptr = bptr;
+ }
+ }
+ parent->childcount = childcount;
+ if (currbptr == parent) // no child
+ currbptr->firstchild[type] = -1;
+ else // the last child
+ currbptr->next[type] = -1;
+}
+
+static boardstat_t *
+addnewbrdstat(int n, int state)
+{
+ boardstat_t *ptr;
+
+ // ptt 2 local modification
+ // XXX maybe some developer discovered signed short issue?
+ assert(n != -32769);
+
+ assert(0<=n && n<MAX_BOARD);
+ assert(0<=brdnum && brdnum<nbrdsize);
+ ptr = &nbrd[brdnum++];
+ //boardheader_t *bptr = &bcache[n];
+ //ptr->total = &(SHM->total[n]);
+ //ptr->lastposttime = &(SHM->lastposttime[n]);
+
+ ptr->bid = n + 1;
+ ptr->myattr = state;
+ if ((B_BH(ptr)->brdattr & BRD_HIDE) && state == NBRD_BOARD)
+ B_BH(ptr)->brdattr |= BRD_POSTMASK;
+ if (!IS_LISTING_FAV())
+ ptr->myattr &= ~NBRD_FAV;
+ check_newpost(ptr);
+ return ptr;
+}
+
+#if !HOTBOARDCACHE
+static int
+cmpboardfriends(const void *brd, const void *tmp)
+{
+#ifdef USE_COOLDOWN
+ if ((B_BH((boardstat_t*)tmp)->brdattr & BRD_COOLDOWN) &&
+ (B_BH((boardstat_t*)brd)->brdattr & BRD_COOLDOWN))
+ return 0;
+ else if ( B_BH((boardstat_t*)tmp)->brdattr & BRD_COOLDOWN ) {
+ if (B_BH((boardstat_t*)brd)->nuser == 0)
+ return 0;
+ else
+ return 1;
+ }
+ else if ( B_BH((boardstat_t*)brd)->brdattr & BRD_COOLDOWN ) {
+ if (B_BH((boardstat_t*)tmp)->nuser == 0)
+ return 0;
+ else
+ return -1;
+ }
+#endif
+ return ((B_BH((boardstat_t*)tmp)->nuser) -
+ (B_BH((boardstat_t*)brd)->nuser));
+}
+#endif
+
+static void
+load_boards(char *key)
+{
+ int type = cuser.uflag & BRDSORT_FLAG ? 1 : 0;
+ int i;
+ int state;
+
+ brdnum = 0;
+ if (nbrd) {
+ free(nbrd);
+ nbrdsize = 0;
+ nbrd = NULL;
+ }
+ if (!IN_CLASS()) {
+ if(IS_LISTING_FAV()){
+ fav_t *fav = get_current_fav();
+ int nfav = get_data_number(fav);
+ if( nfav == 0 ) {
+ nbrdsize = 1;
+ nbrd = (boardstat_t *)malloc(sizeof(boardstat_t) * 1);
+ addnewbrdstat(0, 0); // dummy
+ return;
+ }
+ nbrdsize = nfav;
+ nbrd = (boardstat_t *)malloc(sizeof(boardstat_t) * nfav);
+ for( i = 0 ; i < fav->DataTail; ++i ){
+ int state;
+ if (!(fav->favh[i].attr & FAVH_FAV))
+ continue;
+
+ if ( !key[0] ){
+ if (get_item_type(&fav->favh[i]) == FAVT_LINE )
+ state = NBRD_LINE;
+ else if (get_item_type(&fav->favh[i]) == FAVT_FOLDER )
+ state = NBRD_FOLDER;
+ else {
+ state = NBRD_BOARD;
+ if (is_set_attr(&fav->favh[i], FAVH_UNREAD))
+ state |= NBRD_UNREAD;
+ }
+ } else {
+ if (get_item_type(&fav->favh[i]) == FAVT_LINE )
+ continue;
+ else if (get_item_type(&fav->favh[i]) == FAVT_FOLDER ){
+ if( strcasestr(
+ get_folder_title(fav_getid(&fav->favh[i])),
+ key)
+ )
+ state = NBRD_FOLDER;
+ else
+ continue;
+ }else{
+ boardheader_t *bptr = getbcache(fav_getid(&fav->favh[i]));
+ assert(0<=fav_getid(&fav->favh[i])-1 && fav_getid(&fav->favh[i])-1<MAX_BOARD);
+ if (strcasestr(bptr->title, key))
+ state = NBRD_BOARD;
+ else
+ continue;
+ if (is_set_attr(&fav->favh[i], FAVH_UNREAD))
+ state |= NBRD_UNREAD;
+ }
+ }
+
+ if (is_set_attr(&fav->favh[i], FAVH_TAG))
+ state |= NBRD_TAG;
+ if (is_set_attr(&fav->favh[i], FAVH_ADM_TAG))
+ state |= NBRD_TAG;
+ // ¦³¨Ç¤H ¬Y¨Ç bid < 0 Orzz // ptt2 local modification
+ if (fav_getid(&fav->favh[i]) < 1)
+ continue;
+ addnewbrdstat(fav_getid(&fav->favh[i]) - 1, NBRD_FAV | state);
+ }
+ }
+#if HOTBOARDCACHE
+ else if(IN_HOTBOARD()){
+ nbrdsize = SHM->nHOTs;
+ if(nbrdsize == 0) {
+ nbrdsize = 1;
+ nbrd = (boardstat_t *)malloc(sizeof(boardstat_t) * 1);
+ addnewbrdstat(0, 0); // dummy
+ return;
+ }
+ assert(0<nbrdsize);
+ nbrd = (boardstat_t *)malloc(sizeof(boardstat_t) * nbrdsize);
+ for( i = 0 ; i < nbrdsize; ++i ) {
+ if(SHM->HBcache[i] == -1)
+ continue;
+ addnewbrdstat(SHM->HBcache[i], HasBoardPerm(&bcache[SHM->HBcache[i]]));
+ }
+ }
+#endif
+ else { // general case
+ nbrdsize = numboards;
+ assert(0<nbrdsize && nbrdsize<=MAX_BOARD);
+ nbrd = (boardstat_t *) malloc(sizeof(boardstat_t) * nbrdsize);
+ for (i = 0; i < nbrdsize; i++) {
+ int n = SHM->bsorted[type][i];
+ boardheader_t *bptr;
+ if (n < 0)
+ continue;
+ bptr = &bcache[n];
+ if (bptr == NULL)
+ continue;
+ if (!bptr->brdname[0] ||
+ (bptr->brdattr & (BRD_GROUPBOARD | BRD_SYMBOLIC)) ||
+ !((state = HasBoardPerm(bptr)) || GROUPOP()) ||
+ TITLE_MATCH(bptr, key)
+#if ! HOTBOARDCACHE
+ || (IN_HOTBOARD() && bptr->nuser < 5)
+#endif
+ )
+ continue;
+ addnewbrdstat(n, state);
+ }
+ }
+#if ! HOTBOARDCACHE
+ if (IN_HOTBOARD())
+ qsort(nbrd, brdnum, sizeof(boardstat_t), cmpboardfriends);
+#endif
+ } else { /* load boards of a subclass */
+ boardheader_t *bptr = getbcache(class_bid);
+ int childcount;
+ int bid;
+
+ assert(0<=class_bid-1 && class_bid-1<MAX_BOARD);
+ if (bptr->firstchild[type] == 0 || bptr->childcount==0)
+ load_uidofgid(class_bid, type);
+
+ childcount = bptr->childcount; // Ptt: child count after load_uidofgid
+
+ nbrdsize = childcount + 5;
+ nbrd = (boardstat_t *) malloc((childcount+5) * sizeof(boardstat_t));
+ // ¹w¯d¨â­Ó¥H§K¤j¶q¶}ªO®É±¾½Õ
+ for (bid = bptr->firstchild[type]; bid > 0 &&
+ brdnum < childcount+5; bid = bptr->next[type]) {
+ assert(0<=bid-1 && bid-1<MAX_BOARD);
+ bptr = getbcache(bid);
+ state = HasBoardPerm(bptr);
+ if ( !(state || GROUPOP()) || TITLE_MATCH(bptr, key) )
+ continue;
+
+ if (bptr->brdattr & BRD_SYMBOLIC) {
+ /* Only SYSOP knows a board is symbolic */
+ if (HasUserPerm(PERM_SYSOP) || HasUserPerm(PERM_SYSSUPERSUBOP))
+ state |= NBRD_SYMBOLIC;
+ else {
+ bid = BRD_LINK_TARGET(bptr);
+ if (bcache[bid - 1].brdname[0] == 0) {
+ vmsg("³sµ²¤w·l·´¡A½Ð¦Ü SYSOP ¦^³ø¦¹°ÝÃD¡C");
+ continue;
+ }
+ }
+ }
+ assert(0<=bid-1 && bid-1<MAX_BOARD);
+ addnewbrdstat(bid-1, state);
+ }
+ if(childcount < brdnum) {
+ //Ptt: dirty fix fix soon
+ getbcache(class_bid)->childcount = 0;
+ }
+
+
+ }
+}
+
+static int
+search_board(void)
+{
+ int num;
+ char genbuf[IDLEN + 2];
+ struct NameList namelist;
+
+ move(0, 0);
+ clrtoeol();
+ NameList_init(&namelist);
+ assert(brdnum<=nbrdsize);
+ NameList_resizefor(&namelist, brdnum);
+ for (num = 0; num < brdnum; num++)
+ if (!IS_LISTING_FAV() ||
+ (nbrd[num].myattr & NBRD_BOARD && HasBoardPerm(B_BH(&nbrd[num]))) )
+ NameList_add(&namelist, B_BH(&nbrd[num])->brdname);
+ namecomplete2(&namelist, MSG_SELECT_BOARD, genbuf);
+ NameList_delete(&namelist);
+
+#ifdef DEBUG
+ vmsg(genbuf);
+#endif
+
+ for (num = 0; num < brdnum; num++)
+ if (!strcasecmp(B_BH(&nbrd[num])->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 = B_TOTAL(ptr);
+ num = total + 1;
+ if ((ptr->myattr & NBRD_UNREAD) && (fd = open(dirfile, O_RDWR)) > 0) {
+ if (!brc_initial_board(B_BH(ptr)->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(ptr->bid, fname, 0))
+ 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(ptr->bid, fname, 0))
+ break;
+ num++;
+ }
+ }
+ close(fd);
+ }
+ if (num < 0)
+ num = 0;
+ return num;
+}
+
+static char
+get_fav_type(boardstat_t *ptr)
+{
+ if (ptr->myattr & NBRD_FOLDER)
+ return FAVT_FOLDER;
+ else if (ptr->myattr & NBRD_BOARD)
+ return FAVT_BOARD;
+ else if (ptr->myattr & NBRD_LINE)
+ return FAVT_LINE;
+ return 0;
+}
+
+static void
+brdlist_foot(void)
+{
+ outs( ANSI_COLOR(34;46) " ¿ï¾Ü¬ÝªO "
+ ANSI_COLOR(31;47) " (c)" ANSI_COLOR(30) "·s¤å³¹¼Ò¦¡ "
+ ANSI_COLOR(31) "(v/V)" ANSI_COLOR(30) "¼Ð¬°¤wŪ/¥¼Åª "
+ ANSI_COLOR(31) "(y)" ANSI_COLOR(30));
+ if(IS_LISTING_FAV())
+ outs("¦C¥X¥þ³¡");
+ else if (IS_LISTING_BRD())
+ outs("¿z¿ï¦Cªí");
+ else outs("¿z¿ï¦Cªí"); // never reach here?
+
+ outslr(" " ANSI_COLOR(31) "(m)" ANSI_COLOR(30) "¤Á´«³Ì·R",
+ 73, ANSI_RESET, 0);
+}
+
+
+static inline char *
+make_class_color(char *name)
+{
+ /* 34 is too dark */
+ char *colorset[8] = {"", ANSI_COLOR(32),
+ ANSI_COLOR(33), ANSI_COLOR(36), ANSI_COLOR(1;34),
+ ANSI_COLOR(1), ANSI_COLOR(1;32), ANSI_COLOR(1;33)};
+
+ return colorset[(unsigned int)
+ (name[0] + name[1] +
+ name[2] + name[3]) & 0x7];
+}
+
+#define HILIGHT_COLOR ANSI_COLOR(1;36)
+
+static void
+show_brdlist(int head, int clsflag, int newflag)
+{
+ int myrow = 2;
+ if (unlikely(IN_CLASSROOT())) {
+ currstat = CLASS;
+ myrow = 6;
+ showtitle("¤ÀÃþ¬ÝªO", BBSName);
+ movie(0);
+ move(1, 0);
+ // TODO remove ascii art here
+ outs(
+ " "
+ "¢© ¢~¡X" ANSI_COLOR(33) "¡´\n"
+ " ùá¡X " ANSI_RESET " "
+ "¢¨¢i" ANSI_COLOR(47) "¡ó" ANSI_COLOR(40) "¢i¢i¢©ùç\n"
+ " " ANSI_COLOR(44) " ¡s¡s¡s¡s¡s¡s¡s¡s "
+ ANSI_COLOR(33) "ùø" ANSI_RESET ANSI_COLOR(44) " ¢©¢¨¢i¢i¢i¡¿¡¿¡¿ùø " ANSI_RESET "\n"
+ " " ANSI_COLOR(44) " "
+ ANSI_COLOR(33) " " ANSI_RESET ANSI_COLOR(44) " ¢«¢ª¢i¢i¢i¡¶¡¶¡¶ ùø" ANSI_RESET "\n"
+ " ¡s¡s¡s¡s¡s¡s¡s¡s " ANSI_COLOR(33)
+ "¢x" ANSI_RESET " ¢ª¢i¢i¢i¢i¢« ùø\n"
+ " " ANSI_COLOR(33) "ùó"
+ "¡X¡X" ANSI_RESET " ¢« ¡X¡Ï" ANSI_RESET);
+ } else if (clsflag) {
+ showtitle("¬ÝªO¦Cªí", BBSName);
+ // [m]¥[¤J©Î²¾¥X§Úªº³Ì·R
+ outs("[¡ö][q]¥D¿ï³æ [¡÷][r]¾\\Ū [¡ô¡õ]¿ï¾Ü [PgUp][PgDn]½­¶ [S]±Æ§Ç [/]·j´M [h]¨D§U\n");
+ outs(ANSI_COLOR(7));
+
+ // boards in Ptt series are very, very large.
+ // let's create more space for board numbers,
+ // and less space for BM.
+ //
+ // newflag is not so different now because we use all 5 digits.
+
+ outs( newflag ? " Á`¼Æ" : " ½s¸¹");
+ outs(" ¬Ý ªO Ãþ§O Âà«H ¤¤ ¤å ±Ô ­z ¤H®ð ªO ¥D");
+ outslr("", 74, ANSI_RESET, 0);
+ move(b_lines, 0);
+ brdlist_foot();
+ }
+ if (brdnum > 0) {
+ boardstat_t *ptr;
+ char *unread[2] = {ANSI_COLOR(37) " " ANSI_RESET, ANSI_COLOR(1;31) "£¾" ANSI_RESET};
+
+ if (IS_LISTING_FAV() && brdnum == 1 && get_fav_type(&nbrd[0]) == 0) {
+
+ // (a) or (i) needs HasUserPerm(PERM_LOGINOK)).
+ // 3 = first line of empty area
+ if (!HasFavEditPerm())
+ {
+ // TODO actually we cannot use 's' (for PTT)...
+ mouts(3, 10,
+ "--- µù¥Uªº¨Ï¥ÎªÌ¤~¯à·s¼W¬ÝªO³á (¥i«ö s ¤â°Ê¿ï¨ú) ---");
+ } else {
+ // normal user. tell him what to do.
+ mouts(3, 10,
+ "--- ªÅ¥Ø¿ý¡A½Ð«ö a ·s¼W©Î¥Î y ¦C¥X¥þ³¡¬ÝªO«á«ö z ¼W§R ---");
+ }
+ return;
+ }
+
+ while (++myrow < b_lines) {
+
+ move(myrow, 0);
+ clrtoeol();
+
+ if (head < brdnum) {
+ assert(0<=head && head<nbrdsize);
+ ptr = &nbrd[head++];
+ if (ptr->myattr & NBRD_LINE){
+ if( !newflag )
+ prints("%7d %c ", head, ptr->myattr & NBRD_TAG ? 'D' : ' ');
+ else
+ prints("%7s ", "");
+
+ if (!(ptr->myattr & NBRD_FAV))
+ outs(ANSI_COLOR(1;30));
+
+ outs("------------"
+ " "
+ // "------"
+ "------------------------------------------"
+ ANSI_RESET "\n");
+ continue;
+ }
+ else if (ptr->myattr & NBRD_FOLDER){
+ char *title = get_folder_title(ptr->bid);
+ prints("%7d %c ",
+ newflag ?
+ get_data_number(get_fav_folder(getfolder(ptr->bid))) :
+ head, ptr->myattr & NBRD_TAG ? 'D' : ' ');
+
+ // well, what to print with myfav folders?
+ // this style is too long and we don't want to
+ // fight with users...
+ // think about new way some otherday.
+ prints("%sMyFavFolder" ANSI_RESET " ¥Ø¿ý ¡¼%-34s",
+ !(cuser.uflag2 & FAVNOHILIGHT)?HILIGHT_COLOR : "",
+ title);
+ /*
+ if (!(cuser.uflag2 & FAVNOHILIGHT))
+ outs(HILIGHT_COLOR);
+ prints("%-12s", "[Folder]");
+ outs(ANSI_RESET);
+ prints(" ¥Ø¿ý £U%-34s", title);
+ */
+ /*
+ outs(ANSI_COLOR(0;36));
+ prints("£U%-70.70s", title);
+ outs(ANSI_RESET);
+ */
+ continue;
+ }
+
+ if (IN_CLASSROOT())
+ outs(" ");
+ else {
+ if (!GROUPOP() && !HasBoardPerm(B_BH(ptr))) {
+ if (newflag) prints("%7s", "");
+ else prints("%7d", head);
+ prints(" %c Unknown?? ÁôªO ¡H³o­ÓªO¬OÁôªO",
+ ptr->myattr & NBRD_TAG ? 'D' : ' ');
+ continue;
+ }
+ }
+
+ if (newflag && B_BH(ptr)->brdattr & BRD_GROUPBOARD)
+ outs(" ");
+ else
+ prints("%7d%c%s",
+ newflag ? (int)(B_TOTAL(ptr)) : head,
+ !(B_BH(ptr)->brdattr & BRD_HIDE) ? ' ' :
+ (B_BH(ptr)->brdattr & BRD_POSTMASK) ? ')' : '-',
+ (ptr->myattr & NBRD_TAG) ? "D " :
+ (B_BH(ptr)->brdattr & BRD_GROUPBOARD) ? " " :
+ unread[ptr->myattr & NBRD_UNREAD ? 1 : 0]);
+
+ if (!IN_CLASSROOT()) {
+ prints("%s%-13s" ANSI_RESET "%s%5.5s" ANSI_COLOR(0;37)
+ "%2.2s" ANSI_RESET "%-34.34s",
+ ((!(cuser.uflag2 & FAVNOHILIGHT) &&
+ getboard(ptr->bid) != NULL))? HILIGHT_COLOR : "",
+ B_BH(ptr)->brdname,
+ make_class_color(B_BH(ptr)->title),
+ B_BH(ptr)->title, B_BH(ptr)->title + 5, B_BH(ptr)->title + 7);
+
+#ifdef USE_COOLDOWN
+ if (B_BH(ptr)->brdattr & BRD_COOLDOWN)
+ outs("ÀR ");
+ else if (B_BH(ptr)->brdattr & BRD_BAD)
+#else
+ if (B_BH(ptr)->brdattr & BRD_BAD)
+#endif
+ outs(" X ");
+
+ else if (B_BH(ptr)->nuser <= 0)
+ prints(" %c ", B_BH(ptr)->bvote ? 'V' : ' ');
+ else if (B_BH(ptr)->nuser <= 10)
+ prints("%2d ", B_BH(ptr)->nuser);
+ else if (B_BH(ptr)->nuser <= 50)
+ prints(ANSI_COLOR(1;33) "%2d" ANSI_RESET " ", B_BH(ptr)->nuser);
+#ifdef EXTRA_HOTBOARD_COLORS
+ // piaip 2008/02/04: new colors
+ else if (B_BH(ptr)->nuser >= 100000)
+ outs(ANSI_COLOR(1;35) "Ãz!" ANSI_RESET);
+ else if (B_BH(ptr)->nuser >= 60000)
+ outs(ANSI_COLOR(1;33) "Ãz!" ANSI_RESET);
+ else if (B_BH(ptr)->nuser >= 30000)
+ outs(ANSI_COLOR(1;32) "Ãz!" ANSI_RESET);
+ else if (B_BH(ptr)->nuser >= 10000)
+ outs(ANSI_COLOR(1;36) "Ãz!" ANSI_RESET);
+#endif
+ else if (B_BH(ptr)->nuser >= 5000)
+ outs(ANSI_COLOR(1;34) "Ãz!" ANSI_RESET);
+ else if (B_BH(ptr)->nuser >= 2000)
+ outs(ANSI_COLOR(1;31) "Ãz!" ANSI_RESET);
+ else if (B_BH(ptr)->nuser >= 1000)
+ outs(ANSI_COLOR(1) "Ãz!" ANSI_RESET);
+ else if (B_BH(ptr)->nuser >= 100)
+ outs(ANSI_COLOR(1) "HOT" ANSI_RESET);
+ else //if (B_BH(ptr)->nuser > 50)
+ prints(ANSI_COLOR(1;31) "%2d" ANSI_RESET " ", B_BH(ptr)->nuser);
+ prints("%.*s" ANSI_CLRTOEND, t_columns - 68, B_BH(ptr)->BM);
+ } else {
+ prints("%-40.40s %.*s", B_BH(ptr)->title + 7,
+ t_columns - 68, B_BH(ptr)->BM);
+ }
+ }
+ clrtoeol();
+ }
+ }
+}
+
+static void
+set_menu_BM(char *BM)
+{
+ if (!HasUserPerm(PERM_NOCITIZEN) && (HasUserPerm(PERM_ALLBOARD) || is_BM(BM))) {
+ currmode |= MODE_GROUPOP;
+ cuser.userlevel |= PERM_SYSSUBOP;
+ }
+}
+
+static void replace_link_by_target(boardstat_t *board)
+{
+ assert(0<=board->bid-1 && board->bid-1<MAX_BOARD);
+ board->bid = BRD_LINK_TARGET(getbcache(board->bid));
+ board->myattr &= ~NBRD_SYMBOLIC;
+}
+static int
+paste_taged_brds(int gid)
+{
+ fav_t *fav;
+ int bid, tmp;
+
+ if (gid == 0 || ! (HasUserPerm(PERM_SYSOP) || GROUPOP()) ||
+ getans("¶K¤W¼Ð°Oªº¬ÝªO?(y/N)")!='y') return 0;
+ fav = get_fav_root();
+ for (tmp = 0; tmp < fav->DataTail; tmp++) {
+ boardheader_t *bh;
+ bid = fav_getid(&fav->favh[tmp]);
+ assert(0<=bid-1 && bid-1<MAX_BOARD);
+ bh = getbcache(bid);
+ if( !is_set_attr(&fav->favh[tmp], FAVH_ADM_TAG))
+ continue;
+ set_attr(&fav->favh[tmp], FAVH_ADM_TAG, FALSE);
+ if (bh->gid != gid) {
+ bh->gid = gid;
+ assert(0<=bid-1 && bid-1<MAX_BOARD);
+ substitute_record(FN_BOARD, bh,
+ sizeof(boardheader_t), bid);
+ reset_board(bid);
+ log_usies("SetBoardGID", bh->brdname);
+ }
+ }
+ sort_bcache();
+ return 1;
+}
+
+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] = "", buf[PATHLEN];
+
+ setutmpmode(newflag ? READNEW : READBRD);
+ if( get_fav_root() == NULL )
+ fav_load();
+ ++choose_board_depth;
+ brdnum = 0;
+ if (!cuser.userlevel) /* guest yank all boards */
+ LIST_BRD();
+
+ do {
+ if (brdnum <= 0) {
+ load_boards(keyword);
+ if (brdnum <= 0) {
+ if (keyword[0] != 0) {
+ vmsg("¨S¦³¥ô¦ó¬ÝªO¼ÐÃD¦³¦¹ÃöÁä¦r");
+ keyword[0] = 0;
+ brdnum = -1;
+ continue;
+ }
+ if (IS_LISTING_BRD()) {
+ if (HasUserPerm(PERM_SYSOP) || GROUPOP()) {
+ if (paste_taged_brds(class_bid) ||
+ m_newbrd(class_bid, 0) == -1)
+ break;
+ brdnum = -1;
+ continue;
+ } else
+ break;
+ }
+ }
+ head = -1;
+ }
+
+ /* reset the cursor when out of range */
+ if (num < 0)
+ num = 0;
+ else if (num >= brdnum)
+ num = brdnum - 1;
+
+ if (head < 0) {
+ if (newflag) {
+ tmp = num;
+ assert(brdnum<=nbrdsize);
+ while (num < brdnum) {
+ ptr = &nbrd[num];
+ if (ptr->myattr & NBRD_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 (IN_CLASSROOT())
+ ch = cursor_key(7 + num - head, 10);
+ else
+ ch = cursor_key(3 + num - head, 0);
+
+ switch (ch) {
+
+ ///////////////////////////////////////////////////////
+ // General Hotkeys
+ ///////////////////////////////////////////////////////
+
+ case 'h':
+ show_helpfile(fn_boardlisthelp);
+ show_brdlist(head, 1, newflag);
+ break;
+ case Ctrl('W'):
+ whereami();
+ head = -1;
+ break;
+
+ case 'c':
+ show_brdlist(head, 1, newflag ^= 1);
+ break;
+ case Ctrl('I'):
+ t_idle();
+ show_brdlist(head, 1, newflag);
+ break;
+
+ case 'e':
+ case KEY_LEFT:
+ case EOF:
+ ch = 'q';
+ case 'q':
+ if (keyword[0]) {
+ keyword[0] = 0;
+ brdnum = -1;
+ ch = ' ';
+ }
+ 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 KEY_UP:
+ case 'p':
+ case 'k':
+ if (num-- <= 0)
+ num = brdnum - 1;
+ break;
+ case '*':
+ if (IS_LISTING_FAV()) {
+ int i = 0;
+ assert(brdnum<=nbrdsize);
+ for (i = 0; i < brdnum; i++)
+ {
+ ptr = &nbrd[i];
+ if (IS_LISTING_FAV()){
+ assert(nbrdsize>0);
+ if(get_fav_type(&nbrd[0]) != 0)
+ fav_tag(ptr->bid, get_fav_type(ptr), 2);
+ }
+ ptr->myattr ^= NBRD_TAG;
+ }
+ head = 9999;
+ }
+ break;
+ case 't':
+ assert(0<=num && num<nbrdsize);
+ ptr = &nbrd[num];
+ if (IS_LISTING_FAV()){
+ assert(nbrdsize>0);
+ if(get_fav_type(&nbrd[0]) != 0)
+ fav_tag(ptr->bid, get_fav_type(ptr), EXCH);
+ }
+ else if (HasUserPerm(PERM_SYSOP) ||
+ HasUserPerm(PERM_SYSSUPERSUBOP) ||
+ HasUserPerm(PERM_SYSSUBOP) ||
+ HasUserPerm(PERM_BOARD)) {
+ /* ¯¸ªøºÞ²z¥Îªº tag */
+ if (ptr->myattr & NBRD_TAG)
+ set_attr(getadmtag(ptr->bid), FAVH_ADM_TAG, FALSE);
+ else
+ fav_add_admtag(ptr->bid);
+ }
+ ptr->myattr ^= NBRD_TAG;
+ 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 '/':
+ getdata_buf(b_lines - 1, 0, "½Ð¿é¤J¬ÝªO¤¤¤åÃöÁä¦r:",
+ keyword, sizeof(keyword), DOECHO);
+ brdnum = -1;
+ break;
+ case 'S':
+ if(IS_LISTING_FAV()){
+ move(b_lines - 2, 0); clrtobot();
+ outs("­«·s±Æ§Ç¬ÝªO "
+ ANSI_COLOR(1;33) "(ª`·N, ³o­Ó°Ê§@·|Âмg­ì¨Ó³]©w)" ANSI_RESET " \n");
+ tmp = getans("±Æ§Ç¤è¦¡ (1)«ö·ÓªO¦W±Æ§Ç (2)«ö·ÓÃþ§O±Æ§Ç ==> [0]¨ú®ø ");
+ if( tmp == '1' )
+ fav_sort_by_name();
+ else if( tmp == '2' )
+ fav_sort_by_class();
+ }
+ else
+ cuser.uflag ^= BRDSORT_FLAG;
+ brdnum = -1;
+ break;
+
+
+ case 'v':
+ case 'V':
+ assert(0<=num && num<nbrdsize);
+ ptr = &nbrd[num];
+ if(nbrd[num].bid < 0 || !HasBoardPerm(B_BH(ptr)))
+ break;
+ if (ch == 'v') {
+ ptr->myattr &= ~NBRD_UNREAD;
+ brc_toggle_all_read(ptr->bid, 1);
+ } else {
+ brc_toggle_all_read(ptr->bid, 0);
+ ptr->myattr |= NBRD_UNREAD;
+ }
+ show_brdlist(head, 0, newflag);
+ break;
+ case 's':
+ if ((tmp = search_board()) != -1) {
+ head = -1;
+ num = tmp;
+ break;
+ }
+ // TODO try global search?
+ // TODO entering boards is now too complex...
+ // please refine the code.
+ //
+ // if (Select() != NEWDIRECT) {
+ // }
+
+ // update screen
+ head = -1;
+ num = tmp;
+ break;
+
+ case KEY_RIGHT:
+ case '\n':
+ case '\r':
+ case 'r':
+ {
+ if (IS_LISTING_FAV()) {
+ assert(nbrdsize>0);
+ if (get_fav_type(&nbrd[0]) == 0)
+ break;
+ assert(0<=num && num<nbrdsize);
+ ptr = &nbrd[num];
+ if (ptr->myattr & NBRD_LINE)
+ break;
+ if (ptr->myattr & NBRD_FOLDER){
+ int t = num;
+ num = 0;
+ fav_folder_in(ptr->bid);
+ choose_board(0);
+ fav_folder_out();
+ num = t;
+ LIST_FAV(); // XXX press 'y' in fav makes yank_flag = LIST_BRD
+ brdnum = -1;
+ head = 9999;
+ break;
+ }
+ } else {
+ assert(0<=num && num<nbrdsize);
+ ptr = &nbrd[num];
+ if (ptr->myattr & NBRD_SYMBOLIC) {
+ replace_link_by_target(ptr);
+ }
+ }
+
+ assert(0<=ptr->bid-1 && ptr->bid-1<MAX_BOARD);
+ if (!(B_BH(ptr)->brdattr & BRD_GROUPBOARD)) { /* «Dsub class */
+ if (HasBoardPerm(B_BH(ptr))) {
+ brc_initial_board(B_BH(ptr)->brdname);
+
+ if (newflag) {
+ setbdir(buf, currboard);
+ tmp = unread_position(buf, ptr);
+ head = tmp - t_lines / 2;
+ getkeep(buf, head > 1 ? head : 1, tmp + 1);
+ }
+ Read();
+ check_newpost(ptr);
+ head = -1;
+ setutmpmode(newflag ? READNEW : READBRD);
+ }
+ } else { /* sub class */
+ move(12, 1);
+ bidtmp = class_bid;
+ currmodetmp = currmode;
+ tmp1 = num;
+ num = 0;
+ if (!(B_BH(ptr)->brdattr & BRD_TOP))
+ class_bid = ptr->bid;
+ else
+ class_bid = -1; /* ¼öªù¸s²Õ¥Î */
+
+ if (!GROUPOP()) /* ¦pªGÁÙ¨S¦³¤p²ÕªøÅv­­ */
+ set_menu_BM(B_BH(ptr)->BM);
+
+ if (now < B_BH(ptr)->bupdate) {
+ int mr = 0;
+
+ setbfile(buf, B_BH(ptr)->brdname, fn_notes);
+ mr = more(buf, NA);
+ if (mr != -1 && mr != READ_NEXT)
+ pressanykey();
+ }
+ tmp = currutmp->brc_id;
+ setutmpbid(ptr->bid);
+ free(nbrd);
+ nbrd = NULL;
+ nbrdsize = 0;
+ if (IS_LISTING_FAV()) {
+ LIST_BRD();
+ choose_board(0);
+ LIST_FAV();
+ }
+ else
+ choose_board(0);
+ currmode = currmodetmp; /* Â÷¶}ªOªO«á´N§âÅv­­®³±¼³á */
+ num = tmp1;
+ class_bid = bidtmp;
+ setutmpbid(tmp);
+ brdnum = -1;
+ }
+ }
+ break;
+ ///////////////////////////////////////////////////////
+ // MyFav Functionality (Require PERM_BASIC)
+ ///////////////////////////////////////////////////////
+ case 'y':
+ if (HasFavEditPerm() && !(IN_CLASS())) {
+ if (get_current_fav() != NULL || !IS_LISTING_FAV()){
+ yank_flag ^= 1; /* FAV <=> BRD */
+ }
+ brdnum = -1;
+ }
+ break;
+ case Ctrl('D'):
+ if (HasFavEditPerm()) {
+ if (getans("§R°£©Ò¦³¼Ð°O[N]?") == 'y'){
+ fav_remove_all_tagged_item();
+ brdnum = -1;
+ }
+ }
+ break;
+ case Ctrl('A'):
+ if (HasFavEditPerm()) {
+ fav_add_all_tagged_item();
+ brdnum = -1;
+ }
+ break;
+ case Ctrl('T'):
+ if (HasFavEditPerm()) {
+ fav_remove_all_tag();
+ brdnum = -1;
+ }
+ break;
+ case Ctrl('P'):
+ if (paste_taged_brds(class_bid))
+ brdnum = -1;
+ break;
+
+ case 'L':
+ if ((HasUserPerm(PERM_SYSOP) ||
+ (HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP())) && IN_CLASS()) {
+ // TODO XXX why need symlink here? Can we remove it?
+ if (make_symbolic_link_interactively(class_bid) < 0)
+ break;
+ brdnum = -1;
+ head = 9999;
+ }
+ else if (HasFavEditPerm() && IS_LISTING_FAV()) {
+ if (fav_add_line() == NULL) {
+ vmsg("·s¼W¥¢±Ñ¡A¤À¹j½u/Á`³Ì·R ¼Æ¶q¹F³Ì¤j­È¡C");
+ break;
+ }
+ /* done move if it's the first item. */
+ assert(nbrdsize>0);
+ if (get_fav_type(&nbrd[0]) != 0)
+ move_in_current_folder(brdnum, num);
+ brdnum = -1;
+ head = 9999;
+ }
+ break;
+
+ case 'd': // why don't we enable 'd'?
+ case 'z':
+ case 'm':
+ if (HasFavEditPerm()) {
+ assert(0<=num && num<nbrdsize);
+ ptr = &nbrd[num];
+ if (IS_LISTING_FAV()) {
+ if (ptr->myattr & NBRD_FAV) {
+ if (getans("§A½T©w§R°£¶Ü? [N/y]") != 'y')
+ break;
+ fav_remove_item(ptr->bid, get_fav_type(ptr));
+ ptr->myattr &= ~NBRD_FAV;
+ }
+ }
+ else
+ {
+ if (getboard(ptr->bid) != NULL) {
+ fav_remove_item(ptr->bid, FAVT_BOARD);
+ ptr->myattr &= ~NBRD_FAV;
+ }
+ else if (ch != 'd') // 'd' only deletes something.
+ {
+ if (fav_add_board(ptr->bid) == NULL)
+ vmsg("§Aªº³Ì·R¤Ó¦h¤F°Õ ¯uªá¤ß");
+ else
+ ptr->myattr |= NBRD_FAV;
+ }
+ }
+ brdnum = -1;
+ head = 9999;
+ }
+ break;
+ case 'M':
+ if (HasFavEditPerm()){
+ if (IN_FAVORITE() && IS_LISTING_FAV()){
+ imovefav(num);
+ brdnum = -1;
+ head = 9999;
+ }
+ }
+ break;
+ case 'g':
+ if (HasFavEditPerm() && IS_LISTING_FAV()) {
+ fav_type_t *ft;
+ if (fav_stack_full()){
+ vmsg("¥Ø¿ý¤w¹F³Ì¤j¼h¼Æ!!");
+ break;
+ }
+ if ((ft = fav_add_folder()) == NULL) {
+ vmsg("·s¼W¥¢±Ñ¡A¥Ø¿ý/Á`³Ì·R ¼Æ¶q¹F³Ì¤j­È¡C");
+ break;
+ }
+ fav_set_folder_title(ft, "·sªº¥Ø¿ý");
+ /* don't move if it's the first item */
+ assert(nbrdsize>0);
+ if (get_fav_type(&nbrd[0]) != 0)
+ move_in_current_folder(brdnum, num);
+ brdnum = -1;
+ head = 9999;
+ }
+ break;
+ case 'T':
+ assert(0<=num && num<nbrdsize);
+ if (HasFavEditPerm() && nbrd[num].myattr & NBRD_FOLDER) {
+ fav_type_t *ft = getfolder(nbrd[num].bid);
+ strlcpy(buf, get_item_title(ft), sizeof(buf));
+ getdata_buf(b_lines-1, 0, "½Ð­×§ï¦WºÙ: ", buf, BTLEN+1, DOECHO);
+ fav_set_folder_title(ft, buf);
+ brdnum = -1;
+ }
+ break;
+ case 'K':
+ if (HasFavEditPerm()) {
+ char c, fname[80];
+ if (get_current_fav() != get_fav_root()) {
+ vmsg("½Ð¨ì§Úªº³Ì·R³Ì¤W¼h°õ¦æ¥»¥\\¯à");
+ break;
+ }
+
+ c = getans("½Ð¿ï¾Ü 2)³Æ¥÷§Úªº³Ì·R 3)¨ú¦^³Ì·R³Æ¥÷ [Q]");
+ if(!c)
+ break;
+ if(getans("½T©w¶Ü [y/N] ") != 'y')
+ break;
+ switch(c){
+ case '2':
+ fav_save();
+ setuserfile(fname, FAV);
+ sprintf(buf, "%s.bak", fname);
+ Copy(fname, buf);
+ break;
+ case '3':
+ setuserfile(fname, FAV);
+ sprintf(buf, "%s.bak", fname);
+ if (!dashf(buf)){
+ vmsg("§A¨S¦³³Æ¥÷§Aªº³Ì·R³á");
+ break;
+ }
+ Copy(buf, fname);
+ fav_free();
+ fav_load();
+ break;
+ }
+ brdnum = -1;
+ }
+ break;
+
+ case 'a':
+ case 'i':
+ if(IN_FAVORITE() && HasFavEditPerm()){
+ char bname[IDLEN + 1];
+ int bid;
+ move(0, 0);
+ clrtoeol();
+ /* use CompleteBoard or CompleteBoardAndGroup ? */
+ CompleteBoard(ANSI_COLOR(7) "¡i ¼W¥[§Úªº³Ì·R ¡j" ANSI_RESET "\n"
+ "½Ð¿é¤J±ý¥[¤Jªº¬ÝªO¦WºÙ(«öªÅ¥ÕÁä¦Û°Ê·j´M)¡G",
+ bname);
+
+ if (bname[0] && (bid = getbnum(bname)) &&
+ HasBoardPerm(getbcache(bid))) {
+ fav_type_t * ptr = getboard(bid);
+ if (ptr != NULL) { // already in fav list
+ // move curser to item
+ for (num = 0; num<nbrdsize && bid != nbrd[num].bid; ++num);
+ assert(bid==nbrd[num].bid);
+ } else {
+ ptr = fav_add_board(bid);
+
+ if (ptr == NULL)
+ vmsg("§Aªº³Ì·R¤Ó¦h¤F°Õ ¯uªá¤ß");
+ else {
+ ptr->attr |= NBRD_FAV;
+
+ if (ch == 'i' && get_data_number(get_current_fav()) > 1)
+ move_in_current_folder(brdnum, num);
+ else
+ num = brdnum;
+ }
+ }
+ }
+ }
+ brdnum = -1;
+ head = 9999;
+ break;
+
+ case 'w':
+ /* allowing save BRC/fav once per 10 minutes */
+ if (now - last_save_fav_and_brc > 10 * 60) {
+ fav_save();
+ brc_finalize();
+
+ last_save_fav_and_brc = now;
+ }
+ break;
+
+ ///////////////////////////////////////////////////////
+ // Administrator Only
+ ///////////////////////////////////////////////////////
+
+ case 'F':
+ case 'f':
+ if (HasUserPerm(PERM_SYSOP)) {
+ getbcache(class_bid)->firstchild[cuser.uflag & BRDSORT_FLAG ? 1 : 0] = 0;
+ brdnum = -1;
+ }
+ break;
+ case 'D':
+ if (HasUserPerm(PERM_SYSOP) ||
+ (HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP())) {
+ assert(0<=num && num<nbrdsize);
+ ptr = &nbrd[num];
+ if (ptr->myattr & NBRD_SYMBOLIC) {
+ if (getans("½T©w§R°£³sµ²¡H[N/y]") == 'y')
+ delete_symbolic_link(getbcache(ptr->bid), ptr->bid);
+ }
+ brdnum = -1;
+ }
+ break;
+ case 'E':
+ if (HasUserPerm(PERM_SYSOP | PERM_BOARD) || GROUPOP()) {
+ assert(0<=num && num<nbrdsize);
+ ptr = &nbrd[num];
+ move(1, 1);
+ clrtobot();
+ m_mod_board(B_BH(ptr)->brdname);
+ brdnum = -1;
+ }
+ break;
+ case 'R':
+ if (HasUserPerm(PERM_SYSOP) || GROUPOP()) {
+ m_newbrd(class_bid, 1);
+ brdnum = -1;
+ }
+ break;
+ case 'B':
+ if (HasUserPerm(PERM_SYSOP) || GROUPOP()) {
+ m_newbrd(class_bid, 0);
+ brdnum = -1;
+ }
+ break;
+ case 'W':
+ if (IN_SUBCLASS() &&
+ (HasUserPerm(PERM_SYSOP) || GROUPOP())) {
+ setbpath(buf, getbcache(class_bid)->brdname);
+ mkdir(buf, 0755); /* Ptt:¶}¸s²Õ¥Ø¿ý */
+ b_note_edit_bname(class_bid);
+ brdnum = -1;
+ }
+ break;
+
+ }
+ } while (ch != 'q');
+ free(nbrd);
+ nbrd = NULL;
+ nbrdsize = 0;
+ --choose_board_depth;
+}
+
+int
+Class(void)
+{
+ init_brdbuf();
+ class_bid = 1;
+ LIST_BRD();
+ choose_board(0);
+ return 0;
+}
+
+int
+Favorite(void)
+{
+ init_brdbuf();
+ class_bid = 0;
+ LIST_FAV();
+ choose_board(0);
+ return 0;
+}
+
+
+int
+New(void)
+{
+ int mode0 = currutmp->mode;
+ int stat0 = currstat;
+
+ class_bid = 0;
+ init_brdbuf();
+ choose_board(1);
+ currutmp->mode = mode0;
+ currstat = stat0;
+ return 0;
+}