/* $Id: mandex.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ /* target : 精華區索引程式 (man index) syntax : mandex [board] [board] 有值 ==> 只跑該 board 空的 ==> 所有的 boards 都跑 */ #include #include #include #include #include #include #include #include "config.h" #include "pttstruct.h" #include "util.h" #ifndef MAXPATHLEN #define MAXPATHLEN 1024 #endif extern int numboards; extern boardheader_t *bcache; char color[4][10] = {"", "", "", ""}; char fn_index[] = ".index"; char fn_new[] = ".index.new"; char index_title[] = "◎ 精華區目錄索引"; FILE *fndx; int ndir; int nfile; int index_pos; char topdir[128], pgem[512], pndx[512]; int nb = 0; /* board 數 */ struct boardinfo { char bname[40]; int ndir; int nfile; int k; }; typedef struct boardinfo boardinfo; boardinfo board[MAX_BOARD]; int k_cmp(b, a) boardinfo *b, *a; { return ((a->k / 100 + a->ndir + a->nfile) - (b->k / 100 + b->ndir + b->nfile)); } int dashd(fname) char *fname; { struct stat st; return (stat(fname, &st) == 0 && S_ISDIR(st.st_mode)); } /* visit the hierarchy recursively */ void mandex(level, num_header, fpath) int level; char *fpath, *num_header; { FILE *fgem; char *fname, buf[256]; struct stat st; int count; fileheader_t fhdr; fgem = fopen(fpath, "r+"); if (fgem == NULL) return; fname = strrchr(fpath, '.'); if (!level) { printf("%s\r\n",fpath); strcpy(pgem, fpath); strcpy(fname, fn_new); fndx = fopen(fpath, "w"); if (fndx == NULL) { fclose(fgem); return; } fprintf(fndx, "序號\t\t\t精華區主題\n" "──────────────────────────────────────\n"); strcpy(pndx, fpath); ndir = nfile = 0; index_pos = -1; } 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); sprintf(buf, "%.*s%s%3d. %s \n", 11 * level, num_header, color[level % 4], ++count, fhdr.title); /* Ptt */ fputs(buf, fndx); if (dashd(fpath)) { ++ndir; if (*fhdr.title != '#' && level < 10) { strcat(fpath, "/.DIR"); mandex(level + 1, buf, fpath); } } else ++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.); board[nb].k = st.st_size; /* Ptt */ printf("(%d)[%dK]", nb, board[nb].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(fgem); } int main(int argc, char* argv[]){ boardheader_t *bptr; DIR *dirp; struct dirent *de; int ch, n; int place = 0; char *fname, fpath[MAXPATHLEN]; resolve_boards(); nb = 0; if(argc == 1){ 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, "%s/.DIR", argv[1]); mandex(0, "", fpath); exit(0); } /* process all boards */ if(!(dirp = opendir(topdir))) { printf("## unable to enter [man/boards]\n"); exit(-1); } while((de = readdir(dirp))){ fname = de->d_name; ch = fname[0]; if (ch != '.'){ board[nb].k = 0; strcpy(board[nb].bname, fname); sprintf(fpath, "%s/.DIR", fname); mandex(0, "", fpath); printf("%-14sd: %d\tf: %d\n", fname, ndir, nfile); /* report */ board[nb].ndir = ndir; board[nb].nfile = nfile; if (board[nb].k) nb++; } } closedir(dirp); qsort(board, nb, sizeof(boardinfo), k_cmp); if (!(fndx = fopen(BBSHOME "/etc/topboardman", "w"))) exit(0); fprintf(fndx, "排名 看 版 目錄數 檔案數" " byte數  總 分 版 主 \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 | BRD_HIDE))) continue; if (board[ch].ndir + board[ch].nfile < 5) break; fprintf(fndx, "%3d.%15s %5d %7d %10d %6d %-24.24s\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); exit(0); }