summaryrefslogblamecommitdiffstats
path: root/util/mandex.c
blob: 8b073ea2e59356d8e26570eed2806f38b4f946ae (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                       
 
                         
 
                



                        
              

                   

                       
 















                                                                    

































                                                                                   
                




                                 
                          



                                                        

                                                               





                            
                                                     


                                                                            
                              






                                           

                                                                               
                         
                          
                   
                                                  







                                              
                







                                     
                                                        







                                                                               

                                          
                                  
                               







                                                                
                 










                                                         

                                
                        

                       
                                    
                                                        






                                                                       
 
                                                   



















                                                                   
                     

                    
                                            


                                       
     
 

                                                 
                    
                                                          

                             


                            













                                                                 







                                                           
    











                                                                   
                 












                                                                               
                 

             
                       
     
    






                                                                          
























                                                                               
             
 
/* $Id: mandex.c,v 1.4 2002/06/06 21:34:14 in2 Exp $ */

/* 'mandex -h' to help */

#include "bbs.h"
#ifndef MAXPATHLEN
#define MAXPATHLEN  1024
#endif

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;

int sortbyname(const void *a, const void *b)
{
    return strcmp(((boardinfo*)b)->bname, ((boardinfo*)a)->bname);
}

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.);
        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(fgem);
}


int main(int argc, char* argv[])
{
    boardheader_t *bptr;
    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', NULL};

    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;
    }
    }

    argc -= optind;
    argv += optind;

    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);
    return 0;
    }

    /* process all boards */
    if( checkrebuild &&
    (fd = open(BBSHOME "/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 )
        ;
    nSorted = nb;
    }
    else{
    memset(board, 0, sizeof(board));
    checkrebuild = 0;
    nSorted = nb = 0;
    }

    for( i = 0 ; dirs[i] != NULL ; ++i ){
    sprintf(topdir, BBSHOME "/man/boards/%c", dirs[i]);
    chdir(topdir);
    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 != '.'){
        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;
        }
        }
    }
    closedir(dirp);
    }
    
    qsort(board, nb, sizeof(boardinfo), k_cmp);
    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));       
    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 | 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);
    return 0;
}