Search code examples
linuxmacosfilesystemsfreebsdctime

Change ctime of file under FreeBSD UFS / MacOS X HFS


I'm searching for a way to create a file with an old ctime on different filesystems. On Linux ext, this is achieved by using

touch /path/to/file debugfs -w -R 'set_inode_field /path/to/file ctime 201001010101' /dev/sdX echo 3 > /proc/sys/vm/drop_caches

Is there any equivalent on FreeBSD's UFS ? And maybe even on MacOSX HFS+ ?


Solution

  • On FreeBSD, the touch command using the -f option may work for this, for example:

    touch -t 0510242022.13 file
    

    Will set date to 2005, November 24 at 20:22:13

    The format is [[CC]YY]MMDDhhmm[.SS], from the man touch:

       -t      Change the access and modification times to the specified time
                 instead of the current time of day.  The argument is of the form
                 ``[[CC]YY]MMDDhhmm[.SS]'' where each pair of letters represents
                 the following:
    
                       CC      The first two digits of the year (the century).
                       YY      The second two digits of the year.  If ``YY'' is
                               specified, but ``CC'' is not, a value for ``YY''
                               between 69 and 99 results in a ``CC'' value of 19.
                               Otherwise, a ``CC'' value of 20 is used.
                       MM      The month of the year, from 01 to 12.
                       DD      the day of the month, from 01 to 31.
                       hh      The hour of the day, from 00 to 23.
                       mm      The minute of the hour, from 00 to 59.
                       SS      The second of the minute, from 00 to 61.
    

    To change the ctime you could use fsdb, probably you will need to boot on single mode to have the disk in read only mode, example:

    > fsdb /dev/vtbd0p2
    ** /dev/vtbd0p2 (NO WRITE)
    Editing file system `/dev/vtbd0p2'
    Last Mounted on /
    current inode: directory
    I=2 MODE=40755 SIZE=1024
            BTIME=Sep 29 01:45:50 2016 [0 nsec]
            MTIME=Nov 26 09:47:37 2016 [339135000 nsec]
            CTIME=Nov 26 09:47:37 2016 [339135000 nsec]
            ATIME=Nov 26 09:28:38 2016 [679268000 nsec]
    OWNER=root GRP=wheel LINKCNT=20 FLAGS=0 BLKCNT=8 GEN=37b9b524
    fsdb (inum: 2)>
    

    From there I can cd to the directory and next select it:

    fsdb (inum: 2)> cd /usr/home/nbari
    

    And

    fsdb (inum: 644816)> lookup file
    

    You can type active to double check is the file, example:

    fsdb (inum: 642101)> active
    current inode: regular file
    I=642101 MODE=100644 SIZE=29
            BTIME=Oct 24 20:22:13 2005 [0 nsec]
            MTIME=Jan  1 12:12:12 2012 [0 nsec]
            CTIME=Jan  1 12:12:12 2012 [0 nsec]
            ATIME=Jan  1 12:12:12 2012 [0 nsec]
    OWNER=nbari GRP=nbari LINKCNT=1 FLAGS=0 BLKCNT=8 GEN=384445f7
    

    And later just change the ctime to you desired date:

     fsdb (inum: 642101)> ctime 20121212010101
    

    format is YYYYMMDDHHMMSS[.nsec]

    Then just exit by typing q or exit, to double check run stat, example:

    > stat -x test_file
      File: "test_file"
      Size: 29           FileType: Regular File
      Mode: (0644/-rw-r--r--)         Uid: ( 1002/   nbari)  Gid: ( 1002/   nbari)
    Device: 0,68   Inode: 642101    Links: 1
    Access: Sun Jan  1 12:12:12 2012
    Modify: Sun Jan  1 12:12:12 2012
    Change: Sun Jan  1 12:12:12 2012