//////////////////////////////// //~ Archive types #define TAR_ArchiveLookupTableCapacityFactor 2.0 Struct(TAR_Entry) { b32 valid; String file_name; String data; b32 is_dir; TAR_Entry *next; TAR_Entry *next_child; /* If entry is dir, points to first child. Otherwise points to next sibling. */ }; Struct(TAR_Archive) { Dict *lookup; TAR_Entry *head; }; extern Readonly TAR_Entry TAR_nil_entry; //////////////////////////////// //~ Header types typedef u8 TAR_FileKind; enum { TAR_FileKind_File = '0', TAR_FileKind_HardLink = '1', TAR_FileKind_SymLink = '2', TAR_FileKind_CharacterSpecial = '3', TAR_FileKind_BlockSpecial = '4', TAR_FileKind_Directory = '5', TAR_FileKind_Fifo = '6', TAR_FileKind_ContiguousFile = '7', TAR_FileKind_PaxHeaderG = 'g', TAR_FileKind_PaxHeaderX = 'x' }; Packed(Struct(TAR_Header) { /* Pre-posix */ u8 file_name[100]; u8 file_mode[8]; u8 owner_id[8]; u8 group_id[8]; u8 file_size[12]; u8 last_modified[12]; u8 checksum[8]; /* Both */ u8 file_type; u8 linked_file_name[100]; /* UStar */ u8 ustar_indicator[6]; u8 ustar_version[2]; u8 owner_user_name[32]; u8 owner_group_name[32]; u8 device_major_number[8]; u8 device_minor_number[8]; u8 file_name_prefix[155]; u8 padding[12]; }); //////////////////////////////// //~ Archive operations u64 TAR_U64FromOctString(String str); TAR_Archive TAR_ArchiveFromString(Arena *arena, String data, String prefix); TAR_Entry *TAR_EntryFromName(TAR_Archive *archive, String name);