[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, ®s);
+ }
+
+ /* 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, ®s);
+ }
+
+ /* 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