diff options
author | wens <wens@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2008-08-05 14:35:19 +0800 |
---|---|---|
committer | wens <wens@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2008-08-05 14:35:19 +0800 |
commit | acc64c7026616cd9b811a5e6f0aa3818bcbc2704 (patch) | |
tree | 8d89db899d1ef3f8d60c848cc20eb912d551e6a8 | |
parent | 7841c7805eecd66410e223336ee4fd557f67a126 (diff) | |
download | pttbbs-acc64c7026616cd9b811a5e6f0aa3818bcbc2704.tar pttbbs-acc64c7026616cd9b811a5e6f0aa3818bcbc2704.tar.gz pttbbs-acc64c7026616cd9b811a5e6f0aa3818bcbc2704.tar.bz2 pttbbs-acc64c7026616cd9b811a5e6f0aa3818bcbc2704.tar.lz pttbbs-acc64c7026616cd9b811a5e6f0aa3818bcbc2704.tar.xz pttbbs-acc64c7026616cd9b811a5e6f0aa3818bcbc2704.tar.zst pttbbs-acc64c7026616cd9b811a5e6f0aa3818bcbc2704.zip |
Partial rewrite, make things clearer
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4396 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r-- | util/mandex.c | 443 |
1 files changed, 231 insertions, 212 deletions
diff --git a/util/mandex.c b/util/mandex.c index 2ca7edee..aeb0740c 100644 --- a/util/mandex.c +++ b/util/mandex.c @@ -3,177 +3,238 @@ /* 'mandex -h' to help */ #include "bbs.h" -#ifndef MAXPATHLEN -#define MAXPATHLEN 1024 -#endif -typedef struct -{ +typedef struct { char bname[40]; int ndir, nfile, k; -} boardinfo; - -extern int numboards; -extern boardheader_t *bcache; -boardinfo board[MAX_BOARD], *biptr; -char color[4][10] = {"[1;33m", "[1;32m", "[1;36m", "[1;37m"}; -char fn_index[] = ".index"; -char fn_new[] = ".index.new"; -char index_title[] = "◎ 精華區目錄索引"; -char topdir[128], pgem[512], pndx[512]; -FILE *fndx; -int ndir, nfile, index_pos, k; -int nSorted, nb; +} boardinfo_t; + +static const char *color[4] = {"[1;33m", "[1;32m", "[1;36m", "[1;37m"}; +static const char *fn_index = ".index"; +static const char *fn_new = ".index.new"; +static const char *index_title = "◎ 精華區目錄索引";; int sortbyname(const void *a, const void *b) { - return strcmp(((boardinfo*)b)->bname, ((boardinfo*)a)->bname); + return strcmp(((boardinfo_t*)b)->bname, ((boardinfo_t*)a)->bname); } -int k_cmp(b, a) - boardinfo *b, *a; +int k_cmp(const void *x, const void *y) { + boardinfo_t *b = (boardinfo_t *)x, *a = (boardinfo_t *)y; return ((a->k / 100 + a->ndir + a->nfile) - (b->k / 100 + b->ndir + b->nfile)); } -/* visit the hierarchy recursively */ +static FILE *fp_index; +static boardinfo_t curr_brdinfo; +/* visit the hierarchy recursively */ void -mandex(level, num_header, fpath) - int level; - char *fpath, *num_header; +mandex(const int level, const char *num_header, char *fpath) { - FILE *fgem; - char *fname, buf[256]; - struct stat st; + FILE *fp_dir; + char *fname, buf[512]; int count; fileheader_t fhdr; - fgem = fopen(fpath, "r+"); - if (fgem == NULL) + if ((fp_dir = fopen(fpath, "r+")) == NULL) return; - fname = strrchr(fpath, '.'); - if (!level){ - printf("%s\r\n",fpath); - strcpy(pgem, fpath); + fname = strrchr(fpath, '/') + 1; + count = 0; + + while (fread(&fhdr, sizeof(fhdr), 1, fp_dir) == 1) { + ++count; - strcpy(fname, fn_new); - fndx = fopen(fpath, "w"); - if (fndx == NULL){ - fclose(fgem); - return; - } - fprintf(fndx, "[1;32m序號\t\t\t精華區主題[m\n" - "[36m───────────────────" - "───────────────────[m\n"); - strcpy(pndx, fpath); - ndir = nfile = 0; - index_pos = -1; - } + if (!fhdr.filename[0]) + continue; - count = 0; - while (fread(&fhdr, sizeof(fhdr), 1, fgem) == 1){ - strcpy(fname, fhdr.filename); - if (!fname[0]) continue; - if (!level && !strncmp(fhdr.title, index_title, strlen(index_title)) - && index_pos < 0){ - index_pos = count; - unlink(fpath); - } - st.st_size = 0; - stat(fpath, &st); + *fname = '\0'; + strlcat(fpath, fhdr.filename, PATHLEN); - sprintf(buf, "%.*s%s%3d. %s [m\n", - 11 * level, num_header, color[level % 4], ++count, fhdr.title); + snprintf(buf, sizeof(buf), "%.*s%s%3d. %s [m\n", + 11 * level, num_header, color[level % 4], count, fhdr.title); /* Ptt */ - fputs(buf, fndx); - if (dashd(fpath)){ - ++ndir; - /* I can't find the code to change title? */ - if (*fhdr.title != '#' && level < 10 && - (fhdr.filemode&(FILE_BM|FILE_HIDE))==0){ - strcat(fpath, "/.DIR"); + fputs(buf, fp_index); + + if (dashd(fpath)) { + curr_brdinfo.ndir++; + if (level < 10 && !(fhdr.filemode & (FILE_BM|FILE_HIDE))) { + strlcat(fpath, "/" FN_DIR, PATHLEN); mandex(level + 1, buf, fpath); } } else - ++nfile; + curr_brdinfo.nfile++; } - if (!level){ - char lpath[MAXPATHLEN]; - - fclose(fndx); - strcpy(fname, fn_index); - rename(pndx, fpath); - strcpy(pndx, fpath); - - sprintf(buf, "%s.new", pgem); - if (index_pos >= 0 || (fndx = fopen(buf, "w"))){ - fname[-1] = 0; - stamplink(fpath, &fhdr); - unlink(fpath); - strcpy(fhdr.owner, "每天自動更新"); - sprintf(lpath, "%s/%s", topdir, pndx); - st.st_size = 0; - stat(lpath, &st); - sprintf(fhdr.title, "%s (%.1fk)", index_title, st.st_size / 1024.); - k = st.st_size; /* Ptt */ - printf("(%s)[%dK]", fpath, k); - symlink(lpath, fpath); - if (index_pos < 0){ - fwrite(&fhdr, sizeof(fhdr), 1, fndx); - rewind(fgem); - while (fread(&fhdr, sizeof(fhdr), 1, fgem) == 1) - fwrite(&fhdr, sizeof(fhdr), 1, fndx); - fclose(fndx); - fclose(fgem); - rename(buf, pgem); - } - else{ - fseek(fgem, index_pos * sizeof(fhdr), 0); - fwrite(&fhdr, sizeof(fhdr), 1, fgem); - fclose(fgem); - } - return; + fclose(fp_dir); +} + +void +man_index(const char * brdname) +{ + char buf[PATHLEN], fpath[PATHLEN], *p; + int i, index_pos = -1; + FILE *fp_dir; + struct stat st; + fileheader_t fhdr; + boardheader_t *bptr; + + if ((i = getbnum(brdname)) == 0) + return; + + bptr = getbcache(i); + if (strcmp(brdname, bptr->brdname) != 0) + return; + + memset(&curr_brdinfo, 0, sizeof(curr_brdinfo)); + strlcpy(curr_brdinfo.bname, brdname, sizeof(curr_brdinfo.bname)); + + setapath(buf, brdname); + setadir(fpath, buf); + + setdirpath(buf, fpath, fn_new); + + if ((fp_index = fopen(buf, "w")) == NULL) + return; + + fprintf(fp_index, "[1;32m序號\t\t\t精華區主題[m\n" + "[36m───────────────────" + "───────────────────[m\n"); + printf("%s ", fpath); + mandex(0, "", fpath); + fclose(fp_index); + stat(buf, &st); + curr_brdinfo.k = st.st_size; + printf("(%s)[%dK] d: %d f: %d\n", buf, curr_brdinfo.k, curr_brdinfo.ndir, curr_brdinfo.nfile); + + setdirpath(fpath, buf, fn_index); + rename(buf, fpath); + setdirpath(fpath, buf, FN_DIR); + + sprintf(buf, "%s.new", fpath); + + if ((fp_dir = fopen(fpath, "r+")) == NULL) + return; + + if ((fp_index = fopen(buf, "w")) == NULL) { + fclose(fp_dir); + return; + } + + i = 0; + while (fread(&fhdr, sizeof(fhdr), 1, fp_dir) == 1) { + if (strncmp(fhdr.title, index_title, strlen(index_title)) == 0) { + index_pos = i; + setdirpath(buf, fpath, fhdr.filename); + unlink(buf); + break; } + i++; + } + + p = strrchr(buf, '/'); + *p = '\0'; + stamplink(buf, &fhdr); + unlink(buf); + symlink(fn_index, buf); + strlcpy(fhdr.owner, "每天自動更新", sizeof(fhdr.owner)); + snprintf(fhdr.title, sizeof(fhdr.title), "%s (%.1fk)", index_title, st.st_size / 1024.); + + sprintf(buf, "%s.new", fpath); + + if (index_pos >= 0) { + fseek(fp_dir, index_pos * sizeof(fhdr), SEEK_SET); + fwrite(&fhdr, sizeof(fhdr), 1, fp_dir); + unlink(buf); + } else { + fwrite(&fhdr, sizeof(fhdr), 1, fp_index); + rewind(fp_dir); + while (fread(&fhdr, sizeof(fhdr), 1, fp_dir) == 1) + fwrite(&fhdr, sizeof(fhdr), 1, fp_index); + rename(buf, fpath); } - fclose(fgem); + + fclose(fp_index); + fclose(fp_dir); } +void +output_chart(const boardinfo_t * board, const int nbrds) +{ + FILE * fp; + int i, n, place = 0; + boardheader_t *bptr = NULL; + + if (!(fp = fopen(BBSHOME "/etc/topboardman", "w"))) + return; + + fprintf(fp, "[1;44m排名[47;30m 看 板 目錄數 檔案數" + " byte數 [30m 總 分 板 主 [m\n"); + + for (i = 0; i < nbrds; i++) { + if ((n = getbnum(board[i].bname)) == 0) + continue; + + bptr = getbcache(n); + if (strcmp(board[i].bname, bptr->brdname) != 0) + continue; + + if (bptr->brdattr & (BRD_BAD | BRD_NOCOUNT)) + continue; + + /* 板主設定不列入記錄 */ + if (bptr->brdattr & BRD_HIDE && !(bptr->brdattr & BRD_BMCOUNT)) + continue; + + if (board[i].ndir + board[i].nfile < 5) + break; + + fprintf(fp, "%3d.[33m%15s[m %5d %7d %10d %6d [31m%-24.24s[m\n", + ++place, board[i].bname, board[i].ndir, board[i].nfile, board[i].k + ,board[i].k / 100 + board[i].nfile + board[i].ndir + ,bptr->BM); + } + fclose(fp); +} int main(int argc, char* argv[]) { - boardheader_t *bptr = NULL; + boardinfo_t board[MAX_BOARD], *biptr; + int nSorted, nb; DIR *dirp; struct dirent *de; - int ch, n, place = 0, fd, i; - char checkrebuild = 0, *fname, fpath[MAXPATHLEN]; - char dirs[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', - 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', - 'z', 'x', 'c', 'v', 'b', 'n', 'm', - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', - 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', - 'Z', 'X', 'C', 'V', 'B', 'N', 'M', 0}; + int i, fd, checkrebuild = 0; + char *fname, fpath[PATHLEN]; + char dirs[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 0}; nice(10); - while( (ch = getopt(argc, argv, "xh")) != -1 ){ - switch( ch ){ - case 'x': - checkrebuild = 1; - break; - case 'h': - printf("NAME \n" - " mandex - 精華區索引程式 (man index)\n\n" - "SYNOPSIS \n" - " mandex [-x] [board] \n\n" - "DESCRIPTION \n" - "精華區索引 (man index) \n\n" - "-x 只有含有 .rebuild的目錄才重製 \n" - "board 全部的板 (default to all) \n\n"); - return 0; + while ((i = getopt(argc, argv, "xh")) != -1) { + switch (i) { + case 'x': + checkrebuild = 1; + break; + case 'h': + printf("NAME\n" + " mandex - 精華區索引程式 (man index)\n" + "\n" + "SYNOPSIS\n" + " mandex [-x] [-v] [board] ...\n" + "\n" + "DESCRIPTION\n" + "精華區索引 (man index)\n\n" + "-x 只有含有 .rebuild的目錄才重製\n" + "-v 顯示全部路徑\n" + "board 全部的板 (default to all)\n\n"); + return 0; } } @@ -182,114 +243,72 @@ int main(int argc, char* argv[]) attach_SHM(); resolve_boards(); -/* - if( argc == 0 ){ - puts("Creating the whole index..."); - chdir(strcpy(topdir, BBSHOME)); - strcpy(fpath, "man/.DIR"); - mandex(0, "", fpath); - } -*/ - chdir(strcpy(topdir, BBSHOME "/man/boards")); - if( argc == 1 ){ - sprintf(fpath, "%c/%s/.DIR", argv[0][0], argv[0]); - mandex(0, "", fpath); + chdir(BBSHOME); + + /* process boards given in arguments */ + if (argc > 0) { + for (i = 0; i < argc; i++) + man_index(argv[i]); + return 0; } /* process all boards */ - if( checkrebuild && - (fd = open(BBSHOME "/man/.rank.cache", O_RDONLY)) >= 0 ){ + if (checkrebuild && (fd = open("man/.rank.cache", O_RDONLY)) >= 0) { read(fd, board, sizeof(board)); close(fd); - qsort(board, MAX_BOARD, sizeof(boardinfo), sortbyname); - for( nb = 0 ; board[nb].bname[0] != 0 ; ++nb ) - ; + qsort(board, MAX_BOARD, sizeof(boardinfo_t), sortbyname); + for (nb = 0; board[nb].bname[0] != 0; ++nb); nSorted = nb; - } - else{ + } else { memset(board, 0, sizeof(board)); checkrebuild = 0; nSorted = nb = 0; } - for( i = 0 ; dirs[i] != 0 ; ++i ){ - sprintf(topdir, BBSHOME "/man/boards/%c", dirs[i]); - chdir(topdir); - if(!(dirp = opendir(topdir))) { - printf("## unable to enter [man/boards]\n"); + for (i = 0; dirs[i] != 0; ++i) { + snprintf(fpath, sizeof(fpath), "man/boards/%c", dirs[i]); + if (!(dirp = opendir(fpath))) { + printf("## unable to enter [man/boards/%c]\n", dirs[i]); exit(-1); } - while((de = readdir(dirp))){ + while ((de = readdir(dirp))) { fname = de->d_name; - ch = fname[0]; - if (ch != '.'){ - k = 0; - if( checkrebuild ){ - sprintf(fpath, "%s/.rebuild", fname); - if( access(fpath, 0) < 0 ){ - printf("skip no modify board %s\n", fname); - continue; - } - unlink(fpath); - } - sprintf(fpath, "%s/.DIR", fname); - mandex(0, "", fpath); - printf("%-14sd: %d\tf: %d\n", fname, ndir, nfile); /* report */ - if( k ){ - if( !(biptr = bsearch(fname, board, nSorted, - sizeof(boardinfo), sortbyname))){ - biptr = &board[nb]; - ++nb; - } - strcpy(biptr->bname, fname); - biptr->ndir = ndir; - biptr->nfile = nfile; - biptr->k = k; + + if (fname[0] == '.') + continue; + + if (checkrebuild) { + sprintf(fpath, "%s/.rebuild", fname); + if (access(fpath, 0) < 0) { + printf("skip no modify board %s\n", fname); + continue; } + unlink(fpath); + } + + man_index(fname); + + if (curr_brdinfo.k) { + if (!(biptr = bsearch(fname, board, nSorted, sizeof(boardinfo_t), sortbyname))) + biptr = &board[nb++]; + memcpy(biptr, &curr_brdinfo, sizeof(boardinfo_t)); } } closedir(dirp); } - qsort(board, nb, sizeof(boardinfo), k_cmp); + qsort(board, nb, sizeof(boardinfo_t), k_cmp); + output_chart(board, nb); unlink(BBSHOME "/man/.rank.cache"); - if( (fd = open(BBSHOME "/man/.rank.cache", - O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, 0660)) >= 0 ){ - write(fd, board, sizeof(board)); + + if ((fd = open(BBSHOME "/man/.rank.cache", + O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, 0660)) >= 0) { + write(fd, board, sizeof(board)); close(fd); } - if (!(fndx = fopen(BBSHOME "/etc/topboardman", "w"))) - exit(0); - - fprintf(fndx, "[1;44m排名[47;30m 看 板 目錄數 檔案數" - " byte數 [30m 總 分 板 主 [m\n"); - - for (ch = 0; ch < nb; ch++){ - for (n = 0; n < numboards; n++){ - bptr = &bcache[n]; - if (!strcmp(bptr->brdname, board[ch].bname)) - break; - } - if (n >= numboards || - (bptr->brdattr & (BRD_BAD | BRD_NOCOUNT))) - continue; - /* 板主設定不列入記錄 */ - if (bptr->brdattr & BRD_HIDE && !(bptr->brdattr & BRD_BMCOUNT)) - continue; - - if (board[ch].ndir + board[ch].nfile < 5) - break; - fprintf(fndx, "%3d.[33m%15s[m %5d %7d %10d %6d [31m%-24.24s[m\n", - ++place, - board[ch].bname, - board[ch].ndir, board[ch].nfile, board[ch].k - ,board[ch].k / 100 + board[ch].nfile + board[ch].ndir - ,bptr->BM); - } - fclose(fndx); return 0; } |