🔍 Code Extractor

function set_file_dates

Maturity: 51

Sets all file timestamps (creation time, modification time, access time, and change time) to a specified Unix timestamp by directly modifying the file's inode using debugfs.

File:
/tf/active/vicechatdev/mailsearch/fix_file_dates.py
Lines:
45 - 91
Complexity:
complex

Purpose

This function provides low-level timestamp manipulation for files on Linux ext filesystems. It bypasses normal filesystem APIs to set all four timestamp types (crtime, mtime, atime, ctime) simultaneously at the inode level, which is useful for forensic analysis, file restoration, or timestamp synchronization tasks where standard methods cannot modify all timestamps (particularly ctime and crtime).

Source Code

def set_file_dates(filepath, timestamp):
    """
    Set all file dates (birth/crtime, modified/mtime, accessed/atime, changed/ctime) to the specified timestamp.
    Uses debugfs to set all timestamps at the inode level.
    """
    # Convert timestamp to datetime
    dt = datetime.fromtimestamp(timestamp)
    
    # Convert to POSIX seconds and split into 32-bit lo/hi parts
    posix_seconds = int(timestamp)
    time_lo = posix_seconds & 0xFFFFFFFF  # Lower 32 bits
    time_hi = (posix_seconds >> 32) & 0xFFFFFFFF  # Higher 32 bits
    
    # Get the device that contains the file
    try:
        result = subprocess.run(
            ['df', '--output=source', filepath],
            capture_output=True,
            text=True,
            check=True
        )
        device = result.stdout.strip().split('\n')[1]
    except (subprocess.CalledProcessError, IndexError) as e:
        print(f"  ✗ Failed to get device: {e}")
        return False
    
    # Use debugfs to set all timestamp fields at inode level
    cmd = f"""debugfs -w {device} << EOF
set_inode_field "{filepath}" ctime_lo {time_lo}
set_inode_field "{filepath}" ctime_hi {time_hi}
set_inode_field "{filepath}" atime_lo {time_lo}
set_inode_field "{filepath}" atime_hi {time_hi}
set_inode_field "{filepath}" mtime_lo {time_lo}
set_inode_field "{filepath}" mtime_hi {time_hi}
set_inode_field "{filepath}" crtime_lo {time_lo}
set_inode_field "{filepath}" crtime_hi {time_hi}
quit
EOF
"""
    
    try:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, check=True)
        print(f"  ✓ Set all timestamps to {dt.strftime('%Y-%m-%d %H:%M:%S')}")
        return True
    except subprocess.CalledProcessError as e:
        print(f"  ✗ Failed to set timestamps: {e.stderr}")
        return False

Parameters

Name Type Default Kind
filepath - - positional_or_keyword
timestamp - - positional_or_keyword

Parameter Details

filepath: String or path-like object representing the absolute or relative path to the file whose timestamps should be modified. The file must exist on an ext2/ext3/ext4 filesystem.

timestamp: Unix timestamp (float or int) representing the desired date/time in seconds since epoch (January 1, 1970). This value will be applied to all four timestamp fields (ctime, atime, mtime, crtime).

Return Value

Returns a boolean value: True if all timestamps were successfully set, False if any error occurred (such as failure to determine the device, permission issues, or debugfs command failure). The function also prints status messages to stdout indicating success or failure.

Dependencies

  • subprocess
  • datetime
  • debugfs (system utility)
  • df (system utility)

Required Imports

from datetime import datetime
import subprocess

Usage Example

from datetime import datetime
import subprocess

def set_file_dates(filepath, timestamp):
    dt = datetime.fromtimestamp(timestamp)
    posix_seconds = int(timestamp)
    time_lo = posix_seconds & 0xFFFFFFFF
    time_hi = (posix_seconds >> 32) & 0xFFFFFFFF
    try:
        result = subprocess.run(['df', '--output=source', filepath], capture_output=True, text=True, check=True)
        device = result.stdout.strip().split('\n')[1]
    except (subprocess.CalledProcessError, IndexError) as e:
        print(f"  ✗ Failed to get device: {e}")
        return False
    cmd = f"""debugfs -w {device} << EOF
set_inode_field "{filepath}" ctime_lo {time_lo}
set_inode_field "{filepath}" ctime_hi {time_hi}
set_inode_field "{filepath}" atime_lo {time_lo}
set_inode_field "{filepath}" atime_hi {time_hi}
set_inode_field "{filepath}" mtime_lo {time_lo}
set_inode_field "{filepath}" mtime_hi {time_hi}
set_inode_field "{filepath}" crtime_lo {time_lo}
set_inode_field "{filepath}" crtime_hi {time_hi}
quit
EOF
"""
    try:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, check=True)
        print(f"  ✓ Set all timestamps to {dt.strftime('%Y-%m-%d %H:%M:%S')}")
        return True
    except subprocess.CalledProcessError as e:
        print(f"  ✗ Failed to set timestamps: {e.stderr}")
        return False

# Example usage (requires root privileges)
target_timestamp = datetime(2020, 1, 1, 12, 0, 0).timestamp()
success = set_file_dates('/path/to/file.txt', target_timestamp)

Best Practices

  • This function requires root/sudo privileges to execute debugfs with write access
  • Only works on ext2/ext3/ext4 filesystems - will fail on other filesystem types (NTFS, FAT32, Btrfs, etc.)
  • Always backup important data before modifying inode-level metadata
  • The function uses shell=True in subprocess.run which can be a security risk - ensure filepath is validated/sanitized
  • Timestamps are split into 32-bit lo/hi parts to support 64-bit timestamps on modern filesystems
  • The function prints status messages directly - consider capturing or redirecting output in production environments
  • Modifying ctime (change time) is normally impossible through standard APIs - this is one of the few ways to do it
  • Consider unmounting or remounting the filesystem after timestamp changes to ensure changes are fully committed
  • Error handling catches subprocess errors but may not catch all edge cases (e.g., invalid timestamp values)

Similar Components

AI-powered semantic similarity - components with related functionality:

  • function fix_file_dates 68.8% similar

    Normalizes all timestamp attributes (creation, modification, access) of a file to the oldest timestamp among them, with optional dry-run mode for preview.

    From: /tf/active/vicechatdev/mailsearch/fix_file_dates.py
  • function get_file_times 64.8% similar

    Retrieves all available timestamps for a file, including modification time, access time, change time, and birth time (creation time) when available.

    From: /tf/active/vicechatdev/mailsearch/fix_file_dates.py
  • function main_v112 57.6% similar

    Entry point function that parses command-line arguments to fix file timestamps by setting them to the oldest date found, either for a single file or recursively through a directory.

    From: /tf/active/vicechatdev/mailsearch/fix_file_dates.py
  • function copy_file_with_date 57.4% similar

    Copies a file from source to destination and sets the file's modification and access times to match a provided datetime object.

    From: /tf/active/vicechatdev/mailsearch/copy_signed_documents.py
  • function modify_test_document 48.5% similar

    Modifies the content of a test document file by writing new content to it, with a built-in delay to ensure the file's modification time changes.

    From: /tf/active/vicechatdev/docchat/test_incremental_indexing.py
← Back to Browse