[Pkg-wmaker-commits] [wmbiff] 41/92: Imported Upstream version 0.3.8

Doug Torrance dtorrance-guest at moszumanska.debian.org
Thu Aug 20 02:59:24 UTC 2015


This is an automated email from the git hooks/post-receive script.

dtorrance-guest pushed a commit to branch master
in repository wmbiff.

commit 13ce02cb21e3cc17a675178c18d18e96268578e1
Author: Doug Torrance <dtorrance at monmouthcollege.edu>
Date:   Fri Nov 14 08:19:59 2014 -0600

    Imported Upstream version 0.3.8
---
 ChangeLog                    |  518 ++++++++++++++++++-
 NEWS                         |  282 ++++++++++
 README                       |   84 ++-
 README.licq                  |   23 +
 TODO                         |   15 +
 wmbiff/Client.h              |  125 +++++
 wmbiff/Imap4Client.c         |  454 ++++++++++++++++
 wmbiff/LicqClient.c          |   91 ++++
 wmbiff/Makefile              |  137 ++++-
 wmbiff/Pop3Client.c          |  498 +++++++++++-------
 wmbiff/Pop3Client.h          |   34 --
 wmbiff/ShellClient.c         |  114 +++++
 wmbiff/charutil.c            |  221 ++++++++
 wmbiff/charutil.h            |   34 ++
 wmbiff/maildirClient.c       |  135 +++++
 wmbiff/mboxClient.c          |  133 +++++
 wmbiff/sample.wmbiffrc       |   54 +-
 wmbiff/socket.c              |   61 +++
 wmbiff/test-wmbiffrc.shell   |   24 +
 wmbiff/tlsComm.c             |  451 ++++++++++++++++
 wmbiff/tlsComm.h             |   55 ++
 wmbiff/wmbiff-master-led.xpm |    2 +-
 wmbiff/wmbiff-master.xpm     |    1 -
 wmbiff/wmbiff.1              |   88 ++++
 wmbiff/wmbiff.c              | 1166 ++++++++++++++++++++----------------------
 wmbiff/wmbiffrc.5            |  198 +++++++
 wmgeneral/list.h             |    2 +-
 wmgeneral/wmgeneral.c        |   40 +-
 wmgeneral/wmgeneral.h        |    6 +-
 29 files changed, 4144 insertions(+), 902 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f9693ad..f3178c4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,13 +1,507 @@
