forward cron mail to sysadmin@fsf.org
[mharc.git] / bin / mh-month-pack
CommitLineData
2ea8f66b
IK
1#!/usr/bin/perl
2##--------------------------------------------------------------------------##
3## File:
4## $Id: mh-month-pack,v 1.5 2002/10/11 23:52:28 ehood Exp $
5## Description:
6## See POD below or run program with -man option.
7##--------------------------------------------------------------------------##
8## Copyright (C) 2002 Earl Hood <earl@earlhood.com>
9##
10## This program is free software; you can redistribute it and/or modify
11## it under the terms of the GNU General Public License as published by
12## the Free Software Foundation; either version 2 of the License, or
13## (at your option) any later version.
14##
15## This program is distributed in the hope that it will be useful,
16## but WITHOUT ANY WARRANTY; without even the implied warranty of
17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18## GNU General Public License for more details.
19##
20## You should have received a copy of the GNU General Public License
21## along with this program; if not, write to the Free Software
22## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23## 02111-1307, USA
24##--------------------------------------------------------------------------##
25
26package MHArc::mh_month_pack;
27
28BEGIN { die qq/CGI use FORBIDDEN!\n/ if (defined($ENV{'GATEWAY_INTERFACE'})); }
29
30use Getopt::Long;
31
32use constant SCAN_FORMAT_STR =>
33 '%(msg) %<{x-mharc-packed}*%>%(year{date})-%02(mon{date})-%02(mday{date})';
34
35my $debug = 0;
36my $verbose = 0;
37my $noop = 0;
38my $noanno = 0;
39my $all = 0;
40
41my $outdir = '.';
42my $yearly = 0;
43
44MAIN: {
45 # Grap command-line options
46 GetOptions(
47 "all!" => \$all,
48 "debug!" => \$debug,
49 "n!" => \$noop,
50 "noanno!" => \$noanno,
51 "outdir=s" => \$outdir,
52 "verbose!" => \$verbose,
53 "yearly!" => \$yearly,
54
55 "help" => \$help,
56 "man" => \$man
57 ) || usage(0);
58 usage(1) if $help;
59 usage(2) if $man;
60
61 $verbose = 1 if $noop;
62 $verbose = 1 if $debug;
63
64 my @folders = @ARGV;
65 if (@folders <= 0) {
66 die qq/Error: No folders specified\n/;
67 }
68
69 # Trim in leading +'s specified
70 foreach (@folders) {
71 s/^\+//;
72 }
73
74 # Save off current folder
75 my $curfolder = `folder -fast`;
76 chomp $curfolder;
77 print qq/Current folder is "$curfolder"\n"/ if $verbose;
78
79 local(*SCAN);
80 my $folder;
81 foreach $folder (@folders) {
82 print qq/Processing folder "$folder"...\n/ if $verbose;
83
84 # Open read pipe to scan to get message number and date for each
85 # message.
86 if (!open(SCAN, qq/scan +$folder -format '/.SCAN_FORMAT_STR.qq/'|/)) {
87 warn qq/Warning: Non-zero exit status from "scan": $?\n/;
88 next;
89 }
90
91 my($msg, $date, $rest);
92 my($year, $mon, $day);
93 my($mbox, $packed);
94
95 # Read scan output and copy messages into mailbox files
96 while (<SCAN>) {
97 next unless /^\s*\d/;
98
99 print $_ if $debug;
100 chomp;
101
102 ($msg, $date, $rest) = split(' ', $_, 3);
103 $packed = $date =~ s/\*//;
104
105 if (!$all && $packed) {
106 print qq/Skipping message "$msg", already packed.\n/;
107 next;
108 }
109
110 $date += 1900 if $date < 1900; # just incase
111 ($year, $mon, $day) = split('-', $date, 3);
112
113 if ($yearly) {
114 $mbox = $year;
115 } else {
116 $mbox = "$year-$mon";
117 }
118
119 # Pre-create the mbox file if it does not exist: prevents
120 # packf from prompting to create.
121 if (! -e $mbox) {
122 run_cmd("touch $outdir/$mbox");
123 }
124
125 # Have packf actually append message to mailbox file.
126 if (run_cmd("packf -mbox -file $outdir/$mbox $msg")) {
127 warn qq/Warning: Non-zero exit status from "packf": $?\n/;
128 next;
129 }
130
131 # Annotate message that it has been processed.
132 if (!$noanno) {
133 if (run_cmd("anno -component x-mharc-packed -inplace -nodate ".
134 "-text '1' $msg")) {
135 warn qq/Warning: Non-zero exit status from "anno": $?\n/;
136 next;
137 }
138 }
139 }
140
141 close(SCAN);
142 }
143
144 # Restore current folder
145 run_cmd("folder +$curfolder");
146
147} # End: MAIN
148
149
150sub run_cmd {
151 if ($verbose) {
152 print @_, "\n";
153 }
154 return 0 if ($noop);
155 system(@_);
156}
157
158sub usage {
159 require Pod::Usage;
160 my $verbose = shift;
161 if ($verbose == 0) {
162 Pod::Usage::pod2usage(-verbose => $verbose);
163 } else {
164 my $pager = $ENV{'PAGER'} || 'more';
165 local(*PAGER);
166 my $fh = (-t STDOUT && open(PAGER, "|$pager")) ? \*PAGER : \*STDOUT;
167 Pod::Usage::pod2usage(-verbose => $verbose,
168 -output => $fh);
169 }
170}
171
172
173##--------------------------------------------------------------------------##
174__END__
175
176=head1 NAME
177
178mh-month-pack - Copy MH/nmh messages into monthly mailbox files.
179
180=head1 SYNOPSIS
181
182 mh-month-pack [options] folder ...
183
184=head1 DESCRIPTION
185
186This program copies MH/nmh messages into mailbox files. By default,
187monthly mailbox files are created with filenames of I<YYYY-MM> format.
188If the C<-yearly> option is specified, than messages will be split
189into yearly, I<YYYY>, files. If a mailbox file already exists,
190messages will be appended to it.
191
192Each MH/nmh process will be annotated inorder to mark the message as
193having been processed, unless the C<-noanno> option is specified.
194The annotation allows this program to reprocess folders multiple
195times and to skip messages that have been packed before.
196
197This program is provided as part of mharc to provide the ability
198to import MH/nmh messages into mharc archives. This program could
199be used for sites that have an existing MH/nmh filtering system
200inplace and want to usage mharc to generate web-based archives.
201This program can be used instead of L<filter-spool|filter-spool> to
202move incoming messages into the raw message archive before calling
203L<web-archive|web-archive>.
204
205=head1 OPTIONS
206
207Any non-option argument is treated as an MH/nmh folder to process.
208Folders are specified in the same manner as in MH/nmh commands.
209
210=over
211
212=item C<-all>
213
214Force packing of all messages, even if some messages are marked as
215processed.
216
217=item C<-debug>
218
219Like C<-verbose>, but prints out more.
220
221=item C<-help>
222
223Print out help message.
224
225=item C<-man>
226
227Print out the manpage.
228
229=item C<-n>
230
231Just echo what would be done, but do not do it. This is handy
232to verify what will be done before actually doing it for real.
233
234=item C<-noanno>
235
236Do not annotate messages that have been processed. By default, this
237program will annotate the messages via the anno(1) command to mark
238messages as being processed. Therefore, if the folder is processed
239again in the future, the message will be skipped.
240
241=item C<-outdir> I<directory>
242
243Directory to place mailbox files. If not specified, the
244current working directory is used.
245
246=item C<-verbose>
247
248Print status of what is going on.
249
250=item C<-yearly>
251
252Generate yearly-based mailbox files instead of monthly-based.
253
254=back
255
256=head1 DEPENDENCIES
257
258This program requires that the following MH/nmh commands are in
259your search path: C<anno(1)>, C<folder(1)>, C<scan(1)>, C<packf(1)>.
260
261=head1 LIMITATIONS
262
263=over
264
265=item *
266
267Pre-existing gzipped mailbox files are not recognized.
268
269=back
270
271=head1 VERSION
272
273$Id: mh-month-pack,v 1.5 2002/10/11 23:52:28 ehood Exp $
274
275=head1 AUTHOR
276
277Earl Hood, earl@earlhood.com
278
279This program is part of the mharc archiving system and comes with
280ABSOLUTELY NO WARRANTY and may be copied only under the terms of
281the GNU General Public License, which may be found in the mharc
282distribution.
283
284=cut
285