<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!/usr/bin/perl -w
#----------------------------------------------------------------------------------------
# /usr/bin/fix-maildir-date.pl - fix the message access and modification date and also
#                                the name of a message, based on the date header.
#
# Copyright (c) 2018-2020  Lilo von Hanffstengel, info(at)gwendragon(dot)de
# Copyright (c) 2020-2025  The Eisfair Team, team(at)eisfair(dot)org
#
# Creation:     2020-07-13  jed
# Last Update:  $Id$
#
# Usage:        fix-maildir-date.pl [FILENAME] [FILENAME...] [-h] [-?]
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#----------------------------------------------------------------------------------------
# This script was inspired by the maildate2ftime script, which has been published
# by Lilo von Hanffstengel (info(at)gwendragon(dot)de) on her website. It has been
# enhanced by a rename function of the file name, which usually contains the date
# at the beginning of its name.
#
# Example: '121122228.M7X7.example.org,S=59554,W=52424:2,Sa'
#           ^^^^^^^^^- date stamp
#
# Source: https://labs.gwendragon.de/blog/Web/Server/mail-dateien-timestamp-wert-date-header-setzen
#----------------------------------------------------------------------------------------

use strict;
use warnings;
use Mail::Header;
use HTTP::Date;
use File::Basename;
use File::Copy qw(move);

# disable output buffering for debug purposes
# use IO::Handle;
# STDOUT-&gt;autoflush(1);
# STDERR-&gt;autoflush(1);

#----------------------------------------------------------------------------------------
# show help
#----------------------------------------------------------------------------------------
if ( !@ARGV or grep /\-[?h]/, @ARGV ) {
    print "fix-maildir-date.pl [FILENAME] [FILENAME...] [-h] [-?]

  This program is used to repair broken 'Received' dates of mails in
  maildir format. It sets a file's timestamp (access and modification
  date/time) to the timestamp of the Date header of the mail.
  Additionally it renames the file name itself based on that date.

  Examples:

  fix-maildir-date.pl '121122228.M7X7.example.org,S=59554,W=52424:2,Sa'
      Sets for Maildir file '121122228.M7X7.example.org,S=59554,W=52424:2,Sa'
      the timestamp to Date header value of the mail.

  fix-maildir-date.pl [-h|-?]  - Shows this help

";
    exit;
}

#========================================================================================
# main
#========================================================================================

for my $filename_org (@ARGV) {
    my $filename_tmp;
    my $filename_time;
    my $filename_rest;
    my $filename_new;
    my $header;
    my $date;
    my $time;
    my $dirname;
    my $len;
    my $pos;

    print "processing file '$filename_org' ...\n";

    if (-e $filename_org) {
        if ( open my $FH, '&lt;', $filename_org ) {
            $header = Mail::Header-&gt;new( \*$FH );
            $date   = $header-&gt;get('date');

            # if the date contains a round bracket use only
            # the left part for the date/time.
            #    'Sun, 30 Apr 2000 19:44:30 +0200 (GMT+02:00)'
            # -&gt; 'Sun, 30 Apr 2000 19:44:30 +0200'
            $date   = substr( $date, 0, index( $date, "(" ) );
          # print "DATE:$date\n"; 

            if ($date) {
                # read Date from email header
                $time = str2time($date);
              # print "TIME:$time\n";

                utime( $time, $time, $filename_org )
                    and warn "- touched successfully.\n"
                    or warn "- couldn't be touched: $!\n";
            }
            else {
                warn "- Date: header couldn't be fetched\n";
            }
        }
        else {
            warn "- file couldn't be opened: $!\n";
        }
    }
    else {
        warn "- file doesn't exist: $!\n";
    }

    if ($time) {
        # time read from Date header, get directory and file name
        $dirname      = dirname( $filename_org );
        $filename_tmp = basename( $filename_org );

        # '121122228.M7X7.example.org,S=59554,W=52424:2,Sa'
        # -&gt; $filename_time = '121122228'
        # -&gt; $filename_rest = 'M7X7.example.org,S=59554,W=52424:2,Sa'
        $len = length( $filename_tmp );
        $pos = index( $filename_tmp, "." );

        $filename_time = substr( $filename_tmp, 0, $pos );
        $filename_rest = substr( $filename_tmp, $pos + 1, $len - $pos - 1 );

        # check if file stamps differ
        if ( "$time" != "$filename_time" ) {
            # time stamps differ, rename file ...
            $filename_new = "$dirname/$time.$filename_rest";

            move "$filename_org", "$filename_new"
                and warn "- renamed successfully to '$filename_new'.\n"
                or warn "- couldn't be renamed: $!\n";
        }
    }
}

#========================================================================================
# End
#========================================================================================
</pre></body></html>