summaryrefslogblamecommitdiffstats
path: root/util/mandex.c
blob: 9373f8140897567bfd3c69395aa92e74b303bb15 (plain) (tree)






































































































































































































































































                                                                                                          
/* $Id: mandex.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */

/*
  target : 精華區索引程式 (man index)
  
  syntax : mandex [board]
  [board] 有值 ==> 只跑該 board
  空的 ==> 所有的 boards 都跑
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#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);
}