This is patch Elm 2.4 PL25 -> Elm 2.4ME+ PL50 (25)
Warning: Elm 2.4ME+ is UNOFFICIAL!

                                        - K E H <hurtta+elm@ozone.FMI.FI>
-------------------------------------------------------------------------------
Index: elm2.4.ME+.50/hdrs/patchlevel.h
*** elm2.4.25/hdrs/patchlevel.h	Mon Dec  4 17:50:56 1995
--- elm2.4.ME+.50/hdrs/patchlevel.h	Tue Nov 17 21:14:08 1998
***************
*** 1 ****
! #define PATCHLEVEL "25"
--- 1,6 ----
! #define PATCHLEVEL        "50 (25)"
! #define LAST_REPORT_TIME  942862610
! #define BUG_REPORT_ADDR   "Kari Hurtta <hurtta+elm@ozone.FMI.FI>"
! #define VERS_DATE	  "Nov, 1998"	/* for elm -v option */
! #define WHAT_STRING	\
! 	"@(#) Version 2.4(ME+), USENET supported version, released Nov, 1998"
Index: elm2.4.ME+.50/README.ME+
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/README.ME+	Tue Nov 17 21:14:08 1998
***************
*** 0 ****
--- 1,1962 ----
+ $Header: /data/cvsroot/mail/elmme+/README.ME+,v 1.11 1998/11/17 18:20:24 hurtta Exp $
+ 
+ Version Elm2.4ME+ PL0 (25) is based to version Elm2.4 PL24 ME8b+.
+ Version Elm2.4 PL24 ME8b+ is based to version Elm2.4 PL24 ME8b.
+ 
+ Version Elm2.4 PL24 ME8b is done by Michael Elkins <elkins.aero.org>.
+ For details, look file ANNOUNCE.ME
+ 
+ [ Michael Elkins posted equivalent of MIME code in Elm2.4 PL24 ME8b 
+   to Elm Development Cordinator. Later changes are not posted to
+   Elm Development Cordinator. ]
+    
+ Version Elm2.4 PL24 ME8b is based to version Elm2.4 PL24.
+ Version Elm2.4ME+ PLx (25) includes patch of version Elm2.4 PL25.
+ 
+ Changes of Elm2.4ME+ PL50 (25) compared to Elm2.4ME+ PL49 (25)
+ --------------------------------------------------------------
+ 
+ 	- elm -vvvv now print names of some configuration files
+ 	- elm -vvvvv prints some configuration data (mainly
+           locale dependent data)
+ 
+         - "When I use the keys '+' or '-' in an empty attachment 
+            list elm exits with a segmentation violation. This seems 
+            to occur because the variable 'ptrs' points to NULL (and 
+            'ptr_max' is equal to 0) which is not checked.
+ 
+           The following patch fixes this bug."
+          From: Henrik Pletat <pletat@informatik.hu-berlin.de>
+ 
+ 	- Added locale_init() to lib/read_rc.c and moved to
+ 	 catopen and setlocale to it.
+ 
+ 	- Added mapping from LC_CTYPE locale to display_charset.
+          Mapping is done on file $lib/elm.mimecharsets or on 
+          .elm/mime.charsets
+ 
+        - Special value DISPLAY on elmrc variable charset
+          means that use display_charset.
+ 
+ 	- Moved variable substitution from Configure to
+           ConfTool/Substitute (called automatically)
+ 
+         - Ctrl-U and Ctrl-D on builtin++ pager was working
+           inconsistently.
+          Problem reported by: Andrew J. Piziali <andy@piziali.dv.org>
+ 
+ Changes of Elm2.4ME+ PL49 (25) compared to Elm2.4ME+ PL48 (25)
+ --------------------------------------------------------------
+ 
+         - Put ME+ to under of CVS. Because revision numbers 
+           changed there was need of changing header text of files.
+ 
+         - "It fixes a small problem with the date representation 
+            in the upper right corner.  Currently, times like
+            "09:08:02" are displayed as " 9: 8: 2".  This is because 
+            src/date.c uses the format "%2.2d:%2.2d:%2.2d" which is 
+            not supported by elm_vmessage() (gets interpreted as 
+            "%2d:%2d:%2d").  The patch changes this to "%02d:%02d:%02d" 
+            (this is used everywhere else anyway), which fixes the
+           problem."
+          From: Gertjan van Oosten <gertjan@West.NL>
+ 
+         - If To: is empty and I have sender, show sender of mail
+           (DisplayAddrress (lib/dispaddr.c) was not correctly 
+            detectection empty To: -header.)
+          
+ Changes of Elm2.4ME+ PL48 (25) compared to Elm2.4ME+ PL47 (25)
+ --------------------------------------------------------------
+ 
+         - Changed to and cc field on header_rec to include 
+           result of break_down_address 
+         - Added to_matches and cc_matches to pattern.c
+ 
+         - moved and reimplemented forwarded from utils/newmail.c 
+           and src/addr_util.c to lib/forwarded.c 
+         
+         - shift_lower needs const for argument
+ 
+         - Add buffer overflow check to stip_parens() and get_parens()
+           (lib/striparens.c)
+         
+         - Moved main part of parse_arpa_date() to new routine
+           parse_date_time (lib_/parsarpdat.c) and let parse_arpa_date()
+           to call that routine.
+ 
+         - Reimplemented process_expiration_date() (src/expires.c).
+           Original code did not handled 4 number years and was broken
+           on year 2000. New code uses just parse_date_time() --
+           However it accepts expiration times where date part
+           is only given from RFC 822 date-time format.
+ 
+         - Now real_from() (lib/realfrom.c) assumes local timezone,
+           if timezone is not given, because From mailbox separator
+           is normally inserted locally.
+         
+         - There was "multi-character character constant" -warning 
+           coming from src/mkhdrs.c
+           Reported by: Witold Witkowski <yawitkow@cyf-kr.edu.pl>
+ 
+         - "If you switch to the option editor screen, change 
+            "O)utbound mail saved" from "=sent" to "=sent" (i.e. 
+            enter the displayed character sequence), return to the 
+            index, and then mail a message, the outgoing message 
+            will be saved in a file named ~/=sent rather than in
+            ~/Mail/sent.  The equal sign is not getting expanded 
+            to the user's mail folder directory."
+           Reported by: Andrew J. Piziali <andy@elijah.dv.org>
+ 
+         - "I suggest checking and accepting (extending) existing PATH"
+           From: Witold Witkowski <yawitkow@cyf-kr.edu.pl>
+         > Moved $PATH to beginning of initial PATH of Configure
+ 
+ Changes of Elm2.4ME+ PL47 (25) compared to Elm2.4ME+ PL46 (25)
+ --------------------------------------------------------------
+ 
+         - Do not treate characters > 127 as controls (allow
+           they on words of phrases)
+ 
+         - Fix name of "Forwarded message from" -text
+ 
+ Changes of Elm2.4ME+ PL46 (25) compared to Elm2.4ME+ PL45 (25)
+ --------------------------------------------------------------
+ 
+         - Split break_down_address to look_special_tokens(),
+           scanned_to_phrase(), scanned_to_str() routines
+           and reimplement break_down_address as state machine
+           (4 states, 6 terminals).
+         > Now phrase from group -syntax is ignored and
+           route from address is dropped.
+ 
+         - strtok(), strpbrk(), strstr() was declared in both 
+           of elmlib.h and defs.h (remove later declaration).
+          Noted by: John Goerzen <jgoerzen@complete.org>,
+                    Emmanuel Bigler <bigler@alpha.univ-fcomte.fr>
+ 
+         - Changed from field on header_rec to include 
+           result of break_down_address (instead of just fullname).
+         - "From " address is stored to new env_from field
+         > Sorting based on sender uses first "From " address
+           and then parsed From: -header (fullname and then address)
+         > Limit with 'from' now works both of full name and address
+           and it uses now MIME-decoded full name. Also "From "
+           address is considered.
+         - get_return (on returnaddr.c) is simplified. Now it uses
+           stored (and parsed) From: -header from from field of header_rec
+ 
+         - Assume INTERNET (style addresses). Remove question from
+           Configure and all ifdefs.
+ 
+         - Assume USE_EMBEDDED_ADDRESS (From: and Reply-Top:). Remove
+           question from Configure and all ifdefs.
+ 
+         - Call user_init(), init_defaults() and read_rc_file() on 
+           newmail.
+ 
+ Changes of Elm2.4ME+ PL45 (25) compared to Elm2.4ME+ PL44 (25)
+ --------------------------------------------------------------
+ 
+         - skip_envelope on melib/parse_util.c was not skipping
+           ">From " -lines.
+ 
+         - Save composition filename to global variable
+           (so it does not need to be genrated in signal handler
+            for removal)
+ 
+ Changes of Elm2.4ME+ PL44 (25) compared to Elm2.4ME+ PL43 (25)
+ --------------------------------------------------------------
+ 
+         - Added lib/getaddr.c (break_down_address, 
+           free_addr_list)
+         - Moved rfc822_tokenize, remove_space_tokenized,
+           free_rfc822tokenized from melib/parse_util.c
+           to lib/getaddr.c
+         - Reimplemented parse_arpa_who (lib/parsarpwho.c)
+           and get_address_from (lib/getaddrfrm.c) with
+           break_down_address
+         - Added size argument to (get_address_from)
+ 
+         - replace break_down_to_list (src/reply.c) with 
+           break_down_address
+ 
+         - "patch-hmo-1 extends the '#' debug menu, showing 
+            all defined message flags, in the order present 
+            in hdrs/defs.h."
+           From: Helge Oldach <hmo@sep.hamburg.com>
+ 
+ Changes of Elm2.4ME+ PL43 (25) compared to Elm2.4ME+ PL42 (25)
+ --------------------------------------------------------------
+ 
+         - print attachment instead of just printing [skipping...]
+           message when printing from atttachment -menu
+ 
+         - Changes calling sequence of Write_to_screen
+         - Added some messages to message catalog
+         - Added PutLineX to curses.c
+         - Dropped Putline1, PutLine2, PutLine3 to favor
+           PutLineX
+ 
+         - Remove hostname initialization from fastmail,
+           fastmail now calls read_rc -routines
+ 
+ Changes of Elm2.4ME+ PL42 (25) compared to Elm2.4ME+ PL41 (25)
+ --------------------------------------------------------------
+ 
+         - Tweak little (add missing space) to build_header_line
+ 
+         - "When I'm in the attach menu before sending a mail and 
+            I use the delete function on the LAST attachment, the 
+            cursor diappears. Trying then to move up the cursor 
+            elm exits with a sigmentation violation.
+ 
+            This error appears in several versions of elm."
+           From: Henrik Pletat <pletat@informatik.hu-berlin.de>
+ 
+         - Fix call of parse_arpa_who in figure_out_addressee, which
+           caused that To -address in 'frm' was truncated.
+ 
+         - Change days_ahead to return year in 4 numbers and simplify it.
+         - Some year 2000 fixes for src/date.c
+         - Make elm_date_str to return year in 4 numbers
+ 
+         [ Undo Elm2.4ME+ PL41h patch before installing this patch. ]
+ 
+ Changes of Elm2.4ME+ PL41h (25) compared to Elm2.4ME+ PL41 (25)
+ --------------------------------------------------------------
+ 
+         - Tweak little (add missing space) to build_header_line
+ 
+ Changes of Elm2.4ME+ PL41 (25) compared to Elm2.4ME+ PL40 (25)
+ --------------------------------------------------------------
+ 
+         [ Warning: This is so much changes (and some are 
+           incomplete) so this this quite sure more buggy than
+           PL40. ]
+ 
+         - "it's not "a X-Windows" but rather "an X-Windows"; and 
+            BTW, it's not "X-Windows" at all cause that term simply 
+            does not exist (cf. man X).  Simply replay "an X-Windows" 
+            by "an X11". Thanks."
+           From: (sender's name lost)
+ 
+         ( I managed to delete hurtta+elm Mailbox, so resend
+           your mails if they are sent between 1998-03-04 and
+           1998-04-04. )
+ 
+         - Added some messages to message catalog
+ 
+         - iprintf.c dropped (so far) -- it is not used (at least yet)
+ 
+         - elm_sfprintf, elm_message
+         > Global change: Most of sprintf calls replaced with elm_sfrpintf
+ 
+         - Do not longer test existence of mkdir()
+ 
+         - "this is another very simple fix that repairs this:
+            posixsig.c:89: warning: preprocessing directive not 
+               recognized within macro arg"
+           From: Helge Oldach <hmo@sep.hamburg.com>
+ 
+         - Dropped error1, error2, error3 to favor lib_error
+ 
+         - Changed how menu2.c works (and therefore changed
+           DSN and remailer menus.)
+ 
+         - Tweak parsearpawho 
+         > Now From: is not assument to be part of buffer
+         > from in header struct is now mime decoded
+         > That is now mime encoded when generating comment to
+           reply address.
+ 
+         - Handles now phrases on From: -header which uses
+           continuation lines
+ 
+         - Dropped get_real_name -- it is it is at least
+           equal broken than parse_arpa_who
+ 
+         - ' added to set of characters which need quotation because 
+           sendmail otherwise will quote words which includes ' on 
+           phrases -- even that ' is not special character -- and that 
+           way destroy MIME encoding.
+       
+         - MIME decoding is now done when showing values in header menu
+           (for address headers)
+ 
+         - MIME encoding also full name got from gecos field of passwd
+ 
+         - MIME encode also name entered to comments in header edit screen
+           (for address headers)
+ 
+ Changes of Elm2.4ME+ PL40 (25) compared to Elm2.4ME+ PL39 (25)
+ --------------------------------------------------------------
+ 
+         - Enumerated options 
+           userlevel:            beginner        intermediate    expert
+           noencoding:           pass-7bit       pass-8bit       pass-binary
+ 
+         - Move reading of elmrc to elmlib and put elm tools to read
+           elmrc. This may make to some time in future to possible
+           to do binary distributions of elm.
+         > pmalloc.c moved from src/ to lib/
+ 
+         - Added option elm -vvv
+ 
+         - Add routine lib_error (lib/output.c)
+ 
+         - Added some messages to message catalog
+ 
+         - "I have a nice patch to elm-me+-2.4pl25ME+39:
+            If you press (l)imit and then type "thread", all messages 
+            with the same subject are shown. A leading "Re: " is stripped.
+ 
+            That is usefull for (large) mailing lists, where you don't read 
+            all messages. (It's like the thread command in most net news 
+            readers)"
+           From: Christian Hammers <ch@lathspell.westend.com>
+ 
+         - "I have determined what the problem is.  When you `bounce' a 
+            message elm fails to strip the `From ' line from the top of 
+            the message.  This causes Smail to think that the message is 
+            an incoming UUCP transmission.  Smail uses the `From ' line 
+            to build the new return path using a !, getting a wrong answer.
+ 
+            Elm should strip the `From ' from bounced messages."
+           From: Ian Jackson <ian@chiark.greenend.org.uk>
+         > Added CM_REMOVE_ENVELOPE flag to call of copy_message
+           in remail.c in case of INTERNET is defined 
+           (From comments it looks that passing of "From " is done
+            by purpose: "For those cases when you want to have a 
+            message continue along to another person in such a way 
+            as they end up receiving it with the return address the 
+            person YOU received the mail from")
+ 
+         - Elm -v now prints warning "Elm is not intended to be 
+           distributed in binary form.  If that is done, then it 
+           is very likely that compile time configuration does not
+           match to your system."
+ 
+ Changes of Elm2.4ME+ PL39 (25) compared to Elm2.4ME+ PL38 (25)
+ --------------------------------------------------------------
+ 
+         - "The filter included in elm-2.4ME+37 also appears to
+            be vulnerable to the "save_embedded_address()" attack,
+            but not to the "get_filter_rules()" attack."
+           From: KSR[T] <ksrt@DEC.NET>
+         > I didn't used supplied patch. Instead I added bound
+           check to one loop in save_embedded_address (I was
+           added it to one loop but was missed other loop. )
+         > Note that Makefile will not compile ot install filter
+           -- that is intentionally (it was dropped because of
+           security problems)
+ 
+         - "here is another small fix relative to elm-2.4ME+37. 
+            This is relevant for empty folders with keepempty=OFF. 
+            Previously an empty folder was deleted *only* when this 
+            folder was left with all (and >= 1) messages marked 
+            'deleted'. Now an already empty folder is also deleted 
+            upon quit or change to another folder."
+           From: Helge Oldach <hmo@sep.hamburg.com>
+         > I didn't used supplied patch. Instead I modified leave_mbox.
+ 
+         - Added elmrc -option "dsn-success"
+ 
+         - "it looks like that the help function in change folders 
+            of this used version (2.4me+38) doesn't work."
+           Reported by: Roeland Th. Jansen <bengel@grobbebol.xs4all.nl>
+         > init_helpmsg was called with wrong number of parameters.
+ 
+ Changes of Elm2.4ME+ PL38 (25) compared to Elm2.4ME+ PL37 (25)
+ --------------------------------------------------------------
+ 
+         - getarpdate generated date wrongly in year 2000
+ 
+         - "Here's another small fix which allows elm to deal more 
+            reasonably with empty last name/first name/comment fields 
+            in the alias file. This is intended for situations where 
+            people use mail addresses which already include the full 
+            name (like: Helge.Oldach@sep.hamburg.com), so that 
+            duplicating the last name and first name on the alias list 
+            seems not reasonable. If one just leaves the last name/first 
+            name/comment fields empty like in:
+ 
+                 hmo =  = Helge.Oldach@sep.hamburg.com
+ 
+            then the alias screen will display nothing but the alias, 
+            which doesn't tell anything. This patch makes elm display 
+            the actual mail address instead of an empty last name/first 
+            name/comment field.
+ 
+            It also fixes the display of such empty fields when displaying
+            the actual address while sending a mail ("Message addressed as:
+            Helge.Oldach@sep.hamburg.com ()") - the empty brackets won't 
+            appear in this case."
+           From: Helge Oldach <hmo@sep.hamburg.com>
+ 
+         - "background_wait_time should be background-wait-time in 
+            doc/elmrc-info, otherwise the elmrc update function (elm -w) 
+            won't copy the comment."
+           From: Helge Oldach <hmo@sep.hamburg.com>
+ 
+         - "It wasn't properly truncating the subject line if 
+            the rest of the header was longer than 44 characters"
+           From: Guy Harris <guy@netapp.com>
+ 
+         - If msgcat.c will be compiled, don't include <nl_types.h>
+           In that situation always include "elm_nl_types.h"
+ 
+         - rfc822_tokenize, remove_space_tokenized, free_rfc822tokenized,
+           strmcat
+ 
+ Changes of Elm2.4ME+ PL37 (25) compared to Elm2.4ME+ PL36 (25)
+ --------------------------------------------------------------
+ 
+         - include <sys.wait.h> in defs.h
+ 
+         - include <sys/wait.h> in lib/posixsig.c on Ultrix V4.4
+           From: Bernhard Simon <bs@bsws.edvz.tuwien.ac.at>
+ 
+         - "The latest elm.me has a nl_types.h include which on 
+            Digital UNIX is conflicting with a system include having 
+            the same name, which is of course needed for proper 
+            compilation :(."
+           From: Christophe Wolfhugel <wolf@pasteur.fr>
+         > Rename nl_types.h to elm_nl_types.h
+         > There was wrong number of argument in catgets
+           call in iprintf.c [ not currently used ]
+           From: Christophe Wolfhugel <wolf@pasteur.fr>
+ 
+         - Changes for configure to run in Dec Unix (OSF1)
+           "-  cc -std (to have prototypes)
+            -  nm_opts='' for DEC Unix or it gives wrong output with -p 
+               and Configure won't see some functions (like strspn)
+            -  signal hardcoded, because cc -E or cpp or DEC Unix does not 
+               pass the   standard defines (the ones put by cc -std) and we 
+               will miss the signal prototype anyway :(."
+           From: Christophe Wolfhugel <wolf@pasteur.fr>
+ 
+         - Some changes that Elm compiles cleanly on Digital Unix (OSF1)
+           [ It was not defining __STDC__, but was complaining
+             if char * argument was given to unsigned char * argument
+             of function (and opposite) ]
+ 
+         - Digital Unix (OSF1) was defineing macto BSD (sig!)
+           Renamed BSD macro to BSD_TYPE
+ 
+ Changes of Elm2.4ME+ PL36 (25) compared to Elm2.4ME+ PL35 (25)
+ --------------------------------------------------------------
+ 
+         - "If the mail transport agent (MTA) is missing, elm
+            silently fails.  No message is delivered and no warning or 
+            error message is displayed."
+           From: Jan Prikryl <prikryl@cg.tuwien.ac.at>, 
+                 Andrew J. Piziali <andy@elijah.dv.org>
+         > Return status of process was decoded incorrectly.
+         > Also errno status was written to wrong end of report -pipe.
+ 
+         - Redraw screen also if old position was on screen
+           when new mail arrives.
+ 
+         - Dropped return_value_of from curses.c
+ 
+         - Support arrow cursor on attachment menu
+ 
+         - "I recently tried to run the Configure script on AIXv4.2.1 which 
+            failed trying to extract the function names out of libc.a. 
+            I updated the script so it will work on AIX."
+          From: Will Fiveash <will@austin.ibm.com>
+ 
+         - "Also, I am including my file locking patch so that
+            elm will lock a folder when trying to save or copy to it."
+           From: Will Fiveash <will@austin.ibm.com>
+         > Added elmrc option lock-in-copy, that locking is done if
+           this option is TRUE (default).
+         * NOTICE: This does not work with dot-locking
+         * NOTICE: This is usefull only with folders which elm
+                   treats as mailboxes, because folder are not
+                   locked (when visited). 
+ 
+         - Changed can_open to use my_wait and prepared for EINTR
+ 
+         - Dropped move_old_files_to_new()
+ 
+ Changes of Elm2.4ME+ PL35 (25) compared to Elm2.4ME+ PL34 (25)
+ --------------------------------------------------------------
+ 
+         - "I've built elm-2.4.ME+3[34] under SunOS 4.1.2 using 
+            libc 1.1.7 and gcc-2.7.2 and can't actually open a mail 
+            file with them. "
+           From: Dave Rynne <dave@funcom.ie>
+         - wait in can_access was not prepared for EINTR
+         - can_access was not using my_wait
+           [ And why can_access just not use access system call?
+             -- it used real uid and gid anyway!!!! ]
+ 
+         - "The run_state structure declared in me.h has a member 
+            called "errno". However, it is unsafe to use errno as an 
+            identifier under some Unices, e.g. when errno is a macro.  
+            Here is a patch against PL34 which renames the struct member."
+          From: Jesse Thilo <jthilo@early.com>
+          [ It turns out that culprit is Linux libc 6 ]
+ 
+         - Add support for multipart/alternative. Elmrc
+           variable pagealternative is added. If that is TRUE (default),
+           and at least one subpart of multipart/alternative is displayable
+           metamail is not called. If that is FALSE, metamail is not called
+           if all subparts of multipart/alternative are displayable.
+ 
+ Changes of Elm2.4ME+ PL34 (25) compared to Elm2.4ME+ PL33 (25)
+ ---------------------------------------------------------------
+ 
+         - Print "Elm: Unsupported locale (check $LANG)" if setlocale
+           fails. 
+           Suggested by: Michael Rudolf <mich@mich.isdn.cs.tu-berlin.de>
+ 
+         - "I've found a bug in the Configure script for elm2.4.ME+.33:
+            when Configure asks for the metamail path and the path doesn't
+            exist elm asks you: "File ... doesn't exist.  Use that name 
+            anyway?", if you answer 'y' then metamail_path is set 
+            to 'y'. I think that's not the desired action... :)"
+          From: Jose A. Rodriguez <Jose.Rodriguez@ac.upc.es>
+ 
+         - Add elmrc -varaible pgp. This gives path to PGP.
+           If "none", pgp is not called. Also checked that 
+           pgp is executable with given path.
+           Suggested by: John Goerzen <jgoerzen@complete.org>
+ 
+         - check with can_open that debug file can be opened.
+ 
+         - -A (attach) option didn't used "~/.elm/mime.types" file.
+           Reported by: Andrew J. Piziali <andy@piziali.dv.org>
+          
+ Changes of Elm2.4ME+ PL33 (25) compared to Elm2.4ME+ PL32 (25)
+ --------------------------------------------------------------
+ 
+         - Content-Disposition: inline; filename = "filename"
+           was not parsed correctly.
+           Reported by: Jussi Kaurola <kaurola@ozone.FMI.FI>
+ 
+         - Remove NIS tests from Configure. $passcat was not used
+         ( Next section "set up shell script to do ~ expansion"
+           may perhaps need it, but actually it does not use it. )
+           Hint from: Jerzy Sobczyk <J.Sobczyk@ia.pw.edu.pl>
+         > Now sun is always added to from of $libswanted
+ 
+         - Added elmrc option background-wait-time (default 2 seconds)
+           If = 0  wait mailer to completion
+              > 0  wait background-wait-time seconds for completion
+                   if not completed in this time, let it go to background
+ 
+                 (completion of mailing is still reported if user have
+                  not exited from elm in that time when mailer have completed)
+           Suggested by: Heiko W.Rupp <hwr@pilhuhn.de>
+                         Daniel C. Sobral <dcs@gns.com.br>
+         * THIS option is supported only in POSIX systems
+         > Added my_wait to lib/posigsig.c
+ 
+         - Added VOLATILE to defs.h
+         > to resize_screen, redraw_screen (elm.h, headers.h)
+ 
+         - "When I tried to compile elm2.4.ME+.32 for Digital Unix 4.0 I got
+            a few compiler errors. The problem is that ANSIC/not ANSIC headers
+            are not in sync...
+ 
+            They are fixed with this patch (for lib/iprintf.c file)"
+           From: Jose A. Rodriguez <Jose.Rodriguez@ac.upc.es>
+         * Actually this (ELMCHAR, iprintf) code isn't yet in use
+ 
+         - "The bug was that filter truncated the "Saved folder" to 
+            only 3 chars (out of the full path). To fix it, just change 
+            the following line in 'utils.c' in the filter directory"
+           From: From: Yuval Shamir <yuvals@iil.intel.com>
+           [ Suggested fix was incorrect. ]
+ 
+         > Notice: filter code is not tested (and compilation
+           of it is commented out from Makefile in all ME+)
+ 
+ Changes of Elm2.4ME+ PL32 (25) compared to Elm2.4ME+ PL31 (25)
+ ---------------------------------------------------------------
+ 
+         - Incorrect Content-length: -header was causing corruption
+           of folders.
+           From: Guy Harris <guy@netapp.com>
+ 
+         - argv_from_to was not handled ',' in comments correctly.
+           Detected from report of Gary Casterline 
+                 <casterln@nature.Berkeley.EDU>
+         > Use rfc822_toklen instead of len_next_part
+ 
+         - SECURITY: strcpy -> strfcpy changes of Elm2.4ME+ PL29 (25)
+           was not done for curses.c in this source tree.
+           Bug report on List <BUGTRAQ@NETSPACE.ORG>.
+           From: John Goerzen <jgoerzen@happy.cs.twsu.edu>
+ 
+         - Some changes on curses.c (bl -- bell)
+ 
+         - Change output of option -v
+ 
+         - "If you use 'answer -u', then every user name is truncated to 
+            three letters." ... "Change line 232 to: " ...
+           From: Jean-Pierre Radley <jpr@jpr.com>
+           [ Suggested fix was incorrect. ]
+ 
+         - "Configure always has had a problem on Linux systems, 
+            extracting names in a usuable format (from /usr/lib/libc.so).
+            The following small change fixes this."
+           From: Bauke Jan Douma <bjdouma@xs4all.nl>
+ 
+         - "In Solaris enviroment NIS+ is now used instead of Yellow 
+            Pages so I have modified Configure to reflect this and 
+            allow to use niscat in the same fashion as ypcat was."
+           From: Jerzy Sobczyk <J.Sobczyk@ia.pw.edu.pl>
+           [ Undone in PL33 ]
+ 
+         - Compilation of filter (actions.c) fail.
+           Reported by: Arnout Boer <arnoutb@xs4all.nl>
+ 
+         - Typo mismatch in lib/strftime.c
+           From: Yuval Shamir <yuvals@iil.intel.com>
+         - [wordwrap.c, bultin editor] 
+           "Wordwrap and delete at the 
+            beginning of the line does not work in PL31. Fix is below."
+           From: "Zoltan T. Hidvegi" <hzoli@VNET.IBM.COM> 
+           [ I didn't used supplied patch. ]
+ 
+         - [builtin editor] There was 'sizeof buffer' instead of 
+           'buffer_size' in get_with_expansion()
+ 
+         - Add same fflush -fix to remail.c which is in mailmsg2.c
+ 
+ Changes of Elm2.4ME+ PL31H (25) compared to Elm2.4ME+ PL31 (25)
+ ---------------------------------------------------------------
+ 
+         [ This is out of branch patch. ]
+ 
+         - Incorrect Content-length: -header was causing corruption
+           of folders.
+           From: Guy Harris <guy@netapp.com>
+ 
+         - argv_from_to was not handled ',' in comments correctly.
+           Detected from report of Gary Casterline 
+                 <casterln@nature.Berkeley.EDU>
+         > Use rfc822_toklen instead of len_next_part
+ 
+ Changes of Elm2.4ME+ PL31 (25) compared to Elm2.4ME+ PL30 (25)
+ --------------------------------------------------------------
+ 
+         - Print "Warning: BINARY data? Check Content-Type!"
+           when trying send binary (*) data as text in attachment
+           menu.
+ 
+         (*) binary = not fill requirements of "7bit" and "8bit".
+ 
+         - Convert some system_call() to use 
+           start_run() ... wait_end() instead.
+ 
+         - optionally_enter() in pgp_decode.c was called without 
+           size -argument
+ 
+         - "The problem appears to be that when a "FILE *" is rewound, 
+            the underlying file is not, causing mail messages to be empty. "
+           Reported by: Jon Harder <Jon.Harder@mennolink.org>
+           [ Now input file descriptor is fflush'ed -- this should 
+             synzronize it.
+           ]
+ 
+ 
+         - "I often mail PGP-encrypted attachments to people with the 
+            appropriate content type.  If I want to review the attachment 
+            before sending it, I go the to a)ttachments screen, select the 
+            attachment of interest, and press <Enter>. Elm prompts me for a 
+            pass phrase because I always encrypt using my public key along 
+            with the recipient's.  If I mistype my pass phrase, I cannot use
+            control-F (^F) to cause Elm to forget the cached pass phrase from 
+            either the attachments screen or the send screen.
+ 
+            I wish ^F were recognized on those two screen also."
+           Suggested by: Andrew J. Piziali <andy@piziali.dv.org>
+         * Added ^F to verify_transmission, attachment menu, and to 
+           showmsg_c.c
+ 
+ Changes of Elm2.4ME+ PL30 (25) compared to Elm2.4ME+ PL29 (25)
+ --------------------------------------------------------------
+ 
+         - mailerflags -array (argument vector) was not NULL
+           terminated in remail.c.
+ 
+         - Elm was not recognized SortBy (and aliassortby) keywords
+           [ strfcpy was got size of pointer instead of array size
+             in read_rc.c ]
+           Reported by: "Ralf S. Engelschall" <rse@engelschall.com>
+ 
+         - Fixed some error messages in read_rc.c
+ 
+         - "The problem is that 'case:' statement use int range, so
+            0xFC02 expanded to 0x0000FC02, not to 0xFFFFFC02,
+            but xxx->magic value is short and expanded to 0xFFFFxxxx,
+            so comparation is unsuccessful.
+            Fix is simple: direct cast to short."
+           From: "Andrey A. Chernov" <ache@nagual.ru>
+           [ I don't actually used that fix. Instead I changed magic
+             values to 'unsigned short' in elmlib.h. Now they 
+             are used same way as in melib.h. ]
+         * Actually this (ELMCHAR) code isn't yet in use
+ 
+ Changes of Elm2.4ME+ PL29 (25) compared to Elm2.4ME+ PL28 (25)
+ --------------------------------------------------------------
+ 
+         [ Warning: This is so much changes (and some are 
+           incomplete) so this this quite sure more buggy than
+           PL28. ]
+ 
+         - SECURITY: Elm was passing `shell command` without
+                     quotation to shell when invoking sendmail.
+           Reported by: Wolfgang Ley <ley@cert.dfn.de>
+                  from: "Computer Emergency Response Team, Germany"
+                         <dfncert@cert.dfn.de>
+           (Originally from: Dirk Nimmich <nimmich@uni-muenster.de> )
+         > Don't use shell when calling sendmail (or other mailers)
+         - quote_args() dropped from strings.c
+         - now elm waits until sendmail returns
+           (and simple not put it background without checking
+            if mailing succees)
+         > Now -V option of Elm works better
+ 
+         - Small change in displaying of multipart messages
+ 
+         - (mime_decode.c) Use in_state_seekable instead of 
+                 testing magic agaist STATE_in_file
+ 
+         - Move state.c from src/ to melib/
+ 
+         - New header files melib.h and elmlib.h
+ 
+         - Add routine strfcat to strfcpy.c
+ 
+         - get_folder_type is litle more smarter to detect files
+           in mail directory
+ 
+         - d)omainze removed from header config -menu
+ 
+         - Don't ask shell in configure -- take shell from passwd
+           If passwd is used, default value for elmrc is null string
+           If $SHELL env variable is used, defaualt value for elmrc is 
+                 $SHELL string
+ 
+         - If $EDITOR env varaible is used, default value for elmrc is
+                 $EDITOR string
+ 
+         - Default to p)gp if replying to pgp encoded message
+           (in verify_transmission -menu)
+ 
+         - Remove bounceback variable and bouncebk.c
+ 
+         - [defs.h] In IRIX define 'int32' by using 'int32_t'
+           Warning: If you have compiled Elm with ABI=-64
+                    (default on IRIX64), this changes on disk
+                    format of aliases database
+         * Actual use inttypes.h 
+           (does not work if -cckr is used,
+           (also can't be used in IRIX 5.3 because of conflicts
+            with sys/types.h -- ARGH!)
+ 
+         - Removed references to VMS and EUNICE from Configure
+ 
+         - Removed I_STDARG -- 
+                 now if ANSI_C is defined stdarg.h is used,
+                 otherwise varargs.h is used
+ 
+         - Add do { .... } while(0) to dprint -macro
+ 
+         - Global change: Use strfcpy instead of strcpy
+                     and: Use strfcat (new routine) instead of strcat
+           (but sprintf -calls are still untouched!)
+ 
+         [ Undo Elm2.4ME+ PL28s patch before installing this patch. ]
+ 
+ Changes of Elm2.4ME+ PL28s (25) compared to Elm2.4ME+ PL28 (25)
+ --------------------------------------------------------------
+ 
+         - SECURITY: Elm was passing `shell command` without
+                     quotation to shell when invoking sendmail.
+           Reported by: Wolfgang Ley <ley@cert.dfn.de>
+                  from: "Computer Emergency Response Team, Germany"
+                         <dfncert@cert.dfn.de>
+           (Originally from: Dirk Nimmich <nimmich@uni-muenster.de> )
+         > Quote ` -character
+ 
+ Changes of Elm2.4ME+ PL28 (25) compared to Elm2.4ME+ PL27 (25)
+ --------------------------------------------------------------
+ 
+         - mailerflags was too short for DSN flags
+ 
+ Changes of Elm2.4ME+ PL27 (25) compared to Elm2.4ME+ PL26 (25)
+ --------------------------------------------------------------
+ 
+         - 'hdr -> magic = NULL;' should be 'hdr -> magic = 0;'
+            in parse_util.c
+            Noted by: "Andrew J. Piziali" <andy@piziali.dv.org>
+ 
+         -  "Change Elm to exit after printing the error message, rather than
+             continuing and erasing the screen message and all, if it 
+             encounters an error when reading your "elmrc" file."
+            From: Guy Harris <guy@netapp.com>
+         * But do not do this if in batch mode!
+         * Don't exit if there is errors in global elmrc!
+         * Let user save new .elm/elmrc with option -w
+ 
+         - state_read_headers was building next_header chain
+           incorrectly (and possible other chains also).
+ 
+         - add_paramater_t routine (wrapper for add_parameter)
+           to mime_encode.c
+ 
+         - Let user attach files with option -A
+           To get this work correctly, user needs to have
+           mapping file extension -> mime/type in
+           his .elm/elmrc
+ 
+         - Added field magic to mime_t and routine mime_panic.
+           Now it is possible to get error message MIME_PANIC
+           if in mime structure in memory is something wrong
+           (analogy to STATE PANIC and HEADER PANIC).
+ 
+         - Size of forwarded mail in message/rfc822 was not set 
+           correctly in Elm2.4ME+ PL23.
+ 
+         - Added DSN (Delivery Status Notification) Configure
+           menu to verify_tranmission. You need sendmail 8.8
+           to get this.
+ 
+         - In menu of verify_transmission, show
+           a)attachments option also in user level = 0, if there
+           is attachments.
+         - In menu of verify_transmission, show
+           p)gp option also in user level = 0, if original message
+           was pgp -encoded (when replying).
+         - In menu of verify_transmission, show
+           D)SN option also in user level = 0 if there is dsn settings
+           (does not apply now).
+ 
+ Changes of Elm2.4ME+ PL26 (25) compared to Elm2.4ME+ PL25 (25)
+ --------------------------------------------------------------
+ 
+         - Adding final \n\n was badly broken in copy_message()
+           Reported by: Eilon Gishri <eilon@ibm.net.il>
+ 
+         - Try fixing handling of null bodys in read_headers()
+           { newmbox.c } in some cases. Perhaps this brokes
+           nothing?
+ 
+         - rfc1522_encode_text failed to \0 terminate Subject
+           From: Claus Assmann <ca@informatik.uni-kiel.de>
+ 
+         - PGP fails to check signature if KEEPBINARY=ON
+           From: Heiko W. Rupp <hwr@xlink.net>
+ 
+         - Created new directory melib and made archive libme.a.
+           Some code is moved to that directory. You need to
+           create that directory before applying path!
+ 
+ Changes of Elm2.4ME+ PL25 (25) compared to Elm2.4ME+ PL24 (25)
+ --------------------------------------------------------------
+ 
+         - Problem with screen size (elm_LINES and elm_COLUMNS
+           are inconsistent).
+           [ I was commented out line what was comment
+                       /* kludge for HP Window system? ... */
+             in PL23. VERY misleading........................
+ 
+             I HATE this.         - K E H <hurtta@ozone.FMI.FI>
+           ]
+           
+ 
+         - Fix release month
+ 
+ Changes of Elm2.4ME+ PL24 (25) compared to Elm2.4ME+ PL23 (25)
+ --------------------------------------------------------------
+ 
+         - ks/ke capabilities are optional. They are not present
+           in ANSI -terminal.
+           From: "Andrey A. Chernov" <ache@nagual.ru>
+ 
+         - X-ELM-OSV was not correctly parsed
+ 
+ Changes of Elm2.4ME+ PL23 (25) compared to Elm2.4ME+ PL22 (25)
+ --------------------------------------------------------------
+ 
+         - Add a new config variable, called askpgpsig. 
+           When set to ON, Elm will ask for a username to 
+           sign pgp messages with. 
+           From: Guido van Rooij <guido@gvr.win.tue.nl>
+ 
+         - menu2.c: ch must be int, or comparations with -1 (EOF) 
+           and 257 (REDRAW_MARK) produce wrong results.
+           From: Andrey A. Chernov <ache@nagual.ru>
+           From: Guy Harris <guy@netapp.com>
+ 
+         - In "do_pipe()", "redraw" was both a variable and a label.
+           From: Guy Harris <guy@netapp.com>
+ 
+         - If you've set characters such as the word-erase or 
+           reprint character to non-standard values, use your values, 
+           not the standard ones.
+           From: Guy Harris <guy@netapp.com>
+           [ Added also !escaped test, because now these characters can 
+             be printable. ]
+ 
+         - Moved processing of cursor keys to ReadCh
+           (old cursor key handling was buggy).
+         > HP's shoftkeys are not supported:
+            No options: -k -K
+            No elmrc variables: softkeys keypad
+         > Recognized keys are:
+                 Key             tercap name     terminfo name
+                 -----           -----------     -------------
+                 UP arrow        ku              kcuu1
+                 DOWN arrow      kd              kcud1
+                 LEFT arrow      kl              kcub1
+                 RIGHT arrow     kr              kcuf1
+                 PAGE UP         kP              kpp
+                 PAGE DOWN       kN              knp
+                 HOME            kh              khome
+                 HELP            %1              khlp
+                 FIND            @0              kfnd
+         > To get keys to use, your $TERM variable must point 
+           termcap/terminfo defination what includes these keys.
+           Notice that 'vt100' does not include other than cursor
+           keys. You must perhaps make new defination, for example
+           terminal type 'vt100-plus' :-) For terminfo use 'tic' and
+           'infocmp' -commands.
+ 
+         - state operations are moved outside of #ifdef MIME ... #endif
+         - Added new routines state_write_headers, state_read_headers,
+           delete_headers, locate_header and find_header to
+           parse_util.c. read_header_line is now implemented with routine
+           state_read_hdr_line. file_read_headers is implemented with routine
+           state_read_headers.
+         > Now included RFC 822 parts have printed text
+           -- Start of included mail From: xxxxx
+           instead of
+           -- Start of included mail.
+         - Rewritten read_mime_header to use file_read_headers, mainly by 
+           dividing it to new routine parse_mime_headers
+         > Rewritten rfc822_parse. Now non-mime messages inside of
+           message/rfc822 should be handled more correctly.
+         - Setting elmrc variable 
+           require-mime-version-for-body-encoding to FALSE causes
+           that almost all messages are treated as MIME -messages and
+           MIME-Version is not required for these (in top level
+           or inside of message/rfc822).
+ 
+         - Add  flag CM_REMOVE_ENVELOPE for copy_message
+         > make message/RFC822 attachment when forwarding with copy_message
+ 
+         - Make wait() in matapager restart in case of EINTR error
+ 
+         - Do MIME Part 2 (RFC 1522) decoding even when not MIME
+           even when not Mime-Version -header is present 
+           (If you want olf behauviour, set elmrc variable
+            require-mime-version-for-hdr-encoding to TRUE).
+           Header decoding is not done if sending elm was 
+           disabled to do MIME Part 2 (RFC 1522) encoding
+           (as set in elmrc variable nohdrencoding). That 
+           information is carried in header X-ELM-OSV:
+           (Our standard violations).
+ 
+         - quoted-printable-decode was not decoding zero length part
+           correctly.
+         > Indicate with length == -1 as not set instead of length == 0
+ 
+         - Added symbolics values RHL_MARK_FOLDING and RHL_CHECK_HEADER
+           for flags of read_header_line. Now read_header_line check
+           header for carefully. Side effect: If there is spaces before
+           ':' in header, them are deleted (assuming RHL_CHECK_HEADER).
+ 
+         - Add to mime_types[] following non-standard main content types:
+           x-world, model
+ 
+ Changes of Elm2.4ME+ PL22 (25) compared to Elm2.4ME+ PL21 (25)
+ --------------------------------------------------------------
+ 
+         [ Warning: There is quite much changes in
+           user interface, so perhaps there is bugs. ]
+ 
+         > Changes in Makefile.SH -- remember to run
+           'Configure' or 'Configure -d' or 'Configure -S'
+ 
+         - 'ch' need to be 'int' in alias()
+         - 'cmd' need to be 'int' in MenuLoop()
+         - 'ch' need to be 'int' in generic_menu()
+           Problem noted by: Claus Assmann <ca@informatik.uni-kiel.de>
+ 
+         - There was unwanted trigraph in run_decoder()
+           Problem noted by: Claus Assmann <ca@informatik.uni-kiel.de>
+ 
+         - There was missing 'default:' in state_put()
+           Problem noted by: Claus Assmann <ca@informatik.uni-kiel.de>
+           Problem noted by: Guy Harris <guy@netapp.com>
+ 
+         - rename 'timeout' to 'elm_timeout' to get rid out linker warning
+         - rename 'filter' to 'elm_filter' to get rid out linker warning
+         - rename 'LINES' to 'elm_LINES' to get rid out linker warning
+           (These are defined also in libtermlib.so)
+ 
+         - rename 'COLUMNS' to 'elm_COLUMNS' to match 'elm_LINES'
+ 
+         - If there is Raw(ON) in parent in metapager(), then
+           also Raw(OFF) must be in parent
+           Noted by (?): Jurgen Fluk <louis@dachau.marco.de>
+ 
+         - Replace some getchar()s with ReadCh(REDRAW_MARK)
+           in syscall.c
+ 
+         - Replace some getchar()s with ReadCh(REDRAW_MARK)
+           in read_rc.c
+ 
+         - Replace some getchar()s with ReadCh(REDRAW_MARK)
+           in alias.c
+ 
+         - Replace some getchar() with ReadCh(REDRAW_MARK)
+           in utils.c
+ 
+         - Use type application/X-ELM-encode with
+           [enclode] ... [clear] if message is multipart
+           (Elm 2.4ME+ PL6 should know this type, but there
+            was error is some versions of ME+ in mime_notplain).
+ 
+         - mime_notplain was returning TRUE (should be FALSE) 
+           for application/X-ELM-encode.
+ 
+         - The builtin++ pager clears the screen before displaying the 
+           first screen of the message; however, the metapager wasn't 
+           clearing the screen before running the external pager, which 
+           left some junk on the screen.
+           From: Guy Harris <guy@netapp.com>
+ 
+         - Convert optionally_enter to use flag bits and
+           now it returns REDRAW_MARK in most places when redraw
+           is needed
+ 
+         - LOCK_DIR removed from Configure / config.h.SH
+ 
+         - Rememmber if last Configure run there was answer
+           'none' for additional librariers
+ 
+         - Some new checks in Makefile (or actually in Makefile.SH), 
+           Configure is run lately (that confih.sh or Makefile or
+           config.h are not stale)
+           
+ 
+ Changes of Elm2.4ME+ PL21 (25) compared to Elm2.4ME+ PL20 (25)
+ --------------------------------------------------------------
+ 
+         - More Configure fixes for IRIX 6.2
+ 
+         - PGP signed messages (with type text/plain) was not handled
+           correctly.
+           Noted by: Volker Paulsen <Volker.Paulsen@gmd.de>
+ 
+         - Just a short one-liner to fix the display:  
+           When you leave the key selection menu in 
+           pgp_mail_public_key() with `q' (i.e., don't mail a key), 
+           this routine currently returns 0.  This means that the main list
+           won't be redrawn and seems to be a bug.
+           From: Thomas Roessler <roessler@sobolev.rhein.de>
+ 
+         - read_number should create buffer of size SLEN, not NLEN
+           since it uses optionally_enter() which assumes that the 
+           buffer has length SLEN
+           From: Thomas Roessler <roessler@sobolev.rhein.de>
+ 
+         - Additionally, one might want to have the pgp functions 
+           in the help menu.
+           From: Thomas Roessler <roessler@sobolev.rhein.de>
+           
+ Changes of Elm2.4ME+ PL20 (25) compared to Elm2.4ME+ PL19 (25)
+ --------------------------------------------------------------
+ 
+         [ There is changes of error handling of leave_mbox --
+           so report, if you lost mail... ]
+ 
+         - Look also termlib.so and curses.so in Configure
+ 
+         - Remove PGP test from need_meta in showmsg.c
+           (It was causing that metamail was not called for 
+            multipart/signed what isn't supported.)
+ 
+         - Move metamail flags before PGP flags in show_message
+           in screen.c 
+ 
+         - lib/safeopen.c need to be added to MANIFEST
+           Noted by: Keith Manley <kmanley@bits.fc.hp.com>
+ 
+         - Elm as acting quite oddly if ending boundary of multipart
+           structure was missing.
+           Detected from report of: Rolf Larsson <rln@ludd.luth.se>
+ 
+         - Add sleep_message() to out_utils.c
+ 
+         - Detect if there is read error in newmbox!
+ 
+         - Check read errors also in some other places....
+ 
+         - Changes in leave_mbox -- now it returns with value -2 if
+            it fails to leave folder
+ 
+         - SIGUSR1 and SIGUSR2 is anly handled when in prompt
+           (because otherwise we can be in wrong state --
+            for example in middle in resync.)
+ 
+         - Check in ReadCh if it was called from GetPrompt
+           (GetPrompt want to see EINTR error!)
+ 
+         - ReadCh takes now redraw flag: Either 0 or REDRAW_MARK.
+           Now elm is able in many places automatically redraw screen
+           when elm resumes after suspending.
+ 
+         - skip_envelope() to parse_util.c
+ 
+         - Use skip_envelope() in get_and_expand_everybody() and
+           handle_reply_to() -- now elm should not be confused
+           with MMDF envelope of mail
+           Reported by: { Unknown -- mail lost }
+ 
+ Changes of Elm2.4ME+ PL19 (25) compared to Elm2.4ME+ PL18 (25)
+ --------------------------------------------------------------
+ 
+         - Fix SIGSEGV (with application/pgp; format=mime)
+ 
+         - With application/pgp; format=mime in included mime type
+           nested structures was not parsed (actually that was causing
+           SIGSEGV)
+ 
+         - recognize application/pgp; x-action=signclear
+ 
+         - Add "-- Start of included mail." and "-- End of included mail."
+           texts.
+ 
+ Changes of Elm2.4ME+ PL18 (25) compared to Elm2.4ME+ PL17 (25)
+ --------------------------------------------------------------
+ 
+         [ This patch includes very many changes, so perhaps there
+           are bugs ... ]
+ 
+         - Clean up some of the questions in the "Configure" script.
+           From: Guy Harris <guy@netapp.com>
+ 
+         - Added a '-S' option to the Configure script to just redo the
+           "variable substitutions on .SH files" that the script performs
+           at the end.  "I found this extremely useful, as I often made
+           changes to the config.sh (for instance, the 'optimize' flags),
+           and I wanted to re-create the Makefiles without running the
+           entire Configure script all over again."
+         - Also added '-h' option to report usage and available options to
+           Configure script.
+           From: Will Day <willday@rom.oit.gatech.edu>
+ 
+         - Add support for a "mailpermissions" variable in your "elmrc" file 
+           that can be set to specify the permissions to be used when creating 
+           a new mail folder.  The syntax to use when specifying the permissions
+           is *not* numeric, it's an "ls"-style string such as "rw-rw----", and
+           the default is "rw-------".
+           From: Guy Harris <guy@netapp.com>
+ 
+         - (Elm)HelpViewAttach was missing from s_elm.m
+ 
+         - Have the NLS stuff make "s_elmalias.h" from "s_elmalias.m".
+           From: Guy Harris <guy@netapp.com>
+ 
+         - Fix up "gencat" to compile on systems that don't do ANSI C 
+           (e.g., SunOS 4.1[.x] when using the bundled C compiler).
+           From: Guy Harris <guy@netapp.com>
+ 
+         - Some additions to help text of Elm
+ 
+         - Reconstruct mime_send_t.  There was wrong type when multipart
+           message was sent and pgp was used.
+           Noted by: J. Porter Clark <jpc@hammer.msfc.nasa.gov>
+ 
+         - Added elmrc option: "quoteforward", which will let the user 
+           restore the behavior of original elm when forwarding messages 
+           - that is, to quote them like replies.  
+           "I wanted this available, because usually when I forward a 
+            message, I will comment various lines, and if it's not quoted 
+            like a reply, my comments can be confused with the forwarded 
+            message (and I didn't want to have to manually comment the 
+            message every time)."
+           From: Will Day <willday@rom.oit.gatech.edu>
+ 
+         - convert mail() and send_msg() to use binary flags. 
+           Get rid of global variable "forwarding".
+ 
+         - Added safeopen_rdwr() call yet some places.
+           "While browsing through elm me+ xyz kh's source code, 
+            I stumbled across an invocation of tempnam() in a 
+            somewhat insecure environment:  In mailmsg2.c, it's 
+            output is used as argument to fopen(...,"w+").  This is
+            dangerous, since it may allow other users to access those 
+            temporary files."
+           From: Thomas Roessler <roessler@sobolev.rhein.de>
+         > Also use open_end_update() call, then code is cleaner
+           [ In suplied patch there was possibility that elm destroyes
+             =sent folder... ]
+ 
+         - Modification for Configure: On a Linux system which uses 
+           ELF-format shared libaries, the library symbols do not have 
+           an underscore prepended to them.
+           "I simply removed the [._] part from the sed expression.  This
+            makes everything compile and run happily on my machine, 
+            but if you want to correct this problem in your distribution, 
+            you would probably want to keep the old rule as well, to keep 
+            it from breaking elsewhere."
+           Noted by: Matthew Hunt <hunt@mph124.rh.psu.edu>
+ 
+         - "The second patch (re-)enables the use of the `T' key in the menu 
+            at the end of a message (tag + next).  This used to work in 
+            earlier releases of elm."
+           From: J Wunsch <j@uriah.heep.sax.de>
+ 
+         - "I think there is a small bug in metapager.c which has the 
+            consequence that the pager menu is sometimes displayed on the 
+            wrong screen page. The patch below fixes this behaviour."
+          From: Thomas Roessler <roessler@sobolev.rhein.de>
+ 
+          [ This patch little questionable -- 'ti' is "string to begin
+            brograms that use cup" (cursor addressing) and 'te' is
+            "string to end programs rhat use cup" -- problem is
+            that xterm uses ti/te to swap screen page... ]
+ 
+         - "Additionally, there is still an ugly timezone bug in elm-me+; 
+            the old patch for elm 2.4 applies cleanly to the current me+ 
+            version."
+           Noted by: Thomas Roessler <roessler@sobolev.rhein.de>
+         > Fix timezone:
+           "OK...here is the fix for the wierd timezone shifting.  
+            Besides the botched month parameter, the year also was wrong.
+ 
+            This patch better documents the input parameters to the 
+            lib/date_util.c procedures, and fixes get_tz_mins() to avoid 
+            a wierd offset shifting problem.  Thanks to Thomas Roessler 
+            <roessler@sobolev.rhein.de> for chasing down the cause of the 
+            problem."
+          From: Chip Rosenthal <chip@unicom.com>
+ 
+         - Fix dangling pointer bug in attach_viewer!
+ 
+         - Recognize text/x-pgp.
+           From: Guido van Rooij <guido@gvr.win.tue.nl>
+           [ + #ifdef USE_PGP added ]
+         > If type was text/x-pgp, don't consider case 
+           that PGP file is binary
+ 
+         - Don't convert application/x-pgp* to application/pgp
+           in newmbox.c -- instead recognize it in mime_decode.
+ 
+         - Don't reset type_opts when converting text/plain to
+           application/pgp.
+           [ That change was buggy -- fixed in PL21 ]
+ 
+         - Move "Decrypting message..." and "Checking signature..."
+           messages to another place.
+ 
+ Changes of Elm2.4ME+ PL17 (25) compared to Elm2.4ME+ PL16 (25)
+ --------------------------------------------------------------
+ 
+         -  Some systems use OXTABS bit instead of TABDLY
+           [ Various paches for *BSD ]
+           From: Ollivier Robert <roberto@keltia.freenix.fr>
+           From: Jeff Thieleke <thieleke@lust.isca.uiowa.edu>
+           From: Andrey A. Chernov <ache@astral.msk.su>
+ 
+         - Undone HP-UX change for ANSI_C
+           "This is mostly incorrect.  We figured out that 
+            the problem was the -traditional flag that was included 
+            by default when compiling with gcc."
+           Noted by: Jeff Thieleke <thieleke@lust.isca.uiowa.edu>
+ 
+         - Removed -traditional from gcc flags in Configure
+           "The real fix would be to remove the default CFLAGS when 
+            compiling with gcc, since they probably aren't needed any more."
+           Suggested by: Jeff Thieleke <thieleke@lust.isca.uiowa.edu>
+ 
+         - Don't allow change a filename of forwarded mail in attachment
+           menu.
+ 
+         - If content-transfer-encoding is unknown when saving attachment,
+           treate it as binary.
+ 
+         - Don't allow change filename in attachment menu to non-existent
+ 
+ Changes of Elm2.4ME+ PL16 (25) compared to Elm2.4ME+ PL15 (25)
+ --------------------------------------------------------------
+ 
+         [ Warning: state routines are rewritten -- so look below
+           what to do if you get STATE PANIC message ... ]
+ 
+         - Add #include "headers.h" to safeopen.c to get rid
+           out one stupid compiler warning
+           Urged by: Andrew J. Piziali <andy@daldd.sc.ti.com>
+ 
+         - struct state is divided to two structs: struct in_state
+           and struct out_state. Large modifications to state
+           routines (state.c). 
+ 
+           If you get message STATE PANIC: Bad magic number
+           compile elm with debugging -g and -DDEBUG
+           and run elm with -d11 and try get it repeated.
+           Now STATE PANIC should cause producing of core file.
+           
+           Look with debugger where that STACE PANIC accured (ask
+           stack trace from debugger) and look also file ~/ELM:debug.info
+ 
+         - If terminal driver is expanding tabs, do not print
+           them -- instead jump to correct location
+ 
+         - "HP-UX apparently doesn't declare __STDC__ (like AIX), 
+            so compiling with cc or gcc fails in src/init.c at the getgid(), 
+            getuid() prototypes."
+           From: Jeff Thieleke <thieleke@icaen.uiowa.edu>
+           [ Undone in ME+ PL17 ]
+ 
+         - If you sign 8-bit mail, it will be later encoded with
+           quoted-printable or base64 (by elm or by sendmail).
+           Thus 'invalidating' because pgp_decode does not undo contet-
+           transfer encoding before calling PGP.
+           Noted by: Zoltan Hidvegi <hzoli@cs.elte.hu>
+           Noted by: Hans-Christoph Wirth <hansi@dianoia.mayn.de>
+         * Now content-transfer-encoding is decoded before bodypart
+           is passed to pgp (it also now work, when *.pgp file
+           is encoded with base64).
+         > That decoding is done via temporary file -- perhaps I
+           some time stack state routines so temporary file is not needed
+           and decoding of content-ttransfer-encodings are done during
+           reading.
+         > If I some day get implemented MIME/PGP then 8-bit mail is always
+           encoded with quoted printable and then passed to PGP for signing.
+ 
+         - Display text before PGP armor if elmrc variable showpgppreamble
+           is set (default). Binary PGP files are detected by looking first
+           byte (after decoding content-transfer-encoding).
+ 
+         - Fix to PL15 fix: "Elm fail in resyncing if mailfile is created 
+           after initial entering to mailbox." -- previous fix can cuase
+           elm exiting with message 
+           "What's this?  The temp folder already exists??" and then
+           "Ahhhh... I give up."
+           Perhaps noted by: Andrew J. Piziali <andy@daldd.sc.ti.com>
+ 
+         - SECURITY: Elm was running PGP as setgid mail (by using popen)
+           when searching matching keys -- converting to use 
+                 pipe - fork - setgid (groupid) - execl
+ 
+         - Need pass +language=en to PGP when searching matching keys
+           Noted by: Boris Staeblow <balu@reido.in-berlin.de>
+ 
+         - Initialize last (extra) element also to NULL in DynamicArray
+           so that DestroyDynamicArray works (lib/dynarray.c)
+           -- was causing SIGSEGV in GetPGPKey
+ 
+         [ Undo Elm2.4ME+ PL15s patch before installing this patch. ]
+ 
+ Changes of Elm2.4ME+ PL15s (25) compared to Elm2.4ME+ PL15 (25)
+ ---------------------------------------------------------------
+ 
+         - SECURITY: Elm was running PGP as setgid mail (by using popen)
+           when searching matching keys -- converting to use 
+                 pipe - fork - setgid (groupid) - execl
+ 
+ Changes of Elm2.4ME+ PL15 (25) compared to Elm2.4ME+ PL14 (25)
+ --------------------------------------------------------------
+ 
+         [ Warning: This is perhaps more buggy than PL14. ]
+ 
+         - Some changes in Makefiles, Configure
+         - Change of temporary mbox name, put temporary mbox to
+           back to temp directory (from home directory)
+         - lib/safeopen.c
+         - can_open(filename,"sw") checks if creating of _new_ file
+            is possible (O_EXCL) -- and use that in leavembox.c
+            Side-effect: New file is created
+         - use isprint((unsigned char)ch) in src/curses.c
+         - "I removed all fopen(file, "w") where file was a filename in /tmp 
+            and replaced these with a safeopen(file) call.  These changes 
+            should be also applied to the vanilla elm source."
+         - "Also there are some minor bugfixes for PL11.  
+            Elm did not asked my PGP password when I wanted to 
+            read a PGP encrypted mail since it wrongly thought
+            that the mail is only signed but not encrypted.  
+            That's the most serious bug."
+         - "I add a ClearScreen() before the fork in pgp_decrypt_init() 
+            to make the screen look clearer."
+            From: Zoltan Hidvegi <hzoli@cs.elte.hu>
+ 
+         - Routine safeopen_rdwr added to safeopen.c 
+ 
+         - Test agaist special modes was WRONG in leavembox.c
+                 (it was 0x7000 and it should be 07000)
+         - Treate files with special modes as SPOOL files (newmbox.c)
+         - Handle 'intelligent' way also SPOOL files what haven't in mailhome
+         - Restore also special modes of file if file is not executable
+         - Don't chown file if owner is already correct -- it resets
+           special modes
+         * With these changes it is possible to redirect sendmail aliases
+           to files (mode 04600) and cause that elm does not reset setgid
+           bit (what is required to be set, before sendmail accepts forwarding
+           to no world writable files).
+ 
+         - Multiple To: -headers was cauisng of trashing of memory
+           and SIGSEGV
+           Noted by: Richard Allen <ra@rhi.hi.is>
+ 
+         - Elm fail in resyncing if mailfile is created after initial
+           entering to mailbox.
+           Noted by: Miroslav Ruda <ruda@ics.muni.cz>
+           { I didn't used suplied patch. }
+ 
+         - Elm fails to create received -folder
+           Noted by: Jussi Kaurola <kaurola@dionysos.FMI.FI>
+         - Added function open_end_update to file_util.c
+ 
+         - Replace iscntrl((unsigned char)*pending) with
+           !isprint((unsigned char)*pending) in builtin++.c
+           because Configure asks that is isprint 
+           working with 8-bit values, but it does not ask about iscntrl
+ 
+         * Notice: Seems that someones does not agreed with interpretation
+           of ASCII_CTYPE defination. My interpretation is:
+ 
+                 ASCII_CTYPE defined:    isprint works only with arguments
+                                         0-127
+ 
+                 Conclusion:             We can't test that is characters in
+                                         range 128-255 printable or not, so
+                                         don't print them
+ 
+           ASCII_CTYPE is defined when you answer "no" to following question:
+           "Should Elm assume that isprint() won't break on 
+             non-ASCII characters?"
+ 
+           To get 8-bit characters to work you need:
+                 1) 8-bit clean ctype functions and macros
+                 2) ASCII_CTYPE is not defined
+                 3) setlocale exists (Configure have found locale.h;
+                    that is: I_LOCALE is defined)
+                 4) Correct locale defination (environment variable
+                         $LANG or $LC_CTYPE usually)
+                    Look manual page of setlocale
+                 - If you are not using builtin(++) pager in Elm, thinks
+                   can go more complicated -- all pagers does not use
+                   locale definations
+ 
+         - Use kill(getpid(), SIGSTOP) instead of  kill(0, SIGSTOP)
+           so that delivering of mail does not stop when user suspends
+           Elm.
+           Reported by: Richard J. Auletta <rauletta@erebor.cudenver.edu>
+ 
+ Changes of Elm2.4ME+ PL14 (25) compared to Elm2.4ME+ PL13 (25)
+ --------------------------------------------------------------
+ 
+         - PGP signed (or encrypted) MIME mail was not quoted when 
+           replying. Quick fix for pgp_decode in pgp.c. It still 
+           perhaps have broken...
+ 
+ Changes of Elm2.4ME+ PL13 (25) compared to Elm2.4ME+ PL12 (25)
+ --------------------------------------------------------------
+ 
+         - Compiler was giving warning that 'char *' and
+           'unsigned char *' are not assignment-compatible
+           (for code in mime_encode.c)
+           Noted by: Arkady Altman <aya@cae.cig.mot.com>
+ 
+         - Include headers of forwarded message to editor
+           buffer even when you have noheader = ON
+           (that is in situation mimeforward = OFF).
+           That is now controlled with elmrc variable "noheaderfwd"
+           (default: OFF)
+ 
+         - Elm was getting SIGSEGV in remailer_parse_opts in remailer.c
+           Noted by: V Menayang <victor@slip-50-11.ots.utexas.edu>
+           [ Notice that this REMAILER code is still broken! ]
+ 
+         - remailer.c was calling finger without resetting egid!
+ 
+         - FreeBSD changes to utils/newmail.c also pertain to NetBSD
+           From: Jeff Thieleke <thieleke@icaen.uiowa.edu>
+ 
+ Changes of Elm2.4ME+ PL12 (25) compared to Elm2.4ME+ PL11 (25)
+ --------------------------------------------------------------
+ 
+         Warning: This version is probably much more buggy
+                  than PL11 !!
+ 
+         - The blank line between two messages in a folder 
+           was missing.
+           Noted by: Juergen Obermann <Juergen.Obermann@hrz.uni-giessen.de>
+ 
+         - If nohdrencoding = TRUE and there is 8bit  characters in subject,
+           treat as there was 8bit characters in body.
+           From: Andrey A. Chernov <ache@astral.msk.su>
+           [ This does not work very well... ie. It works only when
+             Content-Type is Text/plain. ]
+           " Before RFC 1522 issued, too many users (f.e. Russian users) use
+             8bit chars in Subject: header field. There is a lots of 8bit 
+             capable MUA & MTA exists now, much more then RFC1522 compatible 
+             ones. In existent variant when you enter 8bit subject with ASCII 
+             body result content charset stays as ASCII, it makes impossible to
+             recognize Subject: charset. I UNDERSTAND that my method violates 
+             MIME slightly (no 8bit characters must be in header field) but it 
+             is adoptation of real life practic."
+ 
+         - Add /usr/sbin to default path, there is sendmail on FreeBSD
+         - Disable national extensions of 'date'
+         - Add FreeBSD lock directory
+         - Add KOI8-R charset to user prompt, it is officially registered, 
+           RFC1700
+         - Fix utime_buffer declaration for FreeBSD
+         - Allow mailbox editing for Expert user level only. Total disabling
+           of this option makes life harder for experienced users and total
+           enabling cause accidental 'e' hitting damage novice users mailboxes.
+           It seems that enabling it for Expert user leve is the best solution.
+           From: Andrey A. Chernov <ache@astral.msk.su>
+ 
+         - "I also discovered another small 'bug'... Michael Elkins changed 
+            someday in pgp.c a get_address_from() call to a simple strcpy() 
+            which caused my pgp not to find my secret key because of a 
+            leading blank:
+            " Volker Paulsen <paulsen@gmd.de>"
+             ^
+            After I changed it back to get_address_from() the leading blank
+            becomes removed and pgp matches the key correctly against its key
+            ring ."
+           From: Volker Paulsen <Volker.Paulsen@gmd.de>
+ 
+         - Add binary -flag for header_rec. No longer hack for remail.c.
+ 
+         - Make more clear what part of message was PGP signed or encrypted.
+           (Why pgp returns exit status 0 even when signature doesn not
+            match???)
+ 
+         - Some massive rewriting of copy_message. Now should decoding of
+           RFC 1522 encoding work correctly when replying (and forwarding).
+           Side effects:
+                 - Headers which have longer than 32 KB after unfolding
+                   are truncated
+                 - Exact folding is not preserved
+ 
+ Changes of Elm2.4ME+ PL11 (25) compared to Elm2.4ME+ PL10 (25)
+ --------------------------------------------------------------
+ 
+         - Elm wrote incorrect Content-Length: -header when 
+           updating Status: -header
+           Noted by: Juergen Obermann <Juergen.Obermann@hrz.uni-giessen.de>
+           [ That content-length is lightly too big and is not fixed
+             if it is last mail in folder (it is not big enough that
+             newmbox.c notices) also incorrent Content-Length: -header
+             causes in other situations that it is ignored. This causes
+             problems when "From ":s are not escaped. ]
+ 
+ Changes of Elm2.4ME+ PL10 (25) compared to Elm2.4ME+ PL9 (25)
+ -------------------------------------------------------------
+ 
+         - CM_DISPLAYING was wrong value in hdrs/defs.h
+ 
+         - Elm was corrupting folder by adding number to end of mail...
+           And therefore causes that next mail does not start
+           with "From " in folder.
+           Noted by: Volker Paulsen <Volker.Paulsen@gmd.de>
+ 
+         - REMAILER code does not compile.
+           From: Andrey A. Chernov <ache@astral.msk.su>
+           From: Arkady Altman <aya@cae.cig.mot.com> 
+ 
+ Changes of Elm2.4ME+ PL9 (25) compared to Elm2.4ME+ PL8 (25)
+ ------------------------------------------------------------
+ 
+         - Attach viewer does not completely fill header_rec 
+           so "lines" was uninitiazed, which may cause
+           "metapager()" to choose randomly whether to use the 
+           built-in pager or not, if you haven't set "pager" to 
+           "builtin" or "internal". Now structure is pre-initialized
+           completely. "lines" is set to number of bytes / 60
+           (not saticfactory, but actually metapager should use 
+            number of lines in decoded message -- 
+           not in original anyway.)
+           Prompted by: Guy Harris <guy@netapp.com>
+ 
+ Changes of Elm2.4ME+ PL8 (25) compared to Elm2.4ME+ PL7 (25)
+ ------------------------------------------------------------
+ 
+         - In syscall.c, around line 180, the space for p 
+           was allocated but the actual string was never built.
+           From: Mark Johnson <Mark.Johnson@ustc.vlsi.COM>
+         
+         - At the end of a message with the buildin pager I 
+           sometimes get the prompt "MORE (you've seen 101%):"
+           and I can not read the next message with 
+           pressing the space bar.
+           From: Juergen Obermann <Juergen.Obermann@hrz.uni-giessen.de>
+ 
+         - "rfc822_reap_comments()" wasn't properly handling 
+           Content-Type: headers like
+ 
+           Content-Type: Multipart/Mixed;
+                 boundary="--Next_Part(Wed_Feb_14_09:54:49_1996)--"
+ 
+           because it didn't realize that the ")" in the boundary 
+           was inside a quote, and therefore should be copied rather 
+           than being stripped out.
+           From: Guy Harris <guy@netapp.com>
+ 
+         - It wasn't RFC 1522-decoding the name in the "From:" header 
+           when it put in the "Forwarded message from" and 
+           "End of forwarded message from" lines.
+           From: Guy Harris <guy@netapp.com>
+ 
+         - Put defualt disposition for attachment to be 'attachment'
+           when sending.
+ 
+         - Check that attachment is not deleted before mail is sent.
+ 
+         - Because copy_message is now called from metapager, it
+           needs two more arguments (mailfile and current_header).
+           I hope that this change breaks nothing! 
+           Detected from report of: Mark Johnson <Mark.Johnson@ustc.vlsi.COM>
+ 
+ Changes of Elm2.4ME+ PL7 (25) compared to Elm2.4ME+ PL6 (25)
+ ------------------------------------------------------------
+ 
+         - Incorrect subject
+ 
+ Changes of Elm2.4ME+ PL6 (25) compared to Elm2.4ME+ PL5 (25)
+ ------------------------------------------------------------
+ 
+         - Sometimes extra newline was added when message or
+           body of it was copied.
+ 
+               > copy_message in fileio.c was gone too hairy.
+                 Tried to reorganize it. I hope that nothing
+                 breaks.
+ 
+               > Semantic of flag CM_DECODE is now changed.
+ 
+               > Now message is decoded before replying and forwarding
+                 (excpet when mime_forward is true -- forwarded message
+                 as attachment is not decoded).
+ 
+               > Well, now [encode] [clear] does not work when metamail
+                 is called.
+ 
+               > [encode] ... [clear] is now internally handled as
+                 application/X-ELM-encode (in MIME -message)
+ 
+         - Do RFC 1522 decoding only in MIME messages.
+ 
+         - builtin++ code in metapager was broken [encode] ... [clear] 
+ 
+               > I simplified metapager. I hope that nothing
+                 breaks.
+ 
+         > Notice that [encode] ... [clear] is broken when sending
+           multipart messages.
+ 
+         - Now also headers of message/rfc822 are prefixed when replying
+ 
+         - Nicer printing of folded headers (in metapager and rfc822_decode)
+ 
+         - Letter 'e' (= uses Elm's [encode] ... [clear]) added to status
+           letter of mailbox menu.
+ 
+ Changes of Elm2.4ME+ PL5 (25) compared to Elm2.4ME+ PL4 (25)
+ ------------------------------------------------------------
+ 
+         - "nohdrencoding" was in wrong place in list
+ 
+         - To instead of From in headers was always displayed:
+           From: Petr Lampa <lampa@fee.vutbr.cz>
+ 
+         - There was some confusion in (char *) versus (unsigned char *)
+           in rfc1522_encode_text.
+           Pointed by: Petr Lampa <lampa@fee.vutbr.cz>
+ 
+         - Replaced check of R_OK with ECCESS_EXISTS in can_save 
+           in attach_menu.c
+ 
+         - Reordering of attach_viewer so metamail is not called 
+           when it isn't needed (new defination of 'pagemultipart'
+           was broken it.)
+ 
+         - Message "Parsing MIME structure..." is printed
+ 
+         - Added to some unlink and elm_chown calls to attach_menu.c
+ 
+         - Now prints "Executing metamail..." if metamail is called for
+           display message.
+ 
+         - Tried fix MIME decoding of headers in copy_message
+           (well, it still can't work correctly.)
+ 
+         - MIME (RFC 1522) encoding of In-Reply-To -header
+ 
+                 > Address headers and headers from .elm/elmheaders are still
+                   not encoded.
+ 
+         - Don't try print To: address in menu if it does not exists.
+ 
+ Changes of Elm2.4ME+ PL4 (25) compared to Elm2.4ME+ PL3 (25)
+ ------------------------------------------------------------
+ 
+         [ Warning: This is perhaps more buggy than PL 3 (25). ]
+ 
+         * Sending of simple Text/Plain messages with quoted-printable encoding
+           was broken when remailer -code was added.
+           Noted by: Petr Lampa <lampa@fee.vutbr.cz>
+ 
+         - In the index screen Tag all, Delete all and Undelete all 
+           didn't show the new status of the messages.
+           From: Juergen Obermann <Juergen.Obermann@hrz.uni-giessen.de>
+ 
+         - In readmsg the Cc-header line is always shown.
+           From: Juergen Obermann <Juergen.Obermann@hrz.uni-giessen.de>
+           [ This should be also posted to Elm Development Cordinator ]
+ 
+         - Add a "Status: RO" line to all outgoing messages (when the "copy" 
+           option is turned on), so that they do not show up as "New" when you 
+           look at a folder.
+           From: Pete Wenzel <pete@stc.com> 
+ 
+         - The macro X_OK is undefined in some systems. 
+           Use EXECUTE_ACCESS instead.
+           From: Gunnar Ekolin <ekolin@carlstedt.se>
+ 
+         > Failing to include <unistd.h>. 
+           Test agaist I_UNISTD instead of ANSI_C.
+           Noted by: Petr Lampa <lampa@fee.vutbr.cz>
+ 
+         > Now EXECUTE_ACCESS, WRITE_ACCESS, READ_ACCESS, ACCESS_EXISTS,
+           EDIT_ACCESS is defined in terms of X_OK, W_OK, R_OK, F_OK
+           from unistd.h (if available)
+ 
+         - Fix defination in hdrs/mcprt.h to match with lib/mcprt.c
+           From: Claus Assmann <ca@informatik.uni-kiel.de>
+ 
+         - DisplayAddress not work (well, I really not used that patch).
+           That needs still reconsideration.
+           From: Claus Assmann <ca@informatik.uni-kiel.de>
+ 
+         - Mime (RFC 1522) encoding of following headers:
+                 - From  (fullname)
+                 - Subject
+                 - Content-Description
+ 
+                 Encoding of In-Reply-To, To, CC or headers in 
+                 .elm/elmheaders is NOT done.
+ 
+         - New elmrc variable "nohdrencoding". If this variable is TRUE,
+           then MIME encoding of headers isn't done.
+ 
+         - Wrong tests with allow_no_encoding in src/mailmsg2.c.
+           Noted by: Petr Lampa <lampa@fee.vutbr.cz>
+ 
+         - Use strincmp for lib/strincmp.c instead of strcasecmp.
+           Noted by: Petr Lampa <lampa@fee.vutbr.cz>
+ 
+         - Added check for write errors in mime_encode.c
+         
+ Changes of Elm2.4ME+ PL3 (25) compared to Elm2.4ME+ PL2 (25)
+ ------------------------------------------------------------
+ 
+         - Fix to builtin++.c SIGSEGV fix
+ 
+ Changes of Elm2.4ME+ PL2 (25) compared to Elm2.4ME+ PL1 (25)
+ ------------------------------------------------------------
+ 
+         - Really fix In-Reply-To -header
+           [ This is also posted to Elm Development Cordinator ]
+ 
+ Changes of Elm2.4ME+ PL1 (25) compared to Elm2.4ME+ PL0 (25)
+ ------------------------------------------------------------
+ 
+         - SIGSEGV in builtin++.c when looking full headers of mail
+           and Ctrl-L was hit.
+ 
+         - Typo in remailer.c (causes that it don't link)
+           From: Ollivier Robert <roberto@keltia.freenix.fr>
+ 
+         - Ultrix patch from comp.mail.elm
+           From: John Simonson <gort@wildcat.ceas.rochester.edu>,
+                 Sydney Weinstein <syd@myxa.com>, 
+                 Bill Gianopoulos <wag@swl.msd.ray.com>
+ 
+         - Now Elm's Configure search for metamail -program
+ 
+         - DisplayAddress: Don't munge sender with get_real_name
+ 
+         - Elm was generating syntactically incorrect In-Reply-To -headers
+ 
+         - Because some peoples seems have trashed src/state.c that patch
+           includes file src/state.c.PL1. 
+           If src/state.c.PL1 and src/state.c don't have identical,
+           use command: mv src/state.c.PL1 src/state.c
+           otherwise:   rm src/state.c.PL1
+ 
+         - SIGSEGV when hitting 'G' in builtin++.c
+ 
+ 
+ Changes of Elm2.4ME+ PL0 (25) compared to version Elm2.4 PL24 ME8b+
+ -------------------------------------------------------------------
+ 
+         - Added (security) patch PL24 -> PL25 and 
+           added same kind (security) fixes for MIME code
+ 
+         - Version number is now formed with new style :-)
+ 
+         - elmrc -variable 'displaycharset' is propgated to
+           environment variable $MM_CHARSET when calling metamail.
+           Environment variable $MM_CHARSET overwrides default value
+           of 'displaycharset'.
+ 
+         - New elmrc -variable 'metamail'. So now you not need define
+           environment variable $NOMETAMAIL, if you want compile Elm
+           with MIME support, and you don't have metamail. Special values:
+                 none            Don't call metamail
+                 metamail        Call metamail, if environment variable
+                                 $NOMETAMAIL is not defined
+                 /path           Call tiss, if this is executable
+ 
+         - Meaning of elmrc -variable 'pagemultipart' is changed. If
+           this is FALSE (default), then call metamail if elm can't
+           handle all subpart of multipart -type or if type is other
+           than multipart/mixed, multipart/digest or multipart/report.
+           If 'pagemultipart' is TRUE, then always handle multipart type
+           without metamail (and treate unknown subtypes as multipart/mixed).
+ 
+           Decision can Elm handle that type, is done when message is 
+           displayed. So there is now 'M' -letter (= metamail needed) in
+           multipart mails until message is displayed even when Elm can
+           show it (that is because that defination is recursive and
+           requires parsing of structure of message.)
+ 
+         - Multipart/digest now works correctly when viewing attachment
+           what we have sending and we have put type for it to be 
+           Multipart/mixed.
+ 
+         - Configure now tries test if sendmail supports -B8BITMIME and
+           -BBINARYMIME (unlikely).
+ 
+         - Makefile now don't compile or install 'filter' because security
+           problems in it.
+ 
+ Changes of Elm2.4 PL24 ME8b+ compared to version Elm2.4 PL24 ME8b
+ -----------------------------------------------------------------
+ 
+         - New version of my Reply-To patch included
+           [ Old version of that patch is posted to Elm Development Cordinator ]
+ 
+         - Made MIME part 2 (RFC 1522) decoding more accoriding of RFC.
+ 
+         - Some bugfixes
+ 
+ Elm mailbox menu's status letters
+ ---------------------------------
+         - First letter:         D       Deleted
+                                 E       Expired
+                                 N       New
+                                 O       Unread
+                                 r       replied
+ 
+         - Second letter:        C       Confidental
+                                 U       Urgent
+                                 P       Private         (or ...)
+                                 A       Action
+                                 F       Form letter
+                                 e       Uses Elm's [encode] ... [clear]
+                                 P       PGP message     (or ...)
+                                 S       PGP signed message
+                                 K       PGP public key
+                                 ?       MIME message with unknown
+                                                 MIME version
+                                 M       MIME message wich requires metamail
+                                                 or isn't yet parsed
+                                 m       Pre-MIME message wich requires metamail
+ 
+ New elmrc variables for Elm 2.4ME+ (compared to Elm 2.4)
+ --------------------------------------------------------
+ 
+         askpgpsig                               PGP
+         background-wait-time                    -
+         dsn-success                             MIME / DSN
+         keeppassfor                             PGP
+         lock-in-copy                            -
+         metamail                                MIME
+         mimeforward                             MIME
+         noencoding                              MIME
+         nohdrencoding                           MIME
+         noheaderfwd                             -
+         pagealternative                         MIME
+         pagemultipart                           MIME
+         pgp                                     PGP
+         quoteforward                            -
+         require-mime-version-for-body-encoding  MIME
+         require-mime-version-for-hdr-encoding   MIME
+         showpgppreamble                         PGP
+         usepgppass                              PGP
+ 
+ Obsolete elmrc variables
+ -------------------------
+         hpkeypad                                (alias to keypad)
+         hpsoftkeys                              (alias to softkeys)
+         keypad                                  -
+         softkeys                                -
+         textencoding                            MIME
+         bounce                                  (alias to bounceback)
+         bounceback                              UUCP
+ 
+ New elm options for Elm 2.4ME+ (compared to Elm 2.4)
+ ----------------------------------------------------
+ 
+         -w                      Write .elm/elmrc on startup
+         -A                      Attach file
+ 
+ Obsolete elm options
+ --------------------
+ 
+         -k                      Enable HP 2622 terminal keyboard\n\r
+         -K                      Keypad&softkeys - enable use of softkeys + "-k"
+ 
+ Options which now takes enumerated values
+ -----------------------------------------
+ 
+         userlevel               beginner, intermediate, expert
+         noencoding              pass-7bit, pass-8bit, pass-binary
+ 
+ Warnings
+ -------- 
+ 
+         - Not compiled with MMDF or REMAILER support defined, so
+           probably they don't work (or even compile).
+ 
+         - As far I know REMAILER code have newer worked. 
+           Specially: remailers are incompatible with MIME
+ 
+         - This is not tested very much so there can be bad bugs. Bug
+           Reports to: Kari E. Hurtta <hurtta+elm@ozone.FMI.FI>
+ 
+         - Decoding of MIME is not done when searching content of mail
+ 
+         - RFC 1522: Mime part 2 support is incomplete
+ 
+         - There is not support for multipart/signed and multipart/encrypted
+           (specially: no support for PGP/MIME)
+ 
+         > But anyway, Elm will newer be MIME Conformant
+ 
+         - HP's shoftkeys are no longer supported
+ 
+         - DECNET addresses like host::user may be interpreted as phrase
+           of group syntax or as route of source routed address.
+ 
+ Collector of these patches
+ --------------------------
+ 
+         Kari E. Hurtta <hurtta+elm@ozone.FMI.FI>
Index: elm2.4.ME+.50/ANNOUNCE.ME
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/ANNOUNCE.ME	Tue Nov 17 21:12:53 1998
***************
*** 0 ****
--- 1,287 ----
+ 
+ This ANNOUNCE.ME is for ME patches of the 2.4 version.
+ 
+ Look file README.ME+ for the 2.4ME+ version.
+ 
+ --------------------------------------------------------------------
+ 
+ ELM 2.4 PL24 ME8
+ 
+ This is an announcement for Patchlevel ME8 for Elm 2.4pl24.
+ 
+ The most current version of this document is available via the web:
+ http://www.cs.hmc.edu/~me/elm/announce.html. You can also visit the "ME" home
+ page at http://www.cs.hmc.edu/~me/elm/me.html.
+ NOTE THAT THIS ADDRESS HAS CHANGED FROM THE PREVIOUS ANNOUNCEMENT!
+ 
+ What's new:
+ 
+    * Anonymous remailer support (plus chaining, PGP encryption & MIME support)
+    * mime.types file when guessing the content-type of an attachment.
+    * Forwarded messages can be attached as MESSAGE/RFC822 data
+    * Supports extraction of PGP public keys directly
+    * Support for application/pgp type inside multipart/mixed and message/rfc822
+      messages
+ 
+ Changes from ME7a:
+ 
+    * Replying to MULTIPART messages now works correctly.
+    * MESSAGE/RFC822 is now properly supported.
+    * BINARY encoding is better supported.
+    * Fixed bugs with BASE64 and QUOTED-PRINTABLE encodings.
+    * Enhanced attachment menu
+    * Improved interface for PGP encrypting messages
+ 
+ Where to get it:
+ 
+    * ftp://cs.hmc.edu/pub/me/elm-2.4pl24me8.tar.Z
+    * ftp://cs.hmc.edu/pub/me/elm-2.4pl24me8.tar.gz
+    * ftp://cs.hmc.edu/pub/me/elm-2.4pl24me8.diffs.Z
+    * ftp://cs.hmc.edu/pub/me/elm-2.4pl24me7a-8.diffs.Z
+ 
+ -OR-
+ 
+    * ftp://uiarchive.cso.uiuc.edu/pub/packages/mail/elm/me/elm-2.4pl24me8.tar.Z
+    * ftp://uiarchive.cso.uiuc.edu/pub/packages/mail/elm/me/elm-2.4pl24me8.tar.gz
+    * ftp://uiarchive.cso.uiuc.edu/pub/packages/mail/elm/me/elm-2.4pl24me8.diffs.Z
+    * ftp://uiarchive.cso.uiuc.edu/pub/packages/mail/elm/me/elm-2.4pl24me7a-8.diffs.Z
+ 
+ -------------------------------------------------------------------------------
+ 
+ STATUS
+ 
+ These patches are not an official release of Elm, and are not supported by the
+ Elm Development Group. Features included in this patch may or may not be
+ included in the next official release of Elm. I can say for certain that the
+ PGP portion will not. I am hoping that my MIME patches will be included in the
+ 2.5 release, but that is still an open question. Should the 2.5 release appear
+ without these patches, I plan on "porting" them and using 2.5 as the base.
+ -------------------------------------------------------------------------------
+ And now on to the interesting stuff...
+ 
+ PGP SUPPORT
+ 
+ [This work was inspired by pgpelm which was started by Mic the Missing and
+ furthur developed by Ken Cox (kenc@viewlogic.com). This version is a complete
+ rewrite of that system but looks very similar.]
+ 
+ Features include: mark on folder menu showing PGP encrypted messages and public
+ key blocks, encryption/signing of outgoing messages, decrypting/signature
+ check, mailing public key blocks, and extracting public key blocks from
+ messages. Special feature allows you to have ELM keep track of your PGP
+ passphrase so you only need to enter it a minimal number of times.
+ 
+ I have written a primer for using PGP with this version of ELM which can be
+ found at http://www.cs.hmc.edu/~me/elm/pgp.html. It contains everything you
+ need to know about how to use PGP with ELM.
+ 
+ MIME SUPPORT
+ 
+ With this version of Elm, the need for metamail is much less since it can now
+ handle the MIME encodings and multipart/* messages internally. The only case in
+ which metamail is called is when there is a content-type which Elm does not
+ understand (eg. image/*, audio/*). In most cases you will probably only receive
+ this as attachments anyway, so you might still not require metamail.
+ 
+    * Incoming Attachments
+ 
+      Access to individual portions of a MIME mulitpart message can be accessed
+      via the "Attachments" menu (type 'v' in the index menu). This brings up a
+      menu listing the attachments for the current message. You then have the
+      option of viewing or saving the attachment.
+ 
+    * Outgoing Attachments
+ 
+      In addition to using the "[include ..." construct when editing your
+      message, there is now an "Attachments" menu accesible from the "Send" menu
+      (it is abbreviated to "a)tt" because of space problems). Simply type "a"
+      to get into the Attachments menu. You may then add/delete/edit/modify
+      attachments. When possible, Elm will attempt to guess the correct
+      Content-Type (based on file extension, see the "mime.types" section below)
+      and Content-Transfer-Encoding.
+ 
+    * Automatic encoding for outgoing messages.
+ 
+      If Elm finds 8bit or control characters in text files to be attached, it
+      will automatically encode them QUOTED-PRINTABLE if Elm has been compiled
+      without the 8BITMIME option (meaning that your MTA isn't 8bit clean). This
+      behavior can be overriden with the "noencoding" elmrc option (see below)
+      in cases where your sendmail is 8bit clean, but doesn't support the
+      -B8BITMIME option.
+ 
+    * mime.types file
+ 
+      Elm now mime.types file which maps filename extensions to Content-Type
+      field when sending attachments via the new attachment menu. The format of
+      these files is as follows:
+ 
+      <extension> <content-type>
+ 
+      A hash character ('#') may be used as a comment, but it must be in the
+      first column of a line.
+ 
+      Here is an example of mime.types file:
+ 
+      # This is a commented line
+      html    text/html
+      tgz     application/octet-stream; type=tar; conversions="x-gzip"
+ 
+      Note that the content-type field is not limited to just the type/subtype
+      part; in can also include suplementary information.
+ 
+      Elm first looks to see if the user has a ~/.elm/mime.types file. If there
+      is no match, Elm will then try to read the system types file (typically
+      /usr/local/lib/elm.mimetypes). Failing that, Elm has a few builtin types
+      that it understands.
+ 
+      You might want to pick up a copy of my mime.types file as a starting point
+      for either your personal or system file at
+      http://www.cs.hmc.edu/~me/elm/mime.types.
+ 
+ REMAILER SUPPORT
+ 
+ This version of Elm has the ability to prepare messages for use with anonymous
+ remailers (if you don't know what that is, read alt.privacy.anon-server for
+ more information).
+ 
+ Elm gets its information about anonymous servers by either fingering
+ "remailer-list@kiwi.cs.berkeley.edu" or by reading ~/.elm/remailers (if this
+ file exists, it overrides the "finger" so you can still use this feature even
+ if you are not directly net connected.)
+ 
+ To send an anonymous message, first compose your message as you normally would,
+ entering the name of the person who should ultimately receive the message as
+ the To: address. Then, at the "send" menu, you can type "r" to get into the
+ "remailer" menu.
+ 
+ There are several options in this menu: remail, chain, path and encrypt.
+ The "remail" option indicates whether or not the current message will be
+ remailed.
+ 
+ "chain" indicates how many servers this message should be sent through (the
+ higher chain is, the more secure, but the tradeoff is how long until the
+ receiver gets the message).
+ 
+ "path" is where you can specify which servers you would like this message to go
+ through (this overrides "chain"). You can specify a semi-colon (";") separated
+ list of server "nicknames" here.
+ 
+ "encrypt" means that Elm should encrypt your messages with the PGP public key
+ of server you are remailing through (note that if chain > 1 or there is more
+ that one server in "path", Elm will do the "right" thing and call PGP multiple
+ times for each hop).
+ 
+ Once the desired options are set, you can quit the menu and send the message.
+ What you see next will vary... If you are a PGP user and set encrypt=TRUE in
+ the remailer menu, you will see the call(s) to pgp flash across your screen.
+ Otherwise you will most likely just see the "Mail sent." message.
+ 
+ If you have MIME defined, it should be possible for you to include attachments
+ in your anonymous mail in the normal manner. Most servers these days support
+ the "hash" option which Elm makes use of to pass the proper MIME headers.
+ 
+ NEW ELMRC OPTIONS
+ 
+    * usepgppass = [ ON | OFF ]
+      Default: usepgppass = OFF
+         o OFF: Elm does not keep your passphrase in memory. You must enter it
+           each time you want to decrypt a pgp mail.
+         o ON: Elm keep your passphrase in memory for "keeppassfor" seconds.
+    * keeppassfor = <number>
+      Default: keeppassfor = 0
+         o keeppassfor>=0: Elm will keep your passphrase in memory for seconds
+           after entering the passphrase.
+         o keeppassfor<0: Elm will keep your passphrase in memory without
+           clearing it from memory.
+    * noencoding = <level>
+      Default: noencoding = 0
+ 
+      This control makes it possible to send raw 8bit or binary data when the
+      MTA doesn't support 8BITMIME and the -B8BITMIME option or BINARYMIME and
+      the -BBINARYMIME option.
+ 
+      Possible values:
+         o  0 : Always convert 8BIT and BINARY data to QUOTED-PRINTABLE if the
+           MTA doesn't support the -B8BITMIME and -BBINARYMIME options.
+         o  1 : Allow 8bit without -B8BITMIME, but binary data is encoded
+         o  2+: Allow binary without -BBINARYMIME and and 8bit without
+           -B8BITMIME
+      It is STRONGLY recommended that it be left set to 0 unless you know what
+      you are doing!!
+    * showto = [ ON | OFF ]
+      Default: showto = OFF
+         o ON: Elm should show you who the message is addressed to rather than
+           who it is from if the message is not addressed to you.
+         o OFF: normal behavior
+    * pagemultipart = [ ON | OFF ]
+      Default: pagemultipart = ON
+         o ON: Use the internal MIME support to display MULTIPART messages
+           rather than calling metamail
+         o OFF: display MULTIPART messages with metamail
+    * mimeforward = [ ON | OFF ]
+      Default: mimeforward = OFF
+         o ON: When forwarding a message, Elm will attach as a MIME body part of
+           type MESSAGE/RFC822.
+         o OFF: Elm will include the forwarded message in your message, just
+           like it always has.
+ 
+ BUILTIN++ PAGER
+ 
+ This pager looks a lot like more, but has some of the movement features of
+ less, most notably, paging backwards through your messages. Press '?' inside of
+ the pager for a list of valid keystroke commands.
+ 
+ TAGS
+ 
+ Use the keyword "tagged" in the "Delete messages with pattern" (invoked by ^D
+ in the index menu) to delete all tagged messages.
+ 
+ You can now use the keyword "all" to tag all visible messages.
+ 
+ LIMIT FUNCTIONALITY
+ 
+    * Simple compound statements can be made using '|' (OR) and '&' (AND).
+    * The "Cc:" field is now availible for search.
+    * New keyword "tagged" for narrowing to only the currently tagged messages.
+ 
+ MISCELLANEOUS
+ 
+ '*' may be used as a wildcard in the "alternatives" list in the elmrc file. For
+ instance, "me@*.hmc.edu" would me to match the user "me" in all hosts from the
+ "hmc.edu" domain.
+ 
+ Elm will keep track of the messages which you have replied to with an 'r' mark
+ in the index menu.
+ 
+ Forwarded messages are encapsulated instead of quoted like replies:
+ 
+         ----- Forwarded message from Joe User  -----
+         [...]
+         ----- End of forwarded message from Joe User  -----
+ 
+ You can effect an automatic Bcc: line by setting the address(es) in the "BCC"
+ environment variable. Note that this is non-standard, but provided as a means
+ of accomplishing the task.
+ 
+ BUGS
+ 
+ A list of known bugs can be found at
+ http://www.cs.hmc.edu/~elkins/elm/bugs.html.
+ 
+ AUTHOR
+ 
+ Michael Elkins <elkins@aero.org>
+ Home Page: http://www.cs.hmc.edu/~me/index.html
+ 
+ If you are interested in knowing what my future plans are, you can browse my
+ "TO DO" list at http://www.cs.hmc.edu/~me/elm/todo.html
+ 
+ THANKS
+ 
+ Kari Hurrta <Kari.Hurtta@fmi.fi> has contributed a great deal to the MIME
+ support (and fixed lots of my stupid bugs ;-)
+ 
+ I would also like to thank everyone who took the time to report bugs or suggest
+ improvements!
+ -------------------------------------------------------------------------------
+ Last updated Sept 21, 1995.
Index: elm2.4.ME+.50/ChangeLog.ME
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/ChangeLog.ME	Tue Nov 17 21:12:53 1998
***************
*** 0 ****
--- 1,812 ----
+ 
+ This ChangeLog.ME is for ME patches of the 2.4 version.
+ 
+ Look file README.ME+ for changes of the 2.4ME+ version.
+ 
+ -------------------------------------------------------------------------
+ 
+ -----------------
+ Changes from ME8a
+ -----------------
+ When checking to see if the subject line should be centered when displaying
+ a mail message, the weedlist check should be for "subject:", not "subject".
+ This case is more general.
+ 
+ control-F in the main menu now causes Elm to forget your passphrase.  Useful
+ for when you screw up so you don't have to exit Elm before using PGP
+ again.
+ 
+ Added a "metoo" argument in pgp_encrypt to decide whether or not the
+ +encrypttoself=on flag should be passed to pgp.  This was needed so that
+ the value of auto_cc can be overidden when remailing.
+ 
+ Added support for decoding of RFC1522 style encoded headers.  This should
+ work in the index menu, the pager, and when replying (the "attribution").
+ 
+ metapager will now recover if pgp fails by displaying the message "as is"
+ in the case where the message is only signed.
+ 
+ Simplified "pager" check in metapager since there are two pagers now.
+ 
+ Fixed problem in copy_message where the rfc822 newline at the end of the
+ headers was missing.
+ 
+ Fixed bug in menu2.c:generic_menu (used by the remailer) which caused
+ Elm to segfault when not compiled with gcc.
+ From: Andrey A. Chernov <ache@astral.msk.su>
+ 
+ Fixed problem where trailing MMDF separator was still being printed.
+ 
+ The default filename for the Content-Disposition header was not getting
+ set if the included file did not have an extension.
+ 
+ text/plain => application/pgp conversion is now NOT done for public key
+ blocks.
+ 
+ Configure now figures out where "finger" is instead of hardcoding a path
+ in remailer.c
+ 
+ Hopefully fixed definition for sleep() in defs.h.
+ 
+ Fixed bug where elm would segfault when typing ^E when there are no messages
+ in the mailbox.
+ 
+ Fixed bug where a leading space could be inserted before the real name when
+ looking up a PGP public key from the return address.
+ 
+ Fixed some of the movement commands in builtin++ so that they work now.
+ 
+ Convert application/x-pgp-* => application/pgp to decode messages generated
+ by pgpelm.
+ 
+ Fixed problem where if the signature was added after editing the message,
+ it would be written over the message right after the content length.  Fixed
+ by seeking to the end of the file after writing the content length field.
+ 
+ ----------------
+ Changes from ME8
+ ----------------
+ Fixed bug in conversion of text/plain => application/pgp in newmbox.c which
+ was causing Elm to segfault. (Thanks to Kari.Hurtta@fmi.fi)
+ 
+ Fixed bug where builtin++ segfaults when viewing zero length messages.
+ 
+ -----------------------
+ Changes from ME8alpha19
+ -----------------------
+ Fixed bug where external pager did not work with non-MIME messages when
+ USE_PGP is defined.
+ 
+ Cleaned up mime_pgp_decode so that it does not need to look at the
+ header_rec for the current message any longer.
+ 
+ Do text/plain => application/pgp conversion in newmbox.c if PGP type data
+ is discovered in the message.  This supports those who are sending PGP
+ messages but are not compliant with what Elm expects.
+ 
+ Added the control-E (extract public key) command to showmsg_c.c.
+ 
+ Security fix from Olaf Kirch <okir@monad.swb.de> which forces Elm to write
+ the temp spool mailbox in the user's home directory instead of /tmp.  This
+ prevents exploitation of symlinks to create a .rhosts in the user's 
+ directory.
+ 
+ Fixed bug in show_status where flags from the previous message were not
+ being properly cleared with USE_PGP was defined and MIME was not.
+ 
+ -----------------------
+ Changes from ME8alpha18
+ -----------------------
+ added application_decode for support of APPLICATION/* types.  Calls
+ null_decode if the subtype is unknown.
+ 
+ rfc822_decode now matches the headers against the weedlist when printing
+ out.  You can view all the headers for a message by pressing 'h' while
+ viewing a message just as you normally would.
+ 
+ added mime_pgp_decode for inline decoding of application/pgp parts.
+ application/pgp at the top level is still handled by metapager since some
+ people will be configured without MIME.  I might eventually require that
+ to use PGP, you must also define MIME, but not yet!
+ 
+ Status header was printed in the wrong place with BINARY encoding.
+ From: Kari.Hurtta@fmi.fi
+ 
+ Added the DONT_ADD_FROM and NEEDS_LONE_PERIOD_ESCAPE checks to write_encoded,
+ and other MIME text parts.
+ From: Kari.Hurtta@fmi.fi
+ 
+ Added a "type_opts" field in mime_send_t.
+ 
+ mime_write_header now just writes the MIME headers.  The code to add the
+ boundary for multipart messages and the charset for text/plain was moved into
+ mailmsg2.c.
+ 
+ Changed pgp code to set MIME fields to use add_parameter and type_opts instead
+ of directly writing to subtype.
+ 
+ Made some changes in the Content-Type for PGP messages to be more compliant
+ with the unofficial standard.
+ 
+ -----------------------
+ Changes from ME8alpha17
+ -----------------------
+ MIME header code in write_header_info() was moved to 
+ mime_write_header in mime_encode.c.  This was done to greatly simplify the
+ code, and to make it possible for me to send MIME messages with the
+ remailer code.  This will also make it possible for me to have PGP
+ encrypted MIME messages in the future.
+ 
+ Content-Length headers are generated regardless of whether or not MIME
+ is defined.
+ 
+ Lots of changes to the remailer code to make it work with MIME.
+ 
+ -----------------------
+ Changes from ME8alpha16
+ -----------------------
+ Removed Content-Length header from attachments included by the "[include ...]"
+ statement.
+ 
+ Made the existing global variables that set the toplevel Content-Length header
+ a part of mime_send_t.  This has the side effect that if MIME is not
+ defined, no Content-Length header will be added on outgoing messages.
+ 
+ Commented out the code which reads the content-length header from attachments
+ in mime_parse.c.  It should now ignore that header and figure out the length
+ in multipart_parse().
+ 
+ -----------------------
+ Changes from ME8alpha15
+ -----------------------
+ New option "mimeforward" controls whether or not forwarded messages are
+ sent as MESSAGE/RFC822 MIME messages, or are sent in the old non-MIME
+ way.
+ 
+ - Fixes for my mistakes in alpha15.
+ - text_unsupported_decode() added for printing warning message about
+ unsupported text subtypes.
+ From: Kari.Hurtta@fmi.fi
+ 
+ Changed disposition handing such that a message saying that the user should
+ type 'v' to view an attachment which is declared something other than
+ "inline".
+ 
+ -----------------------
+ Changes from ME8alpha14
+ -----------------------
+ Make sure that arguments to fseek(), etc., are type long.
+ From: Kari.Hurtta@fmi.fi
+ 
+ Added some general access commands for attachments in the attach_menu.c
+ routines.
+ From: Kari.Hurtta@fmi.fi
+ 
+ The disposition is now displayed in the little mini-header.  This looks nicer
+ than the previous message about "[Content-Disposition: attachment, skipping]".
+ 
+ select_CT_decoder now returns text_decode for all TEXT types.  My reasoning
+ here is that since the MIME spec says that all unknown subtypes of TEXT
+ should be treated as TEXT/PLAIN so long as the charset is understood, then
+ all TEXT can be treated in this manner.
+ 
+ Made sure that the pgp field of header_rec gets set to zero when initializing
+ in attach_viewer and also in newmbox.c.
+ 
+ Removed lots of unused variables.
+ 
+ Added some parentheses in places to make "gcc -Wparentheses" happy.
+ 
+ -----------------------
+ Changes from ME8alpha13
+ -----------------------
+ Forgot to initialize usepass=FALSE in pgp_decrypt_init.  This caused elm
+ to hang when trying to decode a signed message while pgp was waiting for
+ the passphrase...
+ 
+ The attachment menu should now work properly for viewing message/rfc822
+ messages with the builtin pager.
+ 
+ When attaching a message/rfc822 with the "forward" command, you should
+ now be able to perform all the actions in attach_menu() as for a "normal"
+ attachment.
+ 
+ -----------------------
+ Changes from ME8alpha12
+ -----------------------
+ Tried to fix MIME_NOTPLAIN code again.  This time MESSAGE/RFC822 will not
+ have it set, which MULTIPART will if pagemultipart=OFF.
+ 
+ Fixed attach_menu so that Elm does not segfault when you try to do an
+ operation on an attachment when there are no attachments defined.
+ 
+ Removed the MIME_NOTPLAIN flag and made it a one-bit flag in mime_t instead.
+ Removed PGP flags from defs.h and use a 3-bit field in header_rec instead.
+ These two now ensure that the "status" field of header_rec is always less
+ than 65536 so that 16bit integer machines will not have troubles.
+ 
+ Elm now pays attention to what the MIME-Version header says and passes any
+ messages with an unknown MIME-Version header value to metamail, or displays
+ an error if $NOMETAMAIL is set.
+ From: Kari.Hurtta@fmi.fi
+ 
+ -----------------------
+ Changes from ME8alpha11
+ -----------------------
+ pgp_call() now uses the expanded_* address lists so that aliases are 
+ expanded before trying to look up the ids with PGP.
+ 
+ Fixed calls in mailmsg2.c with wrong number of arguments (botched job
+ including Kari Hurtta's patch).
+ From: Kari.Hurtta@fmi.fi
+ 
+ Reordered the preMIME code in newmbox.c to make it a little more efficient.
+ 
+ Fixed bug in write_header_info() where a spurious newline was being printed
+ after the Content-Type header for TEXT.  This was causing the remaining 
+ fields not to be a part of the message header.
+ 
+ Removed check for old-style RFCXXX Mime-Version header.  I don't believe
+ anybody uses that anymore since RFC1341 has been out so long.
+ 
+ pgp_status needed to be reset when the user aborts sending a message,
+ otherwise you can't encrypt another message until you successfully send
+ another message.
+ 
+ MIME_NOTPLAIN is not set for multipart messages if "pagemultipart" is TRUE.
+ 
+ Cleaned up code for deciding if metamail mail should be called to display
+ a message in showmsg.c.  Created a need routine, need_meta(), for this
+ purpose.
+ 
+ -----------------------
+ Changes from ME8alpha10
+ -----------------------
+ Fixes to remove some global MIME variables used for composing.
+ From: Kari.Hurtta@fmi.fi
+ 
+ Added a redraw command to the attachment menu.
+ 
+ Fixed the code in newmbox.c where MIME_NOTPLAIN was not set for non-TEXT
+ content-types.  Also, check for "plain" should be "text" for old-style
+ pre-MIME content-type headers.
+ 
+ Added a print command to the attachment menu.
+ 
+ Made the remailer support a Configure option.
+ 
+ ----------------------
+ Changes from ME8alpha9
+ ----------------------
+ Use Elm's error routines in the attachment menu. 
+ Protected iscntrl() more calling isascii() before it in builtin++.
+ From: Kari Hurtta <Kari.Hurtta@fmi.fi>
+ 
+ Added bit of code lost from old showmsg.c which centers the subject line 
+ after the title line in the case where "subject" is in the weedlist.
+ 
+ Viewing attachments with metamail while in send mode now works.  It required
+ different arguments to be passed to metamail.
+ 
+ -----------------------
+ Changes from ME8alpha8a
+ -----------------------
+ mime_t_clear() now sets the defaults of TEXT/PLAIN, ENCODING_7BIT, DISP_INLINE,
+ when called.
+ 
+ More fixes from Kari Hurtta <kari.hurtta@fmi.fi>
+ 
+ Removed padding bitfield from struct mimeinfo since it isn't needed.
+ 
+ Added +clearsig=ON when adding a PGP signature to a message.
+ 
+ Added prototypes for the functions defined in pgp.c.
+ 
+ Elm will now allow you to edit the list of usernames to encrypt to when
+ using PGP.  This fixes the problem where sometimes the return address
+ doesn't match the address on the key.  However, it still requires that
+ the user know this.
+ 
+ Implemented Kari Hurtta's suggestion of using a "state" variable for the
+ MIME output when decoding messages.  This will make it easier to add new
+ extensions for output.  The state information is defined in hdrs/state.h
+ 
+ The user interface for the attachment menu now is more consistent with
+ the mailbox menu.  (Kari.Hurtta@fmi.fi)
+ 
+ User is now asked for confirmation upon deleting an attachment from the
+ attachment menu if "ask=ON" in the elmrc.
+ 
+ Fixed replying to messages with PGP signatures.  They were getting sucked
+ into the new MIME code and getting skipped as an unknown type.
+ 
+ Added new procedure to allow for extraction of PGP public keys directly
+ instead of relying on metamail.
+ 
+ If Elm can't find a PGP key that it is looking for, it now tells the user
+ which key instead of just that there was an error.
+ 
+ The user is now allowed to re-edit the filename in attach_modify() if the
+ file was not found.  This also allows a user to change the file associated
+ with an attachment.
+ 
+ Fixed very old bug of MMDF separators being printed when displaying a
+ message.
+ 
+ ----------------------
+ Changes from ME8alpha8
+ ----------------------
+ Fixed problem where you couldn't edit the default filename in attach_save().
+ 
+ ----------------------
+ Changes from ME8alpha7
+ ----------------------
+ Use safe_malloc() and safe_realloc() instead. (Kari Hurtta)
+ 
+ Fixed bug where no EOLN token was printed after the Content-Type header
+ when type_opts was NULL in attach_generate_message().
+ 
+ Reorganized struct mimeinfo so that bitfields are next to each other and
+ added padding to make them 1 byte long total.
+ 
+ -----------------------
+ Changes from ME8alpha6+
+ -----------------------
+ Reduced memory usage in "struct mimeinfo" by using bitfields or pointers
+ instead of predefined strings when possible.  Also removed the "comments"
+ fields.
+ 
+ New routine lib/strmcpy.c for doing malloc/realloc and strcpy in one shot.
+ Helps out with the above objective.
+ 
+ The attachment menu now defaults to disposition "inline" when sending
+ mail.
+ 
+ Reorganized the screen in the attachment "configuration" menu.
+ 
+ Removed code for adding "name=" field to APPLICATION/OCTET-STREAM types.
+ Uses Kari's code for Content-Disposition "filename" instead.  attach_menu()
+ still supports both for getting default filename when saving an
+ attachment.
+ 
+ Removed MIME_MULTIPART flag.  Use MIME_TYPE_MULTIPART with "type" instead.
+ 
+ Removed "encoding" field from "header_rec".  Use "encoding" in "mimeinfo"
+ instead (this was already mostly true, but there were a few cases left
+ over from the early support for encoding...)
+ 
+ ----------------------
+ Changes from ME8alpha6
+ ----------------------
+ Incorporated changes from Kari Hurtta <Kari.Hurtta@FMI.FI>.
+ Big changes are the use of Content-Disposition and routines to better parse
+ rfc822 headers.  Also fixed multi-line MIME header problem in newmbox.c
+ 
+ ----------------------
+ Changes from ME8alpha5
+ ----------------------
+ Fixed places where "/tmp" was hardcoded for temporary files instead of using
+ "temp_dir" in the ME extensions.
+ 
+ Fixed more isspace() problems with "signed char".
+ 
+ Made some formatting improvements in multipart_decode().
+ 
+ Fixed bug where multi-line Content-Type headers were not properly parsed in
+ newmbox.c.
+ 
+ Added builtin++2.c which contains a tempfile based pager which may become
+ part of the "official" distribution.  For right now it is "experimental".
+ 
+ ----------------------
+ Changes from ME8alpha4
+ ----------------------
+ Fixed attach_modify() to use ->type and ->subtype like the rest of the
+ attachment routines.
+ 
+ Viewing an attachment while sending didn't work because it read from
+ mailfile...  Now it can view external files as well.
+ 
+ Fixed problem with signed char and iscntrl() in AddLineToCache().
+ This fixes the problem with umlaut characters in some sets.
+ From: guy@netapp.com.
+ 
+ Modified mime_generate_boundary() to use mime_count as a counter so that
+ subsequent calls will generate different values.
+ 
+ Elm will now read ~/.elm/mime.types and $libdir/elm.mimetypes (system
+ mime.types file), if they exist, to map filename extensions to
+ Content-Type values when sending attachments.  The format of this file
+ is:
+ 	<suffix> <content-type>
+ There must be no line breaks in the Content-Type field.
+ Example:
+ 	tar	application/octet-stream; type=tar
+ for .tar files.
+ NOTE: data which is declared "application/octet-stream" will automatically
+       get the option "name=<default_filename>" added to it, so there is no
+       need to put it in the definition.
+ 
+ Modified attach_info() so that it uses BASE64 encoding for "application"
+ types that have 8bit or control chars in them.
+ Also, "image" automatically defaults to BASE64 without reading the file.
+ 
+ attach_save() now uses the "name=<default_filename>" field of "application"
+ types as the default filename.
+ 
+ Added '+' as a synonym for NEXT_PAGE in builtin++ per popular request.
+ 
+ attach_generate_msg() no longer puts Content-Length headers on parts that
+ it generates.
+ 
+ ----------------------
+ Changes from ME8alpha3
+ ----------------------
+ Added support for multi-line Content-Type: headers in read_headers() and
+ mime_read_headers().
+ 
+ me.h now contains prototypes for functions defined by this set of patches.
+ 
+ Fixed some problems with using PGP and remailers.
+ 
+ Fixed parsing of options in the Content-Type header so that semicolons
+ inside quotes are protected.
+ 
+ If MIME is defined, forwarded messages will be an attachment of type
+ MESSAGE/RFC822.
+ 
+ Fixed problem with viewing MULTIPART or MESSAGE/RFC822 attachments from
+ the attachment menu.
+ 
+ Replaced MIME_BOUNDARY with a function (mime_generate_boundary()) that
+ sets the global variable "mime_boundary" to generate unique multipart
+ boundaries.  This is important now that Elm will be sending out
+ MESSAGE/RFC822 data which Elm might have originally generated...
+ 
+ ----------------------
+ Changes from ME8alpha2
+ ----------------------
+ Added a second line for menu items in verify_transmission() since adding
+ the "r)emailer" option didn't fit on the first line.
+ 
+ Modified the PGP code a little for more flexibility.  You can now specify
+ a string of "ids" to encrypt with in pgp_call().
+ 
+ ---------------------
+ Changes from ME8alpha
+ ---------------------
+ The menus from attach.c and attach_send.c were combined into a single
+ menu in attach_menu.c which servers both purposes.  The difference is
+ whether or not the user is allowed to modify the given attachments.
+ 
+ The rest of attach_send.c was renamed as mime_encode.c.
+ 
+ -----------------
+ Changes from ME7a
+ -----------------
+ 
+ Added a check in quoted_printable_decode() to make sure that the index
+ into outbuf[] does not run off the end and cause problems.
+ 
+ attach_edit() didn't return TRUE after editing in one spot, which causes
+ problems on some platforms, namely Solaris.
+ From: Martin Walter <mawa@ruf.uni-freiburg.de>
+ 
+ base64_decode() was broken because it would fread() a data chunk, and 
+ wasn't always a multiple of 4 bytes, causing the decoding to break.
+ 
+ Changed char => unsigned char in most places in *_encode() to fix problems
+ with ISO characters >127.
+ 
+ Added message about PGP support for the 'elm -v' command in args.c.
+ 
+ Support for anonymous remailers. [ALPHA]
+ 
+ Major rewrite of the MIME handling code.  MULTIPART and MESSAGE/RFC822
+ messages are parsed the first time they are accessed (eg. viewed/replied)
+ and then are ready to use without parsing after that.  See mime_parse.c
+ and mime_decode.c for details.
+ 
+ From: Kari Hurtta <Kari.Hurtta@fmi.fi>
+   Put a loop around verify_transmission() so that Elm will no longer just
+   be lame when an error occurs in [include ...] statements.  (Way cool! -Ed)
+ 
+   Don't allow user read or writes files as attachmentds which he don't heve 
+   access. Notice that elm is (usually) setgid mail.
+ 
+   Consider if MTA supports 8BITMIME also when encoding attachments.
+ 
+   Now mail is encoded with quoted-printable if it includes control characters.
+   8BITMIME doesn't help in this case.
+ 
+   Attachments are checked for 8bit characters, then content-transfer-encoding
+   7bit is not allowed.
+ 
+   If any of subpart (also attachments) have content-tarnsfer-encoding 8bit
+   or binary it propagates to content-transfer-encoding of top multipart -type.
+ 
+   Now taken note of MIME's canonical encoding model:
+   - End of line in text -subtypes when they have encoded with BASE64
+     must be encoded as CR LF.
+   - Also CR and LF must be encoded in quoted-printable-encoding if
+     type have binary data (ie. not line oriented).
+   - Done mapping CR LF -> LF when decoding text -subtypes.
+ 
+   These content-transfer-encoding checks for attachments are also done
+   for [include ...] keywords when sending.
+ 
+   Now [include ...] also don't need metamail's help (they use same routines
+   than attachments menu).
+ 
+   Added configuration file option 'noencoding' (see elmrc-info for details
+   on what this does).
+ 
+ ----------------
+ Changes from ME7
+ ----------------
+ 
+ Forgot to kill the newline from the PGP output before putting it in to the
+ builtin++ pager.  This resulted in messages being displayed double-spaced.
+ Ick!
+ 
+ ----------------
+ Changes from ME6
+ ----------------
+ 
+ attach_send.c needs <sys/stat.h> on some machines.
+ 
+ Fixed initialization of arrays in attach_send.c because CC isn't quite
+ ANSI compliant.  You can only initialize static arrays.
+ From: Guy Harris <guy@netapp.com>
+ 
+ Added support for sendmail 8.7 which has support for 8BIT content 
+ encoding.  Uses the -B8BITMIME option.
+ From: Kari Hurtta <hurtta@dionysos.fmi.fi>
+ 
+ Fixed problem where QUOTED-PRINTABLE messages were not decoded when
+ replying if USE_PGP was not defined.
+ From: Kari Hurtta <hurtta@dionysos.fmi.fi>
+ 
+ [keyword ...] constructs are no longer broken when using MIME and the
+ message is to be encoded QUOTED-PRINTABLE.
+ From: Kari Hurtta <hurtta@dionysos.fmi.fi>
+ 
+ Made the QUOTED-PRINTABLE encoding routine more compliant with the
+ standard.
+ From: Kari Hurtta <hurtta@dionysos.fmi.fi>
+ 
+ Added patch to mark messages NEW in all folders (not just the SPOOL)
+ if there is no status: line.
+ NOTE: This will probably go away when 2.5 is released.  Instead, they
+ will use some sort of "magic" flag to accomplish the same thing.
+ 
+ Added check to make sure that we don't run off the end of outbuf[] in
+ base64_decode() in mime.c.
+ From: Kurt.Jaeger@rus.uni-stuttgart.de
+ 
+ Fixed type casting problem with BSD 4.4 derivatives in mime.c.
+ From: Andrey A. Chernov <ache@astral.msk.su>
+ 
+ KOI8-R added as a valid compat charset.
+ From: Andrey A. Chernov <ache@astral.msk.su>
+ 
+ builtin++ now wraps the line at the number of columns on the screen, not
+ one character before.  NewLine() apparently "does the right thing" and
+ doesn't print an extra line if the last character is in the last column.
+ From: Kari Hurtta <Kari.Hurtta@fmi.fi>
+ 
+ The arrow keys now do what they did before instead of controlling the
+ bultin++ pager.
+ 
+ builtin++ always clears the screen before displaying the next (or
+ previous) page.
+ 
+ The length of a line in the cache for builtin++ is increased to 150
+ chars because the old value of 128 didn't work with hpterms with a 
+ width of 134 chars.
+ 
+ Fixed problem where Elm would SIGBUS if you tried to use the
+ attachments menu in an empty folder.
+ From: Kari Hurtta <Kari.Hurtta@fmi.fi>
+ 
+ buf[STRING] was too short in AttachmentMenu() and caused certain Elm to
+ bomb out on certain messages which had header lines which were too
+ long.
+ 
+ AddLineToCache() can now handle multiline input.  This meant that
+ calls to it from metapager had to remove the trailing newlines.
+ 
+ Changed the MIME mini-header format in metapager().
+ 
+ attach_edit() looks more like header_edit() now.  Makes the interface
+ more consistent.
+ 
+ lib/getrealname.c needed <ctype.h> on older BSD systems.
+ 
+ Fixed nasty bug where the blank line in between the headers and the body
+ of a NEW message would get deleted when resync'ing in the spool folder.
+ 
+ Fixed infinite loop in Configure when run with the -d option.
+ 
+ ----------------
+ Changes from ME5
+ ----------------
+ 
+ Added the DoAll() call so that the keyword "all" can be used when tagging
+ or deleting.
+ 
+ Decoupled PGP and MIME support such that you don't need MIME to use PGP.
+ 
+ Added lots of error checking code in metapager.c.
+ From: guy@netapp.com (Guy Harris).
+ 
+ Fixed bug in quoted_printable_decode() where I did not convert read
+ characters to base16.
+ 
+ Added hex() function to protect index_hex from bad values.
+ 
+ metapager() prompts for a command if necessary after running the external
+ pager, just as Elm used to do.
+ 
+ Fixed the From: line in write_header_info() where I broke it before.
+ 
+ Fixed bug where the MIME multipart boundary would be written after the
+ MMDF separator when copy=ON and the message was being copied to the user's
+ desired folder.
+ 
+ Added an "Attachments" menu in verify_transmission() for including 
+ attachments.  This works in addition to the current method of using
+ "[include ..."
+ 
+ Elm now directly supports writing of BASE64 and QUOTED-PRINTABLE
+ encodings.
+ 
+ Changed the return value of match_address() to be zero, since it
+ returns an int, and NULL is not always an int.
+ From: Michael Shields <shields@tembel.org>
+ 
+ AttachViewer() now uses notplain() to determine whether or not
+ metamail is needed to view the message.
+ From: Guy Harris <guy@netapp.com>
+ 
+ needs_mmdecode() now takes the integer version of the encoding rather
+ than a string.  This avoids parsing the string twice.
+ From: Guy Harris <guy@netapp.com>
+ 
+ Elm now checks outgoing messages to see if there are any non-printable
+ characters, and if so encodes the message QUOTED-PRINTABLE.
+ 
+ Cleaned up PGP code by moving more code to pgp.c so that other files
+ require less modification (ie. the diffs will be simpler).
+ 
+ Fixed showmsg.c so that it passes anything that doesn't require metamail
+ to the metapager.  This fixed the problem where messages with no
+ Mime-Version header but had a Content-Type header wouldn't get displayed.
+ From: Guy Harris <guy@netapp.com>
+ 
+ Fixed bug in dispaddr.c so that if a message is from the user, it will
+ always use the TO address to display.
+ 
+ Moved get_real_name() to its own file in lib so it can be used by
+ dispaddr.c.
+ 
+ Modified get_real_name() so that if it sees an address like
+ "<elkins@aero.org>" it will return "elkins@aero.org" instead of a zero
+ length string.
+ 
+ ----------------
+ Changes from ME4
+ ----------------
+ 
+ Introduced the "metapager".  It replaces most of the code in showmsg.c.
+ It also takes care of all the MIME and PGP functions the bultin++ pager
+ used to perform, so that the user doesn't have to use builtin++ in those
+ cases.
+ 
+ PGP decrypting function was rewritten using pipes so no temp files are
+ required!
+ 
+ The attachment handling code was modified to handle multiline content-type
+ headers generate by such mailers as zmailer.  It also looks through each
+ modifier in the line intead of just assuming that the boundary field will
+ be the first.
+ From: guy@netapp.com (Guy Harris)
+ 
+ The "command" status line in the builtin++ pager now floats around instead
+ of always being on the bottom.  This was done to facilitate the ^L in
+ the pager so it didn't look stupid.
+ 
+ Moved the MIME QUOTED-PRINTABLE and BASE64 decoding code to mime.c so it
+ can be shared.
+ 
+ Fixed copy_message() so that it will automatically decode MIME B64 and QP
+ encodings.  This means that replies to these types of messages do what the
+ user will expect.
+ 
+ ----------------
+ Changes from ME3
+ ----------------
+ 
+ Fixed problems in builtin++.c and pgp.c where I used the return value
+ from sprintf() as a char* when in SYSV systems it returns an int. 
+ This caused Elm to seg fault while decrypting messages.
+ 
+ Configure now asks about PGP support and automatically sets up
+ config.h.  Thanks to Ken Cox (kenc@viewlogic.com) for additional help.
+ 
+ PGP messages are now automatically decrypted when replying if
+ usepgppass = ON.
+ 
+ Back to using the application/pgp format content-type.  Use
+ format=keys-only for send a public key block.
+ 
+ PGPCall() now uses the pgp option +encrypttoself=on instead of tacking
+ the username on the end of the TO list.
+ 
+ Fixed problem where any messages after sending a PGP public key had
+ the key text included before the included message text.
+ 
+ Use rename() if availible instead of copying the file in PGPCall(). 
+ Otherwise use link(), unlink().  This should be a little more
+ efficient.
+ 
+ pgp is now called with the -w (wipe) option when encrypting.
+ 
+ builtin++ can now handle text which is QUOTED-PRINTABLE or BASE64
+ encoded.
+ 
+ Fixed bug where the last line of messages was not being printed.
+ 
+ Elm will no longer seg fault if you hit return without entering your
+ PGP passphrase.
+ 
+ Discovered the +batchmode option for pgp.  This makes dealing with
+ incorrect passphrases much easier!
+ 
+ Fixed bug in builtin++ where the last line of pgp messages would be
+ printed more than once while at the end of the message under certain
+ circumstances.
+ 
+ Changed notplain() in mime.c to support message/* content-type.
+ 
+ Cleaned up the multipart handling by removing the boundary string from
+ header_rec to conserve memory.  This is now handled by builtin++ and
+ AttachMenu().
+ 
+ builtin++ can now handle multipart/digest correctly.
+ 
+ SaveAttach() no longer needs to call metamail to decode QUOTED-PRINTABLE
+ or BASE64 encodings.
+ 
+ -----------------
+ Changes from ME2a
+ -----------------
+ 
+ Elm will now keep track of your PGP passphrase for your RSA secret key.
+ To use this feature, add the line "usepgppass = ON" to your .elmrc.
+ There is also a timeout feature which will cause Elm to "forget" your
+ passphrase after so many seconds if you don't use it.  The default is
+ 300 seconds, but this can be changes by setting the variable
+ "keeppassfor" in your .elmrc.
+ 
+ The builtin++ pager was completely rewritten (again) so that it can now
+ handle normal messages, MIME multipart messages, automatic decryption
+ and automatic signature checking for PGP messages.  It also seems to be
+ lacking some of the memory allocation bugs that the previous pager had.
+ 
+ Fixed a bug in DynamicArray() which causes DestroyDynamicArray() to
+ seg fault if exactly max+n elements were allocated. (weo@recco.de)
+ 
+ ----------------
+ Changes from ME2
+ ----------------
+ 
+ It is now possible to delete all "tagged" messages by entering "tagged"
+ as the pattern to match after typing <control>-d (^D).
+ 
+ fixed a bug in the limit command where you could not "un"limit the
+ display of headers.  Thanks to guy@netapp.com (Guy Harris) for
+ pointing it out!
+ 
+ fixed a bug in is_multipart() where the "boundary" token match was
+ case-sensitive.
Index: elm2.4.ME+.50/Changes
*** elm2.4.25/Changes	Sun Dec 20 07:19:11 1992
--- elm2.4.ME+.50/Changes	Tue Nov 17 21:12:53 1998
***************
*** 1,3 ****
--- 1,9 ----
+ 
+ This Changes is for the 2.4 version.
+ 
+ Look file README.ME+ for changes of the 2.4ME+ version.
+ 
+ --------------------------------------------------------------------------
  This file describes major changes made to the Elm source distribution
  between Releases 2.3 and 2.4.  Please remember that Elm is a volunteer
  project, we did what we had time for, and perhaps, what interested us.
Index: elm2.4.ME+.50/Configure
*** elm2.4.25/Configure	Mon May 30 19:55:55 1994
--- elm2.4.ME+.50/Configure	Tue Nov 17 21:14:08 1998
***************
*** 8,21 ****
  # and edit it to reflect your system.  Some packages may include samples
  # of config.h for certain machines, so you might look for one of those.)
  #
! # $Header: /home/syd/elm.rel/RCS/Configure,v 5.38 1994/05/30 16:55:46 syd Exp $
  #
- # Yes, you may rip this off to use in other distribution packages.
- # (Note: this Configure script was generated automatically.  Rather than
- # working with this copy of Configure, you may wish to get metaconfig.)
  
  : sanity checks
! PATH=".:/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc:/usr/new:/usr/new/bin:/usr/nbin:$PATH"
  export PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh $0; kill $$)
  
  if test ! -t 0; then
--- 8,18 ----
  # and edit it to reflect your system.  Some packages may include samples
  # of config.h for certain machines, so you might look for one of those.)
  #
! # $Header: /data/cvsroot/mail/elmme+/Configure,v 1.10 1998/11/17 18:55:48 hurtta Exp $
  #
  
  : sanity checks
! PATH="$PATH:.:/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc:/usr/new:/usr/new/bin:/usr/nbin"
  export PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh $0; kill $$)
  
  if test ! -t 0; then
***************
*** 34,43 ****
      cd UU
  fi
  
! case "$1" in
! -d) shift; fastread='yes';;
  esac
  
  Log=''
  Header=''
  bin=''
--- 31,70 ----
      cd UU
  fi
  
! fastread=''
! extractsh=''
! 
! while test $# -gt 0; do
! 	case "$1" in
! 		-d) shift; fastread='yes';;
! 		-S) shift; extractsh=true;;
! 		-h) shift; error=true;;
! 		-*) echo "Configure: unknown option $1" >&2; shift; error=true;;
! 		*) break;;
! 	esac
! done
! 
! case "$error" in
! true)
!     cat >&2 << EOM
! Usage: Configure [-dS]
!   -d : use defaults for all answers.
!   -h : print this help message and exit (with an error status).
!   -S : perform variable substitutions on all .SH files
! EOM
!     exit 1
!     ;;
! esac
! 
! case "$extractsh" in
! true)
!     cd ..
!     . ConfTool/Substitute
!     exit 0
!     ;;
  esac
  
+ 
  Log=''
  Header=''
  bin=''
***************
*** 46,55 ****
  cppminus=''
  d_getopt=''
  d_memcpy=''
- d_mkdir=''
  d_rename=''
  d_symlink=''
  d_whoami=''
  n=''
  c=''
  orderlib=''
--- 73,84 ----
  cppminus=''
  d_getopt=''
  d_memcpy=''
  d_rename=''
  d_symlink=''
  d_whoami=''
+ d_poll=''
+ d_inttypes=''
+ d_nointtypes=''
  n=''
  c=''
  orderlib=''
***************
*** 56,66 ****
  ranlib=''
  package=''
  pager=''
- prefshell=''
  startsh=''
- d_eunice=''
  define=''
- eunicefix=''
  loclist=''
  expr=''
  sed=''
--- 85,92 ----
***************
*** 71,77 ****
  cp=''
  tail=''
  tr=''
- mkdir=''
  sort=''
  uniq=''
  grep=''
--- 97,102 ----
***************
*** 138,144 ****
  d_flock=''
  d_dotlock=''
  d_fcntlock=''
- lock_dir=''
  has_flock=''
  has_fcntl=''
  d_ftruncate=''
--- 163,168 ----
***************
*** 160,166 ****
  d_mallocvoid=''
  d_mboxedit=''
  d_mime=''
! defencoding=''
  defcharset=''
  defdispcharset=''
  d_mmdf=''
--- 184,194 ----
  d_mallocvoid=''
  d_mboxedit=''
  d_mime=''
! metamail_path=''
! metamail=''
! d_8bitmime=''
! d_binarymime=''
! d_dsn=''
  defcharset=''
  defdispcharset=''
  d_mmdf=''
***************
*** 190,195 ****
--- 218,224 ----
  d_strftime=''
  d_strings=''
  d_pwdinsys=''
+ d_waitpid=''
  strings=''
  includepath=''
  d_strstr=''
***************
*** 200,206 ****
  tempnamc=''
  d_termio=''
  d_termios=''
- d_useembed=''
  d_utimbuf=''
  d_vfork=''
  defbatsub=''
--- 229,234 ----
***************
*** 211,217 ****
  mydomain=''
  autohostname=''
  i_memory=''
- i_stdarg=''
  i_stdlib=''
  i_time=''
  i_systime=''
--- 239,244 ----
***************
*** 248,258 ****
  ldflags=''
  cc=''
  libs=''
  nametype=''
  d_passnames=''
  d_berknames=''
  d_usgnames=''
! passcat=''
  rmttape=''
  roff=''
  roffopts=''
--- 275,286 ----
  ldflags=''
  cc=''
  libs=''
+ noaddlib=''
  nametype=''
  d_passnames=''
  d_berknames=''
  d_usgnames=''
! # passcat=''
  rmttape=''
  roff=''
  roffopts=''
***************
*** 267,272 ****
--- 295,306 ----
  xenlf=''
  d_xenix=''
  d_bsd=''
+ d_pgp=''
+ pgp=''
+ pgp_path=''
+ d_remailer=''
+ finger=''
+ finger_path=''
  CONFIG=''
  : set package name
  package=elm2
***************
*** 273,279 ****
  
  echo " "
  echo "Beginning of configuration questions for $package kit."
- : Eunice requires " " instead of "", can you believe it
  echo " "
  
  define='define'
--- 307,312 ----
***************
*** 285,299 ****
  rmlist='kit[1-9]isdone kit[1-9][0-9]isdone'
  trap 'echo " "; rm -f $rmlist; exit 1' 1 2 3
  
- : We must find out about Eunice early
- eunicefix=':'
- if test -f /etc/unixtovms; then
-     eunicefix=/etc/unixtovms
- fi
- if test -f /etc/unixtovms.exe; then
-     eunicefix=/etc/unixtovms.exe
- fi
- 
  : Now test for existence of everything in MANIFEST
  
  echo "First let's make sure your kit is complete.  Checking..."
--- 318,323 ----
***************
*** 339,345 ****
      echo "Found bin directory"
  fi
  
! libswanted="intl nls"
  attrlist="$attrlist sgi"
  
  : some greps do not return status, grrr.
--- 363,370 ----
      echo "Found bin directory"
  fi
  
! # libswanted="intl nls"
! libswanted="sun intl nls c_s"
  attrlist="$attrlist sgi"
  
  : some greps do not return status, grrr.
***************
*** 374,380 ****
      echo "Okay, let's see if #! works on this system..."
      e=/bin/echo; test -f $e || e=/usr/bin/echo
      echo "#!$e hi" > try
-     $eunicefix try
      chmod +x try
      ./try > today
      if $contains hi today >/dev/null 2>&1; then
--- 399,404 ----
***************
*** 382,388 ****
  	sharpbang='#!'
      else
  	echo "#! $e hi" > try
- 	$eunicefix try
  	chmod +x try
  	./try > today
  	if test -s today; then
--- 406,411 ----
***************
*** 398,404 ****
      shsharp=false
      echo "exec grep -v '^#'" >spitshell
      chmod +x spitshell
-     $eunicefix spitshell
      spitshell=`pwd`/spitshell
      echo "I presume that if # doesn't work, #! won't work either!"
      sharpbang=': use '
--- 421,426 ----
***************
*** 416,422 ****
  EOSS
  
  chmod +x try
- $eunicefix try
  if ./try; then
      echo "Yup, it does."
  else
--- 438,443 ----
***************
*** 553,562 ****
  	if test -f \$dir/\$thing; then
  	    echo \$dir/\$thing
  	    exit 0
- 	elif test -f \$dir/\$thing.exe; then
- 	    : on Eunice apparently
- 	    echo \$dir/\$thing
- 	    exit 0
  	fi
  	;;
      esac
--- 574,579 ----
***************
*** 565,571 ****
  exit 1
  EOSC
  chmod +x loc
- $eunicefix loc
  loclist="
  cat
  chgrp
--- 582,587 ----
***************
*** 591,596 ****
--- 607,613 ----
  date
  emacs
  execmail
+ finger
  ispell
  line
  lint
***************
*** 597,607 ****
--- 614,626 ----
  lp
  lpr
  mailx
+ metamail
  mips
  more
  nroff
  pack
  pg
+ pgp
  pmake
  pr
  rmail
***************
*** 705,711 ****
  
  : see if date exists, if so, init c_date
  if $test ! "x$date" = "x" ; then
!     c_date=`LANGUAGE= $date`
  else
      c_date='date was unavailable at configuration'
  fi
--- 724,730 ----
  
  : see if date exists, if so, init c_date
  if $test ! "x$date" = "x" ; then
!     c_date=`LANG= LC_TIME= $date`
  else
      c_date='date was unavailable at configuration'
  fi
***************
*** 814,819 ****
--- 833,844 ----
  	echo exit 1 >bsd
  	echo exit 0 >usg
  	echo exit 1 >v7
+     elif $test "$uname_os" = "IRIX" ; then
+     : test `echo abc | tr a-z A-Z` = Abc does not work in IRIX 6.2
+ 	echo "Looks like an IRIX system, but we'll see.."
+ 	echo exit 1 >bsd
+ 	echo exit 0 >usg
+ 	echo exit 1 >v7
      else
  	echo "Looks kind of like a BSD system, but we'll see..."
  	echo exit 0 >bsd
***************
*** 826,847 ****
      echo exit 1 >usg
      echo exit 0 >v7
  fi
! case "$eunicefix" in
! *unixtovms*)
!     cat <<'EOI'
! There is, however, a strange, musty smell in the air that reminds me of
! something...hmm...yes...I've got it...there's a VMS nearby, or I'm a Blit.
! EOI
!     echo "exit 0" >eunice
!     d_eunice="$define"
!     ;;
! *)
!     echo " "
!     echo "Congratulations.  You aren't running Eunice."
!     d_eunice="$undef"
!     echo "exit 1" >eunice
!     ;;
! esac
  if test -f /xenix; then
      echo "Actually, this looks more like a XENIX system..."
      echo "exit 0" >xenix
--- 851,857 ----
      echo exit 1 >usg
      echo exit 0 >v7
  fi
! 
  if test -f /xenix; then
      echo "Actually, this looks more like a XENIX system..."
      echo "exit 0" >xenix
***************
*** 851,857 ****
      echo "exit 1" >xenix
  fi
  chmod +x xenix
- $eunicefix xenix
  if test -f /venix; then
      echo "Actually, this looks more like a VENIX system..."
      echo "exit 0" >venix
--- 861,866 ----
***************
*** 864,873 ****
      fi
      echo "exit 1" >venix
  fi
! chmod +x bsd usg v7 eunice venix
! $eunicefix bsd usg v7 eunice venix
  rm -rf foo
! rmlist="$rmlist bsd usg v7 eunice venix xenix"
  
  : find out how to find out full name
  echo " "
--- 873,881 ----
      fi
      echo "exit 1" >venix
  fi
! chmod +x bsd usg v7 venix
  rm -rf foo
! rmlist="$rmlist bsd usg v7 venix xenix"
  
  : find out how to find out full name
  echo " "
***************
*** 881,886 ****
--- 889,896 ----
  	dflt=y
      elif xenix; then
  	dflt=y
+     elif $test "$uname_os" = "IRIX"; then
+         dflt=y
      else
  	dflt=n
      fi
***************
*** 934,967 ****
      ;;
  esac
  
- : see if we have to deal with yellow pages, if so, put sun
- : library first, as the yp password routines must override
- : the c library ones
- if $test -d /usr/etc/yp || $test -d /etc/yp; then
-     if $test "$passcat" = "ypcat passwd"; then
- 	dflt=y
-     elif $contains '^\+:' /etc/passwd; then
- 	dflt=y
-     else
- 	dflt=n
-     fi
-     rp="Are you getting the passwd file via yellow pages? [$dflt]"
-     $echo $n "$rp $c"
-     . myread
-     case "$ans" in
-     y*) passcat='ypcat passwd'
- 	case "$libswanted" in
- 	'') libswanted='sun c_s';;
- 	*)  libswanted=`$echo "$libswanted" | $sed -e 's/sun //g'`
- 	    libswanted="sun $libswanted";;
- 	esac
- 	;;
-     *) passcat='cat /etc/passwd';;
-     esac
- else
-     passcat='cat /etc/passwd'
- fi
- 
  : set up shell script to do ~ expansion
  cat >filexp <<EOSS
  $startsh
--- 944,949 ----
***************
*** 998,1004 ****
  esac
  EOSS
  chmod +x filexp
- $eunicefix filexp
  
  # determine text processor to use, default to troff if found.
  case "$roff" in
--- 980,985 ----
***************
*** 1646,1653 ****
  
  case "$ccflags" in
  '') case "$cc" in
!     *gcc*) dflt='-fpcc-struct-return -traditional';;
!     *) dflt='';;
      esac
      ;;
  *) dflt="$ccflags";;
--- 1627,1638 ----
  
  case "$ccflags" in
  '') case "$cc" in
!     *gcc*) dflt='-fpcc-struct-return';;
!     *) dflt=''
! 	if test "$uname_os" = "OSF1"; then
!            dflt='-std'
!         fi
!     ;;
      esac
      ;;
  *) dflt="$ccflags";;
***************
*** 1754,1795 ****
  case "$libswanted" in
  '') libswanted='c_s';;
  esac
! for thislib in $libswanted; do
!     case "$thislib" in
!     dbm) thatlib=ndbm;;
!     *_s) thatlib=NONE;;
!     *) thatlib="${thislib}_s";;
!     *) thatlib=NONE;;
!     esac
!     xxx=`loc lib$thislib.a X /usr/lib /usr/ccs/lib /usr/local/lib /lib`
!     if test -f $xxx; then
! 	echo "Found -l$thislib."
! 	case "$dflt" in
! 	*-l$thislib*|*-l$thatlib*);;
! 	*) dflt="$dflt -l$thislib";;
  	esac
!     else
! 	xxx=`loc lib$thislib.a X $libpth`
  	if test -f $xxx; then
! 	    echo "Found $xxx."
  	    case "$dflt" in
! 	    *$xxx*);;
! 	    *) dflt="$dflt $xxx";;
  	    esac
  	else
! 	    xxx=`loc Slib$thislib.a X $xlibpth`
  	    if test -f $xxx; then
! 		echo "Found -l$thislib."
  		case "$dflt" in
! 		*-l$thislib*|*-l$thatlib*);;
! 		*) dflt="$dflt -l$thislib";;
  		esac
  	    else
! 		echo "No -l$thislib."
  	    fi
  	fi
!     fi
! done
  set X $dflt
  shift
  dflt="$*"
--- 1739,1784 ----
  case "$libswanted" in
  '') libswanted='c_s';;
  esac
! if [ "$noaddlib" != yes ]; then
!     for thislib in $libswanted; do
! 	case "$thislib" in
! 	dbm) thatlib=ndbm;;
! 	*_s) thatlib=NONE;;
! 	*) thatlib="${thislib}_s";;
! 	*) thatlib=NONE;;
  	esac
! 	xxx=`loc lib$thislib.a X /usr/lib /usr/ccs/lib /usr/local/lib /lib`
  	if test -f $xxx; then
! 	    echo "Found -l$thislib."
  	    case "$dflt" in
! 	    *-l$thislib*|*-l$thatlib*);;
! 	    *) dflt="$dflt -l$thislib";;
  	    esac
  	else
! 	    xxx=`loc lib$thislib.a X $libpth`
  	    if test -f $xxx; then
! 		echo "Found $xxx."
  		case "$dflt" in
! 		*$xxx*);;
! 		*) dflt="$dflt $xxx";;
  		esac
  	    else
! 		xxx=`loc Slib$thislib.a X $xlibpth`
! 		if test -f $xxx; then
! 		    echo "Found -l$thislib."
! 		    case "$dflt" in
! 		    *-l$thislib*|*-l$thatlib*);;
! 		    *) dflt="$dflt -l$thislib";;
! 		    esac
! 		else
! 		    echo "No -l$thislib."
! 		fi
  	    fi
  	fi
!     done
! else
!     echo "You told last time that additional libraries are not needed!"
! fi
  set X $dflt
  shift
  dflt="$*"
***************
*** 1816,1822 ****
  $echo $n "$rp $c"
  . myread
  case "$ans" in
! none) ans='';
  esac
  libs="$ans"
  
--- 1805,1816 ----
  $echo $n "$rp $c"
  . myread
  case "$ans" in
! none|'') ans='';
!     noaddlib='yes';
!     ;;
! *)
!     noaddlib='no'
!     ;;
  esac
  libs="$ans"
  
***************
*** 1840,1849 ****
--- 1834,1847 ----
  case "$nm_opts" in
  '') if test -f /mach_boot; then
  	nm_opts=''
+     elif test "$uname_os" = "OSF1"; then
+  	nm_opts=''
      elif test -d /usr/ccs/lib; then
  	nm_opts='-p'
      elif "$mips"; then
  	nm_opts='-B'
+     elif test "$uname_os"="Linux"; then
+ 	nm_opts='-D -f sysv'
      else
  	nm_opts=''
      fi
***************
*** 1941,1947 ****
  set `echo $libc $libnames | tr ' ' '\012' | sort | uniq`
  $echo $n "Extracting names from $* for later perusal...$c"
  nm $nm_opts $* 2>/dev/null >libc.tmp
! $sed -n -e 's/^.* [ATDS]  *[_.]*//p' -e 's/^.* [ATDS] //p' <libc.tmp >libc.list
  if $contains '^printf$' libc.list >/dev/null 2>&1; then
      echo done
  elif $sed -n -e 's/^__*//' -e 's/^\([a-zA-Z_0-9$]*\).*xtern.*/\1/p' \
--- 1939,1958 ----
  set `echo $libc $libnames | tr ' ' '\012' | sort | uniq`
  $echo $n "Extracting names from $* for later perusal...$c"
  nm $nm_opts $* 2>/dev/null >libc.tmp
! if $test `uname` = "AIX" 
! then
!    cat libc.tmp |egrep '^\..* *T'|egrep -v '^\._|Srestf|Ssavef|^\.\$'|\
!       $sed -e 's/\.\(.* \)T.*/\1/' -e 's/ *//g' >libc.list
! 
!    if $test -f /lib/syscalls.exp; then
!       echo " "
!       echo "Also extracting names from /lib/syscalls.exp for good ole AIX..." 
!       $sed -n 's/^\([^  ]*\)[    ]*syscall$/\1/p' /lib/syscalls.exp >>libc.list
!    fi
! else
!    $sed -n -e 's/^.* [ATDSUW]  *[_.]*//p' -e 's/^.* [ATDSUW] //p' <libc.tmp >libc.list
! fi
! 
  if $contains '^printf$' libc.list >/dev/null 2>&1; then
      echo done
  elif $sed -n -e 's/^__*//' -e 's/^\([a-zA-Z_0-9$]*\).*xtern.*/\1/p' \
***************
*** 1966,1971 ****
--- 1977,1986 ----
  	   <libc.tmp >libc.list; \
    $contains '^printf$' libc.list >/dev/null 2>&1; then
      echo done
+ elif $sed -n -e 's/^.* [ATDSUW]  *//p' -e 's/^.* [ATDSUW] //p' \
+ 	<libc.tmp >libc.list; \
+   $contains '^printf$' libc.list >/dev/null 2>&1; then
+     echo done
  else
      nm -p $* 2>/dev/null >libc.tmp
      $sed -n -e 's/^.* [AT]  *_[_.]*//p' -e 's/^.* [AT] //p' <libc.tmp >libc.list
***************
*** 2175,2181 ****
  exit \$status
  EOSS
  chmod +x Cppsym
! $eunicefix Cppsym
  echo "Your C preprocessor defines the following symbols:"
  Cppsym -l $attrlist >Cppsym.true
  cat Cppsym.true
--- 2190,2196 ----
  exit \$status
  EOSS
  chmod +x Cppsym
! 
  echo "Your C preprocessor defines the following symbols:"
  Cppsym -l $attrlist >Cppsym.true
  cat Cppsym.true
***************
*** 2247,2256 ****
  
  $cat << EOM
  
! Some modern Mail Transport Agents (mailers) support the Content-Length: header.
! In doing so, they do not wish to have messages escaped to protect 'From ' lines
! in the body of the message, among other strings.  Does the Mail Transport Agent
! in use on this system honor the Content-Length: header?
  EOM
  
  echo " "
--- 2262,2273 ----
  
  $cat << EOM
  
! Some Local Delivery Agents (mailers) support the Content-Length: header. In 
! doing so, they do not wish to have messages escaped to protect 'From ' lines
! in the body of the message, among other strings.  Does the Local Delivery Agent
! in use on this system use the Content-Length: header when writing mails to
! (incoming) mailbox?
! 
  EOM
  
  echo " "
***************
*** 2459,2479 ****
      echo 'Dot lock style locking will be used'
  fi
  
- if $test -d /usr/spool/locks ; then
-     lock_dir=/usr/spool/locks
- elif $test -d /usr/spool/uucp ; then
-     lock_dir=/usr/spool/uucp
- elif $test -d /var/spool/locks ; then
-     lock_dir=/var/spool/locks
- elif $test -d /var/spool/uucp ; then
-     lock_dir=/var/spool/uucp
- else
-     lock_dir=/tmp
- fi
- echo " "
- echo "Non-mailbox locks will use the $lock_dir directory"
- echo " "
- 
  : now get the host name
  if $test "$autohostname" != "$undef" -o "$hostname" = "" ; then
      autohostname="$define"
--- 2476,2481 ----
***************
*** 2642,2647 ****
--- 2644,2692 ----
      d_whoami="$undef"
  fi
  
+ 
+ : see if there is a poll file
+ echo " "
+ if $test -r /usr/include/poll.h ; then
+     d_poll="$define"
+     echo "poll.h found."
+ else
+     d_poll="$undef"
+ fi
+ 
+ : see if there is a poll file
+ echo " "
+ if $test -r /usr/include/inttypes.h ; then
+     d_inttypes="$define"
+     echo "inttypes.h found."
+ 
+ 	case "$d_nointtypes" in
+ 		"$define") dflt=y;;
+ 		"$undef")  dflt=n;;
+ 		*)         dflt=n;;
+ 	esac
+ 
+     echo "In some systems (such as IRIX 5.3, but not in IRIX 6.2) "
+     echo "including of inttypes.h causes error (types defined also "
+     echo "in sys/types.h)"
+     echo " "
+     rp="Avoid including inttypes.h [$dflt]"
+     $echo $n "$rp $c"
+     . myread
+     case "$ans" in
+ 	[Yy]*)	
+ 		d_nointtypes="$define"
+ 		;;
+ 	*)
+ 		d_nointtypes="$undef"
+     esac
+ 
+ else
+     d_inttypes="$undef"
+     d_nointtypes="$undef"
+ fi
+ 
+ 
  : see how we will look up host name
  echo " "
  d_douname="$undef"
***************
*** 2909,2914 ****
--- 2954,2971 ----
  *)  d_mmdf="$undef";;
  esac
  
+ # BSD Sendmail installs itself either /usr/lib/sendmail, /usr/sbin/sendmail
+ # or /usr/ucblib/sendmail, prefer that over other locations
+ if [ -x  /usr/lib/sendmail ] ; then
+ 	sendmail=/usr/lib/sendmail
+ 	echo "BSD(?) sendmail is on $sendmail"
+ elif [ -x /usr/sbin/sendmail ] ; then
+ 	sendmail=/usr/sbin/sendmail
+ 	echo "BSD(?) sendmail is on $sendmail"
+ elif [ -x /usr/ucblib/sendmail ] ; then
+ 	sendmail=/usr/ucblib/sendmail
+ 	echo "BSD(?) sendmail is on $sendmail"
+ fi 
  : determine mail delivery agent for Elm to use
  case "$mailer" in
  '')
***************
*** 2964,2998 ****
      execmail=''
  fi
  
- : check for internet mailer
- case "$d_internet" in
- "$define")	dflt=y;;
- "$undef")	dflt=n;;
- *)	if $test -f "$sendmail"; then
- 	    dflt=y
- 	elif $test -f "$submit"; then
- 	    dflt=y
- 	elif $test -f "$smail"; then
- 	    dflt=y
- 	else
- 	    dflt=n
- 	fi
- 	;;
- esac
- $cat <<EOM
-  
- Some newer mailers can deliver mail to addresses of the INTERNET
- persuasion, such as user@host.domain.  Other older mailers require the
- complete uucp ! path to the destination to be specified in the address.
- EOM
- rp="Does your mailer understand INTERNET addresses? [$dflt]"
- $echo $n "$rp $c"
- . myread
- case "$ans" in
- y*) d_internet="$define";;
- *)  d_internet="$undef";;
- esac
- 
  : check for ispell spelling checker
  case "$d_ispell" in
  "$define")	dflt=y
--- 3021,3026 ----
***************
*** 3207,3224 ****
  case "$d_mime" in
  "$define") dflt=y;;
  "$undef")  dflt=n;;
! *)	   if $test -f "$metamail"; then
! 		$cat <<EOM
! 
! I've found the metamail program out there, I assume you want support for
! MIME (Multipurpose Internet Mail Extension, RFC 1341).
! 
! EOM
! 		dflt=y
! 	   else
! 		dflt=n
! 	   fi;;
! 
  esac
  $cat <<EOM
  
--- 3235,3241 ----
  case "$d_mime" in
  "$define") dflt=y;;
  "$undef")  dflt=n;;
! *)         dflt=y;;
  esac
  $cat <<EOM
  
***************
*** 3228,3247 ****
  doesn't necessarily need graphics capabilities on your display, but its
  useful.
  
- If you have installed Nathaniel Borenstein's metamail package for
- displaying MIME messages, elm can make use of it.  If you didn't
- have metamail installed you might want to obtain a copy of it.  The
- most recent version is on thumper.bellcore.com [128.96.41.1], or ask
- the archie servers for the nearest site.
- 
  Compiling elm even with MIME support enabled would not depend on the
! metamail package, but you would not be able to use nearly all of the
! MIME features as long as you don't have metamail installed.  Metamail
! with its companion programs (mmencode) must be installed somewhere in
! the search path, usually /usr/local/bin.
!   
! 
  
  EOM
  
  rp="Should support for MIME be compiled in? [$dflt]"
--- 3245,3257 ----
  doesn't necessarily need graphics capabilities on your display, but its
  useful.
  
  Compiling elm even with MIME support enabled would not depend on the
! Nathaniel Borenstein's metamail package, but you would not be able to 
! use nearly all of the MIME features as long as you don't have metamail 
! installed.  
  
+ You can also compile Elm with MIME support and tell that metamail should
+ not be used. This is configuration option.
  EOM
  
  rp="Should support for MIME be compiled in? [$dflt]"
***************
*** 3252,3260 ****
  *)  d_mime="$undef";;
  esac
  
- 
  case "$defcharset" in
! '') defcharset="US-ASCII";;
  *) defcharset="$defcharset";;
  esac
  
--- 3262,3269 ----
  *)  d_mime="$undef";;
  esac
  
  case "$defcharset" in
! '') defcharset="DISPLAY";;
  *) defcharset="$defcharset";;
  esac
  
***************
*** 3263,3284 ****
  *) defdispcharset="$defdispcharset";;
  esac
  
! case "$defencoding" in
! '') if $test "$defcharset" = "US-ASCII"; then
! 		defencoding="7bit"
! 	else
! 		defencoding="8bit"
! 	fi;;
! *) defencoding="$defencoding";;
! esac
  
  if $test "$d_mime" = "$define"; then
  	dflt="$defcharset"
  cat <<EOM
  
  The Default Character Set which should be used on outgoing messages.
! Most sites would use US-ASCII.
! 
  EOM
  	rp="Default Character Set for MIME Content-type text? [$dflt]"
  	$echo $n "$rp $c"
--- 3272,3364 ----
  *) defdispcharset="$defdispcharset";;
  esac
  
! if $test "$defdispcharset" = DISPLAY 
! then
! 	defdispcharset=ISO-8859-1
! fi
  
  if $test "$d_mime" = "$define"; then
+ 
+ case "$metamail_path" in
+ '') if test -f "$metamail" ; then
+ 	dflt="$metamail"
+ 	echo
+         echo "Metamail program found from $metamail"
+     else
+         dflt='none'
+     fi
+    ;;
+ *) dflt="$metamail_path"
+    ;;
+ esac
+ 
+ 
+ cat <<EOM
+ 
+ If you have installed Nathaniel Borenstein's metamail package for
+ displaying MIME messages, elm can make use of it.  If you didn't
+ have metamail installed you might want to obtain a copy of it.  The
+ most recent version is on thumper.bellcore.com [128.96.41.1], or ask
+ the archie servers for the nearest site.
+ 
+ This version (Elm 2.4ME+) does not use Metamail's companion programs 
+ (such as mmencode) directly, but metamail package supposes that
+ companion programs are installed to search path.
+   
+ What is the compile time default path for metamail?
+ Possible values include:
+ 	none		Don't call metamail
+ 	metamail	Call metamail if environment variable \$NOMETAMAIL
+ 			is not set.
+ 	/path		Call metamail via that path, if it is executable
+   
+ EOM
+ cont=true
+ while $test "$cont" ; do
+ 	rp="Default path for metamail? [$dflt]"
+ 	$echo $n "$rp $c"
+ 	. myread
+ 	case "$ans" in
+ 		none|metamail)
+ 			metamail_path="$ans"
+ 	    		cont=''
+ 		;;
+ 		/*)
+ 			if $test -f "$ans"; then
+ 		                metamail_path="$ans"	
+ 	    			cont=''
+ 			else
+ 	    			if $test "$fastread" = yes; then
+ 					dflt=y
+ 	    			else
+ 					dflt=n
+ 	    			fi
+ 	    			rp="File $ans doesn't exist.  Use that name anyway? [$dflt]"
+ 	    			$echo $n "$rp $c"
+ 				savedAns="$ans"
+ 	    			. myread
+ 	    			case "$ans" in
+ 	    				y*) 
+ 					metamail_path="$savedAns"
+ 					cont='';;
+ 	    			esac
+ 			fi
+ 		;;
+ 		*)
+ 			metamail_path="$ans"
+ 		;;
+ 	esac
+ done
+ 
  	dflt="$defcharset"
  cat <<EOM
  
  The Default Character Set which should be used on outgoing messages.
! Possible values include:
! 	DISPLAY		The character set, which your terminal supports
! 		        (asked in next question)
! 	US-ASCII	Some sites would use US-ASCII.
! 	ISO-8859-1	Most European sites would prefer ISO-8859-1
  EOM
  	rp="Default Character Set for MIME Content-type text? [$dflt]"
  	$echo $n "$rp $c"
***************
*** 3289,3298 ****
  	$cat <<EOM
  
  The Character Set which your terminals support. You could set this
! to one of the ISO-8859 charsets, even if you set the default for
! the Text Messages to US-ASCII, as the ISO-8859 charsets could display
! US-ASCII as well. For a X-Windows environment, ISO-8859-1 would be 
! a convenient value.
  
  EOM
  	rp="Default Character Set which could be displayed [$dflt]"
--- 3369,3387 ----
  	$cat <<EOM
  
  The Character Set which your terminals support. You could set this
! to one of the ISO-8859 charsets or KOI8-R charset, even if you set
! the default for the Text Messages to US-ASCII, as the ISO-8859 and
! KOI8-R charsets could display US-ASCII as well. For an X11
! environment, ISO-8859-1 would be a convenient value.
! 
! Default Display Character Set is overriden by environment variable
! \$MM_CHARSET if it is set (and \$NOMETAMAIL is not set.)
! 
! In systems which supports locales, mapping from LC_CTYPE to
! character set is used instead. In that case selection on here
! or on configuration file serves as default. Mapping is given 
! in file elm.mimecharsets on elm library directory or on file 
! .elm/mime.charsets
  
  EOM
  	rp="Default Character Set which could be displayed [$dflt]"
***************
*** 3300,3325 ****
  	. myread
  	defdispcharset="$ans"
  
! 	dflt="$defencoding"
! 	$cat <<EOM
! Default Content-Transfer-Encoding for MIME Content-type text.
! If you are using the default US-ASCII charset, you should use
! 7bit encoding. But if you are using some other national character
! set, 8bit is recommended, unless you are using a 7bit character set.
! For 8bit encoding your transport paths should be 8bit clean, which
! is not true all over the world. base64 or quoted-printable aren't
! yet supported for the default Content-Transfer-Encoding.
  
  EOM
! 	rp="Default Content-Transfer-Encoding for MIME Content-type text? [$dflt]"
! 	$echo $n "$rp $c"
! 	. myread
! 	defencoding="$ans"
  fi
  
! : see if mkdir exists
! set mkdir d_mkdir
! eval $inlibc
  
  : ask about newmail running in the background automatically
  case "$d_newauto" in
--- 3389,3631 ----
  	. myread
  	defdispcharset="$ans"
  
! case "$d_8bitmime" in
! "$define") dflt=y;;
! "$undef") dflt=n;;
! *)  
! if $test "$mailer" = "$sendmail" ; then
! 	echo "Testing if your mailer supports -B8BITMIME ..."
! 	if $mailer -B8BITMIME -bv root >/dev/null < /dev/null; then
! 		echo "Yup. Option -B8BITMIME perhaps works."
! 		echo "(Sendmail 8.6 will accept but ignore that option.)"
! 		dflt=y
! 	else
! 		echo "Seems that option -B8BITMIME does not work."
! 		dflt=n
! 	fi
! else
! 	echo "Can't figure how to test if your mailer supports -B8BITMIME ..."
! 	dflt=n
! fi
! ;;
! esac
! 
! cat <<EOM
! 
! If your MTA (Mail transport Agent) supports 8BITMIME ESMTP -extension
! and accepts also option -B8BITMIME (that is BODYTYPE=8BITMIME), Elm
! can left doing encoding from 8bit to quoted_printable to MTA. Otherwise
! Elm does encoding of 8bit data itself. Sendmail version 8.7 supports
! 8BITMIME -extension.
  
  EOM
! rp="MTA supports -B8BITMIME -option? [$dflt]"
! $echo $n "$rp $c"
! . myread
! case "$ans" in
! y*) d_8bitmime="$define";;
! *)  d_8bitmime="$undef";;
! esac
! 
! # If mailer don't support 8BITMIME it also don't support BINARYMIME
! case "$d_8bitmime" in
! "$define")
! 
! case "$d_binarymime" in
! "$define") dflt=y;;
! "$undef") dflt=n;;
! *)  
! if $test "$mailer" = "$sendmail" ; then
! 	echo " "
! 	echo "Testing if your mailer supports -BBINARYMIME ..."
! 	if $mailer -BBINARYMIME -bv root >/dev/null </dev/null; then
! 		echo "Yup. Option -BBINARYMIME perhaps works."
! 		echo "(Is there really MTA what supports BINARYMIME?)"
! 		dflt=y
! 	else
! 		echo "Seems that option -BBINARYMIME does not work."
! 		dflt=n
! 	fi
! else
! 	echo "Can't figure how to test if your mailer supports -BBINARYMIME ..."
! 	dflt=n
  fi
+ ;;
+ esac
  
! cat <<EOM
! 
! If your MTA (Mail transport Agent) supports BINARYMIME ESMTP -extension
! and accepts also option -BBINARYMIME (that is BODYTYPE=BINARYMIME), Elm
! can left doing encoding from BINARY to base64 or quoted-printabe to MTA. 
! Otherwise Elm does encoding of binary data itself. Passing of binary data
! requires that all text data lines are terminated with CRLF -- Unix's
! LF is NOT sufficient. Currently ELM don't use CRLF as line terminator
! in every places when using -BBINARYMIME option (so that option is only
! partially implemented by Elm). Notice also that isn't known any MTA (mailer)
! what implements BINARYMIME or accepts -BBINARYMIME option. Notice also
! that BINARYMIME is Experimental Protocol (as stated in RFC1830).
! 
! EOM
! rp="MTA supports -BBINARYMIME -option? [$dflt]"
! $echo $n "$rp $c"
! . myread
! case "$ans" in
! y*) d_binarymime="$define";;
! *)  d_binarymime="$undef";;
! esac
! 
! ;;
! *) d_binarymime="$undef";;
! esac
! 
! 
! case "$d_dsn" in
! "$define") dflt=y;;
! "$undef") dflt=n;;
! *)  
! if $test "$mailer" = "$sendmail" ; then
! 	echo " "
! 	echo "Testing if your mailer supports DSN options: -N -R -V ..."
! 	if $mailer -N success -R hdrs -V zzz -bv root  >/dev/null </dev/null
!         then
! 		echo "Yup. Options -N succees -R hdrs -V zzz perhaps works."
! 		dflt=y
! 	else
! 		echo "Seems that options -N succees -R hdrs -V zzz does not work."
! 		dflt=n
! 	fi
! else
! 	echo "Can't figure how to test if your mailer supports DSN options: -N -R -V "
! 	dflt=n
! fi
! ;;
! esac
! 
! cat <<EOF
! If your MTA (Mail transport Agent) supports DSN ESMTP -extension
! (Delivery Status Notification) and accepts also options:
! 	-N success,failure,delay/never        
! 	-R hdrs/full                              for RET= -paramater
! 	-V ...                                    for ENVID= -paramater
! Elm can use them. Sendmail 8.8 supports this (sendmail 8.7 supports
! ESMTP DSN, but it is not available via command line options).
! EOF
!     rp="MTA supports DSN via options -N -R -V ? [$dflt]"
!     $echo $n "$rp $c"
!     . myread
!     case "$ans" in
!     y*) d_dsn="$define";;
!     *)  d_dsn="$undef";;
!     esac
! else
! 
! metamail_path="none"
! d_8bitmime="$undef"
! d_binarymime="$undef"
! d_dsn="$undef"
! 
! fi
! 
! : ask about PGP support
! if $test "$d_pgp" = "$define"; then
! 	dflt=y
! 	pgp=$pgp_path
! else
! 	dflt=n
! fi
! echo ''
! rp="Should PGP (Pretty Good Privacy) support be compiled in? [$dflt]"
! echo $n "$rp $c"
! . myread
! if test "$ans" = "y"; then
! 	d_pgp="$define"
! cat <<EOM
! 
! What is the compile time default path for pgp?
! Possible values include:
! 	none		Don't call pgp
! 	/path		Call metamail via that path, if it is executable
! 
! EOM
! 	cont=true
! 	dflt="$pgp"
! 	while $test "$cont"; do
!                 rp="Where is the pgp binary located? [$dflt]"
! 		echo $n "$rp $c"
! 		. myread
! 		pgp_path="$ans"
! 		case "$ans" in
! 		none)
! 			pgp_path=none
! 			cont=''
! 			;;
! 		/*)
! 			if $test -f $ans; then
! 				cont=''
! 			else
! 				if $test "$fastread" = yes; then
! 					dflt=y
! 				else
! 					dflt=n
! 				fi
! 				rp="File $ans doesn't exist.  Use that name anyway? [$dflt]"
! 				echo $n "$rp $c"
! 				. myread
! 				case "$ans" in
! 				y*) cont='';;
! 				esac
! 			fi
! 			;;
! 		*)
! 			echo "Please give the full pathname."
! 			;;
! 		esac
! 	done
! else
! 	d_pgp="$undef"
! fi
! 
! : ask about remailer support
! if $test "$d_remailer" = "$define"; then
! 	dflt='y'
! else
! 	dflt='n'
! fi
! echo ''
! echo 'Warning: REMAILER code does not work.'
! echo ''
! rp="Should support for anonymous remailers be included? [$dflt]"
! echo $n "$rp $c"
! . myread
! if $test "$ans" = "y"; then
! 	d_remailer="$define"
! 	dflt=$finger
! 	cont=true
! 	while $test "$cont"; do
! 		rp="Where is the finger binary located? [$dflt]"
! 		echo $n "$rp $c"	
! 		. myread
! 		finger_path=$ans
! 		if $test -f $ans; then
! 			cont=''
! 		else
! 			if $test "$fastread" = yes; then
! 				dflt=y
! 			else
! 				dflt=n
! 			fi
! 			rp="File $ans doesn't exist.  Use that name anyway? [$dflt]"
! 			echo $n "$rp $c"
! 			. myread
! 			case "$ans" in
! 			y*) cont='';;
! 			esac;
! 		fi
! 	done
! else
! 	d_remailer="$undef"
! fi
  
  : ask about newmail running in the background automatically
  case "$d_newauto" in
***************
*** 3717,3722 ****
--- 4023,4035 ----
      fi
  fi
  
+ if $contains waitpid libc.list >/dev/null 2>&1; then
+     echo "waitpid() found."
+     d_waitpid="$define"
+ else
+     d_waitpid="$undef"
+ fi
+ 
  : see if strspn exists
  set strspn d_strspn
  eval $inlibc
***************
*** 3820,3856 ****
      fi
  fi
  
- : check for valid reply/to fields
- case "$d_useembed" in
- "$define")	dflt=y;;
- "$undef")	dflt=n;;
- *)	        if $test "$d_internet" = "$define" ; then
- 	            dflt=y
- 	        else
- 	            dflt=n
- 	        fi
- 	        ;;
- esac
- $cat <<EOM
-  
- One of the more annoying quirks of the UUCP network and various other
- systems that interact with it are that everyone seems to have different
- ideas about how to do routing, etc.  Therefore, a lot of times e-mail
- will arrive from off site with corrupt, unusable "Reply-To:" and "From:"
- fields.  This next question relates to whether your site is liable to
- get mangled fields or not...
- 
- Does your site receive e-mail with valid "Reply-To:" and "From:" fields?
- 
- EOM
- $echo $n "Use Reply-To: and From: addresses? [$dflt] $c"
- rp="Are Reply-to: and From: addresses reliable? [$dflt]"
- . myread
- case "$ans" in
- y*) d_useembed="$define";;
- *)  d_useembed="$undef";;
- esac
- 
  : see if getdomainname exists
  if $contains "^getdomainname\$" libc.list > /dev/null 2>&1; then
      echo "getdomainname() found"
--- 4133,4138 ----
***************
*** 4001,4007 ****
  #include <sys/types.h>
  #include <sys/stat.h>
  #define far /* to keep Xenix from complaining */
! #if (defined(BSD) || !defined(apollo))
  #  include <sys/file.h>
  #endif
  #ifdef I_TIME
--- 4283,4289 ----
  #include <sys/types.h>
  #include <sys/stat.h>
  #define far /* to keep Xenix from complaining */
! #if (defined(BSD_TYPE) || !defined(apollo))
  #  include <sys/file.h>
  #endif
  #ifdef I_TIME
***************
*** 4010,4016 ****
  #ifdef I_SYSTIME
  #  include <sys/time.h>
  #endif
! #ifdef BSD
  #  include <sys/timeb.h>
  #endif
  #ifdef I_UTIME
--- 4292,4298 ----
  #ifdef I_SYSTIME
  #  include <sys/time.h>
  #endif
! #ifdef BSD_TYPE
  #  include <sys/timeb.h>
  #endif
  #ifdef I_UTIME
***************
*** 4041,4047 ****
  		  cflags="$cflags -DI_SYSTIME"
  	      fi
  	      if $test "$d_bsd" = "$define"; then
! 		  cflags="$cflags -DBSD"
  	      fi
  	      if $cc $cflags try.c -o try >/dev/null 2>&1 ; then
  		  d_utimbuf="$define"
--- 4323,4329 ----
  		  cflags="$cflags -DI_SYSTIME"
  	      fi
  	      if $test "$d_bsd" = "$define"; then
! 		  cflags="$cflags -DBSD_TYPE"
  	      fi
  	      if $cc $cflags try.c -o try >/dev/null 2>&1 ; then
  		  d_utimbuf="$define"
***************
*** 4075,4091 ****
  	i_memory="$undef"
  fi
  
- : see if stdarg.h is in includepath
- echo " "
- i_stdarg=`loc stdarg.h "" /usr/include $includepath`
- if $test -n "$i_stdarg"; then
- 	echo "Found <stdarg.h>"
- 	i_stdarg="$define"
- else
- 	echo "Did not find <stdarg.h>"
- 	i_stdarg="$undef"
- fi
- 
  : see if unistd.h is in includepath
  echo " "
  i_unistd=`loc unistd.h "" /usr/include $includepath`
--- 4357,4362 ----
***************
*** 4100,4106 ****
  : see if signal is declared as pointer to function returning int or void
  echo " "
  $cppstdin $cppflags < /usr/include/signal.h >$$.tmp
! if $contains 'void.*[^s]signal' $$.tmp >/dev/null 2>&1 ; then
      echo "You have void (*signal())() instead of int."
      sigtype="void"
  elif $contains 'int.*[^s]signal' $$.tmp >/dev/null 2>&1 ; then
--- 4371,4380 ----
  : see if signal is declared as pointer to function returning int or void
  echo " "
  $cppstdin $cppflags < /usr/include/signal.h >$$.tmp
! if test "$uname_os" = "OSF1" ; then
!     echo "You have void (*signal())()."
!     sigtype="void"
! elif $contains 'void.*[^s]signal' $$.tmp >/dev/null 2>&1 ; then
      echo "You have void (*signal())() instead of int."
      sigtype="void"
  elif $contains 'int.*[^s]signal' $$.tmp >/dev/null 2>&1 ; then
***************
*** 4287,4292 ****
--- 4561,4635 ----
      fi
  done
  
+ if [ "$d_locale" = "$define" ] ; then
+ 	$cat <<EOM
+ 
+ Elm ME+ is ability to map locale's LC_CTYPE to MIME character set.
+ That is done via file elm.mimecharsets on elm's library directory.
+ 
+ EOM
+ 	(
+ 	cd ..
+ 	if [ -r $lib/elm.mimecharsets ] ; then
+ 		cp $lib/elm.mimecharsets bin/elm.mimecharsets
+ 	else 
+ 		cat >bin/elm.mimecharsets <<'EOM'
+ # Mapping from LC_CTYPE locale to MIME's charset values
+ # Format is:
+ #	LC_CTYPE	charset
+ # LC_CTYPE is on form
+ #	LL_cc.encoding
+ # then also following formats are available:
+ #	LL_cc		charset
+ #	LL		charset
+ #	*.encoding	charset
+ EOM
+ 	fi
+ 
+ 	values="`locale -a 2>/dev/null`"
+ 	if $test -z "$values" ; then
+ 		values="`ls /usr/lib/locale`"
+ 	fi
+ 
+ 	for lc_ctype in $values ; do
+ 		if grep "^$lc_ctype" bin/elm.mimecharsets > /dev/null; then
+ 			echo "$lc_ctype ok"
+ 		else
+ 			echo $n "Adding $lc_ctype $c"
+ 			if $test "$lc_ctype" = C -o "$defdispcharset" = "" 
+ 			then
+ 				echo "$lc_ctype US-ASCII" >> bin/elm.mimecharsets
+ 				echo "(as US-ASCII)"
+ 			elif grep "^$lc_ctype" doc/mime.charsets >> bin/elm.mimecharsets
+ 			then
+ 			    echo "   (from doc/mime.charsets)"
+ 			else
+ 				echo "$lc_ctype $defdispcharset" >> bin/elm.mimecharsets
+ 				echo "(as $defdispcharset)"
+ 			fi
+ 		fi
+ 	done
+ 
+ 	if $test -f /usr/lib/locale/locale.alias ; then
+ 	        echo "# /usr/lib/locale/locale.alias gives:" >> bin/elm.mimecharsets
+ 		sed 's/^/#/g' < /usr/lib/locale/locale.alias >> bin/elm.mimecharsets
+ 		echo "Copying /usr/lib/locale/locale.alias to elm.mimecharsets as comment"
+ 	fi
+ 
+ 	
+ 	echo 
+ 	echo "Resulting elm.mimecharsets is following:"
+ 	echo
+ 	cat bin/elm.mimecharsets
+ 	echo
+ 
+ 	rp="If you need to edit bin/elm.mimecharsets, do it as a shell escape here:"
+ 	$echo $n "$rp $c"
+ 	. UU/myread
+ 	$echo
+ 	)
+ fi
+ 
  : ask the preferred line printer and options for this system.
  case "$linepr" in
  '')
***************
*** 4348,4354 ****
  
  : ask the preferred pager for this system.
  case "$pager" in
! '') dflt="builtin+";;
  *)  dflt="$pager";;
  esac
  
--- 4691,4697 ----
  
  : ask the preferred pager for this system.
  case "$pager" in
! '') dflt="builtin++";;
  *)  dflt="$pager";;
  esac
  
***************
*** 4367,4372 ****
--- 4710,4718 ----
      builtin+)
          cont=''
  	;;
+     builtin++)
+         cont=''
+         ;;
      /*)
  	if $test -f "$ans"; then
  	    cont=''
***************
*** 4390,4434 ****
      esac
  done
  
- : find out which shell people like to use most
- case "$prefshell" in
- '')
-     if $test -f /bin/ksh; then
- 	dflt='/bin/ksh'
-     elif $test -f /bin/csh; then
- 	dflt='/bin/csh'
-     else
- 	dflt='/bin/sh'
-     fi
-     ;;
- *)  dflt="$prefshell";;
- esac
- cont=true
- while $test "$cont" ; do
-     echo " "
-     echo "Give the full path name of the shell most people like to use on your"
-     $echo $n "system: [$dflt] $c"
-     rp="Preferred shell: [$dflt]"
-     . myread
-     prefshell=$ans
-     if test -f $ans; then
- 	cont=''
-     else
- 	if $test "$fastread" = yes; then
- 	    dflt=y
- 	else
- 	    dflt=n
- 	fi
- 	rp="File $ans doesn't exist.  Use that name anyway? [$dflt]"
- 	$echo $n "$rp $c"
- 	. myread
- 	dflt=''
- 	case "$ans" in
- 	y*) cont='';;
- 	esac
-     fi
- done
- 
  : see if ar generates random libraries by itself
  echo " "
  echo "Checking how to generate random libraries on your machine..."
--- 4736,4741 ----
***************
*** 4476,4481 ****
--- 4783,4791 ----
      if $test "$ans" = x; then
          ans=`loc Slibtermlib.a x $libpth`
      fi
+     if $test "$ans" = x; then
+         ans=`loc libtermlib.so x $libpth`
+     fi
      case "$ans" in
      /usr/lib*|/usr/ccs/lib*|/lib*)
  	termlib='-ltermlib'
***************
*** 4492,4497 ****
--- 4802,4810 ----
  	if $test "$ans" = x; then
  	    ans=`loc Slibcurses.a x $libpth`
  	fi
+ 	if $test "$ans" = x; then
+ 	    ans=`loc libcurses.so x $libpth`
+ 	fi
  	case "$ans" in
  	/*)
  	    ar t $ans >grimble
***************
*** 4626,4631 ****
--- 4939,4960 ----
  #$i_systime I_SYSTIME
  #include <stdio.h>
  #include <sys/types.h>
+ 
+ 
+ #ifdef I_TIME
+ #  include <time.h>
+ #endif
+ #ifdef I_SYSTIME
+ #  include <sys/time.h>
+ #endif
+ 
+ #ifndef	_POSIX_SOURCE
+ extern struct tm *localtime();
+ extern time_t	  time();
+ #endif
+ EOF
+ cat >elmlib.h <<EOF
+ extern char *get_tz_name();
  EOF
  $echo " "
  dflt_handling=$tzname_handling
***************
*** 4647,4653 ****
  	$echo "Trying -DTZNAME_USE_$tzname_handling"
  	$cc -D_CONFIGURE -DTZNAME_USE_$tzname_handling $ccflags \
  		try.c -o try >/dev/null 2>&1
! 	if $test $? -eq 0 && ./try >try.out 2>&1 ; then
  		$echo "Alright!  That seems to have worked."
  		break
  	fi
--- 4976,4983 ----
  	$echo "Trying -DTZNAME_USE_$tzname_handling"
  	$cc -D_CONFIGURE -DTZNAME_USE_$tzname_handling $ccflags \
  		try.c -o try >/dev/null 2>&1
! 	if $test $? -eq 0 && ./try >try.out 2>&1 
!         then
  		$echo "Alright!  That seems to have worked."
  		break
  	fi
***************
*** 4663,4669 ****
  	$echo "You will have to set \"tzname_handling\" manually."
      fi
  fi
! $rm -f defs.h try.c try.o try try.out
  
  
  : the "config.over" file can be used to patch configuration changes
--- 4993,4999 ----
  	$echo "You will have to set \"tzname_handling\" manually."
      fi
  fi
! $rm -f defs.h elmlib.h try.c try.o try try.out
  
  
  : the "config.over" file can be used to patch configuration changes
***************
*** 4714,4723 ****
  cppminus='$cppminus'
  d_getopt='$d_getopt'
  d_memcpy='$d_memcpy'
- d_mkdir='$d_mkdir'
  d_rename='$d_rename'
  d_symlink='$d_symlink'
  d_whoami='$d_whoami'
  n='$n'
  c='$c'
  orderlib='$orderlib'
--- 5044,5055 ----
  cppminus='$cppminus'
  d_getopt='$d_getopt'
  d_memcpy='$d_memcpy'
  d_rename='$d_rename'
  d_symlink='$d_symlink'
  d_whoami='$d_whoami'
+ d_poll='$d_poll'
+ d_inttypes='$d_inttypes'
+ d_nointtypes='$d_nointtypes'
  n='$n'
  c='$c'
  orderlib='$orderlib'
***************
*** 4724,4734 ****
  ranlib='$ranlib'
  package='$package'
  pager='$pager'
- prefshell='$prefshell'
  startsh='$startsh'
- d_eunice='$d_eunice'
  define='$define'
- eunicefix='$eunicefix'
  loclist='$loclist'
  expr='$expr'
  sed='$sed'
--- 5056,5063 ----
***************
*** 4739,4745 ****
  cp='$cp'
  tail='$tail'
  tr='$tr'
- mkdir='$mkdir'
  sort='$sort'
  uniq='$uniq'
  grep='$grep'
--- 5068,5073 ----
***************
*** 4789,4794 ****
--- 5117,5123 ----
  compress='$compress'
  execmail='$execmail'
  libswanted='$libswanted'
+ noaddlib='$noaddlib'
  c_date='$c_date'
  d_ascii='$d_ascii'
  d_broke_ctype='$d_broke_ctype'
***************
*** 4806,4812 ****
  d_flock='$d_flock'
  d_dotlock='$d_dotlock'
  d_fcntlock='$d_fcntlock'
- lock_dir='$lock_dir'
  has_flock='$has_flock'
  has_fcntl='$has_fcntl'
  d_ftruncate='$d_ftruncate'
--- 5135,5140 ----
***************
*** 4828,4834 ****
--- 5156,5166 ----
  d_mallocvoid='$d_mallocvoid'
  d_mboxedit='$d_mboxedit'
  d_mime='$d_mime'
+ metamail_path='$metamail_path'
  defencoding='$defencoding'
+ d_8bitmime='$d_8bitmime'
+ d_binarymime='$d_binarymime'
+ d_dsn='$d_dsn'
  defcharset='$defcharset'
  defdispcharset='$defdispcharset'
  d_mmdf='$d_mmdf'
***************
*** 4850,4855 ****
--- 5182,5188 ----
  d_sighold='$d_sighold'
  d_sigprocmask='$d_sigprocmask'
  d_sigblock='$d_sigblock'
+ d_waitpid='$d_waitpid'
  d_sigaction='$d_sigaction'
  d_strcspn='$d_strcspn'
  d_strspn='$d_strspn'
***************
*** 4868,4874 ****
  tempnamc='$tempnamc'
  d_termio='$d_termio'
  d_termios='$d_termios'
- d_useembed='$d_useembed'
  d_utimbuf='$d_utimbuf'
  d_vfork='$d_vfork'
  defbatsub='$defbatsub'
--- 5201,5206 ----
***************
*** 4920,4926 ****
  d_passnames='$d_passnames'
  d_berknames='$d_berknames'
  d_usgnames='$d_usgnames'
! passcat='$passcat'
  rmttape='$rmttape'
  roff='$roff'
  roffopts='$roffopts'
--- 5252,5258 ----
  d_passnames='$d_passnames'
  d_berknames='$d_berknames'
  d_usgnames='$d_usgnames'
! # passcat='$passcat'
  rmttape='$rmttape'
  roff='$roff'
  roffopts='$roffopts'
***************
*** 4935,4940 ****
--- 5267,5278 ----
  xenlf='$xenlf'
  d_xenix='$d_xenix'
  d_bsd='$d_bsd'
+ d_pgp='$d_pgp'
+ pgp='$pgp'
+ pgp_path='$pgp_path'
+ d_remailer='$d_remailer'
+ finger='$finger'
+ finger_path='$finger_path'
  CONFIG=true
  EOT
  
***************
*** 4953,5014 ****
      eval $ans;;
  esac
  : if this fails, just run all the .SH files by hand
! . ./config.sh
! 
! echo " "
! echo "Doing variable substitutions on .SH files..."
! set x `awk '{print $1}' <MANIFEST | $grep '\.SH'`
! shift
! case $# in
! 0) set x *.SH; shift;;
! esac
! if test ! -f $1; then
!     shift
! fi
! for file in $*; do
!     case "$file" in
!     */*)
! 	dir=`$expr X$file : 'X\(.*\)/'`
! 	file=`$expr X$file : 'X.*/\(.*\)'`
! 	(cd $dir && . $file)
! 	;;
!     *)
! 	. $file
! 	;;
!     esac
! done
! if test -f config.h.SH; then
!     if test ! -f config.h; then
! 	: oops, they left it out of MANIFEST, probably, so do it anyway.
! 	. config.h.SH
!     fi
! fi
! 
! if $contains '^depend:' Makefile >/dev/null 2>&1; then
!     dflt=n
!     $cat <<EOM
! 
! Now you need to generate make dependencies by running "make depend".
! You might prefer to run it in background: "make depend > makedepend.out &"
! It can take a while, so you might not want to run it right now.
! 
! EOM
!     rp="Run make depend now? [$dflt]"
!     $echo $n "$rp $c"
!     . UU/myread
!     case "$ans" in
!     y*) make depend && echo "Now you must run a make."
! 	;;
!     *)  echo "You must run 'make depend' then 'make'."
! 	;;
!     esac
! elif test -f Makefile; then
!     echo " "
!     echo "Now you must run a make."
! else
!     echo "Done."
! fi
! 
  $rm -f kit*isdone
  : the following is currently useless
  cd UU && $rm -f $rmlist
--- 5291,5297 ----
      eval $ans;;
  esac
  : if this fails, just run all the .SH files by hand
! . ConfTool/Substitute
  $rm -f kit*isdone
  : the following is currently useless
  cd UU && $rm -f $rmlist
Index: elm2.4.ME+.50/Instruct
*** elm2.4.25/Instruct	Thu Mar 10 19:20:28 1994
--- elm2.4.ME+.50/Instruct	Tue Nov 17 21:12:53 1998
***************
*** 1,7 ****
  				Instructions
  				------------
  
! 		        Last Update: $Date: 1994/03/10 17:20:23 $
  
  
  	This file contains instructions on how to create and install
--- 1,7 ----
  				Instructions
  				------------
  
! 		        Last Update: $Date: 1998/10/15 15:36:38 $
  
  
  	This file contains instructions on how to create and install
Index: elm2.4.ME+.50/MANIFEST
*** elm2.4.25/MANIFEST	Thu Mar 10 19:14:46 1994
--- elm2.4.ME+.50/MANIFEST	Tue Nov 17 21:14:08 1998
***************
*** 1,7 ****
--- 1,11 ----
+ README.ME+
+ ANNOUNCE.ME
+ ChangeLog.ME
  Changes
  Configure
  Instruct
  MANIFEST
+ ConfTool/Substitute
  Makefile.SH
  NOTICE
  Overview
***************
*** 31,36 ****
--- 35,42 ----
  doc/frm.1
  doc/listalias.1
  doc/messages.1
+ doc/mime.types
+ doc/mime.charsets
  doc/newalias.1
  doc/newmail.1
  doc/printmail.1
***************
*** 55,64 ****
  hdrs/headers.h
  hdrs/mcprt.h
  hdrs/mcprtlib.h
  hdrs/mime.h
  hdrs/msgcat.h
  hdrs/ndbz.h
! hdrs/nl_types.h
  hdrs/patchlevel.h
  hdrs/regexp.h
  hdrs/s_aliases.h
--- 61,73 ----
  hdrs/headers.h
  hdrs/mcprt.h
  hdrs/mcprtlib.h
+ hdrs/me.h
+ hdrs/menu.h
+ hdrs/menu2.h
  hdrs/mime.h
  hdrs/msgcat.h
  hdrs/ndbz.h
! hdrs/elm_nl_types.h
  hdrs/patchlevel.h
  hdrs/regexp.h
  hdrs/s_aliases.h
***************
*** 84,89 ****
--- 93,100 ----
  lib/can_open.c
  lib/chloc.c
  lib/date_util.c
+ lib/dispaddr.c
+ lib/dynarray.c
  lib/errno.c
  lib/expand.c
  lib/figadrssee.c
***************
*** 124,133 ****
--- 135,146 ----
  lib/strftime.c
  lib/strincmp.c
  lib/striparens.c
+ lib/strmcpy.c
  lib/strstr.c
  lib/strtokq.c
  lib/tail_of.c
  lib/validname.c
+ lib/safeopen.c
  nls/C/C/C/s_aliases.m
  nls/C/C/C/s_answer.m
  nls/C/C/C/s_elm.m
***************
*** 159,166 ****
  src/alias.c
  src/aliaslib.c
  src/args.c
! src/bouncebk.c
! src/builtin.c
  src/calendar.c
  src/curses.c
  src/date.c
--- 172,179 ----
  src/alias.c
  src/aliaslib.c
  src/args.c
! src/attach_menu.c
! src/builtin++.c
  src/calendar.c
  src/curses.c
  src/date.c
***************
*** 185,200 ****
  src/lock.c
  src/mailmsg1.c
  src/mailmsg2.c
  src/mime.c
  src/mkhdrs.c
  src/newmbox.c
  src/options.c
  src/out_utils.c
  src/pattern.c
! src/pmalloc.c
  src/quit.c
  src/read_rc.c
  src/remail.c
  src/reply.c
  src/returnadd.c
  src/save_opts.c
--- 198,218 ----
  src/lock.c
  src/mailmsg1.c
  src/mailmsg2.c
+ src/menu.c
+ src/menu2.c
+ src/metapager.c
  src/mime.c
+ src/mime_encode.c
  src/mkhdrs.c
  src/newmbox.c
  src/options.c
  src/out_utils.c
  src/pattern.c
! src/pgp.c
  src/quit.c
  src/read_rc.c
  src/remail.c
+ src/remailer.c
  src/reply.c
  src/returnadd.c
  src/save_opts.c
***************
*** 227,229 ****
--- 245,263 ----
  utils/printmail.SH
  utils/prlong.c
  utils/readmsg.c
+ melib/Makefile.SH
+ melib/mime.c
+ melib/mime_decode.c
+ melib/mime_parse.c
+ melib/parse_util.c
+ melib/pgp_decode.c
+ melib/state.c
+ hdrs/melib.h
+ hdrs/elmlib.h
+ lib/read_rc.c
+ lib/output.c
+ lib/pmalloc.c
+ nls/C/C/C/s_me.m
+ hdrs/s_me.h
+ lib/getaddr.c
+ lib/forwarded.c
Index: elm2.4.ME+.50/Makefile.SH
*** elm2.4.25/Makefile.SH	Wed Apr 21 04:53:22 1993
--- elm2.4.ME+.50/Makefile.SH	Tue Nov 17 21:12:53 1998
***************
*** 21,44 ****
  echo "Extracting Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
  #
! # $Id: Makefile.SH,v 5.3 1993/04/21 01:53:10 syd Exp $
  #
  #  Makefile for the entire ELM mail system
  #
  #         (C) Copyright 1986,1987, by Dave Taylor
  #         (C) Copyright 1988-1992, USENET Community Trust
- #
- #  $Log: Makefile.SH,v $
- # Revision 5.3  1993/04/21  01:53:10  syd
- # take out parallelism, effects standard make
- #
- # Revision 5.2  1993/04/21  01:26:18  syd
- # Support parallel makes in subdirectories with e.g. "make J=2".
- # From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
- #
- # Revision 5.1  1992/10/03  22:12:17  syd
- # Initial checkin as of 2.4 Release at PL0
- #
  # 
  #
  
--- 21,32 ----
  echo "Extracting Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
  #
! # $Id: Makefile.SH,v 1.2 1998/10/20 19:57:09 hurtta Exp $
  #
  #  Makefile for the entire ELM mail system
  #
  #         (C) Copyright 1986,1987, by Dave Taylor
  #         (C) Copyright 1988-1992, USENET Community Trust
  # 
  #
  
***************
*** 65,77 ****
  default_target:	all
  
  #	Targets that are simply executed in each subordinate makefile as is
! all install uninstall lint clean:
  		cd lib; $(MAKE) $(MJ) -$(MAKEFLAGS) $@
  		cd src; $(MAKE) $(MJ) -$(MAKEFLAGS) $@
  		cd utils; $(MAKE) $(MJ) -$(MAKEFLAGS) $@
! 		cd filter; $(MAKE) $(MJ) -$(MAKEFLAGS) $@
  		cd doc; $(MAKE) $(MJ) -$(MAKEFLAGS) $@
  
  #	Targets that apply to all elm at once
  listing:
  		@$(ECHO) "Making source listing in file LISTING."
--- 53,80 ----
  default_target:	all
  
  #	Targets that are simply executed in each subordinate makefile as is
! all install uninstall lint clean: config.h config.sh Makefile
! 		cd melib; $(MAKE) $(MJ) -$(MAKEFLAGS) $@	
  		cd lib; $(MAKE) $(MJ) -$(MAKEFLAGS) $@
  		cd src; $(MAKE) $(MJ) -$(MAKEFLAGS) $@
  		cd utils; $(MAKE) $(MJ) -$(MAKEFLAGS) $@
! 		# cd filter; $(MAKE) $(MJ) -$(MAKEFLAGS) $@
  		cd doc; $(MAKE) $(MJ) -$(MAKEFLAGS) $@
  
+ # Check that config.h is up of date
+ config.h: config.h.SH config.sh
+ 	@echo "You must run 'sh Configure -S' or 'sh Configure'"
+ 	exit 1
+ 
+ # Check that config.sh is up of data
+ config.sh: Configure	
+ 	@echo "You must run 'sh Configure'"
+ 	exit 1
+ 
+ Makefile: Makefile.SH config.sh
+ 	@echo "You must run 'sh Configure -S' or 'sh Configure'"
+ 	exit 1
+ 
  #	Targets that apply to all elm at once
  listing:
  		@$(ECHO) "Making source listing in file LISTING."
***************
*** 84,92 ****
  		  $(ECHO) "ELM on the remote machine <$(REMOTE)>. If this is";\
  		  $(ECHO) "not the case, interrupt this process quickly!";\
  		  $(SLEEP) 10;)
  		cd lib; $(MAKE) $(MJ) -$(MAKEFLAGS) REMOTE=$(REMOTE) $@
  		cd src; $(MAKE) $(MJ) -$(MAKEFLAGS) REMOTE=$(REMOTE) $@
! 		cd filter; $(MAKE) $(MJ) -$(MAKEFLAGS) REMOTE=$(REMOTE) $@
  		cd utils; $(MAKE) $(MJ) -$(MAKEFLAGS) REMOTE=$(REMOTE) $@
  		cd doc; $(MAKE) $(MJ) -$(MAKEFLAGS) REMOTE=$(REMOTE) $@
  
--- 87,96 ----
  		  $(ECHO) "ELM on the remote machine <$(REMOTE)>. If this is";\
  		  $(ECHO) "not the case, interrupt this process quickly!";\
  		  $(SLEEP) 10;)
+ 		cd melib; $(MAKE) $(MJ) -$(MAKEFLAGS) REMOTE=$(REMOTE) $@
  		cd lib; $(MAKE) $(MJ) -$(MAKEFLAGS) REMOTE=$(REMOTE) $@
  		cd src; $(MAKE) $(MJ) -$(MAKEFLAGS) REMOTE=$(REMOTE) $@
! 		# cd filter; $(MAKE) $(MJ) -$(MAKEFLAGS) REMOTE=$(REMOTE) $@
  		cd utils; $(MAKE) $(MJ) -$(MAKEFLAGS) REMOTE=$(REMOTE) $@
  		cd doc; $(MAKE) $(MJ) -$(MAKEFLAGS) REMOTE=$(REMOTE) $@
  
***************
*** 111,116 ****
--- 115,121 ----
  	cd doc; $(MAKE) $(MJ) -$(MAKEFLAGS) $@
  
  elm:
+ 	cd melib; $(MAKE) $(MJ) -$(MAKEFLAGS) all
  	cd lib; $(MAKE) $(MJ) -$(MAKEFLAGS) all
  	cd src; $(MAKE) $(MJ) -$(MAKEFLAGS) all
  
***************
*** 120,126 ****
  filter: _filter
  
  _filter:
! 	cd filter; $(MAKE) $(MJ) -$(MAKEFLAGS) all
  
  #	The dummy dependency here prevents make from thinking the target is the
  #	utils directory that sits in the current directory, rather than
--- 125,131 ----
  filter: _filter
  
  _filter:
! 	# cd filter; $(MAKE) $(MJ) -$(MAKEFLAGS) all
  
  #	The dummy dependency here prevents make from thinking the target is the
  #	utils directory that sits in the current directory, rather than
Index: elm2.4.ME+.50/README
*** elm2.4.25/README	Tue May 11 06:19:23 1993
--- elm2.4.ME+.50/README	Tue Nov 17 21:12:53 1998
***************
*** 1,3 ****
--- 1,7 ----
+ This README is for the 2.4 version.
+ Look file README.ME+ for the 2.4ME+ version.
+ 
+ ------------------------------------------------------------------
  This is the 2.4 (USENET) version of the Elm Mail System
  
  See the NOTICE and Instruct files for further details.
Index: elm2.4.ME+.50/config.h.SH
*** elm2.4.25/config.h.SH	Mon May 30 19:55:57 1994
--- elm2.4.ME+.50/config.h.SH	Tue Nov 17 21:12:54 1998
***************
*** 56,68 ****
   */
  #$d_memcpy	MEMCPY		/**/
  
- /* MKDIR:
-  *	This symbol, if defined, indicates that the mkdir routine is available
-  *	to create directories.  Otherwise you should fork off a new process to
-  *	exec /bin/mkdir.
-  */
- #$d_mkdir	MKDIR		/**/
- 
  /* RENAME:
   *	This symbol, if defined, indicates that the rename routine is available
   *	to rename files.  Otherwise you should do the unlink(), link(), unlink()
--- 56,61 ----
***************
*** 82,107 ****
   */
  #$d_whoami	WHOAMI		/**/
  
! /* PREFSHELL:
!  *	This symbol contains the full name of the preferred user shell on this
!  *	system.  Usual values are /bin/csh, /bin/ksh, /bin/sh.
!  */
! #define PREFSHELL "$prefshell"		/**/
! 
! /* EUNICE:
!  *	This symbol, if defined, indicates that the program is being compiled
!  *	under the EUNICE package under VMS.  The program will need to handle
!  *	things like files that don't go away the first time you unlink them,
!  *	due to version numbering.  It will also need to compensate for lack
!  *	of a respectable link() command.
!  */
! /* VMS:
!  *	This symbol, if defined, indicates that the program is running under
!  *	VMS.  It is currently only set in conjunction with the EUNICE symbol.
   */
! #$d_eunice	EUNICE		/**/
! #$d_eunice	VMS		/**/
  
  /* CONFIGURE_DATE
   *	This symbol contains the last date that configure was run for elm -v output.
   */
--- 75,95 ----
   */
  #$d_whoami	WHOAMI		/**/
  
! /* POLL:
!  *	This symbol, if defined, indicates that the program may include
!  *	poll.h.
!  */
! #$d_poll	POLL		/**/
! 
! /* I_INTTYPES:
!  *	This symbol, if defined, indicates that the program may include
!  *	inttypes.h.
   */
! #$d_inttypes	I_INTTYPES		/**/
! #$d_nointtypes NO_INTTYPES		/**/
  
+ 
+ 
  /* CONFIGURE_DATE
   *	This symbol contains the last date that configure was run for elm -v output.
   */
***************
*** 185,194 ****
  /* USE_FCNTL_LOCKING
   *	This symbol, if defined, indicates that SYSV style fcntl file locking should be used.
   */
- /* LOCK_DIR
-  *	This symbol is the name of the lock directory for access (not mailbox) locks.
-  *	It will be /usr/spool/locks or /usr/spool/uucp
-  */
  #$d_flock	USE_FLOCK_LOCKING		/**/
  
  #$d_dotlock	USE_DOTLOCK_LOCKING		/**/
--- 173,178 ----
***************
*** 195,202 ****
  
  #$d_fcntlock	USE_FCNTL_LOCKING	/**/
  
- #define		LOCK_DIR	"$lock_dir"	/**/
- 
  /* FTRUNCATE:
   *	This symbol, if defined, indicates that the ftruncate() routine exists.
   */
--- 179,184 ----
***************
*** 235,246 ****
  #$d_index	index strchr	/* cultural */
  #$d_index	rindex strrchr	/*  differences? */
  
- /* INTERNET:
-  *	This symbol, if defined, indicates that there is a mailer available
-  *	which supports internet-style addresses (user@site.domain).
-  */
- #$d_internet	INTERNET	/**/
- 
  /* ISPELL:
   *	This symbol, if defined, indicates that the GNU ispell
   *	spelling checker that is available to Elm.
--- 217,222 ----
***************
*** 292,297 ****
--- 268,314 ----
   */
  #$d_mime	MIME	/**/
  
+ /* MIME:
+  *	This symbol defines default path to metamail.
+  *          Special values:    none         Don't call metamail
+  *                             metamail     Call metamail if environment
+  *                                          variable NOMETAMAIL is not defined
+  */                     
+ #define METAMAIL_PATH    "$metamail_path"
+ 
+ /* USE_8BITMIME
+  *     Mailer accepts -B8BITMIME option
+  *     -B == BODYTYPE
+  */
+ #$d_8bitmime     USE_8BITMIME      /**/
+ 
+ /* USE_BINARYMIME
+  *     Mailer accepts -BBINARYMIME option
+  *     -B == BODYTYPE
+  *
+  * Elm don't yet fully support BINARYMIME: it requires that lines are
+  * terminated with \r\n, Unix's \n isn't sufficient!
+  * That is only partially implemented in this version of Elm.
+  *
+  * Quote from RFC 1830 (Experimental Protocol): 
+  *  SMTP Service Extensions for Transmission of Large and Binary MIME Messages
+  *
+  *      It is important to note that when using BINARYMIME, it is
+  *      especially important to ensure that the MIME message itself is
+  *      properly formed.  In particular, it is essential that text be
+  *      canonically encoded with each line properly terminated with <CR>
+  *      <LF>.  Any transformation of text into non-canonical MIME to
+  *      observe local storage conventions must be reversed before sending
+  *      as BINARYMIME.  The usual line-oriented shortcuts will break if
+  *      used with BINARYMIME.
+  */
+ #$d_binarymime     USE_BINARYMIME      /**/
+ 
+ /*
+  *  If mailer support DSN via options -N -V -R
+  */
+ #$d_dsn            USE_DSN      /**/
+ 
  /* MMDF:
   *	This symbol, if defined, indicates that mailboxes are in
   *	the MMDF format.
***************
*** 398,403 ****
--- 415,422 ----
  
  #$d_sigprocmask	HASSIGPROCMASK	/**/
  
+ #$d_waitpid	HASWAITPID	/**/
+ 
  /* STRSPN:
   *	This symbol, if defined, indicates that the strspn() routine exists.
   */
***************
*** 469,479 ****
  
  #$d_termio	TERMIO		/**/
  
- /* USE_EMBEDDED_ADDRESSES:
-  *	This symbol, if defined, indicates that replyto: and from:
-  *	headers can be trusted.
-  */
- #$d_useembed USE_EMBEDDED_ADDRESSES	 /**/
  
  /* UTIMBUF:
   *	This symbol is defined if this system defines struct utimbuf.
--- 488,493 ----
***************
*** 517,528 ****
   */
  #$i_memory	I_MEMORY	/**/
  
- /* I_STDARG:
-  *	This symbol, if defined, indicates that the file stdarg.h
-  *	should be included instead of varargs
-  */
- #$i_stdarg	I_STDARG	/**/
- 
  /* I_STDLIB:
   *	This symbol, if defined, indicates that the file stdlib.h
   *	should be included instead of declaring the stdlib routines.
--- 531,536 ----
***************
*** 596,605 ****
   *	This symbol, if defined, indicates this is a Xenix system,
   *	for knocking  out the far keyword in selected places.
   */
! /* BSD:
   *	This symbol, if defined, indicates this is a BSD type system,
   */
  #$d_xenix	XENIX	/**/
! #$d_bsd	BSD	/**/
  
  !GROK!THIS!
--- 604,635 ----
   *	This symbol, if defined, indicates this is a Xenix system,
   *	for knocking  out the far keyword in selected places.
   */
! /* BSD_TYPE:
   *	This symbol, if defined, indicates this is a BSD type system,
   */
  #$d_xenix	XENIX	/**/
! #$d_bsd	BSD_TYPE	/**/
  
+ /* USE_PGP:
+  *	This symbol, if defined, means that PGP support should be compiled in.
+  */
+ /* PGP_PATH:
+  *	The path to the PGP binary.
+  */
+ #$d_pgp USE_PGP /**/
+ #ifdef USE_PGP
+ #define PGP_PATH "$pgp_path"
+ #endif
+ 
+ /* USE_REMAILER:
+  *	If defined, includes support for anonymous remailing, chaining, and
+  *      if USE_PGP is defined, encryption.
+  *
+  * FINGER_PATH:
+  *      Path to the finger binary.
+  */
+ #$d_remailer USE_REMAILER /**/
+ #ifdef USE_REMAILER
+ #define FINGER_PATH "$finger_path"
+ #endif
  !GROK!THIS!
Index: elm2.4.ME+.50/doc/Alias.guide
*** elm2.4.25/doc/Alias.guide	Tue Jul 20 06:02:25 1993
--- elm2.4.ME+.50/doc/Alias.guide	Tue Nov 17 21:12:54 1998
***************
*** 1,4 ****
! .\" @(#)$Id: Alias.guide,v 5.7 1993/07/20 03:02:11 syd Exp $
  .\"
  .\"  A guide to the ELM alias system and so on.
  .\"  format with:
--- 1,4 ----
! .\" @(#)$Id: Alias.guide,v 1.2 1998/10/20 19:57:19 hurtta Exp $
  .\"
  .\"  A guide to the ELM alias system and so on.
  .\"  format with:
***************
*** 6,43 ****
  .\"
  .\"  (C) Copyright 1986,1987 Dave Taylor
  .\"  (C) Copyright 1988-1992 Usenet Community Trust
! .\"  Elm is now in the public trust. Bug reports, comments, suggestions, flames
! .\"  etc. should go to:
! .\"	Syd Weinstein		elm@DSI.COM (dsinc!elm)
! .\"
! .\"  $Log: Alias.guide,v $
! .\" Revision 5.7  1993/07/20  03:02:11  syd
! .\" drop useless reference to Elm address validation
! .\" From: Syd
! .\"
! .\" Revision 5.6  1993/07/20  02:16:26  syd
! .\" Explain that newalias for global takes -g argument
! .\" From: Syd via request from Manfred Ebery
! .\"
! .\" Revision 5.5  1993/04/12  01:45:22  syd
! .\" Update for quotes
! .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
! .\"
! .\" Revision 5.4  1992/12/24  23:48:05  syd
! .\" make Nroff not use co symbol, just the word
! .\" From: Syd via request from Tim Pierce
! .\"
! .\" Revision 5.3  1992/12/20  05:06:19  syd
! .\" Here are the doc changes for my additions to the alias system and
! .\" the new switches to listalias.
! .\" From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
! .\"
! .\" Revision 5.2  1992/10/17  22:01:01  syd
! .\" corrected typos
! .\" From: David.W.Tamkin@gagme.chi.il.us (David W. Tamkin)
! .\"
! .\" Revision 5.1  1992/10/03  20:51:50  syd
! .\" Initial checkin as of 2.4 Release at PL0
  .\"
  .\"
  .\"
--- 6,12 ----
  .\"
  .\"  (C) Copyright 1986,1987 Dave Taylor
  .\"  (C) Copyright 1988-1992 Usenet Community Trust
! .\"  Elm is now in the public trust. 
  .\"
  .\"
  .\"
Index: elm2.4.ME+.50/doc/Config.guid
*** elm2.4.25/doc/Config.guid	Fri Jul 30 05:23:26 1993
--- elm2.4.ME+.50/doc/Config.guid	Tue Nov 17 21:12:54 1998
***************
*** 1,4 ****
! .\" @(#)$Id: Config.guid,v 5.9 1993/07/30 02:23:21 syd Exp $
  .\"
  .\"  A guide to the ELM alias system and so on.
  .\"  format with:
--- 1,4 ----
! .\" @(#)$Id: Config.guid,v 1.1.1.1 1998/10/15 15:36:39 hurtta Exp $
  .\"
  .\"  A guide to the ELM alias system and so on.
  .\"  format with:
***************
*** 6,52 ****
  .\"
  .\"  (C) Copyright 1986,1987 Dave Taylor
  .\"  (C) Copyright 1988-1992 Usenet Community Trust
- .\"  Elm is now in the public trust. Bug reports, comments, suggestions, flames
- .\"  etc. should go to:
- .\"	Syd Weinstein		elm@DSI.COM (dsinc!elm)
  .\"
- .\"  $Log: Config.guid,v $
- .\" Revision 5.9  1993/07/30  02:23:21  syd
- .\" fix -q to -g in newalias call
  .\"
- .\" Revision 5.8  1993/04/12  04:00:55  syd
- .\" remove unused ALIAS parameters
  .\"
- .\" Revision 5.7  1993/04/12  01:47:45  syd
- .\" Update for quotes
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
  .\"
- .\" Revision 5.6  1992/12/24  23:48:05  syd
- .\" make Nroff not use co symbol, just the word
- .\" From: Syd via request from Tim Pierce
- .\"
- .\" Revision 5.5  1992/11/27  02:51:18  syd
- .\" Make the docs catch up with the code, config.changes -> config.over
- .\" From: Syd
- .\"
- .\" Revision 5.4  1992/11/22  00:49:31  syd
- .\" Add support for a "config.over" file to override Configure decisions.
- .\" From: chip@chinacat.unicom.com (Chip Rosenthal)
- .\"
- .\" Revision 5.3  1992/10/24  13:51:44  syd
- .\" More typos
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.2  1992/10/11  01:15:53  syd
- .\" A cleaned up Config.guid follows.  Corrected some spelling errors,
- .\" and played with some formatting:
- .\" From: David Barr <barr@pop.psu.edu>
- .\"
- .\" Revision 5.1  1992/10/03  20:51:50  syd
- .\" Initial checkin as of 2.4 Release at PL0
- .\"
- .\"
- .\"
  .tm Have we been run through "tbl" first?? I hope so!
  .po 1i
  .ds h0
--- 6,15 ----
***************
*** 248,263 ****
  a lone period into a period and a blank to avoid this problem.
  This symbol is ignored if the \*QHonors Content-Length: header?\*U question
  is answered \f2yes\f1.
- .sp
- .ne 4
- \f3Does your mailer understand INTERNET addresses?\f1
- .sp
- Elm works with systems that can process the \*q@\*u character of
- Internet format addresses or with the \*q!\*u format of \f2uucp\f1
- addresses.  If your MTA understands the \*q@\*u format addresses, they
- should be used and this question answered \f2yes\f1.  If messages
- bounce when you send them with \*q@\*u format addresses (such as
- \*Qelm@dsi.com\*U), then answer this question \f2no\f1.
  .sp
  .ne 4
  \f3Am I going to be running as a setgid program?\f1
--- 211,216 ----
Index: elm2.4.ME+.50/doc/Elm.cover
*** elm2.4.25/doc/Elm.cover	Sat May  8 22:58:27 1993
--- elm2.4.ME+.50/doc/Elm.cover	Tue Nov 17 21:12:54 1998
***************
*** 1,31 ****
! .\" @(#)$Id: Elm.cover,v 5.4 1993/05/08 19:58:20 syd Exp $
  .\"
  .\"  Cover sheet for the ELM mail system...
  .\"  format with 
  .\"	troff tmac.n Elm.cover > Coversheet.fmtd'
  .\"
! .\"  Elm is now in the public trust. Bug reports, comments, suggestions, flames
! .\"  etc. should go to:
! .\"	Syd Weinstein		elm@DSI.COM (dsinc!elm)
  .\"
  .\"  (C) Copyright 1986,1987 Dave Taylor
  .\"  (C) Copyright 1988-1992 Usenet Community Trust
- .\"
- .\"  $Log: Elm.cover,v $
- .\" Revision 5.4  1993/05/08  19:58:20  syd
- .\" use new quote macros
- .\" From: Syd
- .\"
- .\" Revision 5.3  1992/12/24  23:48:05  syd
- .\" make Nroff not use co symbol, just the word
- .\" From: Syd via request from Tim Pierce
- .\"
- .\" Revision 5.2  1992/10/24  14:13:39  syd
- .\" Add notice file
- .\"
- .\" Revision 5.1  1992/10/03  20:51:50  syd
- .\" Initial checkin as of 2.4 Release at PL0
- .\"
  .\" 
  .\"  
  .po 1i
--- 1,13 ----
! .\" @(#)$Id: Elm.cover,v 1.2 1998/10/20 19:57:19 hurtta Exp $
  .\"
  .\"  Cover sheet for the ELM mail system...
  .\"  format with 
  .\"	troff tmac.n Elm.cover > Coversheet.fmtd'
  .\"
! .\"  Elm is now in the public trust. 
  .\"
  .\"  (C) Copyright 1986,1987 Dave Taylor
  .\"  (C) Copyright 1988-1992 Usenet Community Trust
  .\" 
  .\"  
  .po 1i
Index: elm2.4.ME+.50/doc/Filter.guid
*** elm2.4.25/doc/Filter.guid	Fri Apr 16 07:11:54 1993
--- elm2.4.ME+.50/doc/Filter.guid	Tue Nov 17 21:12:54 1998
***************
*** 1,4 ****
! .\" @(#)$Id: Filter.guid,v 5.7 1993/04/16 04:11:29 syd Exp $
  .\"
  .\"  A guide to the Elm Filter program
  .\"  format with:
--- 1,4 ----
! .\" @(#)$Id: Filter.guid,v 1.2 1998/10/20 19:57:19 hurtta Exp $
  .\"
  .\"  A guide to the Elm Filter program
  .\"  format with:
***************
*** 7,48 ****
  .\"  (C) Copyright 1986,1987 Dave Taylor
  .\"  (C) Copyright 1988-1992 Usenet Community Trust
  .\"
! .\"  Elm is now in the public trust. Bug reports, comments, suggestions, flames
! .\"  etc. should go to:
! .\"	Syd Weinstein		elm@DSI.COM (dsinc!elm)
! .\"
! .\"  $Log: Filter.guid,v $
! .\" Revision 5.7  1993/04/16  04:11:29  syd
! .\" Fix wrong variable used in shell script
! .\" From: Bruce Tindall <sasbmt@unx.sas.com>
! .\"
! .\" Revision 5.6  1993/04/12  01:46:12  syd
! .\" Update for quotes
! .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
! .\"
! .\" Revision 5.5  1993/01/27  19:45:15  syd
! .\" Filter turns spaces in quoted strings into _ and then back again. This destroys
! .\" any _ that where there in the first place. This patch removes that.
! .\" Also fixed a minor bug where 'filter -r' wrote out the wrong thing if the
! .\" relation in a rule was '~'.
! .\" From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
! .\"
! .\" Revision 5.4  1993/01/27  19:40:01  syd
! .\" I implemented a change to filter's default verbose message format
! .\" including %x %X style date and time along with username
! .\" From: mark@drd.com (Mark Lawrence)
! .\"
! .\" Revision 5.3  1992/12/24  23:48:05  syd
! .\" make Nroff not use co symbol, just the word
! .\" From: Syd via request from Tim Pierce
! .\"
! .\" Revision 5.2  1992/11/15  01:41:50  syd
! .\" Add regexp processing to filter.
! .\" Add execc operator
! .\" From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
! .\"
! .\" Revision 5.1  1992/10/03  20:51:50  syd
! .\" Initial checkin as of 2.4 Release at PL0
  .\"
  .\"
  .po 1i
--- 7,13 ----
  .\"  (C) Copyright 1986,1987 Dave Taylor
  .\"  (C) Copyright 1988-1992 Usenet Community Trust
  .\"
! .\"  Elm is now in the public trust. 
  .\"
  .\"
  .po 1i
Index: elm2.4.ME+.50/doc/Form.guide
*** elm2.4.25/doc/Form.guide	Mon Apr 12 04:47:13 1993
--- elm2.4.ME+.50/doc/Form.guide	Tue Nov 17 21:12:54 1998
***************
*** 1,39 ****
! .\" @(#)$Id: Form.guide,v 5.4 1993/04/12 01:47:13 syd Exp $
  .\"
  .\"  A guide to using the Elm Forms mode
  .\"  format with:
  .\"	'troff tmac.n - > Forms.format'
  .\"
! .\"  Elm is now in the public trust. Bug reports, comments, suggestions, flames
! .\"  etc. should go to:
! .\"	Syd Weinstein		elm@DSI.COM (dsinc!elm)
  .\"
  .\"  Copyright (c) 1988-1992 USENET Community Trust
  .\"  Copyright (c) 1986,1987 Dave Taylor
- .\"
- .\"  $Log: Form.guide,v $
- .\" Revision 5.4  1993/04/12  01:47:13  syd
- .\" Update for quotes
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.3  1992/12/24  23:48:05  syd
- .\" make Nroff not use co symbol, just the word
- .\" From: Syd via request from Tim Pierce
- .\"
- .\" Revision 5.2  1992/10/11  01:33:36  syd
- .\" fixed a bug in the .lp macro in doc/tmac.n.  The lp macros is always
- .\" called with a unit specified for the second argument, however, the
- .\" macro added a "n" unit specifier to that argument.  The following patch
- .\" fixes this problem.
- .\"
- .\" The various .guide books use the troff .tl macro liberally, but often the
- .\" extra ' characters needed at the end of the lines to explicitly specify
- .\" the trailing nulls fields were left off.  The following patch fixes the
- .\" erroneous lines.
- .\" From: Larry Philps <larryp@sco.COM>
- .\"
- .\" Revision 5.1  1992/10/03  20:51:50  syd
- .\" Initial checkin as of 2.4 Release at PL0
  .\"
  .\"
  .\"
--- 1,13 ----
! .\" @(#)$Id: Form.guide,v 1.2 1998/10/20 19:57:19 hurtta Exp $
  .\"
  .\"  A guide to using the Elm Forms mode
  .\"  format with:
  .\"	'troff tmac.n - > Forms.format'
  .\"
! .\"  Elm is now in the public trust. 
  .\"
  .\"  Copyright (c) 1988-1992 USENET Community Trust
  .\"  Copyright (c) 1986,1987 Dave Taylor
  .\"
  .\"
  .\"
Index: elm2.4.ME+.50/doc/Makefile.SH
*** elm2.4.25/doc/Makefile.SH	Thu Mar 10 19:20:29 1994
--- elm2.4.ME+.50/doc/Makefile.SH	Tue Nov 17 21:12:54 1998
***************
*** 16,82 ****
  echo "Extracting doc/Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
  #
! # $Id: Makefile.SH,v 5.12 1994/03/10 17:20:23 syd Exp $
  #
  #  Makefile for the documentation of the ELM mail system
  #
  #         (C) Copyright 1988-1992, USENET Community Trust
  #
- #  $Log: Makefile.SH,v $
- # Revision 5.12  1994/03/10  17:20:23  syd
- # Remove autoreply
- # From: Syd
  #
- # Revision 5.11  1993/04/12  02:12:07  syd
- # Added elmalias.1 man page.  Updated Users.guide to mention elmalias.
- # From: chip@chinacat.unicom.com (Chip Rosenthal)
- #
- # Revision 5.10  1993/01/20  03:11:51  syd
- # During 'make uninstall', an error occurs with the make for doc/,
- # due to a wrongly-extended "if" statement in the Makefile.
- # From: Allan Kugel <hico2!hico3!allan@tsdiag.ocpt.ccur.com>
- #
- # Revision 5.9  1992/12/13  18:00:05  syd
- # Add one more missing rm of a previously packed man page
- # From: Bo Asbjorn Muldbak <bam@jutland.ColumbiaSC.NCR.COM>
- #
- # Revision 5.8  1992/12/12  01:28:50  syd
- # Remove the old packed manual page before trying to pack the new one.
- # From: Tom Moore <tmoore@fievel.DaytonOH.NCR.COM>
- #
- # Revision 5.7  1992/12/07  05:05:27  syd
- # fix ; placement
- # From: Syd
- #
- # Revision 5.6  1992/12/07  03:28:35  syd
- # add else clause with true to TEST lines as some Makefiles exit if
- # the if construct doesnt execute a clause as the if returns an error
- # status.
- # From: Syd via requests from several people
- #
- # Revision 5.5  1992/12/07  02:17:14  syd
- # Add missing -n flag to doc makefile.
- # From: gwh@dogmatix.inmos.co.uk
- #
- # Revision 5.4  1992/11/22  00:47:02  syd
- # Change the way Configure and doc/Makefile.SH deal with installing
- # man pages.
- # From: Tom Moore <tmoore@wnas.DaytonOH.NCR.COM>
- #
- # Revision 5.3  1992/11/07  16:13:00  syd
- # Limit test arguments to -f instead of -x as several shells and
- # their resulting test commands dont have -x
- # From: Syd via request from Tim Pierce
- #
- # Revision 5.2  1992/10/30  21:06:09  syd
- # add missing MAKE variable definition
- # From: syd via note from Keith Petersen w8sdz@tacom-emh1.army.mil
- #
- # Revision 5.1  1992/10/03  20:51:50  syd
- # Initial checkin as of 2.4 Release at PL0
- #
- # 
- #
  # Variables
  #	Variables established by Configure
  CHMOD		=	$chmod
--- 16,28 ----
  echo "Extracting doc/Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
  #
! # $Id: Makefile.SH,v 1.2 1998/10/20 19:57:19 hurtta Exp $
  #
  #  Makefile for the documentation of the ELM mail system
  #
  #         (C) Copyright 1988-1992, USENET Community Trust
  #
  #
  # Variables
  #	Variables established by Configure
  CHMOD		=	$chmod
***************
*** 114,120 ****
  			$(MAN)/elm$(MANEXT)		\
  			$(MAN)/elmalias$(MANEXT)	\
  			$(MAN)/fastmail$(MANEXT)	\
- 			$(MAN)/filter$(MANEXT)		\
  			$(MAN)/frm$(MANEXT)		\
  			$(MAN)/listalias$(MANEXT)	\
  			$(MAN)/messages$(MANEXT)	\
--- 60,65 ----
***************
*** 123,128 ****
--- 68,75 ----
  			$(MAN)/printmail$(MANEXT)	\
  			$(MAN)/readmsg$(MANEXT)
  
+ #			$(MAN)/filter$(MANEXT)		
+ 
  # List of installed catman pages (except for wnemail.1 - handled differently)
  CATMAN_LIST	=	$(CATMAN)/answer$(CATMANEXT)$(SUFFIX)	\
  			$(CATMAN)/checkalias$(CATMANEXT)$(SUFFIX)\
***************
*** 129,135 ****
  			$(CATMAN)/elm$(CATMANEXT)$(SUFFIX)	\
  			$(CATMAN)/elmalias$(CATMANEXT)$(SUFFIX)\
  			$(CATMAN)/fastmail$(CATMANEXT)$(SUFFIX)	\
- 			$(CATMAN)/filter$(CATMANEXT)$(SUFFIX)	\
  			$(CATMAN)/frm$(CATMANEXT)$(SUFFIX)	\
  			$(CATMAN)/listalias$(CATMANEXT)$(SUFFIX)	\
  			$(CATMAN)/messages$(CATMANEXT)$(SUFFIX)	\
--- 76,81 ----
***************
*** 138,143 ****
--- 84,91 ----
  			$(CATMAN)/printmail$(CATMANEXT)$(SUFFIX)	\
  			$(CATMAN)/readmsg$(CATMANEXT)$(SUFFIX)
  
+ #			$(CATMAN)/filter$(CATMANEXT)$(SUFFIX)
+ 
  # List of formatted pages for catman
  FORMATTED_PAGES_LIST =	catman/answer$(CATMANEXT)$(SUFFIX)	\
  			catman/checkalias$(CATMANEXT)$(SUFFIX)\
***************
*** 144,150 ****
  			catman/elm$(CATMANEXT)$(SUFFIX)	\
  			catman/elmalias$(CATMANEXT)$(SUFFIX)\
  			catman/fastmail$(CATMANEXT)$(SUFFIX)	\
- 			catman/filter$(CATMANEXT)$(SUFFIX)	\
  			catman/frm$(CATMANEXT)$(SUFFIX)	\
  			catman/listalias$(CATMANEXT)$(SUFFIX)	\
  			catman/messages$(CATMANEXT)$(SUFFIX)	\
--- 92,97 ----
***************
*** 153,158 ****
--- 100,107 ----
  			catman/printmail$(CATMANEXT)$(SUFFIX)	\
  			catman/readmsg$(CATMANEXT)$(SUFFIX)
  
+ #			catman/filter$(CATMANEXT)$(SUFFIX)	
+ 
  # List of remotely installed man pages (except for wnemail.1 - handled
  # differently)
  REMOTE_MAN_LIST	=	$(REMOTE)$(MAN)/answer$(MANEXT)	\
***************
*** 160,166 ****
  			$(REMOTE)$(MAN)/elm$(MANEXT)		\
  			$(REMOTE)$(MAN)/elmalias$(MANEXT)	\
  			$(REMOTE)$(MAN)/fastmail$(MANEXT)	\
- 			$(REMOTE)$(MAN)/filter$(MANEXT)	\
  			$(REMOTE)$(MAN)/frm$(MANEXT)		\
  			$(REMOTE)$(MAN)/listalias$(MANEXT)	\
  			$(REMOTE)$(MAN)/messages$(MANEXT)	\
--- 109,114 ----
***************
*** 169,174 ****
--- 117,124 ----
  			$(REMOTE)$(MAN)/printmail$(MANEXT)	\
  			$(REMOTE)$(MAN)/readmsg$(MANEXT)
  
+ #			$(REMOTE)$(MAN)/filter$(MANEXT)	
+ 
  # List of files installed in LIB directory
  LIB_LIST	=	$(LIB)/elm-help.0	\
  			$(LIB)/elm-help.1	\
***************
*** 187,196 ****
  FORMATTED_LIST	=	Alias.fmtd	\
  			Config.fmtd 	\
  			Cover.fmtd	\
- 			Filter.fmtd	\
  			Form.fmtd	\
  			Ref.fmtd	\
  			Users.fmtd
  
  # Targets
  all: 
--- 137,147 ----
  FORMATTED_LIST	=	Alias.fmtd	\
  			Config.fmtd 	\
  			Cover.fmtd	\
  			Form.fmtd	\
  			Ref.fmtd	\
  			Users.fmtd
+ 
+ #			Filter.fmtd	
  
  # Targets
  all: 
Index: elm2.4.ME+.50/doc/Ref.guide
*** elm2.4.25/doc/Ref.guide	Mon Sep 20 02:43:36 1993
--- elm2.4.ME+.50/doc/Ref.guide	Tue Nov 17 21:12:54 1998
***************
*** 1,184 ****
! .\" @(#)$Id: Ref.guide,v 5.30 1993/09/19 23:43:35 syd Exp $
  .\"
  .\"  Reference guide to the Elm mail system.
  .\"  format with
  .\"      troff tmac.n Ref.guide > Ref.format
  .\"
! .\"  Elm is now in the public trust. Bug reports, comments, suggestions, flames
! .\"  etc. should go to:
! .\"	Syd Weinstein		elm@DSI.COM (dsinc!elm)
  .\"
  .\"  (C) Copyright 1986,1987 Dave Taylor
  .\"  (C) Copyright 1988-1992 Usenet Community Trust
- .\"
- .\"  $Log: Ref.guide,v $
- .\" Revision 5.30  1993/09/19  23:43:35  syd
- .\" Conform textencoding addition to style standard.
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.29  1993/08/23  02:53:52  syd
- .\" Added some documentation for textencoding variable.
- .\" From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
- .\"
- .\" Revision 5.28  1993/08/10  21:25:09  syd
- .\" Correct typo and use hard spaces within quotes in *clear-weed-list* note.
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.27  1993/08/03  18:56:24  syd
- .\" Added text about how the weedout list works w.r.t From: and From_
- .\" From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
- .\"
- .\" Revision 5.26  1993/07/20  02:43:05  syd
- .\" [ Patch description ]
- .\" Update the example elmrc and move a couple out of order variable
- .\" descriptions.
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.25  1993/05/14  03:56:39  syd
- .\" Moved the new numeric variables to the Numeric Variables section and
- .\" applied the quoting/highlight policy to them.
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.24  1993/05/08  20:08:43  syd
- .\" add sleepmsg parameter
- .\"
- .\" Revision 5.23  1993/05/08  20:00:22  syd
- .\" fix mail added >From lines
- .\" From: Syd
- .\"
- .\" Revision 5.22  1993/05/08  18:56:16  syd
- .\" created a new elmrc variable named "readmsginc".  This specifies an
- .\" increment by which the message count is updated.  If this variable is
- .\" set to, say, 25, then the message count will only be updated every 25
- .\" messages, displaying 0, 25, 50, 75, and so forth.  The default value
- .\" of 1 will cause Elm to behave exactly as it currently does in PL21.
- .\" From: Eric Peterson <epeterso@encore.com>
- .\"
- .\" Revision 5.21  1993/04/12  03:15:41  syd
- .\" These patches makes 'T' (since it was free) do a Tag and Move command in the
- .\" index and alias page, and in the builtin pager.
- .\" In the alias help in src/alias.c, there is a tolower done on the character
- .\" one wants help for.  This is clearly wrong.
- .\" From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
- .\"
- .\" Revision 5.20  1993/04/12  01:44:20  syd
- .\" Update for quotes
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.19  1993/01/27  20:57:47  syd
- .\" Corrections to PL21 Alpha docs and consistent punctuation use in help files.
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.18  1993/01/20  04:01:07  syd
- .\" Adds a new integer parameter builtinlines.
- .\" if (builtinlines < 0) and (the length of the message < LINES on
- .\"       screen + builtinlines) use internal.
- .\" if (builtinlines > 0) and (length of message < builtinlines)
- .\" 	use internal pager.
- .\" if (builtinlines = 0) or none of the above conditions hold, use the
- .\" external pager if defined.
- .\" From: "John P. Rouillard" <rouilj@ra.cs.umb.edu>
- .\"
- .\" Revision 5.17  1993/01/19  04:52:19  syd
- .\" 	add c)hange alias command to alias helpfile
- .\" 	if a deleted alias is changed, undelete it.  Also added the 'N'
- .\" flag to changed aliases to help remind the user.  Documented it.
- .\" Note:  if they mark the alias for deletion AFTER making the change it
- .\" WILL be deleted. (and marked accordingly)
- .\" 	modified alias mode title string to indicate when a resync was
- .\" needed.
- .\" 	allow editing alias file when none exist.
- .\" 	Now aliases are check for illegal characters (and WS) and
- .\" addresses are check for illegal WS when they are being entered.  If
- .\" anything illegal is found and message is printed and they keep entering
- .\" the item until they get it right.
- .\" 	I fixed a couple of places where int should be long to match
- .\" the declared type of alias_rec.length
- .\" From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
- .\"
- .\" Revision 5.16  1992/12/24  23:48:05  syd
- .\" make Nroff not use co symbol, just the word
- .\" From: Syd via request from Tim Pierce
- .\"
- .\" Revision 5.15  1992/12/20  05:22:13  syd
- .\" Fix formatting and typograpical problems
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.14  1992/12/20  05:06:19  syd
- .\" Here are the doc changes for my additions to the alias system and
- .\" the new switches to listalias.
- .\" From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
- .\"
- .\" Revision 5.13  1992/12/12  01:27:41  syd
- .\" Make verb and pronoun agree.
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.12  1992/12/07  02:41:21  syd
- .\" This implements the use of SIGUSR1 and SIGUSR2 as discussed on the
- .\" mailing list recently, and adds them to the documentation.
- .\" From: scs@lokkur.dexter.mi.us (Steve Simmons)
- .\"
- .\" Revision 5.11  1992/11/07  19:37:21  syd
- .\" Enhanced printing support.  Added "-I" to readmsg to
- .\" suppress spurious diagnostic messages.
- .\" From: chip@chinacat.unicom.com (Chip Rosenthal)
- .\"
- .\" Revision 5.10  1992/11/07  16:31:15  syd
- .\" another typo (2.4.6 Ref.guide)
- .\" From: David.W.Tamkin@gagme.chi.il.us (David W. Tamkin)
- .\"
- .\" Revision 5.9  1992/10/30  20:56:37  syd
- .\" Things I found in doc/Ref.guide looking over patches 4 & 5:
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.8  1992/10/24  13:53:16  syd
- .\" I think all these are typos
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.7  1992/10/24  13:44:41  syd
- .\" There is now an additional elmrc option "displaycharset", which
- .\" sets the charset supported on your terminal. This is to prevent
- .\" elm from calling out to metamail too often.
- .\" Plus a slight documentation update for MIME composition (added examples)
- .\" From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
- .\"
- .\" Revision 5.6  1992/10/24  13:25:41  syd
- .\" In our global elm.rc I keep the four options as below
- .\"
- .\" 	confirmappend = OFF	Don't confirm every append to any file.
- .\" 	confirmcreate = ON	Confirm creation of every new file.
- .\" 	confirmfiles = ON	Confirm append to non folder files though.
- .\" 	confirmfolders = ON	In case someone does not want to be asked
- .\" 				every time when creating a new file try
- .\" 				to confirm creation of folders though.
- .\" From: Jukka Ukkonen <ukkonen@csc.fi>
- .\"
- .\" Revision 5.5  1992/10/17  22:58:57  syd
- .\" patch to make elm use (or in my case, not use) termcap/terminfo ti/te.
- .\" From: Graham Hudspith <gwh@inmos.co.uk>
- .\"
- .\" Revision 5.4  1992/10/17  22:01:01  syd
- .\" corrected typos
- .\" From: David.W.Tamkin@gagme.chi.il.us (David W. Tamkin)
- .\"
- .\" Revision 5.3  1992/10/11  01:33:36  syd
- .\" fixed a bug in the .lp macro in doc/tmac.n.  The lp macros is always
- .\" called with a unit specified for the second argument, however, the
- .\" macro added a "n" unit specifier to that argument.  The following patch
- .\" fixes this problem.
- .\"
- .\" The various .guide books use the troff .tl macro liberally, but often the
- .\" extra ' characters needed at the end of the lines to explicitly specify
- .\" the trailing nulls fields were left off.  The following patch fixes the
- .\" erroneous lines.
- .\" From: Larry Philps <larryp@sco.COM>
- .\"
- .\" Revision 5.2  1992/10/04  01:15:43  syd
- .\" Emphasize that hostdomain, hostname and hostfullname must all be specified
- .\" if one is specified in elmrc file.
- .\"
- .\" Revision 5.1  1992/10/03  20:51:50  syd
- .\" Initial checkin as of 2.4 Release at PL0
  .\"
  .\"
  .\"
--- 1,13 ----
! .\" @(#)$Id: Ref.guide,v 1.2 1998/10/20 19:57:19 hurtta Exp $
  .\"
  .\"  Reference guide to the Elm mail system.
  .\"  format with
  .\"      troff tmac.n Ref.guide > Ref.format
  .\"
! .\"  Elm is now in the public trust. 
  .\"
  .\"  (C) Copyright 1986,1987 Dave Taylor
  .\"  (C) Copyright 1988-1992 Usenet Community Trust
  .\"
  .\"
  .\"
Index: elm2.4.ME+.50/doc/Users.guide
*** elm2.4.25/doc/Users.guide	Thu Mar 10 19:21:24 1994
--- elm2.4.ME+.50/doc/Users.guide	Tue Nov 17 21:12:54 1998
***************
*** 1,59 ****
! .\" @(#)$Id: Users.guide,v 5.9 1994/03/10 17:21:21 syd Exp $
  .\"
  .\"  Users guide to the ELM mail system.
  .\"  format with:
  .\"	'tbl Users.guide | troff tmac.n - > Users.fmtd'
  .\"
! .\"  Elm is now in the public trust. Bug reports, comments, suggestions, flames
! .\"  etc. should go to:
! .\"	Syd Weinstein		elm@DSI.COM (dsinc!elm)
  .\"
  .\"  (C) Copyright 1986,1987 Dave Taylor
  .\"  (C) Copyright 1988-1992 Usenet Community Trust
- .\"
- .\"  $Log: Users.guide,v $
- .\" Revision 5.9  1994/03/10  17:21:21  syd
- .\" remove autoreply
- .\"
- .\" Revision 5.8  1993/05/08  20:00:22  syd
- .\" fix mail added >From lines
- .\" From: Syd
- .\"
- .\" Revision 5.7  1993/04/12  02:12:07  syd
- .\" Added elmalias.1 man page.  Updated Users.guide to mention elmalias.
- .\" From: chip@chinacat.unicom.com (Chip Rosenthal)
- .\"
- .\" Revision 5.6  1993/04/12  01:42:16  syd
- .\" Update for quotes
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.5  1992/12/24  23:48:05  syd
- .\" make Nroff not use co symbol, just the word
- .\" From: Syd via request from Tim Pierce
- .\"
- .\" Revision 5.4  1992/12/11  02:01:13  syd
- .\" fix Obvious typos.
- .\" From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
- .\"
- .\" Revision 5.3  1992/10/17  21:59:56  syd
- .\" Fix spelling of name
- .\" From: Larry Philps <larryp@sco.COM>
- .\"
- .\" Revision 5.2  1992/10/11  01:33:36  syd
- .\" fixed a bug in the .lp macro in doc/tmac.n.  The lp macros is always
- .\" called with a unit specified for the second argument, however, the
- .\" macro added a "n" unit specifier to that argument.  The following patch
- .\" fixes this problem.
- .\"
- .\" The various .guide books use the troff .tl macro liberally, but often the
- .\" extra ' characters needed at the end of the lines to explicitly specify
- .\" the trailing nulls fields were left off.  The following patch fixes the
- .\" erroneous lines.
- .\" From: Larry Philps <larryp@sco.COM>
- .\"
- .\" Revision 5.1  1992/10/03  20:51:50  syd
- .\" Initial checkin as of 2.4 Release at PL0
- .\"
  .\"
  .\"
  .tm I trust we've run this through "tbl" first...
--- 1,13 ----
! .\" @(#)$Id: Users.guide,v 1.2 1998/10/20 19:57:20 hurtta Exp $
  .\"
  .\"  Users guide to the ELM mail system.
  .\"  format with:
  .\"	'tbl Users.guide | troff tmac.n - > Users.fmtd'
  .\"
! .\"  Elm is now in the public trust. 
  .\"
  .\"  (C) Copyright 1986,1987 Dave Taylor
  .\"  (C) Copyright 1988-1992 Usenet Community Trust
  .\"
  .\"
  .tm I trust we've run this through "tbl" first...
Index: elm2.4.ME+.50/doc/elm-help.0
*** elm2.4.25/doc/elm-help.0	Mon Apr 12 06:13:09 1993
--- elm2.4.ME+.50/doc/elm-help.0	Tue Nov 17 21:12:54 1998
***************
*** 1,5 ****
  
!         Command                      Elm 2.4 Action
  
            <RETURN>,<SPACE>      Display current message
             |                    Pipe current message or tagged messages to
--- 1,5 ----
  
!         Command                      Elm 2.4ME+ Action
  
            <RETURN>,<SPACE>      Display current message
             |                    Pipe current message or tagged messages to
***************
*** 24,35 ****
--- 24,38 ----
             c                    Change to another folder
             d                    Delete current message
            ^D                    Delete messages with a specified pattern
+           ^E                    Extract PGP public keys from current message
             e                    Edit current folder
             f                    Forward current message
+           ^F                    Forget PGP passphrase
             g                    Group (all recipients) reply to current message
             h                    Headers displayed with message
             J                    Increment current message by one
             j, <DOWN>            Advance to next undeleted message
+           ^K                    Mail PGP public key(s)
             K                    Decrement current message by one
             k, <UP>              Advance to previous undeleted message
             l                    Limit messages by specified criteria
***************
*** 50,55 ****
--- 53,59 ----
            ^T                    Tag messages with a specified pattern
             u                    Undelete current message
            ^U                    Undelete messages with a specified pattern
+            v                    View attachments in current message.
             x, ^Q                Exit leaving folder untouched, ask permission
                                          if folder changed
             X                    Exit leaving folder untouched, unconditionally
Index: elm2.4.ME+.50/doc/elm-help.3
*** elm2.4.25/doc/elm-help.3	Mon Apr 12 06:13:10 1993
--- elm2.4.ME+.50/doc/elm-help.3	Tue Nov 17 21:12:54 1998
***************
*** 1,5 ****
  
!         Command                      Elm 2.4 Action
  
  
            <RETURN>              Display the current message,
--- 1,5 ----
  
!         Command                      Elm 2.4ME+ Action
  
  
            <RETURN>              Display the current message,
***************
*** 38,43 ****
--- 38,44 ----
             t                    Tag current message for further operations
             T                    Tag current message and go to next message
             u                    Undelete current message
+ 	   v			View attachments in current message.
             x                    Exit leaving folder untouched, ask permission
                                          if folder changed
             X                    Exit leaving folder untouched, unconditionally
Index: elm2.4.ME+.50/doc/elm.1
*** elm2.4.25/doc/elm.1	Fri Dec 25 01:46:52 1992
--- elm2.4.ME+.50/doc/elm.1	Tue Nov 17 21:12:54 1998
***************
*** 74,79 ****
--- 74,84 ----
  .B "  -a"
  Arrow - force the arrow cursor (instead of the inverse bar)
  .TP
+ .B "  -A \fIfile\fR "
+ Attach file. Look also option -i.
+ To get this to work correctly, in file "$HOME/.elm/mime.types"
+ must be mapping from extension of filename to mime type.
+ .TP
  .B "  -c"
  Checkalias - expand the following aliases and return.
  .TP
***************
*** 88,102 ****
--- 93,112 ----
  .TP
  .B "  -i \fIfile\fR  "
  Include - include prepared file in edit buffer for sending.
+ Look also option -A.
  .TP
  .B "  -?"
  Synonymous with the "-h" option.
  .TP
  .B "  -k"
+ Ignored.
+ 
  Keypad - force knowledge of HP terminal keyboard, to allow
  the use of the NEXT, PREV and HOME/SHIFT-HOME keys.
  .TP
  .B "  -K"
+ Ignored.
+ 
  Keypad + softkeys - enable use of softkeys on HP terminals only.
  .TP
  .B "  -m"
***************
*** 110,115 ****
--- 120,129 ----
  .TP
  .B "  -v"
  Version - print version and configuration information.
+ .TP
+ .B "  -w"
+ Write .elm/elmrc in startup. Useful if your .elm/elmrc 
+ have errors.
  .TP
  .B "  -z"
  Zero - don't enter \fBElm\fR if no mail is pending.
Index: elm2.4.ME+.50/doc/elmrc-info
*** elm2.4.25/doc/elmrc-info	Fri Mar 11 23:19:26 1994
--- elm2.4.ME+.50/doc/elmrc-info	Tue Nov 17 21:14:08 1998
***************
*** 1,5 ****
! #@(#)$Id: elmrc-info,v 5.11 1994/03/11 21:19:26 syd Exp $
! # Elm Version 2.4
  #
  #$HDR - magic line to mark comments to put at top of user's elmrc file.
  #
--- 1,5 ----
! #@(#)$Id: elmrc-info,v 1.2 1998/11/08 18:20:15 hurtta Exp $
! # Elm Version 2.4ME+
  #
  #$HDR - magic line to mark comments to put at top of user's elmrc file.
  #
***************
*** 15,20 ****
--- 15,21 ----
  
  shell
  # The shell to use for shell escapes
+ # If not set value from passwd is used
  
  fullname
  # The full user name for outbound mail
***************
*** 22,27 ****
--- 23,31 ----
  maildir
  # where to save my mail to, default directory is "Mail"
  
+ mailpermissions
+ # permissions to be given to newly-created saved mail files, default rw-------
+   
  tmpdir
  # where to place temporary files, default directory is "/tmp"
  
***************
*** 88,96 ****
--- 92,157 ----
  weed
  # enable the weedout list to be read?
  
+ metamail
+ # This tells path of metamail program
+ #
+ # That version (Elm 2.4ME+) does not use Metamail's companion programs 
+ # (suchs as mmencode) directly, but metamail package supposes that
+ # companion programs are installed to search path.
+ #
+ # Special values:   none		Don't call metamail
+ #		    metamail		Don't call metamail if environment
+ #						variable $NOMETAMAIL is defined
+ 
+ noencoding
+ # This control makes it possible to send raw 8bit or binary data when the MTA
+ # doesn't support 8BITMIME and the -B8BITMIME option or
+ # BINARYMIME and the -BBINARYMIME option
+ #
+ # Possible values:
+ #    pass-7bit (0)   : Always convert 8BIT and BINARY data to QUOTED-PRINTABLE 
+ #                      if the MTA doesn't support the -B8BITMIME and 
+ #                      -BBINARYMIME options.
+ #    pass-8bit (1)   : Allow 8bit without -B8BITMIME, but binary data is 
+ #                      encoded
+ #    pass-binary (2) : Allow binary without -BBINARYMIME and and 8bit without 
+ #                      -B8BITMIME
+ #
+ # It is STRONGLY recommended that it be left set to pass-7bit unless you know 
+ # what you are doing!!
+ #
+ # Elm doesn't yet fully support BINARYMIME: it requires that text lines are
+ # terminated with \r\n, Unix's \n isn't sufficient!
+ # That is only partially implemented in this version of Elm.
+ #
+ # Quote from RFC 1830 (Experimental Protocol): 
+ #  SMTP Service Extensions for Transmission of Large and Binary MIME Messages
+ #
+ #      It is important to note that when using BINARYMIME, it is
+ #      especially important to ensure that the MIME message itself is
+ #      properly formed.  In particular, it is essential that text be
+ #      canonically encoded with each line properly terminated with <CR>
+ #      <LF>.  Any transformation of text into non-canonical MIME to
+ #      observe local storage conventions must be reversed before sending
+ #      as BINARYMIME.  The usual line-oriented shortcuts will break if
+ #      used with BINARYMIME.
+ 
+ nohdrencoding
+ # Don't do MIME part 2 (RFC 1522) encoding for 8-bit headers?
+ # Because 8-bit data is not allowed in headers, 
+ # it is STRONGLY recommended that this is left set to OFF
+ 
  noheader
  # when messages are copied into the outbound buffer, don't include headers?
+ # when replying
  
+ noheaderfwd
+ # when messages are copied into the outbound buffer, don't include headers?
+ # when forwarding 	
+ # (Notice that messages are not copiend to outbound buffer when
+ #  mimeworward = ON)
+ 
+ 
  titles
  # display message title when displaying pages of message?
  
***************
*** 164,170 ****
  # do we want to be able to mail out AT&T Mail Forms?
  
  userlevel
! # are we good at it?  0=beginner, 1=intermediate, 2+ = expert!
  
  names
  # just show the names when expanding aliases?
--- 225,231 ----
  # do we want to be able to mail out AT&T Mail Forms?
  
  userlevel
! # are we good at it?  beginner (0), intermediate (1), expert (2)
  
  names
  # just show the names when expanding aliases?
***************
*** 193,203 ****
  charset
  # name of Character Set used with MIME text/plain Content-type
  # US-ASCII is default. Be aware that if you use a national charset
! # elm probably needs metamail to display US-ASCII.
  
  displaycharset
  # name of Character Set which the display supports. This is independent
! # of the above "charset".
  
  compatcharsets
  # list of Character Sets, which are more or less a superset of US-ASCII
--- 254,273 ----
  charset
  # name of Character Set used with MIME text/plain Content-type
  # US-ASCII is default. Be aware that if you use a national charset
! # elm probably needs metamail to display US-ASCII. Special value
! # DISPLAY means that Charcter Set used in content-type is same
! # which the display supports (see: displaycharset)
  
  displaycharset
  # name of Character Set which the display supports. This is independent
! # of the above "charset". This is also copied to environment variable 
! # MM_CHARSET when metamail is called. This is used only as default
! # on systems which supports locale. In these systems LC_CTYPE locale
! # is mapped to Character Set. Mapping is given in file elm.mimecharsets
! # on elm library directory or on file .elm/mime.charsets
! 
! dsn-success
! # If TRUE, success Delivery-Status-Notifications are asked by default.
  
  compatcharsets
  # list of Character Sets, which are more or less a superset of US-ASCII
***************
*** 247,250 ****
  textencoding
  # Type of encoding to be put into the MIME Content-Transfer-Encoding header.
  # Usual values are 7bit or 8bit.
! # NOTE: Elm will not encode your message based on this variable.
--- 317,391 ----
  textencoding
  # Type of encoding to be put into the MIME Content-Transfer-Encoding header.
  # Usual values are 7bit or 8bit.
! #
! # -- NOT Used in this version of elm (2.4 PL24 ME7) or ELM 2.4ME+ PLxx (25)
! # Now elm analyzes mail when sending and does that encoding of quoted-printable
! # when necessary.
! 
! showpgppreamble
! # if this variable is ON, display text before PGP armor.
! 
! showto
! # if this variable is ON, Elm will show who the message is to rather than
! # who it is from in the headers display.
! 
! usepgppass
! # If ON, Elm will prompt you for your PGP passphrase and use it whenever
! # necessary to make it more convenient to hand PGP messages.
! 
! keeppassfor
! # The number of seconds Elm should remember your passphrase.  -1 means never
! # expire it.
! 
! askpgpsig
! # If ON, Elm will prompt you for a username with which to sign the pgp
! # message
! 
! pagealternative
! # Should Elm use "pager" for display one part of multipart/alternative,
! # if there are found one part which can be displayed. If not
! # set, Elm uses "pager" for display one part of multipart/alternative,
! # if are parts are displayable.
! 
! pagemultipart
! # Should Elm use "pager" to display MIME multipart messages
! # with unknown subparts or with unknown subtype?
! 
! mimeforward
! # This option controls how Elm will forward messages when MIME is defined.
! #	ON: Causes Elm to send the message as a MIME attachment of type
! #		MESSAGE/RFC822.  Highly recommended when forwarding MIME
! #		messages so that the receiver can correctly view the message!
! #	OFF: Elm will include the forwarded message in your editor instead
! #		of making it an attachment.
! 
! quoteforward
! # Forwarded messages are quoted like replies, rather than included
! # with "Forwarded message" and "End of forwarded message" banners 
! # above and below. This don't have effect if "mimeforward" is TRUE.
! 
! require-mime-version-for-hdr-encoding
! # If set MIME Part 2 (RFC 1522) decoding is only done when MIME-version
! # header is present. Default: False
! 
! require-mime-version-for-body-encoding
! # If set MIME Part 1 (RFC 1521) decoding is only done when MIME-version
! # header is present. Default: True
! 
! background-wait-time
! # If = 0  wait mailer to completion
! #    > 0  wait background_wait_time seconds for completion
! #         if not completed in this time, let it go to background
! #
! #	  (completion of mailing is still reported if user have
! #	   not exited in that time when mailer have completed)
! 
! pgp
! # What is the path for pgp?
! # Possible values include:
! # 	none		Don't call pgp
! # 	/path		Call metamail via that path, if it is executable
! 
! lock-in-copy
! # If set, elm will lock a folder when trying to save or copy to it.
! # NOTICE: Does not work with dot-locking
Index: elm2.4.ME+.50/doc/elmrc.samp
*** elm2.4.25/doc/elmrc.samp	Sat May  8 23:08:48 1993
--- elm2.4.ME+.50/doc/elmrc.samp	Tue Nov 17 21:14:08 1998
***************
*** 1,193 ****
! #@(#)$Id: elmrc.samp,v 5.5 1993/05/08 20:08:43 syd Exp $
  #
  # .elm/elmrc - options file for the ELM mail system
  #
! # Saved automatically by ELM 2.4 for Elm Development Group
  #
  
! # For yes/no settings with ?, ON means yes, OFF means no
  
! # where to save calendar entries
! calendar = ~/.Agenda
  
! # what editor to use ("none" means simulate Berkeley Mail)
! # '%s' can be used as the temporary filename for the outgoing message
! editor = none
  
! # the character to use in the builtin editor for entering commands
! escape = ~
  
! # the full user name for outbound mail
! fullname = Elm Development Group
  
! # where to save received messages to, default file is "=received"
! receivedmail = $HOME/Mail/received
  
! # where to save my mail to, default directory is "Mail"
! maildir = /users/elmdev/Mail
  
! #directory to hold my temporary files to avoid NFS cross mount problems
! tmpdir = /users/elmdev/Mail/tmp
  
! # program to use for displaying messages ('builtin' is recommended)
! pager = builtin
  
! # prefix sequence for indenting included message text in outgoing messages...
! prefix = >_
  
! # how to print a message ('%s' is the filename)
! print = lpr -Plw2 %s
  
  # attribution string for replies ('%s' is the author of original message)
! attribution = According to %s:
! 
! # where to save copies of outgoing mail to, default file is "=sent"
! sentmail = /users/elmdev/Mail/mail.sent
  
! # the shell to use for shell escapes
! shell = /bin/csh
  
! # local ".signature" file to append to appropriate messages...
! localsignature = localsig
  
! # remote ".signature" file to append to appropriate messages...
! remotesignature =  remotesig
  
! # do we want dashes above signatures? (News 2.11 compatibility and convention)
! sigdashes = ON
  
! # how to sort folders, "Reverse Sent" by default
! sortby = Reverse-Received
  
! # should the default be to delete messages we've marked for deletion?
! alwaysdelete = ON
  
! # should the default be to store read messages to the "received" folder?
! alwaysstore = ON
  
! # should the default be to keep unread messages in the incoming mailbox?
! alwayskeep = ON
  
! # should we use the "->" rather than the inverse video bar?
! arrow = OFF
  
! # should the message disposition questions be displayed(ON) or
! # auto-answered(OFF) with the default answers when we resync or change folders?
! ask = ON
  
! # would you like to be asked for Carbon-Copies information each msg?
! askcc = ON
  
! # automatically copy message being replied to into buffer? 
! autocopy = OFF
  
! # threshold for bouncing copies of remote uucp messages...
! # zero = disable function.
! bounceback = 0
  
! # save a copy of all outbound messages?
! copy = ON
  
  # do we want to be able to mail out AT&T Mail Forms?
! forms = OFF
  
  # should we keep folders from which all messages are deleted?
! keepempty = OFF
  
! # we're running on an HP terminal and want HOME, PREV, NEXT, etc...
! keypad = OFF
  
  # should we display the three-line 'mini' menu?
! menu = ON
  
  # would you like a copy of a message you send to an alias you are on?
! metoo = OFF
  
  # when using the page commands (+ - <NEXT> <PREV>) change the current
  # message pointer...?
  movepage = ON
  
  # just show the names when expanding aliases?
! names = ON
  
  # when messages are copied into the outbound buffer, don't include headers?
! noheader = ON
  
  # start up by pointing to the first new message received, if possible?
! pointnew = ON
  
  # prompt for a command after the external pager exits?
! promptafter = ON
  
! # emulate the mailx message increment mode (only increment after something
! # has been 'done' to a message, either saved or deleted, as opposed to 
! # simply each time something is touched)?
! resolve = ON
  
! # save messages, incoming and outbound, by login name of sender/recipient?
! savename = ON
  
! # save outbound messages by login name of sender/recipient even if the
! # associated folder doesn't already exist?
! forcename = OFF
  
! # are we running on an HP terminal and want HOME, PREV, NEXT, etc...?
! # (this implies "keypad=ON" too)
! softkeys = OFF
  
! # set the main prompt timeout for resynching...
! timeout = 60
  
! # display message title when displaying pages of message?
! titles = ON
  
! # are we good at it?  0=beginner, 1=intermediate, 2+ = expert!
! userlevel = 2
  
! # enable the weedout list to be read?
! weed = ON
  
! # what headers I DON'T want to see, ever.
! weedout = "Path:" "Via:" "Sent:" "Date" "Status:" "Original" "Phase" 
! 	"Subject:" "Fruit" "Sun" "Lat" "Buzzword" "Return" "Posted" 
! 	"Telephone" "Postal-Address" "Origin" "X-Sent-By-Nmail-V" "Resent" 
! 	"X-Location" "Source" "Mood" "Neuron" "Libido" "To:" "X-Mailer:" 
! 	"Full-Name:" "X-HPMAIL" "Cc:" "cc:" "Mmdf" "Network-" "Really-" 
! 	"Sender:" "Post" "Message-" "Relay-" "Article-" "Lines:" 
! 	"Approved:" "Xref:" "Organization:" 	"*end-of-user-headers*"
  
! # alternative addresses that I could receive mail from (usually a
! # forwarding mailbox) and don't want to have listed...
! alternatives = dsidev!elmdev  dsirel!elmdev  elmdev@dsidev  elmdev%dsidev  
  
! # list of delivery precedences allowed, or empty to allow anything
! # precedence may be followed by optional ":priority" specification
! precedences = special-delivery:urgent air-mail:urgent first-class bulk junk
  
! # name of Character Set used with MIME text/plain Content-type
! # US-ASCII is default. Be aware that if you use a national charset
! # elm probably needs metamail to display US-ASCII. Elm tries to 
! # know if that charset could display US-ASCII too, but the list
! # of us-ascii compatible charsets is not yet complete
! charset=US-ASCII
  
! # name of Character Set which the display supports. This is independent
! # of the above "charset".
! displaycharset=US-ASCII
  
! # list of Character Sets, which are more or less a superset of US-ASCII
! # so we know that we can display messages with charset=US-ASCII without
! # help of metamail
! compatcharsets = ISO-8859-1 ISO-8859-2 ISO-8859-3 ISO-8859-4 ISO-8859-5 ISO-8859-6 ISO-8859-7 ISO-8859-8 ISO-8859-9
  
  # would you like to use termcap/terminfo ti/te entries?
! usetite = ON
  
! # Value by which message count is incremented while reading a new mailbox.
! # Setting this value to a number larger than one will speed up the time it
! # takes to read a large mailbox when using a slow terminal.
! readmsginc = 5
  
! # time in seconds which Elm will wait after displaying a transient message
! # and before erasing it.  Can be 0 or positive integer.
! sleepmsg = 2
--- 1,371 ----
! #@(#)$Id: elmrc.samp,v 1.2 1998/11/08 18:20:15 hurtta Exp $
  #
  # .elm/elmrc - options file for the ELM mail system
  #
! # Saved automatically by ELM 2.4ME+ PL50 (25) for Kari E. Hurtta
  #
  
! #
! # For yes/no settings, ON means yes, OFF means no.
! #
! # Lines beginning with "#" (like this one!) are comments.
! #
! # The "###" lines mean that you do not have a value set and the system
! # default will be used.  The value shown was the default at the time
! # this file was created.  Yes...the default could have changed between
! # then and now.
! #
  
! # how to sort the alias list, "Name" by default
! aliassortby = Name
  
! # name of editor to use for replies that have text
! ### alteditor = /bin/vi 
  
! # alternative addresses that I could receive mail from (usually a
! # forwarding mailbox) and don't want to have listed...
! # alternatives = 
  
! # should the default be to delete messages we've marked for deletion?
! ### alwaysdelete = OFF
  
! # should the default be to keep unread messages in the incoming mailbox?
! ### alwayskeep = ON
  
! # should the default be to store read messages to the "received" folder?
! ### alwaysstore = OFF
  
! # should we use the "->" rather than the inverse video bar?
! ### arrow = OFF
  
! # should the message disposition questions be displayed(ON) or
! # auto-answered(OFF) with the default answers when we resync or
! # change folders?
! ### ask = ON
  
! # would you like to be asked for Carbon-Copies information each msg?
! ### askcc = ON
  
! # If ON, Elm will prompt you for a username with which to sign the pgp
! # message
! ### askpgpsig = OFF
  
  # attribution string for replies ('%s' is the author of original message)
! attribution = %s:
  
! # automatically copy message being replied to into buffer?
! autocopy = ON
  
! # If = 0  wait mailer to completion
! #    > 0  wait background_wait_time seconds for completion
! #         if not completed in this time, let it go to background
! #
! #	  (completion of mailing is still reported if user have
! #	   not exited in that time when mailer have completed)
! ### background-wait-time = 2
! 
! # This is used to determine if the builtin pager should be used on some
! # messages even if you would usually use an external pager program.
! # There are two ways of determining whether the builtin pager should be
! # used. If you want any message that is shorter than "n" lines to use the
! # internal pager, set the parameter to "n".  If you want the builtin
! # pager to be used if the message is "m" lines shorter than the number of
! # lines on your screen set the parameter to be "-m".  Setting the
! # parameter to zero will result in the message always being sent through
! # your external pager.
! ### builtinlines = -3
  
! # where to save calendar entries
! ### calendar = /home/people/hurtta/
  
! # name of Character Set used with MIME text/plain Content-type
! # US-ASCII is default. Be aware that if you use a national charset
! # elm probably needs metamail to display US-ASCII. Special value
! # DISPLAY means that Charcter Set used in content-type is same
! # which the display supports (see: displaycharset)
! charset = DISPLAY
  
! # list of Character Sets, which are more or less a superset of US-ASCII
! # so we know that we can display messages with charset=US-ASCII without
! # help of metamail
! ### compatcharsets = ISO-8859-1 ISO-8859-2 ISO-8859-3 ISO-8859-4 ISO-8859-5 ISO-8859-7 ISO-8859-8 ISO-8859-9 KOI8-R X-ROMAN8
  
! # list of options that can be configured at the "o)ptions" screen
! ### configoptions = ^_defspyv_am_un_ho
  
! # Should elm always ask the user to confirm before it appends
! # messages to any existing file?
! # This is used for both folders in the user's mail directory
! # and ordinary files.
! ### confirmappend = OFF
! 
! # Should elm always ask the user to confirm before it creates
! # any new files?
! # This is used for both folders in the user's mail directory
! # and ordinary files.
! ### confirmcreate = OFF
! 
! # Should elm ask for confirmation before it appends a message
! # to an existing file that is not a folder in the user's Mail
! # directory?
! # This is used for ordinary files only and does not affect
! # folders in the user's mail directory.
! ### confirmfiles = OFF
! 
! # Should elm ask for confirmation before it creates a new folder
! # in the user's Mail directory?
! # This is used only for folders in the user's mail directory and
! # does not affect ordinary files.
! ### confirmfolders = OFF
  
! # save a copy of all outbound messages?
! copy = ON
  
! # name of Character Set which the display supports. This is independent
! # of the above "charset". This is also copied to environment variable 
! # MM_CHARSET when metamail is called. This is used only as default
! # on systems which supports locale. In these systems LC_CTYPE locale
! # is mapped to Character Set. Mapping is given in file elm.mimecharsets
! # on elm library directory or on file .elm/mime.charsets
! ### displaycharset = ISO-8859-1
  
! # If TRUE, success Delivery-Status-Notifications are asked by default.
! dsn-success = ON
  
! # name of editor for ~e command (when editor="builtin")
! ### easyeditor = emacs
  
! # what editor to use ("none" means simulate Berkeley Mail)
! ### editor = /bin/vi 
  
! # the character to use in the builtin editor for entering commands
! ### escape = ~
  
! # save outbound messages by login name of sender/recipient even if the
! # associated folder doesn't already exist?
! ### forcename = OFF
  
  # do we want to be able to mail out AT&T Mail Forms?
! ### forms = OFF
  
+ # The full user name for outbound mail
+ ### fullname = Kari E. Hurtta
+ 
  # should we keep folders from which all messages are deleted?
! ### keepempty = OFF
! 
! # The number of seconds Elm should remember your passphrase.  -1 means never
! # expire it.
! ### keeppassfor = 300
! 
! # local ".signature" file to append to appropriate messages...
! ### localsignature = 
! 
! # If set, elm will lock a folder when trying to save or copy to it.
! # NOTICE: Does not work with dot-locking
! ### lock-in-copy = ON
! 
! # where to save my mail to, default directory is "Mail"
! ### maildir = /home/people/hurtta/Mail
  
! # permissions to be given to newly-created saved mail files, default rw-------
! ### mailpermissions = rw-------
  
  # should we display the three-line 'mini' menu?
! ### menu = ON
! 
! # This tells path of metamail program
! #
! # That version (Elm 2.4ME+) does not use Metamail's companion programs 
! # (suchs as mmencode) directly, but metamail package supposes that
! # companion programs are installed to search path.
! #
! # Special values:   none		Don't call metamail
! #		    metamail		Don't call metamail if environment
! #						variable $NOMETAMAIL is defined
! ### metamail = /usr/freeware/bin/metamail
  
  # would you like a copy of a message you send to an alias you are on?
! ### metoo = OFF
  
+ # This option controls how Elm will forward messages when MIME is defined.
+ #	ON: Causes Elm to send the message as a MIME attachment of type
+ #		MESSAGE/RFC822.  Highly recommended when forwarding MIME
+ #		messages so that the receiver can correctly view the message!
+ #	OFF: Elm will include the forwarded message in your editor instead
+ #		of making it an attachment.
+ mimeforward = ON
+ 
  # when using the page commands (+ - <NEXT> <PREV>) change the current
  # message pointer...?
  movepage = ON
  
  # just show the names when expanding aliases?
! ### names = ON
! 
! # This control makes it possible to send raw 8bit or binary data when the MTA
! # doesn't support 8BITMIME and the -B8BITMIME option or
! # BINARYMIME and the -BBINARYMIME option
! #
! # Possible values:
! #    pass-7bit (0)   : Always convert 8BIT and BINARY data to QUOTED-PRINTABLE 
! #                      if the MTA doesn't support the -B8BITMIME and 
! #                      -BBINARYMIME options.
! #    pass-8bit (1)   : Allow 8bit without -B8BITMIME, but binary data is 
! #                      encoded
! #    pass-binary (2) : Allow binary without -BBINARYMIME and and 8bit without 
! #                      -B8BITMIME
! #
! # It is STRONGLY recommended that it be left set to pass-7bit unless you know 
! # what you are doing!!
! #
! # Elm doesn't yet fully support BINARYMIME: it requires that text lines are
! # terminated with \r\n, Unix's \n isn't sufficient!
! # That is only partially implemented in this version of Elm.
! #
! # Quote from RFC 1830 (Experimental Protocol): 
! #  SMTP Service Extensions for Transmission of Large and Binary MIME Messages
! #
! #      It is important to note that when using BINARYMIME, it is
! #      especially important to ensure that the MIME message itself is
! #      properly formed.  In particular, it is essential that text be
! #      canonically encoded with each line properly terminated with <CR>
! #      <LF>.  Any transformation of text into non-canonical MIME to
! #      observe local storage conventions must be reversed before sending
! #      as BINARYMIME.  The usual line-oriented shortcuts will break if
! #      used with BINARYMIME.
! ### noencoding = pass-7bit
! 
! # Don't do MIME part 2 (RFC 1522) encoding for 8-bit headers?
! # Because 8-bit data is not allowed in headers, 
! # it is STRONGLY recommended that this is left set to OFF
! ### nohdrencoding = OFF
! 
! # when messages are copied into the outbound buffer, don't include headers?
! # when replying
! ### noheader = ON
  
  # when messages are copied into the outbound buffer, don't include headers?
! # when forwarding 	
! # (Notice that messages are not copiend to outbound buffer when
! #  mimeworward = ON)
! ### noheaderfwd = OFF
! 
! # Should Elm use "pager" for display one part of multipart/alternative,
! # if there are found one part which can be displayed. If not
! # set, Elm uses "pager" for display one part of multipart/alternative,
! # if are parts are displayable.
! ### pagealternative = ON
! 
! # Should Elm use "pager" to display MIME multipart messages
! # with unknown subparts or with unknown subtype?
! ### pagemultipart = OFF
! 
! # program to use for displaying messages ('builtin' is recommended)
! pager = builtin
  
+ # What is the path for pgp?
+ # Possible values include:
+ # 	none		Don't call pgp
+ # 	/path		Call metamail via that path, if it is executable
+ pgp = /usr/local/pgp/bin/pgp
+ 
  # start up by pointing to the first new message received, if possible?
! ### pointnew = ON
! 
! # list of delivery precedences allowed, or empty to allow anything
! # precedence may be followed by optional ":priority" specification
! ### precedences = 
! 
! # prefix sequence for indenting included message text in outgoing messages...
! ### prefix = >_
! 
! # how to print a message ('%s' is the filename)
! print = mpage -o2p -Parth7bw %s
  
  # prompt for a command after the external pager exits?
! ### promptafter = ON
  
! # Forwarded messages are quoted like replies, rather than included
! # with "Forwarded message" and "End of forwarded message" banners 
! # above and below. This don't have effect if "mimeforward" is TRUE.
! ### quoteforward = OFF
  
! # Value by which message count is incremented while reading a new mailbox.
! # Setting this value to a number larger than one will speed up the time it
! # takes to read a large mailbox when using a slow terminal.
! readmsginc = 25
  
! # where to save received messages to, default file is "=received"
! ### receivedmail = =received
  
! # remote ".signature" file to append to appropriate messages...
! ### remotesignature = 
  
! # If set MIME Part 1 (RFC 1521) decoding is only done when MIME-version
! # header is present. Default: True
! ### require-mime-version-for-body-encoding = ON
! 
! # If set MIME Part 2 (RFC 1522) decoding is only done when MIME-version
! # header is present. Default: False
! ### require-mime-version-for-hdr-encoding = OFF
! 
! # emulate the mailx message increment mode (only increment after
! # something has been 'done' to a message, either saved or deleted,
! # as opposed to simply each time something is touched)?
! ### resolve = ON
  
! # save messages, incoming and outbound, by login name of sender/recipient?
! ### savename = ON
  
! # where to save copies of outgoing mail to, default file is "=sent"
! ### sentmail = =sent
  
! # The shell to use for shell escapes
! # If not set value from passwd is used
! ### shell = $SHELL
! 
! # if this variable is ON, display text before PGP armor.
! ### showpgppreamble = ON
! 
! # if this variable is ON, Elm will show who the message is to rather than
! # who it is from in the headers display.
! ### showto = OFF
  
! # do we want dashes above signatures? (News 2.11 compatibility and convention)
! ### sigdashes = ON
  
! # time in seconds which Elm will wait after displaying a transient message
! # and before erasing it.  Can be 0 or positive integer.
! ### sleepmsg = 2
  
! # how to sort folders, "Reverse Sent" by default
! sortby = Reverse-Sent
  
! # Set the main prompt timeout for resynching...
! ### timeout = 600
  
! # display message title when displaying pages of message?
! ### titles = ON
  
! # where to place temporary files, default directory is "/tmp"
! ### tmpdir = /usr/tmp/
  
+ # If ON, Elm will prompt you for your PGP passphrase and use it whenever
+ # necessary to make it more convenient to hand PGP messages.
+ usepgppass = ON
+ 
+ # are we good at it?  beginner (0), intermediate (1), expert (2)
+ userlevel = intermediate
+ 
  # would you like to use termcap/terminfo ti/te entries?
! ### usetite = ON
  
! # name of editor for ~v command (when editor="builtin")
! ### visualeditor = /bin/vi 
  
! # enable the weedout list to be read?
! ### weed = ON
! 
! # what headers I DON'T want to see, ever.
! ### weedout = "*end-of-user-headers*"
Index: elm2.4.ME+.50/doc/mime.types
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/doc/mime.types	Tue Nov 17 21:12:54 1998
***************
*** 0 ****
--- 1,27 ----
+ # mime.types for Elm 2.4PL24 ME8 (or greater)
+ #
+ # Format of this file:
+ # <suffix> <content-type>
+ #
+ # Elm already has the following "builtin" definitions:
+ # ps	application/postscript
+ # gif	image/gif
+ # tiff	image/tiff
+ # jpeg	image/jpeg
+ #
+ # NOTE: data which is declared "application/octet-stream" will automatically
+ # have the "name=<default_filename>" option added to it, so you should not
+ # put it in your definitions.
+ 
+ gz	application/octet-stream
+ pbm	image/pbm
+ pgm	image/pgm
+ ppm	image/ppm
+ taz	application/octet-stream; type=tar; conversions=x-compress
+ tgz	application/octet-stream; type=tar; conversions=x-gzip
+ tar	application/octet-stream; type=tar
+ Z	application/octet-stream
+ zip	application/octet-stream; type=zip
+ 
+ # PGP users might want the following
+ pgp	application/pgp
Index: elm2.4.ME+.50/doc/tmac.n
*** elm2.4.25/doc/tmac.n	Mon Apr 12 04:35:36 1993
--- elm2.4.ME+.50/doc/tmac.n	Tue Nov 17 21:12:54 1998
***************
*** 1,4 ****
! .\" @(#)$Id: tmac.n,v 5.5 1993/04/12 01:35:29 syd Exp $
  .\" The News macro package
  .\"
  .\" This  is  the macro package that is used to format news documents.  It
--- 1,4 ----
! .\" @(#)$Id: tmac.n,v 1.1.1.1 1998/10/15 15:36:39 hurtta Exp $
  .\" The News macro package
  .\"
  .\" This  is  the macro package that is used to format news documents.  It
Index: elm2.4.ME+.50/filter/Makefile.SH
*** elm2.4.25/filter/Makefile.SH	Sun Jun  6 20:35:08 1993
--- elm2.4.ME+.50/filter/Makefile.SH	Tue Nov 17 21:12:54 1998
***************
*** 21,58 ****
  fi
  cat >Makefile <<!GROK!THIS!
  #
! # @(#)$Id: Makefile.SH,v 5.5 1993/06/06 17:35:04 syd Exp $
  #  Makefile for the Elm system filter program
  #
  #         (C) Copyright 1986,1987, by Dave Taylor
  #         (C) Copyright 1988-1992, USENET Community Trust
  #
- # Bug reports, patches, comments, suggestions should be sent to:
- #
- #	Syd Weinstein - elm@DSI.COM
- #			dsinc!elm
- #
- #  $Log: Makefile.SH,v $
- # Revision 5.5  1993/06/06  17:35:04  syd
- # Remove useless buffer.c
- #
- # Revision 5.4  1993/02/03  16:22:06  syd
- # add libutil.a as strtokq moved to lib
- #
- # Revision 5.3  1993/01/27  19:40:01  syd
- # I implemented a change to filter's default verbose message format
- # including %x %X style date and time along with username
- # From: mark@drd.com (Mark Lawrence)
  #
- # Revision 5.2  1992/11/15  01:40:43  syd
- # Add regexp processing to filter.
- # Add execc operator
- # From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
- #
- # Revision 5.1  1992/10/03  22:18:09  syd
- # Initial checkin as of 2.4 Release at PL0
- #
- #
  # Variables
  #	Variables established by Configure
  CC		=	$cc
--- 21,34 ----
  fi
  cat >Makefile <<!GROK!THIS!
  #
! # @(#)$Id: Makefile.SH,v 1.2 1998/10/20 19:57:27 hurtta Exp $
! #
  #  Makefile for the Elm system filter program
  #
  #         (C) Copyright 1986,1987, by Dave Taylor
  #         (C) Copyright 1988-1992, USENET Community Trust
  #
  #
  # Variables
  #	Variables established by Configure
  CC		=	$cc
***************
*** 86,92 ****
  #	Other variables
  BIN		=	../bin
  INCLDIR		=	../hdrs
! CFLAGS		=	$(CCFLAGS) $(OPTIMIZE) -I$(INCLDIR) $(DEBUG) $(DACSNET) 
  LINTFLAGS	=	-I$(INCLDIR)
  SHELL		=	/bin/sh
  
--- 62,68 ----
  #	Other variables
  BIN		=	../bin
  INCLDIR		=	../hdrs
! CFLAGS		=	-I$(INCLDIR) $(CCFLAGS) $(OPTIMIZE) $(DEBUG) $(DACSNET) 
  LINTFLAGS	=	-I$(INCLDIR)
  SHELL		=	/bin/sh
  
***************
*** 109,121 ****
  			rules.o		\
  			summarize.o	\
  			utils.o		\
! 			audit.o		\
! 			../lib/libutil.a
  
  # Standard targets
! all:		$(BIN)/filter
  		
! install:	$(DEST)/filter
  
  uninstall:	
  		$(RM) $(DEST)/filter
--- 85,100 ----
  			rules.o		\
  			summarize.o	\
  			utils.o		\
! 			audit.o		
  
  # Standard targets
! all:		Makefile $(BIN)/filter
  		
! install:	Makefile $(DEST)/filter
! 
! Makefile: Makefile.SH ../config.sh
! 	@echo "You must run 'sh Configure -S' or 'sh Configure'"
! 	exit 1
  
  uninstall:	
  		$(RM) $(DEST)/filter
***************
*** 162,176 ****
  			$(TOUCH) $@
  
  #	Dependencies and rules for C object files
! actions.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h
! filter.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h
! lock.o:			$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h
! parse.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h
! regexp.o:		$(INCLDIR)/defs.h $(INCLDIR)/regexp.h
! rules.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h
! summarize.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h
! utils.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h
! audit.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h
  
  #	Dependencies and rules for compiling programs
  $(BIN)/filter:	$& $(FILTER_OBJ)
--- 141,155 ----
  			$(TOUCH) $@
  
  #	Dependencies and rules for C object files
! actions.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h $(INCLDIR)/elmlib.h
! filter.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h $(INCLDIR)/elmlib.h
! lock.o:			$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h $(INCLDIR)/elmlib.h
! parse.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h $(INCLDIR)/elmlib.h
! regexp.o:		$(INCLDIR)/defs.h $(INCLDIR)/regexp.h $(INCLDIR)/elmlib.h
! rules.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h $(INCLDIR)/elmlib.h
! summarize.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h $(INCLDIR)/elmlib.h
! utils.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h $(INCLDIR)/elmlib.h
! audit.o:		$(INCLDIR)/defs.h $(INCLDIR)/filter.h $(INCLDIR)/s_filter.h $(INCLDIR)/elmlib.h
  
  #	Dependencies and rules for compiling programs
  $(BIN)/filter:	$& $(FILTER_OBJ)
Index: elm2.4.ME+.50/filter/actions.c
*** elm2.4.25/filter/actions.c	Tue Aug  3 22:28:40 1993
--- elm2.4.ME+.50/filter/actions.c	Tue Nov 17 21:12:54 1998
***************
*** 1,73 ****
  
! static char rcsid[] ="@(#)$Id: actions.c,v 5.8 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.8 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein - elm@DSI.COM
!  *			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: actions.c,v $
!  * Revision 5.8  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.7  1993/08/03  19:07:58  syd
!  * Removed bogus string lockfile.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.6  1993/04/21  01:25:45  syd
!  * I'm using Elm 2.4.21 under Linux.  Linux has no Bourne shell.  Each
!  * user installs her favorite shell as /bin/sh.  I use Bash 1.12.
!  *
!  * Elm invokes the mail transport (MTA) like so:
!  *
!  *    ( ( MTA destination; rm -f tempfile ) & ) < tempfile &
!  *
!  * This form of command doesn't work with my Bash, in which any command
!  * which is backgrounded ("&") gets its stdin attached to /dev/null.
!  *
!  * The below patch arranges for Elm to call the MTA thusly:
!  *
!  *    ( MTA destination <tempfile; rm -f tempfile ) &
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.5  1993/01/27  19:40:01  syd
!  * I implemented a change to filter's default verbose message format
!  * including %x %X style date and time along with username
!  * From: mark@drd.com (Mark Lawrence)
!  *
!  * Revision 5.4  1993/01/20  03:37:16  syd
!  * Nits and typos in the NLS messages and corresponding default messages.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.3  1992/12/24  19:22:05  syd
!  * Quote from the filter of phrase to prevent RFC-822 parsing problems
!  * From: Syd via request from Ian Stewartson <istewart@dlvax2.datlog.co.uk>
!  *
!  * Revision 5.2  1992/12/11  02:16:08  syd
!  * remove unreachable return(0) at end of function
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:18:09  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  
  /** RESULT oriented routines *chuckle*.  These routines implement the
--- 1,16 ----
  
! static char rcsid[] ="@(#)$Id: actions.c,v 1.2 1998/10/20 19:57:27 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  
  /** RESULT oriented routines *chuckle*.  These routines implement the
***************
*** 78,85 ****
--- 21,32 ----
  #include <stdio.h>
  #include <pwd.h>
  #include <fcntl.h>
+ #include <errno.h>
+ extern int errno;
  
  #include "defs.h"
+ #include "elmlib.h"
+ 
  #include "filter.h"
  #include "s_filter.h"
  
***************
*** 97,103 ****
         */
  
  	FILE *pipefd, *tempfd, *mailfd;
! 	int  in_header = TRUE, line_count = 0, mailunit, pid, statusp;
  	char tempfile[SLEN], mailbox[SLEN],
  	     buffer[VERY_LONG_STRING], *cp;
  
--- 44,51 ----
         */
  
  	FILE *pipefd, *tempfd, *mailfd;
! 	int  in_header = TRUE, line_count = 0, mailunit, pid,sig;
! 	S__ statusp;
  	char tempfile[SLEN], mailbox[SLEN],
  	     buffer[VERY_LONG_STRING], *cp;
  
***************
*** 107,113 ****
  		  date_n_user(), address);
  
  	if (! show_only) {
! 	  sprintf(tempfile, "%s.%d", filter_temp, getpid());
  
  	  if ((tempfd = fopen(tempfile, "r")) == NULL) {
  	    if (outfd != NULL)
--- 55,63 ----
  		  date_n_user(), address);
  
  	if (! show_only) {
! 	  elm_sfprintf(tempfile, sizeof tempfile,
! 		       FRM("%s.%d"), 
! 		       filter_temp, getpid());
  
  	  if ((tempfd = fopen(tempfile, "r")) == NULL) {
  	    if (outfd != NULL)
***************
*** 134,142 ****
  	    }
  
  	    if (strcmp(sendmail, mailer) == 0)
! 	      sprintf(buffer, "%s %s %s", sendmail, smflags, address);
  	    else
! 	      sprintf(buffer, "%s %s", mailer, address);
  
  	    /*
  	     * we do a fork/exec here to prevent evil people
--- 84,96 ----
  	    }
  
  	    if (strcmp(sendmail, mailer) == 0)
! 	      elm_sfprintf(buffer, sizeof buffer,
! 			   FRM("%s -oi -oem %s"), 
! 			   sendmail, address);
  	    else
! 	      elm_sfprintf(buffer, sizeof buffer,
! 			   FRM("%s %s"), 
! 			   mailer, address);
  
  	    /*
  	     * we do a fork/exec here to prevent evil people
***************
*** 145,163 ****
  	    
  	    if ( (pid=fork()) > 0 ) /* we're the parent */
  	      {
! 		    wait(&statusp);
! 		    if (statusp!=0)
  		      {
  			    fprintf(outfd,
  				    catgets(elm_msg_cat,
  					    FilterSet,FilterBadWaitStat,
  		    "filter (%s): Command \"%s\" exited with value %d\n"),
! 				    date_n_user(),buffer,statusp);
  		      }
  	      }
  	    else if (pid==0) /* we're the child */
  	      {
! 		    /* use safe permissions */
  		    
  		    setuid(user_uid);
  		    setgid(user_gid);
--- 99,134 ----
  	    
  	    if ( (pid=fork()) > 0 ) /* we're the parent */
  	      {
! 		int w;
! 		while (pid != (w = my_wait(pid,&statusp)) &&
! 		       -1 != w || EINTR == errno);
! 
! 		if (w != pid) {
! 		  fprintf(outfd,
! 			  "filter (%s): Command \"%s\", wait failed (erro = %d) \n",
! 			  date_n_user(),buffer,errno);
! 		
! 		} else {
! 		  int sig, stat;
! 		  sig = convert_status(statusp,&stat);
! 		  if (sig) {
! 		    fprintf(outfd,
! 			    "filter (%s): Command \"%s\" died with signal = %d\n",
! 			    date_n_user(),buffer,sig);
! 
! 		  } else if (stat!=0)
  		      {
  			    fprintf(outfd,
  				    catgets(elm_msg_cat,
  					    FilterSet,FilterBadWaitStat,
  		    "filter (%s): Command \"%s\" exited with value %d\n"),
! 				    date_n_user(),buffer,stat);
  		      }
+ 		}
  	      }
  	    else if (pid==0) /* we're the child */
  	      {
! 		      /* use safe permissions */
  		    
  		    setuid(user_uid);
  		    setgid(user_gid);
***************
*** 167,175 ****
  			    fprintf(outfd,catgets(elm_msg_cat,
  						  FilterSet,FilterPopenFailed,
  		  "filter (%s): popen %s failed!\n"), date_n_user(), buffer);
! 			  sprintf(buffer, "(%s %s %s < %s ; %s %s) &",
! 				  sendmail, smflags, address, tempfile,
! 				  remove_cmd, tempfile);
  			  exit(system(buffer));
  		    }
  		    
--- 138,147 ----
  			    fprintf(outfd,catgets(elm_msg_cat,
  						  FilterSet,FilterPopenFailed,
  		  "filter (%s): popen %s failed!\n"), date_n_user(), buffer);
! 			  elm_sfprintf(buffer, sizeof buffer,
! 				       FRM("(%s -oi -oem %s < %s ; %s %s) &"),
! 				       sendmail, address, tempfile,
! 				       remove_cmd, tempfile);
  			  exit(system(buffer));
  		    }
  		    
***************
*** 218,224 ****
  	  
  	  /** OTHERWISE it is to the current user... **/
  
! 	  sprintf(mailbox, "%s%s", mailhome, username);
  
  	  if (!lock()) {
  	    if (outfd != NULL) {
--- 190,198 ----
  	  
  	  /** OTHERWISE it is to the current user... **/
  
! 	  elm_sfprintf(mailbox, sizeof mailbox,
! 		       FRM("%s%s"), 
! 		       mailhome, username);
  
  	  if (!lock()) {
  	    if (outfd != NULL) {
***************
*** 256,263 ****
  	} /* end if show only */
  }
  
! save_message(foldername)
! char *foldername;
  {
  	/** Save the message in a folder.  Use full file buffering to
  	    make this work without contention problems **/
--- 230,238 ----
  	} /* end if show only */
  }
  
! int save_message(foldername, namesize)
!      char *foldername;
!      int namesize;
  {
  	/** Save the message in a folder.  Use full file buffering to
  	    make this work without contention problems **/
***************
*** 269,275 ****
  	     statusp, ret;
  
  	/* allow for ~ file names expansion in rules */
! 	(void) expand_filename(foldername);
  
  	if (verbose && outfd != NULL)
  	  fprintf(outfd, catgets(elm_msg_cat,FilterSet,FilterSavedMessage,
--- 244,250 ----
  	     statusp, ret;
  
  	/* allow for ~ file names expansion in rules */
! 	(void) expand_filename(foldername, namesize);
  
  	if (verbose && outfd != NULL)
  	  fprintf(outfd, catgets(elm_msg_cat,FilterSet,FilterSavedMessage,
***************
*** 292,298 ****
  	      
  	      if ((pid=fork()) > 0) /* we're the parent */
  	      {
! 		    wait(&statusp);
  		    return(statusp);
  			  
  	      }
--- 267,273 ----
  	      
  	      if ((pid=fork()) > 0) /* we're the parent */
  	      {
! 		    my_wait(pid,&statusp);
  		    return(statusp);
  			  
  	      }
***************
*** 351,357 ****
        char  filename[SLEN], buffer[SLEN];
        int   fdunit;
        
!       sprintf(filename, "%s.%d", filter_temp, filter_pid);
        
        if ((fdunit = open(foldername,
  			 O_APPEND | O_WRONLY | O_CREAT, 0600)) < 0) {
--- 326,334 ----
        char  filename[SLEN], buffer[SLEN];
        int   fdunit;
        
!       elm_sfprintf(filename, sizeof filename,
! 		   FRM("%s.%d"), 
! 		   filter_temp, filter_pid);
        
        if ((fdunit = open(foldername,
  			 O_APPEND | O_WRONLY | O_CREAT, 0600)) < 0) {
***************
*** 407,418 ****
  	       "filter (%s): Executing %s\n"), date_n_user(), command);
  
  	if (! show_only) {
! 	      sprintf(buffer, "%s %s.%d | %s",
! 		      cat, filter_temp, getpid(), command);
  
  	      if ( (pid=fork()) > 0) /* we're the parent */
  		{
! 		      wait(&statusp);
  		      if (statusp!=0)
  			{
  			      fprintf(outfd,
--- 384,396 ----
  	       "filter (%s): Executing %s\n"), date_n_user(), command);
  
  	if (! show_only) {
! 	      elm_sfprintf(buffer, sizeof buffer,
! 			   FRM("%s < %s.%d"),
! 			   command, filter_temp, getpid());
  
  	      if ( (pid=fork()) > 0) /* we're the parent */
  		{
! 		      my_wait(pid,&statusp);
  		      if (statusp!=0)
  			{
  			      fprintf(outfd,
***************
*** 455,461 ****
  	char  mailbox[SLEN];
  	int   mailunit;
  
! 	sprintf(mailbox, "%s/%s", home, EMERGENCY_MAILBOX);
  
  	if ((mailunit = open(mailbox, O_APPEND | O_WRONLY | O_CREAT, 0600)) < 0) {
  	  if (outfd != NULL)
--- 433,441 ----
  	char  mailbox[SLEN];
  	int   mailunit;
  
! 	elm_sfprintf(mailbox, sizeof mailbox,
! 		     FRM("%s/%s"), 
! 		     home, EMERGENCY_MAILBOX);
  
  	if ((mailunit = open(mailbox, O_APPEND | O_WRONLY | O_CREAT, 0600)) < 0) {
  	  if (outfd != NULL)
***************
*** 463,469 ****
  				 "filter (%s): Can't open %s either!!\n"),
  		    date_n_user(), mailbox);
  
! 	  sprintf(mailbox,"%s/%s", home, EMERG_MBOX); 
  
  	  if ((mailunit = open(mailbox, O_APPEND | O_WRONLY | O_CREAT, 0600)) < 0) {
  
--- 443,451 ----
  				 "filter (%s): Can't open %s either!!\n"),
  		    date_n_user(), mailbox);
  
! 	  elm_sfprintf(mailbox,sizeof mailbox,
! 		       FRM("%s/%s"), 
! 		       home, EMERG_MBOX); 
  
  	  if ((mailunit = open(mailbox, O_APPEND | O_WRONLY | O_CREAT, 0600)) < 0) {
  
***************
*** 498,500 ****
--- 480,483 ----
  	tempfd = fdopen(mailunit, "a");
  	return((FILE *) tempfd);
  }
+ 
Index: elm2.4.ME+.50/filter/audit.c
*** elm2.4.25/filter/audit.c	Tue Feb  9 21:04:48 1993
--- elm2.4.ME+.50/filter/audit.c	Tue Nov 17 21:12:54 1998
***************
*** 1,30 ****
  
! static char rcsid[] ="@(#)$Id: audit.c,v 5.3 1993/02/09 19:04:38 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein - elm@DSI.COM
!  *			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: audit.c,v $
!  * Revision 5.3  1993/02/09  19:04:38  syd
!  * use standard include method on time.h style includes
!  *
!  * Revision 5.2  1993/01/27  21:30:10  syd
!  * fix include syntax
!  *
!  * Revision 5.1  1993/01/27  19:40:18  syd
!  * Initial checkin
!  *
!  *
!  ******************************************************************************/
  
  
  /** allow date/time to be combined with username in verbose audit
--- 1,16 ----
  
! static char rcsid[] ="@(#)$Id: audit.c,v 1.2 1998/10/20 19:57:27 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  
  /** allow date/time to be combined with username in verbose audit
***************
*** 35,48 ****
  #include <fcntl.h>
  #include <errno.h>
  
- #ifdef I_TIME
- #  include <time.h>
- #endif
- #ifdef I_SYSTIME
- #  include <sys/time.h>
- #endif
- 
  #include "defs.h"
  #include "filter.h"
  #include "s_filter.h"
  
--- 21,29 ----
  #include <fcntl.h>
  #include <errno.h>
  
  #include "defs.h"
+ #include "elmlib.h"
+ 
  #include "filter.h"
  #include "s_filter.h"
  
***************
*** 54,59 ****
--- 35,41 ----
      static char     date[NLEN];
      static char    *stuff = NULL;
      time_t          now;
+     int size;
  
      now = time(NULL);
      if (!strftime(date, NLEN, "%c", localtime(&now)))
***************
*** 60,68 ****
          return (username);
      if (stuff)
          free(stuff);
!     if (!(stuff = malloc(strlen(username) + strlen(date) + 3)))
!         return (username);
!     sprintf(stuff, "%s %s", date, username);
! 	return(stuff);
  }
  
--- 42,49 ----
          return (username);
      if (stuff)
          free(stuff);
!     
!     stuff = elm_message("%s %s", date, username);
!     return(stuff);
  }
  
Index: elm2.4.ME+.50/filter/filter.c
*** elm2.4.25/filter/filter.c	Mon May 30 19:31:55 1994
--- elm2.4.ME+.50/filter/filter.c	Tue Nov 17 21:14:08 1998
***************
*** 1,62 ****
  
! static char rcsid[] ="@(#)$Id: filter.c,v 5.7 1994/05/30 16:31:40 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.7 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein - elm@DSI.COM
!  *			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: filter.c,v $
!  * Revision 5.7  1994/05/30  16:31:40  syd
!  * make getpwuid dependent on ANSI_C not posix flag
!  * From: Syd
!  *
!  * Revision 5.6  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.5  1993/06/06  17:58:20  syd
!  * make white space skipping work for blank or tab
!  *
!  * Revision 5.4  1993/01/27  19:40:01  syd
!  * I implemented a change to filter's default verbose message format
!  * including %x %X style date and time along with username
!  * From: mark@drd.com (Mark Lawrence)
!  *
!  * Revision 5.3  1992/11/15  01:40:43  syd
!  * Add regexp processing to filter.
!  * Add execc operator
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.2  1992/11/07  16:20:56  syd
!  * The first is that when doing a summary, macros are expanded when printing the
!  * rule. IMHO they should be printed as with the -r option (i.e. %t is
!  * printed as "<time>" and so on).
!  *
!  * The second one is that the summary printed "applied n time" regardless of
!  * the value of n, not "applied n times" when n > 1.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.1  1992/10/03  22:18:09  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  
  /** This program is used as a filter within the users ``.forward'' file
--- 1,16 ----
  
! static char rcsid[] ="@(#)$Id: filter.c,v 1.3 1998/11/07 14:12:00 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  
  /** This program is used as a filter within the users ``.forward'' file
***************
*** 81,94 ****
  #include <stdio.h>
  #include <pwd.h>
  #include "defs.h"
! #ifdef I_TIME
! #  include <time.h>
! #endif
! #ifdef I_SYSTIME
! #  include <sys/time.h>
! #endif
  #include <fcntl.h>
  
  #define  MAIN_ROUTINE			/* for the filter.h file, of course! */
  #include "filter.h"
  #include "s_filter.h"
--- 35,45 ----
  #include <stdio.h>
  #include <pwd.h>
  #include "defs.h"
! #include "elmlib.h"
! 
  #include <fcntl.h>
  
+  
  #define  MAIN_ROUTINE			/* for the filter.h file, of course! */
  #include "filter.h"
  #include "s_filter.h"
***************
*** 95,103 ****
  
  extern char *date_n_user();
  
! main(argc, argv)
! int argc;
! char *argv[];
  {
  	extern char *optarg;
  	FILE   *fd;				/* for output to temp file! */
--- 46,60 ----
  
  extern char *date_n_user();
  
! static void save_from P_((char *)); /* Prototype */
! static void save_subject P_((char *));
! static void save_sender P_((char *));
! static void save_to P_((char *));
! static void save_embedded_address P_((char *, char *));
! 
! int main(argc, argv)
!      int argc;
!      char *argv[];
  {
  	extern char *optarg;
  	FILE   *fd;				/* for output to temp file! */
***************
*** 113,146 ****
  	     summary   = FALSE,			/* a summary is requested?  */
  	     c;					/* var for getopt routine   */
  
! #ifdef I_LOCALE
!         setlocale(LC_ALL, "");
! #endif
! 
!         elm_msg_cat = catopen("elm2.4", 0);
! 
  		
! 	/* first off, let's get the info from /etc/passwd */ 
! 	
! 	if ((passwd_entry = getpwuid(getuid())) == NULL) 
! 	  leave(catgets(elm_msg_cat,FilterSet,FilterCantGetPasswdEntry,
! 		"Cannot get password entry for this uid!"));
! 
! 	strcpy(home, passwd_entry->pw_dir);
! 	strcpy(username, passwd_entry->pw_name);
! 	user_uid = passwd_entry->pw_uid;
! 	user_gid = passwd_entry->pw_gid;
  	
  	/* nothing read in yet, right? */
  	outfname[0] = to[0] = filterfile[0] = '\0';
  	
- 	
- #ifdef HOSTCOMPILED
- 	strncpy(hostname, HOSTNAME, sizeof(hostname));
- #else
- 	gethostname(hostname, sizeof(hostname));
- #endif
- 
  	/* now parse the starting arguments... */
  
  	while ((c = getopt(argc, argv, "clno:qrSsvf:")) != EOF)
--- 70,86 ----
  	     summary   = FALSE,			/* a summary is requested?  */
  	     c;					/* var for getopt routine   */
  
! 	locale_init();
! 	user_init();
! 	init_defaults();
! 	read_rc_file();
  		
! 	user_uid = userid;
! 	user_gid = groupid;
  	
  	/* nothing read in yet, right? */
  	outfname[0] = to[0] = filterfile[0] = '\0';
  	
  	/* now parse the starting arguments... */
  
  	while ((c = getopt(argc, argv, "clno:qrSsvf:")) != EOF)
***************
*** 150,156 ****
  		    clear_logs = TRUE;
  		    break;
  	       case 'f' :
! 		    strcpy(filterfile,optarg);
  		    break;
  	       case 'l' :
  		    log_actions_only = TRUE;
--- 90,96 ----
  		    clear_logs = TRUE;
  		    break;
  	       case 'f' :
! 		    strfcpy(filterfile,optarg, sizeof filterfile);
  		    break;
  	       case 'l' :
  		    log_actions_only = TRUE;
***************
*** 159,165 ****
  		    show_only = TRUE;
  		    break;
  	       case 'o' :
! 		    strcpy(outfname, optarg);
  		    break;
  	       case 'q' :
  		    logging = FALSE;
--- 99,105 ----
  		    show_only = TRUE;
  		    break;
  	       case 'o' :
! 		    strfcpy(outfname, optarg, sizeof outfname);
  		    break;
  	       case 'q' :
  		    logging = FALSE;
***************
*** 191,197 ****
  
  	/* use default filter file name if none specified */
  	if (!*filterfile)
! 	     sprintf(filterfile,"%s/%s",home,FILTERFILE);
  	
  	
  	/* let's open our outfd logfile as needed... */
--- 131,139 ----
  
  	/* use default filter file name if none specified */
  	if (!*filterfile)
! 	     elm_sfprintf(filterfile,sizeof filterfile,
! 			  FRM("%s/%s"),
! 			  home,FILTERFILE);
  	
  	
  	/* let's open our outfd logfile as needed... */
***************
*** 230,244 ****
  
  	/* next, create the tempfile and save the incoming message */
  
! 	sprintf(filename, "%s.%d", filter_temp, getpid());
  
! 	if ((fd = fopen(filename,"w")) == NULL)
  	  {
! 		sprintf(buffer,
! 			catgets(elm_msg_cat,FilterSet,
! 				FilterCantOpenTempFileLeave,
! 			"Cannot open temporary file %s"),
! 				filename);
  		leave(buffer);
  	  }
  	
--- 172,188 ----
  
  	/* next, create the tempfile and save the incoming message */
  
! 	elm_sfprintf(filename, sizeof filename,
! 		     FRM("%s.%d"), 
! 		     filter_temp, getpid());
  
! 	if ((fd = safeopen(filename)) == NULL)
  	  {
! 		elm_sfprintf(buffer, sizeof buffer,
! 			     CATGETS(elm_msg_cat,FilterSet,
! 				     FilterCantOpenTempFileLeave,
! 				     "Cannot open temporary file %s"),
! 			     filename);
  		leave(buffer);
  	  }
  	
***************
*** 265,280 ****
  	    }
  	    else if (the_same(buffer, "X-Filtered-By:")) 
  	      already_been_forwarded++;	/* could be a loop here! */
- #ifdef USE_EMBEDDED_ADDRESSES
  	    else if (the_same(buffer, "From:"))
  	      save_embedded_address(buffer, "From:");
  	    else if (the_same(buffer, "Reply-To:"))
  	      save_embedded_address(buffer, "Reply-To:");
- #endif
  	    else if (strlen(buffer) < 2) 
  	      in_header = 0;
  	    else if (whitespace(buffer[0]) && in_to)
! 	      strcat(to, buffer);
  	  }
  	
            fprintf(fd, "%s\n", buffer);	/* and save it regardless! */
--- 209,222 ----
  	    }
  	    else if (the_same(buffer, "X-Filtered-By:")) 
  	      already_been_forwarded++;	/* could be a loop here! */
  	    else if (the_same(buffer, "From:"))
  	      save_embedded_address(buffer, "From:");
  	    else if (the_same(buffer, "Reply-To:"))
  	      save_embedded_address(buffer, "Reply-To:");
  	    else if (strlen(buffer) < 2) 
  	      in_header = 0;
  	    else if (whitespace(buffer[0]) && in_to)
! 	      strfcat(to, buffer, sizeof to);
  	  }
  	
            fprintf(fd, "%s\n", buffer);	/* and save it regardless! */
***************
*** 294,302 ****
  
  	  if (rule_choosen >= 0) {
  	    expand_macros(rules[rule_choosen].argument2, action_argument,
! 			rules[rule_choosen].line, printing_rules);
  	    /* Got to do this because log_msg() uses argument2 in rules[] */
! 	    strcpy(rules[rule_choosen].argument2, action_argument);
  	  }
  
  	  switch (action) {
--- 236,246 ----
  
  	  if (rule_choosen >= 0) {
  	    expand_macros(rules[rule_choosen].argument2, action_argument,
! 			  rules[rule_choosen].line, printing_rules,
! 			  sizeof action_argument);
  	    /* Got to do this because log_msg() uses argument2 in rules[] */
! 	    strfcpy(rules[rule_choosen].argument2, action_argument,
! 		    sizeof rules[rule_choosen].argument2);
  	  }
  
  	  switch (action) {
***************
*** 309,315 ****
  				    date_n_user());
  			  log_msg(DELETE_MSG);				break;
  
! 	    case SAVE   : if (save_message(rules[rule_choosen].argument2)) {
  			    mail_message(username);
  			    log_msg(FAILED_SAVE);
  			  }
--- 253,261 ----
  				    date_n_user());
  			  log_msg(DELETE_MSG);				break;
  
! 	    case SAVE   : if (save_message(rules[rule_choosen].argument2,
! 					   sizeof rules[rule_choosen].
! 					   argument2)) {
  			    mail_message(username);
  			    log_msg(FAILED_SAVE);
  			  }
***************
*** 317,323 ****
  		 	    log_msg(SAVE);
  	                  break;
  
! 	    case SAVECC : if (save_message(rules[rule_choosen].argument2))
  			    log_msg(FAILED_SAVE);
  			  else
  		            log_msg(SAVECC);
--- 263,271 ----
  		 	    log_msg(SAVE);
  	                  break;
  
! 	    case SAVECC : if (save_message(rules[rule_choosen].argument2,
! 					   sizeof rules[rule_choosen].
! 					   argument2))
  			    log_msg(FAILED_SAVE);
  			  else
  		            log_msg(SAVECC);
***************
*** 353,360 ****
  	exit(0);
  }
  
! save_from(buffer)
! char *buffer;
  {
  	/** save the SECOND word of this string as FROM **/
  
--- 301,308 ----
  	exit(0);
  }
  
! static void save_from(buffer)
!      char *buffer;
  {
  	/** save the SECOND word of this string as FROM **/
  
***************
*** 366,379 ****
  	while (whitespace(*buffer))
  	  buffer++;				/* skip delimited  */
  
! 	for (; (!whitespace(*buffer)) && *buffer; buffer++, f++) 
  	  *f = *buffer;				/* copy it and     */
  
  	*f = '\0';				/* Null terminate! */
  }
  
! save_subject(buffer)
! char *buffer;
  {
  	/** save all but the word "Subject:" for the subject **/
  
--- 314,329 ----
  	while (whitespace(*buffer))
  	  buffer++;				/* skip delimited  */
  
! 	for (; (!whitespace(*buffer)) && *buffer &&
! 	       f < from + (sizeof from -1); 
! 	     buffer++, f++) 
  	  *f = *buffer;				/* copy it and     */
  
  	*f = '\0';				/* Null terminate! */
  }
  
! static void save_subject(buffer)
!      char *buffer;
  {
  	/** save all but the word "Subject:" for the subject **/
  
***************
*** 382,392 ****
  	while (whitespace(buffer[skip]))
  		skip++;
  
! 	strcpy(subject, (char *) buffer + skip);
  }
  
! save_sender(buffer)
! char *buffer;
  {
  	/** save all but the word "Sender:" for the sender **/
  
--- 332,342 ----
  	while (whitespace(buffer[skip]))
  		skip++;
  
! 	strfcpy(subject, (char *) buffer + skip, sizeof subject);
  }
  
! static void save_sender(buffer)
!      char *buffer;
  {
  	/** save all but the word "Sender:" for the sender **/
  
***************
*** 395,405 ****
  	while (whitespace(buffer[skip]))
  		skip++;
  
! 	strcpy(sender, (char *) buffer + skip);
  }
  
! save_to(buffer)
! char *buffer;
  {
  	/** save all but the word "To:" or "Cc:" or
  	    "Apparently-To:" for the to list **/
--- 345,355 ----
  	while (whitespace(buffer[skip]))
  		skip++;
  
! 	strfcpy(sender, (char *) buffer + skip, sizeof sender);
  }
  
! static void save_to(buffer)
!      char *buffer;
  {
  	/** save all but the word "To:" or "Cc:" or
  	    "Apparently-To:" for the to list **/
***************
*** 412,426 ****
  	while (whitespace(buffer[skip]))
  		skip++;
  
  	if (*to)
! 		strcat(to, " "); /* place one blank between items */
  
! 	strcat(to, (char *) buffer + skip);
  }
  
! #ifdef USE_EMBEDDED_ADDRESSES
! 
! save_embedded_address(buffer, fieldname)
  char *buffer, *fieldname;
  {
  	/** this will replace the 'from' address with the one given, 
--- 362,375 ----
  	while (whitespace(buffer[skip]))
  		skip++;
  
+ 	/* place one blank between items */
  	if (*to)
! 		strfcat(to, " ", sizeof to); 
  
! 	strfcat(to, (char *) buffer + skip, sizeof to);
  }
  
! static void save_embedded_address(buffer, fieldname)
  char *buffer, *fieldname;
  {
  	/** this will replace the 'from' address with the one given, 
***************
*** 442,448 ****
  	  for (i=strlen(buffer)-1; buffer[i] != '<' && i > 0; i--)
  		/* nothing - just move backwards .. */ ;
  	  i++;	/* skip the leading '<' symbol */
! 	  while (buffer[i] != '>')
  	    address[j++] = buffer[i++];
  	  address[j] = '\0';
  	}
--- 391,397 ----
  	  for (i=strlen(buffer)-1; buffer[i] != '<' && i > 0; i--)
  		/* nothing - just move backwards .. */ ;
  	  i++;	/* skip the leading '<' symbol */
! 	  while (buffer[i] != '>' && j < sizeof address -1)
  	    address[j++] = buffer[i++];
  	  address[j] = '\0';
  	}
***************
*** 449,455 ****
  	else {	/* get past "from:" and copy until white space or paren hit */
  	  for (i=strlen(fieldname); whitespace(buffer[i]); i++)
  	     /* skip past that... */ ;
! 	  while (buffer[i] != '(' && ! whitespace(buffer[i]) && buffer[i]!='\0')
  	    address[j++] = buffer[i++];
  	  address[j] = '\0';
  	}
--- 398,405 ----
  	else {	/* get past "from:" and copy until white space or paren hit */
  	  for (i=strlen(fieldname); whitespace(buffer[i]); i++)
  	     /* skip past that... */ ;
! 	  while (buffer[i] != '(' && ! whitespace(buffer[i]) && 
! 		 buffer[i]!='\0' && j < sizeof address-1)
  	    address[j++] = buffer[i++];
  	  address[j] = '\0';
  	}
***************
*** 460,469 ****
  	if (processed_a_reply_to)
  	  return;	/* forget it! */
  
! 	strcpy(from, address);			/* replaced!! */
  
  	if (istrcmp(fieldname, "Reply-To:") == 0)
  	  processed_a_reply_to++;
  }
! #endif
  
--- 410,419 ----
  	if (processed_a_reply_to)
  	  return;	/* forget it! */
  
! 	strfcpy(from, address, sizeof from);			/* replaced!! */
  
  	if (istrcmp(fieldname, "Reply-To:") == 0)
  	  processed_a_reply_to++;
  }
! 
  
Index: elm2.4.ME+.50/filter/lock.c
*** elm2.4.25/filter/lock.c	Tue Jan 19 05:55:42 1993
--- elm2.4.ME+.50/filter/lock.c	Tue Nov 17 21:12:54 1998
***************
*** 1,49 ****
  
! static char rcsid[] ="@(#)$Id: lock.c,v 5.6 1993/01/19 03:55:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.6 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein - elm@DSI.COM
!  *			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: lock.c,v $
!  * Revision 5.6  1993/01/19  03:55:39  syd
!  * exitprog.c makes a reference to a null character pointer, savecopy.c
!  * tries to reference an uninitialized variable, and the previous patch to
!  * src/lock.c to get rid of an uninitialized variable compiler message
!  * needed to be put in filter/lock.c as well.
!  * From: wdh@grouper.mkt.csd.harris.com (W. David Higgins)
!  *
!  * Revision 5.5  1992/12/07  03:49:49  syd
!  * use BSD or not apollo on file.h include as its not valid
!  * for Apollos under sys5.3 compile type
!  * From: gordonb@mcil.comm.mot.com (Gordon Berkley)
!  *
!  * Revision 5.4  1992/10/17  22:35:33  syd
!  * Change lock file name to add user name on filter locking of mail spool
!  * From: Peter Brouwer <pb@idca.tds.philips.nl>
!  *
!  * Revision 5.3  1992/10/12  00:25:52  syd
!  * Lock error codes (fcntl vs flock) were backwards
!  * From: howardl@wb3ffv.ampr.org (Howard Leadmon - WB3FFV)
!  *
!  * Revision 5.2  1992/10/11  00:52:11  syd
!  * Switch to wrapper for flock and fcntl locking.
!  * Change order to fcntl first, other order blocked.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.1  1992/10/03  22:18:09  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  
  /** The lock() and unlock() routines herein duplicate exactly the
--- 1,16 ----
  
! static char rcsid[] ="@(#)$Id: lock.c,v 1.2 1998/10/20 19:57:27 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  
  /** The lock() and unlock() routines herein duplicate exactly the
***************
*** 57,62 ****
--- 24,31 ----
  #include <fcntl.h>
  #include <errno.h>
  #include "defs.h"
+ 
+ #include "elmlib.h"
  #include "filter.h"
  #include "s_filter.h"
  
***************
*** 68,74 ****
  #ifdef	USE_FLOCK_LOCKING
  #define	NEEDS_FLOCK_FD
  #include <sys/types.h>
! #  if (defined(BSD) || !defined(apollo))
  #    include <sys/file.h>
  #  endif
  #endif
--- 37,43 ----
  #ifdef	USE_FLOCK_LOCKING
  #define	NEEDS_FLOCK_FD
  #include <sys/types.h>
! #  if (defined(BSD_TYPE) || !defined(apollo))
  #    include <sys/file.h>
  #  endif
  #endif
***************
*** 188,195 ****
  	int attempts = 0, ret;
  
  #ifdef	USE_DOTLOCK_LOCKING			/* { USE_DOTLOCK_LOCKING	*/
! 	strcpy(dotlock_name,mailhome);
! 	strcat(dotlock_name,username);
  	lockfile = mk_lockname(dotlock_name);
  #ifdef PIDCHECK
  	/** first, try to read the lock file, and if possible, check the pid.
--- 157,164 ----
  	int attempts = 0, ret;
  
  #ifdef	USE_DOTLOCK_LOCKING			/* { USE_DOTLOCK_LOCKING	*/
! 	strfcpy(dotlock_name,mailhome, sizeof dotlock_name);
! 	strfcat(dotlock_name,username, sizeof dotlock_name);
  	lockfile = mk_lockname(dotlock_name);
  #ifdef PIDCHECK
  	/** first, try to read the lock file, and if possible, check the pid.
***************
*** 228,234 ****
  #endif					/* } USE_DOTLOCK_LOCKING	*/
  
  #ifdef	NEEDS_FLOCK_FD			/* { NEEDS_FLOCK_FD	*/
! 	(void)sprintf(flock_name,"%s%s",mailhome,username);
  	flock_fd = open(flock_name, O_RDWR | O_CREAT, 0600);
  
  	if ( flock_fd >= 0 ) {
--- 197,205 ----
  #endif					/* } USE_DOTLOCK_LOCKING	*/
  
  #ifdef	NEEDS_FLOCK_FD			/* { NEEDS_FLOCK_FD	*/
! 	(void)elm_sfprintf(flock_name,sizeof flock_name,
! 			   FRM("%s%s"),
! 			   mailhome,username);
  	flock_fd = open(flock_name, O_RDWR | O_CREAT, 0600);
  
  	if ( flock_fd >= 0 ) {
Index: elm2.4.ME+.50/filter/parse.c
*** elm2.4.25/filter/parse.c	Mon Sep 20 02:11:18 1993
--- elm2.4.ME+.50/filter/parse.c	Tue Nov 17 21:12:54 1998
***************
*** 1,88 ****
  
! static char rcsid[] ="@(#)$Id: parse.c,v 5.13 1993/09/19 23:11:17 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.13 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein - elm@DSI.COM
!  *			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: parse.c,v $
!  * Revision 5.13  1993/09/19  23:11:17  syd
!  * strtokq was called with the wrong number of parameters.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.12  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.11  1993/04/12  03:04:01  syd
!  * Removed a malloc of a struct condition_rec that is never used.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.10  1993/04/12  03:03:07  syd
!  * The setting of relop to the default (EQ) was in the wrong place,
!  * causing the wrong relation to be inserted in the rule.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.9  1993/02/03  16:22:22  syd
!  * move strtokq to lib directory
!  * From: Syd
!  *
!  * Revision 5.8  1993/01/27  19:45:15  syd
!  * Filter turns spaces in quoted strings into _ and then back again. This destroys
!  * any _ that where there in the first place. This patch removes that.
!  * Also fixed a minor bug where 'filter -r' wrote out the wrong thing if the
!  * relation in a rule was '~'.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.7  1993/01/27  19:40:01  syd
!  * I implemented a change to filter's default verbose message format
!  * including %x %X style date and time along with username
!  * From: mark@drd.com (Mark Lawrence)
!  *
!  * Revision 5.6  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.5  1992/12/07  05:08:03  syd
!  * add sys/types for time_t
!  * From: Syd
!  *
!  * Revision 5.4  1992/11/15  01:40:43  syd
!  * Add regexp processing to filter.
!  * Add execc operator
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.3  1992/10/28  14:52:25  syd
!  * fix compiler warning
!  * From: steve@nshore.org (Stephen J. Walick)
!  *
!  * Revision 5.2  1992/10/24  14:20:24  syd
!  * remove the 25 (MAXRULES) limitation.
!  * Basically it mallocs rules in hunks of RULESINC (25) as it goes along.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.1  1992/10/03  22:18:09  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  
  /** This is the parser for the filter program.  It accepts a wide variety of
--- 1,16 ----
  
! static char rcsid[] ="@(#)$Id: parse.c,v 1.2 1998/10/20 19:57:27 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  
  /** This is the parser for the filter program.  It accepts a wide variety of
***************
*** 95,100 ****
--- 23,30 ----
  #include <stdio.h>
  
  #include "defs.h"
+ #include "elmlib.h"
+ 
  #include "filter.h"
  #include "s_filter.h"
  
***************
*** 172,178 ****
  	struct condition_rec
  	     *cond, *newcond;
  
! 	strcpy(filename,filterfile);
  
  	if ((fd = fopen(filename,"r")) == NULL) {
  	  if (outfd != NULL)
--- 102,108 ----
  	struct condition_rec
  	     *cond, *newcond;
  
! 	strfcpy(filename,filterfile, sizeof filename);
  
  	if ((fd = fopen(filename,"r")) == NULL) {
  	  if (outfd != NULL)
***************
*** 279,285 ****
  	        cond->relation  = (not_condition? - (relop) : relop);
  		cond->regex = NULL;
  
! 		strcpy(cond->argument1, cond_argument);
  	        cond->next = NULL;
  
  	        state = READING_ACTION;
--- 209,216 ----
  	        cond->relation  = (not_condition? - (relop) : relop);
  		cond->regex = NULL;
  
! 		strfcpy(cond->argument1, cond_argument,
! 			sizeof cond->argument1);
  	        cond->next = NULL;
  
  	        state = READING_ACTION;
***************
*** 305,311 ****
  	        if (relop == NONE) relop = EQ;	/* otherwise can't do -relop */
  	        cond->relation  = (not_condition? - (relop) : relop);
  		cond->regex = NULL;
! 		strcpy(cond->argument1, cond_argument);
  	        if ((newcond = (struct condition_rec *)
  	             malloc(sizeof(struct condition_rec))) == NULL) {
  		  if (outfd != NULL)
--- 236,243 ----
  	        if (relop == NONE) relop = EQ;	/* otherwise can't do -relop */
  	        cond->relation  = (not_condition? - (relop) : relop);
  		cond->regex = NULL;
! 		strfcpy(cond->argument1, cond_argument,
! 			sizeof cond->argument1);
  	        if ((newcond = (struct condition_rec *)
  	             malloc(sizeof(struct condition_rec))) == NULL) {
  		  if (outfd != NULL)
***************
*** 367,375 ****
  		for (;;) {
  	          if ((word = strtokq(str, "/", 0)) == NULL)
  	            break;
! 		  strcat(cond_argument, word);
  		  if (word[strlen(word)-1] == '\\') /* If / was escaped ... */
! 		    strcat(cond_argument, "/");
  		  else
  		    break;
  		}
--- 299,307 ----
  		for (;;) {
  	          if ((word = strtokq(str, "/", 0)) == NULL)
  	            break;
! 		  strfcat(cond_argument, word, sizeof cond_argument);
  		  if (word[strlen(word)-1] == '\\') /* If / was escaped ... */
! 		    strfcat(cond_argument, "/", sizeof cond_argument);
  		  else
  		    break;
  		}
***************
*** 381,387 ****
  	          if ((word = strtokq(str, " ()[]\t\n", 1)) == NULL)
  	            continue;
  	        }
! 	        strcpy(cond_argument, word);
  	      }
  	      state = NEXT_CONDITION;
  	    }
--- 313,319 ----
  	          if ((word = strtokq(str, " ()[]\t\n", 1)) == NULL)
  	            continue;
  	        }
! 	        strfcpy(cond_argument, word, sizeof cond_argument);
  	      }
  	      state = NEXT_CONDITION;
  	    }
***************
*** 438,444 ****
  	    }
  	
  	    if (state == ACTION_ARGUMENT) {
! 	      strcpy(action_argument, word);
  
  	      /** add this to the rules section and alloc next... **/
  
--- 370,376 ----
  	    }
  	
  	    if (state == ACTION_ARGUMENT) {
! 	      strfcpy(action_argument, word, sizeof action_argument);
  
  	      /** add this to the rules section and alloc next... **/
  
***************
*** 450,458 ****
  	      **/
  	      if (printing_rules)
  	        expand_macros(action_argument, rules[total_rules].argument2,
! 			      line, printing_rules);
  	      else
! 		strcpy(rules[total_rules].argument2, action_argument);
  
  	      if (++total_rules >= sizeof_rules)
  	        sizeof_rules = grow(&rules, sizeof_rules, RULESINC);
--- 382,392 ----
  	      **/
  	      if (printing_rules)
  	        expand_macros(action_argument, rules[total_rules].argument2,
! 			      line, printing_rules,
! 			      sizeof rules[total_rules].argument2);
  	      else
! 		strfcpy(rules[total_rules].argument2, action_argument,
! 			sizeof rules[total_rules].argument2);
  
  	      if (++total_rules >= sizeof_rules)
  	        sizeof_rules = grow(&rules, sizeof_rules, RULESINC);
Index: elm2.4.ME+.50/filter/regexp.c
*** elm2.4.25/filter/regexp.c	Thu Jun 10 06:12:16 1993
--- elm2.4.ME+.50/filter/regexp.c	Tue Nov 17 21:12:54 1998
***************
*** 1,49 ****
  
! static char rcsid[] = "@(#)$Id: regexp.c,v 5.7 1993/06/10 03:12:10 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.7 $   $State: Exp $
   *
!  * 			Copyright (c) 1992 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: regexp.c,v $
!  * Revision 5.7  1993/06/10  03:12:10  syd
!  * Add missing rcs id lines
!  * From: Syd
!  *
!  * Revision 5.6  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.5  1992/12/07  05:10:51  syd
!  * add include of sys/types.h for time_t
!  * From: Syd
!  *
!  * Revision 5.4  1992/11/17  18:25:42  syd
!  * change to use index instead of strchr
!  * From: Syd
   *
!  * Revision 5.3  1992/11/17  04:10:01  syd
!  * The changes to filter/regexp.c are to correct compiler warnings about
!  * unreachable statements.
!  *
!  * The changes to filter/rules.c are to correct the fact that we are passing
!  * a pointer to a condition_rec structore to a function expecting a pointer to
!  * a character string.
!  * From: Tom Moore <tmoore@fievel.DaytonOH.NCR.COM>
!  *
!  * Revision 5.2  1992/11/15  01:39:31  syd
!  * add proper headers
!  *
!  *
!  ******************************************************************************/
  
  /*
   * regcomp and regexec -- regsub and regerror are elsewhere
--- 1,15 ----
  
! static char rcsid[] = "@(#)$Id: regexp.c,v 1.2 1998/10/20 19:57:27 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  * 			Copyright (c) 1992 USENET Community Trust
!  *****************************************************************************/
  
  /*
   * regcomp and regexec -- regsub and regerror are elsewhere
***************
*** 76,81 ****
--- 42,48 ----
  #include <stdio.h>
  #include "defs.h"
  #include "regexp.h"
+ #include "elmlib.h"
  
  /* #include "regmagic.h" -- Inlined here (next 5 lines) */
  /*
***************
*** 1153,1159 ****
  	register char *p;
  	static char buf[50];
  
! 	(void) strcpy(buf, ":");
  
  	switch (OP(op)) {
  	case BOL:
--- 1120,1126 ----
  	register char *p;
  	static char buf[50];
  
! 	(void) strfcpy(buf, ":", sizeof buf);
  
  	switch (OP(op)) {
  	case BOL:
***************
*** 1195,1201 ****
  	case OPEN+7:
  	case OPEN+8:
  	case OPEN+9:
! 		sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
  		p = NULL;
  		break;
  	case CLOSE+1:
--- 1162,1170 ----
  	case OPEN+7:
  	case OPEN+8:
  	case OPEN+9:
! 		elm_sfprintf(buf+strlen(buf), sizeof buf - strlen(buf),
! 			     FRM("OPEN%d"), 
! 			     OP(op)-OPEN);
  		p = NULL;
  		break;
  	case CLOSE+1:
***************
*** 1207,1213 ****
  	case CLOSE+7:
  	case CLOSE+8:
  	case CLOSE+9:
! 		sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
  		p = NULL;
  		break;
  	case STAR:
--- 1176,1183 ----
  	case CLOSE+7:
  	case CLOSE+8:
  	case CLOSE+9:
! 		elm_sfprintf(buf+strlen(buf), sizeof buf - strlen(buf),
! 			     FRM("CLOSE%d"), OP(op)-CLOSE);
  		p = NULL;
  		break;
  	case STAR:
***************
*** 1221,1227 ****
  		break;
  	}
  	if (p != NULL)
! 		(void) strcat(buf, p);
  	return(buf);
  }
  #endif
--- 1191,1197 ----
  		break;
  	}
  	if (p != NULL)
! 		(void) strfcat(buf, p, sizeof buf);
  	return(buf);
  }
  #endif
Index: elm2.4.ME+.50/filter/rules.c
*** elm2.4.25/filter/rules.c	Fri Mar 11 22:40:24 1994
--- elm2.4.ME+.50/filter/rules.c	Tue Nov 17 21:12:54 1998
***************
*** 1,79 ****
  
! static char rcsid[] ="@(#)$Id: rules.c,v 5.9 1994/03/11 20:40:24 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.9 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein - elm@DSI.COM
!  *			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: rules.c,v $
!  * Revision 5.9  1994/03/11  20:40:24  syd
!  * Fix where buffer was not getting null terminated during its
!  * construction, so the strcat failed (due to garbage data existing in the
!  * array at malloc() time).
!  * From: lm@yallara.cs.rmit.oz.au (Luke Mewburn)
!  *
!  * Revision 5.8  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.7  1993/01/27  19:45:15  syd
!  * Filter turns spaces in quoted strings into _ and then back again. This destroys
!  * any _ that where there in the first place. This patch removes that.
!  * Also fixed a minor bug where 'filter -r' wrote out the wrong thing if the
!  * relation in a rule was '~'.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.6  1993/01/27  19:40:01  syd
!  * I implemented a change to filter's default verbose message format
!  * including %x %X style date and time along with username
!  * From: mark@drd.com (Mark Lawrence)
!  *
!  * Revision 5.5  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.4  1992/11/22  00:06:45  syd
!  * Fix when expanding the macro '%S', the subject line is scanned for a
!  * 'Re:', and if nothing is found, a '"Re: ' is added. But when a 'Re:'
!  * *is* found, then nothing is added, not even the '"'.
!  * From: Sigmund Austigard <austig@solan.unit.no>
!  *
!  * Revision 5.3  1992/11/17  04:10:01  syd
!  * The changes to filter/regexp.c are to correct compiler warnings about
!  * unreachable statements.
!  *
!  * The changes to filter/rules.c are to correct the fact that we are passing
!  * a pointer to a condition_rec structore to a function expecting a pointer to
!  * a character string.
!  * From: Tom Moore <tmoore@fievel.DaytonOH.NCR.COM>
!  *
!  * Revision 5.2  1992/11/15  01:40:43  syd
!  * Add regexp processing to filter.
!  * Add execc operator
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.1  1992/10/03  22:18:09  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This file contains all the rule routines, including those that apply the
      specified rules and the routine to print the rules out.
--- 1,16 ----
  
! static char rcsid[] ="@(#)$Id: rules.c,v 1.2 1998/10/20 19:57:27 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This file contains all the rule routines, including those that apply the
      specified rules and the routine to print the rules out.
***************
*** 80,96 ****
  
  **/
  
- #include <stdio.h>
  #include "defs.h"
  #include <pwd.h>
! #ifdef I_TIME
! #  include <time.h>
! #endif
! #ifdef I_SYSTIME
! #  include <sys/time.h>
! #endif
  #include <fcntl.h>
  
  #include "filter.h"
  #include "s_filter.h"
  
--- 17,28 ----
  
  **/
  
  #include "defs.h"
  #include <pwd.h>
! 
  #include <fcntl.h>
  
+ #include "elmlib.h"
  #include "filter.h"
  #include "s_filter.h"
  
***************
*** 209,217 ****
  	FilterRegsubNine,	"<submatch-9>",
  };
  
! expand_macros(word, buffer, line, display)
! char *word, *buffer;
! int  line, display;
  {
  	/** expand the allowable macros in the word;
  		%d	= day of the month  
--- 141,150 ----
  	FilterRegsubNine,	"<submatch-9>",
  };
  
! void expand_macros(word, buffer, line, display, size)
!      char *word, *buffer;
!      int  line, display;
!      int size;
  {
  	/** expand the allowable macros in the word;
  		%d	= day of the month  
***************
*** 238,243 ****
--- 171,178 ----
  	time_t	thetime;
  	register int i, j=0, gotten_time = 0, reading_a_percent_sign = 0,
                       len, backslashed=0, regsub;
+ 	
+ 	buffer[0] = '\0';
  
  	for (i = 0, len = strlen(word); i < len; i++) {
  	  if (reading_a_percent_sign) {
***************
*** 244,359 ****
  	    reading_a_percent_sign = 0;
  	    switch (word[i]) {
  
! 	      case 'n' : buffer[j] = '\0';
  			 if (display)
! 			   strcat(buffer,catgets(elm_msg_cat,
  						 FilterSet,FilterSender,
! 						 "<sender>"));
  			 else {
! 			   strcat(buffer, "\"");
! 			   strcat(buffer, sender);
! 			   strcat(buffer, "\"");
  			 }
  			 j = strlen(buffer);
  			 break;
  
! 	      case 'r' : buffer[j] = '\0';
  			 if (display)
! 	 		   strcat(buffer,catgets(elm_msg_cat,
! 						 FilterSet,FilterReturnAddress,
! 						 "<return-address>"));
  			 else
! 			   strcat(buffer, from);
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 's' : buffer[j] = '\0';
  			 if (display)
! 	 		   strcat(buffer,catgets(elm_msg_cat,
  						FilterSet,FilterSubject,
! 						 "<subject>"));
  			 else {
! 			   strcat(buffer, "\"");
! 			   strcat(buffer, subject);
! 			   strcat(buffer, "\"");
  			 }
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 'S' : buffer[j] = '\0';
  			 if (display)
! 	 		   strcat(buffer,catgets(elm_msg_cat,
  						 FilterSet,FilterReSubject,
! 						 "<Re: subject>"));
  			 else {
! 			   strcat(buffer, "\"");
  			   if (! the_same(subject, "Re:")) 
! 			     strcat(buffer, "Re: ");
! 			   strcat(buffer, subject);
! 			   strcat(buffer, "\"");
  			 }
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 'd' : get_the_time(); buffer[j] = '\0';
  			 if (display)
! 			   strcat(buffer,catgets(elm_msg_cat,
  						 FilterSet,FilterDayOfMonth,
! 						 "<day-of-month>"));
  			 else
! 			   strcat(buffer, itoa(timerec->tm_mday,FALSE));
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 'D' : get_the_time(); buffer[j] = '\0';
  			 if (display)
! 			   strcat(buffer,catgets(elm_msg_cat,
! 						 FilterSet,FilterDayOfWeek,
! 						 "<day-of-week>"));
  			 else
! 			   strcat(buffer, itoa(timerec->tm_wday,FALSE));
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 'm' : get_the_time(); buffer[j] = '\0';
  			 if (display)
! 			   strcat(buffer,catgets(elm_msg_cat,
! 						 FilterSet,FilterMonth,
! 						 "<month>"));
  			 else
! 			   sprintf(&buffer[j],"%2.2d",timerec->tm_mon+1);
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 'y' : get_the_time(); buffer[j] = '\0';
  			 if (display)
! 			   strcat(buffer,catgets(elm_msg_cat,
! 						 FilterSet,FilterYear,
! 						 "<year>"));
  			 else
! 			   strcat(buffer, itoa(timerec->tm_year,FALSE));
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 'h' : get_the_time(); buffer[j] = '\0';
  			 if (display)
! 			   strcat(buffer,catgets(elm_msg_cat,
! 						 FilterSet,FilterHour,
! 						 "<hour>"));
  			 else
! 			   strcat(buffer, itoa(timerec->tm_hour,FALSE));
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 't' : get_the_time(); buffer[j] = '\0';
  			 if (display)
! 			   strcat(buffer,catgets(elm_msg_cat,
! 						 FilterSet,FilterTime,
! 						 "<time>"));
  		         else {
! 			   strcat(buffer, itoa(timerec->tm_hour,FALSE));
! 			   strcat(buffer, ":");
! 			   strcat(buffer, itoa(timerec->tm_min,TRUE));
  			 }
  	                 j = strlen(buffer);
  			 break;
--- 179,309 ----
  	    reading_a_percent_sign = 0;
  	    switch (word[i]) {
  
! 	      case 'n' : 
  			 if (display)
! 			   strfcat(buffer,catgets(elm_msg_cat,
  						 FilterSet,FilterSender,
! 						 "<sender>"),
! 				   size);
  			 else {
! 			   strfcat(buffer, "\"", size);
! 			   strfcat(buffer, sender, size);
! 			   strfcat(buffer, "\"", size);
  			 }
  			 j = strlen(buffer);
  			 break;
  
! 	      case 'r' : 
  			 if (display)
! 	 		   strfcat(buffer,catgets(elm_msg_cat,
! 						  FilterSet,
! 						  FilterReturnAddress,
! 						  "<return-address>"),
! 				   size);
  			 else
! 			   strfcat(buffer, from, sizeof buffer);
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 's' : 
  			 if (display)
! 	 		   strfcat(buffer,catgets(elm_msg_cat,
  						FilterSet,FilterSubject,
! 						 "<subject>"),
! 				   size);
  			 else {
! 			   strfcat(buffer, "\"", size);
! 			   strfcat(buffer, subject, size);
! 			   strfcat(buffer, "\"", size);
  			 }
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 'S' : 
  			 if (display)
! 	 		   strfcat(buffer,catgets(elm_msg_cat,
  						 FilterSet,FilterReSubject,
! 						 "<Re: subject>"),
! 				   size);
  			 else {
! 			   strfcat(buffer, "\"", size);
  			   if (! the_same(subject, "Re:")) 
! 			     strfcat(buffer, "Re: ", size);
! 			   strfcat(buffer, subject, size);
! 			   strfcat(buffer, "\"", size);
  			 }
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 'd' : get_the_time(); 
  			 if (display)
! 			   strfcat(buffer,catgets(elm_msg_cat,
  						 FilterSet,FilterDayOfMonth,
! 						  "<day-of-month>"),
! 				   size);
  			 else
! 			   strfcat(buffer, itoa(timerec->tm_mday,FALSE),size);
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 'D' : get_the_time(); 
  			 if (display)
! 			   strfcat(buffer,catgets(elm_msg_cat,
! 						  FilterSet,FilterDayOfWeek,
! 						  "<day-of-week>"),
! 				   size);
  			 else
! 			   strfcat(buffer, itoa(timerec->tm_wday,FALSE),
! 				   size);
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 'm' : get_the_time(); 
  			 if (display)
! 			   strfcat(buffer,catgets(elm_msg_cat,
! 						  FilterSet,FilterMonth,
! 						  "<month>"),
! 				   size);
  			 else
! 			   elm_sfprintf(&buffer[j],size,
! 					FRM("%2.2d"),
! 					timerec->tm_mon+1);
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 'y' : get_the_time(); 
  			 if (display)
! 			   strfcat(buffer,catgets(elm_msg_cat,
! 						  FilterSet,FilterYear,
! 						  "<year>"),
! 				   size);
  			 else
! 			   strfcat(buffer, itoa(timerec->tm_year,FALSE),
! 				   size);
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 'h' : get_the_time(); 
  			 if (display)
! 			   strfcat(buffer,catgets(elm_msg_cat,
! 						  FilterSet,FilterHour,
! 						  "<hour>"), size);
  			 else
! 			   strfcat(buffer, itoa(timerec->tm_hour,FALSE),
! 				   size);
  	                 j = strlen(buffer);
  			 break;
  
! 	      case 't' : get_the_time(); 
  			 if (display)
! 			   strfcat(buffer,catgets(elm_msg_cat,
! 						  FilterSet,FilterTime,
! 						  "<time>"),
! 				   size);
  		         else {
! 			   strfcat(buffer, itoa(timerec->tm_hour,FALSE), size);
! 			   strfcat(buffer, ":", size);
! 			   strfcat(buffer, itoa(timerec->tm_min,TRUE), size);
  			 }
  	                 j = strlen(buffer);
  			 break;
***************
*** 365,374 ****
  			 else regsub = word[i] - '0';
  
  			 if (display) {
! 			   strcpy(buffer + j,catgets(elm_msg_cat,
! 						 FilterSet,
! 						 regmessage[regsub].id,
! 						 regmessage[regsub].str));
  			   j = strlen(buffer);
  			 } else {
  			   if (last_regexp != NULL) {
--- 315,325 ----
  			 else regsub = word[i] - '0';
  
  			 if (display) {
! 			   strfcpy(buffer,catgets(elm_msg_cat,
! 						  FilterSet,
! 						  regmessage[regsub].id,
! 						  regmessage[regsub].str),
! 				   size);
  			   j = strlen(buffer);
  			 } else {
  			   if (last_regexp != NULL) {
***************
*** 375,381 ****
  			     char *sp = last_regexp->startp[regsub];
  			     char *ep = last_regexp->endp[regsub];
  			     if (sp != NULL && ep != NULL && ep > sp)
! 			       while (sp < ep) buffer[j++] = *sp++;
  			   }
  			 }
  			 break;
--- 326,334 ----
  			     char *sp = last_regexp->startp[regsub];
  			     char *ep = last_regexp->endp[regsub];
  			     if (sp != NULL && ep != NULL && ep > sp)
! 			       while (sp < ep && j < size-2) 
! 				 buffer[j++] = *sp++;
! 			     buffer[j] = '\0';
  			   }
  			 }
  			 break;
***************
*** 391,414 ****
  	  }
  	  else if (word[i] == '%') {
  	    if (backslashed) {
!                  buffer[j++] = '%';
!                  backslashed = 0;
              } else {
  	         reading_a_percent_sign++;
  	    }
  	  } else if (word[i] == '\\') {
  	    if (backslashed) {
! 		 buffer[j++] = '\\';
! 		 backslashed = 0;
  	    } else {
  		 backslashed++;
  	    }
  	  } else {
! 	    buffer[j++] = word[i];
  	    backslashed = 0;
  	  }
  	}
- 	buffer[j] = '\0';
  }
  
  print_rules()
--- 344,375 ----
  	  }
  	  else if (word[i] == '%') {
  	    if (backslashed) {
! 	      if (j < size-2) {
! 		buffer[j++] = '%';
! 		buffer[j] = '\0';       
! 	      }
! 	      backslashed = 0;
              } else {
  	         reading_a_percent_sign++;
  	    }
  	  } else if (word[i] == '\\') {
  	    if (backslashed) {
! 	      if (j < size-2) {
! 		buffer[j++] = '\\';
! 		buffer[j] = '\0';			
! 	      }
! 	      backslashed = 0;
  	    } else {
  		 backslashed++;
  	    }
  	  } else {
! 	    if (j < size-2) {
! 	      buffer[j++] = word[i];
! 	      buffer[j] = '\0';
! 	    }
  	    backslashed = 0;
  	  }
  	}
  }
  
  print_rules()
***************
*** 478,484 ****
  	  case SUBJECT: return("subject");
  	  case LINES  : return ("lines");
  	  case CONTAINS: return("contains");
! 	  default     : sprintf(buffer, "?%d?", n); return((char *)buffer);
  	}
  }
  
--- 439,447 ----
  	  case SUBJECT: return("subject");
  	  case LINES  : return ("lines");
  	  case CONTAINS: return("contains");
! 	  default     : elm_sfprintf(buffer, sizeof buffer,
! 				     FRM("?%d?"), n); 
! 	  return((char *)buffer);
  	}
  }
  
Index: elm2.4.ME+.50/filter/summarize.c
*** elm2.4.25/filter/summarize.c	Mon Feb  8 20:38:13 1993
--- elm2.4.ME+.50/filter/summarize.c	Tue Nov 17 21:12:54 1998
***************
*** 1,57 ****
  
! static char rcsid[] ="@(#)$Id: summarize.c,v 5.8 1993/02/08 18:38:12 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.8 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein - elm@DSI.COM
!  *			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: summarize.c,v $
!  * Revision 5.8  1993/02/08  18:38:12  syd
!  * Fix to copy_file to ignore unescaped from if content_length not yet reached.
!  * Fixes to NLS messages match number of newlines between default messages
!  * and NLS messages. Also an extra ) was removed.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.7  1993/01/27  19:40:01  syd
!  * I implemented a change to filter's default verbose message format
!  * including %x %X style date and time along with username
!  * From: mark@drd.com (Mark Lawrence)
!  *
!  * Revision 5.6  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.5  1992/12/07  05:14:19  syd
!  * add sys/types.h for time_t
!  * From: Syd
!  *
!  * Revision 5.4  1992/11/15  01:40:43  syd
!  * Add regexp processing to filter.
!  * Add execc operator
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.3  1992/11/07  20:48:55  syd
!  * fix applied rule count message
!  *
!  * Revision 5.2  1992/10/24  14:20:24  syd
!  * remove the 25 (MAXRULES) limitation.
!  * Basically it mallocs rules in hunks of RULESINC (25) as it goes along.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.1  1992/10/03  22:18:09  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This routine is called from the filter program (or can be called
      directly with the correct arguments) and summarizes the users filterlog
--- 1,16 ----
  
! static char rcsid[] ="@(#)$Id: summarize.c,v 1.2 1998/10/20 19:57:27 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This routine is called from the filter program (or can be called
      directly with the correct arguments) and summarizes the users filterlog
***************
*** 67,72 ****
--- 26,33 ----
  #include <stdio.h>
  
  #include "defs.h"
+ #include "elmlib.h"
+ 
  #include "filter.h"
  #include "s_filter.h"
  
***************
*** 85,91 ****
  	     rule,
  	     *applied;
  
! 	sprintf(filename, "%s/%s", home, filtersum);
  
  	if ((fd = fopen(filename, "r")) == NULL) {
  	  if (outfd != NULL)
--- 46,54 ----
  	     rule,
  	     *applied;
  
! 	elm_sfprintf(filename, sizeof filename,
! 		     FRM("%s/%s"), 
! 		     home, filtersum);
  
  	if ((fd = fopen(filename, "r")) == NULL) {
  	  if (outfd != NULL)
***************
*** 254,260 ****
  
  	  /* next, after a ^L, include the actual log file... */
  
! 	  sprintf(filename, "%s/%s", home, filterlog);
  
  	  if ((fd = fopen(filename, "r")) == NULL) {
  	    fprintf(outfd,catgets(elm_msg_cat,
--- 217,225 ----
  
  	  /* next, after a ^L, include the actual log file... */
  
! 	  elm_sfprintf(filename, sizeof filename,
! 		       FRM("%s/%s"), 
! 		       home, filterlog);
  
  	  if ((fd = fopen(filename, "r")) == NULL) {
  	    fprintf(outfd,catgets(elm_msg_cat,
***************
*** 276,284 ****
  	/* now remove the log files, please! */
  
  	if (clear_logs) {
! 	  sprintf(filename, "%s/%s", home, filterlog);
  	  unlink(filename);
! 	  sprintf(filename, "%s/%s", home, filtersum);
  	  unlink(filename);
  	}
  
--- 241,253 ----
  	/* now remove the log files, please! */
  
  	if (clear_logs) {
! 	  elm_sfprintf(filename, sizeof filename,
! 		       FRM("%s/%s"), 
! 		       home, filterlog);
  	  unlink(filename);
! 	  elm_sfprintf(filename, sizeof filename,
! 		       FRM("%s/%s"), 
! 		       home, filtersum);
  	  unlink(filename);
  	}
  
Index: elm2.4.ME+.50/filter/utils.c
*** elm2.4.25/filter/utils.c	Tue Aug  3 22:28:42 1993
--- elm2.4.ME+.50/filter/utils.c	Tue Nov 17 21:12:54 1998
***************
*** 1,46 ****
  
! static char rcsid[] ="@(#)$Id: utils.c,v 5.4 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein - elm@DSI.COM
!  *			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: utils.c,v $
!  * Revision 5.4  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.3  1993/01/27  19:40:01  syd
!  * I implemented a change to filter's default verbose message format
!  * including %x %X style date and time along with username
!  * From: mark@drd.com (Mark Lawrence)
!  *
!  * Revision 5.2  1992/11/15  01:40:43  syd
!  * Add regexp processing to filter.
!  * Add execc operator
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.1  1992/10/03  22:18:09  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** Utility routines for the filter program...
  
--- 1,16 ----
  
! static char rcsid[] ="@(#)$Id: utils.c,v 1.2 1998/10/20 19:57:27 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** Utility routines for the filter program...
  
***************
*** 51,56 ****
--- 21,28 ----
  #include <fcntl.h>
  
  #include "defs.h"
+ #include "elmlib.h"
+ 
  #include "filter.h"
  #include "s_filter.h"
  
***************
*** 81,87 ****
  		return;
  
  	if (! show_only) {
! 	  sprintf(filename, "%s/%s", home, filtersum);	/* log action once! */
  	  if ((fd = fopen(filename, "a")) == NULL) {
  	    if (outfd != NULL)
  	      fprintf(outfd,catgets(elm_msg_cat,
--- 53,61 ----
  		return;
  
  	if (! show_only) {
! 	  elm_sfprintf(filename, sizeof filename,
! 		       FRM("%s/%s"), 
! 		       home, filtersum);	/* log action once! */
  	  if ((fd = fopen(filename, "a")) == NULL) {
  	    if (outfd != NULL)
  	      fprintf(outfd,catgets(elm_msg_cat,
***************
*** 94,100 ****
  	  fclose(fd);
  	}
  
! 	sprintf(filename, "%s/%s", home, filterlog);
  
  	if (show_only)
  	  fd = stdout;
--- 68,76 ----
  	  fclose(fd);
  	}
  
! 	elm_sfprintf(filename, sizeof filename,
! 		     FRM("%s/%s"), 
! 		     home, filterlog);
  
  	if (show_only)
  	  fd = stdout;
***************
*** 241,255 ****
   * it has been stripped down to only handle ~ expansion
   */
  
! expand_filename(filename)
! char *filename;
  {
  	/** Expands	~/	to the current user's home directory
  
  	    Side effect: strips off trailing blanks
  
- 	    Returns 	1	upon proper expansions
- 			0	upon failed expansions
  	 **/
  
  	char temp_filename[SLEN], *ptr;
--- 217,230 ----
   * it has been stripped down to only handle ~ expansion
   */
  
! void expand_filename(filename, namesize)
!      char *filename;
!      int namesize;
  {
  	/** Expands	~/	to the current user's home directory
  
  	    Side effect: strips off trailing blanks
  
  	 **/
  
  	char temp_filename[SLEN], *ptr;
***************
*** 256,262 ****
  
  	ptr = filename;
  	while (*ptr == ' ') ptr++;	/* leading spaces GONE! */
! 	strcpy(temp_filename, ptr);
  
  	/** New stuff - make sure no illegal char as last **/
  	ptr = temp_filename + strlen(temp_filename) - 1;
--- 231,237 ----
  
  	ptr = filename;
  	while (*ptr == ' ') ptr++;	/* leading spaces GONE! */
! 	strfcpy(temp_filename, ptr, sizeof temp_filename);
  
  	/** New stuff - make sure no illegal char as last **/
  	ptr = temp_filename + strlen(temp_filename) - 1;
***************
*** 269,276 ****
  
  	if ((temp_filename[0] == '~') &&
  	    (temp_filename[1] == '/')) {
! 	    sprintf(filename, "%s%s%s",
! 		  home, (lastch(home) != '/' ? "/" : ""), &temp_filename[2]);
  
  	/* any further expansion, such as = + < >
  	 * would require parsing the elmrc file
--- 244,253 ----
  
  	if ((temp_filename[0] == '~') &&
  	    (temp_filename[1] == '/')) {
! 	    elm_sfprintf(filename, namesize,
! 			 FRM("%s%s%s"),
! 			 home, (lastch(home) != '/' ? "/" : ""), 
! 			 &temp_filename[2]);
  
  	/* any further expansion, such as = + < >
  	 * would require parsing the elmrc file
***************
*** 277,283 ****
  	 */
  
  	} else
! 	  strcpy(filename, temp_filename);
  	  
- 	return(1);
  }
--- 254,263 ----
  	 */
  
  	} else
! 	  strfcpy(filename, temp_filename, namesize);
  	  
  }
+ 
+ 
+ 
+ 
Index: elm2.4.ME+.50/hdrs/curses.h
*** elm2.4.25/hdrs/curses.h	Sun Oct  4 01:35:06 1992
--- elm2.4.ME+.50/hdrs/curses.h	Tue Nov 17 21:12:54 1998
***************
*** 1,44 ****
  
! /* $Id: curses.h,v 5.1 1992/10/03 22:34:39 syd Exp $ */
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: curses.h,v $
!  * Revision 5.1  1992/10/03  22:34:39  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
! 
!      /*** Include file for seperate compilation.  ***/
  
  #define OFF		0
  #define ON 		1
  
! int  InitScreen(),      /* This must be called before anything else!! */
! 
!      ClearScreen(), 	 CleartoEOLN(),
! 
!      MoveCursor(),
! 
!      StartBold(),        EndBold(), 
!      StartUnderline(),   EndUnderline(), 
!      StartHalfbright(),  EndHalfbright(),
!      StartInverse(),     EndInverse(),
! 	
!      transmit_functions(),
! 
!      Raw(),              RawState(),
!      ReadCh();
! 
! char *return_value_of();
--- 1,47 ----
  
! /* $Id: curses.h,v 1.2 1998/10/20 19:57:35 hurtta Exp $ */
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  ****************************************************************************/
  
  #define OFF		0
  #define ON 		1
  
! #undef P_
! #ifdef __STDC__
! #define P_(x) x
! #else
! #define P_(x) ()
! #endif
! 
! extern int InitScreen P_(()),      /* This must be called before anything else!! */
!   ClearScreen P_((void)), 	 
!   CleartoEOLN P_((void)),
!   MoveCursor  P_((int, int)),
!   StartBold P_((void)),        
!   EndBold P_((void)), 
!   StartUnderline P_((void)),   
!   EndUnderline   P_((void)),
!   StartHalfbright P_((void)),  
!   EndHalfbright   P_((void)),
!   StartInverse P_((void)),     
!   EndInverse   P_((void)),
!   transmit_functions P_((int)),
!   Raw P_((int)),              
!   RawState P_((void)),
!   ReadCh P_((int));
! 
! extern void ScreenSize P_((int *lines, int *columns));
! extern void Write_to_screen P_((
! 				const char *format, const char *msg, ...
! 				));
! extern void PutLine0 P_((int, int, const char *));
! extern void PutLineX P_((int, int, const char *, const char *, ...));
Index: elm2.4.ME+.50/hdrs/defs.h
*** elm2.4.25/hdrs/defs.h	Mon Dec  4 17:50:56 1995
--- elm2.4.ME+.50/hdrs/defs.h	Tue Nov 17 21:12:55 1998
***************
*** 1,189 ****
  
! /* $Id: defs.h,v 5.35 1994/09/01 19:42:39 syd Exp $ */
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.35 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: defs.h,v $
!  * Revision 5.35  1994/09/01  19:42:39  syd
!  * Moved #defines for SETJMP & LONGJMP from src/editmsg.c to hdrs/defs.h and
!  * used them instead of (set|long)jmp directly. This makes the usage consistent
!  * and Solaris 2.3 behaves correctly w.r.t stop/continue.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.34  1994/05/15  23:10:08  syd
!  * Below are the changes required to compile/link elm 2.4 pl23 under
!  * QNX 4.2 with the Watcom 9.5 compiler (very picky).
!  * From: "Brian Campbell" <brianc@quantum>
!  *
!  * Revision 5.33  1993/09/19  23:40:48  syd
!  * Defince SEEK_SET in one of our headers as a last resort
!  * From: Syd
!  *
!  * Revision 5.32  1993/08/23  02:46:51  syd
!  * Test ANSI_C, not __STDC__ (which is not set on e.g. AIX).
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.31  1993/08/23  02:45:29  syd
!  * The macro ctrl(c) did not work correctly for a DEL character
!  * neither did it make the backward mapping from a control char
!  * to the letter that is normally used with an up-arrow prefix
!  * to represent the control character.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.30  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.29  1993/08/03  19:05:33  syd
!  * When STDC is used on Convex the feof() function is defined as
!  * a true library routine in the header files and moreover the
!  * library routine also leaks royally. It returns always 1!!
!  * So we have to use a macro. Convex naturally does not provide
!  * you with one though if you are using a STDC compiler. So we
!  * have to include one.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.28  1993/07/20  02:59:53  syd
!  * Support aliases both on 64 bit and 32 bit machines at the same time.
!  * From: Dan Mosedale <mosedale@genome.stanford.edu>
!  *
!  * Revision 5.27  1993/05/08  19:41:13  syd
!  * make it now depend on mallocvoid
!  *
!  * Revision 5.26  1993/04/16  04:16:24  syd
!  * For convex, #if-defed memcpy, memset and sleep.
!  * From: rzm@oso.chalmers.se (Rafal Maszkowski)
!  *
!  * Revision 5.25  1993/04/12  03:30:23  syd
!  * On AIX, __STDC__ is not defined but it does use unistd.h, etc.  In
!  * hdrs/def.h, ANS_C already gets defined if __STDC__ or _AIX.  But this
!  * variable then needs to be used in src/init.c and hdrs/filter.h in place
!  * of the current test for __STDC__.
!  * From:	rstory@elegant.com (Robert Story)
!  *
!  * Revision 5.24  1993/04/12  03:25:26  syd
!  * Use I_UNISTD instead of UNISTD_H
!  *
!  * Revision 5.23  1993/04/12  03:22:49  syd
!  * Add UNISTD_H to check for unistd.h include
!  * From: Syd
!  *
!  * Revision 5.22  1993/04/12  01:51:42  syd
!  * Added safe_malloc(), safe_realloc(), and safe_strdup().  They
!  * will be used in the new elmalias utility.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.21  1993/02/09  15:31:10  syd
!  * Make the str declare symbol ANSI_C, our contrived symbol
!  * so IBM compiles work ok.
!  * From: Syd
!  *
!  * Revision 5.20  1993/02/07  15:12:50  syd
!  * fix declaration of fseek, it was of the wrong type (sb int, was long)
!  *
!  * Revision 5.19  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.18  1993/02/03  16:56:24  syd
!  * add unistd.h for include of lseek/fseek on stdc compilers
!  * From: Syd via prompt from mfvargo@netcom.com (Michael Vargo)
!  *
!  * Revision 5.17  1993/02/03  16:18:17  syd
!  * add strtokq
!  * From: Syd
!  *
!  * Revision 5.16  1993/01/20  03:02:19  syd
!  * Move string declarations to defs.h
!  * From: Syd
!  *
!  * Revision 5.15  1993/01/20  02:56:38  syd
!  * hide index and rindex declarations inside __STDC__ so AIX doesnt see it
!  *
!  * Revision 5.14  1993/01/19  05:07:05  syd
!  * Trim erroreous extra log entry
!  * From: Syd
!  *
!  * Revision 5.13  1993/01/19  04:47:12  syd
!  * Significant changes to provide consistent Date and From_ header
!  * cracking.  Overhauled date utilities and moved into library.  Moved
!  * real_from() into library.  Modified frm, newmail, and readmsg utilities
!  * to use library version of real_from().  Moved get_word() from Elm
!  * source into library.  Added new library routines atonum() and strfcpy().
!  * Fixed trailing backslash bug in len_next().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.12  1993/01/05  03:36:10  syd
!  * remove leading 0s from access() defs as it confuses some
!  * compilers (and I know it shouldnt)
!  * From: Syd
!  *
!  * Revision 5.11  1992/12/11  01:58:50  syd
!  * Allow for use from restricted shell by putting SHELL=/bin/sh in the
!  * environment of spawned mail transport program.
!  * From: chip@tct.com (Chip Salzenberg)
!  *
!  * Revision 5.10  1992/12/11  01:29:27  syd
!  * add include of sys/types.h for time_t usage
!  *
!  * Revision 5.9  1992/12/07  02:47:45  syd
!  * fix time variables that are not declared time_t
!  * From: Syd via prompting from Jim Brown
!  *
!  * Revision 5.8  1992/11/26  01:46:26  syd
!  * add Decode option to copy_message, convert copy_message to
!  * use bit or for options.
!  * From: Syd and bjoerns@stud.cs.uit.no (Bjoern Stabell)
!  *
!  * Revision 5.7  1992/11/22  01:22:29  syd
!  * This mod fixes overlapping prototypes for strchr and index on
!  * Convex.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.6  1992/11/07  20:40:27  syd
!  * flag for no tite for curses calls
!  *
!  * Revision 5.5  1992/11/07  20:05:52  syd
!  * change to use header_cmp to allow for linear white space around the colon
!  * From: Syd
!  *
!  * Revision 5.4  1992/10/27  01:40:08  syd
!  * fix compilation error on posix_signals for non STDC
!  * From: tom@osf.org
!  *
!  * Revision 5.3  1992/10/25  02:01:58  syd
!  * Here are the patches to support POSIX sigaction().
!  * From: tom@osf.org
!  *
!  * Revision 5.2  1992/10/25  01:47:45  syd
!  * fixed a bug were elm didn't call metamail on messages with a characterset,
!  * which could be displayed by elm itself, but message is encoded with QP
!  * or BASE64
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.1  1992/10/03  22:34:39  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /**  define file for ELM mail system.  **/
  
--- 1,16 ----
  
! /* $Id: defs.h,v 1.2 1998/10/20 19:57:35 hurtta Exp $ */
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /**  define file for ELM mail system.  **/
  
***************
*** 194,208 ****
  #include "sysdefs.h"	/* system/configurable defines */
  
  
! # define VERSION	"2.4"				/* Version number... */
! # define VERS_DATE	"November 11, 1995"		/* for elm -v option */
! # define WHAT_STRING	\
! 	"@(#) Version 2.4, USENET supported version, released November 11, 1995"
  
  #if defined(__STDC__) || defined(_AIX)
  # define ANSI_C 1
  #endif
  
  #define KLICK		25
  
  #define SLEN		256	    /* long for ensuring no overwrites... */
--- 21,38 ----
  #include "sysdefs.h"	/* system/configurable defines */
  
  
! # define VERSION	"2.4ME+"		/* Version number... */
  
  #if defined(__STDC__) || defined(_AIX)
  # define ANSI_C 1
  #endif
  
+ #if ANSI_C 
+ #define VOLATILE volatile
+ #else
+ #define VOLATILE
+ #endif
+ 
  #define KLICK		25
  
  #define SLEN		256	    /* long for ensuring no overwrites... */
***************
*** 231,238 ****
--- 61,84 ----
  #define TILDE_ESCAPE	'~'		/* escape character~    */
  #define ESCAPE		'\033'		/* the escape		*/
  
+ 
  #define NO_OP_COMMAND	'\0'		/* no-op for timeouts   */
  
+ #define READCH_MASK      0x0FFF         /* Mask flags off        */
+ #define READCH_CURSOR    0x1000         /* Return cursor keys    */      
+ #define READCH_NOCURSOR  0x2000         /* Disable cursor keys   */      
+ 
+ #define REDRAW_MARK    257              /* Artificial "char" for  redrawing */
+ #define UP_MARK        258              /* Artificial UP key    */
+ #define LEFT_MARK      259              /* Artificial LEFT key  */
+ #define RIGHT_MARK     260              /* Artificial RIGHT key */
+ #define DOWN_MARK      261              /* Artificial DOWN key  */
+ #define PAGEUP_MARK    262              /* Artificial PAGE UP key */
+ #define PAGEDOWN_MARK  263              /* Artificial PAGE DOWN key */
+ #define HELP_MARK      264              /* Artificial HELP key      */
+ #define HOME_MARK      265              /* Artificial HOME key      */
+ #define FIND_MARK      266              /* Artificial FIND key      */
+ 
  #define STANDARD_INPUT  0		/* file number of stdin */
  
  #ifndef TRUE
***************
*** 263,268 ****
--- 109,117 ----
  #define SY_ENAB_SIGHUP	(1<<2)		/* pgm to exec can handle signals    */
  #define SY_ENAB_SIGINT	(1<<3)		/*  ...and it can handle SIGINT too  */
  #define SY_DUMPSTATE	(1<<4)		/* create folder state dump file     */
+ #define SY_ENV_METAMAIL	(1<<5)		/* put MM_CHARSET to environ         */
+ #define SY_NOTTY	(1<<6)		/* no tty                    */
+ #define SY_CLRWAIT	(1<<7)		/* clr and wait 'any key' in end     */
  
  /* options to the copy_message() procedure */
  #define CM_REMOVE_HEADER	(1<<0)	/* skip header of message */
***************
*** 270,282 ****
  #define CM_UPDATE_STATUS	(1<<2)	/* Update Status: Header  */
  #define CM_MMDF_HEAD		(1<<3)	/* strip mmdf message seperator */
  #define CM_REMAIL		(1<<4)	/* Add Sender: and Orig-To: headers */
! #define CM_DECODE		(1<<5)	/* prompt for key if message is encrypted */
  
! #define EXECUTE_ACCESS	1		/* These five are 	   */
! #define WRITE_ACCESS	2		/*    for the calls	   */
! #define READ_ACCESS	4		/*       to access()       */
! #define ACCESS_EXISTS	0		/*           <etc>         */
! #define EDIT_ACCESS	6		/*  (this is r+w access)   */
  
  #define BIG_NUM		999999		/* big number!             */
  #define BIGGER_NUM	9999999 	/* bigger number!          */
--- 119,144 ----
  #define CM_UPDATE_STATUS	(1<<2)	/* Update Status: Header  */
  #define CM_MMDF_HEAD		(1<<3)	/* strip mmdf message seperator */
  #define CM_REMAIL		(1<<4)	/* Add Sender: and Orig-To: headers */
! #define CM_DECODE		(1<<5)	/* Decode MIME, PGP and elm */
! #define CM_FILT_HDR		(1<<6)  /* Filter headers (for forwarding) */
! #define CM_DISPLAYING		(1<<7)  /* Pass to MIME code */
! #define CM_REMOVE_ENVELOPE	(1<<8)	/* Remove envelope */
! 
! /* Options for mail() procedure */
! #define MAIL_COPY_MSG          (1<<0)
! #define MAIL_EDIT_MSG          (1<<1)
! #define MAIL_ISFORM            (1<<2)
! #define MAIL_REPLYING          (1<<3)
! #define MAIL_FORWARDING        (1<<4)
! #define MAIL_HAVE_ATTACHMENTS  (1<<5)    /* Flag for verify transmission */
! #define MAIL_HAVE_PGP_ENCODED  (1<<6)    /* Falg for verify transmission */
! 
! /* options to the optionally_enter() function */
! #define OE_APPEND_CURRENT      (1<<0) 
! #define OE_PASSWD              (1<<1)
! #define OE_REDRAW_MARK         (1<<2)
  
! /* xxx_ACCESS moved to down after including of unistd.h */
  
  #define BIG_NUM		999999		/* big number!             */
  #define BIGGER_NUM	9999999 	/* bigger number!          */
***************
*** 287,292 ****
--- 149,160 ----
  #define DONT_SAVE	"[no save]"
  #define DONT_SAVE2	"[nosave]"
  
+ 
+ /* They are used to support Grab_the_file in save() */
+ #define  FLOCKING_OK 0
+ #define  FLOCKING_RETRY 1
+ #define  FLOCKING_FAIL  -1
+ 
  #define alias_file	".aliases"
  #define group_file	".groups"
  #define system_file	".systems"
***************
*** 309,330 ****
  
  /** some defines for the "status" field of the header and alias record **/
  
! #define ACTION		1		/* bit masks, of course */
! #define CONFIDENTIAL	2
! #define DELETED		4
! #define EXPIRED		8
! #define FORM_LETTER	16
! #define NEW		32
! #define PRIVATE		64
! #define TAGGED		128
! #define URGENT		256
! #define VISIBLE		512
! #define UNREAD		1024
! #define STATUS_CHANGED	2048
! #define MIME_MESSAGE	4096	/* indicates existence of MIME Header */
! #define MIME_NEEDDECOD	8192	/* indicates that we need to call mmdecode */
! #define	MIME_NOTPLAIN	16384	/* indicates that we have a content-type,
! 				   for which we need metamail anyway. */
  
  /** some defines for the "type" field of the alias record **/
  
--- 177,205 ----
  
  /** some defines for the "status" field of the header and alias record **/
  
! #define ACTION               1          /* bit masks, of course */
! #define CONFIDENTIAL         2
! #define DELETED              4
! #define EXPIRED              8
! #define FORM_LETTER         16
! #define NEW                 32
! #define PRIVATE             64
! #define TAGGED             128
! #define URGENT             256
! #define VISIBLE            512
! #define UNREAD            1024
! #define REPLIED           2048
! #define MIME_MESSAGE      4096  /* indicates existence of MIME Header */
! #define PRE_MIME_CONTENT  8192
! #define MIME_UNSUPPORTED 16384
! #define NOHDRENCODING    32768
! /* Don't add values bigger than 2^15 == 32768 */
! 
! #ifdef USE_PGP
! #define PGP_MESSAGE		1
! #define PGP_SIGNED_MESSAGE	2
! #define PGP_PUBLIC_KEY		4
! #endif
  
  /** some defines for the "type" field of the alias record **/
  
***************
*** 414,419 ****
--- 289,307 ----
  extern char		*getenv();
  #endif
  
+ 
+ #ifdef I_TIME
+ #  include <time.h>
+ #endif
+ #ifdef I_SYSTIME
+ #  include <sys/time.h>
+ #endif
+ 
+ #ifndef	_POSIX_SOURCE
+ extern struct tm *localtime();
+ extern time_t	  time();
+ #endif
+ 
  /* find tab stops preceding or following a given column position 'a', where
   * the column position starts counting from 1, NOT 0!
   * The external integer "tabspacing" must be declared to use this. */
***************
*** 420,431 ****
  #define prev_tab(a)	(((((a-1)/tabspacing))*tabspacing)+1)
  #define next_tab(a)	(((((a-1)/tabspacing)+1)*tabspacing)+1)
  
- #define movement_command(c)	(c == 'j' || c == 'k' || c == ' ' || 	      \
- 				 c == BACKSPACE || c == ESCAPE || c == '*' || \
- 				 c == '-' || c == '+' || c == '=' ||          \
- 				 c == '#' || c == '@' || c == 'x' || 	      \
- 				 c == 'a' || c == 'q')
- 
  #define no_ret(s)	{ register int xyz; /* varname is for lint */	      \
  		          for (xyz=strlen(s)-1; xyz >= 0 && 		      \
  				(s[xyz] == '\r' || s[xyz] == '\n'); )	      \
--- 308,313 ----
***************
*** 506,526 ****
  #define PMALLOC_THRESHOLD	256	/* if greater, then just use malloc */
  #define PMALLOC_BUFFER_SIZE    2048	/* internal [memory] buffer size... */
  
  /** the following macro is as suggested by Larry McVoy.  Thanks! **/
  
  # ifdef DEBUG
! #  define   dprint(n,x)		{ 				\
! 				   if (debug >= n)  {		\
  				     fprintf x ; 		\
  				     fflush(debugfile);         \
  				   }				\
! 				}
  # else
  #  define   dprint(n,x)
  # endif
  
  /* some random structs... */
  
  struct header_rec {
  	int  lines;		/** # of lines in the message	**/
  	int  status;		/** Urgent, Deleted, Expired?	**/
--- 388,455 ----
  #define PMALLOC_THRESHOLD	256	/* if greater, then just use malloc */
  #define PMALLOC_BUFFER_SIZE    2048	/* internal [memory] buffer size... */
  
+ /* Flags for  classify_header in parse_util.c */
+ 
+ #define HDR_TEXT       1
+ #define HDR_STRUCTURED 2
+ #define HDR_PHRASE     4
+ #define HDR_COMMENT    8     /* inside of comment -- for rfc1522_encode_text */
+ 
  /** the following macro is as suggested by Larry McVoy.  Thanks! **/
  
  # ifdef DEBUG
! #  define   dprint(n,x)		do { 				\
! 				   if (debug >= n && debugfile)  {  \
  				     fprintf x ; 		\
  				     fflush(debugfile);         \
  				   }				\
! 				} while(0)
  # else
  #  define   dprint(n,x)
  # endif
  
+ /* Values for dsn flag */
+ #define DSN_FULL    1
+ #define DSN_HDRS    2
+ #define DSN_SUCCESS 4
+ #define DSN_FAILURE 8
+ #define DSN_DELAY   16
+ #define DSN_NEVER   32
+ 
  /* some random structs... */
  
+ #ifdef MIME
+ #define MIME_magic              0xFD00
+ typedef struct mimeinfo {
+   unsigned short magic;         /* MIME_magic */
+   unsigned char  type;          /* see mime.h for MIME_TYPE_* */
+   unsigned int disposition : 1; /* DISP_INLINE or DISP_ATTACH */
+   unsigned int unlink : 1;      /* used to mark that the file should be
+                                  * unlinked after sending the attachment */
+   unsigned int notplain : 1;
+ 
+   char subtype[WLEN];
+   char *type_opts;
+   char *disposition_opts;
+   char *description;
+ 
+   int encoding;      /* Notice: ENCODING_ILLEGAL == -1, ENCODING_* in mime.h */
+   long length;
+   long begin_offset; /* the beginning of the attachment (includes headers) */
+   long offset;       /* where the real data starts */
+   int flags;
+ 
+   struct mimeinfo *parts; /* If this is a multipart message, pointer
+                            * to the list of parts contained inside it */
+   
+   struct mimeinfo *next; /* pointer to the next attachment in the list */
+   
+   /* These next fields are only used when sending multipart messages. */
+   char *pathname;
+   struct mimeinfo *prev;
+ } mime_t;
+ #endif
+ 
  struct header_rec {
  	int  lines;		/** # of lines in the message	**/
  	int  status;		/** Urgent, Deleted, Expired?	**/
***************
*** 531,538 ****
  	long content_length;	/** content_length in bytes from message header	**/
  	long offset;		/** offset in bytes of message	**/
  	time_t received_time;	/** when elm received here	**/
! 	char from[STRING];	/** who sent the message?	**/
! 	char to[STRING];	/** who it was sent to		**/
  	char messageid[STRING];	/** the Message-ID: value	**/
  	char time_zone[12];	/**                incl. tz	**/
  	time_t time_sent;	/** gmt when sent for sorting	**/
--- 460,469 ----
  	long content_length;	/** content_length in bytes from message header	**/
  	long offset;		/** offset in bytes of message	**/
  	time_t received_time;	/** when elm received here	**/
!         char env_from[STRING];  /* sender from "From "          */
! 	struct addr_item *from;	/** who sent the message?	**/
! 	struct addr_item *to;	/** who it was sent to		**/
!         struct addr_item *cc;
  	char messageid[STRING];	/** the Message-ID: value	**/
  	char time_zone[12];	/**                incl. tz	**/
  	time_t time_sent;	/** gmt when sent for sorting	**/
***************
*** 540,553 ****
--- 471,528 ----
  	time_t tz_offset;	/** offset to gmt of time sent	**/
  	char subject[STRING];   /** The subject of the mail	**/
  	char mailx_status[WLEN];/** mailx status flags (RO...)	**/
+ #ifdef MIME
+ 	mime_t mime_rec;        /** MIME information for this message **/
+ #endif
+ #ifdef USE_PGP
+ 	unsigned int pgp : 3;
+ #endif
+ 	unsigned int binary :1;  /* Binary message -- headers are terminated
+ 				  * with \r\n 
+ 				  */
         };
  
+ #if  ANSI_C
+ # include <stdarg.h>
+ # define Va_start(a,b) va_start(a,b)
+ #else
+ # include <varargs.h>
+ # define Va_start(a,b) va_start(a)
+ #endif
+ 
+ /* inttypes.h includes stdarg.h, so it conflicts with varargs.h 
+  *
+  * varargs.h does not work in 64 bit IRIXes...
+  */
+ 
+ /* inttypes.h can't be used if it conflicts with sys/types.h
+  *
+  * unfortunately sys/types.h does not define uint16_t (in IRIX 5.3),
+  * but including of inttypes.h causes compilation error!
+  */
+ 
+ #if defined(I_INTTYPES) && ANSI_C && !defined(NO_INTTYPES)
+ 
+ #include <inttypes.h>
+ 
+ /* For support 64 bit IRIXes also */
+ #define int32 int32_t
+ #define uint16 uint16_t
+ 
+ #else /* I_INTTYPES */
+ 
  #ifdef __alpha
  #define int32 int
+ #define uint16 unsigned short    /* is this correct? */
  #else
+ 
  #define int32 long
+ #define uint16 unsigned short
+ 
  #endif
  
+ #endif /* I_INTTYPES */
+ 
  struct alias_disk_rec {
  	int32 status;			/* DELETED, TAGGED, VISIBLE, ...     */
  	int32 alias;			/* alias name                        */
***************
*** 621,672 ****
  #  endif
  #endif
  
! #ifndef ANSI_C   /* ANSI puts these in string.h */
  char *index(), *rindex(); /* names will be traslated by define in config.h */
! char *strtok(), *strcpy(), *strcat(), *strncpy(); /* more in string.h in ANSI */
  long lseek();
  int fseek();
- #if defined(__convexc__)
- unsigned sleep();
- #else
- unsigned long sleep();
  #endif
  #else
! #  ifdef I_UNISTD /* unistd.h available */
! #    include <unistd.h> /* ansi C puts sleep, lseek and fseek in unistd.h */
! #  else /* I_UNISTD */
! long lseek();
! int fseek();
! unsigned long sleep();
! #  endif /* I_UNISTD */
  #endif
  char *strtokq(); /* our own quote minding strtok */
  
- #ifndef STRSTR
- char *strstr();
- #endif
  
  #ifdef I_LOCALE
  #include <locale.h>
  #endif
  
  #ifdef I_NL_TYPES
  #include <nl_types.h>
  #else
! #include "../hdrs/nl_types.h"
  #endif
  
- #ifndef	USENLS
  #define MCprintf printf
  #define MCfprintf fprintf
  #define MCsprintf sprintf
! #else
  #include "mcprt.h"
- #endif
  
  #ifdef POSIX_SIGNALS
  #define signal posix_signal
! #if ANSI_C
  extern SIGHAND_TYPE (*posix_signal(int, SIGHAND_TYPE (*)(int)))(int);
  #else	/* ANSI_C */
  extern SIGHAND_TYPE (*posix_signal())();
--- 596,655 ----
  #  endif
  #endif
  
! #ifdef I_UNISTD
! #include <unistd.h>
! #else
! unsigned sleep();
  char *index(), *rindex(); /* names will be traslated by define in config.h */
! char *strcpy(), *strcat(), *strncpy(); /* more in string.h in ANSI */
  long lseek();
  int fseek();
  #endif
+ 
+ /* Defined in unistd.h ... */
+ #ifdef F_OK
+ #define EXECUTE_ACCESS  X_OK
+ #define WRITE_ACCESS    W_OK
+ #define READ_ACCESS     R_OK
+ #define ACCESS_EXISTS   F_OK
+ #define EDIT_ACCESS     (W_OK|R_OK)
  #else
! #define EXECUTE_ACCESS	1		/* These five are 	   */
! #define WRITE_ACCESS	2		/*    for the calls	   */
! #define READ_ACCESS	4		/*       to access()       */
! #define ACCESS_EXISTS	0		/*           <etc>         */
! #define EDIT_ACCESS	6		/*  (this is r+w access)   */
  #endif
+ 
  char *strtokq(); /* our own quote minding strtok */
  
  
  #ifdef I_LOCALE
  #include <locale.h>
  #endif
  
+ #ifndef	USENLS
+ 
  #ifdef I_NL_TYPES
  #include <nl_types.h>
  #else
! #include "elm_nl_types.h"
  #endif
  
  #define MCprintf printf
  #define MCfprintf fprintf
  #define MCsprintf sprintf
! 
! #else /* USENLS */
! 
! #include "elm_nl_types.h"
  #include "mcprt.h"
  
+ #endif /* USENLS */
+ 
  #ifdef POSIX_SIGNALS
  #define signal posix_signal
! #ifdef ANSI_C
  extern SIGHAND_TYPE (*posix_signal(int, SIGHAND_TYPE (*)(int)))(int);
  #else	/* ANSI_C */
  extern SIGHAND_TYPE (*posix_signal())();
***************
*** 690,695 ****
--- 673,686 ----
  # define LONGJMP(env,val)	longjmp((env), (val))
  #endif
  
+ #if defined(POSIX_SIGNALS) && defined(HASWAITPID)
+ #define BACKGROUD_PROCESSES               /* Only with POSIX signals */
+ #endif
+ 
+ #if defined(HASWAITPID) || defined(BSD_TYPE) 
+ #include <sys/wait.h>
+ #endif
+ 
  /*
   * Some of the old BSD ctype conversion macros corrupted characters.
   * We will substitute our own versions if required.
***************
*** 737,743 ****
  char *shift_lower();
  char *strip_commas();
  char *strip_parens();
- char *strpbrk();
  char *qstrpbrk();
  char *strfcpy();
  char *strtok();
--- 728,733 ----
***************
*** 746,751 ****
--- 736,745 ----
  char *pmalloc();
  char *header_cmp();
  char *safe_strdup();
+ 
+ FILE *safeopen();
+ FILE *safeopen_rdwr();
+ FILE *open_end_update();
  
  malloc_t safe_malloc();
  malloc_t safe_realloc();
Index: elm2.4.ME+.50/hdrs/elm.h
*** elm2.4.25/hdrs/elm.h	Thu Sep  1 22:42:40 1994
--- elm2.4.ME+.50/hdrs/elm.h	Tue Nov 17 21:14:08 1998
***************
*** 1,85 ****
  
! /* $Id: elm.h,v 5.12 1994/09/01 19:42:39 syd Exp $ */
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.12 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: elm.h,v $
!  * Revision 5.12  1994/09/01  19:42:39  syd
!  * Moved #defines for SETJMP & LONGJMP from src/editmsg.c to hdrs/defs.h and
!  * used them instead of (set|long)jmp directly. This makes the usage consistent
!  * and Solaris 2.3 behaves correctly w.r.t stop/continue.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.11  1994/08/30  18:16:05  syd
!  * Fix up Solaris and SVR4 signal handling for timeout
!  * From: Syd
!  *
!  * Revision 5.10  1993/08/10  18:49:32  syd
!  * When an environment variable was given as the tmpdir definition the src
!  * and dest overlapped in expand_env.  This made elm produce a garbage
!  * expansion because expand_env cannot cope with overlapping src and
!  * dest.  I added a new variable raw_temp_dir to keep src and dest not to
!  * overlap.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.9  1993/05/08  20:03:12  syd
!  * add sleepmsg to list
!  *
!  * Revision 5.8  1993/05/08  18:56:16  syd
!  * created a new elmrc variable named "readmsginc".  This specifies an
!  * increment by which the message count is updated.  If this variable is
!  * set to, say, 25, then the message count will only be updated every 25
!  * messages, displaying 0, 25, 50, 75, and so forth.  The default value
!  * of 1 will cause Elm to behave exactly as it currently does in PL21.
!  * From: Eric Peterson <epeterso@encore.com>
!  *
!  * Revision 5.7  1993/01/20  17:37:56  syd
!  * fix spacing of =- to avoid compiler warnings
!  *
!  * Revision 5.6  1993/01/20  04:01:07  syd
!  * Adds a new integer parameter builtinlines.
!  * if (builtinlines < 0) and (the length of the message < LINES on
!  *       screen + builtinlines) use internal.
!  * if (builtinlines > 0) and (length of message < builtinlines)
!  * 	use internal pager.
!  * if (builtinlines = 0) or none of the above conditions hold, use the
!  * external pager if defined.
!  * From: "John P. Rouillard" <rouilj@ra.cs.umb.edu>
!  *
!  * Revision 5.5  1992/10/25  02:38:27  syd
!  * Add missing new flags for new elmrc options for confirm
!  * From: Syd
!  *
!  * Revision 5.4  1992/10/24  13:44:41  syd
!  * There is now an additional elmrc option "displaycharset", which
!  * sets the charset supported on your terminal. This is to prevent
!  * elm from calling out to metamail too often.
!  * Plus a slight documentation update for MIME composition (added examples)
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.3  1992/10/24  13:35:39  syd
!  * changes found by using codecenter on Elm 2.4.3
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.2  1992/10/17  22:58:57  syd
!  * patch to make elm use (or in my case, not use) termcap/terminfo ti/te.
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.1  1992/10/03  22:34:39  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /**  Main header file for ELM mail system.  **/
  
--- 1,16 ----
  
! /* $Id: elm.h,v 1.3 1998/11/07 14:12:04 hurtta Exp $ */
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /**  Main header file for ELM mail system.  **/
  
***************
*** 89,97 ****
  #include <errno.h>
  #include <signal.h>
  
! #include "../hdrs/curses.h"
! #include "../hdrs/defs.h"
  #include <setjmp.h>
  
  /******** static character string containing the version number  *******/
  
--- 20,31 ----
  #include <errno.h>
  #include <signal.h>
  
! #include "curses.h"
! #include "defs.h"
  #include <setjmp.h>
+ /*
+ #include "melib.h"
+ */
  
  /******** static character string containing the version number  *******/
  
***************
*** 104,109 ****
--- 38,44 ----
  
  /******** global variables accessable by all pieces of the program *******/
  
+ 
  int check_size = 0;		/* don't start mailer if no mail */
  int current = 0;		/* current message number  */
  int header_page = 0;     	/* current header page     */
***************
*** 116,177 ****
  int sendmail_verbose = 0;       /* Extended mail debugging */
  int redraw = 0,	 		/* do we need to rewrite the entire screen? */
      nucurr = 0,	 		/* change list or just the current pointer...   */
!     nufoot = 0,	 		/* clear lines 16 thru bottom and new menu  */
!     readmsginc = 1,		/* increment of msg cnt when reading new mbox */
!     sleepmsg = 2;		/* time to sleep for messages being overwritten on screen */
  #ifdef MIME
! char charset[SLEN] = {0};		/* name of character set */
! char display_charset[SLEN] = {0};	/* the charset, the display supports */
! char charset_compatlist[SLEN] = {0};	/* list of charsets which are a
! 					   superset of us-ascii */
! char text_encoding[SLEN] = {0};	/* default encoding for text/plain */
  #endif
  char cur_folder[SLEN] = {0};	/* name of current folder */
  char cur_tempfolder[SLEN] = {0};/* name of temp folder open for a mailbox */
! char defaultfile[SLEN] = {0};	/* name of default folder */
! char temp_dir[SLEN] = {0};      /* name of temp directory */
! char raw_temp_dir[SLEN] = {0};  /* unexpanded name of temp directory */
! char hostname[SLEN] = {0};	/* name of machine we're on*/
! char hostdomain[SLEN] = {0};	/* name of domain we're in */
! char hostfullname[SLEN] = {0};	/* name of FQDN we're in */
  char item[WLEN] = "message";	/* either "message" or "alias" */
  char items[WLEN] = "messages";	/* plural: either "messages" or "aliases" */
  char Item[WLEN] = "Message";	/* CAP: either "Message" or "Alias" */
  char Items[WLEN] = "Messages";	/* CAP-plural: either "Messages" or "Aliases" */
  char Prompt[WLEN] = "Command: ";	/* Menu Prompt: either "Command" or "Alias" */
! char username[SLEN] = {0};	/* return address name!    */
! char full_username[SLEN] = {0};	/* Full username - gecos   */
! char home[SLEN] = {0};		/* home directory of user  */
! char folders[SLEN] = {0};	/* folder home directory   */
! char raw_folders[SLEN] = {0};	/* unexpanded folder home directory   */
! char recvd_mail[SLEN] = {0};	/* folder for storing received mail     */
! char raw_recvdmail[SLEN] = {0};	/* unexpanded recvd_mail name */
! char editor[SLEN] = {0};	/* editor for outgoing mail*/
! char raw_editor[SLEN] = {0};	/* unexpanded editor for outgoing mail*/
! char alternative_editor[SLEN] = {0};	/* alternative editor...   */
! char printout[SLEN] = {0};	/* how to print messages   */
! char raw_printout[SLEN] = {0};	/* unexpanded how to print messages   */
! char sent_mail[SLEN] = {0};	/* name of file to save copies to */
! char raw_sentmail[SLEN] = {0};	/* unexpanded name of file to save to */
! char calendar_file[SLEN] = {0};	/* name of file for clndr  */
! char raw_calendar_file[SLEN] = {0};	/* unexpanded name of file for clndr  */
! char attribution[SLEN] = {0};	/* attribution string for replies     */
! char prefixchars[SLEN] = "> ";	/* prefix char(s) for msgs */
! char shell[SLEN] = {0};		/* current system shell    */
! char raw_shell[SLEN] = {0};	/* unexpanded current system shell    */
! char pager[SLEN] = {0};		/* what pager to use       */
! char raw_pager[SLEN] = {0};	/* unexpanded what pager to use       */
  char batch_subject[SLEN] = {0};	/* subject buffer for batchmail */
  char included_file[SLEN] = {0};	/* prepared file to include in the edit buf */
! char local_signature[SLEN] = {0};	/* local msg signature file     */
! char raw_local_signature[SLEN] = {0};	/* unexpanded local msg signature file     */
! char remote_signature[SLEN] = {0};	/* remote msg signature file    */
! char raw_remote_signature[SLEN] = {0};	/* unexpanded remote msg signature file    */
  char version_buff[NLEN] = {0};	/* version buffer */
! char e_editor[SLEN] = {0};	/* "~e" editor...   */
! char v_editor[SLEN] = {0};	/* "~v" editor...   */
! char config_options[SLEN] = {0};	/* which options are in o)ptions */
! char allowed_precedences[SLEN] = {0};	/* list of precedences user may specify */
   
  char *def_ans_yes;		/* default yes answer - single char, lc	*/
  char *def_ans_no;		/* default no answer - single char, lc	*/
--- 51,117 ----
  int sendmail_verbose = 0;       /* Extended mail debugging */
  int redraw = 0,	 		/* do we need to rewrite the entire screen? */
      nucurr = 0,	 		/* change list or just the current pointer...   */
!     nufoot = 0;	 		/* clear lines 16 thru bottom and new menu  */
! 
! 
  #ifdef MIME
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
  #endif
  char cur_folder[SLEN] = {0};	/* name of current folder */
  char cur_tempfolder[SLEN] = {0};/* name of temp folder open for a mailbox */
! char cur_editfile[SLEN] = {0};  /* editor buffer */
! 
! 
! 
! 
! 
  char item[WLEN] = "message";	/* either "message" or "alias" */
  char items[WLEN] = "messages";	/* plural: either "messages" or "aliases" */
  char Item[WLEN] = "Message";	/* CAP: either "Message" or "Alias" */
  char Items[WLEN] = "Messages";	/* CAP-plural: either "Messages" or "Aliases" */
  char Prompt[WLEN] = "Command: ";	/* Menu Prompt: either "Command" or "Alias" */
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
  char batch_subject[SLEN] = {0};	/* subject buffer for batchmail */
  char included_file[SLEN] = {0};	/* prepared file to include in the edit buf */
! #ifdef MIME
! mime_t *attach_files = NULL;    /* prepare attachments for sending */
! #endif
! 
! 
! 
! 
  char version_buff[NLEN] = {0};	/* version buffer */
! 
! 
! 
! 
   
  char *def_ans_yes;		/* default yes answer - single char, lc	*/
  char *def_ans_no;		/* default no answer - single char, lc	*/
***************
*** 190,278 ****
  char *copied_word;		/* copied */
  
  char backspace,			/* the current backspace char */
-      escape_char = TILDE_ESCAPE,/* '~' or something else..    */
-      kill_line;			/* the current kill-line char */
  
! char up[SHORT] = {0},		/* cursor control seq's    */
!      down[SHORT] = {0},
!      left[SHORT] = {0},
!      right[SHORT] = {0};
! int  cursor_control = FALSE;	/* cursor control avail?   */
  
  int  has_highlighting = FALSE;	/* highlighting available? */
  
! char *weedlist[MAX_IN_WEEDLIST] = {0};
! int  weedcount;
  
! int allow_forms = NO;		/* flag: are AT&T Mail forms okay?  */
! int mini_menu = 1;		/* flag: menu specified?	    */
! int metoo = 0;			/* flag: copy me on mail to alias?  */
! int prompt_after_pager = 1;	/* flag: prompt after pager exits   */
  int folder_type = 0;		/* flag: type of folder		    */
! int auto_copy = 0;		/* flag: automatically copy source? */
! int filter = 1;			/* flag: weed out header lines?	    */
! int resolve_mode = 1;		/* flag: delete saved mail?	    */
! int auto_cc = 0;		/* flag: mail copy to user?	    */
! int noheader = 1;		/* flag: copy + header to file?     */
! int title_messages = 1;		/* flag: title message display?     */
! int forwarding = 0;		/* flag: are we forwarding the msg? */
! int hp_terminal = 0;		/* flag: are we on HP term?	    */
! int hp_softkeys = 0;		/* flag: are there softkeys?        */
! int save_by_name = 1;		/* flag: save mail by login name?   */
! int force_name = 0;		/* flag: save by name forced?	    */
  int mail_only = 0;		/* flag: send mail then leave?      */
  int check_only = 0;		/* flag: check aliases then leave?  */
  int batch_only = 0;		/* flag: send without prompting?    */
! int move_when_paged = 0;	/* flag: move when '+' or '-' used? */
! int point_to_new = 1;		/* flag: start pointing at new msg? */
! int builtin_lines= -3;		/* int: if < 0 use builtin if message
! 					shorter than LINES+builtin_lines
! 					else use pager. If > 0 use builtin
! 					if message has fewer than # of lines */
! int bounceback = 0;		/* flag: bounce copy off remote?    */
! int always_keep = 1;		/* flag: always keep unread msgs?   */
! int always_store = 0;		/* flag: always store read msgs?    */
! int always_del = 0;		/* flag: always delete marked msgs? */
! int arrow_cursor = 0;		/* flag: use "->" cursor regardless?*/
! int debug = 0; 			/* flag: default is no debug!       */
! int user_level = 0;		/* flag: how good is the user?      */
  int selected = 0;		/* flag: used for select stuff      */
! int names_only = 1;		/* flag: display user names only?   */
! int question_me = 1;		/* flag: ask questions as we leave? */
! int keep_empty_files = 0;	/* flag: leave empty folder files? */
! int clear_pages = 0;		/* flag: act like "page" (more -c)? */
! int prompt_for_cc = 1;		/* flag: ask user for "cc:" value?  */
! int sig_dashes = 1;		/* flag: include dashes above sigs? */
! int use_tite = 1;		/* flag: use termcap/terminfo ti/te?*/
! int confirm_append = 0;		/* flag: confirm append to folder?  */
! int confirm_create = 0;		/* flag: confirm create new folder? */
! int confirm_files = 0;		/* flag: confirm files for append?  */
! int confirm_folders = 0;	/* flag: confirm folders for create?*/
  
- int sortby = REVERSE SENT_DATE;	/* how to sort incoming mail...     */
- int alias_sortby = NAME_SORT;	/* how to sort aliases...           */
  
- long timeout = 600L;		/* timeout (secs) on main prompt    */
  
  /** set up some default values for a 'typical' terminal *snicker* **/
  
! int LINES=23;			/** lines per screen      **/
! int COLUMNS=80;			/** columns per page      **/
  #ifdef SIGWINCH
! int resize_screen = 0;		/** SIGWINCH occured?	  **/
  #endif
  
  long size_of_pathfd;		/** size of pathfile, 0 if none **/
  
  FILE *mailfile;			/* current folder	    */
- FILE *debugfile;		/* file for debug output    */
  FILE *pathfd;			/* path alias file          */
  FILE *domainfd;			/* domain file		    */
- nl_catd elm_msg_cat = 0;	/* message catalog	    */
  
  long mailfile_size;		/* size of current mailfile */
  
! int   max_headers = 0;		/* number of headers allocated */
  
  struct header_rec **headers;    /* array of header structure pointers */
  
--- 130,220 ----
  char *copied_word;		/* copied */
  
  char backspace,			/* the current backspace char */
  
!      kill_line,			/* the current kill-line char */
!      word_erase,		/* the current word-erase char */
!      interrupt_char,		/* the current interrupt char */
!      reprint_char,		/* the current reprint-line char */
!      eof_char;			/* the current end-of-file char */
  
  int  has_highlighting = FALSE;	/* highlighting available? */
  
! 
! 
! 
  
! 
! int write_elmrc = 0;            /* flag: write elmrc in starting    */
! 
! 
  int folder_type = 0;		/* flag: type of folder		    */
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
  int mail_only = 0;		/* flag: send mail then leave?      */
  int check_only = 0;		/* flag: check aliases then leave?  */
  int batch_only = 0;		/* flag: send without prompting?    */
! 
! 
! 
! 
! 
! 
! 
! 
! 
  int selected = 0;		/* flag: used for select stuff      */
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
  
  
  
+ 
+ 
+ 
+ 
+ 
+ 
+ 
  /** set up some default values for a 'typical' terminal *snicker* **/
  
! int elm_LINES=23;		/** lines per screen      **/
! int elm_COLUMNS=80;		/** columns per page      **/
  #ifdef SIGWINCH
! VOLATILE int resize_screen = 0;		/** SIGWINCH occured?	  **/
! #endif
! VOLATILE int redraw_screen = 0;          /* Elm suspended?          */
! #ifdef BACKGROUD_PROCESSES       
! VOLATILE int handle_sigchld = 0;       /* got SIGCHLD */
! 
  #endif
  
+ 
  long size_of_pathfd;		/** size of pathfile, 0 if none **/
  
  FILE *mailfile;			/* current folder	    */
  FILE *pathfd;			/* path alias file          */
  FILE *domainfd;			/* domain file		    */
  
  long mailfile_size;		/* size of current mailfile */
  
! int   max_headers = 0;		/* number of headers alloated */
  
  struct header_rec **headers;    /* array of header structure pointers */
  
***************
*** 279,294 ****
  struct alias_rec **aliases;     /* for the alias menu */
  int   max_aliases = 0;		/* number of aliases allocated */
  
- struct addr_rec *alternative_addresses;	/* how else do we get mail? */
  
  int system_data = -1;		/* fileno of system data file */
  int user_data = -1;		/* fileno of user data file   */
  
! int userid;			/* uid for current user	      */
! int groupid;			/* groupid for current user   */
! #ifdef SAVE_GROUP_MAILBOX_ID
! int mailgroupid;		/* groupid for current user   */
! #endif
  
  JMP_BUF GetPromptBuf;		/* setjmp buffer */
  int InGetPrompt;		/* set if in GetPrompt() in read() */
--- 221,260 ----
  struct alias_rec **aliases;     /* for the alias menu */
  int   max_aliases = 0;		/* number of aliases allocated */
  
  
+ 
  int system_data = -1;		/* fileno of system data file */
  int user_data = -1;		/* fileno of user data file   */
  
! 
! 
! 
! 
  
+ 
  JMP_BUF GetPromptBuf;		/* setjmp buffer */
  int InGetPrompt;		/* set if in GetPrompt() in read() */
+ #ifdef USE_PGP
+ 
+ int pgp_status=0;    /* var to keep track of pgp internals */
+ 
+ 
+ 
+ 
+ #endif
+ int me_retcode;
+ 
+ #ifdef MIME
+ 
+ 
+ 
+ 
+ short mime_count = 0; /* A counter used so that each call to
+                        * mime_generate_boundary() returns a unique value.
+                        */
+ mime_t *attachments = NULL;
+ 
+ #endif
+ #ifdef USE_REMAILER
+ int remailing;
+ #endif
Index: elm2.4.ME+.50/hdrs/elmutil.h
*** elm2.4.25/hdrs/elmutil.h	Sun Oct  4 01:35:07 1992
--- elm2.4.ME+.50/hdrs/elmutil.h	Tue Nov 17 21:14:08 1998
***************
*** 1,24 ****
  
! /* $Id: elmutil.h,v 5.1 1992/10/03 22:34:39 syd Exp $ */
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: elmutil.h,v $
!  * Revision 5.1  1992/10/03  22:34:39  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /**  Main header file for ELM utilities.  **/
  
--- 1,16 ----
  
! /* $Id: elmutil.h,v 1.3 1998/11/07 14:12:04 hurtta Exp $ */
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /**  Main header file for ELM utilities.  **/
  
***************
*** 28,35 ****
  #include <errno.h>
  #include <signal.h>
  
! #include "../hdrs/curses.h"
! #include "../hdrs/defs.h"
  
  /******** static character string containing the version number  *******/
  
--- 20,30 ----
  #include <errno.h>
  #include <signal.h>
  
! #include "curses.h"
! #include "defs.h"
! 
! #include "patchlevel.h"
! #include "elmlib.h"
  
  /******** static character string containing the version number  *******/
  
***************
*** 42,57 ****
  
  /******** global variables accessable by all pieces of the program *******/
  
! char hostname[SLEN] = {0};      /* name of machine we're on*/
! char hostdomain[SLEN] = {0};    /* name of domain we're in */
! char hostfullname[SLEN] = {0};  /* name of FQDN we're in */
! char username[SLEN] = {0};      /* return address name!    */
! char full_username[SLEN] = {0}; /* Full username - gecos   */
! nl_catd elm_msg_cat = 0;	/* message catalog	    */
! int userid;			/* uid for current user	      */
! int groupid;			/* groupid for current user   */
  
- struct addr_rec *alternative_addresses = NULL;	/* can't do it without elmrc */
  
  extern char *gcos_name();
  extern char *get_full_name();
--- 37,52 ----
  
  /******** global variables accessable by all pieces of the program *******/
  
! 
! 
! 
! 
! 
! 
! 
! 
! 
  
  
  extern char *gcos_name();
  extern char *get_full_name();
Index: elm2.4.ME+.50/hdrs/filter.h
*** elm2.4.25/hdrs/filter.h	Tue Aug  3 22:28:44 1993
--- elm2.4.ME+.50/hdrs/filter.h	Tue Nov 17 21:14:08 1998
***************
*** 1,83 ****
  
! /* $Id: filter.h,v 5.11 1993/08/03 19:28:39 syd Exp $ */
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.11 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: filter.h,v $
!  * Revision 5.11  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.10  1993/06/06  17:34:40  syd
!  * remove useless _vbuf definition
!  *
!  * Revision 5.9  1993/04/16  04:16:24  syd
!  * For convex, #if-defed memcpy, memset and sleep.
!  * From: rzm@oso.chalmers.se (Rafal Maszkowski)
!  *
!  * Revision 5.8  1993/04/12  03:30:23  syd
!  * On AIX, __STDC__ is not defined but it does use unistd.h, etc.  In
!  * hdrs/def.h, ANS_C already gets defined if __STDC__ or _AIX.  But this
!  * variable then needs to be used in src/init.c and hdrs/filter.h in place
!  * of the current test for __STDC__.
!  * From:	rstory@elegant.com (Robert Story)
!  *
!  * Revision 5.7  1993/04/12  03:25:26  syd
!  * Use I_UNISTD instead of UNISTD_H
!  *
!  * Revision 5.6  1993/04/12  03:22:49  syd
!  * Add UNISTD_H to check for unistd.h include
!  * From: Syd
!  *
!  * Revision 5.5  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.4  1993/01/27  19:45:15  syd
!  * Filter turns spaces in quoted strings into _ and then back again. This destroys
!  * any _ that where there in the first place. This patch removes that.
!  * Also fixed a minor bug where 'filter -r' wrote out the wrong thing if the
!  * relation in a rule was '~'.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.3  1992/11/15  01:42:57  syd
!  * Add regexp processing to filter.
!  * Add execc operator
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.2  1992/10/24  14:20:24  syd
!  * remove the 25 (MAXRULES) limitation.
!  * Basically it mallocs rules in hunks of RULESINC (25) as it goes along.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.1  1992/10/03  22:34:39  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** Headers for the filter program.
  
  **/
  
  #include "regexp.h"
  
  /** define a few handy macros for later use... **/
--- 1,22 ----
  
! /* $Id: filter.h,v 1.3 1998/11/07 14:12:04 hurtta Exp $ */
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** Headers for the filter program.
  
  **/
  
+ #include <stdio.h>
  #include "regexp.h"
  
  /** define a few handy macros for later use... **/
***************
*** 153,162 ****
  
  #ifdef MAIN_ROUTINE
  
- char home[SLEN],				/* the users home directory */
-      hostname[SLEN],			/* the machine name...      */
-      username[SLEN];			/* the users login name...  */
- 
  char to[VERY_LONG_STRING], 
       from[LONG_STRING], 
       subject[LONG_STRING],		/* from current message     */
--- 92,97 ----
***************
*** 165,171 ****
  FILE *outfd;
  char outfname[SLEN];
  char filterfile[SLEN];
- nl_catd elm_msg_cat = 0;			/* message catalog          */
  
  int  total_rules = 0,				/* how many rules to check  */
       sizeof_rules = 0,				/* how big is rules array?  */
--- 100,105 ----
***************
*** 184,193 ****
    
  #else
  
- extern char home[SLEN],				/* the users home directory */
-             hostname[SLEN],			/* the machine name...      */
-             username[SLEN];			/* the users login name...  */
  
  extern char to[VERY_LONG_STRING], 
              from[LONG_STRING], 
  	    subject[LONG_STRING],		/* from current message     */
--- 118,126 ----
    
  #else
  
  
+ 
+ 
  extern char to[VERY_LONG_STRING], 
              from[LONG_STRING], 
  	    subject[LONG_STRING],		/* from current message     */
***************
*** 196,202 ****
  extern FILE *outfd;
  extern char outfname[SLEN];
  extern char filterfile[SLEN];
- extern nl_catd elm_msg_cat;			/* message catalog          */
  
  extern int total_rules,				/* how many rules to check  */
             sizeof_rules,			/* how big is rules array?  */
--- 129,134 ----
***************
*** 241,254 ****
  
  char *itoa();
  
! #ifdef	ANSI_C		/*{ANSI_C*/
  #include <string.h>
! #  ifdef I_UNISTD /* unistd.h available */
  #    include <unistd.h>
! #  else /* I_UNISTD */
! unsigned long sleep();
! #  endif /* I_UNISTD */
! #else				/*}ANSI_C{*/
  unsigned short getuid();
  
  #if defined(__convexc__)
--- 173,186 ----
  
  char *itoa();
  
! #ifdef	ANSI_C		
  #include <string.h>
! #endif
! 
! # ifdef I_UNISTD /* unistd.h available */
  #    include <unistd.h>
! # else
! 
  unsigned short getuid();
  
  #if defined(__convexc__)
***************
*** 259,268 ****
  
  char *strcpy(), *strcat();
  
! #ifdef BSD
! 	
!   FILE *popen();
  
! #endif
  
- #endif				/*}ANSI_C*/
--- 191,201 ----
  
  char *strcpy(), *strcat();
  
! #endif		
  
! extern void expand_macros P_((char *, char *, int, int, int));
! extern void expand_filename P_((char *filename, int namesize));
! extern int save_message P_((char *foldername, int namesize));
! 
! 
  
Index: elm2.4.ME+.50/hdrs/headers.h
*** elm2.4.25/hdrs/headers.h	Thu Sep  1 22:42:40 1994
--- elm2.4.ME+.50/hdrs/headers.h	Tue Nov 17 21:14:08 1998
***************
*** 1,86 ****
  
! /* $Id: headers.h,v 5.13 1994/09/01 19:42:39 syd Exp $ */
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.13 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: headers.h,v $
!  * Revision 5.13  1994/09/01  19:42:39  syd
!  * Moved #defines for SETJMP & LONGJMP from src/editmsg.c to hdrs/defs.h and
!  * used them instead of (set|long)jmp directly. This makes the usage consistent
!  * and Solaris 2.3 behaves correctly w.r.t stop/continue.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.12  1994/08/30  18:16:05  syd
!  * Fix up Solaris and SVR4 signal handling for timeout
!  * From: Syd
!  *
!  * Revision 5.11  1993/08/10  20:49:40  syd
!  * Add raw_temp_dir
!  *
!  * Revision 5.10  1993/05/08  20:03:12  syd
!  * add sleepmsg to list
!  *
!  * Revision 5.9  1993/05/08  18:56:16  syd
!  * created a new elmrc variable named "readmsginc".  This specifies an
!  * increment by which the message count is updated.  If this variable is
!  * set to, say, 25, then the message count will only be updated every 25
!  * messages, displaying 0, 25, 50, 75, and so forth.  The default value
!  * of 1 will cause Elm to behave exactly as it currently does in PL21.
!  * From: Eric Peterson <epeterso@encore.com>
!  *
!  * Revision 5.8  1993/04/21  01:24:54  syd
!  * It's very non-portable, and fairly dangerous, to ass_u_me that you
!  * know what's inside a FILE.  So don't #define clearerr().
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.7  1993/01/20  04:01:07  syd
!  * Adds a new integer parameter builtinlines.
!  * if (builtinlines < 0) and (the length of the message < LINES on
!  *       screen + builtinlines) use internal.
!  * if (builtinlines > 0) and (length of message < builtinlines)
!  * 	use internal pager.
!  * if (builtinlines = 0) or none of the above conditions hold, use the
!  * external pager if defined.
!  * From: "John P. Rouillard" <rouilj@ra.cs.umb.edu>
!  *
!  * Revision 5.6  1992/10/30  21:47:30  syd
!  * Use copy_message in mime shows to get encode processing
!  * From: bjoerns@stud.cs.uit.no (Bjoern Stabell)
!  *
!  * Revision 5.5  1992/10/25  02:38:27  syd
!  * Add missing new flags for new elmrc options for confirm
!  * From: Syd
!  *
!  * Revision 5.4  1992/10/24  13:44:41  syd
!  * There is now an additional elmrc option "displaycharset", which
!  * sets the charset supported on your terminal. This is to prevent
!  * elm from calling out to metamail too often.
!  * Plus a slight documentation update for MIME composition (added examples)
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.3  1992/10/24  13:35:39  syd
!  * changes found by using codecenter on Elm 2.4.3
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.2  1992/10/17  22:58:57  syd
!  * patch to make elm use (or in my case, not use) termcap/terminfo ti/te.
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.1  1992/10/03  22:34:39  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /**  This is the header file for ELM mail system.  **/
  
--- 1,16 ----
  
! /* $Id: headers.h,v 1.3 1998/11/07 14:12:04 hurtta Exp $ */
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /**  This is the header file for ELM mail system.  **/
  
***************
*** 97,104 ****
--- 27,39 ----
  #include "mime.h"
  #endif
  
+ #include "elmlib.h"
+ /*
+ #include "me.h"
+ */
  /******** global variables accessable by all pieces of the program *******/
  
+ 
  extern int check_size;		/* don't start mailer if no mail */
  extern int current;		/* current message number  */
  extern int header_page;         /* current header page     */
***************
*** 111,172 ****
  extern int sendmail_verbose;    /* Allow extended debugging on sendmail */
  extern int redraw, 		/** do we need to rewrite the entire screen? **/
             nucurr, 		/** change list or just the current pointer  **/
!            nufoot, 		/** clear lines 16 thru bottom and new menu  **/
! 	   readmsginc,		/* msg cnt increment during new mbox read */
! 	   sleepmsg;		/* time to sleep for messages being overwritten on screen */
  #ifdef MIME
! extern char charset[SLEN];	/* name of character set */
! extern char display_charset[SLEN];	/* name of character set */
! extern char charset_compatlist[SLEN];	/* list of charsets which are a
! 					   superset of us-ascii */
  extern char text_encoding[SLEN];	/* default encoding for text/plain */
  #endif
! extern char cur_folder[SLEN];	/* name of current folder */
  extern char cur_tempfolder[SLEN]; /* name of temp folder open for a mailbox */
! extern char defaultfile[SLEN];	/* name of default folder */
! extern char temp_dir[SLEN];     /* name of temp directory */
! extern char raw_temp_dir[SLEN]; /* unexpanded name of temp directory */
! extern char hostname[SLEN];	/* name of machine we're on*/
! extern char hostdomain[SLEN];	/* name of domain we're in */
! extern char hostfullname[SLEN]; /* name of FQDN we're in */
  extern char item[WLEN];		/* either "message" or "alias" */
  extern char items[WLEN];	/* plural: either "messages" or "aliases" */
  extern char Item[WLEN];		/* CAP: either "Message" or "Alias" */
  extern char Items[WLEN];	/* CAP-plural: either "Messages" or "Aliases" */
  extern char Prompt[WLEN];	/* Menu Prompt: either "Command" or "Alias" */
! extern char username[SLEN];	/* return address name!    */
! extern char full_username[SLEN];/* Full username - gecos   */
! extern char home[SLEN];		/* home directory of user  */
! extern char folders[SLEN];	/* folder home directory   */
! extern char raw_folders[SLEN];	/* unexpanded folder home directory   */
! extern char recvd_mail[SLEN];	/* folder for storing received mail	*/
! extern char raw_recvdmail[SLEN];/* unexpanded recvd_mail name */
! extern char editor[SLEN];	/* default editor for mail */
! extern char raw_editor[SLEN];	/* unexpanded default editor for mail */
! extern char alternative_editor[SLEN];/* the 'other' editor */
! extern char printout[SLEN];	/* how to print messages   */
! extern char raw_printout[SLEN];	/* unexpanded how to print messages   */
! extern char sent_mail[SLEN];	/* name of file to save copies to */
! extern char raw_sentmail[SLEN];	/* unexpanded name of file to save to */
! extern char calendar_file[SLEN];/* name of file for clndr  */
! extern char raw_calendar_file[SLEN];/* unexpanded name of file for clndr  */
! extern char attribution[SLEN];  /* attribution string for replies     */
! extern char prefixchars[SLEN];	/* prefix char(s) for msgs */
! extern char shell[SLEN];	/* default system shell    */
! extern char raw_shell[SLEN];	/* unexpanded default system shell    */
! extern char pager[SLEN];	/* what pager to use...    */
! extern char raw_pager[SLEN];	/* unexpanded what pager to use...    */
  extern char batch_subject[SLEN];/* subject buffer for batchmail */
  extern char included_file[SLEN];/* name of file to place in edit buf */
! extern char local_signature[SLEN];/* local msg signature file   */
! extern char raw_local_signature[SLEN];/* unexpanded local msg signature file */
! extern char remote_signature[SLEN];/* remote msg signature file */
! extern char raw_remote_signature[SLEN];/* unexpanded remote msg signature file*/
  extern char version_buff[NLEN]; /* version buffer */
! extern char e_editor[SLEN];	/* "~e" editor...   */
! extern char v_editor[SLEN];	/* "~v" editor...   */
! extern char config_options[SLEN];	/* which options are in o)ptions */
! extern char allowed_precedences[SLEN];	/* list of precedences user may specify */
  extern char *def_ans_yes;	/* default yes answer - single char, lc	*/
  extern char *def_ans_no;	/* default no answer - single char, lc	*/
  extern char *nls_deleted;	/* [deleted] */
--- 46,117 ----
  extern int sendmail_verbose;    /* Allow extended debugging on sendmail */
  extern int redraw, 		/** do we need to rewrite the entire screen? **/
             nucurr, 		/** change list or just the current pointer  **/
!            nufoot; 		/** clear lines 16 thru bottom and new menu  **/
! 
! 
  #ifdef MIME
! 
! 
! 
! 
  extern char text_encoding[SLEN];	/* default encoding for text/plain */
+ 
+ 
+ 
+ 
+ 
+ 
+ 
  #endif
! extern char cur_folder[SLEN];	  /* name of current folder */
  extern char cur_tempfolder[SLEN]; /* name of temp folder open for a mailbox */
! extern char defaultfile[SLEN];	  /* name of default folder */
! extern char cur_editfile[SLEN];   /* editor buffer */
! 
! 
! 
! 
  extern char item[WLEN];		/* either "message" or "alias" */
  extern char items[WLEN];	/* plural: either "messages" or "aliases" */
  extern char Item[WLEN];		/* CAP: either "Message" or "Alias" */
  extern char Items[WLEN];	/* CAP-plural: either "Messages" or "Aliases" */
  extern char Prompt[WLEN];	/* Menu Prompt: either "Command" or "Alias" */
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
  extern char batch_subject[SLEN];/* subject buffer for batchmail */
  extern char included_file[SLEN];/* name of file to place in edit buf */
! #ifdef MIME
! extern mime_t *attach_files;    /* prepare attachments for sending */
! #endif
! 
! 
! 
! 
  extern char version_buff[NLEN]; /* version buffer */
! 
! 
! 
! 
  extern char *def_ans_yes;	/* default yes answer - single char, lc	*/
  extern char *def_ans_no;	/* default no answer - single char, lc	*/
  extern char *nls_deleted;	/* [deleted] */
***************
*** 184,265 ****
  extern char *copied_word;	/* copied */
  
  extern char backspace,		/* the current backspace char  */
- 	    escape_char,	/* '~' or something else...    */
- 	    kill_line;		/* the current kill_line char  */
  
! extern char up[SHORT], 
! 	    down[SHORT],
! 	    left[SHORT],
! 	    right[SHORT];	/* cursor control seq's    */
! extern int  cursor_control;	/* cursor control avail?   */
  
  extern int  has_highlighting;	/* highlighting available? */
  
  /** the following two are for arbitrary weedout lists.. **/
  
! extern char *weedlist[MAX_IN_WEEDLIST];
! extern int  weedcount;		/* how many headers to check?        */
  
! extern int  allow_forms;	/* flag: are AT&T Mail forms okay?    */
! extern int  prompt_after_pager;	/* flag: prompt after pager exits     */
! extern int  mini_menu;		/* flag: display menu?     	      */
! extern int  metoo;		/* flag: copy me on mail to alias?    */
  extern int  folder_type;	/* flag: type of folder		      */
! extern int  auto_copy;		/* flag: auto copy source into reply? */
! extern int  filter;		/* flag: weed out header lines?	      */
! extern int  resolve_mode;	/* flag: resolve before moving mode?  */
! extern int  auto_cc;		/* flag: mail copy to yourself?       */
! extern int  noheader;		/* flag: copy + header to file?       */
! extern int  title_messages;	/* flag: title message display?       */
! extern int  forwarding;		/* flag: are we forwarding the msg?   */
! extern int  hp_terminal;	/* flag: are we on an hp terminal?    */
! extern int  hp_softkeys;	/* flag: are there softkeys?          */
! extern int  save_by_name;  	/* flag: save mail by login name?     */
! extern int  force_name;		/* flag: save by name forced?	      */
  extern int  mail_only;		/* flag: send mail then leave?        */
  extern int  check_only;		/* flag: check aliases and leave?     */
  extern int  batch_only;		/* flag: send without prompting?      */
! extern int  move_when_paged;	/* flag: move when '+' or '-' used?   */
! extern int  point_to_new;	/* flag: start pointing at new msgs?  */
! extern int  builtin_lines;	/* int use builtin pager?             */
! extern int  bounceback;		/* flag: bounce copy off remote?      */
! extern int  always_keep;	/* flag: always keep unread msgs?     */
! extern int  always_store;	/* flag: always store read mail?      */
! extern int  always_del;		/* flag: always delete marked msgs?   */
! extern int  arrow_cursor;	/* flag: use "->" regardless?	      */
! extern int  debug;		/* flag: debugging mode on?           */
! extern int  user_level;		/* flag: how knowledgable is user?    */
  extern int  selected;		/* flag: used for select stuff        */
! extern int  names_only;		/* flag: display names but no addrs?  */
! extern int  question_me;	/* flag: ask questions as we leave?   */
! extern int  keep_empty_files;	/* flag: keep empty files??	      */
! extern int  clear_pages;	/* flag: clear screen w/ builtin pgr? */
! extern int  prompt_for_cc;	/* flag: prompt user for 'cc' value?  */
! extern int  sig_dashes;		/* flag: put dashes above signature?  */
! extern int  use_tite;		/* flag: use termcap/terminfo ti/te?  */
! extern int  confirm_append;	/* flag: confirm append to folder?    */
! extern int  confirm_create;	/* flag: confirm create new folder?   */
! extern int  confirm_files;	/* flag: confirm files for append?    */
! extern int  confirm_folders;	/* flag: confirm folders for create?  */
  
- extern int  sortby;		/* how to sort folders	      */
- extern int  alias_sortby;	/* how to sort aliases        */
  
- extern long timeout;		/* seconds for main level timeout     */
  
! extern int LINES;		/** lines per screen    **/
! extern int COLUMNS;		/** columns per line    **/
  #ifdef SIGWINCH
! extern int resize_screen;	/** SIGWINCH occured?   **/
  #endif
  
  extern long size_of_pathfd;	/** size of pathfile, 0 if none **/
  
  extern FILE *mailfile;		/* current folder 	    */
! extern FILE *debugfile;		/* file for debut output    */
  extern FILE *pathfd;		/* path alias file          */
  extern FILE *domainfd;		/* domains file 	    */
- extern nl_catd elm_msg_cat;	/* message catalog	    */
  
  extern long mailfile_size;	/* size of current mailfile */
  
--- 129,220 ----
  extern char *copied_word;	/* copied */
  
  extern char backspace,		/* the current backspace char  */
  
! 	    kill_line,		/* the current kill_line char  */
!   	    word_erase,		/* the current word-erase char */
!   	    interrupt_char,	/* the current interrupt char */
!   	    reprint_char,	/* the current reprint-line char */
!   	    eof_char;		/* the current end-of-file char */
  
  extern int  has_highlighting;	/* highlighting available? */
  
  /** the following two are for arbitrary weedout lists.. **/
  
! 
! 
  
! 
! 
! 
! 
  extern int  folder_type;	/* flag: type of folder		      */
! extern int  write_elmrc;        /* flag: write elmrc in starting      */
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
  extern int  mail_only;		/* flag: send mail then leave?        */
  extern int  check_only;		/* flag: check aliases and leave?     */
  extern int  batch_only;		/* flag: send without prompting?      */
! 
! 
! 
! 
! 
! 
! 
! 
! 
! 
  extern int  selected;		/* flag: used for select stuff        */
! 
! 
! 
! 
! 
! 
! 
! 
! 
  
  
  
! 
! 
! 
! 
! 
! 
! 
! #ifdef USE_DSN
! 
! #endif
! 
! 
! extern int elm_LINES;		/** lines per screen    **/
! extern int elm_COLUMNS;		/** columns per line    **/
  #ifdef SIGWINCH
! VOLATILE extern int resize_screen;	/** SIGWINCH occured?   **/
! #endif
! VOLATILE extern int redraw_screen;	/** Elm suspended?   **/
! #ifdef BACKGROUD_PROCESSES       
! extern VOLATILE int handle_sigchld;       /* got SIGCHLD */
! 
  #endif
  
  extern long size_of_pathfd;	/** size of pathfile, 0 if none **/
  
  extern FILE *mailfile;		/* current folder 	    */
! 
  extern FILE *pathfd;		/* path alias file          */
  extern FILE *domainfd;		/* domains file 	    */
  
  extern long mailfile_size;	/* size of current mailfile */
  
***************
*** 270,285 ****
  extern struct alias_rec **aliases; /* for the alias menu */
  extern int    max_aliases;	/* number of aliases allocated */
  
! extern struct addr_rec *alternative_addresses;	/* how else do we get mail? */
  
  extern int system_data;		/* fileno of system data file */
  extern int user_data;		/* fileno of user data file   */
  
! extern int userid;		/* uid for current user	      */
! extern int groupid;		/* groupid for current user   */
! #ifdef SAVE_GROUP_MAILBOX_ID
! extern int mailgroupid;		/* groupid for current user   */
! #endif
  
  extern JMP_BUF GetPromptBuf;	/* setjmp buffer */
  extern int InGetPrompt;		/* set if in GetPrompt() in read() */
--- 225,258 ----
  extern struct alias_rec **aliases; /* for the alias menu */
  extern int    max_aliases;	/* number of aliases allocated */
  
! 
  
  extern int system_data;		/* fileno of system data file */
  extern int user_data;		/* fileno of user data file   */
  
! 
  
+ 
+ 
+ 
  extern JMP_BUF GetPromptBuf;	/* setjmp buffer */
  extern int InGetPrompt;		/* set if in GetPrompt() in read() */
+ #ifdef USE_PGP
+ 
+ extern int pgp_status;
+ 
+ extern int pgp_keeppassfor; /* how long to keep it before expiring */
+ 
+ 
+ 
+ #endif
+ 
+ extern int me_retcode;
+ #ifdef MIME
+ 
+ 
+ 
+ 
+ extern char *mime_types[];
+ 
+ #endif
Index: elm2.4.ME+.50/hdrs/mcprt.h
*** elm2.4.25/hdrs/mcprt.h	Thu Jun 30 19:42:29 1994
--- elm2.4.ME+.50/hdrs/mcprt.h	Tue Nov 17 21:12:54 1998
***************
*** 48,54 ****
  #include <stdio.h>
  
  #ifdef USENLS
! #  ifdef ANSI_C
  extern int     	MCprintf(char *fmt, ...);
  extern int     	MCfprintf(FILE *fptr, char *fmt, ...);
  extern int     	MCsprintf(char *cptr, char *fmt, ...);
--- 48,54 ----
  #include <stdio.h>
  
  #ifdef USENLS
! #  if ANSI_C 
  extern int     	MCprintf(char *fmt, ...);
  extern int     	MCfprintf(FILE *fptr, char *fmt, ...);
  extern int     	MCsprintf(char *cptr, char *fmt, ...);
Index: elm2.4.ME+.50/hdrs/mcprtlib.h
*** elm2.4.25/hdrs/mcprtlib.h	Mon Aug 23 05:48:18 1993
--- elm2.4.ME+.50/hdrs/mcprtlib.h	Tue Nov 17 21:12:54 1998
***************
*** 49,61 ****
  /* taken from Xm/lib/VaSimple.h
     currently no one defines MISSING_STDARG_H */
   
- #ifdef	I_STDARG
- # include <stdarg.h>
- # define Va_start(a,b) va_start(a,b)
- #else
- # include <varargs.h>
- # define Va_start(a,b) va_start(a)
- #endif
  
  #define MCFree		0x0010			/* Reminder to MCPrintFree */
  #define MCCatalog	0x0100			/* Probably came from catalog */
--- 49,54 ----
Index: elm2.4.ME+.50/hdrs/me.h
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/hdrs/me.h	Tue Nov 17 21:12:54 1998
***************
*** 0 ****
--- 1,299 ----
+ /* $Id: me.h,v 1.3 1998/10/20 20:04:45 hurtta Exp $ */
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *
+  *  Initially written by: Michael Elkins <elkins@aero.org>, 1995
+  *****************************************************************************/
+ 
+ #include "melib.h"
+ 
+ #define PUBLIC 
+ 
+ /* curses.c */
+ 
+ extern int ReadCh            P_((int));
+ 
+ /* args.c */
+ 
+ extern char * parse_arguments P_((int, char *[], char *, int *, int));
+ 
+ /* init.c */
+ void initialize P_((char *, int));
+ 
+ /* elm.c */
+ extern void motion P_((int));
+ 
+ /* in_utils.c */
+ 
+ extern int want_to          P_((char *, int, int, int));
+ extern int read_number      P_((int, char *));
+ extern int optionally_enter P_((char *, int, int, int, int));
+ extern int pattern_enter    P_((char *, char *, int, int, char *, int, int));
+ extern int GetPrompt        P_((void));
+ 
+ /* out_utils.c */
+ 
+ extern void sleep_message P_((void));
+ extern int  error P_((const char *s));
+ extern void out_util_setup();
+ 
+ /* pattern.c */
+ 
+ extern int from_matches P_((int message_number, char *pat));
+ extern int to_matches P_((int message_number, char *pat));
+ extern int cc_matches P_((int message_number, char *pat));
+ extern int subject_matches P_((int message_number, char *pat));
+ 
+ /* addr_util.c */
+ 
+ extern int build_address P_((char *, char *, int, int ));
+ extern struct address_list * address_list_from_string P_((const char *s));
+ extern int fix_arpa_address P_((char *address, int size));
+ 
+ /* Alias.c */
+ 
+ extern void alias P_((void));
+ 
+ /* a_screen.c */
+ 
+ extern void build_alias_line P_((char *buffer,
+ 				 struct alias_rec *entry,
+ 				 int message_number, int highlight,
+ 				 int buffer_size));
+ 
+ 
+ /* file.c */
+ 
+ int expand_filename P_((char *, int, int));
+ void init_helpmsg P_(( char *, char *, int, int ));
+ 
+ /* fileutil.c */
+ 
+ extern FILE *open_end_update P_((char *));
+ 
+ /* src/remailer.c */
+ 
+ #ifdef USE_REMAILER
+ #ifdef MIME
+ extern int remailer_copy_message_across P_((FILE *, FILE *, int, mime_send_t *));
+ #else
+ extern int remailer_copy_message_across P_((FILE *, FILE *, int));
+ #endif
+ extern int remailer_proc P_((void));
+ #endif 
+ 
+ #ifdef USE_PGP
+ /* pgp.c */
+ extern int pgp_encrypt			P_((char *, char *, char *, int, int));
+ extern int pgp_menu			P_((char *));
+ extern int pgp_extract_public_key	P_((void));
+ #endif
+ 
+ /* read_rc.c */
+ 
+ extern void directory_check     P_((void));
+ 
+ 
+ 
+ extern int metapager		P_((FILE *, struct header_rec *, int));
+ extern int builtinplusplus	P_((FILE *, long, int, char **, int));
+ 
+ /* mime.c */
+ 
+ extern int have_metamail        P_((void));
+ 
+ /* strings.c */
+ 
+ extern char **argv_from_to      P_((char *to));
+ 
+ /* fileio.h */
+ extern void copy_message P_((FILE *, struct header_rec *,
+ 			     char *, FILE *, int));
+ 
+ extern void copy_plain P_((char *,FILE *,int, struct header_rec *, FILE *));
+ #ifdef MIME
+ extern void copy_mime P_((char *,FILE *,int, struct header_rec *, FILE *));
+ #endif
+ 
+ typedef void copy_decoder P_((char *,FILE *,int, struct header_rec *, FILE *));
+ typedef copy_decoder *copy_decoder_t;
+ extern copy_decoder_t select_copy_decoder P_((struct header_rec *));
+ 
+ /* newmbox.c */
+ 
+ extern void header_zero P_((struct header_rec *));
+ extern void header_clear P_((struct header_rec *));
+ 
+ #ifdef MIME
+ extern int is_pre_mime_content_type P_((mime_t *,char *));
+ #endif /* MIME */
+ 
+ /* file_util.c */
+ 
+ extern long fsize P_((FILE *));
+ extern long bytes P_((char *));
+ 
+ /* mailmsg1.c */
+ 
+ extern void output_abbreviated_to P_((char *address));
+ 
+ #ifdef FFR_NOT
+ 
+ struct mailing_headers {
+   char subject[SLEN];
+   char in_reply_to[SLEN];
+   char expires[SLEN];
+   char action[SLEN]; 
+   char priority[SLEN];
+   char reply_to[SLEN];
+  
+   struct address_list *to;
+   struct address_list *cc;
+  
+   char user_defined_header[SLEN];
+   struct address_list *bcc;
+   char precedence[SLEN];
+   char expires_days[SLEN];
+ };
+ extern void zero_mailing_headers P_((struct mailing_headers *hdrs));
+ 
+ #endif
+ 
+ int send_msg            P_((char *, char *, char *, int, int));
+ int copy_the_msg        P_((int *,int));
+ int get_to P_((char *, char *, int, int)); 
+ 
+ /* mailmsg2.c */
+ 
+ int mail P_((struct header_rec *, int, int));
+ int mail_form P_((struct header_rec *, char *, char *));
+ 
+ /* aliaslib.c */
+ 
+ extern char *get_alias_address P_((
+ 				   char *name, /* name to expand as an alias */
+ 				   int mailing, /* TRUE to fully expand group names & recursive aliases */
+ 				   int *too_longp /* error code if expansion overflows buffer             */
+ 				   ));
+ 
+ /* syscall.c */
+ #ifdef BACKGROUD_PROCESSES
+ extern void init_backgroud_handling P_((void));
+ #endif
+ 
+ extern int system_call    P_((char *, int));
+ 
+ #ifdef BACKGROUD_PROCESSES      
+ struct process_list;
+ struct run_state;
+ 
+ typedef void end_handler P_((FILE *fd, char * title, struct run_state *rs,
+ 			     int ret, int exit_stat));
+ 
+ extern void sigchld_handler P_((void));
+ extern int maybe_background P_((struct run_state *rs, int *exit_code,
+ 				FILE *fd, char *title, end_handler *func));
+ #endif
+ 
+ struct run_state {
+   int pid;
+   int save_errno;
+   int raw;
+   int options;
+ #ifdef BACKGROUD_PROCESSES      
+   struct process_list *listptr;
+ #endif
+ };
+ 
+ extern int start_run        P_((struct run_state *rs, int options,
+ 				char * argv[], int infd, int outfd));
+ extern int run_already_done P_((struct run_state *rs, int *exit_code));
+ extern int wait_end         P_((struct run_state *rs, int *exit_code));
+ extern char ** join_argv    P_((char * argv1[], char * argv2[]));
+ 
+ /* lib/errno.c */
+ 
+ extern char *error_description P_((int));
+ 
+ /* savecopy.c */
+ 
+ extern int name_copy_file P_((char *, int));
+ 
+ #ifdef MIME
+ 
+ 
+ extern int save_copy		P_((char *, char *, char *, char *, 
+ 				       char *, int, mime_send_t *));
+ extern int append_copy_to_file	P_((char *, char *, char *, char *, 
+ 				       char *, int, mime_send_t *));
+ extern FILE *write_header_info	P_((char *, char *, char *, char *, 
+ 				       int, int, mime_send_t *));
+ extern int copy_message_across	P_((FILE *, FILE *, int, mime_send_t *));
+ 
+ /* mime.c */
+ 
+ extern int check_for_multipart	P_((FILE *, mime_send_t *));
+ extern int Include_Part		P_((FILE *, char *, int, mime_send_t *, int));
+ extern int needs_encoding       P_((FILE *));
+ 
+ /* mime_encode.c */
+ 
+ extern void attach_generate_message P_((mime_t *, FILE *, int, mime_send_t *));
+ extern void base64_encode	    P_((FILE *, FILE *, int, mime_send_t *));
+ extern void line_quoted_printable_encode P_((char *, FILE *, int, int,
+ 					       int, mime_send_t *));
+ extern void quoted_printable_encode	P_((FILE *, FILE *, int, int,
+ 						mime_send_t *));
+ extern int is_text_type			P_((char *, char *, int));
+ extern char *mime_generate_boundary	P_((char *, int));
+ extern void add_parameter		P_((char *,char *,char *,int, int));
+ extern void add_parameter_t             P_((mime_t *, char *, char *, int));
+ 
+ extern void print_EOLN			P_((FILE *,int));
+ extern int update_encoding		P_((int *,int));
+ extern void write_encoded   P_((FILE *, FILE *, int, int, int, mime_send_t *));
+ extern void mime_write_header		P_((FILE *, mime_send_t *, int));
+ extern void rfc1522_encode_text         P_((char *,int,const char *,int));
+ 
+ /* attach_menu.c */
+ 
+ extern mime_t *attach_menu		P_((mime_t *, int));
+ extern int Attach_it                    P_((char *));
+ extern int Check_attachments            P_((void));
+ #endif
+ 
+ /* returnadd.c */
+ extern int get_return                   P_((char *, int, int));
+ 
+ /* lock.c */
+ 
+ extern int Grab_the_file P_((int flock_fd));
+ extern int Release_the_file P_((int flock_fd));
+ extern int unlock P_((int interrupt));
+ 
+ /* utils.c */
+ 
+ extern void emergency_exit P_((int interrupt));
+ extern void leave P_((int interrupt));
+ 
+ /* date.c */
+ 
+ extern void days_ahead P_((int days, char *buffer, int size));
+ extern char * elm_date_str P_((char *buf, time_t seconds, int size));
+ 
+ /* expires.h */
+ 
+ extern void process_expiration_date P_((char *date,
+ 					int  *message_status));
+ 
+ 
+ /* reply.c */
+ 
+ extern int get_return_name P_((
+ 			       char *address, char *name,
+ 			       int   trans_to_lowercase,
+ 			       int size));
+ 
Index: elm2.4.ME+.50/hdrs/menu.h
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/hdrs/menu.h	Tue Nov 17 21:12:55 1998
***************
*** 0 ****
--- 1,24 ----
+ /* $Id: menu.h,v 1.2 1998/10/20 19:57:35 hurtta Exp $
+  *
+  * Initially written by: Michael Elkins <elkins@aero.org>, 17 May 1995.
+  */
+ 
+ /* returns the number of the current selection from the menu */
+ #define MenuCurrent(X) X.current
+ 
+ /* this will make MenuLoop() update the screen on the next call */
+ #define MenuUpdate(X) (X.update = 1)
+ 
+ struct menu_object {
+   char **data;
+   char *title;
+   char *prompt;
+   char *help;
+   int prompt_length;
+   int len;
+   int max;
+   int current;
+   int pagetop; /* the index of the first entry on this page */
+   unsigned int update : 1;
+ };
+ typedef struct menu_object menu_t;
Index: elm2.4.ME+.50/hdrs/menu2.h
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/hdrs/menu2.h	Tue Nov 17 21:12:55 1998
***************
*** 0 ****
--- 1,12 ----
+ struct menu_item {
+   char *option;
+   char key;
+   char offset;
+   char type;
+   union ptrs { 
+     char *c;
+     int *i; /* used by BOL and INT */
+   } d;
+   int size;
+ };
+ 
Index: elm2.4.ME+.50/hdrs/mime.h
*** elm2.4.25/hdrs/mime.h	Sat Nov  7 22:50:23 1992
--- elm2.4.ME+.50/hdrs/mime.h	Tue Nov 17 21:12:55 1998
***************
*** 1,42 ****
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
!  * 			Copyright (c) 1988-1992 USENET Community Trust
!  * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
   ******************************************************************************
!  * $Log: mime.h,v $
!  * Revision 5.3  1992/11/07  20:50:08  syd
!  * add some new names to make header_cmp use easier
!  * From: Syd
!  *
!  * Revision 5.2  1992/10/25  01:47:45  syd
!  * fixed a bug were elm didn't call metamail on messages with a characterset,
!  * which could be displayed by elm itself, but message is encoded with QP
!  * or BASE64
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.1  1992/10/03  22:34:39  syd
!  * Initial checkin as of 2.4 Release at PL0
   *
!  *
!  ******************************************************************************/
  
  #define	MIME_HEADER	"MIME-Version: 1.0"
  #define	MIME_HEADER_NAME	"MIME-Version"
  #define	MIME_HEADER_VERSION	"1.0"
- #define	MIME_OLDVERSION	"MIME-Version: RFCXXXX"
- #define	MIME_HEADER_OLDVERSION	"RFCXXXX"
  #define	MIME_INCLUDE	"[include"
- #define MIME_BOUNDARY	"%#%record%#%"	/* default boundary */
  #define	MIME_CONTENTTYPE	"Content-Type:"
  #define	MIME_HEADER_CONTENTTYPE	"Content-Type"
  #define	MIME_CONTENTENCOD	"Content-Transfer-Encoding:"
  #define	MIME_HEADER_CONTENTENCOD	"Content-Transfer-Encoding"
  
  /* Encoding types */
--- 1,23 ----
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
   ******************************************************************************
!  *  The Elm Mail System 
   *
!  * 			Copyright (c) 1988-1992 USENET Community Trust
!  * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  #define	MIME_HEADER	"MIME-Version: 1.0"
  #define	MIME_HEADER_NAME	"MIME-Version"
  #define	MIME_HEADER_VERSION	"1.0"
  #define	MIME_INCLUDE	"[include"
  #define	MIME_CONTENTTYPE	"Content-Type:"
+ #define	MIME_CONTENTTYPE_LEN	13
  #define	MIME_HEADER_CONTENTTYPE	"Content-Type"
  #define	MIME_CONTENTENCOD	"Content-Transfer-Encoding:"
+ #define	MIME_CONTENTENCOD_LEN	26
  #define	MIME_HEADER_CONTENTENCOD	"Content-Transfer-Encoding"
  
  /* Encoding types */
***************
*** 50,62 ****
  #define	ENCODING_BASE64	5
  #define	ENCODING_EXPERIMENTAL	6
  
! #define	ENC_NAME_7BIT	"7bit"
! #define	ENC_NAME_8BIT	"8bit"
! #define	ENC_NAME_BINARY	"binary"
! #define	ENC_NAME_QUOTED "quoted-printable"
! #define	ENC_NAME_BASE64	"base64"
! 
! /* default charsets, which are a superset of US-ASCII, so we did not
     have to go out to metamail for us-ascii */
  
! #define COMPAT_CHARSETS "ISO-8859-1 ISO-8859-2 ISO-8859-3 ISO-8859-4 ISO-8859-5 ISO-8859-7 ISO-8859-8 ISO-8859-9"
--- 31,104 ----
  #define	ENCODING_BASE64	5
  #define	ENCODING_EXPERIMENTAL	6
  
! /* Default charsets, which are a superset of US-ASCII, so we do not
     have to go out to metamail for us-ascii */
  
! #define COMPAT_CHARSETS "ISO-8859-1 ISO-8859-2 ISO-8859-3 ISO-8859-4 ISO-8859-5 ISO-8859-7 ISO-8859-8 ISO-8859-9 KOI8-R"
! 
! /* These are for figuring out what the encoding on outgoing messages should
!  * be.
!  */
! #define HAVE_8BIT 1
! #define HAVE_CTRL 4
! #define HAVE_BINARY 8
! 
! /* Possible major types in Content-Type field. */
! #define MIME_TYPE_UNKNOWN	0
! #define MIME_TYPE_APPLICATION	1
! #define MIME_TYPE_AUDIO		2
! #define MIME_TYPE_IMAGE		3
! #define MIME_TYPE_MESSAGE	4
! #define MIME_TYPE_MULTIPART	5
! #define MIME_TYPE_TEXT		6
! #define MIME_TYPE_VIDEO		7
! 
! /* Values for the "flag" field in "mimeinfo" */
! #define MIME_RFC822      1
! #define MIME_MIXED       2
! #define MIME_DIGEST      4
! #define MIME_ALTERNATIVE 8
! 
! /* Content-Disposition */
! #define DISP_INLINE	0
! #define DISP_ATTACH	1
! 
! #define DISPOSITION(x) (x == DISP_INLINE ? "inline" : "attachment")
! #define TYPE(x) (mime_types[(x)])
! #define NONULL(x) (x ? x : "")
! #define ENCODING(x) (x >= 0 ? mime_encode_names[x] : "<ILLEGAL>")
! extern char *mime_encode_names[]; /* defined in mime.c */
! 
! typedef struct mime_send {    /* Mime parameters for this mail */
! 
!   /* Information for multipart  */
!   int encoding_top; /* Encoding for top multipart type.
!                      * ENCODING_8BIT:   add content_transfer_encoding: 8bit
!                      *                  pass -B8BITMIME to mailer
!                      * ENCODING_BINARY: add content_transfer_encoding: binary
! 		     *                  pass -BBINARYMIME to mailer
!                      */
!   char mime_boundary[STRING];
!   char type_opts_top[STRING];
! 
!   /* Information for text parts */
!   int encoding_text;/* Encoding of text parts (nt attachments)
! 		     * ENCODING_QUOTED: 
! 		     *         add content_transfer_encoding: quoted-printable
! 		     * ENCODING_8BIT:
! 		     *         add content_transfer_encoding: 8bit
! 		     */
!   int need_enc;     /* Bitmask: HAVE_8BIT:   have 8-bit data
! 		     *          HAVE_BINARY: have 'binary' data
! 		     *          HAVE_CTRL:   have control characters
! 		     */
!   char * Charset;   /* Charset of text */
!   unsigned int type_text : 3;
!   char         subtype_text[STRING];
!   char         type_opts_text[STRING];
! 
!   int msg_is_multipart;
!   char encoded_subject[LONG_STRING];
!   char encoded_fullname[STRING];
!   char encoded_in_reply_to[LONG_STRING];
! } mime_send_t;
Index: elm2.4.ME+.50/hdrs/ndbz.h
*** elm2.4.25/hdrs/ndbz.h	Tue Jul 20 05:59:54 1993
--- elm2.4.ME+.50/hdrs/ndbz.h	Tue Nov 17 21:12:55 1998
***************
*** 1,33 ****
  
! /* $Id: ndbz.h,v 5.3 1993/07/20 02:59:53 syd Exp $ */
! 
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: ndbz.h,v $
!  * Revision 5.3  1993/07/20  02:59:53  syd
!  * Support aliases both on 64 bit and 32 bit machines at the same time.
!  * From: Dan Mosedale <mosedale@genome.stanford.edu>
!  *
!  * Revision 5.2  1992/10/11  01:46:35  syd
!  * change dbm name to dbz to avoid conflicts with partial call
!  * ins from shared librarys, and from mixing code with yp code.
!  * From: Syd via prompt from Jess Anderson
!  *
!  * Revision 5.1  1992/10/03  22:34:39  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /**  define file for ndbz for mail system.  **/
  
--- 1,15 ----
+ /* $Id: ndbz.h,v 1.2 1998/10/20 19:57:35 hurtta Exp $ */
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
!  *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /**  define file for ndbz for mail system.  **/
  
***************
*** 133,153 ****
  	int dbz_written;		/* has a store() been done? */
  	} DBZ;
  
  /* standard dbz functions */
! extern DBZ *dbz_open();
! extern datum dbz_fetch();
! extern int dbz_store();
  extern int dbz_delete();	/* not in dbz */
  extern datum dbz_firstkey();	/* not in dbz */
  extern datum dbz_nextkey();	/* not in dbz */
! extern int dbz_close();		/* in dbz, but not in old dbm */
  
  /* new stuff for dbz */
! extern DBZ *dbz_fresh();
! extern DBZ *dbz_again();
! extern int dbz_sync();
! extern long dbz_size();
! extern int dbz_incore();
  extern int dbz_cancel();
  extern int dbz_debug();
  
--- 115,142 ----
  	int dbz_written;		/* has a store() been done? */
  	} DBZ;
  
+ #undef P_
+ #ifdef __STDC__
+ #define P_(x) x
+ #else
+ #define P_(x) ()
+ #endif
+ 
  /* standard dbz functions */
! extern DBZ *dbz_open          P_((char *,int, int));
! extern datum dbz_fetch        P_((DBZ *,datum));
! extern int dbz_store          P_((DBZ *,datum,datum));
  extern int dbz_delete();	/* not in dbz */
  extern datum dbz_firstkey();	/* not in dbz */
  extern datum dbz_nextkey();	/* not in dbz */
! extern int dbz_close          P_((DBZ *));     /* in dbz, but not in old dbm */
  
  /* new stuff for dbz */
! extern DBZ *dbz_fresh         P_((char *,long,int,of_t));
! extern DBZ *dbz_again         P_((char *,char *));
! extern int dbz_sync           P_((DBZ *));
! extern long dbz_size          P_((long));
! extern int dbz_incore         P_((int));
  extern int dbz_cancel();
  extern int dbz_debug();
  
Index: elm2.4.ME+.50/hdrs/nl_types.h
*** elm2.4.25/hdrs/nl_types.h	Sun Oct  4 01:35:10 1992
--- /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
***************
*** 1,46 ****
- #ifndef __nl_typesh
- #define __nl_typesh
- 
- 
- /***********************************************************
- Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
- 
-                         All Rights Reserved
- 
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that Alfalfa's name not be used in
- advertising or publicity pertaining to distribution of the software
- without specific, written prior permission.
- 
- ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
- 
- If you make any modifications, bugfixes or other changes to this software
- we'd appreciate it if you could send a copy to us so we can keep things
- up-to-date.  Many thanks.
- 				Kee Hinckley
- 				Alfalfa Software, Inc.
- 				267 Allston St., #3
- 				Cambridge, MA 02139  USA
- 				nazgul@alfalfa.com
-     
- ******************************************************************/
- 
- #define	NL_SETD	0
- 
- typedef	long	nl_catd;
- typedef long	nl_item;
- 
-     extern nl_catd 	catopen();
-     extern char		*catgets();
-     extern void		catclose();
- 
- #endif
--- 0 ----
Index: elm2.4.ME+.50/hdrs/elm_nl_types.h
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/hdrs/elm_nl_types.h	Tue Nov 17 21:12:55 1998
***************
*** 0 ****
--- 1,46 ----
+ #ifndef __nl_typesh
+ #define __nl_typesh
+ 
+ 
+ /***********************************************************
+ Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
+ 
+                         All Rights Reserved
+ 
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose and without fee is hereby granted,
+ provided that the above copyright notice appear in all copies and that
+ both that copyright notice and this permission notice appear in
+ supporting documentation, and that Alfalfa's name not be used in
+ advertising or publicity pertaining to distribution of the software
+ without specific, written prior permission.
+ 
+ ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ SOFTWARE.
+ 
+ If you make any modifications, bugfixes or other changes to this software
+ we'd appreciate it if you could send a copy to us so we can keep things
+ up-to-date.  Many thanks.
+ 				Kee Hinckley
+ 				Alfalfa Software, Inc.
+ 				267 Allston St., #3
+ 				Cambridge, MA 02139  USA
+ 				nazgul@alfalfa.com
+     
+ ******************************************************************/
+ 
+ #define	NL_SETD	0
+ 
+ typedef	long	nl_catd;
+ typedef long	nl_item;
+ 
+     extern nl_catd 	catopen();
+     extern char		*catgets();
+     extern void		catclose();
+ 
+ #endif
Index: elm2.4.ME+.50/hdrs/regexp.h
*** elm2.4.25/hdrs/regexp.h	Sun Nov 15 03:38:25 1992
--- elm2.4.ME+.50/hdrs/regexp.h	Tue Nov 17 21:12:55 1998
***************
*** 1,26 ****
  
! /* $Id: regexp.h,v 5.3 1992/11/15 01:38:23 syd Exp $ */
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
!  * 			Copyright (c) 1992 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: regexp.h,v $
!  * Revision 5.3  1992/11/15  01:38:23  syd
!  * fix headers
   *
!  * Revision 5.2  1992/11/15  01:37:57  syd
!  * add proper headers
!  *
!  *
!  ******************************************************************************/
  
  /*
   * Definitions etc. for regexp(3) routines.
--- 1,15 ----
  
! /* $Id: regexp.h,v 1.2 1998/10/20 19:57:35 hurtta Exp $ */
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  * 			Copyright (c) 1992 USENET Community Trust
!  *****************************************************************************/
  
  /*
   * Definitions etc. for regexp(3) routines.
Index: elm2.4.ME+.50/hdrs/s_aliases.h
*** elm2.4.25/hdrs/s_aliases.h	Mon Apr 12 07:14:23 1993
--- elm2.4.ME+.50/hdrs/s_aliases.h	Tue Nov 17 21:12:55 1998
***************
*** 1,4 ****
- /* s_aliases.h created from s_aliases.us by gencat on Mon Apr 12 00:14:23 EDT 1993 */
  
  #define AliasesSet	0x5
  #define AliasesDelete	0x1
--- 1,3 ----
***************
*** 120,122 ****
--- 119,122 ----
  #define AliasesHelpc	0x8e
  #define AliasesHelpT	0x8f
  #define AliasesModified	0x90
+ #define AliasesAddressAs1	0x91
Index: elm2.4.ME+.50/hdrs/s_answer.h
*** elm2.4.25/hdrs/s_answer.h	Sun Oct  4 01:35:11 1992
--- elm2.4.ME+.50/hdrs/s_answer.h	Tue Nov 17 21:12:55 1998
***************
*** 1,4 ****
- /* s_answer.h created from s_answer.us by gencat on Sat Oct  3 18:33:40 EDT 1992 */
  
  #define AnswerSet	0xb
  #define AnswerQuitWord	0x1
--- 1,3 ----
Index: elm2.4.ME+.50/hdrs/s_elm.h
*** elm2.4.25/hdrs/s_elm.h	Tue Aug  3 21:58:35 1993
--- elm2.4.ME+.50/hdrs/s_elm.h	Tue Nov 17 21:12:55 1998
***************
*** 1,4 ****
- /* s_elm.h created from s_elm.us by gencat on Tue Aug  3 14:58:35 EDT 1993 */
  
  #define ElmSet	0x3
  #define ElmYes	0x1
--- 1,3 ----
***************
*** 226,233 ****
  #define ElmHdrmenuPrecedenceBadValue	0xef
  #define ElmHdrmenuUserdefNotAlnum	0xf0
  #define ElmHdrmenuUserdefMissingColon	0xf1
- #define ElmHdrmenuDomInstruct	0xf2
- #define ElmHdrmenuDomPrompt	0xf3
  #define ElmHelpMessage	0xff
  #define ElmHelpPrompt	0x100
  #define ElmHelpUnknownCommand	0x101
--- 225,230 ----
***************
*** 759,761 ****
--- 756,923 ----
  #define ElmVfyMenuSndFgt	0x34e
  #define ElmVfyMessageKept	0x34f
  #define ElmVfyNoFieldsInForm	0x350
+ #define ElmHelpViewAttach	0x351
+ #define ElmBadModeInElmrc	0x352
+ #define ElmBadKeyInElmrc	0x353
+ #define ElmSendingMailBackground	0x354
+ #define ElmResendingMailBackground	0x355
+ #define ElmCouldntLockFolder	0x356
+ #define ElmIncludeBINARY	0x357
+ #define ElmInclude8BIT	0x358
+ #define ElmDoesnt8BIT	0x359
+ #define ElmDoesntBINARY	0x35a
+ #define ElmDontEncoding	0x35b
+ #define ElmCantMetamail	0x35c
+ #define ElmFolderRemoved	0x35d
+ #define ElmBadEKeyInElmrc	0x35e
+ #define ElmBadEKeyValues	0x35f
+ #define ElmLongValueInElmrc	0x360
+ #define ElmBackgroundLLT	0x361
+ #define ElmErrorReading	0x362
+ #define ElmErrorReadableUser	0x363
+ #define ElmCantOpenAttach	0x364
+ #define ElmInternalnoFD	0x365
+ #define ElmFailedSeekAttach	0x366
+ #define ElmWriteErrorAttach	0x367
+ #define ElmErrorCreatTempfile	0x368
+ #define ElmJobSpooled	0x369
+ #define ElmErrorPrinting	0x36a
+ #define ElmNoPermissionWrite	0x36b
+ #define ElmErrorOpening	0x36c
+ #define ElmUnsupportedEncoding	0x36d
+ #define ElmErrorSaving	0x36e
+ #define ElmMailSaved	0x36f
+ #define ElmCantStat	0x370
+ #define ElmCouldOpenReading	0x371
+ #define ElmStrucredNoEncoding	0x372
+ #define ElmNotKnowPrint	0x373
+ #define ElmMailNotSaved	0x374
+ #define ElmCantRenameTmpFile	0x375
+ #define ElmCantLinkTmpFile	0x376
+ #define ElmCantUnLinkTmpFile	0x377
+ #define ElmPgpNonZeroValue	0x378
+ #define ElmRunningPgp	0x379
+ #define ElmFailSignal	0x37a
+ #define ElmFailErrno	0x37b
+ #define ElmPgpErrorStatus	0x37c
+ #define ElmPgpDone	0x37d
+ #define ElmLostErrno	0x37e
+ #define ElmCantStart	0x37f
+ #define ElmOpenTmpWriting	0x380
+ #define ElmCantChangeFilename	0x381
+ #define ElmErrorAccess	0x382
+ #define ElmWarningBINARY	0x383
+ #define ElmStructuredNoencoding	0x384
+ #define ElmStructuredLeaf	0x385
+ #define ElmUnknownCommand2	0x386
+ #define ElmFileNotExist	0x387
+ #define ElmCantStatFile	0x388
+ #define ElmNotReadableByUser	0x389
+ #define ElmCheckingEncoding	0x38a
+ #define ElmCantOpenFile	0x38b
+ #define ElmNoAttachments	0x38c
+ #define ElmLastAttachment	0x38d
+ #define ElmFirstAttachment	0x38e
+ #define ElmPassphraseForgotten	0x38f
+ #define ElmUnknownCommand3	0x390
+ #define ElmBuiltInMore	0x391
+ #define ElmPgpMultipleKeys	0x392
+ #define ElmPgpPublicKey	0x393
+ #define ElmRemailTo	0x394
+ #define ElmMsgDeleted	0x395
+ #define ElmMsgsDeleted	0x396
+ #define ElmPagerStatDeleted	0x397
+ #define ElmPagerStatMessage	0x398
+ #define ElmPagerFailedTmpFile	0x399
+ #define ElmAttachMenu	0x39a
+ #define ElmErrorReadMailfile	0x39b
+ #define ElmForwardedMesg	0x39c
+ #define ElmMailTo	0x39d
+ #define ElmFailFileForward	0x39e
+ #define ElmUsingUNKNOWN8BIT	0x39f
+ #define ElmFixInclude	0x3a0
+ #define ElmAccessAttach	0x3a1
+ #define ElmBadAttach	0x3a2
+ #define ElmPgpAlreadyEncSig	0x3a3
+ #define ElmFailedSeekBytes	0x3a4
+ #define ElmPgpNoMatch	0x3a5
+ #define ElmHeaderUsingUNKNOWN8BIT	0x3a6
+ #define ElmHeaderBadCharset	0x3a7
+ #define ElmErrorOpeningName	0x3a8
+ #define ElmErrorWhenReading	0x3a9
+ #define ElmFailedLeaveFolder	0x3aa
+ #define ElmFailedResyncFolder	0x3ab
+ #define ElmALERTMailfileShrinken	0x3ac
+ #define ElmNoFolderEditing	0x3ad
+ #define ElmNoPgpPublicKeys	0x3ae
+ #define ElmNoMIMEMessage	0x3b1
+ #define ElmNoMessages	0x3b2
+ #define ElmDecryptBadPGP	0x3b3
+ #define ElmDecryptFailInitPGP	0x3b4
+ #define ElmDecryptFailInitPGPRaw	0x3b5
+ #define ElmDecryptEndRaw	0x3b6
+ #define ElmSigaction	0x3b7
+ #define ElmReadFailedCopy	0x3b8
+ #define ElmFingering	0x3b9
+ #define ElmRemailerReading	0x3ba
+ #define ElmRemailerCoulntTime	0x3bb
+ #define ElmRemailerCouldntList	0x3bc
+ #define ElmRemailerErrorTemp	0x3bd
+ #define ElmRemailerErrorTempRename	0x3be
+ #define ElmRemailerDatabase	0x3bf
+ #define ElmRemailerFind	0x3c0
+ #define ElmRemailerTempWriting	0x3c1
+ #define ElmRemailerFormating	0x3c2
+ #define ElmRemailerTempRead	0x3c3
+ #define ElmBuiltinHelpTitle	0x3c4
+ #define ElmBuiltinHelpKeyA	0x3c5
+ #define ElmBuiltinHelpSpace	0x3c6
+ #define ElmBuiltinHelpMinus	0x3c7
+ #define ElmBuiltinHelpReturn	0x3c8
+ #define ElmBuiltinHelpq	0x3c9
+ #define ElmBuiltinHelpDiv	0x3ca
+ #define ElmBuiltinHelpArr	0x3cb
+ #define ElmBuiltinHelpG	0x3cc
+ #define ElmBuiltinHelpCtrlL	0x3cd
+ #define ElmBuiltinHelpCtrlP	0x3ce
+ #define ElmBuiltinHelpCtrlD	0x3cf
+ #define ElmBuiltinHelpCtrlU	0x3d0
+ #define ElmBuiltinHelpQuestion	0x3d1
+ #define ElmBuiltinMore0	0x3d2
+ #define ElmBuiltinCommandi	0x3d3
+ #define ElmPgpEncrypt	0x3d4
+ #define ElmPgpSign	0x3d5
+ #define ElmPgpSignEncrypt	0x3d6
+ #define ElmWriteFMimeEncode	0x3d7
+ #define ElmWriteFWriteEncoded	0x3d8
+ #define ElmExtractPGPKey	0x3d9
+ #define ElmDebugHeader	0x3da
+ #define ElmVfyMenuAtttach	0x3db
+ #define ElmVfyMenuDsn	0x3dc
+ #define ElmVfyMenuSend	0x3dd
+ #define ElmVfyMenuForget	0x3de
+ #define ElmVfyMenuCopyFile	0x3df
+ #define ElmVfyMenuEdit	0x3e0
+ #define ElmVfyMenuHeaders	0x3e1
+ #define ElmVfyMenuIspell2	0x3e2
+ #define ElmVfyMenuPgp	0x3e3
+ #define ElmMenu2True	0x3e4
+ #define ElmMenu2False	0x3e5
+ #define ElmBuiltinHelpPressRet	0x3e6
+ #define ElmBuiltinNotFound	0x3e7
+ #define ElmBuiltinSearch	0x3e8
+ #define ElmPgpTo	0x3e9
+ #define ElmPgpFrom	0x3ea
+ #define ElmPgpP	0x3eb
+ #define ElmPgpEntUser	0x3ec
+ #define ElmDbxCurrMsgNum	0x3ed
+ #define ElmDbxHdrPage	0x3ee
+ #define ElmDbxCurrMailFile	0x3ef
+ #define ElmDbxPressAnyKey	0x3f0
+ #define ElmTerminatedWithSignal	0x3f1
+ #define ElmExitedWithStatus	0x3f2
+ #define ElmDoneCont	0x3f3
+ #define ElmMetaPagePressAnyKey	0x3f4
+ #define ElmToParen	0x3f5
+ #define ElmToNoParen	0x3f6
+ #define ElmToNoParen2	0x3f7
Index: elm2.4.ME+.50/hdrs/s_elmalias.h
*** elm2.4.25/hdrs/s_elmalias.h	Mon Apr 12 05:10:16 1993
--- elm2.4.ME+.50/hdrs/s_elmalias.h	Tue Nov 17 21:12:55 1998
***************
*** 1,4 ****
- /* s_elmalias.h created from s_elmalias.us by gencat on Sun Apr 11 22:03:05 EDT 1993 */
  
  #define ElmaliasSet	0x4
  #define ElmaliasUsage	0x1
--- 1,3 ----
Index: elm2.4.ME+.50/hdrs/s_elmrc.h
*** elm2.4.25/hdrs/s_elmrc.h	Fri Mar 11 23:18:49 1994
--- elm2.4.ME+.50/hdrs/s_elmrc.h	Tue Nov 17 21:12:55 1998
***************
*** 1,4 ****
- /* s_elmrc.h created from s_elmrc.us by gencat on Fri Mar 11 16:18:48 EST 1994 */
  
  #define ElmrcSet	0x1
  #define ElmrcExpandHome	0x1
--- 1,3 ----
Index: elm2.4.ME+.50/hdrs/s_error.h
*** elm2.4.25/hdrs/s_error.h	Sun Oct  4 01:35:12 1992
--- elm2.4.ME+.50/hdrs/s_error.h	Tue Nov 17 21:12:55 1998
***************
*** 1,4 ****
- /* s_error.h created from s_error.us by gencat on Sat Oct  3 18:34:12 EDT 1992 */
  
  #define ErrorSet	0x2
  #define ErrorGetoptReq	0x1
--- 1,3 ----
Index: elm2.4.ME+.50/hdrs/s_fastmail.h
*** elm2.4.25/hdrs/s_fastmail.h	Sun Oct  4 01:35:13 1992
--- elm2.4.ME+.50/hdrs/s_fastmail.h	Tue Nov 17 21:12:55 1998
***************
*** 1,4 ****
- /* s_fastmail.h created from s_fastmail.us by gencat on Sat Oct  3 18:34:11 EDT 1992 */
  
  #define FastmailSet	0x12
  #define FastmailCantFindFile	0x1
--- 1,3 ----
Index: elm2.4.ME+.50/hdrs/s_filter.h
*** elm2.4.25/hdrs/s_filter.h	Sun Nov 15 04:02:01 1992
--- elm2.4.ME+.50/hdrs/s_filter.h	Tue Nov 17 21:12:55 1998
***************
*** 1,4 ****
- /* s_filter.h created from s_filter.us by gencat on Sat Nov 14 21:02:00 EST 1992 */
  
  #define FilterSet	0x10
  #define FilterCantGetPasswdEntry	0x1
--- 1,3 ----
Index: elm2.4.ME+.50/hdrs/s_from.h
*** elm2.4.25/hdrs/s_from.h	Mon May 31 22:36:00 1993
--- elm2.4.ME+.50/hdrs/s_from.h	Tue Nov 17 21:12:54 1998
***************
*** 1,4 ****
- /* s_from.h created from s_from.us by gencat on Mon May 31 15:36:00 EDT 1993 */
  
  #define FromSet	0x11
  #define FromForMoreInfo	0x1
--- 1,3 ----
Index: elm2.4.ME+.50/hdrs/s_newalias.h
*** elm2.4.25/hdrs/s_newalias.h	Fri Dec 11 05:04:45 1992
--- elm2.4.ME+.50/hdrs/s_newalias.h	Tue Nov 17 21:12:55 1998
***************
*** 1,4 ****
- /* s_newalias.h created from s_newalias.us by gencat on Thu Dec 10 22:04:44 EST 1992 */
  
  #define NewaliasSet	0xc
  #define NewaliasUsage	0x1
--- 1,3 ----
Index: elm2.4.ME+.50/hdrs/s_newmail.h
*** elm2.4.25/hdrs/s_newmail.h	Tue Nov 17 21:24:10 1992
--- elm2.4.ME+.50/hdrs/s_newmail.h	Tue Nov 17 21:12:55 1998
***************
*** 1,4 ****
- /* s_newmail.h created from s_newmail.us by gencat on Sat Oct  3 18:34:18 EDT 1992 */
  
  #define NewmailSet	0xd
  #define NewmailNoSubject	0x1
--- 1,3 ----
Index: elm2.4.ME+.50/hdrs/s_readmsg.h
*** elm2.4.25/hdrs/s_readmsg.h	Sun Oct  4 01:35:16 1992
--- elm2.4.ME+.50/hdrs/s_readmsg.h	Tue Nov 17 21:12:54 1998
***************
*** 1,4 ****
- /* s_readmsg.h created from s_readmsg.us by gencat on Sat Oct  3 18:34:19 EDT 1992 */
  
  #define ReadmsgSet	0x13
  #define ReadmsgUsage	0x1
--- 1,3 ----
Index: elm2.4.ME+.50/hdrs/save_opts.h
*** elm2.4.25/hdrs/save_opts.h	Tue Aug 10 21:49:32 1993
--- elm2.4.ME+.50/hdrs/save_opts.h	Tue Nov 17 21:14:08 1998
***************
*** 1,75 ****
  
! /* @(#)$Id: save_opts.h,v 5.10 1993/08/10 18:49:32 syd Exp $ */
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.10 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: save_opts.h,v $
!  * Revision 5.10  1993/08/10  18:49:32  syd
!  * When an environment variable was given as the tmpdir definition the src
!  * and dest overlapped in expand_env.  This made elm produce a garbage
!  * expansion because expand_env cannot cope with overlapping src and
!  * dest.  I added a new variable raw_temp_dir to keep src and dest not to
!  * overlap.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.9  1993/06/12  05:28:06  syd
!  * Missing checkin
!  *
!  * Revision 5.8  1993/05/08  18:56:16  syd
!  * created a new elmrc variable named "readmsginc".  This specifies an
!  * increment by which the message count is updated.  If this variable is
!  * set to, say, 25, then the message count will only be updated every 25
!  * messages, displaying 0, 25, 50, 75, and so forth.  The default value
!  * of 1 will cause Elm to behave exactly as it currently does in PL21.
!  * From: Eric Peterson <epeterso@encore.com>
!  *
!  * Revision 5.7  1993/01/20  04:01:07  syd
!  * Adds a new integer parameter builtinlines.
!  * if (builtinlines < 0) and (the length of the message < LINES on
!  *       screen + builtinlines) use internal.
!  * if (builtinlines > 0) and (length of message < builtinlines)
!  * 	use internal pager.
!  * if (builtinlines = 0) or none of the above conditions hold, use the
!  * external pager if defined.
!  * From: "John P. Rouillard" <rouilj@ra.cs.umb.edu>
!  *
!  * Revision 5.6  1992/10/25  02:43:50  syd
!  * fix typo
!  *
!  * Revision 5.5  1992/10/25  02:38:27  syd
!  * Add missing new flags for new elmrc options for confirm
!  * From: Syd
!  *
!  * Revision 5.4  1992/10/24  13:44:41  syd
!  * There is now an additional elmrc option "displaycharset", which
!  * sets the charset supported on your terminal. This is to prevent
!  * elm from calling out to metamail too often.
!  * Plus a slight documentation update for MIME composition (added examples)
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.3  1992/10/17  22:58:57  syd
!  * patch to make elm use (or in my case, not use) termcap/terminfo ti/te.
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.2  1992/10/17  22:42:24  syd
!  * Add flags to read_rc to support command line overrides of the option.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.1  1992/10/03  22:34:39  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /*
   *	Defines for the storage of options portion of the Elm system.
--- 1,16 ----
  
! /* @(#)$Id: save_opts.h,v 1.3 1998/11/08 18:21:22 hurtta Exp $ */
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /*
   *	Defines for the storage of options portion of the Elm system.
***************
*** 95,100 ****
--- 36,42 ----
  #define DT_SRT 7 /* sort-by code */
  #define DT_MLT 8 /* multiple destinations for data */
  #define DT_ASR 9 /* sort-by code */
+ #define DT_PRM 10 /* file permissions */
  #define DT_MASK 037 /* mask for data type */
  #define FL_LOCAL 0040          /* flag if changed */
  #define FL_NOSPC 0100          /* flag if preserve blanks as "_" */
***************
*** 102,107 ****
--- 44,54 ----
  #define FL_OR    0400          /* flag if boolean value may have been set */
  #define FL_AND  01000          /* flag if boolean value may have been unset */
  
+ typedef struct {
+    int nlen;
+    char **list;
+ }  enumerate_list;
+ 
  typedef struct { 
  	char 	name[NLEN]; 	/* name of instruction */
  	long 	offset;		/* offset into elmrc-info file */
***************
*** 115,120 ****
--- 62,69 ----
            struct addr_rec **alts;
            int 	*sort;
            } val;
+           int size_val;
+           enumerate_list   *e_ptr;
  	} save_info_recs;
  
  /*
***************
*** 127,132 ****
--- 76,83 ----
  	long 	offset;		/* offset into elmrc-info file */
          int	flags;	/* DT_STR, DT_NUM, DT_BOL, etc */
          char 	*str;
+         int              size_val;
+         enumerate_list   *e_ptr;
  	} save_info_recs_init;
  
  #define SAVE_INFO_STR(x) (save_info[x].val.str)
***************
*** 137,144 ****
  #define SAVE_INFO_ALT(x) (save_info[x].val.alts)
  #define SAVE_INFO_SRT(x) (save_info[x].val.sort)
  #define SAVE_INFO_ASR(x) (save_info[x].val.sort)
! #define SAVE_INFO_SYN(x) ((char *)save_info[x].val.str)
! #define SAVE_INFO_MLT(x) ((char **)save_info[x].val.weed)
  
  #ifdef SAVE_OPTS
  
--- 88,95 ----
  #define SAVE_INFO_ALT(x) (save_info[x].val.alts)
  #define SAVE_INFO_SRT(x) (save_info[x].val.sort)
  #define SAVE_INFO_ASR(x) (save_info[x].val.sort)
! #define SAVE_INFO_SYN(x) (save_info[x].val.str)
! #define SAVE_INFO_MLT(x) (save_info[x].val.weed)
  
  #ifdef SAVE_OPTS
  
***************
*** 148,253 ****
  char *SIGS[]={"remotesignature","localsignature",NULL},
  	*ALWAYS[]={"alwayskeep","alwaysstore",NULL};
  
  save_info_recs_init save_info_data[] = {
! {"aliassortby",		-1L,DT_ASR,(char *)&alias_sortby},
! {"alteditor",		-1L,DT_STR,alternative_editor},
! {"alternatives",	-1L,DT_ALT,(char *)&alternative_addresses},
! {"alwaysdelete",	-1L,DT_BOL,(char *)&always_del},
! {"alwayskeep",		-1L,DT_BOL,(char *)&always_keep},
! {"alwaysleave",		-1L,DT_MLT,(char *)ALWAYS},
! {"alwaysstore",		-1L,DT_BOL,(char *)&always_store},
! {"arrow",		-1L,DT_BOL|FL_OR,(char *)&arrow_cursor},
! {"ask",			-1L,DT_BOL,(char *)&question_me},
! {"askcc",		-1L,DT_BOL,(char *)&prompt_for_cc},
! {"attribution",		-1L,DT_STR,attribution},
! {"auto_cc",		-1L,DT_SYN,"copy"},
! {"autocopy",		-1L,DT_BOL,(char *)&auto_copy},
! {"bounce",		-1L,DT_SYN,"bounceback"},
! {"bounceback",		-1L,DT_NUM,(char *)&bounceback},
! {"builtinlines",	-1L,DT_NUM,(char *)&builtin_lines},
! {"calendar",		-1L,DT_STR,raw_calendar_file},
! {"cc",			-1L,DT_SYN,"askcc"},
! #ifdef MIME
! {"charset",		-1L,DT_STR,charset},
! {"compatcharsets",		-1L,DT_STR,charset_compatlist},
! #endif
! {"configoptions",	-1L,DT_STR,config_options},
! {"confirmappend",	-1L,DT_BOL,(char *)&confirm_append},
! {"confirmcreate",	-1L,DT_BOL,(char *)&confirm_create},
! {"confirmfiles",	-1L,DT_BOL,(char *)&confirm_files},
! {"confirmfolders",	-1L,DT_BOL,(char *)&confirm_folders},
! {"copy",		-1L,DT_BOL,(char *)&auto_cc},
! {"delete",		-1L,DT_SYN,"alwaysdelete"},
! #ifdef MIME
! {"displaycharset",	-1L,DT_STR,display_charset},
! #endif
! {"easyeditor",		-1L,DT_STR,e_editor},
! {"editor",		-1L,DT_STR,raw_editor},
! {"escape",		-1L,DT_CHR,(char *)&escape_char},
! {"folders",		-1L,DT_SYN,"maildir"},
! {"forcename",		-1L,DT_BOL,(char *)&force_name},
! {"form",		-1L,DT_SYN,"forms"},
! {"forms",		-1L,DT_BOL,(char *)&allow_forms},
! {"fullname",		-1L,DT_STR,full_username},
! {"hostdomain",		-1L,DT_STR|FL_SYS,hostdomain},
! {"hostfullname",	-1L,DT_STR|FL_SYS,hostfullname},
! {"hostname",		-1L,DT_STR|FL_SYS,hostname},
! {"hpkeypad",		-1L,DT_SYN,"keypad"},
! {"hpsoftkeys",		-1L,DT_SYN,"softkeys"},
! {"keep",		-1L,DT_SYN,"keepempty"},
! {"keepempty",		-1L,DT_BOL,(char *)&keep_empty_files},
! {"keypad",		-1L,DT_BOL|FL_OR,(char *)&hp_terminal},
! {"localsignature",	-1L,DT_STR,raw_local_signature},
! {"mailbox",		-1L,DT_SYN,"receivedmail"},
! {"maildir",		-1L,DT_STR,raw_folders},
! {"mailedit",		-1L,DT_SYN,"editor"},
! {"menu",		-1L,DT_BOL|FL_AND,(char *)&mini_menu},
! {"menus",		-1L,DT_SYN,"menu"},
! {"metoo",		-1L,DT_BOL,(char *)&metoo},
! {"movepage",		-1L,DT_BOL,(char *)&move_when_paged},
! {"movewhenpaged",	-1L,DT_SYN,"movepage"},
! {"name",		-1L,DT_SYN,"fullname"},
! {"names",		-1L,DT_BOL,(char *)&names_only},
! {"noheader",		-1L,DT_BOL,(char *)&noheader},
! {"page",		-1L,DT_SYN,"pager"},
! {"pager",		-1L,DT_STR,raw_pager},
! {"pointnew",		-1L,DT_BOL,(char *)&point_to_new},
! {"pointtonew",		-1L,DT_SYN,"pointnew"},
! {"precedences",		-1L,DT_STR,allowed_precedences},
! {"prefix",		-1L,DT_STR|FL_NOSPC,prefixchars},
! {"print",		-1L,DT_STR,raw_printout},
! {"printmail",		-1L,DT_SYN,"print"},
! {"promptafter",		-1L,DT_BOL,(char *)&prompt_after_pager},
! {"question",		-1L,DT_SYN,"ask"},
! {"readmsginc",		-1L,DT_NUM,(char *)&readmsginc},
! {"receivedmail",	-1L,DT_STR,raw_recvdmail},
! {"remotesignature",	-1L,DT_STR,raw_remote_signature},
! {"resolve",		-1L,DT_BOL,(char *)&resolve_mode},
! {"savebyname",		-1L,DT_SYN,"savename"},
! {"savemail",		-1L,DT_SYN,"sentmail"},
! {"savename",		-1L,DT_BOL,(char *)&save_by_name},
! {"saveto",		-1L,DT_SYN,"sentmail"},
! {"sentmail",		-1L,DT_STR,raw_sentmail},
! {"shell",		-1L,DT_STR,raw_shell},
! {"sigdashes",		-1L,DT_BOL,(char *)&sig_dashes},
! {"signature",		-1L,DT_MLT,(char *)SIGS},
! {"sleepmsg",		-1L,DT_NUM,(char *)&sleepmsg},
! {"softkeys",		-1L,DT_BOL|FL_OR,(char *)&hp_softkeys},
! {"sort",		-1L,DT_SYN,"sortby"},
! {"sortby",		-1L,DT_SRT,(char *)&sortby},
! {"store",		-1L,DT_SYN,"alwaysstore"},
! #ifdef MIME
! {"textencoding", -1L,DT_STR,text_encoding},
! #endif
! {"timeout",		-1L,DT_NUM,(char *)&timeout},
! {"titles",		-1L,DT_BOL,(char *)&title_messages},
! {"tmpdir",		-1L,DT_STR,raw_temp_dir},
! {"userlevel",		-1L,DT_NUM,(char *)&user_level},
! {"username",		-1L,DT_SYN,"fullname"},
! {"usetite",		-1L,DT_BOL|FL_AND,(char *)&use_tite},
! {"visualeditor",	-1L,DT_STR,v_editor},
! {"weed",		-1L,DT_BOL,(char *)&filter},
! {"weedout",		-1L,DT_WEE,(char *)weedlist},
  };
  int NUMBER_OF_SAVEABLE_OPTIONS=(sizeof(save_info_data)/sizeof(save_info_recs_init));
  save_info_recs *save_info = (save_info_recs *) save_info_data;
--- 99,271 ----
  char *SIGS[]={"remotesignature","localsignature",NULL},
  	*ALWAYS[]={"alwayskeep","alwaysstore",NULL};
  
+ static char * USERLEVELS[] = { "beginner", "intermediate", "expert", NULL };
+ static enumerate_list USERLEVEL = {3, &(USERLEVELS[0]) };
+ 
+ static char * NOENCODINGS[] = { "pass-7bit", "pass-8bit", "pass-binary", NULL };
+ static enumerate_list NOENCODING = {3, &(NOENCODINGS[0]) };
+ 
  save_info_recs_init save_info_data[] = {
! {"aliassortby",		-1L,DT_ASR,(char *)&alias_sortby, 0, NULL},
! {"alteditor",		-1L,DT_STR,alternative_editor,
!    sizeof alternative_editor, NULL},
! {"alternatives",	-1L,DT_ALT,(char *)&alternative_addresses, 0, NULL},
! {"alwaysdelete",	-1L,DT_BOL,(char *)&always_del, 0, NULL},
! {"alwayskeep",		-1L,DT_BOL,(char *)&always_keep, 0, NULL},
! {"alwaysleave",		-1L,DT_MLT,(char *)ALWAYS, 0, NULL},
! {"alwaysstore",		-1L,DT_BOL,(char *)&always_store, 0, NULL},
! {"arrow",		-1L,DT_BOL|FL_OR,(char *)&arrow_cursor, 0, NULL},
! {"ask",			-1L,DT_BOL,(char *)&question_me, 0,   NULL},
! {"askcc",		-1L,DT_BOL,(char *)&prompt_for_cc, 0, NULL},
! #ifdef USE_PGP
! {"askpgpsig",		-1L,DT_BOL,(char *)&pgp_askpgpsig, 0, NULL},
! #endif
! {"attribution",		-1L,DT_STR,attribution, sizeof attribution, NULL},
! {"auto-cc",		-1L,DT_SYN,"copy", 0, NULL},
! {"autocopy",		-1L,DT_BOL,(char *)&auto_copy, 0, NULL},
! #ifdef BACKGROUD_PROCESSES       
! { "background-wait-time",-1L,DT_NUM,(char *)&background_wait_time, 0, NULL }, 
! #endif
!   /* {"bounce",		-1L,DT_SYN,"bounceback", 0, NULL},
!      {"bounceback",		-1L,DT_NUM,(char *)&bounceback, 0, NULL},
!      */
! {"builtinlines",	-1L,DT_NUM,(char *)&builtin_lines, 0, NULL},
! {"calendar",		-1L,DT_STR,raw_calendar_file, 
!    sizeof raw_calendar_file, NULL},
! {"cc",			-1L,DT_SYN,"askcc", 0, NULL},
! #ifdef MIME
! {"charset",		-1L,DT_STR,raw_charset, sizeof raw_charset, NULL},
! {"compatcharsets",		-1L,DT_STR,charset_compatlist,
!    sizeof charset_compatlist, NULL},
! #endif
! {"configoptions",	-1L,DT_STR,config_options, sizeof config_options, 
!    NULL},
! {"confirmappend",	-1L,DT_BOL,(char *)&confirm_append, 0, NULL},
! {"confirmcreate",	-1L,DT_BOL,(char *)&confirm_create, 0, NULL},
! {"confirmfiles",	-1L,DT_BOL,(char *)&confirm_files, 0, NULL},
! {"confirmfolders",	-1L,DT_BOL,(char *)&confirm_folders, 0, NULL},
! {"copy",		-1L,DT_BOL,(char *)&auto_cc, 0, NULL},
! {"delete",		-1L,DT_SYN,"alwaysdelete",   0, NULL},
! #ifdef MIME
! {"displaycharset",	-1L,DT_STR,raw_display_charset,
!    sizeof raw_display_charset, NULL},
! #endif
! #ifdef USE_DSN
! {"dsn-success",         -1L,DT_BOL,(char *)&DSN_success, 0, NULL },
! #endif
! {"easyeditor",		-1L,DT_STR,e_editor,   sizeof e_editor,   NULL},
! {"editor",		-1L,DT_STR,raw_editor, sizeof raw_editor, NULL},
! {"escape",		-1L,DT_CHR,(char *)&escape_char, 0,       NULL},
! {"folders",		-1L,DT_SYN,"maildir", 0,                  NULL},
! {"forcename",		-1L,DT_BOL,(char *)&force_name, 0,        NULL},
! {"form",		-1L,DT_SYN,"forms", 0,                    NULL},
! {"forms",		-1L,DT_BOL,(char *)&allow_forms, 0,       NULL},
! {"fullname",		-1L,DT_STR,full_username, sizeof full_username, NULL},
! {"hostdomain",		-1L,DT_STR|FL_SYS,hostdomain,   sizeof hostdomain, 
!    NULL},
! {"hostfullname",	-1L,DT_STR|FL_SYS,hostfullname, sizeof hostfullname, 
!    NULL},
! {"hostname",		-1L,DT_STR|FL_SYS,hostname,     sizeof hostname, 
!    NULL},
!   /* {"hpkeypad",		-1L,DT_SYN,"keypad", 0, NULL}, */
!   /* {"hpsoftkeys",		-1L,DT_SYN,"softkeys", 0, NULL}, */
! {"keep",		-1L,DT_SYN,"keepempty", 0, NULL},
! {"keepempty",		-1L,DT_BOL,(char *)&keep_empty_files, 0, NULL},
! #ifdef USE_PGP
! {"keeppassfor", -1L,DT_NUM,(char *)&pgp_keeppassfor, 0, NULL},
! #endif
!   /* {"keypad",		-1L,DT_BOL|FL_OR,(char *)&hp_terminal, 0, NULL}, */
! {"localsignature",	-1L,DT_STR,raw_local_signature, 
!    sizeof raw_local_signature, NULL},
! {"lock-in-copy",        -1L,DT_BOL,(char *)&lock_in_copy,0, NULL},
! {"mailbox",		-1L,DT_SYN,"receivedmail", 0, NULL},
! {"maildir",		-1L,DT_STR,raw_folders, sizeof raw_folders, NULL},
! {"mailedit",		-1L,DT_SYN,"editor", 0, NULL},
! {"mailpermissions",	-1L,DT_PRM,(char *)&mail_permissions, 0, NULL},
! {"menu",		-1L,DT_BOL|FL_AND,(char *)&mini_menu, 0, NULL},
! {"menus",		-1L,DT_SYN,"menu", 0, NULL},
! #ifdef MIME
! {"metamail",		-1L,DT_STR,raw_metamail_path, 
!    sizeof raw_metamail_path, NULL},
! #endif
! {"metoo",		-1L,DT_BOL,(char *)&metoo, 0, NULL},
! #ifdef MIME
! {"mimeforward",		-1L,DT_BOL,(char *)&mimeforward, 0, NULL},
! #endif
! {"movepage",		-1L,DT_BOL,(char *)&move_when_paged, 0, NULL},
! {"movewhenpaged",	-1L,DT_SYN,"movepage", 0, NULL},
! {"name",		-1L,DT_SYN,"fullname", 0, NULL},
! {"names",		-1L,DT_BOL,(char *)&names_only, 0, NULL},
! #ifdef MIME
! {"noencoding",-1L,DT_NUM,(char *)&allow_no_encoding, 0, &NOENCODING},
!                                  /* 1 (8bit): Allow 8bit without -B8BITMIME
!                                   * 2 (biary): Allow binary without -BBINARYMIME and
!                                   *    and 8bit without -B8BITMIME */
! {"nohdrencoding",       -1L,DT_BOL,(char *)&allow_no_hdrencoding, 0, NULL},
! #endif /* MIME **/
! {"noheader",		-1L,DT_BOL,(char *)&noheader, 0, NULL},
! {"noheaderfwd",		-1L,DT_BOL,(char *)&noheaderfwd, 0, NULL},
! {"page",		-1L,DT_SYN,"pager", 0, NULL},
! #ifdef MIME
! {"pagealternative",	-1L,DT_BOL,(char *)&pagealternative, 0, NULL},
! {"pagemultipart",	-1L,DT_BOL,(char *)&pagemultipart, 0, NULL},
! #endif /* MIME */
! {"pager",		-1L,DT_STR,raw_pager, sizeof raw_pager, NULL},
! #ifdef USE_PGP
! {"pgp",		        -1L,DT_STR,raw_pgp_path, sizeof raw_pgp_path, NULL},
! #endif
! {"pointnew",		-1L,DT_BOL,(char *)&point_to_new, 0, NULL},
! {"pointtonew",		-1L,DT_SYN,"pointnew", 0, NULL},
! {"precedences",		-1L,DT_STR,allowed_precedences, 
!    sizeof allowed_precedences, NULL},
! {"prefix",		-1L,DT_STR|FL_NOSPC,prefixchars,
!    sizeof prefixchars, NULL},
! {"print",		-1L,DT_STR,raw_printout, sizeof raw_printout, NULL},
! {"printmail",		-1L,DT_SYN,"print", 0, NULL},
! {"promptafter",		-1L,DT_BOL,(char *)&prompt_after_pager, 0, NULL},
! {"question",		-1L,DT_SYN,"ask", 0, NULL},
! {"quoteforward",	-1L,DT_BOL,(char *)&quote_forward, 0, NULL},
! {"readmsginc",		-1L,DT_NUM,(char *)&readmsginc, 0, NULL},
! {"receivedmail",	-1L,DT_STR,raw_recvdmail, sizeof raw_recvdmail, NULL},
! {"remotesignature",	-1L,DT_STR,raw_remote_signature, 
!    sizeof raw_remote_signature, NULL},
! #ifdef MIME
! {"require-mime-version-for-body-encoding",
!    -1L,DT_BOL,(char *)&req_mime_bodyencoding, 0, NULL},
! {"require-mime-version-for-hdr-encoding",
!    -1L,DT_BOL,(char *)&req_mime_hdrencoding, 0, NULL},
! #endif
! {"resolve",		-1L,DT_BOL,(char *)&resolve_mode, 0, NULL},
! {"savebyname",		-1L,DT_SYN,"savename", 0, NULL},
! {"savemail",		-1L,DT_SYN,"sentmail", 0, NULL},
! {"savename",		-1L,DT_BOL,(char *)&save_by_name, 0, NULL},
! {"saveto",		-1L,DT_SYN,"sentmail", 0, NULL},
! {"sentmail",		-1L,DT_STR,raw_sentmail, sizeof raw_sentmail, NULL},
! {"shell",		-1L,DT_STR,raw_shell, sizeof raw_shell, NULL},
! #ifdef USE_PGP
! {"showpgppreamble",	-1L,DT_BOL,(char *)&pgp_noarmor, 0, NULL},
! #endif
! {"showto",		-1L,DT_BOL,(char *)&showto, 0, NULL},
! {"sigdashes",		-1L,DT_BOL,(char *)&sig_dashes, 0, NULL},
! {"signature",		-1L,DT_MLT,(char *)SIGS, 0, NULL},
! {"sleepmsg",		-1L,DT_NUM,(char *)&sleepmsg, 0, NULL},
!   /* {"softkeys",		-1L,DT_BOL|FL_OR,(char *)&hp_softkeys, 0, 
!      NULL}, */
! {"sort",		-1L,DT_SYN,"sortby", 0, NULL},
! {"sortby",		-1L,DT_SRT,(char *)&sortby, 0, NULL},
! {"store",		-1L,DT_SYN,"alwaysstore", 0, NULL},
! {"timeout",		-1L,DT_NUM,(char *)&elm_timeout, 0, NULL},
! {"titles",		-1L,DT_BOL,(char *)&title_messages, 0, NULL},
! {"tmpdir",		-1L,DT_STR,raw_temp_dir, sizeof raw_temp_dir, NULL},
! #ifdef USE_PGP
! {"usepgppass",          -1L,DT_BOL,(char *)&pgp_keeppass, 0, NULL},
! #endif
! {"userlevel",		-1L,DT_NUM,(char *)&user_level, 0, &USERLEVEL},
! {"username",		-1L,DT_SYN,"fullname", 0, NULL},
! {"usetite",		-1L,DT_BOL|FL_AND,(char *)&use_tite, 0, NULL},
! {"visualeditor",	-1L,DT_STR,v_editor, sizeof v_editor, NULL},
! {"weed",		-1L,DT_BOL,(char *)&elm_filter, 0, NULL},
! {"weedout",		-1L,DT_WEE,(char *)weedlist, 0, NULL},
  };
  int NUMBER_OF_SAVEABLE_OPTIONS=(sizeof(save_info_data)/sizeof(save_info_recs_init));
  save_info_recs *save_info = (save_info_recs *) save_info_data;
Index: elm2.4.ME+.50/hdrs/sysdefs.SH
*** elm2.4.25/hdrs/sysdefs.SH	Thu Dec 24 21:24:11 1992
--- elm2.4.ME+.50/hdrs/sysdefs.SH	Tue Nov 17 21:14:08 1998
***************
*** 16,60 ****
  
  echo "Extracting hdrs/sysdefs.h (with variable substitutions)"
  sed <<!GROK!THIS! >sysdefs.h -e 's!^#undef!/\*#undef!'
! /* $Id: sysdefs.SH,v 5.4 1992/12/24 19:24:10 syd Exp $ */
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: sysdefs.SH,v $
!  * Revision 5.4  1992/12/24  19:24:10  syd
!  * EDITOROPTS and DEFEDITOR appear to be unused but here is
!  * a patch to make use of $editoropts.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.3  1992/11/22  01:14:20  syd
!  * Allow SCO MMDF to use the mmdf library for mailer via execmail.
!  * From: Larry Philps <larryp@sco.com>
!  *
!  * Revision 5.2  1992/10/24  13:44:41  syd
!  * There is now an additional elmrc option "displaycharset", which
!  * sets the charset supported on your terminal. This is to prevent
!  * elm from calling out to metamail too often.
!  * Plus a slight documentation update for MIME composition (added examples)
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.1  1992/10/03  22:34:39  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /**  System level, configurable, defines for the ELM mail system.  **/
  
- 
  #define MAX_IN_WEEDLIST 150	/* max headers to weed out               */
  
  #define MAX_HOPS	35	/* max hops in return addr to E)veryone  */
--- 16,35 ----
  
  echo "Extracting hdrs/sysdefs.h (with variable substitutions)"
  sed <<!GROK!THIS! >sysdefs.h -e 's!^#undef!/\*#undef!'
! /* $Id: sysdefs.SH,v 1.4 1998/11/08 18:21:22 hurtta Exp $ */
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.4 $   $State: Exp $
!  *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /**  System level, configurable, defines for the ELM mail system.  **/
  
  #define MAX_IN_WEEDLIST 150	/* max headers to weed out               */
  
  #define MAX_HOPS	35	/* max hops in return addr to E)veryone  */
***************
*** 78,91 ****
  
  ****************************************************************************/
  
! #define system_text_file        "$lib/aliases.text"
! #define system_data_file        "$lib/aliases"
! #define system_rc_file		"$lib/elm.rc"
! 
! #define ALIAS_TEXT		".elm/aliases.text"
! #define ALIAS_DATA		".elm/aliases"
  
! #define hostdomfile             "$lib/domain"
  
  /** where to put the output of the elm -d command... (in home dir) **/
  #define DEBUGFILE	"ELM:debug.info"
--- 53,70 ----
  
  ****************************************************************************/
  
! #define SYSTEM_TEXT_FILE        "$lib/aliases.text"
! #define SYSTEM_DATA_FILE        "$lib/aliases"
! #define SYSTEM_RC_FILE		"$lib/elm.rc"
! #define SYSTEM_MIME_TYPES	"$lib/elm.mimetypes"
! #define SYSTEM_MIME_CHARSETS    "$lib/elm.mimecharsets"
! 
! #define USER_ALIAS_TEXT		".elm/aliases.text"
! #define USER_ALIAS_DATA		".elm/aliases"
! #define USER_MIME_TYPES	        ".elm/mime.types"
! #define USER_MIME_CHARSETS	".elm/mime.charsets"
  
! #define HOSTDOMFILE             "$lib/domain"
  
  /** where to put the output of the elm -d command... (in home dir) **/
  #define DEBUGFILE	"ELM:debug.info"
***************
*** 97,103 ****
  #define temp_mbox	"mbox."
  #define temp_print      "print."
  #define temp_edit	"elm-edit"
! #define temp_uuname	"uuname."
  #define temp_state	"est."
  
  #define emacs_editor	"$emacs"
--- 76,82 ----
  #define temp_mbox	"mbox."
  #define temp_print      "print."
  #define temp_edit	"elm-edit"
! /* #define temp_uuname	"uuname." */
  #define temp_state	"est."
  
  #define emacs_editor	"$emacs"
***************
*** 106,130 ****
  #define default_editor	"$defeditor $editoropts"
  #define mailhome	"$maildir/"
  
- #define default_shell	"$prefshell"
  #define default_pager	"$pager"
  #define default_printout	"$cat %s | $linepr"
  
  #define default_charset	"$defcharset"
! #define default_display_charset	"$defdispcharset"
! #define default_encoding	"$defencoding"
  #define execmail	"$execmail"
- #define emflags		""
- #define emflagsv	"-d"		/* Verbose voyuer mode */
- #define emflagmt	"-m"		/* metoo copy to sender */
  
  #define sendmail	"$sendmail"
- #define smflags		"-oi -oem"	/* ignore dots and mail back errors */
- #define smflagsv	"-oi -oem -v"	/* Verbose voyuer mode */
- #define smflagmt	" -om"		/* metoo copy to sender */
  #define submitmail	"$submit"
  #define submitflags	"-mlrnvxto,cc*"
- #define submitflags_s	"-mlrnv"
  #define mailer		"$mailer"
  
  #define mailx		"$mailx"
--- 85,100 ----
  #define default_editor	"$defeditor $editoropts"
  #define mailhome	"$maildir/"
  
  #define default_pager	"$pager"
  #define default_printout	"$cat %s | $linepr"
  
  #define default_charset	"$defcharset"
! #define DEFAULT_DISPLAY_CHARSET	"$defdispcharset"
  #define execmail	"$execmail"
  
  #define sendmail	"$sendmail"
  #define submitmail	"$submit"
  #define submitflags	"-mlrnvxto,cc*"
  #define mailer		"$mailer"
  
  #define mailx		"$mailx"
***************
*** 134,142 ****
  
  #define ELMRC_INFO	"$lib/elmrc-info"
  
! #define elmrcfile	".elm/elmrc"
  #define old_elmrcfile	".elm/elmrc.old"
! #define mailheaders	".elm/elmheaders"
  #define dead_letter	"Canceled.mail"
  
  #define unedited_mail	"emergency.mbox"
--- 104,112 ----
  
  #define ELMRC_INFO	"$lib/elmrc-info"
  
! #define ELMRCFILE	".elm/elmrc"
  #define old_elmrcfile	".elm/elmrc.old"
! #define MAILHEADERS	".elm/elmheaders"
  #define dead_letter	"Canceled.mail"
  
  #define unedited_mail	"emergency.mbox"
***************
*** 145,154 ****
  #define readmsg		"readmsg"
  
  #define remove_cmd	"$rm -f"	/* how to remove a file */
! #define cat		"$cat"		/* how to display files */
  #define sed_cmd		"$sed"		/* how to access sed */
  #define move_cmd	"$mv"		/* how to access sed */
! #define uuname		"$uuname"	/* how to get a uuname  */
  
  #define MSG_SEPARATOR	"\001\001\001\001\n"	/* mmdf message seperator */
  
--- 115,124 ----
  #define readmsg		"readmsg"
  
  #define remove_cmd	"$rm -f"	/* how to remove a file */
! /* #define cat		"$cat"		/* how to display files */
  #define sed_cmd		"$sed"		/* how to access sed */
  #define move_cmd	"$mv"		/* how to access sed */
! /* #define uuname		"$uuname"	/* how to get a uuname  */
  
  #define MSG_SEPARATOR	"\001\001\001\001\n"	/* mmdf message seperator */
  
Index: elm2.4.ME+.50/lib/Makefile.SH
*** elm2.4.25/lib/Makefile.SH	Tue Aug  3 22:28:46 1993
--- elm2.4.ME+.50/lib/Makefile.SH	Tue Nov 17 21:12:55 1998
***************
*** 36,42 ****
  
  echo "Extracting lib/Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
! # $Id: Makefile.SH,v 5.15 1993/08/03 19:28:39 syd Exp $
  #
  #  Makefile for the ELM mail program.
  #
--- 36,42 ----
  
  echo "Extracting lib/Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
! # $Id: Makefile.SH,v 1.1.1.1 1998/10/15 15:36:40 hurtta Exp $
  #
  #  Makefile for the ELM mail program.
  #
***************
*** 43,141 ****
  #	Copyright (c) 1986,1987 Dave Taylor
  #	Copyright (c) 1988-1992 USENET Community Trust
  #
- # Bug reports, patches, comments, suggestions should be sent to:
  #
- #	Syd Weinstein - elm@DSI.COM
- #			dsinc!elm
  #
- # $Log: Makefile.SH,v $
- # Revision 5.15  1993/08/03  19:28:39  syd
- # Elm tries to replace the system toupper() and tolower() on current
- # BSD systems, which is unnecessary.  Even worse, the replacements
- # collide during linking with routines in isctype.o.  This patch adds
- # a Configure test to determine whether replacements are really needed
- # (BROKE_CTYPE definition).  The <ctype.h> header file is now included
- # globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
- # there.  Inclusion of <ctype.h> was removed from *all* the individual
- # files, and the toupper() and tolower() routines in lib/opt_utils.c
- # were dropped.
- # From: chip@chinacat.unicom.com (Chip Rosenthal)
- #
- # Revision 5.14  1993/08/03  19:17:33  syd
- # Implement new timezone handling.  New file lib/get_tz.c with new timezone
- # routines.  Added new TZMINS_USE_xxxxxx and TZNAME_USE_xxxxxx configuration
- # definitions.  Obsoleted TZNAME, ALTCHECK, and TZ_MINUTESWEST configuration
- # definitions.  Updated Configure.  Modified lib/getarpdate.c and
- # lib/strftime.c to use new timezone routines.
- #
- # From: chip@chinacat.unicom.com (Chip Rosenthal)
- #
- # Revision 5.13  1993/08/02  18:14:35  syd
- # add missing references for mcprt.c/mcprtlib.c to defs.h
- # From: Syd
- #
- # Revision 5.12  1993/06/10  03:02:46  syd
- # break_down_tolist() tried to blindly split address lists at "," which
- # caused bogus results with addreses that had a comma inside a comment
- # or quoted text, such as "user@domain (Last, First)".  This patch steps
- # through the address in quanta of RFC-822 tokens when searching for a
- # delimiting comma.  It also adds "rfc822_toklen()" to the library to
- # get that length.
- # From: chip@chinacat.unicom.com (Chip Rosenthal)
- #
- # Revision 5.11  1993/04/12  01:51:42  syd
- # Added safe_malloc(), safe_realloc(), and safe_strdup().  They
- # will be used in the new elmalias utility.
- # From: chip@chinacat.unicom.com (Chip Rosenthal)
- #
- # Revision 5.10  1993/02/03  16:21:03  syd
- # add strtokq
- # From: Syd
- #
- # Revision 5.9  1993/01/27  18:52:03  syd
- # add strftime as optional component
- #
- # Revision 5.8  1993/01/19  05:07:05  syd
- # Trim erroreous extra log entry
- # From: Syd
- #
- # Revision 5.7  1993/01/19  04:47:12  syd
- # Significant changes to provide consistent Date and From_ header
- # cracking.  Overhauled date utilities and moved into library.  Moved
- # real_from() into library.  Modified frm, newmail, and readmsg utilities
- # to use library version of real_from().  Moved get_word() from Elm
- # source into library.  Added new library routines atonum() and strfcpy().
- # Fixed trailing backslash bug in len_next().
- # From: chip@chinacat.unicom.com (Chip Rosenthal)
- #
- # Revision 5.6  1992/12/24  19:33:59  syd
- # tune dependency list further
- # From: Syd
- #
- # Revision 5.5  1992/12/24  19:30:46  syd
- # Make all object depend on config.h, so a reconfig for a new
- # arch in shared sources (or copied sources) forces a recompile
- # of all modules.
- # From: Syd
- #
- # Revision 5.4  1992/12/20  05:15:58  syd
- # Add a c)hange alias, -u and -t options to listalias to list only user
- # and only system aliases respectively.
- # From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
- #
- # Revision 5.3  1992/11/07  20:07:23  syd
- # Add header_cmp routine
- # From: Syd
- #
- # Revision 5.2  1992/10/27  01:43:40  syd
- # Move posix_signal to lib directory
- # From: tom@osf.org
- #
- # Revision 5.1  1992/10/03  22:41:36  syd
- # Initial checkin as of 2.4 Release at PL0
- #
- #
- #
  # Variables
  #	Variables established by Configure
  AR		=	ar
--- 43,50 ----
***************
*** 172,178 ****
  # DACSNET	=	-DACSNET
  
  #	Other general variables
! CFLAGS		=	$(CCFLAGS) $(OPTIMIZE) -I$(INCLDIR) $(DEBUG) $(DACSNET) 
  INCLDIR		=	../hdrs
  LINTFLAGS	=	-I$(INCLDIR)
  SHELL		=	/bin/sh
--- 81,87 ----
  # DACSNET	=	-DACSNET
  
  #	Other general variables
! CFLAGS		=	-I$(INCLDIR) $(CCFLAGS) $(OPTIMIZE) $(DEBUG) $(DACSNET) 
  INCLDIR		=	../hdrs
  LINTFLAGS	=	-I$(INCLDIR)
  SHELL		=	/bin/sh
***************
*** 188,197 ****
--- 97,111 ----
  			can_open.c	\
  			chloc.c		\
  			date_util.c	\
+ 			dispaddr.c	\
+ 			dynarray.c	\
  			errno.c		\
  			expand.c	\
  			figadrssee.c	\
+ 			forwarded.c     \
  			gcos_name.c	\
+ 			getaddr.c	\
+ 			getaddr.c	\
  			getaddrfrm.c	\
  			getarpdate.c	\
  			getfullnam.c	\
***************
*** 209,220 ****
--- 123,137 ----
  			ndbz.c		\
  			okay_addr.c	\
  			opt_utils.c	\
+ 			output.c        \
  			parsarpdat.c	\
  			parsarpwho.c	\
+ 			pmalloc.c	\
  			posixsig.c	\
  			putenv.c	\
  			realfrom.c	\
  			qstrings.c	\
+ 			read_rc.c       \
  			remfirstwd.c	\
  			reverse.c	\
  			rfc822tlen.c	\
***************
*** 225,233 ****
  			striparens.c	\
  			$(STRSRC)	\
  			$(FTIMESRC)	\
  			strtokq.c	\
  			tail_of.c	\
! 			validname.c
  
  LIB_OBJ		=	add_site.o	\
  			addrmchusr.o	\
--- 142,152 ----
  			striparens.c	\
  			$(STRSRC)	\
  			$(FTIMESRC)	\
+ 			strmcpy.c	\
  			strtokq.c	\
  			tail_of.c	\
! 			validname.c	\
! 			safeopen.c
  
  LIB_OBJ		=	add_site.o	\
  			addrmchusr.o	\
***************
*** 239,249 ****
--- 158,172 ----
  			can_open.o	\
  			chloc.o		\
  			date_util.o	\
+ 			dispaddr.o	\
+ 			dynarray.o	\
  			errno.o		\
  			expand.o	\
  			figadrssee.o	\
+ 			forwarded.o     \
  			gcos_name.o	\
  			get_tz.o	\
+ 			getaddr.o	\
  			getaddrfrm.o	\
  			getarpdate.o	\
  			getfullnam.o	\
***************
*** 260,270 ****
--- 183,196 ----
  			ndbz.o		\
  			okay_addr.o	\
  			opt_utils.o	\
+ 			output.o	\
  			parsarpdat.o	\
  			parsarpwho.o	\
+ 			pmalloc.o	\
  			posixsig.o	\
  			putenv.o	\
  			qstrings.o	\
+ 			read_rc.o	\
  			realfrom.o	\
  			remfirstwd.o	\
  			reverse.o	\
***************
*** 276,288 ****
  			striparens.o	\
  			$(STROBJ)	\
  			$(FTIMEOBJ)	\
  			strtokq.o	\
  			tail_of.o	\
! 			validname.o
  
! all:			libutil.a
  
! install:		libutil.a
  
  uninstall:		libutil.a
  
--- 202,216 ----
  			striparens.o	\
  			$(STROBJ)	\
  			$(FTIMEOBJ)	\
+ 			strmcpy.o	\
  			strtokq.o	\
  			tail_of.o	\
! 			validname.o	\
! 			safeopen.o
  
! all:			Makefile libutil.a
  
! install:		Makefile libutil.a
  
  uninstall:		libutil.a
  
***************
*** 290,295 ****
--- 218,227 ----
  			$(AR) r $@ $?
  			$(RANLIB) $@
  
+ Makefile: Makefile.SH ../config.sh
+ 	@echo "You must run 'sh Configure -S' or 'sh Configure'"
+ 	exit 1
+ 
  lint:		
  		$(LINT) $(LINTFLAGS) $(LIB_SRC) > LINT.OUT
  
***************
*** 307,317 ****
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
! $(INCLDIR)/elm.h:	$(INCLDIR)/curses.h $(INCLDIR)/defs.h
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
! $(INCLDIR)/headers.h:	$(INCLDIR)/curses.h $(INCLDIR)/defs.h
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
--- 239,249 ----
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
! $(INCLDIR)/elm.h:	$(INCLDIR)/curses.h $(INCLDIR)/defs.h $(INCLDIR)/melib.h
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
! $(INCLDIR)/headers.h:	$(INCLDIR)/curses.h $(INCLDIR)/defs.h $(INCLDIR)/elmlib.h $(INCLDIR)/me.h
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
***************
*** 318,324 ****
  #	Dependencies of C object files
  add_site.o:	$(INCLDIR)/headers.h
  addrmchusr.o:	$(INCLDIR)/headers.h
! atonum.o:	$(INCLDIR)/defs.h
  mk_aliases.o:	$(INCLDIR)/headers.h $(INCLDIR)/ndbz.h $(INCLDIR)/s_newalias.h
  aliasdb.o:	$(INCLDIR)/headers.h $(INCLDIR)/ndbz.h
  mk_lockname.o:	$(INCLDIR)/headers.h
--- 250,256 ----
  #	Dependencies of C object files
  add_site.o:	$(INCLDIR)/headers.h
  addrmchusr.o:	$(INCLDIR)/headers.h
! atonum.o:	$(INCLDIR)/defs.h $(INCLDIR)/elmlib.h
  mk_aliases.o:	$(INCLDIR)/headers.h $(INCLDIR)/ndbz.h $(INCLDIR)/s_newalias.h
  aliasdb.o:	$(INCLDIR)/headers.h $(INCLDIR)/ndbz.h
  mk_lockname.o:	$(INCLDIR)/headers.h
***************
*** 326,369 ****
  can_open.o:	$(INCLDIR)/headers.h
  chloc.o:	$(INCLDIR)/headers.h
  date_util.o:	$(INCLDIR)/headers.h
  errno.o:	$(INCLDIR)/headers.h
! expand.o:	$(INCLDIR)/defs.h $(INCLDIR)/s_elmrc.h
  figadrssee.o:	$(INCLDIR)/headers.h
  gcos_name.o:	$(INCLDIR)/headers.h
! get_tz.o:	$(INCLDIR)/defs.h
  getaddrfrm.o:	$(INCLDIR)/headers.h
  getarpdate.o:	$(INCLDIR)/headers.h
  getfullnam.o:	$(INCLDIR)/headers.h
! getword.o:	$(INCLDIR)/defs.h
  header_cmp.o:	$(INCLDIR)/headers.h
  in_list.o:	$(INCLDIR)/headers.h
  in_string.o:	$(INCLDIR)/headers.h
  istrcmp.o:	$(INCLDIR)/headers.h
! ldstate.o:	$(INCLDIR)/defs.h
! len_next.o:	../config.h
! mail_gets.o:	../config.h
  mcprt.o:	$(INCLDIR)/mcprt.h $(INCLDIR)/mcprtlib.h $(INCLDIR)/defs.h
! mcprtlib.o:	$(INCLDIR)/mcprtlib.h $(INCLDIR)/nl_types.h $(INCLDIR)/defs.h
  move_left.o:	$(INCLDIR)/headers.h
! msgcat.o:	$(INCLDIR)/msgcat.h $(INCLDIR)/nl_types.h
  ndbz.o:		$(INCLDIR)/headers.h $(INCLDIR)/ndbz.h
  okay_addr.o:	$(INCLDIR)/headers.h
  opt_utils.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_error.h
  parsarpdat.o:	$(INCLDIR)/headers.h
  parsarpwho.o:	$(INCLDIR)/headers.h
  posixsig.o:	$(INCLDIR)/headers.h
  putenv.o:	$(INCLDIR)/headers.h
  realfrom.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! qstrings.o:	../config.h
  remfirstwd.o:	$(INCLDIR)/headers.h
  reverse.o:	$(INCLDIR)/headers.h
! safemalloc.o:	$(INCLDIR)/defs.h
  shiftlower.o:	$(INCLDIR)/headers.h
  strincmp.o:	$(INCLDIR)/headers.h
  striparens.o:	$(INCLDIR)/headers.h
  strstr.o:	$(INCLDIR)/headers.h
  strtokq.o:	$(INCLDIR)/headers.h
  tail_of.o:	$(INCLDIR)/headers.h
! validname.o:	$(INCLDIR)/defs.h
  
  !NO!SUBS!
--- 258,309 ----
  can_open.o:	$(INCLDIR)/headers.h
  chloc.o:	$(INCLDIR)/headers.h
  date_util.o:	$(INCLDIR)/headers.h
+ dispaddr.o:     $(INCLDIR)/headers.h
  errno.o:	$(INCLDIR)/headers.h
! expand.o:	$(INCLDIR)/defs.h $(INCLDIR)/s_elmrc.h $(INCLDIR)/elmlib.h
  figadrssee.o:	$(INCLDIR)/headers.h
+ forwarded.o:	$(INCLDIR)/headers.h
  gcos_name.o:	$(INCLDIR)/headers.h
! get_tz.o:	$(INCLDIR)/defs.h $(INCLDIR)/elmlib.h
! getaddr.o:	$(INCLDIR)/headers.h
  getaddrfrm.o:	$(INCLDIR)/headers.h
  getarpdate.o:	$(INCLDIR)/headers.h
  getfullnam.o:	$(INCLDIR)/headers.h
! getword.o:	$(INCLDIR)/defs.h $(INCLDIR)/elmlib.h
  header_cmp.o:	$(INCLDIR)/headers.h
  in_list.o:	$(INCLDIR)/headers.h
  in_string.o:	$(INCLDIR)/headers.h
  istrcmp.o:	$(INCLDIR)/headers.h
! ldstate.o:	$(INCLDIR)/defs.h $(INCLDIR)/elmlib.h
! len_next.o:	$(INCLDIR)/defs.h $(INCLDIR)/elmlib.h
! mail_gets.o:	$(INCLDIR)/defs.h $(INCLDIR)/elmlib.h
  mcprt.o:	$(INCLDIR)/mcprt.h $(INCLDIR)/mcprtlib.h $(INCLDIR)/defs.h
! mcprtlib.o:	$(INCLDIR)/mcprtlib.h $(INCLDIR)/defs.h
  move_left.o:	$(INCLDIR)/headers.h
! msgcat.o:	$(INCLDIR)/msgcat.h $(INCLDIR)/defs.h $(INCLDIR)/elmlib.h
  ndbz.o:		$(INCLDIR)/headers.h $(INCLDIR)/ndbz.h
  okay_addr.o:	$(INCLDIR)/headers.h
  opt_utils.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_error.h
+ output.o:	$(INCLDIR)/headers.h
  parsarpdat.o:	$(INCLDIR)/headers.h
  parsarpwho.o:	$(INCLDIR)/headers.h
+ pmalloc.o:	$(INCLDIR)/defs.h $(INCLDIR)/s_elm.h
  posixsig.o:	$(INCLDIR)/headers.h
  putenv.o:	$(INCLDIR)/headers.h
+ read_rc.o:      $(INCLDIR)/headers.h $(INCLDIR)/save_opts.h $(INCLDIR)/s_elm.h
  realfrom.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! qstrings.o:	$(INCLDIR)/defs.h $(INCLDIR)/elmlib.h
  remfirstwd.o:	$(INCLDIR)/headers.h
  reverse.o:	$(INCLDIR)/headers.h
! safemalloc.o:	$(INCLDIR)/defs.h $(INCLDIR)/elmlib.h
  shiftlower.o:	$(INCLDIR)/headers.h
+ strfcpy.o:      $(INCLDIR)/defs.h $(INCLDIR)/elmlib.h
+ strmcpy.o:      $(INCLDIR)/defs.h $(INCLDIR)/elmlib.h
  strincmp.o:	$(INCLDIR)/headers.h
  striparens.o:	$(INCLDIR)/headers.h
  strstr.o:	$(INCLDIR)/headers.h
  strtokq.o:	$(INCLDIR)/headers.h
  tail_of.o:	$(INCLDIR)/headers.h
! validname.o:	$(INCLDIR)/defs.h $(INCLDIR)/elmlib.h
  
  !NO!SUBS!
Index: elm2.4.ME+.50/lib/add_site.c
*** elm2.4.25/lib/add_site.c	Sun Oct  4 01:42:21 1992
--- elm2.4.ME+.50/lib/add_site.c	Tue Nov 17 21:12:56 1998
***************
*** 1,24 ****
  
! static char rcsid[] = "@(#)$Id: add_site.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: add_site.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: add_site.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 26,33 ****
  
  #include "headers.h"
  
! add_site(buffer, site, lastsite)
! char *buffer, *site, *lastsite;
  {
  	/** add site to buffer, unless site is 'uucp' or site is
  	    the same as lastsite.   If not, set lastsite to site.
--- 18,26 ----
  
  #include "headers.h"
  
! int add_site(buffer, site, lastsite, size)
!      char *buffer, *site, *lastsite;
!      int  size;
  {
  	/** add site to buffer, unless site is 'uucp' or site is
  	    the same as lastsite.   If not, set lastsite to site.
***************
*** 41,51 ****
  	if (istrcmp(stripped, "uucp") != 0)
  	  if (strcmp(stripped, lastsite) != 0) {
  	    if (buffer[0] == '\0')
! 	      strcpy(buffer, stripped);         /* first in list! */
  	    else {
! 	      sprintf(local_buffer,"%s!%s", buffer, stripped);
! 	      strcpy(buffer, local_buffer);
  	    }
! 	    strcpy(lastsite, stripped); /* don't want THIS twice! */
  	  }
  }
--- 34,51 ----
  	if (istrcmp(stripped, "uucp") != 0)
  	  if (strcmp(stripped, lastsite) != 0) {
  	    if (buffer[0] == '\0')
! 	      strfcpy(buffer, stripped, size);         /* first in list! */
  	    else {
! 	      elm_sfprintf(local_buffer,sizeof local_buffer,
! 			   FRM("%.*s!%.*s"), 
! 			   sizeof local_buffer /2 -2, buffer, 
! 			   sizeof local_buffer /2 -2, stripped);
! 	      strfcpy(buffer, local_buffer, size);
  	    }
! 	    strfcpy(lastsite, stripped, size); /* don't want THIS twice! */
  	  }
+ 	return 0;
  }
+ 
+ 
+ 
Index: elm2.4.ME+.50/lib/addrmchusr.c
*** elm2.4.25/lib/addrmchusr.c	Sun Oct  4 01:42:21 1992
--- elm2.4.ME+.50/lib/addrmchusr.c	Tue Nov 17 21:12:55 1998
***************
*** 1,24 ****
  
! static char rcsid[] = "@(#)$Id: addrmchusr.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: addrmchusr.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: addrmchusr.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 26,38 ****
  
  #include "headers.h"
  
! int
! addr_matches_user(addr,user)
! register char *addr, *user;
  {
  	int len = strlen(user);
! 	static char c_before[] = "!:%";	/* these can appear before a username */
! 	static char c_after[] = ":%@";	/* these can appear after a username  */
  
  	do {
  	  if ( strncmp(addr,user,len) == 0 ) {
--- 18,31 ----
  
  #include "headers.h"
  
! int addr_matches_user(addr,user)
!      char *addr, *user;
  {
  	int len = strlen(user);
! 	/* these can appear before a username */
! 	static char c_before[] = "!:%";	
! 	/* these can appear after a username  */
! 	static char c_after[] = ":%@";	
  
  	do {
  	  if ( strncmp(addr,user,len) == 0 ) {
Index: elm2.4.ME+.50/lib/aliasdb.c
*** elm2.4.25/lib/aliasdb.c	Mon Sep 20 02:41:00 1993
--- elm2.4.ME+.50/lib/aliasdb.c	Tue Nov 17 21:12:55 1998
***************
*** 1,63 ****
  
! static char rcsid[] = "@(#)$Id: aliasdb.c,v 5.8 1993/09/19 23:40:48 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.8 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: aliasdb.c,v $
!  * Revision 5.8  1993/09/19  23:40:48  syd
!  * Defince SEEK_SET in one of our headers as a last resort
!  * From: Syd
!  *
!  * Revision 5.7  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.6  1993/07/20  02:59:53  syd
!  * Support aliases both on 64 bit and 32 bit machines at the same time.
!  * From: Dan Mosedale <mosedale@genome.stanford.edu>
!  *
!  * Revision 5.5  1993/06/10  03:12:10  syd
!  * Add missing rcs id lines
!  * From: Syd
!  *
!  * Revision 5.4  1993/06/10  02:58:26  syd
!  * Correct problem in fetch_alias() with alias record fixup that caused
!  * core dump on machines with pointers larger than int.  This problem
!  * was reported on comp.mail.elm by Richard Eckman and Jim Brown.  Simplify
!  * get_one_alias() by having it use fetch_alias().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.3  1993/04/21  01:40:12  syd
!  * add seekset define
!  *
!  * Revision 5.2  1993/04/12  01:53:38  syd
!  * Added fetch_alias() and next_addr_in_list() routines for use in
!  * new elmalias utility.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1992/12/20  05:14:05  syd
!  * Initial checkin
!  *
!  *
!  ******************************************************************************/
  
  /** Alias interface with dbz routines.
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: aliasdb.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** Alias interface with dbz routines.
  
***************
*** 71,77 ****
  #include "headers.h"
  #include "ndbz.h"
  
! #ifdef BSD
  #  include <sys/file.h>
  #endif
  
--- 24,30 ----
  #include "headers.h"
  #include "ndbz.h"
  
! #ifdef BSD_TYPE
  #  include <sys/file.h>
  #endif
  
***************
*** 81,89 ****
  
  static of_t			/* transformed result */
  bytemap(ino, map1, map2)
! of_t ino;
! int *map1;
! int *map2;
  {
  	union oc {
  		of_t o;
--- 34,42 ----
  
  static of_t			/* transformed result */
  bytemap(ino, map1, map2)
!      of_t ino;
!      int *map1;
!      int *map2;
  {
  	union oc {
  		of_t o;
***************
*** 99,107 ****
  	return(out.o);
  }
  
! read_one_alias(db, adr)
! DBZ *db;
! struct alias_disk_rec *adr;
  {
  /*
   *	Read an alias (name, address, etc.) from the data file
--- 52,60 ----
  	return(out.o);
  }
  
! int read_one_alias(db, adr)
!      DBZ *db;
!      struct alias_disk_rec *adr;
  {
  /*
   *	Read an alias (name, address, etc.) from the data file
***************
*** 144,151 ****
   * reached, a NULL is returned.
   */
  struct alias_rec *fetch_alias(db, alias)
! DBZ *db;
! char *alias;
  {
  	datum key, val;
  	struct alias_disk_rec adrec;
--- 97,104 ----
   * reached, a NULL is returned.
   */
  struct alias_rec *fetch_alias(db, alias)
!      DBZ *db;
!      char *alias;
  {
  	datum key, val;
  	struct alias_disk_rec adrec;
***************
*** 245,251 ****
   * Return NULL when list finished.  This routine scribbles on the list.
   */
  char *next_addr_in_list(aptr)
! char **aptr;
  {
  	register char *front, *back;
  
--- 198,204 ----
   * Return NULL when list finished.  This routine scribbles on the list.
   */
  char *next_addr_in_list(aptr)
!      char **aptr;
  {
  	register char *front, *back;
  
Index: elm2.4.ME+.50/lib/atonum.c
*** elm2.4.25/lib/atonum.c	Tue Aug  3 22:28:47 1993
--- elm2.4.ME+.50/lib/atonum.c	Tue Nov 17 21:12:56 1998
***************
*** 1,37 ****
  
! static char rcsid[] = "@(#)$Id: atonum.c,v 5.2 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
   *
!  * 			Copyright (c) 1993 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: atonum.c,v $
!  * Revision 5.2  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
   *
!  * Revision 5.1  1993/01/19  04:46:21  syd
!  * Initial Checkin
!  *
!  *
!  ******************************************************************************/
  
  #include "defs.h"
  
  /*
   * This is similar to atoi(), but it complains if the string
--- 1,18 ----
  
! static char rcsid[] = "@(#)$Id: atonum.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  * 			Copyright (c) 1993 USENET Community Trust
!  *****************************************************************************/
  
  #include "defs.h"
+ #include "elmlib.h"
  
  /*
   * This is similar to atoi(), but it complains if the string
***************
*** 39,45 ****
   * value on success, -1 on error.
   */
  int atonum(str)
! register char *str;
  {
      register int value;
  
--- 20,26 ----
   * value on success, -1 on error.
   */
  int atonum(str)
!      char *str;
  {
      register int value;
  
Index: elm2.4.ME+.50/lib/can_access.c
*** elm2.4.25/lib/can_access.c	Mon Aug 23 05:46:07 1993
--- elm2.4.ME+.50/lib/can_access.c	Tue Nov 17 21:12:55 1998
***************
*** 1,75 ****
  
! static char rcsid[] = "@(#)$Id: can_access.c,v 5.8 1993/08/23 02:46:07 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.8 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: can_access.c,v $
!  * Revision 5.8  1993/08/23  02:46:07  syd
!  * Don't declare _exit() if <unistd.h> already did it.
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.7  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.6  1993/05/14  03:52:10  syd
!  * When compiled on a POSIX host PL22 failed checking whether the file is
!  * readable and a regular file or not. There was one `!' missing in the
!  * `if (S_ISREG(mode))' test which should read `if (! S_ISREG(mode))'.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.5  1993/05/08  19:16:41  syd
!  * Remove symlink code from can_access, we dont care if its a symlink
!  * only if we can access the file pointed to by the symlink anyway and
!  * stat resolves to that file.
!  *
!  * Revision 5.4  1993/04/12  04:08:36  syd
!  * Fix if alignment
!  *
!  * Revision 5.3  1993/04/12  03:33:39  syd
!  * the posix macros to interpret the result of the stat-call.
!  * From: vogt@isa.de (Gerald Vogt)
!  *
!  * Revision 5.2  1992/12/12  01:29:26  syd
!  * Fix double inclusion of sys/types.h
!  * From: Tom Moore <tmoore@wnas.DaytonOH.NCR.COM>
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** can_access - can this user access this file using their normal uid/gid
  
  **/
  
  #include "headers.h"
  #include <sys/stat.h>
  #include <errno.h>
  
- #ifdef BSD
- # include <sys/wait.h>
- #endif
- 
  #ifndef I_UNISTD
  void _exit();
  #endif
--- 1,32 ----
  
! static char rcsid[] = "@(#)$Id: can_access.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** can_access - can this user access this file using their normal uid/gid
  
  **/
  
+ /* WHAT HELL THIS IS!
+  *
+  * access -system call uses real uid / gid anyway !!!!!
+  *
+  *                              - K E H <hurtta@ozone.FMI.FI>
+  */
+ 
  #include "headers.h"
  #include <sys/stat.h>
  #include <errno.h>
  
  #ifndef I_UNISTD
  void _exit();
  #endif
***************
*** 76,96 ****
  
  extern int errno;		/* system error number */
  
! int
! can_access(file, mode)
! char *file; 
! int   mode;
  {
  	/** returns ZERO iff user can access file or "errno" otherwise **/
  
  	int the_stat = 0, pid, w; 
  	struct stat stat_buf;
! #if defined(BSD) && !defined(WEXITSTATUS)
  	union wait status;
  #else
  	int status;
  #endif
- 	register SIGHAND_TYPE (*istat)(), (*qstat)();
  	
  #ifdef VFORK
  	if ((pid = vfork()) == 0) {
--- 33,51 ----
  
  extern int errno;		/* system error number */
  
! int can_access(file, mode)
!      char *file; 
!      int   mode;
  {
  	/** returns ZERO iff user can access file or "errno" otherwise **/
  
  	int the_stat = 0, pid, w; 
  	struct stat stat_buf;
! #if defined(BSD_TYPE) && !defined(WEXITSTATUS)
  	union wait status;
  #else
  	int status;
  #endif
  	
  #ifdef VFORK
  	if ((pid = vfork()) == 0) {
***************
*** 109,133 ****
  	  _exit(127);
  	}
  
! 	istat = signal(SIGINT, SIG_IGN);
! 	qstat = signal(SIGQUIT, SIG_IGN);
  
- 	while ((w = wait(&status)) != pid && w != -1)
- 		;
  
! #if	defined(WEXITSTATUS)
! 	/* Use POSIX macro if defined */
! 	the_stat = WEXITSTATUS(status);
! #else
! #ifdef BSD
! 	the_stat = status.w_retcode;
! #else
! 	the_stat = status >> 8;
! #endif
! #endif	/*WEXITSTATUS*/
  
- 	signal(SIGINT, istat);
- 	signal(SIGQUIT, qstat);
  	if (the_stat == 0) {
  	  if (stat(file, &stat_buf) == 0) {
  #ifndef _POSIX_SOURCE
--- 64,85 ----
  	  _exit(127);
  	}
  
! 	errno = 0;
! 	while ((w = my_wait(pid,&status)) != pid && w != -1 || 
! 	       EINTR == errno)
! 	  ;
  
  
! 	if (w == -1) {
! 	  the_stat = errno;
! 	  if (!the_stat)
! 	    the_stat = 1;
! 	} else {
! 	  int sig = convert_status(status,&the_stat);
! 	  if (sig)
! 	    the_stat = 1;
! 	}
  
  	if (the_stat == 0) {
  	  if (stat(file, &stat_buf) == 0) {
  #ifndef _POSIX_SOURCE
***************
*** 145,147 ****
--- 97,101 ----
  
  	return(the_stat);
  }
+ 
+ 
Index: elm2.4.ME+.50/lib/can_open.c
*** elm2.4.25/lib/can_open.c	Mon Aug 23 05:46:08 1993
--- elm2.4.ME+.50/lib/can_open.c	Tue Nov 17 21:12:56 1998
***************
*** 1,44 ****
  
! static char rcsid[] = "@(#)$Id: can_open.c,v 5.4 1993/08/23 02:46:07 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: can_open.c,v $
!  * Revision 5.4  1993/08/23  02:46:07  syd
!  * Don't declare _exit() if <unistd.h> already did it.
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.3  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.2  1992/12/12  01:29:26  syd
!  * Fix double inclusion of sys/types.h
!  * From: Tom Moore <tmoore@wnas.DaytonOH.NCR.COM>
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** can_open - can this user open this file using their normal uid/gid
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: can_open.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** can_open - can this user open this file using their normal uid/gid
  
***************
*** 48,57 ****
  #include <sys/stat.h>
  #include <errno.h>
  
- #ifdef BSD
- # include <sys/wait.h>
- #endif
- 
  #ifndef I_UNISTD
  void _exit();
  #endif
--- 20,25 ----
***************
*** 58,66 ****
  
  extern int errno;		/* system error number */
  
! int
! can_open(file, mode)
! char *file, *mode;
  {
  	/** Returns 0 iff user can open the file.  This is not
  	    the same as can_access - it's used for when the file might
--- 26,33 ----
  
  extern int errno;		/* system error number */
  
! int can_open(file, mode)
!      char *file, *mode;
  {
  	/** Returns 0 iff user can open the file.  This is not
  	    the same as can_access - it's used for when the file might
***************
*** 67,79 ****
  	    not exist... **/
  
  	FILE *fd;
! 	int the_stat = 0, pid, w, preexisted = 0; 
! #if defined(BSD) && !defined(WEXITSTATUS)
! 	union wait status;
! #else
! 	int status;
! #endif
! 	register SIGHAND_TYPE (*istat)(), (*qstat)();
  	
  #ifdef VFORK
  	if ((pid = vfork()) == 0) {
--- 34,41 ----
  	    not exist... **/
  
  	FILE *fd;
! 	int the_stat = 0, pid, w, preexisted = 0,sig;
! 	S__ status;
  	
  #ifdef VFORK
  	if ((pid = vfork()) == 0) {
***************
*** 83,88 ****
--- 45,61 ----
  	  setgid(groupid);
  	  setuid(userid);		/** back to normal userid **/
  	  errno = 0;
+ 	  if (mode[0] == 's' && mode[1] == 'w' && ! mode[2]) {
+ 	      int filedes = open(file, O_WRONLY | O_CREAT | O_EXCL, 0600);
+ 	      if (filedes < 0 &&
+ 		  (unlink(file) ||
+ 		   (filedes = open(file, O_WRONLY|O_CREAT|O_EXCL, 0600)) < 0))
+ 		  _exit(errno);
+ 	      else {
+ 		  close(filedes);
+ 		  _exit(0);
+ 	      }
+ 	  }
  	  if (access(file, ACCESS_EXISTS) == 0)
  	    preexisted = 1;
  	  if ((fd = fopen(file, mode)) == NULL)
***************
*** 96,119 ****
  	  _exit(127);
  	}
  
! 	istat = signal(SIGINT, SIG_IGN);
! 	qstat = signal(SIGQUIT, SIG_IGN);
! 
! 	while ((w = wait(&status)) != pid && w != -1)
! 		;
! 
! #ifdef WEXITSTATUS
! 	the_stat = WEXITSTATUS(status);
! #else
! #ifdef BSD
! 	the_stat = status.w_retcode;
! #else
! 	the_stat = status >> 8;
! #endif
! #endif /*WEXITSTATUS*/
! 	
! 	signal(SIGINT, istat);
! 	signal(SIGQUIT, qstat);
! 
  	return(the_stat);
  }
--- 69,82 ----
  	  _exit(127);
  	}
  
! 	errno = 0;
! 	while ((w = my_wait(pid,&status)) != pid && w != -1 ||
! 	       EINTR == errno)
! 	  ;
! 
! 	sig = convert_status(status,&the_stat);
! 	if (sig)
! 	  the_stat = 1;
! 	dprint(1,(debugfile,"can_open(%s,%s) = %d\n",file,mode,the_stat));
  	return(the_stat);
  }
Index: elm2.4.ME+.50/lib/chloc.c
*** elm2.4.25/lib/chloc.c	Sun Oct  4 01:42:22 1992
--- elm2.4.ME+.50/lib/chloc.c	Tue Nov 17 21:12:56 1998
***************
*** 1,24 ****
  
! static char rcsid[] = "@(#)$Id: chloc.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: chloc.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: chloc.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 26,38 ****
  
  #include "headers.h"
  
! int
! chloc(string, ch)
! char *string;
! register char ch;
  {
  	/** returns the index of ch in string, or -1 if not in string **/
! 	register char *s;
  
  	for (s = string; *s; s++)
  		if (*s == ch)
--- 18,38 ----
  
  #include "headers.h"
  
! /* Is this really needed? This does same than strchr or index, except
!  *  that return type is different.
!  *
!  *                          - K E H <hurtta@ozone.FMI.FI>
!  */
! 
! /* Argument (second) can't be char because there is both prototype and
!  * non-prototype declaration.
!  */
! int chloc(string, ch)
!      char *string;
!      int ch;
  {
  	/** returns the index of ch in string, or -1 if not in string **/
! 	char *s;
  
  	for (s = string; *s; s++)
  		if (*s == ch)
***************
*** 40,49 ****
  	return(-1);
  }
  
! int
! qchloc(string, ch)
! char *string;
! register char ch;
  {
  	/* returns the index of ch in string, or -1 if not in string
           * skips over quoted portions of the string
--- 40,48 ----
  	return(-1);
  }
  
! int qchloc(string, ch)
!      char *string;
!      int ch;
  {
  	/* returns the index of ch in string, or -1 if not in string
           * skips over quoted portions of the string
Index: elm2.4.ME+.50/lib/date_util.c
*** elm2.4.25/lib/date_util.c	Tue Aug  3 22:28:48 1993
--- elm2.4.ME+.50/lib/date_util.c	Tue Nov 17 21:12:56 1998
***************
*** 1,42 ****
  
! static char rcsid[] = "@(#)$Id: date_util.c,v 5.3 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
!  * 			Copyright (c) 1993 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: date_util.c,v $
!  * Revision 5.3  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.2  1993/01/27  20:54:24  syd
!  * There is a small bug in this routine in Chip's PL21 patch.  The code
!  * calls atonum to convert the 4 digit timezone field.  However this field
!  * is actually of the form HHMM, not a decimal number, so for example
!  * -0500 was being converted to -500 rather than the correct -300.
!  * From: Larry Philps <larryp@sco.COM>
   *
!  * Revision 5.1  1993/01/19  04:46:21  syd
!  * Initial Checkin
!  *
!  *
!  ******************************************************************************/
  
  #include "headers.h"
  
--- 1,15 ----
  
! static char rcsid[] = "@(#)$Id: date_util.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  * 			Copyright (c) 1993 USENET Community Trust
!  *****************************************************************************/
  
  #include "headers.h"
  
***************
*** 130,137 ****
  
  
  int cvt_dayname_to_daynum(str, day_p)
! char *str;
! int *day_p;
  {
      /*
       * Convert a day name to number (Sun = 1).  Only the first three
--- 103,110 ----
  
  
  int cvt_dayname_to_daynum(str, day_p)
!      char *str;
!      int *day_p;
  {
      /*
       * Convert a day name to number (Sun = 1).  Only the first three
***************
*** 153,163 ****
      return FALSE;
  }
  
- 
- 
  int cvt_monthname_to_monthnum(str, month_p)
! char *str;
! int *month_p;
  {
      /*
       * Convert a month name to number (Jan = 1).  Only the first three
--- 126,134 ----
      return FALSE;
  }
  
  int cvt_monthname_to_monthnum(str, month_p)
!      char *str;
!      int *month_p;
  {
      /*
       * Convert a month name to number (Jan = 1).  Only the first three
***************
*** 179,188 ****
      return FALSE;
  }
  
- 
  int cvt_yearstr_to_yearnum(str, year_p)
! char *str;
! int *year_p;
  {
      /*
       * Convert a year from a string to a number.  We will add the century
--- 150,158 ----
      return FALSE;
  }
  
  int cvt_yearstr_to_yearnum(str, year_p)
!      char *str;
!      int *year_p;
  {
      /*
       * Convert a year from a string to a number.  We will add the century
***************
*** 211,223 ****
      return FALSE;
  }
  
- 
  int cvt_mmddyy_to_dayofyear(month, dayofmon, year, dayofyear_p)
! int month, dayofmon, year, *dayofyear_p;
  {
      /*
!      * Convert numeric month, day of month, and year to day of year
!      * (Jan 1 = 0).  Always returns TRUE.
       */
  
      int dayofyear, i;
--- 181,192 ----
      return FALSE;
  }
  
  int cvt_mmddyy_to_dayofyear(month, dayofmon, year, dayofyear_p)
!      int month, dayofmon, year, *dayofyear_p;
  {
      /*
!      * Convert numeric month (1-12), day of month (1-31), and year (with
!      * century) to day of year (Jan 1 = 0).  Always returns TRUE.
       */
  
      int dayofyear, i;
***************
*** 229,238 ****
      return TRUE;
  }
  
! 
! int cvt_timezone_to_offset(str, mins_p)
! char *str;
! int *mins_p;
  {
      /*
       * Convert a timezone to a number of minutes *east* of gmt.  The
--- 198,207 ----
      return TRUE;
  }
  
! int cvt_timezone_to_offset(str, mins_p, size)
!      char *str;
!      int *mins_p;
!      int size;
  {
      /*
       * Convert a timezone to a number of minutes *east* of gmt.  The
***************
*** 252,258 ****
      if ((*str == '+' || *str == '-') && (tz = cvt_numtz_to_mins(str+1)) >= 0) {
  	switch (strlen(str)) {
  	case 3:					/* +NN		*/
! 	    (void) strcat(str, "00");		/*  make +NN00	*/
  	    tz *= 60;
  	    break;
  	case 5:					/* +NNNN	*/
--- 221,227 ----
      if ((*str == '+' || *str == '-') && (tz = cvt_numtz_to_mins(str+1)) >= 0) {
  	switch (strlen(str)) {
  	case 3:					/* +NN		*/
! 	    (void) strfcat(str, "00", size);		/*  make +NN00	*/
  	    tz *= 60;
  	    break;
  	case 5:					/* +NNNN	*/
***************
*** 271,276 ****
--- 240,246 ----
      if (*str == '-') {
  	tz = -1;
  	++str;
+ 	size--;
      } else {
  	tz = 1;
      }
***************
*** 294,302 ****
      return FALSE;
  }
  
- 
  int cvt_numtz_to_mins(str)
! char *str;
  {
      /*
       * Convert an HHMM string to minutes.  Check to make sure that the
--- 264,271 ----
      return FALSE;
  }
  
  int cvt_numtz_to_mins(str)
!      char *str;
  {
      /*
       * Convert an HHMM string to minutes.  Check to make sure that the
***************
*** 336,345 ****
      return -1;
  }
  
- 
  int cvt_timestr_to_hhmmss(str, hours_p, mins_p, secs_p)
! char *str;
! int *hours_p, *mins_p, *secs_p;
  {
      /*
       * Convert a HH:MM[:SS] time specification to hours, minutes, seconds.
--- 305,313 ----
      return -1;
  }
  
  int cvt_timestr_to_hhmmss(str, hours_p, mins_p, secs_p)
!      char *str;
!      int *hours_p, *mins_p, *secs_p;
  {
      /*
       * Convert a HH:MM[:SS] time specification to hours, minutes, seconds.
***************
*** 406,417 ****
      return FALSE;
  }
  
- 
  long make_gmttime(year, month, day, hours, mins, secs)
! int year, month, day, hours, mins, secs;
  {
      /*
!      * Convert date specification to seconds since epoch (1 Jan 1970 00:00).
       */
  
      long days_since_epoch, secs_since_midnight;
--- 374,385 ----
      return FALSE;
  }
  
  long make_gmttime(year, month, day, hours, mins, secs)
!      int year, month, day, hours, mins, secs;
  {
      /*
!      * Convert date specification (year with century, month 1-12, day 1-31,
!      * and HH:MM:SS) to seconds since epoch (1 Jan 1970 00:00).
       */
  
      long days_since_epoch, secs_since_midnight;
***************
*** 438,512 ****
       */
      return days_since_epoch*(24*60*60) + secs_since_midnight;
  }
- 
- 
- #ifdef _TEST /*{*/
- 
- int getitem(prompt, item)
- char *prompt, *item;
- {
- 	char buf[1024];
- 	printf("%s [%s] > ", prompt, item);
- 	fflush(stdout);
- 	if (gets(buf) == NULL)
- 		return -1;
- 	if (buf[0] != '\0')
- 		(void) strcpy(item, buf);
- 	return 0;
- }
- 
- main()
- {
- 	char dowstr[256], domstr[256], monstr[256], yrstr[256],
- 		tzstr[256], timestr[256];
- 	int dow, dom, mon, yr, tzmins, dayofyr, hrs, mins, secs;
- 	long gmttime;
- 	extern char *ctime();
- 
- 	(void) strcpy(dowstr, "Monday");
- 	(void) strcpy(domstr, "1");
- 	(void) strcpy(monstr, "January");
- 	(void) strcpy(yrstr, "1980");
- 	(void) strcpy(tzstr, "GMT");
- 	(void) strcpy(timestr, "00:00:00");
- 
- 	for (;;) {
- 		if (getitem("day of week", dowstr) != 0)
- 			break;
- 		if (getitem("month", monstr) != 0)
- 			break;
- 		if (getitem("day", domstr) != 0)
- 			break;
- 		if (getitem("year", yrstr) != 0)
- 			break;
- 		if (getitem("timezone", tzstr) != 0)
- 			break;
- 		if (getitem("time", timestr) != 0)
- 			break;
- 		if (!cvt_dayname_to_daynum(dowstr, &dow))
- 			fputs("cvt_dayname_to_daynum failed\n", stderr);
- 		if (!cvt_monthname_to_monthnum(monstr, &mon))
- 			fputs("cvt_monthname_to_monthnum failed\n", stderr);
- 		dom = atoi(domstr);
- 		if (!cvt_yearstr_to_yearnum(yrstr, &yr))
- 			fputs("cvt_yearstr_to_yearnum failed\n", stderr);
- 		if (!cvt_timezone_to_offset(tzstr, &tzmins))
- 			fputs("cvt_timezone_to_offset failed\n", stderr);
- 		if (!cvt_mmddyy_to_dayofyear(mon, dom, yr, &dayofyr))
- 			fputs("cvt_mmddyy_to_dayofyear failed\n", stderr);
- 		if (!cvt_timestr_to_hhmmss(timestr, &hrs, &mins, &secs))
- 			fputs("cvt_timestr_to_hhmmss failed\n", stderr);
- 		gmttime = make_gmttime(yr, mon, dom, hrs, mins+tzmins, secs);
- 		printf("date=%04d/%02d/%02d  time=%02d:%02d:%02d  tzmins=%d\n",
- 			yr, mon, dom, hrs, mins, secs, tzmins);
- 		printf("day-of-week=%d day-of-year=%d gmttime=%ld gmtdate=%s",
- 			dow, dayofyr, gmttime, ctime(&gmttime));
- 		putchar('\n');
- 	}
- 
- 	putchar('\n');
- 	exit(0);
- }
- 
- #endif /*}_TEST*/
  
--- 406,409 ----
Index: elm2.4.ME+.50/lib/dispaddr.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/lib/dispaddr.c	Tue Nov 17 21:14:08 1998
***************
*** 0 ****
--- 1,107 ----
+ static char rcsid[] = "@(#)$Id: dispaddr.c,v 1.3 1998/11/16 17:08:30 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *
+  *  Initially written by: Michael Elkins <elkins@aero.org>, 1995
+  *****************************************************************************/
+ 
+ #include "headers.h"
+ #include "me.h"
+ 
+ static void addr_to_str P_((char *f, int size, struct addr_item *addr));
+ static void addr_to_str(f,size,addr)
+      char *f; 
+      int size; 
+      struct addr_item *addr;
+ {
+   struct addr_item *ptr;
+ 
+   f[0] = '\0';
+   for (ptr=addr; ptr && ptr->addr; ptr++) {
+     char * t = ptr->fullname;
+     if (!t[0])
+       t = ptr->addr;
+     if (ptr == addr)
+       strfcpy(f, t, size);
+     else {
+       strfcat(f, ", ", size);
+       strfcat(f, t, size);
+     }
+   }
+ }
+ 
+ int
+ DisplayAddress (h, f, size, decoder)
+      struct header_rec *h;
+      char *f;
+      int size;
+      decode_who decoder;
+ {
+   int i = 0, using_to = 0;
+   struct addr_item *p,*ptr;
+   int okay_to = 1, okay_cc = 1;
+   
+   f[0] = '\0';
+   
+   if (!h->to ||
+       !h->to->addr ||
+       !h->to->fullname) {
+     /* No To: address, must select From: address anyway.... */
+     goto was_from;
+   }
+ 
+   for (p = h->from; p && p->addr && p->fullname; p++)
+     if (addr_matches_user (p->addr, username) ||
+ 	0 == strincmp(p->fullname, full_username,STRING))
+       break;
+ 
+   for (ptr = h->to; ptr && ptr->addr && ptr->fullname; ptr++)
+     if (!okay_address(ptr->addr, h->env_from))
+       okay_to = 0;
+ 
+   for (ptr = h->cc; ptr && ptr->addr && ptr->fullname; ptr++)
+     if (!okay_address(ptr->addr, h->env_from))
+       okay_cc = 0;
+ 
+ 
+   if (p && p->addr && p->fullname ||
+       addr_matches_user (h->env_from, username)) {
+     /* I sent this message.  Use the TO address.  
+      * (perhaps I have also receiver... hmm.)
+      */
+     f[0] = '\0';
+     addr_to_str(f,size,h->to);
+     if (f[0])
+       using_to = TRUE;
+   }
+   else if (okay_to && okay_cc) {
+ 
+     /* This message is not addressed to me. */
+ 
+     if (showto) {
+       f[0] = '\0';
+       addr_to_str(f,size,h->to);
+       if (f[0])
+ 	using_to = TRUE;
+       else
+ 	goto was_from;
+     } else 
+       goto was_from;
+       
+   }
+   else { /* This message is addressed to me (or sender of mail). */
+   was_from:
+     addr_to_str(f,size,h->from);
+     if (f[0] == '\0')
+       strfcpy (f, h->env_from, size);
+     if (f[0] == '\0' || 0 == strcmp(f,"<>"))
+       strfcpy (f, "Mailer Daemon", size);
+   }
+ 
+   return(using_to);
+ }
+ 
+ 
Index: elm2.4.ME+.50/lib/dynarray.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/lib/dynarray.c	Tue Nov 17 21:12:55 1998
***************
*** 0 ****
--- 1,52 ----
+ /* $Id: dynarray.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $
+  *
+  * Initially written by: Michael Elkins <elkins@aero.org>, 1995/06/01
+  */
+ 
+ /** routines for handling of dynamic arrays **/
+ 
+ char **
+ DynamicArray (p, record_size, max, n)
+ char **p;
+ int record_size;
+ int *max;
+ int n;
+ {
+ 	int newmax, j;
+ 	char **c;
+ 
+ 	newmax = *max + n;
+ 
+ 	if (!p)
+ 		c = (char**)safe_malloc(record_size * (n+1));
+ 	else
+ 		c = (char**)safe_realloc(p, record_size * (newmax+1));
+ 
+ 	if (!c)
+ 		return(0);
+ 
+ 	/* We reserver in above (newmax+1) elements --
+ 	 * element c[newmax] must be always NULL so DestroyDynamicArray
+ 	 * works.
+ 	 */
+ 	for (j = *max ; j <= newmax ; j++)
+ 		c[j] = 0;
+ 
+ 	*max = newmax;
+ 
+ 	return(c);
+ }
+ 
+ void
+ DestroyDynamicArray (p)
+ char **p;
+ {
+ 	char **b;
+ 
+ 	if (!p)
+ 		return;
+ 	b = p;
+ 	while (*b)
+ 		free(*b++);
+ 	free(p);
+ }
Index: elm2.4.ME+.50/lib/errno.c
*** elm2.4.25/lib/errno.c	Thu Sep  1 22:42:07 1994
--- elm2.4.ME+.50/lib/errno.c	Tue Nov 17 21:12:55 1998
***************
*** 1,36 ****
  
! static char rcsid[] = "@(#)$Id: errno.c,v 5.4 1994/09/01 19:42:07 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: errno.c,v $
!  * Revision 5.4  1994/09/01  19:42:07  syd
!  * Add extern declaration of strerror to avoid compiler warning.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.3  1993/04/21  01:58:20  syd
!  * change to detect strerror routine
!  * From: Syd
!  *
!  * Revision 5.2  1993/04/21  01:25:11  syd
!  * Use strerror() with ANSI compilers.
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This routine maps error numbers to error names and error messages.
      These are all directly ripped out of the include file errno.h, and
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: errno.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This routine maps error numbers to error names and error messages.
      These are all directly ripped out of the include file errno.h, and
***************
*** 42,47 ****
--- 22,28 ----
  **/
  
  #include "headers.h"
+ #include "me.h"
  
  #ifndef STRERROR
  #ifdef ERRLST
***************
*** 92,98 ****
  #endif /* STRERROR */
  
  char *error_description(errnumber)
! int errnumber;
  {
  #ifdef STRERROR
  
--- 73,79 ----
  #endif /* STRERROR */
  
  char *error_description(errnumber)
!      int errnumber;
  {
  #ifdef STRERROR
  
***************
*** 105,111 ****
  	static char buffer[50];
  
  	if (errnumber < 0 || errnumber >= sys_nerr)  {
! 	  sprintf(buffer,"ERR-UNKNOWN (%d)", errnumber);
  	  return(buffer);
  	}
  
--- 86,93 ----
  	static char buffer[50];
  
  	if (errnumber < 0 || errnumber >= sys_nerr)  {
! 	  elm_sfprintf(buffer,sizeof buffer,
! 		       FRM("ERR-UNKNOWN (%d)"), errnumber);
  	  return(buffer);
  	}
  
Index: elm2.4.ME+.50/lib/expand.c
*** elm2.4.25/lib/expand.c	Mon Sep 20 02:38:55 1993
--- elm2.4.ME+.50/lib/expand.c	Tue Nov 17 21:12:55 1998
***************
*** 1,38 ****
  
! static char rcsid[] = "@(#)$Id: expand.c,v 5.4 1993/09/19 23:38:55 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: expand.c,v $
!  * Revision 5.4  1993/09/19  23:38:55  syd
!  * expand() didn't read the global rc file if the user elmrc didn't exist or
!  * didn't have an entry for maildir.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.3  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.2  1992/12/07  04:48:15  syd
!  * add include of types.h to get time_t define
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This is a library routine for the various utilities that allows
      users to have the standard 'Elm' folder directory nomenclature
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: expand.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This is a library routine for the various utilities that allows
      users to have the standard 'Elm' folder directory nomenclature
***************
*** 44,182 ****
  #include <stdio.h>
  #include "defs.h"
  #include "s_elmrc.h"
  
  extern nl_catd elm_msg_cat;	/* message catalog	    */
  
! char *expand_define();
! 
! static char*
! expand_maildir(rcfile, filename, buffer)
! FILE *rcfile;
! char *filename;
! char *buffer;
  {
! 	char *home = NULL, *bufptr;
! 	int  foundit = 0;
  
! 	bufptr = (char *) buffer;		/* same address */
! 	
! 	while (! foundit && mail_gets(buffer, SLEN, rcfile) != 0) {
! 	  if (strncmp(buffer, "maildir", 7) == 0 ||
! 	      strncmp(buffer, "folders", 7) == 0) {
! 	    while (*bufptr != '=' && *bufptr) 
! 	      bufptr++;
! 	    bufptr++;			/* skip the equals sign */
! 	    while (whitespace(*bufptr) && *bufptr)
! 	      bufptr++; 
! 	    home = bufptr;		/* remember this address */
! 
! 	    while (! whitespace(*bufptr) && *bufptr != '\n')
! 	      bufptr++;
! 
! 	    *bufptr = '\0';		/* remove trailing space */
! 	    foundit++;
! 	  }
! 	}
! 
! 	return home;
! }
! 
! int
! expand(filename)
! char *filename;
! {
! 	/** Expand the filename since the first character is a meta-
! 	    character that should expand to the "maildir" variable
! 	    in the users ".elmrc" file or in the global rc file...
! 
! 	    Note: this is a brute force way of getting the entry out 
! 	    of the .elmrc file, and isn't recommended for the faint 
! 	    of heart!
! 	**/
! 
! 	FILE *rcfile;
! 	char  buffer[SLEN], *home, *expanded_dir;
! 
! 	if ((home = getenv("HOME")) == NULL) {
! 	  printf(catgets(elm_msg_cat, ElmrcSet, ElmrcExpandHome,
! 	     "Can't expand environment variable $HOME to find .elmrc file!\n"));
! 	  return(NO);
! 	}
! 
! 	sprintf(buffer, "%s/%s", home, elmrcfile);
! 
! 	home = NULL;
! 	if ((rcfile = fopen(buffer, "r")) != NULL) {
! 	  home = expand_maildir(rcfile, filename, buffer);
! 	  fclose(rcfile);
! 	}
! 
! 	if (home == NULL) { /* elmrc didn't exist or maildir wasn't in it */
! 	  if ((rcfile = fopen(system_rc_file, "r")) != NULL) {
! 	    home = expand_maildir(rcfile, filename, buffer);
! 	    fclose(rcfile);
! 	  }
! 	}
! 
! 	if (home == NULL) {
! 	  /* Didn't find it, use default */
! 	  sprintf(buffer, "~/%s", default_folders);
! 	  home = buffer;
! 	}
! 
! 	/** Home now points to the string containing your maildir, with
! 	    no leading or trailing white space...
! 	**/
! 
! 	if ((expanded_dir = expand_define(home)) == NULL)
! 		return(NO);
! 
! 	sprintf(buffer, "%s%s%s", expanded_dir, 
! 		(expanded_dir[strlen(expanded_dir)-1] == '/' ||
! 		filename[0] == '/') ? "" : "/", (char *) filename+1);
! 
! 	strcpy(filename, buffer);
! 	return(YES);
  }
  
- char *expand_define(maildir)
- char *maildir;
- {
- 	/** This routine expands any occurances of "~" or "$var" in
- 	    the users definition of their maildir directory out of
- 	    their .elmrc file.
- 
- 	    Again, another routine not for the weak of heart or staunch
- 	    of will!
- 	**/
- 
- 	static char buffer[SLEN];	/* static buffer AIEE!! */
- 	char   name[SLEN],		/* dynamic buffer!! (?) */
- 	       *nameptr,	       /*  pointer to name??     */
- 	       *value;		      /* char pointer for munging */
- 
- 	if (*maildir == '~') 
- 	  sprintf(buffer, "%s%s", getenv("HOME"), ++maildir);
- 	else if (*maildir == '$') { 	/* shell variable */
- 
- 	  /** break it into a single word - the variable name **/
- 
- 	  strcpy(name, (char *) maildir + 1);	/* hurl the '$' */
- 	  nameptr = (char *) name;
- 	  while (*nameptr != '/' && *nameptr) nameptr++;
- 	  *nameptr = '\0';	/* null terminate */
- 	  
- 	  /** got word "name" for expansion **/
- 
- 	  if ((value = getenv(name)) == NULL) {
- 	    printf(catgets(elm_msg_cat, ElmrcSet, ElmrcExpandShell,
- 		    "Couldn't expand shell variable $%s in .elmrc!\n"),
- 		    name);
- 	    return(NULL);
- 	  }
- 	  sprintf(buffer, "%s%s", value, maildir + strlen(name) + 1);
- 	}
- 	else strcpy(buffer, maildir);
- 
- 	return( ( char *) buffer);
- }
--- 22,45 ----
  #include <stdio.h>
  #include "defs.h"
  #include "s_elmrc.h"
+ #include "elmlib.h"
  
  extern nl_catd elm_msg_cat;	/* message catalog	    */
  
! int expand(filename, size)
!      char *filename;
!      int size;
  {
!   char  buffer[SLEN];
  
!   strfcpy(buffer,folders, sizeof buffer);
!   if (folders[0] && folders[strlen(folders)-1] != '/' &&
!       filename[0] != '/')
!     strfcat(buffer, "/", sizeof buffer);
!   
!   strfcat(buffer,filename+1, sizeof buffer);
!   
!   strfcpy(filename, buffer, size);
!   return(YES);
  }
  
Index: elm2.4.ME+.50/lib/figadrssee.c
*** elm2.4.25/lib/figadrssee.c	Sat Jun 12 08:33:39 1993
--- elm2.4.ME+.50/lib/figadrssee.c	Tue Nov 17 21:12:56 1998
***************
*** 1,33 ****
  
! static char rcsid[] = "@(#)$Id: figadrssee.c,v 5.3 1993/06/12 05:33:32 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: figadrssee.c,v $
!  * Revision 5.3  1993/06/12  05:33:32  syd
!  * Remove useless auto
!  * From: Syd
!  *
!  * Revision 5.2  1993/02/03  16:25:45  syd
!  * Adresses with double quoted strings that contains comma was parsed
!  * wrongly by break_down_tolist() and figure_out_addressee().
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: figadrssee.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 35,43 ****
  
  #include "headers.h"
  
! figure_out_addressee(buffer, mail_to)
! char *buffer;
! char *mail_to;
  {
  	/** This routine steps through all the addresses in the "To:"
  	    list, initially setting it to the first entry (if mail_to
--- 18,27 ----
  
  #include "headers.h"
  
! void figure_out_addressee(buffer, mail_to, size)
!      char *buffer;
!      char *mail_to;
!      int size;
  {
  	/** This routine steps through all the addresses in the "To:"
  	    list, initially setting it to the first entry (if mail_to
***************
*** 55,76 ****
  	while ((address = strtokq(bufptr, ",\t\n\r", 1)) != NULL) {
  
  	  if (! okay_address(address, "don't match me!")) {
! 	    strcpy(mail_to, username);	/* it's to YOU! */
  	    return;
  	  }
  	  else if (strlen(mail_to) == 0) {	/* it's SOMEthing! */
  	
! 	    /** this next bit is kinda gory, but allows us to use the
! 		existing routines to parse the address - by pretending
! 		it's a From: line and going from there...
! 		Ah well - you get what you pay for, right?
! 	    **/
! 
! 	      if (strlen(address) > (sizeof mybuf) - 7)	/* ensure it ain't */
! 		address[(sizeof mybuf)-7] = '\0';	/*  too long mon!  */
! 
! 	      sprintf(mybuf, "From: %s", address);
! 	      parse_arpa_who(mybuf, mail_to, TRUE);
  	  }
  
  	  bufptr = (char *) NULL;	/* set to null */
--- 39,52 ----
  	while ((address = strtokq(bufptr, ",\t\n\r", 1)) != NULL) {
  
  	  if (! okay_address(address, "don't match me!")) {
! 	    strfcpy(mail_to, username, size);	/* it's to YOU! */
  	    return;
  	  }
  	  else if (strlen(mail_to) == 0) {	/* it's SOMEthing! */
  	
! 	      parse_arpa_who(address, mail_to, 
! 			     decode_who_none,
! 			     size);
  	  }
  
  	  bufptr = (char *) NULL;	/* set to null */
***************
*** 78,80 ****
--- 54,59 ----
  
  	return;
  }
+ 
+ 
+ 
Index: elm2.4.ME+.50/lib/gcos_name.c
*** elm2.4.25/lib/gcos_name.c	Tue Aug  3 22:28:49 1993
--- elm2.4.ME+.50/lib/gcos_name.c	Tue Nov 17 21:12:56 1998
***************
*** 1,39 ****
! static char rcsid[] = "@(#)$Id: gcos_name.c,v 5.3 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: gcos_name.c,v $
!  * Revision 5.3  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.2  1993/01/20  03:02:19  syd
!  * Move string declarations to defs.h
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,15 ----
! static char rcsid[] = "@(#)$Id: gcos_name.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 41,49 ****
  
  #include "headers.h"
  
! char *
! gcos_name(gcos_field, logname)
! char *logname, *gcos_field;
  {
      /** Return the full name found in a passwd file gcos field **/
  
--- 17,24 ----
  
  #include "headers.h"
  
! char * gcos_name(gcos_field, logname)
!      char *logname, *gcos_field;
  {
      /** Return the full name found in a passwd file gcos field **/
  
Index: elm2.4.ME+.50/lib/get_tz.c
*** elm2.4.25/lib/get_tz.c	Mon May 30 19:53:43 1994
--- elm2.4.ME+.50/lib/get_tz.c	Tue Nov 17 21:12:56 1998
***************
*** 1,61 ****
  
! static char rcsid[] = "@(#)$Id: get_tz.c,v 5.4 1994/05/30 16:53:35 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
!  * 			Copyright (c) 1992, 1993 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: get_tz.c,v $
!  * Revision 5.4  1994/05/30  16:53:35  syd
!  * back out revision, uses local defs.h
!  *
!  * Revision 5.3  1994/05/30  16:46:07  syd
!  * I had to add a region of conditional compilation around "defs.h"
!  * to make Configure work correctly with the TZNAME_USE_xxxx stuff.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.2  1994/03/11  20:55:23  syd
!  * Replaced the get_tz_mins() routine in lib/get_tz.c with a portable
!  * version that requires no configuration.  Rewrote the test case in
!  * lib/get_tz.c, and also wrote in support to simplify configuration
!  * tests.  Dropped TZMINS_USE_XXXX configuration parameter.  Simplified
!  * timezone determination in Configure.  The new get_tz_mins() introduces
!  * two side effects.  First it steps on the static data returned by
!  * localtime().  Second, it uses a routine in lib/date_util.c, which
!  * requires debug initializations.  Rewrote get_arpa_date() to work around
!  * the first issue.  Rather than doing the same for lib/strftime.c, just
!  * removed the timezone stuff with a conditional compile.  Elm does not
!  * use it.  Added debugging initializations to util/fastmail.c.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
   *
!  * Revision 5.1  1993/08/10  18:56:53  syd
!  * Initial Checkin
!  *
!  *
!  ******************************************************************************/
  
  #include "defs.h"
! 
! #ifdef I_TIME
! #  include <time.h>
! #endif
! #ifdef I_SYSTIME
! #  include <sys/time.h>
! #endif
! 
! #ifndef	_POSIX_SOURCE
! extern struct tm *localtime();
! extern struct tm *gmtime();
! extern time_t	  time();
! #endif
! 
  
  #ifdef _CONFIGURE
  /*
--- 1,18 ----
  
! static char rcsid[] = "@(#)$Id: get_tz.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  * 			Copyright (c) 1992, 1993 USENET Community Trust
!  *****************************************************************************/
  
  #include "defs.h"
! #include "elmlib.h"
  
  #ifdef _CONFIGURE
  /*
***************
*** 96,106 ****
  	time(&tval);
  
  	tm = localtime(&tval);
! 	t1 = make_gmttime(tm->tm_year, tm->tm_mon, tm->tm_mday,
  		tm->tm_hour, tm->tm_min, tm->tm_sec);
  
  	tm = gmtime(&tval);
! 	t2 = make_gmttime(tm->tm_year, tm->tm_mon, tm->tm_mday,
  		tm->tm_hour, tm->tm_min, tm->tm_sec);
  
  	return (int) ((t2-t1)/60);
--- 53,63 ----
  	time(&tval);
  
  	tm = localtime(&tval);
! 	t1 = make_gmttime(1900+tm->tm_year, 1+tm->tm_mon, tm->tm_mday,
  		tm->tm_hour, tm->tm_min, tm->tm_sec);
  
  	tm = gmtime(&tval);
! 	t2 = make_gmttime(1900+tm->tm_year, 1+tm->tm_mon, tm->tm_mday,
  		tm->tm_hour, tm->tm_min, tm->tm_sec);
  
  	return (int) ((t2-t1)/60);
***************
*** 129,135 ****
   */
  
  char *get_tz_name(tm)
! struct tm *tm;
  {
  
  	if (tm == 0) {
--- 86,92 ----
   */
  
  char *get_tz_name(tm)
!      struct tm *tm;
  {
  
  	if (tm == 0) {
Index: elm2.4.ME+.50/lib/getaddrfrm.c
*** elm2.4.25/lib/getaddrfrm.c	Tue Aug  3 22:28:49 1993
--- elm2.4.ME+.50/lib/getaddrfrm.c	Tue Nov 17 21:12:55 1998
***************
*** 1,45 ****
  
! static char rcsid[] = "@(#)$Id: getaddrfrm.c,v 5.4 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: getaddrfrm.c,v $
!  * Revision 5.4  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.3  1993/05/16  20:55:52  syd
!  * Fix bug where text following "<" within double-quote delimited comment
!  * is taken as an address.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.2  1992/11/07  20:05:52  syd
!  * change to use header_cmp to allow for linear white space around the colon
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: getaddrfrm.c,v 1.2 1998/10/20 19:57:46 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 47,107 ****
  
  #include "headers.h"
  
! #ifdef USE_EMBEDDED_ADDRESSES
! 
! get_address_from(line, buffer)
! char *line, *buffer;
  {
! 	/** This routine extracts the address from either a 'From:' line
! 	    or a 'Reply-To:' line.  The strategy is as follows:  if the
! 	    line contains a '<', then the stuff enclosed is returned.
! 	    Otherwise we go through the line and strip out comments
! 	    and return that.  White space will be elided from the result.
  	**/
  
!     register char *s;
!     register int l;
  
!     /**  Skip start of line over prefix, e.g. "From:".  **/
!     if ((s = index(line, ':')) != NULL)
! 	line = s + 1;
! 
!     /*
!      * If there is a '<' then copy from it to '>' into the buffer.  We
!      * used to search with an "index()", but we need to handle RFC-822
!      * conventions (e.g. "<" within a double-quote comment) correctly.
!      */
!     for (s = line ; *s != '\0' && *s != '<' ; s += len_next_part(s))
! 	;
!     if (*s == '<') {
! 	++s;
! 	while (*s != '\0' && *s != '>') {
! 	    if ((l = len_next_part(s)) == 1 && isspace(*s)) {
! 		++s; /* elide embedded whitespace */
! 	    } else {
! 		while (--l >= 0)
! 		    *buffer++ = *s++;
! 	    }
! 	}
! 	*buffer = '\0';
! 	return;
!     }
  
!     /**  Otherwise, strip comments and get address with whitespace elided.  **/
!     s = strip_parens(line);
!     while (*s != '\0') {
! 	l = len_next_part(s);
! 	if (l == 1) {
! 	  if ( !isspace(*s) )
! 	    *buffer++ = *s;
! 	  s++;
! 	} else {
! 	  while (--l >= 0)
! 	    *buffer++ = *s++;
! 	}
      }
-     *buffer = '\0';
  
  }
  
! #endif
--- 18,63 ----
  
  #include "headers.h"
  
! void get_address_from(line, buffer, size)
!      char *line, *buffer;
!      int size;
  {
! 	/** This routine extracts the address from a 'From:' line
  	**/
  
!   struct addr_item * list;
  
!   dprint(12,(debugfile,
! 	     "get_address_from: line=%.100s, size=%d\n",
! 	     line,size));
! 
!   no_ret(line);		/* blow away '\n' char! */
! 
!   list = break_down_address(line,decode_who_none);
! 
!   buffer[0]='\0';
! 
!   if (list) {
!     struct addr_item * ptr;
  
!     for (ptr=list; ptr->addr; ptr++) {
!       char *t = ptr->addr;
!       if (ptr == list)
! 	strfcpy(buffer, t, size);
!       else {
! 	strfcat(buffer, ", ", size);
! 	strfcat(buffer, t, size);
!       }
      }
  
+   } 
+ 
+   free_addr_items(list);
+ 
+   dprint(12,(debugfile,
+ 	     "get_address_from: buffer=%.100s\n",
+ 	     buffer));
  }
  
! 
! 
Index: elm2.4.ME+.50/lib/getarpdate.c
*** elm2.4.25/lib/getarpdate.c	Fri Mar 11 22:55:24 1994
--- elm2.4.ME+.50/lib/getarpdate.c	Tue Nov 17 21:12:56 1998
***************
*** 1,91 ****
! static char rcsid[] = "@(#)$Id: getarpdate.c,v 5.10 1994/03/11 20:55:23 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.10 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: getarpdate.c,v $
!  * Revision 5.10  1994/03/11  20:55:23  syd
!  * Replaced the get_tz_mins() routine in lib/get_tz.c with a portable
!  * version that requires no configuration.  Rewrote the test case in
!  * lib/get_tz.c, and also wrote in support to simplify configuration
!  * tests.  Dropped TZMINS_USE_XXXX configuration parameter.  Simplified
!  * timezone determination in Configure.  The new get_tz_mins() introduces
!  * two side effects.  First it steps on the static data returned by
!  * localtime().  Second, it uses a routine in lib/date_util.c, which
!  * requires debug initializations.  Rewrote get_arpa_date() to work around
!  * the first issue.  Rather than doing the same for lib/strftime.c, just
!  * removed the timezone stuff with a conditional compile.  Elm does not
!  * use it.  Added debugging initializations to util/fastmail.c.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.9  1993/08/03  19:17:33  syd
!  * Implement new timezone handling.  New file lib/get_tz.c with new timezone
!  * routines.  Added new TZMINS_USE_xxxxxx and TZNAME_USE_xxxxxx configuration
!  * definitions.  Obsoleted TZNAME, ALTCHECK, and TZ_MINUTESWEST configuration
!  * definitions.  Updated Configure.  Modified lib/getarpdate.c and
!  * lib/strftime.c to use new timezone routines.
!  *
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.8  1993/05/08  19:22:46  syd
!  * On the DEC Alpha, OSF/1 the following change made things happy.
!  * From: dave@opus.csd.uwm.edu (Dave Rasmussen)
!  *
!  * Revision 5.7  1993/04/21  01:45:39  syd
!  * Try and get getarpdate to work on AIX
!  * From: "William F. Pemberton" <wfp5p@holmes.acc.virginia.edu>
!  *
!  * Revision 5.6  1993/04/16  03:42:38  syd
!  * As per "William F. Pemberton" <wfp5p@holmes.acc.virginia.edu>
!  * IBMs have the date already adjusted for dst in the min decode
!  * From: Syd
!  *
!  * Revision 5.5  1992/12/12  01:29:26  syd
!  * Fix double inclusion of sys/types.h
!  * From: Tom Moore <tmoore@wnas.DaytonOH.NCR.COM>
!  *
!  * Revision 5.4  1992/11/15  02:18:15  syd
!  * Change most of the rest of the BSDs to TZNAME
!  * From: Syd
!  *
!  * Revision 5.3  1992/11/15  02:10:58  syd
!  * change tzname ifdef from ndefBSD to ifdef TZNAME on its own
!  * configure variable
!  * From: Syd
!  *
!  * Revision 5.2  1992/11/07  19:27:30  syd
!  * Symbol change for AIX370
!  * From: uri@watson.ibm.com
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  #include "headers.h"
  
- #ifdef I_TIME
- #  include <time.h>
- #endif
- #ifdef I_SYSTIME
- #  include <sys/time.h>
- #endif
- 
- #ifndef	_POSIX_SOURCE
- extern struct tm *localtime();
- extern time_t	  time();
- #endif
- 
  static char *arpa_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
  		  "Fri", "Sat", "" };
  
--- 1,18 ----
! static char rcsid[] = "@(#)$Id: getarpdate.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  #include "headers.h"
  
  static char *arpa_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
  		  "Fri", "Sat", "" };
  
***************
*** 95,102 ****
  extern int get_tz_mins();
  extern char *get_tz_name();
  
! char *
! get_arpa_date()
  {
  	/** returns an ARPA standard date.  The format for the date
  	    according to DARPA document RFC-822 is exemplified by;
--- 22,28 ----
  extern int get_tz_mins();
  extern char *get_tz_name();
  
! char * get_arpa_date()
  {
  	/** returns an ARPA standard date.  The format for the date
  	    according to DARPA document RFC-822 is exemplified by;
***************
*** 103,108 ****
--- 29,39 ----
  
  	       	      Mon, 12 Aug 85 6:29:08 MST
  
+ 
+ 	    Actually generates following kind result:
+                       
+                       Mon, 12 Aug 1985 6:29:0 +0400 (MST)
+ 
  	**/
  
  	static char buffer[SLEN];	/* static character buffer       */
***************
*** 119,126 ****
  	(void) time(&curr_time);
  	curr_tm = *localtime(&curr_time);
  
! 	if ((year = curr_tm.tm_year) < 100)
! 		year += 1900;
  
  	if ((tzmin = -get_tz_mins()) >= 0) {
  		tzsign = '+';
--- 50,56 ----
  	(void) time(&curr_time);
  	curr_tm = *localtime(&curr_time);
  
! 	year = curr_tm.tm_year + 1900;
  
  	if ((tzmin = -get_tz_mins()) >= 0) {
  		tzsign = '+';
***************
*** 129,139 ****
  		tzmin = -tzmin;
  	}
  
! 	sprintf(buffer, "%s, %d %s %d %02d:%02d:%02d %c%02d%02d (%s)",
! 	  arpa_dayname[curr_tm.tm_wday],
! 	  curr_tm.tm_mday, arpa_monname[curr_tm.tm_mon], year,
! 	  curr_tm.tm_hour, curr_tm.tm_min, curr_tm.tm_sec,
! 	  tzsign, tzmin / 60, tzmin % 60, get_tz_name(&curr_tm));
  	
  	return buffer;
  }
--- 59,70 ----
  		tzmin = -tzmin;
  	}
  
! 	elm_sfprintf(buffer, sizeof buffer,
! 		     FRM("%s, %d %s %d %02d:%02d:%02d %c%02d%02d (%s)"),
! 		     arpa_dayname[curr_tm.tm_wday],
! 		     curr_tm.tm_mday, arpa_monname[curr_tm.tm_mon], year,
! 		     curr_tm.tm_hour, curr_tm.tm_min, curr_tm.tm_sec,
! 		     tzsign, tzmin / 60, tzmin % 60, get_tz_name(&curr_tm));
  	
  	return buffer;
  }
Index: elm2.4.ME+.50/lib/getfullnam.c
*** elm2.4.25/lib/getfullnam.c	Sun Oct  4 01:42:24 1992
--- elm2.4.ME+.50/lib/getfullnam.c	Tue Nov 17 21:12:56 1998
***************
*** 1,24 ****
  
! static char rcsid[] = "@(#)$Id: getfullnam.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: getfullnam.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: getfullnam.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 33,41 ****
  
  char *gcos_name();
  
! char *
! get_full_name(logname)
! char *logname;
  {
  	/* return a pointer to the full user name for the passed logname
  	 * or NULL if cannot be found
--- 25,32 ----
  
  char *gcos_name();
  
! char * get_full_name(logname)
!      char *logname;
  {
  	/* return a pointer to the full user name for the passed logname
  	 * or NULL if cannot be found
***************
*** 53,61 ****
  	if((pass = getpwnam(logname)) == NULL)
  	  return(NULL);
  #ifdef PASSNAMES	/* get full_username from gcos field */
! 	strcpy(fullname, gcos_name(pass->pw_gecos, logname));
  #else			/* get full_username from ~/.fullname file */
! 	sprintf(fullnamefile, "%s/.fullname", pass->pw_dir);
  
  	if(can_access(fullnamefile, READ_ACCESS) != 0)
  	  return(NULL);		/* fullname file not accessible to user */
--- 44,54 ----
  	if((pass = getpwnam(logname)) == NULL)
  	  return(NULL);
  #ifdef PASSNAMES	/* get full_username from gcos field */
! 	strfcpy(fullname, gcos_name(pass->pw_gecos, logname),
! 		sizeof fullname);
  #else			/* get full_username from ~/.fullname file */
! 	elm_sfprintf(fullnamefile, sizeof fullnamefile,
! 		     FRM("%s/.fullname"), pass->pw_dir);
  
  	if(can_access(fullnamefile, READ_ACCESS) != 0)
  	  return(NULL);		/* fullname file not accessible to user */
Index: elm2.4.ME+.50/lib/getword.c
*** elm2.4.25/lib/getword.c	Tue Aug  3 22:28:50 1993
--- elm2.4.ME+.50/lib/getword.c	Tue Nov 17 21:12:56 1998
***************
*** 1,44 ****
  
! static char rcsid[] = "@(#)$Id: getword.c,v 5.2 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
   *
!  * 			Copyright (c) 1993 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: getword.c,v $
!  * Revision 5.2  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
   *
!  * Revision 5.1  1993/01/19  04:46:21  syd
!  * Initial Checkin
!  *
!  *
!  ******************************************************************************/
  
  #include <stdio.h>
  #include "defs.h"
  
  int get_word(buffer, start, word, wordlen)
! char *buffer;
! int start;
! char *word;
! int wordlen;
  {
      /*
       * Extracts the next white-space delimited word from the "buffer"
--- 1,25 ----
  
! static char rcsid[] = "@(#)$Id: getword.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  * 			Copyright (c) 1993 USENET Community Trust
!  *****************************************************************************/
  
  #include <stdio.h>
  #include "defs.h"
+ #include "elmlib.h"
  
  int get_word(buffer, start, word, wordlen)
!      const char *buffer;
!      int start;
!      char *word;
!      int wordlen;
  {
      /*
       * Extracts the next white-space delimited word from the "buffer"
***************
*** 51,58 ****
       * in the buffer then -1 is returned.
       */
  
!     register int len;
!     register char *p;
  
      for (p = buffer+start ; isspace(*p) ; ++p)
  	;
--- 32,39 ----
       * in the buffer then -1 is returned.
       */
  
!     int len;
!     const char *p;
  
      for (p = buffer+start ; isspace(*p) ; ++p)
  	;
Index: elm2.4.ME+.50/lib/header_cmp.c
*** elm2.4.25/lib/header_cmp.c	Tue Aug  3 22:28:50 1993
--- elm2.4.ME+.50/lib/header_cmp.c	Tue Nov 17 21:12:56 1998
***************
*** 1,38 ****
! static char rcsid[] = "@(#)$Id: header_cmp.c,v 5.3 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: header_cmp.c,v $
!  * Revision 5.3  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.2  1992/11/07  20:59:49  syd
!  * fix typo
!  *
!  * Revision 5.1  1992/11/07  20:16:29  syd
!  * Initial Checkin
!  *
!  *
!  ******************************************************************************/
  
  /** 
  	compare a header, ignoring case and allowing linear white space
--- 1,15 ----
! static char rcsid[] = "@(#)$Id: header_cmp.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  	compare a header, ignoring case and allowing linear white space
***************
*** 45,54 ****
  
  #include "headers.h"
  
! 
! char *
! header_cmp(header, prefix, suffix)
! register char *header, *prefix, *suffix;
  {
  	int len;
  
--- 22,29 ----
  
  #include "headers.h"
  
! char * header_cmp(header, prefix, suffix)
!      char *header, *prefix, *suffix;
  {
  	int len;
  
Index: elm2.4.ME+.50/lib/in_list.c
*** elm2.4.25/lib/in_list.c	Sun Oct  4 01:42:24 1992
--- elm2.4.ME+.50/lib/in_list.c	Tue Nov 17 21:12:56 1998
***************
*** 1,23 ****
! static char rcsid[] = "@(#)$Id: in_list.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: in_list.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,15 ----
! static char rcsid[] = "@(#)$Id: in_list.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 25,35 ****
  
  #include "headers.h"
  
! 
! int
! in_list(list, target)
! char *list, *target;
! 
  {
  	/* Returns TRUE iff target is an item in the list - case ignored.
  	 * If target is simple (an atom of an address) match must be exact.
--- 17,29 ----
  
  #include "headers.h"
  
! /* in_list should use quoted -variants (strtokq, ...)
!  *                            - K E H <hurtta@ozone.FMI.FI>
!  */
! 
! int in_list(list, target)
!      char *list;
!      const char *target;
  {
  	/* Returns TRUE iff target is an item in the list - case ignored.
  	 * If target is simple (an atom of an address) match must be exact.
***************
*** 59,71 ****
  				lower_list[VERY_LONG_STRING],
  				lower_target[SLEN];
  
! 	rest_of_list = strcpy(lower_list, shift_lower(list));
! 	strcpy(lower_target, shift_lower(target));
  	while((next_item = strtok(rest_of_list, ", \t\n")) != NULL) {
  	    /* see if target matches the whole item */
  	    if(strcmp(next_item, lower_target) == 0)
  		return(TRUE);
  
  	    if(strpbrk(lower_target,"!@%:") != NULL) {
  
  	      /* Target is complex */
--- 53,71 ----
  				lower_list[VERY_LONG_STRING],
  				lower_target[SLEN];
  
! 	rest_of_list = strfcpy(lower_list, shift_lower(list),
! 			       sizeof lower_list);
! 	strfcpy(lower_target, shift_lower(target), 
! 		sizeof lower_target);
  	while((next_item = strtok(rest_of_list, ", \t\n")) != NULL) {
  	    /* see if target matches the whole item */
  	    if(strcmp(next_item, lower_target) == 0)
  		return(TRUE);
  
+             if(index(lower_target,'*')!=0){
+ 	      if (globmatch(next_item,lower_target))
+                 return(TRUE);
+             } else
  	    if(strpbrk(lower_target,"!@%:") != NULL) {
  
  	      /* Target is complex */
***************
*** 85,88 ****
--- 85,123 ----
  	    rest_of_list = NULL;
  	}
  	return(FALSE);
+ }
+ 
+ int globmatch (string, pat)
+      char *string, *pat;
+ {
+   char buf[1024];
+   int i=0,j=0,k,offset=0;
+   
+   for (;;) {
+     k=0;
+     while (pat[j]!='*' && pat[j]!='\0') {
+       buf[k++]=pat[j++];
+     }
+     buf[k]='\0';
+ 
+     /* check everything up to the first '*' */
+     if (strncmp(string+offset,buf,i=strlen(buf))!=0)
+       return(FALSE);
+ 
+     /* if we have run out of pattern, then the string matches... */
+     if (pat[j]=='\0' || pat[j+1]=='\0')
+       return(TRUE);
+ 
+     ++j; /* advance to the next 'real' character in the pattern */
+ 
+     /* ffwd to the next real char that matches */
+     while (string[i] != pat[j]) {
+       /* if we still have pattern, but no string, then it doesn't match */
+       if (string[i]=='\0')
+ 	return(FALSE);
+       i++;
+     }
+     offset+=i;
+   }
+   /* not reached */
  }
Index: elm2.4.ME+.50/lib/in_string.c
*** elm2.4.25/lib/in_string.c	Sun Oct  4 01:42:24 1992
--- elm2.4.ME+.50/lib/in_string.c	Tue Nov 17 21:12:56 1998
***************
*** 1,23 ****
! static char rcsid[] = "@(#)$Id: in_string.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: in_string.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,15 ----
! static char rcsid[] = "@(#)$Id: in_string.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 25,34 ****
  
  #include "headers.h"
  
  
! int 
! in_string(buffer, pattern)
! char *buffer, *pattern;
  {
  	/** Returns TRUE iff pattern occurs IN IT'S ENTIRETY in buffer. **/ 
  
--- 17,28 ----
  
  #include "headers.h"
  
+ /* Is that needed? This is almost same as strstr (except return type).
+  *                                     - K E H <hurtta@ozone.FMI.FI> 
+  */
  
! int in_string(buffer, pattern)
!      char *buffer, *pattern;
  {
  	/** Returns TRUE iff pattern occurs IN IT'S ENTIRETY in buffer. **/ 
  
Index: elm2.4.ME+.50/lib/istrcmp.c
*** elm2.4.25/lib/istrcmp.c	Tue Aug  3 22:28:51 1993
--- elm2.4.ME+.50/lib/istrcmp.c	Tue Nov 17 21:12:55 1998
***************
*** 1,35 ****
! static char rcsid[] = "@(#)$Id: istrcmp.c,v 5.2 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: istrcmp.c,v $
!  * Revision 5.2  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,15 ----
! static char rcsid[] = "@(#)$Id: istrcmp.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 36,45 ****
  **/
  
  #include "headers.h"
  
! int
! istrcmp(s1,s2)
! register char *s1, *s2;
  {
  	/* case insensitive comparison */
  	register int d;
--- 16,26 ----
  **/
  
  #include "headers.h"
+ #include "me.h"
  
! /* This is same than strcasecmp.   - K E H <hurtta@ozone.FMI.FI>  */
! int istrcmp(s1,s2)
!      register char *s1, *s2;
  {
  	/* case insensitive comparison */
  	register int d;
Index: elm2.4.ME+.50/lib/ldstate.c
*** elm2.4.25/lib/ldstate.c	Fri Mar 11 23:01:35 1994
--- elm2.4.ME+.50/lib/ldstate.c	Tue Nov 17 21:12:55 1998
***************
*** 1,50 ****
  
! static char rcsid[] = "@(#)$Id: ldstate.c,v 5.7 1994/03/11 21:01:35 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.7 $   $State: Exp $
   *
!  *			Copyright (c) 1992 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: ldstate.c,v $
!  * Revision 5.7  1994/03/11  21:01:35  syd
!  * detect whether atol() is a macro
!  * From: Mitch DSouza <m.dsouza@mrc-applied-psychology.cambridge.ac.uk>
!  *
!  * Revision 5.6  1993/08/23  02:46:51  syd
!  * Test ANSI_C, not __STDC__ (which is not set on e.g. AIX).
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.5  1993/02/03  15:26:13  syd
!  * protect atol in ifndef __STDC__ as some make it a macro, and its in stdlib.h
!  *
!  * Revision 5.4  1992/12/24  21:48:07  syd
!  * Make fgetline elm_fgetline, as BSD 4.4 now has such a routine, and
!  * it causes compile problems.
!  * From: Syd
   *
!  * Revision 5.3  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.2  1992/12/07  04:51:34  syd
!  * add sys/types.h for time_t declaration
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
- #include <stdio.h>
  #include "defs.h"
  
  /*
   * Retrieve Elm folder state.
--- 1,18 ----
  
! static char rcsid[] = "@(#)$Id: ldstate.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  *			Copyright (c) 1992 USENET Community Trust
!  *****************************************************************************/
  
  #include "defs.h"
+ #include "elmlib.h"
  
  /*
   * Retrieve Elm folder state.
***************
*** 70,78 ****
  #endif
  
  static char *elm_fgetline(buf, buflen, fp)
! char *buf;
! unsigned buflen;
! FILE *fp;
  {
      if (fgets(buf, buflen, fp) == NULL)
  	return (char *) NULL;
--- 38,46 ----
  #endif
  
  static char *elm_fgetline(buf, buflen, fp)
!      char *buf;
!      unsigned buflen;
!      FILE *fp;
  {
      if (fgets(buf, buflen, fp) == NULL)
  	return (char *) NULL;
***************
*** 80,91 ****
      return buf;
  }
  
- 
  int load_folder_state_file(fst)
! struct folder_state *fst;
  {
      char buf[SLEN], *state_fname;
!     int status, i;
      FILE *fp;
  
      /* clear out the folder status record */
--- 48,58 ----
      return buf;
  }
  
  int load_folder_state_file(fst)
!      struct folder_state *fst;
  {
      char buf[SLEN], *state_fname;
!     int status, i, Len;
      FILE *fp;
  
      /* clear out the folder status record */
***************
*** 107,115 ****
      /* retrieve pathname of the folder */
      if (elm_fgetline(buf, sizeof(buf), fp) == NULL || buf[0] != 'F')
  	goto done;
!     if ((fst->folder_name = malloc(strlen(buf+1) + 1)) == NULL)
  	goto done;
!     (void) strcpy(fst->folder_name, buf+1);
  
      /* retrieve number of messages in the folder */
      if (elm_fgetline(buf, sizeof(buf), fp) == NULL || buf[0] != 'N')
--- 74,83 ----
      /* retrieve pathname of the folder */
      if (elm_fgetline(buf, sizeof(buf), fp) == NULL || buf[0] != 'F')
  	goto done;
!     Len = strlen(buf+1) + 1;
!     if ((fst->folder_name = malloc(Len)) == NULL)
  	goto done;
!     strfcpy(fst->folder_name, buf+1, Len);
  
      /* retrieve number of messages in the folder */
      if (elm_fgetline(buf, sizeof(buf), fp) == NULL || buf[0] != 'N')
Index: elm2.4.ME+.50/lib/len_next.c
*** elm2.4.25/lib/len_next.c	Tue Aug  3 22:28:51 1993
--- elm2.4.ME+.50/lib/len_next.c	Tue Nov 17 21:12:55 1998
***************
*** 1,52 ****
  
! static char rcsid[] = "@(#)$Id: len_next.c,v 5.5 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.5 $   $State: Exp $
   *
!  * 			Copyright (c) 1992 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: len_next.c,v $
!  * Revision 5.5  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.4  1993/04/12  01:27:30  syd
!  * len_next_part() was botching quote-delimited strings.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.3  1993/01/19  05:07:05  syd
!  * Trim erroreous extra log entry
!  * From: Syd
   *
!  * Revision 5.2  1993/01/19  04:47:12  syd
!  * Significant changes to provide consistent Date and From_ header
!  * cracking.  Overhauled date utilities and moved into library.  Moved
!  * real_from() into library.  Modified frm, newmail, and readmsg utilities
!  * to use library version of real_from().  Moved get_word() from Elm
!  * source into library.  Added new library routines atonum() and strfcpy().
!  * Fixed trailing backslash bug in len_next().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** get the length of the next part of the address/data field
  
--- 1,15 ----
  
! static char rcsid[] = "@(#)$Id: len_next.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  * 			Copyright (c) 1992 USENET Community Trust
!  *****************************************************************************/
  
  /** get the length of the next part of the address/data field
  
***************
*** 66,77 ****
  
  **/
  
  
! int
! len_next_part(str)
! register char *str;
  {
! 	register char *s;
  
  	switch (*str) {
  
--- 29,41 ----
  
  **/
  
+ #include "defs.h"
+ #include "elmlib.h"
  
! int len_next_part(str)
!      const char *str;
  {
! 	const char *s;
  
  	switch (*str) {
  
Index: elm2.4.ME+.50/lib/mail_gets.c
*** elm2.4.25/lib/mail_gets.c	Tue Aug  3 22:28:52 1993
--- elm2.4.ME+.50/lib/mail_gets.c	Tue Nov 17 21:12:56 1998
***************
*** 1,51 ****
  
! static char rcsid[] = "@(#)$Id: mail_gets.c,v 5.4 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
!  * 			Copyright (c) 1992 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: mail_gets.c,v $
!  * Revision 5.4  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.3  1993/08/03  19:05:33  syd
!  * When STDC is used on Convex the feof() function is defined as
!  * a true library routine in the header files and moreover the
!  * library routine also leaks royally. It returns always 1!!
!  * So we have to use a macro. Convex naturally does not provide
!  * you with one though if you are using a STDC compiler. So we
!  * have to include one.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
   *
!  * Revision 5.2  1993/04/12  01:13:30  syd
!  * In some cases, with certain editors, the user can create an
!  * aliases.text file in which the last line is terminated with an EOF but
!  * doesn't have a '\n'.  Currently, elm with complain that the line is
!  * too long.
!  * From: "William F. Pemberton" <wfp5p@holmes.acc.virginia.edu>
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** get a line from the mail file, but be tolerant of nulls
  
--- 1,15 ----
  
! static char rcsid[] = "@(#)$Id: mail_gets.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  * 			Copyright (c) 1992 USENET Community Trust
!  *****************************************************************************/
  
  /** get a line from the mail file, but be tolerant of nulls
  
***************
*** 55,66 ****
  
  #include <stdio.h>
  #include "defs.h"
  
! int
! mail_gets(buffer, size, mailfile)
! char *buffer;
! int size;
! FILE *mailfile;
  {
  	register int line_bytes = 0, ch;
  	register char *c = buffer;
--- 19,30 ----
  
  #include <stdio.h>
  #include "defs.h"
+ #include "elmlib.h"
  
! int mail_gets(buffer, size, mailfile)
!      char *buffer;
!      int size;
!      FILE *mailfile;
  {
  	register int line_bytes = 0, ch;
  	register char *c = buffer;
Index: elm2.4.ME+.50/lib/mcprt.c
*** elm2.4.25/lib/mcprt.c	Thu Jun 30 19:44:02 1994
--- elm2.4.ME+.50/lib/mcprt.c	Tue Nov 17 21:12:55 1998
***************
*** 1,5 ****
  
! static char rcsid[] = "@(#)$Id: mcprt.c,v 5.6 1994/06/30 16:43:14 syd Exp $";
  
  /***********************************************************
  Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
--- 1,5 ----
  
! static char rcsid[] = "@(#)$Id: mcprt.c,v 1.1.1.1 1998/10/15 15:36:39 hurtta Exp $";
  
  /***********************************************************
  Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
***************
*** 49,55 ****
  #include "mcprt.h"
  #include "mcprtlib.h"
  
! #ifdef	ANSI_C
  int	MCprintf(char *fmt, ...)
  #else
  int	MCprintf(fmt, va_alist)
--- 49,55 ----
  #include "mcprt.h"
  #include "mcprtlib.h"
  
! #if	ANSI_C 
  int	MCprintf(char *fmt, ...)
  #else
  int	MCprintf(fmt, va_alist)
***************
*** 71,77 ****
      return len;
  }
  
! #ifdef	ANSI_C
  int	MCfprintf(FILE *fptr, char *fmt, ...)
  #else
  int	MCfprintf(fptr, fmt, va_alist)
--- 71,77 ----
      return len;
  }
  
! #if	ANSI_C 
  int	MCfprintf(FILE *fptr, char *fmt, ...)
  #else
  int	MCfprintf(fptr, fmt, va_alist)
***************
*** 94,100 ****
      return len;
  }
  
! #ifdef	ANSI_C
  int	MCsprintf(char *cptr, char *fmt, ...)
  #else
  int	MCsprintf(cptr, fmt, va_alist)
--- 94,100 ----
      return len;
  }
  
! #if	ANSI_C 
  int	MCsprintf(char *cptr, char *fmt, ...)
  #else
  int	MCsprintf(cptr, fmt, va_alist)
***************
*** 120,122 ****
--- 120,123 ----
  
      return len;
  }
+ 
Index: elm2.4.ME+.50/lib/mcprtlib.c
*** elm2.4.25/lib/mcprtlib.c	Mon Aug 23 05:54:32 1993
--- elm2.4.ME+.50/lib/mcprtlib.c	Tue Nov 17 21:12:55 1998
***************
*** 1,5 ****
  
! static char rcsid[] = "@(#)$Id: mcprtlib.c,v 5.5 1993/08/23 02:54:31 syd Exp $";
  
  /***********************************************************
  Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
--- 1,5 ----
  
! static char rcsid[] = "@(#)$Id: mcprtlib.c,v 1.1.1.1 1998/10/15 15:36:40 hurtta Exp $";
  
  /***********************************************************
  Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
***************
*** 53,59 ****
--- 53,61 ----
  
  #include "mcprtlib.h"
  #ifdef CATGETS
+ /*
  # include "nl_types.h"
+ */
  # ifndef MCMakeId
  #  define MCMakeId(s,m)	(unsigned long)(((unsigned short)s<<(sizeof(short)*8))\
  					|(unsigned short)m)
Index: elm2.4.ME+.50/lib/mk_aliases.c
*** elm2.4.25/lib/mk_aliases.c	Tue Aug  3 22:28:53 1993
--- elm2.4.ME+.50/lib/mk_aliases.c	Tue Nov 17 21:12:56 1998
***************
*** 1,118 ****
  
! static char rcsid[] = "@(#)$Id: mk_aliases.c,v 5.15 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.15 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: mk_aliases.c,v $
!  * Revision 5.15  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.14  1993/07/20  02:59:53  syd
!  * Support aliases both on 64 bit and 32 bit machines at the same time.
!  * From: Dan Mosedale <mosedale@genome.stanford.edu>
!  *
!  * Revision 5.13  1993/07/20  01:45:56  syd
!  * When resyncing aliases from elm, and there was aliases to delete,
!  * the alias.pag file could be corrupted since file_offset wasn't set to zero.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.12  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.11  1993/04/12  01:06:42  syd
!  * If I have two aliases of the same name the duplicate is caught *but
!  * still written to the data file*!!!
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.10  1993/02/08  01:11:49  syd
!  * Make alias names consistently handled as lower case.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.9  1993/01/20  03:37:16  syd
!  * Nits and typos in the NLS messages and corresponding default messages.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.8  1993/01/19  04:52:19  syd
!  * 	add c)hange alias command to alias helpfile
!  * 	if a deleted alias is changed, undelete it.  Also added the 'N'
!  * flag to changed aliases to help remind the user.  Documented it.
!  * Note:  if they mark the alias for deletion AFTER making the change it
!  * WILL be deleted. (and marked accordingly)
!  * 	modified alias mode title string to indicate when a resync was
!  * needed.
!  * 	allow editing alias file when none exist.
!  * 	Now aliases are check for illegal characters (and WS) and
!  * addresses are check for illegal WS when they are being entered.  If
!  * anything illegal is found and message is printed and they keep entering
!  * the item until they get it right.
!  * 	I fixed a couple of places where int should be long to match
!  * the declared type of alias_rec.length
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.7  1993/01/05  17:52:14  syd
!  * Add missing quote check to whitespace error check loop
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.6  1992/12/11  02:10:24  syd
!  * Make Elm complain about spaces that are not after commas in
!  * alias and address lists
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.5  1992/12/11  02:09:06  syd
!  * Fix where the user creates a first new alias, then deletes it, the
!  * alias stays on screen, but the file really will be empty if it was the
!  * last alias, so the retry to delete gives 'cannot open ...file' messages
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.4  1992/11/15  01:15:28  syd
!  * The alias message_count isn't set to zero if the last alias has
!  * been deleted from the alias table. As no aliases are reread from
!  * the aliases database the message_count is left as it was before.
!  *
!  * Fixed that the function do_newalias() sometimes returns without freeing
!  * the buffer allocated before. The patch adds these free calls.
!  *
!  * When you erroneously type a number in your folder elm asks you for
!  * a new current message number. But now if you erase this one number
!  * and leave the string empty elm will set the new current message to
!  * the second message on our sun4! The patch adds a check for an empty
!  * string and returns the current number if no number was entered.
!  * From: vogt@isa.de (Gerald Vogt)
!  *
!  * Revision 5.3  1992/11/07  16:32:14  syd
!  * comments should be allowed anywhere in the alias file.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.2  1992/10/11  01:46:35  syd
!  * change dbm name to dbz to avoid conflicts with partial call
!  * ins from shared librarys, and from mixing code with yp code.
!  * From: Syd via prompt from Jess Anderson
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** Install a new set of aliases for the 'Elm' mailer. 
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: mk_aliases.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** Install a new set of aliases for the 'Elm' mailer. 
  
***************
*** 133,139 ****
  #include "s_newalias.h"
  #include "ndbz.h"
  
! #ifdef BSD
  #  include <sys/file.h>
  #endif
  
--- 31,37 ----
  #include "s_newalias.h"
  #include "ndbz.h"
  
! #ifdef BSD_TYPE
  #  include <sys/file.h>
  #endif
  
***************
*** 157,164 ****
  
  int
  get_alias(file, fromelm)
! FILE *file;
! int fromelm;
  {
  	/* load buffer with the next complete alias from the file.
  	   (this can include reading in multiple lines and appending
--- 55,62 ----
  
  int
  get_alias(file, fromelm)
!      FILE *file;
!      int fromelm;
  {
  	/* load buffer with the next complete alias from the file.
  	   (this can include reading in multiple lines and appending
***************
*** 179,185 ****
  
  	if (get_line(file, mybuffer, TRUE, fromelm) == -1) 
  	    return(-1);
! 	strcpy(buffer, mybuffer);
  	len = strlen(buffer);
  
  	/** now read in the rest (if there is any!) **/
--- 77,83 ----
  
  	if (get_line(file, mybuffer, TRUE, fromelm) == -1) 
  	    return(-1);
! 	strfcpy(buffer, mybuffer, buffer_size);
  	len = strlen(buffer);
  
  	/** now read in the rest (if there is any!) **/
***************
*** 197,214 ****
  	      *--s = ' ';
  	      len += strlen(s);
  	      if (len >= buffer_size) {
! 	          sprintf(msg_buff, catgets(elm_msg_cat,
! 	                  NewaliasSet, NewaliasLineToLong,
! 	              "Line + continuations exceeds maximum length of %ld:"),
! 	              buffer_size);
! 	          error(msg_buff);
! 	          if (fromelm && sleepmsg > 0)
! 	              sleep(sleepmsg);
! 	          sprintf(msg_buff, "%.40s", buffer);
! 	          error(msg_buff);
! 		  err_flag++;
  	      } else
! 		  strcat(buffer, s);
  	  }
  	} while (! done);
  	
--- 95,110 ----
  	      *--s = ' ';
  	      len += strlen(s);
  	      if (len >= buffer_size) {
! 		lib_error(CATGETS(elm_msg_cat,
! 				  NewaliasSet, NewaliasLineToLong,
! 				  "Line + continuations exceeds maximum length of %ld:"),
! 			  buffer_size);
! 		if (fromelm && sleepmsg > 0)
! 		  sleep(sleepmsg);
! 		lib_error(FRM("%.40s"), buffer);
! 		err_flag++;
  	      } else
! 		strfcat(buffer, s, buffer_size);
  	  }
  	} while (! done);
  	
***************
*** 215,225 ****
  	return(0);	/* no sweat! */
  }
  
! int
! get_line(file, buffer, first_line, fromelm)
! FILE *file;
! char *buffer;
! int  first_line, fromelm;
  {
  /*
   *	Read line from file.
--- 111,120 ----
  	return(0);	/* no sweat! */
  }
  
! int get_line(file, buffer, first_line, fromelm)
!      FILE *file;
!      char *buffer;
!      int  first_line, fromelm;
  {
  /*
   *	Read line from file.
***************
*** 247,264 ****
  	  if (len > 0) {
  	    if (buffer[len - 1] != '\n') {
  	      if (fromelm) {
! 		  error(catgets(elm_msg_cat, NewaliasSet, NewaliasSplitShort,
! 		  "Line too long, split using continuation line format:"));
  		  if (sleepmsg > 0)
  			  sleep(sleepmsg);
- 		  sprintf(msg_buff, "%.40s", buffer);
  	      }
  	      else {
! 		  sprintf(msg_buff, catgets(elm_msg_cat,
! 			  NewaliasSet, NewaliasSplit,
! 		  "Line too long, split using continuation line format (starting line\nwith whitespace):\n%.40s\n"), buffer);
  	      }
- 	      error(msg_buff);
  	      err_flag++;
  	      return(-1);
  	    }
--- 142,159 ----
  	  if (len > 0) {
  	    if (buffer[len - 1] != '\n') {
  	      if (fromelm) {
! 		  lib_error(CATGETS(elm_msg_cat, NewaliasSet, 
! 				    NewaliasSplitShort,
! 				    "Line too long, split using continuation line format:"));
  		  if (sleepmsg > 0)
  			  sleep(sleepmsg);
  	      }
  	      else {
! 		  lib_error(CATGETS(elm_msg_cat,
! 				    NewaliasSet, NewaliasSplit,
! 				    "Line too long, split using continuation line format (starting line\nwith whitespace):\n%.40s\n"), 
! 			    buffer);
  	      }
  	      err_flag++;
  	      return(-1);
  	    }
***************
*** 276,284 ****
  	return(0);
  }
  
! void
! de_escape(the_string)
! char *the_string;
  {
  	register char *s, *out;
  
--- 171,178 ----
  	return(0);
  }
  
! void de_escape(the_string)
!      char *the_string;
  {
  	register char *s, *out;
  
***************
*** 293,302 ****
  	return;
  }
  
! int
! add_to_hash_table(word, offset)
! char *word;
! int32  offset;
  {
  	datum	key, value, ovalue;
  	int32	off;
--- 187,195 ----
  	return;
  }
  
! int add_to_hash_table(word, offset)
!      char *word;
!      int32  offset;
  {
  	datum	key, value, ovalue;
  	int32	off;
***************
*** 309,327 ****
  
  	ovalue = dbz_fetch(aliases_hash, key);
  	if (ovalue.dptr != NULL) {
! 	    sprintf(msg_buff, catgets(elm_msg_cat,
! 	            NewaliasSet, NewaliasDupAlias,
! 		    "** Duplicate alias '%s' in file.  Multiples ignored."),
! 		word);
! 	    error(msg_buff);
  	    return(-1);
  	}
  
  	if (dbz_store(aliases_hash, key, value) < 0) {
! 	    sprintf(msg_buff, catgets(elm_msg_cat,
! 	            NewaliasSet, NewaliasErrWrite,
! 		    "** Error writing alias '%s'."), word);
! 	    error(msg_buff);
  	    err_flag++;
  	    return(-1);
  	}
--- 202,218 ----
  
  	ovalue = dbz_fetch(aliases_hash, key);
  	if (ovalue.dptr != NULL) {
! 	    lib_error(CATGETS(elm_msg_cat,
! 			      NewaliasSet, NewaliasDupAlias,
! 			      "** Duplicate alias '%s' in file.  Multiples ignored."),
! 		      word);
  	    return(-1);
  	}
  
  	if (dbz_store(aliases_hash, key, value) < 0) {
! 	    lib_error(CATGETS(elm_msg_cat,
! 			      NewaliasSet, NewaliasErrWrite,
! 			      "** Error writing alias '%s'."), word);
  	    err_flag++;
  	    return(-1);
  	}
***************
*** 333,345 ****
  
  }
  
! void
! add_to_table(data, aliases, lastn, firstn, comment, addresses)
! FILE *data;
! register char *aliases, *lastn, *firstn, *comment, *addresses;
  {
  	struct alias_disk_rec	alias;
! 	register char	*s;
  /*
   *	crack the information into an alias_rec structure, then add the entry
   *	each alias at a time to the dbz file.
--- 224,235 ----
  
  }
  
! void add_to_table(data, aliases, lastn, firstn, comment, addresses)
!      FILE *data;
!      char *aliases, *lastn, *firstn, *comment, *addresses;
  {
  	struct alias_disk_rec	alias;
! 	char	*s;
  /*
   *	crack the information into an alias_rec structure, then add the entry
   *	each alias at a time to the dbz file.
***************
*** 402,410 ****
  
  }	
  
! int
! check_alias(aliases)
! char *aliases;
  {
  /*
   *	Check and make sure this is a legal alias.
--- 292,299 ----
  
  }	
  
! int check_alias(aliases)
!      char *aliases;
  {
  /*
   *	Check and make sure this is a legal alias.
***************
*** 434,444 ****
   *	up and doesn't display well at all.
   */
  	if (badws_flg) {
! 	    sprintf(msg_buff, catgets(elm_msg_cat,
! 	        NewaliasSet, NewaliasAliasWSNotAllowed,
! 	        "Error - whitespace in alias '%.30s' is not allowed."),
! 	        aliases);
! 	    error(msg_buff);
  	    return(-1);
  	}
  
--- 323,332 ----
   *	up and doesn't display well at all.
   */
  	if (badws_flg) {
! 	    lib_error(CATGETS(elm_msg_cat,
! 			      NewaliasSet, NewaliasAliasWSNotAllowed,
! 			      "Error - whitespace in alias '%.30s' is not allowed."),
! 		      aliases);
  	    return(-1);
  	}
  
***************
*** 447,465 ****
   */
  	for (s = aliases; *s != '\0' && (ok_alias_char(*s)||*s==','); ++s ) ;
  	if ( *s != '\0' ) {
! 	    MCsprintf(msg_buff, catgets(elm_msg_cat,
! 	            NewaliasSet, NewaliasCharNotSupported,
! 		    "Error - character '%c' in alias '%s' is not supported."),
  	        *s, aliases);
- 	    error(msg_buff);
  	    return(-1);
  	}
  	return(0);
  }
  
! int
! check_address(addresses)
! char *addresses;
  {
  
  	register char *s, *out;
--- 335,351 ----
   */
  	for (s = aliases; *s != '\0' && (ok_alias_char(*s)||*s==','); ++s ) ;
  	if ( *s != '\0' ) {
! 	   lib_error(CATGETS(elm_msg_cat,
! 			     NewaliasSet, NewaliasCharNotSupported,
! 			     "Error - character '%c' in alias '%s' is not supported."),
  	        *s, aliases);
  	    return(-1);
  	}
  	return(0);
  }
  
! int check_address(addresses)
!      char *addresses;
  {
  
  	register char *s, *out;
***************
*** 492,510 ****
   *	up and doesn't display well at all.
   */
  	if (badws_flg) {
! 	    sprintf(msg_buff, catgets(elm_msg_cat,
! 	        NewaliasSet, NewaliasAddressWSNotAllowed,
! 	        "Error - whitespace in address '%.30s' is not allowed."),
  	        addresses);
- 	    error(msg_buff);
  	    return(-1);
  	}
  	return(0);
  }
  
! void
! put_alias(data)
! FILE *data;
  {
  /*
   *	parse the buffer into aliases, names, comments and addresses
--- 378,394 ----
   *	up and doesn't display well at all.
   */
  	if (badws_flg) {
! 	    lib_error(CATGETS(elm_msg_cat,
! 			      NewaliasSet, NewaliasAddressWSNotAllowed,
! 			      "Error - whitespace in address '%.30s' is not allowed."),
  	        addresses);
  	    return(-1);
  	}
  	return(0);
  }
  
! void put_alias(data)
!      FILE *data;
  {
  /*
   *	parse the buffer into aliases, names, comments and addresses
***************
*** 519,529 ****
   */
  	aliases = buffer;
  	if ((s = index(buffer, '=')) == NULL) {
! 	    sprintf(msg_buff, catgets(elm_msg_cat,
! 	            NewaliasSet, NewaliasNoFieldSep,
! 	            "Error - alias \"%.40s\" missing '=' field separator."),
  	        aliases);
- 	    error(msg_buff);
  	    err_flag++;
  	    return;
  	}
--- 403,412 ----
   */
  	aliases = buffer;
  	if ((s = index(buffer, '=')) == NULL) {
! 	    lib_error(CATGETS(elm_msg_cat,
! 			      NewaliasSet, NewaliasNoFieldSep,
! 			      "Error - alias \"%.40s\" missing '=' field separator."),
  	        aliases);
  	    err_flag++;
  	    return;
  	}
***************
*** 563,573 ****
  	}
  
  	if (*s != '=') {
! 	    sprintf(msg_buff, catgets(elm_msg_cat,
! 	            NewaliasSet, NewaliasNoFieldSep,
! 		    "Error - alias \"%.40s\" missing '=' field separator."),
! 		aliases);
! 	    error(msg_buff);
  	    err_flag++;
  	    return;
  	}
--- 446,455 ----
  	}
  
  	if (*s != '=') {
! 	    lib_error(CATGETS(elm_msg_cat,
! 			      NewaliasSet, NewaliasNoFieldSep,
! 			      "Error - alias \"%.40s\" missing '=' field separator."),
! 		      aliases);
  	    err_flag++;
  	    return;
  	}
***************
*** 670,679 ****
  	add_to_table(data, aliases, lastn, firstn, comment, addresses);
  }
  
! int
! do_newalias(inputname, dataname, fromelm, textwarn)
! char *inputname, *dataname;
! int fromelm, textwarn;
  {
  	FILE *in, *data;
  
--- 552,562 ----
  	add_to_table(data, aliases, lastn, firstn, comment, addresses);
  }
  
! static void delete_alias_files P_((char *, int)); /* Prototype */
! 
! int do_newalias(inputname, dataname, fromelm, textwarn)
!      char *inputname, *dataname;
!      int fromelm, textwarn;
  {
  	FILE *in, *data;
  
***************
*** 699,731 ****
  	if ((in = fopen(inputname,"r")) == NULL) {
  	    if ( textwarn )
  	    {
! 	        sprintf(msg_buff, catgets(elm_msg_cat,
! 	            NewaliasSet, NewaliasNoOpenIn,
! 	            "Couldn't open %s for input!"), inputname);
  	    }
  	    else {
  	        *msg_buff = '\0';
  	    }
- 	    error(msg_buff);
  	    free(buffer);
  	    return(-1);
  	}
  
  	if ((aliases_hash = dbz_fresh(dataname, 4999, 0, 0)) == NULL) {
! 	    MCsprintf(msg_buff, catgets(elm_msg_cat,
! 	            NewaliasSet, NewaliasNoOpendbz,
! 		    "Couldn't open %s.pag or %s.dir for output!"),
! 	        dataname, dataname);
! 	    error(msg_buff);
  	    free(buffer);
  	    return(-1);
  	}
  
  	if ((data = fopen(dataname, "w")) == NULL) {
! 	    sprintf(msg_buff, catgets(elm_msg_cat,
! 	            NewaliasSet, NewaliasNoOpenOut,
! 	            "Couldn't open %s for output!"), dataname);
! 	    error(msg_buff);
  	    free(buffer);
  	    return(-1);
  	}
--- 582,612 ----
  	if ((in = fopen(inputname,"r")) == NULL) {
  	    if ( textwarn )
  	    {
! 	       lib_error(CATGETS(elm_msg_cat,
! 				 NewaliasSet, NewaliasNoOpenIn,
! 				 "Couldn't open %s for input!"), 
! 			 inputname);
  	    }
  	    else {
  	        *msg_buff = '\0';
  	    }
  	    free(buffer);
  	    return(-1);
  	}
  
  	if ((aliases_hash = dbz_fresh(dataname, 4999, 0, 0)) == NULL) {
! 	    lib_error(CATGETS(elm_msg_cat,
! 			      NewaliasSet, NewaliasNoOpendbz,
! 			      "Couldn't open %s.pag or %s.dir for output!"),
! 		      dataname, dataname);
  	    free(buffer);
  	    return(-1);
  	}
  
  	if ((data = fopen(dataname, "w")) == NULL) {
! 	    lib_error(CATGETS(elm_msg_cat,
! 			      NewaliasSet, NewaliasNoOpenOut,
! 			      "Couldn't open %s for output!"), dataname);
  	    free(buffer);
  	    return(-1);
  	}
***************
*** 763,771 ****
  	/*NOTREACHED*/
  }
  
! delete_alias_files(dataname, fromelm)
! char *dataname;
! int fromelm;
  {
  /*
   *	This routine remove all the alias hash and data files.
--- 644,652 ----
  	/*NOTREACHED*/
  }
  
! static void delete_alias_files(dataname, fromelm)
!      char *dataname;
!      int fromelm;
  {
  /*
   *	This routine remove all the alias hash and data files.
***************
*** 776,808 ****
  	char fname[SLEN];
  
  	if (unlink(dataname)) {
! 	  sprintf(msg_buff,
! 		catgets(elm_msg_cat, NewaliasSet, NewaliasCouldntDeleteData,
! 		"Could not delete alias data file %s!"), fname);
! 	  error(msg_buff);
  	  if (fromelm && sleepmsg > 0)
  		sleep(sleepmsg);
  	}
  
! 	sprintf(fname,"%s.dir", dataname);
  	if (unlink(fname)) {
! 	  sprintf(msg_buff,
! 		catgets(elm_msg_cat, NewaliasSet, NewaliasCouldntDeleteHash,
! 		"Could not delete alias hash file %s!"), fname);
! 	  error(msg_buff);
  	  if (fromelm && sleepmsg > 0)
  		sleep(sleepmsg);
  	}
  
! 	sprintf(fname,"%s.pag", dataname);
  	if (unlink(fname)) {
! 	  sprintf(msg_buff,
! 		catgets(elm_msg_cat, NewaliasSet, NewaliasCouldntDeleteHash,
! 		"Could not delete alias hash file %s!"), fname);
! 	  error(msg_buff);
  	  if (fromelm && sleepmsg > 0)
! 		sleep(sleepmsg);
  	}
  
  }
  
--- 657,694 ----
  	char fname[SLEN];
  
  	if (unlink(dataname)) {
! 	  lib_error(
! 		    CATGETS(elm_msg_cat, NewaliasSet, 
! 			    NewaliasCouldntDeleteData,
! 			"Could not delete alias data file %s!"), 
! 		    fname);
  	  if (fromelm && sleepmsg > 0)
  		sleep(sleepmsg);
  	}
  
! 	elm_sfprintf(fname,sizeof fname,FRM("%s.dir"), dataname);
  	if (unlink(fname)) {
! 	  lib_error(
! 		    CATGETS(elm_msg_cat, NewaliasSet, 
! 			    NewaliasCouldntDeleteHash,
! 			    "Could not delete alias hash file %s!"), 
! 		    fname);
  	  if (fromelm && sleepmsg > 0)
  		sleep(sleepmsg);
  	}
  
! 	elm_sfprintf(fname,sizeof fname,FRM("%s.pag"), dataname);
  	if (unlink(fname)) {
! 	  lib_error(
! 		    CATGETS(elm_msg_cat, NewaliasSet, 
! 			    NewaliasCouldntDeleteHash,
! 			    "Could not delete alias hash file %s!"), fname);
  	  if (fromelm && sleepmsg > 0)
! 	    sleep(sleepmsg);
  	}
  
  }
+ 
+ 
+ 
  
Index: elm2.4.ME+.50/lib/mk_lockname.c
*** elm2.4.25/lib/mk_lockname.c	Sun Oct  4 01:42:26 1992
--- elm2.4.ME+.50/lib/mk_lockname.c	Tue Nov 17 21:12:56 1998
***************
*** 1,34 ****
  
! static char rcsid[] = "@(#)$Id: mk_lockname.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: mk_lockname.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  #include <stdio.h>
  #include <fcntl.h>
  #include <errno.h>
! #include "defs.h"
  
  static char lock_name[SLEN];
  
  char * mk_lockname(file_to_lock)
! char *file_to_lock;
  {
        /** Create the proper name of the lock file for file_to_lock,
              which is presumed to be a spool file full path (see
--- 1,26 ----
  
! static char rcsid[] = "@(#)$Id: mk_lockname.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  #include <stdio.h>
  #include <fcntl.h>
  #include <errno.h>
! #include "headers.h"
  
  static char lock_name[SLEN];
  
  char * mk_lockname(file_to_lock)
!      char *file_to_lock;
  {
        /** Create the proper name of the lock file for file_to_lock,
              which is presumed to be a spool file full path (see
***************
*** 38,47 ****
  
  #ifdef XENIX
          /* lock is /tmp/[basename of file_to_lock].mlk */
!         sprintf(lock_name, "/tmp/%.10s.mlk", rindex(file_to_lock, '/')+1);
  #else
          /* lock is [file_to_lock].lock */
!         sprintf(lock_name, "%s.lock", file_to_lock);
  #endif
          return(lock_name);
  }
--- 30,41 ----
  
  #ifdef XENIX
          /* lock is /tmp/[basename of file_to_lock].mlk */
!         elm_sfprintf(lock_name, sizeof lock_name,
! 		     FRM("/tmp/%.10s.mlk"), rindex(file_to_lock, '/')+1);
  #else
          /* lock is [file_to_lock].lock */
!         elm_sfprintf(lock_name, sizeof lock_name,
! 		     FRM("%s.lock"), file_to_lock);
  #endif
          return(lock_name);
  }
Index: elm2.4.ME+.50/lib/move_left.c
*** elm2.4.25/lib/move_left.c	Sun Oct  4 01:42:26 1992
--- elm2.4.ME+.50/lib/move_left.c	Tue Nov 17 21:12:56 1998
***************
*** 1,23 ****
! static char rcsid[] = "@(#)$Id: move_left.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: move_left.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,15 ----
! static char rcsid[] = "@(#)$Id: move_left.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 26,34 ****
  #include "headers.h"
  
  
! move_left(string, chars)
! char *string;
! int  chars;
  {
  	/** moves string chars characters to the left DESTRUCTIVELY **/
  
--- 18,26 ----
  #include "headers.h"
  
  
! void move_left(string, chars)
!      char *string;
!      int  chars;
  {
  	/** moves string chars characters to the left DESTRUCTIVELY **/
  
Index: elm2.4.ME+.50/lib/msgcat.c
*** elm2.4.25/lib/msgcat.c	Thu Jun 10 06:12:20 1993
--- elm2.4.ME+.50/lib/msgcat.c	Tue Nov 17 21:12:55 1998
***************
*** 1,5 ****
  
! static char rcsid[] = "@(#)$Id: msgcat.c,v 5.2 1993/06/10 03:12:10 syd Exp $";
  
  /* -*- c++ -*- */
  
--- 1,5 ----
  
! static char rcsid[] = "@(#)$Id: msgcat.c,v 1.1.1.1 1998/10/15 15:36:40 hurtta Exp $";
  
  /* -*- c++ -*- */
  
***************
*** 50,70 ****
   * to add an error handling routine.
   */
  
  #include "nl_types.h"
  #include "msgcat.h"
  
! #ifdef BSD
  #include <sys/file.h>
  #include <sys/param.h>
  #endif
  #include <sys/stat.h>
  #include <fcntl.h>
- #include <stdio.h>
  
- #ifdef MIPS
- #include <unistd.h>
- #endif
- 
  #ifndef True
  # define True	~0
  # define False	0
--- 50,70 ----
   * to add an error handling routine.
   */
  
+ #include "defs.h"
+ #include "elmlib.h"
+ 
+ /*
  #include "nl_types.h"
+ */
  #include "msgcat.h"
  
! #ifdef BSD_TYPE
  #include <sys/file.h>
  #include <sys/param.h>
  #endif
  #include <sys/stat.h>
  #include <fcntl.h>
  
  #ifndef True
  # define True	~0
  # define False	0
***************
*** 86,93 ****
  static nl_catd loadCat();
  static nl_catd loadSet();
  
- extern char *malloc(), *getenv();
-     
  nl_catd 	catopen( name, type)
  char *name;
  int type;
--- 86,91 ----
***************
*** 109,120 ****
  	    nlspath = "/nlslib/%L/%N.cat:/nlslib/%N/%L";
  	}
  	if (MCAppPath) {
! 	    tmppath = (char *) malloc(strlen(nlspath) + strlen(MCAppPath) + 3);
  	    if (!tmppath) return(NLERR);
! 	    strcpy(tmppath, nlspath);
  	    if (tmppath[strlen(tmppath)-1] != ':' && *MCAppPath != ':')
! 	      strcat(tmppath, ":");
! 	    strcat(tmppath, MCAppPath);
  	    nlspath = tmppath;
  	}
  	
--- 107,119 ----
  	    nlspath = "/nlslib/%L/%N.cat:/nlslib/%N/%L";
  	}
  	if (MCAppPath) {
! 	    int Len = strlen(nlspath) + strlen(MCAppPath) + 3;
! 	    tmppath = (char *) malloc(Len);
  	    if (!tmppath) return(NLERR);
! 	    strfcpy(tmppath, nlspath, Len);
  	    if (tmppath[strlen(tmppath)-1] != ':' && *MCAppPath != ':')
! 	      strfcat(tmppath, ":", Len);
! 	    strfcat(tmppath, MCAppPath, Len);
  	    nlspath = tmppath;
  	}
  	
***************
*** 121,127 ****
  	len = strlen(nlspath);
  	base = cptr = (char *) malloc(len + 2);
  	if (!base) return(NLERR);
! 	strcpy(cptr, nlspath);
  	cptr[len] = ':';
  	cptr[len+1] = '\0';
          
--- 120,126 ----
  	len = strlen(nlspath);
  	base = cptr = (char *) malloc(len + 2);
  	if (!base) return(NLERR);
! 	strfcpy(cptr, nlspath,len+2);
  	cptr[len] = ':';
  	cptr[len+1] = '\0';
          
***************
*** 132,145 ****
  		    if (*nlspath == '%') {
  			if (*(nlspath + 1) == 'L') {
  			    ++nlspath;
! 			    strcpy(pathP, lang);
! 			    pathP += strlen(lang);
  			} else if (*(nlspath + 1) == 'N') {
  			    ++nlspath;
! 			    strcpy(pathP, name);
! 			    pathP += strlen(name);
! 			} else *(pathP++) = *nlspath;
! 		    } else *(pathP++) = *nlspath;
  		}
  		*pathP = '\0';
  		if (stat(path, &sbuf) == 0) {
--- 131,148 ----
  		    if (*nlspath == '%') {
  			if (*(nlspath + 1) == 'L') {
  			    ++nlspath;
! 			    strfcpy(pathP, lang, 
! 				    sizeof path - (pathP-path));
! 			    pathP += strlen(pathP);
  			} else if (*(nlspath + 1) == 'N') {
  			    ++nlspath;
! 			    strfcpy(pathP, name,
! 				    sizeof path - (pathP-path));
! 			    pathP += strlen(pathP);
! 			} else if (pathP < path + sizeof path -1)
! 			  *(pathP++) = *nlspath;
! 		    } else if (pathP < path + sizeof path -1)
! 		      *(pathP++) = *nlspath;
  		}
  		*pathP = '\0';
  		if (stat(path, &sbuf) == 0) {
***************
*** 283,289 ****
      for (i = 0; i < cat->numSets; ++i) {
  	set = cat->sets + i;
  	if (!set->invalid) {
! 	    free(set->data);
  	    free(set->u.msgs);
  	}
      }
--- 286,292 ----
      for (i = 0; i < cat->numSets; ++i) {
  	set = cat->sets + i;
  	if (!set->invalid) {
! 	    free(set->data.ptr);
  	    free(set->u.msgs);
  	}
      }
Index: elm2.4.ME+.50/lib/ndbz.c
*** elm2.4.25/lib/ndbz.c	Fri Mar 11 23:34:01 1994
--- elm2.4.ME+.50/lib/ndbz.c	Tue Nov 17 21:12:55 1998
***************
*** 1,78 ****
! static char rcsid[] = "@(#)$Id: ndbz.c,v 5.12 1994/03/11 21:01:35 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.12 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: ndbz.c,v $
!  * Revision 5.12  1994/03/11  21:01:35  syd
!  * detect whether atol() is a macro
!  * From: Mitch DSouza <m.dsouza@mrc-applied-psychology.cambridge.ac.uk>
!  *
!  * Revision 5.11  1993/08/23  02:46:51  syd
!  * Test ANSI_C, not __STDC__ (which is not set on e.g. AIX).
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.10  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.9  1993/08/03  19:22:01  syd
!  * Add proper casts to free() calls to suppress warnings.
!  * Properly cast return types.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.8  1993/07/20  02:59:53  syd
!  * Support aliases both on 64 bit and 32 bit machines at the same time.
!  * From: Dan Mosedale <mosedale@genome.stanford.edu>
!  *
!  * Revision 5.7  1993/06/09  23:41:34  syd
!  * Add frees of db structure on failed dbz_open
!  * From: Syd
!  *
!  * Revision 5.6  1993/02/08  00:18:11  syd
!  * fix taghere to be || instead of | and paren to make
!  * it catch duplicates again, as per testing.
!  * From: Syd and Chip Rosenthal
!  *
!  * Revision 5.5  1993/02/03  15:26:13  syd
!  * protect atol in ifndef __STDC__ as some make it a macro, and its in stdlib.h
!  *
!  * Revision 5.4  1993/01/27  20:40:10  syd
!  * make code match cnews dbz, remove extra | taghere in search,
!  * that was causing a compiler error anyway, as improper code
!  * From: Syd, via prompt from Denis Lambot
!  *
!  * Revision 5.3  1992/12/12  01:29:26  syd
!  * Fix double inclusion of sys/types.h
!  * From: Tom Moore <tmoore@wnas.DaytonOH.NCR.COM>
!  *
!  * Revision 5.2  1992/10/11  01:46:35  syd
!  * change dbm name to dbz to avoid conflicts with partial call
!  * ins from shared librarys, and from mixing code with yp code.
!  * From: Syd via prompt from Jess Anderson
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  	multi-database dbm replacement
--- 1,15 ----
! static char rcsid[] = "@(#)$Id: ndbz.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  	multi-database dbm replacement
***************
*** 302,311 ****
   */
  DBZ *				/* NULL for failure, !NULL for success */
  dbz_fresh(name, size, fs, tagmask)
! char *name;			/* base name; .dir and .pag must exist */
! long size;			/* table size (0 means default) */
! int fs;				/* field-separator character in base file */
! of_t tagmask;			/* 0 default, 1 no tags */
  {
  	register char *fn;
  	struct dbzconfig c;
--- 239,248 ----
   */
  DBZ *				/* NULL for failure, !NULL for success */
  dbz_fresh(name, size, fs, tagmask)
!      char *name;		/* base name; .dir and .pag must exist */
!      long size;			/* table size (0 means default) */
!      int fs;		        /* field-separator character in base file */
!      of_t tagmask;		/* 0 default, 1 no tags */
  {
  	register char *fn;
  	struct dbzconfig c;
***************
*** 383,391 ****
  /*
   - dbz_size - what's a good table size to hold this many entries?
   */
! long
! dbzsize(contents)
! long contents;			/* 0 means what's the default */
  {
  	register long n;
  
--- 320,327 ----
  /*
   - dbz_size - what's a good table size to hold this many entries?
   */
! long dbzsize(contents)
!      long contents;			/* 0 means what's the default */
  {
  	register long n;
  
***************
*** 444,451 ****
   */
  DBZ *				/* NULL for failure, !NULL for success */
  dbz_again(name, oldname)
! char *name;			/* base name; .dir and .pag must exist */
! char *oldname;			/* base name; all must exist */
  {
  	register char *fn;
  	struct dbzconfig c;
--- 380,387 ----
   */
  DBZ *				/* NULL for failure, !NULL for success */
  dbz_again(name, oldname)
!      char *name;		/* base name; .dir and .pag must exist */
!      char *oldname;	        /* base name; all must exist */
  {
  	register char *fn;
  	struct dbzconfig c;
***************
*** 672,682 ****
  char *s2;
  {
  	register char *p;
  
! 	p = malloc((size_t)strlen(s1) + (size_t)strlen(s2) + 1);
  	if (p != NULL) {
! 		(void) strcpy(p, s1);
! 		(void) strcat(p, s2);
  	} else {
  		dprint(5, (debugfile, "enstring(%s, %s) out of memory\n", s1, s2));
  	}
--- 608,619 ----
  char *s2;
  {
  	register char *p;
+ 	size_t Len = strlen(s1) + strlen(s2) + 1;
  
! 	p = malloc(Len);
  	if (p != NULL) {
! 		(void) strfcpy(p, s1, Len);
! 		(void) strfcat(p, s2, Len);
  	} else {
  		dprint(5, (debugfile, "enstring(%s, %s) out of memory\n", s1, s2));
  	}
***************
*** 686,694 ****
  /*
   - dbz_close - close a database
   */
! int
! dbz_close(db)
! register DBZ *db;
  {
  	register int ret = 0;
  
--- 623,630 ----
  /*
   - dbz_close - close a database
   */
! int dbz_close(db)
!      DBZ *db;
  {
  	register int ret = 0;
  
***************
*** 732,740 ****
  /*
   - dbz_sync - push all in-core data out to disk
   */
! int
! dbz_sync(db)
! register DBZ *db;
  {
  	register int ret = 0;
  
--- 668,675 ----
  /*
   - dbz_sync - push all in-core data out to disk
   */
! int dbz_sync(db)
!      DBZ *db;
  {
  	register int ret = 0;
  
***************
*** 787,794 ****
   */
  datum				/* dptr NULL, dsize 0 means failure */
  dbz_fetch(db, key)
! register DBZ *db;
! datum key;
  {
  	char buffer[DBZMAXKEY + 1];
  	static of_t key_ptr;		/* return value points here */
--- 722,729 ----
   */
  datum				/* dptr NULL, dsize 0 means failure */
  dbz_fetch(db, key)
!      DBZ *db;
!      datum key;
  {
  	char buffer[DBZMAXKEY + 1];
  	static of_t key_ptr;		/* return value points here */
***************
*** 890,898 ****
   */
  int				/* 0 success, -1 failure */
  dbz_store(db, key, data)
! register DBZ *db;
! datum key;
! datum data;
  {
  	of_t value;
  
--- 825,833 ----
   */
  int				/* 0 success, -1 failure */
  dbz_store(db, key, data)
!      DBZ *db;
!      datum key;
!      datum data;
  {
  	of_t value;
  
***************
*** 942,948 ****
   */
  int				/* old setting */
  dbz_incore(value)
! int value;
  {
  	register int old = default_incore;
  
--- 877,883 ----
   */
  int				/* old setting */
  dbz_incore(value)
!      int value;
  {
  	register int old = default_incore;
  
Index: elm2.4.ME+.50/lib/okay_addr.c
*** elm2.4.25/lib/okay_addr.c	Sun Oct  4 01:42:27 1992
--- elm2.4.ME+.50/lib/okay_addr.c	Tue Nov 17 21:12:56 1998
***************
*** 1,23 ****
! static char rcsid[] = "@(#)$Id: okay_addr.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: okay_addr.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,15 ----
! static char rcsid[] = "@(#)$Id: okay_addr.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 26,34 ****
  #include "headers.h"
  
  
! int
! okay_address(address, return_address)
! char *address, *return_address;
  {
  	/** This routine checks to ensure that the address we just got
  	    from the "To:" or "Cc:" line isn't us AND isn't the person	
--- 18,25 ----
  #include "headers.h"
  
  
! int okay_address(address, return_address)
!      char *address, *return_address;
  {
  	/** This routine checks to ensure that the address we just got
  	    from the "To:" or "Cc:" line isn't us AND isn't the person	
***************
*** 43,61 ****
  	if(in_list(address, username))
  	  return(FALSE);
  
! 	sprintf(our_address, "%s!%s", hostname, username);
  	if (in_list(address, our_address))
  	  return(FALSE);
  
! 	sprintf(our_address, "%s!%s", hostfullname, username);
  	if (in_list(address, our_address))
  	  return(FALSE);
  
! 	sprintf(our_address, "%s@%s", username, hostname);
  	if (in_list(address, our_address))
  	  return(FALSE);
  
! 	sprintf(our_address, "%s@%s", username, hostfullname);
  	if (in_list(address, our_address))
  	  return(FALSE);
  
--- 34,56 ----
  	if(in_list(address, username))
  	  return(FALSE);
  
! 	elm_sfprintf(our_address, sizeof our_address,
! 		     FRM("%s!%s"), hostname, username);
  	if (in_list(address, our_address))
  	  return(FALSE);
  
! 	elm_sfprintf(our_address, sizeof our_address,
! 		     FRM("%s!%s"), hostfullname, username);
  	if (in_list(address, our_address))
  	  return(FALSE);
  
! 	elm_sfprintf(our_address, sizeof our_address, 
! 		     FRM("%s@%s"), username, hostname);
  	if (in_list(address, our_address))
  	  return(FALSE);
  
! 	elm_sfprintf(our_address, sizeof our_address,
! 		     FRM("%s@%s"), username, hostfullname);
  	if (in_list(address, our_address))
  	  return(FALSE);
  
***************
*** 69,71 ****
--- 64,67 ----
  
  	return(TRUE);
  }
+ 
Index: elm2.4.ME+.50/lib/opt_utils.c
*** elm2.4.25/lib/opt_utils.c	Mon May 30 19:31:56 1994
--- elm2.4.ME+.50/lib/opt_utils.c	Tue Nov 17 21:12:56 1998
***************
*** 1,69 ****
  
! static char rcsid[] = "@(#)$Id: opt_utils.c,v 5.9 1994/05/30 16:31:40 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.9 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: opt_utils.c,v $
!  * Revision 5.9  1994/05/30  16:31:40  syd
!  * make getpwuid dependent on ANSI_C not posix flag
!  * From: Syd
!  *
!  * Revision 5.8  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.7  1993/01/20  03:02:19  syd
!  * Move string declarations to defs.h
!  * From: Syd
!  *
!  * Revision 5.6  1993/01/19  05:07:05  syd
!  * Trim erroreous extra log entry
!  * From: Syd
!  *
!  * Revision 5.5  1993/01/19  04:47:12  syd
!  * Significant changes to provide consistent Date and From_ header
!  * cracking.  Overhauled date utilities and moved into library.  Moved
!  * real_from() into library.  Modified frm, newmail, and readmsg utilities
!  * to use library version of real_from().  Moved get_word() from Elm
!  * source into library.  Added new library routines atonum() and strfcpy().
!  * Fixed trailing backslash bug in len_next().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.4  1992/12/12  01:29:26  syd
!  * Fix double inclusion of sys/types.h
!  * From: Tom Moore <tmoore@wnas.DaytonOH.NCR.COM>
!  *
!  * Revision 5.3  1992/10/30  21:49:38  syd
!  * Add init of buf
!  * From: Syd via request from hessmann@unipas.fmi.uni-passau.de (Georg Hessmann)
!  *
!  * Revision 5.2  1992/10/24  13:06:23  syd
!  * make getdomainname optional
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This file contains routines that might be needed for the various
       machines that the mailer can run on.  Please check the Makefile
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: opt_utils.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This file contains routines that might be needed for the various
       machines that the mailer can run on.  Please check the Makefile
***************
*** 88,96 ****
  
  #ifndef GETHOSTNAME
  
! gethostname(cur_hostname,size) /* get name of current host */
! char *cur_hostname;
! int size;
  {
  	/** Return the name of the current host machine. **/
  
--- 35,43 ----
  
  #ifndef GETHOSTNAME
  
! int gethostname(cur_hostname,size) /* get name of current host */
!      char *cur_hostname;
!      int size;
  {
  	/** Return the name of the current host machine. **/
  
***************
*** 133,141 ****
  #endif  /* GETHOSTNAME */
  
  
! gethostdomain(hostdom, size)    /* get domain of current host */
! char *hostdom;
! int size;
  {
  	char    buf[64];
  	FILE    *fp;
--- 80,88 ----
  #endif  /* GETHOSTNAME */
  
  
! int gethostdomain(hostdom, size)    /* get domain of current host */
!      char *hostdom;
!      int size;
  {
  	char    buf[64];
  	FILE    *fp;
***************
*** 202,208 ****
      if (returnonly) {
        return(name);
      } else {
!       strcpy(uname, name);
        return name;
      }
    } 
--- 149,155 ----
      if (returnonly) {
        return(name);
      } else {
!       strfcpy(uname, name, L_cuserid);
        return name;
      }
    } 
***************
*** 215,221 ****
  	  }
  	else 
  	  {
! 	    strcpy(uname, password_entry->pw_name);
  	    return name;
  	  }
        } 
--- 162,168 ----
  	  }
  	else 
  	  {
! 	    strfcpy(uname, password_entry->pw_name, L_cuserid);
  	    return name;
  	  }
        } 
***************
*** 231,237 ****
  #ifndef STRTOK
  
  char *strtok(source, keys)
! char *source, *keys;
  {
  	/** This function returns a pointer to the next word in source
  	    with the string considered broken up at the characters 
--- 178,184 ----
  #ifndef STRTOK
  
  char *strtok(source, keys)
!      char *source, *keys;
  {
  	/** This function returns a pointer to the next word in source
  	    with the string considered broken up at the characters 
***************
*** 280,286 ****
  #ifndef STRPBRK
  
  char *strpbrk(source, keys)
! char *source, *keys;
  {
  	/** Returns a pointer to the first character of source that is any
  	    of the specified keys, or NULL if none of the keys are present
--- 227,233 ----
  #ifndef STRPBRK
  
  char *strpbrk(source, keys)
!      char *source, *keys;
  {
  	/** Returns a pointer to the first character of source that is any
  	    of the specified keys, or NULL if none of the keys are present
***************
*** 302,309 ****
  
  #ifndef STRSPN
  
! strspn(source, keys)
! char *source, *keys;
  {
  	/** This function returns the length of the substring of
  	    'source' (starting at zero) that consists ENTIRELY of
--- 249,256 ----
  
  #ifndef STRSPN
  
! int strspn(source, keys)
!      char *source, *keys;
  {
  	/** This function returns the length of the substring of
  	    'source' (starting at zero) that consists ENTIRELY of
***************
*** 328,335 ****
  
  #ifndef STRCSPN
  
! strcspn(source, keys)
! char *source, *keys;
  {
  	/** This function returns the length of the substring of
  	    'source' (starting at zero) that consists entirely of
--- 275,282 ----
  
  #ifndef STRCSPN
  
! int strcspn(source, keys)
!      char *source, *keys;
  {
  	/** This function returns the length of the substring of
  	    'source' (starting at zero) that consists entirely of
***************
*** 358,367 ****
  static int cnt = 0;
  
  char *tempnam( dir, pfx)
!  char *dir, *pfx;
  {
  	char space[SLEN];
  	char *newspace;
  
  	if (dir == NULL) {
  		dir = "/usr/tmp";
--- 305,315 ----
  static int cnt = 0;
  
  char *tempnam( dir, pfx)
!      char *dir, *pfx;
  {
  	char space[SLEN];
  	char *newspace;
+ 	int Len;
  
  	if (dir == NULL) {
  		dir = "/usr/tmp";
***************
*** 373,384 ****
  		pfx = "";
  	}
  
! 	sprintf(space, "%s%s%d.%d", dir, pfx, getpid(), cnt);
  	cnt++;
  	
! 	newspace = malloc(strlen(space) + 1);
  	if (newspace != NULL) {
! 		strcpy(newspace, space);
  	}
  	return newspace;
  }
--- 321,334 ----
  		pfx = "";
  	}
  
! 	elm_sfprintf(space, sizeof space,
! 		     FRM("%s%s%d.%d"), dir, pfx, getpid(), cnt);
  	cnt++;
  	
! 	Len = strlen(space) + 1;
! 	newspace = malloc(Len);
  	if (newspace != NULL) {
! 		strfcpy(newspace, space, Len);
  	}
  	return newspace;
  }
***************
*** 405,414 ****
  int	optopt;
  char	*optarg;
  
! int
! getopt(argc, argv, opts)
! int	argc;
! char	**argv, *opts;
  {
  	static int sp = 1;
  	register int c;
--- 355,363 ----
  int	optopt;
  char	*optarg;
  
! int getopt(argc, argv, opts)
!      int	argc;
!      char	**argv, *opts;
  {
  	static int sp = 1;
  	register int c;
Index: elm2.4.ME+.50/lib/parsarpdat.c
*** elm2.4.25/lib/parsarpdat.c	Tue Aug  3 22:28:55 1993
--- elm2.4.ME+.50/lib/parsarpdat.c	Tue Nov 17 21:12:55 1998
***************
*** 1,39 ****
  
! static char rcsid[] = "@(#)$Id: parsarpdat.c,v 5.3 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
!  * 			Copyright (c) 1993 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: parsarpdat.c,v $
!  * Revision 5.3  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.2  1993/04/12  02:16:32  syd
!  * Fix year handling bug in date(1) time formats.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1993/01/19  04:46:21  syd
!  * Initial Checkin
   *
!  *
!  ******************************************************************************/
  
  
  #include "headers.h"
--- 1,15 ----
  
! static char rcsid[] = "@(#)$Id: parsarpdat.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  * 			Copyright (c) 1993 USENET Community Trust
!  *****************************************************************************/
  
  
  #include "headers.h"
***************
*** 77,238 ****
  						 ;  hours+min. (HHMM)
  */
  
! 
! int parse_arpa_date(str, entry)
! char *str;
! struct header_rec *entry;
  {
!     /*
!      * Parse a date field in either RFC-822 or Unix date(1) format.
!      * We will fill in the "time_zone", "tz_offset", and "time_sent"
!      * parts of the "entry" structure.  Return TRUE on success, FALSE
!      * on failure.
!      */
! 
!     char field[STRING], save_tz[STRING];
!     int month, day, year, hours, mins, secs, tz, len, i;
! 
      /*
!      * Since this is an RFC-822 field, there might be parenthetical
!      * comments.  Yank them out.  Note that strip_parens() returns
!      * a pointer to static data.
       */
!     str = strip_parens(str);
! 
      /*
!      * The first field is an optional day of the week.  If it exists
!      * it is supposed to have a trailing comma by RFC-822, but we won't
!      * complain if it doesn't.  If the date string was generated by
!      * the Unix date(1) command then it won't have the comma.  We don't
!      * do anything with this information, just skip over it if it exists.
       */
-     if ((len = get_word(str, 0, field, sizeof(field))) < 0)
- 	goto failed;
-     if (cvt_dayname_to_daynum(field, &i))
- 	str += len;
  
!     /*
!      * Peek at the next character to determine what format to
!      * parse the rest of the line as.
!      */
!     while (isspace(*str))
! 	++str;
!     if (!isdigit(*str)) {
! 
! 	/*
! 	 * Parse the line in Unix date(1) format.  The syntax is:
! 	 *
! 	 *	month day hh:mm:ss [tz] year
! 	 *
! 	 * e.g. "Jun 21 06:45:44 CDT 1989".  The timezone is optional.
! 	 */
! 
! 	dprint(7, (debugfile,
! 	    "parse_arpa_date parsing \"%s\" in time(1) format\n", str));
! 
! 	/* <month> */
! 	if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 		!cvt_monthname_to_monthnum(field, &month))
! 	    goto failed;
! 	str += len;
! 
! 	/* <day> */
! 	if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 		(day = atonum(field)) < 0)
! 	    goto failed;
! 	str += len;
! 
! 	/* <hh:mm:ss> */
! 	if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 		!cvt_timestr_to_hhmmss(field, &hours, &mins, &secs))
! 	    goto failed;
! 	str += len;
! 
! 	/* optional <tz> */
! 	save_tz[0] = save_tz[1] = '\0';
! 	tz = 0;
! 	while ((len = get_word(str, 0, field, sizeof(field))) > 0 &&
! 		cvt_timezone_to_offset(field, &i)) {
! 	    (void) strcat(save_tz, " ");
! 	    (void) strcat(save_tz, field);
! 	    tz += i;
! 	    str += len;
! 	}
! 
! 	/* <year> */
! 	if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 		(year = atonum(field)) < 0)
! 	    goto failed;
! 	str += len;
! 
! 	/* there might be more...but we ignore it */
! 
!     } else {
! 
! 	/*
! 	 * Parse the line in RFC-822 format.  The syntax is:
! 	 *
! 	 *	day month year hh:mm:ss zone
! 	 *
! 	 * e.g. "17 Nov 92 23:34:25 CST".
! 	 */
! 
! 	dprint(7, (debugfile,
! 	    "parse_arpa_date parsing \"%s\" in RFC-822 format\n", str));
! 
! 	/* <day> */
! 	if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 		(day = atonum(field)) < 0)
! 	    goto failed;
! 	str += len;
! 
! 	/* <month> */
! 	if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 		!cvt_monthname_to_monthnum(field, &month))
! 	    goto failed;
! 	str += len;
! 
! 	/* <year> */
! 	if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 		!cvt_yearstr_to_yearnum(field, &year))
! 	    goto failed;
! 	str += len;
! 
! 	/* <hh:mm:ss> */
! 	if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 		!cvt_timestr_to_hhmmss(field, &hours, &mins, &secs))
! 	    goto failed;
! 	str += len;
! 
! 	/* <tz> - silently ignore bogus or missing timezones */
! 	save_tz[0] = save_tz[1] = '\0';
! 	tz = 0;
! 	while ((len = get_word(str, 0, field, sizeof(field))) > 0 &&
! 		cvt_timezone_to_offset(field, &i)) {
! 	    (void) strcat(save_tz, " ");
! 	    (void) strcat(save_tz, field);
! 	    tz += i;
! 	    str += len;
! 	}
  
! 	/* there might be more...but we ignore it */
  
!     }
  
!     strfcpy(entry->time_zone, save_tz+1, sizeof(entry->time_zone));
!     entry->tz_offset = tz*60;
!     entry->time_sent = make_gmttime(year, month, day, hours, mins-tz, secs);
  
      dprint(7, (debugfile, "  year=%d month=%d day=%d\n", year, month, day));
      dprint(7, (debugfile, "  hours=%d mins=%d secs=%d tz=%d\n",
  	hours, mins, secs, tz));
      dprint(7, (debugfile, "  return success\n"));
      return TRUE;
  
  failed:
!     dprint(4, (debugfile, "parse_arpa_date failed at \"%s\"\n",
  	(len <= 0 ? "<premature eol>" : field)));
      return FALSE;
  }
  
  #ifdef _TEST
--- 53,252 ----
  						 ;  hours+min. (HHMM)
  */
  
! int parse_date_time(str,time_zone,size_time_zone,tz_offset, time_result)
!      const char *str;
!      char *time_zone; 
!      int size_time_zone;
!      time_t *tz_offset; 
!      time_t *time_result; 
  {
!   /*
!    * Parse a date field in either RFC-822 or Unix date(1) format.
!    */
! 
!   char field[STRING], save_tz[STRING];
!   int month, day, year, hours, mins, secs, tz, len, i;
!   
!   /*
!    * Since this is an RFC-822 field, there might be parenthetical
!    * comments.  Yank them out.  Note that strip_parens() returns
!    * a pointer to static data.
!    */
!   str = strip_parens(str);
! 
!   /*
!    * The first field is an optional day of the week.  If it exists
!    * it is supposed to have a trailing comma by RFC-822, but we won't
!    * complain if it doesn't.  If the date string was generated by
!    * the Unix date(1) command then it won't have the comma.  We don't
!    * do anything with this information, just skip over it if it exists.
!    */
!   if ((len = get_word(str, 0, field, sizeof(field))) < 0)
!     goto failed;
!   if (cvt_dayname_to_daynum(field, &i))
!     str += len;
! 
!   /*
!    * Peek at the next character to determine what format to
!    * parse the rest of the line as.
!    */
!   while (isspace(*str))
!     ++str;
!   if (!isdigit(*str)) {
!     
      /*
!      * Parse the line in Unix date(1) format.  The syntax is:
!      *
!      *	month day hh:mm:ss [tz] year
!      *
!      * e.g. "Jun 21 06:45:44 CDT 1989".  The timezone is optional.
       */
!     
!     dprint(7, (debugfile,
! 	       "parse_date_time parsing \"%s\" in time(1) format\n", str));
!     
!     /* <month> */
!     if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 	!cvt_monthname_to_monthnum(field, &month))
!       goto failed;
!     str += len;
!     
!     /* <day> */
!     if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 	(day = atonum(field)) < 0)
!       goto failed;
!     str += len;
!     
!     /* <hh:mm:ss> */
!     if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 	!cvt_timestr_to_hhmmss(field, &hours, &mins, &secs))
!       goto failed;
!     str += len;
!     
!     /* optional <tz> */
!     save_tz[0] = save_tz[1] = '\0';
!     tz = 0;
!     while ((len = get_word(str, 0, field, sizeof(field))) > 0 &&
! 	   cvt_timezone_to_offset(field, &i, sizeof field)) {
!       (void) strfcat(save_tz, " ", sizeof save_tz);
!       (void) strfcat(save_tz, field, sizeof save_tz);
!       tz += i;
!       str += len;
!     }
!     
!     /* <year> */
!     if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 	(year = atonum(field)) < 0)
!       goto failed;
!     str += len;
!     
!     /* there might be more...but we ignore it */
!     
!   } else {
!     
      /*
!      * Parse the line in RFC-822 format.  The syntax is:
!      *
!      *	day month year hh:mm:ss zone
!      *
!      * e.g. "17 Nov 92 23:34:25 CST".
       */
  
!     dprint(7, (debugfile,
! 	       "parse_date_time parsing \"%s\" in RFC-822 format\n", str));
!     
!     /* <day> */
!     if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 	(day = atonum(field)) < 0)
!       goto failed;
!     str += len;
!     
!     /* <month> */
!     if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 	!cvt_monthname_to_monthnum(field, &month))
!       goto failed;
!     str += len;
! 
!     /* <year> */
!     if ((len = get_word(str, 0, field, sizeof(field))) < 0 ||
! 	!cvt_yearstr_to_yearnum(field, &year))
!       goto failed;
!     str += len;
! 
!     /* <hh:mm:ss> */
!     if ((len = get_word(str, 0, field, sizeof(field))) < 0) {
!       /* on expires header there is no necessary time -part */
!       save_tz[0] = save_tz[1] = '\0';
!       tz = 0;
!       hours = 0;
!       mins = 0;
!       secs = 0;
!       dprint(7, (debugfile, "  only date given (no time and timezone)\n"));
!       goto notime;
!     }
!     if (!cvt_timestr_to_hhmmss(field, &hours, &mins, &secs))
!       goto failed;
!     str += len;
!     
!     /* <tz> - silently ignore bogus or missing timezones */
!     save_tz[0] = save_tz[1] = '\0';
!     tz = 0;
!     while ((len = get_word(str, 0, field, sizeof(field))) > 0 &&
! 	   cvt_timezone_to_offset(field, &i, sizeof field)) {
!       (void) strfcat(save_tz, " ", sizeof save_tz);
!       (void) strfcat(save_tz, field, sizeof save_tz);
!       tz += i;
!       str += len;
!     }
!     
!     /* there might be more...but we ignore it */
  
!   }
  
! notime:
  
!   if (time_zone)
!     strfcpy(time_zone, save_tz+1, size_time_zone);
!   if (tz_offset)
!     *tz_offset = tz*60;
!   *time_result = make_gmttime(year, month, day, hours, mins-tz, secs);
  
      dprint(7, (debugfile, "  year=%d month=%d day=%d\n", year, month, day));
      dprint(7, (debugfile, "  hours=%d mins=%d secs=%d tz=%d\n",
  	hours, mins, secs, tz));
+     dprint(7, (debugfile, "  time_result=%ld\n",(long)*time_result));
      dprint(7, (debugfile, "  return success\n"));
      return TRUE;
  
  failed:
!     dprint(4, (debugfile, "parse_date_time failed at \"%s\"\n",
  	(len <= 0 ? "<premature eol>" : field)));
      return FALSE;
+ 
+ }
+ 
+ int parse_arpa_date(src, entry)
+      char *src;
+      struct header_rec *entry;
+ {
+     /*
+      * Parse a date field in either RFC-822 or Unix date(1) format.
+      * We will fill in the "time_zone", "tz_offset", and "time_sent"
+      * parts of the "entry" structure.  Return TRUE on success, FALSE
+      * on failure.
+      */
+ 
+ 
+   if (parse_date_time(src,
+ 		      entry->time_zone,sizeof(entry->time_zone),
+ 		      &(entry->tz_offset), &(entry->time_sent))) {
+     dprint(7, (debugfile,
+ 	       "parse_arpa_date SUCCESS for %s\n",src));
+     return TRUE;
+   }
+   dprint(7, (debugfile,
+ 	     "parse_arpa_date failed for %s\n",src));
+   return FALSE;
  }
  
  #ifdef _TEST
Index: elm2.4.ME+.50/lib/parsarpwho.c
*** elm2.4.25/lib/parsarpwho.c	Tue Jul 20 05:06:41 1993
--- elm2.4.ME+.50/lib/parsarpwho.c	Tue Nov 17 21:12:55 1998
***************
*** 1,41 ****
  
! static char rcsid[] = "@(#)$Id: parsarpwho.c,v 5.4 1993/07/20 02:06:13 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: parsarpwho.c,v $
!  * Revision 5.4  1993/07/20  02:06:13  syd
!  * Changes for vms problem
!  * From: M.  Anio
!  *
!  * Revision 5.3  1993/01/19  05:07:05  syd
!  * Trim erroreous extra log entry
!  * From: Syd
!  *
!  * Revision 5.2  1993/01/19  04:47:12  syd
!  * Significant changes to provide consistent Date and From_ header
!  * cracking.  Overhauled date utilities and moved into library.  Moved
!  * real_from() into library.  Modified frm, newmail, and readmsg utilities
!  * to use library version of real_from().  Moved get_word() from Elm
!  * source into library.  Added new library routines atonum() and strfcpy().
!  * Fixed trailing backslash bug in len_next().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,12 ----
  
! static char rcsid[] = "@(#)$Id: parsarpwho.c,v 1.1.1.1 1998/10/15 15:36:39 hurtta Exp $";
  
! /******************************************************************************
   *
+  * This code is reimpleted. Original code was following copyright:
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 43,155 ****
  
  #include "headers.h"
  
! parse_arpa_who(buffer, newfrom, is_really_a_to)
! char *buffer, *newfrom;
! int is_really_a_to;
  {
! 	/** try to parse the 'From:' line given... It can be in one of
! 	    two formats:
! 		From: Dave Taylor <hplabs!dat>
! 	    or  From: hplabs!dat (Dave Taylor)
! 
! 	    Added: removes quotes if name is quoted (12/12)
! 	     HOWEVER:  From: "NAME \"VMS USER\"" <USER@VMS>
! 	           must be handled delicately !
! 	    Added: only copies STRING characters...
! 	    Added: if no comment part, copy address instead! 
! 	    Added: if is_really_a_to, this is really a 'to' line
! 		   and treat as if we allow embedded addresses
! 	**/
! 
! 	int use_embedded_addresses;
! 	char temp_buffer[LONG_STRING], *temp;
! 	register int i, j = 0, in_parens;
! 
! 	temp = (char *) temp_buffer;
! 	temp[0] = '\0';
! 
! 	no_ret(buffer);		/* blow away '\n' char! */
! 
! 	if (lastch(buffer) == '>') {
! 	  for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
! 	       buffer[i] != '('; i++)
! 	    temp[j++] = buffer[i];
! 	  temp[j] = '\0';
! 	}
! 	else if (lastch(buffer) == ')') {
! 	  in_parens = 1;
! 	  for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '<'; i--) {
! 	    switch(buffer[i]) {
! 	    case ')':	in_parens++;
! 			break;
! 	    case '(':	in_parens--;
! 			break;
! 	    }
! 	    if(!in_parens) break;
! 	    temp[j++] = buffer[i];
! 	  }
! 	  temp[j] = '\0';
! 	  reverse(temp);
! 	}
! 
! #ifdef USE_EMBEDDED_ADDRESSES
! 	use_embedded_addresses = TRUE;
! #else
! 	use_embedded_addresses = FALSE;
! #endif
! 
! 	if(use_embedded_addresses || is_really_a_to) {
! 	  /** if we have a null string at this point, we must just have a 
! 	      From: line that contains an address only.  At this point we
! 	      can have one of a few possibilities...
! 
! 		  From: address
! 		  From: <address>
! 		  From: address ()
! 	  **/
! 	    
! 	  if (strlen(temp) == 0) {
! 	    if (lastch(buffer) != '>') {       
! 	      for (i=strlen("From:");buffer[i] != '\0' && buffer[i] != '('; i++)
! 		temp[j++] = buffer[i];
! 	      temp[j] = '\0';
! 	    }
! 	    else {	/* get outta '<>' pair, please! */
! 	      for (i=strlen(buffer)-2;buffer[i] != '<' && buffer[i] != ':';i--)
! 		temp[j++] = buffer[i];
! 	      temp[j] = '\0';
! 	      reverse(temp);
! 	    }
! 	  }
! 	}
! 	  
! 	if (strlen(temp) > 0) {		/* mess with buffer... */
! 
! 	  /* remove leading spaces and ONE quote... */
! 
! 	  while (whitespace(temp[0]))
! 	    temp = (char *) (temp + 1);		/* increment address! */
! 	  if (temp[0] == '"')
! 	    temp = (char *) (temp + 1);		/* increment address! */
! 	  while (whitespace(temp[0]))
! 	    temp = (char *) (temp + 1);		/* increment address! */
! 
! 	  /* remove trailing spaces and ONE quote... */
! 
! 	  i = strlen(temp) - 1;
! 
! 	  while (i >= 0 && (whitespace(temp[i])))
! 	   temp[i--] = '\0';
! 	  /* Can delete ONE trailing quote, NOT THEM ALL!
! 	     Assuming the incoming quotes were all right.. [mea@utu.fi] */
! 	  if (i >= 0 && temp[i] == '"')
! 	   temp[i--] = '\0';
! 	  while (i >= 0 && (whitespace(temp[i])))
! 	   temp[i--] = '\0';
! 
! 	  /* if anything is left, let's change 'from' value! */
! 
! 	  if (strlen(temp) > 0)
! 	    strfcpy(newfrom, temp, STRING);
! 	}
  }
--- 14,71 ----
  
  #include "headers.h"
  
! void decode_who_none (class,bfr, size)
!      int class;
!      char *bfr;
!      int size;
! {
!   if (class != 0) {
!     bfr++;
!     size--;
!   }
!   return;
! }
! 
! /* This perhaps should go away.   - K E H <hurtta@ozone.FMI.FI> */
! 
! void parse_arpa_who(buffer, newfrom, decoder, size)
!      char *buffer, *newfrom;
!      decode_who decoder;
!      int size;
  {
! 
!   struct addr_item * list;
! 
!   dprint(12,(debugfile,
! 	     "parse_arpa_who: buffer=%.100s, newfrom=%.100s, size=%d\n",
! 	     buffer,newfrom,size));
! 
!   no_ret(buffer);		/* blow away '\n' char! */
! 
!   list = break_down_address(buffer,decoder);
! 	
!   if (list) {
!     struct addr_item * ptr;
! 
!     for (ptr=list; ptr->addr; ptr++) {
!       char * t = ptr->fullname;
!       if (!t[0])
! 	t = ptr->addr;
!       if (ptr == list)
! 	strfcpy(newfrom, t, size);
!       else {
! 	strfcat(newfrom, ", ", size);
! 	strfcat(newfrom, t, size);
!       }
!     }
!     dprint(12,(debugfile,
! 	       "parse_arpa_who: setting newfrom=%.100s\n",
! 	       newfrom))	    ;
!   }
!   
!   free_addr_items(list);
  }
+ 
+ 
+ 
+ 
Index: elm2.4.ME+.50/lib/posixsig.c
*** elm2.4.25/lib/posixsig.c	Mon Aug 23 05:46:55 1993
--- elm2.4.ME+.50/lib/posixsig.c	Tue Nov 17 21:12:55 1998
***************
*** 1,56 ****
  
! static char rcsid[] = "@(#)$Id: posixsig.c,v 5.8 1993/08/23 02:46:51 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.8 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: posixsig.c,v $
!  * Revision 5.8  1993/08/23  02:46:51  syd
!  * Test ANSI_C, not __STDC__ (which is not set on e.g. AIX).
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.7  1993/08/03  20:14:49  syd
!  * Fix where some systems name SIG_ERR BADSIG
!  * From: Syd
!  *
!  * Revision 5.6  1993/04/21  01:16:45  syd
!  * SunOS 4.1.3 uses the BSD convention for signal handling in system
!  * calls like read. The system call resumes when the signal handler
!  * returns unless the SA_INTERRUPT flag is set. Thus to make elm resize
!  * it's window after a SIGWINCH this flag must be set.
!  * From: vogt@isa.de (Gerald Vogt)
!  *
!  * Revision 5.5  1992/12/24  21:44:49  syd
!  * Add apollo check
!  * From: Syd
!  *
!  * Revision 5.4  1992/12/07  03:13:08  syd
!  * Add code to work around SunOS and sigalrm not returning EINTR
!  * From: Chip, Tom, Steve, Et. Al.
!  *
!  * Revision 5.3  1992/11/07  19:30:01  syd
!  * Fix redefinition complaint by SCO 3.2v2.0.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.2  1992/10/27  16:08:32  syd
!  * Fix non ansi declaration
!  * From: tom@osf.org
!  *
!  * Revision 5.1  1992/10/27  01:43:56  syd
!  * Initial Checkin
!  * Moved from src/signals.c
!  *
!  *
!  ******************************************************************************/
  
  /** Duplicate the old signal() call with POSIX sigaction
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: posixsig.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** Duplicate the old signal() call with POSIX sigaction
  
***************
*** 105,107 ****
--- 65,167 ----
  	    return(oact.sa_handler);
  }
  #endif /* POSIX_SIGNALS */
+ 
+ extern int errno;
+ 
+ #ifdef BACKGROUD_PROCESSES       /* We assume POSIX in here */
+ 
+ int my_wait (pid,statptr)
+      int pid; 
+ #if defined(BSD_TYPE) && !defined(WEXITSTATUS)
+      union wait *statptr;
+ #else
+      int *statptr;
+ #endif
+ {
+   int ret,err;
+   dprint(10, (debugfile, "my_wait(%d,...) ... with BACKGROUD_PROCESSES\n", 
+ 	      pid));
+   errno = 0;
+   ret = waitpid(pid,statptr,0);
+   err = errno;
+ 
+ #if defined(BSD_TYPE) && !defined(WEXITSTATUS)
+   dprint(10, (debugfile, "my_wait(%d,*statptr=%d) = %d\n", pid,
+ 	      statptr->w_status,ret));
+ #else
+   dprint(10, (debugfile, "my_wait(%d,*statptr=%d) = %d\n", pid,
+ 	      *statptr,ret));
+ #endif
+ 
+   if (err) {
+     dprint(10, (debugfile, " *** errno=%d (%s)\n",err,
+ 		error_description(err)));
+   }
+   errno = err;
+   return ret;
+ }
+ 
+ #else
+ 
+ int my_wait (pid,statptr)
+      int pid; 
+ #if defined(BSD_TYPE) && !defined(WEXITSTATUS)
+      union wait *statptr;
+ #else
+      int *statptr;
+ #endif
+ {
+   int ret,err;
+   dprint(10, (debugfile, "my_wait(%d,...) ... no BACKGROUD_PROCESSES\n", pid));
+   errno = 0;
+   ret = wait(statptr);
+   err = errno;
+   dprint(10, (debugfile, "my_wait(%d,*statptr=%d) = %d\n", pid,
+ #if defined(BSD_TYPE) && !defined(WEXITSTATUS)
+ 	      statptr->w_status
+ #else
+ 	      *statptr
+ #endif
+ 	      ,ret));
+   if (err) {
+     dprint(10, (debugfile, " *** errno=%d (%s)\n",err,
+ 		error_description(err)));
+   }
+   errno = err;
+   return ret;
+ 
+ }
+ #endif
+ 
+ int convert_status(status,exit_code) 
+ #if defined(BSD_TYPE) && !defined(WEXITSTATUS)
+      union wait status;
+ #else
+      int status;
+ #endif
+      int *exit_code;
+ {
+   int sig;
+ #ifdef	WEXITSTATUS
+   *exit_code = WEXITSTATUS(status);
+   if (WIFSIGNALED(status)) {
+      sig        = WTERMSIG(status);
+      dprint(10, (debugfile, "convert_status: TERMINATED WITH SIGNAL %d\n",
+                  sig));
+   } else
+      sig        = 0;
+ #else
+ # ifdef	BSD_TYPE
+   *exit_code = status.w_retcode;
+   sig        = status.w_termsig;
+ # else
+   *exit_code = status >> 8;
+   sig        = status & 128;
+ # endif
+ #endif
+ 
+   dprint(10, (debugfile, "convert_status=%d (sig): exit_code=%d\n", 
+ 	      sig,*exit_code));
+ 
+   return sig;
+ }
Index: elm2.4.ME+.50/lib/putenv.c
*** elm2.4.25/lib/putenv.c	Sun Oct  4 01:42:28 1992
--- elm2.4.ME+.50/lib/putenv.c	Tue Nov 17 21:12:55 1998
***************
*** 1,23 ****
  
! static char rcsid[] = "@(#)$Id: putenv.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
!  *			Copyright (c) 1992 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: putenv.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
   *
!  *
!  ******************************************************************************/
  
  /*
   * This code was stolen from cnews.  Modified to make "newenv" static so
--- 1,15 ----
  
! static char rcsid[] = "@(#)$Id: putenv.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  *			Copyright (c) 1992 USENET Community Trust
!  *****************************************************************************/
  
  /*
   * This code was stolen from cnews.  Modified to make "newenv" static so
***************
*** 34,42 ****
  #define WORKED 0
  #define FAILED 1
  
! int
! putenv(var)			/* put var in the environment */
! char *var;
  {
  	register char **envp;
  	register int oldenvcnt;
--- 26,33 ----
  #define WORKED 0
  #define FAILED 1
  
! int putenv(var)			/* put var in the environment */
!      char *var;
  {
  	register char **envp;
  	register int oldenvcnt;
Index: elm2.4.ME+.50/lib/qstrings.c
*** elm2.4.25/lib/qstrings.c	Tue Aug  3 22:28:56 1993
--- elm2.4.ME+.50/lib/qstrings.c	Tue Nov 17 21:12:55 1998
***************
*** 1,36 ****
  
! static char rcsid[] = "@(#)$Id: qstrings.c,v 5.2 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: qstrings.c,v $
!  * Revision 5.2  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This file contains equivalent routines to the string routines, but
       modifed to handle quoted strings.
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: qstrings.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This file contains equivalent routines to the string routines, but
       modifed to handle quoted strings.
***************
*** 37,46 ****
  
  **/
  
! #include "headers.h"
  
  char *qstrpbrk(source, keys)
! char *source, *keys;
  {
  	/** Returns a pointer to the first character of source that is any
  	    of the specified keys, or NULL if none of the keys are present
--- 17,27 ----
  
  **/
  
! #include "defs.h"
! #include "elmlib.h"
  
  char *qstrpbrk(source, keys)
!      char *source, *keys;
  {
  	/** Returns a pointer to the first character of source that is any
  	    of the specified keys, or NULL if none of the keys are present
***************
*** 64,72 ****
  	return(NULL);
  }
  
! int
! qstrspn(source, keys)
! char *source, *keys;
  {
  	/** This function returns the length of the substring of
  	    'source' (starting at zero) that consists ENTIRELY of
--- 45,52 ----
  	return(NULL);
  }
  
! int qstrspn(source, keys)
!      char *source, *keys;
  {
  	/** This function returns the length of the substring of
  	    'source' (starting at zero) that consists ENTIRELY of
***************
*** 91,99 ****
  	return(loc);
  }
  
! int
! qstrcspn(source, keys)
! char *source, *keys;
  {
  	/** This function returns the length of the substring of
  	    'source' (starting at zero) that consists entirely of
--- 71,78 ----
  	return(loc);
  }
  
! int qstrcspn(source, keys)
!      char *source, *keys;
  {
  	/** This function returns the length of the substring of
  	    'source' (starting at zero) that consists entirely of
Index: elm2.4.ME+.50/lib/realfrom.c
*** elm2.4.25/lib/realfrom.c	Tue Aug 30 18:11:20 1994
--- elm2.4.ME+.50/lib/realfrom.c	Tue Nov 17 21:12:55 1998
***************
*** 1,62 ****
  
! static char rcsid[] = "@(#)$Id: realfrom.c,v 5.5 1994/08/30 15:11:20 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.5 $   $State: Exp $
   *
!  * 			Copyright (c) 1993 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: realfrom.c,v $
!  * Revision 5.5  1994/08/30  15:11:20  syd
!  * Work around null from names by looking to see whether the second or
!  * third field is a valid month and using that to determine if there
!  * is an address.
!  * From: alex@samwise.dccs.upenn.edu (Alex Garthwaite)
!  *
!  * Revision 5.4  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.3  1993/05/08  17:09:56  syd
!  * Fix problem where "<space>From" was recognized as a valid "From_" line.
!  * From: decwrl!decvax!gatech!WLK.COM!chip (Chip Rosenthal)
!  *
!  * Revision 5.2  1993/04/12  01:24:59  syd
!  * Have real_from() ignore bogus timezones in From_ lines
!  * rather than bailing out with an error.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1993/01/19  04:46:21  syd
!  * Initial Checkin
   *
!  *
!  ******************************************************************************/
  
  
  #include "headers.h"
  
- 
  extern long make_gmttime();
  
! 
! int
! real_from(buffer, entry)
! char *buffer;
! struct header_rec *entry;
  {
  
      /*
--- 1,24 ----
  
! static char rcsid[] = "@(#)$Id: realfrom.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  * 			Copyright (c) 1993 USENET Community Trust
!  *****************************************************************************/
  
  
  #include "headers.h"
  
  extern long make_gmttime();
  
! int real_from(buffer, entry)
!      char *buffer;
!      struct header_rec *entry;
  {
  
      /*
***************
*** 89,95 ****
       */
      if (entry != NULL) {
  	entry->time_zone[0] = '\0';
! 	entry->from[0] = '\0';
  	entry->time_sent = 0;
  	entry->received_time = 0;
  	entry->tz_offset = 0;
--- 51,57 ----
       */
      if (entry != NULL) {
  	entry->time_zone[0] = '\0';
! 	entry->env_from[0] = '\0';
  	entry->time_sent = 0;
  	entry->received_time = 0;
  	entry->tz_offset = 0;
***************
*** 125,131 ****
  	  /*  field2 is month, field3 is day  */
            /* <user> */
            if (entry != NULL)
! 	      *( entry->from ) = '\0';
            dprint(7, (debugfile, "  user=\n"));
  
            /* <day> */
--- 87,93 ----
  	  /*  field2 is month, field3 is day  */
            /* <user> */
            if (entry != NULL)
! 	      *( entry->env_from ) = '\0';
            dprint(7, (debugfile, "  user=\n"));
  
            /* <day> */
***************
*** 136,142 ****
        {
          /* <user> */
          if (entry != NULL)
! 	    strfcpy(entry->from, field, sizeof(field));
          dprint(7, (debugfile, "  user=%s\n", field));
  
          /* <day> */
--- 98,104 ----
        {
          /* <user> */
          if (entry != NULL)
! 	    strfcpy(entry->env_from, field, sizeof(entry->env_from));
          dprint(7, (debugfile, "  user=%s\n", field));
  
          /* <day> */
***************
*** 172,178 ****
  	 * First check if this is a TZ field.  If so, pull in the info
  	 * and continue onto the next field.
  	 */
! 	if (cvt_timezone_to_offset(field, &i)) {
  	    tz += i;
  	    i = strlen(save_tz);
  	    (void) strfcpy(save_tz+i, " ", sizeof(save_tz)-i);
--- 134,140 ----
  	 * First check if this is a TZ field.  If so, pull in the info
  	 * and continue onto the next field.
  	 */
! 	if (cvt_timezone_to_offset(field, &i, sizeof field)) {
  	    tz += i;
  	    i = strlen(save_tz);
  	    (void) strfcpy(save_tz+i, " ", sizeof(save_tz)-i);
***************
*** 196,201 ****
--- 158,182 ----
  	    "  assuming \"%s\" is a bogus timezone - skipping it\n", field));
  
      }
+     
+     if (!save_tz[0] && tz == 0) {
+       /* Assume local timezone */
+       long      tzmin;		/* number of minutes off gmt 	 */
+       int	  tzsign;		/* + or - gmt 			 */
+       
+       if ((tz = (tzmin = -get_tz_mins())) >= 0) {
+ 	tzsign = '+';
+       } else {
+ 	tzsign = '-';
+ 	tzmin = -tzmin;
+       }
+       elm_sfprintf(save_tz, sizeof save_tz,
+ 		   FRM(" %c%02d%02d"),
+ 		   tzsign,tzmin / 60, tzmin % 60);
+       dprint(7, (debugfile,
+ 		 "  assuming local timezone %s", save_tz));
+ 
+     }
      if (entry != NULL) {
  	entry->tz_offset = tz * 60;
  	(void) strfcpy(entry->time_zone, save_tz+1, sizeof(entry->time_zone));
***************
*** 233,239 ****
  	else {
  	    printf("OK %s\n", buf);
  	    printf("from=%s time_zone=%s tz_offset=%d\n",
! 		hdr.from, hdr.time_zone, hdr.tz_offset);
  	    printf("time_sent=%ld received_time=%ld %s",
  		hdr.time_sent, hdr.received_time, ctime(&hdr.received_time));
  	}
--- 214,220 ----
  	else {
  	    printf("OK %s\n", buf);
  	    printf("from=%s time_zone=%s tz_offset=%d\n",
! 		hdr.env_from, hdr.time_zone, hdr.tz_offset);
  	    printf("time_sent=%ld received_time=%ld %s",
  		hdr.time_sent, hdr.received_time, ctime(&hdr.received_time));
  	}
Index: elm2.4.ME+.50/lib/remfirstwd.c
*** elm2.4.25/lib/remfirstwd.c	Sun Oct  4 01:42:29 1992
--- elm2.4.ME+.50/lib/remfirstwd.c	Tue Nov 17 21:12:56 1998
***************
*** 1,23 ****
! static char rcsid[] = "@(#)$Id: remfirstwd.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: remfirstwd.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,15 ----
! static char rcsid[] = "@(#)$Id: remfirstwd.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 25,33 ****
  
  #include "headers.h"
  
! 
! remove_first_word(string)
! char *string;
  {	/** removes first word of string, ie up to first non-white space
  	    following a white space! **/
  
--- 17,24 ----
  
  #include "headers.h"
  
! void remove_first_word(string)
!      char *string;
  {	/** removes first word of string, ie up to first non-white space
  	    following a white space! **/
  
***************
*** 42,49 ****
  	move_left(string, loc);
  }
  
! remove_header_keyword(string)
! char *string;
  {	/** removes a RFC822 header keyword from the string.
  	    i.e. removes up to (and including) the first colon,
  	    plus any white-space immediately following it.  **/
--- 33,40 ----
  	move_left(string, loc);
  }
  
! void remove_header_keyword(string)
!      char *string;
  {	/** removes a RFC822 header keyword from the string.
  	    i.e. removes up to (and including) the first colon,
  	    plus any white-space immediately following it.  **/
Index: elm2.4.ME+.50/lib/reverse.c
*** elm2.4.25/lib/reverse.c	Sun Oct  4 01:42:29 1992
--- elm2.4.ME+.50/lib/reverse.c	Tue Nov 17 21:12:55 1998
***************
*** 1,23 ****
! static char rcsid[] = "@(#)$Id: reverse.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: reverse.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,15 ----
! static char rcsid[] = "@(#)$Id: reverse.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 25,42 ****
  
  #include "headers.h"
  
! 
! reverse(string)
! char *string;
  {
  	/** reverse string... pretty trivial routine, actually! **/
  
  	register char *head, *tail, c;
  
! 	for (head = string, tail = string + strlen(string) - 1; head < tail; head++, tail--)
! 		{
! 		c = *head;
! 		*head = *tail;
! 		*tail = c;
! 		}
  }
--- 17,34 ----
  
  #include "headers.h"
  
! void reverse(string)
!      char *string;
  {
  	/** reverse string... pretty trivial routine, actually! **/
  
  	register char *head, *tail, c;
  
! 	for (head = string, tail = string + strlen(string) - 1; 
! 	     head < tail; 
! 	     head++, tail--) {
! 	  c = *head;
! 	  *head = *tail;
! 	  *tail = c;
! 	}
  }
Index: elm2.4.ME+.50/lib/rfc822tlen.c
*** elm2.4.25/lib/rfc822tlen.c	Tue Jul 20 06:15:24 1993
--- elm2.4.ME+.50/lib/rfc822tlen.c	Tue Nov 17 21:12:56 1998
***************
*** 1,26 ****
  
! static char rcsid[] = "@(#)$Id: rfc822tlen.c,v 5.2 1993/07/20 03:15:15 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
   *
!  *			Copyright (c) 1993 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: rfc822tlen.c,v $
!  * Revision 5.2  1993/07/20  03:15:15  syd
!  * remove extra garbage line
!  *
!  * Revision 5.1  1993/06/10  03:02:20  syd
!  * Initial Checkin
   *
!  *
!  ******************************************************************************/
  
  #include <stdio.h>
  
--- 1,15 ----
  
! static char rcsid[] = "@(#)$Id: rfc822tlen.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  *			Copyright (c) 1993 USENET Community Trust
!  *****************************************************************************/
  
  #include <stdio.h>
  
***************
*** 53,62 ****
   */
  #define IS822_SPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
  
! /*
!  * We've thrown non-ASCII (value > 0177) into this.
!  */
! #define IS822_CTL(c)	((c) <= 037 || (c) >= 0177)
  
  #define IS822_ATOMCH(c)	(!IS822_SPECIAL(c) && !IS822_SPACE(c) && !IS822_CTL(c))
  
--- 42,48 ----
   */
  #define IS822_SPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
  
! #define IS822_CTL(c)	((unsigned char)(c) <= 037 || (unsigned char)(c) == 0177)
  
  #define IS822_ATOMCH(c)	(!IS822_SPECIAL(c) && !IS822_SPACE(c) && !IS822_CTL(c))
  
Index: elm2.4.ME+.50/lib/safemalloc.c
*** elm2.4.25/lib/safemalloc.c	Mon Apr 12 04:51:33 1993
--- elm2.4.ME+.50/lib/safemalloc.c	Tue Nov 17 21:12:56 1998
***************
*** 1,26 ****
  
! static char rcsid[] = "@(#)$Id: safemalloc.c,v 5.1 1993/04/12 01:51:01 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
!  * 			Copyright (c) 1992 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: safemalloc.c,v $
!  * Revision 5.1  1993/04/12  01:51:01  syd
!  * Initial Checkin
!  *
   *
!  ******************************************************************************/
  
- #include <stdio.h>
  #include "defs.h"
  
  /*
   * These routines perform dynamic memory allocation with error checking.
--- 1,18 ----
  
! static char rcsid[] = "@(#)$Id: safemalloc.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  * 			Copyright (c) 1992 USENET Community Trust
!  *****************************************************************************/
  
  #include "defs.h"
+ #include "elmlib.h"
  
  /*
   * These routines perform dynamic memory allocation with error checking.
***************
*** 31,38 ****
  
  
  void dflt_safe_malloc_fail_handler(proc, len)
! char *proc;
! unsigned len;
  {
  	fprintf(stderr,
  		"error - out of memory [%s failed allocating %d bytes]\n",
--- 23,30 ----
  
  
  void dflt_safe_malloc_fail_handler(proc, len)
!      char *proc;
!      unsigned len;
  {
  	fprintf(stderr,
  		"error - out of memory [%s failed allocating %d bytes]\n",
***************
*** 42,50 ****
  
  void (*safe_malloc_fail_handler)() = dflt_safe_malloc_fail_handler;
  
- 
  malloc_t safe_malloc(len)
! unsigned len;
  {
  	malloc_t p;
  	if ((p = malloc(len)) == NULL)
--- 34,41 ----
  
  void (*safe_malloc_fail_handler)() = dflt_safe_malloc_fail_handler;
  
  malloc_t safe_malloc(len)
!      unsigned len;
  {
  	malloc_t p;
  	if ((p = malloc(len)) == NULL)
***************
*** 54,61 ****
  
  
  malloc_t safe_realloc(p, len)
! malloc_t p;
! unsigned len;
  {
  	if ((p = (p == NULL ? malloc(len) : realloc((malloc_t)p, len))) == NULL)
  		(*safe_malloc_fail_handler)("safe_realloc", len);
--- 45,52 ----
  
  
  malloc_t safe_realloc(p, len)
!      malloc_t p;
!      unsigned len;
  {
  	if ((p = (p == NULL ? malloc(len) : realloc((malloc_t)p, len))) == NULL)
  		(*safe_malloc_fail_handler)("safe_realloc", len);
***************
*** 62,73 ****
  	return p;
  }
  
- 
  char *safe_strdup(s)
! char *s;
  {
  	char *p;
! 	if ((p = (char *) malloc(strlen(s)+1)) == NULL)
! 		(*safe_malloc_fail_handler)("safe_strdup", strlen(s)+1);
! 	return strcpy(p, s);
  }
--- 53,64 ----
  	return p;
  }
  
  char *safe_strdup(s)
!      const char *s;
  {
  	char *p;
! 	int Len = strlen(s)+1;
! 	if ((p = (char *) malloc(Len)) == NULL)
! 		(*safe_malloc_fail_handler)("safe_strdup", Len);
! 	return strfcpy(p, s, Len);
  }
Index: elm2.4.ME+.50/lib/shiftlower.c
*** elm2.4.25/lib/shiftlower.c	Sat Mar 12 00:11:09 1994
--- elm2.4.ME+.50/lib/shiftlower.c	Tue Nov 17 21:12:56 1998
***************
*** 1,43 ****
! static char rcsid[] = "@(#)$Id: shiftlower.c,v 5.3 1994/03/11 22:11:09 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: shiftlower.c,v $
!  * Revision 5.3  1994/03/11  22:11:09  syd
!  * There is a bug in the alias-system of elm-2.4.23 that did not appear in
!  * elm-2.4.21. When searching for a string in the alias-table with the '//'
!  * command, elm sometimes gets a segmentation fault. With help of a debugger,
!  * I found that the function shift_lower gets a NULL argument. A fix is
!  * appended, but maybe the problem lies elsewhere.
!  * From: Sjaak Schilperoort <J.W.Schilperoort@research.ptt.nl>
!  *
!  * Revision 5.2  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,15 ----
! static char rcsid[] = "@(#)$Id: shiftlower.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 46,67 ****
  #include "headers.h"
  
  char *shift_lower(string)
! char *string;
  {
  	/** return 'string' shifted to lower case.  Do NOT touch the
  	    actual string handed to us! **/
  
  	static char buffer[VERY_LONG_STRING];
! 	register char *bufptr = buffer;
  
  	if (string == NULL) {
  		buffer[0] = 0;
  		return( (char *) buffer);
  	}
! 	for (; *string; string++, bufptr++)
  	  *bufptr = tolower(*string);
  	
  	*bufptr = 0;
  	
  	return( (char *) buffer);
  }
--- 18,48 ----
  #include "headers.h"
  
  char *shift_lower(string)
!      const char *string;
  {
  	/** return 'string' shifted to lower case.  Do NOT touch the
  	    actual string handed to us! **/
  
  	static char buffer[VERY_LONG_STRING];
! 	char *bufptr = buffer;
! 	const char *src0 = string;
  
  	if (string == NULL) {
  		buffer[0] = 0;
  		return( (char *) buffer);
  	}
! 	for (; *string && bufptr - buffer < sizeof buffer; 
! 	     string++, bufptr++)
  	  *bufptr = tolower(*string);
  	
  	*bufptr = 0;
  	
+ 	if (*string != '\0') {
+ 	  dprint(1,(debugfile,
+ 		    "shift_lower: --- too long string (max=%d): %.30s...\n",
+ 		    sizeof buffer -1,src0));
+ 	}
+ 
+ 
  	return( (char *) buffer);
  }
Index: elm2.4.ME+.50/lib/strfcpy.c
*** elm2.4.25/lib/strfcpy.c	Tue Jan 19 06:47:05 1993
--- elm2.4.ME+.50/lib/strfcpy.c	Tue Nov 17 21:12:55 1998
***************
*** 1,23 ****
  
! static char rcsid[] = "@(#)$Id: strfcpy.c,v 5.1 1993/01/19 04:46:21 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
!  * 			Copyright (c) 1993 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: strfcpy.c,v $
!  * Revision 5.1  1993/01/19  04:46:21  syd
!  * Initial Checkin
!  *
   *
!  ******************************************************************************/
  
  /*
   * This is just like strncpy() except:
--- 1,15 ----
  
! static char rcsid[] = "@(#)$Id: strfcpy.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
!  * 			Copyright (c) 1993 USENET Community Trust
!  *****************************************************************************/
  
  /*
   * This is just like strncpy() except:
***************
*** 29,43 ****
   *   the trailing '\0'.  That is, strncpy() fills in the end with '\0'
   *   if strlen(src)<len.  We don't bother.
   */
  char *strfcpy(dest, src, len)
! register char *dest, *src;
! register int len;
  {
! 	char *dest0 = dest;
! 	while (--len > 0 && *src != '\0')
! 		*dest++ = *src++;
! 	*dest = '\0';
! 	return dest0;
  }
  
  #ifdef _TEST
--- 21,75 ----
   *   the trailing '\0'.  That is, strncpy() fills in the end with '\0'
   *   if strlen(src)<len.  We don't bother.
   */
+ 
+ #include "defs.h"
+ #include "elmlib.h"
+ 
  char *strfcpy(dest, src, len)
!      char *dest;
!      const char *src;
!      int len;
! {
!   int size = len;
!   const char *src0 = src;
! 
!   char *dest0 = dest;
! 
!   while (--len > 0 && *src != '\0')
!     *dest++ = *src++;
! 
!   if (*src != '\0') {
!     dprint(1,(debugfile,
! 	      "strfcpy: --- too long string (max=%d): %.30s...\n",
! 	      size,src0));
!   }
! 
!   *dest = '\0';
!   return dest0;
! }
! 
! char *strfcat(dest, src, len)
!      char *dest;
!      const char *src;
!      int len;
  {
!   int size = len;
!   const char *src0 = src;
! 
!   char *dest0 = dest;
!   while ('\0' != *dest && --len > 0)
!     dest++;
!   while (--len > 0 && *src != '\0')
!     *dest++ = *src++;
! 
!   if (*src != '\0') {
!     dprint(1,(debugfile,
! 	      "strfcat: --- too long string (max target=%d): %.30s...\n",
! 	      size,src0));
!   }
! 
!   *dest = '\0';
!   return dest0;
  }
  
  #ifdef _TEST
Index: elm2.4.ME+.50/lib/strftime.c
*** elm2.4.25/lib/strftime.c	Mon May 16 03:05:33 1994
--- elm2.4.ME+.50/lib/strftime.c	Tue Nov 17 21:12:55 1998
***************
*** 1,92 ****
  
! static char rcsid[] = "@(#)$Id: strftime.c,v 5.11 1994/05/16 00:05:27 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.11 $   $State: Exp $
   *
   * Public-domain relatively quick-and-dirty implemenation of
   * ANSI library routine for System V Unix systems.
   *
   * Arnold Robbins
   *
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  * (Note: this routine is provided as is, without support for those sites that
!  *	do not have strftime in their library)
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: strftime.c,v $
!  * Revision 5.11  1994/05/16  00:05:27  syd
!  * Update to strftime-6.1
!  * From: Syd
!  *
!  * Revision 5.10  1994/03/11  20:55:23  syd
!  * Replaced the get_tz_mins() routine in lib/get_tz.c with a portable
!  * version that requires no configuration.  Rewrote the test case in
!  * lib/get_tz.c, and also wrote in support to simplify configuration
!  * tests.  Dropped TZMINS_USE_XXXX configuration parameter.  Simplified
!  * timezone determination in Configure.  The new get_tz_mins() introduces
!  * two side effects.  First it steps on the static data returned by
!  * localtime().  Second, it uses a routine in lib/date_util.c, which
!  * requires debug initializations.  Rewrote get_arpa_date() to work around
!  * the first issue.  Rather than doing the same for lib/strftime.c, just
!  * removed the timezone stuff with a conditional compile.  Elm does not
!  * use it.  Added debugging initializations to util/fastmail.c.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.9  1994/03/11  20:43:42  syd
!  * Fix ANSI prototype stripping macro
!  * From: "Tom Moore" <tmoore@fievel.DaytonOH.NCR.COM>
!  *
!  * Revision 5.8  1993/08/23  02:46:51  syd
!  * Test ANSI_C, not __STDC__ (which is not set on e.g. AIX).
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.7  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.6  1993/08/03  19:20:31  syd
!  * Implement new timezone handling.  New file lib/get_tz.c with new timezone
!  * routines.  Added new TZMINS_USE_xxxxxx and TZNAME_USE_xxxxxx configuration
!  * definitions.  Obsoleted TZNAME, ALTCHECK, and TZ_MINUTESWEST configuration
!  * definitions.  Updated Configure.  Modified lib/getarpdate.c and
!  * lib/strftime.c to use new timezone routines.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.5  1993/06/10  03:17:45  syd
!  * Change from TZNAME_MISSING to TZNAME
!  * From: Syd via request from Dan Blanchard
!  *
!  * Revision 5.4  1993/05/08  19:56:45  syd
!  * update to newer version
!  * From: Syd
!  *
!  * Revision 5.3  1993/04/21  01:42:23  syd
!  * avoid name conflicts on min and max
!  *
!  * Revision 5.2  1993/04/16  04:29:34  syd
!  * attempt to bsdize a bit strftime
!  * From: many via syd
!  *
!  * Revision 5.1  1993/01/27  18:52:15  syd
!  * Initial checkin of contributed public domain routine.
!  * This routine is provided as is and not covered by Elm Copyright.
!  *
!  *
!  *
!  ******************************************************************************/
  
  /*
   * strftime.c
--- 1,19 ----
  
! static char rcsid[] = "@(#)$Id: strftime.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * Public-domain relatively quick-and-dirty implemenation of
   * ANSI library routine for System V Unix systems.
   *
   * Arnold Robbins
   *
!  *****************************************************************************/
  
  /*
   * strftime.c
***************
*** 127,147 ****
  
  #include "headers.h"
  
! #ifdef I_TIME
! #  include <time.h>
! #endif
! #ifdef I_SYSTIME
! #  include <sys/time.h>
! #endif
! 
! #if ANSI_C
! # define P_(x) x
! #else
! # define P_(x) () /**/
! # define const	/**/
! #endif
! 
! #ifndef BSD
  extern void tzset P_((void));
  #endif
  static int weeknumber P_((const struct tm *timeptr, int firstweekday));
--- 54,60 ----
  
  #include "headers.h"
  
! #ifndef BSD_TYPE
  extern void tzset P_((void));
  #endif
  static int weeknumber P_((const struct tm *timeptr, int firstweekday));
***************
*** 284,290 ****
  			savetz = (char *) malloc(tzlen + 1);
  			if (savetz != NULL) {
  				savetzlen = tzlen + 1;
! 				strcpy(savetz, tz);
  			}
  		}
  		tzset();
--- 197,203 ----
  			savetz = (char *) malloc(tzlen + 1);
  			if (savetz != NULL) {
  				savetzlen = tzlen + 1;
! 				strfcpy(savetz, tz, savetzlen);
  			}
  		}
  		tzset();
***************
*** 297,306 ****
  			savetz = (char *) realloc(savetz, i);
  			if (savetz) {
  				savetzlen = i;
! 				strcpy(savetz, tz);
  			}
  		} else
! 			strcpy(savetz, tz);
  		tzset();
  	}
  #endif	/* POSIX_SEMANTICS */
--- 210,219 ----
  			savetz = (char *) realloc(savetz, i);
  			if (savetz) {
  				savetzlen = i;
! 				strfcpy(savetz, tz, savetzlen);
  			}
  		} else
! 			strfcpy(savetz, tz, savetzlen);
  		tzset();
  	}
  #endif	/* POSIX_SEMANTICS */
***************
*** 323,338 ****
  
  		case 'a':	/* abbreviated weekday name */
  			if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
! 				strcpy(tbuf, "?");
  			else
! 				strcpy(tbuf, days_a[timeptr->tm_wday]);
  			break;
  
  		case 'A':	/* full weekday name */
  			if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
! 				strcpy(tbuf, "?");
  			else
! 				strcpy(tbuf, days_l[timeptr->tm_wday]);
  			break;
  
  #ifdef SYSV_EXT
--- 236,253 ----
  
  		case 'a':	/* abbreviated weekday name */
  			if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
! 				strfcpy(tbuf, "?", sizeof tbuf);
  			else
! 				strfcpy(tbuf, days_a[timeptr->tm_wday],
! 					sizeof tbuf);
  			break;
  
  		case 'A':	/* full weekday name */
  			if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
! 				strfcpy(tbuf, "?", sizeof tbuf);
  			else
! 				strfcpy(tbuf, days_l[timeptr->tm_wday],
! 					sizeof tbuf);
  			break;
  
  #ifdef SYSV_EXT
***************
*** 340,376 ****
  #endif
  		case 'b':	/* abbreviated month name */
  			if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
! 				strcpy(tbuf, "?");
  			else
! 				strcpy(tbuf, months_a[timeptr->tm_mon]);
  			break;
  
  		case 'B':	/* full month name */
  			if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
! 				strcpy(tbuf, "?");
  			else
! 				strcpy(tbuf, months_l[timeptr->tm_mon]);
  			break;
  
  		case 'c':	/* appropriate date and time representation */
! 			sprintf(tbuf, "%s %s %2d %02d:%02d:%02d %d",
! 				days_a[range(0, timeptr->tm_wday, 6)],
! 				months_a[range(0, timeptr->tm_mon, 11)],
! 				range(1, timeptr->tm_mday, 31),
! 				range(0, timeptr->tm_hour, 23),
! 				range(0, timeptr->tm_min, 59),
! 				range(0, timeptr->tm_sec, 61),
! 				timeptr->tm_year + 1900);
  			break;
  
  		case 'd':	/* day of the month, 01 - 31 */
  			i = range(1, timeptr->tm_mday, 31);
! 			sprintf(tbuf, "%02d", i);
  			break;
  
  		case 'H':	/* hour, 24-hour clock, 00 - 23 */
  			i = range(0, timeptr->tm_hour, 23);
! 			sprintf(tbuf, "%02d", i);
  			break;
  
  		case 'I':	/* hour, 12-hour clock, 01 - 12 */
--- 255,296 ----
  #endif
  		case 'b':	/* abbreviated month name */
  			if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
! 				strfcpy(tbuf, "?", sizeof tbuf);
  			else
! 				strfcpy(tbuf, months_a[timeptr->tm_mon],
! 					sizeof tbuf);
  			break;
  
  		case 'B':	/* full month name */
  			if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
! 				strfcpy(tbuf, "?", sizeof tbuf);
  			else
! 				strfcpy(tbuf, months_l[timeptr->tm_mon],
! 					sizeof tbuf);
  			break;
  
  		case 'c':	/* appropriate date and time representation */
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				    FRM("%s %s %2d %02d:%02d:%02d %d"),
! 				    days_a[range(0, timeptr->tm_wday, 6)],
! 				    months_a[range(0, timeptr->tm_mon, 11)],
! 				    range(1, timeptr->tm_mday, 31),
! 				    range(0, timeptr->tm_hour, 23),
! 				    range(0, timeptr->tm_min, 59),
! 				    range(0, timeptr->tm_sec, 61),
! 				    timeptr->tm_year + 1900);
  			break;
  
  		case 'd':	/* day of the month, 01 - 31 */
  			i = range(1, timeptr->tm_mday, 31);
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%02d"), i);
  			break;
  
  		case 'H':	/* hour, 24-hour clock, 00 - 23 */
  			i = range(0, timeptr->tm_hour, 23);
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%02d"), i);
  			break;
  
  		case 'I':	/* hour, 12-hour clock, 01 - 12 */
***************
*** 379,462 ****
  				i = 12;
  			else if (i > 12)
  				i -= 12;
! 			sprintf(tbuf, "%02d", i);
  			break;
  
  		case 'j':	/* day of the year, 001 - 366 */
! 			sprintf(tbuf, "%03d", timeptr->tm_yday + 1);
  			break;
  
  		case 'm':	/* month, 01 - 12 */
  			i = range(0, timeptr->tm_mon, 11);
! 			sprintf(tbuf, "%02d", i + 1);
  			break;
  
  		case 'M':	/* minute, 00 - 59 */
  			i = range(0, timeptr->tm_min, 59);
! 			sprintf(tbuf, "%02d", i);
  			break;
  
  		case 'p':	/* am or pm based on 12-hour clock */
  			i = range(0, timeptr->tm_hour, 23);
  			if (i < 12)
! 				strcpy(tbuf, ampm[0]);
  			else
! 				strcpy(tbuf, ampm[1]);
  			break;
  
  		case 'S':	/* second, 00 - 61 */
  			i = range(0, timeptr->tm_sec, 61);
! 			sprintf(tbuf, "%02d", i);
  			break;
  
  		case 'U':	/* week of year, Sunday is first day of week */
! 			sprintf(tbuf, "%02d", weeknumber(timeptr, 0));
  			break;
  
  		case 'w':	/* weekday, Sunday == 0, 0 - 6 */
  			i = range(0, timeptr->tm_wday, 6);
! 			sprintf(tbuf, "%d", i);
  			break;
  
  		case 'W':	/* week of year, Monday is first day of week */
! 			sprintf(tbuf, "%02d", weeknumber(timeptr, 1));
  			break;
  
  		case 'x':	/* appropriate date representation */
! 			sprintf(tbuf, "%s %s %2d %d",
! 				days_a[range(0, timeptr->tm_wday, 6)],
! 				months_a[range(0, timeptr->tm_mon, 11)],
! 				range(1, timeptr->tm_mday, 31),
! 				timeptr->tm_year + 1900);
  			break;
  
  		case 'X':	/* appropriate time representation */
! 			sprintf(tbuf, "%02d:%02d:%02d",
! 				range(0, timeptr->tm_hour, 23),
! 				range(0, timeptr->tm_min, 59),
! 				range(0, timeptr->tm_sec, 61));
  			break;
  
  		case 'y':	/* year without a century, 00 - 99 */
  			i = timeptr->tm_year % 100;
! 			sprintf(tbuf, "%02d", i);
  			break;
  
  		case 'Y':	/* year with century */
! 			sprintf(tbuf, "%d", 1900 + timeptr->tm_year);
  			break;
  
  		case 'Z':	/* time zone name or abbrevation */
  #ifdef TZNAME_USE_TZNAME
  			i = (daylight && timeptr->tm_isdst);	/* 0 or 1 */
! 			strcpy(tbuf, tzname[i]);
  #else
  #ifdef TZNAME_USE_TM_ZONE
! 			strcpy(tbuf, timeptr->tm_zone);
  #else
  			gettimeofday(& tv, & zone);
! 			strcpy(tbuf, timezone(zone.tz_minuteswest,
! 						timeptr->tm_isdst));
  #endif
  #endif
  			break;
--- 299,394 ----
  				i = 12;
  			else if (i > 12)
  				i -= 12;
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%02d"), i);
  			break;
  
  		case 'j':	/* day of the year, 001 - 366 */
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%03d"), timeptr->tm_yday + 1);
  			break;
  
  		case 'm':	/* month, 01 - 12 */
  			i = range(0, timeptr->tm_mon, 11);
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%02d"), i + 1);
  			break;
  
  		case 'M':	/* minute, 00 - 59 */
  			i = range(0, timeptr->tm_min, 59);
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%02d"), i);
  			break;
  
  		case 'p':	/* am or pm based on 12-hour clock */
  			i = range(0, timeptr->tm_hour, 23);
  			if (i < 12)
! 				strfcpy(tbuf, ampm[0], sizeof tbuf);
  			else
! 				strfcpy(tbuf, ampm[1], sizeof tbuf);
  			break;
  
  		case 'S':	/* second, 00 - 61 */
  			i = range(0, timeptr->tm_sec, 61);
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%02d"), i);
  			break;
  
  		case 'U':	/* week of year, Sunday is first day of week */
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				    FRM("%02d"), weeknumber(timeptr, 0));
  			break;
  
  		case 'w':	/* weekday, Sunday == 0, 0 - 6 */
  			i = range(0, timeptr->tm_wday, 6);
! 			elm_sfprintf(tbuf, sizeof tbuf, FRM("%d"), i);
  			break;
  
  		case 'W':	/* week of year, Monday is first day of week */
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%02d"), weeknumber(timeptr, 1));
  			break;
  
  		case 'x':	/* appropriate date representation */
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%s %s %2d %d"),
! 				     days_a[range(0, timeptr->tm_wday, 6)],
! 				     months_a[range(0, timeptr->tm_mon, 11)],
! 				     range(1, timeptr->tm_mday, 31),
! 				     timeptr->tm_year + 1900);
  			break;
  
  		case 'X':	/* appropriate time representation */
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%02d:%02d:%02d"),
! 				     range(0, timeptr->tm_hour, 23),
! 				     range(0, timeptr->tm_min, 59),
! 				     range(0, timeptr->tm_sec, 61));
  			break;
  
  		case 'y':	/* year without a century, 00 - 99 */
  			i = timeptr->tm_year % 100;
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%02d"), i);
  			break;
  
  		case 'Y':	/* year with century */
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%d"), 1900 + timeptr->tm_year);
  			break;
  
  		case 'Z':	/* time zone name or abbrevation */
  #ifdef TZNAME_USE_TZNAME
  			i = (daylight && timeptr->tm_isdst);	/* 0 or 1 */
! 			strfcpy(tbuf, tzname[i], sizeof tbuf);
  #else
  #ifdef TZNAME_USE_TM_ZONE
! 			strfcpy(tbuf, timeptr->tm_zone, sizeof tbuf);
  #else
  			gettimeofday(& tv, & zone);
! 			strfcpy(tbuf, timezone(zone.tz_minuteswest,
! 					       timeptr->tm_isdst),
! 				sizeof tbuf);
  #endif
  #endif
  			break;
***************
*** 477,483 ****
  			break;
  
  		case 'e':	/* day of month, blank padded */
! 			sprintf(tbuf, "%2d", range(1, timeptr->tm_mday, 31));
  			break;
  
  		case 'r':	/* time as %I:%M:%S %p */
--- 409,417 ----
  			break;
  
  		case 'e':	/* day of month, blank padded */
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%2d"), 
! 				     range(1, timeptr->tm_mday, 31));
  			break;
  
  		case 'r':	/* time as %I:%M:%S %p */
***************
*** 495,501 ****
  
  #ifdef SUNOS_EXT
  		case 'k':	/* hour, 24-hour clock, blank pad */
! 			sprintf(tbuf, "%2d", range(0, timeptr->tm_hour, 23));
  			break;
  
  		case 'l':	/* hour, 12-hour clock, 1 - 12, blank pad */
--- 429,436 ----
  
  #ifdef SUNOS_EXT
  		case 'k':	/* hour, 24-hour clock, blank pad */
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%2d"), range(0, timeptr->tm_hour, 23));
  			break;
  
  		case 'l':	/* hour, 12-hour clock, 1 - 12, blank pad */
***************
*** 504,510 ****
  				i = 12;
  			else if (i > 12)
  				i -= 12;
! 			sprintf(tbuf, "%2d", i);
  			break;
  #endif
  
--- 439,445 ----
  				i = 12;
  			else if (i > 12)
  				i -= 12;
! 			elm_sfprintf(tbuf, sizeof tbuf, FRM("%2d"), i);
  			break;
  #endif
  
***************
*** 511,520 ****
  
  #ifdef VMS_EXT
  		case 'v':	/* date as dd-bbb-YYYY */
! 			sprintf(tbuf, "%02d-%3.3s-%4d",
! 				range(1, timeptr->tm_mday, 31),
! 				months_a[range(0, timeptr->tm_mon, 11)],
! 				timeptr->tm_year + 1900);
  			for (i = 3; i < 6; i++)
  				if (islower(tbuf[i]))
  					tbuf[i] = toupper(tbuf[i]);
--- 446,456 ----
  
  #ifdef VMS_EXT
  		case 'v':	/* date as dd-bbb-YYYY */
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%02d-%3.3s-%4d"),
! 				     range(1, timeptr->tm_mday, 31),
! 				     months_a[range(0, timeptr->tm_mon, 11)],
! 				     timeptr->tm_year + 1900);
  			for (i = 3; i < 6; i++)
  				if (islower(tbuf[i]))
  					tbuf[i] = toupper(tbuf[i]);
***************
*** 524,530 ****
  
  #ifdef POSIX2_DATE
  		case 'C':
! 			sprintf(tbuf, "%02d", (timeptr->tm_year + 1900) / 100);
  			break;
  
  
--- 460,468 ----
  
  #ifdef POSIX2_DATE
  		case 'C':
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%02d"), 
! 				     (timeptr->tm_year + 1900) / 100);
  			break;
  
  
***************
*** 547,559 ****
  			}
  		}
  #endif
! 			sprintf(tbuf, "%02d", iso8601wknum(timeptr));
  			break;
  
  		case 'u':
  		/* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */
! 			sprintf(tbuf, "%d", timeptr->tm_wday == 0 ? 7 :
! 					timeptr->tm_wday);
  			break;
  #endif	/* POSIX2_DATE */
  		default:
--- 485,499 ----
  			}
  		}
  #endif
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%02d"), iso8601wknum(timeptr));
  			break;
  
  		case 'u':
  		/* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */
! 			elm_sfprintf(tbuf, sizeof tbuf,
! 				     FRM("%d"), timeptr->tm_wday == 0 ? 7 :
! 				     timeptr->tm_wday);
  			break;
  #endif	/* POSIX2_DATE */
  		default:
***************
*** 565,571 ****
  		i = strlen(tbuf);
  		if (i) {
  			if (s + i < endp - 1) {
! 				strcpy(s, tbuf);
  				s += i;
  			} else
  				return 0;
--- 505,511 ----
  		i = strlen(tbuf);
  		if (i) {
  			if (s + i < endp - 1) {
! 				strfcpy(s, tbuf, maxsize - (s-start));
  				s += i;
  			} else
  				return 0;
Index: elm2.4.ME+.50/lib/strincmp.c
*** elm2.4.25/lib/strincmp.c	Tue Aug  3 22:28:58 1993
--- elm2.4.ME+.50/lib/strincmp.c	Tue Nov 17 21:14:08 1998
***************
*** 1,36 ****
  
! static char rcsid[] = "@(#)$Id: strincmp.c,v 5.2 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: strincmp.c,v $
!  * Revision 5.2  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** compare strings ignoring case - length limited
  **/
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: strincmp.c,v 1.3 1998/11/08 18:21:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** compare strings ignoring case - length limited
  **/
***************
*** 37,49 ****
  
  #include "headers.h"
  
! int
! strincmp(s1,s2,n)
! register char *s1, *s2;
! register int n;
  {
  	/* case insensitive comparison */
! 	register int d;
  	while (--n >= 0) {
  	  d = (tolower(*s1) - tolower(*s2));
  	  if ( d != 0 || *s1 == '\0' || *s2 == '\0' )
--- 17,32 ----
  
  #include "headers.h"
  
! /* Is this needed? This is same than strncasecmp 
!  *        - K E H <hurtta@ozone.FMI.FI>
!  */
! 
! int strincmp(s1,s2,n)
!      const char *s1, *s2;
!      int n;
  {
  	/* case insensitive comparison */
! 	int d;
  	while (--n >= 0) {
  	  d = (tolower(*s1) - tolower(*s2));
  	  if ( d != 0 || *s1 == '\0' || *s2 == '\0' )
Index: elm2.4.ME+.50/lib/striparens.c
*** elm2.4.25/lib/striparens.c	Thu Jun 10 06:09:06 1993
--- elm2.4.ME+.50/lib/striparens.c	Tue Nov 17 21:12:55 1998
***************
*** 1,28 ****
! static char rcsid[] = "@(#)$Id: striparens.c,v 5.2 1993/06/10 03:09:06 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: striparens.c,v $
!  * Revision 5.2  1993/06/10  03:09:06  syd
!  * Greatly simplified "lib/striparens.c" to use new rfc822_toklen() routine.
!  * This cut more than 50% out of the object size.  Also added _TEST case.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /* 
   * strip_parens() - Delete all (parenthesized) information from a string.
--- 1,15 ----
! static char rcsid[] = "@(#)$Id: striparens.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /* 
   * strip_parens() - Delete all (parenthesized) information from a string.
***************
*** 39,77 ****
  static char paren_buffer[VERY_LONG_STRING];
  
  char *strip_parens(src)
! register char *src;
  {
! 	register int len;
! 	register char *dest = paren_buffer;
! 
! 	while (*src != '\0') {
! 		len = rfc822_toklen(src);
! 		if (*src != '(') {	/*)*/
! 			strncpy(dest, src, len);
! 			dest += len;
! 		}
! 		src += len;
! 	}
! 	*dest = '\0';
! 	return paren_buffer;
  }
  
  char *get_parens(src)
! register char *src;
  {
! 	register int len;
! 	register char *dest = paren_buffer;
! 
! 	while (*src != '\0') {
! 		len = rfc822_toklen(src);
! 		if (len > 2 && *src == '(') {	/*)*/
! 			strncpy(dest, src+1, len-2);
! 			dest += (len-2);
! 		}
! 		src += len;
! 	}
! 	*dest = '\0';
! 	return paren_buffer;
  }
  
  #ifdef _TEST
--- 26,85 ----
  static char paren_buffer[VERY_LONG_STRING];
  
  char *strip_parens(src)
!      const char *src;
  {
!   int len;
!   char *dest = paren_buffer;
!   const char *src0 = src;
! 
!   while (*src != '\0') {
!     len = rfc822_toklen(src);		
!     if (*src != '(') {	/*)*/
!       if ((dest-paren_buffer) + len < sizeof paren_buffer -1) {
! 	strncpy(dest, src, len);
! 	dest += len;
!       } else {
! 	dprint(1,(debugfile,
! 		  "strip_parens: --- too long string (max=%d): %.30s...\n",
! 		  sizeof paren_buffer,src0));	
! 	dprint(1,(debugfile,
! 		  "strip_parens: next token: %.*s\n",len,src));
! 	break;
!       }
!     }
!     src += len;
!   }
!   *dest = '\0';
!   return paren_buffer;
  }
  
  char *get_parens(src)
!      const char *src;
  {
!   int len;
!   char *dest = paren_buffer;
!   const char *src0 = src;
! 
!   while (*src != '\0') {
!     len = rfc822_toklen(src);
!     if (len > 2 && *src == '(') {	/*)*/
!       if ((dest-paren_buffer) + len < sizeof paren_buffer) {	
! 	strncpy(dest, src+1, len-2);
! 	dest += (len-2);
!       } else {
! 	dprint(1,(debugfile,
! 		  "get_parens: --- too long string (max=%d): %.30s...\n",
! 		  sizeof paren_buffer,src0));	
! 	dprint(1,(debugfile,
! 		  "get_parens: next token: %.*s\n",len,src));
! 	break;
!       }
! 
!     }
!     src += len;
!   }
!   *dest = '\0';
!   return paren_buffer;
  }
  
  #ifdef _TEST
Index: elm2.4.ME+.50/lib/strmcpy.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/lib/strmcpy.c	Tue Nov 17 21:14:08 1998
***************
*** 0 ****
--- 1,43 ----
+ static char rcsid[] = "@(#)$Id: strmcpy.c,v 1.2 1998/11/16 17:08:30 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *
+  *  Initially written by: Michael Elkins <elkins@aero.org>, 1995
+  *****************************************************************************/
+ 
+ #include "defs.h"
+ #include "elmlib.h"
+ 
+ char * strmcpy (dest, src)
+      char *dest;
+      const char *src;
+ {
+ 	int len = strlen (src) + 1;
+ 
+ 	if (dest)
+ 		dest = (char *) safe_realloc (dest, len);
+ 	else
+ 		dest = (char *) safe_malloc (len);
+ 	strfcpy (dest, src, len);
+ 	return dest;
+ }
+ 
+ 
+ char * strmcat (dest, src)
+      char *dest;
+      const char *src;
+ {
+ 	int len;
+ 
+ 	if (!dest)
+ 	  return strmcpy(dest,src);
+ 
+ 	len = strlen (src) + 1 + strlen(dest);
+ 
+ 	dest = (char *) safe_realloc (dest, len);
+ 	strfcat (dest, src, len);
+ 	return dest;
+ }
Index: elm2.4.ME+.50/lib/strstr.c
*** elm2.4.25/lib/strstr.c	Sun Oct  4 01:42:30 1992
--- elm2.4.ME+.50/lib/strstr.c	Tue Nov 17 21:12:55 1998
***************
*** 1,24 ****
  
! static char rcsid[] = "@(#)$Id: strstr.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: strstr.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** look for substring in string
  **/
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: strstr.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** look for substring in string
  **/
***************
*** 49,55 ****
   */
  
  char *strstr(s1, s2)
! char *s1, *s2;
  {
  	int len;
  	char *ptr;
--- 41,47 ----
   */
  
  char *strstr(s1, s2)
!      char *s1, *s2;
  {
  	int len;
  	char *ptr;
Index: elm2.4.ME+.50/lib/strtokq.c
*** elm2.4.25/lib/strtokq.c	Tue Jul 20 05:05:17 1993
--- elm2.4.ME+.50/lib/strtokq.c	Tue Nov 17 21:12:56 1998
***************
*** 1,43 ****
  
! static char rcsid[] = "@(#)$Id: strtokq.c,v 5.3 1993/07/20 02:05:17 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: strtokq.c,v $
!  * Revision 5.3  1993/07/20  02:05:17  syd
!  * A long-standing bug of handling replies to VMS systems.
!  * Original "From: " -line is of format:
!  * 	From: "NAME \"Real Name\"" <USERNAME@vms-system>
!  * (PMDF mailer)
!  * 	Anyway,  parse_arpa_who()  strips quotes too cleanly
!  * resulting data:
!  * 	NAME \"Real Name\
!  * which, when put into parenthesis, becomes:
!  * 	(NAME \"Real Name\)
!  * which in its turn lacks closing `)'
!  * Patch of  lib/parsarpwho.c  fixes that.
!  * strtokq() started one position too late to search for next double-quote (") char.
!  * Another one-off (chops off trailing comment character, quote or not..)  in   src/reply.c
!  * From:	Matti Aarnio <mea@utu.fi>
!  *
!  * Revision 5.2  1993/02/03  16:20:30  syd
!  * add include file
!  *
!  * Revision 5.1  1993/02/03  16:19:31  syd
!  * Initial checkin, taken from filter/parse.c
!  *
!  *
!  ******************************************************************************/
  
  
  /* Like strtok, but returns quoted strings as one token (quotes removed)
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: strtokq.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  
  /* Like strtok, but returns quoted strings as one token (quotes removed)
***************
*** 46,54 ****
  
  #include "headers.h"
  
  char *strtokq(source, keys, flag)
! char *source, *keys;
! int flag;
  {
  	register int  last_ch;
  	static   char *sourceptr = NULL;
--- 19,31 ----
  
  #include "headers.h"
  
+ /* Why there is ' -- it is not quote character in mail.
+  *    - K E H <hurtta@ozone.FMI.FI>
+  */
+ 
  char *strtokq(source, keys, flag)
!      char *source, *keys;
!      int flag;
  {
  	register int  last_ch;
  	static   char *sourceptr = NULL;
Index: elm2.4.ME+.50/lib/tail_of.c
*** elm2.4.25/lib/tail_of.c	Sun Oct  4 01:42:30 1992
--- elm2.4.ME+.50/lib/tail_of.c	Tue Nov 17 21:12:56 1998
***************
*** 1,23 ****
! static char rcsid[] = "@(#)$Id: tail_of.c,v 5.1 1992/10/03 22:41:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: tail_of.c,v $
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  
--- 1,15 ----
! static char rcsid[] = "@(#)$Id: tail_of.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  
***************
*** 26,34 ****
  #include "headers.h"
  
  
! int
! tail_of(from, buffer, to)
! char *from, *buffer, *to;
  {
  	/** Return last two words of 'from'.  This is to allow
  	    painless display of long return addresses as simply the
--- 18,26 ----
  #include "headers.h"
  
  
! int tail_of(from, buffer, to, size)
!      char *from, *buffer, *to;
!      int size;
  {
  	/** Return last two words of 'from'.  This is to allow
  	    painless display of long return addresses as simply the
***************
*** 52,71 ****
  
  	register int loc, i = 0, cnt = 0, using_to = 0;
  	
- #ifndef INTERNET
- 	
- 	/** let's see if we have an address appropriate for hacking: 
- 	    what this actually does is remove the spuriously added
- 	    local bogus Internet header if we have one and the message
- 	    has some sort of UUCP component too...
- 	**/
- 
- 	sprintf(buffer, "@%s", hostfullname); 
- 	if (chloc(from,'!') != -1 && in_string(from, buffer))
- 	   from[strlen(from)-strlen(buffer)] = '\0';
- 
- #endif
- 
  	/**
  	    Produce a simplified version of the from into buffer.  If the
  	    from is just "username" or "Full Username" it will be preserved.
--- 44,49 ----
***************
*** 72,78 ****
  	    If it is an address, the rightmost "stuff!stuff", "stuff@stuff",
  	    or "stuff:stuff" will be used.
  	**/
! 	for (loc = strlen(from)-1; loc >= 0 && cnt < 2; loc--) {
  	  if (from[loc] == BANG || from[loc] == AT_SIGN ||
  	      from[loc] == COLON) cnt++;
  	  if (cnt < 2) buffer[i++] = from[loc];
--- 50,56 ----
  	    If it is an address, the rightmost "stuff!stuff", "stuff@stuff",
  	    or "stuff:stuff" will be used.
  	**/
! 	for (loc = strlen(from)-1; loc >= 0 && cnt < 2 && i < size; loc--) {
  	  if (from[loc] == BANG || from[loc] == AT_SIGN ||
  	      from[loc] == COLON) cnt++;
  	  if (cnt < 2) buffer[i++] = from[loc];
***************
*** 83,92 ****
  #ifdef MMDF
  	if (strlen(buffer) == 0) {
  	  if(to && *to != '\0' && !addr_matches_user(to, username)) {
! 	    tail_of(to, buffer, (char *)0);
  	    using_to = 1;
  	  } else
! 	    strcpy(buffer, full_username);
          }
  #endif /* MMDF */
  
--- 61,70 ----
  #ifdef MMDF
  	if (strlen(buffer) == 0) {
  	  if(to && *to != '\0' && !addr_matches_user(to, username)) {
! 	    tail_of(to, buffer, (char *)0, size);
  	    using_to = 1;
  	  } else
! 	    strfcpy(buffer, full_username, size);
          }
  #endif /* MMDF */
  
***************
*** 100,110 ****
  	   */
  
  	  if(to && *to != '\0' && !addr_matches_user(to, username)) {
! 	    tail_of(to, buffer, (char *)0);
  	    using_to = 1;
  	  } else
! 	    strcpy(buffer, full_username);
  
  	} else {					/* user%host@host? */
  
  	  /** The logic here is that we're going to use 'loc' as a handy
--- 78,91 ----
  	   */
  
  	  if(to && *to != '\0' && !addr_matches_user(to, username)) {
! 	    tail_of(to, buffer, (char *)0, size);
  	    using_to = 1;
  	  } else
! 	    strfcpy(buffer, full_username, size);
  
+ 	} else if (showto && to != 0 && strcmp (to, username) != 0) {
+ 		tail_of (to, buffer, (char *)0, size);
+ 		using_to = 1;
  	} else {					/* user%host@host? */
  
  	  /** The logic here is that we're going to use 'loc' as a handy
Index: elm2.4.ME+.50/lib/validname.c
*** elm2.4.25/lib/validname.c	Fri Dec 11 03:45:28 1992
--- elm2.4.ME+.50/lib/validname.c	Tue Nov 17 21:12:56 1998
***************
*** 1,36 ****
  
! static char rcsid[] = "@(#)$Id: validname.c,v 5.3 1992/12/11 01:45:04 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: validname.c,v $
!  * Revision 5.3  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.2  1992/12/07  04:55:16  syd
!  * add sys/types include for time_t
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:41:36  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  #include <stdio.h>
  #include "defs.h"
  
  #ifndef NOCHECK_VALIDNAME		 /* Force a return of valid */
  # ifdef PWDINSYS
--- 1,20 ----
  
! static char rcsid[] = "@(#)$Id: validname.c,v 1.2 1998/10/20 19:57:48 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  #include <stdio.h>
  #include "defs.h"
+ #include "elmlib.h"
  
  #ifndef NOCHECK_VALIDNAME		 /* Force a return of valid */
  # ifdef PWDINSYS
***************
*** 40,48 ****
  # endif
  #endif
  
! int
! valid_name(name)
! char *name;
  {
  	/** Determine whether "name" is a valid logname on this system.
  	    It is valid if there is a password entry, or if there is
--- 24,33 ----
  # endif
  #endif
  
! /* This is quite bogus   - K E H <hurtta@ozone.FMI.FI> */
! 
! int valid_name(name)
!      char *name;
  {
  	/** Determine whether "name" is a valid logname on this system.
  	    It is valid if there is a password entry, or if there is
***************
*** 61,67 ****
  	if(getpwnam(name) != NULL)
  	  return(TRUE);
  
! 	sprintf(filebuf,"%s/%s", mailhome, name);
  	if (access(filebuf, ACCESS_EXISTS) == 0)
  	  return(TRUE);
  
--- 46,53 ----
  	if(getpwnam(name) != NULL)
  	  return(TRUE);
  
! 	elm_sfprintf(filebuf,sizeof filebuf,
! 		     FRM("%s/%s"), mailhome, name);
  	if (access(filebuf, ACCESS_EXISTS) == 0)
  	  return(TRUE);
  
Index: elm2.4.ME+.50/nls/C/C/C/s_aliases.m
*** elm2.4.25/nls/C/C/C/s_aliases.m	Sat Jun 12 08:26:18 1993
--- elm2.4.ME+.50/nls/C/C/C/s_aliases.m	Tue Nov 17 21:12:56 1998
***************
*** 243,245 ****
--- 243,247 ----
  143	T = Tag current alias and go to next alias.
  $ #Modified
  144	"(modified, resync needed) "
+ $ #AddressAs1
+ 145	Messages addressed as: %s
Index: elm2.4.ME+.50/nls/C/C/C/s_elm.m
*** elm2.4.25/nls/C/C/C/s_elm.m	Tue Aug  3 21:58:06 1993
--- elm2.4.ME+.50/nls/C/C/C/s_elm.m	Tue Nov 17 21:12:56 1998
***************
*** 451,459 ****
  $ #HdrmenuScreenTitle
  229	Message Header Edit Screen
  $ #HdrmenuInstruct
! 230	Choose header, u)ser defined header, d)omainize, !)shell, or <return>.
  $ #HdrmenuInstructNoShell
! 231	Choose header, u)ser defined header, d)omainize, or <return>.
  $quote "
  $ #HdrmenuPrompt
  232	"Choice: "
--- 451,459 ----
  $ #HdrmenuScreenTitle
  229	Message Header Edit Screen
  $ #HdrmenuInstruct
! 230	Choose header, u)ser defined header, !)shell, or <return>.
  $ #HdrmenuInstructNoShell
! 231	Choose header, u)ser defined header, or <return>.
  $quote "
  $ #HdrmenuPrompt
  232	"Choice: "
***************
*** 476,487 ****
  240	The user-defined header must begin with a letter or number.
  $ #HdrmenuUserdefMissingColon
  241	The user-defined header must have a colon after the field name.
- $ #HdrmenuDomInstruct
- 242	Select header to domainize:  T)o, C)c, B)cc, or <return>.
- $quote "
- $ #HdrmenuDomPrompt
- 243	"Domainize choice: "
- $quote
  $ #HelpMessage
  255	Press the key you want help for, '?' for a key list, or '.' to exit help
  $ #HelpPrompt
--- 476,481 ----
***************
*** 603,609 ****
  $ #HelpMakeMessageCurrent
  313	<number> = Make specified number the current message.
  $ #YouHaveNoPasswordEntry
! 314	You have no password entry!\r\n
  $ #CouldNotOpenDebugFile
  315	Could not open file %s for debug output!\n
  $ #NoTerm
--- 597,603 ----
  $ #HelpMakeMessageCurrent
  313	<number> = Make specified number the current message.
  $ #YouHaveNoPasswordEntry
! 314	You have no password entry!
  $ #CouldNotOpenDebugFile
  315	Could not open file %s for debug output!\n
  $ #NoTerm
***************
*** 787,793 ****
  $ #NoEncryptInBatch
  411	Sorry. Cannot send encrypted mail in "batch mode".\n
  $ #WriteFailedCopyAcross
! 412	\nWrite failed in copy_message_across\n
  $ #BounceOffRemote
  413	"Bounce" a copy off the remote machine? (%c/%c) "
  $ #WarningBlankIgnored
--- 781,787 ----
  $ #NoEncryptInBatch
  411	Sorry. Cannot send encrypted mail in "batch mode".\n
  $ #WriteFailedCopyAcross
! 412	Write failed in copy_message_across\n
  $ #BounceOffRemote
  413	"Bounce" a copy off the remote machine? (%c/%c) "
  $ #WarningBlankIgnored
***************
*** 988,994 ****
  $ #MatchSeekFailed
  522	ELM [match] failed looking %ld bytes into file (%s).
  $ #CouldntMallocBytes
! 523	\n\nCouldn't malloc %d bytes!!\n\n
  $ #ChangeToWhichFolder
  524	"Change to which folder: "
  $quote
--- 982,988 ----
  $ #MatchSeekFailed
  522	ELM [match] failed looking %ld bytes into file (%s).
  $ #CouldntMallocBytes
! 523	Couldn't malloc %d bytes!!
  $ #ChangeToWhichFolder
  524	"Change to which folder: "
  $quote
***************
*** 1000,1010 ****
  \t -dn\t\tDebug - set debug level to 'n'\n\r\
  \t -fx\t\tFolder - read folder 'x' rather than incoming mailbox\n\r\
  \t -h \t\tHelp - give this list of options\n\r\
! \t -ix\t\tInclude prepared file 'x' in edit buffer for send\n\r\
! \t -k \t\tKeypad - enable HP 2622 terminal keyboard\n\r
  $ #ArgsHelp2
! 536	\t -K \t\tKeypad&softkeys - enable use of softkeys + "-k"\n\r\
! \t -m \t\tMenu - Turn off menu, using more of the screen\n\r\
  \t -sx\t\tSubject 'x' - for batch mailing\n\r\
  \t -t \t\tTiTe - don't use termcap/terminfo ti/te entries.\n\r\
  \t -V \t\tEnable sendmail voyeur mode.\n\r\
--- 994,1002 ----
  \t -dn\t\tDebug - set debug level to 'n'\n\r\
  \t -fx\t\tFolder - read folder 'x' rather than incoming mailbox\n\r\
  \t -h \t\tHelp - give this list of options\n\r\
! \t -ix\t\tInclude prepared file 'x' in edit buffer for send\n\r
  $ #ArgsHelp2
! 536	\t -m \t\tMenu - Turn off menu, using more of the screen\n\r\
  \t -sx\t\tSubject 'x' - for batch mailing\n\r\
  \t -t \t\tTiTe - don't use termcap/terminfo ti/te entries.\n\r\
  \t -V \t\tEnable sendmail voyeur mode.\n\r\
***************
*** 1041,1056 ****
  $ #CouldNotOpenNewElmrc
  554	Warning: could not open new ".elm/elmrc" file! Using default parameters.\n\r
  $ #BadSortKeyInElmrc
! 555	I can't understand sort key "%s" in line %d in your ".elm/elmrc" file\n\r
  $ #BadAliasSortInElmrc
! 556	I can't understand alias sort key "%s" in line %d in your ".elm/elmrc" file\n\r
  $ #SignatureObsolete
! 557	"signature" used in obsolete way in .elm/elmrc file. Ignored!\n\r\
! \t(Signature should specify the filename to use rather than on/off.)\n\r\n
  $ #BouncebackGTMaxhops
  558	Warning: bounceback is set to greater than %d (max-hops). Ignored.\n\r
  $ #TimeoutLTTen
! 559	Warning: timeout is set to less than 10 seconds. Ignored.\n\r
  $ #BadLineElmrc
  560	I can't understand line %d in your ".elm/elmrc" file:\n\r> %s\n\r
  $ #BatchNoticeFoldersDir
--- 1033,1048 ----
  $ #CouldNotOpenNewElmrc
  554	Warning: could not open new ".elm/elmrc" file! Using default parameters.\n\r
  $ #BadSortKeyInElmrc
! 555	I can't understand sort key "%s" in line %d in "%s" file
  $ #BadAliasSortInElmrc
! 556	I can't understand alias sort key "%s" in line %d in "%s" file
  $ #SignatureObsolete
! 557	"signature" used in obsolete way in .elm/elmrc file. Ignored!\n\
! \t(Signature should specify the filename to use rather than on/off.)
  $ #BouncebackGTMaxhops
  558	Warning: bounceback is set to greater than %d (max-hops). Ignored.\n\r
  $ #TimeoutLTTen
! 559	Warning: timeout is set to less than 10 seconds. Ignored.
  $ #BadLineElmrc
  560	I can't understand line %d in your ".elm/elmrc" file:\n\r> %s\n\r
  $ #BatchNoticeFoldersDir
***************
*** 1063,1075 ****
  ELM requires the use of a folders directory to store your mail folders in.\n\r\
  Shall I create the directory %s for you (%c/%c/q)? %c%c
  $ #TooManyWeedHeaders
! 563	Too many weed headers!  Leaving...\n\r
  $ #TooManyWeedPmalloc
! 564	Too many weed headers! Out of memory!  Leaving...\n\r
  $ #NoMemDefaultWeed
! 565	\nNot enough memory for default weedlist. Leaving.\n
  $ #CannotInitErrorExpanding
! 566	\r\nCannot initialize "%s" - error expanding "%s".\r\n
  $ #CouldntMakeTempFileName
  567	Sorry - couldn't make file temp file name.
  $ #CouldntOpenForWriting
--- 1055,1067 ----
  ELM requires the use of a folders directory to store your mail folders in.\n\r\
  Shall I create the directory %s for you (%c/%c/q)? %c%c
  $ #TooManyWeedHeaders
! 563	Too many weed headers!  Leaving...
  $ #TooManyWeedPmalloc
! 564	Too many weed headers! Out of memory!  Leaving...
  $ #NoMemDefaultWeed
! 565	Not enough memory for default weedlist. Leaving.
  $ #CannotInitErrorExpanding
! 566	Cannot initialize "%s" - error expanding "%s".
  $ #CouldntMakeTempFileName
  567	Sorry - couldn't make file temp file name.
  $ #CouldntOpenForWriting
***************
*** 1423,1447 ****
  $ #SortUnknown
  740	*UNKNOWN-SORT-PARAMETER*
  $ #EnterLastSelected
! 741	Enter: {"subject","to","from"} [pattern] OR "all"
  $ #EnterSelected
! 742	Enter: {"subject","to","from"} [pattern]
  $ #HelpUndeletePattern
  743	^U = Undelete all messages with the specified pattern.
  $ #NoIncludeFilename
! 744	\n\rNo Filename given, include line ignored\n\r
  $ #NoContentTypeGiven
! 745	\n\rNo Content-type given, include line ignored\n\r
  $ #EncodingIsIllegal
! 746	\n\rEncoding is illegal\n\r
  $ #IncludeCannotAccess
! 747	\n\rInclude File can't be accessed\n\r
  $ #UnknownEncodingInInclude
  748	\n\rUnknown Encoding, include line ignored\n\r
  $ #CantStatIncludedFile
  749	\n\rCan't stat included File,ignored\n\r
  $ #CantOpenIncludedFile
! 750	\nCan't open included File\n
  $ #PressAnyKeyIndex
  751	Press any key to return to index.
  $ #ArgsInclFileNotSend
--- 1415,1439 ----
  $ #SortUnknown
  740	*UNKNOWN-SORT-PARAMETER*
  $ #EnterLastSelected
! 741	Enter: {"subject","to","from","cc"} [pattern] OR {"thread","tagged","all"}
  $ #EnterSelected
! 742	Enter: {"subject","to","from"} [pattern] OR {"thread","tagged"}
  $ #HelpUndeletePattern
  743	^U = Undelete all messages with the specified pattern.
  $ #NoIncludeFilename
! 744	No Filename given, include line ignored
  $ #NoContentTypeGiven
! 745	No Content-type given, include line ignored
  $ #EncodingIsIllegal
! 746	Encoding is illegal
  $ #IncludeCannotAccess
! 747	Include File can't be accessed
  $ #UnknownEncodingInInclude
  748	\n\rUnknown Encoding, include line ignored\n\r
  $ #CantStatIncludedFile
  749	\n\rCan't stat included File,ignored\n\r
  $ #CantOpenIncludedFile
! 750	Can't open included File
  $ #PressAnyKeyIndex
  751	Press any key to return to index.
  $ #ArgsInclFileNotSend
***************
*** 1559,1565 ****
  $ #CouldntSeekBytesIntoTempFile
  822	\nCouldn't seek %ld bytes into temp file.\n
  $ #CannotExpand
! 823	Cannot expand alias '%s'!\n\r
  $ #NoItemToScan
  824	No %s to scan!
  $quote "
--- 1551,1557 ----
  $ #CouldntSeekBytesIntoTempFile
  822	\nCouldn't seek %ld bytes into temp file.\n
  $ #CannotExpand
! 823	Cannot expand alias '%s'!
  $ #NoItemToScan
  824	No %s to scan!
  $quote "
***************
*** 1585,1593 ****
  $ #OptionReturnHelp
  834	i,q = Return from option menu.
  $ #ReadMessageIncrement
! 835	Warning: readmsginc is set to less than 1.  Ignored.\n\r
  $ #SleepMessageInvalid
! 836	Warning: sleepmsg is set to less than 0.  Setting to 0.\n\r
  $ #VfyPromptPleaseChoose
  837	Please choose one of the following options by parenthesized letter: s
  $ #VfyMenuUser0
--- 1577,1585 ----
  $ #OptionReturnHelp
  834	i,q = Return from option menu.
  $ #ReadMessageIncrement
! 835	Warning: readmsginc is set to less than 1.  Ignored.
  $ #SleepMessageInvalid
! 836	Warning: sleepmsg is set to less than 0.  Setting to 0.
  $ #VfyPromptPleaseChoose
  837	Please choose one of the following options by parenthesized letter: s
  $ #VfyMenuUser0
***************
*** 1614,1616 ****
--- 1606,1942 ----
  847	Message kept.  Can be restored at next f)orward, m)ail or r)eply.
  $ #VfyNoFieldsInForm
  848	No fields in form!\007
+ $ #HelpViewAttach
+ 849	v = View Attachments in current message.
+ $ #BadModeInElmrc
+ 850	I can't understand file permissions "%s" in line %d in "%s" file
+ $ #BadKeyInElmrc
+ 851	I can't understand keyword "%s" in line %d in "%s" file
+ $ #SendingMailBackground
+ 852	Sending mail... in background
+ $ #ResendingMailBackground
+ 853	Resending mail... in background
+ $ #CouldntLockFolder
+ 854	Couldn't lock folder %s!
+ $ #IncludeBINARY
+ 855	Include file has BINARY data.
+ $ #Include8BIT
+ 856	Include file has 8BIT data.
+ $ #Doesnt8BIT
+ 857	Mailer (MTA) doesn't support 8BIT encoding.
+ $ #DoesntBINARY
+ 858	Mailer (MTA) doesn't support BINARY encoding!
+ $ #DontEncoding
+ 859	Content-Type don't allow encoding -- ignoring this part.
+ $ #CantMetamail
+ 860	Can't execute metamail: %s.30: %.30s
+ $ #FolderRemoved
+ 861	Folder removed.
+ $ #BadEKeyInElmrc
+ 862	I can't understand %s key "%s" in line %d in "%s" file
+ $ #BadEKeyValues
+ 863	Possible values are:
+ $ #LongValueInElmrc
+ 864	Value of "%s" in line %d in "%s" file is too long
+ $ #BackgroundLLT
+ 865	Warning: background_wait_time is set less than 0. Setting to 0.
+ $ #ErrorReading
+ 866	Error reading from %.50s
+ $ #ErrorReadableUser
+ 867	%.50s isn't readable by user!	
+ $ #CantOpenAttach
+ 868	Can't open attachment: %.50s
+ $ #InternalnoFD
+ 869	Internal error: no parent fd!
+ $ #FailedSeekAttach
+ 870	Failed to seek beginning of attachment!
+ $ #WriteErrorAttach
+ 871	Write error when copying attachment!
+ $ #ErrorCreatTempfile
+ 872	Error creating tempfile %s
+ $ #JobSpooled
+ 873	Print job spooled.
+ $ #ErrorPrinting
+ 874	Error while printing!
+ $ #NotKnowPrint
+ 875	Don't know how to print this type of data!
+ $ #MailNotSaved
+ 876	Mail not saved.
+ $ #NoPermissionWrite
+ 875	You do not have permission to write that file!
+ $ #ErrorOpening
+ 876	Error opening file!
+ $ #UnsupportedEncoding
+ 877	Unsupported encoding! Decode manually!
+ $ #ErrorSaving
+ 878	Error saving file!
+ $ #MailSaved
+ 879	Mail saved.
+ $ #CantStat
+ 880	Can't stat file!
+ $ #CouldOpenReading
+ 881	Could not open file for reading!
+ $ #StrucredNoEncoding
+ 882	%.30s: Structured types don't allow encoding of data.
+ $ #NotKnowPrint
+ 883	Don't know how to print this type of data!
+ $ #MailNotSaved
+ 884	Mail not saved.
+ $ #CantRenameTmpFile
+ 885	Could not rename temporary file!
+ $ #CantLinkTmpFile
+ 886	Could not create link to temporary file!
+ $ #CantUnLinkTmpFile
+ 887	Could not unlink temporary file!
+ $ #PgpNonZeroValue
+ 888	Pgp returned a non-zero value!
+ $ #RunningPgp
+ 889	Running PGP...
+ $ #FailSignal
+ 890	%.30s fail: Signal?
+ $ #FailErrno
+ 891	Failed: %.30s: %.40s
+ $ #PgpErrorStatus
+ 892	Pgp returned error status %d
+ $ #PgpDone
+ 893	Running PGP... Done.
+ $ #LostErrno
+ 894	%.30s lost: %.40s
+ $ #CantStart
+ 895	Can't start %.30s
+ $ #OpenTmpWriting
+ 896	Could not open temp file %.30s for writing!
+ $ #CantChangeFilename
+ 897	You can't change filename!
+ $ #ErrorAccess
+ 898	%.45s: %.33s
+ $ #WarningBINARY
+ 899	Warning: BINARY data? Check Content-Type!
+ $ #StructuredNoencoding
+ 900	Structured types don't allow encoding of data.
+ $ #StructuredLeaf
+ 901	Structured types must be encoded in leaf type!
+ $ #UnknownCommand2
+ 902	Unknown command.
+ $ #FileNotExist
+ 903	That file %.20s does not exist!
+ $ #CantStatFile
+ 904	Could not stat file %.20s!
+ $ #NotReadableByUser
+ 905	%.50s isn't readable by user!
+ $ #CheckingEncoding
+ 906	Checking %s...
+ $ #CantOpenFile
+ 907	Can't open %s!
+ $ #NoAttachments
+ 908	There are no attachments!
+ $ #LastAttachment
+ 909	You are on the last attachment!
+ $ #FirstAttachment
+ 910	You are on the first attachment!
+ $ #PassphraseForgotten
+ 911	Passphrase forgotten!
+ $ #UnknownCommand3
+ 912	Unknown command: %c
+ $ #BuiltInMore
+ 913	MORE (you've seen %d%%):
+ $ #PgpMultipleKeys
+ 914	Multiple keys match '%s':
+ $ #PgpPublicKey
+ 915	PGP public key for %s
+ $ #RemailTo
+ 916	Remail to %.50s...
+ $ #MsgDeleted
+ 917	Message deleted.
+ $ #MsgsDeleted
+ 918	%d messages deleted.
+ $ #PagerStatDeleted
+ 919	[Deleted] %d/%d 
+ $ #PagerStatMessage
+ 920	Message %d/%d 
+ $ #PagerFailedTmpFile
+ 921	Failed to create temporary file!
+ $ #AttachMenu
+ 922	Attachment Menu (%d attachments)
+ $ #ErrorReadMailfile
+ 923	Error when reading mailfile %s
+ $ #ForwardedMesg
+ 924	Forwarded message from %s
+ $ #MailTo
+ 925	Mail to %.50s...
+ $ #FailFileForward
+ 926	Failed to create file for forwarding
+ $ #UsingUNKNOWN8BIT
+ 927	Text has 8BIT data and charset=US-ASCII, using charset=UNKNOWN-8BIT instead.
+ $ #FixInclude
+ 928	Please fix [include ...] lines!
+ $ #AccessAttach
+ 929	Can't access attachment: %.50s
+ $ #BadAttach
+ 930	Bad attachment -- no filename!
+ $ #PgpAlreadyEncSig
+ 931	This message is already encrypted and/or signed!
+ $ #FailedSeekBytes
+ 932	Failed to seek %d bytes into file!
+ $ #PgpNoMatch
+ 933	Couldn't find key matching '%s'!
+ $ #HeaderUsingUNKNOWN8BIT
+ 934	Header has 8BIT data and charset=US-ASCII, using charset=UNKNOWN-8BIT instead.
+ $ #HeaderBadCharset
+ 935	Bad charset=%s, using charset=UNKNOWN-8BIT instead.
+ $ #ErrorOpeningName
+ 936	Error opening %s!
+ $ #ErrorWhenReading
+ 937	Error when reading: %s
+ $ #FailedLeaveFolder
+ 938	Failed to leave folder!
+ $ #FailedResyncFolder
+ 939	Failed to resync folder!
+ $ #ALERTMailfileShrinken
+ 940	ALERT: Mailfile shrinken %d bytes!
+ $ #NoFolderEditing
+ 941	You are not experienced to use folder editing
+ $ #NoPgpPublicKeys
+ 942	This message does not contain PGP public keys!
+ $ #NoMIMEMessage
+ 945	This is not a MIME message!
+ $ #NoMessages
+ 946	There are no messages!
+ $ #DecryptBadPGP
+ 947	Decrypting message... Bad PGP passphrase.
+ $ #DecryptFailInitPGP
+ 948	Decrypting message... Failed to init PGP.
+ $ #DecryptFailInitPGPRaw
+ 949	[Decrypting message... Failed to init PGP. Raw data follows.]\n
+ $ #DecryptEndRaw
+ 950	[Decrypting message... End of raw data.]\n
+ $ #Sigaction
+ 951	sigaction: %s
+ $ #ReadFailedCopy
+ 952	Read failed in copy
+ $ #Fingering
+ 953	Fingering %s...
+ $ #RemailerReading
+ 954	Reading %s...
+ $ #RemailerCoulntTime
+ 955	Could not convert time for remailer %s!
+ $ #RemailerCouldntList
+ 956	Could not retrieve list of remailers!
+ $ #RemailerErrorTemp
+ 957	Error opening temp file!
+ $ #RemailerErrorTempRename
+ 958	Could not rename temp file!
+ $ #RemailerDatabase
+ 959	Could not find remailer database!
+ $ #RemailerFind
+ 960	Could not find remailer '%s'.
+ $ #RemailerTempWriting
+ 961	Could not open temp file for writing!
+ $ #RemailerFormating
+ 962	Error while formatting for remailer!
+ $ #RemailerTempRead
+ 963	Could not read temp file!
+ $ #BuiltinHelpTitle
+ 964	Help for builtin++
+ $ #BuiltinHelpKeyA
+ 965	Key\t\tAction
+ $ #BuiltinHelpSpace
+ 966	<SPACE>, +\tNext page.
+ $ #BuiltinHelpMinus
+ 967	-\t\tPrevious page.
+ $ #BuiltinHelpReturn
+ 968	<RETURN>\tNext line.
+ $ #BuiltinHelpq
+ 969	q, x, i\t\tReturn to the index menu.
+ $ #BuiltinHelpDiv
+ 970	/\t\tSearch for pattern in message.
+ $ #BuiltinHelpArr
+ 971	^\t\tFirst page.
+ $ #BuiltinHelpG
+ 972	G\t\tLast page.
+ $ #BuiltinHelpCtrlL
+ 973	^L\t\tRefresh display.
+ $ #BuiltinHelpCtrlP
+ 974	^P\t\tUp one line.
+ $ #BuiltinHelpCtrlD
+ 975	^D\t\tDown one-half page.
+ $ #BuiltinHelpCtrlU
+ 976	^U\t\tUp one-half page.
+ $ #BuiltinHelpQuestion
+ 977	?\t\tThis help screen.
+ $ #BuiltinMore0
+ 978	More (you've seen 0%%)
+ $ #BuiltinCommandi
+ 979	Command ('i' to return to index):
+ $ #PgpEncrypt
+ 980	Encrypt
+ $ #PgpSign
+ 981	Sign
+ $ #PgpSignEncrypt
+ 982	Sign and Encrypt
+ $ #WriteFMimeEncode
+ 983	Write failed in mime_encode\n
+ $ #WriteFWriteEncoded
+ 984	Write failed in write_encoded\n
+ $ #ExtractPGPKey
+ 985	Extract PGP public key
+ $ #DebugHeader
+ 986	Num      From                    Subject                Lines   Offset  Content\n\r\n\r
+ $ #VfyMenuAtttach
+ 987	Attachments
+ $ #VfyMenuDsn
+ 988	Dsn
+ $ #VfyMenuSend
+ 989	Send
+ $ #VfyMenuForget
+ 990	Forget
+ $ #VfyMenuCopyFile
+ 991	Copy file
+ $ #VfyMenuEdit
+ 992	Edit
+ $ #VfyMenuHeaders
+ 993	Headers
+ $ #VfyMenuIspell2
+ 994	Ispell
+ $ #VfyMenuPgp
+ 995	Pgp
+ $ #Menu2True
+ 996	TRUE
+ $ #Menu2False
+ 997	FALSE
+ $ #BuiltinHelpPressRet
+ 998	Press any key to return...
+ $ #BuiltinNotFound
+ 999	NOT FOUND!
+ $ #BuiltinSearch
+ 1000	Search%s
+ $ #PgpTo
+ 1001	To%s
+ $ #PgpFrom
+ 1002	From%s
+ $ #PgpP
+ 1003	pgp%s
+ $ #PgpEntUser
+ 1004	Enter userid of public key%s
+ $ #DbxCurrMsgNum
+ 1005	Current message number = %d\t\t%d message(s) total\n
+ $ #DbxHdrPage
+ 1006	Header_page = %d           \t\t%d possible page(s)\n
+ $ #DbxCurrMailFile
+ 1007	\nCurrent mail file is %s.\n\r\n
+ $ #DbxPressAnyKey
+ 1008	Press any key to return.
+ $ #TerminatedWithSignal
+ 1009	Terminated with signal %d. Press any key to continue: 
+ $ #ExitedWithStatus
+ 1010	Exited with status %d. Press any key to continue: 
+ $ #DoneCont
+ 1011	Done. Press any key to continue: 
+ $ #MetaPagePressAnyKey
+ 1012	Press any key to continue...
+ $ #ToParen
+ 1013	To: (%s)
+ $ #ToNoParen
+ 1014	To: %s
+ $ #ToNoParen2
+ 1015	          To: %s
Index: elm2.4.ME+.50/nls/Makefile
*** elm2.4.25/nls/Makefile	Thu Mar 10 19:21:47 1994
--- elm2.4.ME+.50/nls/Makefile	Tue Nov 17 21:12:57 1998
***************
*** 8,13 ****
--- 8,15 ----
  HFILES=	$(HDIR)/s_aliases.h \
  	$(HDIR)/s_answer.h \
  	$(HDIR)/s_elm.h \
+ 	$(HDIR)/s_me.h \
+ 	$(HDIR)/s_elmalias.h \
  	$(HDIR)/s_elmrc.h \
  	$(HDIR)/s_error.h \
  	$(HDIR)/s_fastmail.h \
***************
*** 20,25 ****
--- 22,29 ----
  MFILES=	$(SDIR)/s_aliases.m \
  	$(SDIR)/s_answer.m \
  	$(SDIR)/s_elm.m \
+ 	$(SDIR)/s_me.m \
+ 	$(SDIR)/s_elmalias.m \
  	$(SDIR)/s_elmrc.m \
  	$(SDIR)/s_error.m \
  	$(SDIR)/s_fastmail.m \
Index: elm2.4.ME+.50/nls/gencat/Makefile
*** elm2.4.25/nls/gencat/Makefile	Wed Jul  1 03:56:25 1992
--- elm2.4.ME+.50/nls/gencat/Makefile	Tue Nov 17 21:12:57 1998
***************
*** 6,19 ****
  
  all:	gencat dumpmsg
  
! gencat:	gencat.o genlib.o
! 	$(CC) $(CFLAGS) -o $@ gencat.o genlib.o
  
! dumpmsg: dumpmsg.o genlib.o
! 	$(CC) $(CFLAGS) -o $@ dumpmsg.o genlib.o
  
  clean:
  	rm -f gencat.o genlib.o dumpmsg.o *~ *.bak gencat dumpmsg
  
  gencat.o:	gencat.h
! genlib.o:	gencat.h ../../hdrs/msgcat.h
--- 6,19 ----
  
  all:	gencat dumpmsg
  
! gencat:	gencat.o genlib.o ../../lib/libutil.a
! 	$(CC) $(CFLAGS) -o $@ gencat.o genlib.o ../../lib/libutil.a
  
! dumpmsg: dumpmsg.o genlib.o  ../../lib/libutil.a
! 	$(CC) $(CFLAGS) -o $@ dumpmsg.o genlib.o ../../lib/libutil.a
  
  clean:
  	rm -f gencat.o genlib.o dumpmsg.o *~ *.bak gencat dumpmsg
  
  gencat.o:	gencat.h
! genlib.o:	gencat.h ../../hdrs/msgcat.h ../../hdrs/elmlib.h
Index: elm2.4.ME+.50/nls/gencat/gencat.c
*** elm2.4.25/nls/gencat/gencat.c	Mon Aug 23 05:46:29 1993
--- elm2.4.ME+.50/nls/gencat/gencat.c	Tue Nov 17 21:12:57 1998
***************
*** 68,74 ****
  #if ANSI_C || defined(__cplusplus)
  # define P_(x) x
  #else
! # define P_(x) /**/
  #endif
  
  static void writeIfChanged P_((char *fname, int lang, int orConsts));
--- 68,74 ----
  #if ANSI_C || defined(__cplusplus)
  # define P_(x) x
  #else
! # define P_(x) ()
  #endif
  
  static void writeIfChanged P_((char *fname, int lang, int orConsts));
***************
*** 197,203 ****
      }
  
      /* If it does exist, create a temp file for now */
!     sprintf(tmpname, "/tmp/gencat.%d", (int) getpid());
      if ((tfd = open(tmpname, O_RDWR|O_CREAT, 0666)) < 0) {
  	fprintf(stderr, "gencat: Unable to open temporary file: %s\n", tmpname);
  	exit(1);
--- 197,204 ----
      }
  
      /* If it does exist, create a temp file for now */
!      elm_sfprintf(tmpname, sizeof tmpname,
!            FRM("/tmp/gencat.%d"), (int) getpid());
      if ((tfd = open(tmpname, O_RDWR|O_CREAT, 0666)) < 0) {
  	fprintf(stderr, "gencat: Unable to open temporary file: %s\n", tmpname);
  	exit(1);
Index: elm2.4.ME+.50/nls/gencat/gencat.h
*** elm2.4.25/nls/gencat/gencat.h	Mon Aug 23 05:46:29 1993
--- elm2.4.ME+.50/nls/gencat/gencat.h	Tue Nov 17 21:12:57 1998
***************
*** 86,92 ****
  #if ANSI_C || defined(__cplusplus)
  # define P_(x) x
  #else
! # define P_(x) /**/
  #endif
  
  extern void MCAddSet P_((int setId, char *c));
--- 86,92 ----
  #if ANSI_C || defined(__cplusplus)
  # define P_(x) x
  #else
! # define P_(x) ()
  #endif
  
  extern void MCAddSet P_((int setId, char *c));
Index: elm2.4.ME+.50/nls/gencat/genlib.c
*** elm2.4.25/nls/gencat/genlib.c	Sun Nov 15 03:05:11 1992
--- elm2.4.ME+.50/nls/gencat/genlib.c	Tue Nov 17 21:12:57 1998
***************
*** 273,282 ****
  char *ostr;
  {
      char	*nstr;
  
!     nstr = (char *) malloc(strlen(ostr) + 1);
      if (!nstr) error(NULL, "unable to allocate storage");
!     strcpy(nstr, ostr);
      return(nstr);
  }
  
--- 273,283 ----
  char *ostr;
  {
      char	*nstr;
+     int Len = strlen(ostr) + 1;
  
!     nstr = (char *) malloc(Len);
      if (!nstr) error(NULL, "unable to allocate storage");
!     strfcpy(nstr, ostr, Len);
      return(nstr);
  }
  
***************
*** 373,379 ****
  		cptr = wskip(cptr);
  		if (*cptr == '#') {
  		    ++cptr;
! 		    strcpy(hconst, token(cptr));
  		}
  	    } else {
  		if (*cptr) {
--- 374,380 ----
  		cptr = wskip(cptr);
  		if (*cptr == '#') {
  		    ++cptr;
! 		    strfcpy(hconst, token(cptr), sizeof hconst);
  		}
  	    } else {
  		if (*cptr) {
Index: elm2.4.ME+.50/src/Makefile.SH
*** elm2.4.25/src/Makefile.SH	Thu Dec 24 23:42:05 1992
--- elm2.4.ME+.50/src/Makefile.SH	Tue Nov 17 21:14:08 1998
***************
*** 19,44 ****
  if test "$mailermode" = 755; then
  	chgrp=":"
  fi
  cat >Makefile <<!GROK!THIS!
! # $Id: Makefile.SH,v 5.1 1992/10/03 22:58:40 syd Exp $
  #
  #  Makefile for the ELM mail program.
  #
  #	Copyright (c) 1988-1992 USENET Community Trust
  #	Copyright (c) 1986,1987 Dave Taylor
- #
- # Bug reports, patches, comments, suggestions should be sent to:
- #
- #	Syd Weinstein - elm@DSI.COM
- #			dsinc!elm
- #
- # $Log: Makefile.SH,v $
- # Revision 5.1  1992/10/03  22:58:40  syd
- # Initial checkin as of 2.4 Release at PL0
- #
- # Revision 5.1  1992/10/03  22:58:40  syd
- # Initial checkin as of 2.4 Release at PL0
- #
  # 
  #
  # Variables
--- 19,41 ----
  if test "$mailermode" = 755; then
  	chgrp=":"
  fi
+ 
+ case "$d_locale" in
+ define)
+ 	localetarget='$(LIB)/elm.mimecharsets'
+ 	;;
+ *)
+ 	localetarget=
+ 	;;
+ esac
+ 
  cat >Makefile <<!GROK!THIS!
! # $Id: Makefile.SH,v 1.3 1998/11/17 15:09:00 hurtta Exp $
  #
  #  Makefile for the ELM mail program.
  #
  #	Copyright (c) 1988-1992 USENET Community Trust
  #	Copyright (c) 1986,1987 Dave Taylor
  # 
  #
  # Variables
***************
*** 63,68 ****
--- 60,67 ----
  TOUCH		=	$touch
  TAGS		=	ctags
  
+ LOCALETARG	=	$localetarget
+ 
  !GROK!THIS!
  
  cat >>Makefile <<'!NO!SUBS!'
***************
*** 78,84 ****
  
  #	Other general variables
  BIN		=	../bin
! CFLAGS		=	$(CCFLAGS) $(OPTIMIZE) -I$(INCLDIR) $(DEBUG) $(DACSNET) 
  INCLDIR		=	../hdrs
  LINTFLAGS	=	-I$(INCLDIR)
  SHELL		=	/bin/sh
--- 77,83 ----
  
  #	Other general variables
  BIN		=	../bin
! CFLAGS		=	-I$(INCLDIR) $(CCFLAGS) $(OPTIMIZE) $(DEBUG) $(DACSNET) 
  INCLDIR		=	../hdrs
  LINTFLAGS	=	-I$(INCLDIR)
  SHELL		=	/bin/sh
***************
*** 92,99 ****
  			a_screen.c	\
  			a_sort.c	\
  			a_quit.c	\
! 			bouncebk.c	\
! 			builtin.c	\
  			calendar.c	\
  			curses.c	\
  			date.c		\
--- 91,98 ----
  			a_screen.c	\
  			a_sort.c	\
  			a_quit.c	\
! 			attach_menu.c	\
! 			builtin++.c	\
  			calendar.c	\
  			curses.c	\
  			date.c		\
***************
*** 118,133 ****
  			limit.c		\
  			mailmsg1.c	\
  			mailmsg2.c	\
! 			mime.c		\
  			mkhdrs.c	\
  			newmbox.c	\
  			options.c	\
  			out_utils.c	\
  			pattern.c	\
! 			pmalloc.c	\
  			quit.c		\
  			read_rc.c	\
  			remail.c	\
  			reply.c		\
  			returnadd.c	\
  			save_opts.c	\
--- 117,137 ----
  			limit.c		\
  			mailmsg1.c	\
  			mailmsg2.c	\
! 			menu.c		\
! 			menu2.c		\
! 			metapager.c	\
! 		 	mime.c          \
! 			mime_encode.c	\
  			mkhdrs.c	\
  			newmbox.c	\
  			options.c	\
  			out_utils.c	\
  			pattern.c	\
! 			pgp.c		\
  			quit.c		\
  			read_rc.c	\
  			remail.c	\
+ 			remailer.c	\
  			reply.c		\
  			returnadd.c	\
  			save_opts.c	\
***************
*** 136,142 ****
  			showmsg.c	\
  			showmsg_c.c	\
  			signals.c	\
- 			softkeys.c	\
  			sort.c		\
  			string2.c	\
  			strings.c	\
--- 140,145 ----
***************
*** 144,160 ****
  			utils.c		\
  			wildcards.c	\
  			wordwrap.c
  
  ELM_OBJ		=	addr_util.o	\
  			alias.o		\
  			aliaslib.o	\
  			args.o		\
  			a_edit.o	\
  			a_screen.o	\
  			a_sort.o	\
  			a_quit.o	\
! 			bouncebk.o	\
! 			builtin.o	\
  			calendar.o	\
  			curses.o	\
  			date.o		\
--- 147,164 ----
  			utils.c		\
  			wildcards.c	\
  			wordwrap.c
+ #			softkeys.c	
  
  ELM_OBJ		=	addr_util.o	\
  			alias.o		\
  			aliaslib.o	\
  			args.o		\
+ 			attach_menu.o	\
  			a_edit.o	\
  			a_screen.o	\
  			a_sort.o	\
  			a_quit.o	\
! 			builtin++.o	\
  			calendar.o	\
  			curses.o	\
  			date.o		\
***************
*** 179,194 ****
  			limit.o		\
  			mailmsg1.o	\
  			mailmsg2.o	\
  			mime.o		\
  			mkhdrs.o	\
  			newmbox.o	\
  			options.o	\
  			out_utils.o	\
  			pattern.o	\
! 			pmalloc.o	\
  			quit.o		\
  			read_rc.o	\
  			remail.o	\
  			reply.o		\
  			returnadd.o	\
  			save_opts.o	\
--- 183,203 ----
  			limit.o		\
  			mailmsg1.o	\
  			mailmsg2.o	\
+ 			menu.o		\
+ 			menu2.o		\
+ 			metapager.o	\
  			mime.o		\
+ 			mime_encode.o	\
  			mkhdrs.o	\
  			newmbox.o	\
  			options.o	\
  			out_utils.o	\
  			pattern.o	\
! 			pgp.o		\
  			quit.o		\
  			read_rc.o	\
  			remail.o	\
+ 			remailer.o	\
  			reply.o		\
  			returnadd.o	\
  			save_opts.o	\
***************
*** 197,203 ****
  			showmsg.o	\
  			showmsg_c.o	\
  			signals.o	\
- 			softkeys.o	\
  			sort.o		\
  			string2.o	\
  			strings.o	\
--- 206,211 ----
***************
*** 205,219 ****
  			utils.o		\
  			wildcards.o	\
  			wordwrap.o
  
  # Standard targets
! all:		$(BIN)/elm
  
! install:	$(DEST)/elm
  
  uninstall:	
  		$(RM) $(DEST)/elm
  
  #	This is the only target that gets installed even if not out-of-date
  #	with respect the files from which it is installed.
  rmt-install:	rmt-defined
--- 213,233 ----
  			utils.o		\
  			wildcards.o	\
  			wordwrap.o
+ #			softkeys.o	
  
  # Standard targets
! all:		Makefile $(BIN)/elm
  
! install:	Makefile $(DEST)/elm $(LOCALETARG)
  
  uninstall:	
  		$(RM) $(DEST)/elm
  
+ Makefile: Makefile.SH ../config.sh
+ 	@echo "You must run 'sh Configure -S' or 'sh Configure'"
+ 	exit 1
+ 
+ 
  #	This is the only target that gets installed even if not out-of-date
  #	with respect the files from which it is installed.
  rmt-install:	rmt-defined
***************
*** 250,260 ****
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
! $(INCLDIR)/elm.h:	$(INCLDIR)/curses.h $(INCLDIR)/defs.h
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
! $(INCLDIR)/headers.h:	$(INCLDIR)/curses.h $(INCLDIR)/defs.h
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
--- 264,274 ----
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
! $(INCLDIR)/elm.h:	$(INCLDIR)/curses.h $(INCLDIR)/defs.h  $(INCLDIR)/me.h
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
! $(INCLDIR)/headers.h:	$(INCLDIR)/curses.h $(INCLDIR)/defs.h $(INCLDIR)/mime.h $(INCLDIR)/me.h $(INCLDIR)/elmlib.h
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
***************
*** 267,309 ****
  a_screen.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_aliases.h
  a_sort.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_aliases.h
  a_quit.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_aliases.h
! bouncebk.o:	$(INCLDIR)/headers.h
! builtin.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  calendar.o:	$(INCLDIR)/headers.h
! curses.o:	$(INCLDIR)/headers.h
  date.o:		$(INCLDIR)/headers.h
  delete.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  edit.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  editmsg.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! elm.o:		$(INCLDIR)/elm.h $(INCLDIR)/s_elm.h
  encode.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! exitprog.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  expires.o:	$(INCLDIR)/headers.h
! file.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! file_util.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! fileio.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  find_alias.o:	$(INCLDIR)/headers.h
  forms.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! hdrconfg.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  help.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! in_utils.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! init.o:		$(INCLDIR)/headers.h $(INCLDIR)/patchlevel.h $(INCLDIR)/s_elm.h
! leavembox.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! lock.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  limit.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/s_aliases.h
  mailmsg1.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! mailmsg2.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! mkhdrs.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! mime.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! newmbox.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  options.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/save_opts.h
  out_utils.o:	$(INCLDIR)/headers.h
  pattern.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! pmalloc.o:	$(INCLDIR)/defs.h $(INCLDIR)/s_elm.h
  quit.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  read_rc.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/save_opts.h
! remail.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! reply.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  returnadd.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  save_opts.o:	$(INCLDIR)/save_opts.h $(INCLDIR)/headers.h $(INCLDIR)/s_elmrc.h
  savecopy.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
--- 281,328 ----
  a_screen.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_aliases.h
  a_sort.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_aliases.h
  a_quit.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_aliases.h
! attach_menu.o:	$(INCLDIR)/headers.h $(INCLDIR)/me.h $(INCLDIR)/s_elm.h
! builtin++.o:	$(INCLDIR)/headers.h $(INCLDIR)/me.h
  calendar.o:	$(INCLDIR)/headers.h
! curses.o:	$(INCLDIR)/headers.h $(INCLDIR)/me.h
  date.o:		$(INCLDIR)/headers.h
  delete.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  edit.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  editmsg.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! elm.o:		$(INCLDIR)/elm.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h $(INCLDIR)/patchlevel.h
  encode.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! exitprog.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
  expires.o:	$(INCLDIR)/headers.h
! file.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
! file_util.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
! fileio.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
  find_alias.o:	$(INCLDIR)/headers.h
  forms.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! hdrconfg.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
  help.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! in_utils.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
! init.o:		$(INCLDIR)/headers.h $(INCLDIR)/patchlevel.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
! leavembox.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
  limit.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/s_aliases.h
+ lock.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  mailmsg1.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! mailmsg2.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h $(INCLDIR)/menu2.h
! menu2.o:	$(INCLDIR)/headers.h $(INCLDIR)/me.h $(INCLDIR)/menu2.h
! menu.o:		$(INCLDIR)/headers.h $(INCLDIR)/me.h $(INCLDIR)/menu.h
! metapager.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
! mime.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
! mime_encode.o:   $(INCLDIR)/headers.h $(INCLDIR)/me.h
! mkhdrs.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
! newmbox.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
  options.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/save_opts.h
  out_utils.o:	$(INCLDIR)/headers.h
  pattern.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! pgp.o:		$(INCLDIR)/headers.h $(INCLDIR)/me.h
  quit.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  read_rc.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/save_opts.h
! remail.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
! remailer.o:	$(INCLDIR)/headers.h $(INCLDIR)/me.h $(INCLDIR)/menu2.h $(INCLDIR)/s_elm.h
! reply.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
  returnadd.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  save_opts.o:	$(INCLDIR)/save_opts.h $(INCLDIR)/headers.h $(INCLDIR)/s_elmrc.h
  savecopy.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
***************
*** 315,328 ****
  sort.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  string2.o:	$(INCLDIR)/headers.h
  strings.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! syscall.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! utils.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  wildcards.o:	$(INCLDIR)/defs.h
! wordwrap.o:	$(INCLDIR)/headers.h
  
  #	Dependencies and rules for compiling C programs
! $(BIN)/elm:	$& $(ELM_OBJ) ../lib/libutil.a
! 		$(CC) $(LFLAGS) -o $@ $(ELM_OBJ) ../lib/libutil.a $(LIBS) $(LIB2)
  
  #	Dependencies and rules for installing C programs
  $(DEST)/elm:	$(BIN)/elm
--- 334,347 ----
  sort.o:		$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
  string2.o:	$(INCLDIR)/headers.h
  strings.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h
! syscall.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
! utils.o:	$(INCLDIR)/headers.h $(INCLDIR)/s_elm.h $(INCLDIR)/me.h
  wildcards.o:	$(INCLDIR)/defs.h
! wordwrap.o:	$(INCLDIR)/headers.h $(INCLDIR)/me.h
  
  #	Dependencies and rules for compiling C programs
! $(BIN)/elm:	$& $(ELM_OBJ) ../melib/libme.a ../lib/libutil.a 
! 		$(CC) $(LFLAGS) -o $@ $(ELM_OBJ) ../melib/libme.a ../lib/libutil.a $(LIBS) $(LIB2)
  
  #	Dependencies and rules for installing C programs
  $(DEST)/elm:	$(BIN)/elm
***************
*** 332,335 ****
--- 351,357 ----
  		$(CHGRP) $(MAILGRP) $@
  		$(CHMOD) $(MAILERMODE) $@
  
+ $(LIB)/elm.mimecharsets: $(BIN)/elm.mimecharsets
+ 		$(CP) $? $@
+ 		$(CHMOD) u=rw,go=r $@
  !NO!SUBS!
Index: elm2.4.ME+.50/src/a_edit.c
*** elm2.4.25/src/a_edit.c	Sat Oct 31 21:27:53 1992
--- elm2.4.ME+.50/src/a_edit.c	Tue Nov 17 21:14:08 1998
***************
*** 1,28 ****
  
! static char rcsid[] = "@(#)$Id: a_edit.c,v 5.2 1992/10/31 19:27:44 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: a_edit.c,v $
!  * Revision 5.2  1992/10/31  19:27:44  syd
!  * Clear selection on resync of aliases
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This routine is for allowing the user to edit their aliases.text
      as they wish. 
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: a_edit.c,v 1.3 1998/11/06 13:56:58 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This routine is for allowing the user to edit their aliases.text
      as they wish. 
***************
*** 43,52 ****
  	    hard to figure out what occurred in the edit session...
  	**/
  
! 	char     at_file[SLEN];
! 
! 	sprintf(at_file,"%s/%s", home, ALIAS_TEXT);
! 	if (edit_a_file(at_file) == 0) {
  	    return (0);
  	}
  /*
--- 31,37 ----
  	    hard to figure out what occurred in the edit session...
  	**/
  
! 	if (edit_a_file(user_text_file) == 0) {
  	    return (0);
  	}
  /*
Index: elm2.4.ME+.50/src/a_quit.c
*** elm2.4.25/src/a_quit.c	Mon Apr 12 05:34:36 1993
--- elm2.4.ME+.50/src/a_quit.c	Tue Nov 17 21:12:57 1998
***************
*** 1,42 ****
  
! static char rcsid[] = "@(#)$Id: a_quit.c,v 5.4 1993/04/12 02:34:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: a_quit.c,v $
!  * Revision 5.4  1993/04/12  02:34:36  syd
!  * I have now added a parameter which controls whether want_to clears the
!  * line and centers the question or behaves like it did before. I also
!  * added a 0 at the end of the parameter list to all the other calls to
!  * want_to where a centered question on a clean line is not desirable.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.3  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.2  1992/12/11  02:09:06  syd
!  * Fix where the user creates a first new alias, then deletes it, the
!  * alias stays on screen, but the file really will be empty if it was the
!  * last alias, so the retry to delete gives 'cannot open ...file' messages
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** a_quit: leave the aliases menu and return to the main menu.
    
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: a_quit.c,v 1.2 1998/10/20 19:58:15 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** a_quit: leave the aliases menu and return to the main menu.
    
***************
*** 87,96 ****
--- 61,72 ----
  	ask_questions = ((!prompt) ? FALSE : question_me);
  
  	/* YES or NO on softkeys */
+ 	/*
  	if (hp_softkeys && ask_questions) {
  	  define_softkeys(YESNO);
  	  softkeys_on();
  	}
+ 	*/
  
  	/* Determine if deleted messages are really to be deleted */
  
***************
*** 106,123 ****
  	  answer = (always_del ? *def_ans_yes : *def_ans_no);	/* default answer */
  	  if(ask_questions) {
  	    if (marked_deleted == 1)
! 	      MCsprintf(buffer, catgets(elm_msg_cat, AliasesSet, AliasesDelete,
! 			"Delete 1 alias? (%c/%c) "), *def_ans_yes, *def_ans_no);
  	    else
! 	      MCsprintf(buffer, catgets(elm_msg_cat, AliasesSet, AliasesDeletePlural,
! 			"Delete %d aliases? (%c/%c) "),
! 			marked_deleted, *def_ans_yes, *def_ans_no);
  	                    
! 	    answer = want_to(buffer, answer, LINES-3, 0);
  	  }
  
  	  if(answer == *def_ans_yes) {
! 	    list = (char **) malloc(marked_deleted*sizeof(*list));
  	    for (i = 0; i < message_count; i++) {
  	      if (ison(aliases[i]->status, DELETED)) {
  		list[to_delete] = aliases[i]->alias;
--- 82,103 ----
  	  answer = (always_del ? *def_ans_yes : *def_ans_no);	/* default answer */
  	  if(ask_questions) {
  	    if (marked_deleted == 1)
! 	      elm_sfprintf(buffer, sizeof buffer,
! 			   CATGETS(elm_msg_cat, AliasesSet, AliasesDelete,
! 				   "Delete 1 alias? (%c/%c) "), 
! 			   *def_ans_yes, *def_ans_no);
  	    else
! 	      elm_sfprintf(buffer, sizeof buffer,
! 			   CATGETS(elm_msg_cat, AliasesSet, 
! 				   AliasesDeletePlural,
! 				   "Delete %d aliases? (%c/%c) "),
! 			   marked_deleted, *def_ans_yes, *def_ans_no);
  	                    
! 	    answer = want_to(buffer, answer, elm_LINES-3, 0);
  	  }
  
  	  if(answer == *def_ans_yes) {
! 	    list = (char **) safe_malloc(marked_deleted*sizeof(*list));
  	    for (i = 0; i < message_count; i++) {
  	      if (ison(aliases[i]->status, DELETED)) {
  		list[to_delete] = aliases[i]->alias;
***************
*** 136,151 ****
  	    if (to_keep > 0) {
  	      current = 1;		/* Reset current alias */
  	      if (to_keep == 1)
! 		sprintf(buffer, catgets(elm_msg_cat, AliasesSet, AliasesKeepDelete,
! 			  "[Keeping 1 alias and deleting %d.]"), to_delete);
  	      else
! 		MCsprintf(buffer, catgets(elm_msg_cat, AliasesSet, AliasesKeepDeletePlural,
! 			  "[Keeping %d aliases and deleting %d.]"), to_keep, to_delete);
  	    }
  	    else {
  	      current = 0;		/* No aliases left */
! 	      sprintf(buffer, catgets(elm_msg_cat, AliasesSet, AliasesDeleteAll,
! 			  "[Deleting all aliases.]"));
  	    }
  
  	    dprint(2, (debugfile, "Action: %s\n", buffer));
--- 116,138 ----
  	    if (to_keep > 0) {
  	      current = 1;		/* Reset current alias */
  	      if (to_keep == 1)
! 		elm_sfprintf(buffer, sizeof buffer,
! 			     CATGETS(elm_msg_cat, AliasesSet, 
! 				     AliasesKeepDelete,
! 				     "[Keeping 1 alias and deleting %d.]"), 
! 			     to_delete);
  	      else
! 		elm_sfprintf(buffer, sizeof buffer,
! 			     CATGETS(elm_msg_cat, AliasesSet, 
! 				     AliasesKeepDeletePlural,
! 				     "[Keeping %d aliases and deleting %d.]"),
! 			     to_keep, to_delete);
  	    }
  	    else {
  	      current = 0;		/* No aliases left */
! 	      elm_sfprintf(buffer, sizeof buffer,
! 			   CATGETS(elm_msg_cat, AliasesSet, AliasesDeleteAll,
! 				   "[Deleting all aliases.]"));
  	    }
  
  	    dprint(2, (debugfile, "Action: %s\n", buffer));
Index: elm2.4.ME+.50/src/a_screen.c
*** elm2.4.25/src/a_screen.c	Fri Apr 16 06:54:15 1993
--- elm2.4.ME+.50/src/a_screen.c	Tue Nov 17 21:12:57 1998
***************
*** 1,50 ****
  
! static char rcsid[] = "@(#)$Id: a_screen.c,v 5.4 1993/04/16 03:53:43 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: a_screen.c,v $
!  * Revision 5.4  1993/04/16  03:53:43  syd
!  * fix wrong softkeys displayed
!  * From: From: Michael Greenberg <hp.com!hpbbn.bbn.hp.com!hputlaa!hputlav!michael>
!  *
!  * Revision 5.3  1993/01/19  04:52:19  syd
!  * 	add c)hange alias command to alias helpfile
!  * 	if a deleted alias is changed, undelete it.  Also added the 'N'
!  * flag to changed aliases to help remind the user.  Documented it.
!  * Note:  if they mark the alias for deletion AFTER making the change it
!  * WILL be deleted. (and marked accordingly)
!  * 	modified alias mode title string to indicate when a resync was
!  * needed.
!  * 	allow editing alias file when none exist.
!  * 	Now aliases are check for illegal characters (and WS) and
!  * addresses are check for illegal WS when they are being entered.  If
!  * anything illegal is found and message is printed and they keep entering
!  * the item until they get it right.
!  * 	I fixed a couple of places where int should be long to match
!  * the declared type of alias_rec.length
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.2  1992/12/20  05:15:58  syd
!  * Add a c)hange alias, -u and -t options to listalias to list only user
!  * and only system aliases respectively.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /**  alias screen display routines for ELM program
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: a_screen.c,v 1.2 1998/10/20 19:58:15 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /**  alias screen display routines for ELM program
  
***************
*** 73,80 ****
  
  	show_last_error();
  
! 	if (hp_terminal)
! 	  define_softkeys(ALIAS);
  }
  
  alias_title(modified)
--- 39,45 ----
  
  	show_last_error();
  
! 	/* define_softkeys(ALIAS); */
  }
  
  alias_title(modified)
***************
*** 87,94 ****
  	char modmsg[SLEN];
  
  	if (modified) {
! 	    strcpy(modmsg, catgets(elm_msg_cat, AliasesSet, AliasesModified,
! 		"(modified, resync needed) "));
  	}
  	else {
  	    modmsg[0] = '\0';
--- 52,60 ----
  	char modmsg[SLEN];
  
  	if (modified) {
! 	    strfcpy(modmsg, catgets(elm_msg_cat, AliasesSet, AliasesModified,
! 				    "(modified, resync needed) "),
! 		    sizeof modmsg);
  	}
  	else {
  	    modmsg[0] = '\0';
***************
*** 95,110 ****
  	}
  
  	if (selected)
! 	  MCsprintf(buffer, catgets(elm_msg_cat, AliasesSet, AliasesSelect,
! 	      "Alias mode: %d shown out of %d %s[ELM %s]"),
! 	      selected, message_count, modmsg, version_buff);
  	else if (message_count == 1)
! 	  sprintf(buffer, catgets(elm_msg_cat, AliasesSet, AliasesSingle,
! 	      "Alias mode: 1 alias %s[ELM %s]"), modmsg, version_buff);
  	else
! 	  MCsprintf(buffer, catgets(elm_msg_cat, AliasesSet, AliasesPlural,
! 	      "Alias mode: %d aliases %s[ELM %s]"),
! 	      message_count, modmsg, version_buff);
  
  	ClearLine(1);
  
--- 61,80 ----
  	}
  
  	if (selected)
! 	  elm_sfprintf(buffer, sizeof buffer,
! 		       CATGETS(elm_msg_cat, AliasesSet, AliasesSelect,
! 			       "Alias mode: %d shown out of %d %s[ELM %s]"),
! 		       selected, message_count, modmsg, version_buff);
  	else if (message_count == 1)
! 	  elm_sfprintf(buffer, sizeof buffer,
! 		       CATGETS(elm_msg_cat, AliasesSet, AliasesSingle,
! 			       "Alias mode: 1 alias %s[ELM %s]"), 
! 		       modmsg, version_buff);
  	else
! 	  elm_sfprintf(buffer, sizeof buffer,
! 		       CATGETS(elm_msg_cat, AliasesSet, AliasesPlural,
! 			       "Alias mode: %d aliases %s[ELM %s]"),
! 		       message_count, modmsg, version_buff);
  
  	ClearLine(1);
  
***************
*** 117,146 ****
  	/* Moved from alias.c */
  
  	if (user_level == RANK_AMATEUR) {	/* Give less options  */
! 	  Centerline(LINES-7, catgets(elm_msg_cat, AliasesSet, AliasesRMenuLn1,
  "You can use any of the following commands by pressing the first character;"));
! 	  Centerline(LINES-6, catgets(elm_msg_cat, AliasesSet, AliasesRMenuLn2,
  "a)lias current message, n)ew alias, d)elete or u)ndelete an alias,"));
! 	  Centerline(LINES-5, catgets(elm_msg_cat, AliasesSet, AliasesRMenuLn3,
  "m)ail to alias, or r)eturn to main menu.  To view an alias, press <return>."));
! 	  Centerline(LINES-4, catgets(elm_msg_cat, AliasesSet, AliasesRMenuLn4,
  "j = move down, k = move up, ? = help"));
  	}
  	else {
! 	    Centerline(LINES-7, catgets(elm_msg_cat, AliasesSet, AliasesMenuLn1,
  "Alias commands:  ?=help, <n>=set current to n, /=search pattern"));
! 	    Centerline(LINES-6, catgets(elm_msg_cat, AliasesSet, AliasesMenuLn2,
  "a)lias current message, c)hange, d)elete, e)dit aliases.text, f)ully expand,"));
! 	    Centerline(LINES-5, catgets(elm_msg_cat, AliasesSet, AliasesMenuLn3,
  "l)imit display, m)ail, n)ew alias, r)eturn, t)ag, u)ndelete, or e(x)it"));
  	}
  
  }
  
! build_alias_line(buffer, entry, message_number, highlight)
! char *buffer;
! struct alias_rec *entry;
! int message_number, highlight;
  {
  	/** Build in buffer the alias header ... entry is the current
  	    message entry, 'highlight' is either TRUE or FALSE,
--- 87,125 ----
  	/* Moved from alias.c */
  
  	if (user_level == RANK_AMATEUR) {	/* Give less options  */
! 	  Centerline(elm_LINES-7, catgets(elm_msg_cat, AliasesSet, 
! 					  AliasesRMenuLn1,
  "You can use any of the following commands by pressing the first character;"));
! 	  Centerline(elm_LINES-6, catgets(elm_msg_cat, AliasesSet, 
! 					  AliasesRMenuLn2,
  "a)lias current message, n)ew alias, d)elete or u)ndelete an alias,"));
! 	  Centerline(elm_LINES-5, catgets(elm_msg_cat, AliasesSet, 
! 					  AliasesRMenuLn3,
  "m)ail to alias, or r)eturn to main menu.  To view an alias, press <return>."));
! 	  Centerline(elm_LINES-4, catgets(elm_msg_cat, AliasesSet, 
! 					  AliasesRMenuLn4,
  "j = move down, k = move up, ? = help"));
  	}
  	else {
! 	    Centerline(elm_LINES-7, catgets(elm_msg_cat, AliasesSet, 
! 					    AliasesMenuLn1,
  "Alias commands:  ?=help, <n>=set current to n, /=search pattern"));
! 	    Centerline(elm_LINES-6, catgets(elm_msg_cat, AliasesSet, 
! 					    AliasesMenuLn2,
  "a)lias current message, c)hange, d)elete, e)dit aliases.text, f)ully expand,"));
! 	    Centerline(elm_LINES-5, catgets(elm_msg_cat, AliasesSet, 
! 					    AliasesMenuLn3,
  "l)imit display, m)ail, n)ew alias, r)eturn, t)ag, u)ndelete, or e(x)it"));
  	}
  
  }
  
! void
! build_alias_line(buffer, entry, message_number, highlight, buffer_size)
!      char *buffer;
!      struct alias_rec *entry;
!      int message_number, highlight;
!      int buffer_size;
  {
  	/** Build in buffer the alias header ... entry is the current
  	    message entry, 'highlight' is either TRUE or FALSE,
***************
*** 159,185 ****
  
  	/* Note that one huge sprintf() is too hard for some compilers. */
  
! 	sprintf(buffer, "%s%s%c%-3d ",
! 		(highlight && arrow_cursor)? "->" : "  ",
! 		show_status(entry->status),
! 		(entry->status & TAGGED?  '+' : ' '),
! 		message_number);
  
  	/* Set the name display width. */
! 	name_width = COLUMNS-40;
  
! 	/* Put the name and associated comment in local buffer */
! 	if (strlen(entry->comment))
! 	  MCsprintf(mybuffer, "%s, %s", entry->name, entry->comment);
! 	else
! 	  sprintf(mybuffer, "%s", entry->name);
  
  	/* complete line with name, type and alias. */
! 	sprintf(buffer + strlen(buffer), "%-*.*s %s %-18.18s",
! 		/* give max and min width parameters for 'name' */
! 		name_width, name_width, mybuffer,
! 		alias_type(entry->type),
! 		entry->alias);
  }
  
  char *alias_type(type)
--- 138,176 ----
  
  	/* Note that one huge sprintf() is too hard for some compilers. */
  
! 	elm_sfprintf(buffer, buffer_size,
! 		     FRM("%s%s%c%-3d "),
! 		     (highlight && arrow_cursor)? "->" : "  ",
! 		     show_status(entry->status,NULL),
! 		     (entry->status & TAGGED?  '+' : ' '),
! 		     message_number);
  
  	/* Set the name display width. */
! 	name_width = elm_COLUMNS-40;
  
! 	/* Put the name and associated comment 
! 	   (or just the address if null) in local buffer */
! 	if (strlen(entry->name)) {
! 	  if (strlen(entry->comment))
! 	    elm_sfprintf(mybuffer, sizeof mybuffer,
! 			 FRM("%.100s, %.100s"), 
! 			 entry->name, entry->comment);
! 	  else
! 	    elm_sfprintf(mybuffer, sizeof mybuffer,
! 			 FRM("%.100s"), 
! 			 entry->name);
! 	} else
! 	  elm_sfprintf(mybuffer, sizeof mybuffer,
! 		       FRM("%.100s"), 
! 		       entry->address);
  
  	/* complete line with name, type and alias. */
! 	elm_sfprintf(buffer + strlen(buffer), buffer_size - strlen(buffer),
! 		     FRM("%-*.*s %s %-18.18s"),
! 		     /* give max and min width parameters for 'name' */
! 		     name_width, name_width, mybuffer,
! 		     alias_type(entry->type),
! 		     entry->alias);
  }
  
  char *alias_type(type)
***************
*** 193,203 ****
  	static char mybuffer[10];
  	extern char *a_group_name, *a_person_name, *a_system_flag;
  
! 	if (type & GROUP)	strcpy(mybuffer, a_group_name);
! 	else			strcpy(mybuffer, a_person_name);
  
! 	if (type & SYSTEM)	strcat(mybuffer, a_system_flag);
! 	else			strcat(mybuffer, "   ");
  
  	return( (char *) mybuffer);
  }
--- 184,194 ----
  	static char mybuffer[10];
  	extern char *a_group_name, *a_person_name, *a_system_flag;
  
! 	if (type & GROUP)    strfcpy(mybuffer, a_group_name, sizeof mybuffer);
! 	else		     strfcpy(mybuffer, a_person_name, sizeof mybuffer);
  
! 	if (type & SYSTEM)   strfcat(mybuffer, a_system_flag, sizeof mybuffer);
! 	else		     strfcat(mybuffer, "   ", sizeof mybuffer);
  
  	return( (char *) mybuffer);
  }
Index: elm2.4.ME+.50/src/a_sort.c
*** elm2.4.25/src/a_sort.c	Sat Mar 12 17:32:55 1994
--- elm2.4.ME+.50/src/a_sort.c	Tue Nov 17 21:12:58 1998
***************
*** 1,54 ****
  
! static char rcsid[] = "@(#)$Id: a_sort.c,v 5.5 1993/06/12 05:27:44 syd Exp syd $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.5 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: a_sort.c,v $
!  * Revision 5.5  1993/06/12  05:27:44  syd
!  * Fix calling sequence error
!  * From: Syd
!  *
!  * Revision 5.4  1993/04/12  01:10:15  syd
!  * fix @aliasname sort problem
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.3  1993/01/19  04:52:19  syd
!  * 	add c)hange alias command to alias helpfile
!  * 	if a deleted alias is changed, undelete it.  Also added the 'N'
!  * flag to changed aliases to help remind the user.  Documented it.
!  * Note:  if they mark the alias for deletion AFTER making the change it
!  * WILL be deleted. (and marked accordingly)
!  * 	modified alias mode title string to indicate when a resync was
!  * needed.
!  * 	allow editing alias file when none exist.
!  * 	Now aliases are check for illegal characters (and WS) and
!  * addresses are check for illegal WS when they are being entered.  If
!  * anything illegal is found and message is printed and they keep entering
!  * the item until they get it right.
!  * 	I fixed a couple of places where int should be long to match
!  * the declared type of alias_rec.length
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.2  1992/11/22  00:05:07  syd
!  * Fix bug where alias records were not sorting by both last and
!  * first names.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** Sort alias table by the field specified in the global
      variable "alias_sortby"...
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: a_sort.c,v 1.2 1998/10/20 19:58:15 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** Sort alias table by the field specified in the global
      variable "alias_sortby"...
***************
*** 78,85 ****
  	  last_index = aliases[current-1]->length;
  
  	if ((entries > 30) && visible && are_in_aliases) {
! 	    error1(catgets(elm_msg_cat, AliasesSet, AliasesSort,
! 		    "Sorting aliases by %s..."), alias_sort_name(FULL));
  	}
  	
  	if (entries > 1)
--- 40,48 ----
  	  last_index = aliases[current-1]->length;
  
  	if ((entries > 30) && visible && are_in_aliases) {
! 	    lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesSort,
! 			      "Sorting aliases by %s..."), 
! 		      alias_sort_name(FULL));
  	}
  	
  	if (entries > 1)
Index: elm2.4.ME+.50/src/addr_util.c
*** elm2.4.25/src/addr_util.c	Tue Aug  3 22:28:59 1993
--- elm2.4.ME+.50/src/addr_util.c	Tue Nov 17 21:12:57 1998
***************
*** 1,89 ****
  
! static char rcsid[] = "@(#)$Id: addr_util.c,v 5.11 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.11 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: addr_util.c,v $
!  * Revision 5.11  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.10  1993/05/31  19:32:20  syd
!  * With this patch build_address() should treat local mailing
!  * lists and other aliases known by the transport agent as valid
!  * addresses.
!  * I also conditionalized printing the "Expands to: " message
!  * in check_only mode to be done only when there is an expanded
!  * address to print. Build_address will inform anyway about an
!  * alias that does not exist.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.9  1993/05/14  03:53:46  syd
!  * Fix wrong message being displayed and then overwritten
!  * for long aliases.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.8  1993/04/16  03:26:50  syd
!  * For many embedded X.400 addresses in the format
!  * "/.../.../.../.../"@admd.country NLEN was simply too short and part of
!  * the address never made it to the reply address. In my opinion 512 bytes
!  * should be enough. So make it LONG_STRING.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.7  1993/01/19  05:07:05  syd
!  * Trim erroreous extra log entry
!  * From: Syd
!  *
!  * Revision 5.6  1993/01/19  04:47:12  syd
!  * Significant changes to provide consistent Date and From_ header
!  * cracking.  Overhauled date utilities and moved into library.  Moved
!  * real_from() into library.  Modified frm, newmail, and readmsg utilities
!  * to use library version of real_from().  Moved get_word() from Elm
!  * source into library.  Added new library routines atonum() and strfcpy().
!  * Fixed trailing backslash bug in len_next().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.5  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.4  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.3  1992/10/31  18:52:51  syd
!  * Corrections to Unix date parsing and time zone storage
!  * From: eotto@hvlpa.att.com
!  *
!  * Revision 5.2  1992/10/25  02:18:01  syd
!  * fix found_year flag
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This file contains addressing utilities 
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: addr_util.c,v 1.2 1998/10/20 19:58:15 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This file contains addressing utilities 
  
***************
*** 91,97 ****
  
  #include "headers.h"
  #include "s_elm.h"
! 
  
  translate_return(addr, ret_addr)
  char *addr, *ret_addr;
--- 18,24 ----
  
  #include "headers.h"
  #include "s_elm.h"
! #include "me.h"
  
  translate_return(addr, ret_addr)
  char *addr, *ret_addr;
***************
*** 170,178 ****
  	ret_addr[iindex] = '\0';
  }
  
! int
! build_address(to, full_to)
! char *to, *full_to;
  {
  	/** loop on all words in 'to' line...append to full_to as
  	    we go along, until done or length > len.  Modified to
--- 97,105 ----
  	ret_addr[iindex] = '\0';
  }
  
! int build_address(to, full_to, size_to, size_full_to)
!      char *to, *full_to;
!      int size_to, size_full_to;
  {
  	/** loop on all words in 'to' line...append to full_to as
  	    we go along, until done or length > len.  Modified to
***************
*** 215,225 ****
  	  else if (word[0] == '-'){
  	    for (k=0; word[k]; word[k] = word[k+1],k++);
  	    if (elim_list[0] != '\0')
! 	      strcat(elim_list, " ");
! 	    strcat(elim_list, word);
  	  }
  	  if ((i = j) > 0)
! 	    strcpy(word, next_word);
  	}
  
  	if (elim_list[0] != '\0')
--- 142,152 ----
  	  else if (word[0] == '-'){
  	    for (k=0; word[k]; word[k] = word[k+1],k++);
  	    if (elim_list[0] != '\0')
! 	      strfcat(elim_list, " ", sizeof elim_list);
! 	    strfcat(elim_list, word, sizeof elim_list);
  	  }
  	  if ((i = j) > 0)
! 	    strfcpy(word, next_word, sizeof word);
  	}
  
  	if (elim_list[0] != '\0')
***************
*** 236,245 ****
  	    in_parens++;
  
  	  if (in_parens) {
! 	    if(word[strlen(word)-1] == ')')
  	      in_parens--;
! 	    strcat(full_to, " ");
! 	    strcat(full_to, word);
  	  }
  
  	  else if (word[0] == '-') {
--- 163,195 ----
  	    in_parens++;
  
  	  if (in_parens) {
! 	    char c1 = '\0', c2 = '\0';
! 	    char *word1 = word;
! #ifdef MIME
! 	    char temp[LONG_STRING];
! #endif
! 
! 	    if (word1[0] == '(') {
! 	      c1 = '(';
! 	      word1++;
! 	    }
! 	    if(word1[strlen(word1)-1] == ')') {
  	      in_parens--;
! 	      c2 = ')';
! 	      word1[strlen(word1)-1] = '\0';
! 	    }
! #ifdef MIME
! 	    if (!allow_no_hdrencoding) {
! 	      rfc1522_encode_text(temp,sizeof temp,word1,HDR_COMMENT);
! 	      word1 = temp;
! 	    } 
! #endif 
! 	    strfcat(full_to, " ", size_full_to);
! 	    if (c1)
! 	      strfcat(full_to, "(", size_full_to);
! 	    strfcat(full_to, word1, size_full_to-1);
! 	    if (c2)
! 	      strfcat(full_to, ")", size_full_to);
  	  }
  
  	  else if (word[0] == '-') {
***************
*** 246,253 ****
  	  }
  
  	  else if (qstrpbrk(word,"!@:") != NULL) {
! 	    sprintf(full_to, "%s%s%s", full_to,
!                     full_to[0] != '\0'? ", " : "", word);
  	  }
  	  else if ((ptr = get_alias_address(word, TRUE, &too_long)) != NULL) {
  
--- 196,204 ----
  	  }
  
  	  else if (qstrpbrk(word,"!@:") != NULL) {
! 	    elm_sfprintf(full_to, size_full_to,
! 			 FRM("%s%s%s"), full_to,
! 			 full_to[0] != '\0'? ", " : "", word);
  	  }
  	  else if ((ptr = get_alias_address(word, TRUE, &too_long)) != NULL) {
  
***************
*** 258,271 ****
  	      while (k > 0) {
  		l = get_word(ptr, k, next_word_a, sizeof(next_word_a));
  		if (in_list(elim_list, word_a) == 0)
! 		  sprintf(full_to, "%s%s%s", full_to,
! 			  full_to[0] != '\0' ? ", " : "", word_a);
  		if ((k = l) > 0)
! 		  strcpy(word_a, next_word_a);
  	      }
  	    } else
! 	      sprintf(full_to, "%s%s%s", full_to, 
!                       full_to[0] != '\0'? ", " : "", ptr);
  	    expanded_information++;
  	  }
  	  else if (too_long) {
--- 209,224 ----
  	      while (k > 0) {
  		l = get_word(ptr, k, next_word_a, sizeof(next_word_a));
  		if (in_list(elim_list, word_a) == 0)
! 		  elm_sfprintf(full_to, size_full_to,
! 			       FRM("%s%s%s"), full_to,
! 			       full_to[0] != '\0' ? ", " : "", word_a);
  		if ((k = l) > 0)
! 		  strfcpy(word_a, next_word_a, sizeof word_a);
  	      }
  	    } else
! 	      elm_sfprintf(full_to, size_full_to,
! 			   FRM("%s%s%s"), full_to, 
! 			   full_to[0] != '\0'? ", " : "", ptr);
  	    expanded_information++;
  	  }
  	  else if (too_long) {
***************
*** 278,306 ****
  	      dprint(2,(debugfile,"Overflowed alias expansion for %s\n", word));
  	  }
  	  else if (strlen(word) > 0) {
  	    if (valid_name(word)) {
  	      if (j > 0 && next_word[0] == '(')	/* already has full name */
  		gecos = NULL;
  	      else				/* needs a full name */
  		gecos = get_full_name(word);
! #if defined(INTERNET) & defined(USE_DOMAIN)
! 	      sprintf(full_to, "%s%s%s@%s%s%s%s",
! 		      full_to,
! 		      (full_to[0] ? ", " : ""),
! 		      word,
! 		      hostfullname,
! 		      (gecos ? " (" : ""),
! 		      (gecos ? gecos : ""),
! 		      (gecos ? ")" : ""));
! #else /* INTERNET and USE_DOMAIN */
! 	      sprintf(full_to, "%s%s%s%s%s%s",
! 		      full_to,
! 		      (full_to[0] ? ", " : ""),
! 		      word,
! 		      (gecos ? " (" : ""),
! 		      (gecos ? gecos : ""),
! 		      (gecos ? ")" : ""));
! #endif /* INTERNET and USE_DOMAIN */
  	    }
  	    else if (check_only) {
  		if (! isatty(fileno(stdin)) ) {
--- 231,273 ----
  	      dprint(2,(debugfile,"Overflowed alias expansion for %s\n", word));
  	  }
  	  else if (strlen(word) > 0) {
+ #ifdef MIME
+ 	    char temp[LONG_STRING];
+ #endif
  	    if (valid_name(word)) {
  	      if (j > 0 && next_word[0] == '(')	/* already has full name */
  		gecos = NULL;
  	      else				/* needs a full name */
  		gecos = get_full_name(word);
! #ifdef MIME
! 	    if (!allow_no_hdrencoding && gecos) {
! 	      /* from is not longer mime encoded */
! 
! 	      rfc1522_encode_text(temp,sizeof temp,gecos,HDR_COMMENT);
! 	      gecos = temp;
! 	    } 
! #endif 
! 
! #if defined(USE_DOMAIN)
! 	      elm_sfprintf(full_to, size_full_to,
! 			   FRM("%s%s%s@%s%s%s%s"),
! 			   full_to,
! 			   (full_to[0] ? ", " : ""),
! 			   word,
! 			   hostfullname,
! 			   (gecos ? " (" : ""),
! 			   (gecos ? gecos : ""),
! 			   (gecos ? ")" : ""));
! #else /* USE_DOMAIN */
! 	      elm_sfprintf(full_to, size_full_to,
! 			   FRM("%s%s%s%s%s%s"),
! 			   full_to,
! 			   (full_to[0] ? ", " : ""),
! 			   word,
! 			   (gecos ? " (" : ""),
! 			   (gecos ? gecos : ""),
! 			   (gecos ? ")" : ""));
! #endif /* USE_DOMAIN */
  	    }
  	    else if (check_only) {
  		if (! isatty(fileno(stdin)) ) {
***************
*** 327,409 ****
  		}
  	    }
  	    else {
! 	      sprintf(full_to, "%s%s%s",
! 		      full_to,
! 		      (full_to[0] ? ", " : ""),
! 		      word);
  	    }
  	  }
  
  	  /* and this word to the new to list */
  	  if(*new_to_list != '\0')
! 	    strcat(new_to_list, " ");
! 	  strcat(new_to_list, word);
  
  	  if((i = j) > 0)
! 	    strcpy(word, next_word);
  	}
  
  	/* if new to list is different from original, update original */
  	if (changed)
! 	  strcpy(to, new_to_list);
  
  	return( expanded_information > 0 ? 1 : 0 );
  }
  
! 
! forwarded(buffer, entry)
! char *buffer;
! struct header_rec *entry;
! {
! 	/** Change 'from' and date fields to reflect the ORIGINATOR of 
! 	    the message by iteratively parsing the >From fields... 
! 	    Modified to deal with headers that include the time zone
! 	    of the originating machine... **/
! 
! 	char machine[SLEN], buff[SLEN], holding_from[SLEN];
! 	int len;
! 
! 	machine[0] = holding_from[0] = '\0';
! 
! 	sscanf(buffer, "%*s %s", holding_from);
! 
! 	/* after skipping over From and address, process rest as date field */
! 
! 	while (!isspace(*buffer)) buffer++;	/* skip From */
! 	while (isspace(*buffer)) buffer++;
! 
! 	while (*buffer) {
! 	  len = len_next_part(buffer);
! 	  if (len > 1) {
! 	    buffer += len;
! 	  } else {
! 	    if (isspace(*buffer))
! 	      break;
! 	    buffer++;
! 	  }
! 	}
! 	while (isspace(*buffer)) buffer++;
! 
! 	parse_arpa_date(buffer, entry);
! 
! 	/* the following fix is to deal with ">From xyz ... forwarded by xyz"
! 	   which occasionally shows up within AT&T.  Thanks to Bill Carpenter
! 	   for the fix! */
! 
! 	if (strcmp(machine, holding_from) == 0)
! 	  machine[0] = '\0';
! 
! 	if (machine[0] == '\0')
! 	  strcpy(buff, holding_from[0] ? holding_from : "anonymous");
! 	else
! 	  sprintf(buff,"%s!%s", machine, holding_from);
! 
! 	strfcpy(entry->from, buff, STRING);
! }
! 
! 
! fix_arpa_address(address)
! char *address;
  {
  	/** Given a pure ARPA address, try to make it reasonable.
  
--- 294,326 ----
  		}
  	    }
  	    else {
! 	      elm_sfprintf(full_to, size_full_to,
! 			   FRM("%s%s%s"),
! 			   full_to,
! 			   (full_to[0] ? ", " : ""),
! 			   word);
  	    }
  	  }
  
  	  /* and this word to the new to list */
  	  if(*new_to_list != '\0')
! 	    strfcat(new_to_list, " ", sizeof new_to_list);
! 	  strfcat(new_to_list, word, sizeof new_to_list);
  
  	  if((i = j) > 0)
! 	    strfcpy(word, next_word, sizeof word);
  	}
  
  	/* if new to list is different from original, update original */
  	if (changed)
! 	  strfcpy(to, new_to_list, size_to);
  
  	return( expanded_information > 0 ? 1 : 0 );
  }
  
! int fix_arpa_address(address, size)
!      char *address;
!      int size;
  {
  	/** Given a pure ARPA address, try to make it reasonable.
  
***************
*** 425,431 ****
  	      ;
  
  	  if (i == host_count) {
! 	    strcpy(hosts[host_count++], host);
  	    if (host_count == MAX_HOPS) {
  	       dprint(2, (debugfile, 
             "Can't build return address - hit MAX_HOPS in fix_arpa_address\n"));
--- 342,348 ----
  	      ;
  
  	  if (i == host_count) {
! 	    strfcpy(hosts[host_count++], host, sizeof hosts[host_count]);
  	    if (host_count == MAX_HOPS) {
  	       dprint(2, (debugfile, 
             "Can't build return address - hit MAX_HOPS in fix_arpa_address\n"));
***************
*** 444,453 ****
  	address[0] = '\0';
  
  	for (i = 0; i < host_count; i++)
! 	  sprintf(address, "%s%s%s", address, 
! 	          address[0] == '\0'? "" : 
! 	 	    (i == host_count - 1 ? "@" : "%"),
! 	          hosts[i]);
  
! 	return(0);
  }
--- 361,371 ----
  	address[0] = '\0';
  
  	for (i = 0; i < host_count; i++)
! 	  elm_sfprintf(address, size,
! 		       FRM("%s%s%s"), address, 
! 		       address[0] == '\0'? "" : 
! 		       (i == host_count - 1 ? "@" : "%"),
! 		       hosts[i]);
  
! 	return 0;
  }
Index: elm2.4.ME+.50/src/alias.c
*** elm2.4.25/src/alias.c	Mon May 30 19:42:49 1994
--- elm2.4.ME+.50/src/alias.c	Tue Nov 17 21:14:09 1998
***************
*** 1,263 ****
  
! static char rcsid[] = "@(#)$Id: alias.c,v 5.40 1994/05/30 16:42:48 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.40 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: alias.c,v $
!  * Revision 5.40  1994/05/30  16:42:48  syd
!  * Just a minor fix to an impossible character comparison.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.39  1994/05/15  23:10:08  syd
!  * Below are the changes required to compile/link elm 2.4 pl23 under
!  * QNX 4.2 with the Watcom 9.5 compiler (very picky).
!  * From: "Brian Campbell" <brianc@quantum>
!  *
!  * Revision 5.38  1994/03/11  21:25:24  syd
!  * Fix Elm looping if an EOF is received.
!  * From: Gregory Neil Shapiro <gshapiro@WPI.EDU>
!  *
!  * Revision 5.37  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.36  1993/06/12  05:27:44  syd
!  * Fix calling sequence error
!  * From: Syd
!  *
!  * Revision 5.35  1993/06/10  02:58:26  syd
!  * Correct problem in fetch_alias() with alias record fixup that caused
!  * core dump on machines with pointers larger than int.  This problem
!  * was reported on comp.mail.elm by Richard Eckman and Jim Brown.  Simplify
!  * get_one_alias() by having it use fetch_alias().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.34  1993/05/14  03:57:36  syd
!  * A couple of calls to want_to() had typos. Here is the patch.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.33  1993/05/14  03:53:46  syd
!  * Fix wrong message being displayed and then overwritten
!  * for long aliases.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.32  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.31  1993/05/08  17:04:15  syd
!  * Jan's removal of tolower in alias.c breaks help for 'I'.  This fixes
!  * that and makes the help messages for characters that have printable
!  * synonyms on the alias and options screens consistent with the help files.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.30  1993/04/21  01:33:49  syd
!  * Use pointer arithmetic for aliases on crays
!  * From: Quentin Van Abbe <rxxqva@argolis.osf.rmit.OZ.AU>
!  *
!  * Revision 5.29  1993/04/12  03:15:41  syd
!  * These patches makes 'T' (since it was free) do a Tag and Move command in the
!  * index and alias page, and in the builtin pager.
!  * In the alias help in src/alias.c, there is a tolower done on the character
!  * one wants help for.  This is clearly wrong.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.28  1993/04/12  03:00:57  syd
!  * None of i, q, x, >, and ^L are recognized by the single character help
!  * on the options screen.  <return> causes the options screen to scroll
!  * because all non-printing characters are echoed by the error message.
!  * Options and alias help files didn't list all commands.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.27  1993/04/12  02:34:36  syd
!  * I have now added a parameter which controls whether want_to clears the
!  * line and centers the question or behaves like it did before. I also
!  * added a 0 at the end of the parameter list to all the other calls to
!  * want_to where a centered question on a clean line is not desirable.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.26  1993/04/12  01:14:11  syd
!  * The test in delete did not take into account for mixed case.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.25  1993/04/12  01:13:05  syd
!  * Move first name to lastname if lastname blank.
!  * this is the only real way for now.  I think that the dbz stuff, sorting,
!  * and other things all hope to see a lastname.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.24  1993/04/12  01:10:15  syd
!  * fix @aliasname sort problem
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.23  1993/04/12  01:08:16  syd
!  * test firstname == lastname and if true zero out firstname before
!  * writing to the aliases.text file.  Let me check out the source.  Now if
!  * you try to change a SYSTEM alias it lets you know and asks to verify
!  * that you are going to superceed that alias.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.22  1993/02/03  16:56:59  syd
!  * Fix which seek is being used on DBZ file, FILE * requires fseek
!  * From: syd via prompt from mfvargo@netcom.com (Michael Vargo)
!  *
!  * Revision 5.21  1993/01/20  03:37:16  syd
!  * Nits and typos in the NLS messages and corresponding default messages.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.20  1993/01/19  04:52:19  syd
!  * 	add c)hange alias command to alias helpfile
!  * 	if a deleted alias is changed, undelete it.  Also added the 'N'
!  * flag to changed aliases to help remind the user.  Documented it.
!  * Note:  if they mark the alias for deletion AFTER making the change it
!  * WILL be deleted. (and marked accordingly)
!  * 	modified alias mode title string to indicate when a resync was
!  * needed.
!  * 	allow editing alias file when none exist.
!  * 	Now aliases are check for illegal characters (and WS) and
!  * addresses are check for illegal WS when they are being entered.  If
!  * anything illegal is found and message is printed and they keep entering
!  * the item until they get it right.
!  * 	I fixed a couple of places where int should be long to match
!  * the declared type of alias_rec.length
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.19  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.18  1992/12/20  05:15:58  syd
!  * Add a c)hange alias, -u and -t options to listalias to list only user
!  * and only system aliases respectively.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.17  1992/12/13  17:59:18  syd
!  * Please write on the blackboard 500 times `NULL != 0.'
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.16  1992/12/11  02:09:06  syd
!  * Fix where the user creates a first new alias, then deletes it, the
!  * alias stays on screen, but the file really will be empty if it was the
!  * last alias, so the retry to delete gives 'cannot open ...file' messages
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.15  1992/12/11  01:58:22  syd
!  * Anytime elm wants to re-run newalias, selected is set to 0.
!  * (removing any limit in effect)
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.14  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.13  1992/12/07  03:02:03  syd
!  * On machines with 64 bit pointers (and 64 bit longs) using int
!  * for newmax causes pointer truncation.
!  * From: Jim Brown
!  *
!  * Revision 5.12  1992/11/26  00:46:50  syd
!  * Fix how errno is used so err is inited and used instead
!  * as errno gets overwritten by print system call
!  * From: Syd
!  *
!  * Revision 5.11  1992/11/15  01:24:34  syd
!  * The situation is that the .elm/aliases file is missing, but
!  * .elm/aliases.dir and .elm/aliases.pag exist (isn't serendipity
!  * wonderful?).  The ndbz functions tolerate this and just put a NULL
!  * pointer in the db structure for the data file FILE pointer.  However,
!  * get_one_alias() in listalias and elm doesn't account for the db_open()
!  * succeeding but the dbz_basef field being NULL, so it passes the NULL
!  * pointer to fread().  Detect null and return 0
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.10  1992/11/15  01:15:28  syd
!  * The alias message_count isn't set to zero if the last alias has
!  * been deleted from the alias table. As no aliases are reread from
!  * the aliases database the message_count is left as it was before.
!  *
!  * Fixed that the function do_newalias() sometimes returns without freeing
!  * the buffer allocated before. The patch adds these free calls.
!  *
!  * When you erroneously type a number in your folder elm asks you for
!  * a new current message number. But now if you erase this one number
!  * and leave the string empty elm will set the new current message to
!  * the second message on our sun4! The patch adds a check for an empty
!  * string and returns the current number if no number was entered.
!  * From: vogt@isa.de (Gerald Vogt)
!  *
!  * Revision 5.9  1992/10/24  13:35:39  syd
!  * changes found by using codecenter on Elm 2.4.3
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.8  1992/10/19  16:58:18  syd
!  * more on the update of compiler warnings
!  * From: Syd
!  *
!  * Revision 5.7  1992/10/19  16:50:41  syd
!  * Fix a couple more compiler gripes from SYSVR4
!  * From: Tom Moore <tmoore@wnas.DaytonOH.NCR.COM>
!  *
!  * Revision 5.6  1992/10/17  22:47:09  syd
!  * adds the function bytemap() and the macros MAPIN and MAPOUT from the file
!  * lib/ndbz.c in the file src/alias.c.
!  *
!  * prevent elm from exiting when resyncing the empty incoming mailbox.
!  * From: vogt@isa.de (Gerald Vogt)
!  *
!  * Revision 5.5  1992/10/11  01:46:35  syd
!  * change dbm name to dbz to avoid conflicts with partial call
!  * ins from shared librarys, and from mixing code with yp code.
!  * From: Syd via prompt from Jess Anderson
!  *
!  * Revision 5.4  1992/10/11  01:21:17  syd
!  * 1. If firstname && lastname is null then copy aliasname into the
!  * personal name field (inside the ()'s) when creating an alias
!  * from the menu using the 'n' command.
!  *
!  * 2. Now if for some reason and alias has a null personal name field
!  * (the person hand edited aliases.text) the blank () is not printed
!  * as part of the address.  This actually cured another problem, where
!  * the To: field on the screen (when you hit 'm' on the alias menu)
!  * used to be blank, now the address shows up....
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.3  1992/10/11  01:07:52  syd
!  * get_return() assumes that message_count reflects the number of
!  * messages in the current folder, but the message_count it's seeing
!  * from the alias subsystem is actually the *alias* count.
!  * toggle the main state before and after calling get_return().
!  * From: cliff@sfn.ORG (R. Cliff Young)
!  *
!  * Revision 5.2  1992/10/11  00:59:39  syd
!  * Fix some compiler warnings that I receive compiling Elm on my SVR4
!  * machine.
!  * From: Tom Moore <tmoore@fievel.DaytonOH.NCR.COM>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This file contains alias stuff
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: alias.c,v 1.4 1998/11/07 16:41:29 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.4 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This file contains alias stuff
  
***************
*** 269,277 ****
--- 22,41 ----
  #include <sys/stat.h>
  #include "s_aliases.h"
  #include "ndbz.h"
+ #include "me.h"
  
  #define	ECHOIT	1 	/* echo on for prompting */
  
+ static int get_aliasname P_((
+ 			     char *aliasname, char *buffer,
+ 			     int *duplicate,
+ 			     int size,int  buffer_size));
+ 
+ static int superceed_system P_((
+ 				int this_alias,
+ 				char *buffer,
+ 				int buffer_size));
+ 
  /*
   * A simple macro to make it easier to remember how to do a simple
   * resync and not screw up whether or not to prompt on deletions.
***************
*** 281,289 ****
  
  extern char *alias_type(), *get_alias_address();
  char *error_description(), *get_parens();
- void get_realnames();
  void install_aliases();
  
  int  is_system=0;		/* system file updating?     */
  
  extern int errno;
--- 45,58 ----
  
  extern char *alias_type(), *get_alias_address();
  char *error_description(), *get_parens();
  void install_aliases();
  
+ static void get_realnames P_((char *, char *, char *, char *, char *,
+ 			      int, int, int, int));
+ static int add_alias P_((int, int));
+ static int ask_accept P_((char *, char *, char *, char *, char *, char *,
+ 			  int, int, int));
+ 
  int  is_system=0;		/* system file updating?     */
  
  extern int errno;
***************
*** 436,442 ****
  
  	/* If hash file hasn't changed, don't bother re-reading. */
  
! 	sprintf(fname, "%s/%s", home, ALIAS_DATA);
  
  	if (stat(fname, &hst) == 0) {			/* File exists */
  	    if (hst.st_ctime == user_ctime &&
--- 205,211 ----
  
  	/* If hash file hasn't changed, don't bother re-reading. */
  
! 	strfcpy(fname,user_data_file,sizeof fname);
  
  	if (stat(fname, &hst) == 0) {			/* File exists */
  	    if (hst.st_ctime == user_ctime &&
***************
*** 480,488 ****
  
  }
  
! int
! add_alias(replace, to_replace)
! int replace, to_replace;
  {
  /*
   *	Add an alias to the user alias text file.  If there
--- 249,256 ----
  
  }
  
! static int add_alias(replace, to_replace)
!      int replace, to_replace;
  {
  /*
   *	Add an alias to the user alias text file.  If there
***************
*** 524,538 ****
  	  * There is only on alias tagged.  Ask the question
  	  * but the default response is NO.
  	  */
! 	    PutLine0(LINES-2,0, catgets(elm_msg_cat,
! 	            AliasesSet, AliasesOneTagged,
! 	            "There is 1 alias tagged..."));
  	    CleartoEOLN();
! 	    MCsprintf(buffer, catgets(elm_msg_cat,
! 	            AliasesSet, AliasesCreateGroup,
! 	            "Create group alias? (%c/%c) "),
! 	        *def_ans_yes, *def_ans_no);
! 	    ch = want_to(buffer, *def_ans_no, LINES-3, 0);
  	}
  	else if (tagged > 1) {
  	 /*
--- 292,307 ----
  	  * There is only on alias tagged.  Ask the question
  	  * but the default response is NO.
  	  */
! 	    PutLine0(elm_LINES-2,0, catgets(elm_msg_cat,
! 					    AliasesSet, AliasesOneTagged,
! 					    "There is 1 alias tagged..."));
  	    CleartoEOLN();
! 	    elm_sfprintf(buffer, sizeof buffer,
! 			 CATGETS(elm_msg_cat,
! 				 AliasesSet, AliasesCreateGroup,
! 				 "Create group alias? (%c/%c) "),
! 			 *def_ans_yes, *def_ans_no);
! 	    ch = want_to(buffer, *def_ans_no, elm_LINES-3, 0);
  	}
  	else if (tagged > 1) {
  	 /*
***************
*** 540,554 ****
  	  * wants to create a group alias.  The default response
  	  * is YES.
  	  */
! 	    PutLine1(LINES-2,0, catgets(elm_msg_cat,
! 	            AliasesSet, AliasesManyTagged,
! 	            "There are %d aliases tagged..."), tagged);
  	    CleartoEOLN();
! 	    MCsprintf(buffer, catgets(elm_msg_cat,
! 	            AliasesSet, AliasesCreateGroup,
! 	            "Create group alias? (%c/%c) "),
! 	        *def_ans_yes, *def_ans_no);
! 	    ch = want_to(buffer, *def_ans_yes, LINES-3, 0);
  	}
  
  /*
--- 309,325 ----
  	  * wants to create a group alias.  The default response
  	  * is YES.
  	  */
! 	    PutLineX(elm_LINES-2,0, CATGETS(elm_msg_cat,
! 					    AliasesSet, AliasesManyTagged,
! 					    "There are %d aliases tagged..."),
! 		     tagged);
  	    CleartoEOLN();
! 	    elm_sfprintf(buffer, sizeof buffer,
! 			 CATGETS(elm_msg_cat,
! 				 AliasesSet, AliasesCreateGroup,
! 				 "Create group alias? (%c/%c) "),
! 			 *def_ans_yes, *def_ans_no);
! 	    ch = want_to(buffer, *def_ans_yes, elm_LINES-3, 0);
  	}
  
  /*
***************
*** 558,568 ****
   *	and the user responded correctly).
   */
  	if (ch == *def_ans_yes) {
! 	    strcpy(address1, aliases[leftoff]->alias);
  	    for (i=leftoff+1; i < message_count; i++) {
  	        if (ison(aliases[i]->status, TAGGED)) {
! 	            strcat(address1, ",");
! 	            strcat(address1, aliases[i]->alias);
  	        }
  	    }
  	}
--- 329,341 ----
   *	and the user responded correctly).
   */
  	if (ch == *def_ans_yes) {
! 	    strfcpy(address1, aliases[leftoff]->alias,
! 		    sizeof address1);
  	    for (i=leftoff+1; i < message_count; i++) {
  	        if (ison(aliases[i]->status, TAGGED)) {
! 	            strfcat(address1, ",", sizeof address1);
! 	            strfcat(address1, aliases[i]->alias, 
! 			    sizeof address1);
  	        }
  	    }
  	}
***************
*** 575,581 ****
   *	current alias.
   */
  	if (replace) {
! 	    strcpy(aliasname, aliases[to_replace]->alias);
  	/*
  	 *  First, see if what we are replacing is a SYSTEM
  	 *  alias.  If so, we need to ask a question.
--- 348,355 ----
   *	current alias.
   */
  	if (replace) {
! 	    strfcpy(aliasname, aliases[to_replace]->alias,
! 		    sizeof aliasname);
  	/*
  	 *  First, see if what we are replacing is a SYSTEM
  	 *  alias.  If so, we need to ask a question.
***************
*** 587,609 ****
  	     *  If they don't want to superceed the SYSTEM alias then
  	     *  just return.
  	     */
! 	        if( ! superceed_system(to_replace, buffer)) {
! 	            ClearLine(LINES-2);
  	            return(0);
  	        }
  	    }
  	}
  	else {
! 	    strcpy(buffer, catgets(elm_msg_cat,
! 	            AliasesSet, AliasesEnterAliasName, "Enter alias name: "));
! 	    PutLine0(LINES-2,0, buffer);
  	    CleartoEOLN();
  	    *aliasname = '\0';
! 	    if ((replace = get_aliasname(aliasname, buffer, &to_replace)) < 0) {
! 	        dprint(3, (debugfile, 
! 	            "Aliasname [%s] was rejected in add_alias\n", aliasname));
! 	        ClearLine(LINES-2);
! 	        return(0);
  	    }
  	}
  
--- 361,394 ----
  	     *  If they don't want to superceed the SYSTEM alias then
  	     *  just return.
  	     */
! 	        if( ! superceed_system(to_replace, buffer, sizeof buffer)) {
! 	            ClearLine(elm_LINES-2);
  	            return(0);
  	        }
  	    }
  	}
  	else {
! 	    strfcpy(buffer, catgets(elm_msg_cat,
! 				   AliasesSet, AliasesEnterAliasName, 
! 				   "Enter alias name: "),
! 		    sizeof buffer);
! 	    PutLine0(elm_LINES-2,0, buffer);
  	    CleartoEOLN();
  	    *aliasname = '\0';
! 
! 	    replace = get_aliasname(aliasname, buffer, &to_replace,
! 				    sizeof aliasname, sizeof buffer);
! 	    while (REDRAW_MARK == replace) {
! 	      PutLine0(elm_LINES-2,0, buffer);
! 	      replace = get_aliasname(aliasname, buffer, &to_replace,
! 				      sizeof aliasname, sizeof buffer);
! 	    }
! 
! 	    if (replace < 0) {
! 	      dprint(3, (debugfile, 
! 			 "Aliasname [%s] was rejected in add_alias\n", aliasname));
! 	      ClearLine(elm_LINES-2);
! 	      return(0);
  	    }
  	}
  
***************
*** 613,623 ****
   *	there.  So we copy some defaults from the existing alias.
   */
  	if (replace) {
! 	    strcpy(lastname, aliases[to_replace]->last_name);
! 	    strcpy(firstname, aliases[to_replace]->name);
  	    ch_ptr = strstr(firstname, lastname);
! 	    *(ch_ptr-1) = '\0';
! 	    strcpy(comment, aliases[to_replace]->comment);
  	}
  	else {
  	    *lastname = '\0';
--- 398,411 ----
   *	there.  So we copy some defaults from the existing alias.
   */
  	if (replace) {
! 	    strfcpy(lastname, aliases[to_replace]->last_name,
! 		    sizeof lastname);
! 	    strfcpy(firstname, aliases[to_replace]->name,
! 		    sizeof firstname);
  	    ch_ptr = strstr(firstname, lastname);
! 	    if (ch_ptr)
! 	      *(ch_ptr-1) = '\0';
! 	    strfcpy(comment, aliases[to_replace]->comment, sizeof comment);
  	}
  	else {
  	    *lastname = '\0';
***************
*** 624,630 ****
  	    *firstname = '\0';
  	    *comment = '\0';
  	}
! 	get_realnames(aliasname, firstname, lastname, comment, buffer);
  
  /*
   *	Since there are no tagged aliases, we must ask for an
--- 412,420 ----
  	    *firstname = '\0';
  	    *comment = '\0';
  	}
! 	get_realnames(aliasname, firstname, lastname, comment, buffer,
! 		      sizeof firstname, sizeof lastname, sizeof comment,
! 		      sizeof buffer);
  
  /*
   *	Since there are no tagged aliases, we must ask for an
***************
*** 632,657 ****
   *	presented.
   */
  	if (tagged == 0) {
! 	    sprintf(buffer, catgets(elm_msg_cat,
! 	            AliasesSet, AliasesEnterAddress,
! 	            "Enter address for %s: "), aliasname);
! 	    PutLine0(LINES-2,0, buffer);
  	    CleartoEOLN();
  	    if (replace) {
! 	        strcpy(address1, aliases[to_replace]->address);
  	    }
  	    else {
  	        *address1 = '\0';
  	    }
  	    do {
! 	        optionally_enter(address1, LINES-2, strlen(buffer),
! 	                         FALSE, FALSE);
! 	        Raw(ON);
! 	        if (strlen(address1) == 0) {
! 	            error(catgets(elm_msg_cat, AliasesSet, AliasesNoAddressSpec,
! 	                    "No address specified!"));
! 	            return(0);
! 	        }
  	    } while (check_address(address1) == -1);
  
  	    clear_error();			/* Just in case */
--- 422,466 ----
   *	presented.
   */
  	if (tagged == 0) {
! 	    elm_sfprintf(buffer, sizeof buffer,
! 			 CATGETS(elm_msg_cat,
! 				 AliasesSet, AliasesEnterAddress,
! 				 "Enter address for %s: "), 
! 			 aliasname);
! 	    PutLine0(elm_LINES-2,0, buffer);
  	    CleartoEOLN();
  	    if (replace) {
! 	        strfcpy(address1, aliases[to_replace]->address,
! 			sizeof address1);
  	    }
  	    else {
  	        *address1 = '\0';
  	    }
  	    do {
! 	      int status =
! 	        optionally_enter(address1, elm_LINES-2, strlen(buffer),
! 	                         OE_REDRAW_MARK, sizeof address1);
! 
! 	      while (REDRAW_MARK == status) {
! 		elm_sfprintf(buffer, sizeof buffer,
! 			     CATGETS(elm_msg_cat,
! 				     AliasesSet, AliasesEnterAddress,
! 				     "Enter address for %s: "), 
! 			     aliasname);
! 		PutLine0(elm_LINES-2,0, buffer);
! 		status =
! 		  optionally_enter(address1, elm_LINES-2, strlen(buffer),
! 				   OE_REDRAW_MARK|OE_APPEND_CURRENT,
! 				   sizeof address1);
! 	      }
! 
! 	      if (0 != status ||
! 		  strlen(address1) == 0) {
! 		lib_error(CATGETS(elm_msg_cat, AliasesSet, 
! 				  AliasesNoAddressSpec,
! 				  "No address specified!"));
! 		return(0);
! 	      }
  	    } while (check_address(address1) == -1);
  
  	    clear_error();			/* Just in case */
***************
*** 658,664 ****
  	}
  
  	if(ask_accept(aliasname, firstname, lastname, comment, address1,
! 	        buffer, replace, to_replace)) {
  	 /*
  	  * We can only clear the tags after we know that the
  	  * alias was added.  This allows the user to back out
--- 467,474 ----
  	}
  
  	if(ask_accept(aliasname, firstname, lastname, comment, address1,
! 		      buffer, replace, to_replace,
! 		      sizeof buffer)) {
  	 /*
  	  * We can only clear the tags after we know that the
  	  * alias was added.  This allows the user to back out
***************
*** 705,734 ****
  	if (current_mail_message == 0) {
  	 dprint(4, (debugfile, 
  		"Add current alias called without any current message!\n"));
! 	 error(catgets(elm_msg_cat, AliasesSet, AliasesNoMessage,
! 		"No message to alias to!"));
  	 return(0);
  	}
  	current_header = headers[current_mail_message - 1];
  	
! 	strcpy(buffer, catgets(elm_msg_cat, AliasesSet, AliasesCurrentMessage,
! 		"Current message address aliased to: "));
! 	PutLine0(LINES-2,0, buffer);
  	CleartoEOLN();
  	*aliasname = '\0';
! 	if ((replace = get_aliasname(aliasname, buffer, &to_replace)) < 0) {
  	    dprint(3, (debugfile, 
  	        "Aliasname [%s] was rejected in add_current_alias\n",
  	        aliasname));
! 	    ClearLine(LINES-2);
  	    return(0);
  	}
  
! 	/* use full name in current message for default comment */
! 	tail_of(current_header->from, comment_buff, current_header->to);
! 	if(index(comment_buff, (int)'!') || index(comment_buff, (int)'@'))
! 	  /* never mind - it's an address not a full name */
! 	  *comment_buff = '\0';
  
  /*
   *	Try to break up the From: comment into firstname, lastname, and
--- 515,554 ----
  	if (current_mail_message == 0) {
  	 dprint(4, (debugfile, 
  		"Add current alias called without any current message!\n"));
! 	 lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesNoMessage,
! 			   "No message to alias to!"));
  	 return(0);
  	}
  	current_header = headers[current_mail_message - 1];
  	
! 	strfcpy(buffer, catgets(elm_msg_cat, AliasesSet, AliasesCurrentMessage,
! 				"Current message address aliased to: "),
! 		sizeof buffer);
! 	PutLine0(elm_LINES-2,0, buffer);
  	CleartoEOLN();
  	*aliasname = '\0';
! 	replace = get_aliasname(aliasname, buffer, &to_replace,
! 				sizeof aliasname, sizeof buffer);
! 	while (REDRAW_MARK == replace) {
! 	  PutLine0(elm_LINES-2,0, buffer);
! 	  replace = get_aliasname(aliasname, buffer, &to_replace,
! 				  sizeof aliasname, sizeof buffer);
! 	}
! 	if (replace < 0) {
  	    dprint(3, (debugfile, 
  	        "Aliasname [%s] was rejected in add_current_alias\n",
  	        aliasname));
! 	    ClearLine(elm_LINES-2);
  	    return(0);
  	}
  
! 	/* take fullname if there was exatcly one address */
! 	comment_buff[0] = '\0';
! 	if (current_header->from && 
! 	    current_header->from[0].fullname &&
! 	    !current_header->from[1].fullname)
! 	  strfcpy(comment_buff,current_header->from[0].fullname,
! 		  sizeof comment_buff);
  
  /*
   *	Try to break up the From: comment into firstname, lastname, and
***************
*** 755,761 ****
  	    *   Get firstname and move bufptr.
  	    */
  	        *chspace = '\0';
! 	        strcpy(firstname, bufptr);
  	        bufptr = chspace + 1;			/* Move the pointer */
  	        while (*bufptr == SPACE) bufptr++;
  	    }
--- 575,581 ----
  	    *   Get firstname and move bufptr.
  	    */
  	        *chspace = '\0';
! 	        strfcpy(firstname, bufptr, sizeof firstname);
  	        bufptr = chspace + 1;			/* Move the pointer */
  	        while (*bufptr == SPACE) bufptr++;
  	    }
***************
*** 776,797 ****
  	        *   probably a middle initial.  Add it to firstname
  	        *   and shift.
  	        */
! 	            strcat(firstname, " ");
! 	            strcat(firstname, bufptr);
  	            bufptr = chspace + 1;		/* Move the pointer */
  	            while (*bufptr == SPACE) bufptr++;
  	            goto above;
  	        }
! 	        strcpy(lastname, bufptr);
  	        bufptr = chspace + 1;			/* Move the pointer */
  	        while (*bufptr == SPACE) bufptr++;
! 	        strcpy(comment, bufptr);
  	    }
  	    else {
  	   /*
  	    *   Only a lastname left.
  	    */
! 	        strcpy(lastname, bufptr);
  	    }
  
  	/*
--- 596,617 ----
  	        *   probably a middle initial.  Add it to firstname
  	        *   and shift.
  	        */
! 	            strfcat(firstname, " ", sizeof firstname);
! 	            strfcat(firstname, bufptr, sizeof firstname);
  	            bufptr = chspace + 1;		/* Move the pointer */
  	            while (*bufptr == SPACE) bufptr++;
  	            goto above;
  	        }
! 	        strfcpy(lastname, bufptr, sizeof lastname);
  	        bufptr = chspace + 1;			/* Move the pointer */
  	        while (*bufptr == SPACE) bufptr++;
! 	        strfcpy(comment, bufptr, sizeof comment);
  	    }
  	    else {
  	   /*
  	    *   Only a lastname left.
  	    */
! 	        strfcpy(lastname, bufptr, sizeof lastname);
  	    }
  
  	/*
***************
*** 811,826 ****
  	    }
  	}
  
! 	get_realnames(aliasname, firstname, lastname, comment, buffer);
  
  	/* grab the return address of this message */
  	main_state(); /* toggle main state so that message_count is right */
! 	get_return(address1, current_mail_message-1);
  	main_state(); /* toggle main state back to alias mode */
! 	strcpy(address1, strip_parens(address1));	/* remove parens! */
  
  	return(ask_accept(aliasname, firstname, lastname, comment, address1,
! 	        buffer, replace, to_replace));
  
  }
  
--- 631,649 ----
  	    }
  	}
  
! 	get_realnames(aliasname, firstname, lastname, comment, buffer,
! 		      sizeof firstname, sizeof lastname, sizeof comment,
! 		      sizeof buffer);
  
  	/* grab the return address of this message */
  	main_state(); /* toggle main state so that message_count is right */
! 	get_return(address1, current_mail_message-1, sizeof address1);
  	main_state(); /* toggle main state back to alias mode */
! 	strfcpy(address1, strip_parens(address1),
! 		sizeof address1);	/* remove parens! */
  
  	return(ask_accept(aliasname, firstname, lastname, comment, address1,
! 			  buffer, replace, to_replace, sizeof buffer));
  
  }
  
***************
*** 838,844 ****
  	char buffer[SLEN];
  	int  err;
  	
! 	sprintf(fname,"%s/%s", home, ALIAS_TEXT);
  	
  	save_file_stats(fname);
  	if ((file = fopen(fname, "a")) == NULL) {
--- 661,667 ----
  	char buffer[SLEN];
  	int  err;
  	
! 	strfcpy(fname,user_text_file,sizeof fname);
  	
  	save_file_stats(fname);
  	if ((file = fopen(fname, "a")) == NULL) {
***************
*** 847,866 ****
  		 "Failure attempting to add alias to file %s within %s",
  		   fname, "add_to_alias_text"));
  	  dprint(2, (debugfile, "** %s **\n", error_description(err)));
! 	  error1(catgets(elm_msg_cat, AliasesSet, AliasesCouldntOpenAdd,
! 		 "Couldn't open %s to add new alias!"), fname);
  	  return(1);
  	}
  
  	if (strlen(firstname) == 0) {
! 	    strcpy(buffer, lastname);  
  	}
  	else {
! 	    sprintf(buffer, "%s; %s", lastname, firstname);
  	}
  	if (strlen(comment) != 0) {
! 	    strcat(buffer, ", ");
! 	    strcat(buffer, comment);
  	}
  	if (fprintf(file,"%s = %s = %s\n", aliasname, buffer, address) == EOF) {
  	    err = errno;
--- 670,691 ----
  		 "Failure attempting to add alias to file %s within %s",
  		   fname, "add_to_alias_text"));
  	  dprint(2, (debugfile, "** %s **\n", error_description(err)));
! 	  lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesCouldntOpenAdd,
! 			    "Couldn't open %s to add new alias!"), 
! 		    fname);
  	  return(1);
  	}
  
  	if (strlen(firstname) == 0) {
! 	    strfcpy(buffer, lastname, sizeof buffer);  
  	}
  	else {
! 	  elm_sfprintf(buffer, sizeof buffer,
! 		       FRM("%s; %s"), lastname, firstname);
  	}
  	if (strlen(comment) != 0) {
! 	    strfcat(buffer, ", ", sizeof buffer);
! 	    strfcat(buffer, comment, sizeof buffer);
  	}
  	if (fprintf(file,"%s = %s = %s\n", aliasname, buffer, address) == EOF) {
  	    err = errno;
***************
*** 868,875 ****
  		       "Failure attempting to write alias to file within %s",
  		       fname, "add_to_alias_text"));
  	    dprint(2, (debugfile, "** %s **\n", error_description(err)));
! 	    error1(catgets(elm_msg_cat, AliasesSet, AliasesCouldntWrite,
! 		   "Couldn't write alias to file %s!"), fname);
  	    fclose(file);
  	    return(1);
  	}
--- 693,701 ----
  		       "Failure attempting to write alias to file within %s",
  		       fname, "add_to_alias_text"));
  	    dprint(2, (debugfile, "** %s **\n", error_description(err)));
! 	    lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesCouldntWrite,
! 			      "Couldn't write alias to file %s!"), 
! 		      fname);
  	    fclose(file);
  	    return(1);
  	}
***************
*** 881,886 ****
--- 707,715 ----
  	return(0);
  }
  
+ static int parse_aliases P_((char *, char *, int, int)); /* Prototype */
+ 
+ 
  delete_from_alias_text(name, num_to_delete)
  char **name;
  int num_to_delete;
***************
*** 905,915 ****
  
  	delete_continues = FALSE;
  
! 	for (i=0; i < num_to_delete; i++)
! 	  strcat(name[i], ","); 
! 
! 	sprintf(fname,"%s/%s", home, ALIAS_TEXT);
! 	sprintf(tmpfname,"%s/%s.t", home, ALIAS_TEXT);
  	
  	save_file_stats(fname);
  
--- 734,742 ----
  
  	delete_continues = FALSE;
  
! 	strfcpy(fname,user_text_file,sizeof fname);
! 	elm_sfprintf(tmpfname,sizeof tmpfname,
! 		     FRM("%s.t"), user_text_file);
  	
  	save_file_stats(fname);
  
***************
*** 919,926 ****
  		 "Failure attempting to delete alias from file %s within %s",
  		   fname, "delete_from_alias_text"));
  	  dprint(2, (debugfile, "** %s **\n", error_description(err)));
! 	  error1(catgets(elm_msg_cat, AliasesSet, AliasesCouldntOpenDelete,
! 		 "Couldn't open %s to delete alias!"), fname);
  	  return(1);
  	}
  
--- 746,754 ----
  		 "Failure attempting to delete alias from file %s within %s",
  		   fname, "delete_from_alias_text"));
  	  dprint(2, (debugfile, "** %s **\n", error_description(err)));
! 	  lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesCouldntOpenDelete,
! 			    "Couldn't open %s to delete alias!"), 
! 		    fname);
  	  return(1);
  	}
  
***************
*** 930,937 ****
  		 "Failure attempting to open temp file %s within %s",
  		   tmpfname, "delete_from_alias_text"));
  	  dprint(2, (debugfile, "** %s **\n", error_description(err)));
! 	  error1(catgets(elm_msg_cat, AliasesSet, AliasesCouldntOpenTemp,
! 	  	 "Couldn't open temp file %s to delete alias!"), tmpfname);
  	  return(1);
  	}
  
--- 758,766 ----
  		 "Failure attempting to open temp file %s within %s",
  		   tmpfname, "delete_from_alias_text"));
  	  dprint(2, (debugfile, "** %s **\n", error_description(err)));
! 	  lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesCouldntOpenTemp,
! 			    "Couldn't open temp file %s to delete alias!"), 
! 		    tmpfname);
  	  return(1);
  	}
  
***************
*** 940,952 ****
  	  if (! whitespace(line_in_file[0])) {
  	    delete_continues = FALSE;
  	    if (line_in_file[0] != '#') {
! 	      if (num_aliases = parse_aliases(line_in_file, rest_of_line)) {
  	        for (i=0; i < num_to_delete && num_aliases; i++) {
! 	          if ((s = strstr(line_in_file, name[i])) != NULL) {
  /*
   *	Collapse the to be deleted alias out of line_in_file
   */
! 	            rest = index(s, (int)',');
  	            for (++rest; *rest; rest++)
  	              *s++ = *rest;
  	            *s = '\0';
--- 769,787 ----
  	  if (! whitespace(line_in_file[0])) {
  	    delete_continues = FALSE;
  	    if (line_in_file[0] != '#') {
! 	      if (num_aliases = parse_aliases(line_in_file, rest_of_line,
! 					      sizeof line_in_file,
! 					      sizeof rest_of_line)) {
  	        for (i=0; i < num_to_delete && num_aliases; i++) {
! 		  char buf[LONG_STRING];
! 		  strfcpy(buf,name[i], sizeof buf);
! 		  strfcat(buf,",", sizeof buf);
! 
! 	          if ((s = strstr(line_in_file, buf)) != NULL) {
  /*
   *	Collapse the to be deleted alias out of line_in_file
   */
! 	            rest = index(s, ',');
  	            for (++rest; *rest; rest++)
  	              *s++ = *rest;
  	            *s = '\0';
***************
*** 955,961 ****
  	        }
  	        if (num_aliases) {
  	          *(line_in_file + strlen(line_in_file) - 1) = ' ';
! 	          strcat(line_in_file, rest_of_line);
  	        }
  	        else {
  	          delete_continues = TRUE;
--- 790,797 ----
  	        }
  	        if (num_aliases) {
  	          *(line_in_file + strlen(line_in_file) - 1) = ' ';
! 	          strfcat(line_in_file, rest_of_line,
! 			  sizeof line_in_file);
  	        }
  	        else {
  	          delete_continues = TRUE;
***************
*** 970,977 ****
  		"Failure attempting to write to temp file %s within %s",
  		tmpfname, "delete_from_alias_text"));
  	      dprint(2, (debugfile, "** %s **\n", error_description(err)));
! 	      error1(catgets(elm_msg_cat, AliasesSet, AliasesCouldntWriteTemp,
! 		"Couldn't write to temp file %s!"), tmpfname);
  	      fclose(file);
  	      fclose(tmp_file);
  	      unlink(tmpfname);
--- 806,815 ----
  		"Failure attempting to write to temp file %s within %s",
  		tmpfname, "delete_from_alias_text"));
  	      dprint(2, (debugfile, "** %s **\n", error_description(err)));
! 	      lib_error(CATGETS(elm_msg_cat, AliasesSet, 
! 				AliasesCouldntWriteTemp,
! 				"Couldn't write to temp file %s!"), 
! 			tmpfname);
  	      fclose(file);
  	      fclose(tmp_file);
  	      unlink(tmpfname);
***************
*** 983,990 ****
  	fclose(tmp_file);
  	if (rename(tmpfname, fname) != 0)
  	{
! 		error1(catgets(elm_msg_cat, AliasesSet, AliasesCouldntRenameTemp,
! 			"Couldn't rename temp file %s after deleting alias!"), tmpfname);
  		return(1);
  	}
  
--- 821,830 ----
  	fclose(tmp_file);
  	if (rename(tmpfname, fname) != 0)
  	{
! 		lib_error(CATGETS(elm_msg_cat, AliasesSet, 
! 				  AliasesCouldntRenameTemp,
! 				  "Couldn't rename temp file %s after deleting alias!"), 
! 			  tmpfname);
  		return(1);
  	}
  
***************
*** 993,998 ****
--- 833,839 ----
  	return(0);
  }
  
+ void
  alias()
  {
  /*
***************
*** 999,1005 ****
   *	Work with alias commands...
   */
  
! 	char name[NLEN], *address, ch, buffer[SLEN];
  	char *commap;
  	int  key_offset;        /** Position offset within keyboard string   **/
  	static int  newaliases = 0;
--- 840,847 ----
   *	Work with alias commands...
   */
  
! 	char name[NLEN], *address, buffer[SLEN];
! 	int ch;
  	char *commap;
  	int  key_offset;        /** Position offset within keyboard string   **/
  	static int  newaliases = 0;
***************
*** 1018,1024 ****
  	open_alias_files(FALSE);	/* First, read the alias files. RLH */
  
  	alias_screen(newaliases);
! 	define_softkeys(ALIAS);
  
  	while (1) {
  
--- 860,866 ----
  	open_alias_files(FALSE);	/* First, read the alias files. RLH */
  
  	alias_screen(newaliases);
! 	/* define_softkeys(ALIAS); */
  
  	while (1) {
  
***************
*** 1028,1041 ****
  
  	    ScreenSize(&newLINES, &newCOLUMNS);
  	    resize_screen = 0;
! 	    if (newLINES != LINES || newCOLUMNS != COLUMNS) {
! 	      LINES = newLINES, COLUMNS = newCOLUMNS;
  #undef max
  #define max(a,b)	       ((a) < (b) ? (b) : (a))
  	      if (mini_menu)
! 		headers_per_page = max (LINES - 13, 1);
  	      else
! 		headers_per_page = max (LINES -	 8, 1);	  /* 5 more headers! */
  #undef max
  	      redraw++;
  	    }
--- 870,883 ----
  
  	    ScreenSize(&newLINES, &newCOLUMNS);
  	    resize_screen = 0;
! 	    if (newLINES != elm_LINES || newCOLUMNS != elm_COLUMNS) {
! 	      elm_LINES = newLINES, elm_COLUMNS = newCOLUMNS;
  #undef max
  #define max(a,b)	       ((a) < (b) ? (b) : (a))
  	      if (mini_menu)
! 		headers_per_page = max (elm_LINES - 13, 1);
  	      else
! 		headers_per_page = max (elm_LINES -	 8, 1);	  /* 5 more headers! */
  #undef max
  	      redraw++;
  	    }
***************
*** 1049,1063 ****
  
  	  prompt(Prompt);
  	  CleartoEOLN();
! 	  ch = ReadCh();
! 	  MoveCursor(LINES-3,strlen(Prompt)); CleartoEOS();
! 	  
! 	  dprint(3, (debugfile, "\n-- Alias command: %c\n\n", ch));
  
  	  switch (ch) {
  	    case '?': redraw += alias_help();			break;
  
! 	    case '$': PutLine0(LINES-3, strlen(Prompt),
  			     catgets(elm_msg_cat, AliasesSet, AliasesResync,
  					"Resynchronize aliases..."));
  	           /*
--- 891,914 ----
  
  	  prompt(Prompt);
  	  CleartoEOLN();
! 	  ch = ReadCh(REDRAW_MARK|READCH_CURSOR);
! 	  MoveCursor(elm_LINES-3,strlen(Prompt)); CleartoEOS();
! 
! 	  if (isascii(ch) && isprint(ch)) {
! 	    dprint(4, (debugfile, "-- Alias command: %c [%d]\n",ch,ch));
! 	  } else {
! 	    dprint(4, (debugfile, "-- Alias command: [%d]\n",ch));
! 	  }
  
  	  switch (ch) {
+ 	  case HELP_MARK:
  	    case '?': redraw += alias_help();			break;
  
! 	    case REDRAW_MARK:
! 	    case 'L'&31: redraw++;                              break;
! 
! 
! 	    case '$': PutLine0(elm_LINES-3, strlen(Prompt),
  			     catgets(elm_msg_cat, AliasesSet, AliasesResync,
  					"Resynchronize aliases..."));
  	           /*
***************
*** 1071,1079 ****
  		      }
  		      break;
  
! 	    case 'a': PutLine0(LINES-3, strlen(Prompt),
! 			     catgets(elm_msg_cat, AliasesSet, AliasesAddCurrent,
! 					"Add address from current message..."));
  		      clear_error();
  		      if (add_current_alias()) {
  		          newaliases++;
--- 922,931 ----
  		      }
  		      break;
  
! 	    case 'a': PutLine0(elm_LINES-3, strlen(Prompt),
! 			       catgets(elm_msg_cat, AliasesSet, 
! 				       AliasesAddCurrent,
! 				       "Add address from current message..."));
  		      clear_error();
  		      if (add_current_alias()) {
  		          newaliases++;
***************
*** 1083,1089 ****
  
  	    case 'c':
  	              if (current > 0) {
! 	                  PutLine0(LINES-3, strlen(Prompt),
  			      catgets(elm_msg_cat,
  	                              AliasesSet, AliasesReplaceCurrent,
  	                              "Replace current alias in database..."));
--- 935,941 ----
  
  	    case 'c':
  	              if (current > 0) {
! 	                  PutLine0(elm_LINES-3, strlen(Prompt),
  			      catgets(elm_msg_cat,
  	                              AliasesSet, AliasesReplaceCurrent,
  	                              "Replace current alias in database..."));
***************
*** 1094,1108 ****
  		          }
  	              }
  	              else {
! 		          error(catgets(elm_msg_cat,
! 	                          AliasesSet, AliasesNoneToReplace,
! 				  "Warning: no aliases to replace!"));
  	              }
  		      break;
  
! 	    case 'e': PutLine1(LINES-3, strlen(Prompt),
! 	                  catgets(elm_msg_cat, AliasesSet, AliasesEdit,
! 	                      "Edit %s..."), ALIAS_TEXT);
  	           /*
  	            * Process aliases.text for deletions, etc.  You
  	            * have to do this *before* checking current because
--- 946,960 ----
  		          }
  	              }
  	              else {
! 		          lib_error(CATGETS(elm_msg_cat,
! 					    AliasesSet, AliasesNoneToReplace,
! 					    "Warning: no aliases to replace!"));
  	              }
  		      break;
  
! 	    case 'e': PutLineX(elm_LINES-3, strlen(Prompt),
! 			       CATGETS(elm_msg_cat, AliasesSet, AliasesEdit,
! 				       "Edit %s..."), USER_ALIAS_TEXT);
  	           /*
  	            * Process aliases.text for deletions, etc.  You
  	            * have to do this *before* checking current because
***************
*** 1112,1140 ****
  	              if (edit_aliases_text()) {
  	                  newaliases = 0;
  	              }
- 	              if (cursor_control) {
- 	                  transmit_functions(ON);	/* insurance */
- 	              }
  		      redraw++;
  		      break;
  
  	    case 'm':
  	              if (current > 0) {
! 	                  PutLine0(LINES-3, strlen(Prompt),
  	                      catgets(elm_msg_cat, AliasesSet, AliasesMail,
  	                          "Mail..."));
  	                  redraw += a_sendmsg(TRUE,allow_forms);
  	              }
  	              else {
! 		          error(catgets(elm_msg_cat,
! 	                          AliasesSet, AliasesNoneToMail,
! 				  "Warning: no aliases to send mail to!"));
  	              }
  		      break;
  
! 	    case 'n': PutLine0(LINES-3, strlen(Prompt),
! 			     catgets(elm_msg_cat, AliasesSet, AliasesAddNew,
! 					     "Add a new alias to database..."));
  		      clear_error();
  		      if (add_alias(FALSE, -1)) {
  		          newaliases++;
--- 964,989 ----
  	              if (edit_aliases_text()) {
  	                  newaliases = 0;
  	              }
  		      redraw++;
  		      break;
  
  	    case 'm':
  	              if (current > 0) {
! 	                  PutLine0(elm_LINES-3, strlen(Prompt),
  	                      catgets(elm_msg_cat, AliasesSet, AliasesMail,
  	                          "Mail..."));
  	                  redraw += a_sendmsg(TRUE,allow_forms);
  	              }
  	              else {
! 		          lib_error(CATGETS(elm_msg_cat,
! 					    AliasesSet, AliasesNoneToMail,
! 					    "Warning: no aliases to send mail to!"));
  	              }
  		      break;
  
! 	    case 'n': PutLine0(elm_LINES-3, strlen(Prompt),
! 			       catgets(elm_msg_cat, AliasesSet, AliasesAddNew,
! 				       "Add a new alias to database..."));
  		      clear_error();
  		      if (add_alias(FALSE, -1)) {
  		          newaliases++;
***************
*** 1147,1155 ****
  	    case 'i':
  	    case 'I':
  	    case 'r':
! 	    case 'R': PutLine0(LINES-3, strlen(Prompt),
! 			     catgets(elm_msg_cat, AliasesSet, AliasesAddReturn,
! 					"Return to main menu..."));
  	           /*
  	            * leaving the alias system.  Must check for
  	            * pending deletes, etc.  prompt is set to FALSE
--- 996,1005 ----
  	    case 'i':
  	    case 'I':
  	    case 'r':
! 	    case 'R': PutLine0(elm_LINES-3, strlen(Prompt),
! 			       catgets(elm_msg_cat, AliasesSet, 
! 				       AliasesAddReturn,
! 				       "Return to main menu..."));
  	           /*
  	            * leaving the alias system.  Must check for
  	            * pending deletes, etc.  prompt is set to FALSE
***************
*** 1169,1204 ****
  	    case SPACE:
  	    case 'v':
  		      if (newaliases) {		/* Need this ?? */
! 		          error(catgets(elm_msg_cat,
! 	                          AliasesSet, AliasesNotInstalled,
! 				  "Warning: new aliases not installed yet!"));
  	              }
  
  	              if (current > 0) {
  	                  if (aliases[current-1]->type & GROUP) {
! 	                      PutLine1(LINES-1, 0, catgets(elm_msg_cat,
! 	                              AliasesSet, AliasesGroupAlias,
! 				      "Group alias: %-60.60s"),
  	                          aliases[current-1]->address);
  		          }
  		          else {
! 	                      PutLine1(LINES-1, 0, catgets(elm_msg_cat,
! 	                              AliasesSet, AliasesAliasedAddress,
! 				      "Aliased address: %-60.60s"), 
! 	                          aliases[current-1]->address);
  		          }
  		      }
  	              else {
! 		          error(catgets(elm_msg_cat,
! 	                          AliasesSet, AliasesNoneToView,
! 				  "Warning: no aliases to view!"));
  		      }
  		      break;
  
  	    case 'x':
! 	    case 'X': PutLine0(LINES-3, strlen(Prompt),
! 			     catgets(elm_msg_cat, AliasesSet, AliasesAddReturn,
! 					"Return to main menu..."));
  	              exit_alias();
  		      clear_error();
  		      main_state();		/* Done with aliases. */
--- 1019,1057 ----
  	    case SPACE:
  	    case 'v':
  		      if (newaliases) {		/* Need this ?? */
! 		          lib_error(CATGETS(elm_msg_cat,
! 					    AliasesSet, AliasesNotInstalled,
! 					    "Warning: new aliases not installed yet!"));
  	              }
  
  	              if (current > 0) {
  	                  if (aliases[current-1]->type & GROUP) {
! 	                      PutLineX(elm_LINES-1, 0, 
! 				       CATGETS(elm_msg_cat,
! 					       AliasesSet, AliasesGroupAlias,
! 					       "Group alias: %-60.60s"),
  	                          aliases[current-1]->address);
  		          }
  		          else {
! 	                      PutLineX(elm_LINES-1, 0, 
! 				       CATGETS(elm_msg_cat,
! 					       AliasesSet, AliasesAliasedAddress,
! 					       "Aliased address: %-60.60s"), 
! 				       aliases[current-1]->address);
  		          }
  		      }
  	              else {
! 		          lib_error(CATGETS(elm_msg_cat,
! 					    AliasesSet, AliasesNoneToView,
! 					    "Warning: no aliases to view!"));
  		      }
  		      break;
  
  	    case 'x':
! 	    case 'X': PutLine0(elm_LINES-3, strlen(Prompt),
! 			       catgets(elm_msg_cat, AliasesSet, 
! 				       AliasesAddReturn,
! 				       "Return to main menu..."));
  	              exit_alias();
  		      clear_error();
  		      main_state();		/* Done with aliases. */
***************
*** 1208,1234 ****
  	    case 'F':
  	              if (current > 0) {
  		          clear_error();
! 		          strcpy(name, aliases[current-1]->alias);
  		          if (ch == 'F') {
! 		              strcpy(buffer, catgets(elm_msg_cat,
! 	                              AliasesSet, AliasesFullyExpanded,
! 				      "Fully expand alias: "));
! 		              PutLine0(LINES-2,0, buffer);
  		              CleartoEOS();
! 		              optionally_enter(name, LINES-2, strlen(buffer),
! 			          FALSE, FALSE);
  		          }
  	                  too_long = FALSE;
  		          address = get_alias_address(name, TRUE, &too_long);
  		          if (address != NULL) {
  		              while (TRUE) {
  	                          ClearScreen();
! 			          PutLine1(2,0, catgets(elm_msg_cat,
! 	                                  AliasesSet, AliasesAliasedFull,
! 					  "Aliased address for:\t%s\n\r"),
! 	                              name);
  		                  i = 4;
! 		                  while (i < LINES-2) {
  		                      if ((commap = index(address, (int)','))
  	                                          == NULL) {
  		                          PutLine0(i, 4, address);
--- 1061,1106 ----
  	    case 'F':
  	              if (current > 0) {
  		          clear_error();
! 		          strfcpy(name, aliases[current-1]->alias,
! 				  sizeof name);
  		          if (ch == 'F') {
! 			    int status;
! 			    
! 		              strfcpy(buffer, catgets(elm_msg_cat,
! 						      AliasesSet, 
! 						      AliasesFullyExpanded,
! 						      "Fully expand alias: "),
! 				      sizeof buffer);
! 		              PutLine0(elm_LINES-2,0, buffer);
  		              CleartoEOS();
! 		              status = optionally_enter(name, elm_LINES-2, 
! 					       strlen(buffer),
! 					       OE_REDRAW_MARK, sizeof name);
! 			      while (REDRAW_MARK == status) {
! 				PutLine0(elm_LINES-2,0, buffer);
! 				status = optionally_enter(name, elm_LINES-2, 
! 							  strlen(buffer),
! 							  OE_REDRAW_MARK|
! 							  OE_APPEND_CURRENT,
! 							  sizeof name);
! 				redraw++;
! 			      }
! 			      if (0 != status)
! 				break;
  		          }
+ 		      redraw2:
  	                  too_long = FALSE;
  		          address = get_alias_address(name, TRUE, &too_long);
  		          if (address != NULL) {
  		              while (TRUE) {
  	                          ClearScreen();
! 			          PutLineX(2,0, 
! 					   CATGETS(elm_msg_cat,
! 						   AliasesSet, AliasesAliasedFull,
! 						   "Aliased address for:\t%s\n\r"),
! 					   name);
  		                  i = 4;
! 		                  while (i < elm_LINES-2) {
  		                      if ((commap = index(address, (int)','))
  	                                          == NULL) {
  		                          PutLine0(i, 4, address);
***************
*** 1238,1247 ****
  		                      PutLine0(i++, 4, address);
  		                      address = commap+2;
  		                  }
! 	                          PutLine0(LINES-1, 0, catgets(elm_msg_cat,
  	                                  AliasesSet, AliasesPressReturn,
  					  "Press <return> to continue."));
! 			          (void) getchar();
  		                  if (commap == NULL) {
  			              redraw++;
  		                      break;
--- 1110,1122 ----
  		                      PutLine0(i++, 4, address);
  		                      address = commap+2;
  		                  }
! 	                          PutLine0(elm_LINES-1, 0, catgets(elm_msg_cat,
  	                                  AliasesSet, AliasesPressReturn,
  					  "Press <return> to continue."));
! 			          if (REDRAW_MARK == ReadCh(REDRAW_MARK)) {
! 				    redraw++;
! 				    goto redraw2;
! 				  }
  		                  if (commap == NULL) {
  			              redraw++;
  		                      break;
***************
*** 1249,1263 ****
  		              }
  		          }
  	                  else if (! too_long) {
! 			      error(catgets(elm_msg_cat,
! 	                              AliasesSet, AliasesNotFound,
! 				      "Not found."));
  		          }
  		      }
  	              else {
! 		          error(catgets(elm_msg_cat,
! 	                          AliasesSet, AliasesNoneToView,
! 				  "Warning: no aliases to view!"));
  		      }
  		      break;
  
--- 1124,1138 ----
  		              }
  		          }
  	                  else if (! too_long) {
! 			      lib_error(CATGETS(elm_msg_cat,
! 						AliasesSet, AliasesNotFound,
! 						"Not found."));
  		          }
  		      }
  	              else {
! 		          lib_error(CATGETS(elm_msg_cat,
! 					    AliasesSet, AliasesNoneToView,
! 					    "Warning: no aliases to view!"));
  		      }
  		      break;
  
***************
*** 1287,1298 ****
  	    show_current();
  	  else if (nufoot) {
  	    if (mini_menu) {
! 	      MoveCursor(LINES-7, 0);  
                CleartoEOS();
  	      show_alias_menu();
  	    }
  	    else {
! 	      MoveCursor(LINES-4, 0);
  	      CleartoEOS();
  	    }
  	    show_last_error();	/* for those operations that have to
--- 1162,1173 ----
  	    show_current();
  	  else if (nufoot) {
  	    if (mini_menu) {
! 	      MoveCursor(elm_LINES-7, 0);  
                CleartoEOS();
  	      show_alias_menu();
  	    }
  	    else {
! 	      MoveCursor(elm_LINES-4, 0);
  	      CleartoEOS();
  	    }
  	    show_last_error();	/* for those operations that have to
***************
*** 1317,1329 ****
  	char buffer[SLEN];
  
  
! 	error(catgets(elm_msg_cat, AliasesSet, AliasesUpdating,
! 		"Updating aliases..."));
  	if (sleepmsg > 0)
  		sleep(sleepmsg);
  
! 	sprintf(itextfile, "%s/%s", home, ALIAS_TEXT);
! 	sprintf(odatafile, "%s/%s", home, ALIAS_DATA);
  
  /*
   *	We need to unlimit everything since aliases are 
--- 1192,1204 ----
  	char buffer[SLEN];
  
  
! 	lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesUpdating,
! 			  "Updating aliases..."));
  	if (sleepmsg > 0)
  		sleep(sleepmsg);
  
! 	strfcpy(itextfile,user_text_file, sizeof itextfile);
! 	strfcpy(odatafile,user_data_file,sizeof odatafile);
  
  /*
   *	We need to unlimit everything since aliases are 
***************
*** 1333,1345 ****
  
  	na = do_newalias(itextfile, odatafile, TRUE, FALSE);
  	if (na >= 0) {
! 	    error1(catgets(elm_msg_cat, AliasesSet, AliasesReReading,
! 		  "Processed %d aliases.  Re-reading the database..."), na);
  	    if (sleepmsg > 0)
  		sleep(sleepmsg);
  	    open_alias_files(TRUE);
! 	    set_error(catgets(elm_msg_cat, AliasesSet, AliasesUpdatedOK,
! 		  "Aliases updated successfully."));
  	}
  }
  
--- 1208,1221 ----
  
  	na = do_newalias(itextfile, odatafile, TRUE, FALSE);
  	if (na >= 0) {
! 	    lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesReReading,
! 			      "Processed %d aliases.  Re-reading the database..."), 
! 		      na);
  	    if (sleepmsg > 0)
  		sleep(sleepmsg);
  	    open_alias_files(TRUE);
! 	    lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesUpdatedOK,
! 			      "Aliases updated successfully."));
  	}
  }
  
***************
*** 1363,1479 ****
  		alias_prompt = catgets(elm_msg_cat, AliasesSet, AliasesLongKey,
  			"Key you want help for: ");
  
! 	MoveCursor(LINES-3, 0);	CleartoEOS();
  
  	if (mini_menu) {
! 	  Centerline(LINES-3, catgets(elm_msg_cat, AliasesSet, AliasesKeyMenu,
   "Press the key you want help for, '?' for a key list, or '.' to exit help"));
  	}
  
  	lower_prompt(alias_prompt);
  
! 	while ((ch = ReadCh()) != '.') {
  	  switch(ch) {
! 	    case EOF : leave(0);
  	               break;
  	    case '?' : display_helpfile(ALIAS_HELP);	
  		       redraw++;
  		       return(redraw);
  
! 	    case '$': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpDollar,
! "$ = Force resynchronization of aliases, processing additions and deletions."));
  		      break;
  
! 	    case '/': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpSlash,
! 			"/ = Search for specified name or alias in list."));
  		      break;
  
  	    case RETURN:
  	    case LINE_FEED:
  	    case SPACE:
! 	    case 'v': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpv,
! 	    "v = View the address for the currently selected alias."));
  		      break;
  	
! 	    case 'a': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpa,
! 	    "a = Add (return) address of current message to alias database."));
  		      break;
  
! 	    case 'c': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpc,
! "c = Change current user alias, modifying alias database at next resync."));
  		      break;
  
! 	    case 'd': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpd,
! 	    "d = Mark the current alias for deletion from alias database."));
  		      break;
  
! 	    case ctrl('D'): error(catgets(elm_msg_cat, AliasesSet, AliasesHelpCtrlD,
! 	    "^D = Mark for deletion user aliases matching specified pattern."));
  		      break;
  
! 	    case 'e': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpe,
! 	    "e = Edit the alias text file directly (will run newalias)."));
  		      break;
  
! 	    case 'f': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpf,
! 		"f = Display fully expanded address of current alias."));
  		      break;
  
! 	    case 'l': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpl,
! 	    "l = Limit displayed aliases on the specified criteria."));
  		      break;
  
! 	    case ctrl('L'): error(catgets(elm_msg_cat, AliasesSet, AliasesHelpCtrlL,
! 		      "^L = Rewrite the screen."));
  	    	      break;
  
! 	    case 'm': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpm,
! 	    "m = Send mail to the current or tagged aliases."));
  		      break;
  
! 	    case 'n': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpn,
! "n = Add a new user alias, adding to alias database at next resync."));
  		      break;
  
  	    case 'r':
  	    case 'q':
! 	    case 'i': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpi,
! 		      "r,q,i = Return from alias menu (with prompting)."));
  	   	      break;
  		      
  	    case 'R':
  	    case 'Q':
! 	    case 'I': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpQ,
! 		      "R,Q,I = Return from alias menu (no prompting)."));
  	   	      break;
  		      
! 	    case 't': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpt,
! 		      "t = Tag current alias for further operations."));
  		      break;
  	
! 	    case 'T': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpT,
! 		      "T = Tag current alias and go to next alias."));
  		      break;
  	
! 	    case ctrl('T'): error(catgets(elm_msg_cat, AliasesSet, AliasesHelpCtrlT,
! 	    "^T = Tag aliases matching specified pattern."));
  		      break;
  
! 	    case 'u': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpu,
! 	    "u = Unmark the current alias for deletion from alias database."));
  		      break;
  
! 	    case ctrl('U'): error(catgets(elm_msg_cat, AliasesSet, AliasesHelpCtrlU,
! "^U = Mark for undeletion user aliases matching specified pattern."));
  		      break;
  
  	    case 'x':
! 	    case 'X': error(catgets(elm_msg_cat, AliasesSet, AliasesHelpX,
! 	    "x = Exit from alias menu, abandoning any pending deletions."));
  	   	      break;
  
! 	    default : error(catgets(elm_msg_cat, AliasesSet, AliasesHelpNoHelp,
! 			"That key isn't used in this section."));
  	   	      break;
  	  }
  	  lower_prompt(alias_prompt);
--- 1239,1365 ----
  		alias_prompt = catgets(elm_msg_cat, AliasesSet, AliasesLongKey,
  			"Key you want help for: ");
  
! 	MoveCursor(elm_LINES-3, 0);	CleartoEOS();
  
  	if (mini_menu) {
! 	  Centerline(elm_LINES-3, catgets(elm_msg_cat, AliasesSet, 
! 					  AliasesKeyMenu,
   "Press the key you want help for, '?' for a key list, or '.' to exit help"));
  	}
  
  	lower_prompt(alias_prompt);
  
! 	while ((ch = ReadCh(0|READCH_CURSOR)) != '.') {
  	  switch(ch) {
! 	  case EOF : leave(0);
  	               break;
+ 	  case HELP_MARK:
  	    case '?' : display_helpfile(ALIAS_HELP);	
  		       redraw++;
  		       return(redraw);
  
! 	    case '$': lib_error(CATGETS(elm_msg_cat, AliasesSet, 
! 					AliasesHelpDollar,
! 					"$ = Force resynchronization of aliases, processing additions and deletions."));
  		      break;
  
! 	  case FIND_MARK:
! 	    case '/': lib_error(CATGETS(elm_msg_cat, AliasesSet, 
! 					AliasesHelpSlash,
! 					"/ = Search for specified name or alias in list."));
  		      break;
  
  	    case RETURN:
  	    case LINE_FEED:
  	    case SPACE:
! 	    case 'v': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpv,
! 					"v = View the address for the currently selected alias."));
  		      break;
  	
! 	    case 'a':lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpa,
! 				       "a = Add (return) address of current message to alias database."));
  		      break;
  
! 	    case 'c': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpc,
! 					"c = Change current user alias, modifying alias database at next resync."));
  		      break;
  
! 	    case 'd': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpd,
! 					"d = Mark the current alias for deletion from alias database."));
  		      break;
  
! 	    case ctrl('D'): lib_error(CATGETS(elm_msg_cat, AliasesSet, 
! 					      AliasesHelpCtrlD,
! 					      "^D = Mark for deletion user aliases matching specified pattern."));
  		      break;
  
! 	    case 'e': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpe,
! 					"e = Edit the alias text file directly (will run newalias)."));
  		      break;
  
! 	    case 'f': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpf,
! 					"f = Display fully expanded address of current alias."));
  		      break;
  
! 	    case 'l': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpl,
! 					"l = Limit displayed aliases on the specified criteria."));
  		      break;
  
! 	    case ctrl('L'): lib_error(CATGETS(elm_msg_cat, AliasesSet, 
! 					      AliasesHelpCtrlL,
! 					      "^L = Rewrite the screen."));
  	    	      break;
  
! 	    case 'm': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpm,
! 					"m = Send mail to the current or tagged aliases."));
  		      break;
  
! 	    case 'n': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpn,
! 					"n = Add a new user alias, adding to alias database at next resync."));
  		      break;
  
  	    case 'r':
  	    case 'q':
! 	    case 'i': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpi,
! 					"r,q,i = Return from alias menu (with prompting)."));
  	   	      break;
  		      
  	    case 'R':
  	    case 'Q':
! 	    case 'I': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpQ,
! 					"R,Q,I = Return from alias menu (no prompting)."));
  	   	      break;
  		      
! 	    case 't': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpt,
! 					"t = Tag current alias for further operations."));
  		      break;
  	
! 	    case 'T': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpT,
! 					"T = Tag current alias and go to next alias."));
  		      break;
  	
! 	    case ctrl('T'): lib_error(CATGETS(elm_msg_cat, AliasesSet, 
! 					      AliasesHelpCtrlT,
! 					      "^T = Tag aliases matching specified pattern."));
  		      break;
  
! 	    case 'u': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpu,
! 					"u = Unmark the current alias for deletion from alias database."));
  		      break;
  
! 	    case ctrl('U'): lib_error(CATGETS(elm_msg_cat, AliasesSet, 
! 					      AliasesHelpCtrlU,
! 					      "^U = Mark for undeletion user aliases matching specified pattern."));
  		      break;
  
  	    case 'x':
! 	    case 'X': lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpX,
! 					"x = Exit from alias menu, abandoning any pending deletions."));
  	   	      break;
  
! 	    default : lib_error(CATGETS(elm_msg_cat, AliasesSet, 
! 					AliasesHelpNoHelp,
! 					"That key isn't used in this section."));
  	   	      break;
  	  }
  	  lower_prompt(alias_prompt);
***************
*** 1480,1486 ****
  	}
  
  	/* Remove help lines */
! 	MoveCursor(LINES-3, 0);	CleartoEOS();
  	return(redraw);
  }
  
--- 1366,1372 ----
  	}
  
  	/* Remove help lines */
! 	MoveCursor(elm_LINES-3, 0);	CleartoEOS();
  	return(redraw);
  }
  
***************
*** 1623,1633 ****
  	    selected = main_selected;
  	    header_page = main_page;
  
! 	    strcpy(item, catgets(elm_msg_cat, ElmSet, Elmitem, "message"));
! 	    strcpy(items, catgets(elm_msg_cat, ElmSet, Elmitems, "messages"));
! 	    strcpy(Item, catgets(elm_msg_cat, ElmSet, ElmItem, "Message"));
! 	    strcpy(Items, catgets(elm_msg_cat, ElmSet, ElmItems, "Messages"));
! 	    strcpy(Prompt, catgets(elm_msg_cat, ElmSet, ElmPrompt, "Command: "));
  
  	    dprint(3, (debugfile, "Leaving alias mode\n"));
  	    inalias = FALSE;
--- 1509,1525 ----
  	    selected = main_selected;
  	    header_page = main_page;
  
! 	    strfcpy(item, catgets(elm_msg_cat, ElmSet, Elmitem, "message"),
! 		    sizeof item);
! 	    strfcpy(items, catgets(elm_msg_cat, ElmSet, Elmitems, "messages"),
! 		    sizeof items);
! 	    strfcpy(Item, catgets(elm_msg_cat, ElmSet, ElmItem, "Message"),
! 		    sizeof Item);
! 	    strfcpy(Items, catgets(elm_msg_cat, ElmSet, ElmItems, "Messages"),
! 		    sizeof Items);
! 	    strfcpy(Prompt, catgets(elm_msg_cat, ElmSet, ElmPrompt, 
! 				    "Command: "),
! 		    sizeof Prompt);
  
  	    dprint(3, (debugfile, "Leaving alias mode\n"));
  	    inalias = FALSE;
***************
*** 1646,1656 ****
  	    selected = alias_selected;
  	    header_page = alias_page;
  
! 	    strcpy(item, catgets(elm_msg_cat, AliasesSet, Aliasesitem, "alias"));
! 	    strcpy(items, catgets(elm_msg_cat, AliasesSet, Aliasesitems, "aliases"));
! 	    strcpy(Item, catgets(elm_msg_cat, AliasesSet, AliasesItem, "Alias"));
! 	    strcpy(Items, catgets(elm_msg_cat, AliasesSet, AliasesItems, "Aliases"));
! 	    strcpy(Prompt, catgets(elm_msg_cat, AliasesSet, AliasesPrompt, "Alias: "));
  
  	    dprint(3, (debugfile, "Entered alias mode\n"));
  	    inalias = TRUE;
--- 1538,1558 ----
  	    selected = alias_selected;
  	    header_page = alias_page;
  
! 	    strfcpy(item, catgets(elm_msg_cat, AliasesSet, Aliasesitem, 
! 				  "alias"),
! 		    sizeof item);
! 	    strfcpy(items, catgets(elm_msg_cat, AliasesSet, Aliasesitems, 
! 				   "aliases"),
! 		    sizeof items);
! 	    strfcpy(Item, catgets(elm_msg_cat, AliasesSet, AliasesItem, 
! 				  "Alias"),
! 		    sizeof Item);
! 	    strfcpy(Items, catgets(elm_msg_cat, AliasesSet, AliasesItems, 
! 				   "Aliases"),
! 		    sizeof Items);
! 	    strfcpy(Prompt, catgets(elm_msg_cat, AliasesSet, AliasesPrompt, 
! 				    "Alias: "),
! 		    sizeof Prompt);
  
  	    dprint(3, (debugfile, "Entered alias mode\n"));
  	    inalias = TRUE;
***************
*** 1657,1665 ****
  	}
  }
  
! int
! parse_aliases(buffer, remainder)
! char *buffer, *remainder;
  {
  /*
   *	This routine will parse out the individual aliases present
--- 1559,1567 ----
  	}
  }
  
! static int parse_aliases(buffer, remainder, size_buffer, size_remainder)
!      char *buffer, *remainder;
!      int size_buffer, size_remainder;
  {
  /*
   *	This routine will parse out the individual aliases present
***************
*** 1681,1701 ****
  
  /*	Check to see if an alias */
  
! 	if ((s = index(buffer, (int)'=')) == NULL)
  	  return (0);
  
! 	strcpy(remainder, s);		/* Save the remainder of the line */
  
  /*	Terminate the list of aliases with a ',' */
  
  	while (--s >= buffer && whitespace(*s)) ;
! 	*++s = ',';
! 	*++s = '\0';
  
  /*	Lowercase everything */
  
  	s = shift_lower(buffer);
! 	strcpy(buffer, s);
  
  /*	Now, count the aliases */
  
--- 1583,1606 ----
  
  /*	Check to see if an alias */
  
! 	if ((s = index(buffer, '=')) == NULL)
  	  return (0);
  
! 	/* Save the remainder of the line */
! 	strfcpy(remainder, s, size_remainder);		
  
  /*	Terminate the list of aliases with a ',' */
  
  	while (--s >= buffer && whitespace(*s)) ;
! 	if (s < buffer + size_buffer -2) {
! 	  *++s = ',';
! 	  *++s = '\0';
! 	}
  
  /*	Lowercase everything */
  
  	s = shift_lower(buffer);
! 	strfcpy(buffer, s, size_buffer);
  
  /*	Now, count the aliases */
  
***************
*** 1707,1716 ****
  	return (number);
  }
  
! int
! get_aliasname(aliasname, buffer, duplicate)
! char *aliasname, *buffer;
! int *duplicate;
  {
  
  /*
--- 1612,1621 ----
  	return (number);
  }
  
! static int get_aliasname(aliasname, buffer, duplicate, size, buffer_size)
!      char *aliasname, *buffer;
!      int *duplicate;
!      int size, buffer_size;
  {
  
  /*
***************
*** 1730,1746 ****
   *		that the user has chosen to replace.  In this
   *		case the alias to replace is passed back in
   *		in the variable 'duplicate'.
   */
  
  	int loc;
  
  	do {
! 	    optionally_enter(aliasname, LINES-2, strlen(buffer), FALSE, FALSE);
  	/*
  	 *  Return if nothing was entered.
  	 */
! 	    if (strlen(aliasname) == 0) 
! 	        return(-1);
  
  	} while (check_alias(aliasname) == -1);
  
--- 1635,1659 ----
   *		that the user has chosen to replace.  In this
   *		case the alias to replace is passed back in
   *		in the variable 'duplicate'.
+  *
+  *   REDRAW_MARK
   */
  
  	int loc;
  
  	do {
! 	  int status =
! 	    optionally_enter(aliasname, elm_LINES-2, strlen(buffer), 
! 			     OE_REDRAW_MARK, size);
! 
! 	  if (REDRAW_MARK == status)
! 	    return REDRAW_MARK;
! 
  	/*
  	 *  Return if nothing was entered.
  	 */
! 	  if (0 != status || strlen(aliasname) == 0) 
! 	    return(-1);
  
  	} while (check_alias(aliasname) == -1);
  
***************
*** 1753,1775 ****
  	         "Attempt to add a duplicate alias [%s] in get_aliasname\n",
  	         aliases[loc]->alias)); 
  	    if (aliases[loc]->type & GROUP )
! 	        PutLine1(LINES-2,0, catgets(elm_msg_cat,
! 	                AliasesSet, AliasesAlreadyGroup,
! 	                "Already a group with name %s."), aliases[loc]->alias);
  	    else
! 	        PutLine1(LINES-2,0, catgets(elm_msg_cat,
! 	                AliasesSet, AliasesAlreadyAlias,
! 	                "Already an alias for %s."), aliases[loc]->alias);
  	    CleartoEOLN();
! 	    MCsprintf(buffer, catgets(elm_msg_cat,
! 	            AliasesSet, AliasesReplaceExisting,
! 	            "Replace existing alias? (%c/%c) "),
! 	        *def_ans_yes, *def_ans_no);
  	 /*
  	  * If they don't want to replace the alias by that name
  	  * then just return.
  	  */
! 	    if (want_to(buffer, *def_ans_no, LINES-3, 0) != *def_ans_yes)
  	        return(-1);
  	    *duplicate = loc;
  	    return(1);
--- 1666,1693 ----
  	         "Attempt to add a duplicate alias [%s] in get_aliasname\n",
  	         aliases[loc]->alias)); 
  	    if (aliases[loc]->type & GROUP )
! 	        PutLineX(elm_LINES-2,0, 
! 			 CATGETS(elm_msg_cat,
! 				 AliasesSet, AliasesAlreadyGroup,
! 				 "Already a group with name %s."), 
! 			 aliases[loc]->alias);
  	    else
! 	        PutLineX(elm_LINES-2,0, 
! 			 CATGETS(elm_msg_cat,
! 				 AliasesSet, AliasesAlreadyAlias,
! 				 "Already an alias for %s."), 
! 			 aliases[loc]->alias);
  	    CleartoEOLN();
! 	    elm_sfprintf(buffer, buffer_size,
! 			 CATGETS(elm_msg_cat,
! 				 AliasesSet, AliasesReplaceExisting,
! 				 "Replace existing alias? (%c/%c) "),
! 			 *def_ans_yes, *def_ans_no);
  	 /*
  	  * If they don't want to replace the alias by that name
  	  * then just return.
  	  */
! 	    if (want_to(buffer, *def_ans_no, elm_LINES-3, 0) != *def_ans_yes)
  	        return(-1);
  	    *duplicate = loc;
  	    return(1);
***************
*** 1787,1793 ****
  	      "Attempt to add a duplicate system alias [%s] in get_aliasname\n",
  	      aliases[loc]->address)); 
  	  
! 	    if( ! superceed_system(loc, buffer))
  	        return(-1);
  	}
  	return(0);
--- 1705,1711 ----
  	      "Attempt to add a duplicate system alias [%s] in get_aliasname\n",
  	      aliases[loc]->address)); 
  	  
! 	    if( ! superceed_system(loc, buffer, buffer_size))
  	        return(-1);
  	}
  	return(0);
***************
*** 1794,1857 ****
  
  }
  
! int
! superceed_system(this_alias, buffer)
! int this_alias;
! char *buffer;
  {
  
! 	PutLine2(LINES-2, 0, catgets(elm_msg_cat,
! 	        AliasesSet, AliasesSystemAlias, "System (%6s) alias for %s."),
! 	    alias_type(aliases[this_alias]->type), aliases[this_alias]->alias);
! 
! 	MCsprintf(buffer, catgets(elm_msg_cat, AliasesSet, AliasesSuperceed,
! 	        "Superceed? (%c/%c) "), *def_ans_yes, *def_ans_no);
  /*
   *	If they don't want to superceed the SYSTEM alias then
   *	return a FALSE.
   */
! 	return(want_to(buffer, *def_ans_no, LINES-3, 0) == *def_ans_yes);
  }
  
! void
! get_realnames(aliasname, firstname, lastname, comment, buffer)
! char *aliasname, *firstname, *lastname, *comment, *buffer;
  {
! 
! 	sprintf(buffer, catgets(elm_msg_cat, AliasesSet, AliasesEnterLastName,
! 		"Enter last name for %s: "), aliasname);
! 	PutLine0(LINES-2,0, buffer);
  	CleartoEOLN();
! 	optionally_enter(lastname, LINES-2, strlen(buffer), FALSE, FALSE);
  
! 	sprintf(buffer, catgets(elm_msg_cat, AliasesSet, AliasesEnterFirstName,
! 		"Enter first name for %s: "), aliasname);
! 	PutLine0(LINES-2,0, buffer);
  	CleartoEOLN();
! 	optionally_enter(firstname, LINES-2, strlen(buffer), FALSE, FALSE);
  
  	if (strlen(lastname) == 0) {
! 	    if (strlen(firstname) == 0) {
! 	        strcpy(lastname, aliasname);  
! 	    }
! 	    else {
! 	        strcpy(lastname, firstname);  
! 	        *firstname = '\0';
! 	    }
  	}
  
! 	sprintf(buffer, catgets(elm_msg_cat, AliasesSet, AliasesEnterComment,
! 		"Enter optional comment for %s: "), aliasname);
! 	PutLine0(LINES-2,0, buffer);
! 	optionally_enter(comment, LINES-2, strlen(buffer), FALSE, FALSE);
  
  }
  
! int
! ask_accept(aliasname, firstname, lastname, comment, address, buffer,
! 	replace, replacement)
! char *aliasname, *firstname, *lastname, *comment, *address, *buffer;
! int replace, replacement;
  {
  
  	char ch;
--- 1712,1801 ----
  
  }
  
! static int
! superceed_system(this_alias, buffer, buffer_size)
!      int this_alias;
!      char *buffer;
!      int buffer_size;
  {
  
! 	PutLineX(elm_LINES-2, 0, 
! 		 CATGETS(elm_msg_cat,
! 			 AliasesSet, AliasesSystemAlias, 
! 			 "System (%6s) alias for %s."),
! 		 alias_type(aliases[this_alias]->type), 
! 		 aliases[this_alias]->alias);
! 
!         elm_sfprintf(buffer, buffer_size,
! 		     CATGETS(elm_msg_cat, AliasesSet, AliasesSuperceed,
! 			     "Superceed? (%c/%c) "), *def_ans_yes, *def_ans_no);
  /*
   *	If they don't want to superceed the SYSTEM alias then
   *	return a FALSE.
   */
! 	return(want_to(buffer, *def_ans_no, elm_LINES-3, 0) == *def_ans_yes);
  }
  
! static void get_realnames(aliasname, firstname, lastname, comment, buffer,
! 		   size_first, size_last, size_comment, size_buffer)
!      char *aliasname, *firstname, *lastname, *comment, *buffer;
!      int size_first, size_last, size_comment, size_buffer;
  {
!   int status;
! 	
!   elm_sfprintf(buffer, size_buffer,
! 	       CATGETS(elm_msg_cat, AliasesSet, AliasesEnterLastName,
! 		       "Enter last name for %s: "), aliasname);
! 	PutLine0(elm_LINES-2,0, buffer);
  	CleartoEOLN();
! 	status = optionally_enter(lastname, elm_LINES-2, strlen(buffer),
! 				  OE_REDRAW_MARK, size_last);
! 	while (REDRAW_MARK == status) {
! 	  PutLine0(elm_LINES-2,0, buffer);
! 	  status = optionally_enter(lastname, elm_LINES-2, strlen(buffer),
! 				    OE_REDRAW_MARK|OE_APPEND_CURRENT,
! 				    size_last);
! 	}
  
! 	elm_sfprintf(buffer, size_buffer,
! 		     CATGETS(elm_msg_cat, AliasesSet, AliasesEnterFirstName,
! 			     "Enter first name for %s: "), aliasname);
! 	PutLine0(elm_LINES-2,0, buffer);
  	CleartoEOLN();
! 	status = optionally_enter(firstname, elm_LINES-2, strlen(buffer), 
! 				  OE_REDRAW_MARK, size_first);
! 	while (REDRAW_MARK == status) {
! 	  PutLine0(elm_LINES-2,0, buffer);
! 	  status = optionally_enter(firstname, elm_LINES-2, strlen(buffer), 
! 				    OE_REDRAW_MARK|OE_APPEND_CURRENT,
! 				    size_first);
! 	}
  
  	if (strlen(lastname) == 0) {
! 	    strfcpy(lastname, firstname, size_last);  
! 	    *firstname = '\0';
  	}
  
! 	elm_sfprintf(buffer, size_buffer,
! 		     CATGETS(elm_msg_cat, AliasesSet, AliasesEnterComment,
! 			     "Enter optional comment for %s: "), aliasname);
! 	PutLine0(elm_LINES-2,0, buffer);
! 	status = optionally_enter(comment, elm_LINES-2, strlen(buffer), 
! 				  OE_REDRAW_MARK, size_comment);
! 	while (status == REDRAW_MARK) {
! 	  PutLine0(elm_LINES-2,0, buffer);
! 	  status = optionally_enter(comment, elm_LINES-2, strlen(buffer), 
! 				    OE_REDRAW_MARK|OE_APPEND_CURRENT,
! 				    size_comment);
! 	}
  
  }
  
! static int ask_accept(aliasname, firstname, lastname, comment, address, buffer,
! 	       replace, replacement, size_buffer)
!      char *aliasname, *firstname, *lastname, *comment, *address, *buffer;
!      int replace, replacement;
!      int size_buffer;
  {
  
  	char ch;
***************
*** 1865,1885 ****
  	    *firstname = '\0';
  	}
  
! 	if (strlen(firstname) == 0) {
! 	    strcpy(buffer, lastname);  
! 	}
  	else {
! 	    sprintf(buffer, "%s %s", firstname, lastname);
  	}
- 	PutLine2(LINES-1,0, catgets(elm_msg_cat, AliasesSet, AliasesAddressAs,
- 	        "Messages addressed as: %s (%s)"), address, buffer);
  	if (strlen(comment) != 0) {
! 	    strcat(buffer, ", ");
! 	    strcat(buffer, comment);
  	}
  
! 	PutLine2(LINES-2,0, catgets(elm_msg_cat, AliasesSet, AliasesAddressTo,
! 	        "New alias: %s is '%s'."), aliasname, buffer);
  	CleartoEOLN();
  /*
   *	Kludge Alert:  Spaces are padded to the front of the prompt
--- 1809,1843 ----
  	    *firstname = '\0';
  	}
  
! 	if (strlen(lastname) == 0)
! 	  PutLineX(elm_LINES-1,0, CATGETS(elm_msg_cat, AliasesSet, 
! 					  AliasesAddressAs1,
! 					  "Messages addressed as: %s"), 
! 		   address);
  	else {
! 	  if (strlen(firstname) == 0) {
! 	      strfcpy(buffer, lastname, size_buffer);  
! 	  }
! 	  else {
! 	      elm_sfprintf(buffer, size_buffer,
! 			   FRM("%s %s"), firstname, lastname);
! 	  }
! 	  PutLineX(elm_LINES-1,0, 
! 		   CATGETS(elm_msg_cat, AliasesSet, 
! 			   AliasesAddressAs,
! 			   "Messages addressed as: %s (%s)"), 
! 		   address, buffer);
  	}
  	if (strlen(comment) != 0) {
! 	    strfcat(buffer, ", ", size_buffer);
! 	    strfcat(buffer, comment, size_buffer);
  	}
  
! 	PutLineX(elm_LINES-2,0, 
! 		 CATGETS(elm_msg_cat, AliasesSet, 
! 			 AliasesAddressTo,
! 			 "New alias: %s is '%s'."), 
! 		 aliasname, buffer);
  	CleartoEOLN();
  /*
   *	Kludge Alert:  Spaces are padded to the front of the prompt
***************
*** 1886,1894 ****
   *	to write over the previous question.  Should probably record
   *	the end of the line, move to it, and CleartoEOLN() it.
   */
! 	MCsprintf(buffer, catgets(elm_msg_cat, AliasesSet, AliasesAcceptNew,
! 		"      Accept new alias? (%c/%c) "), *def_ans_yes, *def_ans_no);
! 	if((ch = want_to(buffer, *def_ans_yes, LINES-3, 0)) == *def_ans_yes) {
  	    if (replace) {
  	        old_alias[0] = aliases[replacement]->alias;
  	    /*
--- 1844,1854 ----
   *	to write over the previous question.  Should probably record
   *	the end of the line, move to it, and CleartoEOLN() it.
   */
! 	elm_sfprintf(buffer, size_buffer,
! 		    CATGETS(elm_msg_cat, AliasesSet, AliasesAcceptNew,
! 			    "      Accept new alias? (%c/%c) "), 
! 		     *def_ans_yes, *def_ans_no);
! 	if((ch = want_to(buffer, *def_ans_yes, elm_LINES-3, 0)) == *def_ans_yes) {
  	    if (replace) {
  	        old_alias[0] = aliases[replacement]->alias;
  	    /*
***************
*** 1922,1929 ****
  	    }
  	    add_to_alias_text(aliasname, firstname, lastname, comment, address);
  	}
! 	ClearLine(LINES-2);
! 	ClearLine(LINES-1);
  	return(ch == *def_ans_yes ? 1 : 0);
  
  }
--- 1882,1889 ----
  	    }
  	    add_to_alias_text(aliasname, firstname, lastname, comment, address);
  	}
! 	ClearLine(elm_LINES-2);
! 	ClearLine(elm_LINES-1);
  	return(ch == *def_ans_yes ? 1 : 0);
  
  }
Index: elm2.4.ME+.50/src/aliaslib.c
*** elm2.4.25/src/aliaslib.c	Tue Aug  3 22:29:01 1993
--- elm2.4.ME+.50/src/aliaslib.c	Tue Nov 17 21:12:57 1998
***************
*** 1,80 ****
  
! static char rcsid[] = "@(#)$Id: aliaslib.c,v 5.10 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.10 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: aliaslib.c,v $
!  * Revision 5.10  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.9  1993/05/31  19:39:43  syd
!  * Elm either failed to expand a group alias or crashed in strlen
!  * (called from do_expand_group()).
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.8  1993/05/14  03:53:46  syd
!  * Fix wrong message being displayed and then overwritten
!  * for long aliases.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.7  1993/05/08  17:03:16  syd
!  * If there are local user names (account names) in the alias, they don't
!  * get fully expanded with a GCOS field like they do when you type an
!  * account name on the To line.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.6  1993/04/12  01:10:15  syd
!  * fix @aliasname sort problem
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.5  1993/02/07  15:13:13  syd
!  * remove extra declaration of lseek, now in hdrs/defs.h
!  * From: Syd
!  *
!  * Revision 5.4  1993/01/20  03:02:19  syd
!  * Move string declarations to defs.h
!  * From: Syd
!  *
!  * Revision 5.3  1992/12/12  01:28:24  syd
!  * in do_get_alias().  abuf[] was under dimensioned.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.2  1992/10/11  01:21:17  syd
!  * 1. If firstname && lastname is null then copy aliasname into the
!  * personal name field (inside the ()'s) when creating an alias
!  * from the menu using the 'n' command.
!  *
!  * 2. Now if for some reason and alias has a null personal name field
!  * (the person hand edited aliases.text) the blank () is not printed
!  * as part of the address.  This actually cured another problem, where
!  * the To: field on the screen (when you hit 'm' on the alias menu)
!  * used to be blank, now the address shows up....
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** Library of functions dealing with the alias system...
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: aliaslib.c,v 1.2 1998/10/20 19:58:15 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** Library of functions dealing with the alias system...
  
***************
*** 171,180 ****
  	if ( !sysalias ) {
  	  if ( (loc = find_alias(name, USER)) >= 0 ) {
  	    match = aliases[loc];
! 	    strcpy(abuf, match->address);
  	    if ( match->type & PERSON ) {
  	      if (strlen(match->name) > 0) {
!                 sprintf(abuf+strlen(abuf), " (%s)", match->name);
  	      }
  	    }
  	    goto do_expand;
--- 107,117 ----
  	if ( !sysalias ) {
  	  if ( (loc = find_alias(name, USER)) >= 0 ) {
  	    match = aliases[loc];
! 	    strfcpy(abuf, match->address, sizeof abuf);
  	    if ( match->type & PERSON ) {
  	      if (strlen(match->name) > 0) {
!                 elm_sfprintf(abuf+strlen(abuf),  sizeof abuf -strlen(abuf),
! 			     FRM(" (%s)"), match->name);
  	      }
  	    }
  	    goto do_expand;
***************
*** 184,193 ****
  	/* check for a system alias */
  	  if ( (loc = find_alias(name, SYSTEM)) >= 0 ) {
  	    match = aliases[loc];
! 	    strcpy(abuf, match->address);
  	    if ( match->type & PERSON ) {
  	      if (strlen(match->name) > 0) {
!                 sprintf(abuf+strlen(abuf), " (%s)", match->name);
  	      }
  	    }
  	    sysalias = TRUE;
--- 121,131 ----
  	/* check for a system alias */
  	  if ( (loc = find_alias(name, SYSTEM)) >= 0 ) {
  	    match = aliases[loc];
! 	    strfcpy(abuf, match->address, sizeof abuf);
  	    if ( match->type & PERSON ) {
  	      if (strlen(match->name) > 0) {
!                 elm_sfprintf(abuf+strlen(abuf), sizeof abuf -strlen(abuf),
! 			     FRM(" (%s)"), match->name);
  	      }
  	    }
  	    sysalias = TRUE;
***************
*** 221,229 ****
  	if ( depth > 12 ) {
  	  dprint(2, (debugfile,
  	      "alias expansion loop detected at \"%s\" - bailing out\n", name));
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmErrorExpanding,
! 		"Error expanding \"%s\" - probable alias definition loop."),
! 		name);
  	    return FALSE;
  	}
  
--- 159,167 ----
  	if ( depth > 12 ) {
  	  dprint(2, (debugfile,
  	      "alias expansion loop detected at \"%s\" - bailing out\n", name));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorExpanding,
! 			      "Error expanding \"%s\" - probable alias definition loop."),
! 		      name);
  	    return FALSE;
  	}
  
***************
*** 298,304 ****
  	    gecos = get_full_name(name);
  
  	    if (gecos && (strlen(gecos) > 0)) {
! 	        sprintf(expanded_address, "%s (%s)", name, gecos);
  	        name = expanded_address;
  	    }
  	  }
--- 236,243 ----
  	    gecos = get_full_name(name);
  
  	    if (gecos && (strlen(gecos) > 0)) {
! 	        elm_sfprintf(expanded_address, sizeof expanded_address,
! 			     FRM("%s (%s)"), name, gecos);
  	        name = expanded_address;
  	    }
  	  }
***************
*** 334,341 ****
  	    *bufsizep = -1;
  	    dprint(2, (debugfile,
  		"Alias expansion is too long in add_name_to_list()\n"));
! 	    error(catgets(elm_msg_cat, ElmSet, ElmAliasExpTooLong,
! 		"Alias expansion is too long."));
  	    return FALSE;
  	}
  
--- 273,280 ----
  	    *bufsizep = -1;
  	    dprint(2, (debugfile,
  		"Alias expansion is too long in add_name_to_list()\n"));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmAliasExpTooLong,
! 			      "Alias expansion is too long."));
  	    return FALSE;
  	}
  
Index: elm2.4.ME+.50/src/args.c
*** elm2.4.25/src/args.c	Mon Apr 12 06:35:24 1993
--- elm2.4.ME+.50/src/args.c	Tue Nov 17 21:14:09 1998
***************
*** 1,54 ****
  
! static char rcsid[] = "@(#)$Id: args.c,v 5.9 1993/04/12 03:35:08 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.9 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: args.c,v $
!  * Revision 5.9  1993/04/12  03:35:08  syd
!  * No tite for elm -z
!  * From: Syd
!  *
!  * Revision 5.8  1993/02/03  19:06:31  syd
!  * Remove extra strchr/strcat/strcpy et al declarations
!  * From: Syd
!  *
!  * Revision 5.7  1993/01/20  03:37:16  syd
!  * Nits and typos in the NLS messages and corresponding default messages.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.6  1992/10/30  21:12:40  syd
!  * Make patchlevel a text string to allow local additions to the variable
!  * From: syd via a request from Dave Wolfe
!  *
!  * Revision 5.5  1992/10/27  01:37:29  syd
!  * add usetite clear to -c mode
!  *
!  * Revision 5.4  1992/10/24  13:35:39  syd
!  * changes found by using codecenter on Elm 2.4.3
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.3  1992/10/17  23:09:10  syd
!  * fix position of t arg
!  *
!  * Revision 5.2  1992/10/17  22:58:57  syd
!  * patch to make elm use (or in my case, not use) termcap/terminfo ti/te.
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** starting argument parsing routines for ELM system...
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: args.c,v 1.5 1998/11/17 07:33:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.5 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** starting argument parsing routines for ELM system...
  
***************
*** 57,70 ****
  #include "headers.h"
  #include "patchlevel.h"
  #include "s_elm.h"
  
  extern char *optarg;		/* optional argument as we go */
  extern int   optind;			/* argnum + 1 when we leave   */
  
! char *
! parse_arguments(argc, argv, to_whom)
! int argc;
! char *argv[], *to_whom;
  {
  	/** Set flags according to what was given to program.  If we are 
  	    fed a name or series of names, put them into the 'to_whom' buffer
--- 19,37 ----
  #include "headers.h"
  #include "patchlevel.h"
  #include "s_elm.h"
+ #include "me.h"
  
  extern char *optarg;		/* optional argument as we go */
  extern int   optind;			/* argnum + 1 when we leave   */
  
! 
! static void args_version P_((int i));
! 
! char * parse_arguments(argc, argv, to_whom, size_r, size)
!      int argc;
!      char *argv[], *to_whom;
!      int *size_r;
!      int size;
  {
  	/** Set flags according to what was given to program.  If we are 
  	    fed a name or series of names, put them into the 'to_whom' buffer
***************
*** 74,105 ****
  	    **/
  
  	register int c = 0;
  	static char req_mfile[SLEN];
  
  	to_whom[0] = '\0';
  	batch_subject[0] = '\0';
  	included_file[0] = '\0';
  
!         while ((c = getopt(argc, argv, "?acd:f:hi:kKms:tVvz")) != EOF) {
! 	   switch (c) {
! 	     case 'a' : arrow_cursor++;		break;
! 	     case 'c' : check_only++; use_tite = 0;	break;
! 	     case 'd' : debug = atoi(optarg);	break;
! 	     case 'f' : strcpy(req_mfile, optarg);	break;
! 	     case '?' :
! 	     case 'h' : args_help();
! 	     case 'i' : strcpy(included_file, optarg);	break;
! 	     case 'k' : hp_terminal++;	break;
! 	     case 'K' : hp_terminal++; hp_softkeys++;	break;
! 	     case 'm' : mini_menu = 0;	break;
! 	     case 's' : strcpy(batch_subject, optarg);	break;
! 	     case 't' : use_tite = 0;	break;
!              case 'V' : sendmail_verbose++;     break;
! 	     case 'v' : args_version();
! 	     case 'z' : check_size++; use_tite = 0;   break;
! 	    }
! 	 }
  
  
  #ifndef DEBUG
  	if (debug)
--- 41,87 ----
  	    **/
  
  	register int c = 0;
+ 	int v = 0;
  	static char req_mfile[SLEN];
  
+ 	*size_r = sizeof req_mfile;
+ 
  	to_whom[0] = '\0';
  	batch_subject[0] = '\0';
  	included_file[0] = '\0';
  
!         while ((c = getopt(argc, argv, "?aA:cd:f:hi:kKms:tVvwz")) != EOF) {
! 	  switch (c) {
! 	  case 'a' : arrow_cursor++;		break;
! #ifdef MIME
! 	  case 'A' : 
! 	    if(!Attach_it(optarg)) exit(1);
! 	    break;
! #endif 
! 	  case 'c' : check_only++; use_tite = 0;	break;
! 	  case 'd' : debug = atoi(optarg);	break;
! 	  case 'f' : strfcpy(req_mfile, optarg,sizeof req_mfile);	
! 	    break;
! 	  case '?' :
! 	  case 'h' : args_help();
! 	  case 'i' : strfcpy(included_file, optarg, sizeof included_file);  
! 	    break;
! 	       /* case 'k' : hp_terminal++;	break;
! 		  case 'K' : hp_terminal++; hp_softkeys++;	break;
! 		  */
! 	  case 'm' : mini_menu = 0;	break;
! 	  case 's' : strfcpy(batch_subject, optarg, sizeof batch_subject);
! 	    break;
! 	  case 't' : use_tite = 0;	break;
! 	  case 'V' : sendmail_verbose++;     break;
! 	  case 'v' : v++; break;
! 	  case 'w' : write_elmrc++; break;
! 	  case 'z' : check_size++; use_tite = 0;   break;
! 	  }
! 	}
  
+ 	if (v)
+ 	  args_version(v);
  
  #ifndef DEBUG
  	if (debug)
***************
*** 110,122 ****
  
  	if (optind < argc) {
  	  while (optind < argc) {
! 		if (strlen(to_whom) + strlen(to_whom[0] != '\0'? " " : "") +
  			strlen(argv[optind]) > SLEN)
  				exit(printf(catgets(elm_msg_cat, ElmSet, ElmArgsTooManyAddresses,
  					"\n\rToo many addresses, or addresses too long!\n\r")));
  
! 	    sprintf(to_whom, "%s%s%s", to_whom, 
! 	            to_whom[0] != '\0'? " " : "", argv[optind]);
  	    if(!check_only)
  	      mail_only++;
  	    optind++;
--- 92,105 ----
  
  	if (optind < argc) {
  	  while (optind < argc) {
! 		if (strlen(to_whom) + strlen(to_whom[0] != '\0'? "," : "") +
  			strlen(argv[optind]) > SLEN)
  				exit(printf(catgets(elm_msg_cat, ElmSet, ElmArgsTooManyAddresses,
  					"\n\rToo many addresses, or addresses too long!\n\r")));
  
! 	    elm_sfprintf(to_whom, size,
! 			 FRM("%s%s%s"), to_whom, 
! 			 to_whom[0] != '\0'? "," : "", argv[optind]);
  	    if(!check_only)
  	      mail_only++;
  	    optind++;
***************
*** 131,140 ****
  	if (!isatty(fileno(stdin)) && !check_only) {
  	  batch_only = ON;
  	  if(*batch_subject == '\0')
! 	    strcpy(batch_subject, DEFAULT_BATCH_SUBJECT);
  	}
  
! 	if (strlen(included_file) > 0) {
  	  if (! mail_only)
  	    exit(printf(catgets(elm_msg_cat, ElmSet, ElmArgsInclFileNotSend,
              "\n\rCan't specify an included file with no-one to send to!\n\r")));
--- 114,128 ----
  	if (!isatty(fileno(stdin)) && !check_only) {
  	  batch_only = ON;
  	  if(*batch_subject == '\0')
! 	    strfcpy(batch_subject, DEFAULT_BATCH_SUBJECT, 
! 		    sizeof batch_subject);
  	}
  
! 	if (strlen(included_file) > 0
! #ifdef MIME
! 	    || attach_files
! #endif
! 	    ) {
  	  if (! mail_only)
  	    exit(printf(catgets(elm_msg_cat, ElmSet, ElmArgsInclFileNotSend,
              "\n\rCan't specify an included file with no-one to send to!\n\r")));
***************
*** 144,151 ****
          }
  
  	return(req_mfile);
- 
- 
  }
  
  args_help()
--- 132,137 ----
***************
*** 156,273 ****
  	  "\nPossible Starting Arguments for ELM program:\n\n\r\
  \targ\t\t\tMeaning\n\r\
  \t -a \t\tArrow - use the arrow pointer regardless\n\r\
  \t -c \t\tCheckalias - check the given aliases only\n\r\
  \t -dn\t\tDebug - set debug level to 'n'\n\r\
  \t -fx\t\tFolder - read folder 'x' rather than incoming mailbox\n\r\
  \t -h \t\tHelp - give this list of options\n\r\
! \t -ix\t\tInclude prepared file 'x' in edit buffer for send\n\r\
! \t -k \t\tKeypad - enable HP 2622 terminal keyboard\n\r"));
  	printf(catgets(elm_msg_cat, ElmSet, ElmArgsHelp2,
! 	  "\t -K \t\tKeypad&softkeys - enable use of softkeys + \"-k\"\n\r\
! \t -m \t\tMenu - Turn off menu, using more of the screen\n\r\
  \t -sx\t\tSubject 'x' - for batch mailing\n\r\
  \t -t \t\tTiTe - don't use termcap/terminfo ti/te entries.\n\r\
  \t -V \t\tEnable sendmail voyeur mode.\n\r\
  \t -v \t\tPrint out ELM version information.\n\r\
  \t -z \t\tZero - don't enter ELM if no mail is pending\n\r\
  \n\n"));
  	exit(1);
  }
  
! args_version()
  {
  	/** print out version information **/
  
  	printf("\nElm Version and Identification Information:\n\n");
  	printf("\tElm %s PL%s, of %s\n",VERSION,PATCHLEVEL,VERS_DATE);
! 	printf("\t(C) Copyright 1988-1992 USENET Community Trust\n");
! 	printf("\tBased on Elm 2.0, (C) Copyright 1986,1987 Dave Taylor\n");
! 	printf("\t----------------------------------\n");
! 	printf("\tConfigured %s\n", CONFIGURE_DATE);
! 	printf("\t----------------------------------\n");
  
  #ifdef MMDF
! 	printf("\tUse MMDF Mail Transport Agent/Mailbox Delimiters: MMDF\n");
  #else /* MMDF */
! 	printf("\tUse UNIX Mailbox Delimiters and %s Mail Transport Agent: not MMDF\n", mailer);
  #endif /* MMDF */
! 
  #ifdef DONT_ADD_FROM
! 	printf("\tLet the MTA add the From: header: DONT_ADD_FROM\n");
  #else /* DONT_ADD_FROM */
! 	printf("\tElm will add the From: header: not DONT_ADD_FROM\n");
  #endif /* DONT_ADD_FROM */
! 
! 	printf("\tFollowing mail spool locking protocols will be used:");
  #ifdef USE_DOTLOCK_LOCKING
! 	printf(" USE_DOTLOCK_LOCKING (.lock)");
  #endif
  #ifdef USE_FLOCK_LOCKING
! 	printf(" USE_FLOCK_LOCKING");
  #endif
  #ifdef USE_FCNTL_LOCKING
! 	printf(" USE_FCNTL_LOCKING");
  #endif
! 	printf("\n");
! 
! #ifdef USE_EMBEDDED_ADDRESSES
! 	printf("\tFrom: and Reply-To: addresses are good: USE_EMBEDDED_ADDRESSES\n");
! #else /* USE_EMBEDDED_ADDRESSES */
! 	printf("\tFrom: and Reply-To: addresses ignored: not USE_EMBEDDED_ADDRESSES\n");
! #endif /* USE_EMBEDDED_ADDRESSES */
  
  #ifdef MIME
! 	printf("\tSupport Multipurpose Internet Mail Extensions: MIME\n");
  #else /* MIME */
! 	printf("\tIgnore Multipurpose Internet Mail Extensions: not MIME\n");
  #endif /* MIME */
  
- #ifdef INTERNET
- 	printf("\tPrefers Internet address formats: INTERNET\n");
- #else /* INTERNET */
- 	printf("\tInternet address formats not used: not INTERNET\n");
- #endif /* INTERNET */
- 
  #ifdef DEBUG
! 	printf("\tDebug options are available: DEBUG\n");
  #else /* DEBUG */
! 	printf("\tNo debug options are available: not DEBUG\n");
  #endif /* DEBUG */
  		
  #ifdef CRYPT
! 	printf("\tCrypt function enabled: CRYPT\n");
  #else /* CRYPT */
! 	printf("\tCrypt function disabled: not CRYPT\n");
  #endif /* CRYPT */
  
  #ifdef ALLOW_MAILBOX_EDITING
! 	printf("\tMailbox editing included: ALLOW_MAILBOX_EDITING\n");
  #else /* ALLOW_MAILBOX_EDITING */
! 	printf("\tMailbox editing not included: not ALLOW_MAILBOX_EDITING\n");
  #endif /* ALLOW_MAILBOX_EDITING */
  
  #ifdef ALLOW_SUBSHELL
! 	printf("\tSubshell menu items included: ALLOW_SUBSHELL\n");
  #else /* ALLOW_SUBSHELL */
! 	printf("\tSubshell menu items not included: not ALLOW_SUBSHELL\n");
  #endif /* ALLOW_SUBSHELL */
  
  #ifdef ISPELL
! 	printf("\tSpell checking feature enabled: ISPELL\n");
! 	printf("\t\t(Default spelling checker is %s options '%s')\n", ISPELL_PATH, ISPELL_OPTIONS);
  #else /* ISPELL */
! 	printf("\tSpell checking feature disabled: not ISPELL\n");
  #endif /* ISPELL */
  
  #ifdef ENABLE_CALENDAR
! 	printf("\tCalendar file feature enabled: ENABLE_CALENDAR\n");
! 	printf("\t\t(Default calendar file is %s)\n",dflt_calendar_file);
  #else /* ENABLE_CALENDAR */
! 	printf("\tCalendar file feature disabled: not ENABLE_CALENDAR\n");
  #endif /* ENABLE_CALENDAR */
  
! 	printf("\n\n");
! 	exit(1);
  
  }
  
--- 142,368 ----
  	  "\nPossible Starting Arguments for ELM program:\n\n\r\
  \targ\t\t\tMeaning\n\r\
  \t -a \t\tArrow - use the arrow pointer regardless\n\r\
+ \t -A \t\tAttach file (requires .elm/mime.types)\n\r\
  \t -c \t\tCheckalias - check the given aliases only\n\r\
  \t -dn\t\tDebug - set debug level to 'n'\n\r\
  \t -fx\t\tFolder - read folder 'x' rather than incoming mailbox\n\r\
  \t -h \t\tHelp - give this list of options\n\r\
! \t -ix\t\tInclude prepared file 'x' in edit buffer for send\n\r"));
  	printf(catgets(elm_msg_cat, ElmSet, ElmArgsHelp2,
! 	  "\t -m \t\tMenu - Turn off menu, using more of the screen\n\r\
  \t -sx\t\tSubject 'x' - for batch mailing\n\r\
  \t -t \t\tTiTe - don't use termcap/terminfo ti/te entries.\n\r\
  \t -V \t\tEnable sendmail voyeur mode.\n\r\
  \t -v \t\tPrint out ELM version information.\n\r\
+ \t -w \t\tWrite .elm/elmrc\n\r\
  \t -z \t\tZero - don't enter ELM if no mail is pending\n\r\
  \n\n"));
+ 	/*
+ 	  \t -k \t\tKeypad - enable HP 2622 terminal keyboard\n\r
+ 	  \t -K \t\tKeypad&softkeys - enable use of softkeys + \"-k\"\n\r\
+ 	  */
  	exit(1);
  }
  
! static void args_version(i)
!      int i;
  {
+         time_t    curr_time = time(NULL);
+  
  	/** print out version information **/
  
  	printf("\nElm Version and Identification Information:\n\n");
  	printf("\tElm %s PL%s, of %s\n",VERSION,PATCHLEVEL,VERS_DATE);
! 	if (curr_time < LAST_REPORT_TIME && i != 2) {
! 	  printf("\tSend bug reports to %s\n",BUG_REPORT_ADDR);
! 	  printf("\n\tWARNING: Elm is not intended to be distributed in\n");
! 	  printf(  "\t         binary form. If that is done, then it is very\n");
! 	  printf(  "\t         likely that compile time configuration does not\n");
! 	  printf(  "\t         match to your system. This is NOT bug of ELM ME+\n");
! 	  printf(  "\t         and bug reports for that reason will be rejected.\n\n");
! 	}
! 	if (i == 1)
! 	  printf("\n\tBased on Elm 2.4 PL24 - PL25\n");
  
+ 	if (i < 3) {
+ 	  printf("\t(C) Copyright 1988-1992 USENET Community Trust\n");
+ 	  printf("\tBased on Elm 2.0, (C) Copyright 1986,1987 Dave Taylor\n");
+ 	}
+ 	if ( i < 2 ) {
+ 	  printf ("\n\tTo print configuration, use option: -vv\n");
+ 	  exit(1);
+ 	}
+ 	if (i < 3) {
+ 	  printf("\t----------------------------------\n");
+ 	  printf("\tConfigured %s\n", CONFIGURE_DATE);
+ 	  printf("\t----------------------------------\n");
+ 
  #ifdef MMDF
! 	  printf("\tUse MMDF Mail Transport Agent/Mailbox Delimiters: MMDF\n");
  #else /* MMDF */
! 	  printf("\tUse UNIX Mailbox Delimiters and %s Mail Transport Agent: not MMDF\n", mailer);
  #endif /* MMDF */
! 	  
  #ifdef DONT_ADD_FROM
! 	  printf("\tLet the MTA add the From: header: DONT_ADD_FROM\n");
  #else /* DONT_ADD_FROM */
! 	  printf("\tElm will add the From: header: not DONT_ADD_FROM\n");
  #endif /* DONT_ADD_FROM */
! 	  
! 	  printf("\tFollowing mail spool locking protocols will be used:");
  #ifdef USE_DOTLOCK_LOCKING
! 	  printf(" USE_DOTLOCK_LOCKING (.lock)");
  #endif
  #ifdef USE_FLOCK_LOCKING
! 	  printf(" USE_FLOCK_LOCKING");
  #endif
  #ifdef USE_FCNTL_LOCKING
! 	  printf(" USE_FCNTL_LOCKING");
  #endif
! 	  printf("\n");
  
  #ifdef MIME
! 	  printf("\tSupport Multipurpose Internet Mail Extensions: MIME\n");
! 
! #ifdef USE_8BITMIME
! 	  printf("\tUse 8BIT content_transfer_encoding and -B8BITMIME -option: USE_8BITMIME\n");
! #else /* USE_8BITMIME */
! 	  printf("\tDon't use 8BIT content_transfer_encoding with -B8BITMIME -option: not USE_8BITMIME\n");
! #endif /* USE_8BITMIME */
! 	  
! #ifdef USE_BINARYMIME
! 	  printf("\tUse BINARY content_transfer_encoding and -BBINARYMIME -option: USE_BINARYMIME");
! #else /* USE_BINARYMIME */
! 	  printf("\tDon't use BINARY content_transfer_encoding with -BBINARYMIME -option: not USE_BINARYMIME");
! #endif /* USE_BINARYMIME */
! 	  printf(" (This option isn't fully implemented yet.)\n");
! 
! #ifdef USE_DSN
! 	  printf("\tUse DSN and options -N -R -V: USE_DSN\n");
! #else /* USE_DSN */
! 	  printf("\tDon't use DSN with -N -R -V -options: not USE_DSN\n");
! #endif /* USE_DSN */
! 
  #else /* MIME */
! 	  printf("\tIgnore Multipurpose Internet Mail Extensions: not MIME\n");
  #endif /* MIME */
  
  #ifdef DEBUG
! 	  printf("\tDebug options are available: DEBUG\n");
  #else /* DEBUG */
! 	  printf("\tNo debug options are available: not DEBUG\n");
  #endif /* DEBUG */
  		
  #ifdef CRYPT
! 	  printf("\tCrypt function enabled: CRYPT\n");
  #else /* CRYPT */
! 	  printf("\tCrypt function disabled: not CRYPT\n");
  #endif /* CRYPT */
  
  #ifdef ALLOW_MAILBOX_EDITING
! 	  printf("\tMailbox editing included: ALLOW_MAILBOX_EDITING\n");
  #else /* ALLOW_MAILBOX_EDITING */
! 	  printf("\tMailbox editing not included: not ALLOW_MAILBOX_EDITING\n");
  #endif /* ALLOW_MAILBOX_EDITING */
  
  #ifdef ALLOW_SUBSHELL
! 	  printf("\tSubshell menu items included: ALLOW_SUBSHELL\n");
  #else /* ALLOW_SUBSHELL */
! 	  printf("\tSubshell menu items not included: not ALLOW_SUBSHELL\n");
  #endif /* ALLOW_SUBSHELL */
  
  #ifdef ISPELL
! 	  printf("\tSpell checking feature enabled: ISPELL\n");
! 	  printf("\t\t(Default spelling checker is %s options '%s')\n", ISPELL_PATH, ISPELL_OPTIONS);
  #else /* ISPELL */
! 	  printf("\tSpell checking feature disabled: not ISPELL\n");
  #endif /* ISPELL */
  
  #ifdef ENABLE_CALENDAR
! 	  printf("\tCalendar file feature enabled: ENABLE_CALENDAR\n");
! 	  printf("\t\t(Default calendar file is %s)\n",dflt_calendar_file);
  #else /* ENABLE_CALENDAR */
! 	  printf("\tCalendar file feature disabled: not ENABLE_CALENDAR\n");
  #endif /* ENABLE_CALENDAR */
  
! #ifdef USE_PGP
! 	  printf("\tPGP support enabled: USE_PGP\n");
! #else
! 	  printf("\tPGP support disabled: not USE_PGP\n");
! #endif
! #ifdef USE_REMAILER
! 	  printf("\tRemailer support enabled: USE_REMAILER\n");
! #else
! 	  printf("\tRemailer support disabled: not USE_REMAILER\n");
! #endif
! 	  printf("\n\n");
  
+ 	  printf("\tTo read global initialization file %s, use Elm -vvv\n",
+ 		 system_rc_file);
+ 	  exit(1);
+ 	}
+ 
+ 	switch (i) {
+ 	case 3:
+ 	printf("\t------------------------------------------\n");
+ 	printf("\tSystem RC file: %s\n",system_rc_file);
+ 	printf("\t------------------------------------------\n\n");
+ 	
+ 	user_init();
+ 	init_defaults();
+ 	post_init_check();
+ 
+ 	printf("\tShort host name:           %s\n",hostname);
+ 	printf("\tHost's domain:             %s\n",hostdomain);
+ 	printf("\tQualified host name:       %s\n",hostfullname);
+ 	printf("\tMailbox:                   %s\n",defaultfile);
+ #ifdef MIME
+ 	printf("\tDisplay character-set:     %s\n",display_charset);
+ 	printf("\tSending character-set:     %s\n",charset);
+ #endif
+ 	printf("\n\tTo list configuration files, use Elm -vvvv\n");
+ 	break;
+ 
+ 	case 4:
+ 	printf("\t------------------------------------------\n");
+ 	printf("\tElm ME+ configuration files: \n");
+ 	printf("\t------------------------------------------\n\n");
+ 	user_init();
+ 
+ 	printf("System configuration files:\n");
+ 	printf("\tRC file:                  %s\n",system_rc_file);
+ 	printf("\tAliases database:         %s\n",system_data_file);
+ 	printf("\tAliases file:             %s\n",system_text_file);
+ 	printf("\tMapping to content-type:  %s\n",system_mime_types);
+ 	printf("\tMapping to charset:       %s\n",system_mime_charsets);
+ 	printf("\tDomain-name file:         %s\n",hostdomfile);
+ 	printf("User configuration files:\n");
+ 	printf("\tRC file:                  %s\n",user_rc_file);
+ 	printf("\tAliases database:         %s\n",user_data_file);
+ 	printf("\tAliases file:             %s\n",user_text_file);
+ 	printf("\tMapping to content-type:  %s\n",user_mime_types);
+ 	printf("\tMapping to charset:       %s\n",user_mime_charsets);
+ 	printf("\tAdditional mail-headers:  %s\n",user_mailheaders);
+ 	printf("\n\tTo read user configuration, use Elm -vvvvv\n");
+ 	break;
+ 
+ 	case 5:
+ 	user_init();
+ 	init_defaults();
+ 	printf("\t------------------------------------------\n");
+ 	printf("\tUser RC file: %s\n",user_rc_file);
+ 	printf("\t------------------------------------------\n\n");
+ 
+ 	read_rc_file();
+ 	post_init_check();
+ 
+ 	printf("\tLocale (LC_CTYPE):         %s\n",display_locale);
+ #ifdef MIME
+ 	printf("\tDisplay character-set:     %s\n",display_charset);
+ 	printf("\tSending character-set:     %s\n",charset);
+ #endif
+ 
+ 	}
+ 	exit(1);
  }
  
Index: elm2.4.ME+.50/src/attach_menu.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/src/attach_menu.c	Tue Nov 17 21:14:09 1998
***************
*** 0 ****
--- 1,1645 ----
+ static char rcsid[] = "@(#)$Id: attach_menu.c,v 1.5 1998/11/08 18:22:25 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.5 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *
+  *  Initially written by: Michael Elkins <elkins@aero.org>, 1995
+  *****************************************************************************/
+ 
+ #include "headers.h"
+ #include "me.h"
+ #include "s_elm.h"
+ 
+ #ifdef MIME
+ #include <sys/errno.h>
+ #include <sys/stat.h>
+ /* unistd.h is included in headers.h */
+ 
+ extern int errno;
+ extern int elm_COLUMNS;
+ 
+ static int can_save(filename) 
+      char *filename;
+ {
+   if (access(filename,ACCESS_EXISTS) < 0) {
+     if (errno == ENOENT)
+       return 1;    /* File not exists -- can save ! */
+     return 0;     /* Other error -- don't save with that name ! */
+   } else
+     return 0;    /* File exits -- don't save over ! */
+ }
+ 
+ static FILE * 
+ get_attachment(mail_fd,att)
+      FILE * mail_fd;
+      mime_t *att;
+ {
+   FILE * result = NULL;
+ 
+   if (att->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"get_attachment",
+ 	       "Bad magic number");
+ 
+   if (att->pathname) {
+     if (can_open(att->pathname,"r") != 0) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorReadableUser,
+ 			"%.50s isn't readable by user!"), 
+ 		att->pathname);
+       sleep_message();
+       return NULL;
+     }
+ 
+     result = fopen(att->pathname,"r");
+     if (!result) {
+       	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCantOpenAttach,
+ 			      "Can't open attachment: %.50s"),
+ 		      att->pathname);
+ 	    sleep_message();
+     }
+   } else if (!mail_fd) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmInternalnoFD,
+ 			"Internal error: no parent fd!"));
+       sleep_message();
+   } else {
+     result = mail_fd;
+     if (fseek(mail_fd,att->offset,SEEK_SET) != 0) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFailedSeekAttach,
+ 			"Failed to seek beginning of attachment!"));
+       sleep_message();
+       result = NULL;
+     }
+   }
+   return result;
+ }
+ 
+ void close_attachment(mail_fd, tmpfd)
+      FILE * mail_fd, *tmpfd;
+ {
+   if (!tmpfd)
+     return;
+   if (mail_fd != tmpfd)
+     fclose(tmpfd);
+ }
+ 
+ void attachment_copy(att, tmpfd, outfd)
+      FILE *tmpfd, *outfd;
+      mime_t *att;
+ {
+   if (att->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"attachment_copy",
+ 	       "Bad magic number");
+ 
+   if (att->pathname) {  /* Already decoded */
+     char buf[VERY_LONG_STRING];
+     int len;
+     while (0 < (len = fread(buf,1,sizeof(buf),tmpfd))) {
+       if (fwrite(buf,1,len,outfd) != len) {
+         lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWriteErrorAttach,
+ 			  "Write error when copying attachment!"));
+ 	sleep_message();
+ 	break;
+       }
+     }
+     if (ferror(tmpfd)) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorReading,
+ 			"Error reading from %.50s"),
+ 		att->pathname);
+       sleep_message();
+     }
+   } else { /* Needs decode */
+     in_state_t state_in;
+     out_state_t state_out;
+     int disp = att -> disposition;
+ 
+     in_state_clear(&state_in, STATE_in_file);
+     out_state_clear(&state_out, STATE_out_file);
+ 
+     set_out_state_file(outfd,&state_out);
+     state_out.displaying = FALSE;
+     set_in_state_file(tmpfd,&state_in);
+ 
+     att -> disposition = DISP_INLINE;  /* Show it ! */
+     mime_decode(att,&state_in, &state_out);
+     att -> disposition = disp;
+ 
+ 
+     in_state_destroy(&state_in);
+     out_state_destroy(&state_out);
+   }
+ }
+ 
+ static void
+ attach_print (att)
+      mime_t *att;
+ {
+   char tempfile[STRING];
+   char buf[VERY_LONG_STRING];
+   
+   if (att->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"attach_print",
+ 	       "Bad magic number");
+ 
+   elm_sfprintf(tempfile,sizeof tempfile,
+ 	       FRM("%selm.%d"), temp_dir, getpid());
+ 
+   if (att->type == MIME_TYPE_TEXT && istrcmp(att->subtype,"plain") == 0) {
+     FILE *f_out, *f_in;
+     int ret;
+ 
+     dprint(3,(debugfile,"attach_print: printing directly\n"));
+ 
+     
+     if (!(f_out = safeopen(tempfile))) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorCreatTempfile,
+ 			"Error creating tempfile %s"),
+ 		tempfile);
+       sleep_message();
+       return;
+     }
+ 
+     if (!(f_in = get_attachment(mailfile,att))) {
+       fclose(f_out);
+       unlink(tempfile);
+       return;
+     }
+     attachment_copy(att,f_in,f_out);
+ 
+     (void) elm_chown (tempfile, userid, groupid);
+       
+     fclose(f_out);
+     elm_sfprintf(buf, sizeof buf,
+ 		 FRM(printout), tempfile);
+     ret = system_call(buf,0);
+     if (ret == 0)
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmJobSpooled,
+ 			"Print job spooled."));
+     else
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorPrinting,
+ 			"Error while printing!"));
+     unlink(tempfile);
+     close_attachment(mailfile,f_in);
+   }
+   else if (have_metamail()) {
+     dprint(3,(debugfile,"attach_print: printing via metamail: %s\n",
+ 	      metamail_path));
+     if (att->pathname)
+       elm_sfprintf(buf,sizeof buf,
+ 		   FRM("%s -m Elm -h -b -c %s/%s %s"),
+ 		   metamail_path,TYPE(att->type), att->subtype, att->pathname);
+     else {
+       FILE *fpout;
+ 
+       fpout = safeopen(tempfile);
+ 
+       if (!fpout) {
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorCreatTempfile,
+ 			  "Error creating tempfile %s"),
+ 		  tempfile);
+ 	sleep_message();
+ 	return;
+       }
+ 
+       (void) elm_chown (tempfile, userid, groupid);
+       fseek(mailfile,att->begin_offset,0);
+       while (ftell(mailfile) < att->offset + att->length) {
+ 	int len = mail_gets(buf,VERY_LONG_STRING,mailfile);
+ 	if (len <= 0) 
+ 	  break; /* Error ? */
+ 	fwrite(buf,1,len,fpout);
+       }
+       /* Option -z cuses that metamail unlinks tempfile */
+       fclose(fpout);
+       elm_sfprintf(buf,sizeof buf,
+ 		   FRM("%s -m Elm -h -z %s"),
+ 		   metamail_path, tempfile);
+     }
+     Raw(OFF);
+     system_call(buf,SY_ENV_METAMAIL);
+     PressAnyKeyToContinue();
+     Raw(ON);
+   }
+   else
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNotKnowPrint,
+ 		      "Don't know how to print this type of data!"));
+ 
+ }
+ 
+ static void attach_save (a)
+      mime_t *a;
+ {
+   char savefile[STRING], buf[VERY_LONG_STRING], tmp[STRING];
+   int bytes=0, err, is_text;
+   in_state_t state_in;
+   out_state_t state_out;
+   FILE *f_in, *f_out;
+   int code;
+ 
+   in_state_clear(&state_in, STATE_in_file);
+   out_state_clear(&state_out, STATE_out_file);
+ 
+   if (a->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"attach_save",
+ 	       "Bad magic number");
+ 
+   savefile[0] = '\0';
+   if (a->type == MIME_TYPE_APPLICATION &&
+       istrcmp (a->subtype, "octet-stream") == 0) {
+ 
+     /* See if there is a name=<...> field for the default filename */
+     tmp[0] = '\0';
+     if (a->type_opts &&
+ 	mime_get_param ("name", tmp, a->type_opts, sizeof(tmp))) {
+       char *p = strrchr (tmp, '/');
+       if (p)
+ 	p++;
+       else
+ 	p = tmp;
+       if (can_save(p))
+ 	strfcpy (savefile, p, sizeof (savefile));
+     }
+   }
+ 
+    /* See if there is a filename=<...> field for the default filename */
+   tmp[0] = '\0';
+   if (a->disposition_opts &&
+       mime_get_param ("filename", tmp, a->disposition_opts, sizeof(tmp))) {
+     char *p = strrchr (tmp, '/');
+     if (p)
+       p++;
+     else
+       p = tmp;
+     if (can_save(p))
+       strfcpy (savefile, p, sizeof (savefile));
+   }
+ 
+   ClearLine (elm_LINES-2);
+ 
+ redraw:
+   PutLine0 (elm_LINES-2, 0, "To file: ");
+   code = optionally_enter(savefile, elm_LINES-2, 9, OE_APPEND_CURRENT|
+ 			  OE_REDRAW_MARK, sizeof savefile);
+   if (REDRAW_MARK == code)
+     goto redraw;
+ 
+   if (code < 0 || 
+       savefile[0]=='\0'){
+     ClearLine(elm_LINES-2);
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMailNotSaved,
+ 		      "Mail not saved."));
+     
+     in_state_destroy(&state_in);
+     out_state_destroy(&state_out);
+     sleep_message();
+     return;
+   }
+ 
+   ClearLine(elm_LINES-2);
+ 
+   
+   if (!(f_in = get_attachment(mailfile,a)))  {
+ 
+     in_state_destroy(&state_in);
+     out_state_destroy(&state_out);
+     return;
+   }
+ 
+   if (can_open (savefile,"w") != 0) {
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNoPermissionWrite,
+ 		      "You do not have permission to write that file!"));
+     sleep_message();
+ 
+     in_state_destroy(&state_in);
+     out_state_destroy(&state_out);
+ 
+     close_attachment(mailfile,f_in);
+ 
+     return;
+   }
+ 
+   
+   if (! (f_out = fopen(savefile, "w"))) {
+     	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorOpening,
+ 			      "Error opening file!"));
+     sleep_message();
+ 
+     in_state_destroy(&state_in);
+     out_state_destroy(&state_out);
+ 
+     close_attachment(mailfile,f_in);
+     return;
+   }
+ 
+   is_text = is_text_type (TYPE(a->type), a->subtype, a->encoding);
+ 
+   set_in_state_file(f_in,&state_in);
+   set_out_state_file(f_out,&state_out);
+ 
+   state_out.prefix = NULL;
+   state_out.displaying = 0;
+ 
+   if (a->encoding == ENCODING_BASE64 && !a->pathname)
+      base64_decode (&state_in, &state_out, a->length, is_text);
+   else if (a->encoding == ENCODING_QUOTED && !a->pathname)
+      quoted_printable_decode (&state_in, &state_out, a->length, is_text);
+   else {
+     if (a->encoding != ENCODING_NONE && a->encoding != ENCODING_7BIT &&
+ 	a->encoding != ENCODING_8BIT && a->encoding != ENCODING_BINARY
+ 	&& !a->pathname) {
+       	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmUnsupportedEncoding,
+ 			      "Unsupported encoding! Decode manually!"));
+       sleep_message();
+ 
+       /* save without decoding ! */
+       is_text = 0;  /* We can't suppose it is text before decoding... */
+     }
+     while (bytes < a->length) {
+       int chunk = VERY_LONG_STRING;
+       int len;
+ 
+       if (chunk > a->length - bytes)
+ 	chunk = a->length - bytes;
+       if ((len = state_getl (buf, chunk, &state_in)) <= 0)
+ 	break;
+       bytes += len;
+       if (is_text > 0) { /* replace CRLF with LF */
+ 	if (len >= 2 && buf[len-2] == '\r' && buf[len-1] == '\n') {
+ 	  buf[len-2] = '\n';
+ 	  buf[len-1] = '\0';
+ 	  len--;
+ 	}
+       }
+       state_put(buf,len,&state_out);
+     }
+   }
+ 
+   err = ferror (f_out); 
+   err = err || fclose (f_out) != 0;
+   elm_chown (savefile, userid, groupid);
+ 
+   close_attachment(mailfile,f_in);
+ 
+   if (err)
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorSaving,
+ 		      "Error saving file!"));
+   else
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMailSaved,
+ 		      "Mail saved."));
+ 
+   in_state_destroy(&state_in);
+   out_state_destroy(&state_out);
+   return;
+ }
+ 
+ static int attach_info P_((mime_t *ptr));
+ 
+ static void attach_edit (ptr)
+      mime_t *ptr;
+ {
+   int savetime;
+   struct stat sb;
+   char buf[STRING];
+ 
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"attach_edit",
+ 	       "Bad magic number");
+ 
+   if (!ptr->pathname)
+     return;
+ 
+   if (-1 == stat (ptr->pathname, &sb)) {
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCantStat,
+ 		      "Can't stat file!"));
+     sleep_message();
+     return;
+   }
+   if (strlen(ptr->pathname) + strlen(editor) > STRING-5)
+     return;
+   savetime = sb.st_mtime;
+   Raw(OFF);
+   elm_sfprintf (buf, sizeof buf,
+ 		FRM("%s %s"), editor, ptr->pathname);
+   system_call (buf, 0);
+   Raw(ON);
+   if (stat (ptr->pathname, &sb) == -1 || sb.st_mtime != savetime)
+     (void) attach_info (ptr);  /* update the information on this attachment */
+   return;
+ }
+ 
+ static void attach_viewer (a)
+      mime_t *a;
+ {
+   char buf[LONG_STRING];
+ 
+   struct header_rec tmp;
+   FILE *tmpfp = NULL;
+   struct stat sb;
+ 
+   /* The next line is required so that mime_t_clear() doesn't call
+    * mime_destroy() or free() on bad pointers
+    */
+   header_zero(&tmp);
+   mime_t_clear (&tmp.mime_rec);
+ 
+   if (a->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"attach_viewer",
+ 	       "Bad magic number");
+     
+   /* So that metapager() doesn't try to do special handling */
+   tmp.status = MIME_MESSAGE;  /* Now I test again MIME_MESSAGE
+ 			       * - K E H   <hurtta@dionysos.FMI.FI>
+ 			       */
+ #ifdef USE_PGP
+     tmp.pgp = 0;
+ #endif
+ 
+   if (a->pathname) {
+     ClearScreen();     /* Extra clear for attach_parse ... */
+ 
+     if (can_open(a->pathname,"r") != 0) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorReadableUser,
+ 			"%.50s isn't readable by user!"), 
+ 		a->pathname);
+       sleep_message();
+       return;
+     }
+ 
+     tmpfp = fopen (a->pathname, "r");
+     if (! tmpfp) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldOpenReading,
+ 			"Could not open file for reading!"));
+       sleep_message();
+       return;
+     }
+ 
+     tmp.mime_rec.flags = a->flags;
+     tmp.mime_rec.type = a->type;
+     strfcpy (tmp.mime_rec.subtype,a->subtype,
+ 	     sizeof tmp.mime_rec.subtype);
+     if (a->type_opts) {
+       tmp.mime_rec.type_opts = strmcpy(tmp.mime_rec.type_opts,a->type_opts);
+     }
+     tmp.mime_rec.notplain = a->notplain;  
+ 
+     tmp.mime_rec.disposition = DISP_INLINE;  /* Show it ! */
+     tmp.offset = tmp.mime_rec.offset = 0;
+     tmp.mime_rec.encoding = ENCODING_7BIT;
+     stat(a->pathname, &sb);
+     tmp.content_length = tmp.mime_rec.length = sb.st_size;
+     attach_parse(&tmp, tmpfp);
+ 
+   }
+   else {
+ 
+     /* Make copy of mime structure: */
+     mime_t_copy(&(tmp.mime_rec),a);
+     tmp.mime_rec.disposition = DISP_INLINE;  /* Show it ! */
+ 
+     tmp.offset = tmp.mime_rec.offset = a -> offset;
+     tmp.content_length = tmp.mime_rec.length = a->length;
+ #ifdef USE_PGP
+     if (headers)
+       tmp.pgp = headers[current-1]->pgp;
+ #endif
+   }
+ 
+   if (tmp.lines < 1)
+     tmp.lines = tmp.content_length / 60; /* This value is used for selecting
+ 					  * external pager versus internal
+ 					  * pager.
+ 					  */
+   /* there is nothing to display! */
+   if (tmp.mime_rec.length <= 0)
+     goto fail;
+ 
+   if (!mime_notplain(&(tmp.mime_rec)) || !have_metamail()) {
+ 
+     metapager (tmpfp == NULL ? mailfile : tmpfp, &tmp, FALSE);
+   } else {
+     /* otherwise call metamail */
+ 
+     if (!a->pathname) {
+       char tmpfile[STRING], c;
+       FILE *out;
+       int bytes;
+ 
+       elm_sfprintf (tmpfile, sizeof tmpfile,
+ 		    FRM("%selm.%d"), temp_dir, getpid());
+ 
+       out = safeopen(tmpfile);
+ 
+       if (out == NULL) {
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorCreatTempfile,
+ 			  "Error creating tempfile %s"),		 
+ 		  tmpfile);
+ 	sleep_message();
+ 	goto fail;
+       }
+       /* copy the headers plus the message to a temp file */
+       fseek (mailfile, a->begin_offset, 0);
+       bytes = a->begin_offset - a->offset;
+       while (bytes < a->length) {
+ 	c = fgetc (mailfile);
+ 	fputc (c, out);
+ 	bytes++;
+       }
+       fclose (out);
+       elm_sfprintf (buf, sizeof buf,
+ 		    FRM("%s -m Elm -p -z %s"), metamail_path,tmpfile);
+     }
+     else
+       /* This is the case when we are viewing attachments for an outgoing
+        * message.
+        */
+       elm_sfprintf(buf,sizeof buf,
+ 		   FRM("%s -m Elm -p -b -c %s/%s %s"), 
+ 		   metamail_path,TYPE(a->type), a->subtype, a->pathname);
+     
+ 
+     (void) elm_chown (tmpfile, userid, groupid);
+ 
+     /* Option -z causes that metamail deletes input file */
+ 
+     Raw (OFF);
+     ClearScreen();
+     printf ("Executing: %s\n", buf);
+     system_call (buf, SY_ENAB_SIGINT|SY_ENV_METAMAIL);
+     PressAnyKeyToContinue();
+     Raw (ON);
+   }
+ 
+  fail:
+   mime_t_clear (&(tmp.mime_rec));
+ 
+   if (tmpfp) {
+     fclose (tmpfp);
+   }
+ 
+   return;
+ }
+ 
+ int Check_attachments() { /* Check initial attachments */
+   mime_t * tmp;
+   for (tmp = attach_files; tmp; tmp = tmp -> next) {
+     int need_enc;
+     int is_text;
+     char buf[40];
+ 
+     need_enc = attach_info (tmp);
+     if (need_enc < 0) {
+       return 0;
+     }
+ 
+     is_text = is_text_type (mime_types[tmp->type], 
+ 			    tmp->subtype, tmp->encoding);
+     
+     if (tmp->type == MIME_TYPE_TEXT && (need_enc & HAVE_8BIT) &&
+ 	!mime_get_param("charset",buf,tmp->type_opts,sizeof (buf)) &&
+ 	charset[0] != '\0')
+       add_parameter_t(tmp, "charset", charset,0);
+ 
+     is_text = is_text_type (mime_types[tmp->type], 
+ 			    tmp->subtype, tmp->encoding);
+   
+     if (is_text < 0 && (tmp->encoding == ENCODING_QUOTED || 
+ 			tmp->encoding == ENCODING_BASE64)) {
+       	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmStrucredNoEncoding,
+ "%.30s: Structured types don't allow encoding of data."),
+ 	      tmp->pathname);
+       sleep_message();
+ 
+       return 0;
+     }
+   }
+   return 1;
+ }
+ 
+ /* Make initial attachment */
+ int Attach_it(pathname) 
+      char *pathname;
+ {
+   mime_t * tmp;
+ 
+   if (access(pathname,READ_ACCESS) < 0) {
+     int err = errno;
+     lib_error(FRM("%.45s: %.33s"),
+ 	      pathname,error_description(err));
+     return 0;
+   }
+ 
+   tmp = (mime_t *) mime_t_alloc ();
+   tmp->pathname = strmcpy (tmp->pathname, pathname);
+ 
+   /* Default disposition for attachments: attachment */
+   tmp->disposition = DISP_ATTACH;
+ 
+   tmp->next = attach_files;
+   attach_files = tmp;
+   return 1;
+ }
+ 
+ static int attach_modify (att, new)
+      mime_t *att;
+      int new;
+ {
+   char buf[STRING];
+   int update = TRUE, prompt = TRUE, need_enc = 0;
+   int is_text = -1, ch;
+ 
+   if (att->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"attach_modify",
+ 	       "Bad magic number");
+ 
+   buf[0] = '\0';
+ 
+   if (new) {
+     /* set the default charset */
+     add_parameter_t (att, "charset", charset, 0);
+ 
+     /* Default disposition for attachments: attachment */
+     att->disposition = DISP_ATTACH;
+ 
+     /* force a prompt for a filename */
+     prompt = FALSE;
+     ch = 'f';
+     att->unlink = 0;
+   }
+   
+   /* 1 if is text type (true)
+    * 0 if not text type
+    * -1 if can't be encoded (ie structured) Message/ or Multpart/
+    */
+   is_text = is_text_type (TYPE(att->type), att->subtype, att->encoding);
+ 
+   for (;;) {
+     if (update) {
+       int add = 0;
+       ClearScreen ();
+       
+       Centerline (1, "Attachment Configuration");
+       
+       if (att->unlink) 
+ 	PutLineX(3, 0, 
+ 		 FRM("%-26.26s: %.*s"), "Filename", 
+ 		 sizeof(buf)-30, NONULL(att->pathname));
+       else
+ 	PutLineX(3, 0, 
+ 		 FRM("%-26.26s: %.*s"), "F)ilename", 
+ 		 sizeof(buf)-30, NONULL(att->pathname));
+ 
+       PutLineX(4, 0, 
+ 	       FRM("%-26.26s: %.*s"), "D)escription", 
+ 	       sizeof(buf)-30, NONULL(att->description));
+ 
+ 
+       PutLineX (5, 0, 
+ 		FRM("%-26.26s: %.15s/%.30s%s"), "Content-T)ype",
+ 		TYPE(att->type), att->subtype,
+ 		att->type_opts ? ";" : "");
+ 
+       if (att->type_opts) {
+ 	PutLine0 (6+add, 28, att->type_opts);
+ 	add++;
+       }
+       PutLineX(6+add, 0, 
+ 	       FRM("%-26.26s: %s"), "content-transfer-E)ncoding",
+ 	       ENCODING(att->encoding));
+ 
+       
+ 
+       PutLineX (7+add, 0, 
+ 		FRM("%-26.26s: %.15s%s"), "content-disP)osition", 
+ 		DISPOSITION(att->disposition),
+ 		att->disposition_opts ? ";" : "");
+ 
+       if (att->disposition_opts) {
+ 	PutLine0 (8+add, 28, att->disposition_opts);
+ 	add++;
+       }
+ 
+       if (is_text < 0)
+ 	PutLineX(9+add, 0, 
+ 		 FRM("%-26.26s: %s"), 
+ 		 "CRLF-conversions",
+ 		 "structured (direct content-encoding not allowed)");
+       else if (is_text)
+ 	PutLineX(9+add, 0, 
+ 		 FRM("%-26.26s: %s"), 
+ 		 "CRLF-conversions",
+ 		 "Text (line orienteed, convert LF <-> CRLF)");
+       else 
+ 	PutLineX(9+add, 0, 
+ 		 FRM("%-26.26s: %s"), "CRLF-conversions",
+ 		 "Binary (no conversions)");
+ 
+ 
+       update = FALSE;
+       show_last_error();
+     }
+     
+     if (prompt) {
+       PutLine0 (elm_LINES-2, 0, "Enter letter or RETURN to quit: ");
+       ch = ReadCh(REDRAW_MARK);
+       clear_error();
+     }
+     
+     if (ch == '\n' || ch == 'q' || ch == 'Q' || ch == 'x' || ch == 'X')
+       return (TRUE);
+     else if (ch == ctrl('L') || ch == REDRAW_MARK)
+       update = TRUE;
+     else if (ch == 'f' || ch == 'F') {
+       int code;
+ 
+       if (att->unlink)  {
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			  ElmCantChangeFilename,"You can't change filename!"));
+ 	continue;
+       }
+       if (att->pathname)
+ 	strfcpy(buf, att->pathname, sizeof(buf));
+       else
+ 	buf[0] = '\0';
+ 
+       prompt = TRUE;
+       PutLine0 (elm_LINES-2, 0, "Filename: ");
+       code = optionally_enter (buf, elm_LINES-2, 10, OE_APPEND_CURRENT|
+ 			       OE_REDRAW_MARK, sizeof buf);
+       if (REDRAW_MARK == code) {
+ 	update = TRUE;
+ 	prompt = FALSE;
+ 	continue;
+       }
+ 
+       if (buf[0] != '\0') {
+ 	if (access(buf,READ_ACCESS) < 0) {
+ 	  int err = errno;
+ 	  lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			    ElmErrorAccess,
+ 			    "%.45s: %.33s"),
+ 		    buf,error_description(err));
+ 	  continue;
+ 	}
+         att->pathname = strmcpy (att->pathname, buf);
+ 	update = TRUE;
+ 
+       } else {
+ 	update = TRUE;
+ 
+         if (att->pathname) {
+           free (att->pathname);
+           att->pathname = NULL;
+         }
+         if (new)
+           return FALSE;
+         else
+           continue;
+       }
+ 
+       /* Set some information about this attachment */
+       need_enc = attach_info (att);
+       if (need_enc < 0)
+ 	continue;
+ 
+       /* 1 if is text type (true)
+        * 0 if not text type
+        * -1 if can't be encoded (ie structured) Message/ or Multpart/
+        */
+       is_text = is_text_type (TYPE(att->type), att->subtype, att->encoding);
+       if (is_text > 0 && (need_enc & HAVE_BINARY)) {
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			  ElmWarningBINARY,
+ 			  "Warning: BINARY data? Check Content-Type!"));
+       }
+ 
+       if (is_text < 0 && (att->encoding == ENCODING_QUOTED || 
+ 			  att->encoding == ENCODING_BASE64)) {
+ 	/* Reconsider encoding ... */
+ 	ch = 'e';
+ 	prompt = FALSE;
+ 	update = TRUE;
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			  ElmStructuredNoencoding,
+ 			  "Structured types don't allow encoding of data."));
+ 	sleep_message();
+ 
+ 	break;
+       } 
+ 
+       /* now let the user do what they want */
+       if (new)
+ 	prompt = TRUE;
+       
+     }
+     else if (ch == 'd' || ch == 'D') {
+       int code;
+ 
+       PutLine0 (elm_LINES-2, 0, "Description: ");
+       buf[0] = '\0';
+       if (att->description)
+ 	strfcpy(buf,att->description,sizeof(buf));
+ 
+       prompt = TRUE;
+       code =
+ 	optionally_enter (buf, elm_LINES-2, 13, OE_APPEND_CURRENT|
+ 			  OE_REDRAW_MARK, sizeof buf);
+       if (REDRAW_MARK == code) {
+ 	update = TRUE;
+ 	prompt = FALSE;
+ 	continue;
+       }
+       if (code != 0)
+ 	continue;
+ 
+       if (buf[0])
+         att->description = strmcpy (att->description, buf);
+       else if (att->description) {
+         free (att->description);
+ 	att->description = NULL;
+       }
+       update = TRUE;
+     }
+     else if (ch == 't' || ch == 'T') {
+       int code;
+ 
+       prompt = TRUE;
+       PutLine0 (elm_LINES-2, 0, "Content-Type: ");
+       att -> flags &= ~(MIME_RFC822);
+       att -> flags &= ~(MIME_MIXED);
+       att -> flags &= ~(MIME_DIGEST);
+       elm_sfprintf (buf, sizeof buf,
+ 		    FRM("%.15s/%.30s"), 
+ 		    TYPE(att->type), att->subtype);
+       if (att->type_opts) {
+ 	int l;
+ 
+ 	strfcat (buf, "; ", sizeof buf);
+         l = strlen (buf);
+ 	strfcpy (buf + l, att->type_opts, sizeof (buf) - l);
+       }
+       
+       code = optionally_enter (buf, elm_LINES-2, 14, OE_APPEND_CURRENT|
+ 			       OE_REDRAW_MARK, sizeof buf);
+       if (REDRAW_MARK == code) {
+ 	update = TRUE;
+ 	prompt = FALSE;
+ 	continue;
+       }
+       if (0 != code)
+ 	continue;
+ 
+       mime_get_content (buf, att);
+       if (att->type == MIME_TYPE_TEXT && (need_enc & HAVE_8BIT) &&
+ 	  !mime_get_param("charset",buf,att->type_opts,sizeof (buf)))
+ 	add_parameter_t(att, "charset", charset,0);
+       
+       /* 1 if is text type (true)
+        * 0 if not text type
+        * -1 if can't be encoded (ie structured) Message/ or Multpart/
+        */
+       is_text = is_text_type (mime_types[att->type], 
+ 			      att->subtype, att->encoding);
+       update = TRUE;
+       if (is_text < 0 && (att->encoding == ENCODING_QUOTED || 
+ 			  att->encoding == ENCODING_BASE64)) {
+ 	/* Reconsider encoding ... */
+ 	ch = 'e';
+ 	prompt = FALSE;
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			  ElmStructuredNoencoding,
+ 			  "Structured types don't allow encoding of data."));
+ 	sleep_message();
+       } 
+     }
+     else if (ch == 'p' || ch == 'P') {
+       int code;
+ 
+       prompt = TRUE;
+       PutLine0 (elm_LINES-2, 0, "Content-Disposition: ");
+       strfcpy (buf, DISPOSITION(att->disposition), sizeof buf);
+       if (att->disposition_opts) {
+ 	int l;
+ 
+ 	strfcat (buf,"; ", sizeof buf);
+         l = strlen (buf);
+ 	strfcpy (buf + l, att->disposition_opts, sizeof (buf) - l);
+       }
+       
+       code = optionally_enter (buf, elm_LINES-2, 21, 
+ 			       OE_REDRAW_MARK|OE_APPEND_CURRENT,
+ 			       sizeof buf);
+       if (REDRAW_MARK == code) {
+ 	update = TRUE;
+ 	prompt = FALSE;
+ 	continue;
+       }
+       if (0 != code)
+ 	continue;
+       mime_get_disposition (buf, att);
+       update = TRUE;
+     }
+     else if (ch == 'e' || ch == 'E') {
+       prompt = TRUE;
+       PutLine0 (elm_LINES-2, 0, "Content-Transfer-Encoding: ");
+       Centerline (elm_LINES-1, "<SPACE> for next value, <RETURN> to accept.");
+       for (;;) {
+ 	MoveCursor (elm_LINES-2, 27);
+ 	CleartoEOLN ();
+ 
+ #define NEXT_ENCODING  { \
+ 			   att->encoding++; \
+ 			   if (att->encoding > 5) att->encoding = 1; \
+ 			   continue; \
+ 		       }
+ 
+ #ifndef USE_8BITMIME
+ 	if (allow_no_encoding < 1) {
+ 	  if (att->encoding == ENCODING_8BIT) {  /* Mailer won't support ! */
+ 	    /* TRY next encosing instead */
+ 	    NEXT_ENCODING;
+ 	  }
+ 	}
+ #endif
+ 	
+ #ifndef USE_BINARYMIME
+ 	if (allow_no_encoding < 2) {
+ 	  if (att->encoding == ENCODING_BINARY) {  /* Mailer won't support ! */
+ 	    /* TRY next encoding instead */
+ 	    NEXT_ENCODING;
+ 	  }
+ 	}
+ #endif
+ 
+ 	/* Don't allow 7bit if the file contains 8bit chars... 
+ 	 * 7bit encoding is allowed if file includes control characters 
+ 	 */
+ 	if (att->encoding == ENCODING_7BIT && (need_enc & HAVE_8BIT)) {
+ 	  NEXT_ENCODING;
+ 	}
+ 	/* Don't allow 7bit or 8bit if the file required binary
+ 	 * encoding according of Mime Draft Standard.
+ 	 */
+ 	if ((att->encoding == ENCODING_7BIT || att->encoding == ENCODING_8BIT)
+ 	    && (need_enc & HAVE_BINARY)) {
+ 	  NEXT_ENCODING;
+ 	}
+ 
+ 	/* Don't allow encoding for Multipart/ and Message/ 
+ 	 * See mime Draft Standard. Be carefull that don't create
+ 	 * infinitive loop! */
+ 
+ 	if (is_text < 0) {
+ 	  static int again = 0;    /* Prevent looping */
+ 	  if (att->encoding == ENCODING_QUOTED || 
+ 	      att->encoding == ENCODING_BASE64) {
+ 	    if (again == att->encoding) {
+  	      	lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 				  ElmStructuredLeaf,
+ 				  "Structured types must be encoded in leaf type!"));
+ 	      sleep_message();
+ 
+ 	      /* prompt for new content-type */
+ 	      prompt = FALSE;
+ 	      ch = 't';
+ 	      break;
+ 	    } else {
+ 	      if (!again)
+ 		again = att->encoding;
+ 	      NEXT_ENCODING;
+ 	    }
+ 	  } else
+ 	    again = 0;
+ 	}
+ 
+ 	Write_to_screen (FRM("%s"),ENCODING(att->encoding));
+ 	ch = ReadCh(REDRAW_MARK);
+ 	if (ch == '\n')
+ 	  break;
+ 	else if (ch == ' ') {
+ 	  NEXT_ENCODING;
+ 	}
+ 	else if (ch == REDRAW_MARK) {
+ 	  update = TRUE;
+ 	  prompt = FALSE;
+ 	  ch =  'e';
+ 	  
+ 	  break;
+ 	}
+       }
+ 
+ #undef NEXT_ENCODING
+ 
+       ClearLine (elm_LINES-1);
+       /* 1 if is text type (true)
+        * 0 if not text type
+        * -1 if can't be encoded (ie structured) Message/ or Multpart/
+        */
+       is_text = is_text_type (mime_types[att->type], att->subtype, att->encoding);
+       update = TRUE;
+     }
+     else
+       lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			ElmUnknownCommand2,			
+ 			"Unknown command."));
+   }
+   /* Not reached. */
+ }
+ 
+ static void
+ mime_guess_content_type (ptr)
+      mime_t *ptr;
+ {
+   /* This routine tries to guess the content-type of an attachment by looking
+    * at the suffix of ptr->pathname.  It first looks to see if it can find
+    * an entry in ~/.elm/mime.types, then in "system_mime_types", and failing
+    * that, to a small list of builtin definitions.
+    */
+   int i, found = FALSE;
+   char *p, *c, buf[LONG_STRING];
+   FILE *fp;
+ 
+   dprint (3, (debugfile, "mime_guess_content_type: pathname=%s\n",
+ 	      ptr->pathname));
+ 
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"mime_guess_content_type",
+ 	       "Bad magic number");
+ 
+   /* Set the "filename" field for content-disposition */
+   p = strrchr (ptr->pathname, '/');
+   if (p)
+     p++;
+   else
+     p = ptr->pathname;
+   buf[0] = '\0';
+   add_parameter (buf, "filename", p, sizeof (buf), 0);
+   ptr->disposition_opts = strmcpy (ptr->disposition_opts, buf);
+ 
+   /* Try to guess the content type of the data by the filename extension */
+   p = strrchr (ptr->pathname, '.');
+   if (! p)
+     return;
+   p++;
+   for (i = 0; i < 3; i++) {
+   dprint (3, (debugfile, 
+ 	      "mime_guess_content_type: searching \"%s\", i=%d\n",
+ 	      p,i));
+     if (i == 0) {
+       
+       /* First try the user's mime.types file */
+       
+       fp = fopen (user_mime_types, "r");
+       if (!fp)
+ 	continue;
+     }
+     else if (i == 1) {
+       
+       /* If it wasn't there, try the system file... */
+       
+       fp = fopen (system_mime_types, "r");
+       if (! fp)
+ 	continue;
+     }
+     else {
+       /* Couldn't find user or system mime.types file,
+        * use these defaults...
+        */
+       if (istrcmp (p, "ps") == 0) {
+ 	ptr->type = MIME_TYPE_APPLICATION;
+ 	strfcpy (ptr->subtype, "postscript", sizeof ptr->subtype);
+         if (ptr->type_opts) {
+           free (ptr->type_opts);
+           ptr->type_opts = NULL;
+         }
+       }
+       else if (istrcmp (p, "gif") == 0 || istrcmp (p, "jpeg") == 0 ||
+ 	       istrcmp (p, "tiff") == 0) {
+ 	ptr->type = MIME_TYPE_IMAGE;
+ 	strfcpy (ptr->subtype, p, sizeof ptr->subtype);
+         if (ptr->type_opts) {
+           free (ptr->type_opts);
+           ptr->type_opts = NULL;
+         }
+       }
+       dprint (3, (debugfile, 
+ 		  "mime_guess_content_type: built-in default \"%s\" as \"%s/%s\"\n", 
+ 		  p, TYPE(ptr->type), ptr->subtype));
+     }
+     
+     if (i < 2) {
+       int l = strlen(p);
+       while (fgets (buf, LONG_STRING, fp) != NULL) {
+ 	int l1 = strlen(buf);
+ 	
+ 	if ('\n' == buf[l1 -1]) 
+ 	  buf[l1 - 1] = '\0';
+ 	else {
+ 	  lib_error("mime.types: Too long line: %.30s...\n",buf);
+ 	  break;
+ 	}
+ 	while (l1-- > 0 && whitespace(buf[l1]))
+ 	  buf[l1] = '\0';
+ 
+ 	c = buf;
+ 	while (*c && whitespace ( *c)) /* skip leading whitespace */
+ 	  c++;
+ 	if (*c == '#') /* Skip comments */
+ 	  continue;
+ 	if (! *c)
+ 	  continue;
+ 	if (strincmp (c, p, l) == 0 &&
+ 	    whitespace(c[l])) {
+ 	  mime_get_content (c + l + 1, ptr);
+ 	  dprint (3, (debugfile, "mime_guess_content_type: user defined \"%s\" as \"%s/%s\"\n", p, TYPE(ptr->type), ptr->subtype));
+ 	  found = TRUE;
+ 	  break;
+ 	}
+       }
+       fclose (fp);
+       if (found)
+ 	break;
+     }
+   }
+   return;
+ }
+ 
+ static int attach_info (ptr)
+      mime_t *ptr;
+ {
+   struct stat sb;
+   FILE *fp;
+   int need_enc;
+ 
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"attach_info",
+ 	       "Bad magic number");
+ 
+   if (stat (ptr->pathname, &sb) == -1) {
+     if (errno == ENOENT)
+       lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			ElmFileNotExist,			
+ 			"That file %.20s does not exist!"),
+ 		ptr->pathname);
+     else
+       lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			ElmCantStatFile,			
+ 			"Could not stat file %.20s!"),
+ 		ptr->pathname);
+     sleep_message();
+     return (-1);
+   }
+ 
+   ptr->length = sb.st_size;
+ 
+   if (can_open(ptr->pathname,"r") != 0) {
+     lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 		      ElmNotReadableByUser,			
+ 		      "%.50s isn't readable by user!"), 
+ 	      ptr->pathname);
+     ptr->pathname[0] = '\0';
+     sleep_message();
+     return (-1);
+   }
+ 
+   mime_guess_content_type (ptr);
+ 
+   /* Figure out what the default encoding is... */
+ 
+   lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 		    ElmCheckingEncoding,			
+ 		    "Checking %s..."), 
+ 	    ptr->pathname);
+   fp = fopen (ptr->pathname, "r");
+   if (!fp) {
+     lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 		      ElmCantOpenFile,			
+ 		      "Can't open %s!"), 
+ 	      ptr->pathname);
+     sleep_message();
+     return -1;
+   }
+ 
+   need_enc = needs_encoding (fp);
+   
+   if (need_enc & HAVE_CTRL)
+     ptr->encoding = (need_enc & HAVE_BINARY) 
+       ? ENCODING_BASE64 : ENCODING_QUOTED;
+   else if (need_enc & HAVE_BINARY) { 
+     /* HAVE_BINARY, but not HAVE_CTRL so that have long lines! */
+ #ifdef USE_BINARYMIME
+     ptr->encoding = ENCODING_BINARY;
+ #else
+     ptr->encoding = ENCODING_QUOTED;
+ #endif
+   }
+   else if (need_enc & HAVE_8BIT) {
+ #ifdef USE_8BITMIME
+     ptr->encoding = ENCODING_8BIT;
+ #else
+     ptr->encoding = ENCODING_QUOTED;
+ #endif
+   }
+   fclose (fp);
+   clear_error();  /* Remove reading ... -message */
+ 
+   dprint(3,(debugfile,"attach_info: need_enc=%d, encoding=%d, pathname=%s\n",
+ 	    need_enc,ptr->encoding,ptr->pathname));
+   return (need_enc);
+ }
+ 
+ static void attach_header P_((mime_t *mt,
+ 			      int num, int is_cur, int offset, int use_desc));
+ 
+ static void attach_header (mt, num, is_cur, use_desc, offset)
+      mime_t *mt;
+      int num, is_cur, offset, use_desc;
+ {
+   /* Displays a header for a menu for the specified attachment. */
+   char *Encoding = "???";
+  
+   char buf[LONG_STRING], buf2[LONG_STRING];
+   int len, len2;
+   int Width = elm_COLUMNS;     /* Protect arbitary big values of COLUMNS */
+   if (Width > sizeof (buf)-1)
+     Width = sizeof (buf)-1;
+ 
+   if (mt->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"attach_header",
+ 	       "Bad magic number");
+ 
+   Encoding = ENCODING(mt->encoding);
+ 
+   elm_sfprintf (buf, sizeof buf,
+ 		FRM("%4d %-30.30s (%d) "),
+ 		num,
+ 		use_desc ? NONULL(mt->description) : NONULL(mt->pathname),
+ 		mt->length);
+   if (mt->length < 10)
+     strfcat (buf, "   ", sizeof buf);
+   else if (mt->length < 100)
+     strfcat (buf, "  ", sizeof buf);
+   else if (mt->length < 1000)
+     strfcat (buf, " ", sizeof buf);
+   elm_sfprintf (buf2, sizeof buf2,
+ 		FRM("%.15s/%.30s"), TYPE(mt->type), mt->subtype);
+   strfcat (buf, buf2, sizeof buf);
+   len = Width - strlen (buf);
+   len2 = strlen (Encoding) + 3;
+   if (len2 > len) {
+     buf[Width-len2] = '\0';
+     len = len2 = 0;
+   }
+   elm_sfprintf (buf2, sizeof buf2,
+ 		FRM("%s %*.*s[%s]"), buf, len-len2, len-len2, "", Encoding);
+   
+   if (is_cur && arrow_cursor) {
+     buf2[0] = '-';
+     buf2[1] = '>';
+   }
+ 
+   if (is_cur && has_highlighting && ! arrow_cursor) 
+     StartInverse();
+   PutLine0 (offset, 0, buf2);
+   if (is_cur && has_highlighting && ! arrow_cursor) 
+     EndInverse();
+ }
+ 
+ static void write_num P_((int num, int is_cur, int offset));
+ 
+ static void write_num(num, is_cur, offset)
+      int num, is_cur,offset;
+ {
+   char buf[10];
+ 
+   elm_sfprintf (buf,sizeof buf,
+ 		FRM("%4d"),num);
+ 
+   if (is_cur) {
+     buf[0] = '-';
+     buf[1] = '>';
+   }
+   PutLine0 (offset, 0, buf);
+ }
+ 
+ mime_t * attach_menu (mt, rdonly)
+      mime_t *mt;
+      int rdonly;
+ {
+   /* A generic attachment menu.  "rdonly" controls whether or not the list
+    * of attachments "mt" may be edited.
+    */
+ 
+   mime_t **ptrs = NULL, *tmp, *ret = NULL;
+   int ptr_len = 0, ptr_max = 0, i, cur = 0, offset = 3, key_offset, ch;
+   int update = TRUE;
+   char buf[STRING];
+   int top = 0;
+ 
+   if (mt && mt->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"attach_menu",
+ 	       "Bad magic number");
+ 
+   /* Generate an array of pointers so it is easier to work with. */
+   while (mt) {
+     if (mt->magic != MIME_magic)
+       mime_panic(__FILE__,__LINE__,"attach_menu",
+ 		 "Bad magic number (next chain)");
+ 
+     if (ptr_len == ptr_max)
+       ptrs = (mime_t **) DynamicArray (ptrs, sizeof (mime_t *), &ptr_len, 5);
+     ptrs[ptr_max++] = mt;
+     mt = mt->next;
+   }
+ 
+   for (;;) {
+     if (cur < top || cur >= top + elm_LINES-3-offset) {
+       if (cur < top) 
+ 	top -= elm_LINES-3-offset;
+       if (cur >= top + elm_LINES-3-offset) 
+ 	top += elm_LINES-3-offset;
+       if (top >= ptr_max)
+ 	top = ptr_max - elm_LINES +3 +offset;
+       if (top < 0)
+ 	top = 0;
+       update = TRUE;
+     }
+     if (update) {
+       ClearScreen ();
+       elm_sfprintf (buf, sizeof buf,
+ 		    CATGETS(elm_msg_cat, ElmSet, ElmAttachMenu,
+ 			    "Attachment Menu (%d attachments)"), 
+ 		    ptr_max);
+       Centerline (1, buf);
+       if (! rdonly)
+ 	strfcpy (buf, "a)dd, e)dit, d)elete, m)odify, ", sizeof buf);
+       else
+ 	buf[0] = '\0';
+       strfcat (buf, "p)rint, s)ave, v)iew subparts, q)uit", sizeof buf);
+       Centerline (elm_LINES-1, buf);
+       for (i = top; i < ptr_max && i < top + elm_LINES -3 - offset; i++)
+ 	attach_header (ptrs[i], i + 1, i == cur, rdonly, offset + i - top);
+       update = FALSE;
+       show_last_error(); 
+     }
+     ClearLine (elm_LINES-2);
+     PutLine0 (elm_LINES-2, 0, "Attachments: ");
+     ch = ReadCh (REDRAW_MARK|READCH_CURSOR);
+     clear_error(); /* Clear the error message (from buffer also) */
+     switch (ch) {
+     case '-':
+     case LEFT_MARK:
+     case PAGEUP_MARK:
+       if ( ptr_max > 0 ) {
+         attach_header (ptrs[cur], cur+1, FALSE, rdonly, offset + cur - top);
+         cur -= elm_LINES -3;
+         if (cur < 0)
+ 	  cur = 0;
+       }
+       else
+         lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 	                  ElmNoAttachments,
+ 		          "There are no attachments!"));
+       break;
+     case '+':
+     case RIGHT_MARK:
+     case PAGEDOWN_MARK:
+       if ( ptr_max > 0 ) {
+         attach_header (ptrs[cur], cur+1, FALSE, rdonly, offset + cur - top);
+         cur += elm_LINES -3;
+         if (cur > ptr_max - 1) 
+ 	  cur = ptr_max - 1;
+       }
+       else
+         lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 	                  ElmNoAttachments,
+ 		          "There are no attachments!"));
+       break;
+     case 's':
+       if (ptr_max > 0)
+         attach_save (ptrs[cur]);
+       else
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			  ElmNoAttachments,			
+ 			  "There are no attachments!"));
+       break;
+     case ' ':
+     case '\n':
+       if (ptr_max > 0) {
+         attach_viewer (ptrs[cur]);
+         update = TRUE;
+       }
+       else
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			  ElmNoAttachments,			
+ 			  "There are no attachments!"));
+       break;
+     case 'p':
+       if (ptr_max > 0)
+ 	attach_print(ptrs[cur]);
+       else
+         lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			  ElmNoAttachments,			
+ 			  "There are no attachments!"));
+ 		
+       break;
+     case 'v': /* Perhaps it is better that attachment meny shows whole
+ 	       * structure -- but this is temporary hack.... */
+       if (ptr_max == 0) {
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			  ElmNoAttachments,			
+ 			  "There are no attachments!"));
+         break;
+       }
+       if (ptrs[cur]->parts) {
+ 	attach_menu(ptrs[cur]->parts,TRUE);
+ 	update = TRUE;
+       }
+       break;
+     case 'e':
+       if (! rdonly) {
+         if (ptr_max == 0) {
+ 	  lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			    ElmNoAttachments,			
+ 			    "There are no attachments!"));
+           break;
+         }
+ 	attach_edit (ptrs[cur]);
+ 	update = TRUE;
+       }
+       break;
+     case 'd':
+       if (! rdonly) {
+         if (ptr_max == 0) {
+ 	  lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			    ElmNoAttachments,			
+ 			    "There are no attachments!"));
+           break;
+         }
+ 	if (question_me) {
+ 	  for(;;) {
+ 	    PutLine0(elm_LINES-2, 0, "Are you sure? (y/n): y");
+ 	    MoveCursor(elm_LINES-2, 21);
+ 	    ch = ReadCh(0);
+ 	    if (ch == 'y' || ch == '\n' || ch == 'n')
+ 	      break;
+ 	  }
+ 	  ClearLine(elm_LINES-2);
+ 	  if (ch == 'n')
+ 	    break;
+ 	}
+       delete_it:
+ 	/* List will be rebuild in exit */
+ 	ptrs[cur]->next = NULL;
+   	mime_destroy (ptrs[cur]);
+ 	ptrs[cur] = NULL;
+ 	/* Shift the rest of the pointers down by one. */
+ 	for (i = cur + 1; i < ptr_max; i++)
+ 	  ptrs[i-1] = ptrs[i];
+ 	ptrs[ptr_max-1] = NULL;
+         ptr_max--;
+ 	if ( cur >= ptr_max && cur > 0 ) cur = ptr_max-1;
+ 	update = TRUE;
+       }
+       break;
+     case 'a':
+       if (! rdonly) {
+ 	tmp = (mime_t *) mime_t_alloc ();
+ 	if (attach_modify (tmp, TRUE)) {
+ 	  if (ptr_len == ptr_max)
+ 	    ptrs = (mime_t **) DynamicArray (ptrs, sizeof (mime_t *), &ptr_len, 5);
+ 	  ptrs[ptr_max++] = tmp;
+ 	}
+ 	else {
+ 	  /* List will be rebuild in exit */
+ 	  tmp->next = NULL;
+ 	  mime_destroy(tmp);
+ 	}
+         update = TRUE;
+       }
+       break;
+     case 'm':
+       if (! rdonly) {
+         if (ptr_max == 0) {
+ 	  lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			    ElmNoAttachments,			
+ 			    "There are no attachments!"));
+           break;
+         }
+ 	attach_modify (ptrs[cur], FALSE);
+ 	/* If there is not pathname it is otherwise assumed to be 
+ 	 * part from mailfile...!
+ 	 */
+ 	if (ptrs[cur]->pathname == NULL)
+ 	  goto delete_it;
+         update = TRUE;
+       }
+       break;
+     case 'j':
+     case 'J':
+     case 'n':
+     case DOWN_MARK:
+     case ctrl('N'):
+     NEXT_ATTACH:
+       if (cur >= ptr_max - 1) {
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			  ElmLastAttachment,			
+ 			  "You are on the last attachment!"));
+ 	break;
+       }
+       if (arrow_cursor)
+ 	write_num(cur+1,FALSE,offset + cur - top);
+       else
+ 	attach_header (ptrs[cur], cur+1, FALSE, rdonly, offset + cur - top);
+       cur++;
+       if (cur < top + elm_LINES -3 - offset) {
+ 	if (arrow_cursor)
+ 	  write_num(cur+1,TRUE,offset + cur - top);
+ 	else
+ 	  attach_header (ptrs[cur], cur+1, TRUE, rdonly, offset + cur - top);
+       }
+       break;
+     case 'k':
+     case 'K':
+     case ctrl('K'):
+     case UP_MARK:
+     PREV_ATTACH:
+       if (cur == 0) {
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			  ElmFirstAttachment,			
+ 			  "You are on the first attachment!"));
+ 	break;
+       }
+       if (arrow_cursor) 
+ 	write_num(cur+1,FALSE,offset + cur - top);
+       else
+ 	attach_header (ptrs[cur], cur+1, FALSE, rdonly, offset + cur - top);
+       cur--;
+       if (cur >= top) {
+ 	if (arrow_cursor)
+ 	  write_num(cur+1,TRUE,offset + cur - top);
+ 	else	  
+ 	  attach_header (ptrs[cur], cur+1, TRUE, rdonly, offset + cur - top);
+       }
+       break;
+     case 'i':
+       if (! rdonly)
+         break;
+       /* else fall through to next statement! */
+     case 'q':
+     case 'x':
+       if (ptrs == NULL)
+         return NULL;
+       if (! rdonly) {
+ 	/* The attachments might have been edited, so rebuild the list */
+ 	if (ptr_max > 0) {
+ 	  ret = tmp = ptrs[0];
+ 
+ 	  if (ret->magic != MIME_magic)
+ 	    mime_panic(__FILE__,__LINE__,"attach_menu",
+ 		       "Bad magic number (ptrs[0])");
+ 
+ 	  for (i = 1; i < ptr_max; i++) {
+ 	    
+ 	    if (ptrs[i]->magic != MIME_magic)
+ 	      mime_panic(__FILE__,__LINE__,"attach_menu",
+ 			 "Bad magic number (ptrs[..])");
+ 
+ 	    tmp->next = ptrs[i];
+ 	    tmp = tmp->next;
+ 	  }
+ 	  tmp->next = NULL;
+ 	}
+ 	else
+ 	  ret = NULL;
+       }
+       else
+ 	ret = mt;
+       free (ptrs);
+       return ret;
+ #ifdef USE_PGP
+     case ctrl('F'):
+       pgp_void_passphrase();
+       lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			ElmPassphraseForgotten,			
+ 			"Passphrase forgotten!"));
+       break;
+ #endif
+     case ctrl('L'):
+     case REDRAW_MARK:
+       update = TRUE;
+       break;
+     default:
+       lib_error(CATGETS(elm_msg_cat, ElmSet,
+ 			ElmUnknownCommand3,		       
+ 			"Unknown command: %c"), 
+ 		ch);
+     }
+   }
+ }
+ #endif /* MIME */
+ 
+ 
+ 
+ 
+ 
+ 
Index: elm2.4.ME+.50/src/bouncebk.c
*** elm2.4.25/src/bouncebk.c	Wed Feb  3 21:06:46 1993
--- elm2.4.ME+.50/src/bouncebk.c	Tue Nov 17 21:12:57 1998
***************
*** 1,132 ****
- 
- static char rcsid[] = "@(#)$Id: bouncebk.c,v 5.2 1993/02/03 19:06:31 syd Exp $";
- 
- /*******************************************************************************
-  *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
-  *
-  * 			Copyright (c) 1988-1992 USENET Community Trust
-  * 			Copyright (c) 1986,1987 Dave Taylor
-  *******************************************************************************
-  * Bug reports, patches, comments, suggestions should be sent to:
-  *
-  *	Syd Weinstein, Elm Coordinator
-  *	elm@DSI.COM			dsinc!elm
-  *
-  *******************************************************************************
-  * $Log: bouncebk.c,v $
-  * Revision 5.2  1993/02/03  19:06:31  syd
-  * Remove extra strchr/strcat/strcpy et al declarations
-  * From: Syd
-  *
-  * Revision 5.1  1992/10/03  22:58:40  syd
-  * Initial checkin as of 2.4 Release at PL0
-  *
-  *
-  ******************************************************************************/
- 
- /** This set of routines implement the bounceback feature of the mailer.
-     This feature allows mail greater than 'n' hops away (n specified by
-     the user) to have a 'cc' to the user through the remote machine.  
- 
-     Due to the vagaries of the Internet addressing (uucp -> internet -> uucp)
-     this will NOT generate bounceback copies with mail to an internet host!
- 
- **/
- 
- #include "headers.h"
- 
- char *bounce_off_remote();		/* forward declaration */
- 
- int
- uucp_hops(to)
- register char *to;
- {	
- 	/** Given the entire "To:" list, return the number of hops in the
- 	    first address (a hop = a '!') or ZERO iff the address is to a
-   	    non uucp address.
- 	**/
- 
- 	register int hopcount = 0, len;
- 
- 	while (*to) {
- 	  len = len_next_part(to);
- 	  if (len == 1) {
- 	    if (whitespace(*to))
- 	      break;
- 	    
- 	    if (*to == '!')
- 	      hopcount++;
- 	    else if (*to == '@' || *to == '%' || *to == ':')
- 	      return(0);	/* don't continue! */
- 	  }
- 	  to += len;
- 	}
- 
- 	return(hopcount);
- }
- 	
- char *bounce_off_remote(to)
- register char *to;
- {
- 	/** Return an address suitable for framing (no, that's not it...)
- 	    Er, suitable for including in a 'cc' line so that it ends up
- 	    with the bounceback address.  The method is to take the first 
- 	    address in the To: entry and break it into machines, then 
- 	    build a message up from that.  For example, consider the
- 	    following address:
- 			a!b!c!d!e!joe
- 	    the bounceback address would be;
- 			a!b!c!d!e!d!c!b!a!ourmachine!ourname
- 	    simple, eh?
- 	**/
- 
- 	static char address[LONG_STRING];	/* BEEG address buffer! */
- 
- 	char   host[MAX_HOPS][NLEN];	/* for breaking up addr */
- 	register int hostcount = 0, hindex = 0, iindex, len;
- 
- 	while (*to) {
- 	  len = len_next_part(to);
- 	  if (len == 1) {
- 	    if (whitespace(*to))
- 	      break;
- 	    
- 	    if (*to == '!') {
- 	      host[hostcount][hindex] = '\0';
- 	      hostcount++;
- 	      hindex = 0;
- 	    } else 
- 	      host[hostcount][hindex++] = *to++;
- 	  } else {
- 	    while (--len >= 0)
- 	      host[hostcount][hindex++] = *to++;
- 	  }
- 	}
- 
- 	/* we have hostcount hosts... */
- 
- 	strcpy(address, host[0]);	/* initialize it! */
- 
- 	for (iindex=1; iindex < hostcount; iindex++) {
- 	  strcat(address, "!");
- 	  strcat(address, host[iindex]);
- 	}
- 	
- 	/* and now the same thing backwards... */
- 
- 	for (iindex = hostcount -2; iindex > -1; iindex--) {
- 	  strcat(address, "!");
- 	  strcat(address, host[iindex]);
- 	}
- 
- 	/* and finally, let's tack on our machine and login name */
- 
- 	strcat(address, "!");
- 	strcat(address, hostname);
- 	strcat(address, "!");
- 	strcat(address, username);
- 
- 	/* and we're done!! */
- 
- 	return( (char *) address );
- }
--- 0 ----
Index: elm2.4.ME+.50/src/builtin++.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/src/builtin++.c	Tue Nov 17 21:14:09 1998
***************
*** 0 ****
--- 1,411 ----
+ static char rcsid[] = "@(#)$Id: builtin++.c,v 1.3 1998/11/16 17:08:35 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *
+  *  Initially written by: Michael Elkins <elkins@aero.org>, 1995
+  *****************************************************************************/
+ 
+ #include "headers.h"
+ #include "me.h"
+ #include "s_elm.h"
+ 
+ extern int errno;
+ extern int tabspacing;
+ 
+ static void
+ builtin_help () {
+   /* A help screen for the pager below. */
+ 
+ redraw:
+   ClearScreen ();
+   StartInverse();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpTitle,
+ 			   "Help for builtin++"));
+   EndInverse();
+   NewLine ();
+   NewLine ();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpKeyA,
+ 			   "Key\t\tAction"));
+   NewLine ();
+   Write_to_screen (FRM("---\t\t------"));
+   NewLine ();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpSpace,
+ 			   "<SPACE>, +\tNext page."));
+   NewLine ();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpMinus,
+ 			   "-\t\tPrevious page."));
+   NewLine ();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpReturn,
+ 			   "<RETURN>\tNext line."));
+   NewLine ();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpq,
+ 			   "q, x, i\t\tReturn to the index menu."));
+   NewLine ();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpDiv,
+ 			   "/\t\tSearch for pattern in message."));
+   NewLine ();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpArr,
+ 			   "^\t\tFirst page."));
+   NewLine ();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpG,
+ 			   "G\t\tLast page."));
+   NewLine ();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpCtrlL,
+ 			   "^L\t\tRefresh display."));
+   NewLine ();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpCtrlP,
+ 			   "^P\t\tUp one line."));
+   NewLine ();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpCtrlP,
+ 			   "^D\t\tDown one-half page."));
+   NewLine ();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpCtrlU,
+ 			   "^U\t\tUp one-half page."));
+   NewLine ();
+   Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpQuestion,
+ 			   "?\t\tThis help screen."));
+   NewLine ();
+   PutLineX (elm_LINES, 0, 
+ 	    CATGETS(elm_msg_cat, ElmSet, ElmBuiltinHelpPressRet,
+ 		    "Press any key to return..."));
+   if (REDRAW_MARK == ReadCh (REDRAW_MARK))
+     goto redraw;
+ 
+   return;
+ }
+ 
+ int
+ builtinplusplus (fp, begin, length, text, textlen)
+      FILE *fp;
+      long begin;
+      int length, textlen;
+      char **text;
+ {
+   char buffer[LONG_STRING], searchword[STRING], *pending = NULL;
+   long **offsets = NULL;
+   int offset_len = 0, offset_max = 0;
+   int lines = 0, saveidx, ch, len, chars;
+   int slurping = FALSE; /* used to find the end of the file */
+   int searching = FALSE;
+   long end_offset = begin + length;
+   int idx = -textlen, cur_line_len;
+   int is_end = 0;
+ 
+   if (fseek (fp, begin, 0) == -1) {
+     dprint (1, (debugfile, "pager2(): fseek() returned errno %d!\n", errno));
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFailedSeekBytes,
+ 		      "Failed to seek %d bytes into file!"), 
+ 	      begin);
+     if (sleepmsg > 0)
+       sleep (sleepmsg);
+     return (0);
+   }
+ 
+   clear_error();
+   ClearScreen();
+ 
+   for (;;) {
+     while (((ftell (fp) < end_offset) || (idx < 0)) &&
+ 	   (lines < elm_LINES || searching || slurping)) {
+ 
+       if (pending == NULL) {
+ 	/* There is no pending data to output, so we need to grab another
+ 	 * line.
+ 	 */
+ 	if (idx < 0) {
+ 	  /* Negative index numbers refer to the text block passed to pager2.
+ 	   * this is necessary for doings things like adding a title and
+ 	   * weeding unwanted headers.
+ 	   */
+ 	  pending = text[textlen+idx];
+ 	  idx++;
+ 	}
+ 	else {
+ 	  if (offset_len >= offset_max - 1)
+ 	    offsets = (long **) DynamicArray (offsets, 
+ 					      sizeof (long *), &offset_max, 
+ 					      elm_LINES + 1);
+ 	  if (idx == offset_len) {
+ 	    if (! offsets[idx]) {
+ 	      offsets[idx] = (long *) safe_malloc (sizeof (long));
+ 	      offset_len++;
+ 	    }
+ 	    *offsets[idx] = ftell (fp);
+ 	  }
+ 	
+ 	  if ((cur_line_len= mail_gets (buffer, LONG_STRING, fp)) <= 0) {
+ 	    if (slurping) {
+ 	      slurping = FALSE;
+ 	      idx -= elm_LINES;
+ 	      if (idx < -textlen)
+ 		idx = -textlen;
+ 	      fseek (fp, *offsets[idx > -1 ? idx : 0], 0);
+ 	      continue;
+ 	    }
+ 	    if (searching) {
+ 	      searching = FALSE;
+ 	      ClearLine (elm_LINES);
+ 	      PutLineX (elm_LINES, 0, 	    
+ 			CATGETS(elm_msg_cat, ElmSet, ElmBuiltinNotFound,
+ 				"NOT FOUND!"));
+ 	      if (sleepmsg > 0)
+ 		sleep (sleepmsg);	 
+ 	      ClearLine (elm_LINES);
+ 	      /* Reposition the file at the appropriate place */
+ 	      idx = saveidx;
+ 	      fseek (fp, *offsets[idx > 0 ? idx : 0], 0);
+ 	    }
+ 	    break;
+ 	  }
+ 	  
+ 	  idx++;
+ 
+ 	  if (slurping)
+ 	    continue;
+ 	  
+ 	  if (searching) {
+ 	    if (in_string (buffer, searchword)) {
+ 	      searching = FALSE;
+ 	      idx -= 3;
+ 	      if (idx < -textlen)
+ 		idx = -textlen;
+ 	      if (idx >= 0) fseek (fp, *offsets[idx], 0);
+ 	      else fseek (fp, begin, 0);
+ 	      ClearScreen ();
+ 	      lines = 0;
+ 	    }
+ 	    continue;
+ 	  }
+ 
+ 	  if (cur_line_len > 0 && buffer[cur_line_len-1] == '\n') {
+ 	    buffer[cur_line_len-1] = '\0';
+ 	    if (cur_line_len > 1 && buffer[cur_line_len-2] == '\r') 
+ 	      buffer[cur_line_len-2] = '\0';
+ 	  }
+ 
+ 	  pending = buffer;
+ 	}
+       }
+ 
+       /* This is the part of the code that actually displays on the screen */
+       chars = 0;
+       while (*pending) {
+ 	if (chars >= elm_COLUMNS)
+ 	  break;
+ 
+ 	if (*pending == '\t') {
+ 	  Writechar('\t');
+ 	  /* 'chars += tabspacing' is INCORRENT! - K E H */ 
+ 	  chars = ((chars / tabspacing ) +1) * tabspacing; 
+ 	}
+ #ifdef ASCII_CTYPE
+         else if (!isascii((unsigned char)*pending)) {
+           Writechar('?');
+           chars++;
+         }
+ #endif
+ 	else if (!isprint((unsigned char)*pending)) {
+ 	  if (*pending >= 0 && *pending <= 31) {    
+             /* This won't fit on the line, so just skip it for now */
+             if (chars == elm_COLUMNS - 1)
+               break;
+ 
+             Writechar('^');
+             Writechar(*pending + 64);
+             chars += 2;
+ 
+             /* Honor the formfeed character */
+             if (*pending == ctrl('L')) {
+               break;
+             }
+           }
+           else {
+             Writechar('?');
+             chars++;
+           }
+ 	}
+ 	else {
+ 	  Writechar(*pending);
+ 	  chars++;
+ 	}
+ 	pending++;
+       }
+       NewLine();
+       lines++;
+ 
+       if (*pending == ctrl('L')) {
+         pending++;
+         if (*pending == '\0')
+           pending = NULL;
+         break;
+       }
+ 
+       /* Check to see if we are finished with this line */
+       if (*pending == '\0')
+ 	pending = NULL;
+     }
+     if (slurping){
+       slurping = FALSE;
+       idx -= elm_LINES;
+       if (idx < -textlen)
+         idx = -textlen;
+       if (idx >= 0) fseek (fp, *offsets[idx], 0);
+       else fseek (fp, begin, 0);
+       continue;
+     }
+ 
+     StartBold();
+     if (idx < 0) {
+       Write_to_screen (CATGETS(elm_msg_cat, ElmSet, ElmBuiltinMore0,
+ 			       "More (you've seen 0%%)"));
+       len = 0;
+       is_end = 0;
+     }
+     else {
+       if (length < 1)
+         len = 100;
+       else {
+         long pos = ftell (fp);
+ 
+         len = 100 * (pos - begin) / length;
+       }
+ 
+       if (len >= 100) {
+         Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmBuiltinCommandi,
+ 				"Command ('i' to return to index):"));
+         is_end = 1;
+       }
+       else {
+         Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmBuiltInMore,
+ 				"MORE (you've seen %d%%):"), 
+ 			len);
+         is_end = 0;
+       }
+     }
+     EndBold();
+ 
+     ch = ReadCh (REDRAW_MARK|READCH_CURSOR);
+     switch (ch) {
+     case ' ':
+     case '+':
+     case PAGEDOWN_MARK:
+       if (is_end) {
+ 	DestroyDynamicArray (offsets);
+ 	return (' ');
+       }
+       lines = 0;
+       ClearScreen ();
+       break;
+     case HOME_MARK:
+     case '^':      
+       idx = -textlen;
+       fseek (fp, begin, 0);
+       lines = 0;
+       ClearScreen ();
+       break;
+     case 'G':
+       idx = offset_len-1;
+       if (idx >= 0) fseek (fp, *offsets[idx], 0);
+       else fseek (fp, begin, 0);
+       slurping = TRUE;
+       lines = 0;
+       ClearScreen ();
+       break;
+     case FIND_MARK:
+     case '/':
+       ClearLine (elm_LINES);
+       PutLineX (elm_LINES, 0, 
+ 		CATGETS(elm_msg_cat, ElmSet, ElmBuiltinSearch,"Search%s"),
+ 		": ");
+       searchword[0] = '\0';
+       {
+ 	int code = optionally_enter (searchword, elm_LINES, 8, 
+ 				     OE_REDRAW_MARK, 
+ 				     sizeof searchword);
+ 	if (REDRAW_MARK == code)
+ 	  goto redraw;
+ 	if (code < 0)
+ 	  goto quit;
+       }
+       if (searchword[0])
+ 	searching = TRUE;
+       saveidx = idx;
+       break;	
+     case PAGEUP_MARK:
+     case '-':
+       idx -= elm_LINES * 2;
+       if (idx < -textlen)
+ 	idx = -textlen;
+       if (idx >= 0) fseek (fp, *offsets[idx], 0);
+       else fseek (fp, begin, 0);
+       ClearScreen ();
+       lines = 0;
+       break;
+     case ctrl('P'):
+       idx -= elm_LINES + 1;
+       if (idx < -textlen)
+ 	idx = -textlen;
+       if (idx >= 0) fseek (fp, *offsets[idx], 0);
+       else fseek (fp, begin, 0);
+       lines = 0;
+       ClearScreen();
+       break;
+     case ctrl('D'):
+       lines = elm_LINES / 2;
+       CarriageReturn();
+       if (CleartoEOLN() >= 0)
+ 	 break;  
+ 
+       idx -= (elm_LINES / 2);
+       if (idx < -textlen)
+ 	idx = -textlen;
+       if (idx >= 0) fseek (fp, *offsets[idx], 0);
+       else fseek (fp, begin, 0);
+       lines = 0;
+       ClearScreen ();
+       break;
+ 
+     case ctrl('U'):
+       idx -= elm_LINES + (elm_LINES / 2);
+       if (idx < -textlen)
+ 	idx = -textlen;
+       if (idx >= 0) fseek (fp, *offsets[idx], 0);
+       else fseek (fp, begin, 0);
+       lines = 0;
+       ClearScreen ();
+       break;
+     case HELP_MARK:
+     case '?':
+       builtin_help ();
+     case REDRAW_MARK:
+     case ctrl('L'):
+     redraw:
+       idx -= elm_LINES;
+       if (idx < -textlen)
+ 	idx = -textlen;
+       if (idx >= 0) fseek (fp, *offsets[idx], 0);
+       else fseek (fp, begin, 0);
+       ClearScreen ();
+       lines = 0;
+       break;
+     case '\n':
+       {
+ 	int x, y;
+ 
+ 	GetXYLocation (&x, &y);
+ 	ClearLine (x);
+       }
+       lines = elm_LINES - 1;
+       break;
+     case EOF:
+     default:
+     quit:
+       DestroyDynamicArray (offsets);
+       return (ch == 'q' || ch == 'x' ? 0 : ch);
+     }
+   }
+ }
+ 
Index: elm2.4.ME+.50/src/calendar.c
*** elm2.4.25/src/calendar.c	Wed Feb  3 21:06:47 1993
--- elm2.4.ME+.50/src/calendar.c	Tue Nov 17 21:12:58 1998
***************
*** 1,33 ****
  
! static char rcsid[] = "@(#)$Id: calendar.c,v 5.3 1993/02/03 19:06:31 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: calendar.c,v $
!  * Revision 5.3  1993/02/03  19:06:31  syd
!  * Remove extra strchr/strcat/strcpy et al declarations
!  * From: Syd
!  *
!  * Revision 5.2  1992/11/26  00:46:50  syd
!  * Fix how errno is used so err is inited and used instead
!  * as errno gets overwritten by print system call
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This routine implements a rather snazzy idea suggested by Warren
      Carithers of the Rochester Institute of Technology that allows
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: calendar.c,v 1.2 1998/10/20 19:58:15 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This routine implements a rather snazzy idea suggested by Warren
      Carithers of the Rochester Institute of Technology that allows
***************
*** 67,74 ****
  		  "Error: wrong permissions to append to calendar %s\n",
  		  calendar_file));
  	  dprint(2, (debugfile, "** - %s **\n", error_description(err)));
! 	  error1(catgets(elm_msg_cat, ErrorSet, ErrorCalendarCanOpen,
! 		  "Not able to append to file %s!"), calendar_file);
  	  return; 
  	}
  
--- 50,58 ----
  		  "Error: wrong permissions to append to calendar %s\n",
  		  calendar_file));
  	  dprint(2, (debugfile, "** - %s **\n", error_description(err)));
! 	  lib_error(CATGETS(elm_msg_cat, ErrorSet, ErrorCalendarCanOpen,
! 			    "Not able to append to file %s!"), 
! 		    calendar_file);
  	  return; 
  	}
  
***************
*** 80,87 ****
  		"Error: couldn't append to calendar file %s (scan)\n", 
  		calendar_file));
  	  dprint(2, (debugfile, "** - %s **\n", error_description(err)));
! 	  error1(catgets(elm_msg_cat, ErrorSet, ErrorCalendarAppend,
! 		  "Couldn't append to file %s!"), calendar_file);
  	  return; 
  	}
  	
--- 64,72 ----
  		"Error: couldn't append to calendar file %s (scan)\n", 
  		calendar_file));
  	  dprint(2, (debugfile, "** - %s **\n", error_description(err)));
! 	  lib_error(CATGETS(elm_msg_cat, ErrorSet, ErrorCalendarAppend,
! 			    "Couldn't append to file %s!"), 
! 		    calendar_file);
  	  return; 
  	}
  	
***************
*** 93,106 ****
  
  	if (count > 0) {
  	  if (count > 1)
! 	    error1(catgets(elm_msg_cat, ErrorSet, ErrorCalendarSavedPlural,
! 		    "%d entries saved in calendar file."), count);
  	  else
! 	    error(catgets(elm_msg_cat, ErrorSet, ErrorCalendarSaved,
! 		    "1 entry saved in calendar file."));
  	} else 
! 	  error(catgets(elm_msg_cat, ErrorSet, ErrorCalendarNoneSaved,
! 		  "No calendar entries found in that message."));
  
  	return;
  }
--- 78,92 ----
  
  	if (count > 0) {
  	  if (count > 1)
! 	    lib_error(CATGETS(elm_msg_cat, ErrorSet, ErrorCalendarSavedPlural,
! 			      "%d entries saved in calendar file."), 
! 		      count);
  	  else
! 	    lib_error(CATGETS(elm_msg_cat, ErrorSet, ErrorCalendarSaved,
! 			      "1 entry saved in calendar file."));
  	} else 
! 	  lib_error(CATGETS(elm_msg_cat, ErrorSet, ErrorCalendarNoneSaved,
! 			    "No calendar entries found in that message."));
  
  	return;
  }
***************
*** 123,131 ****
         	  dprint(1,(debugfile, 
  		"ERROR: Attempt to seek %d bytes into file failed (%s)",
  		headers[current-1]->offset, "extract_info"));
!        	  error1(catgets(elm_msg_cat, ErrorSet, ErrorCalendarSeek,
! 		  "ELM [seek] failed trying to read %d bytes into file."),
! 	     	headers[current-1]->offset);
         	  return(0);
      	}
  
--- 109,117 ----
         	  dprint(1,(debugfile, 
  		"ERROR: Attempt to seek %d bytes into file failed (%s)",
  		headers[current-1]->offset, "extract_info"));
!        	  lib_error(CATGETS(elm_msg_cat, ErrorSet, ErrorCalendarSeek,
! 			    "ELM [seek] failed trying to read %d bytes into file."),
! 		    headers[current-1]->offset);
         	  return(0);
      	}
  
Index: elm2.4.ME+.50/src/curses.c
*** elm2.4.25/src/curses.c	Mon May 30 19:27:44 1994
--- elm2.4.ME+.50/src/curses.c	Tue Nov 17 21:14:09 1998
***************
*** 1,116 ****
  
! static char rcsid[] = "@(#)$Id: curses.c,v 5.18 1994/05/30 16:27:44 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.18 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
-  *******************************************************************************
-  * Bug reports, patches, comments, suggestions should be sent to:
-  *
-  *	Syd Weinstein, Elm Coordinator
-  *	elm@DSI.COM			dsinc!elm
-  *
-  *******************************************************************************
-  * $Log: curses.c,v $
-  * Revision 5.18  1994/05/30  16:27:44  syd
-  * There was a typo in src/curses.c. An include read out like
-  * "# include <vararg.h>" though the file name should have been
-  * varargs.h.
-  * From: Jukka Antero Ukkonen <ukkonen@csc.fi>
-  *
-  * Revision 5.17  1994/05/15  23:10:08  syd
-  * Below are the changes required to compile/link elm 2.4 pl23 under
-  * QNX 4.2 with the Watcom 9.5 compiler (very picky).
-  * From: "Brian Campbell" <brianc@quantum>
-  *
-  * Revision 5.16  1994/05/15  22:58:36  syd
-  * Tune the Ultrix fix for ispell
-  * From: Bill Gianopoulos <wag@sccux1.msd.ray.com>
-  *
-  * Revision 5.15  1994/05/15  22:55:25  syd
-  * I had to put in some changes to builtin+ to allow it to display
-  * 8-bit letters as they should when the message has been sent
-  * through a real 8-bit channel like ESMTP with 8bit MIME Content-
-  * Transfer-Encoding.
-  * From: Jukka Ukkonen <ukkonen@csc.fi>
-  *
-  * Revision 5.14  1994/03/11  20:45:03  syd
-  * fixed ReadCh() to recover from EINTR and EAGAIN instead
-  * of just returning an unexpected EOF.
-  * From: Jukka Ukkonen <ukkonen@csc.fi>
-  *
-  * Revision 5.13  1993/08/23  02:56:35  syd
-  * have Writechar() backspace over the left edge of the screen to the end
-  * of the previous line if the current line is not the first line on the
-  * screen.
-  * From: Jukka Ukkonen <ukkonen@csc.fi>
-  *
-  * Revision 5.12  1993/08/03  19:28:39  syd
-  * Elm tries to replace the system toupper() and tolower() on current
-  * BSD systems, which is unnecessary.  Even worse, the replacements
-  * collide during linking with routines in isctype.o.  This patch adds
-  * a Configure test to determine whether replacements are really needed
-  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
-  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
-  * there.  Inclusion of <ctype.h> was removed from *all* the individual
-  * files, and the toupper() and tolower() routines in lib/opt_utils.c
-  * were dropped.
-  * From: chip@chinacat.unicom.com (Chip Rosenthal)
-  *
-  * Revision 5.11  1993/07/20  02:13:20  syd
-  * Make tabspacing check for <= 0 so we dont get divide by
-  * zero errors when the termcap has tabspacing 0
-  * From: Syd via request from G A Smant
-  *
-  * Revision 5.10  1993/04/12  03:57:45  syd
-  * Give up and add an Ultrix specific patch. There is a bug in Ispell under
-  * ultrix.  The problem is that when ispell returns, the terminal is no
-  * longer in raw mode. (Ispell isn't restoring the terminal parameters)
-  * From: Scott Ames <scott@cwis.unomaha.edu>
-  *
-  * Revision 5.9  1993/02/03  19:06:31  syd
-  * Remove extra strchr/strcat/strcpy et al declarations
-  * From: Syd
-  *
-  * Revision 5.8  1992/12/11  01:45:04  syd
-  * remove sys/types.h include, it is now included by defs.h
-  * and this routine includes defs.h or indirectly includes defs.h
-  * From: Syd
-  *
-  * Revision 5.7  1992/11/07  20:45:39  syd
-  * add no tite flag on options that should not use ti/te
-  * Hack by Syd
-  *
-  * Revision 5.6  1992/10/27  15:46:35  syd
-  * Suns dont like ioctl on top of termios
-  * From: syd
-  *
-  * Revision 5.5  1992/10/27  01:52:16  syd
-  * Always include <sys/ioctl.h> in curses.c When calling ioctl()
-  *
-  * Remove declaration of getegid() from leavembox.c & lock.c
-  * They aren't even used there.
-  * From: tom@osf.org
-  *
-  * Revision 5.4  1992/10/24  13:35:39  syd
-  * changes found by using codecenter on Elm 2.4.3
-  * From: Graham Hudspith <gwh@inmos.co.uk>
-  *
-  * Revision 5.3  1992/10/17  22:58:57  syd
-  * patch to make elm use (or in my case, not use) termcap/terminfo ti/te.
-  * From: Graham Hudspith <gwh@inmos.co.uk>
   *
!  * Revision 5.2  1992/10/11  01:02:05  syd
!  * Add AIX to those who dont define window size in termios.h
!  * From: Syd via note from Tom Kovar
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /**  This library gives programs the ability to easily access the
       termcap information and write screen oriented and raw input
--- 1,17 ----
  
! static char rcsid[] = "@(#)$Id: curses.c,v 1.3 1998/11/15 19:11:19 hurtta Exp $";
  
! /*****************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
   *
!  *****************************************************************************/
  
  /**  This library gives programs the ability to easily access the
       termcap information and write screen oriented and raw input
***************
*** 126,137 ****
  **/
  
  #include "headers.h"
  
- #ifdef I_STDARG
- # include <stdarg.h>
- #else
- # include <varargs.h>
- #endif
  #ifdef TERMIOS
  # include <termios.h>
  # ifndef sun
--- 27,35 ----
  **/
  
  #include "headers.h"
+ #include <errno.h>
+ #include "me.h"
  
  #ifdef TERMIOS
  # include <termios.h>
  # ifndef sun
***************
*** 174,183 ****
  #define	ttgetattr(fd,where)	ioctl((fd),TCGETA,(where))
  #define	ttsetattr(fd,where)	ioctl((fd),TCSETAW,(where))
  # else
! struct sgttyb _raw_tty,
! 	      _original_tty;
! #define	ttgetattr(fd,where)	ioctl((fd),TIOCGETP,(where))
! #define	ttsetattr(fd,where)	ioctl((fd),TIOCSETP,(where))
  # endif	/*TERMIO*/
  #endif	/*TERMIOS*/
  
--- 72,83 ----
  #define	ttgetattr(fd,where)	ioctl((fd),TCGETA,(where))
  #define	ttsetattr(fd,where)	ioctl((fd),TCSETAW,(where))
  # else
! struct tty_modes {
!   struct sgttyb sgttyb;
!   struct tchars tchars;
! }  _raw_tty, _original_tty;
! static int ttgetattr P_((int,struct tty_modes *));  /* Prototype */
! static int ttsetattr P_((int,struct tty_modes *)); /* Prototype */
  # endif	/*TERMIO*/
  #endif	/*TERMIOS*/
  
***************
*** 190,206 ****
  static int _line  = -1,			/* initialize to "trash" */
             _col   = -1;
  
! static int _intransmit;			/* are we transmitting keys? */
  
  static
! char *_clearscreen, *_moveto, *_up, *_down, *_right, *_left,
!      *_setbold, *_clearbold, *_setunderline, *_clearunderline, 
!      *_sethalfbright, *_clearhalfbright, *_setinverse, *_clearinverse,
!      *_cleartoeoln, *_cleartoeos, *_transmit_on, *_transmit_off,
!      *_set_memlock, *_clear_memlock, *_start_termcap, *_end_termcap;
  
  static int _lines, _columns, _automargin, _eatnewlineglitch;
  int tabspacing;
  
  static char _terminal[1024];              /* Storage for terminal entry */
  static char _capabilities[1024];           /* String for cursor motion */
--- 90,113 ----
  static int _line  = -1,			/* initialize to "trash" */
             _col   = -1;
  
! static int _intransmit = -1;	        /* are we transmitting keys? */
  
  static
! char *_clearscreen = NULL, *_moveto = NULL, *_up = NULL, *_down = NULL, 
!   *_right = NULL, *_left = NULL, *_setbold = NULL, *_clearbold = NULL, 
!   *_setunderline = NULL, *_clearunderline = NULL, *_sethalfbright = NULL, 
!   *_clearhalfbright = NULL, *_setinverse = NULL, *_clearinverse = NULL,
!   *_cleartoeoln = NULL, *_cleartoeos = NULL, *_transmit_on = NULL, 
!   *_transmit_off = NULL, *_set_memlock = NULL, *_clear_memlock = NULL, 
!   *_start_termcap = NULL, *_end_termcap = NULL, *_bell = NULL,
! 
!   *_key_up = NULL, *_key_down = NULL, *_key_left = NULL, *_key_right = NULL,
!   *_key_pageup = NULL, *_key_pagedown = NULL, *_key_home = NULL, 
!   *_key_help = NULL, *_key_find = NULL;
  
  static int _lines, _columns, _automargin, _eatnewlineglitch;
  int tabspacing;
+ static int tabexpand = 0;          /* Is terminal driver expanding tabs? */
  
  static char _terminal[1024];              /* Storage for terminal entry */
  static char _capabilities[1024];           /* String for cursor motion */
***************
*** 207,212 ****
--- 114,122 ----
  
  static char *ptr = _capabilities;	/* for buffering         */
  
+ static int  cursor_control    = 0;
+ static int  need_moveabsolute = 0;
+ 
  int    outchar();			/* char output for tputs */
  char  *tgetstr(),     		       /* Get termcap capability */
        *tgoto();				/* and the goto stuff    */
***************
*** 225,232 ****
  	
  	if ((termenv = getenv("TERM")) == NULL) return(-1);
  
! 	if (strcpy(termname, termenv) == NULL)
! 		return(-1);
  
  	if ((err = tgetent(_terminal, termname)) != 1)
  		return(err-2);
--- 135,141 ----
  	
  	if ((termenv = getenv("TERM")) == NULL) return(-1);
  
! 	strfcpy(termname, termenv, sizeof termname);
  
  	if ((err = tgetent(_terminal, termname)) != 1)
  		return(err-2);
***************
*** 241,246 ****
--- 150,157 ----
  	_down              = tgetstr("do", &ptr);
  	_right             = tgetstr("nd", &ptr);
  	_left              = tgetstr("bc", &ptr);
+ 	_bell              = tgetstr("bl", &ptr);
+ 
  	_setbold           = tgetstr("so", &ptr);
  	_clearbold         = tgetstr("se", &ptr);
  	_setunderline      = tgetstr("us", &ptr);
***************
*** 263,329 ****
  	_start_termcap	   = tgetstr("ti", &ptr);
  	_end_termcap	   = tgetstr("te", &ptr);
  
  
! 	if (!_left) {
! 		_left = "\b";
  	}
  
! 	return(0);
! }
  
! char *return_value_of(termcap_label)
! char *termcap_label;
! {
! 	/** This will return the string kept by termcap for the 
! 	    specified capability. Modified to ensure that if 
! 	    tgetstr returns a pointer to a transient address	
! 	    that we won't bomb out with a later segmentation
! 	    fault (thanks to Dave@Infopro for this one!)
! 
! 	    Tweaked to remove padding sequences.
! 	 **/
! 
! 	static char escape_sequence[20];
! 	register int i=0,j=0;
! 	char buffer[20];
! 	char *myptr, *tgetstr();     		/* Get termcap capability */
! 
! 	if (strlen(termcap_label) < 2)
! 	  return(NULL);
! 
! 	if (termcap_label[0] == 's' && termcap_label[1] == 'o')
! 	  {
! 	  if (_setinverse)
! 	    strcpy(escape_sequence, _setinverse);
! 	  else
! 	    return( (char *) NULL );
! 	  }
! 	else if (termcap_label[0] == 's' && termcap_label[1] == 'e')
! 	  {
! 	  if (_clearinverse)
! 	    strcpy(escape_sequence, _clearinverse);
! 	  else
! 	    return( (char *) NULL );
! 	  }
! 	else if ((myptr = tgetstr(termcap_label, &ptr)) == NULL)
! 	  return( (char *) NULL );
! 	else
! 	  strcpy(escape_sequence, myptr);
! 
! 	if (chloc(escape_sequence, '$') != -1) {
! 	  while (escape_sequence[i] != '\0') {
! 	    while (escape_sequence[i] != '$' && escape_sequence[i] != '\0')
! 	      buffer[j++] = escape_sequence[i++];
! 	    if (escape_sequence[i] == '$') {
! 	      while (escape_sequence[i] != '>') i++;
! 	      i++;
! 	    }
! 	  }
! 	  buffer[j] = '\0';
! 	  strcpy(escape_sequence, buffer);
  	}
  
! 	return( (char *) escape_sequence);
  }
  
  transmit_functions(newstate)
--- 174,202 ----
  	_start_termcap	   = tgetstr("ti", &ptr);
  	_end_termcap	   = tgetstr("te", &ptr);
  
+ 	_key_up            = tgetstr("ku", &ptr);
+ 	_key_down          = tgetstr("kd", &ptr);
+ 	_key_left          = tgetstr("kl", &ptr);
+ 	_key_right         = tgetstr("kr", &ptr);
+ 	_key_pageup        = tgetstr("kP", &ptr);
+ 	_key_pagedown      = tgetstr("kN", &ptr);
+ 	_key_home          = tgetstr("kh", &ptr);
+ 	_key_help          = tgetstr("%1", &ptr);
+ 	_key_find          = tgetstr("@0", &ptr);
  
! 	if (_transmit_on && _transmit_off && _key_up && _key_down) {
! 	  cursor_control = TRUE;
  	}
  
! 	if (_setinverse && _clearinverse) {
! 	  has_highlighting = TRUE;
! 	}
  
! 	if (!_left) {
! 		_left = "\b";
  	}
  
! 	return(0);
  }
  
  transmit_functions(newstate)
***************
*** 332,338 ****
  	/** turn function key transmission to ON | OFF **/
  
  	if (newstate != _intransmit) {
! 		_intransmit = ! _intransmit;
  		if (newstate == ON)
  		  tputs(_transmit_on, 1, outchar);
  		else 
--- 205,211 ----
  	/** turn function key transmission to ON | OFF **/
  
  	if (newstate != _intransmit) {
! 		_intransmit = newstate;
  		if (newstate == ON)
  		  tputs(_transmit_on, 1, outchar);
  		else 
***************
*** 343,350 ****
  
  /****** now into the 'meat' of the routines...the cursor stuff ******/
  
! ScreenSize(lines, columns)
! int *lines, *columns;
  {
  	/** returns the number of lines and columns on the display. **/
  
--- 216,223 ----
  
  /****** now into the 'meat' of the routines...the cursor stuff ******/
  
! void ScreenSize(lines, columns)
!      int *lines, *columns;
  {
  	/** returns the number of lines and columns on the display. **/
  
***************
*** 362,368 ****
  	if (_lines == 0) _lines = DEFAULT_LINES_ON_TERMINAL;
  	if (_columns == 0) _columns = DEFAULT_COLUMNS_ON_TERMINAL;
  
! 	*lines = _lines - 1;		/* assume index from zero */
  	*columns = _columns;
  }
  
--- 235,259 ----
  	if (_lines == 0) _lines = DEFAULT_LINES_ON_TERMINAL;
  	if (_columns == 0) _columns = DEFAULT_COLUMNS_ON_TERMINAL;
  
! 
! 	/* WARNING: elm_LINES and elm_COLUMNS are inconsistent!
! 	 *
! 	 * elm_LINES    == number of lines in screen -1
! 	 * elm_COLUMNS  == number of rows in screen
! 	 *
! 	 *
! 	 * Check code in MoveCursor!
! 	 *
! 	 * row          == 0 .. elm_LINES
! 	 * col          == 0 .. elm_COLUMNS-1
! 	 *
! 	 *
! 	 * Who was this smart programmer!!!!!!!!!!!!!!!!!!!!!
! 	 *
! 	 *                         - K E H <hurtta@ozone.FMI.FI>
! 	 */
! 
! 	*lines = _lines - 1;	     
  	*columns = _columns;
  }
  
***************
*** 395,400 ****
--- 286,294 ----
  	_line = 0;	/* clear leaves us at top... */
  	_col  = 0;
  
+ 	redraw_screen = 0;
+ 	_intransmit = -1;   /* Re-set state */
+ 
  	if (!_clearscreen)
  		return(-1);
  
***************
*** 403,484 ****
  	return(0);
  }
  
! static
! CursorUp(n)
! int n;
  {
! 	/** move the cursor up 'n' lines **/
! 	/** Calling function must check that _up is not null before calling **/
  
! 	_line = (_line-n > 0? _line - n: 0);	/* up 'n' lines... */
  
! 	while (n-- > 0)
! 		tputs(_up, 1, outchar);
  
! 	fflush(stdout);
! 	return(0);
  }
  
  
! static
! CursorDown(n)
! int n;
  {
! 	/** move the cursor down 'n' lines **/
! 	/** Caller must check that _down is not null before calling **/
  
! 	_line = (_line+n <= LINES? _line + n: LINES);    /* down 'n' lines... */
  
! 	while (n-- > 0)
! 		tputs(_down, 1, outchar);
  
! 	fflush(stdout);
! 	return(0);
  }
  
  
! static
! CursorLeft(n)
! int n;
  {
  	/** move the cursor 'n' characters to the left **/
! 	/** Caller must check that _left is not null before calling **/
! 
! 	_col = (_col - n> 0? _col - n: 0);	/* left 'n' chars... */
! 
! 	while (n-- > 0)
! 		tputs(_left, 1, outchar);
  
! 	fflush(stdout);
! 	return(0);
  }
  
  
! static
! CursorRight(n)
! int n;
  {
! 	/** move the cursor 'n' characters to the right (nondestructive) **/
! 	/** Caller must check that _right is not null before calling **/
  
! 	_col = (_col+n < COLUMNS? _col + n: COLUMNS);	/* right 'n' chars... */
  
! 	while (n-- > 0)
! 		tputs(_right, 1, outchar);
  
! 	fflush(stdout);
! 	return(0);
  }
  
! static
! moveabsolute(col, row)
  {
  
! 	char *stuff, *tgoto();
  
! 	stuff = tgoto(_moveto, col, row);
! 	tputs(stuff, 1, outchar);
! 	fflush(stdout);
  }
  
  MoveCursor(row, col)
--- 297,397 ----
  	return(0);
  }
  
! static void moveabsolute P_((int col, int row));
! 
! static CursorUp(n)
!      int n;
  {
!   /** move the cursor up 'n' lines **/
!   /** Calling function must check that _up is not null before calling **/
  
!   if (need_moveabsolute)
!     moveabsolute(_col, _line);
  
!   _line = (_line-n > 0? _line - n: 0);	/* up 'n' lines... */
  
!   while (n-- > 0)
!     tputs(_up, 1, outchar);
! 
!   fflush(stdout);
!   return(0);
  }
  
  
! static CursorDown(n)
!      int n;
  {
!   /** move the cursor down 'n' lines **/
!   /** Caller must check that _down is not null before calling **/
  
!   if (need_moveabsolute)
!     moveabsolute(_col, _line);;
  
!   _line = (_line+n <= elm_LINES? _line + n: elm_LINES);    /* down 'n' lines... */
  
!   while (n-- > 0)
!     tputs(_down, 1, outchar);
!   
!   fflush(stdout);
!   return(0);
  }
  
  
! static CursorLeft(n)
!      int n;
  {
  	/** move the cursor 'n' characters to the left **/
!   /** Caller must check that _left is not null before calling **/
!   
!   if (need_moveabsolute)
!     moveabsolute(_col, _line);
  
!   _col = (_col - n> 0? _col - n: 0);	/* left 'n' chars... */
!   
!   while (n-- > 0)
!     tputs(_left, 1, outchar);
!   
!   fflush(stdout);
!   return(0);
  }
  
  
! static CursorRight(n)
!      int n;
  {
!   /** move the cursor 'n' characters to the right (nondestructive) **/
!   /** Caller must check that _right is not null before calling **/
!   
!   if (need_moveabsolute)
!     moveabsolute(_col, _line);
  
!   _col = (_col+n < elm_COLUMNS? _col + n: elm_COLUMNS);	
!   /* right 'n' chars... */
  
!   while (n-- > 0)
!     tputs(_right, 1, outchar);
  
!   fflush(stdout);
!   return(0);
  }
  
! static void moveabsolute(col, row)
!      int col, row;
  {
  
!   char *stuff, *tgoto();
  
!   if (need_moveabsolute) {
!     dprint(4,(debugfile,
! 	      "Curses: moveabsolute: Syncronizing cursos position (col=%d,row=%d)\n",
! 	      col,row));
!   }
! 
!   stuff = tgoto(_moveto, col, row);
!   tputs(stuff, 1, outchar);
!   fflush(stdout);
!   
!   need_moveabsolute = 0;
  }
  
  MoveCursor(row, col)
***************
*** 491,510 ****
  
  	/* we don't want to change "rows" or we'll mangle scrolling... */
  
  	if (col < 0)
  	  col = 0;
! 	if (col >= COLUMNS)
! 	  col = COLUMNS - 1;
  	if (row < 0)
  	  row = 0;
! 	if (row > LINES) {
  	  if (col == 0)
! 	    scrollafter = row - LINES;
! 	  row = LINES;
  	}
  
  	if (!_moveto)
! 		return(-1);
  
  	if (row == _line) {
  	  if (col == _col)
--- 404,426 ----
  
  	/* we don't want to change "rows" or we'll mangle scrolling... */
  
+ 	if (need_moveabsolute)
+ 	  moveabsolute(_col, _line);;
+ 
  	if (col < 0)
  	  col = 0;
! 	if (col >= elm_COLUMNS)
! 	  col = elm_COLUMNS - 1;
  	if (row < 0)
  	  row = 0;
! 	if (row > elm_LINES) {
  	  if (col == 0)
! 	    scrollafter = row - elm_LINES;
! 	  row = elm_LINES;
  	}
  
  	if (!_moveto)
! 	  return(-1);
  
  	if (row == _line) {
  	  if (col == _col)
***************
*** 543,550 ****
  
  	if (scrollafter) {
  	  putchar('\r');
! 	  while (scrollafter--)
  	    putchar('\n');
  	}
  
  	return(0);
--- 459,467 ----
  
  	if (scrollafter) {
  	  putchar('\r');
! 	  while (scrollafter--) {
  	    putchar('\n');
+ 	  }
  	}
  
  	return(0);
***************
*** 693,700 ****
  
  	if (! _memory_locked) {
  
! 	  _old_LINES = LINES;
! 	  LINES -= _line;		/* we can't use this for scrolling */
  
  	  tputs(_set_memlock, 1, outchar);
  	  fflush(stdout);
--- 610,617 ----
  
  	if (! _memory_locked) {
  
! 	  _old_LINES = elm_LINES;
! 	  elm_LINES -= _line;		/* we can't use this for scrolling */
  
  	  tputs(_set_memlock, 1, outchar);
  	  fflush(stdout);
***************
*** 713,719 ****
  	  return(-1);
  
  	if (_memory_locked) {
! 	  LINES = _old_LINES;		/* back to old setting */
    
  	  tputs(_clear_memlock, 1, outchar);
  	  fflush(stdout);
--- 630,636 ----
  	  return(-1);
  
  	if (_memory_locked) {
! 	  elm_LINES = _old_LINES;		/* back to old setting */
    
  	  tputs(_clear_memlock, 1, outchar);
  	  fflush(stdout);
***************
*** 732,737 ****
--- 649,657 ----
  	static int wrappedlastchar = 0;
  	int justwrapped, nt;
  
+ 	if (need_moveabsolute)
+ 	  moveabsolute(_col, _line);
+ 
  	ch &= 0xFF;
  	justwrapped = 0;
  
***************
*** 750,756 ****
  	else if (ch == '\n') {
  	  if (!wrappedlastchar) {
  	    putchar('\n');
! 	    if (_line < LINES)
  	      ++_line;
  	  }
  	}
--- 670,676 ----
  	else if (ch == '\n') {
  	  if (!wrappedlastchar) {
  	    putchar('\n');
! 	    if (_line < elm_LINES)
  	      ++_line;
  	  }
  	}
***************
*** 762,768 ****
  		_col--;
  	    }
  	    else if (_line > 0) {
! 		_col = COLUMNS - 1;
  		_line--;
  		moveabsolute (_col, _line);
  	    }
--- 682,688 ----
  		_col--;
  	    }
  	    else if (_line > 0) {
! 		_col = elm_COLUMNS - 1;
  		_line--;
  		moveabsolute (_col, _line);
  	    }
***************
*** 771,786 ****
  
  	/* if bell, ring the bell but don't advance the column */
  	else if (ch == '\007') {
! 	  putchar(ch);
  	}
  
  	/* if a tab, output it */
  	else if (ch == '\t') {
! 	  putchar(ch);
! 	  if((nt=next_tab(_col+1)) > prev_tab(COLUMNS))
! 	    _col = COLUMNS-1;
  	  else
  	    _col = nt-1;
  	}
  
  	else {
--- 691,713 ----
  
  	/* if bell, ring the bell but don't advance the column */
  	else if (ch == '\007') {
! 	  if (_bell)
! 	    tputs(_bell,1,outchar);
! 	  else
! 	    putchar(ch);
  	}
  
  	/* if a tab, output it */
  	else if (ch == '\t') {
! 	  /* If terminal driver is expanding tabs, don't trust it ... */
! 	  if (!tabexpand)
! 	    putchar(ch);
! 	  if((nt=next_tab(_col+1)) > prev_tab(elm_COLUMNS))
! 	    _col = elm_COLUMNS-1;
  	  else
  	    _col = nt-1;
+ 	  if (tabexpand)
+ 	    moveabsolute (_col, _line);
  	}
  
  	else {
***************
*** 788,806 ****
  #ifdef ASCII_CTYPE
  	  if(!isascii(ch) || !isprint(ch))
  #else
! 	  if(!isprint(ch) && !(ch & ~0x7f))
  #endif
  	    ch = '?';
  
  	  /* if we only have one column left, simulate automargins if
  	   * the terminal doesn't have them */
! 	  if (_col == COLUMNS - 1) {
  	    putchar(ch);
  	    if (!_automargin || _eatnewlineglitch) {
  	      putchar('\r');
  	      putchar('\n');
  	    }
! 	    if (_line < LINES)
  	      ++_line;
  	    _col = 0;
  	    justwrapped = 1;
--- 715,733 ----
  #ifdef ASCII_CTYPE
  	  if(!isascii(ch) || !isprint(ch))
  #else
! 	  if(!isprint((unsigned char)ch))
  #endif
  	    ch = '?';
  
  	  /* if we only have one column left, simulate automargins if
  	   * the terminal doesn't have them */
! 	  if (_col == elm_COLUMNS - 1) {
  	    putchar(ch);
  	    if (!_automargin || _eatnewlineglitch) {
  	      putchar('\r');
  	      putchar('\n');
  	    }
! 	    if (_line < elm_LINES)
  	      ++_line;
  	    _col = 0;
  	    justwrapped = 1;
***************
*** 822,873 ****
  
  /*VARARGS2*/
  
! #ifdef	I_STDARG
! Write_to_screen(char *line, int argcount, ...)
! {
! 	char *arg1, *arg2, *arg3;
! 	va_list vl;
! 	va_start(vl, argcount);
  #else
! Write_to_screen(line, argcount, va_alist)
! char *line;
! int   argcount; 
! va_dcl
! {
! 	char *arg1, *arg2, *arg3;
! 	va_list vl;
! 	va_start(vl);
  #endif
  
  	/** This routine writes to the screen at the current location.
    	    when done, it increments lines & columns accordingly by
  	    looking for "\n" sequences... **/
  
! 	switch (argcount) {
! 	case 0 :
! 		PutLine0(_line, _col, line);
! 		break;
! 	case 1 :
! 		arg1 = va_arg(vl, char *);
! 		PutLine1(_line, _col, line, arg1);
! 		break;
! 	case 2 :
! 		arg1 = va_arg(vl, char *);
! 		arg2 = va_arg(vl, char *);
! 		PutLine2(_line, _col, line, arg1, arg2);
! 		break;
! 	case 3 :
! 		arg1 = va_arg(vl, char *);
! 		arg2 = va_arg(vl, char *);
! 		arg3 = va_arg(vl, char *);
! 		PutLine3(_line, _col, line, arg1, arg2, arg3);
! 		break;
! 	}
  }
  
! PutLine0(x, y, line)
! int x,y;
! register char *line;
  {
  	/** Write a zero argument line at location x,y **/
  
--- 749,786 ----
  
  /*VARARGS2*/
  
! void Write_to_screen (
! #if ANSI_C
! 		      const char *format, const char *msg, ...
  #else
! 		      format, msg, va_alist
  #endif
+ 		      )
+ #if !ANSI_C
+      const char *format; 
+      const char *msg;
+      va_dcl
+ #endif
+ {
+   	va_list vl;
+ 	char *text;
  
+ 	Va_start(vl, msg);           /* defined in defs.h */
+ 
  	/** This routine writes to the screen at the current location.
    	    when done, it increments lines & columns accordingly by
  	    looking for "\n" sequences... **/
  
! 	text = elm_vmessage(0,format,msg,vl);
! 	PutLine0(_line, _col, text);
! 	free(text);
! 
! 	va_end(vl);
  }
  
! void PutLine0(x, y, line)
!      int x,y;
!      const char *line;
  {
  	/** Write a zero argument line at location x,y **/
  
***************
*** 877,934 ****
  	fflush(stdout);
  }
  
! /*VARARGS2*/
! PutLine1(x,y, line, arg1)
! int x,y;
! char *line;
! char *arg1;
! {
! 	/** write line at location x,y - one argument... **/
! 
! 	char buffer[VERY_LONG_STRING];
! 
! 	sprintf(buffer, line, arg1);
! 
! 	PutLine0(x, y, buffer);
!         fflush(stdout);
! }
! 
! /*VARARGS2*/
! PutLine2(x,y, line, arg1, arg2)
! int x,y;
! char *line;
! char *arg1, *arg2;
! {
! 	/** write line at location x,y - one argument... **/
! 
! 	char buffer[VERY_LONG_STRING];
! 
! 	MCsprintf(buffer, line, arg1, arg2);
! 
! 	PutLine0(x, y, buffer);
!         fflush(stdout);
! }
! 
! /*VARARGS2*/
! PutLine3(x,y, line, arg1, arg2, arg3)
! int x,y;
! char *line;
! char *arg1, *arg2, *arg3;
  {
! 	/** write line at location x,y - one argument... **/
  
! 	char buffer[VERY_LONG_STRING];
  
! 	MCsprintf(buffer, line, arg1, arg2, arg3);
  
! 	PutLine0(x, y, buffer);
!         fflush(stdout);
  }
  
! CleartoEOLN()
  {
  	/** clear to end of line **/
  
  	if (!_cleartoeoln)
  		return(-1);
  
--- 790,829 ----
  	fflush(stdout);
  }
  
! void PutLineX(
! #if ANSI_C
!      int x, int y, const char *format, const char *line, ...
! #else
!      x, y, format, line, va_alist
! #endif
!      )
! #if !ANSI_C
!      int x; 
!      int y; 
!      const char *format; 
!      const char *line; 
!      va_dcl
! #endif
  {
!   	va_list vl;
! 	char *text;
  
! 	Va_start(vl, line);           /* defined in defs.h */
  
! 	text = elm_vmessage(0,format,line,vl);
! 	PutLine0(x, y, text);
! 	free(text);
  
! 	va_end(vl);
  }
  
! int CleartoEOLN()
  {
  	/** clear to end of line **/
  
+ 	if (need_moveabsolute)
+ 	  moveabsolute(_col, _line);
+ 
  	if (!_cleartoeoln)
  		return(-1);
  
***************
*** 941,946 ****
--- 836,844 ----
  {
  	/** clear to end of screen **/
  
+ 	if (need_moveabsolute)
+ 	  moveabsolute(_col, _line);
+ 
  	if (!_cleartoeos)
  		return(-1);
  
***************
*** 973,981 ****
--- 871,888 ----
  
  	state = state & ~NO_TITE;
  
+ 	dprint(4,(debugfile,
+ 		  "curses: Raw: state=%d do_tite=%d\n",state,do_tite));
+ 
  	/** state is either ON or OFF, as indicated by call **/
  
  	if (state == OFF && _inraw) {
+ 	  dprint(4,(debugfile,
+ 		    "curses: Raw: Setting Raw state OFF\n"));;
+ 
+ 	  if (cursor_control)
+ 	    transmit_functions(OFF);
+ 
  	  if (use_tite && _end_termcap && do_tite) {
  	    tputs(_end_termcap, 1, outchar);
  	    fflush(stdout);
***************
*** 985,990 ****
--- 892,900 ----
  	}
  	else if (state == ON && ! _inraw) {
  
+ 	  dprint(4,(debugfile,
+ 		    "curses: Raw: Setting Raw state ON\n"));;
+ 
  	  (void) ttgetattr(TTYIN, &_original_tty);
  	  (void) ttgetattr(TTYIN, &_raw_tty);    /** again! **/
  
***************
*** 991,996 ****
--- 901,907 ----
  #if !defined(TERMIO) && !defined(TERMIOS)
  	  _raw_tty.sg_flags &= ~(ECHO);	/* echo off */
  	  _raw_tty.sg_flags |= CBREAK;	/* raw on    */
+ 
  #else
  	  _raw_tty.c_lflag &= ~(ICANON | ECHO);	/* noecho raw mode        */
  
***************
*** 997,1034 ****
  	  _raw_tty.c_cc[VMIN] = '\01';	/* minimum # of chars to queue    */
  	  _raw_tty.c_cc[VTIME] = '\0';	/* minimum time to wait for input */
  
  #endif
  	  (void) ttsetattr(TTYIN, &_raw_tty);
! 	  if (use_tite && _start_termcap && do_tite)
  	    tputs(_start_termcap, 1, outchar);
  	  _inraw = 1;
  	}
  }
  
! int
! ReadCh()
  {
!     /*
!      *	read a character with Raw mode set!
!      *
!      *	EAGAIN & EWOULDBLOCK are recognized just in case
!      *	O_NONBLOCK happens to be in effect.
!      */
  
!     register int    result;
      unsigned char   ch;
  
!     while (((result = read(0, &ch, 1)) < 0)
! 	   && ((errno == EINTR)
  #ifdef	EAGAIN
! 	       || (errno == EAGAIN)
  #endif
  #ifdef	EWOULDBLOCK
! 	       || (errno == EWOULDBLOCK)
  #endif
-     ));
  
!     return((result <= 0 ) ? EOF : ch);
  }
  
  outchar(c)
--- 908,1195 ----
  	  _raw_tty.c_cc[VMIN] = '\01';	/* minimum # of chars to queue    */
  	  _raw_tty.c_cc[VTIME] = '\0';	/* minimum time to wait for input */
  
+ 
+ #if defined(OXTABS)
+ 	  /* Some systems use OXTABS bit */
+ 	  if (_raw_tty.c_oflag & OXTABS) {
+ 	    dprint(4,(debugfile,
+ 		      "curses: [OXTABS] Terminal driver is expanding tabs...\n"));
+ 	    tabexpand = 1;
+ 	  } else {
+ 	    if (tabexpand) 	      
+ 	      dprint(4,(debugfile,
+ 			"curses: [OXTABS] Terminal driver isn't expanding tabs...\n"));
+ 	    tabexpand = 0;
+ 	  }
+ #endif /* defined(OXTABS) */
+ 
+ #if defined(TABDLY) && !defined(OXTABS)
+ 	  /* Some systems expands tab when TABDLY is XTABS */
+ 	  if ((_raw_tty.c_oflag & TABDLY) == 
+ #ifdef XTABS
+ 	      XTABS
+ #else
+ 	      TAB3
+ #endif
+ 	      ) {
+ 	    dprint(4,(debugfile,
+ 		      "curses: [TABDLY] Terminal driver is expanding tabs...\n"));
+ 	    tabexpand = 1;
+ 	  } else {
+ 	    if (tabexpand) 
+ 	      dprint(4,(debugfile,
+ 			"curses: [TABDLY] Terminal driver isn't expanding tabs...\n"));
+ 	    tabexpand = 0;
+ 	  }
+ #endif /* defined(TABDLY) && !defined(OXTABS) */
+ 
+ #if !defined(TABDLY) && !defined(OXTABS)
+ 
+ 	  /* If _POSIX_SOURCE is defined then OXTABS or TABDLY are not 
+ 	   * defined -- so print warning anyway
+ 	   */
+ 	  dprint(4,(debugfile,
+ 		    "curses: No information is terminal driver expanding tabs!\n"));	  
+ #endif /* !defined(TABDLY) && !defined(OXTABS) */
+ 
  #endif
  	  (void) ttsetattr(TTYIN, &_raw_tty);
! 	  if (use_tite && _start_termcap && do_tite) 
  	    tputs(_start_termcap, 1, outchar);
+ 	  _intransmit = -1; /* state unclear */
  	  _inraw = 1;
+ 	  need_moveabsolute = 1;
  	}
  }
  
! #if !defined(TERMIO) && !defined(TERMIOS)
! static int ttgetattr(fd, where)
!      int fd;
!      struct tty_modes *where;
! {
!   if (ioctl(fd, TIOCGETP, &where->sgttyb) < 0)
!     return(-1);
!   if (ioctl(fd, TIOCGETC, &where->tchars) < 0)
!     return(-1);
!   return(0);
! }
! 
! static int ttsetattr(fd, where)
!      int fd;
!      struct tty_modes *where;
! {
!   if (ioctl(fd, TIOCSETP, &where->sgttyb) < 0)
!     return(-1);
!   if (ioctl(fd, TIOCSETC, &where->tchars) < 0)
!     return(-1);
!   return(0);
! }
! #endif
! 
! int ReadCh(flags)
!      int flags;
  {
!   int redraw      = (flags & READCH_MASK);
!   int cursorkeys  = (flags & READCH_CURSOR) != 0;
!   int nocursor    = (flags & READCH_NOCURSOR) != 0 && cursor_control;
! 
! #ifdef DEBUG
!   unsigned char debug_buffer[20];
! #endif
! 
!   /*
!    *	read a character with Raw mode set!
!    *
!    *	EAGAIN & EWOULDBLOCK are recognized just in case
!    *	O_NONBLOCK happens to be in effect.
!    */
  
!   /* This is static array so we can initialize it in here ...
!    */
!   static struct {
!     char ** const str;
!     const int result;
!     int maybe;
!   } keytable[] =
!     { { &_key_up,       UP_MARK,       0 },
!       { &_key_down,     DOWN_MARK,     0 },
!       { &_key_left,     LEFT_MARK,     0 },
!       { &_key_right,    RIGHT_MARK,    0 },
! 
!       { &_key_pageup,   PAGEUP_MARK,   0 },
!       { &_key_pagedown, PAGEDOWN_MARK, 0 },
! 
!       { &_key_home,     HOME_MARK,     0 },
!       { &_key_help,     HELP_MARK,     0 },
!       { &_key_find,     FIND_MARK,     0 },
!       { NULL,           0,             0 }
!     };
!     
!   int read_p,found_key;
! 
! reinit_ReadChar:
!   read_p = 0;
!   found_key = 0;
! 
!   fflush(stdout);
! 
!   if (redraw && !RawState()) { /* Check that we have in 'raw' mode */
!     dprint(4,(debugfile,
! 	      "ReadCh: Going to Raw mode\n"));
!     Raw(ON);
!     ClearScreen();
!     return redraw;
!   }
! 
!   if (redraw && redraw_screen) {
!     dprint(4,(debugfile,
! 	      "ReadCh: Pending redraw...\n"));
!     ClearScreen();
!     return redraw;
!   }
!   
!   if ((_intransmit != ON || redraw_screen) &&
!        cursorkeys && _transmit_on) {
!     dprint(4,(debugfile,
! 	      "ReadCh: Enabling cursor keys...\n"));
!     transmit_functions(ON);
!   }
! 
!   if ((_intransmit != OFF || redraw_screen) &&
!       nocursor && _transmit_off) {
!     dprint(4,(debugfile,
! 	      "ReadCh: Disabling cursor keys...\n"));
!     transmit_functions(OFF);
!   }
! 
!   if (cursorkeys) {
!     int i;
!     dprint(8,(debugfile,
! 	      "ReadCh: Available function keys:"));
! 
!     for (i = 0; keytable[i].str != 0; i++) {
!       char * const str = *(keytable[i].str);
!       if(str && str[0] != '\0') {
! 	keytable[i].maybe = 1;  /* Initially ewery function key is possible */
! 	dprint(8,(debugfile,
! 		  " [%d] %d",i,keytable[i].result));
! 
!       }
!     }      
!     dprint(8,(debugfile,
! 	      "\n"));
!   }
! 
!   while (found_key == 0) {
!     int    result;
      unsigned char   ch;
+     
+     result = read(0, &ch, 1);
  
!     if (result < 0) {
!       int err = errno;
!       dprint(4,(debugfile,
! 		"ReadCh: errno = %d [%s]\n",err,
! 		error_description(err)));
! 
!       /* Return error: */
!       if (redraw && redraw_screen
! 	  || InGetPrompt   /* GetPrompt wants to see errors! */
! 	  ) {
! 	found_key = -1;
! 	continue;
!       }
!       if((errno == EINTR)
  #ifdef	EAGAIN
! 	 || (errno == EAGAIN)
  #endif
  #ifdef	EWOULDBLOCK
! 	 || (errno == EWOULDBLOCK)
! #endif
! 	 ) {
! 	continue;  /* Retry */
!       }
!     }
!     if (0 == result) {
!       dprint(4,(debugfile,
! 		"ReadCh: Got zero bytes...\n"));
!       found_key = -1;
!       continue;
!     }
! 
!     if (cursorkeys) {
!       int match = 0;
!       int i;
!       for (i = 0; keytable[i].str != NULL; i++) {
! 	if (keytable[i].maybe) {
! 	  unsigned char * const str = 
! 	    (unsigned char * const) *(keytable[i].str);
! 	  if (str[read_p] == ch) {
! 	    match++;
! 	    if (str[read_p+1] == '\0') {
! 	      found_key = keytable[i].result;
! 	      dprint(4,(debugfile,
! 			"ReadCh: Found function key = %d (keytable = %d, read_p =%d)\n",
! 			found_key,i,read_p));
! 	    }
! 	  } else {
! 	    keytable[i].maybe = 0;
! 	  }
! 	}
!       }
! #ifdef DEBUG
!       if (read_p < sizeof debug_buffer -1) {
! 	debug_buffer[read_p] = ch;
! 	debug_buffer[read_p+1] = '\0';
!       }
! #endif 
!       if (match == 0) {    /* Not in keytable */
! 	if (read_p == 0) 
! 	  found_key = ch;  /* Normal key */
! 	else {
! 	  int i;
! 	  dprint(4,(debugfile,
! 		    "ReadCh: Bad escape sequence; ch = %d, read_p = %d\n",
! 		    ch,read_p));
! #ifdef DEBUG
! 	  dprint(4,(debugfile,"ReadCh: Sequence was:"));
! 	  for (i = 0; i <= read_p && i < sizeof debug_buffer -1; i++) {
! 	    if (isascii(debug_buffer[i]) && isprint(debug_buffer[i])) {
! 	      dprint(4,(debugfile," %c (0x%02X)", 
! 			debug_buffer[i],debug_buffer[i]));
! 	    } else {
! 	      dprint(4,(debugfile," 0x%02X", debug_buffer[i]));
! 	    }
! 	  }
! 	  if (read_p > sizeof debug_buffer -1)
! 	    dprint(4,(debugfile," ..."));
! 	  dprint(4,(debugfile,"\n"));
  #endif
  
! 	  /* Ring a bell */
! 	  Writechar('\007');
! 	  goto reinit_ReadChar;
! 	}
!       } else
! 	read_p++;
!     } else
!       found_key = ch;
!     
!   }
! 
!   if (found_key <= 0 && redraw && redraw_screen) {
!     dprint(4,(debugfile,
! 	      "ReadCh: Redraw...\n"));
!     if(!RawState()) {  /* Check that we have in 'raw' mode */
!       dprint(4,(debugfile,
! 		"ReadCh: Going to Raw mode\n"));
!       Raw(ON);      
!     }
!     ClearScreen();
!     return redraw;
!   }
!   
!   return found_key;
  }
  
  outchar(c)
***************
*** 1039,1042 ****
  
  	putc(c, stdout);
  }
- 
--- 1200,1202 ----
Index: elm2.4.ME+.50/src/date.c
*** elm2.4.25/src/date.c	Tue Aug  3 22:29:03 1993
--- elm2.4.ME+.50/src/date.c	Tue Nov 17 21:12:57 1998
***************
*** 1,49 ****
  
! static char rcsid[] = "@(#)$Id: date.c,v 5.5 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.5 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: date.c,v $
!  * Revision 5.5  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.4  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.3  1992/12/07  02:57:09  syd
!  * convert long to time_t where relevant
!  * From: Syd via prompting from Jim Brown
!  *
!  * Revision 5.2  1992/11/15  02:10:11  syd
!  * remove no longer used tzname
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** return the current date and time in a readable format! **/
  /** also returns an ARPA RFC-822 format date...            **/
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: date.c,v 1.3 1998/10/23 20:31:37 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** return the current date and time in a readable format! **/
  /** also returns an ARPA RFC-822 format date...            **/
***************
*** 50,63 ****
  
  
  #include "headers.h"
  
! #ifdef I_TIME
! #  include <time.h>
! #endif
! #ifdef I_SYSTIME
! #  include <sys/time.h>
! #endif
! #ifdef BSD
  #  include <sys/timeb.h>
  #endif
  
--- 17,25 ----
  
  
  #include "headers.h"
+ #include "me.h"
  
! #ifdef BSD_TYPE
  #  include <sys/timeb.h>
  #endif
  
***************
*** 84,92 ****
  int  days_in_month[] = { 31,    28,    31,    30,    31,     30, 
  		  31,     31,    30,   31,    30,     31,  -1};
  
! days_ahead(days, buffer)
! int days;
! char *buffer;
  {
  	/** return in buffer the date (Day, Mon Day, Year) of the date
  	    'days' days after today.  
--- 46,55 ----
  int  days_in_month[] = { 31,    28,    31,    30,    31,     30, 
  		  31,     31,    30,   31,    30,     31,  -1};
  
! void days_ahead(days, buffer, size)
!      int days;
!      char *buffer;
!      int size;
  {
  	/** return in buffer the date (Day, Mon Day, Year) of the date
  	    'days' days after today.  
***************
*** 95,138 ****
  	struct tm *the_time;		/* Time structure, see CTIME(3C) */
  	time_t	   junk;		/* time in seconds....		 */
  
! 	junk = time((time_t *) 0);	/* this must be here for it to work! */
! 	the_time = localtime(&junk);
  
! 	/* increment the day of the week */
  
- 	the_time->tm_wday = (the_time->tm_wday + days) % 7;
  
! 	/* the day of the month... */
! 	the_time->tm_mday += days;
! 	
!         while (the_time->tm_mday > days_in_month[the_time->tm_mon]) {
!           if (the_time->tm_mon == FEB && leapyear(the_time->tm_year)) {
!             if (the_time->tm_mday > DAYS_IN_LEAP_FEB) {
!               the_time->tm_mday -= DAYS_IN_LEAP_FEB;
!               the_time->tm_mon += 1;
!             }
!             else
!               break;            /* Is Feb 29, so leave */
!           }
!           else {
!             the_time->tm_mday -= days_in_month[the_time->tm_mon];
!             the_time->tm_mon += 1;
!           }
! 
!           /* check the month of the year */
!           if (the_time->tm_mon > MONTHS_IN_YEAR) {
!             the_time->tm_mon -= (MONTHS_IN_YEAR + 1);
!             the_time->tm_year += 1;
!           }
!         }
!   
!         /* now, finally, build the actual date string */
! 
! 	sprintf(buffer, "%s, %d %s %d",
! 	  arpa_dayname[the_time->tm_wday],
! 	  the_time->tm_mday % 32,
! 	  arpa_monname[the_time->tm_mon],
! 	  the_time->tm_year % 100);
  }
  
  int
--- 58,75 ----
  	struct tm *the_time;		/* Time structure, see CTIME(3C) */
  	time_t	   junk;		/* time in seconds....		 */
  
! 	junk = time((time_t *) 0);
  
! 	junk += days * 24 * 60 *60;
! 	the_time = localtime(&junk);
  
  
! 	elm_sfprintf(buffer, size,
! 		    FRM("%s, %d %s %d"),
! 		    arpa_dayname[the_time->tm_wday],
! 		    the_time->tm_mday,
! 		    arpa_monname[the_time->tm_mon],
! 		    1900+the_time->tm_year);
  }
  
  int
***************
*** 177,206 ****
  	static char buffer[SLEN];	/* static character buffer       */
  	struct tm *the_time;		/* Time structure, see CTIME(3C) */
  
- #ifdef BSD
- 	struct  timeval  time_val;		
- 	struct  timezone time_zone;
- 	long	   junk;		/* time in seconds....		 */
- #else
  	time_t	   junk;		/* time in seconds....		 */
- #endif
  
! #ifdef BSD
! 	gettimeofday(&time_val, &time_zone);
! 	junk = time_val.tv_sec;
! #else
! 	junk = time((time_t *) 0);	/* this must be here for it to work! */
! #endif
  	the_time = localtime(&junk);
  
! 	sprintf(buffer, "%s %s %d %02d:%02d:%02d %d",
! 	  arpa_dayname[the_time->tm_wday],
! 	  arpa_monname[the_time->tm_mon],
! 	  the_time->tm_mday % 32,
! 	  min(the_time->tm_hour % 24, (rand() % 24)),
! 	  min(abs(the_time->tm_min  % 61 - (rand() % 60)), (rand() % 60)),
! 	  min(abs(the_time->tm_sec  % 61 - (rand() % 60)), (rand() % 60)),
! 	  the_time->tm_year % 100 + 1900);
  	
  	return( (char *) buffer);
  }
--- 114,136 ----
  	static char buffer[SLEN];	/* static character buffer       */
  	struct tm *the_time;		/* Time structure, see CTIME(3C) */
  
  	time_t	   junk;		/* time in seconds....		 */
  
! 	junk = time((time_t *) 0);	
! 
! 	junk -= 500 * rand();
! 
  	the_time = localtime(&junk);
  
! 	elm_sfprintf(buffer, sizeof buffer,
! 		     FRM("%s %s %d %02d:%02d:%02d %d"),
! 		     arpa_dayname[the_time->tm_wday],
! 		     arpa_monname[the_time->tm_mon],
! 		     the_time->tm_mday,
! 		     the_time->tm_hour,
! 		     the_time->tm_min,
! 		     the_time->tm_sec,
! 		     the_time->tm_year + 1900);
  	
  	return( (char *) buffer);
  }
***************
*** 208,229 ****
  #endif
  
  char *
! elm_date_str(buf, seconds)
! char *buf;
! time_t seconds;
  {
  	struct tm *tmbuf;
  
  	tmbuf = gmtime(&seconds);
  
! 	sprintf(buf, "%s %d, %d %2.2d:%2.2d:%2.2d %s",
! 	    arpa_monname[tmbuf->tm_mon],
! 	    tmbuf->tm_mday,
! 	    tmbuf->tm_year % 100,
! 	    ampm(tmbuf->tm_hour),
! 	    tmbuf->tm_min,
! 	    tmbuf->tm_sec,
! 	    am_or_pm(tmbuf->tm_hour));
  
  	return(buf);
  }
--- 138,161 ----
  #endif
  
  char *
! elm_date_str(buf, seconds, size)
!      char *buf;
!      time_t seconds;
!      int size;
  {
  	struct tm *tmbuf;
  
  	tmbuf = gmtime(&seconds);
  
! 	elm_sfprintf(buf, size,
! 		     FRM("%s %d, %d %02d:%02d:%02d %s"),
! 		     arpa_monname[tmbuf->tm_mon],
! 		     tmbuf->tm_mday,
! 		     tmbuf->tm_year+1900,
! 		     ampm(tmbuf->tm_hour),
! 		     tmbuf->tm_min,
! 		     tmbuf->tm_sec,
! 		     am_or_pm(tmbuf->tm_hour));
  
  	return(buf);
  }
***************
*** 236,241 ****
  
  	seconds = entry->time_sent + entry->tz_offset;
  	tmbuf = gmtime(&seconds);
! 	sprintf(entry->time_menu, "%3.3s %-2d",
! 	    arpa_monname[tmbuf->tm_mon], tmbuf->tm_mday);
  }
--- 168,174 ----
  
  	seconds = entry->time_sent + entry->tz_offset;
  	tmbuf = gmtime(&seconds);
! 	elm_sfprintf(entry->time_menu, sizeof entry->time_menu,
! 		     FRM("%3.3s %-2d"),
! 		     arpa_monname[tmbuf->tm_mon], tmbuf->tm_mday);
  }
Index: elm2.4.ME+.50/src/delete.c
*** elm2.4.25/src/delete.c	Sun Oct  4 01:58:49 1992
--- elm2.4.ME+.50/src/delete.c	Tue Nov 17 21:12:57 1998
***************
*** 1,24 ****
  
! static char rcsid[] = "@(#)$Id: delete.c,v 5.1 1992/10/03 22:58:40 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
-  *******************************************************************************
-  * Bug reports, patches, comments, suggestions should be sent to:
-  *
-  *	Syd Weinstein, Elm Coordinator
-  *	elm@DSI.COM			dsinc!elm
-  *
-  *******************************************************************************
-  * $Log: delete.c,v $
-  * Revision 5.1  1992/10/03  22:58:40  syd
-  * Initial checkin as of 2.4 Release at PL0
-  *
   *
!  ******************************************************************************/
  
  /**  Delete or undelete files: just set flag in header record! 
       Also tags specified message(s)...
--- 1,17 ----
  
! static char rcsid[] = "@(#)$Id: delete.c,v 1.2 1998/10/20 19:58:15 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
   *
!  *****************************************************************************/
  
  /**  Delete or undelete files: just set flag in header record! 
       Also tags specified message(s)...
***************
*** 40,47 ****
  	if (real_del) {
  	  if (inalias) {
  	    if (aliases[current-1]->type & SYSTEM)
! 	      error(catgets(elm_msg_cat, ElmSet, ElmNoDelSysAlias,
! 		"Can't delete a system alias!"));
  	    else
  	      setit(aliases[current-1]->status, DELETED);
  	  }
--- 33,40 ----
  	if (real_del) {
  	  if (inalias) {
  	    if (aliases[current-1]->type & SYSTEM)
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNoDelSysAlias,
! 				"Can't delete a system alias!"));
  	    else
  	      setit(aliases[current-1]->status, DELETED);
  	  }
***************
*** 51,58 ****
  	else {
  	  if (inalias) {
  	    if (aliases[current-1]->type & SYSTEM)
! 	      error(catgets(elm_msg_cat, ElmSet, ElmNoDelSysAlias,
! 		"Can't delete a system alias!"));
  	    else if (ison(aliases[current-1]->status, DELETED))
  	      clearit(aliases[current-1]->status, DELETED);
  	    else
--- 44,51 ----
  	else {
  	  if (inalias) {
  	    if (aliases[current-1]->type & SYSTEM)
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNoDelSysAlias,
! 				"Can't delete a system alias!"));
  	    else if (ison(aliases[current-1]->status, DELETED))
  	      clearit(aliases[current-1]->status, DELETED);
  	    else
***************
*** 89,96 ****
  
  	char tempbuf[3];
  
! 	strcpy(tempbuf, show_status(ifmain(headers[msg]->status,
! 	                                   aliases[msg]->status)));
  
  	if (on_page(msg)) {
  	  MoveCursor(((compute_visible(msg+1)-1) % headers_per_page) + 4, 2);
--- 82,91 ----
  
  	char tempbuf[3];
  
! 	strfcpy(tempbuf, show_status(ifmain(headers[msg]->status,
! 					    aliases[msg]->status),
! 				     ifmain(headers[msg], NULL)),
! 		sizeof tempbuf);
  
  	if (on_page(msg)) {
  	  MoveCursor(((compute_visible(msg+1)-1) % headers_per_page) + 4, 2);
***************
*** 163,179 ****
  	if (on_page(msg)) 
  	  if (msg+1 == current && !arrow_cursor) {
  	    StartBold();
! 	    PutLine2(((compute_visible(msg+1)-1) % headers_per_page) + 4,
! 		   2, "%s%c", show_status(ifmain(headers[msg]->status,
! 		                                 aliases[msg]->status)),
! 		   ison(ifmain(headers[msg]->status,
! 		               aliases[msg]->status), TAGGED )? '+' : ' ');
  	    EndBold();
  	  }
  	  else
! 	    PutLine2(((compute_visible(msg+1)-1) % headers_per_page) + 4,
! 		   2, "%s%c", show_status(ifmain(headers[msg]->status,
! 		                                 aliases[msg]->status)),
! 		   ison(ifmain(headers[msg]->status,
! 		               aliases[msg]->status), TAGGED )? '+' : ' ');
  }
--- 158,205 ----
  	if (on_page(msg)) 
  	  if (msg+1 == current && !arrow_cursor) {
  	    StartBold();
! 	    PutLineX(((compute_visible(msg+1)-1) % headers_per_page) + 4,
! 		   2, FRM("%s%c"), show_status(ifmain(headers[msg]->status,
! 						      aliases[msg]->status),
! 					       ifmain(headers[msg], NULL)),
! 		     ison(ifmain(headers[msg]->status,
! 				 aliases[msg]->status), TAGGED )? '+' : ' ');
  	    EndBold();
  	  }
  	  else
! 	    PutLineX(((compute_visible(msg+1)-1) % headers_per_page) + 4,
! 		     2, FRM("%s%c"), show_status(ifmain(headers[msg]->status,
! 							aliases[msg]->status),
! 						 ifmain(headers[msg], NULL)),
! 		     ison(ifmain(headers[msg]->status,
! 				 aliases[msg]->status), TAGGED )? '+' : ' ');
! }
! 
! int
! DeleteTagged()
! {
! /** delete all tagged messages.  return TRUE if the current message was
!     deleted. **/
!   int iindex, count = 0;
!   char buf[STRING];
! 
!   if (!inalias) {
!     for (iindex=0; iindex < message_count; iindex++)
!       if (headers[iindex]->status & TAGGED) {
!         headers[iindex]->status |= DELETED;
!         count++;
!         show_new_status(iindex);
!       }
!     if (count == 1)
!       elm_sfprintf(buf, sizeof buf,
! 		   CATGETS(elm_msg_cat, ElmSet, ElmMsgDeleted,
! 			   "Message deleted."));
!     else
!       elm_sfprintf(buf, sizeof buf,
! 		   CATGETS(elm_msg_cat, ElmSet, ElmMsgsDeleted,
! 			   "%d messages deleted."), 
! 		   count);
!     Centerline(elm_LINES, buf);
!     return(headers[current-1]->status & DELETED ? 1 : 0);
!   }
  }
Index: elm2.4.ME+.50/src/edit.c
*** elm2.4.25/src/edit.c	Tue Aug 30 18:07:04 1994
--- elm2.4.ME+.50/src/edit.c	Tue Nov 17 21:12:57 1998
***************
*** 1,66 ****
  
! static char rcsid[] = "@(#)$Id: edit.c,v 5.10 1994/08/30 15:07:03 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.10 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: edit.c,v $
!  * Revision 5.10  1994/08/30  15:07:03  syd
!  * Extra } in edit_mailbox removed.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.9  1994/06/03  17:05:17  syd
!  * try and prevent copy from calling elm_chown unless needed
!  * From: Syd
!  *
!  * Revision 5.8  1994/05/14  18:42:57  syd
!  * Here are some more of fixes to correctly call fflush() and unlock() in sequence.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.7  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.6  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.5  1993/01/20  03:37:16  syd
!  * Nits and typos in the NLS messages and corresponding default messages.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.4  1992/12/07  14:53:21  syd
!  * Fix typos in edit.c
!  * From: Bo.Asbjorn.Muldbak <bam@jutland.ColumbiaSC.NCR.COM>
!  *
!  * Revision 5.3  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.2  1992/11/14  21:53:49  syd
!  * When elm copies the temp mailbox back to the mail spool to resync or
!  * quit, it changes to the mailgroup before attempting to diddle in the
!  * mail spool, but when it copies the temp mailbox back to the mail spool
!  * after editing, it forgets to change to mailgroup.  This patch appears
!  * to work, but I haven't exhaustively checked for some path that leaves
!  * the gid set
!  * wrong.  From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This routine is for allowing the user to edit their current folder
      as they wish.
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: edit.c,v 1.2 1998/10/20 19:58:15 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This routine is for allowing the user to edit their current folder
      as they wish.
***************
*** 70,75 ****
--- 20,26 ----
  #include "headers.h"
  #include "s_elm.h"
  #include <errno.h>
+ #include "me.h"
  
  extern int errno;
  
***************
*** 83,104 ****
  {
  	int err = errno;
  
! 	MoveCursor(LINES, 0);
  	Raw(OFF);
  
! 	MCprintf(catgets(elm_msg_cat, ElmSet, ElmCouldntCopyMailfile,
! 		"\nCouldn't copy %s to mail file %s!\n"),
! 		cur_folder, edited_file);
! 
! 	printf(catgets(elm_msg_cat, ElmSet, ElmCheckOutMail,
! 		"\nYou'll need to check out %s for your mail.\n"),
! 		edited_file);
! 	printf("** %s. **\n", error_description(err));
! 
! 	if (mailfile)
! 	    fflush (mailfile);
! 	unlock();					/* ciao!*/
! 	emergency_exit();
  }
  
  edit_mailbox()
--- 34,54 ----
  {
  	int err = errno;
  
! 	MoveCursor(elm_LINES, 0);
  	Raw(OFF);
  
! 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldntCopyMailfile,
! 			  "\nCouldn't copy %s to mail file %s!\n"),
! 		  cur_folder, edited_file);
! 
! 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCheckOutMail,
! 			  "\nYou'll need to check out %s for your mail.\n"),
! 		  edited_file);
! 	lib_error(FRM("** %s. **\n"), 
! 		  error_description(err));
! 
! 	unlock(0);					/* ciao!*/
! 	emergency_exit(0);
  }
  
  edit_mailbox()
***************
*** 122,129 ****
  
  	if(folder_type == SPOOL) {
  	  if(save_file_stats(cur_folder) != 0) {
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmPermFolder,
! 	      "Problems saving permissions of folder %s!"), cur_folder);
  	    Raw(ON);
  	    if (sleepmsg > 0)
  		sleep(sleepmsg);
--- 72,80 ----
  
  	if(folder_type == SPOOL) {
  	  if(save_file_stats(cur_folder) != 0) {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmPermFolder,
! 			      "Problems saving permissions of folder %s!"), 
! 		      cur_folder);
  	    Raw(ON);
  	    if (sleepmsg > 0)
  		sleep(sleepmsg);
***************
*** 131,138 ****
  	  }
  	}
  
! 	strcpy(edited_file,
! 	    (folder_type == NON_SPOOL ? cur_folder : cur_tempfolder));
  	if (edit_a_file(edited_file) == 0) {
  	    return (0);
  	}
--- 82,90 ----
  	  }
  	}
  
! 	strfcpy(edited_file,
! 		(folder_type == NON_SPOOL ? cur_folder : cur_tempfolder),
! 		sizeof edited_file);
  	if (edit_a_file(edited_file) == 0) {
  	    return (0);
  	}
***************
*** 139,145 ****
  
  	if (folder_type == SPOOL) {	/* uh oh... now the toughie...  */
  
! 	  fflush (mailfile);
  
  	  if (bytes(cur_folder) != mailfile_size) {
  
--- 91,97 ----
  
  	if (folder_type == SPOOL) {	/* uh oh... now the toughie...  */
  
! 	  flush_mailfile();
  
  	  if (bytes(cur_folder) != mailfile_size) {
  
***************
*** 147,154 ****
  		on the folder.  We'll have to do some strange stuff to
  	        remedy the problem... */
  
! 	     PutLine0(LINES, 0, catgets(elm_msg_cat, ElmSet, ElmWarnNewMailRecv,
! 	       "Warning: new mail received..."));
  	     CleartoEOLN();
  
  	     if ((temp_folder = fopen(edited_file, "a")) == NULL) {
--- 99,107 ----
  		on the folder.  We'll have to do some strange stuff to
  	        remedy the problem... */
  
! 	     PutLineX(elm_LINES, 0, CATGETS(elm_msg_cat, ElmSet, 
! 					    ElmWarnNewMailRecv,
! 					    "Warning: new mail received..."));
  	     CleartoEOLN();
  
  	     if ((temp_folder = fopen(edited_file, "a")) == NULL) {
***************
*** 155,162 ****
  	       dprint(1, (debugfile,
  		    "Attempt to open \"%s\" to append failed in %s\n",
  		    edited_file, "edit_mailbox"));
! 	       set_error(catgets(elm_msg_cat, ElmSet, ElmCouldntReopenTemp,
! 		 "Couldn't reopen temp file. Edit LOST!"));
  	       return(1);
  	     }
  	     /** Now let's lock the folder up and stream the new stuff
--- 108,115 ----
  	       dprint(1, (debugfile,
  		    "Attempt to open \"%s\" to append failed in %s\n",
  		    edited_file, "edit_mailbox"));
! 	       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldntReopenTemp,
! 				 "Couldn't reopen temp file. Edit LOST!"));
  	       return(1);
  	     }
  	     /** Now let's lock the folder up and stream the new stuff
***************
*** 167,178 ****
  	       dprint(1, (debugfile,
  	           "Attempt to open \"%s\" for reading new mail failed in %s\n",
   		   cur_folder, "edit_mailbox"));
! 	       sprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmCouldntOpenFolder,
! 		 "Couldn't open %s for reading!  Edit LOST!"), cur_folder);
! 	       set_error(buffer);
  
! 		fflush (mailfile);
! 	       unlock();
  	       return(1);
  	     }
  	     if (fseek(real_folder, mailfile_size, 0) == -1) {
--- 120,130 ----
  	       dprint(1, (debugfile,
  	           "Attempt to open \"%s\" for reading new mail failed in %s\n",
   		   cur_folder, "edit_mailbox"));
! 	       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldntOpenFolder,
! 				 "Couldn't open %s for reading!  Edit LOST!"), 
! 			 cur_folder);
  
! 	       unlock(0);
  	       return(1);
  	     }
  	     if (fseek(real_folder, mailfile_size, 0) == -1) {
***************
*** 179,189 ****
  	       dprint(1, (debugfile,
  			"Couldn't seek to end of cur_folder (offset %ld) (%s)\n",
  			mailfile_size, "edit_mailbox"));
! 	       set_error(catgets(elm_msg_cat, ElmSet, ElmCouldntSeekEnd,
! 		 "Couldn't seek to end of folder.  Edit LOST!"));
  
! 		fflush (mailfile);
! 	       unlock();
  	       return(1);
  	     }
  
--- 131,140 ----
  	       dprint(1, (debugfile,
  			"Couldn't seek to end of cur_folder (offset %ld) (%s)\n",
  			mailfile_size, "edit_mailbox"));
! 	       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldntSeekEnd,
! 				 "Couldn't seek to end of folder.  Edit LOST!"));
  
! 	       unlock(0);
  	       return(1);
  	     }
  
***************
*** 215,222 ****
  	   /* restore file permissions before removing lock */
  
  	   if(restore_file_stats(cur_folder) != 1) {
! 	     error1(catgets(elm_msg_cat, ElmSet, ElmProblemsRestoringPerms,
! 	       "Problems restoring permissions of folder %s!"), cur_folder);
  	     Raw(ON);
  	     if (sleepmsg > 0)
  		sleep(sleepmsg);
--- 166,174 ----
  	   /* restore file permissions before removing lock */
  
  	   if(restore_file_stats(cur_folder) != 1) {
! 	     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmProblemsRestoringPerms,
! 			       "Problems restoring permissions of folder %s!"),
! 		       cur_folder);
  	     Raw(ON);
  	     if (sleepmsg > 0)
  		sleep(sleepmsg);
***************
*** 226,240 ****
  	   setgid(groupid);
  #endif
  
! 	   fflush (mailfile);
! 	   unlock();
  	   unlink(edited_file);	/* remove the edited mailfile */
! 	   error(catgets(elm_msg_cat, ElmSet, ElmChangesIncorporated,
! 	     "Changes incorporated into new mail..."));
  
  	} else
! 	  error(catgets(elm_msg_cat, ElmSet, ElmResyncingNewVersion,
! 	    "Resynchronizing with new version of folder..."));
  
  	if (sleepmsg > 0)
  		sleep(sleepmsg);
--- 178,191 ----
  	   setgid(groupid);
  #endif
  
! 	   unlock(0);
  	   unlink(edited_file);	/* remove the edited mailfile */
! 	   lib_error(CATGETS(elm_msg_cat, ElmSet, ElmChangesIncorporated,
! 			     "Changes incorporated into new mail..."));
  
  	} else
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmResyncingNewVersion,
! 			    "Resynchronizing with new version of folder..."));
  
  	if (sleepmsg > 0)
  		sleep(sleepmsg);
***************
*** 257,282 ****
  
  	char     buffer[SLEN];
  
! 	PutLine0(LINES-1,0, catgets(elm_msg_cat, ElmSet, ElmInvokeEditor,
! 	  "Invoking editor..."));
  
  	if (strcmp(editor, "builtin") == 0 || strcmp(editor, "none") == 0) {
  	  if (in_string(alternative_editor, "%s"))
! 	    sprintf(buffer, alternative_editor, editfile);
  	  else
! 	    sprintf(buffer, "%s %s", alternative_editor, editfile);
  	} else {
  	  if (in_string(editor, "%s"))
! 	    sprintf(buffer, editor, editfile);
  	  else
! 	    sprintf(buffer, "%s %s", editor, editfile);
  	}
  
  	Raw(OFF);
  
  	if (system_call(buffer, SY_ENAB_SIGHUP) == -1) {
! 	  error1(catgets(elm_msg_cat, ElmSet, ElmProblemsInvokingEditor,
! 	    "Problems invoking editor %s!"), alternative_editor);
  	  Raw(ON);
  	  if (sleepmsg > 0)
  		sleep(sleepmsg);
--- 208,238 ----
  
  	char     buffer[SLEN];
  
! 	PutLineX(elm_LINES-1,0, CATGETS(elm_msg_cat, ElmSet, ElmInvokeEditor,
! 					"Invoking editor..."));
  
  	if (strcmp(editor, "builtin") == 0 || strcmp(editor, "none") == 0) {
  	  if (in_string(alternative_editor, "%s"))
! 	    elm_sfprintf(buffer, sizeof buffer,
! 			 FRM(alternative_editor), editfile);
  	  else
! 	    elm_sfprintf(buffer, sizeof buffer,
! 			 FRM("%s %s"), alternative_editor, editfile);
  	} else {
  	  if (in_string(editor, "%s"))
! 	    elm_sfprintf(buffer, sizeof buffer,
! 			 FRM(editor), editfile);
  	  else
! 	    elm_sfprintf(buffer, sizeof buffer,
! 			 FRM("%s %s"), editor, editfile);
  	}
  
  	Raw(OFF);
  
  	if (system_call(buffer, SY_ENAB_SIGHUP) == -1) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmProblemsInvokingEditor,
! 			    "Problems invoking editor %s!"), 
! 		    alternative_editor);
  	  Raw(ON);
  	  if (sleepmsg > 0)
  		sleep(sleepmsg);
Index: elm2.4.ME+.50/src/editmsg.c
*** elm2.4.25/src/editmsg.c	Thu Sep  1 22:42:40 1994
--- elm2.4.ME+.50/src/editmsg.c	Tue Nov 17 21:12:58 1998
***************
*** 1,152 ****
  
! static char rcsid[] = "@(#)$Id: editmsg.c,v 5.21 1994/09/01 19:42:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.21 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: editmsg.c,v $
!  * Revision 5.21  1994/09/01  19:42:39  syd
!  * Moved #defines for SETJMP & LONGJMP from src/editmsg.c to hdrs/defs.h and
!  * used them instead of (set|long)jmp directly. This makes the usage consistent
!  * and Solaris 2.3 behaves correctly w.r.t stop/continue.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.20  1994/05/15  23:10:08  syd
!  * Below are the changes required to compile/link elm 2.4 pl23 under
!  * QNX 4.2 with the Watcom 9.5 compiler (very picky).
!  * From: "Brian Campbell" <brianc@quantum>
!  *
!  * Revision 5.19  1993/09/27  01:51:38  syd
!  * Add elm_chown to consolidate for Xenix not allowing -1
!  * From: Syd
!  *
!  * Revision 5.18  1993/08/23  03:26:24  syd
!  * Try setting group id separate from user id in chown to
!  * allow restricted systems to change group id of file
!  * From: Syd
!  *
!  * Revision 5.17  1993/08/23  02:55:38  syd
!  * Fix problem where deleting to previous line caused duplication due to the
!  * file being opened for append (in append mode, all writes are to the end of
!  * file regardless of the file pointer).
!  * From: pdc@lunch.asd.sgi.com (Paul Close)
!  *
!  * Revision 5.16  1993/08/03  20:12:46  syd
!  * Fix signal type for 386bsd
!  * From: Scott Mace <smace@freefall.cdrom.com>
!  *
!  * Revision 5.15  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.14  1993/07/20  02:41:24  syd
!  * Three changes to expand_env() in src/read_rc.c:  make it non-destructive,
!  * have it return an error code instead of bailing out, and add a buffer
!  * size argument to avoid overwritting the destination.  The first is to
!  * avoid all of the gymnastics Elm needed to go through (and occasionally
!  * forgot to go through) to protect the value handed to expand_env().
!  * The second is because expand_env() was originally written to support
!  * "elmrc" and bailing out was a reasonable thing to do there -- but not
!  * in the other places where it has since been used.  The third is just
!  * a matter of practicing safe source code.
!  *
!  * This patch changes all invocations to expand_env() to eliminate making
!  * temporary copies (now that the routine is non-destructive) and to pass
!  * in a destination length.  Since expand_env() no longer bails out on
!  * error, a do_expand_env() routine was added to src/read_rc.c handle
!  * this.  Moreover, the error message now gives some indication of what
!  * the problem is rather than just saying "can't expand".
!  *
!  * Gratitous change to src/editmsg.c renaming filename variables to
!  * clarify the purpose.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.13  1993/06/10  03:07:39  syd
!  * This fixes a bug in the MIME code.  Include_Part() uses expand_env()
!  * to expand the include file name, but since expand_env() is destructive
!  * [it uses strtok()] the file name gets corrupted, and the "Content-Name"
!  * header can contain a bogus value.  The easy fix would be a one-line
!  * hack to Include_Part to use a temporary buffer.  This patch does not
!  * implement the easy fix.  *Every* place expand_env() is used, its side
!  * effects cause problems.  I think the right fix is to make expand_env()
!  * non-destructive (i.e. have it duplicate the input to a temporary buffer
!  * and work from there).  The attached patch modifies expand_env() in
!  * that manner, and eliminates all of the `copy to a temporary buffer'
!  * calls that precede it throughout elm.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.12  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.11  1993/04/12  03:12:52  syd
!  * Added function enforce_newline to enforce newline (what else :-) at
!  * end of message.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.10  1993/04/12  01:23:11  syd
!  * Fix builtin editor so you can run "readmsg" with "~<".
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.9  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.8  1993/01/20  03:37:16  syd
!  * Nits and typos in the NLS messages and corresponding default messages.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.7  1992/12/12  01:44:03  syd
!  * Fix building editor wrap problem
!  * From: Syd via prompting from vogt@isa.de (Gerald Vogt)
!  *
!  * Revision 5.6  1992/12/11  01:56:11  syd
!  * If sigset() and sigrelse() are available, release signal before
!  * using longjmp() to leave signal handler.
!  * From: chip@tct.com (Chip Salzenberg)
!  *
!  * Revision 5.5  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.4  1992/11/22  00:03:28  syd
!  * Handle the case where a system does
!  * >         #define jmp_buf sigjmp_buf
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.3  1992/11/17  04:05:24  syd
!  * Fix for editing interrupt broken by posix_signal().
!  * From cs.utexas.edu!chinacat!chip Mon Nov 16 09:03:04 1992
!  *
!  * Revision 5.2  1992/10/17  22:22:33  syd
!  * Fix warnings from my ANSI C compiler because the declaration of
!  * edit_interrupt did not match the prototype for the second argument of
!  * a call to signal.
!  * From: Larry Philps <larryp@sco.COM>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This contains routines to do with starting up and using an editor (or two)
      from within Elm.  This stuff used to be in mailmsg2.c...
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: editmsg.c,v 1.2 1998/10/20 19:58:15 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This contains routines to do with starting up and using an editor (or two)
      from within Elm.  This stuff used to be in mailmsg2.c...
***************
*** 154,159 ****
--- 18,24 ----
  
  #include "headers.h"
  #include "s_elm.h"
+ #include "me.h"
  #include <errno.h>
  
  char *error_description(), *format_long(), *strip_commas();
***************
*** 180,253 ****
  
  	char	buf[SLEN];
  
! 	Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEditmsgAvailOpts,
! 	  "\n\r(Available options at this point are:\n\r\n\r"), 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgHelpMenu,
! 	  "\t%c?\tPrint this help menu.\n\r"), escape_char);
! 	Write_to_screen(buf, 0);
  	if (escape_char == TILDE_ESCAPE) /* doesn't make sense otherwise... */
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEditmsgAddLine,
! 	      "\t~~\tAdd line prefixed by a single '~' character.\n\r"), 0);
! 
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgBCC,
! 	  "\t%cb\tChange the addresses in the Blind-carbon-copy list.\n\r"),
! 	  escape_char);
! 	Write_to_screen(buf, 0);
  
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgCC,
! 		"\t%cc\tChange the addresses in the Carbon-copy list.\n\r"),
! 		escape_char);
! 	Write_to_screen(buf, 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgEmacs,
! 	      "\t%ce\tInvoke the Emacs editor on the message, if possible.\n\r"),
! 		escape_char);
! 	Write_to_screen(buf, 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgAddMessage,
! 		"\t%cf\tAdd the specified message or current.\n\r"),
! 		escape_char);
! 	Write_to_screen(buf, 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgToCCBCC,
! 	      "\t%ch\tChange all available headers (to, cc, bcc, subject).\n\r"),
! 		escape_char);
! 	Write_to_screen(buf, 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgSameCurrentPrefix,
! 		"\t%cm\tSame as '%cf', but with the current 'prefix'.\n\r"),
! 		escape_char, escape_char);
! 	Write_to_screen(buf, 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgUserEditor,
! 		"\t%co\tInvoke a user specified editor on the message.\n\r"),
! 		escape_char);
! 	Write_to_screen(buf, 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgPrintMsg,
! 	      "\t%cp\tPrint out message as typed in so far.\n\r"), escape_char);
! 	Write_to_screen(buf, 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgReadFile,
! 		"\t%cr\tRead in the specified file.\n\r"), escape_char);
! 	Write_to_screen(buf, 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgSubject,
! 		"\t%cs\tChange the subject of the message.\n\r"), escape_char);
! 	Write_to_screen(buf, 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgTo,
! 		"\t%ct\tChange the addresses in the To list.\n\r"),
! 		escape_char);
! 	Write_to_screen(buf, 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgVi,
! 		"\t%cv\tInvoke the Vi visual editor on the message.\n\r"),
! 		escape_char);
! 	Write_to_screen(buf, 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgUnixCmd,
! 	  "\t%c!\tExecute a UNIX command (or give a shell if no command).\n\r"),
! 	  escape_char);
! 	Write_to_screen(buf, 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgAddUnixCmd,
!       "\t%c<\tExecute a UNIX command adding the output to the message.\n\r"),
  	  escape_char);
! 	Write_to_screen(buf, 0);
! 	sprintf(buf, catgets(elm_msg_cat, ElmSet, ElmEditmsgEndMsg,
!       "\t.  \tby itself on a line (or a control-D) ends the message.\n\r"));
! 	Write_to_screen(buf, 0);
! 	Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEditmsgContinue,
! 	  "Continue.)\n\r"), 0);
  }
  
  void
--- 45,120 ----
  
  	char	buf[SLEN];
  
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgAvailOpts,
! 				"\n\r(Available options at this point are:\n\r\n\r"));
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgHelpMenu,
! 				"\t%c?\tPrint this help menu.\n\r"), 
! 			escape_char);
  	if (escape_char == TILDE_ESCAPE) /* doesn't make sense otherwise... */
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgAddLine,
! 				  "\t~~\tAdd line prefixed by a single '~' character.\n\r"));
  
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgBCC,
! 				"\t%cb\tChange the addresses in the Blind-carbon-copy list.\n\r"),
! 			escape_char);
! 
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgCC,
! 				"\t%cc\tChange the addresses in the Carbon-copy list.\n\r"),
! 			escape_char);
! 	
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgEmacs,
! 				"\t%ce\tInvoke the Emacs editor on the message, if possible.\n\r"),
! 			escape_char);
!       
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgAddMessage,
! 				 "\t%cf\tAdd the specified message or current.\n\r"),
! 			 escape_char);
! 	
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgToCCBCC,
! 				"\t%ch\tChange all available headers (to, cc, bcc, subject).\n\r"),
! 			escape_char);
! 	
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgSameCurrentPrefix,
! 				"\t%cm\tSame as '%cf', but with the current 'prefix'.\n\r"),
! 			escape_char, escape_char);
!        
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgUserEditor,
! 				"\t%co\tInvoke a user specified editor on the message.\n\r"),
! 			escape_char);
! 	
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgPrintMsg,
! 				"\t%cp\tPrint out message as typed in so far.\n\r"), 
! 			escape_char);
! 	
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgReadFile,
! 				"\t%cr\tRead in the specified file.\n\r"), 
! 			escape_char);
!        
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgSubject,
! 				"\t%cs\tChange the subject of the message.\n\r"),
! 			escape_char);
! 	
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgTo,
! 				"\t%ct\tChange the addresses in the To list.\n\r"),
! 			escape_char);
! 	
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgVi,
! 				"\t%cv\tInvoke the Vi visual editor on the message.\n\r"),
! 			escape_char);
!        
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgUnixCmd,
! 			       "\t%c!\tExecute a UNIX command (or give a shell if no command).\n\r"),
  	  escape_char);
! 	
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgAddUnixCmd,
! 				"\t%c<\tExecute a UNIX command adding the output to the message.\n\r"),
! 			escape_char);
! 	
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgEndMsg,
! 				"\t.  \tby itself on a line (or a control-D) ends the message.\n\r"));
! 	
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgContinue,
! 				"Continue.)\n\r"));
  }
  
  void
***************
*** 272,285 ****
  	(void) expand_env(exp_fname, filename, sizeof(exp_fname));
  
  	if (exp_fname[0] == '\0') {
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmNoFilenameSpecified,
! 	      "\n\r(No filename specified for file read! Continue.)\n\r"), 0);
  	  return;
  	}
  
  	if ((myfd = fopen(exp_fname,"r")) == NULL) {
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmCouldntReadFile,
! 	    "\n\r(Couldn't read file '%s'! Continue.)\n\r"), 1, exp_fname);
  	  return;
  	}
  
--- 139,152 ----
  	(void) expand_env(exp_fname, filename, sizeof(exp_fname));
  
  	if (exp_fname[0] == '\0') {
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmNoFilenameSpecified,
! 				  "\n\r(No filename specified for file read! Continue.)\n\r"));
  	  return;
  	}
  
  	if ((myfd = fopen(exp_fname,"r")) == NULL) {
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmCouldntReadFile,
! 				  "\n\r(Couldn't read file '%s'! Continue.)\n\r"), exp_fname);
  	  return;
  	}
  
***************
*** 293,317 ****
  	fclose(myfd);
  
  	if (lines == 1)
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmAddedLine,
! 	    "\n\r(Added 1 line ["), 0);
  	else
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmAddedLinePlural,
! 	    "\n\r(Added %d lines ["), 1, lines);
  
  	if (nchars == 1)
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmAddedChar,
! 	    "1 char] "), 0);
  	else
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmAddedCharPlural,
! 	    "%d chars] "), 1, nchars);
  
  	if (show_user_filename)
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmAddedFromFile,
! 		"from file %s. Continue.)\n\r"), 1, exp_fname);
  	else
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmAddedToMessage,
! 		"to message. Continue.)\n\r"), 0);
  
  	return;
  }
--- 160,185 ----
  	fclose(myfd);
  
  	if (lines == 1)
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmAddedLine,
! 				  "\n\r(Added 1 line ["));
  	else
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmAddedLinePlural,
! 				  "\n\r(Added %d lines ["), lines);
  
  	if (nchars == 1)
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmAddedChar,
! 				  "1 char] "));
  	else
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmAddedCharPlural,
! 				  "%d chars] "), nchars);
  
  	if (show_user_filename)
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmAddedFromFile,
! 				  "from file %s. Continue.)\n\r"),  
! 			  exp_fname);
  	else
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmAddedToMessage,
! 				  "to message. Continue.)\n\r"));
  
  	return;
  }
***************
*** 335,348 ****
  	fflush(edit_fd);
  	fseek(edit_fd, 0L, 0);
  
! 	Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEditmsgPrintTo,
! 	    "\n\rTo: %s\n\r"), 1, format_long(to, 4));
! 	Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEditmsgPrintCC,
! 	    "Cc: %s\n\r"), 1, format_long(cc, 4));
! 	Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEditmsgPrintBCC,
! 	    "Bcc: %s\n\r"), 1, format_long(bcc, 5));
! 	Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEditmsgPrintSubject,
! 	    "Subject: %s\n\r\n\r"), 1, subject);
  
  	while (fgets(buffer, SLEN, edit_fd) != NULL) {
  	  Write_to_screen(buffer, 0);
--- 203,220 ----
  	fflush(edit_fd);
  	fseek(edit_fd, 0L, 0);
  
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgPrintTo,
! 				"\n\rTo: %s\n\r"), 
! 			format_long(to, 4));
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgPrintCC,
! 				"Cc: %s\n\r"), 
! 			format_long(cc, 4));
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgPrintBCC,
! 	    "Bcc: %s\n\r"), 
! 			format_long(bcc, 5));
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgPrintSubject,
! 				"Subject: %s\n\r\n\r"), 
! 			subject);
  
  	while (fgets(buffer, SLEN, edit_fd) != NULL) {
  	  Write_to_screen(buffer, 0);
***************
*** 349,356 ****
  	  CarriageReturn();
  	}
  
! 	Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEditmsgPrintContinue,
! 	    "\n\r(Continue entering message.)\n\r"), 0);
  }
  
  void
--- 221,228 ----
  	  CarriageReturn();
  	}
  
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgPrintContinue,
! 				"\n\r(Continue entering message.)\n\r"));
  }
  
  void
***************
*** 379,394 ****
  
  	/* a couple of quick checks */
  	if(message_count < 1) {
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmNoMessageReadContinue,
! 	    "(No messages to read in! Continue.)\n\r"), 0);
  	  return;
  	}
  	if (isdigit(*arg)) {
  	  if((mindex = atoi(arg)) < 1 || mindex > message_count) {
! 	    sprintf(local_buffer, catgets(elm_msg_cat, ElmSet, ElmValidNumbersBetween,
! 	      "(Valid message numbers are between 1 and %d. Continue.)\n\r"),
! 	      message_count);
! 	    Write_to_screen(local_buffer, 0);
  	    return;
  	  }
  	}
--- 251,267 ----
  
  	/* a couple of quick checks */
  	if(message_count < 1) {
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 				  ElmNoMessageReadContinue,
! 				  "(No messages to read in! Continue.)\n\r"));
  	  return;
  	}
  	if (isdigit(*arg)) {
  	  if((mindex = atoi(arg)) < 1 || mindex > message_count) {
! 	    Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmValidNumbersBetween,
! 				    "(Valid message numbers are between 1 and %d. Continue.)\n\r"),
! 			    message_count);
! 	    
  	    return;
  	  }
  	}
***************
*** 398,408 ****
  	  return;
  
  	/* go run readmsg and get output */
! 	sprintf(local_buffer, "%s -- %s", readmsg, arg);
  	if ((myfd = popen(local_buffer, "r")) == NULL) {
! 	   Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmCantFindReadmsg,
! 	       "(Can't find 'readmsg' command! Continue.)\n\r"),
! 	       0);
  	   (void) remove_folder_state_file();
  	   return;	
  	}
--- 271,282 ----
  	  return;
  
  	/* go run readmsg and get output */
! 	elm_sfprintf(local_buffer, sizeof local_buffer,
! 		     FRM("%s -- %s"), 
! 		     readmsg, arg);
  	if ((myfd = popen(local_buffer, "r")) == NULL) {
! 	   Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmCantFindReadmsg,
! 				   "(Can't find 'readmsg' command! Continue.)\n\r"));
  	   (void) remove_folder_state_file();
  	   return;	
  	}
***************
*** 421,454 ****
          (void) remove_folder_state_file();
  	
  	if (lines == 0) {
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEditmsgCouldntAdd,
! 	 	 "(Couldn't add the requested message. Continue.)\n\r"), 0);
  	  return;
  	}
  
  	if (lines == 1)
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmAddedLine,
! 	    "\n\r(Added 1 line ["), 0);
  	else
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmAddedLinePlural,
! 	    "\n\r(Added %d lines ["), 1, lines);
  
  	if (nchars == 1)
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmAddedChar,
! 	    "1 char] "), 0);
  	else
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmAddedCharPlural,
! 	    "%d chars] "), 1, nchars);
  
! 	Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmAddedToMessage,
! 		"to message. Continue.)\n\r"), 0);
  
  	return;
  }
  
! void
! get_with_expansion(prompt, buffer, expanded_buffer, sourcebuf)
! char *prompt, *buffer, *expanded_buffer, *sourcebuf;
  {
  	/** This is used to prompt for a new value of the specified field.
  	    If expanded_buffer == NULL then we won't bother trying to expand
--- 295,332 ----
          (void) remove_folder_state_file();
  	
  	if (lines == 0) {
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgCouldntAdd,
! 	 	 "(Couldn't add the requested message. Continue.)\n\r"));
  	  return;
  	}
  
  	if (lines == 1)
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmAddedLine,
! 	    "\n\r(Added 1 line ["));
  	else
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmAddedLinePlural,
! 				  "\n\r(Added %d lines ["), lines);
  
  	if (nchars == 1)
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmAddedChar,
! 				  "1 char] "));
  	else
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmAddedCharPlural,
! 				  "%d chars] "), nchars);
  
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmAddedToMessage,
! 				"to message. Continue.)\n\r"));
  
  	return;
  }
  
! static void get_with_expansion P_((char *, char *, char *, char *,
! 				   int, int)); /* Prototype */
! 
! static void get_with_expansion(prompt, buffer, expanded_buffer, sourcebuf,
! 			       buffer_size, expanded_buffer_size)
!      char *prompt, *buffer, *expanded_buffer, *sourcebuf;
!      int buffer_size, expanded_buffer_size;
  {
  	/** This is used to prompt for a new value of the specified field.
  	    If expanded_buffer == NULL then we won't bother trying to expand
***************
*** 455,461 ****
  	    this puppy out!  (sourcebuf could be an initial addition)
  	**/
  
! 	Write_to_screen(prompt, 0);	fflush(stdout);	/* output! */
  
  	if (sourcebuf != NULL) {
  	  while (!whitespace(*sourcebuf) && *sourcebuf != '\0') 
--- 333,339 ----
  	    this puppy out!  (sourcebuf could be an initial addition)
  	**/
  
! 	Write_to_screen(FRM("%s"),prompt);	fflush(stdout);	/* output! */
  
  	if (sourcebuf != NULL) {
  	  while (!whitespace(*sourcebuf) && *sourcebuf != '\0') 
***************
*** 464,484 ****
  	    while (whitespace(*sourcebuf)) 
  	      sourcebuf++;
  	    if (strlen(sourcebuf) > 0) {
! 	      strcat(buffer, " ");
! 	      strcat(buffer, sourcebuf);
  	    }
  	  }
  	}
  
! 	optionally_enter(buffer, -1, -1, TRUE, FALSE);	/* already data! */
  
  	if(expanded_buffer != NULL) {
! 	  build_address(strip_commas(buffer), expanded_buffer);
  	  if(*expanded_buffer != '\0') {
  	    if (*prompt == '\n')
! 	      Write_to_screen("%s%s", 2, prompt, expanded_buffer);
  	    else
! 	      Write_to_screen("\n\r%s%s", 2, prompt, expanded_buffer);
  	  }
  	}
  	NewLine();
--- 342,364 ----
  	    while (whitespace(*sourcebuf)) 
  	      sourcebuf++;
  	    if (strlen(sourcebuf) > 0) {
! 	      strfcat(buffer, " ", buffer_size);
! 	      strfcat(buffer, sourcebuf, buffer_size);
  	    }
  	  }
  	}
  
! 	optionally_enter(buffer, -1, -1, OE_APPEND_CURRENT,
! 			 buffer_size);  /* already data! */
  
  	if(expanded_buffer != NULL) {
! 	  build_address(strip_commas(buffer), expanded_buffer,
! 			buffer_size, expanded_buffer_size);
  	  if(*expanded_buffer != '\0') {
  	    if (*prompt == '\n')
! 	      Write_to_screen(FRM("%s%s"), prompt, expanded_buffer);
  	    else
! 	      Write_to_screen(FRM("\n\r%s%s"), prompt, expanded_buffer);
  	  }
  	}
  	NewLine();
***************
*** 499,510 ****
  	signal(SIGQUIT, edit_interrupt);
  
  	if (interrupts_while_editing++ == 0)
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEditmsgOneMoreCancel,
! 		"(Interrupt. One more to cancel this letter.)\n\r"),
! 	  	0);
  	else
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEditmsgCancelled,
! 		"(Interrupt. Letter canceled.)\n\r"), 0);
  
  #if defined(SIGSET) && defined(HASSIGHOLD)
  	/*
--- 379,390 ----
  	signal(SIGQUIT, edit_interrupt);
  
  	if (interrupts_while_editing++ == 0)
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 				  ElmEditmsgOneMoreCancel,
! 				  "(Interrupt. One more to cancel this letter.)\n\r"));
  	else
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEditmsgCancelled,
! 				  "(Interrupt. Letter canceled.)\n\r"));
  
  #if defined(SIGSET) && defined(HASSIGHOLD)
  	/*
***************
*** 578,602 ****
  	buffer[0] = '\0';
  
  	if (strcmp(editor, "builtin") == 0 || strcmp(editor, "none") == 0) {
! 	  if (already_has_text && strcmp(alternative_editor, "builtin") &&
! 	      strcmp(alternative_editor, "none")) {
  	    if (in_string(alternative_editor, "%s"))
! 	      sprintf(buffer, alternative_editor, filename);
  	    else
! 	      sprintf(buffer, "%s %s", alternative_editor, filename);
  	  } else
  	    return(no_editor_edit_the_message(filename));
  	}
  
! 	PutLine0(LINES, 0, catgets(elm_msg_cat, ElmSet, ElmInvokeEditor,
! 	  "Invoking editor..."));
  	fflush(stdout);
  
  	if (strlen(buffer) == 0) {
  	  if (in_string(editor, "%s"))
! 	    sprintf(buffer, editor, filename);
  	  else
! 	    sprintf(buffer, "%s %s", editor, filename);
  	}
  
  	(void) elm_chown(filename, userid, groupid);
--- 458,489 ----
  	buffer[0] = '\0';
  
  	if (strcmp(editor, "builtin") == 0 || strcmp(editor, "none") == 0) {
! 	  if (already_has_text && 
! 	      0 != strcmp(alternative_editor, "builtin") &&
! 	      0 != strcmp(alternative_editor, "none")) {
  	    if (in_string(alternative_editor, "%s"))
! 	      elm_sfprintf(buffer, sizeof buffer,
! 			   FRM(alternative_editor), filename);
  	    else
! 	      elm_sfprintf(buffer, sizeof buffer,
! 			   FRM("%s %s"), alternative_editor, filename);
  	  } else
  	    return(no_editor_edit_the_message(filename));
  	}
  
! 	PutLine0(elm_LINES, 0, catgets(elm_msg_cat, ElmSet, ElmInvokeEditor,
! 				       "Invoking editor..."));
  	fflush(stdout);
  
  	if (strlen(buffer) == 0) {
  	  if (in_string(editor, "%s"))
! 	    elm_sfprintf(buffer, sizeof buffer,
! 			 FRM(editor), 
! 			 filename);
  	  else
! 	    elm_sfprintf(buffer, sizeof buffer,
! 			 FRM("%s %s"), 
! 			 editor, filename);
  	}
  
  	(void) elm_chown(filename, userid, groupid);
***************
*** 604,612 ****
  	if (( old_raw = RawState()) == ON)
  	  Raw(OFF);
  
- 	if (cursor_control)
- 	  transmit_functions(OFF);		/* function keys are local */
- 
  	if ((stat = system_call(buffer, SY_ENAB_SIGHUP|SY_DUMPSTATE)) == -1) {
  	  err = errno;
  	  dprint(1,(debugfile, 
--- 491,496 ----
***************
*** 613,621 ****
  		  "System call failed with stat %d (edit_the_message)\n", 
  		  stat));
  	  dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	  ClearLine(LINES-1);
! 	  error1(catgets(elm_msg_cat, ElmSet, ElmCantInvokeEditor,
! 	    "Can't invoke editor '%s' for composition."), editor);
  	  if (sleepmsg > 0)
  		sleep(sleepmsg);
  	  return_value = 1;
--- 497,506 ----
  		  "System call failed with stat %d (edit_the_message)\n", 
  		  stat));
  	  dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	  ClearLine(elm_LINES-1);
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCantInvokeEditor,
! 			    "Can't invoke editor '%s' for composition."), 
! 		    editor);
  	  if (sleepmsg > 0)
  		sleep(sleepmsg);
  	  return_value = 1;
***************
*** 627,637 ****
  	   Raw(ON);
  
  	SetXYLocation(0, 40);	/* a location not near the next request, so an absolute is used */
! 	MoveCursor(LINES, 0);	/* dont know where we are, force last row, col 0 */
  
- 	if (cursor_control)
- 	  transmit_functions(ON);		/* function keys are local */
- 	
  	return(return_value);
  }
  
--- 512,519 ----
  	   Raw(ON);
  
  	SetXYLocation(0, 40);	/* a location not near the next request, so an absolute is used */
! 	MoveCursor(elm_LINES, 0);	/* dont know where we are, force last row, col 0 */
  
  	return(return_value);
  }
  
***************
*** 653,662 ****
  
  	/* The built-in editor is not re-entrant! */
  	if (builtin_editor_active) {
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmIntReentrantBuiltinEditor,
! 		"\r\nInternal error - reentrant call to builtin editor attempted.\r\n\r\n"), 0);
  	  dprint(1, (debugfile,
! 	    "Reentrant call to builtin editor for %s attempted\n", filename));
  	  return(1);
  	}
  
--- 535,544 ----
  
  	/* The built-in editor is not re-entrant! */
  	if (builtin_editor_active) {
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmIntReentrantBuiltinEditor,
! 				  "\r\nInternal error - reentrant call to builtin editor attempted.\r\n\r\n"), 0);
  	  dprint(1, (debugfile,
! 		     "Reentrant call to builtin editor for %s attempted\n", filename));
  	  return(1);
  	}
  
***************
*** 669,678 ****
  
  	if ((edit_fd = fopen(filename, "r+")) == NULL) {
  	  err = errno;
! 	  sprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmCouldntOpenAppend,
! 	    "Couldn't open %s for update [%s]."),
! 	    filename, error_description(err));
! 	  Write_to_screen(buffer, 0);
  	  dprint(1, (debugfile,
  		"Error encountered trying to open file %s;\n", filename));
  	  dprint(1, (debugfile, "** %s **\n", error_description(err)));
--- 551,560 ----
  
  	if ((edit_fd = fopen(filename, "r+")) == NULL) {
  	  err = errno;
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmCouldntOpenAppend,
! 				  "Couldn't open %s for update [%s]."),
! 			  filename, error_description(err));
! 	  
  	  dprint(1, (debugfile,
  		"Error encountered trying to open file %s;\n", filename));
  	  dprint(1, (debugfile, "** %s **\n", error_description(err)));
***************
*** 685,702 ****
  	/** is there already text in this file? **/
  
  	if (fsize(edit_fd) > 0L)
! 	  strcpy(buf, catgets(elm_msg_cat, ElmSet, ElmContinueEntering,
! 	    "\n\rContinue entering message."));
  	else
! 	  strcpy(buf, catgets(elm_msg_cat, ElmSet, ElmEnterMessage,
! 	    "\n\rEnter message."));
! 	strcat(buf, catgets(elm_msg_cat, ElmSet, ElmTypeElmCommands,
! 	  "  Type Elm commands on lines by themselves.\n\r"));
! 	sprintf(buf + strlen(buf), catgets(elm_msg_cat, ElmSet, ElmCommandsInclude,
!     "Commands include:  ^D or '.' to end, %cp to list, %c? for help.\n\r\n\r"),
! 		escape_char, escape_char);
  	CleartoEOS();
! 	Write_to_screen(buf, 0);
  
  	oldint  = signal(SIGINT,  edit_interrupt);
  	oldquit = signal(SIGQUIT, edit_interrupt);
--- 567,587 ----
  	/** is there already text in this file? **/
  
  	if (fsize(edit_fd) > 0L)
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmContinueEntering,
! 				  "\n\rContinue entering message."),
! 			  sizeof buf);
  	else
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEnterMessage,
! 				  "\n\rEnter message."),
! 			  sizeof buf);
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmTypeElmCommands,
! 				"  Type Elm commands on lines by themselves.\n\r"),
! 			sizeof buf);
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmCommandsInclude,
! 				"Commands include:  ^D or '.' to end, %cp to list, %c? for help.\n\r\n\r"),
! 			escape_char, escape_char);
  	CleartoEOS();
! 	
  
  	oldint  = signal(SIGINT,  edit_interrupt);
  	oldquit = signal(SIGQUIT, edit_interrupt);
***************
*** 723,734 ****
  /*** Code changed to provide for line wrapping ***/
  wrap_input: wrap[0] = '\0';
  
! 	while (wrapped_enter(buffer, wrap, -1,-1, edit_fd, &is_wrapped) == 0) {
  
  	  if (is_wrapped) { /* No need to check for escape or break */
  	    fprintf(edit_fd, "%s\n", buffer);
  	    NewLine();
! 	    sprintf(buffer,"%s",wrap);
  	    goto wrap_input;
  	  }
  
--- 608,620 ----
  /*** Code changed to provide for line wrapping ***/
  wrap_input: wrap[0] = '\0';
  
! 	while (wrapped_enter(buffer, wrap, -1,-1, edit_fd, &is_wrapped,
! 			     sizeof buffer, sizeof wrap) == 0) {
  
  	  if (is_wrapped) { /* No need to check for escape or break */
  	    fprintf(edit_fd, "%s\n", buffer);
  	    NewLine();
! 	    strfcpy(buffer,wrap, sizeof buffer);
  	    goto wrap_input;
  	  }
  
***************
*** 746,769 ****
  	      case TILDE_ESCAPE: move_left(buffer, 1); 
  			  	 goto tilde_input;	/*!!*/
  
! 	      case 't' : get_with_expansion("\n\rTo: ",
! 	      		   to, expanded_to, buffer);
! 			 goto more_input;
! 	      case 'b' : get_with_expansion("\n\rBcc: ",
! 			   bcc, expanded_bcc, buffer);
! 			 goto more_input;
! 	      case 'c' : get_with_expansion("\n\rCc: ",
! 			   cc, expanded_cc, buffer);
! 			 goto more_input;
! 	      case 's' : get_with_expansion("\n\rSubject: ",
! 			   subject,NULL,buffer);
!    			 goto more_input;
! 
! 	      case 'h' : get_with_expansion("\n\rTo: ", to, expanded_to, NULL);	
! 			 get_with_expansion("Cc: ", cc, expanded_cc, NULL);
! 			 get_with_expansion("Bcc: ", bcc,expanded_bcc, NULL);
! 			 get_with_expansion("Subject: ", subject, NULL, NULL);
! 			 goto more_input;
  
  	      case 'r' : read_in_file(edit_fd, (char *) buffer + 2, 1);
  		  	 goto more_input;
--- 632,663 ----
  	      case TILDE_ESCAPE: move_left(buffer, 1); 
  			  	 goto tilde_input;	/*!!*/
  
! 	    case 't' : get_with_expansion("\n\rTo: ",
! 					  to, expanded_to, buffer,
! 					  sizeof to, sizeof expanded_to);
! 	    goto more_input;
! 	    case 'b' : get_with_expansion("\n\rBcc: ",
! 					  bcc, expanded_bcc, buffer,
! 					  sizeof bcc, sizeof expanded_bcc);
! 	    goto more_input;
! 	    case 'c' : get_with_expansion("\n\rCc: ",
! 					  cc, expanded_cc, buffer,
! 					  sizeof cc, sizeof expanded_cc);
! 	    goto more_input;
! 	    case 's' : get_with_expansion("\n\rSubject: ",
! 					  subject,NULL,buffer,
! 					  sizeof subject,0);
! 	    goto more_input;
! 
! 	    case 'h' : get_with_expansion("\n\rTo: ", to, expanded_to, NULL,
! 					  sizeof to, sizeof expanded_to);
! 	    get_with_expansion("Cc: ", cc, expanded_cc, NULL,
! 			       sizeof cc, sizeof expanded_cc);
! 	    get_with_expansion("Bcc: ", bcc,expanded_bcc, NULL,
! 			       sizeof bcc, sizeof expanded_bcc);
! 	    get_with_expansion("Subject: ", subject, NULL, NULL,
! 			       sizeof subject, 0);
! 	    goto more_input;
  
  	      case 'r' : read_in_file(edit_fd, (char *) buffer + 2, 1);
  		  	 goto more_input;
***************
*** 770,839 ****
  
  	      case 'e' : if (strlen(e_editor) > 0) 
  			   if (access(e_editor, ACCESS_EXISTS) == 0) {
! 			     strcpy(buffer, editor);
! 			     strcpy(editor, e_editor);
  	  		     fclose(edit_fd);
  			     (void) edit_the_message(filename,0);
! 			     strcpy(editor, buffer);
  			     edit_fd = fopen(filename, "a+");
! 			     Write_to_screen(post_ed_continue, 0);
  			     goto more_input;
  			   }
  			   else
! 			     Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmCantFindEmacs,
! 			"\n\r(Can't find Emacs on this system! Continue.)\n\r"),
! 			0);
  			 else
! 			   Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmDontKnowEmacs,
! 			"\n\r(Don't know where Emacs would be. Continue.)\n\r"),
! 			0);	
  			 goto more_input;
  
  	       case 'v' : NewLine();
! 			  strcpy(buffer, editor);
! 			  strcpy(editor, v_editor);
  			  fclose(edit_fd);
  			  (void) edit_the_message(filename,0);
! 			  strcpy(editor, buffer);
  			  edit_fd = fopen(filename, "a+");
! 			  Write_to_screen(post_ed_continue, 0);
  			  goto more_input;
  
! 	       case 'o' : Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEnterNameEditor,
! 			     "\n\rPlease enter the name of the editor: "), 0);
  			  editor_name[0] = '\0';
! 			  optionally_enter(editor_name,-1,-1, FALSE, FALSE);
  			  NewLine();
  			  if (strlen(editor_name) > 0) {
! 			    strcpy(buffer, editor);
! 			    strcpy(editor, editor_name);
  			    fclose(edit_fd);
  			    (void) edit_the_message(filename,0);
! 			    strcpy(editor, buffer);
  			    edit_fd = fopen(filename, "a+");
! 			    Write_to_screen(post_ed_continue, 0);
  			    goto more_input;
  			  }
! 	  		  Write_to_screen(simple_continue, 0);
  			  goto more_input; 
  
  		case '<' : NewLine();
  			   if (strlen(buffer) < 3)
! 			     Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmUseSpecificCommand,
! 		 "(You need to use a specific command here. Continue.)\n\r"), 0);
  			   else {
! 			     sprintf(buf, " > %s%s.%d 2>&1", temp_dir, temp_edit, getpid());
! 			     strcat(buffer, buf);
  			     if (( old_raw = RawState()) == ON)
  			       Raw(OFF);
  			     (void) system_call((char *) buffer+2, SY_ENAB_SIGINT|SY_DUMPSTATE);
  			     if (old_raw == ON)
  				Raw(ON);
! 			     sprintf(buffer, "~r %s%s.%d", temp_dir, temp_edit, getpid());
  	      		     read_in_file(edit_fd, (char *) buffer + 3, 0);
  			     (void) unlink((char *) buffer+3);
  			     SetXYLocation(0, 40);	/* a location not near the next request, so an absolute is used */
! 			     MoveCursor(LINES, 0);	/* and go to a known location, last row col 0 */
  			   }
  			   goto more_input; 
  
--- 664,751 ----
  
  	      case 'e' : if (strlen(e_editor) > 0) 
  			   if (access(e_editor, ACCESS_EXISTS) == 0) {
! 			     strfcpy(buffer, editor, sizeof buffer);
! 			     strfcpy(editor, e_editor, sizeof editor);
  	  		     fclose(edit_fd);
  			     (void) edit_the_message(filename,0);
! 			     strfcpy(editor, buffer, sizeof editor);
  			     edit_fd = fopen(filename, "a+");
! 			     Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 						     ElmPostEdContinue,
! 						     "(Continue entering message.  Type ^D or '.' on a line by itself to end.)\n\r"));
  			     goto more_input;
  			   }
  			   else
! 			     Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 						     ElmCantFindEmacs,
! 						     "\n\r(Can't find Emacs on this system! Continue.)\n\r"));
  			 else
! 			   Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 						   ElmDontKnowEmacs,
! 						   "\n\r(Don't know where Emacs would be. Continue.)\n\r"));	
  			 goto more_input;
  
  	       case 'v' : NewLine();
! 			  strfcpy(buffer, editor, sizeof buffer);
! 			  strfcpy(editor, v_editor, sizeof editor);
  			  fclose(edit_fd);
  			  (void) edit_the_message(filename,0);
! 			  strfcpy(editor, buffer, sizeof editor);
  			  edit_fd = fopen(filename, "a+");
! 			  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 						  ElmPostEdContinue,
! 						  "(Continue entering message.  Type ^D or '.' on a line by itself to end.)\n\r"));
  			  goto more_input;
  
! 	       case 'o' : Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEnterNameEditor,
! 						  "\n\rPlease enter the name of the editor: "));
  			  editor_name[0] = '\0';
! 			  if (optionally_enter(editor_name,-1,-1, 0,
! 					       sizeof editor_name) != 0) {
! 			    NewLine();
! 			    goto more_input;
! 			  }
! 
  			  NewLine();
  			  if (strlen(editor_name) > 0) {
! 			    strfcpy(buffer, editor, sizeof buffer);
! 			    strfcpy(editor, editor_name, sizeof editor);
  			    fclose(edit_fd);
  			    (void) edit_the_message(filename,0);
! 			    strfcpy(editor, buffer, sizeof editor);
  			    edit_fd = fopen(filename, "a+");
! 			    Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 						    ElmPostEdContinue,
! 						    "(Continue entering message.  Type ^D or '.' on a line by itself to end.)\n\r"));
  			    goto more_input;
  			  }
! 	  		  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 						  ElmSimpleContinue,
! 						  "(Continue.)\n\r"));
  			  goto more_input; 
  
  		case '<' : NewLine();
  			   if (strlen(buffer) < 3)
! 			     Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 						     ElmUseSpecificCommand,
! 						     "(You need to use a specific command here. Continue.)\n\r"));
  			   else {
! 			     elm_sfprintf(buf, sizeof buf,
! 					  FRM(" > %s%s.%d 2>)&1"), 
! 					  temp_dir, temp_edit, getpid());
! 			     strfcat(buffer, buf, sizeof buffer);
  			     if (( old_raw = RawState()) == ON)
  			       Raw(OFF);
  			     (void) system_call((char *) buffer+2, SY_ENAB_SIGINT|SY_DUMPSTATE);
  			     if (old_raw == ON)
  				Raw(ON);
! 			     elm_sfprintf(buffer, sizeof buffer,
! 					  FRM("~r %s%s.%d"), 
! 					  temp_dir, temp_edit, getpid());
  	      		     read_in_file(edit_fd, (char *) buffer + 3, 0);
  			     (void) unlink((char *) buffer+3);
  			     SetXYLocation(0, 40);	/* a location not near the next request, so an absolute is used */
! 			     MoveCursor(elm_LINES, 0);	/* and go to a known location, last row col 0 */
  			   }
  			   goto more_input; 
  
***************
*** 845,852 ****
  			   if (old_raw == ON)
  			      Raw(ON);
  			   SetXYLocation(0, 40);	/* a location not near the next request, so an absolute is used */
! 			   MoveCursor(LINES, 0);	/* and go to a known location, last row col 0 */
! 	    		   Write_to_screen(simple_continue, 0);
  			   goto more_input;
  
  		 case 'm' : /* same as 'f' but with leading prefix added */
--- 757,766 ----
  			   if (old_raw == ON)
  			      Raw(ON);
  			   SetXYLocation(0, 40);	/* a location not near the next request, so an absolute is used */
! 			   MoveCursor(elm_LINES, 0);	/* and go to a known location, last row col 0 */
! 	    		   Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 						   ElmSimpleContinue,
! 						   "(Continue.)\n\r"));
  			   goto more_input;
  
  		 case 'm' : /* same as 'f' but with leading prefix added */
***************
*** 861,870 ****
  			    print_message_so_far(edit_fd, filename);
  			    goto more_input;
  
! 		 default  : MCsprintf(buf, catgets(elm_msg_cat, ElmSet, ElmDontKnowChar,
! 			 "\n\r(Don't know what %c%c is. Try %c? for help.)\n\r"),
! 				    escape_char, buffer[1], escape_char);
! 			    Write_to_screen(buf, 0);
  	       }
  	     }
  	     else {
--- 775,785 ----
  			    print_message_so_far(edit_fd, filename);
  			    goto more_input;
  
! 		 default  : Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 						    ElmDontKnowChar,
! 						    "\n\r(Don't know what %c%c is. Try %c? for help.)\n\r"),
! 					 escape_char, buffer[1], escape_char);
! 		 
  	       }
  	     }
  	     else {
***************
*** 876,883 ****
  	}
  
  
! 	Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEndOfMessage,
! 	  "\n\r<end-of-message>\n\r\n\r\n\r\n\r"), 0);
  
  	(void) signal(SIGINT,  oldint);
  	(void) signal(SIGQUIT, oldquit);
--- 791,798 ----
  	}
  
  
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmEndOfMessage,
! 				"\n\r<end-of-message>\n\r\n\r\n\r\n\r"));
  
  	(void) signal(SIGINT,  oldint);
  	(void) signal(SIGQUIT, oldquit);
***************
*** 888,891 ****
--- 803,807 ----
  	builtin_editor_active = FALSE;
  	return(0);
  }
+ 
  
Index: elm2.4.ME+.50/src/elm.c
*** elm2.4.25/src/elm.c	Mon May 30 19:26:14 1994
--- elm2.4.ME+.50/src/elm.c	Tue Nov 17 21:14:09 1998
***************
*** 1,186 ****
  
! static char rcsid[] = "@(#)$Id: elm.c,v 5.21 1994/05/30 16:26:03 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.21 $   $State: Exp $
   *
   * This file and all associated files and documentation:
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: elm.c,v $
!  * Revision 5.21  1994/05/30  16:26:03  syd
!  * Add protection to fflush on mailfile
!  * From: Syd
!  *
!  * Revision 5.20  1994/05/15  23:10:08  syd
!  * Below are the changes required to compile/link elm 2.4 pl23 under
!  * QNX 4.2 with the Watcom 9.5 compiler (very picky).
!  * From: "Brian Campbell" <brianc@quantum>
!  *
!  * Revision 5.19  1994/05/14  18:42:57  syd
!  * Here are some more of fixes to correctly call fflush() and unlock() in sequence.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.18  1994/03/12  15:22:43  syd
!  * Fix a line of debug output that is too long
!  * From: "C.R. Ritson" <C.R.Ritson@newcastle.ac.uk>
!  *
!  * Revision 5.17  1994/03/11  21:25:24  syd
!  * Fix Elm looping if an EOF is received.
!  * From: Gregory Neil Shapiro <gshapiro@WPI.EDU>
!  *
!  * Revision 5.16  1993/09/19  23:46:00  syd
!  * Although it doesnt solve the limit/resync problem of new
!  * messages, allow them to be accessed anyway.
!  * From: austig@solan.unit.no
!  *
!  * Revision 5.15  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.14  1993/05/31  19:32:20  syd
!  * With this patch build_address() should treat local mailing
!  * lists and other aliases known by the transport agent as valid
!  * addresses.
!  * I also conditionalized printing the "Expands to: " message
!  * in check_only mode to be done only when there is an expanded
!  * address to print. Build_address will inform anyway about an
!  * alias that does not exist.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.13  1993/04/12  03:15:41  syd
!  * These patches makes 'T' (since it was free) do a Tag and Move command in the
!  * index and alias page, and in the builtin pager.
!  * In the alias help in src/alias.c, there is a tolower done on the character
!  * one wants help for.  This is clearly wrong.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.12  1993/01/20  03:37:16  syd
!  * Nits and typos in the NLS messages and corresponding default messages.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.11  1993/01/19  04:34:28  syd
!  * Just a small bugfix for the '#' (Debug Message) screen.  The columns of the
!  * various flags don't all line up properly:
!  * From: Gary Bartlett <garyb@abekrd.co.uk>
!  *
!  * Revision 5.10  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.9  1992/12/16  14:33:25  syd
!  * add back missing nl on check only output
!  * From: Syd
!  *
!  * Revision 5.8  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.7  1992/12/07  02:58:13  syd
!  * fix long -> time_t
!  * From: Syd
!  *
!  * Revision 5.6  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.5  1992/11/22  00:03:56  syd
!  * Fix segmentation violation on restricted alias page jump.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.4  1992/11/07  19:37:21  syd
!  * Enhanced printing support.  Added "-I" to readmsg to
!  * suppress spurious diagnostic messages.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.3  1992/10/31  20:02:26  syd
!  * remove duplicate ScreenSize call
!  * From: Syd
!  *
!  * Revision 5.2  1992/10/25  01:47:45  syd
!  * fixed a bug were elm didn't call metamail on messages with a characterset,
!  * which could be displayed by elm itself, but message is encoded with QP
!  * or BASE64
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /* Main program of the ELM mail system! 
  */
  
  #include "elm.h"
  #include "s_elm.h"
  
! #ifdef I_TIME
! #  include <time.h>
! #endif
! #ifdef I_SYSTIME
! #  include <sys/time.h>
! #endif
! #ifdef BSD
  #  include <sys/timeb.h>
  #endif
  
  long bytes();
  char *format_long(), *parse_arguments(), *error_description();
  
! main(argc, argv)
  int argc;
  char *argv[];
  {
  	int  ch;
  	char address[SLEN], to_whom[SLEN], *req_mfile;
  	int  i,j;      		/** Random counting variables (etc)          **/
- 	int  pageon, 		/** for when we receive new mail...          **/
- 	     last_in_folder;	/** for when we receive new mail too...      **/
  	long num;		/** another variable for fun..               **/
  	extern int errno;
  
! #ifdef I_LOCALE
! 	setlocale(LC_ALL, "");
! #endif
! 
! 	elm_msg_cat = catopen("elm2.4", 0);
! 
! 	req_mfile = parse_arguments(argc, argv, to_whom);
  
! 	initialize(req_mfile);
  
  	if (mail_only) {
  	   dprint(3, (debugfile, "Mail-only: mailing to\n-> \"%s\"\n", 
  		   format_long(to_whom, 3)));
  	   if(!batch_only) {
! 	     sprintf(address, catgets(elm_msg_cat, ElmSet, ElmSendOnlyMode,
! 	       "Send only mode [ELM %s]"), version_buff);
  	     Centerline(1, address);
  	   }
! 	   (void) send_msg(to_whom, "", batch_subject, TRUE,
! 	     (batch_only ? NO : allow_forms), FALSE); 
  	   leave(0);
  	} else if (check_only) {
! 	   do_check_only(to_whom);
  	   leave(0);
  	}
  
--- 1,74 ----
  
! static char rcsid[] = "@(#)$Id: elm.c,v 1.3 1998/11/07 14:12:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * This file and all associated files and documentation:
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /* Main program of the ELM mail system! 
  */
  
+ #include "patchlevel.h"
  #include "elm.h"
  #include "s_elm.h"
+ #include "elmlib.h"
  
! #ifdef BSD_TYPE
  #  include <sys/timeb.h>
  #endif
  
+ #ifdef MIME
+ #include "mime.h"
+ #endif
+ #include "me.h"
+ 
  long bytes();
  char *format_long(), *parse_arguments(), *error_description();
  
! static void do_check_only P_((char *, int)); /* Prototype */
! 
! int main(argc, argv)
  int argc;
  char *argv[];
  {
  	int  ch;
  	char address[SLEN], to_whom[SLEN], *req_mfile;
+ 	int size_r;
  	int  i,j;      		/** Random counting variables (etc)          **/
  	long num;		/** another variable for fun..               **/
  	extern int errno;
  
! 	locale_init();
! 	
! 	req_mfile = parse_arguments(argc, argv, to_whom, 
! 				   &size_r, sizeof to_whom);
  
! 	initialize(req_mfile, size_r);
  
  	if (mail_only) {
  	   dprint(3, (debugfile, "Mail-only: mailing to\n-> \"%s\"\n", 
  		   format_long(to_whom, 3)));
  	   if(!batch_only) {
! 	     elm_sfprintf(address, sizeof address,
! 			  CATGETS(elm_msg_cat, ElmSet, ElmSendOnlyMode,
! 				  "Send only mode [ELM %s]"), 
! 			  version_buff);
  	     Centerline(1, address);
  	   }
! 	   (void) send_msg(to_whom, "", batch_subject, 
! 			   MAIL_EDIT_MSG,
! 			   (batch_only ? NO : allow_forms));
  	   leave(0);
  	} else if (check_only) {
! 	   do_check_only(to_whom, sizeof to_whom);
  	   leave(0);
  	}
  
***************
*** 193,206 ****
  
  	    ScreenSize(&newLINES, &newCOLUMNS);
  	    resize_screen = 0;
! 	    if (newLINES != LINES || newCOLUMNS != COLUMNS) {
! 	      LINES = newLINES, COLUMNS = newCOLUMNS;
  #undef max
  #define max(a,b)	       ((a) < (b) ? (b) : (a))
  	      if (mini_menu)
! 		headers_per_page = max (LINES - 13, 1);
  	      else
! 		headers_per_page = max (LINES -	 8, 1);	  /* 5 more headers! */
  #undef max
  	      redraw++;
  	    }
--- 81,94 ----
  
  	    ScreenSize(&newLINES, &newCOLUMNS);
  	    resize_screen = 0;
! 	    if (newLINES != elm_LINES || newCOLUMNS != elm_COLUMNS) {
! 	      elm_LINES = newLINES, elm_COLUMNS = newCOLUMNS;
  #undef max
  #define max(a,b)	       ((a) < (b) ? (b) : (a))
  	      if (mini_menu)
! 		headers_per_page = max (elm_LINES - 13, 1);
  	      else
! 		headers_per_page = max (elm_LINES -	 8, 1);	  /* 5 more headers! */
  #undef max
  	      redraw++;
  	    }
***************
*** 212,228 ****
  	  nufoot = 0;
  	  nucurr = 0;
  
  	  if (mailfile)
! 		  fflush (mailfile);
  
! 	  if ((num = bytes(cur_folder)) != mailfile_size) {
  	    dprint(2, (debugfile, "Just received %d bytes more mail (elm)\n", 
  		    num - mailfile_size));
! 	    error(catgets(elm_msg_cat, ElmSet, ElmNewMailHangOn,
! 	      "New mail has arrived! Hang on..."));
  	    fflush(stdin);	/* just to be sure... */
! 	    last_in_folder = message_count;
! 	    pageon = header_page;
  
  	    if ((errno = can_access(cur_folder, READ_ACCESS)) != 0) {
  	      dprint(1, (debugfile,
--- 100,125 ----
  	  nufoot = 0;
  	  nucurr = 0;
  
+ #ifdef BACKGROUD_PROCESSES      
+ 	  if (handle_sigchld)
+ 	    sigchld_handler();
+ #endif
+ 
  	  if (mailfile)
! 	    flush_mailfile();
  
! 	  if ((num = bytes(cur_folder)) > mailfile_size) {
! 	    int was_on_page = on_page(current);
! 	    int pageon = header_page;
! 	    int last_in_folder = message_count;
! 
  	    dprint(2, (debugfile, "Just received %d bytes more mail (elm)\n", 
  		    num - mailfile_size));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNewMailHangOn,
! 			      "New mail has arrived! Hang on..."));
  	    fflush(stdin);	/* just to be sure... */
! 	    
! 	    
  
  	    if ((errno = can_access(cur_folder, READ_ACCESS)) != 0) {
  	      dprint(1, (debugfile,
***************
*** 229,236 ****
  		    "Error: given file %s as folder - unreadable (%s)!\n", 
  		    cur_folder, error_description(errno)));
  	      Raw(OFF);
! 	      fprintf(stderr, catgets(elm_msg_cat, ElmSet, ElmCantOpenFolderRead,
! 		"Can't open folder '%s' for reading!\n"), cur_folder);
  	      leave(0);
  	      }
  
--- 126,134 ----
  		    "Error: given file %s as folder - unreadable (%s)!\n", 
  		    cur_folder, error_description(errno)));
  	      Raw(OFF);
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCantOpenFolderRead,
! 				"Can't open folder '%s' for reading!\n"), 
! 			cur_folder);
  	      leave(0);
  	      }
  
***************
*** 241,268 ****
  	    if (selected)               /* update count of selected messages */
  	      selected += message_count - last_in_folder;
  
! 	    if (on_page(current))   /* do we REALLY have to rewrite? */
  	      showscreen();
! 	    else {
! 	      update_title();
! 	      ClearLine(LINES-1);	     /* remove reading message... */
! 	      if ((message_count - last_in_folder) == 1)
! 	        error(catgets(elm_msg_cat, ElmSet, ElmNewMessageRecv,
! 		       "1 new message received."));
! 	      else
! 	        error1(catgets(elm_msg_cat, ElmSet, ElmNewMessageRecvPlural,
! 		       "%d new messages received."), 
! 		       message_count - last_in_folder);
! 	    }
! 	    /* mailfile_size = num; */
! 	    if (cursor_control)
! 	      transmit_functions(ON);	/* insurance */
  	  }
  
  	  prompt(Prompt);
  
  	  CleartoEOLN();
  	  ch = GetPrompt();
  #ifdef SIGWINCH
  	  if (resize_screen) {
  	    int	newLINES, newCOLUMNS;
--- 139,177 ----
  	    if (selected)               /* update count of selected messages */
  	      selected += message_count - last_in_folder;
  
! 	    if (on_page(current) || 
! 		was_on_page) /* do we REALLY have to rewrite? */
  	      showscreen();
! 	    
! 	    update_title();
! 	    ClearLine(elm_LINES-1);	     /* remove reading message... */
! 	    if ((message_count - last_in_folder) == 1)
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNewMessageRecv,
! 				"1 new message received."));
! 	    else
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNewMessageRecvPlural,
! 				"%d new messages received."), 
! 			message_count - last_in_folder);
! 	  } else if (num < mailfile_size) {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmALERTMailfileShrinken,
! 			      "ALERT: Mailfile shrinken %d bytes!"),
! 		      mailfile_size - num);
! 	    dprint(1,(debugfile,"ALERT: Mailfile shrinken %d bytes!",
! 		      mailfile_size - num));
! 	    sleep_message();
  	  }
  
+ 	    /* mailfile_size = num; */
  	  prompt(Prompt);
  
  	  CleartoEOLN();
  	  ch = GetPrompt();
+ 
+ 	  if (redraw_screen) {
+ 	    redraw_screen = 0;
+ 	    redraw++;
+ 	  }
+ 
  #ifdef SIGWINCH
  	  if (resize_screen) {
  	    int	newLINES, newCOLUMNS;
***************
*** 269,281 ****
  
  	    ScreenSize(&newLINES, &newCOLUMNS);
  	    resize_screen = 0;
! 	    if (newLINES != LINES || newCOLUMNS != COLUMNS) {
! 	      LINES = newLINES, COLUMNS = newCOLUMNS;
  #define max(a,b)	       ((a) < (b) ? (b) : (a))
  	      if (mini_menu)
! 		headers_per_page = max (LINES - 13, 1);
  	      else
! 		headers_per_page = max (LINES -	 8, 1);	  /* 5 more headers! */
  #undef max
  	      redraw++;
  	    }
--- 178,190 ----
  
  	    ScreenSize(&newLINES, &newCOLUMNS);
  	    resize_screen = 0;
! 	    if (newLINES != elm_LINES || newCOLUMNS != elm_COLUMNS) {
! 	      elm_LINES = newLINES, elm_COLUMNS = newCOLUMNS;
  #define max(a,b)	       ((a) < (b) ? (b) : (a))
  	      if (mini_menu)
! 		headers_per_page = max (elm_LINES - 13, 1);
  	      else
! 		headers_per_page = max (elm_LINES - 8, 1);	  /* 5 more headers! */
  #undef max
  	      redraw++;
  	    }
***************
*** 282,298 ****
  	  }
  #endif
  	  CleartoEOS();
! #ifdef DEBUG
! 	  if (! movement_command(ch))
  	    dprint(4, (debugfile, "\nCommand: %c [%d]\n\n", ch, ch));
! #endif
  
  	  set_error("");	/* clear error buffer */
  
! 	  MoveCursor(LINES-3,strlen(Prompt));
  
  	  switch (ch) {
  
  	    case '?' 	:  if (help(FALSE))
  	  		     redraw++;
  			   else
--- 191,210 ----
  	  }
  #endif
  	  CleartoEOS();
! 
! 	  if (isascii(ch) && isprint(ch)) {
  	    dprint(4, (debugfile, "\nCommand: %c [%d]\n\n", ch, ch));
! 	  } else {
! 	    dprint(4, (debugfile, "\nCommand: %d\n\n", ch, ch));
! 	  }
  
  	  set_error("");	/* clear error buffer */
  
! 	  MoveCursor(elm_LINES-3,strlen(Prompt));
  
  	  switch (ch) {
  
+ 	  case HELP_MARK:
  	    case '?' 	:  if (help(FALSE))
  	  		     redraw++;
  			   else
***************
*** 299,305 ****
  			     nufoot++;
  			   break;
  
! 	    case '$'    :  PutLine0(LINES-3, strlen(Prompt),
  			     catgets(elm_msg_cat, ElmSet, ElmResyncFolder,
  	    		     "Resynchronize folder"));
  			   redraw += resync();
--- 211,217 ----
  			     nufoot++;
  			   break;
  
! 	    case '$'    :  PutLine0(elm_LINES-3, strlen(Prompt),
  			     catgets(elm_msg_cat, ElmSet, ElmResyncFolder,
  	    		     "Resynchronize folder"));
  			   redraw += resync();
***************
*** 308,320 ****
  
  	    case '|'    :  Writechar('|'); 
  			   if (message_count < 1) {
! 			     error(catgets(elm_msg_cat, ElmSet, ElmNoMailToPipe,
! 			       "No mail to pipe!"));
  			     fflush(stdin);
  			   } else {
! 	    		     softkeys_off();
                               redraw += do_pipe();		
! 			     softkeys_on();
  			   }
  			   break;
  
--- 220,233 ----
  
  	    case '|'    :  Writechar('|'); 
  			   if (message_count < 1) {
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoMailToPipe,
! 					       "No mail to pipe!"));
  			     fflush(stdin);
  			   } else {
! 	    		     /* softkeys_off(); */
                               redraw += do_pipe();		
! 			     /* softkeys_on(); */
  			   }
  			   break;
  
***************
*** 325,337 ****
  #endif
  
  	    case '%'    :  if (current > 0) {
! 			     get_return(address, current-1);
  			     clear_error();
! 			     PutLine1(LINES,(COLUMNS-strlen(address))/2,
! 				      "%.78s", address);	
  			   } else {
! 			     error(catgets(elm_msg_cat, ElmSet, ElmNoMailReturnAddress,
! 			       "No mail to get return address of!")); 
  			     fflush(stdin);
  			   }
  			   break;
--- 238,252 ----
  #endif
  
  	    case '%'    :  if (current > 0) {
! 			     get_return(address, current-1, sizeof address);
  			     clear_error();
! 			     PutLineX(elm_LINES,
! 				      (elm_COLUMNS-strlen(address))/2,
! 				      FRM("%.78s"), address);	
  			   } else {
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoMailReturnAddress,
! 					       "No mail to get return address of!")); 
  			     fflush(stdin);
  			   }
  			   break;
***************
*** 339,357 ****
  	    case '<'    :  /* scan current message for calendar information */
  #ifdef ENABLE_CALENDAR
  			   if  (message_count < 1) {
! 			     error(catgets(elm_msg_cat, ElmSet, ElmNoMailToScan,
! 			       "No mail to scan!"));
  			     fflush(stdin);
  			   }
  			   else {
! 			       PutLine0(LINES-3, strlen(Prompt), 	
  			           catgets(elm_msg_cat, ElmSet, ElmScanForCalendar,
  				   "Scan message for calendar entries..."));
  			       scan_calendar();
  			   }
  #else
! 	 		   error(catgets(elm_msg_cat, ElmSet, ElmSorryNoCalendar,
! 			     "Sorry. Calendar function disabled."));
  			   fflush(stdin);
  #endif
  			   break;
--- 254,274 ----
  	    case '<'    :  /* scan current message for calendar information */
  #ifdef ENABLE_CALENDAR
  			   if  (message_count < 1) {
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoMailToScan,
! 					       "No mail to scan!"));
  			     fflush(stdin);
  			   }
  			   else {
! 			       PutLine0(elm_LINES-3, strlen(Prompt), 	
  			           catgets(elm_msg_cat, ElmSet, ElmScanForCalendar,
  				   "Scan message for calendar entries..."));
  			       scan_calendar();
  			   }
  #else
! 	 		   lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					     ElmSorryNoCalendar,
! 					     "Sorry. Calendar function disabled."));
  			   fflush(stdin);
  #endif
  			   break;
***************
*** 358,372 ****
  
  	    case 'a'    :  alias();
  			   redraw++;
! 			   define_softkeys(MAIN); 	break;
  			
! 	    case 'b'    :  PutLine0(LINES-3, strlen(Prompt), 
  			     catgets(elm_msg_cat, ElmSet, ElmBounceMessage,
  			     "Bounce message"));
  			   fflush(stdout);
  			   if (message_count < 1) {
! 	  		     error(catgets(elm_msg_cat, ElmSet, ElmNoMailToBounce,
! 			       "No mail to bounce!"));
  			     fflush(stdin);
  			   }
  			   else 
--- 275,290 ----
  
  	    case 'a'    :  alias();
  			   redraw++;
! 			   /* define_softkeys(MAIN); */	break;
  			
! 	    case 'b'    :  PutLine0(elm_LINES-3, strlen(Prompt), 
  			     catgets(elm_msg_cat, ElmSet, ElmBounceMessage,
  			     "Bounce message"));
  			   fflush(stdout);
  			   if (message_count < 1) {
! 	  		     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoMailToBounce,
! 					       "No mail to bounce!"));
  			     fflush(stdin);
  			   }
  			   else 
***************
*** 373,483 ****
  			     nufoot = remail();
  			   break;
  
! 	    case 'c'    :  PutLine0(LINES-3, strlen(Prompt), 
  			     catgets(elm_msg_cat, ElmSet, ElmChangeFolder,
  			     "Change folder"));
! 			   define_softkeys(CHANGE);
  			   redraw += change_file();
! 			   define_softkeys(MAIN);
  			   break;
  
  #ifdef ALLOW_MAILBOX_EDITING
! 	    case 'e'    :  PutLine0(LINES-3,strlen(Prompt),
  			     catgets(elm_msg_cat, ElmSet, ElmEditFolder,
  			     "Edit folder"));
  			   if (current > 0) {
  			     edit_mailbox();
- 	    		     if (cursor_control)
- 			       transmit_functions(ON);	/* insurance */
  	   		   }
  			   else {
! 			     error(catgets(elm_msg_cat, ElmSet, ElmFolderIsEmpty,
! 			       "Folder is empty!"));
  			     fflush(stdin);
  			   }
  			   break;
  #else
! 	    case 'e'    : error(catgets(elm_msg_cat, ElmSet, ElmNoFolderEdit,
! 		    "Folder editing isn't configured in this version of ELM."));
  			  fflush(stdin);
  			  break;
  #endif
! 		
! 	    case 'f'    :  PutLine0(LINES-3, strlen(Prompt),
  			     catgets(elm_msg_cat, ElmSet, ElmForward,
  			     "Forward"));
! 			   define_softkeys(YESNO);
  			   if (current > 0) {
  			     if(forward()) redraw++;
  			     else nufoot++;
  			   } else {
! 			     error(catgets(elm_msg_cat, ElmSet, ElmNoMailToForward,
! 			       "No mail to forward!"));
  			     fflush(stdin);
  			   }
! 			   define_softkeys(MAIN);
  			   break;
  
! 	    case 'g'    :  PutLine0(LINES-3,strlen(Prompt),
  			     catgets(elm_msg_cat, ElmSet, ElmGroupReply,
  			     "Group reply"));
  			   fflush(stdout);
  			   if (current > 0) {
  			     if (headers[current-1]->status & FORM_LETTER) {
! 			       error(catgets(elm_msg_cat, ElmSet, ElmCantGroupReplyForm,
! 				 "Can't group reply to a Form!!"));
  			       fflush(stdin);
  			     }
  			     else {
! 			       define_softkeys(YESNO);
  			       redraw += reply_to_everyone();	
! 			       define_softkeys(MAIN);
  			     }
  			   }
  			   else {
! 			     error(catgets(elm_msg_cat, ElmSet, ElmNoMailToReply,
! 			       "No mail to reply to!")); 
  			     fflush(stdin);
  			   }
  			   break;
  
! 	    case 'h'    :  if (filter)
! 			     PutLine0(LINES-3, strlen(Prompt), 
  			       catgets(elm_msg_cat, ElmSet, ElmMessageWithHeaders,
  			       "Message with headers..."));
  			   else
! 			     PutLine0(LINES-3, strlen(Prompt),
  			       catgets(elm_msg_cat, ElmSet, ElmDisplayMessage,
  			       "Display message"));
  			   if(current > 0) {
  			     fflush(stdout);
! 			     j = filter;
! 			     filter = FALSE;
  			     i = show_msg(current);
  			     while (i)
  				i = process_showmsg_cmd(i);
! 			     filter = j;
  			     redraw++;
  			     (void)get_page(current);
  			   } else
! 			     error(catgets(elm_msg_cat, ElmSet, ElmNoMailToRead,
! 			       "No mail to read!"));
  			   break;
  
! 	    case 'm'    :  PutLine0(LINES-3, strlen(Prompt),
  			     catgets(elm_msg_cat, ElmSet, ElmMail,
  			     "Mail"));
!  			   redraw += send_msg("", "", "", TRUE,allow_forms,FALSE); 
! 			   break;
  
  	    case ' '    : 
  	    case ctrl('J'):
! 	    case ctrl('M'): PutLine0(LINES-3, strlen(Prompt), 
! 			      catgets(elm_msg_cat, ElmSet, ElmDisplayMessage,
! 	    		      "Display message"));	
  			   fflush(stdout);
  			   if(current > 0 ) {
! 			     define_softkeys(READ);
  
  			     i = show_msg(current);
  			     while (i)
--- 291,446 ----
  			     nufoot = remail();
  			   break;
  
! 	    case 'c'    :  PutLine0(elm_LINES-3, strlen(Prompt), 
  			     catgets(elm_msg_cat, ElmSet, ElmChangeFolder,
  			     "Change folder"));
! 	                   /* define_softkeys(CHANGE); */
  			   redraw += change_file();
! 			   /* define_softkeys(MAIN); */
  			   break;
  
  #ifdef ALLOW_MAILBOX_EDITING
! 	    case 'e'    :  if (user_level < 2) {
! 				lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 						  ElmNoFolderEditing,
! 						  "You are not experienced to use folder editing"));
! 				fflush(stdin);
! 				break;
! 			   }
! 			   PutLine0(elm_LINES-3,strlen(Prompt),
  			     catgets(elm_msg_cat, ElmSet, ElmEditFolder,
  			     "Edit folder"));
  			   if (current > 0) {
  			     edit_mailbox();
  	   		   }
  			   else {
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmFolderIsEmpty,
! 					       "Folder is empty!"));
  			     fflush(stdin);
  			   }
  			   break;
  #else
! 	    case 'e'    : lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					    ElmNoFolderEdit,
! 					    "Folder editing isn't configured in this version of ELM."));
  			  fflush(stdin);
  			  break;
  #endif
! #ifdef USE_PGP
! 	    case ctrl('E'):
!               if (message_count < 1)
!                 lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNoMailInFolder,
! 				  "There is no mail in this folder!"));
!               else {
!   	        Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmExtractPGPKey,
! 					"Extract PGP public key"));
! 	        if (headers[current-1]->pgp & PGP_PUBLIC_KEY)
! 	  	  redraw = pgp_extract_public_key();
! 	        else
! 		  lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 				    ElmNoPgpPublicKeys,
! 				    "This message does not contain PGP public keys!"));
!               }
! 	      break;
! 
!            case ctrl('F'):
! 	      PutLine0(elm_LINES-3,strlen(Prompt),"Forget PGP passphrase");
!               pgp_void_passphrase();
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 				ElmPassphraseForgotten,
! 				"Passphrase forgotten!"));
!               break;
! #endif
! 
! 	    case 'f'    :  PutLine0(elm_LINES-3, strlen(Prompt),
  			     catgets(elm_msg_cat, ElmSet, ElmForward,
  			     "Forward"));
! 	                   /* define_softkeys(YESNO); */
  			   if (current > 0) {
  			     if(forward()) redraw++;
  			     else nufoot++;
  			   } else {
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoMailToForward,
! 					       "No mail to forward!"));
  			     fflush(stdin);
  			   }
! 			   /* define_softkeys(MAIN); */
  			   break;
  
! 	    case 'g'    :  PutLine0(elm_LINES-3,strlen(Prompt),
  			     catgets(elm_msg_cat, ElmSet, ElmGroupReply,
  			     "Group reply"));
  			   fflush(stdout);
  			   if (current > 0) {
  			     if (headers[current-1]->status & FORM_LETTER) {
! 			       lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 						 ElmCantGroupReplyForm,
! 						 "Can't group reply to a Form!!"));
  			       fflush(stdin);
  			     }
  			     else {
! 			       /* define_softkeys(YESNO); */
  			       redraw += reply_to_everyone();	
! 			       /* define_softkeys(MAIN); */
  			     }
  			   }
  			   else {
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoMailToReply,
! 					       "No mail to reply to!")); 
  			     fflush(stdin);
  			   }
  			   break;
  
! 	    case 'h'    :  if (elm_filter)
! 			     PutLine0(elm_LINES-3, strlen(Prompt), 
  			       catgets(elm_msg_cat, ElmSet, ElmMessageWithHeaders,
  			       "Message with headers..."));
  			   else
! 			     PutLine0(elm_LINES-3, strlen(Prompt),
  			       catgets(elm_msg_cat, ElmSet, ElmDisplayMessage,
  			       "Display message"));
  			   if(current > 0) {
  			     fflush(stdout);
! 			     j = elm_filter;
! 			     elm_filter = FALSE;
  			     i = show_msg(current);
  			     while (i)
  				i = process_showmsg_cmd(i);
! 			     elm_filter = j;
  			     redraw++;
  			     (void)get_page(current);
  			   } else
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoMailToRead,
! 					       "No mail to read!"));
  			   break;
  
! #ifdef USE_PGP
!             case ctrl('K'):
! 	                   PutLine0(elm_LINES-3, strlen(Prompt), 
! 				    "Mail PGP public key");
! 	                   redraw = pgp_mail_public_key ();
!                            break;
! #endif
! 	    case 'm'    :  PutLine0(elm_LINES-3, strlen(Prompt),
  			     catgets(elm_msg_cat, ElmSet, ElmMail,
  			     "Mail"));
!  			   redraw += send_msg("", "", "", MAIL_EDIT_MSG,
! 					      allow_forms);
! 	                   break;
  
  	    case ' '    : 
  	    case ctrl('J'):
! 	    case ctrl('M'): PutLine0(elm_LINES-3, strlen(Prompt), 
! 				     catgets(elm_msg_cat, ElmSet, 
! 					     ElmDisplayMessage,
! 					     "Display message"));	
  			   fflush(stdout);
  			   if(current > 0 ) {
! 			     /* define_softkeys(READ); */
  
  			     i = show_msg(current);
  			     while (i)
***************
*** 485,502 ****
  			     redraw++;
  			     (void)get_page(current);
  			   } else
! 			     error(catgets(elm_msg_cat, ElmSet, ElmNoMailToRead,
! 			       "No mail to read!"));
  			   break;
  
! 	    case 'n'    :  PutLine0(LINES-3,strlen(Prompt),
! 			     catgets(elm_msg_cat, ElmSet, ElmNextMessage,
! 			     "Next Message"));
  			   fflush(stdout);
! 			   define_softkeys(READ);
  
  			   if(current > 0 ) {
! 			     define_softkeys(READ);
  
  			     i = show_msg(current);
  			     while (i)
--- 448,467 ----
  			     redraw++;
  			     (void)get_page(current);
  			   } else
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoMailToRead,
! 					       "No mail to read!"));
  			   break;
  
! 	    case 'n'    :  PutLine0(elm_LINES-3,strlen(Prompt),
! 				    catgets(elm_msg_cat, ElmSet, 
! 					    ElmNextMessage,
! 					    "Next Message"));
  			   fflush(stdout);
! 			   /* define_softkeys(READ); */
  
  			   if(current > 0 ) {
! 			     /* define_softkeys(READ); */
  
  			     i = show_msg(current);
  			     while (i)
***************
*** 506,518 ****
  			       current = message_count;
  			     (void)get_page(current);
  			   } else
! 			     error(catgets(elm_msg_cat, ElmSet, ElmNoMailToRead,
! 			       "No mail to read!"));
  			   break;
  
! 	    case 'o'    :  PutLine0(LINES-3, strlen(Prompt),
! 			     catgets(elm_msg_cat, ElmSet, ElmOptions,
! 			     "Options"));
  			   if((i=options()) > 0)
  			     get_page(current);
  			   else if(i < 0)
--- 471,484 ----
  			       current = message_count;
  			     (void)get_page(current);
  			   } else
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoMailToRead,
! 					       "No mail to read!"));
  			   break;
  
! 	    case 'o'    :  PutLine0(elm_LINES-3, strlen(Prompt),
! 				    catgets(elm_msg_cat, ElmSet, ElmOptions,
! 					    "Options"));
  			   if((i=options()) > 0)
  			     get_page(current);
  			   else if(i < 0)
***************
*** 520,549 ****
  			   redraw++;	/* always fix da screen... */
  			   break;
  
! 	    case 'p'    :  PutLine0(LINES-3, strlen(Prompt),
! 			     catgets(elm_msg_cat, ElmSet, ElmPrintMail,
! 			     "Print mail"));
  			   fflush(stdout);
  			   if (message_count < 1) {
! 			     error(catgets(elm_msg_cat, ElmSet, ElmNoMailToPrint,
! 			       "No mail to print!"));
  			     fflush(stdin);
  			   } else if (print_msg(TRUE) != 0)
  			     redraw++;
  			   break;
  
! 	    case 'q'    :  PutLine0(LINES-3, strlen(Prompt),
! 			     catgets(elm_msg_cat, ElmSet, ElmQuit,
! 			     "Quit"));
  
  			   if (mailfile_size != bytes(cur_folder)) {
! 			     error(catgets(elm_msg_cat, ElmSet, ElmNewMailQuitCancelled,
! 				"New Mail!  Quit canceled..."));
  			     fflush(stdin);
  
  			     if (folder_type == SPOOL) {
! 				fflush (mailfile);
! 				unlock();
  			     }
  			   }
  			   else
--- 486,516 ----
  			   redraw++;	/* always fix da screen... */
  			   break;
  
! 	    case 'p'    :  PutLine0(elm_LINES-3, strlen(Prompt),
! 				    catgets(elm_msg_cat, ElmSet, ElmPrintMail,
! 					    "Print mail"));
  			   fflush(stdout);
  			   if (message_count < 1) {
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoMailToPrint,
! 					       "No mail to print!"));
  			     fflush(stdin);
  			   } else if (print_msg(TRUE) != 0)
  			     redraw++;
  			   break;
  
! 	    case 'q'    :  PutLine0(elm_LINES-3, strlen(Prompt),
! 				    catgets(elm_msg_cat, ElmSet, ElmQuit,
! 					    "Quit"));
  
  			   if (mailfile_size != bytes(cur_folder)) {
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNewMailQuitCancelled,
! 					       "New Mail!  Quit canceled..."));
  			     fflush(stdin);
  
  			     if (folder_type == SPOOL) {
! 				unlock(0);
  			     }
  			   }
  			   else
***************
*** 551,566 ****
  
  			   break;
  
! 	    case 'Q'    :  PutLine0(LINES-3, strlen(Prompt),
! 			     catgets(elm_msg_cat, ElmSet, ElmQuickQuit,
! 			     "Quick quit"));
  
  			   if (mailfile_size != bytes(cur_folder)) {
! 			     error(catgets(elm_msg_cat, ElmSet, ElmNewMailQuickQuitCancelled,
! 			       "New Mail!  Quick Quit canceled..."));
  	  		     if (folder_type == SPOOL) {
! 				fflush (mailfile);
! 				unlock();
  			     }
  			   }
  			   else
--- 518,533 ----
  
  			   break;
  
! 	    case 'Q'    :  PutLine0(elm_LINES-3, strlen(Prompt),
! 				    catgets(elm_msg_cat, ElmSet, ElmQuickQuit,
! 					    "Quick quit"));
  
  			   if (mailfile_size != bytes(cur_folder)) {
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNewMailQuickQuitCancelled,
! 					       "New Mail!  Quick Quit canceled..."));
  	  		     if (folder_type == SPOOL) {
! 				unlock(0);
  			     }
  			   }
  			   else
***************
*** 568,584 ****
  
  			   break;
  
! 	    case 'r'    :  PutLine0(LINES-3, strlen(Prompt), 
! 			     catgets(elm_msg_cat, ElmSet, ElmReplyToMessage,
! 			     "Reply to message"));
  			   if (current > 0) 
  			     redraw += reply();	
  			   else {
! 			     error(catgets(elm_msg_cat, ElmSet, ElmNoMailToReplyTo,
! 			       "No mail to reply to!")); 
  			     fflush(stdin);
  			   }
! 			   softkeys_on();
  			   break;
  
  	    case '>'    : /** backwards compatibility **/
--- 535,553 ----
  
  			   break;
  
! 	  case 'r'    :  PutLine0(elm_LINES-3, strlen(Prompt), 
! 				  catgets(elm_msg_cat, ElmSet, 
! 					  ElmReplyToMessage,
! 					  "Reply to message"));
  			   if (current > 0) 
  			     redraw += reply();	
  			   else {
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoMailToReplyTo,
! 					       "No mail to reply to!")); 
  			     fflush(stdin);
  			   }
! 			   /* softkeys_on(); */
  			   break;
  
  	    case '>'    : /** backwards compatibility **/
***************
*** 586,610 ****
  	    case 'C'	:
  	    case 's'    :  if  (message_count < 1) {
  			     if (ch != 'C')
! 			       error(catgets(elm_msg_cat, ElmSet, ElmNoMailToSave,
! 				 "No mail to save!"));
  			     else
! 			       error(catgets(elm_msg_cat, ElmSet, ElmNoMailToCopy,
! 				 "No mail to copy!"));
  			     fflush(stdin);
  			   }
  			   else {
  			     if (ch != 'C')
! 			       PutLine0(LINES-3, strlen(Prompt),
! 				      catgets(elm_msg_cat, ElmSet, ElmSaveToFolder,
! 				      "Save to folder"));
  			     else
! 			       PutLine0(LINES-3, strlen(Prompt),
! 				      catgets(elm_msg_cat, ElmSet, ElmCopyToFolder,
! 				      "Copy to folder"));
! 			     PutLine0(LINES-3,COLUMNS-40,
! 			        catgets(elm_msg_cat, ElmSet, ElmUseForHelp,
! 				"(Use '?' for help)"));
  			     if (save(&redraw, FALSE, (ch != 'C'))
  				 && resolve_mode && ch != 'C') {
  			       if((i=next_message(current-1, TRUE)) != -1) {
--- 555,584 ----
  	    case 'C'	:
  	    case 's'    :  if  (message_count < 1) {
  			     if (ch != 'C')
! 			       lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 						 ElmNoMailToSave,
! 						 "No mail to save!"));
  			     else
! 			       lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 						 ElmNoMailToCopy,
! 						 "No mail to copy!"));
  			     fflush(stdin);
  			   }
  			   else {
  			     if (ch != 'C')
! 			       PutLine0(elm_LINES-3, strlen(Prompt),
! 					catgets(elm_msg_cat, ElmSet, 
! 						ElmSaveToFolder,
! 						"Save to folder"));
  			     else
! 			       PutLine0(elm_LINES-3, strlen(Prompt),
! 					catgets(elm_msg_cat, ElmSet, 
! 						ElmCopyToFolder,
! 						"Copy to folder"));
! 			     PutLine0(elm_LINES-3,elm_COLUMNS-40,
! 				      catgets(elm_msg_cat, ElmSet, 
! 					      ElmUseForHelp,
! 					      "(Use '?' for help)"));
  			     if (save(&redraw, FALSE, (ch != 'C'))
  				 && resolve_mode && ch != 'C') {
  			       if((i=next_message(current-1, TRUE)) != -1) {
***************
*** 613,632 ****
  			       }
  			     }
  			   }
! 			   ClearLine(LINES-2);		
  			   break;
! 
! 	    case 'X'    :  PutLine0(LINES-3, strlen(Prompt),
! 			     catgets(elm_msg_cat, ElmSet, ElmQuickExit,
! 			     "Quick Exit"));
                             fflush(stdout);
  			   leave(0);
  			   break;
! 
  	    case ctrl('Q') :
! 	    case 'x'    :  PutLine0(LINES-3, strlen(Prompt),
! 			     catgets(elm_msg_cat, ElmSet, ElmExit,
! 			     "Exit"));  
                             fflush(stdout);
  			   exit_prog();
  			   break;
--- 587,630 ----
  			       }
  			     }
  			   }
! 			   ClearLine(elm_LINES-2);		
  			   break;
! #ifdef MIME
! 	    case 'v'    :  if (headers) {	      
! 	                    if (headers[current-1]->status & MIME_MESSAGE) {
! 			      mime_warnings(headers[current-1]);
! 			      attach_parse (headers[current-1], mailfile);
! 			      if (headers[current-1]->mime_rec.parts)
! 				(void) attach_menu (headers[current-1]->
! 						    mime_rec.parts, TRUE);
! 			      else 
! 				/* So we can save mail in decoded ... */
! 				(void) attach_menu (&(headers[current-1]->
! 						      mime_rec),TRUE);
! 			      redraw++;
! 			    }
!                              else
!                                lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 						 ElmNoMIMEMessage,
! 						 "This is not a MIME message!"));
!                            }
!                            else
!                              lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoMessages,
! 					       "There are no messages!"));
!                            break;
! #endif
! 	    case 'X'    :  PutLine0(elm_LINES-3, strlen(Prompt),
! 				    catgets(elm_msg_cat, ElmSet, ElmQuickExit,
! 					    "Quick Exit"));
                             fflush(stdout);
  			   leave(0);
  			   break;
! 		
  	    case ctrl('Q') :
! 	    case 'x'    :  PutLine0(elm_LINES-3, strlen(Prompt),
! 				    catgets(elm_msg_cat, ElmSet, ElmExit,
! 					    "Exit"));  
                             fflush(stdout);
  			   exit_prog();
  			   break;
***************
*** 641,648 ****
  			    redraw++;	
  			  } 
  			  else {
! 			    error(catgets(elm_msg_cat, ElmSet, ElmNoMailToCheck,
! 			      "No mail to check."));
  			    fflush(stdin);
  			  }
  			  break;
--- 639,647 ----
  			    redraw++;	
  			  } 
  			  else {
! 			    lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					      ElmNoMailToCheck,
! 					      "No mail to check."));
  			    fflush(stdin);
  			  }
  			  break;
***************
*** 664,675 ****
  	    show_current();
  	  else if (nufoot) {
  	    if (mini_menu) {
! 	      MoveCursor(LINES-7, 0);  
                CleartoEOS();
  	      show_menu();
  	    }
  	    else {
! 	      MoveCursor(LINES-4, 0);
  	      CleartoEOS();
  	    }
  	    show_last_error();	/* for those operations that have to
--- 663,674 ----
  	    show_current();
  	  else if (nufoot) {
  	    if (mini_menu) {
! 	      MoveCursor(elm_LINES-7, 0);  
                CleartoEOS();
  	      show_menu();
  	    }
  	    else {
! 	      MoveCursor(elm_LINES-4, 0);
  	      CleartoEOS();
  	    }
  	    show_last_error();	/* for those operations that have to
***************
*** 688,701 ****
  	register int i, j;
  	char     buffer[SLEN];
  
  	ClearScreen();
  
! 	PutLine2(0,0,"Current message number = %d\t\t%d message(s) total\n",
! 		current, message_count);
! 	PutLine2(2,0,"Header_page = %d           \t\t%d possible page(s)\n",
! 		header_page, (int) (message_count / headers_per_page) + 1);
! 
! 	PutLine1(4,0,"\nCurrent mail file is %s.\n\r\n", cur_folder);
  
  	i = header_page*headers_per_page;	/* starting header */
  
--- 687,708 ----
  	register int i, j;
  	char     buffer[SLEN];
  
+ redraw:
  	ClearScreen();
  
! 	PutLineX(0,0,CATGETS(elm_msg_cat, ElmSet, 
! 			     ElmDbxCurrMsgNum,
! 			     "Current message number = %d\t\t%d message(s) total\n"),
! 		 current, message_count);
! 	PutLineX(2,0,CATGETS(elm_msg_cat, ElmSet, 
! 			     ElmDbxHdrPage,
! 			     "Header_page = %d           \t\t%d possible page(s)\n"),
! 		 header_page, (int) (message_count / headers_per_page) + 1);
! 
! 	PutLineX(4,0,CATGETS(elm_msg_cat, ElmSet, 
! 			     ElmDbxCurrMailFile,
! 			     "\nCurrent mail file is %s.\n\r\n"), 
! 		 cur_folder);
  
  	i = header_page*headers_per_page;	/* starting header */
  
***************
*** 702,725 ****
  	if ((j = i + (headers_per_page-1)) >= message_count) 
  	  j = message_count-1;
  
! 	Write_to_screen(
! "Num      From                    Subject                Lines   Offset  Content\n\r\n\r",0);
! 
  	while (i <= j) {
! 	   sprintf(buffer, 
! 	   "%3d %-16.16s %-35.35s %4d %8d %8d\n\r",
! 		    i+1,
! 		    headers[i]->from, 
! 		    headers[i]->subject,
! 		    headers[i]->lines,
! 		    headers[i]->offset,
! 		    headers[i]->content_length);
! 	    Write_to_screen(buffer, 0);
  	  i++;
  	}
  	
! 	PutLine0(LINES,0,"Press any key to return.");
! 	(void) ReadCh();
  }
  
  
--- 709,745 ----
  	if ((j = i + (headers_per_page-1)) >= message_count) 
  	  j = message_count-1;
  
! 	Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmDebugHeader,
! 				"Num      From                    Subject                Lines   Offset  Content\n\r\n\r"));
! 	
  	while (i <= j) {
! 	  
! 	  char * From = headers[i]->env_from;
! 
! 	  if (headers[i]->from) {
! 	    if (headers[i]->from->fullname &&
! 		headers[i]->from->fullname[0])
! 	      From = headers[i]->from->fullname;
! 	    else if (headers[i]->from->addr &&
! 		     headers[i]->from->addr[0])
! 	      From = headers[i]->from->addr;
! 	  }
! 
! 	  Write_to_screen(FRM("%3d %-16.16s %-35.35s %4d %8d %8d\n\r"),
! 			  i+1,
! 			  From, 
! 			  headers[i]->subject,
! 			  headers[i]->lines,
! 			  headers[i]->offset,
! 			  headers[i]->content_length);
! 	  
  	  i++;
  	}
  	
! 	PutLineX(elm_LINES,0,CATGETS(elm_msg_cat, ElmSet, 
! 			     ElmDbxPressAnyKey,"Press any key to return."));
! 	if (REDRAW_MARK == ReadCh(REDRAW_MARK))
! 	  goto redraw;
  }
  
  
***************
*** 732,802 ****
  	time_t header_time;
  	register struct header_rec *current_header = headers[current-1];
  
  	ClearScreen();
  
! 	Write_to_screen("\t\t\t----- Message %d -----\n\r\n\r\n\r\n\r", 1,
! 		current);
  
! 	Write_to_screen(     "Lines : %-5d\t\t\tStatus: A  C  D  E  F  M  D  N  N  O  P  T  U  V\n\r", 1,
! 		current_header->lines);
! 	Write_to_screen("Content-Length: %-12d\t        c  o  e  x  o  i  e  p  e  l  r  a  r  i\n\r", 1,
! 		current_header->content_length);
! 	Write_to_screen(     "            \t\t\t        t  n  l  p  r  m  c  l  w  d  i  g  g  s\n\r", 0);
! 	Write_to_screen(     "            \t\t\t        n  f  d  d  m  e  o  a        v  d  n  i\n\r", 0);
! 
! 	sprintf(buffer, 
! 		"\n\rOffset: %ld\t\t\t        %d  %d  %d  %d  %d  %d  %d  %d",
! 		current_header->offset,
! 		(current_header->status & ACTION) != 0,
! 		(current_header->status & CONFIDENTIAL) != 0,
! 		(current_header->status & DELETED) != 0,
! 		(current_header->status & EXPIRED) != 0,
! 		(current_header->status & FORM_LETTER) != 0,
! 		(current_header->status & MIME_MESSAGE) != 0,
! 		(current_header->status & MIME_NEEDDECOD) != 0,
! 		(current_header->status & MIME_NOTPLAIN) != 0);
! 	sprintf(buffer + strlen(buffer),
! 		"  %d  %d  %d  %d  %d  %d\n",
! 		(current_header->status & NEW) != 0,
! 		(current_header->status & UNREAD) != 0,
! 		(current_header->status & PRIVATE) != 0,
! 		(current_header->status & TAGGED) != 0,
! 		(current_header->status & URGENT) != 0,
! 		(current_header->status & VISIBLE) != 0);
! 
! 	Write_to_screen(buffer, 0);
! 
! 	sprintf(buffer, "\n\rReceived on: %s\r",
! 		asctime(localtime(&current_header->received_time)));
! 	Write_to_screen(buffer, 0);
  
  	header_time = current_header->time_sent + current_header->tz_offset;
! 	sprintf(buffer, "Message sent on: %s\rFrom timezone: %s (%d)\n\r",
! 		asctime(gmtime(&header_time)),
! 		current_header->time_zone,
! 		current_header->tz_offset);
! 	Write_to_screen(buffer, 0);
  	
! 	Write_to_screen("From: %s\n\rSubject: %s", 2,
! 		current_header->from,
! 		current_header->subject);
! 
! 	Write_to_screen("\n\rPrimary Recipient: %s\n\rInternal Index Reference Number = %d\n\r", 2,
! 		current_header->to,
! 		current_header->index_number);
! 
! 	Write_to_screen("Message-ID: %s\n\r", 1,
! 		strlen(current_header->messageid) > 0 ? 
! 		current_header->messageid : "<none>");
  
! 	Write_to_screen("Status: %s\n\r", 1, current_header->mailx_status);
  	
! 	PutLine0(LINES,0,"Please Press any key to return.");
! 	(void) ReadCh();
  }
  
! do_check_only(to_whom)
! char *to_whom;
  {
  	char buffer[VERY_LONG_STRING], *msg;
  
--- 752,872 ----
  	time_t header_time;
  	register struct header_rec *current_header = headers[current-1];
  
+ redraw:
  	ClearScreen();
  
! 	Write_to_screen(FRM("\t\t\t----- Message %d -----\n\r\n\r\n\r\n\r"), 
! 			current);
  
! 	Write_to_screen(FRM("Lines: %-17dStatus: A  C  D  E  F  N  P  T  U  V  O  R  M  P  U  N\n\r"), 
! 			current_header->lines);
! 	Write_to_screen(FRM("Content-Length: %-16dc  o  e  x  o  e  r  a  r  i  l  e  i  r  s  H\n\r"), 
! 			current_header->content_length);
! 	Write_to_screen(FRM("Binary: %-24dt  n  l  p  r  w  i  g  g  s  d  p  m  e  u  d\n\r"), 
! 			current_header->binary);
! 	Write_to_screen(FRM("\t\t\t\tn  f  d  d  m     v  d  n  i     l  e  M  p  r\n\r"));
! 
! 	Write_to_screen(FRM("\n\rOffset: %-22ld%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d\n"),
! 			current_header->offset,
! 			(current_header->status & ACTION) != 0,
! 			(current_header->status & CONFIDENTIAL) != 0,
! 			(current_header->status & DELETED) != 0,
! 			(current_header->status & EXPIRED) != 0,
! 			(current_header->status & FORM_LETTER) != 0,
! 			(current_header->status & NEW) != 0,
! 			(current_header->status & PRIVATE) != 0,
! 			(current_header->status & TAGGED) != 0,
! 			(current_header->status & URGENT) != 0,
! 			(current_header->status & VISIBLE) != 0,
! 			(current_header->status & UNREAD) != 0,
! 			(current_header->status & REPLIED) != 0,
! 			(current_header->status & MIME_MESSAGE) != 0,
! 			(current_header->status & PRE_MIME_CONTENT) != 0,
! 			(current_header->status & MIME_UNSUPPORTED) != 0,
! 			(current_header->status & NOHDRENCODING) != 0);
! 	
!         Write_to_screen(FRM("\n\rReceived on: %s\r"),
! 			asctime(localtime(&current_header->received_time)));
!       
  
  	header_time = current_header->time_sent + current_header->tz_offset;
! 	Write_to_screen(FRM("\rMessage sent on: %s\r\nFrom timezone: %s (%d)\n\r"),
! 			asctime(gmtime(&header_time)),
! 			current_header->time_zone,
! 			current_header->tz_offset);
  	
! 	Write_to_screen(FRM("(Env) From: %s\n\r"), 
! 			current_header->env_from);
! 
! 	if (current_header->from) {
! 	  int first = 1;
! 	  struct addr_item *p;
! 	  for (p = current_header->from; p->fullname && p->addr; p++) {
! 	    if (first)
! 	      Write_to_screen(FRM(     "From: "));
! 	    else
! 	      Write_to_screen(FRM(",\r\n      "));
! 	    Write_to_screen(FRM("%-30s <%s>"),p->fullname,p->addr);
! 	    first = 0;
! 	  }
! 	  Write_to_screen(FRM("\r\n"));
! 	}
! 
! 	Write_to_screen(FRM("Subject: %s\n\rInternal Index Reference Number = %d\n\r"),
! 			current_header->subject,
! 			current_header->index_number);
! 
! 	if (current_header->to) {
! 	  int first = 1;
! 	  struct addr_item *p;
! 	  for (p = current_header->to; p->fullname && p->addr; p++) {
! 	    if (first)
! 	      Write_to_screen(FRM(     "To: "));
! 	    else
! 	      Write_to_screen(FRM(",\r\n    "));
! 	    Write_to_screen(FRM("%-30s <%s>"),p->fullname,p->addr);
! 	    first = 0;
! 	  }
! 	  Write_to_screen(FRM("\r\n"));
! 	}
! 
! 	if (current_header->cc) {
! 	  int first = 1;
! 	  struct addr_item *p;
! 	  for (p = current_header->cc; p->fullname && p->addr; p++) {
! 	    if (first)
! 	      Write_to_screen(FRM(     "CC: "));
! 	    else
! 	      Write_to_screen(FRM(",\r\n    "));
! 	    Write_to_screen(FRM("%-30s <%s>"),p->fullname,p->addr);
! 	    first = 0;
! 	  }
! 	  Write_to_screen(FRM("\r\n"));
! 	}
! 
  
! 	Write_to_screen(FRM("Message-ID: %s\n\r"), 
! 			strlen(current_header->messageid) > 0 ? 
! 			current_header->messageid : "<none>");
! 
! 	Write_to_screen(FRM("Status: %s\n\r"),  
! 			current_header->mailx_status);
! 
! #ifdef MIME
! 	Write_to_screen(FRM("Content-Transfer-Encoding: %s\n\r"),
! 			ENCODING(current_header->mime_rec.encoding));
! #endif
  	
! 	PutLineX(elm_LINES,0,CATGETS(elm_msg_cat, ElmSet, 
! 			     ElmDbxPressAnyKey,
! 				     "Please Press any key to return."));
! 	if (REDRAW_MARK == ReadCh(REDRAW_MARK))
! 	  goto redraw;
  }
  
! static void do_check_only(to_whom, size_to_whom)
!      char *to_whom;
!      int size_to_whom;
  {
  	char buffer[VERY_LONG_STRING], *msg;
  
***************
*** 803,809 ****
  	dprint(3, (debugfile, "Check-only: checking \n-> \"%s\"\n", 
  		format_long(to_whom, 3)));
  
! 	if (build_address(strip_commas(to_whom), buffer)) {
  
  	    msg = catgets(elm_msg_cat, ElmSet, ElmExpandsTo,
  			  "Expands to: ");
--- 873,880 ----
  	dprint(3, (debugfile, "Check-only: checking \n-> \"%s\"\n", 
  		format_long(to_whom, 3)));
  
! 	if (build_address(strip_commas(to_whom), buffer,
! 			  size_to_whom, sizeof buffer)) {
  
  	    msg = catgets(elm_msg_cat, ElmSet, ElmExpandsTo,
  			  "Expands to: ");
***************
*** 848,855 ****
  static char *no_mail = NULL;
  static char *no_aliases = NULL;
  
  motion(ch)
! char ch;
  {
  	/* Consolidated the standard menu navigation and delete/tag
  	 * commands to a function.                                   */
--- 919,927 ----
  static char *no_mail = NULL;
  static char *no_aliases = NULL;
  
+ void
  motion(ch)
!      int ch;
  {
  	/* Consolidated the standard menu navigation and delete/tag
  	 * commands to a function.                                   */
***************
*** 866,887 ****
  
  	switch (ch) {
  
! 	    case '/'    :  /* scan mbox or aliases for string */
! 			   if  (message_count < 1) {
! 			     error1(catgets(elm_msg_cat, ElmSet,
! 				ElmNoItemToScan, "No %s to scan!"), items);
! 			     fflush(stdin);
! 			   }
! 			   else if (pattern_match())
! 			     nucurr = get_page(current);
! 			   else {
! 			     error(catgets(elm_msg_cat, ElmSet, ElmPatternNotFound,
! 			       "pattern not found!"));
! 			     fflush(stdin);
! 			   }
! 			   break;
  
  next_page:
  	    case '+'	:  /* move to next page if we're not on the last */
  			   if((selected &&
  			     ((header_page+1)*headers_per_page < selected))
--- 938,964 ----
  
  	switch (ch) {
  
! 	case FIND_MARK:
! 	case '/'    :  /* scan mbox or aliases for string */
! 	              if  (message_count < 1) {
! 			lib_error(CATGETS(elm_msg_cat, ElmSet,
! 					  ElmNoItemToScan, "No %s to scan!"), 
! 				  items);
! 			fflush(stdin);
! 		      }
! 		      else if (pattern_match())
! 			nucurr = get_page(current);
! 		      else {
! 			lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					  ElmPatternNotFound,
! 					  "pattern not found!"));
! 			fflush(stdin);
! 		      }
! 		      break;
  
  next_page:
+ 	case PAGEDOWN_MARK :
+ 	case RIGHT_MARK :
  	    case '+'	:  /* move to next page if we're not on the last */
  			   if((selected &&
  			     ((header_page+1)*headers_per_page < selected))
***************
*** 900,910 ****
  				 current = header_page * headers_per_page + 1;
  			     }
  			   } else
! 			     error(catgets(elm_msg_cat, ElmSet, ElmAlreadyOnLastPage,
! 			       "Already on last page."));
  			   break;
  
  prev_page:
  	    case '-'	:  /* move to prev page if we're not on the first */
  			   if(header_page > 0) {
  			     header_page--;
--- 977,990 ----
  				 current = header_page * headers_per_page + 1;
  			     }
  			   } else
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmAlreadyOnLastPage,
! 					       "Already on last page."));
  			   break;
  
  prev_page:
+ 	case PAGEUP_MARK :
+ 	case LEFT_MARK  :
  	    case '-'	:  /* move to prev page if we're not on the first */
  			   if(header_page > 0) {
  			     header_page--;
***************
*** 919,929 ****
  				 current = header_page * headers_per_page + 1;
  			     }
  			   } else
! 			     error(catgets(elm_msg_cat, ElmSet, ElmAlreadyOnFirstPage,
! 			       "Already on first page."));
  			   break;
  
  first_msg:
  	    case '='    :  if (selected)
  			     current = visible_to_index(1)+1;
  			   else
--- 999,1011 ----
  				 current = header_page * headers_per_page + 1;
  			     }
  			   } else
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmAlreadyOnFirstPage,
! 					       "Already on first page."));
  			   break;
  
  first_msg:
+ 	case HOME_MARK:
  	    case '='    :  if (selected)
  			     current = visible_to_index(1)+1;
  			   else
***************
*** 945,952 ****
  	    case ctrl('D') :
  	    case '^'    :
  	    case 'd'    :  if (message_count < 1) {
! 			     error1(catgets(elm_msg_cat, ElmSet, ElmNoItemToDelete,
! 			       "No %s to delete!"), item);
  			     fflush(stdin);
  			   }
  			   else {
--- 1027,1036 ----
  	    case ctrl('D') :
  	    case '^'    :
  	    case 'd'    :  if (message_count < 1) {
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoItemToDelete,
! 					       "No %s to delete!"), 
! 				       item);
  			     fflush(stdin);
  			   }
  			   else {
***************
*** 972,990 ****
  			       current = i+1;
  			       nucurr = get_page(current);
  			     } else
! 			       error1(catgets(elm_msg_cat, ElmSet, ElmNoMoreItemBelow,
! 				 "No more %s below."), items);
  			   } else error(ifmain(no_mail, no_aliases));
  			   break;
  
  next_undel_msg:
  	    case 'j'    :  if(current > 0) {
  			     if((i=next_message(current-1, TRUE)) != -1) {
  			       current = i+1;
  			       nucurr = get_page(current);
  			     } else
! 			       error1(catgets(elm_msg_cat, ElmSet, ElmNoItemUndeletedBelow,
! 				 "No more undeleted %s below."), items);
  			   } else error(ifmain(no_mail, no_aliases));
  			   break;
  
--- 1056,1079 ----
  			       current = i+1;
  			       nucurr = get_page(current);
  			     } else
! 			       lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 						 ElmNoMoreItemBelow,
! 						 "No more %s below."), 
! 					 items);
  			   } else error(ifmain(no_mail, no_aliases));
  			   break;
  
  next_undel_msg:
+ 	case DOWN_MARK :
  	    case 'j'    :  if(current > 0) {
  			     if((i=next_message(current-1, TRUE)) != -1) {
  			       current = i+1;
  			       nucurr = get_page(current);
  			     } else
! 			       lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 						 ElmNoItemUndeletedBelow,
! 						 "No more undeleted %s below."), 
! 					 items);
  			   } else error(ifmain(no_mail, no_aliases));
  			   break;
  
***************
*** 993,1017 ****
  			       current = i+1;
  			       nucurr = get_page(current);
  			     } else
! 			       error1(catgets(elm_msg_cat, ElmSet, ElmNoMoreItemAbove,
! 				 "No more %s above."), items);
  			   } else error(ifmain(no_mail, no_aliases));
  			   break;
  
  prev_undel_msg:
  	    case 'k'    :  if(current > 0) {
  			     if((i=prev_message(current-1, TRUE)) != -1) {
  			       current = i+1;
  			       nucurr = get_page(current);
  			     } else
! 			       error1(catgets(elm_msg_cat, ElmSet, ElmNoMoreUndeletedAbove,
! 				 "No more undeleted %s above."), items);
  			   } else error(ifmain(no_mail, no_aliases));
  			   break;
  
! 	    case 'l'    :  PutLine1(LINES-3, strlen(Prompt),
! 				   catgets(elm_msg_cat, ElmSet, ElmLimitDisplayBy,
! 				   "Limit displayed %s by..."), items);
  			   clear_error();
  			   if (limit() != 0) {
  			     get_page(current);
--- 1082,1113 ----
  			       current = i+1;
  			       nucurr = get_page(current);
  			     } else
! 			       lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 						 ElmNoMoreItemAbove,
! 						 "No more %s above."), 
! 					 items);
  			   } else error(ifmain(no_mail, no_aliases));
  			   break;
  
  prev_undel_msg:
+ 	case UP_MARK :
  	    case 'k'    :  if(current > 0) {
  			     if((i=prev_message(current-1, TRUE)) != -1) {
  			       current = i+1;
  			       nucurr = get_page(current);
  			     } else
! 			       lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 						 ElmNoMoreUndeletedAbove,
! 						 "No more undeleted %s above."), 
! 					 items);
  			   } else error(ifmain(no_mail, no_aliases));
  			   break;
  
! 	    case 'l'    :  PutLineX(elm_LINES-3, strlen(Prompt),
! 				    CATGETS(elm_msg_cat, ElmSet, 
! 					    ElmLimitDisplayBy,
! 					    "Limit displayed %s by..."), 
! 				    items);
  			   clear_error();
  			   if (limit() != 0) {
  			     get_page(current);
***************
*** 1024,1031 ****
              case ctrl('T') :
  	    case 'T'	   :
  	    case 't'       :  if (message_count < 1) {
! 				error1(catgets(elm_msg_cat, ElmSet, ElmNoItemToTag,
! 				  "No %s to tag!"), items);
  				fflush(stdin);
  			      }
  			      else if (ch == 't')
--- 1120,1129 ----
              case ctrl('T') :
  	    case 'T'	   :
  	    case 't'       :  if (message_count < 1) {
! 				lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 						  ElmNoItemToTag,
! 						  "No %s to tag!"), 
! 					  items);
  				fflush(stdin);
  			      }
  			      else if (ch == 't')
***************
*** 1039,1046 ****
  			      break;
  
  	    case 'u'    :  if (message_count < 1) {
! 			     error1(catgets(elm_msg_cat, ElmSet, ElmNoItemToMarkUndeleted,
! 			       "No %s to mark as undeleted!"), items);
  			     fflush(stdin);
  			   }
  			   else {
--- 1137,1146 ----
  			      break;
  
  	    case 'u'    :  if (message_count < 1) {
! 			     lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					       ElmNoItemToMarkUndeleted,
! 					       "No %s to mark as undeleted!"), 
! 				       items);
  			     fflush(stdin);
  			   }
  			   else {
***************
*** 1064,1071 ****
  			   break;
  
  	    case ctrl('U') : if (message_count < 1) {
! 			       error1(catgets(elm_msg_cat, ElmSet, ElmNoItemToUndelete,
! 				 "No %s to undelete!"), items);
  			       fflush(stdin);
  			     }
  			     else 
--- 1164,1173 ----
  			   break;
  
  	    case ctrl('U') : if (message_count < 1) {
! 			       lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 						 ElmNoItemToUndelete,
! 						 "No %s to undelete!"), 
! 					 items);
  			       fflush(stdin);
  			     }
  			     else 
***************
*** 1076,1132 ****
  
  	    case NO_OP_COMMAND : break;	/* noop for timeout loop */
  
- 	    case ESCAPE : if (cursor_control) {
- 			    key_offset = 1;
- 			    ch = ReadCh(); 
-   
-                             if ( ch == '[' || ch == 'O')
-                             {
-                               ch = ReadCh();
-                               key_offset++;
-                             }
-   
- 			    if(ch == up[key_offset]) goto prev_undel_msg;
- 			    else if(ch == down[key_offset]) goto next_undel_msg;
- 			    else if(ch == right[key_offset]) goto next_page;
- 			    else if(ch == left[key_offset]) goto prev_page;
- 			    else if (hp_terminal) {
- 			      switch (ch) {
- 			      case 'U':		goto next_page;
- 			      case 'V':		goto prev_page;
- 			      case 'h': 	
- 			      case 'H':		goto first_msg;
- 			      case 'F':		goto last_msg;
- 			      case 'A':
- 			      case 'D':
- 			      case 'i':		goto next_undel_msg;
- 			      case 'B':
- 			      case 'I':
- 			      case 'C':		goto prev_undel_msg;
- 			      default: PutLine2(LINES-3, strlen(Prompt), 
- 					"%c%c", ESCAPE, ch);
- 			      }
- 			    } else /* false hit - output */
- 			      PutLine2(LINES-3, strlen(Prompt), 
- 					  "%c%c", ESCAPE, ch);
- 			  }
- 
- 			  /* else fall into the default error message! */
- 
  	    default	: if (ch > '0' && ch <= '9') {
! 			    PutLine1(LINES-3, strlen(Prompt), 
! 				    catgets(elm_msg_cat, ElmSet, ElmNewCurrentItem,
! 				    "New Current %s"), Item);
  			    i = read_number(ch, item);
  
  			    if( i > message_count)
! 			      error1(catgets(elm_msg_cat, ElmSet, ElmNotThatMany,
! 				"Not that many %s."), items);
  			    else if(selected
  				&& isoff(ifmain(headers[i-1]->status,
  			                        aliases[i-1]->status), VISIBLE))
! 			      error1(catgets(elm_msg_cat, ElmSet, ElmNotInLimitedDisplay,
! 				"%s not in limited display."), Item);
  			    else {
  			      current = i;
  			      nucurr = get_page(current);
--- 1178,1202 ----
  
  	    case NO_OP_COMMAND : break;	/* noop for timeout loop */
  
  	    default	: if (ch > '0' && ch <= '9') {
! 			    PutLineX(elm_LINES-3, strlen(Prompt), 
! 				     CATGETS(elm_msg_cat, ElmSet, 
! 					     ElmNewCurrentItem,
! 					     "New Current %s"), Item);
  			    i = read_number(ch, item);
  
  			    if( i > message_count)
! 			      lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 						ElmNotThatMany,
! 						"Not that many %s."), 
! 					items);
  			    else if(selected
  				&& isoff(ifmain(headers[i-1]->status,
  			                        aliases[i-1]->status), VISIBLE))
! 			      lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 						ElmNotInLimitedDisplay,
! 						"%s not in limited display."),
! 					Item);
  			    else {
  			      current = i;
  			      nucurr = get_page(current);
***************
*** 1133,1140 ****
  			    }
  			  }
  			  else {
! 	 		    error(catgets(elm_msg_cat, ElmSet, ElmUnknownCommand,
! 			      "Unknown command. Use '?' for help."));
  			    fflush(stdin);
  			  }
  	}
--- 1203,1211 ----
  			    }
  			  }
  			  else {
! 	 		    lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					      ElmUnknownCommand,
! 					      "Unknown command. Use '?' for help."));
  			    fflush(stdin);
  			  }
  	}
Index: elm2.4.ME+.50/src/encode.c
*** elm2.4.25/src/encode.c	Sat May  8 23:25:39 1993
--- elm2.4.ME+.50/src/encode.c	Tue Nov 17 21:12:58 1998
***************
*** 1,54 ****
  
! static char rcsid[] = "@(#)$Id: encode.c,v 5.5 1993/05/08 20:25:33 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.5 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: encode.c,v $
!  * Revision 5.5  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.4  1993/04/12  01:26:06  syd
!  * According to the SVID (version 3) the function crypt is
!  *
!  *     char *     crypt( const char *, const char * )
!  *
!  * However, it is declared as
!  *
!  *     unsigned char crypt();
!  *
!  * on line 179 of src/encode.c.  The "unsigned" keyword causes the compile
!  * to fail on SVID3 compliant systems.  Upon inspection, it appeared that
!  * the declaration was not even required if CRYPT was not defined, so
!  * changed it to be conditionally compiled.
!  * From: Larry Philps <larryp@sco.COM>
!  *
!  * Revision 5.3  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.2  1992/12/07  02:34:56  syd
!  * Traditional C used 'unsigned preserving' rules when an integral data
!  * value is widened to integer and ANSI C changed the rules to 'value
!  * preserving'. This is one of the few things that the ANSI X3J11 comitte
!  * did that might break existing programs.  Casting to (int)
!  * From: Bo.Asbjorn.Muldbak <bam@jutland.ColumbiaSC.NCR.COM>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This is a heavily mangled version of the 'cypher' program written by
      person or persons unknown.  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: encode.c,v 1.2 1998/10/20 19:58:15 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This is a heavily mangled version of the 'cypher' program written by
      person or persons unknown.  
***************
*** 57,62 ****
--- 19,25 ----
  
  #include "headers.h"
  #include "s_elm.h"
+ #include "me.h"
  
  #define RTRSZ	94
  #define RN	4
***************
*** 83,90 ****
  static char *decrypt_prompt = NULL;
  static char *first_enc_prompt = NULL;
  static char *second_enc_prompt = NULL;
! #define PROMPT_LINE		LINES-1
  
  getkey(send)
  int send;
  {
--- 46,65 ----
  static char *decrypt_prompt = NULL;
  static char *first_enc_prompt = NULL;
  static char *second_enc_prompt = NULL;
! #define PROMPT_LINE		elm_LINES-1
! 
! /* For some ANSI C compilers 'char *' and 'unsigned char *' are incompatible
!  * types -- we don't use casting macro here because it disables type checking
!  * altogether:
!  */
  
+ static char * sig_str P_((unsigned char * str));
+ static char * sig_str(str) 
+      unsigned char * str;
+ { 
+   return (char *)str; 
+ }
+ 
  getkey(send)
  int send;
  {
***************
*** 103,117 ****
  	}
  
  	while (1) {
  	  PutLine0(PROMPT_LINE, 0, (send ? first_enc_prompt : decrypt_prompt));
  	  CleartoEOLN();
! 	  optionally_enter(buffer[0], PROMPT_LINE,
! 	    strlen(send ? first_enc_prompt : decrypt_prompt), FALSE, TRUE);
  	  if (send) {
  	    PutLine0(PROMPT_LINE, 0, second_enc_prompt);
  	    CleartoEOLN();
! 	    optionally_enter(buffer[1], PROMPT_LINE, strlen(second_enc_prompt),
! 	      FALSE, TRUE);
  	    if(strcmp(buffer[0], buffer[1]) != 0) {
  	      error(catgets(elm_msg_cat, ElmSet, ElmKeysNotSame,
  		"Your keys were not the same!"));
--- 78,108 ----
  	}
  
  	while (1) {
+ 	  int code;
+ 
  	  PutLine0(PROMPT_LINE, 0, (send ? first_enc_prompt : decrypt_prompt));
  	  CleartoEOLN();
! 	  code = optionally_enter(buffer[0], PROMPT_LINE,
! 				  strlen(send ? first_enc_prompt : 
! 					 decrypt_prompt), 
! 				  OE_PASSWD|OE_REDRAW_MARK,
! 				  sizeof buffer[0]);
! 	  if (REDRAW_MARK == code)
! 	    continue;
! 	  if (code < 0)
! 	    return;
! 
  	  if (send) {
  	    PutLine0(PROMPT_LINE, 0, second_enc_prompt);
  	    CleartoEOLN();
! 	    code = optionally_enter(buffer[1], PROMPT_LINE, 
! 				    strlen(second_enc_prompt),
! 				    OE_PASSWD|OE_REDRAW_MARK,
! 				    sizeof buffer[1]);
! 	    if (REDRAW_MARK == code)
! 	      continue;
! 	    if (code < 0)
! 	      return;
  	    if(strcmp(buffer[0], buffer[1]) != 0) {
  	      error(catgets(elm_msg_cat, ElmSet, ElmKeysNotSame,
  		"Your keys were not the same!"));
***************
*** 123,129 ****
  	  }
  	  break;
  	}
!         strcpy((char *) the_key, buffer[0]);	/* save unencrypted key */
  	makekey(buffer[0]);
  
  	setup();		/** initialize the rotors etc. **/
--- 114,121 ----
  	  }
  	  break;
  	}
!         strfcpy(sig_str(the_key), 
! 		buffer[0], sizeof the_key);	/* save unencrypted key */
  	makekey(buffer[0]);
  
  	setup();		/** initialize the rotors etc. **/
***************
*** 140,146 ****
  
  	char buffer[SLEN];
  
! 	strcpy(buffer, (char *) the_key);
  
  	makekey( buffer );
  
--- 132,138 ----
  
  	char buffer[SLEN];
  
! 	strfcpy(buffer, sig_str(the_key), sizeof buffer);
  
  	makekey( buffer );
  
Index: elm2.4.ME+.50/src/exitprog.c
*** elm2.4.25/src/exitprog.c	Mon Apr 12 05:34:38 1993
--- elm2.4.ME+.50/src/exitprog.c	Tue Nov 17 21:12:58 1998
***************
*** 1,47 ****
  
! static char rcsid[] = "@(#)$Id: exitprog.c,v 5.5 1993/04/12 02:34:36 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.5 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: exitprog.c,v $
!  * Revision 5.5  1993/04/12  02:34:36  syd
!  * I have now added a parameter which controls whether want_to clears the
!  * line and centers the question or behaves like it did before. I also
!  * added a 0 at the end of the parameter list to all the other calls to
!  * want_to where a centered question on a clean line is not desirable.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.4  1993/01/19  03:55:39  syd
!  * exitprog.c makes a reference to a null character pointer, savecopy.c
!  * tries to reference an uninitialized variable, and the previous patch to
!  * src/lock.c to get rid of an uninitialized variable compiler message
!  * needed to be put in filter/lock.c as well.
!  * From: wdh@grouper.mkt.csd.harris.com (W. David Higgins)
!  *
!  * Revision 5.3  1992/12/25  00:26:49  syd
!  * Fix routine names
!  * From: Syd
!  *
!  * Revision 5.2  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  #include "headers.h"
  #include "s_elm.h"
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: exitprog.c,v 1.2 1998/10/20 19:58:15 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  #include "headers.h"
  #include "s_elm.h"
***************
*** 64,83 ****
  	for (changes = 0, i = 0; i < message_count; i++)
  	  if (ison(headers[i]->status, DELETED) || headers[i]->status_chgd)
  	    changes++;
! 	
  	if (changes) {
  	  /* YES or NO on softkeys */
  	  if (hp_softkeys) {
  	    define_softkeys(YESNO);
  	    softkeys_on();
  	  }
  	  if (changes == 1)
! 	    MCsprintf(msg, catgets(elm_msg_cat, ElmSet, ElmAbandonChange,
! 		"Abandon change to mailbox? (%c/%c) "), *def_ans_yes, *def_ans_no);
  	  else
! 	    MCsprintf(msg, catgets(elm_msg_cat, ElmSet, ElmAbandonChangePlural,
! 		"Abandon changes to mailbox? (%c/%c) "), *def_ans_yes, *def_ans_no);
! 	  answer = want_to(msg, *def_ans_no, LINES-3, 0);
  
  	  if(answer != *def_ans_yes) return -1;
  	}
--- 33,58 ----
  	for (changes = 0, i = 0; i < message_count; i++)
  	  if (ison(headers[i]->status, DELETED) || headers[i]->status_chgd)
  	    changes++;
! 		
  	if (changes) {
  	  /* YES or NO on softkeys */
+ 	  /*
  	  if (hp_softkeys) {
  	    define_softkeys(YESNO);
  	    softkeys_on();
  	  }
+ 	  */
  	  if (changes == 1)
! 	    elm_sfprintf(msg, sizeof msg,
! 			 CATGETS(elm_msg_cat, ElmSet, ElmAbandonChange,
! 				 "Abandon change to mailbox? (%c/%c) "), 
! 			 *def_ans_yes, *def_ans_no);
  	  else
! 	    elm_sfprintf(msg, sizeof msg,
! 			 CATGETS(elm_msg_cat, ElmSet, ElmAbandonChangePlural,
! 				 "Abandon changes to mailbox? (%c/%c) "), 
! 			 *def_ans_yes, *def_ans_no);
! 	  answer = want_to(msg, *def_ans_no, elm_LINES-3, 0);
  
  	  if(answer != *def_ans_yes) return -1;
  	}
Index: elm2.4.ME+.50/src/expires.c
*** elm2.4.25/src/expires.c	Tue Aug 10 21:53:31 1993
--- elm2.4.ME+.50/src/expires.c	Tue Nov 17 21:12:57 1998
***************
*** 1,45 ****
  
! static char rcsid[] = "@(#)$Id: expires.c,v 5.4 1993/08/10 18:53:31 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: expires.c,v $
!  * Revision 5.4  1993/08/10  18:53:31  syd
!  * I compiled elm 2.4.22 with Purify 2 and fixed some memory leaks and
!  * some reads of unitialized memory.
!  * From: vogt@isa.de
!  *
!  * Revision 5.3  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.2  1992/12/07  02:58:56  syd
!  * Fix long -> time_t
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This routine is written to deal with the Expires: header on the
      individual mail coming in.  What it does is to look at the date,
--- 1,12 ----
  
! static char rcsid[] = "@(#)$Id: expires.c,v 1.1.1.1 1998/10/15 15:36:42 hurtta Exp $";
  
! /*****************************************************************************
!  * This code is reimpleted. Original code was following copyright:
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This routine is written to deal with the Expires: header on the
      individual mail coming in.  What it does is to look at the date,
***************
*** 48,177 ****
  **/
  
  #include "headers.h"
  
! #ifdef I_TIME
! #  include <time.h>
! #endif
! #ifdef I_SYSTIME
! #  include <sys/time.h>
! #endif
! 
! process_expiration_date(date, message_status)
! char *date;
! int  *message_status;
  {
! 	struct tm *timestruct;
! 	time_t thetime;
! 	char word1[WLEN], word2[WLEN], word3[WLEN], word4[WLEN], word5[WLEN];
! 	int  month = 0, day = 0, year = 0, hour = 0, minute = 0, items;
  #ifndef	_POSIX_SOURCE
- 	struct tm *localtime();
  	time_t time();
  #endif
  
! 	/** first step is to break down the date given into MM DD YY HH MM
! 	    format:  The possible formats for this field are, by example:
! 	
! 		(1) Mon, Jun 11, 87
! 		(2) Mon, 11 Jun 87
! 		(3) Jun 11, 87
! 		(4) 11 Jun 87
! 		(5) 11/06/87	<- ambiguous - will be ignored!!
! 		(6) 8711061248GMT
! 		(7) Mon, Jun 11, 87 12:48:35 GMT
! 
! 	    The reason #5 is considered ambiguous will be made clear
! 	    if we consider a message to be expired on Jan 4, 88:
! 			01/04/88	in the United States
! 			04/01/88	in Europe
! 	    so is the first field the month or the day?  Standard prob.
! 	**/
! 
! 	items = sscanf(date, "%s %s %s %s %s",
! 		       word1, word2, word3, word4, word5);
! 
! 	if (items < 5)
! 	  word5[0] = '\0';
! 	if (items < 4)
! 	  word4[0] = '\0';
! 	if (items < 3)
! 	  word3[0] = '\0';
! 	if (items < 2)
! 	  word2[0] = '\0';
! 	if (items < 1)
! 	  word1[0] = '\0';
! 
! 	if (strlen(word5) != 0) {	/* we have form #7 */
! 	  day   = atoi(word1);
! 	  month = month_number(word2);
! 	  year  = atoi(word3);
! 	  sscanf(word4, "%02d%*c%02d",
! 	       &hour, &minute);
! 	}
! 	else if (strlen(word2) == 0) {	/* we have form #6 or form #5 */
! 	  if (isdigit(word1[1]) && isdigit(word1[2]))	  /* form #6 */
! 	    sscanf(word1, "%02d%02d%02d%02d%02d%*c",
! 		 &year, &month, &day, &hour, &minute);
! 	}
! 	else if (strlen(word4) != 0) {		   /* form #1 or form #2 */
! 	  if(isdigit(word2[0])) {		   /* form #2 */
! 	      month = month_number(word3);
! 	      day   = atoi(word2);
! 	      year  = atoi(word4);
! 	  } else {				   /* form #1 */
! 	      month = month_number(word2);
! 	      day   = atoi(word3);
! 	      year  = atoi(word4);
! 	  }
! 	}
! 	else if (! isdigit(word1[0])) {		   /* form #3 */
! 	  month = month_number(word1);
! 	  day   = atoi(word2);
! 	  year  = atoi(word3);
! 	}
! 	else {					   /* form #4 */
! 	  day   = atoi(word1);
! 	  month = month_number(word2);
! 	  year  = atoi(word3);
! 	}
! 
! 	if (day == 0 || year == 0)
! 	  return;			/* we didn't get a valid date */
  
! 	/** next let's get the current time and date, please **/
  
  	thetime = time((time_t *) 0);
  
! 	timestruct = localtime(&thetime);
! 
! 	/** and compare 'em **/
! 
! 	if (year > timestruct->tm_year)
! 	  return;
! 	else if (year < timestruct->tm_year)
! 	  goto expire_message;
! 
! 	if (month > timestruct->tm_mon)
! 	  return;
! 	else if (month < timestruct->tm_mon)
! 	  goto expire_message;
! 
! 	if (day > timestruct->tm_mday)
! 	  return;
! 	else if (day < timestruct->tm_mday)
! 	  goto expire_message;
  
! 	if (hour > timestruct->tm_hour)
  	  return;
- 	else if (hour < timestruct->tm_hour)
- 	  goto expire_message;
- 
- 	if (minute > timestruct->tm_min)
- 	  return;
- 
- expire_message:
  
  	/** it's EXPIRED!  Yow!! **/
  
  	(*message_status) |= EXPIRED;
  }
--- 15,51 ----
  **/
  
  #include "headers.h"
+ #include "me.h"
  
! void process_expiration_date(date, message_status)
!      char *date;
!      int  *message_status;
  {
! 	time_t thetime, expiretime;
  #ifndef	_POSIX_SOURCE
  	time_t time();
  #endif
  
! 	if (!parse_date_time(date,
! 			     NULL, 0, NULL, &expiretime)) {
! 	  dprint(7, (debugfile,
! 		     "process_expiration_date: \"%s\" unparseable\n", date));
  
! 	}
  
  	thetime = time((time_t *) 0);
  
! 	dprint(7, (debugfile,
! 		   "process_expiration_date: now %ld, expires %ld\n", 
! 		   (long)thetime, (long)expiretime));
  
! 	if (expiretime > thetime)
  	  return;
  
  	/** it's EXPIRED!  Yow!! **/
  
  	(*message_status) |= EXPIRED;
+ 	dprint(7, (debugfile,
+ 		   "process_expiration_date: Message is expired\n")); 
+ 	return;
  }
Index: elm2.4.ME+.50/src/file.c
*** elm2.4.25/src/file.c	Tue Aug  3 22:29:06 1993
--- elm2.4.ME+.50/src/file.c	Tue Nov 17 21:12:58 1998
***************
*** 1,143 ****
  
! static char rcsid[] = "@(#)$Id: file.c,v 5.21 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.21 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: file.c,v $
!  * Revision 5.21  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.20  1993/05/14  03:57:36  syd
!  * A couple of calls to want_to() had typos. Here is the patch.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.19  1993/05/14  03:53:46  syd
!  * Fix wrong message being displayed and then overwritten
!  * for long aliases.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.18  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.17  1993/05/08  19:26:36  syd
!  * Prevent overwriting appended message.
!  * From: Jason Molenda <molenda@sequent.com>
!  *
!  * Revision 5.16  1993/04/12  02:34:36  syd
!  * I have now added a parameter which controls whether want_to clears the
!  * line and centers the question or behaves like it did before. I also
!  * added a 0 at the end of the parameter list to all the other calls to
!  * want_to where a centered question on a clean line is not desirable.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.15  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.14  1993/01/29  03:40:18  syd
!  * back out the change to clear lines-2, its worse than
!  * overwriting it.
!  * From: Syd
!  *
!  * Revision 5.13  1993/01/27  20:48:01  syd
!  * Change where confirm prompt are written.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.12  1993/01/19  05:07:05  syd
!  * Trim erroreous extra log entry
!  * From: Syd
!  *
!  * Revision 5.11  1993/01/19  04:55:10  syd
!  * fix which file name is used on confirm messages
!  * From: vogt@isa.de (Gerald Vogt)
!  *
!  * Revision 5.10  1993/01/19  04:47:12  syd
!  * Significant changes to provide consistent Date and From_ header
!  * cracking.  Overhauled date utilities and moved into library.  Moved
!  * real_from() into library.  Modified frm, newmail, and readmsg utilities
!  * to use library version of real_from().  Moved get_word() from Elm
!  * source into library.  Added new library routines atonum() and strfcpy().
!  * Fixed trailing backslash bug in len_next().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.9  1992/12/25  00:20:32  syd
!  * fix variable name
!  * From: Syd
!  *
!  * Revision 5.8  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.7  1992/12/07  02:38:45  syd
!  * When ELM is reporting "appending to <foldername>" I never get to see
!  * but a flash of light, before the message line has been replaced by a
!  * dummy "Messages saved" string.  And if you happen to have mistyped the
!  * foldername or the leading '=', you never see the foldername.
!  *
!  * This fix will change file.c to show either
!  *
!  * 	Message <what> to <foldername>
!  *
!  * or
!  * 	<#> messages <what> to <foldername>
!  * From: Bo.Asbjorn.Muldbak <bam@jutland.ColumbiaSC.NCR.COM>
!  *
!  * Revision 5.6  1992/11/26  01:46:26  syd
!  * add Decode option to copy_message, convert copy_message to
!  * use bit or for options.
!  * From: Syd and bjoerns@stud.cs.uit.no (Bjoern Stabell)
!  *
!  * Revision 5.5  1992/10/30  21:01:49  syd
!  * More changes to folder creation confirmation
!  * From: Larry Philps <larryp@sco.COM>
!  *
!  * Revision 5.4  1992/10/24  13:25:41  syd
!  * In our global elm.rc I keep the four options as below
!  *
!  * 	confirmappend = OFF	Don't confirm every append to any file.
!  * 	confirmcreate = ON	Confirm creation of every new file.
!  * 	confirmfiles = ON	Confirm append to non folder files though.
!  * 	confirmfolders = ON	In case someone does not want to be asked
!  * 				every time when creating a new file try
!  * 				to confirm creation of folders though.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.3  1992/10/19  16:44:00  syd
!  * Make headers before pwd to allow include of stdio to
!  * appear first to avoid prototype conflicts
!  * From: Syd via news article by Don Watts
!  *
!  * Revision 5.2  1992/10/11  00:59:39  syd
!  * Fix some compiler warnings that I receive compiling Elm on my SVR4
!  * machine.
!  * From: Tom Moore <tmoore@fievel.DaytonOH.NCR.COM>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** File I/O routines, mostly the save to file command...
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: file.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** File I/O routines, mostly the save to file command...
  
***************
*** 152,157 ****
--- 25,31 ----
  
  #include "s_elm.h"
  #include <errno.h>
+ #include "me.h"
  
  extern int errno;
  
***************
*** 163,219 ****
  static char savehelp[VERY_LONG_STRING];
  static char prev_fold[SLEN];           /* name of previous folder */
  
! void
! init_helpmsg( msg, action_word, allow_dot )
! char	*msg , *action_word ;
! int      allow_dot ;
  {
! 	strcpy( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg1,
! 		"\n\r\n\rYou must specify a file or folder to "));
  
! 	strcat( msg, action_word );
  
! 	strcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg2,
  		" to.  Several options\n\rare available:\n\r\
! \n\r  '!'  will use your incoming mailbox ("));
  
! 	strcat( msg, defaultfile ) ;
  
! 	strcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg3,
! 		")\n\r  '>'  will use your \"received\" folder ("));
  
! 	strcat( msg, nameof( recvd_mail ) ) ;
  
! 	strcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg4,
! 		")\n\r  '<'  will use your \"sent\" folder ("));
  
! 	strcat( msg, nameof( sent_mail ) ) ;
  
  	if( allow_dot ) {
! 	    strcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg5,
! 		    ")\n\r  '.' will use the previous folder ("));
  
! 	    strcat( msg, nameof(prev_fold));
  	}
  
  
! 	strcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg6,
! 		")\n\r  '@alias' will use the default folder for \"alias\"\n\r\n\r\
  If you enter a filename elm will use that file.  If the file name begins\n\r\
  with a '=', elm will look for the file in your folder directory\n\r\
! (your folder directory is "));
  
! 	strcat( msg, raw_folders ) ;
  
! 	strcat( msg, ").\n\r\n\r" ) ;
  
! 	strcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg7,
! 		"You may use wildcards in the name, exactly as you do in the shell.  If you\n\r\
  do this, a list of all matching files or folders will be printed and you\n\r\
  will be prompted for another name.  Thus typing '=a*' will print the names\n\r\
  of all folders in your folder directory starting with 'a'.  Typing 'b*.c'\n\r\
! will print all files in your local directory starting with 'b' and ending\n\r"));
! 	strcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg8,
  "in '.c'.  A star (*) will usually list everything.  See your local shell\n\r\
  manual for more information on wildcards.\n\r\
  \n\r\
--- 37,100 ----
  static char savehelp[VERY_LONG_STRING];
  static char prev_fold[SLEN];           /* name of previous folder */
  
! void init_helpmsg( msg, action_word, allow_dot, size_msg )
!      char	*msg , *action_word ;
!      int      allow_dot ;
!      int size_msg;
  {
! 	strfcpy( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg1,
! 			      "\n\r\n\rYou must specify a file or folder to "),
! 		 size_msg);
  
! 	strfcat( msg, action_word, size_msg );
  
! 	strfcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg2,
  		" to.  Several options\n\rare available:\n\r\
! \n\r  '!'  will use your incoming mailbox ("),
! 		 size_msg);
  
! 	strfcat( msg, defaultfile, size_msg ) ;
  
! 	strfcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg3,
! 		")\n\r  '>'  will use your \"received\" folder ("),
! 		 size_msg);
  
! 	strfcat( msg, nameof( recvd_mail ), size_msg ) ;
  
! 	strfcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg4,
! 		")\n\r  '<'  will use your \"sent\" folder ("),
! 		 size_msg);
  
! 	strfcat( msg, nameof( sent_mail ), size_msg ) ;
  
  	if( allow_dot ) {
! 	    strfcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg5,
! 				  ")\n\r  '.' will use the previous folder ("),
! 		     size_msg);
  
! 	    strfcat( msg, nameof(prev_fold), size_msg);
  	}
  
  
! 	strfcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg6,
! 			      ")\n\r  '@alias' will use the default folder for \"alias\"\n\r\n\r\
  If you enter a filename elm will use that file.  If the file name begins\n\r\
  with a '=', elm will look for the file in your folder directory\n\r\
! (your folder directory is "),
! 		 size_msg);
  
! 	strfcat( msg, raw_folders, size_msg ) ;
  
! 	strfcat( msg, ").\n\r\n\r", size_msg ) ;
  
! 	strfcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg7,
! 			      "You may use wildcards in the name, exactly as you do in the shell.  If you\n\r\
  do this, a list of all matching files or folders will be printed and you\n\r\
  will be prompted for another name.  Thus typing '=a*' will print the names\n\r\
  of all folders in your folder directory starting with 'a'.  Typing 'b*.c'\n\r\
! will print all files in your local directory starting with 'b' and ending\n\r"),
! 		 size_msg);
! 	strfcat( msg, catgets(elm_msg_cat, ElmSet, ElmFileHelpmsg8,
  "in '.c'.  A star (*) will usually list everything.  See your local shell\n\r\
  manual for more information on wildcards.\n\r\
  \n\r\
***************
*** 222,228 ****
  erase or line erase keys.\n\r\
  \n\r\
  \n\r\
! \n\r"));
  }
  
  
--- 103,110 ----
  erase or line erase keys.\n\r\
  \n\r\
  \n\r\
! \n\r"),
! 		 size_msg);
  }
  
  
***************
*** 248,253 ****
--- 130,136 ----
  	char	filename[SLEN], address[LONG_STRING], buffer[LONG_STRING],
  		ch, msg_buffer[SLEN], answer;
  	FILE *save_file;
+ 	int save_fd;
  
  	oldstat = headers[current-1]->status;	/* remember */
  	*redraw = FALSE;
***************
*** 272,300 ****
  
  Retry_Save_If_Not_Confirmed:
  	while (1) {
  	  if (tagged == 1)
! 	    PutLine1(LINES-2, 0, catgets(elm_msg_cat, ElmSet, ElmSaveMessageTo,
! 		  "%s message to: "), (delete ? cap_save_word : cap_copy_word));
  	  else
! 	    PutLine1(LINES-2, 0, catgets(elm_msg_cat, ElmSet, ElmSaveMessagesTo,
! 		  "%s messages to: "), (delete ? cap_save_word : cap_copy_word));
  
  	  if (save_by_name) {
  	    /** build default filename to save to **/
! 	    get_return(address, mesgnum);
! 	    get_return_name(address, buffer, TRUE);
! 	    sprintf(filename, "=%s", buffer);
  	  }
  	  else
  	    filename[0] = '\0';
  
  	  if (tagged > 1)
! 	    optionally_enter(filename, LINES-2, 19, FALSE, FALSE);
  	  else	
! 	    optionally_enter(filename, LINES-2, 18, FALSE, FALSE);
    
  
! 	  if (strlen(filename) == 0) {  /** <return> means 'cancel', right? **/
  	    headers[current-1]->status = oldstat;	/* BACK! */
  	    return(0);
  	  }
--- 155,197 ----
  
  Retry_Save_If_Not_Confirmed:
  	while (1) {
+ 	  int code;
+ 
  	  if (tagged == 1)
! 	    PutLineX(elm_LINES-2, 0, 
! 		     CATGETS(elm_msg_cat, ElmSet, ElmSaveMessageTo,
! 			     "%s message to: "), 
! 		     (delete ? cap_save_word : cap_copy_word));
  	  else
! 	    PutLineX(elm_LINES-2, 0, 
! 		     CATGETS(elm_msg_cat, ElmSet, ElmSaveMessagesTo,
! 			     "%s messages to: "), 
! 		     (delete ? cap_save_word : cap_copy_word));
  
  	  if (save_by_name) {
  	    /** build default filename to save to **/
! 	    get_return(address, mesgnum, sizeof address);
! 	    get_return_name(address, buffer, TRUE, sizeof buffer);
! 	    elm_sfprintf(filename, sizeof filename,
! 			 FRM("=%s"), buffer);
  	  }
  	  else
  	    filename[0] = '\0';
  
  	  if (tagged > 1)
! 	    code = optionally_enter(filename, elm_LINES-2, 19, OE_REDRAW_MARK,
! 				    sizeof filename);
  	  else	
! 	    code = optionally_enter(filename, elm_LINES-2, 18, OE_REDRAW_MARK,
! 				    sizeof filename);
! 	  if (REDRAW_MARK == code) {
! 	    *redraw = TRUE;
! 	    continue;
! 	  }
    
  
! 	  if (0 != code || 
! 	      strlen(filename) == 0) {  /** <return> means 'cancel', right? **/
  	    headers[current-1]->status = oldstat;	/* BACK! */
  	    return(0);
  	  }
***************
*** 304,310 ****
  	    if ( delete )
  	    {
  	      if ( !*savehelp )	/* format helpmsg if not yet done */
! 	        init_helpmsg( savehelp, save_word, TRUE ) ;
  	      ClearScreen();
  	      (void) printf( savehelp ) ;
  	    }
--- 201,207 ----
  	    if ( delete )
  	    {
  	      if ( !*savehelp )	/* format helpmsg if not yet done */
! 	        init_helpmsg( savehelp, save_word, TRUE, sizeof savehelp ) ;
  	      ClearScreen();
  	      (void) printf( savehelp ) ;
  	    }
***************
*** 311,317 ****
  	    else
  	    {
  	      if ( !*copyhelp )	/* format helpmsg if not yet done */
! 		init_helpmsg( copyhelp, copy_word, TRUE ) ;
  	      ClearScreen();
  	      (void) printf( copyhelp ) ;
  	    }
--- 208,214 ----
  	    else
  	    {
  	      if ( !*copyhelp )	/* format helpmsg if not yet done */
! 		init_helpmsg( copyhelp, copy_word, TRUE, sizeof copyhelp ) ;
  	      ClearScreen();
  	      (void) printf( copyhelp ) ;
  	    }
***************
*** 326,332 ****
  	    continue ;
  	  }
  	  /* else - got a folder name - check it out */
! 	  if (! expand_filename(filename, TRUE)) {
  	    dprint(2, (debugfile,
  		  "Error: Failed on expansion of filename %s (save)\n", 
  		  filename));
--- 223,229 ----
  	    continue ;
  	  }
  	  /* else - got a folder name - check it out */
! 	  if (! expand_filename(filename, TRUE, sizeof filename)) {
  	    dprint(2, (debugfile,
  		  "Error: Failed on expansion of filename %s (save)\n", 
  		  filename));
***************
*** 336,344 ****
  	  is_ordinary_file = strncmp (filename, folders, strlen(folders));
  	  
  	  if ((errno = can_open(filename, "a"))) {
! 	    error2(catgets(elm_msg_cat, ElmSet, ElmCannotSaveMessage,
! 		"Cannot %s message to folder %s!"),
! 	      delete ? save_word:copy_word, filename);
  	    continue;
  	  }
  	  break;	/* got a valid filename */
--- 233,241 ----
  	  is_ordinary_file = strncmp (filename, folders, strlen(folders));
  	  
  	  if ((errno = can_open(filename, "a"))) {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCannotSaveMessage,
! 			      "Cannot %s message to folder %s!"),
! 		      delete ? save_word:copy_word, filename);
  	    continue;
  	  }
  	  break;	/* got a valid filename */
***************
*** 351,365 ****
  	    if (confirm_append || (confirm_files && is_ordinary_file)) {
  
  	        if (is_ordinary_file)
! 	          MCsprintf(msg_buffer, catgets(elm_msg_cat, ElmSet, ElmConfirmFilesAppend,
! 		      "Append to an existing file `%s'? (%c/%c) "),
! 		    filename, *def_ans_yes, *def_ans_no);
  	        else
! 	          MCsprintf(msg_buffer, catgets(elm_msg_cat, ElmSet, ElmConfirmFolderAppend,
! 	              "Append to mail folder `%s'? (%c/%c) "),
! 		    filename, *def_ans_yes, *def_ans_no);
  
! 	        answer = want_to(msg_buffer, *def_ans_no, LINES-1, 1);
  
  		if (answer != *def_ans_yes) {
  		    goto Retry_Save_If_Not_Confirmed;
--- 248,266 ----
  	    if (confirm_append || (confirm_files && is_ordinary_file)) {
  
  	        if (is_ordinary_file)
! 	          elm_sfprintf(msg_buffer, sizeof msg_buffer,
! 			       CATGETS(elm_msg_cat, ElmSet, 
! 				       ElmConfirmFilesAppend,
! 				       "Append to an existing file `%s'? (%c/%c) "),
! 			       filename, *def_ans_yes, *def_ans_no);
  	        else
! 	          elm_sfprintf(msg_buffer, sizeof msg_buffer,
! 			       CATGETS(elm_msg_cat, ElmSet, 
! 				       ElmConfirmFolderAppend,
! 				       "Append to mail folder `%s'? (%c/%c) "),
! 			       filename, *def_ans_yes, *def_ans_no);
  
! 	        answer = want_to(msg_buffer, *def_ans_no, elm_LINES-1, 1);
  
  		if (answer != *def_ans_yes) {
  		    goto Retry_Save_If_Not_Confirmed;
***************
*** 370,384 ****
              if (confirm_create || (confirm_folders && !is_ordinary_file)) {
  
  	        if (is_ordinary_file)
! 	          MCsprintf(msg_buffer, catgets(elm_msg_cat, ElmSet, ElmConfirmFilesCreate,
! 		      "Create a new file `%s'? (%c/%c) "),
! 		    filename, *def_ans_yes, *def_ans_no);
  	        else
! 	          MCsprintf(msg_buffer, catgets(elm_msg_cat, ElmSet, ElmConfirmFolderCreate,
! 	              "Create a new mail folder `%s'? (%c/%c) "),
! 		    filename, *def_ans_yes, *def_ans_no);
  
! 	        answer = want_to(msg_buffer, *def_ans_no, LINES-1, 1);
  
  		if (answer != *def_ans_yes) {
  		    goto Retry_Save_If_Not_Confirmed;
--- 271,289 ----
              if (confirm_create || (confirm_folders && !is_ordinary_file)) {
  
  	        if (is_ordinary_file)
! 	          elm_sfprintf(msg_buffer, sizeof msg_buffer,
! 			       CATGETS(elm_msg_cat, ElmSet, 
! 				       ElmConfirmFilesCreate,
! 				       "Create a new file `%s'? (%c/%c) "),
! 			       filename, *def_ans_yes, *def_ans_no);
  	        else
! 	          elm_sfprintf(msg_buffer, sizeof msg_buffer,
! 			       CATGETS(elm_msg_cat, ElmSet, 
! 				       ElmConfirmFolderCreate,
! 				       "Create a new mail folder `%s'? (%c/%c) "),
! 			       filename, *def_ans_yes, *def_ans_no);
  
! 	        answer = want_to(msg_buffer, *def_ans_no, elm_LINES-1, 1);
  
  		if (answer != *def_ans_yes) {
  		    goto Retry_Save_If_Not_Confirmed;
***************
*** 390,406 ****
  
  	/* save this filename for the next time */
  	strfcpy(prev_fold, filename, SLEN);
! 
! 	if ((save_file = fopen(filename,"a")) == NULL) {
  	  dprint(2, (debugfile,
  		"Error: couldn't append to specified folder %s (save)\n", 
  		filename));
! 	  error1(catgets(elm_msg_cat, ElmSet, ElmCouldntAppendFolder,
! 		"Couldn't append to folder %s!"), filename);
  	  headers[current-1]->status = oldstat;	/* BACK! */
  	  return(0); 
  	}
  
  	/* if we need a redraw that means index screen no longer present
  	 * so whatever silently was, now it's true - we can't show those
  	 * delete markings.
--- 295,346 ----
  
  	/* save this filename for the next time */
  	strfcpy(prev_fold, filename, SLEN);
!       
! 	if ((save_fd = open(filename,O_RDWR|O_CREAT,0600)) == -1 ||
! 	    (save_file = fdopen(save_fd,"r+")) == NULL) {
! 	  close(save_fd);
  	  dprint(2, (debugfile,
  		"Error: couldn't append to specified folder %s (save)\n", 
  		filename));
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldntAppendFolder,
! 			    "Couldn't append to folder %s!"), 
! 		    filename);
  	  headers[current-1]->status = oldstat;	/* BACK! */
  	  return(0); 
  	}
  
+ 	if (lock_in_copy) {
+ 	  /*  lock the file to be modified to serialize access with other */
+ 	  /* programs like procmail. */
+ 
+ 	  if (Grab_the_file(save_fd) != FLOCKING_OK){
+ 	    fclose(save_file);
+ 	    dprint(2, (debugfile,
+ 		       "Error: couldn't lock specified folder %s (save)\n", 
+ 		       filename));
+ 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldntAppendFolder,
+ 			      "Couldn't lock folder %s!"), 
+ 		      filename);
+ 	    headers[current-1]->status = oldstat; /* BACK! */
+ 	    return(0); 
+ 	  }
+ 	}
+ 
+ 	/* copy_message want now seek backwards ... */
+ 	if (0 != fseek(save_file,0,SEEK_END)) {
+ 	  if (lock_in_copy)
+ 	    Release_the_file(save_fd); 
+ 	  dprint(2, (debugfile,
+ 		"Error: couldn't seek to end of specified folder %s (save)\n", 
+ 		filename));
+ 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldntAppendFolder,
+ 			    "Couldn't append to folder %s!"), 
+ 		    filename);
+ 	  headers[current-1]->status = oldstat;	/* BACK! */
+ 	  fclose(save_file);
+ 	  return (0);
+ 	}
+ 
  	/* if we need a redraw that means index screen no longer present
  	 * so whatever silently was, now it's true - we can't show those
  	 * delete markings.
***************
*** 414,432 ****
  	    scount++;
  	  }
  
  	fclose(save_file);
  
  	restore_file_stats(filename);
  
  	if (tagged == 1 && !appending)
! 	  error2(catgets(elm_msg_cat, ElmSet, ElmMessageSaved,
! 		"Message %s to %s."), delete ? saved_word: copied_word,
! 		filename);
  	else if (tagged > 1)
! 	  error3(catgets(elm_msg_cat, ElmSet, ElmMessagesSaved,
! 		  "%d messages %s to %s."), scount, 
! 		  delete ? saved_word: copied_word,
! 		  filename);
  	return(1);
  }
  
--- 354,375 ----
  	    scount++;
  	  }
  
+ 	if (lock_in_copy)
+ 	  Release_the_file(save_fd); /* XXX LOCKING */
  	fclose(save_file);
  
  	restore_file_stats(filename);
  
  	if (tagged == 1 && !appending)
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMessageSaved,
! 			    "Message %s to %s."), 
! 		    delete ? saved_word: copied_word,
! 		    filename);
  	else if (tagged > 1)
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMessagesSaved,
! 			    "%d messages %s to %s."), scount, 
! 		    delete ? saved_word: copied_word,
! 		    filename);
  	return(1);
  }
  
***************
*** 460,466 ****
  	 */
  	if(is_new = ison(headers[number]->status, NEW))
  	  clearit(headers[number]->status, NEW);
! 	copy_message("", fd, CM_UPDATE_STATUS);
  	if(is_new)
  	  setit(headers[number]->status, NEW);
  	current = save_current;
--- 403,410 ----
  	 */
  	if(is_new = ison(headers[number]->status, NEW))
  	  clearit(headers[number]->status, NEW);
! 	copy_message(mailfile,headers[number],
! 		     "", fd, CM_UPDATE_STATUS);
  	if(is_new)
  	  setit(headers[number]->status, NEW);
  	current = save_current;
***************
*** 470,481 ****
  	clearit(headers[number]->status, TAGGED);  /* not tagged anymore */
  
  	if (appending)
! 	  error2(catgets(elm_msg_cat, ElmSet, ElmMessageAppendedFolder,
! 		"Message %d appended to folder %s."), number+1, filename);
  	else
! 	  error3(catgets(elm_msg_cat, ElmSet, ElmMessageSavedFolder,
! 		"Message %d %s to folder %s."),
! 	     number+1, delete ? saved_word : copied_word, filename);
  
  	if (! silently)
  	  show_new_status(number);	/* update screen, if needed */
--- 414,426 ----
  	clearit(headers[number]->status, TAGGED);  /* not tagged anymore */
  
  	if (appending)
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMessageAppendedFolder,
! 			    "Message %d appended to folder %s."), 
! 		    number+1, filename);
  	else
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMessageSavedFolder,
! 			    "Message %d %s to folder %s."),
! 		    number+1, delete ? saved_word : copied_word, filename);
  
  	if (! silently)
  	  show_new_status(number);	/* update screen, if needed */
***************
*** 485,494 ****
  		sleep(sleepmsg);
  }
  
! int
! expand_filename(filename, use_cursor_control)
! char *filename;
! int use_cursor_control;
  {
  	/** Expands	~/	to the current user's home directory
  			~user/	to the home directory of "user"
--- 430,439 ----
  		sleep(sleepmsg);
  }
  
! int expand_filename(filename, use_cursor_control, size_filename)
!      char *filename;
!      int use_cursor_control;
!      int size_filename;
  {
  	/** Expands	~/	to the current user's home directory
  			~user/	to the home directory of "user"
***************
*** 516,522 ****
  
  	ptr = filename;
  	while (*ptr == ' ') ptr++;	/* leading spaces GONE! */
! 	strcpy(temp_filename, ptr);
  
  	/** New stuff - make sure no illegal char as last **/
  	/** Strip off any trailing backslashes or blanks **/
--- 461,467 ----
  
  	ptr = filename;
  	while (*ptr == ' ') ptr++;	/* leading spaces GONE! */
! 	strfcpy(temp_filename, ptr, sizeof temp_filename);
  
  	/** New stuff - make sure no illegal char as last **/
  	/** Strip off any trailing backslashes or blanks **/
***************
*** 529,536 ****
  
  	if (temp_filename[0] == '~') {
  	  if(temp_filename[1] == '/')
! 	    sprintf(filename, "%s%s%s",
! 		  home, (lastch(home) != '/' ? "/" : ""), &temp_filename[2]);
  	  else {
  	    for(ptr = &temp_filename[1], iindex = 0; *ptr && *ptr != '/'; ptr++, iindex++)
  	      logname[iindex] = *ptr;
--- 474,483 ----
  
  	if (temp_filename[0] == '~') {
  	  if(temp_filename[1] == '/')
! 	    elm_sfprintf(filename, size_filename,
! 			 FRM("%s%s%s"),
! 			 home, (lastch(home) != '/' ? "/" : ""), 
! 			 &temp_filename[2]);
  	  else {
  	    for(ptr = &temp_filename[1], iindex = 0; *ptr && *ptr != '/'; ptr++, iindex++)
  	      logname[iindex] = *ptr;
***************
*** 540,548 ****
  		      "Error: Can't get home directory for %s (%s)\n",
  		      logname, "expand_filename"));
  	      if(use_cursor_control)
! 		error1(catgets(elm_msg_cat, ElmSet, ElmDontKnowHomeCursor,
! 			"Don't know what the home directory of \"%s\" is!"),
! 			logname);
  	      else
  		printf(catgets(elm_msg_cat, ElmSet, ElmDontKnowHomePrintf,
  		    "\n\rDon't know what the home directory of \"%s\" is!\n\r"),
--- 487,495 ----
  		      "Error: Can't get home directory for %s (%s)\n",
  		      logname, "expand_filename"));
  	      if(use_cursor_control)
! 		lib_error(CATGETS(elm_msg_cat, ElmSet, ElmDontKnowHomeCursor,
! 				  "Don't know what the home directory of \"%s\" is!"),
! 			  logname);
  	      else
  		printf(catgets(elm_msg_cat, ElmSet, ElmDontKnowHomePrintf,
  		    "\n\rDon't know what the home directory of \"%s\" is!\n\r"),
***************
*** 549,563 ****
  		    logname);
  	      return(0);
  	    }
! 	    sprintf(filename, "%s%s", pass->pw_dir, ptr);
  	  }
  
  	}
  	else if (temp_filename[0] == '=' || temp_filename[0] == '+' || 
  	 	 temp_filename[0] == '%') {
! 	  sprintf(filename, "%s%s%s", folders, 
! 		(temp_filename[1] != '/' && lastch(folders) != '/')? "/" : "",
! 	  	&temp_filename[1]);
  	}
  	else if  ( temp_filename[0] == '@' ) {
  
--- 496,513 ----
  		    logname);
  	      return(0);
  	    }
! 	    elm_sfprintf(filename, size_filename,
! 			 FRM("%s%s"), pass->pw_dir, ptr);
  	  }
  
  	}
  	else if (temp_filename[0] == '=' || temp_filename[0] == '+' || 
  	 	 temp_filename[0] == '%') {
! 	  elm_sfprintf(filename, size_filename,
! 		       FRM("%s%s%s"), folders, 
! 		       (temp_filename[1] != '/' && 
! 			lastch(folders) != '/')? "/" : "",
! 		       &temp_filename[1]);
  	}
  	else if  ( temp_filename[0] == '@' ) {
  
***************
*** 572,588 ****
  	    }
  
  	    /* get filename from address */
! 	    get_return_name(address, buffer, TRUE);
  
! 	    sprintf(filename, "%s%s%s",
! 	      folders, 
! 	      (temp_filename[1] != '/' && lastch(folders) != '/') ? "/" : "", 
! 	      buffer);
  	  }
            else {
  	    if ( use_cursor_control )
! 	      error1(catgets(elm_msg_cat, ElmSet, ElmCannotExpand,
! 		     "Cannot expand alias '%s'!\n\r"), &(temp_filename[1]) );
  	    else
  	      printf(catgets(elm_msg_cat, ElmSet, ElmCannotExpand,
  		     "Cannot expand alias '%s'!\n\r"), &(temp_filename[1]) );
--- 522,541 ----
  	    }
  
  	    /* get filename from address */
! 	    get_return_name(address, buffer, TRUE, sizeof buffer);
  
! 	    elm_sfprintf(filename, size_filename,
! 			 FRM("%s%s%s"),
! 			 folders, 
! 			 (temp_filename[1] != '/' && 
! 			  lastch(folders) != '/') ? "/" : "", 
! 			 buffer);
  	  }
            else {
  	    if ( use_cursor_control )
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCannotExpand,
! 				"Cannot expand alias '%s'!"), 
! 			&(temp_filename[1]) );
  	    else
  	      printf(catgets(elm_msg_cat, ElmSet, ElmCannotExpand,
  		     "Cannot expand alias '%s'!\n\r"), &(temp_filename[1]) );
***************
*** 596,602 ****
  
  	  env_value[0] = '\0';			/* null string for strlen! */
  	  if (getenv(varname) != NULL)
! 	    strcpy(env_value, getenv(varname));
  
  	  if (strlen(env_value) == 0) {
  	    dprint(3,(debugfile, 
--- 549,555 ----
  
  	  env_value[0] = '\0';			/* null string for strlen! */
  	  if (getenv(varname) != NULL)
! 	    strfcpy(env_value, getenv(varname), sizeof env_value);
  
  	  if (strlen(env_value) == 0) {
  	    dprint(3,(debugfile, 
***************
*** 603,610 ****
  		    "Error: Can't expand environment variable $%s (%s)\n",
  		    varname, "expand_filename"));
  	    if(use_cursor_control)
! 	      error1(catgets(elm_msg_cat, ElmSet, ElmDontKnowValueCursor,
! 		    "Don't know what the value of $%s is!"), varname);
  	    else
  	      printf(catgets(elm_msg_cat, ElmSet, ElmDontKnowValuePrintf,
  		    "\n\rDon't know what the value of $%s is!\n\r"), varname);
--- 556,564 ----
  		    "Error: Can't expand environment variable $%s (%s)\n",
  		    varname, "expand_filename"));
  	    if(use_cursor_control)
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmDontKnowValueCursor,
! 				"Don't know what the value of $%s is!"), 
! 			varname);
  	    else
  	      printf(catgets(elm_msg_cat, ElmSet, ElmDontKnowValuePrintf,
  		    "\n\rDon't know what the value of $%s is!\n\r"), varname);
***************
*** 611,629 ****
  	    return(0);
  	  }
  
! 	  sprintf(filename, "%s%s%s", env_value, 
! 		(*ptr && *ptr != '/' && lastch(env_value) != '/')? "/" : "", ptr);
  
  	} else if (strcmp(temp_filename, "!") == 0) {
! 	  strcpy(filename, defaultfile);
  	} else if (strcmp(temp_filename, ">") == 0) {
! 	  strcpy(filename, recvd_mail);
  	} else if (strcmp(temp_filename, "<") == 0) {
! 	  strcpy(filename, sent_mail);
  	} else if (strcmp(temp_filename, ".") == 0) {
! 	  strcpy(filename, prev_fold);
  	} else
! 	  strcpy(filename, temp_filename);
  	  
  	return(1);
  }
--- 565,585 ----
  	    return(0);
  	  }
  
! 	  elm_sfprintf(filename, size_filename,
! 		       FRM("%s%s%s"), env_value, 
! 		       (*ptr && *ptr != '/' && 
! 			lastch(env_value) != '/')? "/" : "", ptr);
  
  	} else if (strcmp(temp_filename, "!") == 0) {
! 	  strfcpy(filename, defaultfile, size_filename);
  	} else if (strcmp(temp_filename, ">") == 0) {
! 	  strfcpy(filename, recvd_mail, size_filename);
  	} else if (strcmp(temp_filename, "<") == 0) {
! 	  strfcpy(filename, sent_mail, size_filename);
  	} else if (strcmp(temp_filename, ".") == 0) {
! 	  strfcpy(filename, prev_fold, size_filename);
  	} else
! 	  strfcpy(filename, temp_filename, size_filename);
  	  
  	return(1);
  }
Index: elm2.4.ME+.50/src/file_util.c
*** elm2.4.25/src/file_util.c	Fri Jun  3 20:05:32 1994
--- elm2.4.ME+.50/src/file_util.c	Tue Nov 17 21:12:58 1998
***************
*** 1,81 ****
  
! static char rcsid[] = "@(#)$Id: file_util.c,v 5.12 1994/06/03 17:05:17 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.12 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: file_util.c,v $
!  * Revision 5.12  1994/06/03  17:05:17  syd
!  * try and prevent copy from calling elm_chown unless needed
!  * From: Syd
!  *
!  * Revision 5.11  1994/05/14  18:42:57  syd
!  * Here are some more of fixes to correctly call fflush() and unlock() in sequence.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.10  1993/09/27  01:51:38  syd
!  * Add elm_chown to consolidate for Xenix not allowing -1
!  * From: Syd
!  *
!  * Revision 5.9  1993/09/19  23:37:29  syd
!  * I found a few places more where the code was missing a call
!  * to fflush() before it called unlock() and fclose()/exit()
!  * right after unlocking the mail drop.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.8  1993/08/23  03:26:24  syd
!  * Try setting group id separate from user id in chown to
!  * allow restricted systems to change group id of file
!  * From: Syd
!  *
!  * Revision 5.7  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.6  1993/02/03  19:06:31  syd
!  * Remove extra strchr/strcat/strcpy et al declarations
!  * From: Syd
!  *
!  * Revision 5.5  1993/01/20  03:37:16  syd
!  * Nits and typos in the NLS messages and corresponding default messages.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.4  1992/12/16  14:30:52  syd
!  * Make forward to checking consistent on sign ignoring
!  * From: Syd
!  *
!  * Revision 5.3  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.2  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** File oriented utility routines for ELM 
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: file_util.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** File oriented utility routines for ELM 
  
***************
*** 85,94 ****
  #include "s_elm.h"
  #include <sys/stat.h>
  #include <errno.h>
! 
! #ifdef BSD
! # include <sys/wait.h>
! #endif
  
  extern int errno;		/* system error number */
  
--- 20,26 ----
  #include "s_elm.h"
  #include <sys/stat.h>
  #include <errno.h>
! #include "me.h"
  
  extern int errno;		/* system error number */
  
***************
*** 95,103 ****
  char *error_description(), *getlogin();
  long  fsize();
  
! long
! bytes(name)
! char *name;
  {
  	int err;
  	/** return the number of bytes in the specified file.  This
--- 27,34 ----
  char *error_description(), *getlogin();
  long  fsize();
  
! long bytes(name)
!      char *name;
  {
  	int err;
  	/** return the number of bytes in the specified file.  This
***************
*** 112,127 ****
  	if (stat(name, &buffer) != 0)
  	  if (errno != 2) {
  	    err = errno;
! 	    MoveCursor(LINES, 0);
  	    Raw(OFF);
  	    dprint(1,(debugfile,
  		     "Error: errno %s on fstat of file %s (bytes)\n", 
  		     error_description(err), name));
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmErrorFstat,
! 		     "\nError attempting fstat on file %s!\n"),
! 		     name);
! 	    printf("** %s. **\n", error_description(err));
! 	    emergency_exit();
  	  }
  	  else
  	    ok = 0;
--- 43,59 ----
  	if (stat(name, &buffer) != 0)
  	  if (errno != 2) {
  	    err = errno;
! 	    MoveCursor(elm_LINES, 0);
  	    Raw(OFF);
  	    dprint(1,(debugfile,
  		     "Error: errno %s on fstat of file %s (bytes)\n", 
  		     error_description(err), name));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorFstat,
! 			      "\nError attempting fstat on file %s!\n"),
! 		      name);
! 	    lib_error(FRM("** %s. **\n"), 
! 		      error_description(err));
! 	    emergency_exit(0);
  	  }
  	  else
  	    ok = 0;
***************
*** 147,154 ****
  	if ((from_file = fopen(from, "r")) == NULL) {
  	    dprint(1, (debugfile, "Error: could not open %s for reading (copy)\n",
  		       from));
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmCouldNotOpenFile,
! 			   "Could not open file %s."), from);
  	    return(1);
  	}
  
--- 79,87 ----
  	if ((from_file = fopen(from, "r")) == NULL) {
  	    dprint(1, (debugfile, "Error: could not open %s for reading (copy)\n",
  		       from));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldNotOpenFile,
! 			      "Could not open file %s."), 
! 		      from);
  	    return(1);
  	}
  
***************
*** 155,180 ****
  	if ((to_file = fopen(to, "w")) == NULL) {
  	    dprint(1, (debugfile, "Error: could not open %s for writing (copy)\n",
  		       to));
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmCouldNotOpenFile,
! 			   "Could not open file %s."), to);
  	    return(1);
  	}
  
! 	while (len = fread(buffer, 1, VERY_LONG_STRING, from_file)) {
! 	    if (fwrite(buffer, 1, len, to_file) != len) {
! 		Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmWriteFailedCopy,
! 			"\n\rWrite failed to temp file in copy\n\r"), 0);
! 		perror(to);
! 		/*
! 		 *  NEVER close anything just at whim!!
! 		 *  If the file has been locked using fcntl() or lockf()
! 		 *	YOU WILL DROP ALL LOCKS refering to the file.
! 		 */
! 		fflush(to_file);
! 		fclose(to_file);
! 		fclose(from_file);
! 		return(1);
! 	    }
  	}
  
  	fclose(from_file);
--- 88,127 ----
  	if ((to_file = fopen(to, "w")) == NULL) {
  	    dprint(1, (debugfile, "Error: could not open %s for writing (copy)\n",
  		       to));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldNotOpenFile,
! 			      "Could not open file %s."), 
! 		      to);
! 	    sleep_message();
! 	    return(1);
! 	}
! 
! 	while ((len = fread(buffer, 1, VERY_LONG_STRING, from_file)) > 0) {
! 	  if (fwrite(buffer, 1, len, to_file) != len) {
! 	    int err = errno;
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWriteFailedCopy,
! 			      "Write failed in copy: %s: %s"), 
! 		      to, error_description(err));
! 	    sleep_message();
! 	    /*
! 	     *  NEVER close anything just at whim!!
! 	     *  If the file has been locked using fcntl() or lockf()
! 	     *	YOU WILL DROP ALL LOCKS refering to the file.
! 	     */
! 	    fflush(to_file);
! 	    fclose(to_file);
! 	    fclose(from_file);
  	    return(1);
+ 	  }
  	}
  
! 	if (ferror(from_file)) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmReadFailedCopy,
! 			    "Read failed in copy"));
! 	  fflush(to_file);
! 	  fclose(to_file);
! 	  fclose(from_file);
! 	  sleep_message();
! 	  return(1);
  	}
  
  	fclose(from_file);
***************
*** 181,193 ****
  	fflush(to_file);
  
  	if (fclose(to_file) == EOF) {
! 	    Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmCloseFailedCopy,
! 		    "\n\rClose failed on temp file in copy\n\r"), 0);
! 	    perror(to);
! 	    return(1);
  	}
  	if (!isspool)
! 	    (void) elm_chown( to, userid, groupid);
  
  	return(0);
  }
--- 128,142 ----
  	fflush(to_file);
  
  	if (fclose(to_file) == EOF) {
! 	  int err = errno;
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCloseFailedCopy,
! 			    "Close failed in copy: %s: %s"), 
! 		    to, error_description(err));
! 	  sleep_message();
! 	  return(1);
  	}
  	if (!isspool)
! 	  (void) elm_chown( to, userid, groupid);
  
  	return(0);
  }
***************
*** 212,221 ****
  	}
  
  	if (prefix_str != NULL && fputs(prefix_str, fd) == EOF) {
! 	  MoveCursor(LINES, 0);
  	  Raw(OFF);
! 	  printf(catgets(elm_msg_cat, ElmSet, ElmWriteFailedAppend,
! 		"\nWrite failed to temp file in append\n"));
  	  perror(filename);
  	  rm_temps_exit();
  	}
--- 161,170 ----
  	}
  
  	if (prefix_str != NULL && fputs(prefix_str, fd) == EOF) {
! 	  MoveCursor(elm_LINES, 0);
  	  Raw(OFF);
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWriteFailedAppend,
! 			    "\nWrite failed to temp file in append\n"));
  	  perror(filename);
  	  rm_temps_exit();
  	}
***************
*** 222,240 ****
  
  	while (len = fread(buffer, 1, VERY_LONG_STRING, my_fd))
  	  if (fwrite(buffer, 1, len, fd) != len) {
! 	      MoveCursor(LINES, 0);
  	      Raw(OFF);
! 	      printf(catgets(elm_msg_cat, ElmSet, ElmWriteFailedAppend,
! 		      "\nWrite failed to temp file in append\n"));
  	      perror(filename);
  	      rm_temps_exit();
  	  }
  
  	if (fclose(my_fd) == EOF) {
! 	  MoveCursor(LINES, 0);
  	  Raw(OFF);
! 	  printf(catgets(elm_msg_cat, ElmSet, ElmCloseFailedAppend,
! 		  "\nClose failed on temp file in append\n"));
  	  perror(filename);
  	  rm_temps_exit();
  	}
--- 171,189 ----
  
  	while (len = fread(buffer, 1, VERY_LONG_STRING, my_fd))
  	  if (fwrite(buffer, 1, len, fd) != len) {
! 	      MoveCursor(elm_LINES, 0);
  	      Raw(OFF);
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWriteFailedAppend,
! 				"\nWrite failed to temp file in append\n"));
  	      perror(filename);
  	      rm_temps_exit();
  	  }
  
  	if (fclose(my_fd) == EOF) {
! 	  MoveCursor(elm_LINES, 0);
  	  Raw(OFF);
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCloseFailedAppend,
! 			    "\nClose failed on temp file in append\n"));
  	  perror(filename);
  	  rm_temps_exit();
  	}
***************
*** 309,317 ****
  	return(retcode);
  }
  
- 
  long fsize(fd)
! FILE *fd;
  {
  	/** return the size of the current file pointed to by the given
  	    file descriptor - see "bytes()" for the same function with
--- 258,265 ----
  	return(retcode);
  }
  
  long fsize(fd)
!      FILE *fd;
  {
  	/** return the size of the current file pointed to by the given
  	    file descriptor - see "bytes()" for the same function with
***************
*** 330,333 ****
--- 278,322 ----
  	(void) fstat(fileno(fd), &buffer);
  
  	return( (long) buffer.st_size );
+ }
+ 
+ /* Open and possible creates file for updates and seeks end of file. */
+ 
+ FILE *open_end_update(name)
+      char *name;
+ {
+   
+   FILE *fp;
+   int fd = open(name, O_RDWR | O_CREAT,0600);
+   
+   if (fd < 0) {
+     int err = errno;
+     dprint(1, (debugfile, 
+ 	       "open_end_update: could not open file %s\n\tError: %s\n", 
+ 	       name, error_description(err)));
+ 
+     return NULL;
+   }
+   
+   if (! (fp = fdopen(fd, "r+"))) {
+     dprint(1, (debugfile, 
+ 	       "open_end_update: could not fdopen(%d) file %s\n", 
+ 	       fd,name));
+     
+     close(fd);
+     return NULL;
+   }  
+   
+   if (0 != fseek(fp,0,SEEK_END)) {
+     int err = errno;
+     
+     dprint(1, (debugfile, 
+ 	       "open_end_update: could not seek to EOF %s\n\tError: %s\n", 
+ 	       name, error_description(err)));
+     
+     fclose(fp);
+     return NULL;
+   }
+   
+   return fp;
  }
Index: elm2.4.ME+.50/src/fileio.c
*** elm2.4.25/src/fileio.c	Tue Aug 30 18:08:09 1994
--- elm2.4.ME+.50/src/fileio.c	Tue Nov 17 21:12:57 1998
***************
*** 1,101 ****
  
! static char rcsid[] = "@(#)$Id: fileio.c,v 5.16 1994/08/30 15:08:09 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.16 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: fileio.c,v $
!  * Revision 5.16  1994/08/30  15:08:09  syd
!  * Add an fflush to detect over quota on file saves.
!  * From: Larry Schwimmer <rosebud@cyclone.Stanford.EDU>
!  *
!  * Revision 5.15  1994/08/30  15:06:37  syd
!  * The "copy_message" function in src/fileio.c incorrectly computes the
!  * size of the message.  The "bytes_seen" variable currently counts all
!  * bytes in the message ***including the message header*** when it should
!  * only be counting the bytes in the actual body of the message.
!  * From: Thomas Dwyer III <tomiii@mtu.edu>
!  *
!  * Revision 5.14  1993/09/27  01:51:38  syd
!  * Add elm_chown to consolidate for Xenix not allowing -1
!  * From: Syd
!  *
!  * Revision 5.13  1993/09/19  23:15:52  syd
!  * Here's some more patch stuff for undersize buffers for header lines.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.12  1993/08/23  12:28:23  syd
!  * Fix placement of ifdef for PC_CHOWN
!  * From: syd
!  *
!  * Revision 5.11  1993/08/23  03:26:24  syd
!  * Try setting group id separate from user id in chown to
!  * allow restricted systems to change group id of file
!  * From: Syd
!  *
!  * Revision 5.10  1993/08/10  20:29:52  syd
!  * add PC_CHOWN_RESTRICTED where needed
!  * From: Syd
!  *
!  * Revision 5.9  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.8  1993/02/08  18:38:12  syd
!  * Fix to copy_file to ignore unescaped from if content_length not yet reached.
!  * Fixes to NLS messages match number of newlines between default messages
!  * and NLS messages. Also an extra ) was removed.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.7  1993/01/20  03:02:19  syd
!  * Move string declarations to defs.h
!  * From: Syd
!  *
!  * Revision 5.6  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.5  1992/12/07  04:23:23  syd
!  * fix typo
!  * From: Syd
!  *
!  * Revision 5.4  1992/11/26  01:46:26  syd
!  * add Decode option to copy_message, convert copy_message to
!  * use bit or for options.
!  * From: Syd and bjoerns@stud.cs.uit.no (Bjoern Stabell)
!  *
!  * Revision 5.3  1992/11/26  00:48:34  syd
!  * Make it do raw(off) before final error message to
!  * display error message on proper screen
!  * From: Syd
!  *
!  * Revision 5.2  1992/11/07  20:05:52  syd
!  * change to use header_cmp to allow for linear white space around the colon
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** File I/O routines, including deletion from the folder! 
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: fileio.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** File I/O routines, including deletion from the folder! 
  
***************
*** 105,110 ****
--- 20,26 ----
  #include "s_elm.h"
  #include <sys/stat.h>
  #include <errno.h>
+ #include "me.h"
  
  extern int errno;
  
***************
*** 112,118 ****
  
  static void copy_write_error_exit()
  {
! 	MoveCursor(LINES, 0);
  	Raw(OFF);
  	printf(catgets(elm_msg_cat, ElmSet, ElmWriteCopyMessageFailed,
  		"\nWrite in copy_message failed\n"));
--- 28,34 ----
  
  static void copy_write_error_exit()
  {
! 	MoveCursor(elm_LINES, 0);
  	Raw(OFF);
  	printf(catgets(elm_msg_cat, ElmSet, ElmWriteCopyMessageFailed,
  		"\nWrite in copy_message failed\n"));
***************
*** 120,420 ****
  	rm_temps_exit();
  }
  
! copy_message(prefix, 
! 	     dest_file, 
! 	     cm_options)
! char *prefix;
! FILE *dest_file;
! int cm_options;
  {
! 	/** Copy current message to destination file, with optional 'prefix' 
! 	    as the prefix for each line.  If remove_header is true, it will 
! 	    skip lines in the message until it finds the end of header line...
! 	    then it will start copying into the file... If remote is true
! 	    then it will append "remote from <hostname>" at the end of the
! 	    very first line of the file (for remailing) 
! 
! 	    If "forwarding" is true then it'll do some nice things to
! 	    ensure that the forwarded message looks pleasant; e.g. remove
! 	    stuff like ">From " lines and "Received:" lines.
! 
! 	    If "update_status" is true then it will write a new Status:
! 	    line at the end of the headers.  It never copies an existing one.
! 
! 	    If "decode" is true, prompt for key if the message is encrypted,
! 	    else just copy it as it is.
! 	**/
  
!     /*
!      *	Changed buffer[SLEN] to buffer[VERY_LONG_STRING] to make it
!      *	big enough to contain a full length header line. Any header
!      *	is allowed to be at least 1024 bytes in length. (r.t.f. RFC)
!      *	14-Sep-1993 Jukka Ukkonen <ukkonen@csc.fi>
!      */
  
!     char buffer[VERY_LONG_STRING];
!     register struct header_rec *current_header = headers[current-1];
!     register int  lines, front_line, next_front,
! 		  in_header = 1, first_line = TRUE, ignoring = FALSE;
!     int remove_header = cm_options & CM_REMOVE_HEADER;
!     int remote = cm_options & CM_REMOTE;
!     int update_status = cm_options & CM_UPDATE_STATUS;
!     int remail = cm_options & CM_REMAIL;
!     int decode = cm_options & CM_DECODE;
!     int	end_header = 0;
!     int sender_added = 0;
!     int crypted = 0;
!     int bytes_seen = 0;
!     int buf_len, err;
  
!       /** get to the first line of the message desired **/
  
!     if (fseek(mailfile, current_header->offset, 0) == -1) {
!        dprint(1, (debugfile, 
! 		"ERROR: Attempt to seek %d bytes into file failed (%s)",
! 		current_header->offset, "copy_message"));
!        error1(catgets(elm_msg_cat, ElmSet, ElmSeekFailed,
! 	     "ELM [seek] failed trying to read %d bytes into file."),
! 	     current_header->offset);
!        return;
!     }
  
!     /* how many lines in message? */
  
!     lines = current_header->lines;
  
-     /* set up for forwarding just in case... */
  
!     if (forwarding)
!       remove_header = FALSE;
  
!     if (current_header->encrypted && decode) {
! 	getkey(OFF);
      }
! 
!     /* now while not EOF & still in message... copy it! */
! 
!     next_front = TRUE;
  
!     while (lines) {
!       if (! (buf_len = mail_gets(buffer, VERY_LONG_STRING, mailfile)))
!         break;
  
!       bytes_seen += buf_len;
!       front_line = next_front;
  
-       if(buffer[buf_len - 1] == '\n') {
- 	lines--;	/* got a full line */
- 	next_front = TRUE;
-       }
-       else
- 	next_front = FALSE;
-       
-       if (front_line && ignoring)
- 	ignoring = whitespace(buffer[0]);
  
!       if (ignoring)
! 	continue;
  
  #ifdef MMDF
!       if ((cm_options & CM_MMDF_HEAD) && strcmp(buffer, MSG_SEPARATOR) == 0)
! 	continue;
! #endif /* MMDF */
! 
!       /* are we still in the header? */
! 
!       if (in_header && front_line) {
! 	if (buf_len < 2) {
! 	  in_header = 0;
! 	  bytes_seen = 0;
! 	  end_header = -1;
! 	  if (remail && !sender_added) {
! 	    if (fprintf(dest_file, "%sSender: %s\n", prefix, username) == EOF) {
! 	      copy_write_error_exit();
! 	    }
! 	  }
! 	}
! 	else if (!isspace(*buffer)
! 	      && index(buffer, ':') == NULL
  #ifdef MMDF
! 	      && strcmp(buffer, MSG_SEPARATOR) != 0
  #endif /* MMDF */
! 		) {
! 	  in_header = 0;
! 	  bytes_seen = 0;
! 	  end_header = 1;
! 	  if (remail && !sender_added) {
! 	    if (fprintf(dest_file, "%sSender: %s\n", prefix, username) == EOF) {
! 	      copy_write_error_exit();
! 	    }
  	  }
! 	} else if (in_header && remote && header_cmp(buffer, "Sender", NULL)) {
! 	  if (remail)
! 	    if (fprintf(dest_file, "%sSender: %s\n", prefix, username) == EOF) {
! 	      copy_write_error_exit();
! 	    }
! 	  sender_added = TRUE;
  	  continue;
  	}
! 	if (end_header) {
! 	  if (update_status) {
! 	      if (isoff(current_header->status, NEW)) {
! 		if (ison(current_header->status, UNREAD)) {
! 		  if (fprintf(dest_file, "%sStatus: O\n", prefix) == EOF) {
! 		    copy_write_error_exit();
! 		  }
! 		} else	/* read */
! #ifdef BSD
! 		  if (fprintf(dest_file, "%sStatus: OR\n", prefix) == EOF) {
! #else
! 		  if (fprintf(dest_file, "%sStatus: RO\n", prefix) == EOF) {
! #endif
! 		    copy_write_error_exit();
! 		  }
! 		update_status = FALSE; /* do it only once */
! 	      }	/* else if NEW - indicate NEW with no Status: line. This is
! 		 * important if we resync a mailfile - we don't want
! 		 * NEW status lost when we copy each message out.
! 		 * It is the responsibility of the function that calls
! 		 * this function to unset NEW as appropriate to its
! 		 * reason for using this function to copy a message
! 		 */
! 
! 		/*
! 		 * add the missing newline for RFC 822
! 		 */
! 	      if (end_header > 0) {
! 		/* add the missing newline for RFC 822 */
! 		if (fprintf(dest_file, "\n") == EOF) {
! 		  copy_write_error_exit();
! 		}
! 	      }
  	  }
  	}
        }
! 
!       if (in_header) {
! 	/* Process checks while in header area */
! 
! 	if (remove_header) {
! 	  ignoring = TRUE;
! 	  continue;
! 	}
! 
! 	/* add remote on to front? */
! 	if (first_line && remote) {
! 	  no_ret(buffer);
! #ifndef MMDF
! 	  if (fprintf(dest_file, "%s%s remote from %s\n",
! 		  prefix, buffer, hostname) == EOF) {
! 		copy_write_error_exit();
! 	  }
! #else
! 	  if (first_word(buffer, "From ")) {
! 	    if (fprintf(dest_file, "%s%s remote from %s\n",
! 		    prefix, buffer, hostname) == EOF) {
! 		copy_write_error_exit();
! 	    }
! 	  } else {
! 	    if (fprintf(dest_file, "%s%s\n", prefix, buffer) == EOF) {
! 		copy_write_error_exit();
! 	    }
! 	  }
! #endif /* MMDF */
! 	  first_line = FALSE;
! 	  continue;
! 	}
! 
! 	if (!forwarding) {
! 	  if(! header_cmp(buffer, "Status", NULL)) {
! 	    if (fprintf(dest_file, "%s%s", prefix, buffer) == EOF) {
! 	      copy_write_error_exit();
! 	      }
! 	    continue;
! 	  } else {
! 	    ignoring = TRUE;
! 	    continue;	/* we will output a new Status: line later, if desired. */
  	  }
  	}
! 	else { /* forwarding */
! 
! 	  if (header_cmp(buffer, "Received", NULL   ) ||
! 	      first_word_nc(buffer, ">From"         ) ||
! 	      header_cmp(buffer, "Status", NULL     ) ||
! 	      header_cmp(buffer, "Return-Path", NULL))
! 	      ignoring = TRUE;
! 	  else
! 	    if (remail && header_cmp(buffer, "To", NULL)) {
! 	      if (fprintf(dest_file, "%sOrig-%s", prefix, buffer) == EOF) {
! 		copy_write_error_exit();
! 	      }
! 	    } else {
! 	      if (fprintf(dest_file, "%s%s", prefix, buffer) == EOF) {
! 		copy_write_error_exit();
! 	      }
! 	    }
  	}
        }
!       else { /* not in header */
!         /* Process checks that occur after the header area */
  
! 	/* perform encryption checks */
! 	if (buffer[0] == '[' && decode) {
! 		if (!strncmp(buffer, START_ENCODE, strlen(START_ENCODE))) {
! 			crypted = ON;
! 		} else if (!strncmp(buffer, END_ENCODE, strlen(END_ENCODE))) {
! 			crypted = OFF;
! 		} else if (crypted) {
! 			no_ret(buffer);
! 			encode(buffer);
! 			strcat(buffer, "\n");
! 		}
! 	} else if (crypted) {
! 		no_ret(buffer);
! 		encode(buffer);
! 		strcat(buffer, "\n");
! 	}
  
  
! #ifndef MMDF
! #ifndef DONT_ESCAPE_MESSAGES
! 	if(first_word(buffer, "From ") && (real_from(buffer, NULL)) &&
! 	   current_header->content_length <= bytes_seen) {
! 	  /* If we have a content-length > bytes_seen and there is lines left
! 	  ** this is probably a From line that is part of the body, as an
! 	  ** included message. A simple heuristic test.
! 	  */
! 	  dprint(1, (debugfile,
! 		 "\n*** Internal Problem...Tried to add the following;\n"));
! 	  dprint(1, (debugfile,
! 		 "  '%s'\nto output file (copy_message) ***\n", buffer));
! 	  break;	/* STOP NOW! */
! 	}
! #endif /* DONT_ESCAPE_MESSAGES */
! #endif /* MMDF */
  
! 	err = fprintf(dest_file, "%s", prefix);
! 	if (err != EOF)
! 	  err = fwrite(buffer, 1, buf_len, dest_file);
! 	if (err != buf_len) {
! 	  copy_write_error_exit();
! 	}
        }
      }
  #ifndef MMDF
!     if (buf_len + strlen(prefix) > 1)
! 	if (fprintf(dest_file, "\n") == EOF) {	/* blank line to keep mailx happy *sigh* */
! 	  copy_write_error_exit();
! 	}
! #endif /* MMDF */
! 
!     /* Since fprintf is buffered, its return value is only useful for
!      * writes which exceed the blocksize.  Do a fflush to ensure that
!      * the message has, in fact, been written.
!      */
!     if (fflush(dest_file) == EOF) {
!       copy_write_error_exit();
      }
  }
  
  static struct stat saved_buf;
--- 36,750 ----
  	rm_temps_exit();
  }
  
! #ifdef USE_PGP
! /* Prototype */
! static void copy_pgp P_((char *,FILE *,int, struct header_rec *, FILE *));
! 
! static void copy_pgp(prefix,dest_file,cm_options,current_header, infile)
!      char *prefix;
!      FILE *dest_file;
!      int cm_options;
!      struct header_rec *current_header;
!      FILE * infile;
  {
!   int body_bytes = 0;
!   FILE *fpin = NULL, *fpout = NULL;
!   char buffer[VERY_LONG_STRING];
!   int buf_len,err,child;
!   S__ status;
!   int pgp_seen = !pgp_noarmor;
! 
!   dprint(5,(debugfile,
! 	    "copy_pgp called: Need read %d bytes\n",
! 	    current_header->content_length));
! 
!   if ((current_header->pgp & PGP_MESSAGE) && pgp_keeppass) {
!     if (!pgp_goodPassphrase()) {
!       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmDecryptBadPGP,
! 			"Decrypting message... Bad PGP passphrase."));
!       fprintf(dest_file,"[");
!       fprintf(dest_file,catgets(elm_msg_cat, ElmSet, ElmDecryptBadPGP,
! 				"Decrypting message... Bad PGP passphrase."));
!       fprintf(dest_file,"]\n");
!       return;
!     }
!   }
!   
!   if ((child=pgp_decrypt_init(&fpin, &fpout, current_header->pgp & 
! 			      (PGP_MESSAGE|PGP_SIGNED_MESSAGE))) == -1) {
!     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmDecryptFailInitPGP,
! 		      "Decrypting message... Failed to init PGP."));
!     fprintf(dest_file,
! 	    catgets(elm_msg_cat, ElmSet, ElmDecryptFailInitPGPRaw,
! 		    "[Decrypting message... Failed to init PGP. Raw data follows.]\n"));
!     copy_plain(prefix,dest_file,cm_options,current_header,infile);
!     fprintf(dest_file,
! 	    catgets(elm_msg_cat, ElmSet, ElmDecryptEndRaw,
! 		    "[Decrypting message... End of raw data.]\n"));
!     return;
!   }
! 
!   while (body_bytes < current_header->content_length) {      
!     if (! (buf_len = mail_gets(buffer, VERY_LONG_STRING, infile)))
!       break;
!     
!     if (!pgp_seen) {
!       if (strncmp(buffer, "-----BEGIN PGP", 14) == 0) {
! 	pgp_seen = 1;
! 	goto pgp_found;
!       }
!       /* text before PGP section */
!       if (0 == body_bytes)
! 	fprintf(dest_file,"[There is text before PGP section.]\n");
! 
!       err = fprintf(dest_file, "%s", prefix);
!       if (err != EOF)
! 	err = fwrite(buffer, 1, buf_len, dest_file);
!       if (err != buf_len) {
! 	copy_write_error_exit();
!       }	
!     } else {
!       /* Pass PGP section to pgp */
!     pgp_found:
!       if (EOF == fputs(buffer, fpout))
! 	copy_write_error_exit();
!     }
!     body_bytes += buf_len;
!   }
!   if (fclose(fpout) == EOF)
!     copy_write_error_exit();
!   
!   dprint(5,(debugfile,
! 	    "copy_pgp: Passed %d bytes to PGP.\n",
! 	    body_bytes));
!   body_bytes = 0;
! 
!   fprintf(dest_file,"-- Start of PGP%s%s section.\n",
! 	  current_header->pgp & PGP_SIGNED_MESSAGE ? " signed" : "",
! 	  current_header->pgp & PGP_MESSAGE ? " encoded": "");
! 
!   while (0 < (buf_len = mail_gets(buffer, VERY_LONG_STRING, fpin))) {
!     body_bytes += buf_len;
!     
!     err = fprintf(dest_file, "%s", prefix);
!     if (err != EOF)
!       err = fwrite(buffer, 1, buf_len, dest_file);
!     if (err != buf_len) {
!       copy_write_error_exit();
!     }
!   }
!   fclose(fpin);
  
!   {
!     int w,stat=-1;
!     while ((w = my_wait(child,&status)) != child)
!       if (w == -1 && errno != EINTR)
! 	break;
!     if (w == child) {
!       int sig = convert_status(status,&stat);
!       if (sig)
! 	stat = 1;
!     }
!     fprintf(dest_file,"-- End of PGP%s%s section%s\n",
! 	  current_header->pgp & PGP_SIGNED_MESSAGE ? " signed" : "",
! 	  current_header->pgp & PGP_MESSAGE ? " encoded" : "",
! 	  stat ? ", PGP failed!" : ".");
! 
!   }
! 
!   PressAnyKeyToContinue();
!   Raw(ON);
!   dprint(5,(debugfile,
! 	    "copy_pgp: Readed %d bytes from PGP.\n",
! 	    body_bytes));
! }
! #endif /* USE_PGP */
  
! #ifdef MIME
! /* Prototype */
! void copy_mime P_((char *,FILE *,int, struct header_rec *, FILE *));
! 
! void copy_mime(prefix,dest_file,cm_options,current_header, infile)
!      char *prefix;
!      FILE *dest_file;
!      int cm_options;
!      struct header_rec *current_header;
!      FILE *infile;
! {
!   in_state_t  state_in;
!   out_state_t state_out;
!   in_state_clear(&state_in,  STATE_in_file);
!   out_state_clear(&state_out, STATE_out_file);
  
!   dprint(5,(debugfile,
! 	    "copy_mime called: Need read %d bytes\n",
! 	    current_header->content_length));
  
!   attach_parse(current_header, infile);
  
!   set_in_state_file(infile,&state_in);
!   set_out_state_file(dest_file,&state_out);
  
!   state_out.prefix = prefix;
!   state_out.displaying = (cm_options & CM_DISPLAYING) ? 1 : 0;
!   mime_decode(&(current_header->mime_rec), &state_in, &state_out);
!   
!   dprint(5,(debugfile,"copy_mime: mail decoded\n"));
  
  
!   in_state_destroy(&state_in);  
!   out_state_destroy(&state_out);  
! }
! #endif /* MIME */
  
! /* Prototype */
! static void copy_encrypted P_((char *,FILE *,int, struct header_rec *, 
! 			       FILE *));
! 
! static void copy_encrypted(prefix,dest_file,cm_options,current_header,infile)
!      char *prefix;
!      FILE *dest_file;
!      int cm_options;
!      struct header_rec *current_header;
!      FILE *infile;
! {
!   char buffer[VERY_LONG_STRING];
!   long body_bytes = 0;
!   int crypted = OFF;
!   int buf_len, err;
! 
!   dprint(5,(debugfile,
! 	    "copy_encrypted called: Need read %d bytes\n",
! 	    current_header->content_length));
! 
!   getkey(OFF);
! 
!   while (body_bytes < current_header->content_length) {      
!     if (! (buf_len = mail_gets(buffer, sizeof buffer, infile)))
!       break;
!     
!     body_bytes += buf_len;
!     
!     if (!strncmp(buffer, START_ENCODE, strlen(START_ENCODE))) {
!       crypted = ON;
!       fputs("-- Start of (Elm) encoded section.\n",dest_file);
!       continue;
!     } else if (!strncmp(buffer, END_ENCODE, strlen(END_ENCODE))) {
!       crypted = OFF;
!       fputs("-- End of (Elm) encoded section.\n",dest_file);
!       continue;
!     } else if (crypted) {
!       no_ret(buffer);
!       encode(buffer);      
!       strfcat(buffer, "\n", sizeof buffer);
      }
!     if (fprintf(dest_file, "%s%s", prefix, buffer) == EOF) {
!       copy_write_error_exit();
!     }
!   }
!   dprint(5,(debugfile,
! 	      "copy_encrypted: Readed %d bytes from body\n",body_bytes));
! }
  
! /* Prototype */
! void copy_plain P_((char *,FILE *,int, struct header_rec *, FILE *));
  
! void copy_plain(prefix,dest_file,cm_options,current_header, infile) 
!      char *prefix;
!      FILE *dest_file;
!      int cm_options;
!      struct header_rec *current_header;
!      FILE *infile;
! {
!   char buffer[VERY_LONG_STRING];
!   int body_bytes = 0;
!   int buf_len, err;
!  
!   dprint(5,(debugfile,
! 	    "copy_plain called: Need read %d bytes\n",
! 	    current_header->content_length));;
! 
! 
!   while (body_bytes < current_header->content_length) {      
!     if (! (buf_len = mail_gets(buffer, VERY_LONG_STRING, infile)))
!       break;
!     
!     body_bytes += buf_len;
!     
!     err = fprintf(dest_file, "%s", prefix);
!     if (err != EOF)
!       err = fwrite(buffer, 1, buf_len, dest_file);
!     if (err != buf_len) {
!       copy_write_error_exit();
!     }
!   }
!   dprint(5,(debugfile,
! 	      "copy_plain: Readed %d bytes from body\n",body_bytes));
! }
  
  
! copy_decoder_t select_copy_decoder (current_header) 
!      struct header_rec * current_header;
! {
!     if (0)
!       /* Do nothing -- filler */;
! #ifdef MIME
!     else if (current_header->status & MIME_MESSAGE) 
!       return copy_mime; 
! #endif
! #ifdef USE_PGP
!     else if (current_header->pgp & (PGP_MESSAGE|PGP_SIGNED_MESSAGE))
!       return copy_pgp;
! #endif
!     else if (current_header -> encrypted)
!       return copy_encrypted;
!     else
!       return copy_plain;
! }
  
+ void
+ copy_message(infile,
+ 	     current_header,
+ 	     prefix, 
+ 	     dest_file, 
+ 	     cm_options)
+      FILE *infile;
+      struct header_rec *current_header;
+      char *prefix;
+      FILE *dest_file;
+      int cm_options;
+ {
+   /** Copy current message to destination file, with optional 'prefix' 
+     as the prefix for each line.  If remove_header is true, it will 
+     skip lines in the message until it finds the end of header line...
+     then it will start copying into the file... If remote is true
+     then it will append "remote from <hostname>" at the end of the
+     very first line of the file (for remailing) 
+     
+     If "filter_header" is true then it'll do some nice things to
+     ensure that the forwarded message looks pleasant; e.g. remove
+     stuff like ">From " lines and "Received:" lines.
+     
+     If "update_status" is true then it will write a new Status:
+     line at the end of the headers.  It never copies an existing one.
+     
+     If "decode" decode MIME, PGP and elm's (unsafe) own decoding.
+     **/
+   
+   char buffer[32*1024+1]; /* Allow one header line to be 32 KB
+ 			   * after unfolding 
+ 			   */
+   int in_header = 1, first_line = TRUE;
+   int remove_header = cm_options & CM_REMOVE_HEADER;
+   int remove_envelope = cm_options & CM_REMOVE_ENVELOPE;
+   int remote = cm_options & CM_REMOTE;
+   int update_status = cm_options & CM_UPDATE_STATUS;
+   int remail = cm_options & CM_REMAIL;
+   int decode = cm_options & CM_DECODE;
+   int filter_headers = cm_options & CM_FILT_HDR;
+   int bytes_seen = 0, body_bytes = 0;
+   int content_length_seen = FALSE;
+   long CL_pos = -1L, BODY_pos = -1L, END_pos = -1L;
+   int was_binary = current_header -> binary && !decode;
+   
+   int buf_len, err;
+   int i;
+   
+ 
+   dprint(5, (debugfile,
+ 	     "copy_message(cm_options=(%d)%s%s%s%s%s%s%s%s)\n",
+ 	     cm_options,
+ 	     remove_header   ? " CM_REMOVE_HEADER"   : "",
+ 	     remove_envelope ? " CM_REMOVE_ENVELOPE" : "",
+ 	     remote          ? " CM_REMOTE"          : "",
+ 	     update_status   ? " CM_UPDATE_STATUS"   : "",
+ 	     remail          ? " CM_REMAIL"          : "",
+ 	     decode          ? " CM_DECODE"          : "",
+ 	     filter_headers  ? " CM_FILT_HDR"        : "",
+ 	     (cm_options & CM_DISPLAYING) ? " CM_DISPLAYING" : ""));
+   
+   /** get to the first line of the message desired **/
+   
+   if (fseek(infile, current_header->offset, 0) == -1) {
+     dprint(1, (debugfile, 
+ 	       "ERROR: Attempt to seek %d bytes into file failed (%s)",
+ 	       current_header->offset, "copy_message"));
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSeekFailed,
+ 		      "ELM [seek] failed trying to read %d bytes into file."),
+ 	      current_header->offset);
+     return;
+   }
+   
+   /* now while not EOF & still in message... copy it! */
+   
+   dprint(5,(debugfile,"copy_message: [%ld] start mailbox separator section\n",
+ 	    ftell(infile)));
+   
  #ifdef MMDF
!   if (!(CM_MMDF_HEAD & cm_options) && !remove_header && !remove_envelope) {
!     dprint(5,(debugfile,"copy_message: Write MMDF message separator\n"));
!     if (fprintf(dest_file, "%s", MSG_SEPARATOR) == EOF)
!       copy_write_error_exit();
!   }   
! #endif
!   
!   while (in_header) {      
!     long last_pos = ftell(infile);
!     if (last_pos < 0) {
!       dprint(5,(debugfile,"copy_message: ftell(infile) failed!\n"));
!       break;
!     }
!     
!     if (! (buf_len = mail_gets(buffer, sizeof(buffer), infile)))
!       break;
!     
  #ifdef MMDF
!     if (strcmp(buffer, MSG_SEPARATOR) == 0)
!       continue; /* MSG SEPRATOR is already written */
  #endif /* MMDF */
!     
!     if(buffer[buf_len - 1] == '\n') {
!       no_ret(buffer);
!       if (first_word(buffer, "From ")) {
! 	if (first_line && remote && !remove_header && !remove_envelope) {
! 	  if (fprintf(dest_file, "%s%s remote from %s\n",
! 		      prefix, buffer, hostname) == EOF) {
! 	    copy_write_error_exit();
  	  }
! 	  first_line = FALSE;
  	  continue;
  	}
! 	if (!remove_header && !remove_envelope) {
! 	  if (fprintf(dest_file, "%s%s\n", prefix, buffer) == EOF) {
! 	    copy_write_error_exit();
  	  }
  	}
+ 	first_line = FALSE;
+ 	continue;
        }
!       if (!first_line && first_word_nc(buffer, ">From")) {
! 	if (!filter_headers && !remove_header && !remove_envelope) {
! 	  if (fprintf(dest_file, "%s%s\n", prefix, buffer) == EOF) {
! 	    copy_write_error_exit();
  	  }
  	}
! 	continue;	
!       }
!       /* fall thru */
!     }
!     dprint(5,(debugfile,
! 	      "copy_message: Not a mailbox line -- seeking back!\n"));
!     dprint(5,(debugfile,
! 	      "copy_message- Line was: %s\n",buffer));
!     
!     if (0 != fseek(infile,last_pos,SEEK_SET)) {
!       dprint(5,(debugfile,
! 		"copy_message: seek failed!\n"));
!       copy_write_error_exit();
!     }
!     break; /* Go out of loop */
!   }
!   if (first_line) {
!     dprint(5,(debugfile,
! 	      "copy_message: No 'From ' line seen...\n"));
!     if (!remove_header && !remove_envelope) {
!       time_t thetime = time((time_t *) 0);
!       dprint(5,(debugfile,
! 		"copy_message: Create it!\n"));
!       if (fprintf(dest_file,
! 		  "%sFrom %s %s", prefix,username, ctime(&thetime)) == EOF)
! 	copy_write_error_exit();
!     }
!   }
!   
!   dprint(5,(debugfile,"copy_message: [%ld] start header section\n",
! 	    ftell(infile)));
!   
!   while (in_header) {      
!     char * colptr,*hdr,*body,*ptr;
!     int header_class;
! 
!     if ( (buf_len = read_header_line(infile,buffer,sizeof(buffer),
! 				     RHL_CHECK_HEADER|RHL_MARK_FOLDING))
! 	< 2) {
!       dprint(5,(debugfile,"copy_message: End of headers: buf_len=%d\n",
! 		buf_len));
!       break;
!     }
!     
!     bytes_seen += buf_len;
!     
!     colptr = strchr(buffer, ':');
!     if (NULL == colptr) {
!       in_header = 0;
!       dprint(1,(debugfile,"copy_message: Software error; No ':' !!\n"));
!       break;
!     }
!     *colptr = '\0';
!     hdr = buffer;
!     body = colptr +1;
! 
!     if (remove_header)
!       continue;
!     
!     header_class = classify_header(hdr);
!     dprint(12,(debugfile,"copy_message: header=%s,class=%d,rest=%s\n",
! 	       hdr,header_class,body));;
!     
! #ifdef MIME
!     if (decode && !(current_header -> status & NOHDRENCODING)) {
!       
!       if (header_class & HDR_TEXT) {
! 	if (is_rfc1522 (body))
! 	  rfc1522_decode (body, sizeof (buffer) - (body - buffer) -1);
!       } else if (header_class & HDR_STRUCTURED) {
! 	rfc1522_decode_structured(header_class,
! 				  body, 
! 				  sizeof (buffer) -(body - buffer) -1);
!       }
!       
!       dprint(12,(debugfile,"copy_message: decoded rest=%s\n",body));
!     }
! #endif
!     if ((remote || remail) && 0 == istrcmp("Sender",hdr)) {
! 	continue;
!     }
! #ifdef MIME
!     /* These headers are incorrect after decoding ... */
!     if (decode && (current_header->status & MIME_MESSAGE) &&
! 	(0 == istrcmp(buffer, "MIME-Version") ||
! 	 0 == istrcmp(buffer, "Content-Type") ||
! 	 0 == istrcmp(buffer, "Content-Transfer-Encoding")))
!       continue;
! #endif
!     
!     if(0 == istrcmp(buffer, "Content-Length")) {
!       /* make correct Content-Length later */
!       content_length_seen = TRUE;
!       continue;
!     }
!     
!     if (!filter_headers) {
!       if (0 == istrcmp(buffer,"Status"))
! 	continue;   /* we will output a new Status: line later, if desired. */
!     }
!     else { /* filter_headers */
!       if (0 == istrcmp(buffer, "Received") ||
! 	  0 == istrcmp(buffer, "Status") ||
! 	  0 == istrcmp(buffer, "Return-Path"))
! 	continue;
!       if (remail && 0 == istrcmp(buffer, "To"))
! 	hdr = "Orig-To";
!     }
!     dprint(5,(debugfile,"copy_message- hdr=%s body=%s\n",hdr,body));
!     
!     for (ptr = strtok(body,"\n"); ptr; ptr = strtok(NULL,"\n")) { 
!       if (fprintf(dest_file,"%s",prefix) == EOF)
! 	copy_write_error_exit ();
!       
!       if (ptr > body) { /* Do folding */
! 	--ptr;
! 	if (*(ptr+1) == ' ')
! 	  *ptr = ' ';
! 	else
! 	  *ptr = '\t';
!       } else {
! 	if (fprintf(dest_file,"%s:",hdr) == EOF)
! 	  copy_write_error_exit ();
!       }
!       if (fprintf(dest_file,"%s%s",ptr,was_binary ? "\r\n" : "\n") == EOF)
! 	copy_write_error_exit ();
!     }       
!   }
!   
!   dprint(5,(debugfile,
! 	    "copy_message: [%ld] end of headers. Readed ~ %d bytes.\n",
! 	    ftell(infile), bytes_seen));
! 
!   if (!remove_header) {  
!     if (!filter_headers && content_length_seen) {
! 	if (fprintf (dest_file, "Content-Length: ") == EOF)
! 	  copy_write_error_exit ();
! 	CL_pos = ftell(dest_file);
! 	if (fprintf (dest_file, "%5d%s",
! 		     current_header->content_length,
! 		     was_binary ? "\r\n" : "\n") == EOF)
! 	  copy_write_error_exit ();
!     }
!     if (remail) {
!       if (fprintf (dest_file, "%sSender: %s%s",
! 		   prefix,username,
! 		   was_binary ? "\r\n" : "\n") == EOF)
! 	copy_write_error_exit ();
!     }
!     if (update_status) {
!       if (isoff(current_header->status, NEW)) {
! 	if (fprintf (dest_file, "%sStatus: ", prefix) == EOF)
! 	  copy_write_error_exit ();
! 	
! 	if (ison(current_header->status, UNREAD)) {
! 	  if (fprintf(dest_file, "O") == EOF)
! 	    copy_write_error_exit();
! 	} else {	/* read */
! 	if (fprintf(dest_file, "RO") == EOF)
! 	  copy_write_error_exit();
! 	
! 	if (ison(current_header->status, REPLIED)) {
! 	  if (fprintf (dest_file, "r") == EOF)
! 	    copy_write_error_exit ();
  	}
        }
! 	
! 	/* save all the status flags that ELM doesn't understand */
! 	for (i=0; current_header->mailx_status[i] != '\0'; i++)
! 	  switch (current_header->mailx_status[i]) {
! 	  case 'R':
! 	  case 'O':
! 	  case 'r':
! 	    break;
! 	  default:
! 	    if (fprintf (dest_file, "%c", current_header->mailx_status[i]) == EOF)
! 	      copy_write_error_exit ();
! 	  }
! 	if (fprintf(dest_file, was_binary ? "\r\n" : "\n") == EOF) {
! 	  copy_write_error_exit();
! 	}      
!       }	/* else if NEW - indicate NEW with no Status: line. This is
! 	 * important if we resync a mailfile - we don't want
! 	 * NEW status lost when we copy each message out.
! 	 * It is the responsibility of the function that calls
! 	 * this function to unset NEW as appropriate to its
! 	 * reason for using this function to copy a message
! 	 */
!     }
!     
!     /*
!      * Add empty line between headers and body (that was not copied
!      *  in above)
!      */
  
!     if (fprintf(dest_file, was_binary ? "\r\n" : "\n") == EOF) {
!       copy_write_error_exit();
!     }
!   }
!    
!   dprint(5,(debugfile,
! 	    "copy_message: [%ld] Starting reading of body: %d bytes expected\n",
! 	    ftell(infile),
! 	    current_header->content_length));
! 
!   BODY_pos = ftell(dest_file);
! 
!   dprint(5,(debugfile,
! 	    "copy_message> output offset=[%ld]\n",BODY_pos));
!      
!   if (decode) {
!     copy_decoder_t decoder = select_copy_decoder(current_header);
!     decoder(prefix,dest_file,cm_options,current_header,infile);
!   } else    
!     copy_plain(prefix,dest_file,cm_options,current_header,infile);
! 
!   END_pos = ftell(dest_file);
! 
!   dprint(5,(debugfile,
! 	    "copy_message: [%ld] Body readed.\n",
! 	    ftell(infile)));
!   dprint(5,(debugfile,
! 	    "copy_message> output offset=[%ld]\n",END_pos));
! 
!   if (CL_pos > 0 && BODY_pos > 0 && END_pos >= BODY_pos) {
!     /* Actually written content length is good if conversions are
!      * not done and there was no errors ... 
!      */
!     clearerr(dest_file);
! 
!     /* Notice that these tests indicates failure */
!     if (0   != fseek(dest_file,CL_pos,SEEK_SET) ||
! 	ftell(dest_file) != CL_pos ||
! 	EOF == fprintf (dest_file, "%5d", (int) (END_pos - BODY_pos)) ||
! 	0   != fseek(dest_file,END_pos,SEEK_SET)) {
!       dprint(5,(debugfile,
! 		"copy_message: Writing Content-length -- writing or seeking failed.\n"));
!       copy_write_error_exit();
!     } else {
!       dprint(5,(debugfile,
! 		"copy_message: Content-length fixed: %d bytes.\n",
! 		(int) (END_pos - BODY_pos)));
!     }
!       
!   }
!   
!   {
!     char buffer[2];
!     int i;
!     long NEW_pos = END_pos - 2L;
!     buffer[0] = '\0';
!     buffer[1] = '\0';
!     if (NEW_pos < 0L)
!       NEW_pos = 0L;
! 
!     if (0 != fseek(dest_file,NEW_pos,SEEK_SET)) {
!       dprint(5,(debugfile,
! 		"copy_message: Failed to seek to %ld (output)\n",
! 		NEW_pos)); 
!     }
  
+     i = fread(buffer,sizeof (char),2,dest_file);
+     if (i < 0) {
+       dprint(5,(debugfile,
+ 		"copy_message: Read error! (output)\n"));
+       i = 0;
+     } else {
+       dprint(5,(debugfile,
+ 		"copy_message: readed %d bytes (output). \n",i));
+     }
+     
+     for (; i < 2; i++) {
+       buffer[i] = '\0';
+     }
  
!     dprint(5,(debugfile,
! 	      "copy_message: [%ld] last two bytes %d %d (output)\n",
! 	      ftell(infile), buffer[0], buffer[1])); 
!     
!     if (0 != fseek(dest_file,0L,SEEK_CUR)) {
!       dprint(5,(debugfile,
! 		"copy_message: Failed to seek 0 bytes (output)\n"));
!     }
  
!     if (buffer[1] != '\n') {
!       /* No \n in end ? */ 	
!       dprint(5,(debugfile,
! 		"copy_message: NL missing from end of mail\n")); 
!       if (fprintf(dest_file, "\n") == EOF) {
! 	dprint(5,(debugfile,
! 		  "copy_message: Failed to add NL to end of mail\n"));
! 	copy_write_error_exit();
        }
      }
  #ifndef MMDF
!     if (buffer[0] != '\n') {
!       dprint(5,(debugfile,
! 		"copy_message: NL NL missing from end of mail\n")); 
!       /* blank line to keep mailx happy *sigh* */      
!       if (fprintf(dest_file, "\n") == EOF) {
! 	dprint(5,(debugfile,
! 		  "copy_message: Failed to add second NL to end of mail\n"));
! 	copy_write_error_exit();
!       }
      }
+ #endif
+   }
+   
+   /* Since fprintf is buffered, its return value is only useful for
+    * writes which exceed the blocksize.  Do a fflush to ensure that
+    * the message has, in fact, been written.
+    */
+   if (fflush(dest_file) == EOF) {
+     dprint(5,(debugfile,
+ 	      "copy_message: Final fflush failed!\n")); 
+     copy_write_error_exit();
+   }
  }
  
  static struct stat saved_buf;
***************
*** 436,442 ****
  	 */
  
  	if(stat(fname, &saved_buf) != -1) {
! 	  (void)strcpy(saved_fname, fname);
  	  dprint(2, (debugfile,
  	    "** saved stats for file owner = %d group = %d mode = %o %s **\n",
  	    saved_buf.st_uid, saved_buf.st_gid, saved_buf.st_mode, fname));
--- 766,772 ----
  	 */
  
  	if(stat(fname, &saved_buf) != -1) {
! 	  strfcpy(saved_fname, fname, sizeof saved_fname);
  	  dprint(2, (debugfile,
  	    "** saved stats for file owner = %d group = %d mode = %o %s **\n",
  	    saved_buf.st_uid, saved_buf.st_gid, saved_buf.st_mode, fname));
***************
*** 461,516 ****
  	 */
  
  	int old_umask, i, new_mode, new_owner, new_group, ret_code;
! 
! 
! 	new_mode = 0600;
  	new_owner = userid;
  	new_group = groupid;
  	ret_code = 0;
  
  	if(strcmp(fname, saved_fname) == 0) {
! 	  new_mode = saved_buf.st_mode;
  	  new_owner = saved_buf.st_uid;
  	  new_group = saved_buf.st_gid;
  	  ret_code = 1;
  	}
  	dprint(2, (debugfile, "** %s file stats for %s **\n",
! 	  (ret_code ? "restoring" : "setting"), fname));
  
  	old_umask = umask(0);
! 	if((i = chmod(fname, new_mode & 0777)) == -1)
  	  ret_code = -1;
  
! 	dprint(2, (debugfile, "** chmod(%s, %.3o) returns %d [errno=%d] **\n",
! 		fname, new_mode & 0777, i, errno));
  
  	(void) umask(old_umask);
  
! #ifdef	BSD
! 	/*
! 	 * Chown is restricted to root on BSD unix
! 	 */
! 	(void) elm_chown(fname, new_owner, new_group);
  #else
  #  ifdef _PC_CHOWN_RESTRICTED
! /*
!  * Chown may or may not be restricted to root in SVR4, if it is,
!  *	then need to copy must be true, and no restore of permissions
!  *	should be performed.
!  */
!         if (!pathconf(fname, _PC_CHOWN_RESTRICTED)) {
  #  endif
! 	    if((i = elm_chown(fname, new_owner, new_group)) == -1)
  		ret_code = -1;
! 
! 	    dprint(2, (debugfile, "** elm_chown(%s, %d, %d) returns %d [errno=%d] **\n",
! 		       fname, new_owner, new_group, i, errno));
  #  ifdef _PC_CHOWN_RESTRICTED
! 	} else {
! 	    (void) elm_chown(fname, new_owner, new_group);
! 	}
  #  endif /* _PC_CHOWN_RESTRICTED */
! #endif /* BSD */
  
  	return(ret_code);
  
--- 791,877 ----
  	 */
  
  	int old_umask, i, new_mode, new_owner, new_group, ret_code;
! 	struct stat testbuf;
! 	new_mode = mail_permissions;
  	new_owner = userid;
  	new_group = groupid;
  	ret_code = 0;
  
  	if(strcmp(fname, saved_fname) == 0) {
! 	  new_mode = saved_buf.st_mode & 0777;
! 	  
! 	  /* Restore also special bits if file is NOT executable */
! 	  if (!(saved_buf.st_mode & 0111)) {
! 	    new_mode |= saved_buf.st_mode & 07000;
! 	    dprint(2, (debugfile, 
! 		       "** not excutable -- restore also special modes\n"));
! 	  }
! 
  	  new_owner = saved_buf.st_uid;
  	  new_group = saved_buf.st_gid;
  	  ret_code = 1;
  	}
+ 
  	dprint(2, (debugfile, "** %s file stats for %s **\n",
! 		   (ret_code ? "restoring" : "setting"), fname));
  
  	old_umask = umask(0);
! 	if((i = chmod(fname, new_mode)) == -1)
  	  ret_code = -1;
  
! 	dprint(2, (debugfile, "** chmod(%s, %05o) returns %d [errno=%d] **\n",
! 		   fname, new_mode, i, errno));
  
  	(void) umask(old_umask);
  
! 	if(stat(fname, &testbuf) != -1) {
! 	  dprint(2, (debugfile,
! 	    "** stats for file owner = %d group = %d mode = %o %s **\n",
! 	    testbuf.st_uid, testbuf.st_gid, testbuf.st_mode, fname));
! 
! 	  /* Don't do chown because it resets special modes, if not
! 	   * neccessary 
! 	   */
! 	  
! 	  if (new_owner == testbuf.st_uid && new_group == testbuf.st_gid) {
! 	    dprint(2, (debugfile,
! 		       "** Owner correct -- chown not needed.\n"));
! 
! 	  } else {
! 
! #ifdef	BSD_TYPE
! 	    /*
! 	     * Chown is restricted to root on BSD unix
! 	     */
! 	    (void) elm_chown(fname, new_owner, new_group);
  #else
  #  ifdef _PC_CHOWN_RESTRICTED
! 	    /*
! 	     * Chown may or may not be restricted to root in SVR4, if it is,
! 	     *	then need to copy must be true, and no restore of permissions
! 	     *	should be performed.
! 	     */
! 	    if (!pathconf(fname, _PC_CHOWN_RESTRICTED)) {
  #  endif
! 	      if((i = elm_chown(fname, new_owner, new_group)) == -1)
  		ret_code = -1;
! 	      
! 	      dprint(2, (debugfile, "** elm_chown(%s, %d, %d) returns %d [errno=%d] **\n",
! 			 fname, new_owner, new_group, i, errno));
  #  ifdef _PC_CHOWN_RESTRICTED
! 	    } else {
! 	      (void) elm_chown(fname, new_owner, new_group);
! 	    }
  #  endif /* _PC_CHOWN_RESTRICTED */
! #endif /* BSD_TYPE */
! 	  }
! 	}
! 	
! 	if(stat(fname, &testbuf) != -1) {
! 	  dprint(2, (debugfile,
! 	    "** stats for file owner = %d group = %d mode = %o %s **\n",
! 	    testbuf.st_uid, testbuf.st_gid, testbuf.st_mode, fname));
! 	}
  
  	return(ret_code);
  
Index: elm2.4.ME+.50/src/find_alias.c
*** elm2.4.25/src/find_alias.c	Sun Oct  4 01:58:55 1992
--- elm2.4.ME+.50/src/find_alias.c	Tue Nov 17 21:12:58 1998
***************
*** 1,24 ****
  
! static char rcsid[] = "@(#)$Id: find_alias.c,v 5.1 1992/10/03 22:58:40 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.1 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: find_alias.c,v $
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** 
  	Search the list of aliases for a specific address.  Search
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: find_alias.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** 
  	Search the list of aliases for a specific address.  Search
Index: elm2.4.ME+.50/src/forms.c
*** elm2.4.25/src/forms.c	Tue Aug  3 22:10:22 1993
--- elm2.4.ME+.50/src/forms.c	Tue Nov 17 21:12:57 1998
***************
*** 1,38 ****
  
! static char rcsid[] = "@(#)$Id: forms.c,v 5.4 1993/08/03 19:10:22 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: forms.c,v $
!  * Revision 5.4  1993/08/03  19:10:22  syd
!  * The last character of a form field gets zapped if more characters than
!  * the field expects are entered.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.3  1993/02/03  19:06:31  syd
!  * Remove extra strchr/strcat/strcpy et al declarations
!  * From: Syd
!  *
!  * Revision 5.2  1992/11/26  00:46:50  syd
!  * Fix how errno is used so err is inited and used instead
!  * as errno gets overwritten by print system call
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This set of files supports the 'forms' options (AT&T Mail Forms) to
      the mail system.  The specs are drawn from a document from AT&T entitled
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: forms.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /*****************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  ****************************************************************************/
  
  /** This set of files supports the 'forms' options (AT&T Mail Forms) to
      the mail system.  The specs are drawn from a document from AT&T entitled
***************
*** 63,68 ****
--- 41,47 ----
  #include "headers.h"
  #include "s_elm.h"
  #include <errno.h>
+ #include "me.h"
  
  extern int errno;
  
***************
*** 79,88 ****
  	register int field_count = 0;
  
  	if ((form = fopen(filename, "r")) == NULL) {
! 	  error2(catgets(elm_msg_cat, ElmSet, ElmErrorOpeningCheckFields,
! 		  "Error %s trying to open %s to check fields!"),
! 		  error_description(errno), filename);
! 	  return(-1);
  	}
  	
  	while (mail_gets(buffer, SLEN, form)) {
--- 58,67 ----
  	register int field_count = 0;
  
  	if ((form = fopen(filename, "r")) == NULL) {
! 	 lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorOpeningCheckFields,
! 			   "Error %s trying to open %s to check fields!"),
! 		   error_description(errno), filename);
! 	 return(-1);
  	}
  	
  	while (mail_gets(buffer, SLEN, form)) {
***************
*** 114,121 ****
  
  	if ((form = fopen(filename, "r")) == NULL) {
  	  err = errno;
! 	  error(catgets(elm_msg_cat, ElmSet, ElmCantReadMessageToValidate,
! 		"Can't read the message to validate the form!"));
  	  dprint(1, (debugfile,
                "** Error encountered opening file \"%s\" - %s (check_form) **\n",
  	      filename, error_description(err)));
--- 93,100 ----
  
  	if ((form = fopen(filename, "r")) == NULL) {
  	  err = errno;
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCantReadMessageToValidate,
! 			    "Can't read the message to validate the form!"));
  	  dprint(1, (debugfile,
                "** Error encountered opening file \"%s\" - %s (check_form) **\n",
  	      filename, error_description(err)));
***************
*** 122,133 ****
  	  return(-1);
  	}
  
! 	sprintf(newfname, "%s%s%d", temp_dir, temp_form_file, getpid());
  
! 	if ((newform = fopen(newfname, "w")) == NULL) {
  	  err = errno;
! 	  error(catgets(elm_msg_cat, ElmSet, ElmCouldntOpenNewformOutput,
! 		"Couldn't open newform file for form output!"));
  	  dprint(1, (debugfile, 
                "** Error encountered opening file \"%s\" - %s (check_form) **\n",
  	      newfname, error_description(err)));
--- 101,113 ----
  	  return(-1);
  	}
  
! 	elm_sfprintf(newfname, sizeof newfname,
! 		     FRM("%s%s%d"), temp_dir, temp_form_file, getpid());
  
! 	if ((newform = safeopen(newfname)) == NULL) {
  	  err = errno;
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldntOpenNewformOutput,
! 			    "Couldn't open newform file for form output!"));
  	  dprint(1, (debugfile, 
                "** Error encountered opening file \"%s\" - %s (check_form) **\n",
  	      newfname, error_description(err)));
***************
*** 154,176 ****
  
  	if (form_count > 0) {
  	  if (unlink(filename) != 0) {
! 	    error2(catgets(elm_msg_cat, ElmSet, ElmErrorUnlinkingFile,
! 		"Error %s unlinking file %s."),
! 		error_description(errno), filename);
  	    return(-1);
  	  }
  	  if (link(newfname, filename)) {
! 	    error3(catgets(elm_msg_cat, ElmSet, ElmErrorLinkingFile,
! 		"Error %s linking %s to %s."),
! 		    error_description(errno), newfname, filename);
  	    return(-1);
  	  }
  	}
  
  	if (unlink(newfname)) {
! 	  error2(catgets(elm_msg_cat, ElmSet, ElmErrorUnlinkingFile,
! 	        "Error %s unlinking file %s."),
! 		error_description(errno), newfname);
  	  return(-1);	
  	}
  
--- 134,157 ----
  
  	if (form_count > 0) {
  	  if (unlink(filename) != 0) {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorUnlinkingFile,
! 			      "Error %s unlinking file %s."),
! 		      error_description(errno), 
! 		      filename);
  	    return(-1);
  	  }
  	  if (link(newfname, filename)) {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorLinkingFile,
! 			      "Error %s linking %s to %s."),
! 		      error_description(errno), newfname, filename);
  	    return(-1);
  	  }
  	}
  
  	if (unlink(newfname)) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorUnlinkingFile,
! 			    "Error %s unlinking file %s."),
! 		    error_description(errno), newfname);
  	  return(-1);	
  	}
  
***************
*** 199,207 ****
  		   "Error: seek %ld resulted in errno %s (%s)\n", 
  		   headers[current-1]->offset, error_description(errno), 
  		   "mail_filled_in_form"));
! 	  error2(catgets(elm_msg_cat, ElmSet, ElmSeekFailedFile,
! 		"ELM [seek] couldn't read %d bytes into file (%s)."),
! 	         headers[current-1]->offset, error_description(errno));
  	  return(0);
          }
   
--- 180,188 ----
  		   "Error: seek %ld resulted in errno %s (%s)\n", 
  		   headers[current-1]->offset, error_description(errno), 
  		   "mail_filled_in_form"));
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSeekFailedFile,
! 			    "ELM [seek] couldn't read %d bytes into file (%s)."),
! 		    headers[current-1]->offset, error_description(errno));
  	  return(0);
          }
   
***************
*** 212,219 ****
  	  if (len_buf == 1)	/* <return> only */
  	    break;
  	  else if (lines >= max_lines) { 
! 	    error(catgets(elm_msg_cat, ElmSet, ElmNoFormInMessage,
! 		"No form in this message!?"));
  	    return(0);
  	  }
  
--- 193,200 ----
  	  if (len_buf == 1)	/* <return> only */
  	    break;
  	  else if (lines >= max_lines) { 
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNoFormInMessage,
! 			      "No form in this message!?"));
  	    return(0);
  	  }
  
***************
*** 222,229 ****
  	}
  
  	if (len_buf == 0) {
! 	  error(catgets(elm_msg_cat, ElmSet, ElmNoFormInMessage,
! 	      "No form in this message!?"));
  	  return(0);
  	}
  
--- 203,210 ----
  	}
  
  	if (len_buf == 0) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNoFormInMessage,
! 			    "No form in this message!?"));
  	  return(0);
  	}
  
***************
*** 242,256 ****
  	    lines++;
  
  	  if (lines >= max_lines) {
! 	    error(catgets(elm_msg_cat, ElmSet, ElmBadForm,
! 		"Badly constructed form.  Can't reply!"));
  	    return(0);
  	  }
  	}
  
  	if (len_buf == 0) {
! 	  error(catgets(elm_msg_cat, ElmSet, ElmBadForm,
! 		"Badly constructed form.  Can't reply!"));
  	  return(0);
  	}
  
--- 223,237 ----
  	    lines++;
  
  	  if (lines >= max_lines) {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadForm,
! 			      "Badly constructed form.  Can't reply!"));
  	    return(0);
  	  }
  	}
  
  	if (len_buf == 0) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadForm,
! 			    "Badly constructed form.  Can't reply!"));
  	  return(0);
  	}
  
***************
*** 258,271 ****
  	
  	/* one last thing - let's open the tempfile for output... */
  	
! 	sprintf(buffer, "%s%s%d", temp_dir, temp_form_file, getpid());
  
  	dprint(2, (debugfile,"-- forms sending using file %s --\n", buffer));
  
! 	if ((fd = fopen(buffer,"w")) == NULL) {
! 	  error2(catgets(elm_msg_cat, ElmSet, ElmCantOpenAsOutputFile,
! 		"Can't open \"%s\" as output file! (%s)."),
! 		buffer, error_description(errno));
  	  dprint(1, (debugfile,
  		  "** Error %s encountered trying to open temp file %s;\n",
  		  error_description(errno), buffer));
--- 239,253 ----
  	
  	/* one last thing - let's open the tempfile for output... */
  	
! 	elm_sfprintf(buffer, sizeof buffer,
! 		     FRM("%s%s%d"), temp_dir, temp_form_file, getpid());
  
  	dprint(2, (debugfile,"-- forms sending using file %s --\n", buffer));
  
! 	if ((fd = safeopen(buffer)) == NULL) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCantOpenAsOutputFile,
! 			    "Can't open \"%s\" as output file! (%s)."),
! 		    buffer, error_description(errno));
  	  dprint(1, (debugfile,
  		  "** Error %s encountered trying to open temp file %s;\n",
  		  error_description(errno), buffer));
***************
*** 315,321 ****
  
  	/** let's just mail this off now... **/
  
! 	mail_form(address, subject);
  
  	return(1);
  }
--- 297,303 ----
  
  	/** let's just mail this off now... **/
  
! 	mail_form(headers[current-1],address, subject);
  
  	return(1);
  }
***************
*** 337,344 ****
  		"prompt-for-multiple [%d] -entries \"%s\"\n", entries,
  		buffer));
  
! 	strcpy(prompt, catgets(elm_msg_cat, ElmSet, ElmFormNoPrompt,
! 		"No Prompt Available:"));
  
  	while (entries--) {
  	  j=0; 
--- 319,326 ----
  		"prompt-for-multiple [%d] -entries \"%s\"\n", entries,
  		buffer));
  
! 	strfcpy(prompt, catgets(elm_msg_cat, ElmSet, ElmFormNoPrompt,
! 		"No Prompt Available:"), sizeof prompt);
  
  	while (entries--) {
  	  j=0; 
***************
*** 373,379 ****
  
  	  /*  field_size-1 for the space spaces[] starts with  */
  	  for (j = strlen(mybuffer); j < field_size-1; j++)
! 	    strcat(spaces, " ");
  
  	  fprintf(fd, "%s: %s%s", prompt, mybuffer, spaces);
  	  fflush(fd);
--- 355,361 ----
  
  	  /*  field_size-1 for the space spaces[] starts with  */
  	  for (j = strlen(mybuffer); j < field_size-1; j++)
! 	    strfcat(spaces, " ", sizeof spaces);
  
  	  fprintf(fd, "%s: %s%s", prompt, mybuffer, spaces);
  	  fflush(fd);
Index: elm2.4.ME+.50/src/hdrconfg.c
*** elm2.4.25/src/hdrconfg.c	Tue Aug  3 22:29:09 1993
--- elm2.4.ME+.50/src/hdrconfg.c	Tue Nov 17 21:12:57 1998
***************
*** 1,42 ****
  
! static char rcsid[] = "@(#)$Id: hdrconfg.c,v 5.3 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: hdrconfg.c,v $
!  * Revision 5.3  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.2  1992/11/22  01:15:15  syd
!  * Add on initial display or display where the entire screen is being
!  * drawn, we should not output the trailing blanks that clear the old
!  * value.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /**   This file contains the routines necessary to be able to modify
        the mail headers of messages on the way off the machine.  The
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: hdrconfg.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /**   This file contains the routines necessary to be able to modify
        the mail headers of messages on the way off the machine.  The
***************
*** 62,70 ****
  /*
   * Placement of prompts and messages at the bottom of the screen.
   */
! #define INSTRUCT_LINE           (LINES-4)
! #define INPUT_LINE		(LINES-2)
! #define ERROR_LINE		(LINES-1)
  #define TOPMOST_PROMPTAREA_LINE INSTRUCT_LINE
  
  /*
--- 36,44 ----
  /*
   * Placement of prompts and messages at the bottom of the screen.
   */
! #define INSTRUCT_LINE           (elm_LINES-4)
! #define INPUT_LINE		(elm_LINES-2)
! #define ERROR_LINE		(elm_LINES-1)
  #define TOPMOST_PROMPTAREA_LINE INSTRUCT_LINE
  
  /*
***************
*** 104,109 ****
--- 78,85 ----
  			/*   the "inpval" value to "expval" value.  If	*/
  			/*   no verification or expansion is needed	*/
  			/*   then this will be NULL.			*/
+     int size_inpval;
+     int size_expval;
  };
  
  /*
***************
*** 127,161 ****
  static int hdrproc_expires();
  static int hdrproc_precedence();
  static int hdrproc_userhdr();
- static int domainize_submenu();
- static void domainize();
- static void domainize_addr();
  
  /*
   * Definition of all the header editing menu fields.
   */
  struct hdr_menu_item hmenu_item_list[] = {
!     { 't', "T)o",		 2, HF_DISP_3ROW|HF_APPENDENTRY,
! 					to, expanded_to, hdrproc_addr },
!     { 'c', "C)c",		 5, HF_DISP_3ROW|HF_APPENDENTRY,
! 					cc, expanded_cc, hdrproc_addr },
!     { 'b', "B)cc",		 8, HF_DISP_2ROW|HF_APPENDENTRY,
! 					bcc, expanded_bcc, hdrproc_addr },
!     { 's', "S)ubject",		10, HF_DISP_2ROW, subject, subject, NULL },
!     { 'r', "R)eply-to",		12, HF_DISP_1ROW, reply_to, expanded_reply_to,
! 					hdrproc_addr },
!     { 'a', "A)ction",		13, HF_DISP_LEFT, action, action, NULL },
!     { 'e', "E)xpires",		13, HF_DISP_RIGHT|HF_PROMPT_EXP, expires_days,
! 					expires, hdrproc_expires },
!     { 'p', "P)riority",		14, HF_DISP_LEFT, priority, priority, NULL },
!     { 'n', "Precede(n)ce",	14, HF_DISP_RIGHT, precedence,
! 					precedence, hdrproc_precedence },
!     { 'i', "I)n-reply-to",	15, HF_DISP_2ROW,
! 					in_reply_to, in_reply_to, NULL },
!     { 'u', NULL,		17, HF_DISP_1ROW|HF_PROMPT_USR,
! 					user_defined_header,
! 					user_defined_header, hdrproc_userhdr },
!     { -1, NULL, -1, -1, NULL, NULL, NULL },
  };
  
  /*
--- 103,152 ----
  static int hdrproc_expires();
  static int hdrproc_precedence();
  static int hdrproc_userhdr();
  
  /*
   * Definition of all the header editing menu fields.
   */
  struct hdr_menu_item hmenu_item_list[] = {
!   { 't', "T)o",		 2, HF_DISP_3ROW|HF_APPENDENTRY,
!     to, expanded_to, hdrproc_addr,
!     sizeof to, sizeof expanded_to
!   },
!   { 'c', "C)c",		 5, HF_DISP_3ROW|HF_APPENDENTRY,
!     cc, expanded_cc, hdrproc_addr,
!     sizeof cc, sizeof expanded_cc
!   },
!   { 'b', "B)cc",		 8, HF_DISP_2ROW|HF_APPENDENTRY,
!     bcc, expanded_bcc, hdrproc_addr,
!     sizeof bcc, sizeof expanded_bcc
!   },
!   { 's', "S)ubject",		10, HF_DISP_2ROW, subject, subject, NULL,
!     sizeof subject, sizeof subject
!   },
!   { 'r', "R)eply-to",		12, HF_DISP_1ROW, reply_to, expanded_reply_to,
!     hdrproc_addr, sizeof reply_to, sizeof expanded_reply_to 
!   },
!   { 'a', "A)ction",		13, HF_DISP_LEFT, action, action, NULL,
!     sizeof action, sizeof action
!   },
!   { 'e', "E)xpires",		13, HF_DISP_RIGHT|HF_PROMPT_EXP, expires_days,
!     expires, hdrproc_expires, sizeof expires_days, sizeof expires 
!   },
!   { 'p', "P)riority",		14, HF_DISP_LEFT, priority, priority, NULL,
!     sizeof priority, sizeof priority
!   },
!   { 'n', "Precede(n)ce",	14, HF_DISP_RIGHT, precedence,
!     precedence, hdrproc_precedence, sizeof precedence, sizeof precedence
!   },
!   { 'i', "I)n-reply-to",	15, HF_DISP_2ROW,
!     in_reply_to, in_reply_to, NULL, sizeof in_reply_to, sizeof in_reply_to
!   },
!   { 'u', NULL,		17, HF_DISP_1ROW|HF_PROMPT_USR,
!     user_defined_header,
!     user_defined_header, hdrproc_userhdr,
!     sizeof user_defined_header, sizeof user_defined_header 
!   },
!   { -1, NULL, -1, -1, NULL, NULL, NULL, 0, 0 },
  };
  
  /*
***************
*** 179,184 ****
--- 170,176 ----
  {
      int c, i, do_redraw;
      struct hdr_menu_item *h;
+     int precmd = 0;
      
      /* expand out all of the header values */
      /* menu displays expanded values, user edits unexpended versions */
***************
*** 187,193 ****
  	    (*h->hdrproc)(h);
      }
  
!     clearerr(stdin);
      do_redraw = TRUE;
      while (TRUE) {	/* forever */
  
--- 179,185 ----
  	    (*h->hdrproc)(h);
      }
  
! redraw:
      do_redraw = TRUE;
      while (TRUE) {	/* forever */
  
***************
*** 205,221 ****
  #ifdef ALLOW_SUBSHELL
  	Centerline(INSTRUCT_LINE, catgets(elm_msg_cat, ElmSet,
  	    ElmHdrmenuInstruct,
! 	    "Choose header, u)ser defined header, d)omainize, !)shell, or <return>."));
  #else
  	Centerline(INSTRUCT_LINE, catgets(elm_msg_cat, ElmSet,
  	    ElmHdrmenuInstructNoShell,
! 	    "Choose header, u)ser defined header, d)omainize, or <return>."));
  #endif
  
  	/* prompt for command */
  	PutLine0(INPUT_LINE, 0, catgets(elm_msg_cat, ElmSet,
  	    ElmHdrmenuPrompt, "Choice: "));
! 	c = getchar();
  	if (isupper(c))
  	    c = tolower(c);
  	hdrmenu_clear_promptarea();
--- 197,223 ----
  #ifdef ALLOW_SUBSHELL
  	Centerline(INSTRUCT_LINE, catgets(elm_msg_cat, ElmSet,
  	    ElmHdrmenuInstruct,
! 	    "Choose header, u)ser defined header, !)shell, or <return>."));
  #else
  	Centerline(INSTRUCT_LINE, catgets(elm_msg_cat, ElmSet,
  	    ElmHdrmenuInstructNoShell,
! 	    "Choose header, u)ser defined header, or <return>."));
  #endif
  
  	/* prompt for command */
  	PutLine0(INPUT_LINE, 0, catgets(elm_msg_cat, ElmSet,
  	    ElmHdrmenuPrompt, "Choice: "));
! 	if (precmd) {
! 	  c = precmd;
! 	  precmd = 0;
! 	} else {
! 	  c = ReadCh(REDRAW_MARK);
! 	  if (c == REDRAW_MARK) {
! 	    do_redraw = TRUE;
! 	    continue;
! 	  }
! 	}
! 
  	if (isupper(c))
  	    c = tolower(c);
  	hdrmenu_clear_promptarea();
***************
*** 229,239 ****
  	case 'q':
  	    return 0;
  
- 	case 'd':
- 	    if (domainize_submenu() != 0)
- 		return 0;
- 	    break;
- 
  #ifdef ALLOW_SUBSHELL
  	case '!':
  	    if (subshell())
--- 231,236 ----
***************
*** 248,257 ****
  	default:
  	    for (h = hmenu_item_list ; h->menucmd > 0 ; ++h) {
  		if (h->menucmd == c) {
! 		    if (hdrmenu_get(h) != 0)
! 			return 0;
! 		    hdrmenu_put(h, FALSE);
  		    break;
  		}
  	    }
  	    if (h->menucmd <= 0) {
--- 245,261 ----
  	default:
  	    for (h = hmenu_item_list ; h->menucmd > 0 ; ++h) {
  		if (h->menucmd == c) {
! 		  int status = hdrmenu_get(h);
! 		  if (REDRAW_MARK == status) {
! 		    precmd = c;
! 		    do_redraw = TRUE;
  		    break;
+ 		  }
+ 
+ 		  if (status != 0)
+ 		    return 0;
+ 		  hdrmenu_put(h, FALSE);
+ 		  break;
  		}
  	    }
  	    if (h->menucmd <= 0) {
***************
*** 325,331 ****
  
      /* get input from the user */
      do_append = ((h->flags & HF_APPENDENTRY) != 0);
!     ret = optionally_enter(h->inpval, INPUT_LINE, plen, do_append, FALSE);
      hdrmenu_clear_promptarea();
  
      /* bail out on error */
--- 329,340 ----
  
      /* get input from the user */
      do_append = ((h->flags & HF_APPENDENTRY) != 0);
!     ret = optionally_enter(h->inpval, INPUT_LINE, plen, 
! 			   (do_append ? OE_APPEND_CURRENT : 0) | 
! 			   OE_REDRAW_MARK, h->size_inpval);
!     if (ret == REDRAW_MARK)
!       return REDRAW_MARK;
! 
      hdrmenu_clear_promptarea();
  
      /* bail out on error */
***************
*** 349,376 ****
  {
      char    *p;
      int     start_row, max_row, start_col, max_col, row, col;
  
      /* figure out the dimensions of the field */
      switch (h->flags & HF_DISP_MASK) {
      case HF_DISP_LEFT:
  	start_row = h->lineno;		max_row = h->lineno;
! 	start_col = 0;			max_col = COLUMNS/2 - 2;
  	break;
      case HF_DISP_RIGHT:
  	start_row = h->lineno;		max_row = h->lineno;
! 	start_col = COLUMNS/2 + 1;	max_col = COLUMNS-1;
  	break;
      case HF_DISP_3ROW:
  	start_row = h->lineno;		max_row = h->lineno+2;
! 	start_col = 0;			max_col = COLUMNS-1;
  	break;
      case HF_DISP_2ROW:
  	start_row = h->lineno;		max_row = h->lineno+1;
! 	start_col = 0;			max_col = COLUMNS-1;
  	break;
      default:
  	start_row = h->lineno;		max_row = h->lineno;
! 	start_col = 0;			max_col = COLUMNS-1;
  	break;
      }
  
--- 358,386 ----
  {
      char    *p;
      int     start_row, max_row, start_col, max_col, row, col;
+     char buffer[LONG_STRING];
  
      /* figure out the dimensions of the field */
      switch (h->flags & HF_DISP_MASK) {
      case HF_DISP_LEFT:
  	start_row = h->lineno;		max_row = h->lineno;
! 	start_col = 0;			max_col = elm_COLUMNS/2 - 2;
  	break;
      case HF_DISP_RIGHT:
  	start_row = h->lineno;		max_row = h->lineno;
! 	start_col = elm_COLUMNS/2 + 1;	max_col = elm_COLUMNS-1;
  	break;
      case HF_DISP_3ROW:
  	start_row = h->lineno;		max_row = h->lineno+2;
! 	start_col = 0;			max_col = elm_COLUMNS-1;
  	break;
      case HF_DISP_2ROW:
  	start_row = h->lineno;		max_row = h->lineno+1;
! 	start_col = 0;			max_col = elm_COLUMNS-1;
  	break;
      default:
  	start_row = h->lineno;		max_row = h->lineno;
! 	start_col = 0;			max_col = elm_COLUMNS-1;
  	break;
      }
  
***************
*** 385,391 ****
  
      /* display the header value */
      GetXYLocation(&row, &col);
!     for (p = h->expval ; *p != '\0' && row <= max_row ; ++p) {
  	if (row == max_row && col == max_col-4 && strlen(p) > 4)
  	    p = " ...";		/* neat hack alert */
  	Writechar(*p);
--- 395,411 ----
  
      /* display the header value */
      GetXYLocation(&row, &col);
! 
!     strfcpy(buffer, h->expval, sizeof buffer);
! #ifdef MIME
!     if (!allow_no_hdrencoding && h->hdrproc == hdrproc_addr && 
! 	is_rfc1522(buffer)) {
!       /* HDR_PHRASE is not needed because there is no phrases */
!       rfc1522_decode_structured(0,buffer,sizeof buffer);
!     }
! #endif
! 
!     for (p = buffer ; *p != '\0' && row <= max_row ; ++p) {
  	if (row == max_row && col == max_col-4 && strlen(p) > 4)
  	    p = " ...";		/* neat hack alert */
  	Writechar(*p);
***************
*** 397,403 ****
      if (!already_clear) {
  
  	/* clear out remaining space in this line of the field */
! 	if (max_col == COLUMNS-1) {
  	    /* people on slow terminals might appreciate doing it this way */
  	    CleartoEOLN();
  	} else {
--- 417,423 ----
      if (!already_clear) {
  
  	/* clear out remaining space in this line of the field */
! 	if (max_col == elm_COLUMNS-1) {
  	    /* people on slow terminals might appreciate doing it this way */
  	    CleartoEOLN();
  	} else {
***************
*** 424,430 ****
  static int hdrproc_addr(h)
  struct hdr_menu_item *h;
  {
!     (void) build_address(strip_commas(h->inpval), h->expval);
      return 0;
  }
  
--- 444,451 ----
  static int hdrproc_addr(h)
  struct hdr_menu_item *h;
  {
!     (void) build_address(strip_commas(h->inpval), h->expval,
! 			 h->size_inpval, h->size_expval);
      return 0;
  }
  
***************
*** 463,469 ****
      }
  
      /* convert number of days to a date */
!     days_ahead(days, h->expval);
      return 0;
  }
  
--- 484,490 ----
      }
  
      /* convert number of days to a date */
!     days_ahead(days, h->expval, h->size_expval);
      return 0;
  }
  
***************
*** 491,497 ****
  
      /* the "allowed_precedences[]" format is: */
      /*   precedence[:priority-value] precedence[:priority-value] ... */
!     bp = strcpy(buf, allowed_precedences);
      while ((prec = strtok(bp, " \t\n")) != NULL) {
  	bp = NULL;
  	if ((prio = index(prec, ':')) != NULL)
--- 512,518 ----
  
      /* the "allowed_precedences[]" format is: */
      /*   precedence[:priority-value] precedence[:priority-value] ... */
!     bp = strfcpy(buf, allowed_precedences, sizeof buf);
      while ((prec = strtok(bp, " \t\n")) != NULL) {
  	bp = NULL;
  	if ((prio = index(prec, ':')) != NULL)
***************
*** 511,517 ****
  
      /* see if this precedence has an associated priority */
      if (prio != NULL && hmenu_priority.inpval[0] == '\0') {
! 	(void) strcpy(hmenu_priority.inpval, prio);
  	hdrmenu_put(&hmenu_priority, FALSE);
      }
  
--- 532,539 ----
  
      /* see if this precedence has an associated priority */
      if (prio != NULL && hmenu_priority.inpval[0] == '\0') {
! 	(void) strfcpy(hmenu_priority.inpval, prio,
! 		       hmenu_priority.size_inpval);
  	hdrmenu_put(&hmenu_priority, FALSE);
      }
  
***************
*** 556,714 ****
      }
  
      return 0;
- }
- 
- 
- /*
-  * Prompt the user to domainize a header.
-  */
- static int domainize_submenu()
- {
-     int c;
-     struct hdr_menu_item *h;
- 
-     Centerline(INSTRUCT_LINE, catgets(elm_msg_cat, ElmSet,
- 	ElmHdrmenuDomInstruct,
- 	"Select header to domainize:  T)o, C)c, B)cc, or <return>."));
-     PutLine0(INPUT_LINE, 0, catgets(elm_msg_cat, ElmSet,
- 	ElmHdrmenuDomPrompt, "Domainize choice: "));
- 
-     for (;;) {
- 
- 	c = getchar();
- 
- 	switch (tolower(c)) {
- 	case 't':
- 	    h = &hmenu_to;
- 	    break;
- 	case 'c':
- 	    h = &hmenu_cc;
- 	    break;
- 	case 'b':
- 	    h = &hmenu_bcc;
- 	    break;
- 	case '\r':
- 	case '\n':
- 	case EOF:
- 	    h = NULL;
- 	    break;
- 	default:
- 	    Writechar('\007');
- 	    continue;
- 	}
- 
- 	if (h != NULL) {
- 	    domainize(h->expval);
- 	    hdrmenu_put(h, FALSE);
- 	}
- 
- 	hdrmenu_clear_promptarea();
- 	return (c == EOF ? -1 : 0);
- 
-     }
- 
-     /*NOTREACHED*/
- }
- 
- 
- 
- static void domainize(addresses)
- char *addresses;
- {
- 	/*** Convert the given addresses from bang paths to domain format.
- 	     This policy amounts to Rabid Rerouting.  However, since it's
- 	     under the sender's control, I don't mind. ***/
- 
- 	char buffer[VERY_LONG_STRING];
- 	char *a, *d;
- 	int how_many;
- 
- 	strcpy(buffer, addresses);
- 	a = buffer;
- 	d = addresses;
- 	how_many = 0;
- 
- 	for (;;) {
- 	  while (*a == ' ' || *a == ',')
- 	    ++a;
- 	  if (*a == '\0')
- 	    break;
- 
- 	  if (*a == '(' || *a == '"') {
- 	    int endch;
- 
- 	    if (d != addresses)
- 	      *d++ = ' ';
- 	    endch = (*a == '(') ? ')' : '"';
- 	    while (*a && *a != endch) {
- 	      if (*a == '\\' && *(a + 1))
- 		*d++ = *a++;
- 	      *d++ = *a++;
- 	    }
- 	    if (*a)
- 	      *d++ = *a++;
- 	  }
- 	  else {
- 	    char *addr;
- 
- 	    if (how_many) {
- 	      *d++ = ',';
- 	      *d++ = ' ';
- 	    }
- 	    ++how_many;
- 
- 	    if (*a == '<') {
- 	      *d++ = *a++;
- 	      addr = a;
- 	      while (*a && *a != '>') {
- 		if (*a == '\\' && *(a + 1))
- 		  ++a;
- 		++a;
- 	      }
- 	      if (*a)
- 		*a++ = '\0';
- 	      domainize_addr(addr, d);
- 	      d += strlen(d);
- 	      *d++ = '>';
- 	    }
- 	    else {
- 	      addr = a;
- 	      while (*a && *a != ' ' && *a != ',')
- 		++a;
- 	      if (*a)
- 		*a++ = '\0';
- 	      domainize_addr(addr, d);
- 	      d += strlen(d);
- 	    }
- 	  }
- 	}
- 
- 	*d = '\0';
- }
- 
- static void domainize_addr(src, dest)
- char *src, *dest;
- {
- 	/*** Convert one address to domain form. ***/
- 
- 	char *locpart, *host;
- 
- 	if (index(src, '@') != NULL
- 	 || (locpart = rindex(src, '!')) == NULL) {
- 	  strcpy(dest, src);
- 	  return;
- 	}
- 
- 	*locpart++ = '\0';
- 
- 	if ((host = rindex(src, '!')) != NULL)
- 	  ++host;
- 	else
- 	  host = src;
- 	sprintf(dest, "%s@%s", locpart, host);
- 	if (!index(host, '.'))
- 	  strcat(dest, ".uucp");
- 
- 	*--locpart = '!';
  }
  
--- 578,582 ----
Index: elm2.4.ME+.50/src/help.c
*** elm2.4.25/src/help.c	Mon May 30 19:42:49 1994
--- elm2.4.ME+.50/src/help.c	Tue Nov 17 21:12:57 1998
***************
*** 1,55 ****
  
! static char rcsid[] = "@(#)$Id: help.c,v 5.6 1994/05/30 16:42:48 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.6 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: help.c,v $
!  * Revision 5.6  1994/05/30  16:42:48  syd
!  * Just a minor fix to an impossible character comparison.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.5  1994/03/11  21:25:24  syd
!  * Fix Elm looping if an EOF is received.
!  * From: Gregory Neil Shapiro <gshapiro@WPI.EDU>
!  *
!  * Revision 5.4  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.3  1993/04/12  03:15:41  syd
!  * These patches makes 'T' (since it was free) do a Tag and Move command in the
!  * index and alias page, and in the builtin pager.
!  * In the alias help in src/alias.c, there is a tolower done on the character
!  * one wants help for.  This is clearly wrong.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.2  1993/01/20  03:37:16  syd
!  * Nits and typos in the NLS messages and corresponding default messages.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /*** help routine for ELM program 
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: help.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /*** help routine for ELM program 
  
***************
*** 82,99 ****
  			  "Unknown command.  Use '?' for a list of commands.");
  	}
  
! 	MoveCursor(LINES-4,0);
  	CleartoEOS();
  
  	if(pager_help) {
  	  put_border();
! 	  Centerline(LINES, help_message);
! 	  prompt_line = LINES-3;
  	} else {
! 	  Centerline(LINES-4, catgets(elm_msg_cat, ElmSet, ElmHelpSystem,
! 		"ELM Help System"));
! 	  Centerline(LINES-3, help_message);
! 	  prompt_line = LINES-2;
  	}
  	info_line = prompt_line + 1;
  
--- 43,60 ----
  			  "Unknown command.  Use '?' for a list of commands.");
  	}
  
! 	MoveCursor(elm_LINES-4,0);
  	CleartoEOS();
  
  	if(pager_help) {
  	  put_border();
! 	  Centerline(elm_LINES, help_message);
! 	  prompt_line = elm_LINES-3;
  	} else {
! 	  Centerline(elm_LINES-4, catgets(elm_msg_cat, ElmSet, ElmHelpSystem,
! 					  "ELM Help System"));
! 	  Centerline(elm_LINES-3, help_message);
! 	  prompt_line = elm_LINES-2;
  	}
  	info_line = prompt_line + 1;
  
***************
*** 101,108 ****
  
  	do {
  	  MoveCursor(prompt_line, strlen(help_prompt));
! 	  ch = ReadCh();
  	  
  	  if (ch == '.') return(0);	/* zero means footer rewrite only */
  
  	  s = unknown_command;
--- 62,70 ----
  
  	do {
  	  MoveCursor(prompt_line, strlen(help_prompt));
! 	  ch = ReadCh(REDRAW_MARK|READCH_CURSOR);
  	  
+ 	  if (ch == REDRAW_MARK) return 1;
  	  if (ch == '.') return(0);	/* zero means footer rewrite only */
  
  	  s = unknown_command;
***************
*** 109,114 ****
--- 71,77 ----
  
  	  switch (ch) {
  
+ 	  case HELP_MARK:
  	    case '?': display_helpfile(pager_help? PAGER_HELP : MAIN_HELP);
  		      return(1);
  
***************
*** 141,150 ****
--- 104,116 ----
  				"* = Go to the last message in the current folder.");
  		      break;
  
+ 	  case LEFT_MARK:
+ 	  case PAGEUP_MARK:
  	    case '-': if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpPreviousPage,
  "- = Go to the previous page of messages.  This is the same as the LEFT arrow.");
  		      break;
  
+ 	  case HOME_MARK:
  	    case '=': if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpFirstMessage,
  			"'=' = Go to the first message in the current folder.");
  		      break;
***************
*** 157,167 ****
--- 123,136 ----
  				"<space> = Display the current message.");
  		      break;
  
+ 	  case RIGHT_MARK:
+ 	  case PAGEDOWN_MARK:
  	    case '+': if(!pager_help)
  	    		s = catgets(elm_msg_cat, ElmSet, ElmHelpNextPage,
    "+ = Go to the next page of messages.  This is the same as the RIGHT arrow.");
  		      break;
  
+ 	  case FIND_MARK:
  	    case '/': if(!pager_help)
  			s = catgets(elm_msg_cat, ElmSet, ElmHelpSearchFolder,
  				"/ = Search for specified pattern in folder.");
***************
*** 207,213 ****
  		      break;
  
  #ifdef ALLOW_MAILBOX_EDITING
! 	    case 'e': if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpEditor,
       "e = Invoke the editor on the entire folder, resynchronizing when done.");
  		      break;
  #endif
--- 176,184 ----
  		      break;
  
  #ifdef ALLOW_MAILBOX_EDITING
! 	    case 'e': if (user_level < 2)
! 			break;
! 		      if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpEditor,
       "e = Invoke the editor on the entire folder, resynchronizing when done.");
  		      break;
  #endif
***************
*** 233,238 ****
--- 204,210 ----
  			"J = Go to the next message.");
  		      break;
  
+ 	  case DOWN_MARK:
  	    case 'j': s = catgets(elm_msg_cat, ElmSet, ElmHelpNextUndeleted,
    "j = Go to the next undeleted message.  This is the same as the DOWN arrow.");
  		      break;
***************
*** 241,246 ****
--- 213,219 ----
  			"K = Go to the previous message.");
  		      break;
  
+ 	  case UP_MARK:
  	    case 'k': s = catgets(elm_msg_cat, ElmSet, ElmHelpPreviousUndeleted,
  "k = Go to the previous undeleted message.  This is the same as the UP arrow.");
  		      break;
***************
*** 306,311 ****
--- 279,289 ----
  	    case ctrl('U') : s = catgets(elm_msg_cat, ElmSet, ElmHelpUndeletePattern,
  		      "^U = Undelete all messages with the specified pattern.");
  		      break;
+ #ifdef MIME
+             case 'v':  s = catgets(elm_msg_cat, ElmSet, ElmHelpViewAttach,
+                        "v = View Attachments in current message.");
+                        break;
+ #endif
  
  	    case 'x': s = catgets(elm_msg_cat, ElmSet, ElmHelpExitFolder,
  			"x = Exit leaving the folder untouched, ask permission if changed.");
***************
*** 365,371 ****
  
  	char buffer[SLEN];
  
! 	sprintf(buffer, "%s/%s.%d", helphome, helpfile, section);
  	return(display_file(buffer));
  }
  
--- 343,350 ----
  
  	char buffer[SLEN];
  
! 	elm_sfprintf(buffer, sizeof buffer,
! 		     FRM("%s/%s.%d"), helphome, helpfile, section);
  	return(display_file(buffer));
  }
  
***************
*** 381,388 ****
  	if ((fileptr = fopen(file,"r")) == NULL) {
  	  dprint(1, (debugfile,
  		 "Error: Couldn't open file %s (help)\n", file));
! 	  error1(catgets(elm_msg_cat, ElmSet, ElmHelpCouldntOpenFile,
! 		"Couldn't open file %s."), file);
  	  return(FALSE);
  	}
  	
--- 360,368 ----
  	if ((fileptr = fopen(file,"r")) == NULL) {
  	  dprint(1, (debugfile,
  		 "Error: Couldn't open file %s (help)\n", file));
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmHelpCouldntOpenFile,
! 			    "Couldn't open file %s."), 
! 		    file);
  	  return(FALSE);
  	}
  	
***************
*** 389,398 ****
  	ClearScreen();
  
  	while (fgets(buffer, SLEN, fileptr) != NULL) {
! 	  if (lines > LINES-3) {
! 	    PutLine0(LINES, 0, catgets(elm_msg_cat, ElmSet, ElmHelpPressSpaceToContinue,
! 		"Press <space> to continue, 'q' to return."));
! 	    if(ReadCh() == 'q') {
  	      clear_error();
  	      fclose(fileptr);
  	      return(TRUE);
--- 369,380 ----
  	ClearScreen();
  
  	while (fgets(buffer, SLEN, fileptr) != NULL) {
! 	  if (lines > elm_LINES-3) {
! 	    PutLine0(elm_LINES, 0, 
! 		     catgets(elm_msg_cat, ElmSet, 
! 			     ElmHelpPressSpaceToContinue,
! 			     "Press <space> to continue, 'q' to return."));
! 	    if(ReadCh(0) == 'q') {
  	      clear_error();
  	      fclose(fileptr);
  	      return(TRUE);
***************
*** 399,416 ****
  	    }
  	    lines = 0;
  	    ClearScreen();
! 	    Write_to_screen("%s\r", 1, buffer);
  	  }
  	  else 
! 	    Write_to_screen("%s\r", 1, buffer);
  
! 	  lines += strlen(buffer)/COLUMNS + 1;
  	}
  
!         PutLine0(LINES, 0, catgets(elm_msg_cat, ElmSet, ElmHelpPressAnyKeyToReturn,
  		"Press any key to return."));
  
! 	(void) ReadCh();
  	clear_error();
  
  	fclose(fileptr);
--- 381,399 ----
  	    }
  	    lines = 0;
  	    ClearScreen();
! 	    Write_to_screen(FRM("%s\r"), buffer);
  	  }
  	  else 
! 	    Write_to_screen(FRM("%s\r"), buffer);
  
! 	  lines += strlen(buffer)/elm_COLUMNS + 1;
  	}
  
!         PutLine0(elm_LINES, 0, catgets(elm_msg_cat, ElmSet, 
! 				       ElmHelpPressAnyKeyToReturn,
  		"Press any key to return."));
  
! 	(void) ReadCh(0);
  	clear_error();
  
  	fclose(fileptr);
Index: elm2.4.ME+.50/src/in_utils.c
*** elm2.4.25/src/in_utils.c	Thu Sep  1 22:42:41 1994
--- elm2.4.ME+.50/src/in_utils.c	Tue Nov 17 21:12:57 1998
***************
*** 1,114 ****
  
! static char rcsid[] = "@(#)$Id: in_utils.c,v 5.16 1994/09/01 19:42:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.16 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: in_utils.c,v $
!  * Revision 5.16  1994/09/01  19:42:39  syd
!  * Moved #defines for SETJMP & LONGJMP from src/editmsg.c to hdrs/defs.h and
!  * used them instead of (set|long)jmp directly. This makes the usage consistent
!  * and Solaris 2.3 behaves correctly w.r.t stop/continue.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.15  1994/08/30  18:16:05  syd
!  * Fix up Solaris and SVR4 signal handling for timeout
!  * From: Syd
!  *
!  * Revision 5.14  1994/03/11  21:25:24  syd
!  * Fix Elm looping if an EOF is received.
!  * From: Gregory Neil Shapiro <gshapiro@WPI.EDU>
!  *
!  * Revision 5.13  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.12  1993/08/03  19:10:50  syd
!  * Patch for Elm 2.4 PL22 to correct handling of SIGWINCH signals on
!  * DecStations with Ultrix 4.2.
!  * The problem was that elm running in an xterm exits silently when the
!  * window is resize. This was caused by incorrect signal handling for BSD.
!  * From: vogt@isa.de
!  *
!  * Revision 5.11  1993/05/16  20:56:18  syd
!  * fix want-to patch collision
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.10  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.9  1993/04/12  03:38:19  syd
!  * In GetPrompt(), when timeout = 0 make sure we check the return of
!  * ReadCh() for EINTR on non-POSIX (BSDish) systems.
!  * From: tom@osf.org
!  *
!  * Revision 5.8  1993/04/12  03:09:17  syd
!  * want_to() wrote "No." when user pressed return even if the default answer
!  * wasn't == *def_ans_no.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.7  1993/04/12  02:34:36  syd
!  * I have now added a parameter which controls whether want_to clears the
!  * line and centers the question or behaves like it did before. I also
!  * added a 0 at the end of the parameter list to all the other calls to
!  * want_to where a centered question on a clean line is not desirable.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.6  1993/01/30  15:57:19  syd
!  * fix where it clears the prompt from
!  *
!  * Revision 5.5  1993/01/29  03:43:46  syd
!  * back out change to clear question line,
!  * its worse that the original problem.
!  * From: Syd
!  *
!  * Revision 5.4  1993/01/27  20:48:01  syd
!  * Change where confirm prompt are written.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.3  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.2  1992/11/15  01:15:28  syd
!  * The alias message_count isn't set to zero if the last alias has
!  * been deleted from the alias table. As no aliases are reread from
!  * the aliases database the message_count is left as it was before.
!  *
!  * Fixed that the function do_newalias() sometimes returns without freeing
!  * the buffer allocated before. The patch adds these free calls.
!  *
!  * When you erroneously type a number in your folder elm asks you for
!  * a new current message number. But now if you erase this one number
!  * and leave the string empty elm will set the new current message to
!  * the second message on our sun4! The patch adds a check for an empty
!  * string and returns the current number if no number was entered.
!  * From: vogt@isa.de (Gerald Vogt)
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** Mindless I/O routines for ELM 
  	
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: in_utils.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** Mindless I/O routines for ELM 
  	
***************
*** 116,121 ****
--- 18,24 ----
  
  #include "headers.h"
  #include "s_elm.h"
+ #include "me.h"
  #include <errno.h>
  
  extern int errno;		/* system error number */
***************
*** 127,136 ****
  #define erase_a_char()		{ Writechar(BACKSPACE); Writechar(' '); \
  			          Writechar(BACKSPACE); fflush(stdout); }
  
! int
! want_to(question, dflt, where, clear_and_center)
! char *question, dflt;
! int where, clear_and_center;
  {
  	/** Ask 'question' on 'where' left enough to just leave room for an
  	    answer, returning the answer in lower case.
--- 30,39 ----
  #define erase_a_char()		{ Writechar(BACKSPACE); Writechar(' '); \
  			          Writechar(BACKSPACE); fflush(stdout); }
  
! int want_to(question, dflt, where, clear_and_center)
!      char *question;
!      int dflt;
!      int where, clear_and_center;
  {
  	/** Ask 'question' on 'where' left enough to just leave room for an
  	    answer, returning the answer in lower case.
***************
*** 140,146 ****
  	**/
  	register int ch, cols;
  
! 	cols = COLUMNS - (strlen(question) + 5 );	/* 5 for "Yes." + 1 */
  	if (cols < 0) {
  	    cols = 0;
  	}
--- 43,50 ----
  	**/
  	register int ch, cols;
  
! redraw:
! 	cols = elm_COLUMNS - (strlen(question) + 5 );	/* 5 for "Yes." + 1 */
  	if (cols < 0) {
  	    cols = 0;
  	}
***************
*** 148,167 ****
  	MoveCursor(where, (clear_and_center || (cols < 2)) ? 0 : cols-2);
  	CleartoEOLN();
  
! 	PutLine3(where, clear_and_center ? cols/2 : cols,
! 		 "%s%c%c", question, dflt, BACKSPACE);
  	fflush(stdout);
  	fflush(stdin);
  
! 	ch = ReadCh();
! 	if (ch == EOF)
  	  leave(0);
  	ch = tolower(ch);
  
  	while (!( ch == *def_ans_yes || ch == *def_ans_no || ch == '\n' || ch == '\r')) {
! 	  ch = ReadCh();
! 	  if (ch == EOF)
  	    leave(0);
  	  ch = tolower(ch);
  	}
  	if(ch == '\n' || ch == '\r')
--- 52,77 ----
  	MoveCursor(where, (clear_and_center || (cols < 2)) ? 0 : cols-2);
  	CleartoEOLN();
  
! 	PutLineX(where, clear_and_center ? cols/2 : cols,
! 		 FRM("%s%c%c"), question, dflt, BACKSPACE);
  	fflush(stdout);
  	fflush(stdin);
  
! 	ch = ReadCh(REDRAW_MARK);
! 	if (ch == REDRAW_MARK)
! 	  goto redraw;
! 	if (ch == EOF) {
  	  leave(0);
+ 	}
  	ch = tolower(ch);
  
  	while (!( ch == *def_ans_yes || ch == *def_ans_no || ch == '\n' || ch == '\r')) {
! 	  ch = ReadCh(REDRAW_MARK);
! 	  if (ch == REDRAW_MARK)
! 	    goto redraw;
! 	  if (ch == EOF) {
  	    leave(0);
+ 	  }
  	  ch = tolower(ch);
  	}
  	if(ch == '\n' || ch == '\r')
***************
*** 168,176 ****
  	  ch = dflt;
  
  	if(ch == *def_ans_yes)
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmYesWord, "Yes."), 0);
  	else if (ch == *def_ans_no)
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmNoWord, "No."), 0);
  	else
  	  return(ch); /* Don't write anything, just return */
  
--- 78,86 ----
  	  ch = dflt;
  
  	if(ch == *def_ans_yes)
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmYesWord, "Yes."));
  	else if (ch == *def_ans_no)
! 	  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmNoWord, "No."));
  	else
  	  return(ch); /* Don't write anything, just return */
  
***************
*** 182,203 ****
  	return(ch);
  }
  
! int
! read_number(ch, item)
! char ch, *item;
  {
  	/** Read a number, where 'ch' is the leading digit! **/
  	
! 	char buff[NLEN];
! 	int  num;
  
  	buff[0] = ch;
  	buff[1] = '\0';
  
! 	PutLine1(LINES-3, COLUMNS-40,catgets(elm_msg_cat, ElmSet, ElmSetCurrentTo,
! 		"Set current %s to :"), item);
! 	if (optionally_enter(buff, LINES-3, COLUMNS-15, TRUE, FALSE) == -1)
  	  return(current);
  
  	if (buff[0] == '\0')
  	  return(current);
--- 92,121 ----
  	return(ch);
  }
  
! int read_number(ch, item)
!      int ch;
!      char *item;
  {
  	/** Read a number, where 'ch' is the leading digit! **/
  	
! 	char buff[SLEN+1];
! 	int  num, status;
  
  	buff[0] = ch;
  	buff[1] = '\0';
  
! redraw:
! 	PutLineX(elm_LINES-3, elm_COLUMNS-40,
! 		 CATGETS(elm_msg_cat, ElmSet, 
! 			 ElmSetCurrentTo,
! 			 "Set current %s to :"), item);
! 	status = optionally_enter(buff, elm_LINES-3, elm_COLUMNS-15, 
! 				  OE_APPEND_CURRENT|OE_REDRAW_MARK,
! 				  sizeof buff);
! 	if (status == -1)
  	  return(current);
+ 	if (status == REDRAW_MARK)
+ 	  goto redraw;
  
  	if (buff[0] == '\0')
  	  return(current);
***************
*** 206,216 ****
  	return(num);
  }
  
! int
! optionally_enter(string, x, y, append_current, passwd)
! char *string;
! int  x,y, append_current, passwd;
  {
  	/** This will display the string on the screen and allow the user to
  	    either accept it (by pressing RETURN) or alter it according to
  	    what the user types.   The various flags are:
--- 124,138 ----
  	return(num);
  }
  
! int optionally_enter(string, x, y, flags, size)
!      char *string;
!      int  x,y,flags; 
!      int size;
  {
+   int append_current = 0 != (flags & OE_APPEND_CURRENT);
+   int passwd         = 0 != (flags & OE_PASSWD);
+   int redraw         = (flags & OE_REDRAW_MARK) ? REDRAW_MARK : 0;
+ 
  	/** This will display the string on the screen and allow the user to
  	    either accept it (by pressing RETURN) or alter it according to
  	    what the user types.   The various flags are:
***************
*** 229,250 ****
  
  	int ch;
  	register int ch_count = 0, iindex = 0, escaped = OFF;
! 	register int len = strlen(string), maxbuf = SLEN;
! 
! 	clearerr(stdin);
  
  	if(!passwd) {
  	  if(!(x >=0 && y >= 0))
  	    GetXYLocation(&x, &y);
! 	  PutLine1(x, y, "%s", string);	
  	}
  
  	CleartoEOLN();
  
- 	if ( len > maxbuf ) {
- 	  maxbuf = len;
- 	}
- 
  	if (! append_current) {
  	  MoveCursor(x,y);
  	}
--- 151,166 ----
  
  	int ch;
  	register int ch_count = 0, iindex = 0, escaped = OFF;
! 	register int len = strlen(string);
  
  	if(!passwd) {
  	  if(!(x >=0 && y >= 0))
  	    GetXYLocation(&x, &y);
! 	  PutLineX(x, y, FRM("%s"), string);	
  	}
  
  	CleartoEOLN();
  
  	if (! append_current) {
  	  MoveCursor(x,y);
  	}
***************
*** 251,258 ****
  	else
  	  iindex = strlen(string);
  
! 	if (cursor_control)
! 	  transmit_functions(OFF);
  
  	/** now we have the screen as we want it and the cursor in the 
  	    right place, we can loop around on the input and return the
--- 167,176 ----
  	else
  	  iindex = strlen(string);
  
! 	if (iindex > size-1) {
! 	  iindex = size-1;
! 	  string[iindex] = '\0';
! 	}
  
  	/** now we have the screen as we want it and the cursor in the 
  	    right place, we can loop around on the input and return the
***************
*** 260,277 ****
  	**/
  
  	do {
! 	  ch = getchar();
  
! 	  if (ch == ctrl('D') || ch == EOF) {		/* we've hit EOF */
! 	    if (cursor_control)
! 	      transmit_functions(ON);
  	    return(1);
  	  }
  
  	  if (ch_count++ == 0) {
  	    if (ch == '\n' || ch == '\r') {
- 	      if (cursor_control)
- 	        transmit_functions(ON);
  	      return(0);
  	    }
  	    else if (! append_current) {
--- 178,201 ----
  	**/
  
  	do {
! 	  ch = ReadCh(redraw|READCH_NOCURSOR);
! 
! 	  if (ch == REDRAW_MARK) {
! 	    if (ch_count > 0)
! 	      string[iindex] = '\0';
! 	    return REDRAW_MARK;
! 	  }
! 
! 	  if (ch == eof_char && !escaped
! 	      || ch == EOF) {		/* we've hit EOF */
  
! 	    if (ch_count > 0)
! 	      string[iindex] = '\0';
  	    return(1);
  	  }
  
  	  if (ch_count++ == 0) {
  	    if (ch == '\n' || ch == '\r') {
  	      return(0);
  	    }
  	    else if (! append_current) {
***************
*** 309,322 ****
  	      fflush(stdout);
  	    }
  	  }
! 	  else if (ch == EOF || ch == '\n' || ch == '\r') {
! 	    escaped = OFF;
  	    string[iindex] = '\0';
- 	    if (cursor_control)
- 	      transmit_functions(ON);
  	    return(0);
  	  }
! 	  else if (!passwd && ch == ctrl('W')) {	/* back up a word! */
  	    escaped = OFF;
  	    if (iindex == 0)
  	      continue;		/* no point staying here.. */
--- 233,243 ----
  	      fflush(stdout);
  	    }
  	  }
! 	  else if (ch == '\n' || ch == '\r') {
  	    string[iindex] = '\0';
  	    return(0);
  	  }
! 	  else if (!passwd && ch == word_erase && !escaped) {	/* back up a word! */
  	    escaped = OFF;
  	    if (iindex == 0)
  	      continue;		/* no point staying here.. */
***************
*** 337,347 ****
  	      iindex++;	/* and make sure we point at the first AVAILABLE slot */
  	    }
  	  }
! 	  else if (!passwd && ch == ctrl('R')) {
  	    escaped = OFF;
  	    string[iindex] = '\0';
! 	    PutLine1(x,y, "%s", string);	
  	    CleartoEOLN();
  	  }
  	  else if (!escaped && ch == kill_line) {
  	    /* needed to test if escaped since kill_line character could
--- 258,275 ----
  	      iindex++;	/* and make sure we point at the first AVAILABLE slot */
  	    }
  	  }
! 	  else if (!passwd && ch == reprint_char && !escaped) {
  	    escaped = OFF;
  	    string[iindex] = '\0';
! 	    PutLineX(x,y, FRM("%s"), string);	
! 	    CleartoEOLN();
! 	  }
! 	  else if (!passwd && ch == ctrl('L') && redraw) {
! 	    string[iindex] = '\0';
! 	    ClearScreen();
! 	    PutLineX(x,y, FRM("%s"), string);	
  	    CleartoEOLN();
+ 	    return REDRAW_MARK;
  	  }
  	  else if (!escaped && ch == kill_line) {
  	    /* needed to test if escaped since kill_line character could
***************
*** 353,363 ****
  	    }
  	    iindex = 0;
  	  }
! 	  else if (ch == '\0') {
! 	    escaped = OFF;
! 	    if (cursor_control)
! 	      transmit_functions(ON);
! 	    fflush(stdin); 	/* remove extraneous chars, if any */
  	    string[0] = '\0'; /* clean up string, and... */
  	    return(-1);
  	  }
--- 281,288 ----
  	    }
  	    iindex = 0;
  	  }
! 	  else if (ch == '\0' || 
! 		   ch == interrupt_char && !escaped) {
  	    string[0] = '\0'; /* clean up string, and... */
  	    return(-1);
  	  }
***************
*** 389,408 ****
  		escaped = ( ch == '\\' ? ON : OFF);
  	      }
  	  }
! 	} while (iindex < maxbuf);
  
  	string[iindex] = '\0';
  
- 	if (cursor_control)
- 	  transmit_functions(ON);
- 
  	return(0);
  }
  
! int
! pattern_enter(string, alt_string, x, y, alternate_prompt)
! char *string, *alt_string, *alternate_prompt;
! int  x,y;
  {
  	/** This function is functionally similar to the routine
  	    optionally-enter, but if the first character pressed
--- 314,331 ----
  		escaped = ( ch == '\\' ? ON : OFF);
  	      }
  	  }
! 	} while (iindex < size-1);
  
  	string[iindex] = '\0';
  
  	return(0);
  }
  
! int pattern_enter(string, alt_string, x, y, alternate_prompt, 
! 		  string_size, alt_string_size)
!      char *string, *alt_string, *alternate_prompt;
!      int  x,y;
!      int string_size,alt_string_size;
  {
  	/** This function is functionally similar to the routine
  	    optionally-enter, but if the first character pressed
***************
*** 414,439 ****
  	int ch;
  	register int iindex = 0, escaped = OFF;
  
! 	PutLine1(x, y, "%s", string);	
  	CleartoEOLN();
  	MoveCursor(x,y);
  
! 	if (cursor_control)
! 	  transmit_functions(OFF);
! 
! 	ch = getchar();
  
  	if (ch == '\n' || ch == '\r') {
- 	  if (cursor_control)
- 	    transmit_functions(ON);
  	  return(0);	/* we're done.  No change needed */
  	}
  	
  	if (ch == '/') {
! 	  PutLine1(x, 0, "%s", alternate_prompt);
  	  CleartoEOLN();
! 	  (void) optionally_enter(alt_string, x, strlen(alternate_prompt)+1,
! 		 FALSE, FALSE);
  	  return(1);
  	}
  
--- 337,366 ----
  	int ch;
  	register int iindex = 0, escaped = OFF;
  
! 	PutLineX(x, y, FRM("%s"), string);	
  	CleartoEOLN();
  	MoveCursor(x,y);
  
! 	ch = ReadCh(0|READCH_NOCURSOR);
  
  	if (ch == '\n' || ch == '\r') {
  	  return(0);	/* we're done.  No change needed */
  	}
  	
  	if (ch == '/') {
! 	  int status;
! 	  PutLineX(x, 0, FRM("%s"), alternate_prompt);
  	  CleartoEOLN();
! 	  status = optionally_enter(alt_string, x, strlen(alternate_prompt)+1,
! 				    OE_REDRAW_MARK,alt_string_size);
! 	  while (REDRAW_MARK == status) {
! 	    PutLineX(x, 0, FRM("%s"), alternate_prompt);
! 	    status = optionally_enter(alt_string, x, 
! 				      strlen(alternate_prompt)+1,
! 				      OE_REDRAW_MARK|OE_APPEND_CURRENT,
! 				      alt_string_size);
! 	  }
! 
  	  return(1);
  	}
  
***************
*** 462,468 ****
  
  	do {
  	  fflush(stdout);
! 	  ch = getchar();
  
  	  /* the following is converted from a case statement to
  	     allow the variable characters (backspace, kill_line
--- 389,395 ----
  
  	do {
  	  fflush(stdout);
! 	  ch = ReadCh(0);
  
  	  /* the following is converted from a case statement to
  	     allow the variable characters (backspace, kill_line
***************
*** 494,504 ****
  	    else if (ch == '\n' || ch == '\r') {
  	      escaped = OFF;
  	      string[iindex] = '\0';
- 	      if (cursor_control)
- 	        transmit_functions(ON);
  	      return(0);
  	    }
! 	    else if (ch == ctrl('W')) {
  	      escaped = OFF;
  	      if (iindex == 0)
  	        continue;		/* no point staying here.. */
--- 421,429 ----
  	    else if (ch == '\n' || ch == '\r') {
  	      escaped = OFF;
  	      string[iindex] = '\0';
  	      return(0);
  	    }
! 	    else if (ch == word_erase && !escaped) {
  	      escaped = OFF;
  	      if (iindex == 0)
  	        continue;		/* no point staying here.. */
***************
*** 519,528 ****
  	        iindex++;/* and make sure we point at the first AVAILABLE slot */
  	      }
  	    }
! 	    else if (ch == ctrl('R')) {
  	      escaped = OFF;
  	      string[iindex] = '\0';
! 	      PutLine1(x,y, "%s", string);	
  	      CleartoEOLN();
  	    }
  	    else if (!escaped && ch == kill_line) {
--- 444,453 ----
  	        iindex++;/* and make sure we point at the first AVAILABLE slot */
  	      }
  	    }
! 	    else if (ch == reprint_char && !escaped) {
  	      escaped = OFF;
  	      string[iindex] = '\0';
! 	      PutLineX(x,y, FRM("%s"), string);	
  	      CleartoEOLN();
  	    }
  	    else if (!escaped && ch == kill_line) {
***************
*** 533,542 ****
                CleartoEOLN();
  	      iindex = 0;
  	    }
! 	    else if (ch == '\0') {
  	      escaped = OFF;
- 	      if (cursor_control)
- 	        transmit_functions(ON);
  	      fflush(stdin); 	/* remove extraneous chars, if any */
  	      string[0] = '\0'; /* clean up string, and... */
  	      return(-1);
--- 458,466 ----
                CleartoEOLN();
  	      iindex = 0;
  	    }
! 	    else if (ch == '\0' || 
! 		     ch == interrupt_char && !escaped) {
  	      escaped = OFF;
  	      fflush(stdin); 	/* remove extraneous chars, if any */
  	      string[0] = '\0'; /* clean up string, and... */
  	      return(-1);
***************
*** 566,582 ****
  		  escaped = ( ch == '\\' ? ON : OFF);
  		}
  	    }
! 	} while (iindex < SLEN);
  
  	string[iindex] = '\0';
- 
- 	if (cursor_control)
- 	  transmit_functions(ON);
  	return(0);
  }
  
! int
! GetPrompt()
  {
  	/** This routine does a read/timeout for a single character.
  	    The way that this was determined is that the routine to
--- 490,502 ----
  		  escaped = ( ch == '\\' ? ON : OFF);
  		}
  	    }
! 	} while (iindex < string_size-1);
  
  	string[iindex] = '\0';
  	return(0);
  }
  
! int GetPrompt()
  {
  	/** This routine does a read/timeout for a single character.
  	    The way that this was determined is that the routine to
***************
*** 589,612 ****
  
  	int ch;
  
! 	if (timeout > 0) {
! 	  alarm((unsigned) timeout);
! 	  if (SETJMP(GetPromptBuf)) {
! 	    InGetPrompt = 0;
! 	    ch = NO_OP_COMMAND;
! 	    alarm((unsigned) 0);
! 	  }
! 	  else {
! 	    InGetPrompt = 1;
! 	    ch = ReadCh();
! 	    InGetPrompt = 0;
! 	    alarm((unsigned) 0);
! 	  }
  	}
  	else {
! 	    errno = 0;
! 	    ch = ReadCh();
! 	    if (errno == EINTR) ch = NO_OP_COMMAND;
  	}
  	return(ch);
  }
--- 509,536 ----
  
  	int ch;
  
! 	if (elm_timeout > 0) {
! 	  alarm((unsigned) elm_timeout);
  	}
+ 	if (SETJMP(GetPromptBuf)) {
+ 	  InGetPrompt = 0;
+ 	  ch = NO_OP_COMMAND;
+ 	  alarm((unsigned) 0);
+ 	}
  	else {
! 	  errno = 0;
! 	  InGetPrompt = 1;
! 	  ch = ReadCh(0|READCH_CURSOR);
! 	  if (errno == EINTR)  ch = NO_OP_COMMAND;
! #ifdef	EAGAIN
! 	  if (errno == EAGAIN) ch = NO_OP_COMMAND;
! #endif
! #ifdef	EWOULDBLOCK
! 	  if (errno == EWOULDBLOCK) ch = NO_OP_COMMAND;
! #endif
! 	  InGetPrompt = 0;
! 	  alarm((unsigned) 0);
  	}
  	return(ch);
  }
+ 
Index: elm2.4.ME+.50/src/init.c
*** elm2.4.25/src/init.c	Mon May 30 19:31:57 1994
--- elm2.4.ME+.50/src/init.c	Tue Nov 17 21:12:58 1998
***************
*** 1,122 ****
  
! static char rcsid[] = "@(#)$Id: init.c,v 5.20 1994/05/30 16:31:40 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.20 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: init.c,v $
!  * Revision 5.20  1994/05/30  16:31:40  syd
!  * make getpwuid dependent on ANSI_C not posix flag
!  * From: Syd
!  *
!  * Revision 5.19  1993/09/27  01:51:38  syd
!  * Add elm_chown to consolidate for Xenix not allowing -1
!  * From: Syd
!  *
!  * Revision 5.18  1993/08/23  03:26:24  syd
!  * Try setting group id separate from user id in chown to
!  * allow restricted systems to change group id of file
!  * From: Syd
!  *
!  * Revision 5.17  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.16  1993/04/12  03:30:23  syd
!  * On AIX, __STDC__ is not defined but it does use unistd.h, etc.  In
!  * hdrs/def.h, ANS_C already gets defined if __STDC__ or _AIX.  But this
!  * variable then needs to be used in src/init.c and hdrs/filter.h in place
!  * of the current test for __STDC__.
!  * From:	rstory@elegant.com (Robert Story)
!  *
!  * Revision 5.15  1993/04/12  03:07:57  syd
!  * The "window is too small..." message gets printed on the wrong screen. The
!  * message also needs \r\n at the end.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.14  1993/04/12  01:52:31  syd
!  * Initialize safe_malloc() failure trap just to play it safe.  Although
!  * Elm doesn't currently use these routines, do this just in case somebody
!  * someday adds a call to a library routine that does use them.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.13  1993/02/03  19:08:03  syd
!  * fix extra declares
!  * From: syd
!  *
!  * Revision 5.12  1993/01/20  03:43:37  syd
!  * Some systems dont have SIGBUS, make it optional
!  *
!  * Revision 5.11  1993/01/20  03:02:19  syd
!  * Move string declarations to defs.h
!  * From: Syd
!  *
!  * Revision 5.10  1993/01/19  05:07:05  syd
!  * Trim erroreous extra log entry
!  * From: Syd
!  *
!  * Revision 5.9  1993/01/19  04:47:12  syd
!  * Significant changes to provide consistent Date and From_ header
!  * cracking.  Overhauled date utilities and moved into library.  Moved
!  * real_from() into library.  Modified frm, newmail, and readmsg utilities
!  * to use library version of real_from().  Moved get_word() from Elm
!  * source into library.  Added new library routines atonum() and strfcpy().
!  * Fixed trailing backslash bug in len_next().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.8  1992/12/07  02:41:21  syd
!  * This implements the use of SIGUSR1 and SIGUSR2 as discussed on the
!  * mailing list recently, and adds them to the documentation.
!  * From: scs@lokkur.dexter.mi.us (Steve Simmons)
!  *
!  * Revision 5.7  1992/11/26  01:26:04  syd
!  * only enter raw mode if not batch and not elm -c, to avoid
!  * screen swap and cursor control output
!  *
!  * Revision 5.6  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.5  1992/10/30  21:12:40  syd
!  * Make patchlevel a text string to allow local additions to the variable
!  * From: syd via a request from Dave Wolfe
!  *
!  * Revision 5.4  1992/10/27  01:34:12  syd
!  * It fixes the problem where ti/te was being used (by Raw()),
!  * AFTER the command line args had been read but BEFORE the rc files had.
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.3  1992/10/25  02:01:58  syd
!  * Here are the patches to support POSIX sigaction().
!  * From: tom@osf.org
!  *
!  * Revision 5.2  1992/10/24  13:35:39  syd
!  * changes found by using codecenter on Elm 2.4.3
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /***** Initialize - read in all the defaults etc etc 
  *****/
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: init.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /***** Initialize - read in all the defaults etc etc 
  *****/
***************
*** 125,130 ****
--- 19,26 ----
  #include "patchlevel.h"
  #include "s_elm.h"
  
+ #include "me.h"
+ 
  #ifdef TERMIOS
  #  include <termios.h>
     typedef struct termios term_buff;
***************
*** 135,142 ****
     typedef struct termio term_buff;
  # else
  #  include <sgtty.h>
! #  define tcgetattr(fd,buf)	ioctl((fd),TIOCGETP,(buf))
!    typedef struct sgttyb term_buff;
  # endif
  #endif
  
--- 31,44 ----
     typedef struct termio term_buff;
  # else
  #  include <sgtty.h>
! typedef struct {
!   struct sgttyb sgttyb;
!   struct tchars tchars;
! #ifdef TIOCLGET
!   struct ltchars ltchars;
! #endif
! } term_buff;
! static int tcgetattr P_((int,term_buff *));  /* Prototype */
  # endif
  #endif
  
***************
*** 146,158 ****
  #  include <pwd.h>
  #endif
  
- #ifdef I_TIME
- #  include <time.h>
- #endif
- #ifdef I_SYSTIME
- #  include <sys/time.h>
- #endif
- 
  #include <errno.h>
  
  extern int errno;		/* system error number on failure */
--- 48,53 ----
***************
*** 160,166 ****
  
  char *error_description();
  
! #ifndef ANSI_C /* items are in unistd.h which is included if __STDC__ */
  char *getlogin();
  unsigned short getgid(), getuid(); 
  struct passwd *getpwuid();
--- 55,61 ----
  
  char *error_description();
  
! #ifndef I_UNISTD 
  char *getlogin();
  unsigned short getgid(), getuid(); 
  struct passwd *getpwuid();
***************
*** 186,205 ****
  extern void init_opts_menu();
  extern void malloc_failed_exit();
  
! initialize(requestedmfile)
! char *requestedmfile;	/* first mail file to open, empty if the default */
  {
! 	/** initialize the whole ball of wax.
! 	**/
! 	struct passwd *pass, *getpwnam();
! 	register int init_scr_return, hostlen, domlen; 
  
  #if defined(SIGVEC) & defined(SV_INTERRUPT)
  	struct sigvec alarm_vec;
  #endif /* defined(SIGVEC) & defined(SV_INTERRUPT) */
- 	char     buffer[SLEN], *cp;
  
! 	sprintf(version_buff, "%s PL%s", VERSION, PATCHLEVEL);
  	def_ans_yes = catgets(elm_msg_cat, ElmSet, ElmYes, "y");
  	def_ans_no = catgets(elm_msg_cat, ElmSet, ElmNo, "n");
  	nls_deleted = catgets(elm_msg_cat, ElmSet, ElmTitleDeleted, "[deleted]");
--- 81,99 ----
  extern void init_opts_menu();
  extern void malloc_failed_exit();
  
! void initialize(requestedmfile, size)
!      char *requestedmfile;	/* first mail file to open, empty if the default */
!      int size;
  {
! 	register int init_scr_return; 
! 	char buffer[SLEN], *cp;
  
  #if defined(SIGVEC) & defined(SV_INTERRUPT)
  	struct sigvec alarm_vec;
  #endif /* defined(SIGVEC) & defined(SV_INTERRUPT) */
  
! 	elm_sfprintf(version_buff, sizeof version_buff,
! 		     FRM("%s PL%s"), VERSION, PATCHLEVEL);
  	def_ans_yes = catgets(elm_msg_cat, ElmSet, ElmYes, "y");
  	def_ans_no = catgets(elm_msg_cat, ElmSet, ElmNo, "n");
  	nls_deleted = catgets(elm_msg_cat, ElmSet, ElmTitleDeleted, "[deleted]");
***************
*** 215,225 ****
  	cap_copy_word = catgets(elm_msg_cat, ElmSet, ElmCapCopy, "Copy");
  	saved_word = catgets(elm_msg_cat, ElmSet, ElmSaved, "saved");
  	copied_word = catgets(elm_msg_cat, ElmSet, ElmCopied, "copied");
! 	strcpy(item, catgets(elm_msg_cat, ElmSet, Elmitem, "message"));
! 	strcpy(items, catgets(elm_msg_cat, ElmSet, Elmitems, "messages"));
! 	strcpy(Item, catgets(elm_msg_cat, ElmSet, ElmItem, "Message"));
! 	strcpy(Items, catgets(elm_msg_cat, ElmSet, ElmItems, "Messages"));
! 	strcpy(Prompt, catgets(elm_msg_cat, ElmSet, ElmPrompt, "Command: "));
  
  	/*
  	 * Install the error trap to take if xmalloc() or friends fail.
--- 109,124 ----
  	cap_copy_word = catgets(elm_msg_cat, ElmSet, ElmCapCopy, "Copy");
  	saved_word = catgets(elm_msg_cat, ElmSet, ElmSaved, "saved");
  	copied_word = catgets(elm_msg_cat, ElmSet, ElmCopied, "copied");
! 	strfcpy(item, catgets(elm_msg_cat, ElmSet, Elmitem, "message"),
! 		sizeof item);
! 	strfcpy(items, catgets(elm_msg_cat, ElmSet, Elmitems, "messages"),
! 		sizeof items);
! 	strfcpy(Item, catgets(elm_msg_cat, ElmSet, ElmItem, "Message"),
! 		sizeof Item);
! 	strfcpy(Items, catgets(elm_msg_cat, ElmSet, ElmItems, "Messages"),
! 		sizeof Items);
! 	strfcpy(Prompt, catgets(elm_msg_cat, ElmSet, ElmPrompt, "Command: "),
! 		sizeof Prompt);
  
  	/*
  	 * Install the error trap to take if xmalloc() or friends fail.
***************
*** 229,234 ****
--- 128,134 ----
  	init_opts_menu();
  	init_scr_return = InitScreen();
  
+ 	out_util_setup();
  	/* save original user and group ids */
  	userid  = getuid();
  	groupid = getgid();	
***************
*** 240,278 ****
  	/* make all newly created files private */
  	original_umask = umask(077);
  
! 	/* Get username (logname), home (login directory), and full_username
! 	 * (part of GCOS) field from the password entry for this user id.
! 	 * Full_username will get overridden by fullname in elmrc, if defined.
! 	 *
! 	 * For those sites that have various user names with the same user
! 	 * ID, use the passwd entry corresponding to the user name as long 
! 	 * as it matches the user ID.  Otherwise fall back on the entry 
! 	 * associated with the user ID alone.
! 	 */
! 
! 	if((cp = getenv("LOGNAME")) == NULL)
! 		cp = getenv("USER");
! 	if(cp != NULL && (pass = getpwnam(cp)) != NULL &&
! 	    pass->pw_uid == userid) {
! 	  ;  /* Null body */
! 	} else if((pass = getpwuid(userid)) == NULL) {
! 	  error(catgets(elm_msg_cat, ElmSet, ElmYouHaveNoPasswordEntry,
! 		"You have no password entry!\r\n"));
! 	  exit(1);
! 	}
! 	strcpy(username, pass->pw_name);
! 	strcpy(home, pass->pw_dir);
! 
! 	if((cp = get_full_name(username)) != NULL)
! 	  strcpy(full_username, cp);
! 	else
! 	  strcpy(full_username, username);	/* fall back on logname */
  
  #ifdef DEBUG
  	if (debug) {		/* setup for dprint() statements! */
  	  char newfname[SLEN], filename[SLEN];
  
! 	  sprintf(filename, "%s/%s", home, DEBUGFILE);
  	  if (access(filename, ACCESS_EXISTS) == 0) {	/* already one! */
  	    sprintf(newfname,"%s/%s", home, OLDEBUG);
  	    (void) rename(filename, newfname);
--- 140,156 ----
  	/* make all newly created files private */
  	original_umask = umask(077);
  
! 	/* get username and home directory */
! 	user_init();
  
  #ifdef DEBUG
  	if (debug) {		/* setup for dprint() statements! */
  	  char newfname[SLEN], filename[SLEN];
+ 	  debugfile = stderr;
  
! 	  elm_sfprintf(filename, sizeof filename,
! 		       FRM("%s/%s"), 
! 		       home, DEBUGFILE);
  	  if (access(filename, ACCESS_EXISTS) == 0) {	/* already one! */
  	    sprintf(newfname,"%s/%s", home, OLDEBUG);
  	    (void) rename(filename, newfname);
***************
*** 284,299 ****
  	     the mailer.  Dumb, subtle, but easy enough to do!
   	  */
  
! 	  if ((debugfile = fopen(filename, "w")) == NULL) {
  	    debug = 0;	/* otherwise 'leave' will try to log! */
  	    leave(fprintf(stderr, catgets(elm_msg_cat, ElmSet, ElmCouldNotOpenDebugFile,
! 			"Could not open file %s for debug output!\n"),
! 		  filename));
  	  }
  	  (void) elm_chown(filename, userid, groupid); /* file owned by user */
! 
  	  fprintf(debugfile, 
!      "Debug output of the ELM program (at debug level %d).  Version %s\n\n",
  		  debug, version_buff);
  	}
  #endif
--- 162,178 ----
  	     the mailer.  Dumb, subtle, but easy enough to do!
   	  */
  
! 	  if (0 != can_open(filename,"w") || 
! 	      (debugfile = fopen(filename, "w")) == NULL) {
  	    debug = 0;	/* otherwise 'leave' will try to log! */
  	    leave(fprintf(stderr, catgets(elm_msg_cat, ElmSet, ElmCouldNotOpenDebugFile,
! 					  "Could not open file %s for debug output!\n"),
! 			  filename));
  	  }
  	  (void) elm_chown(filename, userid, groupid); /* file owned by user */
! 	  
  	  fprintf(debugfile, 
! 		  "Debug output of the ELM program (at debug level %d).  Version %s\n\n",
  		  debug, version_buff);
  	}
  #endif
***************
*** 367,439 ****
  	signal(SIGWINCH, winch_signal);		/* change screen size */
  #endif
  
  	get_term_chars();
  
- 	/*
- 	 * Get the host name as per configured behavior.
- 	 */
- #ifdef HOSTCOMPILED
- 	strfcpy(hostname, HOSTNAME, sizeof(hostname));
- #else
- 	gethostname(hostname, sizeof(hostname));
- #endif
  
! 	/*
! 	 * now get the domain name, used to build the full name
! 	 */
! 	gethostdomain(hostdomain, sizeof(hostdomain));
  
! 	/*
! 	 * now the tough part:
! 	 *	we need to make three variables out of this stuff:
! 	 *	hostname = just the hostname, as in bangpaths,
! 	 *		this is whatever the user gave us so far,
! 	 *		we wont change this one
! 	 *	hostdomain = this is the domain considered local to this
! 	 *		machine, and should be what we got above.
! 	 *	hostfullname = this is the full FQDN of this machine,
! 	 *		and is a strange combination of the first two.
! 	 *	if tail(hostname) == hostdomain
! 	 *		then hostfullname = hostname
! 	 *			ie: node.ld.domain.type, ld.domain.type -> node.ld.domain.type
! 	 *	else if hostname == hostdomain + 1
! 	 *		then hostfullname = hostname
! 	 *			ie: domain.type, .domain.type -> domain.type
! 	 *	
! 	 *	else hostfullname = hostname + hostdomain
! 	 *			ie: host, .domain.type -> host.domain.type
! 	 * lost yet?
! 	 */
! 	hostlen = strlen(hostname);
! 	domlen = strlen(hostdomain);
! 	if (hostlen >= domlen) {
! 	  if (istrcmp(&hostname[hostlen - domlen], hostdomain) == 0)
! 	    strcpy(hostfullname, hostname);
! 	  else {
! 	    strcpy(hostfullname, hostname);
! 	    strcat(hostfullname, hostdomain);
! 	  }
! 	} else {
! 	  if (istrcmp(hostname, hostdomain + 1) == 0)
! 	    strcpy(hostfullname, hostname);
! 	  else {
! 	    strcpy(hostfullname, hostname);
! 	    strcat(hostfullname, hostdomain);
  	  }
  	}
  
! 	/* Determine the default mail file name.
! 	 * 
! 	 * First look for an environment variable MAIL, then
! 	 * use then mailhome if it is not found
! 	 */
! 	if ((cp = getenv("MAIL")) == NULL)
! 		sprintf(defaultfile, "%s%s", mailhome, username);
! 	else
! 		strcpy(defaultfile, cp);
  
! 	/* Determine options that might be set in the .elm/elmrc */
! 	read_rc_file();
  
  	/* Now that we've read the rc file we can enter RAW mode */
  	if (!batch_only && !check_only)
--- 246,282 ----
  	signal(SIGWINCH, winch_signal);		/* change screen size */
  #endif
  
+ #ifdef BACKGROUD_PROCESSES
+ 	init_backgroud_handling();
+ #endif
+ 
  	get_term_chars();
  
  
! 	/* Determine options that might be set in the global elmrc */
! 	if (init_defaults() != 0) {
! 	  sleep(1);
! 	}
  
! 	/* Determine options that might be set in the .elm/elmrc */
! 	if (read_rc_file() != 0) {
! 	  sleep(1);
! 	  if (!batch_only && !write_elmrc) {
! 	    printf("Fix .elm/elmrc or let elm rebuild elmrc with option '-w'\n");
! 	    exit(1);
  	  }
  	}
+ 	
+ 	if (!Check_attachments())
+ 	  exit(1);
  
! 	/* Check if .elm and Mail directories exists */
! 	directory_check();
  
! 	if (write_elmrc) {
! 	  save_options();
! 	  sleep(1);
! 	}
  
  	/* Now that we've read the rc file we can enter RAW mode */
  	if (!batch_only && !check_only)
***************
*** 441,448 ****
  
  	/* Determine the mail file to read */
  	if (*requestedmfile == '\0')
! 	  strcpy(requestedmfile, defaultfile);
! 	else if(!expand_filename(requestedmfile, FALSE)) {
  	    Raw(OFF);
  	    exit(0);
          }
--- 284,292 ----
  
  	/* Determine the mail file to read */
  	if (*requestedmfile == '\0')
! 	  strfcpy(requestedmfile, defaultfile, size);
! 	else if(!expand_filename(requestedmfile, FALSE,
! 				 size)) {
  	    Raw(OFF);
  	    exit(0);
          }
***************
*** 456,468 ****
  	if (! mail_only) {
  	  if ((errno = can_access(requestedmfile, READ_ACCESS)) != 0) {
  	    if (strcmp(requestedmfile, defaultfile) != 0 || errno != ENOENT) {
  	      dprint(1, (debugfile,
  		    "Error: given file %s as folder - unreadable (%s)!\n", 
  		    requestedmfile, error_description(errno)));
! 	      fprintf(stderr, catgets(elm_msg_cat, ElmSet, ElmCantOpenFolderRead,
! 			"Can't open folder '%s' for reading!\n"),
! 		    requestedmfile);
! 	      Raw(OFF);
  	      exit(1);
  	    }
  	  }
--- 300,312 ----
  	if (! mail_only) {
  	  if ((errno = can_access(requestedmfile, READ_ACCESS)) != 0) {
  	    if (strcmp(requestedmfile, defaultfile) != 0 || errno != ENOENT) {
+ 	      Raw(OFF);
  	      dprint(1, (debugfile,
  		    "Error: given file %s as folder - unreadable (%s)!\n", 
  		    requestedmfile, error_description(errno)));
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCantOpenFolderRead,
! 				"Can't open folder '%s' for reading!\n"),
! 			requestedmfile);
  	      exit(1);
  	    }
  	  }
***************
*** 472,517 ****
  	    value different to that in the termcap entry (for
  	    windowing systems, of course!) **/
  
! 	ScreenSize(&LINES, &COLUMNS);
  
  	if ((cp = getenv("LINES")) != NULL && isdigit(*cp)) {
! 	  sscanf(cp, "%d", &LINES);
! 	  LINES -= 1;	/* kludge for HP Window system? ... */
  	}
  
  	if ((cp = getenv("COLUMNS")) != NULL && isdigit(*cp))
! 	  sscanf(cp, "%d", &COLUMNS);
  
  	/** fix the shell if needed **/
  
  	if (shell[0] != '/') {
! 	   sprintf(buffer, "/bin/%s", shell);
! 	   strcpy(shell, buffer);
! 	}
! 
! 	if (! mail_only && ! check_only) {
! 
! 	  /* get the cursor control keys... */
! 
! 	  cursor_control = FALSE;
! 
! 	  if ((cp = return_value_of("ku")) != NULL) {
! 	    strcpy(up, cp);
! 	    if ((cp = return_value_of("kd")) != NULL) {
! 	      strcpy(down, cp);
! 	      if ((cp = return_value_of("kl")) != NULL) {
! 		strcpy(left, cp);
! 		if ((cp = return_value_of("kr")) != NULL) {
! 		  strcpy(right, cp);
! 		  cursor_control = TRUE;
! 		  transmit_functions(ON);
! 		}
! 	      }
! 	    }
! 	  }
! 	  if (!arrow_cursor) 	/* try to use inverse bar instead */
! 	    if (return_value_of("so") != NULL && return_value_of("se") != NULL)
! 	        has_highlighting = TRUE;
  	}
  
  	/** clear the screen **/
--- 316,355 ----
  	    value different to that in the termcap entry (for
  	    windowing systems, of course!) **/
  
! 	ScreenSize(&elm_LINES, &elm_COLUMNS);
! 
! 	/* WARNING: elm_LINES and elm_COLUMNS are inconsistent!
! 	 *
! 	 * elm_LINES    == number of lines in screen -1
! 	 * elm_COLUMNS  == number of rows in screen
! 	 *
! 	 *
! 	 * Check code in MoveCursor!
! 	 *
! 	 * row          == 0 .. elm_LINES
! 	 * col          == 0 .. elm_COLUMNS-1
! 	 *
! 	 *
! 	 * Who was this smart programmer!!!!!!!!!!!!!!!!!!!!!
! 	 *
! 	 *                         - K E H <hurtta@ozone.FMI.FI>
! 	 */
  
  	if ((cp = getenv("LINES")) != NULL && isdigit(*cp)) {
! 	  sscanf(cp, "%d", &elm_LINES);
! 	  elm_LINES -= 1; 
  	}
  
  	if ((cp = getenv("COLUMNS")) != NULL && isdigit(*cp))
! 	  sscanf(cp, "%d", &elm_COLUMNS);
  
  	/** fix the shell if needed **/
  
  	if (shell[0] != '/') {
! 	   elm_sfprintf(buffer, sizeof buffer,
! 			FRM("/bin/%s"), 
! 			shell);
! 	   strfcpy(shell, buffer, sizeof shell);
  	}
  
  	/** clear the screen **/
***************
*** 520,534 ****
  
  	if (! mail_only && ! check_only) {
  	  if (mini_menu)
! 	    headers_per_page = LINES - 13;
  	  else
! 	    headers_per_page = LINES -  8;	/* 5 more headers! */
  
  	  if (headers_per_page <= 0) {
  	    Raw(OFF);
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmWindowSizeTooSmall,
! 		 "The window is too small to run Elm.  It must have at least %d rows"),
! 		 1 + LINES - headers_per_page);
  	    exit(1);
  	  }
  	  newmbox(requestedmfile, FALSE);	/* read in the folder! */
--- 358,372 ----
  
  	if (! mail_only && ! check_only) {
  	  if (mini_menu)
! 	    headers_per_page = elm_LINES - 13;
  	  else
! 	    headers_per_page = elm_LINES -  8;	/* 5 more headers! */
  
  	  if (headers_per_page <= 0) {
  	    Raw(OFF);
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWindowSizeTooSmall,
! 			      "The window is too small to run Elm.  It must have at least %d rows"),
! 		 1 + elm_LINES - headers_per_page);
  	    exit(1);
  	  }
  	  newmbox(requestedmfile, FALSE);	/* read in the folder! */
***************
*** 579,592 ****
  	  /* set to defaults for terminal driver */
  	  backspace = BACKSPACE;
  	  kill_line = ctrl('U');
  	}
  	else {
  #if defined(TERMIO) || defined(TERMIOS)
  	  backspace = term_buffer.c_cc[VERASE];
  	  kill_line = term_buffer.c_cc[VKILL];
  #else
! 	  backspace = term_buffer.sg_erase;
! 	  kill_line = term_buffer.sg_kill;
  #endif
  	}
  }
--- 417,474 ----
  	  /* set to defaults for terminal driver */
  	  backspace = BACKSPACE;
  	  kill_line = ctrl('U');
+ 	  word_erase = ctrl('W');
+  	  interrupt_char = 0177;	/* DEL */
+  	  reprint_char = ctrl('R');
+  	  eof_char = ctrl('D');
  	}
  	else {
  #if defined(TERMIO) || defined(TERMIOS)
  	  backspace = term_buffer.c_cc[VERASE];
  	  kill_line = term_buffer.c_cc[VKILL];
+ #if   defined(TERMIOS) && defined(VWERASE)
+ 	  word_erase = term_buffer.c_cc[VWERASE];
+ #else
+ 	  word_erase = ctrl('W');
+ #endif
+  	  interrupt_char = term_buffer.c_cc[VINTR];
+ #if defined(TERMIOS) && defined(VREPRINT)
+ 	  reprint_char = term_buffer.c_cc[VREPRINT];
  #else
! 	  reprint_char = ctrl('R');
  #endif
+ 	  eof_char = term_buffer.c_cc[VEOF];
+ #else
+ 	  backspace = term_buffer.sgttyb.sg_erase;
+ 	  kill_line = term_buffer.sgttyb.sg_kill;
+ #ifdef     TIOCLGET
+  	  word_erase = term_buffer.ltchars.t_werasc;
+ 	  reprint_char = term_buffer.ltchars.t_rprntc;
+ #else
+ 	  word_erase = ctrl('W');
+ 	  reprint_char = ctrl('R');
+ #endif
+ 	  interrupt_char = term_buffer.tchars.t_intrc;
+ 	  eof_char = term_buffer.tchars.t_eofc;
+ #endif
  	}
  }
+ 
+ #if !defined(TERMIO) && !defined(TERMIOS)
+ static int
+ tcgetattr(fd, buf)
+      int fd;
+      term_buff *buf;
+ {
+ 	if (ioctl(fd, TIOCGETP, &buf->sgttyb) < 0)
+ 	  return(-1);
+ 	if (ioctl(fd, TIOCGETC, &buf->tchars) < 0)
+ 	  return(-1);
+ #ifdef TIOCLGET
+ 	if (ioctl(fd, TIOCLGET, &buf->ltchars) < 0)
+ 	  return(-1);
+ #endif
+ 	return(0);
+ }
+ #endif
+ 
Index: elm2.4.ME+.50/src/leavembox.c
*** elm2.4.25/src/leavembox.c	Fri Jun  3 20:12:44 1994
--- elm2.4.ME+.50/src/leavembox.c	Tue Nov 17 21:12:58 1998
***************
*** 1,133 ****
  
! static char rcsid[] = "@(#)$Id: leavembox.c,v 5.24 1994/06/03 17:05:17 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.24 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: leavembox.c,v $
!  * Revision 5.24  1994/06/03  17:05:17  syd
!  * try and prevent copy from calling elm_chown unless needed
!  * From: Syd
!  *
!  * Revision 5.23  1994/05/14  18:42:57  syd
!  * Here are some more of fixes to correctly call fflush() and unlock() in sequence.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.22  1994/05/14  17:31:56  syd
!  * try and use copying to remove SVR4 inability to chgrp file
!  * properly
!  *
!  * Revision 5.21  1994/03/12  15:20:01  syd
!  * The latest Linux shared library (4.5.8) "catches" a double fclose()
!  * by generating a SIGSEGV.  :-/
!  * From: fin!chip@dg-rtp.dg.com (Chip Salzenberg)
!  *
!  * Revision 5.20  1993/09/27  01:51:38  syd
!  * Add elm_chown to consolidate for Xenix not allowing -1
!  * From: Syd
!  *
!  * Revision 5.19  1993/08/23  03:26:24  syd
!  * Try setting group id separate from user id in chown to
!  * allow restricted systems to change group id of file
!  * From: Syd
!  *
!  * Revision 5.18  1993/08/03  19:59:49  syd
!  * Check for chown restricted and if so, do copyover and
!  * back to avoid need for chown
!  * From: Syd
!  *
!  * Revision 5.17  1993/05/31  19:47:45  syd
!  * change is_symlink to no_restore and use it for special modes as well
!  * From: Syd
!  *
!  * Revision 5.16  1993/05/31  19:44:46  syd
!  * If 'enforcement' modes set, use copy not link
!  *
!  * Revision 5.15  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.14  1993/04/12  02:34:36  syd
!  * I have now added a parameter which controls whether want_to clears the
!  * line and centers the question or behaves like it did before. I also
!  * added a 0 at the end of the parameter list to all the other calls to
!  * want_to where a centered question on a clean line is not desirable.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.13  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.12  1993/01/27  20:43:26  syd
!  * The following minor patch for leavembox.c is useful for BSD systems
!  * which implement correct (per SVID & POSIX) struct utimbuf.  Where the
!  * source previously tested just '#ifdef BSD' it now tests '#if
!  * defined(BSD) && !defined(UTIMBUF)'.  This suppresses a compile-time
!  * warning on ConvexOS due to the prototype of utime.
!  * From: rwright@dhostwo.convex.com (Randy Wright)
!  *
!  * Revision 5.11  1993/01/20  03:08:43  syd
!  * alter the message on aborts to report the temp file name to the user
!  * From: The Postmaster <sysnet@central1.lancaster.ac.uk>
!  *
!  * Revision 5.10  1993/01/20  03:02:19  syd
!  * Move string declarations to defs.h
!  * From: Syd
!  *
!  * Revision 5.9  1992/12/24  21:58:52  syd
!  * Add lstat call to properly detect symlink
!  * From: Syd via partial patch from Bryan Curnutt
!  *
!  * Revision 5.8  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.7  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.6  1992/12/07  03:49:49  syd
!  * use BSD or not apollo on file.h include as its not valid
!  * for Apollos under sys5.3 compile type
!  * From: gordonb@mcil.comm.mot.com (Gordon Berkley)
!  *
!  * Revision 5.5  1992/11/26  01:46:26  syd
!  * add Decode option to copy_message, convert copy_message to
!  * use bit or for options.
!  * From: Syd and bjoerns@stud.cs.uit.no (Bjoern Stabell)
!  *
!  * Revision 5.4  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.3  1992/10/27  01:52:16  syd
!  * Always include <sys/ioctl.h> in curses.c When calling ioctl()
!  *
!  * Remove declaration of getegid() from leavembox.c & lock.c
!  * They aren't even used there.
!  * From: tom@osf.org
!  *
!  * Revision 5.2  1992/10/17  22:18:36  syd
!  * Correct reversed usage of $d_utimbuf.
!  * From: chip@tct.com (Chip Salzenberg)
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** leave current folder, updating etc. as needed...
    
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: leavembox.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** leave current folder, updating etc. as needed...
    
***************
*** 143,159 ****
  #define SYSCALL_LOCKING
  #endif
  #ifdef SYSCALL_LOCKING
! #  if (defined(BSD) || !defined(apollo))
  #    include <sys/file.h>
  #  endif
  #endif
  #include <errno.h>
- #ifdef I_TIME
- #  include <time.h>
- #endif
- #ifdef I_SYSTIME
- #  include <sys/time.h>
- #endif
  #ifdef I_UTIME
  #  include <utime.h>
  #endif
--- 26,36 ----
  #define SYSCALL_LOCKING
  #endif
  #ifdef SYSCALL_LOCKING
! #  if (defined(BSD_TYPE) || !defined(apollo))
  #    include <sys/file.h>
  #  endif
  #endif
  #include <errno.h>
  #ifdef I_UTIME
  #  include <utime.h>
  #endif
***************
*** 160,166 ****
  #ifdef I_SYSUTIME
  #  include <sys/utime.h>
  #endif
! 
  
  /**********
     Since a number of machines don't seem to bother to define the utimbuf
--- 37,43 ----
  #ifdef I_SYSUTIME
  #  include <sys/utime.h>
  #endif
! #include "me.h"
  
  /**********
     Since a number of machines don't seem to bother to define the utimbuf
***************
*** 169,175 ****
     Suprise, though, BSD has a different utime() entirely...*sigh*
  **********/
  
! #ifndef BSD
  # ifndef UTIMBUF
  
  struct utimbuf {
--- 46,52 ----
     Suprise, though, BSD has a different utime() entirely...*sigh*
  **********/
  
! #ifndef BSD_TYPE
  # ifndef UTIMBUF
  
  struct utimbuf {
***************
*** 178,184 ****
         };
  
  # endif /* UTIMBUF */
! #endif /* BSD */
  
  extern int errno;
  
--- 55,61 ----
         };
  
  # endif /* UTIMBUF */
! #endif /* BSD_TYPE */
  
  extern int errno;
  
***************
*** 195,200 ****
--- 72,79 ----
  			0	Folder not altered
  			-1	New mail arrived during the process and
  					closing was aborted.
+ 			-2      Leaving of folder failed
+ 			
  	    If "resyncing" we are just writing out folder to reopen it. We
  		therefore only consider deletes and keeps, not stores to mbox.
  		Also we don't remove NEW status so that it can be preserved
***************
*** 214,220 ****
  #ifdef SYMLINK
  	struct stat    lbuf;		/* lstat command  */
  #endif
! #if defined(BSD) && !defined(UTIMBUF)
  	time_t utime_buffer[2];		/* utime command */
  #else
  	struct utimbuf utime_buffer;	/* utime command */
--- 93,99 ----
  #ifdef SYMLINK
  	struct stat    lbuf;		/* lstat command  */
  #endif
! #if defined(BSD_TYPE) && !defined(UTIMBUF)
  	time_t utime_buffer[2];		/* utime command */
  #else
  	struct utimbuf utime_buffer;	/* utime command */
***************
*** 223,228 ****
--- 102,108 ----
  		     marked_deleted, marked_read, marked_unread,
  		     last_sortby, ask_questions,  asked_storage_q,
  		     num_chgd_status, need_to_copy;
+ 	int was_symlink = FALSE;
  	char answer;
  	int  err;
  	long bytes();
***************
*** 229,244 ****
  
  	dprint(1, (debugfile, "\n\n-- leaving folder --\n\n"));
  
! 	if (message_count == 0)
  	  return(0);	/* nothing changed */
  
  	ask_questions = ((quitting && !prompt) ? FALSE : question_me);
  
  	/* YES or NO on softkeys */
  	if (hp_softkeys && ask_questions) {
  	  define_softkeys(YESNO);
  	  softkeys_on();
  	}
  
  	/* Clear the exit dispositions of all messages, just in case
  	 * they were left set by a previous call to this function
--- 109,144 ----
  
  	dprint(1, (debugfile, "\n\n-- leaving folder --\n\n"));
  
! 	if (message_count == 0) {
! 	  if (folder_type == NON_SPOOL && !keep_empty_files && !resyncing &&
! 	      0 == bytes(cur_folder)) {
! 
! 	    /* i.e. if no messages were and this is not a spool
! 	     * folder and we aren't keeping empty non-spool folders,
! 	     * simply remove the old original folder and that's it!
! 	     */
! 	    if (0 == unlink(cur_folder)) {
! 
! 	      dprint(3, (debugfile, "Removing folder!\n"));
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFolderRemoved,
! 				"Folder removed."));
! 
! 	    }
! 	    return(1);
! 	  }
! 
  	  return(0);	/* nothing changed */
  
+ 	}
  	ask_questions = ((quitting && !prompt) ? FALSE : question_me);
  
  	/* YES or NO on softkeys */
+ 	/*
  	if (hp_softkeys && ask_questions) {
  	  define_softkeys(YESNO);
  	  softkeys_on();
  	}
+ 	*/
  
  	/* Clear the exit dispositions of all messages, just in case
  	 * they were left set by a previous call to this function
***************
*** 258,269 ****
  	  answer = (always_del ? *def_ans_yes : *def_ans_no);	/* default answer */
  	  if(ask_questions) {
  	    if (marked_deleted == 1)
! 	      MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveDeleteMessage,
! 		"Delete message? (%c/%c) "), *def_ans_yes, *def_ans_no);
  	    else
! 	      MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveDeleteMessages,
! 		"Delete messages? (%c/%c) "), *def_ans_yes, *def_ans_no);
! 	    answer = want_to(buffer, answer, LINES-3, 0);
  	  }
  
  	  if(answer == *def_ans_yes) {
--- 158,173 ----
  	  answer = (always_del ? *def_ans_yes : *def_ans_no);	/* default answer */
  	  if(ask_questions) {
  	    if (marked_deleted == 1)
! 	      elm_sfprintf(buffer, sizeof buffer,
! 			   CATGETS(elm_msg_cat, ElmSet, ElmLeaveDeleteMessage,
! 				   "Delete message? (%c/%c) "), 
! 			   *def_ans_yes, *def_ans_no);
  	    else
! 	      elm_sfprintf(buffer, sizeof buffer,
! 			   CATGETS(elm_msg_cat, ElmSet, ElmLeaveDeleteMessages,
! 				   "Delete messages? (%c/%c) "), 
! 			   *def_ans_yes, *def_ans_no);
! 	    answer = want_to(buffer, answer, elm_LINES-3, 0);
  	  }
  
  	  if(answer == *def_ans_yes) {
***************
*** 308,321 ****
  	    answer = (always_store ? *def_ans_yes : *def_ans_no);	/* default answer */
  	    if(ask_questions) {
  	      if (marked_read == 1)
! 		MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveMoveMessage,
! 			"Move read message to \"received\" folder? (%c/%c) "),
! 			*def_ans_yes, *def_ans_no);
  	      else
! 		MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveMoveMessages,
! 			"Move read messages to \"received\" folder? (%c/%c) "),
! 			*def_ans_yes, *def_ans_no);
! 	      answer = want_to(buffer, answer, LINES-3, 0);
  	      asked_storage_q = TRUE;
  	    }
  
--- 212,227 ----
  	    answer = (always_store ? *def_ans_yes : *def_ans_no);	/* default answer */
  	    if(ask_questions) {
  	      if (marked_read == 1)
! 		elm_sfprintf(buffer, sizeof buffer,
! 			     CATGETS(elm_msg_cat, ElmSet, ElmLeaveMoveMessage,
! 				     "Move read message to \"received\" folder? (%c/%c) "),
! 			     *def_ans_yes, *def_ans_no);
  	      else
! 		elm_sfprintf(buffer, sizeof buffer,
! 			     CATGETS(elm_msg_cat, ElmSet, ElmLeaveMoveMessages,
! 				     "Move read messages to \"received\" folder? (%c/%c) "),
! 			     *def_ans_yes, *def_ans_no);
! 	      answer = want_to(buffer, answer, elm_LINES-3, 0);
  	      asked_storage_q = TRUE;
  	    }
  
***************
*** 362,375 ****
  	      answer = (always_keep ? *def_ans_yes : *def_ans_no);	/* default answer */
  	      if(ask_questions) {
  		if (marked_unread == 1)
! 		  MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveKeepMessage,
  		    "Keep unread message in incoming mailbox? (%c/%c) "),
! 		    *def_ans_yes, *def_ans_no);
  		else
! 		  MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveKeepMessages,
! 		    "Keep unread messages in incoming mailbox? (%c/%c) "),
! 		    *def_ans_yes, *def_ans_no);
! 		answer = want_to(buffer, answer, LINES-3, 0);
  	      }
  
  	      for (i = 0; i < message_count; i++) {
--- 268,283 ----
  	      answer = (always_keep ? *def_ans_yes : *def_ans_no);	/* default answer */
  	      if(ask_questions) {
  		if (marked_unread == 1)
! 		  elm_sfprintf(buffer, sizeof buffer,
! 			       CATGETS(elm_msg_cat, ElmSet, ElmLeaveKeepMessage,
  		    "Keep unread message in incoming mailbox? (%c/%c) "),
! 			       *def_ans_yes, *def_ans_no);
  		else
! 		  elm_sfprintf(buffer, sizeof buffer,
! 			       CATGETS(elm_msg_cat, ElmSet, ElmLeaveKeepMessages,
! 				       "Keep unread messages in incoming mailbox? (%c/%c) "),
! 			       *def_ans_yes, *def_ans_no);
! 		answer = want_to(buffer, answer, elm_LINES-3, 0);
  	      }
  
  	      for (i = 0; i < message_count; i++) {
***************
*** 394,407 ****
  	dprint(3, (debugfile, "Messages to keep: %d\n", to_keep));
  
  	if(to_delete + to_store + to_keep != message_count) {
! 	  MoveCursor(LINES, 0);
  	  Raw(OFF);
  	  dprint(1, (debugfile,
  	  "Error: %d to delete + %d to store + %d to keep != %d message cnt\n",
  	    to_delete, to_store, to_keep, message_count));
! 	  printf(catgets(elm_msg_cat, ElmSet, ElmSomethingWrongInCounts,
! 		"Something wrong in message counts! Folder unchanged.\n"));
! 	  emergency_exit();
  	}
  	  
  
--- 302,315 ----
  	dprint(3, (debugfile, "Messages to keep: %d\n", to_keep));
  
  	if(to_delete + to_store + to_keep != message_count) {
! 	  MoveCursor(elm_LINES, 0);
  	  Raw(OFF);
  	  dprint(1, (debugfile,
  	  "Error: %d to delete + %d to store + %d to keep != %d message cnt\n",
  	    to_delete, to_store, to_keep, message_count));
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSomethingWrongInCounts,
! 			    "Something wrong in message counts! Folder unchanged.\n"));
! 	  emergency_exit(0);
  	}
  	  
  
***************
*** 430,437 ****
  	
  	if(!to_delete && !to_store && !num_chgd_status && !resyncing) {
  	  dprint(3, (debugfile, "Folder keep as is!\n"));
! 	  error(catgets(elm_msg_cat, ElmSet, ElmFolderUnchanged,
! 		"Folder unchanged."));
  	  return(0);
  	}
  
--- 338,345 ----
  	
  	if(!to_delete && !to_store && !num_chgd_status && !resyncing) {
  	  dprint(3, (debugfile, "Folder keep as is!\n"));
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFolderUnchanged,
! 			    "Folder unchanged."));
  	  return(0);
  	}
  
***************
*** 455,522 ****
  	  if (to_store > 0) {
  	    if (to_delete > 0) {
  	      if (to_keep == 1)
! 	        MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveKeepStoreDelete,
! 		      "[Keeping 1 message, storing %d, and deleting %d.]"), 
! 		    to_store, to_delete);
  	      else
! 	        MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveKeepStoreDeletePlural,
! 		      "[Keeping %d messages, storing %d, and deleting %d.]"), 
! 		    to_keep, to_store, to_delete);
  	    } else {
  	      if (to_keep == 1)
! 		sprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveKeepStore,
! 			"[Keeping 1 message and storing %d.]"), 
! 		      to_store);
  	      else
! 		MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveKeepStorePlural,
! 			"[Keeping %d messages and storing %d.]"), 
! 		      to_keep, to_store);
  	    }
  	  } else {
  	    if (to_delete > 0) {
  	      if (to_keep == 1)
! 		sprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveKeepDelete,
! 			"[Keeping 1 message and deleting %d.]"), 
! 		      to_delete);
  	      else
! 		MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveKeepDeletePlural,
! 			"[Keeping %d messages and deleting %d.]"), 
! 		      to_keep, to_delete);
  	    } else {
  	      if (to_keep == 1)
! 		strcpy(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveKeep,
! 			"[Keeping message.]"));
  	      else
! 		strcpy(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveKeepPlural,
! 			"[Keeping all messages.]"));
  	    }
  	  }
  	} else if (to_store > 0) {
  	  if (to_delete > 0) {
  	    if (to_store == 1)
! 	      sprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveStoreDelete,
! 		      "[Storing 1 message and deleting %d.]"), 
! 		    to_delete);
  	    else
! 	      MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveStoreDeletePlural,
! 		      "[Storing %d messages and deleting %d.]"), 
! 		    to_store, to_delete);
  	  } else {
  	    if (to_store == 1)
! 	      strcpy(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveStore,
! 		      "[Storing message.]"));
  	    else
! 	      strcpy(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveStorePlural,
! 		      "[Storing all messages.]"));
  	  }
  	} else {
  	  if (to_delete > 0)
! 	    strcpy(buffer, catgets(elm_msg_cat, ElmSet, ElmLeaveDelete,
! 		"[Deleting all messages.]"));
! 	  else
! 	    buffer[0] = '\0';
  	}
! 	/* NOTE: don't use variable "buffer" till message is output later */
  
  	/** next, let's lock the file up and make one last size check **/
  
--- 363,437 ----
  	  if (to_store > 0) {
  	    if (to_delete > 0) {
  	      if (to_keep == 1)
! 		lib_error(
! 			  CATGETS(elm_msg_cat, ElmSet, ElmLeaveKeepStoreDelete,
! 				  "[Keeping 1 message, storing %d, and deleting %d.]"), 
! 			  to_store, to_delete);
  	      else
! 		lib_error(
! 			  CATGETS(elm_msg_cat, ElmSet, ElmLeaveKeepStoreDeletePlural,
! 				  "[Keeping %d messages, storing %d, and deleting %d.]"), 
! 			  to_keep, to_store, to_delete);
  	    } else {
  	      if (to_keep == 1)
! 		lib_error(
! 			  CATGETS(elm_msg_cat, ElmSet, ElmLeaveKeepStore,
! 				  "[Keeping 1 message and storing %d.]"), 
! 			  to_store);
  	      else
! 		lib_error(
! 			  CATGETS(elm_msg_cat, ElmSet, ElmLeaveKeepStorePlural,
! 				  "[Keeping %d messages and storing %d.]"), 
! 			  to_keep, to_store);
  	    }
  	  } else {
  	    if (to_delete > 0) {
  	      if (to_keep == 1)
! 		lib_error(
! 			  CATGETS(elm_msg_cat, ElmSet, ElmLeaveKeepDelete,
! 				  "[Keeping 1 message and deleting %d.]"), 
! 			  to_delete);
  	      else
! 		lib_error(
! 			  CATGETS(elm_msg_cat, ElmSet, ElmLeaveKeepDeletePlural,
! 				  "[Keeping %d messages and deleting %d.]"), 
! 			  to_keep, to_delete);
  	    } else {
  	      if (to_keep == 1)
! 		lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveKeep,
! 					"[Keeping message.]"));
  	      else
! 		lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 				  ElmLeaveKeepPlural,
! 				  "[Keeping all messages.]"));
  	    }
  	  }
  	} else if (to_store > 0) {
  	  if (to_delete > 0) {
  	    if (to_store == 1)
! 	      lib_error(
! 			CATGETS(elm_msg_cat, ElmSet, ElmLeaveStoreDelete,
! 				"[Storing 1 message and deleting %d.]"), 
! 			to_delete);
  	    else
! 	      lib_error(
! 			CATGETS(elm_msg_cat, ElmSet, ElmLeaveStoreDeletePlural,
! 				"[Storing %d messages and deleting %d.]"), 
! 			to_store, to_delete);
  	  } else {
  	    if (to_store == 1)
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveStore,
! 				      "[Storing message.]"));
  	    else
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveStorePlural,
! 				"[Storing all messages.]"));
  	  }
  	} else {
  	  if (to_delete > 0)
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveDelete,
! 			      "[Deleting all messages.]"));
  	}
! 
  
  	/** next, let's lock the file up and make one last size check **/
  
***************
*** 523,587 ****
  	if (folder_type == SPOOL)
  	  lock(OUTGOING);
  	
! 	fflush (mailfile);
  
  	if (mailfile_size != bytes(cur_folder)) {
! 	    unlock();
! 	    error(catgets(elm_msg_cat, ElmSet, ElmLeaveNewMailArrived,
! 			  "New mail has just arrived. Resynchronizing..."));
  	    return(-1);
  	}
  	
- 	/* Everything's GO - so ouput that user message and go to it. */
  
  	block_signals();
  	
! 	dprint(2, (debugfile, "Action: %s\n", buffer));
! 	error(buffer);
  
  	/* Store messages slated for storage in received mail folder */
  	if (to_store > 0) {
  	  if ((err = can_open(recvd_mail, "a"))) {
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmLeaveAppendDenied,
! 	      "Permission to append to %s denied!  Leaving folder intact.\n"),
! 	      recvd_mail);
  	    dprint(1, (debugfile,
  	      "Error: Permission to append to folder %s denied!! (%s)\n",
  	      recvd_mail, "leavembox"));
  	    dprint(1, (debugfile, "** %s **\n", error_description(err)));
  
! 	    fflush (mailfile);
! 	    unlock();
  
  	    unblock_signals();
  	    return(0);
  	  }
! 	  if ((temp = fopen(recvd_mail,"a")) == NULL) {
  	    err = errno;
  
! 	    fflush (mailfile);
! 	    unlock();
  
- 	    MoveCursor(LINES, 0);
- 	    Raw(OFF);
  	    dprint(1, (debugfile, "Error: could not append to file %s\n", 
  	      recvd_mail));
  	    dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmLeaveCouldNotAppend,
! 		"Could not append to folder %s!\n"), recvd_mail);
! 	    emergency_exit();
  	  }
  	  dprint(2, (debugfile, "Storing message%s ", plural(to_store)));
  	  for (i = 0; i < message_count; i++) {
  	    if(headers[i]->exit_disposition == STORE) {
  	      current = i+1;
  	      dprint(2, (debugfile, "#%d, ", current));
! 	      copy_message("", temp, CM_UPDATE_STATUS);
  	    }
  	  }
  	  fclose(temp);
  	  dprint(2, (debugfile, "\n\n"));
  	  (void) elm_chown(recvd_mail, userid, groupid);
  	}
  
  	/* If there are any messages to keep, first copy them to a
--- 438,517 ----
  	if (folder_type == SPOOL)
  	  lock(OUTGOING);
  	
! 	flush_mailfile();
  
  	if (mailfile_size != bytes(cur_folder)) {
! 	    unlock(0);
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveNewMailArrived,
! 			      "New mail has just arrived. Resynchronizing..."));
  	    return(-1);
  	}
  	
  
  	block_signals();
  	
! 	dprint(2, (debugfile, "Action...\n"));
  
  	/* Store messages slated for storage in received mail folder */
  	if (to_store > 0) {
  	  if ((err = can_open(recvd_mail, "a"))) {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveAppendDenied,
! 			      "Permission to append to %s denied!  Leaving folder intact.\n"),
! 		      recvd_mail);
  	    dprint(1, (debugfile,
  	      "Error: Permission to append to folder %s denied!! (%s)\n",
  	      recvd_mail, "leavembox"));
  	    dprint(1, (debugfile, "** %s **\n", error_description(err)));
  
! 	    unlock(0);
  
  	    unblock_signals();
  	    return(0);
  	  }
! 
! 	  /* open_end_update seeks to end of file */
! 	  if ((temp = open_end_update(recvd_mail)) == NULL) {
  	    err = errno;
  
! 	    unlock(0);
  
  	    dprint(1, (debugfile, "Error: could not append to file %s\n", 
  	      recvd_mail));
  	    dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveCouldNotAppend,
! 			      "Could not append to folder %s!\n"), 
! 		      recvd_mail);
! 	    sleep_message();
! 
! 	    unblock_signals();
! 	    return(0);
  	  }
+ 	  
  	  dprint(2, (debugfile, "Storing message%s ", plural(to_store)));
  	  for (i = 0; i < message_count; i++) {
  	    if(headers[i]->exit_disposition == STORE) {
  	      current = i+1;
  	      dprint(2, (debugfile, "#%d, ", current));
! 	      copy_message(mailfile,headers[i],
! 			   "", temp, CM_UPDATE_STATUS);
  	    }
  	  }
  	  fclose(temp);
  	  dprint(2, (debugfile, "\n\n"));
  	  (void) elm_chown(recvd_mail, userid, groupid);
+ 	  if (ferror(mailfile)) {
+ 	    unlock(0);
+ 
+ 	    dprint(1, (debugfile, "error when reading mailfile\n"));
+ 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorReadMailfile,
+ 			      "Error when reading mailfile %s"),
+ 		      cur_folder);
+ 	    sleep_message();
+ 	    clearerr(mailfile);
+ 
+ 	    unblock_signals();
+ 	    return(-2);
+ 	  }
  	}
  
  	/* If there are any messages to keep, first copy them to a
***************
*** 588,623 ****
  	 * temp file, then remove original and copy whole temp file over.
  	 */
  	if (to_keep > 0) {
! 	  sprintf(temp_keep_file, "%s%s%d", temp_dir, temp_file, getpid());
! 	  if ((err = can_open(temp_keep_file, "w"))) {
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmLeaveTempFileDenied,
! "Permission to create temp file %s for writing denied! Leaving folder intact."),
! 	      temp_keep_file);
  	    dprint(1, (debugfile,
  	      "Error: Permission to create temp file %s denied!! (%s)\n",
  	      temp_keep_file, "leavembox"));
  	    dprint(1, (debugfile, "** %s **\n", error_description(err)));
  
! 	    fflush (mailfile);
! 	    unlock();
  
  	    unblock_signals();
! 	    return(0);
  	  }
! 	  if ((temp = fopen(temp_keep_file,"w")) == NULL) {
  	    err = errno;
  
! 	    fflush (mailfile);
! 	    unlock();
  
- 	    MoveCursor(LINES, 0);
- 	    Raw(OFF);
  	    dprint(1, (debugfile, "Error: could not create file %s\n", 
  	      temp_keep_file));
  	    dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmLeaveCouldNotCreate,
! 		"Could not create temp file %s!\n"), temp_keep_file);
! 	    emergency_exit();
  	  }
  	  dprint(2, (debugfile, "Copying to temp file message%s to be kept ",
  	    plural(to_keep)));
--- 518,554 ----
  	 * temp file, then remove original and copy whole temp file over.
  	 */
  	if (to_keep > 0) {
! 	  elm_sfprintf(temp_keep_file, sizeof temp_keep_file,
! 		       FRM("%s%s%d"), 
! 		       temp_dir, temp_file, getpid());
! 	  if ((err = can_open(temp_keep_file, "sw"))) {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveTempFileDenied,
! 			      "Permission to create temp file %s for writing denied! Leaving folder intact."),
! 		      temp_keep_file);
  	    dprint(1, (debugfile,
  	      "Error: Permission to create temp file %s denied!! (%s)\n",
  	      temp_keep_file, "leavembox"));
  	    dprint(1, (debugfile, "** %s **\n", error_description(err)));
  
! 	    unlock(0);
  
  	    unblock_signals();
! 	    return(-2);
  	  }
! 	  if ((temp = fopen(temp_keep_file,"w+")) == NULL) {
  	    err = errno;
  
! 	    unlock(0);
  
  	    dprint(1, (debugfile, "Error: could not create file %s\n", 
  	      temp_keep_file));
  	    dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveCouldNotCreate,
! 			      "Could not create temp file %s!"), 
! 		      temp_keep_file);
! 
! 	    unblock_signals();
! 	    return(-2);
  	  }
  	  dprint(2, (debugfile, "Copying to temp file message%s to be kept ",
  	    plural(to_keep)));
***************
*** 625,642 ****
  	    if(headers[i]->exit_disposition == KEEP) {
  	      current = i+1;
  	      dprint(2, (debugfile, "#%d, ", current));
! 	      copy_message("", temp, CM_UPDATE_STATUS);
  	    }
  	  }
  	  if ( fclose(temp) == EOF ) {
! 	    MoveCursor(LINES, 0);
! 	    Raw(OFF);
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmLeaveCloseFailedTemp,
! 		"\nClose failed on temp keep file in leavembox\n"));
! 	    perror(temp_keep_file);
! 	    dprint(2, (debugfile, "\n\rfclose err on temp_keep_file - leavembox\n\r"));
! 	    rm_temps_exit();
  	  }
  	  dprint(2, (debugfile, "\n\n"));
  
  	} else if (folder_type == NON_SPOOL && !keep_empty_files && !resyncing) {
--- 556,595 ----
  	    if(headers[i]->exit_disposition == KEEP) {
  	      current = i+1;
  	      dprint(2, (debugfile, "#%d, ", current));
! 	      copy_message(mailfile,headers[i],
! 			   "", temp, CM_UPDATE_STATUS);
  	    }
  	  }
  	  if ( fclose(temp) == EOF ) {
! 	    err = errno;
! 	    unlock(0);
! 
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveCloseFailedTemp,
! 			      "Close failed in leavembox: %s: %s"),
! 		      temp_keep_file,
! 		      error_description(err));
! 	    dprint(2, (debugfile, 
! 		       "\n\rfclose err on temp_keep_file - leavembox\n\r"));
! 	    unblock_signals();
! 	    unlink (temp_keep_file);
! 	    return -2;
! 	  }
! 	  if (ferror(mailfile)) {
! 	    unlock(0);
! 
! 	    dprint(1,(debugfile,"Failed to read mailfile!"));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorReadMailfile,
! 			      "Error when reading mailfile %s"),
! 		      cur_folder);
! 	    sleep_message();
! 
! 	    unblock_signals();
! 	    clearerr(mailfile);
! 	    unlink (temp_keep_file);
! 
! 	    return -2;
  	  }
+ 
  	  dprint(2, (debugfile, "\n\n"));
  
  	} else if (folder_type == NON_SPOOL && !keep_empty_files && !resyncing) {
***************
*** 645,651 ****
  	   * folder and we aren't keeping empty non-spool folders,
  	   * simply remove the old original folder and that's it!
  	   */
! 	  (void)unlink(cur_folder);
  	  unblock_signals();
  	  return(1);
  	}
--- 598,608 ----
  	   * folder and we aren't keeping empty non-spool folders,
  	   * simply remove the old original folder and that's it!
  	   */
! 	  if (0 == unlink(cur_folder)) {
! 	    dprint(3, (debugfile, "Removing folder!\n"));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFolderRemoved,
! 			      "Folder removed."));	
! 	  }
  	  unblock_signals();
  	  return(1);
  	}
***************
*** 656,665 ****
  	 * mail folder before we remove it.
  	 */
  	if(save_file_stats(cur_folder) != 0) {
! 	  error1(catgets(elm_msg_cat, ElmSet, ElmLeaveProblemsSavingPerms,
! 		"Problems saving permissions of folder %s!"), cur_folder);
! 	  if (sleepmsg > 0)
! 		sleep(sleepmsg);
  	}
  	  
          if (stat(cur_folder, &buf) != 0) {
--- 613,623 ----
  	 * mail folder before we remove it.
  	 */
  	if(save_file_stats(cur_folder) != 0) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveProblemsSavingPerms,
! 			    "Problems saving permissions of folder %s!"), 
! 		    cur_folder);
! 
! 	  sleep_message();
  	}
  	  
          if (stat(cur_folder, &buf) != 0) {
***************
*** 666,673 ****
  	  err = errno;
  	  dprint(1, (debugfile, "Error: errno %s attempting to stat file %s\n", 
  		     error_description(err), cur_folder));
!           error2(catgets(elm_msg_cat, ElmSet, ElmLeaveErrorOnStat,
! 		"Error %s on stat(%s)."), error_description(err), cur_folder);
  	}
  
  #ifdef SYMLINK
--- 624,634 ----
  	  err = errno;
  	  dprint(1, (debugfile, "Error: errno %s attempting to stat file %s\n", 
  		     error_description(err), cur_folder));
!           lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveErrorOnStat,
! 			    "Error %s on stat(%s)."), 
! 		    error_description(err), cur_folder);
! 
! 	  sleep_message();
  	}
  
  #ifdef SYMLINK
***************
*** 675,682 ****
  	  err = errno;
  	  dprint(1, (debugfile, "Error: errno %s attempting to stat file %s\n", 
  		     error_description(err), cur_folder));
!           error2(catgets(elm_msg_cat, ElmSet, ElmLeaveErrorOnStat,
! 		"Error %s on stat(%s)."), error_description(err), cur_folder);
  	}
  #endif
  
--- 636,645 ----
  	  err = errno;
  	  dprint(1, (debugfile, "Error: errno %s attempting to stat file %s\n", 
  		     error_description(err), cur_folder));
!           lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveErrorOnStat,
! 			    "Error %s on stat(%s)."), 
! 		    error_description(err), cur_folder);
! 	  sleep_message();
  	}
  #endif
  
***************
*** 705,711 ****
  	 * individual closes in the subcases to ensure that the
  	 * mailbox is locked until we are finished with it.
  	 */
! 	fflush(mailfile);
  
  #ifdef SYSCALL_LOCKING
  	need_to_copy = (folder_type == SPOOL ? TRUE : FALSE);
--- 668,675 ----
  	 * individual closes in the subcases to ensure that the
  	 * mailbox is locked until we are finished with it.
  	 */
! 
! 	flush_mailfile();
  
  #ifdef SYSCALL_LOCKING
  	need_to_copy = (folder_type == SPOOL ? TRUE : FALSE);
***************
*** 715,721 ****
  	if (buf.st_nlink > 1)
  		need_to_copy = TRUE;
  
! 	if (buf.st_mode & 0x7000) { /* copy if special modes set */
  		need_to_copy = TRUE;    /* such as enforcement lock */
  	}
  
--- 679,685 ----
  	if (buf.st_nlink > 1)
  		need_to_copy = TRUE;
  
! 	if (buf.st_mode & 07000) { /* copy if special modes set */
  		need_to_copy = TRUE;    /* such as enforcement lock */
  	}
  
***************
*** 726,731 ****
--- 690,696 ----
  	if ((lbuf.st_mode & S_IFMT) == S_IFLNK) {
  #endif
  		need_to_copy = TRUE;
+ 		was_symlink = TRUE;
  	}
  #endif
  
***************
*** 758,778 ****
  		need_to_copy = TRUE;
  	      } else {
  		err = errno;
! 		MoveCursor(LINES, 0);
  		Raw(OFF);
  		dprint(1, (debugfile, "link(%s, %s) failed (leavembox)\n", 
  		       temp_keep_file, cur_folder));
  		dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 		printf(catgets(elm_msg_cat, ElmSet, ElmLeaveLinkFailed,
! 			"Link failed! %s.\n"), error_description(err));
  #ifdef SAVE_GROUP_MAILBOX_ID
  	        if (folder_type == SPOOL)
  		  setgid(groupid);
  #endif
! 		fflush (mailfile);
! 		unlock();
  		fclose(mailfile);
! 		emergency_exit();
  	      }
  	    }
  	  }
--- 723,743 ----
  		need_to_copy = TRUE;
  	      } else {
  		err = errno;
! 		MoveCursor(elm_LINES, 0);
  		Raw(OFF);
  		dprint(1, (debugfile, "link(%s, %s) failed (leavembox)\n", 
  		       temp_keep_file, cur_folder));
  		dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 		lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveLinkFailed,
! 				  "Link failed! %s.\n"), 
! 			  error_description(err));
  #ifdef SAVE_GROUP_MAILBOX_ID
  	        if (folder_type == SPOOL)
  		  setgid(groupid);
  #endif
! 		unlock(0);
  		fclose(mailfile);
! 		emergency_exit(0);
  	      }
  	    }
  	  }
***************
*** 786,822 ****
  	      dprint(1, (debugfile, "leavembox: copy(%s, %s) failed;",
  		      temp_keep_file, cur_folder));
  	      dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	      error(catgets(elm_msg_cat, ElmSet, ElmLeaveCouldntModifyFolder,
! 			"Couldn't modify folder!"));
  	      if (sleepmsg > 0)
  		    sleep((sleepmsg + 1) / 2);
! 	      sprintf(cur_folder,"%s/%s", home, unedited_mail);
  	      if (copy(temp_keep_file, cur_folder, FALSE) != 0) {
  
  		/* couldn't copy to special file either */
  		err = errno;
! 		MoveCursor(LINES, 0);
  		Raw(OFF);
  		dprint(1, (debugfile, 
  			"leavembox: couldn't copy to %s either!!  Help;", 
  			cur_folder));
  		dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 		printf(catgets(elm_msg_cat, ElmSet, ElmLeaveCantCopyMailbox,
! 			"Can't copy folder, system trouble : contents preserved in %s\n"),temp_keep_file);
  #ifdef SAVE_GROUP_MAILBOX_ID
  	        if (folder_type == SPOOL)
  		  setgid(groupid);
  #endif
! 		fflush (mailfile);
! 		unlock();
  		fclose(mailfile);
! 		emergency_exit();
  	      } else {
  		dprint(1, (debugfile,
  			"\nWoah! Confused - Saved mail in %s (leavembox)\n", 
  			cur_folder));
! 		error1(catgets(elm_msg_cat, ElmSet, ElmLeaveSavedMailIn,
! 			"Saved mail in %s."), cur_folder);
  		if (sleepmsg > 0)
  		    sleep((sleepmsg + 1) / 2);
  	      }
--- 751,789 ----
  	      dprint(1, (debugfile, "leavembox: copy(%s, %s) failed;",
  		      temp_keep_file, cur_folder));
  	      dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveCouldntModifyFolder,
! 				"Couldn't modify folder!"));
  	      if (sleepmsg > 0)
  		    sleep((sleepmsg + 1) / 2);
! 	      elm_sfprintf(cur_folder,sizeof cur_folder,
! 			   FRM("%s/%s"), home, unedited_mail);
  	      if (copy(temp_keep_file, cur_folder, FALSE) != 0) {
  
  		/* couldn't copy to special file either */
  		err = errno;
! 		MoveCursor(elm_LINES, 0);
  		Raw(OFF);
  		dprint(1, (debugfile, 
  			"leavembox: couldn't copy to %s either!!  Help;", 
  			cur_folder));
  		dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 		lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveCantCopyMailbox,
! 				  "Can't copy folder, system trouble : contents preserved in %s\n"),
! 			  temp_keep_file);
  #ifdef SAVE_GROUP_MAILBOX_ID
  	        if (folder_type == SPOOL)
  		  setgid(groupid);
  #endif
! 		unlock(0);
  		fclose(mailfile);
! 		emergency_exit(0);
  	      } else {
  		dprint(1, (debugfile,
  			"\nWoah! Confused - Saved mail in %s (leavembox)\n", 
  			cur_folder));
! 		lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveSavedMailIn,
! 				  "Saved mail in %s."), 
! 			  cur_folder);
  		if (sleepmsg > 0)
  		    sleep((sleepmsg + 1) / 2);
  	      }
***************
*** 833,840 ****
  	   * spool files), create an empty file */
  
  	  if(folder_type == NON_SPOOL)
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmLeaveKeepingEmpty,
! 		"Keeping empty folder '%s'."), cur_folder);
  	  temp = fopen(cur_folder, "w");
  	  fclose(temp);
  	}
--- 800,808 ----
  	   * spool files), create an empty file */
  
  	  if(folder_type == NON_SPOOL)
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveKeepingEmpty,
! 			      "Keeping empty folder '%s'."), 
! 		      cur_folder);
  	  temp = fopen(cur_folder, "w");
  	  fclose(temp);
  	}
***************
*** 845,860 ****
  	 * tracking down what it points to.
  	 */
  
! 	if (!need_to_copy) {
  	  if(restore_file_stats(cur_folder) != 1) {
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmLeaveProblemsRestoringPerms,
! 		  "Problems restoring permissions of folder %s!"), cur_folder);
  	    if (sleepmsg > 0)
  		sleep(sleepmsg);
  	  }
  	}
  
! #if defined(BSD) && !defined(UTIMBUF)
  	utime_buffer[0]     = buf.st_atime;
  	utime_buffer[1]     = buf.st_mtime;
  #else
--- 813,829 ----
  	 * tracking down what it points to.
  	 */
  
! 	if (!was_symlink) {
  	  if(restore_file_stats(cur_folder) != 1) {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveProblemsRestoringPerms,
! 			      "Problems restoring permissions of folder %s!"),
! 		      cur_folder);
  	    if (sleepmsg > 0)
  		sleep(sleepmsg);
  	  }
  	}
  
! #if defined(BSD_TYPE) && !defined(UTIMBUF)
  	utime_buffer[0]     = buf.st_atime;
  	utime_buffer[1]     = buf.st_mtime;
  #else
***************
*** 862,868 ****
  	utime_buffer.modtime= buf.st_mtime;
  #endif
  
! #if defined(BSD) && !defined(UTIMBUF)
  	if (utime(cur_folder, utime_buffer) != 0) 
  #else
  	if (utime(cur_folder, &utime_buffer) != 0) 
--- 831,837 ----
  	utime_buffer.modtime= buf.st_mtime;
  #endif
  
! #if defined(BSD_TYPE) && !defined(UTIMBUF)
  	if (utime(cur_folder, utime_buffer) != 0) 
  #else
  	if (utime(cur_folder, &utime_buffer) != 0) 
***************
*** 872,880 ****
  	  dprint(1, (debugfile, 
  		 "Error: encountered error doing utime (leavmbox)\n"));
  	  dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	  error2(catgets(elm_msg_cat, ElmSet, ElmLeaveChangingAccessTime,
! 		"Error %s trying to change file %s access time."), 
! 		   error_description(err), cur_folder);
  	}
  #ifdef SAVE_GROUP_MAILBOX_ID
  	if (folder_type == SPOOL)
--- 841,850 ----
  	  dprint(1, (debugfile, 
  		 "Error: encountered error doing utime (leavmbox)\n"));
  	  dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveChangingAccessTime,
! 			    "Error %s trying to change file %s access time."), 
! 		    error_description(err), 
! 		    cur_folder);
  	}
  #ifdef SAVE_GROUP_MAILBOX_ID
  	if (folder_type == SPOOL)
***************
*** 881,889 ****
  	    setgid(groupid);
  #endif
  
- 	fflush (mailfile);
  	mailfile_size = bytes(cur_folder);
! 	unlock();	/* remove the lock on the file ASAP! */
  	fclose(mailfile);
  	mailfile = NULL;
  	unblock_signals();
--- 851,858 ----
  	    setgid(groupid);
  #endif
  
  	mailfile_size = bytes(cur_folder);
! 	unlock(0);	/* remove the lock on the file ASAP! */
  	fclose(mailfile);
  	mailfile = NULL;
  	unblock_signals();
***************
*** 994,997 ****
  #  endif /* HASSIGBLOCK */
  #endif /* HASSIGPROCMASK */
  }
- 
--- 963,965 ----
Index: elm2.4.ME+.50/src/limit.c
*** elm2.4.25/src/limit.c	Mon May 16 02:10:11 1994
--- elm2.4.ME+.50/src/limit.c	Tue Nov 17 21:12:58 1998
***************
*** 1,41 ****
  
! static char rcsid[] = "@(#)$Id: limit.c,v 5.4 1994/05/15 23:10:08 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: limit.c,v $
!  * Revision 5.4  1994/05/15  23:10:08  syd
!  * Below are the changes required to compile/link elm 2.4 pl23 under
!  * QNX 4.2 with the Watcom 9.5 compiler (very picky).
!  * From: "Brian Campbell" <brianc@quantum>
!  *
!  * Revision 5.3  1993/05/31  19:17:02  syd
!  * While looking into the feasibility of adding `limit sender' as requested
!  * on Usenet, I noticed that the limit code was replicated for each of
!  * the supported conditions.  The following patch simplifies limit_selection()
!  * by sharing the common code between all conditions.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.2  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This stuff is inspired by MH and dmail and is used to 'select'
      a subset of the existing mail in the folder based on one of a
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: limit.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This stuff is inspired by MH and dmail and is used to 'select'
      a subset of the existing mail in the folder based on one of a
***************
*** 49,59 ****
--- 24,37 ----
  #include "headers.h"
  #include "s_elm.h"
  #include "s_aliases.h"
+ #include "me.h"
  
  #define TO		1
  #define FROM		2
+ #define CC              3
  
  char *shift_lower();
+ void ClearSelection();
  
  int
  limit()
***************
*** 63,68 ****
--- 41,48 ----
  	char criteria[STRING], first[STRING], rest[STRING], msg[STRING];
  	static char *prompt = NULL;
  	int  last_selected, all;
+ 	char 	ch_s[255];
+ 	char  	*ch_p;
  
  	last_selected = selected;
  	all = 0;
***************
*** 72,101 ****
  	}
  
  	if (selected) {
! 	  MCsprintf(msg, catgets(elm_msg_cat, ElmSet, ElmLimitAlreadyHave,
! 		"Already have selection criteria - add more? (%c/%c) %c%c"),
! 		*def_ans_yes, *def_ans_no, *def_ans_no, BACKSPACE);
! 	  PutLine0(LINES-2, 0, msg);
! 	  criteria[0] = ReadCh();
  	  if (tolower(criteria[0]) == *def_ans_yes) {
! 	    Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmYesWord, "Yes."), 0);
! 	    PutLine0(LINES-3, COLUMNS-30, catgets(elm_msg_cat, ElmSet, ElmLimitAdding,
! 		"Adding criteria..."));
  	  } else {
! 	    Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmNoWord, "No."), 0);
  	    selected = 0;
- 	    PutLine0(LINES-3, COLUMNS-30, catgets(elm_msg_cat, ElmSet, ElmLimitChanging,
- 		"Change criteria..."));
  	  }
  	}
  
  	while(1) {
! 	  PutLine0(LINES-2, 0, prompt);
  	  CleartoEOLN();
  
  	  criteria[0] = '\0';
! 	  optionally_enter(criteria, LINES-2, strlen(prompt), FALSE, FALSE);
! 	  error("");
  	  
  	  if (strlen(criteria) == 0) {
  	    /* no change */
--- 52,87 ----
  	}
  
  	if (selected) {
! 	  elm_sfprintf(msg, sizeof msg,
! 		       CATGETS(elm_msg_cat, ElmSet, ElmLimitAlreadyHave,
! 			       "Already have selection criteria - add more? (%c/%c) %c%c"),
! 		       *def_ans_yes, *def_ans_no, *def_ans_no, BACKSPACE);
! 	  PutLine0(elm_LINES-2, 0, msg);
! 	  criteria[0] = ReadCh(0);
  	  if (tolower(criteria[0]) == *def_ans_yes) {
! 	    Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmYesWord, "Yes."));
! 	    PutLine0(elm_LINES-3, elm_COLUMNS-30, 
! 		     catgets(elm_msg_cat, ElmSet, ElmLimitAdding,
! 			     "Adding criteria..."));
  	  } else {
! 	    Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmNoWord, "No."));
! 	    PutLine0(elm_LINES-3, elm_COLUMNS-30, 
! 		     catgets(elm_msg_cat, ElmSet, ElmLimitChanging,
! 			     "Change criteria..."));
  	    selected = 0;
  	  }
  	}
  
  	while(1) {
! 	  PutLine0(elm_LINES-2, 0, prompt);
  	  CleartoEOLN();
  
  	  criteria[0] = '\0';
! 	  if (0 != optionally_enter(criteria, elm_LINES-2, strlen(prompt), 0,
! 				    sizeof criteria))
! 	    return TRUE;
! 
! 	  clear_error();
  	  
  	  if (strlen(criteria) == 0) {
  	    /* no change */
***************
*** 108,118 ****
  	  if (inalias) {
  	    if (equal(first, "?")) {
  	      if (last_selected)
! 	        error(catgets(elm_msg_cat, AliasesSet, AliasesEnterLastSelected,
! 	          "Enter:{\"name\",\"alias\"} [pattern] OR {\"person\",\"group\",\"user\",\"system\"} OR \"all\""));
  	      else
! 	        error(catgets(elm_msg_cat, AliasesSet, AliasesEnterSelected,
! 	          "Enter: {\"name\",\"alias\"} [pattern] OR {\"person\",\"group\",\"user\",\"system\"}"));
  	      continue;
  	    }
  	    else if (equal(first, "all")) {
--- 94,106 ----
  	  if (inalias) {
  	    if (equal(first, "?")) {
  	      if (last_selected)
! 	        lib_error(CATGETS(elm_msg_cat, AliasesSet, 
! 				  AliasesEnterLastSelected,
! 				  "Enter:{\"name\",\"alias\"} [pattern] OR {\"person\",\"group\",\"user\",\"system\"} OR \"all\""));
  	      else
! 	        lib_error(CATGETS(elm_msg_cat, AliasesSet, 
! 				  AliasesEnterSelected,
! 				  "Enter: {\"name\",\"alias\"} [pattern] OR {\"person\",\"group\",\"user\",\"system\"}"));
  	      continue;
  	    }
  	    else if (equal(first, "all")) {
***************
*** 132,139 ****
  	    else if (equal(first, "system"))
  	      selected = limit_alias_selection(SYSTEM, rest, selected);
  	    else {
! 	      error1(catgets(elm_msg_cat, ElmSet, ElmLimitNotValidCriterion,
! 		"\"%s\" not a valid criterion."), first);
  	      continue;
  	    }
  	    break;
--- 120,129 ----
  	    else if (equal(first, "system"))
  	      selected = limit_alias_selection(SYSTEM, rest, selected);
  	    else {
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 				ElmLimitNotValidCriterion,
! 				"\"%s\" not a valid criterion."), 
! 			first);
  	      continue;
  	    }
  	    break;
***************
*** 141,151 ****
  	  else {
  	    if (equal(first, "?")) {
  	      if (last_selected)
! 	        error(catgets(elm_msg_cat, ElmSet, ElmEnterLastSelected,
! 	          "Enter: {\"subject\",\"to\",\"from\"} [pattern] OR \"all\""));
  	      else
! 	        error(catgets(elm_msg_cat, ElmSet, ElmEnterSelected,
! 		  "Enter: {\"subject\",\"to\",\"from\"} [pattern]"));
  	      continue;
  	    }
  	    else if (equal(first, "all")) {
--- 131,141 ----
  	  else {
  	    if (equal(first, "?")) {
  	      if (last_selected)
! 	        lib_error(CATGETS(elm_msg_cat, ElmSet, ElmEnterLastSelected,
! 				  "Enter: {\"subject\",\"to\",\"from\",\"cc\"} [pattern] OR {\"thread\",\"tagged\",\"all\"}"));
  	      else
! 	        lib_error(CATGETS(elm_msg_cat, ElmSet, ElmEnterSelected,
! 				  "Enter: {\"subject\",\"to\",\"from\"} [pattern] OR \"thread\",\"tagged\"}"));
  	      continue;
  	    }
  	    else if (equal(first, "all")) {
***************
*** 152,201 ****
  	      all++;
  	      selected = 0;
  	    }
! 	    else if (equal(first, "subj") || equal(first, "subject"))
! 	      selected = limit_selection(SUBJECT, rest, selected);
! 	    else if (equal(first, "to"))
! 	      selected = limit_selection(TO, rest, selected);
! 	    else if (equal(first, "from"))
! 	      selected = limit_selection(FROM, rest, selected);
  	    else {
! 	      error1(catgets(elm_msg_cat, ElmSet, ElmLimitNotValidCriterion,
! 		"\"%s\" not a valid criterion."), first);
! 	      continue;
  	    }
  	    break;
  	  }
! 	}
  
  	if (all && last_selected)
! 	  strcpy(msg, catgets(elm_msg_cat, ElmSet, ElmLimitReturnToUnlimited,
! 		"Returned to unlimited display."));
  	else {
  	  if (inalias) {
  	    if (selected > 1)
! 	      sprintf(msg, catgets(elm_msg_cat, AliasesSet,
! 		AliasesLimitMessagesSelected, "%d aliases selected."),
! 		selected);
  	    else if (selected == 1)
! 	      strcpy(msg, catgets(elm_msg_cat, AliasesSet,
! 		AliasesLimitMessageSelected, "1 alias selected."));
  	    else
! 	      strcpy(msg, catgets(elm_msg_cat, AliasesSet,
! 		AliasesLimitNoMessagesSelected, "No aliases selected."));
  	  }
  	  else {
  	    if (selected > 1)
! 	      sprintf(msg, catgets(elm_msg_cat, ElmSet,
! 		ElmLimitMessagesSelected, "%d messages selected."), selected);
  	    else if (selected == 1)
! 	      strcpy(msg, catgets(elm_msg_cat, ElmSet, ElmLimitMessageSelected,
! 		"1 message selected."));
  	    else
! 	      strcpy(msg, catgets(elm_msg_cat, ElmSet,
! 		ElmLimitNoMessagesSelected, "No messages selected."));
  	  }
  	}
- 	set_error(msg);
  
  	/* we need a redraw if there had been a selection or there is now. */
  	if (last_selected || selected) {
--- 142,250 ----
  	      all++;
  	      selected = 0;
  	    }
! 	    else if (equal(first, "tagged"))
! 	      selected = SelectTaggedMessages();
  	    else {
! 	      char *c, *p, buf[STRING], buf2[STRING];
! 	      int complx = 0, err = 0, iter = 0;
! 
! 	      if (!selected)
! 		ClearSelection();
! 		
! 	      /* this next bit of code assumes that the input string is a
! 		 list of "and"ed or "or"ed items.  NOTE: it assumes that
! 		 if the first operator is "and", then all operators are "and",
! 		 and vice-versa. */
! 	      strfcpy(buf, first, sizeof buf);
! 	      strfcat(buf, " ", sizeof buf);
! 	      strfcat(buf, rest, sizeof buf);
! 	      p = buf;
! 	      if (index(p, '&') != NULL)
! 		complx = 1;
! 	      while ((c = strtok(p, "|&")) != NULL) {
! 		while (*c && isspace(*c)) ++c;
! 		p = c;
! 		while (*p && !isspace(*p)) ++p;
! 		while (*p && isspace(*p)) ++p;
! 		strfcpy(buf2, p, sizeof buf2);
! 		remove_possible_trailing_spaces(buf2);
! 		if (strncmp(c, "subj", 4) == 0)
! 		  limit_selection(SUBJECT, buf2, selected||(complx&&iter!=0));
! 		else if (strncmp(c, "to", 2) == 0)
! 		  limit_selection(TO, buf2, selected||(complx&&iter!=0));
! 		else if (strncmp(c, "cc", 2) == 0)
! 		  limit_selection(CC, buf2, selected||(complx&&iter!=0));
! 		else if (strncmp(c, "from", 4) == 0)
! 		  limit_selection(FROM, buf2, selected||(complx&&iter!=0));
! 		else if (strncmp(c, "thread", 6) == 0) {
! 		  if (!headers)
! 		    continue;
! 		  strfcpy(ch_s, headers[current-1]->subject, sizeof(ch_s));
! 		  ch_p=&ch_s[0]; while (*ch_p) {
! 		  	*ch_p=(char)tolower(*ch_p); ch_p++;
! 		        }
! 		  if (strncmp(ch_s,"re: ",4) == 0) {
! 		    limit_selection(SUBJECT,ch_s+4,selected||(complx&&iter!=0));
! 		    } else {
! 		    limit_selection(SUBJECT,ch_s, selected||(complx&&iter!=0));
! 		    }
! 		  }
! 		else {
! 		  if ((p = index(c, ' ')) != NULL)
! 		    *p = '\0';
! 		  lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 				    ElmLimitNotValidCriterion,
! 				    "\"%s\" not a valid criterion."), 
! 			    c);
! 		  err = 1;
! 		  break;
! 		}
! 		p = NULL;
! 		++iter;
! 	      }
! 	      if (err)
! 		continue;
! 	      selected = TallySelection();
  	    }
  	    break;
  	  }
!         }
  
  	if (all && last_selected)
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLimitReturnToUnlimited,
! 			    "Returned to unlimited display."));
  	else {
  	  if (inalias) {
  	    if (selected > 1)
! 	      lib_error(CATGETS(elm_msg_cat, AliasesSet,
! 				AliasesLimitMessagesSelected, 
! 				"%d aliases selected."),
! 			selected);
  	    else if (selected == 1)
! 	      lib_error(CATGETS(elm_msg_cat, AliasesSet,
! 				AliasesLimitMessageSelected, 
! 				"1 alias selected."));
  	    else
! 	      lib_error(CATGETS(elm_msg_cat, AliasesSet,
! 				AliasesLimitNoMessagesSelected, 
! 				"No aliases selected."));
  	  }
  	  else {
  	    if (selected > 1)
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet,
! 				ElmLimitMessagesSelected, 
! 				"%d messages selected."), 
! 			selected);
  	    else if (selected == 1)
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 				ElmLimitMessageSelected,
! 				"1 message selected."));
  	    else
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet,
! 				ElmLimitNoMessagesSelected, 
! 				"No messages selected."));
  	  }
  	}
  
  	/* we need a redraw if there had been a selection or there is now. */
  	if (last_selected || selected) {
***************
*** 211,262 ****
  
  int
  limit_selection(based_on, pattern, additional_criteria)
! int based_on, additional_criteria;
! char *pattern;
  {
! 	/** Given the type of criteria, and the pattern, mark all
! 	    non-matching headers as ! VISIBLE.  If additional_criteria,
! 	    don't mark as visible something that isn't currently!
! 	**/
! 
! 	register int iindex;
! 	register char *hdr_value;
! 	int count = 0;
! 
! 	dprint(2, (debugfile, "\n\n\n**limit on %d - '%s' - (%s) **\n\n",
! 		   based_on, pattern, additional_criteria?"add'tl":"base"));
! 
  	for (iindex = 0 ; iindex < message_count ; iindex++) {
  
! 	    switch (based_on) {
! 	    case FROM:
! 		hdr_value = headers[iindex]->from;
! 		break;
! 	    case TO:
! 		hdr_value = headers[iindex]->to;
! 		break;
! 	    case SUBJECT:
! 	    default:
! 		hdr_value = headers[iindex]->subject;
! 		break;
! 	    }
  
! 	    if (!in_string(shift_lower(hdr_value), pattern))
  		headers[iindex]->status &= ~VISIBLE;
- 	    else if (additional_criteria && !(headers[iindex]->status&VISIBLE))
- 		; /* leave this marked not visible */
- 	    else {
- 		headers[iindex]->status |= VISIBLE;
- 		count++;
- 		dprint(5, (debugfile,
- 		    "  Message %d (%s from %s) marked as visible\n",
- 		    iindex, headers[iindex]->subject, headers[iindex]->from));
  	    }
! 
! 	}
! 
! 	dprint(4, (debugfile, "\n** returning %d selected **\n\n\n", count));
! 	return(count);
  }
  
  int
--- 260,300 ----
  
  int
  limit_selection(based_on, pattern, additional_criteria)
!      int based_on, additional_criteria;
!      char *pattern;
  {
! 	int iindex;
! 	
  	for (iindex = 0 ; iindex < message_count ; iindex++) {
+ 	  int match;
  
! 	  switch (based_on) {
  
! 	  case FROM:
! 	    match = from_matches(iindex,pattern);
! 	    break;
! 	  case TO:
! 	    match = to_matches(iindex,pattern);
! 	    break;
! 	  case CC:
! 	    match = cc_matches(iindex,pattern);
! 	    break;
! 	  case SUBJECT:
! 	  default:
! 	    match = subject_matches(iindex,pattern);
! 	    break;
! 	  }
! 
! 	  if (additional_criteria) {
! 	    if (headers[iindex]->status & VISIBLE) {
! 	      if (!match)
  		headers[iindex]->status &= ~VISIBLE;
  	    }
! 	  }
! 	  else if (match)
! 	    headers[iindex]->status |= VISIBLE;
!         }
! 	return 0;
  }
  
  int
***************
*** 438,441 ****
--- 476,510 ----
  	dprint(4, (debugfile, "index %d is NOT displayed!\n", message));
  
  	return(message_count+1);
+ }
+ 
+ void
+ ClearSelection() {
+   int iindex;
+ 
+   for (iindex = 0; iindex < message_count; iindex++)
+     headers[iindex]->status &= ~VISIBLE;
+ }
+ 
+ int
+ TallySelection() {
+   int iindex, count = 0;
+ 
+   for (iindex = 0 ; iindex < message_count ; iindex++)
+     if (headers[iindex]->status & VISIBLE)
+       ++count;
+   return(count);
+ }
+ 
+ int
+ SelectTaggedMessages() {
+   int iindex, count = 0;
+ 
+   for (iindex = 0; iindex < message_count; iindex++)
+     if (headers[iindex]->status & TAGGED) {
+       headers[iindex]->status |= VISIBLE;
+       ++count;
+     } else
+       headers[iindex]->status &= ~VISIBLE;
+   return(count);
  }
Index: elm2.4.ME+.50/src/lock.c
*** elm2.4.25/src/lock.c	Mon May 16 02:02:12 1994
--- elm2.4.ME+.50/src/lock.c	Tue Nov 17 21:12:58 1998
***************
*** 1,92 ****
  
! static char rcsid[] = "@(#)$Id: lock.c,v 5.16 1994/05/15 23:02:12 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.16 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: lock.c,v $
!  * Revision 5.16  1994/05/15  23:02:12  syd
!  * Solaris 2.3 can return EACCES or EEXIST for lockfile already existing.
!  * From: xcea@uxa.ecn.bgu.edu (Chad Adams)
!  *
!  * Revision 5.15  1993/05/31  19:16:24  syd
!  * It looks like there was some earlier patch that re-introduced
!  * some lock problems from the past time of 2.4beta.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.14  1993/04/16  14:13:49  syd
!  * Make it clear errno, some systems arent
!  * From: Syd
!  *
!  * Revision 5.13  1993/04/16  03:58:57  syd
!  * Fix where Solaris 2.0 leaves an error code
!  * yet creates the lock file
!  * From: Syd via pointer from Daniel Bidwell <bidwell@elrond.cs.andrews.edu>
!  *
!  * Revision 5.12  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.11  1993/01/20  03:02:19  syd
!  * Move string declarations to defs.h
!  * From: Syd
!  *
!  * Revision 5.10  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.9  1992/12/07  03:49:49  syd
!  * use BSD or not apollo on file.h include as its not valid
!  * for Apollos under sys5.3 compile type
!  * From: gordonb@mcil.comm.mot.com (Gordon Berkley)
!  *
!  * Revision 5.8  1992/12/07  02:23:35  syd
!  * Always init fcntlerr and flockerr so useage after ifdef code doesnt cause problem
!  * From: Syd via prompt from wdh@grouper.mkt.csd.harris.com (W. David Higgins)
!  *
!  * Revision 5.7  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.6  1992/10/27  01:52:16  syd
!  * Always include <sys/ioctl.h> in curses.c When calling ioctl()
!  *
!  * Remove declaration of getegid() from leavembox.c & lock.c
!  * They aren't even used there.
!  * From: tom@osf.org
!  *
!  * Revision 5.5  1992/10/19  16:50:41  syd
!  * Fix a couple more compiler gripes from SYSVR4
!  * From: Tom Moore <tmoore@wnas.DaytonOH.NCR.COM>
!  *
!  * Revision 5.4  1992/10/17  22:13:50  syd
!  * ci -u src/lock.c < mail/lock.pat.i
!  *
!  * Revision 5.3  1992/10/12  00:25:52  syd
!  * Lock error codes (fcntl vs flock) were backwards
!  * From: howardl@wb3ffv.ampr.org (Howard Leadmon - WB3FFV)
!  *
!  * Revision 5.2  1992/10/11  00:52:11  syd
!  * Switch to wrapper for flock and fcntl locking.
!  * Change order to fcntl first, other order blocked.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** leave current folder, updating etc. as needed...
    
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: lock.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** leave current folder, updating etc. as needed...
    
***************
*** 106,132 ****
  #endif
  
  #ifdef SYSCALL_LOCKING
! #  if (defined(BSD) || !defined(apollo))
  #    include <sys/file.h>
  #  endif
  #endif
  #include <errno.h>
- #ifdef I_TIME
- #  include <time.h>
- #endif
- #ifdef I_SYSTIME
- #  include <sys/time.h>
- #endif
  
- 
  extern int errno;
  
  char *error_description();
  
- #define	FLOCKING_OK	0
- #define	FLOCKING_RETRY	1
- #define	FLOCKING_FAIL	-1
- 
  extern char *mk_lockname();
  
  static int  lock_state = OFF;
--- 30,45 ----
  #endif
  
  #ifdef SYSCALL_LOCKING
! #  if (defined(BSD_TYPE) || !defined(apollo))
  #    include <sys/file.h>
  #  endif
  #endif
  #include <errno.h>
  
  extern int errno;
  
  char *error_description();
  
  extern char *mk_lockname();
  
  static int  lock_state = OFF;
***************
*** 142,150 ****
  static struct flock lock_info;
  #endif
  
! int
! Grab_the_file(flock_fd)
! int flock_fd;
  {
      int	retcode	= FLOCKING_OK;
  
--- 55,62 ----
  static struct flock lock_info;
  #endif
  
! int Grab_the_file(flock_fd)
!      int flock_fd;
  {
      int	retcode	= FLOCKING_OK;
  
***************
*** 190,198 ****
      return FLOCKING_OK;
  }
  
! int
! Release_the_file(flock_fd)
! int flock_fd;
  {
      int	fcntlret = 0,
  	flockret = 0,
--- 102,109 ----
      return FLOCKING_OK;
  }
  
! int Release_the_file(flock_fd)
!      int flock_fd;
  {
      int	fcntlret = 0,
  	flockret = 0,
***************
*** 275,287 ****
  	    if (kill_status != 0 && errno != EPERM) {
  	      close(create_fd);
  	      if (unlink(lockfile) != 0) {
! 	        MoveCursor(LINES, 0);
  		Raw(OFF);
  		dprint(1, (debugfile,
  		  "Error %s\n\ttrying to unlink file %s (%s)\n", 
  		  error_description(errno), lockfile, "lock"));
! 		printf(catgets(elm_msg_cat, ElmSet, ElmLeaveCouldntRemoveCurLock,
! 		  "\nCouldn't remove the current lock file %s\n"), lockfile);
  		printf("** %s **\n", error_description(errno));
  #ifdef SAVE_GROUP_MAILBOX_ID
  		setgid(groupid);
--- 186,200 ----
  	    if (kill_status != 0 && errno != EPERM) {
  	      close(create_fd);
  	      if (unlink(lockfile) != 0) {
! 	        MoveCursor(elm_LINES, 0);
  		Raw(OFF);
  		dprint(1, (debugfile,
  		  "Error %s\n\ttrying to unlink file %s (%s)\n", 
  		  error_description(errno), lockfile, "lock"));
! 		lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 				  ElmLeaveCouldntRemoveCurLock,
! 				  "\nCouldn't remove the current lock file %s\n"), 
! 			  lockfile);
  		printf("** %s **\n", error_description(errno));
  #ifdef SAVE_GROUP_MAILBOX_ID
  		setgid(groupid);
***************
*** 289,295 ****
  		if (direction == INCOMING)
  		  leave(0);
  		else
! 		  emergency_exit();
  	      }
  	    }
  	  }
--- 202,208 ----
  		if (direction == INCOMING)
  		  leave(0);
  		else
! 		  emergency_exit(0);
  	      }
  	    }
  	  }
***************
*** 310,332 ****
              /* If /var/mail nfs mounted on Solaris 2.3 at least you can */
  	    /* get EACCES.  Treat it like EEXIST. */
  
! 	    MoveCursor(LINES, 0);
  	    Raw(OFF);
  	    if (direction == OUTGOING) {
  	      dprint(1, (debugfile, 
  		"Error encountered attempting to create lock %s\n", lockfile));
  	      dprint(1, (debugfile, "** %s **\n", error_description(errno)));
! 	      printf(catgets(elm_msg_cat, ElmSet, ElmLeaveErrorCreatingLock,
! 	   "\nError encountered while attempting to create lock file %s;\n"),
! 		lockfile);
! 	      printf("** %s.**\n\n", error_description(errno));
  	    } else {	/* incoming - permission denied in the middle?  Odd. */
  	      dprint(1, (debugfile,
  	       "Can't create lock file: creat(%s) raises error %s (lock)\n", 
  		lockfile, error_description(errno)));
! 	      printf(catgets(elm_msg_cat, ElmSet, ElmLeaveCantCreateLock,
! 	       "Can't create lock file! Need write permission in \"%s\".\n"),
! 		mailhome);
  	    }
  #ifdef SAVE_GROUP_MAILBOX_ID
  	    setgid(groupid);
--- 223,246 ----
              /* If /var/mail nfs mounted on Solaris 2.3 at least you can */
  	    /* get EACCES.  Treat it like EEXIST. */
  
! 	    MoveCursor(elm_LINES, 0);
  	    Raw(OFF);
  	    if (direction == OUTGOING) {
  	      dprint(1, (debugfile, 
  		"Error encountered attempting to create lock %s\n", lockfile));
  	      dprint(1, (debugfile, "** %s **\n", error_description(errno)));
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveErrorCreatingLock,
! 				"\nError encountered while attempting to create lock file %s;\n"),
! 			lockfile);
! 	      lib_error(FRM("** %s.**\n\n"), 
! 			error_description(errno));
  	    } else {	/* incoming - permission denied in the middle?  Odd. */
  	      dprint(1, (debugfile,
  	       "Can't create lock file: creat(%s) raises error %s (lock)\n", 
  		lockfile, error_description(errno)));
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveCantCreateLock,
! 				"Can't create lock file! Need write permission in \"%s\".\n"),
! 			mailhome);
  	    }
  #ifdef SAVE_GROUP_MAILBOX_ID
  	    setgid(groupid);
***************
*** 336,344 ****
  	}
  	dprint(2, (debugfile,"File '%s' already exists!  Waiting...(lock)\n", 
  	  lockfile));
! 	error1(catgets(elm_msg_cat, ElmSet, ElmLeaveWaitingToRead,
! 	  "Waiting to read mailbox while mail is being received: attempt #%d"),
! 	  create_iteration);
  	sleep(5);
        } while (create_iteration++ < MAX_ATTEMPTS);
        clear_error();
--- 250,258 ----
  	}
  	dprint(2, (debugfile,"File '%s' already exists!  Waiting...(lock)\n", 
  	  lockfile));
! 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveWaitingToRead,
! 			  "Waiting to read mailbox while mail is being received: attempt #%d"),
! 		  create_iteration);
  	sleep(5);
        } while (create_iteration++ < MAX_ATTEMPTS);
        clear_error();
***************
*** 355,375 ****
  	dprint(2, (debugfile, 
  	   "Warning: I'm giving up waiting - removing lock file(lock)\n"));
  	if (direction == INCOMING)
! 	  PutLine0(LINES, 0, catgets(elm_msg_cat, ElmSet, ElmLeaveTimedOutRemoving,
  		"\nTimed out - removing current lock file..."));
  	else
! 	  error(catgets(elm_msg_cat, ElmSet, ElmLeaveThrowingAwayLock,
! 		"Throwing away the current lock file!"));
  
  	if (unlink(lockfile) != 0) {
! 	  MoveCursor(LINES, 0);
  	  Raw(OFF);
  	  dprint(1, (debugfile,
  	    "Error %s\n\ttrying to unlink file %s (%s)\n", 
  	    error_description(errno), lockfile, "lock"));
! 	  printf(catgets(elm_msg_cat, ElmSet, ElmLeaveCouldntRemoveCurLock,
! 	    "\nCouldn't remove the current lock file %s\n"), lockfile);
! 	  printf("** %s **\n", error_description(errno));
  #ifdef SAVE_GROUP_MAILBOX_ID
  	  setgid(groupid);
  #endif
--- 269,290 ----
  	dprint(2, (debugfile, 
  	   "Warning: I'm giving up waiting - removing lock file(lock)\n"));
  	if (direction == INCOMING)
! 	  PutLine0(elm_LINES, 0, catgets(elm_msg_cat, ElmSet, ElmLeaveTimedOutRemoving,
  		"\nTimed out - removing current lock file..."));
  	else
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveThrowingAwayLock,
! 			    "Throwing away the current lock file!"));
  
  	if (unlink(lockfile) != 0) {
! 	  MoveCursor(elm_LINES, 0);
  	  Raw(OFF);
  	  dprint(1, (debugfile,
  	    "Error %s\n\ttrying to unlink file %s (%s)\n", 
  	    error_description(errno), lockfile, "lock"));
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveCouldntRemoveCurLock,
! 			    "\nCouldn't remove the current lock file %s\n"), lockfile);
! 	  lib_error(FRM("** %s **\n"), 
! 		    error_description(errno));
  #ifdef SAVE_GROUP_MAILBOX_ID
  	  setgid(groupid);
  #endif
***************
*** 376,382 ****
  	  if (direction == INCOMING)
  	    leave(0);
  	  else
! 	    emergency_exit();
  	}
  
  	/* we've removed the bad lock, let's try to assert lock once more */
--- 291,297 ----
  	  if (direction == INCOMING)
  	    leave(0);
  	  else
! 	    emergency_exit(0);
  	}
  
  	/* we've removed the bad lock, let's try to assert lock once more */
***************
*** 386,397 ****
  	  dprint(1, (debugfile, 
  	    "Error encountered attempting to create lock %s\n", lockfile));
  	  dprint(1, (debugfile, "** %s **\n", error_description(errno)));
! 	  MoveCursor(LINES, 0);
  	  Raw(OFF);
! 	  printf(catgets(elm_msg_cat, ElmSet, ElmLeaveErrorCreatingLock,
! 	  "\nError encountered while attempting to create lock file %s;\n"),
! 	    lockfile);
! 	  printf("** %s. **\n\n", error_description(errno));
  #ifdef SAVE_GROUP_MAILBOX_ID
  	  setgid(groupid);
  #endif
--- 301,313 ----
  	  dprint(1, (debugfile, 
  	    "Error encountered attempting to create lock %s\n", lockfile));
  	  dprint(1, (debugfile, "** %s **\n", error_description(errno)));
! 	  MoveCursor(elm_LINES, 0);
  	  Raw(OFF);
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveErrorCreatingLock,
! 			    "\nError encountered while attempting to create lock file %s;\n"),
! 		    lockfile);
! 	  lib_error(FRM("** %s. **\n\n"), 
! 		    error_description(errno));
  #ifdef SAVE_GROUP_MAILBOX_ID
  	  setgid(groupid);
  #endif
***************
*** 401,414 ****
  	/* Okay...we die and leave, not updating the mailfile mbox or
  	   any of those! */
  
! 	MoveCursor(LINES, 0);
  	Raw(OFF);
  	if (direction == INCOMING) {
! 	  printf(catgets(elm_msg_cat, ElmSet, ElmLeaveGivingUp,
! 		"\n\nGiving up after %d iterations.\n"), 
! 	    create_iteration);
! 	  printf(catgets(elm_msg_cat, ElmSet, ElmLeavePleaseTryAgain,
! 	  "\nPlease try to read your mail again in a few minutes.\n\n"));
  	  dprint(1, (debugfile, 
  	    "Warning: bailing out after %d iterations...(lock)\n",
  	    create_iteration));
--- 317,330 ----
  	/* Okay...we die and leave, not updating the mailfile mbox or
  	   any of those! */
  
! 	MoveCursor(elm_LINES, 0);
  	Raw(OFF);
  	if (direction == INCOMING) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveGivingUp,
! 			    "\n\nGiving up after %d iterations.\n"), 
! 		    create_iteration);
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeavePleaseTryAgain,
! 			    "\nPlease try to read your mail again in a few minutes.\n\n"));
  	  dprint(1, (debugfile, 
  	    "Warning: bailing out after %d iterations...(lock)\n",
  	    create_iteration));
***************
*** 423,430 ****
  #ifdef SAVE_GROUP_MAILBOX_ID
  	  setgid(groupid);
  #endif
! 	  printf(catgets(elm_msg_cat, ElmSet, ElmLeaveErrorTimedOutLock,
! 		"Timed out on locking mailbox.  Leaving program.\n"));
  	  leave(0);
  	}
  #endif
--- 339,346 ----
  #ifdef SAVE_GROUP_MAILBOX_ID
  	  setgid(groupid);
  #endif
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveErrorTimedOutLock,
! 			    "Timed out on locking mailbox.  Leaving program.\n"));
  	  leave(0);
  	}
  #endif
***************
*** 436,442 ****
  	(direction == INCOMING ? "incoming" : "outgoing"), cur_folder));
  
        /* Place the pid of Elm into the lock file for SVR3.2 and its ilk */
!       sprintf(pid_buffer, "%d", getpid());
        write(create_fd, pid_buffer, strlen(pid_buffer));
  
        (void)close(create_fd);
--- 352,360 ----
  	(direction == INCOMING ? "incoming" : "outgoing"), cur_folder));
  
        /* Place the pid of Elm into the lock file for SVR3.2 and its ilk */
!       elm_sfprintf(pid_buffer, sizeof pid_buffer,
! 		   FRM("%d"), 
! 		   getpid());
        write(create_fd, pid_buffer, strlen(pid_buffer));
  
        (void)close(create_fd);
***************
*** 453,464 ****
  	dprint(1, (debugfile, 
  	    "Error encountered attempting to reopen %s for lock\n", cur_folder));
  	dprint(1, (debugfile, "** %s **\n", error_description(errno)));
! 	MoveCursor(LINES, 0);
  	Raw(OFF);
! 	printf(catgets(elm_msg_cat, ElmSet, ElmLeaveErrorReopenMailbox,
!  "\nError encountered while attempting to reopen mailbox %s for lock;\n"), 
! 	      cur_folder);
! 	printf("** %s. **\n\n", error_description(errno));
  #ifdef	USE_DOTLOCK_LOCKING
  	(void)unlink(lockfile);
  #endif /* USE_DOTLOCK_LOCKING */
--- 371,383 ----
  	dprint(1, (debugfile, 
  	    "Error encountered attempting to reopen %s for lock\n", cur_folder));
  	dprint(1, (debugfile, "** %s **\n", error_description(errno)));
! 	MoveCursor(elm_LINES, 0);
  	Raw(OFF);
! 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveErrorReopenMailbox,
! 			  "\nError encountered while attempting to reopen mailbox %s for lock;\n"), 
! 		  cur_folder);
! 	lib_error(FRM("** %s. **\n\n"), 
! 		  error_description(errno));
  #ifdef	USE_DOTLOCK_LOCKING
  	(void)unlink(lockfile);
  #endif /* USE_DOTLOCK_LOCKING */
***************
*** 483,494 ****
  			"Error encountered attempting to flock %s\n",
  			cur_folder));
  	    dprint (1, (debugfile, "** %s **\n", error_description(errno)));
! 	    MoveCursor(LINES, 0);
  	    Raw(OFF);
! 	    printf (catgets(elm_msg_cat, ElmSet, ElmLeaveErrorFlockMailbox,
! 	 "\nError encountered while attempting to flock mailbox %s;\n"), 
! 		  cur_folder);
! 	    printf("** %s. **\n\n", error_description(errno));
  #ifdef	USE_DOTLOCK_LOCKING
  	    (void)unlink(lockfile);
  #endif /* USE_DOTLOCK_LOCKING */
--- 402,414 ----
  			"Error encountered attempting to flock %s\n",
  			cur_folder));
  	    dprint (1, (debugfile, "** %s **\n", error_description(errno)));
! 	    MoveCursor(elm_LINES, 0);
  	    Raw(OFF);
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveErrorFlockMailbox,
! 			      "\nError encountered while attempting to flock mailbox %s;\n"), 
! 		      cur_folder);
! 	    lib_error(FRM("** %s. **\n\n"), 
! 		      error_description(errno));
  #ifdef	USE_DOTLOCK_LOCKING
  	    (void)unlink(lockfile);
  #endif /* USE_DOTLOCK_LOCKING */
***************
*** 500,508 ****
  	default:
  	    dprint (2, (debugfile,
  	      "Mailbox '%s' already locked!  Waiting...(lock)\n", cur_folder));
! 	    error1 (catgets(elm_msg_cat, ElmSet, ElmLeaveWaitingToRead,
! 			   "Waiting to read mailbox while mail is being received: attempt #%d"),
! 		    flock_iteration);
  	    sleep(5);
  	}
        } while (flock_iteration++ < MAX_ATTEMPTS);
--- 420,428 ----
  	default:
  	    dprint (2, (debugfile,
  	      "Mailbox '%s' already locked!  Waiting...(lock)\n", cur_folder));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveWaitingToRead,
! 			      "Waiting to read mailbox while mail is being received: attempt #%d"),
! 		      flock_iteration);
  	    sleep(5);
  	}
        } while (flock_iteration++ < MAX_ATTEMPTS);
***************
*** 512,531 ****
  
        if(errno != 0) {
  
! 	MoveCursor(LINES, 0);
  	Raw(OFF);
  	/* We couldn't lock the file. We die and leave not updating
  	 * the mailfile mbox or any of those! */
  
  	if (direction == INCOMING) {
! 	  printf(catgets(elm_msg_cat, ElmSet, ElmLeaveGivingUp,
! 		"\n\nGiving up after %d iterations.\n"), 
! 	    flock_iteration);
! 	  printf(catgets(elm_msg_cat, ElmSet, ElmLeavePleaseTryAgain,
! 	  "\nPlease try to read your mail again in a few minutes.\n\n"));
  	  dprint(1, (debugfile, 
  	    "Warning: bailing out after %d iterations...(lock)\n",
! 	    flock_iteration));
  	} else {
  	  dprint(1, (debugfile, 
  	   "Warning: after %d iterations, timed out! (lock)\n",
--- 432,451 ----
  
        if(errno != 0) {
  
! 	MoveCursor(elm_LINES, 0);
  	Raw(OFF);
  	/* We couldn't lock the file. We die and leave not updating
  	 * the mailfile mbox or any of those! */
  
  	if (direction == INCOMING) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveGivingUp,
! 			    "\n\nGiving up after %d iterations.\n"), 
! 		    flock_iteration);
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeavePleaseTryAgain,
! 			    "\nPlease try to read your mail again in a few minutes.\n\n"));
  	  dprint(1, (debugfile, 
  	    "Warning: bailing out after %d iterations...(lock)\n",
! 		     flock_iteration));
  	} else {
  	  dprint(1, (debugfile, 
  	   "Warning: after %d iterations, timed out! (lock)\n",
***************
*** 534,540 ****
  #ifdef	USE_DOTLOCK_LOCKING
  	(void)unlink(lockfile);
  #endif
! 	printf(catgets(elm_msg_cat, ElmSet, ElmLeaveErrorTimedOutLock,
  		"Timed out on locking mailbox.  Leaving program.\n"));
  	leave(0);
        }
--- 454,460 ----
  #ifdef	USE_DOTLOCK_LOCKING
  	(void)unlink(lockfile);
  #endif
! 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLeaveErrorTimedOutLock,
  		"Timed out on locking mailbox.  Leaving program.\n"));
  	leave(0);
        }
***************
*** 553,559 ****
  }
  
  int
! unlock()
  {
  	/** Remove the lock file!    This must be part of the interrupt
  	    processing routine to ensure that the lock file is NEVER
--- 473,494 ----
  }
  
  int
! flush_mailfile()
! {
! 	if (!mailfile)
! 		return(0);
! #ifdef ultrix
! 	/** Ultrix returns an error if fflush is called on a file opened
! 	    for read only, so we have to account for this.
! 	**/
! 
! 	if ((mailfile->_flag & (_IOREAD|_IORW)) == _IOREAD)
! 		return(0);
! #endif
! 	return(fflush(mailfile));
! }
! 
! int unlock(int interrupt)
  {
  	/** Remove the lock file!    This must be part of the interrupt
  	    processing routine to ensure that the lock file is NEVER
***************
*** 564,569 ****
--- 499,512 ----
  
  	int retcode = 0;
  
+ 	/* If interrupt is set, avoid calling no-reentrant routines ... */
+ 
+ 	/** Flush the mailfile buffer if necessary before removing the lock.
+ 	**/
+ 
+ 	if (mailfile && !interrupt)
+ 		flush_mailfile();
+ 
  #ifndef USE_DOTLOCK_LOCKING
  	dprint(5,
  	  (debugfile, "Lock (no .lock) for file %s %s off.\n",
***************
*** 591,600 ****
  	      "Error %s\n\ttrying to force unlock file %s via close() (%s)\n", 
  				error_description(errno),
  				cur_folder, "unlock"));
! 		    error1 (catgets (elm_msg_cat, ElmSet,
! 				     ElmLeaveCouldntUnlockOwnMailbox,
! 				     "Couldn't unlock my own mailbox %s!"),
! 				     cur_folder);
  		    return(retcode);
  		}
  	    }
--- 534,544 ----
  	      "Error %s\n\ttrying to force unlock file %s via close() (%s)\n", 
  				error_description(errno),
  				cur_folder, "unlock"));
! 		    if (!interrupt)
! 		    lib_error (CATGETS (elm_msg_cat, ElmSet,
! 					ElmLeaveCouldntUnlockOwnMailbox,
! 					"Couldn't unlock my own mailbox %s!"),
! 			       cur_folder);
  		    return(retcode);
  		}
  	    }
***************
*** 613,620 ****
  	    dprint(1, (debugfile,
  	      "Error %s\n\ttrying to unlink file %s (%s)\n", 
  	      error_description(errno), lockfile,"unlock"));
! 	      error1(catgets(elm_msg_cat, ElmSet, ElmLeaveCouldntRemoveOwnLock,
! 		"Couldn't remove my own lock file %s!"), lockfile);
  	  }
  #ifdef SAVE_GROUP_MAILBOX_ID
  	  setgid(groupid);
--- 557,567 ----
  	    dprint(1, (debugfile,
  	      "Error %s\n\ttrying to unlink file %s (%s)\n", 
  	      error_description(errno), lockfile,"unlock"));
! 	    if (!interrupt)
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 				ElmLeaveCouldntRemoveOwnLock,
! 				"Couldn't remove my own lock file %s!"), 
! 			lockfile);
  	  }
  #ifdef SAVE_GROUP_MAILBOX_ID
  	  setgid(groupid);
Index: elm2.4.ME+.50/src/mailmsg1.c
*** elm2.4.25/src/mailmsg1.c	Tue Jul 20 05:46:14 1993
--- elm2.4.ME+.50/src/mailmsg1.c	Tue Nov 17 21:12:58 1998
***************
*** 1,53 ****
  
! static char rcsid[] = "@(#)$Id: mailmsg1.c,v 5.7 1993/07/20 02:46:14 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.7 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: mailmsg1.c,v $
!  * Revision 5.7  1993/07/20  02:46:14  syd
!  * Handle reply-to in batch mode.
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.6  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.5  1993/04/12  02:34:36  syd
!  * I have now added a parameter which controls whether want_to clears the
!  * line and centers the question or behaves like it did before. I also
!  * added a 0 at the end of the parameter list to all the other calls to
!  * want_to where a centered question on a clean line is not desirable.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.4  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.3  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.2  1992/12/20  05:15:58  syd
!  * Add a c)hange alias, -u and -t options to listalias to list only user
!  * and only system aliases respectively.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** Interface to allow mail to be sent to users.  Part of ELM  **/
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: mailmsg1.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** Interface to allow mail to be sent to users.  Part of ELM  **/
  
***************
*** 54,59 ****
--- 17,23 ----
  
  #include "headers.h"
  #include "s_elm.h"
+ #include "me.h"
  
  /** strings defined for the hdrconfg routines **/
  
***************
*** 105,122 ****
  
  	if (mail_only)
  	  if (strlen(newaddress) > 80) 
! 	    PutLine1(to_line, to_col, "To: (%s)", 
! 	       tail_of_string(newaddress, 60));
  	  else
! 	    PutLine1(to_line, to_col, "To: %s", newaddress);
  	else if (strlen(newaddress) > 50) 
! 	   PutLine1(to_line, to_col, "To: (%s)", 
! 	       tail_of_string(newaddress, 40));
  	 else {
  	   if (strlen(newaddress) > 30)
! 	     PutLine1(to_line, to_col, "To: %s", newaddress);
  	   else
! 	     PutLine1(to_line, to_col, "          To: %s", newaddress);
  	   CleartoEOLN();
  	 }
  
--- 69,95 ----
  
  	if (mail_only)
  	  if (strlen(newaddress) > 80) 
! 	    PutLineX(to_line, to_col, 
! 		     CATGETS(elm_msg_cat, ElmSet, ElmToParen, "To: (%s)"), 
! 		     tail_of_string(newaddress, 60));
  	  else
! 	    PutLineX(to_line, to_col, 
! 		     CATGETS(elm_msg_cat, ElmSet, ElmToNoParen, "To: %s"), 
! 		     newaddress);
  	else if (strlen(newaddress) > 50) 
! 	   PutLineX(to_line, to_col, 
! 		    CATGETS(elm_msg_cat, ElmSet, ElmToParen, "To: (%s)"), 
! 		    tail_of_string(newaddress, 40));
  	 else {
  	   if (strlen(newaddress) > 30)
! 	     PutLineX(to_line, to_col, 
! 		      CATGETS(elm_msg_cat, ElmSet, ElmToNoParen, "To: %s"), 
! 		      newaddress);
  	   else
! 	     PutLineX(to_line, to_col, 
! 		      CATGETS(elm_msg_cat, ElmSet, ElmToNoParen2, 
! 			      "          To: %s"), 
! 		      newaddress);
  	   CleartoEOLN();
  	 }
  
***************
*** 132,139 ****
  	 **/
  	register int open_paren;
  
! 	to_line = mail_only ? 3 : LINES - 3;
! 	to_col = mail_only ? 0 : COLUMNS - 50;
  	if (names_only)
  	  if ((open_paren = chloc(address, '(')) > 0) {
  	    if (open_paren < chloc(address, ')')) {
--- 105,112 ----
  	 **/
  	register int open_paren;
  
! 	to_line = mail_only ? 3 : elm_LINES - 3;
! 	to_col = mail_only ? 0 : elm_COLUMNS - 50;
  	if (names_only)
  	  if ((open_paren = chloc(address, '(')) > 0) {
  	    if (open_paren < chloc(address, ')')) {
***************
*** 143,167 ****
  	  }
  	if(mail_only)
  	  if(strlen(address) > 80)
! 	    PutLine1(to_line, to_col, "To: (%s)", 
! 	        tail_of_string(address, 75));
  	  else
! 	    PutLine1(to_line, to_col, "To: %s", address);
  	else if (strlen(address) > 45) 
! 	  PutLine1(to_line, to_col, "To: (%s)", 
! 	      tail_of_string(address, 40));
  	else {
  	  if (strlen(address) > 30) 
! 	    PutLine1(to_line, to_col, "To: %s", address);
  	  else
! 	    PutLine1(to_line, to_col, "          To: %s", address);
  	  CleartoEOLN();
  	}
  }
  
! int
! get_to(to_field, address)
! char *to_field, *address;
  {
  	/** prompt for the "To:" field, expanding into address if possible.
  	    This routine returns ZERO if errored, or non-zero if okay **/
--- 116,149 ----
  	  }
  	if(mail_only)
  	  if(strlen(address) > 80)
! 	    PutLineX(to_line, to_col, 
! 		     CATGETS(elm_msg_cat, ElmSet, ElmToParen, "To: (%s)"), 
! 		     tail_of_string(address, 75));
  	  else
! 	    PutLineX(to_line, to_col, 
! 		     CATGETS(elm_msg_cat, ElmSet, ElmToNoParen, "To: %s"), 
! 		     address);
  	else if (strlen(address) > 45) 
! 	  PutLineX(to_line, to_col, 
! 		   CATGETS(elm_msg_cat, ElmSet, ElmToParen, "To: (%s)"), 
! 		   tail_of_string(address, 40));
  	else {
  	  if (strlen(address) > 30) 
! 	    PutLineX(to_line, to_col, 
! 		     CATGETS(elm_msg_cat, ElmSet, ElmToNoParen, "To: %s"), 
! 		     address);
  	  else
! 	    PutLineX(to_line, to_col, 
! 		     CATGETS(elm_msg_cat, ElmSet, ElmToNoParen2, 
! 			     "          To: %s"), 
! 		     address);
  	  CleartoEOLN();
  	}
  }
  
! int get_to(to_field, address, to_field_size, address_size)
!      char *to_field, *address;
!      int to_field_size, address_size;
  {
  	/** prompt for the "To:" field, expanding into address if possible.
  	    This routine returns ZERO if errored, or non-zero if okay **/
***************
*** 168,194 ****
  
  	if (strlen(to_field) == 0) {
  	  if (user_level < 2) {
! 	    PutLine0(LINES-2, 0, catgets(elm_msg_cat, ElmSet, ElmSendTheMessageTo,
! 		"Send the message to: "));
! 	    (void) optionally_enter(to_field, LINES-2, 21, FALSE, FALSE); 
  	  }
  	  else {
! 	    PutLine0(LINES-2, 0, catgets(elm_msg_cat, ElmSet, ElmTo, "To: "));
! 	    (void) optionally_enter(to_field, LINES-2, 4, FALSE, FALSE); 
  	  }
  	  if (strlen(to_field) == 0) {
! 	    ClearLine(LINES-2);	
  	    return(0);
  	  }
! 	  (void) build_address(strip_commas(to_field), address); 
  	}
  	else if (mail_only) 
! 	  (void) build_address(strip_commas(to_field), address); 
  	else 
! 	  strcpy(address, to_field);
  	
  	if (strlen(address) == 0) {	/* bad address!  Removed!! */
! 	  ClearLine(LINES-2);
  	  return(0);
  	}
  
--- 150,203 ----
  
  	if (strlen(to_field) == 0) {
  	  if (user_level < 2) {
! 	    int code;
! 	    PutLine0(elm_LINES-2, 0, 
! 		     catgets(elm_msg_cat, ElmSet, ElmSendTheMessageTo,
! 			     "Send the message to: "));
! 	    code = optionally_enter(to_field, elm_LINES-2, 21, 
! 				    OE_REDRAW_MARK, to_field_size); 
! 	    while (REDRAW_MARK == code) {
! 	      PutLine0(elm_LINES-2, 0, 
! 		       catgets(elm_msg_cat, ElmSet, ElmSendTheMessageTo,
! 			       "Send the message to: "));
! 	      code = optionally_enter(to_field, elm_LINES-2, 21, 
! 				      OE_REDRAW_MARK|OE_APPEND_CURRENT,
! 				      to_field_size); 
! 	    }
! 	    if (0 != code)
! 	      return 0;
  	  }
  	  else {
! 	    int code;
! 	    PutLine0(elm_LINES-2, 0, 
! 		     catgets(elm_msg_cat, ElmSet, ElmTo, "To: "));
! 	    code = optionally_enter(to_field, elm_LINES-2, 4, OE_REDRAW_MARK,
! 				    to_field_size); 
! 	    while (code == REDRAW_MARK) {
! 	      PutLine0(elm_LINES-2, 0, 
! 		       catgets(elm_msg_cat, ElmSet, ElmTo, "To: "));
! 	      code = optionally_enter(to_field, elm_LINES-2, 4, 
! 				      OE_REDRAW_MARK|OE_APPEND_CURRENT,
! 				      to_field_size); 
! 	      if (0 != code)
! 		return 0;
! 	    }
  	  }
  	  if (strlen(to_field) == 0) {
! 	    ClearLine(elm_LINES-2);	
  	    return(0);
  	  }
! 	  (void) build_address(strip_commas(to_field), address,
! 			       to_field_size, address_size); 
  	}
  	else if (mail_only) 
! 	  (void) build_address(strip_commas(to_field), address,
! 			       to_field_size, address_size); 
  	else 
! 	  strfcpy(address, to_field, address_size);
  	
  	if (strlen(address) == 0) {	/* bad address!  Removed!! */
! 	  ClearLine(elm_LINES-2);
  	  return(0);
  	}
  
***************
*** 195,204 ****
  	return(1);		/* everything is okay... */
  }
  
! int
! send_msg(given_to, given_cc, given_subject, edit_message, form_letter, replying)
! char *given_to, *given_cc, *given_subject;
! int   edit_message, form_letter, replying;
  {
  	/** Prompt for fields and then call mail() to send the specified
  	    message.  If 'edit_message' is true then don't allow the
--- 204,216 ----
  	return(1);		/* everything is okay... */
  }
  
! static int get_copies  P_((char *, char *, char *, int, int, int));
! static int get_subject P_((char *, int));
! 
! 
! int send_msg(given_to, given_cc, given_subject, options, form_letter)
!      char *given_to, *given_cc, *given_subject;
!      int   options, form_letter;
  {
  	/** Prompt for fields and then call mail() to send the specified
  	    message.  If 'edit_message' is true then don't allow the
***************
*** 213,218 ****
--- 225,235 ----
  	int  copy_msg = FALSE, is_a_response = FALSE;
  	char *p;
  
+ 	struct header_rec * current_header = NULL;
+       
+ 	if (0 != (options & (MAIL_REPLYING|MAIL_FORWARDING))) 
+ 	  current_header = headers[current-1];
+ 
  	/* First: zero all current global message strings */
  
  	cc[0] = bcc[0] = reply_to[0] = expires[0] = '\0';
***************
*** 222,272 ****
  
  	/* Then: fill in default values for some fields */
  
! 	strcpy(subject, given_subject);
! 	strcpy(to, given_to);
! 	strcpy(cc, given_cc);
  
  	if ((p = getenv("REPLYTO")) != NULL)
! 	  strcpy(reply_to, p);
  
  	/******* And now the real stuff! *******/
  
  	/* copy msg into edit buffer? */
! 	copy_msg = copy_the_msg(&is_a_response);
  
  	/* get the To: address and expand */
! 	if (! get_to(to, expanded_to))
  	  return(0);
  
  	/* expand the Cc: address */
  	if (cc[0])
! 	  build_address(strip_commas(cc), expanded_cc);
  
  	/* expand the Reply-To: address */
  	if (reply_to[0])
! 	  build_address(strip_commas(reply_to), expanded_reply_to);
  
  	/** if we're batchmailing, let's send it and GET OUTTA HERE! **/
  
  	if (batch_only) {
! 	  return(mail(FALSE, FALSE, form_letter));
  	}
  
  	display_to(expanded_to);	/* display the To: field on screen... */
  
! 	if (get_subject(subject) == 0)	    /* get the Subject: field */
  	  return(0);
  
  	if (prompt_for_cc) {
! 	  if (get_copies(cc, expanded_to, expanded_cc, copy_msg) == 0)
  	    return(0);
  	}
  
! 	MoveCursor(LINES,0);	/* so you know you've hit <return> ! */
  
  	/** generate the In-Reply-To: header... **/
  
! 	if (is_a_response && replying)
  	  generate_reply_to(current-1);
  
  	/* and mail that puppy outta here! */
--- 239,303 ----
  
  	/* Then: fill in default values for some fields */
  
! 	strfcpy(subject, given_subject, sizeof subject);
! 	strfcpy(to, given_to, sizeof to);
! 	strfcpy(cc, given_cc, sizeof cc);
  
  	if ((p = getenv("REPLYTO")) != NULL)
! 	  strfcpy(reply_to, p, sizeof reply_to);
  
+         /* auto bcc line */
+         if ((p = getenv("BCC")) != NULL)
+           strfcpy(bcc, p, sizeof bcc);
+ 
  	/******* And now the real stuff! *******/
  
  	/* copy msg into edit buffer? */
! 	copy_msg = copy_the_msg(&is_a_response, options);
! 	if (copy_msg) options |= MAIL_COPY_MSG;
  
  	/* get the To: address and expand */
! 	if (! get_to(to, expanded_to, sizeof to, sizeof expanded_to))
  	  return(0);
  
  	/* expand the Cc: address */
  	if (cc[0])
! 	  build_address(strip_commas(cc), expanded_cc,
! 			sizeof cc, sizeof expanded_cc);
  
  	/* expand the Reply-To: address */
  	if (reply_to[0])
! 	  build_address(strip_commas(reply_to), expanded_reply_to,
! 			sizeof reply_to, sizeof expanded_reply_to);
! 
! 	/* expand the bcc address */
! 	if (bcc[0])
! 	  build_address(strip_commas(bcc), expanded_bcc,
! 			sizeof bcc, sizeof expanded_bcc);
  
  	/** if we're batchmailing, let's send it and GET OUTTA HERE! **/
  
  	if (batch_only) {
! 	  return(mail(NULL, 0, form_letter));
  	}
  
  	display_to(expanded_to);	/* display the To: field on screen... */
  
! 	/* get the Subject: field */
! 	if (get_subject(subject, sizeof subject) == 0) 
  	  return(0);
  
  	if (prompt_for_cc) {
! 	  if (get_copies(cc, expanded_to, expanded_cc, copy_msg,
! 			 sizeof cc, sizeof expanded_cc) == 0)
  	    return(0);
  	}
  
! 	MoveCursor(elm_LINES,0);	/* so you know you've hit <return> ! */
  
  	/** generate the In-Reply-To: header... **/
  
! 	if (is_a_response && 0 != (options & MAIL_REPLYING))
  	  generate_reply_to(current-1);
  
  	/* and mail that puppy outta here! */
***************
*** 276,295 ****
  	dprint(4, (debugfile, "subject=\"%s\"\n",subject));
  	dprint(5, (debugfile, "cc=\"%s\" expanded_cc=\"%s\"\n",cc,expanded_cc));
  	dprint(5, (debugfile, "bcc=\"%s\" expanded_bcc=\"%s\"\n",bcc,expanded_bcc));
! 	return(mail(copy_msg, edit_message, form_letter));
  }
  
! int
! get_subject(subject_field)
! char *subject_field;
  {
  	char	ch, msgbuf[SLEN];
  
  	/** get the subject and return non-zero if all okay... **/
  	int len = 9, prompt_line;
  
! 	prompt_line = mail_only ? 4 : LINES-2;
  
  	if (user_level == 0) {
  	  PutLine0(prompt_line,0, catgets(elm_msg_cat, ElmSet, ElmSubjectOfMessage,
  		"Subject of message: "));
--- 307,329 ----
  	dprint(4, (debugfile, "subject=\"%s\"\n",subject));
  	dprint(5, (debugfile, "cc=\"%s\" expanded_cc=\"%s\"\n",cc,expanded_cc));
  	dprint(5, (debugfile, "bcc=\"%s\" expanded_bcc=\"%s\"\n",bcc,expanded_bcc));
! 	return(mail(current_header,options, form_letter));
! 
  }
  
! static int get_subject(subject_field, size)
!      char *subject_field;
!      int size;
  {
  	char	ch, msgbuf[SLEN];
+ 	int code;
  
  	/** get the subject and return non-zero if all okay... **/
  	int len = 9, prompt_line;
  
! 	prompt_line = mail_only ? 4 : elm_LINES-2;
  
+ redraw:
  	if (user_level == 0) {
  	  PutLine0(prompt_line,0, catgets(elm_msg_cat, ElmSet, ElmSubjectOfMessage,
  		"Subject of message: "));
***************
*** 300,317 ****
  
  	CleartoEOLN();
  
! 	if(optionally_enter(subject_field, prompt_line, len, TRUE, FALSE)==-1){
  	  /** User hit the BREAK key! **/
  	  MoveCursor(prompt_line,0); 	
  	  CleartoEOLN();
! 	  error(catgets(elm_msg_cat, ElmSet, ElmMailNotSent, "Mail not sent."));
  	  return(0);
  	}
  
  	if (strlen(subject_field) == 0) {	/* zero length subject?? */
! 	  MCsprintf(msgbuf, catgets(elm_msg_cat, ElmSet, ElmNoSubjectContinue,
! 	    "No subject - Continue with message? (%c/%c) "),
! 	    *def_ans_yes, *def_ans_no);
  
  	  ch = want_to(msgbuf, *def_ans_no, prompt_line, 0);
  	  if (ch != *def_ans_yes) {	/* user says no! */
--- 334,359 ----
  
  	CleartoEOLN();
  
! 	code = optionally_enter(subject_field, prompt_line, len,
! 				OE_APPEND_CURRENT|OE_REDRAW_MARK,
! 				size);
! 	if (REDRAW_MARK == code)
! 	  goto redraw;
! 
! 	if(code==-1){
  	  /** User hit the BREAK key! **/
  	  MoveCursor(prompt_line,0); 	
  	  CleartoEOLN();
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMailNotSent, 
! 			    "Mail not sent."));
  	  return(0);
  	}
  
  	if (strlen(subject_field) == 0) {	/* zero length subject?? */
! 	  elm_sfprintf(msgbuf, sizeof msgbuf,
! 		       CATGETS(elm_msg_cat, ElmSet, ElmNoSubjectContinue,
! 			       "No subject - Continue with message? (%c/%c) "),
! 		       *def_ans_yes, *def_ans_no);
  
  	  ch = want_to(msgbuf, *def_ans_no, prompt_line, 0);
  	  if (ch != *def_ans_yes) {	/* user says no! */
***************
*** 318,324 ****
  	    if (sleepmsg > 0)
  		sleep((sleepmsg + 1) / 2);
  	    ClearLine(prompt_line);
! 	    error(catgets(elm_msg_cat, ElmSet, ElmMailNotSend, "Mail not sent."));
  	    return(0);
  	  }
  	  else {
--- 360,367 ----
  	    if (sleepmsg > 0)
  		sleep((sleepmsg + 1) / 2);
  	    ClearLine(prompt_line);
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMailNotSend, 
! 			      "Mail not sent."));
  	    return(0);
  	  }
  	  else {
***************
*** 330,339 ****
  	return(1);		/** everything is cruising along okay **/
  }
  
! int
! get_copies(cc_field, address, addressII, copy_message)
! char *cc_field, *address, *addressII;
! int   copy_message;
  {
  	/** Get the list of people that should be cc'd, returning ZERO if
  	    any problems arise.  Address and AddressII are for expanding
--- 373,383 ----
  	return(1);		/** everything is cruising along okay **/
  }
  
! static int get_copies(cc_field, address, addressII, copy_message,
! 		      cc_field_size, addressII_size)
!      char *cc_field, *address, *addressII;
!      int   copy_message;
!      int cc_field_size, addressII_size;
  {
  	/** Get the list of people that should be cc'd, returning ZERO if
  	    any problems arise.  Address and AddressII are for expanding
***************
*** 345,361 ****
  	    possibly rewritten Cc: line...
  	**/
  	int prompt_line;
  
! 	prompt_line = mail_only ? 5 : LINES - 1;
! 	PutLine0(prompt_line,0, catgets(elm_msg_cat, ElmSet, ElmCopiesTo, "Copies to: "));
  
  	fflush(stdout);
  
! 	if (optionally_enter(cc_field, prompt_line, 11, FALSE, FALSE) == -1) {
  	  ClearLine(prompt_line-1);
  	  ClearLine(prompt_line);
  	  
! 	  error(catgets(elm_msg_cat, ElmSet, ElmMailNotSend, "Mail not sent."));
  	  return(0);
  	}
  	
--- 389,417 ----
  	    possibly rewritten Cc: line...
  	**/
  	int prompt_line;
+ 	int code;
  
! 	prompt_line = mail_only ? 5 : elm_LINES - 1;
! 	PutLine0(prompt_line,0, 
! 		 catgets(elm_msg_cat, ElmSet, ElmCopiesTo, "Copies to: "));
  
  	fflush(stdout);
  
! 	code = optionally_enter(cc_field, prompt_line, 11, OE_REDRAW_MARK,
! 				cc_field_size);
! 	while (REDRAW_MARK == code) {
! 	  PutLine0(prompt_line,0, 
! 		   catgets(elm_msg_cat, ElmSet, ElmCopiesTo, "Copies to: "));
! 	  code = optionally_enter(cc_field, prompt_line, 11, 
! 				  OE_REDRAW_MARK|OE_APPEND_CURRENT,
! 				  cc_field_size);
! 	}
! 	if (code == -1) {
  	  ClearLine(prompt_line-1);
  	  ClearLine(prompt_line);
  	  
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMailNotSend, 
! 			    "Mail not sent."));
  	  return(0);
  	}
  	
***************
*** 367,374 ****
  	    for the Cc: field).
  	**/
  
! 	if (build_address(strip_commas(cc_field), addressII)) {
! 	  PutLine1(prompt_line, 11, "%s", addressII);
  	  if ((strcmp(editor, "builtin") != 0 && strcmp(editor, "none") != 0)
  	      || copy_message)
  	    if (sleepmsg > 0)
--- 423,431 ----
  	    for the Cc: field).
  	**/
  
! 	if (build_address(strip_commas(cc_field), addressII,
! 			  cc_field_size, addressII_size)) {
! 	  PutLineX(prompt_line, 11, FRM("%s"), addressII);
  	  if ((strcmp(editor, "builtin") != 0 && strcmp(editor, "none") != 0)
  	      || copy_message)
  	    if (sleepmsg > 0)
***************
*** 378,384 ****
  	if (strlen(address) + strlen(addressII) > VERY_LONG_STRING) {
  	  dprint(2, (debugfile, 
  		"String length of \"To:\" + \"Cc\" too long! (get_copies)\n"));
! 	  error(catgets(elm_msg_cat, ElmSet, ElmTooManyPeople, "Too many people. Copies ignored."));
  	  if (sleepmsg > 0)
  		sleep(sleepmsg);
  	  cc_field[0] = '\0';
--- 435,442 ----
  	if (strlen(address) + strlen(addressII) > VERY_LONG_STRING) {
  	  dprint(2, (debugfile, 
  		"String length of \"To:\" + \"Cc\" too long! (get_copies)\n"));
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmTooManyPeople, 
! 			    "Too many people. Copies ignored."));
  	  if (sleepmsg > 0)
  		sleep(sleepmsg);
  	  cc_field[0] = '\0';
***************
*** 387,418 ****
  	return(1);		/* everything looks okay! */
  }
  	
! int
! copy_the_msg(is_a_response)
! int *is_a_response;
  {
! 	/** Returns True iff the user wants to copy the message being
! 	    replied to into the edit buffer before invoking the editor! 
! 	    Sets "is_a_response" to true if message is a response...
! 	**/
  
! 	char msg[SLEN];
! 	int answer = FALSE;
! 
! 	if (forwarding)
! 	  answer = TRUE;
! 	else if (strlen(to) > 0 && !mail_only) {  /* predefined 'to' line! */
! 	  if (auto_copy) 
! 	    answer = TRUE;
! 	  else {
! 	    MCsprintf(msg, catgets(elm_msg_cat, ElmSet, ElmCopyMessageYN,
! 		"Copy message? (%c/%c) "), *def_ans_yes, *def_ans_no);
! 	    answer = (want_to(msg, *def_ans_no, LINES-3, 0) == *def_ans_yes);
! 	  }
! 	  *is_a_response = TRUE;
! 	}
! 
! 	return(answer);
  }
  
  int
--- 445,480 ----
  	return(1);		/* everything looks okay! */
  }
  	
! int copy_the_msg(is_a_response, options)
!      int *is_a_response;
!      int options;
  {
!   int forwarding = 0 != (options & MAIL_FORWARDING);
  
!   /** Returns True iff the user wants to copy the message being
!     replied to into the edit buffer before invoking the editor! 
!     Sets "is_a_response" to true if message is a response...
!     **/
! 
!   char msg[SLEN];
!   int answer = FALSE;
!   
!   if (forwarding)
!     answer = TRUE;
!   else if (strlen(to) > 0 && !mail_only) {  /* predefined 'to' line! */
!     if (auto_copy) 
!       answer = TRUE;
!     else {
!       elm_sfprintf(msg, sizeof msg,
! 		   CATGETS(elm_msg_cat, ElmSet, ElmCopyMessageYN,
! 			   "Copy message? (%c/%c) "), 
! 		   *def_ans_yes, *def_ans_no);
!       answer = (want_to(msg, *def_ans_no, elm_LINES-3, 0) == *def_ans_yes);
!     }
!     *is_a_response = TRUE;
!   }
!   
!   return(answer);
  }
  
  int
***************
*** 420,427 ****
  int   edit_message, form_letter;
  {
  	/** Prompt for fields and then call mail() to send the specified
! 	    message.  If 'edit_message' is true then don't allow the
!             message to be edited. 'form_letter' can be "YES" "NO" or "MAYBE".
  	    if YES, then add the header.  If MAYBE, then add the M)ake form
  	    option to the last question (see mailsg2.c) etc. etc. 
  
--- 482,489 ----
  int   edit_message, form_letter;
  {
  	/** Prompt for fields and then call mail() to send the specified
! 	    message.  If 'edit_message' is true then by defualt go to
!             editor. 'form_letter' can be "YES" "NO" or "MAYBE".
  	    if YES, then add the header.  If MAYBE, then add the M)ake form
  	    option to the last question (see mailsg2.c) etc. etc. 
  
***************
*** 442,455 ****
  
  	for (i=0; i < message_count; i++) {
  	  if (ison(aliases[i]->status, TAGGED)) {
! 	    strcat(to, aliases[i]->alias);
! 	    strcat(to, " ");
  	    tagged++;
  	  }
  	}
  
  	if (tagged == 0) {
! 	  strcpy(to, aliases[current-1]->alias);
  	}
  
  	dprint(4, (debugfile, "%d aliases tagged for mailing (a_sndmsg)\n",
--- 504,517 ----
  
  	for (i=0; i < message_count; i++) {
  	  if (ison(aliases[i]->status, TAGGED)) {
! 	    strfcat(to, aliases[i]->alias, sizeof to);
! 	    strfcat(to, " ", sizeof to);
  	    tagged++;
  	  }
  	}
  
  	if (tagged == 0) {
! 	  strfcpy(to, aliases[current-1]->alias, sizeof to);
  	}
  
  	dprint(4, (debugfile, "%d aliases tagged for mailing (a_sndmsg)\n",
***************
*** 457,478 ****
  
  	/******* And now the real stuff! *******/
  
! 	if (build_address(to, expanded_to) == 0)   /* build the To: address and expand */
  	  return(0);
  	if ( cc[0] != '\0' )			/* expand out CC addresses */
! 	  build_address(strip_commas(cc), expanded_cc);
  
  	display_to(expanded_to);	/* display the To: field on screen... */
! 
! 	if (get_subject(subject) == 0)	    /* get the Subject: field */
  	  return(0);
  
  	if (prompt_for_cc) {
! 	  if (get_copies(cc, expanded_to, expanded_cc, FALSE) == 0)
  	    return(0);
  	}
  
! 	MoveCursor(LINES,0);	/* so you know you've hit <return> ! */
  
  	/* and mail that puppy outta here! */
  	
--- 519,545 ----
  
  	/******* And now the real stuff! *******/
  
! 	/* build the To: address and expand */
! 	if (build_address(to, expanded_to,
! 			  sizeof to, sizeof expanded_to) == 0)   
  	  return(0);
+ 
  	if ( cc[0] != '\0' )			/* expand out CC addresses */
! 	  build_address(strip_commas(cc), expanded_cc,
! 			sizeof cc, sizeof expanded_cc);
  
  	display_to(expanded_to);	/* display the To: field on screen... */
! 	/* get the Subject: field */
! 	if (get_subject(subject, sizeof subject) == 0)	    
  	  return(0);
  
  	if (prompt_for_cc) {
! 	  if (get_copies(cc, expanded_to, expanded_cc, FALSE,
! 			 sizeof cc, sizeof expanded_cc) == 0)
  	    return(0);
  	}
  
! 	MoveCursor(elm_LINES,0);	/* so you know you've hit <return> ! */
  
  	/* and mail that puppy outta here! */
  	
***************
*** 483,489 ****
  	dprint(5, (debugfile, "bcc=\"%s\" expanded_bcc=\"%s\"\n",bcc,expanded_bcc));
  
  	main_state();
! 	ret = mail(FALSE, edit_message, form_letter);
  	main_state();
  
  /*
--- 550,556 ----
  	dprint(5, (debugfile, "bcc=\"%s\" expanded_bcc=\"%s\"\n",bcc,expanded_bcc));
  
  	main_state();
! 	ret = mail(NULL, edit_message ? MAIL_EDIT_MSG : 0, form_letter);
  	main_state();
  
  /*
Index: elm2.4.ME+.50/src/mailmsg2.c
*** elm2.4.25/src/mailmsg2.c	Mon Dec  4 17:50:56 1995
--- elm2.4.ME+.50/src/mailmsg2.c	Tue Nov 17 21:12:58 1998
***************
*** 1,242 ****
  
! static char rcsid[] = "@(#)$Id: mailmsg2.c,v 5.39 1994/05/30 17:24:38 syd Exp $";
! 
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.39 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: mailmsg2.c,v $
!  * Revision 5.39  1994/05/30  17:24:38  syd
!  * use Elm routine instead of strcasecmp for portability
!  * From: Syd
!  *
!  * Revision 5.38  1994/05/30  16:43:14  syd
!  * I found a few months old patch I have not sent you before (I guess).
!  * It avoids unknowingly confusing some too rigidly and simple mindedly
!  * coded mailers with weird settings like
!  *
!  * 	charset=us-ascii and textencoding=8bit
!  *
!  * This patch will force 7bit encoding with charset=us-ascii.
!  * E.g. older versions of pine will dump core on 8bit & us-ascii.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.37  1994/05/15  23:10:08  syd
!  * Below are the changes required to compile/link elm 2.4 pl23 under
!  * QNX 4.2 with the Watcom 9.5 compiler (very picky).
!  * From: "Brian Campbell" <brianc@quantum>
!  *
!  * Revision 5.36  1994/03/11  21:25:24  syd
!  * Fix Elm looping if an EOF is received.
!  * From: Gregory Neil Shapiro <gshapiro@WPI.EDU>
!  *
!  * Revision 5.35  1993/09/27  01:51:38  syd
!  * Add elm_chown to consolidate for Xenix not allowing -1
!  * From: Syd
!  *
!  * Revision 5.34  1993/08/23  03:26:24  syd
!  * Try setting group id separate from user id in chown to
!  * allow restricted systems to change group id of file
!  * From: Syd
!  *
!  * Revision 5.33  1993/08/10  18:53:31  syd
!  * I compiled elm 2.4.22 with Purify 2 and fixed some memory leaks and
!  * some reads of unitialized memory.
!  * From: vogt@isa.de
!  *
!  * Revision 5.32  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.31  1993/07/20  01:47:47  syd
!  * Fix time() declaration
!  * From: Syd via prompt from Dan Mosedale
!  *
!  * Revision 5.30  1993/06/06  17:53:06  syd
!  * Remove extranious clear
!  * From: Chip
!  *
!  * Revision 5.29  1993/05/31  19:31:31  syd
!  * Total rewrite of verify_transmission().  The existing code was a monsterous
!  * mess and rife with bugs (couldn't forget zero-length messages in send-only
!  * mode, prompts were being setup wrong, perms on Canceled.mail not done right,
!  * etc. etc. etc.)  Previously, the work had been split among two places,
!  * the main code in mail() and the menu in verify_transmission(), and Elm kept
!  * bouncing back and forth between the two.  Now, all work is performed in
!  * verify_transmission() and it simply returns a send-it/forget-it status.
!  * Modified "Canceled.mail" handling so that the files it creates are in
!  * an mbox format (i.e. now includes headers as well as message body).
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.28  1993/05/14  03:56:19  syd
!  * A MIME body-part must end with a newline even when there was no newline
!  * at the end of the actual body or the body is null. Otherwise the next
!  * mime boundary may not be recognized.  The same goes with the closing
!  * boundary too.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.27  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.26  1993/05/08  19:54:17  syd
!  * fix nesting error
!  *
!  * Revision 5.25  1993/05/08  19:06:58  syd
!  * add not keeping empty cancelled messages
!  * From: Syd via request from Phil Richards
!  *
!  * Revision 5.24  1993/05/08  18:51:32  syd
!  * Make Elm quote full names it adds, its easier than checking
!  * for specials and only quoting for specials in the name
!  * From: Syd
!  *
!  * Revision 5.23  1993/04/21  01:25:45  syd
!  * I'm using Elm 2.4.21 under Linux.  Linux has no Bourne shell.  Each
!  * user installs her favorite shell as /bin/sh.  I use Bash 1.12.
!  *
!  * Elm invokes the mail transport (MTA) like so:
!  *
!  *    ( ( MTA destination; rm -f tempfile ) & ) < tempfile &
!  *
!  * This form of command doesn't work with my Bash, in which any command
!  * which is backgrounded ("&") gets its stdin attached to /dev/null.
!  *
!  * The below patch arranges for Elm to call the MTA thusly:
!  *
!  *    ( MTA destination <tempfile; rm -f tempfile ) &
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.22  1993/04/12  03:57:45  syd
!  * Give up and add an Ultrix specific patch. There is a bug in Ispell under
!  * ultrix.  The problem is that when ispell returns, the terminal is no
!  * longer in raw mode. (Ispell isn't restoring the terminal parameters)
!  * From: Scott Ames <scott@cwis.unomaha.edu>
!  *
!  * Revision 5.21  1993/04/12  02:34:36  syd
!  * I have now added a parameter which controls whether want_to clears the
!  * line and centers the question or behaves like it did before. I also
!  * added a 0 at the end of the parameter list to all the other calls to
!  * want_to where a centered question on a clean line is not desirable.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.20  1993/02/12  21:35:07  syd
!  * fix edit form catting on to end, strcat->strcpy
!  * From: Syd
!  *
!  * Revision 5.19  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.18  1993/02/03  16:45:26  syd
!  * A Raw(OFF) was missing so when in mail only mode and one
!  * does f)orget, the "Message saved" ends up on wrong screen.
!  * Also added \r\n to end of messages to make output look nicer.
!  *
!  * When composing mail in the builtin editor, it wrapped on /.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.17  1993/02/03  16:36:56  syd
!  * Fix where we remove the extra hostbangs and on which fields we do
!  * it to include bcc and cc as well as to, and to do it in the file
!  * copies as well as the command line.
!  *
!  * Revision 5.16  1993/01/20  03:02:19  syd
!  * Move string declarations to defs.h
!  * From: Syd
!  *
!  * Revision 5.15  1992/12/28  14:24:25  syd
!  * Fix problem where it won't let no answer on recall last message
!  * From: Syd
!  *
!  * Revision 5.14  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.13  1992/12/20  05:04:51  syd
!  * restore unintnded prefix_chars that caused forwarding without editing
!  * to add prefix
!  * From: Syd
!  *
!  * Revision 5.12  1992/12/11  01:58:50  syd
!  * Allow for use from restricted shell by putting SHELL=/bin/sh in the
!  * environment of spawned mail transport program.
!  * From: chip@tct.com (Chip Salzenberg)
!  *
!  * Revision 5.11  1992/12/07  04:26:26  syd
!  * add missing err declare
!  * From: Syd
!  *
!  * Revision 5.10  1992/12/07  03:20:30  syd
!  * Change $HOME/Cancelled.mail in message to /fullpath/Cancelled.mail
!  * as AFS uses different meaning for $HOME than Elm does and it was
!  * confusing to some users.
!  * From: Syd
!  *
!  * Revision 5.9  1992/11/26  01:46:26  syd
!  * add Decode option to copy_message, convert copy_message to
!  * use bit or for options.
!  * From: Syd and bjoerns@stud.cs.uit.no (Bjoern Stabell)
!  *
!  * Revision 5.8  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.7  1992/11/22  01:14:20  syd
!  * Allow SCO MMDF to use the mmdf library for mailer via execmail.
!  * From: Larry Philps <larryp@sco.com>
!  *
!  * Revision 5.6  1992/11/07  20:29:28  syd
!  * These small typos stopped me from making forms, so here is a patch.
!  * From: andrew.mcparland@rd.eng.bbc.co.uk (Andrew McParland)
!  *
!  * Revision 5.5  1992/11/07  16:21:56  syd
!  * There is no need to write out the MIME-Version header in subparts
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.4  1992/10/30  21:04:04  syd
!  * fix a bug in the forms reply caused by the Cc: buffer not being
!  * cleared.  If one has sent mail just prior to replying to the form and
!  * specified a Cc:  address, the form reply is also sent to those Cc:
!  * address(es).
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.3  1992/10/25  01:47:45  syd
!  * fixed a bug were elm didn't call metamail on messages with a characterset,
!  * which could be displayed by elm itself, but message is encoded with QP
!  * or BASE64
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.2  1992/10/24  13:44:41  syd
!  * There is now an additional elmrc option "displaycharset", which
!  * sets the charset supported on your terminal. This is to prevent
!  * elm from calling out to metamail too often.
!  * Plus a slight documentation update for MIME composition (added examples)
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** Interface to allow mail to be sent to users.  Part of ELM  **/
  
--- 1,15 ----
+ static char rcsid[] = "@(#)$Id: mailmsg2.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
!  *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** Interface to allow mail to be sent to users.  Part of ELM  **/
  
***************
*** 243,248 ****
--- 16,26 ----
  #include "headers.h"
  #include "s_elm.h"
  #include <errno.h>
+ #include "me.h"
+ 
+ #ifdef USE_DSN
+ #include "menu2.h"
+ #endif
  
  extern int errno;
  extern char version_buff[];
***************
*** 266,278 ****
  	    bcc[VERY_LONG_STRING], expanded_bcc[VERY_LONG_STRING],
  	    precedence[SLEN], expires_days[SLEN];
  
  
  #ifdef	MIME
! int msg_is_multipart;
  #endif /* MIME */
! long C_L_Position[2];   /*To Remember position of the Content-Length*/
! long C_StartData[2];    /*To Remember length of Header Area */
! long C_EndData[2];	/* To Remember the end of the BodyPart */
  
  int  gotten_key;
  char *bounce_off_remote();
--- 44,59 ----
  	    bcc[VERY_LONG_STRING], expanded_bcc[VERY_LONG_STRING],
  	    precedence[SLEN], expires_days[SLEN];
  
+ long cl_offset;
+ long cl_start;
+ long cl_end;
  
  #ifdef	MIME
! extern mime_t *attachments;
  #endif /* MIME */
! #ifdef USE_REMAILER
! extern int remailing;
! #endif
  
  int  gotten_key;
  char *bounce_off_remote();
***************
*** 314,323 ****
  	addrs[j] = 0;
  }
  
! int
! mail(copy_msg, edit_message, form)
! int  copy_msg, edit_message, form;
  {
  	/** Given the addresses and various other miscellany (specifically, 
  	    'copy-msg' indicates whether a copy of the current message should 
  	    be included, 'edit_message' indicates whether the message should 
--- 95,120 ----
  	addrs[j] = 0;
  }
  
! #ifdef MIME
! static int check_8bit_str P_((char *str));    /* Prototype */
! #endif
! 
! static int verify_transmission P_((char *,int  *, int *, int, char *,
! 				   int, int, int *, int));  /* Prototype */
! 
! static void mail_sent P_((FILE *fd, char * title, struct run_state *rs,
!  			  int ret, int exit_stat));
! 
! 
! int mail(current_header,options,form)
!      struct header_rec * current_header;
!      int options,form;
  {
+   int copy_msg       = 0 != current_header && 0 != (options & MAIL_COPY_MSG);
+   int edit_message   =                        0 != (options & MAIL_EDIT_MSG);
+   int replying       = 0 != current_header && 0 != (options & MAIL_REPLYING);
+   int forwarding     = 0 != current_header && 0 != (options & MAIL_FORWARDING);
+ 
  	/** Given the addresses and various other miscellany (specifically, 
  	    'copy-msg' indicates whether a copy of the current message should 
  	    be included, 'edit_message' indicates whether the message should 
***************
*** 333,362 ****
  
  	FILE *reply, *real_reply; /* second is post-input buffer */
  	char *whole_msg_file, *tempnam();
! 	char filename[SLEN], fname[SLEN], copy_file[SLEN],
!              very_long_buffer[VERY_LONG_STRING], mailerflags[NLEN];
! 	int ch, sys_status, line_len, filename_handle;
  	register int retransmit = FALSE; 
  	int      already_has_text = FALSE;		/* we need an ADDRESS */
  	int	 signature_done = FALSE;
  	int	 need_redraw = 0;
  	int	 err;
  
  	static int cancelled_msg = 0;
  
  	dprint(4, (debugfile, "\nMailing to \"%s\" (with%s editing)\n",
  		  expanded_to, edit_message? "" : "out"));
! 	
  	gotten_key = 0;		/* ignore previously gotten encryption key */
  
  	/** first generate the temporary filename **/
  
! 	sprintf(filename,"%s%s%d", temp_dir, temp_file, getpid());
  
  	/** if possible, let's try to recall the last message? **/
  
  	if (! batch_only && copy_msg != FORM && user_level != 0)
! 	  retransmit = recall_last_msg(filename, copy_msg, &cancelled_msg, 
  		       &already_has_text);
  
  	/** if we're not retransmitting, create the file.. **/
--- 130,200 ----
  
  	FILE *reply, *real_reply; /* second is post-input buffer */
  	char *whole_msg_file, *tempnam();
! 	char fname[SLEN], copy_file[SLEN],
!              very_long_buffer[VERY_LONG_STRING];
! 	  
! 	char *mailerflags[20], **argv;
! 	char t[80];
! 
! 	int ch, sys_status, line_len, mf_idx=0;
  	register int retransmit = FALSE; 
  	int      already_has_text = FALSE;		/* we need an ADDRESS */
  	int	 signature_done = FALSE;
  	int	 need_redraw = 0;
  	int	 err;
+ 	int reask_verify = FALSE;
+ 	int dsn = 0;
+ #ifdef MIME
+ 	mime_send_t MIME_info;
+ #endif
  
  	static int cancelled_msg = 0;
  
+ #ifdef USE_DSN
+ 	if(DSN_success)
+ 	  dsn |= DSN_SUCCESS|DSN_FAILURE|DSN_DELAY;
+ #endif
+ 
+         if (current_header && (options & MAIL_ISFORM))
+ 	  copy_msg = FORM;
+ 
+ #ifdef MIME
+ 	/* Initialize structure */
+ 	MIME_info.encoding_top = ENCODING_7BIT;
+         MIME_info.type_opts_top[0] = '\0';
+ 	MIME_info.encoding_text = ENCODING_7BIT;
+ 	MIME_info.Charset = charset;
+ 	MIME_info.need_enc = 0;
+ 	MIME_info.type_text = MIME_TYPE_TEXT;
+ 	strfcpy (MIME_info.subtype_text, "plain", 
+ 		 sizeof MIME_info.subtype_text);
+         MIME_info.type_opts_text[0] = '\0';
+ 	MIME_info.encoded_subject[0] = '\0';
+ 	strfcpy (MIME_info.encoded_fullname, full_username,
+ 		 sizeof(MIME_info.encoded_fullname));
+ #endif /* MIME */
+ #ifdef USE_REMAILER
+         remailing = FALSE;
+ #endif
+ 	cl_offset = cl_start = cl_end = 0;
+ 
  	dprint(4, (debugfile, "\nMailing to \"%s\" (with%s editing)\n",
  		  expanded_to, edit_message? "" : "out"));
! 	/* this will get set to 1 on a successful reply */ 
! 	me_retcode = 0;
! 
  	gotten_key = 0;		/* ignore previously gotten encryption key */
  
  	/** first generate the temporary filename **/
  
! 	elm_sfprintf(cur_editfile,sizeof cur_editfile,
! 		     FRM("%s%s%d"), 
! 		     temp_dir, temp_file, getpid());
  
  	/** if possible, let's try to recall the last message? **/
  
  	if (! batch_only && copy_msg != FORM && user_level != 0)
! 	  retransmit = recall_last_msg(cur_editfile, copy_msg, &cancelled_msg, 
  		       &already_has_text);
  
  	/** if we're not retransmitting, create the file.. **/
***************
*** 363,390 ****
  
  	if (! retransmit)
          {
!           unlink(filename); /* we don't care if it fails since the open() will catch it*/
!           if ( ( (filename_handle = open(filename, O_RDWR|O_CREAT|O_EXCL,0600)) == -1) ||
! 	       ( (reply = fdopen(filename_handle, "w")) == NULL) ) {
  	    err = errno;
  	    dprint(1, (debugfile, 
                 "Attempt to write to temp file %s failed with error %s (mail)\n",
! 		 filename, error_description(err)));
! 	    if(batch_only) {
! 	      MCprintf(catgets(elm_msg_cat, ElmSet, ElmCouldNotCreateFile,
! 		"Could not create file %s (%s)."),
! 		filename, error_description(err));
! 	      printf("\n");
! 	    } else
! 	      error2(catgets(elm_msg_cat, ElmSet, ElmCouldNotCreateFile,
! 		"Could not create file %s (%s)."),
! 		filename, error_description(errno));
  	    return(need_redraw);
  	  }
  	}
     
  
! 	(void) elm_chown(filename, userid, groupid);
  
  	/* copy the message from standard input */
  	if (batch_only) {
--- 201,220 ----
  
  	if (! retransmit)
          {
! 	  if ((reply = safeopen_rdwr(cur_editfile)) == NULL) {
  	    err = errno;
  	    dprint(1, (debugfile, 
                 "Attempt to write to temp file %s failed with error %s (mail)\n",
! 		 cur_editfile, error_description(err)));
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldNotCreateFile,
! 				"Could not create file %s (%s)."),
! 			cur_editfile, error_description(errno));
  	    return(need_redraw);
  	  }
  	}
     
  
! 	(void) elm_chown(cur_editfile, userid, groupid);
  
  	/* copy the message from standard input */
  	if (batch_only) {
***************
*** 399,406 ****
  	    dprint(1, (debugfile, 
                "Can't open included file %s.  Failed with error %s (mail)\n",
  	      included_file, error_description(errno)));
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmCouldNotOpenFile,
! 	      "Could not open file %s."), included_file);
  	    return(need_redraw);
  	  }
  
--- 229,237 ----
  	    dprint(1, (debugfile, 
                "Can't open included file %s.  Failed with error %s (mail)\n",
  	      included_file, error_description(errno)));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldNotOpenFile,
! 			      "Could not open file %s."), 
! 		      included_file);
  	    return(need_redraw);
  	  }
  
***************
*** 412,418 ****
  	}
  
  	if (copy_msg == FORM) {
! 	  sprintf(fname, "%s%s%d", temp_dir, temp_form_file, getpid());
  	  fclose(reply);	/* we can't retransmit a form! */
  	  if (access(fname,ACCESS_EXISTS) != 0) {
  	    if(batch_only) {
--- 243,250 ----
  	}
  
  	if (copy_msg == FORM) {
! 	  elm_sfprintf(fname, sizeof fname,
! 		       FRM("%s%s%d"), temp_dir, temp_form_file, getpid());
  	  fclose(reply);	/* we can't retransmit a form! */
  	  if (access(fname,ACCESS_EXISTS) != 0) {
  	    if(batch_only) {
***************
*** 420,432 ****
  		"Couldn't find forms file!"));
  	      printf("\n");
  	    } else
! 	      error(catgets(elm_msg_cat, ElmSet, ElmCouldNotFindForm,
! 		"Couldn't find forms file!"));
  	    return(need_redraw);
  	  }
  	  dprint(4, (debugfile, "-- renaming existing file %s to file %s --\n",
! 		  fname, filename));
! 	  rename(fname, filename);
  
  	  /* kill leftover headers since forms reply skips regular init */
  	  expires[0] = '\0';
--- 252,264 ----
  		"Couldn't find forms file!"));
  	      printf("\n");
  	    } else
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldNotFindForm,
! 				"Couldn't find forms file!"));
  	    return(need_redraw);
  	  }
  	  dprint(4, (debugfile, "-- renaming existing file %s to file %s --\n",
! 		  fname, cur_editfile));
! 	  rename(fname, cur_editfile);
  
  	  /* kill leftover headers since forms reply skips regular init */
  	  expires[0] = '\0';
***************
*** 443,465 ****
  	  precedence[0] = '\0';
  	}
  	else if (copy_msg && ! retransmit) {  /* if retransmit we have it! */
! 	  if (attribution[0]) {
! 	    fprintf(reply, attribution, headers[current-1]->from);
! 	    fputc('\n', reply);
! 	  }
! 	  else if (forwarding) {
! 	    fputs("Forwarded message:\n", reply);
! 	  }
! 	  if (edit_message) {
! 	    copy_message(prefixchars, reply,
! 		( noheader ? CM_REMOVE_HEADER : 0 ) | CM_MMDF_HEAD | CM_DECODE);
! 	    already_has_text = TRUE;	/* we just added it, right? */
  	  }
! 	  else
! 	    copy_message("", reply,
! 		( noheader ? CM_REMOVE_HEADER : 0 ) | CM_MMDF_HEAD);
  	}
  
          /* append signature now if we are going to use an external editor */
  	/* Don't worry about the remote/local determination too much */
  
--- 275,398 ----
  	  precedence[0] = '\0';
  	}
  	else if (copy_msg && ! retransmit) {  /* if retransmit we have it! */
! 	  char From_buffer[LONG_STRING];
! 	  struct addr_item *p;
! 
! 	  From_buffer[0] = '\0';
! 	  if (current_header->from) {
! 	    for (p = current_header->from; p->addr && p->fullname; p++) {
! 	      char * str = p->fullname[0] ? p->fullname : p->addr;
! 	      if (From_buffer[0])
! 		strfcat(From_buffer,", ",sizeof From_buffer);
! 	      strfcat(From_buffer,str,sizeof From_buffer);
! 	    }
  	  }
! 
! #ifdef MIME
! 	  if (!forwarding || (forwarding && !mimeforward)) {
! #endif
! 	    if (forwarding && !quote_forward) {
! 	      if (From_buffer[0]) {
! 		fprintf (reply, "----- Forwarded message from %s -----\n\n", 
! 			 From_buffer);
! 	      } else
! 		fprintf (reply, "----- Forwarded message (env-from %s) -----\n\n", 
! 			 current_header->env_from);
! 	      
! 	    } else if (attribution[0] && current_header) {
! 	      if (From_buffer[0]) {
! 		fprintf(reply, attribution, From_buffer);
! 	      } else
! 		fprintf(reply, attribution, current_header->env_from);
! 	      fputc('\n', reply);
! 	    }
! 	    if (edit_message) {
! 	      int NOHDR = forwarding ? noheaderfwd : noheader;
! 	      int NOQUOTE = forwarding && !quote_forward; 
! 	      copy_message(mailfile,current_header,
! 			   NOQUOTE ? "" : prefixchars, reply,
! 			   ( NOHDR ? CM_REMOVE_HEADER : 0 ) 
! 			   | CM_MMDF_HEAD | CM_DECODE 
! 			   /* I think it is good idea to use CM_FILT_HDR
! 			    * even when we don't have forwarding ... -KEH
! 			    */
! 			   | CM_FILT_HDR );
! 	      already_has_text = TRUE;	/* we just added it, right? */
! 	    }
! 	    else {
! 	      int NOHDR = forwarding ? noheaderfwd : noheader;
! 	      copy_message(mailfile,current_header,
! 			   "", reply,
! 			   ( NOHDR ? CM_REMOVE_HEADER : 0 ) 
! 			   | CM_MMDF_HEAD
! 			   /* I added CM_DECODE to here -KEH */
! 			   | CM_DECODE);
! 	    }
! 	    if (forwarding && !quote_forward) {
! 	      if (From_buffer[0])
! 		fprintf (reply, "----- End of forwarded message from %s -----\n",
! 			 From_buffer);
! 	      else
! 		fprintf (reply, "----- End of forwarded message (env-from %s) -----\n",
! 			 current_header->env_from);
! 	    }
! #ifdef MIME
! 	  }
! 	  else {
! 	    FILE *tmpfp;
! 	    int len,first_line = 1;
! 	    int in_headers = TRUE;
! 
! 	    /* Use MESSAGE/RFC822 to forward messages. */
! 
! 	    elm_sfprintf (very_long_buffer, sizeof very_long_buffer,
! 			  FRM("%selmfwd.%d"), 
! 			  temp_dir, getpid ());
! 	    if (! (tmpfp = safeopen_rdwr (very_long_buffer))) {
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFailFileForward,
! 			    "Failed to create file for forwarding"));
! 	    } else {
! 	      attachments = (mime_t *) mime_t_alloc ();
! 	      attachments->flags = MIME_RFC822;
! 	      attachments->pathname = (char *) strmcpy(attachments->pathname, 
! 						       very_long_buffer);
! 
! 
! 	      copy_message(mailfile,current_header,"",tmpfp,
! 			   CM_REMOVE_ENVELOPE);
! 	   
! 	      attachments->length = fsize(tmpfp);
! 	      fclose (tmpfp);
! 	      attachments->unlink = 1; /* mark for later deletion */
! 	      attachments->type = MIME_TYPE_MESSAGE;
! 	      strfcpy (attachments->subtype, "rfc822", 
! 		       sizeof attachments->subtype);
! 	      elm_sfprintf (very_long_buffer, sizeof very_long_buffer,
! 			    CATGETS(elm_msg_cat, ElmSet, ElmForwardedMesg,
! 				    "Forwarded message from %s"), 
! 			    From_buffer[0] ? From_buffer : current_header->env_from);
! 	      attachments->description = (char *)strmcpy (attachments->description,
! 							  very_long_buffer);
! 	      
! 	      /* Pick up the encoding from the message. */
! 	      attachments->encoding = ENCODING_7BIT;
! 	      (void) update_encoding (&(attachments->encoding),
! 				      current_header->mime_rec.encoding);
! 	      
! 	    }
! 	  }
! #endif /* MIME */
  	}
  
+ #ifdef MIME
+ 	/* Initial attachment */
+ 	if(attachments) 
+ 	  attachments->next = attach_files;
+ 	else
+ 	  attachments = attach_files;
+ 	attach_files = NULL;
+ #endif
+ 
          /* append signature now if we are going to use an external editor */
  	/* Don't worry about the remote/local determination too much */
  
***************
*** 480,543 ****
  	if(auto_cc) {
  	  if(save_by_name) {
  	    if(force_name) {
! 	      strcpy(copy_file, "=");	/* signals save by 'to' logname */
  	    } else {
! 	      strcpy(copy_file, "=?");	/* conditional save by 'to' logname */
  	    }
  	  } else {
! 	    strcpy(copy_file, "<");	/* signals save to sentmail */
  	  }
  	} else *copy_file = '\0';	/* signals to not save a copy */
  
! 	/* ask the user to confirm transmission of the message */
! 	if (!batch_only) {
  	    ch = (edit_message? 'e' : '\0');
! 	    if (verify_transmission(filename, &form, &need_redraw,
! 		    already_has_text, copy_file, ch) != 0) {
! 		cancelled_msg = (bytes(filename) > 0);
! 		return need_redraw;
  	    }
! 	    if (form == YES && format_form(filename) < 1) {
! 		cancelled_msg = (bytes(filename) > 0);
! 		return need_redraw;
  	    }
! 	}
  
! 	if ((reply = fopen(filename,"r")) == NULL) {
  	    err = errno;
  	    dprint(1, (debugfile,
! 		"Attempt to open file %s for reading failed with error %s (mail)\n",
! 		filename, error_description(err)));
! 	    if (!batch_only) {
! 		error1(catgets(elm_msg_cat, ElmSet, ElmCouldNotOpenReply,
! 		    "Could not open reply file (%s)."), error_description(err));
! 	    } else {
! 		printf(catgets(elm_msg_cat, ElmSet, ElmCouldNotOpenReply,
! 		    "Could not open reply file (%s)."), error_description(err));
! 		putchar('\n');
! 	    }
  	    return need_redraw;
! 	}
  
! 	cancelled_msg = FALSE;	/* it ain't cancelled, is it? */
  
! 	/** ask about bounceback if the user wants us to.... **/
  
! 	if (uucp_hops(to) > bounceback && bounceback > 0 && copy_msg != FORM) 
! 	  if (verify_bounceback() == TRUE) {
! 	    if (strlen(cc) > 0) strcat(expanded_cc, ", ");
! 	    strcat(expanded_cc, bounce_off_remote(to));
! 	  }
  
  #ifdef	MIME
! 	/* Look if its a Multimedia/multipart Message */
! 	msg_is_multipart = check_for_multipart(reply);
  
! 	if (msg_is_multipart == -1) {
! 		return(need_redraw);
! 	}
! #endif /* MIME */
  
  	/** grab a copy if the user so desires... **/
  
  	remove_hostbang(expanded_to);
--- 413,652 ----
  	if(auto_cc) {
  	  if(save_by_name) {
  	    if(force_name) {
! 	      strfcpy(copy_file, "=",
! 		      sizeof copy_file);    /* signals save by 'to' logname */
  	    } else {
! 	      strfcpy(copy_file, "=?",
! 		      sizeof copy_file); /* conditional save by 'to' logname */
  	    }
  	  } else {
! 	    strfcpy(copy_file, "<", sizeof copy_file);	/* signals save to sentmail */
  	  }
  	} else *copy_file = '\0';	/* signals to not save a copy */
  
! #ifdef MIME
! 	/* tell to verify_transmission() */
! 	if (attachments) 
! 	  options |= MAIL_HAVE_ATTACHMENTS;
! #endif
! #ifdef USE_PGP
! 	if (current_header &&
! 	    current_header->pgp & PGP_MESSAGE)
! 	  options |= MAIL_HAVE_PGP_ENCODED;
! #endif
! 
! 	do { /* So we can return here if check_for_multipart() fails
! 	      * - K E H <hurtta@dionysos.FMI.FI>    */
! 
! 	  reask_verify = 0;
! 
! 	  /* ask the user to confirm transmission of the message */
! 	  if (!batch_only) {
! 	  fatal_label:
  	    ch = (edit_message? 'e' : '\0');
! 	    if (verify_transmission(cur_editfile, &form, &need_redraw,
! 				    already_has_text, copy_file, ch,
! 				    options, &dsn, sizeof copy_file) != 0) {
! 	      cancelled_msg = (bytes(cur_editfile) > 0);
! # ifdef MIME
! 	      if (attachments) {
! 		mime_destroy (attachments);
! 		attachments = 0;
! 	      }
! # endif
! 	      return need_redraw;
  	    }
! 	    if (form == YES && format_form(cur_editfile) < 1) {
! 	      cancelled_msg = (bytes(cur_editfile) > 0);
! 	      return need_redraw;
  	    }
!             /* so we can mark the reply flag */
!             me_retcode = 1;
! 	  }
  
! 	  if ((reply = fopen(cur_editfile,"r")) == NULL) {
  	    err = errno;
  	    dprint(1, (debugfile,
! 		       "Attempt to open file %s for reading failed with error %s (mail)\n",
! 		       cur_editfile, error_description(err)));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldNotOpenReply,
! 			      "Could not open reply file (%s)."), 
! 		      error_description(err));
  	    return need_redraw;
! 	  }
! #ifdef MIME
! 	  MIME_info.encoding_top  = ENCODING_7BIT;/* Encoding for Multipart/ */
! 	  MIME_info.encoding_text = ENCODING_7BIT;/* Encoding for Text/plain */
! 	  {
! 	    /* Determine how this message should be MIME encoded:
! 	     * 7BIT, 8BIT, BINARY or QUOTED-PRINTABLE.
! 	     */
! 	    MIME_info.need_enc = needs_encoding (reply);
! 	    if (allow_no_hdrencoding)
! 		MIME_info.need_enc |= check_8bit_str (subject);
! 	    
! 	    if (MIME_info.need_enc & HAVE_BINARY) {
! #ifdef USE_BINARYMIME
! 	      MIME_info.encoding_text =  ENCODING_BINARY;
! #else
! 	      if (allow_no_encoding >= 2)
! 		/* Just send BINARY anyway */
! 		MIME_info.encoding_text = ENCODING_BINARY;
! 	      else
! 		/* no -BBINARYMIME option */
! 		MIME_info.encoding_text = ENCODING_QUOTED;
! #endif
! 	    }
! 	    else if (MIME_info.need_enc & HAVE_8BIT) {
! #ifdef USE_8BITMIME
! 	      MIME_info.encoding_text =  ENCODING_8BIT;
! #else
! 	      if (allow_no_encoding >= 1)
! 		/* Just send 8BIT anyway */
! 		MIME_info.encoding_text = ENCODING_8BIT;
! 	      else
! 		/* no -B8BITMIME option */
! 		MIME_info.encoding_text = ENCODING_QUOTED;
! #endif
! 	    }
! 	    /* Control characters can send with encoding 7BIT
! 	     * HAVE_BINARY takes care really severe stuff */
! 	    if ((MIME_info.need_enc & HAVE_CTRL) &&
! 		MIME_info.encoding_text != ENCODING_QUOTED) {
! 	      if (batch_only) 		
! 		MIME_info.encoding_text =  ENCODING_QUOTED;
! 	      else { 
! 		int ch;
! 		ch = want_to("Text have control characters. \
! Encode text with quoted-printable? ",*def_ans_yes,elm_LINES-1,0);
! 		if (ch == *def_ans_yes) 
! 		  MIME_info.encoding_text =  ENCODING_QUOTED;
! 		else if (ch != *def_ans_no) {
! 		  edit_message = FALSE;
! 		  reask_verify = TRUE;
! 		  continue;    /* Go again to verify_transmission loop */
! 		}
! 	      }
! 	    }
! 	  }
  
! 	  (void) update_encoding(&MIME_info.encoding_top,
! 				 MIME_info.encoding_text);
  
! 	  /* Update Charset */
! 	  MIME_info.Charset = charset;
! 	  if (!(MIME_info.need_enc & HAVE_8BIT) &&
! 	      istrcmp(charset,"US-ASCII") != 0 &&
! 	      charset_ok(charset))
! 	    MIME_info.Charset="US-ASCII";
! 	  else if ((MIME_info.need_enc & HAVE_8BIT) &&
! 		   istrcmp(charset,"US-ASCII") == 0 &&
! 		   istrcmp(display_charset,"US-ASCII") != 0 &&
! 		   charset_ok(display_charset))
! 	    MIME_info.Charset=display_charset;
! 	  else if ((MIME_info.need_enc & HAVE_8BIT) &&
! 		   istrcmp(charset,"US-ASCII") == 0) {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmUsingUNKNOWN8BIT,
! 			      "Text has 8BIT data and charset=US-ASCII, using charset=UNKNOWN-8BIT instead."));
! 	    
! 	    if (sleepmsg > 0)
! 	      sleep(sleepmsg);
! 	    
! 	    MIME_info.Charset="UNKNOWN-8BIT";           
!          }
  
! #endif /* MIME */
  
+ 	  cancelled_msg = FALSE;	/* it ain't cancelled, is it? */
+ 
  #ifdef	MIME
! 	  MIME_info.msg_is_multipart = check_for_multipart(reply, &MIME_info);
! 	  if (MIME_info.msg_is_multipart < 0) { /* Error in [include ...] */
! 	    if (!batch_only) {
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFixInclude,
! 				"Please fix [include ...] lines!"));
! 	      if (sleepmsg > 0)
! 		sleep (sleepmsg);
  
! 	      edit_message = FALSE;
! 	      reask_verify = TRUE; /* Go to verify_transmission again. */
! 	    }
! 	  }
! 
! 	  if (attachments != 0) {
! 	    /* Determine what the top level Content-Transfer-Encoding: field
! 	     * should be.  BINARY has the highest weight, followed by
! 	     * 8BIT.  NOTE: no checking to see if the mailer supports those
! 	     * encodings since that will already have been done in the
! 	     * attach_menu() routine.
! 	     */
! 	    mime_t *tmp;
! 	    
! 	    MIME_info.msg_is_multipart = TRUE;
! 	    
! 	    for (tmp = attachments; tmp != 0; tmp = tmp->next) {
! 	      (void) update_encoding(&MIME_info.encoding_top,tmp->encoding); 
! 	      if (tmp->pathname) {
! 		if (access(tmp->pathname,READ_ACCESS) < 0) {
! 		  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmAccessAttach,
! 				    "Can't access attachment: %.50s"),
! 			    tmp->pathname);
! 		  reask_verify = TRUE; /* Go to verify_transmission again. */
! 		  if (sleepmsg > 0)
! 		    sleep (sleepmsg);
! 		  edit_message = FALSE;
! 		}
! 	      } else {
! 		lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadAttach,
! 				  "Bad attachment -- no filename!"));
! 	      }
! 	    }
! 	  }
  
+ #endif /* MIME */
+ 	  /* End of check_for_multipart failure loop */
+ 	} while (!batch_only && reask_verify);
+ #ifdef MIME
+ 	if (MIME_info.msg_is_multipart) {
+ 	  (void) mime_generate_boundary (MIME_info.mime_boundary,
+ 					 sizeof MIME_info.mime_boundary);
+           add_parameter(MIME_info.type_opts_top, "boundary",
+                         MIME_info.mime_boundary, 
+ 			sizeof(MIME_info.type_opts_top),
+                         FALSE);
+ 	}
+ #ifdef USE_PGP
+         if (pgp_status & (PGP_MESSAGE | PGP_SIGNED_MESSAGE | PGP_PUBLIC_KEY)) {
+           MIME_info.type_text = MIME_TYPE_APPLICATION;
+           strfcpy(MIME_info.subtype_text, "pgp",
+ 		  sizeof MIME_info.subtype_text);
+ 	  if (pgp_status & PGP_PUBLIC_KEY)
+             add_parameter(MIME_info.type_opts_text,"format","keys-only",
+                           sizeof(MIME_info.type_opts_text), FALSE);
+           else {
+             add_parameter(MIME_info.type_opts_text, "format", "text",
+                           sizeof(MIME_info.type_opts_text), FALSE);
+             /* This next bit is a non-non-standard, but exmh does this and it
+              * can be very useful when parsing the message.
+              */
+             if (pgp_status & PGP_MESSAGE) {
+               add_parameter(MIME_info.type_opts_text, "x-action",
+                             (pgp_status & PGP_SIGNED_MESSAGE) ? 
+ 			    "encryptsign" : "encrypt",
+                             sizeof(MIME_info.type_opts_text),FALSE);
+             }
+             else
+               add_parameter(MIME_info.type_opts_text, "x-action", "sign",
+                             sizeof(MIME_info.type_opts_text), FALSE);
+           }
+         }
+ #endif
+ 	/* charset parameter is valid for all subtypes of Text/ */
+         if (MIME_info.type_text == MIME_TYPE_TEXT)
+           add_parameter(MIME_info.type_opts_text, "charset", MIME_info.Charset,
+                         sizeof(MIME_info.type_opts_text), FALSE);
+ #endif
+          
  	/** grab a copy if the user so desires... **/
  
  	remove_hostbang(expanded_to);
***************
*** 544,552 ****
  	remove_hostbang(expanded_cc);
  	remove_hostbang(expanded_bcc);
  
  	if (*copy_file) /* i.e. if copy_file contains a name */
  	  save_copy(expanded_to, expanded_cc, expanded_bcc,
! 	       filename, copy_file, form);
  
  	/** write all header information into whole_msg_file **/
  
--- 653,767 ----
  	remove_hostbang(expanded_cc);
  	remove_hostbang(expanded_bcc);
  
+ #ifdef USE_REMAILER
+ 	if (remailing)
+ 	  /* Retrieves the database of remailers and sets the To: address
+ 	   * to the appropriate remailer.  This is done here so that a
+ 	   * saved copy of this message will look the same as the outgoing
+ 	   * message.
+ 	   */
+ 	  remailer_proc();
+ #endif
+ 
+ #ifdef MIME
+ 	if (allow_no_hdrencoding) {
+ 	  strfcpy(MIME_info.encoded_subject,subject,
+ 		  sizeof(MIME_info.encoded_subject));
+ 
+ 	  MIME_info.encoded_fullname[0] = '"';
+ 	  strfcpy(MIME_info.encoded_fullname+1,full_username,
+ 		  sizeof(MIME_info.encoded_fullname)-2);
+ 	  strfcat(MIME_info.encoded_fullname,"\"",
+ 		  sizeof MIME_info.encoded_fullname);
+ 
+ 	  strfcpy(MIME_info.encoded_in_reply_to,in_reply_to,
+ 		  sizeof(MIME_info.encoded_in_reply_to));
+ 
+ 	  dprint(2,(debugfile,"Subject not encoded: %s\n",
+ 		    MIME_info.encoded_subject));
+ 	  dprint(2,(debugfile,"Fullname not encoded: %s\n",
+ 		    MIME_info.encoded_fullname));
+ 	  dprint(2,(debugfile,"In-Reply-To not encoded: %s\n",
+ 		    MIME_info.encoded_in_reply_to));
+ 
+ 	} else {
+ 	  char *ptr,*next_ptr,*rptr;
+ 	  int qcount = 0;
+ 
+ 	  rfc1522_encode_text(MIME_info.encoded_subject,
+ 			      sizeof(MIME_info.encoded_subject),
+ 			      subject,0);
+ 	  rfc1522_encode_text(MIME_info.encoded_fullname,
+ 			      sizeof(MIME_info.encoded_fullname),
+ 			      full_username,HDR_PHRASE);
+ 
+ 	  for (ptr = in_reply_to, rptr = MIME_info.encoded_in_reply_to; 
+ 	       ptr && *ptr; ptr = next_ptr) {
+ 	    int left = ((MIME_info.encoded_in_reply_to + 
+ 			 sizeof(MIME_info.encoded_in_reply_to)) - rptr)-1;
+ 	    char c = 0;
+ 	    if (left < 2)
+ 	      break;
+ 	    next_ptr = qstrpbrk(ptr,"<>");
+ 	    if (next_ptr) {
+ 	      c = *next_ptr;
+ 	      *next_ptr = '\0';
+ 	      if ('<' == c) 
+ 		qcount ++;
+ 	    }
+ 	    dprint(12,(debugfile,
+ 		       "Encoding in-reply-to - elem='%s', qcount=%d, c='%c'\n",
+ 		       ptr,qcount,c));
+ 	    if (!next_ptr || next_ptr > ptr) {
+ 	      int len;
+ 	      if (qcount > 0) {
+ 		strfcpy(rptr,ptr,left);
+ 	      } else if (0 == qcount) {
+ 		rfc1522_encode_text(rptr,left,ptr,HDR_PHRASE);
+ 	      } else {
+ 		error("Error in In-Reply-To");
+ 		*rptr = '\0';		
+ 	      }
+ 	      dprint(12,(debugfile,
+ 			 "Encoding in-reply-to - encoded='%s'\n",
+ 			 rptr));
+ 
+ 	      len = strlen(rptr);
+ 	      rptr += len;
+ 	    }
+ 	    if (next_ptr) {
+ 	      if ('>' == c) 
+ 		qcount --;
+ 	      *next_ptr = c;
+ 	      next_ptr++;
+ 	      if (rptr < (MIME_info.encoded_in_reply_to + 
+ 			  sizeof(MIME_info.encoded_in_reply_to)) -1) 
+ 		*rptr++=c;
+ 	      *rptr='\0';
+ 	    }
+ 	  }
+ 	  *rptr = '\0';
+ 	  if (qcount > 0) {
+ 	    error("Error in In-Reply-To");
+ 	  }
+ 
+ 	  dprint(2,(debugfile,"Encoded subject: %s\n",
+ 		    MIME_info.encoded_subject));
+ 	  dprint(2,(debugfile,"Encoded fullname: %s\n",
+ 		    MIME_info.encoded_fullname));
+ 	  dprint(2,(debugfile,"Encoded In-Reply-To: %s\n",
+ 		    MIME_info.encoded_in_reply_to));
+ 	}
+ #endif
+ 
  	if (*copy_file) /* i.e. if copy_file contains a name */
+ #ifdef MIME
  	  save_copy(expanded_to, expanded_cc, expanded_bcc,
! 	       cur_editfile, copy_file, form, &MIME_info);
! #else
! 	  save_copy(expanded_to, expanded_cc, expanded_bcc,
! 	       cur_editfile, copy_file, form);
! #endif
  
  	/** write all header information into whole_msg_file **/
  
***************
*** 568,709 ****
  	/** try to write headers to new temp file **/
  
  	dprint(6, (debugfile, "Composition file='%s' and mail buffer='%s'\n", 
! 		    filename, whole_msg_file));
  
  	dprint(2,(debugfile,"--\nTo: %s\nCc: %s\nBcc: %s\nSubject: %s\n---\n", 
  		  expanded_to, expanded_cc, expanded_bcc, subject));
  
  	if ((real_reply = 
  	   write_header_info(whole_msg_file, expanded_to,
! 	     expanded_cc, expanded_bcc, form == YES, FALSE)) == NULL) {
! 
! 	  /** IT FAILED!!  MEIN GOTT!  Use a dumb mailer instead! **/
! 
! 	  dprint(3, (debugfile, "** write_header failed: %s\n", 
! 		 error_description(errno)));
! 
! 	  if (cc[0] != '\0')  		/* copies! */
! 	    sprintf(expanded_to,"%s %s", expanded_to, expanded_cc);
! 
! 	  quote_args(very_long_buffer, strip_parens(strip_commas(expanded_to)));
! 	  strcpy(expanded_to, very_long_buffer);
! 
! 	  sprintf(very_long_buffer, "(%s -s \"%s\" %s < %s ; %s %s) &",
! 		  mailx, subject, expanded_to, filename, remove_cmd, filename);
! 
! 	  if(batch_only) {
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmUsedDumpMailer,
! 		"Message sent using dumb mailer %s."), mailx);
! 	    printf("\n");
! 	  } else
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmUsedDumpMailer,
! 		"Message sent using dumb mailer %s."), mailx);
! 	    if (sleepmsg > 0)
! 		sleep(sleepmsg);
! 
  	}
- 	else {
- 
- 	  C_StartData[0] = ftell(real_reply);
- 
- 	  copy_message_across(reply, real_reply, FALSE);
- 
-           /* Append signature if not done earlier */
  
!           if (!signature_done && !retransmit && copy_msg != FORM)
!                append_sig(real_reply);
! 	  
  #ifdef MIME
! 	  if (!copy_msg != FORM && msg_is_multipart) {
! 	    fprintf(real_reply, "\n--%s--\n", MIME_BOUNDARY);
! 	    if (C_L_Position[1] != 0L) {
! 	      C_EndData[1] = ftell(real_reply);
! 	      C_L_Position[1] = fseek(real_reply, C_L_Position[1], 0);
! 	      fprintf(real_reply, "%d", C_EndData[1] - C_StartData[1]);
! 	      fseek(real_reply, C_EndData[1], 0);
! 	    }
  	  }
  #endif
! 
! 	  C_EndData[0] = ftell(real_reply);
  	    
! 	  fseek(real_reply, C_L_Position[0], 0);
! 	  fprintf(real_reply, "%d", C_EndData[0] - C_StartData[0]);
! 	  fclose(real_reply);
! 
! 	  if (cc[0] != '\0')  				         /* copies! */
! 	    sprintf(expanded_to,"%s %s", expanded_to, expanded_cc);
! 
! 	  if (bcc[0] != '\0') {
! 	    strcat(expanded_to, " ");
! 	    strcat(expanded_to, expanded_bcc);
  	  }
  
! 	  if (strcmp(sendmail, mailer) == 0
  #ifdef SITE_HIDING
! 	      && ! is_a_hidden_user(username)
  #endif
! 	  ) {
! 	    strcpy(mailerflags, (sendmail_verbose ? smflagsv : smflags));
! 	    if (metoo) strcat(mailerflags, smflagmt);
! 	  } else if (strcmp(submitmail, mailer) == 0)
! 	    strcpy(mailerflags, submitflags_s);
! 	  else if (strcmp(execmail, mailer) == 0) {
! 	    strcpy(mailerflags, (sendmail_verbose ? emflagsv : emflags));
! 	    if (metoo) strcat(mailerflags, emflagmt);
! 	  } else
! 	    mailerflags[0] ='\0';
  
! 	  if (strcmp(submitmail, mailer) == 0)
! 	    strcpy(expanded_to, " ");
! 	  else {
! 	    quote_args(very_long_buffer, strip_parens(strip_commas(expanded_to)));
! 	    strcpy(expanded_to, very_long_buffer);
  	  }
! 
! 	  sprintf(very_long_buffer,"(%s %s %s < %s ; %s %s) &", 
! 		mailer, mailerflags, expanded_to, whole_msg_file,
! 		remove_cmd, whole_msg_file);
  	}
  
  	free(whole_msg_file);
  
  	fclose(reply);
  
! 	if(batch_only) {
! 	  printf(catgets(elm_msg_cat, ElmSet, ElmSendingMail,
! 		"Sending mail..."));
! 	  printf("\n");
! 	} else {
! 	  PutLine0(LINES,0,catgets(elm_msg_cat, ElmSet, ElmSendingMail,
! 		"Sending mail..."));
! 	  CleartoEOLN();
! 	}
! 
! 	/* Take note of mailer return value */
  
! 	if ( sys_status = system_call(very_long_buffer, SY_ENV_SHELL) ) {
! 		/* problem case: */
! 		if (mail_only || batch_only) {
! 		   printf("\r\n");
! 		   printf(catgets(elm_msg_cat, ElmSet, ElmMailerReturnedError,
! 			"mailer returned error status %d"), sys_status);
! 		   printf("\r\n");
! 		} else {
! 		   sprintf(very_long_buffer, catgets(elm_msg_cat, ElmSet, ElmMailerReturnedError,
! 			"mailer returned error status %d"), sys_status);
! 		   set_error(very_long_buffer);
  		}
! 	} else {
! 		/* Success case: */
! 		if(batch_only) {
! 		  printf(catgets(elm_msg_cat, ElmSet, ElmMailSent, "Mail sent!"));
! 	          printf("\n");
! 		} else if(mail_only)
! 		  error(catgets(elm_msg_cat, ElmSet, ElmMailSent, "Mail sent!"));
! 		else
! 		  set_error(catgets(elm_msg_cat, ElmSet, ElmMailSent, "Mail sent!"));
  	}
  
  	/* Unlink temp file now.
  	 * This is a precaution in case the message was encrypted.
--- 783,1063 ----
  	/** try to write headers to new temp file **/
  
  	dprint(6, (debugfile, "Composition file='%s' and mail buffer='%s'\n", 
! 		    cur_editfile, whole_msg_file));
  
  	dprint(2,(debugfile,"--\nTo: %s\nCc: %s\nBcc: %s\nSubject: %s\n---\n", 
  		  expanded_to, expanded_cc, expanded_bcc, subject));
  
  	if ((real_reply = 
+ #ifdef MIME
  	   write_header_info(whole_msg_file, expanded_to,
! 	     expanded_cc, expanded_bcc, form == YES, FALSE, &MIME_info)
! #else
! 	   write_header_info(whole_msg_file, expanded_to,
! 	     expanded_cc, expanded_bcc, form == YES, FALSE)
! #endif
! 	     ) == NULL) {
! 	  error("Failed to create temp file for mailing!");
! 	  sleep_message();
! 	  edit_message = FALSE;
! 	  fclose(reply);
! 	  free(whole_msg_file);
! 
! 	  if (!batch_only)
! 	    goto fatal_label;
! 
! 	  if (!batch_only)
! 	    goto fatal_label;
! 	  return TRUE; /* need redraw */
  	}
  
! 	cl_start = ftell(real_reply);
  #ifdef MIME
! #ifdef USE_REMAILER
! 	if (remailing) {
! 	  int ret;
! 	  
! 	  ret = remailer_copy_message_across(reply, real_reply, FALSE,
! 					     &MIME_info);
! 	  remailer_destroy_db();
! 	  /* Check for error to ensure that the message is not sent if
! 	   * there was a problem, or else the sender's anonymity could
! 	   * be compromised!
! 	   */
! 	  if (ret == -1) {
! 	    edit_message = FALSE;
! 	    fclose(reply);
! 	    fclose(real_reply);
! 	    free(whole_msg_file);
! 	    if (!batch_only)
! 	      goto fatal_label;
! 	    
! 	    unlink(cur_editfile);
! 	    return TRUE;
  	  }
+ 	}
+ 	else
  #endif
! 	  copy_message_across(reply, real_reply, FALSE, &MIME_info);
! 	
! 	/* clean up the allocated space */
! 	if (attachments) {
! 	  mime_destroy (attachments);
! 	  attachments = 0;
! 	}
! #else
! #ifdef USE_REMAILER
! 	if (remailing) {
! 	  int ret;
! 	  
! 	  ret = remailer_copy_message_across(reply, real_reply, FALSE);
! 	  remailer_destroy_db();
! 	  /* Check for error to ensure that the message is not sent if
! 	   * there was a problem, or else the sender's anonymity could
! 	   * be compromised!
! 	   */
! 	  if (ret == -1) {
! 	    edit_message = FALSE;
! 	    fclose(reply);
! 	    fclose(real_reply);
! 	    free(whole_msg_file);
! 	    if (!batch_only)
! 	      goto fatal_label;
  	    
! 	    unlink(cur_editfile);
! 	    return TRUE;
  	  }
+ 	}
+ 	else
+ #endif
+ 	  copy_message_across(reply, real_reply, FALSE);
+ #endif
+ 	cl_end = ftell(real_reply);	    
+ 	fseek(real_reply, cl_offset, 0);
+ 	fprintf(real_reply, "%d", cl_end - cl_start);
+ 	
+ 	/* Return to the end of the file! */
+ 	fseek (real_reply, 0, 2);
+ 	
+ 	/* Append signature if not done earlier */
+ 	
+ 	if (!signature_done && !retransmit && copy_msg != FORM)
+ 	  append_sig(real_reply);
+ 		
+ 	if (cc[0] != '\0') { 				         /* copies! */
+ 	  strfcat(expanded_to, ",", sizeof expanded_to);
+ 	  strfcat(expanded_to, expanded_cc, sizeof expanded_to);
+ 	}
+ 	
+ 	if (bcc[0] != '\0') {
+ 	  strfcat(expanded_to, ",", sizeof expanded_to);
+ 	  strfcat(expanded_to, expanded_bcc, sizeof expanded_to);
+ 	}
  
! 	mailerflags[mf_idx++] = mailer;;
! 	
! 	if (strcmp(sendmail, mailer) == 0
  #ifdef SITE_HIDING
! 	    && ! is_a_hidden_user(username)
! #endif
! 	    ) {
! 	  mailerflags[mf_idx++] = "-oi";
! 	  mailerflags[mf_idx++] = "-oem";
! 	  if (sendmail_verbose)
! 	    mailerflags[mf_idx++] = "-v";
! 	  if (metoo) 
! 	    mailerflags[mf_idx++] = "-om";
! 	} else if (strcmp(submitmail, mailer) == 0)
! 	  mailerflags[mf_idx++] = "-mlrnv";
! 	else if (strcmp(execmail, mailer) == 0) {
! 	  if (sendmail_verbose)
! 	    mailerflags[mf_idx++] = "-d";
! 	  if (metoo)
! 	    mailerflags[mf_idx++] = "-m";
! 	} 
! 	
! #ifdef MIME
! #ifdef USE_8BITMIME
! 	if (MIME_info.encoding_top == ENCODING_8BIT)
! 	  mailerflags[mf_idx++] = "-B8BITMIME";
! #endif
! #ifdef USE_BINARYMIME
! 	if (MIME_info.encoding_top == ENCODING_BINARY)
! 	  /* With -BBINARYMIME lines must terminate with \r\n
! 	   * Unix's \n is _NOT_ sufficient - K E H              */
! 	  mailerflags[mf_idx++] = "-BBINARYMIME";
  #endif
! #endif
  
! #ifdef USE_DSN
! 	if (dsn & DSN_FULL) {
! 	  mailerflags[mf_idx++] = "-R";
! 	  mailerflags[mf_idx++] = "full";
! 	} else if (dsn & DSN_HDRS) {
! 	  mailerflags[mf_idx++] = "-R";
! 	  mailerflags[mf_idx++] = "hdrs";
! 	}
! 	
! 	if (dsn & DSN_NEVER) {
! 	  mailerflags[mf_idx++] = "-N";
! 	  mailerflags[mf_idx++] = "never";
! 	} else if (dsn & (DSN_SUCCESS|DSN_FAILURE|DSN_DELAY)) {	    
! 	  t[0] = '\0';
! 	  if (dsn & DSN_SUCCESS)
! 	    strfcat(t,"success", sizeof t);
! 	  if (dsn & DSN_FAILURE) {
! 	    if (t[0]) strfcat(t,",", sizeof t);
! 	    strfcat(t,"failure", sizeof t);
  	  }
! 	  if (dsn & DSN_DELAY) {
! 	    if (t[0]) strfcat(t,",", sizeof t);
! 	    strfcat(t,"delay", sizeof t);
! 	  }
! 	  mailerflags[mf_idx++] = "-N";
! 	  mailerflags[mf_idx++] = t;
  	}
+ #endif
  
+ 	mailerflags[mf_idx] = NULL;
+ 	
+ 	if (strcmp(submitmail, mailer) == 0)
+ 	  argv = mailerflags;
+ 	else {
+ 	  char **argvt = argv_from_to(expanded_to);
+ 	  argv = join_argv(mailerflags,argvt);
+ 	  free(argvt);
+ 	}
+ 		
+ 	unlink(whole_msg_file);
  	free(whole_msg_file);
  
  	fclose(reply);
  
! 	{
! 	  struct run_state RS;
! 	  int options = SY_ENV_SHELL;
! 	  int ret;
! 
! 	  if (!sendmail_verbose)
! 	    options |= SY_NOTTY;
! 
! 	  fseek (real_reply, 0, 0);
! #ifdef _POSIX_VERSION
! 	  fflush(real_reply);  /* Synzronize underlying file descriptor */
! #else
! 	  seek(fileno(real_reply),0,0);
! #endif
  
! 	  ret=start_run(&RS, options, argv, fileno(real_reply),-1);
! 	  if (ret) {
!  	    int backgrounded = 0;
! 	    int exit_code;
! 	    char title[80];
! 
! 	    elm_sfprintf(title, sizeof title,
! 			 CATGETS(elm_msg_cat, ElmSet, ElmMailTo,
! 				 "Mail to %.50s..."),
! 			 expanded_to);
! 	    ret = run_already_done(&RS,&exit_code);
! 	    if (0 == ret) {
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSendingMail,
! 				"Sending mail..."));
! 	      fflush(stdout);
! 
! #ifdef BACKGROUD_PROCESSES       /* We assume POSIX in here */
! 	      if (background_wait_time) {
!  		int tmp;
!  		dprint(4, (debugfile, 
!  			   "Sleeping ( %d seconds ) for completion!\n",
!  			   background_wait_time));
!  		tmp = sleep(background_wait_time);  
!  		/* POSIX sleep returns time in left on
!  		 * interrupt -- when sendmail terminates
! 		 * we will get interrupt (SIGCHLD signal)
! 		 */
! 		if (tmp > 0) {
! 		  dprint(4, (debugfile, 
! 			     " -- sleeping interrupted, %d seconds left!\n",
! 			     tmp));
! 		} else if (tmp < 0) {
! 		  dprint(4, (debugfile, 
! 			     " -- sleeping failed?\n",
! 			     tmp));
  		}
! 		ret = run_already_done(&RS,&exit_code);
! 		if (0 == ret) 
! 		  ret = maybe_background(&RS,&exit_code,
! 				       real_reply,title,mail_sent);
! 		if (0 == ret) {
! 		  lib_error(
! 			    CATGETS(elm_msg_cat, ElmSet, 
! 				    ElmSendingMailBackground,
! 				    "Sending mail... in background"));
! 		  fflush(stdout);
! 		  backgrounded = 1;
! 		}
!   	      } else
! #endif
! 		ret = wait_end(&RS,&exit_code);
! 	    }
! 	    if (!backgrounded)
!  	      mail_sent(real_reply,title,&RS,ret,exit_code);
! 
! 	  } else {
! 	    if (RS.save_errno)
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFailErrno,
! 				"Failed: %.30s: %.40s"),
! 			argv[0],error_description(RS.save_errno));
! 	    else
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCantStart,
! 				"Can't start %.30s"),
! 			argv[0]);
! 	  }
  	}
+ 	if (argv != mailerflags)
+ 	  free(argv);
+ 
+ 	fclose(real_reply);
  
  	/* Unlink temp file now.
  	 * This is a precaution in case the message was encrypted.
***************
*** 712,732 ****
  	 * with root privelges. The best we can do is not let this
  	 * file just hang after we're finished with it.
  	 */
! 	(void)unlink(filename);
! 
  	return(need_redraw);
  }
  
! mail_form(address, subj)
! char *address, *subj;
  {
! 	/** copy the appropriate variables to the shared space... */
  
! 	strcpy(subject, subj);
! 	strcpy(to, address);
! 	strcpy(expanded_to, address);
  
! 	return(mail(FORM, NO, NO));
  }
  
  int
--- 1066,1123 ----
  	 * with root privelges. The best we can do is not let this
  	 * file just hang after we're finished with it.
  	 */
! 	(void)unlink(cur_editfile);
! #ifdef USE_PGP
!         pgp_status=0;
! #endif
  	return(need_redraw);
+ 	
  }
  
! static void mail_sent (fd,title,rs,ret,exit_code)
!      FILE *fd; 
!      char * title;
!      struct run_state *rs;
!      int ret; 
!      int exit_code;
  {
!   char very_long_buffer[90];
  
!   lower_prompt(title);
!   if (ret < 0) 
!     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFailSignal,
! 		      "%.30s fail: Signal?"),
! 	      mailer);
!   else if (ret > 0) {
!     if (rs->save_errno)
!       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFailErrno,
! 			"Failed: %.30s: %.40s"),
! 		mailer,error_description(rs->save_errno));
!     else if (exit_code) {
!       lib_error(
! 		CATGETS(elm_msg_cat, ElmSet, 
! 			ElmMailerReturnedError,
! 			"mailer returned error status %d"), 
! 		exit_code);
!     } else
!       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMailSent, "Mail sent!"));
!   } else {
!     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLostErrno,
! 		      "%.30s lost: %.40s"),
! 	      mailer,error_description(rs->save_errno));
!   }
! }
! 
! int mail_form(current_header, address, subj)
!      struct header_rec *current_header;
!      char *address, *subj;
! {
! 	/** copy the appropriate variables to the shared space... */
  
! 	strfcpy(subject, subj, sizeof subject);
! 	strfcpy(to, address, sizeof to);
! 	strfcpy(expanded_to, address, sizeof expanded_to);
! 	return(mail(current_header,MAIL_ISFORM,NO));
  }
  
  int
***************
*** 749,768 ****
  	  Raw(ON);
  	  CleartoEOLN();
  	  if (copy_msg)
! 	    MCsprintf(msg, catgets(elm_msg_cat, ElmSet, ElmRecallLastInstead,
! 		     "Recall last kept message instead? (%c/%c) "),
! 		     *def_ans_yes, *def_ans_no);
  	  else
! 	    MCsprintf(msg, catgets(elm_msg_cat, ElmSet, ElmRecallLastKept,
! 		     "Recall last kept message? (%c/%c) "),
! 		     *def_ans_yes, *def_ans_no);
  	  do {
! 	    ch = want_to(msg, '\0', LINES-1, 0);
  	    if (ch == *def_ans_yes) {
                retransmit++;
  	      *already_has_text = TRUE;
  	    } else if (ch != *def_ans_no) {
! 	      Write_to_screen("%c??", 1, 07);	/* BEEP */
  	      if (sleepmsg > 0)
  		    sleep((sleepmsg + 1) / 2);
  	      ch = 0;
--- 1140,1161 ----
  	  Raw(ON);
  	  CleartoEOLN();
  	  if (copy_msg)
! 	    elm_sfprintf(msg, sizeof msg,
! 			 CATGETS(elm_msg_cat, ElmSet, ElmRecallLastInstead,
! 				 "Recall last kept message instead? (%c/%c) "),
! 			 *def_ans_yes, *def_ans_no);
  	  else
! 	    elm_sfprintf(msg, sizeof msg,
! 			 CATGETS(elm_msg_cat, ElmSet, ElmRecallLastKept,
! 				 "Recall last kept message? (%c/%c) "),
! 			 *def_ans_yes, *def_ans_no);
  	  do {
! 	    ch = want_to(msg, '\0', elm_LINES-1, 0);
  	    if (ch == *def_ans_yes) {
                retransmit++;
  	      *already_has_text = TRUE;
  	    } else if (ch != *def_ans_no) {
! 	      Write_to_screen(FRM("%c??"), 07);	/* BEEP */
  	      if (sleepmsg > 0)
  		    sleep((sleepmsg + 1) / 2);
  	      ch = 0;
***************
*** 777,799 ****
  	return(retransmit);
  }
  
  
  /*
   * verify_transmission() - Ask the user to confirm transmission of the
   * message.  Returns 0 to send it, -1 to forget it.
   */
! int
  verify_transmission(filename, form_p, need_redraw_p,
! 	already_has_text, copy_file, force_cmd)
! char *filename;		/* pathname to mail mssg composition file	*/
! int  *form_p;		/* pointer to form message state		*/
! int *need_redraw_p;	/* pointer to flag indicating screen stepped on	*/
! int already_has_text;	/* indicates there is already text in the mssg	*/
! char *copy_file;	/* pointer to buffer holding copy file name	*/
! int force_cmd;		/* command to do, '\0' to prompt user for cmd	*/
  {
      char *prompt_mssg;		/* message to display prompting for cmd	*/
!     char prompt_menu[SLEN];	/* menu of available commands		*/
      int bad_cmd;		/* set TRUE to bitch about user's entry	*/
      int did_prompt;		/* TRUE if cmd prompted for and entered	*/
      int prev_form;		/* "*form_p" value last time thru loop	*/
--- 1170,1254 ----
  	return(retransmit);
  }
  
+ #ifdef USE_DSN
+ 
+ void dsn_menu P_((int *));
+ void dsn_menu(dsn)
+      int * dsn;
+ {
+   static int hdr_only = 0;
+   static int failure  = 1;
+   static int delay    = 1;
+   static int success  = 0;
+   static int DSN_off  = 0;
+ 
+ #define BOL 1
+   static struct menu_item dsn_items[] = {
+     { "Return H)eaders only on FAILURE:", 'h', 3,  BOL, (char *) &hdr_only,
+       sizeof hdr_only },
+     { "Return DSN on F)AILURE         :", 'f', 5,  BOL, (char *) &failure,
+       sizeof failure },
+     { "              D)ELAY           :", 'd', 6,  BOL, (char *) &delay,
+       sizeof delay },
+     { "              S)UCCESS         :", 's', 7,  BOL, (char *) &success,
+       sizeof success },
+     { "U)se defaults (DSN off)        :", 'u', 12, BOL, (char *) &DSN_off,
+       sizeof DSN_off }
+   };
+ 
+   if (0 == *dsn)
+     DSN_off = 1;
+   else {
+     if (DSN_FULL    & *dsn) hdr_only = 0;
+     if (DSN_HDRS    & *dsn) hdr_only = 1;
+     if (DSN_SUCCESS & *dsn) success  = 1;
+     if (DSN_FAILURE & *dsn) failure  = 1;
+     if (DSN_DELAY   & *dsn) delay    = 1;
+     if (DSN_NEVER   & *dsn) { success = 0; failure = 0; delay = 0; }
+   }
+   
+   generic_menu(dsn_items,sizeof dsn_items / sizeof (struct menu_item),
+ 	       "DSN (Delivery Status Notification) Configuration",
+ 	       "DSN: ");
+ 
+   if (DSN_off) *dsn = 0;
+   else if (!success && !failure && !delay) *dsn = DSN_NEVER;
+   else {
+     int val = 0;
+     if (hdr_only) val |= DSN_HDRS;
+     else          val |= DSN_FULL;
+     if (success)  val |= DSN_SUCCESS;
+     if (failure)  val |= DSN_FAILURE;
+     if (delay)    val |= DSN_DELAY;
+ 
+     *dsn = val;
+   }
+   
+ }
+ #endif
+ 
  
  /*
   * verify_transmission() - Ask the user to confirm transmission of the
   * message.  Returns 0 to send it, -1 to forget it.
   */
! static int
  verify_transmission(filename, form_p, need_redraw_p,
! 		    already_has_text, copy_file, force_cmd, options,
! 		    dsn, copy_file_size)
!      char *filename;	    /* pathname to mail mssg composition file        */
!      int  *form_p;	    /* pointer to form message state	             */
!      int *need_redraw_p;    /* pointer to flag indicating screen stepped on  */
!      int already_has_text;  /* indicates there is already text in the mssg   */
!      char *copy_file;	    /* pointer to buffer holding copy file name	     */
!      int force_cmd;	    /* command to do, '\0' to prompt user for cmd    */
!      int options;
!      int *dsn;
!      int copy_file_size;
  {
      char *prompt_mssg;		/* message to display prompting for cmd	*/
!     char prompt_menu[SLEN],	/* menu of available commands		*/
!          prompt_menu2[SLEN];
      int bad_cmd;		/* set TRUE to bitch about user's entry	*/
      int did_prompt;		/* TRUE if cmd prompted for and entered	*/
      int prev_form;		/* "*form_p" value last time thru loop	*/
***************
*** 800,805 ****
--- 1255,1269 ----
      int cmd;			/* command to perform			*/
      char lbuf[VERY_LONG_STRING];
      int x_coord, y_coord;
+     int replying          = 0 != (options & MAIL_REPLYING);
+ #ifdef MIME
+     int have_attachments  = 0 != (options & MAIL_HAVE_ATTACHMENTS);
+ #endif
+ #ifdef USE_PGP
+     int was_pgp_encoded   = 0 != (options & MAIL_HAVE_PGP_ENCODED);
+ #endif
+ 
+ 
  
      prev_form = *form_p + 1;	/* force build of prompt strings	*/
      bad_cmd = FALSE;		/* nothing to complain about yet	*/
***************
*** 812,857 ****
  	} else if (user_level == 0) {
  	    prompt_mssg = catgets(elm_msg_cat, ElmSet, ElmVfyPromptPleaseChoose,
  		"Please choose one of the following options by parenthesized letter: s");
! 	    strcpy(prompt_menu, catgets(elm_msg_cat, ElmSet, ElmVfyMenuUser0,
! 		"e)dit message, edit h)eaders, s)end it, or f)orget it."));
  	} else {
  	    prompt_mssg = catgets(elm_msg_cat, ElmSet, ElmVfyPromptAndNow,
  		"And now: s");
  	    switch (*form_p) {
  	    case PREFORMATTED:
! 		strcpy(prompt_menu, "");
  		break;
  	    case YES:
! 		strcpy(prompt_menu, catgets(elm_msg_cat, ElmSet,
! 		    ElmVfyMenuEditForm, "e)dit form, "));
  		break;
  	    case MAYBE:
! 		strcpy(prompt_menu, catgets(elm_msg_cat, ElmSet,
! 		    ElmVfyMenuEditMake, "e)dit msg, m)ake form, "));
  		break;
  	    default:
! 		strcpy(prompt_menu, catgets(elm_msg_cat, ElmSet,
! 		    ElmVfyMenuEditMsg, "e)dit message, "));
  		break;
  	    }
! 	    strcat(prompt_menu, catgets(elm_msg_cat, ElmSet, ElmVfyMenuVfyCpy,
! 		"h)eaders, c)opy, "));
  #ifdef ISPELL
! 	    strcat(prompt_menu, catgets(elm_msg_cat, ElmSet, ElmVfyMenuIspell,
! 		"i)spell, "));
  #endif
  #ifdef ALLOW_SUBSHELL
! 	    strcat(prompt_menu, catgets(elm_msg_cat, ElmSet, ElmVfyMenuShell,
! 		"!)shell, "));
  #endif
! 	    strcat(prompt_menu, catgets(elm_msg_cat, ElmSet, ElmVfyMenuSndFgt,
! 		"s)end, or f)orget"));
  	}
  	prev_form = *form_p;
  
  	/* complain if last entry was bad */
  	if (bad_cmd) {
! 	    Write_to_screen("%c??", 1, 07);
  	    if (sleepmsg > 0)
  		sleep((sleepmsg + 1) / 2);
  	    bad_cmd = FALSE;
--- 1276,1375 ----
  	} else if (user_level == 0) {
  	    prompt_mssg = catgets(elm_msg_cat, ElmSet, ElmVfyPromptPleaseChoose,
  		"Please choose one of the following options by parenthesized letter: s");
! 	    strfcpy(prompt_menu, 
! 		    catgets(elm_msg_cat, ElmSet, ElmVfyMenuUser0,
! 			    "e)dit message, edit h)eaders, s)end it, or f)orget it."),
! 		    sizeof prompt_menu);
!             prompt_menu2[0] = '\0';
! 
! 	    /* In some conditions add these also to menu in user_level == 0 */
! #ifdef MIME
! 	    if (have_attachments)
! 	      strfcat(prompt_menu2, "a)ttachments", sizeof prompt_menu2);
! #ifdef USE_DSN
! 	    if (dsn && *dsn != 0) {
! 	      if (prompt_menu2[0]) strfcat(prompt_menu2,", ", 
! 					   sizeof prompt_menu2);
! 	      strfcat(prompt_menu2, "D)SN", sizeof prompt_menu2);
! 	    }
! #endif
! #endif
! #ifdef USE_PGP
! 	    if (replying && was_pgp_encoded) {
! 	      if (prompt_menu2[0]) strfcat(prompt_menu2,", ",
! 					   sizeof prompt_menu2);
! 	      strfcat(prompt_menu2, "p)gp", sizeof prompt_menu2);
! 	    }
! #endif
  	} else {
  	    prompt_mssg = catgets(elm_msg_cat, ElmSet, ElmVfyPromptAndNow,
  		"And now: s");
  	    switch (*form_p) {
  	    case PREFORMATTED:
! 		prompt_menu[0] = '\0';
  		break;
  	    case YES:
! 		strfcpy(prompt_menu, catgets(elm_msg_cat, ElmSet,
! 					     ElmVfyMenuEditForm, 
! 					     "e)dit form, "),
! 			sizeof prompt_menu);
  		break;
  	    case MAYBE:
! 		strfcpy(prompt_menu, catgets(elm_msg_cat, ElmSet,
! 					     ElmVfyMenuEditMake, 
! 					     "e)dit msg, m)ake form, "),
! 			sizeof prompt_menu);
  		break;
  	    default:
! 		strfcpy(prompt_menu, catgets(elm_msg_cat, ElmSet,
! 					     ElmVfyMenuEditMsg, 
! 					     "e)dit message, "),
! 			sizeof prompt_menu);
  		break;
  	    }
! 	    strfcat(prompt_menu, catgets(elm_msg_cat, ElmSet, ElmVfyMenuVfyCpy,
! 					"h)eaders, c)opy, "),
! 		    sizeof prompt_menu);
  #ifdef ISPELL
! 	    strfcat(prompt_menu, catgets(elm_msg_cat, ElmSet, ElmVfyMenuIspell,
! 					 "i)spell, "),
! 		    sizeof prompt_menu);
  #endif
  #ifdef ALLOW_SUBSHELL
! 	    strfcat(prompt_menu, catgets(elm_msg_cat, ElmSet, ElmVfyMenuShell,
! 					 "!)shell, "),
! 		    sizeof prompt_menu);
! #endif
!             /* The previous line was getting too full... */
!             prompt_menu2[0] = '\0';
! #ifdef MIME
! 	    strfcat(prompt_menu2, "a)ttachments", sizeof prompt_menu2);
! #ifdef USE_DSN
! 	    if (dsn) strfcat(prompt_menu2, ", D)SN", sizeof prompt_menu2);
! #endif
! #endif
! #ifdef USE_PGP
! 	    if (prompt_menu2[0]) strfcat(prompt_menu2,", ", 
! 					 sizeof prompt_menu2);
!             strfcat(prompt_menu2, "p)gp", sizeof prompt_menu2);
! #endif
! #ifdef USE_REMAILER
! 	    if (prompt_menu2[0]) strfcat(prompt_menu2,", ", 
! 					 sizeof prompt_menu2);
! 	    strfcat(prompt_menu2, "r)emailer", sizeof prompt_menu2);
  #endif
! 	    strfcat(prompt_menu, catgets(elm_msg_cat, ElmSet, ElmVfyMenuSndFgt,
! 					 "s)end, or f)orget"),
! 		    sizeof prompt_menu);
  	}
+ 
+ 
+ 
  	prev_form = *form_p;
  
  	/* complain if last entry was bad */
  	if (bad_cmd) {
! 	    Write_to_screen(FRM("%c??"), 07);
  	    if (sleepmsg > 0)
  		sleep((sleepmsg + 1) / 2);
  	    bad_cmd = FALSE;
***************
*** 863,879 ****
  	    force_cmd = '\0';
  	    did_prompt = FALSE;
  	} else {
! 	    MoveCursor(LINES-2, 0);
! 	    CleartoEOS();
! 	    PutLine0(LINES-2, 0, prompt_mssg);
  	    GetXYLocation(&x_coord, &y_coord);
  	    y_coord--; /* backspace over default answer */
! 	    Centerline(LINES-1, prompt_menu);
! 	    fflush(stdin);
  	    fflush(stdout);
- 	    Raw(ON); /* double check... testing only... */
  	    MoveCursor(x_coord, y_coord);
! 	    cmd = ReadCh();
  	    if (cmd == EOF)
  	      leave(0);
  	    cmd = tolower(cmd);
--- 1381,1405 ----
  	    force_cmd = '\0';
  	    did_prompt = FALSE;
  	} else {
! 	redraw:
! 	    ClearLine(elm_LINES-3);
! 	    PutLine0(elm_LINES-3, 0, prompt_mssg);
  	    GetXYLocation(&x_coord, &y_coord);
  	    y_coord--; /* backspace over default answer */
! #ifdef USE_PGP
! 	    if (replying && was_pgp_encoded &&
! 		! (pgp_status & PGP_MESSAGE)) 
! 	      PutLine0(elm_LINES-3, y_coord, "p");
! #endif
! 	    ClearLine(elm_LINES-2);
! 	    Centerline(elm_LINES-2, prompt_menu);
!             ClearLine(elm_LINES-1);
!             Centerline(elm_LINES-1, prompt_menu2);
  	    fflush(stdout);
  	    MoveCursor(x_coord, y_coord);
! 	    cmd = ReadCh(REDRAW_MARK);
! 	    if (cmd == REDRAW_MARK)
! 	      goto redraw;
  	    if (cmd == EOF)
  	      leave(0);
  	    cmd = tolower(cmd);
***************
*** 883,922 ****
  	/* handle command */
  	switch (cmd) {
  
  	case '\n':
  	case '\r':
  	case 's':
  	    if (did_prompt)
! 		Write_to_screen("Send", 0);
  	    return 0;
  	    /*NOTREACHED*/
! 
! 	case 'f': 
  	    if (did_prompt)
! 		Write_to_screen("Forget", 0);
  	    if (bytes(filename) <= 0) {
  		; /* forget about empty files */
  	    } else if (mail_only) {
! 		sprintf(lbuf, "%s/%s", home, dead_letter);
! 		(void) append_copy_to_file(to, cc, bcc, lbuf, filename,
! 		    *form_p);
  	    } else if (user_level > 0) {
! 		set_error(catgets(elm_msg_cat, ElmSet, ElmVfyMessageKept,
! 		    "Message kept.  Can be restored at next f)orward, m)ail or r)eply."));
  	    }
  	    return -1;
  	    /*NOTREACHED*/
  
  	case 'c':
  	    if (did_prompt)
! 		Write_to_screen("Copy file", 0);
! 	    if (name_copy_file(copy_file) != 0)
  		*need_redraw_p = TRUE;
  	    break;
  
  	case 'e':
  	    if (did_prompt)
! 		Write_to_screen("Edit", 0);
  	    if (*form_p == PREFORMATTED) {
  		bad_cmd = TRUE;
  	    } else {
--- 1409,1544 ----
  	/* handle command */
  	switch (cmd) {
  
+ #ifdef  MIME
+ 	case 'a':
+ 	    if (did_prompt)
+ 	        Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmVfyMenuAtttach,
+ 					"Attachments"));
+ 	  attachments = (mime_t *) attach_menu (attachments, FALSE);
+ 	  break;
+ #ifdef USE_DSN
+         case 'd':
+ 	    if (did_prompt)
+ 	        Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmVfyMenuDsn,
+ 					"Dsn"));
+ 	  if (dsn) dsn_menu(dsn);
+ 	  break;
+ #endif
+ #endif
  	case '\n':
  	case '\r':
+ #ifdef USE_PGP
+ 	      if (replying && was_pgp_encoded &&
+ 		  ! (pgp_status & PGP_MESSAGE)) 
+ 		goto select_pgp;
+ #endif
+ 		/* fall thru */
  	case 's':
  	    if (did_prompt)
! 	        Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmVfyMenuSend,
! 					"Send"));
! #ifdef USE_PGP
! 	      if (replying && was_pgp_encoded &&
! 		  ! (pgp_status & PGP_MESSAGE)) {
!               ClearLine(elm_LINES-2);
! 	      PutLine0(elm_LINES-2, 0, "The recv'd message was PGP encoded, are you sure? ");
! 	      for (;;) {
! 		cmd = ReadCh(0);
! 		if (cmd == *def_ans_yes) {
! 		  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmYesWord, 
! 					  "Yes."));
! 		  return(0);
! 		}
! 		if (cmd == *def_ans_no) {
! 		  Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmNoWord, 
! 					  "No."));
! 		  break;
! 		}
! 	      }
! 	      break;
! 	    }
! #endif /* USE_PGP */
  	    return 0;
  	    /*NOTREACHED*/
! #ifdef USE_PGP
! 	case ctrl('F'):
! 	  pgp_void_passphrase();
! 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmPassphraseForgotten,
! 			  "Passphrase forgotten!"));
! 	  break;
! #endif
!        case 'f': 
  	    if (did_prompt)
! 		Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmVfyMenuForget, 
! 					"Forget"));
  	    if (bytes(filename) <= 0) {
  		; /* forget about empty files */
  	    } else if (mail_only) {
! #ifdef MIME
! 	      FILE * fd;
! 	      mime_send_t MIME_info;
! 	      
! 	      MIME_info.encoding_top  = ENCODING_7BIT;
! 	      if ((fd = fopen(filename,"r")) != NULL) {
! 		MIME_info.msg_is_multipart = 
! 		  check_for_multipart(fd,&MIME_info);
! 		MIME_info.need_enc = needs_encoding (fd);
! 		if (allow_no_hdrencoding)
! 			MIME_info.need_enc |= check_8bit_str (subject);
! 		fclose(fd);
! 	      } else {
! 		MIME_info.msg_is_multipart = 0;
! 		MIME_info.need_enc = 0;
! 	      }
! 	      MIME_info.encoding_text =  ENCODING_7BIT;
! 	      MIME_info.Charset       =  charset;
! 	      
! 	      if (MIME_info.need_enc & HAVE_BINARY) 
! 		MIME_info.encoding_text =  ENCODING_BINARY;
! 	      else  if (MIME_info.need_enc & HAVE_8BIT) 
! 		MIME_info.encoding_text =  ENCODING_8BIT;
! 	      
! 	      update_encoding(&MIME_info.encoding_top,MIME_info.encoding_text);
! 	      
! 	      if (MIME_info.msg_is_multipart)
! 		(void) mime_generate_boundary (MIME_info.mime_boundary,
! 					       sizeof MIME_info.mime_boundary);
! 	      
! 	      elm_sfprintf(lbuf, sizeof lbuf,
! 			   FRM("%s/%s"), 
! 			   home, dead_letter);
! 	      (void) append_copy_to_file(to, cc, bcc, lbuf, filename,
! 					 *form_p, &MIME_info);
! #else
! 	      elm_sfprintf(lbuf, sizeof lbuf,
! 			   FRM("%s/%s"), 
! 			   home, dead_letter);
! 	      (void) append_copy_to_file(to, cc, bcc, lbuf, filename,
! 					 *form_p);
! #endif
  	    } else if (user_level > 0) {
! 		lib_error(CATGETS(elm_msg_cat, ElmSet, ElmVfyMessageKept,
! 				  "Message kept.  Can be restored at next f)orward, m)ail or r)eply."));
  	    }
+ #ifdef USE_PGP
+             pgp_status = 0; /* make sure to reset! */
+ #endif
  	    return -1;
  	    /*NOTREACHED*/
  
  	case 'c':
  	    if (did_prompt)
! 	      Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 				      ElmVfyMenuCopyFile, 
! 				      "Copy file"));
! 	    if (name_copy_file(copy_file, copy_file_size) != 0)
  		*need_redraw_p = TRUE;
  	    break;
  
  	case 'e':
  	    if (did_prompt)
! 		Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 					ElmVfyMenuEdit, "Edit"));
  	    if (*form_p == PREFORMATTED) {
  		bad_cmd = TRUE;
  	    } else {
***************
*** 930,936 ****
  
  	case 'h':
  	    if (did_prompt)
! 		Write_to_screen("Headers", 0);
  	    (void) edit_headers();
  	    *need_redraw_p = TRUE;
  	    break;
--- 1552,1559 ----
  
  	case 'h':
  	    if (did_prompt)
! 		Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 					ElmVfyMenuHeaders,"Headers"));
  	    (void) edit_headers();
  	    *need_redraw_p = TRUE;
  	    break;
***************
*** 944,951 ****
  		    /* couldn't open file??? */
  		    return -1;
  		case 0:
! 		    Write_to_screen(catgets(elm_msg_cat, ElmSet,
! 			ElmVfyNoFieldsInForm, "No fields in form!\007"), 0);
  		    if (sleepmsg > 0)
  			sleep(sleepmsg);
  		    break;
--- 1567,1575 ----
  		    /* couldn't open file??? */
  		    return -1;
  		case 0:
! 		    Write_to_screen(CATGETS(elm_msg_cat, ElmSet,
! 					    ElmVfyNoFieldsInForm, 
! 					    "No fields in form!\007"));
  		    if (sleepmsg > 0)
  			sleep(sleepmsg);
  		    break;
***************
*** 960,973 ****
  #ifdef ISPELL
  	case 'i':
  	    if (did_prompt)
! 		Write_to_screen("Ispell", 0);
  	    if (*form_p == PREFORMATTED) {
  		bad_cmd = TRUE;
  	    } else {
  		if (*form_p == YES)
  		    *form_p = MAYBE;
! 		sprintf(lbuf, "%s %s %s",
! 		    ISPELL_PATH, ISPELL_OPTIONS, filename);
  		system_call(lbuf, SY_ENAB_SIGHUP);
  		*need_redraw_p = TRUE;
  #ifdef ultrix
--- 1584,1599 ----
  #ifdef ISPELL
  	case 'i':
  	    if (did_prompt)
! 		Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 					ElmVfyMenuIspell2,"Ispell"));
  	    if (*form_p == PREFORMATTED) {
  		bad_cmd = TRUE;
  	    } else {
  		if (*form_p == YES)
  		    *form_p = MAYBE;
! 		elm_sfprintf(lbuf, sizeof lbuf,
! 			     FRM("%s %s %s"),
! 			     ISPELL_PATH, ISPELL_OPTIONS, filename);
  		system_call(lbuf, SY_ENAB_SIGHUP);
  		*need_redraw_p = TRUE;
  #ifdef ultrix
***************
*** 986,992 ****
  	    }
  	    break;
  #endif
! 
  	default:
  	    bad_cmd = TRUE;
  	    break;
--- 1612,1637 ----
  	    }
  	    break;
  #endif
! #ifdef USE_PGP
!         case 'p':
! 	select_pgp:
! 	    if (did_prompt)
! 	        Write_to_screen(CATGETS(elm_msg_cat, ElmSet, 
! 					ElmVfyMenuPgp,"Pgp"));
! 	    if (!pgp_status) {
! 	      pgp_status = pgp_menu (filename);
! 	      *need_redraw_p = TRUE;
! 	    }
!             else
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmPgpAlreadyEncSig,
! 				"This message is already encrypted and/or signed!"));
!             break;
! #endif
! #ifdef USE_REMAILER
! 	case 'r':
! 		remailer_menu ();
! 		break;
! #endif
  	default:
  	    bad_cmd = TRUE;
  	    break;
***************
*** 997,1008 ****
  
  }
  
- 
  FILE *
  write_header_info(filename, long_to, long_cc, long_bcc, form, copy)
! char *filename, *long_to, *long_cc, *long_bcc;
! int   form, copy;
  {
  	/** Try to open filedesc as the specified filename.  If we can,
  	    then write all the headers into the file.  The routine returns
  	    'filedesc' if it succeeded, NULL otherwise.  Added the ability
--- 1642,1658 ----
  
  }
  
  FILE *
+ #ifdef MIME
+ write_header_info(filename, long_to, long_cc, long_bcc, form, copy, mime_info)
+      mime_send_t *mime_info;
+ #else
  write_header_info(filename, long_to, long_cc, long_bcc, form, copy)
! #endif
!      char *filename, *long_to, *long_cc, *long_bcc;
!      int   form, copy;
  {
+ 
  	/** Try to open filedesc as the specified filename.  If we can,
  	    then write all the headers into the file.  The routine returns
  	    'filedesc' if it succeeded, NULL otherwise.  Added the ability
***************
*** 1014,1023 ****
  	char opentype[3];
  	time_t time(), thetime;
  	char *ctime();
! 	static FILE *filedesc;		/* our friendly file descriptor  */
          char to_buf[VERY_LONG_STRING];
  	int err;
! 
  #ifdef SITE_HIDING
  	char  buffer[SLEN];
  	int   is_hidden_user;		/* someone we should know about?  */
--- 1664,1673 ----
  	char opentype[3];
  	time_t time(), thetime;
  	char *ctime();
! 	FILE *filedesc = NULL;		/* our friendly file descriptor  */
          char to_buf[VERY_LONG_STRING];
  	int err;
! 	char fullname_buf[STRING], *qfullname = fullname_buf; 
  #ifdef SITE_HIDING
  	char  buffer[SLEN];
  	int   is_hidden_user;		/* someone we should know about?  */
***************
*** 1025,1043 ****
  #ifdef MMDF
  	int   is_submit_mailer;		/* using submit means change From: */
  #endif /* MMDF */
! 
! 	char  *get_arpa_date();
! 
! 	if(copy) 
! 	    strcpy(opentype, "r+");
! 	else
! 	    strcpy(opentype, "w+");
  
  	save_file_stats(filename);
! 
! 	filedesc = fopen(filename, opentype);
! 	if (copy && filedesc == NULL)
! 	  filedesc = fopen(filename, "w+");
  
  	if (filedesc == NULL) {
  	  err = errno;
--- 1675,1694 ----
  #ifdef MMDF
  	int   is_submit_mailer;		/* using submit means change From: */
  #endif /* MMDF */
! #ifndef DONT_ADD_FROM
! 	char from_buf[3*40+10];
! #endif
!       	char  *get_arpa_date();
  
+ 	elm_sfprintf(fullname_buf,sizeof fullname_buf,
+ 		     FRM("\"%.*s\""),
+ 		     sizeof(fullname_buf)-4,full_username);
  	save_file_stats(filename);
! 	
! 	if (copy) /* Go end of (perhaps existing) file */
! 	  filedesc = open_end_update(filename);
! 	else /* Create _new_ temporary file */
! 	  filedesc = safeopen_rdwr(filename);
  
  	if (filedesc == NULL) {
  	  err = errno;
***************
*** 1045,1063 ****
  	    "Attempt to open file %s for writing failed! (write_header_info)\n",
  	     filename));
  	  dprint(1, (debugfile, "** %s **\n\n", error_description(err)));
! 	  error2(catgets(elm_msg_cat, ElmSet, ElmErrorTryingToWrite,
! 		"Error %s encountered trying to write to %s."), 
! 		error_description(err), filename);
  	  if (sleepmsg > 0)
  		sleep(sleepmsg);
  	  return(NULL);		/* couldn't open it!! */
  	}
  
- 	if (copy) {
- 		/* Position to the end of the file */
- 		fseek(filedesc, 0L, 2);
- 	}
- 
  	restore_file_stats(filename);
  
  	if(copy) {	/* Add top line that mailer would add */
--- 1696,1709 ----
  	    "Attempt to open file %s for writing failed! (write_header_info)\n",
  	     filename));
  	  dprint(1, (debugfile, "** %s **\n\n", error_description(err)));
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorTryingToWrite,
! 			    "Error %s encountered trying to write to %s."), 
! 		    error_description(err), filename);
  	  if (sleepmsg > 0)
  		sleep(sleepmsg);
  	  return(NULL);		/* couldn't open it!! */
  	}
  
  	restore_file_stats(filename);
  
  	if(copy) {	/* Add top line that mailer would add */
***************
*** 1068,1074 ****
  	  fprintf(filedesc,"From %s %s", username, ctime(&thetime));
  #ifdef MMDF
  	} else if (strcmp(submitmail,mailer) == 0) {
! 	  sprintf(to_buf, "%s %s %s", long_to, long_cc, long_bcc);
  	  do_mmdf_addresses(filedesc, strip_parens(strip_commas(to_buf)));
  #endif /* MMDF */
  	}
--- 1714,1722 ----
  	  fprintf(filedesc,"From %s %s", username, ctime(&thetime));
  #ifdef MMDF
  	} else if (strcmp(submitmail,mailer) == 0) {
! 	  elm_sfprintf(to_buf, sizeof to_buf,
! 		       FRM("%s %s %s"), 
! 		       long_to, long_cc, long_bcc);
  	  do_mmdf_addresses(filedesc, strip_parens(strip_commas(to_buf)));
  #endif /* MMDF */
  	}
***************
*** 1076,1083 ****
  #ifdef SITE_HIDING
  	if ( !copy && (is_hidden_user = is_a_hidden_user(username))) {
  	  /** this is the interesting part of this trick... **/
! 	  sprintf(buffer, "From %s!%s %s\n",  HIDDEN_SITE_NAME,
! 		  username, get_ctime_date());
  	  fprintf(filedesc, "%s", buffer);
  	  dprint(1,(debugfile, "\nadded: %s", buffer));
  	  /** so is this perverted or what? **/
--- 1724,1733 ----
  #ifdef SITE_HIDING
  	if ( !copy && (is_hidden_user = is_a_hidden_user(username))) {
  	  /** this is the interesting part of this trick... **/
! 	  elm_sfprintf(buffer, sizeof buffer,
! 		       FRM("From %s!%s %s\n"),  
! 		       HIDDEN_SITE_NAME,
! 		       username, get_ctime_date());
  	  fprintf(filedesc, "%s", buffer);
  	  dprint(1,(debugfile, "\nadded: %s", buffer));
  	  /** so is this perverted or what? **/
***************
*** 1100,1108 ****
  	    of headers is irrelevant).  Gahhhhh....
  	**/
  
! 	fprintf(filedesc, "Subject: %s\n", subject);
  
! 	  fprintf(filedesc, "To: %s\n", format_long(long_to, strlen("To:")));
  
  	fprintf(filedesc,"Date: %s\n", get_arpa_date());
  
--- 1750,1807 ----
  	    of headers is irrelevant).  Gahhhhh....
  	**/
  
! #ifdef MIME
! 	if (!form) {
! 	  /* Our standard violations */
! 	  char OSV[100];
! 	  OSV[0] = '\0';
! 
! 	  fprintf(filedesc, "Subject: %s",mime_info ->encoded_subject);
! 	  print_EOLN(filedesc,mime_info->encoding_top);
! 	  qfullname = mime_info->encoded_fullname;
! 
! #ifndef DONT_ADD_FROM
! 	  /* Else From can still be Mime Par 2 encoded */
! 	  if (allow_no_hdrencoding && 
! 	      (check_8bit_str (mime_info ->encoded_subject) ||
! 	       is_rfc1522     (mime_info ->encoded_subject) ||
! 	       check_8bit_str (mime_info ->encoded_in_reply_to) ||
! 	       is_rfc1522     (mime_info ->encoded_in_reply_to) ||
! 	       check_8bit_str (qfullname) ||
! 	       is_rfc1522     (qfullname)))
! 	    add_parameter(OSV,"no-hdr-encoding","1",sizeof(OSV),TRUE);
! #endif
! 
! 	  if (check_8bit_str (mime_info ->encoded_subject) ||
! 	      check_8bit_str (qfullname) ||
! 	      check_8bit_str (mime_info->encoded_in_reply_to))
! 	    add_parameter(OSV,"hdr-charset",
! 			  mime_info ->Charset,sizeof(OSV),FALSE);
! 
! 	  if (strlen(mime_info->encoded_in_reply_to)) {
! 	    fprintf(filedesc, "In-Reply-To: %s", 
! 		    mime_info->encoded_in_reply_to);
! 	    print_EOLN(filedesc,mime_info->encoding_top);
! 	  }
! 
! 	  if (OSV[0]) {
! 	    fprintf(filedesc, "X-ELM-OSV: (Our standard violations) %s",OSV);
! 	    print_EOLN(filedesc,mime_info->encoding_top);
! 	  }
! 
! 	} else 
! #endif
! 	  {
! 	    fprintf(filedesc, "Subject: %s\n", subject);
! 	    qfullname = fullname_buf;	    
! 	    
! 	    if (strlen(in_reply_to) > 0)
! 	      fprintf(filedesc, "In-Reply-To: %s\n", in_reply_to);	
! 	    fprintf(filedesc, 
! 		    "X-ELM-OSV: (Our standard violations) no-mime=1; no-hdr-encoding=1\n");
! 	  }
  
! 	fprintf(filedesc, "To: %s\n", format_long(long_to, strlen("To:")));
  
  	fprintf(filedesc,"Date: %s\n", get_arpa_date());
  
***************
*** 1116,1160 ****
  # ifdef SITE_HIDING
  #    ifdef MMDF
  	if (is_submit_mailer)
! 	  fprintf(filedesc,"From: \"%s\" <%s>\n", full_username, username);
  	else
  #    endif /* MMDF */
  	if (is_hidden_user)
! 	  fprintf(filedesc,"From: \"%s\" <%s!%s!%s>\n", full_username,
! 		  hostname, HIDDEN_SITE_NAME, username);
  	else
! 	  fprintf(filedesc,"From: \"%s\" <%s!%s>\n", full_username,
! 		  hostname, username);
  # else
- #  ifdef  INTERNET
  #   ifdef  USE_DOMAIN
  #    ifdef MMDF
  	if (is_submit_mailer)
! 	  fprintf(filedesc,"From: \"%s\" <%s>\n", full_username, username);
  	else
  #    endif /* MMDF */
! 	  fprintf(filedesc,"From: \"%s\" <%s@%s>\n", full_username, 
! 		username, hostfullname);
  #   else
  #    ifdef MMDF
  	if (is_submit_mailer)
! 	  fprintf(filedesc,"From: \"%s\" <%s>\n", full_username, username);
  	else
  #    endif /* MMDF */
! 	fprintf(filedesc,"From: \"%s\" <%s@%s>\n", full_username,
! 		username, hostname);
  #   endif
- #  else
- #    ifdef MMDF
- 	if (is_submit_mailer)
- 	  fprintf(filedesc,"From: \"%s\" <%s>\n", full_username, username);
- 	else
- #    endif /* MMDF */
- 	fprintf(filedesc,"From: \"%s\" <%s!%s>\n", full_username,
- 		hostname, username);
- #  endif
  # endif
  #endif
  
  	if (cc[0] != '\0')
  	    fprintf(filedesc, "Cc: %s\n", format_long(long_cc, strlen("Cc: ")));
--- 1815,1863 ----
  # ifdef SITE_HIDING
  #    ifdef MMDF
  	if (is_submit_mailer)
! 	  elm_sfprintf(from_buf,sizeof from_buf,
! 		       FRM("%.40s"),username);
  	else
  #    endif /* MMDF */
  	if (is_hidden_user)
! 	  elm_sfprintf(from_buf,sizeof from_buf,
! 		       FRM("%.40s!%.40s!%.40s"),
! 		       hostname, HIDDEN_SITE_NAME, username);
  	else
! 	  elm_sfprintf(from_buf,sizeof  from_buf,
! 		       FRM("%.40s!%.40s"),
! 		       hostname, username);
  # else
  #   ifdef  USE_DOMAIN
  #    ifdef MMDF
  	if (is_submit_mailer)
! 	  elm_sfprintf(from_buf,sizeof from_buf,
! 		       FRM("%.40s"), 
! 		       username);
  	else
  #    endif /* MMDF */
! 	  elm_sfprintf(from_buf,sizeof from_buf,
! 		       FRM("%.40s@%.40s"),  
! 		       username, hostfullname);
  #   else
  #    ifdef MMDF
  	if (is_submit_mailer)
! 	  elm_sfprintf(from_buf,sizeof from_buf,
! 		       FRM("%.40s"), username);
  	else
  #    endif /* MMDF */
! 	elm_sfprintf(from_buf,sizeof from_buf,
! 		     FRM("%.40s@%.40s"),
! 		     username, hostname);
  #   endif
  # endif
+ 	fprintf(filedesc,"From: %s <%s>",qfullname,from_buf);
+ #ifdef MIME
+ 	print_EOLN(filedesc,mime_info->encoding_top);
+ #else
+ 	fputc('\n',filedesc);
  #endif
+ #endif
  
  	if (cc[0] != '\0')
  	    fprintf(filedesc, "Cc: %s\n", format_long(long_cc, strlen("Cc: ")));
***************
*** 1177,1185 ****
  	if (strlen(expanded_reply_to) > 0)
  	    fprintf(filedesc, "Reply-To: %s\n", expanded_reply_to);
  
- 	if (strlen(in_reply_to) > 0)
- 	    fprintf(filedesc, "In-Reply-To: %s\n", in_reply_to);
- 
  	if (strlen(user_defined_header) > 0)
  	    fprintf(filedesc, "%s\n", user_defined_header);
  
--- 1880,1885 ----
***************
*** 1189,1226 ****
  	fprintf(filedesc, "X-Mailer: ELM [version %s]\n", version_buff);
  #endif /* !NO_XHEADER */
  
! 	if (form)
  	  fprintf(filedesc, "Content-Type: mailform\n");
- #ifdef MIME
- 	else if (msg_is_multipart) {
- 	  fprintf(filedesc, "%s\n", MIME_HEADER);
- 	  fprintf(filedesc,
- 		"%s multipart/mixed; boundary=%s\n", MIME_CONTENTTYPE, MIME_BOUNDARY);
- 	}
- #endif /* MIME */
  	else {
! #ifdef	MIME
! 	  fprintf(filedesc, "%s\n", MIME_HEADER);
! 	  fprintf(filedesc, "%s text/plain; charset=%s\n",
! 		  MIME_CONTENTTYPE, charset);
! 	  fprintf(filedesc, "Content-Transfer-Encoding: %s\n",
! 		  (!strincmp ("us-ascii", charset)
! 		   && strincmp ("7bit", text_encoding))
! 		  ? "7bit" : text_encoding);
  #else
  	  fprintf(filedesc, "Content-Type: text\n");
  #endif /* MIME */
  	}
  	fprintf(filedesc, "Content-Length: ");
! 	C_L_Position[0] = ftell(filedesc);
! 	fprintf(filedesc, "          \n"); /* Print Blanks as Placeholders */
! 
! 	putc('\n', filedesc);
! 
! 	return((FILE *) filedesc);
  }
  
  copy_message_across(source, dest, copy)
  FILE *source, *dest;
  int copy;
  {
--- 1889,1934 ----
  	fprintf(filedesc, "X-Mailer: ELM [version %s]\n", version_buff);
  #endif /* !NO_XHEADER */
  
! 	if (form) 
  	  fprintf(filedesc, "Content-Type: mailform\n");
  	else {
! #ifdef MIME
! #ifdef USE_REMAILER
! 	  if (!remailing)
! 	    /* Don't write the MIME header if we are remailing.  It will be
! 	     * taken care of by the remailing code.
! 	     */
! #endif
! 	    mime_write_header (filedesc, mime_info, 1);
  #else
  	  fprintf(filedesc, "Content-Type: text\n");
  #endif /* MIME */
  	}
  	fprintf(filedesc, "Content-Length: ");
! 	cl_offset = ftell(filedesc);
! 	fprintf(filedesc, "          "); /* Print Blanks as Placeholders */
! #ifdef MIME
! 	print_EOLN(filedesc,mime_info->encoding_top);
!  	if (copy) {
! 	  fprintf(filedesc, "Status: RO");
! 	  print_EOLN(filedesc,mime_info->encoding_top);
! 	}
! 	print_EOLN(filedesc,mime_info->encoding_top);
! #else
! 	fputc('\n',filedesc);
! 	if (copy) 
! 	  fprintf(filedesc, "Status: RO\n");
! 	fputc('\n',filedesc);
! #endif
! 	return(filedesc);
  }
  
+ #ifdef MIME
+ copy_message_across(source, dest, copy, mime_info)
+ mime_send_t *mime_info;
+ #else
  copy_message_across(source, dest, copy)
+ #endif
  FILE *source, *dest;
  int copy;
  {
***************
*** 1235,1251 ****
  #ifdef MIME
  	int	text_lines = 0;
  	int	at_boundary = FALSE;
- 
- 	C_L_Position[1] = 0L;
- 	C_StartData[1] = 0L;
- 	C_EndData[1] = 0L;
- 
  #endif /* MIME */
  
! 	while (line_len = mail_gets(buffer, SLEN, source)) {
  	  if (buffer[0] == '[') {
! 	    if (strncmp(buffer, START_ENCODE, strlen(START_ENCODE))==0)
  	      crypted = TRUE;
  	    else if (strncmp(buffer, END_ENCODE, strlen(END_ENCODE))==0)
  	      crypted = FALSE;
  	    else if ((strncmp(buffer, DONT_SAVE, strlen(DONT_SAVE)) == 0)
--- 1943,1974 ----
  #ifdef MIME
  	int	text_lines = 0;
  	int	at_boundary = FALSE;
  #endif /* MIME */
  
! 	/* Reserve one byte for conversion LF -> CR LF in
! 	 * case of binary mime transmission:
! 	 */
! 	while (line_len = mail_gets(buffer, SLEN-1, source)) {
  	  if (buffer[0] == '[') {
! 	    if (strncmp(buffer, START_ENCODE, strlen(START_ENCODE))==0) {
! #ifdef MIME
! 	      if (mime_info->msg_is_multipart) {
! 		if (!at_boundary) {
! 		  print_EOLN(dest,mime_info->encoding_top);
! 		  fprintf(dest,"--%s",mime_info->mime_boundary);
! 		  print_EOLN(dest,mime_info->encoding_top);
! 		}
! 		mime_info->type_text    =  MIME_TYPE_APPLICATION;
! 		strfcpy(mime_info->subtype_text,"X-ELM-encode",
! 			sizeof mime_info->subtype_text);
! 		
! 		mime_write_header (dest, mime_info, 0);
! 		print_EOLN(dest,mime_info->encoding_top);
! 		at_boundary = FALSE;
! 	      }
! #endif
  	      crypted = TRUE;
+ 	    }
  	    else if (strncmp(buffer, END_ENCODE, strlen(END_ENCODE))==0)
  	      crypted = FALSE;
  	    else if ((strncmp(buffer, DONT_SAVE, strlen(DONT_SAVE)) == 0)
***************
*** 1256,1271 ****
  	    } else if (strncmp(buffer, MIME_INCLUDE, strlen(MIME_INCLUDE))==0) {
  	      text_lines = 0;
  	      if (!at_boundary) {
! 		if (C_L_Position[1] != 0L) {
! 		  C_EndData[1] = ftell(dest);
! 		  C_L_Position[1] = fseek(dest, C_L_Position[1], 0);
! 		  fprintf(dest, "%d", C_EndData[1] - C_StartData[1]);
! 		  fseek(dest, C_EndData[1], 0);
! 		}
! 		fprintf(dest, "\n--%s\n", MIME_BOUNDARY);
  	      }
! 	      Include_Part(dest, buffer, FALSE);
! 	      fprintf(dest, "--%s\n", MIME_BOUNDARY);
  	      at_boundary = TRUE;
  	      continue;
  #endif /* MIME */
--- 1979,1992 ----
  	    } else if (strncmp(buffer, MIME_INCLUDE, strlen(MIME_INCLUDE))==0) {
  	      text_lines = 0;
  	      if (!at_boundary) {
! 		print_EOLN(dest,mime_info->encoding_top);
! 		fprintf(dest, "--%s", mime_info->mime_boundary);
! 		print_EOLN(dest,mime_info->encoding_top);
  	      }
! 	      Include_Part(dest, buffer, FALSE, mime_info, copy);
! 	      print_EOLN(dest,mime_info->encoding_top);
! 	      fprintf(dest, "--%s", mime_info->mime_boundary);
! 	      print_EOLN(dest,mime_info->encoding_top);
  	      at_boundary = TRUE;
  	      continue;
  #endif /* MIME */
***************
*** 1276,1282 ****
  	        getkey(ON);
  	      else if (! encoded_lines)
  	        get_key_no_prompt();		/* reinitialize.. */
! 	      if (strncmp(buffer, START_ENCODE, strlen(START_ENCODE))) {
  	        encode(buffer);
  	        encoded_lines++;
  	      }
--- 1997,2003 ----
  	        getkey(ON);
  	      else if (! encoded_lines)
  	        get_key_no_prompt();		/* reinitialize.. */
! 	      if (0 != strncmp(buffer, START_ENCODE, strlen(START_ENCODE))) {
  	        encode(buffer);
  	        encoded_lines++;
  	      }
***************
*** 1291,1297 ****
  	      getkey(ON);
  	    else if (! encoded_lines)
  	      get_key_no_prompt();		/* reinitialize.. */
! 	    if (strncmp(buffer, START_ENCODE, strlen(START_ENCODE))) {
  	      encode(buffer);
  	      encoded_lines++;
  	    }
--- 2012,2018 ----
  	      getkey(ON);
  	    else if (! encoded_lines)
  	      get_key_no_prompt();		/* reinitialize.. */
! 	    if (0 != strncmp(buffer, START_ENCODE, strlen(START_ENCODE))) {
  	      encode(buffer);
  	      encoded_lines++;
  	    }
***************
*** 1298,1318 ****
  #ifdef MIME
  	  } else {
  	    if (text_lines == 0) {
! 	      if (msg_is_multipart) {
  		if (!at_boundary) {
! 	 	  fprintf(dest,"--%s\n",MIME_BOUNDARY);
  		}
! 	        fprintf(dest, "%s text/plain; charset=%s\n",
! 			MIME_CONTENTTYPE, charset);
! 		fprintf(dest, "Content-Transfer-Encoding: %s\n",
! 			(!strincmp ("us-ascii", charset)
! 			 && strincmp ("7bit", text_encoding))
! 			? "7bit" : text_encoding);
! 		fprintf(dest, "Content-Length: ");
! 		C_L_Position[1] = ftell(dest);
! 		fprintf(dest, "          \n"); /* Print Placeholders */
! 	        fprintf(dest, "\n");
! 		C_StartData[1] = ftell(dest);
  		at_boundary = FALSE;
  	      }
  	    }	
--- 2019,2034 ----
  #ifdef MIME
  	  } else {
  	    if (text_lines == 0) {
! 	      char tmp[STRING];
! 	      if (mime_info->msg_is_multipart) {
  		if (!at_boundary) {
! 		  print_EOLN(dest,mime_info->encoding_top);
! 	 	  fprintf(dest,"--%s",mime_info->mime_boundary);
! 		  print_EOLN(dest,mime_info->encoding_top);
  		}
! 
! 		mime_write_header (dest, mime_info, 0);
! 		print_EOLN(dest,mime_info->encoding_top);
  		at_boundary = FALSE;
  	      }
  	    }	
***************
*** 1320,1335 ****
  #endif /* MIME */
            }
  
  #ifndef DONT_ESCAPE_MESSAGES
  	  if (copy && (strncmp(buffer, "From ", 5) == 0)) {
  	    /* Add in the > to a From on our copy */
  	    fprintf(dest, ">");
  	    if (fwrite(buffer, 1, line_len, dest) != line_len) {
! 		MoveCursor(LINES, 0);
  		Raw(OFF);
! 		Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmWriteFailedCopyAcross,
! 			"\nWrite failed in copy_message_across\n"), 0);
! 		emergency_exit();
  	    }
  	  }
  #ifdef NEED_LONE_PERIOD_ESCAPE
--- 2036,2076 ----
  #endif /* MIME */
            }
  
+ #ifdef MIME
+ 	  if (mime_info->encoding_top == ENCODING_BINARY) {
+ 	    /* It is better perhaps use canonical eol (CRLF) when mail have
+ 	     * content transfer encoding BINARY somewhere (see notes about 
+ 	     * BINARYMIME)
+ 	     */
+ 
+ 	    if (buffer[line_len-1] == '\n') {
+ 	      int add = 1;
+ 	      if (line_len >1 && buffer[line_len-2] == '\r')
+ 		add = 0;
+ 	      if (add) {
+ 		buffer[line_len-1] = '\r';
+ 		buffer[line_len] = '\n';
+ 		line_len++;
+ 	      }	      
+ 	    }
+ 	  }
+ 
+ 	  /* Do QUOTED-PRINTABLE conversion if necessary... */
+ 	  if (mime_info->encoding_text == ENCODING_QUOTED)
+ 	    line_quoted_printable_encode(buffer,dest,copy,line_len,TRUE,
+ 					 mime_info);
+ 	  else
+ #endif
  #ifndef DONT_ESCAPE_MESSAGES
  	  if (copy && (strncmp(buffer, "From ", 5) == 0)) {
  	    /* Add in the > to a From on our copy */
  	    fprintf(dest, ">");
  	    if (fwrite(buffer, 1, line_len, dest) != line_len) {
! 		MoveCursor(elm_LINES, 0);
  		Raw(OFF);
! 		lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWriteFailedCopyAcross,
! 				  "Write failed in copy_message_across\n"));
! 		emergency_exit(0);
  	    }
  	  }
  #ifdef NEED_LONE_PERIOD_ESCAPE
***************
*** 1342,1354 ****
    	  else
  #endif /* DONT_ESCAPE_MESSAGES */
    	    if (fwrite(buffer, 1, line_len, dest) != line_len) {
! 		MoveCursor(LINES, 0);
  		Raw(OFF);
! 		Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmWriteFailedCopyAcross,
! 			"\nWrite failed in copy_message_across\n"), 0);
! 		emergency_exit();
  	    }
  	} 
  #ifdef MMDF
  	if (copy) fputs(MSG_SEPARATOR, dest);
  #else
--- 2083,2107 ----
    	  else
  #endif /* DONT_ESCAPE_MESSAGES */
    	    if (fwrite(buffer, 1, line_len, dest) != line_len) {
! 		MoveCursor(elm_LINES, 0);
  		Raw(OFF);
! 		lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 				  ElmWriteFailedCopyAcross,
! 				  "Write failed in copy_message_across\n"));
! 		emergency_exit(0);
  	    }
  	} 
+ #ifdef MIME
+ 	if (mime_info->msg_is_multipart) {
+ 	  /* now add any attachments (NEW STYLE) */
+ 	  if (attachments)
+ 	    attach_generate_message (attachments, dest, copy, mime_info);
+ 
+ 	  print_EOLN(dest,mime_info->encoding_top);
+ 	  fprintf(dest,"--%s--", mime_info->mime_boundary);
+ 	  print_EOLN(dest,mime_info->encoding_top);
+ 	}
+ #endif /* MIME */
  #ifdef MMDF
  	if (copy) fputs(MSG_SEPARATOR, dest);
  #else
***************
*** 1357,1384 ****
  }
  
  int
- verify_bounceback()
- {
- 	char	ch;
- 	char	msg[SLEN];
- 
- 	/** Ensure the user wants to have a bounceback copy too.  (This is
- 	    only called on messages that are greater than the specified 
- 	    threshold hops and NEVER for non-uucp addresses.... Returns
- 	    TRUE iff the user wants to bounce a copy back.... 
- 	 **/
- 
- 	MoveCursor(LINES,0);
- 	CleartoEOLN();
- 	MCsprintf(msg, catgets(elm_msg_cat, ElmSet, ElmBounceOffRemote,
- 	      "\"Bounce\" a copy off the remote machine? (%c/%c) "),
- 	      *def_ans_yes, *def_ans_no);
- 	ch = want_to(msg, *def_ans_no, LINES, 0);
- 	return (ch == *def_ans_yes);
- }
- 
- 
- int
  append_sig(file)
  FILE *file;
  {
--- 2110,2115 ----
***************
*** 1408,1415 ****
  	      /* if any one is different than this, then use remote sig */
  	      int len;
  	      char *ptr;
! 	      char sitename[SLEN];
! 	      sprintf(sitename,"@%s",hostfullname);
  	      len = strlen(sitename);
                sig = local_signature;
                for (ptr = index(expanded_to,'@'); ptr;  /* check To: list */
--- 2139,2147 ----
  	      /* if any one is different than this, then use remote sig */
  	      int len;
  	      char *ptr;
! 	      char sitename[SLEN];	      
! 	      sitename[0] = '@';
! 	      strfcpy(sitename+1,hostfullname, sizeof sitename -1);
  	      len = strlen(sitename);
                sig = local_signature;
                for (ptr = index(expanded_to,'@'); ptr;  /* check To: list */
***************
*** 1435,1443 ****
  
              if (sig[0]) {  /* if there is a signature file */
  	      if (sig[0] != '/')
! 	        sprintf(filename2, "%s/%s", home, sig);
  	      else
! 	        strcpy(filename2, sig);
  	      /* append the file - with a news 2.11 compatible */
  	      /* seperator if "sig_dashes" is enabled */
  	      (void) append(file, filename2, (sig_dashes ? "\n-- \n" : NULL));
--- 2167,2177 ----
  
              if (sig[0]) {  /* if there is a signature file */
  	      if (sig[0] != '/')
! 	        elm_sfprintf(filename2, sizeof filename2,
! 			     FRM("%s/%s"), 
! 			     home, sig);
  	      else
! 	        strfcpy(filename2, sig, sizeof filename2);
  	      /* append the file - with a news 2.11 compatible */
  	      /* seperator if "sig_dashes" is enabled */
  	      (void) append(file, filename2, (sig_dashes ? "\n-- \n" : NULL));
***************
*** 1450,1452 ****
--- 2184,2198 ----
  
  }
  
+ #ifdef MIME
+ static int check_8bit_str (str)
+      char *str;
+ {
+   char *s;
+ 
+   for (s = str;	*s; s++)
+     if (*s & 0x80)
+       return HAVE_8BIT;
+   return 0;
+ }
+ #endif
Index: elm2.4.ME+.50/src/menu.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/src/menu.c	Tue Nov 17 21:14:09 1998
***************
*** 0 ****
--- 1,227 ----
+ static char rcsid[] = "@(#)$Id: menu.c,v 1.2 1998/11/16 17:08:35 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *
+  *  Initially written by: Michael Elkins <elkins@aero.org>, 1995
+  *****************************************************************************/
+ 
+ /* 
+  *
+  * API for creating menus in Elm.
+  * Initially written by: Michael Elkins <elkins@aero.org>, 17 May 1995.
+  *
+  * PLEASE SEND ME ANY CHANGES YOU MAKE TO THIS API!
+  *
+  * The basic sequence of using this api is as follows:
+  *
+  *  menu_t menu;
+  *
+  *  MenuInit(&menu, "Test Menu", "Please Select an option: ", "q)uit");
+  *  for (...)
+  *    MenuAdd(&menu, "Menu item n");
+  *  for (;;) {
+  *    switch(MenuLoop(&menu)) {
+  *    case '\n':
+  *      selected_item = MenuCurrent(&menu);
+  *      MenuDestroy(&menu);
+  *      return(selected_item);
+  *    }
+  *  }
+  */
+ 
+ #include "menu.h"
+ #include "headers.h"
+ #include "me.h"
+ 
+ /* creates a new menu instance.  'm' is a pointer to a 'menu_t', 't' is the
+    menu title, 'p' is the prompt string and 'h' is a help string. 'h' may
+    be specified as NULL if no help line is desired.  */
+ void
+ MenuInit (m, t, p, h)
+ menu_t *m;
+ char *t, *p, *h;
+ {
+   int Len;
+   m->data = 0;
+   m->max = m->len = m->current = 0;
+   m->update = 1; /* so we can see something on the first MenuLoop() call! */
+ 
+   Len = strlen(t) + 1;
+   m->title = (char *) safe_malloc(Len);
+   strfcpy(m->title, t, Len);
+ 
+   Len = strlen(p) + 1;
+   m->prompt = (char *) safe_malloc(Len);
+   strfcpy(m->prompt, p, Len);
+ 
+   m->prompt_length = strlen(m->prompt);
+   if (h) {
+     Len = strlen(h) + 1;
+     m->help = (char *) safe_malloc(Len);
+     strfcpy(m->help, h, Len);
+   } else
+     m->help = 0;
+   m->pagetop = 0;
+ }
+ 
+ void
+ MenuDestroy (m)
+ menu_t *m;
+ {
+   if (m->title)
+     free(m->title);
+   if (m->prompt)
+     free(m->prompt);
+   DestroyDynamicArray(m->data);
+ }
+ 
+ int
+ MenuAdd (m, s)
+ menu_t *m;
+ char *s;
+ {
+   int Len;
+   if (m->len == m->max)
+     m->data = (char **) DynamicArray(m->data, sizeof(char*),
+ 				     &m->max, elm_LINES);
+   if (!m->data)
+     return(-1);
+ 
+   Len = strlen(s) + 1;
+   m->data[m->len] = (char *) safe_malloc(Len);
+   strfcpy(m->data[m->len], s, Len);
+ 
+   ++m->len;
+   return(0);
+ }
+ 
+ int
+ MenuPrintLine (s, voffset, isCurrent) 
+ char *s;
+ int voffset, isCurrent;
+ {
+   int size = elm_COLUMNS+1;
+   char *buf = (char*)safe_malloc(size);
+ 
+   if (!buf)
+     return(-1);
+ 
+   if (isCurrent && !arrow_cursor)
+     StartInverse();
+   elm_sfprintf(buf, size,
+ 	       FRM("%s %-*.*s"), 
+ 	       isCurrent && arrow_cursor ? "->" : "  ",
+ 	       elm_COLUMNS-4, elm_COLUMNS-4, s);
+   PutLine0 (voffset, 0, buf);
+   if (isCurrent && !arrow_cursor)
+     EndInverse();
+   free(buf);
+   return(0);
+ }
+ 
+ /* the main loop for a menu.  it takes care of moving the selection and
+    returns the command that the user selected. */
+ int
+ MenuLoop (m)
+ menu_t *m;
+ {
+   int j, key_offset;
+   int cmd;
+ 
+   for (;;) {
+     if (m->update) {
+       ClearScreen();
+       Centerline(1, m->title);
+       for (j = 0; j < elm_LINES-6 && m->pagetop + j < m->len; j++)
+ 	MenuPrintLine(m->data[m->pagetop+j], 3+j, m->pagetop+j == m->current);
+       if (m->help)
+ 	Centerline(elm_LINES-1, m->help);
+       m->update = 0;
+     }
+     PutLine0(elm_LINES-2, 0, m->prompt);
+ 
+     switch(cmd = ReadCh(REDRAW_MARK|READCH_CURSOR)) {
+     case RIGHT_MARK:
+     case PAGEDOWN_MARK:
+       if (m->pagetop + elm_LINES-6 < m->len) {
+ 	m->pagetop += elm_LINES-6;
+ 	m->current = m->pagetop;
+ 	m->update = 1;
+       } else
+ 	Centerline(elm_LINES, "You are already on the last page!");
+       break;
+     case LEFT_MARK:
+     case PAGEUP_MARK:
+       if (m->pagetop != 0) {
+ 	m->pagetop -= elm_LINES-6;
+ 	if (m->pagetop < 0)
+ 	  m->pagetop = 0;
+ 	m->current = m->pagetop;
+ 	m->update = 1;
+       } else
+ 	Centerline(elm_LINES, "You are on the first page!");
+       break;
+     case REDRAW_MARK:
+     case ctrl('L'):
+       m->update = 1;
+       break;
+     case HOME_MARK:
+     case '=': /* first item */
+       m->current = 0;
+       m->pagetop = 0;
+       m->update = 1;
+       break;
+     case '*': /* last item */
+       m->current = m->len - 1;
+       m->pagetop = m->len - elm_LINES + 6;
+       if (m->pagetop < 0)
+ 	m->pagetop = 0;
+       m->update = 1;
+       break;
+     case UP_MARK:
+     case 'k':
+     case 'K':
+     case ctrl('P'):
+ previous_entry:
+       if (m->current > 0) {
+ 	if (m->current != m->pagetop) {
+ 	  MenuPrintLine(m->data[m->current], 3 + m->current - m->pagetop, 0);
+ 	  --m->current;
+ 	  MenuPrintLine(m->data[m->current], 3 + m->current - m->pagetop, 1);
+ 	} else { /* move to the previous page */
+ 	  --m->current;
+ 	  m->pagetop -= elm_LINES-6;
+ 	  if (m->pagetop < 0)
+ 	    m->pagetop = 0;
+ 	  m->update = 1;
+ 	}
+       }
+       break;
+     case DOWN_MARK:
+     case 'j':
+     case 'J':
+     case ctrl('N'):
+     case 'n':
+ next_entry:
+       if (m->current < m->len-1) {
+ 	if (m->current < m->pagetop + elm_LINES-7) {
+ 	  MenuPrintLine(m->data[m->current], 3 + m->current -  m->pagetop, 0);
+ 	  ++m->current;
+ 	  MenuPrintLine(m->data[m->current], 3 + m->current - m->pagetop, 1);
+ 	} else { /* move to the next page */
+ 	  ++m->current;
+ 	  m->pagetop = m->current;
+ 	  m->update = 1;
+ 	}
+       } else
+ 	Centerline(elm_LINES, "You are on the last item!");
+       break;
+     default:
+       return(cmd);
+     }
+   }
+   /* not reached */
+ }
Index: elm2.4.ME+.50/src/menu2.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/src/menu2.c	Tue Nov 17 21:12:58 1998
***************
*** 0 ****
--- 1,153 ----
+ /* $Id: menu2.c,v 1.1.1.1 1998/10/15 15:36:43 hurtta Exp $
+  *
+  * This code originally written by Michael Elkins <elkins@aero.org>.
+  */
+ 
+ #include "headers.h"
+ #include "menu2.h"
+ #include "me.h"
+ #include "s_elm.h"
+ 
+ #define BOL 1
+ #define STR 2
+ #define INT 3
+ 
+ static int do_item P_((struct menu_item *));
+ static int do_item (it)
+      struct menu_item *it;
+ {
+   short len;
+   char buf[STRING];
+   int ch;
+ 
+   ClearLine (it->offset);
+   Write_to_screen (FRM("%s"),it->option);
+   len = strlen (it->option) + 1;
+   if (it->type == STR)
+     return 
+       optionally_enter (it->d.c, it->offset, len, 
+ 			OE_APPEND_CURRENT|OE_REDRAW_MARK,
+ 			it->size);
+   else if (it->type == BOL) {
+     for (;;) {
+       MoveCursor (it->offset, len);
+       CleartoEOLN ();
+       if (*(it->d.i) == TRUE)
+ 	Write_to_screen (CATGETS(elm_msg_cat, ElmSet, 
+ 				 ElmMenu2True,
+ 				 "TRUE"));
+       else if (*(it->d.i) == FALSE)
+ 	Write_to_screen (CATGETS(elm_msg_cat, ElmSet, 
+ 				 ElmMenu2False,
+ 				 "FALSE"));
+       ch = ReadCh (OE_REDRAW_MARK);
+       if (ch == EOF) 
+ 	return -1;
+       if (ch == REDRAW_MARK)
+ 	return REDRAW_MARK;
+       if (ch == '\n')
+ 	return 0;
+       else if (ch == ' ')
+ 	*(it->d.i) = *(it->d.i) ? FALSE : TRUE;
+     }
+   }
+   else if (it->type == INT) {
+     int code;
+     elm_sfprintf (buf,sizeof buf,
+ 		  FRM("%d"), *(it->d.i));
+     code = optionally_enter (buf, it->offset, len, 
+ 			     OE_APPEND_CURRENT|OE_REDRAW_MARK,
+ 			     sizeof buf);
+     if (code != 0)
+       return code;
+     *(it->d.i) = atoi (buf);
+   }
+   return 0;
+ }
+ 
+ void
+ generic_menu (items, max, title, prompt)
+      struct menu_item items[];
+      short max;
+      char *prompt, *title;
+ {
+   short i = 0;
+   char buf[STRING], buf2[STRING];
+   int ch;
+   short update = TRUE;
+   int precmd = 0;
+ 
+   ClearScreen ();
+   for (;;) {
+     if (update) {
+       Centerline (1, title);
+       for (i = 0 ; i < max ; i++) {
+ 	strfcpy(buf,items[i].option, sizeof buf);
+ 	strfcat(buf," ",sizeof buf);
+ 	if (items[i].type == BOL) {
+ 	  if (*items[i].d.i == TRUE)
+ 	    strfcat (buf, "TRUE", sizeof buf);
+ 	  else
+ 	    strfcat (buf, "FALSE", sizeof buf);
+ 	}
+ 	else if (items[i].type == STR)
+ 	  strfcat (buf, items[i].d.c, sizeof buf);
+ 	else if (items[i].type == INT) {
+ 	  elm_sfprintf (buf2, sizeof buf2,
+ 			FRM("%d"), 
+ 			*items[i].d.i);
+ 	  strfcat (buf, buf2, sizeof buf);
+ 	}
+ 	ClearLine(items[i].offset);
+ 	PutLine0 (items[i].offset, 0, buf);
+       }
+       update = FALSE;
+     }
+     ClearLine (elm_LINES-2);
+     PutLine0 (elm_LINES-2, 0, prompt);
+     if (precmd) {
+       ch = precmd;
+       precmd = 0;
+     } else
+       ch = ReadCh (REDRAW_MARK);
+     if (EOF == ch)
+       return;
+     switch (ch) {
+     case '\n':
+       return;
+     case REDRAW_MARK:
+       update = TRUE;
+       break;
+     default:
+       for (i = 0; i < max ; i++) {
+ 	if (ch == items[i].key) {
+ 	  int code = do_item (&items[i]);
+ 	  if (REDRAW_MARK == code)
+ 	    precmd = ch;
+ 	  if (-1 == code)
+ 	    return;
+ 	  update = TRUE;
+ 	  break;
+ 	}
+       }
+       if (i == max && isascii(ch)) {
+ 	for (i = 0; i < max ; i++) {
+ 	  if (isascii (items[i].key) && 
+ 	      tolower(ch) == tolower(items[i].key)) {
+ 	    int code = do_item (&items[i]);
+ 	    if (REDRAW_MARK == code)
+ 	      precmd = ch;
+ 	    if (-1 == code)
+ 	      return;
+ 	    update = TRUE;
+ 	    break;
+ 	  }
+ 	}
+       }
+     }
+   }
+   /* Not reached. */
+ }
+ 
+ 
+ 
Index: elm2.4.ME+.50/src/metapager.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/src/metapager.c	Tue Nov 17 21:12:58 1998
***************
*** 0 ****
--- 1,448 ----
+ #include <errno.h>
+ #include "headers.h"
+ #include "s_elm.h"
+ #include "me.h"
+ 
+ #ifdef MIME
+ extern int errno;
+ #endif /* MIME */
+ 
+ void
+ PressAnyKeyToContinue()
+ {
+   Raw(ON | NO_TITE);
+ redraw:
+   PutLine0(elm_LINES, 0, catgets(elm_msg_cat, ElmSet, ElmMetaPagePressAnyKey,
+ 				 "Press any key to continue..."));
+   if (ReadCh(REDRAW_MARK) == REDRAW_MARK)
+     goto redraw;
+   Raw(OFF | NO_TITE);
+   printf("\n\r");
+ }
+ 
+ metapager (fp, hdr, do_headers)
+      FILE *fp;
+      struct header_rec *hdr;
+      int do_headers;
+ {
+ 
+   int wait_ret, fork_ret, builtin = 0, matched = 0, status, len, line_len;
+   long start_offset = hdr->offset, end_offset;
+   int ch = 0;
+   char buf[VERY_LONG_STRING];
+   FILE *fpout = NULL;
+   copy_decoder_t decoder;
+   int err;				/* place holder for errno */
+   char **text = 0;
+   int text_idx = 0, text_len = 0;
+   char tempfile[STRING];
+   FILE *fpin, *tfpout;
+   int wanna_tempfile = 0;
+ 
+   /* check to see if we want the internal pager */
+   if (strincmp(pager, "builtin", 7) == 0 ||
+       strincmp(pager, "internal", 8) == 0 ||
+       (builtin_lines < 0 
+        ? hdr->lines < elm_LINES + builtin_lines 
+        : hdr->lines < builtin_lines)) {
+ 
+     builtin++;
+ 
+     decoder = select_copy_decoder(hdr);
+ 
+     /* Also [encode] [clear] requires tempfile ... */
+     if (decoder != copy_plain 
+ #ifdef MIME
+ 	&&
+ 	(decoder != copy_mime || mime_needs_processing (&hdr->mime_rec))
+ #endif
+ 	) 
+       wanna_tempfile = 1;
+   } else {
+     /* FOr simplify we use tempfile always with external pager.
+      * That way we don't need take care if pager is taken terminal
+      * before routines called from copy_message want ask decode key
+      * or passhrase from user ...
+      */
+     wanna_tempfile = 1;
+   }
+ 
+   if (wanna_tempfile) {
+     elm_sfprintf (tempfile, sizeof tempfile,
+ 		  FRM("%selm.%d"), temp_dir, getpid());
+     
+     unlink(tempfile);
+     fpout = safeopen_rdwr(tempfile);
+     unlink(tempfile); /* We can now unlink tempfile ... So nobody
+ 		       * sees data easily (and O_EXCL should prevent
+ 		       * evil playings with symlinks) ...
+ 		       */
+     if (!fpout) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmPagerFailedTmpFile,
+ 			"Failed to create temporary file!"));
+       return 0;
+     }
+     
+     dprint (1, (debugfile, "metapager(): using tempfile %s\n", tempfile));
+   } else {
+     dprint (1, (debugfile, "metapager(): [experimental] look ma!  no tempfile!\n"));
+     builtin++;
+   }
+ 
+ 
+   if (fseek (fp, hdr->offset, 0) == -1) {
+     err = errno;
+     dprint(1, (debugfile,
+ 	       "Error: seek %d bytes into file, errno %s (show_message)\n",
+ 	       hdr->offset, error_description(err)));
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSeekFailedFile,
+ 		      "ELM [seek] couldn't read %d bytes into file (%s)."),
+ 	      hdr->offset, error_description(err));	
+     return (0);
+   }
+       
+   /* this is only true if metapager() is not called from ViewAttachment() */
+   if (do_headers) {
+     if (title_messages) {
+       char buf2[STRING], buf3[STRING], buf4[STRING];
+       struct addr_item *p;
+       int l4;
+       /* first print a title line */
+       
+       elm_date_str(buf2, hdr->time_sent + hdr->tz_offset, sizeof buf2);
+       strfcat(buf2, " ", sizeof buf2);
+       strfcat(buf2, hdr->time_zone, sizeof buf2);
+       if (hdr->status & DELETED)
+ 	elm_sfprintf(buf, sizeof buf, 
+ 		     CATGETS(elm_msg_cat, ElmSet, ElmPagerStatDeleted,
+ 			     "[Deleted] %d/%d "),
+ 		     current,
+ 		     message_count);
+       else
+ 	elm_sfprintf(buf, sizeof buf,
+ 		     CATGETS(elm_msg_cat, ElmSet, ElmPagerStatMessage,
+ 			     "Message %d/%d "),
+ 		     current,
+ 		     message_count);
+       len = elm_COLUMNS - 2 - strlen(buf) - strlen(buf2);
+ 
+       if (hdr->from) {
+ 	buf4[0] = '\0';
+ 	l4 = 0;
+ 	for (p = hdr->from; p->addr && p->fullname; p++) {
+ 	  int left = len-l4;
+ 	  char *s = p->fullname[0] ? p ->fullname : p->addr;
+ 	  int l = strlen(s);
+ 	  
+ 	  if (left > sizeof buf4 - l4 -1)
+ 	    left = sizeof buf4 - l4 -1;
+ 	  if (left < 4)
+ 	    break;
+ 	  if (l4 > 0) {
+ 	    strfcat(buf4+l4,", ",left);
+ 	    left -= 2;
+ 	    l4 += 2;
+ 	  }
+ 	  strncat(buf4+l4,s,left);
+ 	  if (left < l) {
+ 	    strfcpy(buf4+l4+left-3,"...",sizeof buf4 - (l4+left-3+1));
+ 	    break;
+ 	  }
+ 	  l4 += l;
+ 	  left -= l;
+ 	}
+ 	buf4[l4] = '\0';
+ 	elm_sfprintf(buf3, sizeof buf3,
+ 		     FRM("%s%-*.*s %s"),
+ 		     buf,
+ 		     len,
+ 		     len,
+ 		     buf4,
+ 		     buf2);
+       } else if (len > 10)
+ 	elm_sfprintf(buf3, sizeof buf3,
+ 		     FRM("%s (env) %-*.*s %s"),
+ 		     buf,
+ 		     len-7,
+ 		     len-7,
+ 		     hdr->env_from,
+ 		     buf2);
+ 
+       if (builtin > 1) {
+ 	if (text_idx == text_len)
+ 	  text = (char **) DynamicArray (text, sizeof (char *), &text_len, 5);
+ 	text[text_idx] = strmcpy (text[text_idx], buf3);
+ 	text_idx++;
+       }
+       else {
+ 	fputs (buf3, fpout);
+ 	fputs ("\n", fpout);
+       }
+       
+       /** Print the subject line centered if there is enough room **/
+       if ((len = strlen(hdr->subject)) > 0 && matches_weedlist("subject:")) {
+         len = (elm_COLUMNS-len)/2;
+         if (len < 0)
+           len = 0;
+         elm_sfprintf(buf,sizeof buf,
+ 		     FRM("%*.*s%s"),
+ 		     len,len,"",hdr->subject);
+         if (builtin > 1)
+           text[text_idx++] = strmcpy(text[text_idx], buf);
+         else
+           fprintf(fpout, "%s\n", buf);
+       }
+       
+       if (builtin > 1) {
+         text[text_idx] = (char *) safe_malloc(1);
+         *text[text_idx++] = '\0';
+       }
+       else
+         fputc('\n', fpout);
+       
+       /* now some information about this message */
+       
+       buf[0]='\0';
+       if (hdr->status & EXPIRED) {
+ 	if (buf[0] == '\0')
+ 	  strfcpy(buf, "(** This message has EXPIRED", sizeof buf);
+ 	else
+ 	  strfcat(buf, ", and has EXPIRED", sizeof buf);
+       }
+       if (hdr->status & CONFIDENTIAL) {
+ 	if (buf[0] == '\0')
+ 	  strfcpy(buf, "(** This message is tagged CONFIDENTIAL", sizeof buf);
+ 	else
+ 	  strfcat(buf, ", and is tagged CONFIDENTIAL", sizeof buf);
+       }      
+       if (hdr->status & URGENT) {
+ 	if (buf[0] == '\0')
+ 	  strfcpy(buf, "(** This message is tagged URGENT", sizeof buf);
+ 	else if (hdr->status & CONFIDENTIAL)
+ 	  strfcat(buf, ", and URGENT", sizeof buf);
+ 	else
+ 	  strfcat(buf, ", and is tagged URGENT", sizeof buf);
+       }
+       
+       if (buf[0] != '\0') {
+ 	strfcat(buf, " **)", sizeof buf);
+ 	if (builtin > 1) {
+ 	  text[text_idx] = strmcpy (text[text_idx], buf);
+ 	  text_idx++;
+ 	  text[text_idx] = (char *) safe_malloc (1);
+ 	  *text[text_idx] = '\0';
+ 	  text_idx++;
+ 	}
+ 	else	  {
+ 	  fputs (buf, fpout);
+ 	  fputs ("\n\n", fpout);
+ 	}
+       }
+     }
+ 
+     /** Now do the headers. **/
+ 
+     /* read_header_line with flag = 1 terminates header with \n and marks
+      * folding with \n
+      */
+     while (0 < (line_len = read_header_line (fp, buf, VERY_LONG_STRING,
+ 					     RHL_MARK_FOLDING))) {
+       char *ptr;
+ #ifdef MMDF
+       if (strcmp (buf, MSG_SEPARATOR) == 0)
+         continue;
+ #endif
+       if (elm_filter) {
+ 	if (matches_weedlist (buf)) {
+ 	  matched = 1;
+ 	  continue;
+ 	}
+ 	else
+ 	  matched = 0;
+       }
+       
+       if (buf[0] == '\n') {
+ #ifndef MIME
+ 	start_offset = ftell(fp);
+ #endif
+ 	/* strtok -hack don't print last empty line anyway ... */
+ 
+ 	break;       
+       }
+ #ifdef MIME
+       else {
+ 	ptr = strchr(buf,':');
+ 	if (ptr && !(hdr -> status & NOHDRENCODING)) {
+ 	  char *ptr2 = ptr +1;
+ 	  int class;
+ 	  *ptr = '\0';
+ 
+ 	  class = classify_header(buf);
+ 	  dprint(12,(debugfile,"metapager: header=%s,class=%d,rest=%s\n",
+ 		     buf,class,ptr2));
+ 
+ 	  if (class & HDR_TEXT) {
+ 	    if (is_rfc1522 (ptr2))
+ 	      rfc1522_decode (ptr2, sizeof (buf) - (ptr2 - buf) -1);
+  	  } else if (class & HDR_STRUCTURED) {
+ 	    rfc1522_decode_structured(class,
+ 				      ptr2, sizeof (buf) - (ptr2 - buf) -1);
+ 	  }
+ 
+ 	  dprint(12,(debugfile,"metapager: decoded rest=%s\n",ptr2));
+ 	  *ptr = ':';
+ 	}
+       }
+ #endif
+ 
+       for (ptr = strtok(buf,"\n"); ptr; ptr = strtok(NULL,"\n")) { 
+ 	if (ptr > buf) { /* Do folding */
+ 	  --ptr;
+ 	  if (*(ptr+1) == ' ')
+ 	    *ptr = ' ';
+ 	  else
+ 	    *ptr = '\t';
+ 	}
+ 	if (builtin > 1) {
+ 	  
+ 	  if (text_idx >= text_len - 1)
+ 	    text = (char **) DynamicArray (text, sizeof (char *), &text_len, 5);
+ 	  text[text_idx] = strmcpy (text[text_idx], ptr);
+ 	  text_idx++;
+ 	}
+ 	else {
+ 	  fputs (ptr, fpout);
+ 	  fputc ('\n',fpout);
+ 	}
+       }
+     }
+   }
+ 
+   if (builtin > 1) {    
+     if (text_idx >= text_len - 1)
+       text = (char **) DynamicArray (text, sizeof (char *), &text_len, 5);
+     text[text_idx] = strmcpy (text[text_idx], "");
+     text_idx++;
+   }
+   else {
+     fputc ('\n',fpout);
+   }
+ 
+ #ifdef MIME
+   start_offset = hdr->mime_rec.offset;
+ #endif
+   
+   /* finally the body */
+ 
+   if (builtin > 1) {
+ #ifdef MIME
+     if (hdr->status & MIME_MESSAGE)
+       mime_warnings(hdr);
+ #endif
+ 
+     /* No special processing needs to take place, so just start the pager! */
+     
+ #ifdef MMDF
+     /* Shorten the size of the message such that it does not include the
+      * trailing separator.
+      */
+     ch = builtinplusplus (fp, start_offset, hdr->content_length - 5,
+                           text, text_idx);
+ #else
+     ch = builtinplusplus (fp, start_offset, hdr->content_length, text,
+                           text_idx);
+ #endif
+     DestroyDynamicArray (text);
+     return ch;
+   }
+ 
+   /* Now this does decoding of MIME and PGP */
+   copy_message(fp,hdr,
+ 	       "",fpout,CM_REMOVE_HEADER|CM_DECODE|CM_DISPLAYING);
+   rewind(fpout);
+   clear_error();
+ 
+   /** Now run the pager! **/
+ 
+   if (builtin) {
+     fseek (fpout, (long)0, 2);
+     ch = builtinplusplus (fpout, (long) 0, ftell (fpout), NULL, 0);
+     fclose (fpout);
+     return (ch);
+   }
+ 
+ 
+   /** The rest of the code is for an external pager. **/
+   Raw(OFF); /* Raw(OFF) must do in parent.... 
+ 	     * Or otherwise in Raw(ON) does not
+ 	     * have effect (because Raw (ON /OFF) 
+ 	     * does nothing if it thinks that mode is
+ 	     * already correct)
+ 	     */
+   
+   if ((fork_ret = fork()) == -1) {
+     err = errno;
+     dprint(1, (debugfile, "Error: fork failed, errno %s (metapager)\n",
+ 	       error_description(err)));
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmPreparePagerFork,
+ 		      "Could not prepare for external pager(fork()-%s)."),
+ 	      error_description(err));	
+     PressAnyKeyToContinue();
+     Raw (ON);
+     return (0);
+   } else if (fork_ret == 0) {
+     /* child fork */
+     
+     /* Direct our temporary file to standard input of child.
+      * Because we immediately unlinked it (for security reasons) 
+      * after creating we don't have name for it and
+      * we can't use < in system_call
+      */
+ 
+     if (dup2 (fileno(fpout),0) == -1) {
+       err = errno;
+       dprint(1, (debugfile, "Error: dup failed, errno %s (metapager)\n",
+ 		 error_description(err)));	
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmPreparePagerDup,
+ 			"Could not prepare for external pager(dup()-%s)."),
+ 		error_description(err));	
+       _exit(err);	
+     }
+ 
+     clear_error();
+     ClearScreen();
+     
+     /* now execute pager and exit */
+     
+     /* system_call() will return user to user's normal permissions. */
+     _exit(system_call(pager, SY_ENAB_SIGINT));
+   }
+ 
+   fclose (fpout);
+ 
+   while ((wait_ret = wait (&status)) != fork_ret && wait_ret != -1
+ 	 /* Handle possible signals ... */	 
+ 	 || wait_ret == -1 && errno == EINTR)
+     ;
+   /* turn raw on **after** child terminates in case child
+    * doesn't put us back to cooked mode after we return ourselves to
+    * raw.
+    */
+   Raw(ON | NO_TITE);
+ 
+   if (prompt_after_pager) {
+     StartBold ();
+     PutLine0 (elm_LINES, 0, catgets(elm_msg_cat, ElmSet, ElmCommandIToReturn,
+ 				    " Command ('i' to return to index): "));
+     EndBold ();
+     fflush (stdout);
+     ch = ReadCh('i' | READCH_CURSOR);
+   }
+   else
+     ch = 0;
+ 
+   Raw(OFF | NO_TITE);
+   Raw(ON);
+ 
+   return (ch == 'i' || ch == 'q' ? 0 : ch);
+ }
Index: elm2.4.ME+.50/src/mime.c
*** elm2.4.25/src/mime.c	Mon Aug 23 05:55:06 1993
--- elm2.4.ME+.50/src/mime.c	Tue Nov 17 21:12:58 1998
***************
*** 1,132 ****
  
! static char rcsid[] = "@(#)$Id: mime.c,v 5.15 1993/08/23 02:55:05 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.15 $   $State: Exp $
   *
!  *			Copyright (c) 1988-1992 USENET Community Trust
!  *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
   ******************************************************************************
!  * $Log: mime.c,v $
!  * Revision 5.15  1993/08/23  02:55:05  syd
!  * Add missing parens
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.14  1993/08/10  18:53:31  syd
!  * I compiled elm 2.4.22 with Purify 2 and fixed some memory leaks and
!  * some reads of unitialized memory.
!  * From: vogt@isa.de
!  *
!  * Revision 5.13  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.12  1993/07/20  02:41:24  syd
!  * Three changes to expand_env() in src/read_rc.c:  make it non-destructive,
!  * have it return an error code instead of bailing out, and add a buffer
!  * size argument to avoid overwritting the destination.  The first is to
!  * avoid all of the gymnastics Elm needed to go through (and occasionally
!  * forgot to go through) to protect the value handed to expand_env().
!  * The second is because expand_env() was originally written to support
!  * "elmrc" and bailing out was a reasonable thing to do there -- but not
!  * in the other places where it has since been used.  The third is just
!  * a matter of practicing safe source code.
!  *
!  * This patch changes all invocations to expand_env() to eliminate making
!  * temporary copies (now that the routine is non-destructive) and to pass
!  * in a destination length.  Since expand_env() no longer bails out on
!  * error, a do_expand_env() routine was added to src/read_rc.c handle
!  * this.  Moreover, the error message now gives some indication of what
!  * the problem is rather than just saying "can't expand".
!  *
!  * Gratitous change to src/editmsg.c renaming filename variables to
!  * clarify the purpose.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.11  1993/06/10  03:12:10  syd
!  * Add missing rcs id lines
!  * From: Syd
!  *
!  * Revision 5.10  1993/05/14  03:56:19  syd
!  * A MIME body-part must end with a newline even when there was no newline
!  * at the end of the actual body or the body is null. Otherwise the next
!  * mime boundary may not be recognized.  The same goes with the closing
!  * boundary too.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
   *
!  * Revision 5.9  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.8  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.7  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.6  1992/11/22  01:22:48  syd
!  * According to the MIME BNF, quoted strings are allowed in the value portion
!  * of a parameter.
!  * From: chk@alias.com (C. Harald Koch)
!  *
!  * Revision 5.5  1992/11/07  16:21:56  syd
!  * There is no need to write out the MIME-Version header in subparts
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.4  1992/10/30  21:10:39  syd
!  * it invokes metamail (the pseudo is because "text" isn't a legal Content-Type).
!  * in src/mime.c notplain() tries to check for text but fails because it should
!  * look for "text\n" not "text".
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.3  1992/10/25  01:47:45  syd
!  * fixed a bug were elm didn't call metamail on messages with a characterset,
!  * which could be displayed by elm itself, but message is encoded with QP
!  * or BASE64
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.2  1992/10/24  13:44:41  syd
!  * There is now an additional elmrc option "displaycharset", which
!  * sets the charset supported on your terminal. This is to prevent
!  * elm from calling out to metamail too often.
!  * Plus a slight documentation update for MIME composition (added examples)
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  
  #include "headers.h"
  #include "s_elm.h"
  
  #ifdef MIME
  
! #include <errno.h>
! #include <sys/stat.h>
  
! int check_for_multipart(filedesc)
! FILE *filedesc;
  {
    char buffer[SLEN];
    int Multi_Part = FALSE;
--- 1,29 ----
  
! static char rcsid[] = "@(#)$Id: mime.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
   ******************************************************************************
!  *  The Elm Mail System 
   *
!  *			Copyright (c) 1988-1992 USENET Community Trust
!  *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  
  #include "headers.h"
  #include "s_elm.h"
+ #include "me.h"
  
  #ifdef MIME
  
! extern int errno;
  
! int check_for_multipart(filedesc, mime_info)
!      FILE *filedesc;
!      mime_send_t *mime_info;
  {
    char buffer[SLEN];
    int Multi_Part = FALSE;
***************
*** 139,145 ****
      if (buffer[0] == '[') {
        if (strncmp(buffer, MIME_INCLUDE, strlen(MIME_INCLUDE)) == 0) {
        	Multi_Part = TRUE;
! 	if (Include_Part((FILE *)NULL, buffer, TRUE) == -1) {
  	   return(-1);
  	}
        }
--- 36,42 ----
      if (buffer[0] == '[') {
        if (strncmp(buffer, MIME_INCLUDE, strlen(MIME_INCLUDE)) == 0) {
        	Multi_Part = TRUE;
! 	if (Include_Part((FILE *)NULL, buffer, TRUE, mime_info, FALSE) == -1) {
  	   return(-1);
  	}
        }
***************
*** 148,157 ****
    return(Multi_Part);
  }
  
! Include_Part(dest, buffer, check)
! FILE *dest;
! char *buffer;
! int	check;
  {
    char *ptr;
    char *incptr;
--- 45,57 ----
    return(Multi_Part);
  }
  
! int
! Include_Part(dest, buffer, check, mime_info, copy)
!      FILE *dest;
!      char *buffer;
!      int  check;
!      mime_send_t *mime_info;
!      int copy;
  {
    char *ptr;
    char *incptr;
***************
*** 159,207 ****
    char Expanded_Filename[SLEN];
    char tmp_fn[SLEN];
    char *filename;
!   char Content_Type[SLEN];
    char Encoding[SLEN];
    char sh_buffer[SLEN];
    char Encode_Flag[3];
    int  Enc_Type;
    FILE *incfile;
-   struct stat	file_status;
    int  line_len;
  
    ptr = buffer + strlen(MIME_INCLUDE);
    while ((*ptr != '\0') && (*ptr == ' '))
      ptr++;
    incptr = Include_Filename;
!   while ((*ptr != ' ') && (*ptr != ']') && (*ptr != '\0'))
      *incptr++ = *ptr++;
    *incptr = '\0';
  
    while ((*ptr != '\0') && (*ptr == ' '))
      ptr++;
!   incptr = Content_Type;
!   while ((*ptr != ' ') && (*ptr != ']') && (*ptr != '\0'))
      *incptr++ = *ptr++;
    *incptr = '\0';
  
    while ((*ptr != '\0') && (*ptr == ' '))
      ptr++;
    incptr = Encoding;
!   while ((*ptr != ' ') && (*ptr != ']') && (*ptr != '\0'))
      *incptr++ = *ptr++;
    *incptr = '\0';
  
    if (strlen(Include_Filename) == 0) {
!     Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmNoIncludeFilename,
!                     "\n\rNo Filename given, include line ignored\n\r"), 0);
      if (sleepmsg > 0)
  	    sleep(sleepmsg);
      return(-1);
    }
!   (void) expand_env(Expanded_Filename, Include_Filename, sizeof(Expanded_Filename));
  
!   if (strlen(Content_Type) == 0) {
!     Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmNoContentTypeGiven,
!                     "\n\rNo Content-type given, include line ignored\n\r"), 0);
      if (sleepmsg > 0)
  	    sleep(sleepmsg);
      return(-1);
--- 59,147 ----
    char Expanded_Filename[SLEN];
    char tmp_fn[SLEN];
    char *filename;
!   char Primary_Type[SLEN];
!   char SubType[SLEN];
!   char Params[STRING];
    char Encoding[SLEN];
    char sh_buffer[SLEN];
    char Encode_Flag[3];
    int  Enc_Type;
    FILE *incfile;
    int  line_len;
+   int is_text;
  
    ptr = buffer + strlen(MIME_INCLUDE);
    while ((*ptr != '\0') && (*ptr == ' '))
      ptr++;
    incptr = Include_Filename;
!   while ((*ptr != ' ') && (*ptr != ']') && (*ptr != '\0') &&
! 	 (incptr < Include_Filename + sizeof(Include_Filename) -1))
      *incptr++ = *ptr++;
    *incptr = '\0';
  
    while ((*ptr != '\0') && (*ptr == ' '))
      ptr++;
!   incptr = Primary_Type;
!   while ((*ptr != ' ') && (*ptr != ']') && (*ptr != '\0') && (*ptr!='/')
! 	 && (*ptr != ';') 
! 	 && (incptr < Primary_Type + sizeof(Primary_Type) -1))
      *incptr++ = *ptr++;
    *incptr = '\0';
+   while ((*ptr != '\0') && (*ptr == ' '))
+     ptr++;
+   incptr = SubType;
+   if (*ptr == '/') {
+     ptr++;
+     while ((*ptr != '\0') && (*ptr == ' '))
+       ptr++;
+     while ((*ptr != ' ') && (*ptr != ']') && (*ptr != '\0') && (*ptr!=';')
+ 	   && (incptr < SubType + sizeof(SubType) -1))
+       *incptr++ = *ptr++;
+   }
+   *incptr = '\0';
+   while ((*ptr != '\0') && (*ptr == ' '))
+     ptr++;
+   incptr = Params;
+   while (*ptr == ';') {
+     ptr++;
+     if (incptr > Params) {
+       *incptr++ = ';';
+     } else if (*ptr == ' ')
+       ptr++;
+ 
+     while ((*ptr != '\0') && (*ptr == ' ')
+ 	   && (incptr < Params + sizeof(Params) -1))
+       *incptr++ = *ptr++;
+ 
+     while ((*ptr != ' ') && (*ptr != ']') && (*ptr != '\0') && (*ptr!=';')
+ 	   && (incptr < Params + sizeof(Params) -1))
+       *incptr++ = *ptr++;
+     while ((*ptr != '\0') && (*ptr == ' '))
+       ptr++;
+   }
+   *incptr = '\0';
  
    while ((*ptr != '\0') && (*ptr == ' '))
      ptr++;
    incptr = Encoding;
!   while ((*ptr != ' ') && (*ptr != ']') && (*ptr != '\0')
! 	 && (incptr < Encoding + sizeof(Encoding) -1))
      *incptr++ = *ptr++;
    *incptr = '\0';
  
    if (strlen(Include_Filename) == 0) {
!     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNoIncludeFilename,
! 		      "No Filename given, include line ignored"));
      if (sleepmsg > 0)
  	    sleep(sleepmsg);
      return(-1);
    }
!   (void) expand_env(Expanded_Filename, Include_Filename, 
! 		    sizeof(Expanded_Filename));
  
!   if (strlen(Primary_Type) == 0 || strlen(SubType) == 0 ) {
!     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNoContentTypeGiven,
!                     "No Content-type given, include line ignored"));
      if (sleepmsg > 0)
  	    sleep(sleepmsg);
      return(-1);
***************
*** 210,217 ****
    Enc_Type = check_encoding(Encoding);
  
    if (Enc_Type == ENCODING_ILLEGAL) {
!         Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmEncodingIsIllegal,
! 			"\n\rEncoding is illegal\n\r"), 0);
  	if (sleepmsg > 0)
  		sleep(sleepmsg);
  	return(-1);
--- 150,157 ----
    Enc_Type = check_encoding(Encoding);
  
    if (Enc_Type == ENCODING_ILLEGAL) {
!         lib_error(CATGETS(elm_msg_cat, ElmSet, ElmEncodingIsIllegal,
! 			  "Encoding is illegal"));
  	if (sleepmsg > 0)
  		sleep(sleepmsg);
  	return(-1);
***************
*** 218,397 ****
    }
  
    if (can_open(Expanded_Filename, "r")) {
!         Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmIncludeCannotAccess,
! 			"\n\rInclude File can't be accessed\n\r"), 0);
  	if (sleepmsg > 0)
  		sleep(sleepmsg);
  	return(-1);
    }
    if (check) {
  	return(0);
    }
!   if (Enc_Type == ENCODING_7BIT || Enc_Type == ENCODING_8BIT ||
! 	Enc_Type == ENCODING_BINARY || Enc_Type == ENCODING_NONE ||
! 	Enc_Type == ENCODING_EXPERIMENTAL) {
!     /* No explicit encoding, assume 7-BIT */
!     filename = Expanded_Filename;
!   } else {
!     sprintf(tmp_fn, "%semm.%d.%d", temp_dir, getpid(), getuid());
!     filename = tmp_fn;
!     if (Enc_Type == ENCODING_BASE64) {
!       strcpy(Encode_Flag, "-b");
!     } else if (Enc_Type == ENCODING_QUOTED) {
!       strcpy(Encode_Flag, "-q");
!     } else {
!       Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmUnknownEncodingInInclude,
! 		      "\n\rUnknown Encoding, include line ignored\n\r"), 0);
!       if (sleepmsg > 0)
! 	    sleep(sleepmsg);
!       return(-1);
      }
!     sprintf(sh_buffer, "mmencode %s %s >%s", Encode_Flag, Expanded_Filename,
! 			tmp_fn);
!     (void) system_call(sh_buffer, 0);
!   }
!   if ((incfile = fopen(filename, "r")) != NULL) {
!     if (stat(filename, &file_status) != 0) {
!         Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmCantStatIncludedFile,
! 			"\n\rCan't stat included File,ignored\n\r"), 0);
! 	if (sleepmsg > 0)
! 		sleep(sleepmsg);
! 	return(-1);
      }
!     fprintf(dest, "%s %s\n", MIME_CONTENTTYPE, Content_Type);
!     fprintf(dest, "Content-Name: %s\n", Include_Filename);
!     fprintf(dest, "Content-Length: %d\n", file_status.st_size);
      if (Enc_Type != ENCODING_NONE) {
! 	fprintf(dest, "Content-Transfer-Encoding: %s\n", Encoding);
      }
!     fprintf(dest, "\n");
!     while (line_len = fread(buffer, 1, sizeof(buffer), incfile)) {
!       if (fwrite(buffer, 1, line_len, dest) != line_len) {
! 	MoveCursor(LINES, 0);
! 	Raw(OFF);
!         Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmWriteFailedCopyAcross,
! 	        "\nWrite failed in copy_message_across\n"), 0);
!         emergency_exit();
!       }
!     } 
! 
! /*  write CRLF after body-part */
  
!     fprintf(dest, "\n");
! 
      fclose(incfile);
!     if (filename == tmp_fn) {
! 	unlink(tmp_fn);
!     }
!   } else {
!     MoveCursor(LINES, 0);
      Raw(OFF);
!     Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmCantOpenIncludedFile,
! 		    "\nCan't open included File\n"), 0);
!     emergency_exit();
    }
    return(0);
  }
  
- int check_encoding(Encoding)
- char *Encoding;
- {
- 	if (strlen(Encoding) == 0) return (ENCODING_NONE);
- 	if (strincmp(Encoding, ENC_NAME_7BIT, strlen(ENC_NAME_7BIT)) == 0)
- 		return (ENCODING_7BIT);
- 	if (strincmp(Encoding, ENC_NAME_8BIT, strlen(ENC_NAME_8BIT)) == 0)
- 		return (ENCODING_8BIT);
- 	if (strincmp(Encoding, ENC_NAME_BINARY, strlen(ENC_NAME_BINARY)) == 0)
- 		return (ENCODING_BINARY);
- 	if (strincmp(Encoding, ENC_NAME_QUOTED, strlen(ENC_NAME_QUOTED)) == 0)
- 		return (ENCODING_QUOTED);
- 	if (strincmp(Encoding, ENC_NAME_BASE64, strlen(ENC_NAME_BASE64)) == 0)
- 		return (ENCODING_BASE64);
- 	if (strincmp(Encoding, "x-", 2) == 0) return (ENCODING_EXPERIMENTAL);
- 	return(ENCODING_ILLEGAL);
- }
  
! needs_mmdecode(s)
! char *s;
! {
! 	char buf[SLEN];
! 	char *t;
! 	int EncType;
! 
! 	if (!s) return(1);
! 	while (*s && isspace(*s)) ++s;
! 	t = buf;
! 	while (*s && !isspace(*s) && ((t-buf) < (SLEN-1))) *t++ = *s++;
! 	*t = '\0';
! 	EncType = check_encoding(buf);
! 	if ((EncType == ENCODING_NONE) ||
! 	    (EncType == ENCODING_7BIT) ||
! 	    (EncType == ENCODING_8BIT) ||
! 	    (EncType == ENCODING_BINARY)) {
! 	    /* We don't need to go out to mmdecode, return 0 */
! 	    return(0);
! 	} else {
! 	    return(1);
! 	}
! }
  
! notplain(s)
! char *s;
  {
! 	char *t;
! 	if (!s) return(1);
! 	while (*s && isspace(*s)) ++s;
! 	if (istrcmp(s, "text\n") == 0) {
! 		/* old MIME spec, subtype now obligat, accept it as
! 		   "text/plain; charset=us-ascii" for compatibility
! 		   reason */
! 		return(0);
! 	}
! 	if (strincmp(s, "text/plain", 10)) return(1);
! 	t = (char *) index(s, ';');
! 	while (t) {
! 		++t;
! 		while (*t && isspace(*t)) ++t;
! 		if (!strincmp(t, "charset", 7)) {
! 			s = (char *) index(t, '=');
! 			if (s) {
! 				++s;
! 				while (*s && (isspace(*s) || *s == '\"')) ++s;
! 				if (!strincmp(s, display_charset, strlen(display_charset)))
! 					return(0);
! 				if (!strincmp(s, "us-ascii", 8)) {
! 					/* check if configured charset could
! 					   display us-ascii */
! 					if(charset_ok(display_charset)) return(0);
! 				}
! 			}
! 			return(1);
! 		}
! 		t = (char *) index(t, ';');
! 	}
! 	return(0); /* no charset, was text/plain */
  }
  
! int charset_ok(s)
! char *s;
  {
!     /* Return true if configured charset could display us-ascii too */
!     char buf[SLEN];	/* assumes sizeof(charset_compatlist) <= SLEN */
!     char *bp, *chset;
! 
!     /* the "charset_compatlist[]" format is: */
!     /*   charset charset charset ... */
!     bp = strcpy(buf, charset_compatlist);
!     while ((chset = strtok(bp, " \t\n")) != NULL) {
! 	bp = NULL;
! 	if (istrcmp(chset, s) == 0)
! 	    break;
!     }
! 
!     /* see if we reached the end of the list without a match */
!     if (chset == NULL) {
! 	return(FALSE);
      }
!     return(TRUE);
  }
  #endif /* MIME */
--- 158,406 ----
    }
  
    if (can_open(Expanded_Filename, "r")) {
!         lib_error(CATGETS(elm_msg_cat, ElmSet, ElmIncludeCannotAccess,
! 			"Include File can't be accessed"), 0);
  	if (sleepmsg > 0)
  		sleep(sleepmsg);
  	return(-1);
    }
+ 
+   /* Don't allow 7BIT if 8-bit charcters in any type,    
+    * don't allow 8BIT if 'binary' characters       - K E H */
+   if (Enc_Type == ENCODING_7BIT || Enc_Type == ENCODING_NONE
+       || Enc_Type == ENCODING_8BIT) {
+     
+     FILE * fp = fopen (Expanded_Filename, "r");
+     if (fp) {
+       int tmp = needs_encoding (fp);
+       if (tmp & HAVE_BINARY) {
+ 
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet,ElmIncludeBINARY,
+ 			  "Include file has BINARY data."));
+ 	
+ 	sleep_message();
+ 	
+ 	if (Enc_Type == ENCODING_7BIT || Enc_Type == ENCODING_8BIT) {
+ 	  if (check)
+ 	    return -1; /* indicate failure */
+ 	}
+ 	
+ 	Enc_Type = ENCODING_BINARY;
+ 
+       } else if ((tmp & HAVE_8BIT) && Enc_Type != ENCODING_8BIT) {
+ 	
+ 	lib_error (CATGETS(elm_msg_cat, ElmSet,ElmInclude8BIT,
+ 			   "Include file has 8BIT data."));
+ 	
+ 	sleep_message();
+ 	
+ 	if (Enc_Type == ENCODING_7BIT) {
+ 	  if (check)
+ 	    return -1; /* indicate failure */
+ 	}
+ 	
+ 	Enc_Type = ENCODING_8BIT;
+ 	
+       }
+       fclose(fp);
+     }
+   }
+ 
+   if (Enc_Type == ENCODING_8BIT) {
+ #ifndef USE_8BITMIME
+     if (allow_no_encoding < 1) {
+       Enc_Type = ENCODING_QUOTED;
+       lib_error (CATGETS(elm_msg_cat, ElmSet,ElmDoesnt8BIT,
+ 			 "Mailer (MTA) doesn't support 8BIT encoding."));
+ 
+       sleep_message();
+ 
+       if (check)
+ 	return -1; /* indicate failure */
+     }
+ #endif
+   }
+ 
+   if (Enc_Type == ENCODING_BINARY) {
+ #ifndef USE_BINARYMIME
+     if (allow_no_encoding < 2) {
+       /* Convert to QUOTED-PRINTABLE */
+       Enc_Type = ENCODING_QUOTED;
+       lib_error (CATGETS(elm_msg_cat, ElmSet,ElmDoesntBINARY,
+ 			 "Mailer (MTA) doesn't support BINARY encoding!"));
+       sleep_message();
+       if (check)
+ 	return (-1);
+     }
+ #endif
+   }
+ 
+   is_text = is_text_type(Primary_Type, SubType, Enc_Type);
+   /* 1 if is text type (true)
+    * 0 if not text type
+    * -1 if can't be encoded (ie structured) Message/ or Multipart/ 
+    */
+     
+   if (is_text < 0 && (Enc_Type == ENCODING_QUOTED ||
+ 		      Enc_Type == ENCODING_BASE64)) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet,ElmDontEncoding,
+ 		     "Content-Type don't allow encoding -- ignoring this part."));
+       sleep_message();
+       return (-1);
+   }
+ 
+ 
+   (void) update_encoding(&(mime_info->encoding_top),Enc_Type);
+ 
    if (check) {
  	return(0);
    }
! 
!   incfile = fopen (Expanded_Filename, "r");
!   if (incfile) {
! 
!     dprint (10, (debugfile, 
! 		 "Include_Part: '%s' C-T=%s/%s Params=%s Enc=%d is_text=%d\n",
! 		 Expanded_Filename,Primary_Type,SubType, Params, Enc_Type,
! 		 is_text));
! 
!     fprintf(dest, "%s %s/%s", MIME_CONTENTTYPE, Primary_Type, SubType);
!     if (Params[0] == '\0') 
!       print_EOLN(dest,mime_info->encoding_top);
!     else { 
!       if (strlen(Primary_Type) + strlen(SubType) + strlen(Params) > 60) {
! 	fprintf(dest,";");
! 	print_EOLN(dest,mime_info->encoding_top);
! 	fputc('\t',dest);
!       } else
! 	fprintf(dest,"; ");
!       fprintf(dest,"%s",Params);
!       print_EOLN(dest,mime_info->encoding_top);
      }
! 
!     {
!       char buf[STRING];
!       buf [0] = 0;
! 
!       add_parameter(buf,"filename",Include_Filename,sizeof(buf),0);
!       
!       /* When user uses [include ...] it is better use disposition
!        * 'inline' instead of 'attachment'
!        */
!       fprintf(dest,"Content-Disposition: inline; %s",buf);
!       print_EOLN(dest,mime_info->encoding_top);
      }
! 
      if (Enc_Type != ENCODING_NONE) {
!       if (Enc_Type < ENCODING_EXPERIMENTAL) 
! 	fprintf(dest, "%s %s", MIME_CONTENTENCOD, 
! 		ENCODING(Enc_Type));
!       else /* For ENCODING_EXPERIMENTAL */
! 	fprintf(dest, "%s %s", MIME_CONTENTENCOD, Encoding);
!       print_EOLN(dest,mime_info->encoding_top);
      }
!     print_EOLN(dest,mime_info->encoding_top);
  
!     /* encoding rules are different for text and no text 
!      * for text we must do \n -> \r\n before base64 encoding */
!     
!     /* For ENCODING_EXPERIMENTAL this is already supposed to be encoded */
!     (void)write_encoded(incfile,dest,Enc_Type,copy,is_text,mime_info);
!     
      fclose(incfile);
!   }
!   else {
!     MoveCursor(elm_LINES, 0);
      Raw(OFF);
!     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCantOpenIncludedFile,
! 		    "Can't open included File"));
!     emergency_exit(0);
    }
    return(0);
  }
  
  
! /* Determine whether or not the data in "fp" needs to be QUOTED-PRINTABLE
!     encoded.  Used when sending a message.
!        1 == have 8bit data                (HAVE_8BIT)
!        4 == have control charcters        (HAVE_CTRL)
!        8 == mime requires encoding BINARY (HAVE_BINARY)
! */
  
! int needs_encoding (fp)
!      FILE *fp;
  {
!   int ch;
!   int ret = FALSE;
!   int len = 0;
! 
!   rewind (fp);
!   while ((ch = fgetc (fp)) != EOF) {
!     /* check for end of line */
!     if (ch == 13) {   /* CR */
!       ch = fgetc(fp);
!       if (ch != 10) {  /* Not CR LF */
! 	dprint (3, (debugfile, "\nneeds_encoding(): found CR without LF\n"));
! 	ret |= HAVE_BINARY;
!       }
!       if (ch == EOF)
! 	break;
!     }
!     if (ch == 10) {
!       len = 0;
!       continue; /* skip newlines and tabs */
!     }
!     len++;
!     if (len > 990) {
!       dprint (3, (debugfile,"\nneeds_encoding(): Line over 990 characters\n"));
! 	ret |= HAVE_BINARY;
!     }
! 
!     if (ch == 9) /* skip newlines and tabs */
!       continue;
!     if (ch < 32 || ch > 126) {
!       dprint (3, (debugfile, "\nneeds_encoding(): found char decimal=%d\n", ch));
!       if (ch == 0) 
! 	ret |= HAVE_BINARY;
!       if (ch < 32 || ch == 127)
! 	ret |= HAVE_CTRL;
!       if (ch > 127)
! 	ret |= HAVE_8BIT;
!     }
!     if (ret == (HAVE_8BIT | HAVE_CTRL | HAVE_BINARY))
!       break;
! 
!   }
!   rewind (fp);
!   return (ret);
  }
  
! char *error_description();
! 
! int have_metamail()
  {
!   int return_value = 1;
!   
!   if (strcmp(metamail_path,"none") == 0 || 
!       metamail_path[0] == '\0') {
!     return_value = 0;
!   } else if (metamail_path[0] == '/') {
!     if (-1 == access(metamail_path,EXECUTE_ACCESS)) {
!       int err = errno;
!       lib_error(CATGETS(elm_msg_cat, ElmSet,ElmCantMetamail,
! 			"Can't execute metamail: %s.30: %.30s"),
! 	     metamail_path,
! 	     error_description(err));
!       dprint(5,(debugfile,"have_metamail: no access %s: %s\n",metamail_path,
! 		error_description(err)));
!       sleep_message();
!       return_value = 0;
      }
!   }
! 
!   dprint(5,(debugfile,"have_metamail=%d\n",return_value));
!   return return_value;
  }
+ 
  #endif /* MIME */
+ 
Index: elm2.4.ME+.50/src/mime_encode.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/src/mime_encode.c	Tue Nov 17 21:12:57 1998
***************
*** 0 ****
--- 1,1004 ----
+ static char rcsid[] = "@(#)$Id: mime_encode.c,v 1.2 1998/10/21 15:13:22 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *
+  *  Initially written by: Michael Elkins <elkins@aero.org>, 1995
+  *****************************************************************************/
+ 
+ #include <string.h>
+ 
+ #include "headers.h"
+ #include "s_elm.h"
+ #include "me.h"
+ 
+ #ifdef MIME
+ #include <sys/time.h>
+ 
+ extern short mime_count;
+ 
+ static char base64chars[64] = {
+ 	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+ 	'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
+ 	'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ 	'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+ 	'4', '5', '6', '7', '8', '9', '+', '/'
+ };
+ #define to64(c) (((c) >= 0) && ((c) < 64)) ? base64chars[(c)] : -1
+ 
+ static char hexchars[16] = {
+ 	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
+ 	'E', 'F',
+ };
+ 
+ int
+ update_encoding(top_encoding,encoding)
+ int *top_encoding;
+ int encoding;
+ {
+   if (encoding == ENCODING_8BIT &&
+       (*top_encoding) != ENCODING_BINARY)
+     (*top_encoding) = ENCODING_8BIT;
+   if (encoding == ENCODING_BINARY)
+     (*top_encoding) = ENCODING_BINARY;
+   
+   return (*top_encoding);
+ }
+ 
+ static void write_failed P_((void)) {
+   MoveCursor(elm_LINES, 0);
+   Raw(OFF);
+   lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWriteFMimeEncode,
+ 		    "Write failed in mime_encode\n"));
+   emergency_exit(0);
+ }
+ 
+ #define ERROR_EOF(x) do { \
+    int error_eof = (x); if (EOF == error_eof) write_failed(); } while(0)
+ 
+ 
+ void
+ print_EOLN(fp,top_encoding) 
+      FILE *fp;
+      int top_encoding;
+ {  /* Write canoniocal end of line of we are sending binary mail */
+   if (top_encoding == ENCODING_BINARY)
+     ERROR_EOF(fputc('\r',fp));
+   ERROR_EOF(fputc('\n',fp));
+ }
+ 
+ char *
+ mime_generate_boundary (str, size)
+      char *str;
+ {
+   time_t t = time (NULL);
+ 	
+   elm_sfprintf (str, size,
+ 		FRM("ELM%d-%d-%d_"), t, getpid(), mime_count++);
+   return str;
+ }
+ 
+ void 
+ add_parameter_t (t,name,value,quoted) 
+      mime_t *t;
+      char *name, *value;
+      int quoted;
+ {
+   char buffer[1025];
+ 
+   if (t->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"add_paramater_t",
+ 	       "Bad magic number");
+ 
+   buffer[0] = '\0';
+ 
+   if (t->type_opts)
+     strfcpy(buffer,t->type_opts,sizeof(buffer));
+ 
+   add_parameter(buffer,name,value,sizeof buffer,quoted);
+ 
+   t->type_opts = strmcpy(t->type_opts,buffer);
+ }
+ 
+ 
+ void 
+ add_parameter(opts,name,value,size,quoted) 
+      char *opts, *name, *value;
+      int size, quoted;
+ {
+   int len = strlen(opts);
+   int ln = strlen(name);
+   char * ptr = opts + len, *c;
+   int need_quotation = 0;
+   
+   /* Following characters require quotation: ( ) < > @ , ; : \ " / [ ] ? =
+    * Also whitespace requires quotation. See Mime Draft Standard
+    */
+   if (!quoted && (NULL != strpbrk(value,"()<>@,;:\\\"/[]?= \t")
+ 		  || value[0] == '\0'))
+     need_quotation = 1;
+ 
+   if (len + strlen(value) + ln + 4 + 2 * need_quotation > size)
+     return; /* Don't fit anyway */
+ 
+   if (ptr != opts) {
+     *ptr++ = ';'; *ptr++ = ' ';
+   }
+   strfcpy(ptr,name, size - (ptr-opts));  ptr += ln;
+   *ptr++ = '=';
+ 
+   if (need_quotation) 
+     *ptr++ = '"';
+ 
+   for (c = value; *c != '\0'; c++) {
+     if (need_quotation && ('\\' == *c || '"' == *c)) {
+       if (ptr < opts + size - 3) {
+ 	*ptr++ = '\\';
+ 	*ptr++ = *c;
+       } else
+ 	break;
+     } else {
+       if (ptr < opts + size - need_quotation - 1) 
+ 	*ptr++ = *c;
+       else
+ 	break;
+     }
+   }
+ 
+   if (need_quotation) 
+     *ptr++ = '"';
+   *ptr = '\0';
+   return;
+ }
+ 
+ /* Prototype */
+ void write_encoded P_((FILE *, FILE *, int, int, int, mime_send_t *));
+ 
+ /* For some ANSI C compilers 'char *' and 'unsigned char *' are incompatible
+  * types -- we don't use casting macro here because it disables type checking
+  * altogether:
+  */
+ static char * std_str P_((unsigned char * str));
+ static char * std_str(str) 
+      unsigned char *str;
+ { 
+   return (char *)str; 
+ 
+ }
+ 
+ static int rfc1522_encode_word(buf,size,source, hibit) 
+      unsigned char *buf, *source;
+      int size,hibit;
+ {
+   unsigned char * walk, * walk2, * startptr = NULL;
+   char * Charset = charset;
+   int charsetlen;
+ 
+   dprint (14, (debugfile, 
+ 	      "rfc1522_encode_word: (buf)size=%d, source='%s', hibit=%d\n",
+ 	      size,source,hibit));
+ 
+   size--; /* Space of \0 in end */
+ 
+   if (! hibit) { /* No 8-bit characters */
+     /* We assume that in headers we don't use other 7-bit charset
+      * than US-ASCII !
+      */
+     Charset = "us-ascii";
+   } else if (istrcmp(charset, "us-ascii") == 0) {
+     if (istrcmp(display_charset, "us-ascii") != 0 && 
+ 	charset_ok(display_charset))
+       Charset=display_charset;	    
+     else if (istrcmp(charset,"us-ascii") == 0) {
+       static int message_printed = 0;
+      
+       if (!message_printed) {
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmHeaderUsingUNKNOWN8BIT,
+ 			  "Header has 8BIT data and charset=US-ASCII, using charset=UNKNOWN-8BIT instead."));
+ 	sleep_message();
+ 	message_printed = 1;
+       }
+      
+       Charset = "UNKNOWN-8BIT";
+     }
+   }
+   
+   /* Even when we can use charset names what have space (they have
+    * plenty of them in ASSIGNED NUMBERS -- STD 3 (RFC 1700) --
+    * we can't use them in RFC 1522 encoded words!!!
+    */
+   if (0 != strpbrk(Charset," \t\r\n()\"")) {
+     static int message_printed = 0;
+     
+     if (!message_printed) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmHeaderBadCharset,
+ 			"Bad charset=%s, using charset=UNKNOWN-8BIT instead."),
+ 		Charset);
+       sleep_message();
+       message_printed = 1;
+     }
+     
+     Charset = "UNKNOWN-8BIT";
+   } 
+ 
+   charsetlen = strlen(Charset);
+   
+ #define LEFT (size - (walk2 - buf))
+   for (walk=source, walk2=buf; *walk != '\0'; walk++) {
+     if (startptr && (walk2 - startptr) > 60) {
+       *walk2++ = '?';
+       *walk2++ = '=';
+       dprint (14, (debugfile, 
+ 		  "rfc1522_encode_word> [%d] -> [%d] Encoded word: %.*s\n",
+ 		  walk-source,walk2-buf,walk2-startptr,startptr));
+       *walk2++ = ' ';
+       startptr = NULL;
+     }
+     
+     if (!startptr) {
+       /* Print start of encoded word */
+       if (LEFT < 11 + charsetlen) {
+ 	dprint (14, (debugfile, 
+ 		    "rfc1522_encode_word> [%d] -> [%d] No space left; bailing out\n",
+ 		    walk-source,walk2-buf));
+ 	break;
+       }
+       startptr = walk2;
+       *walk2++ = '=';  *walk2++ = '?';
+       strfcpy(std_str(walk2),Charset, LEFT); 
+       walk2 += charsetlen;
+       *walk2++ = '?'; *walk2++ = 'Q';
+       *walk2++ = '?';    
+     }
+     if (LEFT <= 5) {
+       dprint (14, (debugfile, 
+ 		  "rfc1522_encode_word> [%d] -> [%d] No space left; bailing out\n",
+ 		  walk-source,walk2-buf));
+       break;
+     }
+ 
+     if (NULL != strchr(" \r\n",*walk)) { /* Treat as space */
+       *walk2++ = '_';
+     } else if ((*walk >= 'A' && *walk <= 'Z') || 
+ 	       (*walk >= 'a' && *walk <= 'z') ||
+ 	       (*walk >= '0' && *walk <= '9')) { /* Can be copien always */
+       *walk2++ = *walk;
+     } else { /* Encode */
+       unsigned char value = *walk;
+       *walk2++ = '=';
+       *walk2++ = hexchars[value / 16];
+       *walk2++ = hexchars[value % 16];
+     }
+ 
+   }
+   if (startptr) {
+     *walk2++ = '?';
+     *walk2++ = '=';
+     dprint (14, (debugfile, 
+ 		"rfc1522_encode_word> [%d] -> [%d] Encoded word: %.*s\n",
+ 		walk-source,walk2-buf,walk2-startptr,startptr));
+     startptr = NULL;
+   }
+   *walk2='\0';
+ #undef LEFT
+ 
+   dprint (14, (debugfile, 
+ 	      "rfc1522_encode_word=%d; RESULT: '%s'\n",
+ 	      walk2 - buf,buf));
+   return walk2 - buf;
+ }
+ 
+ void rfc1522_encode_text(buf,size,source,flag) 
+      char *buf;
+      const char *source;
+      int size, flag;
+ {
+   /* If flag & HDR_PHRASE, then consider that to be phrase */
+   /* if flag & HDR_COMMENT, we are encoding of comment     */
+ 
+   unsigned char * walk, * walk2, * prvptr;
+   unsigned char * ubuf = (unsigned char *) buf;
+   unsigned tlen;
+   int was_encoded = 0;
+   
+   dprint (14, (debugfile, 
+ 	      "rfc1522_encode_text: (buf)size=%d, flag=%d, source='%s'\n",
+ 	      size,flag,source));
+ 
+   size--; /* Space of \0 in end */
+ 
+   for (walk = (unsigned char *)source, walk2 = ubuf, prvptr = walk; 
+        *walk; 
+        prvptr = walk, walk += tlen) {
+     unsigned hibit = 0, qchar = 0;
+     unsigned char *uptr, *work = walk, * workprvptr = prvptr;
+     unsigned is_encoded = 0, worklen;
+ 
+     { /* rfc822_toklen can't be used in here!! 
+        * Notice: (char *) != (unsigned char *)
+        */
+       char * nwalk = (char *)walk;
+       char * nptr;
+ 
+       if (flag & HDR_PHRASE) 
+ 	nptr = qstrpbrk(nwalk," \t\r\n") ;
+       else if (flag & HDR_COMMENT) 
+ 	nptr = blstrpbrk(nwalk," \t\r\n()");
+       else
+ 	nptr = strpbrk(nwalk," \t\r\n");
+ 
+       if (NULL == nptr)      tlen = strlen(nwalk);
+       else if (nwalk == nptr) { 
+ 	/* Special handle this */
+ 	tlen = 1;
+ 	if ('(' == *nptr || ')' == *nptr) {
+ 	  dprint (14, (debugfile, 
+ 		       "rfc1522_encode_text> comment; word = '%.*s', was_encoded=%d\n",
+ 		       tlen,walk,was_encoded));
+ 	  was_encoded = 0;
+ 	} else {
+ 	  dprint (14, (debugfile, 
+ 		       "rfc1522_encode_text> SPACE; word = '%.*s', was_encoded=%d\n",
+ 		       tlen,walk,was_encoded));
+ 	}
+ 	if (walk2 < ubuf + size) {
+ 	  *walk2++ = *walk;
+ 	  continue;
+ 	} else
+ 	  break;
+       }
+       else                  tlen = nptr - nwalk;
+     }
+     worklen = tlen;
+ 
+     for (uptr = walk; uptr < walk + tlen ; uptr++)
+       if (*uptr & 128) 
+ 	hibit++;
+ 
+     /* Check if current word is valid encoded word */
+     if (0 == hibit && tlen > 9 && walk[0] == '=' && walk[1] == '?' &&
+ 	walk[tlen-1] == '=' && walk[tlen-2] == '?') {
+       unsigned char *ptr4;
+       int count = 0;
+       for (ptr4 = walk; ptr4 - walk < tlen; ptr4++) {
+ 	if (*ptr4 == '?')
+ 	  count++;
+ 	if (NULL != strchr(" \t\r\n",*ptr4)) {
+ 	  count = -1;
+ 	  break;
+ 	}
+       }
+       if (4 == count)
+ 	is_encoded = 1;
+     }
+     dprint (14, (debugfile, 
+ 		"rfc1522_encode_text> word = '%.*s', is_encoded=%d, hibit=%d\n",
+ 		tlen,walk,is_encoded,hibit));
+ 
+     /* Remove quotes from phrase */
+     if (flag & HDR_PHRASE) {
+       unsigned char *cptr;
+       int q = 0;
+       int plus = walk - prvptr;
+       workprvptr = (unsigned char *) safe_malloc(tlen+1+plus);
+       work = workprvptr+plus;
+       cptr = workprvptr;
+       for (uptr = prvptr; uptr < walk ; uptr++) 
+ 	*cptr++ = *uptr;
+ 
+       if (cptr != work) {
+ 	dprint (1, (debugfile, 
+ 		    "rfc1522_encode_text> FAIL! cptr != work; plus=%d\n",
+ 		    plus)); 
+       }
+ 
+       cptr = work;
+       for (uptr = walk; uptr < walk + tlen ; uptr++) {
+ 	if (q) {
+ 	  *cptr++ = *uptr;
+ 	  q = 0;
+ 	} else if ('\\' == *uptr)
+ 	  q = 1;
+ 	else if ('"' != *uptr)
+ 	  *cptr++ = *uptr;
+       }
+       worklen = cptr - work;    
+ 
+ 
+       /* Number of characters what needs quotation */
+       for (uptr = work; uptr < work + worklen ; uptr++)
+ 	if (NULL != strchr("()\\.[]\",;@:'",*uptr))
+ 	  qchar++;    
+       /* ' added to set because sendmail otherwise will quote words
+        * which includes ' on pharses -- even that ' is not special
+        * character -- and that way destroy mime encoding.
+        */
+ 	 
+     }
+ 
+     dprint (14, (debugfile, 
+ 		"rfc1522_encode_text> work = '%.*s', qchar=%d\n",
+ 		worklen,work,qchar));
+ 
+     { unsigned char safe = work[worklen];
+       int rlen = 0;
+       int left = size - (walk2 - ubuf);
+       work[worklen] = 0;
+ 
+       dprint (14, (debugfile, 
+ 		  "rfc1522_encode_text> workprvptr = '%s', was_encoded=%d\n",
+ 		  workprvptr,was_encoded));
+ 
+       if (left > 0) {
+ 	if (hibit || is_rfc1522(std_str(work)) && !is_encoded) {
+ 	  /* Encode string */
+ 	  if (was_encoded && NULL != strchr(" \t",workprvptr[0]))
+ 	    rlen = rfc1522_encode_word(walk2,left+1,workprvptr,hibit);
+ 	  else
+ 	    rlen = rfc1522_encode_word(walk2,left+1,work,hibit);
+ 	  is_encoded = (rlen > 0);
+ 	} else if (qchar) {
+ 	  /* quote string */
+ 	  unsigned char * cptr = walk2;
+ 
+ 	  if (cptr + 1 < walk2 + left) *cptr++ = '"';
+ 	  else break;
+ 	  for (uptr = work; uptr < work + worklen ; uptr++) {
+ 	    if ('"' == *uptr || '\\' == *uptr) {
+ 	      if (cptr +2 < walk2 + left) {
+ 		*cptr++ = '\\';
+ 		*cptr++ = *uptr;
+ 	      }
+ 	    } else {
+ 	      if (cptr + 1 < walk2 + left) *cptr++ = *uptr;
+ 	    }
+ 	  }
+ 	  if (cptr < walk2 + left) *cptr++ = '"';
+ 	  rlen = cptr - walk2;
+ 	} else {
+ 	  /* copy string */
+ 	  unsigned char * cptr = walk2;
+ 	  for (uptr = work; uptr < work + worklen ; uptr++) {
+ 	    if (cptr < walk2 + left) *cptr++ = *uptr;
+ 	  }
+ 	  rlen = cptr - walk2;
+ 	}
+       }
+       work[worklen] = safe;
+     walk2[rlen] = '\0';
+       dprint (14, (debugfile, 
+ 		  "rfc1522_encode_text> rlen=%d, coded: '%s', is_encoded=%d\n",
+ 		  rlen,walk2,is_encoded));
+       walk2 += rlen;
+     }
+ 
+     if (workprvptr != prvptr)
+       free(workprvptr);
+     was_encoded = is_encoded;
+   }
+   *walk2 = '\0';
+   dprint (14, (debugfile, 
+ 	      "rfc1522_encode_text: RESULT: '%s'\n",buf));
+ 
+ }
+ 
+ 
+ void attach_generate_message (gopher, fpout, copy, mime_info)
+      mime_t *gopher;
+      FILE *fpout;
+      int copy;
+      mime_send_t *mime_info;
+ {
+ /* given a list of attachments, write them in MIME format to the specified
+  * output stream */
+ 
+   FILE *srcfp;
+   int is_text;
+ 
+   if (gopher->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"attach_generate_message",
+ 	       "Bad magic number");
+ 
+   while (gopher) {
+     if (gopher->magic != MIME_magic)
+       mime_panic(__FILE__,__LINE__,"attach_generate_message",
+ 		 "Bad magic number (next -chain)");
+ 
+     if (can_open(gopher->pathname,"r") != 0) {
+       gopher = gopher -> next;
+       continue;
+     }
+     srcfp = fopen (gopher->pathname, "r");
+ 
+     if (srcfp) {
+       
+       /* 1 if is text type (true)
+        * 0 if not text type
+        * -1 if can't be encoded (ie structured) Message/ or Multpart/
+        */
+       is_text = is_text_type (mime_types[gopher->type], gopher->subtype, 
+ 			      gopher->encoding);
+       
+       /* write the attachment header */
+       print_EOLN(fpout,mime_info->encoding_top);
+       ERROR_EOF(fprintf (fpout, "--%s", mime_info->mime_boundary));
+       print_EOLN(fpout,mime_info->encoding_top);
+       ERROR_EOF(fprintf (fpout, "Content-Type: %s/%s", 
+ 			mime_types[gopher->type], gopher->subtype));
+       if (gopher->type_opts) {
+ 	ERROR_EOF(fputc (';', fpout));
+ 	if (strlen (gopher->type_opts) > 45) {
+ 	  print_EOLN (fpout, mime_info->encoding_top);
+ 	  ERROR_EOF(fputc ('\t', fpout));
+       }
+ 	else
+ 	  ERROR_EOF(fputc (' ', fpout));
+ 	ERROR_EOF(fputs (gopher->type_opts, fpout));
+       }
+       print_EOLN (fpout, mime_info->encoding_top);
+     
+       /* Now add the Content-Disposition header */
+       ERROR_EOF(fprintf (fpout, "Content-Disposition: %s",
+ 			 DISPOSITION(gopher->disposition)));
+       if (gopher->disposition_opts) {
+ 	ERROR_EOF(fputc (';', fpout));
+ 	if (strlen (gopher->disposition_opts) > 45) {
+ 	  print_EOLN (fpout, mime_info->encoding_top);
+ 	  ERROR_EOF(fputc ('\t', fpout));
+ 	}
+ 	else
+ 	  ERROR_EOF(fputc (' ', fpout));
+ 	ERROR_EOF(fputs (gopher->disposition_opts, fpout));
+       }
+       print_EOLN (fpout, mime_info->encoding_top);
+ 
+       ERROR_EOF(fprintf (fpout, "Content-Description: "));
+       if (allow_no_hdrencoding) {
+ 	if (gopher->description)
+ 	  ERROR_EOF(fputs (gopher->description, fpout));
+  	else
+ 	  ERROR_EOF(fputs (gopher->pathname, fpout));
+       } else {
+ 	char buffer[LONG_STRING];
+ 	if (gopher->description)
+ 	  rfc1522_encode_text(buffer,sizeof(buffer),gopher->description,0);
+ 	else 
+ 	  rfc1522_encode_text(buffer,sizeof(buffer),gopher->pathname,0);
+ 	ERROR_EOF(fputs (buffer, fpout));
+       }
+       print_EOLN(fpout,mime_info->encoding_top);
+       ERROR_EOF(fprintf (fpout, "Content-Transfer-Encoding: %s",
+ 			 ENCODING(gopher->encoding)));
+       print_EOLN(fpout,mime_info->encoding_top);
+       print_EOLN(fpout,mime_info->encoding_top);
+       
+       (void) write_encoded (srcfp, fpout, gopher->encoding, copy, is_text,
+ 			    mime_info);
+ 
+       fclose (srcfp);
+     }
+     else {
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorOpeningName,
+ 			"Error opening %s!"), 
+ 		gopher->pathname);
+       dprint (1, (debugfile, "mime_gen_msg(): could not open %s\n", 
+ 		  gopher->pathname));
+       sleep_message();
+     }
+     
+     gopher = gopher->next;
+   }
+   return;
+ }
+ 
+ void
+ base64_encode (srcfp, fpout, istext, mime_info)
+      FILE *srcfp, *fpout;
+      int istext;
+      mime_send_t * mime_info;
+ {
+   int c1, c2, c3;
+   char ch1, ch2, ch3, ch4;
+   int chars = 0;
+   int last_c = 0;
+ 
+   for (;;) {
+     c1 = fgetc (srcfp);
+     if (c1 == -1)
+       break;
+     if (istext && last_c != '\r' && c1 == '\n') {
+       /* In text end of line must be coded as CR LF */
+       c1 = '\r';
+       c2 = '\n';
+     }
+     else
+       c2 = fgetc (srcfp);
+ 
+     if (istext && c1 != '\r' && c2 == '\n') {
+       /* In text end of line must be coded as CR LF */
+       c2 = '\r';
+       c3 = '\n';
+     }
+     else if (c2 != -1)
+       c3 = fgetc (srcfp);
+  
+     if (istext && c2 != '\r' && c3 == '\n') {
+       /* In text end of line must be coded as CR LF */
+       ungetc(c3,srcfp);
+       c3 = '\r';
+     }
+       
+     last_c = c3;
+  
+     ch1 = c1 >> 2;
+     ch1 = to64(ch1);
+     
+     if (c2 != -1) {
+       ch2 = ((c1 & 0x3) << 4) | (c2 >> 4);
+       ch2 = to64(ch2);
+       
+       if (c3 != -1) {
+ 	ch3 = ((c2 & 0xf) << 2) | (c3 >> 6);
+ 	ch3 = to64(ch3);
+ 	ch4 = c3 & 0x3f;
+ 	ch4 = to64(ch4);
+       }
+       else {
+ 	ch3 = (c2 & 0xf) << 2;
+ 	ch3 = to64(ch3);
+ 	ch4 = '=';
+       }
+     }
+     else {
+       ch2 = (c1 & 0x3) << 4;
+       ch2 = to64(ch2);
+       ch3 = '=';
+       ch4 = '=';
+     }
+     
+     ERROR_EOF(fputc (ch1, fpout));
+     ERROR_EOF(fputc (ch2, fpout));
+     ERROR_EOF(fputc (ch3, fpout));
+     ERROR_EOF(fputc (ch4, fpout));
+     chars += 4;
+     
+     if (chars >= 76) {
+       print_EOLN(fpout,mime_info->encoding_top);
+       chars = 0;
+     }	
+   }
+   print_EOLN(fpout,mime_info->encoding_top);
+   return;
+ }
+ 
+ void
+ line_quoted_printable_encode (input,fpout,copy,len,istext,mime_info) 
+      char *input;
+      FILE *fpout;
+      int copy; /* whether or not this is a copy of the message */
+      int len; /* length of data -- be binary clean */
+      int istext; /* if binary (not text) also CRLF need to be encoded */
+      mime_send_t *mime_info;
+ {
+   int chars = 0;
+   char buffer[STRING];
+   unsigned char c1, c2, c3;
+   unsigned char lastchar = 0;
+   unsigned char lastchar2 = 0;
+   
+   dprint (10, (debugfile, 
+ 	       "line_quoted_printable_encode: copy=%d, len=%d, istext=%d\n",
+ 	       copy,len,istext));
+ 
+   if (istext) {  
+     if (len > 0 && input[len-1] == '\n') {
+       lastchar = input[len-1];
+       input[len-1] = '\0';
+       len--;
+       if (len > 0 && input[len-1] == '\r')  {   /* Was CR LF */
+         lastchar2 = input[len-1];
+         input[len-1] = '\0';
+         len--;
+       } else if (mime_info->encoding_top == ENCODING_BINARY)
+ 	lastchar2 = '\r';     /* Simulate it */
+     }
+   }
+ 
+   /* I don't test agaist macros bacause these encodings are recommended
+    * according MIME Draft Standard anyway and MIME encodings are
+    * reversible.
+    *
+    * DONT_ESCAPE_MESSAGES refers '>' escaping -- not reversible
+    * MIME encoding -- '>' escaping was not reversible -- this is.
+    *
+    * We also want do these encodings when sending (copy == 0)
+    * not only when copying to another folder 
+    *            -- K E H <hurtta@dionysos.FMI.FI>                     */
+ 
+   while (len > 0)  {
+     /* Assume that buffer don't have newlines (or they have binary data) ...
+        this routine encodes one line */
+     c1 = (unsigned char) *input++;
+     len--;
+ 
+     if (c1 == '=') {
+       if (chars > 72) {	    
+ 	buffer[chars++] = '=';
+ 	buffer[chars++] = '\0';
+ 	chars = 0;
+ 
+ 	ERROR_EOF(fputs (buffer, fpout));
+ 	print_EOLN(fpout,mime_info->encoding_top);
+       }
+       buffer[chars++] = '=';
+       buffer[chars++] = '3';
+       buffer[chars++] = 'D';
+     }    
+     /*  printable characters -- EXCEPT:   Encode "From " in beginning */
+     else if ((c1 > 31 && c1 < 127) && ((c1 != ' ' || chars != 4 || 
+ 					strncmp(buffer,"From",4) != 0)
+ 				       /* Encode "." if only in line alone */
+ 				       && (c1 != '.' || chars != 0 || len > 0)
+ 				       /* Last space must encode also */
+ 				       && (c1 != ' ' || len > 0)) 
+ 	     ||
+ 	     (c1 == 9 && len > 0 && istext)) { 
+       /* Don't make sense wrap before last character, when last character
+        * is not encoded -- wrapping and character use equal number of columns.
+        * But left space for '=\n' if we will print it in end of function
+        * instead of '\n'. */
+       if (chars > 74 && (len > 0 || !lastchar)) {
+ 	buffer[chars++] = '=';
+ 	buffer[chars++] = '\0';
+ 	chars = 0;
+ 
+ 	ERROR_EOF(fputs (buffer, fpout));
+ 	print_EOLN(fpout,mime_info->encoding_top);
+       }
+       buffer[chars++] = c1;
+     }
+     else {
+       if (chars > 72) {
+ 	buffer[chars++] = '=';
+ 	buffer[chars++] = '\0';
+ 	chars = 0;
+ 
+ 	ERROR_EOF(fputs (buffer, fpout));
+ 	print_EOLN(fpout,mime_info->encoding_top);
+       }
+       c2 = (c1 >> 4) & 0xf;
+       c3 = c1 & 0xf;
+       buffer[chars++] = '=';
+       buffer[chars++] = hexchars[c2];
+       buffer[chars++] = hexchars[c3];
+     }
+   }
+ 
+   /* Make sure to flush the buffer.  */
+   if (chars > 0) {
+     buffer[chars] = '\0';
+     ERROR_EOF(fputs (buffer, fpout));
+   }
+   if (lastchar2)
+     ERROR_EOF(fputc (lastchar2, fpout));
+   if (lastchar) {
+     fputc(lastchar,fpout);
+   } else { /* If input line don't terminate NL then print shoft wrap to end
+ 	    * instead of hard NL */
+     ERROR_EOF(fputs ("=", fpout));
+     print_EOLN(fpout,mime_info->encoding_top);
+   }
+ }
+ 
+ void
+ quoted_printable_encode (srcfp, fpout, copy, istext, mime_info)
+      FILE *srcfp, *fpout;
+      int copy;    /* whether or not this is a copy of the message */
+      int istext;  /* if binary (not text) also CRLF need to be encoded */
+      mime_send_t *mime_info;
+ {
+   char buffer[VERY_LONG_STRING];
+   int len;
+ 
+   dprint (10, (debugfile, 
+ 	       "quoted_printable_encode: copy=%d, istext=%d\n",
+ 	       copy,istext));
+ 
+   if (istext) {
+     /* mail_gets is in ../lib -- it handles also NUL characters */
+     while ((len = mail_gets (buffer, VERY_LONG_STRING, srcfp)) > 0)
+       line_quoted_printable_encode (buffer, fpout, copy, len, istext,
+ 				    mime_info);
+   } else {
+     /* mail_gets may add LF to end of file if file don't end with LF
+      * So it is not good for binary data */
+     while ((len = fread(buffer, 1, sizeof(buffer), srcfp)) > 0)
+       line_quoted_printable_encode (buffer, fpout, copy, len, istext,
+ 				    mime_info);
+   }
+ 
+   return;
+ }
+ 
+ int
+ is_text_type (primary_type, subtype, enc)
+      char *primary_type, *subtype;
+      int enc;
+ {
+  /* encoding rules are different for text and no text 
+   * for text we must do \n -> \r\n before base64 encoding */
+ 
+  /* Current MIME Draft Standard says that part is text
+   * (ie. line oriented) when it is Text/ -type -- otherwise no.
+   *
+   * new draft for Mime standards allows also other parts ot be text.
+   * It says that content-transfer-encodings: 7bit and 8bit are only
+   * allowed for line orienteed types */
+ 
+   /* Actually Message/ and Multipart/ can't be newer encoded directly */
+   if ( istrcmp(primary_type,"Message") == 0 ||
+        istrcmp(primary_type,"Multipart") == 0)
+     return -1;
+ 
+   if (istrcmp(primary_type,"Text") == 0) 
+     return 1;               /* Subtypes of text are always text (ie.
+                              * line oriented). */
+ 
+   if (istrcmp(primary_type,"Application") == 0 &&
+       istrcmp(subtype,"X-ELM-encode") == 0)
+     return 1;            /*  That is text ... */
+     
+   if (enc == ENCODING_NONE || enc == ENCODING_7BIT || enc == ENCODING_8BIT)
+     return 1;             /* It is text */
+ 
+   if (enc == ENCODING_BINARY)
+     return 0;            /* It is probably binary (or very long lines) */
+ 
+   if (istrcmp(primary_type,"Application") == 0 &&
+       istrcmp(subtype,"Postscript") == 0)
+     return 1;            /*  Postscript is often text */
+   
+   return 0;              /* Default: It is binary */
+ }
+ 
+ void
+ write_encoded (srcfp, fpout, encoding, copy, is_text, mime_info)
+      FILE *srcfp, *fpout;
+      int encoding, copy, is_text;
+      mime_send_t *mime_info;
+ {
+   char buffer[VERY_LONG_STRING];
+   int line_len;
+ 
+   dprint (12, (debugfile, 
+ 	       "write_encoded: encoding=%d, copy=%d, is_text=%d\n",
+ 	       encoding,copy,is_text));
+ 
+   if (encoding == ENCODING_BASE64)
+     base64_encode (srcfp, fpout, is_text, mime_info);
+   else if (encoding == ENCODING_QUOTED)
+     quoted_printable_encode (srcfp, fpout, copy, is_text, mime_info);
+   else if (mime_info-> encoding_top == ENCODING_BINARY && is_text > 0) {
+     /* It is better perhaps use canonical eol (CRLF) when mail have
+      * content transfer encoding BINARY somewhere (see notes about BINARYMIME)
+      */
+     while ((line_len = mail_gets(buffer, sizeof(buffer)-1, srcfp)) > 0) {
+       if (buffer[line_len-1] == '\n') {
+         int add = 1;
+         if (line_len >1 && buffer[line_len-2] == '\r')
+           add = 0;
+         if (add) {
+           buffer[line_len-1] = '\r';
+           buffer[line_len] = '\n';
+           line_len++;
+         }
+       }
+       if (fwrite(buffer, 1, line_len, fpout) != line_len) {
+         MoveCursor(elm_LINES, 0);
+         Raw(OFF);
+         lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWriteFWriteEncoded,
+ 			  "Write failed in write_encoded\n"));
+         emergency_exit(0);
+       }
+     }
+   }
+   else {
+     /* BUG: This may add extra \n in end of file if file does not end with \n
+      * but we can't read that with fread when we to need look for escaping of
+      * "From " or lone "."
+      */
+     while (1) {
+ #ifndef DONT_ESCAPE_MESSAGES
+       if (mime_info->encoding_top != ENCODING_BINARY) {
+ 	if ((line_len = mail_gets(buffer, sizeof(buffer)-1, srcfp)) <= 0)
+ 	  break;
+       }
+       else
+ #endif
+ 	if ((line_len = fread(buffer, 1,sizeof(buffer)-1, srcfp)) <= 0)
+ 	  break;
+       
+       if (mime_info-> encoding_top != ENCODING_BINARY) {
+ #ifndef DONT_ESCAPE_MESSAGES
+ 	if (copy && (strncmp(buffer, "From ", 5) == 0)) {
+ 	  /* Add in the > to a From on our copy */
+ 	  ERROR_EOF(fprintf(fpout, ">"));
+ 	  if (fwrite(buffer, 1, line_len, fpout) != line_len) {
+ 	    MoveCursor(elm_LINES, 0);
+ 	    Raw(OFF);
+ 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWriteFWriteEncoded,
+ 			      "Write failed in write_encoded()\n"));
+ 	    emergency_exit(0);
+ 	  }
+ 	}
+ #ifdef NEED_LONE_PERIOD_ESCAPE
+ 	else if (!copy && strcmp(buffer, ".\n") == 0)
+ 	  /* Because some mail transport agents take a lone period to
+ 	   * mean EOF, we add a blank space on outbound message.
+ 	   */
+ 	  ERROR_EOF(fputs(". \n", fpout));
+ #endif /* NEED_LONE_PERIOD_ESCAPE */
+ 	else
+ #endif /* DONT_ESCAPE_MESSAGES */
+ 	  if (fwrite(buffer, 1, line_len, fpout) != line_len) {
+ 	    MoveCursor(elm_LINES, 0);
+ 	    Raw(OFF);
+ 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWriteFWriteEncoded,
+ 			      "Write failed in write_encoded\n"));
+ 	    emergency_exit(0);
+ 	  }
+       }
+       else if (fwrite(buffer, 1, line_len, fpout) != line_len) {
+ 	MoveCursor(elm_LINES, 0);
+ 	Raw(OFF);
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWriteFWriteEncoded,
+ 			  "Write failed in write_encoded\n"));
+ 	emergency_exit(0);
+       }
+     }
+   }
+   return;
+ }
+ 
+ void
+ mime_write_header(fp, ptr, top)
+      FILE *fp;
+      mime_send_t *ptr;
+      int top;
+ {
+   int encoding;
+   int type;
+   char * subtype;
+   char * type_opts;
+ 
+   if (ptr->msg_is_multipart && top) {
+     encoding  = ptr->encoding_top;
+     type      = MIME_TYPE_MULTIPART;
+     subtype   = "mixed";
+     type_opts = ptr->type_opts_top;
+   } else {
+     encoding  = ptr->encoding_text;
+     type      = ptr->type_text;
+     subtype   = ptr->subtype_text;
+     type_opts = ptr->type_opts_text;
+   }
+ 
+   if (top) {
+     ERROR_EOF(fputs(MIME_HEADER, fp));
+     print_EOLN(fp, ptr->encoding_top);  
+   }
+   ERROR_EOF(fprintf(fp, "%s %s/%s", MIME_CONTENTTYPE, TYPE(type), 
+ 		    subtype));
+   if (type_opts[0])
+     ERROR_EOF(fprintf(fp, "; %s", type_opts));
+   print_EOLN(fp, ptr->encoding_top);
+   
+   if (encoding != ENCODING_NONE) {
+     ERROR_EOF(fprintf(fp, "%s %s", MIME_CONTENTENCOD, 
+ 		      ENCODING(encoding)));
+     print_EOLN(fp, ptr->encoding_top);
+   }
+ } 
+ #endif /* MIME */
Index: elm2.4.ME+.50/src/mkhdrs.c
*** elm2.4.25/src/mkhdrs.c	Sat May  8 23:25:44 1993
--- elm2.4.ME+.50/src/mkhdrs.c	Tue Nov 17 21:14:09 1998
***************
*** 1,32 ****
  
! static char rcsid[] = "@(#)$Id: mkhdrs.c,v 5.3 1993/05/08 20:25:33 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: mkhdrs.c,v $
!  * Revision 5.3  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.2  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This contains all the header generating routines for the ELM
      program.
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: mkhdrs.c,v 1.3 1998/11/06 13:56:58 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This contains all the header generating routines for the ELM
      program.
***************
*** 34,39 ****
--- 18,24 ----
  **/
  
  #include "headers.h"
+ #include "me.h"
  #include "s_elm.h"
  
  extern char in_reply_to[SLEN];
***************
*** 44,64 ****
  int msg;
  {
  	/** Generate an 'in-reply-to' message... **/
! 	char buffer[SLEN], date_buf[SLEN];
  
- 
  	if (msg == -1)		/* not a reply! */
  	  in_reply_to[0] = '\0';
  	else {
! 	  if (chloc(headers[msg]->from, '!') != -1)
! 	    tail_of(headers[msg]->from, buffer, 0);
! 	  else
! 	    strcpy(buffer, headers[msg]->from);
! 	  sprintf(in_reply_to, "%s from \"%s\" at %s",
!                   headers[msg]->messageid[0] == '\0'? "<no.id>":
! 		  headers[msg]->messageid,
! 		  buffer,
! 		  elm_date_str(date_buf, headers[msg]->time_sent + headers[msg]->tz_offset));
  	}
  }
  
--- 29,100 ----
  int msg;
  {
  	/** Generate an 'in-reply-to' message... **/
! 	char buffer[SLEN], date_buf[SLEN], buffer2[LONG_STRING];
  
  	if (msg == -1)		/* not a reply! */
  	  in_reply_to[0] = '\0';
  	else {
! 	  int q = 0;
! 	  char  *d = buffer2;
! 	  struct addr_item *p;
! 	  
! 
! 	  for (p = headers[msg]->from;
! 	       p && p->addr && p->fullname &&
! 		 d - buffer2 < sizeof buffer2 - 7;
! 	       p++) {	    
! 	    const char *str = "", *c;
! 
! 	    if (p->fullname[0]) 
! 	      str = p->fullname;
! 	    else
! 	      str = p->addr;
! 	    
! 	    if (d > buffer2) {
! 	      d--;  /* overwrite last " */
! 	      *d++ = ',';
! 	      *d++ = ' ';
! 	    } else
! 	      *d++ = '"';
! 	    
! 	  /* Remove unquoted " -characters from buffer.
! 	   */
! 	  for (c = str ;
! 	       '\0' != *c && d - buffer2 < sizeof buffer-3; 
! 	       c++) {
! 	    if (q) {
! 	      *d++ = '\\';
! 	      *d++ = *c;
! 	      q = 0;
! 	    } else if ('\\' == *c) {
! 	      q = 1;
! 	    } else if ('"' != *c) {
! 	      *d++ = *c;
! 	    }
! 	  }
! 	  *d++ = '"';
! 	  *d = '\0';
! 	  }
! 	  if (d == buffer2 && headers[msg]->env_from[0])
! 	    elm_sfprintf(buffer2,
! 			 sizeof buffer2,
! 			 FRM("(env: %s)"),
! 			 headers[msg]->env_from);
! 	  else if (d == buffer2)
! 	    strfcpy(buffer2,
! 		    "someone",
! 		    sizeof buffer2);
! 
! 	  elm_sfprintf(in_reply_to, 
! 		       sizeof in_reply_to,
! 		       FRM("%s%s %s at \"%s\""),
! 		       headers[msg]->messageid,
! 		       headers[msg]->messageid[0] ? " from" : "From",
! 		       buffer2,
! 		       elm_date_str(date_buf, 
! 				    headers[msg]->time_sent + 
! 				    headers[msg]->tz_offset,
! 				    sizeof date_buf));
  	}
  }
  
***************
*** 70,86 ****
  	**/
  
  	FILE *fd;
! 	char filename[SLEN], buffer[SLEN];
  
- 	sprintf(filename, "%s/%s", home, mailheaders);
  
! 	if ((fd = fopen(filename, "r")) != NULL) {
  	  while (fgets(buffer, SLEN, fd) != NULL)
  	    if (strlen(buffer) < 2) {
  	      dprint(2, (debugfile,
  	         "Strlen of line from .elmheaders is < 2 (write_header_info)"));
! 	      error1(catgets(elm_msg_cat, ElmSet, ElmWarningBlankIgnored,
! 		"Warning: blank line in %s ignored!"), filename);
  	      if (sleepmsg > 0)
  		    sleep(sleepmsg);
  	    }
--- 106,122 ----
  	**/
  
  	FILE *fd;
! 	char buffer[SLEN];
  
  
! 	if ((fd = fopen(user_mailheaders, "r")) != NULL) {
  	  while (fgets(buffer, SLEN, fd) != NULL)
  	    if (strlen(buffer) < 2) {
  	      dprint(2, (debugfile,
  	         "Strlen of line from .elmheaders is < 2 (write_header_info)"));
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWarningBlankIgnored,
! 				"Warning: blank line in %s ignored!"), 
! 			user_mailheaders);
  	      if (sleepmsg > 0)
  		    sleep(sleepmsg);
  	    }
***************
*** 117,131 ****
  	  command[j++] = buffer[i];
  	command[j] = '\0';
  
! 	sprintf(fname,"%s%s%d", temp_dir, temp_print, getpid());
  
! 	sprintf(command_buffer, "%s > %s", command, fname);
  
  	(void) system_call(command_buffer, 0);
  
  	if ((fd = fopen(fname, "r")) == NULL) {
! 	  error1(catgets(elm_msg_cat, ElmSet, ElmBackquoteCmdFailed,
! 		"Backquoted command \"%s\" in elmheaders failed."), command);
  	  return;	
  	}
  
--- 153,170 ----
  	  command[j++] = buffer[i];
  	command[j] = '\0';
  
! 	elm_sfprintf(fname,sizeof fname,
! 		     FRM("%s%s%d"), temp_dir, temp_print, getpid());
  
! 	elm_sfprintf(command_buffer, sizeof command_buffer,
! 		     FRM("%s > %s"), command, fname);
  
  	(void) system_call(command_buffer, 0);
  
  	if ((fd = fopen(fname, "r")) == NULL) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBackquoteCmdFailed,
! 			    "Backquoted command \"%s\" in elmheaders failed."),
! 		    command);
  	  return;	
  	}
  
Index: elm2.4.ME+.50/src/newmbox.c
*** elm2.4.25/src/newmbox.c	Mon Dec  4 17:50:56 1995
--- elm2.4.ME+.50/src/newmbox.c	Tue Nov 17 21:12:57 1998
***************
*** 1,198 ****
  
! static char rcsid[] = "@(#)$Id: newmbox.c,v 5.36 1994/05/14 18:42:57 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.36 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: newmbox.c,v $
!  * Revision 5.36  1994/05/14  18:42:57  syd
!  * Here are some more of fixes to correctly call fflush() and unlock() in sequence.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.35  1994/03/11  21:01:35  syd
!  * detect whether atol() is a macro
!  * From: Mitch DSouza <m.dsouza@mrc-applied-psychology.cambridge.ac.uk>
!  *
!  * Revision 5.34  1993/09/27  01:51:38  syd
!  * Add elm_chown to consolidate for Xenix not allowing -1
!  * From: Syd
!  *
!  * Revision 5.33  1993/09/19  23:38:16  syd
!  * Erroneous Content-Length:s that ended up beyond the end of the folder
!  * wasn't checked for, so the rest of the folder became one big message.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.32  1993/09/19  23:32:35  syd
!  * Fix a code portability problem with Convex.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.31  1993/09/19  23:15:28  syd
!  * Changed a few buffers from LONG_STRING (512) to VERY_LONG_STRING
!  * to avoid long header lines overflowing the allocated space. At
!  * least 1024 bytes should be allowed in any header line/field.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.30  1993/08/23  03:26:24  syd
!  * Try setting group id separate from user id in chown to
!  * allow restricted systems to change group id of file
!  * From: Syd
!  *
!  * Revision 5.29  1993/08/23  02:46:51  syd
!  * Test ANSI_C, not __STDC__ (which is not set on e.g. AIX).
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.28  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.27  1993/07/20  15:32:36  syd
!  * no dprint should be at level 0
!  * From: Syd
!  *
!  * Revision 5.26  1993/05/14  03:55:13  syd
!  * The recent feature addition for the "readmsginc" variable did not modify
!  * the output statement that is used when MMDF is defined.  The following
!  * patch makes the variable work on MMDF systems.
!  * From: Larry Philps <larryp@sco.COM>
!  *
!  * Revision 5.25  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.24  1993/05/08  18:56:16  syd
!  * created a new elmrc variable named "readmsginc".  This specifies an
!  * increment by which the message count is updated.  If this variable is
!  * set to, say, 25, then the message count will only be updated every 25
!  * messages, displaying 0, 25, 50, 75, and so forth.  The default value
!  * of 1 will cause Elm to behave exactly as it currently does in PL21.
!  * From: Eric Peterson <epeterso@encore.com>
!  *
!  * Revision 5.23  1993/04/16  04:03:18  syd
!  * *** empty log message ***
!  *
!  * Revision 5.22  1993/02/09  19:36:52  syd
!  * STDC declares rewind
!  * From: Syd
!  *
!  * Revision 5.21  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.20  1993/02/03  15:26:13  syd
!  * protect atol in ifndef __STDC__ as some make it a macro, and its in stdlib.h
!  *
!  * Revision 5.19  1993/01/27  20:45:55  syd
!  * When elm exits because a spool mailbox is used, it should do a Raw(OFF) so
!  * that the error message get's printed on the right screen.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.18  1993/01/27  20:44:27  syd
!  * Correct MMDF syntax problems and newmail botches.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.17  1993/01/20  03:37:16  syd
!  * Nits and typos in the NLS messages and corresponding default messages.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.16  1993/01/20  03:02:19  syd
!  * Move string declarations to defs.h
!  * From: Syd
!  *
!  * Revision 5.15  1993/01/19  05:20:32  syd
!  * On a resync, the temp file was being reopened in *append*
!  * mode, thus the fseek that tried to back up the file pointer had no
!  * effect.
!  * From: Larry Philps <larryp@sco.COM>
!  *
!  * Revision 5.14  1993/01/19  05:12:22  syd
!  * read_headers() in src/newmbox.c assumes that Mime-Version preceeds
!  * Content-Type in the headers. I removed that assumption.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.13  1993/01/19  05:07:05  syd
!  * Trim erroreous extra log entry
!  * From: Syd
!  *
!  * Revision 5.12  1993/01/19  04:47:12  syd
!  * Significant changes to provide consistent Date and From_ header
!  * cracking.  Overhauled date utilities and moved into library.  Moved
!  * real_from() into library.  Modified frm, newmail, and readmsg utilities
!  * to use library version of real_from().  Moved get_word() from Elm
!  * source into library.  Added new library routines atonum() and strfcpy().
!  * Fixed trailing backslash bug in len_next().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.11  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.10  1992/12/07  04:31:38  syd
!  * Fix typo
!  * From: Syd
!  *
!  * Revision 5.9  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.8  1992/11/22  00:08:45  syd
!  * I was playing with the metamail stuff and Sun's Openwindows Mailtool
!  * and discovered that I was able to 'display' messages generated with
!  * Mailtool in elm using metamail.  This marks the Sun Attachments as
!  * needing metamail.
!  * From: Lutz Brunke <brunke@dkrz-hamburg.dbp.de>
!  *
!  * Revision 5.7  1992/11/14  21:49:42  syd
!  * I think that the code in 'newmbox.c' which handles bad 'Content-length'
!  * entries is incomplete. The file-ptr for the mail file is
!  * backed up, but the file-ptr of the temp file WAS LEFT UNMODIFIED !
!  * From langesw.ssw.de!root Wed Nov 11 14:28:57 1992
!  *
!  * Revision 5.6  1992/11/07  20:05:52  syd
!  * change to use header_cmp to allow for linear white space around the colon
!  * From: Syd
!  *
!  * Revision 5.5  1992/11/07  16:08:52  syd
!  * add tolerance for incorrect content length line
!  * From: Syd
!  *
!  * Revision 5.4  1992/10/31  18:52:51  syd
!  * Corrections to Unix date parsing and time zone storage
!  * From: eotto@hvlpa.att.com
!  *
!  * Revision 5.3  1992/10/25  01:47:45  syd
!  * fixed a bug were elm didn't call metamail on messages with a characterset,
!  * which could be displayed by elm itself, but message is encoded with QP
!  * or BASE64
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.2  1992/10/24  12:51:34  syd
!  * Fixes SysV style forwarding
!  * From: Baruch Cochavy <bcochavy@ilux39.intel.com>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /**  read new folder **/
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: newmbox.c,v 1.2 1998/10/20 19:58:16 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /**  read new folder **/
  
***************
*** 202,214 ****
  #include <sys/stat.h>
  #include <errno.h>
  
! #ifdef I_TIME
! #  include <time.h>
! #endif
! #ifdef I_SYSTIME
! #  include <sys/time.h>
! #endif
! 
  extern int errno;
  
  char *error_description();
--- 20,26 ----
  #include <sys/stat.h>
  #include <errno.h>
  
! #include "me.h"   /* for defination of null_decode and text_decode */
  extern int errno;
  
  char *error_description();
***************
*** 218,227 ****
  extern long atol();
  #endif
  
! int
! newmbox(new_file, adds_only)
! char *new_file;
! int adds_only;
  {
  	/** Read a folder.
  
--- 30,41 ----
  extern long atol();
  #endif
  
! static int read_headers P_((int));   /* Prototype */
! static void mk_temp_mail_fn P_((char *, char *, int)); /* Prototype */
! 
! int newmbox(new_file, adds_only)
!      char *new_file;
!      int adds_only;
  {
  	/** Read a folder.
  
***************
*** 243,251 ****
  	int err;
  	char new_tempfile[SLEN];
  
  	/* determine type of new mailfile and calculate temp file name */
  	if((new_folder_type = get_folder_type(new_file)) == SPOOL)
! 	  mk_temp_mail_fn(new_tempfile, new_file);
  	else
  	  *new_tempfile = '\0';
  
--- 57,67 ----
  	int err;
  	char new_tempfile[SLEN];
  
+ reread:
+ 
  	/* determine type of new mailfile and calculate temp file name */
  	if((new_folder_type = get_folder_type(new_file)) == SPOOL)
! 	  mk_temp_mail_fn(new_tempfile, new_file, sizeof new_tempfile);
  	else
  	  *new_tempfile = '\0';
  
***************
*** 268,278 ****
  	    Centerline(18, catgets(elm_msg_cat, ElmSet, ElmAlreadyRunning3,
  		"If this is in error, then you'll need to remove the following file:"));
  	    Centerline(19, new_tempfile);
! 	    MoveCursor(LINES, 0);  /* so shell prompt upon exit is on newline */
  	    silently_exit();
  	  }
  	}
  
  	/* If we were reading a spool file and we are not just reading
  	 * in the additional new messages to the same file, we need to
  	 * remove the corresponding tempfile.
--- 84,106 ----
  	    Centerline(18, catgets(elm_msg_cat, ElmSet, ElmAlreadyRunning3,
  		"If this is in error, then you'll need to remove the following file:"));
  	    Centerline(19, new_tempfile);
! 	    MoveCursor(elm_LINES, 0);  /* so shell prompt upon exit is on newline */
  	    silently_exit();
  	  }
  	}
  
+ 
+ 	if (message_count == 0 && adds_only) {
+ 	  dprint(1, (debugfile, 
+ 		     "newmbox: message_count == 0 -- clearing adds_only flag.\n"));
+ 	  /* Clearing adds_only flag so temp folder gets created
+ 	   * It was not created in first call if mailfile was not
+ 	   * existing...
+ 	   */
+ 	  adds_only = FALSE;
+ 	}
+ 
+ 
  	/* If we were reading a spool file and we are not just reading
  	 * in the additional new messages to the same file, we need to
  	 * remove the corresponding tempfile.
***************
*** 281,298 ****
  	if((folder_type == SPOOL) && !adds_only) {
  	  if (access(cur_tempfolder, ACCESS_EXISTS) != -1) {
  	    if (unlink(cur_tempfolder) != 0) {
! 	      error2(catgets(elm_msg_cat, ElmSet, ElmSorryCantUnlinkTemp,
! 		"Sorry, can't unlink the temp file %s [%s]!\n\r"),
! 	        cur_tempfolder, error_description(errno));
  	      silently_exit();
  	    }
  	  }
  	}
  
  	/* Okay! Now establish this new file as THE file */
! 	strcpy(cur_folder, new_file);
  	folder_type = new_folder_type;
! 	strcpy(cur_tempfolder, new_tempfile);
  
  	clear_error();
  	clear_central_message();
--- 109,130 ----
  	if((folder_type == SPOOL) && !adds_only) {
  	  if (access(cur_tempfolder, ACCESS_EXISTS) != -1) {
  	    if (unlink(cur_tempfolder) != 0) {
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSorryCantUnlinkTemp,
! 				"Sorry, can't unlink the temp file %s [%s]!\n\r"),
! 			cur_tempfolder, error_description(errno));
  	      silently_exit();
+ 	    } else {
+ 	      dprint(1, (debugfile, 
+ 			 "newmbox: Unlinking tempfile (%s).\n",
+ 			 cur_tempfolder));
  	    }
  	  }
  	}
  
  	/* Okay! Now establish this new file as THE file */
! 	strfcpy(cur_folder, new_file, sizeof cur_folder);
  	folder_type = new_folder_type;
! 	strfcpy(cur_tempfolder, new_tempfile, sizeof cur_tempfolder);
  
  	clear_error();
  	clear_central_message();
***************
*** 303,309 ****
  	if ((mailfile = fopen(cur_folder,"r")) == NULL)  {
  	  if (errno != ENOENT ) { /* error on anything but file not exist */
  	    err = errno;
! 	    MoveCursor(LINES,0);
  	    Raw(OFF);
  	    printf(catgets(elm_msg_cat, ElmSet, ElmFailOnOpenNewmbox,
  		    "\nfail on open in newmbox, open %s failed!!\n"),
--- 135,141 ----
  	if ((mailfile = fopen(cur_folder,"r")) == NULL)  {
  	  if (errno != ENOENT ) { /* error on anything but file not exist */
  	    err = errno;
! 	    MoveCursor(elm_LINES,0);
  	    Raw(OFF);
  	    printf(catgets(elm_msg_cat, ElmSet, ElmFailOnOpenNewmbox,
  		    "\nfail on open in newmbox, open %s failed!!\n"),
***************
*** 320,325 ****
--- 152,175 ----
  	  }
  	} else {                          /* folder exists, read headers */
  	  read_headers(adds_only);
+ 	  if (ferror(mailfile)) {
+ 	    dprint(1, (debugfile, "error when reading mailfile: %s\n",
+ 		       cur_folder));
+ 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorWhenReading,
+ 			      "Error when reading: %s"),
+ 		      cur_folder);
+ 	    sleep_message();
+ 	    if (*def_ans_yes == want_to ("Error when reading! Reread folder?",
+ 					 *def_ans_yes,elm_LINES,0)) {
+ 	      adds_only = FALSE;
+ 
+ 	      dprint(1, (debugfile, "rereading mailfile: %s\n",
+ 			 cur_folder));
+ 	      goto reread;
+ 	    }
+ 					 
+ 	    rm_temps_exit();
+ 	  }
  	}
  
  	if(!same_file)		/* limit mode off if this is a new file */
***************
*** 335,343 ****
  	return(0);
  }
  
! int
! get_folder_type(filename)
! char *filename;
  {
  	/** returns the type of mailfile filename is
  	    NO_NAME = no name
--- 185,194 ----
  	return(0);
  }
  
! static int is_in_spool P_((char *)); /* prototype */
! 
! int get_folder_type(filename)
!      char *filename;
  {
  	/** returns the type of mailfile filename is
  	    NO_NAME = no name
***************
*** 347,357 ****
  	 **/
  
  	char *last_slash;
  
  	/* if filename is null or is of zero length */
! 	if((filename == NULL) || (*filename == '\0'))
  	  return(NO_NAME);
  
  	/* if filename begins with mailhome,
  	 * and there is a slash in filename,
  	 * and there is a filename after it (i.e. last slash is not last char),
--- 198,215 ----
  	 **/
  
  	char *last_slash;
+ 	struct stat    buf;		/* stat command  */
  
  	/* if filename is null or is of zero length */
! 	if((filename == NULL) || (*filename == '\0')) {
! 	  dprint(8, (debugfile, 
! 		     "get_folder_type=NO_NAME: no filename\n"));
  	  return(NO_NAME);
+ 	}
  
+ 	dprint(8, (debugfile, 
+ 		   "get_folder_type: filename=%s\n",filename));
+ 
  	/* if filename begins with mailhome,
  	 * and there is a slash in filename,
  	 * and there is a filename after it (i.e. last slash is not last char),
***************
*** 358,399 ****
  	 * and the last character of mailhome is last slash in filename,
  	 * it's a spool file .
  	 */
! 	if((first_word(filename, mailhome)) &&
! 	  ((last_slash = rindex(filename, '/')) != NULL) &&
! 	  (*(last_slash+1) != '\0') &&
! 	  (filename + strlen(mailhome) - 1 == last_slash))
! 	    return(SPOOL);
  	/* if file name == default mailbox, its a spool file also
  	 * even if its not in the spool directory. (SVR4)
  	 */
! 	if (strcmp(filename, defaultfile) == 0)
  	    return(SPOOL);
  
  	return(NON_SPOOL);
  }
  
! mk_temp_mail_fn(tempfn, mbox)
! char *tempfn, *mbox;
  {
! 	/** create in tempfn the name of the temp file corresponding to
! 	    mailfile mbox. Mbox is presumed to be a file in mailhome;
! 	    Strangeness may result if it is not!
! 	 **/
  
! 	char *cp;
  
! 	sprintf(tempfn, "%s%s", default_temp, temp_mbox);
! 	if((cp = rindex(mbox, '/')) != NULL) {
! 	  cp++;
! 	  if (strcmp(cp, "mbox") == 0 || strcmp(cp, "mailbox") == 0 ||
! 		strcmp(cp, "inbox") == 0 || *cp == '.')
! 	    strcat(tempfn, username);
! 	  else
! 	    strcat(tempfn, cp);
! 	}
  }
  
! int
  read_headers(add_new_only)
  int add_new_only;
  {
--- 216,510 ----
  	 * and the last character of mailhome is last slash in filename,
  	 * it's a spool file .
  	 */
! 	if(is_in_spool(filename)) {
! 	  dprint(8, (debugfile, 
! 		     "get_folder_type=SPOOL\n"));
! 	  return(SPOOL);
! 	}
  	/* if file name == default mailbox, its a spool file also
  	 * even if its not in the spool directory. (SVR4)
  	 */
! 	if (strcmp(filename, defaultfile) == 0) {
! 	  dprint(8, (debugfile, 
! 		     "get_folder_type=SPOOL\n"));
! 	  return(SPOOL);
! 	  }
!         if (stat(filename, &buf) != 0) {
! 	  int err = errno;
! 	  dprint(8, (debugfile, 
! 		     "get_folder_type: errno %s attempting to stat file %s\n", 
! 		     error_description(err), filename));
! 	} else {
! 	  if (buf.st_mode & 07000) { 
! 	    /* is 'SPOOL' file is special modes set */
! 	    dprint(8, (debugfile, 
! 		       "get_folder_type=SPOOL; mode=%05o\n",buf.st_mode));
  	    return(SPOOL);
+ 	  }
+ 	}
  
+ 	dprint(8, (debugfile, 
+ 		   "get_folder_type=NON_SPOOL\n"));
  	return(NON_SPOOL);
  }
  
! static int same_file P_((char *,char *)); /* Prototype */
! 
! static int same_file(name1,name2)
!      char *name1, *name2;
  {
!   struct stat buf1, buf2;
!   
!   if (0 == strcmp(name1,name2)) {
!     dprint(8, (debugfile, 
! 	       "same_file(%s,%s)=TRUE\n",name1,name2)); 
!     return TRUE;
!   }
! 
!   if (stat(name1, &buf1) != 0) {
!     int err = errno;
!     dprint(8, (debugfile, 
! 	       "same_file(%s,%s)=FALSE: %s (errno=%d) attempting to stat file %s\n", 
! 	       name1,name2,error_description(err), err, name1));
!     return FALSE;
!   }
! 
!   if (stat(name2, &buf2) != 0) {
!     int err = errno;
!     dprint(8, (debugfile, 
! 	       "same_file(%s,%s)=FALSE: %s (errno=%d) attempting to stat file %s\n", 
! 	       name1,name2,error_description(err), err, name2));
!     return FALSE;
!   }
! 
!   if (buf1.st_ino == buf2.st_ino && buf1.st_dev == buf2.st_dev) {
!     dprint(8, (debugfile, 
! 	       "same_file(%s,%s)=TRUE\n",name1,name2)); 
!     return TRUE;
!   }
!   dprint(8, (debugfile, 
! 	     "same_file(%s,%s)=FALSE\n",name1,name2)); 
!   return FALSE;
! }
  
! static int is_in_spool(mbox)
!      char *mbox;
! {
!   char * ptr = strrchr(mbox,'/');
!   int in_spool = 0;
  
!   if (ptr) {
!     char temp = *(++ptr);
!     *ptr = '\0';
!     in_spool = 0 == strcmp(mbox,mailhome);
! 
!     dprint(8,(debugfile,"is_in_spool: base=%s\n",
! 	      mbox));
! 
!     *ptr = temp;
!   } else
!     ptr = mbox;
! 
!   dprint(8,(debugfile,"is_in_spool(%s): in_spool=%d\n",
! 	    mbox,in_spool));
! 
!   if (!in_spool) {
!     char tempname[SLEN];
!     if (strlen(mailhome) + strlen(ptr) > SLEN-1) {
!       dprint(1,(debugfile,
! 		"is_in_spool(%s): Too long path or mailbox!\n",mbox));
!     } else {
!       elm_sfprintf(tempname,sizeof tempname,
! 		   FRM("%s%s"),mailhome,ptr);
!       
!       if (same_file(tempname,mbox))
! 	in_spool = TRUE;
!     } 
!   }
!   dprint(8,(debugfile,"is_in_spool=%d\n",
! 	    in_spool));
!   return in_spool;
! }
! 
! static void mk_temp_mail_fn(tempfn, mbox, tempfn_size)
!      char *tempfn, *mbox;
!      int tempfn_size;
! {
!   /** create in tempfn the name of the temp file corresponding to
!     mailfile mbox. 
!     **/
!   
!   char *cp,*ptr;
!   int in_spool = is_in_spool(mbox);
! 
!   dprint(8,(debugfile,"mk_temp_mail_fn: in_spool=%d, mbox=%s\n",
! 	    in_spool,mbox));
! 	       
!   if (strlen(default_temp) + strlen(temp_mbox) > tempfn_size-1) {
!     dprint(1,(debugfile,"mk_temp_mail_fn: Too long path!\n"));
!     strfcpy(tempfn,"TEMP_MBOX", tempfn_size);
!     return;
!   }
! 
!   elm_sfprintf(tempfn, tempfn_size,
! 	       FRM("%s%s"), default_temp, temp_mbox);
!   
!   if((cp = rindex(mbox, '/')) != NULL) {    
!     cp++;
!     if (strcmp(cp, "mbox") == 0 || strcmp(cp, "mailbox") == 0 ||
! 	strcmp(cp, "inbox") == 0 || *cp == '.') {
!       ptr = username;
!     }
!     else {
!       ptr = cp;
!     }
!   } else {
!     ptr = mbox;
!   }
! 
!   if (strlen(tempfn) + strlen(ptr) > tempfn_size-1) {
!     dprint(1,(debugfile,
! 	      "mk_temp_mail_fn: Too long path or mailbox!\n"));
!   } else
!     strfcat(tempfn, ptr, tempfn_size);
! 
!   if (!in_spool) {
!     /* Assume that this is user's incoming mail area */
!     if (strlen(tempfn) + strlen(username) > tempfn_size-2) {
!       dprint(1,(debugfile,
! 		"mk_temp_mail_fn: Too long path or username!\n"));
!     } else {
!       strfcat(tempfn, "-", tempfn_size);
!       strfcat(tempfn, username, tempfn_size);
!     }
!   }
!   dprint(8,(debugfile,"mk_temp_mail_fn: tempfname=%s\n",tempfn));
! }
! 
! static time_t now = 0;
! 
! void header_clear(h) 
!      struct header_rec *h;
! {
!   if (0 == now) now = time(NULL);
! 
!   h->lines            = 0;
!   h->status           = 0;
!   h->encrypted        = 0;
!   h->exit_disposition = 0;
!   h->status_chgd      = 0;
!   h->content_length   = -1;
!   h->offset           = -1;
!   h->received_time    = now;
!   h->env_from[0]      = '\0';
!   if (h->from)
!     free_addr_items(h->from);
!   h->from             = NULL;
!   if (h->to)
!     free_addr_items(h->to);
!   h->to               = NULL;
!   if (h->cc)
!     free_addr_items(h->cc);
!   h->cc               = NULL;
!   h->messageid[0]     = '\0';
!   h->time_zone[0]     = '\0';
!   h->time_menu[0]     = '\0';
!   h->tz_offset        = 0;
!   h->subject[0]       = '\0';
!   h->mailx_status[0]  = '\0';
! #ifdef MIME
!   mime_t_clear (&(h->mime_rec));
! #endif
! #ifdef USE_PGP
!   h->pgp              = 0;
! #endif
!   h->binary           = 0;
! }
! 
! void header_zero(h)
!      struct header_rec *h;
! {
!   if (0 == now) now = time(NULL);
! 
!   h->lines            = 0;
!   h->status           = 0;
!   h->encrypted        = 0;
!   h->exit_disposition = 0;
!   h->status_chgd      = 0;
!   h->content_length   = -1;
!   h->offset           = -1;
!   h->received_time    = now;
!   h->env_from[0]      = '\0';
!   h->from             = NULL;
!   h->to               = NULL;
!   h->cc               = NULL;
!   h->messageid[0]     = '\0';
!   h->time_zone[0]     = '\0';
!   h->time_menu[0]     = '\0';
!   h->tz_offset        = 0;
!   h->subject[0]       = '\0';
!   h->mailx_status[0]  = '\0';
! #ifdef MIME
!   mime_t_zero (&(h->mime_rec));
! #endif
! #ifdef USE_PGP
!   h->pgp              = 0;
! #endif
!   h->binary           = 0;
! }
! 
! #ifdef MIME
! 
! PUBLIC int is_pre_mime_content_type (ptr,content_type)
!      mime_t *ptr;
!      char *content_type;
! {
!   int result;
!   char *cptr = strpbrk(content_type,"/;()");
! 
!   dprint(12,(debugfile,"is_pre_mime_content_type(): content_type=%s\n",
! 	     content_type));
!   
!   if (!cptr || ';' == *cptr) {
!     char *ptr2;
!     char *tmp = content_type;
!     while (whitespace(*tmp))
!       tmp++;
!     
!     if (cptr)
!       *cptr = '\0';
!     
!     ptr2 = strpbrk(tmp," \t");
!     if (ptr2)
!       *ptr2 = '\0';
! 
!     if (istrcmp(tmp,"text")!=0) {
!       char buf[STRING];
!       ptr -> notplain = TRUE;
! 
!       /* Put some 'intelligent' value */
!       ptr ->type = MIME_TYPE_APPLICATION;
!       elm_sfprintf(buf,sizeof buf,
! 		   FRM("X-RFC1049-%.30s"),tmp);
!       strfcpy(ptr->subtype,buf,sizeof(ptr->subtype));
!     } else {
!       ptr -> notplain = FALSE;
!       ptr ->type = MIME_TYPE_TEXT;
!       strfcpy(ptr->subtype,"plain",sizeof(ptr->subtype));
!     }
!     result = 1;
!   } else 
!     result = 0;
! 
!   dprint(12,(debugfile,"is_pre_mime_content_type=%d\n",result));
! 
!   return result;
  }
  
! #endif
! 
! 
! static int
  read_headers(add_new_only)
  int add_new_only;
  {
***************
*** 410,454 ****
          int temp_handle;
  	struct header_rec *current_header = NULL;
  	char buffer[VERY_LONG_STRING], tbuffer[VERY_LONG_STRING], *c;
! 	long fbytes = 0L, line_bytes = 0L, content_start = 0L,
  	  content_remaining = -1L, lines_start = 0L;
  	register long line = 0;
  	register int count = 0, another_count,
! 	  subj = 0, copyit = 0, in_header = FALSE;
  	int count_x, count_y = 17, err;
! 	int in_to_list = FALSE, forwarding_mail = FALSE, first_line = TRUE,
! 	  content_length_found = FALSE;
  
  	static int first_read = 0;
  #ifdef MMDF
          int newheader = 0;
  #endif /* MMDF */
  
  	if (folder_type == SPOOL) {
  	  lock(INCOMING);	/* ensure no mail arrives while we do this! */
  	  if (! add_new_only) {
! 	    if ( (temp_handle = open(cur_tempfolder, O_RDWR|O_CREAT|O_EXCL)) == -1) {
  	      /* Hey!  What the hell is this?  The temp file already exists? */
  	      /* Looks like a potential clash of processes on the same file! */
  
! 	      fflush (mailfile);
! 
! 	      unlock();				     /* so remove lock file! */
! 	      error(catgets(elm_msg_cat, ElmSet, ElmWhatsThisTempExists,
! 		"What's this?  The temp folder already exists??"));
  	      if (sleepmsg > 0)
  		    sleep(sleepmsg);
! 	      error(catgets(elm_msg_cat, ElmSet, ElmIGiveUp,
! 		"Ahhhh... I give up."));
  	      silently_exit();	/* leave without tampering with it! */
  	    }
  	    if ((temp = fdopen(temp_handle,"w")) == NULL) {
  
- 	     fflush (mailfile);
- 
  	     err = errno;
! 	     unlock();	/* remove lock file! */
! 	     MoveCursor(LINES, 0);
  	     Raw(OFF);
  	     printf(catgets(elm_msg_cat, ElmSet, ElmCouldntOpenForTemp,
  		     "\nCouldn't open file %s for use as temp file.\n"),
--- 521,583 ----
          int temp_handle;
  	struct header_rec *current_header = NULL;
  	char buffer[VERY_LONG_STRING], tbuffer[VERY_LONG_STRING], *c;
! 	long fbytes = 0L, line_bytes = 0L, content_start = -1L,
  	  content_remaining = -1L, lines_start = 0L;
  	register long line = 0;
  	register int count = 0, another_count,
! 	  subj = 0, copyit = 0, in_header = FALSE,
! 	  forwarding_mail = FALSE, first_line = TRUE;
  	int count_x, count_y = 17, err;
! 
! 	int content_length_found = FALSE;
! 	char Subject[VERY_LONG_STRING], From[VERY_LONG_STRING],
! 	  To[VERY_LONG_STRING], Cc[VERY_LONG_STRING];
  
  	static int first_read = 0;
  #ifdef MMDF
          int newheader = 0;
  #endif /* MMDF */
+ #ifdef MIME
+ 	int is_content = 0;
+ 	char content_type[VERY_LONG_STRING];
+ #endif
+ 	enum what_header { IN_none,
+ 			   IN_to_list,  
+ 			   IN_cc_list,
+ 			   IN_subject,
+ 			   IN_from } in_what = IN_none;
+ 	Subject[0] = 0;
+ 	From[0] = 0;
+ 	To[0] = 0;
+ 	Cc[0] = 0;
  
  	if (folder_type == SPOOL) {
  	  lock(INCOMING);	/* ensure no mail arrives while we do this! */
  	  if (! add_new_only) {
! 	    if ( (temp_handle = open(cur_tempfolder, O_RDWR|O_CREAT|O_EXCL,
! 				     0600)) == -1) {
  	      /* Hey!  What the hell is this?  The temp file already exists? */
  	      /* Looks like a potential clash of processes on the same file! */
  
! 	      unlock(0);		           /* so remove lock file! */
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWhatsThisTempExists,
! 				"What's this?  The temp folder already exists??"));
  	      if (sleepmsg > 0)
  		    sleep(sleepmsg);
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmIGiveUp,
! 				"Ahhhh... I give up."));
  	      silently_exit();	/* leave without tampering with it! */
+ 	    } else {
+ 	      dprint(1, (debugfile, 
+ 			 "read_headers: Creating tempfile (%s).\n",
+ 			 cur_tempfolder));
  	    }
  	    if ((temp = fdopen(temp_handle,"w")) == NULL) {
  
  	     err = errno;
! 	     close(temp_handle);   /* - K E H */
! 	     unlock(0);	/* remove lock file! */
! 	     MoveCursor(elm_LINES, 0);
  	     Raw(OFF);
  	     printf(catgets(elm_msg_cat, ElmSet, ElmCouldntOpenForTemp,
  		     "\nCouldn't open file %s for use as temp file.\n"),
***************
*** 477,486 ****
  	   if ((temp = fopen(cur_tempfolder,"r+")) == NULL) {
  	     err = errno;
  
! 	     fflush (mailfile);
! 
! 	     unlock();	/* remove lock file! */
! 	     MoveCursor(LINES,0);
  	     Raw(OFF);
  	     printf(catgets(elm_msg_cat, ElmSet, ElmCouldntReopenForTemp,
  		     "\nCouldn't reopen file %s for use as temp file.\n"),
--- 606,613 ----
  	   if ((temp = fopen(cur_tempfolder,"r+")) == NULL) {
  	     err = errno;
  
! 	     unlock(0);	/* remove lock file! */
! 	     MoveCursor(elm_LINES,0);
  	     Raw(OFF);
  	     printf(catgets(elm_msg_cat, ElmSet, ElmCouldntReopenForTemp,
  		     "\nCouldn't reopen file %s for use as temp file.\n"),
***************
*** 494,504 ****
  	   if (fseek(temp, 0, 2) == -1) {
  	     err = errno;
  
! 	     fflush (mailfile);
! 
! 	     unlock();	/* remove lock file! */
  	     fclose(temp);
! 	     MoveCursor(LINES,0);
  	     Raw(OFF);
  	     printf(catgets(elm_msg_cat, ElmSet, ElmCouldntSeekTempEnd,
  		     "\nCouldn't fseek to end of reopened temp mbox.\n"));
--- 621,629 ----
  	   if (fseek(temp, 0, 2) == -1) {
  	     err = errno;
  
! 	     unlock(0);	/* remove lock file! */
  	     fclose(temp);
! 	     MoveCursor(elm_LINES,0);
  	     Raw(OFF);
  	     printf(catgets(elm_msg_cat, ElmSet, ElmCouldntSeekTempEnd,
  		     "\nCouldn't fseek to end of reopened temp mbox.\n"));
***************
*** 513,540 ****
  	}
  
  	if (! first_read++) {
! 	  ClearLine(LINES-1);
! 	  ClearLine(LINES);
  	  if (add_new_only)
! 	    PutLine2(LINES, 0, catgets(elm_msg_cat, ElmSet, ElmReadingInMessage,
! 		     "Reading in %s, message: %d"),
  		     cur_folder, message_count);
  	  else
! 	    PutLine1(LINES, 0, catgets(elm_msg_cat, ElmSet, ElmReadingInMessage0,
! 		     "Reading in %s, message: 0"), cur_folder);
! 	  count_x = LINES;
            count_y = 22 + strlen(cur_folder);
  	}
  	else {
! 	  count_x = LINES-2;
! 	  PutLine0(LINES-2, 0, catgets(elm_msg_cat, ElmSet, ElmReadingMessage0,
! 		"Reading message: 0"));
  	}
  
  	if (add_new_only) {
! 	   if (fseek(mailfile, mailfile_size, 0) == -1) {
  	     err = errno;
! 	     MoveCursor(LINES, 0);
  	     Raw(OFF);
  	     MCprintf(catgets(elm_msg_cat, ElmSet, ElmCouldntSeekEndFolder,
  		"\nCouldn't seek to %ld (end of folder) in %s!\n"),
--- 638,669 ----
  	}
  
  	if (! first_read++) {
! 	  ClearLine(elm_LINES-1);
! 	  ClearLine(elm_LINES);
  	  if (add_new_only)
! 	    PutLineX(elm_LINES, 0, CATGETS(elm_msg_cat, ElmSet, 
! 					   ElmReadingInMessage,
! 					   "Reading in %s, message: %d"),
  		     cur_folder, message_count);
  	  else
! 	    PutLineX(elm_LINES, 0, CATGETS(elm_msg_cat, ElmSet, 
! 					   ElmReadingInMessage0,
! 					   "Reading in %s, message: 0"), 
! 		     cur_folder);
! 	  count_x = elm_LINES;
            count_y = 22 + strlen(cur_folder);
  	}
  	else {
! 	  count_x = elm_LINES-2;
! 	  PutLineX(elm_LINES-2, 0, CATGETS(elm_msg_cat, ElmSet, 
! 					   ElmReadingMessage0,
! 					   "Reading message: 0"));
  	}
  
  	if (add_new_only) {
! 	   if (fseek(mailfile, mailfile_size, SEEK_SET) == -1) {
  	     err = errno;
! 	     MoveCursor(elm_LINES, 0);
  	     Raw(OFF);
  	     MCprintf(catgets(elm_msg_cat, ElmSet, ElmCouldntSeekEndFolder,
  		"\nCouldn't seek to %ld (end of folder) in %s!\n"),
***************
*** 543,549 ****
  	     dprint(1, (debugfile,
       "Error: Couldn't seek to end of folder %s: (offset %ld) Errno %s (%s)\n",
  	        cur_folder, mailfile_size, error_description(err), "read_headers"));
! 	     emergency_exit();
  	   }
  	   count = message_count;		/* next available  */
  	   fbytes = mailfile_size;		/* start correctly */
--- 672,678 ----
  	     dprint(1, (debugfile,
       "Error: Couldn't seek to end of folder %s: (offset %ld) Errno %s (%s)\n",
  	        cur_folder, mailfile_size, error_description(err), "read_headers"));
! 	     emergency_exit(0);
  	   }
  	   count = message_count;		/* next available  */
  	   fbytes = mailfile_size;		/* start correctly */
***************
*** 551,559 ****
  
  	/** find the size of the folder then unlock the file **/
  
- 	fflush (mailfile);
  	mailfile_size = bytes(cur_folder);
! 	unlock();
  
  	/** now let's copy it all across accordingly... **/
  
--- 680,687 ----
  
  	/** find the size of the folder then unlock the file **/
  
  	mailfile_size = bytes(cur_folder);
! 	unlock(0);
  
  	/** now let's copy it all across accordingly... **/
  
***************
*** 565,571 ****
  	  if (copyit)
  	    if (fwrite(buffer, 1, line_bytes, temp) != line_bytes) {
  		err = errno;
! 		MoveCursor(LINES, 0);
  		Raw(OFF);
  		printf(catgets(elm_msg_cat, ElmSet, ElmWriteToTempFailed,
  				"\nWrite to temp file %s failed!!\n"),
--- 693,699 ----
  	  if (copyit)
  	    if (fwrite(buffer, 1, line_bytes, temp) != line_bytes) {
  		err = errno;
! 		MoveCursor(elm_LINES, 0);
  		Raw(OFF);
  		printf(catgets(elm_msg_cat, ElmSet, ElmWriteToTempFailed,
  				"\nWrite to temp file %s failed!!\n"),
***************
*** 608,614 ****
  #else
  	    if (! first_word(buffer, "From ") && !forwarding_mail) {
  #endif /* MMDF */
! 	      MoveCursor(LINES,0);
  	      Raw(OFF);
  	      printf(catgets(elm_msg_cat, ElmSet, ElmFolderCorrupt,
  		  "\nFolder is corrupt!!  I can't read it!!\n\n"));
--- 736,742 ----
  #else
  	    if (! first_word(buffer, "From ") && !forwarding_mail) {
  #endif /* MMDF */
! 	      MoveCursor(elm_LINES,0);
  	      Raw(OFF);
  	      printf(catgets(elm_msg_cat, ElmSet, ElmFolderCorrupt,
  		  "\nFolder is corrupt!!  I can't read it!!\n\n"));
***************
*** 644,650 ****
  			new_max * sizeof(struct header_rec *));
  		}
  		if (new_headers == NULL) {
! 	          MoveCursor(LINES,0);
  	          Raw(OFF);
  		  printf(catgets(elm_msg_cat, ElmSet, ElmCouldntAllocMemory,
  	"\n\nCouldn't allocate enough memory! Message #%d.\n\n"),
--- 772,778 ----
  			new_max * sizeof(struct header_rec *));
  		}
  		if (new_headers == NULL) {
! 	          MoveCursor(elm_LINES,0);
  	          Raw(OFF);
  		  printf(catgets(elm_msg_cat, ElmSet, ElmCouldntAllocMemory,
  	"\n\nCouldn't allocate enough memory! Message #%d.\n\n"),
***************
*** 663,669 ****
  
  		if ((h = (struct header_rec *)
  			  malloc(sizeof(struct header_rec))) == NULL) {
! 	          MoveCursor(LINES,0);
  	          Raw(OFF);
  		  printf(catgets(elm_msg_cat, ElmSet, ElmCouldntAllocMemory,
  	"\n\nCouldn't allocate enough memory! Message #%d.\n\n"),
--- 791,797 ----
  
  		if ((h = (struct header_rec *)
  			  malloc(sizeof(struct header_rec))) == NULL) {
! 	          MoveCursor(elm_LINES,0);
  	          Raw(OFF);
  		  printf(catgets(elm_msg_cat, ElmSet, ElmCouldntAllocMemory,
  	"\n\nCouldn't allocate enough memory! Message #%d.\n\n"),
***************
*** 670,712 ****
  			  count);
  		  leave(0);
  		}
  		headers[count] = h;
  	      }
  
  	      dprint(1, (debugfile, 
! 		   "\n**** Calling real_from for \"From_\" ****\n"));
  	      if (real_from(buffer, headers[count])) {
  
! 	        dprint(1, (debugfile, "\ncontent_remaining = %ld, content_start = %ld, lines_start = %ld, fbytes = %ld\n",
! 			content_remaining, content_start, lines_start, fbytes));
  
  		current_header = headers[count];
  
  		current_header->offset = (long) fbytes;
- 		current_header->content_length = -1; /* not found yet */
  		current_header->index_number = count+1;
  		content_length_found = FALSE;
! 		/* set default status - always 'visible'  - and
! 		 * if a spool file, presume 'new', otherwise
! 		 * 'read', for the time being until overridden
! 		 * by a Status: header.
! 		 * We presume 'read' for nonspool mailfile messages
! 		 * to be compatible messages stored with older versions of elm,
! 		 * which didn't support a Status: header.
! 		 */
! 		if(folder_type == SPOOL)
! 		  current_header->status = VISIBLE | NEW | UNREAD;
! 		else
! 		  current_header->status = VISIBLE;
  
! 		strcpy(current_header->subject, "");	/* clear subj    */
! 		strcpy(current_header->to, "");		/* clear to    */
! 		strcpy(current_header->mailx_status, "");	/* clear status flags */
! 		strcpy(current_header->time_menu, "");	/* clear menu date */
! 		strcpy(current_header->messageid, "<no.id>"); /* set no id into message id */
! 		current_header->encrypted = 0;		/* clear encrypted */
  		current_header->exit_disposition = UNSET;
- 		current_header->status_chgd = FALSE;
  
  		/* Set the number of lines for the _preceding_ message,
  		 * but only if there was a preceding message and
--- 798,833 ----
  			  count);
  		  leave(0);
  		}
+ 		header_zero(h);
  		headers[count] = h;
  	      }
  
+ 	      /* Need to be called before real_from, because real_from
+ 	       * sets time
+ 	       */
+ 	      header_clear(headers[count]);
+ 
  	      dprint(1, (debugfile, 
! 		   "\n**** Calling real_from for 'From ' ****\n"));
  	      if (real_from(buffer, headers[count])) {
  
! 	        dprint(1, (debugfile, 
! 			   "'From ' seen -- content_remaining = %ld, content_start = %ld, lines_start = %ld, fbytes = %ld\n",
! 			   content_remaining, content_start, lines_start, 
! 			   fbytes));
  
  		current_header = headers[count];
  
  		current_header->offset = (long) fbytes;
  		current_header->index_number = count+1;
  		content_length_found = FALSE;
! 		current_header->status = VISIBLE | NEW | UNREAD;
  
! 		Subject[0] = '\0';
! 		From[0]    = '\0';
! 		To[0] = 0;
! 		Cc[0] = 0;
  		current_header->exit_disposition = UNSET;
  
  		/* Set the number of lines for the _preceding_ message,
  		 * but only if there was a preceding message and
***************
*** 718,725 ****
  		if ((count) && (!add_new_only || count > message_count)) {
  		  headers[count-1]->lines = line;
  
! 		  if (headers[count-1]->content_length < 0)
! 		    headers[count-1]->content_length = fbytes - content_start;
  		}
  
  		count++;
--- 839,851 ----
  		if ((count) && (!add_new_only || count > message_count)) {
  		  headers[count-1]->lines = line;
  
! 		  if (headers[count-1]->content_length < 0) {
! 		    if (content_start >= 0) 
! 		      headers[count-1]->content_length = 
! 			fbytes - content_start;
! 		    else
! 		      headers[count-1]->content_length = 0;
! 		  }
  		}
  
  		count++;
***************
*** 726,733 ****
  		subj = 0;
  		line = 0;
  		in_header = TRUE;
  		if (count % readmsginc == 0)
! 		  PutLine1(count_x, count_y, "%d", count);
  #ifdef MMDF
  	      } else if (newheader) {
  		current_header = headers[count];
--- 852,860 ----
  		subj = 0;
  		line = 0;
  		in_header = TRUE;
+ 		content_start = -1L;
  		if (count % readmsginc == 0)
! 		  PutLineX(count_x, count_y, FRM("%d"), count);
  #ifdef MMDF
  	      } else if (newheader) {
  		current_header = headers[count];
***************
*** 749,765 ****
  		else
  		  current_header->status = VISIBLE;
  
! 		strcpy(current_header->from, "");		/* clear from    */
! 		strcpy(current_header->subject, "");	/* clear subj    */
! 		strcpy(current_header->to, "");		/* clear to    */
! 		strcpy(current_header->time_zone, "");	/* clear time zone name */
! 		strcpy(current_header->time_menu, "");	/* clear menu date */
! 		strcpy(current_header->mailx_status, "");	/* clear status flags */
! 		strcpy(current_header->messageid, "<no.id>"); /* set no id into message id */
! 		current_header->encrypted = 0;		/* clear encrypted */
  		current_header->exit_disposition = UNSET;
! 		current_header->status_chgd = FALSE;
! 
  		/* Set the number of lines for the _preceding_ message,
  		 * but only if there was a preceding message and
  		 * only if it wasn't calculated already. It would
--- 876,887 ----
  		else
  		  current_header->status = VISIBLE;
  
! 		Subject[0] = '\0';
! 		From[0] = '\0';
! 		To[0] = 0;
! 		Cc[0] = 0;
  		current_header->exit_disposition = UNSET;
! 		
  		/* Set the number of lines for the _preceding_ message,
  		 * but only if there was a preceding message and
  		 * only if it wasn't calculated already. It would
***************
*** 769,784 ****
  		 */
  		if (count && (!add_new_only || (count > message_count))) {
  		  headers[count-1]->lines = line;
! 		  if (headers[count-1]->content_length < 0)
! 		    headers[count-1]->content_length = fbytes - content_start;
  		}
  
  		count++;
  		subj = 0;
  		line = 0;
  		in_header = TRUE;
  		if (count % readmsginc == 0)
! 		  PutLine1(count_x, count_y, "%d", count);
  		dprint(1, (debugfile, 
  			     "\n**** Added header record ****\n"));
  #endif /* MMDF */
--- 891,915 ----
  		 */
  		if (count && (!add_new_only || (count > message_count))) {
  		  headers[count-1]->lines = line;
! 		  if (headers[count-1]->content_length < 0) {
! 		    if (content_start >= 0) 
! 		      headers[count-1]->content_length = 
! 			fbytes - content_start;
! 		    else
! 		      headers[count-1]->content_length = 0;
! 		  }
  		}
  
  		count++;
  		subj = 0;
  		line = 0;
+ 		content_start = -1L;
+ 		content_remaining = -1L;
+ 		content_length_found = FALSE;
+ 		in_what    = IN_none;
  		in_header = TRUE;
  		if (count % readmsginc == 0)
! 		  PutLineX(count_x, count_y, FRM("%d"), count);
  		dprint(1, (debugfile, 
  			     "\n**** Added header record ****\n"));
  #endif /* MMDF */
***************
*** 787,793 ****
  	      /* if this is the first "From" in file but the "From" line is
  	       * not of the proper format, we've got a corrupt folder.
  	       */
! 	      MoveCursor(LINES,0);
  	      Raw(OFF);
  	      printf(catgets(elm_msg_cat, ElmSet, ElmFolderCorrupt,
  		  "\nFolder is corrupt!!  I can't read it!!\n\n"));
--- 918,924 ----
  	      /* if this is the first "From" in file but the "From" line is
  	       * not of the proper format, we've got a corrupt folder.
  	       */
! 	      MoveCursor(elm_LINES,0);
  	      Raw(OFF);
  	      printf(catgets(elm_msg_cat, ElmSet, ElmFolderCorrupt,
  		  "\nFolder is corrupt!!  I can't read it!!\n\n"));
***************
*** 803,844 ****
  		 * in the spool file and the number of lines in the
  		 * message.
  		 */
! 	      if (fseek(mailfile, content_start, 0) == -1) {
! 		err = errno;
! 		MoveCursor(LINES, 0);
! 		Raw(OFF);
! 		printf(catgets(elm_msg_cat, ElmSet, ElmCouldntSeekBytesIntoFolder,
! 		   "\nCouldn't seek %ld bytes into folder.\n"),
! 		   mailfile_size);	
! 		printf("** %s. **\n", 1, error_description(err));
! 		dprint(1, (debugfile,
!       "Error: Couldn't seek folder %s: (offset %ld) Errno %s (%s)\n",
! 		   cur_folder, mailfile_size, error_description(err), "reset - read_headers"));
! 		emergency_exit();
! 	      }
! 	      if (copyit)
! 		if (fseek(temp, content_start, 0) == -1) {
  		  err = errno;
! 		  MoveCursor(LINES, 0);
  		  Raw(OFF);
! 		  printf(catgets(elm_msg_cat, ElmSet, ElmCouldntSeekBytesIntoTempFile,
! 		     "\nCouldn't seek %ld bytes into temp file.\n"),
! 		     mailfile_size);
! 		  printf("** %s. **\n", error_description(err));
  		  dprint(1, (debugfile,
! 	"Error: Couldn't seek temp file %s: (offset %ld) Errno %s (%s)\n",
! 		     cur_tempfolder, mailfile_size, error_description(err), "reset - read_headers"));
! 		  emergency_exit();
  		}
! 	      fbytes = content_start;
! 	      line = lines_start;
! 	      content_length_found = FALSE;
! 	      current_header->content_length = -1; /* mark as if not found yet */
! 	      line_bytes = 0;
  	    }
! 	  }
  
- 	  if (in_header == TRUE) {
  #ifdef MMDF
  	    if (strcmp(buffer, MSG_SEPARATOR) == 0) {
  	      /*
--- 934,1110 ----
  		 * in the spool file and the number of lines in the
  		 * message.
  		 */
! 	      if (content_start >= 0) {
! 		if (fseek(mailfile, content_start, 0) == -1) {
  		  err = errno;
! 		  MoveCursor(elm_LINES, 0);
  		  Raw(OFF);
! 		  printf(catgets(elm_msg_cat, ElmSet, 
! 				 ElmCouldntSeekBytesIntoFolder,
! 				 "\nCouldn't seek %ld bytes into folder.\n"),
! 			 mailfile_size);	
! 		  printf("** %s. **\n", 1, error_description(err));
  		  dprint(1, (debugfile,
! 			     "Error: Couldn't seek folder %s: (offset %ld) Errno %s (%s)\n",
! 			     cur_folder, mailfile_size, 
! 			     error_description(err), "reset - read_headers"));
! 		  emergency_exit(0);
! 		}
! 		if (copyit) {
! 		  if (fseek(temp, content_start, 0) == -1) {
! 		    err = errno;
! 		    MoveCursor(elm_LINES, 0);
! 		    Raw(OFF);
! 		    printf(catgets(elm_msg_cat, ElmSet, ElmCouldntSeekBytesIntoTempFile,
! 		       "\nCouldn't seek %ld bytes into temp file.\n"),
! 			   mailfile_size);
! 		    printf("** %s. **\n", error_description(err));
! 		    dprint(1, (debugfile,
! 			     "Error: Couldn't seek temp file %s: (offset %ld) Errno %s (%s)\n",
! 			     cur_tempfolder, mailfile_size, error_description(err), "reset - read_headers"));
! 		    emergency_exit(0);
! 		  }
  		}
! 		fbytes = content_start;
! 		line = lines_start;
! 		content_length_found = FALSE;
! 		current_header->content_length = -1; /* mark as if not found yet */
! 		line_bytes = 0;
! 	      }
  	    }
! 	    }
! 
! 	    /* Handling of continuation lines must be done before parsing
! 	     * next line!   or it don't work!   
! 	     *
! 	     * Another bug is that there can happen buffer overflow....
! 	     *   (well perhaps I can do quick fix for that)
! 	     *
! 	     *                              - K E H <hurtta@dionysos.FMi.FI>
! 	     */
! 
! 	    if (in_what == IN_to_list) {
! 	      dprint(12,(debugfile,"in_to_list; in_header=%d, buffer=%s\n",
! 			 in_header,buffer));
! 	      if (in_header && whitespace(buffer[0])) {
! 		if ((c = index(buffer, '\n')) != NULL)
! 		  *c = '\0';
! 		c = buffer;
! 		while (*c && isspace(*c)) ++c;
! 		strfcat(To, " ", 
! 			sizeof To);		  
! 		strfcat(To, c,
! 			sizeof To);
! 	      } else 
! 		in_what = IN_none;
! 	    } 
! 	    if (in_what == IN_cc_list) {
! 	      dprint(12,(debugfile,"in_cc_list; in_header=%d, buffer=%s\n",
! 			 in_header,buffer));
!               if (in_header && whitespace(buffer[0])) {
! 		if ((c = index(buffer, '\n')) != NULL)
! 		  *c = '\0';
! 		c = buffer;
! 		while (*c && isspace(*c)) ++c;
! 		strfcat(Cc, " ",sizeof Cc);
! 		strfcat(Cc, c, sizeof Cc);
! 	      } else
! 		in_what = IN_none;
! 	    }
! 	    if (in_what == IN_subject) {
! 	      dprint(12,(debugfile,"in_subject; in_header=%d, buffer=%s\n",
! 			 in_header,buffer));
! 
!               if (in_header && whitespace(buffer[0])) {
! 		int l = strlen(buffer);
! 		buffer[0] = ' ';
! 		if (l > 1 && buffer[l-2] == '\r' && buffer[l-1] == '\n')
! 		  buffer[l-2] = 0;
! 		if (buffer[l-1] == '\n')
! 		  buffer[l-1] = 0;
! 
!                 strfcat (Subject, buffer,sizeof(Subject));
! 		dprint(12,(debugfile,
! 			   "in_subject; l=%d => subject=%s\n",
! 			    l,Subject));
!               }
!               else 
! 		in_what = IN_none;
! 	      
! 	    }
! 	    if (in_what == IN_from) {
! 	      dprint(12,(debugfile,"in_from; in_header=%d, buffer=%s\n",
! 			 in_header,buffer));
! 
!               if (in_header && whitespace(buffer[0])) {
! 		int l = strlen(buffer);
! 		buffer[0] = ' ';
! 		if (l > 1 && buffer[l-2] == '\r' && buffer[l-1] == '\n')
! 		  buffer[l-2] = 0;
! 		if (buffer[l-1] == '\n')
! 		  buffer[l-1] = 0;
! 
!                 strfcat (From, buffer,sizeof(From));
! 		dprint(12,(debugfile,
! 			   "in_from; l=%d => from=%s\n",
! 			    l,From));
!               }
!               else 
! 		in_what = IN_none;
! 	    }
! 
! #ifdef MIME
! 	    if (is_content) {
! 	      dprint(12,(debugfile,"is_content; in_header=%d, buffer=%s\n",
! 			 in_header,buffer));
!               if (in_header && whitespace(buffer[0])) {
! 		int l = strlen(buffer);
! 		buffer[0] = ' ';
! 		if (l > 1 && buffer[l-2] == '\r' && buffer[l-1] == '\n')
! 		  buffer[l-2] = 0;
! 		if (buffer[l-1] == '\n')
! 		  buffer[l-1] = 0;
! 
!                 strfcat (content_type, buffer,sizeof(content_type));
! 		dprint(12,(debugfile,
! 			   "is_content=%d,l=%d => content_type=%s\n",
! 			    is_content,l,content_type));
!               }
!               else {
! 		char buf [STRING];
! 		dprint(12,(debugfile,
! 			   "is_content=%d => content_type=%s\n",
! 			   is_content,content_type));
! 		if (is_content == 1) {
! 
! 		  if (is_pre_mime_content_type(&current_header->mime_rec,
! 					       content_type)) {
! 
! 		    dprint(12,(debugfile,"NOT mime's content-type: %s\n",
! 			       content_type));
! 		      
! 		    current_header->status |= PRE_MIME_CONTENT;
! 		  }
!                   else {
! 		    dprint(12,(debugfile,"MIME's content-type: %s\n",
! 			       content_type));
! 
! 		    mime_get_content (content_type, &current_header->mime_rec);
!                     if (mime_notplain(&current_header->mime_rec))
!                       current_header->mime_rec.notplain = TRUE;
! 		  }
! 		}
! 		else if (is_content == 2) {
! 		  mime_get_disposition (content_type, 
! 					&current_header->mime_rec);
! 		}
! 		is_content = 0;
!               }
! 	    }
! #endif
! 
! 	 if (in_header == TRUE) {
  
  #ifdef MMDF
  	    if (strcmp(buffer, MSG_SEPARATOR) == 0) {
  	      /*
***************
*** 854,887 ****
  	      real_from(buffer, current_header);
  	    } else
  #endif /* MMDF */
! 	    if (header_cmp(buffer,">From", NULL))
! 	      parse_arpa_who(buffer, current_header->from, FALSE);
! 	    else if (first_word_nc(buffer,">From")) 
! 	      forwarded(buffer, current_header); /* return address */
  	    else if (header_cmp(buffer,"Subject", NULL) ||
  		     header_cmp(buffer,"Subj", NULL) ||
  		     header_cmp(buffer,"Re", NULL)) {
  	      if (! subj++) {
! 		strfcpy(tbuffer, buffer, sizeof(tbuffer));
! 	        remove_header_keyword(tbuffer);
! 	        copy_sans_escape(current_header->subject, tbuffer, STRING);
! 		remove_possible_trailing_spaces(current_header->subject);
  	      }
  	    }
  	    else if (header_cmp(buffer,"From", NULL)) {
! 	      dprint(1, (debugfile, 
! 		   "\n**** Calling parse_arpa_who for \"From\" ****\n"));
! #ifdef MMDF
! 	      parse_arpa_who(buffer, current_header->from, TRUE);
! #else
! 	      parse_arpa_who(buffer, current_header->from, FALSE);
! #endif /* MMDF */
! 
  	    }
  	    else if (header_cmp(buffer, "Message-Id", NULL)) {
! 	      buffer[line_bytes - 1] = '\0';
! 	      strcpy(current_header->messageid,
! 		     (char *) buffer + 12);
  	    }
  
  	    else if (header_cmp(buffer, "Content-Length", NULL)) {
--- 1120,1165 ----
  	      real_from(buffer, current_header);
  	    } else
  #endif /* MMDF */
! 	    if (first_word_nc(buffer,">From ")) 
! 	      forwarded(buffer+6, current_header); /* return address */
  	    else if (header_cmp(buffer,"Subject", NULL) ||
  		     header_cmp(buffer,"Subj", NULL) ||
  		     header_cmp(buffer,"Re", NULL)) {
  	      if (! subj++) {
! 		int l = strlen(buffer);
! 		in_what = IN_subject;
! 		if (buffer[l-2] == '\r' && buffer[l-1] == '\n')
! 		  buffer[l-2] = 0;
! 		if (buffer[l-1] == '\n')
! 		  buffer[l-1] = 0;
! 		strfcpy (Subject, buffer,sizeof(Subject));
! 		remove_header_keyword(Subject);
! 		dprint(12,(debugfile,"in_subject; START! Subject: %s\n",
! 			   Subject));
  	      }
  	    }
  	    else if (header_cmp(buffer,"From", NULL)) {
! 		int l = strlen(buffer);
! 		if (l > 1 && buffer[l-2] == '\r' && buffer[l-1] == '\n')
! 		  buffer[l-2] = 0;
! 		if (buffer[l-1] == '\n')
! 		  buffer[l-1] = 0;
! 
!                 strfcpy (From, buffer+6,sizeof(From));
! 		dprint(12,(debugfile,
! 			   "Starting in_from; l=%d => from=%s\n",
! 			    l,From));
! 		in_what = IN_from;
  	    }
  	    else if (header_cmp(buffer, "Message-Id", NULL)) {
! 	      int l = strlen(buffer);
! 	      if (buffer[l-2] == '\r' && buffer[l-1] == '\n')
! 		buffer[l-2] = 0;
! 	      if (buffer[l-1] == '\n')
! 		buffer[l-1] = 0;
! 
! 	      strfcpy(current_header->messageid,
! 		      buffer + 12, sizeof current_header->messageid);
  	    }
  
  	    else if (header_cmp(buffer, "Content-Length", NULL)) {
***************
*** 920,947 ****
  	      current_header->status |= PRIVATE;
  	    else if (header_cmp(buffer, "Sensitivity", "3"))
  	      current_header->status |= CONFIDENTIAL;
! 	    else if (header_cmp(buffer, "Content-Type", "mailform"))
! 	      current_header->status |= FORM_LETTER;
  	    else if (header_cmp(buffer, "Action", NULL))
  	      current_header->status |= ACTION;
  #ifdef	MIME
  	    else if (header_cmp(buffer, MIME_HEADER_NAME, MIME_HEADER_VERSION))
  	      current_header->status |= MIME_MESSAGE;
! 	    /* Next two lines for backward compatability to old drafts */
! 	    else if (header_cmp(buffer, MIME_HEADER_NAME, MIME_HEADER_OLDVERSION))
! 	      current_header->status |= MIME_MESSAGE;
! 	    /* Next two lines for minimal support for mail generated by
! 	     * Sun's Openwindows mailtool */
! 	    else if (header_cmp(buffer, "Content-Type", "X-"))
! 	      current_header->status |= MIME_MESSAGE|MIME_NOTPLAIN;
  	    else if (header_cmp(buffer, MIME_HEADER_CONTENTTYPE, NULL)) {
! 	      if (! (current_header->status & MIME_NOTPLAIN) &&
! 		  notplain(buffer+strlen(MIME_CONTENTTYPE)))
! 		current_header->status |= MIME_NOTPLAIN;
  	    }
  	    else if (header_cmp(buffer, MIME_HEADER_CONTENTENCOD, NULL)) {
! 	      if (needs_mmdecode(buffer+strlen(MIME_CONTENTENCOD)))
! 		current_header->status |= MIME_NEEDDECOD;
  	    }
  #endif /* MIME */
  
--- 1198,1266 ----
  	      current_header->status |= PRIVATE;
  	    else if (header_cmp(buffer, "Sensitivity", "3"))
  	      current_header->status |= CONFIDENTIAL;
! 	    else if (header_cmp(buffer, "Content-Type", "mailform")) 
! 	      current_header->status |= FORM_LETTER | PRE_MIME_CONTENT;
  	    else if (header_cmp(buffer, "Action", NULL))
  	      current_header->status |= ACTION;
  #ifdef	MIME
+ 	    else if (header_cmp(buffer, "X-ELM-OSV",NULL)) {
+ 	      char value [20];
+ 	      if (mime_get_param("no-hdr-encoding",value,buffer+10,
+ 				 sizeof value)) {
+ 		int i = atoi(value);
+ 		dprint(12,(debugfile,"-- no-hdr-encoding=%d\n",i));
+ 		if (i) 
+ 		  current_header->status |= NOHDRENCODING;
+ 	      }
+ 	    }
+ 	    /* We should accept headers like:
+ 	     *    MIME-Version: (MetaSend v1.7) 1.0
+ 	     * And if version number is something other accept it but give 
+ 	     * warning when message is viewed or replied.
+ 	     * Perhaps in next version. 
+ 	     */
  	    else if (header_cmp(buffer, MIME_HEADER_NAME, MIME_HEADER_VERSION))
  	      current_header->status |= MIME_MESSAGE;
!             else if (header_cmp(buffer, MIME_HEADER_NAME, NULL))
!               current_header->status |= MIME_MESSAGE|MIME_UNSUPPORTED;
  	    else if (header_cmp(buffer, MIME_HEADER_CONTENTTYPE, NULL)) {
! 	      int l = strlen(buffer);
!               is_content = 1;   /* This is quick hack -- mime headers
! 				 * should be decoded with mime_read_header
! 				 * otherwise we duplicate code ...
! 				 *     - K E H     <hurtta@dionysos.FMI.FI>
! 				 */
! 	      if (buffer[l-2] == '\r' && buffer[l-1] == '\n')
! 		buffer[l-2] = 0;
! 	      if (buffer[l-1] == '\n')
! 		buffer[l-1] = 0;
!               strfcpy (content_type, buffer + 13, sizeof(content_type));
! 	    }
! 	    else if (header_cmp(buffer, "Content-Disposition", NULL)) {
! 	      int l = strlen(buffer);
!               is_content = 2;   /* This is quick hack -- mime headers
! 				 * should be decoded with mime_read_header
! 				 * otherwise we duplicate code ...
! 				 *     - K E H     <hurtta@dionysos.FMI.FI>
! 				 */	
! 	      if (buffer[l-2] == '\r' && buffer[l-1] == '\n')
! 		buffer[l-2] = 0;
! 	      if (buffer[l-1] == '\n')
! 		buffer[l-1] = 0;
!               strfcpy (content_type, buffer + 20, sizeof(content_type));
  	    }
  	    else if (header_cmp(buffer, MIME_HEADER_CONTENTENCOD, NULL)) {
! 	      int l = strlen(buffer);
! 	      if (buffer[l-2] == '\r' && buffer[l-1] == '\n')
! 		buffer[l-2] = 0;
! 	      if (buffer[l-1] == '\n')
! 		buffer[l-1] = 0;
! 
!               c = buffer + MIME_CONTENTENCOD_LEN;
!               while (*c && isspace(*c)) ++c;
!               current_header->mime_rec.encoding = check_encoding (c);
! 	      if (mime_notplain(&current_header->mime_rec))
! 		current_header->mime_rec.notplain = TRUE;
  	    }
  #endif /* MIME */
  
***************
*** 948,957 ****
  	    /** next let's see if it's to us or not... **/
  
  	    else if (header_cmp(buffer, "To", NULL)) {
! 	      in_to_list = TRUE;
! 	      current_header->to[0] = '\0';	/* nothing yet */
! 	      figure_out_addressee((char *) buffer +3, 
! 				   current_header->to);
  	    }
  	    else if (header_cmp(buffer, "Status", NULL)) {
  	      strfcpy(tbuffer, buffer, sizeof(tbuffer));
--- 1267,1293 ----
  	    /** next let's see if it's to us or not... **/
  
  	    else if (header_cmp(buffer, "To", NULL)) {
! 	      in_what = IN_to_list;
! 
! 	      if ((c = index(buffer, '\n')) != NULL)
! 		*c = '\0';
! 	      c = buffer + 3;
! 	      while (*c && isspace(*c)) ++c;
! 
! 	      if (To[0] != '\0')
! 		strfcat(To, ", ",sizeof To);
! 	      strfcat(To, c, sizeof To);
! 	    }
! 	    else if (header_cmp(buffer, "Cc", NULL)) {
! 	      in_what = IN_cc_list;
! 	      if ((c = index(buffer, '\n')) != NULL)
! 		*c = '\0';
! 	      c = buffer + 3;
! 
! 	      while (*c && isspace(*c)) ++c;
! 	      if (Cc[0] != '\0')
! 		strfcat(Cc, ", ",sizeof Cc);
! 	      strfcat(Cc, c, sizeof Cc);
  	    }
  	    else if (header_cmp(buffer, "Status", NULL)) {
  	      strfcpy(tbuffer, buffer, sizeof(tbuffer));
***************
*** 961,966 ****
--- 1297,1305 ----
  	      c = index(current_header->mailx_status, '\n');
  	      if (c != NULL)
  		*c = '\0';
+ 	      c = index(current_header->mailx_status, '\r');
+ 	      if (c != NULL)
+ 		*c = '\0';
  	      remove_possible_trailing_spaces(current_header->mailx_status);
  
  	      /* Okay readjust the status. If there's an 'R', message
***************
*** 974,1021 ****
  		current_header->status &= ~NEW;
  		current_header->status |= UNREAD;
  	      }
  	    }
  
! 	    else if (buffer[0] == LINE_FEED || buffer[0] == '\0') {
  	      in_header = FALSE;	/* in body of message! */
- 	      in_to_list = FALSE;
  	      content_remaining = current_header->content_length;
  	      content_start = fbytes + 1;
  	      lines_start = line;
  	    }
  	    if (in_header == TRUE) {
  	       if ((!whitespace(buffer[0])) && index(buffer, ':') == NULL) {
  	        in_header = FALSE;	/* in body of message! */
- 	        in_to_list = FALSE;
  	        content_remaining = current_header->content_length;
  	        content_start = fbytes;
  	        lines_start = line;
  	      }
  	    }
! 	    if (in_to_list == TRUE) {
! 	      if (whitespace(buffer[0]))
! 	        figure_out_addressee(buffer, current_header->to);
! 	      else in_to_list = FALSE;
  	    }
  	  }
- 	  if (in_header == FALSE && first_word(buffer, START_ENCODE))
- 	    current_header->encrypted = 1;
  	  fbytes += (long) line_bytes;
  	  content_remaining -= (long) line_bytes;
  	}
  
  	if (count) {
  	  headers[count-1]->lines = line + 1;
! 	  if (headers[count-1]->content_length < 0)
! 	    headers[count-1]->content_length = fbytes - content_start;
  	}
  
  	if (folder_type == SPOOL) {
! 	  fflush (mailfile);
! 	  unlock();	/* remove lock file! */
  	  if ((ferror(mailfile)) || (fclose(mailfile) == EOF)) {
  	    err = errno;
! 	    MoveCursor(LINES, 0);
  	    Raw(OFF);
  	    printf(catgets(elm_msg_cat, ElmSet, ElmCloseOnFolderFailed,
  			   "\nClose on folder %s failed!!\n"),
--- 1313,1526 ----
  		current_header->status &= ~NEW;
  		current_header->status |= UNREAD;
  	      }
+               if (index(current_header->mailx_status, 'r') != NULL)
+                 current_header->status |= REPLIED;
  	    }
  
! 	    else if (buffer[0] == LINE_FEED || buffer[0] == '\0' ||
! 		     buffer[0] == '\r' && buffer[1] == '\n') {
! 	      current_header->binary = 
! 		(buffer[0] == '\r' && buffer[1] == '\n');
  	      in_header = FALSE;	/* in body of message! */
  	      content_remaining = current_header->content_length;
  	      content_start = fbytes + 1;
+ 	      if (current_header->binary)
+ 		content_start = fbytes + 2;
  	      lines_start = line;
+ #ifdef MIME
+ 	      current_header->mime_rec.offset = ftell (mailfile);
+ #endif
  	    }
  	    if (in_header == TRUE) {
  	       if ((!whitespace(buffer[0])) && index(buffer, ':') == NULL) {
  	        in_header = FALSE;	/* in body of message! */
  	        content_remaining = current_header->content_length;
  	        content_start = fbytes;
  	        lines_start = line;
+ #ifdef MIME
+ 	      current_header->mime_rec.offset = content_start;
+ #endif
+ 	      }
+ 	    }
+ 	    /* No longer in headers */
+ 	    if (in_header == FALSE) {
+ 	      struct addr_item * addrs;
+ #ifdef MIME
+ 	      if (req_mime_hdrencoding &&
+ 		  !(current_header->status & MIME_MESSAGE)) {
+ 		current_header -> status |= NOHDRENCODING;
+ 		dprint(12,(debugfile,"-- Turning on NOHDRENCODING\n"));
+ 	      }
+ 
+ 	      if (!req_mime_bodyencoding && 
+ 		  !(current_header->status & PRE_MIME_CONTENT)) {
+ 		current_header -> status |= MIME_MESSAGE;
+ 		dprint(12,(debugfile,"-- Turning on MIME_MESSAGE\n"));
+ 	      }
+ 
+ 	      if (!(current_header -> status & NOHDRENCODING) &&
+ 		  is_rfc1522(Subject)) 
+ 		rfc1522_decode(Subject,sizeof(Subject));
+ #endif
+ 	        copy_sans_escape(current_header->subject, Subject, STRING);
+ 		remove_possible_trailing_spaces(current_header->subject);
+ 		dprint(12,(debugfile,"-- Decoded subject: %s\n",
+ 			   current_header->subject));
+ 
+ 
+ 
+ 	      dprint(1, (debugfile, 
+ 		   "\n**** Calling parse_arpa_who for \"From\" ****\n"));
+ 
+ 	      addrs = break_down_address(From,
+ #ifdef MIME
+ 					 !(current_header -> status & NOHDRENCODING) &&
+ 					 is_rfc1522(From) ?
+ 					 rfc1522_decode_structured : decode_who_none
+ #else
+ 					 decode_who_none
+ #endif
+ 					 );
+ 
+ 	      if (addrs) {
+ 		if (current_header->from)
+ 		  free_addr_items(current_header->from);
+ 		current_header->from = addrs;
  	      }
+ 
+ 	      addrs = break_down_address(To,
+ #ifdef MIME
+ 					 !(current_header -> status & NOHDRENCODING) &&
+ 					 is_rfc1522(To) ?
+ 					 rfc1522_decode_structured : decode_who_none
+ #else
+ 					 decode_who_none
+ #endif
+ 					 );
+ 
+ 	      if (addrs) {
+ 		if (current_header->to)
+ 		  free_addr_items(current_header->to);
+ 		current_header->to = addrs;
+ 	      }
+ 
+ 	      addrs = break_down_address(Cc,
+ #ifdef MIME
+ 					 !(current_header -> status & NOHDRENCODING) &&
+ 					 is_rfc1522(Cc) ?
+ 					 rfc1522_decode_structured : decode_who_none
+ #else
+ 					 decode_who_none
+ #endif
+ 					 );
+ 
+ 	      if (addrs) {
+ 		if (current_header->cc)
+ 		  free_addr_items(current_header->cc);
+ 		current_header->cc = addrs;
+ 	      }
+ 
+ 	    }
+ 	  }
+ 	  if (in_header == FALSE) {
+ 	    if (first_word(buffer, START_ENCODE)) {
+ 	      current_header->encrypted = 1;
+ 	      dprint(12,(debugfile,"-- encrypted: %s\n",buffer));
+ #ifdef MIME
+ 	      /* Text/plain can be converted to application/X-ELM-encode */
+ 	      if (current_header->mime_rec.type == MIME_TYPE_TEXT && 
+ 		  (istrcmp(current_header->mime_rec.subtype,"plain")==0)) {
+ 		  current_header->mime_rec.type = MIME_TYPE_APPLICATION;
+ 		  strfcpy(current_header->mime_rec.subtype, "X-ELM-encode",
+ 			  sizeof current_header->mime_rec.subtype);
+ 		  /* Keep current_header->mime_rec.type_opts ! */
+ 	      }
+ 	      dprint(12,(debugfile,"-- encrypted, %d/%s; opts=%s\n",
+ 			 current_header->mime_rec.type,
+ 			 current_header->mime_rec.subtype,
+ 			 NONULL(current_header->mime_rec.type_opts)));
+ #endif /* MIME */
  	    }
! #ifdef USE_PGP
! 	    if (strncmp(buffer, "-----BEGIN PGP", 14) == 0) {
! 	      if (strncmp(buffer + 15, "PUBLIC", 6) == 0) {
! 		current_header->pgp |= PGP_PUBLIC_KEY;
! 		dprint(12,(debugfile,"-- PGP PUBLIC KEY: %s\n",buffer));
! 	      } else {
! #ifdef MIME
! 		char pgpbuffer[STRING];
! 
! 		/* Text/plain can be converted to application/pgp.  There will
! 		 * a possible loss of surrounding text, but there is no way
! 		 * to get around this without having the sender use the proper
! 		 * MIME type.
! 		 */
! 		if (current_header->mime_rec.type == MIME_TYPE_TEXT && 
! 		    istrcmp(current_header->mime_rec.subtype,"plain")==0) {
! 		  current_header->mime_rec.type = MIME_TYPE_APPLICATION;
! 		  strfcpy(current_header->mime_rec.subtype, "pgp",
! 			  sizeof current_header->mime_rec.subtype);
! 		  /* Keep current_header->mime_rec.type_opts ! */
! 		}
! #endif
! 		if (strncmp(buffer + 15, "SIG", 3) == 0) {
! 		  current_header->pgp |= PGP_SIGNED_MESSAGE;
! 		  dprint(12,(debugfile,"-- PGP signed: %s\n",buffer));
! #ifdef MIME
! 		  if (!mime_get_param("x-action",
! 				      pgpbuffer,
! 				      current_header->mime_rec.type_opts,
! 				      sizeof(pgpbuffer))) {
! 		      add_parameter_t(&(current_header->mime_rec),
! 				      "x-action", "sign",
! 				      FALSE);
! 		  }
! 		  dprint(12,(debugfile,"-- PGP signed, %d/%s; opts=%s\n",
! 			     current_header->mime_rec.type,
! 			     current_header->mime_rec.subtype,
! 			     NONULL(current_header->mime_rec.type_opts)));
! #endif
! 		}
! 		else {
! 		  current_header->pgp |= PGP_MESSAGE;
! 		  dprint(12,(debugfile,"-- PGP message: %s\n",buffer));
! #ifdef MIME
! 		  if (!mime_get_param("x-action",pgpbuffer,
! 				      current_header->mime_rec.type_opts,
! 				      sizeof(pgpbuffer))) {		    
! 		      add_parameter_t(&(current_header->mime_rec),
! 				      "x-action", "encrypt",FALSE);
! 		  }
! 		  dprint(12,(debugfile,"-- PGP message, %d/%s; opts=%s\n",
! 			     current_header->mime_rec.type,
! 			     current_header->mime_rec.subtype,
! 			     NONULL(current_header->mime_rec.type_opts)));
! #endif
! 		}
!               }
  	    }
+ #endif /* USE_PGP */
  	  }
  	  fbytes += (long) line_bytes;
+ 	  
  	  content_remaining -= (long) line_bytes;
  	}
  
  	if (count) {
  	  headers[count-1]->lines = line + 1;
! 	  if (headers[count-1]->content_length < 0) {
! 	    if (content_start >= 0L)
! 	      headers[count-1]->content_length = fbytes - content_start;
! 	    else
! 	      headers[count-1]->content_length = 0;
! 	  }
  	}
  
  	if (folder_type == SPOOL) {
! 	  unlock(0);	/* remove lock file! */
  	  if ((ferror(mailfile)) || (fclose(mailfile) == EOF)) {
  	    err = errno;
! 	    MoveCursor(elm_LINES, 0);
  	    Raw(OFF);
  	    printf(catgets(elm_msg_cat, ElmSet, ElmCloseOnFolderFailed,
  			   "\nClose on folder %s failed!!\n"),
***************
*** 1028,1034 ****
  
  	  if ((ferror(temp)) || (fclose(temp) == EOF)) {
  	      err = errno;
! 	      MoveCursor(LINES, 0);
  	      Raw(OFF);
  	      printf(catgets(elm_msg_cat, ElmSet, ElmCloseOnTempFailed,
  			      "\nClose on temp file %s failed!!\n"), 
--- 1533,1539 ----
  
  	  if ((ferror(temp)) || (fclose(temp) == EOF)) {
  	      err = errno;
! 	      MoveCursor(elm_LINES, 0);
  	      Raw(OFF);
  	      printf(catgets(elm_msg_cat, ElmSet, ElmCloseOnTempFailed,
  			      "\nClose on temp file %s failed!!\n"), 
***************
*** 1041,1047 ****
  
  	  /* sanity check on append - is resulting temp file longer??? */
  	  if ( bytes(cur_tempfolder) != mailfile_size) {
! 	     MoveCursor(LINES, 0);
  	     Raw(OFF);
  	     printf(catgets(elm_msg_cat, ElmSet, ElmLengthNESpool,
  	       "\nnewmbox - length of mbox. != spool mailbox length!!\n"));
--- 1546,1552 ----
  
  	  /* sanity check on append - is resulting temp file longer??? */
  	  if ( bytes(cur_tempfolder) != mailfile_size) {
! 	     MoveCursor(elm_LINES, 0);
  	     Raw(OFF);
  	     printf(catgets(elm_msg_cat, ElmSet, ElmLengthNESpool,
  	       "\nnewmbox - length of mbox. != spool mailbox length!!\n"));
***************
*** 1051,1057 ****
  
  	  if ((mailfile = fopen(cur_tempfolder,"r")) == NULL) {
  	    err = errno;
! 	    MoveCursor(LINES,0);
  	    Raw(OFF);
  	    printf(catgets(elm_msg_cat, ElmSet, ElmCouldntReopenForTemp,
  		   "\nCouldn't reopen file %s for use as temp file.\n"),
--- 1556,1562 ----
  
  	  if ((mailfile = fopen(cur_tempfolder,"r")) == NULL) {
  	    err = errno;
! 	    MoveCursor(elm_LINES,0);
  	    Raw(OFF);
  	    printf(catgets(elm_msg_cat, ElmSet, ElmCouldntReopenForTemp,
  		   "\nCouldn't reopen file %s for use as temp file.\n"),
Index: elm2.4.ME+.50/src/options.c
*** elm2.4.25/src/options.c	Mon May 30 19:42:50 1994
--- elm2.4.ME+.50/src/options.c	Tue Nov 17 21:12:58 1998
***************
*** 1,135 ****
  
! static char rcsid[] = "@(#)$Id: options.c,v 5.18 1994/05/30 16:42:48 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.18 $   $State: Exp $
   *
   * 			Copyright (c) 1986,1987 Dave Taylor
   * 			Copyright (c) 1988-1992 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: options.c,v $
!  * Revision 5.18  1994/05/30  16:42:48  syd
!  * Just a minor fix to an impossible character comparison.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.17  1994/03/11  21:25:24  syd
!  * Fix Elm looping if an EOF is received.
!  * From: Gregory Neil Shapiro <gshapiro@WPI.EDU>
!  *
!  * Revision 5.16  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.15  1993/07/20  02:41:24  syd
!  * Three changes to expand_env() in src/read_rc.c:  make it non-destructive,
!  * have it return an error code instead of bailing out, and add a buffer
!  * size argument to avoid overwritting the destination.  The first is to
!  * avoid all of the gymnastics Elm needed to go through (and occasionally
!  * forgot to go through) to protect the value handed to expand_env().
!  * The second is because expand_env() was originally written to support
!  * "elmrc" and bailing out was a reasonable thing to do there -- but not
!  * in the other places where it has since been used.  The third is just
!  * a matter of practicing safe source code.
!  *
!  * This patch changes all invocations to expand_env() to eliminate making
!  * temporary copies (now that the routine is non-destructive) and to pass
!  * in a destination length.  Since expand_env() no longer bails out on
!  * error, a do_expand_env() routine was added to src/read_rc.c handle
!  * this.  Moreover, the error message now gives some indication of what
!  * the problem is rather than just saying "can't expand".
!  *
!  * Gratitous change to src/editmsg.c renaming filename variables to
!  * clarify the purpose.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.14  1993/06/12  05:32:00  syd
!  * fix calling sequence for new argument
!  * From: Syd
!  *
!  * Revision 5.13  1993/06/10  03:07:39  syd
!  * This fixes a bug in the MIME code.  Include_Part() uses expand_env()
!  * to expand the include file name, but since expand_env() is destructive
!  * [it uses strtok()] the file name gets corrupted, and the "Content-Name"
!  * header can contain a bogus value.  The easy fix would be a one-line
!  * hack to Include_Part to use a temporary buffer.  This patch does not
!  * implement the easy fix.  *Every* place expand_env() is used, its side
!  * effects cause problems.  I think the right fix is to make expand_env()
!  * non-destructive (i.e. have it duplicate the input to a temporary buffer
!  * and work from there).  The attached patch modifies expand_env() in
!  * that manner, and eliminates all of the `copy to a temporary buffer'
!  * calls that precede it throughout elm.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.12  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.11  1993/05/08  17:04:15  syd
!  * Jan's removal of tolower in alias.c breaks help for 'I'.  This fixes
!  * that and makes the help messages for characters that have printable
!  * synonyms on the alias and options screens consistent with the help files.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.10  1993/04/21  01:35:36  syd
!  * NLS message ElmOptionBorderMenu should be ElmOptionBorderHelp in one place.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.9  1993/04/12  03:05:59  syd
!  * The wrong NLS message was used in the option screen for the "A(l)ias Sorting".
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.8  1993/04/12  03:05:31  syd
!  * The primary editor didn't change at once when you entered a new value in
!  * the option screen.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.7  1993/04/12  03:00:57  syd
!  * None of i, q, x, >, and ^L are recognized by the single character help
!  * on the options screen.  <return> causes the options screen to scroll
!  * because all non-printing characters are echoed by the error message.
!  * Options and alias help files didn't list all commands.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.6  1993/02/03  19:06:31  syd
!  * Remove extra strchr/strcat/strcpy et al declarations
!  * From: Syd
!  *
!  * Revision 5.5  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.4  1993/01/20  03:02:19  syd
!  * Move string declarations to defs.h
!  * From: Syd
!  *
!  * Revision 5.3  1992/11/07  19:37:21  syd
!  * Enhanced printing support.  Added "-I" to readmsg to
!  * suppress spurious diagnostic messages.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.2  1992/10/24  13:35:39  syd
!  * changes found by using codecenter on Elm 2.4.3
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This set of routines allows the alteration of a number of paramaters
      in the Elm mailer, including the following;
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: options.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1986,1987 Dave Taylor
   * 			Copyright (c) 1988-1992 USENET Community Trust
!  ****************************************************************************/
  
  /** This set of routines allows the alteration of a number of paramaters
      in the Elm mailer, including the following;
***************
*** 179,184 ****
--- 60,66 ----
  #include "headers.h"
  #include "save_opts.h"
  #include "s_elm.h"
+ #include "me.h"
  
  #undef onoff
  #define   onoff(n)	(n == 1? on_name : off_name)
***************
*** 226,232 ****
  static post_sent(f)
  int f;
  {
!     (void) expand_env(sent_mail, raw_sentmail, sizeof(sent_mail));
  }
  
  static post_print(f)
--- 108,125 ----
  static post_sent(f)
  int f;
  {
!   char     buffer[SLEN];
! 
!   (void) expand_env(sent_mail, raw_sentmail, sizeof(sent_mail));
!   
! #define  metachar(c)	(c == '+' || c == '%' || c == '=')
! 
!   if(metachar(sent_mail[0])) {
!     
!     strfcpy(buffer, &sent_mail[1], sizeof buffer);
!     elm_sfprintf(sent_mail, sizeof sent_mail,
! 		 FRM("%s/%s"), folders, buffer);
!   }
  }
  
  static post_print(f)
***************
*** 238,244 ****
  static post_menu(f)
  int f;
  {
!     headers_per_page = LINES - (mini_menu ? 13 : 8);
  }
  
  opts_menu cfg_opts[] = {
--- 131,137 ----
  static post_menu(f)
  int f;
  {
!     headers_per_page = elm_LINES - (mini_menu ? 13 : 8);
  }
  
  opts_menu cfg_opts[] = {
***************
*** 385,398 ****
  		continue;
  	    }
              o = find_cfg_opts(*s);
!             if (o != NULL && y<LINES-5) {
! 		sprintf(buf,"%-20.20s : %%s", o->menu);
! 		PutLine1(y, 0, buf, str_opt_nam(o->parm, FULL));
  		}
  	    }
  	if (!printed_title) {
! 	    Centerline(LINES-5, catgets(elm_msg_cat, ElmSet, ElmOptionsEditor,
! 		"-- ELM Options Editor --"));
  	}
  }
  
--- 278,293 ----
  		continue;
  	    }
              o = find_cfg_opts(*s);
!             if (o != NULL && y<elm_LINES-5) {
! 	      PutLineX(y, 0, FRM("%-20.20s : %s"), 
! 		       o->menu,
! 		       str_opt_nam(o->parm, FULL));
  		}
  	    }
  	if (!printed_title) {
! 	    Centerline(elm_LINES-5, catgets(elm_msg_cat, ElmSet, 
! 					    ElmOptionsEditor,
! 					    "-- ELM Options Editor --"));
  	}
  }
  
***************
*** 405,417 ****
  	char	*ptr, *prompt;
  	int	c;
  
! 	ClearLine(LINES-2);		/* clear option prompt message */
! 	Centerline(LINES-3, catgets(elm_msg_cat, ElmSet, ElmPressKeyHelp,
    "Press the key you want help for, '?' for a key list, or '.' to exit help"));
  
  	lower_prompt(prompt = catgets(elm_msg_cat, ElmSet, ElmKeyPrompt, "Key : "));
  
! 	while ((c = ReadCh()) != '.') {
  	  if (c == EOF)
  	    leave(0);
  
--- 300,312 ----
  	char	*ptr, *prompt;
  	int	c;
  
! 	ClearLine(elm_LINES-2);		/* clear option prompt message */
! 	Centerline(elm_LINES-3, catgets(elm_msg_cat, ElmSet, ElmPressKeyHelp,
    "Press the key you want help for, '?' for a key list, or '.' to exit help"));
  
  	lower_prompt(prompt = catgets(elm_msg_cat, ElmSet, ElmKeyPrompt, "Key : "));
  
! 	while ((c = ReadCh(0)) != '.') {
  	  if (c == EOF)
  	    leave(0);
  
***************
*** 424,454 ****
  	  }
  
  	  if ((ptr = one_liner_for(c)) != NULL)
! 	    error2("%c = %s", c, ptr);
  	  else
  	    switch (c) {
! 	      case ctrl('L'): error(catgets(elm_msg_cat, ElmSet,
! 				  ElmOptionCtrlLHelp,
! 				  "^L = Rewrite the screen."));		break;
  
- 	      case '>' : error(catgets(elm_msg_cat, ElmSet,ElmOptionGreaterHelp,
- 				"> = Save to elmrc file."));		break;
- 
  	      case 'q' :
! 	      case 'i' : error(catgets(elm_msg_cat, ElmSet, ElmOptionReturnHelp,
! 				"i,q = Return from option menu."));	break;
! 
! 	      case 'x' : error(catgets(elm_msg_cat, ElmSet, ElmHelpQuickExit,
! 				"X = Exit leaving the folder untouched, unconditionally."));
  				break;
  
! 	      default: error(catgets(elm_msg_cat, ElmSet, ElmKeyIsntUsed,
! 				"That key isn't used in this section."));
  	    }
  	  lower_prompt(prompt);
  	}
! 	ClearLine(LINES-3);		/* clear Press help key message */
! 	ClearLine(LINES-1);		/* clear lower prompt message */
  }
  
  
--- 319,355 ----
  	  }
  
  	  if ((ptr = one_liner_for(c)) != NULL)
! 	    lib_error(FRM("%c = %s"), c, ptr);
  	  else
  	    switch (c) {
! 	      case ctrl('L'): lib_error(CATGETS(elm_msg_cat, ElmSet,
! 						ElmOptionCtrlLHelp,
! 						"^L = Rewrite the screen."));
! 	      break;
! 
! 	      case '>' : lib_error(CATGETS(elm_msg_cat, ElmSet,
! 					   ElmOptionGreaterHelp,
! 					   "> = Save to elmrc file."));
! 	      break;
  
  	      case 'q' :
! 	      case 'i' : lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					   ElmOptionReturnHelp,
! 					   "i,q = Return from option menu."));
! 	      break;
! 
! 	      case 'x' : lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 					   ElmHelpQuickExit,
! 					   "X = Exit leaving the folder untouched, unconditionally."));
  				break;
  
! 	      default: lib_error(CATGETS(elm_msg_cat, ElmSet, ElmKeyIsntUsed,
! 					 "That key isn't used in this section."));
  	    }
  	  lower_prompt(prompt);
  	}
! 	ClearLine(elm_LINES-3);		/* clear Press help key message */
! 	ClearLine(elm_LINES-1);		/* clear lower prompt message */
  }
  
  
***************
*** 491,503 ****
  	}
  	if (!config_options[0]) {
  #ifdef ENABLE_CALENDAR
! 	    strcpy(config_options,"^_cdefsopyv_am_un");
  #else
! 	    strcpy(config_options,"^_defsopyv_am_un");
  #endif
  	}
  
! 
  	resort = 0;
  	prompt = catgets(elm_msg_cat, ElmSet, ElmPrompt, "Command: ");
  	display_options();
--- 392,406 ----
  	}
  	if (!config_options[0]) {
  #ifdef ENABLE_CALENDAR
! 	    strfcpy(config_options,"^_cdefsopyv_am_un",
! 		    sizeof config_options);
  #else
! 	    strfcpy(config_options,"^_defsopyv_am_un",
! 		    sizeof config_options);
  #endif
  	}
  
! redraw:
  	resort = 0;
  	prompt = catgets(elm_msg_cat, ElmSet, ElmPrompt, "Command: ");
  	display_options();
***************
*** 505,518 ****
  	clearerr(stdin);
  
  	while(1) {
! 	  ClearLine(LINES-4);
  
! 	  Centerline(LINES-4, catgets(elm_msg_cat, ElmSet, ElmSelectOptionLetter,
   "Select letter of option line, '>' to save, or 'i' to return to index."));
  
! 	  PutLine0(LINES-2, 0, prompt);
  
! 	  ch = ReadCh();
  	  if (ch == EOF)
  	    leave(0);
  	  ch = tolower(ch);
--- 408,424 ----
  	clearerr(stdin);
  
  	while(1) {
! 	  ClearLine(elm_LINES-4);
  
! 	  Centerline(elm_LINES-4, catgets(elm_msg_cat, ElmSet, 
! 					  ElmSelectOptionLetter,
   "Select letter of option line, '>' to save, or 'i' to return to index."));
  
! 	  PutLine0(elm_LINES-2, 0, prompt);
  
! 	  ch = ReadCh(REDRAW_MARK);
! 	  if (ch == REDRAW_MARK)
! 	    goto redraw;
  	  if (ch == EOF)
  	    leave(0);
  	  ch = tolower(ch);
***************
*** 522,543 ****
  	  if (index(config_options, ch)) {
  	      y = index(config_options,ch) - config_options;
                o = find_cfg_opts(ch);
!               if (o != NULL && y < LINES-5) {
  		  one_liner(o->one_liner);
  		  y = info_enter(o->parm, y, 23, FALSE, FALSE);
  		  if (o->post)
  		      (o->post)(y);
  	      } else
! 	          error(catgets(elm_msg_cat, ElmSet, ElmCommandUnknown,
! 			"Command unknown!"));
  	  } else {
  	      one_liner(NULL);
  	      switch (ch) {
  	    case '?' : options_help(); 
! 	               PutLine0(LINES-2,0, prompt);			break;
  	   
! 	    case '>' : printf(catgets(elm_msg_cat, ElmSet, ElmSaveOptions,
! 			"Save options in .elm/elmrc..."));
  		       fflush(stdout);    save_options();		break;
  
  	    case 'x' :	return(-1);	/* exit elm */
--- 428,449 ----
  	  if (index(config_options, ch)) {
  	      y = index(config_options,ch) - config_options;
                o = find_cfg_opts(ch);
!               if (o != NULL && y < elm_LINES-5) {
  		  one_liner(o->one_liner);
  		  y = info_enter(o->parm, y, 23, FALSE, FALSE);
  		  if (o->post)
  		      (o->post)(y);
  	      } else
! 	          lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCommandUnknown,
! 				    "Command unknown!"));
  	  } else {
  	      one_liner(NULL);
  	      switch (ch) {
  	    case '?' : options_help(); 
! 	               PutLine0(elm_LINES-2,0, prompt);			break;
  	   
! 	    case '>' : lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSaveOptions,
! 					 "Save options in .elm/elmrc..."));
  		       fflush(stdout);    save_options();		break;
  
  	    case 'x' :	return(-1);	/* exit elm */
***************
*** 545,552 ****
  	    case 'i' :  /* return to index screen */
  			return(resort ? 1 : 0);
  	    case ctrl('L'): display_options();				break;
! 	    default: error(catgets(elm_msg_cat, ElmSet, ElmCommandUnknown,
! 			"Command unknown!"));
  	      }
  	  }
  	}
--- 451,458 ----
  	    case 'i' :  /* return to index screen */
  			return(resort ? 1 : 0);
  	    case ctrl('L'): display_options();				break;
! 	    default: lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCommandUnknown,
! 				       "Command unknown!"));
  	      }
  	  }
  	}
***************
*** 567,573 ****
  	MoveCursor(x,y+3);	/* at end of value... */
  
  	do {
! 	  ch = ReadCh();
  
  	  if (ch == SPACE) {
  	    *var = ! *var;
--- 473,479 ----
  	MoveCursor(x,y+3);	/* at end of value... */
  
  	do {
! 	  ch = ReadCh(0);
  
  	  if (ch == SPACE) {
  	    *var = ! *var;
***************
*** 589,597 ****
  
  	MoveCursor(x,y);	/* at end of value... */
  
! 	while (ReadCh() == ' ') {
  	  *ulevel = (*ulevel >= 2? 0 : *ulevel + 1);
! 	  PutLine1(x,y, "%s", level_name(*ulevel));
  	}
  
  	MoveCursor(x,y+20); 	CleartoEOLN();	/* remove help prompt */
--- 495,503 ----
  
  	MoveCursor(x,y);	/* at end of value... */
  
! 	while (ReadCh(0) == ' ') {
  	  *ulevel = (*ulevel >= 2? 0 : *ulevel + 1);
! 	  PutLineX(x,y, FRM("%s"), level_name(*ulevel));
  	}
  
  	MoveCursor(x,y+20); 	CleartoEOLN();	/* remove help prompt */
***************
*** 612,624 ****
  /*	*var = sortby; 	or...	*var == sortby; 	*/
  	last_sortby = sortby;	/* remember current ordering   */
  
! 	PutLine0(x, COLUMNS-29, catgets(elm_msg_cat, ElmSet, ElmSpaceForNext,
! 		"(SPACE for next, or R)everse)"));
  	sort_one_liner(sortby);
  	MoveCursor(x, y);
  
  	do {
! 	  ch = ReadCh();
  	  ch = tolower(ch);
  	  switch (ch) {
  	    case SPACE : if (sortby < 0) { 
--- 518,531 ----
  /*	*var = sortby; 	or...	*var == sortby; 	*/
  	last_sortby = sortby;	/* remember current ordering   */
  
! 	PutLine0(x, elm_COLUMNS-29, 
! 		 catgets(elm_msg_cat, ElmSet, ElmSpaceForNext,
! 			 "(SPACE for next, or R)everse)"));
  	sort_one_liner(sortby);
  	MoveCursor(x, y);
  
  	do {
! 	  ch = ReadCh(0);
  	  ch = tolower(ch);
  	  switch (ch) {
  	    case SPACE : if (sortby < 0) { 
***************
*** 640,655 ****
  	 }
          } while (ch == SPACE || ch == 'r');
  
! 	MoveCursor(x, COLUMNS-30);	CleartoEOLN();
  
  	if (sortby != last_sortby) {
! 	  error(catgets(elm_msg_cat, ElmSet, ElmResortingFolder,
! 		"Resorting folder..."));
  	  if (sleepmsg > 0)
  		sleep((sleepmsg + 1) / 2);
  	  sort_mailbox(message_count, 0);
  	}
! 	ClearLine(LINES-2);		/* clear sort_one_liner()! */
  	*var=sortby;
  	sortby=last_sortby;
  	return(*var-sortby);
--- 547,562 ----
  	 }
          } while (ch == SPACE || ch == 'r');
  
! 	MoveCursor(x, elm_COLUMNS-30);	CleartoEOLN();
  
  	if (sortby != last_sortby) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmResortingFolder,
! 			    "Resorting folder..."));
  	  if (sleepmsg > 0)
  		sleep((sleepmsg + 1) / 2);
  	  sort_mailbox(message_count, 0);
  	}
! 	ClearLine(elm_LINES-2);		/* clear sort_one_liner()! */
  	*var=sortby;
  	sortby=last_sortby;
  	return(*var-sortby);
***************
*** 661,669 ****
  {
  	/** A single-line description of the selected item... **/
  
! 	ClearLine(LINES-4);
  	if (string)
! 		Centerline(LINES-4, string);
  }
  
  
--- 568,576 ----
  {
  	/** A single-line description of the selected item... **/
  
! 	ClearLine(elm_LINES-4);
  	if (string)
! 		Centerline(elm_LINES-4, string);
  }
  
  
***************
*** 672,734 ****
  {
  	/** A one line summary of the particular sorting scheme... **/
  
! 	ClearLine(LINES-2);
  
  	switch (sorting_by) {
  	  
! 	  case REVERSE SENT_DATE:	Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRSentDate,
  "This sort will order most-recently-sent to least-recently-sent"));
  				break;
! 	  case REVERSE RECEIVED_DATE:	Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRRecvDate,
  "This sort will order most-recently-received to least-recently-received"));
  				break;
! 	  case REVERSE MAILBOX_ORDER:	Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRMailbox,
  "This sort will order most-recently-added-to-folder to least-recently"));
  				break;
! 	  case REVERSE SENDER:		Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRSender,
  "This sort will order by sender name, in reverse alphabetical order"));
  				break;
! 	  case REVERSE SIZE:		Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRSize,
  "This sort will order messages by longest to shortest"));
  				break;
! 	  case REVERSE SUBJECT:		Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRSubject,
  "This sort will order by subject, in reverse alphabetical order"));
  				break;
! 	  case REVERSE STATUS:		Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRStatus,
  "This sort will order by reverse status - Deleted through Tagged..."));
  				break;
! 	  case SENT_DATE:		Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortSentDate,
  "This sort will order least-recently-sent to most-recently-sent"));
  				break;
! 	  case RECEIVED_DATE:		Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRecvDate,
  "This sort will order least-recently-received to most-recently-received"));
  				break;
! 	  case MAILBOX_ORDER:		Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortMailbox,
  "This sort will order least-recently-added-to-folder to most-recently"));
  				break;
! 	  case SENDER:			Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortSender,
  "This sort will order by sender name"));
  				break;
! 	  case SIZE:			Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortSize,
  "This sort will order messages by shortest to longest"));
  				break;
! 	  case SUBJECT:			Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortSubject,
  "This sort will order messages by subject"));
  				break;
! 	  case STATUS:			Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortStatus,
  "This sort will order by status - Tagged through Deleted..."));
  				break;
--- 579,641 ----
  {
  	/** A one line summary of the particular sorting scheme... **/
  
! 	ClearLine(elm_LINES-2);
  
  	switch (sorting_by) {
  	  
! 	  case REVERSE SENT_DATE:	Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRSentDate,
  "This sort will order most-recently-sent to least-recently-sent"));
  				break;
! 	  case REVERSE RECEIVED_DATE:	Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRRecvDate,
  "This sort will order most-recently-received to least-recently-received"));
  				break;
! 	  case REVERSE MAILBOX_ORDER:	Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRMailbox,
  "This sort will order most-recently-added-to-folder to least-recently"));
  				break;
! 	  case REVERSE SENDER:		Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRSender,
  "This sort will order by sender name, in reverse alphabetical order"));
  				break;
! 	  case REVERSE SIZE:		Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRSize,
  "This sort will order messages by longest to shortest"));
  				break;
! 	  case REVERSE SUBJECT:		Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRSubject,
  "This sort will order by subject, in reverse alphabetical order"));
  				break;
! 	  case REVERSE STATUS:		Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRStatus,
  "This sort will order by reverse status - Deleted through Tagged..."));
  				break;
! 	  case SENT_DATE:		Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortSentDate,
  "This sort will order least-recently-sent to most-recently-sent"));
  				break;
! 	  case RECEIVED_DATE:		Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortRecvDate,
  "This sort will order least-recently-received to most-recently-received"));
  				break;
! 	  case MAILBOX_ORDER:		Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortMailbox,
  "This sort will order least-recently-added-to-folder to most-recently"));
  				break;
! 	  case SENDER:			Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortSender,
  "This sort will order by sender name"));
  				break;
! 	  case SIZE:			Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortSize,
  "This sort will order messages by shortest to longest"));
  				break;
! 	  case SUBJECT:			Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortSubject,
  "This sort will order messages by subject"));
  				break;
! 	  case STATUS:			Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmSortStatus,
  "This sort will order by status - Tagged through Deleted..."));
  				break;
***************
*** 751,763 ****
  /*	*var = alias_sortby; 	or...	*var == alias_sortby; 	*/
  	last_sortby = alias_sortby;	/* remember current ordering   */
  
! 	PutLine0(x, COLUMNS-29, catgets(elm_msg_cat, ElmSet, ElmSpaceForNext,
! 		"(SPACE for next, or R)everse)"));
  	alias_sort_one_liner(alias_sortby);
  	MoveCursor(x, y);
  
  	do {
! 	  ch = ReadCh();
  	  ch = tolower(ch);
  	  switch (ch) {
  	    case SPACE : if (alias_sortby < 0) { 
--- 658,671 ----
  /*	*var = alias_sortby; 	or...	*var == alias_sortby; 	*/
  	last_sortby = alias_sortby;	/* remember current ordering   */
  
! 	PutLine0(x, elm_COLUMNS-29, 
! 		 catgets(elm_msg_cat, ElmSet, ElmSpaceForNext,
! 			 "(SPACE for next, or R)everse)"));
  	alias_sort_one_liner(alias_sortby);
  	MoveCursor(x, y);
  
  	do {
! 	  ch = ReadCh(0);
  	  ch = tolower(ch);
  	  switch (ch) {
  	    case SPACE : if (alias_sortby < 0) { 
***************
*** 780,790 ****
  	 }
          } while (ch == SPACE || ch == 'r');
  
! 	MoveCursor(x, COLUMNS-30);	CleartoEOLN();
  
  	if (alias_sortby != last_sortby) {
! 	  error(catgets(elm_msg_cat, ElmSet, ElmResortingAliases,
! 			"Resorting aliases..."));
  	  if (sleepmsg > 0)
  		sleep((sleepmsg + 1) / 2);
  	  main_state();
--- 688,698 ----
  	 }
          } while (ch == SPACE || ch == 'r');
  
! 	MoveCursor(x, elm_COLUMNS-30);	CleartoEOLN();
  
  	if (alias_sortby != last_sortby) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmResortingAliases,
! 			    "Resorting aliases..."));
  	  if (sleepmsg > 0)
  		sleep((sleepmsg + 1) / 2);
  	  main_state();
***************
*** 791,797 ****
  	  sort_aliases(message_count, FALSE, FALSE);
  	  main_state();
  	}
! 	ClearLine(LINES-2);		/* clear alias_sort_one_liner()! */
  	*var=alias_sortby;
  	alias_sortby=last_sortby;
  	return(*var-alias_sortby);
--- 699,705 ----
  	  sort_aliases(message_count, FALSE, FALSE);
  	  main_state();
  	}
! 	ClearLine(elm_LINES-2);		/* clear alias_sort_one_liner()! */
  	*var=alias_sortby;
  	alias_sortby=last_sortby;
  	return(*var-alias_sortby);
***************
*** 802,833 ****
  {
  	/** A one line summary of the particular sorting scheme... **/
  
! 	ClearLine(LINES-2);
  
  	switch (sorting_by) {
  	  
! 	  case REVERSE ALIAS_SORT:	Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmASortRAlias,
  "This sort will order by alias name, in reverse alphabetical order"));
  					break;
! 	  case REVERSE NAME_SORT:	Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmASortRName,
  "This sort will order by user (real) name, in reverse alphabetical order"));
  					break;
! 	  case REVERSE TEXT_SORT:	Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmASortRText,
  "This sort will order aliases in the reverse order as listed in aliases.text"));
  					break;
  
! 	  case ALIAS_SORT:		Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmASortAlias,
  "This sort will order by alias name"));
  					break;
! 	  case NAME_SORT:		Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmASortName,
  "This sort will order by user (real) name"));
  					break;
! 	  case TEXT_SORT:		Centerline(LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmASortText,
  "This sort will order aliases in the order as listed in aliases.text"));
  					break;
--- 710,741 ----
  {
  	/** A one line summary of the particular sorting scheme... **/
  
! 	ClearLine(elm_LINES-2);
  
  	switch (sorting_by) {
  	  
! 	  case REVERSE ALIAS_SORT:	Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmASortRAlias,
  "This sort will order by alias name, in reverse alphabetical order"));
  					break;
! 	  case REVERSE NAME_SORT:	Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmASortRName,
  "This sort will order by user (real) name, in reverse alphabetical order"));
  					break;
! 	  case REVERSE TEXT_SORT:	Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmASortRText,
  "This sort will order aliases in the reverse order as listed in aliases.text"));
  					break;
  
! 	  case ALIAS_SORT:		Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmASortAlias,
  "This sort will order by alias name"));
  					break;
! 	  case NAME_SORT:		Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmASortName,
  "This sort will order by user (real) name"));
  					break;
! 	  case TEXT_SORT:		Centerline(elm_LINES-2,
  				catgets(elm_msg_cat, ElmSet, ElmASortText,
  "This sort will order aliases in the order as listed in aliases.text"));
  					break;
***************
*** 845,851 ****
  int ypos, xpos, append_current, passwd;
  {
  	register int x,q;
! 	char buffer[SLEN];
  	int number;
  
  	for (x = 0; x < NUMBER_OF_SAVEABLE_OPTIONS; x++) {
--- 753,759 ----
  int ypos, xpos, append_current, passwd;
  {
  	register int x,q;
! 	char buffer[SLEN+1];
  	int number;
  
  	for (x = 0; x < NUMBER_OF_SAVEABLE_OPTIONS; x++) {
***************
*** 859,865 ****
  
  	switch(save_info[x].flags & DT_MASK) {
  	    case DT_STR:
! 		strcpy(buffer, SAVE_INFO_STR(x));
  		if (save_info[x].flags & FL_NOSPC) {
  		    register char *s;
  		    for (s = buffer; *s; ++s)
--- 767,774 ----
  
  	switch(save_info[x].flags & DT_MASK) {
  	    case DT_STR:
! 		strfcpy(buffer, SAVE_INFO_STR(x),
! 			sizeof buffer);
  		if (save_info[x].flags & FL_NOSPC) {
  		    register char *s;
  		    for (s = buffer; *s; ++s)
***************
*** 867,873 ****
  			    *s='_';
  		}
  
! 		optionally_enter(buffer, ypos, xpos, append_current, passwd);
  
  		if (save_info[x].flags & FL_NOSPC) {
  		    register char *s;
--- 776,785 ----
  			    *s='_';
  		}
  
! 		optionally_enter(buffer, ypos, xpos, 
! 				 (append_current ? OE_APPEND_CURRENT : 0) |
! 				 (passwd ? OE_PASSWD : 0),
! 				 sizeof buffer);
  
  		if (save_info[x].flags & FL_NOSPC) {
  		    register char *s;
***************
*** 879,885 ****
  		if (equal(buffer, SAVE_INFO_STR(x)))
  		    break;
  
! 		strcpy(SAVE_INFO_STR(x), buffer);
  		q++;
  		break;
  
--- 791,798 ----
  		if (equal(buffer, SAVE_INFO_STR(x)))
  		    break;
  
! 		strfcpy(SAVE_INFO_STR(x), buffer,
! 			save_info[x].size_val);
  		q++;
  		break;
  
Index: elm2.4.ME+.50/src/out_utils.c
*** elm2.4.25/src/out_utils.c	Wed Feb  3 21:06:50 1993
--- elm2.4.ME+.50/src/out_utils.c	Tue Nov 17 21:12:57 1998
***************
*** 1,28 ****
  
! static char rcsid[] = "@(#)$Id: out_utils.c,v 5.2 1993/02/03 19:06:31 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: out_utils.c,v $
!  * Revision 5.2  1993/02/03  19:06:31  syd
!  * Remove extra strchr/strcat/strcpy et al declarations
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This file contains routines used for output in the ELM program.
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: out_utils.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This file contains routines used for output in the ELM program.
  
***************
*** 29,36 ****
  **/
  
  #include "headers.h"
  
- 
  static char err_buffer[SLEN];		/* store last error message */
  
  static char central_message_buffer[SLEN];
--- 17,24 ----
  **/
  
  #include "headers.h"
+ #include "me.h"
  
  static char err_buffer[SLEN];		/* store last error message */
  
  static char central_message_buffer[SLEN];
***************
*** 37,128 ****
  
  show_last_error()
  {
! 	/** rewrite last error message! **/
! 
! 	error(err_buffer);
  }
  
  clear_error()
  {
! 	MoveCursor(LINES,0);
! 	CleartoEOLN();
! 	err_buffer[0] = '\0';
  }
  
  set_error(s)
  char *s;
  {
! 	strcpy(err_buffer, s);
  }
  
- error(s)
- char *s;
- {
- 	/** outputs error 's' to screen at line 22, centered! **/
  
! 	if(batch_only)
! 	  printf("%s\n\r", s);
! 	else {
! 	  MoveCursor(LINES,0);
! 	  CleartoEOLN();
! 	  PutLine0(LINES,(COLUMNS-strlen(s))/2,s);
! 	  fflush(stdout);
! 	}
! 	strcpy(err_buffer, s);	/* save it too! */
  }
  
! /*VARARGS1*/
! 
! error1(s, a)
! char *s, *a;
  {
! 	/** same as error, but with a 'printf' argument **/
! 	char buffer[SLEN];
  
- 	sprintf(buffer,s,a);
- 	error(buffer);
- }
  
! /*VARARGS1*/
  
! error2(s, a1, a2)
! char *s, *a1, *a2;
! {
! 	/** same as error, but with two 'printf' arguments **/
! 	char buffer[SLEN];
  
! 	MCsprintf(buffer,s, a1, a2);
! 	error(buffer);
  }
  
! /*VARARGS1*/
! 
! error3(s, a1, a2, a3)
! char *s, *a1, *a2, *a3;
! {
! 	/** same as error, but with three 'printf' arguments **/
! 	char buffer[SLEN];
! 
! 	MCsprintf(buffer,s, a1, a2, a3);
! 	error(buffer);
  }
  
  lower_prompt(s)
  char *s;
  {
! 	/** prompt user for input on LINES-1 line, left justified **/
! 
! 	PutLine0(LINES-1,0,s);
! 	CleartoEOLN();
  }
  
  prompt(s)
  char *s;
  {
! 	/** prompt user for input on LINES-3 line, left justified **/
  
! 	PutLine0(LINES-3,0,s);
! 	CleartoEOLN();
  }
  
  
--- 25,126 ----
  
  show_last_error()
  {
!   /** rewrite last error message! **/
!   if(RawState()) {
!     error(err_buffer);
!   }
  }
  
  clear_error()
  {
!   if(RawState()) {
!     MoveCursor(elm_LINES,0);
!     CleartoEOLN();
!     err_buffer[0] = '\0';
!   }
  }
  
  set_error(s)
  char *s;
  {
!   strfcpy(err_buffer, s, sizeof err_buffer);
  }
  
  
! static void error_help P_((const char *s));
! static void error_help (s)
!      const char *s;
! {
!   MoveCursor(elm_LINES,0);
!   CleartoEOLN();
!   PutLine0(elm_LINES,(elm_COLUMNS-strlen(s))/2,s);
!   fflush(stdout);
  }
  
! int error(s)
!      const char *s;
  {
! 	/** outputs error 's' to screen at line 22, centered! **/
  
  
!   dprint(1, (debugfile, "ERROR message: %s\n", 
! 	     s));
  
!   if(!RawState())
!     printf("%s\n", s);
  
!   else if (strlen(s) < elm_COLUMNS && NULL == strchr(s,'\n'))
!     error_help(s);
!   else {
!     char * s1 = safe_strdup(s);
!     char *s2, *s3;
!     
!     for (s2=s1; *s2 != '\0'; s2 = s3) {
!       char c;
!       for (s3 = s2; *s3 != '\0' && s3 - s2 < elm_COLUMNS && *s3 != '\n'; s3++);
!       c = *s3;
!       *s3 = '\0';
!       error_help(s2);
!       *s3 = c;
!       if ('\n' == c)
! 	s3++;
!     }
! 
!     free(s1);
!   }
!   strfcpy(err_buffer, s, sizeof err_buffer);	/* save it too! */
!   return 0;
  }
  
! void out_util_setup() {
!   set_error_handler(error);
  }
  
+ 
  lower_prompt(s)
  char *s;
  {
!   /** prompt user for input on LINES-1 line, left justified **/
!   
!   if(RawState()) {
!     PutLine0(elm_LINES-1,0,s);
!     CleartoEOLN();
!   } else {
!     fprintf(stderr,"%s\n",s);
!   }
  }
  
  prompt(s)
  char *s;
  {
!   /** prompt user for input on LINES-3 line, left justified **/
  
!   if(RawState()) {
!     PutLine0(elm_LINES-3,0,s);
!     CleartoEOLN();
!   } else {
!     fprintf(stderr,"%s\n",s);
!   }
  }
  
  
***************
*** 129,154 ****
  set_central_message(string, arg)
  char *string, *arg;
  {
! 	/** set up the given message to be displayed in the center of
! 	    the current window **/ 
  
! 	sprintf(central_message_buffer, string, arg);
  }
  
  display_central_message()
  {
! 	/** display the message if set... **/
  
! 	if (central_message_buffer[0] != '\0') {
! 	  ClearLine(LINES-15);
! 	  Centerline(LINES-15, central_message_buffer);
! 	  fflush(stdout);
! 	}
  }
  
  clear_central_message()
  {
! 	/** clear the central message buffer **/
  
! 	central_message_buffer[0] = '\0';
  }
--- 127,160 ----
  set_central_message(string, arg)
  char *string, *arg;
  {
!   /** set up the given message to be displayed in the center of
!     the current window **/ 
  
!   sprintf(central_message_buffer, string, arg);
!     
  }
  
  display_central_message()
  {
!   /** display the message if set... **/
  
!   if(RawState()) {
!     if (central_message_buffer[0] != '\0') {
!       ClearLine(elm_LINES-15);
!       Centerline(elm_LINES-15, central_message_buffer);
!       fflush(stdout);
!     }
!   }
  }
  
  clear_central_message()
  {
!   /** clear the central message buffer **/
! 
!   central_message_buffer[0] = '\0';
! }
  
! void sleep_message() {
!   if (sleepmsg > 0)
!     sleep(sleepmsg);
  }
Index: elm2.4.ME+.50/src/pattern.c
*** elm2.4.25/src/pattern.c	Mon May 16 02:05:20 1994
--- elm2.4.ME+.50/src/pattern.c	Tue Nov 17 21:12:57 1998
***************
*** 1,75 ****
  
! static char rcsid[] = "@(#)$Id: pattern.c,v 5.11 1994/05/15 23:04:48 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.11 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: pattern.c,v $
!  * Revision 5.11  1994/05/15  23:04:48  syd
!  * Fix segv where in_string didnot like searching NULL
!  * From: Stuart Kemp <stuart@cs.jcu.edu.au> (via syd)
!  *
!  * Revision 5.10  1993/09/19  23:15:28  syd
!  * Changed a few buffers from LONG_STRING (512) to VERY_LONG_STRING
!  * to avoid long header lines overflowing the allocated space. At
!  * least 1024 bytes should be allowed in any header line/field.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.9  1993/05/14  03:53:46  syd
!  * Fix wrong message being displayed and then overwritten
!  * for long aliases.
!  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
!  *
!  * Revision 5.8  1993/04/12  02:34:36  syd
!  * I have now added a parameter which controls whether want_to clears the
!  * line and centers the question or behaves like it did before. I also
!  * added a 0 at the end of the parameter list to all the other calls to
!  * want_to where a centered question on a clean line is not desirable.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.7  1993/02/03  19:06:31  syd
!  * Remove extra strchr/strcat/strcpy et al declarations
!  * From: Syd
!  *
!  * Revision 5.6  1993/01/19  05:10:13  syd
!  * There is a mismatch between the number of args and the format string in
!  * src/pattern.c.
!  * In nls/C/C/C/s_filter.m there is a , after OutOfMemory.
!  * This is my fault, and although it doesn't seem to affect things, there is no
!  * need for it.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.5  1992/12/25  00:30:37  syd
!  * change way message works
!  *
!  * Revision 5.4  1992/12/25  00:22:39  syd
!  * add missing *
!  * From: Syd
!  *
!  * Revision 5.3  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.2  1992/11/26  00:46:50  syd
!  * Fix how errno is used so err is inited and used instead
!  * as errno gets overwritten by print system call
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /**    General pattern matching for the ELM mailer.     
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: pattern.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  ****************************************************************************/
  
  /**    General pattern matching for the ELM mailer.     
  
***************
*** 79,84 ****
--- 20,26 ----
  
  #include "headers.h"
  #include "s_elm.h"
+ #include "me.h"
  
  static char pattern[SLEN] = { "" };
  static char alt_pattern[SLEN] = { "" };
***************
*** 114,119 ****
--- 56,62 ----
  	register int i, tagged=0, count=0, curtag = 0;
  	char		msg[SLEN];
  	static char     meta_pattern[SLEN];
+ 	int status;
  
  	if (delete_word == NULL) {
  	     tag_word = catgets(elm_msg_cat, ElmSet, ElmTag, "Tag");
***************
*** 128,136 ****
  	     enter_pattern = catgets(elm_msg_cat, ElmSet, ElmEnterPattern, "Enter pattern: ");
  	}
  
! 	PutLine2(LINES-3, strlen(Prompt), catgets(elm_msg_cat, ElmSet, ElmMessagesMatchPattern,
! 	     "%s %s that match pattern..."), 
! 	     function==TAGGED?tag_word: function==DELETED?delete_word:undelete_word, items);
  
  	if (function == TAGGED) {	/* are messages already tagged??? */
  	  for (i=0; i < message_count; i++)
--- 71,80 ----
  	     enter_pattern = catgets(elm_msg_cat, ElmSet, ElmEnterPattern, "Enter pattern: ");
  	}
  
! 	PutLineX(elm_LINES-3, strlen(Prompt), CATGETS(elm_msg_cat, ElmSet, 
! 						      ElmMessagesMatchPattern,
! 						      "%s %s that match pattern..."), 
! 		 function==TAGGED?tag_word: function==DELETED?delete_word:undelete_word, items);
  
  	if (function == TAGGED) {	/* are messages already tagged??? */
  	  for (i=0; i < message_count; i++)
***************
*** 140,159 ****
  
  	  if (tagged) {
  	    if (tagged > 1) {
! 	      MCsprintf(tagmsg, catgets(elm_msg_cat, ElmSet, ElmSomeMessagesATagged,
! 		"Some %s are already tagged."), items);
! 	      MCsprintf(msg, catgets(elm_msg_cat, ElmSet, ElmRemoveTags,
! 		"%s Remove Tags? (%c/%c) "),
! 		tagmsg, *def_ans_yes, *def_ans_no);
  	    } else {
! 	      MCsprintf(tagmsg, catgets(elm_msg_cat, ElmSet, ElmAMessageATagged,
! 		"One %s is already tagged."), item);
! 	      MCsprintf(msg, catgets(elm_msg_cat, ElmSet, ElmRemoveTag,
! 		"%s Remove Tag? (%c/%c) "),
! 		tagmsg, *def_ans_yes, *def_ans_no);
  	    }
  	
! 	    ch = want_to(msg, *def_ans_yes, LINES-2, 0);
  	    if (ch != *def_ans_no) {	/* remove tags... */
  	      for (i=0; i < message_count; i++) {
  	        if (inalias)
--- 84,110 ----
  
  	  if (tagged) {
  	    if (tagged > 1) {
! 	      elm_sfprintf(tagmsg, sizeof tagmsg,
! 			   CATGETS(elm_msg_cat, ElmSet, 
! 				   ElmSomeMessagesATagged,
! 				   "Some %s are already tagged."), 
! 			   items);
! 	      elm_sfprintf(msg, sizeof msg,
! 			   CATGETS(elm_msg_cat, ElmSet, ElmRemoveTags,
! 				   "%s Remove Tags? (%c/%c) "),
! 			   tagmsg, *def_ans_yes, *def_ans_no);
  	    } else {
! 	      elm_sfprintf(tagmsg, sizeof tagmsg,
! 			   CATGETS(elm_msg_cat, ElmSet, ElmAMessageATagged,
! 				   "One %s is already tagged."), 
! 			   item);
! 	      elm_sfprintf(msg, sizeof msg,
! 			   CATGETS(elm_msg_cat, ElmSet, ElmRemoveTag,
! 				   "%s Remove Tag? (%c/%c) "),
! 			   tagmsg, *def_ans_yes, *def_ans_no);
  	    }
  	
! 	    ch = want_to(msg, *def_ans_yes, elm_LINES-2, 0);
  	    if (ch != *def_ans_no) {	/* remove tags... */
  	      for (i=0; i < message_count; i++) {
  	        if (inalias)
***************
*** 166,183 ****
  	  }
  	}
  	
! 	PutLine0(LINES-2,0, enter_pattern);
  	CleartoEOLN();
  
! 	optionally_enter(meta_pattern, LINES-2, strlen(enter_pattern),
! 	  FALSE, FALSE);
  
! 	if (strlen(meta_pattern) == 0) {
! 	  ClearLine(LINES-2);
  	  return(curtag);
  	}
  
! 	strcpy(meta_pattern, shift_lower(meta_pattern));   /* lowercase it */
  
  	if (inalias) {
  	  for (i = 0; i < message_count; i++) {
--- 117,146 ----
  	  }
  	}
  	
! 	PutLine0(elm_LINES-2,0, enter_pattern);
  	CleartoEOLN();
  
! 	status = optionally_enter(meta_pattern, elm_LINES-2, 
! 				  strlen(enter_pattern),
! 				  OE_REDRAW_MARK, sizeof meta_pattern);
! 	while (status == REDRAW_MARK) {
! 	  PutLine0(elm_LINES-2,0, enter_pattern);
! 	  status = optionally_enter(meta_pattern, elm_LINES-2, 
! 				    strlen(enter_pattern),
! 				    OE_REDRAW_MARK|OE_APPEND_CURRENT,
! 				    sizeof meta_pattern);
! 	}
  
! 	if (status != 0 || strlen(meta_pattern) == 0) {
! 	  ClearLine(elm_LINES-2);
  	  return(curtag);
  	}
  
! 	strfcpy(meta_pattern, shift_lower(meta_pattern),
! 		sizeof meta_pattern);   /* lowercase it */
! 
! 	if (function == DELETED && strcmp(meta_pattern, "tagged") == 0)
!           return(DeleteTagged());
  
  	if (inalias) {
  	  for (i = 0; i < message_count; i++) {
***************
*** 201,206 ****
--- 164,172 ----
  	  }
  	}
  	else {
+           if (strcmp(meta_pattern, "all") == 0)
+             count = DoAll(function);
+           else
  	  for (i = 0; i < message_count; i++) {
  	    if (from_matches(i, meta_pattern) ||
  	        subject_matches(i, meta_pattern)) {
***************
*** 217,240 ****
  	  }
  	}
  
! 	ClearLine(LINES-2);	/* remove "pattern: " prompt */
  	
  	if (count > 1) {
! 	  error3(catgets(elm_msg_cat, ElmSet, ElmTaggedMessages,
! 		"%s %d %s."), 
! 	         function==TAGGED? Tagged_word : 
! 		   function==DELETED? Mark_delete_word : Undeleted_word,
! 		 count, items);
  	} else if (count == 1) {
! 	  error2(catgets(elm_msg_cat, ElmSet, ElmTaggedMessage,
! 		"%s 1 %s."), 
! 	         function==TAGGED? Tagged_word : 
! 		   function==DELETED? Mark_delete_word : Undeleted_word, item);
  	} else {
! 	  error2(catgets(elm_msg_cat, ElmSet, ElmNoMatchesNoTags,
! 		"No matches. No %s %s."), items,
! 		 function==TAGGED? tagged_word : 
! 		   function==DELETED? mark_delete_word: undeleted_word);
  	}
  
  	return(curtag);
--- 183,206 ----
  	  }
  	}
  
! 	ClearLine(elm_LINES-2);	/* remove "pattern: " prompt */
  	
  	if (count > 1) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmTaggedMessages,
! 			    "%s %d %s."), 
! 		    function==TAGGED? Tagged_word : 
! 		    function==DELETED? Mark_delete_word : Undeleted_word,
! 		    count, items);
  	} else if (count == 1) {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmTaggedMessage,
! 			    "%s 1 %s."), 
! 		    function==TAGGED? Tagged_word : 
! 		    function==DELETED? Mark_delete_word : Undeleted_word, item);
  	} else {
! 	 lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNoMatchesNoTags,
! 			    "No matches. No %s %s."), items,
! 		    function==TAGGED? tagged_word : 
! 		    function==DELETED? mark_delete_word: undeleted_word);
  	}
  
  	return(curtag);
***************
*** 263,287 ****
  		"/ = Match anywhere in %s.");
  	}
  
! 	MCsprintf(buffer, entire_match_pattern, item);
! 
! 	PutLine1(LINES-3,40, match_anywhere, items);
  	
! 	PutLine0(LINES-1,0, match_pattern);
  
! 	if (pattern_enter(pattern, alt_pattern, LINES-1,
! 		strlen(match_pattern)+1, buffer)) {
  	  if (strlen(alt_pattern) == 0) {
  	    return(1);
  	  }
  	  anywhere = TRUE;
! 	  strcpy(pattern, shift_lower(alt_pattern));
  	}
  	else if (strlen(pattern) == 0) {
  	  return(0);
  	}
  	else {
! 	  strcpy(pattern, shift_lower(pattern));
  	}
  
  	if (inalias) {
--- 229,260 ----
  		"/ = Match anywhere in %s.");
  	}
  
! 	elm_sfprintf(buffer, sizeof buffer,
! 		     "Match pattern (in entire %s):", entire_match_pattern, 
! 		     item);
! 
! 	PutLineX(elm_LINES-3,40, CATGETS(elm_msg_cat, ElmSet, ElmMatchAnywhere,
! 					 "/ = Match anywhere in %s."), 
! 		 items);
  	
! 	PutLine0(elm_LINES-1,0, match_pattern);
  
! 	if (pattern_enter(pattern, alt_pattern, elm_LINES-1,
! 			  strlen(match_pattern)+1, buffer,
! 			  sizeof pattern, sizeof alt_pattern)) {
  	  if (strlen(alt_pattern) == 0) {
  	    return(1);
  	  }
  	  anywhere = TRUE;
! 	  strfcpy(pattern, shift_lower(alt_pattern),
! 		  sizeof pattern);
  	}
  	else if (strlen(pattern) == 0) {
  	  return(0);
  	}
  	else {
! 	  strfcpy(pattern, shift_lower(pattern),
! 		  sizeof pattern);
  	}
  
  	if (inalias) {
***************
*** 318,339 ****
  	return(0);
  }
  
! int
! from_matches(message_number, pat)
! int message_number;
! char *pat;
  {
  	/** Returns true iff the pattern occurs in it's entirety
  	    in the from line of the indicated message **/
  
! 	return( in_string(shift_lower(headers[message_number]->from), 
! 		pat) );
  }
  
! int
! subject_matches(message_number, pat)
! int message_number;
! char *pat;
  {
  	/** Returns true iff the pattern occurs in it's entirety
  	    in the subject line of the indicated message **/
--- 291,364 ----
  	return(0);
  }
  
! int from_matches(message_number, pat)
!      int message_number;
!      char *pat;
  {
  	/** Returns true iff the pattern occurs in it's entirety
  	    in the from line of the indicated message **/
  
!     struct addr_item *p;
!     int match = 0;
! 
!     for (p = headers[message_number]->from;
! 	 p && p->fullname && p->addr;
! 	 p++) {
!       if (in_string(shift_lower(p->fullname), pat))
! 	match++;
!       if (in_string(shift_lower(p->addr), pat))
! 	match++;	      
!     }
!     return match;
  }
  
! 
! int to_matches(message_number, pat)
!      int message_number;
!      char *pat;
! {
! 	/** Returns true iff the pattern occurs in it's entirety
! 	    in the TO line of the indicated message **/
! 
!     struct addr_item *p;
!     int match = 0;
! 
!     for (p = headers[message_number]->to;
! 	 p && p->fullname && p->addr;
! 	 p++) {
!       if (in_string(shift_lower(p->fullname), pat))
! 	match++;
!       if (in_string(shift_lower(p->addr), pat))
! 	match++;	      
!     }
!     return match;
! }
! 
! int cc_matches(message_number, pat)
!      int message_number;
!      char *pat;
! {
! 	/** Returns true iff the pattern occurs in it's entirety
! 	    in the CC line of the indicated message **/
! 
!     struct addr_item *p;
!     int match = 0;
! 
!     for (p = headers[message_number]->cc;
! 	 p && p->fullname && p->addr;
! 	 p++) {
!       if (in_string(shift_lower(p->fullname), pat))
! 	match++;
!       if (in_string(shift_lower(p->addr), pat))
! 	match++;	      
!     }
!     return match;
! }
! 
! 
! int subject_matches(message_number, pat)
!      int message_number;
!      char *pat;
  {
  	/** Returns true iff the pattern occurs in it's entirety
  	    in the subject line of the indicated message **/
***************
*** 394,400 ****
  	result = get_alias_address(aliases[message_number]->alias,TRUE,&dummy);
  	if (result != NULL)
  		return(in_string(shift_lower(result), pat) );
! 	return(NULL);
  }
  
  match_in_message(pat)
--- 419,425 ----
  	result = get_alias_address(aliases[message_number]->alias,TRUE,&dummy);
  	if (result != NULL)
  		return(in_string(shift_lower(result), pat) );
! 	return(0);
  }
  
  match_in_message(pat)
***************
*** 411,418 ****
  
  	message_number = current-1;
  
! 	error(catgets(elm_msg_cat, ElmSet, ElmSearchingFolderPattern,
! 		"Searching folder for pattern..."));
  
  	while (message_number < message_count) {
  
--- 436,443 ----
  
  	message_number = current-1;
  
! 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSearchingFolderPattern,
! 			  "Searching folder for pattern..."));
  
  	while (message_number < message_count) {
  
***************
*** 423,431 ****
  		"Error: seek %ld bytes into file failed. errno %d (%s)\n",
  		headers[message_number]->offset, err, 
  		"match_in_message"));
! 	    error2(catgets(elm_msg_cat, ElmSet, ElmMatchSeekFailed,
! 		   "ELM [match] failed looking %ld bytes into file (%s)."),
! 		   headers[message_number]->offset, error_description(err));
  	    return(1);	/* fake it out to avoid replacing error message */
  	  }
  
--- 448,456 ----
  		"Error: seek %ld bytes into file failed. errno %d (%s)\n",
  		headers[message_number]->offset, err, 
  		"match_in_message"));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMatchSeekFailed,
! 			      "ELM [match] failed looking %ld bytes into file (%s)."),
! 		      headers[message_number]->offset, error_description(err));
  	    return(1);	/* fake it out to avoid replacing error message */
  	  }
  
***************
*** 451,454 ****
--- 476,500 ----
  	}
  
  	return(0);
+ }
+ 
+ /* This will tag, delete, or undelete all or the currently visible messages */
+ DoAll(func)
+ int func;
+ {
+         int i, count = 0;
+ 
+         for (i=0; i < message_count; i++)
+                 if (!selected ||
+                     (selected && ison(headers[i]->status,VISIBLE))) {
+                         if (func == TAGGED)
+                                 headers[i]->status |= TAGGED;
+                         else if (func == DELETED)
+                                 headers[i]->status |= DELETED;
+                         else if (func == UNDELETE)
+                                 headers[i]->status &= ~DELETED;
+ 			show_new_status(i);
+                         ++count;
+                 }
+         return(count);
  }
Index: elm2.4.ME+.50/src/pgp.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/src/pgp.c	Tue Nov 17 21:14:09 1998
***************
*** 0 ****
--- 1,610 ----
+ static char rcsid[] = "@(#)$Id: pgp.c,v 1.2 1998/11/16 17:08:35 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *
+  *  Initially written by: Michael Elkins <elkins@aero.org>, 1995
+  *****************************************************************************/
+ 
+ #include "headers.h"
+ #include "me.h"
+ #include "s_elm.h"
+ 
+ #ifdef USE_PGP
+ #include <sys/time.h>
+ #include <errno.h>
+ #include "menu.h"
+ 
+ /* these are defined in mailmsg1.c */
+ extern char expanded_to[VERY_LONG_STRING];
+ extern char expanded_cc[VERY_LONG_STRING];
+ extern char expanded_bcc[VERY_LONG_STRING];
+ extern char subject[VERY_LONG_STRING];
+ 
+ extern int errno;
+ 
+ 
+ char pgp_passphrase[STRING];
+ int pgp_expires;
+ 
+ /* the column in which the userid begins in the 'pgp -kv' command output */
+ #define PGP_USERID_OFFSET 30
+ 
+ 
+ /* 'n' is the key we are looking for.  'k' is the list of possible matches
+    which contains 'len' entries.  prompt the user for which key s/he really
+    wants to use. */
+ static char *
+ PGPSelectKey (n, k, len)
+ 	char *n;
+ 	char **k;
+ 	int len;
+ {
+   int i;
+   char buf[STRING];
+   menu_t menu;
+ 
+   elm_sfprintf(buf, sizeof buf,
+ 	       CATGETS(elm_msg_cat, ElmSet, ElmPgpMultipleKeys,
+ 		       "Multiple keys match '%s':"), 
+ 	       n);
+   MenuInit (&menu, buf, "Select key or 'q' to quit: ", 0);
+ 
+   for (i = 0; i < len; i++)
+     MenuAdd(&menu, k[i]);
+ 
+   for (;;) {
+     switch (MenuLoop(&menu)) {
+     case 'q':
+       MenuDestroy(&menu);
+       return(0);
+     case '\n':
+     case '\r':
+       MenuDestroy(&menu);
+       return(k[MenuCurrent(menu)]);
+     }
+   }
+   /* not reached */
+ }
+ 
+ static int GetPGPKey P_((char *name,
+ 			 char *target,
+ 			 int targetsize));
+ 
+ static int
+ GetPGPKey (name, target, targetsize)
+ 	char *name;
+ 	char *target;
+ 	int targetsize;
+ {
+   /* given "name", return the string to use during the pgp call to specify
+      the key which the user means.  return -1 on error. */
+   char buf[STRING], address[STRING], *c, **keys=0, *pc, userpart[STRING];
+   int i=0, keys_len=0, keys_max=0, return_val=0, start=0;
+   FILE *p;
+ 
+   if (!name || !target)
+     return(-1);
+ 
+   if (!have_pgp())
+     return(-1);
+ 
+   if (index(name, '@') == NULL && index(name, '(') == NULL && index(name, '<') == NULL) {
+     /* this is either just a username, or someone's real name.  in either
+        case it only needs to be checked once. */
+ 
+     strfcpy(address, name, sizeof address);
+     i = 2;
+   }
+   else {
+     get_address_from (name, address, sizeof address);
+   
+     i=0;
+     while (address[i] && address[i] != '@') {
+       userpart[i] = address[i];
+       i++;
+     }
+     userpart[i] = '\0';
+ 
+     i = 0;
+   }
+   c = address;
+ 
+   /* the following loop first checks to see if any keys with the full
+      address, or real name, or finally the username exist */
+ 
+   for (;;) {
+     int fd[2];
+ 
+     if (pipe (fd) == -1) {
+       dprint (1, (debugfile, "GetPGPKey(): ERROR: pipe (errno %d)\n", errno));
+       return -1;
+     }
+ 
+     while (*c && isspace (*c)) c++; /* move past any leading space! */
+     
+     if (fork () == 0) {
+       int tmp;
+       
+       setgid(groupid);
+       setuid(userid);
+ 
+       close (fd[0]);
+       close (1);
+       dup (fd[1]);
+       close (fd[1]);
+ 
+       execl(pgp_path, 
+ 	    pgp_path,"+verbose=0", "+language=en", "-kv", c, (char *)0);
+ 
+       tmp = errno;
+       perror(pgp_path);
+       _exit(tmp);
+     }
+ 
+     close (fd[1]);
+     p = fdopen (fd[0], "r");
+     if (p == NULL) {
+       dprint (1, (debugfile, 
+ 		  "GetPGPKey(): ERROR: fdopen (errno %d)\n", errno));
+       return -1;
+     }
+ 
+     while (fgets(buf, STRING, p) != NULL) {
+       /* see if we've reached the beginning of the key listings... */
+       if (!start && strncmp(buf, "pub", 3)==0)
+ 	  start=1;
+ 
+       if (start) {
+ 	int Len;
+ 
+ 	/* if we've read all the keys, stop here */
+ 	if (buf[0] != 'p' && buf[0] != ' ')
+ 	  break;
+ 
+ 	if (keys_len == keys_max)
+ 	  keys = (char**)DynamicArray(keys, sizeof(char*), &keys_max, 5);
+ 	
+ 	pc = rindex(buf, '\n');
+ 	if (!pc) /* this shouldn't happen! */
+ 	  continue;
+ 	*pc = '\0';
+ 	
+ 	pc = buf + PGP_USERID_OFFSET;
+ 	Len = strlen(pc)+1;
+ 	keys[keys_len] = (char*)safe_malloc(Len);
+ 	strfcpy(keys[keys_len], pc, Len);
+ 	++keys_len;
+       }
+     }
+     pclose(p);
+     if (keys_len > 0 || i > 1)
+       break;
+     else {
+       if (i == 0) {
+ 	strfcpy(address,name, sizeof address);
+ 	parse_arpa_who(name,address, 
+ 		       decode_who_none,		       
+ 		       sizeof address);
+ 
+ 	/* if there was no real name, go on to the userpart check */
+ 	if (strcmp(name, address) == 0) {
+ 	  c = userpart;
+ 	  i++;
+ 	}
+       } else if (i == 1)
+ 	c = userpart;
+       i++;
+     }
+   }
+ 
+   if (keys_len == 1) /* perfect match! */
+     get_address_from(keys[0], target, targetsize);
+   else if (keys_len > 1) { /* ask the user which, if any, s/he meant */
+     c = PGPSelectKey(name, keys, keys_len);
+     if (c)
+       get_address_from(c, target, targetsize);
+     else {
+       target[0] = '\0';
+       return_val = -1;
+     }
+   } else
+     return_val = -1;
+ 
+   DestroyDynamicArray(keys);
+ 
+   return(return_val);
+ }
+ 
+ static int
+ pgp_call (filename, opts)
+ 	char *filename;
+ 	int opts;
+ {
+   char tobuf[VERY_LONG_STRING] = {0};
+   char frombuf[VERY_LONG_STRING] = {0};
+   int status;
+ 
+   if (opts & PGP_MESSAGE) {
+     /* build up the list of recipients */
+     strfcpy(tobuf, expanded_to, sizeof tobuf);
+     if (expanded_cc[0] != '\0') {
+       strfcat(tobuf, ", ", sizeof tobuf);
+       strfcat(tobuf, expanded_cc, sizeof tobuf);
+     }
+     if (expanded_bcc[0] != '\0') {
+       strfcat(tobuf, ", ", sizeof tobuf);
+       strfcat(tobuf, expanded_bcc, sizeof tobuf);
+     }
+     /* If the message is to be encrypted, give the user a chance to edit
+      * the list of ids to encrypt to since the given address may not always
+      * be correct.
+      */
+   redraw:
+     PutLineX (elm_LINES-2, 0, CATGETS(elm_msg_cat, ElmSet, ElmPgpTo,
+ 				      "To%s"),
+ 	      ": ");
+     status = optionally_enter (tobuf, elm_LINES-2, 4, 
+ 			       OE_APPEND_CURRENT|OE_REDRAW_MARK,
+ 			       sizeof tobuf);
+     if (REDRAW_MARK == status)
+       goto redraw;
+     if (status < 0 || tobuf[0] == '\0')
+       return FALSE;
+   }
+ 
+   if (pgp_askpgpsig && (opts & PGP_SIGNED_MESSAGE)) {
+     /* If the message is to be signed, give the user a chance to specify
+      * with which signature.
+      */
+     strfcat(frombuf, username, sizeof frombuf);
+   redraw2:
+     PutLineX (elm_LINES-2, 0, CATGETS(elm_msg_cat, ElmSet, ElmPgpFrom,
+ 				      "From%s"),
+ 	      ": ");
+     status = optionally_enter (frombuf, elm_LINES-2, 6,
+ 			       OE_APPEND_CURRENT|OE_REDRAW_MARK,
+ 			       sizeof frombuf);
+     if (REDRAW_MARK == status)
+       goto redraw2;
+     if (status < 0 || frombuf[0] == '\0')
+       return FALSE;
+   }
+   return (pgp_encrypt (filename, tobuf, frombuf, opts, auto_cc));
+ }
+ 
+ int
+ pgp_encrypt (filename, ids, sig, opts, metoo)
+ 	char *filename, *ids, *sig;
+ 	int opts, metoo;
+ {
+   int i, id_len=0, id_max=0, st, usepgppass=FALSE, fd[2];
+   char
+     keyid[STRING], buf[VERY_LONG_STRING], buf2[STRING], **id_array=0, *c,
+     *p;
+   
+   dprint (2, (debugfile, "pgp_encrypt(): ids=\"%s\", signwith=\"%s\", encrypt=%s, sign=%s\n", ids, sig, opts & PGP_MESSAGE ? "TRUE" : "FALSE", opts & PGP_SIGNED_MESSAGE ? "TRUE" : "FALSE"));
+ 
+   if (!have_pgp())
+     return FALSE;
+ 
+   p = ids;
+   /* If this message is to be encrypted, look up the keys of all the
+      recipients */
+   if (opts & PGP_MESSAGE) {
+     i=0;
+     while ((c = strtok(p, ",")) != NULL) {
+       int Len;
+       if (GetPGPKey(c, keyid, sizeof keyid) == -1) {
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmPgpNoMatch,
+ 			  "Couldn't find key matching '%s'!"),
+ 		  c);
+ 	return FALSE;
+       }
+       if (id_len == id_max)
+ 	id_array = (char**)DynamicArray(id_array, sizeof(char*), &id_max, 25);
+       Len = strlen(keyid) + 1;
+       id_array[id_len] = (char*)safe_malloc(Len);
+       strfcpy(id_array[id_len], keyid, Len);
+       id_len++;
+       p=NULL;
+     }
+   }
+ 
+   if ((opts & PGP_SIGNED_MESSAGE) && pgp_keeppass && pgp_goodPassphrase()) {
+     usepgppass = TRUE;
+     pipe(fd);
+   }
+ 
+   /* build up the command */
+   buf[0] = '\0';
+   if (usepgppass) {
+     elm_sfprintf(buf2, sizeof buf2,
+ 		 FRM("PGPPASSFD=%d; export PGPPASSFD; "), 
+ 		 fd[0]);
+     strfcat(buf, buf2, sizeof buf);
+   }
+   strfcat(buf, pgp_path, sizeof buf);
+   if (metoo)
+     strfcat(buf, " +encrypttoself=on", sizeof buf);
+   if (usepgppass)
+     strfcat(buf, " +batchmode", sizeof buf);
+   if (opts & PGP_SIGNED_MESSAGE)
+     strfcat(buf," +clearsig=on", sizeof buf);
+ 
+   strfcat(buf, " +verbose=0 -atw", sizeof buf);
+ 
+   if (opts & PGP_SIGNED_MESSAGE)
+     strfcat(buf, "s", sizeof buf);
+   if (opts & PGP_MESSAGE)
+     strfcat(buf, "e", sizeof buf);
+ 
+   if (pgp_askpgpsig && (opts & PGP_SIGNED_MESSAGE)) {
+     strfcat(buf, "u ", sizeof buf);
+     strfcat(buf, sig, sizeof buf);
+   }
+ 
+   strfcat(buf, " ", sizeof buf);
+   strfcat(buf, filename, sizeof buf);
+ 
+   /* add all of the userid's protected inside quotes to prevent shell
+      no-no's */
+   if (opts & PGP_MESSAGE)
+     for (i=0; i<id_len; i++) {
+       strfcat(buf, " '", sizeof buf);
+       strfcat(buf, id_array[i], sizeof buf);
+       strfcat(buf, "'", sizeof buf);
+     }
+   DestroyDynamicArray(id_array); /* don't need this any more... */
+ 
+   if (usepgppass) {
+     Raw(OFF);
+     ClearScreen();/**/
+ 
+     write(fd[1], pgp_passphrase, strlen(pgp_passphrase));
+     write(fd[1], "\n", 1); /* pgp expects this as a line terminator! */
+     close(fd[1]);
+   }
+   else {
+     Raw(OFF);
+     ClearScreen();
+     printf("Executing: %s\n\n", buf);
+   }
+   st = system_call(buf, 0);
+ /*  if (!usepgppass)/**/
+     Raw(ON);
+   
+   if (st == 0) { /* pgp returns zero upon success */
+     /* copy the file into it's final destination */
+     elm_sfprintf(buf, sizeof buf,
+ 		 FRM("%s.asc"), filename);
+ #ifdef RENAME
+     if (rename(buf, filename) < 0) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet,ElmCantRenameTmpFile,
+ 			"Could not rename temporary file!"));
+       return FALSE;
+     }
+ #else
+     if (link(buf, filename) < 0) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet,ElmCantLinkTmpFile,
+ 			"Could not create link to temporary file!"));
+       return FALSE;
+     }
+     /* this is not fatal, but a warning should be given */
+     if (unlink(buf) < 0)
+       lib_error(CATGETS(elm_msg_cat, ElmSet,ElmCantUnLinkTmpFile,
+ 			"Could not unlink temporary file!"));
+ #endif
+   }
+   else {
+     lib_error(CATGETS(elm_msg_cat, ElmSet,ElmPgpNonZeroValue,
+ 		      "Pgp returned a non-zero value!"));
+     if (pgp_keeppass)
+       pgp_void_passphrase ();
+     return FALSE;
+   }
+   return opts;
+ }
+ 
+ int
+ pgp_menu (filename)
+ 	char *filename;
+ {
+   int update = TRUE;
+ 
+   for (;;) {
+     if (update) {
+       MoveCursor (elm_LINES-3, 0);
+       CleartoEOS ();
+       Centerline (elm_LINES-2, "e)ncrypt, s)ign, b)oth encrypt and sign");
+       PutLineX (elm_LINES-3, 0, CATGETS(elm_msg_cat, ElmSet, ElmPgpP,
+ 					"pgp%s"),
+ 		": ");
+       update = FALSE;
+     }
+     switch(ReadCh(REDRAW_MARK)) {
+     case 'e':
+       Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmPgpEncrypt,
+ 			      "Encrypt"));
+       return (pgp_call (filename, PGP_MESSAGE));
+     case 's':
+       Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmPgpSign,
+ 			      "Sign"));
+       return (pgp_call (filename, PGP_SIGNED_MESSAGE));
+     case 'b':
+       Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmPgpSignEncrypt,
+ 			      "Sign and Encrypt"));
+       return (pgp_call (filename, PGP_MESSAGE | PGP_SIGNED_MESSAGE));
+     case '\n':
+     case '\r':
+       return FALSE;
+     case REDRAW_MARK:
+     case ctrl('L'):
+       update = 1;
+     }
+   }
+   /* not reached */
+ }
+ 
+ int pgp_mail_public_key ()
+ {
+   int ret;
+   struct run_state RS;
+   char * argv[20];
+   int argc = 0;
+   char userid[SLEN], pgpkey[SLEN], tmpfil[STRING], cmd[STRING], subj[STRING];
+   int status;
+   int need_redraw = FALSE;
+ 
+   userid[0] = '\0';
+   pgpkey[0] = '\0';
+ 
+   if (!have_pgp())
+     return need_redraw;
+ 
+   PutLineX(elm_LINES-2, 0, 
+ 	   CATGETS(elm_msg_cat, ElmSet, ElmPgpEntUser,
+ 		   "Enter userid of public key%s"),
+ 	   ": ");
+   CleartoEOS ();
+   status = optionally_enter(userid, elm_LINES-2, 28, OE_REDRAW_MARK,
+ 			    sizeof userid);
+   while(REDRAW_MARK == status) {
+     PutLineX(elm_LINES-2, 0,   CATGETS(elm_msg_cat, ElmSet, ElmPgpEntUser,
+ 				       "Enter userid of public key%s"),
+ 	     ": ");
+     status = optionally_enter(userid, elm_LINES-2, 28, 
+ 			      OE_REDRAW_MARK|OE_APPEND_CURRENT,
+ 			      sizeof userid);
+     need_redraw = TRUE;
+   }
+   if ( status != 0)
+     return(need_redraw);
+ 
+   if (GetPGPKey(userid, pgpkey, sizeof pgpkey) < 0) {
+     Centerline(elm_LINES, "Sorry, couldn't find that userid.");
+     ClearLine(elm_LINES-2);
+     return(TRUE);
+   }
+   elm_sfprintf(tmpfil, sizeof tmpfil,
+ 	       FRM("%selm.%d"), temp_dir, getpid());
+   
+   argv[argc++] = pgp_path;
+   argv[argc++] = "+verbose=0";
+   argv[argc++] = "-kxa";
+   argv[argc++] = pgpkey;
+   argv[argc++] = tmpfil;
+   argv[argc++] = NULL;
+ 
+   ret = start_run(&RS,SY_NOTTY,argv,-1,-1);
+ 
+   if (ret) {
+     int exit_code;
+     ret = run_already_done(&RS,&exit_code);
+     if (0 == ret) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet,ElmRunningPgp,
+ 			"Running PGP..."));
+       fflush(stdout);
+       ret = wait_end(&RS,&exit_code);
+     }
+     if (ret < 0) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet,ElmFailSignal,
+ 			"%.30s fail: Signal?"),
+ 		argv[0]);
+       return TRUE;
+     } else if (ret > 0) {
+       if (RS.save_errno)
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet,ElmFailErrno,
+ 			  "Failed: %.30s: %.40s"),
+ 		  argv[0],error_description(RS.save_errno));
+       else if (exit_code) {	
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet,ElmPgpErrorStatus,
+ 			  "Pgp returned error status %d"),
+ 		  exit_code);
+ 	return TRUE;
+       } else {
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet,ElmPgpDone,
+ 			  "Running PGP... Done."));
+ 	elm_sfprintf(included_file, sizeof included_file,
+ 		     FRM("%s.asc"), tmpfil);
+       }
+     } else {
+       lib_error(CATGETS(elm_msg_cat, ElmSet,ElmLostErrno,
+ 			"%.30s lost: %.40s"),
+ 		argv[0],error_description(RS.save_errno));
+       return TRUE;
+     }
+   
+   } else {
+     if (RS.save_errno)
+       lib_error(CATGETS(elm_msg_cat, ElmSet,ElmFailErrno,
+ 			"Failed: %.30s: %.40s"),
+ 		argv[0],error_description(RS.save_errno));
+     else
+       lib_error(CATGETS(elm_msg_cat, ElmSet,ElmCantStart,
+ 			"Can't start %.30s"),
+ 		argv[0]);
+     return TRUE;
+   }
+ 
+   /* set the default subject for this message */
+   elm_sfprintf(subj, sizeof subj,
+ 	       CATGETS(elm_msg_cat, ElmSet, ElmPgpPublicKey,
+ 		       "PGP public key for %s"), 
+ 	       pgpkey);
+ 
+   pgp_status = PGP_PUBLIC_KEY;
+ 
+   /* Now send the message off! */
+   send_msg ("", "", subj, 0, 0);
+ 
+   unlink (included_file); /* make sure to clean up. */
+   included_file[0] = '\0';
+   pgp_status = 0; /* reset */
+   return(TRUE);
+ }
+ 
+ int pgp_extract_public_key ()
+ {
+   char tempfile[STRING], buf[STRING];
+   struct run_state RS;
+   char *argv[20];
+   int argc = 0;
+   FILE *fpout;
+   int err,res;
+ 
+   if (!have_pgp())
+     return FALSE;
+ 
+   elm_sfprintf(tempfile,sizeof tempfile,
+ 	       FRM("%selm.%d"),temp_dir,getpid());
+   fpout=safeopen_rdwr(tempfile);
+   if (!fpout) {
+     lib_error(CATGETS(elm_msg_cat, ElmSet,ElmOpenTmpWriting,
+ 		      "Could not open temp file %.30s for writing!"), 
+ 	      tempfile);
+     return FALSE;
+   }
+   copy_message(mailfile,headers[current-1],
+ 	       "",fpout,0);
+   fclose(fpout);
+ 
+   argv[argc++] = pgp_path;
+   argv[argc++] = "+verbose=0";
+   argv[argc++] = tempfile;
+   argv[argc++] = NULL;
+   
+   res=start_run(&RS,SY_CLRWAIT,argv,-1,-1);
+   if (res) {
+     int exit_code;
+     wait_end(&RS,&exit_code);
+   }
+   unlink(tempfile);
+   return TRUE;
+ }
+ 
+ #endif /* USE_PGP */
+ 
+ 
Index: elm2.4.ME+.50/src/pmalloc.c
*** elm2.4.25/src/pmalloc.c	Fri Mar 11 22:59:02 1994
--- elm2.4.ME+.50/src/pmalloc.c	Tue Nov 17 21:12:58 1998
***************
*** 1,103 ****
- 
- static char rcsid[] = "@(#)$Id: pmalloc.c,v 5.4 1994/03/11 20:59:02 syd Exp $";
- 
- /*******************************************************************************
-  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
-  *
-  *			Copyright (c) 1988-1992 USENET Community Trust
-  *			Copyright (c) 1986,1987 Dave Taylor
-  *******************************************************************************
-  * Bug reports, patches, comments, suggestions should be sent to:
-  *
-  *	Syd Weinstein, Elm Coordinator
-  *	elm@DSI.COM			dsinc!elm
-  *
-  *******************************************************************************
-  * $Log: pmalloc.c,v $
-  * Revision 5.4  1994/03/11  20:59:02  syd
-  * I made the following changes to elm 2.4pl23 module pmalloc.c after testing on
-  * a DEC Alpha running OSF1 v1.3.  The difficulty is that the Alpha hardware
-  * requires certain alignment for some operations which was not supplied by
-  * pmalloc (8 byte for addresses instead of 4 byte).  I made a simple minded
-  * change to pmalloc.c to force alignment of the allocated data block to be
-  * adequate on DEC Alpha OSF1.
-  * From: jim@lime.rsmas.miami.edu (Jim Brown)
-  *
-  * Revision 5.3  1992/12/07  04:28:03  syd
-  * change include from defs to headers as now needs LINES
-  * From: Syd
-  *
-  * Revision 5.2  1992/11/26  00:46:13  syd
-  * changes to first change screen back (Raw off) and then issue final
-  * error message.
-  * From: Syd
-  *
-  * Revision 5.1  1992/10/03  22:58:40  syd
-  * Initial checkin as of 2.4 Release at PL0
-  *
-  *
-  ******************************************************************************/
- 
- /** This routine contains a cheap permanent version of the malloc call to 
-     speed up the initial allocation of the weedout headers and the uuname 
-     data.  
- 
-       This routine is originally from Jim Davis of HP Labs, with some 
-     mods by me.
- **/
- 
- #include <stdio.h>
- #include "headers.h"
- #include "s_elm.h"
- 
- extern nl_catd elm_msg_cat;	/* message catalog	    */
- /*VARARGS0*/
- 
- #define MIN_BOUNDARY 8 /* power to 2 */
- 
- char *pmalloc(size)
- int size; 
- {
- 	/** return the address of a specified block **/
- 
- 	static char *our_block = NULL;
- 	static int   free_mem  = 0;
- 
- 	char   *return_value;
- 
- 	/** if bigger than our threshold, just do the real thing! **/
- 
- 	if (size > PMALLOC_THRESHOLD) 
- 	   return((char *) malloc(size));
- 
- 	/** if bigger than available space, get more, tossing what's left **/
- 
- 	size = ((size+3+4)/4)*4;	/* Go to quad byte boundary, fill */
- 
- 	if (size > free_mem) {
- 	  if ((our_block = (char *) malloc(PMALLOC_BUFFER_SIZE)) == NULL) {
- 	    MoveCursor(LINES,0);
- 	    Raw(OFF);
- 	    fprintf(stderr, catgets(elm_msg_cat, ElmSet, ElmCouldntMallocBytes,
- 		    "\n\nCouldn't malloc %d bytes!!\n\n"),
- 		    PMALLOC_BUFFER_SIZE);
- 	    leave(0);	
-           }
- 	  our_block += 4;  /* just for safety, don't give back true address */
- 	  free_mem = PMALLOC_BUFFER_SIZE-4;
- 	}
- 
- 	if (((long)our_block&(MIN_BOUNDARY-1)) != 0) {
- 	  int		drek;
- 
- 	  drek = ((long)our_block&(MIN_BOUNDARY-1)); /* round to minimum */
- 	  our_block += (MIN_BOUNDARY-drek);
- 	  free_mem -= (MIN_BOUNDARY-drek);
- 	}
- 
- 	return_value  = our_block;	/* get the memory */
- 	our_block += size;		/* use it up      */
- 	free_mem  -= size;		/*  and decrement */
- 
- 	return( (char *) return_value);
- }
--- 0 ----
Index: elm2.4.ME+.50/src/quit.c
*** elm2.4.25/src/quit.c	Thu Nov 26 02:46:43 1992
--- elm2.4.ME+.50/src/quit.c	Tue Nov 17 21:12:57 1998
***************
*** 1,40 ****
  
! static char rcsid[] = "@(#)$Id: quit.c,v 5.4 1992/11/26 00:46:13 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: quit.c,v $
!  * Revision 5.4  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.3  1992/10/24  13:35:39  syd
!  * changes found by using codecenter on Elm 2.4.3
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.2  1992/10/17  22:47:09  syd
!  * adds the function bytemap() and the macros MAPIN and MAPOUT from the file
!  * lib/ndbz.c in the file src/alias.c.
!  *
!  * prevent elm from exiting when resyncing the empty incoming mailbox.
!  * From: vogt@isa.de (Gerald Vogt)
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** quit: leave the current folder and quit the program.
    
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: quit.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** quit: leave the current folder and quit the program.
    
***************
*** 42,47 ****
--- 18,24 ----
  
  #include "headers.h"
  #include "s_elm.h"
+ #include "me.h"
  #include <errno.h>
  
  extern int errno;		/* system error number on failure */
***************
*** 53,103 ****
  quit(prompt)
  int prompt;
  {
! 	/* a wonderfully short routine!! */
  
- 	if (leave_mbox(FALSE, TRUE, prompt) == -1)
- 	  /* new mail - leave not done - can't change to another file yet
- 	   * check for change in mailfile_size in main() will do the work
- 	   * of calling newmbox to add in the new messages to the current
- 	   * file and fix the sorting sequence that leave_mbox may have
- 	   * changed for its own purposes */
- 	  return;
  
! 	leave(0);
  }
  
  int
  resync()
  {
! 	/** Resync on the current folder. Leave current and read it back in.
! 	    Return indicates whether a redraw of the screen is needed.
! 	 **/
! 	int  err;
! 
! 	  if(leave_mbox(TRUE, FALSE, TRUE) ==-1)
! 	    /* new mail - leave not done - can't change to another file yet
! 	     * check for change in mailfile_size in main() will do the work
! 	     * of calling newmbox to add in the new messages to the current
! 	     * file and fix the sorting sequence that leave_mbox may have
! 	     * changed for its own purposes */
! 	    return(FALSE);
! 
! 	  if ((errno = can_access(cur_folder, READ_ACCESS)) != 0) {
! 	    if (strcmp(cur_folder, defaultfile) != 0 || errno != ENOENT) {
! 	      err = errno;
! 	      MoveCursor(LINES, 0);
! 	      Raw(OFF);
! 	      dprint(1, (debugfile,
! 		     "Error: given file %s as folder - unreadable (%s)!\n", 
! 		     cur_folder, error_description(err)));
! 	      fprintf(stderr, catgets(elm_msg_cat, ElmSet, ElmCantOpenFolderRead,
! 			"Can't open folder '%s' for reading!\n"), cur_folder);
! 	      leave(0);
! 	    }
! 	  }
! 
! 	  newmbox(cur_folder, FALSE);
! 	  return(TRUE);
  }
  
  char helpmsg[VERY_LONG_STRING];
--- 30,121 ----
  quit(prompt)
  int prompt;
  {
!   int status;
! 
! requit:
!   status = leave_mbox(FALSE, TRUE, prompt);
!   if ( status == -1)
!     /* new mail - leave not done - can't change to another file yet
!      * check for change in mailfile_size in main() will do the work
!      * of calling newmbox to add in the new messages to the current
!      * file and fix the sorting sequence that leave_mbox may have
!      * changed for its own purposes */
!     return;
! 
!   if (status < 0) {
!     int ans;
!     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFailedLeaveFolder,
! 		      "Failed to leave folder!"));
!     sleep_message();
!     
!     if (!prompt) 
!       return;
!     
!   again1:
!     ans = want_to("Failed to leave folder: Try to quit again ? [P]anic",
! 		  *def_ans_no,elm_LINES,1);
!     if (ans = ('L'&31)) {
!       ClearScreen();      
!       goto again1;
!     }
!     if (ans == *def_ans_no)
!       return;
!     if (ans == *def_ans_yes) {
!       clear_error();
!       goto requit;
!     }
!     if (ans == 'P')
!       emergency_exit(0);
!     return;
!   }
  
  
! 
!   leave(0);
  }
  
  int
  resync()
  {
!   int result;
!   /** Resync on the current folder. Leave current and read it back in.
!     Return indicates whether a redraw of the screen is needed.
!     **/
!   int  err;
! 
!   result = leave_mbox(TRUE, FALSE, TRUE);
!   if( result == -1)
!     /* new mail - leave not done - can't change to another file yet
!      * check for change in mailfile_size in main() will do the work
!      * of calling newmbox to add in the new messages to the current
!      * file and fix the sorting sequence that leave_mbox may have
!      * changed for its own purposes */
!     return(FALSE);
! 
!   if (result < 0) {
!     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFailedResyncFolder,
! 		      "Failed to resync folder!"));
!     sleep_message();
!     return FALSE;
!   }
!   
!   if ((errno = can_access(cur_folder, READ_ACCESS)) != 0) {
!     if (strcmp(cur_folder, defaultfile) != 0 || errno != ENOENT) {
!       err = errno;
!       MoveCursor(elm_LINES, 0);
!       Raw(OFF);
!       dprint(1, (debugfile,
! 		 "Error: given file %s as folder - unreadable (%s)!\n", 
! 		 cur_folder, error_description(err)));
!       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCantOpenFolderRead,
! 			"Can't open folder '%s' for reading!\n"), 
! 		cur_folder);
!       leave(0);
!     }
!   }
!   
!   newmbox(cur_folder, FALSE);
!   return(TRUE);
  }
  
  char helpmsg[VERY_LONG_STRING];
***************
*** 114,119 ****
--- 132,138 ----
  
  	  int redraw = FALSE;
  	  char newfile[SLEN];
+ 	  int result;
  
  	  char	*nameof();
  
***************
*** 120,138 ****
  
  	  /* get new file name */
  
! 	  MoveCursor(LINES-3, 30);
  	  CleartoEOS();
! 	  PutLine0(LINES-3, 38, catgets(elm_msg_cat, ElmSet, ElmUseForHelp,
! 		"(Use '?' for help)"));
! 	  PutLine0(LINES-2,0, catgets(elm_msg_cat, ElmSet, ElmChangeToWhichFolder,
! 		"Change to which folder: "));
  	  while(1) {
  	    newfile[0] = '\0';
! 	    (void) optionally_enter(newfile, LINES-2, 24, FALSE, FALSE);
  	    clear_error();
  
! 	    if(*newfile == '\0') {	/* if user didn't enter a file name */
! 	      MoveCursor(LINES-3, 30);	/* abort changing file process */
  	      CleartoEOS();
  	      return(redraw);
  
--- 139,175 ----
  
  	  /* get new file name */
  
! 	  MoveCursor(elm_LINES-3, 30);
  	  CleartoEOS();
! 	  PutLine0(elm_LINES-3, 38, catgets(elm_msg_cat, ElmSet, ElmUseForHelp,
! 					    "(Use '?' for help)"));
! 	  PutLine0(elm_LINES-2,0, catgets(elm_msg_cat, ElmSet, 
! 					  ElmChangeToWhichFolder,
! 					  "Change to which folder: "));
  	  while(1) {
+ 	    int status;
+ 
  	    newfile[0] = '\0';
! 	    status = optionally_enter(newfile, elm_LINES-2, 24, 
! 				      OE_REDRAW_MARK, sizeof newfile);
! 	    while (REDRAW_MARK == status) {
! 	      redraw = TRUE;
! 	      PutLine0(elm_LINES-3, 38, 
! 		       catgets(elm_msg_cat, ElmSet, ElmUseForHelp,
! 			       "(Use '?' for help)"));
! 	      PutLine0(elm_LINES-2,0, 
! 		       catgets(elm_msg_cat, ElmSet, 
! 			       ElmChangeToWhichFolder,
! 			       "Change to which folder: "));
! 	      status = optionally_enter(newfile, elm_LINES-2, 24, 
! 					OE_REDRAW_MARK|OE_APPEND_CURRENT,
! 					sizeof newfile);
! 	    }
! 
  	    clear_error();
  
! 	    if(0 != status || *newfile == '\0') {  /* if user didn't enter a file name */
! 	      MoveCursor(elm_LINES-3, 30);         /* abort changing file process */
  	      CleartoEOS();
  	      return(redraw);
  
***************
*** 141,151 ****
  
  	      /* user wants to list folders */
  	      if(!*helpmsg) 	/* format helpmsg if not yet done */
! 		init_helpmsg( helpmsg, change_word, FALSE );
  	      ClearScreen();
  	      printf( helpmsg ) ;
! 	      PutLine0(LINES-2,0,catgets(elm_msg_cat, ElmSet, ElmChangeToWhichFolder,
! 		"Change to which folder: "));	/* reprompt */
  	      redraw = TRUE;		/* we'll need to clean the screen */
  	      continue ;
  	    }
--- 178,192 ----
  
  	      /* user wants to list folders */
  	      if(!*helpmsg) 	/* format helpmsg if not yet done */
! 		init_helpmsg( helpmsg, change_word, FALSE, sizeof helpmsg );
  	      ClearScreen();
  	      printf( helpmsg ) ;
! 
! 	      /* reprompt */
! 	      PutLine0(elm_LINES-2,0,catgets(elm_msg_cat, ElmSet, 
! 					     ElmChangeToWhichFolder,
! 					     "Change to which folder: "));
! 	      
  	      redraw = TRUE;		/* we'll need to clean the screen */
  	      continue ;
  	    }
***************
*** 153,172 ****
  	    /* if user entered wildcard, list expansions and try again */
  	    if ( has_wildcards( newfile ) ) {
  	      list_folders( 4, NULL, newfile ) ;
! 	      PutLine0(LINES-2,0,catgets(elm_msg_cat, ElmSet, ElmChangeToWhichFolder,
! 		"Change to which folder: "));	/* reprompt */
  	      redraw = TRUE ;
  	      continue ;  
  	    }
  
  	    /* user entered a file name - expand it */
! 	    if (! expand_filename(newfile, TRUE))
  	      continue;	/* prompt again */
  
  	    /* don't accept the same file as the current */
  	    if (strcmp(newfile, cur_folder) == 0) {
! 	      error(catgets(elm_msg_cat, ElmSet, ElmAlreadyReadingThatFolder,
! 		"Already reading that folder!"));
  	      continue;	/* prompt again */
  	    }
  
--- 194,217 ----
  	    /* if user entered wildcard, list expansions and try again */
  	    if ( has_wildcards( newfile ) ) {
  	      list_folders( 4, NULL, newfile ) ;
! 
! 	      /* reprompt */
! 	      PutLine0(elm_LINES-2,0,catgets(elm_msg_cat, ElmSet, 
! 					     ElmChangeToWhichFolder,
! 					     "Change to which folder: "));
  	      redraw = TRUE ;
  	      continue ;  
  	    }
  
  	    /* user entered a file name - expand it */
! 	    if (! expand_filename(newfile, TRUE, sizeof newfile))
  	      continue;	/* prompt again */
  
  	    /* don't accept the same file as the current */
  	    if (strcmp(newfile, cur_folder) == 0) {
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 				ElmAlreadyReadingThatFolder,
! 				"Already reading that folder!"));
  	      continue;	/* prompt again */
  	    }
  
***************
*** 174,181 ****
  	     * default mailfile, which is openable even if empty */
  	    if ((errno = can_access(newfile, READ_ACCESS)) != 0 ) {
  	      if (strcmp(newfile, defaultfile) != 0 || errno != ENOENT) {
! 		error1(catgets(elm_msg_cat, ElmSet, ElmCantOpenFolderReadNONL,
! 			"Can't open folder '%s' for reading!"), newfile);
  		continue; 	/* prompt again */
  	      }
  	    }
--- 219,228 ----
  	     * default mailfile, which is openable even if empty */
  	    if ((errno = can_access(newfile, READ_ACCESS)) != 0 ) {
  	      if (strcmp(newfile, defaultfile) != 0 || errno != ENOENT) {
! 		lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 				  ElmCantOpenFolderReadNONL,
! 				  "Can't open folder '%s' for reading!"), 
! 			  newfile);
  		continue; 	/* prompt again */
  	      }
  	    }
***************
*** 182,192 ****
  	    break;	/* exit loop - we got the name of a good file */
  	  }
  
  	  /* All's clear with the new file to go ahead and leave the current. */
! 	  MoveCursor(LINES-3, 30);
  	  CleartoEOS();
  
! 	  if(leave_mbox(FALSE, FALSE, TRUE) ==-1) {
  	    /* new mail - leave not done - can't change to another file yet
  	     * check for change in mailfile_size in main() will do the work
  	     * of calling newmbox to add in the new messages to the current
--- 229,241 ----
  	    break;	/* exit loop - we got the name of a good file */
  	  }
  
+ rechange:
  	  /* All's clear with the new file to go ahead and leave the current. */
! 	  MoveCursor(elm_LINES-3, 30);
  	  CleartoEOS();
  
! 	  result = leave_mbox(FALSE, FALSE, TRUE);
! 	  if(result ==-1) {
  	    /* new mail - leave not done - can't change to another file yet
  	     * check for change in mailfile_size in main() will do the work
  	     * of calling newmbox to add in the new messages to the current
***************
*** 193,198 ****
--- 242,272 ----
  	     * file and fix the sorting sequence that leave_mbox may have
  	     * changed for its own purposes */
  	    return(redraw);
+ 	  }
+ 	  
+ 	  if (result < 0) {
+ 	    int ans;
+ 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFailedLeaveFolder,
+ 			      "Failed to leave folder!"));
+ 	    sleep_message();
+ 	    
+ 	  again1:
+ 	    ans = want_to("Failed to leave folder: Try to change again ? [P]anic",
+ 			  *def_ans_no,elm_LINES,1);
+ 	    if (ans = ('L'&31)) {
+ 	      redraw = 1;
+ 	      ClearScreen();      
+ 	      goto again1;
+ 	    }
+ 	    if (ans == *def_ans_no)
+ 	      return redraw;
+ 	    if (ans == *def_ans_yes) {
+ 	      clear_error();
+ 	      goto rechange;
+ 	    }
+ 	    if (ans == 'P')
+ 	      emergency_exit(0);
+ 	    return redraw;
  	  }
  
  	  redraw = 1;
Index: elm2.4.ME+.50/src/read_rc.c
*** elm2.4.25/src/read_rc.c	Mon Aug 23 05:58:06 1993
--- elm2.4.ME+.50/src/read_rc.c	Tue Nov 17 21:12:58 1998
***************
*** 1,181 ****
  
! static char rcsid[] = "@(#)$Id: read_rc.c,v 5.25 1993/08/23 02:58:04 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.25 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: read_rc.c,v $
!  * Revision 5.25  1993/08/23  02:58:04  syd
!  * Call to expand_env for pager should be call to do_expand_env.
!  * temp_dir not initialized.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.24  1993/08/10  18:49:32  syd
!  * When an environment variable was given as the tmpdir definition the src
!  * and dest overlapped in expand_env.  This made elm produce a garbage
!  * expansion because expand_env cannot cope with overlapping src and
!  * dest.  I added a new variable raw_temp_dir to keep src and dest not to
!  * overlap.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.23  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.22  1993/08/03  18:57:21  syd
!  * default_weedlist() can't use pmalloc, because weedout() calls free when
!  * it encounters *clear-weed-list*.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.21  1993/08/03  18:55:42  syd
!  * Spaces in weedout strings wasn't preserved ("From " became "From").
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.20  1993/07/20  02:41:24  syd
!  * Three changes to expand_env() in src/read_rc.c:  make it non-destructive,
!  * have it return an error code instead of bailing out, and add a buffer
!  * size argument to avoid overwritting the destination.  The first is to
!  * avoid all of the gymnastics Elm needed to go through (and occasionally
!  * forgot to go through) to protect the value handed to expand_env().
!  * The second is because expand_env() was originally written to support
!  * "elmrc" and bailing out was a reasonable thing to do there -- but not
!  * in the other places where it has since been used.  The third is just
!  * a matter of practicing safe source code.
!  *
!  * This patch changes all invocations to expand_env() to eliminate making
!  * temporary copies (now that the routine is non-destructive) and to pass
!  * in a destination length.  Since expand_env() no longer bails out on
!  * error, a do_expand_env() routine was added to src/read_rc.c handle
!  * this.  Moreover, the error message now gives some indication of what
!  * the problem is rather than just saying "can't expand".
!  *
!  * Gratitous change to src/editmsg.c renaming filename variables to
!  * clarify the purpose.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.19  1993/06/10  03:08:38  syd
!  * I have been repetedly crashing elm 2.4.22 until I discovered that a
!  * test for failing to open the system elmrc file is mising. This could
!  * usefully be added in read_rc.c. Version info and patch follows:
!  * From: "C.R. Ritson" <C.R.Ritson@newcastle.ac.uk>
!  *
!  * Revision 5.18  1993/06/10  03:07:39  syd
!  * This fixes a bug in the MIME code.  Include_Part() uses expand_env()
!  * to expand the include file name, but since expand_env() is destructive
!  * [it uses strtok()] the file name gets corrupted, and the "Content-Name"
!  * header can contain a bogus value.  The easy fix would be a one-line
!  * hack to Include_Part to use a temporary buffer.  This patch does not
!  * implement the easy fix.  *Every* place expand_env() is used, its side
!  * effects cause problems.  I think the right fix is to make expand_env()
!  * non-destructive (i.e. have it duplicate the input to a temporary buffer
!  * and work from there).  The attached patch modifies expand_env() in
!  * that manner, and eliminates all of the `copy to a temporary buffer'
!  * calls that precede it throughout elm.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.17  1993/06/10  02:55:34  syd
!  * Write options to elmrc even if their values are empty strings.
!  * Rationalize code that reads and writes weedouts and alternates.
!  * From: chip%fin@myrddin.sybus.com
!  *
!  * Revision 5.16  1993/05/16  20:59:14  syd
!  * fix not closing file
!  * From: Syd
!  *
!  * Revision 5.15  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.14  1993/05/08  20:06:15  syd
!  * add sleepinterval to valid options
!  *
!  * Revision 5.13  1993/05/08  18:56:16  syd
!  * created a new elmrc variable named "readmsginc".  This specifies an
!  * increment by which the message count is updated.  If this variable is
!  * set to, say, 25, then the message count will only be updated every 25
!  * messages, displaying 0, 25, 50, 75, and so forth.  The default value
!  * of 1 will cause Elm to behave exactly as it currently does in PL21.
!  * From: Eric Peterson <epeterso@encore.com>
!  *
!  * Revision 5.12  1993/02/03  19:06:31  syd
!  * Remove extra strchr/strcat/strcpy et al declarations
!  * From: Syd
!  *
!  * Revision 5.11  1993/01/20  04:01:07  syd
!  * Adds a new integer parameter builtinlines.
!  * if (builtinlines < 0) and (the length of the message < LINES on
!  *       screen + builtinlines) use internal.
!  * if (builtinlines > 0) and (length of message < builtinlines)
!  * 	use internal pager.
!  * if (builtinlines = 0) or none of the above conditions hold, use the
!  * external pager if defined.
!  * From: "John P. Rouillard" <rouilj@ra.cs.umb.edu>
!  *
!  * Revision 5.10  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.9  1992/11/24  01:44:18  syd
!  * Add raw/no tite stuff around directory create questions
!  * From: Syd via bug report from ade@clark.edu
!  *
!  * Revision 5.8  1992/11/07  16:27:33  syd
!  * Fix where elm duplicates the entry's from the global elm.rc.
!  * It will however still copy the global weedout headers to your local
!  * elmrc if they where not already in it.
!  * From: janw@fwi.uva.nl (Jan Wortelboer)
!  *
!  * Revision 5.7  1992/10/24  13:44:41  syd
!  * There is now an additional elmrc option "displaycharset", which
!  * sets the charset supported on your terminal. This is to prevent
!  * elm from calling out to metamail too often.
!  * Plus a slight documentation update for MIME composition (added examples)
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.6  1992/10/24  13:35:39  syd
!  * changes found by using codecenter on Elm 2.4.3
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.5  1992/10/17  22:58:57  syd
!  * patch to make elm use (or in my case, not use) termcap/terminfo ti/te.
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.4  1992/10/17  22:42:24  syd
!  * Add flags to read_rc to support command line overrides of the option.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.3  1992/10/17  22:25:29  syd
!  * TEXT_SORT was supported, but UNRECOGNIZED
!  * From: ls@dmicvx.dmi.min.dk  (Lennart Sorth)
!  *
!  * Revision 5.2  1992/10/11  00:59:39  syd
!  * Fix some compiler warnings that I receive compiling Elm on my SVR4
!  * machine.
!  * From: Tom Moore <tmoore@fievel.DaytonOH.NCR.COM>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This file contains programs to allow the user to have a .elm/elmrc file
      in their home directory containing any of the following: 
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: read_rc.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This file contains programs to allow the user to have a .elm/elmrc file
      in their home directory containing any of the following: 
***************
*** 252,1102 ****
  
  **/
  
- #define SAVE_OPTS
  #include "headers.h"
  #include "save_opts.h"
  #include "s_elm.h"
  #include <errno.h>
  
  extern opts_menu *find_cfg_opts();
  extern int errno;
  
! char  *error_description(), *shift_lower();
! 
! #define  metachar(c)	(c == '+' || c == '%' || c == '=')
! #ifndef ok_rc_char
! #define ok_rc_char(c)   (isalnum(c) || c == '-' || c == '_')
! #endif
! 
! 
! #define ASSIGNMENT      0
! #define WEEDOUT		1
! #define ALTERNATIVES	2
! 
! #define SYSTEM_RC	0
! #define LOCAL_RC	1
! 
! static int lineno = 0;
! static int errors = 0;
! 
! 
! static void
! do_expand_env(descr, dest, src, destlen)
!     char	*descr, *dest, *src;
!     unsigned	destlen;
! {
!     if (expand_env(dest, src, destlen) != 0) {
! 	printf(catgets(elm_msg_cat, ElmSet, ElmCannotInitErrorExpanding,
! 	    "\r\nCannot initialize \"%s\" - error expanding \"%s\".\r\n"),
! 	    descr, src);
! 	leave(0);
!     }
! }
  
  
! read_rc_file()
! {
! 	/** this routine does all the actual work of reading in the
! 	    .rc file... **/
! 
! 	FILE *file;
! 	char buffer[SLEN], filename[SLEN], *cp, 
! 	     	temp[SLEN]; /* for when an option is run through expandenv */
! 	int  i, ch, len, err;
! 
! 	/* Establish some defaults in case elmrc is incomplete or not there.
! 	 * Defaults for other elmrc options were established in their
! 	 * declaration - in elm.h.  And defaults for sent_mail and recvd_mail
! 	 * are established after the elmrc is read in since these default
! 	 * are based on the folders directory name, which may be given
! 	 * in the emrc.
! 	 * Also establish alternative_editor here since it is based on
! 	 * the default editor and not on the one that might be given in the
! 	 * elmrc.
! 	 */
! 	 
! 	default_weedlist();
! 
! 	errors = 0;
! 	alternative_addresses = NULL; 	/* none yet! */
! 
! 	raw_local_signature[0] = raw_remote_signature[0] =
! 		local_signature[0] = remote_signature[0] =
! 		raw_recvdmail[0] = raw_sentmail[0] = 
! 		allowed_precedences[0] = '\0';
! 		/* no defaults for those */
! 
! 
! 	strcpy(raw_shell, ((cp = getenv("SHELL")) == NULL)? default_shell : cp);
! 	do_expand_env("shell", shell, raw_shell, sizeof(shell));
! 
! 	strcpy(raw_pager, ((cp = getenv("PAGER")) == NULL)? default_pager : cp);
! 	do_expand_env("pager", pager, raw_pager, sizeof(pager));
! 
! 	strcpy(raw_temp_dir, (cp = getenv("TMPDIR")) ? cp : default_temp);
! 	do_expand_env("temp_dir", temp_dir, raw_temp_dir, sizeof(temp_dir));
! 	if (temp_dir[strlen (temp_dir)-1] != '/')
! 	    strcat(temp_dir, "/");
! 
! 	strcpy(raw_editor, ((cp = getenv("EDITOR")) == NULL)? default_editor:cp);
! 	strcpy(alternative_editor, raw_editor);
! 	do_expand_env("editor", editor, raw_editor, sizeof(editor));
! 
! 	strcpy(raw_printout, default_printout);
! 	do_expand_env("printout", printout, raw_printout, sizeof(printout));
! 
! 	sprintf(raw_folders, "~/%s", default_folders);
! 	do_expand_env("folders", folders, raw_folders, sizeof(folders));
! 
! 	sprintf(raw_calendar_file, "~/%s", dflt_calendar_file);
! 	do_expand_env("calendar_file", calendar_file, raw_calendar_file,
! 	    sizeof(calendar_file));
! 
! 	strcpy(e_editor, emacs_editor);
! 	strcpy(v_editor, default_editor);
! 
! 	strcpy(raw_printout, default_printout);
! 	strcpy(printout, raw_printout);
! 
! 	sprintf(raw_folders, "%s/%s", home, default_folders);
! 	strcpy(folders, raw_folders);
! 
! 	sprintf(raw_calendar_file, "%s/%s", home, dflt_calendar_file);
! 	strcpy(calendar_file, raw_calendar_file);
! 
! #ifdef MIME
! 	strcpy(charset, default_charset);
! 	strcpy(charset_compatlist, COMPAT_CHARSETS);
! 	strcpy(display_charset, default_display_charset);
! 	strcpy(text_encoding, default_encoding);
! #endif
! 
! 	/* see if the user has a $HOME/.elm directory */
! 	sprintf(filename, "%s/.elm", home);
! 	if (access(filename, 00) == -1) {
! 	  if(batch_only)  {
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmBatchDirNotice, "\nNotice:\
  \nThis version of ELM requires the use of a .elm directory to store your\
  \nelmrc and alias files. I'd like to create the directory .elm for you\
  \nand set it up, but I can't in \"batch mode\".\
  \nPlease run ELM in \"normal mode\" first.\n"));
! 	    exit(0);
! 	  }
! 
! 	  Raw(ON | NO_TITE);
! 	  MCprintf(catgets(elm_msg_cat, ElmSet, ElmDirNotice, "\n\rNotice:\
  \n\rThis version of ELM requires the use of a .elm directory in your home\
  \n\rdirectory to store your elmrc and alias files. Shall I create the\
  \n\rdirectory .elm for you and set it up (%c/%c/q)? %c%c"),
! 		*def_ans_yes, *def_ans_no, *def_ans_no, BACKSPACE);
! 
! 	  fflush(stdout);
! 	  ch=getchar();
  	  ch = tolower(ch);
  	  if (ch == '\n' || ch == '\r') /* they took the default by pressing cr */
! 		ch = *def_ans_no;
! 
  	  if (ch == *def_ans_no) {
  	    printf(catgets(elm_msg_cat, ElmSet, ElmDirNoticeNo,
! "No.\n\rVery well. I won't create it.\n\rBut, you may run into difficulties later.\n\r"));
  	    if (sleepmsg > 0)
! 		sleep(sleepmsg * 2);
  	  }
  	  else if (ch == *def_ans_yes) {
  	    printf(catgets(elm_msg_cat, ElmSet, ElmDirNoticeYes,
! 		"Yes.\n\rGreat! I'll do it now.\n\r"));
  	    create_new_elmdir();
  	  }
  	  else {
  	    printf(catgets(elm_msg_cat, ElmSet, ElmDirNoticeQuit,
! 		    "Quit.\n\rOK.  Bailing out of ELM.\n\r"));
  	    Raw(OFF | NO_TITE);
  	    exit(0);
  	  }
  	  Raw(OFF | NO_TITE);
! 	}
! 
! 	/* try system-wide rc file */
! 	file = fopen(system_rc_file, "r");
! 	if ( file != NULL ) {
! 	  do_rc(file, SYSTEM_RC);
! 	  fclose(file);
! 	}
! 
! 	/* Look for the elmrc file */
! 	sprintf(filename, "%s/%s", home, elmrcfile);
! 	if ((file = fopen(filename, "r")) == NULL) {
! 	  dprint(2, (debugfile, "Warning:User has no \".elm/elmrc\" file\n\n"));
! 
! 	  /* look for old-style .elmrc file in $HOME */
! 	  sprintf(filename, "%s/.elmrc", home);
! 	  if (access(filename, 00) != -1) {
! 	    move_old_files_to_new();
! 
! 	    /* try to open elmrc file again */
! 	    sprintf(filename, "%s/%s", home, elmrcfile);
! 	    if((file = fopen(filename, "r")) == NULL) {
! 	      err = errno;
! 	      dprint(2, (debugfile,
! 		"Warning: could not open new \".elm/elmrc\" file.\n"));
! 	      dprint(2, (debugfile, "** %s **\n", error_description(err)));
! 	      printf(catgets(elm_msg_cat, ElmSet, ElmCouldNotOpenNewElmrc,
! 		"Warning: could not open new \".elm/elmrc\" file! Using default parameters.\n\r"));
! 	      if (sleepmsg > 0)
! 		    sleep(sleepmsg * 2);
! 	    }
! 	  }
! 	}
! 	if (file != NULL) {
!   	  do_rc(file, LOCAL_RC);
! 	  fclose(file);
! 	}
! 
! /* validate/correct config_options string */
  
! 	if (config_options[0]) {
! 	    register char *s, *t;
! 	    register opts_menu *o;
! 	    s = shift_lower(config_options);
! 	    for (t = config_options; *s; ++s) {
! 		if (*s == '_' || *s == '^') {
! 		    *t++ = *s;
! 		    continue;
! 		}
! 		o = find_cfg_opts(*s);
! 		if (o != NULL)
! 		    *t++ = *s; /* silently remove invalid options */
! 		}
! 	    *t = '\0';
! 	}
! 	do_expand_env("folders", folders, raw_folders, sizeof(folders));
! 
! 	do_expand_env("temp_dir", temp_dir, raw_temp_dir, sizeof(temp_dir));
!   	if (temp_dir[strlen (temp_dir)-1] != '/')
!   	    strcat(temp_dir, "/");
!   
! 	do_expand_env("shell", shell, raw_shell, sizeof(shell));
! 
! 	do_expand_env("editor", editor, raw_editor, sizeof(editor));
! 
! 	do_expand_env("calendar_file", calendar_file, raw_calendar_file,
! 	    sizeof(calendar_file));
! 
! 	do_expand_env("printout", printout, raw_printout, sizeof(printout));
! 
! 	do_expand_env("pager", pager, raw_pager, sizeof(pager));
! 	if (equal(pager, "builtin+") || equal(pager, "internal+"))
! 		clear_pages++;
! 
! 	do_expand_env("local_signature", local_signature,
! 	    raw_local_signature, sizeof(local_signature));
! 	do_expand_env("remote_signature", remote_signature,
! 	    raw_remote_signature, sizeof(remote_signature));
! 
! 	if (equal(local_signature, remote_signature) &&
! 	    (equal(shift_lower(local_signature), "on") ||
! 	    equal(shift_lower(local_signature), "off"))) {
! 	    errors++;
! 
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmSignatureObsolete,
! 	"\"signature\" used in obsolete way in .elm/elmrc file. Ignored!\n\r\
! \t(Signature should specify the filename to use rather than on/off.)\n\r\n"));
! 
! 	    raw_local_signature[0] = raw_remote_signature[0] =
! 		local_signature[0] = remote_signature[0] = '\0';
! 	}
! 
! 	if (hp_softkeys) hp_terminal=TRUE;	/* must be set also! */
! 
! 	allow_forms = (allow_forms?MAYBE:NO);
! 	if (bounceback > MAX_HOPS) {
! 	    errors++;
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmBouncebackGTMaxhops,
! 	"Warning: bounceback is set to greater than %d (max-hops). Ignored.\n\r"),
! 		     MAX_HOPS);
! 	    bounceback = 0;
! 	}
! 
! 	if ((timeout != 0) && (timeout < 10)) {
! 	    errors++;
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmTimeoutLTTen,
! 		 "Warning: timeout is set to less than 10 seconds. Ignored.\n\r"));
! 	    timeout = 0;
! 	}
! 
! 	if (readmsginc < 1) {
! 		errors++;
! 		printf(catgets(elm_msg_cat, ElmSet, ElmReadMessageIncrement,
! 		"Warning: readmsginc is set to less than 1.  Ignored.\n\r"));
! 		readmsginc = 1;
! 	}
! 
! 	if (sleepmsg < 0) {
! 		errors++;
! 		printf(catgets(elm_msg_cat, ElmSet, ElmSleepMessageInvalid,
! 		"Warning: sleepmsg is set to less than 0.  Setting to 0.\n\r"));
! 		sleepmsg = 0;
! 	}
! 
! 	/* see if the user has a folders directory */
! 	if (access(folders, 00) == -1) {
! 	  if(batch_only)  {
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmBatchNoticeFoldersDir, "\n\
  Notice:\n\
  ELM requires the use of a folders directory to store your mail folders in.\n\
  I'd like to create the directory %s for you,\n\
  but I can't in \"batch mode\". Please run ELM in \"normal mode\" first.\n"),
! 		folders);
! 	    exit(0);
! 	  }
  
! 	  Raw( ON | NO_TITE );
! 	  MCprintf(catgets(elm_msg_cat, ElmSet, ElmNoticeFoldersDir,"\n\rNotice:\n\r\
  ELM requires the use of a folders directory to store your mail folders in.\n\r\
  Shall I create the directory %s for you (%c/%c/q)? %c%c"),
! 		folders, *def_ans_yes, *def_ans_no, *def_ans_yes, BACKSPACE);
! 
! 	  fflush(stdout);
! 	  ch=getchar();
! 	  ch = tolower(ch);
! 	  if (ch == '\n' || ch == '\r') /* they took the default by pressing cr */
! 		ch = *def_ans_yes;
! 
! 	  if (ch == *def_ans_no) {
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmDirNoticeNo,
! "No.\n\rVery well. I won't create it.\n\rBut, you may run into difficulties later.\n\r"));
! 	    if (sleepmsg > 0)
! 		    sleep(sleepmsg * 2);
! 	  }
! 	  else if (ch == *def_ans_yes) {
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmDirNoticeYes,
! 		"Yes.\n\rGreat! I'll do it now.\n\r"));
! 	    create_new_folders();
! 	  }
! 	  else {
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmDirNoticeQuit,
! 		    "Quit.\n\rOK.  Bailing out of ELM.\n\r"));
! 	    Raw(OFF | NO_TITE);
! 	    exit(0);
! 	  }
! 	  Raw( OFF | NO_TITE );
! 	}
! 
! 	/* If recvd_mail or sent_mail havent't yet been established in
! 	 * the elmrc, establish them from their defaults.
! 	 * Then if they begin with a metacharacter, replace it with the
! 	 * folders directory name.
! 	 */
! 	if(*raw_recvdmail == '\0') {
! 	  strcpy(raw_recvdmail, default_recvdmail);
! 	}
! 
! 	do_expand_env("recvd_mail", recvd_mail, raw_recvdmail,
! 	    sizeof(recvd_mail));
! 
! 	if(metachar(recvd_mail[0])) {
! 	  strcpy(buffer, &recvd_mail[1]);
! 	  sprintf(recvd_mail, "%s/%s", folders, buffer);
! 	}
! 
! 	if(*raw_sentmail == '\0') {
! 	  sprintf(raw_sentmail, default_sentmail);
! 	  sprintf(sent_mail, default_sentmail);
! 	}
! 
! 	do_expand_env("sent_mail", sent_mail, raw_sentmail, sizeof(sent_mail));
! 
! 	if(metachar(sent_mail[0])) {
! 	  strcpy(buffer, &sent_mail[1]);
! 	  sprintf(sent_mail, "%s/%s", folders, buffer);
! 	}
! 
! 	if (debug > 10) 	/** only do this if we REALLY want debug! **/
! 	  dump_rc_results();
! 
! }
! 
! 
! do_rc(file, lcl)
! FILE *file;
! int lcl;
! {
! 	static int prev_type = 0;
! 	int x;
! 	char buffer[SLEN], word1[SLEN], word2[SLEN];
! 
! 	if (!file) return;
! 	lineno=0;
! 
! 	while (x = mail_gets(buffer, SLEN, file)) {
! 	    lineno++;
! 	    no_ret(buffer);	 	/* remove return */
! 	    if (buffer[0] == '#'        /* comment       */
! 	     || x < 2)     /* empty line    */
! 	      continue;
! 
! 	    if(breakup(buffer, word1, word2) == -1)
! 	        continue;		/* word2 is null - let default value stand */
! 
! 	    if(strcmp(word1, "warnings") == 0)
! 		continue;		/* grandfather old keywords */
! 
! 	    strcpy(word1, shift_lower(word1));	/* to lower case */
! 	    x = do_set(file, word1, word2, lcl);
! 
! 	    if (x == 0) {
! 		if (prev_type == DT_ALT) {
! 		    alternatives(buffer);
! 		} else if (prev_type == DT_WEE) {
! 		    weedout(buffer);
! 		} else {
! 		    errors++;
! 		    printf(catgets(elm_msg_cat, ElmSet, ElmBadSortKeyInElmrc,
!       "I can't understand sort key \"%s\" in line %d in your \".elm/elmrc\" file\n\r"),
! 			word1, lineno);
! 		}
! 	    } else
! 		prev_type = x;
! 	}
! }
! 
! /*
!  * set the named parameter according to save_info structure.
!  * This routine may call itself (DT_SYN or DT_MLT).
!  * Also tags params that were set in "local" (personal) RC file
!  * so we know to save them back out in "o)ptions" screen.
!  * Uses an internal table to decode sort-by params...should be coupled
!  * with sort_name(), etc...but...
!  */
! 
! do_set(file, word1, word2, lcl)
! FILE *file;
! int lcl;
! char *word1, *word2;
! {
! 	register int x, y;
! 
! 	for (x=0; x < NUMBER_OF_SAVEABLE_OPTIONS; ++x) {
! 	    y = strcmp(word1, save_info[x].name);
! 	    if (y <= 0)
! 		break;
! 	}
! 
! 	if (y != 0)
! 	    return(0);
! 
! 	if (save_info[x].flags & FL_SYS && lcl == LOCAL_RC)
! 	    return(0);
! 
! 	if (lcl == LOCAL_RC)
! 	    save_info[x].flags |= FL_LOCAL;
! 
! 	switch (save_info[x].flags & DT_MASK) {
! 	    case DT_SYN:
! 		return(do_set(file, SAVE_INFO_SYN(x), word2, lcl));
! 
! 	    case DT_MLT:
! 		y=0;
! 		{ register char **s;
! 		for (s = SAVE_INFO_MLT(x); *s; ++s)
! 		    y |= do_set(file, *s, word2, lcl);
! 		}
! 
! /* a kludge that should be part of the "machine", but... */
! 		if (equal(save_info[x].name, "alwaysleave")) {
! 		    always_store = !always_store;
! 		}
! 		return(y); /* we shouldn't "or" the values into "y" */
! 
! 	    case DT_STR:
! 		strcpy(SAVE_INFO_STR(x), word2);
! 		if (save_info[x].flags & FL_NOSPC) {
! 		    register char *s;
! 		    for (s = SAVE_INFO_STR(x); *s; ++s)
! 			if (*s == '_') *s=' ';
! 		    }
! 		break;
! 
! 	    case DT_CHR:
! 		*SAVE_INFO_CHR(x) = word2[0];
! 		break;
! 
! 	    case DT_NUM:
! 		*SAVE_INFO_NUM(x) = atoi(word2);
! 		break;
! 
! 	    case DT_BOL:
! 		if (save_info[x].flags & FL_OR)
! 		    *SAVE_INFO_BOL(x) |= is_it_on(word2);
! 		else if (save_info[x].flags & FL_AND)
! 		    *SAVE_INFO_BOL(x) &= is_it_on(word2);
! 		else
! 		    *SAVE_INFO_BOL(x) = is_it_on(word2);
! 		break;
! 
! 	    case DT_SRT:
! 		{ static struct { char *kw; int sv; } srtval[]={
! 		    {"sent", SENT_DATE},
! 		    {"received", RECEIVED_DATE},
! 		    {"recieved", RECEIVED_DATE},
! 		    {"rec", RECEIVED_DATE},
! 		    {"from", SENDER},
! 		    {"sender", SENDER},
! 		    {"size", SIZE},
! 		    {"lines", SIZE},
! 		    {"subject", SUBJECT},
! 		    {"mailbox", MAILBOX_ORDER},
! 		    {"folder", MAILBOX_ORDER},
! 		    {"status", STATUS},
! 		    {NULL, 0} };
! 		    char *s = word2;
! 		    int f;
! 
! 		    f = 1;
! 		    strcpy(word2, shift_lower(word2));
! 		    if (strncmp(s, "rev-", 4) == 0 ||
! 			strncmp(s, "reverse-", 8) == 0) {
! 			f = -f;
! 			s = index(s, '-') + 1;
! 		    }
! 
! 		    for (y= 0; srtval[y].kw; y++) {
! 			if (equal(s, srtval[y].kw))
! 			    break;
! 		    }
! 		    if (srtval[y].kw) {
! 			*SAVE_INFO_SRT(x) = f > 0 ? srtval[y].sv : -srtval[y].sv;
! 		    } else {
! 			errors++;
! 			printf(catgets(elm_msg_cat, ElmSet, ElmBadSortKeyInElmrc,
! 	  "I can't understand sort key \"%s\" in line %d in your \".elm/elmrc\" file\n\r"),
! 			    word2, lineno);
! 		    }
! 		}
! 		break;
! 
! 	    case DT_ASR:
! 		{ static struct { char *kw; int sv; } srtval[]={
! 		    {"alias", ALIAS_SORT},
! 		    {"name", NAME_SORT},
! 		    {"text", TEXT_SORT},
! 		    {NULL, 0} };
! 		    char *s = word2;
! 		    int f;
! 
! 		    f = 1;
! 		    strcpy(word2, shift_lower(word2));
! 		    if (strncmp(s, "rev-", 4) == 0 ||
! 			strncmp(s, "reverse-", 8) == 0) {
! 			f = -f;
! 			s = index(s, '-') + 1;
! 		    }
! 
! 		    for (y= 0; srtval[y].kw; y++) {
! 			if (equal(s, srtval[y].kw))
! 			    break;
! 		    }
! 		    if (srtval[y].kw) {
! 			*SAVE_INFO_SRT(x) = f > 0 ? srtval[y].sv : -srtval[y].sv;
! 		    } else {
! 			errors++;
! 			printf(catgets(elm_msg_cat, ElmSet, ElmBadAliasSortInElmrc,
! 	"I can't understand alias sort key \"%s\" in line %d in your \".elm/elmrc\" file\n\r"),
! 			    word2, lineno);
! 		    }
! 		}
! 		break;
! 
! 	    case DT_ALT:
! 		alternatives(word2);
! 		break;
! 
! 	    case DT_WEE:
! 		weedout(word2);
! 		break;
! 	    }
! 
! 	return(save_info[x].flags & DT_MASK);
! }
! 	
! weedout(string)
! char *string;
! {
! 	/** This routine is called with a list of headers to weed out.   **/
! 
! 	char *strptr, *header, *p;
! 	int finished;
! 
! 	finished = FALSE;
! 	strptr = string;
! 	while (!finished && (header = strtokq(strptr, "\t ,", TRUE)) != NULL) {
! 	  strptr = NULL;
! 
! 	  if (!*header)
! 	    continue;
! 
! 	  for (p = header; *p; ++p) {
! 	    if (*p == '_')
! 	      *p = ' ';
! 	  }
! 
! 	  if (! istrcmp(header, "*end-of-user-headers*"))
! 	    break;
! 
! 	  if (! istrcmp(header, "*end-of-defaults*"))
! 	    finished = TRUE;
! 
! 	  if (! istrcmp(header, "*clear-weed-list*")) {
! 	    while (weedcount)
! 	      free(weedlist[--weedcount]);
! 	    header = "*end-of-defaults*";
! 	  }
! 
! 	  if (matches_weedlist(header))
! 	    continue;
! 
! 	  if (weedcount > MAX_IN_WEEDLIST) {
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmTooManyWeedHeaders,
! 		   "Too many weed headers!  Leaving...\n\r"));
! 	    exit(1);
! 	  }
! 	  if ((p = malloc(strlen(header) + 1)) == NULL) {
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmTooManyWeedPmalloc,
! 		   "Too many weed headers!  Out of memory!  Leaving...\n\r"));
! 	    exit(1);
! 	  }
! 	  strcpy(p, header);
! 	  weedlist[weedcount++] = p;
! 	}
! }
! 
! 
! alternatives(string)
! char *string;
! {
! 	/** This routine is called with a list of alternative addresses
! 	    that you may receive mail from (forwarded) **/
! 
! 	char *strptr, *address;
! 	struct addr_rec *current_record, *previous_record;
! 
! 	previous_record = alternative_addresses;	/* start 'er up! */
! 	/* move to the END of the alternative addresses list */
! 
! 	if (previous_record != NULL)
! 	  while (previous_record->next != NULL)
! 	    previous_record = previous_record->next;
! 
! 	strptr = (char *) string;
! 
! 	while ((address = strtok(strptr, "\t ,\"'")) != NULL) {
! 	  if (previous_record == NULL) {
! 	    previous_record = (struct addr_rec *) pmalloc(sizeof 
! 		*alternative_addresses);
! 
! 	    strcpy(previous_record->address, address);
! 	    previous_record->next = NULL;
! 	    alternative_addresses = previous_record;
! 	  }
! 	  else {
! 	    current_record = (struct addr_rec *) pmalloc(sizeof 
! 		*alternative_addresses);
! 	  
! 	    strcpy(current_record->address, address);
! 	    current_record->next = NULL;
! 	    previous_record->next = current_record;
! 	    previous_record = current_record;
! 	  }
! 	  strptr = (char *) NULL;
! 	}
! }
! 
! default_weedlist()
! {
! 	/** Install the default headers to weed out!  Many gracious 
! 	    thanks to John Lebovitz for this dynamic method of 
! 	    allocation!
! 	**/
! 
! 	static char *default_list[] = { ">From", "In-Reply-To:",
! 		       "References:", "Newsgroups:", "Received:",
! 		       "Apparently-To:", "Message-Id:", "Content-Type:",
! 		       "Content-Length", "MIME-Version",
! 		       "Content-Transfer-Encoding",
! 		       "From", "X-Mailer:", "Status:",
! 		       "*end-of-defaults*", NULL
! 		     };
! 
! 	for (weedcount = 0; default_list[weedcount] != (char *) 0;weedcount++){
! 	  if ((weedlist[weedcount] = 
! 	      malloc(strlen(default_list[weedcount]) + 1)) == NULL) {
! 	    printf(catgets(elm_msg_cat, ElmSet, ElmNoMemDefaultWeed,
! 		"\nNot enough memory for default weedlist. Leaving.\n"));
! 	    leave(1);
! 	  }
! 	  strcpy(weedlist[weedcount], default_list[weedcount]);
! 	}
! }
! 
! int
! matches_weedlist(buffer)
! char *buffer;
! {
! 	/** returns true iff the first 'n' characters of 'buffer' 
! 	    match an entry of the weedlist **/
! 	
! 	register int i;
! 
! 	for (i=0;i < weedcount; i++)
! 	  if (strincmp(buffer, weedlist[i], strlen(weedlist[i])) == 0) 
! 	    return(1);
! 
! 	return(0);
! }
! 
! int
! breakup(buffer, word1, word2)
! char *buffer, *word1, *word2;
! {
! 	/** This routine breaks buffer down into word1, word2 where 
! 	    word1 is alpha characters only, and there is an equal
! 	    sign delimiting the two...
! 		alpha = beta
! 	    For lines with more than one 'rhs', word2 is set to the
! 	    entire string.
! 	    Return -1 if word 2 is of zero length, else 0.
! 	**/
! 
! 	register int i;
! 	
! 	for (i=0;buffer[i] != '\0' && ok_rc_char(buffer[i]); i++)
! 	  if (buffer[i] == '_')
! 	    word1[i] = '-';
! 	  else
! 	    word1[i] = tolower(buffer[i]);
! 
! 	word1[i++] = '\0';	/* that's the first word! */
! 
! 	/** spaces before equal sign? **/
! 
! 	while (whitespace(buffer[i])) i++;
! 	if (buffer[i] == '=') i++;
! 
! 	/** spaces after equal sign? **/
! 
! 	while (whitespace(buffer[i])) i++;
! 
! 	if (buffer[i] != '\0')
! 	  strcpy(word2, (char *) (buffer + i));
! 	else
! 	  word2[0] = '\0';
! 
! 	/* remove trailing spaces from word2! */
! 	i = strlen(word2) - 1;
! 	while(i && (whitespace(word2[i]) || word2[i] == '\n'))
! 	  word2[i--] = '\0';
! 
! 	return(*word2 == '\0' ? -1 : 0 );
! 
! }
! 
! 
! /*
!  * expand_env() - Perform environment expansion on a pathname.  Also
!  * replaces "~" at the front of the path with the user's home directory.
!  * Environment expansion occurs at the path component boundaries, e.g.
!  * "/foo/$BAR/baz" is subject to expansion but "/foo/zzz$BAR/baz" is not.
!  * Returns 0 if expansion successful, -1 if an error occurs (result too
!  * long, cannot get home directory, or environment expansion failed).
!  */
! expand_env(dest, src, destlen)
! char *dest;		/* pointer to space to hold the result	*/
! char *src;		/* pointer to string to expand		*/
! unsigned destlen;	/* size of the destination buffer	*/
! {
!     char envname_buf[SLEN], *envname_front, *expval;
!     int check_for_env, len, ret;
! 
!     --destlen;		/* reserve space for trailing '\0' */
!     ret = 0;		/* assume success */
! 
!     /*
!      * Replace "~" at front with user's home directory.
!      */
!     if (src[0] == '~' && (src[1] == '\0' || src[1] == '/')) {
! 	if (home[0] == '\0') {
! 	    expval = "~";
! 	    ret = -1;
! 	} else {
! 	    expval = home;
! 	}
! 	if ((len = strlen(expval)) > destlen)
! 	    len = destlen;
! 	strfcpy(dest, expval, len+1);
! 	dest += len;
! 	destlen -= len;
! 	++src;
      }
! 
!     /*
!      * Copy through the rest, performing $NAME expansion where appropriate.
!      */
!     check_for_env = TRUE;
!     while (destlen > 0 && *src != '\0') {
! 
! 	/*
! 	 * Check for "$NAME" at the start of every path component.
! 	 */
! 	if (check_for_env && *src == '$') {
! 
! 	    /*
! 	     * Get the environment parameter name into "envname_buf"
! 	     * and advance "src" to the next path component.
! 	     */
! 	    envname_front = ++src;
! 	    if ((len = strcspn(src, "/")) == 0)
! 		len = strlen(src);
! 	    src += len;
! 	    if (len > sizeof(envname_buf)-1)
! 		len = sizeof(envname_buf)-1;
! 	    strfcpy(envname_buf, envname_front, len+1);
! 
! 	    /*
! 	     * Copy over the environment expansion.  If the environment
! 	     * parameter is undefined then copy over unchanged and set
! 	     * a fail return status.
! 	     */
! 	    if ((expval = getenv(envname_buf)) == NULL) {
! 		*dest++ = '$';
! 		--destlen;
! 		expval = envname_buf;
! 		ret = -1;
! 	    }
! 	    if ((len = strlen(expval)) > destlen)
! 		len = destlen;
! 	    strfcpy(dest, expval, len+1);
! 	    dest += len;
! 	    destlen -= len;
! 	    check_for_env = FALSE;
! 
! 	} else {
! 
! 	    check_for_env = (*src == '/');
! 	    *dest++ = *src++;
! 	    --destlen;
  
! 	}
  
      }
! 
!     *dest = '\0';
!     if (destlen <= 0)
! 	ret = -1;
!     return ret;
  }
  
  #define on_off(s)	(s == 1? "ON " : "OFF")
! dump_rc_results()
  	{
  	register int i, j, len = 0;
  	char buf[SLEN], *s;
--- 87,234 ----
  
  **/
  
  #include "headers.h"
  #include "save_opts.h"
  #include "s_elm.h"
  #include <errno.h>
+ #include "me.h"
  
  extern opts_menu *find_cfg_opts();
  extern int errno;
  
! char  *error_description(), *shift_lower(), *mode_to_str();
  
+ static void dump_rc_results P_((void));
  
! void directory_check() {
!   char  filename[SLEN];
!   int ch;
! 
!   if (debug > 10) 	/** only do this if we REALLY want debug! **/
!     dump_rc_results();
! 
!   /* see if the user has a $HOME/.elm directory */
!   elm_sfprintf(filename, sizeof filename,
! 	       FRM("%s/.elm"), 
! 	       home);
!   if (access(filename, 00) == -1) {
!     if(batch_only)  {
!       printf(catgets(elm_msg_cat, ElmSet, ElmBatchDirNotice, "\nNotice:\
  \nThis version of ELM requires the use of a .elm directory to store your\
  \nelmrc and alias files. I'd like to create the directory .elm for you\
  \nand set it up, but I can't in \"batch mode\".\
  \nPlease run ELM in \"normal mode\" first.\n"));
!       exit(0);
!     }
!     
!     Raw(ON | NO_TITE);
!   redraw1:
!     MCprintf(catgets(elm_msg_cat, ElmSet, ElmDirNotice, "\n\rNotice:\
  \n\rThis version of ELM requires the use of a .elm directory in your home\
  \n\rdirectory to store your elmrc and alias files. Shall I create the\
  \n\rdirectory .elm for you and set it up (%c/%c/q)? %c%c"),
! 	     *def_ans_yes, *def_ans_no, *def_ans_no, BACKSPACE);
!     
!     fflush(stdout);
!     ch=ReadCh(REDRAW_MARK);
!     if (REDRAW_MARK == ch)
!       goto redraw1;
!     
  	  ch = tolower(ch);
  	  if (ch == '\n' || ch == '\r') /* they took the default by pressing cr */
! 	    ch = *def_ans_no;
! 	  
  	  if (ch == *def_ans_no) {
  	    printf(catgets(elm_msg_cat, ElmSet, ElmDirNoticeNo,
! 			   "No.\n\rVery well. I won't create it.\n\rBut, you may run into difficulties later.\n\r"));
  	    if (sleepmsg > 0)
! 	      sleep(sleepmsg * 2);
  	  }
  	  else if (ch == *def_ans_yes) {
  	    printf(catgets(elm_msg_cat, ElmSet, ElmDirNoticeYes,
! 			   "Yes.\n\rGreat! I'll do it now.\n\r"));
  	    create_new_elmdir();
  	  }
  	  else {
  	    printf(catgets(elm_msg_cat, ElmSet, ElmDirNoticeQuit,
! 			   "Quit.\n\rOK.  Bailing out of ELM.\n\r"));
  	    Raw(OFF | NO_TITE);
  	    exit(0);
  	  }
  	  Raw(OFF | NO_TITE);
!   }	  
  
!   /* see if the user has a folders directory */
!   if (access(folders, 00) == -1) {
!     if(batch_only)  {
!       printf(catgets(elm_msg_cat, ElmSet, ElmBatchNoticeFoldersDir, "\n\
  Notice:\n\
  ELM requires the use of a folders directory to store your mail folders in.\n\
  I'd like to create the directory %s for you,\n\
  but I can't in \"batch mode\". Please run ELM in \"normal mode\" first.\n"),
! 	     folders);
!       exit(0);
!     }
  
!     Raw( ON | NO_TITE );
!   redraw2:
!     MCprintf(catgets(elm_msg_cat, ElmSet, ElmNoticeFoldersDir,"\n\rNotice:\n\r\
  ELM requires the use of a folders directory to store your mail folders in.\n\r\
  Shall I create the directory %s for you (%c/%c/q)? %c%c"),
! 	     folders, *def_ans_yes, *def_ans_no, *def_ans_yes, BACKSPACE);
!     
!     fflush(stdout);
!     ch=ReadCh(REDRAW_MARK);
!     if (REDRAW_MARK == ch)
!       goto redraw2;
!     
!     ch = tolower(ch);
!     if (ch == '\n' || ch == '\r') /* they took the default by pressing cr */
!       ch = *def_ans_yes;
! 
!     if (ch == *def_ans_no) {
!       printf(catgets(elm_msg_cat, ElmSet, ElmDirNoticeNo,
! 		     "No.\n\rVery well. I won't create it.\n\rBut, you may run into difficulties later.\n\r"));
!       if (sleepmsg > 0)
! 	sleep(sleepmsg * 2);
      }
!     else if (ch == *def_ans_yes) {
!       printf(catgets(elm_msg_cat, ElmSet, ElmDirNoticeYes,
! 		     "Yes.\n\rGreat! I'll do it now.\n\r"));
!       create_new_folders();
!     }
!     else {
!       printf(catgets(elm_msg_cat, ElmSet, ElmDirNoticeQuit,
! 		     "Quit.\n\rOK.  Bailing out of ELM.\n\r"));
!       Raw(OFF | NO_TITE);
!       exit(0);
!     }
!     Raw( OFF | NO_TITE );
!   }
  
! /* validate/correct config_options string */
  
+   if (config_options[0]) {
+     register char *s, *t;
+     register opts_menu *o;
+     s = shift_lower(config_options);
+     for (t = config_options; *s; ++s) {
+       if (*s == '_' || *s == '^') {
+ 	*t++ = *s;
+ 	continue;
+       }
+       o = find_cfg_opts(*s);
+       if (o != NULL)
+ 	*t++ = *s; /* silently remove invalid options */
      }
!     *t = '\0';
!   }
  }
  
+ 
+ 
  #define on_off(s)	(s == 1? "ON " : "OFF")
! static void dump_rc_results()
  	{
  	register int i, j, len = 0;
  	char buf[SLEN], *s;
***************
*** 1133,1147 ****
  			break;
  
  		    case DT_NUM:
! 			sprintf(buf, "%d", *SAVE_INFO_NUM(i));
  			s = buf;
  			break;
  
  		    case DT_CHR:
! 			sprintf(buf, "%c", *SAVE_INFO_CHR(i));
  			s = buf;
  			break;
  
  		    case DT_BOL:
  			s = on_off(*SAVE_INFO_BOL(i));
  			break;
--- 265,286 ----
  			break;
  
  		    case DT_NUM:
! 			elm_sfprintf(buf, sizeof buf,
! 				     FRM("%d"), 
! 				     *SAVE_INFO_NUM(i));
  			s = buf;
  			break;
  
  		    case DT_CHR:
! 		        buf[0] = *SAVE_INFO_CHR(i);
! 			buf[1] = '\0';
  			s = buf;
  			break;
  
+ 		    case DT_PRM:
+ 			s = mode_to_str(*SAVE_INFO_NUM(i));
+ 			break;
+ 
  		    case DT_BOL:
  			s = on_off(*SAVE_INFO_BOL(i));
  			break;
***************
*** 1160,1186 ****
  		}
  	    }
  	fprintf(debugfile, "\n\n");
- }
- 
- is_it_on(word)
- char *word;
- {
- 	/** Returns TRUE if the specified word is either 'ON', 'YES'
- 	    or 'TRUE', and FALSE otherwise.   We explicitly translate
- 	    to lowercase here to ensure that we have the fastest
- 	    routine possible - we really DON'T want to have this take
- 	    a long time or our startup will be major pain each time.
- 	**/
- 
- 	static char mybuffer[NLEN];
- 	register int i, j;
- 
- 	for (i=0, j=0; word[i] != '\0'; i++)
- 	  mybuffer[j++] = tolower(word[i]);
- 	mybuffer[j] = '\0';
- 
- 	return(  (strncmp(mybuffer, "on",   2) == 0) ||
- 		 (strncmp(mybuffer, "yes",  3) == 0) ||
- 		 (strncmp(mybuffer, "true", 4) == 0)
- 	      );
  }
--- 299,302 ----
Index: elm2.4.ME+.50/src/remail.c
*** elm2.4.25/src/remail.c	Mon Dec  4 17:50:56 1995
--- elm2.4.ME+.50/src/remail.c	Tue Nov 17 21:12:57 1998
***************
*** 1,97 ****
  
! static char rcsid[] = "@(#)$Id: remail.c,v 5.13 1993/09/27 01:51:38 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.13 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: remail.c,v $
!  * Revision 5.13  1993/09/27  01:51:38  syd
!  * Add elm_chown to consolidate for Xenix not allowing -1
!  * From: Syd
!  *
!  * Revision 5.12  1993/08/23  03:26:24  syd
!  * Try setting group id separate from user id in chown to
!  * allow restricted systems to change group id of file
!  * From: Syd
!  *
!  * Revision 5.11  1993/08/10  18:53:31  syd
!  * I compiled elm 2.4.22 with Purify 2 and fixed some memory leaks and
!  * some reads of unitialized memory.
!  * From: vogt@isa.de
!  *
!  * Revision 5.10  1993/04/21  01:25:45  syd
!  * I'm using Elm 2.4.21 under Linux.  Linux has no Bourne shell.  Each
!  * user installs her favorite shell as /bin/sh.  I use Bash 1.12.
!  *
!  * Elm invokes the mail transport (MTA) like so:
!  *
!  *    ( ( MTA destination; rm -f tempfile ) & ) < tempfile &
!  *
!  * This form of command doesn't work with my Bash, in which any command
!  * which is backgrounded ("&") gets its stdin attached to /dev/null.
!  *
!  * The below patch arranges for Elm to call the MTA thusly:
!  *
!  *    ( MTA destination <tempfile; rm -f tempfile ) &
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.9  1993/04/12  02:34:36  syd
!  * I have now added a parameter which controls whether want_to clears the
!  * line and centers the question or behaves like it did before. I also
!  * added a 0 at the end of the parameter list to all the other calls to
!  * want_to where a centered question on a clean line is not desirable.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.8  1993/01/20  03:37:16  syd
!  * Nits and typos in the NLS messages and corresponding default messages.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.7  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.6  1992/11/26  01:46:26  syd
!  * add Decode option to copy_message, convert copy_message to
!  * use bit or for options.
!  * From: Syd and bjoerns@stud.cs.uit.no (Bjoern Stabell)
!  *
!  * Revision 5.5  1992/11/26  00:49:04  syd
!  * fix use of errno
!  * From: Syd
!  *
!  * Revision 5.4  1992/11/22  01:14:20  syd
!  * Allow SCO MMDF to use the mmdf library for mailer via execmail.
!  * From: Larry Philps <larryp@sco.com>
!  *
!  * Revision 5.3  1992/10/24  13:35:39  syd
!  * changes found by using codecenter on Elm 2.4.3
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.2  1992/10/11  00:59:39  syd
!  * Fix some compiler warnings that I receive compiling Elm on my SVR4
!  * machine.
!  * From: Tom Moore <tmoore@fievel.DaytonOH.NCR.COM>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** For those cases when you want to have a message continue along
      to another person in such a way as they end up receiving it with
!     the return address the person YOU received the mail from (does
!     this comment make any sense yet?)...
  
  **/
  
--- 1,20 ----
  
! static char rcsid[] = "@(#)$Id: remail.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** For those cases when you want to have a message continue along
      to another person in such a way as they end up receiving it with
!     the reply address the person YOU received the mail from.
  
  **/
  
***************
*** 98,103 ****
--- 21,27 ----
  #include "headers.h"
  #include "s_elm.h"
  #include <errno.h>
+ #include "me.h"
  
  extern int errno;
  
***************
*** 104,109 ****
--- 28,36 ----
  char *error_description();
  extern void display_to();
  
+ static void remail_sent P_((FILE *fd, char * title, struct run_state *rs,
+ 			    int ret, int exit_stat));
+ 
  int
  remail()
  {
***************
*** 110,125 ****
  	/** remail a message... returns TRUE if new foot needed ... **/
  	
  	FILE *mailfd;
-         int mailfd_handle;
  	char entered[VERY_LONG_STRING], expanded[VERY_LONG_STRING];
  	char *filename, buffer[VERY_LONG_STRING], ch;
! 	char mailerflags[NLEN];
  	int  err;
  	extern char *tempnam();
  
  	entered[0] = '\0';
  
! 	get_to(entered, expanded);
  	if (strlen(entered) == 0)
  	  return(0);
  
--- 37,53 ----
  	/** remail a message... returns TRUE if new foot needed ... **/
  	
  	FILE *mailfd;
  	char entered[VERY_LONG_STRING], expanded[VERY_LONG_STRING];
  	char *filename, buffer[VERY_LONG_STRING], ch;
! 	char *mailerflags[20], **argv;
! 	int mf_idx = 0;
  	int  err;
  	extern char *tempnam();
  
  	entered[0] = '\0';
  
! 	get_to(entered, expanded, 
! 	       sizeof entered, sizeof expanded);
  	if (strlen(entered) == 0)
  	  return(0);
  
***************
*** 127,148 ****
  
  	if((filename=tempnam(temp_dir, "snd.")) == NULL) {
  	  dprint(1, (debugfile, "couldn't make temp file nam! (remail)\n"));
! 	  sprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmCouldntMakeTempFileName,
! 		"Sorry - couldn't make file temp file name."));
! 	  set_error(buffer);
  	  return(1);
  	}
  
!         if ( ( (mailfd_handle = open(filename, O_RDWR|O_CREAT|O_EXCL,0600)) == -1) ||
!              ( (mailfd = fdopen(mailfd_handle, "w")) == NULL) ) {
  	  err = errno;
  	  dprint(1, (debugfile, "couldn't open temp file %s! (remail)\n", 
  		  filename));
  	  dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	  sprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmCouldntOpenForWriting,
! 			"Sorry - couldn't open file %s for writing (%s)."),
! 		  error_description(err));
! 	  set_error(buffer);
  	  free(filename);
  	  return(1);
  	}
--- 55,73 ----
  
  	if((filename=tempnam(temp_dir, "snd.")) == NULL) {
  	  dprint(1, (debugfile, "couldn't make temp file nam! (remail)\n"));
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldntMakeTempFileName,
! 			    "Sorry - couldn't make file temp file name."));
  	  return(1);
  	}
  
!         if ((mailfd = safeopen_rdwr(filename)) == NULL) {
  	  err = errno;
  	  dprint(1, (debugfile, "couldn't open temp file %s! (remail)\n", 
  		  filename));
  	  dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldntOpenForWriting,
! 			    "Sorry - couldn't open file %s for writing (%s)."),
! 		    error_description(err));
  	  free(filename);
  	  return(1);
  	}
***************
*** 157,212 ****
  	  do_mmdf_addresses(mailfd, strip_parens(strip_commas(expanded)));
  #endif /* MMDF */
  
! 	copy_message("", mailfd, CM_REMOTE | CM_MMDF_HEAD | CM_REMAIL);
! 
! 	fclose(mailfd);
  
  	/** Got the messsage, now let's ensure the person really wants to 
  	    remail it... **/
  
! 	ClearLine(LINES-1);
! 	ClearLine(LINES);
! 	MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmSureYouWantToRemail,
! 	    "Are you sure you want to remail this message (%c/%c)? "),
! 	    *def_ans_yes, *def_ans_no);
  	fflush(stdin);
! 	ch = want_to(buffer, *def_ans_yes, LINES-1, 0);
  	if (ch == *def_ans_no) { /* another day, another No... */
  	  set_error(catgets(elm_msg_cat, ElmSet, ElmBounceCancelled,
  		"Bounce of message canceled."));
  	  (void) unlink(filename);
  	  free(filename);
  	  return(1);
  	}
  
  	if (strcmp(sendmail, mailer) == 0
  #ifdef SITE_HIDING
! 	    && ! is_a_hidden_user(username))
! #else
! 					 )
  #endif
! 	  strcpy(mailerflags, (sendmail_verbose ? smflagsv : smflags));
! 	else if (strcmp(submitmail, mailer) == 0) {
! 	  strcpy(mailerflags, submitflags_s);
! 	  strcpy(expanded, " ");
  	} else if (strcmp(execmail, mailer) == 0) {
! 	  strcpy(mailerflags, (sendmail_verbose ? emflagsv : emflags));
! 	} else
! 	  mailerflags[0] = '\0';
  	
! 	sprintf(buffer,"( %s %s %s < %s ; %s %s) &", 
! 	      mailer, mailerflags, strip_parens(strip_commas(expanded)), 
! 	      filename, remove_cmd, filename);
! 
! 	PutLine0(LINES, 0, catgets(elm_msg_cat, ElmSet, ElmResendingMail,
! 		"Resending mail..."));
! 	(void) system_call(buffer, 0);
! 	set_error(catgets(elm_msg_cat, ElmSet, ElmMailResent, "Mail resent."));
  
      	free(filename);
  
  	return(1);
  }
  #ifdef MMDF
  do_mmdf_addresses(dest_file,buffer)
  FILE *dest_file;
--- 82,300 ----
  	  do_mmdf_addresses(mailfd, strip_parens(strip_commas(expanded)));
  #endif /* MMDF */
  
! 	copy_message(mailfile,headers[current-1],
! 		     "", mailfd, 
! 		     CM_REMOVE_ENVELOPE |
! 		     CM_REMOTE | CM_MMDF_HEAD | CM_REMAIL);
  
  	/** Got the messsage, now let's ensure the person really wants to 
  	    remail it... **/
  
! 	ClearLine(elm_LINES-1);
! 	ClearLine(elm_LINES);
! 	elm_sfprintf(buffer, sizeof buffer,
! 		     CATGETS(elm_msg_cat, ElmSet, ElmSureYouWantToRemail,
! 			     "Are you sure you want to remail this message (%c/%c)? "),
! 		     *def_ans_yes, *def_ans_no);
  	fflush(stdin);
! 	ch = want_to(buffer, *def_ans_yes, elm_LINES-1, 0);
  	if (ch == *def_ans_no) { /* another day, another No... */
  	  set_error(catgets(elm_msg_cat, ElmSet, ElmBounceCancelled,
  		"Bounce of message canceled."));
  	  (void) unlink(filename);
  	  free(filename);
+ 	  fclose(mailfd);
  	  return(1);
  	}
  
+ 	mailerflags[mf_idx++] = mailer;
+ 	
  	if (strcmp(sendmail, mailer) == 0
  #ifdef SITE_HIDING
! 	    && ! is_a_hidden_user(username)
  #endif
! 	    ) {
! 	  mailerflags[mf_idx++] = "-oi";
! 	  mailerflags[mf_idx++] = "-oem";
! 	  if (sendmail_verbose)
! 	    mailerflags[mf_idx++] = "-v";
! 	  if (metoo) 
! 	    mailerflags[mf_idx++] = "-om";
! 	  
! 	} else if (strcmp(submitmail, mailer) == 0) {
! 	  mailerflags[mf_idx++] = "-mlrnv";
  	} else if (strcmp(execmail, mailer) == 0) {
! 	  if (sendmail_verbose)
! 	    mailerflags[mf_idx++] = "-d";
! 	  if (metoo)
! 	    mailerflags[mf_idx++] = "-m";
! 	} 
  	
! #ifdef MIME
! 	{
! 	  struct header_rec *current_header = headers[current-1];
! 	  if (current_header -> status & MIME_MESSAGE) {
! 	    int encoding = current_header->mime_rec.encoding;
! 
! 	    if (encoding == ENCODING_BINARY && 
! 		!(headers[current-1]->binary)) {
! 	      dprint(2,(debugfile,
! 			"Remail: resets encoding=BINARY to encoding=8BIT\n"));
! 	      encoding = ENCODING_8BIT;
! 	    }
! 
! #ifdef USE_8BITMIME
! 	  if (encoding == ENCODING_8BIT)
! 	    mailerflags[mf_idx++] = "-B8BITMIME";
! #endif
! #ifdef USE_BINARYMIME
!           if (encoding == ENCODING_BINARY)
!             /* With -BBINARYMIME lines must terminate with \r\n
!              * Unix's \n is _NOT_ sufficient - K E H              */
! 	    mailerflags[mf_idx++] = "-BBINARYMIME";
! #endif
! 	  }
! 	}
! #endif
! 
! 	mailerflags[mf_idx] = NULL;
! 
! 	if (strcmp(submitmail, mailer) == 0)
! 	  argv = mailerflags;
! 	else {
! 	  char **argvt = argv_from_to(expanded);
! 	  argv = join_argv(mailerflags,argvt);
! 	  free(argvt);
! 	}
! 
! 	{
! 	  struct run_state RS;
! 	  int options = SY_ENV_SHELL;
! 	  int ret;
! 
! 	  if (!sendmail_verbose)
! 	    options |= SY_NOTTY;
! 
! 	  fseek (mailfd, 0, 0);
! #ifdef _POSIX_VERSION
!  	  fflush(mailfd);  /* Synzronize underlying file descriptor */
! #else
!  	  seek(fileno(mailfd),0,0);
! #endif
! 
! 	  ret=start_run(&RS, options, argv, fileno(mailfd),-1);
! 	  if (ret) {
! 	    int exit_code;
! 	    int backgrounded = 0;
! 	    char title[80];
! 
! 	    elm_sfprintf(title, sizeof title,
! 			 CATGETS(elm_msg_cat, ElmSet, ElmRemailTo,
! 				 "Remail to %.50s..."),
! 			 expanded);
! 
! 	    ret = run_already_done(&RS,&exit_code);
! 	    if (0 == ret) {
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmResendingMail,
! 				"Resending mail..."));
! 
! 	      fflush(stdout);
! 
! #ifdef BACKGROUD_PROCESSES       /* We assume POSIX in here */
! 	      if (background_wait_time) {
! 		int tmp;
! 		dprint(4, (debugfile, 
! 			   "Sleeping ( %d seconds ) for completion!\n",
! 			   background_wait_time));
! 		tmp = sleep(background_wait_time);  
! 		/* POSIX sleep returns time in left on
! 		 * interrupt -- when sendmail terminates
! 		 * we will get interrupt (SIGCHLD signal)
! 		 */
! 		if (tmp > 0) {
! 		  dprint(4, (debugfile, 
! 			     " -- sleeping interrupted, %d seconds left!\n",
! 			     tmp));
! 		} else if (tmp < 0) {
! 		  dprint(4, (debugfile, 
! 			     " -- sleeping failed?\n",
! 			     tmp));
! 		}
! 		ret = run_already_done(&RS,&exit_code);
! 		if (0 == ret) 
! 		  ret = maybe_background(&RS,&exit_code,
! 					 mailfd,title,remail_sent);
! 		if (0 == ret) {
! 		  lib_error(
! 			      CATGETS(elm_msg_cat, ElmSet, 
! 				      ElmResendingMailBackground,
! 				      "Resending mail... in background"));
! 		  fflush(stdout);
! 		  backgrounded = 1;
! 		}
!   	      } else
! #endif
! 	      ret = wait_end(&RS,&exit_code);
! 	    }
! 	    if (!backgrounded)
! 	      remail_sent(mailfd,title,&RS,ret,exit_code);	    
! 
! 	  } else {
! 	    if (RS.save_errno)
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFailErrno,
! 				"Failed: %.30s: %.40s"),
! 			argv[0],error_description(RS.save_errno));
! 	    else
! 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCantStart,
! 				"Can't start %.30s"),
! 			argv[0]);
! 	  }
! 	}
! 	if (argv != mailerflags)
! 	  free(argv);
  
+ 	fclose(mailfd);
+ 	unlink(filename);
      	free(filename);
  
  	return(1);
  }
+ 
+ static void remail_sent (fd,title,rs,ret,exit_code)
+      FILE *fd; 
+      char * title;
+      struct run_state *rs;
+      int ret; 
+      int exit_code;
+ {
+   char very_long_buffer[90];
+   lower_prompt(title);
+ 
+   if (ret < 0) 
+     lib_error(CATGETS(elm_msg_cat, ElmSet, 
+ 		      ElmFailSignal,
+ 		      "%.30s fail: Signal?"),
+ 	      mailer);
+   else if (ret > 0) {
+     if (rs->save_errno)
+       lib_error(CATGETS(elm_msg_cat, ElmSet, 
+ 			ElmFailErrno,
+ 			"Failed: %.30s: %.40s"),
+ 		mailer,error_description(rs->save_errno));
+     else if (exit_code) {
+       lib_error(CATGETS(elm_msg_cat, ElmSet, 
+ 			ElmMailerReturnedError,
+ 			"mailer returned error status %d"), 
+ 		exit_code);
+     } else
+       lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMailResent, "Mail resent."));
+   } else {
+     lib_error(CATGETS(elm_msg_cat, ElmSet, 
+ 		      ElmLostErrno,"%.30s lost: %.40s"),
+ 	      mailer,error_description(rs->save_errno));
+   }
+ }
+ 
  #ifdef MMDF
  do_mmdf_addresses(dest_file,buffer)
  FILE *dest_file;
***************
*** 215,225 ****
  	char old[VERY_LONG_STRING], first[VERY_LONG_STRING], 
  		rest[VERY_LONG_STRING];
  
! 	strcpy(old,buffer);
  	split_word(old, first, rest);
  	while (strcmp(first, "") != 0) {
  	  fprintf(dest_file, "%s\n", first);
! 	  strcpy(old, rest);
  	  split_word(old, first, rest);
  	}
  	fprintf(dest_file, "\n");
--- 303,313 ----
  	char old[VERY_LONG_STRING], first[VERY_LONG_STRING], 
  		rest[VERY_LONG_STRING];
  
! 	strfcpy(old,buffer, sizeof old);
  	split_word(old, first, rest);
  	while (strcmp(first, "") != 0) {
  	  fprintf(dest_file, "%s\n", first);
! 	  strfcpy(old, rest, sizeof old);
  	  split_word(old, first, rest);
  	}
  	fprintf(dest_file, "\n");
Index: elm2.4.ME+.50/src/remailer.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/src/remailer.c	Tue Nov 17 21:12:58 1998
***************
*** 0 ****
--- 1,639 ----
+ #include "headers.h"
+ #include "me.h"
+ #include "s_elm.h"
+ 
+ #ifdef USE_REMAILER
+ extern int errno;
+ extern int remailing;
+ 
+ #define REMAILER_SITE "remailer-list@kiwi.cs.berkeley.edu"
+ 
+ #define BOL 1
+ #define STR 2
+ #define INT 3
+ 
+ typedef struct remailer {
+ 	char name[STRING];
+ 	char path[STRING];
+ 	unsigned int pgp : 1;
+ 	unsigned int eric : 1;
+ 	unsigned int cpunk : 1;
+ 	unsigned int penet : 1;
+ 	unsigned int latent : 1;
+ 	unsigned int hash : 1;
+ 	unsigned int special : 1;
+ 	long time;
+ 	struct remailer *next;
+ } remailer_t;
+ 
+ typedef struct remail {
+   int encrypt; /* Use encryption through the servers? */
+   char path[STRING]; /* User-defined route.  Overrides "chain". */
+   int chain; /* How many sites to chain this message through? */
+   remailer_t *info;
+   char address[STRING];
+ } remail_t;
+ 
+ static remail_t remailer;
+ 
+ #include "menu2.h"
+ static struct menu_item remail_items[] = {
+   { "R)email     :", 'r', 3, BOL, (char *) &remailing ,      sizeof remailing},
+   { "C)hain      :", 'c', 5, INT, (char *) &remailer.chain ,  sizeof remailer.chain},
+   { "remail P)ath:", 'p', 6, STR, (char *) remailer.path,
+     sizeof remailer.path },
+   { "E)ncrypt    :", 'e', 8, BOL, (char *) &remailer.encrypt , 
+     sizeof remailer.path}
+ };
+ #define MAX_ITEMS 4
+ 
+ void
+ remailer_menu ()
+ {
+   /* Reset to the defaults... */
+   remailer.encrypt = FALSE;
+   remailer.path[0] = '\0';
+   remailer.chain = 3;
+   remailer.info = NULL;
+ 
+   generic_menu (remail_items, MAX_ITEMS, "Remailer Configuration", "remailer: ");
+ }
+ 
+ static void
+ remailer_print_db (db)
+      remailer_t *db;
+ {
+   dprint(3, (debugfile, "remailer_print_db:\n"));
+   while (db) {
+     dprint(3, (debugfile, "\t%s = %d\n", db->name, db->time));
+     db = db->next;
+   }
+ }
+ 
+ static int
+ remailer_parse_opts (buf, r)
+      char *buf;
+      remailer_t *r;
+ 			       
+ {
+   short i = 0;
+   char *ptr, *ptr2;
+ 
+   ptr = strchr (buf, '"');
+   if (!ptr)
+     return 0;
+ 
+   ptr++;
+   while (*ptr && (*ptr != '"'))
+     r->name[i++] = *ptr++;
+   r->name[i] = '\0';
+ 
+   ptr = strchr (ptr, '<');
+   if (!ptr)
+     return 0;
+ 
+   ptr++;
+   i = 0;
+   while (*ptr && (*ptr != '>'))
+     r->path[i++] = *ptr++;
+   r->path[i] = '\0';
+ 
+   ptr2 = strrchr (ptr, '"');
+   if (!ptr2)
+     return 0;
+ 
+   *ptr2 = '\0';
+   while ((ptr2 = strtok (ptr, " \t\r\n")) != NULL) {
+     if (strcmp (ptr2, "pgp") == 0)
+       r->pgp = 1;
+     else if (strcmp (ptr2, "hash") == 0)
+       r->hash = 1;
+     else if (strcmp (ptr2, "eric") == 0)
+       r->eric = 1;
+     else if (strcmp (ptr2, "penet") == 0)
+       r->penet = 1;
+     else if (strcmp (ptr2, "cpunk") == 0)
+       r->cpunk = 1;
+     else if (strcmp (ptr2, "latent") == 0)
+       r->latent = 1;
+     else if (strcmp (ptr2, "special") == 0)
+       r->special = 1;
+     ptr = 0;
+   }
+   return 1;
+ }
+ 
+ static remailer_t *
+ remailer_lookup (char *name, remailer_t *db)
+ {
+   while (db) {
+     if (strcmp (name, db->name) == 0)
+       return (db);
+     db = db->next;
+   }
+   dprint (3, (debugfile, "remailer_lookup(): %s not found.\n", name));
+   return (0);
+ }
+ 
+ static remailer_t *
+ remailer_sort (remailer_t *p)
+ {
+   /* sorts the remailers in increasing response time. */
+ 
+   remailer_t *tmp;
+   remailer_t *ptr;
+   remailer_t *head;
+   remailer_t *gopher;
+ 
+   if (p == NULL)
+     return (NULL);
+ 
+   /* Pop the first element. */
+   head = gopher = p;
+   ptr = head->next;
+   head->next = 0;
+   
+   /* No go through the rest of the list */
+   while (ptr) {
+     tmp = ptr;
+     ptr = ptr->next;
+     tmp->next = 0;
+     
+     gopher = head;
+     while (gopher) {
+       if (tmp->time <= gopher->time) {
+ 	/* This case should only occur when gopher==head, so we don't have
+ 	 * to worry about this not being the beginning of the list.
+ 	 */
+ 	tmp->next = gopher;
+ 	head = tmp;
+ 	break;
+       }
+       else if (gopher->next && (tmp->time < gopher->next->time)) {
+ 	tmp->next = gopher->next;
+ 	gopher->next = tmp;
+ 	break;
+       }
+       gopher = gopher->next;
+     }
+   }
+   remailer_print_db(head);
+   return (head);
+ }
+ 
+ void
+ remailer_destroy_db ()
+ {
+   remailer_t *p, *db = remailer.info;
+ 
+   while (db) {
+     p = db;
+     db = db->next;
+     free (p);
+   }
+ }
+ 
+ static remailer_t *
+ remailer_get_db ()
+ {
+   /* This routine retrives the list of remailers and their properties.
+    * It first tries to read ~/.elm/remailers, and failing that, it
+    * fingers whatever is defined in REMAILER_SITE for that info.
+    */
+   FILE *fpin;
+   char buf[STRING], *c, buf2[STRING];
+   short i = 0;
+   int hour, min, sec;
+   remailer_t *mailers = 0;
+   remailer_t *end = 0;
+   remailer_t *tmp;
+ 
+   elm_sfprintf (buf, sizeof buf,
+ 		FRM("%s/.elm/remailers"), home);
+   fpin = fopen (buf, "r");
+   if (fpin == NULL) {
+     int fd[2];
+ 
+     if (pipe (fd) == -1) {
+       dprint (1, (debugfile, "remailer_get_db(): ERROR: pipe (errno %d)\n", errno));
+       return (NULL);
+     }
+   
+     if (fork () == 0) {
+       int tmp;
+ 
+       setgid(groupid);
+       setuid(userid);
+ 
+       close (fd[0]);
+       close (1);
+       dup (fd[1]);
+       close (fd[1]);
+       execl(FINGER_PATH,FINGER_PATH,REMAILER_SITE,(char *)0);
+       tmp = errno;
+       perror(FINGER_PATH);
+       _exit(tmp);
+     }
+   
+     close (fd[1]);
+     fpin = fdopen (fd[0], "r");
+     if (fpin == NULL) {
+       dprint (1, (debugfile, "remailer_get_db(): ERROR: fdopen (errno %d)\n", errno));
+       return (NULL);
+     }
+     lib_error (CATGETS(elm_msg_cat, ElmSet, ElmFingering,
+ 		       "Fingering %s..."), 
+ 	       REMAILER_SITE);
+   }
+   else
+     lib_error (CATGETS(elm_msg_cat, ElmSet, ElmRemailerReading,
+ 		       "Reading %s..."), 
+ 	       buf);
+ 
+   while (fgets (buf, STRING, fpin) != NULL) {
+     if (strncmp (buf, "$remailer{", 10) == 0) {
+       tmp = (remailer_t *) safe_malloc (sizeof (remailer_t));
+   
+       tmp->name[0] = '\0';
+       tmp->path[0] = '\0';
+       tmp->pgp     = 0;
+       tmp->eric    = 0;
+       tmp->cpunk   = 0;
+       tmp->penet   = 0;
+       tmp->latent  = 0;
+       tmp->hash    = 0;
+       tmp->special = 0;
+       tmp->time    = 0;
+       tmp->next    = 0;
+ 
+       if (remailer_parse_opts (buf, tmp)) {
+ 	if (mailers == 0)
+ 	  mailers = end = tmp;
+ 	else {
+ 	  end->next = tmp;
+ 	  end = end->next;
+ 	}
+ 	tmp->next = 0;
+       } else {
+ 	free((void *)tmp);
+       }
+     }
+     else if (strncmp (buf, "-----", 5) == 0)
+       break;
+   }
+ 
+   /* Phase 2 : retrieve the rankings (latency). */
+   while (fgets (buf, STRING, fpin) != NULL) {
+     c = buf;
+     i = 0;
+     while (*c && !isspace (*c))
+       buf2[i++] = *c++;
+     buf2[i] = '\0';
+     tmp = remailer_lookup (buf2, mailers);
+     if (tmp != NULL) {
+       c = strchr (buf, ':');
+       while (!isspace(*c))
+ 	c--;
+       c++;
+       i = sscanf (c, "%d:%d:%d", &hour, &min, &sec);
+       if (i == 3)
+ 	tmp->time = (hour * 3600) + min * 60 + sec;
+       else if (i == 2)
+ 	tmp->time = hour * 60 + min;
+       else {
+ 	dprint (1, (debugfile, "remailer_get_db(): error parsing time: %s\n", c));
+ 	lib_error (CATGETS(elm_msg_cat, ElmSet, ElmRemailerCoulntTime,
+ 			   "Could not convert time for remailer %s!"), 
+ 			   tmp->name);
+ 	if (sleepmsg > 0)
+ 	  sleep(sleepmsg);
+       }
+     }
+   }
+   fclose(fpin);
+   remailer_print_db (mailers);
+   return (remailer_sort (mailers));
+ }
+ 
+ static int
+ #ifdef MIME
+ remailer_write_msg (pdb, to, subj, src, tmpfn, pgp, mime_info)
+      mime_send_t *mime_info;
+ #else
+ remailer_write_msg (pdb, to, subj, src, tmpfn, pgp)
+ #endif
+      remailer_t *pdb;
+      char *to, *subj, *src, *tmpfn;
+ {
+   FILE *fpin, *fpout;
+   char buf[VERY_LONG_STRING];
+ 
+   if (pdb == NULL) {
+     dprint (1, (debugfile, "remailer_write_msg(): ERROR!  pdb==NULL\n"));
+     lib_error (CATGETS(elm_msg_cat, ElmSet, ElmRemailerCouldntList,
+ 		       "Could not retrieve list of remailers!"));
+     if (sleepmsg > 0)
+       sleep(sleepmsg);
+     return(-1);
+   }
+ 
+   fpin = fopen (src, "r");
+   if (!fpin) {
+     dprint(1,(debugfile,"remailer_write_msg: %s: could not open for reading!\n",src));
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmRemailerErrorTemp,
+ 		      "Error opening temp file!"));
+     if (sleepmsg > 0)
+       sleep(sleepmsg);
+     return(-1);
+   }
+     
+   fpout = safeopen (tmpfn);
+   if (!fpout) {
+     dprint(1,(debugfile,"remailer_write_msg: %s: could not open for writing!\n",tmpfn));
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmRemailerErrorTemp,
+ 		      "Error opening temp file!"));
+     if (sleepmsg > 0)
+       sleep(sleepmsg);
+     return(-1);
+   }
+ 
+   fputs ("::\n", fpout);
+   if (pdb->cpunk)
+     fputs ("Request-Remailing-To: ", fpout);
+   else if (pdb->eric)
+     fputs ("Anon-Send-To: ", fpout);
+   else if (pdb->penet)
+     fputs ("X-Anon-To: ", fpout);
+   fprintf (fpout, "%s\n\n", to);
+   /* Some remailers require the subject line to be in the "hash" area, so
+    * use it if it's availible.
+    */
+   if (pdb->hash) {
+     fprintf (fpout, "##\nSubject: %s\n", subj);
+ #ifdef MIME
+     if (mime_info) {
+       /* If this is a MIME message, write out a header in the "hash" area
+        * so that the information will be preserved when the remailer
+        * rewrites the message.
+        */
+       mime_write_header(fpout, mime_info, 1);
+       print_EOLN(fpout, mime_info->encoding_top);
+     }
+     else
+ #endif
+       fputc('\n', fpout);
+   }  
+   while (fgets (buf, VERY_LONG_STRING, fpin) != NULL)
+     fputs (buf, fpout);
+   fclose (fpin);
+   fclose (fpout);
+ #ifdef USE_PGP
+   if (pgp && pdb->pgp) {
+     pgp_encrypt (tmpfn, pdb->path, username, PGP_MESSAGE, FALSE);
+     fpin = fopen (tmpfn, "r");
+     fpout = fopen (src, "w");
+     fputs ("::\nEncrypted: PGP\n\n", fpout);
+     while (fgets (buf, VERY_LONG_STRING, fpin) != NULL)
+       fputs (buf, fpout);
+     fclose (fpin);
+     fclose (fpout);
+     unlink (tmpfn);
+   }
+   else
+ #endif
+   {
+ #ifdef RENAME
+     if (rename (tmpfn, src) < 0) {
+       lib_error (CATGETS(elm_msg_cat, ElmSet, ElmRemailerErrorTempRename,
+ 			 "Could not rename temp file!"));
+       dprint (1, (debugfile, "remailer_write_msg: ERROR!  rename(%s,%s); errno=%d\n", src, tmpfn, errno));
+       return(-1);
+     }
+ #else
+     link (tmpfn, src);
+     unlink (tmpfn);
+ #endif
+   }
+   dprint (2, (debugfile, "remailer_write_msg: routing through %s.\n", 
+ 	      pdb->path));
+   return 0;
+ }
+ 
+ int remailer_proc ()
+ {
+   remailer_t *pdb;
+   int chain = remailer.chain;
+   char *c;
+ 
+   /* See if there is anything to do... */
+   if (chain > 0 || (remailer.path[0] != '\0')) {
+     extern char expanded_to[VERY_LONG_STRING];
+       
+     /* Save this information for later use... */
+     pdb = remailer.info = remailer_get_db ();
+ 
+     if (remailer.path[0] != '\0') {
+       /* The user has specified a path to use. */
+       c = remailer.path;
+       while ((c = strtok (c, ";")) != NULL) {
+ 	while (*c && isspace (*c))
+ 	  c++;
+ 	pdb = remailer_lookup (c, remailer.info);
+ 	if (! pdb)
+ 	  return(-1);
+ 	c = NULL;
+       }
+     }
+     else {
+       remailer_t *savedb = 0;
+ 
+       while (chain > 0) {
+ 	if (remailer.encrypt) {
+ 	  /* Find the next remailer which supports pgp. */
+ 	  while (pdb && ((! pdb->pgp) || (pdb->time == 0)))
+ 	    pdb = pdb->next;
+ 	  if (! pdb)
+ 	    return (-1);
+ 	}
+ 	else {
+ 	  /* Some servers will only accept PGP encoded messages, so if PGP was
+ 	   * not requested, skip all servers marked "special".  Also, we want
+ 	   * to skip any servers with a time of zero, since that means there 
+ 	   * wasn't any information availible.
+ 	   */
+ 	  while (pdb && (pdb->special || (pdb->time == 0)))
+ 	    pdb = pdb->next;
+ 	  if (! pdb)
+ 	    return (-1);
+ 	}
+ 	savedb = pdb;
+ 	pdb = pdb->next;
+ 	chain--;
+       }
+       pdb = savedb;
+     }
+ 
+     /* "pdb" should now be set to the last entry.  We should set Elm's
+      * concept of the "To:" address to this remailer.
+      */
+     strfcpy (remailer.address, expanded_to, sizeof remailer.address);
+     strfcpy (expanded_to, pdb->path, sizeof expanded_to);
+   }
+   return(0);
+ }
+ 
+ static int
+ #ifdef MIME
+ remailer_genmsg (filename, to, subj, chain, pgp, mime_info)
+      mime_send_t *mime_info;
+ #else
+ remailer_genmsg (filename, to, subj, chain, pgp)
+ #endif
+      char *to, *subj, *filename;
+      int chain, pgp;
+ {
+   char tmpfn[STRING], *c;
+   char remailto[STRING];
+   remailer_t *db, *pdb;
+ 
+   /* Set the initial address */
+   strfcpy(remailto, to, sizeof remailto);
+ 
+   if (chain < 1 && (remailer.path[0] == '\0'))
+     return (-1); /* nothing to do */
+ 
+   pdb = db = remailer.info;
+   if (db == NULL) {
+     dprint(1, (debugfile, "remailer_genmsg: no database found!\n"));
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmRemailerDatabase,
+ 		      "Could not find remailer database!"));
+     if (sleepmsg>0)
+       sleep(sleepmsg);
+     return(-1);
+   }
+ 
+   elm_sfprintf (tmpfn, sizeof tmpfn,
+ 		FRM("%selmRT%d"), temp_dir, getpid());
+ 
+   if (remailer.path[0] != '\0') {
+     /* The user has specified a path to use. */
+     c = remailer.path;
+     while ((c = strtok (c, ";")) != NULL) {
+       while (*c && isspace (*c))
+ 	c++;
+       pdb = remailer_lookup (c, db);
+       if (! pdb) {
+ 	dprint(1,(debugfile, "remailer_genmsg: could not find remailer '%s'\n",
+ 		  c));
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmRemailerFind,
+ 			  "Could not find remailer '%s'."), 
+ 		  c);
+ 	if (sleepmsg > 0)
+ 	  sleep(sleepmsg);
+         return (-1);
+       }
+ #ifdef MIME
+       remailer_write_msg (pdb, remailto, subj, filename, tmpfn, pgp, mime_info);
+ #else
+       remailer_write_msg (pdb, remailto, subj, filename, tmpfn, pgp);
+ #endif
+       strfcpy(remailto, pdb->path, sizeof remailto);
+       c = NULL;
+     }
+   }
+   else
+     while (chain > 0) {
+       if (pgp) {
+ 	/* Find the next remailer which supports pgp. */
+ 	while (pdb && ((! pdb->pgp) || (pdb->time == 0)))
+ 	  pdb = pdb->next;
+ 	if (! pdb)
+ 	  return (-1);
+       }
+       else {
+ 	/* Some servers will only accept PGP encoded messages, so if PGP was
+ 	 * not requested, skip all servers marked "special".  Also, we want
+ 	 * to skip any servers with a time of zero, since that means there 
+ 	 * wasn't any information availible.
+ 	 */
+ 	while (pdb && (pdb->special || (pdb->time == 0)))
+ 	  pdb = pdb->next;
+         if (! pdb)
+           return (-1);
+       }
+ #ifdef MIME
+       remailer_write_msg (pdb, remailto, subj, filename, tmpfn, pgp, mime_info);
+ #else
+       remailer_write_msg (pdb, remailto, subj, filename, tmpfn, pgp);
+ #endif
+       strfcpy(remailto, pdb->path, sizeof remailto);
+       pdb = pdb->next;
+       chain--;
+     }
+   return (0);
+ }
+ 
+ #ifdef MIME
+ remailer_copy_message_across (reply, real_reply, copy, mime_info)
+      mime_send_t *mime_info;
+ #else
+ remailer_copy_message_across (reply, real_reply, copy)
+ #endif
+      FILE *reply, *real_reply;
+      int copy;
+ {
+   FILE *tmpfp;
+   char tempfile[STRING], buf[VERY_LONG_STRING];
+   extern char subject[];
+   int ret;
+ 
+   elm_sfprintf(tempfile, sizeof tempfile,
+ 	       FRM("%selmR%d"), temp_dir, getpid());
+ 
+   tmpfp = safeopen(tempfile);
+   if (!tmpfp) {
+     dprint(1, (debugfile, "remailer_copy_message_across: %s: could not open for writing!\n", tempfile));
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmRemailerTempWriting,
+ 		      "Could not open temp file for writing!"));
+     if (sleepmsg > 0)
+       sleep(sleepmsg);
+     return(-1);
+   }
+ 
+ #ifdef MIME
+   copy_message_across(reply, tmpfp, copy, mime_info);
+ #else
+   copy_message_across(reply, tmpfp, copy);
+ #endif
+   fclose(tmpfp);
+ #ifdef MIME
+   ret = remailer_genmsg (tempfile, remailer.address, subject, remailer.chain,
+ 			 remailer.encrypt, mime_info);
+ #else
+   ret = remailer_genmsg (tempfile, remailer.address, subject, remailer.chain,
+ 			 remailer.encrypt);
+ #endif
+   if (ret == -1) {
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmRemailerFormating,
+ 		      "Error while formatting for remailer!"));
+     if (sleepmsg > 0)
+       sleep(sleepmsg);
+     unlink(tempfile);
+     return(-1);
+   }
+   tmpfp = fopen(tempfile, "r");
+   if (!tmpfp) {
+     dprint(1, (debugfile, "remailer_copy_message_across: %s: could not open for reading!\n", tempfile));
+     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmRemailerTempRead,
+ 		      "Could not read temp file!"));
+     if (sleepmsg>0)
+       sleep(sleepmsg);
+     unlink(tempfile);
+     return(-1);
+   }
+   while (mail_gets(buf, sizeof(buf), tmpfp) > 0)
+     fputs(buf, real_reply);
+   unlink(tempfile);
+   return 0;
+ }
+ #endif
Index: elm2.4.ME+.50/src/reply.c
*** elm2.4.25/src/reply.c	Tue Aug  3 22:29:18 1993
--- elm2.4.ME+.50/src/reply.c	Tue Nov 17 21:12:57 1998
***************
*** 1,113 ****
  
! static char rcsid[] = "@(#)$Id: reply.c,v 5.15 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.15 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: reply.c,v $
!  * Revision 5.15  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.14  1993/07/20  02:05:17  syd
!  * A long-standing bug of handling replies to VMS systems.
!  * Original "From: " -line is of format:
!  * 	From: "NAME \"Real Name\"" <USERNAME@vms-system>
!  * (PMDF mailer)
!  * 	Anyway,  parse_arpa_who()  strips quotes too cleanly
!  * resulting data:
!  * 	NAME \"Real Name\
!  * which, when put into parenthesis, becomes:
!  * 	(NAME \"Real Name\)
!  * which in its turn lacks closing `)'
!  * Patch of  lib/parsarpwho.c  fixes that.
!  * strtokq() started one position too late to search for next double-quote (") char.
!  * Another one-off (chops off trailing comment character, quote or not..)  in   src/reply.c
!  * From:	Matti Aarnio <mea@utu.fi>
!  *
!  * Revision 5.13  1993/06/10  03:02:46  syd
!  * break_down_tolist() tried to blindly split address lists at "," which
!  * caused bogus results with addreses that had a comma inside a comment
!  * or quoted text, such as "user@domain (Last, First)".  This patch steps
!  * through the address in quanta of RFC-822 tokens when searching for a
!  * delimiting comma.  It also adds "rfc822_toklen()" to the library to
!  * get that length.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.12  1993/04/12  03:02:05  syd
!  * If a To: or Cc: line is split in a comment, that is between ( and ),
!  * get_and_expand_everyone won't parse that correctly.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.11  1993/04/12  02:34:36  syd
!  * I have now added a parameter which controls whether want_to clears the
!  * line and centers the question or behaves like it did before. I also
!  * added a 0 at the end of the parameter list to all the other calls to
!  * want_to where a centered question on a clean line is not desirable.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.10  1993/02/06  16:46:06  syd
!  * remove outdate include of utsname, no longer needed in reply.c
!  * From: Syd
!  *
!  * Revision 5.9  1993/02/03  19:06:31  syd
!  * Remove extra strchr/strcat/strcpy et al declarations
!  * From: Syd
!  *
!  * Revision 5.8  1993/02/03  16:25:45  syd
!  * Adresses with double quoted strings that contains comma was parsed
!  * wrongly by break_down_tolist() and figure_out_addressee().
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.7  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.6  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.5  1992/11/26  00:46:50  syd
!  * Fix how errno is used so err is inited and used instead
!  * as errno gets overwritten by print system call
!  * From: Syd
!  *
!  * Revision 5.4  1992/11/07  20:05:52  syd
!  * change to use header_cmp to allow for linear white space around the colon
!  * From: Syd
!  *
!  * Revision 5.3  1992/10/24  13:35:39  syd
!  * changes found by using codecenter on Elm 2.4.3
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.2  1992/10/11  01:25:58  syd
!  * Add undefs of tolower so BSD macro isnt used from ctype.h
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /*** routine allows replying to the sender of the current message 
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: reply.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /*** routine allows replying to the sender of the current message 
  
***************
*** 114,119 ****
--- 17,23 ----
  ***/
  
  #include "headers.h"
+ #include "me.h"
  #include "s_elm.h"
  #include <errno.h>
  
***************
*** 128,143 ****
  
  char *error_description();
  
  
  /* Determine the subject to use for a reply.  */
! void
! get_reply_subj(out_subj,in_subj,dflt_subj)
! char *out_subj;		/* store the resulting subject here		*/
! char *in_subj;		/* subject of the original message		*/
! char *dflt_subj;	/* default to use if "in_subj" is empty		*/
  {
  	if ( *in_subj == '\0' ) {
! 	  strcpy(out_subj,dflt_subj);
  	  return;
  	}
  	if (
--- 32,49 ----
  
  char *error_description();
  
+ /* Prototype */
+ static void get_reply_subj P_((char *, char *, char *, int));
  
  /* Determine the subject to use for a reply.  */
! static void get_reply_subj(out_subj,in_subj,dflt_subj, size)
!      char *out_subj;	 /* store the resulting subject here		*/
!      char *in_subj;	/* subject of the original message		*/
!      char *dflt_subj;	/* default to use if "in_subj" is empty		*/
!      int size;
  {
  	if ( *in_subj == '\0' ) {
! 	  strfcpy(out_subj,dflt_subj, size);
  	  return;
  	}
  	if (
***************
*** 147,323 ****
  	) {
  	  for ( in_subj += 3 ; whitespace(*in_subj) ; ++in_subj ) ;
  	}
! 	strcat( strcpy( out_subj, "Re: " ), in_subj);
  }
  
! int
! optimize_and_add(new_address, full_address)
! char *new_address, *full_address;
  {
! 	/** This routine will add the new address to the list of addresses
! 	    in the full address buffer IFF it doesn't already occur.  It
! 	    will also try to fix dumb hops if possible, specifically hops
! 	    of the form ...a!b...!a... and hops of the form a@b@b etc 
! 	**/
! 
! 	register int len, host_count = 0, i;
! 	char     hosts[MAX_HOPS][SLEN];	/* array of machine names */
! 	char     *host, *addrptr;
! 
! 	if (in_list(full_address, new_address))
! 	  return(1);	/* duplicate address */
! 
! 	/** optimize **/
! 	/*  break down into a list of machine names, checking as we go along */
! 	
! 	addrptr = (char *) new_address;
! 
! 	while ((host = get_token(addrptr, "!", 1)) != NULL) {
! 	  for (i = 0; i < host_count && ! equal(hosts[i], host); i++)
! 	      ;
! 
! 	  if (i == host_count) {
! 	    strcpy(hosts[host_count++], host);
! 	    if (host_count == MAX_HOPS) {
! 	       dprint(2, (debugfile,
!               "Error: hit max_hops limit trying to build return address (%s)\n",
! 		      "optimize_and_add"));
! 	       error(catgets(elm_msg_cat, ElmSet, ElmBuildRAHitMaxHops,
! 		"Can't build return address. Hit MAX_HOPS limit!"));
! 	       return(1);
! 	    }
! 	  }
! 	  else 
! 	    host_count = i + 1;
! 	  addrptr = NULL;
! 	}
! 
! 	/** fix the ARPA addresses, if needed **/
! 	
! 	if (qchloc(hosts[host_count-1], '@') > -1)
! 	  fix_arpa_address(hosts[host_count-1]);
! 	  
! 	/** rebuild the address.. **/
! 
! 	new_address[0] = '\0';
! 
! 	for (i = 0; i < host_count; i++)
! 	  sprintf(new_address, "%s%s%s", new_address, 
! 	          new_address[0] == '\0'? "" : "!",
! 	          hosts[i]);
! 
! 	if (full_address[0] == '\0')
! 	  strcpy(full_address, new_address);
! 	else {
! 	  len = strlen(full_address);
! 	  full_address[len  ] = ',';
! 	  full_address[len+1] = ' ';
! 	  full_address[len+2] = '\0';
! 	  strcat(full_address, new_address);
! 	}
! 
! 	return(0);
  }
  
! void
! get_and_expand_everyone(return_address, full_address)
! char *return_address, *full_address;
! {
! 	/** Read the current message, extracting addresses from the 'To:'
! 	    and 'Cc:' lines.   As each address is taken, ensure that it
! 	    isn't to the author of the message NOR to us.  If neither,
! 	    prepend with current return address and append to the 
! 	    'full_address' string.
! 	**/
  
!     char ret_address[SLEN], buf[VERY_LONG_STRING], new_address[SLEN],
! 	 address[SLEN], comment[SLEN], next_line[SLEN];
!     int  lines, iindex, line_pending = 0, line_len, err;
  
      /** First off, get to the first line of the message desired **/
  
!     if (fseek(mailfile, headers[current-1]->offset, 0) == -1) {
! 	err = errno;
! 	dprint(1,(debugfile,"Error: seek %ld resulted in errno %s (%s)\n", 
! 		 headers[current-1]->offset, error_description(err), 
! 		 "get_and_expand_everyone"));
! 	error2(catgets(elm_msg_cat, ElmSet, ElmSeekFailedFile,
! 		"ELM [seek] couldn't read %d bytes into file (%s)."),
! 		headers[current-1]->offset, error_description(err));
! 	return;
      }
-  
-     /** okay!  Now we're there!  **/
- 
-     /** let's fix the ret_address to reflect the return address of this
- 	message with '%s' instead of the persons login name... **/
  
-     translate_return(return_address, ret_address);
  
      /** now let's parse the actual message! **/
  
!     for (lines = headers[current-1]->lines;;) {
! 
!       /* read in another line if required - break out if end of mbox reached */
!       if ( !line_pending && (line_len = mail_gets(buf, SLEN, mailfile)) == 0 )
! 	  return;
!       line_pending = 0;
  
!       /* break out at end of header or start of next message */
!       if ( line_len < 2 )
! 	return;
!       if (buf[line_len - 1] == '\n')
! 	lines--;
!       if (lines <= 0)
! 	return;
! 
!       /* we only want lines with addresses */
!       if (!header_cmp(buf, "To", NULL) && !header_cmp(buf, "cc", NULL))
! 	continue;
! 
!       /* extract the addresses from this line and possible continuation lines */
!       next_line[0] = '\0';
! 
!       /* read in another line - continuation lines start with whitespace */
!       while ( (line_len = mail_gets(next_line, SLEN, mailfile)) != 0 &&
! 	      whitespace(next_line[0]) ) {
! 	no_ret(buf);
! 	strcat(buf, next_line); /* Append continuation line */
! 
! 	if (next_line[line_len - 1] == '\n')
! 	  lines--;
! 	next_line[0] = '\0';
!       }
  
!       no_ret(buf);
!       iindex = chloc(buf, ':')+1;		/* point beyond header name */
        dprint(2,(debugfile,"> %s\n",buf));
  
        /* go through all addresses in this line */
!       while (break_down_tolist(buf, &iindex, address, comment)) {
! 	if (okay_address(address, return_address)) {
! 
! 	  /**
! 	      Some mailers can emit unqualified addresses in the
! 	      headers, e.g. a Cc to a local user might appear as
! 	      just "user" and not "user@dom.ain".  We do a real
! 	      low-rent check here.  If it looks like a domain
! 	      address then we will pass it through.  Otherwise we
! 	      send it back through the originating host for routing.
! 	  **/
! 	  if (qchloc(address, '@') >= 0)
! 	    strcpy(new_address, address);
! 	  else
! 	    sprintf(new_address, ret_address, address);
! 	  optimize_and_add(new_address, full_address);
  
! 	}
        }
!       if (next_line[0] != '\0') {
! 	strcpy(buf, next_line);
! 	line_pending++;
        }
      }
  }
  
  int
--- 53,220 ----
  	) {
  	  for ( in_subj += 3 ; whitespace(*in_subj) ; ++in_subj ) ;
  	}
! 	strfcat( strfcpy( out_subj, "Re: ", size ), in_subj, size);
  }
  
! static int
! optimize_and_add P_((const char *new_address, char *full_address,
! 		     int size));
! 
! static int optimize_and_add(new_address, full_address, size)
!      const char *new_address;
!      char *full_address;
!      int size;
  {
!   int len;
!   /** This routine will add the new address to the list of addresses
!     in the full address buffer IFF it doesn't already occur.  
!     **/
! 
!   if (in_list(full_address, new_address))
!     return(1);	/* duplicate address */
!   
!   if (full_address[0] == '\0')
!     strfcpy(full_address, new_address, size);
!   else {
!     len = strlen(full_address);
!     if (len + strlen(new_address) > size-5)
!       return 1;   /* Buffer overflow */
!     full_address[len  ] = ',';
!     full_address[len+1] = ' ';
!     full_address[len+2] = '\0';
!     strfcat(full_address, new_address, size);
!   }
!   
!   return(0);
  }
  
! /* Kari E. Hurtta <Kari.Hurtta@Fmi.FI> */
  
! static void handle_reply_to P_((
! 				char *return_address, char *to_address,
! 				int size, int return_address_size));
! 
! static void handle_reply_to(return_address, to_address, 
! 			    size, return_address_size)
!      char *return_address, *to_address;
!      int size, return_address_size;
! {
!     char buf[VERY_LONG_STRING];
!     int  iindex, line_len, err;
!     int count=0;
  
      /** First off, get to the first line of the message desired **/
  
!     if (skip_envelope(headers[current-1], mailfile) == -1) {
!         err = errno;
!         dprint(1,(debugfile,"Error: seek %ld resulted in errno %s (%s)\n",
!                  headers[current-1]->offset, error_description(err),
!                  "handle_reply_to"));
!         lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSeekFailedFile,
! 			  "ELM [seek] couldn't read %d bytes into file (%s)."),
! 		  headers[current-1]->offset, error_description(err));
!         return;
      }
  
  
      /** now let's parse the actual message! **/
  
!     /* read_header_line reads also continuation lines ... 
!      * 2 == check that this is header line...
!      */
!     while (0 < (line_len = read_header_line(mailfile,buf,sizeof(buf),
! 					    RHL_CHECK_HEADER))) {
!       struct addr_item * addrs,*ptr;
!       /* we only want lines with reply-to addresses */
!       if (!header_cmp(buf, "Reply-To", NULL)) 
!         continue;
  
!       /* extract the addresses from header */
  
!       iindex = chloc(buf, ':')+1;               /* point beyond header name */
        dprint(2,(debugfile,"> %s\n",buf));
  
+       addrs = break_down_address(buf+iindex,decode_who_none);
        /* go through all addresses in this line */
!       for (ptr = addrs; ptr && ptr -> addr && ptr->fullname; ptr++) {
! 	/* can't use okay_address here ! */
  
! 	/* do NOT add sendder's domain in here ! It was MTA's task
!            and if it is not added then there is good reason.
! 	   (adding of senders domain to unqualified addresses
! 	    BREAKS my local mailing lists!!!)
! 	   That is: It is possible that Reply-to is written by some
! 		    other site than From !!!
! 	   - Kari E. Hurtta <Kari.Hurtta@Fmi.Fi>
!          */
!           if (!optimize_and_add(ptr->addr, to_address, size))
! 		count++;
! 	  /* TODO: Also full name should be added, but I suspect
! 	           that in_list on optimize_and_add does not handle
! 		   comments well...
! 	   */
        }
!       if (addrs)
! 	free_addr_items(addrs);
!     }
! 
!     /* if there wasn't reply-to header */
!     if (!count)
! 	optimize_and_add(return_address, to_address, size);
! }
!  
! 
! void
! get_and_expand_everyone(return_address, full_address, size)
!      char *return_address, *full_address;
!      int size;
! {
!   /** As each address is taken, ensure that it
!     isn't to the author of the message NOR to us.  If neither,
!     prepend with current return address and append to the 
!     'full_address' string.
!     **/
!   
!   char ret_address[SLEN]; 
!   enum { h_to = 0, h_cc = 1, h_done = 2 } count;
! 
!   translate_return(return_address, ret_address);
!   
!   for (count = h_to ; count < h_done; count++) {
!     struct addr_item * addrs = NULL, *ptr;
!     
!     switch (count) {
!     case h_to: addrs = headers[current-1]->to; break;
!     case h_cc: addrs = headers[current-1]->cc; break;
!     }
!     
!     /* go through all addresses in this line */
!     for (ptr = addrs; ptr && ptr -> addr && ptr->fullname; ptr++) {
!       if (okay_address(ptr->addr, return_address)) {
! 	char new_address[SLEN];
! 	
! 	/**
! 	  Some mailers can emit unqualified addresses in the
! 	  headers, e.g. a Cc to a local user might appear as
! 	  just "user" and not "user@dom.ain".  We do a real
! 	  low-rent check here.  If it looks like a domain
! 	  address then we will pass it through.  Otherwise we
! 	  send it back through the originating host for routing.
! 	  **/
! 	if (qchloc(ptr->addr, '@') >= 0)
! 	  strfcpy(new_address, ptr->addr, sizeof new_address);
! 	else
! 	  elm_sfprintf(new_address, sizeof new_address,
! 		       FRM(ret_address), ptr->addr);
! 	optimize_and_add(new_address, full_address, size);
! 	  
! 	/* TODO: Also full name should be added, but I suspect
! 	   that in_list on optimize_and_add does not handle
! 	   comments well...
! 	   */
        }
      }
+   }
  }
  
  int
***************
*** 327,348 ****
  	    the screen has to be rewritten. **/
  
  	char return_address[SLEN], subject[SLEN];
  	int  return_value, form_letter;
  
  	form_letter = (headers[current-1]->status & FORM_LETTER);
  
! 	if (get_return(return_address, current-1)) {
! 	  strcpy(subject, headers[current-1]->subject);
  	} else {
  	  get_reply_subj( subject, headers[current-1]->subject,
! 		  ( form_letter ?
! 		  catgets(elm_msg_cat, ElmSet, ElmFilledInForm, "Filled in form") :
! 		  catgets(elm_msg_cat, ElmSet, ElmReYourMail, "Re: your mail") ) );
! 	}
  	if (form_letter)
! 	  return_value = mail_filled_in_form(return_address, subject);
! 	else
! 	  return_value = send_msg(return_address, "", subject, TRUE, NO, TRUE);
  	return(return_value);
  }
  
--- 224,259 ----
  	    the screen has to be rewritten. **/
  
  	char return_address[SLEN], subject[SLEN];
+ 	char to_line[VERY_LONG_STRING];
  	int  return_value, form_letter;
  
  	form_letter = (headers[current-1]->status & FORM_LETTER);
  
! 	if (get_return(return_address, current-1, sizeof return_address)) {
! 	  strfcpy(subject, headers[current-1]->subject, sizeof subject);
  	} else {
  	  get_reply_subj( subject, headers[current-1]->subject,
! 			  ( form_letter ?
! 			    catgets(elm_msg_cat, ElmSet, ElmFilledInForm, 
! 				    "Filled in form") :
! 			    catgets(elm_msg_cat, ElmSet, ElmReYourMail, 
! 				    "Re: your mail") ),
! 			  sizeof subject);
! 	}
! 	to_line[0] = '\0';
! 	handle_reply_to(return_address,to_line, sizeof (to_line),
! 			sizeof return_address);
  	if (form_letter)
! 	  return_value = mail_filled_in_form(to_line, subject);
! 	else {
! 	  return_value = send_msg(to_line, "", subject,
! 				  MAIL_EDIT_MSG | MAIL_REPLYING,
! 				  NO);
!           if (me_retcode) {
!             headers[current-1]->status |= REPLIED;
!             headers[current-1]->status_chgd = TRUE;
!           }
!         }
  	return(return_value);
  }
  
***************
*** 356,376 ****
  
  	char return_address[SLEN], subject[SLEN];
  	char full_address[VERY_LONG_STRING];
  	int  return_value;
  
! 	get_return(return_address, current-1);
  
  	full_address[0] = '\0';			/* no copies yet    */
! 	get_and_expand_everyone(return_address, full_address);
  	dprint(2,(debugfile,
  		"reply_to_everyone() - return_addr=\"%s\" full_addr=\"%s\"\n",
  		return_address,full_address));
  
  	get_reply_subj( subject, headers[current-1]->subject,
! 		  catgets(elm_msg_cat, ElmSet, ElmReYourMail, "Re: your mail"));
! 
!         return_value = send_msg(return_address, full_address, subject, 
! 		TRUE, NO, TRUE);
  	return(return_value);
  
  }
--- 267,299 ----
  
  	char return_address[SLEN], subject[SLEN];
  	char full_address[VERY_LONG_STRING];
+ 	char to_line[VERY_LONG_STRING];
  	int  return_value;
  
! 	get_return(return_address, current-1, sizeof return_address);
!         to_line[0] = '\0';
!         handle_reply_to(return_address,to_line, sizeof(to_line),
! 			sizeof return_address);
  
  	full_address[0] = '\0';			/* no copies yet    */
! 	get_and_expand_everyone(return_address, full_address, 
! 				sizeof (full_address));
  	dprint(2,(debugfile,
  		"reply_to_everyone() - return_addr=\"%s\" full_addr=\"%s\"\n",
  		return_address,full_address));
  
  	get_reply_subj( subject, headers[current-1]->subject,
! 			catgets(elm_msg_cat, ElmSet, ElmReYourMail, 
! 				"Re: your mail"),
! 			sizeof subject);
! 
!         return_value = send_msg(to_line, full_address, subject,
! 				MAIL_EDIT_MSG | MAIL_REPLYING,
! 				NO);
!         if (me_retcode) {
!           headers[current-1]->status |= REPLIED;
!           headers[current-1]->status_chgd = TRUE;
!         }
  	return(return_value);
  
  }
***************
*** 390,438 ****
  	char subject[SLEN], address[VERY_LONG_STRING];
  	int  results, edit_msg = FALSE;
  
- 	forwarding = TRUE;
- 
  	address[0] = '\0';
  
  	if (headers[current-1]->status & FORM_LETTER)
! 	  PutLine0(LINES-3,COLUMNS-40, catgets(elm_msg_cat, ElmSet, ElmNoEditingAllowed,
! 		"<No editing allowed.>"));
  	else {
! 	  MCsprintf(subject, catgets(elm_msg_cat, ElmSet, ElmEditOutgoingMessage,
! 		  "Edit outgoing message? (%c/%c) "), *def_ans_yes, *def_ans_no);
  	  edit_msg = (want_to(subject,
! 			      *def_ans_yes, LINES-3, 0) != *def_ans_no);
  	}
  
  	if (strlen(headers[current-1]->subject) > 0) {
  
! 	  strcpy(subject, headers[current-1]->subject); 
  
  	  /* this next strange compare is to see if the last few chars are
  	     already '(fwd)' before we tack another on */
  
! 	  if (strlen(subject) < 6 || (strcmp((char *) subject+strlen(subject)-5,
  					     "(fwd)") != 0))
! 	    strcat(subject, " (fwd)");
  
! 	  results = send_msg(address, "", subject, edit_msg,
! 	    headers[current-1]->status & FORM_LETTER? 
! 	    PREFORMATTED : allow_forms, FALSE);
  	}
  	else
  	  results = send_msg(address, "",
! 		catgets(elm_msg_cat, ElmSet, ElmForwardedMail, "Forwarded mail..."), edit_msg,
! 		headers[current-1]->status & FORM_LETTER ? PREFORMATTED : allow_forms, FALSE);
! 	
! 	forwarding = FALSE;
! 
  	return(results);
  }
  
! int
! get_return_name(address, name, trans_to_lowercase)
! char *address, *name;
! int   trans_to_lowercase;
  {
  	/** Given the address (either a single address or a combined list 
  	    of addresses) extract the login name of the first person on
--- 313,364 ----
  	char subject[SLEN], address[VERY_LONG_STRING];
  	int  results, edit_msg = FALSE;
  
  	address[0] = '\0';
  
  	if (headers[current-1]->status & FORM_LETTER)
! 	  PutLineX(elm_LINES-3,elm_COLUMNS-40, 
! 		   CATGETS(elm_msg_cat, ElmSet, 
! 			   ElmNoEditingAllowed,
! 			   "<No editing allowed.>"));
  	else {
! 	  elm_sfprintf(subject, sizeof subject,
! 		       CATGETS(elm_msg_cat, ElmSet, ElmEditOutgoingMessage,
! 			       "Edit outgoing message? (%c/%c) "), 
! 		       *def_ans_yes, *def_ans_no);
  	  edit_msg = (want_to(subject,
! 			      *def_ans_yes, elm_LINES-3, 0) != *def_ans_no);
  	}
  
  	if (strlen(headers[current-1]->subject) > 0) {
  
! 	  strfcpy(subject, headers[current-1]->subject, sizeof subject); 
  
  	  /* this next strange compare is to see if the last few chars are
  	     already '(fwd)' before we tack another on */
  
! 	  if (strlen(subject) < 6 || (strcmp(subject+strlen(subject)-5,
  					     "(fwd)") != 0))
! 	    strfcat(subject, " (fwd)", sizeof subject);
  
! 	  results = send_msg(address, "", subject, 
! 			     (edit_msg ? MAIL_EDIT_MSG : 0 ) | MAIL_FORWARDING,
! 			     headers[current-1]->status & FORM_LETTER ? 
! 			     PREFORMATTED : allow_forms);
  	}
  	else
  	  results = send_msg(address, "",
! 		catgets(elm_msg_cat, ElmSet, ElmForwardedMail, 
! 			"Forwarded mail..."), 
! 			     (edit_msg ? MAIL_EDIT_MSG : 0 ) | MAIL_FORWARDING,
! 			     headers[current-1]->status & FORM_LETTER ? 
! 			     PREFORMATTED : allow_forms);	
  	return(results);
  }
  
! int get_return_name(address, name, trans_to_lowercase, size)
!      char *address, *name;
!      int   trans_to_lowercase;
!      int size;
  {
  	/** Given the address (either a single address or a combined list 
  	    of addresses) extract the login name of the first person on
***************
*** 460,474 ****
  			end, first = 0;
  	register char	*c;
  
! 	dprint(6, (debugfile,"get_return_name called with (%s, <>, shift=%s)\n",
! 		   address, onoff(trans_to_lowercase)));
  
  	/* First step - copy address up to a comma, space, or EOLN */
  
! 	for (sa = single_address; *address; ) {
  	    i = len_next_part(address);
  	    if (i > 1) {
! 		while (--i >= 0)
  		    *sa++ = *address++;
  	    } else if (*address == ',' || whitespace(*address))
  		break;
--- 386,402 ----
  			end, first = 0;
  	register char	*c;
  
! 	dprint(6, (debugfile,"get_return_name called with (%s, <>, shift=%s, size=%d)\n",
! 		   address, onoff(trans_to_lowercase), size));
  
  	/* First step - copy address up to a comma, space, or EOLN */
  
! 	for (sa = single_address; *address && 
! 	       sa - single_address < sizeof single_address -1 ; ) {
  	    i = len_next_part(address);
  	    if (i > 1) {
! 		while (--i >= 0 && 
! 		       sa - single_address < sizeof single_address -1)
  		    *sa++ = *address++;
  	    } else if (*address == ',' || whitespace(*address))
  		break;
***************
*** 514,524 ****
  		    || (c = strstr (&single_address[first], "/g"))) {
  
  		    for (c += 2; *c && (*c++ != '='); );
! 		    for ( ;*c && (*c != '/'); c++) {
  			name[iindex++] = trans_to_lowercase
  					? tolower (*c) : *c;
  		    }
! 		    if (iindex > 0) {
  			name[iindex++] = '.';
  		    }
  		}
--- 442,452 ----
  		    || (c = strstr (&single_address[first], "/g"))) {
  
  		    for (c += 2; *c && (*c++ != '='); );
! 		    for ( ;*c && (*c != '/') && iindex < size-1; c++) {
  			name[iindex++] = trans_to_lowercase
  					? tolower (*c) : *c;
  		    }
! 		    if (iindex > 0 && iindex < size-1) {
  			name[iindex++] = '.';
  		    }
  		}
***************
*** 526,532 ****
  		    || (c = strstr (&single_address[first], "/s"))) {
  
  		    for (c += 2; *c && (*c++ != '='); );
! 		    for ( ;*c && (*c != '/'); c++) {
  			name[iindex++] = trans_to_lowercase
  					? tolower (*c) : *c;
  		    }
--- 454,460 ----
  		    || (c = strstr (&single_address[first], "/s"))) {
  
  		    for (c += 2; *c && (*c++ != '='); );
! 		    for ( ;*c && (*c != '/') && iindex < size-1; c++) {
  			name[iindex++] = trans_to_lowercase
  					? tolower (*c) : *c;
  		    }
***************
*** 539,545 ****
  		}
  
  		if (iindex == 0) {
! 		    strcpy (name, "X.400.John.Doe");
  		}
  		return 0;
  	    }
--- 467,473 ----
  		}
  
  		if (iindex == 0) {
! 		    strfcpy (name, "X.400.John.Doe", size);
  		}
  		return 0;
  	    }
***************
*** 568,574 ****
  	
  	    if (i < first || single_address[i] == '!') i++;
  
! 	    for (iindex = 0; iindex < loc - i + 1; iindex++)
  		if (trans_to_lowercase)
  		    name[iindex] = tolower(single_address[iindex+i]);
  		else
--- 496,502 ----
  	
  	    if (i < first || single_address[i] == '!') i++;
  
! 	    for (iindex = 0; iindex < loc - i + 1 && iindex < size-1; iindex++)
  		if (trans_to_lowercase)
  		    name[iindex] = tolower(single_address[iindex+i]);
  		else
***************
*** 586,593 ****
  
  	    loc = strlen(single_address)-1; 	/* last char */
  
! 	    for (i = loc; i > -1 && single_address[i] != '!'
! 		 && single_address[i] != '.'; i--) {
  		if (trans_to_lowercase)
  		    name[iindex++] = tolower(single_address[i]);
  		else
--- 514,523 ----
  
  	    loc = strlen(single_address)-1; 	/* last char */
  
! 	    for (i = loc; 
! 		 i > -1 && single_address[i] != '!'
! 		 && single_address[i] != '.' && iindex < size-1; 
! 		 i--) {
  		if (trans_to_lowercase)
  		    name[iindex++] = tolower(single_address[i]);
  		else
***************
*** 599,733 ****
  	return 0;
  }
  
- int
- break_down_tolist(buf, iindex, address, comment)
- char *buf, *address, *comment;
- int  *iindex;
- {
- 	/** This routine steps through "buf" and extracts a single address
- 	    entry.  This entry can be of any of the following forms;
- 
- 		address (name)
- 		name <address>
- 		address
- 	
- 	    Once it's extracted a single entry, it will then return it as
- 	    two tokens, with 'name' (e.g. comment) surrounded by parens.
- 	    Returns ZERO if done with the string...
- 	**/
- 
- 	char buffer[LONG_STRING];
- 	register int i, loc = 0, hold_index, len;
- 
- 	if (*iindex > strlen(buf)) return(FALSE);
- 
- 	while (whitespace(buf[*iindex])) (*iindex)++;
- 
- 	if (*iindex > strlen(buf)) return(FALSE);
- 
- 	/** Now we're pointing at the first character of the token! **/
- 
- 	hold_index = *iindex;
- 
- 	if (buf[*iindex] == '"') {	/* A quoted string */
- 	  buffer[loc++] = buf[(*iindex)++];
- 	  while (buf[*iindex] != '"' && buf[*iindex] != '\0') {
- 	    if (buf[*iindex] == '\\' && buf[(*iindex)+1] != '\0')
- 	      buffer[loc++] = buf[(*iindex)++];	/* Copy backslash */
- 	    buffer[loc++] = buf[(*iindex)++];
- 	  }
- 	
- 	  if (buf[*iindex] == '"')
- 	    buffer[loc++] = buf[(*iindex)++]; /* Copy final " */
- 	}
- 
- 	/*
- 	 * Previously, we just went looking for a "," to seperate the
- 	 * addresses.  This meant that addresses like:
- 	 *
- 	 *	joe@acme.com (LastName, Firstname)
- 	 *
- 	 * got split right down the middle.  The following was changed
- 	 * to step through the address in quanta of RFC-822 tokens.
- 	 * That fixes the bug, but this routine is still incurably ugly.
- 	 */
- 	i = *iindex;
- 	while (buf[i] != ',' && buf[i] != '\0') {
- 		len = rfc822_toklen(buf+i);
- 		strncpy(buffer+loc, buf+i, len);
- 		loc += len;
- 		i += len;
- 	}
- 	*iindex = i + (buf[i] != '\0' ? 1 : 0);
- 	buffer[loc] = '\0';
- 
- 	while (whitespace(buffer[loc])) 	/* remove trailing whitespace */
- 	  buffer[--loc] = '\0';
- 
- 	if (strlen(buffer) == 0) return(FALSE);
- 
- 	dprint(5, (debugfile, "\n* got \"%s\"\n", buffer));
- 
- 	if (buffer[loc-1] == ')') {	/*   address (name)  format */
- 	  for (loc = 0, len = strlen(buffer);buffer[loc] != '(' && loc < len; loc++)
- 		/* get to the opening comment character... */ ;
- 
- 	  loc--;	/* back up to just before the paren */
- 	  while (whitespace(buffer[loc])) loc--;	/* back up */
- 
- 	  /** get the address field... **/
- 
- 	  for (i=0; i <= loc; i++)
- 	    address[i] = buffer[i];
- 	  address[i] = '\0';
- 
- 	  /** now get the comment field, en toto! **/
- 
- 	  loc = 0;
- 
- 	  for (i = chloc(buffer, '('), len = strlen(buffer); i < len; i++)
- 	    comment[loc++] = buffer[i];
- 	  comment[loc] = '\0';
- 	}
- 	else if (buffer[loc-1] == '>') {	/*   name <address>  format */
- 	  dprint(7, (debugfile, "\tcomment <address>\n"));
- 	  for (loc = 0, len = strlen(buffer);buffer[loc] != '<' && loc < len; loc++)
- 		/* get to the opening comment character... */ ;
- 	  while (whitespace(buffer[loc])) loc--;	/* back up */
- 	  if (loc >= 0 && !whitespace(buffer[loc])) loc++; /* And fwd again! */
- 
- 	  /** get the comment field... **/
- 
- 	  comment[0] = '(';
- 	  for (i=1; i <= loc; i++)
- 	    comment[i] = buffer[i-1];
- 	  comment[i++] = ')';
- 	  comment[i] = '\0';
- 
- 	  /** now get the address field, en toto! **/
- 
- 	  loc = 0;
- 
- 	  for (i = chloc(buffer,'<') + 1, len = strlen(buffer); i < len - 1; i++)
- 	    address[loc++] = buffer[i];
- 	
- 	  address[loc] = '\0';
- 	}
- 	else {
- 	  /** the next section is added so that all To: lines have commas
- 	      in them accordingly **/
- 
- 	  for (i=0; buffer[i] != '\0'; i++)
- 	    if (whitespace(buffer[i])) break;
- 	  if (i < strlen(buffer)) {	/* shouldn't be whitespace */
- 	    buffer[i] = '\0';
- 	    *iindex = hold_index + strlen(buffer) + 1;
- 	  }
- 	  strcpy(address, buffer);
- 	  comment[0] = '\0';
- 	}
- 
- 	dprint(5, (debugfile, "-- returning '%s' '%s'\n", address, comment));
- 
- 	return(TRUE);
- }
--- 529,531 ----
Index: elm2.4.ME+.50/src/returnadd.c
*** elm2.4.25/src/returnadd.c	Mon Apr 12 06:11:24 1993
--- elm2.4.ME+.50/src/returnadd.c	Tue Nov 17 21:12:58 1998
***************
*** 1,58 ****
  
! static char rcsid[] = "@(#)$Id: returnadd.c,v 5.8 1993/04/12 03:11:23 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.8 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: returnadd.c,v $
!  * Revision 5.8  1993/04/12  03:11:23  syd
!  * Fix to don't use address from reply-to field if it is empty.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * This can not happen according to RFC822. It requires at least one address if the
!  * reply-to is present, so this bug (EB48) isn't really a bug. But one can
!  * always try to be nice :-).
!  *
!  * Revision 5.7  1993/02/03  19:06:31  syd
!  * Remove extra strchr/strcat/strcpy et al declarations
!  * From: Syd
!  *
!  * Revision 5.6  1992/12/20  05:25:13  syd
!  * Always pass three parameters to header_cmp().
!  * From: chip@tct.com (Chip Salzenberg)
!  *
!  * Revision 5.5  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.4  1992/11/26  00:46:50  syd
!  * Fix how errno is used so err is inited and used instead
!  * as errno gets overwritten by print system call
!  * From: Syd
!  *
!  * Revision 5.3  1992/11/07  20:05:52  syd
!  * change to use header_cmp to allow for linear white space around the colon
!  * From: Syd
!  *
!  * Revision 5.2  1992/11/07  14:59:05  syd
!  * fix format variable for long
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  * 
!  ******************************************************************************/
  
  /** This set of routines is used to generate real return addresses
      and also return addresses suitable for inclusion in a users
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: returnadd.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This set of routines is used to generate real return addresses
      and also return addresses suitable for inclusion in a users
***************
*** 66,71 ****
--- 24,31 ----
  #include <errno.h>
  #include <sys/stat.h>
  
+ #include "me.h"
+ 
  char *shift_lower();
  
  extern int errno;
***************
*** 72,160 ****
  
  char *error_description();
  
- void
- get_existing_address(buffer, msgnum)
- char *buffer;
- int msgnum;
- {
- 	/** This routine is called when the message being responded to has
- 	    "To:xyz" as the return address, signifying that this message is
- 	    an automatically saved copy of a message previously sent.  The
- 	    correct to address can be obtained fairly simply by reading the
- 	    To: header from the message itself and (blindly) copying it to
- 	    the given buffer.  Note that this header can be either a normal
- 	    "To:" line (Elm) or "Originally-To:" (previous versions e.g.Msg)
- 	**/
- 
- 	char mybuf[LONG_STRING];
- 	register char ok = 1, in_to = 0;
- 	int  err;
- 
- 	buffer[0] = '\0';
- 
- 	/** first off, let's get to the beginning of the message... **/
  
! 	if(msgnum < 0 || msgnum >= message_count || message_count < 1) {
! 	  dprint(1, (debugfile,
! 		"Error: %d not a valid message number message_count = %d (%s)",
! 		msgnum, message_count, "get_existing_address"));
! 	  error1(catgets(elm_msg_cat, ElmSet, ElmNotAValidMessageNum,
! 		"%d not a valid message number!"), msgnum);
! 	  return;
! 	}
!         if (fseek(mailfile, headers[msgnum]->offset, 0) == -1) {
! 	    err = errno;
! 	    dprint(1, (debugfile, 
! 		    "Error: seek %ld bytes into file hit errno %s (%s)", 
! 		    headers[msgnum]->offset, error_description(err), 
! 		    "get_existing_address"));
! 	    error2(catgets(elm_msg_cat, ElmSet, ElmCouldntSeekBytesIntoFlle,
! 		   "Couldn't seek %ld bytes into file (%s)."),
! 	           headers[msgnum]->offset, error_description(err));
! 	    return;
!         }
!  
!         /** okay!  Now we're there!  **/
! 
!         while (ok) {
!           ok = (int) (mail_gets(mybuf, LONG_STRING, mailfile) != 0);
! 	  no_ret(mybuf);	/* remove return character */
! 
!           if (header_cmp(mybuf, "To", NULL) ||
! 	      header_cmp(mybuf, "Original-To", NULL)) {
! 	    in_to = TRUE;
! 	    strcpy(buffer, index(mybuf, ':') + 1);
!           }
! 	  else if (in_to && whitespace(mybuf[0])) {
! 	    strcat(buffer, " ");		/* tag a space in   */
! 	    strcat(buffer, (char *) mybuf + 1);	/* skip 1 whitespace */
! 	  }
! 	  else if (strlen(mybuf) < 2)
! 	    return;				/* we're done for!  */
! 	  else
! 	    in_to = 0;
!       }
  }
  
! int
! get_return(buffer, msgnum)
! char *buffer;
! int msgnum;
  {
  	/** reads msgnum message again, building up the full return 
  	    address including all machines that might have forwarded 
  	    the message.  Returns whether it is using the To line **/
  
- 	char buf[SLEN], name1[SLEN], name2[SLEN], lastname[SLEN];
- 	char hold_return[SLEN], alt_name2[SLEN], buf2[SLEN];
- 	int lines, len_buf, len_buf2, colon_offset, decnet_found;
  	int using_to = FALSE, err;
  
  	/* now initialize all the char buffers [thanks Keith!] */
  
- 	buf[0] = name1[0] = name2[0] = lastname[0] = '\0';
- 	hold_return[0] = alt_name2[0] = buf2[0] = '\0';
- 
  	/** get to the first line of the message desired **/
  
  	if(msgnum < 0 || msgnum >= message_count || message_count < 1) {
--- 32,66 ----
  
  char *error_description();
  
  
! static void kludge P_((char *buffer, int size));
! static void kludge(buffer, size) 
!      char * buffer;
!      int size;
! {
!   if (qchloc(buffer, '@') < 0
!       && qchloc(buffer, '%') < 0
!       && qchloc(buffer, '!') < 9)
!     {
!       strfcat(buffer,"@", size);
!       strfcat(buffer,hostfullname, size);
!     }
  }
  
! int get_return(buffer, msgnum, size)
!      char *buffer;
!      int msgnum;
!      int size;
  {
  	/** reads msgnum message again, building up the full return 
  	    address including all machines that might have forwarded 
  	    the message.  Returns whether it is using the To line **/
  
  	int using_to = FALSE, err;
+ 	struct addr_item *ptr;
  
  	/* now initialize all the char buffers [thanks Keith!] */
  
  	/** get to the first line of the message desired **/
  
  	if(msgnum < 0 || msgnum >= message_count || message_count < 1) {
***************
*** 161,257 ****
  	  dprint(1, (debugfile,
  		"Error: %d not a valid message number message_count = %d (%s)",
  		msgnum, message_count, "get_return"));
! 	  error1(catgets(elm_msg_cat, ElmSet, ElmNotAValidMessageNum,
! 		"%d not a valid message number!"), msgnum);
! 	  return(using_to);
! 	}
! 
! 	if (fseek(mailfile, headers[msgnum]->offset, 0) == -1) {
! 	  err = errno;
! 	  dprint(1, (debugfile,
! 		"Error: seek %ld bytes into file hit errno %s (%s)", 
! 		headers[msgnum]->offset, error_description(err), 
! 	        "get_return"));
! 	  error2(catgets(elm_msg_cat, ElmSet, ElmCouldntSeekBytesIntoFlle,
! 		"Couldn't seek %ld bytes into file (%s)."),
! 	       headers[msgnum]->offset, error_description(err));
  	  return(using_to);
  	}
-  
- 	/** okay!  Now we're there!  **/
  
! 	lines = headers[msgnum]->lines;
  
  	buffer[0] = '\0';
! 
! 	if (len_buf2 = mail_gets(buf2, SLEN, mailfile)) {
! 	  if(buf2[len_buf2-1] == '\n')
! 	    lines--; /* got a full line */
! 	}
! 
! 	while (len_buf2 && lines) {
! 	  buf[0] = '\0';
! 	  strncat(buf, buf2, SLEN);
! 	  len_buf = strlen(buf);
! 	  if (len_buf2 = mail_gets(buf2, SLEN, mailfile)) {
! 	    if(buf2[len_buf2-1] == '\n')
! 	      lines--; /* got a full line */
! 	  }
! 	  while (len_buf2 && lines && whitespace(buf2[0]) && len_buf >= 2) {
! 	    if (buf[len_buf-1] == '\n') {
! 	      len_buf--;
! 	      buf[len_buf] = '\0';
! 	    }
! 	    strncat(buf, buf2, (SLEN-len_buf-1));
! 	    len_buf = strlen(buf);
! 	    if (len_buf2 = mail_gets(buf2, SLEN, mailfile)) {
! 	      if(buf2[len_buf2-1] == '\n')
! 		lines--; /* got a full line */
! 	    }
! 	  }
! 
! /* At this point, "buf" contains the unfolded header line, while "buf2" contains
!    the next single line of text from the mail file */
! 
! 	  if (first_word(buf, "From ")) 
! 	    sscanf(buf, "%*s %s", hold_return);
! 	  else if (first_word_nc(buf, ">From")) {
! 	    sscanf(buf,"%*s %s %*s %*s %*s %*s %*s %*s %*s %s %s", 
! 	           name1, name2, alt_name2);
! 	    if (strcmp(name2, "from") == 0)		/* remote from xyz  */
! 	      strcpy(name2, alt_name2);
! 	    else if (strcmp(name2, "by") == 0)	/* forwarded by xyz */
! 	      strcpy(name2, alt_name2);
! 	    add_site(buffer, name2, lastname);
! 	  }
! 
! #ifdef USE_EMBEDDED_ADDRESSES
! 
! 	  else if (header_cmp(buf, "From", NULL)) {
! 	    get_address_from(buf, hold_return);
! 	    buffer[0] = '\0';
!           }
!           else if (header_cmp(buf, "Reply-To", NULL)) {
! 	    get_address_from(buf, buffer);
! 	    if (strlen(buffer) > 0) return(using_to);
!           }
! 
! #endif
! 
! 	  else if (len_buf < 2)	/* done with header */
!             lines = 0; /* let's get outta here!  We're done!!! */
! 	}
! 
! 	if (buffer[0] == '\0')
! 	  strcpy(buffer, hold_return); /* default address! */
! 	else
! 	  add_site(buffer, name1, lastname);	/* get the user name too! */
! 
! 	if (header_cmp(buffer, "To", NULL)) {	/* backward compatibility ho */
! 	  get_existing_address(buffer, msgnum);
! 	  using_to = TRUE;
! 	}
! 	else {
  	  /*
  	   * KLUDGE ALERT - DANGER WILL ROBINSON
  	   * We can't just leave a bare login name as the return address,
--- 67,87 ----
  	  dprint(1, (debugfile,
  		"Error: %d not a valid message number message_count = %d (%s)",
  		msgnum, message_count, "get_return"));
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNotAValidMessageNum,
! 			    "%d not a valid message number!"), 
! 		    msgnum);
  	  return(using_to);
  	}
  
! 	/* reply-to is now handle in handle_reply_to */
  
  	buffer[0] = '\0';
! 	for (ptr = headers[msgnum]->from; 
! 	     ptr && ptr -> addr && ptr->fullname; 
! 	     ptr++) {
! 	  char buffer1[STRING];
! 	  
! 	  strfcpy(buffer1,ptr->addr, sizeof buffer1);
  	  /*
  	   * KLUDGE ALERT - DANGER WILL ROBINSON
  	   * We can't just leave a bare login name as the return address,
***************
*** 260,294 ****
  	   * Sigh.
  	   */
  
! 	  if ((colon_offset = qchloc(buffer, ':')) > 0)
! 		decnet_found = buffer[colon_offset + 1] == ':';
! 	  else
! 		decnet_found = NO;
! 		
! 	  if (qchloc(buffer, '@') < 0
! 	   && qchloc(buffer, '%') < 0
! 	   && qchloc(buffer, '!') < 0
! 	   && decnet_found == NO)
! 	  {
! #ifdef INTERNET
! 	    sprintf(buffer + strlen(buffer), "@%s", hostfullname);
! #else
! 	    strcpy(buf, buffer);
! 	    sprintf(buffer, "%s!%s", hostname, buf);
! #endif
  	  }
  
- 	  /*
- 	   * If we have a space character,
- 	   * or we DON'T have '!' or '@' chars,
- 	   * append the user-readable name.
- 	   */
- 	  if (qchloc(headers[msgnum]->from, ' ') >= 0 ||
- 	      (qchloc(headers[msgnum]->from, '!') < 0 &&
- 	       qchloc(headers[msgnum]->from, '@') < 0)) {
- 	       sprintf(buffer + strlen(buffer),
- 		       " (%s)", headers[msgnum]->from);
-           }
  	}
  
  	return(using_to);
--- 90,124 ----
  	   * Sigh.
  	   */
  
! 	  kludge(buffer1,sizeof buffer1);
! 	  
! 	  if (buffer[0] != '\0')
! 	    strfcat(buffer,", ", size);
! 	  strfcat(buffer,buffer1, size);
! 	  
! 	  if (ptr->fullname[0] != '\0') {
! #ifdef MIME
! 	    if (!allow_no_hdrencoding) {
! 	      /* from is not longer mime encoded */
! 	      
! 	      char temp[LONG_STRING];
! 	      rfc1522_encode_text(temp,sizeof temp,ptr->fullname,
! 				  HDR_COMMENT);
! 	      elm_sfprintf(buffer + strlen(buffer), size - strlen(buffer),
! 			   FRM(" (%s)"), 
! 			   temp);	    
! 	    } else
! #endif 
! 	      elm_sfprintf(buffer + strlen(buffer), size - strlen(buffer),
! 			   FRM(" (%s)"), 
! 			   ptr->fullname);
  	  }
+ 	}
+ 	
+ 	if (buffer[0] == '\0') {
+ 	  strfcpy(buffer,headers[msgnum]->env_from,size);
+ 	  kludge(buffer,size);
  
  	}
  
  	return(using_to);
Index: elm2.4.ME+.50/src/save_opts.c
*** elm2.4.25/src/save_opts.c	Fri Mar 11 23:19:26 1994
--- elm2.4.ME+.50/src/save_opts.c	Tue Nov 17 21:14:09 1998
***************
*** 1,60 ****
  
! static char rcsid[] = "@(#)$Id: save_opts.c,v 5.8 1994/03/11 21:19:26 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.8 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: save_opts.c,v $
!  * Revision 5.8  1994/03/11  21:19:26  syd
!  * Recognize the "#$HDR" magic cookie as the header to place in the
!  * user's elmrc file rather than hardwiring a minimally helpful
!  * string into the binary.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.7  1993/09/27  01:51:38  syd
!  * Add elm_chown to consolidate for Xenix not allowing -1
!  * From: Syd
!  *
!  * Revision 5.6  1993/08/23  03:26:24  syd
!  * Try setting group id separate from user id in chown to
!  * allow restricted systems to change group id of file
!  * From: Syd
!  *
!  * Revision 5.5  1993/08/10  18:54:45  syd
!  * Elm was failing to write an empty "alternatives" list to elmrc.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.4  1993/08/03  19:03:52  syd
!  * "*clear-weed-list*" in elmrc was wiped out when one saved the options in elm.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.3  1993/06/10  02:55:34  syd
!  * Write options to elmrc even if their values are empty strings.
!  * Rationalize code that reads and writes weedouts and alternates.
!  * From: chip%fin@myrddin.sybus.com
!  *
!  * Revision 5.2  1993/04/12  03:10:54  syd
!  * The onoff macro assumes a boolean option only has values 1 or 0.
!  * This is not true for forms option (may be 2 == MAYBE).
!  *
!  * This is known bug EB51 BTW. I'm looking at the list now and there are some
!  * bugs that I think are simple, and I'll try to fix some of them.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This file contains the routine needed to allow the users to change the
      Elm parameters and then save the configuration in a ".elm/elmrc" file in
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: save_opts.c,v 1.3 1998/11/06 13:56:58 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This file contains the routine needed to allow the users to change the
      Elm parameters and then save the configuration in a ".elm/elmrc" file in
***************
*** 76,81 ****
--- 32,38 ----
  extern char version_buff[];
  
  char *error_description(), *sort_name(), *alias_sort_name(), *level_name();
+ char *mode_to_str();
  long  ftell();
  
  #include "save_opts.h"
***************
*** 103,110 ****
  	FILE *newelmrc; 
  	char  oldfname[SLEN], newfname[SLEN];
  
! 	sprintf(newfname, "%s/%s", home, elmrcfile);
! 	sprintf(oldfname, "%s/%s", home, old_elmrcfile);
  
  	/** first off, let's see if they already HAVE a .elm/elmrc file **/
  
--- 60,69 ----
  	FILE *newelmrc; 
  	char  oldfname[SLEN], newfname[SLEN];
  
! 	strfcpy(newfname,user_rc_file,sizeof newfname);
! 	elm_sfprintf(oldfname, sizeof oldfname,
! 		     FRM("%s/%s"), 
! 		     home, old_elmrcfile);
  
  	/** first off, let's see if they already HAVE a .elm/elmrc file **/
  
***************
*** 121,136 ****
  	/** now let's open the datafile if we can... **/
  
  	if ((elminfo = fopen(ELMRC_INFO, "r")) == NULL) 
! 	  error1(catgets(elm_msg_cat, ElmrcSet, ElmrcSavingWithoutComments,
! 		  "Warning: saving without comments! Can't get to %s."), 
! 		  ELMRC_INFO);
  
  	/** next, open the new .elm/elmrc file... **/
  
  	if ((newelmrc = fopen(newfname, "w")) == NULL) {
! 	   error2(catgets(elm_msg_cat, ElmrcSet, ElmrcCantSaveConfig,
! 		   "Can't save configuration! Can't write to %s [%s]."),
! 		   newfname, error_description(errno));
  	   return;
  	}
  	
--- 80,95 ----
  	/** now let's open the datafile if we can... **/
  
  	if ((elminfo = fopen(ELMRC_INFO, "r")) == NULL) 
! 	  lib_error(CATGETS(elm_msg_cat, ElmrcSet, ElmrcSavingWithoutComments,
! 			    "Warning: saving without comments! Can't get to %s."), 
! 		    ELMRC_INFO);
  
  	/** next, open the new .elm/elmrc file... **/
  
  	if ((newelmrc = fopen(newfname, "w")) == NULL) {
! 	   lib_error(CATGETS(elm_msg_cat, ElmrcSet, ElmrcCantSaveConfig,
! 			     "Can't save configuration! Can't write to %s [%s]."),
! 		     newfname, error_description(errno));
  	   return;
  	}
  	
***************
*** 137,144 ****
  	save_user_options(elminfo, newelmrc);
  	restore_file_stats(newfname);
  
! 	error1(catgets(elm_msg_cat, ElmrcSet, ElmrcOptionsSavedIn,
! 		"Options saved in file %s."), newfname);
  }
  
  static char *str_opt(x, f)
--- 96,103 ----
  	save_user_options(elminfo, newelmrc);
  	restore_file_stats(newfname);
  
! 	lib_error(CATGETS(elm_msg_cat, ElmrcSet, ElmrcOptionsSavedIn,
! 			  "Options saved in file %s."), newfname);
  }
  
  static char *str_opt(x, f)
***************
*** 148,154 ****
  	static char buf[SLEN];
  	register char *s, *t;
  
! 	s = strcpy(buf, "*ERROR*");
  	switch(save_info[x].flags & DT_MASK) {
  	    case DT_STR:
  		if (save_info[x].flags & FL_NOSPC) {
--- 107,113 ----
  	static char buf[SLEN];
  	register char *s, *t;
  
! 	s = strfcpy(buf, "*ERROR*", sizeof buf);
  	switch(save_info[x].flags & DT_MASK) {
  	    case DT_STR:
  		if (save_info[x].flags & FL_NOSPC) {
***************
*** 160,170 ****
  		    s = SAVE_INFO_STR(x);
  		break;
  
! 	    case DT_CHR:
! 		sprintf(buf, "%c", *SAVE_INFO_CHR(x));
! 		s = buf;
  		break;
  
  	    case DT_BOL:
  		s = onoff(*SAVE_INFO_BOL(x));
  		break;
--- 119,134 ----
  		    s = SAVE_INFO_STR(x);
  		break;
  
! 	    case DT_PRM:
! 		s = mode_to_str(*SAVE_INFO_NUM(x));
  		break;
  
+ 	    case DT_CHR:
+ 	      buf[0] = *SAVE_INFO_CHR(x);
+ 	      buf[1] = '\0';
+ 	      s = buf;
+ 	      break;
+ 
  	    case DT_BOL:
  		s = onoff(*SAVE_INFO_BOL(x));
  		break;
***************
*** 174,180 ****
  		    s = sort_name(SHORT);
  		    break;
  		}
! 		sprintf(buf, "%d", *SAVE_INFO_NUM(x));
  		s = buf;
  		break;
  
--- 138,146 ----
  		    s = sort_name(SHORT);
  		    break;
  		}
! 		elm_sfprintf(buf, sizeof buf,
! 			     FRM("%d"), 
! 			     *SAVE_INFO_NUM(x));
  		s = buf;
  		break;
  
***************
*** 183,189 ****
  		    s = alias_sort_name(SHORT);
  		    break;
  		}
! 		sprintf(buf, "%d", *SAVE_INFO_NUM(x));
  		s = buf;
  		break;
  
--- 149,157 ----
  		    s = alias_sort_name(SHORT);
  		    break;
  		}
! 		elm_sfprintf(buf, sizeof buf,
! 			     FRM("%d"), 
! 			     *SAVE_INFO_NUM(x));
  		s = buf;
  		break;
  
***************
*** 194,200 ****
  			break;
  		    }
  		}
! 		sprintf(buf, "%d", *SAVE_INFO_NUM(x));
  		s = buf;
  		break;
  
--- 162,174 ----
  			break;
  		    }
  		}
! 		if (save_info[x].e_ptr && *SAVE_INFO_NUM(x) >= 0 &&
! 		    *SAVE_INFO_NUM(x) <= save_info[x].e_ptr->nlen) {
! 		  s = save_info[x].e_ptr->list[*SAVE_INFO_NUM(x)];
! 		  break;
! 		}
! 		elm_sfprintf(buf, sizeof buf,
! 			     FRM("%d"), *SAVE_INFO_NUM(x));
  		s = buf;
  		break;
  
***************
*** 282,290 ****
  	    local_value = save_info[x].flags & FL_LOCAL;
  	    s = NULL;
  	    switch(save_info[x].flags & DT_MASK) {
! 		case DT_MLT:
! 		case DT_SYN:
! 		    break;
  
  		case DT_ASR:
  		case DT_SRT:
--- 256,264 ----
  	    local_value = save_info[x].flags & FL_LOCAL;
  	    s = NULL;
  	    switch(save_info[x].flags & DT_MASK) {
! 	    case DT_MLT:
! 	    case DT_SYN:
! 	      break;
  
  		case DT_ASR:
  		case DT_SRT:
***************
*** 295,300 ****
--- 269,275 ----
  		case DT_CHR:
  		case DT_BOL:
  		case DT_NUM:
+ 		  case DT_PRM:
  		    s = str_opt(x, SHORT);
  		    break;
  
Index: elm2.4.ME+.50/src/savecopy.c
*** elm2.4.25/src/savecopy.c	Mon May 16 02:10:12 1994
--- elm2.4.ME+.50/src/savecopy.c	Tue Nov 17 21:12:57 1998
***************
*** 1,91 ****
  
! static char rcsid[] = "@(#)$Id: savecopy.c,v 5.13 1994/05/15 23:10:08 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.13 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: savecopy.c,v $
!  * Revision 5.13  1994/05/15  23:10:08  syd
!  * Below are the changes required to compile/link elm 2.4 pl23 under
!  * QNX 4.2 with the Watcom 9.5 compiler (very picky).
!  * From: "Brian Campbell" <brianc@quantum>
!  *
!  * Revision 5.12  1993/05/31  19:35:24  syd
!  * Move the actual file saving code out of "save_copy()" into a seperate
!  * routine called "append_copy_to_file()" to make it globally available.
!  * In particular the "Canceled.mail" handling is going to be rewritten
!  * to use it.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.11  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.10  1993/04/12  02:34:36  syd
!  * I have now added a parameter which controls whether want_to clears the
!  * line and centers the question or behaves like it did before. I also
!  * added a 0 at the end of the parameter list to all the other calls to
!  * want_to where a centered question on a clean line is not desirable.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.9  1993/02/03  17:12:53  syd
!  * move more declarations to defs.h, including sleep
!  * From: Syd
!  *
!  * Revision 5.8  1993/01/19  04:55:10  syd
!  * fix which file name is used on confirm messages
!  * From: vogt@isa.de (Gerald Vogt)
!  *
!  * Revision 5.7  1993/01/19  03:55:39  syd
!  * exitprog.c makes a reference to a null character pointer, savecopy.c
!  * tries to reference an uninitialized variable, and the previous patch to
!  * src/lock.c to get rid of an uninitialized variable compiler message
!  * needed to be put in filter/lock.c as well.
!  * From: wdh@grouper.mkt.csd.harris.com (W. David Higgins)
!  *
!  * Revision 5.6  1992/12/25  00:18:10  syd
!  * Remove editing garbage from end
!  * From: Syd
!  *
!  * Revision 5.5  1992/12/24  21:42:01  syd
!  * Fix messages and nls messages to match.  Plus use want_to
!  * where appropriate.
!  * From: Syd, via prompting from Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.4  1992/11/26  00:46:50  syd
!  * Fix how errno is used so err is inited and used instead
!  * as errno gets overwritten by print system call
!  * From: Syd
!  *
!  * Revision 5.3  1992/10/30  21:01:49  syd
!  * More changes to folder creation confirmation
!  * From: Larry Philps <larryp@sco.COM>
!  *
!  * Revision 5.2  1992/10/24  13:25:41  syd
!  * In our global elm.rc I keep the four options as below
!  *
!  * 	confirmappend = OFF	Don't confirm every append to any file.
!  * 	confirmcreate = ON	Confirm creation of every new file.
!  * 	confirmfiles = ON	Confirm append to non folder files though.
!  * 	confirmfolders = ON	In case someone does not want to be asked
!  * 				every time when creating a new file try
!  * 				to confirm creation of folders though.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** Save a copy of the specified message in a folder.
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: savecopy.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** Save a copy of the specified message in a folder.
  
***************
*** 93,118 ****
  
  #include "headers.h"
  #include "s_elm.h"
- #ifdef I_TIME
- #  include <time.h>
- #endif
- #ifdef I_SYSTIME
- #  include <sys/time.h>
- #endif
  
  #include <errno.h>
  
  char *format_long(), *error_description(), *ctime();
  
  extern int errno;
  
! #ifdef MIME
! extern int msg_is_multipart;
! #endif
! extern long C_L_Position[2];   /*To Remember position of the Content-Length*/
! extern long C_StartData[2];    /*To Remember length of Header Area */
! extern long C_EndData[2];   /* To Remeber the End of the Data */
  
  
  /*
   * save_copy() - Append a copy of the message contained in "filename" to
--- 18,40 ----
  
  #include "headers.h"
  #include "s_elm.h"
  
  #include <errno.h>
+ #include "me.h"
+ 
  
  char *format_long(), *error_description(), *ctime();
  
  extern int errno;
  
! /* Offsets for figuring the Content-Length header */
! extern long cl_offset;
! extern long cl_start;
! extern long cl_end;
  
+ #ifdef USE_REMAILER
+ extern int remailing;
+ #endif
  
  /*
   * save_copy() - Append a copy of the message contained in "filename" to
***************
*** 120,128 ****
--- 42,58 ----
   * the filenames right, and then invokes "append_copy_to_file()" to do
   * the dirty work.
   */
+ int
+ #ifdef MIME
+ save_copy(to, cc, bcc, filename, copy_file, form, mime_info)
+ #else
  save_copy(to, cc, bcc, filename, copy_file, form)
+ #endif
  char *to, *cc, *bcc, *filename, *copy_file;
  int form;
+ #ifdef MIME
+ mime_send_t *mime_info;
+ #endif
  {
  	char  buffer[SLEN],	/* read buffer 		       */
  	      savename[SLEN],	/* name of file saving into    */
***************
*** 132,159 ****
  	int  err;
    
  	/* presume copy_file is okay as is for now */
! 	strcpy(savename, copy_file);
  
  	/* if save-by-name wanted */
  	if((strcmp(copy_file, "=") == 0)  || (strcmp(copy_file, "=?") == 0)) {
  
! 	  get_return_name(to, buffer, TRUE);	/* determine 'to' login */
  	  if (strlen(buffer) == 0) {
  
  	    /* can't get file name from 'to' -- use sent_mail instead */
  	    dprint(3, (debugfile,
  		"Warning: get_return_name couldn't break down %s\n", to));
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmCannotDetermineToName,
! "Cannot determine `to' name to save by! Saving to \"sent\" folder %s instead."),
! 	      sent_mail);
! 	    strcpy(savename, "<");
  	    if (sleepmsg > 0)
  		sleep(sleepmsg);
  	  } else
! 	    sprintf(savename, "=%s", buffer);		/* good! */
  	}
  
! 	expand_filename(savename, TRUE);	/* expand special chars */
  
  	/*
  	 *  If saving conditionally by logname but folder doesn't
--- 62,93 ----
  	int  err;
    
  	/* presume copy_file is okay as is for now */
! 	strfcpy(savename, copy_file, sizeof savename);
  
  	/* if save-by-name wanted */
  	if((strcmp(copy_file, "=") == 0)  || (strcmp(copy_file, "=?") == 0)) {
  
! 	  get_return_name(to, buffer, TRUE, 
! 			  sizeof buffer);	/* determine 'to' login */
  	  if (strlen(buffer) == 0) {
  
  	    /* can't get file name from 'to' -- use sent_mail instead */
  	    dprint(3, (debugfile,
  		"Warning: get_return_name couldn't break down %s\n", to));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCannotDetermineToName,
! 			      "Cannot determine `to' name to save by! Saving to \"sent\" folder %s instead."),
! 		      sent_mail);
! 	    strfcpy(savename, "<", sizeof savename);
  	    if (sleepmsg > 0)
  		sleep(sleepmsg);
  	  } else
! 	    elm_sfprintf(savename, sizeof savename,
! 			 FRM("=%.*s"), 
! 			 sizeof savename-2,buffer);		/* good! */
  	}
  
! 	expand_filename(savename, TRUE, sizeof savename);	
! 	/* expand special chars */
  
  	/*
  	 *  If saving conditionally by logname but folder doesn't
***************
*** 164,171 ****
  	  dprint(5, (debugfile,
  	    "Conditional save by name: file %s doesn't exist - using \"<\".\n",
  	    savename));
! 	  strcpy(savename, "<");
! 	  expand_filename(savename, TRUE);
  	}
  
  	/*
--- 98,105 ----
  	  dprint(5, (debugfile,
  	    "Conditional save by name: file %s doesn't exist - using \"<\".\n",
  	    savename));
! 	  strfcpy(savename, "<", sizeof savename);
! 	  expand_filename(savename, TRUE, sizeof savename);
  	}
  
  	/*
***************
*** 185,212 ****
  		 *  to use sent_mail anyway.
  		 */
  		if (batch_only) {
! 		    strcpy(savename, sent_mail);
  		}
  		else {
  		    if (is_ordinary_file)
! 		      MCsprintf(msg_buffer, catgets(elm_msg_cat, ElmSet, ElmConfirmFilesAppend,
! 			  "Append to an existing file `%s'? (%c/%c) "),
! 			savename, *def_ans_yes, *def_ans_no);
  		    else
! 		      MCsprintf(msg_buffer, catgets(elm_msg_cat, ElmSet, ElmConfirmFolderAppend,
! 			  "Append to mail folder `%s'? (%c/%c) "),
! 			savename, *def_ans_yes, *def_ans_no);
  
! 		    answer = want_to(msg_buffer, *def_ans_no, LINES-2, 1);
  
  		    if (answer != *def_ans_yes) {
! 			strcpy(savename, sent_mail);
! 			PutLine1 (LINES-2, 0, catgets(elm_msg_cat, ElmSet, ElmSavingToInstead,
! 				  "Alright - saving to `%s' instead"),
  				  savename);
  			if (sleepmsg > 0)
  				sleep(sleepmsg);
! 			ClearLine (LINES-2);
  		    }
  		}
  	    }
--- 119,152 ----
  		 *  to use sent_mail anyway.
  		 */
  		if (batch_only) {
! 		    strfcpy(savename, sent_mail, sizeof savename);
  		}
  		else {
  		    if (is_ordinary_file)
! 		      elm_sfprintf(msg_buffer, sizeof msg_buffer,
! 				    CATGETS(elm_msg_cat, ElmSet, 
! 					    ElmConfirmFilesAppend,
! 					    "Append to an existing file `%s'? (%c/%c) "),
! 				    savename, *def_ans_yes, *def_ans_no);
  		    else
! 		      elm_sfprintf(msg_buffer, sizeof msg_buffer,
! 				   CATGETS(elm_msg_cat, ElmSet, 
! 					   ElmConfirmFolderAppend,
! 					   "Append to mail folder `%s'? (%c/%c) "),
! 				   savename, *def_ans_yes, *def_ans_no);
  
! 		    answer = want_to(msg_buffer, *def_ans_no, elm_LINES-2, 1);
  
  		    if (answer != *def_ans_yes) {
! 			strfcpy(savename, sent_mail, sizeof savename);
! 			PutLineX (elm_LINES-2, 0, CATGETS(elm_msg_cat, 
! 							  ElmSet, 
! 							  ElmSavingToInstead,
! 							  "Alright - saving to `%s' instead"),
  				  savename);
  			if (sleepmsg > 0)
  				sleep(sleepmsg);
! 			ClearLine (elm_LINES-2);
  		    }
  		}
  	    }
***************
*** 219,246 ****
  		 *  to use sent_mail anyway.
  		 */
  		if (batch_only) {
! 		    strcpy(savename, sent_mail);
  		}
  		else {
  		    if (is_ordinary_file)
! 		      MCsprintf(msg_buffer, catgets(elm_msg_cat, ElmSet, ElmConfirmFilesCreate,
! 			  "Create a new file `%s'? (%c/%c) "),
  			savename, *def_ans_yes, *def_ans_no);
  		    else
! 		      MCsprintf(msg_buffer, catgets(elm_msg_cat, ElmSet, ElmConfirmFolderCreate,
! 			  "Create a new mail folder `%s'? (%c/%c) "),
  			savename, *def_ans_yes, *def_ans_no);
  
! 		    answer = want_to(msg_buffer, *def_ans_no, LINES-2, 1);
  
  		    if (answer != *def_ans_yes) {
! 			strcpy(savename, sent_mail);
! 			PutLine1 (LINES-2, 0, catgets(elm_msg_cat, ElmSet, ElmSavingToInstead,
! 				  "Alright - saving to `%s' instead"),
  				  savename);
  			if (sleepmsg > 0)
  				sleep(sleepmsg);
! 			ClearLine (LINES-2);
  		    }
  		}
  	    }
--- 159,192 ----
  		 *  to use sent_mail anyway.
  		 */
  		if (batch_only) {
! 		    strfcpy(savename, sent_mail, sizeof savename);
  		}
  		else {
  		    if (is_ordinary_file)
! 		      elm_sfprintf(msg_buffer, sizeof msg_buffer,
! 				   CATGETS(elm_msg_cat, ElmSet, 
! 					   ElmConfirmFilesCreate,
! 					   "Create a new file `%s'? (%c/%c) "),
  			savename, *def_ans_yes, *def_ans_no);
  		    else
! 		      elm_sfprintf(msg_buffer, sizeof msg_buffer,
! 				   CATGETS(elm_msg_cat, ElmSet, 
! 					   ElmConfirmFolderCreate,
! 					   "Create a new mail folder `%s'? (%c/%c) "),
  			savename, *def_ans_yes, *def_ans_no);
  
! 		    answer = want_to(msg_buffer, *def_ans_no, elm_LINES-2, 1);
  
  		    if (answer != *def_ans_yes) {
! 			strfcpy(savename, sent_mail, sizeof savename);
! 			PutLineX (elm_LINES-2, 0, CATGETS(elm_msg_cat, 
! 							  ElmSet, 
! 							  ElmSavingToInstead,
! 							  "Alright - saving to `%s' instead"),
  				  savename);
  			if (sleepmsg > 0)
  				sleep(sleepmsg);
! 			ClearLine (elm_LINES-2);
  		    }
  		}
  	    }
***************
*** 255,262 ****
  	  /* Lets try sent_mail before giving up */
  	  if(strcmp(sent_mail, savename) == 0) {
  	    /* we are ALREADY using sent_mail! */
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmCannotSaveTo,
! 			"Cannot save to %s!"), savename);
  	    if (sleepmsg > 0)
  		    sleep(sleepmsg);
  	    return(FALSE);
--- 201,208 ----
  	  /* Lets try sent_mail before giving up */
  	  if(strcmp(sent_mail, savename) == 0) {
  	    /* we are ALREADY using sent_mail! */
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCannotSaveTo,
! 			      "Cannot save to %s!"), savename);
  	    if (sleepmsg > 0)
  		    sleep(sleepmsg);
  	    return(FALSE);
***************
*** 267,288 ****
  	  "Error: attempt to autosave to a file that can't be appended to!\n"));
  	    dprint(2, (debugfile, "\tfilename = \"%s\"\n", sent_mail));
  	    dprint(2, (debugfile, "** %s **\n", error_description(err)));
! 	    error2(catgets(elm_msg_cat, ElmSet, ElmCannotSaveToNorSent,
! 		    "Cannot save to %s nor to \"sent\" folder %s!"),
! 		    savename, sent_mail);
  	    if (sleepmsg > 0)
  		    sleep(sleepmsg);
  	    return(FALSE);
  	  }
! 	  error2(catgets(elm_msg_cat, ElmSet, ElmCannotSaveToSavingInstead,
! 		"Cannot save to %s! Saving to \"sent\" folder %s instead."),
! 	        savename, sent_mail);
  	  if (sleepmsg > 0)
  		sleep(sleepmsg);
! 	  strcpy(savename, sent_mail);
  	}
! 
  	return (append_copy_to_file(to, cc, bcc, savename, filename, form)==0);
  }
  
  char *
--- 213,238 ----
  	  "Error: attempt to autosave to a file that can't be appended to!\n"));
  	    dprint(2, (debugfile, "\tfilename = \"%s\"\n", sent_mail));
  	    dprint(2, (debugfile, "** %s **\n", error_description(err)));
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCannotSaveToNorSent,
! 			      "Cannot save to %s nor to \"sent\" folder %s!"),
! 		      savename, sent_mail);
  	    if (sleepmsg > 0)
  		    sleep(sleepmsg);
  	    return(FALSE);
  	  }
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCannotSaveToSavingInstead,
! 			    "Cannot save to %s! Saving to \"sent\" folder %s instead."),
! 		    savename, sent_mail);
  	  if (sleepmsg > 0)
  		sleep(sleepmsg);
! 	  strfcpy(savename, sent_mail, sizeof savename);
  	}
! #ifdef MIME
! 	return (append_copy_to_file(to, cc, bcc, savename, filename, form,
! 				    mime_info)==0);
! #else
  	return (append_copy_to_file(to, cc, bcc, savename, filename, form)==0);
+ #endif
  }
  
  char *
***************
*** 306,314 ****
  }
  
  static char *ncf_prompt = NULL;
! int
! name_copy_file(fn)
! char *fn;
  {
      /** Prompt user for name of file for saving copy of outbound msg to.
  	Return true if we need a redraw. **/
--- 256,265 ----
  }
  
  static char *ncf_prompt = NULL;
! 
! int name_copy_file(fn, size)
!      char *fn;
!      int size;
  {
      /** Prompt user for name of file for saving copy of outbound msg to.
  	Return true if we need a redraw. **/
***************
*** 322,340 ****
  	ncf_prompt = catgets(elm_msg_cat, ElmSet, ElmSaveCopyInPrompt,
  			"Save copy in (use '?' for help/to list folders): ");
      }
      /* expand passed copy file name into English */
!     strcpy(buffer, cf_english(fn));
  
      /* prepare screen with instructions */
!     MoveCursor(LINES-2, 0);
      CleartoEOS();
!     PutLine0(LINES-2, 0, ncf_prompt);
  
      while(1) {
  
        /* get file name from user input */
!       strcpy(origbuffer, buffer);
!       optionally_enter(buffer, LINES-2, strlen(ncf_prompt), FALSE, FALSE);
  
        if(strcmp(buffer, "?") != 0) { /* got what we wanted - non-help choice */
  
--- 273,304 ----
  	ncf_prompt = catgets(elm_msg_cat, ElmSet, ElmSaveCopyInPrompt,
  			"Save copy in (use '?' for help/to list folders): ");
      }
+ 
+ redraw1:
      /* expand passed copy file name into English */
!     strfcpy(buffer, cf_english(fn), sizeof buffer);
  
      /* prepare screen with instructions */
!     MoveCursor(elm_LINES-2, 0);
      CleartoEOS();
!     PutLine0(elm_LINES-2, 0, ncf_prompt);
  
      while(1) {
+       int status;
  
        /* get file name from user input */
!       strfcpy(origbuffer, buffer, sizeof origbuffer);
!       status = optionally_enter(buffer, elm_LINES-2, strlen(ncf_prompt), 
! 				OE_REDRAW_MARK, sizeof buffer);
!       if (REDRAW_MARK == status) {
! 	redraw = TRUE;
! 	goto redraw1;
!       }
! 
!       if (status != 0) {
! 	fn[0] = '\0';
! 	return redraw;
!       }
  
        if(strcmp(buffer, "?") != 0) { /* got what we wanted - non-help choice */
  
***************
*** 342,357 ****
  	  /* user changed from our English expansion 
  	   * so we'd better copy user input to fn
  	   */
! 	  strcpy(fn, buffer);
  
  	/* else user presumably left our English expansion - no change in fn */
  
  	/* display English expansion of new user input a while */
! 	PutLine0(LINES-2, strlen(ncf_prompt), cf_english(fn));
! 	MoveCursor(LINES, 0);
  	if (sleepmsg > 0)
  		sleep((sleepmsg + 1) / 2);
! 	MoveCursor(LINES-2, 0);
  	CleartoEOS();
  
  	return(redraw);
--- 306,321 ----
  	  /* user changed from our English expansion 
  	   * so we'd better copy user input to fn
  	   */
! 	  strfcpy(fn, buffer, size);
  
  	/* else user presumably left our English expansion - no change in fn */
  
  	/* display English expansion of new user input a while */
! 	PutLine0(elm_LINES-2, strlen(ncf_prompt), cf_english(fn));
! 	MoveCursor(elm_LINES, 0);
  	if (sleepmsg > 0)
  		sleep((sleepmsg + 1) / 2);
! 	MoveCursor(elm_LINES-2, 0);
  	CleartoEOS();
  
  	return(redraw);
***************
*** 360,390 ****
        /* give help and list folders */
        redraw = TRUE;
        if(!*helpmsg) {	/* help message not yet formulated */
! 	strcpy(helpmsg, catgets(elm_msg_cat, ElmSet, ElmListFoldersHelp1,
  "Enter: <nothing> to not save a copy of the message,\n\
! \r       '<'       to save in your \"sent\" folder ("));
! 	strcat(helpmsg, sent_mail);
! 	strcat(helpmsg, catgets(elm_msg_cat, ElmSet, ElmListFoldersHelp2,
  "),\n\
  \r       '='       to save by name (the folder name depends on whom the\n\
  \r                     message is to, in the end),\n\
  \r       '=?'      to save by name if the folder already exists,\n\
  \r                     and if not, to your \"sent\" folder,\n\
! \r       or a filename (a leading '=' denotes your folder directory).\n\r\n\r"));
        }
  
        list_folders(4, helpmsg, NULL);
!       PutLine0(LINES-2, 0, ncf_prompt);
  
        /* restore as default to English version of the passed copy file name */
!       strcpy(buffer, cf_english(fn));
  
      }
  }
  
- 
  int
  append_copy_to_file(to, cc, bcc, fname_copy, fname_mssg, form)
  char *to;
  char *cc;
  char *bcc;
--- 324,359 ----
        /* give help and list folders */
        redraw = TRUE;
        if(!*helpmsg) {	/* help message not yet formulated */
! 	strfcpy(helpmsg, catgets(elm_msg_cat, ElmSet, ElmListFoldersHelp1,
  "Enter: <nothing> to not save a copy of the message,\n\
! \r       '<'       to save in your \"sent\" folder ("),
! 		sizeof helpmsg);
! 	strfcat(helpmsg, sent_mail, sizeof helpmsg);
! 	strfcat(helpmsg, catgets(elm_msg_cat, ElmSet, ElmListFoldersHelp2,
  "),\n\
  \r       '='       to save by name (the folder name depends on whom the\n\
  \r                     message is to, in the end),\n\
  \r       '=?'      to save by name if the folder already exists,\n\
  \r                     and if not, to your \"sent\" folder,\n\
! \r       or a filename (a leading '=' denotes your folder directory).\n\r\n\r"),
! 		sizeof helpmsg);
        }
  
        list_folders(4, helpmsg, NULL);
!       PutLine0(elm_LINES-2, 0, ncf_prompt);
  
        /* restore as default to English version of the passed copy file name */
!       strfcpy(buffer, cf_english(fn), sizeof buffer);
  
      }
  }
  
  int
+ #ifdef MIME
+ append_copy_to_file(to, cc, bcc, fname_copy, fname_mssg, form, mime_info)
+ #else
  append_copy_to_file(to, cc, bcc, fname_copy, fname_mssg, form)
+ #endif
  char *to;
  char *cc;
  char *bcc;
***************
*** 391,396 ****
--- 360,368 ----
  char *fname_copy;
  char *fname_mssg;
  int form;
+ #ifdef MIME
+ mime_send_t *mime_info;
+ #endif
  {
      int err;
      FILE *fp_copy, *fp_mssg;
***************
*** 403,410 ****
  	    "Error: Couldn't open \"%s\" for read in append_copy_to_file\n",
  	    fname_mssg));
  	dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	error1(catgets(elm_msg_cat, ElmSet, ElmAppendCopyCouldntReadFile,
! 	    "Couldn't read file \"%s\"!"), fname_mssg);
  	if (sleepmsg > 0)
  	    sleep(sleepmsg);
  	return -1;
--- 375,383 ----
  	    "Error: Couldn't open \"%s\" for read in append_copy_to_file\n",
  	    fname_mssg));
  	dprint(1, (debugfile, "** %s **\n", error_description(err)));
! 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmAppendCopyCouldntReadFile,
! 			  "Couldn't read file \"%s\"!"), 
! 		  fname_mssg);
  	if (sleepmsg > 0)
  	    sleep(sleepmsg);
  	return -1;
***************
*** 412,444 ****
  
      /* dump the header to the end of the copy file */
      save_file_stats(fname_copy);
      fp_copy = write_header_info(fname_copy, to, cc, bcc, (form == YES), TRUE);
      if (fp_copy == NULL) {
  	(void) fclose(fp_mssg);
  	return -1;
      }
      restore_file_stats(fname_copy);
-     C_StartData[0] = ftell(fp_copy);
  
!     /* dump the contents of the message to the end of the copy file */
!     copy_message_across(fp_mssg, fp_copy, TRUE);
  
  #ifdef MIME
!     if (!form != NO && msg_is_multipart) {
! 	fprintf(fp_copy, "--%%#%%record%%#%%--\n");
! 	if (C_L_Position[1] != 0L) {
! 	    C_EndData[1] = ftell(fp_copy);
! 	    C_L_Position[1] = fseek(fp_copy, C_L_Position[1], 0);
! 	    fprintf(fp_copy, "%d", C_EndData[1] - C_StartData[1]);
! 	    fseek(fp_copy, C_EndData[1], 0);
! 	}
      }
  #endif
!     C_EndData[0] = ftell(fp_copy) ;
  
  #ifdef MMDF
      /*
!      * Actually, the C_EndData just calculated is wrong for MMDF.
       * Because we are saving a copy instead of handing off to
       * submit, copy_message_across will have added the trailing
       * MMDF MSG_SEPARATOR to the end of the saved message to ensure
--- 385,429 ----
  
      /* dump the header to the end of the copy file */
      save_file_stats(fname_copy);
+ #ifdef MIME
+     fp_copy = write_header_info(fname_copy, to, cc, bcc, (form == YES), TRUE,
+ 				mime_info);
+ #else
      fp_copy = write_header_info(fname_copy, to, cc, bcc, (form == YES), TRUE);
+ #endif
      if (fp_copy == NULL) {
  	(void) fclose(fp_mssg);
  	return -1;
      }
      restore_file_stats(fname_copy);
  
!     cl_start = ftell(fp_copy);
  
+     /* dump the contents of the message to the end of the copy file */
  #ifdef MIME
! #ifdef USE_REMAILER
!     if (remailing) {
!       if (remailer_copy_message_across(fp_mssg, fp_copy, TRUE, mime_info) == -1)
!         return(-1);
!     }
!     else
! #endif
!     copy_message_across(fp_mssg, fp_copy, TRUE, mime_info);
! #else
! #ifdef USE_REMAILER
!     if (remailing) {
!       if (remailer_copy_message_across(fp_mssg, fp_copy, TRUE) == -1)
!         return(-1);
      }
+     else
  #endif
!     copy_message_across(fp_mssg, fp_copy, TRUE);
! #endif
  
+     cl_end = ftell(fp_copy) ;
  #ifdef MMDF
      /*
!      * Actually, the cl_end just calculated is wrong for MMDF.
       * Because we are saving a copy instead of handing off to
       * submit, copy_message_across will have added the trailing
       * MMDF MSG_SEPARATOR to the end of the saved message to ensure
***************
*** 448,459 ****
       * localized to this function, we will just subtract off the
       * length of the MSG_SEPARATOR.
       */
!     C_EndData[0] -= strlen(MSG_SEPARATOR);
  #endif /* MMDF */
  
      /* go fixup the content length header */
!     fseek(fp_copy, C_L_Position[0], 0);
!     fprintf(fp_copy, "%d", C_EndData[0] - C_StartData[0]);
  
      /* copy successfully done */
      fclose(fp_copy);
--- 433,444 ----
       * localized to this function, we will just subtract off the
       * length of the MSG_SEPARATOR.
       */
!     cl_end -= strlen(MSG_SEPARATOR);
  #endif /* MMDF */
  
      /* go fixup the content length header */
!     fseek(fp_copy, cl_offset, 0);
!     fprintf(fp_copy, "%d", cl_end - cl_start);
  
      /* copy successfully done */
      fclose(fp_copy);
***************
*** 460,463 ****
      fclose(fp_mssg);
      return 0;
  }
- 
--- 445,447 ----
Index: elm2.4.ME+.50/src/screen.c
*** elm2.4.25/src/screen.c	Wed Jan 20 05:02:41 1993
--- elm2.4.ME+.50/src/screen.c	Tue Nov 17 21:12:57 1998
***************
*** 1,34 ****
  
! static char rcsid[] = "@(#)$Id: screen.c,v 5.3 1993/01/20 03:02:19 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: screen.c,v $
!  * Revision 5.3  1993/01/20  03:02:19  syd
!  * Move string declarations to defs.h
!  * From: Syd
!  *
!  * Revision 5.2  1992/10/25  01:47:45  syd
!  * fixed a bug were elm didn't call metamail on messages with a characterset,
!  * which could be displayed by elm itself, but message is encoded with QP
!  * or BASE64
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /**  screen display routines for ELM program 
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: screen.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /**  screen display routines for ELM program 
  
***************
*** 35,40 ****
--- 17,23 ----
  **/
  
  #include "headers.h"
+ #include "melib.h"
  #include "s_elm.h"
  
  #define  minimum(a,b)	((a) < (b) ? (a) : (b))
***************
*** 58,65 ****
  
  	show_last_error();
  	
! 	if (hp_terminal) 
! 	  define_softkeys(MAIN);
  }
  
  update_title()
--- 41,47 ----
  
  	show_last_error();
  	
! 	/* define_softkeys(MAIN); */
  }
  
  update_title()
***************
*** 76,104 ****
  
  #ifdef DISP_HOST
  	if (*hostname)
! 		sprintf(folder_string, "%s:%s", hostname, nameof(cur_folder));
  	else
! 		strcpy(folder_string, nameof(cur_folder));
  #else
! 	strcpy(folder_string, nameof(cur_folder));
  #endif
  
  	if (selected)
! 	  MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmShownWithSelect,
! 	      "%s is '%s' with %d shown out of %d [ELM %s]"),
! 	      (folder_type == SPOOL ? mailbox : folder),
! 	      folder_string, selected, message_count, version_buff);
  	else if (message_count == 1)
! 	  MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmShownNoSelect,
! 	      "%s is '%s' with 1 message [ELM %s]"),
! 	      (folder_type == SPOOL ? mailbox : folder),
! 	      folder_string, version_buff);
  	else
! 	  MCsprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmShownNoSelectPlural,
! 	      "%s is '%s' with %d messages [ELM %s]"),
! 	      (folder_type == SPOOL ? mailbox : folder),
! 	      folder_string, message_count, version_buff);
! 
  	ClearLine(1);
  
  	Centerline(1, buffer);
--- 58,93 ----
  
  #ifdef DISP_HOST
  	if (*hostname)
! 		elm_sfprintf(folder_string, sizeof folder_string,
! 			     FRM("%s:%s"), hostname, nameof(cur_folder));
  	else
! 		strfcpy(folder_string, nameof(cur_folder),
! 			sizeof folder_string);
  #else
! 	strfcpy(folder_string, nameof(cur_folder), 
! 		sizeof folder_string);
  #endif
  
  	if (selected)
! 	  elm_sfprintf(buffer, sizeof buffer,
! 		       CATGETS(elm_msg_cat, ElmSet, ElmShownWithSelect,
! 			       "%s is '%s' with %d shown out of %d [ELM %s]"),
! 		       (folder_type == SPOOL ? mailbox : folder),
! 		       folder_string, selected, message_count, version_buff);
  	else if (message_count == 1)
! 	  elm_sfprintf(buffer, sizeof buffer,
! 		       CATGETS(elm_msg_cat, ElmSet, ElmShownNoSelect,
! 			       "%s is '%s' with 1 message [ELM %s]"),
! 		       (folder_type == SPOOL ? mailbox : folder),
! 		       folder_string, version_buff);
  	else
! 	  elm_sfprintf(buffer, sizeof buffer,
! 		       CATGETS(elm_msg_cat, ElmSet, 
! 			       ElmShownNoSelectPlural,
! 			       "%s is '%s' with %d messages [ELM %s]"),
! 		       (folder_type == SPOOL ? mailbox : folder),
! 		       folder_string, message_count, version_buff);
! 	
  	ClearLine(1);
  
  	Centerline(1, buffer);
***************
*** 109,130 ****
  	/** write main system menu... **/
  
  	if (user_level == 0) {	/* a rank beginner.  Give less options  */
! 	  Centerline(LINES-7, catgets(elm_msg_cat, ElmSet, ElmLevel0MenuLine1,
    "You can use any of the following commands by pressing the first character;"));
!           Centerline(LINES-6, catgets(elm_msg_cat, ElmSet, ElmLevel0MenuLine2,
  "d)elete or u)ndelete mail,  m)ail a message,  r)eply or f)orward mail,  q)uit"));
! 	  Centerline(LINES-5, catgets(elm_msg_cat, ElmSet, ElmLevel0MenuLine3,
    "To read a message, press <return>.  j = move down, k = move up, ? = help"));
  	} else {
! 	Centerline(LINES-7, catgets(elm_msg_cat, ElmSet, ElmLevel1MenuLine1,
    "|=pipe, !=shell, ?=help, <n>=set current to n, /=search pattern"));
!         Centerline(LINES-6, catgets(elm_msg_cat, ElmSet, ElmLevel1MenuLine2,
  "a)lias, C)opy, c)hange folder, d)elete, e)dit, f)orward, g)roup reply, m)ail,"));
! 	Centerline(LINES-5, catgets(elm_msg_cat, ElmSet, ElmLevel1MenuLine3,
    "n)ext, o)ptions, p)rint, q)uit, r)eply, s)ave, t)ag, u)ndelete, or e(x)it"));
  	}
  }
  
  int
  show_headers()
  {
--- 98,129 ----
  	/** write main system menu... **/
  
  	if (user_level == 0) {	/* a rank beginner.  Give less options  */
! 	  Centerline(elm_LINES-7, catgets(elm_msg_cat, ElmSet, 
! 					  ElmLevel0MenuLine1,
    "You can use any of the following commands by pressing the first character;"));
!           Centerline(elm_LINES-6, catgets(elm_msg_cat, ElmSet, 
! 					  ElmLevel0MenuLine2,
  "d)elete or u)ndelete mail,  m)ail a message,  r)eply or f)orward mail,  q)uit"));
! 	  Centerline(elm_LINES-5, catgets(elm_msg_cat, ElmSet, 
! 					  ElmLevel0MenuLine3,
    "To read a message, press <return>.  j = move down, k = move up, ? = help"));
  	} else {
! 	Centerline(elm_LINES-7, catgets(elm_msg_cat, ElmSet, 
! 					ElmLevel1MenuLine1,
    "|=pipe, !=shell, ?=help, <n>=set current to n, /=search pattern"));
!         Centerline(elm_LINES-6, catgets(elm_msg_cat, ElmSet, 
! 					ElmLevel1MenuLine2,
  "a)lias, C)opy, c)hange folder, d)elete, e)dit, f)orward, g)roup reply, m)ail,"));
! 	Centerline(elm_LINES-5, catgets(elm_msg_cat, ElmSet, 
! 					ElmLevel1MenuLine3,
    "n)ext, o)ptions, p)rint, q)uit, r)eply, s)ave, t)ag, u)ndelete, or e(x)it"));
  	}
  }
  
+ static void build_header_line P_((char *, struct header_rec *, int, int, 
+ 				  char *, int, int)); /* Prototype */
+ 
+ 
  int
  show_headers()
  {
***************
*** 174,194 ****
  	  if (inalias) {
  	    if (this_msg == current-1)
  	      build_alias_line(buffer, aliases[this_msg], this_msg+1,
! 			       TRUE);
  	    else
  	      build_alias_line(buffer, aliases[this_msg], this_msg+1,
! 			       FALSE);
  	  }
  	  else {
! 	  using_to = tail_of(headers[this_msg]->from, newfrom,
! 	    headers[this_msg]->to); 
! 
  	  if (this_msg == current-1) 
  	    build_header_line(buffer, headers[this_msg], this_msg+1,
! 			    TRUE, newfrom, using_to);
  	  else
  	    build_header_line(buffer, headers[this_msg], 
! 			    this_msg+1, FALSE, newfrom, using_to);
  	  }
  	  if (selected) 
  	    displayed++;
--- 173,200 ----
  	  if (inalias) {
  	    if (this_msg == current-1)
  	      build_alias_line(buffer, aliases[this_msg], this_msg+1,
! 			       TRUE, sizeof buffer);
  	    else
  	      build_alias_line(buffer, aliases[this_msg], this_msg+1,
! 			       FALSE, sizeof buffer);
  	  }
  	  else {
! 	    using_to = DisplayAddress(headers[this_msg], newfrom, 
! 				      sizeof (newfrom),
! #ifdef MIME
! 				      !(headers[this_msg] -> status & NOHDRENCODING) ?
! 				      rfc1522_decode_structured : decode_who_none
! #else
! 				      decode_who_none
! #endif
! 				      );
  	  if (this_msg == current-1) 
  	    build_header_line(buffer, headers[this_msg], this_msg+1,
! 			      TRUE, newfrom, using_to, sizeof buffer);
  	  else
  	    build_header_line(buffer, headers[this_msg], 
! 			      this_msg+1, FALSE, newfrom, using_to,
! 			      sizeof buffer);
  	  }
  	  if (selected) 
  	    displayed++;
***************
*** 195,204 ****
  
  	  if (this_msg == current-1 && has_highlighting && ! arrow_cursor) {
  	      StartInverse();
! 	      Write_to_screen("%s\n\r", 1, buffer);	/* avoid '%' probs */
  	      EndInverse();
  	  } else
! 	      Write_to_screen("%s\n\r", 1, buffer);	/* avoid '%' probs */
  	  CleartoEOLN();
  	  line++;		/* for clearing up in a sec... */
  
--- 201,210 ----
  
  	  if (this_msg == current-1 && has_highlighting && ! arrow_cursor) {
  	      StartInverse();
! 	      Write_to_screen(FRM("%s\n\r"), buffer);	/* avoid '%' probs */
  	      EndInverse();
  	  } else
! 	      Write_to_screen(FRM("%s\n\r"), buffer);	/* avoid '%' probs */
  	  CleartoEOLN();
  	  line++;		/* for clearing up in a sec... */
  
***************
*** 219,227 ****
  	/* clear unused lines */
  
  	if (mini_menu)
! 	  last_line = LINES-8;
  	else
! 	  last_line = LINES-4;
  
  	while (line < last_line) {
  	  CleartoEOLN();
--- 225,233 ----
  	/* clear unused lines */
  
  	if (mini_menu)
! 	  last_line = elm_LINES-8;
  	else
! 	  last_line = elm_LINES-4;
  
  	while (line < last_line) {
  	  CleartoEOLN();
***************
*** 275,286 ****
    
  	  if (inalias)
  	    build_alias_line(new_buffer, aliases[current-1], current,
! 			     TRUE);
  	  else {
! 	  using_to = tail_of(headers[current-1]->from, newfrom,
! 	    headers[current-1]->to); 
! 	  build_header_line(new_buffer, headers[current-1],  current,
! 		  TRUE, newfrom, using_to);
  	  }
  
  	  /* clear last current if it's in proper range */
--- 281,299 ----
    
  	  if (inalias)
  	    build_alias_line(new_buffer, aliases[current-1], current,
! 			     TRUE, sizeof new_buffer);
  	  else {
! 	    using_to = DisplayAddress(headers[current-1], newfrom,
! 				      sizeof(newfrom),
! #ifdef MIME
! 				      !(headers[current-1] -> status & NOHDRENCODING) ?
! 				      rfc1522_decode_structured : decode_who_none
! #else
! 				      decode_who_none
! #endif				      
! );
! 	    build_header_line(new_buffer, headers[current-1],  current,
! 			      TRUE, newfrom, using_to, sizeof new_buffer);
  	  }
  
  	  /* clear last current if it's in proper range */
***************
*** 296,307 ****
  
  	    if (inalias)
  	      build_alias_line(old_buffer, aliases[last_current-1],
! 	                       last_current, FALSE);
  	    else {
! 	    using_to = tail_of(headers[last_current-1]->from, newfrom,
! 	      headers[last_current-1]->to); 
! 	    build_header_line(old_buffer, headers[last_current-1], 
! 		 last_current, FALSE, newfrom, using_to);
  	    }
  
  	    ClearLine(last_line);
--- 309,329 ----
  
  	    if (inalias)
  	      build_alias_line(old_buffer, aliases[last_current-1],
! 	                       last_current, FALSE, sizeof old_buffer);
  	    else {
! 	      using_to = DisplayAddress(headers[last_current-1], newfrom,
! 					sizeof(newfrom),
! #ifdef MIME
! 				      !(headers[last_current-1] -> status & NOHDRENCODING) ?
! 				      rfc1522_decode_structured : decode_who_none
! #else
! 				      decode_who_none
! #endif
! 
! );
! 	      build_header_line(old_buffer, headers[last_current-1], 
! 				last_current, FALSE, newfrom, using_to,
! 				sizeof old_buffer);
  	    }
  
  	    ClearLine(last_line);
***************
*** 309,315 ****
  	  }
  	  MoveCursor(new_line, 0);
  	  StartInverse();
! 	  Write_to_screen("%s", 1, new_buffer);
  	  EndInverse();
  	}
  	else {
--- 331,337 ----
  	  }
  	  MoveCursor(new_line, 0);
  	  StartInverse();
! 	  Write_to_screen(FRM("%s"), new_buffer);
  	  EndInverse();
  	}
  	else {
***************
*** 322,332 ****
  	last_current = current;
  }
  
! build_header_line(buffer, entry, message_number, highlight, from, really_to)
! char *buffer;
! struct header_rec *entry;
! int message_number, highlight, really_to;
! char *from;
  {
  	/** Build in buffer the message header ... entry is the current
  	    message entry, 'from' is a modified (displayable) from line, 
--- 344,356 ----
  	last_current = current;
  }
  
! static void build_header_line(buffer, entry, message_number, highlight, 
! 			      from, really_to, size)
!      char *buffer;
!      struct header_rec *entry;
!      int message_number, highlight, really_to;
!      char *from;
!      int size;
  {
  	/** Build in buffer the message header ... entry is the current
  	    message entry, 'from' is a modified (displayable) from line, 
***************
*** 333,347 ****
  	    'highlight' is either TRUE or FALSE, and 'message_number'
  	    is the number of the message.
  	**/
- 
- 	/** Note: using 'strncpy' allows us to output as much of the
- 	    subject line as possible given the dimensions of the screen.
- 	    The key is that 'strncpy' returns a 'char *' to the string
- 	    that it is handing to the dummy variable!  Neat, eh? **/
  	
  	int who_width = 18, subj_width;
  	char *dot = index(from, '.');
  	char *bang = index(from, '!');
  
  	/* truncate 'from' to 18 characters -
  	 * this includes the leading "To" if really_to is true.
--- 357,367 ----
  	    'highlight' is either TRUE or FALSE, and 'message_number'
  	    is the number of the message.
  	**/
  	
  	int who_width = 18, subj_width;
  	char *dot = index(from, '.');
  	char *bang = index(from, '!');
+ 	int header_without_subj_width;
  
  	/* truncate 'from' to 18 characters -
  	 * this includes the leading "To" if really_to is true.
***************
*** 363,391 ****
  	 *	in 'from', else we truncate on the right.
  	 */
  
- 	/* Note that one huge sprintf() is too hard for some compilers. */
  	if (*entry->time_menu == '\0')
  	   make_menu_date(entry); 
  
- 	sprintf(buffer, "%s%s%c%-3d %s ",
- 		(highlight && arrow_cursor)? "->" : "  ",
- 		show_status(entry->status),
- 		(entry->status & TAGGED?  '+' : ' '),
- 	        message_number,
- 	        entry->time_menu); 
- 
  	/* show "To " in a way that it can never be truncated. */
  	if (really_to) {
- 	  strcat(buffer, "To ");
  	  who_width -= 3;
  	}
  
  	/* truncate 'from' on left if needed.
! 	 * sprintf will truncate on right afterward if needed. */
  	if ((strlen(from) > who_width) && dot && bang && (dot < bang)) {
  	  from += (strlen(from) - who_width);
  	}
  
  	/* Set the subject display width.
  	 * If it is too long, truncate it to fit.
  	 * If it is highlighted but not with the arrow  cursor,
--- 383,428 ----
  	 *	in 'from', else we truncate on the right.
  	 */
  
  	if (*entry->time_menu == '\0')
  	   make_menu_date(entry); 
  
  	/* show "To " in a way that it can never be truncated. */
  	if (really_to) {
  	  who_width -= 3;
  	}
  
  	/* truncate 'from' on left if needed.
! 	 * elm_sfprintf will truncate on right afterward if needed. */
  	if ((strlen(from) > who_width) && dot && bang && (dot < bang)) {
  	  from += (strlen(from) - who_width);
  	}
  
+ 	if (who_width + 30 >= size)
+ 	  who_width = size - 31;
+ 
+ 	elm_sfprintf(buffer, size,
+ 		     FRM("%.2s%.2s%c%-3d %.10s %.3s%-*.*s (%d) %s"),
+ 		     (highlight && arrow_cursor)? "->" : "  ",
+ 		     show_status(entry->status,entry),
+ 		     (entry->status & TAGGED?  '+' : ' '),
+ 		     message_number,
+ 		     entry->time_menu,
+ 		     (really_to ? "To " : ""),
+ 		     /* give max and min width parameters for 'from' */
+ 		     who_width,
+ 		     who_width,
+ 		     from,
+ 		     
+ 		     entry->lines, 
+ 		     (entry->lines / 1000   > 0? ""   :	/* spacing the  */
+ 		      entry->lines / 100   > 0? " "  :	/* same for the */
+ 		      entry->lines / 10  > 0? "  " :	/* lines in ()  */
+ 		      "   ")      /*   [wierd]    */
+ 		     );
+ 	
+ 	/* Get width of the header so far. */
+ 	header_without_subj_width = strlen(buffer);
+ 
  	/* Set the subject display width.
  	 * If it is too long, truncate it to fit.
  	 * If it is highlighted but not with the arrow  cursor,
***************
*** 393,415 ****
  	 * aesthetically the full length of the line.
  	 */
  	if ((highlight && !arrow_cursor)
! 		|| (COLUMNS-44 < (subj_width =strlen(entry->subject))))
! 	    subj_width = COLUMNS-44;
! 
! 	/* complete line with sender, length and subject. */
! 	sprintf(buffer + strlen(buffer), "%-*.*s (%d) %s%-*.*s",
! 		/* give max and min width parameters for 'from' */
! 		who_width,
! 		who_width,
! 		from,
! 
! 		entry->lines, 
! 		(entry->lines / 1000   > 0? ""   :	/* spacing the  */
! 		  entry->lines / 100   > 0? " "  :	/* same for the */
! 		    entry->lines / 10  > 0? "  " :	/* lines in ()  */
! 		                            "   "),     /*   [wierd]    */
! 
! 		subj_width, subj_width, entry->subject);
  }
  
  int
--- 430,448 ----
  	 * aesthetically the full length of the line.
  	 */
  	if ((highlight && !arrow_cursor)
! 		|| (elm_COLUMNS-header_without_subj_width 
! 		    < (subj_width = strlen(entry->subject))))
! 	    subj_width = elm_COLUMNS-header_without_subj_width;
! 
! 	if (header_without_subj_width + subj_width >= size -1)
! 	  subj_width = size - header_without_subj_width -1;
! 
! 	/* complete line with subject. */
! 	if (subj_width > 0)
! 	  elm_sfprintf(buffer + header_without_subj_width, 
! 		       size - header_without_subj_width,
! 		       FRM("%-*.*s"),
! 		       subj_width, subj_width, entry->subject);
  }
  
  int
***************
*** 448,455 ****
  	return(FALSE);
  }
  
! char *show_status(status)
  int status;
  {
  	/** This routine returns a pair of characters indicative of
  	    the status of this message.  The first character represents
--- 481,489 ----
  	return(FALSE);
  }
  
! char *show_status(status,hdr)
  int status;
+ struct header_rec *hdr;
  {
  	/** This routine returns a pair of characters indicative of
  	    the status of this message.  The first character represents
***************
*** 483,488 ****
--- 517,523 ----
  	else if (status & EXPIRED)	mybuffer[0] = 'E';
  	else if (status & NEW)		mybuffer[0] = 'N';
  	else if (status & UNREAD)	mybuffer[0] = 'O';
+         else if (status & REPLIED)	mybuffer[0] = 'r';
  	else                            mybuffer[0] = ' ';
  
  	/** and the second... **/
***************
*** 492,502 ****
  	else if (status & PRIVATE)      mybuffer[1] = 'P';
  	else if (status & ACTION)       mybuffer[1] = 'A';
  	else if (status & FORM_LETTER)  mybuffer[1] = 'F';
  #ifdef MIME
! 	else if ((status & MIME_MESSAGE) &&
! 		 ((status & MIME_NOTPLAIN) ||
! 		  (status & MIME_NEEDDECOD))) mybuffer[1] = 'M';
  #endif /* MIME */
  	else 			        mybuffer[1] = ' ';
  
  	mybuffer[2] = '\0';
--- 527,550 ----
  	else if (status & PRIVATE)      mybuffer[1] = 'P';
  	else if (status & ACTION)       mybuffer[1] = 'A';
  	else if (status & FORM_LETTER)  mybuffer[1] = 'F';
+ 	else if (hdr) {
+ 	  if (hdr->encrypted)                     mybuffer[1] = 'e';
  #ifdef MIME
! 	  else if ((status & MIME_MESSAGE) && (status & MIME_UNSUPPORTED))
! 	    mybuffer[1] = '?';
! 	  else if ((status & MIME_MESSAGE) && hdr->mime_rec.notplain)
! 	    mybuffer[1] = 'M';
! 	  else if ((status & PRE_MIME_CONTENT) && hdr->mime_rec.notplain)
! 	    mybuffer[1] = 'm';
  #endif /* MIME */
+ #ifdef USE_PGP
+ 	  else if (hdr->pgp & PGP_MESSAGE)	  mybuffer[1] = 'P';
+ 	  else if (hdr->pgp & PGP_SIGNED_MESSAGE) mybuffer[1] = 'S';
+ 	  else if (hdr->pgp & PGP_PUBLIC_KEY)	  mybuffer[1] = 'K';
+ #endif /* USE_PGP */
+ 	  else	    
+ 	    mybuffer[1] = ' ';
+ 	}
  	else 			        mybuffer[1] = ' ';
  
  	mybuffer[2] = '\0';
Index: elm2.4.ME+.50/src/showmsg.c
*** elm2.4.25/src/showmsg.c	Tue Aug 30 18:09:44 1994
--- elm2.4.ME+.50/src/showmsg.c	Tue Nov 17 21:12:58 1998
***************
*** 1,103 ****
  
! static char rcsid[] = "@(#)$Id: showmsg.c,v 5.16 1994/08/30 15:09:43 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.16 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: showmsg.c,v $
!  * Revision 5.16  1994/08/30  15:09:43  syd
!  * Block sigwinch when in the external pager.
!  * From: jwa@yog-sothoth.dcrt.nih.gov (James W. Adams)
!  *
!  * Revision 5.15  1993/08/23  02:46:07  syd
!  * Don't declare _exit() if <unistd.h> already did it.
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.14  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.13  1993/05/08  20:25:33  syd
!  * Add sleepmsg to control transient message delays
!  * From: Syd
!  *
!  * Revision 5.12  1993/02/03  19:06:31  syd
!  * Remove extra strchr/strcat/strcpy et al declarations
!  * From: Syd
!  *
!  * Revision 5.11  1993/01/20  04:01:07  syd
!  * Adds a new integer parameter builtinlines.
!  * if (builtinlines < 0) and (the length of the message < LINES on
!  *       screen + builtinlines) use internal.
!  * if (builtinlines > 0) and (length of message < builtinlines)
!  * 	use internal pager.
!  * if (builtinlines = 0) or none of the above conditions hold, use the
!  * external pager if defined.
!  * From: "John P. Rouillard" <rouilj@ra.cs.umb.edu>
!  *
!  * Revision 5.10  1993/01/19  05:11:45  syd
!  * Elm switches screens prematurely when calling metamail. It switches
!  * before writing the "Press any key..." message, thus losing metamail output.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.9  1992/12/07  04:29:12  syd
!  * add missing err declare
!  * From: Syd
!  *
!  * Revision 5.8  1992/11/26  01:46:26  syd
!  * add Decode option to copy_message, convert copy_message to
!  * use bit or for options.
!  * From: Syd and bjoerns@stud.cs.uit.no (Bjoern Stabell)
!  *
!  * Revision 5.7  1992/11/26  00:46:50  syd
!  * Fix how errno is used so err is inited and used instead
!  * as errno gets overwritten by print system call
!  * From: Syd
!  *
!  * Revision 5.6  1992/11/15  01:29:37  syd
!  * Clear the screen before displaying MIME:
!  * From: marius@rhi.hi.is (Marius Olafsson)
!  *
!  * Revision 5.5  1992/11/07  16:23:48  syd
!  * fix null dereferences from patch 5
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.4  1992/10/30  21:47:30  syd
!  * Use copy_message in mime shows to get encode processing
!  * From: bjoerns@stud.cs.uit.no (Bjoern Stabell)
!  *
!  * Revision 5.3  1992/10/25  01:47:45  syd
!  * fixed a bug were elm didn't call metamail on messages with a characterset,
!  * which could be displayed by elm itself, but message is encoded with QP
!  * or BASE64
!  * From: Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
!  *
!  * Revision 5.2  1992/10/24  13:35:39  syd
!  * changes found by using codecenter on Elm 2.4.3
!  * From: Graham Hudspith <gwh@inmos.co.uk>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This file contains all the routines needed to display the specified
      message.
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: showmsg.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This file contains all the routines needed to display the specified
      message.
***************
*** 104,130 ****
  **/
  
  #include "headers.h"
- #include "s_elm.h"
  #include <errno.h>
! 
! #ifdef BSD
! # include <sys/wait.h>
! #endif
! 
! #ifndef I_UNISTD
! void _exit();
! #endif
  
  extern int errno;
  
! extern char *elm_date_str(), *error_description();
  
! int    memory_lock = FALSE;	/* is it available?? */
! int    pipe_abort  = FALSE;	/* did we receive a SIGNAL(SIGPIPE)? */
  
! FILE *pipe_wr_fp;		/* file pointer to write to external pager */
! extern int lines_displayed,	/* defined in "builtin" */	
! 	   lines_put_on_screen;	/*    ditto too!        */
  
  int
  show_msg(number)
--- 17,49 ----
  **/
  
  #include "headers.h"
  #include <errno.h>
! #include "s_elm.h"
! #include "me.h"
  
  extern int errno;
  
! int pipe_abort = FALSE; /* not used anymore, but won't compile without it */
  
! #ifdef MIME
! static int
! need_meta (hdr)
! struct header_rec *hdr;
! {
!   /* Determine whether or not we need to call metamail to display the
!    * message contents.
!    */
!   int result = 0;
! 
!   if ((hdr->status & (MIME_MESSAGE)) && (hdr->status & MIME_UNSUPPORTED))
!       result = TRUE;
!   else if (hdr->status & (MIME_MESSAGE | PRE_MIME_CONTENT))
!     result = hdr->mime_rec.notplain;
  
!   dprint(9,(debugfile,"need_meta=%d\n",result));
!   return result;
! }
! #endif
  
  int
  show_msg(number)
***************
*** 140,183 ****
  	     the index screen (to be processed via process_showmsg_cmd()).
  	***/
  
- 	char title1[SLEN], title2[SLEN], title3[SLEN], titlebuf[SLEN];
- 	char who[LONG_STRING], buffer[VERY_LONG_STRING];
- #if defined(BSD) && !defined(WEXITSTATUS)
- 	union wait wait_stat;
- #else
- 	int wait_stat;
- #endif
- 
- 	int crypted = 0;			/* encryption */
- 	int weed_header, weeding_out = 0;	/* weeding    */ 
- 	int using_to,				/* misc use   */
- 	    pipe_fd[2],				/* pipe file descriptors */
- 	    new_pipe_fd,			/* dup'ed pipe fil des */
- 	    lines,				/* num lines in msg */
- 	    fork_ret,				/* fork return value */
- 	    wait_ret,				/* wait return value */
- 	    form_letter = FALSE,		/* Form ltr?  */
- 	    form_letter_section = 0,		/* section    */
- 	    padding = 0,			/*   counter  */
- 	    builtin = FALSE,			/* our pager? */
- 	    val = 0,				/* return val */
- 	    buf_len,				/* line length */
- 	    err;				/* place holder for errno */
  	struct header_rec *current_header = headers[number-1];
- #ifdef	SIGTSTP
- 	SIGHAND_TYPE	(*oldstop)(), (*oldcont)();
- #endif
- #ifdef	SIGWINCH
- 	SIGHAND_TYPE	(*oldwinch)();
- #endif
- 
- 	lines = current_header->lines; 
  
  	dprint(4, (debugfile,"displaying %d lines from message %d using %s\n", 
! 		lines, number, pager));
  
  	if (number > message_count || number < 1)
! 	  return(val);
  
  	if(ison(current_header->status, NEW)) {
  	  clearit(current_header->status, NEW);   /* it's been read now! */
--- 59,71 ----
  	     the index screen (to be processed via process_showmsg_cmd()).
  	***/
  
  	struct header_rec *current_header = headers[number-1];
  
  	dprint(4, (debugfile,"displaying %d lines from message %d using %s\n", 
! 		current_header->lines, number, pager));
  
  	if (number > message_count || number < 1)
! 	  return(0);
  
  	if(ison(current_header->status, NEW)) {
  	  clearit(current_header->status, NEW);   /* it's been read now! */
***************
*** 188,631 ****
  	  current_header->status_chgd = TRUE;
  	}
  
- 	memory_lock = FALSE;
- 
- 	/* some explanation for that last one - We COULD use memory locking
- 	   to speed up the paging, but the action of "ClearScreen" on a screen
- 	   with memory lock turned on seems to vary considerably (amazingly so)
- 	   so it's safer to only allow memory lock to be a viable bit of
- 	   trickery when dumping text to the screen in scroll mode.
- 	   Philosophical arguments should be forwarded to Bruce at the 
- 	   University of Walamazoo, Australia, via ACSNet  *wry chuckle* */
- 
  #ifdef MIME
! 	if ((current_header->status & MIME_MESSAGE) &&
! 	    ((current_header->status & MIME_NEEDDECOD) ||
! 	     (current_header->status & MIME_NOTPLAIN)) &&
! 	    !getenv("NOMETAMAIL") ) {
! 	    char fname[STRING], Cmd[SLEN], line[VERY_LONG_STRING];
! 	    int code, err;
! 	    long lines = current_header->lines;
! 	    FILE *fpout;
! 
! 	    if (fseek(mailfile, current_header->offset, 0) != -1) {
! 		sprintf(fname, "%semm.%d.%d", temp_dir, getpid(), getuid());
! 		if ((fpout = fopen(fname, "w")) != NULL) {
! 		    copy_message("", fpout, CM_DECODE);
! 		    (void) fclose (fpout);
! 		    sprintf(Cmd, "metamail -p -z -m Elm %s", fname);
! 		    Raw(OFF);
!                   ClearScreen();
! 		    code = system_call(Cmd, SY_ENAB_SIGINT);
! 		    Raw(ON | NO_TITE);	/* Raw on but don't switch screen */
! 		    (void) unlink (fname);
! 		    PutLine0(LINES,0, catgets(elm_msg_cat, ElmSet, ElmPressAnyKeyIndex,
! 			     "Press any key to return to index."));
! 		    (void) ReadCh();
! 		    printf("\r\n");
! 		    Raw(OFF | NO_TITE); /* Raw off so raw on takes effect */
! 		    Raw(ON); /* Finally raw on and switch screen */
  		    return(0);
  		}
! 	    }
! 	}
! #endif
! 
! 	if (fseek(mailfile, current_header->offset, 0) == -1) {
! 	  err = errno;
! 	  dprint(1, (debugfile,
! 		  "Error: seek %d bytes into file, errno %s (show_message)\n",
! 		  current_header->offset, error_description(err)));
! 	  error2(catgets(elm_msg_cat, ElmSet, ElmSeekFailedFile,
! 		  "ELM [seek] couldn't read %d bytes into file (%s)."),
! 		  current_header->offset, error_description(err));	
! 	  return(val);
! 	}
! 	if(current_header->encrypted)
! 	  getkey(OFF);
! 
! 	if(builtin=(first_word(pager,"builtin")||
! 	   first_word(pager,"internal"))||
! 	   ( builtin_lines < 0 ? lines < LINES + builtin_lines :
! 	    lines < builtin_lines))
! 
! 	  start_builtin(lines);
! 
! 	else {
! 
! 	  /* put terminal out of raw mode so external pager has normal env */
! 	  Raw(OFF);
! 
! 	  /* create pipe for external pager and fork */
! 
! 	  if(pipe(pipe_fd) == -1) {
! 	    err = errno;
! 	    dprint(1, (debugfile, "Error: pipe failed, errno %s (show_msg)\n",
! 	      error_description(err)));
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmPreparePagerPipe,
! 	      "Could not prepare for external pager(pipe()-%s)."),
! 	      error_description(err));	
! 	    Raw(ON);
! 	    return(val);
! 	  }
! 
! 	  if((fork_ret = fork()) == -1) {
! 
! 	    err = errno;
! 	    dprint(1, (debugfile, "Error: fork failed, errno %s (show_msg)\n",
! 	      error_description(err)));
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmPreparePagerFork,
! 	      "Could not prepare for external pager(fork()-%s)."),
! 	      error_description(err));	
! 	    Raw(ON);
! 	    return(val);
! 
! 	  } else if (fork_ret == 0) {
! 
! 	    /* child fork */
! 
! 	    /* close write-only pipe fd and fit read-only pipe fd to stdin */
! 
! 	    close(pipe_fd[1]);
! 	    close(fileno(stdin));
! 	    if((new_pipe_fd = dup(pipe_fd[0])) == -1) {
! 	      err = errno;
! 	      dprint(1, (debugfile, "Error: dup failed, errno %s (show_msg)\n",
! 		error_description(err)));
! 	      error1(catgets(elm_msg_cat, ElmSet, ElmPreparePagerDup,
! 	        "Could not prepare for external pager(dup()-%s)."),
! 		error_description(err));	
! 	      _exit(err);
! 	    }
! 	    close(pipe_fd[0]);	/* original pipe fd no longer needed */
! 
! 	    /* use stdio on new pipe fd */
! 	    if(fdopen(new_pipe_fd, "r") == NULL) {
! 	      err = errno;
! 	      dprint(1,
! 		(debugfile, "Error: child fdopen failed, errno %s (show_msg)\n",
! 		error_description(err)));
! 	      error1(catgets(elm_msg_cat, ElmSet, ElmPreparePagerChildFdopen,
! 		"Could not prepare for external pager(child fdopen()-%s)."),
! 		error_description(err));	
! 	      _exit(err);
! 	    }
! 
! 	    /* now execute pager and exit */
! 	    
! 	    /* system_call() will return user to user's normal permissions.
! 	     * This is what makes this pipe secure - user won't have elm's
! 	     * special setgid permissions (if so configured) and will only
! 	     * be able to execute a pager that user normally has permission
! 	     * to execute */
! 
! 	    _exit(system_call(pager, SY_ENAB_SIGINT));
! 	  
! 	  } /* else this is the parent fork */
! 
! 	  /* close read-only pipe fd and do write-only with stdio */
! 	  close(pipe_fd[0]);
! 
! 	  if((pipe_wr_fp = fdopen(pipe_fd[1], "w")) == NULL) {
! 	    err = errno;
! 	    dprint(1,
! 	      (debugfile, "Error: parent fdopen failed, errno %s (show_msg)\n",
! 	      error_description(err)));
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmPreparePagerParentFdopen,
! 	      "Could not prepare for external pager(parent fdopen()-%s)."),
! 	      error_description(err));	
! 
! 	    /* Failure - must close pipe and wait for child */
! 	    close(pipe_fd[1]);
! 	    while ((wait_ret = wait(&wait_stat)) != fork_ret && wait_ret!= -1)
! 	      ;
! 
! 	    Raw(OFF);
! 	    return(val);	/* pager may have already touched the screen */
! 	  }
! 
! 	  /* and that's it! */
! 	  lines_displayed = 0;
! #ifdef	SIGTSTP
! 	  oldstop = signal(SIGTSTP,SIG_DFL);
! 	  oldcont = signal(SIGCONT,SIG_DFL);
! #endif 
! #ifdef	SIGWINCH
! 	  oldwinch = signal(SIGWINCH,SIG_DFL);
! #endif
! 	}
! 
! 	ClearScreen();
! 
! 	if (cursor_control) transmit_functions(OFF);
! 
! 	pipe_abort = FALSE;
! 
! 	if (form_letter = (current_header->status&FORM_LETTER)) {
! 	  if (filter)
! 	    form_letter_section = 1;	/* initialize to section 1 */
! 	}
! 
! 	if (title_messages && filter) {
! 
! 	  using_to =
! 	    tail_of(current_header->from, who, current_header->to);
! 
! 	  MCsprintf(title1, "%s %d/%d  ",
! 		    headers[current-1]->status & DELETED ? nls_deleted :
! 		    form_letter ? nls_form: nls_message,
! 		    number, message_count);
! 	  MCsprintf(title2, "%s %s", using_to? nls_to : nls_from, who);
! 	  elm_date_str(title3, current_header->time_sent + current_header->tz_offset);
! 	  strcat(title3, " ");
! 	  strcat(title3, current_header->time_zone);
! 
! 	  /* truncate or pad title2 portion on the right
! 	   * so that line fits exactly */
! 	  padding =
! 	    COLUMNS -
! 	    (strlen(title1) + (buf_len=strlen(title2)) + strlen(title3));
! 
! 	  sprintf(titlebuf, "%s%-*.*s%s\n", title1, buf_len+padding,
! 	      buf_len+padding, title2, title3);
! 
! 	  if (builtin)
! 	    display_line(titlebuf, strlen(titlebuf));
! 	  else
! 	    fprintf(pipe_wr_fp, "%s", titlebuf);
! 
! 	  /** if there's a subject, let's output it next,
! 	      centered if it fits on a single line.  **/
! 
! 	  if ((buf_len = strlen(current_header->subject)) > 0 && 
! 		matches_weedlist("Subject:")) {
! 	    padding = (buf_len < COLUMNS ? COLUMNS - buf_len : 0);
! 	    sprintf(buffer, "%*s%s\n", padding/2, "", current_header->subject);
! 	  } else
! 	    strcpy(buffer, "\n");
! 
! 	  if (builtin)
! 	    display_line(buffer, strlen(buffer));
! 	  else
! 	    fprintf(pipe_wr_fp, "%s", buffer);
! 	  
! 	  /** was this message address to us?  if not, then to whom? **/
! 
! 	  if (! using_to && matches_weedlist("To:") && filter &&
! 	      strcmp(current_header->to,username) != 0 &&
! 	      strlen(current_header->to) > 0) {
! 	    sprintf(buffer, catgets(elm_msg_cat, ElmSet, ElmMessageAddressedTo,
! 		  "%s(message addressed to %.60s)\n"), 
! 	          strlen(current_header->subject) > 0 ? "\n" : "",
! 		  current_header->to);
! 	    if (builtin)
! 	      display_line(buffer, strlen(buffer));
! 	    else
! 	      fprintf(pipe_wr_fp, "%s", buffer);
! 	  }
! 	
! 	  /** The test above is: if we didn't originally send the mail
! 	      (e.g. we're not reading "mail.sent") AND the user is currently
! 	      weeding out the "To:" line (otherwise they'll get it twice!)
! 	      AND the user is actually weeding out headers AND the message 
! 	      wasn't addressed to the user AND the 'to' address is non-zero 
! 	      (consider what happens when the message doesn't HAVE a "To:" 
! 	      line...the value is NULL but it doesn't match the username 
! 	      either.  We don't want to display something ugly like 
! 	      "(message addressed to )" which will just clutter up the 
! 	      screen!).
! 
! 	      And you thought programming was EASY!!!!
! 	  **/
! 
! 	  /** one more friendly thing - output a line indicating what sort
! 	      of status the message has (e.g. Urgent etc).  Mostly added
! 	      for X.400 support, this is nonetheless generally useful to
! 	      include...
! 	  **/
! 
! 	  buffer[0] = '\0';
! 
! 	  /* we want to flag Urgent, Confidential, Private and Expired tags */
! 
! 	  if (current_header->status & PRIVATE)
! 	    strcpy(buffer, catgets(elm_msg_cat, ElmSet, ElmTaggedPrivate,
! 		"\n(** This message is tagged Private"));
! 	  else if (current_header->status & CONFIDENTIAL) 
! 	    strcpy(buffer, catgets(elm_msg_cat, ElmSet, ElmTaggedCompanyConfidential,
! 		"\n(** This message is tagged Company Confidential"));
! 
! 	  if (current_header->status & URGENT) {
! 	    if (buffer[0] == '\0')
! 	      strcpy(buffer, catgets(elm_msg_cat, ElmSet, ElmTaggedUrgent,
! 		"\n(** This message is tagged Urgent"));
! 	    else if (current_header->status & EXPIRED)
! 	      strcat(buffer, catgets(elm_msg_cat, ElmSet, ElmCommaUrgent, ", Urgent"));
! 	    else
! 	      strcat(buffer, catgets(elm_msg_cat, ElmSet, ElmAndUrgent, " and Urgent"));
! 	  }
! 
! 	  if (current_header->status & EXPIRED) {
! 	    if (buffer[0] == '\0')
! 	      strcpy(buffer, catgets(elm_msg_cat, ElmSet, ElmMessageHasExpired,
! 		"\n(** This message has Expired"));
! 	    else
! 	      strcat(buffer, catgets(elm_msg_cat, ElmSet, ElmAndHasExpired,
! 		", and has Expired"));
! 	  }
! 
! 	  if (buffer[0] != '\0') {
! 	    strcat(buffer, " **)\n");
! 	    if (builtin)
! 	      display_line(buffer, strlen(buffer));
! 	    else
! 	      fprintf(pipe_wr_fp, buffer);
! 	  }
! 
! 	  if (builtin)			/* this is for a one-line blank    */
! 	    display_line("\n",1);	/*   separator between the title   */
! 	  else				/*   stuff and the actual message  */
! 	    fprintf(pipe_wr_fp, "\n");	/*   we're trying to display       */
! 
! 	}
! 
! 	weed_header = filter;	/* allow us to change it after header */
! 
! 	while (lines > 0 && pipe_abort == FALSE) {
! 
! 	    if ((buf_len = mail_gets(buffer, VERY_LONG_STRING, mailfile)) == 0) {
! 
! 	      dprint(1, (debugfile,
! 		"Premature end of file! Lines left = %d msg = %s (show_msg)\n",
! 		lines, number));
! 
! 	      error(catgets(elm_msg_cat, ElmSet, ElmPrematureEndOfFile,
! 		"Premature end of file!"));
! 	      if (sleepmsg > 0)
! 		    sleep(sleepmsg);
! 	      break;
! 	    }
! 	    if (buf_len > 0)  {
! 	      if(buffer[buf_len - 1] == '\n') {
! 	        lines--;
! 	        lines_displayed++;
  		}
! 	      while(buf_len > 0 && (buffer[buf_len - 1] == '\n'
! 				    ||buffer[buf_len - 1] == '\r'))
! 		--buf_len;
! 	    }
! 
!   	    if (buf_len == 0) {
! 	      weed_header = 0;		/* past header! */
! 	      weeding_out = 0;
! 	    }
! 
! 	    if (form_letter && weed_header)
! 		/* skip it.  NEVER display random headers in forms! */;
! 	    else if (weed_header && matches_weedlist(buffer)) 
! 	      weeding_out = 1;	 /* aha!  We don't want to see this! */
! 	    else if (buffer[0] == '[') {
! 	      if (strncmp(buffer, START_ENCODE, strlen(START_ENCODE))==0)
! 	        crypted = ON;
! 	      else if (strncmp(buffer, END_ENCODE, strlen(END_ENCODE))==0)
! 	        crypted = OFF;
! 	      else if (crypted) {
!                 encode(buffer);
! 	        val = show_line(buffer, buf_len, builtin);
! 	      }
! 	      else
! 	        val = show_line(buffer, buf_len, builtin);
! 	    } 
! 	    else if (crypted) {
! 	      encode(buffer);
! 	      val = show_line(buffer, buf_len, builtin); 
! 	    }
! 	    else if (weeding_out) {
! 	      weeding_out = (whitespace(buffer[0]));	/* 'n' line weed */
! 	      if (! weeding_out) 	/* just turned on! */
! 	        val = show_line(buffer, buf_len, builtin);
! 	    } 
! 	    else if (form_letter && first_word(buffer,"***") && filter) {
! 	      strcpy(buffer,
! "\n------------------------------------------------------------------------------\n");
! 	      val = show_line(buffer, buf_len, builtin);	/* hide '***' */
! 	      form_letter_section++;
! 	    }
! 	    else if (form_letter_section == 1 || form_letter_section == 3)
! 	      /** skip this stuff - we can't deal with it... **/;
! 	    else
! 	      val = show_line(buffer, buf_len, builtin);
! 	
! 	    if (val != 0)	/* discontinue the display */
! 	      break;
  	}
- 
-         if (cursor_control) transmit_functions(ON);
- 
- 	if (!builtin) {
- 	  fclose(pipe_wr_fp);
- 	  while ((wait_ret = wait(&wait_stat)) != fork_ret
- 		  && wait_ret!= -1)
- 	    ;
- 	  /* turn raw on **after** child terminates in case child
- 	   * doesn't put us back to cooked mode after we return ourselves
- 	   * to raw.
- 	   */
- 	  Raw(ON);
- #ifdef	SIGTSTP
- 	  (void)signal(SIGTSTP,oldstop);
- 	  (void)signal(SIGCONT,oldcont);
  #endif
! #ifdef	SIGWINCH
! 	  (void)signal(SIGWINCH,oldwinch);
! #endif
! 	}
! 
! 	/* If we are to prompt for a user input command and we don't
! 	 * already have one */
! 	if ((prompt_after_pager || builtin) && val == 0) {
! 	  MoveCursor(LINES,0);
! 	  StartBold();
! 	  Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmCommandIToReturn,
! 		" Command ('i' to return to index): "), 0);
! 	  EndBold();
! 	  fflush(stdout);
! 	  val = ReadCh();
! 	}
! 	
! 	if (memory_lock) EndMemlock();	/* turn it off!! */
! 
! 	/* 'q' means quit current operation and pop back up to previous level -
! 	 * in this case it therefore means return to index screen.
! 	 */
! 	return(val == 'i' || val == 'q' ? 0 : val);
! }
! 
! int
! show_line(buffer, buf_len, builtin)
! char *buffer;
! int  buf_len;
! int  builtin;
! {
! 	/** Hands the given line to the output pipe.  'builtin' is true if
! 	    we're using the builtin pager.
! 	    Return the character entered by the user to indicate
! 	    a command other than continuing with the display (only possible
! 	    with the builtin pager), otherwise 0. **/
! 
! 	strcpy(buffer + buf_len, "\n");
! 	++buf_len;
! #ifdef MMDF
! 	if (strncmp(buffer, MSG_SEPARATOR, buf_len) == 0)
! 	  return(0);	/* no reason to show the ending terminator */
! #endif /* MMDF */
! 	if (builtin) {
! 	  return(display_line(buffer, buf_len));
! 	}
! 	errno = 0;
! 	fprintf(pipe_wr_fp, "%s", buffer);
! 	if (errno != 0)
! 	  dprint(1, (debugfile, "\terror %s hit!\n", error_description(errno)));
! 	return(0);
  }
- 
--- 76,140 ----
  	  current_header->status_chgd = TRUE;
  	}
  
  #ifdef MIME
! 	/* May need recheck: (Because now defination is recursive) */
! 	if ((current_header->status & MIME_MESSAGE) && 
! 	    current_header->mime_rec.notplain)
! 	  attach_parse(current_header,mailfile);
! 
!         if (need_meta(current_header) && have_metamail()) {
! 		char fname[STRING], Cmd[SLEN], line[VERY_LONG_STRING];
! 		int code, err;
! 		long lines = current_header->lines;
! 		FILE *fpout;
! 
! 		if (fseek(mailfile, current_header->offset, 0) == -1) {
! 		    err = errno;
! 		    dprint(1, (debugfile,
! 		      "Error: seek %d bytes into file, errno %s (show_message)\n",
! 		      current_header->offset, error_description(err)));
! 		    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSeekFailedFile,
! 				      "ELM [seek] couldn't read %d bytes into file (%s)."),
! 			      current_header->offset, error_description(err)); 
  		    return(0);
  		}
! 		elm_sfprintf(fname, sizeof fname,
! 			     FRM("%semm.%d.%d"), temp_dir, getpid(), getuid());
! 		if ((fpout = safeopen_rdwr(fname)) == NULL) {
! 		  err = errno;
! 		  dprint(1, (debugfile,
! 			     "Error: open of temporary file %s, errno %s (show_message)\n",
! 			     fname, error_description(err)));
! 		  lib_error(CATGETS(elm_msg_cat, ElmSet, 
! 				    ElmCantOpenAsOutputFile,
! 				    "Can't open \"%s\" as output file! (%s)."),
! 			    fname, error_description(err));
! 		  return(0);
  		}
! 		/* Let metamail decode it! 
! 		 * (Now CM_DECODE also decodes MIME and PGP) -KEH
! 		 */
! 		copy_message(mailfile,current_header,
! 			     "", fpout, 0);
! 		(void) fclose (fpout);
! 		elm_sfprintf(Cmd, sizeof Cmd,
! 			     FRM("%s -p -z -m Elm %s"), 
! 			     metamail_path, fname);
! 		Raw(OFF);
! 		ClearScreen();
! 		printf ("Executing metamail...\n");
! 		code = system_call(Cmd, SY_ENAB_SIGINT|SY_ENV_METAMAIL);
! 		Raw(ON | NO_TITE);	/* Raw on but don't switch screen */
! 		(void) unlink (fname);
! 		PutLine0(elm_LINES,0, catgets(elm_msg_cat, ElmSet, 
! 					      ElmPressAnyKeyIndex,
! 			     "Press any key to return to index."));
! 		(void) ReadCh(0);
! 		printf("\r\n");
! 		Raw(OFF | NO_TITE); /* Raw off so raw on takes effect */
! 		Raw(ON); /* Finally raw on and switch screen */
! 		return(0);
  	}
  #endif
!         return (metapager (mailfile, current_header, TRUE));
  }
Index: elm2.4.ME+.50/src/showmsg_c.c
*** elm2.4.25/src/showmsg_c.c	Fri Mar 11 23:25:27 1994
--- elm2.4.ME+.50/src/showmsg_c.c	Tue Nov 17 21:12:57 1998
***************
*** 1,38 ****
  
! static char rcsid[] = "@(#)$Id: showmsg_c.c,v 5.4 1994/03/11 21:25:24 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: showmsg_c.c,v $
!  * Revision 5.4  1994/03/11  21:25:24  syd
!  * Fix Elm looping if an EOF is received.
!  * From: Gregory Neil Shapiro <gshapiro@WPI.EDU>
!  *
!  * Revision 5.3  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.2  1992/11/07  19:37:21  syd
!  * Enhanced printing support.  Added "-I" to readmsg to
!  * suppress spurious diagnostic messages.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This is an interface for the showmsg command line.  The possible
      functions that could be invoked from the showmsg command line are
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: showmsg_c.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
!  *
!  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
!  ******************************************************************************
!  *  The Elm Mail System 
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This is an interface for the showmsg command line.  The possible
      functions that could be invoked from the showmsg command line are
***************
*** 59,64 ****
--- 37,43 ----
  	   s    = save this message to a maibox/folder 
  	   t    = tag this message
  	   u    = undelete message
+            v    = view attachments
  	   x    = Exit Elm NOW 
  
      all commands not explicitly listed here are beeped at.  Use i)ndex
***************
*** 70,82 ****
  
  #include "headers.h"
  #include "s_elm.h"
  
  int	screen_mangled = 0;
  char    msg_line[SLEN];
  static	char *put_help_prompt = NULL;
! #define store_msg(a)	(void)strcpy(msg_line,a)
! #define put_prompt()	PutLine0(LINES-3, 0, Prompt)
! #define put_help()	PutLine0(LINES-3, 45, put_help_prompt)
  #define POST_PROMPT_COL	strlen(Prompt)
  
  
--- 49,62 ----
  
  #include "headers.h"
  #include "s_elm.h"
+ #include "me.h"
  
  int	screen_mangled = 0;
  char    msg_line[SLEN];
  static	char *put_help_prompt = NULL;
! #define store_msg(a)	strfcpy(msg_line,a, sizeof msg_line)
! #define put_prompt()	PutLine0(elm_LINES-3, 0, Prompt)
! #define put_help()	PutLine0(elm_LINES-3, 45, put_help_prompt)
  #define POST_PROMPT_COL	strlen(Prompt)
  
  
***************
*** 132,138 ****
  
  	    case '%' : put_cmd_name(catgets(elm_msg_cat, ElmSet, ElmDisplayReturnAdd,
  				"Display return address"), TRUE);
! 		       get_return(msg_line, current-1);
  		       break;
  
  	    case 'b' : put_cmd_name(catgets(elm_msg_cat, ElmSet, ElmBounceMessage,
--- 112,118 ----
  
  	    case '%' : put_cmd_name(catgets(elm_msg_cat, ElmSet, ElmDisplayReturnAdd,
  				"Display return address"), TRUE);
! 		       get_return(msg_line, current-1, sizeof msg_line);
  		       break;
  
  	    case 'b' : put_cmd_name(catgets(elm_msg_cat, ElmSet, ElmBounceMessage,
***************
*** 148,153 ****
--- 128,148 ----
  			 goto next_undel_msg;
  		       break;
  
+ #ifdef USE_PGP
+             case ctrl('E'):
+ 			put_cmd_name("Extract PGP public key", TRUE);
+ 			if (headers[current-1]->pgp & PGP_PUBLIC_KEY)
+ 				pgp_extract_public_key ();
+ 			else
+ 				store_msg("This message does not contain any keys!");
+ 			break;
+ 
+ 	  case ctrl('F'):
+ 	    put_cmd_name("Forget PGP passphrase", TRUE);
+ 	    pgp_void_passphrase();
+ 	    error("Passphrase forgotten!");
+ 	    break;
+ #endif
  	    case 'f' : put_cmd_name(catgets(elm_msg_cat, ElmSet, ElmForwardMessage,
  				"Forward message"), TRUE);
  		       if(forward()) put_border();
***************
*** 159,168 ****
  		       break;
  
  	    case 'h' : screen_mangled = 0;
! 		       if (filter) { 
! 		         filter = 0; 
  		         intbuf = show_msg(current); 
! 		         filter = 1;
  			 return(intbuf);
  		       } else
  		         return(show_msg(current)); 
--- 154,163 ----
  		       break;
  
  	    case 'h' : screen_mangled = 0;
! 		       if (elm_filter) { 
! 		         elm_filter = 0; 
  		         intbuf = show_msg(current); 
! 		         elm_filter = 1;
  			 return(intbuf);
  		       } else
  		         return(show_msg(current)); 
***************
*** 170,182 ****
  	    case 'q' :
  	    case 'i' : (void) get_page(current);
  		       clear_error();		/* zero out pending msg   */
- 		       if (cursor_control)
- 			 transmit_functions(ON);
  		       screen_mangled = 0;
  		       return(0);		/* avoid <return> looping */
   
  next_undel_msg :	/* a target for resolve mode actions */
  
  	    case ' ' :
  	    case 'j' :
  	    case 'n' : screen_mangled = 0;
--- 165,176 ----
  	    case 'q' :
  	    case 'i' : (void) get_page(current);
  		       clear_error();		/* zero out pending msg   */
  		       screen_mangled = 0;
  		       return(0);		/* avoid <return> looping */
   
  next_undel_msg :	/* a target for resolve mode actions */
  
+ 	  case DOWN_MARK :
  	    case ' ' :
  	    case 'j' :
  	    case 'n' : screen_mangled = 0;
***************
*** 191,196 ****
--- 185,191 ----
  		       else return(0);
  
  prev_undel_msg:
+ 	  case UP_MARK:
  	    case 'k' : screen_mangled = 0;
  		       if((i=prev_message(current-1, TRUE)) != -1)
  			 return(show_msg(current = i+1));
***************
*** 203,211 ****
  
  	    case 'm' : put_cmd_name(catgets(elm_msg_cat, ElmSet, ElmMailMessage,
  				"Mail message"), TRUE);
! 		       if(send_msg("","","", TRUE, allow_forms, FALSE))
  			 put_border();
! 		       break;
  
  	    case 'p' : put_cmd_name(catgets(elm_msg_cat, ElmSet, ElmPrintMessage,
  				"Print message"), FALSE);
--- 198,206 ----
  
  	    case 'm' : put_cmd_name(catgets(elm_msg_cat, ElmSet, ElmMailMessage,
  				"Mail message"), TRUE);
! 	               if(send_msg("","","", MAIL_EDIT_MSG, allow_forms))
  			 put_border();
! 	               break;
  
  	    case 'p' : put_cmd_name(catgets(elm_msg_cat, ElmSet, ElmPrintMessage,
  				"Print message"), FALSE);
***************
*** 225,230 ****
--- 220,226 ----
  			 goto next_undel_msg;
  		       break;
  
+ 	    case 'T' :
  	    case 't' : istagged=tag_message(FALSE);	
  		       if(istagged)
  			 store_msg(catgets(elm_msg_cat, ElmSet, ElmMessageTagged,
***************
*** 232,237 ****
--- 228,235 ----
  		       else 
  			 store_msg(catgets(elm_msg_cat, ElmSet, ElmMessageUntagged,
  				"Message untagged."));
+ 	               if (command == 'T')
+ 			 goto next_undel_msg;
  		       break;
  
  	    case 'u' : undelete_msg(FALSE); /* undelete it, silently */
***************
*** 249,255 ****
  			 goto next_msg;
  		       }
  		       break;
! 
  	    case 'X' : put_cmd_name(catgets(elm_msg_cat, ElmSet, ElmQuickExit,
  				"Quick Exit"), TRUE);
  		       leave(0);
--- 247,275 ----
  			 goto next_msg;
  		       }
  		       break;
! #ifdef MIME
! 	    case 'v' :
! 	      if (headers) {         
! 		if (headers[current-1]->status & MIME_MESSAGE) {
! 		  mime_warnings(headers[current-1]);
! 
! 		  attach_parse (headers[current-1], mailfile);
! 		  if (headers[current-1]->mime_rec.parts)
! 		    (void) attach_menu (headers[current-1]->
! 					mime_rec.parts, TRUE);
! 		  else 
! 		    /* So we can save mail in decoded ... */
! 		    (void) attach_menu (&(headers[current-1]->
! 					  mime_rec),TRUE);
! 		  redraw++;
! 		}
! 		else
! 		  error ("This is not a MIME message!");
! 	      }
! 	      else
! 		error ("There are no messages!");
! 	      return(0);
! #endif
  	    case 'X' : put_cmd_name(catgets(elm_msg_cat, ElmSet, ElmQuickExit,
  				"Quick Exit"), TRUE);
  		       leave(0);
***************
*** 266,305 ****
  	    case EOF    : leave(0);
                            break;
  
-             case ESCAPE : if (cursor_control) {
-   
-                             key_offset = 1;
-   
-                             ch = ReadCh(); 
-   
-                             if (ch == ESCAPE)
-                              ch = ReadCh();
-   
-                             if ( ch == '[' || ch == 'O') 
-                             {
-                               ch = ReadCh();
-                               key_offset++;
-                             }
-   
-                             if (ch == up[key_offset])
- 			      goto prev_undel_msg;
-                             else if (ch == down[key_offset])
- 			      goto next_undel_msg;
-                             else {
- 			      screen_mangled = 0;
-                               return(0);
- 			    }
-                           }
-                           else          /* Eat 2 chars for escape codes */
-                           {
-                             ch = ReadCh();
-                             ch = ReadCh();
-                             putchar((char) 007);
-                             fflush(stdout);
- 			    screen_mangled = 0;
-                             return(0);
-                            }
-   
  	    default  : putchar((char) 007);	/* BEEP! */
  	  }
  
--- 286,291 ----
***************
*** 311,331 ****
  	    put_prompt();
  	    CleartoEOS();
  	    put_help();
! 	    Centerline(LINES, msg_line);
! 	    MoveCursor(LINES-3, POST_PROMPT_COL);
  	  } else {
  	    /* display bottom line prompt with last generated message */
! 	    MoveCursor(LINES, 0);
  	    CleartoEOS();
  	    StartBold();
! 	    Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmCommandLine,
! 		"%s Command ('i' to return to index): "),
! 		1, msg_line);
  	    EndBold();
  	  }
  	  *msg_line = '\0';	/* null last generated message */
  
! 	  command = ReadCh();	/* get next command from user */
  	}
  }
  
--- 297,317 ----
  	    put_prompt();
  	    CleartoEOS();
  	    put_help();
! 	    Centerline(elm_LINES, msg_line);
! 	    MoveCursor(elm_LINES-3, POST_PROMPT_COL);
  	  } else {
  	    /* display bottom line prompt with last generated message */
! 	    MoveCursor(elm_LINES, 0);
  	    CleartoEOS();
  	    StartBold();
! 	    Write_to_screen(CATGETS(elm_msg_cat, ElmSet, ElmCommandLine,
! 				    "%s Command ('i' to return to index): "),
! 			    msg_line);
  	    EndBold();
  	  }
  	  *msg_line = '\0';	/* null last generated message */
  
! 	  command = ReadCh('i'|READCH_CURSOR);   /* get next command from user */
  	}
  }
  
***************
*** 343,349 ****
  	  screen_mangled = TRUE;
  	}
  	if(screen_mangled) {
! 	  PutLine0(LINES-3, POST_PROMPT_COL, command);
  	  CleartoEOS();
  	}
  }
--- 329,335 ----
  	  screen_mangled = TRUE;
  	}
  	if(screen_mangled) {
! 	  PutLine0(elm_LINES-3, POST_PROMPT_COL, command);
  	  CleartoEOS();
  	}
  }
***************
*** 350,362 ****
  
  put_border()
  {
! 	 PutLine0(LINES-4, 0, 
  "--------------------------------------------------------------------------\n");
  }
  
  build_bottom()
  {
! 	 MoveCursor(LINES-4, 0);
  	 CleartoEOS();
  	 put_border();
  	 put_prompt();
--- 336,348 ----
  
  put_border()
  {
! 	 PutLine0(elm_LINES-4, 0, 
  "--------------------------------------------------------------------------\n");
  }
  
  build_bottom()
  {
! 	 MoveCursor(elm_LINES-4, 0);
  	 CleartoEOS();
  	 put_border();
  	 put_prompt();
Index: elm2.4.ME+.50/src/signals.c
*** elm2.4.25/src/signals.c	Thu Sep  1 22:42:41 1994
--- elm2.4.ME+.50/src/signals.c	Tue Nov 17 21:12:57 1998
***************
*** 1,76 ****
  
! static char rcsid[] = "@(#)$Id: signals.c,v 5.13 1994/09/01 19:42:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.13 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: signals.c,v $
!  * Revision 5.13  1994/09/01  19:42:39  syd
!  * Moved #defines for SETJMP & LONGJMP from src/editmsg.c to hdrs/defs.h and
!  * used them instead of (set|long)jmp directly. This makes the usage consistent
!  * and Solaris 2.3 behaves correctly w.r.t stop/continue.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.12  1994/08/30  18:59:38  syd
!  * add sigcont to release list
!  *
!  * Revision 5.11  1994/08/30  18:27:47  syd
!  * fix typo
!  *
!  * Revision 5.10  1994/08/30  18:16:05  syd
!  * Fix up Solaris and SVR4 signal handling for timeout
!  * From: Syd
!  *
!  * Revision 5.9  1993/08/03  19:10:50  syd
!  * Patch for Elm 2.4 PL22 to correct handling of SIGWINCH signals on
!  * DecStations with Ultrix 4.2.
!  * The problem was that elm running in an xterm exits silently when the
!  * window is resize. This was caused by incorrect signal handling for BSD.
!  * From: vogt@isa.de
!  *
!  * Revision 5.8  1993/04/12  03:04:58  syd
!  * The USR2 signal lost messages on some OS:es and did an unnecessary resync
!  * on others.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.7  1993/01/20  03:43:37  syd
!  * Some systems dont have SIGBUS, make it optional
!  *
!  * Revision 5.6  1992/12/11  02:39:53  syd
!  * A try at making USR? not loose mailbox
!  *
!  * Revision 5.5  1992/12/07  02:41:21  syd
!  * This implements the use of SIGUSR1 and SIGUSR2 as discussed on the
!  * mailing list recently, and adds them to the documentation.
!  * From: scs@lokkur.dexter.mi.us (Steve Simmons)
!  *
!  * Revision 5.4  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.3  1992/10/27  01:43:40  syd
!  * Move posix_signal to lib directory
!  * From: tom@osf.org
!  *
!  * Revision 5.2  1992/10/25  02:01:58  syd
!  * Here are the patches to support POSIX sigaction().
!  * From: tom@osf.org
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This set of routines traps various signals and informs the
      user of the error, leaving the program in a nice, graceful
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: signals.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This set of routines traps various signals and informs the
      user of the error, leaving the program in a nice, graceful
***************
*** 87,93 ****
  quit_signal(sig)
  {
  	dprint(1, (debugfile, "\n\n** Received SIGQUIT **\n\n\n\n"));
! 	leave(0);
  }
  
  SIGHAND_TYPE
--- 27,33 ----
  quit_signal(sig)
  {
  	dprint(1, (debugfile, "\n\n** Received SIGQUIT **\n\n\n\n"));
! 	leave(!InGetPrompt);
  }
  
  SIGHAND_TYPE
***************
*** 94,100 ****
  hup_signal(sig)
  {
  	dprint(1, (debugfile, "\n\n** Received SIGHUP **\n\n\n\n"));
! 	leave(0);
  }
  
  SIGHAND_TYPE
--- 34,40 ----
  hup_signal(sig)
  {
  	dprint(1, (debugfile, "\n\n** Received SIGHUP **\n\n\n\n"));
! 	leave(!InGetPrompt);
  }
  
  SIGHAND_TYPE
***************
*** 101,129 ****
  term_signal(sig) 
  {
  	dprint(1, (debugfile, "\n\n** Received SIGTERM **\n\n\n\n"));
! 	leave(0);
  }
  
  SIGHAND_TYPE
  ill_signal(sig)
  {
! 	MoveCursor(LINES,0);
  	Raw(OFF);
  	dprint(1, (debugfile, "\n\n** Received SIGILL **\n\n\n\n"));
  	printf(catgets(elm_msg_cat, ElmSet, ElmIllegalInstructionSignal,
  		"\n\nIllegal Instruction signal!\n\n"));
! 	emergency_exit();
  }
  
  SIGHAND_TYPE
  fpe_signal(sig)  
  {
! 	MoveCursor(LINES,0);
  	Raw(OFF);
  	dprint(1, (debugfile, "\n\n** Received SIGFPE **\n\n\n\n"));
  	printf(catgets(elm_msg_cat, ElmSet, ElmFloatingPointSignal,
  		"\n\nFloating Point Exception signal!\n\n"));
! 	emergency_exit();
  }
  
  #ifdef SIGBUS
--- 41,69 ----
  term_signal(sig) 
  {
  	dprint(1, (debugfile, "\n\n** Received SIGTERM **\n\n\n\n"));
! 	leave(!InGetPrompt);
  }
  
  SIGHAND_TYPE
  ill_signal(sig)
  {
! 	MoveCursor(elm_LINES,0);
  	Raw(OFF);
  	dprint(1, (debugfile, "\n\n** Received SIGILL **\n\n\n\n"));
  	printf(catgets(elm_msg_cat, ElmSet, ElmIllegalInstructionSignal,
  		"\n\nIllegal Instruction signal!\n\n"));
! 	emergency_exit(!InGetPrompt);
  }
  
  SIGHAND_TYPE
  fpe_signal(sig)  
  {
! 	MoveCursor(elm_LINES,0);
  	Raw(OFF);
  	dprint(1, (debugfile, "\n\n** Received SIGFPE **\n\n\n\n"));
  	printf(catgets(elm_msg_cat, ElmSet, ElmFloatingPointSignal,
  		"\n\nFloating Point Exception signal!\n\n"));
! 	emergency_exit(!InGetPrompt);
  }
  
  #ifdef SIGBUS
***************
*** 130,141 ****
  SIGHAND_TYPE
  bus_signal(sig)
  {
! 	MoveCursor(LINES,0);
  	Raw(OFF);
  	dprint(1, (debugfile, "\n\n** Received SIGBUS **\n\n\n\n"));
  	printf(catgets(elm_msg_cat, ElmSet, ElmBusErrorSignal,
  		"\n\nBus Error signal!\n\n"));
! 	emergency_exit();
  }
  #endif
  
--- 70,81 ----
  SIGHAND_TYPE
  bus_signal(sig)
  {
! 	MoveCursor(elm_LINES,0);
  	Raw(OFF);
  	dprint(1, (debugfile, "\n\n** Received SIGBUS **\n\n\n\n"));
  	printf(catgets(elm_msg_cat, ElmSet, ElmBusErrorSignal,
  		"\n\nBus Error signal!\n\n"));
! 	emergency_exit(!InGetPrompt);
  }
  #endif
  
***************
*** 142,153 ****
  SIGHAND_TYPE
  segv_signal(sig)
  {
! 	MoveCursor(LINES,0);
  	Raw(OFF);
  	dprint(1, (debugfile,"\n\n** Received SIGSEGV **\n\n\n\n"));
  	printf(catgets(elm_msg_cat, ElmSet, ElmSegmentViolationSignal,
  		"\n\nSegment Violation signal!\n\n"));
! 	emergency_exit();
  }
  
  SIGHAND_TYPE
--- 82,93 ----
  SIGHAND_TYPE
  segv_signal(sig)
  {
! 	MoveCursor(elm_LINES,0);
  	Raw(OFF);
  	dprint(1, (debugfile,"\n\n** Received SIGSEGV **\n\n\n\n"));
  	printf(catgets(elm_msg_cat, ElmSet, ElmSegmentViolationSignal,
  		"\n\nSegment Violation signal!\n\n"));
! 	emergency_exit(!InGetPrompt);
  }
  
  SIGHAND_TYPE
***************
*** 186,191 ****
--- 126,134 ----
  	/* This is called when the user presses a ^Z to stop the
  	   process within BSD 
  	*/
+ 
+ 	redraw_screen = 1;
+ 
  #ifdef	SIGTSTP
  	signal(SIGTSTP, SIG_DFL);
  #endif
***************
*** 196,210 ****
  	printf(catgets(elm_msg_cat, ElmSet, ElmStoppedUseFGToReturn,
  		"\n\nStopped.  Use \"fg\" to return to ELM\n\n"));
  
! 	kill(0, SIGSTOP);
  }
  
  SIGHAND_TYPE
  sig_return_from_user_stop(sig)
! {
  	/** this is called when returning from a ^Z stop **/
  	dprint(1, (debugfile,"\n\n** Received SIGCONT **\n\n\n\n", sig));
  
  	signal(SIGCONT, sig_return_from_user_stop);
  	signal(SIGTSTP, sig_user_stop);
  
--- 139,155 ----
  	printf(catgets(elm_msg_cat, ElmSet, ElmStoppedUseFGToReturn,
  		"\n\nStopped.  Use \"fg\" to return to ELM\n\n"));
  
! 	kill(getpid(), SIGSTOP);
  }
  
  SIGHAND_TYPE
  sig_return_from_user_stop(sig)
! {  
  	/** this is called when returning from a ^Z stop **/
  	dprint(1, (debugfile,"\n\n** Received SIGCONT **\n\n\n\n", sig));
  
+ 	redraw_screen = 1;
+ 
  	signal(SIGCONT, sig_return_from_user_stop);
  	signal(SIGTSTP, sig_user_stop);
  
***************
*** 230,235 ****
--- 175,182 ----
  winch_signal(sig)
  {
  	resize_screen = 1;
+ 	redraw_screen = 1;
+ 
  	signal(SIGWINCH, winch_signal);
  
  	if (InGetPrompt)
***************
*** 245,264 ****
  SIGHAND_TYPE
  usr1_signal(sig)
  {
! 	dprint(1, (debugfile, "\n\n** Received SIGUSR1 **\n\n\n\n"));
! 	question_me = FALSE;
! 	while ( leave_mbox(TRUE, FALSE, TRUE) == -1)
! 		newmbox(cur_folder, TRUE);
  
! 	leave(0);
  }
  
  SIGHAND_TYPE
  usr2_signal(sig)
  {
! 	dprint(1, (debugfile, "\n\n** Received SIGUSR2 **\n\n\n\n"));
! 	while ( leave_mbox(FALSE, TRUE, FALSE) == -1)
! 		newmbox(cur_folder, TRUE);
  
! 	leave(0);
  }
--- 192,227 ----
  SIGHAND_TYPE
  usr1_signal(sig)
  {
!   int result;
! 
!   dprint(1, (debugfile, "\n\n** Received SIGUSR1 **\n\n\n\n"));
!   if (!InGetPrompt) {
!     dprint(1, (debugfile, "-- Not in prompt -- can't leave folder\n"));
!     return;
!   }
! 
!   question_me = FALSE;
!   while ((result = leave_mbox(TRUE, FALSE, TRUE)) == -1)
!     newmbox(cur_folder, TRUE);
  
!   if (result >= 0) 
!     leave(!InGetPrompt);
  }
  
  SIGHAND_TYPE
  usr2_signal(sig)
  {
!   int result;
!   
!   dprint(1, (debugfile, "\n\n** Received SIGUSR2 **\n\n\n\n"));
!   if (!InGetPrompt) {
!     dprint(1, (debugfile, "-- Not in prompt -- can't leave folder\n"));
!     return;
!   }
! 
!   while ((result = leave_mbox(FALSE, TRUE, FALSE)) == -1)
!     newmbox(cur_folder, TRUE);
  
!   if (result >= 0)
!     leave(!InGetPrompt);
  }
Index: elm2.4.ME+.50/src/softkeys.c
*** elm2.4.25/src/softkeys.c	Fri Apr 16 06:51:38 1993
--- elm2.4.ME+.50/src/softkeys.c	Tue Nov 17 21:12:58 1998
***************
*** 1,42 ****
  
! static char rcsid[] = "@(#)$Id: softkeys.c,v 5.2 1993/04/16 03:51:38 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: softkeys.c,v $
!  * Revision 5.2  1993/04/16  03:51:38  syd
!  * I found a small screen corruption problem with elm.  If you select 'c' for
!  * change mailbox and then back out by just typing <Return> at the prompt for the
!  * new mailbox, the prompt 'Command: ' seems to be reprinted on the wrong line
!  * leaving the previous prompt and the 'Change Mailbox' string in place.
!  *
!  * Further investiagtion tracked the problem to the softkey programming.  When a
!  * newline (LF) character is sent to the terminal in the sofkey's "send" string,
!  * the terminal still performs a linefeed just as if the linefeed were sent at any
!  * other time.  The particlar set of softkeys for change mode has four such
!  * newlines and this is enought to cause the screen to scroll up one line.  This
!  * in turn causes the prompt to appear on the wrong line.
!  *
!  * I have fixed this by replacing the newlines with carriage returns instead.  I
!  * checked and this still performs the desired action without actually scrolling
!  * the screen.
!  * From: Steve Fosdick <stevef@aom.bt.co.uk>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  *******************************************************************************
   */
  
  #include "headers.h"
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: softkeys.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  ******************************************************************************
   */
  
  #include "headers.h"
***************
*** 149,155 ****
  
  	char buffer[30];
  
! 	sprintf(buffer,"%s%s", display, send);
  
  	fprintf(stderr, "%c&f%dk%dd%dL%s", ESCAPE, key,
  		strlen(display), strlen(send), buffer);
--- 123,130 ----
  
  	char buffer[30];
  
! 	elm_sfprintf(buffer,sizeof buffer,
! 		     FRM("%s%s"), display, send);
  
  	fprintf(stderr, "%c&f%dk%dd%dL%s", ESCAPE, key,
  		strlen(display), strlen(send), buffer);
Index: elm2.4.ME+.50/src/sort.c
*** elm2.4.25/src/sort.c	Mon Apr 12 06:42:56 1993
--- elm2.4.ME+.50/src/sort.c	Tue Nov 17 21:12:58 1998
***************
*** 1,38 ****
  
! static char rcsid[] = "@(#)$Id: sort.c,v 5.2 1993/04/12 03:42:56 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: sort.c,v $
!  * Revision 5.2  1993/04/12  03:42:56  syd
!  * I noticed when I was sorting a mailbox by subject, that 2 messages with
!  * the following subjects
!  *
!  *     Subject: Re: Reading news
!  *     Subject: Reading news
!  *
!  * they were sorted as shown above even though the "Re:" message was
!  * "Sent" after the original.  It turns out that the routine skip_re has a
!  * bug.  If the actual subject (the part after the "Re: ") starts with the
!  * characters "re" skip_re will erroneously not strip the "Re:" part at
!  * all.  The following patch fixes that behaviour.
!  * From: Larry Philps <larryp@sco.COM>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** Sort folder header table by the field specified in the global
      variable "sortby"...if we're sorting by something other than
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: sort.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** Sort folder header table by the field specified in the global
      variable "sortby"...if we're sorting by something other than
***************
*** 89,96 ****
  	  last_index = headers[current-1]->index_number;
  
  	if (entries > 30 && visible)  
! 	  error1(catgets(elm_msg_cat, ElmSet, ElmSortingMessagesBy, 
! 		"Sorting messages by %s..."), sort_name(FULL));
  	
  	if (entries > 1)
  	  qsort((char *) headers, (unsigned) entries,
--- 67,75 ----
  	  last_index = headers[current-1]->index_number;
  
  	if (entries > 30 && visible)  
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSortingMessagesBy, 
! 			    "Sorting messages by %s..."), 
! 		    sort_name(FULL));
  	
  	if (entries > 1)
  	  qsort((char *) headers, (unsigned) entries,
***************
*** 142,150 ****
    		break;
  
  	case SENDER:
! 		tail_of(first->from, from1, first->to);
! 		tail_of(second->from, from2, second->to);
! 		ret = strcmp(from1, from2);
  		break;
  
  	case SIZE:
--- 121,155 ----
    		break;
  
  	case SENDER:
! 	        ret = strcmp(first->env_from,second->env_from);
! 
! 		if (0 == ret) {
! 		  struct addr_item *p, *p1;
! 
! 		  for (p = first->from, p1 = second->from;
! 		       0 == ret; 
! 		       p++, p1++) {
! 		    int is_f = p && p->fullname && p->addr;
! 		    int is_f1 = p1 && p1->fullname && p1->addr;
! 		    
! 		    if (!is_f && !is_f1)
! 		      break;
! 		    
! 		    if (!is_f) {
! 		      ret = -1;
! 		      break;
! 		    }
! 
! 		    if (!is_f1) {
! 		      ret = 1;
! 		      break;
! 		    }
! 		    ret = strcmp(p->fullname,p1->fullname);
! 		    if (0 == ret)
! 		      ret = strcmp(p->addr,p1->addr);
! 		  }
! 		}
! 		
  		break;
  
  	case SIZE:
***************
*** 157,163 ****
  
  	case SUBJECT:
  		/* need some extra work 'cause of STATIC buffers */
! 		strcpy(from1, skip_re(shift_lower(first->subject)));
  		ret = strcmp(from1, skip_re(shift_lower(second->subject)));
  		break;
  
--- 162,169 ----
  
  	case SUBJECT:
  		/* need some extra work 'cause of STATIC buffers */
! 		strfcpy(from1, skip_re(shift_lower(first->subject)),
! 			sizeof from1);
  		ret = strcmp(from1, skip_re(shift_lower(second->subject)));
  		break;
  
***************
*** 285,291 ****
  	while (whitespace(string[i])) i++;
  
  	/* Initialize buffer */
! 	strcpy(buffer, (char *) string);
  
  	do {
  	  if (string[i] == '\0') return( (char *) buffer);	/* forget it */
--- 291,297 ----
  	while (whitespace(string[i])) i++;
  
  	/* Initialize buffer */
! 	strfcpy(buffer, string, sizeof buffer);
  
  	do {
  	  if (string[i] == '\0') return( (char *) buffer);	/* forget it */
***************
*** 308,316 ****
  	  while (whitespace(string[i])) i++;
  
  	  /* Now save the resulting subject for return purposes */
! 	  strcpy(buffer, (char *) string + i);
  
  	} while (string[i] == 'r' && string[i+1] == 'e');
   
! 	return( (char *) buffer);
  }
--- 314,322 ----
  	  while (whitespace(string[i])) i++;
  
  	  /* Now save the resulting subject for return purposes */
! 	  strfcpy(buffer, string + i, sizeof buffer);
  
  	} while (string[i] == 'r' && string[i+1] == 'e');
   
! 	return( buffer);
  }
Index: elm2.4.ME+.50/src/string2.c
*** elm2.4.25/src/string2.c	Tue Aug  3 22:29:21 1993
--- elm2.4.ME+.50/src/string2.c	Tue Nov 17 21:12:58 1998
***************
*** 1,36 ****
  
! static char rcsid[] = "@(#)$Id: string2.c,v 5.2 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: string2.c,v $
!  * Revision 5.2  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This file contains string functions that are shared throughout the
      various ELM utilities...
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: string2.c,v 1.2 1998/10/20 19:58:17 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This file contains string functions that are shared throughout the
      various ELM utilities...
Index: elm2.4.ME+.50/src/strings.c
*** elm2.4.25/src/strings.c	Tue Aug  3 22:29:23 1993
--- elm2.4.ME+.50/src/strings.c	Tue Nov 17 21:12:58 1998
***************
*** 1,65 ****
  
! static char rcsid[] = "@(#)$Id: strings.c,v 5.8 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.8 $   $State: Exp $
   *
   * 			Copyright (c) 1986, 1987 Dave Taylor
   * 			Copyright (c) 1988, 1989, 1990, 1991 USENET Community Trust
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: strings.c,v $
!  * Revision 5.8  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.7  1993/07/20  02:26:58  syd
!  * Fix copy_sans_escape handling of tabs
!  * From: Syd via code from G A Smant
!  *
!  * Revision 5.6  1993/01/20  03:02:19  syd
!  * Move string declarations to defs.h
!  * From: Syd
!  *
!  * Revision 5.5  1993/01/19  05:07:05  syd
!  * Trim erroreous extra log entry
!  * From: Syd
!  *
!  * Significant changes to provide consistent Date and From_ header
!  * cracking.  Overhauled date utilities and moved into library.  Moved
!  * real_from() into library.  Modified frm, newmail, and readmsg utilities
!  * to use library version of real_from().  Moved get_word() from Elm
!  * source into library.  Added new library routines atonum() and strfcpy().
!  * Fixed trailing backslash bug in len_next().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.3  1992/12/24  22:16:06  syd
!  * Make copy_sans_escape expand tabs to prevent subject displays from getting messed up
!  * From: Syd via request from pgf@Cayman.COM (Paul Fox)
!  *
!  * Revision 5.2  1992/10/17  22:30:43  syd
!  * Force text arithimetic into unsigned for those systems
!  * with signed chars
!  * From: Marius Olafsson <marius@rhi.hi.is>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This file contains all the string oriented functions for the
      ELM Mailer, and lots of other generally useful string functions! 
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: strings.c,v 1.2 1998/10/20 19:58:18 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1986, 1987 Dave Taylor
   * 			Copyright (c) 1988, 1989, 1990, 1991 USENET Community Trust
!  *****************************************************************************/
  
  /** This file contains all the string oriented functions for the
      ELM Mailer, and lots of other generally useful string functions! 
***************
*** 128,134 ****
  	char     buffer[VERY_LONG_STRING];
  	char     *word, *bufptr;
  
! 	strcpy(buffer, inbuff);
  
  	bufptr = (char *) buffer;
  
--- 79,85 ----
  	char     buffer[VERY_LONG_STRING];
  	char     *word, *bufptr;
  
! 	strfcpy(buffer, inbuff, sizeof buffer);
  
  	bufptr = (char *) buffer;
  
***************
*** 139,145 ****
  	    /* first, decide what sort of separator we need, if any... */
  
  	  if (strlen(word) + current_length > 80) {
! 	    if (iindex > 0) {
  	      ret_buffer[iindex++] = ',';	/* close 'er up, doctor! */
  	      ret_buffer[iindex++] = '\n';
  	      ret_buffer[iindex++] = '\t';
--- 90,96 ----
  	    /* first, decide what sort of separator we need, if any... */
  
  	  if (strlen(word) + current_length > 80) {
! 	    if (iindex > 0 && iindex < sizeof ret_buffer -4) {
  	      ret_buffer[iindex++] = ',';	/* close 'er up, doctor! */
  	      ret_buffer[iindex++] = '\n';
  	      ret_buffer[iindex++] = '\t';
***************
*** 147,153 ****
  	    
  	    /* now add this pup! */
  
! 	    for (i=(word[0] == ' '? 1:0), len = strlen(word); i<len; i++)
  	      ret_buffer[iindex++] = word[i];
  	    current_length = len + 8;	/* 8 = TAB */
  	  }
--- 98,106 ----
  	    
  	    /* now add this pup! */
  
! 	    for (i=(word[0] == ' '? 1:0), len = strlen(word); 
! 		 i<len && iindex < sizeof ret_buffer -2; 
! 		 i++)
  	      ret_buffer[iindex++] = word[i];
  	    current_length = len + 8;	/* 8 = TAB */
  	  }
***************
*** 154,165 ****
  
  	  else {	/* just add this address to the list.. */
  
! 	    if (iindex > 0) {
  	      ret_buffer[iindex++] = ',';	/* comma added! */
  	      ret_buffer[iindex++] = ' ';
  	      current_length += 2;
  	    }
! 	    for (i=(word[0] == ' '? 1:0), len = strlen(word); i<len; i++)
  	      ret_buffer[iindex++] = word[i];
  	    current_length += len;
  	  }
--- 107,120 ----
  
  	  else {	/* just add this address to the list.. */
  
! 	    if (iindex > 0 && iindex < sizeof ret_buffer -3) {
  	      ret_buffer[iindex++] = ',';	/* comma added! */
  	      ret_buffer[iindex++] = ' ';
  	      current_length += 2;
  	    }
! 	    for (i=(word[0] == ' '? 1:0), len = strlen(word); 
! 		 i<len && iindex < sizeof ret_buffer -2; 
! 		 i++)
  	      ret_buffer[iindex++] = word[i];
  	    current_length += len;
  	  }
***************
*** 172,177 ****
--- 127,202 ----
  	return( (char *) ret_buffer);
  }
  
+ char **argv_from_to(to) 
+      char *to;
+ {
+   int count=1;
+   int idx = 0, q = 0, i;
+   char *ptr=to;
+   char *last;
+   char **res;
+ 
+   dprint(8, (debugfile, "argv_from_to: to=%s\n",to));
+ 
+   while (*ptr) {
+     int len = rfc822_toklen(ptr);
+     if (len == 1 && *ptr == COMMA)
+       count++;
+ 
+     ptr += len;
+   }
+ 
+   dprint(8, (debugfile, "           count=%d\n",count));
+ 
+   res = safe_malloc((count + 1) * sizeof (char *));
+ 
+   ptr = to;
+   last = ptr;
+   while (*ptr) {
+     int len = rfc822_toklen(ptr);
+     dprint(20, (debugfile, "   token: %.*s\n",len,ptr));
+     if (len == 1 && *ptr == ',' && last && !q) {
+       int k;
+       *ptr = '\0';
+       rfc822_reap_comments(last,NULL,0);
+       k = strlen(last);
+       while(k > 0 && last[k-1] == ' ')
+ 	k--;
+       last[k] = '\0';
+       res[idx++] = last;
+       dprint(20, (debugfile, "   addr: %.*s\n",last));
+       last = NULL;
+     } else if (len == 1 && *ptr == '<')
+       q = 1;
+     else if (len == 1 && *ptr == '>')
+       q = 0;
+         
+     if (*ptr && !last && *ptr != ' ')
+       last = ptr;
+ 
+     ptr += len;
+   }
+ 
+   if (last) {
+     int k;
+     *ptr = '\0';
+     rfc822_reap_comments(last,NULL,0);
+     k = strlen(last);
+     while(k > 0 && last[k-1] == ' ')
+       k--;
+     last[k] = '\0';
+     res[idx++] = last;
+     dprint(20, (debugfile, "   addr: %.*s\n",last));
+     last = NULL;
+   }
+   res[idx] = 0;
+   dprint(8, (debugfile, "           idx=%d\n",idx));
+   for (i = 0; i < idx; i++) 
+     dprint(8, (debugfile, "           [%d]=%s\n",i,res[i]));
+   return res;
+ 
+ }
+ 
  char *strip_commas(string)
  char *string;
  {
***************
*** 252,257 ****
--- 277,286 ----
  	len = strlen(string);
  	s = string;
  
+ 	if (maxchars > sizeof buffer -4) {
+ 	  maxchars = sizeof buffer -4;
+ 	}
+ 
  	while (iindex < len) {
  	  i = len_next_part(s);
  	  if (i == 1 && isspace(*s))
***************
*** 291,300 ****
  
  	length = strlen(string);
  
! 	if (length > COLUMNS)
  	  col = 0;
  	else
! 	  col = (COLUMNS - length) / 2;
  
  	PutLine0(line, col, string);
  }
--- 320,329 ----
  
  	length = strlen(string);
  
! 	if (length > elm_COLUMNS)
  	  col = 0;
  	else
! 	  col = (elm_COLUMNS - length) / 2;
  
  	PutLine0(line, col, string);
  }
***************
*** 332,341 ****
  	char     *return_value, *sourceptr;
  
  	if (depth > MAX_RECURSION) {
! 	   error1(catgets(elm_msg_cat, ElmSet, ElmGetTokenOverNested,
! 		"Get_token calls nested greater than %d deep!"), 
! 		  MAX_RECURSION);
! 	   emergency_exit();
  	}
  
  	if (source != NULL)
--- 361,370 ----
  	char     *return_value, *sourceptr;
  
  	if (depth > MAX_RECURSION) {
! 	   lib_error(CATGETS(elm_msg_cat, ElmSet, ElmGetTokenOverNested,
! 			     "Get_token calls nested greater than %d deep!"), 
! 		     MAX_RECURSION);
! 	   emergency_exit(0);
  	}
  
  	if (source != NULL)
***************
*** 369,417 ****
  	return((char *) return_value);	     /* and we're outta here! */
  }
  
- 
- quote_args(out_string,in_string)
- register char *out_string, *in_string;
- {
- 	/** Copy from "in_string" to "out_string", collapsing multiple
- 	    white space and quoting each word.  Returns a pointer to
- 	    the resulting word.
- 	**/
- 
- 	int empty_string = TRUE, len;
- 
- 	while ( *in_string != '\0' ) {
- 
- 	    /**	If this is a space then advance to the start of the next word.
- 		Otherwise, copy through the word surrounded by quotes.
- 	    **/
- 
- 	    if ( isspace(*in_string) ) {
- 		while ( isspace(*in_string) )
- 			++in_string;
- 	    } else {
- 		*out_string++ = '"';
- 
- 		while ( *in_string != '\0') {
- 		  len = len_next_part(in_string);
- 		  if (len == 1 && isspace(*in_string))
- 		    break;
- 
- 		  while (--len >= 0) {
- 		    if (*in_string == '"' || *in_string == '\\' || *in_string == '$')
- 		      *out_string++ = '\\';
- 		    *out_string++ = *in_string++;
- 		  }
- 		}
- 		*out_string++ = '"';
- 		*out_string++ = ' ';
- 		empty_string = FALSE;
- 	    }
- 
-     }
- 
-     if ( !empty_string )
- 	--out_string;
-     *out_string = '\0';
- }
  
--- 398,401 ----
Index: elm2.4.ME+.50/src/syscall.c
*** elm2.4.25/src/syscall.c	Tue Aug 30 18:09:43 1994
--- elm2.4.ME+.50/src/syscall.c	Tue Nov 17 21:12:57 1998
***************
*** 1,62 ****
  
! static char rcsid[] = "@(#)$Id: syscall.c,v 5.9 1994/08/30 15:09:43 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.9 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: syscall.c,v $
!  * Revision 5.9  1994/08/30  15:09:43  syd
!  * Block sigwinch when in the external pager.
!  * From: jwa@yog-sothoth.dcrt.nih.gov (James W. Adams)
!  *
!  * Revision 5.8  1993/08/23  02:46:07  syd
!  * Don't declare _exit() if <unistd.h> already did it.
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.7  1993/01/20  03:48:08  syd
!  * Fix not to use vfork if SY_ENV_SHELL is set, as this causes the
!  * parent environment to be modified.
!  * From: Syd
!  *
!  * Revision 5.6  1992/12/20  05:29:33  syd
!  * Fixed where when doing ! or | and ti/te is enabled, one doesn't see the
!  * "Press any key to return to ELM:" message. because the screens are
!  * switched before the message is printed.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.5  1992/12/11  02:05:26  syd
!  * List_folder knew only about '=' but nothing about the rest
!  * of [+=%] as one would have expected.
!  * From: Jukka Antero Ukkonen <ukkonen@venus.csc.fi>
!  *
!  * Revision 5.4  1992/12/11  01:58:50  syd
!  * Allow for use from restricted shell by putting SHELL=/bin/sh in the
!  * environment of spawned mail transport program.
!  * From: chip@tct.com (Chip Salzenberg)
!  *
!  * Revision 5.3  1992/11/07  20:45:39  syd
!  * add no tite flag on options that should not use ti/te
!  * Hack by Syd
!  *
!  * Revision 5.2  1992/11/07  19:37:21  syd
!  * Enhanced printing support.  Added "-I" to readmsg to
!  * suppress spurious diagnostic messages.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** These routines are used for user-level system calls, including the
      '!' command and the '|' commands...
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: syscall.c,v 1.2 1998/10/20 19:58:18 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** These routines are used for user-level system calls, including the
      '!' command and the '|' commands...
***************
*** 65,77 ****
  
  #include "headers.h"
  #include "s_elm.h"
  
  #include <errno.h>
  
- #ifdef BSD
- #  include <sys/wait.h>
- #endif
- 
  #ifndef I_UNISTD
  void _exit();
  #endif
--- 19,28 ----
  
  #include "headers.h"
  #include "s_elm.h"
+ #include "me.h"
  
  #include <errno.h>
  
  #ifndef I_UNISTD
  void _exit();
  #endif
***************
*** 88,144 ****
  	**/
  
  	char command[SLEN];
! 	int  old_raw, helpful, ret;
  
  	helpful = (user_level == 0);
  
  	if (helpful)
! 	  PutLine0(LINES-3, COLUMNS-40, catgets(elm_msg_cat, ElmSet, ElmUseShellName,
! 		"(Use the shell name for a shell.)"));
! 	PutLine0(LINES-2, 0, catgets(elm_msg_cat, ElmSet, ElmShellCommand,
  		"Shell command: "));
  	CleartoEOS();
  	command[0] = '\0';
! 	(void) optionally_enter(command, LINES-2, 15, FALSE, FALSE);
! 	if (command[0] == 0) {
  	  if (helpful)
! 	    MoveCursor(LINES-3,COLUMNS-40);
  	  else
! 	    MoveCursor(LINES-2,0);
  	  CleartoEOS();
! 	  return 0;
  	}
  
! 	MoveCursor(LINES,0);
  	CleartoEOLN();
  
  	if ((old_raw = RawState()) == ON)
  	  Raw(OFF);
! 	softkeys_off();
! 	if (cursor_control)
! 	  transmit_functions(OFF);
  
  	umask(original_umask);	/* restore original umask so users new files are ok */
  	ret = system_call(command, SY_USER_SHELL|SY_ENAB_SIGINT|SY_DUMPSTATE);
  	umask(077);		/* now put it back to private for mail files */
  
  	SetXYLocation(0, 40);	/* a location not near the next request, so an absolute is used */
! 	PutLine0(LINES, 0, catgets(elm_msg_cat, ElmSet, ElmPressAnyKeyToReturn,
  		"\n\nPress any key to return to ELM: "));
  	Raw(ON | NO_TITE);
! 	(void) getchar();
  	printf("\r\n");
  	Raw(OFF | NO_TITE); /* Done even if old_raw == ON, to get ti/te right */
  	if (old_raw == ON)
  	  Raw(ON);
  
! 	softkeys_on();
! 	if (cursor_control)
! 	  transmit_functions(ON);
  
  	if (ret)
! 	  error1(catgets(elm_msg_cat, ElmSet, ElmReturnCodeWas,
! 		"Return code was %d."), ret);
  
  	return 1;
  }
--- 39,112 ----
  	**/
  
  	char command[SLEN];
! 	int redraw = FALSE;
! 	int  old_raw, helpful, ret, status;
  
  	helpful = (user_level == 0);
  
  	if (helpful)
! 	  PutLine0(elm_LINES-3, elm_COLUMNS-40, 
! 		   catgets(elm_msg_cat, ElmSet, 
! 			   ElmUseShellName,
! 			   "(Use the shell name for a shell.)"));
! 	PutLine0(elm_LINES-2, 0, catgets(elm_msg_cat, ElmSet, ElmShellCommand,
  		"Shell command: "));
  	CleartoEOS();
  	command[0] = '\0';
! 	status = optionally_enter(command, elm_LINES-2, 15, OE_REDRAW_MARK,
! 				  sizeof command);
! 
! 	while (REDRAW_MARK == status) {
! 	  redraw = TRUE;
! 	  PutLine0(elm_LINES-2, 0, 
! 		   catgets(elm_msg_cat, ElmSet, ElmShellCommand,
! 			   "Shell command: "));
! 	  status = optionally_enter(command, elm_LINES-2, 15, 
! 				    OE_REDRAW_MARK|OE_APPEND_CURRENT,
! 				    sizeof command);
! 
! 	}
! 	if (0 != status && command[0] == 0) {
  	  if (helpful)
! 	    MoveCursor(elm_LINES-3,elm_COLUMNS-40);
  	  else
! 	    MoveCursor(elm_LINES-2,0);
  	  CleartoEOS();
! 	  return redraw;
  	}
  
! 	MoveCursor(elm_LINES,0);
  	CleartoEOLN();
  
  	if ((old_raw = RawState()) == ON)
  	  Raw(OFF);
! 	/* softkeys_off(); */
  
  	umask(original_umask);	/* restore original umask so users new files are ok */
  	ret = system_call(command, SY_USER_SHELL|SY_ENAB_SIGINT|SY_DUMPSTATE);
  	umask(077);		/* now put it back to private for mail files */
  
+ redraw2:
  	SetXYLocation(0, 40);	/* a location not near the next request, so an absolute is used */
! 	PutLine0(elm_LINES, 0, catgets(elm_msg_cat, ElmSet, 
! 				       ElmPressAnyKeyToReturn,
  		"\n\nPress any key to return to ELM: "));
  	Raw(ON | NO_TITE);
! 	if (ReadCh(REDRAW_MARK) == REDRAW_MARK) {
! 	  Raw(OFF | NO_TITE);
! 	  goto redraw2;
! 	}
  	printf("\r\n");
  	Raw(OFF | NO_TITE); /* Done even if old_raw == ON, to get ti/te right */
  	if (old_raw == ON)
  	  Raw(ON);
  
! 	/* softkeys_on(); */
  
  	if (ret)
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmReturnCodeWas,
! 			    "Return code was %d."), 
! 		    ret);
  
  	return 1;
  }
***************
*** 145,155 ****
  
  #endif /* ALLOW_SUBSHELL */
  
! int system_call(string, options)
! char *string;
! int options;
  {
! 	/** execute 'string', setting uid to userid... **/
  
  	/** The following might be encoded into the "options" parameter:
  
--- 113,139 ----
  
  #endif /* ALLOW_SUBSHELL */
  
! 
! static int set_child_signals P_((int));      /* Prototype */
! 
! static int set_child_signals(options)
!      int options;
  {
!   /*
!    * Program to exec may or may not be able to handle
!    * interrupt, quit, hangup and stop signals.
!    */
!   if (options&SY_ENAB_SIGINT)
!     options |= SY_ENAB_SIGHUP;
!   (void) signal(SIGHUP,  (options&SY_ENAB_SIGHUP) ? SIG_DFL : SIG_IGN);
!   (void) signal(SIGINT,  (options&SY_ENAB_SIGINT) ? SIG_DFL : SIG_IGN);
!   (void) signal(SIGQUIT, (options&SY_ENAB_SIGINT) ? SIG_DFL : SIG_IGN);
! #ifdef SIGTSTP
!   (void) signal(SIGTSTP, (options&SY_ENAB_SIGHUP) ? SIG_DFL : SIG_IGN);
!   (void) signal(SIGCONT, (options&SY_ENAB_SIGHUP) ? SIG_DFL : SIG_IGN);
! #endif
!   return 0;
! }
  
  	/** The following might be encoded into the "options" parameter:
  
***************
*** 179,201 ****
  				program.  This is so that if "readmsg" is
  				invoked it can figure out what folder we are
  				in and what message(s) are selected.
  	**/
  
! 	int pfd[2], stat, pid, w, iteration;
! 	char *sh;
! #if defined(BSD) && !defined(WEXITSTATUS)
! 	union wait status;
  #else
! 	int status;
  #endif
! 	register SIGHAND_TYPE (*istat)(), (*qstat)(), (*wstat)();
  #ifdef SIGTSTP
! 	register SIGHAND_TYPE (*oldstop)(), (*oldstart)();
  #endif
! 	extern int errno;
  
! 	/* flush any pending output */
! 	fflush(stdout);
  
  	/* figure out what shell we are using here */
  	sh = ((options & SY_USER_SHELL) ? shell : "/bin/sh");
--- 163,620 ----
  				program.  This is so that if "readmsg" is
  				invoked it can figure out what folder we are
  				in and what message(s) are selected.
+ 
+ 	    SY_ENV_METAMAIL	When set, put "MM_CHARSET=[display_charset]"
+ 	                        to environ.
+ 
  	**/
  
! static int set_child_env P_((int));         /* Prototype */
! 
! static int set_child_env(options)
!      int options;
! {
! #ifdef MIME
!   /* Optionally override the MM_CHARSET environment variable. */
!   if (options&SY_ENV_METAMAIL) {
!     static char mm[] = "MM_CHARSET=";
!     int size = sizeof(mm) + strlen(display_charset);
! 
!     /* \0 character is included in size returned by sizeof */
!     char *p = malloc(size);
!     if (p) {
!       elm_sfprintf(p, size,
! 		   FRM("%s%s"), mm , display_charset );
!       putenv(p);
!     }
!   }
! #endif
! 
!   /* Optionally override the SHELL environment variable. */
!   if (options&SY_ENV_SHELL) {
!     static char sheq[] = "SHELL=";
!     char * sh = ((options & SY_USER_SHELL) ? shell : "/bin/sh");
!     int size = sizeof(sheq) + strlen(sh);
! 
!     char *p = malloc(size);
!     if (p) {
!       elm_sfprintf(p, size,
! 		   FRM("%s%s"), sheq, sh);
!       putenv(p);
!     }
!   }
!   return 0;
! }
! 
! #ifdef BACKGROUD_PROCESSES       /* We assume POSIX in here */
! 
! static struct process_list {
!   FILE * fd;
!   char * message;
!   struct run_state state_information;
!   end_handler *handler;
!   struct process_list * next;
! } * my_processes = NULL;
! 
! static void got_sigchld P_((int sig));
! static void got_sigchld (sig) 
!      int sig;
! {
!   handle_sigchld = 1;
! }
! 
! void sigchld_handler() {
! 
!   dprint(2, (debugfile, "sigchld_handler --> ENTER\n"));
! 
!   do {
!     struct process_list *tmp = my_processes, *prev = NULL;
!     handle_sigchld = 0;
!  
!     while (tmp) {
!       struct process_list * this = tmp;
!       int exit_code;
!       int ret = run_already_done(&(tmp->state_information),&exit_code);
! 
!       if (ret != 0) {
! 
! 	tmp->handler(tmp->fd,tmp->message,&(tmp->state_information),
! 		     ret,exit_code);
! 	
! 	if (prev)
! 	  prev -> next = tmp -> next;
! 	else
! 	  my_processes = tmp -> next;
! 
! 	dprint(2, (debugfile, "sigchld_handler: deleting %d from list: %s\n",
! 		   tmp->state_information.pid, tmp->message));
! 	
! 	free(tmp->message);
! 	tmp = tmp -> next;
! 	free(this);
! 	continue;
!       }
! 
!       prev = tmp;
!       tmp  = tmp -> next;
!     }
! 
!   } while (handle_sigchld);
! 
!   dprint(2, (debugfile, "sigchld_handler --> LEAVE\n"));
! }
! 
! void init_backgroud_handling () {
!   /* We use POSIX sigaction here,
!    * so that we not depend different semantic
!    * between SYSV and BSD signal(SIGCHLD, ...)
!    */
! 
!   struct sigaction new_child;
! 
!   new_child.sa_flags    = 0;
! #ifdef SA_INTERRUPT
!   new_child.sa_flags |= SA_INTERRUPT;           /* SunOS? */
! #endif
!   new_child.sa_handler = got_sigchld;
!   sigemptyset(& (new_child.sa_mask));
! 
!   if (-1 == sigaction(SIGCHLD,&new_child,NULL)) {
!     int err = errno;
!     lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSigaction,"sigaction: %s"),
! 	      error_description(err));
!     exit (1);
!   }
! }
! 
! int maybe_background (rs,exit_code,fd,title,func) 
!      struct run_state *rs;
!      int *exit_code;
!      FILE *fd;
!      char *title; 
!      end_handler *func; 
! {
!   int ret;
!   struct process_list *listptr;
!   if (!title)
!     title = "NO NAME";
! 
!   if (rs->raw == ON && RawState() == OFF) {
! 
!     ret = wait_end (rs,exit_code);
!     if (ret != 0)
!       return ret;
!   }
! 
!   listptr = safe_malloc(sizeof (struct process_list));
!   rs -> listptr = listptr;
!   listptr -> fd      = fd;
!   listptr -> message = safe_strdup(title);
!   listptr -> state_information = *rs;
!   listptr -> handler = func;
!   listptr -> next = my_processes;
!   my_processes = listptr;
!   return 0;
! } 
! #endif
! 
! static void raw_exit P_((struct run_state *rs));
! static void raw_exit(rs)
!      struct run_state *rs;
! {
!   if (rs->raw == ON && RawState() == OFF) {
!     dprint(4, (debugfile, "raw_exit: setting RAW on\n"));
!     Raw(ON|NO_TITE);
!   }  else {
!     dprint(4, (debugfile, "raw_exit: no state change\n"));
!   }
! }
! 
! static void print_status P_((struct run_state *rs,int sig,int exit_code));
! static void print_status(rs,sig,exit_code) 
!      struct run_state *rs;
!      int sig, exit_code;
! {
!   if (rs->raw == ON && ( SY_CLRWAIT & rs->options )) {
!   redraw:
!     if (sig) 
!       PutLineX(elm_LINES,0,
! 	       CATGETS(elm_msg_cat, ElmSet, 
! 		       ElmTerminatedWithSignal,
! 		       "Terminated with signal %d. Press any key to continue: "),
! 	       sig);
!     else if (exit_code)
!       PutLineX(elm_LINES,0,
! 	       CATGETS(elm_msg_cat, ElmSet, 
! 		       ElmExitedWithStatus,
! 		       "Exited with status %d. Press any key to continue: "),
! 	       exit_code);
!     else
!       PutLineX(elm_LINES,0,
! 	       CATGETS(elm_msg_cat, ElmSet, 
! 		       ElmDoneCont,
! 		       "Done. Press any key to continue: "));
!     if (ReadCh(REDRAW_MARK) == REDRAW_MARK) 
!       goto redraw;
!   }
! }
! 
! int run_already_done (rs,exit_code)
!      struct run_state *rs;
!      int *exit_code;
! {
!   S__ status;
!   
! #ifdef HASWAITPID
!   int w;
!   /* waitpid is on POSIX */
! 
!   *exit_code = -1;
! 
!   w = waitpid(rs->pid,&status,WNOHANG);
! 
!   if (w == 0) {
!     dprint(2, (debugfile, "run_already_done=%d (w=%d)\n",0,w));
!     return 0;
!   }
! 
!   if (w == -1) {
!     rs->save_errno = errno;
!     dprint(2, (debugfile, "run_already_done: errno=%d\n", rs->save_errno));
! 
!     if (rs->save_errno == EINTR) {
!       dprint(2, (debugfile, "run_already_done=%d (w=%d) [EINTR]\n",0,w));
!       return 0;
!     }
!   }
!  
!   raw_exit(rs);
! 
!   if (w == rs->pid) {
!     int sig = convert_status(status,exit_code);
! 
!     dprint(2, (debugfile, "run_already_done: exit_code=%d, sig=%d\n", 
! 	       *exit_code,sig));
! 
!     print_status(rs,sig,*exit_code) ;
! 
!     if (sig) {
!       dprint(2, (debugfile, "run_already_done=%d\n",-sig));
!       return -sig;
!     }
!   }
!   dprint(2, (debugfile, "run_already_done=%d\n",w != -1));
!   return w != -1;
  #else
!   dprint(2, (debugfile, "run_already_done=%d (no HASWAITPID)\n",0));
!   return 0;      
! #endif
! }
! 
! int wait_end  (rs,exit_code)
!      struct run_state *rs;
!      int *exit_code;
! {
!   int w;
!   S__ status;
! 
!   *exit_code = -1;
! 
!   while ((w = my_wait(rs->pid,&status)) != rs->pid)
!     if (w == -1 && errno != EINTR)
!       break;
! 
!   if (w == -1) {
!     rs->save_errno = errno;
!     dprint(2, (debugfile, "wait_end: errno=%d\n", rs->save_errno));    
!   }
!   
!   raw_exit(rs);
! 
!   if (w == rs->pid) {
!     int sig = convert_status(status,exit_code);
! 
!     dprint(2, (debugfile, "wait_end: exit_code=%d, sig=%d\n", 
! 	       *exit_code,sig));
! 
!     print_status(rs,sig,*exit_code);
! 
!     if (sig) {
!       dprint(2, (debugfile, "wait_end=%d\n",-sig));
!       return -sig;
!     }
!   }
!       
!   dprint(2, (debugfile, "wait_end=%d\n",w != -1));
!   return w != -1;
! }
! 
! char ** join_argv(argv1,argv2)
!      char * argv1[];
!      char * argv2[];
! {
!   int count1;
!   int count2;
!   char ** res;
!   int i;
!   for (count1 = 0; argv1[count1]; count1++);
!   for (count2 = 0; argv2[count2]; count2++);
! 
!   res = safe_malloc((count1 + count2 + 1)* sizeof (char *));
! 
!   for (i = 0; i < count1; i++)
!     res[i] = argv1[i];
!   for (i = 0; i < count2; i++)
!     res[i + count1] = argv2[i];
!   res[count1 + count2] = NULL;
! 
!   return res;
! }
! 
! int start_run(rs, options, argv, infd, outfd)
!      struct run_state *rs;
!      int options;
!      char * argv[];
!      int infd, outfd;
! {
!   int count;
!   int pfd[2], stat;
!   static int fd = -1;
!   int notty = (options & SY_NOTTY) != 0;
! 
!   dprint(2, (debugfile, "start run: [0] %s\n", argv[0]));
!   for (count = 1; argv[count]; count++) {
!     dprint(2, (debugfile, "           [%d] %s\n", count,argv[count]));
!   }
!   dprint(2, (debugfile, "    infd=%d, outfd=%d\n",infd,outfd));
! 
!   if (fd == -1)
!     fd = open("/dev/null",O_RDONLY);
!   dprint(2, (debugfile, "    fd=%d \n", fd));
! 
!   /* flush any pending output */
!   fflush(stdout);
!   rs->save_errno = 0;
!   rs->raw     = RawState();
!   rs->options = options;
! #ifdef BACKGROUD_PROCESSES      
!   rs->listptr = NULL; 
! #endif
! 
!   if (!notty) {
!     MoveCursor(elm_LINES,0);
!     CleartoEOLN();
!     fflush(stdout);
!     if (rs->raw == ON) {
!       if (options & SY_CLRWAIT) {
! 	ClearScreen();
!       }
!       dprint(4, (debugfile, "start_run: setting RAW off\n"));
!       Raw(OFF|NO_TITE);
!     }
!     if (options & SY_CLRWAIT) {
!       printf("Executing: %s ...\n\n",argv[0]);
!     }
!   }
! 
!   if (pipe(pfd) == -1) {
!     rs->save_errno = errno;
! 
!     raw_exit(rs);
!     return 0;
!   }
!   fcntl(pfd[0], F_SETFD, 1);
!   fcntl(pfd[1], F_SETFD, 1);
! 
!   rs->pid = fork();
! 
!   if (rs->pid == -1) {
!     rs->save_errno = errno;
!     
!     raw_exit(rs);
!     return 0;
!   }
!   else if (rs->pid == 0) {
!     close(pfd[0]);
!     /*
!      * Set group and user back to their original values.
!      * Note that group must be set first.
!      */
!     setgid(groupid);
!     setuid(userid);
! 
!     set_child_signals(options);
! 
!     set_child_env(options);
! 
!     if (notty) {
!       if (infd != 0  && -1 == dup2(fd,0) ||
! 	  outfd != 1 && -1 == dup2(fd,1) ||
! 	  outfd != 2 && -1 == dup2(fd,2)) { 
! 	write(pfd[1],&errno,sizeof errno); _exit(127); 
!       }
! 
! #ifdef SIGTTSTP
!       signal(SIGTTIN, SIG_IGN); 
!       signal(SIGTTOU, SIG_IGN);
!       signal(SIGTSTP, SIG_IGN);
  #endif
!     }
! 
!     if (infd >= 0) {
!       if (infd != 0  && -1 == dup2(infd,0)) {
! 	write(pfd[1],&errno,sizeof errno); _exit(127); 
!       }
!     }
!     if (outfd >= 0) {
!       if (outfd != 1  && -1 == dup2(outfd,1)) {
! 	write(pfd[1],&errno,sizeof errno); _exit(127); 
!       }
!     }
!     execvp(argv[0],argv);
!     write(pfd[1],&errno,sizeof errno); _exit(127); 
!   }
!   else {
!     int code, rd;
!     close(pfd[1]);
! 
!     dprint(4, (debugfile, "start_run: child pid=%d\n", rs->pid));
!     rd = read(pfd[0],&code, sizeof code);
!     close(pfd[0]);
! 
!     if (rd > 0) {
!       int exitcode;
! 
!       wait_end(rs,&exitcode);
!       if (rd == sizeof code)
! 	rs->save_errno = code;
!       else
! 	rs->save_errno = 0;
!       return 0;
!     }
!     return 1;
!   }
!   raw_exit(rs);
!   return 0;
! }
! 
! int system_call(string, options)
!      char *string;
!      int options;
! {
!   /** execute 'string', setting uid to userid... **/
! 
!   int pfd[2], stat, pid, w, iteration;
!   char *sh;
!   S__ status;
!   register SIGHAND_TYPE (*istat)(), (*qstat)(), (*wstat)();
  #ifdef SIGTSTP
!   register SIGHAND_TYPE (*oldstop)(), (*oldstart)();
  #endif
!   extern int errno;
  
!   /* flush any pending output */
!   fflush(stdout);
  
  	/* figure out what shell we are using here */
  	sh = ((options & SY_USER_SHELL) ? shell : "/bin/sh");
***************
*** 243,249 ****
  	    sleep(2);
  
  #ifdef VFORK
! 	  if (options&SY_ENV_SHELL)
  	    pid = fork();
  	  else
  	    pid = vfork();
--- 662,668 ----
  	    sleep(2);
  
  #ifdef VFORK
! 	  if (options&SY_ENV_SHELL || options&SY_ENV_METAMAIL)
  	    pid = fork();
  	  else
  	    pid = vfork();
***************
*** 266,294 ****
  	  setgid(groupid);
  	  setuid(userid);
  
! 	  /*
! 	   * Program to exec may or may not be able to handle
! 	   * interrupt, quit, hangup and stop signals.
! 	   */
! 	  if (options&SY_ENAB_SIGINT)
! 		options |= SY_ENAB_SIGHUP;
! 	  (void) signal(SIGHUP,  (options&SY_ENAB_SIGHUP) ? SIG_DFL : SIG_IGN);
! 	  (void) signal(SIGINT,  (options&SY_ENAB_SIGINT) ? SIG_DFL : SIG_IGN);
! 	  (void) signal(SIGQUIT, (options&SY_ENAB_SIGINT) ? SIG_DFL : SIG_IGN);
! #ifdef SIGTSTP
! 	  (void) signal(SIGTSTP, (options&SY_ENAB_SIGHUP) ? SIG_DFL : SIG_IGN);
! 	  (void) signal(SIGCONT, (options&SY_ENAB_SIGHUP) ? SIG_DFL : SIG_IGN);
! #endif
  
! 	  /* Optionally override the SHELL environment variable. */
! 	  if (options&SY_ENV_SHELL) {
! 	    static char sheq[] = "SHELL=";
! 	    char *p = malloc(sizeof(sheq) + strlen(sh));
! 	    if (p) {
! 	      sprintf(p, "%s%s", sheq, sh);
! 	      putenv(p);
! 	    }
! 	  }
  
  	  /* Go for it. */
  	  if (string) execl(sh, argv_zero(sh), "-c", string, (char *) 0);
--- 685,693 ----
  	  setgid(groupid);
  	  setuid(userid);
  
! 	  set_child_signals(options);
  
! 	  set_child_env(options);
  
  	  /* Go for it. */
  	  if (string) execl(sh, argv_zero(sh), "-c", string, (char *) 0);
***************
*** 308,314 ****
  	  rd = read(pfd[0], &ch, 1);
  	  close(pfd[0]);
  
! 	  while ((w = wait(&status)) != pid)
  	      if (w == -1 && errno != EINTR)
  		  break;
  
--- 707,713 ----
  	  rd = read(pfd[0], &ch, 1);
  	  close(pfd[0]);
  
! 	  while ((w = my_wait(pid,&status)) != pid)
  	      if (w == -1 && errno != EINTR)
  		  break;
  
***************
*** 316,330 ****
  	  if (rd > 0)
  	    stat = -1;
  	  else if (w == pid) {
! #ifdef	WEXITSTATUS
! 	    stat = WEXITSTATUS(status);
! #else
! # ifdef	BSD
! 	    stat = status.w_retcode;
! # else
! 	    stat = status;
! # endif
! #endif
  	  }
    	}
    
--- 715,723 ----
  	  if (rd > 0)
  	    stat = -1;
  	  else if (w == pid) {
! 	    int sig = convert_status(status,&stat);
! 	    if (sig)
! 	      stat = -1;
  	  }
    	}
    
***************
*** 354,397 ****
  	char command[SLEN], buffer[SLEN], *prompt;
  	register int  ret;
  	int	old_raw;
  
  	prompt = catgets(elm_msg_cat, ElmSet, ElmPipeTo, "Pipe to: ");
!         PutLine0(LINES-2, 0, prompt);
  	command[0] = '\0';
! 	(void) optionally_enter(command, LINES-2, strlen(prompt), FALSE, FALSE);
! 	if (command[0] == '\0') {
! 	  MoveCursor(LINES-2,0);
  	  CleartoEOLN();
! 	  return(0);
  	}
  
! 	MoveCursor(LINES,0);
  	CleartoEOLN();
  	if (( old_raw = RawState()) == ON)
  	  Raw(OFF);
  
- 	if (cursor_control)
- 	  transmit_functions(OFF);
- 	
  	sprintf(buffer, "%s -Ih|%s", readmsg, command);
  	ret = system_call(buffer, SY_USER_SHELL|SY_ENAB_SIGINT|SY_DUMPSTATE);
  
  	SetXYLocation(0, 40);	/* a location not near the next request, so an absolute is used */
! 	PutLine0(LINES, 0, catgets(elm_msg_cat, ElmSet, ElmPressAnyKeyToReturn,
  		"\n\nPress any key to return to ELM: "));
  
  	Raw(ON | NO_TITE);
! 	(void) getchar();
  	printf("\r\n");
  	Raw(OFF | NO_TITE); /* Done even if old_raw == ON, to get ti/te right */
  	if (old_raw == ON)
  	  Raw(ON);
  
- 	if (cursor_control)  transmit_functions(ON);
- 
  	if (ret != 0)
! 	  error1(catgets(elm_msg_cat, ElmSet, ElmReturnCodeWas,
! 		"Return code was %d."), ret);
  	return(1);
  }
  
--- 747,802 ----
  	char command[SLEN], buffer[SLEN], *prompt;
  	register int  ret;
  	int	old_raw;
+ 	int redraw = FALSE;
+ 	int status;
  
  	prompt = catgets(elm_msg_cat, ElmSet, ElmPipeTo, "Pipe to: ");
!         PutLine0(elm_LINES-2, 0, prompt);
  	command[0] = '\0';
! 	status = optionally_enter(command, elm_LINES-2, strlen(prompt), 
! 				  OE_REDRAW_MARK, sizeof command);
! 	while (status == REDRAW_MARK) {
! 	  redraw = TRUE;
! 	  PutLine0(elm_LINES-2, 0, prompt);
! 	  status = optionally_enter(command, elm_LINES-2, strlen(prompt), 
! 				    OE_REDRAW_MARK|OE_APPEND_CURRENT,
! 				    sizeof command);
! 
! 	}
! 	if (0 != status || command[0] == '\0') {
! 	  MoveCursor(elm_LINES-2,0);
  	  CleartoEOLN();
! 	  return(redraw);
  	}
  
! 	MoveCursor(elm_LINES,0);
  	CleartoEOLN();
  	if (( old_raw = RawState()) == ON)
  	  Raw(OFF);
  
  	sprintf(buffer, "%s -Ih|%s", readmsg, command);
  	ret = system_call(buffer, SY_USER_SHELL|SY_ENAB_SIGINT|SY_DUMPSTATE);
  
+ redraw2:
  	SetXYLocation(0, 40);	/* a location not near the next request, so an absolute is used */
! 	PutLine0(elm_LINES, 0, catgets(elm_msg_cat, ElmSet, 
! 				       ElmPressAnyKeyToReturn,
  		"\n\nPress any key to return to ELM: "));
  
  	Raw(ON | NO_TITE);
! 	if (ReadCh(REDRAW_MARK) == REDRAW_MARK) {
! 	  Raw(OFF | NO_TITE);
! 	  goto redraw2;
! 	}
  	printf("\r\n");
  	Raw(OFF | NO_TITE); /* Done even if old_raw == ON, to get ti/te right */
  	if (old_raw == ON)
  	  Raw(ON);
  
  	if (ret != 0)
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmReturnCodeWas,
! 			    "Return code was %d."), 
! 		    ret);
  	return(1);
  }
  
***************
*** 430,437 ****
  	 * Make sure we know how to print.
  	 */
  	if (printout[0] == '\0') {
! 	    error(catgets(elm_msg_cat, ElmSet, ElmPrintDontKnowHow,
! 		"Don't know how to print - option \"printmail\" undefined!"));
  	    return 0;
  	}
  
--- 835,842 ----
  	 * Make sure we know how to print.
  	 */
  	if (printout[0] == '\0') {
! 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmPrintDontKnowHow,
! 			    "Don't know how to print - option \"printmail\" undefined!"));
  	    return 0;
  	}
  
***************
*** 463,471 ****
  	 */
  	if ((old_raw = RawState()) == ON)
  	    Raw(OFF | NO_TITE);
! 	softkeys_off();
! 	if (cursor_control)
! 	    transmit_functions(OFF);
  
  	/*
  	 * Run the print command in a pipe and grab the output.
--- 868,874 ----
  	 */
  	if ((old_raw = RawState()) == ON)
  	    Raw(OFF | NO_TITE);
! 	/* softkeys_off(); */
  
  	/*
  	 * Run the print command in a pipe and grab the output.
***************
*** 474,483 ****
  	fflush(stdout);
  	nlines = 0;
  	if ((fp = popen(buffer, "r")) == NULL) {
! 	    error(catgets(elm_msg_cat, ElmSet, ElmPrintPipeFailed,
! 		"Cannot create pipe to print command."));
  	    goto done;
  	}
  	while (fgets(buffer, sizeof(buffer), fp) != NULL) {
  	    fputs(buffer, stdout);
  	    ++nlines;
--- 877,887 ----
  	fflush(stdout);
  	nlines = 0;
  	if ((fp = popen(buffer, "r")) == NULL) {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmPrintPipeFailed,
! 			      "Cannot create pipe to print command."));
  	    goto done;
  	}
+ redraw:
  	while (fgets(buffer, sizeof(buffer), fp) != NULL) {
  	    fputs(buffer, stdout);
  	    ++nlines;
***************
*** 491,497 ****
  		"Press any key to continue:"));
  	    fflush(stdout);
  	    Raw(ON | NO_TITE);
! 	    (void) getchar();
  	}
  
  	/*
--- 895,906 ----
  		"Press any key to continue:"));
  	    fflush(stdout);
  	    Raw(ON | NO_TITE);
! 	    if (ReadCh(REDRAW_MARK) == REDRAW_MARK) {
! 	      Raw(OFF | NO_TITE);
! 	      rewind(fp);
! 	      nlines = 2;
! 	      goto redraw;
! 	    }
  	}
  
  	/*
***************
*** 498,511 ****
  	 * Display a status message.
  	 */
  	if ((retcode = pclose(fp)) == 0) {
! 	    error(catgets(elm_msg_cat, ElmSet, ElmPrintJobSpooled,
! 		"Print job has been spooled."));
  	} else if ((retcode & 0xFF) == 0) {
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmPrintFailCode,
! 		"Printout failed with return code %d."), (retcode>>8));
  	} else {
! 	    error1(catgets(elm_msg_cat, ElmSet, ElmPrintFailStatus,
! 		"Printout failed with status 0x%04x."), (retcode>>8));
  	}
  
  	/*
--- 907,922 ----
  	 * Display a status message.
  	 */
  	if ((retcode = pclose(fp)) == 0) {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmPrintJobSpooled,
! 			      "Print job has been spooled."));
  	} else if ((retcode & 0xFF) == 0) {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmPrintFailCode,
! 			      "Printout failed with return code %d."), 
! 		      (retcode>>8));
  	} else {
! 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmPrintFailStatus,
! 			      "Printout failed with status 0x%04x."), 
! 		      (retcode>>8));
  	}
  
  	/*
***************
*** 518,526 ****
  
  done:
  	Raw(old_raw | NO_TITE);
! 	softkeys_on();
! 	if (cursor_control)
! 	    transmit_functions(ON);
  	(void) unlink(filename);
  	(void) remove_folder_state_file();
  	return (nlines > 1);
--- 929,935 ----
  
  done:
  	Raw(old_raw | NO_TITE);
! 	/* softkeys_on(); */
  	(void) unlink(filename);
  	(void) remove_folder_state_file();
  	return (nlines > 1);
***************
*** 549,555 ****
  
  	Raw(OFF | NO_TITE);
  	ClearScreen();
! 	MoveCursor(LINES, 0);
  	if(helpmsg)
  	  printf(helpmsg);
  	if ( NULL == wildcard )
--- 958,964 ----
  
  	Raw(OFF | NO_TITE);
  	ClearScreen();
! 	MoveCursor(elm_LINES, 0);
  	if(helpmsg)
  	  printf(helpmsg);
  	if ( NULL == wildcard )
***************
*** 622,630 ****
      folder_state_fname = folder_state_env_param + strlen(FOLDER_STATE_ENV) +1;
  
      /* open up the folder state file for writing */
!     if ((fp = fopen(folder_state_fname, "w")) == NULL) {
! 	error1(catgets(elm_msg_cat, ElmSet, ElmCannotCreateFolderState,
! 		"Cannot create folder state file \"%s\"."), folder_state_fname);
  	return -1;
      }
  
--- 1031,1040 ----
      folder_state_fname = folder_state_env_param + strlen(FOLDER_STATE_ENV) +1;
  
      /* open up the folder state file for writing */
!     if ((fp = safeopen(folder_state_fname)) == NULL) {
! 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCannotCreateFolderState,
! 			  "Cannot create folder state file \"%s\"."), 
! 		  folder_state_fname);
  	return -1;
      }
  
***************
*** 665,672 ****
  
      /* put pointer to the file in the environment */
      if (putenv(folder_state_env_param) != 0) {
! 	error1(catgets(elm_msg_cat, ElmSet, ElmCannotCreateEnvParam,
! 	    "Cannot create environment parameter \"%s\"."), FOLDER_STATE_ENV);
  	return -1;
      }
  
--- 1075,1083 ----
  
      /* put pointer to the file in the environment */
      if (putenv(folder_state_env_param) != 0) {
! 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCannotCreateEnvParam,
! 			  "Cannot create environment parameter \"%s\"."), 
! 		  FOLDER_STATE_ENV);
  	return -1;
      }
  
Index: elm2.4.ME+.50/src/utils.c
*** elm2.4.25/src/utils.c	Fri Jun  3 20:05:33 1994
--- elm2.4.ME+.50/src/utils.c	Tue Nov 17 21:12:58 1998
***************
*** 1,105 ****
  
! static char rcsid[] = "@(#)$Id: utils.c,v 5.17 1994/06/03 17:05:17 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.17 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: utils.c,v $
!  * Revision 5.17  1994/06/03  17:05:17  syd
!  * try and prevent copy from calling elm_chown unless needed
!  * From: Syd
!  *
!  * Revision 5.16  1994/05/14  18:42:57  syd
!  * Here are some more of fixes to correctly call fflush() and unlock() in sequence.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.15  1993/09/27  01:51:38  syd
!  * Add elm_chown to consolidate for Xenix not allowing -1
!  * From: Syd
!  *
!  * Revision 5.14  1993/09/20  19:21:12  syd
!  * make fflush conditional on the unit being open
!  * From: Syd
!  *
!  * Revision 5.13  1993/09/19  23:37:29  syd
!  * I found a few places more where the code was missing a call
!  * to fflush() before it called unlock() and fclose()/exit()
!  * right after unlocking the mail drop.
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.12  1993/08/23  03:26:24  syd
!  * Try setting group id separate from user id in chown to
!  * allow restricted systems to change group id of file
!  * From: Syd
!  *
!  * Revision 5.11  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.10  1993/04/12  03:11:50  syd
!  * nameof() didn't check that the character after the common string was /, thus
!  * (if Mail is the folderdir) Maildir/x was made to be =dir/x.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.9  1993/04/12  03:08:40  syd
!  * Added check if headers_per_page is zero in get_page().
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.8  1993/04/12  01:52:31  syd
!  * Initialize safe_malloc() failure trap just to play it safe.  Although
!  * Elm doesn't currently use these routines, do this just in case somebody
!  * someday adds a call to a library routine that does use them.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.7  1993/01/20  03:37:16  syd
!  * Nits and typos in the NLS messages and corresponding default messages.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.6  1993/01/05  03:40:45  syd
!  * Protect TSTP for those systems without it.
!  * From: kevin@cfctech.cfc.com (Kevin Darcy)
!  *
!  * Revision 5.5  1992/12/24  22:05:11  syd
!  * Some OS's, especially ULTRIX create extra continue signals
!  * that confuse Elm on exit
!  * From: Syd via patch from Bob Mason
!  *
!  * Revision 5.4  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.3  1992/12/07  04:30:37  syd
!  * fix missing brace on do_cursor calls
!  * From: Syd
!  *
!  * Revision 5.2  1992/11/26  00:46:13  syd
!  * changes to first change screen back (Raw off) and then issue final
!  * error message.
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** Utility routines for ELM
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: utils.c,v 1.2 1998/10/20 19:58:18 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** Utility routines for ELM
  
***************
*** 106,111 ****
--- 17,23 ----
  **/
  
  #include "headers.h"
+ #include "me.h"
  #include "s_elm.h"
  #include <sys/stat.h>
  #include <errno.h>
***************
*** 116,133 ****
  {
  	/* this creates a new folders directory */
  
- #ifdef MKDIR
  	(void) mkdir(folders, 0700);
- #else
- 	char com[SLEN];
- 
- 	/** Some systems don't have a mkdir call - how inconvienient! **/
- 
- 	sprintf(com, "mkdir %s", folders);
- 	(void) system_call(com, 0);
- 	sprintf(com, "chmod 700 %s", folders);
- 	(void) system_call(com, 0);
- #endif /* MKDIR */
  
  	(void) elm_chown(folders, userid, groupid);
  }
--- 28,34 ----
***************
*** 138,209 ****
  	    old elm files to create a new .elm directory **/
  
  	char source[SLEN];
- #ifdef MKDIR
  	sprintf(source, "%s/.elm", home);
  	(void) mkdir(source, 0700);
- #else
- 	char com[SLEN];
  
- 	/** Some systems don't have a mkdir call - how inconvienient! **/
- 
- 	sprintf(com, "mkdir %s/.elm", home);
- 	(void) system_call(com, 0);
- 	sprintf(com, "chmod 700 %s/.elm", home);
- 	(void) system_call(com, 0);
- #endif /* MKDIR */
- 
  	(void) elm_chown( source, userid, groupid);
  }
  
- move_old_files_to_new()
- {
- 	/** this routine is just for allowing people to transition from
- 	    the old Elm, where things are all kept in their $HOME dir,
- 	    to the new one where everything is in $HOME/.elm... **/
- 
- 	char source[SLEN], dest[SLEN], temp[SLEN];
- 	char com[SLEN];
- 
- 	/** simply go through all the files... **/
- 
- 	sprintf(source, "%s/.alias_text", home);
- 	if (access(source, ACCESS_EXISTS) != -1) {
- 	  sprintf(dest,   "%s/%s", home, ALIAS_TEXT);
- 	  MCprintf(catgets(elm_msg_cat, ElmSet, ElmCopyingFromCopyingTo,
- 		"\n\rCopying from: %s\n\rCopying to:   %s\n\r"),
- 		source, dest);
- 
- 	  sprintf(temp, "/tmp/%d", getpid());
- 	  sprintf(com, "%s -e 's/:/=/g' %s > %s\n", sed_cmd, source, temp);
- 	  (void) system_call(com, 0);
- 	  sprintf(com, "%s %s %s\n", move_cmd, temp, dest);
- 	  (void) system_call(com, 0);
- 	  (void) system_call("newalias", 0);
- 	}
- 
- 	sprintf(source, "%s/.elmheaders", home);
- 	if (access(source, ACCESS_EXISTS) != -1) {
- 	  sprintf(dest,   "%s/%s", home, mailheaders);
- 	  MCprintf(catgets(elm_msg_cat, ElmSet, ElmCopyingFromCopyingTo,
- 		"\n\rCopying from: %s\n\rCopying to:   %s\n\r"),
- 	  	source, dest);
- 	  copy(source, dest, FALSE);
- 	}
- 
- 	sprintf(source, "%s/.elmrc", home);
- 	if (access(source, ACCESS_EXISTS) != -1) {
- 	  sprintf(dest,   "%s/%s", home, elmrcfile);
- 	  MCprintf(catgets(elm_msg_cat, ElmSet, ElmCopyingFromCopyingTo,
- 		"\n\rCopying from: %s\n\rCopying to:   %s\n\r"),
- 	  	source, dest);
- 	  copy(source, dest, FALSE);
- 	}
- 
- 	printf(catgets(elm_msg_cat, ElmSet, ElmWelcomeToNewElm,
- 	"\n\rWelcome to the new version of ELM!\n\n\rHit return to continue."));
- 	getchar();
- }
- 
  
  /*
   * The initialize() procedure sets the "xalloc_fail_handler" vector to
--- 39,50 ----
***************
*** 212,227 ****
  /*ARGSUSED*/
  void malloc_failed_exit(proc, len)
  {
!     MoveCursor(LINES,0);
      Raw(OFF);
      fprintf(stderr, catgets(elm_msg_cat, ElmSet, ElmCouldntMallocBytes,
  	"\n\nCouldn't malloc %d bytes!!\n\n"), len);
!     emergency_exit();
  }
  
! 
! emergency_exit()
  {
  	/** used in dramatic cases when we must leave without altering
  	    ANYTHING about the system... **/
  	int do_cursor = RawState();
--- 53,72 ----
  /*ARGSUSED*/
  void malloc_failed_exit(proc, len)
  {
!     MoveCursor(elm_LINES,0);
      Raw(OFF);
      fprintf(stderr, catgets(elm_msg_cat, ElmSet, ElmCouldntMallocBytes,
  	"\n\nCouldn't malloc %d bytes!!\n\n"), len);
!     emergency_exit(0);
  }
  
! void emergency_exit(interrupt)
!      int interrupt;
  {
+   /* if interrupt is true we can't call anything which 
+    * is not reentrant 
+    */
+ 
  	/** used in dramatic cases when we must leave without altering
  	    ANYTHING about the system... **/
  	int do_cursor = RawState();
***************
*** 242,247 ****
--- 87,95 ----
  	signal(SIGCONT,SIG_IGN);
  #endif
  
+ 	if (interrupt)
+ 	  dprint(1, (debugfile, "\nLeaving mailer from signal handler (emergency_exit)\n"));
+ 
  	dprint(1, (debugfile,
       "\nERROR: Something dreadful is happening!  Taking emergency exit!!\n\n"));
  	dprint(1, (debugfile,
***************
*** 251,265 ****
  	if(folder_type == SPOOL) dprint(1, (debugfile,
  	     "     The mailbox lock file: %s\n", mk_lockname(cur_folder)));
  	dprint(1, (debugfile,
! 	     "     The composition file : %s%s%d\n", temp_dir, temp_file, getpid()));
  
! 	if (cursor_control)  transmit_functions(OFF);
! 	if (hp_terminal)     softkeys_off();
  
  	if (do_cursor) {
  	  Raw(OFF);
! 	  MoveCursor(LINES, 0);
! 	  }
  
  	printf(catgets(elm_msg_cat, ElmSet, ElmEmergencyExitTaken,
  		"\nEmergency exit taken! All temp files intact!\n\n"));
--- 99,113 ----
  	if(folder_type == SPOOL) dprint(1, (debugfile,
  	     "     The mailbox lock file: %s\n", mk_lockname(cur_folder)));
  	dprint(1, (debugfile,
! 	     "     The composition file : %s\n", 
! 		   cur_editfile));
  
! 	/* softkeys_off(); */
  
  	if (do_cursor) {
  	  Raw(OFF);
! 	  MoveCursor(elm_LINES, 0);
! 	}
  
  	printf(catgets(elm_msg_cat, ElmSet, ElmEmergencyExitTaken,
  		"\nEmergency exit taken! All temp files intact!\n\n"));
***************
*** 285,310 ****
  	signal(SIGCONT,SIG_IGN);
  #endif
  
! 	PutLine0(LINES, 0, catgets(elm_msg_cat, ElmSet, ElmWriteFailedExitingIntact,
  	 "\nWrite to temp file failed, exiting leaving mailbox intact!\n\n"));
  	dprint(2, (debugfile, "\nrm_temps_exit, deleteing temp files\n"));
  
! 	if (cursor_control)  transmit_functions(OFF);
! 	if (hp_terminal)     softkeys_off();
  
! 	sprintf(buffer,"%s%d",temp_file, getpid());  /* editor buffer */
! 	(void) unlink(buffer);
  
  	if (folder_type == SPOOL) {
  	    (void) unlink(cur_tempfolder);
  	}
  
! 	if (mailfile)
! 	    fflush (mailfile);
! 	unlock();                               /* remove lock file if any */
  
  	if(do_cursor) {
! 	    MoveCursor(LINES,0);
  	    NewLine();
  	    Raw(OFF);
  	}
--- 133,155 ----
  	signal(SIGCONT,SIG_IGN);
  #endif
  
! 	PutLine0(elm_LINES, 0, catgets(elm_msg_cat, ElmSet, ElmWriteFailedExitingIntact,
  	 "\nWrite to temp file failed, exiting leaving mailbox intact!\n\n"));
  	dprint(2, (debugfile, "\nrm_temps_exit, deleteing temp files\n"));
  
! 	/* softkeys_off(); */
  
! 	if (cur_editfile[0])
! 	  unlink(cur_editfile); /* editor buffer */
  
  	if (folder_type == SPOOL) {
  	    (void) unlink(cur_tempfolder);
  	}
  
! 	unlock(0);                               /* remove lock file if any */
  
  	if(do_cursor) {
! 	    MoveCursor(elm_LINES,0);
  	    NewLine();
  	    Raw(OFF);
  	}
***************
*** 315,326 ****
  /*ARGSUSED*/
  /*VARARGS0*/
  
! leave(val)
! int val;	/* not used, placeholder for signal catching! */
  {
! 	char buffer[SLEN];
! 	int do_cursor = RawState();
  
  /*
   *	some OS's get extra cont signal, so once this far into the
   *	exit, ignore those signals (Especially Ultrix)
--- 160,172 ----
  /*ARGSUSED*/
  /*VARARGS0*/
  
! void leave (interrupt)
!      int interrupt;
  {
!   int do_cursor = RawState();
  
+   /* if interrupt is true do not call anything which is not re-entrant */  
+ 
  /*
   *	some OS's get extra cont signal, so once this far into the
   *	exit, ignore those signals (Especially Ultrix)
***************
*** 328,359 ****
  #ifdef SIGTSTP
  	signal(SIGTSTP,SIG_IGN);
  #endif
- #ifdef SIGSTOP
- 	signal(SIGSTOP,SIG_IGN);
- #endif
  #ifdef SIGCONT
  	signal(SIGCONT,SIG_IGN);
  #endif
  
! 	dprint(2, (debugfile, "\nLeaving mailer normally (leave)\n"));
  
! 	if (cursor_control)  transmit_functions(OFF);
! 	if (hp_terminal)     softkeys_off();
  
! 	sprintf(buffer,"%s%s%d", temp_dir, temp_file, getpid());  /* editor buffer */
! 	(void) unlink(buffer);
  
  	if (folder_type == SPOOL) {
  	  (void) unlink(cur_tempfolder);
  	}
  
! 	if (mailfile)
! 	    fflush (mailfile);
! 
! 	unlock();				/* remove lock file if any */
  
  	if (do_cursor) {
! 	  MoveCursor(LINES,0);
  	  NewLine();
  	  Raw(OFF);
  	}
--- 174,201 ----
  #ifdef SIGTSTP
  	signal(SIGTSTP,SIG_IGN);
  #endif
  #ifdef SIGCONT
  	signal(SIGCONT,SIG_IGN);
  #endif
  
! 	if (interrupt)
! 	  dprint(2, (debugfile, "\nLeaving mailer from signal handler (leave)\n"));
! 	else
! 	  dprint(2, (debugfile, "\nLeaving mailer normally (leave)\n"));
  
! 	/* softkeys_off(); */
  
! 	if (cur_editfile[0])
! 	  unlink(cur_editfile); /* editor buffer */
  
  	if (folder_type == SPOOL) {
  	  (void) unlink(cur_tempfolder);
  	}
  
! 	unlock(interrupt);		    /* remove lock file if any */
  
  	if (do_cursor) {
! 	  MoveCursor(elm_LINES,0);
  	  NewLine();
  	  Raw(OFF);
  	}
***************
*** 367,373 ****
  	    files.  It's used when we notice that we're trying to create a
  	    temp mail file and one already exists!!
  	**/
- 	char buffer[SLEN];
  	int do_cursor = RawState();
  
  /*
--- 209,214 ----
***************
*** 386,406 ****
  
  	dprint(2, (debugfile, "\nLeaving mailer quietly (silently_exit)\n"));
  
! 	if (cursor_control)  transmit_functions(OFF);
! 	if (hp_terminal)     softkeys_off();
  
! 	sprintf(buffer,"%s%s%d", temp_dir, temp_file, getpid());  /* editor buffer */
! 	(void) unlink(buffer);
  
  	if (do_cursor) {
! 	  MoveCursor(LINES,0);
  	  NewLine();
  	  Raw(OFF);
  	}
  
! 	if (mailfile)
! 	    fflush (mailfile);
! 	unlock ();
  
  	exit(0);
  }
--- 227,244 ----
  
  	dprint(2, (debugfile, "\nLeaving mailer quietly (silently_exit)\n"));
  
! 	/* softkeys_off(); */
  
! 	if (cur_editfile[0])
! 	  unlink(cur_editfile);
  
  	if (do_cursor) {
! 	  MoveCursor(elm_LINES,0);
  	  NewLine();
  	  Raw(OFF);
  	}
  
! 	unlock (0);
  
  	exit(0);
  }
***************
*** 413,419 ****
  {
  	/** same as leave routine, but don't disturb lock file **/
  
- 	char buffer[SLEN];
          int do_cursor = RawState();
  
  /*
--- 251,256 ----
***************
*** 433,451 ****
          dprint(3, (debugfile,
  	    "\nLeaving mailer due to presence of lock file (leave_locked)\n"));
  
! 	if (cursor_control)  transmit_functions(OFF);
! 	if (hp_terminal)     softkeys_off();
  
! 	sprintf(buffer,"%s%s%d", temp_dir, temp_file, getpid());  /* editor buffer */
! 	(void) unlink(buffer);
  
  	(void) unlink(cur_tempfolder);			/* temp mailbox */
  
  	if (mailfile)
! 	    fflush (mailfile);
  
  	if (do_cursor) {
! 	  MoveCursor(LINES,0);
  	  NewLine();
  	  Raw(OFF);
  	}
--- 270,287 ----
          dprint(3, (debugfile,
  	    "\nLeaving mailer due to presence of lock file (leave_locked)\n"));
  
! 	/* softkeys_off(); */
  
! 	if (cur_editfile[0])
! 	  unlink(cur_editfile); /* editor buffer */
  
  	(void) unlink(cur_tempfolder);			/* temp mailbox */
  
  	if (mailfile)
! 	    flush_mailfile();
  
  	if (do_cursor) {
! 	  MoveCursor(elm_LINES,0);
  	  NewLine();
  	  Raw(OFF);
  	}
Index: elm2.4.ME+.50/src/wildcards.c
*** elm2.4.25/src/wildcards.c	Fri Dec 11 03:45:40 1992
--- elm2.4.ME+.50/src/wildcards.c	Tue Nov 17 21:12:58 1998
***************
*** 1,42 ****
  
! static char rcsid[] = "@(#)$Id: wildcards.c,v 5.5 1992/12/11 01:45:04 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.5 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: wildcards.c,v $
!  * Revision 5.5  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.4  1992/12/07  05:00:39  syd
!  * Add include of sys/types.h for time_t
!  * From: Syd
!  *
!  * Revision 5.3  1992/10/31  18:59:24  syd
!  * Prevent index underflow when wildchar is in first three chars of string
!  * From: Syd via note from gwh@dogmatix.inmos.co.uk
!  *
!  * Revision 5.2  1992/10/11  01:18:23  syd
!  * Fix where a SHELL=sh would cause a segv due to no / in
!  * the shell name.
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /*
   * Wildcard handling module for elm.
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: wildcards.c,v 1.2 1998/10/20 19:58:18 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /*
   * Wildcard handling module for elm.
Index: elm2.4.ME+.50/src/wordwrap.c
*** elm2.4.25/src/wordwrap.c	Tue Aug  3 22:29:25 1993
--- elm2.4.ME+.50/src/wordwrap.c	Tue Nov 17 21:12:58 1998
***************
*** 1,59 ****
  
! static char rcsid[] = "@(#)$Id: wordwrap.c,v 5.6 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.6 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: wordwrap.c,v $
!  * Revision 5.6  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.5  1993/06/10  03:12:10  syd
!  * Add missing rcs id lines
!  * From: Syd
!  *
!  * Revision 5.4  1993/04/12  03:02:40  syd
!  * Check for EINTR if getchar() returns EOF. Happens after a resume from an
!  * interactive stop.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.3  1993/04/12  02:43:53  syd
!  * The builtin editor couldn't back up to a line that had a character
!  * at the wrapcolumn position.
!  * Added tab handling to the builtin editor.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.2  1993/02/03  16:45:26  syd
!  * A Raw(OFF) was missing so when in mail only mode and one
!  * does f)orget, the "Message saved" ends up on wrong screen.
!  * Also added \r\n to end of messages to make output look nicer.
!  *
!  * When composing mail in the builtin editor, it wrapped on /.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.1  1992/10/03  22:58:40  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /***  Routines to wrap lines when using the "builtin" editor
  
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: wordwrap.c,v 1.2 1998/10/20 19:58:18 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /***  Routines to wrap lines when using the "builtin" editor
  
***************
*** 61,66 ****
--- 18,24 ----
  
  #include "headers.h"
  #include <errno.h>
+ #include "me.h"
  
  extern int errno;		/* system error number */
  
***************
*** 74,85 ****
  	/* WARNING: this macro destroys nr */
  #define erase_tab(nr)		do Writechar(BACKSPACE); while (--(nr) > 0)
  
! int
! wrapped_enter(string, tail, x, y, edit_fd, append_current)
! char *string, *tail;
! int  x,y, *append_current;
! FILE *edit_fd;
  
  {
  	/** This will display the string on the screen and allow the user to
  	    either accept it (by pressing RETURN) or alter it according to
--- 32,45 ----
  	/* WARNING: this macro destroys nr */
  #define erase_tab(nr)		do Writechar(BACKSPACE); while (--(nr) > 0)
  
! static int line_wrap P_((char *,char *,int *,int *, int)); /* Prototype */
  
+ int wrapped_enter(string, tail, x, y, edit_fd, append_current,
+ 		  size_string, size_tail)
+      char *string, *tail;
+      int  x,y, *append_current;
+      FILE *edit_fd;
+      int size_string, size_tail;
  {
  	/** This will display the string on the screen and allow the user to
  	    either accept it (by pressing RETURN) or alter it according to
***************
*** 109,115 ****
  
  	if(!(x >=0 && y >= 0))
  	  GetXYLocation(&x, &y);
! 	PutLine1(x, y, "%s", string);	
  
  	CleartoEOLN();
  
--- 69,75 ----
  
  	if(!(x >=0 && y >= 0))
  	  GetXYLocation(&x, &y);
! 	PutLineX(x, y, FRM("%s"), string);	
  
  	CleartoEOLN();
  
***************
*** 119,127 ****
  	else
  	  iindex = strlen(string);
  
- 	if (cursor_control)
- 	  transmit_functions(OFF);
- 
  	/** now we have the screen as we want it and the cursor in the 
  	    right place, we can loop around on the input and return the
  	    string as soon as the user presses <RETURN> or the line wraps.
--- 79,84 ----
***************
*** 128,143 ****
  	**/
  
  	do {
! 	  ch = getchar();
  
! 	  if (ch == EOF && ferror(stdin) && errno == EINTR) {
! 	    clearerr(stdin);
! 	    continue;
! 	  }
! 
! 	  if (ch == ctrl('D') || ch == EOF) {		/* we've hit EOF */
! 	    if (cursor_control)
! 	      transmit_functions(ON);
  	    *append_current = 0;
  	    return(1);
  	  }
--- 85,94 ----
  	**/
  
  	do {
! 	  ch = ReadCh(0|READCH_NOCURSOR);
  
! 	  if (ch == eof_char && !escaped 
! 	      || ch == EOF) {		/* we've hit EOF */
  	    *append_current = 0;
  	    return(1);
  	  }
***************
*** 144,151 ****
  
  	  if (ch_count++ == 0) {
  	    if (ch == '\n' || ch == '\r') {
- 	      if (cursor_control)
- 	        transmit_functions(ON);
  	      *append_current = 0;
  	      return(0);
  	    }
--- 95,100 ----
***************
*** 181,190 ****
  	      } else {
  
  		/** get the last 256 bytes written **/
! 		if ((newpos = pos - 256L) <= 0L) newpos = 0;
! 		(void) fseek(edit_fd, newpos, 0L);
! 		(void) fread(line, sizeof(*line), (int) (pos-newpos),
! 		             edit_fd);
  		pos--;
  
  		/** the last char in line should be '\n'
--- 130,140 ----
  	      } else {
  
  		/** get the last 256 bytes written **/
! 		if ((newpos = pos - (long)(sizeof line)) <= 0L) 
! 		  newpos = 0;
! 		fseek(edit_fd, newpos, SEEK_SET);
! 		fread(line, sizeof(*line), (int) (pos-newpos),
! 		      edit_fd);
  		pos--;
  
  		/** the last char in line should be '\n'
***************
*** 198,218 ****
  		/** check to see if this was the first line in the file **/
  		if (line[(int) (pos-newpos)] == '\n') /** no - it wasn't **/
  		  pos++;
! 		(void) strcpy(string, &line[(int) (pos-newpos)]);
  		line[(int) (pos-newpos)] = '\0';
  
  		/** truncate the file to the current position
  			THIS WILL NOT WORK ON SYS-V **/
! 		(void) fseek(edit_fd, newpos, 0L);
  		(void) fputs(line, edit_fd);
  		fflush(edit_fd);
  		(void) ftruncate(fileno(edit_fd), (int) ftell(edit_fd));
! 		(void) fseek(edit_fd, ftell(edit_fd), 0L);
  
  		/** rewrite line on screen and continue working **/
  		GetXYLocation(&x, &y);
  		if (x > 0) x--;
! 		PutLine1(x, y, "%s", string);
  		CleartoEOLN();
  		iindex = strlen(string);
  
--- 148,169 ----
  		/** check to see if this was the first line in the file **/
  		if (line[(int) (pos-newpos)] == '\n') /** no - it wasn't **/
  		  pos++;
! 		(void) strfcpy(string, &line[(int) (pos-newpos)],
! 			       size_string);
  		line[(int) (pos-newpos)] = '\0';
  
  		/** truncate the file to the current position
  			THIS WILL NOT WORK ON SYS-V **/
! 		(void) fseek(edit_fd, newpos, SEEK_SET);
  		(void) fputs(line, edit_fd);
  		fflush(edit_fd);
  		(void) ftruncate(fileno(edit_fd), (int) ftell(edit_fd));
! 		(void) fseek(edit_fd, ftell(edit_fd), SEEK_SET);
  
  		/** rewrite line on screen and continue working **/
  		GetXYLocation(&x, &y);
  		if (x > 0) x--;
! 		PutLineX(x, y, FRM("%s"), string);
  		CleartoEOLN();
  		iindex = strlen(string);
  
***************
*** 231,242 ****
  	  else if (ch == EOF || ch == '\n' || ch == '\r') {
  	    escaped = OFF;
  	    string[iindex] = '\0';
- 	    if (cursor_control)
- 	      transmit_functions(ON);
  	    *append_current = 0;
  	    return(0);
  	  }
! 	  else if (ch == ctrl('W')) {	/* back up a word! */
  	    escaped = OFF;
  	    if (iindex == 0)
  	      continue;		/* no point staying here.. */
--- 182,191 ----
  	  else if (ch == EOF || ch == '\n' || ch == '\r') {
  	    escaped = OFF;
  	    string[iindex] = '\0';
  	    *append_current = 0;
  	    return(0);
  	  }
! 	  else if (ch == word_erase && !escaped) {	/* back up a word! */
  	    escaped = OFF;
  	    if (iindex == 0)
  	      continue;		/* no point staying here.. */
***************
*** 260,269 ****
  	      iindex++;	/* and make sure we point at the first AVAILABLE slot */
  	    }
  	  }
! 	  else if (ch == ctrl('R')) {
  	    escaped = OFF;
  	    string[iindex] = '\0';
! 	    PutLine1(x,y, "%s", string);	
  	    CleartoEOLN();
  	  }
  	  else if (!escaped && ch == kill_line) {
--- 209,218 ----
  	      iindex++;	/* and make sure we point at the first AVAILABLE slot */
  	    }
  	  }
! 	  else if (ch == reprint_char && !escaped) {
  	    escaped = OFF;
  	    string[iindex] = '\0';
! 	    PutLineX(x,y, FRM("%s"), string);	
  	    CleartoEOLN();
  	  }
  	  else if (!escaped && ch == kill_line) {
***************
*** 274,283 ****
  	    CleartoEOLN();
  	    iindex = 0;
  	  }
! 	  else if (ch == '\0') {
  	    escaped = OFF;
- 	    if (cursor_control)
- 	      transmit_functions(ON);
  	    fflush(stdin); 	/* remove extraneous chars, if any */
  	    string[0] = '\0'; /* clean up string, and... */
  	    *append_current = 0;
--- 223,231 ----
  	    CleartoEOLN();
  	    iindex = 0;
  	  }
! 	  else if (ch == '\0' || 
! 		   ch == interrupt_char && !escaped) {
  	    escaped = OFF;
  	    fflush(stdin); 	/* remove extraneous chars, if any */
  	    string[0] = '\0'; /* clean up string, and... */
  	    *append_current = 0;
***************
*** 302,308 ****
  		string[iindex++] = ch;
  		Writechar(ch);
  	        escaped = OFF;
! 	      } else {
  		if (ch == '\t')
  		  addon += (tabs[tindex++] = 8 - ((addon+iindex) & 07)) - 1;
  
--- 250,256 ----
  		string[iindex++] = ch;
  		Writechar(ch);
  	        escaped = OFF;
! 	      } else if (iindex < size_string-2) {
  		if (ch == '\t')
  		  addon += (tabs[tindex++] = 8 - ((addon+iindex) & 07)) - 1;
  
***************
*** 311,332 ****
  		escaped = ( ch == '\\' ? ON : OFF);
  	      }
  	  }
! 	} while (iindex+addon < wrapcolumn);
  
  	string[iindex] = '\0';
! 	*append_current = line_wrap(string,tail,&iindex,&tabs[tindex-1]);
  
- 	if (cursor_control)
- 	  transmit_functions(ON);
  	return(0);
  }
  
! int
! line_wrap(string,tail,count,tabs)
! char *string;	/* The string to be wrapped */
! char *tail;	/* The part of the string which is wrapped */
! int *count;	/* Offset of string terminator */
! int *tabs;	/* List of how many spaces each tab adds */
  {
  	/** This will check for line wrap.  If the line was wrapped,
  	    it will back up to white space (if possible), write the
--- 259,280 ----
  		escaped = ( ch == '\\' ? ON : OFF);
  	      }
  	  }
! 	} while (iindex+addon < wrapcolumn && 
! 		 iindex < size_string-2);
  
  	string[iindex] = '\0';
! 	*append_current = line_wrap(string,tail,&iindex,&tabs[tindex-1],
! 				    size_tail);
  
  	return(0);
  }
  
! static int line_wrap(string,tail,count,tabs, size_tail)
!      char *string;	/* The string to be wrapped */
!      char *tail;	/* The part of the string which is wrapped */
!      int *count;	/* Offset of string terminator */
!      int *tabs;	/* List of how many spaces each tab adds */
!      int size_tail;
  {
  	/** This will check for line wrap.  If the line was wrapped,
  	    it will back up to white space (if possible), write the
***************
*** 345,352 ****
  	if (n) {
  
  	  /* Copy part to be wrapped */
! 	  for (i=0,j=n+1;j<=*count;tail[i++]=string[j++]);
  
  	  /* Skip the break character and any whitespace */
  	  while (n && isstopchar(string[n]))
  	    --n;
--- 293,304 ----
  	if (n) {
  
  	  /* Copy part to be wrapped */
! 	  for (i=0,j=n+1;
! 	       j<=*count &&
! 		 i < size_tail-1;
! 	       tail[i++]=string[j++]);
  
+ 	  tail[i] = '\0';
  	  /* Skip the break character and any whitespace */
  	  while (n && isstopchar(string[n]))
  	    --n;
***************
*** 357,371 ****
  	/* If no break found */
  	if (!n) {
  	  (*count)--;
! 	  strcpy(tail, &string[*count]);
  	  erase_a_char();
  	} else /* Erase the stuff that will wrap */
  	  while (*count > n) {
  	    --(*count);
! 	  if (string[*count] == '\t') erase_tab(*tabs--);
! 	  else erase_a_char();
  	  }
  
  	string[*count] = '\0';
  	return(1);
  }
--- 309,324 ----
  	/* If no break found */
  	if (!n) {
  	  (*count)--;
! 	  strfcpy(tail, &string[*count], size_tail);
  	  erase_a_char();
  	} else /* Erase the stuff that will wrap */
  	  while (*count > n) {
  	    --(*count);
! 	    if (string[*count] == '\t') erase_tab(*tabs--);
! 	    else erase_a_char();
  	  }
  
  	string[*count] = '\0';
  	return(1);
  }
+ 
Index: elm2.4.ME+.50/utils/Makefile.SH
*** elm2.4.25/utils/Makefile.SH	Thu Mar 10 19:20:29 1994
--- elm2.4.ME+.50/utils/Makefile.SH	Tue Nov 17 21:12:58 1998
***************
*** 16,57 ****
  echo "Extracting utils/Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
  
! # @(#)$Id: Makefile.SH,v 5.6 1994/03/10 17:20:23 syd Exp $
  #
  #  Makefile for the Elm system utilities
  #
  #         (C) Copyright 1986,1987, by Dave Taylor
  #         (C) Copyright 1988-1992, USENET Community Trust
- #
- # Bug reports, patches, comments, suggestions should be sent to:
- #
- #	Syd Weinstein - elm@DSI.COM
- #			dsinc!elm
- #
- # $Log: Makefile.SH,v $
- # Revision 5.6  1994/03/10  17:20:23  syd
- # Remove autoreply
- # From: Syd
- #
- # Revision 5.5  1993/05/31  19:17:28  syd
- # In the Makefile listalias was given only a+x permission
- # though it should have been a+rx.
- # From: Jukka Ukkonen <ukkonen@csc.fi>
- #
- # Revision 5.4  1993/04/16  05:07:10  syd
- # add elmalias
- #
- # Revision 5.3  1993/04/12  02:14:15  syd
- # Fix comments
- #
- # Revision 5.2  1993/04/12  02:11:05  syd
- # Added new utilities "elmalias" and "prlong".  Modified "checkalias"
- # and "listalias" to use them.
- # From: chip@chinacat.unicom.com (Chip Rosenthal)
- #
- # Revision 5.1  1992/10/04  00:46:45  syd
- # Initial checkin as of 2.4 Release at PL0
- #
  # 
  #
  # Variables
--- 16,27 ----
  echo "Extracting utils/Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
  
! # @(#)$Id: Makefile.SH,v 1.2 1998/10/20 19:58:38 hurtta Exp $
  #
  #  Makefile for the Elm system utilities
  #
  #         (C) Copyright 1986,1987, by Dave Taylor
  #         (C) Copyright 1988-1992, USENET Community Trust
  # 
  #
  # Variables
***************
*** 83,89 ****
  
  #	Other general variables
  BIN		=	../bin
! CFLAGS		=	$(CCFLAGS) $(OPTIMIZE) -I$(INCLDIR) $(DEBUG) $(DACSNET) 
  INCLDIR		=	../hdrs
  LINTFLAGS	=	-I$(INCLDIR)
  SHELL		=	/bin/sh
--- 53,59 ----
  
  #	Other general variables
  BIN		=	../bin
! CFLAGS		=	-I$(INCLDIR) $(CCFLAGS) $(OPTIMIZE) $(DEBUG) $(DACSNET) 
  INCLDIR		=	../hdrs
  LINTFLAGS	=	-I$(INCLDIR)
  SHELL		=	/bin/sh
***************
*** 317,323 ****
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
! $(INCLDIR)/elmutil.h:	$(INCLDIR)/curses.h $(INCLDIR)/defs.h
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
--- 287,293 ----
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
! $(INCLDIR)/elmutil.h:	$(INCLDIR)/curses.h $(INCLDIR)/defs.h $(INCLDIR)/elmlib.h
  			$(CHMOD) u+w $@
  			$(TOUCH) $@
  
Index: elm2.4.ME+.50/utils/answer.c
*** elm2.4.25/utils/answer.c	Tue Aug 10 21:54:15 1993
--- elm2.4.ME+.50/utils/answer.c	Tue Nov 17 21:14:09 1998
***************
*** 1,57 ****
  
! static char rcsid[] = "@(#)$Id: answer.c,v 5.7 1993/08/10 18:54:13 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.7 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: answer.c,v $
!  * Revision 5.7  1993/08/10  18:54:13  syd
!  * A change to answer:s mail command to be like those of elm and filter.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.6  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.5  1993/02/04  15:32:52  syd
!  * Add cast to silence compiler warning.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.4  1993/01/20  03:37:16  syd
!  * Nits and typos in the NLS messages and corresponding default messages.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.3  1992/10/11  01:46:35  syd
!  * change dbm name to dbz to avoid conflicts with partial call
!  * ins from shared librarys, and from mixing code with yp code.
!  * From: Syd via prompt from Jess Anderson
!  *
!  * Revision 5.2  1992/10/11  01:25:58  syd
!  * Add undefs of tolower so BSD macro isnt used from ctype.h
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/04  00:46:45  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This program is a phone message transcription system, and
      is designed for secretaries and the like, to allow them to
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: answer.c,v 1.4 1998/11/07 14:12:22 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.4 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This program is a phone message transcription system, and
      is designed for secretaries and the like, to allow them to
***************
*** 61,67 ****
  	  even read in the system alias file at all.
  
  **/
- 
  #include "elmutil.h"
  #include "ndbz.h"
  #include "s_answer.h"
--- 20,25 ----
***************
*** 72,81 ****
  int user_data;		/* fileno of user data file   */
  DBZ *hash;		/* dbz file for same */
  
! #ifdef DEBUG
! FILE *debugfile = stderr;
! int  debug = 0;
! #endif
  
  char *get_alias_address(), *get_token(), *strip_parens(), *shift_lower();
  
--- 30,36 ----
  int user_data;		/* fileno of user data file   */
  DBZ *hash;		/* dbz file for same */
  
! static int translate P_((char *fullname, char *name, int namesize));
  
  char *get_alias_address(), *get_token(), *strip_parens(), *shift_lower();
  
***************
*** 91,101 ****
  	int   msgnum = 0, eof, allow_name = 0, phone_slip = 0;
  	int   ans_pid = getpid();
  	
- #ifdef I_LOCALE
- 	setlocale(LC_ALL, "");
- #endif
  
! 	elm_msg_cat = catopen("elm2.4", 0);
  
  	quit_word = catgets(elm_msg_cat, AnswerSet, AnswerQuitWord, "quit");
  	exit_word = catgets(elm_msg_cat, AnswerSet, AnswerExitWord, "exit");
--- 46,53 ----
  	int   msgnum = 0, eof, allow_name = 0, phone_slip = 0;
  	int   ans_pid = getpid();
  	
  
! 	locale_init();
  
  	quit_word = catgets(elm_msg_cat, AnswerSet, AnswerQuitWord, "quit");
  	exit_word = catgets(elm_msg_cat, AnswerSet, AnswerExitWord, "exit");
***************
*** 120,125 ****
--- 72,81 ----
  	    phone_slip = 1;
  	  }
  	}
+ 	
+ 	user_init();
+ 	init_defaults();
+ 	read_rc_file();
  
  	open_alias_file();
  
***************
*** 147,153 ****
  	      (istrcmp(user_name, bye_word)  == 0))
  	     exit(0);
  
! 	  if (translate(user_name, name) == 0)
  	    goto prompt;
  
  	  address = get_alias_address(name, 1, 0);
--- 103,109 ----
  	      (istrcmp(user_name, bye_word)  == 0))
  	     exit(0);
  
! 	  if (translate(user_name, name, sizeof name) == 0)
  	    goto prompt;
  
  	  address = get_alias_address(name, 1, 0);
***************
*** 165,181 ****
  
  	  printf("address '%s'\n", address);
  
! 	  sprintf(tempfile, "%sans.%d.%d", default_temp, ans_pid, msgnum++);
! 
! 	  if ((fd = fopen(tempfile,"w")) == NULL)
! 	    exit(printf(catgets(elm_msg_cat, AnswerSet, AnswerCouldNotOpenWrite,
! 			"** Fatal Error: could not open %s to write\n"),
! 		 tempfile));
! 
  
  	/** Enter standard phone message fields **/
  	  if (phone_slip) {
! 	    strcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerCaller, "Caller: "));
  	    printf("\n%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
--- 121,142 ----
  
  	  printf("address '%s'\n", address);
  
! 	  elm_sfprintf(tempfile, sizeof tempfile,
! 		       FRM("%sans.%d.%d"), 
! 		       default_temp, ans_pid, msgnum++);
! 
! 	  if ((fd = fopen(tempfile,"w")) == NULL) {
! 	    lib_error(CATGETS(elm_msg_cat, AnswerSet, AnswerCouldNotOpenWrite,
! 			      "** Fatal Error: could not open %s to write\n"),
! 		      tempfile);
! 	    exit(1);
! 	  }
  
  	/** Enter standard phone message fields **/
  	  if (phone_slip) {
! 	    strfcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerCaller, 
! 				    "Caller: "),
! 		    sizeof buffer);
  	    printf("\n%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
***************
*** 182,188 ****
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerOf, "of:     "));
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
--- 143,151 ----
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strfcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerOf, 
! 				    "of:     "),
! 		    sizeof buffer);
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
***************
*** 189,195 ****
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerPhone, "Phone:  "));
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
--- 152,160 ----
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strfcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerPhone, 
! 				    "Phone:  "),
! 		    sizeof buffer);
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
***************
*** 196,202 ****
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s\n",buffer,in_line);
  
! 	    strcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerTelephoned, "TELEPHONED         - "));
  	    printf("\n%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
--- 161,169 ----
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s\n",buffer,in_line);
  
! 	    strfcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerTelephoned, 
! 				    "TELEPHONED         - "),
! 		    sizeof buffer);
  	    printf("\n%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
***************
*** 203,209 ****
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerCalledToSeeYou, "CALLED TO SEE YOU  - "));
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
--- 170,179 ----
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strfcpy(buffer, catgets(elm_msg_cat, AnswerSet, 
! 				    AnswerCalledToSeeYou, 
! 				    "CALLED TO SEE YOU  - "),
! 		    sizeof buffer);
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
***************
*** 210,216 ****
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerWantsToSeeYou, "WANTS TO SEE YOU   - "));
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
--- 180,189 ----
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strfcpy(buffer, catgets(elm_msg_cat, AnswerSet, 
! 				    AnswerWantsToSeeYou, 
! 				    "WANTS TO SEE YOU   - "),
! 		    sizeof buffer);
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
***************
*** 217,223 ****
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerReturnedYourCall, "RETURNED YOUR CALL - "));
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
--- 190,199 ----
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strfcpy(buffer, catgets(elm_msg_cat, AnswerSet, 
! 				    AnswerReturnedYourCall, 
! 				    "RETURNED YOUR CALL - "),
! 		    sizeof buffer);
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
***************
*** 224,230 ****
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerPleaseCall, "PLEASE CALL        - "));
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
--- 200,208 ----
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strfcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerPleaseCall, 
! 				    "PLEASE CALL        - "),
! 		    sizeof buffer);
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
***************
*** 231,237 ****
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerWillCallAgain, "WILL CALL AGAIN    - "));
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
--- 209,218 ----
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strfcpy(buffer, catgets(elm_msg_cat, AnswerSet, 
! 				    AnswerWillCallAgain, 
! 				    "WILL CALL AGAIN    - "),
! 		    sizeof buffer);
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
***************
*** 238,244 ****
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerUrgent, "*****URGENT******  - "));
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
--- 219,227 ----
  	    if (strlen(in_line) > 1)
  	      fprintf(fd,"%s%s",buffer,in_line);
  
! 	    strfcpy(buffer, catgets(elm_msg_cat, AnswerSet, AnswerUrgent, 
! 				    "*****URGENT******  - "),
! 		    sizeof buffer);
  	    printf("%s",buffer);
  	    fflush(stdout);
  	    fgets(in_line, SLEN, stdin);
***************
*** 260,276 ****
  	
  	  fclose(fd);
   
! 	  sprintf(buffer, catgets(elm_msg_cat, AnswerSet, AnswerElmCommand,
! 	     "( ( %s -s \"While You Were Out\" %s < %s ; %s %s) & ) > /dev/null"),
! 	     ELM, strip_parens(address), tempfile, remove_cmd, tempfile);
  
  	  system(buffer);
  	}
  }
  
! int
! translate(fullname, name)
! char *fullname, *name;
  {
  	/** translate fullname into name..
  	       'first last'  translated to first_initial - underline - last
--- 243,260 ----
  	
  	  fclose(fd);
   
! 	  elm_sfprintf(buffer, sizeof buffer,
! 		       CATGETS(elm_msg_cat, AnswerSet, AnswerElmCommand,
! 			       "( ( %s -s \"While You Were Out\" %s < %s ; %s %s) & ) > /dev/null"),
! 		       ELM, strip_parens(address), tempfile, remove_cmd, tempfile);
  
  	  system(buffer);
  	}
  }
  
! static int translate(fullname, name, namesize)
!      char *fullname, *name;
!      int namesize;
  {
  	/** translate fullname into name..
  	       'first last'  translated to first_initial - underline - last
***************
*** 295,303 ****
  	}
  
  	if (lastname) 
! 	  sprintf(name, "%c_%s", fullname[0], (char *) fullname + lastname);
  	else
! 	  strcpy(name, fullname);
  
  	return(1);
  }
--- 279,289 ----
  	}
  
  	if (lastname) 
! 	  elm_sfprintf(name, namesize,
! 		       FRM("%c_%.*s"), 
! 		       fullname[0], namesize-4, (char *) fullname + lastname);
  	else
! 	  strfcpy(name, fullname, namesize);
  
  	return(1);
  }
***************
*** 309,315 ****
  
  	char fname[SLEN];
  
! 	sprintf(fname,  "%s/.elm/aliases", getenv("HOME")); 
  
  	if ((hash = dbz_open(fname, O_RDONLY, 0)) == NULL) 
  	  exit(printf("** Fatal Error: Could not open %s!\n", fname));
--- 295,301 ----
  
  	char fname[SLEN];
  
! 	strfcpy(fname,user_data_file,sizeof fname);
  
  	if ((hash = dbz_open(fname, O_RDONLY, 0)) == NULL) 
  	  exit(printf("** Fatal Error: Could not open %s!\n", fname));
***************
*** 318,323 ****
--- 304,316 ----
  	  return;
  }
  
+ static int expand_group P_((
+ 			    char *target,
+ 			    char *members,
+ 			    int   depth,
+ 			    int targetsize));
+ 
+ 
  char *get_alias_address(name, mailing, depth)
  char *name;
  int   mailing, depth;
***************
*** 348,366 ****
  	read(user_data, buffer, entry.length > VERY_LONG_STRING ? VERY_LONG_STRING : entry.length);
  	if ((entry.type & GROUP) != 0 && mailing) {
  	    if (expand_group(sprbuffer, buffer + (int) entry.address,
! 			     depth) < 0)
  		return NULL;
  	} else {
! 	    sprintf(sprbuffer, "%s (%s)", buffer + (int) entry.address,
! 		    buffer + (int) entry.name);
  	}
  	return sprbuffer;
  }
  
! int expand_group(target, members, depth)
! char *target;
! char *members;
! int   depth;
  {
  	/** given a group of names separated by commas, this routine
  	    will return a string that is the full addresses of each
--- 341,362 ----
  	read(user_data, buffer, entry.length > VERY_LONG_STRING ? VERY_LONG_STRING : entry.length);
  	if ((entry.type & GROUP) != 0 && mailing) {
  	    if (expand_group(sprbuffer, buffer + (int) entry.address,
! 			     depth, sizeof sprbuffer) < 0)
  		return NULL;
  	} else {
! 	    elm_sfprintf(sprbuffer, sizeof sprbuffer,
! 			 FRM("%s (%s)"), 
! 			 buffer + (int) entry.address,
! 			 buffer + (int) entry.name);
  	}
  	return sprbuffer;
  }
  
! static int expand_group(target, members, depth, targetsize)
!      char *target;
!      char *members;
!      int   depth;
!      int targetsize;
  {
  	/** given a group of names separated by commas, this routine
  	    will return a string that is the full addresses of each
***************
*** 369,375 ****
  
  	char   buf[VERY_LONG_STRING], *word, *address, *bufptr;
  
! 	strcpy(buf, members); 	/* parameter safety! */
  	target[0] = '\0';	/* nothing in yet!   */
  	bufptr = (char *) buf;	/* grab the address  */
  	depth++;		/* one more deeply into stack */
--- 365,371 ----
  
  	char   buf[VERY_LONG_STRING], *word, *address, *bufptr;
  
! 	strfcpy(buf, members, sizeof buf); 	/* parameter safety! */
  	target[0] = '\0';	/* nothing in yet!   */
  	bufptr = (char *) buf;	/* grab the address  */
  	depth++;		/* one more deeply into stack */
***************
*** 376,387 ****
  
  	while ((word = (char *) get_token(bufptr, "!, ", depth)) != NULL) {
  	  if ((address = (char *) get_alias_address(word, 1, depth)) == NULL) {
! 	    fprintf(stderr, catgets(elm_msg_cat, AnswerSet, AnswerNotFoundForGroup,
! 		"Alias %s not found for group expansion!\n"), word);
  	    return -1;
  	  }
  	  else if (strcmp(target,address) != 0) {
! 	    sprintf(target + strlen(target), " %s", address);
  	  }
  
  	  bufptr = NULL;
--- 372,386 ----
  
  	while ((word = (char *) get_token(bufptr, "!, ", depth)) != NULL) {
  	  if ((address = (char *) get_alias_address(word, 1, depth)) == NULL) {
! 	    lib_error(CATGETS(elm_msg_cat, AnswerSet, AnswerNotFoundForGroup,
! 			      "Alias %s not found for group expansion!\n"), 
! 		      word);
  	    return -1;
  	  }
  	  else if (strcmp(target,address) != 0) {
! 	    elm_sfprintf(target + strlen(target), targetsize - strlen(target),
! 			 FRM(" %s"), 
! 			 address);
  	  }
  
  	  bufptr = NULL;
Index: elm2.4.ME+.50/utils/checkalias.SH
*** elm2.4.25/utils/checkalias.SH	Mon Apr 12 05:11:06 1993
--- elm2.4.ME+.50/utils/checkalias.SH	Tue Nov 17 21:12:59 1998
***************
*** 17,23 ****
  echo $startsh > checkalias
  cat >>checkalias <<!DO!SUBS!
  # checkalias: part of the Elm mail system
! # @(#)$Id: checkalias.SH,v 5.2 1993/04/12 02:11:05 syd Exp $
  #		Copyright (c) 1988-1992 USENET Community Trust
  # 		Copyright (c) 1986,1987 Dave Taylor
   
--- 17,23 ----
  echo $startsh > checkalias
  cat >>checkalias <<!DO!SUBS!
  # checkalias: part of the Elm mail system
! # @(#)$Id: checkalias.SH,v 1.1.1.1 1998/10/15 15:36:44 hurtta Exp $
  #		Copyright (c) 1988-1992 USENET Community Trust
  # 		Copyright (c) 1986,1987 Dave Taylor
   
Index: elm2.4.ME+.50/utils/elmalias.c
*** elm2.4.25/utils/elmalias.c	Mon May 30 19:31:58 1994
--- elm2.4.ME+.50/utils/elmalias.c	Tue Nov 17 21:14:09 1998
***************
*** 1,56 ****
  
! static char rcsid[] = "@(#)$Id: elmalias.c,v 5.9 1994/05/30 16:31:40 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.9 $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: elmalias.c,v $
!  * Revision 5.9  1994/05/30  16:31:40  syd
!  * make getpwuid dependent on ANSI_C not posix flag
!  * From: Syd
!  *
!  * Revision 5.8  1993/09/27  01:05:37  syd
!  * Eliminate warning about redeclaring getpwuid().
!  * From: riacs!rutgers!tscs.tscs.com!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.7  1993/09/19  23:12:00  syd
!  * Add ability for elmalias to determine HOME if missing from the environment.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.6  1993/08/23  02:44:41  syd
!  * fix where checkalias doesn't fully expand multi-database aliases
!  * From: Steve Wolf <woof@atl.hp.com>
!  *
!  * Revision 5.5  1993/08/03  19:23:25  syd
!  * Added -d option to elmalias.
!  * From: Jan.Djarv@sa.erisoft.se (Jan Djarv)
!  *
!  * Revision 5.4  1993/07/27  20:27:33  syd
!  * fix strchr, Elm uses define to make index strchr when needed
!  * From: Syd
!  *
!  * Revision 5.3  1993/07/20  02:59:53  syd
!  * Support aliases both on 64 bit and 32 bit machines at the same time.
!  * From: Dan Mosedale <mosedale@genome.stanford.edu>
!  *
!  * Revision 5.2  1993/05/16  20:55:32  syd
!  * fix elmalias bug
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1993/04/12  02:09:29  syd
!  * Initial Checkin
!  *
!  *
!  ******************************************************************************/
  
  /*
   * elmalias - Elm alias database access.
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: elmalias.c,v 1.4 1998/11/07 14:12:22 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.4 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /*
   * elmalias - Elm alias database access.
***************
*** 124,133 ****
  /*
   * These are used by the "dbz" routines.
   */
- #ifdef DEBUG
- int debug = 0;
- FILE *debugfile = stderr;
- #endif
  
  char *Progname;
  
--- 84,89 ----
***************
*** 186,195 ****
      /*
       * Initialize.
       */
! #ifdef I_LOCALE
!     setlocale(LC_ALL, "");
! #endif
!     elm_msg_cat = catopen("elm2.4", 0); /* parlez vous francais?	*/
      safe_malloc_fail_handler =	/* install procedure to trap errors in	*/
  	malloc_fail_handler;	/*   the safe_malloc() routines		*/
      Progname = argv[0];		/* program name for diag messages	*/
--- 142,150 ----
      /*
       * Initialize.
       */
! 
!     locale_init();
! 
      safe_malloc_fail_handler =	/* install procedure to trap errors in	*/
  	malloc_fail_handler;	/*   the safe_malloc() routines		*/
      Progname = argv[0];		/* program name for diag messages	*/
***************
*** 200,205 ****
--- 155,164 ----
      out_fmt = "%v";		/* default is to just show alias value	*/
      numdb = 0;			/* no alias files opened yet		*/
  
+     user_init();
+     init_defaults();
+     read_rc_file();
+ 
      /*
       * Crack command line options.
       */
***************
*** 335,358 ****
  
  DBZ *open_user_aliases()
  {
-     char *home, *fname;
      DBZ *db;
!     struct passwd *pw;
! 
!     if ((home = getenv("HOME")) == NULL || *home == '\0') {
! 	if ((pw = getpwuid(getuid())) == NULL) {
! 	    fprintf(stderr, catgets(elm_msg_cat, ElmaliasSet,
! 		ElmaliasCannotDetermineHome,
! 		"%s: cannot determine your HOME directory\n"), Progname);
! 	    exit(1);
! 	}
! 	home = pw->pw_dir;
! 	endpwent();
!     }
!     fname = (char *)safe_malloc(strlen(home) + 1 + strlen(ALIAS_DATA) + 1);
!     (void) strcat(strcat(strcpy(fname, home), "/"), ALIAS_DATA);
!     db = dbz_open(fname, O_RDONLY, 0);
!     (void) free((malloc_t)fname);
      return db;
  }
  
--- 294,301 ----
  
  DBZ *open_user_aliases()
  {
      DBZ *db;
!     db = dbz_open(user_data_file, O_RDONLY, 0);
      return db;
  }
  
Index: elm2.4.ME+.50/utils/fastmail.c
*** elm2.4.25/utils/fastmail.c	Fri Mar 11 22:55:25 1994
--- elm2.4.ME+.50/utils/fastmail.c	Tue Nov 17 21:14:09 1998
***************
*** 1,69 ****
  
! static char rcsid[] = "@(#)$Id: fastmail.c,v 5.9 1994/03/11 20:55:23 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.9 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: fastmail.c,v $
!  * Revision 5.9  1994/03/11  20:55:23  syd
!  * Replaced the get_tz_mins() routine in lib/get_tz.c with a portable
!  * version that requires no configuration.  Rewrote the test case in
!  * lib/get_tz.c, and also wrote in support to simplify configuration
!  * tests.  Dropped TZMINS_USE_XXXX configuration parameter.  Simplified
!  * timezone determination in Configure.  The new get_tz_mins() introduces
!  * two side effects.  First it steps on the static data returned by
!  * localtime().  Second, it uses a routine in lib/date_util.c, which
!  * requires debug initializations.  Rewrote get_arpa_date() to work around
!  * the first issue.  Rather than doing the same for lib/strftime.c, just
!  * removed the timezone stuff with a conditional compile.  Elm does not
!  * use it.  Added debugging initializations to util/fastmail.c.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.8  1993/07/20  02:46:36  syd
!  * In fastmail, if environment variable $REPLYTO is set, use it as
!  * default Reply-To.  Also, eliminate unnecessary strlen() calls.
!  * From: decwrl!uunet.UU.NET!fin!chip (Chip Salzenberg)
!  *
!  * Revision 5.7  1993/06/06  18:31:43  syd
!  * fix typo
!  *
!  * Revision 5.6  1993/06/06  18:08:51  syd
!  * Make it use the message catalog already defined
!  * From: Super Y.S.T. <tabata@matsumoto.dcl.co.jp>
!  *
!  * Revision 5.5  1993/02/03  16:49:11  syd
!  * added the RFC822 fields Comments, In-Reply-To and References.
!  * to fastmail.
!  * From: Greg Smith <smith@heliotrope.bucknell.edu>
!  *
!  * Revision 5.4  1992/11/22  01:26:12  syd
!  * The fastmail utility appears to work incorrectly when multiple addresses are
!  * supplied. Spaces were inserted between addresses rather than commas.
!  * From: little@carina.hks.com (Jim Littlefield)
!  *
!  * Revision 5.3  1992/10/30  21:12:40  syd
!  * Make patchlevel a text string to allow local additions to the variable
!  * From: syd via a request from Dave Wolfe
!  *
!  * Revision 5.2  1992/10/11  00:59:39  syd
!  * Fix some compiler warnings that I receive compiling Elm on my SVR4
!  * machine.
!  * From: Tom Moore <tmoore@fievel.DaytonOH.NCR.COM>
!  *
!  * Revision 5.1  1992/10/04  00:46:45  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This program is specifically written for group mailing lists and
      such batch type mail processing.  It does NOT use aliases at all,
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: fastmail.c,v 1.3 1998/11/07 14:12:22 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This program is specifically written for group mailing lists and
      such batch type mail processing.  It does NOT use aliases at all,
***************
*** 104,111 ****
  char *get_arpa_date();
  static void usage();
  
- int debug = 0;
- FILE *debugfile = stderr;
  
  
  main(argc, argv)
--- 51,56 ----
***************
*** 116,122 ****
  	extern char *optarg;
  	extern int optind;
  	FILE *tempfile;
! 	char hostname[NLEN], username[NLEN], from_string[SLEN], subject[SLEN];
  	char filename[SLEN], tempfilename[SLEN], command_buffer[256];
  	char replyto[SLEN], cc_list[SLEN], bcc_list[SLEN], to_list[SLEN];
  	char from_addr[SLEN], comments[SLEN], inreplyto[NLEN];
--- 61,68 ----
  	extern char *optarg;
  	extern int optind;
  	FILE *tempfile;
! 	char hostname[NLEN], username[NLEN+L_cuserid], from_string[SLEN], 
! 	  subject[SLEN];
  	char filename[SLEN], tempfilename[SLEN], command_buffer[256];
  	char replyto[SLEN], cc_list[SLEN], bcc_list[SLEN], to_list[SLEN];
  	char from_addr[SLEN], comments[SLEN], inreplyto[NLEN];
***************
*** 124,130 ****
  	char *p;
  	int  c, sendmail_available;
  
! 	elm_msg_cat = catopen("elm2.4", 0);
  
  	from_string[0] = '\0';
  	subject[0] = '\0';
--- 70,76 ----
  	char *p;
  	int  c, sendmail_available;
  
! 	locale_init();
  
  	from_string[0] = '\0';
  	subject[0] = '\0';
***************
*** 137,157 ****
  	inreplyto[0] = '\0';
  	references[0] = '\0';
  
  	if ((p = getenv("REPLYTO")) != NULL)
! 	  strcpy(replyto, p);
  
  	while ((c = getopt(argc, argv, "b:c:C:df:F:i:r:R:s:")) != EOF) {
  	  switch (c) {
! 	    case 'b' : strcpy(bcc_list, optarg);		break;
! 	    case 'c' : strcpy(cc_list, optarg);		break;
! 	    case 'C' : strcpy(comments, optarg);		break;
  	    case 'd' : debug++;					break;	
! 	    case 'f' : strcpy(from_string, optarg);	break;
! 	    case 'F' : strcpy(from_addr, optarg);		break;
! 	    case 'i' : strcpy(inreplyto, optarg);		break;
! 	    case 'r' : strcpy(replyto, optarg);		break;
! 	    case 'R' : strcpy(references, optarg);		break;
! 	    case 's' : strcpy(subject, optarg);		break;
  	    case '?' : usage();
   	  }
  	}	
--- 83,116 ----
  	inreplyto[0] = '\0';
  	references[0] = '\0';
  
+ 	user_init();
+ 	init_defaults();
+ 	read_rc_file();
+ 
  	if ((p = getenv("REPLYTO")) != NULL)
! 	  strfcpy(replyto, p, sizeof replyto);
  
  	while ((c = getopt(argc, argv, "b:c:C:df:F:i:r:R:s:")) != EOF) {
  	  switch (c) {
! 	    case 'b' : strfcpy(bcc_list, optarg, 
! 			       sizeof bcc_list);		break;
! 	    case 'c' : strfcpy(cc_list, optarg, 
! 			       sizeof cc_list);		break;
! 	    case 'C' : strfcpy(comments, optarg, 
! 			       sizeof comments);		break;
  	    case 'd' : debug++;					break;	
! 	    case 'f' : strfcpy(from_string, optarg,
! 			       sizeof from_string);	break;
! 	    case 'F' : strfcpy(from_addr, optarg,
! 			       sizeof from_addr);		break;
! 	    case 'i' : strfcpy(inreplyto, optarg,
! 			       sizeof inreplyto);		break;
! 	    case 'r' : strfcpy(replyto, optarg,
! 			       sizeof replyto);		break;
! 	    case 'R' : strfcpy(references, optarg,
! 			       sizeof references);		break;
! 	    case 's' : strfcpy(subject, optarg,
! 			       sizeof subject);		break;
  	    case '?' : usage();
   	  }
  	}	
***************
*** 160,183 ****
  	  usage();
  	}
  
! 	strcpy(filename, argv[optind++]);
  
  	if (optind >= argc) {
  	  usage();
  	}
  
- #ifdef HOSTCOMPILED
- 	strncpy(hostname, HOSTNAME, sizeof(hostname));
- #else
- 	gethostname(hostname, sizeof(hostname));
- #endif
- 
- 	username[0] = '\0';
- 	if ((p = getlogin()) != NULL)
- 	  strcpy(username, p);
- 	if (!username[0])
- 	  cuserid(username);
- 
  	if (strcmp(filename, "-")) {
  	  if (access(filename, READ_ACCESS) == -1) {
  	    fprintf(stderr, "Error: can't find file %s!\n", filename);
--- 119,130 ----
  	  usage();
  	}
  
! 	strfcpy(filename, argv[optind++], sizeof filename);
  
  	if (optind >= argc) {
  	  usage();
  	}
  
  	if (strcmp(filename, "-")) {
  	  if (access(filename, READ_ACCESS) == -1) {
  	    fprintf(stderr, "Error: can't find file %s!\n", filename);
***************
*** 185,191 ****
  	  }
  	}
  
! 	sprintf(tempfilename, "%s%d", temphome, getpid());
  
  	if ((tempfile = fopen(tempfilename, "w")) == NULL) {
  	  fprintf(stderr, "Couldn't open temp file %s\n", tempfilename);
--- 132,140 ----
  	  }
  	}
  
! 	elm_sfprintf(tempfilename, sizeof tempfilename,
! 		     FRM("%s%d"), 
! 		     temphome, getpid());
  
  	if ((tempfile = fopen(tempfilename, "w")) == NULL) {
  	  fprintf(stderr, "Couldn't open temp file %s\n", tempfilename);
***************
*** 240,247 ****
  
  	while (optind < argc) {
  	  if (to_list[0])
! 	    strcat(to_list, ",");
! 	  strcat(to_list, argv[optind++]);
  	}
  	
  	fprintf(tempfile, "To: %s\n", to_list);
--- 189,196 ----
  
  	while (optind < argc) {
  	  if (to_list[0])
! 	    strfcat(to_list, ",", sizeof to_list);
! 	  strfcat(to_list, argv[optind++], sizeof to_list);
  	}
  	
  	fprintf(tempfile, "To: %s\n", to_list);
***************
*** 276,285 ****
  			(bcc_list[0] ? " ":""), bcc_list,
  			sendmail_available? "sendmail" : "rmail");
  
! 	sprintf(command_buffer, "cat %s %s | %s %s %s %s", 
! 		tempfilename, filename, 
! 	        sendmail_available? sendmail : mailer,
! 		to_list, cc_list, bcc_list);
  
  	if (debug)
  	  printf("%s\n", command_buffer);
--- 225,235 ----
  			(bcc_list[0] ? " ":""), bcc_list,
  			sendmail_available? "sendmail" : "rmail");
  
! 	elm_sfprintf(command_buffer, sizeof command_buffer,
! 		     FRM("cat %s %s | %s %s %s %s"), 
! 		     tempfilename, filename, 
! 		     sendmail_available? sendmail : mailer,
! 		     to_list, cc_list, bcc_list);
  
  	if (debug)
  	  printf("%s\n", command_buffer);
Index: elm2.4.ME+.50/utils/from.c
*** elm2.4.25/utils/from.c	Mon May 30 19:27:00 1994
--- elm2.4.ME+.50/utils/from.c	Tue Nov 17 21:14:09 1998
***************
*** 1,94 ****
  
! static char rcsid[] = "@(#)$Id: from.c,v 5.15 1994/05/30 16:27:00 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.15 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: from.c,v $
!  * Revision 5.15  1994/05/30  16:27:00  syd
!  * In utils/from.c there was a conditionalized declaration of
!  * getpwuid() which was triggered by the environment being non-
!  * POSIX instead of non-STDC.
!  * From: Jukka Antero Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.14  1993/05/31  19:36:07  syd
!  * Dave Thomas forgot to update the NLS message file when he added the tidy
!  * option to frm.  While I was at it, I did a little cleanup to keep things
!  * alphabetized.
!  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
!  *
!  * Revision 5.13  1993/05/14  03:58:37  syd
!  * This is a trivial patch to 'from.c' to tidy up the output is
!  * the cases where the 'from' part is longer that 20 characters.
!  * It adds the new '-t' (for tidy) option:
!  * From: dave@devteq.co.uk (Dave Thomas)
!  *
!  * Revision 5.12  1993/05/14  03:57:10  syd
!  * When frm checked for file access on a POSIX system there
!  * was a test `&& S_ISREG(mode)' instead of `&& ! S_ISREG(mode)'
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.11  1993/04/21  01:18:09  syd
!  * frm treated a line with From_ preceeded by whitespace as a valid
!  * message delimiter.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.10  1993/04/12  03:33:39  syd
!  * the posix macros to interpret the result of the stat-call.
!  * From: vogt@isa.de (Gerald Vogt)
!  *
!  * Revision 5.9  1993/04/12  02:25:16  syd
!  * remove extra blank in the new  messages line
!  *
!  * Revision 5.8  1993/01/27  21:07:55  syd
!  * if no files are given to frm, and it cannot open the mail spool,
!  * print No mail.
!  *
!  * Revision 5.7  1993/01/27  20:52:20  syd
!  * fixed the behaviour of the tool nfrm or frm -snew to be inconsistent
!  * with elm itself. In from.c it never recognized the file in the MAIL
!  * environment variable to be a SPOOL file as you say in the source.
!  * From: Erick Otto <eotto@hvlpa.ns-nl.att.com>
!  *
!  * Revision 5.6  1993/01/19  05:07:05  syd
!  * Trim erroreous extra log entry
!  * From: Syd
!  *
!  * Revision 5.5  1993/01/19  04:47:12  syd
!  * Significant changes to provide consistent Date and From_ header
!  * cracking.  Overhauled date utilities and moved into library.  Moved
!  * real_from() into library.  Modified frm, newmail, and readmsg utilities
!  * to use library version of real_from().  Moved get_word() from Elm
!  * source into library.  Added new library routines atonum() and strfcpy().
!  * Fixed trailing backslash bug in len_next().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.4  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.3  1992/11/07  21:03:33  syd
!  * fix typo
!  *
!  * Revision 5.2  1992/11/07  20:05:52  syd
!  * change to use header_cmp to allow for linear white space around the colon
!  * From: Syd
!  *
!  * Revision 5.1  1992/10/04  00:46:45  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** print out whom each message is from in the pending folder or specified 
      one, including a subject line if available.
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: from.c,v 1.3 1998/11/07 14:12:22 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** print out whom each message is from in the pending folder or specified 
      one, including a subject line if available.
***************
*** 144,159 ****
        verbose = FALSE;	/* and should we prepend a header? */
  
  char infile[SLEN];	/* current file name */
- char defaultfile[SLEN];	/* default file name */
  char realname[SLEN];	/* the username of the user who ran the program */
  
  extern char *whos_mail(), *explain();
  
- #ifdef DEBUG
- int debug = 0;
- FILE *debugfile = stderr;
- #endif
- 
  
  main(argc, argv)
  int argc;
--- 66,75 ----
***************
*** 174,184 ****
  	extern int optind;
  	extern char *optarg;
  
! #ifdef I_LOCALE
! 	setlocale(LC_ALL, "");
! #endif
! 
! 	elm_msg_cat = catopen("elm2.4", 0);
  
  	/*
  	 * check the first character of the command basename to
--- 90,99 ----
  	extern int optind;
  	extern char *optarg;
  
! 	locale_init();
! 	user_init();
! 	init_defaults();
! 	read_rc_file();
  
  	/*
  	 * check the first character of the command basename to
***************
*** 262,276 ****
  	  exit(EXIT_ERROR);
  	}
  
! 	strcpy(username,pass->pw_name);
! 	strcpy(realname,username);
  
  	/*
  	 * from init.c: Get the host name as per configured behavior.
  	 */
  #ifdef HOSTCOMPILED
! 	strncpy(hostname, HOSTNAME, sizeof(hostname) - 1);
! 	hostname[sizeof(hostname) - 1] = '\0';
  #else
  	gethostname(hostname, sizeof(hostname));
  #endif
--- 177,190 ----
  	  exit(EXIT_ERROR);
  	}
  
! 	strfcpy(username,pass->pw_name, sizeof username);
! 	strfcpy(realname,username, sizeof realname);
  
  	/*
  	 * from init.c: Get the host name as per configured behavior.
  	 */
  #ifdef HOSTCOMPILED
! 	strfcpy(hostname, HOSTNAME, sizeof hostname);
  #else
  	gethostname(hostname, sizeof(hostname));
  #endif
***************
*** 283,299 ****
  	domlen = strlen(hostdomain);
  	if (hostlen >= domlen) {
  	  if (istrcmp(&hostname[hostlen - domlen], hostdomain) == 0)
! 	    strcpy(hostfullname, hostname);
  	  else {
! 	    strcpy(hostfullname, hostname);
! 	    strcat(hostfullname, hostdomain);
  	  }
  	} else {
  	  if (istrcmp(hostname, hostdomain + 1) == 0)
! 	    strcpy(hostfullname, hostname);
  	  else {
! 	    strcpy(hostfullname, hostname);
! 	    strcat(hostfullname, hostdomain);
  	  }
  	}
  
--- 197,213 ----
  	domlen = strlen(hostdomain);
  	if (hostlen >= domlen) {
  	  if (istrcmp(&hostname[hostlen - domlen], hostdomain) == 0)
! 	    strfcpy(hostfullname, hostname, sizeof hostfullname);
  	  else {
! 	    strfcpy(hostfullname, hostname, sizeof hostfullname);
! 	    strfcat(hostfullname, hostdomain, sizeof hostfullname);
  	  }
  	} else {
  	  if (istrcmp(hostname, hostdomain + 1) == 0)
! 	    strfcpy(hostfullname, hostname, sizeof hostfullname);
  	  else {
! 	    strfcpy(hostfullname, hostname, sizeof hostfullname);
! 	    strfcat(hostfullname, hostdomain, sizeof hostfullname);
  	  }
  	}
  
***************
*** 306,316 ****
  	 *	else use password entry
  	 */
  	  if ((cp = getenv("MAIL")) == NULL) {
! 	    sprintf(infile,"%s%s",mailhome, username);
  	  }
  	  else {
! 	    strcpy(defaultfile, cp);
! 	    strcpy(infile, cp);
  	  }
  	  optind -= 1;	/* ensure one pass through loop */
  	}
--- 220,232 ----
  	 *	else use password entry
  	 */
  	  if ((cp = getenv("MAIL")) == NULL) {
! 	    elm_sfprintf(infile,sizeof infile,
! 			 FRM("%s%s"),
! 			 mailhome, username);
  	  }
  	  else {
! 	    strfcpy(defaultfile, cp, sizeof defaultfile);
! 	    strfcpy(infile, cp, sizeof infile);
  	  }
  	  optind -= 1;	/* ensure one pass through loop */
  	}
***************
*** 322,335 ****
  	  /* copy next argument into infile */
  
  	  if (multiple_files) {
! 	    strcpy(infile, argv[optind]);
  	    printf("%s%s: \n", output_files++ > 0 ? "\n":"", infile);
  	  }
  	  else if (infile[0] == '\0')
! 	    strcpy(infile, argv[optind]);
  
  	  if (metachar(infile[0])) {
! 	    if (expand(infile) == 0) {
  	       fprintf(stderr,catgets(elm_msg_cat,
  				      FromSet,FromCouldntExpandFilename,
  				      "%s: couldn't expand filename %s!\n"), 
--- 238,251 ----
  	  /* copy next argument into infile */
  
  	  if (multiple_files) {
! 	    strfcpy(infile, argv[optind], sizeof infile);
  	    printf("%s%s: \n", output_files++ > 0 ? "\n":"", infile);
  	  }
  	  else if (infile[0] == '\0')
! 	    strfcpy(infile, argv[optind], sizeof infile);
  
  	  if (metachar(infile[0])) {
! 	    if (expand(infile, sizeof infile) == 0) {
  	       fprintf(stderr,catgets(elm_msg_cat,
  				      FromSet,FromCouldntExpandFilename,
  				      "%s: couldn't expand filename %s!\n"), 
***************
*** 402,418 ****
  	     * this affects the "To" processing.
  	     */
  	    if (strncmp(infile, mailhome, strlen(mailhome)) == 0)
! 	      strcpy(username, infile+strlen(mailhome));
  	    else
! 	      strcpy(username, realname);
  
  	    /*
  	     * then get full username
  	     */
  	    if((cp = get_full_name(username)) != NULL)
! 	      strcpy(full_username, cp);
  	    else
! 	      strcpy(full_username, username);
  
  	    read_headers(user_mailbox, &total_msgs, &selected_msgs);
  
--- 318,334 ----
  	     * this affects the "To" processing.
  	     */
  	    if (strncmp(infile, mailhome, strlen(mailhome)) == 0)
! 	      strfcpy(username, infile+strlen(mailhome), sizeof username);
  	    else
! 	      strfcpy(username, realname, sizeof username);
  
  	    /*
  	     * then get full username
  	     */
  	    if((cp = get_full_name(username)) != NULL)
! 	      strfcpy(full_username, cp,sizeof full_username);
  	    else
! 	      strfcpy(full_username, username, sizeof full_username);
  
  	    read_headers(user_mailbox, &total_msgs, &selected_msgs);
  
***************
*** 520,526 ****
  	  }
  #else
  	  if (first_word(buffer, "From ") && real_from(buffer, &hdr)) {
! 	    strcpy(from_whom, hdr.from);
  	    subject[0] = '\0';
  	    to_whom[0] = '\0';
  	    in_header = TRUE;
--- 436,442 ----
  	  }
  #else
  	  if (first_word(buffer, "From ") && real_from(buffer, &hdr)) {
! 	    strfcpy(from_whom, hdr.env_from, sizeof from_whom);
  	    subject[0] = '\0';
  	    to_whom[0] = '\0';
  	    in_header = TRUE;
***************
*** 533,555 ****
  	  else if (in_header) {
  #ifdef MMDF
  	    if (real_from(buffer, &hdr))
! 	      strcpy(from_whom, hdr.from);
  	    else
  #endif /* MMDF */
! 	    if (first_word(buffer,">From ")) 
! 	      forwarded(buffer, from_whom); /* return address */
! 	    else if (header_cmp(buffer,"Subject", NULL) ||
! 		     header_cmp(buffer,"Re", NULL)) {
! 	      if (subject[0] == '\0') {
! 	        remove_header_keyword(buffer);
! 		strcpy(subject, buffer);
  	      }
! 	    }
! 	    else if (header_cmp(buffer,"From", NULL) ||
! 		     header_cmp(buffer, ">From", NULL))
! 	      parse_arpa_who(buffer, from_whom, FALSE);
  	    else if (header_cmp(buffer, "To", NULL))
! 	      figure_out_addressee(index(buffer, ':') + 1, to_whom);
  	    else if (header_cmp(buffer, "Status", NULL)) {
  	      remove_header_keyword(buffer);
  	      switch (*buffer) {
--- 449,473 ----
  	  else if (in_header) {
  #ifdef MMDF
  	    if (real_from(buffer, &hdr))
! 	      strfcpy(from_whom, hdr.env_from, sizeof from_whom);
  	    else
  #endif /* MMDF */
! 	      if (first_word_nc(buffer,">From ")) {
! 		forwarded(buffer+6, &hdr); /* return address */
! 		strfcpy(from_whom, hdr.env_from, sizeof from_whom);
! 	      } else if (header_cmp(buffer,"Subject", NULL) ||
! 			 header_cmp(buffer,"Re", NULL)) {
! 		if (subject[0] == '\0') {
! 		  remove_header_keyword(buffer);
! 		  strfcpy(subject, buffer, sizeof subject);
! 		}
  	      }
! 	      else if (header_cmp(buffer,"From", NULL))
! 		parse_arpa_who(buffer+6, from_whom, 
! 			       decode_who_none, sizeof from_whom);
  	    else if (header_cmp(buffer, "To", NULL))
! 	      figure_out_addressee(index(buffer, ':') + 1, to_whom,
! 				   sizeof to_whom);
  	    else if (header_cmp(buffer, "Status", NULL)) {
  	      remove_header_keyword(buffer);
  	      switch (*buffer) {
***************
*** 565,571 ****
  	      in_header = FALSE;
  #ifdef MMDF
  	      if (*from_whom == '\0')
!                 strcpy(from_whom,username);
  #endif /* MMDF */
  	      count++;
  	      summary[status]++;
--- 483,489 ----
  	      in_header = FALSE;
  #ifdef MMDF
  	      if (*from_whom == '\0')
!                 strfcpy(from_whom,username, sizeof from_whom);
  #endif /* MMDF */
  	      count++;
  	      summary[status]++;
***************
*** 593,602 ****
  
  		selected_msgs++;
  		if (! quiet) {
! 		  if (tail_of(from_whom, who, to_whom) == 1) {
! 		    strcpy(buffer, "To ");
! 		    strcat(buffer, who);
! 		    strcpy(who, buffer);
  		  }
   
  		  /***
--- 511,520 ----
  
  		selected_msgs++;
  		if (! quiet) {
! 		  if (tail_of(from_whom, who, to_whom, sizeof who) == 1) {
! 		    strfcpy(buffer, "To ", sizeof buffer);
! 		    strfcat(buffer, who, sizeof buffer);
! 		    strfcpy(who, buffer, sizeof who);
  		  }
   
  		  /***
***************
*** 685,721 ****
  	}
  }
  
- 
- forwarded(buffer, who)
- char *buffer, *who;
- {
- 	/** change 'from' and date fields to reflect the ORIGINATOR of 
- 	    the message by iteratively parsing the >From fields... **/
- 
- 	char machine[SLEN], buff[SLEN], holding_from[SLEN];
- 
- 	machine[0] = '\0';
- 	holding_from[0] = '\0';
- 	sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %*s %s",
- 	            holding_from, machine);
- 
- 	if(machine[0] == '\0')	/* try for address with timezone in date */
- 	sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s",
- 	            holding_from, machine);
- 
- 	if (machine[0] == '\0') /* try for srm address */
- 	  sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s",
- 	            holding_from, machine);
- 
- 	if (machine[0] == '\0')
- 	  sprintf(buff, holding_from[0] ? holding_from :
- 		  catgets(elm_msg_cat,FromSet,FromAnon, "anonymous"));
- 	else
- 	  sprintf(buff,"%s!%s", machine, holding_from);
- 
- 	strncpy(who, buff, SLEN);
- }
- 
  /*
   * Return an appropriate string as to whom this mailbox belongs.
   */
--- 603,608 ----
***************
*** 731,747 ****
  	  if (*mailname == '/')
  	    mailname++;
  	  if (strcmp(mailname, realname) == 0)
! 	    strcpy(whos_who,catgets(elm_msg_cat,
! 				    FromSet,FromYouHave,"You have"));
  	  else {
! 	    strcpy(whos_who, mailname);
! 	    strcat(whos_who,catgets(elm_msg_cat,FromSet,FromHas, " has"));
  	  }
  	}
  	else
  	/* punt... */
! 	     strcpy(whos_who,catgets(elm_msg_cat,
! 				     FromSet,FromYouHave,"You have"));
  
  	return whos_who;
  }
--- 618,637 ----
  	  if (*mailname == '/')
  	    mailname++;
  	  if (strcmp(mailname, realname) == 0)
! 	    strfcpy(whos_who,catgets(elm_msg_cat,
! 				     FromSet,FromYouHave,"You have"),
! 		    sizeof whos_who);
  	  else {
! 	    strfcpy(whos_who, mailname, sizeof whos_who);
! 	    strfcat(whos_who,catgets(elm_msg_cat,FromSet,FromHas, " has"),
! 		    sizeof whos_who);
  	  }
  	}
  	else
  	/* punt... */
! 	  strfcpy(whos_who,catgets(elm_msg_cat,
! 				   FromSet,FromYouHave,"You have"),
! 		  sizeof whos_who);
  
  	return whos_who;
  }
Index: elm2.4.ME+.50/utils/listalias.SH
*** elm2.4.25/utils/listalias.SH	Mon Apr 12 05:10:38 1993
--- elm2.4.ME+.50/utils/listalias.SH	Tue Nov 17 21:12:59 1998
***************
*** 17,23 ****
  echo $startsh > listalias
  cat >>listalias <<'!NO!SUBS!'
  # listalias: part of the Elm mail system
! # @(#)$Id: listalias.SH,v 5.1 1993/04/12 02:10:26 syd Exp $
  #		Copyright (c) 1988-1992 USENET Community Trust
  # 		Copyright (c) 1986,1987 Dave Taylor
  
--- 17,23 ----
  echo $startsh > listalias
  cat >>listalias <<'!NO!SUBS!'
  # listalias: part of the Elm mail system
! # @(#)$Id: listalias.SH,v 1.1.1.1 1998/10/15 15:36:44 hurtta Exp $
  #		Copyright (c) 1988-1992 USENET Community Trust
  # 		Copyright (c) 1986,1987 Dave Taylor
  
Index: elm2.4.ME+.50/utils/mailrc.awk
*** elm2.4.25/utils/mailrc.awk	Sun Oct  4 03:47:00 1992
--- elm2.4.ME+.50/utils/mailrc.awk	Tue Nov 17 21:12:58 1998
***************
*** 1,15 ****
  #
! # @(#)$Id: mailrc.awk,v 5.1 1992/10/04 00:46:45 syd Exp $
  #		Copyright (c) 1988-1992 USENET Community Trust
  # 		Copyright (c) 1986,1987 Dave Taylor
- # Bug reports, patches, comments, suggestions should be sent to:
- #
- #	Syd Weinstein, Elm Coordinator - elm@DSI.COM
- #					 dsinc!elm
- #
- # $Log: mailrc.awk,v $
- # Revision 5.1  1992/10/04  00:46:45  syd
- # Initial checkin as of 2.4 Release at PL0
  #
  # 
  #
--- 1,8 ----
  #
! # @(#)$Id: mailrc.awk,v 1.2 1998/10/20 19:58:38 hurtta Exp $
! #
  #		Copyright (c) 1988-1992 USENET Community Trust
  # 		Copyright (c) 1986,1987 Dave Taylor
  #
  # 
  #
Index: elm2.4.ME+.50/utils/messages.SH
*** elm2.4.25/utils/messages.SH	Sun Oct 18 01:38:59 1992
--- elm2.4.ME+.50/utils/messages.SH	Tue Nov 17 21:12:58 1998
***************
*** 17,23 ****
  echo $startsh > messages
  cat >>messages <<'!NO!SUBS!'
  # messages: part of the Elm mail system
! # @(#)$Id: messages.SH,v 5.2 1992/10/17 22:38:58 syd Exp $
  #		Copyright (c) 1988-1992 USENET Community Trust
  # 		Copyright (c) 1986,1987 Dave Taylor
   
--- 17,23 ----
  echo $startsh > messages
  cat >>messages <<'!NO!SUBS!'
  # messages: part of the Elm mail system
! # @(#)$Id: messages.SH,v 1.1.1.1 1998/10/15 15:36:44 hurtta Exp $
  #		Copyright (c) 1988-1992 USENET Community Trust
  # 		Copyright (c) 1986,1987 Dave Taylor
   
Index: elm2.4.ME+.50/utils/newalias.c
*** elm2.4.25/utils/newalias.c	Sat May  8 23:25:03 1993
--- elm2.4.ME+.50/utils/newalias.c	Tue Nov 17 21:14:09 1998
***************
*** 1,36 ****
  
! static char rcsid[] = "@(#)$Id: newalias.c,v 5.4 1993/05/08 20:24:55 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
-  *******************************************************************************
-  * Bug reports, patches, comments, suggestions should be sent to:
-  *
-  *	Syd Weinstein, Elm Coordinator
-  *	elm@DSI.COM			dsinc!elm
-  *
-  *******************************************************************************
-  * $Log: newalias.c,v $
-  * Revision 5.4  1993/05/08  20:24:55  syd
-  * add sleepmsg for not in elm mode
-  *
-  * Revision 5.3  1992/10/11  01:10:31  syd
-  * Add missing setlocale and catopen (just forgotten)
-  * From: Syd
-  *
-  * Revision 5.2  1992/10/11  00:59:39  syd
-  * Fix some compiler warnings that I receive compiling Elm on my SVR4
-  * machine.
-  * From: Tom Moore <tmoore@fievel.DaytonOH.NCR.COM>
-  *
-  * Revision 5.1  1992/10/04  00:46:45  syd
-  * Initial checkin as of 2.4 Release at PL0
-  *
   *
!  ******************************************************************************/
  
  /** Install a new set of aliases for the 'Elm' mailer. 
  
--- 1,17 ----
  
! static char rcsid[] = "@(#)$Id: newalias.c,v 1.4 1998/11/07 14:12:22 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.4 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
   *
!  *****************************************************************************/
  
  /** Install a new set of aliases for the 'Elm' mailer. 
  
***************
*** 55,67 ****
  
  void error();
  
- #ifdef DEBUG
- FILE *debugfile = stderr;
- int  debug = 0;
- #endif
- 
  int  is_system=0;		/* system file updating?     */
- int  sleepmsg=0;		/* not in elm, dont wait for messages */
  
  main(argc, argv)
  int argc;
--- 36,42 ----
***************
*** 71,81 ****
  	char home_dir[SLEN];		/* the users home directory  */
  	int  a;
  
! #ifdef I_LOCALE
! 	setlocale(LC_ALL, "");
! #endif
  
! 	elm_msg_cat = catopen("elm2.4", 0);
  
  	for (a = 1; a < argc; ++a) {
  	  if (strcmp(argv[a], "-g") == 0)
--- 46,58 ----
  	char home_dir[SLEN];		/* the users home directory  */
  	int  a;
  
! 
! 	locale_init();
! 	user_init();
! 	init_defaults();
! 	read_rc_file();
  
! 	sleepmsg=0;		/* not in elm, dont wait for messages */
  
  	for (a = 1; a < argc; ++a) {
  	  if (strcmp(argv[a], "-g") == 0)
***************
*** 95,115 ****
  	    printf(catgets(elm_msg_cat, NewaliasSet, NewaliasUpdateSystem,
  	            "Updating the system alias file..."));
  
! 	    strcpy(inputname, system_text_file);
! 	    strcpy(dataname,  system_data_file);
  	}
  	else {
  	    printf(catgets(elm_msg_cat, NewaliasSet, NewaliasUpdatePersonal,
  		"Updating your personal alias file..."));
  	
! 	    if (strcpy(home_dir, getenv("HOME")) == NULL) {
  	        error(catgets(elm_msg_cat, NewaliasSet, NewaliasNoHOME,
  		        "I'm confused - no HOME variable in environment!"));
  	        exit(1);
  	    }
  
! 	    MCsprintf(inputname, "%s/%s", home_dir, ALIAS_TEXT);
! 	    MCsprintf(dataname,  "%s/%s", home_dir, ALIAS_DATA); 
  	}
  
  	if ((a = do_newalias(inputname, dataname, FALSE, TRUE)) < 0) {
--- 72,95 ----
  	    printf(catgets(elm_msg_cat, NewaliasSet, NewaliasUpdateSystem,
  	            "Updating the system alias file..."));
  
! 	    strfcpy(inputname, system_text_file, sizeof inputname);
! 	    strfcpy(dataname,  system_data_file, sizeof dataname);
  	}
  	else {
+ 	  char *cp = getenv("HOME");
  	    printf(catgets(elm_msg_cat, NewaliasSet, NewaliasUpdatePersonal,
  		"Updating your personal alias file..."));
  	
! 	    if (cp == NULL) {
  	        error(catgets(elm_msg_cat, NewaliasSet, NewaliasNoHOME,
  		        "I'm confused - no HOME variable in environment!"));
  	        exit(1);
  	    }
  
! 	    strfcpy(home_dir,cp,sizeof home_dir);
! 
! 	    strfcpy(inputname, user_text_file,sizeof inputname);
! 	    strfcpy(dataname, user_data_file,sizeof dataname);
  	}
  
  	if ((a = do_newalias(inputname, dataname, FALSE, TRUE)) < 0) {
Index: elm2.4.ME+.50/utils/newmail.c
*** elm2.4.25/utils/newmail.c	Mon May 30 19:32:01 1994
--- elm2.4.ME+.50/utils/newmail.c	Tue Nov 17 21:14:09 1998
***************
*** 1,117 ****
  
! static char rcsid[] = "@(#)$Id: newmail.c,v 5.20 1994/05/30 16:31:40 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.20 $   $State: Exp $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: newmail.c,v $
!  * Revision 5.20  1994/05/30  16:31:40  syd
!  * make getpwuid dependent on ANSI_C not posix flag
!  * From: Syd
!  *
!  * Revision 5.19  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.18  1993/06/06  18:00:10  syd
!  * Fix max folder check, off by one
!  *
!  * Revision 5.17  1993/04/21  01:18:27  syd
!  * newmail treated a line with From_ preceeded by whitespace as a valid
!  * message delimiter.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.16  1993/04/12  03:51:42  syd
!  * prevent double spacing in newmail
!  * From: Syd
!  *
!  * Revision 5.15  1993/04/12  03:40:28  syd
!  * Some OSs need the time.h includes
!  * From: ebd@fang.att.com (Elliot B Dierksen)
!  *
!  * Revision 5.14  1993/02/09  19:03:15  syd
!  * add isspace macro from ctype.h include
!  *
!  * Revision 5.13  1993/02/03  16:10:31  syd
!  * More utime portability problems with convex
!  * From: Jukka Ukkonen <ukkonen@csc.fi>
!  *
!  * Revision 5.12  1993/01/27  21:00:30  syd
!  * When newmail stats/reads the mailbox it updates the access times.  This
!  * causes problems for users that run both newmail and xbiff since xbiff
!  * just looks at the access times of the mailbox.  Added code to newmail
!  * that borrows some code from src/leavembox.c for updating mailbox access
!  * times.
!  * From: aj@redwood.cray.com (Chris Jackman)
!  *
!  * Revision 5.11  1993/01/27  20:49:40  syd
!  * It seams that SCO Unix nedds 1 pair of () extra to get
!  * the new newmail.c code to work.
!  * From: Jan S{ll <jan%unikla@Mail.SWIP.net>
!  *
!  * Revision 5.10  1993/01/27  20:44:27  syd
!  * Correct MMDF syntax problems and newmail botches.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.9  1993/01/19  05:07:05  syd
!  * Trim erroreous extra log entry
!  * From: Syd
!  *
!  * Significant changes to provide consistent Date and From_ header
!  * cracking.  Overhauled date utilities and moved into library.  Moved
!  * real_from() into library.  Modified frm, newmail, and readmsg utilities
!  * to use library version of real_from().  Moved get_word() from Elm
!  * source into library.  Added new library routines atonum() and strfcpy().
!  * Fixed trailing backslash bug in len_next().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.7  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.6  1992/11/17  19:23:28  syd
!  * add blank after priority to
!  *
!  * Revision 5.5  1992/11/07  20:05:52  syd
!  * change to use header_cmp to allow for linear white space around the colon
!  * From: Syd
!  *
!  * Revision 5.4  1992/10/27  01:43:40  syd
!  * Move posix_signal to lib directory
!  * From: tom@osf.org
!  *
!  * Revision 5.3  1992/10/25  02:54:00  syd
!  * add posix signal stuff as stop gap, needs to be moved to lib
!  * From: syd
!  *
!  * Revision 5.2  1992/10/24  13:11:42  syd
!  * fix newmail attempting to close a file descriptor even if the corresponding
!  * open failed.
!  * From: "Peter A. Bigot" <pab@cs.arizona.edu>
!  *
!  * Revision 5.1  1992/10/04  00:46:45  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This is actually two programs folded into one - 'newmail()' and
      'wnewmail()'.  They perform essentially the same function, to
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: newmail.c,v 1.3 1998/11/07 14:12:22 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This is actually two programs folded into one - 'newmail()' and
      'wnewmail()'.  They perform essentially the same function, to
***************
*** 168,180 ****
  #endif
  #include <sys/stat.h>
  
! #ifdef I_TIME
! #  include <time.h>
! #endif
! #ifdef I_SYSTIME
! #  include <sys/time.h>
! #endif
! #ifdef BSD
  #  include <sys/timeb.h>
  #endif
  
--- 67,73 ----
  #endif
  #include <sys/stat.h>
  
! #ifdef BSD_TYPE
  #  include <sys/timeb.h>
  #endif
  
***************
*** 193,199 ****
     Suprise, though, BSD has a different utime() entirely...*sigh*
  **********/
  
! #ifndef BSD
  # ifndef UTIMBUF
  
  struct utimbuf {
--- 86,92 ----
     Suprise, though, BSD has a different utime() entirely...*sigh*
  **********/
  
! #ifndef BSD_TYPE
  # ifndef UTIMBUF
  
  struct utimbuf {
***************
*** 202,208 ****
         };
  
  # endif /* UTIMBUF */
! #endif /* BSD */
  
  
  #define LINEFEED		(char) 10
--- 95,101 ----
         };
  
  # endif /* UTIMBUF */
! #endif /* BSD_TYPE */
  
  
  #define LINEFEED		(char) 10
***************
*** 229,244 ****
  	  char		prefix[NLEN];
  	  long		filesize;
  	  int		access_error;
!        } folders[MAX_FOLDERS] = {0};
  
  int  interval_time,		/* how long to sleep between checks */
-      debug = 0,			/* include verbose debug output?    */
       in_window = 0,		/* are we running as 'wnewmail'?    */
       total_folders = 0,		/* # of folders we're monitoring    */
       print_prefix = 0,		/* force printing of prefix	    */
       current_folder = 0;	/* struct pointer for looping       */
  FILE	*fd = NULL;		/* fd to use to read folders	    */
- FILE	*debugfile = stderr;
  
  #ifdef PIDCHECK
  int  parent_pid;		/* See if sucide should be attempt  */
--- 122,135 ----
  	  char		prefix[NLEN];
  	  long		filesize;
  	  int		access_error;
!        } folder_list[MAX_FOLDERS] = {0};
  
  int  interval_time,		/* how long to sleep between checks */
       in_window = 0,		/* are we running as 'wnewmail'?    */
       total_folders = 0,		/* # of folders we're monitoring    */
       print_prefix = 0,		/* force printing of prefix	    */
       current_folder = 0;	/* struct pointer for looping       */
  FILE	*fd = NULL;		/* fd to use to read folders	    */
  
  #ifdef PIDCHECK
  int  parent_pid;		/* See if sucide should be attempt  */
***************
*** 246,253 ****
  
  extern int errno;
  
! #if defined(BSD) && !defined(__convex__)
          time_t utime_buffer[2];         /* utime command */
  #else
          struct utimbuf utime_buffer;    /* utime command */
  #endif
--- 137,146 ----
  
  extern int errno;
  
! 
! #if defined(BSD_TYPE) && !defined(__convex__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
          time_t utime_buffer[2];         /* utime command */
+ 
  #else
          struct utimbuf utime_buffer;    /* utime command */
  #endif
***************
*** 261,266 ****
--- 154,161 ----
  		*to_text,	/* pointer to to text		*/
  		*from_text;	/* pointer to from text		*/
  
+ static void expand_filename P_((char *, char *, int)); /* Prototype */
+ 
  main(argc, argv)
  int argc;
  char *argv[];
***************
*** 278,288 ****
  	struct passwd *getpwuid();
  #endif
  
! #ifdef I_LOCALE
! 	setlocale(LC_ALL, "");
! #endif
  
! 	elm_msg_cat = catopen("elm2.4", 0);
  
  	/* Get the No subject string */
  
--- 173,183 ----
  	struct passwd *getpwuid();
  #endif
  
! 	locale_init();
  
! 	user_init();
! 	init_defaults();
! 	read_rc_file();
  
  	/* Get the No subject string */
  
***************
*** 299,348 ****
  	to_text = catgets(elm_msg_cat, NewmailSet, NewmailTo, "to ");
  	from_text = catgets(elm_msg_cat, NewmailSet, NewmailFrom, "from ");
  
- #ifdef HOSTCOMPILED
- 	strncpy(hostname, HOSTNAME, sizeof(hostname) - 1);
- 	hostname[sizeof(hostname) - 1] = '\0';
- #else
- 	gethostname(hostname, sizeof(hostname));
- #endif
- 	gethostdomain(hostdomain, sizeof(hostdomain));
- 
- 	/*
- 	 * see init.c for an explanation of this!
- 	 */
- 	hostlen = strlen(hostname);
- 	domlen = strlen(hostdomain);
- 	if (hostlen >= domlen) {
- 	  if (istrcmp(&hostname[hostlen - domlen], hostdomain) == 0)
- 	    strcpy(hostfullname, hostname);
- 	  else {
- 	    strcpy(hostfullname, hostname);
- 	    strcat(hostfullname, hostdomain);
- 	  }
- 	} else {
- 	  if (istrcmp(hostname, hostdomain + 1) == 0)
- 	    strcpy(hostfullname, hostname);
- 	  else {
- 	    strcpy(hostfullname, hostname);
- 	    strcat(hostfullname, hostdomain);
- 	  }
- 	}
- 
- 	/*
- 	 * get user name and full user name so we know who we are
- 	 */
- 	if((pass = getpwuid(getuid())) == NULL) {
- 	  fprintf(stderr, catgets(elm_msg_cat, NewmailSet, NewmailNoPasswdEntry,
- 	      "You have no password entry!"));
- 	  exit(1);
- 	}
- 	strcpy(username, pass->pw_name);
- 
- 	if((ptr = get_full_name(username)) != NULL)
- 	  strcpy(full_username, ptr);
- 	else
- 	  strcpy(full_username, username);
- 
  #ifdef PIDCHECK				/* This will get the pid that         */
  	parent_pid = getppid();		/* started the program, ie: /bin/sh   */
  					/* If it dies for some reason (logout)*/
--- 194,199 ----
***************
*** 428,434 ****
  
  	  for (i = 0; i < total_folders; i++) {
  
! 	    cur_folder = &folders[i];
  	    dprint(1, (debugfile, "[checking folder #%d: %s]\n",
  		i, cur_folder->foldername));
  
--- 279,285 ----
  
  	  for (i = 0; i < total_folders; i++) {
  
! 	    cur_folder = &folder_list[i];
  	    dprint(1, (debugfile, "[checking folder #%d: %s]\n",
  		i, cur_folder->foldername));
  
***************
*** 472,478 ****
  	      /* try to set the file access times back, ignore
  		 failures */
  
! #if defined(BSD) && !defined(__convex__)
  	      utime(cur_folder->foldername, utime_buffer);
  #else
                utime(cur_folder->foldername, &utime_buffer);
--- 323,329 ----
  	      /* try to set the file access times back, ignore
  		 failures */
  
! #if defined(BSD_TYPE) && !defined(__convex__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
  	      utime(cur_folder->foldername, utime_buffer);
  #else
                utime(cur_folder->foldername, &utime_buffer);
***************
*** 533,540 ****
  	   * Initialize header record for a new message.
  	   */
  	  if (init_header) {
! 	    hdr.to[0] = '\0';
! 	    hdr.from[0] = '\0';
  	    hdr.subject[0] = '\0';
  	    hdr.priority = FALSE;
  	    in_header = FALSE;
--- 384,392 ----
  	   * Initialize header record for a new message.
  	   */
  	  if (init_header) {
! 	    hdr.to   = NULL;
! 	    hdr.env_from[0] = '\0';
! 	    hdr.from = NULL;
  	    hdr.subject[0] = '\0';
  	    hdr.priority = FALSE;
  	    in_header = FALSE;
***************
*** 572,582 ****
  	    continue;
  #endif /* MMDF */
  
- 	  if (header_cmp(buffer, "From", (char *) NULL))  {
- 	    parse_arpa_who(buffer, hdr.from, 0);
- 	    continue;
- 	  }
- 
  	  /*
  	   * Split up the header into a field name and field value.
  	   */
--- 424,429 ----
***************
*** 591,602 ****
  	  }
  
  	  if (istrcmp(fld_name, ">From") == 0) {
! 	    forwarded(fld_val, hdr.from);
  	    continue;
  	  }
  
  	  if (istrcmp(fld_name, "To:") == 0) {
! 	    figure_out_addressee(fld_val, hdr.to);
  	    continue;
  	  }
  
--- 438,458 ----
  	  }
  
  	  if (istrcmp(fld_name, ">From") == 0) {
! 	    forwarded(fld_val, &hdr);
! 	    continue;
! 	  }
! 
! 	  if (header_cmp(fld_name, "From", (char *) NULL))  {
! 	    /* does not handle continuation lines ! */
! 	    hdr.from = break_down_address(fld_val,
! 					  decode_who_none);
  	    continue;
  	  }
  
  	  if (istrcmp(fld_name, "To:") == 0) {
! 	    hdr.to = break_down_address(fld_val,
! 					  decode_who_none);
! 
  	    continue;
  	  }
  
***************
*** 663,669 ****
  
  	  if (metachar(*cp)) cp++;
  
! 	  strcpy(folders[current_folder].prefix, cp);
  	  print_prefix = 1;
  	}
  	else {			/* nope, let's get the basename of the file */
--- 519,526 ----
  
  	  if (metachar(*cp)) cp++;
  
! 	  strfcpy(folder_list[current_folder].prefix, cp,
! 		  sizeof folder_list[current_folder].prefix);
  	  print_prefix = 1;
  	}
  	else {			/* nope, let's get the basename of the file */
***************
*** 673,679 ****
  	  if (metachar(*cp)) cp++;
  	  if (*cp == '/') cp++;
  
! 	  strcpy(folders[current_folder].prefix, cp);
  	}
  
  	/* and next let's see what kind of weird prefix chars this user
--- 530,537 ----
  	  if (metachar(*cp)) cp++;
  	  if (*cp == '/') cp++;
  
! 	  strfcpy(folder_list[current_folder].prefix, cp,
! 		  sizeof folder_list[current_folder].prefix);
  	}
  
  	/* and next let's see what kind of weird prefix chars this user
***************
*** 682,721 ****
  	*/
  
  	if (metachar(name[0]))
! 	  expand_filename(name, folders[current_folder].foldername);
  	else if (access(name, 00) == -1) {
  	  /* let's try it in the mail home directory */
! 	  sprintf(buf, "%s%s", mailhome, name);
  	  if (access(buf, 00) != -1) 		/* aha! */
! 	    strcpy(folders[current_folder].foldername, buf);
  	  else
! 	    strcpy(folders[current_folder].foldername, name);
  	}
  	else
! 	  strcpy(folders[current_folder].foldername, name);
  
  	/* now let's try to actually open the file descriptor and grab
  	   a size... */
  
! 	if ((fd = fopen(folders[current_folder].foldername, "r")) == NULL)
            if (errno == EACCES) {
  	    fprintf(stderr, catgets(elm_msg_cat, NewmailSet, NewmailErrNoPerm,
  		      "\nPermission to monitor \"%s\" denied!\n\n"),
! 			 folders[current_folder].foldername);
  	    exit(1);
  	  }
  
! 	folders[current_folder].filesize = 
! 	      bytes(folders[current_folder].foldername);
  
  	/* and finally let's output what we did */
  
  	  dprint(1, (debugfile, "folder %d: \"%s\" <%s> %s, size = %ld\n",
  	      current_folder,
! 	      folders[current_folder].foldername,
! 	      folders[current_folder].prefix,
  	      fd == NULL? "not found" : "opened",
! 	      folders[current_folder].filesize));
  
  	if (fd != NULL) /* Close it only if we succeeded in opening it */
  		(void) fclose(fd);
--- 540,585 ----
  	*/
  
  	if (metachar(name[0]))
! 	  expand_filename(name, folder_list[current_folder].foldername,
! 			  sizeof folder_list[current_folder].foldername);
  	else if (access(name, 00) == -1) {
  	  /* let's try it in the mail home directory */
! 	  elm_sfprintf(buf, sizeof buf,
! 		       FRM("%s%s"), 
! 		       mailhome, name);
  	  if (access(buf, 00) != -1) 		/* aha! */
! 	    strfcpy(folder_list[current_folder].foldername, buf,
! 		    sizeof folder_list[current_folder].foldername);
  	  else
! 	    strfcpy(folder_list[current_folder].foldername, name,
! 		    sizeof folder_list[current_folder].foldername);
  	}
  	else
! 	  strfcpy(folder_list[current_folder].foldername, name,
! 		  sizeof folder_list[current_folder].foldername);
  
  	/* now let's try to actually open the file descriptor and grab
  	   a size... */
  
! 	if ((fd = fopen(folder_list[current_folder].foldername, "r")) == NULL)
            if (errno == EACCES) {
  	    fprintf(stderr, catgets(elm_msg_cat, NewmailSet, NewmailErrNoPerm,
  		      "\nPermission to monitor \"%s\" denied!\n\n"),
! 			 folder_list[current_folder].foldername);
  	    exit(1);
  	  }
  
! 	folder_list[current_folder].filesize = 
! 	      bytes(folder_list[current_folder].foldername);
  
  	/* and finally let's output what we did */
  
  	  dprint(1, (debugfile, "folder %d: \"%s\" <%s> %s, size = %ld\n",
  	      current_folder,
! 	      folder_list[current_folder].foldername,
! 	      folder_list[current_folder].prefix,
  	      fd == NULL? "not found" : "opened",
! 	      folder_list[current_folder].filesize));
  
  	if (fd != NULL) /* Close it only if we succeeded in opening it */
  		(void) fclose(fd);
***************
*** 730,754 ****
  {
  	char	*cp;
  
! 	/* this routine will add the users home mailbox as the folder
! 	 * to monitor.  Since there'll only be one folder we'll never
! 	 * prefix it either...
! 	 *	determine mail file from environment variable if found,
! 	 *	else use password entry
! 	 */
! 	if ((cp = getenv("MAIL")) == NULL)
! 	  sprintf(folders[0].foldername, "%s%s", mailhome, getusername());
! 	else
! 	  strcpy(folders[0].foldername, cp);
  	
! 	fd = fopen(folders[0].foldername, "r");
! 	folders[0].filesize = bytes(folders[0].foldername);
  
  	dprint(1, (debugfile, "default folder: \"%s\" <%s> %s, size = %ld\n",
! 	      folders[0].foldername,
! 	      folders[0].prefix,
  	      fd == NULL? "not found" : "opened",
! 	      folders[0].filesize));
  
  	total_folders = 1;
  	if (fd != NULL) /* Close it only if we succeeded in opening it */
--- 594,610 ----
  {
  	char	*cp;
  
! 	strfcpy(folder_list[0].foldername, defaultfile,
! 		sizeof folder_list[0].foldername);
  	
! 	fd = fopen(folder_list[0].foldername, "r");
! 	folder_list[0].filesize = bytes(folder_list[0].foldername);
  
  	dprint(1, (debugfile, "default folder: \"%s\" <%s> %s, size = %ld\n",
! 	      folder_list[0].foldername,
! 	      folder_list[0].prefix,
  	      fd == NULL? "not found" : "opened",
! 	      folder_list[0].filesize));
  
  	total_folders = 1;
  	if (fd != NULL) /* Close it only if we succeeded in opening it */
***************
*** 755,790 ****
  	  fclose(fd);
  }
  
- 
- forwarded(buffer, who)
- char *buffer, *who;
- {
- 	/** change 'from' and date fields to reflect the ORIGINATOR of 
- 	    the message by iteratively parsing the >From fields...
- 	    The leading >From will already be stripped off the line. **/
- 
- 	char machine[SLEN], buff[SLEN];
- 
- 	machine[0] = '\0';
- 	sscanf(buffer, "%s %*s %*s %*s %*s %*s %*s %*s %*s %s",
- 	            who, machine);
- 
- 	if(machine[0] == '\0')	/* try for address with timezone in date */
- 	sscanf(buffer, "%s %*s %*s %*s %*s %*s %*s %*s %s",
- 	            who, machine);
- 
- 	if (machine[0] == '\0') /* try for srm address */
- 	  sscanf(buffer, "%s %*s %*s %*s %*s %*s %*s %s",
- 	            who, machine);
- 
- 	if (machine[0] == '\0')
- 	  sprintf(buff,"anonymous");
- 	else
- 	  sprintf(buff,"%s!%s", machine, who);
- 
- 	strncpy(who, buff, SLEN);
- }
- 
  show_header(hdr, cur_folder)
  struct header_rec *hdr;
  struct folder_struct *cur_folder;
--- 611,616 ----
***************
*** 793,802 ****
  	char prefix[SLEN];
  	int used_to_line;
  
- 	if (hdr->from[0] == '\0')
- 	  strcpy(hdr->from, getusername());
  	if (hdr->subject[0] == '\0')
! 	  strcpy(hdr->subject, no_subj);
  	else {
  	  used_to_line = strlen(hdr->subject) - 1;
  	  if (hdr->subject[used_to_line] == '\n')
--- 619,626 ----
  	char prefix[SLEN];
  	int used_to_line;
  
  	if (hdr->subject[0] == '\0')
! 	  strfcpy(hdr->subject, no_subj, sizeof hdr->subject);
  	else {
  	  used_to_line = strlen(hdr->subject) - 1;
  	  if (hdr->subject[used_to_line] == '\n')
***************
*** 803,836 ****
  	    hdr->subject[used_to_line] = '\0'; /* strip off trailing new line, we add our own */
  	}
  
! 	used_to_line = tail_of(hdr->from, from_line, hdr->to);
  	prefix[0] = '\0';
  
  	if (! in_window)
! 	  strcat(prefix, ">> ");
  
  	if (print_prefix) {
! 	  strcat(prefix, cur_folder->prefix);
! 	  strcat(prefix, ": ");
  	}
  
  	if (in_window) {
  	  if (hdr->priority && used_to_line)
! 	    strcat(prefix, priority_to);
  	  else if (hdr->priority)
! 	    strcat(prefix, priority_text);
  	  else if (used_to_line)
! 	    strcat(prefix, To_text);
  	  printf("\007%s%s -- %s\n", prefix, from_line, hdr->subject);
  	} else {
  	  if (hdr->priority)
! 	    strcat(prefix, priority_mail);
  	  else
! 	    strcat(prefix, mail_text);
  	  if (used_to_line)
! 	    strcat(prefix, to_text);
  	  else
! 	    strcat(prefix, from_text);
  	  printf("\n\r%s%s - %s\n\r", prefix, from_line, hdr->subject);
  	}
  }
--- 627,661 ----
  	    hdr->subject[used_to_line] = '\0'; /* strip off trailing new line, we add our own */
  	}
  
! 	used_to_line = DisplayAddress(hdr,from_line,sizeof from_line,
! 				      decode_who_none);
  	prefix[0] = '\0';
  
  	if (! in_window)
! 	  strfcat(prefix, ">> ", sizeof prefix);
  
  	if (print_prefix) {
! 	  strfcat(prefix, cur_folder->prefix, sizeof prefix);
! 	  strfcat(prefix, ": ", sizeof prefix);
  	}
  
  	if (in_window) {
  	  if (hdr->priority && used_to_line)
! 	    strfcat(prefix, priority_to, sizeof prefix);
  	  else if (hdr->priority)
! 	    strfcat(prefix, priority_text, sizeof prefix);
  	  else if (used_to_line)
! 	    strfcat(prefix, To_text, sizeof prefix);
  	  printf("\007%s%s -- %s\n", prefix, from_line, hdr->subject);
  	} else {
  	  if (hdr->priority)
! 	    strfcat(prefix, priority_mail, sizeof prefix);
  	  else
! 	    strfcat(prefix, mail_text, sizeof prefix);
  	  if (used_to_line)
! 	    strfcat(prefix, to_text, sizeof prefix);
  	  else
! 	    strfcat(prefix, from_text, sizeof prefix);
  	  printf("\n\r%s%s - %s\n\r", prefix, from_line, hdr->subject);
  	}
  }
***************
*** 857,863 ****
  	
  	/* retain the access times for later use */
  
! #if defined(BSD) && !defined(__convex__)
          utime_buffer[0]     = buffer.st_atime;
          utime_buffer[1]     = buffer.st_mtime;
  #else
--- 682,688 ----
  	
  	/* retain the access times for later use */
  
! #if defined(BSD_TYPE) && !defined(__convex__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
          utime_buffer[0]     = buffer.st_atime;
          utime_buffer[1]     = buffer.st_mtime;
  #else
***************
*** 907,918 ****
  
  }
  
! 
! expand_filename(name, store_space)
! char *name, *store_space;
  {
! 	strcpy(store_space, name);
! 	if (expand(store_space) == 0) {
  	  fprintf(stderr, catgets(elm_msg_cat, NewmailSet, NewmailErrExpand,
  	    "Sorry, but I couldn't expand \"%s\"\n"),name);
  	  exit(1);
--- 732,743 ----
  
  }
  
! void expand_filename(name, store_space,size)
!      char *name, *store_space;
!      int size;
  {
! 	strfcpy(store_space, name, size);
! 	if (expand(store_space, size) == 0) {
  	  fprintf(stderr, catgets(elm_msg_cat, NewmailSet, NewmailErrExpand,
  	    "Sorry, but I couldn't expand \"%s\"\n"),name);
  	  exit(1);
***************
*** 930,939 ****
  	register int i, j, len = 0;
  
  	for (i=0; i < total_folders; i++)
! 	  if (len < (j=strlen(folders[i].prefix)))
  	    len = j;
  	
  	for (i=0; i < total_folders; i++)
! 	  for (j = strlen(folders[i].prefix); j < len; j++)
! 	    strcat(folders[i].prefix, " ");
  }
--- 755,764 ----
  	register int i, j, len = 0;
  
  	for (i=0; i < total_folders; i++)
! 	  if (len < (j=strlen(folder_list[i].prefix)))
  	    len = j;
  	
  	for (i=0; i < total_folders; i++)
! 	  for (j = strlen(folder_list[i].prefix); j < len; j++)
! 	    strfcat(folder_list[i].prefix, " ", sizeof folder_list[i].prefix);
  }
Index: elm2.4.ME+.50/utils/printmail.SH
*** elm2.4.25/utils/printmail.SH	Sun Oct  4 03:47:01 1992
--- elm2.4.ME+.50/utils/printmail.SH	Tue Nov 17 21:12:58 1998
***************
*** 17,23 ****
  echo $startsh > printmail
  cat >>printmail <<'!NO!SUBS!'
  # printmail: part of the Elm mail system
! # @(#)$Id: printmail.SH,v 5.1 1992/10/04 00:46:45 syd Exp $
  #		Copyright (c) 1988-1992 USENET Community Trust
  # 		Copyright (c) 1986,1987 Dave Taylor
   
--- 17,23 ----
  echo $startsh > printmail
  cat >>printmail <<'!NO!SUBS!'
  # printmail: part of the Elm mail system
! # @(#)$Id: printmail.SH,v 1.1.1.1 1998/10/15 15:36:44 hurtta Exp $
  #		Copyright (c) 1988-1992 USENET Community Trust
  # 		Copyright (c) 1986,1987 Dave Taylor
   
Index: elm2.4.ME+.50/utils/prlong.c
*** elm2.4.25/utils/prlong.c	Tue May 31 02:59:38 1994
--- elm2.4.ME+.50/utils/prlong.c	Tue Nov 17 21:14:09 1998
***************
*** 1,44 ****
  
! static char rcsid[] = "@(#)$Id: prlong.c,v 5.4 1994/05/30 23:59:24 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.4 $
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: prlong.c,v $
!  * Revision 5.4  1994/05/30  23:59:24  syd
!  * fix those that need getopt, getopt calls elm_msg_cat
!  * From: Syd
!  *
!  * Revision 5.3  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.2  1993/04/21  01:41:14  syd
!  * Needs ctype.h
!  * From: Syd
!  *
!  * Revision 5.1  1993/04/12  02:09:44  syd
!  * Initial checkin
!  *
!  *
!  ******************************************************************************/
  
  
  /*
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: prlong.c,v 1.3 1998/11/07 14:12:22 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  
  /*
***************
*** 118,130 ****
      extern int optind;
      extern char *optarg;
  
! #ifdef I_LOCALE
!     setlocale(LC_ALL, "");
! #endif
! 
! #ifndef GETOPT
!     elm_msg_cat = catopen("elm2.4", 0);
! #endif
  
      /*
       * Initialize defaults.
--- 90,99 ----
      extern int optind;
      extern char *optarg;
  
!     locale_init();
!     user_init();
!     init_defaults();
!     read_rc_file();
  
      /*
       * Initialize defaults.
Index: elm2.4.ME+.50/utils/readmsg.c
*** elm2.4.25/utils/readmsg.c	Tue Aug  3 22:29:29 1993
--- elm2.4.ME+.50/utils/readmsg.c	Tue Nov 17 21:14:09 1998
***************
*** 1,76 ****
  
! static char rcsid[] = "@(#)$Id: readmsg.c,v 5.10 1993/08/03 19:28:39 syd Exp $";
  
! /*******************************************************************************
!  *  The Elm Mail System  -  $Revision: 5.10 $   $State: Exp $
   *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *******************************************************************************
!  * Bug reports, patches, comments, suggestions should be sent to:
!  *
!  *	Syd Weinstein, Elm Coordinator
!  *	elm@DSI.COM			dsinc!elm
!  *
!  *******************************************************************************
!  * $Log: readmsg.c,v $
!  * Revision 5.10  1993/08/03  19:28:39  syd
!  * Elm tries to replace the system toupper() and tolower() on current
!  * BSD systems, which is unnecessary.  Even worse, the replacements
!  * collide during linking with routines in isctype.o.  This patch adds
!  * a Configure test to determine whether replacements are really needed
!  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
!  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
!  * there.  Inclusion of <ctype.h> was removed from *all* the individual
!  * files, and the toupper() and tolower() routines in lib/opt_utils.c
!  * were dropped.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.9  1993/04/21  01:17:51  syd
!  * readmsg treated a line with From_ preceeded by whitespace as a valid
!  * message delimiter.
!  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
!  *
!  * Revision 5.8  1993/04/12  01:54:07  syd
!  * Modified to use new safe_malloc() routines.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.7  1993/02/03  16:46:28  syd
!  * xrealloc name conflicts with some os having a routine called xrealloc,
!  * renamed it elm_xrealloc.
!  * From: Syd
!  *
!  * Revision 5.6  1993/02/03  15:26:13  syd
!  * protect atol in ifndef __STDC__ as some make it a macro, and its in stdlib.h
!  *
!  * Revision 5.5  1993/01/19  05:07:05  syd
!  * Trim erroreous extra log entry
!  * From: Syd
!  *
!  * Revision 5.4  1993/01/19  04:47:12  syd
!  * Significant changes to provide consistent Date and From_ header
!  * cracking.  Overhauled date utilities and moved into library.  Moved
!  * real_from() into library.  Modified frm, newmail, and readmsg utilities
!  * to use library version of real_from().  Moved get_word() from Elm
!  * source into library.  Added new library routines atonum() and strfcpy().
!  * Fixed trailing backslash bug in len_next().
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.3  1992/12/11  01:45:04  syd
!  * remove sys/types.h include, it is now included by defs.h
!  * and this routine includes defs.h or indirectly includes defs.h
!  * From: Syd
!  *
!  * Revision 5.2  1992/11/07  19:37:21  syd
!  * Enhanced printing support.  Added "-I" to readmsg to
!  * suppress spurious diagnostic messages.
!  * From: chip@chinacat.unicom.com (Chip Rosenthal)
!  *
!  * Revision 5.1  1992/10/04  00:46:45  syd
!  * Initial checkin as of 2.4 Release at PL0
!  *
!  *
!  ******************************************************************************/
  
  /** This program extracts messages from a mail folder.  It is particularly
      useful when the user is composting a mail response in an external
--- 1,16 ----
  
! static char rcsid[] = "@(#)$Id: readmsg.c,v 1.3 1998/11/07 14:12:22 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
   *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
   *			Copyright (c) 1988-1992 USENET Community Trust
   *			Copyright (c) 1986,1987 Dave Taylor
!  *****************************************************************************/
  
  /** This program extracts messages from a mail folder.  It is particularly
      useful when the user is composting a mail response in an external
***************
*** 168,177 ****
  extern char *optarg;			/* for parsing the ...		*/
  extern int   optind;			/*  .. starting arguments	*/
  
- #ifdef DEBUG
- int debug = 0;
- FILE *debugfile = stderr;
- #endif
  
  
  void usage_error()
--- 108,113 ----
***************
*** 217,227 ****
  					 * get to the imitation program.
  					 *  -chip  */
  
! #ifdef I_LOCALE
!     setlocale(LC_ALL, "");
! #endif
  
-     elm_msg_cat = catopen("elm2.4", 0);
      prog = argv[0];
      folder_name[0] = '\0';	/* no folder specified yet		*/
      folder_size = -1;		/* message index not loaded yet		*/
--- 153,160 ----
  					 * get to the imitation program.
  					 *  -chip  */
  
!     locale_init();
  
      prog = argv[0];
      folder_name[0] = '\0';	/* no folder specified yet		*/
      folder_size = -1;		/* message index not loaded yet		*/
***************
*** 231,236 ****
--- 164,173 ----
      ign_no_request = FALSE;	/* no action requested is an error	*/
      exit_status = 0;		/* will set nonzero on error		*/
  
+     user_init();
+     init_defaults();
+     read_rc_file();
+ 
      /* install trap for safe_malloc() failure */
      safe_malloc_fail_handler = malloc_fail_handler;
  
***************
*** 256,263 ****
  	    hdr_disp_level = ALL;
  	    break;
  	case 'f' :
! 	    strcpy(folder_name, optarg);
! 	    if (metachar(folder_name[0]) && !expand(folder_name)) {
  		fprintf(stderr, catgets(elm_msg_cat, ReadmsgSet,
  		    ReadmsgCannotExpandFolderName,
  		    "%s: Cannot expand folder name \"%s\".\n"),
--- 193,201 ----
  	    hdr_disp_level = ALL;
  	    break;
  	case 'f' :
! 	    strfcpy(folder_name, optarg, sizeof folder_name);
! 	    if (metachar(folder_name[0]) && 
! 		!expand(folder_name, sizeof folder_name)) {
  		fprintf(stderr, catgets(elm_msg_cat, ReadmsgSet,
  		    ReadmsgCannotExpandFolderName,
  		    "%s: Cannot expand folder name \"%s\".\n"),
***************
*** 280,297 ****
      /* figure out where the folder is */
      if (folder_name[0] == '\0') {
  	if (fstate_valid)
! 	    strcpy(folder_name, fstate.folder_name);
  	else if ((cp = getenv("MAIL")) != NULL)
! 	    strcpy(folder_name, cp);
  	else if ((cp = getenv("LOGNAME")) != NULL)
! 	    sprintf(folder_name, "%s/%s", mailhome, cp);
  	else if ((cp = getenv("USER")) != NULL)
! 	    sprintf(folder_name, "%s/%s", mailhome, cp);
  	else {
! 	    fprintf(stderr, catgets(elm_msg_cat, ReadmsgSet,
! 		ReadmsgCannotGetIncomingName,
! 		"%s: Cannot figure out name of your incoming mail folder.\n"),
! 		prog);
  	    exit(1);
  	}
      }
--- 218,237 ----
      /* figure out where the folder is */
      if (folder_name[0] == '\0') {
  	if (fstate_valid)
! 	    strfcpy(folder_name, fstate.folder_name, sizeof folder_name);
  	else if ((cp = getenv("MAIL")) != NULL)
! 	    strfcpy(folder_name, cp, sizeof folder_name);
  	else if ((cp = getenv("LOGNAME")) != NULL)
! 	    elm_sfprintf(folder_name, sizeof folder_name,
! 			 FRM("%s/%s"), mailhome, cp);
  	else if ((cp = getenv("USER")) != NULL)
! 	    elm_sfprintf(folder_name, sizeof folder_name,
! 			 FRM("%s/%s"), mailhome, cp);
  	else {
! 	    lib_error(CATGETS(elm_msg_cat, ReadmsgSet,
! 			      ReadmsgCannotGetIncomingName,
! 			      "%s: Cannot figure out name of your incoming mail folder.\n"),
! 		      prog);
  	    exit(1);
  	}
      }
***************
*** 336,344 ****
  
      /* see if we are trying to match a pattern */
      if (index("0123456789$*", argv[optind][0]) == NULL) {
! 	strcpy(buf, argv[optind]);
  	while (++optind < argc)
! 		strcat(strcat(buf, " "), argv[optind]);
  	if (print_patmatch_mssg(fp, buf, do_all_matches,
  			hdr_disp_level, do_page_breaks) != 0)
  	    exit_status = 1;
--- 276,285 ----
  
      /* see if we are trying to match a pattern */
      if (index("0123456789$*", argv[optind][0]) == NULL) {
! 	strfcpy(buf, argv[optind], sizeof buf);
  	while (++optind < argc)
! 		strfcat(strfcat(buf, " ", sizeof buf), argv[optind], 
! 			sizeof buf);
  	if (print_patmatch_mssg(fp, buf, do_all_matches,
  			hdr_disp_level, do_page_breaks) != 0)
  	    exit_status = 1;
***************
*** 634,642 ****
      }
  
      if (Hdrmatch(buf, "From ")) {
! 	strcpy(save_from, buf);
  	is_interesting = FALSE;
!     } else if (Hdrmatch(buf, "To:") || Hdrmatch(buf, "Subject:"))
  	is_interesting = TRUE;
      else if (Hdrmatch(buf, "Date:"))
  	got_date = is_interesting = TRUE;
--- 575,584 ----
      }
  
      if (Hdrmatch(buf, "From ")) {
! 	strfcpy(save_from, buf, sizeof save_from);
  	is_interesting = FALSE;
!     } else if (Hdrmatch(buf, "To:") || Hdrmatch(buf, "Subject:")
! 	       || Hdrmatch(buf, "Cc:"))
  	is_interesting = TRUE;
      else if (Hdrmatch(buf, "Date:"))
  	got_date = is_interesting = TRUE;
Index: elm2.4.ME+.50/src/builtin.c
*** elm2.4.25/src/builtin.c	Mon May 30 19:42:49 1994
--- /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
***************
*** 1,352 ****
- 
- static char rcsid[] = "@(#)$Id: builtin.c,v 5.4 1994/05/30 16:42:48 syd Exp $";
- 
- /*******************************************************************************
-  *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
-  *
-  * 			Copyright (c) 1988-1992 USENET Community Trust
-  * 			Copyright (c) 1986,1987 Dave Taylor
-  *******************************************************************************
-  * Bug reports, patches, comments, suggestions should be sent to:
-  *
-  *	Syd Weinstein, Elm Coordinator
-  *	elm@DSI.COM			dsinc!elm
-  *
-  *******************************************************************************
-  * $Log: builtin.c,v $
-  * Revision 5.4  1994/05/30  16:42:48  syd
-  * Just a minor fix to an impossible character comparison.
-  * From: Jukka Ukkonen <ukkonen@csc.fi>
-  *
-  * Revision 5.3  1994/05/15  22:55:25  syd
-  * I had to put in some changes to builtin+ to allow it to display
-  * 8-bit letters as they should when the message has been sent
-  * through a real 8-bit channel like ESMTP with 8bit MIME Content-
-  * Transfer-Encoding.
-  * From: Jukka Ukkonen <ukkonen@csc.fi>
-  *
-  * Revision 5.2  1993/08/03  19:28:39  syd
-  * Elm tries to replace the system toupper() and tolower() on current
-  * BSD systems, which is unnecessary.  Even worse, the replacements
-  * collide during linking with routines in isctype.o.  This patch adds
-  * a Configure test to determine whether replacements are really needed
-  * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
-  * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
-  * there.  Inclusion of <ctype.h> was removed from *all* the individual
-  * files, and the toupper() and tolower() routines in lib/opt_utils.c
-  * were dropped.
-  * From: chip@chinacat.unicom.com (Chip Rosenthal)
-  *
-  * Revision 5.1  1992/10/03  22:58:40  syd
-  * Initial checkin as of 2.4 Release at PL0
-  *
-  *
-  ******************************************************************************/
- 
- /** This is the built-in pager for displaying messages while in the Elm
-     program.  It's a bare-bones pager with precious few options. The idea
-     is that those systems that are sufficiently slow that using an external
-     pager such as 'more' is too slow, then they can use this!
- 
-     Also added support for the "builtin+" pager (clears the screen for
-     each new page) including a two-line overlap for context...
- 
- **/
- 
- #include "headers.h"
- #include "s_elm.h"
- 
- #define  BEEP		007		/* ASCII Bell character */
- 
- static	unfilled_lines,
- 	form_title;
- 
- int	lines_displayed,	    /* total number of lines displayed      */
- 	total_lines_to_display,	    /* total number of lines in message     */
- 	pages_displayed; 	    /* for the nth page titles and all      */
- 
- start_builtin(lines_in_message)
- int lines_in_message;
- {
- 	/** clears the screen and resets the internal counters... **/
- 
- 	dprint(8,(debugfile, 
- 		"displaying %d lines from message using internal pager\n",
- 		lines_in_message));
- 
- 	unfilled_lines = LINES;
- 	form_title = 1;
- 	lines_displayed = 0;
-         pages_displayed = 1;
- 
- 	total_lines_to_display = lines_in_message;
- }
- 
- extern int tabspacing;
- 
- int
- next_line(inputptr, inputlenptr, output, outputlenptr, width)
- char **inputptr, *output;
- register unsigned width;
- int *inputlenptr, *outputlenptr;
- {
- 	/* Copy characters from input to output and copy
- 	 * remainder of output to output. In copying use ^X notation for
- 	 * control characters, '?' non-ascii characters, expand tabs
- 	 * to correct number of spaces till next tab stop.
- 	 * Column zero of the next line is considered to be the tab stop
- 	 * that follows the last one that fits on a line.
- 	 * Copy until newline/return encountered, null char encountered,
- 	 * width characters producted in output buffer.
- 	 * Formfeed is handled exceptionally. If encountered it
- 	 * is removed from input and 1 is returned. Otherwise 0 is returned.
- 	 */
- 
- 	register char *optr, *iptr;
- 	register unsigned chars_output, nt;
- 	int ret_val;
- 	int ilen = *inputlenptr;
- 
- 	optr = output;
- 	iptr = *inputptr;
- 	chars_output = 0;
- 
- 	ret_val = 0;	/* presume no formfeed */
- 	while(ilen > 0) {	/* while there is something */
- 
- 	  if(chars_output >= width) {	/* no more room on line */
- 	    *optr++ = '\r';	
- 	    *optr++ = '\n';
- 	    /* if next input character is newline or return,
- 	     * we can skip over it since we are outputing a newline anyway */ 
- 	    if((*iptr == '\n') || (*iptr == '\r'))
- 	      { iptr++; --ilen; }
- 	    break;		
- 	  } else if (*iptr == '\n' || *iptr == '\r') {	/*newline or return */
- 	    *optr++ = '\r';
- 	    *optr++ = '\n';
- 	    iptr++; --ilen;
- 	    break;			/* end of line */
- 	  } else if(*iptr == '\f') {		/* formfeed */
- 	    /* if next input character is newline or return,
- 	     * we can skip over it since we are outputing a formfeed anyway */ 
- 	    if((*++iptr == '\n') || (*iptr == '\r'))
- 	      { iptr++; --ilen; }
- 	    --ilen;
- 	    ret_val = 1;
- 	    break;			/* leave rest of screen clear */
- 	  } else if(*iptr == '\t') {	/* tab stop */
- 	    if((nt=next_tab(chars_output+1)) > width) {
- 	      *optr++ = '\n';		/* won't fit on this line - autowrap */
- 	      *optr++ = '\r';		/* tab by tabbing so-to-speak to 1st */
- 	      iptr++;			/* column of next line */
- 	      --ilen;
- 	      break;
- 	    } else {		/* will fit - output proper num of spaces */
- 	      while(chars_output < nt-1) {
- 		chars_output++;
- 		*optr++ = ' ';
- 	      }
- 	      iptr++;
- 	      --ilen;
- 	    }
- 	  } else if(iscntrl(*iptr & 0xff)) {	/* Non-white ctrl char */
- 	    if (chars_output + 2 <= width) {
- 		*optr++ = '^';
- 		*optr++ = ctrl(*iptr);
- 		iptr++; --ilen;
- 		chars_output += 2;
- 	    } else {
- 		break;
- 	    }
- 	  } else {		/* Assume a printing char in case isprint */
- 	    *optr++ = *iptr++;	/* macro fails on true 8-bit characters.  */
- 	    chars_output++;
- 	    --ilen;
- 	  }
- 	}
- 	*optr = '\0';
- 	*inputptr = iptr;
- 	*inputlenptr = ilen;
- 	*outputlenptr = chars_output;
- 	return(ret_val);
- }
- 
- 
- int
- display_line(input_line, input_size)
- char *input_line;
- int  input_size;
- {
- 	int	percent_done;
- 	/** Display the given line on the screen, taking into account such
- 	    dumbness as wraparound and such.  If displaying this would put
- 	    us at the end of the screen, put out the "MORE" prompt and wait
- 	    for some input.   Return non-zero if the user terminates the
- 	    paging (e.g. 'i') or zero if we should continue. Also, 
-             this will pass back the value of any character the user types in 
- 	    at the prompt instead, if needed... (e.g. if it can't deal with
- 	    it at this point)
- 	**/
- 	
- 	char *pending, footer[SLEN], display_buffer[SLEN];
- 	int ch, formfeed, lines_more;
- 	int pending_len = input_size, display_len = 0;
- 
- #ifdef MMDF
- 	if (strcmp(input_line, MSG_SEPARATOR) == 0)
- 	  strcpy(input_line," ");
- #endif /* MMDF */
- 	pending = input_line;
- 	CarriageReturn();
- 
- 	do {
- 
- 	  /* while there is more space on the screen - leave prompt line free */
- 	  while(unfilled_lines > 0) {
- 
- 	    /* display a screen's lineful of the input line
- 	     * and reset pending to point to remainder of input line */
- 	    formfeed = next_line(&pending, &pending_len, display_buffer, &display_len, COLUMNS);
- 
- 	    if(*display_buffer == '\0') {	/* no line to display */
- 	      if(!formfeed)	/* no "formfeed" to display
- 	     			 * need more lines for screen */
- 		return(FALSE);
- 	    } else
- 	      Write_to_screen(display_buffer, 0);
- 
- 	    /* if formfeed, clear remainder of screen */
- 	    if(formfeed) {
- 	      CleartoEOS();
- 	      unfilled_lines=0;
- 	    }
- 	    else
- 	      unfilled_lines--;
- 
- 	    /* if screen is not full (leave room for prompt)
- 	     * but we've used up input line, return */
- 
- 	    if(unfilled_lines > 0 && pending_len == 0)
- 	      return(FALSE);	/* we need more lines to fill screen */
- 
- 	    /* otherwise continue to display next part of input line */
- 	  }
- 
- 	  /* screen is now full - prompt for user input */
- 	  lines_more = total_lines_to_display - lines_displayed;
- 	  percent_done = (int)((100L * lines_displayed) / total_lines_to_display);
- 	  if (user_level == 0) {
- 	    if (lines_more == 1)
- 	      MCsprintf(footer, catgets(elm_msg_cat, ElmSet, ElmMoreUser0,
- " There is 1 line left (%d%%). Press <space> for more, or 'i' to return. "),
- 		 percent_done);
- 	    else
- 	      MCsprintf(footer, catgets(elm_msg_cat, ElmSet, ElmMoreUser0Plural,
- " There are %d lines left (%d%%). Press <space> for more, or 'i' to return. "),
- 		 lines_more, percent_done);
- 	  } else if (user_level == 1) {
- 	    if (lines_more == 1)
- 	      MCsprintf(footer, catgets(elm_msg_cat, ElmSet, ElmMoreUser1,
- " 1 line more (%d%%). Press <space> for more, 'i' to return. "),
- 		 percent_done);
- 	    else
- 	      MCsprintf(footer, catgets(elm_msg_cat, ElmSet, ElmMoreUser1Plural,
- " %d lines more (%d%%). Press <space> for more, 'i' to return. "),
- 		 lines_more, percent_done);
- 	  } else {
- 	    if (lines_more == 1)
- 	      MCsprintf(footer, catgets(elm_msg_cat, ElmSet, ElmMoreUser2,
- " 1 line more (you've seen %d%%) "),
- 		 percent_done);
- 	    else
- 	      MCsprintf(footer, catgets(elm_msg_cat, ElmSet, ElmMoreUser2Plural,
- " %d lines more (you've seen %d%%) "),
- 		 lines_more, percent_done);
- 	  }
-  
- 	  MoveCursor(LINES, 0);
- 	  StartBold();
- 	  Write_to_screen(footer, 0);
- 	  EndBold();
- 
- 	  switch(ch = ReadCh()) {
- 
- 	    case '\n':
- 	    case '\r':	/* scroll down a line */
- 			unfilled_lines = 1;
- 			ClearLine(LINES);
- 			break;
- 
- 	    case ' ':	/* scroll a screenful */
- 			unfilled_lines = LINES;
- 			if(clear_pages) {
- 			  ClearScreen();
- 			  MoveCursor(0,0);
- 			  CarriageReturn();
- 
- 			  /* output title */
- 			  if(title_messages && filter) {
- 			    title_for_page(++pages_displayed);
- 			    unfilled_lines -= 2;
- 			  }
- 			} else ClearLine(LINES);
- 
- 			/* and keep last line to be first line of next
- 			 * screenful unless we had a formfeed */
- 			if(!formfeed) {
- 			  if(clear_pages)
- 			    Write_to_screen(display_buffer, 0);
- 			  unfilled_lines--;
- 			}
- 			break;
- 
- 	    default:	return(ch);
- 	  }
- 	  CarriageReturn();
- 	} while(pending_len > 0);
- 	return(FALSE);
- }
- 	  
- title_for_page(page)
- int page;
- {
- 	/** Output a nice title for the second thru last pages of the message 
- 	    we're currently reading. Note - this code is very similar to
- 	    that which produces the title for the first page, except that
- 	    page number replaces the date and the method by which it
- 	    gets to the screen **/
- 
- 	static char title1[SLEN], title2[SLEN];
- 	char titlebuf[SLEN], title3[SLEN], who[SLEN];
- 	static t1_len, t2_len;
- 	register int padding, showing_to;
- 
- 	/* format those parts of the title that are constant for a message */
- 	if(form_title) {
- 
- 	  showing_to = tail_of(headers[current-1]->from, who,
- 	    headers[current-1]->to);
- 
- 	  sprintf(title1, "%s %d/%d  ",
- 	      headers[current-1]->status & DELETED ? nls_deleted :
- 	      headers[current-1]->status & FORM_LETTER ? nls_form: nls_message,
- 	      current, message_count);
- 	  t1_len = strlen(title1);
- 	  sprintf(title2, "%s %s", showing_to? nls_to : nls_from, who);
- 	  t2_len = strlen(title2);
- 	}
- 	/* format those parts of the title that vary between pages of a mesg */
- 	sprintf(title3, nls_page, page);
- 
- 	/* truncate or pad title2 portion on the right
- 	 * so that line fits exactly to the rightmost column */
- 	padding = COLUMNS - (t1_len + t2_len + strlen(title3));
- 
- 	sprintf(titlebuf, "%s%-*.*s%s\n\r\n\r", title1, t2_len+padding,
- 	    t2_len+padding, title2, title3);
- 	    /* extra newline is to give a blank line after title */
- 
- 	Write_to_screen(titlebuf, 0);
- 	form_title = 0;
- }
--- 0 ----
Index: elm2.4.ME+.50/lib/safeopen.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/lib/safeopen.c	Tue Nov 17 21:12:56 1998
***************
*** 0 ****
--- 1,45 ----
+ /* $Id: safeopen.c,v 1.1.1.1 1998/10/15 15:36:41 hurtta Exp $ */
+ 
+ #include <stdio.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ 
+ #include "headers.h"
+ #include "me.h"
+ 
+ FILE *safeopen(name)
+      char *name;
+ {
+     FILE *fp;
+     int fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0600);
+ 
+     if (fd < 0 &&
+ 	(unlink(name) ||
+ 	 (fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0600)) < 0))
+ 	return NULL;
+ 
+     if (! (fp = fdopen(fd, "w"))) {
+       close(fd);
+       unlink(name);
+     }
+     return fp;
+ }
+ 
+ FILE *safeopen_rdwr(name)
+      char *name;
+ {
+     FILE *fp;
+     int fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
+ 
+     if (fd < 0 &&
+ 	(unlink(name) ||
+ 	 (fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0))
+ 	return NULL;
+ 
+     if (! (fp = fdopen(fd, "w+"))) {
+       close(fd);
+       unlink(name);
+     }
+     return fp;
+ }
+ 
Index: elm2.4.ME+.50/melib/Makefile.SH
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/melib/Makefile.SH	Tue Nov 17 21:12:56 1998
***************
*** 0 ****
--- 1,105 ----
+ case $CONFIG in
+ '')
+     if test ! -f config.sh; then
+ 	ln ../config.sh . || \
+ 	ln ../../config.sh . || \
+ 	ln ../../../config.sh . || \
+ 	(echo "Can't find config.sh."; exit 1)
+     fi
+     . ./config.sh
+     ;;
+ esac
+ case "$0" in
+ */*) cd `expr X$0 : 'X\(.*\)/'` ;;
+ esac
+ 
+ echo "Extracting melib/Makefile (with variable substitutions)"
+ cat >Makefile <<!GROK!THIS!
+ # $Id: Makefile.SH,v 1.2 1998/10/20 19:58:08 hurtta Exp $
+ #  Makefile for the ELM mail program.
+ #
+ # Variables
+ #	Variables established by Configure
+ AR		=	ar
+ CC		=	$cc
+ CCFLAGS		=	$ccflags $xencf
+ CHMOD		=	$chmod
+ LINT		=	$lint
+ OPTIMIZE	=	$optimize
+ RANLIB		=	$ranlib
+ RM		= 	$rm -f
+ TOUCH		=	$touch
+ TAGS		=	ctags
+ 
+ !GROK!THIS!
+ 
+ cat >>Makefile <<'!NO!SUBS!'
+ #	Other general variables
+ CFLAGS		=	-I$(INCLDIR) $(CCFLAGS) $(OPTIMIZE) $(DEBUG) $(DACSNET) 
+ INCLDIR		=	../hdrs
+ LINTFLAGS	=	-I$(INCLDIR)
+ SHELL		=	/bin/sh
+ 
+ # 	Lists
+ LIB_SRC		= 	parse_util.c	\
+ 			pgp_decode.c	\
+ 			mime.c		\
+ 			mime_decode.c	\
+ 			mime_parse.c	\
+ 			state.c
+ 
+ LIB_OBJ		=	parse_util.o	\
+ 			pgp_decode.o	\
+ 			mime.o		\
+ 			mime_decode.o	\
+ 			mime_parse.o	\
+ 			state.o
+ 
+ all:			Makefile libme.a
+ 
+ install:		Makefile libme.a
+ 
+ uninstall:		libme.a
+ 
+ Makefile: Makefile.SH ../config.sh
+ 	@echo "You must run 'sh Configure -S' or 'sh Configure'"
+ 	exit 1
+ 
+ libme.a:		$(LIB_OBJ)
+ 			$(AR) r $@ $?
+ 			$(RANLIB) $@
+ 
+ lint:		
+ 		$(LINT) $(LINTFLAGS) $(LIB_SRC) > LINT.OUT
+ 
+ tags:
+ 		$(TAGS) $(LIB_SRC)
+ 
+ clean:		
+ 		$(RM) $(LIB_OBJ) libme.a
+ 
+ # Dependencies and rules
+ #	Dependencies of header files upon other header files they include
+ .PRECIOUS:		$(INCLDIR)/defs.h $(INCLDIR)/elm.h $(INCLDIR)/headers.h
+ 
+ $(INCLDIR)/defs.h:	$(INCLDIR)/../config.h $(INCLDIR)/sysdefs.h
+ 			$(CHMOD) u+w $@
+ 			$(TOUCH) $@
+ 
+ $(INCLDIR)/elm.h:	$(INCLDIR)/curses.h $(INCLDIR)/defs.h  $(INCLDIR)/melib.h
+ 			$(CHMOD) u+w $@
+ 			$(TOUCH) $@
+ 
+ $(INCLDIR)/headers.h:	$(INCLDIR)/curses.h $(INCLDIR)/defs.h  $(INCLDIR)/me.h $(INCLDIR)/elmlib.h
+ 			$(CHMOD) u+w $@
+ 			$(TOUCH) $@
+ 
+ #	Dependencies of C object files
+ pgp_decode.o:		$(INCLDIR)/headers.h $(INCLDIR)/melib.h $(INCLDIR)/s_me.h  
+ parse_util.o:   	$(INCLDIR)/headers.h $(INCLDIR)/melib.h $(INCLDIR)/s_me.h  
+ mime_parse.o:   	$(INCLDIR)/headers.h $(INCLDIR)/melib.h $(INCLDIR)/s_me.h  
+ mime_decode.o:  	$(INCLDIR)/headers.h $(INCLDIR)/melib.h $(INCLDIR)/s_me.h  
+ mime.o:			$(INCLDIR)/headers.h $(INCLDIR)/melib.h $(INCLDIR)/s_me.h  
+ state.o:		$(INCLDIR)/headers.h $(INCLDIR)/melib.h $(INCLDIR)/s_me.h  
+ !NO!SUBS!
+ 
Index: elm2.4.ME+.50/melib/mime.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/melib/mime.c	Tue Nov 17 21:12:56 1998
***************
*** 0 ****
--- 1,133 ----
+ static char rcsid[] = "@(#)$Id: mime.c,v 1.2 1998/10/20 19:58:08 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *****************************************************************************/
+ 
+ #include "headers.h"
+ #include "melib.h"
+ #include "s_me.h"
+ 
+ #ifdef MIME
+ 
+ #include <errno.h>
+ #include <sys/stat.h>
+ 
+ /* Notice that ENCODING_ILLEGAL is -1 
+  */
+ 
+ char *mime_encode_names[] = {
+   "none", /* Not used. */
+   "7bit",
+   "8bit",
+   "binary",
+   "quoted-printable",
+   "base64",
+   "X-???"         /* ENCODING_EXPERIMENTAL */
+ };
+ 
+ 
+ void mime_panic(f,ln,pr,ms) 
+      char * f;
+      int ln;
+      char *pr;
+      char *ms;
+ {
+   int do_cursor = RawState();
+ 
+   dprint(1,(debugfile,"\nMIME PANIC in %s:%d:%s\n",f,ln,pr));
+   dprint(1,(debugfile,">>%s\n",ms));
+ 
+   /* softkeys_off(); */
+ 
+   if (do_cursor) {
+     lib_error(FRM("MIME PANIC: %s"),ms);
+     sleep(1);
+   }
+ 
+   if (do_cursor) {
+     MoveCursor(elm_LINES, 0);
+     Raw(OFF);
+   }
+ 
+   fprintf(stderr,"\nMIME PANIC in %s:%d:%s\n",f,ln,pr);
+   fprintf(stderr,">>%s\n",ms);
+ 
+ #if DEBUG
+   if (debug > 10) {
+     fprintf(stderr,"ABORTING...\n");
+     fflush(stderr);
+     abort();
+   }
+ #endif
+   emergency_exit();
+ }
+ 
+ 
+ int check_encoding(Encoding)
+      char *Encoding;
+ {
+   char *c, *d, tmp[VERY_LONG_STRING];
+   int result =  ENCODING_ILLEGAL;
+ 
+   dprint (9, (debugfile, "check_encoding(): Encoding=\"%s\"\n", Encoding));
+ 
+   /* Don't harm "str" */
+   strfcpy (tmp, Encoding, sizeof(tmp));
+   
+   rfc822_reap_comments (tmp, NULL, 0);
+   c = tmp;
+   d = tmp + strlen(tmp);
+ 
+   while (d > tmp && whitespace(*(d-1)))
+     d--;
+   *d = '\0';
+   while (*c && whitespace(*c))
+     c++;
+ 
+   if ('\0' == *c)
+     result = ENCODING_7BIT;
+   else if (strincmp(c, "x-", 2) == 0) 
+     result = ENCODING_EXPERIMENTAL;
+   else {
+     int i;
+     for (i = ENCODING_7BIT; i < ENCODING_EXPERIMENTAL; i++) {
+       if (istrcmp(c, mime_encode_names[i]) == 0) {
+ 	result = i;
+ 	break;
+       }
+     }
+   }
+ 
+   dprint (9, (debugfile, "check_encoding()=%s (%d)\n",
+ 	      ENCODING(result),result));
+   return(result);
+ }
+ 
+ int charset_ok(s)
+      char *s;
+ {
+     /* Return true if configured charset could display us-ascii too */
+     char buf[SLEN];	/* assumes sizeof(charset_compatlist) <= SLEN */
+     char *bp, *chset;
+ 
+     /* the "charset_compatlist[]" format is: */
+     /*   charset charset charset ... */
+     bp = strfcpy(buf, charset_compatlist, sizeof buf);
+     while ((chset = strtok(bp, " \t\n")) != NULL) {
+ 	bp = NULL;
+ 	if (istrcmp(chset, s) == 0)
+ 	    break;
+     }
+ 
+     /* see if we reached the end of the list without a match */
+     if (chset == NULL) {
+ 	return(FALSE);
+     }
+     return(TRUE);
+ }
+ 
+ 
+ #endif /* MIME */
Index: elm2.4.ME+.50/melib/mime_decode.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/melib/mime_decode.c	Tue Nov 17 21:12:56 1998
***************
*** 0 ****
--- 1,2005 ----
+ static char rcsid[] = "@(#)$Id: mime_decode.c,v 1.2 1998/10/20 19:58:08 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *
+  *  Initially written by: Michael Elkins <elkins@aero.org>, 1995
+  *****************************************************************************/
+ 
+ #include "headers.h"
+ #include "melib.h"
+ #include "s_me.h"
+ 
+ #ifdef MIME
+ 
+ static int index_hex[128] = {
+     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+      0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,
+     -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+     -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
+ };
+ 
+ static int index_64[128] = {
+     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
+     52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
+     -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
+     15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
+     -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
+     41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
+ };
+ 
+ #define base64(c) ((((c) > 0) && ((c) < 127)) ? index_64[ (c) ] : -1)
+ #define hex(c) ((((c) > 0) && ((c) < 127)) ? index_hex[ (c) ] : -1)
+ 
+ /* Prototype */
+ static void Xbit_decode	P_((in_state_t *, out_state_t *, int, int)); 
+ 
+ static void Xbit_decode (s_in, s_out, len, is_text)
+      in_state_t *s_in;
+      out_state_t *s_out;
+      int len;
+      int is_text;
+ {
+   char buf[VERY_LONG_STRING];
+   int offset = 0, length;
+ 
+   if (s_out->prefix) {
+     strfcpy (buf, s_out->prefix, sizeof buf);
+     offset = strlen (buf);
+   }
+   while (len > 0) {
+     if (0 ==
+ 	(length = state_getl (buf + offset, sizeof buf - offset, s_in)))
+       break;
+     len -= length;
+ 
+     /* Take care of CRLF => LF conversion */
+     if (is_text > 0 &&
+ 	length > 1 &&
+ 	buf[offset + length - 1] == '\n' &&
+         buf[offset + length - 2] == '\r') {
+       buf[offset + length - 2] = '\n';
+       buf[offset + length - 1] = '\0';
+       length--;
+     }
+ 
+     state_put(buf,offset+length,s_out);
+   }
+ }
+ 
+ void base64_decode (s_in, s_out, length, astext)
+      in_state_t  *s_in;
+      out_state_t *s_out;
+      int length;
+      int astext;
+ {
+   /* Notes:  this routine assumes that strlen(line length) % 4 == 0.
+      Most intelligent software will do this, so I haven't worried
+      about being *completely* compliant with the standard.  I've
+      not run into any encoded data where this was not true.  */
+   
+   char buf[STRING], *p;
+   int
+     bytes = 0, /* the total number of bytes read so far */
+     terminate = FALSE,
+     c1, c2, c3, c4;
+   unsigned char
+     ch,
+     store_ch = 0; /* for astext */
+   int corrupted = FALSE;
+ 
+   dprint(10,(debugfile,
+            "base64_decode: length=%d, prefix=%s, astext=%d\n",
+            length,
+            s_out->prefix ? s_out->prefix : "<NULL>",
+            astext));
+ 
+   /* Make sure to quote the first line! */
+   state_add_prefix(s_out);
+ 
+   while (! terminate) {
+     int len;
+ 
+     if (bytes >= length)
+       break;
+ 
+     if ((len = state_getl (buf, VERY_LONG_STRING, s_in)) <= 0)
+ 	break;
+ 
+     bytes += len;
+ 
+     p = buf;
+     while (*p) {
+       c1 = *p++;
+ 
+       if (base64(c1) == -1) {
+         p--;
+         /* partial fix -- K E H   <hurtta@dionysos.FMi.FI>  */
+ 
+         while (*p == ' ' || *p == '\t' || *p == '\r')
+           p++;
+ 
+         if (*p != '\n')
+           corrupted = TRUE;  /* Perhaps corrupted */
+ 
+         if (*p == 0)
+           break;
+ 
+         c1 = *p++;
+       }
+ 
+       /* End of the line. */
+       if (c1 == '\n')
+ 	continue;
+ 
+       c2 = *p++;
+       
+       c1 = base64(c1);
+       if (c1 == -1)
+         corrupted = TRUE;
+       c2 = base64(c2);
+       if (c2 == -1)
+         corrupted = TRUE;
+       ch = (c1 << 2) | (c2 >> 4);
+       
+       if (store_ch && ch != '\n') /* for astext */
+ 	state_putc(store_ch,s_out);
+ 
+       store_ch = 0;
+       if (astext && ch == '\r')
+         store_ch = ch;
+       else {
+ 	state_putc(ch,s_out);
+ 	if (ch == '\n')
+ 	  state_add_prefix(s_out);
+       }      
+     
+       c3 = *p++;
+       if (c3 == '=') {
+ 	terminate = TRUE;
+ 	break;
+       }
+       c3 = base64(c3);
+       if (c3 == -1)
+ 	corrupted = TRUE;
+       ch = ((c2 & 0xf) << 4) | (c3 >> 2);
+ 
+       if (store_ch && ch != '\n')
+ 	state_putc(store_ch,s_out);
+ 
+       store_ch = 0;
+ 
+       if (astext && ch == '\r')
+ 	store_ch = ch;
+       else {
+ 	state_putc(ch,s_out);
+ 	if (ch == '\n')
+ 	  state_add_prefix(s_out);
+       }
+   
+       c4 = *p++;
+       if (c4 == '=') {
+ 	terminate = TRUE;
+ 	break;
+       }
+       
+       c4 = base64(c4);
+       if (c4 == -1)
+ 	corrupted = TRUE;
+       ch = ((c3 & 0x3) << 6) | c4;
+       
+       if (store_ch && ch != '\n')
+ 	state_putc(store_ch,s_out);
+ 
+       store_ch = 0;
+ 
+       if (astext && ch == '\r') {
+ 	store_ch = ch;
+       }
+       else {
+ 	state_putc(ch,s_out);
+ 	if (ch=='\n')
+ 	  state_add_prefix(s_out);
+       }
+     }
+   }
+ 
+   /* Make sure to flush anything left in the internal buffer. */
+   if (store_ch)  /* for astext */
+     state_putc(store_ch,s_out);
+ 
+   if (corrupted) {
+     if (s_out->displaying) {
+       state_puts("\n[",s_out);
+       state_puts(catgets(elm_msg_cat, MeSet, MeDecodeBASE64Corrupt,
+ 			 "BASE64 data was corrupt!"),s_out);
+       state_puts("]\n",s_out);
+     }
+     lib_error (CATGETS(elm_msg_cat, MeSet, MeDecodeBASE64Corrupt,
+ 		       "BASE64 data was corrupt!"));
+     sleep_message();
+   }
+ 
+   dprint(10,(debugfile,"base64_decode: readed=%d bytes, corrupted=%d.\n",
+ 	     bytes,corrupted));   
+ 
+   return;
+ }
+   
+ void quoted_printable_decode (s_in, s_out, length, astext)
+      in_state_t  *s_in;
+      out_state_t *s_out;
+      int length;
+      int astext;
+ {
+   int bytes = 0; /* number of bytes read */
+   int nl = TRUE; /* flag to indicate hitting a new line */
+   char *p;
+   int c1, c2;
+   unsigned char ch, store_ch = 0;
+   char buf[VERY_LONG_STRING];
+   int corrupted = 0;
+ 
+   dprint(10,(debugfile,
+ 	     "quoted_printable_decode: length=%d, prefix=%s, astext=%d\n",
+ 	     length,
+ 	     s_out->prefix ? s_out->prefix : "<NULL>",
+ 	     astext));
+ 
+   for (;;) {
+     int len;
+ 
+     if (bytes >= length)
+       break;
+ 
+     if ((len=state_getl (buf, VERY_LONG_STRING, s_in)) <= 0)
+       break;
+     bytes += len;
+ 
+     p = buf;
+     while (*p) {
+ 
+       /* If there is a prefix and this is the beginning of a new line... */
+       if (nl) {
+ 	state_add_prefix(s_out);
+ 	nl = FALSE;
+       }
+ 
+       if (store_ch)
+ 	state_putc(store_ch,s_out);
+       
+       if (*p == '=') {
+ 	p++;
+ 	/* Ignore spaces in end of line   -- see MIME */
+ 	if (*p == '\r' || *p == ' ' || *p == '\t') {
+ 	  char *t = p;
+ 	  while (*t && (*t == '\r' || *t == ' ' || *t == '\t'))
+ 	    t++;
+ 	  if (*t && *t == '\n')
+ 	    p = t;
+ 	}
+ 
+ 	if (*p == '\n') { /* soft linebreak */
+ 	  if (length <= 0)
+ 	    break;
+ 	  p++;
+ 	}
+ 	else {
+ 	  c1 = hex(*p);
+ 	  if (c1 == -1)
+ 	    corrupted = TRUE;
+ 	  p++;
+ 	  c2 = hex(*p);
+ 	  if (c2 == -1)
+ 	    corrupted = TRUE;
+ 	  p++;
+ 	  ch = (c1 << 4) | c2;
+ 
+ 	  /* We not need here CR LF -> LF removing, because
+ 	   * CRLF's which presents end of line should NOT be encoded.
+ 	   *                             - K E H <hurtta@dionysos.FMI.FI> */
+ 
+ 	  state_putc(ch,s_out);
+ 	}
+       }
+       else {
+        if (astext && *p == '\r')
+          store_ch = *p;
+        else
+ 	 state_putc(*p,s_out);
+ 	 
+        if (*p == '\n') {
+ 	 nl = TRUE;
+ 	 if (length <= 0)
+ 	   break;
+        }
+ 
+        p++;
+       }  
+     }
+   }
+ 
+   /* Flush anything left in the buffer */
+   if (store_ch) /* for astext */
+     state_putc(store_ch,s_out);
+ 
+   if (corrupted) {
+     if (s_out -> displaying) {
+       state_puts("\n[",s_out);
+       state_puts(catgets(elm_msg_cat, MeSet, MeDecodeQPCorrupt,
+ 			 "Seems that QUOTED-PRINTABLE data was corrupted."),
+ 		 s_out);
+       state_puts("]\n",s_out);
+     }
+     lib_error (CATGETS(elm_msg_cat, MeSet, MeDecodeQPCorrupt,
+ 		       "Seems that QUOTED-PRINTABLE data was corrupted."));
+     sleep_message();
+   }
+   
+   dprint(10,(debugfile,
+ 	     "quoted_printable_decode: readed=%d bytes, corrupted=%d.\n",
+ 	     bytes,corrupted));
+ 
+   return;
+ }
+ 
+ /* Prototype */
+ static void multipart_decode  P_((mime_t *, 
+ 				  in_state_t *, out_state_t *)); 
+ 
+ static void multipart_decode (att, state_in, state_out)
+      mime_t *att; /* The list of attachments for this MULTIPART data */
+      in_state_t   *state_in;
+      out_state_t  *state_out;
+ {
+   int nattach = 0;
+   char buf[VERY_LONG_STRING];
+ 
+   dprint(12,(debugfile,
+ 	     "multipart_decode -> START\n"));
+ 
+   if (att->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"multipart_decode",
+ 	       "Bad magic number");
+ 
+   if (!in_state_seekable(state_in)) {
+     state_putc('[',state_out);
+     state_puts(catgets(elm_msg_cat, MeSet, MeDecodeMultipartUnsupportedIS,
+ 		       "multipart_decode: unsupported input state"),
+ 	       state_out);
+     state_puts("]\n",state_out);
+     lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeMultipartUnsupportedIS,
+ 		  "multipart_decode: unsupported input state"));
+     sleep_message();
+     return;
+   }
+ 
+   while (att) {
+ 
+     if (att->magic != MIME_magic)
+       mime_panic(__FILE__,__LINE__,"multipart_decode",
+ 		 "Bad magic number (next -chain)");
+ 
+     nattach++;
+ 
+     dprint(12,(debugfile,
+ 	       "multipart_decode: [%d]: Type: %.15s/%.30s, Encoding: %d, Size: %d\n",
+ 	       nattach, 
+ 	       mime_types[att->type], att->subtype,
+ 	       att->encoding, att->length));
+ 
+     if (in_state_fseek(state_in,att->offset) != 0) {
+       state_putc('[',state_out);
+       state_puts(catgets(elm_msg_cat, MeSet, MeDecodeMultipartSeekFail,
+ 			"multipart_decode: seek failed"),
+ 		 state_out);
+       state_puts("]\n",state_out);
+       lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeMultipartSeekFail,
+ 			"multipart_decode: seek failed"));
+       sleep_message();
+       return;
+     }
+ 
+     if (state_out->displaying) {
+       char Buffer[70], tmp[40];
+       char *Encoding = "???";
+        
+       Buffer[0] = '\0';
+       tmp[0] = '\0';
+       if (att->description) {
+ 	elm_sfprintf(Buffer,sizeof Buffer,
+ 		     CATGETS(elm_msg_cat, MeSet, MeDecodeDesc,
+ 			     "\"%.60s\"]\n["),
+ 		     att->description);
+       } else if (att->disposition_opts &&
+ 		 mime_get_param ("filename", tmp, att->disposition_opts, sizeof(tmp))) {
+ 	elm_sfprintf(Buffer,sizeof Buffer,
+ 		     CATGETS(elm_msg_cat, MeSet, MeDecodeDescFilename,
+ 			     "Filename: %.60s]\n["),
+ 		     tmp);
+       }
+ 
+       Encoding = ENCODING(att->encoding);
+       
+       /* First print out a nice display line about this attachment */
+       if (att->disposition != DISP_INLINE)
+ 	elm_sfprintf (buf, sizeof buf,
+ 		      CATGETS(elm_msg_cat, MeSet, MeDecodeAttach,
+ 			      "%s[Attach #%d: %sType: %.15s/%.30s, Encoding: %s, Size: %d]\n"),
+ 		      nattach > 1 ? "\n" : "",
+ 		      nattach, Buffer,
+ 		      mime_types[att->type], att->subtype,
+ 		      Encoding, att->length);
+       else
+ 	elm_sfprintf (buf, sizeof buf,
+ 		      CATGETS(elm_msg_cat, MeSet, MeDecodePart,
+ 			      "%s[Part #%d: %sType: %.15s/%.30s, Encoding: %s, Size: %d]\n"),
+ 		      nattach > 1 ? "\n" : "",
+ 		      nattach, Buffer,
+ 		      mime_types[att->type], att->subtype,
+ 		      Encoding, att->length);
+     }
+     else {
+       buf[0] = '\0';
+       if (nattach > 1)
+         strfcpy (buf, "\n", sizeof buf);
+       if (att->description && (strlen(att->description) < sizeof(buf) -30)) {
+ 	elm_sfprintf (buf, sizeof buf,
+ 		      CATGETS(elm_msg_cat, MeSet, MeDecodeContentDesc,
+ 			      "Content-Description: %.300s\n\n"),
+ 		      att->description, sizeof buf);
+       }
+     }
+       
+     state_puts(buf,state_out);
+     if (state_out->displaying)
+       state_putc('\n', state_out);
+     mime_decode (att, state_in, state_out);
+     att = att->next;
+   }
+   dprint(12,(debugfile,
+ 	     "multipart_decode <- END\n"));
+ }
+ 
+ static mime_t * best_alternative P_((mime_t *att));
+ /* Prototype */
+ static void alternative_decode P_((mime_t *, 
+ 				   in_state_t *, out_state_t *)); 
+ 
+ static void alternative_decode (ptr, state_in, state_out)
+      mime_t *ptr;
+      in_state_t *state_in;
+      out_state_t *state_out;
+ {
+   mime_t *best;
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"alternative_decode",
+ 	       "Bad magic number");
+ 
+   if (!in_state_seekable(state_in)) {
+     state_putc('[',state_out);
+     state_puts(catgets(elm_msg_cat, MeSet, MeDecodeAlternativeUnsupportedIS,
+ 		       "alternative_decode: unsupported input state"),
+ 	       state_out);
+     state_puts("]\n",state_out);
+     lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeAlternativeUnsupportedIS,
+ 		      "alternative_decode: unsupported input state"));
+     sleep_message();
+     return;
+   }
+ 
+   if (! ptr->parts) {
+     state_putc('[',state_out);
+     state_puts (catgets(elm_msg_cat, MeSet, MeDecodeAlternativeNosubtypes,
+ 			"Content-Type: multipart/alternative, no subtypes (parts=null)"), 
+ 		state_out);
+     state_puts("]\n",state_out);
+     lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeAlternativeNosubtypes,
+ 		      "Content-Type: multipart/alternative, no subtypes (parts=null)"));
+     sleep_message();
+     return;
+   }
+ 
+   best = best_alternative(ptr->parts);
+ 
+   if (best) {
+     char buf[300];
+     dprint(12,(debugfile,
+ 	       "multipart_alternative: Type: %.15s/%.30s, Encoding: %d, Size: %d\n",
+ 	       mime_types[best->type], best->subtype,
+ 	       best->encoding, best->length));
+ 
+     if (in_state_fseek(state_in,best->offset) != 0) {
+       state_putc('[',state_out);
+       state_puts(catgets(elm_msg_cat, MeSet, MeDecodeAlternativeSeekFailed,
+ 			 "multipart_alternative: seek failed"),
+ 		 state_out);
+       state_puts("]\n",state_out);
+       lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeAlternativeSeekFailed,
+ 			"multipart_alternative: seek failed"));
+       sleep_message();
+       return;
+     }
+ 
+     if (state_out->displaying) {
+       char Buffer[70], tmp[40];
+       char *Encoding = "???";
+        
+       Buffer[0] = '\0';
+       tmp[0] = '\0';
+       if (best->description) {
+ 	elm_sfprintf(Buffer,sizeof Buffer,
+ 		     CATGETS(elm_msg_cat, MeSet, MeDecodeDesc,
+ 			     "\"%.60s\"]\n["),
+ 		     best->description);
+       } else if (best->disposition_opts &&
+ 		 mime_get_param ("filename", tmp, 
+ 				 best->disposition_opts, sizeof(tmp))) {
+ 	elm_sfprintf(Buffer,sizeof Buffer,
+ 		     CATGETS(elm_msg_cat, MeSet, MeDecodeDescFilename,
+ 			     "Filename: %.60s]\n["),
+ 		     tmp);
+       }
+ 
+       Encoding = ENCODING(best->encoding);
+       
+       /* First print out a nice display line about this part */
+       if (best->disposition != DISP_INLINE)
+ 	elm_sfprintf (buf, sizeof buf,
+ 		      CATGETS(elm_msg_cat, MeSet, MeDecodeSelAttach,
+ 			      
+ 			      "[Selecting attach: %sType: %.15s/%.30s, Encoding: %s, Size: %d]\n"),
+ 		      Buffer,
+ 		      mime_types[best->type], best->subtype,
+ 		      Encoding, best->length);
+       else
+ 	elm_sfprintf (buf, sizeof buf,
+ 		      CATGETS(elm_msg_cat, MeSet, MeDecodeSelPart,
+ 			      
+ 			      "[Selecting part: %sType: %.15s/%.30s, Encoding: %s, Size: %d]\n"),
+ 		      Buffer,
+ 		      mime_types[best->type], best->subtype,
+ 		      Encoding, best->length);
+ 
+     }
+     else {
+       buf[0] = '\0';
+       if (best->description && (strlen(best->description) < sizeof(buf) -30)) {
+ 	elm_sfprintf (buf, sizeof buf,
+ 		      CATGETS(elm_msg_cat, MeSet, MeDecodeContentDesc,
+ 			      "Content-Description: %.300s\n\n"),
+ 		      best->description, sizeof buf);
+       }
+     }
+       
+     state_puts(buf,state_out);
+     if (state_out->displaying)
+       state_putc('\n', state_out);
+     mime_decode (best, state_in, state_out);
+ 
+   } else {
+     state_puts("[", state_out);
+     state_puts(catgets(elm_msg_cat, MeSet, MeDecodeCtNoAlternative,
+ 		       "Content-Type: multipart/alternative, alternative not found"),
+ 	       state_out);
+     
+     state_puts("]\n", state_out);
+     lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeCtNoAlternative,
+ 		      "Content-Type: multipart/alternative, alternative not found"));
+     sleep_message();
+   }
+ }
+ 
+ /* Prototype */
+ static void multipart_0_decode P_((mime_t *, 
+ 				   in_state_t *, out_state_t *)); 
+ 
+ static void multipart_0_decode (ptr, state_in, state_out)
+      mime_t *ptr;
+      in_state_t *state_in;
+      out_state_t *state_out;
+ {
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"multipart_0_decode",
+ 	       "Bad magic number");
+ 
+   if (ptr->parts)
+     multipart_decode (ptr->parts, state_in, state_out);
+   else {
+     state_putc('[',state_out);
+     state_puts (catgets(elm_msg_cat, MeSet, MeDecodeMultipartNoparts,
+ 			"Content-Type: multipart/*, no subtypes (parts = NULL)"),
+  		state_out);
+     state_puts("]\n",state_out);
+     lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeMultipartNoparts,
+ 		      "Content-Type: multipart/*, no subtypes (parts = NULL)"));
+     sleep_message();
+   }
+ }
+ 
+ /* Prototype */
+ static void rfc822_decode P_((mime_t *, 
+ 			      in_state_t *, out_state_t *)); 
+ 
+ static int rfc822_header_filter     P_((header_list_ptr, int));
+ static void rfc822_header_converter P_((header_list_ptr, int, char *, int));
+ 
+ static int rfc822_header_filter(hdr,flag)
+      header_list_ptr hdr;
+      int flag;                  /* elm_filter */
+ {
+   char buf[80];
+ 
+   strfcpy(buf,hdr->header_name->header,78);
+   strfcat(buf,": ", sizeof buf);
+   
+   if (flag) {
+     if (matches_weedlist (buf)) 
+       return 0;
+     else
+       return 1;
+   } else
+     return 1;
+ }
+ 
+ static void rfc822_header_converter (hdr,flag,buffer,size)
+      header_list_ptr hdr;
+      int flag;
+      char *buffer;
+      int size;
+ {
+   int class = hdr->header_name->flag;
+ 
+   if (!hdr->body) {
+     buffer[0] = '\0';
+     return;
+   }
+ 
+   dprint(12,(debugfile,"rfc822_header_converter: header=%s,class=%d,rest=%s",
+ 	     hdr->header_name->header,class,hdr->body));
+ 
+   flag++;      /* So that flag is used */
+ 
+   strfcpy(buffer,hdr->body,size);
+ 
+   if (class & HDR_TEXT) {
+     if (is_rfc1522 (buffer))
+       rfc1522_decode (buffer, size);
+   } else if (class & HDR_STRUCTURED) {
+     rfc1522_decode_structured(class,buffer,size);
+   }
+ 
+   dprint(12,(debugfile,"rfc822_header_converter: decoded rest=%s",buffer));
+ 
+ }
+ 
+ static void rfc822_decode (mt, state_in, state_out)
+      mime_t *mt;
+      in_state_t *state_in;
+      out_state_t *state_out;
+ {
+   /* This looks a lot like multipart_decode() except that we want to print
+    * the headers for the message.  NOTE: "mt" should be a pointer to the
+    * RFC822 attachment, NOT its subpart, since we need the offset in order
+    * to print out the headers.
+    */
+ 
+   header_list_ptr headers = NULL;
+   header_list_ptr From_header, mime_version, osv;
+   int decode_headers = 1;
+ 
+   if (mt->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"rfc822_decode",
+ 	       "Bad magic number");
+   
+   if (!in_state_seekable(state_in)) {
+     state_putc('[',state_out);
+     state_puts(catgets(elm_msg_cat, MeSet, MeDecodeRFC822UnsupportedIS,
+ 		       "rfc822_decode: unsupported input state"),
+ 	       state_out);
+     state_puts("]\n",state_out);
+     lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeRFC822UnsupportedIS,
+ 		      "rfc822_decode: unsupported input state"));
+     sleep_message();
+     return;
+   }
+ 
+   if (in_state_fseek(state_in,mt->offset) != 0) {
+     state_putc('[',state_out);
+     state_puts(catgets(elm_msg_cat, MeSet, MeDecodeRFC822SeekFailed,
+ 		       "rfc822_decode: seek failed"),
+ 	       state_out);
+     state_puts("]\n",state_out);
+     lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeRFC822SeekFailed,
+ 		      "rfc822_decode: seek failed"));
+     sleep_message();
+     return;
+   }
+ 
+   headers = state_read_headers(state_in, RHL_MARK_FOLDING);
+ 
+   mime_version = locate_header_by_name(headers,"MIME-Version");
+   osv          = locate_header_by_name(headers,"X-ELM-OSV");
+ 
+   if (!mime_version && !req_mime_hdrencoding && !req_mime_hdrencoding)
+     decode_headers = 0;
+   if (osv && osv->body) {
+     char value[20];
+     if (mime_get_param("no-hdr-encoding",value,osv->body,
+ 		       sizeof value) && atoi(value) > 0)
+       decode_headers = 0;
+   }
+ 
+   From_header  = locate_header_by_name(headers,"From");
+ 
+   if (From_header) {
+     char buffer[1024+1],buffer2[1024+50];
+     strfcpy(buffer,From_header->body,sizeof buffer);
+     if (decode_headers && is_rfc1522 (buffer))
+       rfc1522_decode_structured (From_header->header_name->flag,
+ 				 buffer, sizeof buffer);
+     elm_sfprintf(buffer2,sizeof buffer2,
+ 	    CATGETS(elm_msg_cat, MeSet, MeDecodeStartMail,
+ 		    "-- Start of included mail From: %s\n"),
+ 	    buffer);
+     state_puts(buffer2,state_out);
+   }
+   else
+     state_puts(catgets(elm_msg_cat, MeSet, MeDecodeStartMail1,
+ 		       "-- Start of included mail.\n"),
+ 	       state_out);
+ 
+   state_write_headers(state_out,headers,
+ 		      rfc822_header_filter,
+ 		      decode_headers ? rfc822_header_converter :
+ 		      NULL_header_converter,
+ 		      elm_filter);
+ 
+   delete_headers(headers); headers = NULL;
+ 
+   state_putc('\n',state_out);
+ 
+   if (mt->parts == NULL) {
+     state_putc('[',state_out);
+     state_puts(catgets(elm_msg_cat, MeSet, MeDecodeNoRFC822,
+ 		       "rfc822_decode: no body of RFC 822 mail (parts = NULL)"),
+ 	       state_out);
+     state_puts("]\n",state_out);
+     lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeNoRFC822,
+ 		  "rfc822_decode: no body of RFC 822 mail (parts = NULL)"));
+     sleep_message();
+     return;
+   }
+ 
+   if (mt->parts->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"rfc822_decode",
+ 	       "Bad magic number (parts)");
+ 
+   mime_decode (mt->parts, state_in, state_out);
+   state_puts(catgets(elm_msg_cat, MeSet, MeDecodeEndMail,
+ 		     "-- End of included mail.\n"),
+ 	     state_out);
+   return;
+ }
+ 
+ static int ASCII_filter(c,st)
+      char c;
+      struct out_state * st;
+ {
+   int res = (unsigned char) c;
+   st++;
+ 
+   if (res & 128)
+     res = '_';
+   return res;
+ }
+ 
+ /* Prototype */
+ static int run_decoder P_((mime_t *, in_state_t *, out_state_t *)); 
+ 
+ static int run_decoder (ptr, state_in, state_out) 
+      mime_t *ptr;
+      in_state_t *state_in;
+      out_state_t *state_out;
+ {
+   int is_text;
+   dprint(12,(debugfile,
+ 	     "run_decoder -> state: offset=%d, length=%d\n",
+ 	     ptr -> offset, ptr -> length));
+ 
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"run_decoder",
+ 	       "Bad magic number");
+ 
+ 
+   if (in_state_seekable(state_in)) {
+     dprint(12,(debugfile,
+ 	       "              (file): ftell=%ld\n",in_state_ftell(state_in))); 
+   } else {
+     dprint(12,(debugfile,
+ 	       "              (\?\?\?\?): magic=%d\n",state_in->magic));
+   }
+ 
+   is_text = is_text_type (mime_types[ptr->type], ptr->subtype, 
+ 			  ptr->encoding);
+ 
+   dprint(12,(debugfile,
+ 	     "run_decoder: is_text=%d; type=%s (%d)/%s; encoding =%s (%d)\n",
+ 	     is_text, mime_types[ptr->type], ptr->type, ptr->subtype,
+ 	     ENCODING(ptr->encoding),
+ 	     ptr->encoding));
+ 
+ 
+   if (ptr->encoding == ENCODING_BASE64)
+     base64_decode (state_in, state_out, ptr->length, is_text);
+   else if (ptr->encoding == ENCODING_QUOTED)
+     quoted_printable_decode (state_in, state_out, ptr->length, is_text);
+   else if (ptr->encoding != ENCODING_NONE && 
+ 	   ptr->encoding != ENCODING_7BIT &&
+ 	   ptr->encoding != ENCODING_8BIT &&
+ 	   ptr->encoding != ENCODING_BINARY) {
+ 
+     dprint(12,(debugfile,
+ 	       "run_decoder=0 <- END; \n"));
+     if (in_state_seekable(state_in)) {
+       dprint(12,(debugfile,
+ 		 "              (file); ftell=%ld\n",
+ 		 in_state_ftell(state_in))); 
+     }
+     return 0;
+   }
+   else
+     Xbit_decode (state_in, state_out, ptr->length, is_text);
+ 
+   dprint(12,(debugfile,
+ 	     "run_decoder=1 <- END; \n"));
+   if (in_state_seekable(state_in)) {
+     dprint(12,(debugfile,
+ 	       "              (file); ftell=%ld\n",
+ 	       in_state_ftell(state_in))); 
+   }
+   
+   return 1;
+ }
+ 
+ int set_filter (ptr, state) 
+      mime_t *ptr;
+      out_state_t *state;
+ {
+   char tmp[SLEN];
+   char buf[STRING];
+   int code;
+ 
+   dprint(12,(debugfile,
+ 	     "set_filter -> state: offset=%d, length=%d\n",
+ 	     ptr -> offset, ptr -> length));
+ 
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"set_filter",
+ 	       "Bad magic number");
+ 
+   state -> filter = NULL_filter;
+ 
+   dprint(12,(debugfile,
+ 	     "set_filter: filter=%p (NULL_filter)\n",
+ 	     (void *)(state -> filter)));
+ 
+   if (0 == (code = mime_get_charset (tmp, ptr->type_opts, sizeof(tmp)))) {
+     
+     /* Don't show this part (or copy to reply buffer) ... */
+ 	  
+     elm_sfprintf (buf, sizeof buf,
+ 		  CATGETS(elm_msg_cat, MeSet, MeDecodeCharsetSkipping,
+ 			  "[Charset %.15s unsupported, skipping...]\n"), 
+ 		  tmp);
+     state_puts(buf,state);
+     if (state->displaying)
+       state_puts(catgets(elm_msg_cat, MeSet, MeDecodeUseVtoView,
+ 			 "[Use 'v' to view or save this part.]\n"),
+ 		 state);
+ 
+     dprint(12,(debugfile,
+ 	       "set_filter=0 <- END\n"));
+     return 0;
+   } else {
+     if (code < 0) {
+       elm_sfprintf (buf, sizeof buf,
+ 		    CATGETS(elm_msg_cat, MeSet, MeDecodeCharsetFiltering,
+ 			    "[Charset %.15s unsupported, filtering to ASCII...]\n"),
+ 		    tmp);
+       state_puts(buf,state);
+       if (state->displaying)	
+ 	state_puts(catgets(elm_msg_cat, MeSet, MeDecodeUseAlsoV,
+ 			   "[You can also use 'v' to view or save this part.]\n\n"),
+ 		   state);
+       
+       state -> filter = ASCII_filter;
+ 
+       dprint(12,(debugfile,
+ 		 "set_filter: filter=%p (ASCII_filter)\n",
+ 		 (void *)(state -> filter)));
+     }
+     dprint(12,(debugfile,
+ 	       "set_filter=1 <- END\n"));
+     return 1;
+   }
+ }
+ 
+ /* Prototype */
+ static void text_decode	P_((mime_t *, in_state_t *, out_state_t *)); 
+ 
+ static void text_decode (ptr, state_in, state_out) 
+      mime_t *ptr;
+      in_state_t *state_in;
+      out_state_t *state_out;
+ {
+   dprint(12,(debugfile,
+ 	     "text_decode -> state: offset=%d, length=%d \n",
+ 	     ptr -> offset, ptr -> length));
+ 
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"text_decode",
+ 	       "Bad magic number");
+ 
+   if (in_state_seekable(state_in)) {
+     dprint(12,(debugfile,
+ 	       "              (file): ftell=%ld\n",
+ 	       in_state_ftell(state_in))); 
+   }
+ 
+   if (set_filter(ptr,state_out)) {
+     if (!run_decoder(ptr,state_in, state_out)) {
+       state_puts(catgets(elm_msg_cat, MeSet, MeDecodeEncodingSkipping,
+ 			 "[Unsupported encoding, skipping...]\n"),
+ 		 state_out);
+       if (state_out->displaying)	
+ 	state_puts(catgets(elm_msg_cat, MeSet, MeDecodeUseVEncodedSave,
+ 			   "[Use 'v' to save this part in encoded form.]\n"),
+ 		   state_out);
+     }
+   }
+ 
+   state_out -> filter = NULL_filter;
+ 
+   dprint(12,(debugfile,
+ 	     "text_decode <- END; \n"));
+   if (in_state_seekable(state_in)) {
+     dprint(12,(debugfile,
+ 	       "          (file); ftell=%ld\n",
+ 	       in_state_ftell(state_in))); 
+   }
+ }
+ 
+ FILE * arrange_decoded(ptr,state_in,state_out,newstate2)
+      mime_t *ptr;
+      in_state_t  *state_in;
+      out_state_t *state_out;
+      in_state_t *newstate2;
+ {
+   FILE * tmpfp = NULL;
+   int result = 1,len;
+   char fname[STRING];
+   out_state_t newstate;
+ 
+   out_state_clear(&newstate,STATE_out_file);
+   
+   dprint(12,(debugfile,
+ 	     "arrange_decoded -> state: offset=%d, length=%d \n",
+ 	     ptr -> offset, ptr -> length));
+ 
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"arrange_decoded",
+ 	       "Bad magic number");
+ 
+   if (in_state_seekable(state_in)) {
+     dprint(12,(debugfile,
+ 	       "                 (file): ftell=%ld\n",
+ 	       in_state_ftell(state_in))); 
+   }
+   
+   elm_sfprintf (fname, sizeof fname,
+ 		FRM("%selmdecode.%d"), 
+ 		temp_dir, getpid ());
+   if (NULL == (tmpfp = safeopen_rdwr(fname))) {
+     lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeFailedCreate,
+ 		      "Failed to create file for decoding."));
+     state_putc('[',state_out);
+     state_puts(catgets(elm_msg_cat, MeSet, MeDecodeFailedCreate,
+ 		       "Failed to create file for decoding."),
+ 	       state_out);
+     state_puts("]\n",state_out);
+     sleep_message();
+     result = 0;
+   } else { /* Tempfile opened */
+     int crypted = OFF;
+     int bytes = 0;
+     unlink(fname);  /* We can unlink it now ... */
+     
+     newstate.displaying = state_out->displaying;
+     
+     set_out_state_file(tmpfp, &newstate);
+     newstate.prefix     = NULL;             /* No prefix in that pass */
+     newstate.filter     = state_out->filter;
+     
+     if (run_decoder(ptr,state_in,&newstate)) { 
+       int len;
+       
+       if (EOF == fflush(tmpfp)) {
+ 	lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeErrorFlush,
+ 			  "Error when flushing temporary file."));
+ 	state_putc('[',state_out);
+ 	state_puts(catgets(elm_msg_cat, MeSet, MeDecodeErrorFlush,
+ 			  "Error when flushing temporary file."),
+ 		   state_out);
+ 	state_puts("]\n",state_out);
+ 	sleep_message();
+ 	result = 0;
+       }
+       rewind(tmpfp); /* Rewind it for reading */
+       
+       set_in_state_file(tmpfp,newstate2);
+     } else { /* Run decoder failed */
+       state_puts(catgets(elm_msg_cat, MeSet, MeDecodeEncodingSkipping,
+ 			 "[Unsupported encoding, skipping...]\n"),
+ 		 state_out);
+       if (state_out->displaying)	
+ 	state_puts(catgets(elm_msg_cat, MeSet, MeDecodeUseVEncodedSave,
+ 			   "[Use 'v' to save this part in encoded form.]\n"),
+ 		   state_out);
+       result = 0;
+     }
+   }
+   out_state_destroy(&newstate);
+ 
+   dprint(12,(debugfile,"arrange_decoded; result=%d\n",result));
+   
+   if (!result && tmpfp) {
+     fclose(tmpfp);
+     tmpfp = NULL;
+   }
+   return tmpfp;
+ }
+ 
+ /* Prototype */
+ static void elm_decode	P_((mime_t *, in_state_t *, out_state_t *)); 
+ 
+ static void elm_decode (ptr, state_in, state_out) 
+      mime_t *ptr;
+      in_state_t  *state_in;
+      out_state_t *state_out;
+ {  
+   in_state_t newstate2;
+ 
+   FILE *tmpfp;
+   char buffer[LONG_STRING];
+   
+   in_state_clear(&newstate2,STATE_in_file);
+   
+   dprint(12,(debugfile,
+ 	     "elm_decode -> state: offset=%d, length=%d; \n",
+ 	     ptr -> offset, ptr -> length));
+ 
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"elm_decode",
+ 	       "Bad magic number");
+ 
+   if (in_state_seekable(state_in)) {
+     dprint(12,(debugfile,
+ 	       "             (file): ftell=%ld\n",
+ 	       in_state_ftell(state_in))); 
+   }
+ 
+   if (tmpfp = arrange_decoded(ptr,state_in,state_out,&newstate2)) {
+     if (set_filter(ptr,state_out)) {
+       int len, crypted = 0;
+       int count = 0;
+       getkey(OFF);
+       
+       while((len = state_getl(buffer,sizeof(buffer),&newstate2)) > 0) {
+ 	count += len;
+ 	  
+ 	if (!strncmp(buffer, START_ENCODE, strlen(START_ENCODE))) {
+ 	  state_puts(catgets(elm_msg_cat, MeSet, MeDecodeStartElmEncoded,
+ 			     "-- Start of (Elm) encoded section.\n"),
+ 		     state_out);
+ 	  crypted = ON;
+ 	  continue;
+ 	} else if (!strncmp(buffer, END_ENCODE, strlen(END_ENCODE))) {
+ 	  crypted = OFF;
+ 	  state_puts(catgets(elm_msg_cat, MeSet, MeDecodeEndElmEncoded,
+ 			     "-- End of (Elm) encoded section.\n"),
+ 		     state_out);
+ 	  continue;
+ 	} else if (crypted) {
+ 	  no_ret(buffer);
+ 	  encode(buffer);      
+ 	  strfcat(buffer, "\n", sizeof buffer);
+ 	}
+ 	state_add_prefix(state_out);
+ 	state_puts(buffer,state_out);
+       }
+ 
+       dprint(12,(debugfile,
+ 		 "elm_decode: Readed %d bytes from temp file\n",count));
+     }
+     fclose(tmpfp);
+   }
+ 
+   dprint(12,(debugfile,
+ 	     "elm_decode <- END; \n"));
+   if (in_state_seekable(state_in)) {
+     dprint(12,(debugfile,
+ 	       "           (file); ftell=%ld\n",
+ 	       in_state_ftell(state_in))); 
+   }
+ 
+   in_state_destroy(&newstate2);
+ }
+  /* Prototype */
+ static void text_unsupported_decode P_((mime_t *, 
+ 					in_state_t *, out_state_t *));
+ 
+ static void text_unsupported_decode (ptr, state_in, state_out) 
+      mime_t *ptr;
+      in_state_t *state_in;
+      out_state_t *state_out;
+ {
+   char buf[STRING];
+ 
+   dprint(12,(debugfile,
+ 	     "text_unsupported_decode -> state: offset=%d, length=%d; \n",
+ 	     ptr -> offset, ptr -> length));
+ 
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"text_unsupported_decode",
+ 	       "Bad magic number");
+ 
+   if (in_state_seekable(state_in)) {
+     dprint(12,(debugfile,
+ 	       "                          (file): ftell=%ld\n",
+ 	       in_state_ftell(state_in))); 
+   }
+ 
+   elm_sfprintf (buf, sizeof buf,
+ 		CATGETS(elm_msg_cat, MeSet, MeDecodeUnsupportedText,
+ 			"[%s/%.30s is unsupported, treating like TEXT/PLAIN]\n\n"), 
+ 		TYPE(ptr->type), ptr->subtype);
+   state_puts (buf,state_out);
+   text_decode (ptr, state_in, state_out);
+ 
+   dprint(12,(debugfile,
+ 	     "text_unsupported_decode <- END; \n"));
+   if (in_state_seekable(state_in)) {
+     dprint(12,(debugfile,
+ 	       "                        (file); ftell=%ld\n",
+ 	       in_state_ftell(state_in))); 
+   }
+ }
+ 
+ void null_decode (ptr, state_in, state_out) 
+      mime_t *ptr;
+      in_state_t *state_in;
+      out_state_t *state_out;
+ {
+   char buf[STRING];
+ 
+   dprint(12,(debugfile,
+ 	     "null_decode <-> state: offset=%d, length=%d; \n",
+ 	     ptr -> offset, ptr -> length));
+ 
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"null_decode",
+ 	       "Bad magic number");
+ 
+   if (in_state_seekable(state_in)) {
+     dprint(12,(debugfile,
+ 	       "               (file): ftell=%ld\n",
+ 	       in_state_ftell(state_in))); 
+   }
+ 
+   elm_sfprintf (buf, sizeof buf,
+ 		CATGETS(elm_msg_cat, MeSet, MeDecodeUnsupportedSkip,
+ 			"[%.15s/%.30s is not supported, skipping...]\n"),
+ 		TYPE(ptr->type),ptr->subtype);
+   state_puts (buf,state_out);
+   if (state_out->displaying)
+     state_puts(catgets(elm_msg_cat, MeSet, MeDecodeUseVtosave,
+ 		       "[Use 'v' to view or save this part.]\n"),
+ 	       state_out);
+ }
+ 
+ CT_decoder_t select_CT_decoder (ptr) 
+      mime_t *ptr;
+ {
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"select_CT_decoder",
+ 	       "Bad magic number");
+ 
+   if (ptr->type == MIME_TYPE_MULTIPART) {
+     if (ptr->flags & MIME_ALTERNATIVE) {
+       dprint(12,(debugfile,
+ 		 "select_CT_decoder [%s/%s] = alternative_decode\n",
+ 		 mime_types[ptr->type], ptr->subtype
+ 		 ));
+       return alternative_decode;
+     } else {
+       dprint(12,(debugfile,
+ 		 "select_CT_decoder [%s/%s] = multipart_0_decode\n",
+ 		 mime_types[ptr->type], ptr->subtype));
+       return multipart_0_decode;
+     }
+   }
+   else if (ptr->flags & MIME_RFC822) {
+     dprint(12,(debugfile,
+ 	       "select_CT_decoder [%s/%s] = rfc822_decode\n",
+ 	       mime_types[ptr->type], ptr->subtype));
+     return rfc822_decode;
+   }
+   else if (ptr->type == MIME_TYPE_MESSAGE &&
+ 	   (0 == istrcmp(ptr->subtype, "delivery-status") ||
+ 	    0 == strincmp(ptr->subtype,"X-delivery-status-",18))) {
+     dprint(12,(debugfile,
+ 	       "select_CT_decoder [%s/%s] = text_decode\n",
+ 	       mime_types[ptr->type], ptr->subtype));
+     return text_decode;
+   }
+   else if (ptr->type == MIME_TYPE_TEXT) {
+     if (0 == istrcmp(ptr->subtype, "rfc822-headers") ||
+ 	0 == istrcmp(ptr->subtype, "plain")) {
+       dprint(12,(debugfile,
+ 		 "select_CT_decoder [%s/%s] = text_decode\n",
+ 		 mime_types[ptr->type], ptr->subtype));
+       return text_decode;
+     }
+ #ifdef USE_PGP
+     if (0 == istrcmp(ptr->subtype, "x-pgp")) {
+       dprint(12,(debugfile,
+ 		 "select_CT_decoder [%s/%s] = pgp_decode\n",
+ 		 mime_types[ptr->type], ptr->subtype));
+       return pgp_decode;
+     }
+ #endif
+     dprint(12,(debugfile,
+ 	       "select_CT_decoder [%s/%s] = text_unsupported_decode\n",
+ 	       mime_types[ptr->type], ptr->subtype));
+     return text_unsupported_decode; /* For that type we try use
+ 				       metamail if available! */
+   }
+ #ifdef USE_PGP
+   else if (ptr->type == MIME_TYPE_APPLICATION &&
+ 	   (istrcmp(ptr->subtype, "pgp") == 0)) {
+     dprint(12,(debugfile,
+ 	       "select_CT_decoder [%s/%s] = pgp_decode\n",
+ 	       mime_types[ptr->type], ptr->subtype));
+     return pgp_decode;
+   }
+   else if (ptr->type == MIME_TYPE_APPLICATION &&
+ 	   (strincmp(ptr->subtype,"x-pgp",5) == 0)) {
+     dprint(12,(debugfile,
+ 	       "select_CT_decoder [%s/%s] = pgp_decode\n",
+ 	       mime_types[ptr->type], ptr->subtype));
+     return pgp_decode;
+   }
+ #endif
+   else if (ptr->type == MIME_TYPE_APPLICATION &&
+ 	   (istrcmp(ptr->subtype, "X-ELM-encode") == 0)) {
+     dprint(12,(debugfile,
+ 	       "select_CT_decoder [%s/%s] = elm_decode\n",
+ 	       mime_types[ptr->type], ptr->subtype));
+     return elm_decode;
+   }
+   
+   dprint(12,(debugfile,
+ 	     "select_CT_decoder [%s/%s] = null_decode\n",
+ 	     mime_types[ptr->type], ptr->subtype));
+   return null_decode;
+ }
+ 
+ 
+ void mime_decode (ptr, state_in, state_out)
+      mime_t *ptr;
+      in_state_t *state_in;
+      out_state_t *state_out;
+ {
+   /* This routine calls the appropriate routine to decode the data
+    * described in "ptr".
+    */
+ 
+   dprint(12,(debugfile,"mime_decode -> state: offset=%d, length=%d\n",
+ 	     ptr -> offset, ptr -> length));
+ 
+   if (ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"mime_decode",
+ 	       "Bad magic number");
+ 
+   if (!in_state_seekable(state_in)) {
+     lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeMimeUnsupportedIS,
+ 		      "mime_decode: unsupported input state"));
+     state_puts("\n[",state_out);
+     state_puts(catgets(elm_msg_cat, MeSet, MeDecodeMimeUnsupportedIS,
+ 		       "mime_decode: unsupported input state"), 
+ 	       state_out);
+     state_puts("]\n",state_out);
+     sleep_message();
+     return;
+   }
+ 
+   if (ptr->disposition == DISP_INLINE) {
+     CT_decoder_t decoder = select_CT_decoder(ptr);
+ 
+     dprint(12,(debugfile,"mime_decode: decoder=%p\n",decoder));
+ 
+     if (in_state_fseek(state_in,ptr->offset) != 0) {
+       state_putc('[',state_out);
+       state_puts(catgets(elm_msg_cat, MeSet, MeDecodeMimeSeekFailed,
+ 			"mime_decode: seek failed"),
+ 		 state_out);
+       state_puts("]\n",state_out);
+       lib_error(CATGETS(elm_msg_cat, MeSet, MeDecodeMimeSeekFailed,
+ 			"mime_decode: seek failed"));
+       sleep_message();
+       return;
+     }
+ 
+     decoder (ptr, state_in, state_out);    
+   }
+   else { 
+     if (state_out->displaying)      
+       state_puts(catgets(elm_msg_cat, MeSet, MeDecodeAttachUseV,
+ 			 "[Attachment, skipping...  Use 'v' to view this part.]\n"),
+ 		 state_out);
+     else
+       state_puts(catgets(elm_msg_cat, MeSet, MeDecodeAttachSkipping,
+ 			 "[Attachment, skipping...]\n"),
+ 		 state_out);
+   }
+ 
+   dprint(12,(debugfile,"mime_decode <- END\n"));
+ }
+ 
+ static int rfc1522_decode_word (ptr, state)
+      char *ptr;
+      out_state_t *state;
+ {
+   char *charset = NULL;
+   char *encoded = NULL;
+   char *buffer = NULL;
+   char *c;
+   int encoding = ENCODING_ILLEGAL;
+   int count;
+   int result = -1; /* Default to ERROR */
+  
+   count = 0;
+ 
+   /* Make a copy so the original is not destroyed */
+   c = buffer = strmcpy (buffer, ptr+2);
+ 
+   while ((c = strtok (c, "?")) != NULL) {
+     if (count == 0)
+       /* get the charset */
+       charset = c;
+     else if (count == 1) {
+       /* Check the encoding */
+       if (toupper (*c) == 'Q')
+ 	encoding = ENCODING_QUOTED;
+       else if (toupper (*c) == 'B')
+ 	encoding = ENCODING_BASE64;
+     }
+     else if (count == 2) 
+       encoded = c;
+     count++;
+     c = NULL;
+   }
+ 
+   if (charset && encoding != ENCODING_ILLEGAL && encoded) {
+     int code = class_charset(charset);
+     result = 0; /* OK */
+ 
+     dprint (14, (debugfile, 
+ 		"rfc1522_decode_word: OK: ptr=%s, code=%d\n",ptr,code));
+ 
+     if (code != 0) {
+       in_state_t state_in;
+ 
+       in_state_clear (&state_in, STATE_in_string);
+ 
+       state->filter = NULL_filter;
+ 
+       if (code < 0) {
+ 	dprint (14,(debugfile, 
+ 		   "rfc1522_decode_word: unsupported charset: %s -- filtering\n",
+ 		   charset));
+ 	state->filter = ASCII_filter;
+ 	state_puts("[",state);
+       }
+ 
+ 
+       if (encoding == ENCODING_QUOTED) { /* Hack */
+ 	char * ptr;
+ 	for (ptr = encoded; *ptr != '\0'; ptr++)
+ 	  if (*ptr == '_')
+ 	    *ptr = ' ';
+       }
+ 
+       set_in_state_buffer (encoded, &state_in);
+       
+       if (encoding == ENCODING_QUOTED)
+ 	quoted_printable_decode (&state_in, state, strlen (encoded), TRUE);
+       else if (encoding == ENCODING_BASE64)
+ 	base64_decode (&state_in,state, strlen (encoded), TRUE);
+       if (code < 0) 
+ 	state_puts("]",state);
+ 
+       state->filter = NULL_filter;
+ 
+       in_state_destroy(&state_in);
+     } else {
+       dprint (14, (debugfile, 
+ 		  "rfc1522_decode_word: unsupported charset: %s -- skipping\n",
+ 		  charset));
+       state_puts("[?",state);
+       state_puts(charset,state);
+       state_puts("?]",state); 
+     }
+   }
+ 
+   if (result == -1) {
+     
+     dprint (14, (debugfile, 
+ 		"rfc1522_decode_word: FAILED: ptr=%s\n",ptr));
+     dprint (14, (debugfile, 
+ 		"rfc1522_decode_word: -> charset=%s, encoding=%d, encoded=%s\n",
+ 		NONULL(charset),encoding,NONULL(encoded)));
+     
+   }
+   
+   free (buffer);
+   buffer = NULL;
+ 
+   return result;
+ }
+ 
+ static int decode_encoded_atom P_((char *trg,int trg_len,const char * src));
+ 
+ static int decode_encoded_atom (trg,trg_len,src) 
+   char *trg;
+   int trg_len; 
+   const char * src;
+ {
+   int len = strlen(src);
+   out_state_t state;
+   int is_encoded = 0;
+ 
+   out_state_clear (&state, STATE_out_string);
+   set_out_state_buffer(trg,trg_len,&state);
+ 
+   /* Check if current atom is valid encoded word */
+   if (len > 9 && src[0] == '=' && src[1] == '?' &&
+       src[len-1] == '=' && src[len-2] == '?') {
+     const char *ptr4;
+     int count = 0;
+     for (ptr4 = src; ptr4 - src < len; ptr4++)
+       if (*ptr4 == '?')
+ 	count++;
+     if (4 == count)
+       is_encoded = 1;
+   }
+ 
+   if (is_encoded) {
+     if (rfc1522_decode_word(src,&state) == -1)
+       is_encoded = 0;
+   }
+ 
+   out_state_destroy (&state);  
+ 
+   return is_encoded;
+ }
+ 
+ 
+ static int rfc1522_decode_real (p, state)
+      char *p;
+      out_state_t *state;
+ {
+   /* This routine decodes RFC1522 compliant headers */
+ 
+   char *buffer = strmcpy(NULL,p);
+   char *ptr = buffer;
+   unsigned char last_char = 0;
+   int result = 0;
+ 
+   while (ptr && *ptr) {
+     char *ptr2 = strpbrk(ptr," \t\r\n");
+     unsigned char last_char2 = 0;
+     int len;
+     int is_encoded = 0;
+ 
+     if (ptr2) {
+       last_char2 = *ptr2;
+       len = ptr2 - ptr;
+       *ptr2 = '\0';
+     } else {
+       len = strlen(ptr);
+     }
+ 
+     /* Check if current word is valid encoded word */
+     if (len > 9 && ptr[0] == '=' && ptr[1] == '?' &&
+ 	ptr[len-1] == '=' && ptr[len-2] == '?') {
+       char *ptr4;
+       int count = 0;
+       for (ptr4 = ptr; ptr4 - ptr < len; ptr4++)
+ 	if (*ptr4 == '?')
+ 	  count++;
+       if (4 == count)
+ 	is_encoded = 1;
+     }
+ 
+     dprint (14, (debugfile, 
+ 		"rfc1522_decode_real: word = %s, len=%d, is_encoded=%d\n",
+ 		ptr,len,is_encoded));
+ 
+     /* Space between encoded chars must delete! --
+      * This allows splitting more than 75 character long
+      * encoded words to two encoded word and using of
+      * continuation lines!
+      */
+     if (!is_encoded && last_char) {
+       state_putc (last_char, state);
+     }
+ 
+     if (is_encoded) {
+       if (-1 == rfc1522_decode_word(ptr,state)) {
+ 	dprint (14, (debugfile, 
+ 		    "rfc1522_decode_real: Error in rfc1522_decode_word ...\n"));
+ 	result = -1;
+ 	break;
+       }
+ 	
+     } else {
+       state_put(ptr,len,state);
+     }
+ 
+     if (!is_encoded && last_char2) {
+       state_putc (last_char2, state);
+       last_char2 = 0;
+     }
+ 
+     ptr = ptr2; /* Next word if any */
+     if (ptr)
+       ptr++;
+     last_char = last_char2;
+   }
+ 
+   free(buffer);
+   return 0;
+ }
+ 
+ int is_rfc1522 (s)
+      char *s;
+ {
+   /* Returns TRUE if the string contains RFC 1522 format encoded data */
+ 
+   while ((s = strchr (s, '=')) != NULL) {
+     s++;
+     if (*s == '?')
+       return TRUE;
+   }
+   return FALSE;
+ }
+ 
+ void rfc1522_decode (ptr, len)
+      char *ptr;
+      int len; /* size of "ptr" */
+ {
+   /* Support for RFC 1522, which allows for encoding of non-ASCII characters
+    * in RFC 822 headers.
+    */
+   char *tmp = safe_malloc (len);
+   out_state_t state;
+ 
+   /* Make a working copy of the header */
+   strfcpy (tmp, ptr, len);
+ 
+   /* The output from the decoding should be put back into the memory area
+    * which was passed into this routine.
+    */
+   out_state_clear (&state, STATE_out_string);
+   set_out_state_buffer(ptr,len,&state);
+   
+   if (rfc1522_decode_real (tmp, &state) == -1) {
+     /* An error occured.  Restore the original value. */    
+     
+     strfcpy (ptr, tmp, len);
+   }
+ 
+   out_state_destroy (&state);  
+ 
+   free (tmp);
+ }
+ 
+ char * blstrpbrk (string, set) 
+   char *string;
+   const char *set;
+ {
+   char *p;
+ 
+   for (p = string; *p; p++) 
+     if ('\\' == *p) {
+       p++;
+       if ('\0' == *p)
+ 	return NULL;
+     } else if (NULL != strchr(set,*p))
+       return p;
+   return NULL;
+ }
+ 
+ static void rfc1522_decode_comment P_((char *ptr,
+ 				       int size));
+ 
+ static void rfc1522_decode_comment (ptr, size)
+      char *ptr;
+      int size; /* size of "ptr" */
+ {
+   char *tmp = safe_strdup(ptr);
+   char *walk, *ptr2=ptr;
+   int len;
+   int skip_space = 0;
+   char add_space = '\0';
+   
+   dprint (22, (debugfile, 
+ 	       "rfc1522_decode_comment: ptr=\"%s\", size=%d\n",
+ 	       ptr,size));
+ 	  
+   size--;  /* place for \0 */
+   
+   for (walk=tmp; *walk && size > 0; walk += len) {
+     char *ptr1 = blstrpbrk(walk," \t\n()");  
+     char c;
+ 
+     if (NULL == ptr1)      len = strlen(walk);
+     else if (walk == ptr1) { 
+       len = 1;
+       
+       if (skip_space && NULL != strchr(" \t\n",*ptr1)) {
+ 	dprint (22, (debugfile, 
+ 		     "rfc1522_decode_comment: \"%c\" -> add space\n",
+ 		     *ptr1));
+ 	
+ 	add_space = ' ';
+       } else {
+ 	dprint (22, (debugfile, 
+ 		     "rfc1522_decode_comment: \"%c\" -> \"%c\"\n",
+ 		     *ptr1,*ptr1));
+ 	
+ 	skip_space = 0;
+ 	*ptr2++ = *ptr1;
+ 	size--;
+       }
+       continue;
+     } else {
+       len = ptr1 - walk;
+       c = *ptr1;
+       *ptr1 = '\0';
+ 
+       dprint (23, (debugfile, 
+ 		   "rfc1522_decode_comment: \"%s\", len=%d c=%c\n",
+ 		   walk,len,c));
+     }
+     
+     if (decode_encoded_atom(ptr2, size,walk)) {
+       int l = strlen(ptr2);
+       
+       dprint (22, (debugfile, 
+ 		   "rfc1522_decode_comment: \"%s\" -> \"%.*s\"\n",
+ 		   walk,l,ptr2));
+       
+       ptr2 += l;
+       size -= l;
+       add_space  = '\0';
+       skip_space = 1;
+     } else {
+       int l;
+       skip_space = 0;
+       if (add_space) {
+ 	dprint (22, (debugfile, 
+ 		     "rfc1522_decode_comment: add space -> \"%c\"\n",
+ 		     add_space));
+ 	
+ 	
+ 	*ptr2++ = add_space;
+ 	size--;
+ 	add_space  = '\0';
+ 	if (!size)
+ 	  break;
+       }
+       strfcpy(ptr2,walk,size);
+       l = strlen(ptr2);
+       
+       dprint (22, (debugfile, 
+ 		   "rfc1522_decode_comment: \"%s\" -> \"%.*s\"\n",
+ 		   walk,l,ptr2));
+       
+       ptr2 += l;
+       size -= l;
+     }
+     if (ptr1)
+       *ptr1 = c;
+   }
+   
+   free(tmp);
+   *ptr2 = '\0';
+   dprint (22, (debugfile, 
+ 	       "rfc1522_decode_comment = \"%s\"\n",
+ 	       ptr));
+   
+ }
+ 
+ void rfc1522_decode_structured (class, ptr, size)
+      int class;
+      char *ptr;
+      int size; /* size of "ptr" */
+ {
+   /* Decodes comments from structured fields 
+    * if class & HDR_PHRASE decodes also prases (or all words outside of < >)
+    *   -- not exactly correct for address lines, but otherwise we need full
+    *      STD 11 (RFC 822) parser ....
+    */
+   char *walk, *walk2;
+   char **tokenized;
+   char *was_space = NULL;
+   int skip_space;
+   int i;
+   int q = 0;
+ 
+   dprint (14, (debugfile, 
+ 	      "rfc1522_decode_structured -> class=%d,size=%d,ptr=%s\n",
+ 	      class,size,ptr));
+ 
+   switch(class) {
+   case HDR_COMMENT:
+     rfc1522_decode_comment(ptr,size);
+     return;
+   case HDR_TEXT:
+     rfc1522_decode(ptr,size);
+     return;
+   }
+ 
+   tokenized = rfc822_tokenize(ptr);
+   ptr[0] = '\0';   /* In place */
+ 
+   for (i = 0; tokenized[i]; i++) {
+     int copy = 1;
+     if ('<' == tokenized[i][0]) 
+       q++;
+     
+     if (!q && '(' != tokenized[i][0] && 0 != (class & HDR_PHRASE)) {
+       int maybe_addr = 0;
+       int j;
+       
+       for (j = i; tokenized[j]; j++) {
+ 	if ('@' == tokenized[j][0]) {
+ 	  maybe_addr = 1;
+ 	  break;
+ 	}
+ 	if (',' == tokenized[j][0] ||
+ 	    '<' == tokenized[j][0] ||
+ 	    ':' == tokenized[j][0])
+ 	  break;
+       }
+ 
+       if (!maybe_addr) {
+ 	if (whitespace(tokenized[i][0]) || '\n' == tokenized[i][0]) {
+ 	  if (skip_space) {
+ 	    was_space = tokenized[i];
+ 	    copy = 0;
+ 	  }
+ 	} else {
+ 	  char temp[STRING];
+ 	  if (decode_encoded_atom(temp, sizeof temp,tokenized[i])) {
+ 	    skip_space = 1;
+ 	    copy = 0;
+ 	    strfcat(ptr,temp,size);
+ 	    dprint (22, (debugfile, 
+ 			 "rfc1522_decode_structured: [%d]=\"%s\" \t=> \"%s\"\n",
+ 			 i, tokenized[i], temp));
+ 	  } else if (was_space) {
+ 	    strfcat(ptr,was_space,size);
+ 	    dprint (22, (debugfile, 
+ 			 "rfc1522_decode_structured: ADD SPACE \t=> \"%s\"\n",
+ 		   was_space));      	    
+ 	    was_space  = NULL;
+ 	    skip_space = 0;
+ 	  }
+ 	}
+       }
+     } else if (was_space) {
+       strfcat(ptr,was_space,size);
+       dprint (22, (debugfile, 
+ 		   "rfc1522_decode_structured: ADD SPACE \t=> \"%s\"\n",
+ 		   was_space));      
+       was_space  = NULL;
+       skip_space = 0;
+     }
+ 
+     if ('>' == tokenized[i][0]) 
+       q--;
+ 
+     if ('(' == tokenized[i][0]) {
+       char temp[STRING];
+       int l;
+       
+       strfcpy(temp,tokenized[i]+1,sizeof temp);
+       l = strlen(temp);
+       if (l > 0 && ')' == temp[l-1])
+ 	temp[l-1] = '\0';
+ 
+       rfc1522_decode_comment(temp,sizeof temp);
+ 
+       strfcat(ptr,"(",size);
+       strfcat(ptr,temp,size);
+       strfcat(ptr,")",size);
+       copy = 0;
+       dprint (22, (debugfile, 
+ 		   "rfc1522_decode_structured: [%d]=\"%s\" \t=> \"(%s)\"\n",
+ 		   i, tokenized[i], temp));
+     }
+ 
+     if (copy) {
+       strfcat(ptr,tokenized[i],size);
+       dprint (22, (debugfile, 
+ 		   "rfc1522_decode_structured: [%d]=\"%s\" \tCOPY\n",
+ 		   i, tokenized[i]));      
+     }
+   }
+ 
+   free_rfc822tokenized(tokenized);
+ 
+   dprint (14, (debugfile, "rfc1522_decode_structured <- ptr=%s\n",ptr));
+ }
+ 
+ static mime_t * best_alternative(att)     
+      mime_t *att;
+ {
+   mime_t *ret = att;
+   if (att->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"best_alternative",
+ 	       "Bad magic number");
+ 
+   while (att) {
+     if (!mime_notplain(att)) {
+ 	dprint(9,(debugfile,"-- best_alternative, found: %s/%s\n",
+ 		  mime_types[att->type], att->subtype));
+       ret = att;
+     }
+     att = att->next;
+   }
+ 
+   if (ret) {
+     dprint(9,(debugfile,"best_alternative - returns: %s/%s\n",
+ 	      mime_types[ret->type], ret->subtype));
+   } else {
+     dprint(9,(debugfile,"best_alternative=NULL"));
+   }
+ 
+   return ret;
+ }
+ 
+ static int can_handle P_((mime_t *att));
+ static int can_handle(att)     
+      mime_t *att;
+ {
+   if (att->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"can_handle",
+ 	       "Bad magic number");
+ 
+   while (att) {
+     if (att->magic != MIME_magic)
+       mime_panic(__FILE__,__LINE__,"can_handle",
+ 		 "Bad magic number (next -chain)");
+ 
+     if (att->disposition == DISP_INLINE) {      
+       if (mime_notplain(att)) {
+ 	dprint(9,(debugfile,"can_handle=NO -- Failed: %s/%s\n",
+ 		  mime_types[att->type], att->subtype));
+ 	return FALSE;
+       }
+       dprint(9,(debugfile,  "can_handle:     Succeed: %s/%s\n",
+ 		mime_types[att->type], att->subtype));
+     } else {
+       dprint(9,(debugfile,  "can_handle:  Attachment: %s/%s\n",
+ 		mime_types[att->type], att->subtype));
+     }
+     att = att->next;
+   }
+   dprint(9,(debugfile,"can_handle=TRUE\n"));
+   return TRUE;
+ }
+ 
+ int mime_notplain (p)
+      mime_t *p;
+ {
+   CT_decoder_t decoder = select_CT_decoder(p);
+   mime_t *z;
+   char buf[STRING];
+  
+   if (p->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"mime_not_plain",
+ 	       "Bad magic number");
+ 
+   if (p->encoding < ENCODING_NONE ||
+       p->encoding >= ENCODING_EXPERIMENTAL) {
+     dprint(9,(debugfile,
+ 	      "mime_notplain=TRUE -- type: %s/%s; encoding=%s (%d)\n",
+ 	      mime_types[p->type], p->subtype,
+ 	      ENCODING(p->encoding),p->encoding));
+     return TRUE;      
+   }
+ 
+   if (decoder == rfc822_decode && p->parts && can_handle(p->parts)) {
+     dprint(9,(debugfile,"mime_notplain=FALSE -- type: %s/%s\n",
+ 	      mime_types[p->type], p->subtype));
+     return FALSE;      
+   }
+   if (decoder == rfc822_decode) {
+     dprint(9,(debugfile,"mime_notplain=TRUE -- type: %s/%s\n",
+ 	      mime_types[p->type], p->subtype));
+     return TRUE;
+   }
+  
+   /* Notice: if (decoder == text_unsupported_decode)
+    *         we return TRUE, because we want call metamail
+    *         if it is available
+    */
+  
+   if (decoder == text_decode || decoder == elm_decode) {
+     /* If mime_get_charsets < 0, we want call metamail
+      * (instead of filtering to US-ASCII)
+      */
+     if (mime_get_charset(buf,p->type_opts,sizeof(buf)) > 0) {
+       dprint(9,(debugfile,"mime_notplain=FALSE -- type: %s/%s; charset=%s\n",
+ 		mime_types[p->type], p->subtype,buf));
+       return FALSE;
+     }
+   }
+   else if (decoder == multipart_0_decode &&
+ 	   ((p->flags & MIME_MIXED) || (p->flags & MIME_DIGEST)) &&
+ 	   p->parts && can_handle(p->parts)) {
+     dprint(9,(debugfile,"mime_notplain=FALSE -- type: %s/%s, flags=%d\n",
+ 	      mime_types[p->type], p->subtype, p->flags));
+     return FALSE;	   
+   }
+   else if (decoder == alternative_decode &&
+ 	   p->parts && ( z= best_alternative(p->parts)) && 
+ 	   (pagealternative ? !mime_notplain(z) : can_handle(p->parts))) {
+     dprint(9,(debugfile,"mime_notplain=FALSE -- type: %s/%s, "
+ 	      "best_alternative: %s/%s\n",
+ 	      mime_types[p->type], p->subtype, 
+ 	      mime_types[z->type], z->subtype));
+ 	   return FALSE;
+   }
+   else if (p->type == MIME_TYPE_MULTIPART && pagemultipart) {
+     dprint(9,(debugfile,"mime_notplain=TRUE -- type: %s/%s "
+ 	      "(pagemultipart=TRUE)\n",
+ 	      mime_types[p->type], p->subtype));
+     return FALSE;
+   }
+ #ifdef USE_PGP
+   else if (decoder == pgp_decode) {
+     dprint(9,(debugfile,"mime_notplain=FALSE -- type: %s/%s\n",
+ 	      mime_types[p->type], p->subtype));
+     return FALSE;
+   }
+ #endif
+   dprint(9,(debugfile,"mime_notplain=TRUE -- type: %s/%s\n",
+ 	    mime_types[p->type], p->subtype));
+   return TRUE;
+ }
+ 
+ #endif /* MIME */
Index: elm2.4.ME+.50/melib/mime_parse.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/melib/mime_parse.c	Tue Nov 17 21:12:56 1998
***************
*** 0 ****
--- 1,1066 ----
+ static char rcsid[] = "@(#)$Id: mime_parse.c,v 1.2 1998/10/20 19:58:08 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *
+  *  Initially written by: Michael Elkins <elkins@aero.org>, 1995
+  *****************************************************************************/
+ 
+ #include "headers.h"
+ #include "melib.h"
+ 
+ #ifdef MIME
+ /* As ordered in mime.h */
+ char *mime_types[] = {
+ 	"*unknown*",
+ 	"application",
+ 	"audio",
+ 	"image",
+ 	"message",
+ 	"multipart",
+ 	"text",
+ 	"video",
+ 	/* Non standard main types */
+ 	"x-world",        /* x-word/x-vmrl */
+ 	"model",          /* draft-nelson-model-mail-ext-02.txt */
+         NULL
+ };
+ 
+ int
+ mime_needs_processing (p)
+      mime_t *p;
+ {
+   /* A routing which metapager() calls to determine if the message specified
+    * by "p" to determine whether or not any special MIME processing needs
+    * to be performed.  This information is used to decide if a temp file
+    * needs to be used in order to effect backwards paging, or if we can page
+    * directly out of the mailbox file.
+    */
+ 
+   if (p->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"mime_needs_processing",
+ 	       "Bad magic number");
+ 
+   if (p->disposition != DISP_INLINE)
+     return TRUE;
+ 
+   if (p->encoding != ENCODING_7BIT && p->encoding != ENCODING_8BIT)
+     return TRUE;
+ 
+   if (p->type != MIME_TYPE_TEXT)
+     return TRUE;
+ 
+   /* This is to support those poor unfortunate folk who don't have true
+    * MIME support.  Often, you see "Content-Type: text".  We'll just
+    * assume that it's normal text.
+    */
+   if (p->subtype[0] == '\0')
+     return FALSE;
+ 
+   if (istrcmp (p->subtype, "plain") != 0)
+     return TRUE;
+ 
+   return FALSE;
+ }
+ 
+ char *
+ mime_parse_content_opts (str)
+      char *str;
+ {
+   /* A routine for parsing the options in a Content-Type: field.  The
+    * important point here is to skip the semi-colon if it appears
+    * inside of quotes.  This works sort of like strtok, except that
+    * the token is already known.
+    */
+   static char *ptr;
+   char *ret;
+   int in_quote = 0;
+ 
+   /* This is the initialization call */
+   if (str)
+     ptr = str;
+   
+   if (*ptr == '\0')
+     return NULL;
+ 
+   ret = ptr;
+   while (*ptr) {
+     if (*ptr == '\\' && in_quote) {		  
+       /* \ escapes next character  
+        * (not allowed outside of quotes) */
+       ptr++;
+       if (*ptr == '\0')
+ 	break;
+     } else if (*ptr == '\"') {
+       if (in_quote)
+ 	in_quote = 0;
+       else
+ 	in_quote = 1;
+     }
+     else if (! in_quote) {
+       if (*ptr == ';') {
+ 	*ptr++ = '\0';
+ 	/* skip leading spaces */
+ 	while (*ptr && isspace ((unsigned char)*ptr))
+ 	  ptr++;
+ 	return (ret);
+       }
+     } 
+     ptr++;
+   }
+   return (ret);
+ }
+ 
+ void
+ mime_destroy (ptr)
+      mime_t *ptr;
+ {
+   mime_t *tmp;
+ 
+   dprint(20,(debugfile,"mime_destroy(%p) --> BEGIN\n",ptr));
+ 
+   if (ptr && ptr->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"mime_destroy",
+ 	       "Bad magic number");
+ 
+   while (ptr) {
+     tmp = ptr;
+     ptr = ptr->next;
+ 
+     if (tmp->magic != MIME_magic)
+       mime_panic(__FILE__,__LINE__,"mime_destroy",
+ 		 "Bad magic number (next -chain)");
+ 
+     if (tmp->description)
+       free (tmp->description);
+     if (tmp->type_opts)
+       free (tmp->type_opts);
+     if (tmp->disposition_opts)
+       free (tmp->disposition_opts);
+ 
+     if (tmp->parts)
+       mime_destroy (tmp->parts);
+ 
+     if (tmp->unlink)
+       unlink (tmp->pathname);
+ 
+     tmp -> magic = 0;
+ 
+     free (tmp);
+   }
+   dprint(20,(debugfile,"mime_destroy(...) <-- END\n"));
+   return;
+ }
+ 
+ void
+ mime_t_clear (mt)
+      mime_t *mt;
+ {
+   dprint(20,(debugfile,"mime_t_clear(%p) --> BEGIN\n",mt));
+ 
+   if (mt->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"mime_t_clear",
+ 	       "Bad magic number");
+ 
+   mt->flags = mt->offset = mt->begin_offset = 0;
+   mt->length = -1;
+   mt->encoding = ENCODING_7BIT;
+   mt->unlink = 0;
+   mt->type = MIME_TYPE_TEXT;
+   mt->disposition = DISP_INLINE;
+   mt->notplain = 0;
+ 
+   if (mt->parts)
+     mime_destroy (mt->parts);
+   if (mt->next)
+     mime_destroy (mt->next);
+ 
+   mt->next = mt->prev = mt->parts = NULL;
+ 
+   if (mt->description)
+     free (mt->description);
+   mt->description = NULL;
+   if (mt->type_opts)
+     free (mt->type_opts);
+   mt->type_opts = NULL;
+   if (mt->disposition_opts)
+     free (mt->disposition_opts);
+   mt->disposition_opts = NULL;
+   if (mt->pathname)
+     free (mt->pathname);
+   mt->pathname = NULL;
+ 
+   strfcpy (mt->subtype, "plain", sizeof mt->subtype);
+ 
+   dprint(20,(debugfile,"mime_t_clear(%p) <-- END\n",mt));
+   return;
+ }
+ 
+ void
+ mime_get_disposition (str, mt)
+      char *str;
+      mime_t *mt;
+ {
+   char *c, tmp[VERY_LONG_STRING];
+ 
+   dprint (9, (debugfile, "mime_get_disposition(): str=\"%s\"\n", str));
+   
+   if (mt->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"mime_get_disposition",
+ 	       "Bad magic number");
+ 
+   /* Don't harm "str" */
+   strfcpy (tmp, str, sizeof(tmp));
+   
+   rfc822_reap_comments (tmp, NULL, 0);
+   
+   /* Look for the options field */
+   if ((c = strchr (tmp, ';')) != NULL) {
+     char *d = c;
+     while (d > tmp && whitespace(*(d-1)))
+       d--;
+     *d = '\0';
+     c++;
+     while (*c && whitespace(*c))
+       c++;
+     mt->disposition_opts = strmcpy (mt->disposition_opts, c);
+   }
+   else {
+     char *d = tmp + strlen(tmp);
+     while (d > tmp && whitespace(*(d-1)))
+       d--;
+     *d = '\0';
+     if (mt->disposition_opts) {
+       free (mt->disposition_opts);
+       mt->disposition_opts = NULL;
+     }
+   }
+   
+   /* All that's left now is the main disposition */
+   c = tmp;
+   while (*c && whitespace(*c))
+     c++;
+   /* No Content-Disposition -header     -> DISP_INLINE
+    *    Content-Disposition: inline     -> DISP_INLINE
+    *    Content-Disposition: attachment -> DISP_ATTACH
+    *    Content-Disposition: {unknown}  -> DISP_ATTACH
+    * See RFC 1806 (Experimental protocol) for details.
+    */   
+   if (istrcmp (c, "inline") != 0)
+     mt->disposition = DISP_ATTACH;
+   else
+     mt->disposition = DISP_INLINE;
+      
+   dprint (9, (debugfile,
+ 	     "mime_get_disposition(): disposition=\"%s\", disposition_opts=\"%s\"\n",
+ 	     DISPOSITION(mt->disposition), NONULL(mt->disposition_opts)));
+ }
+ 
+ int
+ mime_check_type (str)
+ 	char *str;
+ {
+   int i;
+   for (i = 0; mime_types[i] != NULL; i++) {
+     if (istrcmp(str,mime_types[i]) == 0)
+       return i;
+   }
+   return MIME_TYPE_UNKNOWN;
+ }
+ 
+ void
+ mime_get_content (str, mt)
+      char *str;
+      mime_t *mt;
+ {
+   char *c, tmp[VERY_LONG_STRING];
+ 
+   dprint (9, (debugfile, "mime_get_content(): str=\"%s\"\n", str));
+ 
+   if (mt->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"mime_get_content",
+ 	       "Bad magic number");
+ 
+   /* Don't harm "str" */
+   strfcpy (tmp, str, sizeof(tmp));
+ 
+   rfc822_reap_comments (tmp, NULL, 0);
+ 
+   /* Look for the options field */
+   if ((c = strchr (tmp, ';')) != NULL) {
+     char *d = c;
+     while (d > tmp && whitespace(*(d-1)))
+       d--;
+     *d = '\0';
+     c++;
+     while (*c && whitespace(*c))
+       c++;
+     mt->type_opts = strmcpy (mt->type_opts, c);
+   }
+   else {
+     char *d = tmp + strlen(tmp);
+     while (d > tmp && whitespace(*(d-1)))
+       d--;
+     *d = '\0';
+     if (mt->type_opts) {
+       free (mt->type_opts);
+       mt->type_opts = NULL;
+     }
+   }
+   
+   mt->subtype[0] = '\0';
+   /* Get the subtype */
+   if ((c = strchr (tmp, '/')) != NULL) {
+     char *d = c;
+     while (d > tmp && whitespace(*(d-1)))
+       d--;
+     *d = '\0';
+ 
+     c++;
+     while (*c && whitespace(*c))
+       c++;
+     strfcpy (mt->subtype, c, sizeof(mt->subtype));
+   }
+   
+   /* All that's left now is the main type */
+   c = tmp;
+   while (*c && whitespace(*c))
+     c++;
+   mt->type = mime_check_type (c);
+ 
+   /* Mark MESSAGE/RFC822 so we can do special handling later */
+   if (mt->type == MIME_TYPE_MESSAGE && istrcmp (mt->subtype, "rfc822") == 0)
+     mt->flags |= MIME_RFC822;
+   else if (mt->type == MIME_TYPE_MULTIPART) {
+     if (istrcmp (mt->subtype, "mixed") == 0)
+       mt->flags |= MIME_MIXED;
+     if (istrcmp (mt->subtype, "report") == 0)
+       mt->flags |= MIME_MIXED;
+     else if (istrcmp (mt->subtype, "digest") == 0)
+       mt->flags |= MIME_DIGEST;
+     else if (istrcmp (mt->subtype, "alternative") == 0)
+       mt->flags |= MIME_ALTERNATIVE;
+   }
+ 
+   dprint (9,(debugfile,
+ 	     "mime_get_content(): type=\"%s\", subtype=\"%s\", opts=\"%s\"\n",
+ 	     mime_types[mt->type], mt->subtype, NONULL(mt->type_opts)));
+ 
+   return;
+ }
+ 
+ int
+ mime_get_param (name, value, opts, size)
+      char *name, *opts, *value;
+      int size;
+ {
+   char *c, tmp[VERY_LONG_STRING];
+   int i = 0, quoted = FALSE, found = FALSE;
+ 
+   value[0] = '\0';
+ 
+   if (!opts) {
+     dprint(11, (debugfile,"mime_get_param: name=\"%s\", opts=NULL\n",name));
+     return 0;
+   }
+ 
+   dprint(11, (debugfile,"mime_get_param: name=\"%s\", opts=\"%s\"\n",
+ 	      name,opts));
+ 
+   /* Make sure not to harm opts */
+   strfcpy (tmp, opts, sizeof (tmp));
+   rfc822_reap_comments (tmp, NULL, 0);
+ 
+   c = tmp;
+   while ((c = mime_parse_content_opts (c)) != NULL && !found) {
+     char * d  = strchr(c,'=');
+     char * d2 = d;
+     if (!d) {
+       c = NULL;
+       continue;    /* bad paramater */
+     }
+     while (d2 > c && (whitespace (*(d2-1))))
+       d2--;
+     *d2 = '\0';
+     
+     while (*c && whitespace(*c))
+       c++;
+     
+     if (istrcmp (c, name) == 0) {
+       found = TRUE;
+       
+       c = d+1;
+       while (*c && whitespace(*c))
+ 	c++;
+       if (*c == '"') {
+ 	c++;
+         quoted = TRUE;
+       }
+       /* Either look for a trailing quoted (if quoted==TRUE) or a SPACE */
+       while (*c && ((quoted && *c != '"') || (!quoted && *c != ' '))) {
+ 	if (*c == '\\' && quoted) {
+ 	  /* \ escapes next character */
+ 	  c++;
+ 	  if (!*c)
+ 	    break;
+ 	}
+ 	if (i >= size-1)
+ 	  break;    /* Avoid buffer overflow */
+ 	value[i++] = *c++;
+       }
+       value[i] = '\0';
+       break;
+     }
+     c = NULL;
+   }
+ 
+   dprint(11,(debugfile,"mime_get_param: found=%d, value=%s\n",found,value));
+ 
+   return found;
+ }
+ 
+ void mime_get_boundary (boundary, opts, size)
+      char *opts, *boundary;
+      int size;
+ {
+   if (!mime_get_param ("boundary", boundary, opts, size)) {
+     error ("'boundary' paramater is missing from Multipart -type!");
+     sleep_message();
+   }
+ 
+   return;
+ }
+ 
+ int class_charset(charset_value) 
+   char * charset_value;
+ {
+  /* Returns 1 if charset is displayable with charset of text
+   *     (suitable for replying)
+   * Return 2 if charset is displayable with display_charset
+   *           (when replying charset should be changed to display_charset)
+   * Return -1 if need to filter to US-ASCII
+   */
+   int ret = 0;
+ 
+   /* Check agaist charset of text */
+   if (0 == istrcmp(charset_value,"US-ASCII") && charset_ok(charset))
+     ret = 1; /* If charset of text can show us-ascii? */
+   else if (0 == istrcmp(charset_value,charset))
+     ret = 1;
+   /* Check agaist display charset */
+   else if (0 == istrcmp(charset_value,"US-ASCII") && 
+ 	   charset_ok(display_charset))
+     ret = 2; /* If display_charset can show us-ascii? */
+   else if (0 == istrcmp(charset_value,display_charset))
+     ret = 2;
+   else if (0 == istrcmp(display_charset,"US-ASCII") && 
+ 	   charset_ok(charset_value))
+     ret = -1;
+   else if (charset_ok(display_charset) && 
+ 	   charset_ok(charset_value))
+     ret = -1;
+ 
+   dprint(9,(debugfile,"class_charset: charset_value=\"%s\"\n",
+ 	    charset_value));
+   dprint(9,(debugfile,
+ 	    "             : (text)charset=\"%s\",display_charset=\"%s\"\n",
+ 	    charset,display_charset));
+   dprint(9,(debugfile,"class_charset=%d\n",ret));
+ 
+   return ret;
+ }
+ 
+ /* There should better handling in metapager (I have one idea)
+  * Perhaps in next version ...    -K E H    <hurtta@dionysos.fmi.fi>
+  */
+ int 
+ mime_get_charset (charset_value, opts, size)
+      char *opts, *charset_value;
+      int size;
+ {  /* Returns 1 if charset is displayable with charset of text
+     *     (suitable for replying)
+     * Return 2 if cahrset is displayable with display_charset
+     *           (when replying charset should be changed to display_charset)
+     * Return -1 if need to filter to US-ASCII
+     */
+   int ret = 0;
+ 
+   if (!mime_get_param("charset",charset_value,opts,size)) 
+     strfcpy(charset_value,"US-ASCII", size); 
+     /* Default charset if nothing specified */
+ 
+   if (!opts) {
+     dprint(9,(debugfile,"mime_get_charset: opts=NULL\n",opts));
+   } else {
+     dprint(9,(debugfile,"mime_get_charset: opts=\"%s\"\n",opts));
+   }
+   dprint(9,(debugfile,"                : charset_value=\"%s\"\n",
+ 	    charset_value));
+ 
+   ret = class_charset(charset_value);
+ 
+   dprint(9,(debugfile,"mime_get_charset=%d\n",ret));
+ 
+   return ret;
+ }
+ 
+ void
+ mime_t_zero (ptr)
+      mime_t *ptr;
+ {
+   /* This routine should be called whenever a new "mime_t" is created.  It
+    * makes sure that the pointers inside are correctly initialized to NULL
+    * so that we don't end up calling free() on an uninitialized pointer.
+    */
+   dprint(20,(debugfile,"mime_t_zero(%p)\n",ptr));
+ 
+   ptr->next = ptr->parts = NULL;
+   ptr->description = ptr->type_opts = ptr->disposition_opts = 
+     ptr->pathname = NULL;
+   ptr->magic = MIME_magic;
+ }
+ 
+ void mime_t_copy(trg, src)
+      mime_t *trg, *src;
+ {
+   /* This routines make copy of mime_t structure ... */
+ 
+   dprint(20,(debugfile,"mime_t_copy(%p,%p) --> BEGIN\n",trg,src));
+   
+   if (trg->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"mime_t_copy",
+ 	       "Bad magic number (trg)");
+ 
+   if (src->magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"mime_t_copy",
+ 	       "Bad magic number (src)");
+ 
+   mime_t_clear(trg);
+ 
+   trg->flags  =            src->flags;
+   trg->offset =            src->offset; 
+   trg->begin_offset  =     src->begin_offset; 
+   trg->length =            src->length;
+   trg->encoding =          src->encoding;
+   trg->unlink = 0; /* Don't unlink ! */
+   trg->type =              src->type;
+   trg->disposition =       src->disposition;
+   trg->notplain =          src->notplain;
+ 
+   if (src->parts) {
+     trg->parts = mime_t_alloc();
+     mime_t_copy(trg->parts,src->parts);
+   }
+ 
+   if (src->next) {
+     trg->next = mime_t_alloc();
+     mime_t_copy(trg->next,src->next);
+   }
+ 
+   if (src->description) {
+     trg->description = strmcpy(trg->description, src->description);
+   }
+ 
+   if (src->type_opts) {
+     trg->type_opts = strmcpy(trg->type_opts, src->type_opts);
+   }
+ 
+   if (src->disposition_opts) {
+     trg->disposition_opts = strmcpy(trg->disposition_opts, 
+ 				    src->disposition_opts);
+   }
+ 
+   strfcpy(trg->subtype,src->subtype, sizeof trg->subtype);
+ 
+   dprint(20,(debugfile,"mime_t_copy(%p,%p) <-- END\n",trg,src));
+ }
+ 
+ mime_t *
+ mime_t_alloc ()
+ {
+   mime_t *ptr;
+ 
+   dprint(20,(debugfile,"mime_t_alloc()     --> BEGIN\n"));
+ 
+   ptr = (mime_t *) safe_malloc (sizeof (mime_t));
+   /* Make sure to clear the pointers initially so that later we know when
+    * to reclaim memory in mime_t_clear().
+    */
+   mime_t_zero (ptr);
+   mime_t_clear (ptr);
+ 
+   dprint(20,(debugfile,"mime_t_alloc() = %p <-- END\n",ptr));
+   return ptr;
+ }
+ 
+ mime_t *
+ parse_mime_headers(header_list_ptr headers,
+ 		   long part_offset,
+ 		   long body_offset,
+ 		   int opts)
+ {
+   mime_t *ptr;
+   header_list_ptr this_header;
+ 
+   dprint(9,(debugfile, 
+ 	    "parse_mime_headers(): part_offset=%ld, body_offset=%ld, opts=%d\n",
+ 	    part_offset,body_offset,opts));
+ 
+   ptr = mime_t_alloc ();
+ 
+   /* set some defaults */
+   ptr->encoding = ENCODING_7BIT;
+   if (opts & MIME_DIGEST) {
+     ptr->type = MIME_TYPE_MESSAGE;
+     strfcpy (ptr->subtype, "rfc822", sizeof ptr->subtype);
+   }
+   else {
+     ptr->type = MIME_TYPE_TEXT;
+     strfcpy (ptr->subtype, "plain", sizeof ptr->subtype);
+   }
+   ptr->disposition = DISP_INLINE;
+   ptr->description = NULL;
+ 
+   ptr->begin_offset = part_offset;
+   ptr->offset       = body_offset;
+   ptr->length = -1;
+ 
+   if (NULL != (this_header = 
+ 	       locate_header_by_name(headers,"Content-Type")) &&
+       NULL != this_header->body) {
+     mime_get_content (this_header->body, ptr);
+     if (this_header->next_this_header) {
+       error("PARSE ERROR: Several Content-Type headers!");
+       sleep_message();
+     }
+   } else {
+     dprint (9,(debugfile,"parse_mime_headers: No Content-Type -header\n"));
+   }
+ 
+   if (NULL != (this_header = 
+ 	       locate_header_by_name(headers,"Content-Disposition")) &&
+       NULL != this_header->body) {
+     mime_get_disposition (this_header->body, ptr);
+     if (this_header->next_this_header) {
+       error("PARSE ERROR: Several Content-Disposition headers!");
+       sleep_message();
+     }
+   } else {
+     dprint (9,(debugfile,
+ 	       "parse_mime_headers: No Content-Disposition -header\n"));
+   }
+ 
+   if (NULL != (this_header = 
+ 	       locate_header_by_name(headers,"Content-Transfer-Encoding")) &&
+       NULL != this_header->body) {
+     char  * value = this_header->body, *c;
+ 
+     /* This removes comments from buffer this_header->body */
+ 
+     rfc822_reap_comments (value, NULL, 0);
+     c = value;
+     while (*c && isspace((unsigned char) *c))
+ 	c++;
+     ptr->encoding = check_encoding (c);
+ 
+     if (this_header->next_this_header) {
+       error("PARSE ERROR: Several Content-Transfer-Encoding headers!");
+       sleep_message();
+     }
+   } else {
+     dprint (9,(debugfile,
+ 	       "parse_mime_headers: No Content-Transfer-Encoding -header\n"));
+   }
+ 
+   if (NULL != (this_header = 
+ 	       locate_header_by_name(headers,"Content-Description"))  &&
+       NULL != this_header->body) {
+     char value [32 * 1024 +1], *c;
+     strfcpy(value,this_header->body, sizeof value);
+       
+     /* Content-description is unstructured text header */
+     if (is_rfc1522(value))
+       rfc1522_decode(value,sizeof(value));
+ 
+     c = value;
+     while (*c && whitespace(*c))
+       c++;
+     ptr->description = NULL;
+     ptr->description = strmcpy (ptr->description, c);
+ 
+     if (this_header->next_this_header) {
+       error("PARSE ERROR: Several Content-Description headers!");
+       sleep_message();
+     }
+   } else {
+     dprint (9,(debugfile,
+ 	       "parse_mime_headers: No Content-Description -header\n"));
+   }
+ 
+   /* mime_get_content don't set this if this is set as defualt value
+    * because of MIME_DIGEST -flag (in opt)
+    */
+   if (ptr->type == MIME_TYPE_MESSAGE && 
+       istrcmp (ptr->subtype, "rfc822") == 0)
+     ptr->flags |= MIME_RFC822;
+ 
+   dprint(12,(debugfile, 
+ 	     "parse_mime_headers- type=%s/%s; flags=%d;\n",
+ 	     mime_types[ptr->type], ptr->subtype, ptr->flags));
+   dprint(12,(debugfile, 
+ 	     "parse_mime_headers- begin=%ld, offset=%ld, length=%ld\n",
+ 	     ptr->begin_offset,ptr->offset,ptr->length));
+   dprint(9,(debugfile, "parse_mime_headers=%p <-- END\n",(void *)ptr));
+ 
+   return ptr;
+ }
+ 
+ mime_t *
+ mime_read_header (fp, opts)
+      FILE *fp;
+      int opts;
+ {
+   mime_t *ptr;
+   header_list_ptr headers = NULL;
+   long part_offset;
+   long body_offset;
+ 
+ 
+   dprint(9,(debugfile, "mime_read_header: opts=%d --> START\n",opts));
+ 
+   part_offset = ftell (fp);
+   headers = file_read_headers(fp,0);
+   body_offset = ftell(fp);
+ 
+   ptr = parse_mime_headers(headers,part_offset,body_offset,opts);
+ 
+   delete_headers(headers);
+ 
+   return ptr;
+ }
+ 
+ mime_t * multipart_parse (fp, length, boundary, opts)
+      FILE *fp;
+      int length, opts;
+      char *boundary;
+ {
+   int blen, len,last_pos;
+   long end_offset;
+   char buf[VERY_LONG_STRING], subbound[STRING];
+   mime_t *ptr = NULL, *tmp, *ret = NULL;
+ 
+   dprint(9,(debugfile,"multipart_parse --> length=%d, boundary=%s\n",
+ 	    length, boundary));
+ 
+   blen = strlen (boundary);
+   end_offset = ftell (fp) + length;
+   last_pos = ftell(fp);
+ 
+   while (ftell (fp) < end_offset) {
+     if ((len = mail_gets (buf, VERY_LONG_STRING, fp)) == 0)
+       break;
+ 
+     if (buf[0] == '-' && buf[1] == '-' &&
+         strncmp (buf + 2, boundary, blen) == 0) {
+ 
+       /* Save the length of the previous part */
+       if (ptr) {
+         ptr->length = last_pos - ptr->offset;
+ 	dprint(9,(debugfile,"multipart_parse: fixing length=%d\n",
+ 		  ptr->length));
+       }
+       /* Check for the end boundary. */
+       if (buf[blen+2] == '-' && buf[blen+3] == '-')
+         break;
+       
+       tmp = mime_read_header (fp, opts);
+ 
+       dprint(9,(debugfile,"multipart_parse: (reading) content-type=%s/%s; flags=%d\n",
+ 		mime_types[tmp->type], tmp->subtype, tmp->flags));
+ 
+       
+       if (ret == NULL)
+         ptr = ret = tmp;
+       else {
+         ptr->next = tmp;
+         ptr = ptr->next;
+       }
+ #if 0
+       if (ptr->length >= 0) {
+ 	/* If the length of this part is known, skip ahead to the next
+ 	 * part.  If the length is not known, we don't have to worry
+ 	 * about it because the algorithm will search for the next
+ 	 * boundary...
+ 	 */
+         fseek (fp, (long) (ptr->length), SEEK_CUR);
+ 	continue;
+       }
+ #endif
+     }
+     if (ptr && ptr->length < 0) { /* mark position before CR LF */
+       int pos = ftell(fp);
+       if (len > 1 && buf[len-2] == '\r' && buf[len-1] == '\n')
+ 	last_pos = pos -2;
+       else if (len > 0 && buf[len-1] == '\n')
+ 	last_pos = pos -1;
+     }
+   }
+ 
+   if (ptr && ptr->length != last_pos - ptr->offset) {
+     ptr->length = last_pos - ptr->offset;
+     dprint(9,(debugfile,"multipart_parse: fixing length=%d (corrupted?)\n",
+ 	      ptr->length));
+ 
+     error ("Seems that multipart structure was corrupted.");
+     sleep_message();
+   }
+ 
+   /* Now that we know what this message consists of, see if any of the
+    * parts contain data that needs to be parsed. */
+ 
+   for (tmp = ret; tmp != NULL; tmp = tmp->next) {
+ 
+     if (tmp->magic != MIME_magic)
+       mime_panic(__FILE__,__LINE__,"multipart_parse",
+ 		 "Bad magic number (next -chain)");
+ 
+     dprint(9,(debugfile,"multipart_parse: (parsing) content-type=%s/%s; flags=%d\n",
+ 	      mime_types[tmp->type],tmp->subtype,tmp->flags));
+ 
+     if (tmp->flags & MIME_RFC822) {
+       dprint(9,(debugfile,"multipart_parse- (parsing) RFC822\n"));
+       fseek (fp, tmp->offset, SEEK_SET);
+       tmp->parts = rfc822_parse (fp, tmp->length);
+     }
+     else if (tmp->type == MIME_TYPE_MULTIPART) {
+       fseek (fp, tmp->offset, SEEK_SET);
+       mime_get_boundary (subbound, tmp->type_opts, sizeof (subbound));
+       dprint(9,(debugfile,
+ 		"multipart_parse- (parsing) MULTIPART; boundary=%s\n",
+ 		subbound));
+       tmp->parts = multipart_parse (fp, tmp->length, subbound, tmp->flags);
+     }
+   }
+ 
+   /* Make sure to leave the stream at the end of the data since the
+    * calling function might be assuming this.  */
+   fseek (fp, end_offset, SEEK_SET);
+ 
+   dprint(9,(debugfile,"multipart_parse <-- DONE\n"));
+ 
+   return ret;
+ }
+ 
+ mime_t *
+ rfc822_parse (fp, len)
+      FILE *fp;
+      int len;
+ {
+   /* Called to read MESSAGE/RFC822 data.  First reads the header of the
+    * message for MIME information, then (when necessary) calls other
+    * functions to determine the content of MULTIPART or MESSAGE/RFC822
+    * data contained.
+    */
+   mime_t *ret = NULL;
+   long part_offset = ftell (fp);
+   long body_offset;
+   long end_offset  =  part_offset + len;
+   header_list_ptr headers = NULL, mime_version, content_type;
+   int pre_mime_content_type = 0;
+ 
+   dprint(9,(debugfile,"rfc822_parse --> len=%d\n",len));
+ 
+   headers     = file_read_headers(fp,0);
+   body_offset = ftell(fp);
+ 
+   dprint(9,(debugfile,
+ 	    "rfc822_parse- part_offset=%ld, body_offset=%ld, end_offset=%ld\n",
+ 	    part_offset, body_offset, end_offset));
+ 
+   if (!locate_header_by_name(headers,"From") &&
+       !locate_header_by_name(headers,"Subject") &&
+       !locate_header_by_name(headers,"To") &&
+       !locate_header_by_name(headers,"CC")) {
+     error ("Seems that message/rfc822 data was corrupted.");
+     sleep_message();
+   }
+ 
+   mime_version = locate_header_by_name(headers,"MIME-Version");
+   content_type = locate_header_by_name(headers,"Content-Type");
+ 
+   if (content_type && content_type ->body) {
+     ret = mime_t_alloc();
+     ret->begin_offset = part_offset;
+     ret->offset       = body_offset;
+     ret->length = -1;
+ 
+     pre_mime_content_type = is_pre_mime_content_type(ret,content_type->body);
+   }
+ 
+   if (mime_version && pre_mime_content_type) {
+     error ("Warning: message/rfc822 data with MIME-Version and pre-mime Content-type");
+     sleep_message();
+   } 
+ 
+   if (mime_version || !pre_mime_content_type && req_mime_bodyencoding) {
+     if (ret) mime_destroy(ret);
+     ret = parse_mime_headers(headers,part_offset,body_offset,MIME_MIXED);  
+   } else if (!ret) {
+     ret = mime_t_alloc();
+     ret->begin_offset = part_offset;
+     ret->offset       = body_offset;
+     ret->length = -1;
+ 
+   }
+ 
+   dprint(9,(debugfile,"rfc822_parse: content-type=%s/%s; flags=%d\n",
+ 	    mime_types[ret->type], ret->subtype,ret->flags));
+ 
+   if (ret->length < 0) { 
+     ret->length = end_offset - body_offset;
+     dprint(9,(debugfile,"rfc822_parse: fixing length=%d\n",ret->length));
+   }
+ 
+   if (ret->type == MIME_TYPE_MULTIPART) {
+     char boundary[STRING];
+ 
+     mime_get_boundary (boundary, ret->type_opts, STRING);
+     dprint(9,(debugfile,"rfc822_parse- (parsing) MULTIPART; boundary=%s\n",
+ 	      boundary));
+ 
+     ret->parts = multipart_parse (fp, ret->length, boundary, ret->flags);
+   }
+   else if (ret->flags & MIME_RFC822) {
+     dprint(9,(debugfile,"rfc822_parse- (parsing) RFC822\n"));
+     ret->parts = rfc822_parse (fp, ret->length);
+   }
+   
+   delete_headers(headers);
+ 
+   /* Make sure the leave the stream at the end of the data! */
+   fseek (fp, end_offset, SEEK_SET);
+ 
+   dprint(9,(debugfile,"rfc822_parse <-- DONE\n"));
+ 
+   return ret;
+ }
+ 
+ void
+ mime_warnings(hdr) 
+      struct header_rec *hdr;
+ {
+ 
+   if (hdr->status & PRE_MIME_CONTENT) {
+     error("Error: MIME-message has pre-MIME content-type!");
+     sleep_message();
+   }
+   if (hdr->status & MIME_UNSUPPORTED) {
+     error("Warning: Unsupported MIME-Version!");
+     sleep_message();
+   }
+ }
+ 
+ void
+ attach_parse (hdr, fp)
+      struct header_rec *hdr;
+      FILE *fp;
+ {
+   int parsing = 0;
+   /* This routine checks to see if the multipart messages specified by
+    * "hdr" has been parsed for its subparts, and if not, calls the routine
+    * to do so.
+    */
+ 
+   char boundary[STRING];
+ 
+   if (hdr->mime_rec.magic != MIME_magic)
+     mime_panic(__FILE__,__LINE__,"attach_parse",
+ 	       "Bad magic number (mime_rec)");
+ 
+   /* Copy value */
+   if (hdr -> content_length >= 0)
+     hdr->mime_rec.length = hdr -> content_length;
+ 
+   if (hdr->mime_rec.begin_offset <= 0) {
+ 
+     fseek(fp,hdr->offset,SEEK_SET);
+     hdr->mime_rec.begin_offset = hdr->offset;
+     /* Skip mailbox's separator lines ... */
+ 
+     dprint(9,(debugfile,"attach_parse: scanning begin_offset: %d\n",
+ 	      hdr->mime_rec.begin_offset));
+ 
+     hdr->mime_rec.begin_offset = skip_envelope(hdr,fp);
+ 
+     dprint(9,(debugfile,"attach_parse: begin_offset=%d\n",
+ 	      hdr->mime_rec.begin_offset));
+ 
+     if (hdr->mime_rec.begin_offset < 0) {
+       error("Can't parse mail...");
+       sleep_message();
+       return;
+     }
+   }
+ 
+   if (hdr->mime_rec.type == MIME_TYPE_MULTIPART) {
+     if (hdr->mime_rec.parts == NULL) {
+       mime_get_boundary (boundary, hdr->mime_rec.type_opts, STRING);
+       if (0 != fseek (fp, hdr->mime_rec.offset, SEEK_SET)) {
+ 	error("Failed to seek beginning body...");
+ 	sleep_message();
+       } else {
+ 	int tmp;
+ 	parsing = 1;
+ 	lower_prompt("Parsing MIME structure...");
+ 	hdr->mime_rec.parts = 
+ 	  multipart_parse (fp, hdr->content_length, boundary, 
+ 			 hdr->mime_rec.flags);
+ 	/* Reconsider it */
+ 	tmp = mime_notplain(&(hdr->mime_rec));
+ 	if (tmp != hdr->mime_rec.notplain) {
+ 	  hdr->mime_rec.notplain = tmp;
+ 	  if (!tmp) {
+ 	    lower_prompt("Parsing MIME structure... metamail not needed");
+ 	    parsing = 2;
+ 	  }
+ 	}
+       }
+     }
+   } else if (hdr->mime_rec.flags & MIME_RFC822) {
+     if (hdr->mime_rec.parts == NULL) {
+       if (0 != fseek (fp, hdr->mime_rec.offset, SEEK_SET)) {
+ 	error("Failed to seek beginning body...");
+ 	sleep_message();
+       } else {
+ 	int tmp;
+ 	parsing = 1;
+ 	lower_prompt("Parsing MIME structure...");
+ 	hdr->mime_rec.parts = rfc822_parse (fp, hdr->content_length);
+ 	/* Reconsider it */
+ 	tmp = mime_notplain(&(hdr->mime_rec));
+ 	if (tmp != hdr->mime_rec.notplain) {
+ 	  hdr->mime_rec.notplain = tmp;
+ 	  if (!tmp) {
+ 	    lower_prompt("Parsing MIME structure... metamail not needed");
+ 	    parsing = 2;
+ 	  }
+ 	}	
+       }
+     }
+   }
+ 
+   if (parsing) {
+     if (2 == parsing) {
+       if (sleepmsg > 0)
+ 	sleep ((sleepmsg+2)/3);
+     }
+     lower_prompt("");
+   }
+   return;
+ }
+ #endif /* MIME */
+ 
+ 
+ 
Index: elm2.4.ME+.50/melib/parse_util.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/melib/parse_util.c	Tue Nov 17 21:12:56 1998
***************
*** 0 ****
--- 1,641 ----
+ static char rcsid[] = "@(#)$Id: parse_util.c,v 1.2 1998/10/20 19:58:08 hurtta Exp $";
+ 
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
+  *
+  *  Author: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *****************************************************************************/
+ 
+ #include "headers.h"
+ #include "melib.h"
+ #include "s_me.h"
+ 
+ static void header_panic P_((char *,int,char *, char *)); /* Prototype */
+ static void header_panic(f,ln,pr,ms) 
+      char * f;
+      int ln;
+      char *pr;
+      char *ms;
+ {
+   int do_cursor = RawState();
+ 
+   dprint(1,(debugfile,"\nHEADER PANIC in %s:%d:%s\n",f,ln,pr));
+   dprint(1,(debugfile,">>%s\n",ms));
+ 
+   /* softkeys_off(); */
+ 
+   if (do_cursor) {
+     lib_error(FRM("HEADER PANIC: %s"),ms);
+     sleep(1);
+   }
+ 
+   if (do_cursor) {
+     MoveCursor(elm_LINES, 0);
+     Raw(OFF);
+   }
+ 
+   fprintf(stderr,"\nHEADER PANIC in %s:%d:%s\n",f,ln,pr);
+   fprintf(stderr,">>%s\n",ms);
+ 
+ #if DEBUG
+   if (debug > 10) {
+     fprintf(stderr,"ABORTING...\n");
+     fflush(stderr);
+     abort();
+   }
+ #endif
+   emergency_exit();
+ }
+ 
+ 
+ /* Removes comments from string */
+ void rfc822_reap_comments (ptr, comments, size) 
+      char *ptr, *comments;
+      int size;
+ {
+   char *w_ptr = ptr, *c_ptr = comments;
+   int comment_level = 0, saved_level = 0;
+   int in_quote = 0;
+   
+   while (*ptr) {
+     if (*ptr == '\\' && (in_quote || comment_level > 0)) {		  
+       /* \ escapes next character  
+        * (not allowed outside of quotes or comments) */
+       ptr++;
+       if (*ptr == '\0')
+ 	break;
+       if (comment_level > 0 && comments) {
+ 	if (c_ptr < comments + size - saved_level -3) {
+ 	  *c_ptr++ = '\\';
+ 	  *c_ptr++ = *ptr;
+ 	}
+       }
+       if (comment_level == 0) {
+ 	*w_ptr++ = '\\';
+ 	*w_ptr++ = *ptr;
+       }
+       ptr++;
+       continue;
+     } else if (comment_level > 0) {
+       if (*ptr == ')')
+ 	comment_level --;
+       if (*ptr == '(')
+ 	comment_level ++;
+       if (comments && c_ptr < comments + size - saved_level -3) {
+ 	*c_ptr++ = *ptr;
+ 	saved_level = comment_level;
+       }
+     } else if (*ptr == '\"') {
+       if (in_quote)
+ 	in_quote = 0;
+       else
+ 	in_quote = 1;
+     } else if (!in_quote && *ptr == '(') {
+       comment_level ++;
+       if (comments && c_ptr < comments + size - saved_level -4) {
+ 	if (c_ptr != comments)
+ 	  *c_ptr++ = ' ';
+ 	*c_ptr++ = *ptr;
+ 	saved_level = comment_level;
+       }
+       *w_ptr++ = ' ';  /* RFC 822 (STD 11) says that 
+ 			  comments represents one space */
+     }
+     if (comment_level == 0 && (in_quote || *ptr != ')'))
+       *w_ptr++ = *ptr;
+     ptr++;
+   }
+   while (comments && saved_level > 0) {
+     *c_ptr++ = ')';
+     saved_level--;
+   }
+ 
+   if (comments)
+     *c_ptr = '\0';
+   *w_ptr = '\0';
+ }
+ 
+ int read_header_line (fp, buf, size,flag) 
+      FILE *fp;
+      char *buf;
+      int size;
+      int flag;
+ {
+   in_state_t state;
+   int result;
+ 
+   in_state_clear(&state,STATE_in_file);
+ 
+   set_in_state_file(fp,&state);
+ 
+   result = state_read_hdr_line(&state,buf,size,flag);
+ 
+   in_state_destroy(&state);
+ 
+   return result;
+ }
+ 
+ int state_read_hdr_line (s, buf, size,flag) 
+      in_state_t *s;
+      char *buf;
+      int size;
+      int flag;
+ {
+   /* Read and unfold header line -- stores maximum size-1 bytes to buffer
+    * (plus \0). Also handle case when headers are eneded either CR LF or LF.
+    * Returns number of bytes stored. Always _read_ end of header
+    * (even when buffer fills). Returns 0 when reads empty line (only CR LF).
+    * That indicates end of headers.
+    *
+    * If flag & 1 (RHL_MARK_FOLDING) then folding is marked with '\n' 
+    * (instead of ' ' and buffer ended with '\n' before '\0'
+    * If flag & 2 (RHL_CHECK_HEADER) then check that this was header line...
+    */
+ 
+   int len = 0,c;
+   int col_seen = 0;
+   long pos;
+ 
+   dprint(12,(debugfile,"state_read_hdr_line: size=%d, flag=%d\n",size,flag));
+   size--; /* Place for \0 */
+ 
+   if ( (!in_state_seekable(s) ||
+ 	(pos = in_state_ftell(s)) < 0) && 
+        (flag & RHL_CHECK_HEADER)) {
+     dprint(12,(debugfile,"state_read_hdr_line=0; not seekable or ftell failed!"));
+     buf[0] = '\0';
+     return 0;
+   }
+ 
+ #define PUTC(c) { if (len < size) buf[len++] = (c); }
+   
+   while (EOF != (c = state_getc(s))) {
+     if ('\r' == c) {                /* Is this CR LF sequence ? */
+       if (EOF == (c = state_getc(s)))
+ 	break;
+       if (c != '\n') 
+ 	PUTC('\r');
+     }
+     if (c == '\n') {                /* Readed CR LF or LF, check folding */
+       if (!col_seen && len > 0 && (flag & RHL_CHECK_HEADER)) {
+       bad_header_line:
+ 	dprint(12,(debugfile,
+ 		   "state_read_hdr_line: Not ':' seen. Not a header line!\n"));
+ 	if (0 != in_state_fseek(s,pos)) {
+ 	  dprint(5,(debugfile,
+ 		    "read_header_line: seek failed!\n"));
+ 	}
+ 	len = 0;
+       }
+       if (len == 0)
+ 	break;                      /* End of headers ! */
+       if (EOF == (c = state_getc(s)))
+ 	break;
+       if (c != ' ' && c != '\t') {   /* Not a continuation line */
+ 	state_ungetc(c,s);
+ 	break;
+       }
+       /* CRLF LWSP sequence should be replaced with ' ' */
+       c = ' ';
+       if (flag & RHL_MARK_FOLDING)
+ 	c = '\n';
+     }
+     /* Space before ':' ? */
+     if ((' ' == c || '\t' == c) && !col_seen && (flag & RHL_CHECK_HEADER)) {
+       /* Skip to next ':' */
+       while (' ' == c || '\t' == c)
+ 	c = state_getc(s);
+       if (':' != c) 
+ 	goto bad_header_line;
+     }
+     if (':' == c)
+       col_seen = 1;
+     PUTC(c);
+   }
+ 
+   if (flag & RHL_MARK_FOLDING) {
+     PUTC('\n');
+   }
+ 
+ #undef PUTC
+   buf[len] = 0;
+ 
+   dprint(12,(debugfile,"state_read_hdr_line: len=%d, buf=%s\n",len,buf));
+ 
+   return len;
+ }
+ 
+ static struct header_info header_types[] = {
+   /* From STD 11 (RFC 822): */
+   { "Subject",    HDR_TEXT },
+   { "Comments",   HDR_TEXT },
+   { "Return-path",HDR_STRUCTURED },
+   { "Received",   HDR_STRUCTURED },
+   { "Reply-To",   HDR_STRUCTURED|HDR_PHRASE },    /* Not exactly correct .. */
+   { "From",       HDR_STRUCTURED|HDR_PHRASE },    /* Not exactly correct .. */
+   { "Sender",     HDR_STRUCTURED|HDR_PHRASE },    /* Not exactly correct .. */
+   { "Resent-Reply-To", HDR_STRUCTURED|HDR_PHRASE },/* Not exactly correct .. */
+   { "Resent-From",     HDR_STRUCTURED|HDR_PHRASE },/* Not exactly correct .. */
+   { "Resent-Sender",   HDR_STRUCTURED|HDR_PHRASE },/* Not exactly correct .. */
+   { "Date",        HDR_STRUCTURED },
+   { "Resent-Date", HDR_STRUCTURED },
+   { "To",          HDR_STRUCTURED|HDR_PHRASE }, /* Not exactly correct .. */
+   { "Resent-To",   HDR_STRUCTURED|HDR_PHRASE }, /* Not exactly correct .. */
+   { "cc",          HDR_STRUCTURED|HDR_PHRASE }, /* Not exactly correct .. */
+   { "Resent-cc",   HDR_STRUCTURED|HDR_PHRASE }, /* Not exactly correct .. */
+   { "bcc",         HDR_STRUCTURED|HDR_PHRASE }, /* Not exactly correct .. */
+   { "Resent-bcc",  HDR_STRUCTURED|HDR_PHRASE }, /* Not exactly correct .. */
+   { "Message-ID",  HDR_STRUCTURED },
+   { "Resent-Message-ID",  HDR_STRUCTURED },
+   { "In-Reply-To", HDR_STRUCTURED|HDR_PHRASE }, /* Is correct .. */
+   { "References",  HDR_STRUCTURED|HDR_PHRASE }, /* Is correct .. */
+   { "Keywords",  HDR_STRUCTURED|HDR_PHRASE },   /* Is correct :-) .. */
+   { "Encrypted", HDR_STRUCTURED },              /* Well ... */
+   /* From MIME (RFC 1521) */
+   { "MIME-Version",              HDR_STRUCTURED },     
+   { "Content-Type",              HDR_STRUCTURED },     
+   { "Content-Transfer-Encoding", HDR_STRUCTURED },
+   { "Content-ID",                HDR_STRUCTURED },     
+   { "Content-Description",       HDR_TEXT },
+   /* From RFC 1806 */
+   { "Content-Disposition",       HDR_STRUCTURED },
+   /* From RFC 1864 */
+   { "Content-MD5",               0 },
+ 
+   /* mailbox format */
+   { "Content-Length",      0 },
+   { "Status",              0 },
+ 
+   /* Sendmail */
+   { "Full-Name",           HDR_TEXT },
+   { "Return-Receipt-To",   HDR_STRUCTURED|HDR_PHRASE }, /* Not exactly correct .. */
+   { "Auto-Submitted",      HDR_STRUCTURED },
+   { "Precedence",          0 },
+ 
+ 
+   /* IDA Sendmail */
+   { "X-Charset",           0 },
+   { "X-Char-Esc",          0 },
+ 
+   /* Unknown source */
+   { "Action",              0 },
+   { "Priority",            HDR_STRUCTURED },
+   { "Expires",             HDR_STRUCTURED },
+   { "Importance",          HDR_STRUCTURED },
+   { "Sensitivity",         HDR_STRUCTURED },
+ 
+   /* Our non-standard headers */
+   { "X-ELM-OSV",                 HDR_STRUCTURED },
+   { "X-Mailer",                  HDR_TEXT },
+   { "Content-Name",              HDR_TEXT },
+   
+ 
+   /* Tailer */
+   { NULL, 0 }
+ };
+ 
+ /* Grows forever */
+ static struct hdr_list {
+   struct hdr_list * next;
+   struct header_info hdr;
+ } * extra_headers = NULL;
+ static int extra_header_count = 0;
+ 
+ header_ptr find_header(name, create_flag) 
+      char *name;
+      int create_flag;
+ {
+   int i;
+   struct hdr_list * walk, *last = NULL;
+ 
+   for (i = 0; header_types[i].header; i++) 
+     if (strincmp(name,header_types[i].header,STRING) == 0)
+       return &(header_types[i]);
+ 
+   for (walk = extra_headers; 
+        walk != NULL; 
+        last = walk, walk = walk -> next)
+     if (strincmp(name,walk->hdr.header,STRING) == 0)
+       return &(walk->hdr);
+   
+   if (create_flag) {
+     walk = (struct hdr_list * ) safe_malloc (sizeof(struct hdr_list));
+ 
+     if (last) last->next = walk;
+     else extra_headers   = walk;
+     extra_header_count++;
+ 
+     walk->next = NULL;
+     walk->hdr.header = strmcpy(NULL,name);
+     if (strincmp(name,"X-",2) == 0)
+       walk->hdr.flag = HDR_TEXT;     /* Default for user defined headers */
+     else
+       walk->hdr.flag = 0;            /* We don't know it, right? */
+ 
+     return &(walk->hdr);
+   }
+   
+   return NULL;
+ }
+ 
+ int classify_header(name)
+      char *name;
+ {
+   header_ptr P = find_header(name,0);
+ 
+   if (P)
+     return P->flag;
+ 
+   if (strincmp(name,"X-",2) == 0)
+     return HDR_TEXT;              /* Default for user defined headers */
+ 
+   return 0;
+ }
+ 
+ long skip_envelope(hdr, fp)
+      struct header_rec *hdr;
+      FILE *fp;
+ {
+   char buf[STRING];
+   int tmp;
+   int first_line = TRUE;
+ 
+   long result = hdr->offset;
+ 
+   if (0 !=  fseek(fp,hdr->offset,SEEK_SET)) {
+     lib_error(CATGETS(elm_msg_cat, MeSet, MeFailedSeekEnvelope,
+ 		      "Failed to seek beginning of mail envelope (%ld)"),
+ 	      hdr->offset);
+     sleep_message();
+     dprint(9,(debugfile,"skip_envelope=-1 (fseek error)\n"));
+ 
+     return -1;
+   }
+ 
+   dprint(9,(debugfile,"skip_envelope: scanning offset: %ld\n",
+ 	    result));;
+ 
+   while (0 < (tmp = mail_gets(buf,sizeof(buf),fp))) {
+     dprint(9,(debugfile,"skip_envelope: len=%d, got: %s\n",tmp,buf));
+ #ifdef MMDF
+     if (0 == strcmp(buf,MSG_SEPARATOR))
+       continue;
+ #endif
+     if (0 == strncmp(buf,"From ",5)) {
+       first_line = FALSE;
+       continue;
+     }
+     if (!first_line && first_word_nc(buf, ">From"))
+       continue;
+     dprint(20,(debugfile,"skip_envelope: got headers: %s\n",buf));
+     break;
+   }
+   result = ftell(fp) - tmp;
+ 
+   dprint(9,(debugfile,"skip_envelope: beginning of headers=%ld\n",result));
+   if (0 !=  fseek(fp,result,SEEK_SET)) {
+     lib_error(CATGETS(elm_msg_cat, MeSet, MeFailedSeekHeaders,
+ 		      "Failed to seek beginning of mail headers (%ld)"),
+ 	      result);
+     sleep_message();
+     dprint(9,(debugfile,"skip_envelope=-1 (fseek error)\n"));
+     return -1;
+   }
+ 
+   dprint(9,(debugfile,"skip_envelope=%ld\n",result));
+   return result;
+ }
+ 
+ header_list_ptr locate_header(h,n)
+      header_list_ptr h;
+      header_ptr n;
+ {
+   header_list_ptr walk;
+ 
+   for (walk = h; 
+        walk != NULL; 
+        walk = walk -> next_other_header) {
+     if (walk -> magic != HEADER_magic)
+       header_panic(__FILE__,__LINE__,"locate_header",
+ 		   "Bad magic number");
+     if (n == walk -> header_name)
+       return walk;
+   }
+   return NULL;
+ }
+ 
+ header_list_ptr file_read_headers(fp, flag) 
+      FILE * fp;
+      int flag;
+ {
+   in_state_t state;
+   header_list_ptr result;
+ 
+   in_state_clear(&state,STATE_in_file);
+ 
+   set_in_state_file(fp,&state);
+ 
+   result = state_read_headers(&state, flag);
+ 
+   in_state_destroy(&state);
+ 
+   return result;
+ }
+ 
+ header_list_ptr state_read_headers(s, flag) 
+      in_state_t * s;
+      int flag;
+ {
+   char buffer[32*1024+1];
+   int size;
+ 
+   header_list_ptr result = NULL, last = NULL;
+ 
+   dprint(12,(debugfile,"state_read_headers() --> START\n"));
+ 
+   while (size = state_read_hdr_line(s,buffer,sizeof buffer,
+ 				    RHL_CHECK_HEADER|flag) > 0) {
+     header_list_ptr item, last_this = NULL, walk;
+     char * k;
+     if (0 == strcmp(buffer,"\n"))
+       break;
+     k = strchr(buffer,':');
+     if (!k)
+       break;
+     *k = '\0';
+     k++;
+     item = (struct header_list *) safe_malloc(sizeof (struct header_list));
+     item -> header_name = find_header(buffer,1);
+     
+     item -> next_header       = NULL;
+     item -> next_this_header  = NULL;
+     item -> next_other_header = NULL;
+     item -> body              = strmcpy(NULL,k);
+     item -> magic             = HEADER_magic;
+     
+     for (walk = result; 
+ 	 walk != NULL; 
+ 	 last_this = walk, walk = walk -> next_other_header) {
+       if (walk -> magic != HEADER_magic)
+ 	header_panic(__FILE__,__LINE__,"state_read_headers",
+ 		     "Bad magic number");
+       if (item -> header_name == walk -> header_name)
+ 	break;
+     }
+ 
+     if (walk) {  
+       while (walk->next_this_header != NULL) {
+ 	if (walk -> magic != HEADER_magic)
+ 	  header_panic(__FILE__,__LINE__,"state_read_headers",
+ 		       "Bad magic number");
+ 	walk = walk->next_this_header;
+       }
+ 
+       walk->next_this_header = item;
+ 
+       dprint(12,
+ 	     (debugfile,
+ 	      "state_read_headers- header='%s' -- append next_this_header (%s)\n",
+ 	      item->header_name->header,
+ 	      walk->header_name->header));
+ 		 
+     } else if (last_this) {
+       last_this -> next_other_header = item;
+       dprint(12,
+ 	     (debugfile,
+ 	      "state_read_headers- header='%s' -- append next_other_header (%s)\n",
+ 	      item->header_name->header,
+ 	      last_this->header_name->header));
+     }
+ 
+     if (last) {
+       last -> next_header  = item;
+ 
+       dprint(12,
+ 	     (debugfile,
+ 	      "state_read_headers: header='%s' -- append next_header (%s)\n",
+ 	      item->header_name->header,
+ 	      last->header_name->header));
+ 
+     }
+     else      {
+       result               = item;
+       dprint(12,
+ 	     (debugfile,
+ 	      "state_read_headers: header='%s' -- head of next_header\n",
+ 	      item->header_name->header));
+     }
+     last = item;
+ 
+   }
+ 
+   dprint(12,(debugfile,"state_read_headers()=%p <-- END\n",result));
+   return result;
+ }
+ 
+ void delete_headers(hdr)
+      header_list_ptr hdr;
+ {
+   header_list_ptr next = hdr;
+   
+   while(next) {
+     if (next -> magic != HEADER_magic)
+       header_panic(__FILE__,__LINE__,"delete_headers","Bad magic number");
+ 
+     hdr  = next;
+     next = next -> next_header;
+ 
+     if(hdr -> body) {
+       free(hdr -> body);
+       hdr -> body = NULL;
+     }
+     hdr -> next_header       = NULL;
+     hdr -> next_this_header  = NULL;
+     hdr -> next_other_header = NULL;
+     hdr -> magic             = 0;
+     free((void *)hdr);
+   }
+ }
+ 
+ int NULL_header_filter(hdr,flag)
+      header_list_ptr hdr;
+      int flag;
+ {
+   if (hdr -> magic != HEADER_magic)
+     header_panic(__FILE__,__LINE__,"NULL_header_filter","Bad magic number");
+ 
+   flag++;      /* So that flag is used */
+   return 1;
+ }
+ 
+ void NULL_header_converter (hdr,flag,buffer,size)
+      header_list_ptr hdr;
+      int flag;
+      char *buffer;
+      int size;
+ {
+   if (hdr -> magic != HEADER_magic)
+     header_panic(__FILE__,__LINE__,"NULL_header_converter","Bad magic number");
+ 
+   flag++;      /* So that flag is used */
+   
+   if (hdr->body)
+     strfcpy(buffer,hdr->body,size);
+   else
+     buffer[0] = '\0';
+ }
+ 
+ void state_write_headers(s,hdr,filter,convert,flag) 
+      out_state_t * s;
+      header_list_ptr hdr;
+      header_filter    * filter;
+      header_converter * convert;
+      int                flag;
+ {
+   header_list_ptr next = hdr;
+   int ret;
+   
+   for (next = hdr; next; next = next -> next_header) {
+     char buffer [ 32 * 1024 + 1], *ptr;
+     if (next -> magic != HEADER_magic)
+       header_panic(__FILE__,__LINE__,"state_write_headers",
+ 		   "Bad magic number");
+ 
+     if (! (ret = filter(next,flag))) {
+       dprint(12,(debugfile,
+ 		 "state_write_headers: header='%s', {filter}=%d FILTERED\n",
+ 		 next->header_name->header, ret));
+       continue;
+     } else {
+       dprint(12,(debugfile,
+ 		 "state_write_headers: header='%s', {filter}=%d PASSED\n",
+ 		 next->header_name->header, ret));
+     }
+ 
+     buffer[0] = '\0';
+ 
+     convert(next,flag,buffer,sizeof buffer);
+     
+     buffer[sizeof buffer -1] = '\0';
+ 
+     state_add_prefix(s);
+     state_puts(next->header_name->header,s);
+     state_puts(": ",s);
+ 
+     for (ptr = strtok(buffer,"\n"); ptr; ptr = strtok(NULL,"\n")) { 
+       if (ptr > buffer) { /* Do folding */
+ 	--ptr;
+ 	if (*(ptr+1) == ' ')
+ 	  *ptr = ' ';
+ 	else
+ 	  *ptr = '\t';
+ 	state_putc('\n',s);
+ 	state_add_prefix(s);
+       }
+       state_puts(ptr,s);
+     }
+     state_putc('\n',s);
+   }
+ }
+ 
Index: elm2.4.ME+.50/melib/pgp_decode.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/melib/pgp_decode.c	Tue Nov 17 21:12:56 1998
***************
*** 0 ****
--- 1,643 ----
+ static char rcsid[] = "@(#)$Id: pgp_decode.c,v 1.2 1998/10/20 19:58:08 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *
+  *  Initially written by: Michael Elkins <elkins@aero.org>, 1995
+  *****************************************************************************/
+ 
+ #include "headers.h"
+ #include "melib.h"
+ #include "s_me.h"
+ 
+ #ifdef USE_PGP
+ #include <sys/time.h>
+ #include <errno.h>
+ 
+ extern int errno;
+ 
+ extern int pgp_keeppassfor; /* 5 minutes */
+ extern char pgp_passphrase[STRING];
+ extern int pgp_expires;
+ 
+ int have_pgp () 
+ {
+   int return_value = 1;
+ 
+   if (strcmp(pgp_path,"none") == 0 || 
+       pgp_path[0] == '\0') {
+     return_value = 0;
+   } else if (pgp_path[0] == '/') {
+     if (-1 == access(pgp_path,EXECUTE_ACCESS)) {
+       int err = errno;
+       lib_error(CATGETS(elm_msg_cat, MeSet, MePgpCantExecute,
+ 			"Can't execute pgp: %.50s: %.30s"),
+ 		pgp_path, error_description(err));
+ 
+       dprint(5,(debugfile,"have_pgp: no access %s: %s\n",pgp_path,
+ 		error_description(err)));
+       if (sleepmsg > 0)
+ 	sleep(sleepmsg);
+       return_value = 0;
+     }
+   } else {
+     lib_error(CATGETS(elm_msg_cat, MeSet, MePgpPath,
+ 		      "PGP path must start with '/': %.60s"),
+ 	      pgp_path);
+     dprint(5,(debugfile,"have_pgp: bad path: %s\n",pgp_path));
+     if (sleepmsg > 0)
+       sleep(sleepmsg);
+     return_value = 0;
+   }
+ 
+   dprint(5,(debugfile,"have_pgp=%d\n",return_value));
+   return return_value;
+ 
+ }
+ 
+ void pgp_void_passphrase ()
+ {
+   int i;
+ 
+   for (i = 0 ; i < STRING ; i++)
+     pgp_passphrase[i] = '\0';
+   pgp_expires = 0;
+   return;
+ }
+ 
+ static int QueryExpirePassphrase P_((void));
+ 
+ static int QueryExpirePassphrase()
+ {
+   struct timeval now;
+ 
+   /* negative implies never expire */
+   if (pgp_keeppassfor < 0)
+     return(0);
+   gettimeofday(&now, 0);
+   if (now.tv_sec < pgp_expires) {
+     pgp_expires = now.tv_sec + pgp_keeppassfor;
+     return(0);
+   }
+   pgp_void_passphrase ();
+   return(1);
+ }
+ 
+ static int GetPassphrase P_((void));
+ 
+ static int GetPassphrase ()
+ {
+   struct timeval now;
+   int status;
+ 
+ redraw:
+   PutLine0(elm_LINES-2, 0, "Please enter your PGP passphrase: ");
+   CleartoEOS();
+   
+   status = optionally_enter(pgp_passphrase, elm_LINES-2, 34, 
+ 			    OE_PASSWD|OE_REDRAW_MARK, 
+ 			    sizeof pgp_passphrase);
+   if (REDRAW_MARK == status)
+     goto redraw;
+ 
+   if (status != 0)
+     return(0);
+   gettimeofday(&now, 0);
+   if (pgp_keeppassfor > 0)
+     pgp_expires = now.tv_sec + pgp_keeppassfor;
+   return(pgp_passphrase[0] != '\0');
+ }
+ 
+ int pgp_goodPassphrase()
+ {
+   if (pgp_passphrase[0] == '\0' || QueryExpirePassphrase())
+     return(GetPassphrase());
+   else
+     return(1);
+ }
+ 
+ /* opens up a PGP process as a child and returns its stdin and stdout */
+ int pgp_decrypt_init (fpin, fpout, opts)
+      FILE **fpin, **fpout;
+      int opts; /* PGP_MESSAGE or PGP_SIGNED_MESSAGE */
+ {
+   int pgp_child_in[2];
+   int pgp_child_out[2];
+   int passpipe[2];
+   int usepass=FALSE;
+   int fork_ret;
+   char cmd[STRING];
+ 
+   dprint (2, (debugfile, "pgp_descrypt_init() called with opts=%d\n", opts));
+ 
+   if (!have_pgp())
+     return(-1);
+ 
+   if (pipe(pgp_child_in) == -1)
+     return(-1);
+   if (pipe(pgp_child_out) == -1)
+     return(-1);
+   
+   if ((opts & PGP_MESSAGE) && pgp_keeppass) {
+     if (pipe(passpipe) == -1) {
+       close(pgp_child_in[0]);
+       close(pgp_child_out[0]);
+       close(pgp_child_in[1]);
+       close(pgp_child_out[1]);
+       return(-1);
+     }
+     usepass = TRUE;
+   }
+   dprint (3, (debugfile, "usepass = %d.\n", usepass));
+ 
+   Raw(OFF);
+   ClearScreen();
+ 
+   /* Tell the user why they are waiting */
+   if (opts & PGP_MESSAGE) {
+       Write_to_screen(CATGETS(elm_msg_cat, MeSet, MePgpDecryptMes,
+ 			      "Running pgp: Decrypting message...\n"));
+   } else if (opts & PGP_SIGNED_MESSAGE) {
+     Write_to_screen(CATGETS(elm_msg_cat, MeSet, MePgpCheckSig,
+ 			    "Running pgp: Checking signature...\n"));
+   } else {
+     Write_to_screen(CATGETS(elm_msg_cat, MeSet, MePgpRun,
+ 			    "Running pgp ...\n"));
+   }
+ 
+   if ((fork_ret = fork()) == 0) {
+     close (pgp_child_in[1]);
+     close (0);
+     dup (pgp_child_in[0]);
+     close (pgp_child_in[0]);
+     
+     close (pgp_child_out[0]);
+     close (1);
+     dup (pgp_child_out[1]);
+     close (pgp_child_out[1]);
+     
+     /* build up the command */
+     if (usepass) {
+       close (passpipe[1]);
+       elm_sfprintf (cmd, sizeof cmd,
+ 		    FRM("PGPPASSFD=%d; export PGPPASSFD; "),
+ 		    passpipe[0]);
+     }
+     else
+       cmd[0] = '\0';
+     strfcat(cmd,pgp_path, sizeof cmd);
+     strfcat(cmd," -f +verbose=0", sizeof cmd);
+     strfcat(cmd, " +KEEPBINARY=OFF", sizeof cmd);
+     if (usepass || opts == PGP_SIGNED_MESSAGE)
+       strfcat(cmd, " +batchmode", sizeof cmd);
+     _exit (system_call(cmd,0));	
+   }
+   
+   close (pgp_child_in[0]);
+   close (pgp_child_out[1]);
+   
+   /* now send the passphrase if needed */
+   if (usepass) {
+     dprint(3,(debugfile,"pgp_decrypt_init: sending pgp passphrase.\n"));
+     close (passpipe[0]);
+     write (passpipe[1], pgp_passphrase, strlen(pgp_passphrase));
+     write (passpipe[1], "\n", 1);
+     close (passpipe[1]);
+   }
+   
+   if ((*fpin = fdopen(pgp_child_out[0], "r")) == 0) {
+     Raw(ON);
+     return(-1);
+   }
+   if ((*fpout = fdopen(pgp_child_in[1], "w")) == 0) {
+     Raw(ON);
+     return(-1);
+   }
+   
+   return(fork_ret);
+ }
+ 
+ #ifdef MIME
+ static int pgp_mime_opts P_((char *));
+ 
+ static int pgp_mime_opts (s)
+      char *s;
+ {
+   char value[STRING];
+ 
+   if (s) {
+     if (mime_get_param ("format", value, s, sizeof(value))) {
+       if (istrcmp (value, "keys-only") ==  0)
+ 	return PGP_PUBLIC_KEY;
+     }
+     if (mime_get_param ("x-action", value, s, sizeof (value))) {
+       if (istrcmp (value, "encryptsign") == 0)
+ 	return (PGP_MESSAGE | PGP_SIGNED_MESSAGE);
+       else if (istrcmp (value, "encrypt") == 0)
+ 	return PGP_MESSAGE;
+       else if (istrcmp (value, "sign") == 0)
+ 	return PGP_SIGNED_MESSAGE;
+       else if (istrcmp (value, "signclear") == 0)
+ 	return PGP_SIGNED_MESSAGE;
+     }
+   }
+   return PGP_MESSAGE;
+ }
+ 
+ static int wait_pgp P_((int,int)); /* Prototype */  
+ 
+ static int wait_pgp(raw,child)
+      int raw;
+      int child;
+ {
+   S__ status;
+ 
+   int w,stat=-1;
+   while ((w = my_wait(child,&status)) != child)
+     if (w == -1 && errno != EINTR)
+       break;
+   if (w == child) {
+     int sig = convert_status(status,&stat);
+     if (sig)
+       stat = 1;
+   }
+   PressAnyKeyToContinue();
+ 
+   if (raw)
+     Raw (ON);
+ 
+   return stat;
+ }
+ 
+ void pgp_decode (m, s_in, s_out)
+      mime_t *m;
+      in_state_t  *s_in;
+      out_state_t *s_out;
+ {
+   /* This procedure implements the de-facto standard for using PGP with MIME.
+    * Content-Type: application/pgp
+    * Required-Parameters: none
+    * Optional parameters: format, x-action
+    *     format = mime | text | keys-only
+    *         mime : indicates that the signed/encrypted body contains a MIME
+    *                compliant body and should be parsed recursively.
+    *         text : [DEFAULT if there is no format option].  This option
+    *                means that the encrypted/signed data should be presented
+    *                to the user after processing, no additional processing
+    *                needed.
+    *         keys-only:
+    *                The data in the body represents public key data only
+    *     x-action = encryptsign | encrypt | sign
+    *         This keyword is meant to be helpful to the application, but is
+    *         not required, and may not even be necessary to look at.
+    *
+    *         encryptsign : the application/pgp data is both signed and
+    *                       encrypted.
+    *         encrypt     : the data is encrypted only
+    *         sign        : the data is signed only
+    */
+ 
+   char tempfile[STRING], buffer[STRING];
+   FILE *pgpout, *pgpin, *tmpfp=NULL, *decode_fp = NULL;
+   int
+     child,
+     inbody = FALSE,
+     opts,
+     len,
+     raw,
+     stat = -1,
+     bytes = 0,
+     nested = FALSE; /* PGP output should be parsed as a MIME body */
+   mime_t *tmpmt;
+   
+   int was_binary = 0;
+   in_state_t newstate2;
+   in_state_clear(&newstate2,STATE_in_file);
+ 
+   raw = RawState ();
+ 
+   if (mime_get_param ("format", buffer, m->type_opts, sizeof (buffer)) &&
+       (istrcmp (buffer, "mime") == 0)) {
+     nested = TRUE;
+     dprint (3, (debugfile, "pgp_decode: format=mime\n"));
+     
+     elm_sfprintf (tempfile, sizeof tempfile,
+ 		  FRM("%selmPT%d"), 
+ 		  temp_dir, getpid ());
+     
+     if (NULL == (tmpfp = safeopen_rdwr(tempfile))) {
+       lib_error(CATGETS(elm_msg_cat, MeSet, MePgpCantCreate,
+ 			"Failed to create file for decoding."));
+       state_putc('[',s_out);
+       state_puts(catgets(elm_msg_cat, MeSet, MePgpCantCreate,
+ 			"Failed to create file for decoding."),
+ 		 s_out);      
+       state_puts("]\n",s_out);
+       return;
+     }
+ 
+     unlink (tempfile); /* Filename is no longer needed ... */
+   }
+   else
+     tmpfp = NULL;
+ 
+   opts = pgp_mime_opts (m->type_opts);
+ 
+   /* Now metapager does not ask passphrase -- this is called indirectly
+    * via copy_message    -KEH
+    */
+   if ((opts & PGP_MESSAGE) && pgp_keeppass) {
+     if (!pgp_goodPassphrase()) {
+       lib_error(CATGETS(elm_msg_cat, MeSet, MePgpBadPassphrase,
+ 			"Decrypting message... Bad PGP passphrase."));
+       state_putc('[',s_out);
+       state_puts(catgets(elm_msg_cat, MeSet, MePgpBadPassphrase,
+ 			"Decrypting message... Bad PGP passphrase."),
+ 		 s_out);
+       state_puts("]\n",s_out);
+       return;
+     }
+   }
+ 
+   buffer[0] = '\0';
+   if (opts & PGP_PUBLIC_KEY) {
+     state_puts (catgets(elm_msg_cat, MeSet, MePgpPublicKeys,
+ 			"(** This message contains PGP public key(s) **)\n\n"),
+  		s_out);
+   }
+ 
+   /* Decode Content-transfer-encoding */
+   
+   if (decode_fp = arrange_decoded(m,s_in,s_out,&newstate2)) {  
+     /* If arrange_decoded was treated this as text, don't consider
+      * about binary PGP files -- that happens when type is text/x-pgp
+      */
+     int was_text = is_text_type (mime_types[m->type], m->subtype, 
+ 				 m->encoding);
+ 
+     dprint (4, (debugfile, "pgp_decode: was_text = %d\n", was_text));
+ 
+     /* Print text before PGP armor 
+      *
+      */
+ 
+     len = state_getl (buffer, sizeof (buffer), &newstate2);    
+     if ( len < 1) {
+       state_puts(catgets(elm_msg_cat, MeSet, MePgpNoText1,
+ 			 "[No text in PGP section.]\n"),
+ 		 s_out);
+     } else {
+       int c = (unsigned char) buffer[0],i;
+ 
+       if (!pgp_noarmor) {
+ 	was_binary = 1; /* default assumption */
+ 	goto pgp_found;
+       }
+ 
+       if (!was_text) {
+ 	/* Check if that is binary PGP file */
+ 	if (c & 0x80) {
+ 	  /* In PGP block have type byte which have higgest bit set always. 
+ 	   * so if in first byte have higgest bit set assume PGP binary
+ 	   * file.
+ 	   */
+ 	  dprint (4, (debugfile, 
+ 		      "pgp_decode: first byte = %d -- assume binary PGP file\n",
+ 		    c));
+ 	  was_binary = 1; 
+ 	  goto pgp_found;
+ 	}
+ 	/* Another check */
+ 	for (i = 0; i < len; i++) {
+ 	  if (buffer[i] == 0) {
+ 	    dprint (4, (debugfile, 
+ 			"pgp_decode: byte idx=%d is zero -- binary file?\n",
+ 			i));
+ 	    state_puts(catgets(elm_msg_cat, MeSet, MePgpBinary,
+ 			       "[Binary file, but does not look like PGP]\n"),
+ 		       s_out);
+ 	    was_binary = 1; 
+ 	    goto pgp_found;
+ 	  }
+ 	}
+       }
+       if (strncmp(buffer, "-----BEGIN PGP", 14) == 0) 
+ 	goto pgp_found;
+ 
+       state_puts(catgets(elm_msg_cat, MeSet, MePgpBefore,
+ 			 "[There is text before PGP section.]\n"),
+ 		 s_out);
+ 
+       if (set_filter(m,s_out)) { /* Character set filtering */
+ 	do {
+ 	  state_add_prefix(s_out);
+ 
+ 	  /* Take care of CRLF => LF conversion in here because
+ 	   * arrange_decoded() is treating application/pgp as
+ 	   * binary type (it need to treate it as binary because
+ 	   * it may be binary)
+ 	   */
+ 	  if (!was_text &&
+ 	      len > 1 &&
+ 	      buffer[len - 1] == '\n' &&
+ 	      buffer[len - 2] == '\r') {
+ 	    buffer[len - 2] = '\n';
+ 	    buffer[len - 1] = '\0';
+ 	    len--;
+ 	  }
+ 
+ 	  state_put(buffer,len,s_out);
+ 
+ 	} while ((len = state_getl (buffer, sizeof (buffer), &newstate2)) > 0
+ 		 && strncmp(buffer, "-----BEGIN PGP", 14) != 0);
+ 
+       } else {
+ 	  dprint (4, (debugfile, 
+ 		      "pgp_decode: Unsupported character set?\n"));
+       }
+ 
+     pgp_found:
+       s_out -> filter = NULL_filter;
+     }
+ 
+   } else { 
+     if (opts & PGP_MESSAGE)
+       elm_sfprintf(buffer,sizeof buffer,
+ 		   CATGETS(elm_msg_cat, MeSet, MePgpEncodedCantEncoding,
+ 			   "-- Start of PGP encoded section -- can't decode content-transfer-encoding\n"));
+     else if (opts & PGP_SIGNED_MESSAGE)
+       elm_sfprintf(buffer,sizeof buffer,
+ 		   CATGETS(elm_msg_cat, MeSet, MePgpSignedCantEncoding,
+ 			   "-- Start of PGP signed section -- can't decode content-transfer-encoding\n"));
+     else
+       elm_sfprintf(buffer,sizeof buffer,
+ 		   CATGETS(elm_msg_cat, MeSet, MePgpCantEncoding,
+ 			   "-- Start of PGP section -- can't decode content-transfer-encoding\n"));
+     state_puts(buffer,s_out);    
+     return;
+   }
+ 
+   if ( len < 1) {
+     if (opts & PGP_MESSAGE)
+       elm_sfprintf(buffer,sizeof buffer,
+ 		   CATGETS(elm_msg_cat, MeSet, MePgpNoTextEncoded,
+ 			   "[No text in PGP encoded section]\n"));
+     else if (opts & PGP_SIGNED_MESSAGE)
+       elm_sfprintf(buffer,sizeof buffer,
+ 		   CATGETS(elm_msg_cat, MeSet, MePgpNoTextSigned,
+ 			   "[No text in PGP signed section]\n"));
+     else
+       elm_sfprintf(buffer,sizeof buffer,
+ 		   CATGETS(elm_msg_cat, MeSet, MePgpNoText,
+ 			   "[No text in PGP section]\n"));
+     state_puts(buffer,s_out);    
+     return;
+   }
+ 
+   if ((child = pgp_decrypt_init (&pgpout, &pgpin, opts)) == -1) {
+     if (was_binary) 
+       state_puts (catgets(elm_msg_cat, MeSet, MePgpInternalSkipping,
+ 			  "[Internal error while calling pgp, skipping...]\n"), 
+ 		  s_out);
+     else {
+       state_puts (catgets(elm_msg_cat, MeSet, MePgpInternalRawdata,
+ 			  "[Internal error while calling pgp, raw data follows]\n"), 
+ 		  s_out);
+ 
+       do {
+ 	state_add_prefix(s_out);
+ 	
+ 	if (len > 1 &&
+ 	    buffer[len - 1] == '\n' &&
+ 	    buffer[len - 2] == '\r') {
+ 	  buffer[len - 2] = '\n';
+ 	  buffer[len - 1] = '\0';
+ 	  len--;
+ 	}
+ 	
+ 	state_put(buffer,len,s_out);
+ 	bytes += len;
+       }  while ((len = state_getl (buffer, sizeof (buffer), 
+ 				   &newstate2)) > 0);
+ 
+       state_puts (catgets(elm_msg_cat, MeSet, MePgpRawEnd,
+ 			  "[End of raw data]\n"), 
+ 		  s_out);
+     }
+     return;
+   }
+ 
+ 
+   do {
+     fwrite(buffer,1,len,pgpin);
+     bytes += len;
+   }  while ((len = state_getl (buffer, sizeof (buffer), 
+ 			       &newstate2)) > 0);
+   
+   
+ 
+   fclose (pgpin);
+   
+   if (opts & PGP_MESSAGE)
+     elm_sfprintf(buffer,sizeof buffer,
+ 		 CATGETS(elm_msg_cat, MeSet, MePgpStartEncoded,
+ 			 "-- Start of PGP encoded section.\n"));
+   else if (opts & PGP_SIGNED_MESSAGE)
+     elm_sfprintf(buffer,sizeof buffer,
+ 		 CATGETS(elm_msg_cat, MeSet, MePgpStartSigned,
+ 			 "-- Start of PGP signed section.\n"));
+   else
+     elm_sfprintf(buffer,sizeof buffer,
+ 		 CATGETS(elm_msg_cat, MeSet, MePgpStart,
+ 			 "-- Start of PGP section.\n"));
+   state_puts(buffer,s_out);
+   
+   bytes = 0;
+     while ((len = mail_gets (buffer, sizeof (buffer), pgpout)) > 0) {
+       if (nested) {
+ 	if (buffer[0] == '\n' || (buffer[0] == '\r' && buffer[1] == '\n'))
+ 	  inbody = TRUE;
+ 	fputs (buffer, tmpfp);
+ 	if (inbody)
+ 	  bytes += len;
+       } else {
+ 	state_add_prefix(s_out);
+ 	state_puts(buffer,s_out);
+       }
+     }
+     fclose (pgpout);
+ 
+     if (nested) {
+       struct in_state s2_in;
+       in_state_clear(&s2_in,STATE_in_file);
+       
+       dprint (3, (debugfile, "pgp_decode: parsing decrypted data as MIME\n"));
+ 
+       if (EOF == fflush(tmpfp)) {
+ 	lib_error(CATGETS(elm_msg_cat, MeSet, MePgpErrorFlush,
+ 			  "Error when flushing temporary file."));
+ 	state_putc('[',s_out);
+ 	state_puts(catgets(elm_msg_cat, MeSet, MePgpErrorFlush,
+ 			   "Error when flushing temporary file."),
+ 		   s_out);
+ 	state_puts("]\n",s_out);
+       }
+       rewind(tmpfp); /* Rewind it for reading */
+ 
+       tmpmt = mime_read_header (tmpfp, 0);
+       tmpmt->length = bytes;
+ 
+       if (tmpmt->flags & MIME_RFC822) {
+ 	dprint(9,(debugfile,"pgp_decode- (parsing) RFC822\n"));
+ 	fseek (tmpfp, tmpmt->offset, SEEK_SET);
+ 	tmpmt->parts = rfc822_parse (tmpfp, tmpmt->length);
+       }
+       else if (tmpmt->type == MIME_TYPE_MULTIPART) {
+ 	char subbound[80];
+ 	fseek (tmpfp, tmpmt->offset, SEEK_SET);
+ 	mime_get_boundary (subbound, tmpmt->type_opts, sizeof (subbound));
+ 	dprint(9,(debugfile,
+ 		  "pgp_decode- (parsing) MULTIPART; boundary=%s\n",
+ 		  subbound));
+ 	tmpmt->parts = multipart_parse (tmpfp, tmpmt->length, subbound, 
+ 					tmpmt->flags);
+       }
+ 
+       set_in_state_file(tmpfp,&s2_in);
+ 
+       mime_decode (tmpmt, &s2_in, s_out);
+       mime_destroy (tmpmt);
+ 
+       in_state_destroy(&s2_in);
+ 
+       fclose (tmpfp);
+     }
+   
+   stat = wait_pgp(raw,child);
+ 
+   if (opts & PGP_MESSAGE)
+     elm_sfprintf(buffer,sizeof buffer,
+ 		 CATGETS(elm_msg_cat, MeSet, MePgpEndEncoded,
+ 			 "-- End of PGP encoded section%s\n"),
+ 		 stat ? catgets(elm_msg_cat, MeSet, MePgpFail,
+ 				", PGP failed!") : ".");
+   else if (opts & PGP_SIGNED_MESSAGE)
+     elm_sfprintf(buffer,sizeof buffer,
+ 		 CATGETS(elm_msg_cat, MeSet, MePgpEndSigned,
+ 			   "-- End of PGP signed section%s\n"),
+ 		 stat ?  catgets(elm_msg_cat, MeSet, MePgpFail,
+ 				 ", PGP failed!") : ".");
+   else
+     elm_sfprintf(buffer,sizeof buffer,
+ 		 CATGETS(elm_msg_cat, MeSet, MePgpEnd,
+ 			 "-- End of PGP section%s\n"),
+ 		 stat ? catgets(elm_msg_cat, MeSet, MePgpFail,
+ 				", PGP failed!") : ".");
+   state_puts(buffer,s_out);
+ 
+   in_state_destroy(&newstate2);
+ }
+ #endif /* MIME */
+ #endif /* USE_PGP */
Index: elm2.4.ME+.50/melib/state.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/melib/state.c	Tue Nov 17 21:12:56 1998
***************
*** 0 ****
--- 1,641 ----
+ static char rcsid[] = "@(#)$Id: state.c,v 1.2 1998/10/20 19:58:08 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *
+  *  Initially written by: Michael Elkins <elkins@aero.org>, 1995
+  *****************************************************************************/
+ 
+ #include "headers.h"
+ #include "melib.h"
+ 
+ int NULL_filter(c,st)
+      int c;          /* unsigned char assumed */
+      struct out_state * st;
+ {
+   st++;
+   return c;
+ }
+ 
+ static void state_panic P_((char *,int,char *, char *)); /* Prototype */
+ static void state_panic(f,ln,pr,ms) 
+      char * f;
+      int ln;
+      char *pr;
+      char *ms;
+ {
+   int do_cursor = RawState();
+ 
+   dprint(1,(debugfile,"\nSTATE PANIC in %s:%d:%s\n",f,ln,pr));
+   dprint(1,(debugfile,">>%s\n",ms));
+ 
+   /* softkeys_off(); */
+ 
+   if (do_cursor) {
+     lib_error(FRM("STATE PANIC: %s"),ms);
+     sleep(1);
+   }
+ 
+   if (do_cursor) {
+     MoveCursor(elm_LINES, 0);
+     Raw(OFF);
+   }
+ 
+   fprintf(stderr,"\nSTATE PANIC in %s:%d:%s\n",f,ln,pr);
+   fprintf(stderr,">>%s\n",ms);
+ 
+ #if DEBUG
+   if (debug > 10) {
+     fprintf(stderr,"ABORTING...\n");
+     fflush(stderr);
+     abort();
+   }
+ #endif
+   emergency_exit();
+ }
+ 
+ static void init_si_file P_((in_state_t *)); /* Prototype */
+ static void init_si_file(s)
+      in_state_t *s;
+ {
+   s->magic  = STATE_in_file;
+   s->u.file.fpin = NULL;
+ }
+ 
+ static void init_si_string P_((in_state_t *)); /* Prototype */
+ static void init_si_string(s)
+      in_state_t *s;
+ {
+   s->magic  = STATE_in_string;
+   s->u.string.inbuf = NULL;
+   s->u.string.inreadp = NULL;
+ }
+ 
+ void in_state_clear (s,m)
+      in_state_t *s;
+      int m;
+ {
+   s->magic = 0;  /* Not initilized yet */
+ 
+   switch(m) {
+   case STATE_in_file:   init_si_file(s);   break;
+   case STATE_in_string: init_si_string(s); break;
+   default:
+     state_panic(__FILE__,__LINE__,"in_state_clear","Bad magic number");
+   }
+ }
+ 
+ static void dest_si_file P_((in_state_t *)); /* Prototype */
+ static void dest_si_file(s)
+      in_state_t *s;
+ {
+   if (s->magic  != STATE_in_file)
+     state_panic(__FILE__,__LINE__,"dest_si_file","Bad magic number");
+   s->u.file.fpin = NULL;
+ }
+ 
+ static void dest_si_string P_((in_state_t *)); /* Prototype */
+ static void dest_si_string(s)
+      in_state_t *s;
+ {
+   if (s->magic  != STATE_in_string)
+     state_panic(__FILE__,__LINE__,"dest_si_string","Bad magic number");
+ 
+   if (s->u.string.inbuf)
+     free(s->u.string.inbuf);
+   
+   s->u.string.inbuf = NULL;
+   s->u.string.inreadp = NULL;
+ }
+ 
+ void in_state_destroy (s)
+      in_state_t *s;
+ {
+   switch(s->magic) {
+   case STATE_in_file:   dest_si_file(s);   break;
+   case STATE_in_string: dest_si_string(s); break;
+   default:
+     state_panic(__FILE__,__LINE__,"in_state_destroy","Bad magic number");
+   }
+   s->magic = 0; /* State destroyed */
+ }
+ 
+ void set_in_state_buffer (c, s)
+      char *c;
+      in_state_t *s;
+ {
+   if (s->magic  != STATE_in_string)
+     state_panic(__FILE__,__LINE__,"set_in_state_buffer","Bad magic number");
+   
+   if (s->u.string.inbuf)
+     state_panic(__FILE__,__LINE__,"set_in_state_buffer","Already called");
+   
+   s->u.string.inreadp = s->u.string.inbuf = strmcpy (s->u.string.inbuf, c);
+ }
+ 
+ void set_in_state_file (F, s)
+      FILE *F;
+      in_state_t *s;
+ {
+   if (s->magic  != STATE_in_file)
+     state_panic(__FILE__,__LINE__,"set_in_state_file","Bad magic number");
+ 
+   if (s->u.file.fpin)
+     state_panic(__FILE__,__LINE__,"set_in_state_file","Already called");
+ 
+   s->u.file.fpin = F;
+ }
+ 
+ int in_state_seekable (s)
+      in_state_t *s;
+ {
+   switch(s->magic) {
+   case STATE_in_file:   return 1;   
+   case STATE_in_string: return 0; 
+   default:
+     state_panic(__FILE__,__LINE__,"in_state_seekable","Bad magic number");
+   }
+ 
+   return 0;
+ }
+ 
+ int in_state_fseek (s,pos)
+      in_state_t *s;
+      long pos;
+ {
+   if (s->magic  != STATE_in_file)
+     state_panic(__FILE__,__LINE__,"in_state_fseek","Bad magic number");
+ 
+   if (s->u.file.fpin == NULL)
+     state_panic(__FILE__,__LINE__,"in_state_fseek","NULL file pointer");
+ 
+   return fseek(s->u.file.fpin,pos,SEEK_SET);
+ }
+ 
+ long in_state_ftell (s)
+      in_state_t *s;
+ {
+   if (s->magic  != STATE_in_file)
+     state_panic(__FILE__,__LINE__,"in_state_ftell","Bad magic number");
+   
+   if (s->u.file.fpin == NULL)
+     state_panic(__FILE__,__LINE__,"in_state_ftell","NULL file pointer");
+ 
+   return ftell(s->u.file.fpin);
+ }
+ 
+ FILE * in_state_FILE (s) 
+      in_state_t *s;
+ {
+   if (s->magic  != STATE_in_file)
+     state_panic(__FILE__,__LINE__,"in_state_FILE","Bad magic number");
+ 
+   if (s->u.file.fpin == NULL)
+     state_panic(__FILE__,__LINE__,"in_state_FILE","NULL file pointer");
+   
+   return s->u.file.fpin;
+ }
+ 
+ static int getc_si_file P_((in_state_t *)); /* Prototype */
+ static int getc_si_file(s)
+      in_state_t *s;
+ {
+   if (s->magic  != STATE_in_file)
+     state_panic(__FILE__,__LINE__,"getc_si_file","Bad magic number");
+   if (s->u.file.fpin == NULL)
+     state_panic(__FILE__,__LINE__,"getc_si_file","NULL filepointer");
+ 
+   return fgetc (s->u.file.fpin);
+ }
+ 
+ static int getc_si_string P_((in_state_t *)); /* Prototype */
+ static int getc_si_string(s)
+      in_state_t *s;
+ {
+   if (s->magic  != STATE_in_string)
+     state_panic(__FILE__,__LINE__,"getc_si_string","Bad magic number");
+ 
+   if (s->u.string.inbuf) {
+     unsigned char ret;
+ 
+     if (! *s->u.string.inreadp) {
+       /* No more data left in the buffer, so clean up... */
+       s->u.string.inreadp = NULL;
+       free (s->u.string.inbuf);
+       s->u.string.inbuf = NULL;
+       return EOF;
+     }
+     
+     if (*s->u.string.inreadp)
+       ret = (unsigned char) *s->u.string.inreadp++;
+     return ret;
+   }
+   
+   dprint(5, (debugfile, "getc_si_string: inbuf==NULL\n"));
+   return EOF;
+ }
+ 
+ int state_getc (s)
+      in_state_t *s;
+ {
+   switch(s->magic) {
+   case STATE_in_file:   return getc_si_file(s);   
+   case STATE_in_string: return getc_si_string(s); 
+   default:
+     state_panic(__FILE__,__LINE__,"state_getc","Bad magic number");
+   }
+ 
+   return EOF;
+ }
+ 
+ static int ungetc_si_file P_((int,in_state_t *)); /* Prototype */
+ static int ungetc_si_file (c,s)
+      int c;
+      in_state_t *s;
+ {
+   if (s->magic  != STATE_in_file)
+     state_panic(__FILE__,__LINE__,"ungetc_si_file","Bad magic number");
+   if (s->u.file.fpin == NULL)
+     state_panic(__FILE__,__LINE__,"umgetc_si_file","NULL filepointer");
+ 
+   return ungetc(c,s->u.file.fpin);
+ }
+ 
+ static int ungetc_si_string P_((int,in_state_t *)); /* Prototype */
+ static int ungetc_si_string (c,s)
+      int c;
+      in_state_t *s;
+ {
+   if (s->magic  != STATE_in_string)
+     state_panic(__FILE__,__LINE__,"ungetc_si_string","Bad magic number");
+ 
+   if (s->u.string.inbuf) {
+     if (s->u.string.inreadp > s->u.string.inbuf) {
+       return *(--(s->u.string.inreadp));
+     } else {
+       dprint(5, (debugfile, "ungetc_si_string: In beginning of buffer.\n"));
+       return EOF;
+     }
+   } else {
+     dprint(5, (debugfile, "ungetc_si_string: inbuf==NULL\n"));
+     return EOF;
+   }
+ }
+ 
+ int state_ungetc (c,s)
+      int c;
+      in_state_t *s;
+ {
+   switch(s->magic) {
+   case STATE_in_file:   return ungetc_si_file(c,s);   
+   case STATE_in_string: return ungetc_si_string(c,s); 
+   default:
+     state_panic(__FILE__,__LINE__,"state_ungetc","Bad magic number");
+   }
+   return EOF;
+ }
+ 
+ 
+ static char *gets_si_file P_((char *, int, in_state_t *));
+ static char *gets_si_file (dest, length, s)
+      char *dest;
+      int length;
+      in_state_t *s;
+ {
+   if (s->magic  != STATE_in_file)
+     state_panic(__FILE__,__LINE__,"gets_si_file","Bad magic number");
+   if (s->u.file.fpin == NULL)
+     state_panic(__FILE__,__LINE__,"gets_si_file","NULL filepointer");
+   
+   return (fgets (dest, length, s->u.file.fpin));
+ }
+ 
+ static int getl_si_file P_((char *, int, in_state_t *));
+ static int getl_si_file (dest, length, s)
+      char *dest;
+      int length;
+      in_state_t *s;
+ {
+   if (s->magic  != STATE_in_file)
+     state_panic(__FILE__,__LINE__,"getl_si_file","Bad magic number");
+   if (s->u.file.fpin == NULL)
+     state_panic(__FILE__,__LINE__,"getl_si_file","NULL filepointer");
+   
+   return (mail_gets (dest, length, s->u.file.fpin));
+ }
+ 
+ 
+ static int getl_si_string P_((char *, int, in_state_t *));
+ static int getl_si_string (dest, length, s)
+      char *dest;
+      int length;
+      in_state_t *s;
+ {
+   int i = 0, ch;
+   
+   if (s->magic  != STATE_in_string)
+     state_panic(__FILE__,__LINE__,"getl_si_string","Bad magic number");
+ 
+   while (length > 1) {
+     ch = getc_si_string (s);
+     if (ch == EOF)
+       break;
+     else if (ch == '\n') {
+       dest[i++] = '\n';
+       break;
+     }
+     else
+       dest[i++] = ch;
+     length--;
+   }
+   dest[i] = '\0';
+   return i;
+ }
+   
+ static char *gets_si_string P_((char *, int, in_state_t *));
+ static char *gets_si_string (dest, length, s)
+      char *dest;
+      int length;
+      in_state_t *s;
+ {
+   int len;
+ 
+   if (s->magic  != STATE_in_string)
+     state_panic(__FILE__,__LINE__,"getl_si_string","Bad magic number");
+ 
+   len = getl_si_string (dest, length, s);
+   if (len > 0)
+     return dest;
+   else
+     return NULL;
+ }
+ 
+ char *state_gets (dest, length, s)
+      char *dest;
+      int length;
+      in_state_t *s;
+ {
+   switch(s->magic) {
+   case STATE_in_file:   return gets_si_file(dest,length,s);   
+   case STATE_in_string: return gets_si_string(dest,length,s); 
+   default:
+     state_panic(__FILE__,__LINE__,"state_gets","Bad magic number");
+   }
+   return NULL;
+ }
+ 
+ int state_getl (dest, length, s)
+      char *dest;
+      int length;
+      in_state_t *s;
+ {
+   switch(s->magic) {
+   case STATE_in_file:   return getl_si_file(dest,length,s);   
+   case STATE_in_string: return getl_si_string(dest,length,s); 
+   default:
+     state_panic(__FILE__,__LINE__,"state_getl","Bad magic number");
+   }
+   return 0;
+ }
+ 
+ 
+ static void init_so_file P_((out_state_t *)); /* Prototype */
+ static void init_so_file(s)
+      out_state_t *s;
+ {
+   s->magic   = STATE_out_file;
+   s->u.file.fpout = NULL;
+ }
+ 
+ static void init_so_string P_((out_state_t *)); /* Prototype */
+ static void init_so_string(s)
+      out_state_t *s;
+ {
+   s->magic        = STATE_out_string;
+   s->u.string.outbuf     = NULL;
+   s->u.string.outwritep  = NULL;
+   s->u.string.outbufsize = 0;
+ }
+ 
+ void out_state_clear (s,m)
+      out_state_t *s;
+      int m;
+ {
+   s->magic = 0;  /* Not initilized yet */
+ 
+   s->displaying = 0;
+   s->prefix     = NULL;
+   s->filter     = NULL_filter;
+ 
+   switch(m) {
+   case STATE_out_file:   init_so_file(s);   break;
+   case STATE_out_string: init_so_string(s); break;
+   default:
+     state_panic(__FILE__,__LINE__,"out_state_clear","Bad magic number");
+   }
+ }
+ 
+ static void dest_so_file P_((out_state_t *)); /* Prototype */
+ static void dest_so_file(s)
+      out_state_t *s;
+ {
+   if (s->magic   != STATE_out_file)
+     state_panic(__FILE__,__LINE__,"dest_so_file","Bad magic number");
+   s->u.file.fpout = NULL;
+ }
+ 
+ static void dest_so_string P_((out_state_t *)); /* Prototype */
+ static void dest_so_string(s)
+      out_state_t *s;
+ {
+   if (s->magic        != STATE_out_string)
+     state_panic(__FILE__,__LINE__,"dest_so_string","Bad magic number");
+ 
+   s->u.string.outbuf     = NULL;
+   s->u.string.outwritep  = NULL;
+   s->u.string.outbufsize = 0;
+ }
+ 
+ void out_state_destroy (s)
+      out_state_t *s;
+ {
+ 
+   switch(s->magic) {
+   case STATE_out_file:   dest_so_file(s);   break;
+   case STATE_out_string: dest_so_string(s); break;
+   default:
+     state_panic(__FILE__,__LINE__,"out_state_destroy","Bad magic number");
+   }
+ 
+   s->displaying = 0;
+   s->prefix     = NULL;
+   s->filter     = NULL_filter;
+   s->magic      = 0; /* No longer initialized */
+ }
+ 
+ void set_out_state_buffer (buffer,size,s)
+      char * buffer;
+      int size;
+      out_state_t *s;
+ {
+   if (s->magic        != STATE_out_string)
+     state_panic(__FILE__,__LINE__,"set_out_state_buffer","Bad magic number");
+ 
+   if (s->u.string.outbuf     != NULL)
+     state_panic(__FILE__,__LINE__,"set_out_state_buffer","Already called");
+ 
+   s->u.string.outbuf     = buffer;
+   s->u.string.outwritep  = buffer;
+   s->u.string.outbufsize = size;
+ }
+ 
+ void out_state_ref_buffer (s,p,len)
+      out_state_t *s;
+      char **p;
+      int *len;
+ {
+   if (s->magic        != STATE_out_string)
+     state_panic(__FILE__,__LINE__,"out_state_ref_buffer","Bad magic number");
+ 
+   if (s->u.string.outbuf     == NULL)
+     state_panic(__FILE__,__LINE__,
+ 		"out_state_ref_buffer","NULL buffer pointer");
+ 
+   *p   = s->u.string.outbuf;
+   *len = s->u.string.outwritep - s->u.string.outbuf;
+ }
+ 
+ void set_out_state_file (file,s)
+      FILE * file;
+      out_state_t *s;
+ {
+   if (s->magic   != STATE_out_file)
+     state_panic(__FILE__,__LINE__,"set_out_state_file","Bad magic number");
+   if (s->u.file.fpout != NULL)
+     state_panic(__FILE__,__LINE__,"set_out_state_file","Already called");
+   s->u.file.fpout = file;
+ }
+ 
+ static int putc_so_file P_((out_state_t *, int)); /* Prototype */
+ static int putc_so_file(s,ch)
+      out_state_t *s;
+      int ch;
+ {
+   int res;
+   if (s->magic   != STATE_out_file)
+     state_panic(__FILE__,__LINE__,"putc_so_file","Bad magic number");
+   if (s->u.file.fpout == NULL)
+     state_panic(__FILE__,__LINE__,"putc_so_file","NULL file pointer");
+ 
+   res = s-> filter(ch,s);
+ 
+   if (res < 0) /* Destroy char */
+     return EOF;
+ 
+   return (fputc (res, s->u.file.fpout));
+ }
+ 
+ static int putc_so_string P_((out_state_t *, int)); /* Prototype */
+ static int putc_so_string(s,ch)
+      out_state_t *s;
+      int ch;
+ {
+   int res;
+   if (s->magic   != STATE_out_string)
+     state_panic(__FILE__,__LINE__,"putc_so_string","Bad magic number");
+   if (s->u.string.outbuf == NULL)
+     state_panic(__FILE__,__LINE__,"putc_so_string","NULL buffer pointer");
+ 
+   res = s-> filter(ch,s);
+ 
+   if (res < 0) /* Destroy char */
+     return EOF;
+ 
+   if (s->u.string.outbuf - s->u.string.outbuf < s->u.string.outbufsize-1) {
+     *s->u.string.outwritep++ = res;
+     *s->u.string.outwritep = '\0';
+     return res;
+   }
+   else
+     return EOF;
+ }
+ 
+ int state_putc (ch, s)
+      int ch;                        /* unsigned char assumed */
+      out_state_t *s;
+ {
+   switch(s->magic) {
+   case STATE_out_file:   return putc_so_file(s,ch);   break;
+   case STATE_out_string: return putc_so_string(s,ch); break;
+   default: state_panic(__FILE__,__LINE__,"state_putc","Bad magic number");
+   }
+   return EOF;
+ }
+ 
+ static int put_so_file P_((out_state_t *, char *,int)); /* Prototype */
+ static int put_so_file(s,string,len)
+      out_state_t *s;
+      char *string;
+      int len;
+ {
+   if (s->magic   != STATE_out_file)
+     state_panic(__FILE__,__LINE__,"put_so_file","Bad magic number");
+   if (s->u.file.fpout == NULL)
+     state_panic(__FILE__,__LINE__,"put_so_file","NULL file pointer");
+ 
+   if (s->filter == NULL_filter)
+     return fwrite (string, 1, len, s->u.file.fpout);
+   else {
+     int count;
+     
+     for (count = 0; count < len; count++) {
+       if (putc_so_file (s,(unsigned char) string[count]) == EOF)
+ 	return (count > 0 ? count : EOF);
+     }
+     return count;
+   }
+ }
+ 
+ static int put_so_string P_((out_state_t *, char *,int)); /* Prototype */
+ static int put_so_string(s,string,len)
+      out_state_t *s;
+      char *string;
+      int len;
+ {
+   int count;
+ 
+   if (s->magic   != STATE_out_string)
+     state_panic(__FILE__,__LINE__,"put_so_string","Bad magic number");
+   if (s->u.string.outbuf == NULL)
+     state_panic(__FILE__,__LINE__,"put_so_string","NULL buffer pointer");
+     
+   for (count = 0; count < len; count++) {
+     if (putc_so_string (s,(unsigned char) string[count]) == EOF)
+       return (count > 0 ? count : EOF);
+   }
+   return count;
+ }
+ 
+ int state_put (string, len, s)
+      char *string;
+      int len;
+      out_state_t *s;
+ {
+   switch(s->magic) {
+   case STATE_out_file:   return put_so_file(s,string,len);   break;
+   case STATE_out_string: return put_so_string(s,string,len); break;
+   default:  state_panic(__FILE__,__LINE__,"state_put","Bad magic number");
+   }
+   return EOF;
+ }
+ 
+ int state_puts (string, state)
+      char *string;
+      out_state_t *state;
+ {
+   return state_put(string,strlen(string),state);
+ }
+ 
+ 
Index: elm2.4.ME+.50/hdrs/melib.h
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/hdrs/melib.h	Tue Nov 17 21:12:55 1998
***************
*** 0 ****
--- 1,248 ----
+ /* $Id: melib.h,v 1.3 1998/10/20 20:04:45 hurtta Exp $ */
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.3 $   $State: Exp $
+  *
+  *  Author: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *****************************************************************************/
+ 
+ /* melib.h */
+ 
+ #undef P_
+ #ifdef __STDC__
+ #define P_(x) x
+ #else
+ #define P_(x) ()
+ #endif
+ 
+ /** Definitions for state operations **/
+ 
+ struct in_state;
+ struct out_state;
+ 
+ /* can't be 'char' as argumnet because problems of default
+  * promotion rules of arguments -- therefore 'int' is used
+  * in functios: state_filter, state_putc
+  *
+  * Notice also that we assumen here that char agument (as int)
+  * is 'unsigned char'
+  *
+  *  - K E H
+  */
+ 
+ typedef int state_filter P_((int, struct out_state *));
+ 
+ /* state magics */
+ #define   STATE_in_file      0xFA01
+ #define   STATE_in_string    0xFA02
+ 
+ #define   STATE_out_file     0xFB01
+ #define   STATE_out_string   0xFB02
+ 
+ typedef struct {
+   FILE *fpin;
+ } in_state_file;
+ 
+ typedef struct {
+   char *inbuf;
+   char *inreadp;
+ } in_state_string;
+ 
+ typedef struct in_state {
+   unsigned short magic;
+ 
+   union {
+     in_state_file    file;
+     in_state_string  string;
+   } u;
+ } in_state_t;
+ 
+ typedef struct {
+   FILE *fpout;
+ } out_state_file;
+ 
+ typedef struct {
+   char *outbuf;
+   char *outwritep;
+   int outbufsize;
+ } out_state_string;
+ 
+ 
+ typedef struct out_state {
+   unsigned short magic;
+ 
+   unsigned int displaying : 1;
+   char *prefix;
+ 
+   state_filter * filter;
+ 
+   union {
+     out_state_file    file;
+     out_state_string  string;
+   } u;
+ } out_state_t;
+ 
+ #define state_add_prefix(x) if((x)->prefix)state_puts((x)->prefix,x)
+ 
+ extern void in_state_clear   P_((in_state_t *, int));
+ extern void in_state_destroy P_((in_state_t *));
+ 
+ extern void set_in_state_buffer P_((char *,in_state_t *));   /* STATE_in_string */
+ extern void set_in_state_file   P_((FILE *,in_state_t *));   /* STATE_in_file */
+ 
+ extern int  in_state_seekable P_((in_state_t *)); 
+ extern int  in_state_fseek P_((in_state_t *, long)); /* STATE_in_file */
+ extern long in_state_ftell P_((in_state_t *));       /* STATE_in_file */
+ extern FILE * in_state_FILE P_((in_state_t *)); /* STATE_in_file */
+ 
+ extern char *state_gets P_((char *, int, in_state_t *));
+ extern int   state_getl P_((char *, int, in_state_t *));
+ extern int   state_getc P_((in_state_t *s));
+ extern int   state_ungetc P_((int,in_state_t *));
+ 
+ extern void out_state_clear   P_((out_state_t *, int));
+ extern void out_state_destroy P_((out_state_t *));
+ 
+ /* STATE_out_string */
+ extern void set_out_state_buffer P_((char *,int,out_state_t *));
+ extern void set_out_state_file   P_((FILE *,out_state_t *));  /* STATE_out_file */
+ 
+ extern int state_put  P_((char *, int, out_state_t *));
+ extern int state_puts P_((char *, out_state_t *));
+ extern int state_putc P_((int,  out_state_t *));
+ 
+ /* STATE_out_string */
+ extern void out_state_ref_buffer P_((out_state_t *, char **, int*));
+ 
+ extern int NULL_filter P_((int, struct out_state *));
+ 
+ #ifdef USE_PGP
+ /* pgp_decode.c */
+ extern int have_pgp                     P_((void));
+ extern void pgp_void_passphrase         P_((void));
+ extern int pgp_goodPassphrase           P_((void));
+ extern int pgp_decrypt_init		P_((FILE **, FILE **, int));
+ #ifdef MIME
+ extern void pgp_decode  		P_((mime_t *, 
+ 					    in_state_t *, out_state_t *));
+ #endif
+ #endif
+ 
+ /* parse_util.c */
+ 
+ extern char * parse_dequote P_((const char * quoted));
+ typedef void decoder_hack_func P_((char *ptr, int len));
+ typedef decoder_hack_func *decoder_hack;
+ extern char * parse_decomment P_((const char *quoted,
+ 				  decoder_hack decode_mime));
+ extern void null_decoder_hack P_((char *ptr, int len));
+ 
+ typedef void encoder_hack_func P_((char *buf,int size,
+ 				    const char *source,int flag));
+ typedef encoder_hack_func *encoder_hack;
+ extern void null_encoder_hack P_((char *buf,int size,
+ 				  const char *source,int flag));
+ 
+ typedef struct header_info {
+   char * header;
+   int flag;
+ } * header_ptr;
+ 
+ #define HEADER_magic        0xFC00
+ 
+ typedef struct header_list {
+   unsigned short magic;
+   header_ptr header_name;
+   struct header_list * next_this_header;
+   struct header_list * next_header;
+   struct header_list * next_other_header;
+   char * body;
+ } * header_list_ptr;
+ 
+ #define   RHL_MARK_FOLDING      1
+ #define   RHL_CHECK_HEADER      2
+ 
+ extern void rfc822_reap_comments        P_((char *, char *, int));
+ extern int read_header_line             P_((FILE *,char *,int,int));
+ extern int state_read_hdr_line          P_((in_state_t *,char *, int, int));
+ 
+ typedef int header_filter    P_((header_list_ptr, int));
+ typedef void header_converter P_((header_list_ptr, int, char *, int));
+ 
+ extern int NULL_header_filter    P_((header_list_ptr, int));
+ extern void NULL_header_converter P_((header_list_ptr, int, char *, int));
+ 
+ extern void state_write_headers P_((out_state_t *,header_list_ptr,
+ 				    header_filter *, header_converter *,
+ 				    int));
+ 
+ extern header_list_ptr state_read_headers P_((in_state_t *, int));
+ extern header_list_ptr file_read_headers  P_((FILE *, int));
+ extern void delete_headers                P_((header_list_ptr));
+ extern header_list_ptr locate_header      P_((header_list_ptr,header_ptr));
+ 
+ extern header_ptr find_header           P_((char *,int));
+ extern int classify_header              P_((char *));
+ 
+ #define locate_header_by_name(h,n)      locate_header(h,find_header(n,0))
+ 
+ extern long skip_envelope P_((struct header_rec *hdr, FILE *fp));
+ 
+ 
+ 
+ #ifdef MIME
+ 
+ /* mime.c */
+ 
+ extern void mime_panic          P_((char *,int,char *, char *));
+ extern int check_encoding       P_((char *));
+ extern int charset_ok           P_((char *));
+ /* mime_decode.c */
+ 
+ extern char * blstrpbrk P_((char *string, const char *set));
+ extern void base64_decode	P_((in_state_t *, out_state_t *, int, int));
+ extern void quoted_printable_decode  P_((in_state_t *, out_state_t *,
+ 					 int, int));
+ extern void null_decode		P_((mime_t *, in_state_t *, out_state_t *));
+ extern void mime_decode		P_((mime_t *, in_state_t *, out_state_t *));
+ extern void rfc1522_decode P_((char *, int));
+ extern void rfc1522_decode_structured   P_((int, char *, int));
+ extern int rfc1522_decode_encoded_atom P_((char *trg,int trg_len,
+ 					   const char * src));
+ 
+ extern int is_rfc1522 P_((char *));
+ 
+ extern int set_filter	P_((mime_t *, out_state_t *)); 
+ extern FILE *arrange_decoded P_((mime_t *,in_state_t  *,
+ 			      out_state_t *,in_state_t *));
+ 
+ typedef void CT_decoder	        P_((mime_t *, in_state_t *, out_state_t *));
+ typedef CT_decoder *CT_decoder_t;
+ extern CT_decoder_t select_CT_decoder	P_((mime_t *));
+ 
+ /* mime_parse.c */
+ 
+ extern mime_t *mime_t_alloc             P_((void));
+ extern void mime_t_copy                 P_((mime_t *, mime_t *));
+ extern void mime_t_zero                 P_((mime_t *));
+ extern void mime_destroy		P_((mime_t *));
+ extern void mime_get_disposition        P_((char *, mime_t *));
+ extern void mime_get_content		P_((char *, mime_t *));
+ extern int class_charset                P_((char *));
+ extern int mime_get_charset             P_((char *, char *, int));
+ extern char * mime_parse_content_opts	P_((char *));
+ extern int mime_get_param               P_((char *,char *,char *,int));
+ extern void mime_warnings		P_((struct header_rec *));
+ extern mime_t *rfc822_parse		P_((FILE *, int));
+ extern mime_t * multipart_parse         P_((FILE *, int, char *, int));
+ extern void mime_get_boundary           P_((char *, char *, int));
+ 
+ extern void attach_parse		P_((struct header_rec *,FILE *));
+ extern mime_t *mime_read_header         P_((FILE *, int));
+ extern mime_t *parse_mime_headers       P_((header_list_ptr,long,long,int));
+ 
+ #endif
+ 
+ /* Used  by bgp_decode.c */
+ 
+ extern int optionally_enter P_((char *, int, int, int, int));
Index: elm2.4.ME+.50/hdrs/elmlib.h
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/hdrs/elmlib.h	Tue Nov 17 21:14:09 1998
***************
*** 0 ****
--- 1,560 ----
+ /* $Id: elmlib.h,v 1.6 1998/11/08 18:21:22 hurtta Exp $ */
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.6 $   $State: Exp $
+  *
+  *  Author: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *****************************************************************************/
+ 
+ /* elmlib.h */
+ 
+ #undef P_
+ #ifdef __STDC__
+ #define P_(x) x
+ #else
+ #define P_(x) ()
+ #endif
+ 
+ /* lib/strmcpy.c */
+ 
+ extern char *strmcpy P_((char *, const char *));
+ extern char *strmcat P_((char *, const char *));
+ 
+ /* safeopen.c */
+ 
+ extern FILE *safeopen P_((char *));
+ extern FILE *safeopen_rdwr P_((char *));
+ 
+ /* istrcmp.c */
+ 
+ extern int istrcmp P_((char *, char *));
+ 
+ /* add_site.c */
+ 
+ extern int add_site P_((char *, char *, char *, int));
+ 
+ /* addrmchusr.c */
+ 
+ extern int addr_matches_user P_((char *, char *));
+ 
+ /* atonum.c */
+ 
+ extern int atonum P_((char *));
+ 
+ /* mk_aliases.c */
+ 
+ extern int get_alias P_((FILE *,int));
+ extern int get_line P_((FILE *,char *,int, int));
+ extern void de_escape P_((char *));
+ extern int add_to_hash_table P_((char *,int32));
+ extern void add_to_table     P_((FILE *,char *, char *, char *, 
+ 				 char *, char *));
+ extern int check_alias       P_((char *));
+ extern int check_address     P_((char *));
+ extern void put_alias        P_((FILE *));
+ extern int do_newalias       P_((char *, char *,int, int));
+ 
+ /* aliasdb.c */
+ 
+ /* fetch_alias */
+ extern char *next_addr_in_list P_((char **));
+ 
+ /* mk_lockname */
+      
+ extern char * mk_lockname P_((char *));
+ 
+ /* can_access.c */
+ /* I don't understand this routine! access -system call uses
+  * real uid / gid anyway!!!!!!!!!!!!!!
+  *
+  *                                - K E H <hurtta@ozone.FMI.FI>
+  */
+ 
+ extern int can_access P_((char *,int));
+ 
+ /* can_open.c */
+ 
+ extern int can_open P_((char *, char *));
+ 
+ /* chloc.c */
+ 
+ /* Is this really needed? This does same than strchr or index, except
+  *  that return type is different.
+  *
+  *                          - K E H <hurtta@ozone.FMI.FI>
+  */
+ 
+ /* Argument (second) can't be char because there is both prototype and
+  * non-prototype declaration.
+  */
+ extern int chloc  P_((char *,int));
+ extern int qchloc P_((char *, int));
+ 
+ /* date_util.c */
+ 
+ extern int cvt_dayname_to_daynum     P_((char *,int *));
+ extern int cvt_monthname_to_monthnum P_((char *,int *));
+ extern int cvt_yearstr_to_yearnum    P_((char *,int *));
+ extern int cvt_mmddyy_to_dayofyear   P_((int, int, int, int*));
+ extern int cvt_timezone_to_offset    P_((char *str,int *, int));
+ extern int cvt_numtz_to_mins         P_((char *));
+ extern int cvt_timestr_to_hhmmss     P_((char *, int *, int *, int *));
+ extern long make_gmttime             P_((int, int, int, int, int, int));
+ 
+ /* dispaddr.c */
+ 
+ typedef void decode_who P_((int class, char *ptr, int size));
+ extern int DisplayAddress  P_((struct header_rec *,char *,int, decode_who));
+ 
+ /* errno.c */
+ 
+ extern char *error_description P_((int));
+ 
+ /* expnad.c */
+ 
+ extern int expand P_((char *, int));
+ 
+ /* figadrssee.c */
+ 
+ extern void figure_out_addressee P_((char *, char *, int));
+ 
+ /* gcos_name.c */
+ 
+ extern char * gcos_name          P_((char *, char *));
+ 
+ /* get_tz.c */
+ 
+ struct tm;  /* We need here only incomplete defination */
+ 
+ extern int get_tz_mins   P_((void));
+ extern char *get_tz_name P_((struct tm *));
+ 
+ /* getaddr.c */
+ 
+ extern void free_rfc822tokenized   P_((char **res));
+ /* Removes comments from vector: */
+ extern void remove_space_tokenized P_((char ** tokenized));
+ extern char **rfc822_tokenize      P_((const char *line));
+ 
+ extern struct addr_item {
+   char *addr;
+   char *fullname;
+ } * break_down_address P_((const char *buffer, decode_who decoder));
+ 
+ extern void  free_addr_items P_((struct addr_item *list));
+ 
+ /* getaddrfrm.c */
+ 
+ extern void get_address_from P_((char *, char *, int size));
+ 
+ /* getarpdate.c */
+ 
+ extern char * get_arpa_date P_((void));
+ 
+ /* getfullnam.c */
+ 
+ extern char * get_full_name P_((char *));
+ 
+ /* getword.c */
+ 
+ extern int get_word P_((const char *,int,char *,int));
+ 
+ /* getword.c */
+ 
+ extern char * header_cmp P_((char *, char *, char *));
+ 
+ /* in_list.c */
+ 
+ /* in_list should use quoted -variants (strtokq, ...)
+  *                            - K E H <hurtta@ozone.FMI.FI>
+  */
+ extern int in_list   P_((char *, const char *));
+ extern int globmatch P_(( char *, char *));
+ 
+ /* in_string.c */
+ 
+ /* Is that needed? This is almost same as strstr (except return type).
+  *                                     - K E H <hurtta@ozone.FMI.FI> 
+  */
+ extern int in_string P_((char *, char *));
+ 
+ /* istrcmp.c */
+ 
+ /* This is same than strcasecmp.   - K E H <hurtta@ozone.FMI.FI>  */
+ extern int istrcmp  P_((char *, char *));
+ 
+ /* ldstate.c */
+ 
+ /* load_folder_state_file */
+ 
+ /* len_next.c */
+ 
+ extern int len_next_part P_((const char *));
+ 
+ /* mail_gets.c */
+ 
+ extern int mail_gets P_((char *,int,FILE *));
+ 
+ /* move_left.c */
+ 
+ extern void move_left P_((char *,int));
+ 
+ /* okay_address.c */
+ 
+ extern int okay_address P_((char *, char *));
+ 
+ /* opt_utils.c */
+ 
+ #ifndef GETHOSTNAME
+ extern int gethostname P_((char *,int));
+ #endif
+ 
+ extern int gethostdomain P_((char *,int));
+ 
+ #ifndef HAS_CUSERID
+ extern char *cuserid P_((char *));
+ #ifndef L_cuserid
+ #define L_cuserid 9
+ #endif
+ #endif
+ 
+ #ifndef STRTOK
+ extern char *strtok  P_((char *, char *));
+ #endif
+ 
+ #ifndef STRPBRK
+ extern char *strpbrk     P_((char *, char *));
+ #endif
+ 
+ #ifndef STRSPN
+ extern int strspn        P_((char *, char *));
+ #endif
+ 
+ #ifndef STRCSPN
+ extern int strcspn       P_((char *, char *));
+ #endif
+ 
+ #ifndef TEMPNAM
+ extern char *tempnam     P_((char *, char *));
+ #endif
+ 
+ #ifndef GETOPT
+ extern int getopt P_((int,char	**, char *));
+ #endif
+ 
+ #ifndef RENAME
+ int rename P_((const char *, const char *fname));
+ #endif
+ 
+ /* parsarpdat.c */
+ 
+ extern int parse_date_time P_((const char *str, 
+ 			       char *time_zone, int size_time_zone,
+ 			       time_t *tz_offset, time_t *time_result));
+ 
+ struct header_rec;
+ extern int parse_arpa_date P_((char *str,
+ 			       struct header_rec *entry));
+ 
+ /* This perhaps should go away.   - K E H <hurtta@ozone.FMI.FI> */
+ 
+ extern void decode_who_none P_((int class, char *ptr, int size));
+ extern void parse_arpa_who P_((char *, char *,decode_who, int));
+ 
+ /* posixsig.c */
+ 
+ #ifdef POSIX_SIGNALS
+ extern SIGHAND_TYPE (*posig_signal  P_((int, 
+ 					SIGHAND_TYPE (*fun)P_((int))
+ 					))
+ 		     )P_((int));
+ #endif
+ #if defined(BSD_TYPE) && !defined(WEXITSTATUS)
+ typedef union wait S__;
+ #else
+ typedef int        S__;
+ #endif
+ 
+ extern int my_wait P_((int pid, S__ *statptr)); 
+ extern int convert_status P_((S__ status,int *exit_code));
+ 
+ /* putenv.c */
+ #ifndef PUTENV
+ extern int putenv   P_((char *));
+ #endif
+ 
+ /* realfrom.c */
+ 
+ /* real_from */
+ 
+ /* qstrings.c */
+ 
+ extern char *qstrpbrk   P_((char *, char *));
+ extern int qstrspn      P_((char *, char *));
+ extern int qstrcspn     P_((char *, char *));
+ 
+ /* remfirstwd.c */
+ 
+ void remove_first_word     P_((char *));
+ void remove_header_keyword P_((char *));
+ 
+ /* reverse.c */
+ 
+ extern void reverse P_((char *));
+ 
+ /* safemalloc.c */
+ 
+ extern void dflt_safe_malloc_fail_handler P_((char *proc,unsigned));
+ extern void (*safe_malloc_fail_handler)   P_((char *proc,unsigned));
+ 
+ extern malloc_t safe_malloc  P_((unsigned));
+ extern malloc_t safe_realloc P_((malloc_t,unsigned));
+ extern char *safe_strdup     P_((const char *));
+ 
+ /* shiftlower.c */
+ 
+ extern char *shift_lower     P_((const char *));
+ 
+ /* strfcpy */
+ 
+ extern char *strfcpy P_((char *, const char *, int));
+ extern char *strfcat P_((char *, const char *, int));
+ 
+ /* strincmp.c */
+ 
+ /* Is this needed? This is same than strncasecmp 
+  *        - K E H <hurtta@ozone.FMI.FI>
+  */
+ 
+ extern int strincmp P_((const char *, const char *, int));
+ 
+ /* striparens.c */
+ 
+ extern char *strip_parens P_((const char *s));
+ extern char *get_parens   P_((const char *s));
+ 
+ /* strstr.c */
+ 
+ /* Why there is both in_string and strstr????
+  *     - K E H <hurtta@ozone.FMI.FI>
+  */
+ 
+ #ifndef STRSTR
+ extern char *strstr P_((char *,char *)); 
+ #endif
+ 
+ /* strtokq.c */
+ 
+ /* Why there is ' -- it is not quote character in mail.
+  *    - K E H <hurtta@ozone.FMI.FI>
+  */
+ extern char *strtokq P_((char *, char *,int));
+ 
+ /* tail_of.c */
+ 
+ extern int tail_of   P_((char *, char *, char *, int));
+ 
+ /* validname.c */
+ 
+ /* This is quite bogus   - K E H <hurtta@ozone.FMI.FI> */
+ int valid_name       P_((char *));
+ 
+ 
+ 
+ /* lib/read_rc.c */
+ 
+ extern void locale_init P_((void));     /* sets locale and elm_msg_cat */
+ extern void user_init P_((void));       /* get username and home directory */
+ extern int init_defaults P_((void));
+ extern int read_rc_file  P_((void));
+ extern void post_init_check P_((void));  /* read_rc_file calls this */
+ 
+ extern char system_text_file[SLEN];      /* aliases.text */
+ extern char system_data_file[SLEN];      /* aliases */
+ extern char system_rc_file[SLEN];        /* elm.rc */
+ extern char system_mime_types[SLEN];     /* elm.mimetypes */
+ extern char hostdomfile[SLEN];           /* $lib/domain */
+ extern char system_mime_charsets[SLEN];  /* elm.mimecharsets */
+ 
+ extern char user_rc_file[SLEN];          /* .elm/elmrc */
+ extern char user_text_file[SLEN];        /* .elm/aliases.text */
+ extern char user_data_file[SLEN];        /* .elm/aliases */
+ extern char user_mime_types[SLEN];       /* .elm/mime.types */
+ extern char user_mailheaders[SLEN];      /* .elm/elmheaders */
+ extern char user_mime_charsets[SLEN];    /* .elm/mime.charsets */
+ extern char defaultfile[SLEN];	         /* name of default folder */
+ extern char calendar_file[SLEN];	/* name of file for clndr  */
+ extern char raw_calendar_file[SLEN];	/* unexpanded name of file for clndr  */
+ 
+ extern nl_catd elm_msg_cat;	/* message catalog	    */
+ extern int  clear_pages;	/* flag: clear screen w/ builtin pgr? */
+ extern int  title_messages;	/* flag: title message display?       */
+ extern int  debug;		/* flag: debugging mode on?           */
+ extern FILE *debugfile;		/* file for debut output    */
+ extern char home[SLEN];		/* home directory of user  */
+ extern char username[SLEN];	/* return address name!    */
+ extern int userid;		/* uid for current user	      */
+ extern int groupid;		/* groupid for current user   */
+ #ifdef SAVE_GROUP_MAILBOX_ID
+ extern int mailgroupid;		/* groupid for current user   */
+ #endif
+ 
+ /* *** Readed from elmrc: */
+ 
+ extern int  alias_sortby;	/* how to sort aliases        */
+ extern char alternative_editor[SLEN];/* the 'other' editor    */
+ extern struct addr_rec *alternative_addresses;	/* how else do we get mail? */
+ extern int  always_del;		/* flag: always delete marked msgs?   */
+ extern int  always_keep;	/* flag: always keep unread msgs?     */
+ extern int  always_store;	/* flag: always store read mail?      */
+ extern int  arrow_cursor;	/* flag: use "->" regardless?	      */
+ extern int  question_me;	/* flag: ask questions as we leave?   */
+ extern int  prompt_for_cc;	/* flag: prompt user for 'cc' value?  */
+ #ifdef USE_PGP
+ extern int pgp_askpgpsig;   /* Should pgp ask userid to sign messages with? */
+ #endif
+ extern char attribution[SLEN];  /* attribution string for replies     */
+ extern int  auto_copy;		/* flag: auto copy source into reply? */
+ #ifdef BACKGROUD_PROCESSES       
+ extern int background_wait_time; /* If > 0 background mailer after
+ 				  * this number of seconds
+ 				  */
+ #endif
+ /* extern int  bounceback;	*/   /* flag: bounce copy off remote?      */
+ extern int  builtin_lines;	/* int use builtin pager?             */
+ #ifdef MIME
+ extern char raw_charset[SLEN];	/* name of character set */
+ extern char charset[SLEN];	/* name of character set */
+ extern char charset_compatlist[SLEN];	/* list of charsets which are a
+ 					   superset of us-ascii */
+ #endif
+ extern char config_options[SLEN];	/* which options are in o)ptions */
+ extern int  confirm_append;	/* flag: confirm append to folder?    */
+ extern int  confirm_create;	/* flag: confirm create new folder?   */
+ extern int  confirm_files;	/* flag: confirm files for append?    */
+ extern int  confirm_folders;	/* flag: confirm folders for create?  */
+ extern int  auto_cc;		/* flag: mail copy to yourself?       */
+ extern char display_locale[SLEN];	/* LC_CTYPE locale (character set) */
+ #ifdef MIME
+ extern char raw_display_charset[SLEN];
+ extern char default_display_charset[SLEN];
+ extern char display_charset[SLEN];	/* name of character set */
+ #endif
+ #ifdef USE_DSN
+ extern int DSN_success;         /* flag: Ask successfull DSNes      */
+ #endif
+ extern char e_editor[SLEN];	/* "~e" editor...   */
+ extern char editor[SLEN];	/* default editor for mail */
+ extern char raw_editor[SLEN];	/* unexpanded default editor for mail */
+ extern char escape_char;	/* '~' or something else...    */
+ extern int  force_name;		/* flag: save by name forced?	      */
+ extern int  allow_forms;	/* flag: are AT&T Mail forms okay?    */
+ extern char full_username[SLEN];/* Full username - gecos   */
+ extern char hostdomain[SLEN];	/* name of domain we're in */
+ extern char hostfullname[SLEN]; /* name of FQDN we're in */
+ extern char hostname[SLEN];	/* name of machine we're on*/
+ extern int  keep_empty_files;	/* flag: keep empty files??	      */
+ #ifdef USE_PGP
+ extern int pgp_keeppass;    /* should Elm keep the passphrase? */
+ #endif
+ /* extern int  hp_terminal; */	/* flag: are we on an hp terminal?    */
+ extern char local_signature[SLEN];/* local msg signature file   */
+ extern char raw_local_signature[SLEN];/* unexpanded local msg signature file */
+ extern int lock_in_copy;        /* Lock folder when copied to it */
+ extern char folders[SLEN];	/* folder home directory   */
+ extern char raw_folders[SLEN];	/* unexpanded folder home directory   */
+ extern int  mail_permissions;	/* int: permissions for mailbox files   */
+ extern int  mini_menu;		/* flag: display menu?     	      */
+ #ifdef MIME
+ extern char raw_metamail_path[SLEN];
+ extern char metamail_path[SLEN];  /* Metamail path or "none" if no metamail */
+ #endif
+ extern int  metoo;		/* flag: copy me on mail to alias?    */
+ #ifdef MIME
+ extern int mimeforward;
+ #endif
+ extern int  move_when_paged;	/* flag: move when '+' or '-' used?   */
+ extern int  names_only;		/* flag: display names but no addrs?  */
+ #ifdef MIME
+ extern int allow_no_encoding;       /* 1: Allow 8bit without -B8BITMIME
+                                      * 2: Allow binary without -BBINARYMIME
+                                      *    and 8bit without -B8BITMIME */
+ extern int allow_no_hdrencoding;    /* TRUE, if header encoding is 
+ 				     * not required */
+ #endif
+ extern int  noheader;		/* flag: copy + header to file?       */
+ extern int  noheaderfwd;	/* flag: copy + header to file?(fwd)  */
+ #ifdef MIME
+ extern int pagealternative;
+ extern int pagemultipart;
+ #endif
+ extern char pager[SLEN];	/* what pager to use...    */
+ extern char raw_pager[SLEN];	/* unexpanded what pager to use...    */
+ #ifdef USE_PGP
+ extern char pgp_path[SLEN]; /* Pgp path or "none" if no pgp */
+ extern char raw_pgp_path[SLEN];
+ #endif
+ extern int  point_to_new;	/* flag: start pointing at new msgs?  */
+ extern char allowed_precedences[SLEN];	/* list of precedences user may specify */
+ extern char prefixchars[SLEN];	/* prefix char(s) for msgs */
+ extern char printout[SLEN];	/* how to print messages   */
+ extern char raw_printout[SLEN];	/* unexpanded how to print messages   */
+ extern int  prompt_after_pager;	/* flag: prompt after pager exits     */
+ extern int  quote_forward;	/* flag: fwd'd msgs quoted like replies */
+ extern int  readmsginc;		/* msg cnt increment during new mbox read */
+ extern char recvd_mail[SLEN];	/* folder for storing received mail	*/
+ extern char raw_recvdmail[SLEN];/* unexpanded recvd_mail name */
+ extern char remote_signature[SLEN];/* remote msg signature file */
+ extern char raw_remote_signature[SLEN];/* unexpanded remote msg signature file*/
+ #ifdef MIME
+ extern int req_mime_bodyencoding;
+ extern int req_mime_hdrencoding;
+ #endif
+ extern int  resolve_mode;	/* flag: resolve before moving mode?  */
+ extern int  save_by_name;  	/* flag: save mail by login name?     */
+ extern char sent_mail[SLEN];	/* name of file to save copies to */
+ extern char raw_sentmail[SLEN];	/* unexpanded name of file to save to */
+ extern char shell[SLEN];	/* default system shell    */
+ extern char raw_shell[SLEN];	/* unexpanded default system shell    */
+ #ifdef USE_PGP
+ extern int pgp_noarmor;     /* Should Elm display text before PGP armor */
+ #endif
+ extern int  showto;
+ extern int  sig_dashes;		/* flag: put dashes above signature?  */
+ extern int  sleepmsg;		/* time to sleep for messages being overwritten on screen */
+ /* extern int  hp_softkeys; */	/* flag: are there softkeys?          */
+ extern int  sortby;		/* how to sort folders	      */
+ extern long elm_timeout;        /* seconds for main level timeout     */
+ extern char temp_dir[SLEN];     /* name of temp directory */
+ extern char raw_temp_dir[SLEN]; /* unexpanded name of temp directory */
+ #ifdef USE_PGP
+ extern int pgp_keeppass;         /* should Elm keep the passphrase in*/
+ #endif
+ extern int  user_level;		/* flag: how knowledgable is user?    */
+ extern int  use_tite;		/* flag: use termcap/terminfo ti/te?  */
+ extern char v_editor[SLEN];	/* "~v" editor...   */
+ extern int  elm_filter;		/* flag: weed out header lines?	      */
+ extern char *weedlist[MAX_IN_WEEDLIST];
+ extern int  weedcount;		/* how many headers to check?        */
+ 
+ /* lib/output.c */
+ 
+ #define FRM(format)  format,format
+ #define CATGETS(cat,set,def,format) format,catgets(cat,set,def,format) 
+ 
+ typedef int err_handler P_((const char *str));
+ extern int lib_error P_((const char * format, const char *msg, ...));
+ extern void set_error_handler P_((err_handler *h));
+ 
+ extern char *elm_vmessage P_((int max_alloc,
+ 			      const char *format, const char *msg, 
+ 			      va_list args));
+ extern char *elm_message P_((const char * format, const char *msg, ...));
+ extern int elm_sfprintf P_((char *buffer, int size,
+ 			   const char * format, const char *msg, ...));
+ 
+ 
+ /* lib/forwarded.c */
+ 
+ void forwarded P_((char *buffer,
+ 		   struct header_rec *entry));
Index: elm2.4.ME+.50/lib/output.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/lib/output.c	Tue Nov 17 21:12:55 1998
***************
*** 0 ****
--- 1,405 ----
+ #include "headers.h"
+ 
+ static int def_err_handler P_((const char *str));
+ static int def_err_handler (str) 
+      const char *str;
+ {
+   int ret;
+   int l = strlen(str);
+   ret = fprintf(stderr,"%s",str);
+   if (ret > 0 && l && str[l-1] != '\n')
+     ret += fprintf(stderr,"\n");
+   return ret;
+ }
+ 
+ static err_handler *H = def_err_handler;
+ extern void set_error_handler (h)
+      err_handler *h;
+ {
+   H = h;
+ }
+ 
+ 
+ 
+ char *elm_message P_((const char * format, const char *msg, ...));
+ int elm_sfprintf P_((char *buffer, int size,
+ 		    const char * format, const char *msg, ...));
+ 
+ 
+ char *elm_vmessage P_((int max_alloc,
+ 		       const char *format, const char *msg, 
+ 		       va_list args));
+ 
+ 
+ char *elm_vmessage (max_alloc,format,msg,vl)
+      int max_alloc;
+      const char *format;
+      const char *msg;
+      va_list vl;
+ {
+ 
+   const char * s;
+   char * store1 = NULL;
+   int ptr1 = 0, alloced1 = 0;
+ 
+   struct store2 {
+     char * store;
+     int ptr;
+     int alloced;
+   } * store2 = NULL;
+   int store2_len = 0;
+   int i,pos;
+ 
+   int overflow_flag = 0;
+ 
+   dprint(75,(debugfile,"elm_vmessage: max_alloc=%d, format=%s\n",
+ 	     max_alloc,format));
+   dprint(75,(debugfile,"              msg=%s\n",msg));
+ 
+ 
+ #define ENLARGE(ptr,alloced,S) do { if (ptr >= alloced) { \
+     S = safe_realloc(S,alloced+10); alloced += 10; } } while(0)
+ #define PUTC1(c) do { ENLARGE(ptr1,alloced1,store1); store1[ptr1++] = c; } \
+   while(0)
+ #define PUTC2(c) do { ENLARGE(store2[store2_len-1].ptr,\
+    store2[store2_len-1].alloced,store2[store2_len-1].store); \
+    store2[store2_len-1].store[store2[store2_len-1].ptr++] = c; } \
+ while(0)
+ #define NEW_STORE do { \
+   store2 = safe_realloc(store2, \
+   (store2_len+1) * sizeof (struct store2)); store2_len++; \
+   store2[store2_len-1].store = NULL; store2[store2_len-1].alloced = 0; \
+   store2[store2_len-1].ptr = 0; } while(0);
+ #define INC(p) { (p)++; if (!*(p)) break; }
+ 
+ 
+   for (s = format; *s; s++) {
+     int fill = ' ';
+     int left = 0;
+     int plus = 0;
+     int val1 = 0, val2 = 0;
+     int long_f = 0;
+     if (*s != '%') {
+       continue;
+     }
+     INC(s);
+ 
+     if ('%' == *s) {
+       continue;
+     }
+     NEW_STORE;
+ 
+ 
+   again1:
+     if ('0' == *s)      { fill = '0'; INC(s); }
+     else if ('-' == *s) { left = 1;   INC(s); }
+     else if ('+' == *s) { plus = 1;   INC(s); }
+     
+     if (*s >= '1' && *s <= '9') {
+       while (*s >= '0' && *s <= '9') {
+ 	val1 = val1 * 10 + *s - '0';
+ 	INC(s);
+       }
+ 
+       if (*s == '$') {
+ 	val1 = 0;
+ 	INC(s);
+ 	dprint(75,(debugfile,
+ 		   "elm_vmessage: --- Positional args are not allowed in: %s\n",
+ 		   format));
+ 	goto error1;
+       }
+ 
+     } else if ('*' == *s) { 
+       val1 = va_arg(vl,int);
+       INC(s);
+     }
+ 
+     if ('.' == *s) {
+       INC(s);
+       if (*s >= '1' && *s <= '9') {
+ 	while (*s >= '0' && *s <= '9') {
+ 	  val2 = val2 * 10 + *s - '0';
+ 	  INC(s);
+ 	}
+       } else if ('*' == *s) { 
+ 	val2 = va_arg(vl,int);
+ 	INC(s);
+       }      
+     }
+      
+     if ('l' == *s) { 
+       long_f = 1;
+       INC(s);
+     }
+ 
+     switch(*s) {
+       const char *str, *a;
+       int l,c;
+       long val,valz;
+       unsigned long r;
+       unsigned long r1;
+     case 'c':
+       c = va_arg(vl, int);      
+       dprint(75,(debugfile,"elm_vmessage: [c] val1=%d, c=%c\n",
+ 		 val1,c));
+       l = 1;
+       while (l < val1 && !left) { PUTC2(fill); l++; }
+       PUTC2(c);
+       while (l < val1 && left) { PUTC2(' '); l++; }
+       break;
+     case 's':
+       str = va_arg(vl, char *);
+       if (!str)
+ 	goto error1;
+       l = strlen(str);
+       if (val2 <= 0) val2 = l;
+       dprint(75,(debugfile,"elm_vmessage: [s] val1=%d, val2=%d, str=%s\n",
+ 		 val1,val2,str));
+       while (l < val1 && !left) { PUTC2(fill); l++; }
+       for (a = str; *a && a - str < val2; a++) { 
+ 	PUTC2(*a); 
+ 	if (max_alloc > 0 && a - str > max_alloc) {
+ 	  dprint(1,(debugfile,
+ 		    "elm_vmessage: --- too long string (max=%d): %.30s...\n",
+ 		    max_alloc,str));
+ 	  break;
+ 	}
+       }
+       while (l < val1 && left) { PUTC2(' '); l++; }
+       break;
+     case 'd':
+       if (long_f)
+ 	val = va_arg(vl, long);
+       else
+ 	val = va_arg(vl, int);
+       c = 0;
+       if (val < 0) {
+ 	c = '-'; val1--;
+ 	val = -val;
+       } else if (plus) {
+ 	c = '+'; val1--;
+       }
+       dprint(75,(debugfile,"elm_vmessage: [d] val1=%d, val2=%d, c=%c, val=%ld\n",
+ 		 val1,val2,c, val));
+       l = 0;
+       valz = val;
+       r1 = 1;
+       do {
+ 	r = (valz / 10);
+ 	valz = r;
+ 	l++;
+ 	r1 *= (long) 10;
+       } while(r);
+       while (l < val1 && !left && fill != '0') { PUTC2(fill); l++; }
+       if (c) { PUTC2(c); }
+       while (l < val1 && !left && fill == '0') { PUTC2('0');  l++; }
+       valz = val;
+       while(r1 >= (long) 10) {
+ 	r1 /= (long) 10;
+ 	r = (valz / r1);
+ 	PUTC2( '0' + r);
+ 	valz -= r * r1;
+       } 
+       while (l < val1 && left) { PUTC2(' '); l++; }
+       break;
+     default:
+       dprint(75,(debugfile,"elm_vmessage: [%c] ????\n",*s));
+     error1:
+       dprint(75,(debugfile,"elm_vmessage: --- error\n"));
+     }
+     PUTC2('\0');
+   }
+ 
+   for (i = 0; i < store2_len; i++) {
+       dprint(75,(debugfile,"elm_vmessage:  - %d: %.*s\n",i,
+ 		 store2[i].ptr,NONULL(store2[i].store)));
+   }
+ 
+   pos = -1;
+   /* Actual printing */
+   for (s = msg; *s; s++) {
+     int val1 = 0;
+     if (*s != '%') {
+       PUTC1(*s);
+       continue;
+     }
+     INC(s);
+ 
+     if ('%' == *s) {
+       PUTC1(*s);
+       continue;
+     }
+     pos++;
+ 
+   again2:
+     if ('0' == *s)      { INC(s); }
+     else if ('-' == *s) { INC(s); }
+     else if ('+' == *s) { INC(s); }
+     
+     if (*s >= '1' && *s <= '9') {
+       while (*s >= '0' && *s <= '9') {
+ 	val1 = val1 * 10 + *s - '0';
+ 	INC(s);
+       }
+       if ('$' == *s) {
+ 	pos = val1;
+ 	val1 = 0;
+ 	goto again2;
+       }
+     } else if ('*' == *s) { 
+       INC(s);
+     }
+ 
+     if ('.' == *s) {
+       INC(s);
+       if (*s >= '1' && *s <= '9') {
+ 	while (*s >= '0' && *s <= '9') {
+ 	  INC(s);
+ 	}
+       } else if ('*' == *s) { 
+ 	INC(s);
+       }      
+     }
+      
+     if ('l' == *s) { 
+       INC(s);
+     }
+ 
+     switch(*s) {
+       const char *str,*a;
+     case 's': case 'd': case 'c':
+       if (pos < 0 || pos >= store2_len)
+ 	goto error2;
+       str = store2[pos].store;
+       if (!str)
+ 	goto error2;
+       dprint(75,(debugfile,"elm_vmessage: [%c] str=%s\n",*s,str));
+       for (a = str; *a; a++) { 
+ 	PUTC1(*a); 
+       }
+       break;
+     default:
+       dprint(75,(debugfile,"elm_vmessage: [%c] ????\n",*s));
+     error2:
+       dprint(75,(debugfile,"elm_vmessage: --- error\n"));
+       PUTC1('[');
+       PUTC1('?');
+       PUTC1(']');
+     }
+   }
+ 
+   PUTC1('\0');
+ #undef PUTC1
+ #undef INC
+ #undef PUTC2
+ #undef NEW_STORE
+ 
+   for (i = 0; i < store2_len; i++) {
+     if (store2[i].store)
+       free(store2[i].store);
+   }
+   free(store2);
+ 
+   return store1;
+ }
+ 
+ int lib_error P_((const char * format, const char *msg, ...));
+ 
+ int lib_error (
+ #if ANSI_C
+ 			      const char * format, 
+ 			      const char *msg, ...
+ #else
+ 			      format, msg, va_alist
+ #endif
+ 			      )
+ #if !ANSI_C
+      const char * format;
+      const char *msg;
+      va_dcl
+ #endif
+ {
+   int ret = 0;
+   va_list vl;
+   char * store1;
+ 
+   dprint(75,(debugfile,"lib_error: format=%s\n",format));
+   dprint(75,(debugfile,"              msg=%s\n",msg));
+   	            
+   Va_start(vl, msg);           /* defined in defs.h */
+   
+   store1 = elm_vmessage(0,format,msg,vl);
+ 
+   va_end(vl);
+ 
+   ret = H(store1);
+   free(store1);
+   return ret;
+ }
+ 
+ char *elm_message (
+ #if ANSI_C
+ 		   const char * format, 
+ 		   const char *msg, ...
+ #else
+ 		   format, msg, va_alist
+ #endif
+ 		)   
+ #if !ANSI_C
+      const char * format; 
+      const char *msg;
+      va_dcl
+ #endif
+ {
+   va_list vl;
+   char * store1;
+ 
+   dprint(75,(debugfile,"elm_message: format=%s\n",format));
+   dprint(75,(debugfile,"             msg=%s\n",msg));
+   	            
+   Va_start(vl, msg);           /* defined in defs.h */
+   
+   store1 = elm_vmessage(0,format,msg,vl);
+ 
+   va_end(vl);
+ 
+   return store1;
+ }
+ 
+ int elm_sfprintf (
+ #if ANSI_C
+ 		 char * buffer, int size,
+ 		 const char * format, 
+ 		 const char *msg, ...
+ #else
+ 		 buffer, size, format, msg, va_alist
+ #endif
+ 		)   
+ #if !ANSI_C
+      char * buffer;
+      int size;
+      const char * format; 
+      const char *msg;
+      va_dcl
+ #endif
+ {
+   va_list vl;
+   char * store1;
+ 
+   dprint(75,(debugfile,"elm_sfprintf: size=%d, format=%s\n",size, format));
+   dprint(75,(debugfile,"             msg=%s\n",msg));
+   	            
+   Va_start(vl, msg);           /* defined in defs.h */
+   
+   store1 = elm_vmessage(size-1,format,msg,vl);
+ 
+   va_end(vl);
+ 
+   strfcpy(buffer,store1,size);
+   free(store1);
+   return strlen(buffer);
+ }
+ 
+ 
+ 
Index: elm2.4.ME+.50/lib/read_rc.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/lib/read_rc.c	Tue Nov 17 21:14:09 1998
***************
*** 0 ****
--- 1,1545 ----
+ static char rcsid[] = "@(#)$Id: read_rc.c,v 1.5 1998/11/08 18:21:48 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.5 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  *****************************************************************************
+  *
+  * Most of code copied from ../src/read_rc.c. It have following copyright:
+  *
+  *			Copyright (c) 1988-1992 USENET Community Trust
+  *			Copyright (c) 1986,1987 Dave Taylor
+  *****************************************************************************/
+ 
+ #define SAVE_OPTS
+ #include "headers.h"
+ #include "save_opts.h"
+ #include "s_elm.h"
+ #include <errno.h>
+ 
+ extern int errno;
+ 
+ #ifdef PWDINSYS
+ #  include <sys/pwd.h>
+ #else
+ #  include <pwd.h>
+ #endif
+ 
+ #ifndef I_UNISTD 
+ char *getlogin();
+ unsigned short getgid(), getuid(); 
+ struct passwd *getpwuid();
+ #endif
+ 
+ 
+ 
+ 
+ 
+ #define ASSIGNMENT      0
+ #define WEEDOUT		1
+ #define ALTERNATIVES	2
+ 
+ #define SYSTEM_RC	0
+ #define LOCAL_RC	1
+ 
+ static int lineno = 0;
+ static int errors = 0;
+ 
+ static void do_expand_env P_((char *, char *, char *, unsigned));
+ static void do_rc P_((FILE *file,int lcl, char *filaname));
+ static int do_set P_((FILE *, char *, char *, int, int, char *));
+ 
+ #define  metachar(c)	(c == '+' || c == '%' || c == '=')
+ #ifndef ok_rc_char
+ #define ok_rc_char(c)   (isalnum(c) || c == '-' || c == '_')
+ #endif
+ 
+ char system_text_file[SLEN] = SYSTEM_TEXT_FILE;
+ char system_data_file[SLEN]  = SYSTEM_DATA_FILE;
+ char system_rc_file[SLEN]    = SYSTEM_RC_FILE;
+ char system_mime_types[SLEN] = SYSTEM_MIME_TYPES;
+ char hostdomfile[SLEN]       = HOSTDOMFILE;
+ char system_mime_charsets[SLEN] = SYSTEM_MIME_CHARSETS;
+ 
+ char user_rc_file[SLEN]   = ELMRCFILE;              /* user_init fixes */
+ char user_text_file[SLEN] = USER_ALIAS_TEXT;        /* user_init fixes */
+ char user_data_file[SLEN] = USER_ALIAS_DATA;        /* user_init fixes */
+ char user_mime_types[SLEN] = USER_MIME_TYPES;       /* user_init fixes */
+ char user_mailheaders[SLEN] = MAILHEADERS;          /* user_init fixes */
+ char user_mime_charsets[SLEN] = USER_MIME_CHARSETS; /* user_init fixes */
+ 
+ char defaultfile[SLEN] = {0};	/* name of default folder */
+ char calendar_file[SLEN] = {0};	/* name of file for clndr  */
+ char raw_calendar_file[SLEN] = {0};	/* unexpanded name of file for clndr  */
+ int clear_pages = 0;		/* flag: act like "page" (more -c)? */
+ int title_messages = 1;		/* flag: title message display?     */
+ int debug = 0; 			/* flag: default is no debug!       */
+ FILE *debugfile = stderr;	/* file for debug output            */
+ 
+ nl_catd  elm_msg_cat = 0;	/* message catalog	    */
+ 
+ char username[SLEN] = {0};	/* return address name!    */
+ char home[SLEN] = {0};		/* home directory of user  */
+ int userid;			/* uid for current user	      */
+ int groupid;			/* groupid for current user   */
+ #ifdef SAVE_GROUP_MAILBOX_ID
+ int mailgroupid;		/* groupid for current user   */
+ #endif
+ /* ------------- Variables in elmrc ------------------------------- */
+ 
+ int alias_sortby = NAME_SORT;	        /* how to sort aliases...   */
+ char alternative_editor[SLEN] = {0};	/* alternative editor...    */
+ struct addr_rec *alternative_addresses;	/* how else do we get mail? */
+ int always_del = 0;		/* flag: always delete marked msgs? */
+ int always_keep = 1;		/* flag: always keep unread msgs?   */
+ int always_store = 0;		/* flag: always store read msgs?    */
+ int arrow_cursor = 0;		/* flag: use "->" cursor regardless?*/
+ int question_me = 1;		/* flag: ask questions as we leave? */
+ int prompt_for_cc = 1;		/* flag: ask user for "cc:" value?  */
+ #ifdef USE_PGP
+ int pgp_askpgpsig=0; /* Should pgp ask userid to sign messages with? */
+ #endif
+ char attribution[SLEN] = {0};	/* attribution string for replies   */
+ int auto_copy = 0;		/* flag: automatically copy source? */
+ #ifdef BACKGROUD_PROCESSES       
+ int background_wait_time = 2;    /* If > 0 background mailer after  */
+ 				 /* this number of seconds          */
+ #endif
+ /* int bounceback = 0;	*/	/* flag: bounce copy off remote?    */
+ int builtin_lines= -3;		/* int: if < 0 use builtin if message*/
+                                 /* shorter than LINES+builtin_lines */
+                                 /* else use pager. If > 0 use builtin*/
+                                 /* if message has fewer than # of lines*/
+ #ifdef MIME
+ char raw_charset[SLEN] = "DISPLAY";	/* name of character set            */
+ char charset[SLEN] = {0};	/* name of character set            */
+ char charset_compatlist[SLEN] = {0}; /* list of charsets which are a*/
+                                 /* superset of us-ascii             */
+ #endif
+ char config_options[SLEN] = {0};/* which options are in o)ptions    */
+ int confirm_append = 0;		/* flag: confirm append to folder?  */
+ int confirm_create = 0;		/* flag: confirm create new folder? */
+ int confirm_files = 0;		/* flag: confirm files for append?  */
+ int confirm_folders = 0;	/* flag: confirm folders for create?*/
+ int auto_cc = 0;		/* flag: mail copy to user?	    */
+ char display_locale[SLEN] = "NONE";  /* LC_CTYPE locale (character set) */
+ #ifdef MIME
+ char default_display_charset[SLEN] = {0};  /* the charset, the display supports */
+ char display_charset[SLEN] = {0};  /* the charset, the display supports */
+ char raw_display_charset[SLEN] = "$MM_CHARSET";	
+                                /* the charset, the display supports */
+ #endif
+ #ifdef USE_DSN
+ int DSN_success = 0;            /* flag: Ask successfull DSNes      */
+ #endif
+ char e_editor[SLEN] = {0};	/* "~e" editor...                   */
+ char editor[SLEN] = {0};	/* editor for outgoing mail*/
+ char raw_editor[SLEN] = {0};	/* unexpanded editor for outgoing mail*/
+ char escape_char = TILDE_ESCAPE;/* '~' or something else..          */
+ int force_name = 0;		/* flag: save by name forced?	    */
+ int allow_forms = NO;		/* flag: are AT&T Mail forms okay?  */
+ char full_username[SLEN] = {0};	/* Full username - gecos            */
+ char hostdomain[SLEN] = {0};	/* name of domain we're in          */
+ char hostfullname[SLEN] = {0};	/* name of FQDN we're in            */
+ char hostname[SLEN] = {0};	/* name of machine we're on         */
+ int keep_empty_files = 0;	/* flag: leave empty folder files?  */
+ #ifdef USE_PGP
+ int pgp_keeppassfor = 300;      /* 5 minutes                        */
+ #endif
+ /* int hp_terminal = 0;	*/	/* flag: are we on HP term?	    */
+ char local_signature[SLEN] = {0};   /* local msg signature file     */
+ char raw_local_signature[SLEN] = {0};	/* unexpanded local msg     */
+                                 /*               signature file     */
+ int lock_in_copy = 1;           /* Lock folder when copied to it    */
+ char folders[SLEN] = {0};	/* folder home directory            */
+ char raw_folders[SLEN] = {0};	/* unexpanded folder home directory */
+ int mail_permissions = 0600;	/* int: permissions for mailbox files */
+ int mini_menu = 1;		/* flag: menu specified?	    */
+ #ifdef MIME
+ char raw_metamail_path[SLEN] = METAMAIL_PATH;
+ char metamail_path[SLEN] = "metamail"; /* Metamail path or "none"   */
+                                 /* if no metamail                   */
+ #endif
+ int metoo = 0;			/* flag: copy me on mail to alias?  */
+ #ifdef MIME
+ int mimeforward = FALSE;        /* falg: Forward as Message/rfc822  */
+ #endif
+ int move_when_paged = 0;	/* flag: move when '+' or '-' used? */
+ int names_only = 1;		/* flag: display user names only?   */
+ #ifdef MIME
+ int allow_no_encoding = 0;      /* 1: Allow 8bit without -B8BITMIME */
+                                 /* 2: Allow binary without -BBINARYMIME and */
+                                 /*    and 8bit without -B8BITMIME   */
+ int allow_no_hdrencoding = 0;   /* TRUE, if header encoding is      */
+ 				/* not required                     */
+ #endif
+ int noheader = 1;		/* flag: copy + header to file?     */
+ int noheaderfwd = 0;		/* flag: copy + header to file(fwd)? */
+ #ifdef MIME
+ int pagealternative=1;          /* Page if alternative have one know*/
+                                 /* subtype ?                        */
+ int pagemultipart=0;            /* Page unknown mime subparts?      */
+ #endif
+ char pager[SLEN] = {0};		/* what pager to use                */
+ char raw_pager[SLEN] = {0};	/* unexpanded what pager to use     */
+ #ifdef USE_PGP
+ char pgp_path[SLEN]   = "none"; /* Pgp path or "none" if no pgp     */
+ char raw_pgp_path[SLEN] = PGP_PATH;
+ #endif
+ int point_to_new = 1;		/* flag: start pointing at new msg? */
+ char allowed_precedences[SLEN] = {0};	/* list of precedences user */
+                                 /* may specify                      */
+ char prefixchars[SLEN] = "> ";	/* prefix char(s) for msgs          */
+ char printout[SLEN] = {0};	/* how to print messages            */
+ char raw_printout[SLEN] = {0};	/* unexpanded how to print messages */
+ int prompt_after_pager = 1;	/* flag: prompt after pager exits   */
+ int quote_forward = 0;		/* flag: fwd'd msgs quoted like replies */
+ int readmsginc = 1;		/* increment of msg cnt when reading*/
+                                 /* new mbox                         */
+ char recvd_mail[SLEN] = {0};	/* folder for storing received mail */
+ char raw_recvdmail[SLEN] = {0};	/* unexpanded recvd_mail name       */
+ char remote_signature[SLEN] = {0};  /* remote msg signature file    */
+ char raw_remote_signature[SLEN] = {0};	/* unexpanded remote msg    */
+                                 /* signature file                   */
+ #ifdef MIME
+ int req_mime_bodyencoding = 1;  /*                                  */
+ int req_mime_hdrencoding = 0;   /*                                  */
+ #endif
+ int resolve_mode = 1;		/* flag: delete saved mail?	    */
+ int save_by_name = 1;		/* flag: save mail by login name?   */
+ char sent_mail[SLEN] = {0};	/* name of file to save copies to   */
+ char raw_sentmail[SLEN] = {0};	/* unexpanded name of file to save to*/
+ char shell[SLEN] = {0};		/* current system shell             */
+ char raw_shell[SLEN] = {0};	/* unexpanded current system shell  */
+ #ifdef USE_PGP
+ int pgp_noarmor=1;      /* Should Elm display text before PGP armor */
+ #endif
+ int showto = 0;                 /*                                  */
+ int sig_dashes = 1;		/* flag: include dashes above sigs? */
+ int sleepmsg = 2;		/* time to sleep for messages being */
+                                 /* overwritten on screen            */
+ /* int hp_softkeys = 0;	*/	/* flag: are there softkeys?        */
+ int sortby = REVERSE SENT_DATE;	/* how to sort incoming mail...     */
+ long elm_timeout = 600L;	/* timeout (secs) on main prompt    */
+ char temp_dir[SLEN] = {0};      /* name of temp directory           */
+ char raw_temp_dir[SLEN] = {0};  /* unexpanded name of temp directory*/
+ #ifdef USE_PGP
+ int pgp_keeppass=0;             /* should Elm keep the passphrase in*/
+                                 /* memory?                          */
+ #endif
+ int user_level = 0;		/* flag: how good is the user?      */
+ int use_tite = 1;		/* flag: use termcap/terminfo ti/te?*/
+ char v_editor[SLEN] = {0};	/* "~v" editor...                   */
+ int elm_filter = 1;		/* flag: weed out header lines?	    */
+ char *weedlist[MAX_IN_WEEDLIST] = {0}; /*                           */
+ int  weedcount;                 /*                                  */
+ /* ---------------------------------------------------------------- */
+ 
+ static void do_expand_env(descr, dest, src, destlen)
+     char	*descr, *dest, *src;
+     unsigned	destlen;
+ {
+     if (expand_env(dest, src, destlen) != 0) {
+ 	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCannotInitErrorExpanding,
+ 	    "Cannot initialize \"%s\" - error expanding \"%s\"."),
+ 	    descr, src);
+ 	errors++;
+ 	dest[0] = '\0';
+     }
+ }
+ 
+ /* sets locale and elm_msg_cat */
+ static int locale_init_called = 0;
+ 
+ void locale_init () {
+ 
+ #ifdef I_LOCALE
+   char *res;
+ 
+   if (setlocale(LC_ALL, "") == NULL) {
+     lib_error(FRM("Elm: Unsupported locale (check $LANG)\n"));
+     if (setlocale(LC_CTYPE,"") != NULL) {
+       lib_error(FRM("Elm: ... but succeed setting of LC_CTYPE\n"));
+     } else {
+       lib_error(FRM("Elm: ... check also $LC_CTYPE\n"));
+     }
+     /* sleep if stderr points to terminal */
+     if (isatty(2))
+       sleep(1);
+   }
+ #endif
+ 
+   elm_msg_cat       = catopen("elm2.4me+", 0);
+ 
+ #ifdef  I_LOCALE
+   res = setlocale(LC_CTYPE,NULL);
+   if (!res) {
+     lib_error(FRM("Elm: Unable to get current locale (LC_CTYPE)\n"));
+     /* sleep if stderr points to terminal */
+     if (isatty(2))
+       sleep(1);
+   } else
+     strfcpy(display_locale,res, sizeof display_locale);
+ #endif
+   
+   locale_init_called++;
+ }
+ 
+ 
+ 
+ #ifdef MIME
+ 
+ 
+ static int set_charset P_((const char * rest));
+ 
+ static int set_charset(c1)
+      const char *c1;
+ {
+   while (*c1 && whitespace (*c1)) /* skip leading whitespace */
+     c1++;
+ 
+   if (!*c1)
+     return 0;
+   strfcpy(display_charset,c1, 
+ 	  sizeof display_charset);
+   return 1;
+ }
+ 
+ static void map_display_charset P_((const char * lc_ctype));
+ static void map_display_charset(lc_ctype)
+      const char * lc_ctype;
+ {
+   int i;
+   
+   const char *lang = NULL;
+   const char *lang_country = NULL;
+   const char *charset = NULL;
+ 
+   char lbuf[3], cbuf[6];
+ 
+   if (isascii(lc_ctype[0]) && isalpha(lc_ctype[0]) &&
+       isascii(lc_ctype[1]) && isalpha(lc_ctype[1]) &&
+       ('.' == lc_ctype[2] || '_' == lc_ctype[2] || '\0' == lc_ctype[2])) {
+     strncpy(lbuf,lc_ctype,3);
+     lbuf[2] = '\0';
+     lang = lbuf;
+ 
+     if ('_' == lc_ctype[2]) {
+       if (isascii(lc_ctype[3]) && isalpha(lc_ctype[3]) &&
+ 	  isascii(lc_ctype[4]) && isalpha(lc_ctype[4]) &&
+ 	  ('.' == lc_ctype[5] || '\0' == lc_ctype[5])) {
+ 
+ 	strncpy(cbuf,lc_ctype,6);
+ 	cbuf[5] = '\0';
+ 	lang_country = cbuf;
+ 
+ 	if ('.' == lc_ctype[5])
+ 	  charset = lc_ctype+6;
+       }
+     } else if ('.' == lc_ctype[2])
+ 	  charset = lc_ctype+3;      
+   }
+ 
+   if (lang) {
+     dprint (10, (debugfile, 
+ 		"map_display_charset: %s -> lang: %s\n", 
+ 		lc_ctype,lang));
+   } 
+   if (lang_country) {
+     dprint (10, (debugfile, 
+ 		"map_display_charset: %s -> lang_country: %s\n", 
+ 		lc_ctype,lang_country));
+   }
+   if (charset) {
+     dprint (10, (debugfile, 
+ 		"map_display_charset: %s -> charset: %s\n", 
+ 		lc_ctype,charset));
+   }
+ 
+   for (i = 0; i < 3; i++) {
+     if ( i < 2) {
+       char buf[LONG_STRING];
+       FILE *f = NULL;
+       char * fn = user_mime_charsets;
+       int l = strlen(lc_ctype);
+       if (1 == i)
+ 	fn = system_mime_charsets;
+ 
+       f = fopen(fn,"r");
+       if (!f)
+ 	continue;
+ 
+       while (fgets(buf,sizeof buf, f) != NULL) {
+ 	char * c = buf;
+ 	int l1 = strlen(buf);
+ 	
+ 	if ('\n' == buf[l1 -1]) 
+ 	  buf[l1 - 1] = '\0';
+ 	else {
+ 	  lib_error("%30s: Too long line: %.30s...\n",fn,buf);
+ 	  break;
+ 	}
+ 
+ 	while (l1-- > 0 && whitespace(buf[l1]))
+ 	  buf[l1] = '\0';
+ 
+ 	c = buf;
+ 	while (*c && whitespace (*c)) /* skip leading whitespace */
+ 	  c++;
+ 	if ('#' == *c)
+ 	  continue;
+ 	if (!*c)
+ 	  continue;
+ 	if (strincmp (c, lc_ctype, l) == 0 &&
+ 	    whitespace(c[l])) {
+ 	  char *c1 = c + l + 1;
+ 
+ 	  if (!set_charset(c1)) {
+ 	    lib_error("%30s: No charset: %.30s...\n",fn,buf);
+ 	    continue;
+ 	  }
+ 	  dprint (3, (debugfile, 
+ 		      "map_display_charset: user defined \"%s\" as \"%s\"\n", 
+ 		      lc_ctype, display_charset));
+ 	  fclose(f);
+ 	  return;
+ 	}
+ 
+ 
+ 	if (charset && strncmp(c,"*.",2) == 0) {
+ 	  int l3 = strlen(charset);
+ 	  if (strincmp (c+2, charset, l3) == 0 &&
+ 	      whitespace(c[l3])) {
+ 	    char *c1 = c + 5 + 1;
+ 	    
+ 	    if (!set_charset(c1)) {
+ 	      lib_error("%30s: No charset: %.30s...\n",fn,buf);
+ 	      continue;
+ 	    }
+ 	    dprint (3, (debugfile, 
+ 			"map_display_charset: user defined \"%s\" as \"%s\"\n", 
+ 			lc_ctype, display_charset));
+ 	    fclose(f);
+ 	    return;
+ 	  }
+ 	}
+ 
+ 	if (lang_country && strincmp (c, lang_country, 5) == 0 &&
+ 	    whitespace(c[5])) {
+ 	  char *c1 = c + 5 + 1;
+ 
+ 	  if (!set_charset(c1)) {
+ 	    lib_error("%30s: No charset: %.30s...\n",fn,buf);
+ 	    continue;
+ 	  }
+ 	  dprint (3, (debugfile, 
+ 		      "map_display_charset: user defined \"%s\" as \"%s\"\n", 
+ 		      lc_ctype, display_charset));
+ 	  fclose(f);
+ 	  return;
+ 	}
+ 
+ 	if (lang_country && strincmp (c, lang, 2) == 0 &&
+ 	    whitespace(c[2])) {
+ 	  char *c1 = c + 2 + 1;
+ 
+ 	  if (!set_charset(c1)) {
+ 	    lib_error("%30s: No charset: %.30s...\n",fn,buf);
+ 	    continue;
+ 	  }
+ 	  dprint (3, (debugfile, 
+ 		      "map_display_charset: user defined \"%s\" as \"%s\"\n", 
+ 		      lc_ctype, display_charset));
+ 	  fclose(f);
+ 	  return;
+ 	}
+       }
+       
+       fclose(f);
+     } else {
+       int val;
+       if (0 == strcmp(lc_ctype,"C")) 
+ 	strfcpy(display_charset,"US-ASCII",sizeof display_charset);
+       else if (0 == strincmp(lc_ctype,"ISO-8859-",9) &&
+ 	       0 < (val = atoi(lc_ctype+9))) 
+ 	elm_sfprintf(display_charset, sizeof display_charset,
+ 		     FRM("ISO-8859-%d"),
+ 		     val);
+       else if (charset &&
+ 	       0 == strincmp(charset,"ISO-8859-",9) &&
+ 	       0 < (val = atoi(charset+9))) 
+ 	elm_sfprintf(display_charset, sizeof display_charset,
+ 		     FRM("ISO-8859-%d"),
+ 		     val);
+       else if (charset &&
+ 	       0 == strincmp(charset,"ISO8859",7) &&
+ 	       isascii(charset[7]) && isdigit(charset[7]) && 
+ 	       '\0' == charset[8])
+ 	elm_sfprintf(display_charset, sizeof display_charset,
+ 		     FRM("ISO-8859-%c"),
+ 		     charset[7]);
+       else {
+ 	strfcpy(display_charset,default_display_charset, sizeof 
+ 		display_charset);
+ 	lib_error(FRM("Elm: Unable to map %.20s locale (LC_CTYPE) to MIME charset"),
+ 		      lc_ctype);
+ 	lib_error(FRM("     Using default (%.20s). Check %.100s or\n      %.100s"),
+ 		      default_display_charset,system_mime_charsets,
+ 		      user_mime_charsets);
+ 	/* sleep if stderr points to terminal */
+ 	if (isatty(2))
+ 	  sleep(1);	
+       }
+       dprint (3, (debugfile, 
+ 		  "map_display_charset: default \"%s\" as \"%s\"\n", 
+ 		  lc_ctype, display_charset));
+     }
+   }
+ }
+ #endif
+ 
+ 
+ void user_init() {
+   char *cp;
+ 
+ 
+ 	/** initialize the whole ball of wax.
+ 	**/
+ 	struct passwd *pass, *getpwnam();
+ 
+ 	if (!locale_init_called)
+ 	  locale_init ();
+ 
+ 	userid  = getuid();
+ 	groupid = getgid();	
+ 
+ 	/* Get username (logname), home (login directory), and full_username
+ 	 * (part of GCOS) field from the password entry for this user id.
+ 	 * Full_username will get overridden by fullname in elmrc, if defined.
+ 	 *
+ 	 * For those sites that have various user names with the same user
+ 	 * ID, use the passwd entry corresponding to the user name as long 
+ 	 * as it matches the user ID.  Otherwise fall back on the entry 
+ 	 * associated with the user ID alone.
+ 	 */
+ 
+ 	if((cp = getenv("LOGNAME")) == NULL)
+ 		cp = getenv("USER");
+ 	if(cp != NULL && (pass = getpwnam(cp)) != NULL &&
+ 	    pass->pw_uid == userid) {
+ 	  ;  /* Null body */
+ 	} else if((pass = getpwuid(userid)) == NULL) {
+ 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmYouHaveNoPasswordEntry,
+ 			    "You have no password entry!"));
+ 	  exit(1);
+ 	}
+ 	strfcpy(username, pass->pw_name, sizeof username);
+ 	strfcpy(home, pass->pw_dir, sizeof home);
+ 	strfcpy(shell, pass->pw_shell, sizeof shell);
+ 	/* Null shell in /etc/passwd means /bin/sh */
+ 	if ('\0' == shell[0]) 
+ 	  strfcpy(shell, "/bin/sh", sizeof shell);
+ 
+ 	if((cp = get_full_name(username)) != NULL)
+ 	  strfcpy(full_username, cp, sizeof full_username);
+ 	else
+ 	  strfcpy(full_username, username, sizeof full_username);	
+ 	/* fall back on logname */
+ 
+ 
+ 	elm_sfprintf(user_rc_file, sizeof user_rc_file,
+ 		     FRM("%s/%s"), home, ELMRCFILE);
+ 	elm_sfprintf(user_text_file, sizeof user_text_file,
+ 		     FRM("%s/%s"), home, USER_ALIAS_TEXT);
+ 	elm_sfprintf(user_data_file, sizeof user_data_file,
+ 		     FRM("%s/%s"), home, USER_ALIAS_DATA);
+ 	elm_sfprintf(user_mime_types, sizeof user_mime_types,
+ 		     FRM("%s/%s"), home, USER_MIME_TYPES);
+ 	elm_sfprintf(user_mailheaders, sizeof user_mailheaders,
+ 		     FRM("%s/%s"), home, MAILHEADERS);
+ 	elm_sfprintf(user_mime_charsets, sizeof user_mime_charsets,
+ 		     FRM("%s/%s"), home, USER_MIME_CHARSETS);
+ }
+ 
+ int init_defaults() {
+   char     buffer[SLEN], *cp;
+   FILE * file;
+   int hostlen, domlen;
+ 
+   /* Establish some defaults in case elmrc is incomplete or not there.
+    * Defaults for other elmrc options were established in their
+    * declaration - in elm.h.  And defaults for sent_mail and recvd_mail
+    * are established after the elmrc is read in since these default
+    * are based on the folders directory name, which may be given
+    * in the emrc.
+    * Also establish alternative_editor here since it is based on
+    * the default editor and not on the one that might be given in the
+    * elmrc.
+    */
+ 	 
+   default_weedlist();
+   errors = 0;
+ 
+   /*
+    * Get the host name as per configured behavior.
+    */
+ #ifdef HOSTCOMPILED
+   strfcpy(hostname, HOSTNAME, sizeof(hostname));
+ #else
+   gethostname(hostname, sizeof(hostname));
+ #endif
+ 
+   /*
+    * now get the domain name, used to build the full name
+    */
+   gethostdomain(hostdomain, sizeof(hostdomain));
+   
+   /*
+    * now the tough part:
+    *	we need to make three variables out of this stuff:
+    *	hostname = just the hostname, as in bangpaths,
+    *		this is whatever the user gave us so far,
+    *		we wont change this one
+    *	hostdomain = this is the domain considered local to this
+    *		machine, and should be what we got above.
+    *	hostfullname = this is the full FQDN of this machine,
+    *		and is a strange combination of the first two.
+    *	if tail(hostname) == hostdomain
+    *		then hostfullname = hostname
+    *			ie: node.ld.domain.type, ld.domain.type -> node.ld.domain.type
+    *	else if hostname == hostdomain + 1
+    *		then hostfullname = hostname
+    *			ie: domain.type, .domain.type -> domain.type
+    *	
+    *	else hostfullname = hostname + hostdomain
+    *			ie: host, .domain.type -> host.domain.type
+    * lost yet?
+    */
+   hostlen = strlen(hostname);
+   domlen = strlen(hostdomain);
+   if (hostlen >= domlen) {
+     if (istrcmp(&hostname[hostlen - domlen], hostdomain) == 0)
+       strfcpy(hostfullname, hostname, sizeof hostfullname);
+     else {
+       strfcpy(hostfullname, hostname, sizeof hostfullname);
+       strfcat(hostfullname, hostdomain, sizeof hostfullname);
+     }
+   } else {
+     if (istrcmp(hostname, hostdomain + 1) == 0)
+       strfcpy(hostfullname, hostname, sizeof hostfullname);
+     else {
+       strfcpy(hostfullname, hostname, sizeof hostfullname);
+       strfcat(hostfullname, hostdomain, sizeof hostfullname);
+     }
+   }
+   
+   /* Determine the default mail file name.
+    * 
+    * First look for an environment variable MAIL, then
+    * use then mailhome if it is not found
+    */
+   if ((cp = getenv("MAIL")) == NULL)
+     elm_sfprintf(defaultfile, sizeof defaultfile,
+ 		 FRM("%s%s"), mailhome, username);
+   else
+     strfcpy(defaultfile, cp, sizeof defaultfile);
+ 
+   alternative_addresses = NULL; 	/* none yet! */
+   
+   raw_local_signature[0] = raw_remote_signature[0] =
+     local_signature[0] = remote_signature[0] =
+     raw_recvdmail[0] = raw_sentmail[0] = 
+     allowed_precedences[0] = '\0';
+   /* no defaults for those */
+ 
+   if (NULL != (cp = getenv("SHELL")) && '\0' != cp[0]) {
+     strfcpy(raw_shell, "$SHELL", sizeof raw_shell);
+     do_expand_env("shell", shell, raw_shell, sizeof(shell));
+   } else {
+     /* Shell is set from /etc/passwd in initialize () */
+     raw_shell[0] = '\0';
+   }
+   strfcpy(raw_pager, ((cp = getenv("PAGER")) == NULL)? default_pager : cp,
+ 	  sizeof raw_pager);
+   do_expand_env("pager", pager, raw_pager, sizeof(pager));
+   
+   strfcpy(raw_temp_dir, (cp = getenv("TMPDIR")) ? cp : default_temp,
+ 	  sizeof raw_temp_dir);
+ 
+   do_expand_env("temp_dir", temp_dir, raw_temp_dir, sizeof(temp_dir));
+   if (temp_dir[0] == '\0' || 
+       temp_dir[strlen (temp_dir)-1] != '/')
+     strfcat(temp_dir, "/", sizeof temp_dir);
+   
+   if ((cp = getenv("EDITOR")) != NULL && '\0' != cp[0]) {
+     strfcpy(raw_editor, "$EDITOR", sizeof raw_editor);
+     strfcpy(editor, cp, sizeof editor);
+   } else {
+     strfcpy(raw_editor, default_editor, sizeof raw_editor);
+     do_expand_env("editor", editor, raw_editor, sizeof(editor));
+   }
+ 
+   strfcpy(alternative_editor, editor, sizeof alternative_editor);
+   
+   strfcpy(raw_printout, default_printout, sizeof raw_printout);
+   do_expand_env("printout", printout, raw_printout, sizeof(printout));
+   
+   elm_sfprintf(raw_folders, sizeof raw_folders, FRM("~/%s"), default_folders);
+   do_expand_env("folders", folders, raw_folders, sizeof(folders));
+   
+   elm_sfprintf(raw_calendar_file, sizeof raw_calendar_file,
+ 	       FRM("~/%s"), dflt_calendar_file);
+   do_expand_env("calendar_file", calendar_file, raw_calendar_file,
+ 		sizeof(calendar_file));
+ 
+   strfcpy(e_editor, emacs_editor, sizeof e_editor);
+   strfcpy(v_editor, default_editor, sizeof v_editor);
+   
+   strfcpy(raw_printout, default_printout, sizeof raw_printout);
+   strfcpy(printout, raw_printout, sizeof printout);
+ 
+   elm_sfprintf(raw_folders, sizeof raw_folders,
+ 	       FRM("%s/%s"), home, default_folders);
+   strfcpy(folders, raw_folders, sizeof folders);
+ 
+   elm_sfprintf(raw_calendar_file, sizeof raw_calendar_file,
+ 	       FRM("%s/%s"), home, dflt_calendar_file);
+   strfcpy(calendar_file, raw_calendar_file, sizeof calendar_file);
+ 
+ #ifdef MIME
+   strfcpy(charset, default_charset, sizeof charset);
+   strfcpy(charset_compatlist, COMPAT_CHARSETS, 
+ 	  sizeof charset_compatlist);
+   if (!getenv("NOMETAMAIL") && getenv("MM_CHARSET"))
+     strfcpy(raw_display_charset, "$MM_CHARSET",
+ 	    sizeof raw_display_charset);
+   else
+     strfcpy(raw_display_charset, DEFAULT_DISPLAY_CHARSET,
+ 	    sizeof raw_display_charset);
+ #endif
+ 
+   /* try system-wide rc file */
+   file = fopen(system_rc_file, "r");
+   if ( file != NULL ) {
+     do_rc(file, SYSTEM_RC,system_rc_file);
+     fclose(file);
+   }
+ 
+   return errors;
+ }
+ 
+ static void dump_rc_results P_((void));
+ 
+ int read_rc_file()
+ {
+ 	/** this routine does all the actual work of reading in the
+ 	    .rc file... **/
+ 
+ 	FILE *file;
+ 	char buffer[SLEN], filename[SLEN], *cp, 
+ 	     	temp[SLEN]; /* for when an option is run through expandenv */
+ 	int  i, ch, len, err;
+ 
+ 	errors = 0;
+ 
+ 	/* Look for the elmrc file */
+ 	if ((file = fopen(user_rc_file, "r")) == NULL) {
+ 	  dprint(2, (debugfile, 
+ 		     "Warning:User has no \"%s\" file\n\n",
+ 		     user_rc_file));
+ 	}
+ 
+ 	if (file != NULL) {
+   	  do_rc(file, LOCAL_RC, ELMRCFILE);
+ 	  fclose(file);
+ 	}
+ 
+ 	post_init_check();
+ 
+ 	return errors;
+ }
+ 
+ void post_init_check() {
+ 	char     buffer[SLEN];
+ 
+ 	do_expand_env("folders", folders, raw_folders, sizeof(folders));
+ 
+ 	do_expand_env("temp_dir", temp_dir, raw_temp_dir, sizeof(temp_dir));
+   	if ('\0' == temp_dir[0])
+ 	  strfcpy(temp_dir,"/tmp/", sizeof temp_dir);
+ 	else if (temp_dir[strlen (temp_dir)-1] != '/')
+ 	  strfcat(temp_dir, "/", sizeof temp_dir);
+   
+ 	if (raw_shell[0] != '\0') {
+ 	  /* shell is taken from /etc/passwd in initialize() */
+ 	  do_expand_env("shell", shell, raw_shell, sizeof(shell));
+ 	}
+ 	do_expand_env("editor", editor, raw_editor, sizeof(editor));
+ 
+ 	do_expand_env("calendar_file", calendar_file, raw_calendar_file,
+ 	    sizeof(calendar_file));
+ 
+ 	do_expand_env("printout", printout, raw_printout, sizeof(printout));
+ 
+ 	do_expand_env("pager", pager, raw_pager, sizeof(pager));
+ 	if (equal(pager, "builtin+") || equal(pager, "internal+"))
+ 		clear_pages++;
+ 
+ 	do_expand_env("local_signature", local_signature,
+ 	    raw_local_signature, sizeof(local_signature));
+ 	do_expand_env("remote_signature", remote_signature,
+ 	    raw_remote_signature, sizeof(remote_signature));
+ 
+ 	if (equal(local_signature, remote_signature) &&
+ 	    (equal(shift_lower(local_signature), "on") ||
+ 	    equal(shift_lower(local_signature), "off"))) {
+ 	    errors++;
+ 
+ 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSignatureObsolete,
+ 			      "\"signature\" used in obsolete way in .elm/elmrc file. Ignored!\n\
+ \t(Signature should specify the filename to use rather than on/off.)"));
+ 
+ 	    raw_local_signature[0] = raw_remote_signature[0] =
+ 		local_signature[0] = remote_signature[0] = '\0';
+ 	}
+ 
+ 	/* if (hp_softkeys) hp_terminal=TRUE; */	/* must be set also! */
+ 
+ 	allow_forms = (allow_forms?MAYBE:NO);
+ 
+ 	if ((elm_timeout != 0) && (elm_timeout < 10)) {
+ 	    errors++;
+ 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmTimeoutLTTen,
+ 			      "Warning: timeout is set to less than 10 seconds. Ignored."));
+ 	    elm_timeout = 0;
+ 	}
+ 
+ 	if (readmsginc < 1) {
+ 		errors++;
+ 		lib_error(CATGETS(elm_msg_cat, ElmSet, ElmReadMessageIncrement,
+ 				  "Warning: readmsginc is set to less than 1.  Ignored."));
+ 		readmsginc = 1;
+ 	}
+ 
+ 	if (sleepmsg < 0) {
+ 		errors++;
+ 		lib_error(CATGETS(elm_msg_cat, ElmSet, ElmSleepMessageInvalid,
+ 				  "Warning: sleepmsg is set to less than 0.  Setting to 0."));
+ 		sleepmsg = 0;
+ 	}
+ 
+ #ifdef BACKGROUD_PROCESSES       
+ 	if (background_wait_time  < 0) {
+ 	  errors++;
+ 	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBackgroundLLT,
+ 			    "Warning: background_wait_time is set less than 0. Setting to 0."));
+ 	  background_wait_time = 0;
+ 	}
+ #endif
+ 
+ 
+ 	/* If recvd_mail or sent_mail havent't yet been established in
+ 	 * the elmrc, establish them from their defaults.
+ 	 * Then if they begin with a metacharacter, replace it with the
+ 	 * folders directory name.
+ 	 */
+ 	if(*raw_recvdmail == '\0') {
+ 	  strfcpy(raw_recvdmail, default_recvdmail,
+ 		  sizeof raw_recvdmail);
+ 	}
+ 
+ 	do_expand_env("recvd_mail", recvd_mail, raw_recvdmail,
+ 	    sizeof(recvd_mail));
+ 
+ 	if(metachar(recvd_mail[0])) {
+ 	  strfcpy(buffer, &recvd_mail[1], sizeof buffer);
+ 	  elm_sfprintf(recvd_mail, sizeof recvd_mail,
+ 		       FRM("%s/%s"), folders, buffer);
+ 	}
+ 
+ 	if(*raw_sentmail == '\0') {
+ 	  strfcpy(raw_sentmail, default_sentmail, sizeof raw_sentmail);
+ 	  strfcpy(sent_mail, default_sentmail, sizeof sent_mail);
+ 	}
+ 
+ 	do_expand_env("sent_mail", sent_mail, raw_sentmail, sizeof(sent_mail));
+ 
+ 	if(metachar(sent_mail[0])) {
+ 	  strfcpy(buffer, &sent_mail[1], sizeof buffer);
+ 	  elm_sfprintf(sent_mail, sizeof sent_mail,
+ 		       FRM("%s/%s"), folders, buffer);
+ 	}
+ 
+ #ifdef MIME
+ 	do_expand_env("display_charset", default_display_charset, 
+ 		      raw_display_charset, 
+ 		      sizeof(default_display_charset));
+ 
+ 	if (0 != strcmp(display_locale,"NONE"))
+ 	  map_display_charset(display_locale);
+ 	else
+ 	  strfcpy(display_charset,default_display_charset, 
+ 		  sizeof display_charset);
+ 
+ 	if (0 != strcmp(raw_charset,"DISPLAY"))
+ 	  do_expand_env("charset", charset, 
+ 			raw_charset, 
+ 			sizeof(charset));
+ 	else
+ 	  strfcpy(charset,display_charset, 
+ 		  sizeof charset);
+ 
+ 
+ 	if (strcmp(raw_metamail_path,"none") == 0 || 
+ 	    raw_metamail_path[0] == '\0') {
+ 	  strfcpy(raw_metamail_path,"none", sizeof raw_metamail_path);
+ 	  strfcpy(metamail_path,"none", sizeof metamail_path);
+ 	} else if(strcmp(raw_metamail_path,"metamail") == 0) {
+ 	  if (getenv("NOMETAMAIL"))
+ 	    strfcpy(metamail_path,"none", sizeof metamail_path);
+ 	  else
+ 	    strfcpy(metamail_path,"metamail", sizeof metamail_path);
+ 	} else {
+ 	  do_expand_env("metamail", metamail_path, raw_metamail_path, 
+ 			sizeof(metamail_path));
+ 	}
+ #endif
+ 
+ #ifdef USE_PGP
+ 	if (strcmp(raw_pgp_path,"none") == 0 || 
+ 	    raw_pgp_path[0] == '\0') {
+ 	  strfcpy(raw_pgp_path,"none", sizeof raw_pgp_path);
+ 	  strfcpy(pgp_path,"none", sizeof pgp_path);
+ 	} else {
+ 	  do_expand_env("pgp", pgp_path, raw_pgp_path, 
+ 			sizeof(pgp_path));
+ 	}
+ #endif
+ }
+ 
+ static void weedout P_((char *)); /* Prototype */
+ static void alternatives P_((char *));      /* Prototype */
+ static int breakup P_((char *, char *, char *, int, int)); /* Prototype */
+ 
+ void do_rc(file, lcl, filename)
+      FILE *file;
+      int lcl;
+      char *filename;
+ {
+ 	static int prev_type = 0;
+ 	int x;
+ 	char buffer[SLEN], word1[SLEN], word2[SLEN];
+ 
+ 	if (!file) return;
+ 	lineno=0;
+ 
+ 	while (x = mail_gets(buffer, SLEN, file)) {
+ 	    lineno++;
+ 	    no_ret(buffer);	 	/* remove return */
+ 	    if (buffer[0] == '#'        /* comment       */
+ 	     || x < 2)     /* empty line    */
+ 	      continue;
+ 
+ 	    if(breakup(buffer, word1, word2,
+ 		       sizeof word1, sizeof word2) == -1)
+ 	        continue;		/* word2 is null - let default value stand */
+ 
+ 	    if(strcmp(word1, "warnings") == 0)
+ 		continue;		/* grandfather old keywords */
+ 
+ 	    strfcpy(word1, shift_lower(word1), 
+ 		    sizeof word1);	/* to lower case */
+ 	    x = do_set(file, word1, word2, lcl, 
+ 		       sizeof word2, filename);
+ 
+ 	    if (x == 0) {
+ 		if (prev_type == DT_ALT) {
+ 		    alternatives(buffer);
+ 		} else if (prev_type == DT_WEE) {
+ 		    weedout(buffer);
+ 		} else {
+ 		    errors++;
+ 		    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadKeyInElmrc,
+ 				      "I can't understand keyword \"%s\" in line %d in \"%s\" file"),
+ 			word1, lineno,filename);
+ 		}
+ 	    } else
+ 		prev_type = x;
+ 	}
+ }
+ 
+ /*
+  * set the named parameter according to save_info structure.
+  * This routine may call itself (DT_SYN or DT_MLT).
+  * Also tags params that were set in "local" (personal) RC file
+  * so we know to save them back out in "o)ptions" screen.
+  * Uses an internal table to decode sort-by params...should be coupled
+  * with sort_name(), etc...but...
+  */
+ 
+ int do_set(file, word1, word2, lcl, word2_size, filename)
+      FILE *file;
+      int lcl;
+      char *word1, *word2;
+      int word2_size;
+      char *filename;
+ {
+ 	int x, y;
+ 	int e_val = 0;
+ 
+ 	for (x=0; x < NUMBER_OF_SAVEABLE_OPTIONS; ++x) {
+ 	    y = strcmp(word1, save_info[x].name);
+ 	    if (y <= 0)
+ 		break;
+ 	}
+ 
+ 	if (y != 0)
+ 	    return(0);
+ 
+ 	if (save_info[x].flags & FL_SYS && lcl == LOCAL_RC)
+ 	    return(0);
+ 
+ 	if (lcl == LOCAL_RC)
+ 	    save_info[x].flags |= FL_LOCAL;
+ 
+ 	if (save_info[x].e_ptr) {
+ 	  int ci = -1, i;
+ 	  e_val = 0;    /* First value is 'unknown' */
+ 
+ 	  for (i = 0; i < save_info[x].e_ptr->nlen; i++)
+ 	    if (0 == strcmp(save_info[x].e_ptr->list[i],word2)) {
+ 	      e_val = i;
+ 	      break;
+ 	    } else if (0 == istrcmp(save_info[x].e_ptr->list[i],word2))
+ 	      ci = i;
+ 	  if (!e_val && ci >= 0)
+ 	    e_val = ci;
+ 
+ 	  if (i == save_info[x].e_ptr->nlen) {
+ 	    char *p;	    
+ 	    if (
+ 		((save_info[x].flags & DT_MASK) != DT_NUM || 
+ 		 strtol(word2,&p,10) < 0) || *p != '\0'
+ 		) { 
+ 	      
+ 	      errors++;
+ 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadEKeyInElmrc,
+ 				"I can't understand %s key \"%s\" in line %d in \"%s\" file"),
+ 			word1,word2, lineno,filename);
+ 	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadEKeyValues,
+ 				"Possible values are:"));
+ 	      for (i = 0; i < save_info[x].e_ptr->nlen; i++)
+ 		lib_error(FRM(" - %s"),save_info[x].e_ptr->list[i]);
+ 	    }
+ 	  }
+ 
+ 	} else
+ 	  e_val = 0;
+ 
+ 	switch (save_info[x].flags & DT_MASK) {
+ 	    int l;
+ 	    char *p;
+ 	    case DT_SYN:
+ 		return(do_set(file, SAVE_INFO_SYN(x), word2, lcl,
+ 			      word2_size, filename));
+ 
+ 	    case DT_MLT:
+ 		y=0;
+ 		{ register char **s;
+ 		for (s = SAVE_INFO_MLT(x); *s; ++s)
+ 		    y |= do_set(file, *s, word2, lcl, word2_size,filename);
+ 		}
+ 
+ /* a kludge that should be part of the "machine", but... */
+ 		if (equal(save_info[x].name, "alwaysleave")) {
+ 		    always_store = !always_store;
+ 		}
+ 		return(y); /* we shouldn't "or" the values into "y" */
+ 
+ 	    case DT_STR:
+ 	      if (strlen(word2) >= save_info[x].size_val) {
+ 		  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLongValueInElmrc,
+ 				    "Value of \"%s\" in line %d in \"%s\" file is too long"),
+ 			    word1,lineno,filename);
+ 		  errors++;
+ 	      }
+ 	      strfcpy(SAVE_INFO_STR(x), word2,
+ 		      save_info[x].size_val);
+ 	      if (save_info[x].flags & FL_NOSPC) {
+ 		register char *s;
+ 		for (s = SAVE_INFO_STR(x); *s; ++s)
+ 		  if (*s == '_') *s=' ';
+ 	      }
+ 	      break;
+ 
+ 	    case DT_CHR:
+ 		*SAVE_INFO_CHR(x) = word2[0];
+ 		break;
+ 
+ 	    case DT_NUM:
+ 	        l = strtol(word2,&p,10);
+ 	        if (save_info[x].e_ptr && (e_val || *p || l < 0))
+ 		  *SAVE_INFO_NUM(x) = e_val;
+ 		else
+ 		  *SAVE_INFO_NUM(x) = l;
+ 		break;
+ 
+ 	    case DT_PRM:
+ 	        {
+ 		    char *s = word2;
+ 		    int m = 0;
+ 		    char *modecharp = "rwxrwxrwx";
+ 		    int modebit = 0400;
+ 		    char c;
+ 
+ 		    while ((c = *s++) != '\0') {
+ 		    	if (c == *modecharp)
+ 			    m |= modebit;
+ 			else if (c != '-') {
+ 			    errors++;
+ 			    lib_error(CATGETS(elm_msg_cat, ElmSet, 
+ 					      ElmBadModeInElmrc,
+ 					      "I can't understand file permissions \"%s\" in line %d in \"%s\" file"),
+ 				      word2, lineno,filename);
+ 			    goto out;
+ 			}
+ 			modecharp++;
+ 			modebit >>= 1;
+ 		    }
+ 		    if (*modecharp != '\0') {
+ 		      errors++;
+ 		      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadModeInElmrc,
+ 					"I can't understand file permissions \"%s\" in line %d in \"%s\" file"),
+ 			     word2, lineno,filename);
+ 		      break;
+ 		    }
+ 		    *SAVE_INFO_NUM(x) = m;
+ 		}
+ 	out:
+ 	        break;
+ 
+ 	    case DT_BOL:
+ 		if (save_info[x].flags & FL_OR)
+ 		    *SAVE_INFO_BOL(x) |= is_it_on(word2);
+ 		else if (save_info[x].flags & FL_AND)
+ 		    *SAVE_INFO_BOL(x) &= is_it_on(word2);
+ 		else
+ 		    *SAVE_INFO_BOL(x) = is_it_on(word2);
+ 		break;
+ 
+ 	    case DT_SRT:
+ 		{ static struct { char *kw; int sv; } srtval[]={
+ 		    {"sent", SENT_DATE},
+ 		    {"received", RECEIVED_DATE},
+ 		    {"recieved", RECEIVED_DATE},
+ 		    {"rec", RECEIVED_DATE},
+ 		    {"from", SENDER},
+ 		    {"sender", SENDER},
+ 		    {"size", SIZE},
+ 		    {"lines", SIZE},
+ 		    {"subject", SUBJECT},
+ 		    {"mailbox", MAILBOX_ORDER},
+ 		    {"folder", MAILBOX_ORDER},
+ 		    {"status", STATUS},
+ 		    {NULL, 0} };
+ 		    char *s = word2;
+ 		    int f;
+ 
+ 		    f = 1;
+ 		    strfcpy(word2, shift_lower(word2), word2_size);
+ 		    if (strncmp(s, "rev-", 4) == 0 ||
+ 			strncmp(s, "reverse-", 8) == 0) {
+ 			f = -f;
+ 			s = index(s, '-') + 1;
+ 		    }
+ 
+ 		    for (y= 0; srtval[y].kw; y++) {
+ 			if (equal(s, srtval[y].kw))
+ 			    break;
+ 		    }
+ 		    if (srtval[y].kw) {
+ 			*SAVE_INFO_SRT(x) = f > 0 ? srtval[y].sv : -srtval[y].sv;
+ 		    } else {
+ 			errors++;
+ 			lib_error(CATGETS(elm_msg_cat, ElmSet, 
+ 					  ElmBadSortKeyInElmrc,
+ 					  "I can't understand sort key \"%s\" in line %d in \"%s\" file"),
+ 				  word2, lineno, filename);
+ 		    }
+ 		}
+ 		break;
+ 
+ 	    case DT_ASR:
+ 		{ static struct { char *kw; int sv; } srtval[]={
+ 		    {"alias", ALIAS_SORT},
+ 		    {"name", NAME_SORT},
+ 		    {"text", TEXT_SORT},
+ 		    {NULL, 0} };
+ 		    char *s = word2;
+ 		    int f;
+ 
+ 		    f = 1;
+ 		    strfcpy(word2, shift_lower(word2), word2_size);
+ 		    if (strncmp(s, "rev-", 4) == 0 ||
+ 			strncmp(s, "reverse-", 8) == 0) {
+ 			f = -f;
+ 			s = index(s, '-') + 1;
+ 		    }
+ 
+ 		    for (y= 0; srtval[y].kw; y++) {
+ 			if (equal(s, srtval[y].kw))
+ 			    break;
+ 		    }
+ 		    if (srtval[y].kw) {
+ 			*SAVE_INFO_SRT(x) = f > 0 ? srtval[y].sv : -srtval[y].sv;
+ 		    } else {
+ 			errors++;
+ 			lib_error(CATGETS(elm_msg_cat, ElmSet, 
+ 					  ElmBadAliasSortInElmrc,
+ 					  "I can't understand alias sort key \"%s\" in line %d in \"%s\" file"),
+ 				  word2, lineno,filename);
+ 		    }
+ 		}
+ 		break;
+ 
+ 	    case DT_ALT:
+ 		alternatives(word2);
+ 		break;
+ 
+ 	    case DT_WEE:
+ 		weedout(word2);
+ 		break;
+ 	    }
+ 
+ 	return(save_info[x].flags & DT_MASK);
+ }
+ 	
+ static void weedout(string)
+      char *string;
+ {
+ 	/** This routine is called with a list of headers to weed out.   **/
+ 
+ 	char *strptr, *header, *p;
+ 	int Len;
+ 	int finished;
+ 
+ 	finished = FALSE;
+ 	strptr = string;
+ 	while (!finished && (header = strtokq(strptr, "\t ,", TRUE)) != NULL) {
+ 	  strptr = NULL;
+ 
+ 	  if (!*header)
+ 	    continue;
+ 
+ 	  for (p = header; *p; ++p) {
+ 	    if (*p == '_')
+ 	      *p = ' ';
+ 	  }
+ 
+ 	  if (! istrcmp(header, "*end-of-user-headers*"))
+ 	    break;
+ 
+ 	  if (! istrcmp(header, "*end-of-defaults*"))
+ 	    finished = TRUE;
+ 
+ 	  if (! istrcmp(header, "*clear-weed-list*")) {
+ 	    while (weedcount)
+ 	      free(weedlist[--weedcount]);
+ 	    header = "*end-of-defaults*";
+ 	  }
+ 
+ 	  if (matches_weedlist(header))
+ 	    continue;
+ 
+ 	  if (weedcount > MAX_IN_WEEDLIST) {
+ 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmTooManyWeedHeaders,
+ 			      "Too many weed headers!  Leaving..."));
+ 	    exit(1);
+ 	  }
+ 	  Len = strlen(header) + 1;
+ 	  if ((p = malloc(Len)) == NULL) {
+ 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmTooManyWeedPmalloc,
+ 			      "Too many weed headers!  Out of memory!  Leaving..."));
+ 	    exit(1);
+ 	  }
+ 	  strfcpy(p, header, Len);
+ 	  weedlist[weedcount++] = p;
+ 	}
+ }
+ 
+ static void alternatives(string)
+      char *string;
+ {
+ 	/** This routine is called with a list of alternative addresses
+ 	    that you may receive mail from (forwarded) **/
+ 
+ 	char *strptr, *address;
+ 	struct addr_rec *current_record, *previous_record;
+ 
+ 	previous_record = alternative_addresses;	/* start 'er up! */
+ 	/* move to the END of the alternative addresses list */
+ 
+ 	if (previous_record != NULL)
+ 	  while (previous_record->next != NULL)
+ 	    previous_record = previous_record->next;
+ 
+ 	strptr = (char *) string;
+ 
+ 	while ((address = strtok(strptr, "\t ,\"'")) != NULL) {
+ 	  if (previous_record == NULL) {
+ 	    previous_record = (struct addr_rec *) pmalloc(sizeof 
+ 		*alternative_addresses);
+ 
+ 	    strfcpy(previous_record->address, address,
+ 		    sizeof previous_record->address);
+ 	    previous_record->next = NULL;
+ 	    alternative_addresses = previous_record;
+ 	  }
+ 	  else {
+ 	    current_record = (struct addr_rec *) pmalloc(sizeof 
+ 		*alternative_addresses);
+ 	  
+ 	    strfcpy(current_record->address, address,
+ 		    sizeof current_record->address);
+ 	    current_record->next = NULL;
+ 	    previous_record->next = current_record;
+ 	    previous_record = current_record;
+ 	  }
+ 	  strptr = (char *) NULL;
+ 	}
+ }
+ 
+ default_weedlist()
+ {
+ 	/** Install the default headers to weed out!  Many gracious 
+ 	    thanks to John Lebovitz for this dynamic method of 
+ 	    allocation!
+ 	**/
+ 
+ 	static char *default_list[] = { ">From", "In-Reply-To:",
+ 		       "References:", "Newsgroups:", "Received:",
+ 		       "Apparently-To:", "Message-Id:", "Content-Type:",
+ 		       "Content-Length", "MIME-Version",
+ 		       "Content-Transfer-Encoding",
+ 		       "From", "X-Mailer:", "Status:",
+ 		       "X-ELM-",
+ 		       "*end-of-defaults*", NULL
+ 		     };
+ 
+ 	for (weedcount = 0; default_list[weedcount] != (char *) 0;weedcount++){
+ 	  int Len = strlen(default_list[weedcount]) + 1;
+ 	  if ((weedlist[weedcount] = 
+ 	      malloc(Len)) == NULL) {
+ 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNoMemDefaultWeed,
+ 			      "Not enough memory for default weedlist. Leaving."));
+ 	     (*safe_malloc_fail_handler)("default_weedlist", Len);
+ 	     return;
+ 	  }
+ 	  strfcpy(weedlist[weedcount], default_list[weedcount], Len);
+ 	}
+ }
+ 
+ int
+ matches_weedlist(buffer)
+ char *buffer;
+ {
+ 	/** returns true iff the first 'n' characters of 'buffer' 
+ 	    match an entry of the weedlist **/
+ 	
+ 	register int i;
+ 
+ 	for (i=0;i < weedcount; i++)
+ 	  if (strincmp(buffer, weedlist[i], strlen(weedlist[i])) == 0) 
+ 	    return(1);
+ 
+ 	return(0);
+ }
+ 
+ static int breakup(buffer, word1, word2, size_word1, size_word2)
+      char *buffer, *word1, *word2;
+      int size_word1, size_word2;
+ {
+ 	/** This routine breaks buffer down into word1, word2 where 
+ 	    word1 is alpha characters only, and there is an equal
+ 	    sign delimiting the two...
+ 		alpha = beta
+ 	    For lines with more than one 'rhs', word2 is set to the
+ 	    entire string.
+ 	    Return -1 if word 2 is of zero length, else 0.
+ 	**/
+ 
+ 	int i;
+ 	
+ 	for (i=0;
+ 	     buffer[i] != '\0' && ok_rc_char(buffer[i]) && i < size_word1 -1; 
+ 	     i++)
+ 	  if (buffer[i] == '_')
+ 	    word1[i] = '-';
+ 	  else
+ 	    word1[i] = tolower(buffer[i]);
+ 
+ 	word1[i++] = '\0';	/* that's the first word! */
+ 
+ 	/** spaces before equal sign? **/
+ 
+ 	while (whitespace(buffer[i])) i++;
+ 	if (buffer[i] == '=') i++;
+ 
+ 	/** spaces after equal sign? **/
+ 
+ 	while (whitespace(buffer[i])) i++;
+ 
+ 	if (buffer[i] != '\0')
+ 	  strfcpy(word2, (char *) (buffer + i), size_word2);
+ 	else
+ 	  word2[0] = '\0';
+ 
+ 	/* remove trailing spaces from word2! */
+ 	i = strlen(word2) - 1;
+ 	while(i && (whitespace(word2[i]) || word2[i] == '\n'))
+ 	  word2[i--] = '\0';
+ 
+ 	return(*word2 == '\0' ? -1 : 0 );
+ 
+ }
+ 
+ 
+ /*
+  * expand_env() - Perform environment expansion on a pathname.  Also
+  * replaces "~" at the front of the path with the user's home directory.
+  * Environment expansion occurs at the path component boundaries, e.g.
+  * "/foo/$BAR/baz" is subject to expansion but "/foo/zzz$BAR/baz" is not.
+  * Returns 0 if expansion successful, -1 if an error occurs (result too
+  * long, cannot get home directory, or environment expansion failed).
+  */
+ expand_env(dest, src, destlen)
+ char *dest;		/* pointer to space to hold the result	*/
+ char *src;		/* pointer to string to expand		*/
+ unsigned destlen;	/* size of the destination buffer	*/
+ {
+     char envname_buf[SLEN], *envname_front, *expval;
+     int check_for_env, len, ret;
+ 
+     --destlen;		/* reserve space for trailing '\0' */
+     ret = 0;		/* assume success */
+ 
+     /*
+      * Replace "~" at front with user's home directory.
+      */
+     if (src[0] == '~' && (src[1] == '\0' || src[1] == '/')) {
+ 	if (home[0] == '\0') {
+ 	    expval = "~";
+ 	    ret = -1;
+ 	} else {
+ 	    expval = home;
+ 	}
+ 	if ((len = strlen(expval)) > destlen)
+ 	    len = destlen;
+ 	strfcpy(dest, expval, len+1);
+ 	dest += len;
+ 	destlen -= len;
+ 	++src;
+     }
+ 
+     /*
+      * Copy through the rest, performing $NAME expansion where appropriate.
+      */
+     check_for_env = TRUE;
+     while (destlen > 0 && *src != '\0') {
+ 
+ 	/*
+ 	 * Check for "$NAME" at the start of every path component.
+ 	 */
+ 	if (check_for_env && *src == '$') {
+ 
+ 	    /*
+ 	     * Get the environment parameter name into "envname_buf"
+ 	     * and advance "src" to the next path component.
+ 	     */
+ 	    envname_front = ++src;
+ 	    if ((len = strcspn(src, "/")) == 0)
+ 		len = strlen(src);
+ 	    src += len;
+ 	    if (len > sizeof(envname_buf)-1)
+ 		len = sizeof(envname_buf)-1;
+ 	    strfcpy(envname_buf, envname_front, len+1);
+ 
+ 	    /*
+ 	     * Copy over the environment expansion.  If the environment
+ 	     * parameter is undefined then copy over unchanged and set
+ 	     * a fail return status.
+ 	     */
+ 	    if ((expval = getenv(envname_buf)) == NULL) {
+ 		*dest++ = '$';
+ 		--destlen;
+ 		expval = envname_buf;
+ 		ret = -1;
+ 	    }
+ 	    if ((len = strlen(expval)) > destlen)
+ 		len = destlen;
+ 	    strfcpy(dest, expval, len+1);
+ 	    dest += len;
+ 	    destlen -= len;
+ 	    check_for_env = FALSE;
+ 
+ 	} else {
+ 
+ 	    check_for_env = (*src == '/');
+ 	    *dest++ = *src++;
+ 	    --destlen;
+ 
+ 	}
+ 
+     }
+ 
+     *dest = '\0';
+     if (destlen <= 0)
+ 	ret = -1;
+     return ret;
+ }
+ 
+ is_it_on(word)
+ char *word;
+ {
+ 	/** Returns TRUE if the specified word is either 'ON', 'YES'
+ 	    or 'TRUE', and FALSE otherwise.   We explicitly translate
+ 	    to lowercase here to ensure that we have the fastest
+ 	    routine possible - we really DON'T want to have this take
+ 	    a long time or our startup will be major pain each time.
+ 	**/
+ 
+ 	static char mybuffer[NLEN];
+ 	register int i, j;
+ 
+ 	for (i=0, j=0; word[i] != '\0'; i++)
+ 	  mybuffer[j++] = tolower(word[i]);
+ 	mybuffer[j] = '\0';
+ 
+ 	return(  (strncmp(mybuffer, "on",   2) == 0) ||
+ 		 (strncmp(mybuffer, "yes",  3) == 0) ||
+ 		 (strncmp(mybuffer, "true", 4) == 0)
+ 	      );
+ }
+ 
+ char *
+ mode_to_str(mode)
+ int mode;
+ {
+ 	static char modestr[9+1];	/* "rwxrwxrwx\0" */
+ 	char *s = &modestr[0];
+ 	char *modecharp = "rwxrwxrwx";
+ 	int modebit = 0400;
+ 
+ 	while (modebit != 0) {
+ 	    if (mode & modebit)
+ 	        *s++ = *modecharp;
+ 	    else
+ 		*s++ = '-';
+ 	    modecharp++;
+ 	    modebit >>= 1;
+ 	}
+ 	*s = '\0';
+ 	return(modestr);
+ }
+ 
Index: elm2.4.ME+.50/lib/pmalloc.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/lib/pmalloc.c	Tue Nov 17 21:12:56 1998
***************
*** 0 ****
--- 1,89 ----
+ 
+ static char rcsid[] = "@(#)$Id: pmalloc.c,v 1.2 1998/10/20 19:57:47 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
+  *
+  *  Modified by: Kari Hurtta <hurtta+elm@ozone.FMI.FI>
+  ******************************************************************************
+  *  The Elm Mail System 
+  *
+  *			Copyright (c) 1988-1992 USENET Community Trust
+  *			Copyright (c) 1986,1987 Dave Taylor
+  *****************************************************************************/
+ 
+ /** This routine contains a cheap permanent version of the malloc call to 
+     speed up the initial allocation of the weedout headers and the uuname 
+     data.  
+ 
+       This routine is originally from Jim Davis of HP Labs, with some 
+     mods by me.
+ **/
+ 
+ #include <stdio.h>
+ #include "headers.h"
+ #include "s_elm.h"
+ 
+ extern nl_catd elm_msg_cat;	/* message catalog	    */
+ /*VARARGS0*/
+ 
+ #define MIN_BOUNDARY 8 /* power to 2 */
+ 
+ char *pmalloc(size)
+ int size; 
+ {
+ 	/** return the address of a specified block **/
+ 
+ 	static char *our_block = NULL;
+ 	static int   free_mem  = 0;
+ 
+ 	char   *return_value;
+ 
+ 	/** if bigger than our threshold, just do the real thing! **/
+ 
+ 	if (size > PMALLOC_THRESHOLD) 
+ 	   return((char *) safe_malloc(size));
+ 
+ 	/** if bigger than available space, get more, tossing what's left **/
+ 
+ 	dprint(20, (debugfile,"pmalloc(size=%d)",size));
+ 
+ 	size = ((size+(MIN_BOUNDARY-1)+4)/
+ 		MIN_BOUNDARY)*MIN_BOUNDARY;	
+ 	/* Go to MIN_BOUNDARY byte boundary, fill */
+ 
+ 	dprint(20, (debugfile," rounding size to %d, free_mem=%d",size,
+ 		    free_mem));
+ 
+ 	if (size > free_mem-4) {
+ 	  if ((our_block = (char *) malloc(PMALLOC_BUFFER_SIZE)) == NULL) {
+ 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCouldntMallocBytes,
+ 			      "Couldn't malloc %d bytes!!"),
+ 		      PMALLOC_BUFFER_SIZE);
+ 	    (*safe_malloc_fail_handler)("pmalloc", PMALLOC_BUFFER_SIZE);
+ 	    return NULL;
+           }
+ 	  dprint(20, (debugfile,", allocating=%lX (%d bytes)",
+ 		      (long)our_block, PMALLOC_BUFFER_SIZE));;
+ 	  our_block += 4;  /* just for safety, don't give back true address */
+ 	  free_mem = PMALLOC_BUFFER_SIZE-4;
+ 
+ 	}
+ 
+ 	if (((long)our_block&(MIN_BOUNDARY-1)) != 0) {
+ 	  int		drek;
+ 
+ 	  drek = ((long)our_block&(MIN_BOUNDARY-1)); /* round to minimum */
+ 	  our_block += (MIN_BOUNDARY-drek);
+ 	  free_mem -= (MIN_BOUNDARY-drek);
+ 	}
+ 
+ 	return_value  = our_block;	/* get the memory */
+ 	our_block += size;		/* use it up      */
+ 	free_mem  -= size;		/*  and decrement */
+ 
+ 	dprint(20, (debugfile,", returning=%lX (free_mem=%d)\n",
+ 		    (long)return_value,free_mem));
+ 
+ 	return( (char *) return_value);
+ }
Index: elm2.4.ME+.50/nls/C/C/C/s_me.m
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/nls/C/C/C/s_me.m	Tue Nov 17 21:12:57 1998
***************
*** 0 ****
--- 1,139 ----
+ $set 20 #Me
+ $ #DecodeDesc
+ 1	"%.60s"]\n[
+ $ #DecodeDescFilename
+ 2	Filename: %.60s]\n[
+ $ #DecodeAttach
+ 3	%s[Attach #%d: %sType: %.15s/%.30s, Encoding: %s, Size: %d]\n
+ $ #DecodePart
+ 4	%s[Part #%d: %sType: %.15s/%.30s, Encoding: %s, Size: %d]\n
+ $ #DecodeContentDesc
+ 5	Content-Description: %.300s\n\n
+ $ #DecodeSelAttach
+ 6	[Selecting attach: %sType: %.15s/%.30s, Encoding: %s, Size: %d]\n
+ $ #DecodeSelPart
+ 7	[Selecting part: %sType: %.15s/%.30s, Encoding: %s, Size: %d]\n
+ $ #DecodeCtNoAlternative
+ 8	Content-Type: multipart/alternative, alternative not found
+ $ #DecodeStartMail
+ 9	-- Start of included mail From: %s\n
+ $ #DecodeStartMail1
+ 10	-- Start of included mail.\n
+ $ #DecodeNoRFC822
+ 11	rfc822_decode: no body of RFC 822 mail (parts = NULL)
+ $ #DecodeEndMail
+ 12	-- End of included mail.\n
+ $ #DecodeCharsetSkipping
+ 13	[Charset %.15s unsupported, skipping...]\n
+ $ #DecodeUseVtoView
+ 14	[Use 'v' to view or save this part.]\n
+ $ #DecodeCharsetFiltering
+ 15	[Charset %.15s unsupported, filtering to ASCII...]\n
+ $ #DecodeUseAlsoV
+ 16	[You can also use 'v' to view or save this part.]\n\n
+ $ #DecodeUnsupportedText
+ 17	[%s/%.30s is unsupported, treating like TEXT/PLAIN]\n\n
+ $ #DecodeUnsupportedSkip
+ 18	[%.15s/%.30s is not supported, skipping...]\n
+ $ #DecodeUseVtosave
+ 19	[Use 'v' to view or save this part.]\n
+ $ #DecodeBASE64Corrupt
+ 20	BASE64 data was corrupt!
+ $ #DecodeQPCorrupt
+ 21	Seems that QUOTED-PRINTABLE data was corrupted.
+ $ #DecodeMultipartUnsupportedIS
+ 22	multipart_decode: unsupported input state
+ $ #DecodeMultipartSeekFail
+ 23	multipart_decode: seek failed
+ $ #DecodeAlternativeUnsupportedIS
+ 24	alternative_decode: unsupported input state
+ $ #DecodeAlternativeNosubtypes
+ 25	Content-Type: multipart/alternative, no subtypes (parts=null)
+ $ #DecodeAlternativeSeekFailed
+ 26	multipart_alternative: seek failed
+ $ #DecodeMultipartNoparts
+ 27	Content-Type: multipart/*, no subtypes (parts = NULL)
+ $ #DecodeRFC822UnsupportedIS
+ 28	rfc822_decode: unsupported input state
+ $ #DecodeRFC822SeekFailed
+ 29	rfc822_decode: seek failed
+ $ #DecodeFailedCreate
+ 30	Failed to create file for decoding.
+ $ #DecodeErrorFlush
+ 31	Error when flushing temporary file.
+ $ #DecodeMimeUnsupportedIS
+ 32	mime_decode: unsupported input state
+ $ #DecodeMimeSeekFailed
+ 33	mime_decode: seek failed
+ $ #DecodeEncodingSkipping
+ 34	[Unsupported encoding, skipping...]\n
+ $ #DecodeUseVEncodedSave
+ 35	[Use 'v' to save this part in encoded form.]\n
+ $ #DecodeStartElmEncoded
+ 36	-- Start of (Elm) encoded section.\n
+ $ #DecodeEndElmEncoded
+ 37	-- End of (Elm) encoded section.\n
+ $ #DecodeAttachUseV
+ 38	[Attachment, skipping...  Use 'v' to view this part.]\n
+ $ #DecodeAttachSkipping
+ 39	[Attachment, skipping...]\n
+ $ #PgpEncodedCantEncoding
+ 40	-- Start of PGP encoded section -- can't decode content-transfer-encoding\n
+ $ #PgpSignedCantEncoding
+ 41	-- Start of PGP signed section -- can't decode content-transfer-encoding\n
+ $ #PgpCantEncoding
+ 42	-- Start of PGP section -- can't decode content-transfer-encoding\n
+ $ #PgpNoTextEncoded
+ 43	[No text in PGP encoded section]\n
+ $ #PgpNoTextSigned
+ 44	[No text in PGP signed section]\n
+ $ #PgpNoText
+ 45	[No text in PGP section]\n
+ $ #PgpStartEncoded
+ 46	-- Start of PGP encoded section.\n
+ $ #PgpStartSigned
+ 47	-- Start of PGP signed section.\n
+ $ #PgpStart
+ 48	-- Start of PGP section.\n
+ $ #PgpEndEncoded
+ 49	-- End of PGP encoded section%s\n
+ $ #PgpEndSigned
+ 50	-- End of PGP signed section%s\n
+ $ #PgpEnd
+ 51	-- End of PGP section%s\n
+ $ #PgpFail
+ 52	, PGP failed!
+ $ #PgpCantExecute
+ 53	Can't execute pgp: %.50s: %.30s
+ $ #PgpPath
+ 54	PGP path must start with '/': %.60s
+ $ #PgpCantCreate
+ 55	Failed to create file for decoding.
+ $ #PgpBadPassphrase
+ 56	Decrypting message... Bad PGP passphrase.
+ $ #PgpInternalSkipping
+ 57	[Internal error while calling pgp, skipping...]\n
+ $ #PgpInternalRawdata
+ 58	[Internal error while calling pgp, raw data follows]\n
+ $ #PgpErrorFlush
+ 59	Error when flushing temporary file.
+ $ #PgpPublicKeys
+ 60	(** This message contains PGP public key(s) **)\n\n
+ $ #PgpNoText1
+ 61	[No text in PGP section.]\n
+ $ #PgpBinary
+ 62	[Binary file, but does not look like PGP]\n
+ $ #PgpBefore
+ 63	[There is text before PGP section.]\n
+ $ #PgpRawEnd
+ 64	[End of raw data]\n
+ $ #FailedSeekEnvelope
+ 65	Failed to seek beginning of mail envelope (%ld)
+ $ #FailedSeekHeaders
+ 66	Failed to seek beginning of mail headers (%ld)
+ $ #PgpDecryptMes
+ 67	Running pgp: Decrypting message...\n
+ $ #PgpCheckSig
+ 68	Running pgp: Checking signature...\n
+ $ #PgpRun
+ 69	Running pgp ...\n
Index: elm2.4.ME+.50/hdrs/s_me.h
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/hdrs/s_me.h	Tue Nov 17 21:12:55 1998
***************
*** 0 ****
--- 1,71 ----
+ 
+ #define MeSet	0x14
+ #define MeDecodeDesc	0x1
+ #define MeDecodeDescFilename	0x2
+ #define MeDecodeAttach	0x3
+ #define MeDecodePart	0x4
+ #define MeDecodeContentDesc	0x5
+ #define MeDecodeSelAttach	0x6
+ #define MeDecodeSelPart	0x7
+ #define MeDecodeCtNoAlternative	0x8
+ #define MeDecodeStartMail	0x9
+ #define MeDecodeStartMail1	0xa
+ #define MeDecodeNoRFC822	0xb
+ #define MeDecodeEndMail	0xc
+ #define MeDecodeCharsetSkipping	0xd
+ #define MeDecodeUseVtoView	0xe
+ #define MeDecodeCharsetFiltering	0xf
+ #define MeDecodeUseAlsoV	0x10
+ #define MeDecodeUnsupportedText	0x11
+ #define MeDecodeUnsupportedSkip	0x12
+ #define MeDecodeUseVtosave	0x13
+ #define MeDecodeBASE64Corrupt	0x14
+ #define MeDecodeQPCorrupt	0x15
+ #define MeDecodeMultipartUnsupportedIS	0x16
+ #define MeDecodeMultipartSeekFail	0x17
+ #define MeDecodeAlternativeUnsupportedIS	0x18
+ #define MeDecodeAlternativeNosubtypes	0x19
+ #define MeDecodeAlternativeSeekFailed	0x1a
+ #define MeDecodeMultipartNoparts	0x1b
+ #define MeDecodeRFC822UnsupportedIS	0x1c
+ #define MeDecodeRFC822SeekFailed	0x1d
+ #define MeDecodeFailedCreate	0x1e
+ #define MeDecodeErrorFlush	0x1f
+ #define MeDecodeMimeUnsupportedIS	0x20
+ #define MeDecodeMimeSeekFailed	0x21
+ #define MeDecodeEncodingSkipping	0x22
+ #define MeDecodeUseVEncodedSave	0x23
+ #define MeDecodeStartElmEncoded	0x24
+ #define MeDecodeEndElmEncoded	0x25
+ #define MeDecodeAttachUseV	0x26
+ #define MeDecodeAttachSkipping	0x27
+ #define MePgpEncodedCantEncoding	0x28
+ #define MePgpSignedCantEncoding	0x29
+ #define MePgpCantEncoding	0x2a
+ #define MePgpNoTextEncoded	0x2b
+ #define MePgpNoTextSigned	0x2c
+ #define MePgpNoText	0x2d
+ #define MePgpStartEncoded	0x2e
+ #define MePgpStartSigned	0x2f
+ #define MePgpStart	0x30
+ #define MePgpEndEncoded	0x31
+ #define MePgpEndSigned	0x32
+ #define MePgpEnd	0x33
+ #define MePgpFail	0x34
+ #define MePgpCantExecute	0x35
+ #define MePgpPath	0x36
+ #define MePgpCantCreate	0x37
+ #define MePgpBadPassphrase	0x38
+ #define MePgpInternalSkipping	0x39
+ #define MePgpInternalRawdata	0x3a
+ #define MePgpErrorFlush	0x3b
+ #define MePgpPublicKeys	0x3c
+ #define MePgpNoText1	0x3d
+ #define MePgpBinary	0x3e
+ #define MePgpBefore	0x3f
+ #define MePgpRawEnd	0x40
+ #define MeFailedSeekEnvelope	0x41
+ #define MeFailedSeekHeaders	0x42
+ #define MePgpDecryptMes	0x43
+ #define MePgpCheckSig	0x44
+ #define MePgpRun	0x45
Index: elm2.4.ME+.50/lib/getaddr.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/lib/getaddr.c	Tue Nov 17 21:12:55 1998
***************
*** 0 ****
--- 1,509 ----
+ #include "headers.h"
+ 
+ /* Content partially moved from melib/parse_util.c
+  *
+  * Author: Kari Hurtta
+  */
+ 
+ char **rfc822_tokenize(line) 
+      const char *line;
+ {
+   const char * ptr;
+   char **res;
+   int len, count = 0,i;
+   
+   dprint(25,(debugfile,"rfc822_tokenize(line=\"%s\n\"):\n",line));
+ 
+   for (ptr = line; *ptr; ptr += len) {
+     len = rfc822_toklen(ptr);
+     count++;
+   }
+   dprint(25,(debugfile,"rfc822_tokenize: count=%d\n",count));
+   res = safe_malloc((count+1) * sizeof (char *));
+   
+   for (i = 0, ptr = line; 
+        i < count; 
+        i++, ptr += len) {
+     len = rfc822_toklen(ptr);
+     res[i] = safe_malloc(len+1);
+     strncpy(res[i],ptr,len);
+     res[i][len] = '\0';
+     dprint(25,(debugfile,"             : [%i]=\"%s\"\n",i,res[i]));
+   }
+   res[count] = NULL;
+   dprint(25,(debugfile,"             : [%i]=NULL\n",count));
+   return res;
+ }
+ 
+ void remove_space_tokenized(tokenized)
+      char ** tokenized;
+ {
+   int ptr, ptr2 = 0;
+ 
+   for (ptr = 0; tokenized[ptr]; ptr++) {
+     if ('(' == tokenized[ptr][0] || whitespace(tokenized[ptr][0]) ||
+ 	'\n' == tokenized[ptr][0]) {
+       dprint(25,(debugfile,"remove_space_tokenized: FREE \t<= [%d] = \"%s\"\n",
+ 		 ptr,tokenized[ptr]));
+       free(tokenized[ptr]);
+       tokenized[ptr] = NULL;
+     } else {
+       dprint(25,(debugfile,"remove_space_tokenized: [%d] \t<= [%d] = \"%s\"\n",
+ 		 ptr2,ptr,tokenized[ptr]));
+       tokenized[ptr2] = tokenized[ptr];
+       if (ptr2 != ptr)
+ 	tokenized[ptr] = NULL;
+       ptr2++;
+     }
+   }
+   /* Check: */
+   while (ptr2 <= ptr) {
+     if (!tokenized[ptr2]) {
+       dprint(25,(debugfile,"remove_space_tokenized: [%d] \t<= NULL\n",
+ 		 ptr2));
+     } else {
+       dprint(25,(debugfile,"remove_space_tokenized: [%d] \t== \"%s\" ERROR!\n",
+ 		 ptr2,tokenized[ptr2]));
+     }
+     ptr2++;
+   }
+ }
+ 
+ void free_rfc822tokenized(res)
+      char **res; 
+ {
+   int i;
+   for (i = 0; res[i]; i++) {
+     dprint(100,(debugfile,"free_rfc822tokenized: free(res[%d]=\"%s\")\n",
+ 		i,res[i]));
+     free(res[i]);
+   }
+   dprint(100,(debugfile,"free_rfc822tokenized: free(res)\n"));
+   free(res);
+ }
+ 
+ static int look_special_tokens P_((char **tokenized,
+ 			       const char *tok_chars,
+ 			       int start, int *ended,
+ 			       decode_who decoder,
+ 			       char **comments,
+ 			       char ***scanned));
+ 
+ static int look_special_tokens(tokenized,tok_chars,
+ 			       start,ended,decoder,
+ 			       comments,scanned) 
+      char **tokenized;
+      const char *tok_chars;
+      int start; 
+      int *ended;
+      decode_who decoder;
+      char **comments;
+      char ***scanned;
+ {
+   int end;
+ 
+   dprint(30,(debugfile,
+ 	     "look_special_tokens: start=%d, tok_chars=%s,*comments=%X=%s\n", 
+ 	     start,tok_chars,*comments,NONULL(*comments)));
+   
+   *scanned = NULL;
+ 
+   dprint(30,(debugfile,
+ 	     "look_special_tokens: "));
+ 
+   for (end = start; tokenized[end]; end++) {
+     if (NULL != strchr(tok_chars,tokenized[end][0]) &&
+ 	'\0' == tokenized[end][1])
+       break;
+     dprint(30,(debugfile," [%d]=%s",end,tokenized[end]));
+   }
+   dprint(30,(debugfile,"\n"));
+ 
+   if (!tokenized[end]) {
+     dprint(30,(debugfile,"look_special_tokens: end=%d NO MATCH\n",end));
+   } else {
+     dprint(30,(debugfile,"look_special_tokens: end=%d MATCH=%s\n",
+ 	       end,tokenized[end]));
+   }
+   if (end > start) {
+     int count = end-start;
+     int i, in_ptr,out_ptr;
+     char **res;
+     dprint(31,(debugfile,"look_special_tokens: count=%d\n",
+ 	       count));
+ 
+     res = safe_malloc((count+1) * sizeof (char *));
+     for (i = 0; i <= count; i++)
+       res[i] = NULL;
+ 
+     for (in_ptr=start, out_ptr=0;
+ 	 in_ptr < end && out_ptr < count;
+ 	 in_ptr++) {
+       if (whitespace(tokenized[in_ptr][0])) {
+ 	if (*comments && (*comments)[0] && in_ptr < end-1)
+ 	  *comments = strmcat(*comments,tokenized[in_ptr]);
+       } else if ('(' == tokenized[in_ptr][0]) {
+ 	char buffer[1000];
+ 	int k, j = 0;
+ 
+ 	for (k = 1; tokenized[in_ptr][k] && 
+ 	       (tokenized[in_ptr][k] != ')' || tokenized[in_ptr][k+1]) &&
+ 	       j < sizeof buffer -1; k++)
+ 	  buffer[j++] = tokenized[in_ptr][k];
+ 	buffer[j] = '\0';
+ 	    
+ 	/* MIME decode */
+ 	decoder(HDR_COMMENT,buffer,sizeof buffer );
+ 
+ 	*comments = strmcat(*comments,buffer);
+       } else
+ 	res[out_ptr++] = safe_strdup(tokenized[in_ptr]);       
+     }
+ 
+     dprint(31,(debugfile,"look_special_tokens: real count=%d, scanned:",
+ 	       out_ptr));
+ 
+     for (i = 0; i < out_ptr; i++) {
+       dprint(31,(debugfile," [%d]=%s",i,res[i]));
+     }
+     *scanned=res;
+ 
+     dprint(31,(debugfile,
+ 	       "\nlook_special_tokens: *scanned=%X, *comments=%X=%s\n",
+ 	       *scanned,*comments,NONULL(*comments)));
+   }
+   if (ended)
+     *ended = end;
+   dprint(30,(debugfile,"look_special_tokens=%d\n",end-start));
+   return end-start;
+ }
+ 
+ static char *scanned_to_phrase P_((char **scanned,decode_who decoder));
+ 
+ static char *scanned_to_phrase(scanned,decoder)
+      char * *scanned;
+      decode_who decoder;
+ {
+   char *res = NULL;
+   int idx, max_idx;
+ 
+   dprint(30,(debugfile,"scanned_to_phrase:"));
+   for (max_idx  = 0; scanned[max_idx]; max_idx++) {
+     dprint(30,(debugfile," [%d]=%s",max_idx,scanned[max_idx]));
+   }
+   dprint(30,(debugfile,"\n"));
+ 
+   for (idx  = 0; idx < max_idx; idx++) {
+     if ('"' == scanned[idx][0]) {
+       char buffer[1000];
+       int k,j;
+       for (k = 1, j = 0; 
+ 	   scanned[idx][k] && (scanned[idx][k] != '"' || scanned[idx][k+1]) &&
+ 	     j < sizeof buffer -1; 
+ 	   k++)
+ 	buffer[j++] = scanned[idx][k];
+       buffer[j] = '\0';
+       if (res && res[0] != '\0')
+ 	res = strmcat(res," ");
+       res = strmcat(res,buffer);
+     } else {
+       char buffer[1000];
+       strfcpy(buffer,scanned[idx],sizeof buffer);
+       while (idx+1 < max_idx && '"' != scanned[idx+1][0] &&
+ 	     strlen(buffer) + strlen(scanned[idx+1]) +2 < sizeof buffer) {
+ 	strfcat(buffer," ",sizeof buffer);
+ 	strfcat(buffer,scanned[++idx], sizeof buffer);
+       }
+       decoder(HDR_PHRASE,buffer,sizeof buffer);
+       if (res && res[0] != '\0')
+ 	res = strmcat(res," ");
+       res = strmcat(res,buffer);
+     }
+   }
+   dprint(30,(debugfile,"scanned_to_phrase=%X=%s\n",res,NONULL(res)));
+   return res;
+ }
+ 
+ static char *scanned_to_str P_((char **scanned));
+ 
+ static char *scanned_to_str(scanned)
+      char **scanned;
+ {
+   int idx;
+   char * res = NULL;
+   dprint(30,(debugfile,"scanned_to_str:"));
+   for (idx = 0; scanned[idx]; idx++) {
+     dprint(30,(debugfile," [%d]=%s",idx,scanned[idx]));
+     res = strmcat(res,scanned[idx]);
+   }
+   dprint(30,(debugfile,"\nscanned_to_str=%X=%s\n",res,NONULL(res)));
+   return res;
+ }
+ 
+ struct addr_item * break_down_address (buffer, decoder)
+      const char *buffer;
+      decode_who decoder;
+ {
+   int count=1;
+   int i,res_idx = 0;
+   struct addr_item *res;
+   int outer, inner;
+   int tok_end;
+ 
+   struct {
+     int in_group;
+     int in_bracket;
+   } state;
+ 
+   char **tokenized = rfc822_tokenize(buffer);
+ 
+   dprint(13,(debugfile,
+ 	     "break_down_address: buffer=%.100s\n",
+ 	     buffer));
+ 
+   if (!tokenized)
+     return NULL;
+ 
+   for (tok_end = 0; tokenized[tok_end]; tok_end++)
+     if (tokenized[tok_end][0] == ',')
+       count++;
+ 
+   dprint(13,(debugfile,
+ 	     "break_down_address: count=%d, tok_end=%d\n",
+ 	     count,tok_end));
+ 
+   res = safe_malloc((count+1) * sizeof (struct addr_item));
+ 
+   for (i =0; i <= count; i++) {
+     res[i].addr     = NULL;
+     res[i].fullname = NULL;
+   }
+ 
+ 
+   state.in_group   = 0;
+   state.in_bracket = 0;
+ 
+   for (outer = 0; outer < tok_end && res_idx < count; outer = inner) {
+     char **scanned = NULL;
+     char *comments = NULL;
+     char tok = '\0';
+     int len;
+     
+     dprint(25,(debugfile,
+ 	      "break_down_address: [%d]=%.10s... state: in_group=%d in_bracket=%d\n",
+ 	       outer,tokenized[outer],state.in_group,state.in_bracket));
+ 
+     len = look_special_tokens(tokenized,":<>,;",outer,&inner,decoder,
+ 			      &comments,&scanned);
+ 
+     if (inner < tok_end) {
+       tok = tokenized[inner][0];
+       dprint(25,(debugfile,
+ 		 "break_down_address: [%d] token=%c (%s)\n",inner,tok,tokenized[inner]));
+       inner++;
+     } else {
+       tok = '\0';
+       dprint(25,(debugfile,
+ 		 "break_down_address: [%d] token=EOS\n",inner));
+     }
+     
+ 
+     /* state engine */
+     if (!state.in_group) {
+       if (!state.in_bracket)
+ 	switch(tok) {
+ 	case ':':  dprint(25,(debugfile, "... skipping group phrase\n"));
+ 	  state.in_group = 1;
+ 	  break;
+ 	case '<': 
+ 	  if (scanned && scanned[0]) {
+ 	    char *str = scanned_to_phrase(scanned,decoder);
+ 	    dprint(25,(debugfile, "... storing address phrase: %s\n",str));
+ 	    res[res_idx].fullname = strmcat(res[res_idx].fullname,str);
+ 	    free(str);
+ 	  }
+ 	  state.in_bracket = 1;
+ 	  break;
+ 	case '>':
+ 	  dprint(25,(debugfile, "... Parse error, next token '>'\n"));
+ 	  break;
+ 	case ';':
+ 	  dprint(25,(debugfile, "... Parse error, next token ';'\n"));
+ 	  break;
+ 	case ',':
+ 	default: /* \0 */	  
+ 	  if (scanned  && scanned[0]) {
+ 	    char *str = scanned_to_str(scanned);
+ 	    dprint(25,(debugfile, "... storing address: %s\n",str));
+ 	    res[res_idx].addr = strmcat(res[res_idx].addr,str);
+ 	    free(str);
+ 	    if (comments) {
+ 	      dprint(25,(debugfile, "... storing comments: %s\n",comments));
+ 	      res[res_idx].fullname = strmcat(res[res_idx].fullname,comments);
+ 	    }
+ 	  }
+ 	  if (res[res_idx].addr || res[res_idx].fullname) {
+ 	    res[res_idx].addr = strmcat(res[res_idx].addr,"");
+ 	    res[res_idx].fullname = strmcat(res[res_idx].fullname,"");
+ 	    dprint(13,(debugfile,
+ 		       "break_down_address: [%d].addr    =%.100s\n",
+ 		       res_idx,res[res_idx].addr));
+ 	    dprint(13,(debugfile,
+ 		       "                  : [%d].fullname=%.100s\n",
+ 		       res_idx,res[res_idx].fullname));
+ 	    res_idx++;
+ 	  }
+ 	  break;
+ 	} else switch(tok) {    /* state.in_bracket */
+ 	  char *str;
+ 	case ':': dprint(25,(debugfile, "... skipping route\n"));
+ 	  break;
+ 	case '<':
+ 	  dprint(25,(debugfile, "... Parse error, next token '<'\n"));
+ 	  break;
+ 	case '>': store_addr1:
+ 	  if (scanned  && scanned[0]) {
+ 	    char *str = scanned_to_str(scanned);
+ 	    dprint(25,(debugfile, "... storing address: %s\n",str));
+ 	    res[res_idx].addr = strmcat(res[res_idx].addr,str);
+ 	    free(str);
+ 	  }
+ 	  if (res[res_idx].addr || res[res_idx].fullname) {
+ 	    res[res_idx].addr = strmcat(res[res_idx].addr,"");
+ 	    res[res_idx].fullname = strmcat(res[res_idx].fullname,"");
+ 	    dprint(13,(debugfile,
+ 		       "break_down_address: [%d].addr    =%.100s\n",
+ 		       res_idx,res[res_idx].addr));
+ 	    dprint(13,(debugfile,
+ 		       "                  : [%d].fullname=%.100s\n",
+ 		       res_idx,res[res_idx].fullname));
+ 	    res_idx++;
+ 	  }
+ 	  state.in_bracket = 0;
+ 	  break;
+ 	case ',': dprint(25,(debugfile, "... skipping route\n"));
+ 	  break;
+ 	case ';': dprint(25,(debugfile, "... Parse error, next token ';'\n"));
+ 	  break;
+ 	default: /* \0 */	  
+ 	  dprint(25,(debugfile, "... Parse error, missing '>'\n"));
+ 	  goto store_addr1;	  
+ 	}
+     } else { /* state.in_group */
+       if (!state.in_bracket)
+ 	switch(tok) {
+ 	case ':': dprint(25,(debugfile, "... Parse error, next token ':'\n"));
+ 	  break;
+ 	case '<':
+ 	  if (scanned && scanned[0]) {
+ 	    char *str = scanned_to_phrase(scanned,decoder);
+ 	    dprint(25,(debugfile, "... storing address phrase: %s\n",str));
+ 	    res[res_idx].fullname = strmcat(res[res_idx].fullname,str);
+ 	    free(str);
+ 	  }
+ 	  state.in_bracket = 1;
+ 	  break;
+ 	case '>':
+ 	  dprint(25,(debugfile, "... Parse error, next token '>'\n"));
+ 	  break;
+ 	case ';': store_addr2:
+ 	  state.in_group = 0;
+ 	  /* FALLTHRU */
+ 	case ',': 
+ 	  if (scanned  && scanned[0]) {
+ 	    char *str = scanned_to_str(scanned);
+ 	    dprint(25,(debugfile, "... storing address: %s\n",str));
+ 	    res[res_idx].addr = strmcat(res[res_idx].addr,str);
+ 	    free(str);
+ 	    if (comments) {
+ 	      dprint(25,(debugfile, "... storing comments: %s\n",comments));
+ 	      res[res_idx].fullname = strmcat(res[res_idx].fullname,comments);
+ 	    }
+ 	  }
+ 	  if (res[res_idx].addr || res[res_idx].fullname) {
+ 	    res[res_idx].addr = strmcat(res[res_idx].addr,"");
+ 	    res[res_idx].fullname = strmcat(res[res_idx].fullname,"");
+ 	    dprint(13,(debugfile,
+ 		       "break_down_address: [%d].addr    =%.100s\n",
+ 		       res_idx,res[res_idx].addr));
+ 	    dprint(13,(debugfile,
+ 		       "                  : [%d].fullname=%.100s\n",
+ 		       res_idx,res[res_idx].fullname));
+ 	    res_idx++;
+ 	  }
+ 	  break;
+ 	default: /* \0 */
+ 	  dprint(25,(debugfile, "... Parse error, missing ';'\n"));
+ 	  goto store_addr2;
+ 	} else switch(tok) { /* state.in_bracket */
+ 	case ':': dprint(25,(debugfile, "... skipping route\n"));
+ 	  break;
+ 	case '<':
+ 	  dprint(25,(debugfile, "... Parse error, next token '<'\n"));
+ 	  break;
+ 	case ';': 
+ 	  dprint(25,(debugfile, 
+ 		     "... Parse error, next token ';', missing '>'\n"));
+ 	  state.in_group = 0;
+ 	  /* FALLTHRU */
+ 	case '>': store_addr3:
+ 	  if (scanned && scanned[0]) {
+ 	    char *str = scanned_to_str(scanned);
+ 	    dprint(25,(debugfile, "... storing address: %s\n",str));
+ 	    res[res_idx].addr = strmcat(res[res_idx].addr,str);
+ 	    free(str);
+ 	  }
+ 	  if (res[res_idx].addr || res[res_idx].fullname) {
+ 	    res[res_idx].addr = strmcat(res[res_idx].addr,"");
+ 	    res[res_idx].fullname = strmcat(res[res_idx].fullname,"");
+ 	    dprint(13,(debugfile,
+ 		       "break_down_address: [%d].addr    =%.100s\n",
+ 		       res_idx,res[res_idx].addr));
+ 	    dprint(13,(debugfile,
+ 		       "                  : [%d].fullname=%.100s\n",
+ 		       res_idx,res[res_idx].fullname));
+ 	    res_idx++;
+ 	  }
+ 	  state.in_bracket = 0;
+ 	  break;
+ 	case ',': dprint(25,(debugfile, "... skipping route\n"));
+ 	  break;
+ 	default: /* \0 */
+ 	  dprint(25,(debugfile, 
+ 		     "... Parse error, missing '>', missing ';'\n"));
+ 	  state.in_group = 0;
+ 	  goto store_addr3;
+       }
+     }
+     if (comments)
+       free(comments);
+     if (scanned)
+       free_rfc822tokenized(scanned);
+   }
+ 
+   free_rfc822tokenized(tokenized);
+ 
+   dprint(13,(debugfile,
+ 	     "break_down_address=%08X (real count=%d)\n",
+ 	     res,res_idx));
+ 
+   return res;
+ }
+ 
+ void  free_addr_items (list)
+      struct addr_item *list;
+ {
+   struct addr_item *ptr;
+ 
+   dprint(100,(debugfile,
+ 	     "free_addr_items(%08X)\n",ptr));
+ 
+   for (ptr=list; ptr->addr && ptr->fullname; ptr++) {
+     free(ptr->addr);
+     ptr->addr = NULL;
+ 
+     free(ptr->fullname);
+     ptr->fullname = NULL;
+   }
+   free(list);
+ }
Index: elm2.4.ME+.50/lib/forwarded.c
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/lib/forwarded.c	Tue Nov 17 21:12:56 1998
***************
*** 0 ****
--- 1,72 ----
+ /*
+  *
+  * This function is originally from ../utils/newmail.c and 
+  * ../src/addr_util.c. Combined result is however totally
+  * rewritten.
+  *
+  * and that original code have following copyright:
+  * 			Copyright (c) 1988-1992 USENET Community Trust
+  * 			Copyright (c) 1986,1987 Dave Taylor
+  */
+ 
+ #include "headers.h"
+ 
+ void forwarded(buffer, entry)
+      char *buffer;
+      struct header_rec *entry;
+ {
+ 	/** change 'from' and date fields to reflect the ORIGINATOR of 
+ 	    the message by iteratively parsing the >From fields...
+ 	    The leading >From will already be stripped off the line. **/
+ 
+ 	char machine[SLEN], who[SLEN], work[SLEN];
+ 	int count, pointer;
+ 
+ 	machine[0] = '\0';
+ 	who[0]='\0';
+ 	
+ 	dprint(7, (debugfile, "forwarded: buffer=%s\n",buffer));
+ 
+ 	for (count = 0, pointer=0; 
+ 	     count < 10; 
+ 	     count++) {
+ 	  if (-1 == (pointer = get_word(buffer,pointer,work, sizeof work)))
+ 	    break;
+ 	  dprint(7, (debugfile, "forwarded-count=%d, work=%s\n",count,work));
+ 	  switch(count) {
+ 	  case 0: strfcpy(who,work, sizeof who); 
+ 	    
+ 	    if (!parse_arpa_date(buffer+pointer, entry)) {
+ 	      dprint(7, (debugfile, "forwarded: fail!\n"));
+ 	      return;
+ 	    }
+ 	    break;
+ 
+ 	    /* try for srm address */
+ 	  case 7: strfcpy(machine,work, sizeof machine); break;
+ 	    
+ 	    /* try for address with timezone in date */
+ 	  case 8: strfcpy(machine,work, sizeof machine); break;
+ 	    
+ 		/* normal case? */
+ 	  case 9: strfcpy(machine,work, sizeof machine); break;
+ 	  }
+ 	}
+ 	
+ 	if (qstrpbrk(who,"@!") != NULL) {
+ 	  strfcpy(entry->env_from, who, sizeof (entry->env_from));
+ 	} else if (machine[0] == '\0') {
+ 	  dprint(7, (debugfile, "forwarded: fail!\n"));
+ 	  return;
+ 	}
+ 	else 
+ 	  elm_sfprintf(entry->env_from,sizeof (entry->env_from),
+ 		       FRM("%s!%s"), 
+ 		       machine, who);
+ 
+ 	dprint(7, (debugfile,
+ 		   "forwarded, setting env_from=%s\n",entry->env_from));
+ }
+ 
+ 
+ 
Index: elm2.4.ME+.50/ConfTool/Substitute
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/ConfTool/Substitute	Tue Nov 17 21:14:09 1998
***************
*** 0 ****
--- 1,55 ----
+ # $Header: /data/cvsroot/mail/elmme+/ConfTool/Substitute,v 1.1 1998/11/10 16:30:08 hurtta Exp $
+     . ./config.sh
+     echo " "
+     echo "Doing variable substitutions on .SH files..."
+     set x `awk '{print $1}' <MANIFEST | $grep '\.SH'`
+     shift
+     case $# in
+     0) set x *.SH; shift;;
+     esac
+     if test ! -f $1; then
+ 	shift
+     fi
+     for file in $*; do
+ 	case "$file" in
+ 	*/*)
+ 	    dir=`$expr X$file : 'X\(.*\)/'`
+ 	    file=`$expr X$file : 'X.*/\(.*\)'`
+ 	    (cd $dir && . $file)
+ 	    ;;
+     	*)
+ 	    . $file
+ 	    ;;
+     	esac
+     done
+     if test -f config.h.SH; then
+     	if test ! -f config.h; then
+ 	    : oops, they left it out of MANIFEST, probably, so do it anyway.
+ 	    . config.h.SH
+     	fi
+     fi
+ 
+     if $contains '^depend:' Makefile >/dev/null 2>&1; then
+     	dflt=n
+     	$cat <<EOM
+ 
+ Now you need to generate make dependencies by running "make depend".
+ You might prefer to run it in background: "make depend > makedepend.out &"
+ It can take a while, so you might not want to run it right now.
+ 
+ EOM
+     	rp="Run make depend now? [$dflt]"
+     	$echo $n "$rp $c"
+     	. UU/myread
+     	case "$ans" in
+     	y*) make depend && echo "Now you must run a make."
+ 	    ;;
+     	*)  echo "You must run 'make depend' then 'make'."
+ 	    ;;
+     	esac
+     elif test -f Makefile; then
+     	echo " "
+     	echo "Now you must run a make."
+     else
+     	echo "Done."
+     fi
Index: elm2.4.ME+.50/doc/mime.charsets
*** /tmp/8255-very-long-file-name-NULL-comes-in-here	Sun Nov 22 09:14:43 1998
--- elm2.4.ME+.50/doc/mime.charsets	Tue Nov 17 21:14:09 1998
***************
*** 0 ****
--- 1,81 ----
+ # Mapping from LC_CTYPE locale to MIME's charset values
+ # Format is:
+ #	LC_CTYPE	charset
+ # LC_CTYPE is on form
+ #	LL_cc.encoding
+ # then also following formats are available:
+ #	LL_cc		charset
+ #	LL		charset
+ #	*.encoding	charset
+ POSIX		ISO-8859-1
+ C		US-ASCII
+ ar		ISO-8859-6
+ ar_AA		ISO-8859-6
+ bg		ISO-8859-5
+ bg_BG		ISO-8859-5
+ cs		ISO-8859-2
+ cs_CS		ISO-8859-2
+ cz		ISO-8859-2
+ cz_CZ		ISO-8859-2
+ da		ISO-8859-1
+ da_DK		ISO-8859-1
+ de		ISO-8859-1
+ de_DE		ISO-8859-1
+ de_AT		ISO-8859-1
+ de_CH		ISO-8859-1
+ el		ISO-8859-7
+ el_GR		ISO-8859-7
+ en		ISO-8859-1
+ en_AU		ISO-8859-1
+ en_CA		ISO-8859-1
+ en_US		ISO-8859-1
+ es		ISO-8859-1
+ es_ES		ISO-8859-1
+ es_AR		ISO-8859-1
+ es_MX		ISO-8859-1
+ fi		ISO-8859-1
+ fi_FI		ISO-8859-1
+ fr		ISO-8859-1
+ fr_BE		ISO-8859-1
+ fr_CA		ISO-8859-1
+ fr_CH		ISO-8859-1
+ fr_FR		ISO-8859-1
+ hr		ISO-8859-2
+ hr_HR		ISO-8859-2
+ hu		ISO-8859-2
+ hu_HU		ISO-8859-2
+ is		ISO-8859-1
+ is_IS		ISO-8859-1
+ it		ISO-8859-1
+ it_IT		ISO-8859-1
+ it_CH		ISO-8859-1
+ iw		ISO-8859-8
+ iw_IL		ISO-8859-8
+ mk		ISO-8859-5
+ mk_MK		ISO-8859-5
+ nl		ISO-8859-1
+ nl_BE		ISO-8859-1
+ nl_NL		ISO-8859-1
+ no		ISO-8859-1
+ no_NO		ISO-8859-1
+ pl		ISO-8859-2
+ pl_PL		ISO-8859-2
+ pt		ISO-8859-1
+ pt_PT		ISO-8859-1
+ pt_BR		ISO-8859-1
+ ro		ISO-8859-2
+ ro_RO		ISO-8859-2
+ ru		ISO-8859-5
+ ru_SU		ISO-8859-5
+ sh		ISO-8859-2
+ sh_YU		ISO-8859-2
+ sk		ISO-8859-2
+ sk_SK		ISO-8859-2
+ sl		ISO-8859-2
+ sl_CS		ISO-8859-2
+ sp		ISO-8859-5
+ sp_YU		ISO-8859-5
+ sv		ISO-8859-1
+ sv_SE		ISO-8859-1
+ tr		ISO-8859-9
+ tr_TR		ISO-8859-9
