archived.pl.in 9.43 KB
Newer Older
root's avatar
root committed
1
#!--PERL--
2
3
4
# -*- indent-tabs-mode: nil; -*-
# vim:ft=perl:et:sw=4
# $Id$
root's avatar
root committed
5

6
# Sympa - SYsteme de Multi-Postage Automatique
7
8
9
10
#
# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel
# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites
11
# Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017 GIP RENATER
12
13
# Copyright 2017, 2018, 2019, 2021 The Sympa Community. See the
# AUTHORS.md file at the top-level directory of this distribution and at
14
# <https://github.com/sympa-community/sympa.git>.
15
16
17
18
19
20
21
22
23
24
25
26
#
# 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 program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
27
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
root's avatar
root committed
28

29
use lib split(/:/, $ENV{SYMPALIB} || ''), '--modulesdir--';
30
use strict;
31
use warnings;
32
use English qw(-no_match_vars);
sikeda's avatar
sikeda committed
33
use Getopt::Long;
34
use Pod::Usage;
35
use POSIX qw();
root's avatar
root committed
36

37
use Conf;
sikeda's avatar
sikeda committed
38
use Sympa::Constants;
39
use Sympa::Crash;    # Show traceback.
40
use Sympa::DatabaseManager;
41
use Sympa::Language;
42
use Sympa::Log;
43
use Sympa::Process;
44
use Sympa::Spindle::ProcessArchive;
45
use Sympa::Spool::Listmaster;
46
47
48

my $process = Sympa::Process->instance;
$process->init(pidname => 'archived');
root's avatar
root committed
49

50
# Check options
51
my %options;
52
53
54
55
56
unless (
    GetOptions(
        \%main::options, 'config|f=s',  'debug|d', 'help|h',
        'foreground|F',  'log_level=s', 'version|v'
    )
Luc Didry's avatar
Luc Didry committed
57
) {
58
    pod2usage(-exitval => 1, -output => \*STDERR);
59
}
60
61
62
63
64
65
if ($main::options{'help'}) {
    pod2usage(0);
} elsif ($main::options{'version'}) {
    printf "Sympa %s\n", Sympa::Constants::VERSION;
    exit 0;
}
66
$Conf::sympa_config = $main::options{config};
67

salaun's avatar
salaun committed
68
if ($main::options{'debug'}) {
69
70
    $main::options{'log_level'} = 2 unless $main::options{'log_level'};
    $main::options{'foreground'} = 1;
salaun's avatar
salaun committed
71
}
72
73
74

my $log = Sympa::Log->instance;
$log->{'log_to_stderr'} = 'all' if $main::options{'foreground'};
75

root's avatar
root committed
76
# Load sympa.conf
77
unless (Conf::load()) {
78
    die sprintf
79
80
        "Unable to load sympa configuration, file %s has errors.\n",
        Conf::get_sympa_conf();
root's avatar
root committed
81
82
}

83
# Check database connectivity
84
unless (Sympa::DatabaseManager->instance) {
85
86
87
    die sprintf
        "Database %s defined in sympa.conf has not the right structure or is unreachable.\n",
        $Conf::Conf{'db_name'};
88
}
root's avatar
root committed
89

90
91
92
# Put ourselves in background if not in debug mode.
unless ($main::options{'foreground'}) {
    $process->daemonize;
root's avatar
root committed
93
94
}

95
96
97
98
99
# Create and write the PID file.
$process->write_pid(initial => 1);
# If process is running in foreground, don't write STDERR to a dedicated file.
unless ($main::options{foreground}) {
    $process->direct_stderr_to_file;
100
}
101

102
103
# setting log_level using conf unless it is set by calling option
if ($main::options{'log_level'}) {
104
105
    $log->{level} = $main::options{'log_level'};
    $log->syslog('info',
106
107
108
        "Configuration file read, log level set using options : $main::options{'log_level'}"
    );
} else {
109
110
    $log->{level} = $Conf::Conf{'log_level'};
    $log->syslog('info',
111
112
        "Configuration file read, default log level $Conf::Conf{'log_level'}"
    );
113
}
salaun's avatar
salaun committed
114

115
my $log_facility = $Conf::Conf{'log_facility'} || $Conf::Conf{'syslog'};
116
$log->openlog($log_facility, $Conf::Conf{'log_socket_type'});
117

