ar_archive *ar_open_7z_archive(ar_stream *stream) { ar_archive *ar; ar_archive_7z *_7z; SRes res; if (!ar_seek(stream, 0, SEEK_SET)) return NULL; ar = ar_open_archive(stream, sizeof(ar_archive_7z), _7z_close, _7z_parse_entry, _7z_get_name, _7z_uncompress, NULL, 0); if (!ar) return NULL; _7z = (ar_archive_7z *)ar; CSeekStream_CreateVTable(&_7z->in_stream, stream); LookToRead_CreateVTable(&_7z->look_stream, False); _7z->look_stream.realStream = &_7z->in_stream.super; LookToRead_Init(&_7z->look_stream); #ifdef USE_7Z_CRC32 CrcGenerateTable(); #endif SzArEx_Init(&_7z->data); res = SzArEx_Open(&_7z->data, &_7z->look_stream.s, &gSzAlloc, &gSzAlloc); if (res != SZ_OK) { if (res != SZ_ERROR_NO_ARCHIVE) warn("Invalid 7z archive (failed with error %d)", res); free(ar); return NULL; } return ar; }
ar_archive *ar_open_rar_archive(ar_stream *stream) { char signature[7]; if (ar_read(stream, signature, sizeof(signature)) != sizeof(signature)) return NULL; if (memcmp(signature, "Rar!\x1A\x07\x00", 7) != 0) { if (memcmp(signature, "Rar!\x1A\x07\x01", 7) == 0) warn("RAR 5 format isn't supported"); else if (memcmp(signature, "RE~^", 4) == 0) warn("Ancient RAR format isn't supported"); else if (memcmp(signature, "MZ", 2) == 0 || memcmp(signature, "\x7F\x45LF", 4) == 0) warn("SFX archives aren't supported"); return NULL; } return ar_open_archive(stream, sizeof(ar_archive_rar), rar_close, rar_parse_entry, rar_get_name, rar_get_name_w, rar_uncompress); }
ar_archive *ar_open_tar_archive(ar_stream *stream) { ar_archive *ar; ar_archive_tar *tar; if (!ar_seek(stream, 0, SEEK_SET)) return NULL; ar = ar_open_archive(stream, sizeof(ar_archive_tar), tar_close, tar_parse_entry, tar_get_name, tar_uncompress, NULL, 0); if (!ar) return NULL; tar = (ar_archive_tar *)ar; if (!tar_parse_header(tar) || !tar->entry.checksum) { free(ar); return NULL; } return ar; }