作者amaki.bbs@luna.twbbs.org (巧克力羊) 看板: plan
標題[功能]看板精華區排行榜
時間月下夜想 (2004/01/02 Fri 22:58:57) Updated: 2004/01/02
聽說不少站台有這東西,寫寫當新年禮物吧。
站長先在Announce裡新增資料,檔名為@-topgem
util/下新增這支topgemsize.c
crontab -e設個定期跑的時間就可以了。
另外這支程式裡有個node(),裡面的4094跟1024個別是我的硬碟初始化時的block跟
fragment大小,這只能算出比較接近的inode數(一個inode佔去128 bytes),如果你的
比例不是4096 / 1024請調整成自己硬碟的參數。
: src/util/Makefile
EXE = ... topgemsize
: topgemsize.c
/*-------------------------------------------------------*/
/* util/topgemsize.c ( NTHU CS MapleBBS Ver 3.10 ) */
/*-------------------------------------------------------*/
/* target : 看板精華區區排行榜 */
/* create : 04/01/02 */
/* author : amaki.bbs@luna.twbbs.org */
/*-------------------------------------------------------*/
#include "bbs.h"
#define TOPGEM "gem/@/@-topgem"
typedef struct
{
int year;
int yday;
int mon;
int mday;
int wday;
int hour;
} DATE;
typedef struct
{
int bno;
int dir_nums;
int file_nums;
int gsize;
} BGEM;
static BCACHE *bshm;
static BGEM *bgem;
static int
node(size)
int size;
{
int node, frag;
node = (size / 4096) * 128;
node += (frag = (size % 4096) / 1024) ? frag * 128 : 0;
return node;
}
static void
gem_folder(folder, gem_set)
char *folder;
BGEM *gem_set;
{
int fd, count, dnum;
char fpath[64];
HDR *xt, *hdr;
struct stat st;
if ((fd = open(folder, O_RDONLY)) < 0)
return;
fstat(fd, &st);
hdr = xt = (HDR *) malloc(count = st.st_size);
count = read(fd, xt, count) / sizeof(HDR);
close(fd);
do
{
hdr_fpath(fpath, folder, hdr);
if (hdr->xmode & GEM_FOLDER)
{
gem_set->dir_nums++;
if (dnum = rec_num(fpath, sizeof(HDR)) > 0)
{
gem_set->file_nums++;
gem_set->gsize += dnum * sizeof(HDR) + node(dnum * sizeof(HDR));
gem_folder(fpath, gem_set);
}
}
else if (dashf(fpath))
{
stat(fpath, &st);
gem_set->file_nums++;
gem_set->gsize += st.st_size + node(st.st_size);
}
} while (++hdr < xt + count);
free(xt);
}
static void
gem_counter(brd, gem_set)
BRD *brd;
BGEM *gem_set;
{
int fd, count, dnum;
char fpath[64], folder[64];
HDR *xt, *hdr;
struct stat st;
sprintf(folder, "gem/brd/%s/%s", brd->brdname, FN_DIR);
if ((fd = open(folder, O_RDONLY)) < 0)
return;
fstat(fd, &st);
hdr = xt = (HDR *) malloc(count = st.st_size);
count = read(fd, xt, count) / sizeof(HDR);
close(fd);
do
{
hdr_fpath(fpath, folder, hdr);
if (hdr->xmode & GEM_FOLDER)
{
gem_set->dir_nums++;
if (dnum = rec_num(fpath, sizeof(HDR)) > 0)
{
gem_set->file_nums++;
gem_set->gsize += dnum * sizeof(HDR) + node(dnum * sizeof(HDR));
gem_folder(fpath, gem_set);
}
}
else if (dashf(fpath))
{
stat(fpath, &st);
gem_set->file_nums++;
gem_set->gsize += st.st_size + node(st.st_size);
}
} while (++hdr < xt + count);
free(xt);
}
static void
gem_record(date)
DATE *date;
{
int ansi, i = 0;
BRD *brd;
BGEM *bgem_set;
FILE *fp;
char msg[80], dbuf[16], anony[16];
if (!(fp = fopen(TOPGEM, "w")))
return;
sprintf(msg, "%d月%d日看板精華區排行", date->mon, date->mday);
fprintf(fp, "\033[1;35;47m%*s%*s",
41 + strlen(msg) / 2, msg, 41 - strlen(msg) / 2, "\033[m\n");
fprintf(fp, "\033[1;37;45m【排 名】 【看 板】 【檔案數】 【目錄數】"
" 【總精華區大小(bytes)】 \033[m\n");
do
{
ansi = 0;
bgem_set = bgem + i;
brd = bshm->bcache + bgem_set->bno;
sprintf(dbuf, "%d.", i + 1);
sprintf(anony, "%c%s", brd->brdname[0], "○○○○");
if (i < 5)
{
fprintf(fp, " \033[1m%-11s%-14s%-12d%-12d%-d ", dbuf,
(brd->battr & BRD_NOSTAT) ? anony : brd->brdname,
bgem_set->file_nums, bgem_set->dir_nums, bgem_set->gsize);
ansi = 1;
}
else if (i < 9)
{
fprintf(fp, " \033[1;33m%-11s%-14s%-12d%-12d%-d ", dbuf,
(brd->battr & BRD_NOSTAT) ? anony : brd->brdname,
bgem_set->file_nums, bgem_set->dir_nums, bgem_set->gsize);
ansi = 1;
}
else
{
fprintf(fp, " %-11s%-14s%-12d%-12d%-d ", dbuf,
(brd->battr & BRD_NOSTAT) ? anony : brd->brdname,
bgem_set->file_nums, bgem_set->dir_nums, bgem_set->gsize);
}
if (bgem_set->gsize > 1048576)
fprintf(fp, "(%dMB)%s\n", bgem_set->gsize / 1048576, ansi ? "\033[m":"");
else if (bgem_set->gsize > 1024)
fprintf(fp, "(%dKB)%s\n", bgem_set->gsize / 1024, ansi ? "\033[m" : "");
else
fprintf(fp, ansi ? "\033[m\n" : "\n");
} while (++i < bshm->number);
fclose(fp);
}
static int
bgem_cmp(a, b)
BGEM *a, *b;
{
return b->gsize - a->gsize;
}
int
main()
{
int i;
BRD *brd;
DATE now;
BGEM *gem_set;
time_t time_now;
struct tm *t;
chdir(BBSHOME);
bshm = shm_new(BRDSHM_KEY, sizeof(BCACHE));
bgem = (BGEM *) malloc(sizeof(BGEM) * bshm->number);
memset(bgem, 0, sizeof(BGEM) * bshm->number);
time(&time_now);
time_now -= 400;
t = localtime(&time_now);
now.year = t->tm_year;
now.yday = t->tm_yday;
now.mon = t->tm_mon + 1;
now.mday = t->tm_mday;
now.wday = t->tm_wday;
now.hour = t->tm_hour;
for (i = 0; i < bshm->number; i++)
{
brd = bshm->bcache + i;
gem_set = bgem + i;
/* amaki.030730: 開啟看板目錄下的bdata */
if (*brd->brdname)
{
gem_set->bno = i;
gem_counter(brd, gem_set);
}
}
qsort(bgem, bshm->number, sizeof(BGEM), bgem_cmp);
gem_record(&now);
free(bgem);
return 0;
}
--
Origin: luna.twbbs.org