118
## Set the User ID & Group ID for the process
119
120
$GID = $EGID = (getgrnam(Sympa::Constants::GROUP))[2];
$UID = $EUID = (getpwnam(Sympa::Constants::USER))[2];
121

122
## Required on FreeBSD to change ALL IDs(effective UID + real UID + saved UID)
sikeda's avatar
sikeda committed
123
124
POSIX::setuid((getpwnam(Sympa::Constants::USER))[2]);
POSIX::setgid((getgrnam(Sympa::Constants::GROUP))[2]);
125

126
## Check if the UID has correctly been set (useful on OS X)
127
128
unless (($GID == (getgrnam(Sympa::Constants::GROUP))[2])
    && ($UID == (getpwnam(Sympa::Constants::USER))[2])) {
129
130
    die
        "Failed to change process user ID and group ID. Note that on some OS Perl scripts can't change their real UID. In such circumstances Sympa should be run via sudo.\n";
131
132
}

root's avatar
root committed
133
## Sets the UMASK
sikeda's avatar
sikeda committed
134
umask(oct($Conf::Conf{'umask'}));
root's avatar
root committed
135

sikeda's avatar
sikeda committed
136
foreach my $robot (@{Conf::get_robots_list()}) {
137
    my $arc_dir = Conf::get_robot_conf($robot, 'arc_path');
138
139
140
141
    unless ($arc_dir) {
        die sprintf
            'Robot %s has no archives directory. Check arc_path parameter in this robot.conf and in sympa.conf',
            $robot;
142
    }
143
144
}

root's avatar
root committed
145
## Change to list root
sikeda's avatar
sikeda committed
146
unless (chdir($Conf::Conf{'home'})) {
147
    die sprintf 'Unable to change directory to %s: %s', $Conf::Conf{'home'},
148
        $!;
root's avatar
root committed
149
150
}

151
Sympa::Language->instance->set_lang($Conf::Conf{'lang'}, 'en');
salaun's avatar
salaun committed
152

153
$log->syslog('notice', 'Archived %s Started', Sympa::Constants::VERSION);
root's avatar
root committed
154

155
my $spindle = Sympa::Spindle::ProcessArchive->new;
156

157
# Catch signals, in order to exit cleanly, whenever possible.
root's avatar
root committed
158
$SIG{'TERM'} = 'sigterm';
159
$SIG{'INT'}  = 'sigterm';
160

161
162
163
164
165
166
while (not $spindle->{finish}) {
    $spindle->spin;
    last if $spindle->{finish};

    # Sleep for a while if archive spool is empty.
    sleep $Conf::Conf{'sleep'};
167
}
168

169
# Purge grouped notifications.
170
Sympa::Spool::Listmaster->instance->flush(purge => 1);
171

172
173
## Free zombie sendmail processes.
#Sympa::Process->instance->reap_child;
174

175
$log->syslog('notice', 'Archived exited normally due to signal');
176
$process->remove_pid(final => 1);
177

178
exit 0;
179

180
181
# When we catch signal, just change the value of the loop variable.
sub sigterm {
182
    my $sig = shift;
183
184
    $log->syslog('notice',
        'Signal %s received, still processing current task', $sig);
185
    $spindle->{finish} = $sig;
186
}
187

188
# Moved to Sympa::Spindle::ProcessArchive::_twist().
189
#sub process_message;
190

191
# Moved to Sympa::Spindle::ProcessArchive::_do_command().
192
#sub do_command;
193

sikeda's avatar
sikeda committed
194
# Moved to Sympa::Archive::html_remove().  Use do_remove_arc() instead.
195
196
#sub remove;

197
# Moved to Sympa::Spindle::ProcessArchive::_do_remove_arc().
198
#sub do_remove_arc;
root's avatar
root committed
199

sikeda's avatar
sikeda committed
200
# Moved to Sympa::Archive::html_rebuild().  Use do_rebuildarc() instead.
201
#sub rebuild;
202

203
# Moved to Sympa::Spindle::ProcessArchive::_do_rebuildarc().
204
#sub do_rebuildarc;
205

206
# Moved to Sympa::Spindle::ProcessArchive::_mail2arc().
207
#sub mail2arc;
root's avatar
root committed
208

