summaryrefslogtreecommitdiffstats
path: root/util/mandex.c
diff options
context:
space:
mode:
authorwens <wens@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-08-05 14:35:19 +0800
committerwens <wens@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-08-05 14:35:19 +0800
commitacc64c7026616cd9b811a5e6f0aa3818bcbc2704 (patch)
tree8d89db899d1ef3f8d60c848cc20eb912d551e6a8 /util/mandex.c
parent7841c7805eecd66410e223336ee4fd557f67a126 (diff)
downloadpttbbs-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
Diffstat (limited to 'util/mandex.c')
-rw-r--r--util/mandex.c443
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] = {"", "", "", ""};
-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] = {"", "", "", ""};
+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, "序號\t\t\t精華區主題\n"
- "───────────────────"
- "───────────────────\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 \n",
- 11 * level, num_header, color[level % 4], ++count, fhdr.title);
+ snprintf(buf, sizeof(buf), "%.*s%s%3d. %s \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, "序號\t\t\t精華區主題\n"
+ "───────────────────"
+ "───────────────────\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, "排名 看 板 目錄數 檔案數"
+ " byte數  總 分 板 主 \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.%15s %5d %7d %10d %6d %-24.24s\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, "排名 看 板 目錄數 檔案數"
- " 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)))
- continue;
- /* 板主設定不列入記錄 */
- if (bptr->brdattr & BRD_HIDE && !(bptr->brdattr & BRD_BMCOUNT))
- 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);
return 0;
}