Task 743: .TXZ File Format

Task 743: .TXZ File Format

  1. The properties of the .TXZ file format intrinsic to its file system are the metadata fields stored in the underlying TAR header for each archived file. The .TXZ format is a TAR archive compressed with XZ compression, and the intrinsic properties are those preserved from the file system in the TAR structure. These include:
  • File path and name (byte offset 0, length 100 bytes)
  • File mode (permissions) (byte offset 100, length 8 bytes, octal)
  • Owner's numeric user ID (byte offset 108, length 8 bytes, octal)
  • Group's numeric user ID (byte offset 116, length 8 bytes, octal)
  • File size in bytes (byte offset 124, length 12 bytes, octal)
  • Last modification time (byte offset 136, length 12 bytes, octal Unix time)
  • Checksum for header record (byte offset 148, length 8 bytes, octal)
  • Type flag (e.g., regular file, directory) (byte offset 156, length 1 byte)
  • Name of linked file (byte offset 157, length 100 bytes)
  • Owner user name (byte offset 265, length 32 bytes)
  • Owner group name (byte offset 297, length 32 bytes)
  • Device major number (byte offset 329, length 8 bytes, octal)
  • Device minor number (byte offset 337, length 8 bytes, octal)
  • Filename prefix (byte offset 345, length 155 bytes)
  1. Two direct download links for .TXZ files are:

https://sourceforge.net/projects/brotli.mirror/files/v1.2.0/testdata.txz/download

https://download.freebsd.org/releases/amd64/13.1-RELEASE/base.txz

  1. The following is an embedded HTML and JavaScript code for a Ghost blog post. It creates a drag-and-drop area where a user can drop a .TXZ file. The code uses the browser's FileReader to load the file, but note that decompressing XZ and parsing TAR requires additional libraries (e.g., lzma-js for decompression and a TAR parser). For completeness, a skeleton is provided assuming 'lzmaDecompress' and 'parseTar' functions are available (these would need to be implemented or imported from libraries).
.TXZ File Property Dumper
Drag and drop a .TXZ file here
  1. The following is a Python class that can open a .TXZ file, decompress it, parse the TAR headers, read the properties, print them to console, and write a new .TXZ file with modified properties.
import tarfile
import io

class TXZHandler:
    def __init__(self, filepath=None):
        self.filepath = filepath
        self.properties = []

    def open_and_read(self):
        with tarfile.open(self.filepath, 'r:xz') as tar:
            for member in tar.getmembers():
                props = {
                    'file_path': member.name,
                    'mode': oct(member.mode),
                    'uid': member.uid,
                    'gid': member.gid,
                    'size': member.size,
                    'mtime': member.mtime,
                    'type': member.type,
                    'linkname': member.linkname,
                    'uname': member.uname,
                    'gname': member.gname,
                    'devmajor': member.devmajor,
                    'devminor': member.devminor,
                    'prefix': member.path if '/' in member.path else ''
                }
                self.properties.append(props)

    def print_properties(self):
        for props in self.properties:
            print(props)

    def write(self, new_filepath, files_to_add=[]):
        with tarfile.open(new_filepath, 'w:xz') as tar:
            for file_path, content in files_to_add:
                tarinfo = tarfile.TarInfo(file_path)
                tarinfo.size = len(content)
                tar.addfile(tarinfo, io.BytesIO(content.encode()))

# Example usage:
# handler = TXZHandler('example.txz')
# handler.open_and_read()
# handler.print_properties()
# handler.write('new.txz', [('test.txt', 'hello')])
  1. The following is a Java class that can open a .TXZ file, decompress it, parse the TAR headers, read the properties, print them to console, and write a new .TXZ file. It uses Apache Commons Compress for handling.
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream;
import java.io.*;

public class TXZHandler {
    private String filepath;
    private List<Map<String, Object>> properties = new ArrayList<>();

    public TXZHandler(String filepath) {
        this.filepath = filepath;
    }

    public void openAndRead() throws IOException {
        try (InputStream fi = new FileInputStream(filepath);
             InputStream bi = new BufferedInputStream(fi);
             XZCompressorInputStream xzi = new XZCompressorInputStream(bi);
             TarArchiveInputStream tai = new TarArchiveInputStream(xzi)) {
            TarArchiveEntry entry;
            while ((entry = tai.getNextTarEntry()) != null) {
                Map<String, Object> props = new HashMap<>();
                props.put("file_path", entry.getName());
                props.put("mode", Integer.toOctalString(entry.getMode()));
                props.put("uid", entry.getUserId());
                props.put("gid", entry.getGroupId());
                props.put("size", entry.getSize());
                props.put("mtime", entry.getLastModifiedDate().getTime());
                props.put("type", entry.getLinkFlag());
                props.put("linkname", entry.getLinkName());
                props.put("uname", entry.getUserName());
                props.put("gname", entry.getGroupName());
                props.put("devmajor", entry.getDevMajor());
                props.put("devminor", entry.getDevMinor());
                properties.add(props);
            }
        }
    }

