回精華區
作者amaki.bbs@luna.twbbs.org (仙草小羊) 看板: plan
標題Re: [整理]精華區可見名單
時間月下夜想 (Sun, 13 Apr 2003 06:10:16 +0800 (CST) Updated: 2005/10/07
  整理了這段時間諸多高手與itoc的修改,把完整版放上來。

  這裡預設的可見名單檔案是放在 gem/brd/板名/gempal_DIR/ 下。

  精華區可見名單:

  第一次按小o時會詢問,第二次按小o時會詢問是否要解除加密,解除後會
  砍掉所有可見名單。

  加密後,日後若是有需要再加入新的可見名單,請按大O鍵。

: src/lib/dao.p

/* f_path.c */
+ void mak_fpath(char *str, char *key, char *name);
void brd_fpath(char *fpath, char *board, char *fname);
void gem_fpath(char *fpath, char *board, char *fname);
void usr_fpath(char *fpath, char *user, char *fname);

: src/lib/f_path.c:mak_fpath()

- static void
+ void
mak_fpath(str, key, name)

: gem.c  新增六支函式,抄在gem_item()前面。

#ifdef HAVE_GEMPAL
static void
gempal_fpath(fpath, board, mode, hdr)
  char *fpath;
  char *board;
  char mode;       /* 'C':Cansee  'G':Gemimage */
  HDR *hdr;
{
  char gboard[80], fname[32];

  *fpath++ = 'g';
  *fpath++ = 'e';
  *fpath++ = 'm';

  sprintf(gboard, "brd/%s/gempal_DIR", board);
  sprintf(fname, "%s_%s", mode == 'C' ? "Cansee" : "Gemimage", hdr->xname);
  mak_fpath(fpath, gboard, fname);
}


static void
gembrdname_get(brdname, dir)
  char *brdname;
  char *dir;
{
  char xboard[80], *str;

  strcpy(xboard, dir + 8);  /* skip "gem/brd/" */
  if (str = strchr(xboard, '/'))
    *str = '\0';

  strcpy(brdname, xboard);
}


static void
kill_gempal(board, hdr)   /* amaki.030322: 用來砍名單小檔 */
  char *board;
  HDR *hdr;
{
  char fpath[64];

  gempal_fpath(fpath, board, 'C', hdr);
  unlink(fpath);
  gempal_fpath(fpath, board, 'G', hdr);
  unlink(fpath);
}


static int
gempal_belong(board, hdr)
  char *board;
  HDR *hdr;
{
  int fsize, count, result;
  char fpath[64];

  gempal_fpath(fpath, board, 'G', hdr);
  board = f_img(fpath, &fsize);

  result = 0;

  if (board != NULL)
  {
    count = fsize / sizeof(int);
    if (count > 0)
    {
      int userno, *up;
      int datum, mid;

      userno = cuser.userno;
      up = (int *) board;

      while (count > 0)
      {
        datum = up[mid = count >> 1];
        if (userno == datum)
        {
          result = 1;
          break;
        }
        if (userno > datum)
        {
          up += (++mid);
          count -= mid;
        }
        else
        {
          count = mid;
        }
      }
    }
    free(board);
  }
  return result;
}


static int
int_cmp(a, b)
  int *a;
  int *b;
{
  return *a - *b;
}


static void
bm_image_gempal(hdr, board)
  HDR *hdr;
  char *board;
{
  int fd;
  char fpath[64];

  gempal_fpath(fpath, board, 'C', hdr);
  if ((fd = open(fpath, O_RDONLY)) >= 0)
  {
    struct stat st;
    PAL *pal, *up;
    int count;

    fstat(fd, &st);
    if (pal = (PAL *) malloc(count = st.st_size))
    {
      count = read(fd, pal, count) / sizeof(PAL);
      if (count > 0)
      {
        int *userno;
        int c = count;

        userno = (int *) up = pal;
        do
        {
          *userno++ = up->userno;
          up++;
        } while (--c);

        if (count > 1)          /* Thor: 多排序有益身體健康... */
          qsort(pal, count, sizeof(int), int_cmp);

        gempal_fpath(fpath, board, 'G', hdr);
        if ((count = open(fpath, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0)
        {
          write(count, pal, (char *) userno - (char *) pal);
          close(count);
        }
      }
      else  /* Thor.980811: lkchu patch: 與 friend 同步 */
      {
        kill_gempal(board, hdr);
      }
      free(pal);
    }
    close(fd);
  }
}


extern KeyFunc pal_cb[];
static HDR * gem_check();

static int gem_init();

static int
XoBM_gempal(xo)
  XO *xo;
{
  HDR *hdr;
  XO *xt;
  char fpath[64], xboard[BNLEN + 1];

  if (!(xo->key & GEM_M_BIT) || !(hdr = gem_check(xo, NULL, 0)))
    return XO_NONE;

  /* itoc.030323: 個人精華區不需可見名單 */
  if (!(hdr->xmode & GEM_RESTRICT) || *xo->dir == 'u')
    return XO_NONE;

  gembrdname_get(xboard, xo->dir);
  sprintf(fpath, "gem/brd/%s/gempal_DIR", xboard);
  if (!dashd(fpath))
    mkdir(fpath, 0755);

  gempal_fpath(fpath, xboard, 'C', hdr);
  /* itoc.010412: t_pal() 改成每次退出好友名單就 free,而不在
     talk_main() 中,所以要重設 pal_cb */
  xz[XZ_PAL - XO_ZONE].xo = xt = xo_new(fpath);
  xz[XZ_PAL - XO_ZONE].cb = pal_cb;
  xover(XZ_PAL);              /* Thor: 進xover前, pal_xo 一定要 ready */

  /* build userno image to speed up, maybe upgreade to shm */

  bm_image_gempal(hdr, xboard);

  free(xt);

  return gem_init(xo);
}
#endif   /* GEM_PAL */


: gem.c:gem_item()  修改gem_item()

static void
- gem_item(num, hdr, level)
+ gem_item(xo, num, hdr, level)
+  XO *xo;
  int num;
  HDR *hdr;
  int level;
{
  int xmode, gtype;

+#ifdef HAVE_GEMPAL
+ char xboard[BNLEN + 1];
+ gembrdname_get(xboard, xo->dir);
+#endif

  /* ◎☆★◇◆□■▽▼ : A1B7 ... */

  xmode = hdr->xmode;
  gtype = (char) 0xba;

  ......(略)

  gtype = gem_way;

+#ifdef HAVE_GEMPAL
+ if ((xmode & GEM_RESTRICT) && !(level & GEM_M_BIT) &&
+   !gempal_belong(xboard, hdr))
+#else
  if ((xmode & GEM_RESTRICT) && !(level & GEM_M_BIT))
+#endif
    outs(MSG_DATA_CLOAK);             /* itoc.000319: 限制級文章保密 */

: gem.c 所有用到 gem_item() 的地方都要改

 :: gem_body
  do
  {
-   gem_item(++num, hdr++, tail);
+   gem_item(xo, ++num, hdr++, tail);
  } while (num < max);

 :: gem_title
    move(num - xo->top + 2, 0);
-   gem_item(++pos, fhdr, xo->key);
+   gem_item(xo, ++pos, fhdr, xo->key);

 :: gem_refuse
    move(num - xo->top + 2, 0);
-   gem_item(num, hdr, xo->key);
+   gem_item(xo, num, hdr, xo->key);

: gem.c:gem_check()  修改gem_check

  HDR *hdr;
  int gtype;
  char *folder;
+#ifdef HAVE_GEMPAL
+ char xboard[BNLEN + 1];
+ gembrdname_get(xboard, xo->dir);
+#endif

  hdr = (HDR *) xo_pool + (xo->pos - xo->top);
  gtype = hdr->xmode;

+#ifdef HAVE_GEMPAL
+ if ((gtype & GEM_RESTRICT) && !(xo->key & GEM_M_BIT) &&
+   !gempal_belong(xboard, hdr))
+#else
  if ((gtype & GEM_RESTRICT) && !(xo->key & GEM_M_BIT))
+#endif
    return NULL;

  if ((op & GEM_PLAIN) && (gtype & GEM_FOLDER))
    return NULL;

: gem.c:gem_refuse()  修改gem_refuse

static int
gem_refuse(xo)
  XO *xo;
{
  HDR *ghdr;
  int num;

  if ((xo->key & GEM_M_BIT) && (hdr = gem_check(xo, NULL, 0)))
  {
+#ifdef HAVE_GEMPAL
+   if (hdr->xmode & GEM_RESTRICT)
+   {
+     if (vans("您確定要解除文章保密嗎?可見名單將會全部砍除喔![N] ") == 'y')
+     {
+       char xboard[BNLEN + 1];
+
+       hdr->xmode ^= GEM_RESTRICT;
+       rec_put(xo->dir, hdr, sizeof(HDR), xo->pos, NULL);
+
+       gembrdname_get(xboard, xo->dir);
+       kill_gempal(xboard, hdr);
+
+       return gem_load(xo);
+     }
+     return XO_FOOT;
+   }
+#endif

    hdr->xmode ^= GEM_RESTRICT;
    num = xo->pos;
    rec_put(xo->dir, hdr, sizeof(HDR), num, NULL);

+#ifdef HAVE_GEMPAL
+   if (*xo->dir == 'g')   /* amaki.030411: 非看板精華區不設可見名單 */
+     return XoBM_gempal(xo);
+#endif

    num++;
    move(num - xo->top + 2, 0);
    gem_item(num, hdr, xo->key);
  }

  return XO_NONE;
}


: gem.c:delgem() 修改delgem

    if (hdr->xname[0] != '@')
    {
      hdr_fpath(fpath, xo->dir, hdr);
      unlink(fpath);
    }
  }

+#ifdef HAVE_GEMPAL
+ if (!(hdr->xmode & GEM_BOARD) && (hdr->xmode & GEM_RESTRICT))
+ {
+   char xboard[BNLEN + 1];
+
+   gembrdname_get(xboard, xo->dir);
+   kill_gempal(xboard, hdr);
+ }
+#endif
}

: gem.c:gem_cb[]  修改gem_cb

+#ifdef HAVE_GEMPAL
+  'O', XoBM_gempal,
+#endif


: pal.c:pal_body()  修改pal_body

+extern BCACHE *bshm;

static int
pal_body(xo)
  XO *xo;
{
  PAL *pal;
+ BRD *brd;
  int num, max, tail;

+#ifdef HAVE_GEMPAL
+ char *dir;
+ dir = xo->dir;
+#endif

  move(3, 0);
  clrtobot();
  max = xo->max;
  if (max <= 0)
  {
+#ifdef HAVE_GEMPAL
+   if (*dir == 'b')
+   {
+     brd = bshm->bcache + brd_bno(currboard);
+     if ((brd->readlevel == PERM_SYSOP) || (brd->readlevel == PERM_BOARD))
+     {
+       if (vans("要設看板可見名單嗎(Y/N)?[N] ") == 'y')
+         return pal_add(xo);
+     }
+#ifdef HAVE_BUCKET
+     else
+     {
+       if (vans("要設看板水桶名單嗎(Y/N)?[N] ") == 'y')
+         return pal_add(xo);
+     }
+#endif
+   }
+   else if (*dir == 'g')
+   {
+     if (vans("要設精華區可見名單嗎(Y/N)?[N] ") == 'y')
+       return pal_add(xo);
+   }
+   else
+#endif
      if (vans("要交新朋友嗎(Y/N)?[N] ") == 'y')
        return pal_add(xo);
    return XO_QUIT;
  }

--
  Origin: luna.twbbs.org
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