-  *	v 0.1	17-Nov-1999
-  -	Initial release
-
-  *	v 0.1a	18-Nov-1999
-  -	Some fixes with intialization
-
-  *	v 0.2	26-Nov-1999
-  -	POP3 support added with (auto)fetching
-  -	digits blinking on new mail arrival
-  -	resource wasting lowered
-  -	individual rescan interval for differrent mailboxes
-  -	some bugfixes
+2002-03-26 Tuesday 16:30 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, NEWS, wmbiff/Makefile: Released WMBiff 0.3.8.
+
+2002-03-18 Monday 21:13 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* TODO: add failure handling in expect
+
+2002-03-18 Monday 09:47 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmgeneral/wmgeneral.h: un-shadow index
+
+2002-03-18 Monday 09:46 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmgeneral/wmgeneral.c: un-shadow a global variable
+
+2002-03-14 Thursday 08:51 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* README: correct and expand upon crypto instructions
+
+2002-03-12 Tuesday 23:53 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/: Client.h, Imap4Client.c, Pop3Client.c, ShellClient.c,
+	tlsComm.c: fixed misunderstanding of the use of ## in macros with
+	strings - the compiler does the concatenation, not the preprocessor
+
+2002-03-12 Tuesday 09:15 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* TODO: additional todo list items
+
+2002-03-11 Monday 00:11 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/tlsComm.c: slightly better message on expect failure
+
+2002-03-09 Saturday 08:50 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/ShellClient.c: debug messages cleanup; start handling
+	pclose errors; remove open() function pointer assignment; #include
+	fix
+
+2002-03-09 Saturday 08:03 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmgeneral/: list.h, wmgeneral.c: minor warning cleanups
+
+2002-03-08 Friday 19:26 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* README: credit Ben
+
+2002-03-07 Thursday 22:20 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/ShellClient.c: fix error return status (ben's 'lil' patch)
+
+2002-03-07 Thursday 07:04 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/ShellClient.c: appropriate credits
+
+2002-03-06 Wednesday 18:01 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/ShellClient.c: fix my sloppy mistake in shell path parsing
+
+2002-03-06 Wednesday 07:59 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/ShellClient.c: misplaced string.h
+
+2002-03-06 Wednesday 07:59 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/wmbiff.c: rename in Read_Config_File for more 'index'
+	purging
+
+2002-03-06 Wednesday 07:44 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/ShellClient.c: fix a potential file descriptor leak
+
+2002-03-06 Wednesday 07:15 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/: Client.h, Makefile, ShellClient.c, mboxClient.c,
+	sample.wmbiffrc, test-wmbiffrc.shell, wmbiff.1, wmbiff.c,
+	wmbiffrc.5: Draft shell command and gnomeicu support from Beno�t
+	Rouits with minor modifications 1) implement gicu using the shell
+	module rather than as a separate module, 2) edit Ben's shell format
+	to have extra colons for extensibility, 3) add some extra error
+	checking in the shell method.  I also added a test wmbiffrc that
+	can be used to verify that the gicu and shell methods "work".
+
+2002-03-05 Tuesday 05:02 UTC -- Dwayne C. Litzenberger <dlitz at dlitz.net>
+
+	* wmbiff/maildirClient.c: cosmetic changes
+
+2002-03-04 Monday 06:57 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/mboxClient.c: convert a lingering fprintf to DM
+
+2002-03-02 Saturday 23:25 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/: Imap4Client.c, Makefile, wmbiff.c: a little -Wshadow and
+	-Wcast-qual cleanup (or, eliminate the use of 'index' as a variable
+	name)
+
+2002-03-02 Saturday 22:38 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/Client.h: add preprocessor define to handle portability of
+	__attribute__ tag to non-gcc compilers (untested)
+
+2002-03-02 Saturday 06:42 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/tlsComm.c: indent run (oops)
+
+2002-03-02 Saturday 06:41 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/: Pop3Client.c, Imap4Client.c: minor reorganization of
+	gcrypt-needing authentication schemes
+
+2002-03-02 Saturday 06:39 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/tlsComm.c: attribute tags for warning cleanup w/o gnutls
+
+2002-03-02 Saturday 06:36 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/wmbiff.c: gcc attribute tags, minor debug message cleanup
+
+2002-03-02 Saturday 06:31 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/Makefile: rearrange which compiler warnings are implied by
+	DEBUG
+
+2002-03-02 Saturday 05:58 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/Client.h: use off_t instead of size_t in Licq and Maildir
+	for file sizes from stat()
+
+2002-03-02 Saturday 05:50 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/tlsComm.c: bugfix to support compilation without crypto
+
+2002-03-01 Friday 11:58 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* wmbiff/wmbiff.c: Added -debug to help text.  Removed Gennady's
+	mail address and added our devel list.
+
+2002-03-01 Friday 11:28 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* wmbiff/Makefile: Fixed install rule in Makefile.
+
+2002-03-01 Friday 08:41 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/: Client.h, Imap4Client.c, LicqClient.c, Makefile,
+	Pop3Client.c, maildirClient.c, mboxClient.c, tlsComm.c, tlsComm.h,
+	wmbiff.1, wmbiff.c, wmbiffrc.5: Replaced DEBUG_x preprocessor
+	defines with a -debug option and debug configuration keyword. 
+	Replaced most debugging messages with a DM (debug message) macro. 
+	Removed gnutls version 0.2.x support.  Added troubleshooting
+	section to man page.
+
+2002-02-03 Sunday 22:48 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, NEWS: Released WMBiff 0.3.7.
+
+2002-02-03 Sunday 22:43 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* wmbiff/Makefile: Bumped WMBIFF_VERSION to 0.3.7.
+
+2002-02-02 Saturday 18:04 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* NEWS, wmbiff/Client.h, wmbiff/Imap4Client.c, wmbiff/Makefile,
+	wmbiff/Pop3Client.c, wmbiff/charutil.h: Makefile fixes from Simon
+	L. Nielsen, which help building wmbiff in FreeBSD.  Fixed the
+	previous IMAP regex patch.
+
+2002-01-27 Sunday 20:20 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, maint/changelog.sed, maint/prerelease.sh: Some fixes
+	for the maint scripts.
+
+2002-01-27 Sunday 19:59 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, NEWS: Released WMBiff 0.3.6.
+
+2002-01-27 Sunday 19:56 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* wmbiff/Imap4Client.c: Indent fixes.
+
+2002-01-27 Sunday 19:52 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* wmbiff/Makefile: Bump WMBIFF_VERSION to 0.3.6.
+
+2002-01-27 Sunday 12:46 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* NEWS, README, wmbiff/Imap4Client.c, wmbiff/Makefile,
+	wmbiff/wmbiffrc.5: Alternate regex for imap/imaps which allows "@"
+	in passwords.  Fix to correctly handle the auth list in imap. 
+	Patch from David Smith <davidsmith at acm.org>.
+
+2002-01-14 Monday 01:51 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, NEWS: Released WMBiff 0.3.5.
+
+2002-01-14 Monday 01:50 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* wmbiff/Makefile: Bump WMBIFF_VERSION to 0.3.5.
+
+2002-01-12 Saturday 19:18 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/Imap4Client.c: quote patch from Nick Mitchell, ref debian
+	#128863
+
+2002-01-12 Saturday 06:17 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/tlsComm.c: debugging for gnutls3
+
+2002-01-12 Saturday 05:50 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/Makefile: clarify what to do with gnutls version define
+
+2002-01-12 Saturday 05:30 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/: Makefile, charutil.c, tlsComm.c: update for the
+	interface change in gnutls 0.3.0
+
+2001-11-23 Friday 15:57 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog: Released WMBiff 0.3.4.
+
+2001-11-23 Friday 15:55 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* NEWS, wmbiff/Makefile: Bumped version to 0.3.4, and release.
+
+2001-11-23 Friday 15:53 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, NEWS, wmbiff/sample.wmbiffrc: Doc updates for 0.3.4.
+
+2001-11-23 Friday 07:20 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* TODO: one down
+
+2001-11-16 Friday 07:11 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/: Imap4Client.c, Pop3Client.c, charutil.c: regexes limit
+	password and username to 32 characters
+
+2001-11-16 Friday 06:08 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmgeneral/: wmgeneral.c, wmgeneral.h: -Wwrite-strings cleanliness
+
+2001-11-16 Friday 01:13 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/: Client.h, Imap4Client.c, Makefile, Pop3Client.c,
+	charutil.c: rewrite of authentication code to a) allow users to
+	specify authentication type, b) fall back to other authentication
+	methods when hash-based authentication fails (because not everybody
+	uses the cleartext password file) c) fix debug messages
+
+2001-11-16 Friday 00:40 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/charutil.h: regex helpers common to pop3 and imap4 clients
+	extracted and moved here
+
+2001-11-16 Friday 00:40 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/: tlsComm.c, tlsComm.h: blacklist and debugging updates
+	for gnutls 0.2.10 and DM macro
+
+2001-11-16 Friday 00:39 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/wmbiffrc.5: authentication method list, reduced
+	indentation to fit screen better
+
+2001-11-16 Friday 00:38 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/wmbiff-master-led.xpm: made pixmap const char
+
+2001-11-16 Friday 00:37 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/wmbiff.c: -Wwrite-strings cleanliness
+
+2001-11-02 Friday 08:53 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/: Imap4Client.c, wmbiff.c, wmbiffrc.5: Prefer "imaps"
+	instead of "sslimap" (sslimap is still supported, but imaps is
+	documented, and a better name).
+
+2001-11-02 Friday 08:48 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/tlsComm.c: Small debugging message to help if a connection
+	ends unexpectedly.
+
+2001-10-29 Monday 13:57 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, NEWS: Released WMBiff 0.3.3.
+
+2001-10-29 Monday 13:54 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* wmbiff/: Imap4Client.c, wmbiff.c: Indent run.
+
+2001-10-28 Sunday 23:32 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, NEWS, README, wmbiff/Makefile, wmbiff/sample.wmbiffrc:
+	Preparation for 0.3.3.	Documentation updates.
+
+2001-10-28 Sunday 22:22 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/wmbiff.c: Bugfix: initialize libgcrypt properly before
+	cram-md5 (or probably apop) authentication.
+
+2001-10-24 Wednesday 15:35 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* maint/changelog.sed: Added Neil to the sed script.
+
+2001-10-23 Tuesday 21:14 UTC -- Neil Spring <nspring at cs.washington.edu>
+
+	* wmbiff/Imap4Client.c: error check just in case sighup patch is
+	applied
+
+2001-10-23 Tuesday 18:35 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, NEWS: Released WMBiff 0.3.2.
+
+2001-10-23 Tuesday 18:33 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* wmbiff/Makefile: Bump WMBIFF_VERSION to 0.3.2.
+
+2001-10-05 Friday 16:10 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* wmbiff/Makefile: Changed order of additions to LIBS and
+	EXTRAFLAGS, removed extra WMBIFF_VERSION definition.
+
+2001-10-04 Thursday 09:50 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* NEWS, README, TODO, wmbiff/Client.h, wmbiff/Imap4Client.c,
+	wmbiff/LicqClient.c, wmbiff/Makefile, wmbiff/Pop3Client.c,
+	wmbiff/charutil.c, wmbiff/charutil.h, wmbiff/maildirClient.c,
+	wmbiff/mboxClient.c, wmbiff/socket.c, wmbiff/tlsComm.c,
+	wmbiff/tlsComm.h, wmbiff/wmbiff.1, wmbiff/wmbiff.c,
+	wmbiff/wmbiffrc.5: * Big patch from Neil Spring which adds lots of
+	crypto support to WMBiff.  * WMBiff can now speak IMAP over TLS and
+	CRAM-MD5, and APOP using libgcrypt.  * Known problems:	 - gnutls
+	is being developed still, so it may have security related bugs.   
+	- A bug in gnutls (a too-small buffer) may cause problems      in
+	the parsing of openssl certificates. This should be fixed by gnutls
+	     soon, hopefully. Added error messages if this bug is tickled.
+	If you've      got problems with IMAP SSL, please try upgrading
+	gnutls. If the problem	    persists, let us know.    - IMAP has
+	totally been rewritten, so bugs may crop up.	- Pop3 hasn't been
+	rewritten to use the TLS primitives, though it probably      could
+	be if someone wanted to.  * There's a new interface for reading and
+	writing to the socket in   tlsComm.[ch].  This makes the IMAP code
+	somewhat independent of whether   ssl is used, and provides nicer
+	primitives to help skip 'informational'   messages.  * WITH_TLS and
+	WITH_GCRYPT are on-by-default in the Makefile.	TLS   applies to
+	encryption, GCRYPT to cram-md5 and apop authentication.    Since
+	gnutls depends on libgcrypt anyway, these probably don't need to be
+	   independent.  Some compile warnings may be generated when these
+	are    disabled.  * Added code to optionally include dmalloc.h and
+	link -ldmalloc. This   doesn't do anything at the moment, but
+	shouldn't hurt. It's off-by-default.  * IMAP connections are now
+	persistent.  persistent.  This is to cut down on   the need to
+	re-negotiate an SSL connection every time you want to check   mail.
+	It tries to use just one connection per
+	(server/username/password/port	 number), which means multiple
+	mailboxes need only one connection.  * There are a handful of
+	lclint (http://lclint.cs.virginia.edu) annotations   in
+	tlsComm.[ch]. These should also not hurt anyone, and are meant to
+	keep   the signal to noise ratio of lclint high.  * The rewritten
+	IMAP code uses the GNU regex library to handle the   configuration
+	line.  I think its clearer than the cascading strtok()	 solution,
+	but the regex might not be perfect.  * Removed an unnecessary
+	"inline" keyword from charutil.h.  * Added a TODO document with the
+	bits that are missing from the picture.  * Please bow in awe at
+	NAKAYAMA Takao, Jay T. Francis and specially   Neil Spring for all
+	of this.
+
+2001-10-04 Thursday 09:21 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* wmbiff/ApopClient.c: Removed unneeded Apop support code, now
+	integrated in Neil and Jay's patch.
+
+2001-10-04 Thursday 09:00 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* maint/changelog.sed: Added my other SF account, which I intend to
+	use now.
+
+2001-10-04 Thursday 08:54 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, NEWS, README, wmbiff/Client.h, wmbiff/Makefile,
+	wmbiff/sample.wmbiffrc, wmbiff/wmbiff.1, wmbiff/wmbiff.c,
+	wmbiff/wmbiffrc.5: Backed out hoehoe's patch, preparing to apply
+	Neil's.
+
+2001-09-24 Monday 11:58 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, NEWS, README, wmbiff/ApopClient.c, wmbiff/Client.h,
+	wmbiff/Makefile, wmbiff/sample.wmbiffrc, wmbiff/wmbiff.1,
+	wmbiff/wmbiff.c, wmbiff/wmbiffrc.5: Added APOP support, patch from
+	NAKAYAMA Takao <hoehoe at wakaba.jp>.  Fixed some bits of the manpage
+	(Jordi) Bumped version to 0.3.2.
+
+2001-09-24 Monday 11:56 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* maint/prerelease.sh: Removed -t to cvs2cl invocation, to make
+	cleaner ChangeLogs.
+
+2001-06-24 Sunday 18:17 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, NEWS: Released wmbiff 0.3.1.
+
+2001-06-24 Sunday 18:08 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, README: Removed duplicate entry for Vladimir Popov in
+	README.
+
+2001-06-23 Saturday 00:09 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* wmbiff/Imap4Client.c: Imap fix from Rob Funk
+
+2001-06-23 Saturday 00:07 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, NEWS, maint/changelog.sed, maint/prerelease.sh:
+	Renamed CHANGES to ChangeLog and RELEASE-NOTES to NEWS, modified
+	release scripts accordingly. Added Mark to the sed file.
+
+2001-06-22 Friday 23:55 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* CHANGES, RELEASE-NOTES: Renamed to NEWS and ChangeLog
+
+2001-06-19 Tuesday 03:52 UTC -- Dwayne C. Litzenberger <dlitz at dlitz.net>
+
+	* CHANGES, maint/prerelease.sh: * Whoops!  Messed up CVS expansion
+	in maint/prerelease.sh.  Fixed it.  * Also changed
+	maint/prerelease.sh a bit.
+
+2001-06-19 Tuesday 03:38 UTC -- Dwayne C. Litzenberger <dlitz at dlitz.net>
+
+	* CHANGES, ChangeLog, README, RELEASE-NOTES, maint/changelog.sed,
+	maint/prerelease.sh, wmbiff/Client.h, wmbiff/Imap4Client.c,
+	wmbiff/LicqClient.c, wmbiff/Makefile, wmbiff/Pop3Client.c,
+	wmbiff/charutil.c, wmbiff/charutil.h, wmbiff/maildirClient.c,
+	wmbiff/mboxClient.c, wmbiff/sample.wmbiffrc, wmbiff/socket.c,
+	wmbiff/wmbiff.1, wmbiff/wmbiff.c, wmbiff/wmbiffrc.5: * Another big
+	patch that mucks with everything.  I probably deserve to be  
+	flamed for this practice.  Feel free... :-) * Added
+	maint/prerelease.sh script.  Run it before making any releases.  *
+	Added maint/changelog.sed.  Add your SourceForge userid here.  *
+	Moved ChangeLog to RELEASE-NOTES (see below).  * Added a new file,
+	CHANGES (created by maint/prerelease.sh) that tabulates   all the
+	CVS changes.  * Added "distclean" to wmbiff/Makefile.  * Added CVS
+	Id$ to all the files in wmbiff/ .  * I reformatted ths changelog,
+	again.	I hope this is the last time I need   to do this.  The CVS
+	logs should be used for all changes, and this file   should by
+	updated for user-visible changes only, from now on.    (Dwayne C.
+	Litzenberger)  * Updated the README to reflect that Gennady
+	Belyakov died right after releasing   wmBiff 0.2.  May your soul
+	rest in peace, Gennady.  (Dwayne C. Litzenberger)
+
+2001-06-16 Saturday 01:02 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, wmbiff/Makefile, wmbiff/sample.wmbiffrc,
+	wmbiff/wmbiff.c: An FHS fix for wmbiff.c and use $(CC) in the
+	Makefile
+
+2001-05-17 Thursday 04:22 UTC -- Dwayne C. Litzenberger <dlitz at dlitz.net>
+
+	* ChangeLog, wmbiff/Makefile, wmbiff/charutil.c: Committing Mark
+	Hurley's patch
+
+2001-05-16 Wednesday 10:48 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, README: Updated some obsolete info in README
+
+2001-05-11 Friday 15:04 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, wmbiff/Imap4Client.c, wmbiff/Makefile,
+	wmbiff/charutil.c, wmbiff/charutil.h, wmbiff/wmbiff.c: Mark's
+	wmbiffrc parsing fix, small Makefile changes and bump version to
+	0.3.0.
+
+2001-05-11 Friday 14:49 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* wmbiff/: .cvsignore, Makefile: Uncommitted stuff to deal with the
+	removal of the xmp link
+
+2001-05-04 Friday 11:01 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* ChangeLog, wmbiff/Makefile: Updated Changelog and Makefile for
+	0.2r.
+
+2001-05-01 Tuesday 16:11 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* README.licq, ChangeLog, README, wmgeneral/list.c,
+	wmgeneral/list.h, wmgeneral/misc.c, wmgeneral/misc.h,
+	wmgeneral/wmgeneral.h, wmbiff/socket.c, wmgeneral/wmgeneral.c,
+	wmbiff/Imap4Client.c, wmbiff/Makefile, wmbiff/mboxClient.c,
+	wmbiff/sample.wmbiffrc, wmbiff/wmbiff.1, wmbiff/wmbiff.c,
+	wmbiff/wmbiff-master-led.xpm, wmbiff/.cvsignore, wmbiff/Client.h,
+	wmbiff/LicqClient.c, wmbiff/Pop3Client.c, wmbiff/maildirClient.c,
+	wmbiff/wmbiffrc.5: Initial revision
+
+2001-05-01 Tuesday 16:11 UTC -- Jordi Mallach <jordi at sindominio.net>
+
+	* README.licq, ChangeLog, README, wmgeneral/list.c,
+	wmgeneral/list.h, wmgeneral/misc.c, wmgeneral/misc.h,
+	wmgeneral/wmgeneral.h, wmbiff/socket.c, wmgeneral/wmgeneral.c,
+	wmbiff/Imap4Client.c, wmbiff/Makefile, wmbiff/mboxClient.c,
+	wmbiff/sample.wmbiffrc, wmbiff/wmbiff.1, wmbiff/wmbiff.c,
+	wmbiff/wmbiff-master-led.xpm, wmbiff/.cvsignore, wmbiff/Client.h,
+	wmbiff/LicqClient.c, wmbiff/Pop3Client.c, wmbiff/maildirClient.c,
+	wmbiff/wmbiffrc.5: Initial import to SourceForge, version
+	0.2q1+Debian
 
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..bc2ba56
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,282 @@
+Release Notes
+~~~~~~~~~~~~~
+
+Release 0.3.8 - Tue, 26 Mar 2002 17:17:07 +0100
+
+  * Added GnomeICU support.
+  * Added an experimental shell command method which reads the output
+    for a given command. See wmbiffrc(5) for details.
+  * Debug support moved to runtime, using the -debug switch.
+  * Fix for the install rule in Makefile.
+
+Release 0.3.7 - Sun,  3 Feb 2002 23:46:44 +0100
+
+  * No, 0.3.6 never happened :)
+  * Removed unneeded auth list fix which broke things.
+  * Makefile cleanup, with better FreeBSD support. You can now easily
+    use the external GNU regex lib.
+
+Release 0.3.6 - Sun, 27 Jan 2002 20:49:52 +0100
+
+  * Added a new syntax for IMAP, which allows using a "@" in
+    the password field. See wmbiffrc(5) for details.
+  * Fix for a correct usage of the auth list in IMAP.
+
+Release 0.3.5 - Mon, 14 Jan 2002 02:43:23 +0100
+
+  * Added support for GNUtls 0.3. You can still compile wmbiff using
+    GNUtls 0.2.x by removing the GNUTLS_VER=3 define in the Makefile.
+  * Fixed password quoting in IMAP logins.
+
+Release 0.3.4 - Fri, 23 Nov 2001 16:56:29 +0100
+
+  * "imaps" is now prefered to "sslimap" in config files. The old type
+    is still supported for backwards compatibility.
+  * You can now specify what protocol wmbiff should use for a given Pop3
+    or IMAP mailbox. If unspecified, it will try the secure ones first,
+    falling back to unsecure if they fail. See wmbiffrc(5).
+  * Added some debug messages for tls connections.
+  * Pop3 path parsing rewrite.
+  * Manual page fixes.
+  * Compile warning fixes.
+
+Release 0.3.3 - Mon, 29 Oct 2001 14:55:00 +0100
+
+  * Sanity check to IMAP code: exit if wmbiff tries to connect to more
+    than 5 servers.
+  * Fix a missbehaviour of cram-md5 (broke pop3).
+  * Documentation updates.
+
+Release 0.3.2 - Tue, 23 Oct 2001 20:30:37 +0200
+
+  * After some tries (other OpenSSL based patches, independent APOP
+    & CRAM-Md5 patches) we've come up with something based on GNUtls and
+    gcrypt, which are GPL based and have no licensing issues for us.
+    See ChangeLog for details.
+  * WMBiff now supports IMAP-SSL, APOP and CRAM-Md5 authentication. These
+    can be disabled at compile time, commenting out the WITH_TLS and
+    WITH_GCRYPT defines. (Neil Spring, NAKAYAMA Takao and Jay T. Francis).
+
+Release 0.3.1 - Sun, 24 Jun 2001 20:15:41 +0200
+
+  * Replaced /var/spool/mail with /var/mail, which is what the FHS mandates.
+    All decent systems should have either the directory or a symlink pointing
+    somewhere else. (Jordi Mallach)
+  * I reformatted ths changelog, again.  I hope this is the last time I need
+    to do this.  The CVS logs should be used for all changes, and this file
+    should by updated for user-visible changes only, from now on.
+    (Dwayne C. Litzenberger)
+  * Updated the README to reflect that Gennady Belyakov died right after
+    releasing wmBiff 0.2.  May your soul rest in peace, Gennady.
+    (Dwayne C. Litzenberger)
+  * Fixed the IMAP support, again. (Rob Funk)
+
+
+Release 0.3.0 - Fri, 16 May 2001 12:16:44 +0200
+
+  * [ReadLine] removed previous trim leading spaces, added TrimFull.  Fixes
+    Debian Bug #95849 (Mark Hurley).
+  * There was a bug where if a POP3 or IMAP mailbox read failed and the
+    following reads were successful, but no mail was in the server, the given
+    mailbox would remain reading "XX". Now it updates the counter no matter
+    what the read was (Mark Hurley).
+  * wmBiff would only count as new mails in mbox mailboxes with "N" flags,
+    ignoring those marked "ON" (Rob Funk).
+  * Fixed reading of quoted imap folders, which some IMAPd's do (Rob Funk).
+  * README: updated some very obsolete info. (Jordi Mallach)
+
+
+Release 0.2q1+Debian - Tue,  1 May 2001 10:11:00 +0000
+
+  * Moved to CVS at SourceForge. (Jordi Mallach)
+
+
+Release 0.2q1 - Fri, 13 Apr 2001 02:47:10 -0400
+
+  * This release is by Mark Hurley <debian4tux at telocity.com>.
+  * wmbiff/Client.h: move DEBUG_* macros to wmbiff/Makefile
+  * wmbiff/Pop3Client.c:
+    + My password contains an  @  character.  This causes
+      the pop3 line to be incorrectly parsed by wmbiff.
+      * Drop all of the ":" after the pop3 and delimit all values with
+        spaces.  This works well, as passwords/user-id's all agree that
+        the space is a non-legit value.
+         
+        Example: assume my password is:  myEmailhasa at init
+         
+        Old way:
+        path.3=pop3:debian4tux:myEmailhasa at init@mail.telocity.com
+
+        New way:
+        path.3=pop3:debian4tux myEmailhasa at init mail.telcoity.com
+        
+        Ahh...before you say it.  "Backward compatibility?" You will
+        also find in the patch, a NEW function.  So that the OLD and
+        NEW way is easily compatible with all ".wmbiffrc" files.
+        
+        Dev. Comments:
+        This was not the cleanest way to implement it, but I had to
+        suffice with a clean/quick implementation.  I originally wrote
+        one function to handle past and new parsing.  However, I
+        thought it would be beneficial to leave them separated, so we
+        could eventually drop the old method?
+        
+        Related Changes:
+        The man page will need to be updated (not provided in patch).
+        We can weed the "old" style out of the example script as well.
+        Still explaining the changes in the man page to leave out
+        confusion in a users mind (as they are likely to find "old"
+        style scripts).
+    + My mail server at Telocity.com is following the RFC's to
+      a "T".  RFC 1725 states that the LAST command be removed.
+      After some searching I have NOT turned up a replacement.
+      Which does make sense, this command is only so useful,
+      and contributes to the popularity of other such remoting
+      such as LDAP?
+      * I've set the Unread messages to the TotalMessages,
+        assuming (as suggested by the RFC) no messages have been
+        read.  I have also suppressed the error printed to
+        stderr, it is correct to return an error, *now*.  ;)
+
+        The only way to keep track of messages which have been
+        read, is to remember the unique number assigned to them.
+        This is what fetchmail does.  However, it does not work
+        correctly if you check and read mail thru other methods
+        (a web mail client).
+  * wmbiff/wmbiff.c:
+        -       for (index = 0; index < 4; index++)
+        +       for (index = 0; index < 5; index++)
+    
+        BUG!  Last postion #4 was not correctly being checked.
+        Now correctly checks each position.
+
+
+Release 0.2q - Tue, 20 Mar 2001 05:32:35 +0100
+
+  * This release is by Jorge Garc�a <Jorge.Garcia at uv.es>.
+  * wmbiff/{*.[ch]}: removed unnecesary includes.
+  * wmbiff/wmbiff.c: some cleanups and optimizations. 
+    + init_biff:
+      * show error if user config file does not exists
+      * use of userconfig "interval" (wasn't correctly parsed)
+    + {do_biff, displayMsgCounters}: some changes to make Sleep_Interval
+      and Blink_Mode local
+    + parse_cmd: some changes to make uconfig_file local
+    + {BlinkOn, BlinkOff, BlinkToogle}: Removed (merged by do_biff)
+    + {ReadConfigString, ReadConfigInt}: Removed 
+    + countmail: removed init in header (wasn't used)
+    + ReadLine: Created (new parsing code, extracts pairs of setting
+      and value)
+    + Read_Config_File: now there is only ONE parse not 36!
+  * wmbiff/{IMap4Client.c, Pop3Client.c}: check for correct format line to 
+    avoid "segmentation fault" while parsing.
+
+
+Release 0.2p - Mon, 12 Mar 2001 00:00:00 -0600
+
+  * This release is by Dwayne C. Litzenberger <dlitz at dlitz.net>.
+  * Added maildir support!  Yay!
+  * Stole the manpages from Debian.
+  * Massive (lack of) coding style cleanup; Standardized coding style using
+    GNU indent.
+  * Reversed order of ChangeLog as suggested by Jordi.
+  * Cleaned up the v0.2o ChangeLog entry.  What a mess!  Added missing credits.
+  * Cleaned up and reformatted the rest of the changelog to an almost-Debian
+    format while I'm at it.  It's much more readable that way.
+  * Moved definition of WMBIFF_VERSION to the Makefile.
+  * All your base are belong to us.
+  * I'm not maintaining wmBiff; I just submitted a big patch.  Send your
+    complaints (or complements) to Yong-iL Joh.
+  
+
+Release 0.2o - Mon, 12 Mar 2001 00:00:00 +0900
+
+  * This release is by Yong-iL Joh <tolkien at mizi.com>.
+  * I don't think the date of this changelog entry is right.
+    (Dwayne C. Litzenberger)
+  * Jordi Mallach <jordi at sindominio.net>, Debian's wmbiff maintainer, sent
+    me an email a couple of days ago which included a patch with man pages.
+    The patch did the following:
+      + Fixed a major upstream bug that renders this new wmbiff unusable.
+        Thanks to Guillaume Morin, J�r�me Marant and Mark Hurley for their
+        help identifying the bug, and Jorge Garc�a <Jorge.Garcia at uv.es> for
+        writing a patch. Basically, the new upstream broke backwards
+        compatibility of wmbiffrc with Gennady's wmbiff, fixed that.
+        This patch also fixes wmbiff not using $MAIL or defaulting to
+        /var/spool/mail/$USER if no ~/.wmbiffrc is found (closes: #87778).
+      + wmbiff/wmbiff.c: updated WMBIFF_VERSION to current.
+      + wmbiff/{socket.c, wmbiff.c}: removed <sys/time.h> includes.
+      + debian/{wmbiff.1, wmbiffrc.5}: updated for IMAP4 and Licq support.
+      + Jorge Garc�a removed the segfault in Jordi's wmbiffrc
+      + Vladimir Popov <pva48 at mail.ru> fixed a potential buffer overflow
+        in init_biff() (The "/* Make labels look right */" section).
+      + Jorge Garc�a <Jorge.Garcia at uv.es> fixed a display bug in the
+        number-of- mails display.
+  * use poll() instead of select()
+
+ -- Yong-iL Joh <tolkien at mizi.com>  12-Mar-2001 +0900
+
+
+Release 0.2n - Tue, 20 Feb 2001 0:00:00 +0900
+  
+  * This release is by Yong-iL Joh <tolkien at mizi.com>.
+  * Nick Clarey <nclarey at 3glab.com> sent me a patch.
+    that enhances the following:
+      + UW Imap server 2000.283rh
+      + Config file now supports IMAP mailbox "paths" rather than
+        just the mailbox name (e.g. mail/foo/blah)
+
+
+Release 0.2m - Mon,  5 Feb 2001 00:00:00 +0900
+
+  * This release is by Yong-iL Joh <tolkien at mizi.com>.
+  * Imap4Client.c did not close when a connection error occurred.  Fixed it.
+
+
+Release 0.2l - Thu, 11 Jan 2001 00:00:00 +0900
+  
+  * This release is by Yong-iL Joh <tolkien at mizi.com>.
+  * Imap4Client.c had a bug when trying to connect to an imap4 server.  Fixed
+    it.
+
+
+Release 0.2j - Mon,  1 Jan 2001 00:00:00 +0900
+
+  * This release is by Yong-iL Joh <tolkien at mizi.com>.
+  * Because I can't contact the author, I jumped to version 0.2j
+  * Added imap4-based mail server check component.
+  * Divided wmbiff.c to wmbiff.c, LicqClient.c mboxClient.c
+
+
+Release 0.2-licq - Sat,  1 Jan 2000 00:00:00 +0000
+
+  * This release is by Yong-iL Joh <tolkien at mizi.com>.
+  * The actual date of this release is unknown, so I picked New Year's Day,
+    Y2K. (Dwayne C. Litzenberger)
+  * I found it from http://www.licq.org/download.html.
+  
+
+Release 0.2 - Fri, 26 Nov 1999 00:00:00 +0000 
+  
+  * This release is by Gennady Belyakov <gb at ccat.elect.ru>.
+  * We don't actually know the time zone of Gennady's changelog entries
+    (Dwayne C. Litzenberger).
+  * POP3 support added with (auto)fetching
+  * digits blinking on new mail arrival
+  * resource wasting lowered
+  * individual rescan interval for differrent mailboxes
+  * some bugfixes
+
+
+Release 0.1a - Thu, 18 Nov 1999 00:00:00 +0000
+  
+  * This release is by Gennady Belyakov <gb at ccat.elect.ru>.
+  * Some fixes with intialization
+
+
+Release 0.1 - Wed, 17 Nov 1999 00:00:00 +0000
+
+  * Initial release by Gennady Belyakov <gb at ccat.elect.ru>.
+
+
+$Id: NEWS,v 1.16 2002/03/26 16:30:32 jordi Exp $
diff --git a/README b/README
index 54e71a7..c608b3f 100644
--- a/README
+++ b/README
@@ -1,18 +1,22 @@
-   
+
                                   Introducing
                                        
-   wmBiff is an WindowMaker docking utility, that displays number of
+   WMBiff is an WindowMaker docking utility, that displays number of
    total messages count or unread mail messages count in differrent
    mailboxes.
 
+   WMBiff was created by Gennady Belyakov in 1999, and was continued by
+   a team of volunteers after his death.
+
    Green ( cyan? :) ) digits display total number of messages, if there
    are no unread messages in it.
    
    Yellow digits display number of unread messages, with blinking on new
    mail arrival, if any.
    
-   At this moment only unix-style and POP3 mailboxes are supported.
-   wmBiff supports up to 5 mailboxes (but you can start 2 or more
+   At this moment unix-style (mbox), maildir, POP3, APOP and IMAP mailboxes
+   are supported. WMBiff also understands Licq's history files.
+   WMBiff supports up to 5 mailboxes (but you can start 2 or more
    wmbiff's with differrent configs).
    
    Pressing on a 1st (left) mouse button will execute appropriate mail
@@ -27,12 +31,20 @@
                           Compiling and Installation
                                        
 Extract the archive:
-        tar -xvzf wmbiff-0.2.tar.gz
+        tar -xvzf wmbiff-0.x.tar.gz
 
 Enter the wmbiff directory and edit the Makefile:
-        cd wmbiff-0.2/
+        cd wmbiff-0.x/
         vi Makefile
 
+For crypto support either:
+*) Install gnutls and libgrcypt packages from your distribution.
+*) Download them from http://www.gnupg.org/mirrors.html.
+Choose a mirror, then download from the alpha/gnutls and
+alpha/libgcrypt directories.
+*) Disable crypt by uncommenting the "WITHOUT_CRYPTO" line
+in the Makefile.
+
 Make the binary:
         make
 
@@ -68,14 +80,64 @@ position. All other positions will be empty.
    
    Many thanks for:
    Angus Mackay (amackay at gusnet.cx)
-   Jordi Mallach Perez (jordi at sindominio.net)
+   Jordi Mallach P�rez (jordi at sindominio.net)
    Eugene Bobin (gene at utb.ru)
    Helmut 'Kolbi' Kolb (office at kolbi.net)
    Vladimir Popov (pva48 at mail.ru)
-   
+   Jorge Garc�a (Jorge.Garcia at uv.es)
+   Nick Clarey (nclarey at 3glab.com)
+   Dwayne C. Litzenberger (dlitz at dlitz.net)
+   Mark Hurley (debian4tux at telocity.com)
+   Rob Funk (rfunk at funkinet.net)
+   Neil Spring (nspring at cs.washington.edu)
+   NAKAYAMA Takao (hoehoe at wakaba.jp)
+   Jay T Francis (jtf at u880.org)
+   David Smith (davidsmith at acm.org)
+   Beno�t Rouits (brouits at free.fr)
+
      _________________________________________________________________
    
-   Any suggestions/bug reports please send to
-   
-    Gennady Belyakov gb at ccat.elect.ru
+   Any suggestions/bug reports please send to our mailing list,
+ 
+    wmbiff-devel at lists.sourceforge.net
+
+     _________________________________________________________________
+
+UPDATE [2001-06-18]:
+
+On Tuesday, 22 May 2001, Jordi Mallach sent the following email to the
+wmbiff-devel list:
+
+    Hello,
+    I just found evidence of what I had believed for a long time.
+    
+    http://www.monkey.org/openbsd/archive/ports/0101/msg00311.html
+    
+    Gennady Belyakov passed away right after releasing 0.2 and when he
+    stopped answering mail :|
+    
+    I guess we need to update the docs.
+    
+    Jordi
+
+Here is the message, if that URL becomes unavailable:
+
+    To: ports at openbsd.org 
+    Subject: Re: mail/wmbiff update 
+    From: Vladimir Popov <pva48 at mail.ru> 
+    Date: Sat, 27 Jan 2001 09:34:15 +0500 
+    
+    On Fri, Jan 26, 2001 at 01:02:59PM +0000, Christian Weisgerber wrote:
+    > 
+    > The major issue I have with this port is that the master site/home
+    > page is unreachable.
+    > 
+    
+    Well, wmbiff's author Gennady Belyakov passed away in late November 1999.
+    That's why that url isn't any longer valid.
+    
+    --
+    Vladimir
+
+May your soul rest in peace, Gennady.
 
diff --git a/README.licq b/README.licq
new file mode 100644
index 0000000..d668e32
--- /dev/null
+++ b/README.licq
@@ -0,0 +1,23 @@
+wmBiff with ICQ arrival notification
+------------------------------------
+
+This is a version of Gennady Belyakov's wmBiff Window Maker doc app hacked
+to show licq message arrivals.
+
+Motivation:
+Ever found the screen space taken up by licq clients to be too much, but
+don't like to have them beeping when messages are arrived, so you can't put
+them in the background? So did I.
+
+Solution:
+wmBiff with ICQ arrival notification.
+Works alongside licq <http://www.licq.com>, and displays the number of messages
+sitting in a licq history file. When a message arrives, this file is updated,
+so wmBiff flashes and (optionally, if you like that sort of thing) makes noises.
+And, it checks regular mailboxes and pop3 servers for mail!
+
+What more could you wish?
+
+Simply add entries in the .wmbiffrc file with licq: prefixing the path.
+
+Enjoy!
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..db54c8d
--- /dev/null
+++ b/TODO
@@ -0,0 +1,15 @@
+- Store and verify server certificates.
+- Prompt for passwords (in progress)
+- Add a FAQ (sighup, app size, deleted messages)
+- Make the shell method support old messages too
+- Add more shell "recipes" besides gicu.
+- Support "skins" or soft-configurable xpms for,
+   for example, 8bpp displays or non 64x64 appsizes.
+- Support on/off status LED's, for, for example,
+   grep eth0 /proc/net/dev | wc -l
+- Add a failure-expect case in tlsComm. For example,
+   an IMAP status query has a good response (* STATUS) 
+   and a bad response (a003 NO STATUS).  As soon as 
+   one of them is received, we're done.
+
+$Id: TODO,v 1.4 2002/03/18 21:13:55 bluehal Exp $
diff --git a/wmbiff/Client.h b/wmbiff/Client.h
new file mode 100644
index 0000000..231f7e2
--- /dev/null
+++ b/wmbiff/Client.h
@@ -0,0 +1,125 @@
+/* $Id: Client.h,v 1.12 2002/03/12 23:53:15 bluehal Exp $ */
+/* Author : Scott Holden ( scotth at thezone.net )
+   Modified : Yong-iL Joh ( tolkien at mizi.com )
+   Modified : Jorge Garc�a ( Jorge.Garcia at uv.es )
+ *
+ * Email Checker Pop3/Imap4/Licq/Gicu/mbox/maildir
+ *
+ * Last Updated : Mar 20, 05:32:35 CET 2001     
+ *
+ */
+
+#ifndef CLIENT
+#define CLIENT
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+#ifdef WITH_GCRYPT
+#include <gcrypt.h>
+#endif
+
+typedef struct _mbox_t *Pop3;
+typedef struct _mbox_t {
+	char label[32];				/* Printed at left; max 5 chars */
+	char path[256];				/* Path to mailbox */
+	char notify[256];			/* Program to notify mail arrivation */
+	char action[256];			/* Action to execute on mouse click */
+	char fetchcmd[256];			/* Action for mail fetching for pop3/imap */
+	int fetchinterval;
+	int TotalMsgs;				/* Total messages in mailbox */
+	int UnreadMsgs;				/* New (unread) messages in mailbox */
+	int OldMsgs;
+	int OldUnreadMsgs;
+	int blink_stat;				/* blink digits flag-counter */
+	int debug;					/* debugging status */
+
+	union {
+		struct {
+			time_t ctime;
+			time_t mtime;
+			off_t size;
+		} mbox;
+		struct {
+			time_t ctime_new;
+			time_t mtime_new;
+			off_t size_new;
+			time_t ctime_cur;
+			time_t mtime_cur;
+			off_t size_cur;
+		} maildir;
+		struct {
+			char password[32];
+			char userName[32];
+			char serverName[256];
+			int serverPort;
+			int localPort;
+			char authList[100];
+		} pop;
+		struct {
+			char password[32];
+			char userName[32];
+			char serverName[256];
+			int serverPort;
+			int localPort;
+			char authList[100];
+			unsigned int dossl:1;
+		} imap;
+	} u;
+
+	FILE *(*open) (Pop3);
+	int (*checkMail) (Pop3);
+
+	time_t prevtime;
+	time_t prevfetch_time;
+	int loopinterval;			/* loop interval for this mailbox */
+} mbox_t;
+
+#define BUF_SIZE 1024
+
+int sock_connect(const char *hostname, int port);
+int pop3Create(Pop3 pc, const char *str);
+int imap4Create(Pop3 pc, const char *str);
+int licqCreate(Pop3 pc, char *str);
+int shellCreate(Pop3 pc, const char *str);
+int mboxCreate(Pop3 pc, char *str);
+int maildirCreate(Pop3 pc, char *str);
+FILE *openMailbox(Pop3 pc);
+
+/* _NONE is for silent operation.  _ERROR is for things that should
+   be printed assuming that the user might possibly see them. _INFO is
+   for reasonably useless but possibly interesting messages. _ALL is
+   for everything.  Restated, _ERROR will always be printed, _INFO only
+   if debugging messages were requested. */
+#define DEBUG_NONE  0
+#define DEBUG_ERROR 1
+#define DEBUG_INFO  2
+#define DEBUG_ALL   2
+/* inspired by ksymoops-2.3.4/ksymoops.h */
+#define DM(mbox, msglevel, X...) \
+do { \
+  if (mbox == NULL || (mbox)->debug >= msglevel) { \
+     printf("wmbiff: " X); \
+(void)fflush(NULL); \
+  } \
+} while(0)
+
+extern int debug_default;
+#define DMA(msglevel, X...) \
+do { \
+  if (debug_default >= msglevel) { \
+     printf("wmbiff: " X); \
+(void)fflush(NULL); \
+  } \
+} while(0)
+
+/* technique used in apache to allow GCC's attribute tags,
+   without requiring gcc as the compiler */
+#if !defined(__GNUC__) || __GNUC__ < 2 || \
+  (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+#define __attribute__(__x)
+#endif							/* gnuc */
+#endif							/* client.h */
+/* vim:set ts=4: */
diff --git a/wmbiff/Imap4Client.c b/wmbiff/Imap4Client.c
new file mode 100644
index 0000000..4052d00
--- /dev/null
+++ b/wmbiff/Imap4Client.c
@@ -0,0 +1,454 @@
+/* rewrite of the IMAP code by Neil Spring
+ * (nspring at cs.washington.edu) to support gnutls and
+ * persistent connections to servers.  */
+
+/* Originally written by Yong-iL Joh (tolkien at mizi.com),
+ * modified by Jorge Garcia (Jorge.Garcia at uv.es), and
+ * modified by Jay Francis (jtf at u880.org) to support
+ * CRAM-MD5 */
+
+/* get asprintf */
+#define _GNU_SOURCE
+
+#include "Client.h"
+#include "charutil.h"
+#include "tlsComm.h"
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <assert.h>
+#include <unistd.h>
+#include <errno.h>
+
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#define	PCU	(pc->u).imap
+
+#ifdef __LCLINT__
+void asprintf( /*@out@ */ char **out, char *fmt, ...);
+#endif
+
+#define IMAP_DM(pc, lvl, args...) DM(pc, lvl, "imap4: " args)
+
+/* this array maps server:port pairs to file descriptors, so
+   that when more than one mailbox is queried from a server,
+   we only use one socket.  It's limited in size by the
+   number of different mailboxes displayed. */
+#define FDMAP_SIZE 5
+static struct fdmap_struct {
+	char *user_password_server_port;	/* tuple, in string form */
+	/*@owned@ */ struct connection_state *cs;
+} fdmap[FDMAP_SIZE];
+
+
+/* authentication callbacks */
+#ifdef WITH_GCRYPT
+static int authenticate_md5(Pop3 pc, struct connection_state *scs,
+							const char *capabilities);
+#endif
+static int authenticate_plaintext(Pop3 pc, struct connection_state *scs,
+								  const char *capabilities);
+
+/* the auth_methods array maps authentication identifiers
+   to the callback that will attempt to authenticate */
+static struct imap_authentication_method {
+	const char *name;
+	/* callback returns 1 if successful, 0 if failed */
+	int (*auth_callback) (Pop3 pc, struct connection_state * scs,
+						  const char *capabilities);
+} auth_methods[] = {
+	{
+#ifdef WITH_GCRYPT
+	"cram-md5", authenticate_md5}, {
+#endif
+	"plaintext", authenticate_plaintext}, {
+	NULL, NULL}
+};
+
+
+/* recover a socket from the connection cache */
+/*@null@*//*@dependent@ */
+static struct connection_state *state_for_pcu(Pop3 pc)
+{
+	char *connection_id;
+	struct connection_state *retval = NULL;
+	int i;
+	asprintf(&connection_id, "%s|%s|%s|%d", PCU.userName,
+			 PCU.password, PCU.serverName, PCU.serverPort);
+	for (i = 0; i < FDMAP_SIZE; i++)
+		if (fdmap[i].user_password_server_port != NULL &&
+			(strcmp(connection_id,
+					fdmap[i].user_password_server_port) == 0)) {
+			retval = fdmap[i].cs;
+		}
+	free(connection_id);
+	return (retval);
+}
+
+/* bind to the connection cache */
+static void bind_state_to_pcu(Pop3 pc,
+							  /*@owned@ */ struct connection_state *scs)
+{
+	char *connection_id;
+	int i;
+	if (scs == NULL) {
+		abort();
+	}
+	asprintf(&connection_id, "%s|%s|%s|%d", PCU.userName,
+			 PCU.password, PCU.serverName, PCU.serverPort);
+	for (i = 0; i < FDMAP_SIZE && fdmap[i].cs != NULL; i++);
+	if (i == FDMAP_SIZE) {
+		/* should never happen */
+		IMAP_DM(pc, DEBUG_ERROR,
+				"Tried to open too many IMAP connections. Sorry!\n");
+		exit(EXIT_FAILURE);
+	}
+	fdmap[i].user_password_server_port = connection_id;
+	fdmap[i].cs = scs;
+}
+
+/* remove from the connection cache */
+static
+/*@owned@*//*@null@ */
+struct connection_state *unbind( /*@returned@ */ struct connection_state
+								*scs)
+{
+	int i;
+	struct connection_state *retval = NULL;
+	assert(scs != NULL);
+
+	for (i = 0; i < FDMAP_SIZE && fdmap[i].cs != scs; i++);
+	if (i < FDMAP_SIZE) {
+		free(fdmap[i].user_password_server_port);
+		retval = fdmap[i].cs;
+		fdmap[i].cs = NULL;
+	}
+	return (retval);
+}
+
+/* creates a connection to the server, if a matching one doesn't exist. */
+/* *always* returns null, just declared this wasy to match other protocols. */
+/*@null@*/
+FILE *imap_open(Pop3 pc)
+{
+	struct connection_state *scs;
+	struct imap_authentication_method *a;
+	char *connection_name;
+	int sd;
+	char capabilities[BUF_SIZE];
+	char buf[BUF_SIZE];
+
+
+	if (state_for_pcu(pc) != NULL) {
+		/* don't need to open. */
+		return NULL;
+	}
+
+	/* got this far; we're going to create a connection_state 
+	   structure, although it might be a blacklist entry */
+	asprintf(&connection_name, "%s:%d", PCU.serverName, PCU.serverPort);
+
+	assert(pc != NULL);
+
+	/* no cached connection */
+	sd = sock_connect((const char *) PCU.serverName, PCU.serverPort);
+	if (sd == -1) {
+		IMAP_DM(pc, DEBUG_ERROR, "Couldn't connect to %s:%d: %s\n",
+				PCU.serverName, PCU.serverPort, strerror(errno));
+		if (errno == ETIMEDOUT) {
+			/* only give up if it was a time-consuming error */
+			/* try again later if it was just a connection refused */
+			IMAP_DM(pc, DEBUG_ERROR,
+					"Will not retry because this attempt to connect timed out.\n"
+					" This is done so that other mailboxes can be updated in a timely manner.\n"
+					" To try again to connect to %s:%d, restart wmbiff.\n",
+					PCU.serverName, PCU.serverPort);
+			bind_state_to_pcu(pc, initialize_blacklist(connection_name));
+		}
+		return NULL;
+	}
+
+	/* build the connection using STARTTLS */
+	if (PCU.dossl && (PCU.serverPort == 143)) {
+		/* setup an unencrypted binding long enough to invoke STARTTLS */
+		scs = initialize_unencrypted(sd, connection_name, pc);
+
+		/* can we? */
+		tlscomm_printf(scs, "a000 CAPABILITY\r\n");
+		if (!tlscomm_expect(scs, "* CAPABILITY", capabilities, BUF_SIZE))
+			goto communication_failure;
+
+		if (!strstr(capabilities, "STARTTLS")) {
+			IMAP_DM(pc, DEBUG_ERROR,
+					"server doesn't support ssl imap on port 143.");
+			goto communication_failure;
+		}
+
+		/* we sure can! */
+		IMAP_DM(pc, DEBUG_INFO, "Negotiating TLS within IMAP");
+		tlscomm_printf(scs, "a001 STARTTLS\r\n");
+
+		if (!tlscomm_expect(scs, "a001 ", buf, BUF_SIZE))
+			goto communication_failure;
+
+		if (!strstr(buf, "a001 OK")) {
+			IMAP_DM(pc, DEBUG_ERROR, "couldn't negotiate tls. :(\n");
+			goto communication_failure;
+		}
+
+		/* we don't need the unencrypted state anymore */
+		/* note that communication_failure will close the 
+		   socket and free via tls_close() */
+		free(scs);				/* fall through will scs = initialize_gnutls(sd); */
+	}
+
+	/* either we've negotiated ssl from starttls, or
+	   we're starting an encrypted connection now */
+	if (PCU.dossl) {
+		scs = initialize_gnutls(sd, connection_name, pc);
+		if (scs == NULL) {
+			IMAP_DM(pc, DEBUG_ERROR, "Failed to initialize TLS\n");
+			return NULL;
+		}
+	} else {
+		scs = initialize_unencrypted(sd, connection_name, pc);
+	}
+
+	/* authenticate; first find out how */
+	/* note that capabilities may have changed since last
+	   time we may have asked, if we called STARTTLS, my 
+	   server will allow plain password login within an 
+	   encrypted session. */
+	tlscomm_printf(scs, "a000 CAPABILITY\r\n");
+	if (!tlscomm_expect(scs, "* CAPABILITY", capabilities, BUF_SIZE)) {
+		IMAP_DM(pc, DEBUG_ERROR, "unable to query capability string");
+		goto communication_failure;
+	}
+
+	/* try each authentication method in turn. */
+	for (a = auth_methods; a->name != NULL; a++) {
+		/* was it specified or did the user leave it up to us? */
+		if (PCU.authList[0] == '\0' || strstr(PCU.authList, a->name))
+			/* try the authentication method */
+			if ((a->auth_callback(pc, scs, capabilities)) != 0) {
+				/* store this well setup connection in the cache */
+				bind_state_to_pcu(pc, scs);
+				return NULL;
+			}
+	}
+
+	/* if authentication worked, we won't get here */
+	IMAP_DM(pc, DEBUG_ERROR,
+			"All authentication methods failed for '%s@%s:%d'\n",
+			PCU.userName, PCU.serverName, PCU.serverPort);
+  communication_failure:
+	tlscomm_printf(scs, "a002 LOGOUT\r\n");
+	tlscomm_close(scs);
+	return NULL;
+
+}
+
+int imap_checkmail(Pop3 pc)
+{
+	/* recover connection state from the cache */
+	struct connection_state *scs = state_for_pcu(pc);
+	char buf[BUF_SIZE];
+
+	/* if it's not in the cache, try to open */
+	if (scs == NULL) {
+		(void) pc->open(pc);
+		scs = state_for_pcu(pc);
+	}
+	if (scs == NULL) {
+		return -1;
+	}
+
+	if (tlscomm_is_blacklisted(scs)) {
+		/* unresponsive server, don't bother. */
+		return -1;
+	}
+
+	/* if we've got it by now, try the status query */
+	tlscomm_printf(scs, "a003 STATUS %s (MESSAGES UNSEEN)\r\n", pc->path);
+	if (tlscomm_expect(scs, "* STATUS", buf, 127)) {
+		/* a valid response? */
+		(void) sscanf(buf, "* STATUS %*s (MESSAGES %d UNSEEN %d)",
+					  &(pc->TotalMsgs), &(pc->UnreadMsgs));
+	} else {
+		/* something went wrong. bail. */
+		tlscomm_close(unbind(scs));
+		return -1;
+	}
+	return 0;
+}
+
+/* parse the config line to setup the Pop3 structure */
+int imap4Create(Pop3 pc, const char *const str)
+{
+	struct re_registers regs;
+	int i, matchedchars;
+	const char *regexes[] = {
+		".*imaps?:([^: ]{1,32}):([^@]{1,32})@([^/: ]+)(/[^: ]+)?(:[0-9]+)? *",
+		".*imaps?:([^: ]{1,32}) ([^ ]{1,32}) ([^/: ]+)(/[^: ]+)?( [0-9]+)? *",
+		NULL
+	};
+
+	/* IMAP4 format: imap:user:password at server/mailbox[:port] */
+	/* If 'str' line is badly formatted, wmbiff won't display the mailbox. */
+	if (strncmp("sslimap:", str, 8) == 0 || strncmp("imaps:", str, 6) == 0) {
+#ifdef WITH_TLS
+		static int haveBeenWarned;
+		PCU.dossl = 1;
+		if (!haveBeenWarned) {
+			printf("wmbiff uses gnutls for TLS/SSL encryption support:\n"
+				   "  If you distribute software that uses gnutls, don't forget\n"
+				   "  to warn the users of your software that gnutls is at a\n"
+				   "  testing phase and may be totally insecure.\n"
+				   "\nConsider yourself warned.\n");
+			haveBeenWarned = 1;
+		}
+#else
+		printf("This copy of wmbiff was not compiled with gnutls;\n"
+			   "imaps is unavailable.  Exiting to protect your\n"
+			   "passwords and privacy.\n");
+		exit(EXIT_FAILURE);
+#endif
+	} else
+		PCU.dossl = 0;
+
+	for (matchedchars = 0, i = 0;
+		 regexes[i] != NULL && matchedchars <= 0; i++) {
+		matchedchars = compile_and_match_regex(regexes[i], str, &regs);
+	}
+
+	/* failed to match either regex */
+	if (matchedchars <= 0) {
+		pc->label[0] = '\0';
+		IMAP_DM(pc, DEBUG_ERROR, "Couldn't parse line %s (%d)\n", str,
+				matchedchars);
+		return -1;
+	}
+
+	/* copy matches where they belong */
+	copy_substring(PCU.userName, regs.start[1], regs.end[1], str);
+	copy_substring(PCU.password, regs.start[2], regs.end[2], str);
+	copy_substring(PCU.serverName, regs.start[3], regs.end[3], str);
+	if (regs.start[4] != -1)
+		copy_substring(pc->path, regs.start[4] + 1, regs.end[4], str);
+	else
+		strcpy(pc->path, "INBOX");
+	if (regs.start[5] != -1)
+		PCU.serverPort = atoi(str + regs.start[5] + 1);
+	else
+		PCU.serverPort = (PCU.dossl) ? 993 : 143;
+
+	grab_authList(str + regs.end[0], PCU.authList);
+
+	IMAP_DM(pc, DEBUG_INFO, "userName= '%s'\n", PCU.userName);
+	IMAP_DM(pc, DEBUG_INFO, "password is %d characters long\n",
+			strlen(PCU.password));
+	IMAP_DM(pc, DEBUG_INFO, "serverName= '%s'\n", PCU.serverName);
+	IMAP_DM(pc, DEBUG_INFO, "serverPath= '%s'\n", pc->path);
+	IMAP_DM(pc, DEBUG_INFO, "serverPort= '%d'\n", PCU.serverPort);
+	IMAP_DM(pc, DEBUG_INFO, "authList= '%s'\n", PCU.authList);
+
+	pc->open = imap_open;
+	pc->checkMail = imap_checkmail;
+	pc->TotalMsgs = 0;
+	pc->UnreadMsgs = 0;
+	pc->OldMsgs = -1;
+	pc->OldUnreadMsgs = -1;
+	return 0;
+}
+
+static int authenticate_plaintext(Pop3 pc,
+								  struct connection_state *scs,
+								  const char *capabilities)
+{
+	char buf[BUF_SIZE];
+	/* is login prohibited? */
+	/* "An IMAP client which complies with [rfc2525, section 3.2] 
+	 *  MUST NOT issue the LOGIN command if this capability is present.
+	 */
+	if (strstr(capabilities, "LOGINDISABLED")) {
+		IMAP_DM(pc, DEBUG_ERROR,
+				"Plaintext auth prohibited by server: (LOGINDISABLED).\n");
+		goto plaintext_failed;
+	}
+
+	/* login */
+	tlscomm_printf(scs, "a001 LOGIN %s \"%s\"\r\n", PCU.userName,
+				   PCU.password);
+	if (!tlscomm_expect(scs, "a001 ", buf, BUF_SIZE)) {
+		IMAP_DM(pc, DEBUG_ERROR,
+				"Did not get a response to the LOGIN command.\n");
+		goto plaintext_failed;
+	}
+
+	if (buf[5] != 'O') {
+		IMAP_DM(pc, DEBUG_ERROR, "IMAP Login failed.\n");
+		goto plaintext_failed;
+	}
+	return (1);
+  plaintext_failed:
+	return (0);
+}
+
+#ifdef WITH_GCRYPT
+static int authenticate_md5(Pop3 pc,
+							struct connection_state *scs,
+							const char *capabilities)
+{
+	char buf[BUF_SIZE];
+	char buf2[BUF_SIZE];
+	unsigned char *md5;
+	GCRY_MD_HD gmh;
+
+	if (!strstr(capabilities, "AUTH=CRAM-MD5")) {
+		/* server doesn't support cram-md5. */
+		return 0;
+	}
+
+	tlscomm_printf(scs, "a007 AUTHENTICATE CRAM-MD5\r\n");
+	if (!tlscomm_expect(scs, "+ ", buf, BUF_SIZE))
+		goto expect_failure;
+
+	Decode_Base64(buf + 2, buf2);
+	IMAP_DM(pc, DEBUG_INFO, "CRAM-MD5 challenge: %s\n", buf2);
+
+	strcpy(buf, PCU.userName);
+	strcat(buf, " ");
+	gmh = gcry_md_open(GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
+	gcry_md_setkey(gmh, PCU.password, strlen(PCU.password));
+	gcry_md_write(gmh, (unsigned char *) buf2, strlen(buf2));
+	gcry_md_final(gmh);
+	md5 = gcry_md_read(gmh, 0);
+	Bin2Hex(md5, 16, buf2);
+	gcry_md_close(gmh);
+
+	strcat(buf, buf2);
+	IMAP_DM(pc, DEBUG_INFO, "CRAM-MD5 response: %s\n", buf);
+	Encode_Base64(buf, buf2);
+
+	tlscomm_printf(scs, "%s\r\n", buf2);
+	if (!tlscomm_expect(scs, "a007 ", buf, BUF_SIZE))
+		goto expect_failure;
+
+	if (!strncmp(buf, "a007 OK", 7))
+		return 1;				/* AUTH successful */
+
+	IMAP_DM(pc, DEBUG_ERROR,
+			"CRAM-MD5 AUTH failed for user '%s@%s:%d'\n",
+			PCU.userName, PCU.serverName, PCU.serverPort);
+	IMAP_DM(pc, DEBUG_INFO, "It said %s", buf);
+	return 0;
+
+  expect_failure:
+	IMAP_DM(pc, DEBUG_ERROR,
+			"tlscomm_expect failed during cram-md5 auth: %s", buf);
+	IMAP_DM(pc, DEBUG_ERROR, "failed to authenticate using cram-md5.");
+	return 0;
+}
+#endif
diff --git a/wmbiff/LicqClient.c b/wmbiff/LicqClient.c
new file mode 100644
index 0000000..6aa9c37
--- /dev/null
+++ b/wmbiff/LicqClient.c
@@ -0,0 +1,91 @@
+/* $Id: LicqClient.c,v 1.4 2002/03/01 08:41:29 bluehal Exp $ */
+/* Author : Yong-iL Joh ( tolkien at mizi.com )
+   Modified: Jorge Garc�a ( Jorge.Garcia at uv.es )
+ * 
+ * LICQ checker.
+ *
+ * Last Updated : Mar 20, 05:32:35 CET 2001     
+ *
+ */
+
+#include "Client.h"
+#include <sys/stat.h>
+#include <utime.h>
+#include <errno.h>
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#define PCM     (pc->u).mbox
+
+int licqCheckHistory(Pop3 pc)
+{
+	struct stat st;
+	struct utimbuf ut;
+	FILE *F;
+	int count_status = 0;
+	char buf[1024];
+
+	DM(pc, DEBUG_INFO, ">Mailbox: '%s'\n", pc->path);
+
+	/* licq file */
+	if (stat(pc->path, &st)) {
+		DM(pc, DEBUG_ERROR, "Can't stat mailbox '%s': %s\n",
+		   pc->path, strerror(errno));
+		return -1;				/* Error stating mailbox */
+	}
+
+	if (st.st_mtime != PCM.mtime || st.st_size != PCM.size
+		|| pc->OldMsgs < 0) {
+		/* file was changed OR initially read */
+		DM(pc, DEBUG_INFO,
+		   "  was changed,"
+		   " TIME: old %lu, new %lu"
+		   " SIZE: old %lu, new %lu\n",
+		   PCM.mtime, st.st_mtime, (unsigned long) PCM.size, st.st_size);
+		ut.actime = st.st_atime;
+		ut.modtime = st.st_mtime;
+		F = pc->open(pc);
+
+		/* count message */
+		while (fgets(buf, BUF_SIZE, F)) {
+			if ((buf[0] == '[') || (buf[0] == '-')) {	/* new, or old licq */
+				count_status++;
+			}
+		}
+		pc->TotalMsgs = count_status * 2;
+		pc->UnreadMsgs = pc->TotalMsgs - count_status;
+		DM(pc, DEBUG_INFO, "from: %d status: %d\n", pc->TotalMsgs,
+		   pc->UnreadMsgs);
+
+		fclose(F);
+
+		utime(pc->path, &ut);
+		/* Reset atime for MUTT and something others correctly work */
+		PCM.mtime = st.st_mtime;	/* Store new mtime */
+		PCM.size = st.st_size;	/* Store new size */
+	}
+
+	return 0;
+}
+
+int licqCreate(Pop3 pc, char *str)
+{
+	/* LICQ format: licq:fullpathname */
+
+	pc->TotalMsgs = 0;
+	pc->UnreadMsgs = 0;
+	pc->OldMsgs = -1;
+	pc->OldUnreadMsgs = -1;
+	pc->open = openMailbox;
+	pc->checkMail = licqCheckHistory;
+
+	strcpy(pc->path, str + 5);	/* cut off ``licq:'' */
+
+	DM(pc, DEBUG_INFO, "licq: str = '%s'\n", str);
+	DM(pc, DEBUG_INFO, "licq: path= '%s'\n", pc->path);
+
+	return 0;
+}
+
+/* vim:set ts=4: */
diff --git a/wmbiff/Makefile b/wmbiff/Makefile
index 723e97e..4ef3c27 100644
--- a/wmbiff/Makefile
+++ b/wmbiff/Makefile
@@ -1,30 +1,131 @@
-prefix=
-BIN=/usr/X11R6/bin
-CONF=/etc
-LIBDIR = -L/usr/X11R6/lib
-LIBS   = -lXpm -lXext -lX11
-CFLAGS = -O2 -Wall
-OBJS =	wmbiff.o Pop3Client.o \
+# Makefile for wmbiff
+#
+# $Id: Makefile,v 1.28 2002/03/26 16:30:32 jordi Exp $
+
+# Disable gnutls crypto?
+#WITHOUT_CRYPTO=	1
+
+# Use external GNU regexp lib?
+#EXT_GNU_REGEX_LIB=1
+
+# Use debugging?
+#DEBUG=		1
+
+PREFIX?=	/usr/local
+BINDIR?=	$(PREFIX)/bin
+MANDIR?=	$(PREFIX)/share/man
+
+CC?=		gcc
+LIBDIR?=	-L/usr/X11R6/lib
+LIBS=		-lXpm -lXext -lX11
+CFLAGS?=	-O2 -Wall -Wpointer-arith
+
+###########################################################
+# Nothing below here should need to be changed
+###########################################################
+
+WMBIFF_VERSION=	"0.3.8"
+EXTRAFLAGS=	-DWMBIFF_VERSION='$(WMBIFF_VERSION)' 
+
+# Default linux owners
+INSTALL_USER=	root
+INSTALL_GROUP=	root
+
+# Debugging
+ifdef DEBUG
+CFLAGS=		-g -Wall -Wpointer-arith -Wwrite-strings \
+-W -Wtraditional -Wshadow -Wcast-qual
+#-pedantic  -Wmissing-noreturn
+endif
+
+# FreeBSD overrides
+ifeq ($(OSTYPE),FreeBSD)
+INSTALL_GROUP=	wheel
+EXT_GNU_REGEX_LIB=1
+CFLAGS+=	-I/usr/X11R6/include/
+endif
+
+# External GNU RegExp lib... needed on FreeBSD
+ifdef EXT_GNU_REGEX_LIB
+LIBS+=		-lgnuregex
+CFLAGS+=	-DEXT_GNU_REGEX_LIB
+endif
+
+# Crypto support
+ifndef WITHOUT_CRYPTO
+EXTRAFLAGS+=	-DWITH_TLS -DWITH_GCRYPT
+LIBS+=		-lgnutls -lgcrypt
+endif
+
+INSTALL?=	/usr/bin/install
+INSTALL_DIR?=	$(INSTALL) -d -o $(INSTALL_USER) -g $(INSTALL_GROUP) -m 755
+INSTALL_PRG?=	$(INSTALL) -p -o $(INSTALL_USER) -g $(INSTALL_GROUP) -m 755 -s
+INSTALL_FILE?=	$(INSTALL) -p -o $(INSTALL_USER) -g $(INSTALL_GROUP) -m 644
+
+# For malloc debug :
+#CFLAGS	+= -DUSE_DMALLOC
+#LIBS	+= -ldmalloc
+
+
+###########################################################
+# Real make stuff begins :
+###########################################################
+
+OBJS =	wmbiff.o socket.o \
+	Pop3Client.o LicqClient.o mboxClient.o \
+	maildirClient.o Imap4Client.o tlsComm.o \
+	ShellClient.o \
 	../wmgeneral/wmgeneral.o \
 	../wmgeneral/misc.o \
-	../wmgeneral/list.o
+	../wmgeneral/list.o \
+	charutil.o
+
+all: wmbiff
 
+Imap4Client.o: Imap4Client.c Client.h Makefile
+Pop3Client.o: Pop3Client.c Client.h Makefile
+wmbiff.o: wmbiff-master.xpm wmbiff.c Client.h
 
 .c.o:
-	cc -I/usr/X11R6/share/include $(CFLAGS) -c -Wall $< -o $*.o
+	$(CC) $(CFLAGS) $(EXTRAFLAGS) -c $< -o $*.o
 
-wmbiff: $(OBJS)
-	cc $(CFLAGS) -o wmbiff $^ $(LIBDIR) $(LIBS)
-	strip wmbiff
+wmbiff-master.xpm:
+	ln -s wmbiff-master-led.xpm wmbiff-master.xpm
 
-all:: wmbiff
+wmbiff: $(OBJS)
+	$(CC) $(CFLAGS) $(EXTRAFLAGS) -o wmbiff $^ $(LIBDIR) $(LIBS)
 
-clean::
+clean:
 	for i in $(OBJS) ; do \
 		rm -f $$i ; \
 	done
-	rm -f wmbiff *~ tags
+	rm -f wmbiff *~ tags core wmbiff-master.xpm
+
+distclean: clean
+
+install: wmbiff
+	$(INSTALL_DIR) $(BINDIR)
+	$(INSTALL_DIR) $(MANDIR)/man1
+	$(INSTALL_DIR) $(MANDIR)/man5
+	$(INSTALL_PRG) wmbiff $(BINDIR)
+	$(INSTALL_FILE) wmbiff.1 $(MANDIR)/man1
+	$(INSTALL_FILE) wmbiffrc.5 $(MANDIR)/man5
+
+# CODING STYLE AND INDENTATION [2001-Mar-12]:
+#
+# There have been some problems with coding style in the past.  Many people
+# contributed to wmbiff (thank you!), and the code got really messy.  To help
+# resolve this, I used GNU indent with what I believe to be the most
+# widely-accepted coding style options (K&R style) with 4-space TAB indents
+# (because some of the code is highly nested) to clean up the code.  Not
+# everyone may be happy with this, but has been determined to be necessary for
+# consistency and legibility.
+#
+# In other words, make sure you run "make clean" and "make indent", and do not
+# change the options on the indent command, before you submit patches against
+# wmbiff.  This will make everyone's life easier.
+#
+#	-- Dwayne C. Litzenberger <dlitz at dlitz.net>
+indent:
+	indent -npro -kr -i4 -ts4 *.[ch] || true
 
-install:: wmbiff
-	cp -f wmbiff $(prefix)$(BIN)/
-	chmod 755 $(prefix)$(BIN)/wmbiff
diff --git a/wmbiff/Pop3Client.c b/wmbiff/Pop3Client.c
index 4d737e0..0508c82 100644
--- a/wmbiff/Pop3Client.c
+++ b/wmbiff/Pop3Client.c
@@ -1,215 +1,349 @@
+/* $Id: Pop3Client.c,v 1.9 2002/03/12 23:53:15 bluehal Exp $ */
 /* Author : Scott Holden ( scotth at thezone.net )
+   Modified : Yong-iL Joh ( tolkien at mizi.com )
+   Modified : Jorge Garc�a ( Jorge.Garcia at uv.es )
+   Modified ; Mark Hurley ( debian4tux at telocity.com )
+   Modified : Neil Spring ( nspring at cs.washington.edu )
  * 
  * Pop3 Email checker.
  *
- * Last Updated : Mar 20, 1999
+ * Last Updated : Tue Nov 13 13:45:23 PST 2001
  *
  */
 
+#include "Client.h"
+#include "charutil.h"
 
-#include "Pop3Client.h"
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#undef DEBUG_POP3
-/* #define DEBUG_POP3 */
-
-struct pop3_struct{
-        struct sockaddr_in server;
-        struct hostent *hp;
-        enum   {CONNECTED, NOT_CONNECTED} connected;
-        char   inBuf[1024];
-        int    inBufSize;
-        char   outBuf[1024];
-        int    outBufSize;
-        int    s;
-        char   password[256];
-        char   userName[256];
-	char   serverName[256];
-        int    serverPort;
-        int    localPort;
-        int    numOfMessages;
-        int    numOfUnreadMessages;
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#define	PCU	(pc->u).pop
+#define POP_DM(pc, lvl, args...) DM(pc, lvl, "pop3: " args)
 
+#ifdef WITH_GCRYPT
+static FILE *authenticate_md5(Pop3 pc, FILE * fp, char *unused);
+static FILE *authenticate_apop(Pop3 pc, FILE * fp, char *apop_str);
+#endif
+static FILE *authenticate_plaintext(Pop3 pc, FILE * fp, char *unused);
+
+static struct authentication_method {
+	const char *name;
+	/* callback returns the filehandle if successful, 
+	   NULL if failed */
+	FILE *(*auth_callback) (Pop3 pc, FILE * fp, char *apop_str);
+} auth_methods[] = {
+	{
+#ifdef WITH_GCRYPT
+	"cram-md5", authenticate_md5}, {
+	"apop", authenticate_apop}, {
+#endif
+	"plaintext", authenticate_plaintext}, {
+	NULL, NULL}
 };
 
-Pop3 pop3Create(char *str)
+FILE *pop3Login(Pop3 pc)
 {
-  /* POP3 format: pop3:user:password at server[:port] */
-  Pop3 pc;
-  char *tmp;
-  char *p;
+	int fd;
+	FILE *fp;
+	char buf[BUF_SIZE];
+	char apop_str[BUF_SIZE];
+	char *ptr1, *ptr2;
+	struct authentication_method *a;
 
-#ifdef DEBUG_POP3
-  printf("pop3: str = '%s'\n", str);
-#endif
+	apop_str[0] = '\0';			/* if defined, server supports apop */
 
-  pc = (Pop3)malloc( sizeof(*pc) );
-  if( pc == 0)
-        return 0;
-  strcpy(pc->password , "");
-  strcpy(pc->userName , "");
-  strcpy(pc->serverName , "");
-  pc->connected     = NOT_CONNECTED;
-  pc->serverPort    = 110;
-  pc->localPort     = 0;
-  pc->numOfMessages = 0;
-  pc->numOfUnreadMessages = 0;
-  pc->inBufSize     = 0;
-  pc->outBufSize    = 0;
-  tmp = strdup(str);
-  p = strtok(tmp, ":");				/* cut off ``pop3:'' */
-  p = strtok(NULL, ":");			/* p pointed to username */
-  strcpy(pc->userName, p);
-  p = strtok(NULL, "@");			/* p -> password */
-  strcpy(pc->password, p);
-  p = strtok(NULL, ":");			/* p-> server */
-  strcpy(pc->serverName, p);
-  if( (p = strtok(NULL, ":")) != NULL ) {	/* port selected; p -> port */
-    pc->serverPort = atoi(p);
-  }
-  free(tmp);
-#ifdef DEBUG_POP3
-/*  printf("pop3: mbox[%d].path= '%s'\n", item, mbox[item].path); */
-  printf("pop3: userName= '%s'\n", pc->userName);
-  printf("pop3: password= '%s'\n",pc->password);
-  printf("pop3: serverName= '%s'\n", pc->serverName);
-  printf("pop3: serverPort= '%d'\n", pc->serverPort);
-#endif
+	if ((fd = sock_connect(PCU.serverName, PCU.serverPort)) == -1) {
+		POP_DM(pc, DEBUG_ERROR, "Not Connected To Server '%s:%d'\n",
+			   PCU.serverName, PCU.serverPort);
+		return NULL;
+	}
+
+	fp = fdopen(fd, "r+");
+	fgets(buf, BUF_SIZE, fp);
+	fflush(fp);
+	POP_DM(pc, DEBUG_INFO, "%s", buf);
+
+	/* Detect APOP, copy challenge into apop_str */
+	for (ptr1 = buf + strlen(buf), ptr2 = NULL; ptr1 > buf; --ptr1) {
+		if (*ptr1 == '>') {
+			ptr2 = ptr1;
+		} else if (*ptr1 == '<') {
+			if (ptr2) {
+				*(ptr2 + 1) = 0;
+				strncpy(apop_str, ptr1, BUF_SIZE);
+			}
+			break;
+		}
+	}
+
+	/* try each authentication method in turn. */
+	for (a = auth_methods; a->name != NULL; a++) {
+		/* was it specified or did the user leave it up to us? */
+		if (PCU.authList[0] == '\0' || strstr(PCU.authList, a->name))
+			/* did it work? */
+			if ((a->auth_callback(pc, fp, apop_str)) != NULL)
+				return (fp);
+	}
 
-  return pc;
+	/* if authentication worked, we won't get here */
+	POP_DM(pc, DEBUG_ERROR,
+		   "All Pop3 authentication methods failed for '%s@%s:%d'\n",
+		   PCU.userName, PCU.serverName, PCU.serverPort);
+	fprintf(fp, "QUIT\r\n");
+	fclose(fp);
+	return NULL;
 }
 
-int pop3MakeConnection(Pop3 pc)
+int pop3CheckMail(Pop3 pc)
 {
-    pc->s = socket(AF_INET, SOCK_STREAM, 0 );
-    memset( &pc->server, 0 , sizeof(pc->server));
-    pc->server.sin_family = AF_INET;
-    pc->hp = gethostbyname(pc->serverName);
-    if( pc->hp == 0)
-        return -1;
-    memcpy( &pc->server.sin_addr, pc->hp->h_addr, pc->hp->h_length);
-    pc->server.sin_port = htons(pc->serverPort);
-    if ( connect(pc->s, (struct sockaddr *)&pc->server
-                               , sizeof(pc->server)) < 0 )
-        return -1;
-    pc->connected = CONNECTED;
-   return 0;
+	FILE *f;
+	int read;
+	char buf[BUF_SIZE];
+
+	f = pc->open(pc);
+	if (f == NULL)
+		return -1;
+
+	fprintf(f, "STAT\r\n");
+	fflush(f);
+	fgets(buf, 256, f);
+	if (buf[0] != '+') {
+		POP_DM(pc, DEBUG_ERROR,
+			   "Error Receiving Stats '%s@%s:%d'\n",
+			   PCU.userName, PCU.serverName, PCU.serverPort);
+		POP_DM(pc, DEBUG_INFO, "It said: %s\n", buf);
+		return -1;
+	} else {
+		sscanf(buf, "+OK %d", &(pc->TotalMsgs));
+	}
+
+	/*  - Updated - Mark Hurley - debian4tux at telocity.com
+	 *  In compliance with RFC 1725
+	 *  which removed the LAST command, any servers
+	 *  which follow this spec will return:
+	 *      -ERR unimplimented
+	 *  We will leave it here for those servers which haven't
+	 *  caught up with the spec.
+	 */
+	fprintf(f, "LAST\r\n");
+	fflush(f);
+	fgets(buf, 256, f);
+	if (buf[0] != '+') {
+		/* it is not an error to receive this according to RFC 1725 */
+		/* no error should be returned */
+		pc->UnreadMsgs = pc->TotalMsgs;
+	} else {
+		sscanf(buf, "+OK %d", &read);
+		pc->UnreadMsgs = pc->TotalMsgs - read;
+	}
+
+	fprintf(f, "QUIT\r\n");
+	fclose(f);
+
+	return 0;
 }
 
-int pop3IsConnected(Pop3 pc)
+int pop3Create(Pop3 pc, const char *str)
 {
-    if( pc->connected == CONNECTED)
-        return 1;
-    return 0;
+	/* POP3 format: pop3:user:password at server[:port] */
+	/* new POP3 format: pop3:user password server [port] */
+	/* If 'str' line is badly formatted, wmbiff won't display the mailbox. */
+	int i;
+	int matchedchars;
+	struct re_registers regs;
+	/* ([^: ]+) user
+	   ([^@]+) or ([^ ]+) password 
+	   ([^: ]+) server 
+	   ([: ][0-9]+)? optional port 
+	   ' *' gobbles trailing whitespace before authentication types.
+	   use separate regexes for old and new types to permit
+	   use of '@' in passwords
+	 */
+	const char *regexes[] = {
+		"pop3:([^: ]{1,32}) ([^ ]{1,32}) ([^: ]+)( [0-9]+)? *",
+		"pop3:([^: ]{1,32}):([^@]{1,32})@([^: ]+)(:[0-9]+)? *",
+		NULL
+	};
+
+	for (matchedchars = 0, i = 0;
+		 regexes[i] != NULL && matchedchars <= 0; i++) {
+		matchedchars = compile_and_match_regex(regexes[i], str, &regs);
+	}
+
+	/* failed to match either regex */
+	if (matchedchars <= 0) {
+		pc->label[0] = '\0';
+		POP_DM(pc, DEBUG_ERROR, "Couldn't parse line %s (%d)\n", str,
+			   matchedchars);
+		return -1;
+	}
+
+	/* copy matches where they belong */
+	copy_substring(PCU.userName, regs.start[1], regs.end[1], str);
+	copy_substring(PCU.password, regs.start[2], regs.end[2], str);
+	copy_substring(PCU.serverName, regs.start[3], regs.end[3], str);
+	if (regs.start[4] != -1)
+		PCU.serverPort = atoi(str + regs.start[4] + 1);
+	else
+		PCU.serverPort = 110;
+
+	grab_authList(str + regs.end[0], PCU.authList);
+
+	POP_DM(pc, DEBUG_INFO, "userName= '%s'\n", PCU.userName);
+	POP_DM(pc, DEBUG_INFO, "password= is %d characters long\n",
+		   strlen(PCU.password));
+	POP_DM(pc, DEBUG_INFO, "password is %d chars long\n",
+		   strlen(PCU.password));
+	POP_DM(pc, DEBUG_INFO, "serverName= '%s'\n", PCU.serverName);
+	POP_DM(pc, DEBUG_INFO, "serverPort= '%d'\n", PCU.serverPort);
+	POP_DM(pc, DEBUG_INFO, "authList= '%s'\n", PCU.authList);
+
+	pc->open = pop3Login;
+	pc->checkMail = pop3CheckMail;
+	pc->TotalMsgs = 0;
+	pc->UnreadMsgs = 0;
+	pc->OldMsgs = -1;
+	pc->OldUnreadMsgs = -1;
+	return 0;
 }
 
-int pop3Login(Pop3 pc)
+
+#ifdef WITH_GCRYPT
+static FILE *authenticate_md5(Pop3 pc,
+							  FILE * fp,
+							  char *apop_str __attribute__ ((unused)))
 {
-      int size; 
-      char temp[1024];
-
-      if( pc->connected == NOT_CONNECTED ){
-          fprintf(stderr, "Not Connected To Server '%s:%d'\n", pc->serverName, pc->serverPort);
-          return -1;
-      }
-
-      size = recv(pc->s,&pc->inBuf,1024,0);
-      memset(&temp,0,1024);
-      memcpy(&temp,&pc->inBuf,size);
-      if( temp[0] != '+' ){
-          fprintf(stderr, "Error Logging in (server '%s:%d')\n", pc->serverName, pc->serverPort);
-          return -1;
-      }
-
-      sprintf(pc->outBuf,"USER %s\r\n",pc->userName);
-      send(pc->s, &pc->outBuf,strlen(pc->outBuf),0); 
-      size =recv(pc->s,&pc->inBuf,1024,0);
-      memset(&temp,0,1024);
-      memcpy(&temp,&pc->inBuf,size);
-      if( temp[0] != '+' ){
-          fprintf(stderr, "Invalid User Name '%s@%s:%d'\n", pc->userName, pc->serverName, pc->serverPort);
-          return -1;
-      }
-
-      memset(&pc->outBuf,0,1024);
-      sprintf(pc->outBuf,"PASS %s\r\n",pc->password);
-      send(pc->s, pc->outBuf, strlen(pc->outBuf),0 );
-      size =recv(pc->s,&pc->inBuf,1024,0);
-      memset(&temp,0,1024);
-      memcpy(&temp,&pc->inBuf,size);
-      if( temp[0] != '+' ){
-          fprintf(stderr, "Incorrect Password for user '%s@%s:%d'\n", pc->userName, pc->serverName, pc->serverPort);
-          return -1;
-      }
-
-      return 0;
-}
+	char buf[BUF_SIZE];
+	char buf2[BUF_SIZE];
+	unsigned char *md5;
+	GCRY_MD_HD gmh;
 
-int pop3CheckMail(Pop3 pc){
-    int size;
-    char temp[1024];
-    char *ptr;
-    if( pc->connected == NOT_CONNECTED )
-        return -1;
-
-     /* Find total number of messages in mail box */
-     sprintf(pc->outBuf,"STAT\r\n");
-     send(pc->s, pc->outBuf, strlen(pc->outBuf),0 );
-     size =recv(pc->s,&pc->inBuf,1024,0);
-     memset(&temp,0,1024);
-     memcpy(&temp,&pc->inBuf,size);
-     ptr = strtok(temp, " ");
-     ptr = strtok( 0," ");
-     pc->numOfMessages = atoi(ptr);
-
-     if( temp[0] != '+' ){
-         fprintf(stderr, "Error Receiving Stats '%s@%s:%d'\n", pc->userName, pc->serverName, pc->serverPort);
-         return -1;
-     }
-
-     sprintf(pc->outBuf,"LAST\r\n");
-     send(pc->s, pc->outBuf, strlen(pc->outBuf),0 );
-     size =recv(pc->s,&pc->inBuf,1024,0);
-     memset(&temp,0,1024);
-     memcpy(&temp,&pc->inBuf,size);
-     ptr = strtok(temp, " ");
-     ptr = strtok( 0," ");
-     pc->numOfUnreadMessages = pc->numOfMessages - atoi(ptr);
-
-     if( temp[0] != '+' ){
-         fprintf(stderr, "Error Receiving Stats '%s@%s:%d'\n", pc->userName, pc->serverName, pc->serverPort);
-         return -1;
-     }
-     return 1;
+	/* See if MD5 is supported */
+	fprintf(fp, "AUTH CRAM-MD5\r\n");
+	fflush(fp);
+	fgets(buf, BUF_SIZE, fp);
+	POP_DM(pc, DEBUG_INFO, "%s", buf);
 
-}
+	if (buf[0] != '+' || buf[1] != ' ') {
+		/* nope, not supported. */
+		return NULL;
+	}
+
+	Decode_Base64(buf + 2, buf2);
+	POP_DM(pc, DEBUG_INFO, "CRAM-MD5 challenge: %s\n", buf2);
+
+	strcpy(buf, PCU.userName);
+	strcat(buf, " ");
+
+
+	gmh = gcry_md_open(GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
+	gcry_md_setkey(gmh, PCU.password, strlen(PCU.password));
+	gcry_md_write(gmh, (unsigned char *) buf2, strlen(buf2));
+	gcry_md_final(gmh);
+	md5 = gcry_md_read(gmh, 0);
+	/* hmac_md5(buf2, strlen(buf2), PCU.password,
+	   strlen(PCU.password), md5); */
+	Bin2Hex(md5, 16, buf2);
+	gcry_md_close(gmh);
+
+	strcat(buf, buf2);
+	POP_DM(pc, DEBUG_INFO, "CRAM-MD5 response: %s\n", buf);
+	Encode_Base64(buf, buf2);
+
+	fprintf(fp, "%s\r\n", buf2);
+	fflush(fp);
+	fgets(buf, BUF_SIZE, fp);
 
-int  pop3GetTotalNumberOfMessages( Pop3 pc ){
-     if( pc != 0 )
-         return pc->numOfMessages;
-     return -1;    
+	if (!strncmp(buf, "+OK", 3))
+		return fp;				/* AUTH successful */
+	else {
+		POP_DM(pc, DEBUG_ERROR,
+			   "CRAM-MD5 AUTH failed for user '%s@%s:%d'\n",
+			   PCU.userName, PCU.serverName, PCU.serverPort);
+		fprintf(stderr, "It said %s", buf);
+		return NULL;
+	}
 }
 
-int  pop3GetNumberOfUnreadMessages( Pop3 pc ){
-    if( pc != 0)
-        return pc->numOfUnreadMessages;
-    return -1;
+static FILE *authenticate_apop(Pop3 pc, FILE * fp, char *apop_str)
+{
+	GCRY_MD_HD gmh;
+	char buf[BUF_SIZE];
+	unsigned char *md5;
+
+	if (apop_str[0] == '\0') {
+		/* server doesn't support apop. */
+		return (NULL);
+	}
+	POP_DM(pc, DEBUG_INFO, "APOP challenge: %s\n", apop_str);
+	strcat(apop_str, PCU.password);
+
+	gmh = gcry_md_open(GCRY_MD_MD5, 0);
+	gcry_md_write(gmh, (unsigned char *) apop_str, strlen(apop_str));
+	gcry_md_final(gmh);
+	md5 = gcry_md_read(gmh, 0);
+	Bin2Hex(md5, 16, buf);
+	gcry_md_close(gmh);
+
+	POP_DM(pc, DEBUG_INFO, "APOP response: %s %s\n", PCU.userName, buf);
+	fprintf(fp, "APOP %s %s\r\n", PCU.userName, buf);
+	fflush(fp);
+	fgets(buf, BUF_SIZE, fp);
+
+	if (!strncmp(buf, "+OK", 3))
+		return fp;				/* AUTH successful */
+	else {
+		POP_DM(pc, DEBUG_ERROR,
+			   "APOP AUTH failed for user '%s@%s:%d'\n",
+			   PCU.userName, PCU.serverName, PCU.serverPort);
+		POP_DM(pc, DEBUG_INFO, "It said %s", buf);
+		return NULL;
+	}
 }
+#endif							/* WITH_GCRYPT */
 
-int pop3Quit(Pop3 pc){
-    int size;
-    if( pc->connected == NOT_CONNECTED )
-        return -1;
-    send(pc->s, "quit\r\n", 6,0 );
-    size =recv(pc->s,&pc->inBuf,1024,0);
-    pc->connected = NOT_CONNECTED;
-    return 0;
+static FILE *authenticate_plaintext(Pop3 pc, FILE * fp, char *apop_str
+									__attribute__ ((unused)))
+{
+	char buf[BUF_SIZE];
+
+	fprintf(fp, "USER %s\r\n", PCU.userName);
+	fflush(fp);
+	if (fgets(buf, BUF_SIZE, fp) == NULL) {
+		POP_DM(pc, DEBUG_ERROR,
+			   "Error reading from server authenticating '%s@%s:%d'\n",
+			   PCU.userName, PCU.serverName, PCU.serverPort);
+		return NULL;
+	}
+	if (buf[0] != '+') {
+		POP_DM(pc, DEBUG_ERROR,
+			   "Failed user name when authenticating '%s@%s:%d'\n",
+			   PCU.userName, PCU.serverName, PCU.serverPort);
+		/* deb #128863 might be easier if we printed: */
+		POP_DM(pc, DEBUG_ERROR, "The server's error message was: %s\n",
+			   buf);
+		return NULL;
+	};
 
+	fprintf(fp, "PASS %s\r\n", PCU.password);
+	fflush(fp);
+	if (fgets(buf, BUF_SIZE, fp) == NULL) {
+		POP_DM(pc, DEBUG_ERROR,
+			   "Error reading from server (2) authenticating '%s@%s:%d'\n",
+			   PCU.userName, PCU.serverName, PCU.serverPort);
+		return NULL;
+	}
+	if (buf[0] != '+') {
+		POP_DM(pc, DEBUG_ERROR,
+			   "Failed password when authenticating '%s@%s:%d'\n",
+			   PCU.userName, PCU.serverName, PCU.serverPort);
+		POP_DM(pc, DEBUG_ERROR, "The server's error message was: %s\n",
+			   buf);
+		return NULL;
+	};
+
+	return fp;
 }
+
+/* vim:set ts=4: */
diff --git a/wmbiff/Pop3Client.h b/wmbiff/Pop3Client.h
deleted file mode 100644
index 829c85c..0000000
--- a/wmbiff/Pop3Client.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Author : Scott Holden ( scotth at thezone.net )
- *
- * Pop3 Email Checker
- *
- * Last Updated : Mar 20, 1999
- *
- */
-
-
-#ifndef POP3CLIENT
-#define POP3CLIENT
-
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-
-typedef struct pop3_struct *Pop3;
-
-Pop3 pop3Create(char *str);
-int  pop3MakeConnection( Pop3 pc);
-int  pop3IsConnected(Pop3 pc);
-int  pop3Login(Pop3 pc);
-int  pop3Quit(Pop3 pc);
-int  pop3CheckMail(Pop3 pc);
-int  pop3GetTotalNumberOfMessages( Pop3 pc );
-int  pop3GetNumberOfUnreadMessages( Pop3 pc );
-
-#endif
diff --git a/wmbiff/ShellClient.c b/wmbiff/ShellClient.c
new file mode 100644
index 0000000..e1cf744
--- /dev/null
+++ b/wmbiff/ShellClient.c
@@ -0,0 +1,114 @@
+/* Author: Beno�t Rouits ( brouits at free.fr ) thanks to Neil Spring.
+   from LicqClient by Yong-iL Joh ( tolkien at mizi.com ) 
+   and Jorge Garc�a ( Jorge.Garcia at uv.es )
+ * 
+ * generic Shell command support
+ *
+ * Last Updated : Tue Mar  5 15:23:35 CET 2002
+ *
+ */
+
+#include "Client.h"
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#define SH_DM(pc, lvl, args...) DM(pc, lvl, "shell: " args)
+
+/* kind_pclose checks the return value from pclose and prints
+   some nice error messages about it.  ordinarily, this would be 
+   a good idea, but wmbiff has a sigchld handler that reaps 
+   children immediately (needed when spawning other child processes),
+   so no error checking can be done here until that's disabled */
+
+/* TODO: block or unbind sigchld before popen, and reenable on pclose */
+static void kind_pclose(FILE * F, const char *command, Pop3 pc)
+{
+	int exit_status = pclose(F);
+	if (exit_status != 0) {
+		if (exit_status == -1) {
+			/* wmbiff has a sigchld handler already, so wait is likely 
+			   to fail */
+			if (errno != ECHILD) {
+				SH_DM(pc, DEBUG_ERROR, "pclose '%s' failed: %s\n",
+					  command, strerror(errno));
+			}
+		} else {
+			SH_DM(pc, DEBUG_ERROR,
+				  "'%s' exited with non-zero status %d\n", command,
+				  exit_status);
+		}
+	}
+}
+
+int shellCmdCheck(Pop3 pc)
+{
+	FILE *F;
+	int count_status = 0;
+
+	if (pc == NULL)
+		return -1;
+	SH_DM(pc, DEBUG_INFO, ">Mailbox: '%s'\n", pc->path);
+
+	if ((F = popen(pc->path, "r")) == NULL) {
+		SH_DM(pc, DEBUG_ERROR, "popen: error while reading '%s': %s\n",
+			  pc->path, strerror(errno));
+		return -1;
+	}
+
+	/* doesn't really need to be handled separately, but it
+	   seems worth an error message */
+	if (fscanf(F, "%d\n", &(count_status)) != 1) {
+		SH_DM(pc, DEBUG_ERROR,
+			  "'%s' returned something other than an integer message count.\n",
+			  pc->path);
+		kind_pclose(F, pc->path, pc);
+		return -1;
+	}
+
+	pc->TotalMsgs = pc->UnreadMsgs + count_status;
+	pc->UnreadMsgs = count_status;
+	SH_DM(pc, DEBUG_INFO, "from: %d status: %d\n", pc->TotalMsgs,
+		  pc->UnreadMsgs);
+
+	kind_pclose(F, pc->path, pc);
+	return 0;
+}
+
+int shellCreate(Pop3 pc, const char *str)
+{
+	/* SHELL format: shell:::/path/to/script */
+	const char *reserved1, *reserved2, *commandline;
+
+	pc->TotalMsgs = 0;
+	pc->UnreadMsgs = 0;
+	pc->OldMsgs = -1;
+	pc->OldUnreadMsgs = -1;
+	pc->checkMail = shellCmdCheck;
+	reserved1 = str + 6;		/* shell:>:: */
+
+	reserved2 = index(reserved1, ':');
+	if (reserved2 == NULL) {
+		SH_DM(pc, DEBUG_ERROR, "unable to parse '%s', expecting ':'", str);
+		return 0;
+	}
+	reserved2++;				/* shell::>: */
+
+	commandline = index(reserved2, ':');
+	if (commandline == NULL) {
+		SH_DM(pc, DEBUG_ERROR,
+			  "unable to parse '%s', expecting another ':'", str);
+		return 0;
+	}
+	commandline++;				/* shell:::> */
+
+	/* good thing strcpy handles overlapping regions */
+	strcpy(pc->path, commandline);
+	SH_DM(pc, DEBUG_INFO, "path= '%s'\n", commandline);
+	return 0;
+}
+
+/* vim:set ts=4: */
diff --git a/wmbiff/charutil.c b/wmbiff/charutil.c
new file mode 100644
index 0000000..be4c031
--- /dev/null
+++ b/wmbiff/charutil.c
@@ -0,0 +1,221 @@
+/* $Id: charutil.c,v 1.7 2002/01/12 05:30:09 bluehal Exp $ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
+#include "charutil.h"
+
+static __inline__ int LeftTrim(char *psValue)
+{
+
+	char *psTmp = psValue;
+
+	while (*psTmp == ' ' || *psTmp == '\t')
+		psTmp++;
+
+	strcpy(psValue, psTmp);
+
+	return EXIT_SUCCESS;
+}
+
+static __inline__ int RightTrim(char *psValue)
+{
+
+	long lLength = strlen(psValue) - 1;
+
+	while ((psValue[lLength] == ' ' || psValue[lLength] == '\t')
+		   && *psValue) {
+		lLength--;
+	}
+
+	psValue[++lLength] = '\000';
+	return EXIT_SUCCESS;
+}
+
+int FullTrim(char *psValue)
+{
+
+	if (LeftTrim(psValue) != 0)
+		return EXIT_FAILURE;
+	if (RightTrim(psValue) != 0)
+		return EXIT_FAILURE;
+	return EXIT_SUCCESS;
+}
+
+void Bin2Hex(unsigned char *src, int length, char *dst)
+{
+	static char hex_tbl[] = "0123456789abcdef";
+
+	int i = 0;
+	char *ptr = dst;
+
+	if (src && ptr) {
+		for (i = 0; i < length; i++) {
+			*ptr++ = hex_tbl[*src >> 4];
+			*ptr++ = hex_tbl[*src++ & 0xf];
+		}
+		*ptr = 0;
+	}
+}
+
+
+#define PAD '='
+char ALPHABET[65] =
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\000";
+
+/* find char in in alphabet, return offset, -1 otherwise */
+int find_char(char c)
+{
+	char *a = ALPHABET;
+
+	while (*a)
+		if (*(a++) == c)
+			return a - ALPHABET - 1;
+
+	return -1;
+}
+
+void Encode_Base64(char *src, char *dst)
+{
+	int g = 0;
+	int c = 0;
+
+	if (!src || !dst)
+		return;
+
+	while (*src) {
+		g = (g << 8) | *src++;
+		if (c == 2) {
+			*dst++ = ALPHABET[0x3f & (g >> 18)];
+			*dst++ = ALPHABET[0x3f & (g >> 12)];
+			*dst++ = ALPHABET[0x3f & (g >> 6)];
+			*dst++ = ALPHABET[0x3f & g];
+		}
+		c = (c + 1) % 3;
+	}
+
+	if (c) {
+		if (c == 1) {
+			*dst++ = ALPHABET[0x3f & (g >> 2)];
+			*dst++ = ALPHABET[0x3f & (g << 4)];
+			*dst++ = PAD;
+			*dst++ = PAD;
+		} else {
+			*dst++ = ALPHABET[0x3f & (g >> 10)];
+			*dst++ = ALPHABET[0x3f & (g >> 4)];
+			*dst++ = ALPHABET[0x3f & (g << 2)];
+			*dst++ = PAD;
+		}
+	}
+	*dst = 0;
+}
+
+
+void Decode_Base64(char *src, char *dst)
+{
+	int g = 0;
+	int c = 0;
+	int n = 0;
+
+	if (!src || !dst)
+		return;
+
+	while (*src) {
+		n = find_char(*src++);
+		if (n < 0)
+			continue;
+
+		g <<= 6;
+		g |= n;
+		if (c == 3) {
+			*dst++ = g >> 16;
+			*dst++ = g >> 8;
+			*dst++ = g;
+			g = 0;
+		}
+		c = (c + 1) % 4;
+	}
+	if (c) {
+		if (c == 1) {
+			/* shouldn't happen, but do something anyway */
+			*dst++ = g << 2;
+		} else if (c == 2) {
+			*dst++ = g >> 4;
+		} else {
+			*dst++ = g >> 10;
+			*dst++ = g >> 2;
+		}
+	}
+	*dst = 0;
+}
+
+/* helper function for the configuration line parser */
+void copy_substring(char *destination,
+					int startidx, int endidx, const char *source)
+{
+	if (startidx > -1) {
+		strncpy(destination, source + startidx, endidx - startidx);
+		destination[endidx - startidx] = '\0';
+	}
+}
+
+/* common to Pop3 and Imap4 authentication list grabber. */
+void grab_authList(const char *source, char *destination)
+{
+	int i;
+	/* regex isn't all that helpful for lists of things. */
+	/* but does leave the end of the matched region in  regs.end[0] */
+	/* what remains is a list of legal authentication schemes. */
+	if (isalnum(source[0])) {
+		/* copy, while turning caps into lower case */
+		for (i = 0; i < 99 && source[i] != '\0'; i++) {
+			destination[i] = tolower(source[i]);
+		}
+		destination[i] = '\0';
+	} else {
+		destination[0] = '\0';
+	}
+}
+
+
+int compile_and_match_regex(const char *regex, const char *str,	/*@out@ */
+							struct re_registers *regs)
+{
+
+	const char *errstr;
+	int matchedchars;
+	struct re_pattern_buffer rpbuf;
+
+	/* compile the regex pattern */
+	memset(&rpbuf, 0, sizeof(struct re_pattern_buffer));
+
+	/* posix egrep interprets intervals (eg. {1,32}) nicely */
+	re_syntax_options = RE_SYNTAX_POSIX_EGREP;
+	errstr = re_compile_pattern(regex, strlen(regex), &rpbuf);
+	if (errstr != NULL) {
+		fprintf(stderr, "error in compiling regular expression: %s\n",
+				errstr);
+		return -1;
+	}
+
+	/* match the regex */
+	regs->num_regs = REGS_UNALLOCATED;
+	matchedchars = re_match(&rpbuf, str, strlen(str), 0, regs);
+	/* this can fail (return -1 or 0) without being an error,
+	   if we're trying to apply a regex just to see if it
+	   matched. */
+
+#ifdef undef
+	printf("--\n");
+	for (i = 1; i < 6; i++) {
+		printf("%d %d, (%.*s)\n", regs.start[i], regs.end[i],
+			   (regs.end[i] - regs.start[i]),
+			   (regs.start[i] >= 0) ? &str[regs.start[i]] : "");
+	}
+#endif
+
+	return matchedchars;
+}
diff --git a/wmbiff/charutil.h b/wmbiff/charutil.h
new file mode 100644
index 0000000..6e5ac62
--- /dev/null
+++ b/wmbiff/charutil.h
@@ -0,0 +1,34 @@
+/* $Id: charutil.h,v 1.5 2002/02/02 18:04:19 jordi Exp $ */
+/* Author: Mark Hurley  (debian4tux at telocity.com)
+ *
+ * Character / string manipulation utilities. 
+ *
+ */
+
+#ifndef CHARUTIL
+#define CHARUTIL
+
+#ifdef EXT_GNU_REGEX_LIB
+#include <gnuregex.h>
+#else
+#include <regex.h>
+#endif
+
+int FullTrim(char *psValue);
+
+void Bin2Hex(unsigned char *src, int length, char *dst);
+
+void Encode_Base64(char *src, char *dst);
+void Decode_Base64(char *src, char *dst);
+
+/* helper function for the configuration line parser */
+void copy_substring(char *destination,
+					int startidx, int endidx, const char *source);
+
+/* common to Pop3 and Imap4 authentication list grabber. */
+void grab_authList(const char *source, char *destination);
+
+/* handles main regex work */
+int compile_and_match_regex(const char *regex, const char *str,
+							/*@out@ */ struct re_registers *regs);
+#endif
diff --git a/wmbiff/maildirClient.c b/wmbiff/maildirClient.c
new file mode 100644
index 0000000..5b834f5
--- /dev/null
+++ b/wmbiff/maildirClient.c
@@ -0,0 +1,135 @@
+/* $Id: maildirClient.c,v 1.5 2002/03/05 05:02:44 dwonis Exp $ */
+/* Author : Yong-iL Joh ( tolkien at mizi.com )
+   Modified : Jorge Garc�a ( Jorge.Garcia at uv.es )
+   Modified : Dwayne C. Litzenberger ( dlitz at dlitz.net )
+ * 
+ * Maildir checker.
+ *
+ * Last Updated : $Date: 2002/03/05 05:02:44 $
+ *
+ */
+
+#include "Client.h"
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+#include <utime.h>
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
+
+
+#define PCM	(pc->u).maildir
+
+static int count_msgs(char *path)
+{
+	DIR *D;
+	struct dirent *de;
+	int count = 0;
+
+	D = opendir(path);
+	if (D == NULL) {
+		DMA(DEBUG_ERROR,
+			"Error opening directory '%s': %s\n", path, strerror(errno));
+		return -1;
+	}
+
+	while ((de = readdir(D)) != NULL) {
+		if ((strcmp(de->d_name, ".") & strcmp(de->d_name, "..")) != 0) {
+			count++;
+		}
+	}
+	closedir(D);
+
+	return count;
+}
+
+int maildirCheckHistory(Pop3 pc)
+{
+	struct stat st_new;
+	struct stat st_cur;
+	struct utimbuf ut;
+	char path_new[256], path_cur[256];
+
+	int count_new = 0, count_cur = 0;
+
+	DM(pc, DEBUG_INFO, ">Maildir: '%s'\n", pc->path);
+
+	strcpy(path_new, pc->path);
+	strcat(path_new, "/new/");
+	strcpy(path_cur, pc->path);
+	strcat(path_cur, "/cur/");
+
+	/* maildir */
+	if (stat(path_new, &st_new)) {
+		DM(pc, DEBUG_ERROR, "Can't stat mailbox '%s': %s\n",
+		   path_new, strerror(errno));
+		return -1;				/* Error stating mailbox */
+	}
+	if (stat(path_cur, &st_cur)) {
+		DM(pc, DEBUG_ERROR, "Can't stat mailbox '%s': %s\n",
+		   path_cur, strerror(errno));
+		return -1;				/* Error stating mailbox */
+	}
+
+
+	/* file was changed OR initially read */
+	if (st_new.st_mtime != PCM.mtime_new
+		|| st_new.st_size != PCM.size_new
+		|| st_cur.st_mtime != PCM.mtime_cur
+		|| st_cur.st_size != PCM.size_cur || pc->OldMsgs < 0) {
+		DM(pc, DEBUG_INFO, "  was changed,\n"
+		   " TIME(new): old %lu, new %lu"
+		   " SIZE(new): old %lu, new %lu\n"
+		   " TIME(cur): old %lu, new %lu"
+		   " SIZE(cur): old %lu, new %lu\n",
+		   PCM.mtime_new, st_new.st_mtime,
+		   (unsigned long) PCM.size_new, st_new.st_size,
+		   PCM.mtime_cur, st_cur.st_mtime,
+		   (unsigned long) PCM.size_cur, st_cur.st_size);
+
+		count_new = count_msgs(path_new);
+		count_cur = count_msgs(path_cur);
+		if ((count_new | count_cur) == -1) {	/* errors occurred */
+			return -1;
+		}
+
+		pc->TotalMsgs = count_cur + count_new;
+		pc->UnreadMsgs = count_new;
+
+		/* Reset atime for MUTT and something others work correctly */
+		ut.actime = st_new.st_atime;
+		ut.modtime = st_new.st_mtime;
+		utime(path_new, &ut);
+		ut.actime = st_cur.st_atime;
+		ut.modtime = st_cur.st_mtime;
+		utime(path_cur, &ut);
+
+		/* Store new values */
+		PCM.mtime_new = st_new.st_mtime;	/* Store new mtime_new */
+		PCM.size_new = st_new.st_size;	/* Store new size_new */
+		PCM.mtime_cur = st_cur.st_mtime;	/* Store new mtime_cur */
+		PCM.size_cur = st_cur.st_size;	/* Store new size_cur */
+	}
+
+	return 0;
+}
+
+int maildirCreate(Pop3 pc, char *str)
+{
+	/* Maildir format: maildir:fullpathname */
+
+	pc->TotalMsgs = 0;
+	pc->UnreadMsgs = 0;
+	pc->OldMsgs = -1;
+	pc->OldUnreadMsgs = -1;
+	pc->checkMail = maildirCheckHistory;
+	strcpy(pc->path, str + 8);	/* cut off ``maildir:'' */
+
+	DM(pc, DEBUG_INFO, "maildir: str = '%s'\n", str);
+	DM(pc, DEBUG_INFO, "maildir: path= '%s'\n", pc->path);
+
+	return 0;
+}
+
+/* vim:set ts=4: */
diff --git a/wmbiff/mboxClient.c b/wmbiff/mboxClient.c
new file mode 100644
index 0000000..2fbee5a
--- /dev/null
+++ b/wmbiff/mboxClient.c
@@ -0,0 +1,133 @@
+/* $Id: mboxClient.c,v 1.6 2002/03/06 07:15:08 bluehal Exp $ */
+/* Author:		Yong-iL Joh <tolkien at mizi.com>
+   Modified:	Jorge Garc�a <Jorge.Garcia at uv.es>
+   			 	Rob Funk <rfunk at funknet.net>
+ * 
+ * MBOX checker.
+ *
+ * Last Updated : Thu Apr 26 03:09:40 CEST 2001
+ *
+ */
+
+#include "Client.h"
+#include <sys/stat.h>
+#include <errno.h>
+#include <utime.h>
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#define PCM	(pc->u).mbox
+#define FROM_STR   "From "
+#define STATUS_STR "Status: "
+
+FILE *openMailbox(Pop3 pc)
+{
+	FILE *mailbox;
+
+	if ((mailbox = fopen(pc->path, "r")) == NULL) {
+		DM(pc, DEBUG_ERROR, "Error opening mailbox '%s': %s\n",
+		   pc->path, strerror(errno));
+	}
+	return (mailbox);
+}
+
+int mboxCheckHistory(Pop3 pc)
+{
+	struct stat st;
+	struct utimbuf ut;
+	FILE *F;
+	char buf[BUF_SIZE];
+
+
+	int is_header = 0;
+	int next_from_is_start_of_header = 1;
+	int count_from = 0, count_status = 0;
+	int len_from = strlen(FROM_STR), len_status = strlen(STATUS_STR);
+
+	DM(pc, DEBUG_INFO, ">Mailbox: '%s'\n", pc->path);
+
+	/* mbox file */
+	if (stat(pc->path, &st)) {
+		DM(pc, DEBUG_ERROR, "Can't stat mailbox '%s': %s\n",
+		   pc->path, strerror(errno));
+		return -1;				/* Error stating mailbox */
+	}
+
+	if (st.st_mtime != PCM.mtime || st.st_size != PCM.size
+		|| pc->OldMsgs < 0) {
+		/* file was changed OR initially read */
+		DM(pc, DEBUG_INFO,
+		   "  was changed,"
+		   " TIME: old %lu, new %lu"
+		   " SIZE: old %lu, new %lu\n",
+		   PCM.mtime, st.st_mtime, (unsigned long) PCM.size, st.st_size);
+		ut.actime = st.st_atime;
+		ut.modtime = st.st_mtime;
+		F = pc->open(pc);
+
+		/* count message */
+		while (fgets(buf, BUF_SIZE, F)) {
+			if (buf[0] == '\n') {
+				/* a newline by itself terminates the header */
+				if (is_header)
+					is_header = 0;
+				else
+					next_from_is_start_of_header = 1;
+			} else if (!strncmp(buf, FROM_STR, len_from)) {
+				/* A line starting with "From" is the beginning of a new header.
+				   "From" in the text of the mail should get escaped by the MDA.
+				   If your MDA doesn't do that, it is broken.
+				 */
+				if (next_from_is_start_of_header)
+					is_header = 1;
+				if (is_header)
+					count_from++;
+			} else {
+				next_from_is_start_of_header = 0;
+				if (!strncmp(buf, STATUS_STR, len_status)) {
+					if (strrchr(buf, 'R')) {
+						if (is_header)
+							count_status++;
+					}
+				}
+			}
+		}
+
+		DM(pc, DEBUG_INFO, "from: %d status: %d\n", count_from,
+		   count_status);
+		pc->TotalMsgs = count_from;
+		pc->UnreadMsgs = count_from - count_status;
+		fclose(F);
+
+		utime(pc->path, &ut);
+		/* Reset atime for MUTT and something others correctly work */
+		PCM.mtime = st.st_mtime;	/* Store new mtime */
+		PCM.size = st.st_size;	/* Store new size */
+	}
+
+	return 0;
+}
+
+int mboxCreate(Pop3 pc, char *str)
+{
+	/* MBOX format: mbox:fullpathname */
+
+	pc->TotalMsgs = 0;
+	pc->UnreadMsgs = 0;
+	pc->OldMsgs = -1;
+	pc->OldUnreadMsgs = -1;
+	pc->open = openMailbox;
+	pc->checkMail = mboxCheckHistory;
+
+	/* default boxes are mbox... cut mbox: if it exists */
+	if (!strncasecmp(pc->path, "mbox:", 5))
+		strcpy(pc->path, str + 5);	/* cut off ``mbox:'' */
+
+	DM(pc, DEBUG_INFO, "mbox: str = '%s'\n", str);
+	DM(pc, DEBUG_INFO, "mbox: path= '%s'\n", pc->path);
+
+	return 0;
+}
+
+/* vim:set ts=4: */
diff --git a/wmbiff/sample.wmbiffrc b/wmbiff/sample.wmbiffrc
index 3d9a066..660456b 100644
--- a/wmbiff/sample.wmbiffrc
+++ b/wmbiff/sample.wmbiffrc
@@ -1,5 +1,9 @@
+# $Id: sample.wmbiffrc,v 1.8 2002/03/06 07:15:08 bluehal Exp $
+#
+# See wmbiffrc(5) for more info.
+#
 # Global interval -- seconds between check mailboxes
-interval=5
+interval=60
 
 ### First string ###
 
@@ -9,7 +13,7 @@ label.0=Spool
 # Path to mailbox for UNIX-style mailboxes,
 # or pop3:user:password at mailserver[:port] for POP3 accounts
 # port are optional, default - 110
-path.0=/var/spool/mail/gb
+path.0=/var/mail/gb
 
 # Command, which executed on new mail arrival, or special keyword 'beep'
 #notify.0=beep
@@ -31,24 +35,50 @@ action.0=rxvt -name mutt -e mutt
 #fetchcmd.0=/usr/bin/fetchmail
 
 ###
-
-label.1 = KSI
-path.1=/home/gb/mail/10_ksi-linux-list
+# NOTE: line under this line will not be parsed because the space before equal
+label.1 = MBOX
+# MBOX format: mbox:fullpathname
+path.1=mbox:/home/gb/mail/10_ksi-linux-list
 notify.1=my_play /home/gb/sounds/new_mail_has_arrived.wav
 action.1=rxvt -name mutt -e mutt -f /home/gb/mail/10_ksi-linux-list
 
-label.2=fmeat
-path.2=/home/gb/mail/20_FreshMeat
-notify.2=my_play /home/gb/sounds/new_mail_has_arrived.wav
-action.2=rxvt -name mutt -e mutt -f /home/gb/mail/20_FreshMeat
+# label.1 = MDIR
+# # Maildir format: maildir:fullpathname
+# path.1=maildir:/home/gb/Maildir/
+# notify.1=my_play /home/gb/sounds/new_mail_has_arrived.wav
+# action.1=rxvt -name mutt -e mutt -f /home/gb/Maildir
+
+label.2=LICQ
+# LICQ format: licq:fullpathname
+path.2=licq:/home/person/.licq/history/1111111.history
+notify.2=beep
+action.2=licq&
+
+#or if you use gnomeicu:
+#label.2=ICQ
+#path.2=gicu:USER_UIN
+#notify.2=beep
+#action.2=gnomeicu-client show
 
-label.3=nftp
-# pop3 format: pop3:user:password at server[:port]
-path.3=pop3:user:password at server
+label.3=POP3
+# pop3 format: pop3:user:password at server[:port] [auth]
+path.3=pop3:user:password at server apop
 notify.3=my_play /home/gb/sounds/new_mail_has_arrived.wav
 action.3=rxvt -name mutt -e mutt -f /home/gb/mail/30_nftp-list
 interval.3=300		# 5 minutes
 fetchinterval.3=-1
 fetchcmd.3=fetchmail
 
+label.4=IMAP4
+# IMAP4 format: imap:user:password at server[/mailbox][:port] [auth]
+# mailbox is optional, default - INBOX
+# port is optional, default - 143
+path.4=imap:user:password at server
+interval.4=300		# 5 minutes
 
+# label.4=IMAPS
+# Secure IMAP format: imaps:user:password at server[/mailbox][:port] [auth]
+# mailbox is optional, default - INBOX
+# port is optional, default - 993
+# path.4=imaps:user:password at server cram-md5
+# interval.4=300          # 5 minutes
diff --git a/wmbiff/socket.c b/wmbiff/socket.c
new file mode 100644
index 0000000..4e353ba
--- /dev/null
+++ b/wmbiff/socket.c
@@ -0,0 +1,61 @@
+/* $Id: socket.c,v 1.3 2001/10/04 09:50:59 jordi Exp $ */
+/* Copyright (C) 1998 Trent Piepho  <xyzzy at u.washington.edu>
+ *           (C) 1999 Trent Piepho  <xyzzy at speakeasy.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.  */
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
+
+int sock_connect(const char *hostname, int port)
+{
+	struct hostent *host;
+	struct sockaddr_in addr;
+	int fd, i;
+
+	host = gethostbyname(hostname);
+	if (host == NULL) {
+		herror("gethostbyname");
+		return (-1);
+	};
+
+	fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+	if (fd == -1) {
+		perror("Error opening socket");
+		return (-1);
+	};
+
+	addr.sin_family = AF_INET;
+	addr.sin_addr.s_addr = *(u_long *) host->h_addr_list[0];
+	addr.sin_port = htons(port);
+	i = connect(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr));
+	if (i == -1) {
+		perror("Error connecting");
+		close(fd);
+		return (-1);
+	};
+	return (fd);
+}
+
+/* vim:set ts=4: */
diff --git a/wmbiff/test-wmbiffrc.shell b/wmbiff/test-wmbiffrc.shell
new file mode 100644
index 0000000..a84c552
--- /dev/null
+++ b/wmbiff/test-wmbiffrc.shell
@@ -0,0 +1,24 @@
+# $Id: test-wmbiffrc.shell,v 1.1 2002/03/06 07:15:08 bluehal Exp $
+#
+# test wmbiffrc for the shell command and gicu method.
+# see sample.wmbiffrc and wmbiffrc.5 as documentation for the format.
+#
+interval=10
+
+label.0=one
+path.0=shell:::echo 1
+
+label.1=two
+path.1=shell:::echo 2
+
+label.2=uptm
+path.2=shell:::uptime | awk '{print $3}'
+
+label.3=mem
+path.3=shell:::grep Mem: < /proc/meminfo | awk '{ print $3 " * 100 / " $2}' | bc
+
+label.3=gicu
+path.3=gicu:38673016
+
+label.4=nouin
+path.4=gicu:
diff --git a/wmbiff/tlsComm.c b/wmbiff/tlsComm.c
new file mode 100644
index 0000000..a49e5ac
--- /dev/null
+++ b/wmbiff/tlsComm.c
@@ -0,0 +1,451 @@
+/* tlsComm.c - primitive routines to aid TLS communication
+   within wmbiff, without rewriting each mailbox access
+   scheme.  These functions hide whether the underlying
+   transport is encrypted.
+
+   Neil Spring (nspring at cs.washington.edu) */
+
+/* TODO: handle "* BYE" internally? */
+
+#include <stdarg.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#ifdef WITH_TLS
+#include <gnutls.h>
+#endif
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#include "tlsComm.h"
+
+#include "Client.h"				/* debugging messages */
+
+/* WARNING: implcitly uses scs to gain access to the mailbox
+   that holds the per-mailbox debug flag. */
+#define TDM(lvl, args...) DM(scs->pc, lvl, "comm: " args)
+
+/* this is the per-connection state that is maintained for
+   each connection; BIG variables are for ssl (null if not
+   used). */
+#define BUF_SIZE 1024
+struct connection_state {
+	int sd;
+	char *name;
+#ifdef WITH_TLS
+	GNUTLS_STATE state;
+	X509PKI_CLIENT_CREDENTIALS xcred;
+#else
+	/*@null@ */ void *state;
+	/*@null@ */ void *xcred;
+#endif
+	char unprocessed[BUF_SIZE];
+	Pop3 pc;					/* mailbox handle for debugging messages */
+};
+
+/* gotta do our own line buffering, sigh */
+static int
+getline_from_buffer(char *readbuffer, char *linebuffer, int linebuflen);
+void handle_gnutls_read_error(int readbytes, struct connection_state *scs);
+
+void tlscomm_close(struct connection_state *scs)
+{
+	TDM(DEBUG_INFO, "%s: closing.\n",
+		(scs->name != NULL) ? scs->name : "null");
+
+	/* not ok to call this more than once */
+	if (scs->state) {
+#ifdef WITH_TLS
+		gnutls_bye(scs->state, GNUTLS_SHUT_RDWR);
+		gnutls_x509pki_free_sc(scs->xcred);
+		gnutls_deinit(scs->state);
+		scs->xcred = NULL;
+#endif
+	} else {
+		(void) close(scs->sd);
+	}
+	scs->sd = -1;
+	scs->state = NULL;
+	scs->xcred = NULL;
+	free(scs->name);
+	scs->name = NULL;
+	free(scs);
+}
+
+/* this avoids blocking without using non-blocking i/o */
+static int wait_for_it(int sd, int timeoutseconds)
+{
+	fd_set readfds;
+	struct timeval tv;
+	tv.tv_sec = timeoutseconds;
+	tv.tv_usec = 0;
+	FD_ZERO(&readfds);
+	FD_SET(sd, &readfds);
+	if (select(sd + 1, &readfds, NULL, NULL, &tv) == 0) {
+		DMA(DEBUG_INFO,
+			"select timed out after %d seconds on socket: %d\n",
+			timeoutseconds, sd);
+		return (0);
+	}
+	return (FD_ISSET(sd, &readfds));
+}
+
+static int
+getline_from_buffer(char *readbuffer, char *linebuffer, int linebuflen)
+{
+	char *p, *q;
+	int i;
+	/* find end of line (stopping if linebuflen is too small. */
+	for (p = readbuffer, i = 0;
+		 *p != '\n' && *p != '\0' && i < linebuflen - 1; p++, i++);
+
+	if (i != 0) {
+		/* grab the end of line too! */
+		i++;
+		/* copy a line into the linebuffer */
+		strncpy(linebuffer, readbuffer, (size_t) i);
+		/* sigh, null terminate */
+		linebuffer[i] = '\0';
+		/* shift the rest over; this could be done
+		   instead with strcpy... I think. */
+		q = readbuffer;
+		if (*p != '\0') {
+			p++;
+			do {
+				*(q++) = *(p++);
+			} while (*p != '\0');
+		}
+		/* null terminate */
+		*(q++) = *(p++);
+		/* return the length of the line */
+	}
+	return i;
+}
+
+/* eat lines, until one starting with prefix is found;
+   this skips 'informational' IMAP responses */
+/* the correct response to a return value of 0 is almost
+   certainly tlscomm_close(scs): don't _expect() anything
+   unless anything else would represent failure */
+int tlscomm_expect(struct connection_state *scs,
+				   const char *prefix, char *buf, int buflen)
+{
+	int prefixlen = (int) strlen(prefix);
+	memset(buf, 0, buflen);
+	TDM(DEBUG_INFO, "%s: expecting: %s\n", scs->name, prefix);
+	while (wait_for_it(scs->sd, 10)) {
+		int readbytes;
+#ifdef WITH_TLS
+		if (scs->state) {
+			readbytes =
+				gnutls_read(scs->state, scs->unprocessed, BUF_SIZE);
+			if (readbytes < 0) {
+				handle_gnutls_read_error(readbytes, scs);
+				return 0;
+			}
+		} else
+#endif
+		{
+			readbytes = read(scs->sd, scs->unprocessed, BUF_SIZE);
+			if (readbytes < 0) {
+				TDM(DEBUG_ERROR, "%s: error reading: %s\n", scs->name,
+					strerror(errno));
+				return 0;
+			}
+		}
+		if (readbytes == 0) {
+			return 0;			/* bummer */
+		} else
+			while (readbytes >= prefixlen) {
+				int linebytes;
+				linebytes =
+					getline_from_buffer(scs->unprocessed, buf, buflen);
+				if (linebytes == 0) {
+					readbytes = 0;
+				} else {
+					readbytes -= linebytes;
+					if (strncmp(buf, prefix, prefixlen) == 0) {
+						TDM(DEBUG_INFO, "%s: got: %*s", scs->name,
+							readbytes, buf);
+						return 1;	/* got it! */
+					}
+					TDM(DEBUG_INFO, "%s: dumped(%d/%d): %.*s", scs->name,
+						linebytes, readbytes, linebytes, buf);
+				}
+			}
+	}
+	TDM(DEBUG_ERROR, "%s: expecting: '%s', saw: '%s'\n", scs->name, prefix,
+		buf);
+	return 0;					/* wait_for_it failed */
+}
+
+int tlscomm_gets(char *buf, int buflen, struct connection_state *scs)
+{
+	return (tlscomm_expect(scs, "", buf, buflen));
+}
+
+void tlscomm_printf(struct connection_state *scs, const char *format, ...)
+{
+	va_list args;
+	char buf[1024];
+	int bytes;
+
+	if (scs == NULL) {
+		DMA(DEBUG_ERROR, "null connection to tlscomm_printf\n");
+		abort();
+	}
+	va_start(args, format);
+	bytes = vsnprintf(buf, 1024, format, args);
+	va_end(args);
+
+	if (scs->sd != -1) {
+#ifdef WITH_TLS
+		if (scs->state) {
+			int written = gnutls_write(scs->state, buf, bytes);
+			if (written < bytes) {
+				TDM(DEBUG_ERROR,
+					"Error %s prevented writing: %*s\n",
+					gnutls_strerror(written), bytes, buf);
+				return;
+			}
+		} else
+#endif
+			(void) write(scs->sd, buf, bytes);
+	} else {
+		printf
+			("warning: tlscomm_printf called with an invalid socket descriptor\n");
+		return;
+	}
+	TDM(DEBUG_INFO, "wrote %*s", bytes, buf);
+}
+
+/* most of this file only makes sense if using TLS. */
+#ifdef WITH_TLS
+
+/* taken from the GNUTLS documentation, version 0.3.0 and
+   0.2.10; this may need to be updated from gnutls's cli.c
+   (now common.h) if the gnutls interface changes, but that
+   is only necessary if you want debug_comm. */
+#define PRINTX(x,y) if (y[0]!=0) printf(" -   %s %s\n", x, y)
+#define PRINT_DN(X) PRINTX( "CN:", X.common_name); \
+	PRINTX( "OU:", X.organizational_unit_name); \
+	PRINTX( "O:", X.organization); \
+	PRINTX( "L:", X.locality_name); \
+	PRINTX( "S:", X.state_or_province_name); \
+	PRINTX( "C:", X.country); \
+	PRINTX( "E:", X.email)
+static int print_info(GNUTLS_STATE state)
+{
+	const char *tmp;
+	CredType cred;
+	gnutls_DN dn;
+	const gnutls_datum *cert_list;
+	CertificateStatus status;
+	int cert_list_size = 0;
+
+	tmp = gnutls_kx_get_name(gnutls_kx_get_algo(state));
+	printf("- Key Exchange: %s\n", tmp);
+
+	cred = gnutls_auth_get_type(state);
+	switch (cred) {
+	case GNUTLS_ANON:
+		printf("- Anonymous DH using prime of %d bits\n",
+			   gnutls_anon_client_get_dh_bits(state));
+		break;
+	case GNUTLS_X509PKI:
+		cert_list =
+			gnutls_x509pki_client_get_peer_certificate_list(state,
+															&cert_list_size);
+		status = gnutls_x509pki_client_get_peer_certificate_status(state);
+
+		switch (status) {
+		case GNUTLS_CERT_NOT_TRUSTED:
+			printf("- Peer's X509 Certificate was NOT verified\n");
+			break;
+		case GNUTLS_CERT_EXPIRED:
+			printf
+				("- Peer's X509 Certificate was verified but is expired\n");
+			break;
+		case GNUTLS_CERT_TRUSTED:
+			printf("- Peer's X509 Certificate was verified\n");
+			break;
+		case GNUTLS_CERT_NONE:
+			printf("- Peer did not send any X509 Certificate.\n");
+			break;
+		case GNUTLS_CERT_INVALID:
+			printf("- Peer's X509 Certificate was invalid\n");
+			break;
+		}
+
+		if (cert_list_size > 0) {
+			printf(" - Certificate info:\n");
+			printf(" - Certificate version: #%d\n",
+				   gnutls_x509pki_extract_certificate_version(&cert_list
+															  [0]));
+
+			gnutls_x509pki_extract_certificate_dn(&cert_list[0], &dn);
+			PRINT_DN(dn);
+
+			gnutls_x509pki_extract_certificate_issuer_dn(&cert_list[0],
+														 &dn);
+			printf(" - Certificate Issuer's info:\n");
+			PRINT_DN(dn);
+		}
+	default:
+		printf(" - Other.\n");
+	}
+
+	tmp = gnutls_protocol_get_name(gnutls_protocol_get_version(state));
+	printf("- Version: %s\n", tmp);
+
+	tmp = gnutls_compression_get_name(gnutls_compression_get_algo(state));
+	printf("- Compression: %s\n", tmp);
+
+	tmp = gnutls_cipher_get_name(gnutls_cipher_get_algo(state));
+	printf("- Cipher: %s\n", tmp);
+
+	tmp = gnutls_mac_get_name(gnutls_mac_get_algo(state));
+	printf("- MAC: %s\n", tmp);
+
+	return 0;
+}
+
+struct connection_state *initialize_gnutls(int sd, char *name, Pop3 pc)
+{
+	static int gnutls_initialized;
+	int zok;
+	struct connection_state *scs = malloc(sizeof(struct connection_state));
+
+	scs->pc = pc;
+
+	assert(sd >= 0);
+
+	if (gnutls_initialized == 0) {
+		assert(gnutls_global_init() == 0);
+		gnutls_initialized = 1;
+	}
+
+	assert(gnutls_init(&scs->state, GNUTLS_CLIENT) == 0);
+	{
+		const int protocols[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
+		const int ciphers[] =
+			{ GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR, 0 };
+		const int compress[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 };
+		const int key_exch[] = { GNUTLS_KX_X509PKI_RSA, 0 };
+		const int mac[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };
+		assert(gnutls_protocol_set_priority(scs->state, protocols) == 0);
+		assert(gnutls_cipher_set_priority(scs->state, ciphers) == 0);
+		assert(gnutls_compression_set_priority(scs->state, compress) == 0);
+		assert(gnutls_kx_set_priority(scs->state, key_exch) == 0);
+		assert(gnutls_mac_set_priority(scs->state, mac) == 0);
+		/* no client private key */
+		if (gnutls_x509pki_allocate_sc(&scs->xcred, 0) < 0) {
+			DMA(DEBUG_ERROR, "gnutls memory error\n");
+			exit(1);
+		}
+		gnutls_cred_set(scs->state, GNUTLS_X509PKI, scs->xcred);
+		gnutls_transport_set_ptr(scs->state, sd);
+		do {
+			zok = gnutls_handshake(scs->state);
+		} while (zok == GNUTLS_E_INTERRUPTED || zok == GNUTLS_E_AGAIN);
+	}
+
+	if (zok < 0) {
+		TDM(DEBUG_ERROR, "%s: Handshake failed\n", name);
+		TDM(DEBUG_ERROR, "%s: This may be a problem in gnutls, "
+			"which is under development\n", name);
+		TDM(DEBUG_ERROR,
+			"%s: Specifically, problems have been found where the extnValue \n"
+			"  buffer in _gnutls_get_ext_type() in lib/x509_extensions.c is too small in\n"
+			"  gnutls versions up to 0.2.3.  This copy of wmbiff was compiled with \n"
+			"  gnutls version %s.\n", name, LIBGNUTLS_VERSION);
+		gnutls_perror(zok);
+		gnutls_deinit(scs->state);
+		free(scs);
+		return (NULL);
+	} else {
+		TDM(DEBUG_INFO, "%s: Handshake was completed\n", name);
+		if (scs->pc->debug >= DEBUG_INFO)
+			print_info(scs->state);
+		scs->sd = sd;
+		scs->name = name;
+	}
+	return (scs);
+}
+
+/* moved down here, to keep from interrupting the flow with
+   verbose error crap */
+void handle_gnutls_read_error(int readbytes, struct connection_state *scs)
+{
+	if (gnutls_is_fatal_error(readbytes) == 1) {
+		TDM(DEBUG_ERROR,
+			"%s: Received corrupted data(%d) - server has terminated the connection abnormally\n",
+			scs->name, readbytes);
+	} else {
+		if (readbytes == GNUTLS_E_WARNING_ALERT_RECEIVED
+			|| readbytes == GNUTLS_E_FATAL_ALERT_RECEIVED)
+			TDM(DEBUG_ERROR, "* Received alert [%d]\n",
+				gnutls_alert_get_last(scs->state));
+		if (readbytes == GNUTLS_E_REHANDSHAKE)
+			TDM(DEBUG_ERROR, "* Received HelloRequest message\n");
+	}
+	TDM(DEBUG_ERROR,
+		"%s: error reading: %s\n", scs->name, gnutls_strerror(readbytes));
+}
+
+#else
+/* declare stubs when tls isn't compiled in */
+struct connection_state *initialize_gnutls( /*@unused@ */ int sd
+										   __attribute__ ((unused)),
+										   /*@unused@ */ char *name
+										   __attribute__ ((unused)),
+										   /*@unused@ */ Pop3 pc
+										   __attribute__ ((unused)))
+{
+	DM(pc, DEBUG_ERROR,
+	   "FATAL: tried to initialize ssl when ssl wasn't compiled in.\n");
+	exit(EXIT_FAILURE);
+}
+#endif
+
+/* either way: */
+struct connection_state *initialize_unencrypted(int sd,
+												/*@only@ */ char *name,
+												Pop3 pc)
+{
+	struct connection_state *ret = malloc(sizeof(struct connection_state));
+	assert(sd >= 0);
+	assert(ret != NULL);
+	ret->sd = sd;
+	ret->name = name;
+	ret->state = NULL;
+	ret->xcred = NULL;
+	ret->pc = pc;
+	return (ret);
+}
+
+/* bad seed connections that can't be setup */
+/*@only@*/
+struct connection_state *initialize_blacklist( /*@only@ */ char *name)
+{
+	struct connection_state *ret = malloc(sizeof(struct connection_state));
+	assert(ret != NULL);
+	ret->sd = -1;
+	ret->name = name;
+	ret->state = NULL;
+	ret->xcred = NULL;
+	ret->pc = NULL;
+	return (ret);
+}
+
+
+int tlscomm_is_blacklisted(const struct connection_state *scs)
+{
+	return (scs != NULL && scs->sd == -1);
+}
diff --git a/wmbiff/tlsComm.h b/wmbiff/tlsComm.h
new file mode 100644
index 0000000..4968e6c
--- /dev/null
+++ b/wmbiff/tlsComm.h
@@ -0,0 +1,55 @@
+/* tlsComm.h - interface for the thin layer that looks
+   sort of like fgets and fprintf, but might read or write
+   to a socket or a TLS association 
+
+   Neil Spring (nspring at cs.washington.edu)
+
+   Comments in @'s are for lclint's benefit:
+   http://lclint.cs.virginia.edu/
+*/
+
+/* used to drill through per-mailbox debug keys */
+#include "Client.h"
+
+/* opaque reference to the state associated with a 
+   connection: may be just a file handle, or may include
+   encryption state */
+struct connection_state;
+
+/* take a socket descriptor and negotiate a TLS connection
+   over it */
+/*@only@*/
+struct connection_state *initialize_gnutls(int sd, /*@only@ */ char *name,
+										   Pop3 pc);
+
+/* take a socket descriptor and bundle it into a connection
+   state structure for later communication */
+/*@only@*/
+struct connection_state *initialize_unencrypted(int sd,	/*@only@ */
+												char *name, Pop3 pc);
+
+/* store a binding when connect() times out. these should be 
+   skipped when trying to check mail so that other mailboxes
+   are checked responsively.  I believe linux defaults to 
+   around 90 seconds for a failed connect() attempt */
+/* TODO: engineer an eventual retry scheme */
+/*@only@*/
+struct connection_state *initialize_blacklist( /*@only@ */ char *name);
+int tlscomm_is_blacklisted(const struct connection_state *scs);
+
+/* just like fprintf, only takes a connection state structure */
+void tlscomm_printf(struct connection_state *scs, const char *format, ...);
+
+/* modeled after fgets; may not work exactly the same */
+int tlscomm_gets( /*@out@ */ char *buf,
+				 int buflen, struct connection_state *scs);
+
+/* gobbles lines until it finds one starting with {prefix},
+   which is returned in buf */
+int tlscomm_expect(struct connection_state *scs, const char *prefix,
+				   /*@out@ */ char *buf,
+				   int buflen);
+
+/* terminates the TLS association or just closes the socket,
+   and frees the connection state */
+void tlscomm_close( /*@only@ */ struct connection_state *scs);
diff --git a/wmbiff/wmbiff-master-led.xpm b/wmbiff/wmbiff-master-led.xpm
index 1397475..0f6293d 100644
--- a/wmbiff/wmbiff-master-led.xpm
+++ b/wmbiff/wmbiff-master-led.xpm
@@ -1,5 +1,5 @@
 /* XPM */
-static char * wmbiff_master_xpm[] = {
+static const char * wmbiff_master_xpm[] = {
 "160 100 15 1",
 " 	c #00000000FFFF",
 ".	c #208120812081",
diff --git a/wmbiff/wmbiff-master.xpm b/wmbiff/wmbiff-master.xpm
deleted file mode 120000
index 59729ba..0000000
--- a/wmbiff/wmbiff-master.xpm
+++ /dev/null
@@ -1 +0,0 @@
-wmbiff-master-led.xpm
\ No newline at end of file
diff --git a/wmbiff/wmbiff.1 b/wmbiff/wmbiff.1
new file mode 100644
index 0000000..258f362
--- /dev/null
+++ b/wmbiff/wmbiff.1
@@ -0,0 +1,88 @@
+.\" Hey, Emacs!  This is an -*- nroff -*- source file.
+.\" $Id: wmbiff.1,v 1.7 2002/03/06 07:15:08 bluehal Exp $
+.\"
+.\" wmbiff.1 and wmbiffrc.5 are copyright 1999-2001 by
+.\" Jordi Mallach <jordi at debian.org>
+.\"
+.\" This is free documentation, see the latest version of the GNU
+.\" General Public License for copying conditions. There is NO warranty.
+.TH WMBIFF 1 "October 4, 2001" "wmbiff"
+
+.SH NAME
+WMBiff \- A dockable Mailbox Monitor
+
+.SH SYNOPSIS
+.B wmbiff
+[-display <display name>] [-geometry +XPOS+YPOS] [-c <filename>] [-h] [-v] [-debug]
+.br
+
+.SH DESCRIPTION
+WMbiff displays the status of up to five mailboxes. It gives information
+about new mail, if any, or total number of messages. It also has mail
+retrieval capabilies, and can be configured to do this automatically. At the
+moment, UNIX-style, maildir, POP3, APOP and IMAP4 mailboxes are supported.
+WMbiff also supports Licq history files and gnomeicu, displaying the number of new
+messages in your running session, as if they were mail.  
+
+The mailboxes are displayed in 5 different lines, each one with its own
+description of up to five chars. If no mail is present in a given mailbox,
+WMbiff will display the total number of mails in cyan. If there's new mail
+in the box, the number of new messages will be displayed in yellow. When new
+mail arrives, this number will optionally flash for a small period of time,
+and also optionally, a command can be executed on mail arrival (for example,
+opening your mail reader or playing a sound file).
+
+Pressing mouse button 1 will execute a command, defined in the user's config
+file. Mouse button 3 will execute a command to fetch mail, if defined.
+.PP
+
+.SH OPTIONS
+.TP
+.B \-h
+Show summary of options.
+.TP
+.B \-v
+Show version of program.
+.TP
+.B \-display <display name>
+Use an alternate X Display.
+.TP
+.B \-geometry <geometry>
+Initial window position.
+.TP
+.B \-c <filename>
+Use specified config file.
+.TP
+.B \-debug 
+Print verbose log of progress.
+
+.SH BUGS
+Send bug reports or suggestions to the WMBiff Development
+Mailing List <wmbiff-devel at lists.sourceforge.net>.   Consider
+attaching a transcript of your session, generated using:
+.RS
+wmbiff -debug | tee wmbiff-log
+.RE
+Be sure to remove any instances of your password.
+
+.SH FILES
+.TP
+.I ~/.wmbiffrc
+peruser wmbiff configuration file.
+
+.SH AUTHOR
+This manual page was written by Jordi Mallach <jordi at sindominio.net>,
+originally for the Debian GNU/Linux system (but may be used by others).
+.br
+WMBiff was first maintained by Gennady Belyakov. Since January 2001 it is
+maintained group of people that have added lots of new features to the
+original program. Please see the README document for a list of all the people
+involved.
+
+.SH SEE ALSO
+.PD 0
+.TP
+\fBwmbiffrc\fP(5)
+.PP
+\fI/usr/share/doc/wmbiff/examples/sample.wmbiffrc\fP
+(or equivalent for your system)
diff --git a/wmbiff/wmbiff.c b/wmbiff/wmbiff.c
index 08652c8..f836fc0 100644
--- a/wmbiff/wmbiff.c
+++ b/wmbiff/wmbiff.c
@@ -1,624 +1,558 @@
-#include <stdlib.h>
-#include <stdio.h>
+/* $Id: wmbiff.c,v 1.17 2002/03/06 07:59:24 bluehal Exp $ */
+
+#define	USE_POLL
+
 #include <time.h>
-#include <utime.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
 #include <ctype.h>
-#include <errno.h>
-#include <signal.h>
 
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/param.h>
+#ifdef USE_POLL
+#include <poll.h>
+#else
 #include <sys/time.h>
+#endif
+
+#include <sys/wait.h>
 #include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
+#include <signal.h>
 
 #include <X11/Xlib.h>
 #include <X11/xpm.h>
-#include <X11/extensions/shape.h>
+
+#include <errno.h>
 
 #include "../wmgeneral/wmgeneral.h"
 #include "../wmgeneral/misc.h"
 
-#include "Pop3Client.h"
+#include "Client.h"
+#include "charutil.h"
 
-#include "wmbiff-master.xpm"
-char wmbiff_mask_bits[64*64];
-int  wmbiff_mask_width = 64;
-int  wmbiff_mask_height = 64;
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
 
-#define WMBIFF_VERSION "0.2"
+#include "wmbiff-master.xpm"
+char wmbiff_mask_bits[64 * 64];
+const int wmbiff_mask_width = 64;
+const int wmbiff_mask_height = 64;
 
 #define CHAR_WIDTH  5
 #define CHAR_HEIGHT 7
 
-#define BUFFER_SIZE 1024
-
 #define BLINK_TIMES 8
 #define DEFAULT_SLEEP_INTERVAL 1000
 #define BLINK_SLEEP_INTERVAL    200
-
-#define FROM_STR   "From "
-#define STATUS_STR "Status: R"
-
-#undef DEBUG
-#undef DEBUG_MAIL_COUNT
-#undef DEBUG_POP3
-
-int loopinterval=5;	/* Default rescan interval, in seconds */
-int Sleep_Interval = DEFAULT_SLEEP_INTERVAL;	/* Default sleep time, in milliseconds */
-int Blink_Mode = 0;	/* Bit mask, digits are ib blinking mode or not. Each bit for separate mailbox */
-
-typedef struct {
-  char label[32];	/* Printed at left; max 5 chars */
-  char path[256];	/* Path to mailbox */
-  char notify[256];	/* Program to notify mail arrivation */
-  char action[256];	/* Action to execute on mouse click */
-  char fetchcmd[256];	/* Action for mail fetching for pop3/imap */
-  int  fetchinterval;
-  int  TotalMsgs;	/* Total messages in mailbox */
-  int  UnReadMsgs;	/* New (unread) messages in mailbox */
-  int  OldMsgs;
-  int  OldUnReadMsgs;
-  int  blink_stat;	/* blink digits flag-counter */
-  time_t ctime;
-  time_t mtime;
-  size_t size;
-  Pop3 pc;
-  time_t prevtime;
-  time_t prevfetch_time;
-  int  loopinterval;	/* loop interval for this mailbox */
-} mbox_t;
+#define DEFAULT_LOOP 5
 
 mbox_t mbox[5];
 
-char uconfig_file[256];
+int ReadLine(FILE *, char *, char *, int *);
+int Read_Config_File(char *, int *);
+int count_mail(int);
+void parse_cmd(int, char **, char *);
+void init_biff(char *);
+void displayMsgCounters(int, int, int *, int *);
 
 void usage(void);
 void printversion(void);
-void parse_cmd(int argc, char **argv);
-void init_biff(int argc, char **argv);
-void do_biff(int argc, char **argv);
-void displayMsgCounters(int i, int mail_stat);
-int  ReadConfigInt(FILE *fp, char *setting, int *value);
-int  ReadConfigString(FILE *fp, char *setting, char *value);
-int  Read_Config_File( char *filename );
+void do_biff(int argc, char **argv) __attribute__ ((noreturn));
 void parse_mbox_path(int item);
-FILE *open_mailbox_file(char *file);
-int  count_mail(int item, int init);
-void count_messages(FILE *file, int item);
-void BlitString(char *name, int x, int y, int new);
+static void BlitString(const char *name, int x, int y, int new);
 void BlitNum(int num, int x, int y, int new);
 void ClearDigits(int i);
-void BlinkOn(int i);
-void BlinkOff(int i);
-void BlinkToggle(int i);
 void XSleep(int millisec);
 void sigchld_handler(int sig);
 
+int debug_default = DEBUG_ERROR;
 
-void init_biff(int argc, char **argv)
+void init_biff(char *uconfig_file)
 {
-  int	i,j;
-  char	config_file[512];
-  char  *m;
-
-  /* Some defaults, if config file unavailable */
-  strcpy(mbox[0].label,"Spool");
-  if( (m=getenv("MAIL")) != NULL ) {
-    strcpy(mbox[0].path, m);
-  }
-  else if( (m=getenv("USER")) != NULL ) {
-    strcpy(mbox[0].path, "/var/spool/mail/");
-    strcat(mbox[0].path, m);
-  }
-  mbox[0].notify[0]=0;
-  mbox[0].action[0]=0;
-  mbox[0].fetchcmd[0]=0;
-  mbox[0].pc=NULL;
-  mbox[0].loopinterval=loopinterval;
-  mbox[0].OldMsgs = mbox[0].OldUnReadMsgs = -1;
-  for(i=1; i<5; i++) {
-    mbox[i].label[0]=0;
-    mbox[i].path[0]=0;
-    mbox[i].notify[0]=0;
-    mbox[i].action[0]=0;
-    mbox[i].fetchcmd[0]=0;
-    mbox[i].pc = NULL;
-    mbox[i].loopinterval=loopinterval;
-    mbox[i].OldMsgs = mbox[i].OldUnReadMsgs = -1;
-  }
-
-  /* Read config file */
-  if (uconfig_file[0] != 0) {
-    /* user-specified config file */
-    fprintf(stderr, "Using user-specified config file '%s'.\n", uconfig_file);
-    Read_Config_File(uconfig_file);
-  }
-  else {
-    sprintf(config_file, "%s/.wmbiffrc", getenv("HOME"));
-    if (!Read_Config_File(config_file) || m == NULL) {
-      fprintf(stderr, "Cannot open '%s' nor use the MAIL environment var.\n", uconfig_file);
-      exit(1);
-    }
-  }
-
-  /* Make labels looks correctly */
-  for(i=0; i<5; i++) {
-    if(mbox[i].label[0] != 0) {
-      for(j=0; j<5; j++)
-	if(mbox[i].label[j] == 0)
-	  mbox[i].label[j] = ' ';
-      mbox[i].label[5]=':';
-      mbox[i].label[6]=0;
-    }
-  }
+	int i, j, loopinterval = DEFAULT_LOOP;
+	char config_file[256];
+	char *m;
+
+	for (i = 0; i < 5; i++) {
+		mbox[i].label[0] = 0;
+		mbox[i].path[0] = 0;
+		mbox[i].notify[0] = 0;
+		mbox[i].action[0] = 0;
+		mbox[i].fetchcmd[0] = 0;
+		mbox[i].loopinterval = 0;
+		mbox[i].debug = debug_default;
+	}
+
+	/* Some defaults, if config file is unavailable */
+	strcpy(mbox[0].label, "Spool");
+	if ((m = getenv("MAIL")) != NULL) {
+		strcpy(mbox[0].path, m);
+	} else if ((m = getenv("USER")) != NULL) {
+		strcpy(mbox[0].path, "/var/mail/");
+		strcat(mbox[0].path, m);
+	}
+#ifdef WITH_GCRYPT
+	/* gcrypt is a little strange, in that it doesn't 
+	 * seem to initialize its memory pool by itself. 
+	 * I believe we *expect* "Warning: using insecure memory!"
+	 */
+	if ((i = gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0)) != 0) {
+		DMA(DEBUG_ERROR,
+			"Error: gcry_control() to initialize secure memory returned non-zero: %d\n"
+			" Message: %s\n"
+			" libgcrypt version: %s\n"
+			" recovering: will fail later if using CRAM-MD5 or APOP authentication.\n",
+			i, gcry_strerror(gcry_errno()), gcry_check_version(NULL));
+	};
+#endif
+
+	/* Read config file */
+	if (uconfig_file[0] != 0) {
+		/* user-specified config file */
+		DMA(DEBUG_INFO, "Using user-specified config file '%s'.\n",
+			uconfig_file);
+		strcpy(config_file, uconfig_file);
+	} else
+		sprintf(config_file, "%s/.wmbiffrc", getenv("HOME"));
+
+	DMA(DEBUG_INFO, "config_file = %s.\n", config_file);
+
+	if (!Read_Config_File(config_file, &loopinterval)) {
+		if (m == NULL) {
+			DMA(DEBUG_ERROR, "Cannot open '%s' nor use the "
+				"MAIL environment var.\n", uconfig_file);
+			exit(1);
+		}
+		/* we are using MAIL environment var. type mbox */
+		DMA(DEBUG_INFO, "Using MAIL environment var '%s'.\n", m);
+		mboxCreate((&mbox[0]), mbox[0].path);
+	}
+
+	/* Make labels look right */
+	for (i = 0; i < 5; i++) {
+		if (mbox[i].label[0] != 0) {
+			j = strlen(mbox[i].label);
+			if (j < 5) {
+				memset(mbox[i].label + j, ' ', 5 - j);
+			}
+			mbox[i].label[5] = ':';
+			mbox[i].label[6] = 0;
+			/* set global loopinterval to boxes with 0 loop */
+			if (!mbox[i].loopinterval) {
+				mbox[i].loopinterval = loopinterval;
+			}
+		}
+	}
 }
 
 void do_biff(int argc, char **argv)
 {
-  int	i;
-  XEvent Event;
-  int	but_stat = -1;
-  time_t curtime;
-  int	NeedRedraw = 0;
-  
-  createXBMfromXPM(wmbiff_mask_bits, wmbiff_master_xpm, wmbiff_mask_width, wmbiff_mask_height);
-  
-  openXwindow(argc, argv, wmbiff_master_xpm, wmbiff_mask_bits, wmbiff_mask_width, wmbiff_mask_height);
-
-  AddMouseRegion(0, 5,  6, 58, 16);
-  AddMouseRegion(1, 5, 16, 58, 26);
-  AddMouseRegion(2, 5, 26, 58, 36);
-  AddMouseRegion(3, 5, 36, 58, 46);
-  AddMouseRegion(4, 5, 46, 58, 56);
-
-/*  copyXPMArea(39, 84, (3*CHAR_WIDTH), 8, 39, 5);  */
-/*  copyXPMArea(39, 84, (3*CHAR_WIDTH), 8, 39, 16); */
-/*  copyXPMArea(39, 84, (3*CHAR_WIDTH), 8, 39, 27); */
-/*  copyXPMArea(39, 84, (3*CHAR_WIDTH), 8, 39, 38); */
-/*  copyXPMArea(39, 84, (3*CHAR_WIDTH), 8, 39, 49); */
-	      
-/*  BlitString("XX", 45, 5,  0); */
-/*  BlitString("XX", 45, 16, 0); */
-/*  BlitString("XX", 45, 27, 0); */
-/*  BlitString("XX", 45, 38, 0); */
-/*  BlitString("XX", 45, 49, 0); */
-
-  /* Initially read mail counters and resets; and initially draw labels and counters */
-  curtime = time(0);
-  for (i=0; i<5; i++) {
-    if(mbox[i].label[0] != 0) {
-      mbox[i].prevtime = mbox[i].prevfetch_time = curtime;
-      BlitString(mbox[i].label, 5, (11*i) + 5, 0); 
-      displayMsgCounters( i, count_mail(i, 1));
-#ifdef DEBUG
-    printf ("[%d].label=>%s<\n[%d].path=>%s<\n\n",i,mbox[i].label,i,mbox[i].path);
+	int i;
+	XEvent Event;
+	int but_stat = -1;
+	time_t curtime;
+	int NeedRedraw = 0;
+	int Sleep_Interval = DEFAULT_SLEEP_INTERVAL;	/* Default sleep time (in msec) */
+	int Blink_Mode = 0;			/* Bit mask, digits are in blinking mode or not.
+								   Each bit for separate mailbox */
+
+
+	createXBMfromXPM(wmbiff_mask_bits, wmbiff_master_xpm,
+					 wmbiff_mask_width, wmbiff_mask_height);
+
+	openXwindow(argc, argv, wmbiff_master_xpm, wmbiff_mask_bits,
+				wmbiff_mask_width, wmbiff_mask_height);
+
+	AddMouseRegion(0, 5, 6, 58, 16);
+	AddMouseRegion(1, 5, 16, 58, 26);
+	AddMouseRegion(2, 5, 26, 58, 36);
+	AddMouseRegion(3, 5, 36, 58, 46);
+	AddMouseRegion(4, 5, 46, 58, 56);
+
+#if 0
+	copyXPMArea(39, 84, (3 * CHAR_WIDTH), 8, 39, 5);
+	copyXPMArea(39, 84, (3 * CHAR_WIDTH), 8, 39, 16);
+	copyXPMArea(39, 84, (3 * CHAR_WIDTH), 8, 39, 27);
+	copyXPMArea(39, 84, (3 * CHAR_WIDTH), 8, 39, 38);
+	copyXPMArea(39, 84, (3 * CHAR_WIDTH), 8, 39, 49);
+
+	BlitString("XX", 45, 5, 0);
+	BlitString("XX", 45, 16, 0);
+	BlitString("XX", 45, 27, 0);
+	BlitString("XX", 45, 38, 0);
+	BlitString("XX", 45, 49, 0);
 #endif
-    }		  
-  }
-  
-  RedrawWindow();
-  
-  NeedRedraw = 0;
-  while (1) {
-    /* waitpid(0, NULL, WNOHANG); */
-  
-    for (i=0; i<5; i++) {
-      if(mbox[i].label[0] != 0) {
+
+	/* Initially read mail counters and resets,
+	   and initially draw labels and counters */
 	curtime = time(0);
-	if( curtime >= mbox[i].prevtime+mbox[i].loopinterval ) {
-	  NeedRedraw = 1;
-	  mbox[i].prevtime = curtime;
-	  displayMsgCounters(i, count_mail(i, 0));
-#ifdef DEBUG
-	  printf("[%d].label=>%s<\n[%d].path=>%s<\n\n",i,mbox[i].label,i,mbox[i].path);
-	  printf("curtime=%d, prevtime=%d, interval=%d\n",curtime, mbox[i].prevtime,mbox[i].loopinterval);
-#endif
+	for (i = 0; i < 5; i++) {
+		if (mbox[i].label[0] != 0) {
+			mbox[i].prevtime = mbox[i].prevfetch_time = curtime;
+			BlitString(mbox[i].label, 5, (11 * i) + 5, 0);
+			DM(&mbox[i], DEBUG_INFO,
+			   "working on [%d].label=>%s< [%d].path=>%s<\n", i,
+			   mbox[i].label, i, mbox[i].path);
+			displayMsgCounters(i, count_mail(i), &Sleep_Interval,
+							   &Blink_Mode);
+		}
 	}
-      }
-      if(mbox[i].blink_stat > 0) {
-	BlinkToggle(i);
-	displayMsgCounters(i, 1);
-	NeedRedraw = 1;
-	/**/printf("i= %d, Sleep_Interval= %d\n", i, Sleep_Interval);
-      }
-      if(Blink_Mode == 0) {
-	BlinkOff(i);
-      }
-      if( mbox[i].fetchinterval > 0 && mbox[i].fetchcmd[0] != 0 &&
-	  curtime >= mbox[i].prevfetch_time+mbox[i].fetchinterval ) {
-	execCommand(mbox[i].fetchcmd);
-	mbox[i].prevfetch_time = curtime;
-      }
-    }
-    if( NeedRedraw ) {
-      NeedRedraw = 0;
-      RedrawWindow();
-    }
-    
-    /* X Events */
-    while(XPending(display)) {
-      XNextEvent(display, &Event);
-      switch(Event.type) {
-	case Expose:
-	  RedrawWindow();
-	  break;
-	case DestroyNotify:
-	  XCloseDisplay(display);
-	  exit(0);
-	  break;
-	case ButtonPress:
-	  i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
-	  but_stat = i;
-	  break;
-	case ButtonRelease:
-	  i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
-	  if ( but_stat == i && but_stat >= 0 ) {
-	    switch(Event.xbutton.button) {
-	    case 1:					/* Left-mouse click */
-	      if(mbox[but_stat].action[0] != 0)
-		execCommand(mbox[but_stat].action);
-	      break;
-	    case 3:					/* right-mouse click */
-	      if(mbox[but_stat].fetchcmd[0] != 0)
-		execCommand(mbox[but_stat].fetchcmd);
-	      break;
-	    }
-	  }
-	  but_stat = -1;
-/*	    RedrawWindow(); */
-	  break;
-      }
-    }
-    XSleep(Sleep_Interval);
-  }
-}
 
-void displayMsgCounters(int i, int mail_stat)
-{
-  switch( mail_stat) {
-  case 2:						/* New mail has arrived */
-    BlinkOn(i);						/* Enter blink-mode for digits */
-    ClearDigits(i);					/* Clear digits */
-    if((mbox[i].blink_stat&0x01) == 0)
-      BlitNum(mbox[i].UnReadMsgs, 45, (11*i) + 5, 1);	/* Yellow digits */
-    if(mbox[i].notify[0] != 0) {			/* need to call notify ? */
-      if(!strcasecmp(mbox[i].notify,"beep"))		/* Internal keyword ? */
-	XBell(display,100);				/* Yes, bell */
-      else
-	execCommand(mbox[i].notify);			/* Else call external notifyer */
-    }
-    if(mbox[i].fetchinterval == -1 && mbox[i].fetchcmd[0] != 0)	/* Autofetch on new mail arrival ? */
-      execCommand(mbox[i].fetchcmd);			/* yes */
-    break;
-  case 1:						/* mailbox has been rescanned/changed */
-    ClearDigits(i);					/* Clear digits */
-    if((mbox[i].blink_stat&0x01) == 0) {
-      if(mbox[i].UnReadMsgs > 0)			/* New mail arrived */
-	BlitNum(mbox[i].UnReadMsgs, 45, (11*i) + 5, 1);	/* Yellow digits */
-      else
-	BlitNum(mbox[i].TotalMsgs,  45, (11*i) + 5, 0);	/* Cyan digits */
-    }
-    break;
-  case 0:
-    break;
-  case -1:						/* Error was detected */
-    ClearDigits(i);					/* Clear digits */
-    BlitString("XX", 45, (11*i) + 5, 0);
-    break;
-  }
+	RedrawWindow();
+
+	NeedRedraw = 0;
+	while (1) {
+		/* waitpid(0, NULL, WNOHANG); */
+
+		for (i = 0; i < 5; i++) {
+			if (mbox[i].label[0] != 0) {
+				curtime = time(0);
+				if (curtime >= mbox[i].prevtime + mbox[i].loopinterval) {
+					NeedRedraw = 1;
+					DM(&mbox[i], DEBUG_INFO,
+					   "working on [%d].label=>%s< [%d].path=>%s<\n", i,
+					   mbox[i].label, i, mbox[i].path);
+					DM(&mbox[i], DEBUG_INFO,
+					   "curtime=%d, prevtime=%d, interval=%d\n",
+					   (int) curtime, (int) mbox[i].prevtime,
+					   mbox[i].loopinterval);
+					mbox[i].prevtime = curtime;
+					displayMsgCounters(i, count_mail(i), &Sleep_Interval,
+									   &Blink_Mode);
+				}
+			}
+			if (mbox[i].blink_stat > 0) {
+				if (--mbox[i].blink_stat <= 0) {
+					Blink_Mode &= ~(1 << i);
+					mbox[i].blink_stat = 0;
+				}
+				displayMsgCounters(i, 1, &Sleep_Interval, &Blink_Mode);
+				NeedRedraw = 1;
+			}
+			if (Blink_Mode == 0) {
+				mbox[i].blink_stat = 0;
+				Sleep_Interval = DEFAULT_SLEEP_INTERVAL;
+			}
+			if (mbox[i].fetchinterval > 0 && mbox[i].fetchcmd[0] != 0
+				&& curtime >=
+				mbox[i].prevfetch_time + mbox[i].fetchinterval) {
+				execCommand(mbox[i].fetchcmd);
+				mbox[i].prevfetch_time = curtime;
+			}
+		}
+		if (NeedRedraw) {
+			NeedRedraw = 0;
+			RedrawWindow();
+		}
+
+		/* X Events */
+		while (XPending(display)) {
+			XNextEvent(display, &Event);
+			switch (Event.type) {
+			case Expose:
+				RedrawWindow();
+				break;
+			case DestroyNotify:
+				XCloseDisplay(display);
+				exit(0);
+				break;
+			case ButtonPress:
+				i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
+				but_stat = i;
+				break;
+			case ButtonRelease:
+				i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
+				if (but_stat == i && but_stat >= 0) {
+					switch (Event.xbutton.button) {
+					case 1:	/* Left mouse-click */
+						if (mbox[but_stat].action[0] != 0) {
+							execCommand(mbox[but_stat].action);
+						}
+						break;
+					case 3:	/* Right mouse-click */
+						if (mbox[but_stat].fetchcmd[0] != 0) {
+							execCommand(mbox[but_stat].fetchcmd);
+						}
+						break;
+					}
+				}
+				but_stat = -1;
+				/* RedrawWindow(); */
+				break;
+			}
+		}
+		XSleep(Sleep_Interval);
+	}
 }
 
-FILE *open_mailbox_file (char *file)
+void displayMsgCounters(int i, int mail_stat, int *Sleep_Interval,
+						int *Blink_Mode)
 {
-  FILE *mailbox;
-
-  if ( (mailbox = fopen(file, "r")) == NULL ) {
-    fprintf(stderr,"wmbiff: Error opening mailbox '%s': %s\n", file, strerror(errno));
-  }
-  return (mailbox);
+	switch (mail_stat) {
+	case 2:					/* New mail has arrived */
+		/* Enter blink-mode for digits */
+		mbox[i].blink_stat = BLINK_TIMES * 2;
+		*Sleep_Interval = BLINK_SLEEP_INTERVAL;
+		*Blink_Mode |= (1 << i);	/* Global blink flag set for this mailbox */
+		ClearDigits(i);			/* Clear digits */
+		if ((mbox[i].blink_stat & 0x01) == 0) {
+			BlitNum(mbox[i].UnreadMsgs, 45, (11 * i) + 5, 1);	/* Yellow digits */
+		}
+		if (mbox[i].notify[0] != 0) {	/* need to call notify() ? */
+			if (!strcasecmp(mbox[i].notify, "beep")) {	/* Internal keyword ? */
+				XBell(display, 100);	/* Yes, bell */
+			} else {
+				execCommand(mbox[i].notify);	/* Else call external notifyer */
+			}
+		}
+
+		/* Autofetch on new mail arrival? */
+		if (mbox[i].fetchinterval == -1 && mbox[i].fetchcmd[0] != 0) {
+			execCommand(mbox[i].fetchcmd);	/* yes */
+		}
+		break;
+	case 1:					/* mailbox has been rescanned/changed */
+		ClearDigits(i);			/* Clear digits */
+		if ((mbox[i].blink_stat & 0x01) == 0) {
+			if (mbox[i].UnreadMsgs > 0) {	/* New mail arrived */
+				BlitNum(mbox[i].UnreadMsgs, 45, (11 * i) + 5, 1);	/* Yellow digits */
+			} else {
+				BlitNum(mbox[i].TotalMsgs, 45, (11 * i) + 5, 0);	/* Cyan digits */
+			}
+		}
+		break;
+	case 0:
+		break;
+	case -1:					/* Error was detected */
+		ClearDigits(i);			/* Clear digits */
+		BlitString("XX", 45, (11 * i) + 5, 0);
+		break;
+	}
 }
-                             
+
 /** counts mail in spool-file
-   if "init" is >0, messages counted even if mailbox isn't changed (for unix-style)
    Returned value:
    -1 : Error was encountered
    0  : mailbox status wasn't changed
    1  : mailbox was changed (NO new mail)
    2  : mailbox was changed AND new mail has arrived
 **/
-int count_mail(int item, int init)
+int count_mail(int item)
 {
-  struct stat	  st;
-  struct utimbuf  ut;
-  FILE  *F;
-  int    rc = 0;
+	int rc = 0;
 
-#ifdef DEBUG_MAIL_COUNT
-  printf(">Mailbox: '%s'\n",mbox[item].path);
-#endif
-  if(mbox[item].pc == NULL) {		/* ubix-style mailbox */
-    if(stat(mbox[item].path, &st)) {
-/*      if( errno != ENOENT )  */
-	fprintf(stderr,"wmbiff: Can't stat mailbox '%s': %s\n", mbox[item].path, strerror(errno));
-      return -1;			/* Error stating mailbox */
-    }
-
-    if(st.st_mtime != mbox[item].mtime || st.st_size != mbox[item].size || init > 0)  {  /* file was changed OR initially read */
-#ifdef DEBUG_MAIL_COUNT
-      printf("  was changed,"
-	     " TIME: old %lu, new %lu"
-	     " SIZE: old %lu, new %lu\n",
-	     mbox[item].mtime,st.st_mtime,
-	     mbox[item].size,st.st_size);
-#endif
-      ut.actime  = st.st_atime;
-      ut.modtime = st.st_mtime;
-      F = open_mailbox_file(mbox[item].path);
-      count_messages(F, item);					/* No comments :) */
-      fclose(F);
-      utime(mbox[item].path, &ut);				/* Reset atime for MUTT and something others correctly work */
-      mbox[item].mtime = st.st_mtime;				/* Store new mtime */
-      mbox[item].size  = st.st_size;				/* Store new size */
-    }
-  }
-  else {							/* pop3 */
-    if( pop3MakeConnection(mbox[item].pc) == -1 ) {
-      return -1;
-    }
-    if( pop3Login(mbox[item].pc) == -1 ) {
-      pop3Quit(mbox[item].pc);
-      return -1;
-    }
-    if( (pop3CheckMail(mbox[item].pc)) == -1){
-      pop3Quit(mbox[item].pc);
-      return -1;						/* Error connecting to pop3 server */
-    }
-    else{
-      mbox[item].UnReadMsgs = pop3GetNumberOfUnreadMessages(mbox[item].pc);
-      mbox[item].TotalMsgs  = pop3GetTotalNumberOfMessages(mbox[item].pc);
-#ifdef DEBUG_POP3
-      printf("OLD: %d, TOTAL: %d, NEW: %d\n",mbox[item].OldMsgs,mbox[item].TotalMsgs,mbox[item].UnReadMsgs);
-#endif
-      pop3Quit(mbox[item].pc);
-    }
-  }
-  if(mbox[item].UnReadMsgs > mbox[item].OldUnReadMsgs && mbox[item].UnReadMsgs > 0)
-    rc = 2;							/* New mail detected */
-  else if(mbox[item].UnReadMsgs < mbox[item].OldUnReadMsgs ||
-	  mbox[item].TotalMsgs != mbox[item].OldMsgs)
-    rc = 1;							/* mailbox was changed - NO new mail */
-  else
-    rc = 0;							/* mailbox wasn't changed */
-  mbox[item].OldMsgs 	   = mbox[item].TotalMsgs;
-  mbox[item].OldUnReadMsgs = mbox[item].UnReadMsgs;
-  return rc;
-}
+	if (!mbox[item].checkMail) {
+		return -1;
+	}
 
-void count_messages(FILE *file, int item)
-{
-  int is_header = 0;
-  int next_from_is_start_of_header = 1;
-  int count_from = 0, count_status = 0;
-  char buf[BUFFER_SIZE];
-  int len_from = strlen(FROM_STR), len_status = strlen(STATUS_STR);
-
-  while(fgets(buf, BUFFER_SIZE, file)) {
-    if (buf[0] == '\n') {	/* a newline on itself terminates the header */
-      if (is_header) is_header = 0;
-      else next_from_is_start_of_header = 1;
-    }
-    else if(!strncmp(buf, FROM_STR, len_from))  {
-      /* a line starting with "From" is the beginning of a new header 
-         "From" in the text of the mail should get escaped by the MDA.
-         If your MDA doesn't he is broken.
-	*/
-      if (next_from_is_start_of_header) is_header = 1;
-      if (is_header) count_from++;
-    } 
-    else {
-      next_from_is_start_of_header = 0;
-      if(!strncmp(buf, STATUS_STR, len_status)) {
-#ifdef DEBUG_MAIL_COUNT
-/*	printf ("Got a status: %s",buf); */
-#endif
-	if (is_header) count_status++;
-      }
-    }
-  }
-#ifdef DEBUG_MAIL_COUNT
-  printf ("from: %d status: %d\n", count_from, count_status);
-#endif
-  mbox[item].TotalMsgs = count_from;
-  mbox[item].UnReadMsgs = count_from-count_status;
-  return;
+	if (mbox[item].checkMail(&(mbox[item])) < 0) {
+		/* we failed to obtain any numbers
+		 * therefore set them to -1's
+		 * ensuring the next pass (even if zero)
+		 * will be captured correctly
+		 */
+		mbox[item].TotalMsgs = -1;
+		mbox[item].UnreadMsgs = -1;
+		mbox[item].OldMsgs = -1;
+		mbox[item].OldUnreadMsgs = -1;
+		return -1;
+	}
+
+	if (mbox[item].UnreadMsgs > mbox[item].OldUnreadMsgs &&
+		mbox[item].UnreadMsgs > 0) {
+		rc = 2;					/* New mail detected */
+	} else if (mbox[item].UnreadMsgs < mbox[item].OldUnreadMsgs ||
+			   mbox[item].TotalMsgs != mbox[item].OldMsgs) {
+		rc = 1;					/* mailbox was changed - NO new mail */
+	} else {
+		rc = 0;					/* mailbox wasn't changed */
+	}
+	mbox[item].OldMsgs = mbox[item].TotalMsgs;
+	mbox[item].OldUnreadMsgs = mbox[item].UnreadMsgs;
+	return rc;
 }
 
 /* Blits a string at given co-ordinates
    If a ``new'' parameter is given, all digits will be yellow
 */
-void BlitString(char *name, int x, int y, int new)
+static void BlitString(const char *name, int x, int y, int new)
 {
-  int	i, c, k = x;
-
-  for(i=0; name[i]; i++) {
-    c = toupper(name[i]); 
-    if(c >= 'A' && c <= 'Z') {   /* it's a letter */
-      c -= 'A';
-      copyXPMArea(c * (CHAR_WIDTH+1), 74, (CHAR_WIDTH+1), (CHAR_HEIGHT+1), k, y);
-      k += (CHAR_WIDTH+1);
-    }
-    else {   /* it's a number or symbol */
-      c -= '0';
-      if ( new )
-	copyXPMArea((c*(CHAR_WIDTH+1))+65, 0, (CHAR_WIDTH+1), (CHAR_HEIGHT+1), k, y);
-      else
-	copyXPMArea((c*(CHAR_WIDTH+1)),   64, (CHAR_WIDTH+1), (CHAR_HEIGHT+1), k, y);
-      k += (CHAR_WIDTH+1);
-    }
-  }
+	int i, c, k = x;
+
+	for (i = 0; name[i]; i++) {
+		c = toupper(name[i]);
+		if (c >= 'A' && c <= 'Z') {	/* it's a letter */
+			c -= 'A';
+			copyXPMArea(c * (CHAR_WIDTH + 1), 74,
+						(CHAR_WIDTH + 1), (CHAR_HEIGHT + 1), k, y);
+			k += (CHAR_WIDTH + 1);
+		} else {				/* it's a number or symbol */
+			c -= '0';
+			if (new) {
+				copyXPMArea((c * (CHAR_WIDTH + 1)) + 65, 0,
+							(CHAR_WIDTH + 1), (CHAR_HEIGHT + 1), k, y);
+			} else {
+				copyXPMArea((c * (CHAR_WIDTH + 1)), 64,
+							(CHAR_WIDTH + 1), (CHAR_HEIGHT + 1), k, y);
+			}
+			k += (CHAR_WIDTH + 1);
+		}
+	}
 }
 
 /* Blits number to give coordinates.. two 0's, right justified */
 void BlitNum(int num, int x, int y, int new)
 {
-  char buf[32];
-  int newx=x;
+	char buf[32];
+	int newx = x;
 
-  if (num >  99) newx -= (CHAR_WIDTH+1);
-  if (num > 999) newx -= (CHAR_WIDTH+1);
+	if (num > 99)
+		newx -= (CHAR_WIDTH + 1);
+	if (num > 999)
+		newx -= (CHAR_WIDTH + 1);
 
-  sprintf(buf, "%02i", num);
+	sprintf(buf, "%02i", num);
 
-  BlitString(buf, newx, y, new);
+	BlitString(buf, newx, y, new);
 }
 
 void ClearDigits(int i)
 {
-  copyXPMArea(39, 84, (3*(CHAR_WIDTH+1)), (CHAR_HEIGHT+1), 39, (11*i) + 5); /* Clear digits */
-}
-
-void BlinkOn(int i)
-{
-  mbox[i].blink_stat = BLINK_TIMES*2;
-  Sleep_Interval = BLINK_SLEEP_INTERVAL;
-  Blink_Mode |= (1<<i);		/* Global blink flag set for this mailbox */
-}
-
-void BlinkOff(int i)
-{
-  mbox[i].blink_stat = 0;
-  Sleep_Interval = DEFAULT_SLEEP_INTERVAL;
+	copyXPMArea((10 * (CHAR_WIDTH + 1)), 64, (CHAR_WIDTH + 1),
+				(CHAR_HEIGHT + 1), 35, (11 * i) + 5);
+	copyXPMArea(39, 84, (3 * (CHAR_WIDTH + 1)), (CHAR_HEIGHT + 1), 39, (11 * i) + 5);	/* Clear digits */
 }
 
-void BlinkToggle(int i)
+/* 	Read a line from a file to obtain a pair setting=value 
+	skips # and leading spaces
+	NOTE: if setting finish with 0, 1, 2, 3 or 4 last char are deleted and
+	index takes its value... if not index will get -1 
+	Returns -1 if no setting=value
+*/
+int ReadLine(FILE * fp, char *setting, char *value, int *mbox_index)
 {
-  if(--mbox[i].blink_stat <= 0) {
-    Blink_Mode &= ~(1<<i);
-    mbox[i].blink_stat = 0;
-  }
-  
-}
+	char buf[BUF_SIZE];
+	char *p, *q;
+	int len, aux;
 
-/* ReadConfigSetting */
-int ReadConfigString(FILE *fp, char *setting, char *value)
-{
-  char buf[BUFFER_SIZE];
-  char *p=NULL;
-  int  len, slen;
-
-  if (!fp) return 0;
-  
-  fseek(fp, 0, SEEK_SET);
-
-  while( !feof(fp) ) {
-    if( !fgets(buf, BUFFER_SIZE-1, fp) )
-      break;
-    len=strlen(buf);
-    if( buf[len-1] == '\n' ) buf[len-1] = 0;			/* strip linefeed */
-    for( p=(char*)buf; *p != '#' && *p; p++ ) ; *p = 0;		/* Strip comments */
-    for( p=(char*)buf; (*p == ' ' || *p == '\t') && *p; p++) ;	/* Skip leading spaces */
-    if( !strncmp(p, setting, slen=strlen(setting)) ) {		/* found our setting */
-      p += slen;						/* point to end of keyword+1 */
-      while( (*p == ' ' || *p == '=' || *p == '\t') && *p ) p++;/* Skip spaces and equal sign */
-      strcpy(value, p);
-      return 1;
-    }
-  }
-  return 0;
-}
+	*setting = 0;
+	*value = 0;
 
-int ReadConfigInt(FILE *fp, char *setting, int *value)
-{
-  char buf[BUFFER_SIZE];
+	if (!fp || feof(fp) || !fgets(buf, BUF_SIZE - 1, fp))
+		return -1;
 
-  if (ReadConfigString(fp, setting, (char *)buf)) {
-    *value = atoi(buf);
-    return 1;
-  }
+	len = strlen(buf);
 
-  return 0;
+	if (buf[len - 1] == '\n') {
+		buf[len - 1] = 0;		/* strip linefeed */
+	}
+	for (p = (char *) buf; *p != '#' && *p; p++);
+	*p = 0;						/* Strip comments */
+	if (!(p = strtok(buf, "=")))
+		return -1;
+	if (!(q = strtok(NULL, "\n")))
+		return -1;
+
+	/* Chg - Mark Hurley
+	 * Date: May 8, 2001
+	 * Removed for loop (which removed leading spaces)
+	 * Leading & Trailing spaces need to be removed
+	 * to Fix Debian bug #95849
+	 */
+	FullTrim(p);
+	FullTrim(q);
+
+	strcpy(setting, p);
+	strcpy(value, q);
+
+	len = strlen(setting) - 1;
+	if (len > 0) {
+		aux = setting[len] - 48;
+		if (aux > -1 && aux < 5) {
+			setting[len] = 0;
+			*mbox_index = aux;
+		}
+	} else
+		*mbox_index = -1;
+
+	DMA(DEBUG_INFO, "@%s.%d=%s@\n", setting, *mbox_index, value);
+	return 1;
 }
 
 void parse_mbox_path(int item)
 {
-  if(!strncasecmp(mbox[item].path,"pop3:",5)) {			/* pop3 account */
-    mbox[item].pc = pop3Create(mbox[item].path);
-    *strchr(mbox[item].path, ':')=0;				/* special keyword ``pop3'' */
-  }
-  else if(!strncasecmp(mbox[item].path,"imap:",5)) {
-    fprintf(stderr, "IMAP protocol does not realized yet.\n");
-    *strchr(mbox[item].path, ':')=0;				/* special keyword ``imap'' */
-  }
+	if (!strncasecmp(mbox[item].path, "pop3:", 5)) {	/* pop3 account */
+		pop3Create((&mbox[item]), mbox[item].path);
+	} else if (!strncasecmp(mbox[item].path, "shell:", 6)) {	/* generic cmd */
+		shellCreate((&mbox[item]), mbox[item].path);
+	} else if (!strncasecmp(mbox[item].path, "gicu:", 5)) {	/* gnomeicu check */
+		char buf[255];
+		if (isdigit(mbox[item].path[5])) {
+			sprintf(buf, "shell:::gnomeicu-client -u%s msgcount",
+					mbox[item].path + 5);
+		} else {
+			sprintf(buf, "shell:::gnomeicu-client msgcount");
+		}
+		shellCreate((&mbox[item]), buf);
+	} else if (!strncasecmp(mbox[item].path, "licq:", 5)) {	/* licq history file */
+		licqCreate((&mbox[item]), mbox[item].path);
+	} else if (!strncasecmp(mbox[item].path, "imap:", 5) ||	/* imap4 account */
+			   !strncasecmp(mbox[item].path, "sslimap:", 8) ||	/* sslimap4 account */
+			   !strncasecmp(mbox[item].path, "imaps:", 6)) {	/* sslimap4 account */
+		imap4Create((&mbox[item]), mbox[item].path);
+	} else if (!strncasecmp(mbox[item].path, "maildir:", 8)) {	/* maildir */
+		maildirCreate((&mbox[item]), mbox[item].path);
+	} else
+		mboxCreate((&mbox[item]), mbox[item].path);	/* default are mbox */
 }
 
-int Read_Config_File( char *filename )
+int Read_Config_File(char *filename, int *loopinterval)
 {
-  FILE *fp;
-
-  fp = fopen(filename, "r");
-  if (fp) {
-    ReadConfigInt(   fp,    "interval", &loopinterval);
-
-    ReadConfigString(fp, "label.0",     	mbox[0].label);
-    ReadConfigString(fp, "path.0",      	mbox[0].path);
-    ReadConfigString(fp, "notify.0",    	mbox[0].notify);
-    ReadConfigString(fp, "action.0",    	mbox[0].action);
-    ReadConfigInt(   fp, "interval.0", 	       &mbox[0].loopinterval);
-    ReadConfigString(fp, "fetchcmd.0",  	mbox[0].fetchcmd);
-    ReadConfigInt(   fp, "fetchinterval.0",    &mbox[0].fetchinterval);
-    parse_mbox_path(0);
-
-    ReadConfigString(fp, "label.1",		mbox[1].label);
-    ReadConfigString(fp, "path.1",		mbox[1].path);
-    ReadConfigString(fp, "notify.1",		mbox[1].notify);
-    ReadConfigString(fp, "action.1",		mbox[1].action);
-    ReadConfigInt(   fp, "interval.1", 	       &mbox[1].loopinterval);
-    ReadConfigString(fp, "fetchcmd.1",		mbox[1].fetchcmd);
-    ReadConfigInt(   fp, "fetchinterval.1",    &mbox[1].fetchinterval);
-    parse_mbox_path(1);
-
-    ReadConfigString(fp, "label.2",		mbox[2].label);
-    ReadConfigString(fp, "path.2",		mbox[2].path);
-    ReadConfigString(fp, "notify.2",		mbox[2].notify);
-    ReadConfigString(fp, "action.2",		mbox[2].action);
-    ReadConfigInt(   fp, "interval.2",	       &mbox[2].loopinterval);
-    ReadConfigString(fp, "fetchcmd.2",		mbox[2].fetchcmd);
-    ReadConfigInt(   fp, "fetchinterval.2",    &mbox[2].fetchinterval);
-    parse_mbox_path(2);
-
-    ReadConfigString(fp, "label.3",		mbox[3].label);
-    ReadConfigString(fp, "path.3",		mbox[3].path);
-    ReadConfigString(fp, "notify.3",		mbox[3].notify);
-    ReadConfigString(fp, "action.3",		mbox[3].action);
-    ReadConfigInt(   fp, "interval.3",	       &mbox[3].loopinterval);
-    ReadConfigString(fp, "fetchcmd.3",		mbox[3].fetchcmd);
-    ReadConfigInt(   fp, "fetchinterval.3",    &mbox[3].fetchinterval);
-    parse_mbox_path(3);
-    
-    ReadConfigString(fp, "label.4",		mbox[4].label);
-    ReadConfigString(fp, "path.4",		mbox[4].path);
-    ReadConfigString(fp, "notify.4",		mbox[4].notify);
-    ReadConfigString(fp, "action.4",		mbox[4].action);
-    ReadConfigInt(   fp, "interval.4",	       &mbox[4].loopinterval);
-    ReadConfigString(fp, "fetchcmd.4",		mbox[4].fetchcmd);
-    ReadConfigInt(   fp, "fetchinterval.4",    &mbox[4].fetchinterval);
-    parse_mbox_path(4);
-
-    fclose(fp);
-    return 1;
-  }
-  else {
-    perror("Read_Config_File");
-    fprintf(stderr, "Unable to open %s, no settings read.\n", filename);
-    return 0;
-  }
+	FILE *fp;
+	char setting[17], value[250];
+	int mbox_index;
+
+	if (!(fp = fopen(filename, "r"))) {
+		DMA(DEBUG_ERROR, "Unable to open %s, no settings read: %s\n",
+			filename, strerror(errno));
+		return 0;
+	}
+	while (!feof(fp)) {
+		if (ReadLine(fp, setting, value, &mbox_index) == -1)
+			continue;
+		if (!strcmp(setting, "interval")) {
+			*loopinterval = atoi(value);
+		} else if (mbox_index == -1)
+			continue;			/* Didn't read any setting.[0-5] value */
+		if (!strcmp(setting, "label.")) {
+			strcpy(mbox[mbox_index].label, value);
+		} else if (!strcmp(setting, "path.")) {
+			strcpy(mbox[mbox_index].path, value);
+		} else if (!strcmp(setting, "notify.")) {
+			strcpy(mbox[mbox_index].notify, value);
+		} else if (!strcmp(setting, "action.")) {
+			strcpy(mbox[mbox_index].action, value);
+		} else if (!strcmp(setting, "interval.")) {
+			mbox[mbox_index].loopinterval = atoi(value);
+		} else if (!strcmp(setting, "fetchcmd.")) {
+			strcpy(mbox[mbox_index].fetchcmd, value);
+		} else if (!strcmp(setting, "fetchinterval.")) {
+			mbox[mbox_index].fetchinterval = atoi(value);
+		} else if (!strcmp(setting, "debug.")) {
+			int debug_value = debug_default;
+			if (strcasecmp(value, "all") == 0) {
+				debug_value = DEBUG_ALL;
+			}
+			/* could disable debugging, but I want the command
+			   line argument to provide all information
+			   possible. */
+			mbox[mbox_index].debug = debug_value;
+		}
+	}
+	fclose(fp);
+	for (mbox_index = 0; mbox_index < 5; mbox_index++)
+		if (mbox[mbox_index].label[0] != 0)
+			parse_mbox_path(mbox_index);
+	return 1;
 }
+
 /*
  * NOTE: this function assumes that the ConnectionNumber() macro
  *       will return the file descriptor of the Display struct
@@ -626,101 +560,117 @@ int Read_Config_File( char *filename )
  */
 void XSleep(int millisec)
 {
-  struct timeval to;
-  struct timeval *timeout = NULL;
-  fd_set readfds;
-  int max_fd;
-
-  if(millisec >= 0) {
-    timeout = &to;
-    to.tv_sec = millisec / 1000;
-    to.tv_usec = (millisec % 1000) * 1000;
-  }
-  FD_ZERO(&readfds);
-  FD_SET(ConnectionNumber(display), &readfds);
-  max_fd = ConnectionNumber(display);
-
-  select(max_fd+1, &readfds, NULL, NULL, timeout);
+#ifdef USE_POLL
+	struct pollfd timeout;
+
+	timeout.fd = ConnectionNumber(display);
+	timeout.events = POLLIN;
+
+	poll(&timeout, 1, millisec);
+#else
+	struct timeval to;
+	struct timeval *timeout = NULL;
+	fd_set readfds;
+	int max_fd;
+
+	if (millisec >= 0) {
+		timeout = &to;
+		to.tv_sec = millisec / 1000;
+		to.tv_usec = (millisec % 1000) * 1000;
+	}
+	FD_ZERO(&readfds);
+	FD_SET(ConnectionNumber(display), &readfds);
+	max_fd = ConnectionNumber(display);
+
+	select(max_fd + 1, &readfds, NULL, NULL, timeout);
+#endif
 }
 
-void sigchld_handler(int sig)
+void sigchld_handler(int sig __attribute__ ((unused)))
 {
-  waitpid(0, NULL, WNOHANG);
-  signal(SIGCHLD, sigchld_handler);
+	waitpid(0, NULL, WNOHANG);
+	signal(SIGCHLD, sigchld_handler);
 }
 
 int main(int argc, char *argv[])
 {
-    
-  parse_cmd(argc, argv);
+	char uconfig_file[256];
 
-  init_biff(argc, argv);
-
-  signal(SIGCHLD, sigchld_handler);
-
-  do_biff(argc, argv);
-
-  return 0;
+	parse_cmd(argc, argv, uconfig_file);
+	init_biff(uconfig_file);
+	signal(SIGCHLD, sigchld_handler);
+	do_biff(argc, argv);
+	return 0;
 }
 
-void parse_cmd(int argc, char **argv)
+void parse_cmd(int argc, char **argv, char *config_file)
 {
-  int	i;
-
-  uconfig_file[0] = 0;
-  
-  /* Parse Command Line */
-
-  for (i=1; i<argc; i++) {
-    char *arg = argv[i];
-
-    if (*arg=='-') {
-      switch (arg[1]) {
-	case 'd' :
-	  if (strcmp(arg+1, "display")) {
-	    usage();
-	    exit(1);
-	  }
-	  break;
-	case 'g' :
-	  if (strcmp(arg+1, "geometry")) {
-	    usage();
-	    exit(1);
-	  }
-	  break;
-	case 'v' :
-	  printversion();
-	  exit(0);
-	  break;
-        case 'c' :
-          if (argc > (i+1)) {
-	    strcpy(uconfig_file, argv[i+1]);
-            i++;
-          }
-          break;
-        default:
-	  usage();
-	  exit(0);
-	  break;
-      }
-    }
-  }
+	int i;
+
+	char uconfig_file[256];
+
+	uconfig_file[0] = 0;
+	/* Parse Command Line */
+
+	for (i = 1; i < argc; i++) {
+		char *arg = argv[i];
+
+		if (*arg == '-') {
+			switch (arg[1]) {
+			case 'd':
+				if (strcmp(arg + 1, "debug") == 0) {
+					debug_default = DEBUG_ALL;
+				} else if (strcmp(arg + 1, "display")) {
+					usage();
+					exit(EXIT_FAILURE);
+				}
+				break;
+			case 'g':
+				if (strcmp(arg + 1, "geometry")) {
+					usage();
+					exit(EXIT_FAILURE);
+				}
+				break;
+			case 'v':
+				printversion();
+				exit(EXIT_SUCCESS);
+				break;
+			case 'c':
+				if (argc > (i + 1)) {
+					strcpy(uconfig_file, argv[i + 1]);
+					i++;
+				}
+				break;
+			default:
+				usage();
+				exit(EXIT_SUCCESS);
+				break;
+			}
+		}
+	}
+	strcpy(config_file, uconfig_file);
 }
 
 void usage(void)
 {
-  fprintf(stderr, "\nwmBiff v"WMBIFF_VERSION"- incoming mail checker\nGennady Belyakov <gb at ccat.elect.ru>\n\n");
-  fprintf(stderr, "usage:\n");
-  fprintf(stderr, "    -display <display name>\n");
-  fprintf(stderr, "    -geometry +XPOS+YPOS      initial window position\n");
-  fprintf(stderr, "    -c <filename>             use specified config file\n");
-  fprintf(stderr, "    -h                        this help screen\n");
-  fprintf(stderr, "    -v                        print the version number\n");
-  fprintf(stderr, "\n");
+	printf("\nwmBiff v" WMBIFF_VERSION
+		   " - incoming mail checker\n"
+		   "Gennady Belyakov and others (see the README file)\n"
+		   "Please report bugs to wmbiff-devel at lists.sourceforge.net\n"
+		   "\n"
+		   "usage:\n"
+		   "    -debug                    enable debugging\n"
+		   "    -display <display name>   use specified X display\n"
+		   "    -geometry +XPOS+YPOS      initial window position\n"
+		   "    -c <filename>             use specified config file\n"
+		   "    -h                        this help screen\n"
+		   "    -v                        print the version number\n"
+		   "\n");
 }
 
 void printversion(void)
 {
-  fprintf(stderr, "wmbiff v%s\n", WMBIFF_VERSION);
+	printf("wmbiff v%s\n", WMBIFF_VERSION);
 }
 
+/* vim:set ts=4: */
diff --git a/wmbiff/wmbiffrc.5 b/wmbiff/wmbiffrc.5
new file mode 100644
index 0000000..a823074
--- /dev/null
+++ b/wmbiff/wmbiffrc.5
@@ -0,0 +1,198 @@
+.\" Hey, Emacs!  This is an -*- nroff -*- source file.
+.\" $Id: wmbiffrc.5,v 1.10 2002/03/06 07:15:08 bluehal Exp $
+.\"
+.\" wmbiff.1 and wmbiffrc.5 are copyright 1999-2002 by 
+.\" Jordi Mallach <jordi at debian.org>
+.\"
+.\" This is free documentation, see the latest version of the GNU
+.\" General Public License for copying conditions. There is NO warranty.
+.TH WMBIFFRC 5 "January 27, 2002" "wmbiff"
+
+.SH NAME
+wmbiffrc \- configuration file for
+.BR wmbiff (1)
+
+.SH DESCRIPTION
+\fBWMbiff\fP is a mail notification tool for the WindowMaker and AfterStep
+window managers. It can handle up to 5 mailboxes, and you can define actions
+on mouse clicks for the different mailboxes. This manpage explains the
+different options which can be specified in a user's wmbiffrc.
+
+.SH OPTIONS
+Each option takes the form
+.IR option[.mbox] " = " value .
+Comment must be preceeded by pound signs (#).
+
+The supported configuration options are:
+
+.TP 4
+\fBinterval\fP
+Global interval between mailbox checking. Value is the number of seconds, 5
+is the default.
+.TP
+\fBlabel.n\fP
+Specifies the displayed label for a mailbox. It can be up to five characters
+long.
+.TP
+\fBpath.n\fP
+Path to the mailbox, local or remote one. Path lines start with a prefix,
+which specifies the type of wmbiff box you're setting up. The following types
+are supported:
+.RS
+.TP
+.I mbox
+This is a local mbox mailbox. After the prefix, you only need to put the
+path to the mailbox wmbiff needs to read.  This is also the default.
+.RS
+mbox:/path/to/mail/debian-devel
+.RS
+- or -
+.RE
+/path/to/mail/debian-devel
+.RE
+.TP
+.I maildir
+\fBMaildir mailboxes are now supported!\fP
+This works just like \fImbox\fP above.  After the prefix, you need to put
+the path to the maildir wmbiff will read.
+.RS
+maildir:/path/to/mail/bugtraq/
+.RE
+.TP
+.I pop3
+Using this type, wmbiff will fetch mail from a pop3 server, using the
+specified username, password, host and an optional port number (defaulting
+to 110). If your password contained special character, eg. '@' or ':',
+use another path format.  See Authentication below for a description of 
+the auth field. 
+.RS
+pop3:user:passwd at server[:port] [auth]
+.RE
+.RS
+pop3:user passwd server[ port] [auth] 
+.RE
+.TP
+.I imap
+These are IMAP4 boxes. As with pop3, wmbiff will read a imap4 mbox using
+the given values and will display info about the remote mail. This type
+accepts user, password, host and optional path to mailbox and port number.
+See Authentication below for a description of the auth field.
+.RS
+imap:user:passwd at server[/mailbox][:port] [auth]
+.RE
+.RS
+imap:user passwd server[/mailbox][ port] [auth]
+.RE
+.TP
+.I imaps
+These are IMAP4 boxes wrapped in a TLS (SSL) connection, only available if 
+wmbiff was compiled with TLS support.  Parameters are the same as those for 
+ordinary IMAP4 boxes.  Port defaults to 993. If 143 is specified, 
+wmbiff will attempt to connect unencrypted but negotiate TLS using
+IMAP's STARTTLS command.  TLS support uses gnutls, which is under development
+and may be insecure.  TLS support is only for encryption: since certificates
+are not yet checked, it is vulnerable to man-in-the-middle attack.
+.RS
+imaps:user:passwd at server[/mailbox][:port] [auth]
+.RE
+.RS
+imaps:user passwd server[/mailbox][ port] [auth]
+.RE
+.TP
+.I licq
+With this box type, wmbiff will read the given history file and track the
+number of messages in it. It just needs a path to a given licq history file.
+.RS
+licq:/path/to/.licq/history/file.history
+.RE
+.TP
+.I gicu
+With this box type, wmbiff will ask gnomeicu for the number
+of pending messages.  If gnomeicu is not running, nothing
+will be displayed.  gnomeicu-client must be in your path.
+The user's icq UIN is optional.
+.RS
+gicu:[UIN]
+.RE
+.TP
+.I shell
+With this EXPERIMENTAL keyword, wmbiff will launch the
+specified shell command and read its output (STDOUT)
+expecting an integer number to be displayed as a count
+of new messages.   The behavior of this experimental
+keyword is likely to change in future revisions.
+.RS
+shell:::/path/to/command
+.RE
+.RE
+.TP
+\fBnotify.n\fP
+Command to be executed on new mail arrival in the given mailbox. Accepts
+the special keyword "beep" to use the pc speaker.
+.TP
+\fBaction.n\fP
+Command to be executed on left mouse click on a mailbox label.
+.TP
+\fBinterval.n\fP
+Per mailbox check interval. Value is the amount of seconds between
+checkings, default is the global interval.
+.TP
+\fBfetchinterval.n\fP
+Interval between mail auto-fetching. Values accept 0 to disable, -1 for
+autofetching on new mail arrival, and positive values for a given interval
+in seconds.
+.TP
+\fBfetchcmd.n\fP
+Command to be executed to fetch mail. If not specified, fetching through
+wmbiff is disabled completely.
+.TP
+\fBdebug.n\fP 
+Show debugging messages from this mailbox.  Currently
+supported values are "all" and "none".  The \-debug option
+to wmbiff overrides this setting.  Since IMAP uses a single
+connection per server, per-mailbox debugging may not
+
+.SH AUTHENTICATION
+
+Authentication methods include "cram-md5", "apop" (for
+Pop3), and "plaintext".  "cram-md5" and "apop" are only
+available when wmbiff is compiled with libgcrypt.
+Authentication methods are tried in the following order:
+cram-md5, apop, plaintext.
+
+Each authentication method will be tried unless a list is
+included in the [auth] field.  For example, append "cram-md5
+apop" if you don't want your password to be sent in
+cleartext over the network.  Conversely, append "plaintext"
+if you don't want wmbiff to bother with other authentication
+methods.  Leaving authentication methods unspecified should
+be reasonably safe.  The order of entries in the [auth] list
+is not currently considered.
+
+.SH TROUBLESHOOTING
+
+For problems authenticating to servers, try specifying the
+authentication method explicitly as described above:
+sometimes a failed attempt to authenticate can cause later
+failures.  Some servers claim to support cram-md5 but fail:
+telling wmbiff not totry can help.
+
+For other problems, run wmbiff with the -debug option.  See
+wmbiff(1) for details.
+
+.SH FILES
+.TP
+.I ~/.wmbiffrc
+per-user wmbiff configuration file.
+
+.SH AUTHOR
+This manual page was written by Jordi Mallach <jordi at debian.org>,
+originally for the Debian GNU/Linux system (but may be used by others).
+
+.SH SEE ALSO
+.PD 0
+.TP
+\fBwmbiff\fP(1)
+.PP
+\fI/usr/share/doc/wmbiff/examples/sample.wmbiffrc\fP
+(or equivalent on your system)
diff --git a/wmgeneral/list.h b/wmgeneral/list.h
index af0f22c..5ea8ee2 100644
--- a/wmgeneral/list.h
+++ b/wmgeneral/list.h
@@ -44,7 +44,7 @@ INLINE LinkedList* list_cons(void* head, LinkedList* tail);
 
 INLINE int list_length(LinkedList* list);
 
-INLINE void* list_nth(int index, LinkedList* list);
+INLINE void* list_nth(int n, LinkedList* list);
 
 INLINE void list_remove_head(LinkedList** list);
 
diff --git a/wmgeneral/wmgeneral.c b/wmgeneral/wmgeneral.c
index 56b7bd6..acda07e 100644
--- a/wmgeneral/wmgeneral.c
+++ b/wmgeneral/wmgeneral.c
@@ -62,7 +62,7 @@ int			d_depth;
 XSizeHints	mysizehints;
 XWMHints	mywmhints;
 Pixel		back_pix, fore_pix;
-char		*Geometry = "";
+const char		*Geometry = "";
 Window		iconwin, win;
 GC			NormalGC;
 XpmIcon		wmgen;
@@ -86,8 +86,8 @@ MOUSE_REGION	mouse_region[MAX_MOUSE_REGION];
  /* Function Prototypes */
 /***********************/
 
-static void GetXPM(XpmIcon *, char **);
-static Pixel GetColor(char *);
+static void GetXPM(XpmIcon *, const char **);
+static Pixel GetColor(const char *);
 void RedrawWindow(void);
 void AddMouseRegion(int, int, int, int, int);
 int CheckMouseRegion(int, int);
@@ -100,7 +100,7 @@ void parse_rcfile(const char *filename, rckeys *keys) {
 
 	char	*p,*q;
 	char	temp[128];
-	char	*tokens = " :\t\n";
+	const char	*tokens = " :\t\n";
 	FILE	*fp;
 	int		i,key;
 
@@ -135,7 +135,7 @@ void parse_rcfile2(const char *filename, rckeys2 *keys) {
 
 	char	*p;
 	char	temp[128];
-	char	*tokens = " :\t\n";
+	const char	*tokens = " :\t\n";
 	FILE	*fp;
 	int		i,key;
 	char	*family = NULL;
@@ -165,7 +165,7 @@ void parse_rcfile2(const char *filename, rckeys2 *keys) {
 |* GetXPM																	   *|
 \*******************************************************************************/
 
-static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
+static void GetXPM(XpmIcon *wmgen_local, const char *pixmap_bytes[]) {
 
 	XWindowAttributes	attributes;
 	int					err;
@@ -173,10 +173,12 @@ static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
 	/* For the colormap */
 	XGetWindowAttributes(display, Root, &attributes);
 
-	wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
+	wmgen_local->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
 
-	err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
-					&(wmgen->mask), &(wmgen->attributes));
+	err = XpmCreatePixmapFromData(display, Root, (char **)pixmap_bytes, 
+                                  &(wmgen_local->pixmap),
+                                  &(wmgen_local->mask), 
+                                  &(wmgen_local->attributes));
 	
 	if (err != XpmSuccess) {
 		fprintf(stderr, "Not enough free colorcells.\n");
@@ -188,7 +190,7 @@ static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
 |* GetColor																	   *|
 \*******************************************************************************/
 
-static Pixel GetColor(char *name) {
+static Pixel GetColor(const char *name) {
 
 	XColor				color;
 	XWindowAttributes	attributes;
@@ -251,14 +253,14 @@ void RedrawWindowXY(int x, int y) {
 |* AddMouseRegion															   *|
 \*******************************************************************************/
 
-void AddMouseRegion(int index, int left, int top, int right, int bottom) {
+void AddMouseRegion(int region_idx, int left, int top, int right, int bottom) {
 
-	if (index < MAX_MOUSE_REGION) {
-		mouse_region[index].enable = 1;
-		mouse_region[index].top = top;
-		mouse_region[index].left = left;
-		mouse_region[index].bottom = bottom;
-		mouse_region[index].right = right;
+	if (region_idx < MAX_MOUSE_REGION) {
+		mouse_region[region_idx].enable = 1;
+		mouse_region[region_idx].top = top;
+		mouse_region[region_idx].left = left;
+		mouse_region[region_idx].bottom = bottom;
+		mouse_region[region_idx].right = right;
 	}
 }
 
@@ -288,7 +290,7 @@ int CheckMouseRegion(int x, int y) {
 /*******************************************************************************\
 |* createXBMfromXPM															   *|
 \*******************************************************************************/
-void createXBMfromXPM(char *xbm, char **xpm, int sx, int sy) {
+void createXBMfromXPM(char *xbm, const char **xpm, int sx, int sy) {
 
 	int		i,j,k;
 	int		width, height, numcol, depth;
@@ -366,7 +368,7 @@ void setMaskXY(int x, int y) {
 /*******************************************************************************\
 |* openXwindow																   *|
 \*******************************************************************************/
-void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
+void openXwindow(int argc, char *argv[], const char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
 
 	unsigned int	borderwidth = 1;
 	XClassHint		classHint;
diff --git a/wmgeneral/wmgeneral.h b/wmgeneral/wmgeneral.h
index e9d6ca6..a167774 100644
--- a/wmgeneral/wmgeneral.h
+++ b/wmgeneral/wmgeneral.h
@@ -42,14 +42,14 @@ Display		*display;
  /* Function Prototypes */
 /***********************/
 
-void AddMouseRegion(int index, int left, int top, int right, int bottom);
+void AddMouseRegion(int rgn_index, int left, int top, int right, int bottom);
 int CheckMouseRegion(int x, int y);
 
-void openXwindow(int argc, char *argv[], char **, char *, int, int);
+void openXwindow(int argc, char *argv[], const char **, char *, int, int);
 void RedrawWindow(void);
 void RedrawWindowXY(int x, int y);
 
-void createXBMfromXPM(char *, char **, int, int);
+void createXBMfromXPM(char *, const char **, int, int);
 void copyXPMArea(int, int, int, int, int, int);
 void copyXBMArea(int, int, int, int, int, int);
 void setMaskXY(int, int);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-wmaker/wmbiff.git



More information about the Pkg-wmaker-commits mailing list