#!/usr/bin/perl
$^W=1;
use strict;

use Time::Local;

# use UTC/Z/GMT0
$ENV{TZ}='GMT0';
# use C locale for time/date strings
$ENV{LC_ALL}='C';

# input line(s) of form:
# ^(Last-Modified: )?Dow, DD Mmm YYYY HH:HH:SS GMT file ...$
# if file(s) are given, set mtime to that given
# if file(s) don't exist, create them

my $rc=0; # my return code (exit value)

#sed -ne 's/^\(.*\) \(Last-Modified: [FMSTW][aehoru][deintu], [0-3][0-9] [ADFJMNOS][aceopu][bcglnprtvy] [0-9]\{4\} [012][0-9]:[0-5][0-9]:[0-6][0-9] GMT\)\{0,1\}$/\2 \1/p' info
#my $test_data=<<''
#
#;
#chomp($test_data);
#for (split(/\n/,$test_data,-1)){

while(<>){
	s/\r?\n$//o;
	if (
			/
				^
					(?:Last-Modified:\ )?
					(?:
						Sun|Mon|Tue|Wed|Thu|Fri|Sat
					),\ 
					(
						[012]\d |
						3[01]
					)\ 
					(
						Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec
					)\ 
					(
						19	(?:
								69 |
								[789]\d
							) |
						[2-9]\d{3}
					)\ 
					(?:
						([01]\d|2[0-3]):
						([0-5][0-9]):
						([0-5]\d|60)
					)\ 
						GMT
					[\ \t]+
					(.+)
				$
			/ox
	){
		my($DD,$Mmm,$YYYY,$HH,$mm,$SS,$files)=($1,$2,$3,$4,$5,$6,$7);
		my $MM;
		if		($Mmm eq 'Jan'){$MM='01';
		}elsif	($Mmm eq 'Feb'){$MM='02';
		}elsif	($Mmm eq 'Mar'){$MM='03';
		}elsif	($Mmm eq 'Apr'){$MM='04';
		}elsif	($Mmm eq 'May'){$MM='05';
		}elsif	($Mmm eq 'Jun'){$MM='06';
		}elsif	($Mmm eq 'Jul'){$MM='07';
		}elsif	($Mmm eq 'Aug'){$MM='08';
		}elsif	($Mmm eq 'Sep'){$MM='09';
		}elsif	($Mmm eq 'Oct'){$MM='10';
		}elsif	($Mmm eq 'Nov'){$MM='11';
		}elsif	($Mmm eq 'Dec'){$MM='12';
		}else{
			warn("$0: unexpected value for \$Mmm ($Mmm) on $_, skipping\n");
			$rc=1;
			next;
		};
		undef $Mmm;
		my @files=();
		{
			local $_=$files;
			@files=split;
		};
		if(! @files){
			warn("$0: no file(s) found on $_, skipping\n");
			$rc=1;
			next;
		};
		my $mtime = timegm($SS,$mm,$HH,$DD,$MM-1,$YYYY-1900);
#		{
#			my ($sec,$min,$hour,$mday,$mon,$year) = gmtime($mtime);
#			#print( $YYYY, $MM, $DD, $HH, $mm, '.', $SS, ' ', join(' ',('#' . ($#files + 1)),@files), ' ', $_, "\n" );
#			#print( $YYYY, $MM, $DD, $HH, $mm, '.', $SS, ' ', sprintf("%04d%02d%02d%02d%02d.%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec), "\n", );
#		};
		for my $file (@files){
			# we try to open read-only, to avoid race conditions
			# we try stat, to try to preserve atime
			# if we fail in those attempts, we try to create the file
			if(open(FH,'<',$file)){
				my $atime=(stat(FH))[8];
				if(!defined($atime)){
					warn("$0: failed to stat opened file $file: $!, skipping\n");
					$rc=1;
				}elsif(!utime($atime,$mtime,\*FH)){
					warn("$0: failed to set times on $file: $!, skipping\n");
					$rc=1;
				};
				close(FH);
			}else{
				my $atime=(stat($file))[8];
				if(open(FH,'>>',$file)){
					$atime=$mtime if !defined($atime);
					if(!utime($atime,$mtime,\*FH)){
						warn("$0: failed to set times on $file: $!, skipping\n");
						$rc=1;
					};
					close(FH);
				}elsif(!defined($atime)){
					warn("$0: failed to stat or open file $file: $!, skipping\n");
					$rc=1;
				}elsif(!utime($atime,$mtime,$file)){
					warn("$0: failed to set times on $file: $!, skipping\n");
					$rc=1;
				};
			};
		};
	}else{
		warn("$0: line failed to match: $_\n");
		$rc=1;
	};
};

exit($rc);
