回精華區
作者itoc (站上人數:802), 信區: plan
標題[功能] 清除過舊的上站來源記錄
時間2005/02/15 Tue 01:25:24 Updated: 2005/08/15
  usr/u/userid/log 這個『上站來源記錄』會因年代久遠而變得很肥大
  這個程式可以刪除過舊的記錄

: src/util/Makefile

EXE =   ..... delog

: src/util/delog.c 新增這程式

/*-------------------------------------------------------*/
/* util/delog.c         ( NTHU CS MapleBBS Ver 3.10 )    */
/*-------------------------------------------------------*/
/* target : 清除過舊的上站來源記錄                       */
/* create : 05/02/14                                     */
/* update :   /  /                                       */
/* author : itoc.bbs@bbs.tnfsh.tn.edu.tw                 */
/*-------------------------------------------------------*/
/* syntax : delog [userid]                               */
/*-------------------------------------------------------*/


#include "bbs.h"


#define QUICK_DELOG


#ifdef QUICK_DELOG
#define KEEP_BYTES      20480   /* 只保留最後 20480 bytes 的上站來源記錄 */
#else
#define KEEP_DAYS       180     /* 只保留最近 180 天的上站來源記錄 */
static int now;
#endif


#ifdef QUICK_DELOG
static void
delog(fpath)
  char *fpath;
{
  int fd, fsize;
  char *fimage, *fend, *ptr;

  if (fimage = f_img(fpath, &fsize))
  {
    if (fsize > KEEP_BYTES)
    {
      fend = fimage + fsize;

      for (ptr = fimage + fsize - KEEP_BYTES;
        *ptr != '\n' && ptr < fend; ptr++);
      ptr++;

      if (ptr < fend)
      {
        if ((fd = open(fpath, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0)
        {
          write(fd, ptr, fend - ptr);
          close(fd);
        }
      }
    }
    free(fimage);
  }
  else
  {
    unlink(fpath);
  }
}
#else
static int
decode_Btime(str)
  char *str;
{
  /* 依 Btime() 格式不同而變 */

  /* 為簡單起見,不考慮閏年及大小月,所以實際保留的日期
     會和 KEEP_DAYS 略有不同 */

  if (*str == '2')      /* 新格式: 2003/12/01 Mon 22:05:38 */
    return atoi(str) * 365 + atoi(str + 5) * 31 + atoi(str + 8);
  else                  /* 舊格式: 03/12/01 15:33:08 */
    return atoi(str) * 365 + atoi(str + 3) * 31 + atoi(str + 6);
}


static void
delog(fpath)
  char *fpath;
{
  int keep;
  char fnew[64], buf[256];
  FILE *fpr, *fpw;

  if (fpr = fopen(fpath, "r"))
  {
    sprintf(fnew, "%s.new", fpath);
    if (fpw = fopen(fnew, "w"))
    {
      keep = 0;
      while (fgets(buf, sizeof(buf), fpr))
      {
        if (!keep)
        {
          if (decode_Btime(buf) >= now)
            keep = 1;
        }

        if (keep)
          fputs(buf, fpw);
      }

      fclose(fpw);
    }
    fclose(fpr);

    unlink(fpath);
    rename(fnew, fpath);
  }
}
#endif


int
main(argc, argv)
  int argc;
  char *argv[];
{
  char c, *str, fpath[64];
  struct dirent *de;
  DIR *dirp;

  if (argc > 2)
  {
    printf("Usage: %s [userid]\n", argv[0]);
    return -1;
  }

#ifndef QUICK_DELOG
  now = decode_Btime(Now()) - KEEP_DAYS;
#endif

  if (argc == 2)
  {
    chdir(BBSHOME);
    usr_fpath(fpath, argv[1], FN_LOG);
    delog(fpath);
    return 0;
  }

  for (c = 'a'; c <= 'z'; c++)
  {
    printf("正開始處理 %c 開頭的 ID\n", c);

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

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

    while (de = readdir(dirp))
    {
      str = de->d_name;
      if (*str <= ' ' || *str == '.')
        continue;

      sprintf(fpath, "%s/" FN_LOG, str);
      delog(fpath);
    }

    closedir(dirp);
  }

  return 0;
}

--
  若 #undef QUICK_DELOG 的話,蠻吃 I/O 的,久久跑一次就可以了

--
□ 本文章由 itocitoc.Dorm11.NCTU.edu.tw 發表
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