// Detect It Easy: detection rule file
// Author: LinXP
// Status: WIP
// doc-ref: https://en.wikipedia.org/wiki/Ar_(Unix)
includeScript("archive-file");
meta("archive", "The archiver (.AR)");

function detect() {

    function ParseLibInfo() {
        sType = "format";
        sName = "COFF Library (.LIB)";

        var nMachineOffset = Binary.read_uint32(0x48, _BE) + 0x3C,
            nMachine;

        if (Binary.compare("0000FFFF", nMachineOffset)) {
            nMachine = Binary.read_uint16(nMachineOffset + 6);
        } // long format
        else {
            nMachine = Binary.read_uint16(nMachineOffset)
        } // short format
        switch (nMachine) {
            case 0x014c: sVersion = "I386"; break; // Intel 386 or later processors and compatible processors
            case 0x0162: sVersion = "R3000"; break; // MIPS little-endian, 0x160 big-endian
            case 0x01c0: sVersion = "ARM"; break; // ARM little-endian
            case 0x8664: sVersion = "AMD64"; break; // x64
            case 0xAA64: sVersion = "ARM64"; break; // ARM64 little-endian
            case 0x01c4: sVersion = "ARMNT"; break; // Arm Thumb-2 little-endian
            default: sVersion = "Unknown";
        }
    }

    if (Binary.compare("'!<arch>'0A")) {
        bDetected = true;
        var nOffset = 8;
        var nItemCount = 0;

        while (nOffset < Binary.getSize()) {
            sFileName = Binary.getString(nOffset, 0x10).trim();
            nOffset += 0x10;
            nOffset += 0x0C; // modification_timestamp
            nOffset += 0x06; // ownerID
            nOffset += 0x06; // groupID
            nOffset += 0x08; // fileMode
            nFileSize = parseInt(Binary.getString(nOffset, 0x0A));
            nOffset += 0x0A;
            nOffset += 0x02; // endMarker
            switch (sFileName) {
                case "/": ParseLibInfo(); break;
                case "debian-binary": ParseDebInfo(); break;
                case "/\/": break;
                default: Archive.add(nFileSize, nFileSize);
            }
            nOffset += nFileSize;
            if (nFileSize & 1) nOffset += 1; // padding
            nItemCount += 1;
        }

        if (Binary.isVerbose()) sOption(Archive.contents()); // TODO: parse DIR\FILES
    }

    function ParseDebInfo() {
        sName = "Debian Software package (.DEB)";
        sVersion = Binary.getString(nOffset, nFileSize - 1);
    }

    return result();
}