/* $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] \n", argv[0]); fprintf(stderr, " -m convert man (default is board)\n"); } } if ((argc - optind + 1) < 2) { fprintf(stderr, "%s [-m] \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, 0640)) > 0) close(opt); } else touchbtotal(opt); return 0; }