209
210
# Moved to Sympa::Archive::_set_hidden_mode().
#sub set_hidden_mode;
root's avatar
root committed
211

212
213
# Moved to Sympa::Archive::_unset_hidden_mode().
#sub unset_hidden_mode;
root's avatar
root committed
214

215
216
# Moved to Sympa::Archive::_save_idx().
#sub save_idx;
217

218
219
# Moved to Sympa::Archive::_create_idx().
#sub create_idx;
220

221
222
223
# DEPRECATED.
# Use Sympa::Archive::_get_tag().
#sub get_tag;
224

225
# Checks if directory exists and we have write and read accec to it.
226
# DEPRECATED.  No longer used.
227
#sub directory_check;
228
229
230
231
232
233
234
235
236
237
238

__END__

=encoding utf-8

=head1 NAME

archived, archived.pl - Mailing List Archiving Daemon for Sympa

=head1 SYNOPSIS

239
C<archived.pl> S<[ C<--foreground> ]> S<[ C<--debug> ]>
240
241
242

=head1 DESCRIPTION

sikeda's avatar
sikeda committed
243
B<Archived> is a program which scan permanently the archive spool
244
245
246
247
248
249
250
251
252
253
254
255
256
and feeds the web archives, converting messages to the HTML format and
linking them. Original mails are also kept (in I<arctxt/> directory> for
later rebuilding of archives.

The HTML conversion is achieved by the means of the B<MHonArc> program.

Archives are accessed via B<wwsympa.fcgi> and B<sympa.pl>,
which proposes access control;
therefore archives should not be located in a public web directory.

=head1 OPTIONS

These programs follow the usual GNU command line syntax,
257
with long options starting with two dashes (C<-->).  A summary of
258
259
260
261
options is included below.

=over 5

262
=item C<-F>, C<--foreground>
263
264
265

Do not detach TTY.

266
=item C<-f>, C<--config=>I<file>
267
268
269
270

Force archived to use an alternative configuration file instead
of F<--CONFIG-->.

271
=item C<-d>, C<--debug>
272
273
274

Run the program in a debug mode.

275
=item C<-h>, C<--help>
276
277
278
279
280
281
282

Print this help message.

=back

=head1 FILES

283
F<$SPOOLDIR/outgoing/> outgoing Sympa directory.
284

285
286
287
288
289
290
291
292
293
294
F<$DEFAULTDIR/mhonarc_rc.tt2> template of MHonArc resource file.

=over

=item *

F<mhonarc-ressources.tt2> was replaced with F<mhonarc_rc.tt2>
on Sympa 6.2.61b.1.

=back
295
296
297

F<--CONFIG--> Sympa configuration file.

298
F<$PIDDIR/archived.pid> this file contains the process ID
299
300
301
302
of F<archived.pl>.

=head1 MORE DOCUMENTATION

IKEDA Soji's avatar
IKEDA Soji committed
303
304
The full documentation in HTML format can be found in
L<https://sympa-community.github.io/manual/>.
305
306

The mailing lists (with web archives) can be accessed at
IKEDA Soji's avatar
IKEDA Soji committed
307
L<https://listes.renater.fr/sympa/lists/informatique/sympa>.
308

sikeda's avatar
sikeda committed
309
310
311
=head1 HISTORY

This program was originally written by:
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328

=over 4

=item Serge Aumont

ComitE<233> RE<233>seau des UniversitE<233>s

=item Olivier SalaE<252>n

ComitE<233> RE<233>seau des UniversitE<233>s

=back

This manual page was initially written by
JE<233>rE<244>me Marant <jerome.marant@IDEALX.org>
for the Debian GNU/Linux system.

sikeda's avatar
sikeda committed
329
=head1 LICENSE
330
331

You may distribute this software under the terms of the GNU General
sikeda's avatar
sikeda committed
332
Public License Version 2.  For more details see F<README> file.
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts and no Back-Cover Texts.  A
copy of the license can be found under
L<http://www.gnu.org/licenses/fdl.html>.

=head1 BUGS

Report bugs to Sympa bug tracker.
See L<http://www.sympa.org/tracking>.

=head1 SEE ALSO

348
L<sympa_msg(8)>, L<bounced(8)>, L<mhonarc(1)>, L<sympa.conf(5)>.
349

350
L<Sympa::Spindle::ProcessArchive>.
351

352
=cut