Example #1
0
static void
a_showhelp(int level)
{
    clear();
    outs(ANSI_COLOR(36) "【 " BBSNAME "公佈欄使用說明 】" ANSI_RESET "\n\n"
	 "[←][q]         離開到上一層目錄\n"
	 "[↑][k]         上一個選項\n"
	 "[↓][j]         下一個選項\n"
	 "[→][r][enter]  進入目錄╱讀取文章\n"
	 "[^B][PgUp]      上頁選單\n"
	 "[^F][PgDn][Spc] 下頁選單\n"
	 "[##]            移到該選項\n"
	 "[^W]            我在哪裡\n"
	 "[F][U]          將文章寄回 Internet 郵箱/"
	 "將文章 uuencode 後寄回郵箱\n");
    if (level >= MANAGER) {
	outs("\n" ANSI_COLOR(36) "【 板主專用鍵 】" ANSI_RESET "\n"
	     "[H]             切換為 公開/可見會員名單/板主 才能閱\讀\n"
	     "[n/g]           收錄精華文章/開闢目錄\n"
	     "[m/d/D]         移動/刪除文章/刪除一個範圍的文章\n"
	     "[f/T/e]         編輯標題符號/修改文章標題/內容\n"
	     "[c/p/a]         精華區內 標記(複製)/貼上(可多篇)/附加單篇文章\n"
	     "[^P/^A]         貼上/附加精華區外已用't'標記文章\n");
    }
    if (level >= SYSOP) {
	outs("\n" ANSI_COLOR(36) "【 站長專用鍵 】" ANSI_RESET "\n"
	     "[l]             建 symbolic link\n"
	     "[N]             查詢檔名\n");
    }
    pressanykey();
}
Example #2
0
void
pico_toggle_color(int on)
{
    if(on){
	if(pico_hascolor())
	  _using_color = 1;
    }
    else{
	_using_color = 0;
	if(_color_inited){
	    _color_inited = 0;
	    if(!panicking())
	      free_color_table(&color_tbl);

	    if(ANSI_COLOR())
	      putpad("\033[39;49m");
	    else{
		if(_op)
		  putpad(_op);
		if(_oc)
		  putpad(_oc);
	    }
	}
    }
}
Example #3
0
void
showtitle(const char *title, const char *mid)
{
    /* we have to...
     * - display title in left, cannot truncate.
     * - display mid message, cannot truncate
     * - display tail (board info), if possible.
     */
    int llen, rlen, mlen, mpos = 0;
    int pos = 0;
    int tail_type;
    const char *mid_attr = ANSI_COLOR(33);
    int is_currboard_special = 0;
    char buf[64];


    /* prepare mid */
#ifdef DEBUG
    {
	sprintf(buf, "  current pid: %6d  ", getpid());
	mid = buf; 
	mid_attr = ANSI_COLOR(41;5);
    }
#else
    if (ISNEWMAIL(currutmp)) {
	mid = "    你有新信件    ";
	mid_attr = ANSI_COLOR(41;5);
    } else if ( HasUserPerm(PERM_ACCTREG) ) {
Example #4
0
CCW_PROTO void
ccw_print_line(CCW_CTX *ctx, const char *buf, int local)
{
    // FIXME if printed message is too long, the 2nd line will be overwritten
    // by next print_line request.
    ccw_prepare_line(ctx);
    if (ctx->print_line)
    {
        ctx->print_line(ctx, buf, local);
        return;
    }

    if (local <= CCW_LOCAL) // local or remote, but not message
    {
        if (local) {
            outs(ctx->local_id);
        } else {
            outs(ANSI_COLOR(1));
            outs(ctx->remote_id);
        }
        outs(": ");
    }

    outs(buf);
    outs(ANSI_RESET "\n→");
}
Example #5
0
File: stuff.c Project: ptt/pttbbs
// TODO
// move this function to vtuikit.c
void
show_help(const char * const helptext[])
{
    const char     *str;
    int             i;

    clear();
    for (i = 0; (str = helptext[i]); i++) {
	if (*str == '\0')
	    prints(ANSI_COLOR(1) "【 %s 】" ANSI_RESET "\n", str + 1);
	else if (*str == '\01')
	    prints("\n" ANSI_COLOR(36) "【 %s 】" ANSI_RESET "\n", str + 1);
	else
	    prints("        %s\n", str);
    }
    PRESSANYKEY();
}
Example #6
0
int
pico_count_in_color_table(void)
{
    return(
      (ANSI_COLOR()
        ? (ANSI8_COLOR() ? 8 : ANSI16_COLOR() ? 16 : 256)
        : _colors)
      + COL_TRANS());
}
Example #7
0
static void
reversi_drawline(const ChessInfo* info, int line){
    static const char* num_str[] =
    {"", "1", "2", "3", "4", "5", "6", "7", "8"};
    if(line)
	move(line, STARTY);

    if (line == 0) {
	prints(ANSI_COLOR(1;46) "  黑白棋對戰  " ANSI_COLOR(45)
		"%30s VS %-20s%10s" ANSI_RESET,
	       info->user1.userid, info->user2.userid,
	       info->mode == CHESS_MODE_WATCH ? "[觀棋模式]" : "");
    } else if (line == 2)
Example #8
0
void
tinitcolor(void)
{
    if(_color_inited || panicking())
      return;

    if(ANSI_COLOR() || (_colors > 0 && ((_setaf && _setab) || (_setf && _setb)
/**** not sure how to do this yet
       || _scp
****/
	))){
	_color_inited = 1;
	color_tbl = init_color_table();

	if(ANSI_COLOR())
	  putpad("\033[39;49m");
	else{
	    if(_op)
	      putpad(_op);
	    if(_oc)
	      putpad(_oc);
	}
    }
}
Example #9
0
/*
 * These are for terminal keys debug
 */
void
_debug_print_ibuffer()
{
    static int y = 0;
    int i = 0;

    move(y % b_lines, 0);
    for (i = 0; i < t_columns; i++) 
	outc(' ');
    move(y % b_lines, 0);
    prints("%d. Current Buffer: %d/%d, ", y+1, icurrchar, ibufsize);
    outs(ANSI_COLOR(1) "[" ANSI_RESET);
    for (i = 0; i < ibufsize; i++)
    {
	int c = (unsigned char)inbuf[i];
	if(c < ' ')
	{
	    prints(ANSI_COLOR(1;33) "0x%02x" ANSI_RESET, c);
	} else {
Example #10
0
/*
 * We're not actually using the RGB value other than as a string which
 * maps into the color.
 * In fact, on some systems color 1 and color 4 are swapped, and color 3
 * and color 6 are swapped. So don't believe the RGB values.
 * Still, it feels right to have them be the canonical values, so we do that.
 *
 * Actually we are using them more now. In color_to_val we map to the closest
 * color if we don't get an exact match. We ignore values over 255.
 *
 * More than one "name" can map to the same "rgb".
 * More than one "name" can map to the same "val".
 * The "val" for a "name" and for its "rgb" are the same.
 */
struct color_table *
init_color_table(void)
{
    struct color_table *ct = NULL, *t;
    int                 i, count;
    char                colorname[12];

    count = pico_count_in_color_table();

    if(count > 0 && count <= 256+COL_TRANS()){
	int    ind, graylevel;
	struct {
	    char rgb[RGBLEN+1];
	    int red, green, blue;
	} cube[256];

	ct = (struct color_table *) fs_get((count+1) * sizeof(struct color_table));
	if(ct)
	  memset(ct, 0, (count+1) * sizeof(struct color_table));

	/*
	 * We boldly assume that 256 colors means xterm 256-color
	 * color cube and grayscale.
	 */
	if(ANSI_COLOR() && (count == 256+COL_TRANS())){
	    int r, g, b, gray;

	    for(r = 0; r < 6; r++)
	      for(g = 0; g < 6; g++)
		for(b = 0; b < 6; b++){
		    ind = 16 + 36*r + 6*g + b;
		    cube[ind].red   = r ? (40*r + 55) : 0;
		    cube[ind].green = g ? (40*g + 55) : 0;
		    cube[ind].blue  = b ? (40*b + 55) : 0;
		    snprintf(cube[ind].rgb, sizeof(cube[ind].rgb), "%3.3d,%3.3d,%3.3d",
			     cube[ind].red, cube[ind].green, cube[ind].blue);
		}

	    for(gray = 0; gray < 24; gray++){
		ind = gray + 232;
		graylevel = 10*gray + 8;
		cube[ind].red   = graylevel;
		cube[ind].green = graylevel;
		cube[ind].blue  = graylevel;
		snprintf(cube[ind].rgb, sizeof(cube[ind].rgb), "%3.3d,%3.3d,%3.3d",
			 graylevel, graylevel, graylevel);
	    }
	}

	for(i = 0, t = ct; t && i < count; i++, t++){
	    t->val = i;

	    switch(i){
	      case COL_BLACK:
		strncpy(colorname, "black", sizeof(colorname));
		colorname[sizeof(colorname)-1] = '\0';
		break;
	      case COL_RED:
		strncpy(colorname, "red", sizeof(colorname));
		colorname[sizeof(colorname)-1] = '\0';
		break;
	      case COL_GREEN:
		strncpy(colorname, "green", sizeof(colorname));
		colorname[sizeof(colorname)-1] = '\0';
		break;
	      case COL_YELLOW:
		strncpy(colorname, "yellow", sizeof(colorname));
		colorname[sizeof(colorname)-1] = '\0';
		break;
	      case COL_BLUE:
		strncpy(colorname, "blue", sizeof(colorname));
		colorname[sizeof(colorname)-1] = '\0';
		break;
	      case COL_MAGENTA:
		strncpy(colorname, "magenta", sizeof(colorname));
		colorname[sizeof(colorname)-1] = '\0';
		break;
	      case COL_CYAN:
		strncpy(colorname, "cyan", sizeof(colorname));
		colorname[sizeof(colorname)-1] = '\0';
		break;
	      case COL_WHITE:
		strncpy(colorname, "white", sizeof(colorname));
		colorname[sizeof(colorname)-1] = '\0';
		break;
	      default:
		snprintf(colorname, sizeof(colorname), "color%3.3d", i);
		break;
	    }

	    if(COL_TRANS() && i == count-1){
		strncpy(colorname, MATCH_TRAN_COLOR, sizeof(colorname));
		colorname[sizeof(colorname)-1] = '\0';
	    }

	    add_to_color_name_list(t, colorname);

	    if(count == 8+COL_TRANS()){
	      if(COL_TRANS() && i == count-1){
		  t->red = t->green = t->blue = -1;
	      }
	      else
	       switch(i){
		case COL_BLACK:
		  t->red = t->green = t->blue = 0;
		  add_to_color_name_list(t, "color008");
		  add_to_color_name_list(t, "colordgr");
		  add_to_color_name_list(t, "colormgr");
		  break;
		case COL_RED:
		  t->red = 255;
		  t->green = t->blue = 0;
		  add_to_color_name_list(t, "color009");
		  break;
		case COL_GREEN:
		  t->green = 255;
		  t->red = t->blue = 0;
		  add_to_color_name_list(t, "color010");
		  break;
		case COL_YELLOW:
		  t->red = t->green = 255;
		  t->blue = 0;
		  add_to_color_name_list(t, "color011");
		  break;
		case COL_BLUE:
		  t->red = t->green = 0;
		  t->blue = 255;
		  add_to_color_name_list(t, "color012");
		  break;
		case COL_MAGENTA:
		  t->red = t->blue = 255;
		  t->green = 0;
		  add_to_color_name_list(t, "color013");
		  break;
		case COL_CYAN:
		  t->red = 0;
		  t->green = t->blue = 255;
		  add_to_color_name_list(t, "color014");
		  break;
		case COL_WHITE:
		  t->red = t->green = t->blue = 255;
		  add_to_color_name_list(t, "color015");
		  add_to_color_name_list(t, "colorlgr");
		  break;
	       }
	    }
	    else if(count == 16+COL_TRANS() || count == 256+COL_TRANS()){
	      if(COL_TRANS() && i == count-1){
		  t->red = t->green = t->blue = -1;
	      }
	      else
	       /*
	        * This set of RGB values seems to come close to describing
	        * what a 16-color xterm gives you.
	        */
	       switch(i){
		case COL_BLACK:
		  t->red = t->green = t->blue = 0;
		  break;
		case COL_RED:			/* actually dark red */
		  t->red = 174;
		  t->green = t->blue = 0;
		  break;
		case COL_GREEN:			/* actually dark green */
		  t->green = 174;
		  t->red = t->blue = 0;
		  break;
		case COL_YELLOW:		/* actually dark yellow */
		  t->blue = 0;
		  t->red = t->green = 174;
		  break;
		case COL_BLUE:			/* actually dark blue */
		  t->blue = 174;
		  t->red = t->green = 0;
		  break;
		case COL_MAGENTA:		/* actually dark magenta */
		  t->green = 0;
		  t->red = t->blue = 174;
		  break;
		case COL_CYAN:			/* actually dark cyan */
		  t->red = 0;
		  t->green = t->blue = 174;
		  break;
		case COL_WHITE:			/* actually light gray */
		  t->red = t->green = t->blue = 174;
		  if(count == 16)
		    add_to_color_name_list(t, "colorlgr");

		  break;
		case 8:				/* dark gray */
		  t->red = t->green = t->blue = 64;
		  if(count == 16){
		      add_to_color_name_list(t, "colordgr");
		      add_to_color_name_list(t, "colormgr");
		  }

		  break;
		case 9:				/* red */
		  t->red = 255;
		  t->green = t->blue = 0;
		  break;
		case 10:			/* green */
		  t->green = 255;
		  t->red = t->blue = 0;
		  break;
		case 11:			/* yellow */
		  t->blue = 0;
		  t->red = t->green = 255;
		  break;
		case 12:			/* blue */
		  t->blue = 255;
		  t->red = t->green = 0;
		  break;
		case 13:			/* magenta */
		  t->green = 0;
		  t->red = t->blue = 255;
		  break;
		case 14:			/* cyan */
		  t->red = 0;
		  t->green = t->blue = 255;
		  break;
		case 15:			/* white */
		  t->red = t->green = t->blue = 255;
		  break;
		default:
		  t->red   = cube[i].red;
		  t->green = cube[i].green;
		  t->blue  = cube[i].blue;
		  switch(i){
		    case 238:
		      add_to_color_name_list(t, "colordgr");
		      break;

		    case 244:
		      add_to_color_name_list(t, "colormgr");
		      break;

		    case 250:
		      add_to_color_name_list(t, "colorlgr");
		      break;
		  }

		  break;
	       }
	    }
	    else{
	      if(COL_TRANS() && i == count-1){
		  t->red = t->green = t->blue = -1;
	      }
	      else
	       switch(i){
		case COL_BLACK:
		  t->red = t->green = t->blue = 0;
		  break;
		case COL_RED:			/* actually dark red */
		  t->red = 255;
		  t->green = t->blue = 0;
		  break;
		case COL_GREEN:			/* actually dark green */
		  t->green = 255;
		  t->red = t->blue = 0;
		  break;
		case COL_YELLOW:		/* actually dark yellow */
		  t->blue = 0;
		  t->red = t->green = 255;
		  break;
		case COL_BLUE:			/* actually dark blue */
		  t->blue = 255;
		  t->red = t->green = 0;
		  break;
		case COL_MAGENTA:		/* actually dark magenta */
		  t->green = 0;
		  t->red = t->blue = 255;
		  break;
		case COL_CYAN:			/* actually dark cyan */
		  t->red = 0;
		  t->green = t->blue = 255;
		  break;
		case COL_WHITE:			/* actually light gray */
		  t->red = t->green = t->blue = 255;
		  break;
		default:
		  /* this will just be a string match */
		  t->red = t->green = t->blue = 256+i;
		  break;
	       }
	    }
	}

	for(i = 0, t = ct; t && i < count; i++, t++){
	    t->rgb = (char *)fs_get((RGBLEN+1) * sizeof(char));
	    if(COL_TRANS() && i == count-1)
	      snprintf(t->rgb, RGBLEN+1, MATCH_TRAN_COLOR);
	    else
	      snprintf(t->rgb, RGBLEN+1, "%3.3d,%3.3d,%3.3d", t->red, t->green, t->blue);
	}
    }

    return(ct);
}
Example #11
0
int
tbgcolor(int color)
{
    if(!_color_inited)
      tinitcolor();

    if(!_color_inited)
      return(-1);
    
    if((ANSI8_COLOR()  && (color < 0 || color >= 8+COL_TRANS())) ||
       (ANSI16_COLOR() && (color < 0 || color >= 16+COL_TRANS())) ||
       (ANSI256_COLOR() && (color < 0 || color >= 256+COL_TRANS())) ||
       (!ANSI_COLOR()  && (color < 0 || color >= _colors+COL_TRANS())))
      return(-1);

    if(ANSI_COLOR()){
	char buf[20];

	if(COL_TRANS() && color == pico_count_in_color_table()-1)
	  snprintf(buf, sizeof(buf), "\033[49m");
	else if(ANSI256_COLOR())
	  snprintf(buf, sizeof(buf), "\033[48;5;%dm", color);
	else{
	    if(color < 8)
	      snprintf(buf, sizeof(buf), "\033[4%cm",  color + '0');
	    else
	      snprintf(buf, sizeof(buf), "\033[10%cm", (color-8) + '0');
	}
	
	putpad(buf);
    }
    else if(COL_TRANS() && color == pico_count_in_color_table()-1 && _op){
	char fg_color_was[MAXCOLORLEN+1];

	fg_color_was[0] = '\0';

	/*
	 * Setting transparent (default) background color.
	 * We don't know how to set only the default background color,
	 * _op sets both foreground and background. So we need to
	 *
	 * get current foreground color
	 * set default colors
	 * if (current foreground was not default) reset it
	 */
	if(_last_fg_color && strncmp(_last_fg_color, MATCH_TRAN_COLOR, RGBLEN)){
	    strncpy(fg_color_was, _last_fg_color, sizeof(fg_color_was));
	    fg_color_was[sizeof(fg_color_was)-1] = '\0';
	}

	putpad(_op);
	if(fg_color_was[0]){
	    _force_fg_color_change = 1;
	    pico_set_fg_color(fg_color_was);
	}
    }
    else if(_setab)
      putpad(tparm(_setab, color));
    else if(_setb)
      putpad(tparm(_setb, color));
    else if(_scp){
	/* set color pair method */
    }

    return(0);
}
Example #12
0
      ((!HasUserPerm(PERM_BASIC) || HasUserPerm(PERM_LOGINOK))?0:1) :\
	((!x) ? 1 :  \
         ((x & PERM_LOGINOK) ? HasBasicUserPerm(x) : HasUserPerm(x))))

/* help & menu processring */
static int      refscreen = NA;
extern char    *boardprefix;
extern struct utmpfile_t *utmpshm;

static const char *title_tail_msgs[] = {
    "看板",
    "系列",
    "文摘",
};
static const char *title_tail_attrs[] = {
    ANSI_COLOR(37),
    ANSI_COLOR(32),
    ANSI_COLOR(36),
};
enum {
    TITLE_TAIL_BOARD = 0,
    TITLE_TAIL_SELECT,
    TITLE_TAIL_DIGEST,
};

// 由於歷史因素,這裡會出現三種編號: 
// MODE (定義於 modes.h)    是 BBS 對各種功能在 utmp 的編號 (var.c 要加字串)
// Menu Index (M_*)	    是 menu.c 內部分辨選單要對應哪個 mode 的 index
// AdBanner Index	    是動態看版要顯示什麼的值
// 從前這是用兩個 mode map 來轉換的 (令人看得滿頭霧水)
// 重整後 Menu Index 跟 AdBanner Index 合一,請見下面的說明
Example #13
0
// level: 
// -1 - bold out
//  0 - dark text
//  1 - text
//  2 - no highlight (not implemented)
void
grayout(int y, int end, int level)
{
    register screenline_t *slp = NULL;
    char buf[ANSILINELEN];
    int i = 0;

    if (y < 0) y = 0;
    if (end > b_lines) end = b_lines;

    // TODO change to y <= end someday
    // loop lines
    for (; y <= end; y ++)
    {
	// modify by scroll
	i = y + roll;
	if (i < 0)
	    i += t_lines;
	else if (i >= t_lines)
	    i %= t_lines;

	slp = &big_picture[i];

	if (slp->len < 1)
	    continue;

	if (slp->len >= ANSILINELEN)
	    slp->len = ANSILINELEN -1;

	// tweak slp
	slp->data[slp->len] = 0;
	slp->mode &= ~STANDOUT;
	slp->mode |= MODIFIED;
	slp->oldlen = 0;
	slp->sso = slp->eso = 0;
	slp->smod = 0;

	// make slp->data a pure string
	for (i=0; i<slp->len; i++)
	{
	    if (!slp->data[i])
		slp->data[i] = ' ';
	}

	slp->len = strip_ansi(buf, (char*)slp->data, STRIP_ALL);
	buf[slp->len] = 0;

	switch(level)
	{
	    case GRAYOUT_DARK: // dark text
	    case GRAYOUT_BOLD:// bold text
		// basically, in current system slp->data will
		// not exceed t_columns. buffer overflow is impossible.
		// but to make it more robust, let's quick check here.
		// of course, t_columns should always be far smaller.
		if (strlen((char*)slp->data) > (size_t)t_columns)
		    slp->data[t_columns] = 0;
		strcpy((char*)slp->data, 
			level < 0 ? ANSI_COLOR(1) : ANSI_COLOR(1;30;40));
		strcat((char*)slp->data, buf);
		strcat((char*)slp->data, ANSI_RESET ANSI_CLRTOEND);
		slp->len = strlen((char*)slp->data);
		break;

	    case GRAYOUT_NORM: // Plain text
		memcpy(slp->data, buf, slp->len + 1);
		break;
	}
	slp->emod = slp->len -1;
    }
}
Example #14
0
static int
a_where_am_i(const menu_t *root, int current_idx, const char *current_title)
{
    const menu_t *p;
    int lvl, num;
    const int max_lvl = t_lines -3; // 3: vs_hdr() + pause() + where_am_i
    char zidx_buf[STRLEN-sizeof(A_WHEREAMI_PREFIX_STR)-1] = "z";
    int  zidx_len;
    char abuf[12] = "";  // INT_MAX + sign + NUL
    int  last_idx_len = 0;
    char *zidx = zidx_buf + strlen(zidx_buf);
    char bskipping;

    move(1, 0); clrtobot(); outs(A_WHEREAMI_PREFIX_STR ANSI_COLOR(1));

    // decide length of last index
    snprintf(abuf, sizeof(abuf), "-%d", current_idx);
    last_idx_len = strlen(abuf)+1;
    // calculate remaining length
    zidx_len = sizeof(zidx_buf) - strlen(zidx) - last_idx_len;

    bskipping = 0;
    // first round, quick render zidx
    for (p = root; p != NULL; p = p->next)
    {
	snprintf(abuf, sizeof(abuf), "-%d", p->now+1);
	if (p->next == NULL)
	{
	    // tail. always print it.
	    strlcpy(zidx, bskipping ? abuf+1 : abuf, last_idx_len+1);
	} else if (bskipping) {
	    // skip iteration
	    continue;
	} else {
	    // determine if there's still space to print it
	    if ((int)strlen(abuf) > zidx_len)
	    {
		// re-print from previous entry
		char *s = strrchr(zidx_buf, '-');
		assert(s);
		zidx_len += strlen(s);
		strlcpy(s, "...", zidx_len+1);  // '-%d-' enough to hold '...'
		zidx_len -= strlen(s);
		bskipping = 1;
	    } else {
		// simply print it
		strlcpy(zidx, abuf, zidx_len);
		zidx_len -= strlen(zidx);
		zidx     += strlen(zidx);
	    }
	}
    }

    outs(zidx_buf); outs(ANSI_RESET);
    move(2, 0);

    bskipping = 0;
    // second round, render text output
    for (p = root, lvl = 0, num = 0; lvl < max_lvl; p = p->next)
    {
	int onum = num;
	if (p)
	    num = p->now +1;

	if (bskipping && p)
	    continue;

	move(lvl+2, 0);
	prints("%*s", lvl, "");

	//  decide if we need to skip.
	if (++lvl == max_lvl-1 && p && p->next)
	{
	    prints("... (中間已省略) ...");
	    bskipping = 1;
	    continue;
	}

	// in the first round, print topic and no number...
	if (onum)
	    prints("%2d. ", onum);

	// for last round, p == NULL -> use current title
	prints("%s\n", p ? p->mtitle : current_title);

	// break at last round (p == NULL)
	if (!p)
	    break;
    }
    return 0;
}
Example #15
0
static int
search_key_user(const char *passwdfile, int mode)
{
    userec_t        user;
    int             ch;
    int             unum = 0;
    FILE            *fp1 = fopen(passwdfile, "r");
    char            friendfile[PATHLEN]="", key[22], *keymatch;
    int		    keytype = 0;
    int	            isCurrentPwd;

    assert(fp1);

    isCurrentPwd = (strcmp(passwdfile, FN_PASSWD) == 0);
    clear();
    if (!mode)
    {
	getdata(0, 0, "請輸入id :", key, sizeof(key), DOECHO);
    } else {
	// improved search
	vs_hdr("關鍵字搜尋");
	outs("搜尋欄位: [0]全部 1.ID 2.姓名 3.暱稱 4.地址 5.Mail 6.IP 7.職業 8.認證\n");
	getdata(2, 0, "要搜尋哪種資料?", key, 2, NUMECHO);

	if (isascii(key[0]) && isdigit(key[0]))
	    keytype = key[0] - '0';
	if (keytype < 0 || keytype > 8)
	    keytype = 0;
	getdata(3, 0, "請輸入關鍵字: ", key, sizeof(key), DOECHO);
    }

    if(!key[0]) {
	fclose(fp1);
	return 0;
    }
    vs_hdr(key);

    // <= or < ? I'm not sure...
    while ((fread(&user, sizeof(user), 1, fp1)) > 0 && unum++ < MAX_USERS) {

	// skip empty records
	if (!user.userid[0])
	    continue;

	if (!(unum & 0xFF)) {
	    vs_hdr(key);
	    prints("第 [%d] 筆資料\n", unum);
	    refresh();
	}

	// XXX 這裡會取舊資料,要小心 PWD 的 upgrade
	if (!upgrade_passwd(&user))
	    continue;

        keymatch = NULL;

	if (!mode)
	{
	    // only verify id
	    if (!strcasecmp(user.userid, key))
		keymatch = user.userid;
	} else {
	    // search by keytype
	    if ((!keytype || keytype == 1) &&
		DBCS_strcasestr(user.userid, key))
		keymatch = user.userid;
	    else if ((!keytype || keytype == 2) &&
		DBCS_strcasestr(user.realname, key))
		keymatch = user.realname;
	    else if ((!keytype || keytype == 3) &&
		DBCS_strcasestr(user.nickname, key))
		keymatch = user.nickname;
	    else if ((!keytype || keytype == 4) &&
		DBCS_strcasestr(user.address, key))
		keymatch = user.address;
	    else if ((!keytype || keytype == 5) &&
		strcasestr(user.email, key)) // not DBCS.
		keymatch = user.email;
	    else if ((!keytype || keytype == 6) &&
		strcasestr(user.lasthost, key)) // not DBCS.
		keymatch = user.lasthost;
	    else if ((!keytype || keytype == 7) &&
		DBCS_strcasestr(user.career, key))
		keymatch = user.career;
	    else if ((!keytype || keytype == 8) &&
		DBCS_strcasestr(user.justify, key))
		keymatch = user.justify;
	}

        if(keymatch) {
	    vs_hdr(key);
	    prints("第 [%d] 筆資料\n", unum);
	    refresh();

	    user_display(&user, 1);
	    // user_display does not have linefeed in tail.

	    if (isCurrentPwd && HasUserPerm(PERM_ACCOUNTS))
		uinfo_query(user.userid, 1, unum);
	    else
		outs("\n");

	    // XXX don't trust 'user' variable after here
	    // because uinfo_query may have changed it.

	    outs(ANSI_COLOR(44) "               空白鍵" \
		 ANSI_COLOR(37) ":搜尋下一個          " \
		 ANSI_COLOR(33)" Q" ANSI_COLOR(37)": 離開");
	    outs(mode ?
                 "      A: add to namelist " ANSI_RESET " " :
		 "      S: 取用備份資料    " ANSI_RESET " ");
	    while (1) {
		while ((ch = vkey()) == 0)
		    ;
                if (ch == 'a' || ch=='A' )
                  {
                   if(!friendfile[0])
                    {
                     friend_special();
                     setfriendfile(friendfile, FRIEND_SPECIAL);
                    }
                   friend_add(user.userid, FRIEND_SPECIAL, keymatch);
                   break;
                  }
		if (ch == ' ')
		    break;
		if (ch == 'q' || ch == 'Q') {
		    fclose(fp1);
		    return 0;
		}
		if (ch == 's' && !mode) {
		    if (retrieve_backup(&user) >= 0) {
			fclose(fp1);
                        vmsg("已成功\取用備份資料。");
			return 0;
		    } else {
                        vmsg("錯誤: 取用備份資料失敗。");
                    }
		}
	    }
	}
Example #16
0
int main(int argc, char *argv[])
{
    int bmid, i, j=0;
    FILE *inf, *firef;
    time4_t now=time(NULL); 
    attach_SHM();
    resolve_boards();

    if(passwd_init())
	exit(1);      

    memcpy(allbrd,bcache,numboards*sizeof(boardheader_t));

    /* write out the target file */
    inf   = fopen(OUTFILE, "w+");
    if (inf == NULL) {
	printf("open file error : %s\n", OUTFILE);
	exit(1);
    }

    firef = fopen(FIREFILE, "w+");
    if (firef == NULL) {
	printf("open file error : %s\n", FIREFILE);
	exit(1);
    }

    fprintf(inf, "警告: 板主若超過(不包含) %d天未上站,將予於免職\n",
            LAZY_BM_LIMIT_DAYS);
    fprintf(inf,
	    "看板名稱                                           "
	    "    板主        幾天沒來啦\n"
	    "---------------------------------------------------"
	    "--------------------------\n");

    fprintf(firef, "免職板主\n");
    fprintf(firef,
	    "看板名稱                                           "
	    "    板主        幾天沒來啦\n"
	    "---------------------------------------------------"
	    "--------------------------\n"); 


    j = 0;
    for (i = 0; i < numboards; i++) {
	char *p, bmbuf[IDLEN * 3 + 3];
	int   index = 0, flag = 0, k, n;
	userec_t xuser;
	p = allbrd[i].BM;

	if (*p == '[') p++;
	if (allbrd[i].brdname[0] == '\0' ||
		!isalpha(allbrd[i].brdname[0])
	   ) continue;

	p = strtok(p,"/ ]");
	for(index=0; p && index<5; index++) {
	    int diff;
	    // XXX what if bmid is invalid?
	    if(!p[0] || (bmid = passwd_load_user(p, &xuser)) < 1) {
		index--;
		p=strtok(NULL,"/ ]");
		continue;
	    }
	    strlcpy(bms[index].bmname, p, sizeof(bms[index].bmname));
	    bms[index].flag = 0;

	    diff = now - xuser.lastlogin;
	    if (diff < 0)
		diff = 0;

	    if (diff >= 45 * 86400
		    && !(xuser.userlevel & PERM_SYSOPHIDE)
		    && !(xuser.userlevel & PERM_SYSOP)) {
		strlcpy(lostbms[j].bmname, p, sizeof(bms[index].bmname));
		lostbms[j].title = allbrd[i].brdname;
		lostbms[j].ctitle = allbrd[i].title;
		lostbms[j].lostdays = diff / 86400;

		//超過 LAZY_BM_LIMIT_DAYS 天 免職
		if (lostbms[j].lostdays > LAZY_BM_LIMIT_DAYS) {
		    xuser.userlevel &= ~PERM_BM;
		    bms[index].flag = 1;
		    flag = 1;
                    // NOTE: 好像不改也無所謂,目前拔 BM 是自動的。
		    passwd_update(bmid, &xuser);
		}
		j++;
	    }
	    p = strtok(NULL,"/ ]");
	}

	if (flag == 1) {
            boardheader_t *bp = getbcache(i+1);

            // 確認我們沒搞錯 cache. 如果 cache 炸了就別用了
            if (strcmp(bp->brdname, allbrd[i].brdname) != 0) {
                printf("ERROR: unmatched cache!!! (%s - %s)\n",
                        bp->brdname, allbrd[i].brdname);
                bp = NULL;
                exit(1);
                // sync to latest
                memcpy(&allbrd[i], bp, sizeof(boardheader_t));
            }

	    bmbuf[0] = '\0';
	    for (k = 0, n = 0; k < index; k++) {
		if (!bms[k].flag) {
		    if (n++ != 0) strcat(bmbuf, "/");
		    strcat(bmbuf, bms[k].bmname);
		}
	    }
	    strcpy(allbrd[i].BM, bmbuf);
            printf("board %s: %s -> %s\n",
                    allbrd[i].brdname, bp->BM, allbrd[i].BM);
            strcpy(bp->BM, allbrd[i].BM);
	    if (substitute_record(BBSHOME"/"FN_BOARD, &allbrd[i], 
			sizeof(boardheader_t), i+1) == -1) {
		printf("Update Board Failed: %s\n", allbrd[i].brdname);
	    }
	    reset_board(i+1);
	}
    }
    qsort(lostbms, j, sizeof(lostbm), bmlostdays_cmp);

    //write to the etc/toplazyBM
    for (i = 0; i < j; i++) {
	if (lostbms[i].lostdays > LAZY_BM_LIMIT_DAYS) {
	    fprintf(firef, "%-*.*s%-*.*s%-*.*s%3d天沒上站\n",
		    IDLEN, IDLEN, lostbms[i].title, BTLEN-10,
		    BTLEN-10, lostbms[i].ctitle, IDLEN,IDLEN,
		    lostbms[i].bmname,lostbms[i].lostdays);
	} else {
	    fprintf(inf, "%-*.*s%-*.*s%-*.*s%3d天沒上站\n",
		    IDLEN, IDLEN, lostbms[i].title, BTLEN-10,
		    BTLEN-10, lostbms[i].ctitle, IDLEN,IDLEN,
		    lostbms[i].bmname,lostbms[i].lostdays);
	}
    }
    fclose(inf);
    fclose(firef);

    //printf("Total %d boards.\n", count);

    //mail to the users
    for (i=0; i<j; i++) {
	fileheader_t mymail;
	char	genbuf[200];
	int	lostdays;

	lostdays = lostbms[i].lostdays;

	if (lostdays != LAZY_BM_LIMIT_DAYS/2 &&
            lostdays != LAZY_BM_LIMIT_DAYS*2/3 &&
            lostdays != LAZY_BM_LIMIT_DAYS*5/6 &&
            lostdays <= LAZY_BM_LIMIT_DAYS)
	    continue;

	sprintf(genbuf, BBSHOME "/home/%c/%s", 
		lostbms[i].bmname[0], lostbms[i].bmname);
	stampfile(genbuf, &mymail);

	strcpy(mymail.owner, "[" BBSMNAME "警察局]");
	if (lostdays <= LAZY_BM_LIMIT_DAYS)
	    sprintf(mymail.title,
		    ANSI_COLOR(32) "版主通知" ANSI_RESET " %s版版主%s",
		    lostbms[i].title, lostbms[i].bmname);
	else
	    sprintf(mymail.title,
		    ANSI_COLOR(32) "版主自動免職通知" ANSI_RESET " %s 版主 %s",
		    lostbms[i].title, lostbms[i].bmname);

	unlink(genbuf);
	if (lostdays <= LAZY_BM_LIMIT_DAYS)
	    Link(OUTFILE, genbuf);
	else
	    Link(FIREFILE, genbuf);

	sprintf(genbuf, BBSHOME "/home/%c/%s/.DIR", 
		lostbms[i].bmname[0], lostbms[i].bmname);
	append_record(genbuf, &mymail, sizeof(mymail)); 	
    }
    return 0;
}