作者s890510.bbs@bbs.cs.ntou.edu.tw (有變胖趨勢的皮卡.. 看板: itoc
標題[功能] 儘sync功能的程式碼
時間網際時空 (2008/08/16 Sat 05:40:13)
這是今天從expire中去做修改出來的...
如果有問題就...在說吧...(測試後看起來是沒有...)
: /util/makefile
EXE = 在後面加上 sync
: /util/sync.c
/*-------------------------------------------------------*/
/* util/sync.c ( NTHU CS MapleBBS Ver 3.00 ) */
/*-------------------------------------------------------*/
/* target : sync */
/* create : 95/03/29 */
/* update : 97/03/29 */
/* modify : 97/08/15 by s890510 */
/*-------------------------------------------------------*/
#include "bbs.h"
#if 0 /* itoc.030325: 簡易說明 */
sync.c本檔案僅對系統做sync
※本系統是由expire.c修改而成
1) 所謂「sync」,為了避免硬碟有多餘的垃圾,若其不在 .DIR 中,
表示這個檔案已經從索引中遺失了,此時系統會直接將這檔案刪除
2) 本sync並沒有時間的設置
#endif
#define SYNC_LOG "run/sync.log"
/* ----------------------------------------------------- */
/* board:shm 部份須與 cache.c 相容 */
/* ----------------------------------------------------- */
static BCACHE *bshm;
static void
init_bshm()
{
/* itoc.030727: 在開啟 bbsd 之前,應該就要執行過 account,
所以 bshm 應該已設定好 */
bshm = shm_new(BRDSHM_KEY, sizeof(BCACHE));
if (bshm->uptime <= 0) /* bshm 未設定完成 */
exit(0);
}
/* ----------------------------------------------------- */
/* synchronize folder & files */
/* ----------------------------------------------------- */
static time_t synctime;
typedef struct
{
time_t chrono;
char prefix; /* 檔案的 family */
char exotic; /* 1:不在.DIR中 0:在.DIR中 */
} SyncData;
static SyncData *sync_pool;
static int sync_size, sync_head;
#define SYNC_DB_SIZE 2048
static int
sync_cmp(a, b)
SyncData *a, *b;
{
return a->chrono - b->chrono;
}
static void
sync_init(fname)
char *fname;
{
int ch, prefix;
time_t chrono;
char *str, fpath[80];
struct dirent *de;
DIR *dirp;
SyncData *xpool;
int xsize, xhead;
if (xpool = sync_pool)
{
xsize = sync_size;
}
else
{
xpool = (SyncData *) malloc(SYNC_DB_SIZE * sizeof(SyncData));
xsize = SYNC_DB_SIZE;
}
xhead = 0;
ch = strlen(fname);
memcpy(fpath, fname, ch);
fname = fpath + ch;
*fname++ = '/';
fname[1] = '\0';
/* itoc.030325.註解: 先把 brd/brdname/?/* 的所有檔案都丟進去 xpool[]
這份觀察名單中,然後回到 expire() 中檢查該檔案是否在 .DIR 中
若在 .DIR 中,就把 exotic 設回 0
最後在 sync_check() 中把觀察名單中 exotic 還是 1 的檔案都刪除 */
ch = '0';
for (;;)
{
*fname = ch++;
if (dirp = opendir(fpath))
{
while (de = readdir(dirp))
{
str = de->d_name;
prefix = *str;
if (prefix == '.')
continue;
chrono = chrono32(str);
if (chrono > synctime) /* 這是最近剛發表的文章,不需要加入 xpool[] 去
sync */
continue;
if (xhead >= xsize)
{
xsize += (xsize >> 1);
xpool = (SyncData *) realloc(xpool, xsize * sizeof(SyncData));
}
xpool[xhead].chrono = chrono;
xpool[xhead].prefix = prefix;
xpool[xhead].exotic = 1; /* 先全部令為 1,於 expire() 中再改回 0 */
xhead++;
}
closedir(dirp);
}
if (ch == 'W')
break;
if (ch == '9' + 1)
ch = 'A';
}
if (xhead > 1)
qsort(xpool, xhead, sizeof(SyncData), sync_cmp);
sync_pool = xpool;
sync_size = xsize;
sync_head = xhead;
}
static void
sync_check(flog, fname)
FILE *flog;
char *fname;
{
char *str, fpath[80];
SyncData *xpool, *xtail;
time_t cc;
if ((cc = sync_head) <= 0)
return;
xpool = sync_pool;
xtail = xpool + cc;
sprintf(fpath, "%s/ /", fname);
str = strchr(fpath, ' ');
fname = str + 3;
do
{
if (xtail->exotic)
{
cc = xtail->chrono;
fname[-1] = xtail->prefix;
*str = radix32[cc & 31];
archiv32(cc, fname);
unlink(fpath);
fprintf(flog, "-\t%s\n", fpath);
}
} while (--xtail >= xpool);
}
static void
expire(flog, bname, sync)
FILE *flog;
char *bname;
int sync;
{
HDR hdr;
struct stat st;
char fpath[128], fnew[128], index[128], *fname, *str;
int done, keep, total;
FILE *fpr, *fpw;
SyncData *xpool, *xsync;
int xhead;
fprintf(flog, "%s\n", bname);
sprintf(index, "%s/.DIR", bname);
if (!(fpr = fopen(index, "r")))
{
fprintf(flog, "\tError open file: %s\n\n", index);
return;
}
fpw = f_new(index, fnew);
if (!fpw)
{
fprintf(flog, "\tExclusive lock: %s\n\n", fnew);
fclose(fpr);
return;
}
if (sync)
{
sync_init(bname);
xpool = sync_pool;
xhead = sync_head;
if (xhead <= 0)
sync = 0;
else
fprintf(flog, "\t%d files to sync\n\n", xhead);
}
strcpy(fpath, index);
str = (char *) strrchr(fpath, '.');
fname = str + 1;
*fname++ = '/';
done = 1;
fstat(fileno(fpr), &st);
total = st.st_size / sizeof(hdr);
while (fread(&hdr, sizeof(hdr), 1, fpr) == 1)
{
keep = 1;
if (sync && (hdr.chrono < synctime))
{
if (xsync = (SyncData *) bsearch(&hdr.chrono, xpool, xhead,
sizeof(SyncData), sync_cmp))
{
xsync->exotic = 0; /* 這篇在 .DIR 中,不 sync */
}
else
{
keep = 0; /* 一律不保留 */
}
}
if (keep)
{
if (fwrite(&hdr, sizeof(hdr), 1, fpw) != 1)
{
fprintf(flog, "\tError in write DIR.n: %s\n", hdr.xname);
done = 0;
sync = 0; /* Thor.990127: 沒作成, 就別砍了吧 */
break;
}
}
}
fclose(fpr);
fclose(fpw);
if (done)
{
sprintf(fpath, "%s.o", index);
if (!rename(index, fpath))
{
if (rename(fnew, index))
rename(fpath, index); /* 換回來 */
}
}
unlink(fnew);
if (sync)
sync_check(flog, bname);
}
int
main(argc, argv)
int argc;
char *argv[];
{
FILE *fp;
int number;
char *bname;
BRD *brdp, *bend;
/* itoc.030325: 要嘛不指定參數,要嘛指定所有參數 */
setgid(BBSGID);
setuid(BBSUID);
chdir(BBSHOME);
init_bshm();
fp = fopen(SYNC_LOG, "w");
chdir("brd");
synctime = time(NULL);
number = synctime / 86400;
brdp = bshm->bcache;
bend = brdp + bshm->number;
do
{
bname = brdp->brdname;
if (!*bname)
continue;
expire(fp, bname, 1);
brdp->btime = 0;
} while (++brdp < bend);
fclose(fp);
exit(0);
}
--
╭┼ Origin: 海大資工˙網際時空 bbs.cs.ntou.edu.tw
┼┘ Author: s890510 從 118-165-216-143.dynamic.hinet.net 發表