Thread: [Mailagent-svn] SF.net SVN: mailagent: [3] trunk/mailagent
Brought to you by:
rmanfredi
From: <rma...@us...> - 2008-01-17 10:03:21
|
Revision: 3 http://mailagent.svn.sourceforge.net/mailagent/?rev=3&view=rev Author: rmanfredi Date: 2008-01-17 01:58:33 -0800 (Thu, 17 Jan 2008) Log Message: ----------- Removed use of $* which is no longer supported by perl 5.10. Modified Paths: -------------- trunk/mailagent/agent/pl/actions.pl trunk/mailagent/agent/pl/analyze.pl trunk/mailagent/agent/pl/matching.pl trunk/mailagent/agent/pl/parse.pl trunk/mailagent/agent/pl/q.pl trunk/mailagent/agent/pl/read_conf.pl trunk/mailagent/bin/perload Modified: trunk/mailagent/agent/pl/actions.pl =================================================================== --- trunk/mailagent/agent/pl/actions.pl 2006-11-04 11:46:52 UTC (rev 2) +++ trunk/mailagent/agent/pl/actions.pl 2008-01-17 09:58:33 UTC (rev 3) @@ -863,6 +863,7 @@ /^Return-Receipt-To:/i || # Sendmail's acknowledgment /^Received:/i || # We want to remove received /^Precedence:/i || + /^X-Complaints-To:/i || # INN2 does not like this field /^Errors-To:/i # Error report redirection ) { $last_was_header = 1; # Mark we discarded the line @@ -1628,6 +1629,9 @@ &add_log("WARNING cannot chdir to $cf'home: $!") if $loglvl > 5; } + $script =~ s/^\s*~/$cf'home/; # ~ substitution + $script =~ s/\b~/$cf'home/g; # ~ substitution as first letter in word + # Set up the @ARGV array, by parsing the $script variable with &shellwords. # Note that the @ARGV array is held in the main package, but since the # mailagent makes no use of it at this point, there is no need to save its Modified: trunk/mailagent/agent/pl/analyze.pl =================================================================== --- trunk/mailagent/agent/pl/analyze.pl 2006-11-04 11:46:52 UTC (rev 2) +++ trunk/mailagent/agent/pl/analyze.pl 2008-01-17 09:58:33 UTC (rev 3) @@ -108,15 +108,12 @@ local(@filter) = split(/\n/, $header); # Look for each X-Filter local($address) = &email_addr; # Our e-mail address local($done) = 0; # Already processed ? - local($*) = 0; local($_); foreach (@filter) { # Maybe we'll find ourselves if (/mailagent.*for (\S+)/) { # Mark left by us ? $done = 1 if $1 eq $address; # Yes, we did that - $* = 1; # Remove that X-Filter line, LEAVE will add one anyway - $Header{'Head'} =~ s/^X-Filter:\s*mailagent.*for $address\n//; - $* = 0; + $Header{'Head'} =~ s/^X-Filter:\s*mailagent.*for $address\n//m; last; } } Modified: trunk/mailagent/agent/pl/matching.pl =================================================================== --- trunk/mailagent/agent/pl/matching.pl 2006-11-04 11:46:52 UTC (rev 2) +++ trunk/mailagent/agent/pl/matching.pl 2008-01-17 09:58:33 UTC (rev 3) @@ -363,15 +363,14 @@ } else { $buffer = $Header{$selector}; } - $* = 1; # Multi-line matching is attempted - @matched = eval '($buffer =~ ' . $pattern . ');'; + # Ensure multi-line matching by adding trailing "m" option to pattern + @matched = eval '($buffer =~ ' . $pattern . 'm);'; # If buffer is empty, we have to recheck the pattern in a non array context # to see if there is a match. Otherwise, /(.*)/ does not seem to match an # empty string as it returns an empty string in $matched[0]... - $matched[0] = eval '$buffer =~ ' . $pattern if $buffer eq ''; + $matched[0] = eval '$buffer =~ ' . $pattern . 'm' if $buffer eq ''; &eval_error; # Make sure eval worked &update_backref(*matched); # Record non-null backreferences - $* = 0; $matched[0]; # Return matching status } Modified: trunk/mailagent/agent/pl/parse.pl =================================================================== --- trunk/mailagent/agent/pl/parse.pl 2006-11-04 11:46:52 UTC (rev 2) +++ trunk/mailagent/agent/pl/parse.pl 2008-01-17 09:58:33 UTC (rev 3) @@ -232,12 +232,10 @@ # There is usually one Apparently-To line per address. Remove all new lines # in the header line and replace them with ','. Likewise for To: and Cc:. # although it is far less likely to occur. - local($*) = 1; foreach $field ('Apparently-To', 'To', 'Cc') { - $Header{$field} =~ s/\n/,/g; # Remove new-lines - $Header{$field} =~ s/,$/\n/; # Restore last new-line + $Header{$field} =~ s/\n/,/gm; # Remove new-lines + $Header{$field} =~ s/,$/\n/m; # Restore last new-line } - $* = 0; # If no To: field, then maybe there is an Apparently-To: instead. If so, # make them identical. Otherwise, assume the mail was directed to the user. Modified: trunk/mailagent/agent/pl/q.pl =================================================================== --- trunk/mailagent/agent/pl/q.pl 2006-11-04 11:46:52 UTC (rev 2) +++ trunk/mailagent/agent/pl/q.pl 2008-01-17 09:58:33 UTC (rev 3) @@ -15,8 +15,7 @@ # Quotation removal routine sub q { local($_) = @_; - local($*) = 1; - s/^://g; + s/^://gm; $_; } Modified: trunk/mailagent/agent/pl/read_conf.pl =================================================================== --- trunk/mailagent/agent/pl/read_conf.pl 2006-11-04 11:46:52 UTC (rev 2) +++ trunk/mailagent/agent/pl/read_conf.pl 2008-01-17 09:58:33 UTC (rev 3) @@ -111,13 +111,12 @@ if ($@ ne '') { # Parsing error detected local($error) = $@; # Logged error - local($*) = 1; $error = (split(/\n/, $error))[0]; # Keep only first line # Dump error message on stderr, as well as faulty configuration file. # The original is restored out of the perl form to avoid surprise. - $eval =~ s/^\$.* =~ s\|~\|.*\n//g; # Remove added ~ substitutions - $eval =~ s/^\$//g; # Remove leading '$' - $eval =~ s/ = "(.*)";/: $1/g; # Keep only variable value + $eval =~ s/^\$.* =~ s\|~\|.*\n//gm; # Remove added ~ substitutions + $eval =~ s/^\$//gm; # Remove leading '$' + $eval =~ s/ = "(.*)";/: $1/gm; # Keep only variable value chop($eval); print STDERR <<EOM; **** Syntax error in configuration: Modified: trunk/mailagent/bin/perload =================================================================== --- trunk/mailagent/bin/perload 2006-11-04 11:46:52 UTC (rev 2) +++ trunk/mailagent/bin/perload 2008-01-17 09:58:33 UTC (rev 3) @@ -273,8 +273,7 @@ : unless seek(main'DATA, $pos, 0); : local($/) = "\n}"; : local($body) = scalar(<main'DATA>); -: local($*) = 1; -: die "End of file found while loading $_[0].\n" unless $body =~ /^\}$/; +: die "End of file found while loading $_[0].\n" unless $body =~ /^\}$/m; EOC if ($opt_t) { print &q(<<'EOC'); @@ -460,8 +459,7 @@ sub q { local($_) = @_; - local($*) = 1; - s/^://g; + s/^://gm; $_; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-05-28 14:52:40
|
Revision: 9 http://mailagent.svn.sourceforge.net/mailagent/?rev=9&view=rev Author: rmanfredi Date: 2008-05-28 07:51:41 -0700 (Wed, 28 May 2008) Log Message: ----------- Look for utmp in /var/run as well, for modern systems with read-only /etc. Modified Paths: -------------- trunk/mailagent/Configure trunk/mailagent/U/utmp.U Modified: trunk/mailagent/Configure =================================================================== --- trunk/mailagent/Configure 2008-05-28 09:27:26 UTC (rev 8) +++ trunk/mailagent/Configure 2008-05-28 14:51:41 UTC (rev 9) @@ -18,7 +18,7 @@ # $Id: Head.U 6 2006-08-25 22:21:46Z rmanfredi $ # -# Generated on Wed May 28 11:04:29 CEST 2008 [metaconfig 3.5 PL0] +# Generated on Wed May 28 11:41:09 CEST 2008 [metaconfig 3.5 PL0] cat >c1$$ <<EOF ARGGGHHHH!!!!! @@ -6751,7 +6751,7 @@ : determines where the utmp file lies echo " " case "$utmp" in -'') dflt=`./loc utmp /etc/utmp /etc /var/adm /usr/etc`;; +'') dflt=`./loc utmp /etc/utmp /etc /var/adm /usr/etc /var/run`;; *) dflt="$utmp";; esac fn='l/:utmp' Modified: trunk/mailagent/U/utmp.U =================================================================== --- trunk/mailagent/U/utmp.U 2008-05-28 09:27:26 UTC (rev 8) +++ trunk/mailagent/U/utmp.U 2008-05-28 14:51:41 UTC (rev 9) @@ -13,12 +13,12 @@ ?MAKE: -pick add $@ %< ?S:utmp: ?S: The path of the utmp file where logins are recorded on the system. -?S: Typically something like '/etc/utmp' or '/var/adm/utmp'. +?S: Typically something like '/etc/utmp' or '/var/run/utmp'. ?S:. : determines where the utmp file lies echo " " case "$utmp" in -'') dflt=`./loc utmp /etc/utmp /etc /var/adm /usr/etc`;; +'') dflt=`./loc utmp /etc/utmp /etc /var/adm /usr/etc /var/run`;; *) dflt="$utmp";; esac fn='l/:utmp' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-05-28 15:10:15
|
Revision: 11 http://mailagent.svn.sourceforge.net/mailagent/?rev=11&view=rev Author: rmanfredi Date: 2008-05-28 08:10:12 -0700 (Wed, 28 May 2008) Log Message: ----------- Added -U switch to disable first UNIQUE / RECORD rejection for duplicates. Modified Paths: -------------- trunk/mailagent/MANIFEST trunk/mailagent/agent/magent.sh trunk/mailagent/agent/man/mailagent.SH trunk/mailagent/agent/pl/history.pl trunk/mailagent/agent/test/README trunk/mailagent/agent/test/TEST Added Paths: ----------- trunk/mailagent/agent/test/option/U.t Modified: trunk/mailagent/MANIFEST =================================================================== --- trunk/mailagent/MANIFEST 2008-05-28 15:00:47 UTC (rev 10) +++ trunk/mailagent/MANIFEST 2008-05-28 15:10:12 UTC (rev 11) @@ -273,6 +273,7 @@ agent/test/option/I.t Test -I option agent/test/option/L.t Test -L option agent/test/option/V.t Test -V option +agent/test/option/U.t Test -U option agent/test/option/c.t Test -c option agent/test/option/d.t Test -d option agent/test/option/e.t Test -e option Modified: trunk/mailagent/agent/magent.sh =================================================================== --- trunk/mailagent/agent/magent.sh 2008-05-28 15:00:47 UTC (rev 10) +++ trunk/mailagent/agent/magent.sh 2008-05-28 15:10:12 UTC (rev 11) @@ -241,6 +241,9 @@ print STDERR "$prog_name $mversion PL$patchlevel\n"; exit 0; } + elsif ($_ eq '-U') { # Do not allow UNIQUE to reject / abort + ++$disable_unique; + } elsif ($_ eq '-TEST') { # Mailagent run via TEST (undocumented feature) ++$test_mode; } @@ -411,7 +414,7 @@ # Print usage and exit sub usage { print STDERR <<EOF; -Usage: $prog_name [-dhilqtFIV] [-s{umaryt}] [-f file] [-e rules] [-c config] +Usage: $prog_name [-dhilqtFIVU] [-s{umaryt}] [-f file] [-e rules] [-c config] [-L level] [-r file] [-o def] [mailfile] -c : specify alternate configuration file. -d : dump filter rules (special). @@ -429,6 +432,7 @@ -I : install configuration and perform sanity checks. -L : force logging level. -V : print version number and exits. + -U : prevent UNIQUE from rejecting an already processed Message-ID. EOF exit 1; } Modified: trunk/mailagent/agent/man/mailagent.SH =================================================================== --- trunk/mailagent/agent/man/mailagent.SH 2008-05-28 15:00:47 UTC (rev 10) +++ trunk/mailagent/agent/man/mailagent.SH 2008-05-28 15:10:12 UTC (rev 11) @@ -166,7 +166,7 @@ .SH NAME mailagent \- an automatic mail-processing tool .SH SYNOPSIS -\fBmailagent\fR [ \fB\-dhilqtFIV\fR ] [ \fB\-s{umaryt}\fR ] +\fBmailagent\fR [ \fB\-dhilqtFIVU\fR ] [ \fB\-s{umaryt}\fR ] [ \fB\-f\fI file\fR ] [ \fB\-e\fI rule\fR ] [ \fB\-c\fI config\fR ] [ \fB\-L\fI loglevel\fR ] [ \fB\-r\fI rulefile\fR ] [ \fB\-o\fI override\fR ] [ \fImailfile\fR ] @@ -1035,7 +1035,9 @@ the special \fI_SEEN_\fR mode when it detects an \fIX-Filter:\fR line issued by itself, but this option will have it continue as usual (although vacation messages are disabled). Use this option when post-processing mail already -filtered. +filtered. Also look at the +.B \-U +switch if you are using the RECORD or UNIQUE actions in some rules. .TP .B \-h Print out a usage message on the standard error and exit. @@ -1105,6 +1107,16 @@ .TP .B \-V Print version number and exit. +.TP +.B \-U +Prevent the UNIQUE and RECORD commands from rejecting an already processed +Message-ID the first time they are run on a given message. +This is useful when processing messages that have been dropped in the +.I emergdir +directory due to some abnormal (but transient) condition and you wish to +reprocess the message. Also see the +.B \-F +switch if you are re-processing messages. .PP If you invoke mailagent without options and without any arguments, the program waits for a mail on its standard input. If an argument is provided, it Modified: trunk/mailagent/agent/pl/history.pl =================================================================== --- trunk/mailagent/agent/pl/history.pl 2008-05-28 15:00:47 UTC (rev 10) +++ trunk/mailagent/agent/pl/history.pl 2008-05-28 15:10:12 UTC (rev 11) @@ -94,7 +94,7 @@ if ($time > 0) { # Message already recorded local($tagmsg) = $tag eq '' ? '' : " ($tag)"; &add_log("history duplicate <$msg_id>" . $tagmsg) if $loglvl > 6; - $seen++; + $seen++ unless history_ignore($msg_id, $tag); } else { # Record message (appending) &dbr'update($host, 'HISTORY', 0, @regexp); } @@ -102,6 +102,27 @@ return $seen; # Return seen status } +# Look at whether we should ignore the duplicate if -U was given +# We ignore the first match for a given tag, so if one of the tags here +# was already recorded in %ignored_history_tag, we ignore the -U switch. +# The reason is that different paths in the rules could lead to a UNIQUE +# command that is meant to trap the fact the message was already seen... +# Return TRUE if we need to ignore the duplicate for this time +sub history_ignore { + my ($msg_id, $tag) = @_; + return 0 unless $disable_unique; # return unless -U given + if ($ignored_history_tag{$tag}++) { + # We already ignored once for this tag + add_log("not ignoring this duplicate <$msg_id>$tagmsg despite -U") + if $loglvl > 6; + return 0 + } + my $tagmsg = $tag eq '' ? '' : " ($tag)"; + add_log("ignoring duplicate <$msg_id>$tagmsg since you gave -U") + if $loglvl > 6; + return 1; # Ignore this duplicate +} + # Obsolete -- will be removed in next release sub history_record { &history_tag(); Modified: trunk/mailagent/agent/test/README =================================================================== --- trunk/mailagent/agent/test/README 2008-05-28 15:00:47 UTC (rev 10) +++ trunk/mailagent/agent/test/README 2008-05-28 15:10:12 UTC (rev 11) @@ -17,30 +17,48 @@ them. Running the whole test suite takes a long time. On my machine with 40 Mb of -main memory, it requires 12 minutes to complete. It may take a lot longer -if you do not have at least 16 Mb of RAM. +main memory, it requires 12 minutes to complete (in 1991). It may take a lot +longer if you do not have at least 16 Mb of RAM. +The following options are available to TEST: + + -i incremental, rerun only failed tests + -m monitor logfile with "atail" + -n use the non-dataloaded version + -o allow outdated mailagent / filter + -s stop at first error + The option -i turns the incremental mode on. This proved really nice to me when I was writing this suite, as I was able to skip all the successful -tests and focus only on those which failed or the new ones. The -s option will -cause the test suite to stop at the first error. Normally, only failed basic -tests abort the process. The -o option will not restart the tests from scratch, -even if the mailagent or filter is newer than the current OK file. Option -n -will test the non-dataloaded version of the mailagent (because of some bugs -with eval() which cause the dataloaded version to dump core via a segmentation -violation). +tests and focus only on those which failed or the new ones. +The -s option will cause the test suite to stop at the first error. Normally, +only failed basic tests abort the process. + +The -o option will not restart the tests from scratch, even if the mailagent +or filter is newer than the current OK file. + +Option -n will test the non-dataloaded version of the mailagent (because +of some bugs with eval() which cause the dataloaded version to dump core +via a segmentation violation). + The -m option is for desperate cases. It launches the atail process in the background (a real CPU hog) to monitor all changes to the out/agentlog file. This may be really convenient when debugging a test suite failure... -I don't know why I spent some time documenting all this, as I don't expect -anybody to have any chance working on this suite. Anyway, it might be nice -knowing that all the successful tests are recorded in an OK file, along -with the time stamp of the test, so we may re-run those which were updated -since last run. In the event the mailagent or the filter are modified, the -tests are re-run throughoutfully. +Specifying a list of files on the command line will only run these tests. +For instance: + ./TEST options/i.t + +I don't know why I spent some time documenting all this (in 1992), as I +don't expect anybody to have any chance working on this suite. Anyway, it +might be nice knowing that all the successful tests are recorded in an OK +file, along with the time stamp of the test, so we may re-run those which +were updated since last run. In the event the mailagent or the filter are +modified, the tests are re-run throughoutfully. NB: in 2008, I'm glad I +did document all that. :-) + The file 'level' is optional. If present, it gives the default logging level to be applied when most of the tests are run (i.e. for those who do not require any special logging level). If absent, no logging will be done (except for Modified: trunk/mailagent/agent/test/TEST =================================================================== --- trunk/mailagent/agent/test/TEST 2008-05-28 15:00:47 UTC (rev 10) +++ trunk/mailagent/agent/test/TEST 2008-05-28 15:10:12 UTC (rev 11) @@ -98,6 +98,17 @@ select(STDOUT); $| = 1; + +# If they specified a list of files, run them and do not update "OK" +# nor print any summary status. + +if (@ARGV) { + foreach my $file (@ARGV) { + run_file($file); + exit($failed ? 1 : 0) ; + } +} + open(OK, ">>OK"); select(OK); $| = 1; # We may safely interrupt @@ -185,7 +196,7 @@ sub run { local($dir) = @_; - chdir $dir || die "Cannot chdir to $dir: $!\n"; + chdir $dir or die "Cannot chdir to $dir: $!\n"; local(@files) = <*.t>; local($test); local($output); @@ -200,9 +211,24 @@ &result($test, $output); &basic_failed if $dir eq 'basic' && $failed; } - chdir '..' || die "Cannot chdir back to ..: $!\n"; + chdir '..' or die "Cannot chdir back to ..: $!\n"; } +sub run_file { + my ($path) = @_; + my ($dir, $file) = $path =~ m|^(.*)/(.*)|; + my $test = "$dir/$file"; + unless (-f $test) { + warn "WARNING: ignoring missing $path\n"; + return; + } + &print($dir, $file); + chdir $dir or die "Cannot chdir to $dir: $!\n"; + $output = `perl $file`; + &result($test, $output); + chdir $pwd or die "Cannot chdir back to ..: $!\n"; +} + sub basic_failed { print "Failed a basic test, cannot continue.\n"; unlink 'OK'; Added: trunk/mailagent/agent/test/option/U.t =================================================================== --- trunk/mailagent/agent/test/option/U.t (rev 0) +++ trunk/mailagent/agent/test/option/U.t 2008-05-28 15:10:12 UTC (rev 11) @@ -0,0 +1,68 @@ +# -U : disable reject / abort of first UNIQUE and REJECT. + +# $Id$ +# +# Copyright (c) 1990-2006, Raphael Manfredi +# +# You may redistribute only under the terms of the Artistic License, +# as specified in the README file that comes with the distribution. +# You may reuse parts of this distribution only within the terms of +# that same Artistic License; a copy of which may be found at the root +# of the source tree for mailagent 3.0. +# +# $Log: F.t,v $ +# Revision 3.0.1.1 1994/01/26 09:36:08 ram +# patch5: created +# + +do '../pl/init.pl'; +do '../pl/logfile.pl'; +chdir '../out'; +$user = $ENV{'USER'}; # Don't want to include ../pl/filter.pl +unlink 'folder', 'again', $user; + +$devnull = ">/dev/null 2>&1"; + +# Load the dbr database +unlink("dbr/i/e"); +system "$mailagent -e '{ UNIQUE (a); UNIQUE (b); }' -f ../mail $devnull"; +$? == 0 || print "1\n"; +-f $user || print "2\n"; + +unlink $user; +system "$mailagent -U -e '{ UNIQUE (a); SAVE ~/again; }' -f ../mail $devnull"; +$? == 0 || print "3\n"; +-f $user && print "4\n"; +-s 'again' || print "5\n"; +&get_log(6, 'again'); +&check_log('^X-Filter:', 7) == 1 || print "8\n"; + +unlink $user, 'again'; +system "$mailagent -U -e '{ UNIQUE (a); UNIQUE (b); SAVE ~/again; }' -f ../mail" + . $devnull; +$? == 0 || print "9\n"; +-f $user && print "10\n"; +-s 'again' || print "11\n"; + +unlink $user, 'again'; +system "$mailagent -U -e '{ RECORD (a); RECORD (b); SAVE ~/again; }' -f ../mail" + . $devnull; +$? == 0 || print "12\n"; +-f $user && print "13\n"; +-s 'again' || print "14\n"; + +unlink $user, 'again'; +system "$mailagent -U -e '{ RECORD (a); UNIQUE (a); SAVE ~/again; }' -f ../mail" + . $devnull; +$? == 0 || print "15\n"; +-f $user || print "16\n"; +-s 'again' && print "17\n"; + +unlink $user, 'again'; +system "$mailagent -U -e '{ UNIQUE (a); RECORD (a); SAVE ~/again; }' -f ../mail" + . $devnull; +$? == 0 || print "18\n"; +-f $user || print "19\n"; +-s 'again' && print "20\n"; + +print "0\n"; Property changes on: trunk/mailagent/agent/test/option/U.t ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-05-28 09:18:05
|
Revision: 6 http://mailagent.svn.sourceforge.net/mailagent/?rev=6&view=rev Author: rmanfredi Date: 2008-05-28 02:17:55 -0700 (Wed, 28 May 2008) Log Message: ----------- Regenerated. Modified Paths: -------------- trunk/mailagent/Configure trunk/mailagent/config_h.SH Modified: trunk/mailagent/Configure =================================================================== --- trunk/mailagent/Configure 2008-05-28 08:00:09 UTC (rev 5) +++ trunk/mailagent/Configure 2008-05-28 09:17:55 UTC (rev 6) @@ -11,18 +11,16 @@ # Yes, you may rip this off to use in other distribution packages. This # script belongs to the public domain and cannot be copyrighted. # -# (Note: this Configure script was generated automatically. Rather than +# Note: this Configure script was generated automatically. Rather than # working with this copy of Configure, you may wish to get metaconfig. -# The dist-3.0 package (which contains metaconfig) was posted in -# comp.sources.misc and is available on CPAN under authors/id/RAM so -# you may fetch it yourself from your nearest archive site.) -# +# The dist package (which contains metaconfig) is available via SVN: +# svn co https://svn.sourceforge.net/svnroot/dist/trunk/dist -# $Id: Configure,v 3.0.1.15 1999/07/12 13:39:45 ram Exp ram $ +# $Id: Head.U 6 2006-08-25 22:21:46Z rmanfredi $ # -# Generated on Mon Jul 12 15:23:12 METDST 1999 [metaconfig 3.0 PL70] +# Generated on Wed May 28 11:04:29 CEST 2008 [metaconfig 3.5 PL0] -cat >/tmp/c1$$ <<EOF +cat >c1$$ <<EOF ARGGGHHHH!!!!! SCO csh still thinks true is false. Write to SCO today and tell them that next @@ -33,18 +31,18 @@ [End of diatribe. We now return you to your regularly scheduled programming...] EOF -cat >/tmp/c2$$ <<EOF +cat >c2$$ <<EOF OOPS! You naughty creature! You didn't run Configure with sh! I will attempt to remedy the situation by running sh for you... EOF -true || cat /tmp/c1$$ /tmp/c2$$ +true || cat c1$$ c2$$ true || exec sh $0 $argv:q -(exit $?0) || cat /tmp/c2$$ +(exit $?0) || cat c2$$ (exit $?0) || exec sh $0 $argv:q -rm -f /tmp/c1$$ /tmp/c2$$ +rm -f c1$$ c2$$ : compute my invocation name me=$0 @@ -55,13 +53,20 @@ ;; esac -: Proper PATH separator +: Proper separator for the PATH environment variable p_=: -: On OS/2 this directory should exist if this is not floppy only system :-] -if test -d c:/.; then - p_=\; - PATH=`cmd /c "echo %PATH%" | tr '\\\\' / ` - OS2_SHELL=`cmd /c "echo %OS2_SHELL%" | tr '\\\\' / | tr '[A-Z]' '[a-z]'` +: On OS/2 this directory should exist if this is not floppy only system ":-]" +if test -d c:/. ; then + if test -n "$OS2_SHELL"; then + p_=\; + PATH=`cmd /c "echo %PATH%" | tr '\\\\' / ` + OS2_SHELL=`cmd /c "echo %OS2_SHELL%" | tr '\\\\' / | tr '[A-Z]' '[a-z]'` + elif test -n "$DJGPP"; then + case "X${MACHTYPE:-nonesuchmach}" in + *cygwin) ;; + *) p_=\; ;; + esac + fi fi : Proper PATH setting @@ -73,6 +78,7 @@ paths="$paths /bsd4.3/usr/bin /usr/bsd /bsd43/bin /usr/ccs/bin" paths="$paths /etc /usr/lib /usr/ucblib /lib /usr/ccs/lib" paths="$paths /sbin /usr/sbin /usr/libexec" +paths="$paths /system/gnu_library/bin" for p in $paths do @@ -103,9 +109,16 @@ newsh=/usr/bin/bsh fi fi +if test -f /osf_boot -a -f /usr/sbin/setld; then + if test X`/usr/bin/uname -s` = XOSF1; then + avoidksh="to avoid Digital UNIX' ksh" + newsh=/bin/sh + unset BIN_SH + fi +fi case "$inksh/$needksh" in /[a-z]*) - unset ENV + ENV='' changesh=true reason="$needksh" ;; @@ -126,6 +139,7 @@ esac case "$changesh" in true) + export newsh echo "(Feeding myself to $newsh $reason.)" case "$0" in Configure|*/Configure) exec $newsh $0 "$@";; @@ -134,16 +148,38 @@ ;; esac +: if needed, set CDPATH to a harmless value that is not chatty +case "$CDPATH" in +'') ;; +*) case "$SHELL" in + *bash*) CDPATH='.' ;; + *) CDPATH='' ;; + esac + ;; +esac + : Configure runs within the UU subdirectory test -d UU || mkdir UU -unset CDPATH cd UU && rm -f ./* +ccname='' +ccversion='' +ccsymbols='' +cppccsymbols='' +cppsymbols='' +from='' +run='' +targetarch='' +to='' +usecrosscompile='' d_bsd='' +d_dos='' d_eunice='' +d_linux='' +d_os2='' d_xenix='' +_exe='' eunicefix='' -Mcc='' ar='' awk='' bash='' @@ -166,7 +202,7 @@ expr='' find='' flex='' -gcc='' +gmake='' grep='' gzip='' inews='' @@ -184,6 +220,7 @@ mkdir='' more='' mv='' +nm='' nroff='' perl='' pg='' @@ -201,6 +238,7 @@ tail='' tar='' tbl='' +tee='' test='' touch='' tr='' @@ -225,15 +263,17 @@ Revision='' Source='' State='' +_a='' +_o='' archobjs='' firstmakefile='' afs='' +afsroot='' baserev='' bin='' binexp='' installbin='' cc='' -gccversion='' ccflags='' cppflags='' ldflags='' @@ -244,6 +284,7 @@ cf_by='' cf_time='' contains='' +cpp_quote='' cpp_stuff='' cpplast='' cppminus='' @@ -261,6 +302,7 @@ d_uname='' d_getopt='' d_gnulibc='' +gnulibc_version='' d_hidnet='' hiddennet='' d_open3='' @@ -289,9 +331,13 @@ signal_t='' d_wifstat='' defeditor='' +gccosandvers='' +gccversion='' h_fcntl='' h_sysfile='' i_fcntl='' +i_malloc='' +i_stdlib='' i_string='' strings='' i_sysfile='' @@ -316,18 +362,26 @@ intsize='' longsize='' shortsize='' +issymlink='' libc='' +libnames='' glibpth='' libpth='' loclibpth='' plibpth='' xlibpth='' libs='' +libscheck='' +libsdirs='' +libsfiles='' +libsfound='' +libspath='' lns='' maildir='' maildirexp='' mailer='' mailfile='' +make_set_make='' installmansrc='' manext='' mansrc='' @@ -361,6 +415,7 @@ patchlevel='' perlpath='' pidtype='' +pkgsrc='' prefix='' prefixexp='' installprivlib='' @@ -397,13 +452,13 @@ startperl='' startsh='' sysman='' +trnl='' uidtype='' nm_opt='' nm_so_opt='' runnm='' usenm='' incpath='' -mips='' mips_type='' usrinc='' utmp='' @@ -411,6 +466,7 @@ voidflags='' CONFIG='' +: Initialize wide constants define='define' undef='undef' smallmach='pdp11 i8086 z8000 i80286 iAPX286' @@ -425,76 +481,28 @@ eunicefix=/etc/unixtovms.exe fi -: list of known cpp symbols, sorted alphabetically -al="AMIX BIT_MSF BSD BSD4_3 BSD_NET2 CMU CRAY DGUX DOLPHIN DPX2" -al="$al GO32 GOULD_PN HP700 I386 I80960 I960 Lynx M68000 M68K MACH" -al="$al MIPSEB MIPSEL MSDOS MTXINU MULTIMAX MVS" -al="$al M_COFF M_I186 M_I286 M_I386 M_I8086 M_I86 M_I86SM" -al="$al M_SYS3 M_SYS5 M_SYSIII M_SYSV M_UNIX M_XENIX" -al="$al NeXT OCS88 OSF1 PARISC PC532 PORTAR POSIX" -al="$al PWB R3000 RES RISC6000 RT Sun386i SVR3 SVR4" -al="$al SYSTYPE_BSD SYSTYPE_SVR4 SYSTYPE_SYSV Tek4132 Tek4300" -al="$al UMAXV USGr4 USGr4_2 UTEK UTS UTek UnicomPBB UnicomPBD Utek" -al="$al VMS Xenix286" -al="$al _AIX _AIX32 _AIX370 _AM29000 _COFF _CRAY _CX_UX _EPI" -al="$al _IBMESA _IBMR2 _M88K _M88KBCS_TARGET" -al="$al _MIPSEB _MIPSEL _M_COFF _M_I86 _M_I86SM _M_SYS3" -al="$al _M_SYS5 _M_SYSIII _M_SYSV _M_UNIX _M_XENIX _NLS _PGC_ _R3000" -al="$al _SYSTYPE_BSD _SYSTYPE_BSD43 _SYSTYPE_SVR4" -al="$al _SYSTYPE_SYSV _SYSV3 _U370 _UNICOS" -al="$al __386BSD__ __BIG_ENDIAN __BIG_ENDIAN__ __BSD_4_4__" -al="$al __DGUX__ __DPX2__ __H3050R __H3050RX" -al="$al __LITTLE_ENDIAN __LITTLE_ENDIAN__ __MACH__" -al="$al __MIPSEB __MIPSEB__ __MIPSEL __MIPSEL__" -al="$al __Next__ __OSF1__ __PARAGON__ __PGC__ __PWB __STDC__" -al="$al __SVR4_2__ __UMAXV__" -al="$al ____386BSD____ __alpha __alpha__ __amiga" -al="$al __bsd4_2 __bsd4_2__ __bsdi__ __convex__" -al="$al __host_mips__" -al="$al __hp9000s200 __hp9000s300 __hp9000s400 __hp9000s500" -al="$al __hp9000s500 __hp9000s700 __hp9000s800" -al="$al __hppa __hpux __hp_osf __i286 __i286__ __i386 __i386__" -al="$al __i486 __i486__ __i860 __i860__ __ibmesa __ksr1__ __linux__" -al="$al __m68k __m68k__ __m88100__ __m88k __m88k__" -al="$al __mc68000 __mc68000__ __mc68020 __mc68020__" -al="$al __mc68030 __mc68030__ __mc68040 __mc68040__" -al="$al __mc88100 __mc88100__ __mips __mips__" -al="$al __motorola__ __osf__ __pa_risc __sparc__ __stdc__" -al="$al __sun __sun__ __svr3__ __svr4__ __ultrix __ultrix__" -al="$al __unix __unix__ __uxpm__ __uxps__ __vax __vax__" -al="$al _host_mips _mips _unix" -al="$al a29k aegis aix aixpc alliant alpha am29000 amiga ansi ardent" -al="$al apollo ardent att386 att3b" -al="$al bsd bsd43 bsd4_2 bsd4_3 bsd4_4 bsdi bull" -al="$al cadmus clipper concurrent convex cray ctix" -al="$al dmert encore gcos gcx gimpel gould" -al="$al hbullx20 hcx host_mips hp200 hp300 hp700 hp800" -al="$al hp9000 hp9000s300 hp9000s400 hp9000s500" -al="$al hp9000s700 hp9000s800 hp9k8 hppa hpux" -al="$al i186 i286 i386 i486 i8086" -al="$al i80960 i860 iAPX286 ibm ibm032 ibmrt interdata is68k" -al="$al ksr1 linux luna luna88k m68k m88100 m88k" -al="$al mc300 mc500 mc68000 mc68010 mc68020 mc68030" -al="$al mc68040 mc68060 mc68k mc68k32 mc700" -al="$al mc88000 mc88100 merlin mert mips mvs n16" -al="$al ncl_el ncl_mr" -al="$al news1500 news1700 news1800 news1900 news3700" -al="$al news700 news800 news900 ns16000 ns32000" -al="$al ns32016 ns32332 ns32k nsc32000 os osf" -al="$al parisc pc532 pdp11 plexus posix pyr" -al="$al riscix riscos scs sequent sgi sinix sony sony_news" -al="$al sonyrisc sparc sparclite spectrum stardent stratos" -al="$al sun sun3 sun386 svr4 sysV68 sysV88" -al="$al titan tower tower32 tower32_200 tower32_600 tower32_700" -al="$al tower32_800 tower32_850 tss u370 u3b u3b2 u3b20 u3b200" -al="$al u3b20d u3b5 ultrix unix unixpc unos vax venix vms" -al="$al xenix z8000" +: Set executable suffix now -- needed before hints available +if test -f "/libs/version.library"; then + : Amiga OS + _exe="" +elif test -f "/system/gnu_library/bin/ar.pm"; then + : Stratus VOS + _exe=".pm" +elif test -n "$DJGPP"; then + : DOS DJGPP + _exe=".exe" +elif test -d c:/. ; then + : OS/2 or cygwin + _exe=".exe" +else + : All other UNIX systems + _exe="" +fi -: No trailing extension on UNIX executables -_exe='' +ccname='' +ccversion='' : Extra object files, if any, needed on this platform. archobjs='' -gccversion='' : Possible local include directories to search. : Set locincpth to "" in a hint file to defeat local include searches. locincpth="/usr/local/include /opt/local/include /usr/gnu/include" @@ -505,18 +513,18 @@ i_sysselct='' i_whoami='' +libnames='' : change the next line if compiling for Xenix/286 on Xenix/386 xlibpth='/usr/lib/386 /lib/386' - : Possible local library directories to search. loclibpth="/usr/local/lib /opt/local/lib /usr/gnu/lib" loclibpth="$loclibpth /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib" : general looking path for locating libraries -glibpth="/shlib /usr/shlib /lib/pa1.1 /usr/lib/large" -glibpth="$glibpth /lib /usr/lib $xlibpth" -glibpth="$glibpth /lib/large /usr/lib/small /lib/small" +glibpth="/lib /usr/lib $xlibpth" glibpth="$glibpth /usr/ccs/lib /usr/ucblib /usr/local/lib" +test -f /usr/shlib/libc.so && glibpth="/usr/shlib $glibpth" +test -f /shlib/libc.so && glibpth="/shlib $glibpth" : Private path used by Configure to find libraries. Its value : is prepended to libpth. This variable takes care of special @@ -525,6 +533,9 @@ : default library list libswanted='' +: should be set by hint files if needed +libscheck='' +usesocks='' : full support for void wanted by default defvoidused=15 @@ -549,10 +560,13 @@ done for xxx in $try; do if test -f "$xxx"; then - sh="$xxx"; + sh="$xxx" break + elif test -f "$xxx$_exe"; then + sh="$xxx" + break elif test -f "$xxx.exe"; then - sh="$xxx"; + sh="$xxx" break fi done @@ -561,7 +575,7 @@ esac case "$sh" in -'') cat <<EOM >&2 +'') cat >&2 <<EOM $me: Fatal Error: I can't find a Bourne Shell anywhere. Usually it's in /bin/sh. How did you even get this far? @@ -577,18 +591,30 @@ shsharp=true spitshell=cat xcat=/bin/cat - test -f $xcat || xcat=/usr/bin/cat - echo "#!$xcat" >try - $eunicefix try - chmod +x try - ./try > today + test -f $xcat$_exe || xcat=/usr/bin/cat + if test ! -f $xcat$_exe; then + for p in `echo $PATH | sed -e "s/$p_/ /g"` $paths; do + if test -f $p/cat$_exe; then + xcat=$p/cat + break + fi + done + if test ! -f $xcat$_exe; then + echo "Can't find cat anywhere!" + exit 1 + fi + fi + echo "#!$xcat" >sharp + $eunicefix sharp + chmod +x sharp + ./sharp > today 2>/dev/null if test -s today; then sharpbang='#!' else - echo "#! $xcat" > try - $eunicefix try - chmod +x try - ./try > today + echo "#! $xcat" > sharp + $eunicefix sharp + chmod +x sharp + ./sharp > today 2>/dev/null if test -s today; then sharpbang='#! ' else @@ -608,33 +634,58 @@ echo "I presume that if # doesn't work, #! won't work either!" sharpbang=': use ' fi -rm -f try today +rm -f sharp today : figure out how to guarantee sh startup case "$startsh" in '') startsh=${sharpbang}${sh} ;; *) esac -cat >try <<EOSS +cat >sharp <<EOSS $startsh set abc test "$?abc" != 1 EOSS -chmod +x try -$eunicefix try -if ./try; then +chmod +x sharp +$eunicefix sharp +if ./sharp; then : echo "Yup, it does." else echo "Hmm... '$startsh' does not guarantee sh startup..." echo "You may have to fix up the shell scripts to make sure $sh runs them." fi -rm -f try +rm -f sharp +: Save command line options in file UU/cmdline.opt for later use in +: generating config.sh. +cat > cmdline.opt <<EOSH +: Configure command line arguments. +config_arg0='$0' +config_args='$*' +config_argc=$# +EOSH +argn=1 +args_exp='' +args_sep='' +for arg in "$@"; do + cat >>cmdline.opt <<EOSH +config_arg$argn='$arg' +EOSH + cat <<EOC | sed -e "s/'/'"'"'"'"'"'"'/g" > cmdl.opt +$arg +EOC + arg_exp=`cat cmdl.opt` + args_exp="$args_exp$args_sep'$arg_exp'" + argn=`expr $argn + 1` + args_sep=' ' +done +rm -f cmdl.opt + : produce awk script to parse command line options cat >options.awk <<'EOF' BEGIN { - optstr = "dD:eEf:hKOrsSU:V"; # getopt-style specification + optstr = "A:dD:eEf:hKOrsSU:V"; # getopt-style specification len = length(optstr); for (i = 1; i <= len; i++) { @@ -694,7 +745,7 @@ extractsh='' override='' knowitall='' -rm -f optdef.sh +rm -f optdef.sh posthint.sh cat >optdef.sh <<EOS $startsh EOS @@ -748,8 +799,58 @@ esac shift ;; - -V) echo "$me generated by metaconfig 3.0 PL70." >&2 - exit 0;; + -A) + shift + xxx='' + yyy="$1" + zzz='' + uuu=undef + case "$yyy" in + *=*) zzz=`echo "$yyy"|sed 's!=.*!!'` + case "$zzz" in + *:*) zzz='' ;; + *) xxx=append + zzz=" "`echo "$yyy"|sed 's!^[^=]*=!!'` + yyy=`echo "$yyy"|sed 's!=.*!!'` ;; + esac + ;; + esac + case "$xxx" in + '') case "$yyy" in + *:*) xxx=`echo "$yyy"|sed 's!:.*!!'` + yyy=`echo "$yyy"|sed 's!^[^:]*:!!'` + zzz=`echo "$yyy"|sed 's!^[^=]*=!!'` + yyy=`echo "$yyy"|sed 's!=.*!!'` ;; + *) xxx=`echo "$yyy"|sed 's!:.*!!'` + yyy=`echo "$yyy"|sed 's!^[^:]*:!!'` ;; + esac + ;; + esac + case "$xxx" in + append) + echo "$yyy=\"\${$yyy}$zzz\"" >> posthint.sh ;; + clear) + echo "$yyy=''" >> posthint.sh ;; + define) + case "$zzz" in + '') zzz=define ;; + esac + echo "$yyy='$zzz'" >> posthint.sh ;; + eval) + echo "eval \"$yyy=$zzz\"" >> posthint.sh ;; + prepend) + echo "$yyy=\"$zzz\${$yyy}\"" >> posthint.sh ;; + undef) + case "$zzz" in + '') zzz="$uuu" ;; + esac + echo "$yyy=$zzz" >> posthint.sh ;; + *) echo "$me: unknown -A command '$xxx', ignoring -A $1" >&2 ;; + esac + shift + ;; + -V) echo "$me generated by metaconfig 3.5 PL0." >&2 + exit 0;; --) break;; -*) echo "$me: unknown option $1" >&2; shift; error=true;; *) break;; @@ -760,7 +861,7 @@ true) cat >&2 <<EOM Usage: $me [-dehrsEKOSV] [-f config.sh] [-D symbol] [-D symbol=value] - [-U symbol] [-U symbol=] + [-U symbol] [-U symbol=] [-A command:symbol...] -d : use defaults for all answers. -e : go on without questioning past the production of config.sh. -f : specify an alternate default configuration file. @@ -777,6 +878,16 @@ -U : undefine symbol: -U symbol symbol gets the value 'undef' -U symbol= symbol gets completely empty + -A : manipulate symbol after the platform specific hints have been applied: + -A symbol=value append " "value to symbol + -A append:symbol=value append value to symbol + -A define:symbol=value define symbol to have value + -A clear:symbol define symbol to be '' + -A define:symbol define symbol to be 'define' + -A eval:symbol=value define symbol to be eval of value + -A prepend:symbol=value prepend value to symbol + -A undef:symbol define symbol to be 'undef' + -A undef:symbol= define symbol to be '' -V : print version number and exit (with a zero status). EOM exit 1 @@ -787,10 +898,15 @@ case "$fastread$alldone" in yescont|yesexit) ;; *) - if test ! -t 0; then - echo "Say 'sh Configure', not 'sh <Configure'" - exit 1 - fi + case "$extractsh" in + true) ;; + *) + if test ! -t 0; then + echo "Say 'sh Configure', not 'sh <Configure'" + exit 1 + fi + ;; + esac ;; esac @@ -802,9 +918,11 @@ : run the defines and the undefines, if any, but leave the file out there... touch optdef.sh . ./optdef.sh +: create the posthint manipulation script and leave the file out there... +touch posthint.sh : set package name -package=mailagent +package='mailagent' first=`echo $package | sed -e 's/^\(.\).*/\1/'` last=`echo $package | sed -e 's/^.\(.*\)/\1/'` case "`echo AbyZ | tr '[:lower:]' '[:upper:]' 2>/dev/null`" in @@ -812,6 +930,29 @@ *) spackage=`echo $first | tr '[a-z]' '[A-Z]'`$last;; esac +: script used to emulate mkdir -p +cat >mkdirp <<EOS +$startsh +EOS +cat >>mkdirp <<'EOS' +name=$1; +create=""; +while test $name; do + if test ! -d "$name"; then + create="$name $create" + name=`echo $name | sed -e "s|^[^/]*$||"` + name=`echo $name | sed -e "s|\(.*\)/.*|\1|"` + else + name="" + fi +done +for file in $create; do + mkdir $file +done +EOS +chmod +x mkdirp +$eunicefix mkdirp + : Some greps do not return status, grrr. echo "grimblepritz" >grimble if grep blurfldyick grimble >/dev/null 2>&1 ; then @@ -833,153 +974,31 @@ chmod +x contains esac -: first determine how to suppress newline on echo command -echo " " -echo "Checking echo to see how to suppress newlines..." -(echo "hi there\c" ; echo " ") >.echotmp -if $contains c .echotmp >/dev/null 2>&1 ; then - echo "...using -n." - n='-n' - c='' -else - cat <<'EOM' -...using \c -EOM - n='' - c='\c' -fi -echo $n "The star should be here-->$c" -echo '*' -rm -f .echotmp - -: compute the number of columns on the terminal for proper question formatting -case "$COLUMNS" in -'') COLUMNS='80';; -esac - -: set up the echo used in my read -myecho="case \"\$xxxm\" in -'') echo $n \"\$rp $c\" >&4;; -*) case \"\$rp\" in - '') echo $n \"[\$xxxm] $c\";; - *) - if test \`echo \"\$rp [\$xxxm] \" | wc -c\` -ge $COLUMNS; then - echo \"\$rp\" >&4 - echo $n \"[\$xxxm] $c\" >&4 - else - echo $n \"\$rp [\$xxxm] $c\" >&4 - fi - ;; - esac;; -esac" - -: now set up to do reads with possible shell escape and default assignment -cat <<EOSC >myread -$startsh -xxxm=\$dflt -$myecho -ans='!' -case "\$fastread" in -yes) case "\$dflt" in - '') ;; - *) ans=''; - case "\$silent-\$rp" in - true-) ;; - *) echo " " >&4;; - esac;; - esac;; -*) case "\$silent" in - true) case "\$rp" in - '') ans='';; - esac;; - esac;; -esac -while expr "X\$ans" : "X!" >/dev/null; do - read answ - set x \$xxxm - shift - aok=''; eval "ans=\\"\$answ\\"" && aok=y - case "\$answ" in - "!") - sh 1>&4 - echo " " - $myecho - ;; - !*) - set x \`expr "X\$ans" : "X!\(.*\)\$"\` - shift - sh 1>&4 -c "\$*" - echo " " - $myecho - ;; - "\$ans") - case "\$ans" in - \\&*) - set x \`expr "X\$ans" : "X&\(.*\)\$"\` - shift - case "\$1" in - -d) - fastread=yes - echo "(OK, I'll run with -d after this question.)" >&4 - ;; - -*) - echo "*** Sorry, \$1 not supported yet." >&4 - ;; - esac - $myecho - ans=! - ;; - esac;; - *) - case "\$aok" in - y) - echo "*** Substitution done -- please confirm." - xxxm="\$ans" - ans=\`echo $n "\$ans$c" | tr '\012' ' '\` - xxxm="\$ans" - ans=! - ;; - *) - echo "*** Error -- try again." - ans=! - ;; - esac - $myecho - ;; - esac - case "\$ans\$xxxm\$nostick" in - '') - ans=! - $myecho - ;; - esac -done -case "\$ans" in -'') ans="\$xxxm";; -esac -EOSC - : Find the path to the source tree case "$src" in -'') src=`echo $0 | sed -e 's%/[^/][^/]*$%%'`;; +'') case "$0" in + */*) + src=`echo $0 | sed -e 's%/[^/][^/]*$%%'` + ;; + *) src='.';; + esac;; esac case "$src" in -'') - src=. - rsrc=.. +'') src=/ + rsrc=/ ;; -/*) rsrc="$src/..";; -*) rsrc="../$src";; +/*) rsrc="$src";; +*) rsrc="../$src";; esac if test -f $rsrc/Configure && \ - $contains "^package=$package" $rsrc/Configure >/dev/null 2>&1 + $contains "^package='$package'\$" $rsrc/Configure >/dev/null 2>&1 then : found it, so we are ok. else rsrc='' for src in . .. ../.. ../../.. ../../../..; do if test -f ../$src/Configure && \ - $contains "^package=$package" ../$src/Configure >/dev/null 2>&1 + $contains "^package=$package$" ../$src/Configure >/dev/null 2>&1 then rsrc=../$src break @@ -988,63 +1007,43 @@ fi case "$rsrc" in '') - echo " " - dflt= - rp="Directory where sources for $package are located?" - . ./myread - src="$ans" - rsrc="$src" - if test -f $rsrc/Configure && \ - $contains "^package=$package" $rsrc/Configure >/dev/null 2>&1 - then - echo "Ok, I've found them under $src" - else - echo "Sorry, I can't seem to be able to locate $package sources." >&4 - exit 1 - fi + cat <<EOM >&4 + +Sorry, I can't seem to locate the source dir for $package. Please start +Configure with an explicit path -- i.e. /some/path/Configure. + +EOM + exit 1 ;; -../.) ;; +../.) rsrc='..';; *) echo " " - echo "Sources for $package found in $src" >&4 + echo "Sources for $package found in \"$src\"." >&4 ;; esac : script used to extract .SH files with variable substitutions -cat >extract <<'EOS' +cat >extract <<EOS CONFIG=true +SRC="$src" +EOS +cat >>extract <<'EOS' echo "Doing variable substitutions on .SH files..." -if test -f $src/MANIFEST; then - set x `awk '{print $1}' <$src/MANIFEST | grep '\.SH'` +if test -f "$SRC/MANIFEST"; then + set x `awk '{print $1}' <$SRC/MANIFEST | grep '\.SH'` else echo "(Looking for .SH files under the source directory.)" - set x `(cd $src; find . -name "*.SH" -print)` + set x `(cd "$SRC"; find . -name "*.SH" -print)` fi shift case $# in -0) set x `(cd $src; echo *.SH)`; shift;; +0) set x `(cd "$SRC"; echo *.SH)`; shift;; esac -if test ! -f $src/$1; then +if test ! -f "$SRC/$1"; then shift fi -mkdir_p=' -name=$1; -create=""; -while test $name; do - if test ! -d "$name"; then - create="$name $create"; - name=`echo $name | sed -e "s|^[^/]*$||"`; - name=`echo $name | sed -e "s|\(.*\)/.*|\1|"`; - else - name=""; - fi; -done; -for file in $create; do - mkdir $file; -done -' for file in $*; do - case "$src" in + case "$SRC" in ".") case "$file" in */*) @@ -1062,20 +1061,19 @@ */*) dir=`expr X$file : 'X\(.*\)/'` file=`expr X$file : 'X.*/\(.*\)'` - (set x $dir; shift; eval $mkdir_p) - sh <$src/$dir/$file + ./mkdirp $dir + sh <"$SRC/$dir/$file" ;; *) - sh <$src/$file + sh <"$SRC/$file" ;; esac ;; esac done -if test -f $src/config_h.SH; then +if test -f "$SRC/config_h.SH"; then if test ! -f config.h; then - : oops, they left it out of MANIFEST, probably, so do it anyway. - . $src/config_h.SH + sh <"$SRC/config_h.SH" fi fi EOS @@ -1088,19 +1086,17 @@ *) exec 1>&4;; esac case "$config_sh" in - '') config_sh='config.sh'; config="$rsrc/config.sh";; - /*) config="$config_sh";; - *) config="$rsrc/$config_sh";; + '') config_sh='config.sh';; esac echo " " echo "Fetching answers from $config_sh..." - . $config + cd .. + . $config_sh test "$override" && . ./optdef.sh echo " " - cd .. . UU/extract rm -rf UU - echo "Done." + echo "Extraction done." exit 0 ;; esac @@ -1112,15 +1108,36 @@ trap 'echo " "; test -d ../UU && rm -rf X $rmlist; exit 1' 1 2 3 15 +: first determine how to suppress newline on echo command +echo " " +echo "Checking echo to see how to suppress newlines..." +(echo "hi there\c" ; echo " ") >.echotmp +if $contains c .echotmp >/dev/null 2>&1 ; then + echo "...using -n." + n='-n' + c='' +else + cat <<'EOM' +...using \c +EOM + n='' + c='\c' +fi +echo $n "The star should be here-->$c" +echo '*' +rm -f .echotmp + : Now test for existence of everything in MANIFEST echo " " -if test -f $rsrc/MANIFEST; then +if test -f "$rsrc/MANIFEST"; then echo "First let's make sure your kit is complete. Checking..." >&4 - awk '$1 !~ /PACK[A-Z]+/ {print $1}' $rsrc/MANIFEST | split -50 + awk '$1 !~ /PACK[A-Z]+/ {print $1}' "$rsrc/MANIFEST" | \ + (split -l 50 2>/dev/null || split -50) rm -f missing tmppwd=`pwd` for filelist in x??; do - (cd $rsrc; ls `cat $tmppwd/$filelist` >/dev/null 2>>$tmppwd/missing) + (cd "$rsrc"; ls `cat "$tmppwd/$filelist"` \ + >/dev/null 2>>"$tmppwd/missing") done if test -s missing; then cat missing >&4 @@ -1154,6 +1171,144 @@ fi rm -f missing x?? +: Find the appropriate value for a newline for tr +echo " " +if test -n "$DJGPP"; then + trnl='\012' +fi +if test X"$trnl" = X; then + case "`echo foo | tr '\n' x 2>/dev/null`" in + foox) trnl='\n' ;; + esac +fi +if test X"$trnl" = X; then + case "`echo foo | tr '\012' x 2>/dev/null`" in + foox) trnl='\012' ;; + esac +fi +if test X"$trnl" = X; then + case "`echo foo | tr '\r\n' xy 2>/dev/null`" in + fooxy) trnl='\n\r' ;; + esac +fi +if test X"$trnl" = X; then + cat <<EOM >&2 + +$me: Fatal Error: cannot figure out how to translate newlines with 'tr'. + +EOM + exit 1 +else + echo "We'll use '$trnl' to transliterate a newline." +fi + +: compute the number of columns on the terminal for proper question formatting +case "$COLUMNS" in +'') COLUMNS='80';; +esac + +: set up the echo used in my read +myecho="case \"\$xxxm\" in +'') echo $n \"\$rp $c\" >&4;; +*) case \"\$rp\" in + '') echo $n \"[\$xxxm] $c\";; + *) + if test \`echo \"\$rp [\$xxxm] \" | wc -c\` -ge $COLUMNS; then + echo \"\$rp\" >&4 + echo $n \"[\$xxxm] $c\" >&4 + else + echo $n \"\$rp [\$xxxm] $c\" >&4 + fi + ;; + esac;; +esac" + +: now set up to do reads with possible shell escape and default assignment +cat <<EOSC >myread +$startsh +xxxm=\$dflt +$myecho +ans='!' +case "\$fastread" in +yes) case "\$dflt" in + '') ;; + *) ans=''; + case "\$silent-\$rp" in + true-) ;; + *) echo " " >&4;; + esac;; + esac;; +*) case "\$silent" in + true) case "\$rp" in + '') ans='';; + esac;; + esac;; +esac +while expr "X\$ans" : "X!" >/dev/null; do + read answ + set x \$xxxm + shift + aok=''; eval "ans=\\"\$answ\\"" && aok=y + case "\$answ" in + "!") + sh 1>&4 + echo " " + $myecho + ;; + !*) + set x \`expr "X\$ans" : "X!\(.*\)\$"\` + shift + sh 1>&4 -c "\$*" + echo " " + $myecho + ;; + "\$ans") + case "\$ans" in + \\&*) + set x \`expr "X\$ans" : "X&\(.*\)\$"\` + shift + case "\$1" in + -d) + fastread=yes + echo "(OK, I'll run with -d after this question.)" >&4 + ;; + -*) + echo "*** Sorry, \$1 not supported yet." >&4 + ;; + esac + $myecho + ans=! + ;; + esac;; + *) + case "\$aok" in + y) + echo "*** Substitution done -- please confirm." + xxxm="\$ans" + ans=\`echo $n "\$ans$c" | tr '$trnl' ' '\` + xxxm="\$ans" + ans=! + ;; + *) + echo "*** Error -- try again." + ans=! + ;; + esac + $myecho + ;; + esac + case "\$ans\$xxxm\$nostick" in + '') + ans=! + $myecho + ;; + esac +done +case "\$ans" in +'') ans="\$xxxm";; +esac +EOSC + : create .config dir to save info across Configure sessions test -d ../.config || mkdir ../.config cat >../.config/README <<EOF @@ -1215,7 +1370,7 @@ the questions and use the computed defaults (or the previous answers if there was already a config.sh file). Type 'Configure -h' for a list of options. You may also start interactively and then answer '& -d' at any prompt to turn -on the non-interactive behaviour for the remaining of the execution. +on the non-interactive behaviour for the remainder of the execution. EOH . ./myread @@ -1246,6 +1401,24 @@ esac fi +: script used to emit important warnings +cat >warn <<EOS +$startsh +if test \$# -gt 0; then + echo "\$@" >msg +else + cat >msg +fi +echo "*** WARNING:" >&4 +sed -e 's/^/*** /' <msg >&4 +echo "*** " >&4 +cat msg >>config.msg +echo " " >>config.msg +rm -f msg +EOS +chmod +x warn +$eunicefix warn + : find out where common programs are echo " " echo "Locating common programs..." >&4 @@ -1273,9 +1446,16 @@ if test -f \$thisthing; then echo \$thisthing exit 0 + elif test -f \$thisthing$_exe; then + echo \$thisthing + exit 0 elif test -f \$dir/\$thing.exe; then - : on Eunice apparently - echo \$dir/\$thing + if test -n "$DJGPP"; then + echo \$dir/\$thing.exe + else + : on Eunice apparently + echo \$dir/\$thing + fi exit 0 fi ;; @@ -1293,6 +1473,7 @@ chmod chown comm +cp echo expr grep @@ -1307,13 +1488,16 @@ uniq " trylist=" -Mcc +ar cpp date +egrep inews line ln mail +make +nm nroff perl rmail @@ -1333,14 +1517,14 @@ if test -f "$xxx"; then : ok else - echo "WARNING: no $xxx -- ignoring your setting for $file." >&4 + ./warn "no $xxx -- ignoring your setting for $file." xxx=`./loc $file $file $pth` fi ;; '') xxx=`./loc $file $file $pth`;; *) xxx=`./loc $xxx $xxx $pth`;; esac - eval $file=$xxx + eval $file=$xxx$_exe eval _$file=$xxx case "$xxx" in /*) @@ -1366,14 +1550,14 @@ if test -f "$xxx"; then : ok else - echo "WARNING: no $xxx -- ignoring your setting for $file." >&4 + ./warn "no $xxx -- ignoring your setting for $file." xxx=`./loc $file $file $pth` fi ;; '') xxx=`./loc $file $file $pth`;; *) xxx=`./loc $xxx $xxx $pth`;; esac - eval $file=$xxx + eval $file=$xxx$_exe eval _$file=$xxx case "$xxx" in /*) @@ -1392,14 +1576,39 @@ egrep) echo "Substituting grep for egrep." egrep=$grep + _egrep=$_grep ;; esac case "$ln" in ln) echo "Substituting cp for ln." ln=$cp + _ln=$_cp ;; esac +case "$make" in +make) + case "$gmake" in + gmake) + echo "I can't find make or gmake, and my life depends on it." >&4 + echo "Go find a public domain implementation or fix your PATH setting!" >&4 + exit 1 + ;; + esac + ;; +esac +case "$gmake" in +gmake) ;; +*) # We can't have osname yet. + if test -f "/system/gnu_library/bin/ar.pm"; then # Stratus VOS + # Assume that gmake, if found, is definitely GNU make + # and prefer it over the system make. + echo "Substituting gmake for make." + make=$gmake + _make=$_gmake + fi + ;; +esac case "$test" in test) echo "Hopefully test is built into your sh." @@ -1443,10 +1652,106 @@ ;; esac +: generate the trygcc script for later perusal +cat <<EOS >trygcc +$startsh +EOS +cat <<'EOSC' >>trygcc +case "$cc" in +'') ;; +*) $rm -f try try.* + $cat >try.c <<EOM +int main(int argc, char *argv[]) { + (void) argc; + (void) argv; + return 0; +} +EOM + if $cc -o try $ccflags $ldflags try.c; then + : + else + echo "Uh-oh, the C compiler '$cc' doesn't seem to be working." >&4 + despair=yes + trygcc=yes + case "$cc" in + *gcc*) trygcc=no ;; + esac + case "`$cc -v -c try.c 2>&1`" in + *gcc*) trygcc=no ;; + esac + if $test X"$trygcc" = Xyes; then + if gcc -o try -c try.c; then + echo " " + echo "You seem to have a working gcc, though." >&4 + rp="Would you like to use it?" + dflt=y + if $test -f myread; then + . ./myread + else + if $test -f UU/myread; then + . ./UU/myread + else + echo "Cannot find myread, sorry. Aborting." >&2 + exit 1 + fi + fi + case "$ans" in + [yY]*) cc=gcc; ccname=gcc; ccflags=''; despair=no; + $cat *.cbu >checktmp 2>/dev/null + if $contains ccflags checktmp >/dev/null; then + ./warn <<EOM +Any previous setting of the C compiler flags has been lost. +It may be necessary to pass -Dcc=gcc to Configure right away. +EOM + fi;; + esac + fi + fi + fi + $rm -f try try.* + ;; +esac +EOSC + +: generate the checkcc script for later perusal +cat <<EOS >checkcc +$startsh +EOS +cat <<'EOSC' >>checkcc +case "$cc" in +'') ;; +*) $rm -f try try.* + $cat >try.c <<EOM +int main(int argc, char *argv[]) { + (void) argc; + (void) argv; + return 0; +} +EOM + if $cc -o try $ccflags $ldflags try.c; then + : + else + if $test X"$despair" = Xyes; then + echo "Uh-oh, the C compiler '$cc' doesn't seem to be working." >&4 + fi + $cat >&4 <<EOM +You need to find a working C compiler. +Either (purchase and) install the C compiler supplied by your OS vendor, +or for a free C compiler try http://gcc.gnu.org/ +I cannot continue any further, aborting. +EOM + exit 1 + fi + $rm -f try try.* + ;; +esac +EOSC + : determine whether symbolic links are supported echo " " $touch blurfl -if $ln -s blurfl sym > /dev/null 2>&1 ; then +$rm -f sym +if $ln -s blurfl sym > /dev/null 2>&1 && $test -f sym; then echo "Symbolic links are supported." >&4 lns="$ln -s" else @@ -1455,45 +1760,497 @@ fi $rm -f blurfl sym +: determine whether symbolic links are supported +echo " " +case "$lns" in +*"ln"*" -s") + echo "Checking how to test for symbolic links..." >&4 + $lns blurfl sym + if $test "X$issymlink" = X; then + case "$newsh" in + '') sh -c "PATH= test -h sym" >/dev/null 2>&1 ;; + *) $newsh -c "PATH= test -h sym" >/dev/null 2>&1 ;; + esac + if test $? = 0; then + issymlink="test -h" + else + echo "Your builtin 'test -h' may be broken." >&4 + case "$test" in + /*) ;; + *) pth=`echo $PATH | sed -e "s/$p_/ /g"` + for p in $pth + do + if test -f "$p/$test"; then + test="$p/$test" + break + fi + done + ;; + esac + case "$test" in + /*) + echo "Trying external '$test -h'." >&4 + issymlink="$test -h" + if $test ! -h sym >/dev/null 2>&1; then + echo "External '$test -h' is broken, too." >&4 + issymlink='' + fi + ;; + *) issymlink='' ;; + esac + fi + fi + if $test "X$issymlink" = X; then + if $test -L sym 2>/dev/null; then + issymlink="$test -L" + echo "The builtin '$test -L' worked." >&4 + fi + fi + if $test "X$issymlink" != X; then + echo "You can test for symbolic links with '$issymlink'." >&4 + else + echo "I do not know how you can test for symbolic links." >&4 + fi + $rm -f blurfl sym + ;; +*) echo "No symbolic links, so not testing for their testing..." >&4 + ;; +esac + +: define absolute package source directory +case "$src" in +/*) pkgsrc=$src;; +*) pkgsrc=`cd $rsrc; pwd`;; +esac + +: Duplicate the tree with symbolic links if -Dmksymlinks was supplied +case "$mksymlinks" in +$define|true|[yY]*) + echo " " + case "$src" in + ''|'.') echo "Cannot create symlinks in the original directory." >&4 + exit 1 + ;; + *) case "$lns:$issymlink" in + *"ln"*" -s:"*"test -"?) + echo "Creating the symbolic links..." >&4 + echo "(First creating the subdirectories...)" >&4 + cd .. + awk '{print $1}' $src/MANIFEST | grep / | sed 's:/[^/]*$::' | \ + sort -u | while true + do + read dir + test -z "$dir" && break + ./UU/mkdirp $dir 2>/dev/null + if test -d $dir; then + : ok + else + echo "Failed to create '$dir'. Aborting." >&4 + exit 1 + fi + done + echo "(Now creating the symlinks...)" >&4 + awk '{print $1}' $src/MANIFEST | while true; do + read filename + test -z "$filename" && break + if test -f $filename; then + if $issymlink $filename; then + rm -f $filename + fi + fi + if test -f $filename; then + echo "$filename already exists, not symlinking." + else + ln -s $pkgsrc/$filename $filename + fi + done + echo "(Checking current directory...)" >&4 + cd UU + awk '$1 !~ /PACK[A-Z]+/ {print $1}' "$rsrc/MANIFEST" | \ + (split -l 50 2>/dev/null || split -50) + rm -f missing + tmppwd=`pwd` + for filelist in x??; do + (cd ..; ls `cat "$tmppwd/$filelist"` \ + >/dev/null 2>>"$tmppwd/missing") + done + if test -s missing; then + echo "Failed duplication of source tree. Aborting." >&4 + exit 1 + fi + ;; + *) echo "(I cannot figure out how to do symbolic links, ignoring!)" >&4 + ;; + esac + ;; + esac + ;; +esac + : see whether [:lower:] and [:upper:] are supported character classes echo " " -up='[A-Z]' -low='[a-z]' -case "`echo AbyZ | $tr '[:lower:]' '[:upper:]' 2>/dev/null`" in +case "`echo AbyZ | LC_ALL=C $tr '[:lower:]' '[:upper:]' 2>/dev/null`" in ABYZ) echo "Good, your tr supports [:lower:] and [:upper:] to convert case." >&4 up='[:upper:]' low='[:lower:]' ;; +*) # There is a discontinuity in EBCDIC between 'I' and 'J' + # (0xc9 and 0xd1), therefore that is a nice testing point. + if test "X$up" = X -o "X$low" = X; then + case "`echo IJ | LC_ALL=C $tr '[I-J]' '[i-j]' 2>/dev/null`" in + ij) up='[A-Z]' + low='[a-z]' + ;; + esac + fi + if test "X$up" = X -o "X$low" = X; then + case "`echo IJ | LC_ALL=C $tr I-J i-j 2>/dev/null`" in + ij) up='A-Z' + low='a-z' + ;; + esac + fi + if test "X$up" = X -o "X$low" = X; then + case "`echo IJ | od -x 2>/dev/null`" in + *C9D1*|*c9d1*) + echo "Hey, this might be EBCDIC." >&4 + if test "X$up" = X -o "X$low" = X; then + case "`echo IJ | \ + LC_ALL=C $tr '[A-IJ-RS-Z]' '[a-ij-rs-z]' 2>/dev/null`" in + ij) up='[A-IJ-RS-Z]' + low='[a-ij-rs-z]' + ;; + esac + fi + if test "X$up" = X -o "X$low" = X; then + case "`echo IJ | LC_ALL=C $tr A-IJ-RS-Z a-ij-rs-z 2>/dev/null`" in + ij) up='A-IJ-RS-Z' + low='a-ij-rs-z' + ;; + esac + fi + ;; + esac + fi +esac +case "`echo IJ | LC_ALL=C $tr \"$up\" \"$low\" 2>/dev/null`" in +ij) + echo "Using $up and $low to convert case." >&4 + ;; *) - echo "Your tr only supports [a-z] and [A-Z] to convert case." >&4 - ;; + echo "I don't know how to translate letters from upper to lower case." >&4 + echo "Your tr is not acting any way I know of." >&4 + exit 1 + ;; esac : set up the translation script tr, must be called with ./tr of course cat >tr <<EOSC $startsh case "\$1\$2" in -'[A-Z][a-z]') exec $tr '$up' '$low';; -'[a-z][A-Z]') exec $tr '$low' '$up';; +'[A-Z][a-z]') LC_ALL=C exec $tr '$up' '$low';; +'[a-z][A-Z]') LC_ALL=C exec $tr '$low' '$up';; esac -exec $tr "\$@" +LC_ALL=C exec $tr "\$@" EOSC chmod +x tr $eunicefix tr +: setup for possible cross-compilation +run='' +to=: +from=: +usecrosscompile='undef' +targetarch='' +case "$usecrosscompile" in +$define|true|[yY]*) + echo "Cross-compilation is not supported for this package." >&4 + exit 1 + ;; +esac + +: Determine the name of the machine +myuname=`$uname -a 2>/dev/null` +$test -z "$myuname" && myuname=`hostname 2>/dev/null` +myuname=`echo $myuname | $sed -e 's/^[^=]*=//' -e 's/\///g' | \ + ./tr '[A-Z]' '[a-z]' | $tr $trnl ' '` +newmyuname="$myuname" +$test -f "$uname$_exe" && has_uname=y + +: Guessing of the OS name -- half the following guesses are probably wrong... +: If you have better tests or hints, please send them to the metaconfig +: authors and to Rap...@po... +$test -f /irix && osname=irix +$test -f /xenix && osname=sco_xenix +$test -f /dynix && osname=dynix +$test -f /dnix && osname=dnix +$test -f /lynx.os && osname=lynxos +$test -f /unicos && osname=unicos && osvers=`$uname -r` +$test -f /unicosmk && osname=unicosmk && osvers=`$uname -r` +$test -f /unicosmk.ar && osname=unicosmk && osvers=`$uname -r` +$test -f /bin/mips && /bin/mips && osname=mips +$test -d /NextApps && set X `hostinfo | $grep 'NeXT Mach.*:' | \ + $sed -e 's/://' -e 's/\./_/'` && osname=next && osvers=$4 +$test -d /usr/apollo/bin && osname=apollo +$test -f /etc/saf/_sactab && osname=svr4 +$test -d /usr/include/minix && osname=minix +$test -f /system/gnu_library/bin/ar.pm && osname=vos +if $test -d /MachTen -o -d /MachTen_Folder; then + osname=machten + if $test -x /sbin/version; then + osvers=`/sbin/version | $awk '{print $2}' | + $sed -e 's/[A-Za-z]$//'` + elif $test -x /usr/etc/version; then + osvers=`/usr/etc/version | $awk '{print $2}' | + $sed -e 's/[A-Za-z]$//'` + else + osvers="$2.$3" + fi +fi +$test -f /sys/posix.dll && + $test -f /usr/bin/what && + set X `/usr/bin/what /sys/posix.dll` && + $test "$3" = UWIN && + osname=uwin && + osvers="$5" +if $test "X$has_uname" != X; then + set X $myuname + shift + case "$5" in + fps*) osname=fps ;; + mips*) + case "$4" in + umips) osname=umips ;; + *) osname=mips ;; + esac;; + [23]100) osname=mips ;; + next*) osname=next ;; + i386*) + tmp=`/bin/uname -X 2>/dev/null|awk '/3\.2v[45]/{ print $(NF) }'` + if $test "$tmp" != "" -a "$3" = "3.2" -a -f '/etc/systemid'; then + osname='sco' + osvers=$tmp + elif $test -f /etc/kconfig; then + osname=isc + if $test "$lns" = "$ln -s"; then + osvers=4 + elif $contains _SYSV3 /usr/include/stdio.h > /dev/null 2>&1 ; then + osvers=3 + elif $contains _POSIX_SOURCE /usr/include/stdio.h > /dev/null 2>&1 ; then + osvers=2 + fi + fi + tmp='' + ;; + pc*) + if $test -n "$DJGPP"; then + osname=dos + osvers=djgpp + fi + ;; + esac + case "$1" in + aix) osname=aix + tmp=`( (oslevel) 2>/dev/null || echo "not found") 2>&1` + case "$tmp" in + 'not found') osvers="$4"."$3" ;; + '<3240'|'<>3240') osvers=3.2.0 ;; + '=3240'|'>3240'|'<3250'|'<>3250') osvers=3.2.4 ;; + '=3250'|'>3250') osvers=3.2.5 ;; + *) osvers=$tmp;; + esac + ;; + bsd386) osname=bsd386 + osvers=`$uname -r` + ;; + cygwin*) osname=cygwin + osvers="$3" + ;; + *dc.osx) osname=dcosx + osvers="$3" + ;; + dnix) osname=dnix + osvers="$3" + ;; + domainos) osname=apollo + osvers="$3" + ;; + dgux) osname=dgux + osvers="$3" + ;; + dynixptx*) osname=dynixptx + osvers=`echo "$4"|sed 's/^v//'` + ;; + freebsd) osname=freebsd + osvers="$3" ;; + genix) osname=genix ;; + hp*) osname=hpux + osvers=`echo "$3" | $sed 's,.*\.\([0-9]*\.[0-9]*\),\1,'` + ;; + irix*) osname=irix + case "$3" in + 4*) osvers=4 ;; + 5*) osvers=5 ;; + *) osvers="$3" ;; + esac + ;; + linux) osname=linux + case "$3" in + *) osvers="$3" ;; + esac + ;; + MiNT) osname=mint + ;; + netbsd*) osname=netbsd + osvers="$3" + ;; + news-os) osvers="$3" + case "$3" in + 4*) osname=newsos4 ;; + *) osname=newsos ;; + esac + ;; + next*) osname=next ;; + nonstop-ux) osname=nonstopux ;; + openbsd) osname=openbsd + osvers="$3" + ;; + POSIX-BC | posix-bc ) osname=posix-bc + osvers="$3" + ;; + powerux | power_ux | powermax_os | powermaxos | \ + powerunix | power_unix) osname=powerux + osvers="$3" + ;; + qnx) osname=qnx + osvers="$4" + ;; + solaris) osname=solaris + case "$3" in + 5*) osvers=`echo $3 | $sed 's/^5/2/g'` ;; + *) osvers="$3" ;; + esac + ;; + sunos) osname=sunos + case "$3" in + 5*) osname=solaris + osvers=`echo $3 | $sed 's/^5/2/g'` ;; + *) osvers="$3" ;; + esac + ;; + titanos) osname=titanos + case "$3" in + 1*) osvers=1 ;; + 2*) osvers=2 ;; + 3*) osvers=3 ;; + 4*) osvers=4 ;; + *) osvers="$3" ;; + esac + ;; + ultrix) osname=ultrix + osvers="$3" + ;; + osf1|mls+) case "$5" in + alpha) + osname=dec_osf + osvers=`sizer -v | awk '{print $3}' | \ + ./tr '[A-Z]' '[a-z]' | sed 's/^[xvt]//'` + case "$osvers" in + [1-9].[0-9]*) ;; + *) osvers=`echo "$3" | sed 's/^[xvt]//'` ;; + esac + ;; + hp*) osname=hp_osf1 ;; + mips) osname=mips_osf1 ;; + esac + ;; + unixware) osname=svr5 + osvers="$4" + ;; + uts) osname=uts + osvers="$3" + ;; + vos) osvers="$3" + ;; + $2) case "$osname" in + *isc*) ;; + *freebsd*) ;; + svr*) + : svr4.x or possibly later + case "svr$3" in + ${osname}*) + osname=svr$3 + osvers=$4 + ;; + esac + case "$osname" in + svr4.0) + : Check for ESIX + if $test -f /stand/boot ; then + eval `$grep '^INITPROG=[a-z/0-9]*$' /stand/boot` + if $test -n "$INITPROG" -a -f "$INITPROG"; then + isesix=`strings -a $INITPROG | \ + $grep 'ESIX SYSTEM V/386 Release 4.0'` + if $test -n "$isesix"; then + osname=esix4 + fi + fi + fi + ;; + esac + ;; + *) if $test -f /etc/systemid; then + osname=sco + set `echo $3 | $sed 's/\./ /g'` $4 + if $test -f $src/hints/sco_$1_$2_$3.sh; then + osvers=$1.$2.$3 + elif $test -f $src/hints/sco_$1_$2.sh; then + osvers=$1.$2 + elif $test -f $src/hints/sco_$1.sh; then + osvers=$1 + fi + else + case "$osname" in + '') : Still unknown. Probably a generic Sys V. + osname="sysv" + osvers="$3" + ;; + esac + fi + ;; + esac + ;; + *) case "$osname" in + '') : Still unknown. Probably a generic BSD. + osname="$1" + osvers="$3" + ;; + esac + ;; + esac +else + if $test -f /vmunix -a -f $src/hints/news_os.sh; then + (what /vmunix | UU/tr '[A-Z]' '[a-z]') > UU/kernel.what 2>&1 + if $contains news-os UU/kernel.what >/dev/null 2>&1; then + osname=news_os + fi + $rm -f UU/kernel.what + elif $test -d c:/.; then + set X $myuname + osname=os2 + osvers="$5" + fi +fi + : Try to determine whether config.sh was made on this system case "$config_sh" in '') -myuname=`( ($uname -a) 2>/dev/null || hostname) 2>&1` -myuname=`echo $myuname | $sed -e 's/^[^=]*=//' -e 's/\///g' | \ - ./tr '[A-Z]' '[a-z]' | tr '\012' ' '` -newmyuname="$myuname" dflt=n case "$knowitall" in '') if test -f ../config.sh; then if $contains myuname= ../config.sh >/dev/null 2>&1; then - eval "`grep myuname= ../config.sh`" + eval "`$grep myuname= ../config.sh`" fi if test "X$myuname" = "X$newmyuname"; then dflt=y @@ -1503,18 +2260,21 @@ *) dflt=y;; esac -: Get old answers, if there is a config file out there +: Get old answers from config file if it was generated on the same system hint=default -hintfile='' -if test -f ../config.sh; then +if $test -f ../config.sh; then echo " " rp="I see a config.sh file. Shall I use it to set the defaults?" . ./myread case "$ans" in - n*|N*) echo "OK, I'll ignore it.";; + n*|N*) echo "OK, I'll ignore it." + mv ../config.sh ../config.sh.old + myuname="$newmyuname" + ;; *) echo "Fetching default answers from your old config.sh file..." >&4 tmp_n="$n" tmp_c="$c" + tmp_sh="$sh" . ../config.sh cp ../config.sh . n="$tmp_n" @@ -1529,6 +2289,7 @@ echo "Fetching default answers from $config_sh..." >&4 tmp_n="$n" tmp_c="$c" + tmp_sh="$sh" cd .. cp $config_sh config.sh 2>/dev/null chmod +w config.sh @@ -1540,16 +2301,76 @@ hint=previous ;; esac -test "$override" && . ./optdef.sh -myuname="$newmyuname" +case "$sh" in +'') sh="$tmp_sh" ;; +esac +$test "$override" && . ./optdef.sh : Restore computed paths for file in $loclist $trylist; do eval $file="\$_$file" done +. ./checkcc +case "$targetarch" in +'') ;; +*) hostarch=$osname + osname=`echo $targetarch|sed 's,^[^-]*-,,'` + osvers='' + ;; +esac + +: Process their -A options +. ./posthint.sh + +: Ask them to confirm the OS name +cat << EOM + +Configure uses the operating system name and version to set some defaults. +The default value is probably right if the name rings a bell. Otherwise, +since spelling matters for me, either accept the default or answer "none" +to leave it blank. + +EOM +case "$osname" in + ''|' ') + case "$hintfile" in + ''|' '|none) dflt=none ;; + *) dflt=`echo $hintfile | $sed -e 's/\.sh$//' -e 's/_.*$//'` ;; + esac + ;; + *) dflt="$osname" ;; +esac +rp="Operating system name?" +. ./myread +case "$ans" in +none) osname='' ;; +*) osname=`echo "$ans" | $sed -e 's/[ ][ ]*/_/g' | ./tr '[A-Z]' '[a-z]'`;; +esac +echo " " +case "$osvers" in + ''|' ') + case "$hintfile" in + ''|' '|none) dflt=none ;; + *) dflt=`echo $hintfile | $sed -e 's/\.sh$//' -e 's/^[^_]*//'` + dflt=`echo $dflt | $sed -e 's/^_//' -e 's/_/./g'` + case "$dflt" in + ''|' ') dflt=none ;; + esac + ;; + esac + ;; + *) dflt="$osvers" ;; +esac +rp="Operating system version?" +. ./myread +case "$ans" in +none) osvers='' ;; +*) osvers="$ans" ;; +esac + : who configured the system -cf_time=`$date 2>&1` +cf_time=`LC_ALL=C; LANGUAGE=C; export LC_ALL; export LANGUAGE; $date 2>&1` cf_by=`(logname) 2>/dev/null` case "$cf_by" in "") @@ -1639,10 +2460,15 @@ nopath_ok='' orig_rp="$rp" orig_dflt="$dflt" +case "$gfpth" in +'') gfpth='.' ;; +esac case "$fn" in *\(*) - expr $fn : '.*(\(.*\)).*' | tr ',' '\012' >getfile.ok + : getfile will accept an answer from the comma-separated list + : enclosed in parentheses even if it does not meet other criteria. + expr "$fn" : '.*(\(.*\)).*' | $tr ',' $trnl >getfile.ok fn=`echo $fn | sed 's/(.*)//'` ;; esac @@ -1741,6 +2567,7 @@ true) case "$ansexp" in /*) value="$ansexp" ;; + [a-zA-Z]:/*) value="$ansexp" ;; *) redo=true case "$already" in @@ -1765,18 +2592,40 @@ '') case "$type" in File) - if test -f "$ansexp"; then - type='' - elif test -r "$ansexp" || (test -h "$ansexp") >/dev/null 2>&1 - then - echo "($value is not a plain file, but that's ok.)" - type='' - fi + for fp in $gfpth; do + if test "X$fp" = X.; then + pf="$ansexp" + else + pf="$fp/$ansexp" + fi + if test -f "$pf"; then + type='' + elif test -r "$pf" || (test -h "$pf") >/dev/null 2>&1 + then + echo "($value is not a plain file, but that's ok.)" + type='' + fi + if test X"$type" = X; then + value="$pf" + break + fi + done ;; Directory) - if test -d "$ansexp"; then - type='' - fi + for fp in $gfpth; do + if test "X$fp" = X.; then + dir="$ans" + direxp="$ansexp" + else + dir="$fp/$ansexp" + direxp="$fp/$ansexp" + fi + if test -d "$direxp"; then + type='' + value="$dir" + break + fi + done ;; Locate) if test -d "$ansexp"; then @@ -1830,6 +2679,7 @@ rp="$orig_rp" dflt="$orig_dflt" rm -f getfile.ok +test "X$gfpthkeep" != Xy && gfpth="" EOSC : determine root of directory hierarchy where package will be installed. @@ -1895,12 +2745,18 @@ esac;; esac' +: allow them to override the AFS root +case "$afsroot" in +'') afsroot=/afs ;; +*) afsroot=$afsroot ;; +esac + : is AFS running? echo " " case "$afs" in $define|true) afs=true ;; $undef|false) afs=false ;; -*) if test -d /afs; then +*) if $test -d $afsroot; then afs=true else afs=false @@ -1949,7 +2805,8 @@ echo " " case "$sysman" in '') - syspath='/usr/man/man1 /usr/man/mann /usr/man/manl /usr/man/local/man1' + syspath='/usr/share/man/man1 /usr/man/man1' + syspath="$syspath /usr/man/mann /usr/man/manl /usr/man/local/man1" syspath="$syspath /usr/man/u_man/man1 /usr/share/man/man1" syspath="$syspath /usr/catman/u_man/man1 /usr/man/l_man/man1" syspath="$syspath /usr/local/man/u_man/man1 /usr/local/man/l_man/man1" @@ -1986,9 +2843,10 @@ echo "If you don't want the manual sources installed, answer 'none'." case "$mansrc" in '') - lookpath="$prefixexp/man/man1 $prefixexp/man/u_man/man1" - lookpath="$lookpath $prefixexp/man/l_man/man1" + lookpath="$prefixexp/share/man/man1 $prefixexp/man/man1" + lookpath="$lookpath $prefixexp/man/u_man/man1 $prefixexp/man/l_man/man1" lookpath="$lookpath /usr/local/man/man1 /opt/man/man1 /usr/man/manl" + lookpath="$lookpath /usr/share/man/man1 /usr/local/share/man/man1" lookpath="$lookpath /usr/man/local/man1 /usr/man/l_man/man1" lookpath="$lookpath /usr/local/man/u_man/man1 /usr/local/man/l_man/man1" lookpath="$lookpath /usr/man/man.L" @@ -2161,148 +3019,22 @@ . ./getfile perlpath="$ans" -: see what memory models we can support -case "$models" in -'') - $cat >pdp11.c <<'EOP' -main() { -#ifdef pdp11 - exit(0); -#else - exit(1); -#endif -} -EOP - cc -o pdp11 pdp11.c >/dev/null 2>&1 - if ./pdp11 2>/dev/null; then - dflt='unsplit split' - else - tans=`./loc . X /lib/small /lib/large /usr/lib/small /usr/lib/large /lib/medium /usr/lib/medium /lib/huge` - case "$tans" in - X) dflt='none';; - *) if $test -d /lib/small || $test -d /usr/lib/small; then - dflt='small' - else - dflt='' - fi - if $test -d /lib/medium || $test -d /usr/lib/medium; then - dflt="$dflt medium" - fi - if $test -d /lib/large || $test -d /usr/lib/large; then - dflt="$dflt large" - fi - if $test -d /lib/huge || $test -d /usr/lib/huge; then - dflt="$dflt huge" - fi - esac - fi;; -*) dflt="$models";; +: Determine the C compiler to be used +echo " " +case "$cc" in +'') dflt=cc;; +*) dflt="$cc";; esac -$cat <<EOM - -Some systems have different model sizes. On most systems they are called -small, medium, large, and huge. On the PDP11 they are called unsplit and -split. If your system doesn't support different memory models, say "none". -If you wish to force everything to one memory model, say "none" here and -put the appropriate flags later when it asks you for other cc and ld flags. -Venix systems may wish to put "none" and let the compiler figure things out. -(In the following question multiple model names should be space separated.) - -EOM -rp="Which memory models are supported?" +rp="Use which C compiler?" . ./myread -models="$ans" +cc="$ans" -case "$models" in -none) - small='' - medium='' - large='' - huge='' - unsplit='' - split='' - ;; -*split) - case "$split" in - '') if $contains '\-i' $sysman/ld.1 >/dev/null 2>&1 || \ - $contains '\-i' $sysman/cc.1 >/dev/null 2>&1; then - dflt='-i' - else - dflt='none' - fi;; - *) dflt="$split";; - esac - rp="What flag indicates separate I and D space?" - . ./myread - tans="$ans" - case "$tans" in - none) tans='';; - esac - split="$tans" - unsplit='';; -*large*|*small*|*medium*|*huge*) - case "$models" in - *large*) - case "$large" in - '') dflt='-Ml';; - *) dflt="$large";; - esac - rp="What flag indicates large model?" - . ./myread - tans="$ans" - case "$tans" in - none) tans=''; - esac - large="$tans";; - *) large='';; - esac - case "$models" in - *huge*) case "$huge" in - '') dflt='-Mh';; - *) dflt="$huge";; - esac - rp="What flag indicates huge model?" - . ./myread - tans="$ans" - case "$tans" in - none) tans=''; - esac - huge="$tans";; - *) huge="$large";; - esac - case "$models" in - *medium*) case "$medium" in - '') dflt='-Mm';; - *) dflt="$medium";; - esac - rp="What flag indicates medium model?" - . ./myread - tans="$ans" - case "$tans" in - none) tans=''; - esac - medium="$tans";; - *) medium="$large";; - esac - case "$models" in - *small*) case "$small" in - '') dflt='none';; - *) dflt="$small";; - esac - rp="What flag indicates small model?" - . ./myread - tans="$ans" - case "$tans" in - none) tans=''; - esac - small="$tans";; - *) small='';; - esac - ;; -*) - echo "Unrecognized memory models--you may have to edit Makefile.SH" >&4 - ;; -esac +: See whether they have no cc but they do have gcc +. ./trygcc +if $test -f cc.cbu; then + . ./cc.cbu +fi +. ./checkcc : make some quick guesses about what we are up against echo " " @@ -2315,13 +3047,19 @@ echo exit 1 >xenix echo exit 1 >venix echo exit 1 >os2 +echo exit 1 >gnu +echo exit 1 >linux +echo exit 1 >dos d_bsd="$undef" +d_linux="$undef" +d_dos="$undef" +d_os2="$undef" $cat /usr/include/signal.h /usr/include/sys/signal.h >foo 2>/dev/null if test -f /osf_boot || $contains 'OSF/1' /usr/include/ctype.h >/dev/null 2>&1 then echo "Looks kind of like an OSF/1 system, but we'll see..." echo exit 0 >osf1 -elif test `echo abc | tr a-z A-Z` = Abc ; then +elif test `echo abc | $tr a-z A-Z` = Abc ; then xxx=`./loc addbib blurfl $pth` if $test -f $xxx; then echo "Looks kind of like a USG system with BSD features, but we'll see..." @@ -2339,6 +3077,17 @@ echo "Looks kind of like a BSD system, but we'll see..." d_bsd="$define" echo exit 0 >bsd +elif + $rm --version 2>/dev/null >foo; + $contains "Free Software Foundation" foo >/dev/null +then + xxx=`uname` + echo exit 0 >gnu + echo "Looks kind of like a GNU/$xxx system, but we'll see..." + if $test X$xxx = XLinux; then + d_linux="$define" + echo exit 0 >linux + fi else echo "Looks kind of like a Version 7 system, but we'll see..." echo exit 0 >v7 @@ -2364,9 +3113,21 @@ *) $cat <<'EOI' I have the feeling something is not exactly right, however...don't tell me... +EOI + if test -n "$DJGPP"; then + case "X${MACHTYPE:-nonesuchmach}" in + cygwin) echo "hah!... you're running under Cygwin!";; + *) echo "got it... you're running DOS with DJGPP!";; + esac + echo exit 0 >dos + d_dos="$define" + else + $cat <<'EOI' lemme think...does HAL ring a bell?...no, of course, you're only running OS/2! EOI - echo exit 0 >os2 + echo exit 0 >os2 + d_os2="$define" + fi ;; esac if test -f /xenix; then @@ -2391,55 +3152,14 @@ echo "Nor is it Venix..." fi fi -chmod +x bsd usg v7 osf1 eunice xenix venix os2 -$eunicefix bsd usg v7 osf1 eunice xenix venix os2 +chmod +x bsd usg v7 osf1 eunice xenix venix dos os2 gnu linux +$eunicefix bsd usg v7 osf1 eunice xenix venix dos os2 gnu linux $rm -f foo -: see if we need a special compiler +: Check whether they have gcc in any guise. echo " " -if ./usg; then - case "$cc" in - '') case "$Mcc" in - /*) dflt='Mcc';; - *) case "$large" in - -M*) dflt='cc';; - *) if $contains '\-M' $sysman/cc.1 >/dev/null 2>&1 ; then - if $contains '\-M' $sysman/cpp.1 >/dev/null 2>&1; then - dflt='cc' - else - dflt='cc -M' - fi - else - dflt='cc' - fi;; - esac;; - esac;; - *) dflt="$cc";; - esac - $cat <<'EOM' -On some systems the default C compiler will not resolve multiple global -references that happen to have the same name. On some such systems the "Mcc" -command may be used to force these to be resolved. On other systems a "cc -M" -command is required. (Note that the -M flag on other systems indicates a -memory model to use!) If you have the Gnu C compiler, you might wish to use -that instead. - -EOM - rp="What command will force resolution on this system?" - . ./myread - cc="$ans" -else - case "$cc" in - '') dflt=cc;; - *) dflt="$cc";; - esac - rp="Use which C compiler?" - . ./myread - cc="$ans" -fi -echo " " echo "Checking for GNU cc in disguise and/or its version number..." >&4 -$cat >gccvers.c <<EOM +$cat >try.c <<EOM #include <stdio.h> int main() { #ifdef __GNUC__ @@ -2452,11 +3172,13 @@ exit(0); } EOM -if $cc -o gccvers gccvers.c >/dev/null 2>&1; then - gccversion=`./gccvers` +if $cc -o try $ccflags $ldflags try.c >/dev/null 2>&1; then + gccversion=`$run ./try` case "$gccversion" in '') echo "You are not using GNU cc." ;; - *) echo "You are using GNU cc $gccversion." ;; + *) echo "You are using GNU cc $gccversion." + ccname=gcc + ;; esac else echo " " @@ -2469,11 +3191,58 @@ ;; esac fi -$rm -f gccvers* +$rm -f try try.* case "$gccversion" in 1*) cpp=`./loc gcc-cpp $cpp $pth` ;; esac +case "$gccversion" in +'') gccosandvers='' ;; +*) gccshortvers=`echo "$gccversion"|sed 's/ .*//'` + gccosandvers=`$cc -v 2>&1 | \ + $grep '/specs$'|sed "s!.*/[^-/]*-[^-/]*-\([^-/]*\)/$gccshortvers/specs!\1!"` + gccshortvers='' + case "$gccosandvers" in + $osname) gccosandvers='' ;; # linux gccs seem to have no linux osvers, grr + $osname$osvers) ;; # looking good + $osname*) cat <<EOM >&4 +*** WHOA THERE!!! *** + + Your gcc has not been compiled for the exact release of + your operating system ($gccosandvers versus $osname$osvers). + + In general it is a good idea to keep gcc synchronized with + the operating system because otherwise serious problems + may ensue when trying to compile software, like Perl. + + I'm trying to be optimistic here, though, and will continue. + If later during the configuration and build icky compilation + problems appear (headerfile conflicts being the most commo... [truncated message content] |
From: <rma...@us...> - 2008-05-30 09:30:20
|
Revision: 23 http://mailagent.svn.sourceforge.net/mailagent/?rev=23&view=rev Author: rmanfredi Date: 2008-05-30 02:30:12 -0700 (Fri, 30 May 2008) Log Message: ----------- This is now version 3.1. The patchlevel is now ignored, as we track by SVN revision number. Changed all version information reporting to new format "version-revision". Modified Paths: -------------- trunk/mailagent/agent/edusers.SH trunk/mailagent/agent/filter/main.c trunk/mailagent/agent/magent.sh trunk/mailagent/agent/maildist.SH trunk/mailagent/agent/mailhelp.SH trunk/mailagent/agent/maillist.SH trunk/mailagent/agent/mailpatch.SH trunk/mailagent/agent/package.SH trunk/mailagent/agent/pl/sendfile.pl trunk/mailagent/agent/test/option/V.t trunk/mailagent/patchlevel.h Modified: trunk/mailagent/agent/edusers.SH =================================================================== --- trunk/mailagent/agent/edusers.SH 2008-05-30 09:12:22 UTC (rev 22) +++ trunk/mailagent/agent/edusers.SH 2008-05-30 09:30:12 UTC (rev 23) @@ -43,6 +43,7 @@ \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; +\$revision = '$REVISION'; \$defeditor = '$defeditor'; \$phostname = '$phostname'; \$long_filenames = '$d_flexfnam' eq 'define'; Modified: trunk/mailagent/agent/filter/main.c =================================================================== --- trunk/mailagent/agent/filter/main.c 2008-05-30 09:12:22 UTC (rev 22) +++ trunk/mailagent/agent/filter/main.c 2008-05-30 09:30:12 UTC (rev 23) @@ -77,6 +77,7 @@ #include "lock.h" #include "confmagic.h" #include "patchlevel.h" +#include "revision.h" #define MAX_STRING 2048 /* Maximum string length */ @@ -144,7 +145,7 @@ env_home(); /* Get HOME from environment */ break; case 'V': /* version number */ - printf("filter %.1f PL%d\n", VERSION, PATCHLEVEL); + printf("filter %.1f-%d\n", VERSION, REVISION); exit(EX_OK); /* NOTRECHED */ default: Modified: trunk/mailagent/agent/magent.sh =================================================================== --- trunk/mailagent/agent/magent.sh 2008-05-30 09:12:22 UTC (rev 22) +++ trunk/mailagent/agent/magent.sh 2008-05-30 09:30:12 UTC (rev 23) @@ -129,6 +129,7 @@ # Current version number and patchlevel \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; +\$revision = '$REVISION'; # Want to lock mailboxes with flock ? \$lock_by_flock = '$lock_by_flock'; @@ -238,7 +239,7 @@ $log_level = int(shift); } elsif ($_ eq '-V') { # Version number - print STDERR "$prog_name $mversion PL$patchlevel\n"; + print STDERR "$prog_name $mversion-$revision\n"; exit 0; } elsif ($_ eq '-U') { # Do not allow UNIQUE to reject / abort @@ -506,9 +507,9 @@ # The filter message local($address) = &email_addr; $FILTER = - "X-Filter: mailagent [version $mversion PL$patchlevel] for $address"; + "X-Filter: mailagent [version $mversion-$revision] for $address"; $MAILER = - "X-Mailer: mailagent [version $mversion PL$patchlevel]"; + "X-Mailer: mailagent [version $mversion-$revision]"; # For header fields alteration $HD_STRIP = 0; # Strip header fields Modified: trunk/mailagent/agent/maildist.SH =================================================================== --- trunk/mailagent/agent/maildist.SH 2008-05-30 09:12:22 UTC (rev 22) +++ trunk/mailagent/agent/maildist.SH 2008-05-30 09:30:12 UTC (rev 23) @@ -54,6 +54,7 @@ \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; +\$revision = '$REVISION'; !GROK!THIS! $spitshell >>maildist <<'!NO!SUBS!' @@ -102,7 +103,7 @@ print MAILER "To: $path Subject: No program called $system -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] I don't know how to send a program called \"$system\". Sorry. @@ -127,7 +128,7 @@ print MAILER "To: $path Subject: No version $version for $system -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] I don't know how to send version $version of $system. Sorry. @@ -157,7 +158,7 @@ print MAILER "To: $path Subject: System $system $version is obsolete -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] I can't send you version $version of $system. Sorry. @@ -187,7 +188,7 @@ print MAILER "To: $path Subject: Version $version of $system is an old one -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] You asked for version $version of $system. Modified: trunk/mailagent/agent/mailhelp.SH =================================================================== --- trunk/mailagent/agent/mailhelp.SH 2008-05-30 09:12:22 UTC (rev 22) +++ trunk/mailagent/agent/mailhelp.SH 2008-05-30 09:30:12 UTC (rev 23) @@ -46,6 +46,7 @@ \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; +\$revision = '$REVISION'; !GROK!THIS! $spitshell >>mailhelp <<'!NO!SUBS!' @@ -77,7 +78,7 @@ print MAILER "To: $dest Subject: How to use my mail agent -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] "; while (<HELP>) { Modified: trunk/mailagent/agent/maillist.SH =================================================================== --- trunk/mailagent/agent/maillist.SH 2008-05-30 09:12:22 UTC (rev 22) +++ trunk/mailagent/agent/maillist.SH 2008-05-30 09:30:12 UTC (rev 23) @@ -56,6 +56,7 @@ \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; +\$revision = '$REVISION'; \$phostname = '$phostname'; !GROK!THIS! @@ -98,7 +99,7 @@ print XHEAD "To: $dest Subject: List of available distributions -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] Here are the different packages available. If you want the whole distribution, send me the following: Modified: trunk/mailagent/agent/mailpatch.SH =================================================================== --- trunk/mailagent/agent/mailpatch.SH 2008-05-30 09:12:22 UTC (rev 22) +++ trunk/mailagent/agent/mailpatch.SH 2008-05-30 09:30:12 UTC (rev 23) @@ -58,6 +58,7 @@ \$zcat = '$zcat'; \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; +\$revision = '$REVISION'; !GROK!THIS! $spitshell >>mailpatch <<'!NO!SUBS!' @@ -105,7 +106,7 @@ print MAILER "To: $path Subject: No program called $system -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] I don't know how to send patches for a program called $system. Sorry. @@ -130,7 +131,7 @@ print MAILER "To: $path Subject: No patches for $system version $version -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] I don't know how to send patches for version $version of $system. Sorry."; if ($Version{$system} ne '') { @@ -168,7 +169,7 @@ print MAILER "To: $path Subject: $system version $version is not maintained -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] I can't send you patches for version $version of $system, because this code is not maintained by $cf'name. There are no official patches available either... @@ -246,7 +247,7 @@ print MAILER "To: $path Subject: No patches yet for $system version $version -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] There are no patches (yet) for $system version $version. Sorry. @@ -271,7 +272,7 @@ print MAILER "To: $path Subject: Invalid patch request for $system $version -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] "; if ($Patches{$pname}) { print MAILER " Modified: trunk/mailagent/agent/package.SH =================================================================== --- trunk/mailagent/agent/package.SH 2008-05-30 09:12:22 UTC (rev 22) +++ trunk/mailagent/agent/package.SH 2008-05-30 09:30:12 UTC (rev 23) @@ -76,6 +76,7 @@ \$zcat = '$zcat'; \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; +\$revision = '$REVISION'; \$phostname = '$phostname'; \$long_filenames = '$d_flexfnam' eq 'define'; !GROK!THIS! @@ -133,7 +134,7 @@ print MAILER "To: $path Subject: No program called $system -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] I have not heard of a program called $system. Sorry. @@ -154,7 +155,7 @@ print MAILER "To: $path Subject: No package $system version $version -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] I don't know anything about version $version of $system. Sorry."; if ($Version{$system} ne '') { @@ -189,7 +190,7 @@ print MAILER "To: $path Subject: Version $version of $system is out-of-date -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] This short note to warn you that $system version $version is not the lattest one available. If you have some interest in $system, I suggest @@ -216,7 +217,7 @@ print MAILER "To: $path Subject: $system version $version is not maintained -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] I can't keep you up to date on changes to version $version of $system, because this code is not maintained by $cf'name. @@ -246,7 +247,7 @@ print MAILER "To: $path Subject: I didn't understand your package command -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] Your package command requested `$request', and I don't know what that means. @@ -302,7 +303,7 @@ print MAILER "To: $dest Subject: The latest patchlevel for $system version $version is $maxnum -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] Just a quick note to let you know that the latest patchlevel for $system version $version is $maxnum; if you are still at patchlevel $theirpl, I strongly @@ -429,7 +430,7 @@ print MAILER "To: $path Subject: You were not recorded as a $system $version user -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] I can't honour your desire to be left alone for $system version $version updates because you were not found among the registered users. Modified: trunk/mailagent/agent/pl/sendfile.pl =================================================================== --- trunk/mailagent/agent/pl/sendfile.pl 2008-05-30 09:12:22 UTC (rev 22) +++ trunk/mailagent/agent/pl/sendfile.pl 2008-05-30 09:30:12 UTC (rev 23) @@ -149,7 +149,7 @@ "To: $dest Subject: $subject$signal Precedence: bulk -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] Here is the answer to your request: @@ -303,7 +303,7 @@ print MAILER "To: $path Subject: $cmd failed -X-Mailer: mailagent [version $mversion PL$patchlevel] +X-Mailer: mailagent [version $mversion-$revision] Sorry, the $prog_name command failed while sending files. Modified: trunk/mailagent/agent/test/option/V.t =================================================================== --- trunk/mailagent/agent/test/option/V.t 2008-05-30 09:12:22 UTC (rev 22) +++ trunk/mailagent/agent/test/option/V.t 2008-05-30 09:30:12 UTC (rev 23) @@ -18,5 +18,5 @@ do '../pl/init.pl'; $version = `$mailagent -V 2>&1`; $? == 0 || print "1\n"; -$version =~ /PL/ || print "2\n"; +$version =~ /^mailagent \d+\.\d+-\d+/ || print "2\n"; print "0\n"; Modified: trunk/mailagent/patchlevel.h =================================================================== --- trunk/mailagent/patchlevel.h 2008-05-30 09:12:22 UTC (rev 22) +++ trunk/mailagent/patchlevel.h 2008-05-30 09:30:12 UTC (rev 23) @@ -1,4 +1,5 @@ /* mailagent-3.0 - 1 Dec 1993 */ +/* mailagent-3.1 - 2008-05-30 */ -#define VERSION 3.0 -#define PATCHLEVEL 73 +#define VERSION 3.1 +#define PATCHLEVEL 0 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-05-30 09:45:17
|
Revision: 25 http://mailagent.svn.sourceforge.net/mailagent/?rev=25&view=rev Author: rmanfredi Date: 2008-05-30 02:45:13 -0700 (Fri, 30 May 2008) Log Message: ----------- This is now mailagent 3.1. Modified Paths: -------------- trunk/mailagent/README trunk/mailagent/revision.h Modified: trunk/mailagent/README =================================================================== --- trunk/mailagent/README 2008-05-30 09:43:23 UTC (rev 24) +++ trunk/mailagent/README 2008-05-30 09:45:13 UTC (rev 25) @@ -1,6 +1,6 @@ - mailagent 3.0 + mailagent 3.1 - Copyright (c) 1990-2001, Raphael Manfredi + Copyright (c) 1990-2008, Raphael Manfredi ------------------------------------------------------------------------ This program is free software; you can redistribute it and/or modify Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-05-30 09:43:23 UTC (rev 24) +++ trunk/mailagent/revision.h 2008-05-30 09:45:13 UTC (rev 25) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 21 +#define REVISION 24 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-02 15:27:41
|
Revision: 26 http://mailagent.svn.sourceforge.net/mailagent/?rev=26&view=rev Author: rmanfredi Date: 2008-06-02 08:27:03 -0700 (Mon, 02 Jun 2008) Log Message: ----------- Was wrongly handling patterns in rules given under the form m|something| where "something" was containing a "/" character... This led to an error message stating the pattern was incorrect... Also fixed pattern compilation error reports to remove the "(eval 124)" part that modern perl 5.x report in $@ (mailagent was still stripping the older perl 4.x form of eval addition). Modified Paths: -------------- trunk/mailagent/agent/magent.sh trunk/mailagent/agent/pl/matching.pl trunk/mailagent/agent/test/TEST trunk/mailagent/agent/test/rules trunk/mailagent/revision.h Modified: trunk/mailagent/agent/magent.sh =================================================================== --- trunk/mailagent/agent/magent.sh 2008-05-30 09:45:13 UTC (rev 25) +++ trunk/mailagent/agent/magent.sh 2008-06-02 15:27:03 UTC (rev 26) @@ -752,7 +752,8 @@ # Report any eval error and returns 1 if error detected. sub eval_error { if ($@ ne '') { - $@ =~ s/ in file \(eval\) at line \d+//; + $@ =~ s/ in file \(eval\) at line \d+//; # Older perls + $@ =~ s/ at \(eval \d+\) line \d+\.//; # Modern perl 5.x chop($@); &add_log("ERROR $@") if $loglvl > 1; } Modified: trunk/mailagent/agent/pl/matching.pl =================================================================== --- trunk/mailagent/agent/pl/matching.pl 2008-05-30 09:45:13 UTC (rev 25) +++ trunk/mailagent/agent/pl/matching.pl 2008-06-02 15:27:03 UTC (rev 26) @@ -80,15 +80,11 @@ } # Take a pattern as written in the rule file and make it suitable for -# pattern matching as understood by perl. If the pattern starts with a -# leading /, nothing is done. Otherwise, a set of / are added. -# match (1st case). +# pattern matching as understood by perl. Unless the pattern starts with a +# leading / or is of the form m||, it is enclosed within slashes. +# We also enclose the whole pattern within (). sub make_pattern { local($_) = shift(@_); - unless (m|^/|) { # Pattern does not start with a / - $_ = &perl_pattern($_); # Simple words specified via shell patterns - $_ = "/^$_\$/"; # Anchor pattern - } # The whole pattern is inserted within () to make at least one # backreference. Otherwise, the following could happen: # $_ = '1 for you'; @@ -98,7 +94,15 @@ # determine whether it is due to a backreference (2nd case) or a sucessful # match. Knowing we have at least one bracketed reference is enough to # disambiguate. - s|^/(.*)/|/($1)/|; # Enclose whole pattern within () + if (/^m(\W)(.*)\1(\w*)$/) { + $_ = "m$1($2)$1$3"; + } elsif (m|^/(.*)/(\w*)$|) { + $_ = "/($1)/$2"; + } else { + # Pattern does not start with a / or is not of the form m|xxx| + $_ = &perl_pattern($_); # Simple words specified via shell patterns + $_ = "/^($_)\$/"; # Anchor pattern + } $_; # Pattern suitable for eval'ed matching } Modified: trunk/mailagent/agent/test/TEST =================================================================== --- trunk/mailagent/agent/test/TEST 2008-05-30 09:45:13 UTC (rev 25) +++ trunk/mailagent/agent/test/TEST 2008-06-02 15:27:03 UTC (rev 26) @@ -105,8 +105,9 @@ if (@ARGV) { foreach my $file (@ARGV) { run_file($file); - exit($failed ? 1 : 0) ; + exit(1) if $failed && $opt_s; } + exit($failed ? 1 : 0) ; } open(OK, ">>OK"); Modified: trunk/mailagent/agent/test/rules =================================================================== --- trunk/mailagent/agent/test/rules 2008-05-30 09:45:13 UTC (rev 25) +++ trunk/mailagent/agent/test/rules 2008-06-02 15:27:03 UTC (rev 26) @@ -180,10 +180,10 @@ <RANGE> To Cc <1, 2>: must { SAVE always.3; REJECT }; <RANGE> To Cc <3, 1>: ram { SAVE never.2; REJECT }; <RANGE> Body <-, 3>: /SIGPLAN/ { SAVE never.3; REJECT }; -<RANGE> Body <-, ->: /SIGPLAN/ { SAVE always.4; REJECT }; -<RANGE> Body <9, 9>: /SIGPLAN/ { SAVE always.5; REJECT }; +<RANGE> Body <-, ->: /SIGpLAN/i { SAVE always.4; REJECT }; +<RANGE> Body <9, 9>: m|SI\w+N| { SAVE always.5; REJECT }; <RANGE> Body <9, 9>: /CD-ROM/ { SAVE never.4; REJECT }; -<RANGE> Body <13, 14>: /something/ { SAVE always.6; REJECT }; +<RANGE> Body <13, 14>: m,something, { SAVE always.6; REJECT }; <RANGE> Body <-3, ->: /Regards/ { SAVE always.7; REJECT }; <RANGE> Cc <-1, ->: made { SAVE always.8; REJECT }; <RANGE> Body <-3, ->: /request/ { SAVE never.5; REJECT }; Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-05-30 09:45:13 UTC (rev 25) +++ trunk/mailagent/revision.h 2008-06-02 15:27:03 UTC (rev 26) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 24 +#define REVISION 25 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-03 11:38:47
|
Revision: 27 http://mailagent.svn.sourceforge.net/mailagent/?rev=27&view=rev Author: rmanfredi Date: 2008-06-03 04:38:43 -0700 (Tue, 03 Jun 2008) Log Message: ----------- Now parses the following Received line: Received: from ?host1? ([xx.yy.zz.tt]) by host3 Modified Paths: -------------- trunk/mailagent/agent/pl/parse.pl trunk/mailagent/revision.h Modified: trunk/mailagent/agent/pl/parse.pl =================================================================== --- trunk/mailagent/agent/pl/parse.pl 2008-06-02 15:27:03 UTC (rev 26) +++ trunk/mailagent/agent/pl/parse.pl 2008-06-03 11:38:43 UTC (rev 27) @@ -297,6 +297,7 @@ # # Received: from host1 (host2 [xx.yy.zz.tt]) by host3 # Received: from host1 ([xx.yy.zz.tt]) by host3 +# Received: from ?host1? ([xx.yy.zz.tt]) by host3 # Received: from host1 by host3 # Received: from (host2 [xx.yy.zz.tt]) by host3 # Received: from (host1) [xx.yy.zz.tt] by host3 @@ -393,6 +394,10 @@ if (s/^(\[\d+\.\d+\.\d+\.\d+\])\s*//) { $host = $1; # IP address [xx.yy.zz.tt] } + # ?xx.yy.zz.tt? ( [XX.YY.ZZ.TT]) + elsif (s/^\?[\d\.]+\?\s*\(\s*(\[\d+\.\d+\.\d+\.\d+\])\s*\)\s*//) { + $host = $1; + } # foo.domain.com (optional) elsif (s/^([\w-.]+)(\(\S+\))?\s*//) { $host = $1; # host name Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-06-02 15:27:03 UTC (rev 26) +++ trunk/mailagent/revision.h 2008-06-03 11:38:43 UTC (rev 27) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 25 +#define REVISION 26 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-06 12:01:12
|
Revision: 34 http://mailagent.svn.sourceforge.net/mailagent/?rev=34&view=rev Author: rmanfredi Date: 2008-06-06 05:00:59 -0700 (Fri, 06 Jun 2008) Log Message: ----------- Fixed earlier commit mistake in new state logging. Modified Paths: -------------- trunk/mailagent/agent/pl/actions.pl trunk/mailagent/revision.h Modified: trunk/mailagent/agent/pl/actions.pl =================================================================== --- trunk/mailagent/agent/pl/actions.pl 2008-06-06 11:49:48 UTC (rev 33) +++ trunk/mailagent/agent/pl/actions.pl 2008-06-06 12:00:59 UTC (rev 34) @@ -1826,7 +1826,7 @@ return 0 if $opt'sw_t && $lastcmd != 0; return 0 if $opt'sw_f && $lastcmd == 0; if ($mode ne '') { - &add_log("entering new state $wmode") if $loglvl > 6 && $mode ne $wmode; + &add_log("entering new state $mode") if $loglvl > 6 && $mode ne $wmode; $wmode = $mode; } &perform; # This was dynamically bound Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-06-06 11:49:48 UTC (rev 33) +++ trunk/mailagent/revision.h 2008-06-06 12:00:59 UTC (rev 34) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 32 +#define REVISION 33 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-13 09:32:28
|
Revision: 38 http://mailagent.svn.sourceforge.net/mailagent/?rev=38&view=rev Author: rmanfredi Date: 2008-06-13 02:32:24 -0700 (Fri, 13 Jun 2008) Log Message: ----------- Added support for transfer-encoded bodies: mailagent will now decode these bodies before giving them to PASS and GIVE, and will transparently recode the body when the Content-Transfer-Encoding header is changed (at RESYNC time). Also added automatic RESYNC when coming back from a command that requires feedback (such as FEED or PURIFY). The supported encodings are: base64 and quoted-printable. Modified Paths: -------------- trunk/mailagent/MANIFEST trunk/mailagent/agent/magent.sh trunk/mailagent/agent/man/mailagent.SH trunk/mailagent/agent/pl/actions.pl trunk/mailagent/agent/pl/analyze.pl trunk/mailagent/agent/pl/builtins.pl trunk/mailagent/agent/pl/filter.pl trunk/mailagent/agent/pl/matching.pl trunk/mailagent/agent/pl/parse.pl trunk/mailagent/agent/pl/pqueue.pl trunk/mailagent/agent/pl/runcmd.pl trunk/mailagent/agent/test/actions trunk/mailagent/agent/test/cmd/feed.t trunk/mailagent/agent/test/cmd/give.t trunk/mailagent/agent/test/cmd/pass.t trunk/mailagent/agent/test/cmd/purify.t trunk/mailagent/agent/test/pl/mail.pl trunk/mailagent/agent/test/rules trunk/mailagent/revision.h Added Paths: ----------- trunk/mailagent/agent/pl/base64.pl trunk/mailagent/agent/pl/qp.pl trunk/mailagent/agent/test/base64 trunk/mailagent/agent/test/filter/base64.t trunk/mailagent/agent/test/filter/qp.t trunk/mailagent/agent/test/qp Modified: trunk/mailagent/MANIFEST =================================================================== --- trunk/mailagent/MANIFEST 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/MANIFEST 2008-06-13 09:32:24 UTC (rev 38) @@ -113,6 +113,7 @@ agent/pl/add_log.pl Perl library to add logs to logfile agent/pl/addr.pl Approximate address matching and validation agent/pl/analyze.pl Perl library analyzing the incoming mail +agent/pl/base64.pl Simple base64 encoder/decoder agent/pl/biff.pl Built-in biffing support agent/pl/builtins.pl Perl library dealing with builtins agent/pl/callout.pl Perl library to handle callout queue @@ -163,6 +164,7 @@ agent/pl/power.pl Power management for mail server agent/pl/pqueue.pl Processing the queued mails agent/pl/q.pl Quote removal function +agent/pl/qp.pl Simple quoted-printable encoder/decoder agent/pl/queue_mail.pl Queuing mails agent/pl/rangeargs.pl Perl library to expand a list of patches agent/pl/read_conf.pl Perl library to read configuration file @@ -188,6 +190,7 @@ agent/test/TEST Runs the full test suite agent/test/actions Rule file for cmd tests agent/test/atail Active monitoring of the out/agentlog file +agent/test/base64 Sample base64 encoded email agent/test/basic/ Basic tests agent/test/basic/config.t Main test initialization and sanity checks agent/test/basic/filter.t Make sure C filter works @@ -246,6 +249,7 @@ agent/test/filter/ Testing the filtering capabilities agent/test/filter/address.t Test various match patterns on address fields agent/test/filter/backref.t Check backreferences +agent/test/filter/base64.t Check base64 decoding of mail body agent/test/filter/case.t Normalized header case tests agent/test/filter/default.t Check default behaviour when mail not saved agent/test/filter/escape.t Escape sequences within actions @@ -258,6 +262,7 @@ agent/test/filter/multiple.t Check multiple selectors agent/test/filter/not.t Negated pattern tests agent/test/filter/pattern.t Check patterns specification and loading +agent/test/filter/qp.t Check quoted-printable decoding of mail body agent/test/filter/range.t Selector range tests agent/test/filter/status.t Action status updating tests agent/test/level Default logging level for tests @@ -272,8 +277,8 @@ agent/test/option/F.t Test -F option agent/test/option/I.t Test -I option agent/test/option/L.t Test -L option +agent/test/option/U.t Test -U option agent/test/option/V.t Test -V option -agent/test/option/U.t Test -U option agent/test/option/c.t Test -c option agent/test/option/d.t Test -d option agent/test/option/e.t Test -e option @@ -295,6 +300,7 @@ agent/test/pl/mail.pl Modifies mail components agent/test/pl/misc.pl Set up for miscellaneous tests agent/test/pl/mta.pl Trivial MTA and NTA for tests +agent/test/qp Sample quoted-printable encoded email agent/test/rules Rules used by filtering tests bin/ Directory for uninstalled binaries bin/perload The dataloading/autoloading perl translator Modified: trunk/mailagent/agent/magent.sh =================================================================== --- trunk/mailagent/agent/magent.sh 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/magent.sh 2008-06-13 09:32:24 UTC (rev 38) @@ -546,9 +546,10 @@ # List of special header keys which do not represent a true header field. sub init_pseudokey { %Pseudokey = ( - 'Body', 1, - 'Head', 1, - 'All', 1 + 'Body', 1, # Body of message + 'Head', 1, # Header of message + 'All', 1, # Concatenation of Header, "\n", Body + '=Body=', 1, # Reference to body with decoded transfer encoding ); } @@ -824,5 +825,7 @@ $grep -v '^;#' pl/rulenv.pl >>magent $grep -v '^;#' pl/options.pl >>magent $grep -v '^;#' pl/install.pl >>magent +$grep -v '^;#' pl/base64.pl >>magent +$grep -v '^;#' pl/qp.pl >>magent chmod 755 magent $eunicefix magent Modified: trunk/mailagent/agent/man/mailagent.SH =================================================================== --- trunk/mailagent/agent/man/mailagent.SH 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/man/mailagent.SH 2008-06-13 09:32:24 UTC (rev 38) @@ -1908,10 +1908,14 @@ .TP FEED \fIprogram\fR Feed the whole message to a program and get the output back as the new -message. The header structure used by the rules is not updated: an explicit -RESYNC is necessary. Hence the program appears as a filter for the whole -message. It does not tag the message as having been saved. +message. Hence the program appears as a filter for the whole +message. It does not tag the message as having been saved. A RESYNC +is automatically done upon return. (Returns the status of \fIprogram\fR) +.sp +.B WARNING: +Your program must be able to properly parse a MIME message and must deal +with transfer-encoded bodies by itself. .TP FORWARD \fIaddress(es)\fR Forward mail to the specified address(es). This acts as if a save had been @@ -1926,6 +1930,18 @@ input. Any output is mailed to the user who runs the \fImailagent\fR. Note that the message is not tagged as having been saved. (Returns the status of \fIprogram\fR) +.sp +.B NOTE: +If the message had a body that was encoded for transport (using one of +the base64 or quoted-printable transfer encoding), mailagent will +transparently decode it and supply a version that can be properly handled. +In other words, the program does not need to care about the body being +encoded in the message, as it will get a plain one. (Since no headers +are supplied, this is the only possible option). +.sp +Caution though for MIME messages: you should use PIPE for them to give a +chance to the program to properly handle the body, but then it needs to be +fully MIME-aware. .TP KEEP \fIheader_fields_list\fR Keeps only the corresponding lines in the header of the mail. For instance, @@ -2003,6 +2019,17 @@ back from the output of the program. Note that the message is not tagged as having been saved. (Returns the status of \fIprogram\fR) +.sp +.B NOTE: +If the message had a body that was encoded for transport (using one of +the base64 or quoted-printable transfer encoding), mailagent will +transparently decode it and supply a version that can be properly handled. +The body generated by the program will then be automatically encoded back +using the same transfer encoding. +.sp +Caution though for MIME messages: you should use FEED for them to give a +chance to the program to properly handle the body, but then it needs to be +fully MIME-aware. .TP PERL \fIscript\fR [\fIarguments\fR] Escape to a perl \fIscript\fR to perform some actions on the message. This @@ -2017,6 +2044,10 @@ explicitly DELETE it if piping was enough and it did not fail: "REJECT -f" is your friend here to avoid unwanted deletion. (Returns the status of \fIprogram\fR) +.sp +.B WARNING: +Your program must be able to properly parse a MIME message and must deal +with transfer-encoded bodies by itself. .TP POST [\fB\-lb\fR] \fInewsgroup(s)\fR Post the message to the specified newsgroup(s) after having cleaned-up the @@ -2066,11 +2097,18 @@ (Does not alter execution status) .TP PURIFY \fIprogram\fR -Feed the header into a program and get new header back. No RESYNC is done. +Feed the header into a program and get new header back. RESYNC is done +automatically upon return. This may be used to indeed purify the header by removing all the verbose stuff added by so many mail transport agents (X-400 like lines for instance). Obviously, this does not flag the message as having been saved. (Returns the status of \fIprogram\fR) +.sp +If your program removes the Content-Transfer-Encoding header in a MIME message, +mailagent will properly transform the message to have a non-encoded body. +If you change the value of the Content-Transfer-Encoding header, mailagent +will also correctly recode the body for you. The only supported encodings +are base64 and quoted-printable. .TP QUEUE Queue mail again. A successful queuing counts as if mail has been saved. @@ -2123,8 +2161,17 @@ .TP RESYNC Re-synchronize header used for matching with the header of the mail. This is -probably useful only when a FEED command was run. +probably useful only when a SUBST or ANNOTATE command was run. (Does not alter execution status) +.sp +.B NOTE: +At RESYNC time, mailagent will check whether the Content-Transfer-Encoding +header was changed and will transparently recode the body if required, so +that the whole message remains valid despite header mangling. It will also +take care of updating Content-Length if required. Whenever you do change +these important headers via SUBST or ANNOTATE, be sure to call RESYNC before +disposing of the message or you run the risk of saving a corrupted version +that will not be properly understood by your mail user agent. .TP RUN \fIprogram\fR Run the specified program and mail any output to the user who runs Modified: trunk/mailagent/agent/pl/actions.pl =================================================================== --- trunk/mailagent/agent/pl/actions.pl 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/pl/actions.pl 2008-06-13 09:32:24 UTC (rev 38) @@ -1238,8 +1238,8 @@ select(STDOUT); # Now feed the program with the mail - if ($input == $BODY_INPUT) { # Pipes body - print WRITE $Header{'Body'}; + if ($input == $BODY_INPUT) { # Pipes *decoded* body + print WRITE ${$Header{'=Body='}}; } elsif ($input == $MAIL_INPUT) { # Pipes the whole mail print WRITE $Header{'All'}; } elsif ($input == $HEADER_INPUT) { # Pipes the header @@ -1367,6 +1367,21 @@ close TRACE; $Header{'Body'} = $temp unless $input == $HEADER_INPUT; $Header{'All'} = $Header{'Head'} . "\n" . $Header{'Body'}; + if ($input == $BODY_INPUT) { + # Was fed *decoded* body, got at decoded body back. + # Headers have not changed, recoding will happen as in the original + &body_recode; + &header_update_size; + } elsif ($input == $MAIL_INPUT) { + # Headers could have changed and we need to reparse them in order + # to know how/whether we should decode the body. + &header_resync; + &body_check; # Update $Header{'=Body='} to point to *decoded* body + } elsif ($input == $HEADER_INPUT) { + # Headers pertaining to body encoding could have changed. + &header_check_body_encoding; # Check and recode if possible + &header_resync; # Resynchronize %Header + } } # Feed output back into $Back variable (used by BACK command). Typically, the @@ -1390,60 +1405,15 @@ } # The "RESYNC" command -# Resynchronizes the %Header entries by reparsing the 'All' entry +# Resynchronizes the %Header entries by reparsing the 'Head' entry sub header_resync { # Clean up all the non-special entries foreach $key (keys %Header) { next if $Pseudokey{$key}; # Skip pseudo-header entries delete $Header{$key}; } - # There is some code duplication with parse_mail() - local($lines) = 0; - local($first_from); # First From line records sender - local($last_header); # Current normalized header field - local($in_header) = 1; # Bug in the range operator - local($value); # Value of current field - my $missing_warned = 0; - foreach (split(/\n/, $Header{'All'})) { - if ($in_header) { # Still in header of message - if (/^$/) { # End of header - $in_header = 0; - next; - } - if (/^\s/) { # It is a continuation line - s/^\s+/ /; # Swallow multiple spaces - $Header{$last_header} .= $_ if $last_header ne ''; - } elsif (/^([!-9;-~\w-]+):\s*(.*)/) { # We found a new header - $value = $2; # Bug in perl 4.0 PL19 - $last_header = &header'normalize($1); - $missing_warned = 0; - # Multiple headers like 'Received' are separated by a new- - # line character. All headers end on a non new-line. - if ($Header{$last_header} ne '') { - $Header{$last_header} .= "\n$value"; - } else { - $Header{$last_header} .= $value; - } - } elsif (/^From\s+(\S+)/) { # The very first From line - $first_from = $1; - } else { - # Did not identify a header field nor a continuation - # Maybe there was a wrong header split somewhere? - if ($last_header eq '') { - &add_log("ERROR ignoring leading header garbage: $_") - if $loglvl > 1; - } else { - &add_log("ERROR missing continuation for $last_header: $_") - if !$missing_warned && $loglvl > 1; - $Header{$last_header} .= " " . $_; - $missing_warned++; - } - } - } else { - $lines++; # One more line in body - } - } - &header_check($first_from, $lines); # Sanity checks + my $first_from = header_parse($Header{'Head'}, \%Header, 0); + &header_check($first_from, undef); # Sanity checks } # The "STRIP" and "KEEP" commands (case insensitive) @@ -1471,7 +1441,7 @@ } $line = $_; # Save original # Make sure header field name is normalized before attempting a match - s/^([\w-]+):/&header'normalize($1).':'/e; + s/^([!-9;-~\w-]+):/&header'normalize($1).':'/e; unless (/^\s/) { # If not a continuation line $last_was_altered = 0; # Reset header alteration flag $matched = 0; # Assume no match @@ -1494,6 +1464,9 @@ } $Header{'Head'} = join("\n", @newhead) . "\n"; $Header{'All'} = $Header{'Head'} . "\n" . $Header{'Body'}; + + # Headers pertaining to body encoding could have changed. + &header_check_body_encoding; # Check, but no resync } # The "ANNOTATE" command Modified: trunk/mailagent/agent/pl/analyze.pl =================================================================== --- trunk/mailagent/agent/pl/analyze.pl 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/pl/analyze.pl 2008-06-13 09:32:24 UTC (rev 38) @@ -66,6 +66,26 @@ ); } +# Compute shorthand file name for logging based on the processed file +sub mail_logname { + my ($file) = @_; + my ($mfile) = $file =~ m|.*/(.*)|; # Basename of mail file + $mfile = $file unless $mfile; # There was no / in name + $mfile = '<stdin>' unless $mfile; # No $file_name if from STDIN + return $mfile; +} + +# Compute file size for logging, if possible (i.e. not reading from STDIN) +sub mail_logsize { + my ($file) = @_; + return "" unless length $file; + my $msize = (stat($file))[7]; + my $size = ""; + my $s = $msize == 1 ? "" : "s"; + $size = " $msize byte$s" if defined $msize; + return $size; +} + # Parse mail message and apply the filtering rules on it sub analyze_mail { local($file) = shift(@_); # Mail file to be parsed @@ -91,6 +111,11 @@ &env'setup; umask($env'umask); + # Log start of processing + my $mfile = mail_logname($file); + my $msize = mail_logsize($file); + add_log("-- HANDLING [$mfile]$msize --") if $loglvl > 8; + # Parse the mail message in file &parse_mail($file); # Parse the mail and fill-in H tables return 1 unless defined $Header{'All'}; # Mail not parsed correctly Added: trunk/mailagent/agent/pl/base64.pl =================================================================== --- trunk/mailagent/agent/pl/base64.pl (rev 0) +++ trunk/mailagent/agent/pl/base64.pl 2008-06-13 09:32:24 UTC (rev 38) @@ -0,0 +1,222 @@ +;# $Id$ +;# +;# Copyright (c) 2008, Raphael Manfredi +;# +;# You may redistribute only under the terms of the Artistic License, +;# as specified in the README file that comes with the distribution. +;# You may reuse parts of this distribution only within the terms of +;# that same Artistic License; a copy of which may be found at the root +;# of the source tree for mailagent 3.0. +;# +package base64; + +# +# Simple base64 encoder/decoder. +# + +# Initialialize the base64 decoding values +sub init { + @values = ( + # 0 1 2 3 4 5 6 7 8 9 0123456789 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 00 -> 09 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 10 -> 19 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 20 -> 29 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 30 -> 39 + + -1,-1,-1,62,-1,-1,-1,63, # ()*+'-./ - 40 -> 47 + 52,53,54,55,56,57,58,59,60,61, # 0123456789 - 48 -> 57 + -1,-1,-1,-1,-1,-1,-1, 0, 1, 2, # :;<=>?@ABC - 58 -> 67 + 3, 4, 5, 6, 7, 8, 9,10,11,12, # DEFGHIJKLM - 68 -> 77 + 13,14,15,16,17,18,19,20,21,22, # NOPQRSTUVW - 78 -> 87 + 23,24,25,-1,-1,-1,-1,-1,-1,26, # XYZ[\]^_`a - 88 -> 97 + 27,28,29,30,31,32,33,34,35,36, # bcdefghijk - 98 -> 107 + 37,38,39,40,41,42,43,44,45,46, # lmnopqrstu - 108 -> 117 + 47,48,49,50,51, # vwxyz - 118 -> 122 + + -1,-1,-1,-1,-1,-1,-1,-1, # - 123 -> 130 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 131 -> 140 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 141 -> 150 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 151 -> 160 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 161 -> 170 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 171 -> 180 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 181 -> 190 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 191 -> 200 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 201 -> 210 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 211 -> 220 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 221 -> 230 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 231 -> 240 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, # - 241 -> 250 + -1,-1,-1,-1,-1 # - 251 -> 255 + ); + $alphabet = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +} + +# Reset the encoder/decoder +# Must be called before invoking encode() or decode(). +# Once called, one must ONLY invoke encode() or decode() but never intermix +# calls to these two routines. To switch, one must invoke reset() again. +sub reset { + my ($len) = @_; + &init unless $init_done++; + my $data = " " x ($len || 64 * 1024); # pre-extend + $data = ""; + $output = \$data; + $input = 0; + $pad = 0; + @byte = (); + $offset = 0; + undef $error; + undef $op; +} + +# Decode new data from the base64 stream +# Invoke as many times as necessary, until the end of the stream is reached. +# Call output() to actually fetch the decoded string. +sub decode { + my ($data) = @_; + return if defined $error; # Stop as soon as an error occurred + $op = "d" unless defined $op; + if ($op ne "d") { + $error = "mixed decode() within encode() calls"; + return; + } + my $len = length $data; + for (my $i = 0; $i < $len; $i++) { + my $c = substr($data, $i, 1); + my $v; + if ($c eq '=') { + $v = 0; + if ($pad++ >= 2) { + $error = "too much padding"; + return; + } + } else { + $v = $values[ord($c)]; + if ($v < 0) { + $error = "invalid character '$c'"; + return; + } + } + + # In the following picture, we represent how the 4 bytes of input, + # each consisting of only 6 bits of information forming a base64 digit, + # are concatenated back into 3 bytes of binary information. + # + # input digit 0 1 2 3 + # <----><-----><-----><----> + # +--------+--------+--------+ + # |01234501|23450123|45012345| + # +--------+--------+--------+ + # output byte 0 1 2 + + if ($input == 0) { + $byte[0] = $v << 2; + } elsif ($input == 1) { + $byte[1] = ($v & 0x0f) << 4; + $byte[0] |= $v >> 4; + } elsif ($input == 2) { + $byte[2] = ($v & 0x03) << 6; + $byte[1] |= $v >> 2; + } else { + $byte[2] |= $v; + $input = -1; + $$output .= chr($byte[0]) . chr($byte[1]) . chr($byte[2]); + } + $input++; + $offset++; + } +} + +# Encode new data into the base64 stream +# Invoke as many times as necessary, until the end of the stream is reached. +# Call output() to actually fetch the encoded string. +sub encode { + my ($data) = @_; + return if defined $error; # Stop as soon as an error occurred + $op = "e" unless defined $op; + if ($op ne "e") { + $error = "mixed encode() within decode() calls"; + return; + } + my $len = length $data; + for (my $i = 0; $i < $len; $i++) { + my $c = substr($data, $i, 1); + my $v = unpack("C", $c); + + # In the following picture, we represent how the 3 bytes of input + # are split into groups of 6 bits, each group being encoded as a + # single base64 digit. + # + # input byte 0 1 2 + # +--------+--------+--------+ + # |01234501|23450123|45012345| + # +--------+--------+--------+ + # <----><-----><-----><----> + # output digit 0 1 2 3 + # + # Every times we have 16 blocks of 4 chars, we emit a "\n" to avoid + # too long lines. + + if ($input == 0) { + $byte[0] = $v >> 2; + $byte[1] = ($v & 0x3) << 4; + $$output .= "\n" if $offset && 0 == $offset % 57; + } elsif ($input == 1) { + $byte[1] |= $v >> 4; + $byte[2] |= ($v & 0xf) << 2; + } else { + $byte[2] |= $v >> 6; + $byte[3] = $v & 0x3f; + $input = -1; + $$output .= + substr($alphabet, $byte[0], 1) . + substr($alphabet, $byte[1], 1) . + substr($alphabet, $byte[2], 1) . + substr($alphabet, $byte[3], 1); + @byte = (); + } + $input++; + $offset++; + } +} + +# Return a reference to the output of the encoded/decoded base64 stream +sub output { + return $output unless defined $op; # Neither encode() nor decode() called + if ($op eq 'd') { + &'add_log("WARNING truncated base64 input (length = $offset)") + if $input && $'loglvl > 2; + $$output =~ s/\0*$//; + } elsif ($op eq 'e') { + my $pad = $offset % 3; + if ($pad == 1) { + $$output .= + substr($alphabet, $byte[0], 1) . + substr($alphabet, $byte[1], 1) . "=="; + } elsif ($pad == 2) { + $$output .= + substr($alphabet, $byte[0], 1) . + substr($alphabet, $byte[1], 1) . + substr($alphabet, $byte[2], 1) . "="; + } + $$output .= "\n"; + } else { + &'add_log("ERROR unknown base64 operation '$op'") if $'loglvl; + } + return $output; +} + +# Check whether output is valid so far +sub is_valid { + return defined($error) ? 0 : 1; +} + +# Generate error message for non-valid base64 +sub error_msg { + return "" unless defined $error; + return "$error at offset $offset"; +} + +package main; + Property changes on: trunk/mailagent/agent/pl/base64.pl ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Modified: trunk/mailagent/agent/pl/builtins.pl =================================================================== --- trunk/mailagent/agent/pl/builtins.pl 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/pl/builtins.pl 2008-06-13 09:32:24 UTC (rev 38) @@ -118,7 +118,8 @@ sub run_builtins { undef @Builtcode; # Lookup for builtins. Code moved out of &parse_mail. - foreach $line (split(/\n/, $Header{'Body'})) { + # We scan the *decoded* body, not the original one + foreach $line (split(/\n/, ${$Header{'=Body='}})) { if ($line =~ s/^@(\w+)\s*//) { # A builtin command ? local($subroutine) = $Builtin{$1}; &$subroutine($line) if $subroutine; # Record it if known Modified: trunk/mailagent/agent/pl/filter.pl =================================================================== --- trunk/mailagent/agent/pl/filter.pl 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/pl/filter.pl 2008-06-13 09:32:24 UTC (rev 38) @@ -225,7 +225,9 @@ # Run the RESYNC command sub run_resync { - &header_resync; # Resynchronize the %Header array + # Headers pertaining to body encoding could have changed. + &header_check_body_encoding; # Check and recode if possible + &header_resync; # Resynchronize the %Header array &add_log("RESYNCED [$mfile]") if $loglvl > 4; 0; } Modified: trunk/mailagent/agent/pl/matching.pl =================================================================== --- trunk/mailagent/agent/pl/matching.pl 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/pl/matching.pl 2008-06-13 09:32:24 UTC (rev 38) @@ -348,31 +348,33 @@ sub match_var { local($selector, $pattern, $range) = @_; local($lines) = 0; # Number of lines in matching buffer + my $target = \$Header{$selector}; + # Need to special-case Body to use the *decoded* version + $target = $Header{'=Body='} if $selector eq 'Body'; if ($range ne '<1,->') { # Optimize: count lines only if needed - $lines = $Header{$selector} =~ tr/\n/\n/; + $lines = $$target =~ tr/\n/\n/; } local($min, $max) = &mrange($range, $lines); return 0 unless $min; # No matching possible if null range - local($buffer); # Buffer on which matching is attempted + my $buffer; # Buffer on which matching is attempted local(@buffer); # Same, whith range line selected local(@matched); $pattern = &make_pattern($pattern); # Optimize, since range selection is the exception and not the rule. # Most likely, we use the default selection, i.e. we take everything... if ($min != 1 || $max != 9_999_999) { - @buffer = split(/\n/, $Header{$selector}); + @buffer = split(/\n/, $$target); @buffer = @buffer[$min - 1 .. ($max > $#buffer ? $#buffer : $max - 1)]; $buffer = join("\n", @buffer); # Keep only selected lines undef @buffer; # May be big, so free ASAP - } else { - $buffer = $Header{$selector}; + $target = \$buffer; } # Ensure multi-line matching by adding trailing "m" option to pattern - @matched = eval '($buffer =~ ' . $pattern . 'm);'; + @matched = eval '($$target =~ ' . $pattern . 'm);'; # If buffer is empty, we have to recheck the pattern in a non array context # to see if there is a match. Otherwise, /(.*)/ does not seem to match an # empty string as it returns an empty string in $matched[0]... - $matched[0] = eval '$buffer =~ ' . $pattern . 'm' if $buffer eq ''; + $matched[0] = eval '$$target =~ ' . $pattern . 'm' unless length $$target; &eval_error; # Make sure eval worked &update_backref(*matched); # Record non-null backreferences $matched[0]; # Return matching status Modified: trunk/mailagent/agent/pl/parse.pl =================================================================== --- trunk/mailagent/agent/pl/parse.pl 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/pl/parse.pl 2008-06-13 09:32:24 UTC (rev 38) @@ -114,7 +114,7 @@ $Header{'Body'} = ''; $Header{'Head'} = ''; - &add_log ("parsing mail") if $loglvl > 18; + &add_log ("parsing mail" . ($head_only ? " header" : "")) if $loglvl > 18; while (<$fd>) { $added += length($_); @@ -196,25 +196,265 @@ } close MAIL if $file_name ne ''; &header_prepend("$FAKE_FROM\n") unless $first_from; + &body_check unless $head_only; &header_check($first_from, $lines); # Sanity checks } +# Parse given header string into the supplied hash ref. +# Do that silently if told to do so via $silent. +# Returns: the value of the first From line, and fills %$href. +sub header_parse { + my ($headers, $href, $silent) = @_; + # There is some code duplication with parse_mail() above + local($first_from); # First From line records sender + local($last_header); # Current normalized header field + local($value); # Value of current field + my $missing_warned = 0; + foreach (split(/\n/, $headers)) { + if (/^\s/) { # It is a continuation line + s/^\s+/ /; # Swallow multiple spaces + $href->{$last_header} .= $_ if $last_header ne ''; + } elsif (/^([!-9;-~\w-]+):\s*(.*)/) { # We found a new header + $value = $2; # Bug in perl 4.0 PL19 + $last_header = &header'normalize($1); + $missing_warned = 0; + # Multiple headers like 'Received' are separated by a new- + # line character. All headers end on a non new-line. + if ($href->{$last_header} ne '') { + $href->{$last_header} .= "\n$value"; + } else { + $href->{$last_header} .= $value; + } + } elsif (/^From\s+(\S+)/) { # The very first From line + $first_from = $1; + } else { + # Did not identify a header field nor a continuation + # Maybe there was a wrong header split somewhere? + if ($last_header eq '') { + &add_log("ERROR ignoring leading header garbage: $_") + if $loglvl > 1 && !$silent; + } else { + &add_log("ERROR missing continuation for $last_header: $_") + if !$missing_warned && $loglvl > 1 && !$silent; + $href->{$last_header} .= " " . $_; + $missing_warned++; + } + } + } + return $first_from; +} + +# Set number of Lines in body and body Length to reflect reality +# If the headers were physically present in the message, they are +# updated as well. +sub header_update_size { + # Cannot trust %Header to indicate whether the headers were present + # since we add these entries in any case... Use a crude way to detect + # presence then... + my $had_lines = $Header{'Head'} =~ /^Lines:/im; + my $had_length = $Header{'Head'} =~ /^Length:/im; + + my $lines = $Header{'Lines'} = ${$Header{'=Body='}} =~ tr/\n/\n/; + my $length = $Header{'Length'} = length($Header{'Body'}); + my $is_mime = exists $Header{'Mime-Version'}; + + if ($had_lines) { + alter_header("Lines", $HD_STRIP); + header_append(header'format("Lines: $lines")); + } + + if ($had_length) { + alter_header("Length", $HD_STRIP); + &add_log("NOTICE stripped non-RFC822 Length header") if $loglvl > 5; + } + + if ($is_mime && exists $Header{'Content-Length'}) { + my $clen = $Header{'Content-Length'}; + if ($clen != $length) { + alter_header("Content-Length", $HD_STRIP); + header_append(header'format("Content-Length: $length")); + $Header{'Content-Length'} = $length; + &add_log("NOTICE adjusted Content-Length from $clen to $length") + if $loglvl > 5; + } + } + + if (!$is_mime && exists $Header{'Content-Length'}) { + alter_header("Content-Length", $HD_STRIP); + delete $Header{'Content-Length'}; + &add_log("NOTICE stripped Content-Length header in non-MIME message") + if $loglvl > 5; + } +} + +# Check whether the body we got back has received a transfer encoding. +# If it has and we know about that transfer encoding, decode it. +# We make sure the "=Body=" header key is a reference to the decoded body: +# it is either a reference to $Header{'Body'} when we leave it as-is, or +# a reference to a newly allocated scalar. +sub body_check { + $Header{'=Body='} = \$Header{'Body'}; + my $encoding = lc($Header{'Content-Transfer-Encoding'}); + my %decode = map { $_ => 1 } qw(base64 quoted-printable); + unless (exists $Header{'Mime-Version'}) { + return unless length $encoding; + if ($decode{$encoding}) { + &add_log("WARNING ignoring $encoding body transfer encoding") + if $loglvl > 3; + } else { + alter_header("Content-Transfer-Encoding", $HD_STRIP); + delete $Header{'Content-Transfer-Encoding'}; + &add_log("NOTICE stripped $encoding encoding in non-MIME message") + if $loglvl > 6; + } + return; + } + my %enc = map { $_ => 1 } qw(7bit 8bit binary base64 quoted-printable); + if (length $encoding) { + &'add_log("WARNING unknown content transfer encoding \"$encoding\"") + if $'loglvl > 5 && !$enc{$encoding}; + } + return unless $decode{$encoding}; + my @data = split(/\r?\n/, $Header{'Body'}); + my $error; + my $output; + if ($encoding eq "base64") { + base64'reset(length $Header{'Body'}); + foreach my $d (@data) { + base64'decode($d); + } + $error = base64'error_msg(); + $output = base64'output(); + } elsif ($encoding eq "quoted-printable") { + qp'reset(length $Header{'Body'}); + foreach my $d (@data) { + qp'decode($d); + } + $error = qp'error_msg(); + $output = qp'output(); + } + if (length $error) { + &'add_log("WARNING could not decode $encoding body: $error") + if $'loglvl > 5; + } else { + if ($'loglvl > 9) { + my $len = length $$output; + &'add_log("decoded $encoding body into $len bytes"); + } + $Header{'=Body='} = $output; # Reference + } + &header_update_size; +} + +# Force recoding of the body to a new encoding. +# The $Header{'Body'} variable is supposed to hold the decoded version. +sub body_recode_with { + my ($encoding) = @_; + $Header{'=Body='} = \$Header{'Body'}; # The decoded version! + my @data = split(/\r?\n/, $Header{'Body'}); + my $error; + my $output; + if ($encoding eq "base64") { + base64'reset(length($Header{'Body'}) * 4/3); + foreach my $d (@data) { + base64'encode($d); + } + $error = base64'error_msg(); + $output = base64'output(); + } elsif ($encoding eq "quoted-printable") { + qp'reset(length $Header{'Body'} * 1.1); + foreach my $d (@data) { + qp'encode($d); + } + $error = qp'error_msg(); + $output = qp'output(); + } + if (length $error) { + &'add_log("WARNING could not recode $encoding body: $error") + if $'loglvl > 5; + } else { + if ($'loglvl > 9) { + my $len = length $$output; + &'add_log("recoded $encoding body into $len bytes"); + } + delete $Header{'Body'}; # $Header{'=Body='} ref still points to it + $Header{'Body'} = $$output; # Transfer-Encoded version of the body + # The body changed, must update the "All" key... + $Header{'All'} = $Header{'Head'} . "\n" . $Header{'Body'}; + } +} + +# When coming from a feeback routine such as PASS, we have a new body that +# maybe we need to recode to match the original encoding... +sub body_recode { + $Header{'=Body='} = \$Header{'Body'}; # The decoded version! + my $encoding = lc($Header{'Content-Transfer-Encoding'}); + return unless length $encoding; + unless (exists $Header{'Mime-Version'}) { + &add_log("WARNING not recoding body in $encoding: no MIME header") + if $loglvl > 3; + alter_header("Content-Transfer-Encoding", $HD_STRIP); + delete $Header{'Content-Transfer-Encoding'}; + return; + } + my %recode = map { $_ => 1 } qw(base64 quoted-printable); + return unless $recode{$encoding}; + body_recode_with($encoding); +} + +# Whenever we got a new set of headers in $Header{'Head'} we need to ensure +# the new vision is consistent with the body encoding. If they strip the +# Content-Transfer-Encoding header for instance, we have to use the old +# decoded version we had instead of the original body. +# If they add a Content-Transfer-Encoding header, we have to recode the body! +sub header_check_body_encoding { + my $plain = \$Header{'Body'} == $Header{'=Body='}; # No encoding + if ($plain && $Header{'Head'} !~ /^Content-Transfer-Encoding:/mi) { + # No encoding and no header indicating a transfer encodig... + return; # Nothing to change + } + my %new; + header_parse($Header{'Head'}, \%new, 1); # Silently parse new headers + my $encoding = $Header{'Content-Transfer-Encoding'} || "none"; + my $new_encoding = lc($new{'Content-Transfer-Encoding'}) || "none"; + return if lc($encoding) eq $new_encoding; # No change occurred + + &add_log( + "WARNING body transfer encoding changed from $encoding to $new_encoding" + ) if $loglvl > 3; + + + $Header{'Body'} = ${$Header{'=Body='}}; # Restore decoded version + my %encode = map { $_ => 1 } qw(base64 quoted-printable); + unless ($encode{$new_encoding}) { + $Header{'=Body='} = \$Header{'Body'}; + return; + } + body_recode_with($new_encoding); # Then re-encode it + + # At some point a RESYNC will be needed, caller will decide when it is + # necessary to do it. +} + # Now do some sanity checks: # - if there is no From: header, fill it in with the first From # - if there is no To: but an Apparently-To:, copy it also as a To: # - if an Envelope field was defined in the header, override it (sorry) # - likewise for Relayed, which is the list of relaying hosts, first one first. # -# We guarantee the following header entries: +# We guarantee the following header entries (to select on in rules): # Envelope: the actual sender of the message, empty if cannot compute # From: the value of the From field # To: to whom the mail was sent # Lines: number of lines in the message -# Length: number of bytes in the message +# Length: number of bytes in the message body (*decoded* version) # Relayed: the list of relaying hosts deduced from Received: lines # Reply-To: the address we may use to reply # Sender: the value of the Sender field, same as From usually # +# NB: When the $lines parameter is set, we parsed the whole message initially. +# When it is undef, we're resyncing, possibly after an external messaging of +# the message. sub header_check { local($first_from, $lines) = @_; # First From line, number of lines unless (defined $Header{'From'}) { @@ -254,11 +494,17 @@ } } - # Set number of lines in body, unless there is already a Lines: - # header in which case we trust it. Same for Length. - $Header{'Lines'} = $lines unless defined($Header{'Lines'}); - $Header{'Length'} = length($Header{'Head'}) + length($Header{'Body'}) + 1 - unless defined($Header{'Length'}); + # Update length information + # No warning is emitted unless $lines was defined, indicating initial + # parsing of the message we get. + my $length = $Header{'Content-Length'}; + &header_update_size; # Update number of lines and length... + my $count = $Header{'Lines'}; + &add_log("NOTICE adjusted number of lines from $lines to $count") + if $loglvl > 5 && defined($lines) && $count != $lines; + $count = $Header{'Content-Length'}; + &add_log("NOTICE adjusted Content-Length from $length to $count") + if $loglvl > 5 && defined($lines) && $count != $length; # If there is no Reply-To: line, then take the address in From, if any. # Otherwise use the address found in the return-path @@ -287,7 +533,7 @@ # the mail) coming last. unless ($Header{'Relayed'} = &relay_list) { - &add_log("WARNING no valid Received: indication") if $loglvl > 4; + &add_log("NOTICE no valid Received: indication") if $loglvl > 6; } } @@ -330,7 +576,7 @@ local($_); # All the known top-level domains as of 2006-08-15 - # with the addition of "loc" and "private". + # with the addition of "loc", "localdomain" and "private". # See http://data.iana.org/TLD/tlds-alpha-by-domain.txt my $tlds_re = qr/ a(?:ero|rpa|[c-gil-oq-uwxz])| @@ -344,7 +590,7 @@ i(?:n(?:fo|t)|[del-oq-t])| j(?:obs|[emop])| k[eghimnrwyz]| - l(?:[abcikr-vy]|oc)| + l(?:[abcikr-vy]|o(?:c|caldomain))| m(?:il|obi|useum|[acdghk-z])| n(?:ame|et|[acefgilopruz])| o(?:m|rg)| @@ -510,7 +756,6 @@ return join(', ', reverse @unique); } - # Append given field to the header structure, updating the whole mail # text at the same time, hence keeping the %Header table. # The argument must be a valid formatted RFC-822 mail header field. Modified: trunk/mailagent/agent/pl/pqueue.pl =================================================================== --- trunk/mailagent/agent/pl/pqueue.pl 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/pl/pqueue.pl 2008-06-13 09:32:24 UTC (rev 38) @@ -142,7 +142,8 @@ if ($result == 0) { local($len) = $Header{'Length'}; - &add_log("FILTERED [$file] $len bytes") if $loglvl > 4; + my $msize = mail_logsize($filename); + &add_log("FILTERED [$file]$msize ($len bytes)") if $loglvl > 4; } return $result; # 0 if OK, 1 for analyze errors Added: trunk/mailagent/agent/pl/qp.pl =================================================================== --- trunk/mailagent/agent/pl/qp.pl (rev 0) +++ trunk/mailagent/agent/pl/qp.pl 2008-06-13 09:32:24 UTC (rev 38) @@ -0,0 +1,111 @@ +;# $Id$ +;# +;# Copyright (c) 2008, Raphael Manfredi +;# +;# You may redistribute only under the terms of the Artistic License, +;# as specified in the README file that comes with the distribution. +;# You may reuse parts of this distribution only within the terms of +;# that same Artistic License; a copy of which may be found at the root +;# of the source tree for mailagent 3.0. +;# +package qp; + +# +# Simple quoted-printable encoder/decoder. +# + +# Reset the encoder/decoder +# Must be called before invoking encode() or decode(). +# Once called, one must ONLY invoke encode() or decode() but never intermix +# calls to these two routines. To switch, one must invoke reset() again. +sub reset { + my ($len) = @_; + my $data = " " x ($len || 64 * 1024); # pre-extend + $data = ""; + $output = \$data; + $offset = 0; + undef $error; + undef $op; +} + +# Decode new line from the quoted-printable stream +# Invoke as many times as necessary, until the end of the stream is reached. +# Call output() to actually fetch the decoded string. +sub decode { + local ($_) = @_; + return if defined $error; # Stop as soon as an error occurred + $op = "d" unless defined $op; + if ($op ne "d") { + $error = "mixed decode() within encode() calls"; + return; + } + my $soft = 0; + s/[ \t]+$//; # Trailing white spaces + $soft = 1 if s/^=$//; # Soft line break + $soft = 1 if s/([^=])=$/$1/; # Soft line break, but not for trailing == + s/=([\da-fA-F]{2})/pack("C", hex($1))/ge; + $$output .= $_; + $$output .= "\n" unless $soft; + $offset += length($_); +} + +# Encode new line into the base64 stream +# Invoke as many times as necessary, until the end of the stream is reached. +# Call output() to actually fetch the encoded string. +sub encode { + local ($_) = @_; + return if defined $error; # Stop as soon as an error occurred + $op = "e" unless defined $op; + if ($op ne "e") { + $error = "mixed encode() within decode() calls"; + return; + } + s/([^ \t\n!"#\$%&'()*+,\-.\/0-9:;<>?\@A-Z[\\\]^_`a-z{|}~])/ + sprintf("=%02X", ord($1))/eg; + # Trailing white space must be encoded or will be stripped at decode time + s/([ \t]+)$/join('', map { sprintf("=%02X", ord($_)) } split('', $1))/egm; + + # Ensure lines are smaller than 76 chars + # No one-liner here as we cannot break up =xx escapes! + # The trick is to break after 73 chars (76 - 3) and then add 1 or 2 chars + # if they are not '=', thereby ensuring we're not breaking up in the + # middle of a sequence. + + while (length($_) >= 76) { + my $str = substr($_, 0, 73); + s/^.{73}//; + $str .= $1 if substr($_, 0, 1) ne "=" && s/^(.)//; + $str .= $1 if substr($_, 0, 1) ne "=" && s/^(.)//; + $$output .= "$str=\n"; + } + $$output .= $_ . "\n" if length $_; + + $offset += length $_; +} + +# Return a reference to the output of the encoded/decoded base64 stream +sub output { + return $output unless defined $op; # Neither encode() nor decode() called + if ($op eq 'd') { + # Nothing to be done + } elsif ($op eq 'e') { + $$output .= "\n" unless $$output =~ /\n$/s; + } else { + &'add_log("ERROR unknown quoted-printable operation '$op'") if $'loglvl; + } + return $output; +} + +# Check whether output is valid so far +sub is_valid { + return defined($error) ? 0 : 1; +} + +# Generate error message for non-valid base64 +sub error_msg { + return "" unless defined $error; + return "$error at offset $offset"; +} + +package main; + Property changes on: trunk/mailagent/agent/pl/qp.pl ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Modified: trunk/mailagent/agent/pl/runcmd.pl =================================================================== --- trunk/mailagent/agent/pl/runcmd.pl 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/pl/runcmd.pl 2008-06-13 09:32:24 UTC (rev 38) @@ -138,9 +138,7 @@ local($cmd) = @_; # Command to be run (passed to subroutines) local($cmd_name); # Command name local($cont) = $FT_CONT; # Continue by default - local($mfile) = $file_name =~ m|.*/(.*)|; # Basename of mail file - $mfile = $file_name unless $mfile; # There was no / in name - $mfile = '<stdin>' unless $mfile; # No $file_name if from STDIN + local($mfile) = mail_logname($file_name); ¯os_subst(*cmd); # Macros substitutions $cmd =~ s/^\s*//; # Remove leading spaces $cmd =~ s/\s*$//; # And trailing ones Modified: trunk/mailagent/agent/test/actions =================================================================== --- trunk/mailagent/agent/test/actions 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/test/actions 2008-06-13 09:32:24 UTC (rev 38) @@ -167,12 +167,13 @@ REJECT; } -X-Tag: /feed/, To: ram { SAVE no_resync }; +X-Tag: /feed/, !To: ram { SAVE resynced }; X-Tag: /forward 1/ { FORWARD nobody }; X-Tag: /forward 2/ { FORWARD "list" }; -X-Tag: /give/ { GIVE wc > output }; +X-Tag: /give 1/ { GIVE wc > output }; +X-Tag: /give 2/ { GIVE cat > output }; X-Tag: /keep/ { @@ -229,12 +230,19 @@ ONCE (other,tag,0m) SAVE four; } -X-Tag: /pass/ +X-Tag: /pass 1/ { PASS grep -v and; PASS perl -p -e 's/^\>From /From /'; SAVE output; } +X-Tag: /pass 2/ +{ + PASS grep -v successfully; + STRIP Content-Transfer-Encoding; + SAVE output; +} +X-Tag: /pass 3/ { PASS grep -v broken; SAVE output; } X-Tag: /perl/ { REJECT PERL }; <PERL> { PERL perl.2 exit_1; REJECT -t; SAVE exit_ok; REJECT }; @@ -248,11 +256,8 @@ X-Tag: /post 1/ { POST alt.test comp.others }; X-Tag: /post 2/ { POST -l "list" }; -X-Tag: /purify/ -{ - PURIFY grep -v Subject:; - SAVE output; -}; +X-Tag: /purify 1/ { PURIFY grep -v Subject:; SAVE output; }; +X-Tag: /purify 2/ { PURIFY grep -v Transfer-Encoding:; SAVE output; }; X-Tag: /protect/ { Added: trunk/mailagent/agent/test/base64 =================================================================== --- trunk/mailagent/agent/test/base64 (rev 0) +++ trunk/mailagent/agent/test/base64 2008-06-13 09:32:24 UTC (rev 38) @@ -0,0 +1,21 @@ +From rap...@po... Tue Jun 10 17:44:12 2008 +Received: from tours.ram.loc (fetchmail@localhost [127.0.0.1]) + by tours.ram.loc (8.14.3/8.13.8/Debian-3) with ESMTP id m5AFiCJq002957 + for <ram@localhost>; Tue, 10 Jun 2008 17:44:12 +0200 +From: "Raphael Manfredi" <Rap...@po...> +To: "Raphael Manfredi" <Rap...@po...> +Date: Tue, 10 Jun 2008 15:35:21 +0000 +Subject: Sample base64 encoding +Message-ID: <D32...@GV...> +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: base64 +MIME-Version: 1.0 +Content-Length: 346 +Lines: 6 + +VGhpcyBtZXNzYWdlIGlzIG9uZSBiaWcgTUlNRSBwYXJ0IHRoYXQgaGFzIGJlZW4gYmFzZTY0LWVu +Y29kZWQuDQoNClRoZSBtYWlsYWdlbnQgdGVzdCBzdWl0ZSBpcyBnb2luZyB0byBsb29rIGZvciB0 +aGUgZm9sbG93aW5nIGxpbmU6DQoNCiAgICAgICAgKioqIFlFUywgc3VjY2Vzc2Z1bGx5IGRlY29k +ZWQgKioqDQoNCmluIHRoZSBkZWNvZGVkIGJvZHkgYXMgcHJvb2YgdGhhdCB0aGUgYmFzZTY0IGRl +Y29kaW5nIGxvZ2ljIGlzIHdvcmtpbmcuDQo= + Modified: trunk/mailagent/agent/test/cmd/feed.t =================================================================== --- trunk/mailagent/agent/test/cmd/feed.t 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/test/cmd/feed.t 2008-06-13 09:32:24 UTC (rev 38) @@ -16,7 +16,7 @@ # do '../pl/cmd.pl'; -unlink 'ok', 'no_resync'; +unlink 'ok', 'resynced'; &add_header('X-Tag: feed'); `$cmd`; @@ -25,7 +25,7 @@ -f 'ok' || print "3\n"; # ...here &get_log(4, 'ok'); ¬_log('^To:', 5); # Make sure To: disappeared --f 'no_resync' || print "6\n"; # Ensure header not disturbed +-f 'resynced' || print "6\n"; # Ensure RESYNC was done under the hood -unlink 'ok', 'no_resync', 'mail'; +unlink 'ok', 'resynced', 'mail'; print "0\n"; Modified: trunk/mailagent/agent/test/cmd/give.t =================================================================== --- trunk/mailagent/agent/test/cmd/give.t 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/test/cmd/give.t 2008-06-13 09:32:24 UTC (rev 38) @@ -18,7 +18,7 @@ do '../pl/cmd.pl'; unlink 'output'; -&add_header('X-Tag: give'); +&add_header('X-Tag: give 1'); `$cmd`; $? == 0 || print "1\n"; -f 'output' || print "2\n"; # Where output is created @@ -33,4 +33,23 @@ -f "$user" || print "4\n"; # Default action applies unlink 'output', 'mail', "$user"; + +&cp_mail("../base64"); +&add_header('X-Tag: give 2'); +`$cmd`; +$? == 0 || print "5\n"; +&get_log(6, 'output'); +&check_log('successfully decoded', 7) == 1 || print "8\n"; + +unlink 'output', 'mail', "$user"; + +&cp_mail("../qp"); +&add_header('X-Tag: give 2'); +`$cmd`; +$? == 0 || print "9\n"; +&get_log(10, 'output'); +&check_log('broken', 11) == 1 || print "12\n"; +&check_log('Rapha\xEBl', 13) == 1 || print "14\n"; + +unlink 'output', 'mail', "$user"; print "0\n"; Modified: trunk/mailagent/agent/test/cmd/pass.t =================================================================== --- trunk/mailagent/agent/test/cmd/pass.t 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/test/cmd/pass.t 2008-06-13 09:32:24 UTC (rev 38) @@ -24,7 +24,7 @@ do '../pl/misc.pl'; unlink 'output'; -&add_header('X-Tag: pass'); +&add_header('X-Tag: pass 1'); &add_option("-o 'fromesc: OFF'"); open(MAIL, '>>mail'); print MAIL <<EOM; @@ -45,4 +45,25 @@ &check_log('^From test bug', 7) == 1 || print "8\n"; unlink 'output', 'mail', 'ok', 'comp'; + +cp_mail("../base64"); +add_header('X-Tag: pass 2'); +`$cmd`; +$? == 0 || print "9\n"; +&get_log(10, 'output'); +¬_log('successfully', 11); +&check_log('base64-encoded', 12); + +unlink 'output', 'mail'; + +cp_mail("../qp"); +add_header('X-Tag: pass 3'); +`$cmd`; +$? == 0 || print "13\n"; +&get_log(14, 'output'); +¬_log('brok=', 15); # Line was passed decoded, so this was stripped +&check_log("char '=3D'!", 16); # Still encoded in quoted-printable + +unlink 'output', 'mail'; + print "0\n"; Modified: trunk/mailagent/agent/test/cmd/purify.t =================================================================== --- trunk/mailagent/agent/test/cmd/purify.t 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/test/cmd/purify.t 2008-06-13 09:32:24 UTC (rev 38) @@ -18,7 +18,7 @@ do '../pl/cmd.pl'; unlink 'output'; -&add_header('X-Tag: purify'); +&add_header('X-Tag: purify 1'); `$cmd`; $? == 0 || print "1\n"; -f 'output' || print "2\n"; # Where mail is saved @@ -29,4 +29,24 @@ -s 'comp' != -s 'output' || print "5\n"; # Casually check X-Filter was there unlink 'output', 'mail', 'ok', 'comp'; + +cp_mail("../base64"); +add_header('X-Tag: purify 2'); +`$cmd`; +$? == 0 || print "6\n"; +&get_log(7, 'output'); +&check_log('successfully', 8); + +unlink 'output', 'mail'; + +cp_mail("../qp"); +add_header('X-Tag: purify 2'); +`$cmd`; +$? == 0 || print "9\n"; +&get_log(10, 'output'); +¬_log('brok=', 11); # Body must have been recoded +¬_log("char '=3D'!", 12); +&check_log("broken", 13); + +unlink 'output', 'mail'; print "0\n"; Added: trunk/mailagent/agent/test/filter/base64.t =================================================================== --- trunk/mailagent/agent/test/filter/base64.t (rev 0) +++ trunk/mailagent/agent/test/filter/base64.t 2008-06-13 09:32:24 UTC (rev 38) @@ -0,0 +1,29 @@ +# Check base64 body decoding for matching + +# $Id$ +# +# Copyright (c) 2008, Raphael Manfredi +# +# You may redistribute only under the terms of the Artistic License, +# as specified in the README file that comes with the distribution. +# You may reuse parts of this distribution only within the terms of +# that same Artistic License; a copy of which may be found at the root +# of the source tree for mailagent 3.0. + +do '../pl/filter.pl'; +do '../pl/logfile.pl'; +unlink 'always'; +&cp_mail("../base64"); + +&add_header('x-tag: base64'); +`$cmd`; +$? == 0 || print "1\n"; +-f "$user" && print "2\n"; # No default action +-f 'always' || print "3\n"; # Recognized both X-Tag and Body + +&get_log(4, 'always'); +¬_log('YES, successfully decoded', 5); # Body NOT decoded +&check_log('Y29kaW5nIGxvZ2ljIGlzIHdvcmtpbmcuDQo=', 6); + +unlink 'always', "$user"; +print "0\n"; Property changes on: trunk/mailagent/agent/test/filter/base64.t ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Added: trunk/mailagent/agent/test/filter/qp.t =================================================================== --- trunk/mailagent/agent/test/filter/qp.t (rev 0) +++ trunk/mailagent/agent/test/filter/qp.t 2008-06-13 09:32:24 UTC (rev 38) @@ -0,0 +1,29 @@ +# Check quoted-printable body decoding for matching + +# $Id$ +# +# Copyright (c) 2008, Raphael Manfredi +# +# You may redistribute only under the terms of the Artistic License, +# as specified in the README file that comes with the distribution. +# You may reuse parts of this distribution only within the terms of +# that same Artistic License; a copy of which may be found at the root +# of the source tree for mailagent 3.0. + +do '../pl/filter.pl'; +do '../pl/logfile.pl'; +unlink 'always'; +&cp_mail("../qp"); + +&add_header('x-tag: qp'); +`$cmd`; +$? == 0 || print "1\n"; +-f "$user" && print "2\n"; # No default action +-f 'always' || print "3\n"; # Recognized both X-Tag and Body + +&get_log(4, 'always'); +¬_log('broken', 5); # Body NOT decoded +&check_log('brok=', 6); + +unlink 'always', "$user"; +print "0\n"; Property changes on: trunk/mailagent/agent/test/filter/qp.t ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Modified: trunk/mailagent/agent/test/pl/mail.pl =================================================================== --- trunk/mailagent/agent/test/pl/mail.pl 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/test/pl/mail.pl 2008-06-13 09:32:24 UTC (rev 38) @@ -76,8 +76,10 @@ # Copy mail in out/ sub cp_mail { + my ($file) = @_; + $file = "../mail" unless defined $file; local($_); - open(MAIL, '../mail'); + open(MAIL, $file) || die "Can't open $file: $!"; open(HERE, '>mail'); print HERE while <MAIL>; close MAIL; Added: trunk/mailagent/agent/test/qp =================================================================== --- trunk/mailagent/agent/test/qp (rev 0) +++ trunk/mailagent/agent/test/qp 2008-06-13 09:32:24 UTC (rev 38) @@ -0,0 +1,21 @@ +From rap...@po... Tue Jun 10 17:44:12 2008 +Received: from tours.ram.loc (fetchmail@localhost [127.0.0.1]) + by tours.ram.loc (8.14.3/8.13.8/Debian-3) with ESMTP id m5AFiCJq002957 + for <ram@localhost>; Tue, 10 Jun 2008 17:44:12 +0200 +From: "Raphael Manfredi" <Rap...@po...> +To: "Raphael Manfredi" <Rap...@po...> +Date: Tue, 10 Jun 2008 15:35:21 +0000 +Subject: Sample quoted-printable encoding +Message-ID: <D32...@ma...> +Content-Type: text/plain; charset="iso8859-1" +Content-Transfer-Encoding: quoted-printable +MIME-Version: 1.0 +Lines: 7 + +This is a first line of pure ASCII text +This second line contains the word 'Rapha=EBl' +This third line is much longer than 76 chars and therefore needs to be brok= +en up smartly +This fourth line contains the naughty char '=3D'! +This fifth line is unreadable: =E0=E9=F4=EA=E8=E0=E9=F4=EA=E8=E0=E9=F4=EA= +=E8=E0=E9=F4=EA=E8=E0=E9=F4=EA=E8=E0=E9=F4=EA=E8=E0=E9=F4=EA=E8, yeah! Modified: trunk/mailagent/agent/test/rules =================================================================== --- trunk/mailagent/agent/test/rules 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/agent/test/rules 2008-06-13 09:32:24 UTC (rev 38) @@ -161,6 +161,14 @@ # filter/case X-Tag: case, Cc: root { STRIP Cc; SAVE always }; +# filter/base64 +X-Tag: base64, +Body: /successfully/ { SAVE always }; + +# filter/qp +X-Tag: qp, +Body: /broken/ { SAVE always }; + # filter/status X-Tag: /status/ { REJECT -t STATUS }; <STATUS> { RUN ../no/such/file; REJECT -t; SAVE always; REJECT -t; SAVE never }; Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-06-13 09:24:10 UTC (rev 37) +++ trunk/mailagent/revision.h 2008-06-13 09:32:24 UTC (rev 38) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 33 +#define REVISION 37 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-13 14:05:52
|
Revision: 41 http://mailagent.svn.sourceforge.net/mailagent/?rev=41&view=rev Author: rmanfredi Date: 2008-06-13 07:05:31 -0700 (Fri, 13 Jun 2008) Log Message: ----------- Fixed logging message and do not forget a charset can follow the content-type. Modified Paths: -------------- trunk/mailagent/agent/pl/biff.pl trunk/mailagent/revision.h Modified: trunk/mailagent/agent/pl/biff.pl =================================================================== --- trunk/mailagent/agent/pl/biff.pl 2008-06-13 13:50:11 UTC (rev 40) +++ trunk/mailagent/agent/pl/biff.pl 2008-06-13 14:05:31 UTC (rev 41) @@ -241,8 +241,7 @@ my $content; $content = unmime(\@body) if $'Header{'Mime-Version'}; - &'add_log("retained content for biffing is $content") - if length($content) && $'loglvl > 8; + &'add_log("biffing entity is $content") if length($content) && $'loglvl > 8; strip_html(\@body) if $content =~ /html\b/; &trim(*body) if $trim; # Smart trim of leading reply text @@ -475,7 +474,7 @@ @entity = (); my $end = !skip_past($aref, $boundary, \@entity); $grabbed = 1; # Avoid skipping at next loop iteration - last if $entity_content eq "text/plain"; # We found the best one + last if $entity_content =~ m|^text/plain\b|; # Found the best one last if $end; } } Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-06-13 13:50:11 UTC (rev 40) +++ trunk/mailagent/revision.h 2008-06-13 14:05:31 UTC (rev 41) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 39 +#define REVISION 40 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-13 16:44:52
|
Revision: 42 http://mailagent.svn.sourceforge.net/mailagent/?rev=42&view=rev Author: rmanfredi Date: 2008-06-13 09:44:42 -0700 (Fri, 13 Jun 2008) Log Message: ----------- Must not lowercase the whole Content-Type header or we alter the boundary! Modified Paths: -------------- trunk/mailagent/agent/pl/biff.pl trunk/mailagent/revision.h Modified: trunk/mailagent/agent/pl/biff.pl =================================================================== --- trunk/mailagent/agent/pl/biff.pl 2008-06-13 14:05:31 UTC (rev 41) +++ trunk/mailagent/agent/pl/biff.pl 2008-06-13 16:44:42 UTC (rev 42) @@ -238,10 +238,11 @@ # Setting bifflen or bifflines to 0 means no body return '' if $len == 0 || $lines == 0; - my $content; - $content = unmime(\@body) if $'Header{'Mime-Version'}; + my ($content, $entity); + ($content, $entity) = unmime(\@body) if $'Header{'Mime-Version'}; - &'add_log("biffing entity is $content") if length($content) && $'loglvl > 8; + &'add_log("biffing $entity entity is $content") + if length($content) && $'loglvl > 8; strip_html(\@body) if $content =~ /html\b/; &trim(*body) if $trim; # Smart trim of leading reply text @@ -434,15 +435,16 @@ # first text entity in the message. # The supplied array is updated in-place and will contain on return the # lines of the MIME entity that was retained. -# Returns the type of the retained MIME entity. +# Returns the type of the retained MIME entity and the number of the entity +# for logging, saying "global" for the whole message. # NB: if no text part is found, the array will be empty upon return. sub unmime { my ($aref) = @_; - my $content = lc($'Header{'Content-Type'}); + my $content = $'Header{'Content-Type'}; $content =~ s/\(.*?\)\s*//g; # Removed allowed RFC822 comments &'add_log("global MIME content-type is $content") if $'loglvl > 16; - return $content unless $content =~ m|^multipart/|; + return ($content, "global") unless $content =~ m|^multipart/|i; my ($boundary) = $content =~ /boundary=(\S+);/; ($boundary) = $content =~ /boundary=(\S+)/ unless length $boundary; @@ -458,6 +460,7 @@ my @entity; my $grabbed = 0; + my $n = 0; for (;;) { unless ($grabbed) { @@ -469,6 +472,7 @@ $entity_content =~ s/\(.*?\)\s*//g; &'add_log("parsed entity header: content is $entity_content") if $'loglvl > 19; + $n++; if ($entity_content =~ m|^text/|) { # We found (another) text part, collect it... @entity = (); @@ -479,8 +483,14 @@ } } - &'add_log("kept entity $entity_content for biffing") if $'loglvl > 18; + my $entity = "${n}th"; + $entity =~ s/1th$/1st/; + $entity =~ s/2th$/2nd/; + $entity =~ s/3th$/3rd/; + &'add_log("kept $entity entity $entity_content for biffing") + if $'loglvl > 18; + # Maybe the entity bears a transfer encoding? my $entity_encoding = $header->{'Content-Transfer-Encoding'}; $entity_encoding =~ s/\(.*?\)\s*//g; @@ -507,7 +517,8 @@ $error = "no encoding"; } - &'add_log("decoded entity ($entity_encoding), error=$error") + my $error_msg = length($error) ? $error : "none"; + &'add_log("decoded $entity entity ($entity_encoding), error=$error_msg") if $'loglvl > 18; if (length $error) { @@ -515,7 +526,7 @@ } else { @$aref = split(/\r?\n/, $$output); } - return $entity_content; + return ($entity_content, $entity); } # Skip past named boundary in the supplied array Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-06-13 14:05:31 UTC (rev 41) +++ trunk/mailagent/revision.h 2008-06-13 16:44:42 UTC (rev 42) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 40 +#define REVISION 41 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-13 21:19:31
|
Revision: 43 http://mailagent.svn.sourceforge.net/mailagent/?rev=43&view=rev Author: rmanfredi Date: 2008-06-13 14:19:28 -0700 (Fri, 13 Jun 2008) Log Message: ----------- Protect against SIGPIPE during BOUNCE and FORWARD, relying on the exit code at close() time to detect failures. (closes Debian bug #267879) Modified Paths: -------------- trunk/mailagent/agent/pl/actions.pl trunk/mailagent/agent/test/actions trunk/mailagent/agent/test/cmd/bounce.t trunk/mailagent/agent/test/cmd/forward.t trunk/mailagent/revision.h Modified: trunk/mailagent/agent/pl/actions.pl =================================================================== --- trunk/mailagent/agent/pl/actions.pl 2008-06-13 16:44:42 UTC (rev 42) +++ trunk/mailagent/agent/pl/actions.pl 2008-06-13 21:19:28 UTC (rev 43) @@ -670,6 +670,7 @@ if $loglvl; return 1; } + local $SIG{PIPE} = 'IGNORE'; # sendmail failure caught at close() time local(@addr) = split(' ', $addresses); print MAILER &header'format("Resent-From: $address"), "\n"; local($to) = "Resent-To: " . join(', ', @addr); @@ -706,6 +707,7 @@ if $loglvl; return 1; } + local $SIG{PIPE} = 'IGNORE'; # sendmail failure caught at close() time # Protect Sender: lines in the original message foreach (split(/\n/, $Header{'Head'})) { next if /^From\s+(\S+)/; Modified: trunk/mailagent/agent/test/actions =================================================================== --- trunk/mailagent/agent/test/actions 2008-06-13 16:44:42 UTC (rev 42) +++ trunk/mailagent/agent/test/actions 2008-06-13 21:19:28 UTC (rev 43) @@ -149,6 +149,8 @@ X-Tag: /bounce 1/ { BOUNCE nobody }; X-Tag: /bounce 2/ { BOUNCE "list" }; +X-Tag: /bounce 3/ { BOUNCE nobody; REJECT -f; DELETE }; +X-Tag: /bounce 3/ { SAVE ok }; X-Tag: /delete/ { DELETE }; @@ -172,6 +174,8 @@ X-Tag: /forward 1/ { FORWARD nobody }; X-Tag: /forward 2/ { FORWARD "list" }; +X-Tag: /forward 3/ { FORWARD nobody; REJECT -f; DELETE }; +X-Tag: /forward 3/ { SAVE ok }; X-Tag: /give 1/ { GIVE wc > output }; X-Tag: /give 2/ { GIVE cat > output }; Modified: trunk/mailagent/agent/test/cmd/bounce.t =================================================================== --- trunk/mailagent/agent/test/cmd/bounce.t 2008-06-13 16:44:42 UTC (rev 42) +++ trunk/mailagent/agent/test/cmd/bounce.t 2008-06-13 21:19:28 UTC (rev 43) @@ -45,6 +45,20 @@ &check_log('^To: ram', 13) == 1 || print "14\n"; &check_log('^Recipients: first second third$', 15) == 1 || print "16\n"; +unlink 'send.mail', 'ok'; + +&replace_header('X-Tag: bounce 3'); +open(MSEND, '>msend'); +print MSEND <<'EOM'; +#!/bin/sh +exit 1 +EOM +close MSEND; +`$cmd`; +$? == 0 || print "17\n"; +-f "$user" && print "18\n"; # Mail not saved +-f 'ok' || print "19\n"; # Failure caught by "REJECT -f" + &clear_mta; -unlink 'mail', 'list'; +unlink 'mail', 'list', 'ok'; print "0\n"; Modified: trunk/mailagent/agent/test/cmd/forward.t =================================================================== --- trunk/mailagent/agent/test/cmd/forward.t 2008-06-13 16:44:42 UTC (rev 42) +++ trunk/mailagent/agent/test/cmd/forward.t 2008-06-13 21:19:28 UTC (rev 43) @@ -48,6 +48,20 @@ &check_log('^To: ram', 21) == 1 || print "22\n"; &check_log('^Recipients: first second third$', 23) == 1 || print "24\n"; +unlink 'send.mail', 'ok'; + +&replace_header('X-Tag: forward 3'); +open(MSEND, '>msend'); +print MSEND <<'EOM'; +#!/bin/sh +exit 1 +EOM +close MSEND; +`$cmd`; +$? == 0 || print "25\n"; +-f "$user" && print "26\n"; # Mail not saved +-f 'ok' || print "27\n"; # Failure caught by "REJECT -f" + &clear_mta; -unlink 'mail', 'list'; +unlink 'mail', 'list', 'ok'; print "0\n"; Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-06-13 16:44:42 UTC (rev 42) +++ trunk/mailagent/revision.h 2008-06-13 21:19:28 UTC (rev 43) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 41 +#define REVISION 42 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-14 20:58:10
|
Revision: 45 http://mailagent.svn.sourceforge.net/mailagent/?rev=45&view=rev Author: rmanfredi Date: 2008-06-14 13:58:05 -0700 (Sat, 14 Jun 2008) Log Message: ----------- Private unit fixing after running metalint. Modified Paths: -------------- trunk/mailagent/U/Myinit.U trunk/mailagent/U/mboxlock.U trunk/mailagent/revision.h Modified: trunk/mailagent/U/Myinit.U =================================================================== --- trunk/mailagent/U/Myinit.U 2008-06-13 21:41:39 UTC (rev 44) +++ trunk/mailagent/U/Myinit.U 2008-06-14 20:58:05 UTC (rev 45) @@ -18,7 +18,9 @@ ?X: is included after variables are initialized but before any old ?X: config.sh file is read in. ?X: -?MAKE:Myinit: Init +?MAKE:libswanted Myinit: Init ?MAKE: -pick add $@ %< +?LINT:describe libswanted +: private initializations libswanted='' Modified: trunk/mailagent/U/mboxlock.U =================================================================== --- trunk/mailagent/U/mboxlock.U 2008-06-13 21:41:39 UTC (rev 44) +++ trunk/mailagent/U/mboxlock.U 2008-06-14 20:58:05 UTC (rev 45) @@ -7,7 +7,7 @@ ?RCS: Licence as specified in the README file that comes with dist. ?RCS: ?RCS: $Log -?MAKE:d_lockflock d_flockonly lock_by_flock flock_only: cat contains d_flock Myread +usrinc Setvar Oldconfig +?MAKE:d_lockflock d_flockonly lock_by_flock flock_only: cat contains d_flock Myread +usrinc Setvar Oldconfig package ?MAKE: -pick add $@ %< ?S:d_lockflock: ?S: This variable conditionally defines the LOCK_BY_FLOCK symbol, which @@ -34,6 +34,8 @@ ?C:. ?H:#$d_lockflock LOCK_BY_FLOCK /**/ ?H:#$d_flockonly FLOCK_ONLY /**/ +?H:. +?LINT:set d_lockflock d_flockonly : see which mailbox locking should be used echo " " lock_by_flock='' @@ -76,7 +78,7 @@ EOM rp="Would you like to use flock style mail spool locking only?" - . myread + . ./myread case "$ans" in y*|Y*) val="$define";; *) val="$undef";; Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-06-13 21:41:39 UTC (rev 44) +++ trunk/mailagent/revision.h 2008-06-14 20:58:05 UTC (rev 45) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 42 +#define REVISION 44 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-07-02 21:59:47
|
Revision: 57 http://mailagent.svn.sourceforge.net/mailagent/?rev=57&view=rev Author: rmanfredi Date: 2008-07-02 14:59:34 -0700 (Wed, 02 Jul 2008) Log Message: ----------- Fixed formatting bug when headers had a trailing blank that happened to be right at the end of the line: an empty continuation line was emitted and INN did not like that and took it as an End Of Header. Modified Paths: -------------- trunk/mailagent/README trunk/mailagent/agent/pl/header.pl trunk/mailagent/agent/test/cmd/post.t trunk/mailagent/revision.h Modified: trunk/mailagent/README =================================================================== --- trunk/mailagent/README 2008-07-01 07:33:24 UTC (rev 56) +++ trunk/mailagent/README 2008-07-02 21:59:34 UTC (rev 57) @@ -58,7 +58,6 @@ so that the new rule I am about to add to my ~/.rules may correctly redirect your message into a high priority folder :-) - There is a mailing list hosted in Japan and set up by Shigeya Suzuki <sh...@fo...>, for discussion about the mailagent package as a whole. It's a good place to ask questions (or answer them) and to @@ -93,6 +92,9 @@ Raphael Manfredi <Rap...@po...> Grenoble, France, July 12th 1999 + Raphael Manfredi <Rap...@po...> + Grenoble, France, June 28th 2008 + ======================================================================== INSTALLATION @@ -127,17 +129,7 @@ carrying useless files. You should keep this distribution intact, so that future patches will be applyable. -7) I have an automatic patch sender. Send me the following mail: - - Subject: Command - @SH mailhelp PATH - -and you'll get instructions (PATH stands for YOUR e-mail address, either -in INTERNET or in bang notation). I would recommend you to get all the -issued patches before you start making some modifications on this -package. - -8) If you wish to de-install the package, you may run "make deinstall". +7) If you wish to de-install the package, you may run "make deinstall". A separate "make deinstall.man" will remove the manual pages. Be sure the makefiles are correctly set before running any deinstall target. On USG systems, some executable have a chance to remain despite the Modified: trunk/mailagent/agent/pl/header.pl =================================================================== --- trunk/mailagent/agent/pl/header.pl 2008-07-01 07:33:24 UTC (rev 56) +++ trunk/mailagent/agent/pl/header.pl 2008-07-02 21:59:34 UTC (rev 57) @@ -220,8 +220,11 @@ $new .= "$tmp\n"; $field = substr($field, $kept, length $field); } - $new .= $cont if $new; # Add 8 chars if continuation - $new .= $field; # Remaining information on one line + unless ($field =~ /^\s+$/) { # Not only spaces + $new .= $cont if $new; # Add 8 chars if continuation + $new .= $field; # Remaining information on one line + } + return $new; } # Same as format() but with extra magic for news articles: we must never Modified: trunk/mailagent/agent/test/cmd/post.t =================================================================== --- trunk/mailagent/agent/test/cmd/post.t 2008-07-01 07:33:24 UTC (rev 56) +++ trunk/mailagent/agent/test/cmd/post.t 2008-07-02 21:59:34 UTC (rev 57) @@ -46,6 +46,20 @@ &check_log('^Newsgroups: first.news,second.news,third.news', 13); &check_log('^Distribution: local', 14); +unlink 'send.news'; +&replace_header('X-Tag: post 1'); +# Subject with a trailing space +my $subject = <<EOM; +Subject: [perl #2783] Security of ARGV using 2-argument open - It's a feature +EOM +chop $subject; +replace_header($subject); +`$cmd`; +$? == 0 || print "15\n"; +&get_log(16, 'send.news'); +# 1 EOH + 3 paragraphs in mail +&check_log('^$', 17) == 4 or print "18\n"; + &clear_mta; unlink 'mail', 'list'; print "0\n"; Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-07-01 07:33:24 UTC (rev 56) +++ trunk/mailagent/revision.h 2008-07-02 21:59:34 UTC (rev 57) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 53 +#define REVISION 56 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-05-30 09:12:25
|
Revision: 22 http://mailagent.svn.sourceforge.net/mailagent/?rev=22&view=rev Author: rmanfredi Date: 2008-05-30 02:12:22 -0700 (Fri, 30 May 2008) Log Message: ----------- Added automatic computation of the SVN revision in "revision.h", for later perusal by Configure to propagate correct revision numbers in files. Modified Paths: -------------- trunk/mailagent/Configure trunk/mailagent/MANIFEST trunk/mailagent/Makefile.SH Added Paths: ----------- trunk/mailagent/bin/svn-revision trunk/mailagent/revision.h Modified: trunk/mailagent/Configure =================================================================== --- trunk/mailagent/Configure 2008-05-30 09:09:53 UTC (rev 21) +++ trunk/mailagent/Configure 2008-05-30 09:12:22 UTC (rev 22) @@ -16,9 +16,9 @@ # The dist package (which contains metaconfig) is available via SVN: # svn co https://svn.sourceforge.net/svnroot/dist/trunk/dist -# $Id: Head.U 6 2006-08-25 22:21:46Z rmanfredi $ +# $Id: Head.U 25 2008-05-28 11:19:25Z rmanfredi $ # -# Generated on Wed May 28 11:41:09 CEST 2008 [metaconfig 3.5 PL0] +# Generated on Fri May 30 11:10:37 CEST 2008 [metaconfig 3.5-25] cat >c1$$ <<EOF ARGGGHHHH!!!!! @@ -413,6 +413,7 @@ package='' spackage='' patchlevel='' +revision='' perlpath='' pidtype='' pkgsrc='' @@ -849,7 +850,7 @@ esac shift ;; - -V) echo "$me generated by metaconfig 3.5 PL0." >&2 + -V) echo "$me generated by metaconfig 3.5-25." >&2 exit 0;; --) break;; -*) echo "$me: unknown option $1" >&2; shift; error=true;; @@ -6517,9 +6518,9 @@ : set the base revision baserev=3.0 -: get the patchlevel +: get the patchlevel / revision echo " " -echo "Getting the current patchlevel..." >&4 +echo "Getting the current patchlevel / revision..." >&4 if $test -r $rsrc/patchlevel.h;then patchlevel=`awk \ '/^#[ ]*define[ ][ ]*PATCHLEVEL/ {print $3}' \ @@ -6527,7 +6528,22 @@ else patchlevel=0 fi -echo "(You have $package $baserev PL$patchlevel.)" +if $test -r $rsrc/revision.h;then + revision=`awk \ + '/^#[ ]*define[ ][ ]*REVISION/ {print $3}' \ + < $rsrc/revision.h` +else + revision=0 +fi +case "$revision" in +0) echo "(You have $package $baserev PL$patchlevel.)" ;; +*) + case "$patchlevel" in + 0) echo "(You have $package $baserev-$revision)";; + *) echo "(You have $package $baserev-$revision PL$patchlevel)";; + esac + ;; +esac : define an is-a-typedef? function typedef='type=$1; var=$2; def=$3; shift; shift; shift; inclist=$@; @@ -7518,6 +7534,7 @@ reg8='$reg8' reg9='$reg9' registers='$registers' +revision='$revision' rm='$rm' rmail='$rmail' rootid='$rootid' @@ -7579,6 +7596,8 @@ : add special variables $test -f $src/patchlevel.h && \ awk '/^#define/ {printf "%s=%s\n",$2,$3}' $src/patchlevel.h >>config.sh +$test -f $src/revision.h && \ +awk '/^#define/ {printf "%s=%s\n",$2,$3}' $src/revision.h >>config.sh echo "CONFIG=true" >>config.sh : propagate old symbols Modified: trunk/mailagent/MANIFEST =================================================================== --- trunk/mailagent/MANIFEST 2008-05-30 09:09:53 UTC (rev 21) +++ trunk/mailagent/MANIFEST 2008-05-30 09:12:22 UTC (rev 22) @@ -298,6 +298,7 @@ agent/test/rules Rules used by filtering tests bin/ Directory for uninstalled binaries bin/perload The dataloading/autoloading perl translator +bin/svn-revision Updates the top "revision.h" file if needed config_h.SH Produces config.h confmagic.h Magic symbol remapping install.SH Installation script @@ -335,3 +336,4 @@ misc/unkit/rules Rules to be added to handle kit messages misc/unkit/unkit.pl Implementation of the user-defined UNKIT command patchlevel.h Current version number and patch level +revision.h The current SVN revision number for mailagent Modified: trunk/mailagent/Makefile.SH =================================================================== --- trunk/mailagent/Makefile.SH 2008-05-30 09:09:53 UTC (rev 21) +++ trunk/mailagent/Makefile.SH 2008-05-30 09:12:22 UTC (rev 22) @@ -1,5 +1,5 @@ -: Makefile.SH generated from Jmake.tmpl and Jmakefile [jmake 3.0 PL48] -: $X-Id: Jmake.tmpl,v 3.0.1.2 1995/01/11 14:50:21 ram Exp ram $ +: Makefile.SH generated from Jmake.tmpl and Jmakefile [jmake 3.5-25] +: $X-Id: Jmake.tmpl 8 2006-08-25 22:27:18Z rmanfredi $ case $CONFIG in '') @@ -37,7 +37,7 @@ # Parameters set by Configure -- edit config.sh if changes are needed CTAGS = ctags -MAKE = make +JCPPFLAGS = $cppflags MV = $mv RM = $rm -f @@ -50,7 +50,7 @@ $spitshell >>Makefile <<'!NO!SUBS!' ######################################################################## # Jmake rules for building libraries, programs, scripts, and data files -# $X-Id: Jmake.rules,v 3.0.1.2 1995/01/11 14:49:55 ram Exp ram $ +# $X-Id: Jmake.rules 18 2006-12-27 10:35:09Z rmanfredi $ ######################################################################## # Start of Jmakefile @@ -58,7 +58,7 @@ # $X-Id: Jmakefile,v 3.0 1993/11/29 13:47:34 ram Exp ram $ # # Copyright (c) 1990-2006, Raphael Manfredi -# +# # You may redistribute only under the terms of the Artistic License, # as specified in the README file that comes with the distribution. # You may reuse parts of this distribution only within the terms of @@ -80,28 +80,48 @@ for i in $(SUBDIRS) ;\ do \ (cd $$i ; echo "Depending" "in $(DIR)$$i..."; \ - $(MAKE) $(MFLAGS) depend); \ + $(MAKE) $(MFLAGS) depend) || exit 1; \ done +all:: revision.h + +.FORCE: + +revision.h: .FORCE + $(TOP)/bin/svn-revision $(TOP) $@ + ######################################################################## # Common rules for all Makefiles -- do not edit -emptyrule:: +all:: clean: sub_clean local_clean realclean: sub_realclean local_realclean clobber: sub_clobber local_clobber local_clean:: - $(RM) core *~ *.o + if test -f core; then $(RM) core; fi + $(RM) *~ *.o local_realclean:: local_clean $(RM) -r UU local_clobber:: local_realclean $(RM) config.sh config.h + $(RM) -r .config $(RM) Makefile +install:: local_install sub_install +install.man:: maybe_install.man sub_install.man +deinstall:: sub_deinstall local_deinstall +deinstall.man:: sub_deinstall.man maybe_deinstall.man + +install.man-no: +deinstall.man-no: + +maybe_install.man: install.man-no +maybe_deinstall.man: deinstall.man-no + Makefile.SH: Jmakefile -@if test -f $(TOP)/.package; then \ if test -f Makefile.SH; then \ @@ -110,7 +130,7 @@ fi; \ echo " $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT)" ; \ $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT) ; \ - else touch $@; exit 0; fi + else touch $@; fi Makefile: Makefile.SH /bin/sh Makefile.SH @@ -130,20 +150,22 @@ for i in $(SUBDIRS) ;\ do \ (cd $$i ; echo $(VERB) "in $(DIR)$$i..."; \ - $(MAKE) $(MFLAGS) $(FLAGS) $(TARGET)); \ + $(MAKE) $(MFLAGS) $(FLAGS) $(TARGET)) || exit 1; \ done -install:: +sub_install:: @$(MAKE) subdirs TARGET=install VERB="Installing" FLAGS= -deinstall:: +sub_deinstall:: @$(MAKE) subdirs TARGET=deinstall VERB="Deinstalling" FLAGS= + @echo "Back to $(CURRENT) for "deinstall... -install.man:: +sub_install.man:: @$(MAKE) subdirs TARGET=install.man VERB="Installing man pages" FLAGS= -deinstall.man:: +sub_deinstall.man:: @$(MAKE) subdirs TARGET=deinstall.man VERB="Deinstalling man pages" FLAGS= + @echo "Back to $(CURRENT) for "deinstall.man... sub_clean:: @$(MAKE) subdirs TARGET=clean VERB="Cleaning" FLAGS= @@ -162,7 +184,7 @@ for i in $(SUBDIRS) ;\ do \ (cd $$i ; echo "Tagging" "in $(DIR)$$i..."; \ - $(MAKE) $(MFLAGS) tag); \ + $(MAKE) $(MFLAGS) tag) || exit 1; \ done Makefiles:: @@ -172,7 +194,7 @@ echo "Making "Makefiles" in $(DIR)$$i..."; \ (cd $$i || exit 1; \ if test ! -f Makefile; then /bin/sh Makefile.SH; fi; \ - $(MAKE) $(MFLAGS) Makefiles) \ + $(MAKE) $(MFLAGS) Makefiles) || exit 1;\ done Makefiles.SH:: Makefile.SH @@ -189,14 +211,23 @@ /*) newtop="$(TOP)" ;; \ esac; \ echo "Making Makefiles.SH in $(DIR)$$i..."; \ - (cd $$i || exit 1; $(MAKE) $(MFLAGS) -f ../Makefile \ - Makefile TOP=$$newtop CURRENT=$(DIR)$$i;\ - $(MAKE) $(MFLAGS) Makefiles.SH) \ + (cd $$i || exit 1; \ + if test -f Jmakefile; then \ + $(MAKE) $(MFLAGS) -f ../Makefile \ + Makefile TOP=$$newtop CURRENT=$(DIR)$$i && \ + $(MAKE) $(MFLAGS) Makefiles.SH; \ + fi; \ + ) || exit 1; \ done all:: @$(MAKE) subdirs TARGET=all VERB="Making all" FLAGS= +local_install:: +local_deinstall:: +local_install.man:: +local_deinstall.man:: + !NO!SUBS! chmod 644 Makefile $eunicefix Makefile Added: trunk/mailagent/bin/svn-revision =================================================================== --- trunk/mailagent/bin/svn-revision (rev 0) +++ trunk/mailagent/bin/svn-revision 2008-05-30 09:12:22 UTC (rev 22) @@ -0,0 +1,61 @@ +#!/bin/sh + +# +# $Id: svn-revision 12303 2006-11-11 08:11:46Z cbiere $ +# +# Copyright (c) 2006, Raphael Manfredi +# +# You may redistribute only under the terms of the Artistic Licence, +# as specified in the README file that comes with the distribution. +# You may reuse parts of this distribution only within the terms of +# that same Artistic Licence; a copy of which may be found at the root +# of the source tree for dist 4.0. +# +# Computes SVN current revision number, if possible, emitting it in +# the form of a #define for C perusal. +# + +LC_ALL=C +export LC_ALL + +TOP="$1" +FILE="$2" + +if [ "x$FILE" = x ]; then + FILE="&1" + oldrev='' +else + oldrev=`grep REVISION "$FILE" 2>/dev/null | head -n1 | cut -d' ' -f3` +fi + +if test -d "$TOP/.svn"; then + revnum=`svn info "$TOP" 2>/dev/null | grep '^Revision' | head -n1 | cut -d' ' -f2` +else + revnum="$oldrev" # keep as is +fi + +if [ "x$revnum" = "x$oldrev" ]; then + exit 0 +fi + +{ +stamp=`date +"%Y-%m-%d %H:%M:%d %z"` +cat <<EOF +/* + * THIS FILE IS AUTOMATICALLY GENERATED -- DO NOT EDIT + * + * Generated by $0. + */ + +EOF + +if [ "x$revnum" = x ]; then + echo '/* Subversion information not available */' +else + cat <<EOF +#define REVISION $revnum +EOF +fi + +} > "$FILE" + Property changes on: trunk/mailagent/bin/svn-revision ___________________________________________________________________ Name: svn:executable + * Added: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h (rev 0) +++ trunk/mailagent/revision.h 2008-05-30 09:12:22 UTC (rev 22) @@ -0,0 +1,7 @@ +/* + * THIS FILE IS AUTOMATICALLY GENERATED -- DO NOT EDIT + * + * Generated by ./bin/svn-revision. + */ + +#define REVISION 21 Property changes on: trunk/mailagent/revision.h ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-04 12:22:26
|
Revision: 29 http://mailagent.svn.sourceforge.net/mailagent/?rev=29&view=rev Author: rmanfredi Date: 2008-06-04 05:22:16 -0700 (Wed, 04 Jun 2008) Log Message: ----------- Forgot to change on X-Filter line to use the new version numbering scheme. Modified Paths: -------------- trunk/mailagent/agent/magent.sh trunk/mailagent/revision.h Modified: trunk/mailagent/agent/magent.sh =================================================================== --- trunk/mailagent/agent/magent.sh 2008-06-03 12:01:08 UTC (rev 28) +++ trunk/mailagent/agent/magent.sh 2008-06-04 12:22:16 UTC (rev 29) @@ -529,7 +529,7 @@ sub patch_constants { local($address) = &email_addr; # Will prefer cf vars to hardwired ones $FILTER = - "X-Filter: mailagent [version $mversion PL$patchlevel] for $address"; + "X-Filter: mailagent [version $mversion-$revision] for $address"; } # Initializes environment. All the variables are initialized in XENV array Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-06-03 12:01:08 UTC (rev 28) +++ trunk/mailagent/revision.h 2008-06-04 12:22:16 UTC (rev 29) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 26 +#define REVISION 28 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-06 11:18:46
|
Revision: 32 http://mailagent.svn.sourceforge.net/mailagent/?rev=32&view=rev Author: rmanfredi Date: 2008-06-06 04:18:20 -0700 (Fri, 06 Jun 2008) Log Message: ----------- To allow revision updating in scripts without having to run Configure, make sure each .SH extracts the revision from the "revision.h" file. Modified Paths: -------------- trunk/mailagent/agent/edusers.SH trunk/mailagent/agent/magent.sh trunk/mailagent/agent/maildist.SH trunk/mailagent/agent/mailhelp.SH trunk/mailagent/agent/maillist.SH trunk/mailagent/agent/mailpatch.SH trunk/mailagent/agent/package.SH trunk/mailagent/revision.h Modified: trunk/mailagent/agent/edusers.SH =================================================================== --- trunk/mailagent/agent/edusers.SH 2008-06-06 11:15:25 UTC (rev 31) +++ trunk/mailagent/agent/edusers.SH 2008-06-06 11:18:20 UTC (rev 32) @@ -11,6 +11,7 @@ . $TOP/config.sh ;; esac +revision=`awk '/^#define[ ]*REVISION/ {print $3}' < $TOP/revision.h` case "$0" in */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac @@ -43,7 +44,7 @@ \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; -\$revision = '$REVISION'; +\$revision = '$revision'; \$defeditor = '$defeditor'; \$phostname = '$phostname'; \$long_filenames = '$d_flexfnam' eq 'define'; Modified: trunk/mailagent/agent/magent.sh =================================================================== --- trunk/mailagent/agent/magent.sh 2008-06-06 11:15:25 UTC (rev 31) +++ trunk/mailagent/agent/magent.sh 2008-06-06 11:18:20 UTC (rev 32) @@ -14,6 +14,7 @@ case "$0" in */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac +revision=`awk '/^#define[ ]*REVISION/ {print $3}' < $TOP/revision.h` echo "Extracting agent/magent (with variable substitutions)" $spitshell >magent <<!GROK!THIS! $startperl @@ -129,7 +130,7 @@ # Current version number and patchlevel \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; -\$revision = '$REVISION'; +\$revision = '$revision'; # Want to lock mailboxes with flock ? \$lock_by_flock = '$lock_by_flock'; Modified: trunk/mailagent/agent/maildist.SH =================================================================== --- trunk/mailagent/agent/maildist.SH 2008-06-06 11:15:25 UTC (rev 31) +++ trunk/mailagent/agent/maildist.SH 2008-06-06 11:18:20 UTC (rev 32) @@ -11,6 +11,7 @@ . $TOP/config.sh ;; esac +revision=`awk '/^#define[ ]*REVISION/ {print $3}' < $TOP/revision.h` case "$0" in */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac @@ -54,7 +55,7 @@ \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; -\$revision = '$REVISION'; +\$revision = '$revision'; !GROK!THIS! $spitshell >>maildist <<'!NO!SUBS!' Modified: trunk/mailagent/agent/mailhelp.SH =================================================================== --- trunk/mailagent/agent/mailhelp.SH 2008-06-06 11:15:25 UTC (rev 31) +++ trunk/mailagent/agent/mailhelp.SH 2008-06-06 11:18:20 UTC (rev 32) @@ -11,6 +11,7 @@ . $TOP/config.sh ;; esac +revision=`awk '/^#define[ ]*REVISION/ {print $3}' < $TOP/revision.h` case "$0" in */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac @@ -46,7 +47,7 @@ \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; -\$revision = '$REVISION'; +\$revision = '$revision'; !GROK!THIS! $spitshell >>mailhelp <<'!NO!SUBS!' Modified: trunk/mailagent/agent/maillist.SH =================================================================== --- trunk/mailagent/agent/maillist.SH 2008-06-06 11:15:25 UTC (rev 31) +++ trunk/mailagent/agent/maillist.SH 2008-06-06 11:18:20 UTC (rev 32) @@ -11,6 +11,7 @@ . $TOP/config.sh ;; esac +revision=`awk '/^#define[ ]*REVISION/ {print $3}' < $TOP/revision.h` case "$0" in */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac @@ -56,7 +57,7 @@ \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; -\$revision = '$REVISION'; +\$revision = '$revision'; \$phostname = '$phostname'; !GROK!THIS! Modified: trunk/mailagent/agent/mailpatch.SH =================================================================== --- trunk/mailagent/agent/mailpatch.SH 2008-06-06 11:15:25 UTC (rev 31) +++ trunk/mailagent/agent/mailpatch.SH 2008-06-06 11:18:20 UTC (rev 32) @@ -11,6 +11,7 @@ . $TOP/config.sh ;; esac +revision=`awk '/^#define[ ]*REVISION/ {print $3}' < $TOP/revision.h` case "$0" in */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac @@ -58,7 +59,7 @@ \$zcat = '$zcat'; \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; -\$revision = '$REVISION'; +\$revision = '$revision'; !GROK!THIS! $spitshell >>mailpatch <<'!NO!SUBS!' Modified: trunk/mailagent/agent/package.SH =================================================================== --- trunk/mailagent/agent/package.SH 2008-06-06 11:15:25 UTC (rev 31) +++ trunk/mailagent/agent/package.SH 2008-06-06 11:18:20 UTC (rev 32) @@ -11,6 +11,7 @@ . $TOP/config.sh ;; esac +revision=`awk '/^#define[ ]*REVISION/ {print $3}' < $TOP/revision.h` case "$0" in */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac @@ -76,7 +77,7 @@ \$zcat = '$zcat'; \$mversion = '$VERSION'; \$patchlevel = '$PATCHLEVEL'; -\$revision = '$REVISION'; +\$revision = '$revision'; \$phostname = '$phostname'; \$long_filenames = '$d_flexfnam' eq 'define'; !GROK!THIS! Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-06-06 11:15:25 UTC (rev 31) +++ trunk/mailagent/revision.h 2008-06-06 11:18:20 UTC (rev 32) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 28 +#define REVISION 29 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-06 11:49:55
|
Revision: 33 http://mailagent.svn.sourceforge.net/mailagent/?rev=33&view=rev Author: rmanfredi Date: 2008-06-06 04:49:48 -0700 (Fri, 06 Jun 2008) Log Message: ----------- Fixed logging messages for BEGIN and for entering new states. Modified Paths: -------------- trunk/mailagent/agent/pl/filter.pl trunk/mailagent/revision.h Modified: trunk/mailagent/agent/pl/filter.pl =================================================================== --- trunk/mailagent/agent/pl/filter.pl 2008-06-06 11:18:20 UTC (rev 32) +++ trunk/mailagent/agent/pl/filter.pl 2008-06-06 11:49:48 UTC (rev 33) @@ -237,7 +237,7 @@ return 0 if $opt'sw_f && !$lastcmd; # -f means change only if false $newstate = 'INITIAL' unless $newstate; $wmode = $newstate; # $wmode comes from analyze_mail - &add_log("BEGUN new state $newstate") if $loglvl > 4; + &add_log("BEGUN [$mfile] state $newstate") if $loglvl > 4; 0; } @@ -248,8 +248,12 @@ $mode =~ s|^(\w*)\s*\(([^()]*)\).*|$1| && ($tags = $2); local($failed) = 0; if (&history_tag($tags)) { # Message already seen - $wmode = '_SEEN_'; # Enter special mode ($wmode from analyze_mail) - &add_log("NOTICE entering seen mode") if $loglvl > 5; + if ($mode eq '') { + &add_log("NOTICE entering seen mode") + if $loglvl > 5 && $wmode ne '_SEEN_'; + # Enter special mode ($wmode from analyze_mail) + $wmode = '_SEEN_'; + } &alter_execution('x', $mode); $failed = 1; # Make sure it "fails" } @@ -866,7 +870,7 @@ sub alter_execution { local($option, $mode) = @_; # Option, mode we have to change to if ($mode ne '') { - &add_log("entering new state $wmode") if $loglvl > 6 && $wmode ne $mode; + &add_log("entering new state $mode") if $loglvl > 6 && $wmode ne $mode; $wmode = $mode; } if ($option eq 'x') { # Backward compatibility at 3.0 PL24 Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-06-06 11:18:20 UTC (rev 32) +++ trunk/mailagent/revision.h 2008-06-06 11:49:48 UTC (rev 33) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 29 +#define REVISION 32 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-13 13:51:40
|
Revision: 40 http://mailagent.svn.sourceforge.net/mailagent/?rev=40&view=rev Author: rmanfredi Date: 2008-06-13 06:50:11 -0700 (Fri, 13 Jun 2008) Log Message: ----------- Added minimal MIME handling for biffing to extract the text/plain part of the message, if available. If only text/html is available, the HTML is stripped for compact emission on the terminal. Modified Paths: -------------- trunk/mailagent/MANIFEST trunk/mailagent/agent/pl/biff.pl trunk/mailagent/agent/test/actions trunk/mailagent/agent/test/cmd/biff.t trunk/mailagent/revision.h Added Paths: ----------- trunk/mailagent/agent/test/mime Modified: trunk/mailagent/MANIFEST =================================================================== --- trunk/mailagent/MANIFEST 2008-06-13 09:43:39 UTC (rev 39) +++ trunk/mailagent/MANIFEST 2008-06-13 13:50:11 UTC (rev 40) @@ -267,6 +267,7 @@ agent/test/filter/status.t Action status updating tests agent/test/level Default logging level for tests agent/test/mail The mail used by testing routines +agent/test/mime Sample MIME email with HTML and plain parts agent/test/misc/ Directory for miscellaneous tests agent/test/misc/compress.t Folder compression checks agent/test/misc/mh.t MH-style folder checks @@ -301,7 +302,7 @@ agent/test/pl/misc.pl Set up for miscellaneous tests agent/test/pl/mta.pl Trivial MTA and NTA for tests agent/test/qp Sample quoted-printable encoded email -agent/test/rules Rules used by filtering tests +agent/test/rules Rules used by filtering tests bin/ Directory for uninstalled binaries bin/perload The dataloading/autoloading perl translator bin/svn-revision Updates the top "revision.h" file if needed Modified: trunk/mailagent/agent/pl/biff.pl =================================================================== --- trunk/mailagent/agent/pl/biff.pl 2008-06-13 09:43:39 UTC (rev 39) +++ trunk/mailagent/agent/pl/biff.pl 2008-06-13 13:50:11 UTC (rev 40) @@ -230,7 +230,7 @@ local($trim) = @_; # Whether top reply text should be trimmed local($len) = defined $cf'bifflen ? $cf'bifflen : 560; local($lines) = defined $cf'bifflines ? $cf'bifflines : 7; - local(@body) = split(/\n/, $'Header{'Body'}); + local(@body) = split(/\n/, ${$'Header{'=Body='}}); local($skipnl) = $cf'biffnl =~ /OFF/i; # Skip blank lines? local($_); local($res) = ''; @@ -238,6 +238,13 @@ # Setting bifflen or bifflines to 0 means no body return '' if $len == 0 || $lines == 0; + my $content; + $content = unmime(\@body) if $'Header{'Mime-Version'}; + + &'add_log("retained content for biffing is $content") + if length($content) && $'loglvl > 8; + + strip_html(\@body) if $content =~ /html\b/; &trim(*body) if $trim; # Smart trim of leading reply text &mh(*body, $len) if $cf'biffmh =~ /^on/i; @@ -424,5 +431,170 @@ push(@ary, $body); # Remaining information on one line } +# Un-MIME the body by removing all the MIME headers and looking for the +# first text entity in the message. +# The supplied array is updated in-place and will contain on return the +# lines of the MIME entity that was retained. +# Returns the type of the retained MIME entity. +# NB: if no text part is found, the array will be empty upon return. +sub unmime { + my ($aref) = @_; + my $content = lc($'Header{'Content-Type'}); + $content =~ s/\(.*?\)\s*//g; # Removed allowed RFC822 comments + + &'add_log("global MIME content-type is $content") if $'loglvl > 16; + return $content unless $content =~ m|^multipart/|; + + my ($boundary) = $content =~ /boundary=(\S+);/; + ($boundary) = $content =~ /boundary=(\S+)/ unless length $boundary; + $boundary = $1 if $boundary =~ /^"(.*)"/ || $boundary =~ /^'(.*)'/; + + # We do not perform a recursive MIME parsing here + + my $entity_content; + my $header; + + &'add_log("searching text part for biffing, boundary=$boundary") + if $'loglvl > 16; + + my @entity; + my $grabbed = 0; + + for (;;) { + unless ($grabbed) { + return undef unless skip_past($aref, $boundary); + } + $grabbed = 0; + $header = parse_header($aref); + $entity_content = lc($header->{'Content-Type'}); + $entity_content =~ s/\(.*?\)\s*//g; + &'add_log("parsed entity header: content is $entity_content") + if $'loglvl > 19; + if ($entity_content =~ m|^text/|) { + # We found (another) text part, collect it... + @entity = (); + my $end = !skip_past($aref, $boundary, \@entity); + $grabbed = 1; # Avoid skipping at next loop iteration + last if $entity_content eq "text/plain"; # We found the best one + last if $end; + } + } + + &'add_log("kept entity $entity_content for biffing") if $'loglvl > 18; + + # Maybe the entity bears a transfer encoding? + my $entity_encoding = $header->{'Content-Transfer-Encoding'}; + $entity_encoding =~ s/\(.*?\)\s*//g; + + # XXX code duplication with body_check(), factorize some day... + my $output; + my $error; + + if ($entity_encoding =~ /^base64\s*$/i) { + base64'reset(length $'Header{'Body'}); + foreach my $d (@entity) { + base64'decode($d); + } + $error = base64'error_msg(); + $output = base64'output(); + } elsif ($entity_encoding =~ /^quoted-printable\s*$/i) { + qp'reset(length $'Header{'Body'}); + foreach my $d (@entity) { + qp'decode($d); + } + $error = qp'error_msg(); + $output = qp'output(); + } else { + $error = "no encoding"; + } + + &'add_log("decoded entity ($entity_encoding), error=$error") + if $'loglvl > 18; + + if (length $error) { + @$aref = @entity; + } else { + @$aref = split(/\r?\n/, $$output); + } + return $entity_content; +} + +# Skip past named boundary in the supplied array +# If $collect is a defined ARRAY ref, push there all the lines we see until +# the next boundary. +# Return false when we see the LAST boundary in the message, meaning there +# are no more parts to consider. +sub skip_past { + my ($aref, $boundary, $collect) = @_; + my $l; + while (defined ($l = shift @$aref)) { + return 0 if $l eq "--$boundary--"; + return 1 if $l eq "--$boundary"; + push(@$collect, $l) if defined $collect; + } + return undef; # Not found +} + +# Parse embedded MIME headers, returning hash ref +sub parse_header { + my ($aref) = @_; + my %header; + my $val; + my $last_header; + my $l; + my $saw_something = 0; + while (defined ($l = shift @$aref)) { + last if $l =~ /^$/ && $saw_something; + $saw_something++; + if ($l =~ /^\s/) { + $l =~ s/^\s+/ /; + $header{$last_header} .= $l if length $last_header; + } elsif (my ($field, $value) = $l =~ /^([!-9;-~\w-]+):\s*(.*)/) { + $last_header = header'normalize($field); + if ($header{$last_header} ne '') { + $header{$last_header} .= "\n" . $value; + } else { + $header{$last_header} = $value; + } + } + } + return \%header; +} + +# Strip HTML in-place and remove spurious blank lines +# This is done only on a best-effort basis to make the biff output nice +sub strip_html { + my ($aref) = @_; + my @out; + my $in_style = 0; + my $is_nl; + my $last_was_nl = 0; + my $l; + + while (defined ($l = shift @$aref)) { + $in_style++ while $l =~ s/<style\b.*?>//; + $in_style-- while $l =~ s|</style>||; + next if $in_style; + $l =~ s/<[^\0]*?>//g; + $l =~ s/&(\w)cedil;/$1/g; + $l =~ s/&(\w)acute;/$1/g; + $l =~ s/&(\w)grave;/$1/g; + $l =~ s/&(\w)circ;/$1/g; + $l =~ s/&(\w)uml;/$1/g; + $l =~ s/"/'/g; + $l =~ s/ / /g; + $l =~ s/ / /g; # Same as + $l =~ s/&#(\d+);/chr($1)/g; # Corect only for the ASCII part... + $l =~ s/&/&/g; # Must come last + $l =~ s/^\s*//; + $is_nl = 0 == length($l); + next if $last_was_nl && $is_nl; + $last_was_nl = $is_nl; + push(@out, $l); + } + + @$aref = @out; +} + package main; Modified: trunk/mailagent/agent/test/actions =================================================================== --- trunk/mailagent/agent/test/actions 2008-06-13 09:43:39 UTC (rev 39) +++ trunk/mailagent/agent/test/actions 2008-06-13 13:50:11 UTC (rev 40) @@ -145,6 +145,7 @@ X-Tag: /biff 1/ { BIFF off; LEAVE; BIFF on; SAVE ok }; X-Tag: /biff 2/ { BIFF bfmt; SAVE ok; BIFF -l off; LEAVE }; +X-Tag: /biff 3/ { BIFF bfmt; SAVE ok; }; X-Tag: /bounce 1/ { BOUNCE nobody }; X-Tag: /bounce 2/ { BOUNCE "list" }; Modified: trunk/mailagent/agent/test/cmd/biff.t =================================================================== --- trunk/mailagent/agent/test/cmd/biff.t 2008-06-13 09:43:39 UTC (rev 39) +++ trunk/mailagent/agent/test/cmd/biff.t 2008-06-13 13:50:11 UTC (rev 40) @@ -74,8 +74,22 @@ &check_log('^\rTo: ram', 31) == 1 || print "32\n"; &check_log('^Got mail in ~/ok', 33) == 1 || print "34\n"; &check_log('^\r####', 35) == 1 || print "36\n"; -¬_log('^\r----', 37); +&check_log('moderated usenet', 37) == 1 || print "38\n"; +¬_log('^\r----', 39); +&cleanup; +cp_mail("../mime"); +&add_header('X-Tag: biff 3'); +&make_tty(0, 0777, 40); # 40 & 41 +`$cmd`; +$? == 0 || print "41\n"; +-f 'ok' || print "42\n"; +-s 'tty0' || print "43\n"; +&get_log(44, 'tty0'); +¬_log('--foo', 45); +&check_log('^Got mail in ~/ok', 46) == 1 || print "47\n"; +&check_log('successfully decoded', 48) == 1 || print "49\n"; + &cleanup; unlink 'mail'; print "0\n"; Added: trunk/mailagent/agent/test/mime =================================================================== --- trunk/mailagent/agent/test/mime (rev 0) +++ trunk/mailagent/agent/test/mime 2008-06-13 13:50:11 UTC (rev 40) @@ -0,0 +1,38 @@ +From rap...@po... Tue Jun 10 17:44:12 2008 +Received: from tours.ram.loc (fetchmail@localhost [127.0.0.1]) + by tours.ram.loc (8.14.3/8.13.8/Debian-3) with ESMTP id m5AFiCJq002957 + for <ram@localhost>; Tue, 10 Jun 2008 17:44:12 +0200 +From: "Raphael Manfredi" <Rap...@po...> +To: "Raphael Manfredi" <Rap...@po...> +Date: Tue, 10 Jun 2008 15:35:21 +0000 +Subject: Sample MIME message +Message-ID: <D42...@GV...> +MIME-Version: 1.0 +Content-Type: multipart/alternative; boundary="foo" +Status: RO +Content-Length: 609 +Lines: 22 + +--foo +Content-Type: text/html; charset="iso8859-1" + +<html> +<head> + <title>Sample HTML part</title> +</head> +<body> + <p>Sole paragraph</p> +</body> +</html> + +--foo +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: base64 +Content-Length: 346 + +VGhpcyBtZXNzYWdlIGlzIG9uZSBiaWcgTUlNRSBwYXJ0IHRoYXQgaGFzIGJlZW4gYmFzZTY0LWVu +Y29kZWQuDQoNClRoZSBtYWlsYWdlbnQgdGVzdCBzdWl0ZSBpcyBnb2luZyB0byBsb29rIGZvciB0 +aGUgZm9sbG93aW5nIGxpbmU6DQoNCiAgICAgICAgKioqIFlFUywgc3VjY2Vzc2Z1bGx5IGRlY29k +ZWQgKioqDQoNCmluIHRoZSBkZWNvZGVkIGJvZHkgYXMgcHJvb2YgdGhhdCB0aGUgYmFzZTY0IGRl +Y29kaW5nIGxvZ2ljIGlzIHdvcmtpbmcuDQo= +--foo-- Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-06-13 09:43:39 UTC (rev 39) +++ trunk/mailagent/revision.h 2008-06-13 13:50:11 UTC (rev 40) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 37 +#define REVISION 39 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-27 17:02:13
|
Revision: 53 http://mailagent.svn.sourceforge.net/mailagent/?rev=53&view=rev Author: rmanfredi Date: 2008-06-27 10:02:06 -0700 (Fri, 27 Jun 2008) Log Message: ----------- Biffing now probes the terminal size using a termios ioctl. Message is lined-wrapped cleanly on terminals, and long lines wrapping over are accounted for when computing the limit of lines we have to show for a message body. Modified Paths: -------------- trunk/mailagent/Configure trunk/mailagent/MANIFEST trunk/mailagent/agent/magent.sh trunk/mailagent/agent/man/mailagent.SH trunk/mailagent/agent/pl/Jmakefile trunk/mailagent/agent/pl/Makefile.SH trunk/mailagent/agent/pl/biff.pl trunk/mailagent/config_h.SH trunk/mailagent/revision.h Added Paths: ----------- trunk/mailagent/agent/pl/termios/ trunk/mailagent/agent/pl/termios/Jmakefile trunk/mailagent/agent/pl/termios/Makefile.SH trunk/mailagent/agent/pl/termios/termios_ph.c trunk/mailagent/agent/pl/termios/termios_pl.sh Modified: trunk/mailagent/Configure =================================================================== --- trunk/mailagent/Configure 2008-06-27 16:41:09 UTC (rev 52) +++ trunk/mailagent/Configure 2008-06-27 17:02:06 UTC (rev 53) @@ -18,7 +18,7 @@ # $Id: Head.U 25 2008-05-28 11:19:25Z rmanfredi $ # -# Generated on Fri May 30 11:10:37 CEST 2008 [metaconfig 3.5-25] +# Generated on Wed Jun 25 19:17:28 CEST 2008 [metaconfig 3.5-25] cat >c1$$ <<EOF ARGGGHHHH!!!!! @@ -249,6 +249,7 @@ vi='' zcat='' zip='' +libswanted='' hint='' myuname='' osname='' @@ -540,6 +541,7 @@ : full support for void wanted by default defvoidused=15 +: private initializations libswanted='' : Find the basic shell for Bourne shell scripts @@ -5837,7 +5839,7 @@ EOM rp="Would you like to use flock style mail spool locking only?" - . myread + . ./myread case "$ans" in y*|Y*) val="$define";; *) val="$undef";; @@ -7457,6 +7459,7 @@ libsfiles='$libsfiles' libsfound='$libsfound' libspath='$libspath' +libswanted='$libswanted' line='$line' lint='$lint' lkflags='$lkflags' Modified: trunk/mailagent/MANIFEST =================================================================== --- trunk/mailagent/MANIFEST 2008-06-27 16:41:09 UTC (rev 52) +++ trunk/mailagent/MANIFEST 2008-06-27 17:02:06 UTC (rev 53) @@ -176,6 +176,10 @@ agent/pl/sendfile.pl Perl library to send files in shar / kit mode agent/pl/signals.pl Installs emergency signal handlers agent/pl/stats.pl Mailagent's statistics recording and printing +agent/pl/termios/Jmakefile Generic Makefile for termios.pl +agent/pl/termios/Makefile.SH Produces Makefile for termios.pl +agent/pl/termios/termios_ph.c Generates a perl view of struct winsize +agent/pl/termios/termios_pl.sh Produces termios.pl, to handle tty size agent/pl/tilde.pl Perl library to perform ~name expansion agent/pl/unpack.pl Perl library to unpack archive files agent/pl/usrmac.pl User-defined macros Modified: trunk/mailagent/agent/magent.sh =================================================================== --- trunk/mailagent/agent/magent.sh 2008-06-27 16:41:09 UTC (rev 52) +++ trunk/mailagent/agent/magent.sh 2008-06-27 17:02:06 UTC (rev 53) @@ -829,5 +829,6 @@ $grep -v '^;#' pl/install.pl >>magent $grep -v '^;#' pl/base64.pl >>magent $grep -v '^;#' pl/qp.pl >>magent +$grep -v '^;#' pl/termios/termios.pl >>magent chmod 755 magent $eunicefix magent Modified: trunk/mailagent/agent/man/mailagent.SH =================================================================== --- trunk/mailagent/agent/man/mailagent.SH 2008-06-27 16:41:09 UTC (rev 52) +++ trunk/mailagent/agent/man/mailagent.SH 2008-06-27 17:02:06 UTC (rev 53) @@ -364,8 +364,7 @@ a default hardwired format is used. Season to taste. (suggested: ~/.biffmsg). .TP .I biffnice -When \fIbiffmh\fR is turned ON, this option controls whether the compacted -message should be reformatted to nicely fit into 80 columns. +Whether the message should be reformatted to nicely fit into the terminal. (optional, defaults to OFF, suggested: ON when \fIbiffmh\fR is also ON). .TP .I biffnl @@ -3460,7 +3459,9 @@ Same as writing %-H, new line, %-B .TP %-B -The body part of the biffing message +The body part of the biffing message, with content-transfer-encoding removed. +If the message is a MIME multipart one, the text/plain part is shown. If only +a text/html part is available, the HTML markup is stripped for biffing. .TP %-H The header part of the biffing message. If shows only From:, To: Subject: and @@ -3543,10 +3544,8 @@ ----%b .Ef Note that the string \fI...more...\fR appears at the end of the body when -it has not been completely printed out on the screen, regardless of the -value of the remaining lines. This means you'll get the \fI...more...\fR -string even if all the lines from now on are blank and \fIbiffnl\fR is OFF. -And it's not possible to customize this bit, sorry. +it has not been completely printed out on the screen and the remaining +lines are not blank or similar. .SS "Trimming Leading Quotation" .PP It is a standard practice, when replying to a message, to include an @@ -3616,7 +3615,7 @@ Since this compacting is output verbatim on the tty, line breaks will occur randomly and this may make reading difficult. You may request an automatic reformatting of the compacted body by turning \fIbiffnice\fR to ON and the -biff output will fit nicely within 80 columns. +biff output will fit nicely within the terminal. .PP Unfortunately, it is not possible to customize the amount of columns that should be used for formatting: since you may biff to any tty you are logged Modified: trunk/mailagent/agent/pl/Jmakefile =================================================================== --- trunk/mailagent/agent/pl/Jmakefile 2008-06-27 16:41:09 UTC (rev 52) +++ trunk/mailagent/agent/pl/Jmakefile 2008-06-27 17:02:06 UTC (rev 53) @@ -17,5 +17,5 @@ ;# patch20: created ;# -SetSubdirs(utmp) +SetSubdirs(termios utmp) DependSubdirs() Modified: trunk/mailagent/agent/pl/Makefile.SH =================================================================== --- trunk/mailagent/agent/pl/Makefile.SH 2008-06-27 16:41:09 UTC (rev 52) +++ trunk/mailagent/agent/pl/Makefile.SH 2008-06-27 17:02:06 UTC (rev 53) @@ -1,5 +1,5 @@ -: Makefile.SH generated from Jmake.tmpl and Jmakefile [jmake 3.0 PL48] -: $X-Id: Jmake.tmpl,v 3.0.1.2 1995/01/11 14:50:21 ram Exp ram $ +: Makefile.SH generated from Jmake.tmpl and Jmakefile [jmake 3.5-25] +: $X-Id: Jmake.tmpl 8 2006-08-25 22:27:18Z rmanfredi $ case $CONFIG in '') @@ -37,20 +37,20 @@ # Parameters set by Configure -- edit config.sh if changes are needed CTAGS = ctags -MAKE = make +JCPPFLAGS = $cppflags MV = $mv RM = $rm -f ######################################################################## # Automatically generated parameters -- do not edit -SUBDIRS = utmp +SUBDIRS = termios utmp !GROK!THIS! $spitshell >>Makefile <<'!NO!SUBS!' ######################################################################## # Jmake rules for building libraries, programs, scripts, and data files -# $X-Id: Jmake.rules,v 3.0.1.2 1995/01/11 14:49:55 ram Exp ram $ +# $X-Id: Jmake.rules 18 2006-12-27 10:35:09Z rmanfredi $ ######################################################################## # Start of Jmakefile @@ -58,7 +58,7 @@ # $X-Id: Jmakefile,v 3.0.1.1 1994/10/29 17:44:36 ram Exp ram $ # # Copyright (c) 1990-2006, Raphael Manfredi -# +# # You may redistribute only under the terms of the Artistic License, # as specified in the README file that comes with the distribution. # You may reuse parts of this distribution only within the terms of @@ -75,26 +75,38 @@ for i in $(SUBDIRS) ;\ do \ (cd $$i ; echo "Depending" "in $(DIR)$$i..."; \ - $(MAKE) $(MFLAGS) depend); \ + $(MAKE) $(MFLAGS) depend) || exit 1; \ done ######################################################################## # Common rules for all Makefiles -- do not edit -emptyrule:: +all:: clean: sub_clean local_clean realclean: sub_realclean local_realclean clobber: sub_clobber local_clobber local_clean:: - $(RM) core *~ *.o + if test -f core; then $(RM) core; fi + $(RM) *~ *.o local_realclean:: local_clean local_clobber:: local_realclean $(RM) Makefile config.sh +install:: local_install sub_install +install.man:: maybe_install.man sub_install.man +deinstall:: sub_deinstall local_deinstall +deinstall.man:: sub_deinstall.man maybe_deinstall.man + +install.man-no: +deinstall.man-no: + +maybe_install.man: install.man-no +maybe_deinstall.man: deinstall.man-no + Makefile.SH: Jmakefile -@if test -f $(TOP)/.package; then \ if test -f Makefile.SH; then \ @@ -103,7 +115,7 @@ fi; \ echo " $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT)" ; \ $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT) ; \ - else touch $@; exit 0; fi + else touch $@; fi Makefile: Makefile.SH /bin/sh Makefile.SH @@ -123,20 +135,22 @@ for i in $(SUBDIRS) ;\ do \ (cd $$i ; echo $(VERB) "in $(DIR)$$i..."; \ - $(MAKE) $(MFLAGS) $(FLAGS) $(TARGET)); \ + $(MAKE) $(MFLAGS) $(FLAGS) $(TARGET)) || exit 1; \ done -install:: +sub_install:: @$(MAKE) subdirs TARGET=install VERB="Installing" FLAGS= -deinstall:: +sub_deinstall:: @$(MAKE) subdirs TARGET=deinstall VERB="Deinstalling" FLAGS= + @echo "Back to $(CURRENT) for "deinstall... -install.man:: +sub_install.man:: @$(MAKE) subdirs TARGET=install.man VERB="Installing man pages" FLAGS= -deinstall.man:: +sub_deinstall.man:: @$(MAKE) subdirs TARGET=deinstall.man VERB="Deinstalling man pages" FLAGS= + @echo "Back to $(CURRENT) for "deinstall.man... sub_clean:: @$(MAKE) subdirs TARGET=clean VERB="Cleaning" FLAGS= @@ -155,7 +169,7 @@ for i in $(SUBDIRS) ;\ do \ (cd $$i ; echo "Tagging" "in $(DIR)$$i..."; \ - $(MAKE) $(MFLAGS) tag); \ + $(MAKE) $(MFLAGS) tag) || exit 1; \ done Makefiles:: @@ -165,7 +179,7 @@ echo "Making "Makefiles" in $(DIR)$$i..."; \ (cd $$i || exit 1; \ if test ! -f Makefile; then /bin/sh Makefile.SH; fi; \ - $(MAKE) $(MFLAGS) Makefiles) \ + $(MAKE) $(MFLAGS) Makefiles) || exit 1;\ done Makefiles.SH:: Makefile.SH @@ -182,14 +196,23 @@ /*) newtop="$(TOP)" ;; \ esac; \ echo "Making Makefiles.SH in $(DIR)$$i..."; \ - (cd $$i || exit 1; $(MAKE) $(MFLAGS) -f ../Makefile \ - Makefile TOP=$$newtop CURRENT=$(DIR)$$i;\ - $(MAKE) $(MFLAGS) Makefiles.SH) \ + (cd $$i || exit 1; \ + if test -f Jmakefile; then \ + $(MAKE) $(MFLAGS) -f ../Makefile \ + Makefile TOP=$$newtop CURRENT=$(DIR)$$i && \ + $(MAKE) $(MFLAGS) Makefiles.SH; \ + fi; \ + ) || exit 1; \ done all:: @$(MAKE) subdirs TARGET=all VERB="Making all" FLAGS= +local_install:: +local_deinstall:: +local_install.man:: +local_deinstall.man:: + !NO!SUBS! chmod 644 Makefile $eunicefix Makefile Modified: trunk/mailagent/agent/pl/biff.pl =================================================================== --- trunk/mailagent/agent/pl/biff.pl 2008-06-27 16:41:09 UTC (rev 52) +++ trunk/mailagent/agent/pl/biff.pl 2008-06-27 17:02:06 UTC (rev 53) @@ -35,7 +35,7 @@ ;# mailagent-specific daemon on another host is not easy to set-up, and that ;# daemon is vaporware today anyway]. ;# -;# This package relies on pl/utmp/utmp.pl. +;# This package relies on pl/utmp/utmp.pl and pl/termios/termios.pl. # # Local biff support # @@ -65,14 +65,29 @@ $tty = "/dev/$tty" unless $'test_mode; # Re-anchor name in file system return unless -x $tty; # Return if no biffing wanted on that tty - &'add_log("biffing $cf'user on $tty") if $'loglvl > 8; + my ($row, $col) = termios'size($tty); + &'add_log("WARNING cannot compute size of $tty: $row") + if defined($row) && !defined($col) && $'loglvl > 3; + my $assuming = ""; + unless (defined $col) { + ($row, $col) = (24, 80); + $assuming = "assuming "; + } + &'add_log("biffing $cf'user on $tty ($assuming$row x $col)") + if $'loglvl > 8; local($folder) = &'tilda($path); # Replace home directory with a ~ local($n) = "\n\r"; # Use \r in case tty is in raw mode + # Biffing context containing the amount of lines we can still emit before + # reaching the size of the window, and the amount of columns we have for + # displaying the text. + local @context = ($row, $col); + unless (open(TTY, ">$tty")) { - &'add_log("ERROR cannot open $tty: $!") if $'loglvl; - &'add_log("WARNING unable to biff for $folder ($type)") if $'loglvl > 5; + &'add_log("ERROR cannot write on $tty: $!") if $'loglvl; + &'add_log("WARNING unable to biff for $folder ($type) on $tty") + if $'loglvl > 5; return; } @@ -107,7 +122,7 @@ local($format, $type) = @_; unless (open(FORMAT, $format)) { &'add_log("ERROR cannot open biff format $format: $!") if $'loglvl > 1; - &default; # Use default format then + &default; # Use default format then return; } @@ -174,9 +189,23 @@ : \02! EOM local($_); + my $reformat = $cf'biffnice =~ /^on/i; + my $width = $context[1]; while (<FORMAT>) { chop; - print TTY &'macros_subst(*_), $n; + my @lines = split($n, &'macros_subst(*_)); + if (@lines) { + foreach my $l (@lines) { + if ($reformat) { + local @tmp; + &format($l, $width, *tmp); # Format line into @tmp + $l = join($n, @tmp); + } + print TTY $l, $n; + } + } else { + print TTY $n; + } } close FORMAT; ¯o'unload; # Release customized macros @@ -188,8 +217,13 @@ # Default biffing sub default { - print TTY "$n\07New $mtype for $cf'user has arrived in $folder:$n"; + my $header = "New $mtype for $cf'user has arrived in $folder:"; + my $width = $context[1]; + my $lines = int(length($header) / $width) + 1; + $lines-- if 0 == length($header) % $width; + print TTY "$n\07$header$n"; print TTY "----$n"; + $context[0] -= $lines + 1; # Header line plus dashes print TTY &all; print TTY "$n----\07$n"; } @@ -207,15 +241,16 @@ } # Returns mail headers defined in @head, on the opened TTY -# If the header length is greater than 79 characters, it is trimmed at 76 and +# If the header length is greater than the tty width, it is trimmed and # three dots '...' are emitted to show something was truncated. # Also known as the %-H macro sub headers { local($res) = ''; + my $width = $context[1]; # tty columns foreach $head (@head) { next unless defined $'Header{$head}; - local($line) = "$head: $'Header{$head}"; - $line = substr($line, 0, 76) . '...' if length($line) >= 80; + local($line) = unquote_printable("$head: $'Header{$head}"); + $line = substr($line, 0, $width - 4) . '...' if length($line) >= $width; $res .= "$line$n"; } chop($res); # Remove final \n\r for macro substitution @@ -223,6 +258,12 @@ $res; } +# Is line a blank one? +sub is_blank { + my ($l) = @_; + return $l =~ /^[\W_]*$/; # Contains only non-words and underscores +} + # Print first $cf'bifflines lines or $cf'bifflen charaters, whichever # comes first. Assumes TTY already opened correctly # Also known as the %-B macro if called body(0), or %-T if called body(1). @@ -230,7 +271,7 @@ local($trim) = @_; # Whether top reply text should be trimmed local($len) = defined $cf'bifflen ? $cf'bifflen : 560; local($lines) = defined $cf'bifflines ? $cf'bifflines : 7; - local(@body) = split(/\n/, ${$'Header{'=Body='}}); + local(@body) = split(/\r?\n/, ${$'Header{'=Body='}}); local($skipnl) = $cf'biffnl =~ /OFF/i; # Skip blank lines? local($_); local($res) = ''; @@ -248,8 +289,29 @@ &trim(*body) if $trim; # Smart trim of leading reply text &mh(*body, $len) if $cf'biffmh =~ /^on/i; + my $reformat = $cf'biffnice =~ /^on/i; + my $width = $context[1]; + my $tl = 8; # tab length + while ($len > 0 && $lines > 0 && defined ($_ = shift(@body))) { - next if /^\W*$/ && $skipnl; + next if $skipnl && is_blank($_); + my $line_length = 0; + 1 while s|\t|' ' x ($tl - length($`) % $tl)|e; # Expand tabs + s/[\x0-\x1f]//g; # Remove all control chars + if ($reformat) { + local @tmp; + &format($_, $width, *tmp); # Format line into @tmp + @tmp = grep(!is_blank($_), @tmp) if $skipnl; + foreach my $l (@tmp) { + $line_length += length $l; # Do not count newlines + $lines--; + } + $_ = join($n, @tmp); + } else { + $line_length = length $_; + $lines -= int($line_length / $width) + 1; + $lines++ if 0 == $line_length % $width; + } # Check for overflow, in case we use mh-style biffing and no # reformatting occurred: we may be facing a huge string! if (length($_) > $len) { @@ -257,8 +319,7 @@ } else { $res .= $_ . $n; } - $len -= length($_); # Nobody will quibble over missing newline... - $lines--; + $len -= $line_length; } $res .= "...more...$n" if @body > 0 || $len < 0; chop($res); # Remove final \n\r for macro substitution @@ -392,32 +453,26 @@ $line .= $_ . ' '; } chop($line); # Remove trailing extra space - $ary[0] = $line; # Replace first body line with compacted string + $ary[0] = $line; # This is all we keep # We stopped compating at index $i - 1, and indices start at 0. This means # lines in the range [0, $i-1] are now all stored as $ary[0], and lines # from [1, $i-1] must be removed from the array ($i-1 lines). + # We keep the extra lines so that a "...more..." indication can be given + # if needed. splice(@ary, 1, $i - 1); # Remove lines that are now part of $ary[0] - - # Now optionally reformat the first line so that it fits into 80 columns. - # The line is formatted into an array, and that array is spliced back - # into @ary. - - return unless $cf'biffnice =~ /^on/i; - local(@tmp); - &format($line, *tmp); # Format line into @tmp - splice(@ary, 0, 1, @tmp); # Insert formatted string back } - -# Format body to fit into 78 columns by inserting the generated lines in an +# Format body to fit into tty width by inserting the generated lines in an # array, one line per item. sub format { - local($body, *ary) = @_; # Body to be formatted, array for result + # Body to be formatted, tty width, array for result + local($body, $width, *ary) = @_; local($tmp); # Buffer for temporary formatting local($kept); # Length of current line - local($len) = 79; # Amount of characters kept + local($len) = $width - 1; # Amount of characters kept + $len = 1 if $len < 1; # Avoid infinite loop if bad parameter # Format body, separating lines on [;,:.?!] or space. while (length($body) > $len) { $tmp = substr($body, 0, $len); # Keep first $len chars @@ -426,11 +481,27 @@ $tmp =~ s/\s*$//; # Remove trailing spaces $tmp =~ s/^\s*//; # Remove leading spaces push(@ary, $tmp); # Create a new line - $body = substr($body, $kept, 9999); + $body = substr($body, $kept, length $body); } push(@ary, $body); # Remaining information on one line } +# One-liner quoted-printable decoder +sub to_txt { + my ($l) = @_; + $l =~ s/=([\da-fA-F]{2})/pack('C', hex($1))/ge; + return $l; +} + +# Quick removal of quoted-printable escapes within the headers +# We do not care about the charset and hope the tty will be able to display +# the characters just fine. +sub unquote_printable { + my ($l) = @_; + $l =~ s/^(.*?)=\?[\w-]+\?Q\?(.*)\?=/$1 . to_txt($2)/ieg && $l =~ s/_/ /g; + return $l; +} + # Un-MIME the body by removing all the MIME headers and looking for the # first text entity in the message. # The supplied array is updated in-place and will contain on return the @@ -586,7 +657,7 @@ $in_style-- while $l =~ s|</style>||; next if $in_style; $l =~ s/<[^\0]*?>//g; - $l =~ s/&(\w)cedil;/$1/g; + $l =~ s/&(\w)cedil;/$1/g; # Transform into ASCII... $l =~ s/&(\w)acute;/$1/g; $l =~ s/&(\w)grave;/$1/g; $l =~ s/&(\w)circ;/$1/g; @@ -594,7 +665,8 @@ $l =~ s/"/'/g; $l =~ s/ / /g; $l =~ s/ / /g; # Same as - $l =~ s/&#(\d+);/chr($1)/g; # Corect only for the ASCII part... + # Corect only for the ASCII part... + $l =~ s/&#(\d+);/($1 > 31 && $1 < 256) ? chr($1) : "?"/ge; $l =~ s/&/&/g; # Must come last $l =~ s/^\s*//; $is_nl = 0 == length($l); Added: trunk/mailagent/agent/pl/termios/Jmakefile =================================================================== --- trunk/mailagent/agent/pl/termios/Jmakefile (rev 0) +++ trunk/mailagent/agent/pl/termios/Jmakefile 2008-06-27 17:02:06 UTC (rev 53) @@ -0,0 +1,30 @@ +/* + * Jmakefile for termios.pl + */ + +;# $Id: Jmakefile,v 3.0.1.1 1994/10/29 18:12:18 ram Exp ram $ +;# +;# Copyright (c) 1990-2006, Raphael Manfredi +;# +;# You may redistribute only under the terms of the Artistic License, +;# as specified in the README file that comes with the distribution. +;# You may reuse parts of this distribution only within the terms of +;# that same Artistic License; a copy of which may be found at the root +;# of the source tree for mailagent 3.0. +;# +;# $Log: Jmakefile,v $ +;# Revision 3.0.1.1 1994/10/29 18:12:18 ram +;# patch20: created +;# + +CFLAGS = -I$(TOP) +DPFLAGS = -I$(TOP) + +DependTarget() +SimpleProgramTarget(termios_ph) + +AllTarget(termios.pl) + +termios.pl: termios_pl.sh termios_ph + /bin/sh termios_pl.sh + Property changes on: trunk/mailagent/agent/pl/termios/Jmakefile ___________________________________________________________________ Name: svn:eol-style + native Added: trunk/mailagent/agent/pl/termios/Makefile.SH =================================================================== --- trunk/mailagent/agent/pl/termios/Makefile.SH (rev 0) +++ trunk/mailagent/agent/pl/termios/Makefile.SH 2008-06-27 17:02:06 UTC (rev 53) @@ -0,0 +1,211 @@ +: Makefile.SH generated from Jmake.tmpl and Jmakefile [jmake 3.5-25] +: $X-Id: Jmake.tmpl 8 2006-08-25 22:27:18Z rmanfredi $ + +case $CONFIG in +'') + if test -f config.sh; then TOP=.; + elif test -f ../config.sh; then TOP=..; + elif test -f ../../config.sh; then TOP=../..; + elif test -f ../../../config.sh; then TOP=../../..; + elif test -f ../../../../config.sh; then TOP=../../../..; + else + echo "Can't find config.sh."; exit 1 + fi + . $TOP/config.sh + ;; +esac +case "$0" in +*/*) cd `expr X$0 : 'X\(.*\)/'` ;; +esac +CURRENT=agent/pl/termios +DIR=`echo $CURRENT/ | sed -e 's/\.\///g'` +echo "Extracting ${DIR}Makefile (with variable substitutions)" + +DATE=`date` + +$spitshell >Makefile <<!GROK!THIS! +######################################################################## +# Makefile generated from Makefile.SH on $DATE + +SHELL = /bin/sh +JMAKE = jmake +TOP = ../../.. +CURRENT = $CURRENT +DIR = $DIR + +######################################################################## +# Parameters set by Configure -- edit config.sh if changes are needed + +CC = $cc +CTAGS = ctags +_EXE = $_exe +JCFLAGS = \$(CFLAGS) $optimize $ccflags $large +JCPPFLAGS = $cppflags +JLDFLAGS = \$(LDFLAGS) $optimize $ldflags +LIBS = $libs +MKDEP = $mkdep \$(DPFLAGS) \$(JCPPFLAGS) -- +MV = $mv +RM = $rm -f +SED = $sed + +######################################################################## +# Automatically generated parameters -- do not edit + +USRINC = $usrinc +SOURCES = termios_ph.c +OBJECTS = termios_ph.o + +######################################################################## +# New suffixes and associated building rules -- edit with care + +.c.o: + \$(CC) -c \$(JCFLAGS) \$< + +!GROK!THIS! +$spitshell >>Makefile <<'!NO!SUBS!' +######################################################################## +# Jmake rules for building libraries, programs, scripts, and data files +# $X-Id: Jmake.rules 18 2006-12-27 10:35:09Z rmanfredi $ + +######################################################################## +# Force 'make depend' to be performed first -- do not edit + +.FORCE_DEPEND:: + +all:: .FORCE_DEPEND + +######################################################################## +# Start of Jmakefile + +# $X-Id: Jmakefile,v 3.0.1.1 1994/10/29 18:12:18 ram Exp ram $ +# +# Copyright (c) 1990-2006, Raphael Manfredi +# +# You may redistribute only under the terms of the Artistic License, +# as specified in the README file that comes with the distribution. +# You may reuse parts of this distribution only within the terms of +# that same Artistic License; a copy of which may be found at the root +# of the source tree for mailagent 3.0. +# +# $X-Log: Jmakefile,v $ +# Revision 3.0.1.1 1994/10/29 18:12:18 ram +# patch20: created +# + +CFLAGS = -I$(TOP) +DPFLAGS = -I$(TOP) + +depend:: ../../../mkdep + +../../../mkdep: + @echo "You have to run Configure in $(TOP) first."; exit 1 + +depend:: + ($(SED) '/^# DO NOT DELETE/q' Makefile && \ + $(MKDEP) $(SOURCES) | \ + $(SED) -e 's:/usr/lib[^ ]*::g; s:$(USRINC)[^ ]*::g; ' \ + -e '/: / b print' -e '$$ b print' -e 'H; d; n; : print' \ + -e 'x; s/\\$$//; s/\\\n//g; s/ */ /g; s/ :/:/;' -e '/: *$$/d' \ + ) > Makefile.new + cp Makefile Makefile.bak + cp Makefile.new Makefile + $(RM) Makefile.new + +all:: termios_ph + +local_realclean:: + $(RM) termios_ph + +termios_ph: termios_ph.o + $(RM) $@ + if test -f $@$(_EXE); then \ + $(MV) $@$(_EXE) $@~$(_EXE); fi + $(CC) -o $@ termios_ph.o $(JLDFLAGS) $(LIBS) + +all:: termios.pl + +local_realclean:: + $(RM) termios.pl + +termios.pl: termios_pl.sh termios_ph + /bin/sh termios_pl.sh + +######################################################################## +# Common rules for all Makefiles -- do not edit + +all:: + +clean: local_clean +realclean: local_realclean +clobber: local_clobber + +local_clean:: + if test -f core; then $(RM) core; fi + $(RM) *~ *.o + +local_realclean:: local_clean + +local_clobber:: local_realclean + $(RM) Makefile config.sh + +install:: local_install +install.man:: maybe_install.man +deinstall:: local_deinstall +deinstall.man:: maybe_deinstall.man + +install.man-no: +deinstall.man-no: + +maybe_install.man: install.man-no +maybe_deinstall.man: deinstall.man-no + +Makefile.SH: Jmakefile + -@if test -f $(TOP)/.package; then \ + if test -f Makefile.SH; then \ + echo " $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~"; \ + $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~; \ + fi; \ + echo " $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT)" ; \ + $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT) ; \ + else touch $@; fi + +Makefile: Makefile.SH + /bin/sh Makefile.SH + +tags:: + $(CTAGS) -w *.[ch] + $(CTAGS) -xw *.[ch] > tags + +local_clobber:: + $(RM) tags + +######################################################################## +# Empty rules for directories with no sub-directories -- do not edit + +local_install:: + @echo "install in $(CURRENT) done." + +local_deinstall:: + @echo "deinstall in $(CURRENT) done." + +local_install.man:: + @echo "install.man in $(CURRENT) done." + +local_deinstall.man:: + @echo "deinstall.man in $(CURRENT) done." + +Makefiles:: + +Makefiles.SH:: + +######################################################################## +# Dependencies generated by make depend +# DO NOT DELETE THIS LINE -- make depend relies on it + +# Put nothing here or make depend will gobble it up +.FORCE_DEPEND:: + @echo "You must run 'make depend' in $(TOP) first."; exit 1 +!NO!SUBS! +chmod 644 Makefile +$eunicefix Makefile + Property changes on: trunk/mailagent/agent/pl/termios/Makefile.SH ___________________________________________________________________ Name: svn:executable + * Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Added: trunk/mailagent/agent/pl/termios/termios_ph.c =================================================================== --- trunk/mailagent/agent/pl/termios/termios_ph.c (rev 0) +++ trunk/mailagent/agent/pl/termios/termios_ph.c 2008-06-27 17:02:06 UTC (rev 53) @@ -0,0 +1,156 @@ +/* + * termios_ph.c -- Generates perl configuration for termios. + */ + +/* + * $Id$ + * + * Copyright (c) 2008, Raphael Manfredi + * + * You may redistribute only under the terms of the Artistic License, + * as specified in the README file that comes with the distribution. + * You may reuse parts of this distribution only within the terms of + * that same Artistic License; a copy of which may be found at the root + * of the source tree for mailagent 3.0. + */ + +/* + * Only two fields are of interest in struct winsize and need to be unpacked + * by perl: + * + * . ws_row The number of rows in the tty + * . ws_col The number of columns in the tty + * + * This program generates those perl lines: + * + * $TIOCGWINSZ = 0x1234; # The TIOCGWINSZ ioctl() + * $packfmt = 'SS'; # ws_row ws_col + * $length = 8; # sizeof(struct winsize) + * @fields = ('row', 'col', ); + */ + +#define MAX_LEN 1024 /* Max length for strings */ +#define PADSTR "..pad.. " /* Pad string, for comment */ + +#include "config.h" + +#include <stdio.h> + +#ifdef I_STRING +#include <string.h> +#else +#include <strings.h> +#endif + +#ifdef I_STDLIB +#include <stdlib.h> +#endif + +#ifdef I_TERMIOS +#include <termios.h> +#endif + +#ifdef I_SYS_IOCTL +#include <sys/ioctl.h> +#endif + +#ifdef I_UNISTD +#include <unistd.h> +#endif + +#include "confmagic.h" + +#define minimum(a,b) ((a) < (b) ? (a) : (b)) +#define maximum(a,b) ((a) < (b) ? (b) : (a)) + +char *padstr = PADSTR; + +#define ADD_ROW \ + strcat(comment, "ws_row "); \ + sprintf(buf, "%c", 'S'); \ + strcat(fields, "'row', "); \ + last_off += row_len; + +#define ADD_COL \ + strcat(comment, "ws_col "); \ + sprintf(buf, "%c", 'S'); \ + strcat(fields, "'col', "); \ + last_off += col_len; + +int main() +{ +#ifdef I_TERMIOS + struct winsize *win = (struct winsize *) 0; + char comment[MAX_LEN]; + char pack[MAX_LEN]; + char fields[MAX_LEN]; + char buf[MAX_LEN]; + int row_off = (int) &win->ws_row; /* Offset of ws_row */ + int col_off = (int) &win->ws_col; /* Offset of ws_col */ + int row_len = sizeof(win->ws_row); /* Size of ws_row */ + int col_len = sizeof(win->ws_col); /* Size of ws_col */ + int last_off = 0; /* Last offset in pack format */ + int offset; + + *comment = '\0'; /* So that we may strcat() later */ + *pack = '\0'; + sprintf(fields, "("); + + /* + * In case none of ws_row and ws_col begins the structure... + */ + if ((last_off = minimum(row_off, col_off)) != 0) { + strcat(comment, padstr); + sprintf(pack, "x%d", last_off); + strcat(fields, "'pad', "); + } + + /* + * Find out which of ws_row and ws_col comes first... + */ + if (row_off < col_off) { /* ws_row is first */ + ADD_ROW; + } else { + ADD_COL; + } + strcat(pack, buf); + + /* + * Possible padding between ws_row and ws_col. + */ + offset = maximum(row_off, col_off) - last_off; + if (offset > 0) { + strcat(comment, padstr); + strcat(fields, "'pad', "); + sprintf(buf, "x%d", offset); + strcat(pack, buf); + last_off += offset; + } + + /* + * Last field before final padding. + */ + if (last_off == col_off) { + ADD_COL; + } else { + ADD_ROW; + } + strcat(pack, buf); + + strcat(fields, ")"); + + /* + * Spit out perl definitions. + */ + printf("$TIOCGWINSZ = 0x%x;\t# The TIOCGWINSZ ioctl()\n", TIOCGWINSZ); + printf("$packfmt = '%s';\t\t# %s\n", pack, comment); + printf("$length = %d;\t\t\t# sizeof(struct winsize)\n", + sizeof(struct winsize)); + printf("@fields = %s;\n", fields); +#else + printf("$TIOCGWINSZ = undef;\t# No termios\n"); +#endif /* I_TERMIOS */ + + exit(0); +} + Property changes on: trunk/mailagent/agent/pl/termios/termios_ph.c ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Added: trunk/mailagent/agent/pl/termios/termios_pl.sh =================================================================== --- trunk/mailagent/agent/pl/termios/termios_pl.sh (rev 0) +++ trunk/mailagent/agent/pl/termios/termios_pl.sh 2008-06-27 17:02:06 UTC (rev 53) @@ -0,0 +1,80 @@ +case $CONFIG in +'') + if test -f config.sh; then TOP=.; + elif test -f ../config.sh; then TOP=..; + elif test -f ../../config.sh; then TOP=../..; + elif test -f ../../../config.sh; then TOP=../../..; + elif test -f ../../../../config.sh; then TOP=../../../..; + else + echo "Can't find config.sh."; exit 1 + fi + . $TOP/config.sh + ;; +esac +: This forces SH files to create target in same directory as SH file. +: This is so that make depend always knows where to find SH derivatives. +case "$0" in +*/*) cd `expr X$0 : 'X\(.*\)/'` ;; +esac +echo "Extracting agent/pl/termios/termios.pl (with variable substitutions)" +$cat >termios.pl <<!GROK!THIS! +;# $Id: utmp_pl.sh,v 3.0.1.2 1995/01/03 18:18:48 ram Exp ram $ +;# +;# Copyright (c) 2008, Raphael Manfredi +;# +;# You may redistribute only under the terms of the Artistic License, +;# as specified in the README file that comes with the distribution. +;# You may reuse parts of this distribution only within the terms of +;# that same Artistic License; a copy of which may be found at the root +;# of the source tree for mailagent 3.0. +;# +;# Primitives to acess the terminal through the POSIX termios interface +;# +# +# termios primitives +# + +package termios; + +# Initialize constants +sub init { + # (configured and automatically generated section) +!GROK!THIS! +./termios_ph | $sed -e 's/^/ /' >>termios.pl +$cat >>termios.pl <<'!NO!SUBS!' + # (end of configured section) + + $inited = 1; +} + +# Decompile the winsize structure, returning (row, col) +sub decompile { + my ($buf) = @_; + my @f = unpack($packfmt, $buf); + my %win; + foreach my $field (@fields) { + next if $field eq 'pad'; # Padding just skipped over + $win{$field} = shift @f; # This field was decoded by unpack() + } + return ($win{'row'}, $win{'col'}); +} + +# Determine the tty size, returning (row, col). +# Returns () if we cannot determine the size due to missing termios. +# Returns an (error) if there was an error during size computation. +sub size { + my ($tty) = @_; + &init unless $inited; + return () unless defined $TIOCGWINSZ; # No termios + local *TTY; + open(TTY, $tty) || return ("cannot open $tty: $!"); + my $win = ' ' x $length; + my $res = ioctl(TTY, $TIOCGWINSZ, $win); + close TTY; + return ("ioctl(TIOCGWINSZ) on $tty failed: $!") unless defined $res; + return decompile($win); +} + +package main; + +!NO!SUBS! Modified: trunk/mailagent/config_h.SH =================================================================== --- trunk/mailagent/config_h.SH 2008-06-27 16:41:09 UTC (rev 52) +++ trunk/mailagent/config_h.SH 2008-06-27 17:02:06 UTC (rev 53) @@ -301,6 +301,14 @@ */ #$i_syswait I_SYS_WAIT /**/ +/* I_TERMIOS: + * This symbol, if defined, indicates that the program should include + * the POSIX termios.h rather than sgtty.h or termio.h. + * There are also differences in the ioctl() calls that depend on the + * value of this symbol. + */ +#$i_termios I_TERMIOS /**/ + /* I_TIME: * This symbol, if defined, indicates to the C program that it should * include <time.h>. Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-06-27 16:41:09 UTC (rev 52) +++ trunk/mailagent/revision.h 2008-06-27 17:02:06 UTC (rev 53) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 44 +#define REVISION 50 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rma...@us...> - 2008-06-27 19:34:51
|
Revision: 54 http://mailagent.svn.sourceforge.net/mailagent/?rev=54&view=rev Author: rmanfredi Date: 2008-06-27 12:34:02 -0700 (Fri, 27 Jun 2008) Log Message: ----------- Improved perload to detect when the executable changes, to reset the offset table from the new executable: since mailagent can wait in the background, updating the script then could cause an unexpected failure should it need to dataload something after waking up. Modified Paths: -------------- trunk/mailagent/agent/test/Makefile.SH trunk/mailagent/agent/test/basic/mailagent.t trunk/mailagent/bin/perload trunk/mailagent/revision.h Modified: trunk/mailagent/agent/test/Makefile.SH =================================================================== --- trunk/mailagent/agent/test/Makefile.SH 2008-06-27 17:02:06 UTC (rev 53) +++ trunk/mailagent/agent/test/Makefile.SH 2008-06-27 19:34:02 UTC (rev 54) @@ -1,5 +1,5 @@ -: Makefile.SH generated from Jmake.tmpl and Jmakefile [jmake 3.0 PL48] -: $X-Id: Jmake.tmpl,v 3.0.1.2 1995/01/11 14:50:21 ram Exp ram $ +: Makefile.SH generated from Jmake.tmpl and Jmakefile [jmake 3.5-25] +: $X-Id: Jmake.tmpl 8 2006-08-25 22:27:18Z rmanfredi $ case $CONFIG in '') @@ -37,7 +37,7 @@ # Parameters set by Configure -- edit config.sh if changes are needed CTAGS = ctags -MAKE = make +JCPPFLAGS = $cppflags MV = $mv RM = $rm -f @@ -45,7 +45,7 @@ $spitshell >>Makefile <<'!NO!SUBS!' ######################################################################## # Jmake rules for building libraries, programs, scripts, and data files -# $X-Id: Jmake.rules,v 3.0.1.2 1995/01/11 14:49:55 ram Exp ram $ +# $X-Id: Jmake.rules 18 2006-12-27 10:35:09Z rmanfredi $ ######################################################################## # Start of Jmakefile @@ -53,7 +53,7 @@ # $X-Id: Jmakefile,v 3.0 1993/11/29 13:49:20 ram Exp ram $ # # Copyright (c) 1990-2006, Raphael Manfredi -# +# # You may redistribute only under the terms of the Artistic License, # as specified in the README file that comes with the distribution. # You may reuse parts of this distribution only within the terms of @@ -92,20 +92,32 @@ ######################################################################## # Common rules for all Makefiles -- do not edit -emptyrule:: +all:: clean: local_clean realclean: local_realclean clobber: local_clobber local_clean:: - $(RM) core *~ *.o + if test -f core; then $(RM) core; fi + $(RM) *~ *.o local_realclean:: local_clean local_clobber:: local_realclean $(RM) Makefile config.sh +install:: local_install +install.man:: maybe_install.man +deinstall:: local_deinstall +deinstall.man:: maybe_deinstall.man + +install.man-no: +deinstall.man-no: + +maybe_install.man: install.man-no +maybe_deinstall.man: deinstall.man-no + Makefile.SH: Jmakefile -@if test -f $(TOP)/.package; then \ if test -f Makefile.SH; then \ @@ -114,7 +126,7 @@ fi; \ echo " $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT)" ; \ $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT) ; \ - else touch $@; exit 0; fi + else touch $@; fi Makefile: Makefile.SH /bin/sh Makefile.SH @@ -129,16 +141,16 @@ ######################################################################## # Empty rules for directories with no sub-directories -- do not edit -install:: +local_install:: @echo "install in $(CURRENT) done." -deinstall:: +local_deinstall:: @echo "deinstall in $(CURRENT) done." -install.man:: +local_install.man:: @echo "install.man in $(CURRENT) done." -deinstall.man:: +local_deinstall.man:: @echo "deinstall.man in $(CURRENT) done." Makefiles:: Modified: trunk/mailagent/agent/test/basic/mailagent.t =================================================================== --- trunk/mailagent/agent/test/basic/mailagent.t 2008-06-27 17:02:06 UTC (rev 53) +++ trunk/mailagent/agent/test/basic/mailagent.t 2008-06-27 19:34:02 UTC (rev 54) @@ -33,7 +33,7 @@ print RULES "{ DELETE };\n"; close RULES; unlink <queue/qm*>; -open(FILTER, "|$filter -t >/dev/null 2>&1") || print "3\n"; +open(FILTER, "|$filter -t >>.bak 2>&1") || print "3\n"; print FILTER <<EOF; From: test @@ -50,7 +50,7 @@ unlink 'agentlog', '.rules'; sleep 1 while -f "perl$lockext"; # Let background mailagent die # Check empty rules... -open(FILTER, "|$filter -t >/dev/null 2>&1") || print "10\n"; +open(FILTER, "|$filter -t >>.bak 2>&1") || print "10\n"; print FILTER <<EOF; From: test @@ -71,7 +71,7 @@ # Make sure file is correctly queued when another mailagent is running `cp /dev/null perl$lockext`; $? == 0 || print "19\n"; -open(FILTER, "|$filter -t >/dev/null 2>&1") || print "20\n"; +open(FILTER, "|$filter -t >>.bak 2>&1") || print "20\n"; print FILTER <<EOF; Dummy mail EOF Modified: trunk/mailagent/bin/perload =================================================================== --- trunk/mailagent/bin/perload 2008-06-27 17:02:06 UTC (rev 53) +++ trunk/mailagent/bin/perload 2008-06-27 19:34:02 UTC (rev 54) @@ -248,12 +248,19 @@ :# Load the calling function from DATA segment and call it. This function is :# called only once per routine to be loaded. :sub main'dataload { +: package perload; : local($__packname__) = (caller(1))[3]; : $__packname__ =~ s/::/'/; : local($__rpackname__) = $__packname__; : local($__at__) = $@; : $__rpackname__ =~ s/^auto_//; -: &perload'load_from_data($__rpackname__); +: eval { load_from_data($__rpackname__, 0) }; +: if ($@ eq "RETRY\n") { +: undef %Datapos; +: load_from_data($__rpackname__, 1); +: } else { +: die $@ if $@; +: } : local($__fun__) = "$__rpackname__"; : $__fun__ =~ s/'/'load_/; : eval "*$__packname__ = *$__fun__;"; # Change symbol table entry @@ -265,17 +272,28 @@ :# Load function name given as argument, fatal error if not existent :sub perload'load_from_data { : package perload; -: local($pos) = $Datapos{$_[0]}; # Offset within DATA +: local ($name, $retried) = @_; +: local($pos) = $Datapos{$name}; # Offset within DATA : # Avoid side effects by protecting special variables which will be changed : # by the dataloading operation. -: local($., $_, $@); -: $pos = &fetch_function_code unless $pos; -: die "Function $_[0] not found in data section.\n" unless $pos; +: local($., $_); +: $pos = &fetch_function_code($name, $retried) unless $pos; +: die "Function $name not found in data section.\n" unless $pos; : die "Cannot seek to $pos into data section.\n" : unless seek(main'DATA, $pos, 0); : local($/) = "\n}"; : local($body) = scalar(<main'DATA>); -: die "End of file found while loading $_[0].\n" unless $body =~ /^\}$/m; +: local $loaded = $name; +: $loaded =~ s/^(.*?)'(.*)/sub ${1}'load_$2 {/;; +: unless ($body =~ /\n\}$/s && substr($body, 0, length $loaded) eq $loaded) { +: if ($retried) { +: die "End of file found while loading $name.\n" +: unless $body =~ /\n\}$/s; +: die "Offset table garbled or file changed whilst loading $name.\n"; +: } +: die "RETRY\n"; +: } +: local $@; EOC if ($opt_t) { print &q(<<'EOC'); @@ -328,8 +346,20 @@ :# the offset of each of the dataloaded routines held in the data section. :sub perload'fetch_function_code { : package perload; +: local ($name, $retried) = @_; : local($start) = 0; : local($., $_); +: if ($retried) { +: my $date = scalar localtime; +: warn("$0 probably changed, reloading offset table on $date\n"); +: close(main'DATA); +: open(main'DATA, $0) || die "Can't open $0 to reload offset table: $!\n"; +: my $found = 0; +: while (<main'DATA>) { +: if (/^__END__\s$/) { $found++; last } +: } +: die "Unable to find __END__ token in $0\n" unless $found; +: } : while (<main'DATA>) { # First move to start of offset table : next if /^#/; : last if /^$/ && ++$start > 2; # Skip two blank line after end token @@ -341,7 +371,7 @@ : ($key, $value) = split(' '); : $Datapos{$key} = $value + $start; : } -: $Datapos{$_[0]}; # All that pain to get this offset... +: $Datapos{$name}; # All that pain to get this offset... :} : EOC Modified: trunk/mailagent/revision.h =================================================================== --- trunk/mailagent/revision.h 2008-06-27 17:02:06 UTC (rev 53) +++ trunk/mailagent/revision.h 2008-06-27 19:34:02 UTC (rev 54) @@ -4,4 +4,4 @@ * Generated by ./bin/svn-revision. */ -#define REVISION 50 +#define REVISION 53 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |