Git/Makefile: Ignore gpstools/, segfault on Linux Mint 19
[sunny256-utils.git] / dostime
blob164a86a8c7ab23b15328858e98263aea8dd42e01
1 #!/usr/bin/env perl
3 #=======================================================================
4 # dostime
5 # File ID: 0b7a06a0-2e6a-11e4-a319-c80aa9e67bbd
7 # Change file modification time from odd to even seconds because some
8 # file systems are too damn stupid to cope with them. Used to get rid of
9 # differences between timestamps of files in *NIX filesystems and DOSish
10 # ones.
12 # Character set: UTF-8
13 # ©opyleft 2014– Øyvind A. Holm <sunny@sunbase.org>
14 # License: GNU General Public License version 2 or later, see end of
15 # file for legal stuff.
16 #=======================================================================
18 use strict;
19 use warnings;
20 use Getopt::Long;
22 local $| = 1;
24 our %Opt = (
26 'dry-run' => 0,
27 'help' => 0,
28 'quiet' => 0,
29 'verbose' => 0,
30 'version' => 0,
31 'zero' => 0,
35 our $progname = $0;
36 $progname =~ s/^.*\/(.*?)$/$1/;
37 our $VERSION = '0.1.1';
39 Getopt::Long::Configure('bundling');
40 GetOptions(
42 'dry-run|n' => \$Opt{'dry-run'},
43 'help|h' => \$Opt{'help'},
44 'quiet|q+' => \$Opt{'quiet'},
45 'verbose|v+' => \$Opt{'verbose'},
46 'version' => \$Opt{'version'},
47 'zero|z' => \$Opt{'zero'},
49 ) || die("$progname: Option error. Use -h for help.\n");
51 $Opt{'verbose'} -= $Opt{'quiet'};
52 $Opt{'help'} && usage(0);
53 if ($Opt{'version'}) {
54 print_version();
55 exit(0);
58 exit(main());
60 sub main {
61 # {{{
62 my $Retval = 0;
64 $Opt{'zero'} && ($/ = "\x00");
66 for my $curr (@ARGV) {
67 $Retval |= process_file($curr);
69 if (!-t STDIN) {
70 while (my $curr = <STDIN>) {
71 chomp($curr);
72 $Retval |= process_file($curr);
76 return $Retval;
77 # }}}
78 } # main()
80 sub process_file {
81 # {{{
82 my $curr = shift;
84 if (-e $curr) {
85 my ($atime, $mtime) = (stat($curr))[8,9];
86 defined($mtime)
87 or (warn("$progname: $curr: Could not stat file: $!\n"), return 1);
88 my $origtime = $mtime;
90 $mtime = $mtime >> 1;
91 $mtime = $mtime << 1;
93 if (!$Opt{'dry-run'}) {
94 utime($atime, $mtime, $curr)
95 or (warn("$progname: $curr: Could not set file time: $!\n"), return 1);
97 $Opt{'verbose'} && printf("%s: %s: mtime changed from %s to %s%s\n",
98 $progname, $curr, sec_to_string($origtime), sec_to_string($mtime),
99 $Opt{'dry-run'} ? " (SIMULATING)" : "",
101 } else {
102 warn("$progname: $curr: File not found\n");
103 return 1;
106 return 0;
107 # }}}
108 } # process_file()
110 sub sec_to_string {
111 # Convert seconds since 1970 to "yyyymmddThhmmss[.frac]Z"
112 # {{{
113 my ($Seconds) = @_;
114 length($Seconds) || return(undef);
115 ($Seconds =~ /^-?(\d*)(\.\d+)?$/) || return(undef);
116 my $Secfrac = ($Seconds =~ /^([\-\d]*)(\.\d+)$/) ? 1.0*$2 : "";
117 $Secfrac =~ s/^0//;
119 my @TA = gmtime($Seconds);
120 my($DateString) = sprintf("%04u-%02u-%02uT%02u:%02u:%02u%sZ",
121 $TA[5]+1900, $TA[4]+1, $TA[3],
122 $TA[2], $TA[1], $TA[0], $Secfrac);
123 return($DateString);
124 # }}}
125 } # sec_to_string()
127 sub print_version {
128 # Print program version {{{
129 print("$progname $VERSION\n");
130 return;
131 # }}}
132 } # print_version()
134 sub usage {
135 # Send the help message to stdout {{{
136 my $Retval = shift;
138 if ($Opt{'verbose'}) {
139 print("\n");
140 print_version();
142 print(<<"END");
144 Usage: $progname [options] [file [files [...]]]
146 Change file modification time from odd to even seconds because some file
147 systems are too damn stupid to cope with them. Used to get rid of
148 differences between timestamps of files in *NIX filesystems and DOSish
149 ones. Files can be specified on the command line and/or be read from
150 stdin.
152 Options:
154 -h, --help
155 Show this help.
156 -n, --dry-run
157 Simulate what would be done, don't actually change the timestamps.
158 -q, --quiet
159 Be more quiet. Can be repeated to increase silence.
160 -v, --verbose
161 Increase level of verbosity. Can be repeated.
162 -z, --zero
163 Filenames from stdin are separated by zero (NULL) bytes.
164 --version
165 Print version information.
168 exit($Retval);
169 # }}}
170 } # usage()
172 sub msg {
173 # Print a status message to stderr based on verbosity level {{{
174 my ($verbose_level, $Txt) = @_;
176 if ($Opt{'verbose'} >= $verbose_level) {
177 print(STDERR "$progname: $Txt\n");
179 return;
180 # }}}
181 } # msg()
183 __END__
185 # This program is free software; you can redistribute it and/or modify
186 # it under the terms of the GNU General Public License as published by
187 # the Free Software Foundation; either version 2 of the License, or (at
188 # your option) any later version.
190 # This program is distributed in the hope that it will be useful, but
191 # WITHOUT ANY WARRANTY; without even the implied warranty of
192 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
193 # See the GNU General Public License for more details.
195 # You should have received a copy of the GNU General Public License
196 # along with this program.
197 # If not, see L<http://www.gnu.org/licenses/>.
199 # vim: set fenc=UTF-8 ft=perl fdm=marker ts=4 sw=4 sts=4 et fo+=w :