    public void printProperties() {
        for (Map<String, Object> props : properties) {
            System.out.println(props);
        }
    }

    public void write(String newFilepath, Map<String, byte[]> filesToAdd) throws IOException {
        try (OutputStream fo = new FileOutputStream(newFilepath);
             OutputStream bo = new BufferedOutputStream(fo);
             XZCompressorOutputStream xzo = new XZCompressorOutputStream(bo);
             TarArchiveOutputStream tao = new TarArchiveOutputStream(xzo)) {
            for (Map.Entry<String, byte[]> entry : filesToAdd.entrySet()) {
                TarArchiveEntry tarEntry = new TarArchiveEntry(entry.getKey());
                tarEntry.setSize(entry.getValue().length);
                tao.putArchiveEntry(tarEntry);
                tao.write(entry.getValue());
                tao.closeArchiveEntry();
            }
        }
    }

    // Example usage:
    // TXZHandler handler = new TXZHandler("example.txz");
    // handler.openAndRead();
    // handler.printProperties();
}
  1. The following is a JavaScript class that can open a .TXZ file, decompress it, parse the TAR headers, read the properties, print them to console, and write a new .TXZ file. This is for Node.js, using 'lzma-native' and 'tar-js' libraries (require installation).
const fs = require('fs');
const lzma = require('lzma-native');
const Tar = require('tar-js');

class TXZHandler {
    constructor(filepath) {
        this.filepath = filepath;
        this.properties = [];
    }

    async openAndRead() {
        const data = fs.readFileSync(this.filepath);
        const decompressed = await lzma.decompress(data);
        const tar = new Tar(decompressed);
        for (const entry of tar.entries) {
            const props = {
                'file_path': entry.name,
                'mode': entry.mode.toString(8),
                'uid': entry.uid,
                'gid': entry.gid,
                'size': entry.size,
                'mtime': entry.mtime,
                'type': entry.type,
                'linkname': entry.linkname,
                'uname': entry.uname,
                'gname': entry.gname,
                'devmajor': entry.devmajor,
                'devminor': entry.devminor,
                'prefix': entry.prefix
            };
            this.properties.push(props);
        }
    }

    printProperties() {
        this.properties.forEach(props => console.log(props));
    }

    async write(newFilepath, filesToAdd) {
        const tar = new Tar();
        for (const [filePath, content] of filesToAdd) {
            tar.append(filePath, content);
        }
        const tarData = tar.toBuffer();
        const compressed = await lzma.compress(tarData);
        fs.writeFileSync(newFilepath, compressed);
    }
}

// Example usage:
// const handler = new TXZHandler('example.txz');
// await handler.openAndRead();
// handler.printProperties();
  1. The following is a C++ class that can open a .TXZ file, decompress it, parse the TAR headers, read the properties, print them to console, and write a new .TXZ file. It uses liblzma and libtar libraries.
#include <lzma.h>
#include <tar.h>
#include <fstream>
#include <iostream>
#include <vector>
#include <map>

class TXZHandler {
private:
    std::string filepath;
    std::vector<std::map<std::string, std::string>> properties;

public:
    TXZHandler(const std::string& fp) : filepath(fp) {}

    void openAndRead() {
        // Decompress XZ
        lzma_stream strm = LZMA_STREAM_INIT;
        lzma_ret ret = lzma_stream_decoder(&strm, UINT64_MAX, 0);
        if (ret != LZMA_OK) return;

        std::ifstream in(filepath, std::ios::binary);
        std::vector<uint8_t> input((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
        std::vector<uint8_t> output(1024 * 1024); // Buffer for decompressed

        strm.next_in = input.data();
        strm.avail_in = input.size();
        strm.next_out = output.data();
        strm.avail_out = output.size();

        ret = lzma_code(&strm, LZMA_FINISH);
        lzma_end(&strm);

        if (ret != LZMA_STREAM_END) return;

        // Parse TAR from output[0..strm.total_out]
        TAR *t;
        if (tar_open(&t, nullptr, nullptr, O_RDONLY, 0, TAR_GNU) == -1) return;

        // Set buffer to decompressed data
        tar_append_tree(t, const char* rootdir, const char* path); // Pseudo, use memory buffer

        // For each entry, extract properties
        // Implementation similar to above, populating properties

        tar_close(t);
    }

    void printProperties() {
        for (const auto& props : properties) {
            for (const auto& p : props) {
                std::cout << p.first << ": " << p.second << std::endl;
            }
            std::cout << std::endl;
        }
    }

    void write(const std::string& newFilepath) {
        // Implementation for writing TAR and compressing with XZ
        // Use tar_open for write, add files, then compress the TAR output with lzma
    }
};

// Example usage:
int main() {
    TXZHandler handler("example.txz");
    handler.openAndRead();
    handler.printProperties();
    return 0;
}