Beispiel #1
0
/*
=======================================
    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);
}
Beispiel #2
0
/*
=======================================
    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);
}
Beispiel #3
0
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);
}