diff options
Diffstat (limited to 'dist-tools')
-rwxr-xr-x | dist-tools/getstats.py | 18 | ||||
-rwxr-xr-x | dist-tools/growthplot | 114 | ||||
-rwxr-xr-x | dist-tools/indexgen.sh | 386 | ||||
-rwxr-xr-x | dist-tools/listsize | 36 | ||||
-rwxr-xr-x | dist-tools/makerelease | 176 | ||||
-rw-r--r-- | dist-tools/test/test-request | 20 | ||||
-rwxr-xr-x | dist-tools/test/testmail | 10 | ||||
-rwxr-xr-x | dist-tools/test/testmda | 10 | ||||
-rw-r--r-- | dist-tools/test/testrc | 14 | ||||
-rwxr-xr-x | dist-tools/test/testservers-gen.sh | 57 | ||||
-rw-r--r-- | dist-tools/test/testservers.html | 64 | ||||
-rw-r--r-- | dist-tools/test/torturetest.glade | 976 | ||||
-rw-r--r-- | dist-tools/test/torturetest.gladep | 7 | ||||
-rwxr-xr-x | dist-tools/test/torturetest.py | 326 | ||||
-rwxr-xr-x | dist-tools/timeplot | 40 | ||||
-rwxr-xr-x | dist-tools/timeseries | 101 | ||||
-rwxr-xr-x | dist-tools/upload | 26 | ||||
-rwxr-xr-x | dist-tools/uploadfaq | 24 |
18 files changed, 2405 insertions, 0 deletions
diff --git a/dist-tools/getstats.py b/dist-tools/getstats.py new file mode 100755 index 00000000..f957c7d3 --- /dev/null +++ b/dist-tools/getstats.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# +# Collect statistics on current release. + +import commands, string, ftplib + +# Get version and date +date = commands.getoutput("date") +ln = commands.getoutput("co -p RCS/*.[chly],v 2>/dev/null | wc -l") +vers = commands.getoutput("sed -n -e '/VERSION/s/VERSION *= *\\(.*\\)/\\1/p' <Makefile") +print "fetchmail-" + vers + " (" + date + "), " + string.strip(ln) + " lines:" + +# Use local listsize command to grab list statistics +friends = commands.getoutput("listsize friends").strip() +announce = commands.getoutput("listsize announce").strip() +print "There are %s people on fetchmail-friends and %s on fetchmail-announce."% (friends, announce) + +# getstats.py diff --git a/dist-tools/growthplot b/dist-tools/growthplot new file mode 100755 index 00000000..73f4f4e9 --- /dev/null +++ b/dist-tools/growthplot @@ -0,0 +1,114 @@ +#!/bin/sh +# +# growthplot -- plot the fetchmail project's growth as a function of time +# + +PATH="$PATH:.:./dist-tools"; export PATH + +tmp=/tmp/fetchmail-growthplot.$$ +mkdir $tmp + +# Get data from the NEWS file +timeseries >$tmp/growthplot$$ +grep "^[0-9]" $tmp/growthplot$$ >$tmp/growthnumbers$$ +grep "^[0-9.]*.[05].0 " $tmp/growthplot$$ >$tmp/growthmajors$$ +sed '/^4.2.9/,$d' <$tmp/growthnumbers$$ >$tmp/growthannounce$$ + +# gnuplot line styles. These occasionally change (like beteween 3.5 and 3.7); +# use "echo 'set terminal png; test' | gnuplot | display -" to check. +blue_boxes=3 +green_crosses=2 +cyan_diamonds=37 # Once purple triangles, but we can't do that anymore +brown_triangles=23 + +cat >$tmp/growthimage$$ <<EOF +set title "Fetchmail project growth history" +set xlabel 'Days since baseline' +set ylabel 'Participants' +set y2label 'Lines of code' +set ytics nomirror +set y2tics +set tics out +set autoscale y +set y2range [5000:50000] +set key bottom right box +set terminal png + +EOF + +# OK, now write the event labels +( + count=0 + lastday=0 + breakheight=510 + while read version legend + do + if [ "$version" = '%' ] + then + echo "# Associate $lastday to '$legend'" + count=$((count+1)) + lastday=$(($lastday-5)) + endy=$((breakheight+50+count*50)) + if ((endy>lasttotal)) + then + # Label over curve hanging right, arrow down + arrowhead=$((lasttotal+50)) + echo "set label '$legend' at $lastday-10, $endy+15" + else + # Label under curve hanging left, arrow up + arrowhead=$((lasttotal-5)) + strlen=`python -c "print len('$legend')"` + lablen=$((strlen*22)) + echo "set label '$legend' at $lastday-$lablen+10, $endy-15" + fi + echo set arrow \ + from $lastday, $endy \ + to $lastday, $arrowhead \ + head + else + set -- $legend + size=$1 + friends=$2 + announce=$3 + total=$4 + days=$5 + date=$6 + lastday=$days + lasttotal=$total + fi + done +) <$tmp/growthplot$$ >>$tmp/growthimage$$ + +# OK, now write the major-release labels +( + while read version size friends announce total days date + do + echo "set arrow from $days, $total - 55 to $days, $total - 15 head" + echo "set label '$version' at $days - 5, $total - 65" + done +) <$tmp/growthmajors$$ >>$tmp/growthimage$$ + +cat >>$tmp/growthimage$$ <<EOF +plot [] [0:] '$tmp/growthnumbers$$' using 6:5 \ + title "Both lists" with points $blue_boxes, \ + '$tmp/growthannounce$$' using 6:4 \ + title "fetchmail-announce" with points $cyan_diamonds, \ + '$tmp/growthannounce$$' using 6:3 \ + title "fetchmail-friends" with points $green_crosses, \ + '$tmp/growthnumbers$$' using 6:2 axes x1y2 \ + title "Lines of code" with points $brown_triangles +EOF + +gnuplot $tmp/growthimage$$ >growth.png + +rm -f $tmp/growth* +rmdir $tmp + +# growthplot ends here + + + + + + + diff --git a/dist-tools/indexgen.sh b/dist-tools/indexgen.sh new file mode 100755 index 00000000..0fac4259 --- /dev/null +++ b/dist-tools/indexgen.sh @@ -0,0 +1,386 @@ +#!/bin/sh +# +# indexgen.sh -- generate current version of fetchmail home page. +# +goldvers="6.2.0" +goldname="6.2.0" +version=`sed -n <Makefile.in "/VERSION *= */s/VERSION *= *\([^ ]*\)/\1/p"` +date=`date "+%d %b %Y"` + +set -- `timeseries | grep -v "[%#]" | head -1` +subscribers=$4 +make fetchmail +set -- `ls -ks fetchmail` +fetchmailsize=$1 +set -- `(cd /lib; ls libc-*)` +glibc=`echo $1 | sed 's/libc-\(.*\)\.so/\1/'` +glibc="glibc-$glibc" + +rm -f index.html + +# Compute MD5 checksums for security audit +rm -f checksums +for file in fetchmail-$version.tar.gz fetchmail-$version-1.*.rpm +do + md5sum $file >>checksums +done + +if [ $version != $goldvers ] +then + for file in fetchmail-$goldvers.tar.gz fetchmail-$goldvers-1.*.rpm + do + md5sum $file | sed -e "s: .*/: :" >>checksums + done +fi + +# Cryptographically sign checksums +gpg --clearsign checksums +mv checksums.asc checksums + +cat >index.html <<EOF +<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<link rev="made" href="mailto:esr@snark.thyrsus.com" /> +<link rel="stylesheet" href="/~esr/sitestyle.css" type="text/css"/> +<meta name="description" content="Home page of the fetchmail project" /> +<meta name="keywords" content="" /> +<meta name="MSSmartTagsPreventParsing" content="TRUE" /> +<title>The fetchmail home page</title> +</head> +<body> + +<div id="Header"> +<table width="100%" cellpadding="0" summary="Canned page header"> +<tr> +<td>The fetchmail home page</td> +<td align="right">$date</td> +</tr> +</table> +</div> + +<div id="Menu"> + <hr/> + <a href="/~esr" title="My home page">Home Page</a><br /> + <a href="/~esr/sitemap.html" title="Map of the site">Site Map</a><br /> + <a href="/~esr/software.html" title="Software I maintain">Software</a><br /> + <a href="/~esr/projects.html" title="My projects">Projects</a><br /> + <a href="/~esr/faqs/" title="My FAQ documents">HOWTOs</a><br /> + <a href="/~esr/writings/" title="Essays and ruminations">Essays</a><br /> + <a href="/~esr/personal.html" title="Portrait of the author">Personal</a><br /> + <a href="http://www.ibiblio.org/esrblog/">Weblog</a><br/> + <a href="/~esr/netfreedom/">Freedom!</a><br /> + <a href="/~esr/guns/">Firearms!</a><br /> + <hr/> +</div> + +<div id="Content"> + +<h1>The fetchmail Home Page</h1> +</center> + +<p><b>Note: if you are a stranded fetchmail.com user, we're sorry but +we have nothing to do with that site and cannot help you. It's just an +unfortunate coincidence of names.</b></p> + +<h1>What fetchmail does:</h1> + +<p>Fetchmail is a full-featured, robust, well-documented +remote-mail retrieval and forwarding utility intended to be used over +on-demand TCP/IP links (such as SLIP or PPP connections). It supports +every remote-mail protocol now in use on the Internet: POP2, POP3, +RPOP, APOP, KPOP, all flavors of <a +href="http://www.imap.org">IMAP</a>, ETRN, and ODMR. It can even +support IPv6 and IPSEC.</p> + +<p>Fetchmail retrieves mail from remote mail servers and forwards it via +SMTP, so it can then be read by normal mail user agents such as <a +href="http://www.mutt.org/">mutt</a>, elm(1) or BSD Mail. +It allows all your system MTA's filtering, forwarding, and aliasing +facilities to work just as they would on normal mail.</p> + +<p>Fetchmail offers better security than any other Unix remote-mail +client. It supports APOP, KPOP, OTP, Compuserve RPA, Microsoft NTLM, +and IMAP RFC1731 encrypted authentication methods including CRAM-MD5 +to avoid sending passwords en clair. It can be configured to support +end-to-end encryption via tunneling with <a +href="http://www.openssh.com/">ssh, the Secure Shell</a>.</p> + +<p>Fetchmail can be used as a POP/IMAP-to-SMTP gateway for an entire DNS +domain, collecting mail from a single drop box on an ISP and +SMTP-forwarding it based on header addresses. (We don't really +recommend this, though, as it may lose important envelope-header +information. ETRN or a UUCP connection is better.)</p> + +<p>Fetchmail can be started automatically and silently as a system daemon +at boot time. When running in this mode with a short poll interval, +it is pretty hard for anyone to tell that the incoming mail link is +not a full-time "push" connection.</p> + +<p>Fetchmail is easy to configure. You can edit its dotfile directly, or +use the interactive GUI configurator (fetchmailconf) supplied with the +fetchmail distribution. It is also directly supported in linuxconf +versions 1.16r8 and later.</p> + +<p>Fetchmail is fast and lightweight. It packs all its standard +features (POP3, IMAP, and ETRN support) in ${fetchmailsize}K of core on a +Pentium under Linux.</p> + +<p>Fetchmail is <a href="http://www.opensource.org">open-source</a> +software. The openness of the sources is your strongest possible +assurance of quality and reliability.</p> + +<h1>Where to find out more about fetchmail:</h1> + +<p>See the <a href="fetchmail-features.html">Fetchmail Feature List</a> for more +about what fetchmail does.</p> + +<p>See the on-line <a href="fetchmail-man.html">manual page</a> for +basics.</p> + +<p>See the <a href="fetchmail-FAQ.html">HTML Fetchmail FAQ</a> for +troubleshooting help.</p> + +<p>See the <a href="design-notes.html">Fetchmail Design Notes</a> +for discussion of some of the design choices in fetchmail.</p> + +<p>See the project's <a href="todo.html">To-Do list</a> for indications +of known problems and requested features.</p> + +<h1>How to get fetchmail:</h1> + +<p>You can get any of the following leading-edge resources here:</p> +<ul> +<li> <a href="fetchmail-$version.tar.gz"> + Gzipped source archive of fetchmail $version</a> +<li> <a href="fetchmail-$version-1.i386.rpm"> + Intel binary RPM of fetchmail $version (uses $glibc)</a> +<li> <a href="fetchmail-$version-1.src.rpm"> + Source RPM of fetchmail $version</a> +</ul> + +<p>MD5 <a href="checksums">checksums</a> are available for these files; the +checksum file is cryptographically signed and can be verified with the +command:</p> + +<pre> +gpg --verify checksums +</pre> + +EOF + +if [ $version != $goldvers ] +then + cat >>index.html <<EOF + +<p>Or you can get the last \`gold' version, $goldname:</p> +<ul> +<li> <a href="fetchmail-$goldvers.tar.gz"> + Gzipped source archive of fetchmail $goldname</a> +<li> <a href="fetchmail-$goldvers-1.i386.rpm"> + Intel binary RPM of fetchmail $goldname (uses glibc)</a> +<li> <a href="fetchmail-$goldvers-1.alpha.rpm"> + Alpha binary RPM of fetchmail $goldname (uses glibc)</a> +<li> <a href="fetchmail-$goldvers-1.src.rpm"> + Source RPM of fetchmail $goldname</a> +</ul> + +<p>The <a href="fetchmail-$goldvers.tar.gz.asc">detached GPG +signature</a> for the binary tarball can be used to check it for +correctness, with the command</p> + +<pre> +gpg --verify fetchmail-$goldvers.tar.gz.asc fetchmail-$goldvers.tar.gz +</pre> + +<p>For differences between the leading-edge $version and gold $goldname versions, +see the distribution <a href="NEWS">NEWS</a> file.</p> +EOF +fi + +cat >>index.html <<EOF +<p>(Note that the binary RPMs don't have the POP2, OTP, IPv6, Kerberos, +GSSAPI, Compuserve RPA, Microsoft NTLM, or GNU gettext +internationalization support compiled in. To get any of these you +will have to build from sources.)</p> + +<p>The latest version of fetchmail is also carried in the +<a href="http://metalab.unc.edu/pub/Linux/system/mail/pop/!INDEX.html"> +Metalab remote mail tools directory</a>.</p> + +<h1>Getting help with fetchmail:</h1> + +<p>There is a fetchmail-friends list for people who want to discuss +fixes and improvements in fetchmail and help co-develop it. It's a +MailMan list, which you can sign up for at <a +href="http://lists.ccil.org/mailman/listinfo/fetchmail-friends"> +fetchmail-friends@ccil.org</a>. There is also an announcements-only +list, <a +href="http://lists.ccil.org/mailman/listinfo/fetchmail-announce"> +fetchmail-announce@lists.ccil.org</a>.</p> + +<p>Note: before submitting a question to the list, <strong>please read +the <a href="fetchmail-FAQ.html">FAQ</a></strong> (especially item <a +href="fetchmail-FAQ.html#G3">G3</a> on how to report bugs). We +tend to get the same three newbie questions over and over again. The +FAQ covers them like a blanket.</p> + +<p>Fetchmail was written and is maintained by <a +href="../index.html">Eric S. Raymond</a>. There are some designated +backup maintainers (<a href="mailto:rfunk@funknet.net">Rob Funk</a>, <a +href="http://www.dallas.net/~fox/">David DeSimone aka Fuzzy Fox</a>, +<a href="mailto:imdave@mcs.net">Dave Bodenstab</a> and <a +href="mailto:shetye@bombay.retortsoft.com">Sunil Shetye</a>). Other backup +maintainers may be added in the future, in order to ensure continued +support should Eric S. Raymond drop permanently off the net for any +reason.</p> + +<h1>You can help improve fetchmail:</h1> + +<p>I welcome your code contributions. But even if you don't write code, +you can help fetchmail improve.</p> + +<p>If you administer a site that runs a post-office server, you may be +able help improve fetchmail by lending me a test account on your site. +Note that I do not need a shell account for this purpose, just a +maildrop. Nor am I interested in collecting maildrops per se -- +what I'm collecting is different <em>kinds of servers</em>.</p> + +<p>Before each release, I run a test harness that sends date-stamped +test mail to each site on my regression-test list, then tries to +retrieve it. Please take a look at my <a href="testservers.html"> +list of test servers</a>. If you can lend me an account on a kind +of server that is <em>not</em> already on this list, please do.</p> + +<h1>Who uses fetchmail:</h1> + +<p>Fetchmail entered full production status with the 2.0.0 version in +November 1996 after about five months of evolution from the ancestral +<code>popclient</code> utility. It has since come into extremely wide use +in the Internet/Unix/Linux community. The Red Hat, Debian and +Suse Linux distributions and their derivatives all include it. A +customized version is used at Whole Earth 'Lectronic Link. Several +large ISPs are known to recommend it to Unix-using SLIP and PPP +customers.</p> + +<p>Somewhere around a thousand people have participated on the fetchmail +beta lists (at time of current release there were $subscribers on the +friends and announce lists). While it's hard to count the users of +open-source software, we can estimate based on (a) population figures +at the WELL and other known fetchmail sites, (b) the size of the +Linux-using ISP customer base, and (c) the volume of fetchmail-related +talk on USENET. These estimates suggest that daily fetchmail users +number well into the hundreds of thousands, and possibly over a million.</p> + +<h1>The sociology of fetchmail:</h1> + +<p>The fetchmail development project was a sociological experiment as well +as a technical effort. I ran it as a test of some theories about why the +Linux development model works.</p> + +<p>I wrote a paper, <a +href="http://www.catb.org/~esr/writings/cathedral-bazaar/">The +Cathedral And The Bazaar</a>, about these theories and the project. +I developed the line of analysis it suggested in two later essays. +These papers became quite popular and (to my continuing astonishment) may +have actually helped change the world. Chase the title link, above, +for links to all three papers.</p> + +<p>I have done some analysis on the information in the project NEWS file. +You can view a <a href="history.html">statistical history</a> showing +levels of participation and release frequency over time.</p> + +<h1>Recent releases and where fetchmail is going:</h1> + +<p>Fetchmail is now sufficiently stable and effective that I'm getting +very little pressure to fix things or add features. Development has +slowed way down, release frequency has dropped off, and we're +basically in maintainance mode.</p> + +<p>Major changes or additions therefore seem unlikely until there are +significant changes in or additions to the related protocol RFCs.</p> + +<h1>Where you can use fetchmail:</h1> + +<p>The fetchmail code was developed under Linux, but has also been +extensively tested under 4.4BSD, SunOS, Solaris, AIX, and NEXTSTEP. It +should be readily portable to other Unix variants (it requires only +POSIX plus BSD sockets, and uses GNU autoconf).</p> + +<p>Fetchmail is supported only for Unix by its official maintainers. +However, it is reported to build and run correctly under BeOS, +AmigaOS, Rhapsody, and QNX as well. There is a CygWin port.</p> + +<h1>Related resources:</h1> + +<p>Jochen Hayek is developing a set of +<a href="http://www.ACM.org/~Jochen_Hayek/JHimap_utils/"> +IMAP tools in Python</a> that read your .fetchmailrc file and are +designed to work with fetchmail. Jochen's tools can report selected +header lines, or move incoming messages to named mailboxes based on +the contents of headers.</p> + +<p>Donncha O Caoihm has written a Perl script called +<a href="http://cork.linux.ie/projects/install-sendmail/">install-sendmail</a> +that assists you in installing sendmail and fetchmail together.</p> + +<p>Peter Hawkins has written a script called <a +href="http://linux.cudeso.be/linuxdoc/gotmail.php">gotmail</a> that +can retrieve Hotmail. Another script, <a +href="http://yosucker.sourceforge.net">yosucker</a>, can retrieve +Yahoo webmail.</p> + +<p>There's a program called +<http://mailfilter.sourceforge.net/'>mailfilter</a> which can be used +to do span filtering, that works particularly well called from fetchmail's +<code>preconnect</code> directive,</p> + +<p>A hacker identifying himself simply as \`Steines' has written a +filter which rewrites the to-line with a line which only includes +receipients for a given domain and renames the old to-line. It also +rewrites the domain-part of addresses if the offical domain is +different from the local domain. You can find it <a +href="http://www.steines.com/mailf/">here</a>.</p> + +<h1>Fetchmail's funniest fan letter:</h1> + +<a href="funny.html">This letter</a> still cracks me up whenever I reread it. + +<h1>The fetchmail button:</h1> + +<p>If you use fetchmail and like it, here's a nifty fetchmail button you +can put on your web page:</p> + +<center><img src="fetchmail.png" alt="fetchmail logo" /></center> + +<p>Thanks to <a href="http://www.gl.umbc.edu/~smatus1/">Steve +Matuszek</a> for the graphic design. The hand in the button (and the +larger top-of-page graphic) was actually derived from a color scan of +the fetchmail author's hand.</p> + +<h1>Fetchmail mirror sites:</h1> + +<p>There is a FTP mirror of the current sources and RPMs in Japan at +<a href="ftp://ftp.win.ne.jp/pub/network/mail/fetchmail"> +ftp://ftp.win.ne.jp/pub/network/mail/fetchmail</a>. + +<h1>Reviews and Awards</h1> + +<p>Fetchmail was DaveCentral's Best Of Linux winner for +<a href="http://linux.davecentral.com/bol_19990630.html">June 30 1999</a>.</p> + +<p>Fetchmail was a five-star Editor's Pick at Softlandindia.</p> + +</div> + +</body> +</html> +EOF + +# The following sets edit modes for GNU EMACS +# Local Variables: +# mode:html +# truncate-lines:t +# End: diff --git a/dist-tools/listsize b/dist-tools/listsize new file mode 100755 index 00000000..73e25887 --- /dev/null +++ b/dist-tools/listsize @@ -0,0 +1,36 @@ +#!/bin/sh +# +# Mine list sizes from MailMan web interfaces +# +# * Must set environment variable FETCHMAIL_LIST_PASS to list admin password + +project="fetchmail" +admin="http://lists.berlios.de/mailman/admin" +adminpw=$FETCHMAIL_LIST_PASS + +list="$1" +if [ ! "$list" ]; then + echo "Usage: $0 list" 1>&2 + exit 1 +fi +case "$list" in +$project-*) + # already gave us the full name, e.g. fetchmail-announce + ;; +*) + # only gave us the last part of the name, e.g. announce + list="$project-$list" + ;; +esac + +hexpw=`echo "$adminpw" | od -t x1 -w64 | sed -e 's/^[0-9]*//' -e '/^ *$/d' -e 's/ /%/g'` +umask 077 +tmp="/tmp/$project-$list.listsize.$$" +# First get the login cookie... +curl -s -D "$tmp" "$admin/${list}?adminpw=$hexpw" >/dev/null +# Second gets the actual stat +curl -s -b "$tmp" "$admin/${list}/members" \ + | sed -n '/.*>(\([0-9][0-9]*\) members total.*/s//\1/p' +rm -f "$tmp" +# end + diff --git a/dist-tools/makerelease b/dist-tools/makerelease new file mode 100755 index 00000000..41ddf038 --- /dev/null +++ b/dist-tools/makerelease @@ -0,0 +1,176 @@ +#!/usr/bin/env perl +# +# Make a fetchmail release. Must be run as root, to make RPMs. +# Dumps a release notice and diffs as a MIME multipart message +# in RELEASE_NOTES +# +use POSIX qw(strftime); +$timezone = strftime('%z', localtime) || "-0500"; +$tmp = $ENV{TMPDIR} || $ENV{TMP} || $ENV{TEMP} || "/tmp"; + +$project = "fetchmail"; +$svnrepos = "svn://svn.berlios.de/$project"; +$website = "http://developer.berlios.de/projects/$project"; +$mailfrom = "<$project-devel-owner\@lists.berlios.de> (Fetchmail Development Team)"; + +# parse options +$diffs = 0; +$verbose = 0; +$null = ">/dev/null"; +$errnull = "2>/dev/null"; +while ($i = shift @ARGV) +{ + if ($i =~ /^(--diffs|-d)$/i) + { + $diffs = 1; + next; + } + + if ($i =~ /^(--verbose|-v)$/i) + { + $verbose = 1; + $null = ""; + next; + } + + die "Error: Unknown option: $i\n"; +} + +# extract version from source +$version=`grep 'AC_INIT' configure.in`; +$version =~ /AC_INIT\([^,]*,\[?([0-9.]+)\]?\)/; +$version = $1; +die "cannot determine version" unless defined $1; +$tag = "RELEASE_$version"; +$tag =~ tr/./-/; + +# extract existing tags +open(ID, "svn ls $svnrepos/tags|"); +while (<ID>) { + if (m{^(RELEASE_.*)/}) { + unshift(@versions, $1); + } +} +close(ID); + +if ($versions[0] eq $tag) { + $tag = $versions[0]; + $oldtag = $versions[1]; +} else { + $tag = '<workfile>'; + $oldtag = $versions[0]; +} + +$ENV{PATH} .= ":./dist-tools:./dist-tools/shipper:."; + +print "Building $version release, tag $tag, previous tag $oldtag\n"; + +if (-d autom4te.cache) { + system("rm -rf autom4te.cache") + and die "Failure in removing autom4te.cache"; +} + +if (system("autoreconf -isv")) { + die("Failure in regenerating autoconf files\n"); +} + +if (system("./configure && make clean && make -C po update-po && make clean")) { + die("Failure in translation-file rebuild\n"); +} + +print "### Test-building the software...\n"; +if (system("./configure && make clean && make all check")) { + die("Compilation failure\n"); +} + +print "### Building the distribution...\n"; +if (system("make dist $null")) { + die("Distribution-build failure\n"); +} + +print "### Building the RPMs...\n"; +if (system("buildrpms $project-${version}.tar.gz $null")) { + die("RPM-build failure\n"); +} + +open(REPORT, ">$tmp/$project.PREAMBLE.$$"); + +print REPORT <<EOF; +From: $mailfrom +Subject: The $version release of $project is available + +The $version release of $project is now available at the usual locations, +including <URL:$website>. + +The source archive is available at: +<URL:$website/$project-${version}.tar.gz> + +Here are the release notes: + +EOF + +# Extract the current notes +open(NEWS, "NEWS"); +while (<NEWS>) { + if (/^$project/) { + print REPORT $_; + last; + } +} +while (<NEWS>) { + if (/^$project/) { + last; + } + print REPORT $_; +} + +$oldver = $oldtag; +$oldver =~ tr/-/./; +$oldver =~ s/^RELEASE_//; + +if ($diffs) { + print REPORT "Diffs from the previous ($oldver) release follow as a MIME attachment." +} else { + print REPORT "By popular demand, diffs from the previous release have been omitted." +} + +close(NEWS); + +close(REPORT); + +if ($tag eq '<workfile>') { + system("svn diff -r$oldtag $errnull >$tmp/$project.DIFFS.$$"); +} else { + system("svn diff -r$oldtag -r$tag $errnull >$tmp/$project.DIFFS.$$"); +} +print "Diff size:"; +system("wc <$tmp/$project.DIFFS.$$"); + +if ($diffs) { + system "metasend -b" + ." -D '$project-$tag announcement' -m 'text/plain' -e 7bit -f $tmp/$project.PREAMBLE.$$" + ." -n -D 'diff between $oldver and $version' -m 'text/plain' -e 7bit -f $tmp/$project.DIFFS.$$" + ." -o ANNOUNCE.EMAIL"; +} else { + rename("$tmp/$project.PREAMBLE.$$", "ANNOUNCE.EMAIL"); +} +#system("chown esr ANNOUNCE.EMAIL"); +#chmod(0700, "ANNOUNCE.EMAIL"); + +#unlink("$tmp/$project.PREAMBLE.$$"); +unlink("$tmp/$project.DIFFS.$$"); + +print "Building index page...\n"; +system("rm -f index.html; indexgen.sh"); + +if (-r "testsites") { + print "Building test server list...\n"; + system("rm -f testservers.html; testservers-gen.sh >testservers.html"); +} + +print "Making activity graph..."; +system "growthplot"; + +print "Done\n"; + +# makerelease ends here diff --git a/dist-tools/test/test-request b/dist-tools/test/test-request new file mode 100644 index 00000000..160c1885 --- /dev/null +++ b/dist-tools/test/test-request @@ -0,0 +1,20 @@ +I maintain an open-source POP and IMAP client called fetchmail. It is +widely used in the Linux and open-source community, and is probably +the single most popular remote-mail client in that world. You can +find out more about this project at +<http://www.catb.org/~esr/fetchmail>. + +In order to be able to do thorough regression testing before each release, +I collect test accounts on as many different kinds of POP3, IMAP, and +ODMR servers as possible. Because fetchmail is strictly conformant to the +remote-mail RFCs, many server developers have found fetchmail a useful +standards-conformance test. + +I'm writing to request test accounts on your server. I support all flavors +of POP2, POP3, IMAP and ODMR with either plain-password, CRAM-MD5, NTLM, +GSSAPI, or Kerberos authentication. I also support SSL/TLS. + +It would be very helpful if I could have a separate test account for +each protocol you support (that is, separate POP3, IMAP, and ODMR +accounts) so I can do automated regression testing without worrying +about mailbox race conditions. diff --git a/dist-tools/test/testmail b/dist-tools/test/testmail new file mode 100755 index 00000000..7941892e --- /dev/null +++ b/dist-tools/test/testmail @@ -0,0 +1,10 @@ +#!/bin/sh +size=${1:-0} + +( +echo "This mail was generated on "`date`"." + +) | mail -s "${size}k test mail from process $$" esr@ccil.org + + <<EOF +EOF diff --git a/dist-tools/test/testmda b/dist-tools/test/testmda new file mode 100755 index 00000000..98a7c760 --- /dev/null +++ b/dist-tools/test/testmda @@ -0,0 +1,10 @@ +#!/bin/sh +# Test MDA for debugging fetchmail configurations. +echo "[testmda called with the following arguments: $*]" + +# Display the input +cat >/tmp/testmda$$ +echo "[text is "`wc -c </tmp/testmda$$`" bytes long]" +cat /tmp/testmda$$ +rm /tmp/testmda$$ + diff --git a/dist-tools/test/testrc b/dist-tools/test/testrc new file mode 100644 index 00000000..7520f8d4 --- /dev/null +++ b/dist-tools/test/testrc @@ -0,0 +1,14 @@ +# Configuration created Thu Oct 23 20:13:55 2003 by fetchmailconf +set syslog +set postmaster "postmaster" +set bouncemail +set no spambounce +set properties "" +poll pop.whosey.net with proto POP3 + user 'foo' there with password '*' is 'me' here + user 'bar' there with password '*' is 'her' here + user 'baz' there with password '*' is 'that' here + +poll mail.whatsey.ca with proto POP3 interval 60 + user 'nimble' there with password '*' is 'her' here + diff --git a/dist-tools/test/testservers-gen.sh b/dist-tools/test/testservers-gen.sh new file mode 100755 index 00000000..52a1e589 --- /dev/null +++ b/dist-tools/test/testservers-gen.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +date=`date` +cat <<EOF +<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<link rev=made href="mailto:esr@snark.thyrsus.com"/> +<meta name="description" content=""/> +<meta name="keywords" content=""/> +<title>Fetchmail's Test List</title> +</head> +<body> +<table width="100%" cellpadding=0 summary="Canned page header"><tr> +<td width="30%">Back to <a href="/~esr">Eric's Home Page</a> +<td width="30%" align=center>Up to <a href="/~esr/sitemap.html">Site Map</a> +<td width="30%" align=right>${date} +</tr></table> +<hr /> +<h1>Fetchmail's Test List</h1> + +<p>Here are the server types on my regression-test list:</p> + +<table border=1 width=80% align=center summary="Server list"> +<tr> +<td><strong>Protocol & Version:</strong></td> +<td><strong>Special Options:</strong></td> +</tr> +EOF +torturetest.py -t +cat <<EOF +</tr></table> + +<p>If you control a post-office server that is not one of the types listed +here, please consider lending me a test account. Note that I do <em>not</em> +need shell access, just the permissions to send mail to a mailbox the server +looks at and to fetch mail off of it.</p> + +<p>I'd like to have weird things like a POP2 server on here. Also more +closed-source servers because they tend to be broken in odd +ways. These are the real robustness tests.</p> + +<hr /> +<table width="100%" cellpadding=0 summary="Canned page header"><tr> +<td width="30%">Back to <a href="/~esr">Eric's Home Page</a> +<td width="30%" align=center>Up to <a href="/~esr/sitemap.html">Site Map</a> +<td width="30%" align=right>${date} +</tr></table> + +<br clear="left" /> +<ADDRESS>Eric S. Raymond <A HREF="mailto:esr@thyrsus.com"><esr@thyrsus.com></A></ADDRESS> +</BODY> +</HTML> +EOF + diff --git a/dist-tools/test/testservers.html b/dist-tools/test/testservers.html new file mode 100644 index 00000000..62dc9e7b --- /dev/null +++ b/dist-tools/test/testservers.html @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<link rev=made href="mailto:esr@snark.thyrsus.com"/> +<meta name="description" content=""/> +<meta name="keywords" content=""/> +<title>Fetchmail's Test List</title> +</head> +<body> +<table width="100%" cellpadding=0 summary="Canned page header"><tr> +<td width="30%">Back to <a href="/~esr">Eric's Home Page</a> +<td width="30%" align=center>Up to <a href="/~esr/sitemap.html">Site Map</a> +<td width="30%" align=right>Mon Jan 12 15:52:14 EST 2004 +</tr></table> +<hr /> +<h1>Fetchmail's Test List</h1> + +<p>Here are the server types on my regression-test list:</p> + +<table border=1 width=80% align=center summary="Server list"> +<tr> +<td><strong>Protocol & Version:</strong></td> +<td><strong>Special Options:</strong></td> +</tr> +<tr><td>IMAP: CommuniGate IMAP server</td><td>IMAPrev1 STARTTLS AUTH=CRAM-MD5 AUTH=DIGEST-MD5</td> +<tr><td>POP3: CommuniGate POP3 server</td><td>CAPA LAST APOP CRAM-MD5</td> +<tr><td>POP3: IntraStore POP3 mail server</td><td>!CAPA LAST</td> +<tr><td>APOP: IntraStore POP3 mail server</td><td>!CAPA LAST APOP</td> +<tr><td>IMAP: IntraStore IMAP mail server</td><td>IMAPrev1 IDLE AUTH=CRAM-MD5 AUTH=SKEY AUTH=ANONYMOUS</td> +<tr><td>POP3: Eudora EIMS</td><td>CAPA LAST APOP SASL CRAM-MD5 NTLM</td> +<tr><td>POP3: gmx.de pop server</td><td>!CAPA UIDL</td> +<tr><td>IMAP: IMail IMAP server</td><td>IMAP4rev1 AUTH=CRAM-MD5</td> +<tr><td>IMAP: Microsoft Exchange</td><td>IDLE AUTH=NTLM</td> +<tr><td>POP3: qpopper 3.1.2 (Eudora) patched with mysql</td><td>CAPA UIDL</td> +<tr><td>IMAP: Courier IMAP</td><td>IMAP4rev1</td> +<tr><td>POP3: Courier POP3</td><td>CAPA UIDL</td> +<tr><td>APOP: Qpopper using APOP</td><td>!CAPA</td> +<tr><td>IMAP: UW IMAP</td><td>IMAPrev1</td> +<tr><td>IMAP: Courier IMAP</td><td>IMAP4rev1</td> +<tr><td>POP3: Qpopper 4.0.5</td><td>CAPA UIDL</td> +</tr></table> + +<p>If you control a post-office server that is not one of the types listed +here, please consider lending me a test account. Note that I do <em>not</em> +need shell access, just the permissions to send mail to a mailbox the server +looks at and to fetch mail off of it.</p> + +<p>I'd like to have weird things like a POP2 server on here. Also more +closed-source servers because they tend to be broken in odd +ways. These are the real robustness tests.</p> + +<hr /> +<table width="100%" cellpadding=0 summary="Canned page header"><tr> +<td width="30%">Back to <a href="/~esr">Eric's Home Page</a> +<td width="30%" align=center>Up to <a href="/~esr/sitemap.html">Site Map</a> +<td width="30%" align=right>Mon Jan 12 15:52:14 EST 2004 +</tr></table> + +<br clear="left" /> +<ADDRESS>Eric S. Raymond <A HREF="mailto:esr@thyrsus.com"><esr@thyrsus.com></A></ADDRESS> +</BODY> +</HTML> diff --git a/dist-tools/test/torturetest.glade b/dist-tools/test/torturetest.glade new file mode 100644 index 00000000..d2cf07ee --- /dev/null +++ b/dist-tools/test/torturetest.glade @@ -0,0 +1,976 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> + +<glade-interface> + +<widget class="GtkWindow" id="torturetest"> + <property name="visible">True</property> + <property name="title" translatable="yes">torturetest</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <signal name="destroy" handler="on_torturetest_destroy" last_modification_time="Wed, 16 Jul 2003 18:21:37 GMT"/> + + <child> + <widget class="GtkVBox" id="vbox1"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkHBox" id="hbox2"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkLabel" id="sitelabel"> + <property name="visible">True</property> + <property name="label" translatable="yes">Site select: </property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkCombo" id="combo1"> + <property name="visible">True</property> + <property name="value_in_list">False</property> + <property name="allow_empty">True</property> + <property name="case_sensitive">False</property> + <property name="enable_arrow_keys">True</property> + <property name="enable_arrows_always">False</property> + + <child internal-child="entry"> + <widget class="GtkEntry" id="entry2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + <signal name="activate" handler="on_combo_entry1_activate" last_modification_time="Wed, 16 Jul 2003 18:48:10 GMT"/> + </widget> + </child> + + <child internal-child="list"> + <widget class="GtkList" id="list1"> + <property name="visible">True</property> + <property name="selection_mode">GTK_SELECTION_BROWSE</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHSeparator" id="hseparator2"> + <property name="visible">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkTable" id="table1"> + <property name="visible">True</property> + <property name="n_rows">9</property> + <property name="n_columns">2</property> + <property name="homogeneous">False</property> + <property name="row_spacing">0</property> + <property name="column_spacing">0</property> + + <child> + <widget class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="label" translatable="yes">Sitename: </property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="label" translatable="yes">Mail Address: </property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="label" translatable="yes">Username:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label4"> + <property name="visible">True</property> + <property name="label" translatable="yes">Password: </property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="mailaddr_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="username_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="password_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="comment_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">8</property> + <property name="bottom_attach">9</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="recognition_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">7</property> + <property name="bottom_attach">8</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="capabilities_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">6</property> + <property name="bottom_attach">7</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="options_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">5</property> + <property name="bottom_attach">6</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label9"> + <property name="visible">True</property> + <property name="label" translatable="yes">Comment:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">8</property> + <property name="bottom_attach">9</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label8"> + <property name="visible">True</property> + <property name="label" translatable="yes">Recognition: </property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">7</property> + <property name="bottom_attach">8</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label7"> + <property name="visible">True</property> + <property name="label" translatable="yes">Capabilities:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">6</property> + <property name="bottom_attach">7</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label6"> + <property name="visible">True</property> + <property name="label" translatable="yes">Options: </property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">5</property> + <property name="bottom_attach">6</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label5"> + <property name="visible">True</property> + <property name="label" translatable="yes">Protocol:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="host_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox8"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkHBox" id="hbox1"> + <property name="visible">True</property> + <property name="homogeneous">True</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkRadioButton" id="POP3_radiobutton"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">POP3</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkRadioButton" id="APOP_radiobutton"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">APOP</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + <property name="group">POP3_radiobutton</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkRadioButton" id="IMAP_radiobutton"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">IMAP</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + <property name="group">POP3_radiobutton</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkVSeparator" id="vseparator1"> + <property name="visible">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkCheckButton" id="ssl_checkbox"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">SSL</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="x_options">fill</property> + <property name="y_options">fill</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHSeparator" id="hseparator1"> + <property name="visible">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHButtonBox" id="hbuttonbox1"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkButton" id="updatebutton"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <signal name="clicked" handler="on_updatebutton_clicked" last_modification_time="Wed, 16 Jul 2003 23:17:30 GMT"/> + + <child> + <widget class="GtkAlignment" id="alignment4"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + + <child> + <widget class="GtkHBox" id="hbox6"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child> + <widget class="GtkImage" id="image4"> + <property name="visible">True</property> + <property name="stock">gtk-apply</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label14"> + <property name="visible">True</property> + <property name="label" translatable="yes">Update</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkButton" id="newbutton"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <signal name="clicked" handler="on_newbutton_clicked" last_modification_time="Wed, 16 Jul 2003 20:28:12 GMT"/> + + <child> + <widget class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + + <child> + <widget class="GtkHBox" id="hbox3"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child> + <widget class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="stock">gtk-new</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label11"> + <property name="visible">True</property> + <property name="label" translatable="yes">New</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkButton" id="testbutton"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <signal name="clicked" handler="on_testbutton_clicked" last_modification_time="Wed, 16 Jul 2003 20:28:23 GMT"/> + + <child> + <widget class="GtkAlignment" id="alignment3"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + + <child> + <widget class="GtkHBox" id="hbox5"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child> + <widget class="GtkImage" id="image3"> + <property name="visible">True</property> + <property name="stock">gtk-execute</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label13"> + <property name="visible">True</property> + <property name="label" translatable="yes">Test</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkButton" id="quitbutton"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <signal name="clicked" handler="on_quitbutton_clicked" last_modification_time="Wed, 16 Jul 2003 20:08:46 GMT"/> + + <child> + <widget class="GtkAlignment" id="alignment2"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + + <child> + <widget class="GtkHBox" id="hbox4"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child> + <widget class="GtkImage" id="image2"> + <property name="visible">True</property> + <property name="stock">gtk-quit</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label12"> + <property name="visible">True</property> + <property name="label" translatable="yes">Quit</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkButton" id="dumpbutton"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <signal name="clicked" handler="on_dumpbutton_clicked" last_modification_time="Wed, 16 Jul 2003 23:34:47 GMT"/> + + <child> + <widget class="GtkAlignment" id="alignment5"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + + <child> + <widget class="GtkHBox" id="hbox7"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child> + <widget class="GtkImage" id="image5"> + <property name="visible">True</property> + <property name="stock">gtk-print</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label15"> + <property name="visible">True</property> + <property name="label" translatable="yes">Dump</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> +</widget> + +</glade-interface> diff --git a/dist-tools/test/torturetest.gladep b/dist-tools/test/torturetest.gladep new file mode 100644 index 00000000..d44797c3 --- /dev/null +++ b/dist-tools/test/torturetest.gladep @@ -0,0 +1,7 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd"> + +<glade-project> + <name>torturetest</name> + <program_name>torturetest</program_name> +</glade-project> diff --git a/dist-tools/test/torturetest.py b/dist-tools/test/torturetest.py new file mode 100755 index 00000000..f8a3535c --- /dev/null +++ b/dist-tools/test/torturetest.py @@ -0,0 +1,326 @@ +#!/usr/bin/env python2 + +import sys, getopt, os, smtplib, commands, time, gtk, gtk.glade + +protocols = ('POP3', 'APOP', 'IMAP',) + +class TestSite: + temp = "/usr/tmp/torturestest-%d" % os.getpid() + + def __init__(self, line=None): + "Initialize site data from the external representation." + self.host = "" + self.mailaddr = "" + self.username = "" + self.password = "" + self.protocol = "" + self.ssl = "" + self.options = "" + self.capabilities = "" + self.recognition = "" + self.comment = "" + if line: + (self.host, self.mailaddr, self.username, self.password, \ + self.protocol, self.ssl, self.options, self.capabilities, \ + self.recognition, self.comment) = \ + line.strip().split(":") + if not self.mailaddr: + self.mailaddr = self.username + # Test results + self.status = None + self.output = None + + def allattrs(self): + "Return a tuple consisting of all this site's attributes." + return (self.host, self.mailaddr, self.username, self.password, \ + self.protocol, self.ssl, self.options, self.capabilities, \ + self.recognition, self.comment) + + def __repr__(self): + "Return the external representation of this site's data." + return ":".join(self.allattrs()) + + def prettyprint(self): + "Prettyprint a site entry in human-readable form." + return "Host: %s\n" \ + "Mail To: %s\n" \ + "Username: %s\n" \ + "Password: %s\n" \ + "Protocol: %s\n" \ + "SSL: %s\n" \ + "Options: %s\n" \ + "Capabilities: %s\n" \ + "Recognition: %s\n" \ + "Comment: %s\n" \ + % self.allattrs() + + def entryprint(self): + "Print a .fetchmailrc entry corresponding to a site entry." + rep = "poll %s-%s via %s with proto %s %s\n" \ + " user %s there with password '%s' is esr here" \ + % (self.host,self.protocol,self.host,self.protocol,self.options,self.username,self.password) + if self.ssl and self.ssl != 'False': + rep += " options ssl" + rep += "\n\n" + return rep + + def tableprint(self): + "Print an HTML server-type table entry." + return "<tr><td>%s: %s</td><td>%s</td>\n" \ + % (self.protocol, self.comment, self.capabilities) + + def id(self): + "Identify this site." + rep = "%s %s at %s" % (self.protocol, self.recognition, self.host) + if self.capabilities: + rep += " (" + self.capabilities + ")" + if self.options: + rep += " using " + self.options + return rep + + def testmail(self, n=None): + "Send test mail to the site." + server = smtplib.SMTP("localhost") + fromaddr = "esr@thyrsus.com" + if self.mailaddr.find("@") > -1: + toaddr = self.mailaddr + else: + toaddr = "%s@%s" % (self.mailaddr, self.host) + msg = ("From: %s\r\nTo: %s\r\n\r\n" % (fromaddr, toaddr)) + if n != None: + msg += `n` + ": " + msg += "Test mail collected from %s.\n" % (self.id(),) + server.sendmail(fromaddr, toaddr, msg) + server.quit() + + def fetch(self, logfile=False): + "Run a mail fetch on this site." + try: + ofp = open(TestSite.temp, "w") + if logfile: + mda = "(echo; echo \'From torturetest\' `date`;cat) >>TEST.LOG" + else: + mda = 'cat' + ofp.write('defaults mda "%s"\n' % mda) + ofp.write(self.entryprint()) + ofp.close() + (self.status, self.output) = commands.getstatusoutput("fetchmail -d0 -v -f - <%s"%TestSite.temp) + if self.status: + os.system("cat " + TestSite.temp) + finally: + os.remove(TestSite.temp) + + def failed(self): + "Did we have a test failure here?" + return os.WIFEXITED(self.status) and os.WEXITSTATUS(self.status) > 1 + + def explain(self): + "Explain the status of the last test." + if not os.WIFEXITED(self.status): + return self.id() + ": abnormal termination\n" + elif os.WEXITSTATUS(self.status) > 1: + return self.id() + ": %d\n" % os.WEXITSTATUS(self.status) + self.output + else: + return self.id() + ": succeeded\n" + +class TortureGUI: + "Torturetest editing GUI," + + # All site parameters except protocol + field_map = ('host', 'mailaddr', 'username', 'password', \ + 'options', 'capabilities', 'recognition', 'comment') + + def __init__(self): + # Build the widget tree from the glade XML file. + self.wtree = gtk.glade.XML("torturetest.glade") + # File in initial values + self.combo = self.wtree.get_widget("combo1") + self.combo.set_popdown_strings(map(lambda x: x.comment, sitelist)) + self.sslcheck = self.wtree.get_widget("ssl_checkbox") + self.site = sitelist[0] + self.display(self.site) + + # Provide handlers for the widget tree's events + mydict = {} + for key in ('on_torturetest_destroy', + 'on_updatebutton_clicked', + 'on_newbutton_clicked', + 'on_testbutton_clicked', + 'on_quitbutton_clicked', + 'on_dumpbutton_clicked', + 'on_combo_entry1_activate'): + mydict[key] = getattr(self, key) + self.wtree.signal_autoconnect(mydict) + + gtk.mainloop() + print `self.site` + + def get_widget(self, widget): + "Get the value of a widget's contents." + if type(widget) == type(""): + widget = self.wtree.get_widget(widget) + if type(widget) == gtk.Entry: + return widget.get_text() + #elif type(widget) == gtk.SpinButton: + # return widget.get_value() + #elif type(widget) == gtk.TextView: + # return widget.get_buffer().get_text() + + def set_widget(self, name, exp): + "Set the value of a widget by name." + widget = self.wtree.get_widget(name) + if type(widget) == gtk.Entry: + widget.set_text(exp) + elif type(widget) == gtk.SpinButton: + widget.set_value(exp) + elif type(widget) == gtk.TextView: + if not widget.get_buffer(): + widget.set_buffer(gtk.TextBuffer()) + widget.get_buffer().set_text(exp) + + def display(self, site): + for member in TortureGUI.field_map: + self.set_widget(member + "_entry", getattr(site, member)) + for proto in protocols: + self.wtree.get_widget(proto + "_radiobutton").set_active(site.protocol == proto) + self.sslcheck.set_active(int(site.ssl != '' and site.ssl != 'False')) + self.combo.entry.set_text(site.comment) + + def update(self, site): + for member in TortureGUI.field_map: + setattr(site, member, self.get_widget(member + "_entry")) + for proto in protocols: + if self.wtree.get_widget(proto + "_radiobutton").get_active(): + site.protocol = proto + if self.wtree.get_widget("ssl_checkbox").get_active(): + site.ssl = "True" + else: + site.ssl = "False" + + # Housekeeping + def on_torturetest_destroy(self, obj): + gtk.mainquit() + def on_updatebutton_clicked(self, obj): + self.update(self.site) + print self.site + if self.site.comment: + self.combo.entry.set_text(self.site.comment) + else: + self.combo.entry.set_text(self.site.host) + def on_newbutton_clicked(self, obj): + global sitelist + sitelist = [TestSite()] + sitelist + self.site = sitelist[0] + self.display(self.site) + self.combo.entry.set_text("") + def on_testbutton_clicked(self, obj): + self.site.fetch(False) + print self.site.output + def on_quitbutton_clicked(self, obj): + gtk.mainquit() + def on_dumpbutton_clicked(self, obj): + print `self.site` + + def on_combo_entry1_activate(self, obj): + key = self.combo.entry.get_text() + for site in sitelist: + if site.comment.find(key) > -1: + self.site = site + self.display(self.site) + break + +if __name__ == "__main__": + # Start by reading in the sitelist + ifp = open("testsites") + sitelist = [] + linect = 0 + while 1: + linect += 1 + line = ifp.readline() + if not line: + break + elif line[0] in ("#", "\n"): + continue + else: + try: + sitelist.append(TestSite(line)) + except: + print "Error on line %d" % linect + sys.exit(0) + + (options, arguments) = getopt.getopt(sys.argv[1:], "dfp:tigvse") + verbose = 0 + for (switch, value) in options: + if switch == "-d": + # Prettprint the sitelist + map(lambda x: sys.stdout.write(x.prettyprint() + "%%\n"), sitelist) + sys.exit(0) + elif switch == "-f": + # Dump the sitelist as a .fetchmailrc file + map(lambda x: sys.stdout.write(x.entryprint()), sitelist) + sys.exit(0) + elif switch == "-p": + # Probe a single site + selected = [] + for site in sitelist: + if `site`.find(value) > -1: + selected.append(site) + sitelist = selected + # Fall through + elif switch == "-t": + # Dump the sitelist in HTML table form + map(lambda x: sys.stdout.write(x.tableprint()), sitelist) + sys.exit(0) + elif switch == "-i": + # Dump the ids of the sitelist + map(lambda x: sys.stdout.write(x.id() + "\n"), sitelist) + sys.exit(0) + elif switch == "-g": + i = 1 + for site in sitelist: + print "Sending test mail to " + site.id() + site.testmail(i) + i+= 1 + # Send test mail to each site + sys.stdout.write("Delaying to give the test mail time to land...") + time.sleep(5) + sys.stdout.write("here we go:\n") + # Fall through + elif switch == "-v": + # Display the test output + verbose = 1 + elif switch == "-s": + # Dump recognition strings of all tested servers as a Python tuple + print "(" + ",\n".join(map(lambda x: repr(x.recognition), filter(lambda x: x.recognition, sitelist))) + ")" + sys.exit(0) + elif switch == "-e": + TortureGUI() + sys.exit(0) + + # If no options, run the torture test + try: + failures = successes = 0 + os.system("fetchmail -q") + for site in sitelist: + print "Testing " + site.id() + site.fetch(True) + if verbose: + print site.output + if site.failed(): + failures += 1 + else: + successes += 1 + + # OK, summarize results + print "\n%d successes and %d failures out of %d tests" \ + % (successes, failures, len(sitelist)) + + if failures: + print "Bad status was returned on the following sites:" + for site in sitelist: + if site.failed(): + sys.stdout.write(site.explain() + "\n") + except KeyboardInterrupt: + print "Interrupted." + +# end diff --git a/dist-tools/timeplot b/dist-tools/timeplot new file mode 100755 index 00000000..c8240d05 --- /dev/null +++ b/dist-tools/timeplot @@ -0,0 +1,40 @@ +#!/bin/sh +# +# timeplot -- plot data on fetchmail release intervals +# +# + +# Get data from the NEWS file +timeseries | awk >/tmp/timeplot$$ ' +START {maxdiff = 0;} +/^[#%]/ {next;} + {days[count++] = $6;} +END { + for (i = 0; i < count-1; i++) + { + diffs[i] = days[i] - days[i + 1]; + if (maxdiff < diffs[i]) + maxdiff = diffs[i]; + } + for (i = 0; i <= maxdiff; i++) + freq[i] = 0; + for (i = 0; i < count - 1; i++) + { + freq[diffs[i]]++; + } + for (i = 0; i <= maxdiff; i++) + printf("%d %d\n", i, freq[i]); + } +' + +gnuplot >time.png - <<EOF +set xlabel "Release interval (days)" +set ylabel "Interval frequency" +plot '/tmp/timeplot$$' using 1:2 \ + title "Release interval frequency" +pause 9999 +EOF + +rm -f /tmp/time* + +# timeplot ends here diff --git a/dist-tools/timeseries b/dist-tools/timeseries new file mode 100755 index 00000000..7a20c4c2 --- /dev/null +++ b/dist-tools/timeseries @@ -0,0 +1,101 @@ +#!/usr/bin/perl +# +# Extract information on the fetchmail project size from the NEWS file +# +# Note: this only works if you have a news file from 5.1.1 or later -- +# I didn't patch the code sizes into NEWS until then. +# +my($release, $date, $jdate); + +%month_offsets = ( + "Jan", 0, + "Feb", 31, + "Mar", 59, + "Apr", 90, + "May", 120, + "Jun", 151, + "Jul", 181, + "Aug", 212, + "Sep", 243, + "Oct", 273, + "Nov", 304, + "Dec", 334, +); + + +sub day_offset +{ + my($datestring) = @_; + my($wday, $month, $day, $time, $zone, $year) = split(' ', $datestring); + my($jdate); + + # We don't deal with leap years here because the baseline day is after + # the last leap year (1996) and there's a long time before the next + # one (2004). + $jdate = ($year - 1996) * 365; + + $jdate += $month_offsets{$month}; + + $jdate += ($day - 1); + + # Baseline day for the size data was Fri Oct 25 23:02:26 EDT 1996 + $jdate -= 297; + + return($jdate); +} + +open(NEWS, "NEWS"); +$timestamp = `date`; +chop $timestamp; +$release = "unknown"; +$lines = "unknown"; +$date = "unknown"; +$jdate = "unknown"; +print <<EOF; +# Population data from fetchmail NEWS file, as of $timestamp. +# +# Output other than pass-through % lines is tab-separated fields. +# Field 1: release ID +# Field 2: count of source lines under version control +# Field 3: count of fetchmail-friends subscribers +# Field 4: count of fetchmail-announce subscribers +# Field 5: total subscribers to both lists +# Field 6: date of release (days since first datum) +# Field 7: date of release (RFC822 date format) +# +EOF +while ($_ = <NEWS>) +{ + my($sum); + + if (/^%/) { + print $_; + } + elsif (/^fetchmail-([^ ]*) \(([^)]+)\)(, [0-9]* lines)?:/) { + $release = $1; + $date = $2; + $jdate = &day_offset($date); + if ($3) { + $lines = substr($3, 2, length($3) - 8); + } else { + $lines = 'na' + } + } + elsif (/There are ([0-9]*) people on fetchmail-friends and ([0-9]*) on fetchmail-announce/) { + $sum = $1 + $2; + print "${release}\t${lines}\t$1\t$2\t${sum}\t${jdate}\t${date}\n"; + $release = "unknown"; + $date = "unknown"; + } + elsif (/There are ([0-9]*) people on the fetchmail-friends list./) { + print "$release\t${lines}\t$1\t0\t$1\t$jdate\t$date\n"; + $release = "unknown"; + $date = "unknown"; + } +} + +# end + + + + diff --git a/dist-tools/upload b/dist-tools/upload new file mode 100755 index 00000000..3a76ee49 --- /dev/null +++ b/dist-tools/upload @@ -0,0 +1,26 @@ +#!/bin/sh + +version=`sed -n '/VERSION *= *\(.*\)/s//\1/p' <Makefile` +echo "Uploading fetchmail version ${version}" + +if [ $* ] +then + ../upload $* +else + +echo "Beginning web upload..." +# First, copy to primary website +dest=esr@${WWWHOST}:${WWWDIR}/fetchmail +scp fetchmail-${version}.tar.gz.asc $dest +#scp funny.html $dest +#scp fetchmail.png $dest +#scp bighand.png $dest +scp growth.png $dest +scp timeseries $dest +scp growthplot $dest +scp checksums $dest +# shipper does the rest. +rm -f ANNOUNCE.FRESHMEAT +shipper + + diff --git a/dist-tools/uploadfaq b/dist-tools/uploadfaq new file mode 100755 index 00000000..73d29468 --- /dev/null +++ b/dist-tools/uploadfaq @@ -0,0 +1,24 @@ +#!/bin/sh + +version=`sed -n '/VERSION *= *\(.*\)/s//\1/p' <Makefile` +echo "Uploading fetchmail version ${version} FAQ" + +if [ $* ] +then + ../upload $* +else + lftp <<EOF +# First, copy to primary website +open ${WWWHOST} +cd ${WWWDIR}/fetchmail +put fetchmail-FAQ.html +close + +# Next, upload to the ftp site +open locke.ccil.org +cd ~ftp/pub/esr/fetchmail +put FAQ +close +EOF + echo "fetchmail FAQ uploaded" +fi
\ No newline at end of file |