/* ======================================= RAR 文件读取 ======================================= */ CR_API sFMT_PRT* load_rar ( __CR_IO__ iDATIN* datin, __CR_IN__ const sLOADER* param ) { HANDLE rar; sARRAY list; int32u attr; sint_t retc; leng_t fpos; iPAK_RAR* port; sFMT_PRT* rett; sPAK_RAR_FILE temp; RARHeaderDataEx info; RAROpenArchiveDataEx open; /* 只支持磁盘文件 */ if (param->type != CR_LDR_ANSI && param->type != CR_LDR_WIDE) return (NULL); /* 列表模式打开 RAR 文件 */ struct_zero(&open, RAROpenArchiveDataEx); if (param->type == CR_LDR_ANSI) open.ArcName = (ansi_t*)param->name.ansi; else open.ArcNameW = (wide_t*)param->name.wide; open.OpenMode = RAR_OM_LIST; rar = RAROpenArchiveEx(&open); if (rar == NULL) return (NULL); if (param->aprm != NULL && *(byte_t*)param->aprm != 0x00) { RARSetPassword(rar, (ansi_t*)param->aprm); attr = PAK_FILE_ENC; } else { attr = 0; } /* 开始逐个文件读取信息并定位 */ array_initT(&list, sPAK_RAR_FILE); list.free = rar_free; struct_zero(&info, RARHeaderDataEx); for (fpos = 0; ; fpos++) { /* 读取一个文件记录头 */ retc = RARReadHeaderEx(rar, &info); if (retc == ERAR_END_ARCHIVE) break; if (retc != ERAR_SUCCESS) goto _failure1; /* 目录文件不加入列表 */ if (info.Flags & RHDF_DIRECTORY) { retc = RARProcessFile(rar, RAR_SKIP, NULL, NULL); if (retc != ERAR_SUCCESS) goto _failure1; continue; } /* 文件名统一使用 UTF-8 编码 */ struct_zero(&temp, sPAK_RAR_FILE); temp.base.name = local_to_utf8(param->page, info.FileName); if (temp.base.name == NULL) goto _failure1; /* 设置公用文件属性 (偏移没有实际用处) */ temp.base.skip = sizeof(sPAK_RAR_FILE); temp.base.attr = attr; temp.base.offs = 0; temp.base.pack = mk_size(info.PackSizeHigh, info.PackSize); temp.base.size = mk_size(info.UnpSizeHigh, info.UnpSize); if (info.Method != 0x30) temp.base.attr |= PAK_FILE_CMP; if (info.Flags & RHDF_ENCRYPTED) temp.base.attr |= PAK_FILE_ENC; else temp.base.attr &= ~PAK_FILE_ENC; switch (info.Method) { case 0x30: temp.base.memo = "Storing"; break; case 0x31: temp.base.memo = "Fastest compression"; break; case 0x32: temp.base.memo = "Fast compression"; break; case 0x33: temp.base.memo = "Normal compression"; break; case 0x34: temp.base.memo = "Good compression"; break; case 0x35: temp.base.memo = "Best compression"; break; default: temp.base.memo = "Unknown compression"; break; } /* 设置私有文件属性 */ temp.id = fpos; temp.crc32 = (int32u)(info.FileCRC); temp.fattr = (int32u)(info.FileAttr); temp.ftime = (int16u)(info.FileTime & 0xFFFF); temp.fdate = (int16u)(info.FileTime >> 16); temp.htype = (int32u)(info.HashType); mem_cpy(temp.hash, info.Hash, sizeof(temp.hash)); /* 文件信息压入列表 */ if (array_push_growT(&list, sPAK_RAR_FILE, &temp) == NULL) { mem_free(temp.base.name); goto _failure1; } /* 跳过当前已读文件 */ retc = RARProcessFile(rar, RAR_SKIP, NULL, NULL); if (retc != ERAR_SUCCESS && retc != ERAR_BAD_DATA) goto _failure1; } /* 固定一下列表大小 */ if (!array_no_growT(&list, sPAK_RAR_FILE)) goto _failure1; /* 生成读包接口对象 */ port = struct_new(iPAK_RAR); if (port == NULL) goto _failure1; /* 保存需要用到的参数 */ port->m_temp = NULL; if (attr == 0) { port->m_pass = NULL; } else { port->m_pass = str_dupA((ansi_t*)param->aprm); if (port->m_pass == NULL) goto _failure2; } if (param->type == CR_LDR_ANSI) { port->m_wide = NULL; port->m_ansi = str_dupA(param->name.ansi); if (port->m_ansi == NULL) goto _failure3; } else { port->m_ansi = NULL; port->m_wide = str_dupW(param->name.wide); if (port->m_wide == NULL) goto _failure3; } port->m_rar = NULL; port->m_cur = (leng_t)-1; port->m_cnt = array_get_sizeT(&list, sPAK_RAR_FILE); port->pack.__filelst__ = array_get_dataT(&list, sPAK_FILE); port->pack.__vptr__ = &s_pack_vtbl; if (!pack_init_list((iPACKAGE*)port, TRUE)) goto _failure4; RARCloseArchive(rar); /* 返回读取的文件数据 */ rett = struct_new(sFMT_PRT); if (rett == NULL) { iPAK_RAR_release((iPACKAGE*)port); return (NULL); } CR_NOUSE(datin); rett->type = CR_FMTZ_PRT; rett->port = (iPORT*)port; rett->more = "iPACKAGE"; rett->infor = "Roshal ARchive (RAR)"; return (rett); _failure4: TRY_FREE(port->m_ansi); TRY_FREE(port->m_wide); _failure3: TRY_FREE(port->m_pass); _failure2: mem_free(port); _failure1: array_freeT(&list, sPAK_RAR_FILE); RARCloseArchive(rar); return (NULL); }
/* ======================================= TGL IPAC 文件读取 ======================================= */ CR_API sFMT_PRT* load_tgl_ipac ( __CR_IO__ iDATIN* datin, __CR_IN__ const sLOADER* param ) { int16u idx; int16u cnt; int32u offs; int32u size; sFMT_PRT* rett; sIPAC_HDR head; iPAK_IPAC* port; sPAK_FILE* list; ansi_t str[17]; /* 必须使用自己私有的读取接口 */ datin = create_file_inX(param); if (datin == NULL) return (NULL); /* 读取 & 检查头部 */ if (!(CR_VCALL(datin)->geType(datin, &head, sIPAC_HDR))) goto _failure1; if (head.magic != mk_tag4("IPAC")) goto _failure1; /* 分配子文件属性表 */ cnt = WORD_LE(head.count); if (cnt != 0) { list = mem_talloc(cnt, sPAK_FILE); if (list == NULL) goto _failure1; str[16] = CR_AC(NIL); mem_tzero(list, cnt, sPAK_FILE); } else { list = NULL; /* 支持空的包文件 */ } /* 加载文件信息表 */ for (idx = 0; idx < cnt; idx++) { /* 读取文件名不保证\0结尾 */ if (CR_VCALL(datin)->read(datin, str, 16) != 16) goto _failure2; /* 文件的包内偏移和大小 */ if (!CR_VCALL(datin)->getd_le(datin, &offs)) goto _failure2; if (!CR_VCALL(datin)->getd_le(datin, &size)) goto _failure2; /* 文件名统一使用 UTF-8 编码 */ list[idx].name = local_to_utf8(param->page, str); if (list[idx].name == NULL) goto _failure2; /* 设置公用文件属性 */ list[idx].skip = sizeof(sPAK_FILE); list[idx].attr = 0; list[idx].offs = offs; list[idx].pack = size; list[idx].size = size; list[idx].memo = "Store"; } /* 生成读包接口对象 */ port = struct_new(iPAK_IPAC); if (port == NULL) goto _failure2; port->m_cnt = cnt; port->m_file = datin; port->pack.__filelst__ = list; port->pack.__vptr__ = &s_pack_vtbl; if (!pack_init_list((iPACKAGE*)port, TRUE)) { mem_free(port); goto _failure2; } /* 返回读取的文件数据 */ rett = struct_new(sFMT_PRT); if (rett == NULL) { iPAK_IPAC_release((iPACKAGE*)port); return (NULL); } rett->type = CR_FMTZ_PRT; rett->port = (iPORT*)port; rett->more = "iPACKAGE"; rett->infor = "TGL IPAC Archive (IPAC)"; return (rett); _failure2: if (list != NULL) { for (cnt = 0; cnt < idx; cnt++) { TRY_FREE(list[cnt].find); mem_free(list[cnt].name); } mem_free(list); } _failure1: CR_VCALL(datin)->release(datin); return (NULL); }
static void apply_options(void) { char temp[BUFFER_SIZE], sname[BUFFER_SIZE]; char ustr[BUFFER_SIZE]; const char *home; FILE *f; # define DO_INPUT(str,iv) local_to_utf8(ustr, str, BUFFER_SIZE, 0);\ activesession=parse_input(str, iv, activesession); for (struct listnode *opt=options->next; opt; opt=opt->next) { switch (*opt->left) { case '#': *opt->left=tintin_char; activesession=parse_input(opt->left, true, activesession); break; case 'c': DO_INPUT(opt->right, false); break; case 'r': set_magic_hook(activesession); make_name(sname, opt->right); snprintf(temp, BUFFER_SIZE, "%crun %.*s {%s}", tintin_char, MAX_SESNAME_LENGTH, sname, opt->right); DO_INPUT(temp, true); break; case 's': set_magic_hook(activesession); make_name(sname, opt->right); snprintf(temp, BUFFER_SIZE, "%cses %.*s {%s %s}", tintin_char, MAX_SESNAME_LENGTH, sname, opt->right, opt->pr); DO_INPUT(temp, true); break; case 'S': set_magic_hook(activesession); make_name(sname, opt->right); snprintf(temp, BUFFER_SIZE, "%csslses %.*s {%s %s}", tintin_char, MAX_SESNAME_LENGTH, sname, opt->right, opt->pr); DO_INPUT(temp, true); break; case ' ': local_to_utf8(ustr, opt->right, BUFFER_SIZE, 0); if ((f=fopen(opt->right, "r"))) { if (activesession->verbose || !real_quiet) tintin_printf(0, "#READING {%s}", ustr); activesession = do_read(f, ustr, activesession); } else tintin_eprintf(0, "#FILE NOT FOUND: {%s}", ustr); break; case '-': if (!strcmp(DEFAULT_FILE_DIR, "HOME")) if ((home = getenv("HOME"))) strcpy(temp, home); else *temp = '\0'; else strcpy(temp, DEFAULT_FILE_DIR); strcat(temp, "/.tintinrc"); local_to_utf8(ustr, temp, BUFFER_SIZE, 0); if ((f=fopen(temp, "r"))) activesession = do_read(f, ustr, activesession); else if ((home = getenv("HOME"))) { strcpy(temp, home); strcat(temp, "/.tintinrc"); local_to_utf8(ustr, temp, BUFFER_SIZE, 0); if ((f=fopen(temp, "r"))) activesession = do_read(f, ustr, activesession); } } } kill_list(options); }