回文章列表
作者guessi.bbs@cpu.tfcis.org (沒) 看板: itoc
標題[功能] 自動檢查並清除幽靈板主 (修正版)
時間動力核心 (2010/01/10 Sun 19:35:34)
流程簡要概述:

Step 1. 依序檢查板主列表
        i)  ID存在於板主列表 而該ID已不存在
            => 將該ID從板主列表中拿除
        ii) ID存在於板主列表 而該ID沒有PERM_BM權限
            => 表示該ID曾被刪除 且後來又再被申請
               將該ID從板主列表中拿除

Step 2. 建立全站看板板主列表

Step 3. 檢查全站使用者權限
        若該ID擁有PERM_BM權限 卻不在全站板主列表清單中
        => 拿除該ID的PERM_BM權限 (避免非板主看到BM ONLY看板)

DONE!


正文開始:

: src/util/resetPermBM.c 新增此檔案

/*-------------------------------------------------------*/
/* util/resetPermBM.c     ( NTHU CS MapleBBS Ver 3.10 )  */
/*-------------------------------------------------------*/
/* target : 看板板主清單整理刷新                         */
/* create : 01/08/2010                                   */
/* update : 01/08/2010                                   */
/* author : guessi.bbs@bbs.ndhu.edu.tw                   */
/*-------------------------------------------------------*/

#include "bbs.h"

#define MAX_BMLIST_SIZE 1024

static BCACHE *bshm;
static int total = 0;
static char bmlist[MAX_BMLIST_SIZE][IDLEN + 1];

static void
init_bshm()
{
 /*
  * itoc.030727: 在開啟 bbsd 之前,應該就要執行過 account
  *              所以 bshm 應該已設定好
  */
 bshm = shm_new(BRDSHM_KEY, sizeof(BCACHE));

 if (bshm->uptime <= 0)  /* bshm 未設定完成 */
   exit(0);
}

static void
check_bmlist()
{
 ACCT acct;
 BRD *bhdr, *tail, newbrd;
 char userid[IDLEN + 1];
 char fpath[64], buf[80], *blist, *tmp;
 int BMlen, len, rt;

 bhdr = bshm->bcache;
 tail = bhdr + bshm->number;

 do
 {
   /* guessi.100108 先備份 */
   memcpy(&newbrd, bhdr, sizeof(BRD));

   blist = bhdr->BM;
   strcpy(buf, blist);
   BMlen = strlen(buf);
   /* guessi.100108 找出第一個看板板主帳號 */
   tmp = strtok(bhdr->BM, "/");

   while (tmp != NULL)
   {
     sprintf(userid, "%s", tmp);
     len = strlen(userid);
     usr_fpath(fpath, userid, FN_ACCT);
     rt = rec_get(fpath, &acct, sizeof(ACCT), 0);

     /* guessi.011008
      * rt <  0 帳號不存在
      * rt >= 0 && !(acct.userlevel & PERM_BM) 帳號存在 但沒有PERM_BM權限  */
     if (rt < 0 || (rt >= 0 && !(acct.userlevel & PERM_BM)))
     {
       /* guessi.100108 帳號不存在(此部分參考manage.c)
        * 或帳號存在 但沒有PERM_BM 都應該從板主列表中移除 */
       if (BMlen == len)
       {
         /* 若只有一個板主 */
         *buf = '\0';
         break;
       }
       else if (!str_cmp(buf + BMlen - len, userid) && buf[BMlen - len - 1]
== '/')
       {
         /* 板主列表中 最後一位板主 */
         buf[BMlen - len - 1] = '\0';
         len++;
         BMlen -= len;
       }
       else
       {
         /* 其他板主(含正板主) */
         str_lower(userid, userid);
         strcat(userid, "/");
         len++;
         blist = str_str(buf, userid);
         strcpy(blist, blist + len);
         BMlen -= len;
       }
     }
     /* guessi.100108 繼續尋找下一個看板板主帳號 */
     tmp = strtok(NULL, "/");
   }

   strcpy(newbrd.BM, buf);

   /* 若有更動 將BRD記錄寫入 */
   if (memcmp(&newbrd, bhdr, sizeof(BRD)))
   {
     memcpy(bhdr, &newbrd, sizeof(BRD));
     rec_put(FN_BRD, &newbrd, sizeof(BRD), bhdr - bshm->bcache, NULL);
   }
 } while (++bhdr < tail);
}

static void
check_user()
{
 BRD *bhdr, *tail;
 char *tmp, c;
 int x;

 bhdr = bshm->bcache;
 tail = bhdr + bshm->number;

 /* guessi.100110 初始化 */
 for (x = 0; x < MAX_BMLIST_SIZE; x++)
   *bmlist[x] = '\0';

 /* guessi.100110 蒐集全站板主名單 */
 do
 {
   tmp = strtok(bhdr->BM, "/");
   while (tmp != NULL)
   {
     sprintf(bmlist[total++], tmp);
     tmp = strtok(NULL, "/");
   }
 } while (++bhdr < tail);

 /* guessi.100110 開始檢查使用者權限  */
 for (c = 'a'; c <= 'z'; c++)
 {
   char buf[64];
   struct dirent *de;
   DIR *dirp;

   sprintf(buf, BBSHOME "/usr/%c", c);
   chdir(buf);

   if (!(dirp = opendir(".")))
     continue;

   while (de = readdir(dirp))
   {
     ACCT acct;
     int fd;
     char *fname;
     fname = de->d_name;
     if (*fname <= ' ' || *fname == '.')
       continue;

     sprintf(buf, "%s/.ACCT", fname);

     if ((fd = open(buf, O_RDONLY)) < 0)
       continue;

     read(fd, &acct, sizeof(ACCT));
     close(fd);

     /* guessi.100110 若有板主權限 確不在板主清單 拿掉PERM_BM */
     if (!(acct.userlevel & PERM_BM))
     {
       if (!inlist(fname))
       {
         acct.userlevel &= ~PERM_BM;
       }
     }
   }
   closedir(dirp);
 }
}

int
inlist(userid)
 char *userid;
{
 int i = 0;

 while (i < total)
 {
   if (!str_cmp(bmlist[i], userid))
     return 1;
   i++;
 }
 return 0;
}


int
main()
{
 init_bshm();
 chdir(BBSHOME);

 /* guessi.100108 檢查全站幽靈板主                   *
  *               若使用者帳號存在於板主列表         *
  *               而該帳號已不存在或曾經被重新申請   *
  *               則將該帳號從板主列表中拿除         */
 check_bmlist();

 /* guessi.100110 設定全站使用者權限                 *
  *               若有PERM_BM權限 卻不在全站板主清單 *
  *               則拿掉其PERM_BM權限                */
 check_user();

 return 0;
}


: src/util/Makefile

! ... resetPermBM


最後... 將resetPermBM 加入crontab排程 或是有需要的時候再執行



--
=[:摃��:﹎Origin ]|[  Ocpu.tfcis.org  ]|[�搟說:]=
=[:摃�╱�:Author ]|[118-161-212-81.dynamic.hin]|[�:]=
文章選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