回文章列表
作者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: s890510118-165-216-143.dynamic.hinet.net 發表
文章選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