[PATCH 2/3] wmpop3lb: Add version 2.4.2 to repository.
Doug Torrance <[email protected]>
| Newsgroups | gmane.compw.window-managers.windowmaker.devel |
|---|---|
| Message-ID | <[email protected]> |
From:
https://web.archive.org/web/20041026142832fw_/http://lbj.free.fr/wmpop3/wmpop3lb2.4.2.tar.gz
---
wmpop3lb/CHANGE_LOG | 93 +++
wmpop3lb/COPYING | 339 ++++++++
wmpop3lb/INSTALL | 39 +
wmpop3lb/README | 168 ++++
wmpop3lb/wmgeneral/list.c | 169 ++++
wmpop3lb/wmgeneral/list.h | 59 ++
wmpop3lb/wmgeneral/misc.c | 164 ++++
wmpop3lb/wmgeneral/misc.h | 9 +
wmpop3lb/wmgeneral/wmgeneral.c | 480 +++++++++++
wmpop3lb/wmgeneral/wmgeneral.h | 59 ++
wmpop3lb/wmpop3/.wmpop3rc_test | 62 ++
wmpop3lb/wmpop3/.wmpop3rc_test~ | 62 ++
wmpop3lb/wmpop3/Makefile | 47 ++
wmpop3lb/wmpop3/Pop3Client.c | 591 ++++++++++++++
wmpop3lb/wmpop3/Pop3Client.h | 146 ++++
wmpop3lb/wmpop3/wmpop3.c | 1707 +++++++++++++++++++++++++++++++++++++++
wmpop3lb/wmpop3/wmpop3.xpm | 152 ++++
17 files changed, 4346 insertions(+)
create mode 100644 wmpop3lb/CHANGE_LOG
create mode 100644 wmpop3lb/COPYING
create mode 100644 wmpop3lb/INSTALL
create mode 100644 wmpop3lb/README
create mode 100644 wmpop3lb/wmgeneral/list.c
create mode 100644 wmpop3lb/wmgeneral/list.h
create mode 100644 wmpop3lb/wmgeneral/misc.c
create mode 100644 wmpop3lb/wmgeneral/misc.h
create mode 100644 wmpop3lb/wmgeneral/wmgeneral.c
create mode 100644 wmpop3lb/wmgeneral/wmgeneral.h
create mode 100644 wmpop3lb/wmpop3/.wmpop3rc_test
create mode 100644 wmpop3lb/wmpop3/.wmpop3rc_test~
create mode 100644 wmpop3lb/wmpop3/Makefile
create mode 100644 wmpop3lb/wmpop3/Pop3Client.c
create mode 100644 wmpop3lb/wmpop3/Pop3Client.h
create mode 100644 wmpop3lb/wmpop3/wmpop3.c
create mode 100644 wmpop3lb/wmpop3/wmpop3.xpm
diff --git a/wmpop3lb/CHANGE_LOG b/wmpop3lb/CHANGE_LOG
new file mode 100644
index 0000000..3f1a8e6
--- /dev/null
+++ b/wmpop3lb/CHANGE_LOG
@@ -0,0 +1,93 @@
+WMPOP3 CHANGE_LOG
+
+WMPOP3LB
+
+Version 2.4.2:
+ * fixed a bug in pop3WriteOneMail: the first line of a received buffer was
+ always removed, so the received mail was incomplete and corrupted.
+Version 2.4.1:
+ * %c with newmailcommand only applies to new mails
+ * final dot of messages removed when saving to a temporary file.
+ * optmized connecting/disconnecting when using %c or %C
+Version 2.4:
+ * switch directly in the summary view mode from total number of messages
+ to number of unread messages.
+ * selectedmesgcommand configuation option: specify a command per server
+ to launch only on selected messages.
+ * wilcard implemented for newmailcommand, mailclient and
+ selectedmesgcommand.
+ * maxdlsize configuration option: in the case of the %c, %C and %m
+ wildcards, will not download messages bigger than this value.
+ * mailseparator configuration option: specify a separator to include
+ between each mail when using %c or %C wildcards.
+ * configuration options specified between double quotes ('"') can now be
+ spread among multiple lines. Usefull for mailseparator option...
+Version 2.3: skipped
+Version 2.2:
+ * now unlimited (i.e. not limited by wmpop3lb...) number of messages per
+ server listed.
+ * new scrollbar for fast browsing.
+ * newmailcommand configuration option : allows to specify (per server) a
+ command, per server, to run if a new mail has arrived.
+ * progress bar shown when retrieving the messages off the server.
+Version 2.1:
+ * smooth scrolling.
+Version 2.0: !! new, multi pop3 checker !!
+ * can check up to 6 pop3 servers
+ * you can choose in the configuration, for each server,
+ to display the number of unread messages only or the total number
+ of messages.
+ * put back the ability to launch a mail client from WMPop3lb.
+ You can specify one mail client per account!
+ To launch your mail client, switch to the counter view mode and click on
+ the desired server line.
+
+Version 1.0: based on WMPop3
+ * completely changed the GUI.
+ * display information when contacting the POP3 server.
+ * fixed the button behaviour (buttons now "react" to the clicks).
+ * now displays the From: and Subject: header fields of each mail in the
+ mailbox instead of just a picture telling there is new messages.
+ * you can no longer launch your mail browser from the interface, as this is
+ a feature I didn't need. If anyone needs it, please send a mail to
+ [email protected].
+
+The changelog below is from the original work of Scott Holden
+ ( [email protected] ) on WMPop3.
+
+=======================================================================
+Version 0.5.6a : Minor additions
+ * Added extra checking when connecting to pop-server.
+ * Fixed some variable addressing problems.
+ * updated the version number int the source.. :) oops.
+
+Version 0.5.5a : Minor additions
+ * Fixed Pop3Client, it now closes the socket after use.
+ * Fixed Comment missing in the default config file.
+
+Version 0.5.0a : Minor additions
+ * Added arrows to left toggle button. ( very minor ).
+
+Version 0.4.2a : Minor Fixes and additions
+ * Fixed the problem with "::error::" not being properly removed
+ from the display after refresh.
+ * Added the optional ability for unread and read messages to
+ be shown. ( uuu/rrr ).
+ * WMPop3 will now check the pop server 30 sec's after a mail
+ browser has been activated using Wmpop3. ( This will give
+ the mail browser a chance to download messages from the
+ server).
+
+Version 0.4.1a : Minor Fixes and additions
+ * Fixed the problem with the right button showing "AC" when
+ pressed.
+
+Version 0.4.0a : Minor Fixes and additions
+ * Messages shown are now unread messages instead total messages
+
+Version 0.3.5a : Minor Fixes and additions
+ * Fixed messages reading 3 when not connected to the net.
+ Now shows up as "::Error::" when something is wrong.
+ * Added ability to enable/disable autochecking at program
+ startup.
+ * Added text to the "Check Now" and "autochecking" buttons
diff --git a/wmpop3lb/COPYING b/wmpop3lb/COPYING
new file mode 100644
index 0000000..a43ea21
--- /dev/null
+++ b/wmpop3lb/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/wmpop3lb/INSTALL b/wmpop3lb/INSTALL
new file mode 100644
index 0000000..59b0a5d
--- /dev/null
+++ b/wmpop3lb/INSTALL
@@ -0,0 +1,39 @@
+Installation instructions.
+
+This has only been tested and compiled on a i386 Linux machine.
+
+
+ There are two methods to install WMPop3lb, either a system install
+where all users have access to this file, OR a single user install
+which installs WMPop3lb in the users home directory, this is useful
+if you have an account on someone else's computer.
+
+ First thing you should do is the following:
+
+ 1> Remember you are using this at your own risk.
+ 2> tar zxvf wmpop3lbx.x.tar.gz
+ 3> cd wmpop3lb/wmpop3
+
+
+Method 1. System install
+
+A system install will place the WMPop3lb binary in "/usr/local/bin",
+this can be done as follows (must be root for this ) :
+
+ make install1
+
+Method 2. Single user install
+
+A single user install will create a directory called wmpop3lbx.x in the users
+home directory, and copy the wmpop3 binary there. This install is as
+follows:
+
+ make install2
+
+Make sure you put this new directory in your path.
+This usually can be done by placing the following in your login
+shell setup file,( .bashrc, .bashrc_profile, .profile, etc ).
+
+ PATH=$PATH:~/wmpop3
+
+
diff --git a/wmpop3lb/README b/wmpop3lb/README
new file mode 100644
index 0000000..331874c
--- /dev/null
+++ b/wmpop3lb/README
@@ -0,0 +1,168 @@
+WMpop3LB2.4
+=================================
+
+Written by Louis-Benoit JOURDAIN ([email protected])
+
+This software is based on Wmpop3-0.5.6 by Scott Holden ( [email protected] )
+
+WARNING!!! WMPop3LB is to be used at your own risk. I will not be held
+responsible for any damages this application may cause to your system.
+
+1) WHAT IS THIS
+ WMPop3LB is a multi POP3 mail box checker. It will connect to up to 6
+ POP3 servers to check if you have mail, get the "From:" and "Subject:"
+ header fields of each mail and display them in a 7 lines window.
+ If there are more than 7 mails, they can be read by scrolling the window
+ up and down.
+ Messages can be deleted directly off the servers by selecting the mails
+ to delete and clicking the "delete" button.
+ A command to spawn can be specified for each new received message, for
+ selected messages (by clicking on the "open" button) or to launch a
+ mailclient.
+
+2) How do I configure WMPop3LB
+ WMPop3LB when first executed will check if there is a .wmpop3rc file in
+ the user's home directory, it will create it if it can not be located.
+ This file must be edited and the following fields must be changed :
+
+-- before any [server] section:
+ 1) autochecking: This allows to disable or enable auto mail checking.
+ 1 enables, 0 disables
+ 2) displaydelay: this will determine how long error messages show up
+ before the screen is cleaned up.
+ 3) scrollspeed: this is a percentage of the original scrolling speed.
+ Higher than 100, the text will scroll faster, lower than 100, the
+ text will scroll more slowly.
+ 4) tempdir: directory to put temporary mails retrieved when using %c, %C or
+ %m wildcards (default: /tmp).
+ 5) viewallmessages: This allows for alternating mail views upon startup,
+ 0 shows the From: and Subject: header fields of each mail, (message
+ view mode)
+ 1 shows the total number of messages or the number of unread
+ messages, per domain, and the number of selected messages (summary view
+ mode).
+
+-- for each [server] section (you can list up to 6 [server] sections):
+
+ 1) popserver: this is the name of the pop3 server to contact.
+ 2) port: this is the port the pop3 server is on ( default 110).
+ 3) username: user's pop3 login name.
+ 4) password: user's pop3 login password.
+ 5) alias: 3 alphanum characters server alias name, to
+ differentiate servers in the display window.
+ 6) mailcheckdelay: Number of minutes, before checking mail on this server.
+ (default = 10 minutes)
+ 7) countunreadonly: in the counter view, 0 displays the total number of
+ messages on the server, 1 displays only the number of unread
+ messages.
+ 8) mailclient: command to launch when clicking on the server alias name in
+ summary view mode.
+ The command, if it contains spaces or special characters
+ must be written between double quotes (`"').
+ See "template substitution" for more options.
+ 9) newmailcommand: command to launch when a new mail has arrived on the
+ server.
+ See "template substitution" for more options.
+ 10) selectedmesgcommand: command to launch on selected messages.
+ See "template substitution" for more options.
+ 11) mailseparator: specify a separator to include between each mail when
+ using %c or %C template substitutions.
+ 12) maxdlsize: in the case of the %c, %C and %m template substitutions, will
+ not download messages bigger than this value (-1: no limit).
+
+
+3) Using WMPop3.
+
+ 1) If you have no mail, WMPop3LB will show "No mesg" and will count down
+ the time before the next cheking.
+ If none of the configured server can be contacted, WMPop3LB will
+ show "ERROR" and will count down the time before the next checking.
+
+ 2) If you have mails, WMPop3LB will display a line for each mail, and will
+ start scrolling the display, showing the server alias identifier, the
+ "From:" and "Subject:" header fields in the following format:
+ "alias:<from field>/<subject field> * "
+
+ * each time a new mail is received, wmpop3lb will try to launch the
+ newmailcommand if it is specified in the configuration file.
+
+ 3) Depending on the option chosen for viewallmessages, it will display
+ either:
+
+ a) the alias, The From: and Subject: fields of each mail as
+ described above.
+ b) The total number of messages or the number of unread messages
+ (depending on the configuration parameter "countunreadonly") on
+ the POP3 server (if the server has been contacted successfully)
+ as well as the number of messages selected.
+ Switching between number of unread messages and total number of
+ messages can be done by clicking on the right side of each server
+ line (':' means total number, '-' means total number of unread).
+ If the server cannot be contacted, it will show one of the
+ following error message:
+ - alias: C*ER --> connection error
+ - alias: L*ER --> login error (wrong login or passwd)
+ - alias: M*ER --> can't get mails.
+
+ * The far most right button is used to toggle both views.
+
+ 4) To delete one or more messages directly off one or more servers,
+ select the messages you want to delete and then click on the bottom
+ left "DEL" button.
+
+ You can check how many messages are selected by switching view
+ mode.
+
+ A status per server will show up during "displaydelay" seconds with the
+ following error codes:
+ - OK: messages were deleted successfully from the server
+ - NONE: no message was selected for this server
+ - D:nb: nb messages failed to be deleted.
+ - Err: an error has occured (connection or else).
+
+ WMPop3LB will not allow you to delete messages if the content of the
+ mailbox on the server has changed since last checking.
+ It will instead display an error message ("mailbox content has
+ changed between updates del can.") and reload the content of the
+ mailbox from the server.
+
+ 5) If a message is selected in the message view mode, the "reload" button
+ will change to represent an "open" button.
+ Clicking on this button will launch the command specified in the
+ configuration file by the selectedmesgcommand parameter.
+
+ 6) to select all the messages, go to the summary view mode and click on
+ "sel:" (left side of the last displayed line).
+ to unselect all the messages, click on the right side of that line.
+
+ 7) To manually check for mail at any time, mouse click on the
+ 2nd button from the left, with a round arrow, if no message is selected.
+
+ 8) To turn off auto mail checking, mouse click on the "ch" button (second
+ from the right).
+
+ 9) If you have more than 7 messages on all your servers you can scroll the
+ window up and down using the up and down arrows or by using the
+ scrollbar.
+
+
+4) known problems / TODO
+
+ 1) wmpop3lb was built on the existing source code of wmpop3, written by
+ Scott Holden ([email protected]).
+ I didn't touch a lot the network functions, which are still using
+ blocking sockets and connections.
+ Because of that, if there is any network problem while waiting for some
+ data, wmpop3lb will hang forever.
+ The only solution, for the moment, is to restart wmpop3lb.
+
+ Next version will use non-blocking sockets.
+
+
+
+
+
+
+
+
+
diff --git a/wmpop3lb/wmgeneral/list.c b/wmpop3lb/wmgeneral/list.c
new file mode 100644
index 0000000..f804b2c
--- /dev/null
+++ b/wmpop3lb/wmgeneral/list.c
@@ -0,0 +1,169 @@
+/* Generic single linked list to keep various information
+ Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+
+
+Author: Kresten Krab Thorup
+
+Many modifications by Alfredo K. Kojima
+
+
+This file is part of GNU CC.
+
+GNU CC 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; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with files compiled with
+ GCC to produce an executable, this does not cause the resulting executable
+ to be covered by the GNU General Public License. This exception does not
+ however invalidate any other reasons why the executable file might be
+ covered by the GNU General Public License. */
+
+#include "list.h"
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#include <stdlib.h>
+
+/* Return a cons cell produced from (head . tail) */
+
+INLINE LinkedList*
+list_cons(void* head, LinkedList* tail)
+{
+ LinkedList* cell;
+
+ cell = (LinkedList*)malloc(sizeof(LinkedList));
+ cell->head = head;
+ cell->tail = tail;
+ return cell;
+}
+
+/* Return the length of a list, list_length(NULL) returns zero */
+
+INLINE int
+list_length(LinkedList* list)
+{
+ int i = 0;
+ while(list)
+ {
+ i += 1;
+ list = list->tail;
+ }
+ return i;
+}
+
+/* Return the Nth element of LIST, where N count from zero. If N
+ larger than the list length, NULL is returned */
+
+INLINE void*
+list_nth(int index, LinkedList* list)
+{
+ while(index-- != 0)
+ {
+ if(list->tail)
+ list = list->tail;
+ else
+ return 0;
+ }
+ return list->head;
+}
+
+/* Remove the element at the head by replacing it by its successor */
+
+INLINE void
+list_remove_head(LinkedList** list)
+{
+ if (!*list) return;
+ if ((*list)->tail)
+ {
+ LinkedList* tail = (*list)->tail; /* fetch next */
+ *(*list) = *tail; /* copy next to list head */
+ free(tail); /* free next */
+ }
+ else /* only one element in list */
+ {
+ free(*list);
+ (*list) = 0;
+ }
+}
+
+
+/* Remove the element with `car' set to ELEMENT */
+/*
+INLINE void
+list_remove_elem(LinkedList** list, void* elem)
+{
+ while (*list)
+ {
+ if ((*list)->head == elem)
+ list_remove_head(list);
+ *list = (*list ? (*list)->tail : NULL);
+ }
+}*/
+
+INLINE LinkedList *
+list_remove_elem(LinkedList* list, void* elem)
+{
+ LinkedList *tmp;
+
+ if (list) {
+ if (list->head == elem) {
+ tmp = list->tail;
+ free(list);
+ return tmp;
+ }
+ list->tail = list_remove_elem(list->tail, elem);
+ return list;
+ }
+ return NULL;
+}
+
+
+/* Return element that has ELEM as car */
+
+INLINE LinkedList*
+list_find(LinkedList* list, void* elem)
+{
+ while(list)
+ {
+ if (list->head == elem)
+ return list;
+ list = list->tail;
+ }
+ return NULL;
+}
+
+/* Free list (backwards recursive) */
+
+INLINE void
+list_free(LinkedList* list)
+{
+ if(list)
+ {
+ list_free(list->tail);
+ free(list);
+ }
+}
+
+/* Map FUNCTION over all elements in LIST */
+
+INLINE void
+list_mapcar(LinkedList* list, void(*function)(void*))
+{
+ while(list)
+ {
+ (*function)(list->head);
+ list = list->tail;
+ }
+}
diff --git a/wmpop3lb/wmgeneral/list.h b/wmpop3lb/wmgeneral/list.h
new file mode 100644
index 0000000..af0f22c
--- /dev/null
+++ b/wmpop3lb/wmgeneral/list.h
@@ -0,0 +1,59 @@
+/* Generic single linked list to keep various information
+ Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+
+Author: Kresten Krab Thorup
+
+This file is part of GNU CC.
+
+GNU CC 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; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with files compiled with
+ GCC to produce an executable, this does not cause the resulting executable
+ to be covered by the GNU General Public License. This exception does not
+ however invalidate any other reasons why the executable file might be
+ covered by the GNU General Public License. */
+
+#ifndef __LIST_H_
+#define __LIST_H_
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+# define INLINE inline
+#else
+# define INLINE
+#endif
+
+typedef struct LinkedList {
+ void *head;
+ struct LinkedList *tail;
+} LinkedList;
+
+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_remove_head(LinkedList** list);
+
+INLINE LinkedList *list_remove_elem(LinkedList* list, void* elem);
+
+INLINE void list_mapcar(LinkedList* list, void(*function)(void*));
+
+INLINE LinkedList*list_find(LinkedList* list, void* elem);
+
+INLINE void list_free(LinkedList* list);
+
+#endif
diff --git a/wmpop3lb/wmgeneral/misc.c b/wmpop3lb/wmgeneral/misc.c
new file mode 100644
index 0000000..34281e2
--- /dev/null
+++ b/wmpop3lb/wmgeneral/misc.c
@@ -0,0 +1,164 @@
+/* dock.c- built-in Dock module for WindowMaker
+ *
+ * WindowMaker window manager
+ *
+ * Copyright (c) 1997 Alfredo K. Kojima
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include "list.h"
+#include "misc.h"
+
+/*
+ *----------------------------------------------------------------------
+ * parse_command--
+ * Divides a command line into a argv/argc pair.
+ *----------------------------------------------------------------------
+ */
+#define PRC_ALPHA 0
+#define PRC_BLANK 1
+#define PRC_ESCAPE 2
+#define PRC_DQUOTE 3
+#define PRC_EOS 4
+#define PRC_SQUOTE 5
+
+typedef struct {
+ short nstate;
+ short output;
+} DFA;
+
+
+static DFA mtable[9][6] = {
+ {{3,1},{0,0},{4,0},{1,0},{8,0},{6,0}},
+ {{1,1},{1,1},{2,0},{3,0},{5,0},{1,1}},
+ {{1,1},{1,1},{1,1},{1,1},{5,0},{1,1}},
+ {{3,1},{5,0},{4,0},{1,0},{5,0},{6,0}},
+ {{3,1},{3,1},{3,1},{3,1},{5,0},{3,1}},
+ {{-1,-1},{0,0},{0,0},{0,0},{0,0},{0,0}}, /* final state */
+ {{6,1},{6,1},{7,0},{6,1},{5,0},{3,0}},
+ {{6,1},{6,1},{6,1},{6,1},{5,0},{6,1}},
+ {{-1,-1},{0,0},{0,0},{0,0},{0,0},{0,0}}, /* final state */
+};
+
+char*
+next_token(char *word, char **next)
+{
+ char *ptr;
+ char *ret, *t;
+ int state, ctype;
+
+ t = ret = malloc(strlen(word)+1);
+ ptr = word;
+
+ state = 0;
+ *t = 0;
+ while (1) {
+ if (*ptr==0)
+ ctype = PRC_EOS;
+ else if (*ptr=='\\')
+ ctype = PRC_ESCAPE;
+ else if (*ptr=='"')
+ ctype = PRC_DQUOTE;
+ else if (*ptr=='\'')
+ ctype = PRC_SQUOTE;
+ else if (*ptr==' ' || *ptr=='\t')
+ ctype = PRC_BLANK;
+ else
+ ctype = PRC_ALPHA;
+
+ if (mtable[state][ctype].output) {
+ *t = *ptr; t++;
+ *t = 0;
+ }
+ state = mtable[state][ctype].nstate;
+ ptr++;
+ if (mtable[state][0].output<0) {
+ break;
+ }
+ }
+
+ if (*ret==0)
+ t = NULL;
+ else
+ t = strdup(ret);
+
+ free(ret);
+
+ if (ctype==PRC_EOS)
+ *next = NULL;
+ else
+ *next = ptr;
+
+ return t;
+}
+
+
+extern void
+parse_command(char *command, char ***argv, int *argc)
+{
+ LinkedList *list = NULL;
+ char *token, *line;
+ int count, i;
+
+ line = command;
+ do {
+ token = next_token(line, &line);
+ if (token) {
+ list = list_cons(token, list);
+ }
+ } while (token!=NULL && line!=NULL);
+
+ count = list_length(list);
+ *argv = malloc(sizeof(char*)*count);
+ i = count;
+ while (list!=NULL) {
+ (*argv)[--i] = list->head;
+ list_remove_head(&list);
+ }
+ *argc = count;
+}
+
+extern pid_t
+execCommand(char *command)
+{
+ pid_t pid;
+ char **argv;
+ int argc;
+
+ parse_command(command, &argv, &argc);
+
+ if (argv==NULL) {
+ return 0;
+ }
+
+ if ((pid=fork())==0) {
+ char **args;
+ int i;
+
+ args = malloc(sizeof(char*)*(argc+1));
+ if (!args)
+ exit(10);
+ for (i=0; i<argc; i++) {
+ args[i] = argv[i];
+ }
+ args[argc] = NULL;
+ execvp(argv[0], args);
+ exit(10);
+ }
+ return pid;
+}
diff --git a/wmpop3lb/wmgeneral/misc.h b/wmpop3lb/wmgeneral/misc.h
new file mode 100644
index 0000000..602e1b7
--- /dev/null
+++ b/wmpop3lb/wmgeneral/misc.h
@@ -0,0 +1,9 @@
+#ifndef __MISC_H
+#define __MISC_H
+
+#include <unistd.h>
+
+extern void parse_command(char *, char ***, int *);
+
+extern pid_t execCommand(char *);
+#endif /* __MISC_H */
diff --git a/wmpop3lb/wmgeneral/wmgeneral.c b/wmpop3lb/wmgeneral/wmgeneral.c
new file mode 100644
index 0000000..6364956
--- /dev/null
+++ b/wmpop3lb/wmgeneral/wmgeneral.c
@@ -0,0 +1,480 @@
+/*
+ Best viewed with vim5, using ts=4
+
+ wmgeneral was taken from wmppp.
+
+ It has a lot of routines which most of the wm* programs use.
+
+ ------------------------------------------------------------
+
+ Author: Martijn Pieterse ([email protected])
+
+ ---
+ CHANGES:
+ ---
+ 14/09/1998 (Dave Clark, [email protected])
+ * Updated createXBMfromXPM routine
+ * Now supports >256 colors
+ 11/09/1998 (Martijn Pieterse, [email protected])
+ * Removed a bug from parse_rcfile. You could
+ not use "start" in a command if a label was
+ also start.
+ * Changed the needed geometry string.
+ We don't use window size, and don't support
+ negative positions.
+ 03/09/1998 (Martijn Pieterse, [email protected])
+ * Added parse_rcfile2
+ 02/09/1998 (Martijn Pieterse, [email protected])
+ * Added -geometry support (untested)
+ 28/08/1998 (Martijn Pieterse, [email protected])
+ * Added createXBMfromXPM routine
+ * Saves a lot of work with changing xpm's.
+ 02/05/1998 (Martijn Pieterse, [email protected])
+ * changed the read_rc_file to parse_rcfile, as suggested by Marcelo E. Magallon
+ * debugged the parse_rc file.
+ 30/04/1998 (Martijn Pieterse, [email protected])
+ * Ripped similar code from all the wm* programs,
+ and put them in a single file.
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+#include <X11/Xlib.h>
+#include <X11/xpm.h>
+#include <X11/extensions/shape.h>
+
+#include "wmgeneral.h"
+
+ /*****************/
+ /* X11 Variables */
+/*****************/
+
+Window Root;
+int screen;
+int x_fd;
+int d_depth;
+XSizeHints mysizehints;
+XWMHints mywmhints;
+Pixel back_pix, fore_pix;
+char *Geometry = "";
+Window iconwin, win;
+GC NormalGC;
+XpmIcon wmgen;
+Pixmap pixmask;
+
+ /*****************/
+ /* Mouse Regions */
+/*****************/
+
+typedef struct {
+ int enable;
+ int top;
+ int bottom;
+ int left;
+ int right;
+} MOUSE_REGION;
+
+MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
+
+ /***********************/
+ /* Function Prototypes */
+/***********************/
+
+static void GetXPM(XpmIcon *, char **);
+static Pixel GetColor(char *);
+void RedrawWindow(void);
+void AddMouseRegion(int, int, int, int, int);
+int CheckMouseRegion(int, int);
+
+/*******************************************************************************\
+|* parse_rcfile *|
+\*******************************************************************************/
+
+void parse_rcfile(const char *filename, rckeys *keys) {
+
+ char *p,*q;
+ char temp[128];
+ char *tokens = " :\t\n";
+ FILE *fp;
+ int i,key;
+
+ fp = fopen(filename, "r");
+ if (fp) {
+ while (fgets(temp, 128, fp)) {
+ key = 0;
+ q = strdup(temp);
+ q = strtok(q, tokens);
+ while (key >= 0 && keys[key].label) {
+ if ((!strcmp(q, keys[key].label))) {
+ p = strstr(temp, keys[key].label);
+ p += strlen(keys[key].label);
+ p += strspn(p, tokens);
+ if ((i = strcspn(p, "#\n"))) p[i] = 0;
+ free(*keys[key].var);
+ *keys[key].var = strdup(p);
+ key = -1;
+ } else key++;
+ }
+ free(q);
+ }
+ fclose(fp);
+ }
+}
+
+/*******************************************************************************\
+|* parse_rcfile2 *|
+\*******************************************************************************/
+
+void parse_rcfile2(const char *filename, rckeys2 *keys) {
+
+ char *p;
+ char temp[128];
+ char *tokens = " :\t\n";
+ FILE *fp;
+ int i,key;
+ char *family = NULL;
+
+ fp = fopen(filename, "r");
+ if (fp) {
+ while (fgets(temp, 128, fp)) {
+ key = 0;
+ while (key >= 0 && keys[key].label) {
+ if ((p = strstr(temp, keys[key].label))) {
+ p += strlen(keys[key].label);
+ p += strspn(p, tokens);
+ if ((i = strcspn(p, "#\n"))) p[i] = 0;
+ free(*keys[key].var);
+ *keys[key].var = strdup(p);
+ key = -1;
+ } else key++;
+ }
+ }
+ fclose(fp);
+ }
+ free(family);
+}
+
+
+/*******************************************************************************\
+|* GetXPM *|
+\*******************************************************************************/
+
+static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
+
+ XWindowAttributes attributes; int err;
+
+ /* For the colormap */
+ XGetWindowAttributes(display, Root, &attributes);
+
+ wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
+
+ err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
+ &(wmgen->mask), &(wmgen->attributes));
+
+ if (err != XpmSuccess) {
+ fprintf(stderr, "Not enough free colorcells.\n");
+ exit(1);
+ }
+}
+
+/*******************************************************************************\
+|* GetColor *|
+\*******************************************************************************/
+
+static Pixel GetColor(char *name) {
+
+ XColor color;
+ XWindowAttributes attributes;
+
+ XGetWindowAttributes(display, Root, &attributes);
+
+ color.pixel = 0;
+ if (!XParseColor(display, attributes.colormap, name, &color)) {
+ fprintf(stderr, "wm.app: can't parse %s.\n", name);
+ } else if (!XAllocColor(display, attributes.colormap, &color)) {
+ fprintf(stderr, "wm.app: can't allocate %s.\n", name);
+ }
+ return color.pixel;
+}
+
+/*******************************************************************************\
+|* flush_expose *|
+\*******************************************************************************/
+
+static int flush_expose(Window w) {
+
+ XEvent dummy;
+ int i=0;
+
+ while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
+ i++;
+
+ return i;
+}
+
+/*******************************************************************************\
+|* RedrawWindow *|
+\*******************************************************************************/
+
+void RedrawWindow(void) {
+
+ flush_expose(iconwin);
+ XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
+ 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
+ flush_expose(win);
+ XCopyArea(display, wmgen.pixmap, win, NormalGC,
+ 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
+}
+
+/*******************************************************************************\
+|* RedrawWindowXY *|
+\*******************************************************************************/
+
+void RedrawWindowXY(int x, int y) {
+
+ flush_expose(iconwin);
+ XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
+ x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
+ flush_expose(win);
+ XCopyArea(display, wmgen.pixmap, win, NormalGC,
+ x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
+}
+
+/*******************************************************************************\
+|* AddMouseRegion *|
+\*******************************************************************************/
+
+void AddMouseRegion(int index, 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;
+ }
+}
+
+/*******************************************************************************\
+|* CheckMouseRegion *|
+\*******************************************************************************/
+
+int CheckMouseRegion(int x, int y) {
+
+ int i;
+ int found;
+
+ found = 0;
+
+ for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
+ if (mouse_region[i].enable &&
+ x <= mouse_region[i].right &&
+ x >= mouse_region[i].left &&
+ y <= mouse_region[i].bottom &&
+ y >= mouse_region[i].top)
+ found = 1;
+ }
+ if (!found) return -1;
+ return (i-1);
+}
+
+/*******************************************************************************\
+|* createXBMfromXPM *|
+\*******************************************************************************/
+void createXBMfromXPM(char *xbm, char **xpm, int sx, int sy) {
+
+ int i,j,k;
+ int width, height, numcol, depth;
+ int zero=0;
+ unsigned char bwrite;
+ int bcount;
+ int curpixel;
+
+ sscanf(*xpm, "%d %d %d %d", &width, &height, &numcol, &depth);
+
+
+ for (k=0; k!=depth; k++)
+ {
+ zero <<=8;
+ zero |= xpm[1][k];
+ }
+
+ for (i=numcol+1; i < numcol+sy+1; i++) {
+ bcount = 0;
+ bwrite = 0;
+ for (j=0; j<sx*depth; j+=depth) {
+ bwrite >>= 1;
+
+ curpixel=0;
+ for (k=0; k!=depth; k++)
+ {
+ curpixel <<=8;
+ curpixel |= xpm[i][j+k];
+ }
+
+ if ( curpixel != zero ) {
+ bwrite += 128;
+ }
+ bcount++;
+ if (bcount == 8) {
+ *xbm = bwrite;
+ xbm++;
+ bcount = 0;
+ bwrite = 0;
+ }
+ }
+ }
+}
+
+/*******************************************************************************\
+|* copyXPMArea *|
+\*******************************************************************************/
+
+void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy) {
+
+ XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
+
+}
+
+/*******************************************************************************\
+|* copyXBMArea *|
+\*******************************************************************************/
+
+void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy) {
+
+ XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
+}
+
+
+/*******************************************************************************\
+|* setMaskXY *|
+\*******************************************************************************/
+
+void setMaskXY(int x, int y) {
+
+ XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
+ XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
+}
+
+/*******************************************************************************\
+|* openXwindow *|
+\*******************************************************************************/
+void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
+
+ unsigned int borderwidth = 1;
+ XClassHint classHint;
+ char *display_name = NULL;
+ char *wname = argv[0];
+ XTextProperty name;
+
+ XGCValues gcv;
+ unsigned long gcm;
+
+ char *geometry = NULL;
+
+ int dummy=0;
+ int i, wx, wy;
+
+ for (i=1; argv[i]; i++) {
+ if (!strcmp(argv[i], "-display")) {
+ display_name = argv[i+1];
+ i++;
+ }
+ if (!strcmp(argv[i], "-geometry")) {
+ geometry = argv[i+1];
+ i++;
+ }
+ }
+
+ if (!(display = XOpenDisplay(display_name))) {
+ fprintf(stderr, "%s: can't open display %s\n",
+ wname, XDisplayName(display_name));
+ exit(1);
+ }
+ screen = DefaultScreen(display);
+ Root = RootWindow(display, screen);
+ d_depth = DefaultDepth(display, screen);
+ x_fd = XConnectionNumber(display);
+
+ /* Convert XPM to XImage */
+ GetXPM(&wmgen, pixmap_bytes);
+
+ /* Create a window to hold the stuff */
+ mysizehints.flags = USSize | USPosition;
+ mysizehints.x = 0;
+ mysizehints.y = 0;
+
+ back_pix = GetColor("white");
+ fore_pix = GetColor("black");
+
+ XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
+ &mysizehints.x, &mysizehints.y,&mysizehints.width,&mysizehints.height, &dummy);
+
+ mysizehints.width = 64;
+ mysizehints.height = 64;
+
+ win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
+ mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
+
+ iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
+ mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
+
+ /* Activate hints */
+ XSetWMNormalHints(display, win, &mysizehints);
+ classHint.res_name = wname;
+ classHint.res_class = wname;
+ XSetClassHint(display, win, &classHint);
+
+ XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
+ XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
+
+ if (XStringListToTextProperty(&wname, 1, &name) == 0) {
+ fprintf(stderr, "%s: can't allocate window name\n", wname);
+ exit(1);
+ }
+
+ XSetWMName(display, win, &name);
+
+ /* Create GC for drawing */
+
+ gcm = GCForeground | GCBackground | GCGraphicsExposures;
+ gcv.foreground = fore_pix;
+ gcv.background = back_pix;
+ gcv.graphics_exposures = 0;
+ NormalGC = XCreateGC(display, Root, gcm, &gcv);
+
+ /* ONLYSHAPE ON */
+
+ pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
+
+ XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
+ XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
+
+ /* ONLYSHAPE OFF */
+
+ mywmhints.initial_state = WithdrawnState;
+ mywmhints.icon_window = iconwin;
+ mywmhints.icon_x = mysizehints.x;
+ mywmhints.icon_y = mysizehints.y;
+ mywmhints.window_group = win;
+ mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
+
+ XSetWMHints(display, win, &mywmhints);
+
+ XSetCommand(display, win, argv, argc);
+ XMapWindow(display, win);
+
+ if (geometry) {
+ if (sscanf(geometry, "+%d+%d", &wx, &wy) != 2) {
+ fprintf(stderr, "Bad geometry string.\n");
+ exit(1);
+ }
+ XMoveWindow(display, win, wx, wy);
+ }
+}
diff --git a/wmpop3lb/wmgeneral/wmgeneral.h b/wmpop3lb/wmgeneral/wmgeneral.h
new file mode 100644
index 0000000..83b0f09
--- /dev/null
+++ b/wmpop3lb/wmgeneral/wmgeneral.h
@@ -0,0 +1,59 @@
+#ifndef WMGENERAL_H_INCLUDED
+#define WMGENERAL_H_INCLUDED
+
+ /***********/
+ /* Defines */
+/***********/
+
+#define MAX_MOUSE_REGION (16)
+
+ /************/
+ /* Typedefs */
+/************/
+
+typedef struct _rckeys rckeys;
+
+struct _rckeys {
+ const char *label;
+ char **var;
+};
+
+typedef struct _rckeys2 rckeys2;
+
+struct _rckeys2 {
+ const char *family;
+ const char *label;
+ char **var;
+};
+
+typedef struct sXpmIcon{
+ Pixmap pixmap;
+ Pixmap mask;
+ XpmAttributes attributes;
+} XpmIcon;
+
+ /*******************/
+ /* Global variable */
+/*******************/
+
+Display *display;
+
+ /***********************/
+ /* Function Prototypes */
+/***********************/
+
+void AddMouseRegion(int 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 RedrawWindow(void);
+void RedrawWindowXY(int x, int y);
+
+void createXBMfromXPM(char *, char **, int, int);
+void copyXPMArea(int, int, int, int, int, int);
+void copyXBMArea(int, int, int, int, int, int);
+void setMaskXY(int, int);
+
+void parse_rcfile(const char *, rckeys *);
+
+#endif
diff --git a/wmpop3lb/wmpop3/.wmpop3rc_test b/wmpop3lb/wmpop3/.wmpop3rc_test
new file mode 100644
index 0000000..efdc236
--- /dev/null
+++ b/wmpop3lb/wmpop3/.wmpop3rc_test
@@ -0,0 +1,62 @@
+# Replace all < > with appropriate data
+#
+autochecking 1 # 1 enables, 0 disables
+viewallmessages 0 # 0 Shows both read and unread messages
+# and 1 shows only unread messages
+displaydelay 2
+scrollspeed 150
+tempdir "/tmp"
+#[server]
+#popserver pop.free.fr
+#port 110 # default port
+#username lbj
+#password 42vm90cx
+#mailcheckdelay 3 # default mail check time in minutes
+#alias flb
+#countunreadonly 0
+#mailclient "netscape -mail"
+
+[server]
+popserver aaricia.france.sun.com
+port 110
+username test2
+password test
+alias a2
+countunreadonly 0
+mailcheckdelay 10
+newmailcommand "echo aa5 %T %t %f %s %m %n %S %a %P"
+maxdlsize 2000
+mailclient "echo aa5 %T %t %f %s %m %n %S %a %P"
+
+[server]
+popserver aaricia.france.sun.com
+port 110
+username test4
+password test
+alias 4
+countunreadonly 0
+mailcheckdelay 1
+newmailcommand "echo %c %C"
+maxdlsize 650
+mailclient "echo %c %C"
+selectedmesgcommand "echo %c %C"
+mailseparator "
+From -
+"
+
+[server]
+popserver aaricia.france.sun.com
+port 110
+username test3
+password test
+alias aa3
+countunreadonly 0
+mailcheckdelay 1
+newmailcommand "echo %f %s %m"
+maxdlsize -1
+mailclient "echo %f %s %m"
+selectedmesgcommand "emacs %C"
+
+
+
+
diff --git a/wmpop3lb/wmpop3/.wmpop3rc_test~ b/wmpop3lb/wmpop3/.wmpop3rc_test~
new file mode 100644
index 0000000..dd02565
--- /dev/null
+++ b/wmpop3lb/wmpop3/.wmpop3rc_test~
@@ -0,0 +1,62 @@
+# Replace all < > with appropriate data
+#
+autochecking 1 # 1 enables, 0 disables
+viewallmessages 0 # 0 Shows both read and unread messages
+# and 1 shows only unread messages
+displaydelay 2
+scrollspeed 150
+tempdir "/tmp"
+#[server]
+#popserver pop.free.fr
+#port 110 # default port
+#username lbj
+#password 42vm90cx
+#mailcheckdelay 3 # default mail check time in minutes
+#alias flb
+#countunreadonly 0
+#mailclient "netscape -mail"
+
+[server]
+popserver aaricia.france.sun.com
+port 110
+username test2
+password test
+alias a2
+countunreadonly 0
+mailcheckdelay 10
+newmailcommand "echo aa5 %T %t %f %s %m %n %S %a %P"
+maxdlsize 2000
+mailclient "echo aa5 %T %t %f %s %m %n %S %a %P"
+
+[server]
+popserver aaricia.france.sun.com
+port 110
+username test4
+password test
+alias 4
+countunreadonly 0
+mailcheckdelay 1
+newmailcommand "echo %c"
+maxdlsize 650
+mailclient "echo %T %t %c %S %a %P %u %w"
+selectedmesgcommand "emacs %C"
+mailseparator "
+From -
+"
+
+[server]
+popserver aaricia.france.sun.com
+port 110
+username test3
+password test
+alias aa3
+countunreadonly 0
+mailcheckdelay 1
+newmailcommand "echo %f %s %m"
+maxdlsize -1
+mailclient "echo %f %s %m"
+selectedmesgcommand "emacs %C"
+
+
+
+
diff --git a/wmpop3lb/wmpop3/Makefile b/wmpop3lb/wmpop3/Makefile
new file mode 100644
index 0000000..f154d25
--- /dev/null
+++ b/wmpop3lb/wmpop3/Makefile
@@ -0,0 +1,47 @@
+LIBDIR = -L/usr/X11R6/lib
+LIBS = -lXpm -lXext -lX11
+FLAGS = -g2 -D_DEBUG
+OBJS = wmpop3.o \
+ Pop3Client.o \
+ ../wmgeneral/wmgeneral.o \
+ ../wmgeneral/misc.o \
+ ../wmgeneral/list.o
+
+
+.c.o:
+ cc -I/usr/X11R6/share/include $(FLAGS) -c -Wall $< -o $*.o
+
+wmpop3lb: $(OBJS)
+ cc $(FLAGS) -o wmpop3lb $^ -lXext $(LIBDIR) $(LIBS)
+
+all:: wmpop3lb
+
+clean::
+ for i in $(OBJS) ; do \
+ rm -f $$i ; \
+ done
+ rm -f wmpop3lb
+ rm -f *~
+
+install:: wmpop3lb
+ @echo "Use 'make install1' for system install."
+ @echo "Use 'make install2' for single user install."
+ @echo
+
+install1:: wmpop3lb
+ cp -f wmpop3lb /usr/local/bin/
+ chmod 755 /usr/local/bin/wmpop3lb
+ chown root:root /usr/local/bin/wmpop3lb
+ @echo
+ @echo "WMPop3 Installation finished..."
+
+install2:: wmpop3lb
+ mkdir $(HOME)/wmpop3lb
+ cp -f wmpop3lb $(HOME)/wmpop3lb
+ chmod 755 $(HOME)/wmpop3lb
+ @echo "WMPop3 Installation finished..."
+ @echo
+ @echo "Make sure ~/wmpop3 is in your path"
+ @echo
+ @echo "Please run wmpop3lb once and then edit ~/.wmpop3rc"
+
diff --git a/wmpop3lb/wmpop3/Pop3Client.c b/wmpop3lb/wmpop3/Pop3Client.c
new file mode 100644
index 0000000..184eeec
--- /dev/null
+++ b/wmpop3lb/wmpop3/Pop3Client.c
@@ -0,0 +1,591 @@
+/* Author : Louis-Benoit JOURDAIN ([email protected])
+ * based on the original work by Scott Holden ( [email protected] )
+ *
+ * multi Pop3 Email checker.
+ *
+ * Last Updated : Feb 7th, 2002
+ *
+ */
+
+
+#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>
+
+#include <X11/xpm.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/shape.h>
+
+#include "../wmgeneral/misc.h"
+#include "../wmgeneral/wmgeneral.h"
+
+#include "Pop3Client.h"
+
+/* return size if all goes well, -1 if not expected answer */
+int send_command(char *exp_answer, char **retour, Pop3 pc)
+{
+ int size;
+
+ send(pc->s, &pc->outBuf,strlen(pc->outBuf),0);
+ size = recv(pc->s,pc->inBuf,1024,0);
+ memset(*retour,0,1024);
+ memcpy(*retour,pc->inBuf,size);
+ if (strncmp(pc->inBuf, exp_answer, strlen(exp_answer))) {
+ return (-1);
+ }
+ return (size);
+}
+
+Pop3 pop3Create(int num)
+{
+ Pop3 pc;
+
+ pc = (Pop3)malloc( sizeof(*pc) );
+ if( pc == 0)
+ return 0;
+ memset(pc, 0, sizeof(*pc));
+ pc->connected = NOT_CONNECTED;
+ pc->serverport = 110;
+ pc->mailCheckDelay = 10;
+ /* make sure we perform an action first time we receive mail */
+ pc->forcedCheck = 1;
+ pc->sizechanged = -1;
+ pc->maxdlsize = -1;
+ sprintf(pc->alias, "nb%d", num);
+ return (pc);
+}
+int pop3MakeConnection(Pop3 pc, char *serverName, int port){
+
+ pc->s = socket(AF_INET, SOCK_STREAM, 0 );
+ memset( &(pc->server), 0 , sizeof(pc->server));
+ pc->server.sin_family = AF_INET;
+ pc->hp = gethostbyname(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(port);
+ if ( connect(pc->s, (struct sockaddr *)&(pc->server)
+ , sizeof(pc->server)) < 0 )
+ return -1;
+ pc->connected = CONNECTED;
+ return 0;
+}
+
+int pop3IsConnected(Pop3 pc){
+
+ if( pc->connected == CONNECTED)
+ return 1;
+ return 0;
+}
+
+int pop3Login(Pop3 pc, char *name, char *pass){
+
+ int size;
+ char temp[1024];
+
+ if( pc->connected == NOT_CONNECTED ){
+ perror("Not Connected To Server\n");
+ 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\n");
+ return -1;
+ }
+
+ sprintf(pc->outBuf,"USER %s\r\n",name);
+ 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\n");
+ return -1;
+ }
+
+ memset(pc->outBuf,0,1024);
+ sprintf(pc->outBuf,"PASS %s\r\n",pass);
+ 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\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int store_from(char *buf, int pos, int buflen, int num, Pop3 pc) {
+ int end;
+ int deb_addr;
+ int fin_addr;
+ int i;
+
+ /* strip the white spaces */
+ for (; (pos < buflen) && isspace(buf[pos]); pos++);
+ /* get the end of the line */
+ for (end = pos; (end + 1 < buflen) &&
+ (buf[end] != '\r') && (buf[end + 1] != '\n'); end++);
+ /* try to find the '@' sign for the address */
+ for (i = pos; (i < end) && buf[i] != '@'; i++);
+ if (i < end) { /* we found a @ sign before the end of the line */
+ for (deb_addr = i; deb_addr > pos && !isspace(buf[deb_addr]); deb_addr--);
+ while (isspace(buf[deb_addr]) || ('<' == buf[deb_addr]))
+ deb_addr++;
+ for (fin_addr = i; fin_addr < end && !isspace(buf[fin_addr]); fin_addr++);
+ if ('>' == buf[fin_addr - 1])
+ fin_addr--;
+ memcpy(pc->mails[num].from, buf + deb_addr,
+ (fin_addr - deb_addr > MAIL_BUFLEN) ?
+ MAIL_BUFLEN : fin_addr - deb_addr);
+ }
+ else {
+ memcpy(pc->mails[num].from, buf + pos,
+ (end - pos > MAIL_BUFLEN) ? MAIL_BUFLEN : end - pos);
+ }
+ return (end + 2);
+}
+
+int store_subject(char *buf, int pos, int buflen, int num, Pop3 pc) {
+ int end;
+ int i;
+
+ /* get the end of the line */
+ for (end = pos, i = 0; (i < MAIL_BUFLEN) && (end + 1 < buflen) &&
+ (buf[end] != '\r') && (buf[end + 1] != '\n'); end++, i++);
+ for (; (pos < buflen) && (buf[pos] == ' '); pos++);
+ memcpy(pc->mails[num].subject, buf + pos, end - pos);
+ return (end + 2);
+}
+
+int parse_header(char *buf, int buflen, int num, Pop3 pc) {
+ int pos = 0;
+ int retour = 1;
+
+ /* parse the header for the from and subject fields */
+#ifdef _DEBUG
+ printf(" parse_header, buflen: %d, num %d, buf:\n%s\n",
+ buflen, num, buf);
+#endif
+ while (pos < buflen) {
+ if ((buflen > (pos + 2)) && !strncmp(".\r\n", buf + pos, 3)) {
+ /* this is the end */
+ pos = buflen;
+ retour = 0;
+ }
+ else if ((buflen > (pos + 4)) && !strncmp("From:", buf + pos, 5)) {
+ pos += 5;
+ pos = store_from(buf, pos, buflen, num, pc);
+ }
+ else if ((buflen > (pos + 7)) && !strncmp("Subject:", buf + pos, 8)) {
+ pos += 8;
+ pos = store_subject(buf, pos, buflen, num, pc);
+ }
+ else {
+ for( ; (buflen > (pos + 2)) && (buf[pos] != '\r') &&
+ (buf[pos + 1] != '\n'); pos++);
+ pos += 2;
+ }
+ }
+ return (retour);
+}
+
+int pop3VerifStats(Pop3 pc)
+{
+ int retour = 0;
+ char *ptr;
+ int size;
+
+ 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);
+ if( pc->inBuf[0] != '+' ){
+ perror("Error Receiving Stats");
+ return (-1);
+ }
+ ptr = strtok(pc->inBuf, " ");
+ ptr = strtok( 0," ");
+ ptr = strtok( 0, " ");
+ if (ptr)
+ retour = atoi(ptr);
+ return (retour);
+}
+
+long calculate_cksum(char *buf, int len) {
+ int i;
+ long cumul;
+
+ for (i = 0, cumul = 0; i < len; i++) {
+ cumul += (long) buf[i];
+ }
+ return (cumul);
+}
+
+int is_in_old_mails(long cksum, t_mail *oldmails, int numold) {
+ int i;
+
+ for (i = 0; i < numold; i++) {
+ if (oldmails[i].cksum == cksum)
+ return (1);
+ }
+ return (0);
+}
+
+int pop3CheckMail(Pop3 pc) {
+ int size;
+ char temp[4096];
+ char *ptr;
+ int i;
+ int pass;
+ int go;
+ int old_sizeOfAllMessages;
+ int old_numOfMessages;
+ int progressbarpos = 0;
+ t_mail *oldmails;
+
+ if( pc->connected == NOT_CONNECTED )
+ return -1;
+ /* save the old values */
+ old_sizeOfAllMessages = pc->sizeOfAllMessages;
+ old_numOfMessages = pc->numOfMessages;
+ /* 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);
+ pc->inBuf[size] = '\0';
+#ifdef _DEBUG
+ printf(" pop3CheckMail, stat received buf (size=%d): [%s]\n",
+ size, pc->inBuf);
+#endif
+ memset(temp,0,1024);
+ memcpy(temp,pc->inBuf,size);
+ if( temp[0] != '+' ){
+#ifdef _DEBUG
+ printf(" Error Receiving Stats: [%s]\n", temp);
+#endif
+ return (-1);
+ }
+
+ ptr = strtok(temp, " ");
+ ptr = strtok( 0," ");
+ pc->numOfMessages = atoi(ptr);
+
+ /* save the old messages */
+ oldmails = pc->mails;
+ pc->mails = NULL;
+ /* allocate space for the new ones */
+ if (pc->numOfMessages) {
+ if (NULL ==
+ (pc->mails = (t_mail *) malloc (sizeof(t_mail) * pc->numOfMessages))) {
+ fprintf(stderr, "can't allocate memory for message structure\n");
+ /* clear the old messages */
+ if (oldmails) {
+ free (oldmails);
+ }
+ return (-1);
+ }
+ /* Display the progress bar */
+ copyXPMArea(ORIG_PB_TX, ORIG_PB_TY, PROGRESSBAR_LEN, PROGRESSBAR_HEI,
+ PROGRESSBAR_HPOS, PROGRESSBAR_VPOS);
+ RedrawWindow();
+ }
+
+ ptr = strtok( 0, " ");
+ pc->sizeOfAllMessages = atoi(ptr);
+ /* -1 means first time */
+ if (-1 != pc->sizechanged)
+ pc->sizechanged = (old_sizeOfAllMessages != pc->sizeOfAllMessages);
+
+ sprintf(pc->outBuf,"LAST\r\n");
+ send(pc->s, pc->outBuf, strlen(pc->outBuf),0 );
+ size = recv(pc->s,pc->inBuf,1024,0);
+ pc->inBuf[size] = '\0';
+#ifdef _DEBUG
+ printf(" pop3CheckMail, last received buf (size=%d): [%s]\n",
+ size, pc->inBuf);
+#endif
+ memset(temp,0,1024);
+ memcpy(temp,pc->inBuf,size);
+ if( temp[0] != '+' ){
+#ifdef _DEBUG
+ printf(" Error Receiving LAST: [%s]\n", temp);
+#endif
+ pc->numOfUnreadMessages = pc->numOfMessages;
+ }
+ else {
+ ptr = strtok(temp, " ");
+ ptr = strtok( 0," ");
+ pc->numOfUnreadMessages = pc->numOfMessages - atoi(ptr);
+ }
+ /* get the subject and From fields of numOfMessages mails */
+ for (i = 0; i < pc->numOfMessages; i++) {
+#ifdef _DEBUG
+ printf(" ---- message %d ---\n", i);
+#endif
+ /* increment the progress bar by 1 message */
+ progressbarpos = (int) ((i + 1) * (PROGRESSBAR_LEN - 2)) /
+ pc->numOfMessages;
+ copyXPMArea(ORIG_PB_BARX, ORIG_PB_BARY, progressbarpos, 2,
+ PROGRESSBAR_HPOS + 1, PROGRESSBAR_VPOS + 2);
+ RedrawWindow();
+ /* reset the from and subject fields for num */
+ memset(&pc->mails[i], 0, sizeof(t_mail));
+ sprintf(pc->outBuf, "TOP %d 0\r\n", i + 1);
+ send(pc->s, pc->outBuf, strlen(pc->outBuf), 0);
+ pass = 0;
+ go = 1;
+ while (go && (0 < (size = recv(pc->s,pc->inBuf,4096,0)))) {
+ memset(temp, 0, 4096);
+ memcpy(temp, pc->inBuf, size);
+ if (!pass && (temp[0] != '+')) {
+ fprintf(stderr, "Error while getting TOP %d 0\n", i + 1);
+ go = 0;
+ /* must set the from and subject fields to correct value */
+ strncpy(pc->mails[i].from, "::error::", 9);
+ continue;
+ }
+ /* calculate the checksum */
+ pc->mails[i].cksum += calculate_cksum(temp, size);
+ pass++;
+ go = parse_header(temp, size, i, pc);
+ }
+ pc->mails[i].todelete = 0;
+ /* verify if this message is new or not */
+ pc->mails[i].new = !is_in_old_mails(pc->mails[i].cksum, oldmails,
+ old_numOfMessages);
+#ifdef _DEBUG
+ printf(" mess %d, cksum: %ld, new: %d\n",
+ i, pc->mails[i].cksum, pc->mails[i].new);
+#endif
+ }
+ /* clear the old messages */
+ if (oldmails) {
+ free (oldmails);
+ }
+ return 1;
+}
+
+int pop3WriteOneMail(int nb, int dest_fd, Pop3 pc)
+{
+ int len;
+ int retour = 0;
+ char buf[4096];
+ char temp[4096];
+ int size;
+ int pass = 0;
+ int go = 1;
+ char *deb, *fin;
+ int theemailsize = 0;
+ int mustdisconnect = 0;
+
+
+ if (NOT_CONNECTED == pc->connected) {
+#ifdef _DEBUG
+ printf(" pop3WriteOneMail not connected, connecting\n");
+#endif
+ if (pop3MakeConnection(pc,pc->popserver,pc->serverport) == -1){
+ return (1);
+ }
+ if (pop3Login(pc, pc->username, pc->password) == -1) {
+ return (1);
+ }
+ mustdisconnect = 1;
+ }
+ /* check the size */
+#ifdef _DEBUG
+ printf(" pc->maxdlsize = [%d]\n", pc->maxdlsize);
+#endif
+ if (-1 != pc->maxdlsize) {
+ sprintf(pc->outBuf, "LIST %d\r\n", nb);
+#ifdef _DEBUG
+ printf(" pop3WriteOneMail: %s", pc->outBuf);
+#endif
+ send(pc->s, pc->outBuf, strlen(pc->outBuf), 0);
+ size = recv(pc->s, pc->inBuf, 4096, 0);
+#ifdef _DEBUG
+ printf(" received %d bytes\n", size);
+#endif
+ memset(temp, 0, 4096);
+ memcpy(temp, pc->inBuf, size);
+#ifdef _DEBUG
+ printf(" pop3WriteOneMail: answer [%s]\n", temp);
+#endif
+ if (temp[0] != '+') {
+ sprintf(buf, TXT_ERROR, pc->mails[nb - 1].from,
+ pc->mails[nb - 1].subject, pc->outBuf);
+ write (dest_fd, buf, strlen(buf));
+#ifdef _DEBUG
+ printf(" bad answer: [%s]\n", pc->inBuf);
+#endif
+ return (0);
+ }
+ /* go get the size of the email, strip +OK */
+ for (deb = temp; *deb && !isspace(*deb); deb++);
+ /* strip the spaces */
+ for (; *deb && isspace(*deb); deb++);
+ /* strip the email number */
+ for (; *deb && !isspace(*deb); deb++);
+ /* strip the last spaces */
+ for (; *deb && isspace(*deb); deb++);
+ /* go to the end of the size */
+ for (fin = deb; *fin && !isspace(*fin); fin++);
+ if (*deb && *fin) {
+ memcpy(buf, deb, fin - deb);
+ buf[fin - deb] = '\0';
+ theemailsize = atoi(buf);
+#ifdef _DEBUG
+ printf(" email retrieved size: %d\n", theemailsize);
+#endif
+ if (theemailsize > pc->maxdlsize) {
+ sprintf(buf, TXT_MESSAGETOOBIG, pc->mails[nb - 1].from,
+ pc->mails[nb - 1].subject, theemailsize, pc->maxdlsize);
+ write (dest_fd, buf, strlen(buf));
+#ifdef _DEBUG
+ printf(" email too big, return\n");
+#endif
+ return (0);
+ }
+ }
+ /* else {}
+ the command is screwed up, never mind, continue to download the mail */
+ }
+
+
+ sprintf(pc->outBuf, "RETR %d\r\n", nb);
+#ifdef _DEBUG
+ printf(" pop3WriteOneMail: %s", pc->outBuf);
+#endif
+ send(pc->s, pc->outBuf, strlen(pc->outBuf), 0);
+ while (go && (size = recv(pc->s, pc->inBuf, 4096, 0))) {
+#ifdef _DEBUG
+ printf(" received %d bytes\n", size);
+#endif
+ memset(temp, 0, 4096);
+ memcpy(temp, pc->inBuf, size);
+ deb = temp;
+ if (!pass) {
+ if (temp[0] != '+') {
+ sprintf(buf, TXT_ERROR, pc->mails[nb - 1].from,
+ pc->mails[nb - 1].subject, pc->outBuf);
+ write (dest_fd, buf, strlen(buf));
+ retour = 1;
+ go = 0;
+ continue;
+ }
+#ifdef _DEBUG
+ printf(" first pass, skeep RETR answer ([%s])\n", deb);
+#endif
+ /* skip the RETR answer, go to the end of the line; */
+ for (;*deb && ('\n' != *deb); deb++);
+ deb++;
+ }
+ /* check if these are the final bits of the message */
+ fin = temp + size - 5;
+#ifdef _DEBUG
+ printf(" size: %d, fin: [%s]\n", size, fin);
+#endif
+ if (size >= 5) {
+ if (!strncmp(fin, "\r\n.\r\n", 5)) {
+ go = 0;
+ /* don't write the final '.' into the message, skip it*/
+ size -= 3;
+#ifdef _DEBUG
+ printf(" skeeping final '.', new size=%d\n", size);
+#endif
+ }
+ }
+ else
+ go = 0;
+#ifdef _DEBUG
+ printf(" buffer (long: %d):\n[%s]\n", (temp + size) - deb, deb);
+#endif
+ len = 0;
+ while (deb < (temp + size)) {
+ len = write(dest_fd, deb, (temp + size) - deb);
+ deb += len;
+ }
+#ifdef _DEBUG
+ printf(" wrote %d bytes\n", len);
+#endif
+ pass++;
+ }
+ if (mustdisconnect) {
+#ifdef _DEBUG
+ printf(" pop3WriteOneMail disconnecting\n");
+#endif
+ pop3Quit(pc);
+ }
+#ifdef _DEBUG
+ printf(" pop3WriteOneMail, return\n");
+#endif
+ return (retour);
+}
+
+int pop3DeleteMail(int num, Pop3 pc)
+{
+ int size;
+
+ sprintf(pc->outBuf, "DELE %d\r\n", num);
+#ifdef _DEBUG
+ printf(" %s\n", pc->outBuf);
+#endif
+ send(pc->s, pc->outBuf, strlen(pc->outBuf), 0);
+ size = recv(pc->s, pc->inBuf, 4096, 0);
+ if ('+' != pc->inBuf[0]) {
+ perror("error while deleting mail");
+ return (1);
+ }
+ return (0);
+}
+
+
+
+
+int pop3GetTotalNumberOfMessages( Pop3 pc ){
+ if( pc != 0 )
+ return pc->numOfMessages;
+ return -1;
+}
+
+int pop3GetNumberOfUnreadMessages( Pop3 pc ){
+ if( pc != 0)
+ return pc->numOfUnreadMessages;
+ return -1;
+}
+
+int pop3Quit(Pop3 pc){
+ int size;
+
+#ifdef _DEBUG
+ printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n");
+ printf("XXXXXX pop3Quit -------- disconneting XXXXXXXXX\n");
+ printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n");
+#endif
+ 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;
+ if(pc->s != 0)
+ close(pc->s);
+ return 0;
+
+}
+
+
+
diff --git a/wmpop3lb/wmpop3/Pop3Client.h b/wmpop3lb/wmpop3/Pop3Client.h
new file mode 100644
index 0000000..043a62a
--- /dev/null
+++ b/wmpop3lb/wmpop3/Pop3Client.h
@@ -0,0 +1,146 @@
+/* Author : Louis-Benoit JOURDAIN ([email protected])
+ * based on the original work by Scott Holden ( [email protected] )
+ *
+ * multi Pop3 Email checker.
+ *
+ * Last Updated : Feb 7th, 2002
+ *
+ */
+
+
+#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>
+#include <ctype.h>
+#include <sys/poll.h>
+
+#define MAIL_BUFLEN 64
+#define CONF_BUFLEN 256
+
+#define RSET_COLOR color = 0
+#define SWAP_COLOR color = 1 - color
+#define CH_COLOR(a) (color) ? a + 24 : a
+
+#define WMPOP3_VERSION "2.4.2"
+
+#define CHAR_WIDTH 5
+#define CHAR_HEIGHT 5
+#define TOP_MARGIN 5
+#define LEFT_MARGIN 4
+#define NUMBERS 93
+#define LETTERS 85
+#define SMALL_NUM 77
+#define SN_CHAR_W 3
+#define NB_DISP 8
+#define EXTRA 1
+#define NB_LINE 7
+#define SEC_IN_MIN 60
+#define YES 1
+#define NO 0
+#define SELECTONLY 1
+#define NOSELECTONLY 0
+
+/* get mail progress bar */
+#define PROGRESSBAR_LEN 48
+#define PROGRESSBAR_HEI 6
+#define PROGRESSBAR_HPOS 10
+#define PROGRESSBAR_VPOS ((6*6) + TOP_MARGIN)
+
+#define ORIG_PB_TX 72
+#define ORIG_PB_TY 65
+
+#define ORIG_PB_BARX 73
+#define ORIG_PB_BARY 71
+
+#define SCROLL_LX 4 /* left X coordinate */
+#define SCROLL_RX 6 /* right X coordinate */
+#define SCROLL_TY 4 /* top Y coordinate */
+#define SCROLL_BY 45 /* botton Y coordinate */
+#define SCROLL_W 3
+#define SCROLL_H 38 /* this is without SCROLL_EXT at each end */
+#define SCROLL_EXT 2
+
+#define TMPPREFIX "Pop3tmp"
+#define TMPPREFIXLEN 7
+#define TXT_MESSAGETOOBIG "From: %s\n\
+Subject: %s\n\n\
+\
+The size of this email (%d) is above the configured maxdlsize value (%d) and\
+ was not downloaded\n"
+
+#define TXT_ERROR "From: %s\n\
+Subject: %s\n\n\
+\
+There was an error (%s) while getting this email from the server\n"
+
+#define TXT_SEPARATOR "--------------------------------------------------------------------\n"
+
+typedef struct s_scrollbar
+{
+ int top;
+ int bottom;
+ int orig_y;
+ int orig_index_vert;
+ int allowedspace;
+} t_scrollbar;
+
+typedef struct s_mail
+{
+ char from[MAIL_BUFLEN];
+ char subject[MAIL_BUFLEN];
+ char todelete;
+ long cksum; /* checksum of the header */
+ int new; /* mail is new */
+} t_mail;
+
+struct pop3_struct{
+ struct sockaddr_in server;
+ struct hostent *hp;
+ enum {CONNECTED, NOT_CONNECTED} connected;
+ char **mailclient; /* argv[] type of command */
+ char **newmailcommand; /* argv[] type of command */
+ char **selectedmesgcommand; /* argv[] type of command */
+ char username[256];
+ char popserver[128];
+ char password[256];
+ char mailseparator[256];
+ char inBuf[4096];
+ char outBuf[1024];
+ char alias[4];
+ char delstatus[9];
+ int s; /* socket */
+ int serverport;
+ int localPort;
+ int numOfMessages;
+ int numOfUnreadMessages;
+ int countunreadonly;
+ int sizeOfAllMessages;
+ int sizechanged;
+ int mailCheckDelay;
+ int forcedCheck;
+ int status;
+ int maxdlsize;
+ long nextCheckTime;
+ t_mail *mails;
+};
+typedef struct pop3_struct *Pop3;
+
+
+Pop3 pop3Create(int nb_conf);
+int pop3MakeConnection( Pop3 pc, char *serverName, int port);
+int pop3IsConnected(Pop3 pc);
+int pop3Login(Pop3 pc, char *name, char *pass);
+int pop3Quit(Pop3 pc);
+int pop3CheckMail(Pop3 pc);
+int pop3GetTotalNumberOfMessages( Pop3 pc );
+int pop3GetNumberOfUnreadMessages( Pop3 pc );
+int pop3WriteOneMail(int nb, int dest_fd, Pop3 pc);
+#endif
diff --git a/wmpop3lb/wmpop3/wmpop3.c b/wmpop3lb/wmpop3/wmpop3.c
new file mode 100644
index 0000000..a7f4649
--- /dev/null
+++ b/wmpop3lb/wmpop3/wmpop3.c
@@ -0,0 +1,1707 @@
+/*
+ * wmpop3.c
+ * multi pop3 mail checker.
+ * written by Louis-Benoit JOURDAIN ([email protected])
+ * based on the original work by Scott Holden ([email protected])
+ *
+*/
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+
+#include <X11/xpm.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/shape.h>
+
+#include <dirent.h>
+
+#include "../wmgeneral/misc.h"
+#include "../wmgeneral/wmgeneral.h"
+#include "Pop3Client.h"
+
+#include "wmpop3.xpm"
+
+char wminet_mask_bits[64*64];
+int wminet_mask_width = 64;
+int wminet_mask_height = 64;
+
+char *ProgName;
+
+char mailclient[32] = "pine";
+char password[32];
+char username[32];
+char popserver[128];
+int serverport = 110;
+int mailCheckDelay = 10; /* default */
+int autoChecking = YES; /* default */
+int newMessagesOnly = YES; /* default */
+int displaydelay = 1;
+char tempdir[1024];
+char config_file[256] = "not-defined";
+int scrollspeed = 100;
+
+Pop3 conf[6];
+int nb_conf; /* number of configured pop servers */
+int summess; /* total number of messages */
+int color;
+
+#ifdef _DEBUG
+int haspassed = 0;
+#endif
+
+t_scrollbar scrollbar;
+
+void usage(void);
+void printversion(void);
+void wmCheckMail_routine(int, char **);
+int readConfigFile( char *filename );
+
+void BlitString(char *name, int x, int y, int fragment);
+void BlitNum(int num, int x, int y, int todelete);
+
+int pop3DeleteMail(int num, Pop3 pc);
+int pop3VerifStats(Pop3 pc);
+
+/********************************
+ * Main Program
+ ********************************/
+void deleteoldtmpfiles()
+{
+ char buf[1024];
+ DIR *dir;
+ struct dirent *dp;
+
+ if (tempdir) {
+ if ((dir = opendir(tempdir))) {
+ chdir(tempdir);
+ while((dp = readdir(dir))) {
+ if (!strncmp(dp->d_name, TMPPREFIX, TMPPREFIXLEN)) {
+ sprintf(buf, "%s/%s", tempdir, dp->d_name);
+#ifdef _DEBUG
+ printf(" delete old tmp file: %s\n", buf);
+#endif
+ unlink(buf);
+ }
+ }
+ closedir(dir);
+ }
+ }
+}
+
+int main(int argc, char *argv[]) {
+
+ int i;
+
+ ProgName = argv[0];
+ if (strlen(ProgName) >= 5)
+ ProgName += (strlen(ProgName) - 5);
+
+ 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(config_file, argv[i+1]);
+ i++;
+ }
+ break;
+ default:
+ usage();
+ exit(0);
+ break;
+ }
+ }
+ }
+ wmCheckMail_routine(argc, argv);
+
+ return 0;
+}
+
+void build_line(char *buf, int num, int index, Pop3 pc)
+{
+ int len;
+ int pos;
+ char tmp[256];
+
+ /* display spaces in case alias is less than 3 char long */
+ memset(tmp, ' ', sizeof(char) * 3);
+ memset(tmp + 3, 0, sizeof(char) * (256 - 3));
+ memcpy(tmp, pc->alias, strlen(pc->alias));
+ tmp[3] = ':';
+ pos = 4;
+ for (len = 0; len < MAIL_BUFLEN && pc->mails[num].from[len]; len++);
+ memcpy(tmp + pos, pc->mails[num].from, len);
+ tmp[pos + len] = '/';
+ pos += len + 1;
+ for (len = 0; len < MAIL_BUFLEN && pc->mails[num].subject[len]; len++);
+ memcpy(tmp + pos, pc->mails[num].subject, len);
+ len += pos;
+ tmp[len++] = ' ';
+ tmp[len++] = '*';
+ tmp[len++] = ' ';
+ tmp[len] = '\0';
+ pos = index % len;
+ if (len - pos < (NB_DISP + EXTRA)) { /* We are at the end of the string */
+ memcpy(buf, tmp + pos, len - pos);
+ memcpy(buf + len - pos, tmp, (NB_DISP + EXTRA) - len + pos);
+ }
+ else {
+ memcpy(buf, tmp + pos, NB_DISP + EXTRA);
+ }
+}
+
+void display_index(int mail_index, int line, Pop3 pc)
+{
+#ifdef _DEBUG
+ if (haspassed) {
+ printf(" mail_index: %d, line: %d, todelete: %d\n",
+ mail_index, line, pc->mails[mail_index].todelete);
+ }
+#endif
+ if (pc->mails[mail_index].todelete) {
+ copyXPMArea(67, 12, 2, 5, 7, (line * 6) + TOP_MARGIN);
+ }
+ else {
+ copyXPMArea(69, 11, 2, 6, 7, (line * 6) + TOP_MARGIN - 1);
+ }
+}
+
+void ClearDisplay() {
+ int i;
+
+ copyXPMArea(72, 4, 3, 42, LEFT_MARGIN, 4);
+ copyXPMArea(72, 4, 50, 42, 9, 4 );
+ for (i = 0; i < NB_LINE; i++) {
+ copyXPMArea(69, 11, 2, 6, 7, (i * 6) + TOP_MARGIN - 1);
+ }
+}
+
+/* return < 0 if error
+ 0 if no pb
+ else nb of mails which couldn't be deleted */
+int DeleteMail(Pop3 pc)
+{
+ int etat = 0;
+ int old_sizeOfAllMessages;
+ int i;
+
+ old_sizeOfAllMessages = pc->sizeOfAllMessages;
+ BlitString(pc->alias, 10, TOP_MARGIN, 0);
+ BlitString("connect", 10, 6*2 + TOP_MARGIN, 0);
+ RedrawWindow();
+ etat = pop3MakeConnection(pc, pc->popserver, pc->serverport);
+ if (-1 != etat) {
+ BlitString("login", 10, (6*3) + TOP_MARGIN, 0);
+ RedrawWindow();
+ etat = pop3Login(pc, pc->username, pc->password);
+ }
+ if (-1 != etat) {
+ BlitString("chk cont", 10, (6*4) + TOP_MARGIN, 0);
+ RedrawWindow();
+ etat = pop3VerifStats(pc);
+ }
+ if (-1 != etat) {
+ if (etat != old_sizeOfAllMessages) {
+ BlitString("mailbox", 10, TOP_MARGIN, 0);
+ BlitString("content", 10, 6 + TOP_MARGIN, 0);
+ BlitString("changed", 10, 6*2 + TOP_MARGIN, 0);
+ BlitString("between", 10, 6*3 + TOP_MARGIN, 0);
+ BlitString("updates", 10, 6*4 + TOP_MARGIN, 0);
+ BlitString("del can.", 10, 6*6 + TOP_MARGIN, 0);
+ RedrawWindow();
+ sleep(displaydelay);
+ for (i = 0, etat = 0; i < pc->numOfMessages; i++) {
+ etat += pc->mails[i].todelete;
+ }
+ }
+ else {
+ etat = 0;
+ for (i = 0; i < pc->numOfMessages; i++) {
+ if (pc->mails[i].todelete) {
+ etat += pop3DeleteMail(i + 1, pc);
+ }
+ }
+ }
+ }
+ pop3Quit(pc);
+ return (etat);
+}
+
+/*
+void launch_mail_client(int iS)
+{
+ int i;
+ int j;
+ char str[16];
+ char **args;
+
+ ClearDisplay();
+ if ((args = conf[iS]->mailclient)) {
+ BlitString("starting", 10, TOP_MARGIN, 0);
+ for (i = 0; i < 5 && args[i]; i++) {
+ for (j = 0; j < 8 && args[i][j]; j++);
+ memcpy(str, args[i], j);
+ str[j] = '\0';
+ BlitString(str, 10, (i + 2)*6 + TOP_MARGIN, 0);
+ }
+ if (0 == fork()) {
+ if (execvp(args[0], args)) {
+ perror("execvp");
+ copyXPMArea(72, 4, 3, 42, LEFT_MARGIN, 4);
+ copyXPMArea(72, 4, 50, 6, 9, 4 );
+ copyXPMArea(69, 11, 2, 6, 7, TOP_MARGIN - 1);
+ BlitString("Error", 10, TOP_MARGIN, 0);
+ }
+ }
+ else {
+ conf[iS]->nextCheckTime = time(0) + 30;
+ }
+ }
+ else {
+ BlitString(" mail", 10, TOP_MARGIN, 0);
+ BlitString(" client", 10, 6 + TOP_MARGIN, 0);
+ BlitString("not set", 10, 6*2 + TOP_MARGIN, 0);
+ BlitString(" check", 15, 6*5 + TOP_MARGIN, 0);
+ BlitString("wmpop3rc", 10, 6*6 + TOP_MARGIN, 0);
+ }
+ RedrawWindow();
+ sleep(displaydelay);
+}
+*/
+
+void display_scrollbar(int index, int totalmessages,
+ int maxlines, int scrollmode)
+{
+ int delta;
+ int scrollen;
+ int vertpos;
+
+ if (totalmessages <= maxlines) {
+#ifdef _DEBUG
+ if (haspassed)
+ printf(" full scrollbar\n");
+#endif
+ copyXPMArea((scrollmode) ? 68 : 65, 18, SCROLL_W,
+ SCROLL_H + (2 * SCROLL_EXT), SCROLL_LX, SCROLL_TY);
+ scrollbar.top = SCROLL_TY;
+ scrollbar.bottom = SCROLL_TY + SCROLL_H;
+ scrollbar.allowedspace = SCROLL_H;
+ }
+ else {
+ delta = totalmessages - maxlines;
+ /* determine the size of the scrollbar */
+ if (0 >= (scrollen = SCROLL_H - ((SCROLL_H / maxlines) * delta)))
+ scrollen = 1;
+ /* determine the position */
+ scrollbar.allowedspace = SCROLL_H - scrollen;
+ vertpos = scrollbar.allowedspace * index / delta;
+ copyXPMArea((scrollmode) ? 68 : 65, 18, SCROLL_W, SCROLL_EXT,
+ SCROLL_LX, vertpos + SCROLL_TY);
+ copyXPMArea((scrollmode) ? 68 : 65, 18 + SCROLL_EXT, SCROLL_W, scrollen,
+ SCROLL_LX, vertpos + SCROLL_TY + SCROLL_EXT);
+ copyXPMArea((scrollmode) ? 68 : 65, 18 + SCROLL_EXT + SCROLL_H,
+ SCROLL_W, SCROLL_EXT,
+ SCROLL_LX, vertpos + SCROLL_TY + SCROLL_EXT + scrollen);
+ scrollbar.top = vertpos + SCROLL_TY;
+ scrollbar.bottom = vertpos + SCROLL_TY + (SCROLL_EXT * 2) + scrollen;
+
+#ifdef _DEBUG
+ if (haspassed) {
+ printf(" index: %d, totalmess:%d, mxli: %d, delta: %d, vertpos: %d, allowedspace: %d, sl:%d\n",
+ index, totalmessages, maxlines, delta, vertpos,
+ scrollbar.allowedspace, scrollen);
+ }
+#endif
+ }
+ /* RedrawWindow(); */
+}
+
+int is_for_each_mail(char **command)
+{
+ int i;
+
+ if (command) {
+ for (i = 0; command[i]; i++) {
+ if ('%' == command[i][0]) {
+ if (('f' == command[i][1]) ||
+ ('s' == command[i][1]) ||
+ ('m' == command[i][1]) ||
+ ('n' == command[i][1]))
+ return (1);
+ }
+ }
+ }
+ return (0);
+}
+
+char *quotify(char *str)
+{
+ char *retour;
+ int len;
+
+ len = strlen(str);
+ if (NULL != (retour = (char *) malloc(sizeof(char) * len + 3))) {
+ retour[0] = '\'';
+ memcpy(retour + 1, str, len);
+ retour[len + 1] = '\'';
+ retour[len + 2] = '\0';
+ }
+ return (retour);
+}
+
+/* nb: number of the mail on the server - 1 (if -1: for all mails)
+ path: allocated buffer to store path of tmp file
+ newonly: only for new messages
+ onlyselected: only for selected messages
+ pc: main struct.
+ on success return 0 */
+int writemailstofile(int nb, char *path, int newonly,
+ int onlyselected, Pop3 pc)
+{
+ int fd;
+ int len;
+ int i;
+ int retour = 0;
+ int goforwritemail = 0;
+ int mustdisconnect = 0;
+
+ len = strlen(tempdir);
+ if (len) {
+ path[0] = '\0';
+ strcat(path, tempdir);
+ if ('/' != tempdir[len - 1])
+ strcat(path, "/");
+ strcat(path, TMPPREFIX);
+ strcat(path, "XXXXXX");
+#ifdef _DEBUG
+ printf(" creating temporary file [%s]\n", path);
+ printf(" nb=%d, newonly=%d, onlyselected=%d\n",
+ nb, newonly, onlyselected);
+#endif
+ if (-1 == (fd = mkstemp(path))) {
+ fprintf(stderr, "Error: writing mail to file\n");
+ perror(path);
+ retour++;
+ }
+ else {
+ /* to prevent connecting many times, do it now. */
+ if (NOT_CONNECTED == pc->connected) {
+#ifdef _DEBUG
+ printf(" writemailstofile not connected, connecting\n");
+#endif
+ if (pop3MakeConnection(pc,pc->popserver,pc->serverport) == -1){
+ return (1);
+ }
+ if (pop3Login(pc, pc->username, pc->password) == -1) {
+ return (1);
+ }
+ mustdisconnect = 1;
+ }
+
+ if (nb < 0) {
+ /* concatenate all the mails into 1 file */
+ for (i = 0; i < pc->numOfMessages; i++) {
+ goforwritemail = 0;
+#ifdef _DEBUG
+ printf(" mail %d:", i);
+#endif
+ if (!newonly && !onlyselected) {
+#ifdef _DEBUG
+ printf(" !newonly && !onlyselected\n");
+#endif
+ goforwritemail = 1;
+ }
+ else if (newonly) {
+ if (pc->mails[i].new &&
+ (!onlyselected || (onlyselected && pc->mails[i].todelete))) {
+#ifdef _DEBUG
+ printf(" newonly\n");
+#endif
+ goforwritemail = 1;
+ }
+ }
+ else if (onlyselected && pc->mails[i].todelete) {
+#ifdef _DEBUG
+ printf(" onlyselected\n");
+#endif
+ goforwritemail = 1;
+ }
+ if (goforwritemail) {
+ /* put the mail separator */
+ if (strlen(pc->mailseparator)) {
+#ifdef _DEBUG
+ printf(" pc->mailseparator: [%s]\n", pc->mailseparator);
+#endif
+ write(fd, pc->mailseparator, strlen(pc->mailseparator));
+ }
+ else {
+#ifdef _DEBUG
+ printf(" TXT_SEPARATOR: [%s]\n", TXT_SEPARATOR);
+#endif
+ write(fd, TXT_SEPARATOR, strlen(TXT_SEPARATOR));
+ }
+ if (pop3WriteOneMail(i + 1, fd, pc)) {
+ retour++;
+ }
+ }
+ }
+
+ }
+ else {
+ if (pop3WriteOneMail(nb + 1, fd, pc))
+ retour++;
+ }
+ close(fd);
+ /* close the connection if we've opened it */
+ if (mustdisconnect) {
+#ifdef _DEBUG
+ printf(" writemailstofile disconnecting\n");
+#endif
+ pop3Quit(pc);
+ }
+ }
+ }
+ else {
+ fprintf(stderr, "no tempdir configured, can't create file\n");
+ retour++;
+ }
+ return (retour);
+}
+
+/*
+ * do_command_completion
+ * returned array should be freed by calling function
+ * if nbnewmail == 0, for %c option concatenate _all_ the messages
+ */
+char **do_command_completion(int num, char **command,
+ int nbnewmail, Pop3 pc)
+{
+ char **retour;
+ int i;
+ int yaerreur = 0;
+ char path[1024];
+
+ for (i = 0; command[i]; i++);
+#ifdef _DEBUG
+ printf(" %d args to the command, mail num %d\n", i, num);
+#endif
+ if (NULL == (retour = (char **) malloc (sizeof(char *) * i + 1))) {
+ return (NULL);
+ }
+ memset(retour, 0, sizeof(char *) * i + 1);
+ for (i = 0; command[i]; i++) {
+#ifdef _DEBUG
+ printf(" arg %d: [%s]\n", i, command[i]);
+#endif
+ if ('%' == command[i][0]) {
+ switch (command[i][1]) {
+ case 'T': /* total nb of mails */
+ if (NULL != (retour[i] = (char *) malloc(sizeof(char) * 8)))
+ sprintf(retour[i], "%d", pc->numOfMessages);
+ else
+ yaerreur = 1;
+ break;
+ case 't': /* total nb of new mails */
+ if (NULL != (retour[i] = (char *) malloc(sizeof(char) * 8)))
+ sprintf(retour[i], "%d", (nbnewmail < 0) ? 0 : 1);
+ else
+ yaerreur = 1;
+ break;
+ case 'C': /* concatenate all the selected mails in 1 file */
+ if (writemailstofile(-1, path, 0, SELECTONLY, pc))
+ yaerreur = 1;
+ else
+ if (NULL == (retour[i] = strdup(path))) {
+ yaerreur = 1;
+ }
+ break;
+ case 'c': /* concatenate all the mails in 1 file */
+ if (writemailstofile(-1, path, (nbnewmail > 0), NOSELECTONLY, pc))
+ yaerreur = 1;
+ else
+ if (NULL == (retour[i] = strdup(path))) {
+ yaerreur = 1;
+ }
+ break;
+ case 'f': /* from field */
+#ifdef _DEBUG
+ printf(" from field: [%s]\n", pc->mails[num].from);
+#endif
+ if (NULL == (retour[i] = quotify(pc->mails[num].from)))
+ yaerreur = 1;
+ break;
+ case 's': /* subject of the mail */
+#ifdef _DEBUG
+ printf(" subject field: [%s]\n", pc->mails[num].subject);
+#endif
+ if (NULL == (retour[i] = quotify(pc->mails[num].subject)))
+ yaerreur = 1;
+ break;
+ case 'm': /* copy the mail to tmp file */
+ if (0 <= num) {
+ if (writemailstofile(num, path, (nbnewmail > 0), NOSELECTONLY, pc))
+ yaerreur = 1;
+ else
+ if (NULL == (retour[i] = strdup(path))) {
+ yaerreur = 1;
+ }
+ }
+ break;
+ case 'n': /* number of the message on the mail server */
+ if (NULL != (retour[i] = (char *) malloc(sizeof(char) * 8)))
+ sprintf(retour[i], "%d", num + 1);
+ else
+ yaerreur = 1;
+ break;
+ case 'S': /* server name */
+ if (NULL == (retour[i] = strdup(pc->popserver)))
+ yaerreur = 1;
+ break;
+ case 'a': /* server alias */
+ if (NULL == (retour[i] = strdup(pc->alias)))
+ yaerreur = 1;
+ break;
+ case 'u': /* user name */
+ if (NULL == (retour[i] = strdup(pc->username)))
+ yaerreur = 1;
+ break;
+ case 'w': /* user password */
+ if (NULL == (retour[i] = strdup(pc->password)))
+ yaerreur = 1;
+ break;
+ case 'P': /* server port */
+ if (NULL != (retour[i] = (char *) malloc(sizeof(char) * 8)))
+ sprintf(retour[i], "%d", pc->serverport);
+ else
+ yaerreur = 1;
+ break;
+ case '%': /* % character, leave in place */
+ if (NULL == (retour[i] = strdup(command[i])))
+ yaerreur = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ else {
+#ifdef _DEBUG
+ printf(" just copying arg [%s]\n", command[i]);
+#endif
+ if (NULL == (retour[i] = strdup(command[i])))
+ yaerreur = 1;
+ }
+ }
+ retour[i] = NULL;
+#ifdef _DEBUG
+ printf(" retour: %ld\n", (long) retour);
+#endif
+ if (!yaerreur)
+ return (retour);
+ else
+ return (NULL);
+}
+
+/* num is the index of the mail in the mail array
+ if num == -1, means that the command isn't for each mail */
+
+
+void spawn_command(int num, char **command, int nbnewmail,
+ char *display, Pop3 pc)
+{
+ char **tmpcommand;
+ char str[16];
+ int i, j;
+
+ if (display) {
+ ClearDisplay();
+ if (!command) {
+ BlitString(display, 10, 6 + TOP_MARGIN, 0);
+ BlitString("not set", 10, 6*2 + TOP_MARGIN, 0);
+ BlitString(" check", 15, 6*5 + TOP_MARGIN, 0);
+ BlitString("wmpop3rc", 10, 6*6 + TOP_MARGIN, 0);
+ }
+ else {
+ BlitString("starting", 10, TOP_MARGIN, 0);
+ for (i = 0; i < 5 && command[i]; i++) {
+ for (j = 0; j < 8 && command[i][j]; j++);
+ memcpy(str, command[i], j);
+ str[j] = '\0';
+ BlitString(str, 10, (i + 2)*6 + TOP_MARGIN, 0);
+ }
+ RedrawWindow();
+ }
+ }
+ if (command) {
+ /* check for any '%' sign in the command and complete it */
+ tmpcommand = do_command_completion(num, command, nbnewmail, pc);
+ if (tmpcommand) {
+ /* launch the command in a new process */
+ if (0 == fork()) {
+#ifdef _DEBUG
+ printf(" spawning command: [");
+ for (i = 0; tmpcommand[i]; i++) {
+ printf(" %s ", tmpcommand[i]);
+ }
+ printf("]\n");
+#endif
+ if (execvp(tmpcommand[0], tmpcommand)) {
+ perror("execvp");
+ }
+ }
+ else {
+ if (display) {
+ /* set the check delay to 30 seconds */
+ pc->nextCheckTime = time(0) + 30;
+ }
+ /* free the memory (in the parent process...) */
+ for (i = 0; tmpcommand[i]; i++) {
+ free (tmpcommand[i]);
+ }
+ free (tmpcommand);
+ }
+ }
+ else {
+ if (display) {
+ ClearDisplay();
+ BlitString(" Error", 15, TOP_MARGIN, 0);
+ BlitString(" While", 15, 6*2 + TOP_MARGIN, 0);
+ BlitString("parsing", 15, 6*3 + TOP_MARGIN, 0);
+ BlitString("command", 15, 6*4 +TOP_MARGIN, 0);
+ BlitString(display, 10, 6*6 + TOP_MARGIN, 0);
+ fprintf(stderr, "Error while parsing %s\n", display);
+ }
+ else
+ fprintf(stderr, "Error while parsing command\n");
+ }
+ }
+ if (display) {
+ RedrawWindow();
+ sleep(displaydelay);
+ }
+}
+
+/*
+ * wmCheckMail_routine : This function is used to set up the X display
+ * for wmpop3 and check for mail every n number of minutes.
+ */
+
+void wmCheckMail_routine(int argc, char **argv){
+
+ int buttonStatus = -1;
+ int iS;
+ Pop3 pc;
+ int i, j, k;
+ XEvent Event;
+ char str[256];
+ int index = 0;
+ int fragment = 0;
+ int index_vert = 0;
+ int oldnbmess = 0;
+ int nbsel;
+ int selectedmess;
+ int justreloaded;
+ long thistime;
+ char *linestodel[7];
+ int unreachable;
+ long sleeplenght;
+ int scrollmode = 0;
+ int nbnewmail;
+ char separ;
+
+ if( !strcmp( config_file, "not-defined") )
+ sprintf(config_file, "%s/.wmpop3rc", getenv("HOME"));
+
+ if( readConfigFile(config_file) == -1){
+ exit(0);
+ }
+ /* Set up timer for checking mail */
+ createXBMfromXPM(wminet_mask_bits, wmpop3_xpm
+ , wminet_mask_width, wminet_mask_height);
+
+ openXwindow(argc, argv, wmpop3_xpm, wminet_mask_bits
+ , wminet_mask_width, wminet_mask_height);
+
+ AddMouseRegion(0, 19, 49, 30, 58); /* check button */
+ AddMouseRegion(1, 46, 49, 50, 58 ); /* autocheck button */
+ AddMouseRegion(2, 53, 49, 57, 58 ); /* switch display button */
+ AddMouseRegion(3, 5, 49, 16, 58 ); /* delete button */
+ AddMouseRegion(4, 33, 49, 44, 53); /* top arrow */
+ AddMouseRegion(5, 33, 54, 44, 58); /* botton arrow */
+ /* add the mouse regions for each line */
+ for (i = 0; i < NB_LINE; i++) {
+ AddMouseRegion(6 + i, 9, (i*6) + TOP_MARGIN,
+ 58, (i*6) + TOP_MARGIN + CHAR_HEIGHT);
+ }
+
+
+ /* Check if Autochecking is on or off */
+ if(autoChecking == NO ){
+ copyXPMArea(142, 38, 7, 11, 45, 48);
+ }
+ else {
+ copyXPMArea(142, 49, 7, 11, 45, 48);
+ }
+
+ RedrawWindow();
+
+ summess = 0;
+
+ deleteoldtmpfiles();
+
+ sleeplenght = (long) 20000L + (20000L - (20000L * scrollspeed / 100));
+ while (1) {
+ RSET_COLOR;
+ for (iS = 0; iS < nb_conf; iS++) {
+ pc = conf[iS];
+ if( (((time(0) > pc->nextCheckTime) ||
+ (pc->nextCheckTime == 0)) && ( autoChecking == YES))
+ || (pc->forcedCheck == YES)){
+ justreloaded = 1;
+ ClearDisplay();
+ BlitString(pc->alias, 10, TOP_MARGIN, 0);
+ BlitString("connect", 10, (6*2) + TOP_MARGIN, 0);
+ RedrawWindow();
+ pc->status = 0;
+ if(pop3MakeConnection(pc,pc->popserver,pc->serverport) == -1){
+ pc->status = 1;
+ }
+ if (!pc->status) {
+ BlitString("login", 10, (6*3) + TOP_MARGIN, 0);
+ RedrawWindow();
+ if (pop3Login(pc, pc->username, pc->password) == -1 )
+ pc->status = 2;
+ }
+ if (!pc->status) {
+ BlitString("get mail", 10, (6*4) + TOP_MARGIN, 0);
+ RedrawWindow();
+ if (pop3CheckMail(pc) == -1)
+ pc->status = 3;
+ }
+ pc->nextCheckTime = time(0) + (pc->mailCheckDelay * SEC_IN_MIN);
+ index = 0;
+ pc->forcedCheck = NO;
+ /* check if new mail has arrived */
+ for (i = 0, nbnewmail = 0; i < pc->numOfMessages; i++)
+ if (pc->mails[i].new)
+ nbnewmail++;
+ /* launch the new mail command */
+ if (pc->newmailcommand && (-1 != pc->sizechanged)) {
+ if (nbnewmail) {
+#ifdef _DEBUG
+ printf(" %d New mail(s) ha(s)(ve) arrived!\n", nbnewmail);
+#endif
+ if (is_for_each_mail(pc->newmailcommand)) {
+ for (i = 0; i < pc->numOfMessages; i++)
+ if (pc->mails[i].new)
+ spawn_command(i, pc->newmailcommand, nbnewmail, NULL, pc);
+ }
+ else {
+ spawn_command(-1, pc->newmailcommand, nbnewmail, NULL, pc);
+ }
+ }
+ }
+ /* close the connection */
+ pop3Quit(pc);
+ pc->sizechanged = 0;
+ }
+ }
+ waitpid(0, NULL, WNOHANG);
+ /* reset the number of messages */
+ unreachable = 1;
+ for (summess = 0, iS = 0; iS < nb_conf; iS++) {
+ pc = conf[iS];
+ if (!pc->status) {
+ unreachable = 0;
+ summess += pc->numOfMessages;
+ }
+ }
+ /* set the offset from the beginning of the list */
+ if (summess != oldnbmess) {
+ oldnbmess = summess;
+ if (summess < NB_LINE)
+ index_vert = 0;
+ else {
+ index_vert = summess - NB_LINE;
+ }
+ }
+ memset(str, 0, 128);
+ /* clear the display */
+ ClearDisplay();
+ nbsel = 0;
+ for (iS = 0; iS < nb_conf; iS++) {
+ pc = conf[iS];
+ for (i = 0; i < summess && i < pc->numOfMessages; i++) {
+#ifdef _DEBUG
+ if (haspassed) {
+ printf(" %s, mails[%d], todelete=%d\n",
+ pc->alias, i, pc->mails[i].todelete);
+ }
+#endif
+ nbsel += pc->mails[i].todelete;
+ }
+ }
+ if (justreloaded) {
+ /* make sure we display the correct buttons */
+ justreloaded = 0;
+ if ((NO == newMessagesOnly) && nbsel)
+ copyXPMArea(128,49 ,14 ,11 ,18 ,48 );
+ else
+ copyXPMArea(128,27 ,14 ,11 ,18 ,48 );
+ }
+ if (newMessagesOnly == YES ){
+ /* Show messages waiting */
+ RSET_COLOR;
+ for (color = 0, iS = 0; iS < nb_conf; iS++) {
+ pc = conf[iS];
+ if (pc->countunreadonly)
+ separ = '-';
+ else
+ separ = ':';
+ switch(pc->status) {
+ case 1:
+ sprintf(str, "%-3s%cC*ER", pc->alias, separ);
+ break;
+ case 2:
+ sprintf(str, "%-3s%cL*ER", pc->alias, separ);
+ break;
+ case 3:
+ sprintf(str, "%-3s%cM*ER", pc->alias, separ);
+ break;
+ default:
+ sprintf(str, "%-3s%c %3d", pc->alias, separ,
+ (pc->countunreadonly) ? pc->numOfUnreadMessages :
+ pc->numOfMessages);
+ break;
+ }
+ BlitString(str, 10, (int) (6*iS) + TOP_MARGIN, 0);
+ SWAP_COLOR;
+ }
+ RSET_COLOR;
+ sprintf(str, "sel.: %2d", nbsel);
+ BlitString(str, 10, (int) (6*6) + TOP_MARGIN, 0);
+ }
+ else {
+ RSET_COLOR;
+ if (0 == summess) {
+ if (unreachable) {
+ BlitString(" error", 10, TOP_MARGIN, 0);
+ }
+ else {
+ BlitString("No Mesg", 10, TOP_MARGIN, 0);
+ }
+ if (autoChecking == YES) {
+ BlitString(" next", 10, 6*2 + TOP_MARGIN, 0);
+ BlitString(" update", 10, 6*3 + TOP_MARGIN, 0);
+ j = SEC_IN_MIN * 1000;
+ thistime = time(0);
+ for (i = 0, k = 0; i < nb_conf; i++) {
+ if ((conf[i]->nextCheckTime - thistime) < j) {
+ j = conf[i]->nextCheckTime - thistime;
+ k = i;
+ }
+ }
+ sprintf(str, " is:%s", conf[k]->alias);
+ BlitString(str, 10, 6*4 + TOP_MARGIN, 0);
+ BlitString(" in", 10, 6*5 + TOP_MARGIN, 0);
+ sprintf(str, "%-5d s.", j);
+ BlitString(str, 10, 6*6 + TOP_MARGIN, 0);
+ }
+ }
+ else {
+ RSET_COLOR;
+ /* iS = index in the conf struct
+ i = index of the mail
+ j = line nb on display */
+ memset(linestodel, 0, sizeof(char *));
+ for (iS = 0, j = 0; iS < nb_conf && j < NB_LINE + index_vert; iS++) {
+ pc = conf[iS];
+ for (i = 0; (j < NB_LINE + index_vert) && i < pc->numOfMessages;
+ j++, i++) {
+ if (j >= index_vert) {
+ build_line(str, i, index, pc);
+ BlitString(str, 10, ((j - index_vert) * 6) + TOP_MARGIN,
+ fragment);
+ display_index(i, (j - index_vert), pc);
+ /* store the address of the delete flag, so that it will */
+ /* be easier to modify it afterwards */
+ linestodel[j - index_vert] = &(pc->mails[i].todelete);
+ }
+ }
+ SWAP_COLOR;
+ }
+ display_scrollbar(index_vert, summess, NB_LINE, scrollmode);
+ }
+ fragment++;
+ if (0 == (fragment % (CHAR_WIDTH + 1))) {
+ index++;
+ fragment = 0;
+ /* printf("index=%d, fragment=%d\n", index, fragment); */
+ }
+ }
+#ifdef _DEBUG
+ haspassed = 0;
+#endif
+
+ RedrawWindow();
+
+ RSET_COLOR;
+ /* X Events */
+ while (XPending(display)){
+ XNextEvent(display, &Event);
+ switch (Event.type) {
+ case Expose:
+ RedrawWindow();
+ break;
+ case DestroyNotify:
+ XCloseDisplay(display);
+ exit(0);
+ break;
+ case MotionNotify:
+ if (scrollmode) {
+#ifdef _DEBUG
+ printf(" ca bouge... index_vert before = %d, %d x %d, allowedspace: %d, summess: %d\n",
+ index_vert,
+ Event.xbutton.x, Event.xbutton.y,
+ scrollbar.allowedspace,
+ summess);
+
+#endif
+ if (summess > NB_LINE) {
+ index_vert = scrollbar.orig_index_vert +
+ ((Event.xbutton.y - scrollbar.orig_y) * (summess - NB_LINE) /
+ scrollbar.allowedspace);
+ if (0 > index_vert)
+ index_vert = 0;
+ if (index_vert + NB_LINE > summess)
+ index_vert = summess - NB_LINE;
+ }
+#ifdef _DEBUG
+ printf(" deplacement de %d pixels --> index_vert = %d\n",
+ Event.xbutton.y - scrollbar.orig_y, index_vert);
+#endif
+ }
+ break;
+ case ButtonPress:
+ buttonStatus = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
+ if (buttonStatus >= 0){
+ switch (buttonStatus){
+ case 0 : /* check / open button pressed */
+ if ((NO == newMessagesOnly) && nbsel)
+ copyXPMArea(128, 60 ,14 ,11 ,18 ,48 );
+ else
+ copyXPMArea(128,38 ,14 ,11 ,18 ,48 );
+ break;
+ case 1 : /* autocheck button pressed */
+ break;
+ case 2: /* switch display button pressed */
+ break;
+ case 3: /* delete button pressed */
+ copyXPMArea(127, 15, 14, 11, 4, 48);
+ break;
+ case 4: /* top arrow button pressed */
+ break;
+ case 5: /* bottom arrow button pressed */
+ break;
+ default:
+ break;
+ }
+ RedrawWindow();
+ }
+ else if (SCROLL_LX <= Event.xbutton.x && SCROLL_RX >= Event.xbutton.x
+ && scrollbar.top <= Event.xbutton.y &&
+ scrollbar.bottom >= Event.xbutton.y) {
+ scrollbar.orig_y = Event.xbutton.y;
+ scrollbar.orig_index_vert = index_vert;
+ scrollmode = 1;
+ }
+ break;
+ case ButtonRelease:
+ i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
+
+ if (buttonStatus == i && buttonStatus >= 0){
+ switch (buttonStatus){
+ case 0 : /* check button */
+ if (nbsel && !newMessagesOnly) {
+ copyXPMArea(128,49 ,14 ,11 ,18 ,48 );
+ /* this is where you launch the open mail command */
+ for (iS = 0; iS < nb_conf; iS++) {
+ pc = conf[iS];
+ for (i = 0, selectedmess = 0; i < pc->numOfMessages; i++) {
+ if (pc->mails[i].todelete) {
+ selectedmess = 1;
+ break;
+ }
+ }
+ if (selectedmess) {
+#ifdef _DEBUG
+ printf(" launching selectedmesgcommand command for conf %d\n",
+ iS);
+#endif
+
+ if (is_for_each_mail(pc->selectedmesgcommand)) {
+#ifdef _DEBUG
+ if (!pc->numOfMessages) {
+ printf(" command is for each mail but there's no mail\n");
+ }
+ else
+ printf(" command is for each mail\n");
+#endif
+ for (i = 0; i < pc->numOfMessages; i++)
+ spawn_command(i, pc->selectedmesgcommand, 0,
+ "selectm.", pc);
+ }
+ else {
+ spawn_command(-1, pc->selectedmesgcommand, 0,
+ "selectm.", pc);
+ }
+ }
+ }
+ }
+ else {
+ copyXPMArea(128,27 ,14 ,11 ,18 ,48 );
+ for (iS = 0; iS < nb_conf; iS++)
+ conf[iS]->forcedCheck = YES;
+ }
+ break;
+ case 1 : /* autocheck Button */
+ if (autoChecking == YES){
+ autoChecking = NO;
+ copyXPMArea(142, 38, 7, 11, 45, 48);
+ }
+ else {
+ autoChecking = YES;
+ for (iS = 0; iS < nb_conf; iS++)
+ conf[iS]->nextCheckTime = time(0) +
+ (conf[iS]->mailCheckDelay * SEC_IN_MIN);
+ copyXPMArea(142, 49, 7, 11, 45, 48);
+ }
+ break;
+ case 2: /* switch display Button */
+ index = 0;
+ /* change view on # of messages */
+ if( newMessagesOnly == YES ) {
+ newMessagesOnly = NO;
+ copyXPMArea(149,38 , 7 , 11, 52, 48);
+ if (nbsel) {
+ copyXPMArea(128,49,14,11,18,48);
+ }
+ else {
+ copyXPMArea(128,27,14,11,18,48);
+ }
+ }
+ else {
+ newMessagesOnly = YES;
+ copyXPMArea(149,49 , 7 , 11, 52, 48);
+ copyXPMArea(128,27,14,11,18,48);
+ }
+#ifdef _DEBUG
+ haspassed = 1;
+#endif
+ break;
+ case 3: /* delete button */
+ copyXPMArea(143, 15, 14, 11, 4, 48);
+ j = 0;
+ RSET_COLOR;
+ for (iS = 0; iS < nb_conf; iS++) {
+ pc = conf[iS];
+ for (i = 0, k = 0; i < pc->numOfMessages; i++)
+ k += pc->mails[i].todelete;
+ if (k) {
+ /* clear the display */
+ ClearDisplay();
+ k = DeleteMail(pc);
+ if (k < 0) {
+ sprintf(pc->delstatus, "%-3s: Err", pc->alias);
+ }
+ else if (k > 0) {
+ sprintf(pc->delstatus, "%-3s/D:%2d", pc->alias, k);
+ }
+ else
+ sprintf(pc->delstatus, "%-3s: ok", pc->alias);
+ pc->forcedCheck = YES;
+ }
+ else {
+ sprintf(pc->delstatus, "%-3s:none", pc->alias);
+ }
+ }
+ /* clear the display */
+ ClearDisplay();
+ RSET_COLOR;
+ for (iS = 0; iS < nb_conf; iS++) {
+ BlitString(conf[iS]->delstatus, 10, 6*iS + TOP_MARGIN, 0);
+ SWAP_COLOR;
+ }
+ RedrawWindow();
+ sleep(displaydelay);
+ break;
+ case 4: /* top arrow button pressed */
+ index_vert--;
+ if (0 > index_vert)
+ index_vert = 0;
+#ifdef _DEBUG
+ haspassed = 1;
+#endif
+ break;
+ case 5: /* bottom arrow button pressed */
+ if (summess > NB_LINE) {
+ index_vert++;
+ if (index_vert + NB_LINE > summess)
+ index_vert = summess - NB_LINE;
+ }
+#ifdef _DEBUG
+ haspassed = 1;
+#endif
+ break;
+ default:
+ if (newMessagesOnly == NO) { /* message view mode */
+ if ((5 < buttonStatus) && (buttonStatus <= 5 + NB_LINE)) {
+ if ((buttonStatus - 6 + index_vert) < summess) {
+ /* first update lines to del */
+ *(linestodel[buttonStatus - 6]) =
+ 1 - *(linestodel[buttonStatus - 6]);
+#ifdef _DEBUG
+ printf(" button %d pressed, j'update lines to del\n",
+ buttonStatus - 6);
+ haspassed = 1;
+#endif
+ nbsel = 0;
+ for (iS = 0; iS < nb_conf; iS++) {
+ pc = conf[iS];
+ for (i = 0; i < pc->numOfMessages; i++) {
+ nbsel += pc->mails[i].todelete;
+#ifdef _DEBUG
+ printf(" conf %d, mail %d, todelete = %d\n",
+ iS, i, pc->mails[i].todelete);
+#endif
+ }
+ }
+ /* display open or reload buttons */
+ if (nbsel) {
+ copyXPMArea(128,49,14,11,18,48);
+ }
+ else {
+ copyXPMArea(128,27,14,11,18,48);
+ }
+ }
+ }
+ }
+ else { /* summary view mode */
+ if ((5 < buttonStatus) && (buttonStatus <= 5 + nb_conf)) {
+ if ((Event.xbutton.x > 10) &&
+ (Event.xbutton.x < (10 + (4 * (CHAR_WIDTH + 1))))) {
+#ifdef _DEBUG
+ printf(" launching command for conf %d\n",
+ buttonStatus - 6);
+#endif
+ pc = conf[buttonStatus - 6];
+ if (is_for_each_mail(pc->mailclient)) {
+#ifdef _DEBUG
+ if (!pc->numOfMessages) {
+ printf(" command is for each mail but there's no mail\n");
+ }
+#endif
+ for (i = 0; i < pc->numOfMessages; i++)
+ spawn_command(i, pc->mailclient, nbnewmail,
+ "mailcli.", pc);
+ }
+ else {
+ spawn_command(-1, pc->mailclient, nbnewmail,
+ "mailcli.", pc);
+ }
+ }
+ else if ((Event.xbutton.x > (10 + (4 * (CHAR_WIDTH + 1)))) &&
+ (Event.xbutton.x < (10 + (8 * (CHAR_WIDTH + 1))))) {
+ /* swap view mode */
+ conf[buttonStatus - 6]->countunreadonly =
+ 1 - conf[buttonStatus - 6]->countunreadonly;
+#ifdef _DEBUG
+ printf(" swapping view mode for conf %d: %s\n",
+ buttonStatus - 6,
+ (conf[buttonStatus - 6]->countunreadonly) ?
+ "UnreadMessages" : "TotalMessages");
+
+#endif
+ }
+ }
+ else if ((5 + NB_LINE) == buttonStatus) {
+ /* status summary line pressed */
+ if ((Event.xbutton.x > 10) &&
+ (Event.xbutton.x < (10 + (4 * (CHAR_WIDTH + 1))))) {
+ /* select all messages */
+ for (iS = 0; iS < nb_conf; iS++) {
+ for (pc = conf[iS], i = 0; i < pc->numOfMessages; i++) {
+ pc->mails[i].todelete = 1;
+ }
+ }
+ }
+ else if ((Event.xbutton.x > (10 + (4 * (CHAR_WIDTH + 1)))) &&
+ (Event.xbutton.x < (10 + (8 * (CHAR_WIDTH + 1))))) {
+ /* unselect all messages */
+ for (iS = 0; iS < nb_conf; iS++) {
+ for (pc = conf[iS], i = 0; i < pc->numOfMessages; i++) {
+ pc->mails[i].todelete = 0;
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ else {
+ if (buttonStatus >= 0) {
+ /* button has been pressed correctly but released somewhere else */
+ switch(buttonStatus) {
+ case 0: /* check button was pressed */
+ if ((NO == newMessagesOnly) && nbsel)
+ copyXPMArea(128,49 ,14 ,11 ,18 ,48 );
+ else
+ copyXPMArea(128,27 ,14 ,11 ,18 ,48 );
+ break;
+ case 3: /* delete button was pressed */
+ copyXPMArea(143, 15, 14, 11, 4, 48);
+ break;
+ }
+ }
+ }
+ RedrawWindow();
+ buttonStatus = -1;
+ scrollmode = 0;
+ break;
+ }
+ }
+ usleep(sleeplenght);
+ }
+}
+
+
+/*
+ * usage : Prints proper command parameters of wmpop3.
+ */
+void usage(void)
+{
+ fprintf(stdout, "\nWMPop3LB - Louis-Benoit JOURDAIN ([email protected])\n");
+ fprintf(stdout, "based on the work by Scott Holden <[email protected]>\n\n");
+ fprintf(stdout, "usage:\n");
+ fprintf(stdout, " -display <display name>\n");
+ fprintf(stdout, " -geometry +XPOS+YPOS initial window position\n");
+ fprintf(stdout, " -c <filename> use specified config file\n");
+ fprintf(stdout, " -h this help screen\n");
+ fprintf(stdout, " -v print the version number\n");
+ fprintf(stdout, "\n");
+}
+
+void printversion(void)
+{
+ fprintf(stdout, "wmpop3 v%s\n", WMPOP3_VERSION);
+}
+
+// Blits a string at given co-ordinates
+void BlitString(char *name, int x, int y, int fragment)
+{
+ int i;
+ int c;
+ int k;
+ int row;
+
+ /* printf("--name: [%s] \n", name); */
+ for (i = 0, k = x; name[i]; i++) {
+ c = toupper(name[i]);
+ if (c >= 'A' && c <= 'Z') { /* its a letter */
+ c -= 'A';
+ row = LETTERS;
+ }
+ else if (c >= '0' && c <= '9') { /* its a number */
+ c -= '0';
+ row = NUMBERS;
+ }
+ else switch(c) {
+ case '-':
+ c = 26;
+ row = LETTERS;
+ break;
+ case '*':
+ c = 27;
+ row = LETTERS;
+ break;
+ case ':':
+ c = 10;
+ row = NUMBERS;
+ break;
+ case '/':
+ c = 11;
+ row = NUMBERS;
+ break;
+ case '@':
+ c = 12;
+ row = NUMBERS;
+ break;
+ case '%':
+ c = 15;
+ row = NUMBERS;
+ break;
+ case ' ':
+ c = 13;
+ row = NUMBERS;
+ break;
+ case '.':
+ c = 28;
+ row = LETTERS;
+ break;
+ default:
+ c = 14;
+ row = NUMBERS;
+ break;
+ }
+ /* printf("c:%2d (%c), fragment: %d, i:%d, k=%d ",
+ c, name[i], fragment, i, k); */
+ if (i > 0 && i < NB_DISP) {
+ copyXPMArea(c * CHAR_WIDTH, CH_COLOR(row), CHAR_WIDTH + 1, CHAR_HEIGHT,
+ k, y);
+ /* printf(" - k1: %d += %d + 1", k, CHAR_WIDTH); */
+ k += CHAR_WIDTH + 1;
+ }
+ else if (0 == i) {
+ copyXPMArea(c * CHAR_WIDTH + fragment, CH_COLOR(row),
+ CHAR_WIDTH + 1 - fragment, CHAR_HEIGHT,
+ k, y);
+ /* printf(" - k2: %d += %d + 1 - %d", k, CHAR_WIDTH, fragment); */
+ k += CHAR_WIDTH + 1 - fragment;
+ }
+ else if (fragment && (NB_DISP == i)) {
+ copyXPMArea(c * CHAR_WIDTH, CH_COLOR(row), fragment + 1, CHAR_HEIGHT,
+ k, y);
+ /* printf(" - k3: %d += %d ", k, fragment); */
+ k += fragment;
+ }
+ /* printf(" -- apres k=%d\n", k); */
+ }
+}
+
+
+/* Blits number to given coordinates...*/
+
+void BlitNum(int num, int x, int y, int todelete)
+{
+ if (todelete)
+ num += 19;
+ copyXPMArea(((num - 1) * (SN_CHAR_W + 1)) + 1, CH_COLOR(SMALL_NUM),
+ SN_CHAR_W, CHAR_HEIGHT + 1, x, y);
+}
+
+int parsestring(char *buf, char *data, int max, FILE *fp)
+{
+ char *deb;
+ char *end;
+ char *bal;
+ int go = 1;
+ int linelen = 0;
+
+ /* trim the leading spaces */
+ memset(data, 0, max);
+ for (deb = buf; *deb && isspace(*deb); deb++);
+ if (!*deb)
+ return (-1);
+ if ('"' == *deb) {
+ ++deb;
+ bal = data;
+ while (go) {
+#ifdef _DEBUG
+ printf(" line to parse: [%s]\n", deb);
+#endif
+ /* get to the end of the line */
+ for (end = deb; *end && ('"' != *end); end++);
+ if (!*end) { /* this is a multiline entry */
+ linelen += (int) (end - deb);
+ if (linelen > max) {
+#ifdef _DEBUG
+ printf(" maximum line length reached\n");
+#endif
+ return (-1);
+ }
+ memcpy(bal, deb, (int) (end - deb));
+ bal = data + linelen;
+ if (fgets(buf, CONF_BUFLEN, fp)) {
+ deb = buf;
+ }
+ else { /* end of file reached */
+ return (-1);
+ }
+ }
+ else {
+ memcpy(bal, deb, end - deb);
+ go = 0;
+ }
+ }
+ }
+ else {
+ for (end = deb; *end && !isspace(*end); end++);
+ memcpy(data, deb, ((end - deb) > max) ? max : end - deb);
+ }
+#ifdef _DEBUG
+ printf(" parsed string (len=%d) : [%s]\n", strlen(data), data);
+#endif
+ return (0);
+}
+
+int parsenum(char *buf, int *data)
+{
+ char *deb;
+ char *end;
+ char temp[32];
+
+ memset(temp, 0, 32);
+ for (deb = buf; *deb && isspace(*deb); deb++);
+ if (!*deb)
+ return (-1);
+ if ('"' == *deb) {
+ for (end = ++deb; *end && ('"' != *end); end++);
+ if (!*end)
+ return (-1);
+ memcpy(temp, deb, end - deb);
+ *data = atoi(temp);
+ }
+ else {
+ for (end = deb; *end && !isspace(*end); end++);
+ memcpy(temp, deb, end - deb);
+ *data = atoi(temp);
+ }
+ return (0);
+}
+
+char **build_arg_list(char *buf, int len)
+{
+ int espaces;
+ int i, j;
+ char **retour;
+
+ /* count number of args */
+ for (espaces = 0, i = 0; buf[i] && i < len; i++)
+ if (isspace(buf[i]))
+ espaces++;
+ /* allocate space for the structure */
+ if (NULL == (retour = (char **) malloc(sizeof(char *) * espaces + 2)))
+ return (NULL);
+ /* get each arg one by one */
+ for (i = 0, j = 0; j < len && i < 256; i++) {
+ /* get the end of the arg */
+ for (espaces = j; espaces < len && !isspace(buf[espaces]); espaces++);
+ /* allocate space for the arg */
+ if (0 == (retour[i] = malloc(sizeof(char) * (espaces - j) + 1))) {
+ /* free what has been allocated */
+ for (j = 0; j < i; j++)
+ free(retour[j]);
+ return (NULL);
+ }
+ memcpy(retour[i], buf + j, espaces - j);
+ retour[i][espaces - j] = '\0';
+ j = espaces + 1;
+ }
+ retour[i] = 0;
+ return (retour);
+}
+
+
+int readConfigFile( char *filename ){
+ char buf[CONF_BUFLEN];
+ char tmp[CONF_BUFLEN];
+ FILE *fp;
+ char *bal;
+
+ if( (fp = fopen( filename, "r")) == 0 ){
+ sprintf(config_file, "%s/.wmpop3rc", getenv("HOME"));
+ fprintf(stderr, "-Config file does not exit : %s\n",config_file);
+ fprintf(stderr, "+Trying to create new config file.\n");
+ if((fp = fopen(config_file,"w")) == 0){
+ fprintf(stderr, "-Error creating new config file\n");
+ return -1;
+ }
+ fprintf(fp, "#####################################################\n");
+ fprintf(fp, "# wmpop3lb configuration file #\n");
+ fprintf(fp, "# #\n");
+ fprintf(fp, "# for more information about wmpop3lb, please see: #\n");
+ fprintf(fp, "# http://wmpop3lb.jourdain.org #\n");
+ fprintf(fp, "# or send a mail to #\n");
+ fprintf(fp, "# [email protected] #\n");
+ fprintf(fp, "#####################################################\n");
+ fprintf(fp, "autochecking 0 # 1 enables, 0 disables\n");
+ fprintf(fp, "displaydelay 2 # nb of seconds error info is displayed\n");
+ fprintf(fp, "scrollspeed 100 # percentage of original scrool speed\n");
+ fprintf(fp, "tempdir /tmp # directory for tmp files\n");
+ fprintf(fp, "viewallmessages 0 # 0 Shows the from and subject\n");
+ fprintf(fp, "# 1 Shows the number of messages\n");
+ fprintf(fp, "#\n# Replace all values with appropriate data\n#\n");
+ fprintf(fp, "[Server] # server section\n");
+ fprintf(fp, "alias \"3 alphanum. char. long alias\"\n");
+ fprintf(fp, "popserver \" pop3 server name \"\n");
+ fprintf(fp, "port 110 # default port\n");
+ fprintf(fp, "username \" pop3 login name \"\n");
+ fprintf(fp, "password \" pop3 password \"\n");
+ fprintf(fp, "mailcheckdelay 10 # default mail check time in minutes\n");
+ fprintf(fp, "countUnreadOnly 0 # count unread messages only\n");
+ fprintf(fp, "mailclient \"netscape -mail\" # for example...\n");
+ fprintf(fp, "newmailcommand \" specify new mail command \"\n");
+ fprintf(fp, "selectedmesgcommand \"specify command for selected mess\"\n");
+ fprintf(fp, "mailseparator \" separator when concatening messages\"\n");
+ fprintf(fp, "maxdlsize -1 # (no limit)\n");
+ fprintf(fp, "#\n# start new [server] section below (up to a total of 6)\n");
+ fprintf(stderr, "+New config file created : ~/.wmpop3rc\n\n");
+ fprintf(stderr, "+ ~/.wmpop3rc must be configured before running wmpop3.\n");
+ fclose(fp);
+ return -1;
+ }
+
+ nb_conf = 0;
+ tempdir[0] = '\0';
+
+ while ((nb_conf < 7) && fgets(buf, CONF_BUFLEN, fp) != 0) {
+ if (buf[0] != '#') {
+ if (!nb_conf && !strncasecmp( buf, "autochecking", 12) ){
+ if (parsenum(buf + 12, &autoChecking))
+ fprintf(stderr, "syntax error for parameter autochecking\n");
+ }
+ else if (!nb_conf && !strncasecmp( buf, "scrollspeed", 11) ){
+ if (parsenum(buf + 11, &scrollspeed))
+ fprintf(stderr, "syntax error for parameter scrollspeed\n");
+ }
+ else if (!nb_conf && !strncasecmp( buf, "displaydelay", 12) ){
+ if (parsenum(buf + 12, &displaydelay))
+ fprintf(stderr, "syntax error for parameter displaydelay\n");
+ }
+ else if (!nb_conf && !strncasecmp(buf, "tempdir", 7)) {
+ if (parsestring(buf + 7, tempdir, 1024, fp))
+ fprintf(stderr, "syntax error for parameter tempdir\n");
+ }
+ else if (!strncasecmp(buf, "[server]", 8)) {
+ nb_conf++;
+ if (!(conf[nb_conf - 1] = pop3Create(nb_conf))) {
+ fprintf(stderr, "Can't allocate memory for config structure\n");
+ fclose(fp);
+ return (-1);
+ }
+ }
+ else if (nb_conf && !strncasecmp(buf, "username", 8) ) {
+ if (parsestring(buf + 8, conf[nb_conf -1]->username, 256, fp))
+ fprintf(stderr, "section %d: invalid syntax for username\n",
+ nb_conf);
+ }
+ else if (nb_conf && !strncasecmp( buf, "password", 8) ){
+ if (parsestring(buf + 8, conf[nb_conf - 1]->password, 256, fp))
+ fprintf(stderr, "section %d: invalid syntax for password\n",
+ nb_conf);
+ }
+ else if (nb_conf && !strncasecmp(buf, "alias", 5) ) {
+ if (parsestring(buf + 5, conf[nb_conf -1]->alias, 3, fp))
+ fprintf(stderr, "section %d: invalid syntax for alias\n", nb_conf);
+ }
+ else if (nb_conf && !strncasecmp( buf, "popserver", 9) ){
+ if (parsestring(buf + 9, conf[nb_conf - 1]->popserver, 128, fp))
+ fprintf(stderr, "section %d: invalid syntax for popserver\n",
+ nb_conf);
+ }
+ else if (nb_conf && !strncasecmp( buf, "port", 4) ){
+ if (parsenum(buf + 4, &(conf[nb_conf - 1]->serverport)))
+ fprintf(stderr, "section %d: Invalid popserver port number.\n",
+ nb_conf);
+ }
+ else if (!nb_conf && !strncasecmp( buf, "viewallmessages", 15) ){
+ if (parsenum(buf + 15, &newMessagesOnly))
+ fprintf(stderr, "section %d: Invalid number ( viewallmessages )\n",
+ nb_conf);
+ }
+ else if (nb_conf && !strncasecmp(buf, "countunreadonly", 15)) {
+ if (parsenum(buf + 15, &(conf[nb_conf - 1]->countunreadonly)))
+ fprintf(stderr, "section %d: Invalid number ( countunreadonly )\n",
+ nb_conf);
+ }
+ else if (nb_conf && !strncasecmp( buf, "mailcheckdelay", 14) ){
+ if (parsenum(buf + 14, &(conf[nb_conf -1]->mailCheckDelay)))
+ fprintf(stderr, "section %d: Invalid delay time.\n", nb_conf);
+ }
+ else if (nb_conf && !strncasecmp(buf, "mailclient", 10)) {
+ if (parsestring(buf + 10, tmp, 256, fp))
+ fprintf(stderr, "section %d: Invalid syntax for mailclient.\n",
+ nb_conf);
+ else
+ conf[nb_conf - 1]->mailclient = build_arg_list(tmp, strlen(tmp));
+ }
+ else if (nb_conf && !strncasecmp(buf, "newmailcommand", 14)) {
+ if (parsestring(buf + 14, tmp, 256, fp))
+ fprintf(stderr,"section %d: Invalid syntax for newmailcommand.\n",
+ nb_conf);
+ else
+ conf[nb_conf - 1]->newmailcommand =
+ build_arg_list(tmp, strlen(tmp));
+ }
+ else if (nb_conf && !strncasecmp(buf, "selectedmesgcommand", 19)) {
+ if (parsestring(buf + 19, tmp, 256, fp))
+ fprintf(stderr,
+ "section %d: Invalid syntax for selectedmesgcommand.\n",
+ nb_conf);
+ else
+ conf[nb_conf - 1]->selectedmesgcommand =
+ build_arg_list(tmp, strlen(tmp));
+ }
+ else if (nb_conf && !strncasecmp(buf, "mailseparator", 13)) {
+ if (parsestring(buf + 13, conf[nb_conf - 1]->mailseparator, 256, fp))
+ fprintf(stderr, "section %d: Invalid syntax for mailseparator\n",
+ nb_conf);
+ }
+ else if (nb_conf && !strncasecmp( buf, "maxdlsize", 9) ){
+ if (parsenum(buf + 9, &(conf[nb_conf -1]->maxdlsize)))
+ fprintf(stderr, "section %d: Invalid maxdlsize.\n", nb_conf);
+ }
+ else if (nb_conf) {
+ if (*buf && (isalpha(*buf) || isalnum(*buf)))
+ fprintf(stderr, "section %d: Unknown indentifier : [%s]\n",
+ nb_conf, buf);
+ }
+ else {
+ for (bal = buf; *bal && !isalnum(*bal); bal++);
+ if (*bal)
+ fprintf(stderr, "identifier outside Server section: [%s]\n", buf);
+ }
+ }
+ }
+ fclose(fp);
+ return 0;
+}
+
+
+
+
+
+
+
diff --git a/wmpop3lb/wmpop3/wmpop3.xpm b/wmpop3lb/wmpop3/wmpop3.xpm
new file mode 100644
index 0000000..75bea69
--- /dev/null
+++ b/wmpop3lb/wmpop3/wmpop3.xpm
@@ -0,0 +1,152 @@
+/* XPM */
+static char * wmpop3_xpm[] = {
+"160 130 19 1",
+" c None",
+". c #202020",
+"+ c #0000FF",
+"@ c #00EB00",
+"# c #000000",
+"$ c #F7F3FF",
+"% c #727072",
+"& c #C7C3C7",
+"* c #86828E",
+"= c #AEAAAE",
+"- c #B60418",
+"; c #873A45",
+"> c #C44457",
+", c #636363",
+"' c #20B2AE",
+") c #2164A8",
+"! c #E02A8B",
+"~ c #AD206B",
+"{ c #575B5E",
+" .+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+" .+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+" .+++@@++......................................................+#.############++#.############+++",
+" .++@$@@+......................................................+#%%%%%%%%%%%%.++#$$$$$$$$$$$$.+++",
+" ...&*..................................................& .++@@@@+......................................................+#%==========$#++#$==========%#+++",
+" ...&*..................................................& .+++@@++......................................................+#%===.==#===$#++#$===#==.===%#+++",
+" ...&*..................................................& .+++++++......................................................+#%==#.==##==$#++#$==##==.#==%#+++",
+" ...&*..................................................& .+++--++......................................................+#%=##.==###=$#++#$=.##==.##=%#+++",
+" ...&*..................................................& .++-$--+......................................................+#%==#.==##==$#++#$==##==.#==%#+++",
+" ...&*..................................................& .++----+......................................................+#%===.==#===$#++#$===#==.===%#+++",
+" ...&*..................................................& .+++--++......................................................+#%==========$#++#$==========%#+++",
+" ...&*..................................................& .++++&*+......................................................+#$$$$$$$$$$$$#++#%%%%%%%%%%%%#+++",
+" ...&*..................................................& .++;>&*+......................................................+#.############++#.############+++",
+" ...&*..................................................& .++;>&*+......................................................++++++++++++++++++++++++++++++++++",
+" ...&*..................................................& .++;>&*+......................................................++++++++++++++++++++++++++++++++++",
+" ...&*..................................................& .++;>&*+......................................................+##############++##############+++",
+" ...&*..................................................& .++;>&*+......................................................+#%%%%%%%%%%%%#++#$$$$$$$$$$$$#+++",
+" ...&*..................................................& .+++++++......................................................+#%==========$#++#$==========%#+++",
+" ...&*..................................................& .$$$**$+......................................................+#%####=##=#=$#++#$####=##=#=%#+++",
+" ...&*..................................................& .$&**&$+......................................................+#%=#=#=#==#=$#++#$=#=#=#==#=%#+++",
+" ...&*..................................................& .$&**&$+......................................................+#%=#=#=##=#=$#++#$=#=#=##=#=%#+++",
+" ...&*..................................................& .$&**&$+......................................................+#%=#=#=#==#=$#++#$=#=#=#==#=%#+++",
+" ...&*..................................................& .$&**&$+......................................................+#%####=##=##$#++#$####=##=##%#+++",
+" ...&*..................................................& .$&**&$+......................................................+#%==========$#++#$==========%#+++",
+" ...&*..................................................& .$&**&$+......................................................+#$$$$$$$$$$$$#++#%%%%%%%%%%%%#+++",
+" ...&*..................................................& .$&**&$+......................................................+##############++##############+++",
+" ...&*..................................................& .$&**&$+......................................................++++++++++++++++++++++++++++++++++",
+" ...&*..................................................& .$&**&$+......................................................++############################++++",
+" ...&*..................................................& .$&**&$+......................................................++#$$$$$$$$$$$$##$$$$$$$$$$$$#++++",
+" ...&*..................................................& .$&**&$+......................................................++#$==========%##$====..====%#++++",
+" ...&*..................................................& .$&**&$+......................................................++#$==......==%##$==......==%#++++",
+" ...&*..................................................& .$&**&$+......................................................++#$=..====..=%##%%%%%%%%%%%%#++++",
+" ...&*..................................................& .$&**&$+......................................................++#$========.=%##............#++++",
+" ...&*..................................................& .$&**&$+......................................................++#$=....===.=%##$$$$$$$$$$$$#++++",
+" ...&*..................................................& .$&**&$+....................................................##++#$=...===..=%##$==......==%#++++",
+" ...&*..................................................& .$&**&$+......................................................++#$=.=.....==%##$====..====%#++++",
+" ...&*..................................................& .$&**&$+......................................................++#%%%%%%%%%%%%##%%%%%%%%%%%%#++++",
+" ...&*..................................................& .$&**&$+......................................................++############################++++",
+" ...&*..................................................& .$&**&$+......................................................++############################++++",
+" ...&*..................................................& .$&**&$+......................................................++#%%%%%%%%%%%%##$$$$$..$$$$$#++++",
+" ...&*..................................................& .$&**&$+.....................................................#++#%==========$##$###%..$=##%#++++",
+" ...&*..................................................& .$&**&$+.....................................................#++#%==......==$##$#==%..$###%#++++",
+" ...&*..................................................& .$&**&$+.....................................................#++#%=..====..=$##$###%..$=##%#++++",
+" ...&*..................................................& .$&**&$+.....................................................#++#%========.=$##$===%..$===%#++++",
+" ...&*..................................................& .$&**&$+.....................................................#++#%=....===.=$##$#=#%..$##=%#++++",
+" ...&*..................................................& .$&**&$+......................................................++#%=...===..=$##$###%..$###%#++++",
+" & .$&**&$+......................................................++#%=.=.....==$##$#=#%..$##=%#++++",
+" & .$&**&$+......................................................++#$$$$$$$$$$$$##%%%%%..%%%%%#++++",
+" #######################################################& .$&**&$+......................................................++############################++++",
+" #$$$$$$$$$$$$##$$$$$$$$$$$$##$$$$$$$$$$$$#$$$$$..$$$$$#& .$&**&$+......................................................++############################++++",
+" #$==========%##$==========%##$====..====%#$###%..$=##%#& .$&**&$+......................................................++#$$$$$$$$$$$$##%%%%%..%%%%%#++++",
+" #$####=##=#=%##$==......==%##$==......==%#$#==%..$###%#& .$&**&$+......................................................++#$####======%##%###$..%=##$#++++",
+" #$=#=#=#==#=%##$=..====..=%##%%%%%%%%%%%%#$###%..$=##%#& .$&**&$+......................................................++#$#==#####==%##%#==$..%###$#++++",
+" #$=#=#=##=#=%##$========.=%##............#$===%..$===%#& .$&**&$+......................................................++#$#======#==%##%###$..%=##$#++++",
+" #$=#=#=#==#=%##$=....===.=%##$$$$$$$$$$$$#$#=#%..$##=%#& .$&**&$+......................................................++#$#==#######%##%===$..%===$#++++",
+" #$####=##=##%##$=...===..=%##$==......==%#$###%..$###%#& .$&**&$+......................................................++#$#=#,,,,,,#%##%#=#$..%##=$#++++",
+" #$==========%##$=.=.....==%##$====..====%#$#=#%..$##=%#& .$&**&$+......................................................++#$##,,,,,,#=%##%###$..%###$#++++",
+" #%%%%%%%%%%%%##%%%%%%%%%%%%##%%%%%%%%%%%%#%%%%%..%%%%%#& .$&**&$+......................................................++#$########==%##%#=#$..%##=$#++++",
+" #######################################################& .$&**&$+......................................................++#%%%%%%%%%%%%##%$$$$..%$$$$#++++",
+" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& .$**$$$+......................................................++############################++++",
+" .+++++++......................................................++##############++++++++++++++++++",
+" .+++++++......................................................++#%%%%%%%%%%%%#++++++++++++++++++",
+" .+++++++......................................................++#%####======$#++++++++++++++++++",
+" .+++++++ ++#%#==#####==$#++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#%#======#==$#++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++................................................++++++++#%#==#######$#++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++''''''''''''''''''''''''''''''''''''''''''''''''++++++++#%#=#,,,,,,#$#++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'))))))))))))))))))))))))))))))))))))))))))))))'++++++++#%##,,,,,,#=$#++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'))))))))))))))))))))))))))))))))))))))))))))))'++++++++#%########==$#++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++''''''''''''''''''''''''''''''''''''''''''''''''++++++++#$$$$$$$$$$$$#++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++................................................++++++++##############++++++++++++++++++",
+"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++''''''''''''''''''''''''''''''''''''''''''''''+++++++++++++++++++++++++++++++++++++++++",
+"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++''''''''''''''''''''''''''''''''''''''''''''''+++++++++++++++++++++++++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"...............................................................................................................................................................+",
+"..'..'''.'''.'.'.'''.'''.'''.'''.'''.)))..)..))).))).).).))).))).))).))).)))..!..!!!.!!!.!.!.!!!.!!!.!!!.!!!.!!!.~~~..~..~~~.~~~.~.~.~~~.~~~.~~~.~~~.~~~.~~~...+",
+".''....'...'.'.'.'...'.....'.'.'.'.'.).).))....)...).).).)...).....).).).).).!!....!...!.!.!.!...!.....!.!.!.!.!.~.~.~~....~...~.~.~.~...~.....~.~.~.~.~.~.~...+",
+"..'..'''..''.'''.'''.'''...'.'''.'''.).)..)..)))..)).))).))).)))...).))).)))..!..!!!..!!.!!!.!!!.!!!...!.!!!.!!!.~.~..~..~~~..~~.~~~.~~~.~~~...~.~~~.~~~.~~~...+",
+"..'..'.....'...'...'.'.'..'..'.'...'.).)..)..).....)...)...).).)..)..).)...)..!..!.....!...!...!.!.!..!..!.!...!.~.~..~..~.....~...~...~.~.~..~..~.~...~...~...+",
+".'''.'''.'''...'.'''.'''..'..'''.'''.))).))).))).)))...).))).)))..)..))).))).!!!.!!!.!!!...!.!!!.!!!..!..!!!.!!!.~~~.~~~.~~~.~~~...~.~~~.~~~..~..~~~.~~~.~~~...+",
+"...............................................................................................................................................................+",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"...............................................................................................................................................................+",
+"..''..'''...'''.'''..''''.''''..'''.'..'.'''..''''.'..'.'....'..'.'..'..''..''''..''..''''.''''.'''..'..'.'..'.'..'.'..'.'..'.''''......'..'...................+",
+".'..'.'..'.'....'..'.'....'....'....'..'..'.....'..'.'..'....''''.''.'.'..'.'..'.'..'.'..'.'.....'...'..'.'..'.'..'.'..'.'..'....'.......''....................+",
+".''''.'''..'....'..'.'''..'''..'.''.''''..'.....'..''...'....'..'.''''.'..'.''''.''.'.''''.''''..'...'..'.'..'.'..'..''..''''..''..''''.''''...................+",
+".'..'.'..'.'....'..'.'....'....'..'.'..'..'.....'..'.'..'....'..'.'.''.'..'.'....'.''.'.'.....'..'...'..'..''..''''.'..'....'.'..........''....................+",
+".'..'.''''..'''.'''..''''.'.....''..'..'.'''..''...'..'.''''.'..'.'..'..''..'.....'''.'..'.''''..'...''''..''..'..'.'..'.''''.''''......'..'...'...............+",
+"...............................................................................................................................................................+",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"...............................................................................................................................................................+",
+".''''..''..''''.''''.'..'.''''.''''.''''.''''.''''.###.....'..''............'..'...............................................................................+",
+".'..'.'.'.....'....'.'..'.'....'.......'.'..'.'..'.#''....''.''.'.............''...............................................................................+",
+".'..'...'..''''..'''.''''.''''.''''...'..''''.''''..##...''..'.''.......'....''................................................................................+",
+".'..'...'..'.......'....'....'.'..'..'...'..'....'.#''..''...'..............''.................................................................................+",
+".''''.''''.''''.''''....'.''''.''''..'...''''.''''.##...'.....'''...........'..'...............................................................................+",
+"...............................................................................................................................................................+",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ",
+"{{'{{'''{'''{'{'{'''{'''{'''{'''{'''{))){{){{))){))){){){))){))){))){))){))){{!{{!!!{!!!{!{!{!!!{!!!{!!!{!!!{!!!{~~~{{~{{~~~{~~~{~{~{~~~{~~~{~~~{~~~{~~~{~~~{{{ ",
+"{''{{{{'{{{'{'{'{'{{{'{{{{{'{'{'{'{'{){){)){{{{){{{){){){){{{){{{{{){){){){){!!{{{{!{{{!{!{!{!{{{!{{{{{!{!{!{!{!{~{~{~~{{{{~{{{~{~{~{~{{{~{{{{{~{~{~{~{~{~{~{{{ ",
+"{{'{{'''{{''{'''{'''{'''{{{'{'''{'''{){){{){{))){{)){))){))){))){{{){))){))){{!{{!!!{{!!{!!!{!!!{!!!{{{!{!!!{!!!{~{~{{~{{~~~{{~~{~~~{~~~{~~~{{{~{~~~{~~~{~~~{{{ ",
+"{{'{{'{{{{{'{{{'{{{'{'{'{{'{{'{'{{{'{){){{){{){{{{{){{{){{{){){){{){{){){{{){{!{{!{{{{{!{{{!{{{!{!{!{{!{{!{!{{{!{~{~{{~{{~{{{{{~{{{~{{{~{~{~{{~{{~{~{{{~{{{~{{{ ",
+"{'''{'''{'''{{{'{'''{'''{{'{{'''{'''{))){))){))){))){{{){))){))){{){{))){))){!!!{!!!{!!!{{{!{!!!{!!!{{!{{!!!{!!!{~~~{~~~{~~~{~~~{{{~{~~~{~~~{{~{{~~~{~~~{~~~{{{ ",
+"{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ",
+"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ",
+"{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ",
+"{{''{{'''{{{'''{'''{{''''{''''{{'''{'{{'{'''{{''''{'{{'{'{{{{'{{'{'{{'{{''{{''''{{''{{''''{''''{'''{{'{{'{'{{'{'{{'{'{{'{'{{'{''''{{{{{{'{{'{{{{{{{{{{{{{{{{{{{ ",
+"{'{{'{'{{'{'{{{{'{{'{'{{{{'{{{{'{{{{'{{'{{'{{{{{'{{'{'{{'{{{{''''{''{'{'{{'{'{{'{'{{'{'{{'{'{{{{{'{{{'{{'{'{{'{'{{'{'{{'{'{{'{{{{'{{{{{{{''{{{{{{{{{{{{{{{{{{{{ ",
+"{''''{'''{{'{{{{'{{'{'''{{'''{{'{''{''''{{'{{{{{'{{''{{{'{{{{'{{'{''''{'{{'{''''{''{'{''''{''''{{'{{{'{{'{'{{'{'{{'{{''{{''''{{''{{''''{''''{{{{{{{{{{{{{{{{{{{ ",
+"{'{{'{'{{'{'{{{{'{{'{'{{{{'{{{{'{{'{'{{'{{'{{{{{'{{'{'{{'{{{{'{{'{'{''{'{{'{'{{{{'{''{'{'{{{{{'{{'{{{'{{'{{''{{''''{'{{'{{{{'{'{{{{{{{{{{''{{{{{{{{{{{{{{{{{{{{ ",
+"{'{{'{''''{{'''{'''{{''''{'{{{{{''{{'{{'{'''{{''{{{'{{'{''''{'{{'{'{{'{{''{{'{{{{{'''{'{{'{''''{{'{{{''''{{''{{'{{'{'{{'{''''{''''{{{{{{'{{'{{{'{{{{{{{{{{{{{{{ ",
+"{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ",
+"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ",
+"{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ",
+"{''''{{''{{''''{''''{'{{'{''''{''''{''''{''''{''''{{{{{{{{{'{{''{{{{{{{{{{{{'{{'{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ",
+"{'{{'{'{'{{{{{'{{{{'{'{{'{'{{{{'{{{{{{{'{'{{'{'{{'{{''{{{{''{''{'{{{{{{{{{{{{{''{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ",
+"{'{{'{{{'{{''''{{'''{''''{''''{''''{{{'{{''''{''''{{{{{{{''{{'{''{{{{{{{'{{{{''{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ",
+"{'{{'{{{'{{'{{{{{{{'{{{{'{{{{'{'{{'{{'{{{'{{'{{{{'{{''{{''{{{'{{{{{{{{{{{{{{''{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ",
+"{''''{''''{''''{''''{{{{'{''''{''''{{'{{{''''{''''{{{{{{'{{{{{'''{{{{{{{{{{{'{{'{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ",
+"{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ",
+"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
--
2.7.4
--
To unsubscribe, send mail to [email protected].