/* $Id$ */
/* tool to convert itoc bbs to ptt bbs */

#include "bbs.h"

typedef struct {
    time4_t chrono;
#ifdef FOR_WRETCH
    char pad[4]; // Use only for Wretch
#endif
    int xmode;
    int xid;
    char xname[32];               /* 檔案名稱 */
    char owner[80];               /* 作者 (E-mail address) */
    char nick[50];                /* 暱稱 */
    char date[9];                 /* [96/12/01] */
    char title[72];               /* 主題 (TTLEN + 1) */
    char score;
#ifdef FOR_WRETCH
    char pad2[4];
#endif
} itoc_HDR;

#define ITOC_POST_MARKED     0x00000002      /* marked */
#define ITOC_POST_BOTTOM1    0x00002000      /* 置底文章的正本 */

#define ITOC_GEM_RESTRICT    0x0800          /* 限制級精華區，須 manager 才能看 */
#define ITOC_GEM_RESERVED    0x1000          /* 限制級精華區，須 sysop 才能更改 */
#define ITOC_GEM_FOLDER      0x00010000      /* folder / article */
#define ITOC_GEM_BOARD       0x00020000      /* 看板精華區 */

static const char radix32[32] = {
    '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',
};

char *path;
int trans_man = 0;

int convert(char *fname, char *newpath)
{
    int fd;
    char *p;
    char buf[PATHLEN];
    itoc_HDR ihdr;
    fileheader_t fhdr;

    if (fname[0] == '.')
	snprintf(buf, sizeof(buf), "%s/%s", path, fname);
    else
	snprintf(buf, sizeof(buf), "%s/%c/%s", path, fname[7], fname);

    if ((fd = open(buf, O_RDONLY, 0)) == -1)
	return -1;

    while (read(fd, &ihdr, sizeof(ihdr)) == sizeof(ihdr)) {
	if (strcmp(ihdr.xname, "..") == 0 || strchr(ihdr.xname, '/'))
	    continue;

	if (!(ihdr.xmode & 0xffff0000)) {
	    /* article */
	    stampfile(newpath, &fhdr);

	    if (trans_man)
		strlcpy(fhdr.title, "◇ ", sizeof(fhdr.title));

	    if (ihdr.xname[0] == '@')
		snprintf(buf, sizeof(buf), "%s/@/%s", path, ihdr.xname);
	    else
		snprintf(buf, sizeof(buf), "%s/%c/%s", path, ihdr.xname[7], ihdr.xname);

	    fhdr.modified = dasht(buf);
	    if (ihdr.xmode & ITOC_POST_MARKED)
		fhdr.filemode |= FILE_MARKED;

	    copy_file(buf, newpath);
	}
	else if (ihdr.xmode & ITOC_GEM_FOLDER) {
	    /* folder */
	    if (!trans_man)
		continue;

	    stampdir(newpath, &fhdr);

	    if (trans_man)
		strlcpy(fhdr.title, "◆ ", sizeof(fhdr.title));

	    convert(ihdr.xname, newpath);
	}
	else {
	    /* ignore */
	    continue;
	}

	p = strrchr(newpath, '/');
	*p = '\0';

	if (ihdr.xmode & ITOC_GEM_RESTRICT)
	    fhdr.filemode |= FILE_BM;

	strlcat(fhdr.title, ihdr.title, sizeof(fhdr.title));
	strlcpy(fhdr.owner, ihdr.owner, sizeof(fhdr.owner));
	if (ihdr.date[0] && strlen(ihdr.date) == 8)
	    strlcpy(fhdr.date, ihdr.date + 3, sizeof(fhdr.date));
	else
	    strlcpy(fhdr.date, "     ", sizeof(fhdr.date));

	setadir(buf, newpath);
	append_record(buf, &fhdr, sizeof(fhdr));
    }

    close(fd);
    return 0;
}

int main(int argc, char *argv[])
{
    char buf[PATHLEN];
    char *board;
    int opt;

    while ((opt = getopt(argc, argv, "m")) != -1) {
	switch (opt) {
	    case 'm':
		trans_man = 1;
		break;
	    default:
		fprintf(stderr, "%s [-m] <path> <board>\n", argv[0]);
		fprintf(stderr, "  -m convert man (default is board)\n");
	}
    }

    if ((argc - optind + 1) < 2) {
	fprintf(stderr, "%s [-m] <path> <board>\n", argv[0]);
	fprintf(stderr, "  -m convert man (default is board)\n");
	return 0;
    }

    path = argv[optind];
    board = argv[optind+1];

    if (!dashd(path)) {
	fprintf(stderr, "%s is not directory\n", path);
	return 0;
    }

    attach_SHM();
    opt = getbnum(board);

    if (opt == 0) {
	fprintf(stderr, "ERR: board `%s' not found\n", board);
	return 0;
    }

    if (trans_man)
	setapath(buf, board);
    else
	setbpath(buf, board);

    if (!dashd(buf)) {
	fprintf(stderr, "%s is not directory\n", buf);
	return 0;
    }

    attach_SHM();

    convert(".DIR", buf);

    if (trans_man) {
	strlcat(buf, "/.rebuild", sizeof(buf));
	if ((opt = open(buf, O_CREAT, 0644)) > 0)
	    close(opt);
    }
    else
	touchbtotal(opt);

    return 0;
}
