作者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 ]|[ ���O���� cpu.tfcis.org ]|[�搟說�﹎:]=
=[﹊:�摃�╱��:﹊Author ]|[118-161-212-81.dynamic.hin]|[���插�﹊:]=