--- minimalist-2.5.1.2.pl 2004-03-24 20:03:35.000000000 +0200 +++ minimalist.pl 2004-03-24 20:02:04.000000000 +0200 @@ -29,7 +29,7 @@ use Fcntl ':flock'; # LOCK_* constants use integer; -$version = '2.5(1.2) (Idleness)'; +$version = '2.5(1.4) (Idleness)'; $config = "/usr/local/etc/minimalist.conf"; # Program name and arguments for launching if commands in message's body @@ -300,14 +300,19 @@ $qfrom = quotemeta($from); # For use among with 'grep' function +# Look for user's supplied password +# in header (in form: '{pwd: blah-blah}' ) +while ($header =~ s/\{pwd:[ \t]*(\w+)\}//i) { + $userpwd = $1; } +# in body (for compatibility, may be will drop later) +# as very first '*password: blah-blah' in body of message +if (!$userpwd && $body =~ s/^\*password:[ \t]+(\w+)\n+//i) { + $userpwd = $1; } + # Get (multiline) subject if ($header =~ /(^|\n)subject:\s+(.*\n([ \t]+.*\n)*)/i) { $subject = $2; $subject =~ s/$spaces/$1/gs; } -# Get password if it's there and strip this line from message's body -if ($body =~ s/((^|\n)\*password:[ \t]+)(.*)\n+/$2/i) { - $userpwd = $3; } - $body =~ s/\n*$/\n/g; $body =~ s/\n\.\n/\n \.\n/g; # Single '.' treated as end of message @@ -379,8 +384,8 @@ chdir("$directory/$list"); read_config("config"); - # Check and remove X-Been-There - if ($header =~ s/(^|\n)x-been-there:\s+(.*)\n/$1/i) { + # Check and remove X-BeenThere + if ($header =~ s/(^|\n)x-beenthere:\s+(.*)\n/$1/i) { exit 0 if ($2 eq "$list\@$domain"); } if ($modify_subject ne 'no') { @@ -574,7 +579,7 @@ chomp ($header); $header .= "\nPrecedence: list\n"; # For vacation and similar programs - $header .= "X-Been-There: $list\@$domain\n"; + $header .= "X-BeenThere: $list\@$domain\n"; # Remove original Reply-To unconditionally, set configured one if it is $header =~ s/(^|\n)reply-to:\s+.*\n([ \t]+.*\n)*/$1/ig; @@ -775,12 +780,26 @@ if ($list =~ s/^(.*?)(-writers)$/$1/) { # -writers ? $suffix = $2; } - - if ( ($list ne '') && (! -d "$directory/$list") ) { + + %cmds = (cSub => 'subscribe', + cUnsub => 'unsubscribe', + cInfo => 'info', + cWho => 'who', + cSuspend => 'suspend', + cResume => 'resume', + cMaxsize => 'maxsize', + cMode => 'mode'); + + if (! grep(/^$cmd$/, %cmds)) { # Bad syntax or unknown instruction. + $msg =~ s/(^|\n)subject:\s+(.*\n([ \t]+.*\n)*)/$1/i; + $msg .= "Subject: ".$msgtxt{'27.0'.$language}."\n\n * $subject *\n".$msgtxt{'27'.$language}; + $global_exit_status = 10 if ($body_controlled); + } + elsif ( ($list ne '') && (! -d "$directory/$list") ) { $msg .= $msgtxt{'12'.$language}." \U$list\E ".$msgtxt{'13'.$language}. " minimalist\@$domain ".$msgtxt{'14'.$language}; } - elsif ( (($cmd eq 'subscribe') || ($cmd eq 'unsubscribe')) && ($list ne '') ) { + elsif ( ($cmd eq $cmds{cSub} || $cmd eq $cmds{cUnsub}) && ($list ne '') ) { chdir "$directory/$list"; read_config("config"); @@ -796,9 +815,9 @@ } elsif (($email ne '') && ($email ne $from)) { $msg .= $msgtxt{'15'.$language}; } - elsif (($cmd eq 'subscribe') && ($status & $CLOSED)) { + elsif (($cmd eq $cmds{cSub}) && ($status & $CLOSED)) { $msg .= $msgtxt{'16'.$language}.$owner; } - elsif (($cmd eq 'unsubscribe') && ($status & $MANDATORY)) { + elsif (($cmd eq $cmds{cUnsub}) && ($status & $MANDATORY)) { $msg .= $msgtxt{'17'.$language}.$owner; } else { if ($security ne 'paranoid') { @@ -809,7 +828,7 @@ } } # subscribe/unsubscribe - elsif ($cmd eq 'info') { + elsif ($cmd eq $cmds{cInfo}) { &logCommand($subject) if ($logfile ne 'none'); if ($list ne '') { $msg .= $msgtxt{'23'.$language}." \U$list\E\n\n"; @@ -825,7 +844,7 @@ } } - elsif (($cmd eq 'who') && ($list ne '')) { + elsif (($cmd eq $cmds{cWho}) && ($list ne '')) { chdir "$directory/$list"; read_config("config"); @@ -847,8 +866,8 @@ } # NOTE: $email here means value of maxsize - elsif ( ( ($cmd eq 'suspend' || $cmd eq 'resume') && $list) || - ($cmd eq 'maxsize') && $list && $email =~ /[0-9]+/ ) { + elsif ( ( ($cmd eq $cmds{cSuspend} || $cmd eq $cmds{cResume}) && $list) || + ($cmd eq $cmds{cMaxsize}) && $list && $email =~ /[0-9]+/ ) { chdir "$directory/$list"; read_config("config"); @@ -860,7 +879,7 @@ else { $msg = genAuthReport( genAuth($email) ); } } - elsif (($cmd eq 'mode') && $list && $email && + elsif (($cmd eq $cmds{cMode}) && $list && $email && ($usermode =~ s/^(reset|reader|writer|usual|suspend|resume|maxsize)\s*([0-9]+)?$/$1/i) ) { $cmdParams = $2; @@ -876,11 +895,6 @@ $msg .= $msgtxt{'44'.$language}; } } - - else { # Bad syntax or unknown instruction. - $msg .= $msgtxt{'27'.$language}; } - $global_exit_status = 10 if ($body_controlled); - } # Rest commands cleanAuth(); # Clean old authentication requests @@ -913,6 +927,8 @@ sub do_MIME_message { $footer = read_info("$directory/$list/footer"); + return if (! $footer); # If there isn't footer, do nothing + $encoding = '7bit'; $header =~ /(^|\n)Content-Type:[ \t]+(.*\n([ \t]+.*\n)*)/i; @@ -1773,13 +1789,17 @@ Note, that commands with , 'who' and 'mode' can only be used by administrators (users identified in the 'mailfrom' authentication scheme or who used a correct password - either global or local). Otherwise command will -be ignored. Password must be supplied in the first line of the message body -in the following format: +be ignored. Password must be supplied in any header of message as fragment of +the header in the following format: + +{pwd: list_password} + +For example: -*password: list_password +To: MML Discussion {pwd: password1235} -followed by any number of empty rows. This line, of course, will be removed -from the message before sending message to subscribers. +This fragment, of course, will be removed from the header before sending message +to subscribers. _EOF_ #------------------------------- @@ -1834,7 +1854,8 @@ #------------------------------- $msgtxt{'26en'} = "\nERROR:\n\tYou are not allowed to get listing of subscribed users."; #------------------------------- -$msgtxt{'27en'} = "\nERROR:\n\tBad syntax or unknown instruction.\n\nSOLUTION:\n\n".$msgtxt{'1en'}; +$msgtxt{'27.0en'} = "Bad syntax or unknown instruction"; +$msgtxt{'27en'} = "\nERROR:\n\t".$msgtxt{'27.0en'}.".\n\nSOLUTION:\n\n".$msgtxt{'1en'}; #------------------------------- $msgtxt{'28en'} = "Sincerely, the Minimalist"; #-------------------------------