Non-greedy matching for votestrings.
[usenet/usevote.git] / UVconfig.pm
1 # UVconfig: Reads config files and tests configuration
2 # Used by all components
3
4 package UVconfig;
5
6 use strict;
7 use Net::Domain qw(hostname hostfqdn hostdomain);
8 use UVmessage;
9 use vars qw(@ISA @EXPORT $VERSION $usevote_version %config %messages
10             @rules @groups $bdsg_regexp $bdsg2_regexp %ids %functions);
11
12 require Exporter;
13 @ISA = qw(Exporter);
14 @EXPORT = qw($usevote_version %config %messages @rules @groups
15              $bdsg_regexp $bdsg2_regexp %ids %functions);
16
17 # Module version
18 $VERSION = "0.18";
19
20 # Usevote version
21 $usevote_version = "UseVoteGer 4.12";
22
23 sub read_config {
24
25   my ($cfgfile, $redir_errors) = @_;
26   
27   # Default configuration options (overwritten in usevote.cfg)
28   %config = (votefile             => "votes",
29              votename             => "unkonfiguriertes Usevote",
30              sampleballotfile     => "ballot.sample",
31              resultfile           => "ergebnis.alle",
32              rulefile             => "usevote.rul",
33              badaddrfile          => "mailpatterns.cfg",
34              messagefile          => "messages.cfg",
35              idfile               => "scheinkennungen",
36              requestfile          => "anforderung",
37              errorfile            => "errors.log",
38              lockfile             => "usevote.lock",
39              replyto              => 0,
40              personal             => 0,
41              proportional         => 0,
42              bdsg                 => 0,
43              onestep              => 0,
44              multigroup           => 0,
45              voteack              => 1,
46              voteaccount          => "<> (unkonfiguriertes Usevote)",
47              mailfrom             => "<> (unkonfiguriertes Usevote)",
48              envelopefrom         => "<>",
49              mailboxtype          => "mbox",
50              mailstart            => "^From ",
51              archivedir           => "fertig",
52              tmpdir               => "tmp",
53              templatedir          => "templates",
54              formats              => "UVformats.pm",
55              domailfile           => "tmp/domail",
56              controlfile          => "tmp/ack.control",
57              mailcmd              => "sendmail -oi -oem",
58              mailcc               => "",
59              sleepcmd             => "sleep 1",
60              clearcmd             => "clear",
61              diff                 => "diff",
62              pager                => "less",
63              pop3                 => 0,
64              pop3server           => "localhost",
65              pop3port             => 110,
66              pop3user             => "default",
67              pop3pass             => "default",
68              pop3delete           => 0,
69              pop3uidlcache        => "uidlcache",
70              pop3server_req       => "localhost",
71              pop3port_req         => 110,
72              pop3user_req         => "default",
73              pop3pass_req         => "default",
74              pop3delete_req       => 0,
75              pop3uidlcache_req    => "uidlcache_req",
76              pop3server_bounce    => "localhost",
77              pop3port_bounce      => 110,
78              pop3user_bounce      => "default",
79              pop3pass_bounce      => "default",
80              pop3delete_bounce    => 0,
81              pop3uidlcache_bounce => 'uidlcache_bounce',
82              smtp                 => 0,
83              smtpserver           => 'localhost',
84              smtpport             => 25,
85              smtphelo             => hostfqdn(),
86              fqdn                 => hostfqdn(),
87              smtpauth             => 0,
88              smtpuser             => '',
89              smtppass             => '',
90              name_re              => '[a-zA-ZäöüÄÖÜß-]{2,} +.*[a-zA-ZäöüÄÖÜß]{2,}',
91              ja_stimme            => '(J\s*A|J|(D\s*A\s*)?F\s*U\s*E\s*R)',
92              nein_stimme          => '(N\s*E\s*I\s*N|N|(D\s*A\s*)?G\s*E\s*G\s*E\s*N)',
93              enth_stimme          => '(E|E\s*N\s*T\s*H\s*A\s*L\s*T\s*U\s*N\s*G)',
94              ann_stimme           => 'A\s*N\s*N\s*U\s*L\s*L\s*I\s*E\s*R\s*U\s*N\s*G',
95              bdsg_confirm         => 'JA',
96              condition1           => '$yes>=2*$no', # twice as many yes as no
97              condition2           => '$yes>=15',    # min 15 yes votes
98              prop_formula         => '$yes/$no',
99              tpl_ack_mail         => 'ack-mail',
100              tpl_bouncelist       => 'bouncelist',
101              tpl_mailheader       => 'mailheader',
102              tpl_result_multi     => 'result-multi',
103              tpl_result_single    => 'result-single',
104              tpl_result_prop      => 'result-proportional',
105              tpl_votes_multi      => 'votes-multi',
106              tpl_votes_single     => 'votes-single',
107              tpl_voterlist        => 'voterlist',
108              tpl_ballot           => 'ballot',
109              tpl_ballot_request   => 'ballot-request',
110              tpl_ballot_personal  => 'ballot-personal',
111              tpl_addr_reg         => 'address-not-registered',
112              tpl_no_ballotid      => 'no-ballotid',
113              tpl_wrong_ballotid   => 'wrong-ballotid',
114              tpl_bdsg_error       => 'bdsg-error',
115              tpl_cancelled        => 'cancelled',
116              tpl_invalid_account  => 'invalid-account',
117              tpl_invalid_name     => 'invalid-name',
118              tpl_multiple_votes   => 'multiple-votes',
119              tpl_no_ballot        => 'no-ballot',
120              tpl_no_votes         => 'no-votes',
121              tpl_rule_violated    => 'rule-violated',
122              begin_divider        => 'Alles vor dieser Zeile bitte loeschen',
123              end_divider          => 'Alles nach dieser Zeile bitte loeschen',
124              ballotintro          => 'WAHLSCHEIN fuer',
125              nametext             => 'Dein Realname, falls nicht im FROM-Header:',
126              nametext2            => 'Waehlername:',
127              addresstext          => 'Waehleradresse:',
128              ballotidtext         => 'Wahlscheinkennung:',
129              bdsgtext             => 'Datenschutzklausel - Zustimmung',
130              bdsgfile             => 'bdsgtext.cfg',
131              rightmargin          => 72,
132              usevote_version      => $usevote_version); # needed for use in templates
133
134   # read config
135   read_file($cfgfile);
136
137   # read message file
138   open (RES, "<$config{messagefile}")
139      or die "Could not read message file $config{messagefile}!\n\n";
140   my @lines = <RES>;
141   close(RES);
142
143   foreach my $line (@lines) {
144     chomp($line);
145     $line =~ s/^#.*//;        # Delete comments
146     if ($line =~ m/^\s*([A-Za-z0-9_-]+)\s*=\s*(.+)\s*$/){
147       $messages{$1} = $2;
148     }
149   } 
150
151   # missing "groupX =" lines in config file?
152   die UVmessage::get("CONF_NOGROUPS", CONFIGFILE=>$cfgfile) . "\n\n" unless (@groups);
153
154   # redirect errors to a file if desired by calling script
155   open (STDERR, ">$config{errorfile}") if ($redir_errors);
156
157   # check for data protection law? read text for ballot
158   parse_bdsgtext() if ($config{bdsg});
159
160   # personalized ballots? read ballot IDs
161   read_ballot_ids() if ($config{personal});
162
163   load_formats() if ($config{formats});
164  
165 }
166
167
168 ##############################################################################
169 # read config file                                                           #
170 ##############################################################################
171
172 sub read_file {
173
174   my $cfgfile = shift;
175   my $CONFIG;
176   open ($CONFIG, "<$cfgfile") or die "Could not find config file $cfgfile!\n\n";
177
178   while (<$CONFIG>) {
179     next if (/^#/);     # line is a comment
180     chomp;              # delete \n
181     s/\r//;             # delete \r if present
182     s/([^\\])#.*$/$1/;  # Remove comments not starting at beginning of line.
183                         # (ignore escaped comment sign \#)
184
185
186     if (/^include (\S+)$/) {
187       # include other config file
188       read_file($1);
189
190     } elsif (my($key, $value) = split (/\s*=\s*/, $_, 2)) {
191       # delete trailing spaces
192       $value =~ s/\s*$//;
193
194       # evaluate quotation marks
195       $value =~ s/^\"([^\"]+[^\\\"])\".*$/$1/;
196       $value =~ s/\\"/"/g;
197
198       if ($key =~ /^group(\d+)$/) {
199         my $num = $1;
200         $groups[$num-1] = $value;    # internal index starts at 0
201       } else {
202         $config{$key} = $value;
203       }
204     }
205   }
206
207   close ($CONFIG);
208
209 }
210
211
212 ##############################################################################
213 # parse data protection law texts                                            #
214 ##############################################################################
215
216 sub parse_bdsgtext {
217
218   open (BDSG, "<$config{bdsgfile}") or die UVmessage::get("CONF_NOBDSGFILE",
219                             ('BDSGFILE' => "$config{bdsgfile}")) . "\n\n";
220   my @bdsg = <BDSG>;
221   close BDSG;
222
223   $config{bdsginfo} = '';
224
225   foreach my $line (@bdsg) {
226     $config{bdsginfo} .= $line unless ($line =~ /^\s*#/);
227   }
228
229   my $bdsgtmp = $config{bdsginfo};
230   $bdsgtmp =~ s/\"/\\\"/g;
231   $bdsgtmp =~ s/\'/\\\'/g;
232   $bdsgtmp =~ s/\(/\\\(/g;
233   $bdsgtmp =~ s/\)/\\\)/g;
234   $bdsgtmp =~ s/\[/\\\[/g;
235   $bdsgtmp =~ s/\]/\\\]/g;
236   $bdsgtmp =~ s/\./\\\./g;
237   $bdsgtmp =~ s/\!/\\\!/g;
238   my @bdsgtext = split(' ', $bdsgtmp);
239
240   # Build Regular Expression from single words.
241   # There has to be at least a space between two words, additional characters
242   # are allowed, e.g. quotation marks (but no letters)
243   $bdsg_regexp = join('\s\W*?', @bdsgtext);
244
245   # Build Regular Expression from $config{bdsgtext}
246   $bdsg2_regexp = join('\s\W*?', split(' ', $config{bdsgtext}));
247 }
248   
249
250 ##############################################################################
251 # Read suspicious mail addresses (normally mailpatterns.cfg)                 #
252 ##############################################################################
253
254 sub read_badaddr {
255   
256   my @bad_addr = ();
257
258   open (BADADDR, "<$config{badaddrfile}") or die 
259     UVmessage::get("CONF_NOBADADDR",(BADADDRFILE => $config{badaddrfile})) . "\n\n";
260
261   while (<BADADDR>) {
262     chomp;
263     # Comment line? Not only whitespaces?
264     if (/^[^#]/ && /[^\s]/) {
265       push(@bad_addr, $_);
266     }
267   }
268
269   close (BADADDR);
270   return @bad_addr;
271 }
272
273
274 ##############################################################################
275 # Read ballot IDs                                                            #
276 ##############################################################################
277
278 sub read_ballot_ids {
279   # open file with ballot ids
280   open(FILE, "<$config{idfile}") or return 1;
281   while (<FILE>) {
282     chomp;
283     # Format: mailaddress (whitespace) ballot ID
284     if (/^(.+@.+)\s+([a-z0-9]+)/) {
285       # $1=mailadresse, $2=ballot ID
286       $ids{$1} = $2;
287     }
288   }
289   close(FILE);
290   return 0;
291 }
292
293
294 ##############################################################################
295 # Funktionen für Templates laden                                             #
296 ##############################################################################
297
298 sub load_formats {
299   my $modules = $config{formats};
300
301   my @modules = split(/\s*,\s*/, $modules);
302
303   foreach my $module (@modules){
304     if (-r $module){
305       require $module;
306     }
307   }
308 }
309
310
311 ##############################################################################
312 # config test                                                                #
313 ##############################################################################
314
315 sub test_config {
316   print UVmessage::get("CONF_CONFIG"), "\n\n";
317   foreach my $option (keys %config) {
318     print "$option = $config{$option}\n";
319   }
320
321   print "\n", UVmessage::get("CONF_TEST_RULES");
322   if (@rules) {
323     print "\n\n";
324     for (my $n=0; $n<@rules; $n++) {
325       my $text = UVrules::rule_print($n);
326       print $text;
327     }
328     print "\n";
329   } else {
330     print UVmessage::get("CONF_NO_RULES"), "\n\n";
331   }
332 }
333
334 1;
This page took 0.018617 seconds and 3 git commands to generate.