diff options
Diffstat (limited to 'packages/pine')
-rw-r--r-- | packages/pine/.mtn2git_empty | 0 | ||||
-rw-r--r-- | packages/pine/pine-4.63/.mtn2git_empty | 0 | ||||
-rw-r--r-- | packages/pine/pine-4.63/imap-2000-time.patch | 56 | ||||
-rw-r--r-- | packages/pine/pine-4.63/pine-4.30-ldap.patch | 11 | ||||
-rw-r--r-- | packages/pine/pine-4.63/pine-4.31-segfix.patch | 17 | ||||
-rw-r--r-- | packages/pine/pine-4.63/pine-4.40-lockfile-perm.patch | 22 | ||||
-rw-r--r-- | packages/pine/pine-4.63/pine-4.56-passfile.patch | 12 | ||||
-rw-r--r-- | packages/pine/pine-4.63/pine-4.61-largeterminal.patch | 14 | ||||
-rw-r--r-- | packages/pine/pine-4.63/pine-4.61-subjectlength.patch | 59 | ||||
-rw-r--r-- | packages/pine/pine-4.63/pine-4.62-spooldir-permissions.patch | 12 | ||||
-rw-r--r-- | packages/pine/pine-4.63/pine-4.63-r2-chappa-all.patch | 21900 | ||||
-rw-r--r-- | packages/pine/pine-4.63/pine-ldap3.patch | 11 | ||||
-rw-r--r-- | packages/pine/pine-4.63/transparency.patch | 14 | ||||
-rw-r--r-- | packages/pine/pine_4.63.bb | 82 |
14 files changed, 0 insertions, 22210 deletions
diff --git a/packages/pine/.mtn2git_empty b/packages/pine/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 --- a/packages/pine/.mtn2git_empty +++ /dev/null diff --git a/packages/pine/pine-4.63/.mtn2git_empty b/packages/pine/pine-4.63/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 --- a/packages/pine/pine-4.63/.mtn2git_empty +++ /dev/null diff --git a/packages/pine/pine-4.63/imap-2000-time.patch b/packages/pine/pine-4.63/imap-2000-time.patch deleted file mode 100644 index 751d1ff506..0000000000 --- a/packages/pine/pine-4.63/imap-2000-time.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- pine4.33/imap/src/osdep/unix/os_lnx.c.time Wed Feb 14 12:25:06 2001 -+++ pine4.33/imap/src/osdep/unix/os_lnx.c Wed Feb 14 12:25:16 2001 -@@ -23,6 +23,7 @@ - #include "osdep.h" - #include <stdio.h> - #include <sys/time.h> -+#include <time.h> - #include <sys/stat.h> - #include <sys/socket.h> - #include <netinet/in.h> ---- pine4.33/imap/src/osdep/unix/news.c.time Thu Jan 18 21:28:33 2001 -+++ pine4.33/imap/src/osdep/unix/news.c Wed Feb 14 12:24:34 2001 -@@ -21,7 +21,7 @@ - #include <stdio.h> - #include <ctype.h> - #include <errno.h> --extern int errno; /* just in case */ -+#include <time.h> - #include "mail.h" - #include "osdep.h" - #include <sys/stat.h> ---- pine4.33/imap/src/osdep/unix/phile.c.time Thu Jan 18 21:31:20 2001 -+++ pine4.33/imap/src/osdep/unix/phile.c Wed Feb 14 12:24:34 2001 -@@ -21,8 +21,8 @@ - #include <stdio.h> - #include <ctype.h> - #include <errno.h> --extern int errno; /* just in case */ - #include <signal.h> -+#include <time.h> - #include "mail.h" - #include "osdep.h" - #include <pwd.h> ---- pine4.33/imap/src/osdep/unix/mh.c.time Thu Jan 18 21:27:37 2001 -+++ pine4.33/imap/src/osdep/unix/mh.c Wed Feb 14 12:24:34 2001 -@@ -21,7 +21,8 @@ - #include <stdio.h> - #include <ctype.h> - #include <errno.h> --extern int errno; /* just in case */ -+#include <time.h> -+ - #include "mail.h" - #include "osdep.h" - #include <pwd.h> ---- pine4.33/imap/src/osdep/unix/mx.c.time Thu Jan 18 21:28:09 2001 -+++ pine4.33/imap/src/osdep/unix/mx.c Wed Feb 14 12:24:34 2001 -@@ -21,7 +21,7 @@ - #include <stdio.h> - #include <ctype.h> - #include <errno.h> --extern int errno; /* just in case */ -+#include <time.h> - #include "mail.h" - #include "osdep.h" - #include <pwd.h> diff --git a/packages/pine/pine-4.63/pine-4.30-ldap.patch b/packages/pine/pine-4.63/pine-4.30-ldap.patch deleted file mode 100644 index 6b920ade51..0000000000 --- a/packages/pine/pine-4.63/pine-4.30-ldap.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- pine4.30/build.ldap Fri Oct 27 12:48:05 2000 -+++ pine4.30/build Fri Oct 27 12:49:00 2000 -@@ -249,7 +249,7 @@ - case "$?" in - 1) if [ "$LLIBS" != "1" ] - then -- L1="'LDAPLIBS=../ldap/libraries/libldap.a ../ldap/libraries/liblber.a'" -+ L1="'LDAPLIBS=../ldap/libraries/libldap.so ../ldap/libraries/liblber.so ../ldap/libraries/libresolv.so'" - fi - if [ "$LFLAGS" != "1" ] - then diff --git a/packages/pine/pine-4.63/pine-4.31-segfix.patch b/packages/pine/pine-4.63/pine-4.31-segfix.patch deleted file mode 100644 index f65aa60294..0000000000 --- a/packages/pine/pine-4.63/pine-4.31-segfix.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff -urN pine4.31.orig/pine/osdep/lstcmpnt pine4.31/pine/osdep/lstcmpnt ---- pine4.31.orig/pine/osdep/lstcmpnt Mon Oct 30 17:45:08 2000 -+++ pine4.31/pine/osdep/lstcmpnt Tue Dec 12 06:33:53 2000 -@@ -9,10 +9,10 @@ - last_cmpnt(filename) - char *filename; - { -- register char *p = NULL, *q = filename; -+ char *p = NULL, *q = filename; - -- if(!q) -- return(q); -+ if(filename == 0) -+ return 0; - - while(q = strchr(q, '/')) - if(*++q) diff --git a/packages/pine/pine-4.63/pine-4.40-lockfile-perm.patch b/packages/pine/pine-4.63/pine-4.40-lockfile-perm.patch deleted file mode 100644 index f2cb434de2..0000000000 --- a/packages/pine/pine-4.63/pine-4.40-lockfile-perm.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- pine4.40/imap/src/osdep/unix/env_unix.h.lock_protection_fix Thu Oct 4 05:26:33 2001 -+++ pine4.40/imap/src/osdep/unix/env_unix.h Thu Oct 4 05:30:33 2001 -@@ -46,12 +46,15 @@ - - - /* -- * Attention: all sorcerer's apprentices who think that 0666 is a mistake. -- * You are wrong. Read the FAQ. Do not meddle in the affairs of wizards, -- * for they are subtle and quick to anger. -+ * Attention: all people who do not care about OS security, and think that -+ * mode 0666 is a correct. You are wrong. In modern multiuser systems, -+ * both remote and local security is critically important. Allowing 0666 -+ * lockfiles, allows all sorts of security problems to occur. Feel free to -+ * meddle with it however, if you do not care about local security. - */ - --#define MANDATORYLOCKPROT 0666 /* don't change this */ -+/* Change this only if you do not want a secure multiuser system */ -+#define MANDATORYLOCKPROT 0600 - - /* Function prototypes */ - diff --git a/packages/pine/pine-4.63/pine-4.56-passfile.patch b/packages/pine/pine-4.63/pine-4.56-passfile.patch deleted file mode 100644 index bb9813f7c6..0000000000 --- a/packages/pine/pine-4.63/pine-4.56-passfile.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- pine4.56/pine/osdep/os-lnx.h.orig 2003-07-23 07:23:26.000000000 -0700 -+++ pine4.56/pine/osdep/os-lnx.h 2003-07-23 07:23:30.000000000 -0700 -@@ -295,5 +295,9 @@ - #define MAX_ADDR_EXPN (1000) /* Longest expanded addr */ - #define MAX_ADDR_FIELD (10000) /* Longest fully-expanded addr field */ - -+/*---------------------------------------------------------------------- -+ Allow for caching of passwords between connections. -+ ----*/ -+#define PASSFILE ".pinepw" - - #endif /* _OS_INCLUDED */ diff --git a/packages/pine/pine-4.63/pine-4.61-largeterminal.patch b/packages/pine/pine-4.63/pine-4.61-largeterminal.patch deleted file mode 100644 index c046546dba..0000000000 --- a/packages/pine/pine-4.63/pine-4.61-largeterminal.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -Nur pine4.61.orig/pine/osdep/os-lnx.h pine4.61/pine/osdep/os-lnx.h ---- pine4.61.orig/pine/osdep/os-lnx.h 2004-12-18 00:33:46.162401405 +0100 -+++ pine4.61/pine/osdep/os-lnx.h 2004-12-18 00:34:14.473012057 +0100 -@@ -247,8 +247,8 @@ - - - /*-- Max screen pine will display on. Used to define some array sizes --*/ --#define MAX_SCREEN_COLS (170) --#define MAX_SCREEN_ROWS (200) -+#define MAX_SCREEN_COLS (340) -+#define MAX_SCREEN_ROWS (400) - - - /*---------------------------------------------------------------------- diff --git a/packages/pine/pine-4.63/pine-4.61-subjectlength.patch b/packages/pine/pine-4.63/pine-4.61-subjectlength.patch deleted file mode 100644 index b7a9cdf7b7..0000000000 --- a/packages/pine/pine-4.63/pine-4.61-subjectlength.patch +++ /dev/null @@ -1,59 +0,0 @@ ---- pine4.61/pine/strings.c_orig 2004-03-12 10:48:17.783992528 +0100 -+++ pine4.61/pine/strings.c 2004-03-12 11:01:37.929351944 +0100 -@@ -2912,7 +2912,7 @@ int rfc1522_token PROTO((char *, - char **)); - int rfc1522_valtok PROTO((int)); - int rfc1522_valenc PROTO((int)); --int rfc1522_valid PROTO((char *, char **, char **, char **, -+int rfc1522_valid PROTO((char *, int, char **, char **, char **, - char **)); - char *rfc1522_8bit PROTO((void *, int)); - char *rfc1522_binary PROTO((void *, int)); -@@ -2949,7 +2949,7 @@ rfc1522_decode(d, len, s, charset) - - while(s && (sw = strstr(s, RFC1522_INIT))){ - /* validate the rest of the encoded-word */ -- if(rfc1522_valid(sw, &cset, &enc, &txt, &ew)){ -+ if(rfc1522_valid(sw, 1, &cset, &enc, &txt, &ew)){ - if(!rv) - rv = d; /* remember start of dest */ - -@@ -3222,10 +3222,15 @@ rfc1522_valenc(c) - - /* - * rfc1522_valid - validate the given string as to it's rfc1522-ness -+ * if relaxchk is true, double the maximum length of an encoded word. -+ * this is necessary to decode overlong encoded words generated by -+ * numerous incompliant implementations of RFC 2047 (1522). -+ - */ - int --rfc1522_valid(s, charset, enc, txt, endp) -+rfc1522_valid(s, relaxchk, charset, enc, txt, endp) - char *s; -+ int relaxchk; - char **charset; - char **enc; - char **txt; -@@ -3237,7 +3242,11 @@ rfc1522_valid(s, charset, enc, txt, endp - rv = rfc1522_token(c = s+RFC1522_INIT_L, rfc1522_valtok, RFC1522_DLIM, &e) - && rfc1522_token(++e, rfc1522_valtok, RFC1522_DLIM, &t) - && rfc1522_token(++t, rfc1522_valenc, RFC1522_TERM, &p) -- && p - s <= RFC1522_MAXW; -+ && p - s <= RFC1522_MAXW * (relaxchk ? 2 : 1); -+ /* -+ * relax the length condition by doubling the max length of an -+ * encoded word. It's is needed for some longer encoded words. -+ */ - - if(charset) - *charset = c; -@@ -3288,7 +3297,7 @@ rfc1522_encode(d, len, s, charset) - } - else if(*p == RFC1522_INIT[0] - && !strncmp((char *) p, RFC1522_INIT, RFC1522_INIT_L)){ -- if(rfc1522_valid((char *) p, NULL, NULL, NULL, (char **) &q)) -+ if(rfc1522_valid((char *) p, 0, NULL, NULL, NULL, (char **) &q)) - p = q + RFC1522_TERM_L - 1; /* advance past encoded gunk */ - } - else if(*p == ESCAPE && match_escapes((char *)(p+1))){ diff --git a/packages/pine/pine-4.63/pine-4.62-spooldir-permissions.patch b/packages/pine/pine-4.63/pine-4.62-spooldir-permissions.patch deleted file mode 100644 index eb8c2f3eee..0000000000 --- a/packages/pine/pine-4.63/pine-4.62-spooldir-permissions.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -bur pine4.62/imap/src/osdep/unix/env_unix.c pine4.62-gentoo/imap/src/osdep/unix/env_unix.c ---- pine4.62/imap/src/osdep/unix/env_unix.c 2004-09-13 23:32:11.000000000 +0200 -+++ pine4.62-gentoo/imap/src/osdep/unix/env_unix.c 2005-03-24 23:38:13.000000000 +0100 -@@ -106,7 +106,7 @@ - * on the mail spool, or install mlock. - */ - /* disable warning if can't make .lock file */ --static short disableLockWarning = NIL; -+static short disableLockWarning = 1; - - /* UNIX namespaces */ - diff --git a/packages/pine/pine-4.63/pine-4.63-r2-chappa-all.patch b/packages/pine/pine-4.63/pine-4.63-r2-chappa-all.patch deleted file mode 100644 index 313d4544ef..0000000000 --- a/packages/pine/pine-4.63/pine-4.63-r2-chappa-all.patch +++ /dev/null @@ -1,21900 +0,0 @@ -diff -rc pine4.63/README.maildir pine4.63.I.USE/README.maildir -*** pine4.63/README.maildir Thu May 19 19:59:15 2005 ---- pine4.63.I.USE/README.maildir Thu May 19 19:57:24 2005 -*************** -*** 0 **** ---- 1,244 ---- -+ ------------------------------------------------------------------------------- -+ -+ Maildir Driver for Pine4.63 -+ By Eduardo Chappa <chappa@math.washington.edu> -+ http://www.math.washington.edu/~chappa/pine/ -+ -+ ------------------------------------------------------------------------------- -+ 1. General Information About This Patch -+ --------------------------------------- -+ -+ This patch adds support for the maildir format to Pine. We take the -+ approach that this patch is one more driver among the number of formats -+ supported by Pine (more generally c-client). This approach differs from -+ older versions of similar patches, in that once a maildir patch was -+ applied, it was assumed that all your folders would be created in the -+ maildir format. -+ -+ This patch does not assume that maildir is a preferred format, instead -+ puts maildir in equal footing with other formats (mbox, mbx, etc), and so -+ a maildir folder in the mail/ collection is treated in the same way as any -+ other folder in any other format. In another words, just by reading the -+ name of a folder, or opening it, or doing any operation with it, you can -+ not know in which format the folder is. -+ -+ This implies that if you want to add a folder in the maildir format to the -+ mail/ collection, then you must add by pressing "A" in the folder list -+ collection and enter "#driver.md/mail/name_maildir_folder". -+ -+ If you only want to use maildir, however, you can do so too. In this case, -+ you must create a maildir collection. In that collection, only maildir -+ folders will be listed. If there is any folder in any other format, that -+ folder will be ignored. In another words, any folder listed there is in -+ maildir format and can be accessed through that collection, conversely, -+ any folder not listed there is not in maildir format and there is no way -+ to access it using this collection. -+ -+ In order to create a maildir collection, you could press M S L, and "A" to -+ add a collection. Fill in the required fields as follows: -+ -+ Nickname : Anything -+ Server : -+ Path : #md/relative/path/to/maildir/collection/ -+ View : -+ -+ For example, if "path" is set to "#md/mail/", then Pine will look for your -+ maildir folders that are in ~/mail/. -+ -+ The code in this patch is mostly based in code for the unix driver plus -+ some combinations of the mh, mbx and nntp drivers for the c-client -+ library. Those drivers were designed by Mark Crispin, and bugs in this -+ code are not his bugs, but my own. -+ -+ I got all the specification for this patch from -+ http://cr.yp.to/proto/maildir.html. If you know of a place with a better -+ specification for maildir format please let me know. The method this patch -+ uses to create a unique filename for a message is one of the "old -+ fashioned" methods. I realize that this is old fashioned, but it is -+ portable, and portability is the main reason why I decided to use an old -+ fashioned method (most methods are not portable. See the word -+ "Unfortunately" in that document). -+ -+ -------------- -+ 2. Other Goals -+ -------------- -+ -+ It is intended that this code will work well with any application -+ written using the c-client library. Of paramount importance is to make the -+ associated imap server work well when the server accesses a folder in -+ Maildir format. The program mailutil should also work flawlessly with this -+ implemetation of the driver. -+ -+ It is intended that this driver be fast and stable. We intend not to -+ patch Pine to make this driver do its work, unless such patching is for -+ fixing bugs in Pine or to pass parameters to the driver. -+ -+ ---------------------------------------- -+ 3. One sided comparison to other patches -+ ---------------------------------------- -+ -+ There are two other maildir patches that could be easily adapted for -+ version 4.63. -+ -+ The first one is the patch distributed by SuSe which can be downloaded -+ from http://hico.fphil.uniba.sk/pine-patches.html. This patch was last -+ updated for version 4.58. Several hunks fail to be applied when you try to -+ apply it to Pine 4.63. Even if you apply those hunks manually there will -+ still be the following bugs: -+ -+ * You can not save between any two storage systems. The old patch did -+ not do this well, because it had to modify the mailcmd.c file in order -+ to save messages to a unix style mailbox, and this is undesirable, -+ because the mailutil application associated to this patch would fail -+ to save messages. -+ * It corrupts messages when it saves them to a mbx format folder. -+ * It could not save messages to the INBOX folder. -+ * It crashes when two different clients are accessing the same mailbox: -+ For example, if a message is marked deleted in one session, then it -+ should be marked deleted in any other session too, but instead it -+ crashes the second session. -+ * Pine crashes when saving several messages to a maildir (not even the -+ prototype of the function is correctly defined). -+ * Pine crashes when checking for the STATUS of a maildir mailbox. -+ * Pine could not delete a maildir folder. -+ * Pine could not rename a maildir folder. -+ -+ The other patch is available from Glue Logic (GL), was last updated for -+ version 4.61 and fails to apply a hunk in version 4.63, which must be -+ manually applied. There are, however, several problems and bugs. The patch -+ can be found at http://www.gluelogic.com/code/PINE-maildir/ -+ -+ * [Bug] It changes the default sort by arrival into sort by Date in -+ every folder. This makes Pine sort incorrectly any folder (no matter -+ in which format such folder is). -+ -+ * [Missing Important Feature] Lacks support for dual folder use. You can -+ not create a directory with the same name than a given folder and use -+ it! -+ -+ * [Bug] It confuses Unseen and Recent messages. Unseen messages are -+ reported as Recent. An Unseen message is a message that had not been -+ read the last time the folder was closed (or had been read but marked -+ Unseen in an earlier session). A Recent message is one which was not -+ in the folder the last time it was closed. Recent messages are your -+ real new messages, but Unseen are not. In GL patch, every Unseen -+ message is treated as Recent!. -+ -+ * [Problem] Large folders take long time to be opened for the first -+ time. -+ -+ * [Bug] Reported sizes are the number of bytes in the message and not -+ the "on the wire" size. If you were to manually edit a message and -+ either add or remove information from it, the size reported by Pine -+ would not be affected by this change. -+ -+ * [Bug] Crashes when two sessions access the same mailbox and one -+ deletes and expunges a message while the other tries to read that -+ message. (explicitly, if session A uses the GL patch, and session B -+ uses my patch, then the following procedure crashes session A: -+ -+ - In session B delete and expunge a message. -+ - Open that message in session A. Session A will notice it is gone -+ and will not crash. -+ - In session A delete and expunge a message. -+ - Open that message in session B. Session B will print a message -+ about no such message, then it will go back to the index screen -+ telling you that the message your were viewing was gone. -+ - Now in session B delete and expunge a message. -+ - Open that message in session A, Pine will crash). -+ -+ * [Bug] The patch changes the name of a message-file by adding a place -+ for the size in the name of the message-file. By doing so it breaks -+ the maildir specification which only allows you to change the name by -+ changing flags. If there is another client reading that mailbox, there -+ is a chance that the other client will fail finding messages due to -+ changes made by the GL patch. -+ -+ * [Bug] Any patch for Maildir support is NOT a patch for Pine (despite -+ the fact that you have read many times that the patch is for Pine), -+ but a patch for the C-Client library. As such it should work well with -+ any application that can be built with such library, like the UW-IMAP -+ server. The GL patch has a self proclaimed message stating not to use -+ the associated IMAP server to read Maildirs. This restriction does not -+ apply to my patch. I encourage you to use the server built with my -+ patch to access Maildirs. -+ -+ ------------------------------------------------------------------------ -+ 4. What are the known bugs of this implementation of the Maildir driver? -+ ------------------------------------------------------------------------ -+ -+ I don't know any at this time. There have been bugs before, though, but -+ I try to fix bugs as soon as they are reported. All bugs of the other -+ patches have been reported but not fixed, either because there was no one -+ maintaining the patch, or the maintainer has not fixed them yet (all these -+ reports were made as late as November 2004). A very complete list of -+ updates for this patch, which includes bug fixes, improvements and -+ addition of new features can be found at -+ -+ http://www.math.washington.edu/~chappa/pine/updates/maildir.html -+ -+ ---------- -+ 5. On UIDs -+ ---------- -+ -+ This patch does not keep UIDs between sessions, but hopefully it does -+ keep consistent UIDs during one session. This is not a bug of the driver, -+ instead it is a shortcoming of the maildir specification. The main point -+ of the maildir configuration is that you should never (read my lips) ever -+ edit the message, but edit the filename associated to the message. Well, I -+ could not find any single place in the web where it was told how to save -+ the UID of a message, if there is one please let me know and I will add -+ UID support for this driver. -+ -+ -------------------------------------------- -+ 6. Configuring Pine and Setting up a Maildir -+ -------------------------------------------- -+ -+ Once this approach was chosen, it implied the following: -+ -+ * This patch assumes that your INBOX is located at "$HOME/Maildir". -+ This is a directory which should have three subdirectories "cur", -+ "tmp" and "new". Mail is delivered to 'new' and read from 'cur'. I -+ have added a configuration option "maildir-location" which can be -+ used to tell Pine where your Maildir inbox is, in case your system -+ do not use the above directory (e.g. your system may use -+ "~/.maildir"). In this case define that variable to be the name of -+ the directory where your e-mail is being delivered (e.g. -+ ".maildir"). -+ -+ * If you want to use the above configuration as your inbox, you must -+ define your inbox-path as "#md/inbox" (no quotes). You can define -+ the inbox-path like above even if you have changed the -+ maildir-location variable. That's the whole point of that variable. -+ -+ ----------------------------------- -+ 7. What about Courier file systems? -+ ----------------------------------- -+ -+ In a courier file system all folders are subfolders of a root folder -+ called INBOX. Normally INBOX is located at ~/Maildir and subfolders are -+ "dot" directories in ~/Maildir. For example ~/Maildir/.Trash is a -+ subfolder of INBOX and is accessed with the nickname "INBOX.Trash". -+ -+ You can not access folders in this way unless you preceed them with the -+ string "#mc/". The purpose of the string "#mc/" is to warn Pine that a -+ collection in the Courier format is going to be accessed, so you can -+ SELECT a folder like "#mc/INBOX.Trash", but not "INBOX.Trash" -+ -+ You can access a collection through a server, but if you want to access a -+ collection of folders created using the Courier server, you MUST edit your -+ ".pinerc" file and enter the definition of the collection as follows: -+ -+ folder-collections="Anything you want" #mc/INBOX.[] -+ -+ You can replace the string "#mc/INBOX." by something different, for example -+ "#mc/Courier/." will make Pine search for your collection in ~/Courier. -+ -+ You can not add this directly into Pine because Pine fails to accept this -+ value from its input, but it takes it correctly when it is added through -+ the ".pinerc" file. -+ -+ You can access your inbox as "#mc/INBOX" or "#md/INBOX". Both definitions -+ point to the same place. -+ -+ Last Updated April 29, 2005 -diff -rc pine4.63/imap/src/c-client/imap4r1.c pine4.63.I.USE/imap/src/c-client/imap4r1.c -*** pine4.63/imap/src/c-client/imap4r1.c Fri Apr 8 16:44:01 2005 ---- pine4.63.I.USE/imap/src/c-client/imap4r1.c Thu May 19 19:57:33 2005 -*************** -*** 4396,4401 **** ---- 4396,4402 ---- - if (*env) { /* need to merge this header into envelope? */ - if (!(*env)->newsgroups) { /* need Newsgroups? */ - (*env)->newsgroups = nenv->newsgroups; -+ (*env)->ngpathexists = nenv->ngpathexists; - nenv->newsgroups = NIL; - } - if (!(*env)->followup_to) { /* need Followup-To? */ -*************** -*** 4450,4455 **** ---- 4451,4457 ---- - if (oenv) { /* need to merge old envelope? */ - (*env)->newsgroups = oenv->newsgroups; - oenv->newsgroups = NIL; -+ (*env)->ngpathexists = oenv->ngpathexists; - (*env)->followup_to = oenv->followup_to; - oenv->followup_to = NIL; - (*env)->references = oenv->references; -diff -rc pine4.63/imap/src/c-client/mail.c pine4.63.I.USE/imap/src/c-client/mail.c -*** pine4.63/imap/src/c-client/mail.c Wed Mar 16 16:12:17 2005 ---- pine4.63.I.USE/imap/src/c-client/mail.c Thu May 19 19:57:24 2005 -*************** -*** 977,982 **** ---- 977,983 ---- - (((*mailbox == '{') || (*mailbox == '#')) && - (stream = mail_open (NIL,mailbox,OP_PROTOTYPE | OP_SILENT)))) - d = stream->dtb; -+ else if (maildir_valid_name(mailbox)) return maildir_create(stream, mailbox); - else if ((*mailbox != '{') && (ts = default_proto (NIL))) d = ts->dtb; - else { /* failed utterly */ - sprintf (tmp,"Can't create mailbox %.80s: indeterminate format",mailbox); -diff -rc pine4.63/imap/src/c-client/mail.h pine4.63.I.USE/imap/src/c-client/mail.h -*** pine4.63/imap/src/c-client/mail.h Tue Feb 8 15:44:54 2005 ---- pine4.63.I.USE/imap/src/c-client/mail.h Thu May 19 19:57:33 2005 -*************** -*** 149,154 **** ---- 149,156 ---- - #define SET_LOGOUTHOOK (long) 226 - #define GET_LOGOUTDATA (long) 227 - #define SET_LOGOUTDATA (long) 228 -+ #define SET_PASSWORDFILE 229 -+ #define GET_PASSWORDFILE 230 - - /* 3xx: TCP/IP */ - #define GET_OPENTIMEOUT (long) 300 -*************** -*** 311,316 **** ---- 313,320 ---- - #define SET_SNARFPRESERVE (long) 567 - #define GET_INBOXPATH (long) 568 - #define SET_INBOXPATH (long) 569 -+ #define GET_COURIERSTYLE (long) 570 -+ #define SET_COURIERSTYLE (long) 571 - - /* Driver flags */ - -*************** -*** 622,627 **** ---- 626,632 ---- - /* Message envelope */ - - typedef struct mail_envelope { -+ unsigned int ngpathexists : 1; /* newsgroups may be bogus */ - unsigned int incomplete : 1; /* envelope may be incomplete */ - unsigned int imapenvonly : 1; /* envelope only has IMAP envelope */ - char *remail; /* remail header if any */ -*************** -*** 790,795 **** ---- 795,801 ---- - unsigned int spare7 : 1; /* seventh spare bit */ - unsigned int spare8 : 1; /* eighth spare bit */ - void *sparep; /* spare pointer */ -+ void *maildirp; /* for the Maildir driver, can't use sparep */ - unsigned long user_flags; /* user-assignable flags */ - } MESSAGECACHE; - -diff -rc pine4.63/imap/src/c-client/rfc822.c pine4.63.I.USE/imap/src/c-client/rfc822.c -*** pine4.63/imap/src/c-client/rfc822.c Tue Jan 18 12:41:09 2005 ---- pine4.63.I.USE/imap/src/c-client/rfc822.c Thu May 19 19:57:33 2005 -*************** -*** 354,359 **** ---- 354,360 ---- - ENVELOPE *env = (*en = mail_newenvelope ()); - BODY *body = bdy ? (*bdy = mail_newbody ()) : NIL; - long MIMEp = -1; /* flag that MIME semantics are in effect */ -+ long PathP = NIL; /* flag that a Path: was seen */ - parseline_t pl = (parseline_t) mail_parameters (NIL,GET_PARSELINE,NIL); - if (!host) host = BADHOST; /* make sure that host is non-null */ - while (i && *s != '\n') { /* until end of header */ -*************** -*** 443,448 **** ---- 444,452 ---- - *t++ = '\0'; - } - break; -+ case 'P': /* possible Path: */ -+ if (!strcmp (tmp+1,"ATH")) env->ngpathexists = T; -+ break; - case 'R': /* possible Reply-To: */ - if (!strcmp (tmp+1,"EPLY-TO")) - rfc822_parse_adrlist (&env->reply_to,d,host); -diff -rc pine4.63/imap/src/mailutil/mailutil.c pine4.63.I.USE/imap/src/mailutil/mailutil.c -*** pine4.63/imap/src/mailutil/mailutil.c Tue Feb 8 15:50:49 2005 ---- pine4.63.I.USE/imap/src/mailutil/mailutil.c Thu May 19 19:57:33 2005 -*************** -*** 29,34 **** ---- 29,35 ---- - - /* Globals */ - -+ int passfile = NIL; /* password file supplied ? */ - int debugp = NIL; /* flag saying debug */ - int verbosep = NIL; /* flag saying verbose */ - int rwcopyp = NIL; /* flag saying readwrite copy (for POP) */ -*************** -*** 159,164 **** ---- 160,166 ---- - for (nargs = argc ? argc - 1 : 0,args = argv + 1; nargs; args++,nargs--) { - if (*(s = *args) == '-') { /* parse switches */ - if (!strcmp (s,"-debug") || !strcmp (s,"-d")) debugp = T; -+ else if (!strcmp (s,"-passfile")) passfile = T; - else if (!strcmp (s,"-verbose") || !strcmp (s,"-v")) verbosep = T; - else if (!strcmp (s,"-rwcopy") || !strcmp (s,"-rw")) rwcopyp = T; - else if ((nargs > 1) && (!strcmp (s,"-merge") || !strcmp (s,"-m"))) { -*************** -*** 179,184 **** ---- 181,190 ---- - exit (ret); - } - } -+ else if (passfile) { -+ env_parameters(SET_PASSWORDFILE, (void *)s); -+ passfile = NIL; -+ } - else if (!cmd) cmd = s; /* first non-switch is command */ - else if (!src) src = s; /* second non-switch is source */ - else if (!dst) dst = s; /* third non-switch is destination */ -*************** -*** 665,671 **** - username[NETMAXUSER-1] = '\0'; - if (s = strchr (username,'\n')) *s = '\0'; - } -! strcpy (password,getpass ("password: ")); - } - - ---- 671,679 ---- - username[NETMAXUSER-1] = '\0'; - if (s = strchr (username,'\n')) *s = '\0'; - } -! mm_userpwd(mb, &username, &password); -! if (!password || !*password) -! strcpy (password,getpass ("password: ")); - } - - -diff -rc pine4.63/imap/src/osdep/unix/Makefile pine4.63.I.USE/imap/src/osdep/unix/Makefile -*** pine4.63/imap/src/osdep/unix/Makefile Wed Apr 20 17:49:08 2005 ---- pine4.63.I.USE/imap/src/osdep/unix/Makefile Thu May 19 19:57:24 2005 -*************** -*** 119,125 **** - # Standard distribution build parameters - - DEFAULTAUTHENTICATORS=md5 pla log -! DEFAULTDRIVERS=imap nntp pop3 mh mx mbx tenex mtx mmdf unix news phile - - - # Normally no need to change any of these ---- 119,125 ---- - # Standard distribution build parameters - - DEFAULTAUTHENTICATORS=md5 pla log -! DEFAULTDRIVERS=maildir courier imap nntp pop3 mh mx mbx tenex mtx mmdf unix news phile - - - # Normally no need to change any of these -*************** -*** 128,134 **** - BINARIES=osdep.o mail.o misc.o newsrc.o smanager.o utf8.o siglocal.o \ - dummy.o pseudo.o netmsg.o flstring.o fdstring.o \ - rfc822.o nntp.o smtp.o imap4r1.o pop3.o \ -! unix.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o - CFLAGS=-g - - CAT=cat ---- 128,134 ---- - BINARIES=osdep.o mail.o misc.o newsrc.o smanager.o utf8.o siglocal.o \ - dummy.o pseudo.o netmsg.o flstring.o fdstring.o \ - rfc822.o nntp.o smtp.o imap4r1.o pop3.o \ -! unix.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o maildir.o - CFLAGS=-g - - CAT=cat -*************** -*** 257,263 **** - - cyg: # Cygwin - note that most local file drivers don't work!! - $(BUILD) `$(CAT) SPECIALS` OS=$@ \ -! DEFAULTDRIVERS="imap nntp pop3 mbx unix phile" \ - SIGTYPE=psx CHECKPW=cyg LOGINPW=cyg CRXTYPE=std \ - SPOOLDIR=/var \ - ACTIVEFILE=/usr/local/news/lib/active \ ---- 257,263 ---- - - cyg: # Cygwin - note that most local file drivers don't work!! - $(BUILD) `$(CAT) SPECIALS` OS=$@ \ -! DEFAULTDRIVERS="imap nntp pop3 mbx unix maildir phile" \ - SIGTYPE=psx CHECKPW=cyg LOGINPW=cyg CRXTYPE=std \ - SPOOLDIR=/var \ - ACTIVEFILE=/usr/local/news/lib/active \ -*************** -*** 846,852 **** - tenex.o: mail.h misc.h osdep.h dummy.h - unix.o: mail.h misc.h osdep.h unix.h pseudo.h dummy.h - utf8.o: mail.h misc.h osdep.h utf8.h -! - - # OS-dependent - ---- 846,852 ---- - tenex.o: mail.h misc.h osdep.h dummy.h - unix.o: mail.h misc.h osdep.h unix.h pseudo.h dummy.h - utf8.o: mail.h misc.h osdep.h utf8.h -! maildir.o: mail.h misc.h osdep.h maildir.h dummy.h - - # OS-dependent - -diff -rc pine4.63/imap/src/osdep/unix/dummy.c pine4.63.I.USE/imap/src/osdep/unix/dummy.c -*** pine4.63/imap/src/osdep/unix/dummy.c Wed Nov 10 16:16:23 2004 ---- pine4.63.I.USE/imap/src/osdep/unix/dummy.c Thu May 19 19:57:24 2005 -*************** -*** 104,109 **** ---- 104,110 ---- - { - char *s,tmp[MAILTMPLEN]; - struct stat sbuf; -+ maildir_remove_root(&name); - /* must be valid local mailbox */ - if (name && *name && (*name != '{') && (s = mailboxfile (tmp,name))) { - /* indeterminate clearbox INBOX */ -*************** -*** 364,370 **** - char *s,tmp[MAILTMPLEN]; - /* don't \NoSelect dir if it has a driver */ - if ((attributes & LATT_NOSELECT) && (d = mail_valid (NIL,name,NIL)) && -! (d != &dummydriver)) attributes &= ~LATT_NOSELECT; - if (!contents || /* notify main program */ - (!(attributes & LATT_NOSELECT) && (csiz = strlen (contents)) && - (s = mailboxfile (tmp,name)) && ---- 365,374 ---- - char *s,tmp[MAILTMPLEN]; - /* don't \NoSelect dir if it has a driver */ - if ((attributes & LATT_NOSELECT) && (d = mail_valid (NIL,name,NIL)) && -! (d != &dummydriver)){ -! attributes &= ~LATT_NOSELECT; -! attributes |= LATT_NOINFERIORS; -! } - if (!contents || /* notify main program */ - (!(attributes & LATT_NOSELECT) && (csiz = strlen (contents)) && - (s = mailboxfile (tmp,name)) && -*************** -*** 385,390 **** ---- 389,396 ---- - { - char *s,tmp[MAILTMPLEN]; - long ret = NIL; -+ if(!strncmp(mailbox,"#md/",4) || !strncmp(mailbox,"#mc/", 4)) -+ return maildir_create(stream, mailbox); - /* validate name */ - if (!(compare_cstring (mailbox,"INBOX") && (s = dummy_file (tmp,mailbox)))) { - sprintf (tmp,"Can't create %.80s: invalid name",mailbox); -*************** -*** 450,455 **** ---- 456,469 ---- - { - struct stat sbuf; - char *s,tmp[MAILTMPLEN]; -+ if (!strncmp(mailbox,"#md/",4) || !strncmp(mailbox,"#mc/", 4) -+ || is_valid_maildir(&mailbox)){ -+ char tmp[MAILTMPLEN] = {'\0'}; -+ strcpy(tmp, mailbox); -+ if(tmp[strlen(tmp) - 1] != '/') -+ tmp[strlen(tmp)] = '/'; -+ return maildir_delete(stream, tmp); -+ } - if (!(s = dummy_file (tmp,mailbox))) { - sprintf (tmp,"Can't delete - invalid name: %.80s",s); - MM_LOG (tmp,ERROR); -*************** -*** 476,481 **** ---- 490,498 ---- - { - struct stat sbuf; - char c,*s,tmp[MAILTMPLEN],mbx[MAILTMPLEN],oldname[MAILTMPLEN]; -+ -+ maildir_remove_root(&old); -+ maildir_remove_root(&newname); - /* no trailing / allowed */ - if (!dummy_file (oldname,old) || !(s = dummy_file (mbx,newname)) || - ((s = strrchr (s,'/')) && !s[1])) { -diff -rc pine4.63/imap/src/osdep/unix/env_unix.c pine4.63.I.USE/imap/src/osdep/unix/env_unix.c -*** pine4.63/imap/src/osdep/unix/env_unix.c Mon Sep 13 14:31:19 2004 ---- pine4.63.I.USE/imap/src/osdep/unix/env_unix.c Thu May 19 19:57:33 2005 -*************** -*** 24,29 **** ---- 24,30 ---- - - /* c-client environment parameters */ - -+ static char *pwdfile = NIL; /* password file */ - static char *myUserName = NIL; /* user name */ - static char *myHomeDir = NIL; /* home directory name */ - static char *myMailboxDir = NIL;/* mailbox directory name */ -*************** -*** 41,46 **** ---- 42,48 ---- - static char *blackBoxDir = NIL; /* black box directory name */ - /* black box default home directory */ - static char *blackBoxDefaultHome = NIL; -+ static int xlate_key; /* for password file support */ - static short anonymous = NIL; /* is anonymous */ - static short blackBox = NIL; /* is a black box */ - static short closedBox = NIL; /* is a closed box */ -*************** -*** 215,220 **** ---- 217,229 ---- - case GET_SHAREDHOME: - ret = (void *) sharedHome; - break; -+ case SET_PASSWORDFILE: -+ if (pwdfile) fs_give ((void **) &pwdfile); -+ pwdfile = cpystr ((char *) value); -+ break; -+ case GET_PASSWORDFILE: -+ ret = (void *) pwdfile; -+ break; - case SET_SYSINBOX: - if (sysInbox) fs_give ((void **) &sysInbox); - sysInbox = cpystr ((char *) value); -*************** -*** 1638,1640 **** ---- 1647,1723 ---- - } - return ret; - } -+ -+ /* -+ * -+ * Module to add support for password file to a c-client application -+ * -+ * Written by Eduardo Chappa, based on password file support for Pine -+ * -+ */ -+ #ifndef PWDFILE -+ #define PWDFILE 1 -+ #endif -+ -+ #define FIRSTCH 0x20 -+ #define LASTCH 0x7e -+ #define TABSZ (LASTCH - FIRSTCH + 1) -+ -+ char mm_xlate_out (char c); -+ void mm_userpwd (NETMBX *mb, char **username, char **password); -+ -+ /* function that decodes passwords */ -+ -+ char mm_xlate_out (char c) -+ { -+ register int dti; -+ register int xch; -+ -+ if((c >= FIRSTCH) && (c <= LASTCH)){ -+ xch = c - (dti = xlate_key); -+ xch += (xch < FIRSTCH-TABSZ) ? 2*TABSZ : (xch < FIRSTCH) ? TABSZ : 0; -+ dti = (xch - FIRSTCH) + dti; -+ dti -= (dti >= 2*TABSZ) ? 2*TABSZ : (dti >= TABSZ) ? TABSZ : 0; -+ xlate_key = dti; -+ return(xch); -+ } -+ else -+ return(c); -+ } -+ -+ void mm_userpwd (NETMBX *mb, char **username, char **password) -+ { -+ char *s; -+ char tmp[MAILTMPLEN], *ui[5]; -+ FILE *fp; -+ int i, j, n; -+ -+ if (!(pwdfile = env_parameters(GET_PASSWORDFILE, NULL))) -+ return; -+ -+ if (fp = fopen(pwdfile, "r")){ -+ for(n = 0; fgets(tmp, sizeof(tmp), fp); n++){ -+ xlate_key = n; -+ for(i = 0; tmp[i]; i++) -+ tmp[i] = mm_xlate_out(tmp[i]); -+ -+ if(i && tmp[i-1] == '\n') -+ tmp[i-1] = '\0'; -+ -+ ui[0] = ui[1] = ui[2] = ui[3] = ui[4] = NULL; -+ for(i = 0, j = 0; tmp[i] && j < 5; j++){ -+ for(ui[j] = &tmp[i]; tmp[i] && tmp[i] != '\t'; i++); -+ -+ if(tmp[i]) -+ tmp[i++] = '\0'; -+ } -+ if (*username && ui[1] && !strcmp(*username, ui[1]) && mb->host -+ && ((ui[2] && !strcmp(mb->host, ui[2])) -+ || (ui[4] && !strcmp(mb->host,ui[4])) -+ || (ui[2] && !strcmp(mb->orighost, ui[2])) -+ || (ui[4] && !strcmp(mb->orighost,ui[4])))) -+ strcpy (*password,ui[0]); -+ } -+ fclose(fp); -+ } -+ } -diff -rc pine4.63/imap/src/osdep/unix/maildir.c pine4.63.I.USE/imap/src/osdep/unix/maildir.c -*** pine4.63/imap/src/osdep/unix/maildir.c Thu May 19 19:59:15 2005 ---- pine4.63.I.USE/imap/src/osdep/unix/maildir.c Thu May 19 19:57:24 2005 -*************** -*** 0 **** ---- 1,2031 ---- -+ /* -+ * Maildir driver for Pine4.63 -+ * -+ * Written by Eduardo Chappa <chappa@math.washington.edu> -+ * Last Update: May 04, 2005 -+ * -+ * The IMAP toolkit provided in this Distribution is -+ * Copyright 2004 University of Washington. -+ * The full text of our legal notices is contained in the file called -+ * CPYRIGHT, included with this Distribution. -+ */ -+ -+ #include <stdio.h> -+ #include <ctype.h> -+ #include <errno.h> -+ extern int errno; /* just in case */ -+ #include "mail.h" -+ #include "osdep.h" -+ #include <pwd.h> -+ #include <sys/stat.h> -+ #include <sys/time.h> -+ #include "maildir.h" -+ #include "rfc822.h" -+ #include "fdstring.h" -+ #include "misc.h" -+ #include "dummy.h" -+ -+ /* Driver dispatch used by MAIL */ -+ DRIVER maildirdriver = { -+ "md", /* driver name, yes it's md, not maildir */ -+ /* driver flags */ -+ DR_MAIL|DR_LOCAL|DR_NAMESPACE|DR_NOSTICKY, -+ (DRIVER *) NIL, /* next driver */ -+ maildir_valid, /* mailbox is valid for us */ -+ maildir_parameters, /* manipulate parameters */ -+ NIL, /* scan mailboxes */ -+ maildir_list, /* find mailboxes */ -+ maildir_lsub, /* find subscribed mailboxes */ -+ maildir_sub, /* subscribe to mailbox */ -+ maildir_unsub, /* unsubscribe from mailbox */ -+ maildir_create, /* create mailbox */ -+ maildir_delete, /* delete mailbox */ -+ maildir_rename, /* rename mailbox */ -+ mail_status_default, /* status of mailbox */ -+ maildir_open, /* open mailbox */ -+ maildir_close, /* close mailbox */ -+ maildir_fast, /* fetch message "fast" attributes */ -+ NIL, /* fetch message flags */ -+ NIL, /* fetch overview */ -+ NIL, /* fetch message structure */ -+ maildir_header, /* fetch message header */ -+ maildir_text, /* fetch message body */ -+ NIL, /* fetch partial message text */ -+ NIL, /* unique identifier */ -+ NIL, /* message number */ -+ NIL, /* modify flags */ -+ maildir_flagmsg, /* per-message modify flags */ -+ NIL, /* search for message based on criteria */ -+ NIL, /* sort messages */ -+ NIL, /* thread messages */ -+ maildir_ping, /* ping mailbox to see if still alive */ -+ maildir_check, /* check for new messages */ -+ maildir_expunge, /* expunge deleted messages */ -+ maildir_copy, /* copy messages to another mailbox */ -+ maildir_append, /* append string message to mailbox */ -+ NIL /* garbage collect stream */ -+ }; -+ -+ -+ DRIVER courierdriver = { -+ "mc", /* Why a separate driver? So that -+ createproto will work */ -+ /* driver flags */ -+ DR_MAIL|DR_LOCAL|DR_NAMESPACE|DR_NOSTICKY, -+ (DRIVER *) NIL, /* next driver */ -+ maildir_valid, /* mailbox is valid for us */ -+ maildir_parameters, /* manipulate parameters */ -+ NIL, /* scan mailboxes */ -+ courier_list, /* find mailboxes */ -+ maildir_lsub, /* find subscribed mailboxes */ -+ maildir_sub, /* subscribe to mailbox */ -+ maildir_unsub, /* unsubscribe from mailbox */ -+ maildir_create, /* create mailbox */ -+ maildir_delete, /* delete mailbox */ -+ maildir_rename, /* rename mailbox */ -+ mail_status_default, /* status of mailbox */ -+ maildir_open, /* open mailbox */ -+ maildir_close, /* close mailbox */ -+ maildir_fast, /* fetch message "fast" attributes */ -+ NIL, /* fetch message flags */ -+ NIL, /* fetch overview */ -+ NIL, /* fetch message structure */ -+ maildir_header, /* fetch message header */ -+ maildir_text, /* fetch message body */ -+ NIL, /* fetch partial message text */ -+ NIL, /* unique identifier */ -+ NIL, /* message number */ -+ NIL, /* modify flags */ -+ maildir_flagmsg, /* per-message modify flags */ -+ NIL, /* search for message based on criteria */ -+ NIL, /* sort messages */ -+ NIL, /* thread messages */ -+ maildir_ping, /* ping mailbox to see if still alive */ -+ maildir_check, /* check for new messages */ -+ maildir_expunge, /* expunge deleted messages */ -+ maildir_copy, /* copy messages to another mailbox */ -+ maildir_append, /* append string message to mailbox */ -+ NIL /* garbage collect stream */ -+ }; -+ -+ MAILSTREAM maildirproto = {&maildirdriver}; /* prototype stream */ -+ MAILSTREAM courierproto = {&courierdriver}; /* prototype stream */ -+ -+ void -+ md_domain_name(void) -+ { -+ int i; -+ -+ strcpy(mdlocaldomain,mylocalhost ()); -+ for (i = 0; mdlocaldomain[i] ; i++) -+ if(mdlocaldomain[i] == '/') -+ mdlocaldomain[i] = '\057'; -+ else if (mdlocaldomain[i] == ':') -+ mdlocaldomain[i] = '\072'; -+ } -+ -+ /* remove the "#md/" or "#mc/" part from a folder name */ -+ void maildir_remove_root (char **name) -+ { -+ int courier = IS_COURIER(*name); -+ char realname[MAILTMPLEN], *p; -+ -+ if (maildir_valid_name(*name)){ -+ (*name) += 3; -+ if (**name == '/') -+ (*name)++; -+ } -+ if(courier) -+ courier_realname(*name, realname); -+ else -+ strcpy(realname, *name); -+ *name = cpystr(realname); -+ } -+ -+ -+ /* Check validity of the name, we accept: -+ * a) #md/directory/folder -+ * b) #md/inbox -+ * A few considerations: We can only accept as valid -+ * a) names that start with #md/ and the directory exists or -+ * b) names that do not start with #md/ but are maildir directories (have -+ * the /cur, /tmp and /new structure) -+ */ -+ int maildir_valid_name (char *name) -+ { -+ char tmpname[MAILTMPLEN] = {'\0'}; -+ -+ if (mdfpath) -+ fs_give((void **)&mdfpath); -+ if (name && (name[0] != '#')) -+ sprintf(tmpname,"%s%s",MDPREFIX(CCLIENT), name); -+ mdfpath = cpystr(tmpname[0] ? tmpname : name); -+ -+ return IS_CCLIENT(name) || IS_COURIER(name); -+ } -+ -+ /* Check if the directory whose path is given by name is a valid maildir -+ * directory (contains /cur, /tmp and /new) -+ */ -+ int maildir_valid_dir (char *name) -+ { -+ int len; -+ DirNamesType i; -+ struct stat sbuf; -+ char tmp[MAILTMPLEN]; -+ -+ if(name[strlen(name) - 1] == '/') -+ name[strlen(name) - 1] = '\0'; -+ len = strlen(name); -+ for (i = Cur; i != EndDir; i++){ -+ MDFLD(tmp, name, i); -+ if (stat(tmp, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode)) -+ break; -+ } -+ name[len] = '\0'; -+ return i == EndDir ? T : NIL; -+ } -+ -+ void courier_realname(char *name, char *realname) -+ { -+ int i,j; -+ -+ if(!name) -+ return; -+ -+ for (i = 0, j = 0; i < MAILTMPLEN && j < strlen(name); j++, i++){ -+ realname[i] = name[j]; -+ if(name[j] == '/' && name[j+1] != '.' && name[j+1] != '%' -+ && name[j+1] != '*') -+ realname[++i] = '.'; -+ } -+ if(realname[i-1] == '.') -+ i--; -+ realname[i] = '\0'; -+ } -+ -+ -+ /* given a maildir folder, return its path. Memory freed by caller. Directory -+ * does not contain the trailing slash "/". On error NULL is returned. -+ */ -+ int maildir_file_path (char *name, char *tmp) -+ { -+ char *maildirpath = maildir_parameters(GET_INBOXPATH,NIL); -+ char realname[MAILTMPLEN]; -+ int courier = IS_COURIER(name); -+ -+ /* There are several ways in which the path can come, so we will handle -+ them here. First we deal with #mc/ or #md/ prefix by removing the -+ prefix, if any */ -+ -+ maildir_remove_root(&name); -+ tmp[0] = '\0'; /* just in case something fails */ -+ -+ if (strlen(myhomedir()) + -+ max(strlen(name), strlen(maildirpath -+ ? maildirpath : "Maildir")) > MAILTMPLEN){ -+ errno = ENAMETOOLONG; -+ sprintf(tmp,"Error opening \"%s\": %s", name, strerror (errno)); -+ mm_log(tmp,ERROR); -+ return NIL; -+ } -+ -+ /* There are two ways in which the name can come here, either as a -+ full path or not. If it is not a full path it can come in two ways, -+ either as a file system path (Maildir/.Drafts) or as a maildir path -+ (INBOX.Drafts) -+ */ -+ -+ if(*name == '/') /* full path */ -+ strcpy(tmp, name); /* do nothing */ -+ else{ -+ sprintf (tmp,"%s/%s%s%s", myhomedir (), -+ strncmp (ucase (strcpy (tmp, name)), "INBOX", 5) -+ ? name : (maildirpath ? maildirpath : "Maildir"), -+ strncmp (ucase (strcpy (tmp, name)), "INBOX", 5) -+ ? "" : (courier ? "/" : ""), -+ strncmp (ucase (strcpy (tmp, name)), "INBOX", 5) -+ ? "" : *(name+5) == MDSEPARATOR(courier) ? name+5 : ""); -+ } -+ -+ return tmp[0] ? T : NIL; -+ } -+ -+ /* This function is given a full path for a mailbox and returns -+ * if it is a valid maildir transformed to canonical notation -+ */ -+ int -+ is_valid_maildir (char **name) -+ { -+ if (!strncmp(*name, myhomedir (), strlen(myhomedir()))){ -+ (*name) += strlen(myhomedir()); -+ if (**name == '/') (*name)++; -+ } -+ return maildir_valid(*name) ? T : NIL; -+ } -+ -+ /* Check validity of mailbox. This routine does not send errors to log, other -+ * routines calling this one may do so, though -+ */ -+ -+ DRIVER *maildir_valid (char *name) -+ { -+ char tmpname[MAILTMPLEN]; -+ -+ maildir_file_path(name, tmpname); -+ -+ return maildir_valid_dir(tmpname) -+ ? (IS_COURIER(name) ? &courierdriver : &maildirdriver) : NIL; -+ } -+ /*maildir fast */ -+ void maildir_fast (MAILSTREAM *stream,char *sequence,long flags) -+ { -+ unsigned long i; -+ MESSAGECACHE *elt; -+ /* get sequence */ -+ if (stream && LOCAL && ((flags & FT_UID) ? -+ mail_uid_sequence (stream,sequence) : -+ mail_sequence (stream,sequence))) -+ for (i = 1; i <= stream->nmsgs; i++) { -+ if ((elt = mail_elt (stream,i))->sequence && (elt->valid = T) && -+ !(elt->day && elt->rfc822_size)) { -+ ENVELOPE **env = NIL; -+ ENVELOPE *e = NIL; -+ if (!stream->scache) env = &elt->private.msg.env; -+ else if (stream->msgno == i) env = &stream->env; -+ else env = &e; -+ if (!*env || !elt->rfc822_size) { -+ STRING bs; -+ unsigned long hs; -+ char *ht = (*stream->dtb->header) (stream,i,&hs,NIL); -+ -+ if (!*env) rfc822_parse_msg (env,NIL,ht,hs,NIL,BADHOST, -+ stream->dtb->flags); -+ if (!elt->rfc822_size) { -+ (*stream->dtb->text) (stream,i,&bs,FT_PEEK); -+ elt->rfc822_size = hs + SIZE (&bs) - GETPOS (&bs); -+ } -+ } -+ -+ if (!elt->day && *env && (*env)->date) -+ mail_parse_date (elt,(*env)->date); -+ -+ if (!elt->day) elt->day = elt->month = 1; -+ mail_free_envelope (&e); -+ } -+ } -+ } -+ -+ -+ /* -+ * return all files in a given directory. This is a separate call -+ * so that if there are warnings during compilation this only appears once. -+ */ -+ unsigned long -+ maildir_scandir (char *name, struct direct ***flist, -+ unsigned long *nfiles, int *scand, int flag) -+ { -+ struct stat sbuf; -+ -+ if (scand) -+ *scand = -1; /* assume error for safety */ -+ stat(name,&sbuf); /* stat the containing directory */ -+ if (scand) -+ *scand = scandir(name, flist, -+ flag == CCLIENT ? maildir_select : courier_dir_select, -+ flag == CCLIENT ? maildir_namesort : courier_dir_sort); -+ *nfiles = (scand && (*scand > 0)) ? (unsigned long) *scand : 0L; -+ -+ return sbuf.st_ctime; -+ } -+ -+ /* Does a message with given name exists (or was it removed)? -+ * Returns: 1 - yes, such message exist, -+ * 0 - No, that message does not exist anymore -+ * -+ * Parameters: stream, name of mailbox, new name if his message does not -+ * exist. -+ */ -+ -+ int maildir_message_exists(MAILSTREAM *stream, char *name, char *newfile) -+ { -+ char tmp[MAILTMPLEN]; -+ int gotit = NIL; -+ DIR *dir; -+ struct direct *d; -+ struct stat sbuf; -+ -+ /* First check directly if it exists, if not there, look for it */ -+ sprintf(tmp,"%s/%s", LOCAL->curdir, name); -+ if ((stat(tmp, &sbuf) == 0) && ((sbuf.st_mode & S_IFMT) == S_IFREG)) -+ return T; -+ -+ if (!(dir = opendir (LOCAL->curdir))) -+ return NIL; -+ -+ while ((d = readdir(dir)) && gotit == NIL){ -+ if (d->d_name[0] == '.') -+ continue; -+ if (same_maildir_file(d->d_name, name)){ -+ gotit = T; -+ strcpy(newfile, d->d_name); -+ } -+ } -+ closedir(dir); -+ return gotit; -+ } -+ -+ /* Maildir open */ -+ -+ MAILSTREAM *maildir_open (MAILSTREAM *stream) -+ { -+ char tmp[MAILTMPLEN]; -+ struct stat sbuf; -+ -+ if (!stream) return &maildirproto; -+ if (stream->local) fatal ("maildir recycle stream"); -+ md_domain_name(); /* get domain name for maildir files in mdlocaldomain */ -+ stream->uid_last = stream->uid_validity = 0; -+ if (!stream->rdonly){ -+ stream->perm_seen = stream->perm_deleted = stream->perm_flagged = -+ stream->perm_answered = stream->perm_draft = T; -+ } -+ stream->uid_validity = time(0); -+ stream->local = (MAILDIRLOCAL *)fs_get (sizeof (MAILDIRLOCAL)); -+ memset(LOCAL, 0, sizeof(MAILDIRLOCAL)); -+ LOCAL->fd = -1; -+ -+ LOCAL->courier = IS_COURIER(stream->mailbox); -+ strcpy(tmp, stream->mailbox); -+ if (maildir_file_path (stream->mailbox, tmp)) -+ LOCAL->dir = cpystr (tmp); -+ if (LOCAL->dir){ -+ MDFLD(tmp, LOCAL->dir, Cur); -+ LOCAL->curdir = cpystr (tmp); -+ if (stat (LOCAL->curdir,&sbuf) < 0) { -+ sprintf (tmp,"Can't open folder %s: %s", -+ stream->mailbox,strerror (errno)); -+ mm_log (tmp,ERROR); -+ maildir_close(stream, 0); -+ return NIL; -+ } -+ } -+ -+ if(maildir_file_path (stream->mailbox, tmp)){ -+ fs_give ((void **) &stream->mailbox); -+ stream->mailbox = cpystr(tmp); -+ } -+ -+ LOCAL->buf = (char *) fs_get ((LOCAL->buflen = MAXMESSAGESIZE) + 1); -+ stream->sequence++; -+ stream->nmsgs = stream->recent = 0; -+ -+ maildir_parse_folder(stream, 1); -+ -+ return stream; -+ } -+ -+ /* Maildir initial parsing of the folder */ -+ void -+ maildir_parse_folder (MAILSTREAM *stream, int full) -+ { -+ unsigned long total; -+ -+ if (!stream) /* what??? */ -+ return; -+ -+ MM_CRITICAL(stream); -+ -+ /* Scan old messages first, escoba! */ -+ total = LOCAL ? maildir_parse_dir(stream, 0L, Cur, full) -+ : stream->nmsgs; -+ stream->nmsgs = LOCAL ? maildir_parse_dir(stream, total, New, full) -+ : stream->nmsgs; -+ -+ MM_NOCRITICAL(stream); -+ } -+ -+ /* Return the number of messages in the directory, while filling the -+ * elt structure. -+ */ -+ -+ unsigned long -+ maildir_parse_dir(MAILSTREAM *stream, unsigned long nmsgs, -+ DirNamesType dirtype, int full) -+ { -+ char tmp[MAILTMPLEN], tmp2[MAILTMPLEN], file[MAILTMPLEN], -+ newfile[MAILTMPLEN], *mdstr; -+ struct direct **names = NIL; -+ struct stat sbuf; -+ unsigned long i, j = 0L, nfiles, last_scan; -+ unsigned long recent = stream ? stream->recent : 0L; -+ int d = 0, f = 0, r = 0, s = 0, t = 0; -+ int k, we_compute, in_list, scan_err; -+ int silent = stream ? stream->silent : NIL; -+ MESSAGECACHE *elt; -+ -+ MDFLD(tmp, LOCAL->dir, dirtype); -+ if (access (tmp, R_OK|W_OK|X_OK) != 0){ -+ maildir_abort(stream); -+ return stream->nmsgs; -+ } -+ -+ MDFLD(tmp, LOCAL->dir, Cur); -+ if (dirtype != New && -+ (stat(tmp, &sbuf) < 0 || sbuf.st_ctime == LOCAL->scantime)) -+ return stream->nmsgs; -+ -+ MDFLD(tmp, LOCAL->dir, dirtype); -+ last_scan = maildir_scandir (tmp, &names, &nfiles, &scan_err, CCLIENT); -+ if (dirtype == Cur) -+ LOCAL->scantime = last_scan; -+ -+ if (scan_err < 0){ -+ maildir_abort(stream); -+ return nmsgs; -+ } -+ -+ if (dirtype == Cur) -+ for (i = 1L; i <= stream->nmsgs;){ -+ elt = mail_elt(stream, i); -+ in_list = elt && elt->maildirp && nfiles > 0L -+ ? (MDPOS(elt) < nfiles -+ ? same_maildir_file(MDFILE(elt), names[MDPOS(elt)]->d_name) -+ : NIL) -+ || maildir_message_in_list(MDFILE(elt), names, 0L, -+ nfiles - 1L, &MDPOS(elt)) -+ : NIL; -+ if (!in_list){ -+ if (elt->maildirp) -+ maildir_free_file ((void **) &elt->maildirp); -+ -+ if (elt->recent) --recent; -+ mail_expunged(stream,i); -+ } -+ else i++; -+ } -+ -+ stream->silent = T; -+ for (we_compute = 0, i = 1L; i <= nfiles; i++){ -+ unsigned long pos, n; -+ mail_exists(stream, i + nmsgs); -+ elt = mail_elt(stream, i + nmsgs); -+ if (elt && elt->maildirp) -+ pos = MDPOS(elt); /* use data we found above */ -+ else{ -+ if (full) -+ pos = i - 1; /* first time, use sequence number */ -+ else{ -+ for (n = 0L ; (n < nfiles) && !names[n] ; n++); -+ pos = n; /* nfiles > stream->nmsgs!!, assign one */ -+ } -+ } -+ if (dirtype == New) elt->recent = T; -+ if (!elt->private.uid){ -+ elt->private.uid = stream->uid_last + 1; -+ stream->uid_validity = time(0); -+ } -+ if (stream->uid_last < elt->private.uid) -+ stream->uid_last = elt->private.uid; -+ -+ maildir_getflag(names[pos]->d_name, &d, &f, &r ,&s, &t); -+ if (elt->maildirp) -+ maildir_free_file_only ((void **)&elt->maildirp); -+ else{ -+ maildir_get_file((MAILDIRFILE **)&elt->maildirp); -+ we_compute++; -+ } -+ MDFILE(elt) = cpystr(names[pos]->d_name); -+ MDPOS(elt) = pos; -+ -+ if (elt->draft != d || elt->flagged != f || -+ elt->answered != r || elt->seen != s || elt->deleted != t){ -+ elt->draft = d; elt->flagged = f; elt->answered = r; -+ elt->seen = s; elt->deleted = t; -+ if (!we_compute && !stream->rdonly) -+ MM_FLAGS(stream, i+nmsgs); -+ } -+ maildir_get_date(stream, i+nmsgs, dirtype); -+ elt->valid = T; -+ if (dirtype == New && !stream->rdonly){ /* move new messages to cur */ -+ sprintf (file,"%s/%s", tmp, names[pos]->d_name); -+ if (stat (file,&sbuf) == 0 && S_ISREG (sbuf.st_mode)){ -+ strcpy(tmp2,names[pos]->d_name); -+ if ((mdstr = strstr (names[pos]->d_name,MDSEP(3))) -+ || (mdstr = strstr (names[pos]->d_name,MDSEP(2)))){ /* Grrr */ -+ *(mdstr+1) = '2'; -+ sprintf (newfile,"%s/%s",LOCAL->curdir,names[pos]->d_name); -+ } -+ else{ -+ sprintf (newfile,"%s/%s%s",LOCAL->curdir,names[pos]->d_name,MDSEP(2)); -+ strcat(tmp2, MDSEP(2)); -+ } -+ if (link (file,newfile) < 0){ -+ mm_log("Unable to read new mail!",WARN); -+ } -+ else{ -+ unlink (file); -+ j++; /* success!, count it! */ -+ } -+ maildir_free_file_only((void **)&elt->maildirp); -+ MDFILE(elt) = cpystr(tmp2); -+ MDSIZE(elt) = sbuf.st_size; -+ MDMTIME(elt) = sbuf.st_mtime; -+ maildir_get_date(stream, i + nmsgs, New); -+ } -+ } -+ fs_give((void **)&names[pos]); -+ } -+ if(names) -+ fs_give((void **) &names); -+ stream->silent = silent; -+ if (dirtype == New && stream->rdonly) -+ j = nfiles; -+ mail_exists(stream, nmsgs + (dirtype == New ? j : nfiles)); -+ mail_recent(stream, recent + (dirtype == New ? j : 0)); -+ -+ return (nmsgs + (dirtype == New ? j : nfiles)); -+ } -+ -+ long maildir_ping (MAILSTREAM *stream) -+ { -+ maildir_parse_folder(stream, 0); -+ return stream && LOCAL ? T : NIL; -+ } -+ -+ int maildir_select (struct direct *name) -+ { -+ int rv = NIL, val; -+ val = name->d_name[0] - '0'; -+ switch(val){ -+ case 1: case 2: case 3: case 4: case 5: -+ case 6: case 7: case 8: case 9: -+ rv = T; -+ default: break; -+ } -+ return rv; -+ } -+ -+ /* -+ * Unfortunately, there is no way to sort by arrival in this driver, this -+ * means that opening a folder in this driver using the scandir function -+ * will always make this driver slower than any driver that has a natural -+ * way of sorting by arrival (like a flat file format, "mbox", "mbx", etc). -+ */ -+ -+ int maildir_namesort (const void *d1,const void *d2) -+ { -+ const struct direct **e1, **e2; -+ -+ e1 = (const struct direct **)d1; -+ e2 = (const struct direct **)d2; -+ -+ return comp_maildir_file((char*)(*e1)->d_name, (char *)(*e2)->d_name); -+ } -+ -+ /* Maildir close */ -+ -+ void maildir_close (MAILSTREAM *stream, long options) -+ { -+ MESSAGECACHE *elt; -+ unsigned long i; -+ int silent = stream ? stream->silent : 0; -+ mailcache_t mc = (mailcache_t) mail_parameters (NIL,GET_CACHE,NIL); -+ -+ if (!stream) return; -+ -+ for (i = 1; i <= stream->nmsgs; i++) -+ if ((elt = (MESSAGECACHE *) (*mc) (stream,i,CH_ELT)) && elt->maildirp) -+ maildir_free_file ((void **) &(elt->maildirp)); -+ stream->silent = T; -+ if (options & CL_EXPUNGE) maildir_expunge (stream); -+ maildir_abort(stream); -+ if (mdfpath) fs_give((void **)&mdfpath); -+ stream->silent = silent; -+ } -+ -+ void maildir_check (MAILSTREAM *stream) -+ { -+ if (maildir_ping (stream)) mm_log ("Check completed",(long) NIL); -+ } -+ -+ long maildir_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs, long flags) -+ { -+ char tmp[MAILTMPLEN]; -+ unsigned long i; -+ MESSAGECACHE *elt; -+ char *s; -+ /* UID call "impossible" */ -+ if (flags & FT_UID || !LOCAL) return NIL; -+ elt = mail_elt (stream,msgno); -+ sprintf (tmp,"%s/%s",LOCAL->curdir, MDFILE(elt)); -+ if (LOCAL->fd < 0) /* if file closed ? */ -+ LOCAL->fd = open(tmp,O_RDONLY,NIL); -+ -+ if (LOCAL->fd < 0 && (errno == EACCES || errno == ENOENT)){ -+ INIT (bs, mail_string, "", 0); -+ elt->rfc822_size = 0L; -+ return NIL; -+ } -+ -+ if (LOCAL->dirty == 0) -+ MM_FLAGS(stream, elt->msgno); -+ -+ s = maildir_text_work(stream, elt, &i, flags); -+ INIT (bs, mail_string, s, i); -+ return T; -+ } -+ -+ char *maildir_text_work (MAILSTREAM *stream,MESSAGECACHE *elt, -+ unsigned long *length,long flags) -+ { -+ FDDATA d; -+ STRING bs; -+ char *s,*t,*tl,tmp[CHUNK]; -+ unsigned long msgno = elt->msgno; -+ static int try = 0; -+ -+ if (length) -+ *length = 0L; -+ LOCAL->buf[0] = '\0'; -+ -+ sprintf (tmp,"%s/%s",LOCAL->curdir, MDFILE(elt)); -+ if (LOCAL->fd < 0) /* if file closed ? */ -+ LOCAL->fd = open(tmp,O_RDONLY,NIL); -+ -+ if (LOCAL->fd < 0){ /* flag change? */ -+ if (try < 5){ -+ try++; -+ if (maildir_update_elt_maildirp(stream, msgno) > 0) -+ try = 0; -+ return maildir_text_work(stream, mail_elt(stream, msgno),length, flags); -+ } -+ try = 0; -+ return NULL; -+ } -+ -+ lseek (LOCAL->fd, elt->private.msg.text.offset,L_SET); -+ -+ if (flags & FT_INTERNAL) { /* initial data OK? */ -+ if (elt->private.msg.text.text.size > LOCAL->buflen) { -+ fs_give ((void **) &LOCAL->buf); -+ LOCAL->buf = (char *) fs_get ((LOCAL->buflen = -+ elt->private.msg.text.text.size) + 1); -+ } -+ read (LOCAL->fd,LOCAL->buf,elt->private.msg.text.text.size); -+ LOCAL->buf[*length = elt->private.msg.text.text.size] = '\0'; -+ } -+ else { -+ if (elt->rfc822_size > LOCAL->buflen) { -+ fs_give ((void **) &LOCAL->buf); -+ LOCAL->buf = (char *) fs_get ((LOCAL->buflen = elt->rfc822_size) + 1); -+ } -+ d.fd = LOCAL->fd; /* yes, set up file descriptor */ -+ d.pos = elt->private.msg.text.offset; -+ d.chunk = tmp; /* initial buffer chunk */ -+ d.chunksize = CHUNK; -+ INIT (&bs,fd_string,&d,elt->private.msg.text.text.size); -+ for (s = LOCAL->buf; SIZE (&bs);) switch (CHR (&bs)) { -+ case '\r': /* carriage return seen */ -+ *s++ = SNX (&bs); /* copy it and any succeeding LF */ -+ if (SIZE (&bs) && (CHR (&bs) == '\n')) *s++ = SNX (&bs); -+ break; -+ case '\n': -+ *s++ = '\r'; /* insert a CR */ -+ default: -+ *s++ = SNX (&bs); /* copy characters */ -+ } -+ *s = '\0'; /* tie off buffer */ -+ *length = s - (char *) LOCAL->buf; /* calculate length */ -+ } -+ close(LOCAL->fd); LOCAL->fd = -1; -+ return LOCAL->buf; -+ } -+ -+ /* maildir parse, fill the elt structure... well not all of it... */ -+ unsigned long maildir_parse_message(MAILSTREAM *stream, unsigned long msgno, -+ DirNamesType dirtype) -+ { -+ char *b, *s, c; -+ char tmp[MAILTMPLEN]; -+ struct stat sbuf; -+ unsigned long i, len; -+ int offset = 0, d, f, r, se, dt; -+ MESSAGECACHE *elt; -+ -+ elt = mail_elt (stream,msgno); -+ MSGPATH(tmp, LOCAL->dir, MDFILE(elt), dirtype); -+ if(stat(tmp, &sbuf) == 0) -+ MDSIZE(elt) = sbuf.st_size; -+ -+ maildir_get_date(stream, msgno, dirtype); -+ maildir_getflag(MDFILE(elt), &d, &f, &r ,&se, &dt); -+ elt->draft = d; elt->flagged = f; elt->answered = r; elt->seen = se; -+ elt->deleted = dt; elt->valid = T; -+ if (LOCAL->fd < 0) /* if file closed ? */ -+ LOCAL->fd = open(tmp,O_RDONLY,NIL); -+ -+ if (LOCAL->fd >= 0){ -+ s = (char *) fs_get (MDSIZE(elt) + 1); -+ read (LOCAL->fd,s,MDSIZE(elt)); -+ s[MDSIZE(elt)] = '\0'; -+ for (i = 0, b = s; *b && !(i && (*b == '\n')); i = (*b++ == '\n')); -+ len = (*b ? ++b : b) - s; -+ elt->private.msg.header.text.size = -+ elt->private.msg.text.offset = len; -+ elt->private.msg.text.text.size = MDSIZE(elt) - len; -+ for (i = 0, b = s, c = *b; b && c && -+ ((c < '\016') && (((c == '\012') && ++i) || -+ ((c == '\015') && (*++b == '\012') && (i +=2))) -+ || c); i++, c= *++b); -+ elt->rfc822_size = i; -+ fs_give ((void **) &s); -+ close(LOCAL->fd); LOCAL->fd = -1; -+ } -+ return elt->rfc822_size; -+ } -+ -+ int -+ maildir_update_elt_maildirp(MAILSTREAM *stream, unsigned long msgno) -+ { -+ char tmp[MAILTMPLEN]; -+ struct direct **names = NIL; -+ unsigned long i, nfiles, pos; -+ int d = 0, f = 0 , r = 0, s = 0, t = 0, in_list, scan_err; -+ MESSAGECACHE *elt; -+ -+ MDFLD(tmp, LOCAL->dir, Cur); -+ -+ maildir_scandir (tmp, &names, &nfiles, &scan_err, CCLIENT); -+ -+ elt = mail_elt (stream,msgno); -+ -+ in_list = nfiles > 0L -+ ? maildir_message_in_list(MDFILE(elt), names, 0L, -+ nfiles - 1L, &pos) -+ : NIL; -+ -+ if (in_list && pos >= 0L && pos < nfiles -+ && !strcmp(MDFILE(elt), names[pos]->d_name)){ -+ in_list = NIL; -+ maildir_abort(stream); -+ } -+ -+ if (in_list && pos >= 0L && pos < nfiles){ -+ maildir_free_file_only((void **)&elt->maildirp); -+ MDFILE(elt) = cpystr(names[pos]->d_name); -+ maildir_getflag(MDFILE(elt), &d, &f, &r ,&s, &t); -+ if (elt->draft != d || elt->flagged != f || -+ elt->answered != r || elt->seen != s || elt->deleted != t){ -+ elt->draft = d; elt->flagged = f; elt->answered = r; -+ elt->seen = s; elt->deleted = t; -+ MM_FLAGS(stream, msgno); -+ } -+ } -+ for (i = 0L; i < nfiles; i++) -+ fs_give((void **) &names[i]); -+ if (names) -+ fs_give((void **) &names); -+ return in_list ? 1 : -1; -+ } -+ -+ /* Maildir fetch message header */ -+ -+ char *maildir_header (MAILSTREAM *stream,unsigned long msgno, -+ unsigned long *length, long flags) -+ { -+ char tmp[MAILTMPLEN], *s; -+ MESSAGECACHE *elt; -+ static int try = 0; -+ -+ if (length) -+ *length = 0; -+ if (flags & FT_UID || !LOCAL) return ""; /* UID call "impossible" */ -+ elt = mail_elt (stream,msgno); -+ if(elt->private.msg.header.text.size == 0) -+ maildir_parse_message(stream, msgno, Cur); -+ -+ sprintf (tmp,"%s/%s",LOCAL->curdir, MDFILE(elt)); -+ if (LOCAL->fd < 0) -+ LOCAL->fd = open (tmp,O_RDONLY,NIL); -+ -+ if (LOCAL->fd < 0 && errno == EACCES){ -+ mm_log ("Message exists but can not be read. Envelope and body lost!",ERROR); -+ return NULL; -+ } -+ -+ if (LOCAL->fd < 0){ /* flag change? */ -+ if (try < 5){ -+ try++; -+ if (maildir_update_elt_maildirp(stream, msgno) > 0) -+ try = 0; -+ return maildir_header(stream, msgno, length, flags); -+ } -+ try = 0; -+ return NULL; -+ } -+ -+ if ((flags & FT_INTERNAL) && -+ (elt->private.msg.header.text.size > LOCAL->buflen)){ -+ fs_give ((void **) &LOCAL->buf); -+ LOCAL->buf = (char *) fs_get ((LOCAL->buflen = -+ elt->private.msg.header.text.size) + 1); -+ } -+ else -+ s = (char *) fs_get(elt->private.msg.header.text.size+1); -+ if (LOCAL->fd >= 0){ -+ read (LOCAL->fd, flags & FT_INTERNAL ? (void *)LOCAL->buf : (void *)s, -+ elt->private.msg.header.text.size); -+ if (flags & FT_INTERNAL) -+ LOCAL->buf[*length = elt->private.msg.header.text.size] = '\0'; -+ else{ -+ s[*length = elt->private.msg.header.text.size] = '\0'; -+ *length = strcrlfcpy (&LOCAL->buf,&LOCAL->buflen,s, -+ elt->private.msg.header.text.size); -+ fs_give ((void **) &s); -+ } -+ } -+ elt->private.msg.text.offset = elt->private.msg.header.text.size; -+ elt->private.msg.text.text.size = MDSIZE(elt) - elt->private.msg.text.offset; -+ if(s) -+ fs_give((void **)&s); -+ close(LOCAL->fd); LOCAL->fd = -1; -+ return LOCAL->buf; -+ } -+ -+ /* Maildir find list of subscribed mailboxes -+ * Accepts: mail stream -+ * pattern to search -+ */ -+ -+ void maildir_list (MAILSTREAM *stream,char *ref, char *pat) -+ { -+ char *s,test[MAILTMPLEN],file[MAILTMPLEN]; -+ long i = 0; -+ -+ if((!pat || !*pat) && (maildir_canonicalize (test,ref,"*")) -+ && maildir_valid_name(test)){ /* there is a #md/ leading here */ -+ for (i = 3; test[i] && test[i] != '/'; i++); -+ if (s = strchr (test+i+1,'/')) *++s = '\0'; -+ else test[0] = '\0'; -+ mm_list (stream,'/',test, LATT_NOSELECT); -+ } -+ else if (maildir_canonicalize (test,ref,pat)) { -+ if (test[3] == '/') { /* looking down levels? */ -+ /* yes, found any wildcards? */ -+ if (s = strpbrk (test,"%*")) { -+ /* yes, copy name up to that point */ -+ strncpy (file,test+4,i = s - (test+4)); -+ file[i] = '\0'; /* tie off */ -+ } -+ else strcpy (file,test+4);/* use just that name then */ -+ /* find directory name */ -+ if (s = strrchr (file,'/')) { -+ *s = '\0'; /* found, tie off at that point */ -+ s = file; -+ } -+ /* do the work */ -+ if(IS_COURIER(test)) -+ courier_list_work (stream,s,test,0); -+ else -+ maildir_list_work (stream,s,test,0); -+ } -+ /* always an INBOX */ -+ if (!compare_cstring (test,"#MD/INBOX")) -+ mm_list (stream,NIL,"#MD/INBOX",LATT_NOINFERIORS); -+ if (!compare_cstring (test,"#MC/INBOX")) -+ mm_list (stream,NIL,"#MC/INBOX",LATT_NOINFERIORS); -+ } -+ } -+ -+ void courier_list (MAILSTREAM *stream,char *ref, char *pat) -+ { -+ /* I am too lazy to do anything. Do you care to ask maildir list, please? -+ The real reason why this is a dummy function is because we do not want to -+ see the same folder listed twice. -+ */ -+ } -+ -+ /* For those that want to hide things, we give them a chance to do so */ -+ void *maildir_parameters (long function, void *value) -+ { -+ void *ret = NIL; -+ switch ((int) function) { -+ case SET_INBOXPATH: -+ if (myMdInboxDir) fs_give ((void **) &myMdInboxDir); -+ myMdInboxDir = cpystr ((char *) value); -+ case GET_INBOXPATH: -+ if (!myMdInboxDir) myMdInboxDir = cpystr("Maildir"); -+ ret = (void *) myMdInboxDir; -+ break; -+ case SET_COURIERSTYLE: -+ CourierStyle = (long) value; -+ case GET_COURIERSTYLE: -+ ret = (void *) CourierStyle; -+ break; -+ default: -+ break; -+ } -+ return ret; -+ } -+ -+ int maildir_create_folder(char *mailbox) -+ { -+ char tmp[MAILTMPLEN], err[MAILTMPLEN]; -+ int i; -+ -+ for (i = Cur; i != EndDir; i++){ -+ MDFLD(tmp, mailbox, i); -+ if (mkdir(tmp, 0700) && errno != EEXIST){ /* try to make new dir */ -+ sprintf (err, "Can't create %s: %s", tmp, strerror(errno)); -+ mm_log (err,ERROR); -+ return NIL; -+ } -+ } -+ return T; -+ } -+ -+ int maildir_create_work(char *mailbox, int loop) -+ { -+ char *s, c, err[MAILTMPLEN], tmp[MAILTMPLEN], tmp2[MAILTMPLEN], mbx[MAILTMPLEN]; -+ int fnlen, i, create_dir = 0, courier, mv; -+ struct stat sbuf; -+ long style = (long) maildir_parameters(GET_COURIERSTYLE, NIL); -+ -+ courier = IS_COURIER(mailbox); -+ strcpy(mbx, mailbox); -+ mv = maildir_valid(mbx) ? 1 : 0; -+ maildir_file_path(mailbox, tmp); -+ if (mailbox[strlen(mailbox) - 1] == MDSEPARATOR(courier)){ -+ create_dir++; -+ mailbox[strlen(mailbox) - 1] = '\0'; -+ } -+ -+ if(!loop && courier){ -+ if(mv){ -+ if(create_dir){ -+ if(style == CCLIENT) -+ strcpy (err,"Can not create directory: folder exists. Create subfolder"); -+ else -+ strcpy(err,"Folder and Directory already exist"); -+ } -+ else -+ strcpy (err, "Can't create mailbox: mailbox already exists"); -+ } -+ else{ -+ if(create_dir) -+ strcpy(err, "Can not create directory. Cread folder instead"); -+ else -+ err[0] = '\0'; -+ } -+ if(err[0]){ -+ mm_log (err,ERROR); -+ return NIL; -+ } -+ } -+ -+ fnlen = strlen(tmp); -+ if (s = strrchr(mailbox,MDSEPARATOR(courier))){ -+ c = *++s; -+ *s = '\0'; -+ if ((stat(tmp,&sbuf) || ((sbuf.st_mode & S_IFMT) != S_IFDIR)) && -+ !maildir_create_work (mailbox, ++loop)) -+ return NIL; -+ *s = c; -+ } -+ tmp[fnlen] = '\0'; -+ -+ if (mkdir(tmp,0700) && errno != EEXIST) -+ return NIL; -+ -+ if (create_dir) -+ mailbox[fnlen] = '/'; -+ -+ if (create_dir){ -+ if(style == CCLIENT){ -+ if(!courier){ -+ FILE *fp = NULL; -+ sprintf(tmp2,"%s%s", tmp, MDDIR); -+ if ((fp = fopen(tmp2,"w")) == NULL){ -+ sprintf (err,"Problem creating %s: %s", tmp2, strerror(errno)); -+ mm_log (err,ERROR); -+ return NIL; -+ } -+ fclose(fp); -+ } -+ } -+ return T; -+ } -+ else -+ return maildir_create_folder(tmp); -+ } -+ -+ long maildir_create (MAILSTREAM *stream,char *mailbox) -+ { -+ char tmp[MAILTMPLEN], err[MAILTMPLEN]; -+ long rv; -+ int create_dir; -+ -+ create_dir = mailbox ? -+ (mailbox[strlen(mailbox) - 1] == -+ MDSEPARATOR(IS_COURIER(mailbox))) : 0; -+ maildir_file_path(mailbox, tmp); -+ strcpy(tmp, mailbox); -+ rv = maildir_create_work(mailbox, 0); -+ strcpy(mailbox, tmp); -+ if (rv == 0){ -+ sprintf (err,"Can't create %s %s", -+ create_dir ? "directory" : "mailbox", mailbox); -+ mm_log (err,ERROR); -+ } -+ return rv ? 1L : 0L; -+ } -+ -+ #define MAXTRY 10000 -+ void maildir_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt) -+ { -+ char oldfile[MAILTMPLEN],newfile[MAILTMPLEN],fn[MAILTMPLEN]; -+ char tmp[MAILTMPLEN]; -+ char *s; -+ int ren, try = 0; -+ -+ LOCAL->dirty = 0; -+ if (elt->valid){ -+ for (try = 1; try > 0 && try < MAXTRY; try++){ -+ /* build the new filename */ -+ sprintf (oldfile,"%s/%s",LOCAL->curdir, MDFILE(elt)); -+ fn[0] = '\0'; -+ if ((ren = maildir_message_exists(stream, MDFILE(elt), fn)) == 0){ -+ errno = ENOENT; -+ try = MAXTRY; -+ } -+ if (*fn) /* new oldfile! */ -+ sprintf (oldfile,"%s/%s",LOCAL->curdir,fn); -+ if ((s = strchr (MDFILE(elt), FLAGSEP))) *s = '\0'; -+ sprintf (fn,"%s%s%s%s%s%s%s", MDFILE(elt), MDSEP(2), -+ MDFLAG(Draft, elt->draft), MDFLAG(Flagged, elt->flagged), -+ MDFLAG(Replied, elt->answered), MDFLAG(Seen, elt->seen), -+ MDFLAG(Trashed, elt->deleted)); -+ sprintf (newfile,"%s/%s",LOCAL->curdir,fn); -+ if (ren != 0 && rename (oldfile,newfile) >= 0) -+ try = -1; -+ } -+ -+ if (try > 0){ -+ sprintf(oldfile,"Unable to write flags to disk: %s", -+ errno == ENOENT ? "message is gone!" : strerror (errno)); -+ mm_log(oldfile,ERROR); -+ LOCAL->dirty = 1; -+ return; -+ } -+ maildir_free_file_only ((void **) &elt->maildirp); -+ MDFILE(elt) = cpystr (fn); -+ } -+ } -+ -+ void maildir_expunge (MAILSTREAM *stream) -+ { -+ MESSAGECACHE *elt; -+ unsigned long i; -+ unsigned long n = 0; -+ unsigned long nmsgs = stream->nmsgs; -+ unsigned long recent = stream->recent; -+ char tmp[MAILTMPLEN]; -+ -+ mm_critical (stream); /* go critical */ -+ for (i = 1; i <= stream->nmsgs;) -+ if ((elt = mail_elt (stream,i))->deleted){ -+ sprintf (tmp,"%s/%s",LOCAL->curdir, MDFILE(elt)); -+ if (unlink (tmp)) {/* try to delete the message */ -+ sprintf (tmp,"Expunge of message %ld failed, aborted: %s",i, -+ strerror (errno)); -+ if (!stream->silent) -+ mm_log (tmp,WARN); -+ break; -+ } -+ /* free the cached filename */ -+ if (elt->maildirp) -+ maildir_free_file ((void **) &elt->maildirp); -+ -+ if (elt->recent) --recent;/* if recent, note one less recent message */ -+ mail_expunged (stream,i); /* notify upper levels */ -+ n++; /* count up one more expunged message */ -+ } -+ else i++; -+ if (n) { /* output the news if any expunged */ -+ sprintf (tmp,"Expunged %ld messages",n); -+ if (!stream->silent) -+ mm_log (tmp,(long) NIL); -+ } -+ else -+ if (!stream->silent) -+ mm_log ("No messages deleted, so no update needed",(long) NIL); -+ mm_nocritical (stream); /* release critical */ -+ /* notify upper level of new mailbox size */ -+ mail_exists (stream,stream->nmsgs); -+ mail_recent (stream,recent); -+ } -+ -+ long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options) -+ { -+ STRING st; -+ MESSAGECACHE *elt; -+ unsigned long len; -+ int fd; -+ long i, length; -+ struct stat sbuf; -+ char tmp[MAILTMPLEN], flags[MAILTMPLEN], path[MAILTMPLEN], *s, *b; -+ /* copy the messages */ -+ if ((options & CP_UID) ? mail_uid_sequence (stream, sequence) : -+ mail_sequence (stream,sequence)) -+ for (i = 1; i <= stream->nmsgs; i++) -+ if ((elt = mail_elt (stream,i))->sequence){ -+ sprintf (path,"%s/%s",LOCAL->curdir, MDFILE(elt)); -+ if (((fd = open (path,O_RDONLY,NIL)) < 0) -+ ||((!elt->rfc822_size && -+ ((stat(path, &sbuf) < 0) || !S_ISREG (sbuf.st_mode))))) -+ return NIL; -+ if(!elt->rfc822_size) -+ MDSIZE(elt) = sbuf.st_size; -+ s = (char *) fs_get(MDSIZE(elt) + 1); -+ read (fd,s,MDSIZE(elt)); -+ s[MDSIZE(elt)] = '\0'; -+ close (fd); -+ len = strcrlfcpy (&LOCAL->buf,&LOCAL->buflen, s, MDSIZE(elt)); -+ INIT (&st,mail_string, LOCAL->buf, len); -+ elt->rfc822_size = len; -+ fs_give ((void **)&s); -+ -+ flags[0] = flags[1] = '\0'; -+ if (elt->seen) strcat (flags," \\Seen"); -+ if (elt->draft) strcat (flags," \\Draft"); -+ if (elt->deleted) strcat (flags," \\Deleted"); -+ if (elt->flagged) strcat (flags," \\Flagged"); -+ if (elt->answered) strcat (flags," \\Answered"); -+ flags[0] = '('; /* open list */ -+ strcat (flags,")"); /* close list */ -+ mail_date (tmp,elt); /* generate internal date */ -+ if (!mail_append_full (NIL,mailbox,flags,tmp,&st)) -+ return NIL; -+ if (options & CP_MOVE) elt->deleted = T; -+ } -+ return T; /* return success */ -+ } -+ -+ long maildir_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data) -+ { -+ int fd; -+ STRING *message; -+ char c,*s, *flags, *date; -+ char tmp[MAILTMPLEN],file[MAILTMPLEN],path1[MAILTMPLEN],path2[MAILTMPLEN]; -+ MESSAGECACHE elt; -+ long i; -+ long size = 0; -+ long ret = LONGT; -+ unsigned long uf; -+ long f; -+ static unsigned int transact = 0; -+ -+ if (!maildir_valid(mailbox)) { -+ sprintf (tmp,"Not a valid Maildir mailbox: %s",mailbox); -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ -+ if (!*mdlocaldomain) -+ md_domain_name(); /* get domain name for maildir files in mdlocaldomain now! */ -+ -+ if (!(*af) (stream,data,&flags,&date,&message)) return NIL; -+ -+ mm_critical (stream); /* go critical */ -+ do { -+ if (!SIZE (message)) { /* guard against zero-length */ -+ mm_log ("Append of zero-length message",ERROR); -+ ret = NIL; -+ break; -+ } -+ if (date && !mail_parse_date(&elt,date)){ -+ sprintf (tmp,"Bad date in append: %.80s",date); -+ mm_log (tmp,ERROR); -+ ret = NIL; -+ break; -+ } -+ f = mail_parse_flags (stream,flags,&uf); -+ /* build file name we will use */ -+ sprintf (file,"%u.%d_%09u.%s%s%s%s%s%s", -+ time (0),getpid (),transact++,mdlocaldomain, f ? MDSEP(2) : "", -+ MDFLAG(Draft, f&fDRAFT), MDFLAG(Flagged, f&fFLAGGED), -+ MDFLAG(Replied, f&fANSWERED), MDFLAG(Seen, f&fSEEN)); -+ /* build tmp file name */ -+ if (maildir_file_path(mailbox, tmp)) -+ MSGPATH(path1, tmp, file, Tmp); -+ -+ if ((fd = open (path1,O_WRONLY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE)) < 0) { -+ sprintf (tmp,"Can't open append mailbox: %s",strerror (errno)); -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ for (size = 0,i = SIZE (message),s = (char *) fs_get (i + 1); i; --i) -+ if ((c = SNX (message)) != '\015') s[size++] = c; -+ if ((write (fd,s,size) < 0) || fsync (fd)) { -+ unlink (path1); /* delete message */ -+ sprintf (tmp,"Message append failed: %s",strerror (errno)); -+ mm_log (tmp,ERROR); -+ ret = NIL; -+ } -+ fs_give ((void **) &s); /* flush the buffer */ -+ close (fd); /* close the file */ -+ /* build final filename to use */ -+ if (maildir_file_path(mailbox, tmp)) -+ MSGPATH(path2, tmp, file, New); -+ if (link (path1,path2) < 0) { -+ sprintf (tmp,"Message append failed: %s",strerror (errno)); -+ mm_log (tmp,ERROR); -+ ret = NIL; -+ } -+ unlink (path1); -+ -+ if (ret) -+ if (!(*af) (stream,data,&flags,&date,&message)) ret = NIL; -+ -+ } while (ret && message); /* write the data */ -+ -+ mm_nocritical (stream); /* release critical */ -+ return ret; -+ } -+ -+ long maildir_delete (MAILSTREAM *stream,char *mailbox) -+ { -+ DIR *dirp; -+ struct direct *d; -+ int i, remove_dir = 0, mddir = 0, rv, error = 0; -+ char tmp[MAILTMPLEN],tmp2[MAILTMPLEN], realname[MAILTMPLEN]; -+ struct stat sbuf; -+ char *mdpath = maildir_parameters(GET_INBOXPATH,NIL); -+ int courier = IS_COURIER(mailbox); -+ -+ if (mailbox[strlen(mailbox) - 1] == MDSEPARATOR(courier)){ -+ remove_dir++; -+ mailbox[strlen(mailbox) -1] = '\0'; -+ } -+ -+ if (!maildir_valid(mailbox)){ -+ maildir_file_path(mailbox, tmp); -+ if (stat(tmp, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode)){ -+ sprintf(tmp,"Can not remove %s", mailbox); -+ error++; -+ } -+ } -+ -+ if (!error && remove_dir && !maildir_dir_is_empty(mailbox)){ -+ sprintf(tmp,"Can not remove directory %s/: directory not empty", mailbox); -+ error++; -+ } -+ -+ if(error){ -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ -+ maildir_close(stream,0); /* even if stream was NULL */ -+ -+ maildir_file_path(mailbox, realname); -+ -+ if (remove_dir){ -+ sprintf(tmp,"%s/%s", realname, MDDIR); -+ if ((rv = stat (tmp,&sbuf)) == 0 && S_ISREG(sbuf.st_mode)) -+ rv = unlink(tmp); -+ else if (errno == ENOENT) -+ rv = 0; -+ if (rv != 0){ -+ sprintf(tmp,"Can not remove %s/%s: %s", tmp2, MDDIR, strerror(errno)); -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ if (!maildir_valid(realname) && rmdir(realname) != 0){ -+ sprintf(tmp,"Can not remove %s/: %s", mailbox, strerror(errno)); -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ return T; -+ } -+ /* else remove just the folder. Remove all hidden files, except MDDIR */ -+ for (i = Cur; i != EndDir; i++){ -+ MDFLD(tmp, realname, i); -+ -+ if (!(dirp = opendir (tmp))){ -+ sprintf(tmp,"Can not read %s/: %s", mailbox, strerror(errno)); -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ -+ while (d = readdir(dirp)){ -+ if (strcmp(d->d_name, ".") && strcmp(d->d_name,"..")){ -+ sprintf(tmp2,"%s/%s", tmp, d->d_name); -+ if (unlink(tmp2) != 0){ -+ sprintf(tmp2,"Can not remove %s: %s", mailbox, strerror(errno)); -+ mm_log (tmp2,ERROR); -+ return NIL; -+ } -+ } -+ } -+ closedir(dirp); -+ if (rmdir(tmp) != 0){ -+ sprintf(tmp,"Can not remove %s: %s", mailbox, strerror(errno)); -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ } -+ /* -+ * ok we have removed all subdirectories of the folder mailbox, Remove the -+ * hidden files. -+ */ -+ -+ if (!(dirp = opendir (realname))){ -+ sprintf(tmp,"Can not read %s/: %s", realname, strerror(errno)); -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ -+ while (d = readdir(dirp)){ -+ if (strcmp(d->d_name, ".") && strcmp(d->d_name,"..") -+ && !strcmp(d->d_name, MDDIR)){ -+ sprintf(tmp,"%s/%s", realname, d->d_name); -+ mddir++; -+ if (unlink(tmp) != 0) -+ error++; -+ } -+ } -+ closedir(dirp); -+ if (error || -+ (maildir_dir_is_empty(mailbox) && mddir == 0 && rmdir(realname) < 0)){ -+ sprintf(tmp,"Can not remove folder %s: %s", mailbox, strerror(errno)); -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ return T; -+ } -+ -+ long maildir_rename (MAILSTREAM *stream, char *old, char *new) -+ { -+ struct direct **names = NIL; -+ struct stat sbuf; -+ char pathname[MAILTMPLEN], dir[MAILTMPLEN], curdir[MAILTMPLEN]; -+ char tmp[MAILTMPLEN],tmpnew[MAILTMPLEN], realold[MAILTMPLEN]; -+ char realnew[MAILTMPLEN],realpat[MAILTMPLEN], realname[MAILTMPLEN]; -+ char *pat, *endold, c; -+ char *maildirpath = maildir_parameters(GET_INBOXPATH, NIL); -+ int courier = IS_COURIER(old) && IS_COURIER(new); -+ int scand, i, j, rv = T; -+ unsigned long ndir; -+ COURIER_S *cdir; -+ -+ if((IS_COURIER(old) || IS_COURIER(new)) && !courier){ -+ sprintf (tmp,"Can't rename mailbox %s to %s",old, new); -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ -+ if (!maildir_valid(old)){ -+ sprintf (tmp,"Can't rename mailbox %s: folder not in maildir format",old); -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ maildir_file_path(old, realold); -+ if (!maildir_valid_name(new) && new[0] == '#'){ -+ sprintf (tmp,"Can't rename mailbox %s: folder not in maildir format",new); -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ maildir_file_path(new, realnew); -+ if (access(tmpnew,F_OK) == 0){ /* new mailbox name must not exist */ -+ sprintf (tmp,"Can't rename to mailbox %s: destination already exists",new); -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ -+ if(!courier){ -+ if (rename (realold,realnew)){ /* try to rename the directory */ -+ sprintf (tmp,"Can't rename mailbox %s to %s: %s",old, new, -+ strerror(errno)); -+ mm_log (tmp,ERROR); -+ return NIL; -+ } -+ return T; /* return success */ -+ } -+ -+ cdir = courier_list_dir(old); -+ for (i = 0; cdir && i < cdir->total; i++){ -+ if(strstr(cdir->data[i]->name, old)){ -+ sprintf(tmp,"%s%s", new, cdir->data[i]->name+strlen(old)); -+ maildir_file_path(cdir->data[i]->name, realold); -+ maildir_file_path(tmp, realnew); -+ if (rename (realold,realnew)){ -+ sprintf (tmp,"Can't rename mailbox %s to %s: %s",old, new, -+ strerror(errno)); -+ mm_log (tmp,ERROR); -+ rv = NIL; -+ } -+ } -+ } -+ courier_free_cdir(&cdir); -+ return rv; -+ } -+ -+ long maildir_sub (MAILSTREAM *stream,char *mailbox) -+ { -+ return sm_subscribe (mailbox); -+ } -+ -+ long maildir_unsub (MAILSTREAM *stream,char *mailbox) -+ { -+ return sm_unsubscribe (mailbox); -+ } -+ -+ void maildir_lsub (MAILSTREAM *stream,char *ref,char *pat) -+ { -+ void *sdb = NIL; -+ char *s, test[MAILTMPLEN]; -+ /* get canonical form of name */ -+ if (maildir_canonicalize (test,ref,pat) && (s = sm_read (&sdb))) { -+ do if (pmatch_full (s,test,'/')) mm_lsub (stream,'/',s,NIL); -+ while (s = sm_read (&sdb)); /* until no more subscriptions */ -+ } -+ } -+ -+ long maildir_canonicalize (char *pattern,char *ref,char *pat) -+ { -+ if (ref && *ref) { /* have a reference */ -+ strcpy (pattern,ref); /* copy reference to pattern */ -+ /* # overrides mailbox field in reference */ -+ if (*pat == '#') strcpy (pattern,pat); -+ /* pattern starts, reference ends, with / */ -+ else if ((*pat == '/') && (pattern[strlen (pattern) - 1] == '/')) -+ strcat (pattern,pat + 1); /* append, omitting one of the period */ -+ -+ else strcat (pattern,pat); /* anything else is just appended */ -+ } -+ else strcpy (pattern,pat); /* just have basic name */ -+ return (maildir_valid_name(pattern)); -+ } -+ -+ void maildir_list_work (MAILSTREAM *stream,char *dir,char *pat,long level) -+ { -+ DIR *dp; -+ struct direct *d; -+ struct stat sbuf; -+ char *cp,*np, curdir[MAILTMPLEN],name[MAILTMPLEN], tmp[MAILTMPLEN]; -+ int i; -+ char *maildirpath = maildir_parameters(GET_INBOXPATH, NIL); -+ -+ sprintf(curdir,"%s/%s/", myhomedir(), dir ? dir : -+ (maildirpath ? maildirpath : "Maildir")); -+ if (dp = opendir (curdir)){ -+ if (dir) sprintf (name,"%s%s/",MDPREFIX(CCLIENT),dir); -+ else strcpy (name,MDPREFIX(CCLIENT)); -+ -+ if (level == 0 && name && pmatch_full (name, pat, '/')) -+ mm_list (stream,'/', name, LATT_NOSELECT); -+ -+ while (d = readdir (dp)) -+ if(strcmp(d->d_name, ".") && strcmp(d->d_name,"..") -+ && strcmp(d->d_name, MDNAME(Cur)) -+ && strcmp(d->d_name, MDNAME(Tmp)) -+ && strcmp(d->d_name, MDNAME(New))){ -+ -+ if (dir) sprintf (tmp,"%s%s", name,d->d_name); -+ else strcpy(tmp, d->d_name); -+ -+ if(pmatch_full (tmp, pat,'/')){ -+ sprintf(tmp,"%s/%s/%s", myhomedir(), dir ? dir : -+ (maildirpath ? maildirpath : "Maildir"), d->d_name); -+ if(stat (tmp,&sbuf) == 0 -+ && ((sbuf.st_mode & S_IFMT) == S_IFDIR)){ -+ if (dir) sprintf (tmp,"%s%s", name,d->d_name); -+ else strcpy(tmp, d->d_name); -+ i = maildir_valid(tmp) -+ ? (maildir_contains_folder(dir, d->d_name) -+ ? LATT_HASCHILDREN -+ : (maildir_is_dir(dir, d->d_name) -+ ? LATT_HASNOCHILDREN : LATT_NOINFERIORS)) -+ : LATT_NOSELECT; -+ i += maildir_any_new_msgs(tmp) -+ ? LATT_MARKED : LATT_UNMARKED; -+ mm_list (stream,'/',tmp, i); -+ strcat (tmp, "/"); -+ if(dmatch (tmp, pat,'/') && -+ (level < (long) mail_parameters (NIL,GET_LISTMAXLEVEL,NIL))){ -+ sprintf(tmp,"%s/%s",dir,d->d_name); -+ maildir_list_work (stream,tmp,pat,level+1); -+ } -+ } -+ } -+ } -+ } -+ closedir (dp); -+ } -+ -+ void courier_list_work (MAILSTREAM *stream, char *dir, char *pat, long level) -+ { -+ unsigned long ndir; -+ struct direct **names = NIL; -+ struct stat sbuf; -+ char c, d, curdir[MAILTMPLEN],name[MAILTMPLEN], tmp[MAILTMPLEN]; -+ char realname[MAILTMPLEN], realpat[MAILTMPLEN] = {'\0'}, pathname[MAILTMPLEN]; -+ int i, j, scand; -+ long style = (long) maildir_parameters(GET_COURIERSTYLE, NIL); -+ char *maildirpath = maildir_parameters(GET_INBOXPATH, NIL); -+ COURIER_S *cdir; -+ -+ j = strlen(pat) - 1; -+ maildir_file_path(pat, realpat); -+ c = pat[j]; -+ pat[j] = '\0'; -+ realname[0] = '\0'; -+ if(dir) -+ maildir_file_path(dir, realname); -+ sprintf(curdir,"%s%s%s/%s", dir ? "" : myhomedir(), dir ? "" : "/", -+ dir ? realname : (maildirpath ? maildirpath : "Maildir"), -+ dir ? "" : "."); -+ -+ sprintf(tmp, "%s%s/.", MDPREFIX(COURIER), dir ? dir : -+ (maildirpath ? maildirpath : "Maildir")); -+ if (level == 0 && tmp && pmatch_full (tmp, realpat, '.')) -+ mm_list (stream,'.', tmp, LATT_NOSELECT); -+ -+ cdir = courier_list_dir(pat); -+ pat[j] = c; -+ for (i = 0; cdir && i < cdir->total; i++){ -+ if(pmatch_full (cdir->data[i]->name, pat, '.')){ -+ sprintf(tmp, "%s.", cdir->data[i]->name); -+ if(maildir_valid(cdir->data[i]->name)){ -+ if(courier_search_list(cdir->data, tmp, 0, cdir->total - 1)) -+ cdir->data[i]->attribute = LATT_HASCHILDREN; -+ else -+ cdir->data[i]->attribute = style == COURIER -+ ? LATT_HASNOCHILDREN : LATT_NOINFERIORS; -+ } -+ else -+ cdir->data[i]->attribute = LATT_NOSELECT; -+ cdir->data[i]->attribute += maildir_any_new_msgs(cdir->data[i]->name) -+ ? LATT_MARKED : LATT_UNMARKED; -+ mm_list (stream,'.',cdir->data[i]->name, cdir->data[i]->attribute); -+ } -+ } -+ courier_free_cdir(&cdir); -+ } -+ -+ int -+ same_maildir_file(char *name1, char *name2) -+ { -+ char tmp1[MAILTMPLEN], tmp2[MAILTMPLEN]; -+ char *s; -+ -+ strcpy(tmp1, name1 ? name1 : ""); -+ strcpy(tmp2, name2 ? name2 : ""); -+ if (s = strchr(tmp1, FLAGSEP)) -+ *s = '\0'; -+ if (s = strchr(tmp1, SIZESEP)) -+ *s = '\0'; -+ if (s = strchr(tmp2, FLAGSEP)) -+ *s = '\0'; -+ if (s = strchr(tmp2, SIZESEP)) -+ *s = '\0'; -+ -+ return !strcmp(tmp1, tmp2); -+ } -+ -+ -+ int comp_maildir_file(char *name1, char *name2) -+ { -+ unsigned long t1, t2; -+ int i; -+ -+ if (!(name1 && *name1)) -+ return name2 && *name2 ? (*name2 == FLAGSEP ? 0 : -1) : 0; -+ -+ if (!(name2 && *name2)) -+ return name1 && *name1 ? (*name1 == FLAGSEP ? 0 : 1) : 0; -+ -+ if(!strcmp(name1,name2)) -+ return 0; -+ -+ t1 = strtoul(name1, NULL, 10); -+ t2 = strtoul(name2, NULL, 10); -+ -+ if (t1 < t2) -+ return -1; -+ -+ if (t1 > t2) -+ return 1; -+ -+ i = strchr(name1,'.') - name1 + 1; -+ return (strcmp (name1 + i, name2 + i)); -+ } -+ -+ void -+ maildir_getflag(char *name, int *d, int *f, int *r ,int *s, int *t) -+ { -+ char tmp[MAILTMPLEN], *b; -+ int offset = 0; -+ -+ if(d && f && r && s && t) -+ *d = *f = *r = *s = *t = 0; -+ else -+ return; /* can not call this function with null arguments */ -+ -+ strcpy(tmp,name); -+ while (b = strchr(tmp+offset, FLAGSEP)){ -+ char flag,last; -+ int i,k; -+ if (!++b) break; -+ switch (*b){ -+ case '1': -+ case '2': -+ case '3': flag = *b; b += 2; -+ for (k = 0; b[k] && b[k] != FLAGSEP && b[k] != ','; k++); -+ last = b[k]; -+ b[k] = '\0'; -+ if (flag == '2' || flag == '3'){ -+ *d = strchr (b, MDFLAGC(Draft)) ? T : NIL; -+ *f = strchr (b, MDFLAGC(Flagged)) ? T : NIL; -+ *r = strchr (b, MDFLAGC(Replied)) ? T : NIL; -+ *s = strchr (b, MDFLAGC(Seen)) ? T : NIL; -+ *t = strchr (b, MDFLAGC(Trashed)) ? T : NIL; -+ } -+ b[k] = last; -+ b += k; -+ for (; tmp[offset] && tmp[offset] != FLAGSEP; offset++); -+ offset++; -+ break; -+ default: break; /* Should we crash?... Nahhh */ -+ } -+ } -+ } -+ -+ int -+ maildir_message_in_list(char *msgname, struct direct **names, -+ unsigned long bottom, unsigned long top, unsigned long *pos) -+ { -+ unsigned long middle = (bottom + top)/2; -+ int test; -+ -+ if (!msgname) -+ return NIL; -+ -+ if (pos) *pos = middle; -+ -+ if (same_maildir_file(msgname, names[middle]->d_name)) -+ return T; -+ -+ if (middle == bottom){ /* 0 <= 0 < 1 */ -+ int rv = NIL; -+ if (same_maildir_file(msgname, names[middle]->d_name)){ -+ rv = T; -+ if (pos) *pos = middle; -+ } -+ else -+ if (same_maildir_file(msgname, names[top]->d_name)){ -+ rv = T; -+ if (pos) *pos = top; -+ } -+ return rv; -+ } -+ -+ test = comp_maildir_file(msgname, names[middle]->d_name); -+ -+ if (top <= bottom) -+ return test ? NIL : T; -+ -+ if (test < 0 ) /* bottom < msgname < middle */ -+ return maildir_message_in_list(msgname, names, bottom, middle, pos); -+ else if (test > 0) /* middle < msgname < top */ -+ return maildir_message_in_list(msgname, names, middle, top, pos); -+ else return T; -+ } -+ -+ void -+ maildir_abort(MAILSTREAM *stream) -+ { -+ if (LOCAL){ -+ if (LOCAL->dir) fs_give ((void **) &LOCAL->dir); -+ if (LOCAL->curdir) fs_give ((void **) &LOCAL->curdir); -+ if (LOCAL->buf) fs_give ((void **) &LOCAL->buf); -+ fs_give ((void **) &stream->local); -+ } -+ if (mdfpath) fs_give((void **)&mdfpath); -+ stream->dtb = NIL; -+ } -+ -+ int -+ maildir_contains_folder(char *dirname, char *name) -+ { -+ char tmp[MAILTMPLEN], tmp2[MAILTMPLEN]; -+ int rv = 0; -+ DIR *dir; -+ struct direct *d; -+ struct stat sbuf; -+ char *maildirpath = maildir_parameters(GET_INBOXPATH, NIL); -+ -+ sprintf(tmp2,"%s/%s/%s", myhomedir(), dirname ? dirname -+ : (maildirpath ? maildirpath : "Maildir"), name); -+ -+ if (!(dir = opendir (tmp2))) -+ return NIL; -+ -+ while (d = readdir(dir)){ -+ if (strcmp(d->d_name, ".") && strcmp(d->d_name,"..") -+ && strcmp(d->d_name, MDNAME(Cur)) -+ && strcmp(d->d_name, MDNAME(Tmp)) -+ && strcmp(d->d_name, MDNAME(New))){ -+ -+ sprintf(tmp,"%s/%s", tmp2, d->d_name); -+ if(maildir_valid(tmp)){ -+ rv++; -+ break; -+ } -+ } -+ } -+ closedir(dir); -+ return rv; -+ } -+ -+ int -+ maildir_is_dir(char *dirname, char *name) -+ { -+ char tmp[MAILTMPLEN]; -+ struct stat sbuf; -+ char *maildirpath = maildir_parameters(GET_INBOXPATH, NIL); -+ -+ sprintf(tmp,"%s/%s/%s/%s", myhomedir(), dirname ? dirname -+ : (maildirpath ? maildirpath : "Maildir"), name, MDDIR); -+ -+ return (stat(tmp, &sbuf) == 0 && S_ISREG (sbuf.st_mode)) ? 1 : 0; -+ } -+ -+ int -+ maildir_dir_is_empty(char *mailbox) -+ { -+ char tmp[MAILTMPLEN], tmp2[MAILTMPLEN]; -+ int rv = 1; -+ DIR *dir; -+ struct direct *d; -+ struct stat sbuf; -+ -+ maildir_file_path(mailbox, tmp2); -+ -+ if (!(dir = opendir (tmp2))) -+ return rv; -+ -+ while (d = readdir(dir)){ -+ sprintf(tmp,"%s/%s", tmp2, d->d_name); -+ if (strcmp(d->d_name, ".") -+ && strcmp(d->d_name,"..") -+ && strcmp(d->d_name, MDNAME(Cur)) -+ && strcmp(d->d_name, MDNAME(Tmp)) -+ && strcmp(d->d_name, MDNAME(New)) -+ && strcmp(d->d_name, MDDIR) -+ && strcmp(d->d_name, MDUIDVALIDITY) -+ && !(d->d_name[0] == '.' -+ && stat (tmp,&sbuf) == 0 -+ && S_ISREG(sbuf.st_mode))){ -+ rv = 0; -+ break; -+ } -+ } -+ closedir(dir); -+ return rv; -+ } -+ -+ void -+ maildir_get_file (MAILDIRFILE **mdfile) -+ { -+ MAILDIRFILE *md; -+ -+ md = (MAILDIRFILE *) fs_get(sizeof(MAILDIRFILE)); -+ memset(md, 0, sizeof(MAILDIRFILE)); -+ *mdfile = md; -+ } -+ -+ void -+ maildir_free_file (void **mdfile) -+ { -+ MAILDIRFILE *md = (mdfile && *mdfile) ? (MAILDIRFILE *) *mdfile : NULL; -+ -+ if (md){ -+ if (md->name) fs_give((void **)&md->name); -+ fs_give((void **)&md); -+ } -+ } -+ -+ void -+ maildir_free_file_only (void **mdfile) -+ { -+ MAILDIRFILE *md = (mdfile && *mdfile) ? (MAILDIRFILE *) *mdfile : NULL; -+ -+ if (md && md->name) -+ fs_give((void **)&md->name); -+ } -+ -+ int -+ maildir_any_new_msgs(char *mailbox) -+ { -+ char tmp[MAILTMPLEN]; -+ int rv = NIL; -+ DIR *dir; -+ struct direct *d; -+ struct stat sbuf; -+ -+ MDFLD(tmp, mailbox, New); -+ -+ if (!(dir = opendir (tmp))) -+ return rv; -+ -+ while (d = readdir(dir)){ -+ if (d->d_name[0] == '.') -+ continue; -+ rv = T; -+ break; -+ } -+ closedir(dir); -+ return rv; -+ } -+ -+ -+ void -+ maildir_get_date(MAILSTREAM *stream, unsigned long msgno, DirNamesType dirtype) -+ { -+ MESSAGECACHE *elt; -+ struct tm *tm; -+ unsigned long t1; -+ -+ elt = mail_elt (stream,msgno); -+ if ((t1 = strtoul(MDFILE(elt), NULL, 10)) > 0){ -+ tm = gmtime (&t1); -+ elt->day = tm->tm_mday; elt->month = tm->tm_mon + 1; -+ elt->year = tm->tm_year + 1900 - BASEYEAR; -+ elt->hours = tm->tm_hour; elt->minutes = tm->tm_min; -+ elt->seconds = tm->tm_sec; -+ elt->zhours = 0; elt->zminutes = 0; -+ } -+ } -+ -+ /* Support for Courier Style directories -+ -+ When this code is complete there will be two types of support, which -+ will be configurable. The problem is the following: In Courier style -+ folder structure, a "folder" may have a subfolder called -+ "folder.subfolder", which is not natural in the file system in the -+ sense that I can not stat for "folder.subfolder" wihtout knowing what -+ "subfolder" is. It needs to be guessed. Because of this I need to look -+ in the list of folders if there is a folder with a name -+ "folder.subfolder", before I can say if the folder is dual or not. One -+ can avoid this annoyance if one ignores the problem by declaring that -+ every folder is dual. I will however code as the default the more -+ complicated idea of scaning the containing directory each time it is -+ modified and search for subfolders, and list the entries it found. -+ */ -+ -+ int courier_dir_select (struct direct *name) -+ { -+ return name->d_name[0] == '.' && (strlen(name->d_name) > 2 -+ || (strlen(name->d_name) == 2 && name->d_name[1] != '.')); -+ } -+ -+ int courier_dir_sort (const void *d1, const void *d2) -+ { -+ const struct direct **e1, **e2; -+ -+ e1 = (const struct direct **)d1; -+ e2 = (const struct direct **)d2; -+ -+ return strcmp((char*)(*e1)->d_name, (char *)(*e2)->d_name); -+ } -+ -+ void courier_free_cdir (COURIER_S **cdir) -+ { -+ int i; -+ -+ if (!*cdir) -+ return; -+ -+ if ((*cdir)->path) fs_give((void **)&((*cdir)->path)); -+ for (i = 0; i < (*cdir)->total; i++) -+ if((*cdir)->data[i]->name) fs_give((void **)&((*cdir)->data[i]->name)); -+ fs_give((void **)&((*cdir)->data)); -+ fs_give((void **)&(*cdir)); -+ } -+ -+ COURIER_S *courier_get_cdir (int total) -+ { -+ COURIER_S *cdir; -+ -+ cdir = (COURIER_S *)fs_get(sizeof(COURIER_S)); -+ memset(cdir, 0, sizeof(COURIER_S)); -+ cdir->data = (COURIERLOCAL **) fs_get(total*sizeof(COURIERLOCAL *)); -+ cdir->total = total; -+ return cdir; -+ } -+ -+ int courier_search_list(COURIERLOCAL **data, char *name, int first, int last) -+ { -+ int try = (first + last)/2; -+ -+ if(!strstr(data[try]->name, name)){ -+ if(first == try) /* first == last || first + 1 == last */ -+ return strstr(data[last]->name, name) ? 1 : 0; -+ if(strcmp(data[try]->name, name) < 0) /*data[try] < name < data[end] */ -+ return courier_search_list(data, name, try, last); -+ else /* data[begin] < name < data[try] */ -+ return courier_search_list(data, name, first, try); -+ } -+ return 1; -+ } -+ -+ /* Lists all directories that are subdirectories of a given directory */ -+ -+ COURIER_S *courier_list_dir(char *curdir) -+ { -+ struct direct **names = NIL; -+ struct stat sbuf; -+ unsigned long ndir; -+ COURIER_S *cdir; -+ char tmp[MAILTMPLEN], tmp2[MAILTMPLEN], pathname[MAILTMPLEN], -+ realname[MAILTMPLEN]; -+ char *maildirpath = maildir_parameters(GET_INBOXPATH, NIL); -+ int i, j, scand; -+ -+ /* There are two cases, either curdir is -+ #mc/INBOX. #mc/INBOX.foo -+ or -+ #mc/Maildir/. #mc/Maildir/.foo -+ */ -+ strcpy(tmp,curdir + 4); -+ if(!strncmp(ucase(tmp), "INBOX", 5)) -+ strcpy(tmp, "#mc/INBOX."); -+ else{ -+ strcpy(tmp, curdir); -+ for (i = strlen(tmp) - 1; tmp[i] && tmp[i] != '/'; i--); -+ tmp[i+2] = '\0'; /* keep the last "." intact */ -+ } -+ maildir_file_path(tmp, realname); -+ maildir_scandir (realname, &names, &ndir, &scand, COURIER); -+ -+ if (scand > 0){ -+ cdir = courier_get_cdir(ndir); -+ cdir->path = cpystr(realname); -+ for(i = 0, j = 0; i < ndir; i++){ -+ sprintf(tmp2,"%s%s", tmp, names[i]->d_name+1); -+ sprintf(pathname,"%s%s", realname, names[i]->d_name); -+ if(stat(pathname, &sbuf) == 0 && S_ISDIR(sbuf.st_mode)){ -+ cdir->data[j] = (COURIERLOCAL *) fs_get(sizeof(COURIERLOCAL)); -+ cdir->data[j++]->name = cpystr(tmp2); -+ } -+ fs_give((void **)&names[i]); -+ } -+ if(names) -+ fs_give((void **) &names); -+ cdir->total = j; -+ } -+ return cdir; -+ } -diff -rc pine4.63/imap/src/osdep/unix/maildir.h pine4.63.I.USE/imap/src/osdep/unix/maildir.h -*** pine4.63/imap/src/osdep/unix/maildir.h Thu May 19 19:59:15 2005 ---- pine4.63.I.USE/imap/src/osdep/unix/maildir.h Thu May 19 19:57:24 2005 -*************** -*** 0 **** ---- 1,185 ---- -+ /* -+ * A few definitions that try to make this module portable to other -+ * platforms (e.g. Cygwin). This module is based on the information from -+ * http://cr.yp.to/proto/maildir.html -+ */ -+ -+ /* First we deal with the separator character */ -+ #ifndef FLAGSEP -+ #define FLAGSEP ':' -+ #endif -+ #define SIZESEP ',' -+ -+ #define MDUIDVALIDITY ".uidvalidity" /* support for old maildirs */ -+ #define MDDIR ".mdir" /* this folder is a directory */ -+ -+ const char sep1[] = {FLAGSEP, '1', ',', '\0'}; /* experimental semantics*/ -+ const char sep2[] = {FLAGSEP, '2', ',', '\0'}; /* Flags Information */ -+ const char sep3[] = {FLAGSEP, '3', ',', '\0'}; /* Grrrr.... */ -+ -+ const char *sep[] = { sep1, sep2, sep3, NULL}; -+ -+ #define MDSEP(i) sep[((i) - 1)] -+ -+ /* Now we deal with flags. Woohoo! */ -+ typedef enum {Draft, Flagged, Passed, Replied, Seen, Trashed, -+ EmptyFlag, EndFlags} MdFlagNamesType; -+ const int mdimapflags[] = {Draft, Flagged, Replied, Seen, Trashed, EmptyFlag, EndFlags}; -+ const int mdkwdflags[] = {Passed, EmptyFlag, EndFlags}; -+ -+ /* this array lists the codes for mdflgnms (maildir flag names) above */ -+ const char *mdflags[] = { "D", "F", "P", "R", "S", "T", "", NULL}; -+ /* and as characters too */ -+ const char cmdflags[] = { 'D', 'F', 'P', 'R', 'S', 'T', '0', '\0'}; -+ -+ /* MDFLAG(Seen, elt->seen) */ -+ #define MDFLAG(i,j) mdflags[j ? (i) : EmptyFlag] -+ /* MDFLAGC(Seen) */ -+ #define MDFLAGC(i) cmdflags[(i)] -+ -+ /* Now we deal with the directory structure */ -+ typedef enum {Cur, Tmp, New, EndDir} DirNamesType; -+ char *mdstruct[] = {"cur", "tmp", "new", NULL}; -+ #define MDNAME(i) mdstruct[(i)] -+ #define MDFLD(tmp, dir, i) sprintf((tmp),"%s/%s", (dir), mdstruct[(i)]) -+ #define MSGPATH(tmp, dir, msg,i) sprintf((tmp),"%s/%s/%s", (dir), mdstruct[(i)],(msg)) -+ -+ /* Support of Courier Structure */ -+ #define CCLIENT 0 -+ #define COURIER 1 -+ #define IS_CCLIENT(t) \ -+ (((t) && (t)[0] == '#' && ((t)[1] == 'm' || (t)[1] == 'M')\ -+ && ((t)[2] == 'd' || (t)[2] == 'D')\ -+ && (t)[3] == '/' && (t)[4] != '\0') ? 1 : 0) -+ -+ #define IS_COURIER(t) \ -+ (((t) && (t)[0] == '#' && ((t)[1] == 'm' || (t)[1] == 'M')\ -+ && ((t)[2] == 'c' || (t)[2] == 'C')\ -+ && (t)[3] == '/' && (t)[4] != '\0') ? 1 : 0) -+ #define MDPREFIX(s) ((s) ? "#mc/" : "#md/") -+ #define MDSEPARATOR(s) ((s) ? '.' : '/') -+ -+ -+ /* Now we deal with messages filenames */ -+ char mdlocaldomain[MAILTMPLEN+1] = {'\0'}; -+ static char *mdfpath = NULL; -+ static char *myMdInboxDir = NIL;/* Location of the Maildir INBOX */ -+ static long CourierStyle = CCLIENT; -+ -+ #define CHUNK 16384 /* from unix.h */ -+ -+ typedef struct courier_local { -+ char *name; /* name of directory/folder */ -+ int attribute; /* attributes (children/marked/etc) */ -+ } COURIERLOCAL; -+ -+ typedef struct courier { -+ char *path; /* Path to collection */ -+ time_t scantime; /* time at which information was generated */ -+ int total; /* total number of elements in data */ -+ COURIERLOCAL **data; -+ } COURIER_S; -+ -+ /* In gdb this is the *(struct maildir_local *)stream->local structure */ -+ typedef struct maildir_local { -+ unsigned int dirty : 1; /* diskcopy needs updating */ -+ unsigned int courier : 1; /* It is Courier style file system */ -+ int fd; /* fd of open message */ -+ char *dir; /* mail directory name */ -+ char *curdir; /* mail directory name/cur */ -+ unsigned char *buf; /* temporary buffer */ -+ unsigned long buflen; /* current size of temporary buffer */ -+ time_t scantime; /* last time directory scanned */ -+ } MAILDIRLOCAL; -+ -+ /* Convenient access to local data */ -+ #define LOCAL ((MAILDIRLOCAL *) stream->local) -+ -+ typedef struct maildir_file_info { -+ char *name; /* name of the file */ -+ unsigned long pos; /* place in list where this file is listed */ -+ off_t size; /* size in bytes, on disk */ -+ time_t atime; /* last access time */ -+ time_t mtime; /* last modified time */ -+ time_t ctime; /* last changed time */ -+ } MAILDIRFILE; -+ -+ #define MDFILE(F) (((MAILDIRFILE *)((F)->maildirp))->name) -+ #define MDPOS(F) (((MAILDIRFILE *)((F)->maildirp))->pos) -+ #define MDSIZE(F) (((MAILDIRFILE *)((F)->maildirp))->size) -+ #define MDATIME(F) (((MAILDIRFILE *)((F)->maildirp))->atime) -+ #define MDMTIME(F) (((MAILDIRFILE *)((F)->maildirp))->mtime) -+ #define MDCTIME(F) (((MAILDIRFILE *)((F)->maildirp))->ctime) -+ -+ /* Function prototypes */ -+ -+ DRIVER *maildir_valid (char *name); -+ MAILSTREAM *maildir_open (MAILSTREAM *stream); -+ void maildir_close (MAILSTREAM *stream, long options); -+ long maildir_ping (MAILSTREAM *stream); -+ void maildir_check (MAILSTREAM *stream); -+ long maildir_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags); -+ char *maildir_header (MAILSTREAM *stream,unsigned long msgno, -+ unsigned long *length, long flags); -+ void maildir_list (MAILSTREAM *stream,char *ref,char *pat); -+ void *maildir_parameters (long function,void *value); -+ int maildir_create_folder (char *mailbox); -+ long maildir_create (MAILSTREAM *stream,char *mailbox); -+ void maildir_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt); /*check */ -+ void maildir_expunge (MAILSTREAM *stream); -+ long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options); -+ long maildir_append (MAILSTREAM *stream,char *mailbox, append_t af, void *data); -+ long maildir_delete (MAILSTREAM *stream,char *mailbox); -+ long maildir_rename (MAILSTREAM *stream,char *old,char *new); -+ long maildir_sub (MAILSTREAM *stream,char *mailbox); -+ long maildir_unsub (MAILSTREAM *stream,char *mailbox); -+ void maildir_lsub (MAILSTREAM *stream,char *ref,char *pat); -+ void courier_list (MAILSTREAM *stream,char *ref, char *pat); -+ -+ /* utility functions */ -+ void courier_realname (char *name, char *realname); -+ char *maildir_file (char *dst,char *name); -+ int maildir_select (struct direct *name); -+ int maildir_namesort (const void *d1, const void *d2); -+ int courier_dir_select (struct direct *name); -+ int courier_dir_sort (const void *d1, const void *d2); -+ long maildir_canonicalize (char *pattern,char *ref,char *pat); -+ void maildir_list_work (MAILSTREAM *stream,char *subdir,char *pat,long level); -+ void courier_list_work (MAILSTREAM *stream,char *subdir,char *pat,long level); -+ int maildir_file_path(char *name, char *tmp); -+ int maildir_valid_name (char *name); -+ int maildir_valid_dir (char *name); -+ int is_valid_maildir (char **name); -+ int maildir_message_exists(MAILSTREAM *stream,char *name, char *tmp); -+ void maildir_remove_root(char **name); -+ char *maildir_text_work (MAILSTREAM *stream,MESSAGECACHE *elt, unsigned long *length,long flags); -+ unsigned long maildir_parse_message(MAILSTREAM *stream, unsigned long msgno, -+ DirNamesType dirtype); -+ unsigned long maildir_scandir (char *name, struct direct ***flist, -+ unsigned long *nfiles, int *scand, int flag); -+ void maildir_parse_folder (MAILSTREAM *stream, int full); -+ void md_domain_name (void); -+ unsigned long maildir_parse_dir(MAILSTREAM *stream, unsigned long nmsgs, -+ DirNamesType dirtype, int full); -+ int same_maildir_file(char *name1, char *name2); -+ int comp_maildir_file(char *name1, char *name2); -+ int maildir_message_in_list(char *msgname, struct direct **names, -+ unsigned long bottom, unsigned long top, unsigned long *pos); -+ void maildir_getflag(char *name, int *d, int *f, int *r ,int *s, int *t); -+ int maildir_update_elt_maildirp(MAILSTREAM *stream, unsigned long msgno); -+ void maildir_abort (MAILSTREAM *stream); -+ int maildir_contains_folder(char *dirname, char *name); -+ int maildir_is_dir(char *dirname, char *name); -+ int maildir_dir_is_empty(char *mailbox); -+ int maildir_create_work (char *mailbox, int loop); -+ void maildir_get_file (MAILDIRFILE **mdfile); -+ void maildir_free_file (void **mdfile); -+ void maildir_free_file_only (void **mdfile); -+ int maildir_any_new_msgs(char *mailbox); -+ void maildir_get_date(MAILSTREAM *stream, unsigned long msgno, DirNamesType dirtype); -+ void maildir_fast (MAILSTREAM *stream,char *sequence,long flags); -+ -+ void courier_free_cdir (COURIER_S **cdir); -+ COURIER_S *courier_get_cdir (int total); -+ int courier_search_list(COURIERLOCAL **data, char *name, int first, int last); -+ COURIER_S *courier_list_dir(char *curdir); -diff -rc pine4.63/imap/src/osdep/unix/os_cyg.h pine4.63.I.USE/imap/src/osdep/unix/os_cyg.h -*** pine4.63/imap/src/osdep/unix/os_cyg.h Mon Apr 19 08:22:07 2004 ---- pine4.63.I.USE/imap/src/osdep/unix/os_cyg.h Thu May 19 19:57:24 2005 -*************** -*** 39,44 **** ---- 39,45 ---- - #define setpgrp setpgid - - #define SYSTEMUID 18 /* Cygwin returns this for SYSTEM */ -+ #define FLAGSEP ';' - #define geteuid Geteuid - uid_t Geteuid (void); - -diff -rc pine4.63/pico/basic.c pine4.63.I.USE/pico/basic.c -*** pine4.63/pico/basic.c Fri May 7 14:36:44 2004 ---- pine4.63.I.USE/pico/basic.c Thu May 19 19:57:33 2005 -*************** -*** 267,273 **** - int f, n; /* default Flag & Numeric argument */ - { - int quoted, qlen; -! char qstr[NLINE], qstr2[NLINE]; - - if (n < 0) /* the other way...*/ - return(gotoeop(f, -n)); ---- 267,273 ---- - int f, n; /* default Flag & Numeric argument */ - { - int quoted, qlen; -! char qstr[NLINE], qstr2[NLINE], ind_str[NLINE]; - - if (n < 0) /* the other way...*/ - return(gotoeop(f, -n)); -*************** -*** 279,284 **** ---- 279,295 ---- - curwp->w_dotp = lback(curwp->w_dotp); - curwp->w_doto = 0; - } -+ -+ if (indent_match((glo_quote_str || (Pmaster && Pmaster->quote_str)) -+ ? (glo_quote_str ? glo_quote_str : Pmaster->quote_str) -+ : "", -+ curwp->w_dotp,ind_str, NLINE, 0)){ -+ if (n){ /* look for another paragraph ? */ -+ curwp->w_dotp = lback(curwp->w_dotp); -+ continue; -+ } -+ break; -+ } - - /* scan line by line until we come to a line ending with - * a <NL><NL> or <NL><TAB> or <NL><SPACE> -*************** -*** 288,294 **** - */ - quoted = (glo_quote_str || (Pmaster && Pmaster->quote_str)) - ? quote_match(glo_quote_str ? glo_quote_str : Pmaster->quote_str, -! curwp->w_dotp, qstr, NLINE) : 0; - qlen = quoted ? strlen(qstr) : 0; - while(lback(curwp->w_dotp) != curbp->b_linep - && llength(lback(curwp->w_dotp)) > qlen ---- 299,305 ---- - */ - quoted = (glo_quote_str || (Pmaster && Pmaster->quote_str)) - ? quote_match(glo_quote_str ? glo_quote_str : Pmaster->quote_str, -! curwp->w_dotp, qstr, NLINE, 0) : 0; - qlen = quoted ? strlen(qstr) : 0; - while(lback(curwp->w_dotp) != curbp->b_linep - && llength(lback(curwp->w_dotp)) > qlen -*************** -*** 296,308 **** - ? (quoted == quote_match(glo_quote_str ? glo_quote_str - : Pmaster->quote_str, - lback(curwp->w_dotp), -! qstr2, NLINE) - && !strcmp(qstr, qstr2)) - : 1) - && lgetc(curwp->w_dotp, qlen).c != TAB - && lgetc(curwp->w_dotp, qlen).c != ' ') - curwp->w_dotp = lback(curwp->w_dotp); - - if(n){ - /* keep looking */ - if(lback(curwp->w_dotp) == curbp->b_linep) ---- 307,361 ---- - ? (quoted == quote_match(glo_quote_str ? glo_quote_str - : Pmaster->quote_str, - lback(curwp->w_dotp), -! qstr2, NLINE, 0) - && !strcmp(qstr, qstr2)) - : 1) -+ && !indent_match((glo_quote_str -+ || (Pmaster && Pmaster->quote_str)) -+ ? (glo_quote_str ? glo_quote_str : Pmaster->quote_str) -+ : "", -+ lback(curwp->w_dotp),ind_str, NLINE, 0) - && lgetc(curwp->w_dotp, qlen).c != TAB - && lgetc(curwp->w_dotp, qlen).c != ' ') - curwp->w_dotp = lback(curwp->w_dotp); - -+ /* -+ * Ok, we made it here and we assume that we are at the begining -+ * of the paragraph. Let's double check this now. In order to do -+ * so we shell check if the first line was indented in a special -+ * way. -+ */ -+ if(lback(curwp->w_dotp) == curbp->b_linep) -+ break; -+ else{ -+ int indented, i, j; -+ -+ /* -+ * for the following test we need to have the raw values, -+ * not the processed values -+ */ -+ if (glo_quote_str || (Pmaster && Pmaster->quote_str)){ -+ quote_match(glo_quote_str ? glo_quote_str : Pmaster->quote_str, -+ curwp->w_dotp, qstr, NLINE, 1); -+ quote_match(glo_quote_str ? glo_quote_str : Pmaster->quote_str, -+ lback(curwp->w_dotp), qstr2, NLINE, 1); -+ } -+ else -+ qstr[0] = qstr2[0] = '\0'; -+ indented = indent_match((glo_quote_str || (Pmaster && Pmaster->quote_str)) -+ ? (glo_quote_str ? glo_quote_str : Pmaster->quote_str) -+ : "", -+ lback(curwp->w_dotp), -+ ind_str, NLINE, 1); -+ if (strlenis(qstr2) + strlenis(ind_str) < strlenis(qstr)) -+ indented = 0; /* Hack, so that it won't return one more line */ -+ for (i= 0,j=0; qstr[i] && qstr2[i] && (qstr[i] == qstr2[i]);i++,j++); -+ for (; isspace(qstr2[i]); i++); -+ for (; isspace(qstr[j]); j++); -+ if (!qstr2[i] && !qstr[j] && indented) -+ curwp->w_dotp = lback(curwp->w_dotp); -+ } -+ - if(n){ - /* keep looking */ - if(lback(curwp->w_dotp) == curbp->b_linep) -*************** -*** 329,346 **** - return(TRUE); - } - -! - /* -! * go forword to the end of the current paragraph - * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE> - * combination to delimit the begining of a paragraph - */ - gotoeop(f, n) - int f, n; /* default Flag & Numeric argument */ -- - { -! int quoted, qlen; -! char qstr[NLINE], qstr2[NLINE]; - - if (n < 0) /* the other way...*/ - return(gotobop(f, -n)); ---- 382,581 ---- - return(TRUE); - } - -! GetAccent() -! { -! char c,d; -! c = (char) GetKey(); -! if ((c == '?') || (c == '!')) { -! d = c; -! c = '\\'; -! } -! else -! if ((c == 's') || (c == 'S')){ -! c = d = 's'; -! } -! else -! if ((c == 'l') || (c == 'L')){ -! c = d = 'l'; -! } -! else -! d = (char) GetKey(); -! return (int) accent(c,d); -! } -! -! pineaccent(f,n) -! int f,n; -! { int e; -! -! if (e = GetAccent()) -! execute(e,0,1); -! return 1; -! } -! -! unsigned char accent(f,n) -! int f,n; -! { char c,d; -! -! c = (char) f; -! d = (char) n; -! switch(c){ -! case '~' : -! switch(d){ -! case 'a' : return '\343'; -! case 'n' : return '\361'; -! case 'o' : return '\365'; -! case 'A' : return '\303'; -! case 'N' : return '\321'; -! case 'O' : return '\325'; -! } -! break; -! case '\047' : -! switch(d){ -! case 'a' : return '\341'; -! case 'e' : return '\351'; -! case 'i' : return '\355'; -! case 'o' : return '\363'; -! case 'u' : return '\372'; -! case 'y' : return '\375'; -! case 'A' : return '\301'; -! case 'E' : return '\311'; -! case 'I' : return '\315'; -! case 'O' : return '\323'; -! case 'U' : return '\332'; -! case 'Y' : return '\335'; -! } -! break; -! case '"' : -! switch(d){ -! case 'a' : return '\344'; -! case 'e' : return '\353'; -! case 'i' : return '\357'; -! case 'o' : return '\366'; -! case 'u' : return '\374'; -! case 'y' : return '\377'; -! case 'A' : return '\304'; -! case 'E' : return '\313'; -! case 'I' : return '\317'; -! case 'O' : return '\326'; -! case 'U' : return '\334'; -! } -! break; -! case '^' : -! switch(d){ -! case 'a' : return '\342'; -! case 'e' : return '\352'; -! case 'i' : return '\356'; -! case 'o' : return '\364'; -! case 'u' : return '\373'; -! case 'A' : return '\302'; -! case 'E' : return '\312'; -! case 'I' : return '\316'; -! case 'O' : return '\324'; -! case 'U' : return '\333'; -! case '0' : return '\260'; -! case '1' : return '\271'; -! case '2' : return '\262'; -! case '3' : return '\263'; -! } -! break; -! case '`' : -! switch(d){ -! case 'a' : return '\340'; -! case 'e' : return '\350'; -! case 'i' : return '\354'; -! case 'o' : return '\362'; -! case 'u' : return '\371'; -! case 'A' : return '\300'; -! case 'E' : return '\310'; -! case 'I' : return '\314'; -! case 'O' : return '\322'; -! case 'U' : return '\331'; -! } -! break; -! case 'o' : -! switch(d){ -! case 'a' : return '\345'; -! case 'A' : return '\305'; -! case '/' : return '\370'; -! case 'r' : return '\256'; -! case 'R' : return '\256'; -! case 'c' : return '\251'; -! case 'C' : return '\251'; -! } -! break; -! case '-' : -! switch(d){ -! case 'o' : return '\272'; -! case 'O' : return '\272'; -! case '0' : return '\272'; -! case 'a' : return '\252'; -! case 'A' : return '\252'; -! case 'l' : return '\243'; -! case 'L' : return '\243'; -! } -! break; -! case 'O' : -! switch(d){ -! case '/' : return '\330'; -! case 'r' : return '\256'; -! case 'R' : return '\256'; -! case 'c' : return '\251'; -! case 'C' : return '\251'; -! } -! case '/' : -! switch(d){ -! case 'o' : return '\370'; -! case 'O' : return '\330'; -! } -! break; -! case 'a' : -! switch(d){ -! case 'e' : return '\346'; -! case 'E' : return '\346'; -! } -! break; -! case 'A' : -! switch(d){ -! case 'E' : return '\306'; -! case 'e' : return '\306'; -! } -! break; -! case ',' : -! switch(d){ -! case 'c' : return '\347'; -! case 'C' : return '\307'; -! } -! break; -! case '\\' : -! switch(d){ -! case '?' : return '\277'; -! case '!' : return '\241'; -! } -! break; -! case 's' : -! switch(d){ -! case 's' : return '\337'; -! } -! break; -! case 'l' : -! switch(d){ -! case 'l' : return '\243'; -! } -! break; -! } -! return '\0'; -! } -! - /* -! * go forward to the end of the current paragraph - * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE> - * combination to delimit the begining of a paragraph - */ - gotoeop(f, n) - int f, n; /* default Flag & Numeric argument */ - { -! int quoted, qlen, indented; -! char qstr[NLINE], qstr2[NLINE], ind_str[NLINE]; - - if (n < 0) /* the other way...*/ - return(gotobop(f, -n)); -*************** -*** 353,358 **** ---- 588,645 ---- - break; - } - -+ /* -+ * We need to figure out if this line is the first line of -+ * a paragraph that has been indented in a special way. If this -+ * is the case, we advance one more line before we use the -+ * algorithm below -+ */ -+ -+ if(curwp->w_dotp != curbp->b_linep){ -+ int i,j; -+ -+ if (glo_quote_str || (Pmaster && Pmaster->quote_str)){ -+ quote_match(glo_quote_str ? glo_quote_str : Pmaster->quote_str, -+ curwp->w_dotp, qstr, NLINE, 1); -+ quote_match(glo_quote_str ? glo_quote_str : Pmaster->quote_str, -+ lforw(curwp->w_dotp), qstr2, NLINE, 1); -+ } -+ else -+ qstr[0] = qstr2[0] = '\0'; -+ indented = indent_match((glo_quote_str || (Pmaster && Pmaster->quote_str)) -+ ? (glo_quote_str ? glo_quote_str -+ : Pmaster->quote_str) : "", curwp->w_dotp, -+ ind_str, NLINE, 1); -+ if (strlenis(qstr) + strlenis(ind_str) < strlenis(qstr2)){ -+ curwp->w_doto = 0; -+ if(n){ /* this line is a paragraph by itself */ -+ curwp->w_dotp = lforw(curwp->w_dotp); -+ continue; -+ } -+ break; -+ } -+ for (i=0,j=0; qstr[i] && qstr2[i] && (qstr[i] == qstr2[i]);i++,j++); -+ for (; isspace(qstr[i]); i++); -+ for (; isspace(qstr2[j]); j++); -+ if (!qstr[i] && !qstr2[j] && indented){ -+ if (indent_match((glo_quote_str -+ || (Pmaster && Pmaster->quote_str)) -+ ? (glo_quote_str ? glo_quote_str -+ : Pmaster->quote_str) : "", -+ lforw(curwp->w_dotp), -+ ind_str, NLINE, 0)){ -+ if (n){ /* look for another paragraph ? */ -+ curwp->w_dotp = lforw(curwp->w_dotp); -+ continue; -+ } -+ } -+ else{ -+ if (!lisblank(lforw(curwp->w_dotp))) -+ curwp->w_dotp = lforw(curwp->w_dotp); -+ } -+ } -+ } -+ - /* scan line by line until we come to a line ending with - * a <NL><NL> or <NL><TAB> or <NL><SPACE> - * -*************** -*** 361,367 **** - */ - quoted = ((glo_quote_str || (Pmaster && Pmaster->quote_str)) - ? quote_match(glo_quote_str ? glo_quote_str : Pmaster->quote_str, -! curwp->w_dotp, qstr, NLINE) : 0); - qlen = quoted ? strlen(qstr) : 0; - - while(curwp->w_dotp != curbp->b_linep ---- 648,654 ---- - */ - quoted = ((glo_quote_str || (Pmaster && Pmaster->quote_str)) - ? quote_match(glo_quote_str ? glo_quote_str : Pmaster->quote_str, -! curwp->w_dotp, qstr, NLINE, 0) : 0); - qlen = quoted ? strlen(qstr) : 0; - - while(curwp->w_dotp != curbp->b_linep -*************** -*** 370,378 **** - ? (quoted == quote_match(glo_quote_str ? glo_quote_str - : Pmaster->quote_str, - lforw(curwp->w_dotp), -! qstr2, NLINE) - && !strcmp(qstr, qstr2)) - : 1) - && lgetc(lforw(curwp->w_dotp), qlen).c != TAB - && lgetc(lforw(curwp->w_dotp), qlen).c != ' ') - curwp->w_dotp = lforw(curwp->w_dotp); ---- 657,671 ---- - ? (quoted == quote_match(glo_quote_str ? glo_quote_str - : Pmaster->quote_str, - lforw(curwp->w_dotp), -! qstr2, NLINE, 0) - && !strcmp(qstr, qstr2)) - : 1) -+ && !indent_match((glo_quote_str -+ || (Pmaster && Pmaster->quote_str)) -+ ? (glo_quote_str ? glo_quote_str -+ : Pmaster->quote_str) : "", -+ lforw(curwp->w_dotp), -+ ind_str, NLINE, 0) - && lgetc(lforw(curwp->w_dotp), qlen).c != TAB - && lgetc(lforw(curwp->w_dotp), qlen).c != ' ') - curwp->w_dotp = lforw(curwp->w_dotp); -*************** -*** 653,659 **** ---- 946,992 ---- - return (scrollback (n, TRUE)); - } - -+ /* deltext deletes from the specified position until the end of the file -+ * or until the signature (when called from Pine), whichever comes first. -+ */ - -+ int -+ deltext (f,n) -+ int f,n; -+ { -+ LINE *currline = curwp->w_dotp; -+ -+ if ((lastflag&CFKILL) == 0) -+ kdelete(); -+ -+ curwp->w_markp = curwp->w_dotp; -+ curwp->w_marko = curwp->w_doto; -+ -+ while (curwp->w_dotp != curbp->b_linep){ -+ if ((Pmaster) -+ && (llength(curwp->w_dotp) == 3) -+ && (lgetc(curwp->w_dotp, 0).c == '-') -+ && (lgetc(curwp->w_dotp, 1).c == '-') -+ && (lgetc(curwp->w_dotp, 2).c == ' ')){ -+ if (curwp->w_dotp == currline){ -+ if (curwp->w_doto) -+ curwp->w_dotp = lforw(curwp->w_dotp); -+ else -+ break; -+ } -+ else{ -+ curwp->w_dotp = lback(curwp->w_dotp); -+ curwp->w_doto = llength(curwp->w_dotp); -+ break; -+ } -+ } -+ else -+ curwp->w_dotp = lforw(curwp->w_dotp); -+ } -+ killregion(FALSE,1); -+ lastflag |= CFKILL; -+ return TRUE; -+ } - - scrollupline (f, n) - int f, n; -diff -rc pine4.63/pico/composer.c pine4.63.I.USE/pico/composer.c -*** pine4.63/pico/composer.c Thu Mar 17 11:08:37 2005 ---- pine4.63.I.USE/pico/composer.c Thu May 19 19:57:30 2005 -*************** -*** 1560,1565 **** ---- 1560,1567 ---- - } - - UpdateHeader(0); -+ if(sendnow) -+ return(status !=0); - PaintHeader(COMPOSER_TOP_LINE, status != 0); - PaintBody(1); - return(status != 0); -*************** -*** 1691,1697 **** - } - - if(VALID_KEY(ch)){ /* char input */ -! /* - * if we are allowing editing, insert the new char - * end up leaving tbufp pointing to newly - * inserted character in string, and offset to the ---- 1693,1699 ---- - } - - if(VALID_KEY(ch)){ /* char input */ -! insert_char:/* - * if we are allowing editing, insert the new char - * end up leaving tbufp pointing to newly - * inserted character in string, and offset to the -*************** -*** 1775,1780 **** ---- 1777,1789 ---- - } - else { /* interpret ch as a command */ - switch (ch = normalize_cmd(ch, ckm, 2)) { -+ case (CTRL|'\\') : -+ if (ch = GetAccent()) -+ goto insert_char; -+ else -+ clearcursor(); -+ break; -+ - case (CTRL|'@') : /* word skip */ - while(strng[ods.p_off] - && isalnum((unsigned char)strng[ods.p_off])) -*************** -*** 2955,2960 **** ---- 2964,2972 ---- - { - register char *bufp; - -+ if (sendnow) -+ return; -+ - if(ComposerTopLine - 1 >= BOTTOM()) /* silently forget it */ - return; - -*************** -*** 3004,3009 **** ---- 3016,3024 ---- - register char *bufp; - register int i; - -+ if (sendnow) -+ return(TRUE); -+ - bufp = headents[entry].prompt; /* fresh prompt paint */ - if((i = entry_line(entry, FALSE)) == -1) - return(-1); /* silently forget it */ -*************** -*** 3884,3889 **** ---- 3899,3907 ---- - void - ShowPrompt() - { -+ if (sendnow) -+ return; -+ - if(headents[ods.cur_e].key_label){ - menu_header[TO_KEY].name = "^T"; - menu_header[TO_KEY].label = headents[ods.cur_e].key_label; -diff -rc pine4.63/pico/display.c pine4.63.I.USE/pico/display.c -*** pine4.63/pico/display.c Fri May 7 14:38:24 2004 ---- pine4.63.I.USE/pico/display.c Thu May 19 19:57:32 2005 -*************** -*** 362,367 **** ---- 362,370 ---- - register int scroll = 0; - CELL c; - -+ if (sendnow) -+ return; -+ - #if TYPEAH - if (typahead()) - return; -*************** -*** 1400,1405 **** ---- 1403,1409 ---- - - maxl = (nbuf-1 < term.t_ncol - plen - 1) ? nbuf-1 : term.t_ncol - plen - 1; - -+ if (!sendnow) - pputs(buf, 1); - b = &buf[(flg & QBOBUF) ? 0 : strlen(buf)]; - -*************** -*** 1460,1465 **** ---- 1464,1482 ---- - b++; - continue; - -+ case (CTRL|'N'): /* Insert pattern */ -+ if (pat[0] != '\0'){ -+ strcat(buf,pat); -+ pputs(pat,1); -+ b += strlen(pat); -+ changed = TRUE; -+ } -+ else -+ (*term.t_beep)(); -+ continue; -+ -+ -+ - case (CTRL|'G') : /* CTRL-G help */ - if(term.t_mrow == 0 && km_popped == 0){ - movecursor(term.t_nrow-2, 0); -*************** -*** 1515,1520 **** ---- 1532,1542 ---- - b--; - continue; - -+ case (CTRL|'\\'): -+ if (c = GetAccent()) -+ goto text; -+ continue; -+ - case KEY_RIGHT: - if(*b != '\0') - b++; -*************** -*** 1566,1571 **** ---- 1588,1594 ---- - #endif - - default : -+ text: - if(strlen(buf) >= maxl){ /* contain the text */ - (*term.t_beep)(); - continue; -*************** -*** 1604,1625 **** - b[i+1] = b[i]; - while(i-- > 0); - -! pputc(*b++ = c, 0); - } - } - -! pputs(b, 1); /* show default */ - i = term.t_ncol-1; - while(pscreen[ttrow]->v_text[i].c == ' ' - && pscreen[ttrow]->v_text[i].a == 0) - i--; - -! while(ttcol <= i) - pputc(' ', 0); - } - - ret: -! if(km_popped){ - term.t_mrow = 0; - movecursor(term.t_nrow, 0); - peeol(); ---- 1627,1652 ---- - b[i+1] = b[i]; - while(i-- > 0); - -! if(sendnow) -! *b++ = c; -! else -! pputc(*b++ = c, 0); - } - } - -! if(!sendnow) -! pputs(b, 1); /* show default */ - i = term.t_ncol-1; - while(pscreen[ttrow]->v_text[i].c == ' ' - && pscreen[ttrow]->v_text[i].a == 0) - i--; - -! while(!sendnow && ttcol <= i) - pputc(' ', 0); - } - - ret: -! if(!sendnow && km_popped){ - term.t_mrow = 0; - movecursor(term.t_nrow, 0); - peeol(); -*************** -*** 1745,1750 **** ---- 1772,1779 ---- - register int c; - register char *ap; - -+ if(sendnow) -+ return 0; - /* - * the idea is to only highlight if there is something to show - */ -*************** -*** 2472,2477 **** ---- 2501,2509 ---- - char nbuf[NLINE]; - #endif - -+ if(sendnow) -+ return; -+ - #ifdef _WINDOWS - pico_config_menu_items (keymenu); - #endif -diff -rc pine4.63/pico/ebind.h pine4.63.I.USE/pico/ebind.h -*** pine4.63/pico/ebind.h Fri May 7 14:38:24 2004 ---- pine4.63.I.USE/pico/ebind.h Thu May 19 19:57:30 2005 -*************** -*** 105,111 **** - {CTRL|'^', setmark}, - {CTRL|'_', alt_editor}, - {0x7F, backdel}, -! {0, NULL} - }; - - ---- 105,113 ---- - {CTRL|'^', setmark}, - {CTRL|'_', alt_editor}, - {0x7F, backdel}, -! {CTRL|'\\', pineaccent}, -! {0, -! NULL} - }; - - -diff -rc pine4.63/pico/edef.h pine4.63.I.USE/pico/edef.h -*** pine4.63/pico/edef.h Wed Oct 13 18:27:46 2004 ---- pine4.63.I.USE/pico/edef.h Thu May 19 19:57:27 2005 -*************** -*** 43,48 **** ---- 43,49 ---- - - /* initialized global definitions */ - -+ int sendnow = 0; /* should we send now */ - int fillcol = 72; /* Current fill column */ - int userfillcol = -1; /* Fillcol set from cmd line */ - char pat[NPAT]; /* Search pattern */ -*************** -*** 96,101 **** ---- 97,103 ---- - - /* initialized global external declarations */ - -+ extern int sendnow; /* should we send now */ - extern int fillcol; /* Fill column */ - extern int userfillcol; /* Fillcol set from cmd line */ - extern char pat[]; /* Search pattern */ -diff -rc pine4.63/pico/efunc.h pine4.63.I.USE/pico/efunc.h -*** pine4.63/pico/efunc.h Tue Jun 15 15:22:58 2004 ---- pine4.63.I.USE/pico/efunc.h Thu May 19 19:57:33 2005 -*************** -*** 65,70 **** ---- 65,71 ---- - extern int gotoeop PROTO((int, int)); - extern int forwpage PROTO((int, int)); - extern int backpage PROTO((int, int)); -+ extern int deltext PROTO((int, int)); - extern int scrollupline PROTO((int, int)); - extern int scrolldownline PROTO((int, int)); - extern int scrollto PROTO((int, int)); -*************** -*** 73,78 **** ---- 74,82 ---- - extern int setimark PROTO((int, int)); - extern int swapimark PROTO((int, int)); - extern int mousepress PROTO((int, int)); -+ extern unsigned char accent PROTO((int, int)); -+ extern int pineaccent PROTO((int, int)); -+ extern int GetAccent PROTO((void)); - - /* bind.c */ - extern int whelp PROTO((int, int)); -*************** -*** 337,342 **** - extern int fillpara PROTO((int, int)); - extern int fillbuf PROTO((int, int)); - extern int inword PROTO((void)); -! extern int quote_match PROTO((char *, LINE *, char *, int)); - - #endif /* EFUNC_H */ ---- 341,350 ---- - extern int fillpara PROTO((int, int)); - extern int fillbuf PROTO((int, int)); - extern int inword PROTO((void)); -! extern int quote_match PROTO((char *, LINE *, char *, int, int)); -! extern void flatten_qstring PROTO((QSTRING_S *, char *)); -! extern void free_qs PROTO((QSTRING_S **)); -! extern QSTRING_S *do_quote_match PROTO((char *, char *, char *, char *, int)); -! extern QSTRING_S *copy_qs PROTO((QSTRING_S *)); - - #endif /* EFUNC_H */ -diff -rc pine4.63/pico/line.c pine4.63.I.USE/pico/line.c -*** pine4.63/pico/line.c Fri May 7 14:41:16 2004 ---- pine4.63.I.USE/pico/line.c Thu May 19 19:57:29 2005 -*************** -*** 635,641 **** - - n = ((glo_quote_str || (Pmaster && Pmaster->quote_str)) - && quote_match(glo_quote_str ? glo_quote_str : Pmaster->quote_str, -! line, qstr, NLINE)) - ? strlen(qstr) : 0; - - for(; n < llength(line); n++) ---- 635,641 ---- - - n = ((glo_quote_str || (Pmaster && Pmaster->quote_str)) - && quote_match(glo_quote_str ? glo_quote_str : Pmaster->quote_str, -! line, qstr, NLINE, 1)) - ? strlen(qstr) : 0; - - for(; n < llength(line); n++) -diff -rc pine4.63/pico/main.c pine4.63.I.USE/pico/main.c -*** pine4.63/pico/main.c Fri May 7 14:41:16 2004 ---- pine4.63.I.USE/pico/main.c Thu May 19 19:57:31 2005 -*************** -*** 149,154 **** ---- 149,155 ---- - int setlocale_ctype = 0; - char bname[NBUFN]; /* buffer name of file to read */ - char *file_to_edit = NULL; -+ int line_information_on = FALSE; - - timeo = 600; - Pmaster = NULL; /* turn OFF composer functionality */ -*************** -*** 306,311 **** ---- 307,318 ---- - emlwrite("You may possibly have new mail.", NULL); - } - -+ if (c == (CTRL|'\\')){ -+ c = GetAccent(); -+ if (!c) -+ c = NODATA; -+ } -+ - if(km_popped) - switch(c){ - case NODATA: -*************** -*** 327,340 **** - mlerase(); - } - -! f = FALSE; - n = 1; - - #ifdef MOUSE - clear_mfunc(mouse_in_content); - #endif - /* Do it. */ - execute(normalize_cmd(c, fkm, 1), f, n); - } - } - ---- 334,363 ---- - mlerase(); - } - -! f = (c == (CTRL|'J')); - n = 1; -+ if (!line_information_on) -+ line_information_on = (c == (CTRL|'C')); -+ else -+ line_information_on = ((c == KEY_DOWN) || (c == KEY_UP) || -+ (c == KEY_RIGHT) || (c == KEY_LEFT) || -+ (c == (CTRL|'V')) || (c == (CTRL|'Y')) || -+ (c == (CTRL|'K')) || (c == (CTRL|'D')) || -+ (c == (CTRL|'F')) || (c == (CTRL|'B')) || -+ (c == (CTRL|'N')) || (c == (CTRL|'P')) || -+ (c == (CTRL|'A')) || (c == (CTRL|'E')) || -+ (c == (CTRL|'U')) || (c == (CTRL|'^'))) -+ && (c != (CTRL|'C')); - - #ifdef MOUSE - clear_mfunc(mouse_in_content); - #endif - /* Do it. */ - execute(normalize_cmd(c, fkm, 1), f, n); -+ if (line_information_on){ -+ c = (CTRL|'C'); -+ execute(normalize_cmd(c, fkm, 1), f, n); -+ } - } - } - -diff -rc pine4.63/pico/osdep/term.cap pine4.63.I.USE/pico/osdep/term.cap -*** pine4.63/pico/osdep/term.cap Wed Jul 21 15:04:36 2004 ---- pine4.63.I.USE/pico/osdep/term.cap Thu May 19 19:57:27 2005 -*************** -*** 438,443 **** ---- 438,449 ---- - { - int row, col; - -+ if (sendnow){ -+ term.t_nrow = 23; -+ term.t_ncol = 80; -+ return 0; -+ } -+ - /* - * determine the terminal's communication speed and decide - * if we need to do optimization ... -diff -rc pine4.63/pico/osdep/unix pine4.63.I.USE/pico/osdep/unix -*** pine4.63/pico/osdep/unix Tue Apr 19 14:28:56 2005 ---- pine4.63.I.USE/pico/osdep/unix Thu May 19 19:57:27 2005 -*************** -*** 363,368 **** ---- 363,381 ---- - { - int ch, status, cc; - -+ if(sendnow){ -+ ch = Pmaster && Pmaster->auto_cmds && *Pmaster->auto_cmds -+ ? *Pmaster->auto_cmds++ : NODATA; -+ -+ if(ch & 0x80 && Pmaster && Pmaster->hibit_entered) -+ *Pmaster->hibit_entered = 1; -+ -+ if (ch >= 0x00 && ch <= 0x1F) -+ ch = CTRL | (ch+'@'); -+ -+ return(ch); -+ } -+ - if(!ReadyForKey(FUDGE-5)) - return(NODATA); - -diff -rc pine4.63/pico/pico.c pine4.63.I.USE/pico/pico.c -*** pine4.63/pico/pico.c Thu Mar 31 09:08:57 2005 ---- pine4.63.I.USE/pico/pico.c Thu May 19 19:57:27 2005 -*************** -*** 138,143 **** ---- 138,152 ---- - pico_all_done = 0; - km_popped = 0; - -+ if (pm->auto_cmds){ -+ int i; -+ #define CTRL_X 24 -+ for (i = 0; pm->auto_cmds[i]; i++); -+ if ((i > 1) && (pm->auto_cmds[i - 2] == CTRL_X) && -+ ((pm->auto_cmds[i - 1] == 'y') || (pm->auto_cmds[i-1] == 'Y'))) -+ sendnow++; -+ } -+ - if(!vtinit()) /* Init Displays. */ - return(COMP_CANCEL); - -*************** -*** 686,691 **** ---- 695,711 ---- - return(FALSE); - } - -+ /* When we send a message using the command line we are going to -+ ignore if the user wants to spell check, we assume she already -+ did */ -+ if (sendnow){ -+ result = (*Pmaster->exittest)(Pmaster->headents, -+ redraw_pico_for_callback, Pmaster->allow_flowed_text); -+ if (!result) -+ pico_all_done = COMP_EXIT; -+ return(result ? FALSE : TRUE); -+ } -+ - #ifdef SPELLER - if(Pmaster->always_spell_check) - if(spell(0, 0) == -1) -diff -rc pine4.63/pico/pico.h pine4.63.I.USE/pico/pico.h -*** pine4.63/pico/pico.h Wed Mar 30 14:44:42 2005 ---- pine4.63.I.USE/pico/pico.h Thu May 19 19:57:29 2005 -*************** -*** 219,224 **** ---- 219,225 ---- - void (*resize)(); /* callback handling screen resize */ - void (*winch_cleanup)(); /* callback handling screen resize */ - int arm_winch_cleanup; /* do the winch_cleanup if resized */ -+ int *auto_cmds; /* Initial keystroke commands */ - HELP_T search_help; - HELP_T ins_help; - HELP_T ins_m_help; -*************** -*** 342,347 **** ---- 343,364 ---- - struct KBSTREE *left; - } KBESC_T; - -+ /* -+ * struct that will help us determine what the quote string of a line -+ * is. The "next" field indicates the presence of a possible continuation. -+ * The idea is that if a continuation fails, we free it and check for the -+ * remaining structure left -+ */ -+ -+ typedef enum {qsNormal, qsString, qsWord, qsChar} QStrType; -+ -+ typedef struct QSTRING { -+ char *value; /* possible quote string */ -+ QStrType qstype; /* type of quote string */ -+ struct QSTRING *next; /* possible continuation */ -+ } QSTRING_S; -+ -+ - /* - * Protos for functions used to manage keyboard escape sequences - * NOTE: these may ot actually get defined under some OS's (ie, DOS, WIN) -diff -rc pine4.63/pico/random.c pine4.63.I.USE/pico/random.c -*** pine4.63/pico/random.c Fri May 7 14:43:48 2004 ---- pine4.63.I.USE/pico/random.c Thu May 19 19:57:29 2005 -*************** -*** 364,370 **** - else{ - backchar(FALSE, 1); - dotp = curwp->w_dotp; -! gotobop(FALSE, 1); /* then go to the top of the para */ - } - - curwp->w_doto = 0; ---- 364,371 ---- - else{ - backchar(FALSE, 1); - dotp = curwp->w_dotp; -! swapimark(FALSE, 1); /* go back to the spot we marked before justify */ -! /* We assume that no imarks have been set between fillpara and now */ - } - - curwp->w_doto = 0; -diff -rc pine4.63/pico/search.c pine4.63.I.USE/pico/search.c -*** pine4.63/pico/search.c Thu Jul 1 14:36:36 2004 ---- pine4.63.I.USE/pico/search.c Thu May 19 19:57:34 2005 -*************** -*** 78,83 **** ---- 78,87 ---- - "\tbrackets. This string is the default search prompt.", - "~ Hitting only ~R~e~t~u~r~n or at the prompt will cause the", - "\tsearch to be made with the default value.", -+ " ", -+ "~ Hitting ~^~N will reinsert the last string you searched for", -+ "\tso that you can edit it (in case you made a mistake entering the", -+ "\tsearch pattern the first time).", - " ", - "\tThe text search is not case sensitive, and will examine the", - "\tentire message.", -*************** -*** 235,244 **** ---- 239,258 ---- - mlerase(); - FWS_RETURN(TRUE); - -+ case (CTRL|'P'): -+ deletepara(0, 1); -+ mlerase(); -+ FWS_RETURN(TRUE); -+ - case (CTRL|'R'): /* toggle replacement option */ - repl_mode = !repl_mode; - break; - -+ case (CTRL|'X'): -+ deltext(f,n); -+ mlerase(); -+ FWS_RETURN(TRUE); -+ - default: - if(status == ABORT) - emlwrite("Search Cancelled", NULL); -*************** -*** 275,281 **** - } - - if(status + curwp->w_doto >= llength(curwp->w_dotp) || -! !eq(defpat[status],lgetc(curwp->w_dotp, curwp->w_doto + status).c)) - break; /* do nothing! */ - status++; - } ---- 289,295 ---- - } - - if(status + curwp->w_doto >= llength(curwp->w_dotp) || -! !eq((unsigned char)defpat[status],lgetc(curwp->w_dotp, curwp->w_doto + status).c)) - break; /* do nothing! */ - status++; - } -*************** -*** 499,505 **** - register int s; - int i = 0; - char tpat[NPAT+20]; -! EXTRAKEYS menu_pat[8]; - - menu_pat[i = 0].name = "^Y"; - menu_pat[i].label = "FirstLine"; ---- 513,519 ---- - register int s; - int i = 0; - char tpat[NPAT+20]; -! EXTRAKEYS menu_pat[10]; - - menu_pat[i = 0].name = "^Y"; - menu_pat[i].label = "FirstLine"; -*************** -*** 517,522 **** ---- 531,541 ---- - KS_OSDATASET(&menu_pat[i], KS_NONE); - - if(!repl_mode){ -+ menu_pat[++i].name = "^X"; -+ menu_pat[i].label = "EndText"; -+ menu_pat[i].key = (CTRL|'X'); -+ KS_OSDATASET(&menu_pat[i], KS_NONE); -+ - menu_pat[++i].name = "^T"; - menu_pat[i].label = "LineNumber"; - menu_pat[i].key = (CTRL|'T'); -*************** -*** 532,537 **** ---- 551,561 ---- - menu_pat[i].key = (CTRL|'O'); - KS_OSDATASET(&menu_pat[i], KS_NONE); - -+ menu_pat[++i].name = "^P"; -+ menu_pat[i].label = "Delete Para"; -+ menu_pat[i].key = (CTRL|'P'); -+ KS_OSDATASET(&menu_pat[i], KS_NONE); -+ - menu_pat[++i].name = "^U"; - menu_pat[i].label = "FullJustify"; - menu_pat[i].key = (CTRL|'U'); -*************** -*** 630,636 **** - register int s; - int i; - char tpat[NPAT+20]; -! EXTRAKEYS menu_pat[7]; - - menu_pat[i = 0].name = "^Y"; - menu_pat[i].label = "FirstLine"; ---- 654,660 ---- - register int s; - int i; - char tpat[NPAT+20]; -! EXTRAKEYS menu_pat[9]; - - menu_pat[i = 0].name = "^Y"; - menu_pat[i].label = "FirstLine"; -*************** -*** 643,648 **** ---- 667,677 ---- - KS_OSDATASET(&menu_pat[i], KS_NONE); - - if(text_mode){ -+ menu_pat[++i].name = "^X"; -+ menu_pat[i].label = "EndText"; -+ menu_pat[i].key = (CTRL|'X'); -+ KS_OSDATASET(&menu_pat[i], KS_NONE); -+ - menu_pat[++i].name = "^T"; - menu_pat[i].label = "LineNumber"; - menu_pat[i].key = (CTRL|'T'); -*************** -*** 658,663 **** ---- 687,697 ---- - menu_pat[i].key = (CTRL|'O'); - KS_OSDATASET(&menu_pat[i], KS_NONE); - -+ menu_pat[++i].name = "^P"; -+ menu_pat[i].label = "Delete Para"; -+ menu_pat[i].key = (CTRL|'P'); -+ KS_OSDATASET(&menu_pat[i], KS_NONE); -+ - menu_pat[++i].name = "^U"; - menu_pat[i].label = "FullJustify"; - menu_pat[i].key = (CTRL|'U'); -*************** -*** 760,766 **** - c = lgetc(curline, curoff++).c; /* get the char */ - - /* test it against first char in pattern */ -! if (eq(c, patrn[0]) != FALSE) { /* if we find it..*/ - /* setup match pointers */ - matchline = curline; - matchoff = curoff; ---- 794,800 ---- - c = lgetc(curline, curoff++).c; /* get the char */ - - /* test it against first char in pattern */ -! if (eq(c, (unsigned char)patrn[0]) != FALSE) { /* if we find it..*/ - /* setup match pointers */ - matchline = curline; - matchoff = curoff; -*************** -*** 781,787 **** - return(FALSE); - - /* and test it against the pattern */ -! if (eq(*patptr, c) == FALSE) - goto fail; - } - ---- 815,821 ---- - return(FALSE); - - /* and test it against the pattern */ -! if (eq((unsigned char) *patptr, c) == FALSE) - goto fail; - } - -*************** -*** 820,829 **** - int maxlength; /* maximum chars in destination */ - - { -! char c; /* current char to translate */ - - /* scan through the string */ -! while ((c = *srcstr++) != 0) { - if (c == '\n') { /* its an EOL */ - *deststr++ = '<'; - *deststr++ = 'N'; ---- 854,863 ---- - int maxlength; /* maximum chars in destination */ - - { -! unsigned char c; /* current char to translate */ - - /* scan through the string */ -! while ((c = (unsigned char) *srcstr++) != 0) { - if (c == '\n') { /* its an EOL */ - *deststr++ = '<'; - *deststr++ = 'N'; -diff -rc pine4.63/pico/word.c pine4.63.I.USE/pico/word.c -*** pine4.63/pico/word.c Fri May 7 14:45:24 2004 ---- pine4.63.I.USE/pico/word.c Thu May 19 19:57:29 2005 -*************** -*** 360,403 **** - && isalnum((unsigned char)lgetc(curwp->w_dotp, curwp->w_doto).c)); - } - - - /* -! * Return number of quotes if whatever starts the line matches the quote string - */ -! quote_match(q, l, buf, buflen) - char *q; - LINE *l; - char *buf; - int buflen; - { -! register int i, n, j, qb; - -! *buf = '\0'; -! if(*q == '\0') -! return(1); -! -! qb = (strlen(q) > 1 && q[strlen(q)-1] == ' ') ? 1 : 0; -! for(n = 0, j = 0; ;){ -! for(i = 0; j <= llength(l) && qb ? q[i+1] : q[i]; i++, j++) -! if(q[i] != lgetc(l, j).c) -! return(n); -! -! n++; -! if((!qb && q[i] == '\0') || (qb && q[i+1] == '\0')){ -! if(strlen(buf) + strlen(q) + 1 < buflen){ -! strcat(buf,q); -! if(qb && (j > llength(l) || lgetc(l, j).c != ' ')) -! buf[strlen(buf)-1] = '\0'; -! } - } -! if(j > llength(l)) -! return(n); -! else if(qb && lgetc(l, j).c == ' ') -! j++; - } -! return(n); /* never reached */ - } - - - /* Justify the entire buffer instead of just a paragraph */ - fillbuf(f, n) ---- 360,1419 ---- - && isalnum((unsigned char)lgetc(curwp->w_dotp, curwp->w_doto).c)); - } - -+ /* Support of indentation of paragraphs */ -+ #define NBSP ((unsigned char) '\240') -+ #define ISspace(c) ((c) == ' ' || (c) == TAB || ((unsigned char)(c)) == NBSP) -+ #define is_indent_char(c) (((c) == '.' || (c) == '}' || (c) == RPAREN || \ -+ (c) == '*' || (c) == '+' || is_a_digit(c) || \ -+ ISspace(c) || (c) == '-' || \ -+ (c) == ']') ? 1 : 0) -+ #define allowed_after_digit(c,word,k) ((((c) == '.' && \ -+ allowed_after_period(next((word),(k)))) ||\ -+ (c) == RPAREN || (c) == '}' || (c) == ']' ||\ -+ ISspace(c) || is_a_digit(c) || \ -+ ((c) == '-' ) && \ -+ allowed_after_dash(next((word),(k)))) \ -+ ? 1 : 0) -+ #define allowed_after_period(c) (((c) == RPAREN || (c) == '}' || (c) == ']' ||\ -+ ISspace(c) || (c) == '-' || \ -+ is_a_digit(c)) ? 1 : 0) -+ #define allowed_after_parenth(c) (ISspace(c) ? 1 : 0) -+ #define allowed_after_space(c) (ISspace(c) ? 1 : 0) -+ #define allowed_after_braces(c) (ISspace(c) ? 1 : 0) -+ #define allowed_after_star(c) ((ISspace(c) || (c) == RPAREN ||\ -+ (c) == ']' || (c) == '}') ? 1 : 0) -+ #define allowed_after_dash(c) ((ISspace(c) || is_a_digit(c)) ? 1 : 0) -+ #define EOLchar(c) (((c) == '.' || (c) == ':' || (c) == '?' ||\ -+ (c) == '!') ? 1 : 0) -+ -+ int is_indent PROTO((char *, int)); -+ int indent_match PROTO(( char *, LINE *, char *, int, int)); -+ -+ /* Extended justification support */ -+ -+ #define is_cquote(c) ((c) == '>' || (c) == '|' || (c) == ']' || (c) == ':') -+ #define is_cword(c) ((((c) >= 'a') && ((c) <= 'z')) || \ -+ (((c) >= 'A') && ((c) <= 'Z')) || \ -+ (((c) >= '0') && ((c) <= '9')) || \ -+ ((c) == ' ') || ((c) == '?') || \ -+ ((c) == '@') || ((c) == '.') || \ -+ ((c) == '!') || ((c) == '\'') || \ -+ ((c) == ',') || ((c) == '\"') ? 1 : 0) -+ #define isaquote(c) ((c) == '\"' || (c) == '\'') -+ #define is8bit(c) ((((int) (c)) & 0x80) ? 1 : 0) -+ #define forbidden(c) (((c) == '\"') || ((c) == '\'') || ((c) == '$') ||\ -+ ((c) == ',') || ((c) == '.') || ((c) == '-') ||\ -+ ((c) == LPAREN) || ((c) == '/')|| ((c) == '`') ||\ -+ ((c) == '{') || ((c) == '\\') || \ -+ (((c) >= '0') && ((c) <= '9'))) -+ #define is_cletter(c) ((((c) >= 'a') && ((c) <= 'z'))) ||\ -+ ((((c) >= 'A') && ((c) <= 'Z'))||\ -+ is8bit(c)) -+ #define is_cnumber(c) ((c) >= '0' && (c) <= '9') -+ #define allwd_after_word(c) (((c) == ' ') || ((c) == '>') || is_cletter(c)) -+ #define allwd_after_qsword(c) (((c) != '\\') && ((c) != RPAREN)) -+ #define before(word,i) (((i) > 0) ? (word)[(i) - 1] : 0) -+ #define next(w,i) ((((w)[(i)]) != 0) ? ((w)[(i) + 1]) : 0) -+ #define now(w,i) ((w)[(i)]) -+ #define is_qsword(c) (((c) == ':') || ((c) == RPAREN) ? 1 : 0) -+ #define is_colon(c) (((c) == ':') ? 1 : 0) -+ #define is_rarrow(c) (((c) == '>') ? 1 : 0) -+ #define is_tilde(c) (((c) == '~') ? 1 : 0) -+ #define is_dash(c) (((c) == '-') ? 1 : 0) -+ #define is_pound(c) (((c) == '#') ? 1 : 0) -+ #define is_space(c) (((c) == ' ') ? 1 : 0) -+ #define is_a_digit(c) ((((c) >= '0') && ((c) <= '9')) ? 1 : 0) -+ #define is_allowed(c) (is_cquote(c) || is_cword(c) || is_dash(c) || \ -+ is_pound(c)) -+ -+ /* Internal justification functions */ -+ -+ QSTRING_S *is_quote PROTO((char *, char *, int)); -+ QSTRING_S *copy_qs PROTO((QSTRING_S *)); -+ QSTRING_S *qs_normal_part PROTO((QSTRING_S *)); -+ QSTRING_S *qs_remove_trailing_spaces PROTO((QSTRING_S *)); -+ QSTRING_S *trim_qs_from_cl PROTO((QSTRING_S *, QSTRING_S *, QSTRING_S *)); -+ QSTRING_S *fix_qstring PROTO((QSTRING_S *, QSTRING_S *, QSTRING_S *)); -+ QSTRING_S *qs_add PROTO((char *, char *, QStrType, int, int, int, int)); -+ QSTRING_S *remove_qsword PROTO((QSTRING_S *)); -+ int qstring_is_normal PROTO((QSTRING_S *)); -+ int exists_good_part PROTO((QSTRING_S *)); -+ int value_is_space PROTO((char *)); -+ int strcmp_qs PROTO((char *, char *)); -+ int count_levels_qstring PROTO((QSTRING_S *)); -+ int same_qstring PROTO((QSTRING_S *, QSTRING_S *)); -+ int advance_quote_string PROTO((char *, char *, int)); -+ int strlenis PROTO((char *)); -+ void flatten_qstring PROTO((QSTRING_S *, char *)); -+ void linencpy PROTO((char *, LINE *, int)); -+ -+ /* -+ * This function creates a qstring pointer with the information that -+ * is_quote handles to it. -+ * Parameters: -+ * qs - User supplied quote string -+ * word - The line of text that the user is trying to read/justify -+ * beginw - Where we need to start copying from -+ * endw - Where we end copying -+ * offset - Any offset in endw that we need to account for -+ * typeqs - type of the string to be created -+ * neednext - boolean, indicating if we need to compute the next field -+ * of leave it NULL -+ * -+ * It is a mistake to call this function if beginw >= endw + offset. -+ * Please note the equality sign in the above inequality (this is because -+ * we always assume that qstring->value != ""). -+ */ -+ -+ QSTRING_S * -+ qs_add(qs, word, typeqs, beginw, endw, offset, neednext) -+ char *qs; -+ char word[NSTRING]; -+ QStrType typeqs; -+ int beginw; -+ int endw; -+ int offset; -+ int neednext; -+ { -+ QSTRING_S *qstring, *nextqs = (QSTRING_S *) NULL; -+ int i; -+ -+ qstring = (QSTRING_S *) malloc (sizeof(QSTRING_S)); -+ memset (qstring, 0, sizeof(QSTRING_S)); -+ qstring->qstype = qsNormal; -+ -+ if (beginw == 0){ -+ beginw = endw + offset; -+ qstring->qstype = typeqs; -+ } -+ -+ if (neednext) -+ nextqs = is_quote(qs, word+beginw, 1); -+ -+ qstring->value = (char *) malloc((beginw+1)*sizeof(char)); -+ strncpy(qstring->value, word, beginw); -+ qstring->value[beginw] = '\0'; -+ -+ qstring->next = nextqs; -+ -+ return qstring; -+ } -+ -+ -+ int -+ qstring_is_normal(cl) -+ QSTRING_S *cl; -+ { -+ for (;cl && (cl->qstype == qsNormal); cl = cl->next); -+ -+ return cl ? 0 : 1; -+ } -+ -+ void -+ free_qs(cl) -+ QSTRING_S **cl; -+ { -+ if (!(*cl)) -+ return; -+ -+ if ((*cl)->next) -+ free_qs(&((*cl)->next)); -+ -+ (*cl)->next = (QSTRING_S *) NULL; -+ -+ if ((*cl)->value) -+ free((void *)(*cl)->value); -+ -+ (*cl)->value = (char *) NULL; -+ -+ free((void *)(*cl)); -+ *cl = (QSTRING_S *) NULL; -+ } -+ -+ QSTRING_S * -+ copy_qs(cl) -+ QSTRING_S *cl; -+ { -+ QSTRING_S *qs; -+ -+ if (!cl) -+ return (QSTRING_S *)NULL; -+ -+ qs = (QSTRING_S *) malloc (sizeof(QSTRING_S)); -+ memset (qs, 0, sizeof(QSTRING_S)); -+ -+ qs->value = (char *) malloc ((strlen(cl->value)+1)*sizeof(char)); -+ strcpy(qs->value, cl->value); -+ qs->qstype = cl->qstype; -+ qs->next = copy_qs(cl->next); -+ return qs; -+ } -+ -+ /* -+ * Given a quote string, this function returns the part that is the leading -+ * normal part of it. (the normal part is the part that is tagged qsNormal, -+ * that is to say, the one that is not controversial at all (like qsString -+ * for example). -+ */ -+ QSTRING_S * -+ qs_normal_part(cl) -+ QSTRING_S *cl; -+ { -+ -+ if (!cl) /* nothing in, nothing out */ -+ return cl; -+ -+ if (cl->qstype != qsNormal) -+ free_qs(&cl); -+ -+ if (cl) -+ cl->next = qs_normal_part(cl->next); -+ -+ return cl; -+ } -+ -+ int -+ value_is_space(value) -+ char *value; -+ { -+ for (; value && *value && ISspace((unsigned char) *value); value++); -+ -+ return value && *value ? 0 : 1; -+ } -+ -+ /* -+ * this function removes trailing spaces from a quote string, but leaves the -+ * last one if there are trailing spaces -+ */ -+ QSTRING_S * -+ qs_remove_trailing_spaces(cl) -+ QSTRING_S *cl; -+ { -+ QSTRING_S *rl = cl; -+ -+ if (!cl) /* nothing in, nothing out */ -+ return cl; -+ -+ if (cl->next) -+ cl->next = qs_remove_trailing_spaces(cl->next); -+ else{ -+ if (value_is_space(cl->value)) -+ free_qs(&cl); -+ else{ -+ int i, l; -+ i = l = strlen(cl->value) - 1; -+ while (cl->value && cl->value[i] -+ && ISspace((unsigned char) cl->value[i])) -+ i--; -+ i += (i < l) ? 2 : 1; -+ cl->value[i] = '\0'; -+ } -+ } -+ -+ return cl; -+ } -+ -+ /* -+ * This function returns if two strings are the same quote string. -+ * The call is not symmetric. cl must preceed the line nl. This function -+ * should be called for comparing the last part of cl and nl. -+ */ -+ int -+ strcmp_qs(valuecl, valuenl) -+ char *valuecl; -+ char *valuenl; -+ { -+ int j; -+ -+ for (j = 0; valuecl[j] && (valuecl[j] == valuenl[j]); j++); -+ return !strcmp(valuecl, valuenl) -+ || (valuenl[j] && value_is_space(valuenl+j) -+ && value_is_space(valuecl+j) -+ && strlenis(valuecl+j) >= strlenis(valuenl+j)) -+ || (!valuenl[j] && value_is_space(valuecl+j)); -+ } -+ -+ int -+ count_levels_qstring(cl) -+ QSTRING_S *cl; -+ { -+ int count; -+ for (count = 0; cl ; count++, cl = cl->next); -+ -+ return count; -+ } -+ -+ /* -+ * This function returns the number of agreements between -+ * cl and nl. The call is not symmetric. cl must be the line -+ * preceding nl. -+ */ -+ int -+ same_qstring(cl,nl) -+ QSTRING_S *cl; -+ QSTRING_S *nl; -+ { -+ int same = 0, done = 0; -+ -+ for (;cl && nl && !done; cl = cl->next, nl = nl->next) -+ if ((cl->qstype == nl->qstype) && (!strcmp(cl->value, nl->value) -+ || ((!cl->next) && strcmp_qs(cl->value, nl->value)))) -+ same++; -+ else -+ done++; -+ -+ return same; -+ } -+ -+ QSTRING_S * -+ trim_qs_from_cl(cl, nl, pl) -+ QSTRING_S *cl; -+ QSTRING_S *nl; -+ QSTRING_S *pl; -+ { -+ QSTRING_S *cqstring = pl ? pl : nl; -+ QSTRING_S *tl = pl ? pl : nl; -+ int p, c; -+ -+ if (qstring_is_normal(tl)) -+ return tl; -+ -+ p = same_qstring(pl ? pl : cl, pl ? cl : nl); -+ -+ for (c = 1; c < p; c++, cl = cl->next, tl = tl->next); -+ -+ /* -+ * cl->next and tl->next differ, it may be because cl->next does not -+ * exist or tl->next does not exist or simply both exist but are -+ * different. In this last case, it may be that cl->next->value is made -+ * of spaces. If this is the case, tl advances once more. -+ */ -+ -+ if (tl->next){ -+ if (cl && cl->next && value_is_space(cl->next->value)) -+ tl = tl->next; -+ if (tl->next) -+ free_qs(&(tl->next)); -+ } -+ -+ if (!p) -+ free_qs(&cqstring); -+ -+ return cqstring; -+ } -+ -+ /* This function trims cl so that it returns a real quote string based -+ * on information gathered from the previous and next lines. pl and cl are -+ * also trimmed, but that is done in another function, not here. -+ */ -+ QSTRING_S * -+ fix_qstring(cl, nl, pl) -+ QSTRING_S *cl; -+ QSTRING_S *nl; -+ QSTRING_S *pl; -+ { -+ QSTRING_S *cqstring = cl, *nqstring = nl, *pqstring = pl; -+ int c, n; -+ -+ if (qstring_is_normal(cl)) -+ return cl; -+ -+ c = count_levels_qstring(cl); -+ n = same_qstring(cl,nl); -+ -+ if (!n){ /* no next line or no agreement with next line */ -+ int p = same_qstring(pl, cl); /* number of agreements between pl and cl */ -+ QSTRING_S *tl; /* test line */ -+ -+ /* -+ * Here p <= c, so either p < c or p == c. If p == c, we are done, -+ * and return cl. If not, there are two cases, either p == 0 or -+ * 0 < p < c. In the first case, we do not have enough evidence -+ * to return anything other than the normal part of cl, in the second -+ * case we can only return p levels of cl. -+ */ -+ -+ if (p == c) -+ tl = cqstring; -+ else{ -+ if (p){ -+ for (c = 1; c < p; c++) -+ cl = cl->next; -+ free_qs(&(cl->next)); -+ tl = cqstring; -+ } -+ else{ -+ int done = 0; -+ QSTRING_S *al = cl; /* another line */ -+ /* -+ * Ok, we reaelly don't have enough evidence to return anything, -+ * different from the normal part of cl, but it could be possible -+ * that we may want to accept the not-normal part, so we better -+ * make an extra test to determine what needs to be freed -+ */ -+ while (pl && cl && !strucmp(cl->value, pl->value)){ -+ cl = cl->next; -+ pl = pl->next; -+ } -+ if (pl && cl && strcmp_qs(pl->value, cl->value)) -+ cl = cl->next; /* next level differs only in spaces */ -+ while (!done){ -+ while (cl && cl->qstype == qsNormal) -+ cl = cl->next; -+ if (cl){ -+ if ((cl->qstype == qsString) -+ && (cl->value[strlen(cl->value) - 1] == '>')) -+ cl = cl->next; -+ else done++; -+ } -+ else done++; -+ } -+ if (al == cl){ -+ free_qs(&(cl)); -+ tl = cl; -+ } -+ else { -+ while (al && (al->next != cl)) -+ al = al->next; -+ cl = al; -+ if (cl && cl->next) -+ free_qs(&(cl->next)); -+ tl = cqstring; -+ } -+ } -+ } -+ return tl; -+ } -+ if (n + 1 < c){ /* if there are not enough agreements */ -+ int p = same_qstring(pl, cl); /* number of agreement between pl and cl */ -+ QSTRING_S *tl; /* test line */ -+ -+ /* -+ * There's no way we can use cl in this case, but we can use -+ * part of cl, this is if pl does not have more agreements -+ * with cl. -+ */ -+ -+ if (p == c) -+ tl = cqstring; -+ else{ -+ int m = p < n ? n : p; -+ for (c = 1; c < m; c++){ -+ pl = pl ? pl->next : (QSTRING_S *) NULL; -+ nl = nl ? nl->next : (QSTRING_S *) NULL; -+ cl = cl->next; -+ } -+ if ((p == n) && pl && pl->next && nl && nl->next -+ && ((cl->next->qstype == pl->next->qstype) -+ || (cl->next->qstype == nl->next->qstype)) -+ && (strcmp_qs(cl->next->value, pl->next->value) -+ || strcmp_qs(pl->next->value, cl->next->value) -+ || strcmp_qs(cl->next->value, nl->next->value) -+ || strcmp_qs(nl->next->value, cl->next->value))) -+ cl = cl->next; /* next level differs only in spaces */ -+ if (cl->next) -+ free_qs(&(cl->next)); -+ tl = cqstring; -+ } -+ return tl; -+ } -+ if (n + 1 == c){ -+ int p = same_qstring(pl, cl); -+ QSTRING_S *tl; /* test line */ -+ -+ /* -+ * p <= c, so p <= n+1, which means p < n + 1 or p == n + 1. -+ * If p < n + 1, then p <= n. -+ * so we have three possibilities: -+ * p == n + 1 or p == n or p < n. -+ * In the first case we copy p == n + 1 == c levels, in the second -+ * and third case we copy n levels, and check if we can copy the -+ * n + 1 == c level. -+ */ -+ -+ if (p == n + 1) /* p == c, in the above sense of c */ -+ tl = cl; /* use cl, this is enough evidence */ -+ else{ -+ for (c = 1; c < n; c++) -+ cl = cl->next; -+ /* -+ * Here c == n, we only have one more level of cl, and at least one -+ * more level of nl -+ */ -+ if (cl->next->qstype == qsNormal) -+ cl = cl->next; -+ if (cl->next) -+ free_qs(&(cl->next)); -+ tl = cqstring; -+ } -+ return tl; -+ } -+ if (n == c) /* Yeah!!! */ -+ return cqstring; -+ } -+ -+ /* -+ * This function flattens the quote string returned to us by is_quote. A -+ * crash in this function implies a bug elsewhere. -+ */ -+ void -+ flatten_qstring(qs, buff) -+ QSTRING_S *qs; -+ char *buff; -+ { -+ int i = 0, j; -+ -+ for (; qs; qs = qs->next) -+ for (j = 0; (qs->value[j]) && (buff[i++] = qs->value[j]); j++); -+ buff[i] = '\0'; -+ } -+ -+ /* -+ * Given a string, we return the position where the function thinks that -+ * the quote string is over, if you are ever thinking of fixing something, -+ * you got to the right place. Memory freed by caller. Experience shows -+ * that it only makes sense to initialize memory when we need it, not at -+ * the start of this function. -+ */ -+ QSTRING_S * -+ is_quote (qs,word, been_here) -+ char *qs; -+ char word[NSTRING]; -+ int been_here; -+ { -+ int i = 0, j, c, nxt, prev, finished = 0, offset; -+ QSTRING_S *qstring = (QSTRING_S *) NULL; -+ -+ if (!word || !word[0]) -+ return (QSTRING_S *) NULL; -+ -+ while (!finished){ -+ /* -+ * Before we apply our rules, let's advance past the quote string -+ * given by the user, this will avoid not recognition of the -+ * user's indent string and application of the arbitrary rules -+ * below. Notice that this step may bring bugs into this -+ * procedure, but these bugs will only appear if the indent string -+ * is really really strange and the text to be justified -+ * cooperates a lot too, so in general this will not be a problem. -+ * If you are concerned about this bug, simply remove the -+ * following lines after this comment and before the "switch" -+ * command below and use a more normal quote string!. -+ */ -+ i += advance_quote_string(qs, word, i); -+ if (!word[i]) /* went too far? */ -+ return qs_add(qs, word, qsNormal, 0, i, 0, 0); -+ -+ switch (c = now(word,i)){ -+ case NBSP: -+ case TAB : -+ case ' ' : { QSTRING_S *nextqs, *testqs = NULL; -+ int j; -+ -+ for (; ISspace((unsigned char) word[i]); i++); -+ nextqs = is_quote(qs,word+i, 1); -+ /* -+ * Merge qstring and nextqs, since this is an artificial -+ * separation, unless nextqs is of different type. -+ * What this means in practice is that if -+ * qs->qstype == qsNormal and qs->next != NULL, then -+ * qs->next->qstype != qsNormal. -+ * -+ * Can't use qs_add to merge because it could lead -+ * to an infinite loop (e.g a line "^ ^"). -+ */ -+ if (nextqs){ -+ if(nextqs->qstype == qsNormal){ -+ i += strlen(nextqs->value); -+ testqs = copy_qs(nextqs->next); -+ } -+ else -+ testqs = copy_qs(nextqs); -+ free_qs(&nextqs); -+ } -+ -+ qstring = (QSTRING_S *) malloc (sizeof(QSTRING_S)); -+ memset (qstring, 0, sizeof(QSTRING_S)); -+ -+ qstring->value = (char *) malloc((i+1)*sizeof(char)); -+ strncpy(qstring->value, word, i); -+ qstring->value[i] = '\0'; -+ qstring->qstype = qsNormal; -+ -+ qstring->next = testqs; -+ -+ return qstring; -+ } -+ break; -+ -+ case RPAREN: /* parenthesis ')' */ -+ if ((i != 0) || ((i == 0) && been_here)) -+ i++; -+ else -+ if (i == 0) -+ return qs_add(qs, word, qsChar, i, i, 1, 1); -+ else -+ finished++; -+ break; -+ -+ case ';': -+ case ':': /* colon */ -+ case '~': nxt = next(word,i); -+ if (is_tilde(c) && (nxt == '/')) -+ finished++; -+ else if (is_cquote(c) -+ || is_cquote(nxt) -+ || ((c != '~') && (nxt == RPAREN)) -+ || ((i != 0) && is_space(nxt)) -+ || is_cquote(prev = before(word,i)) -+ || (is_space(prev) && !is_tilde(c)) -+ || (is_tilde(c) && nxt != '/')) -+ i++; -+ else if (i == 0 && been_here) -+ return qs_add(qs, word, qsChar, i, i, 1, 1); -+ else -+ finished++; -+ break; -+ -+ case '<' : -+ case '=' : -+ case '-' : offset = is_cquote(nxt = next(word,i)) ? 2 -+ : ((nxt == c) -+ && is_cquote(next(word,i+1))) ? 3 : -1; -+ -+ if (offset > 0) -+ return qs_add(qs, word, qsString, i, i, offset, 1); -+ else -+ finished++; -+ break; -+ -+ case '[' : -+ case '+' : /* accept +>, *> */ -+ case '*' : if (is_rarrow(nxt = next(word, i)) || /* stars */ -+ (is_space(nxt) && is_rarrow(next(word,i+1)))) -+ i++; -+ else -+ finished++; -+ break; -+ -+ case '^' : -+ case '!' : -+ case '%' : -+ case '#' : if (next(word,i) != c) -+ return qs_add(qs, word, qsChar, i, i+1, 0, 1); -+ else -+ finished++; -+ break; -+ -+ default: -+ if (is_cquote(c)) -+ i++; -+ else if (is_cletter(c)){ -+ for (j = i; (is_cletter(nxt = next(word,j)) || is_cnumber(nxt)) -+ && !(is_space(nxt));j++); -+ /* -+ * The whole reason why we are splitting the quote -+ * string is so that we will be able to accept quote -+ * strings that are strange in some way. Here we got to -+ * a point in which a quote string might exist, but it -+ * could be strange, so we need to create a "next" field -+ * for the quote string to warn us that something -+ * strange is coming. We need to confirm if this is a -+ * good choice later. For now we will let it pass. -+ */ -+ if (isaword(word,i,j) || isamailbox(word,i,j)){ -+ int offset; -+ QStrType qstype; -+ -+ offset = (is_cquote(c = next(word,j)) -+ || (c == RPAREN)) ? 2 -+ : ((is_space(c) -+ && is_cquote(next(word,j+1))) ? 3 : -1); -+ -+ qstype = (is_cquote(c) || (c == RPAREN)) -+ ? (is_qsword(c) ? qsWord : qsString) -+ : ((is_space(c) && is_cquote(next(word,j+1))) -+ ? (is_qsword(next(word,j+1)) -+ ? qsWord : qsString) -+ : qsString); -+ -+ /* -+ * qsWords are valid quote strings only when -+ * they are followed by text. -+ */ -+ if ((offset > 0) && (qstype == qsWord) && -+ !(allwd_after_qsword(now(word,j + offset)))) -+ offset = -1; -+ -+ if (offset > 0) -+ return qs_add(qs, word, qstype, i, j, offset, 1); -+ } -+ finished++; -+ } -+ else{ -+ if(!forbidden(c)) -+ return qs_add(qs, word, qsChar, 0, 1, 0, 1); -+ else /* chao pescao */ -+ finished++; -+ } -+ break; -+ } /* End Switch */ -+ } /* End while */ -+ -+ if (i > 0) -+ qstring = qs_add(qs, word, qsNormal, 0, i, 0, 0); -+ -+ return qstring; -+ } -+ -+ void -+ linencpy(word, l, buflen) -+ char word[NSTRING]; -+ LINE *l; -+ int buflen; -+ { -+ int i = 0; -+ for (;(i < buflen) && (i < llength(l)) && (word[i] = (char)lgetc(l,i).c); i++); -+ word[buflen - 1] = '\0'; -+ } -+ -+ -+ -+ int -+ isaword(word,i,j) -+ char word[NSTRING]; -+ int i; -+ int j; -+ { -+ return i <= j && is_cletter(word[i]) ? -+ (i < j ? isaword(word,i+1,j) : 1) : 0; -+ } -+ -+ int -+ isamailbox(word,i,j) -+ char word[NSTRING]; -+ int i; -+ int j; -+ { -+ return i <= j && (is_cletter(word[i]) || is_a_digit(word[i]) -+ || word[i] == '.') -+ ? (i < j ? isamailbox(word,i+1,j) : 1) : 0; -+ } -+ -+ -+ /* -+ * This function returns the quote string as a structure. In this way we -+ have two ways to get the quote string: as a char * or as a QSTRING_S * -+ directly. -+ */ -+ QSTRING_S * -+ qs_quote_match(q, l, buf, buflen, raw) -+ char *q; -+ LINE *l; -+ char *buf; -+ int buflen; -+ int raw; -+ { -+ char GLine[NSTRING] = {'\0'}, NLine[NSTRING] = {'\0'}, -+ PLine[NSTRING] = {'\0'}; -+ LINE *nl = l != curbp->b_linep ? lforw(l) : NULL; -+ LINE *pl = lback(l) != curbp->b_linep ? lback(l) : NULL; -+ -+ if (nl) -+ linencpy(NLine, nl, NSTRING); -+ -+ if (pl) -+ linencpy(PLine, pl, NSTRING); -+ -+ linencpy(GLine, l, NSTRING); -+ -+ return do_quote_match(q,GLine, NLine, PLine, raw); -+ } - - /* -! * Return number of quotes if whatever starts the line matches the quote -! * string - */ -! quote_match(q, l, buf, buflen, raw) - char *q; - LINE *l; - char *buf; - int buflen; -+ int raw; - { -! QSTRING_S *qs; - -! qs = qs_quote_match(q, l, buf, buflen, raw); -! flatten_qstring(qs, buf); -! if (qs) -! free_qs(&qs); -! -! return buf && buf[0] ? strlen(buf) : 0; -! } -! -! /* -! This routine removes the last part that is qsword or qschar that is not -! followed by a normal part. This means that if a qsword or qschar is -! followed by a qsnormal (or qsstring), we accept the qsword (or qschar) -! as part of a quote string. -! */ -! -! QSTRING_S * -! remove_qsword(cl) -! QSTRING_S *cl; -! { -! QSTRING_S *np = cl; -! QSTRING_S *cp = np; /* this variable trails cl */ -! -! while(1){ -! while (cl && cl->qstype == qsNormal) -! cl = cl->next; -! -! if (cl){ -! if (((cl->qstype == qsWord) || (cl->qstype == qsChar)) -! && !exists_good_part(cl)){ -! if (np == cl) /* qsword or qschar at the beginning */ -! free_qs(&cp); -! else{ -! while (np->next != cl) -! np = np->next; -! free_qs(&(np->next)); -! } -! break; -! } -! else -! cl = cl->next; -! } -! else -! break; -! } -! return cp; -! } -! -! int -! exists_good_part (cl) -! QSTRING_S *cl; -! { -! return (cl ? (((cl->qstype != qsWord) && (cl->qstype != qsChar) -! && !value_is_space(cl->value)) -! ? 1 -! : exists_good_part(cl->next)) -! : 0); -! } -! -! -! QSTRING_S * -! do_quote_match(q,GLine, NLine, PLine, raw) -! char *q; -! char GLine[NSTRING]; -! char NLine[NSTRING]; -! char PLine[NSTRING]; -! int raw; -! { -! QSTRING_S *cl, *nl = NULL, *pl = NULL; -! int c, n, p,i, j, NewC, NewN, clength, same = 0; -! char nbuf[NSTRING], pbuf[NSTRING], buf[NSTRING]; -! int emptynl = 0, emptypl = 0; -! -! cl = is_quote(q,GLine, 0); /* Current or Given line */ -! -! if (!cl) /* if nothing in, nothing out */ -! return cl; -! -! if (NLine && NLine[0]) -! nl = is_quote(q,NLine, 0); /* Next Line */ -! if (PLine && PLine[0]) -! pl = is_quote(q,PLine, 0); /* Previous Line */ -! -! /* -! * If there's nothing in the preceeding or following line -! * there is not enough information to accept it or discard it. In this -! * case it's likely to be an isolated line, so we better accept it -! * if it does not look like a word. */ -! -! flatten_qstring(pl, pbuf); -! emptypl = (!PLine || !PLine[0] || -! (pl && value_is_space(pbuf)) && !PLine[strlen(pbuf)]) ? 1 : 0; -! if (emptypl){ -! flatten_qstring(nl, nbuf); -! emptynl = (!NLine || !NLine[0] || -! (nl && value_is_space(nbuf) && !NLine[strlen(nbuf)])) ? 1 : 0; -! if (emptynl){ -! cl = remove_qsword(cl); -! cl = qs_remove_trailing_spaces(cl); -! free_qs(&nl); -! free_qs(&pl); -! -! return cl; -! } -! } -! -! /* -! * If either cl, nl or pl contain suspicious characters that may make -! * them (or not) be quote strings, we need to fix them, so that the -! * next pass will be done correctly. -! */ -! -! cl = fix_qstring(cl, nl, pl); -! nl = trim_qs_from_cl(cl, nl, NULL); -! pl = trim_qs_from_cl(cl, NULL, pl); -! flatten_qstring(cl, buf); -! flatten_qstring(nl, nbuf); -! flatten_qstring(pl, pbuf); -! -! if (raw){ /* if we are asked for the raw string */ -! free_qs(&nl); -! free_qs(&pl); -! -! return cl; /* return now! */ -! } -! /* -! * Once upon a time, is_quote used to return the length of the quote -! * string that it had found. One day, not long ago, black hand came -! * and changed all that, and made is_quote return a quote string -! * divided in several fields, making the algorithm much more -! * complicated. Fortunately black hand left a few comments in the -! * source code to make it more understandable. Because of this change -! * we need to compute the lengths of the quote strings separately -! */ -! c = buf && buf[0] ? strlen(buf) : 0; -! n = nbuf && nbuf[0] ? strlen(nbuf) : 0; -! p = pbuf && pbuf[0] ? strlen(pbuf) : 0; -! -! /* -! * When quote strings contain only blank spaces (ascii code 32) the -! * above count is equal to the length of the quote string, but if -! * there are TABS, the length of the quote string as seen by the user -! * is different than the number that was just computed. Because of -! * this we demand a recount (hmm.. unless you are in Florida, where -! * recounts are forbidden) -! */ -! -! NewC = strlenis(buf); -! NewN = strlenis(nbuf); -! -! /* -! * For paragraphs with spaces in the first line, but no space in the -! * quote string of the second line, we make sure we choose the quote -! * string without a space at the end of it. -! */ -! if ((NLine && !NLine[0]) -! && ((PLine && !PLine[0]) -! || (((same = same_qstring(pl, cl)) != 0) -! && (same != count_levels_qstring(cl))))) -! cl = qs_remove_trailing_spaces(cl); -! else -! if (NewC > NewN){ -! for (j = 0; (j < n) && (GLine[j] == NLine[j]); j++); -! clength = j; -! if (j < n){ /* see if buf and nbuf are padded with spaces and tabs */ -! for (i = clength; i < n && ISspace((unsigned char)NLine[i]); i++); -! if (i == n){ -! for (i = clength; i < c && ISspace((unsigned char)GLine[i]); i++); -! if (i == c) -! j = n; -! } - } -! if (j == n){ -! for (j = clength; j < c && ISspace((unsigned char)GLine[j]); j++); -! if (j == c){ -! -! /* -! * If we get here, it means that the current line has the same -! * quote string (visually) than the next line, but both of them -! * are padded with different amount of TABS or spaces at the end. -! * The current line (GLine) has more spaces/TABs than the next -! * line. This is the typical situation that is found at the -! * begining of a paragraph. We need to check this, however, by -! * checking the previous line. This avoids that we confuse -! * ourselves with being in the last line of a paragraph. -! */ -! -! for (j = 0; (j < p) && (GLine[j] == PLine[j]); j++); -! if (((p == c) && ((j != p) && NLine[n])) -! || ((p != c) && NLine[n])){ -! free_qs(&cl); -! cl = copy_qs(nl); -! } -! } -! } -! } -! -! free_qs(&nl); -! free_qs(&pl); -! -! return cl; -! } -! -! /* -! * Given a line, an initial position, and a quote string, we advance the -! * current line past the quote string, including arbitraty spaces -! * contained in the line, except that it removes trailing spaces. We do -! * not handle TABs, if any, contained in the quote string. At least not -! * yet. -! * -! * Arguments: q - quote string -! * l - a line to process -! * i - position in the line to start processing. i = 0 is the -! * begining of that line. -! */ -! int -! advance_quote_string(q, l, i) -! char *q; -! char l[NSTRING]; -! int i; -! { -! int n = 0, j = 0, is = 0, es = 0; -! int k, m, p, adv; -! char qs[NSTRING] = {'\0'}; -! -! if(!q || !*q) -! return(0); -! -! for (p = strlen(q); (p > 0) && (q[p - 1] == ' '); p--, es++); -! if (!p){ /* string contains only spaces */ -! for (k = 0; l[i + k] == ' '; k++); -! k -= k % es; -! return k; -! } -! for (is = 0; q[is] == ' '; is++); /* count initial spaces */ -! for (m = 0 ; is + m < p ; m++) -! qs[m] = q[is + m]; /* qs = quote string without any space at the end */ -! /* advance as many spaces as there are at the begining */ -! for (k = 0; l[i + j] == ' '; k++, j++); -! /* now find the visible string in the line */ -! for (m = 0; qs[m] && l[i + j] == qs[m]; m++, j++); -! if (!qs[m]){ /* no match */ -! /* -! * So far we have advanced at least "is" spaces, plus the visible -! * string "qs". Now we need to advance the trailing number of -! * spaces "es". If we can do that, we have found the quote string. -! */ -! for (p = 0; l[i + j + p] == ' '; p++); -! adv = advance_quote_string(q, l, i + j + ((p < es) ? p : es)); -! n = ((p < es) ? 0 : es) + k + m + adv; - } -! return n; - } - -+ /* -+ * This function returns the effective length in screen of the quote -+ * string. If the string contains a TAB character, it is added here, if -+ * not, the length returned is the length of the string -+ */ -+ -+ int -+ strlenis(qstr) -+ char *qstr; -+ { -+ int i, rv = 0; -+ -+ if (qstr && *qstr){ -+ for (i = 0; qstr[i]; i++) -+ rv += ((qstr[i] == TAB) ? (~rv & 0x07) + 1 : 1); -+ } -+ return rv; -+ } - - /* Justify the entire buffer instead of just a paragraph */ - fillbuf(f, n) -*************** -*** 475,485 **** - int f, n; /* deFault flag and Numeric argument */ - - { -! int i, j, c, qlen, word[NSTRING], same_word, -! spaces, word_len, line_len, line_last, qn; -! char *qstr, qstr2[NSTRING]; - LINE *eopline; - REGION region; - - if(curbp->b_mode&MDVIEW){ /* don't allow this command if */ - return(rdonly()); /* we are in read only mode */ ---- 1491,1503 ---- - int f, n; /* deFault flag and Numeric argument */ - - { -! int i = 0, j, c, qlen, word[NSTRING], same_word, qlenis, -! spaces, word_len, line_len, line_last, qn, indlen, qi, pqi; -! char *qstr, qstr2[NSTRING], tbuf[NSTRING], ind_str[NSTRING], -! *qstrfl, qstrfl2[NSTRING], quoid[NSTRING]; - LINE *eopline; - REGION region; -+ QSTRING_S *tl; - - if(curbp->b_mode&MDVIEW){ /* don't allow this command if */ - return(rdonly()); /* we are in read only mode */ -*************** -*** 499,512 **** - - /* and back to the beginning of the paragraph */ - gotobop(FALSE, 1); - -! /* determine if we're justifying quoted text or not */ - qstr = ((glo_quote_str || (Pmaster && Pmaster->quote_str)) -! && quote_match(glo_quote_str ? glo_quote_str -! : Pmaster->quote_str, -! curwp->w_dotp, qstr2, NSTRING) -! && *qstr2) ? qstr2 : NULL; -! qlen = qstr ? strlen(qstr) : 0; - - /* let yank() know that it may be restoring a paragraph */ - thisflag |= CFFILL; ---- 1517,1602 ---- - - /* and back to the beginning of the paragraph */ - gotobop(FALSE, 1); -+ setimark(FALSE, 1); /* Remember this spot in case we unjustify */ - -! /* -! * When a paragraph has special indentation, we will get two quote -! * strings. One from the first line of the paragraph, and one from -! * the last line of the paragraph. We will need to use both when -! * we justify. -! * -! * Here's a model of what we will code: -! * -! * +-------+-------+-+-----+ -! * | qstrfl|ind_str|X| text| -! * +-----+-+-------+-+-----+ -! * | qstr| *(space)|X| text| -! * +-----+---------+-+-----+ -! * -! * Here X represents 1 space if it exists after ind_str and -! * "*(space)" represent a variable amount of space that is put there -! * to pad text so that it will align correctly when justified. -! */ -! indlen = indent_match((glo_quote_str || (Pmaster && Pmaster->quote_str)) -! ? (glo_quote_str ? glo_quote_str : Pmaster->quote_str) -! : "", curwp->w_dotp, ind_str, NSTRING, 0); -! qstrfl = (quote_match((glo_quote_str || (Pmaster && Pmaster->quote_str)) -! ? (glo_quote_str ? glo_quote_str : Pmaster->quote_str) -! : ">", curwp->w_dotp, qstrfl2, NSTRING,0) -! && *qstrfl2) ? qstrfl2 : NULL; -! if (qstrfl){ -! if (glo_quote_str || (Pmaster && Pmaster->quote_str)) -! for (; (i < NSTRING) && (quoid[i] = qstrfl[i]); i++); -! else{ -! for (; (i < NSTRING) && qstrfl[i] && (quoid[i] = ' '); i++); -! qstrfl[0] = '\0'; -! } -! } -! if (indlen) -! for (j = 0; ((i + j) < NSTRING) && (quoid[i] = ind_str[j]); i++,j++); -! quoid[i] = '\0'; -! qi = quoid && quoid[0] ? strlen(quoid) : 0; -! if (indlen) /* strip trailing spaces */ -! for (;ISspace((unsigned char) quoid[qi - 1]); qi--); -! quoid[qi] = '\0'; /* we have closed quoid at "X" in the first line */ -! -! if (strlenis(quoid) > fillcol) -! return FALSE; /* Too wide, we can't justify this! */ -! -! /* determine if we're justifying quoted text or not */ - qstr = ((glo_quote_str || (Pmaster && Pmaster->quote_str)) -! && quote_match(glo_quote_str ? glo_quote_str : -! Pmaster->quote_str, -! curwp->w_dotp, qstr2, NSTRING, 0) -! && *qstr2) ? qstr2 : NULL; -! /* In some situations, like in the following paragraph, qstr can be non -! * empty as returned above, when indeed it is empty. Fix it!. -! -! * Item #1 -! * Item #2 -! continuation of item #2 -! */ -! if (qstr && indlen){ -! for (i = strlen(qstr) - 1; ISspace((unsigned char) qstr[i]); i--); -! qstr[i + 1] = '\0'; -! } -! -! qlen = qstr ? strlen(qstr) : 0; -! qlenis = qstr ? strlenis(qstr) : 0; -! -! /* -! * Compare effective lengths of quoid and qstr to decide how much space -! * we need to use to pad with. -! */ -! if (indlen && ((j = strlenis(quoid) - strlenis(qstr)) > 0)){ -! pqi = qstr ? strlen(qstr) : 0; -! for (i = 0; (i < j) && (qstr2[pqi + i] = ' '); i++); -! if (ISspace((unsigned char) ind_str[indlen - 1])) -! qstr2[pqi + i++] = ' '; -! qstr2[pqi + i] = '\0'; -! if (!qstr) -! qstr = qstr2; -! } - - /* let yank() know that it may be restoring a paragraph */ - thisflag |= CFFILL; -*************** -*** 524,541 **** - return(FALSE); - - /* Now insert it back wrapped */ -! spaces = word_len = line_len = same_word = 0; - - /* Beginning with leading quoting... */ -! if(qstr){ -! while(qstr[line_len]) -! linsert(1, qstr[line_len++]); - - line_last = ' '; /* no word-flush space! */ - } - - /* ...and leading white space */ -! for(i = qlen; (c = fremove(i)) == ' ' || c == TAB; i++){ - linsert(1, line_last = c); - line_len += ((c == TAB) ? (~line_len & 0x07) + 1 : 1); - } ---- 1614,1651 ---- - return(FALSE); - - /* Now insert it back wrapped */ -! spaces = word_len = line_len = same_word = i = 0; - - /* Beginning with leading quoting... */ -! if(qstrfl){ -! while((tbuf[line_len] = qstrfl[line_len]) == fremove(line_len)) -! linsert(1, qstrfl[line_len++]); -! /* -! * The only way that at the end of the above loop we don't have -! * line_len == qlen is that there are trailing spaces or TABS -! * which could not be accounted in the qstr in is_quote or other -! * functions before we got here. Now we enter the common part of -! * the quote string in the first line and the rest is only spaces -! * (or TABS) that need to be entered, which are left to the loop -! * following this "if" statement -! */ -! i = line_len; /* start next loop from here */ -! tbuf[line_len] = '\0'; /* closing tbuf... */ -! line_len = strlenis(tbuf); /* we demand a recount! */ -! line_last = ' '; /* no word-flush space! */ -! } - -+ /* ...followed by the indent string, if any */ -+ if (indlen){ -+ for (i, j = 0; (c = fremove(i)) && ind_str[j]; i++, j++){ -+ linsert(1, line_last = c); -+ line_len += ((c == TAB) ? (~line_len & 0x07) + 1 : 1); -+ } - line_last = ' '; /* no word-flush space! */ - } - - /* ...and leading white space */ -! for(i; (c = fremove(i)) == ' ' || c == TAB; i++){ - linsert(1, line_last = c); - line_len += ((c == TAB) ? (~line_len & 0x07) + 1 : 1); - } -*************** -*** 558,572 **** - - default : - if(spaces){ /* flush word? */ -! if((line_len - qlen > 0) - && line_len + word_len + 1 > fillcol -! && ((isspace((unsigned char)line_last)) - || (linsert(1, ' '))) - && (line_len = fpnewline(qstr))) - line_last = ' '; /* no word-flush space! */ - - if(word_len){ /* word to write? */ -! if(line_len && !isspace((unsigned char) line_last)){ - linsert(1, ' '); /* need padding? */ - line_len++; - } ---- 1668,1682 ---- - - default : - if(spaces){ /* flush word? */ -! if((line_len - qlenis > 0) - && line_len + word_len + 1 > fillcol -! && ((ISspace((unsigned char)line_last)) - || (linsert(1, ' '))) - && (line_len = fpnewline(qstr))) - line_last = ' '; /* no word-flush space! */ - - if(word_len){ /* word to write? */ -! if(line_len && !ISspace((unsigned char) line_last)){ - linsert(1, ' '); /* need padding? */ - line_len++; - } -*************** -*** 588,595 **** - - if(word_len + 1 >= NSTRING){ - /* Magic! Fake that we output a wrapped word */ -! if((line_len - qlen > 0) && !same_word++){ -! if(!isspace((unsigned char) line_last)) - linsert(1, ' '); - line_len = fpnewline(qstr); - } ---- 1698,1705 ---- - - if(word_len + 1 >= NSTRING){ - /* Magic! Fake that we output a wrapped word */ -! if((line_len - qlenis > 0) && !same_word++){ -! if(!ISspace((unsigned char) line_last)) - linsert(1, ' '); - line_len = fpnewline(qstr); - } -*************** -*** 608,619 **** - } - - if(word_len){ -! if((line_len - qlen > 0) && (line_len + word_len + 1 > fillcol)){ -! if(!isspace((unsigned char) line_last)) - linsert(1, ' '); -! (void) fpnewline(qstr); - } -! else if(line_len && !isspace((unsigned char) line_last)) - linsert(1, ' '); - - for(j = 0; j < word_len; j++) ---- 1718,1730 ---- - } - - if(word_len){ -! if((line_len - qlenis > 0) && (line_len + word_len + 1 > fillcol)){ -! if(!ISspace((unsigned char) line_last)) - linsert(1, ' '); -! if (line_len && (line_len != qlenis)) -! (void) fpnewline(qstr); - } -! else if(line_len && !ISspace((unsigned char) line_last)) - linsert(1, ' '); - - for(j = 0; j < word_len; j++) -*************** -*** 640,644 **** ---- 1751,1885 ---- - for(len = 0; quote && *quote; quote++, len++) - linsert(1, *quote); - -+ quote -= len; /* go back */ -+ len = strlenis(quote); /* and recount */ - return(len); - } -+ -+ int -+ is_indent (word, plb) -+ char word[NSTRING]; -+ int plb; -+ { -+ int i = 0, finished = 0, c, nxt, j, k, digit = 0, bdigits = -1; -+ -+ if (!word || !word[0]) -+ return i; -+ -+ for (i = 0, j = 0; ISspace((unsigned char) word[i]); i++, j++); -+ while ((i < NSTRING - 2) && !finished){ -+ switch (c = now(word,i)){ -+ case NBSP: -+ case TAB : -+ case ' ' : for (; ISspace((unsigned char )word[i]); i++); -+ if (!is_indent_char(now(word,i))) -+ finished++; -+ break; -+ -+ case '+' : -+ case '.' : -+ case ']' : -+ case '*' : -+ case '}' : -+ case '-' : -+ case RPAREN: -+ nxt = next(word,i); -+ if (((c == '.') && allowed_after_period(nxt)) -+ || ((c == '*') && allowed_after_star(nxt)) -+ || ((c == '}') && allowed_after_braces(nxt)) -+ || ((c == '-') && allowed_after_dash(nxt)) -+ || ((c == '+') && allowed_after_dash(nxt)) -+ || ((c == RPAREN) && allowed_after_parenth(nxt)) -+ || ((c == ']') && allowed_after_parenth(nxt))) -+ i++; -+ else -+ finished++; -+ break; -+ -+ default : if (is_a_digit(c) && plb){ -+ if (bdigits < 0) -+ bdigits = i; /* first digit */ -+ for (k = i; is_a_digit(now(word,k)); k++); -+ if (k - bdigits > 2){ /* more than 2 digits? */ -+ i = bdigits; /* too many! */ -+ finished++; -+ } -+ else{ -+ if(allowed_after_digit(now(word,k),word,k)) -+ i = k; -+ else{ -+ i = bdigits; -+ finished++; -+ } -+ } -+ } -+ else -+ finished++; -+ break; -+ } -+ } -+ if (i == j) -+ i = 0; /* there must be something more than spaces in an indent string */ -+ return i; -+ } -+ -+ -+ /* -+ * If there is an indent string this function returns -+ * its length -+ */ -+ int -+ indent_match(q, l, buf, buflen, raw) -+ char *q; -+ LINE *l; -+ char *buf; -+ int buflen; -+ int raw; -+ { -+ char GLine[NSTRING] = {0}; -+ int i, j, k, plb; -+ -+ k = quote_match(q,l, buf, buflen, raw); -+ -+ linencpy(GLine, l, NSTRING); -+ -+ plb = (lback(l) != curbp->b_linep) ? lisblank(lback(l)) : 1; -+ if (!plb){ -+ i = llength(lback(l)) - 1; -+ for (; i >= 0 && ISspace((unsigned char)lgetc(lback(l), i).c); i--); -+ if (EOLchar(lgetc(lback(l), i).c)) -+ plb++; -+ } -+ -+ i = is_indent(GLine+k, plb); -+ -+ for (j = 0; (j < i) && (buf[j] = GLine[j + k]); j++); -+ buf[j] = '\0'; -+ -+ return i; -+ } -+ -+ deletepara(f, n) /* Delete the current paragraph */ -+ -+ int f, n; /* deFault flag and Numeric argument */ -+ -+ { -+ if(curbp->b_mode&MDVIEW){ /* don't allow this command if */ -+ return(rdonly()); /* we are in read only mode */ -+ } -+ -+ if(!lisblank(curwp->w_dotp)) -+ gotobop(FALSE, 1); -+ -+ curwp->w_markp = curwp->w_dotp; -+ curwp->w_marko = curwp->w_doto; -+ -+ gotoeop(FALSE, 1); -+ if (curwp->w_dotp != curbp->b_linep){ /* if we are not at the end of buffer */ -+ curwp->w_dotp = lforw(curwp->w_dotp); /* get one more line */ -+ curwp->w_doto = 0; /* but only the beginning */ -+ } -+ killregion(f,n); -+ -+ return(TRUE); -+ } -diff -rc pine4.63/pine/addrbook.c pine4.63.I.USE/pine/addrbook.c -*** pine4.63/pine/addrbook.c Tue Apr 26 15:15:46 2005 ---- pine4.63.I.USE/pine/addrbook.c Thu May 19 19:57:32 2005 -*************** -*** 6658,6667 **** - *warped; - { - int find_result, rc, flags; - static char search_string[MAX_SEARCH + 1] = { '\0' }; - char prompt[MAX_SEARCH + 50], nsearch_string[MAX_SEARCH+1]; - HelpType help; -! ESCKEY_S ekey[4]; - PerAddrBook *pab; - long nl; - ---- 6658,6668 ---- - *warped; - { - int find_result, rc, flags; -+ static char last_search_string[MAX_SEARCH + 1] = { '\0' }; - static char search_string[MAX_SEARCH + 1] = { '\0' }; - char prompt[MAX_SEARCH + 50], nsearch_string[MAX_SEARCH+1]; - HelpType help; -! ESCKEY_S ekey[5]; - PerAddrBook *pab; - long nl; - -*************** -*** 6676,6692 **** - ekey[0].name = ""; - ekey[0].label = ""; - -! ekey[1].ch = ctrl('Y'); -! ekey[1].rval = 10; -! ekey[1].name = "^Y"; -! ekey[1].label = "First Adr"; -! -! ekey[2].ch = ctrl('V'); -! ekey[2].rval = 11; -! ekey[2].name = "^V"; -! ekey[2].label = "Last Adr"; - -! ekey[3].ch = -1; - - flags = OE_APPEND_CURRENT | OE_KEEP_TRAILING_SPACE; - while(1){ ---- 6677,6698 ---- - ekey[0].name = ""; - ekey[0].label = ""; - -! ekey[1].ch = ctrl('N'); -! ekey[1].rval = 9; -! ekey[1].name = "^N"; -! ekey[1].label = "Ins Pat"; -! -! ekey[2].ch = ctrl('Y'); -! ekey[2].rval = 10; -! ekey[2].name = "^Y"; -! ekey[2].label = "First Adr"; -! -! ekey[3].ch = ctrl('V'); -! ekey[3].rval = 11; -! ekey[3].name = "^V"; -! ekey[3].label = "Last Adr"; - -! ekey[4].ch = -1; - - flags = OE_APPEND_CURRENT | OE_KEEP_TRAILING_SPACE; - while(1){ -*************** -*** 6697,6702 **** ---- 6703,6711 ---- - help = help == NO_HELP ? h_oe_searchab : NO_HELP; - continue; - } -+ else if(rc == 9) -+ insert_pattern_in_string(nsearch_string, last_search_string -+ , MAX_SEARCH); - else if(rc == 10){ - *warped = 1; - warp_to_beginning(); /* go to top of addrbooks */ -*************** -*** 6724,6730 **** - } - } - -! if(rc != 4) - break; - } - ---- 6733,6739 ---- - } - } - -! if(rc != 4 && rc != 9) - break; - } - -*************** -*** 6737,6742 **** ---- 6746,6754 ---- - search_string[sizeof(search_string)-1] = '\0'; - } - -+ strncpy(last_search_string, nsearch_string, sizeof(last_search_string)); -+ last_search_string[sizeof(last_search_string)-1] = '\0'; -+ - find_result = find_in_book(cur_line, search_string, new_line, wrapped); - - if(*wrapped == 1) -diff -rc pine4.63/pine/adrbkcmd.c pine4.63.I.USE/pine/adrbkcmd.c -*** pine4.63/pine/adrbkcmd.c Thu Mar 31 09:29:09 2005 ---- pine4.63.I.USE/pine/adrbkcmd.c Thu May 19 19:57:26 2005 -*************** -*** 3866,3871 **** ---- 3866,3873 ---- - * won't do anything, but will cause compose_mail to think there's - * already a role so that it won't try to confirm the default. - */ -+ if (ps_global->role) -+ fs_give((void **)&ps_global->role); - if(role) - role = copy_action(role); - else{ -*************** -*** 3873,3878 **** ---- 3875,3881 ---- - memset((void *)role, 0, sizeof(*role)); - role->nick = cpystr("Default Role"); - } -+ ps_global->role = cpystr(role->nick); - } - - compose_mail(addr, fcc, role, NULL, NULL); -diff -rc pine4.63/pine/args.c pine4.63.I.USE/pine/args.c -*** pine4.63/pine/args.c Wed Mar 9 17:10:34 2005 ---- pine4.63.I.USE/pine/args.c Thu May 19 19:57:27 2005 -*************** -*** 74,79 **** ---- 74,80 ---- - char args_err_non_abs_passfile[] = "argument to \"-passfile\" should be fully-qualified"; - char args_err_missing_lu[] = "missing argument for option \"-create_lu\"\nUsage: pine -create_lu <addrbook_file> <addrbook_sort_type>"; - char args_err_missing_sort[] = "missing argument for option \"-sort\""; -+ char args_err_missing_thread_sort[] = "missing argument for option \"-threadsort\""; - char args_err_missing_flag_arg[] = "missing argument for flag \"%c\""; - char args_err_missing_flag_num[] = "Non numeric argument for flag \"%c\""; - char args_err_missing_debug_num[] = "Non numeric argument for \"%s\""; -*************** -*** 117,122 **** ---- 118,124 ---- - " -z \t\tSuspend - allow use of ^Z suspension", - " -r \t\tRestricted - can only send mail to oneself", - " -sort <sort>\tSort - Specify sort order of folder:", -+ " -threadsort <sort>\tSort - Specify sort order of thread index screen:", - "\t\t subject, arrival, date, from, size, /reverse", - " -i\t\tIndex - Go directly to index, bypassing main menu", - " -I <keystroke_list> Initial keystrokes to be executed", -*************** -*** 202,207 **** ---- 204,210 ---- - char *cmd_list = NULL; - char *debug_str = NULL; - char *sort = NULL; -+ char *threadsort = NULL; - char *pinerc_file = NULL; - char *addrbook_file = NULL; - char *ab_sort_descrip = NULL; -*************** -*** 389,394 **** ---- 392,409 ---- - - goto Loop; - } -+ else if(strcmp(*av, "threadsort") == 0){ -+ if(--ac){ -+ threadsort = *++av; -+ COM_THREAD_SORT_KEY = cpystr(threadsort); -+ } -+ else{ -+ display_args_err(args_err_missing_thread_sort, NULL, 1); -+ ++usage; -+ } -+ -+ goto Loop; -+ } - else if(strcmp(*av, "url") == 0){ - if(args->action == aaFolder && !args->data.folder){ - args->action = aaURL; -*************** -*** 496,501 **** ---- 511,522 ---- - do_version = 1; - goto Loop; - } -+ else if(strcmp(*av, "subject") == 0){ -+ if(--ac){ -+ pine_state->subject = cpystr(*++av); -+ } -+ goto Loop; -+ } - #ifdef _WINDOWS - else if(strcmp(*av, "install") == 0){ - ps_global->install_flag = 1; -diff -rc pine4.63/pine/bldaddr.c pine4.63.I.USE/pine/bldaddr.c -*** pine4.63/pine/bldaddr.c Fri Mar 25 15:33:27 2005 ---- pine4.63.I.USE/pine/bldaddr.c Thu May 19 19:57:26 2005 -*************** -*** 2306,2313 **** - if(as.cur >= as.how_many_personals) - pab->type |= GLOBAL; - -! pab->access = adrbk_access(pab); -! - /* global address books are forced readonly */ - if(pab->type & GLOBAL && pab->access != NoAccess) - pab->access = ReadOnly; ---- 2306,2319 ---- - if(as.cur >= as.how_many_personals) - pab->type |= GLOBAL; - -! if(ps_global->mail_stream && -! ps_global->mail_stream->lock && (pab->type & REMOTE_VIA_IMAP)){ -! as.initialized = 0; -! pab->access = NoAccess; -! } -! else{ -! pab->access = adrbk_access(pab); -! } - /* global address books are forced readonly */ - if(pab->type & GLOBAL && pab->access != NoAccess) - pab->access = ReadOnly; -diff -rc pine4.63/pine/filter.c pine4.63.I.USE/pine/filter.c -*** pine4.63/pine/filter.c Thu Apr 7 11:00:56 2005 ---- pine4.63.I.USE/pine/filter.c Thu May 19 19:57:30 2005 -*************** -*** 204,209 **** ---- 204,213 ---- - error_description(errno))); - if(source == TmpFileStar) - (void)unlink(so->name); -+ if (ps_global->send_immediately){ -+ printf("%s : %s\n", so->name, error_description(errno)); -+ exit(1); -+ } - - fs_give((void **)&so->name); - fs_give((void **)&so); /* so freed & set to NULL */ -*************** -*** 6764,6769 **** ---- 6768,6778 ---- - margin_r, - indent; - char special[256]; -+ long curlinenum; /* current line number */ -+ int curqstrpos; /* current position in quote string */ -+ long linenum; /* line number */ -+ long qstrlen; /* multiples of 100 */ -+ char **qstrln; /* qstrln[i] = quote string line i - 1 */ - } WRAP_S; - - #define WRAP_MARG_L(F) (((WRAP_S *)(F)->opt)->margin_l) -*************** -*** 6798,6803 **** ---- 6807,6818 ---- - #define WRAP_COLOR(F) (((WRAP_S *)(F)->opt)->color) - #define WRAP_COLOR_SET(F) ((WRAP_COLOR(F)) && (WRAP_COLOR(F)->fg[0])) - #define WRAP_SPACES(F) (((WRAP_S *)(F)->opt)->spaces) -+ #define WRAP_CURLINE(F) (((WRAP_S *)(F)->opt)->curlinenum) -+ #define WRAP_CURPOS(F) (((WRAP_S *)(F)->opt)->curqstrpos) -+ #define WRAP_LINENUM(F) (((WRAP_S *)(F)->opt)->linenum) -+ #define WRAP_QSTRLEN(F) (((WRAP_S *)(F)->opt)->qstrlen) -+ #define WRAP_QSTRN(F) (((WRAP_S *)(F)->opt)->qstrln) -+ #define WRAP_QSTR(F, N) (((WRAP_S *)(F)->opt)->qstrln[(N)]) - #define WRAP_PUTC(F,C,V) { \ - if((F)->linep == WRAP_LASTC(F)){ \ - size_t offset = (F)->linep - (F)->line; \ -*************** -*** 6872,6877 **** ---- 6887,6894 ---- - case CCR : /* CRLF or CR in text ? */ - state = BOL; /* either way, handle start */ - -+ WRAP_CURLINE(f)++; -+ WRAP_CURPOS(f) = 0; - if(WRAP_FLOW(f)){ - if(f->f2 == 0 && WRAP_SPC_LEN(f)){ /* wrapped line */ - /* -*************** -*** 6963,6969 **** - - case BOL : - if(WRAP_FLOW(f)){ -! if(c == '>'){ - WRAP_FL_QC(f) = 1; /* init it */ - state = FL_QLEV; /* go collect it */ - } ---- 6980,6989 ---- - - case BOL : - if(WRAP_FLOW(f)){ -! if(WRAP_QSTR(f, WRAP_CURLINE(f)) -! && WRAP_QSTR(f, WRAP_CURLINE(f))[WRAP_CURPOS(f)] -! && WRAP_QSTR(f, WRAP_CURLINE(f))[WRAP_CURPOS(f)] == c){ -! WRAP_CURPOS(f)++; - WRAP_FL_QC(f) = 1; /* init it */ - state = FL_QLEV; /* go collect it */ - } -*************** -*** 6977,6983 **** - } - - /* quote level change implies new paragraph */ -! if(WRAP_FL_QD(f)){ - WRAP_FL_QD(f) = 0; - if(WRAP_HARD(f) == 0){ - WRAP_HARD(f) = 1; ---- 6997,7012 ---- - } - - /* quote level change implies new paragraph */ -! if (WRAP_CURLINE(f) > 0 -! && WRAP_CURLINE(f) < WRAP_QSTRLEN(f) -! && (WRAP_QSTR(f, WRAP_CURLINE(f)) != NULL -! || WRAP_QSTR(f, WRAP_CURLINE(f) - 1) != NULL) -! && ((WRAP_QSTR(f, WRAP_CURLINE(f)) != NULL && -! WRAP_QSTR(f, WRAP_CURLINE(f) - 1) == NULL) -! || (WRAP_QSTR(f, WRAP_CURLINE(f)) == NULL && -! WRAP_QSTR(f, WRAP_CURLINE(f) - 1) != NULL) -! || strcmp(WRAP_QSTR(f, WRAP_CURLINE(f)), -! WRAP_QSTR(f, WRAP_CURLINE(f) - 1)))){ - WRAP_FL_QD(f) = 0; - if(WRAP_HARD(f) == 0){ - WRAP_HARD(f) = 1; -*************** -*** 7029,7036 **** - break; - - case FL_QLEV : -! if(c == '>'){ /* another level */ -! WRAP_FL_QC(f)++; - } - else { - /* if EMBEDed, process it and return here */ ---- 7058,7068 ---- - break; - - case FL_QLEV : -! if(WRAP_QSTR(f, WRAP_CURLINE(f)) -! && WRAP_QSTR(f, WRAP_CURLINE(f))[WRAP_CURPOS(f)] -! && WRAP_QSTR(f, WRAP_CURLINE(f))[WRAP_CURPOS(f)] == c){ -! WRAP_CURPOS(f)++; -! WRAP_FL_QC(f)++; /* another level */ - } - else { - /* if EMBEDed, process it and return here */ -*************** -*** 7042,7048 **** - } - - /* quote level change signals new paragraph */ -! if(WRAP_FL_QC(f) != WRAP_FL_QD(f)){ - WRAP_FL_QD(f) = WRAP_FL_QC(f); - if(WRAP_HARD(f) == 0){ /* add hard newline */ - WRAP_HARD(f) = 1; /* hard newline */ ---- 7074,7089 ---- - } - - /* quote level change signals new paragraph */ -! if (WRAP_CURLINE(f) > 0 -! && WRAP_CURLINE(f) < WRAP_QSTRLEN(f) -! && (WRAP_QSTR(f, WRAP_CURLINE(f)) -! || WRAP_QSTR(f, WRAP_CURLINE(f) - 1)) -! && ((WRAP_QSTR(f, WRAP_CURLINE(f)) && -! !WRAP_QSTR(f, WRAP_CURLINE(f) - 1)) -! || (!WRAP_QSTR(f, WRAP_CURLINE(f)) && -! WRAP_QSTR(f, WRAP_CURLINE(f) - 1)) -! || strcmp(WRAP_QSTR(f, WRAP_CURLINE(f)), -! WRAP_QSTR(f, WRAP_CURLINE(f) - 1)))){ - WRAP_FL_QD(f) = WRAP_FL_QC(f); - if(WRAP_HARD(f) == 0){ /* add hard newline */ - WRAP_HARD(f) = 1; /* hard newline */ -*************** -*** 7099,7104 **** ---- 7140,7151 ---- - state = FL_SIG; - break; - -+ case ' ' : /* what? */ -+ if (WRAP_QSTR(f, WRAP_CURLINE(f))){ -+ WRAP_SPC_LEN(f)++; -+ so_writec(' ', WRAP_SPACES(f)); -+ } -+ - default : /* something else */ - state = DFL; - goto case_dfl; /* handle c like DFL */ -*************** -*** 7115,7121 **** - &eob); /* note any embedded*/ - wrap_eol(f, 1, &ip, &eib, - &op, &eob); /* plunk down newline */ -! wrap_bol(f, 1, 1, &ip, &eib, - &op, &eob); /* write any prefix */ - } - ---- 7162,7168 ---- - &eob); /* note any embedded*/ - wrap_eol(f, 1, &ip, &eib, - &op, &eob); /* plunk down newline */ -! wrap_bol(f, 1, WRAP_FLOW(f), &ip, &eib, - &op, &eob); /* write any prefix */ - } - -*************** -*** 7420,7426 **** - wrap_flush_embed(f, &ip, &eib, &op, &eob); - wrap_eol(f, 1, &ip, &eib, &op, - &eob); /* plunk down newline */ -! wrap_bol(f,1,1, &ip, &eib, &op, - &eob); /* write any prefix */ - } - ---- 7467,7473 ---- - wrap_flush_embed(f, &ip, &eib, &op, &eob); - wrap_eol(f, 1, &ip, &eib, &op, - &eob); /* plunk down newline */ -! wrap_bol(f,1,WRAP_FLOW(f), &ip, &eib, &op, - &eob); /* write any prefix */ - } - -*************** -*** 7478,7483 **** ---- 7525,7537 ---- - if(WRAP_COLOR(f)) - free_color_pair(&WRAP_COLOR(f)); - -+ { long i; -+ for (i = 0L; i < WRAP_QSTRLEN(f); i++) -+ if (WRAP_QSTR(f,i)) -+ fs_give((void **) &(WRAP_QSTR(f,i))); -+ fs_give((void **)&WRAP_QSTRN(f)); -+ } -+ - fs_give((void **) &f->line); /* free temp line buffer */ - so_give(&WRAP_SPACES(f)); - fs_give((void **) &f->opt); /* free wrap widths struct */ -*************** -*** 7799,7805 **** - { - int j, i; - COLOR_PAIR *col = NULL; -! char *prefix = NULL, *last_prefix = NULL; - - if(ps_global->VAR_QUOTE_REPLACE_STRING){ - get_pair(ps_global->VAR_QUOTE_REPLACE_STRING, &prefix, &last_prefix, 0, 0); ---- 7853,7860 ---- - { - int j, i; - COLOR_PAIR *col = NULL; -! char *prefix = NULL, *last_prefix = NULL, *wrap_qstr = NULL; -! int level = 0, oldj, len; - - if(ps_global->VAR_QUOTE_REPLACE_STRING){ - get_pair(ps_global->VAR_QUOTE_REPLACE_STRING, &prefix, &last_prefix, 0, 0); -*************** -*** 7808,7817 **** - last_prefix = NULL; - } - } -! -! for(j = 0; j < WRAP_FL_QD(f); j++){ - if(WRAP_USE_CLR(f)){ -! if((j % 3) == 0 - && ps_global->VAR_QUOTE1_FORE_COLOR - && ps_global->VAR_QUOTE1_BACK_COLOR - && (col = new_color_pair(ps_global->VAR_QUOTE1_FORE_COLOR, ---- 7863,7884 ---- - last_prefix = NULL; - } - } -! -! if(WRAP_QSTR(f, WRAP_CURLINE(f))) -! wrap_qstr = cpystr(WRAP_QSTR(f, WRAP_CURLINE(f))); -! len = wrap_qstr ? strlen(wrap_qstr) : 0; -! -! for (j = wrap_qstr && *wrap_qstr == ' ' ? 1 : 0; -! j < len && isspace((unsigned char)wrap_qstr[j]); j++){ -! GF_PUTC_GLO(f->next, wrap_qstr[j]); -! f->n += ((wrap_qstr[j] == TAB) ? (~f->n & 0x07) + 1 : 1); -! } -! -! for(; j < len && level < len; level++){ -! oldj = j; -! j = next_level_quote(wrap_qstr, (char **)NULL, j, WRAP_FLOW(f)); - if(WRAP_USE_CLR(f)){ -! if((level % 3) == 0 - && ps_global->VAR_QUOTE1_FORE_COLOR - && ps_global->VAR_QUOTE1_BACK_COLOR - && (col = new_color_pair(ps_global->VAR_QUOTE1_FORE_COLOR, -*************** -*** 7819,7825 **** - && pico_is_good_colorpair(col)){ - GF_COLOR_PUTC(f, col); - } -! else if((j % 3) == 1 - && ps_global->VAR_QUOTE2_FORE_COLOR - && ps_global->VAR_QUOTE2_BACK_COLOR - && (col = new_color_pair(ps_global->VAR_QUOTE2_FORE_COLOR, ---- 7886,7892 ---- - && pico_is_good_colorpair(col)){ - GF_COLOR_PUTC(f, col); - } -! else if((level % 3) == 1 - && ps_global->VAR_QUOTE2_FORE_COLOR - && ps_global->VAR_QUOTE2_BACK_COLOR - && (col = new_color_pair(ps_global->VAR_QUOTE2_FORE_COLOR, -*************** -*** 7827,7833 **** - && pico_is_good_colorpair(col)){ - GF_COLOR_PUTC(f, col); - } -! else if((j % 3) == 2 - && ps_global->VAR_QUOTE3_FORE_COLOR - && ps_global->VAR_QUOTE3_BACK_COLOR - && (col = new_color_pair(ps_global->VAR_QUOTE3_FORE_COLOR, ---- 7894,7900 ---- - && pico_is_good_colorpair(col)){ - GF_COLOR_PUTC(f, col); - } -! else if((level % 3) == 2 - && ps_global->VAR_QUOTE3_FORE_COLOR - && ps_global->VAR_QUOTE3_BACK_COLOR - && (col = new_color_pair(ps_global->VAR_QUOTE3_FORE_COLOR, -*************** -*** 7840,7884 **** - col = NULL; - } - } - -! if(!WRAP_LV_FLD(f)){ -! if(ps_global->VAR_QUOTE_REPLACE_STRING && prefix){ -! for(i = 0; prefix[i]; i++) -! GF_PUTC_GLO(f->next, prefix[i]); -! f->n += strlen(prefix); -! } -! else if(ps_global->VAR_REPLY_STRING -! && (!strcmp(ps_global->VAR_REPLY_STRING, ">") -! || !strcmp(ps_global->VAR_REPLY_STRING, "\">\""))){ -! GF_PUTC_GLO(f->next, '>'); -! f->n += 1; -! } -! else{ -! GF_PUTC_GLO(f->next, '>'); -! GF_PUTC_GLO(f->next, ' '); -! f->n += 2; -! } - } - else{ -! GF_PUTC_GLO(f->next, '>'); -! f->n += 1; - } - } - if(j && WRAP_LV_FLD(f)){ - GF_PUTC_GLO(f->next, ' '); - f->n++; - } -! else if(j && last_prefix){ - for(i = 0; last_prefix[i]; i++) - GF_PUTC_GLO(f->next, last_prefix[i]); -! f->n += strlen(last_prefix); - } - - if(prefix) - fs_give((void **)&prefix); - if(last_prefix) - fs_give((void **)&last_prefix); -! - return 0; - } - ---- 7907,7960 ---- - col = NULL; - } - } -+ if (j > 1 && wrap_qstr[j-1] == ' ') -+ j -= 1; - -! if(!WRAP_LV_FLD(f) && ps_global->VAR_QUOTE_REPLACE_STRING && prefix){ -! for(i = 0; prefix[i]; i++) -! GF_PUTC_GLO(f->next, prefix[i]); -! f->n += strlenis(prefix); - } - else{ -! for (i = oldj; i < j; i++) -! GF_PUTC_GLO(f->next, wrap_qstr[i]); -! f->n += j - oldj; -! } -! for (i = j; isspace((unsigned char)wrap_qstr[i]); i++); -! if(!wrap_qstr[i]){ -! f->n += i - j; -! for (; j < i; j++) -! GF_PUTC_GLO(f->next, ' '); - } -+ else{ -+ if((WRAP_LV_FLD(f) -+ || !ps_global->VAR_QUOTE_REPLACE_STRING || !prefix) -+ || !ps_global->VAR_REPLY_STRING -+ || (strcmp(ps_global->VAR_REPLY_STRING, ">") -+ && strcmp(ps_global->VAR_REPLY_STRING, "\">\""))){ -+ GF_PUTC_GLO(f->next, ' '); -+ f->n += 1; -+ } -+ } -+ for (; isspace((unsigned char)wrap_qstr[j]); j++); - } - if(j && WRAP_LV_FLD(f)){ - GF_PUTC_GLO(f->next, ' '); - f->n++; - } -! else if(j && !value_is_space(wrap_qstr) && last_prefix){ - for(i = 0; last_prefix[i]; i++) - GF_PUTC_GLO(f->next, last_prefix[i]); -! f->n += strlenis(last_prefix); - } - - if(prefix) - fs_give((void **)&prefix); - if(last_prefix) - fs_give((void **)&last_prefix); -! if (wrap_qstr) -! fs_give((void **)&wrap_qstr); -! - return 0; - } - -*************** -*** 7909,7914 **** ---- 7985,7996 ---- - wrap->leave_flowed = (GFW_FLOW_RESULT & flags) == GFW_FLOW_RESULT; - wrap->delsp = (GFW_DELSP & flags) == GFW_DELSP; - wrap->use_color = (GFW_USECOLOR & flags) == GFW_USECOLOR; -+ wrap->curlinenum = 0L; -+ wrap->curqstrpos = 0; -+ wrap->linenum = 0L; -+ wrap->qstrlen = 100L; -+ wrap->qstrln = (char **) fs_get(100*sizeof(char *)); -+ memset(wrap->qstrln, 0, 100*sizeof(char *)); - - return((void *) wrap); - } -*************** -*** 8330,8336 **** ---- 8412,8595 ---- - } \ - } - -+ #define ADD_QUOTE_STRING(F) { \ -+ int len = tmp_20k_buf[0] ? strlen(tmp_20k_buf) + 1 : 0; \ -+ FILTER_S *fltr; \ -+ \ -+ for(fltr = (F); fltr && fltr->f != gf_wrap; fltr = fltr->next);\ -+ if (fltr){ \ -+ if (WRAP_LINENUM(fltr) >= WRAP_QSTRLEN(fltr)){ \ -+ fs_resize((void **)&WRAP_QSTRN(fltr), \ -+ (WRAP_QSTRLEN(fltr) + 100) * sizeof(char *)); \ -+ memset(WRAP_QSTRN(fltr)+WRAP_QSTRLEN(fltr), 0, \ -+ 100*sizeof(char*)); \ -+ WRAP_QSTRLEN(fltr) += 100L; \ -+ } \ -+ if (len){ \ -+ WRAP_QSTR(fltr, WRAP_LINENUM(fltr)) = \ -+ (char *) fs_get(len*sizeof(char)); \ -+ WRAP_QSTR(fltr, WRAP_LINENUM(fltr)) = cpystr(tmp_20k_buf);\ -+ } \ -+ WRAP_LINENUM(fltr)++; \ -+ } \ -+ } -+ -+ #define GF_ADD_QUOTED_LINE(F, line) \ -+ { \ -+ LT_INS_S *ins = NULL, *insp; \ -+ int done;\ -+ unsigned char ch;\ -+ register char *cp;\ -+ register int l;\ -+ \ -+ if (line){\ -+ done = (*((LINETEST_S *) (F)->opt)->f)((F)->n++,\ -+ line, &ins,\ -+ ((LINETEST_S *) (F)->opt)->local);\ -+ if (done < 2){ \ -+ ADD_QUOTE_STRING((F));\ -+ for(insp = ins, cp = line; *cp ; ){\ -+ while(insp && cp == insp->where){\ -+ for(l = 0; l < insp->len; l++){\ -+ ch = (unsigned char) insp->text[l];\ -+ GF_PUTC((F)->next, ch);\ -+ }\ -+ insp = insp->next;\ -+ }\ -+ GF_PUTC((F)->next, *cp);\ -+ cp++;\ -+ }\ -+ while(insp){\ -+ for(l = 0; l < insp->len; l++){\ -+ ch = (unsigned char) insp->text[l];\ -+ GF_PUTC((F)->next, ch);\ -+ }\ -+ insp = insp->next;\ -+ }\ -+ gf_line_test_free_ins(&ins);\ -+ GF_PUTC((F)->next, '\015');\ -+ GF_PUTC((F)->next, '\012');\ -+ }\ -+ }\ -+ } -+ /* test second line of old line first */ -+ #define SECOND_LINE_QUOTE_TEST(line, F) \ -+ {\ -+ *p = '\0';\ -+ for (i = 0; ((F)->oldline)[i] && ((F)->oldline)[i] != '\015'; i++);\ -+ if (((F)->oldline)[i]){\ -+ i += (((F)->oldline)[i+1] == '\012') ? 2 : 1;\ -+ line = (F)->oldline + i;\ -+ }\ -+ for (i = 0; ((F)->line) \ -+ && (i < LINE_TEST_BLOCK) \ -+ && (i < SIZEOF_20KBUF)\ -+ && ((F)->line)[i] \ -+ && (((F)->line)[i] != '\015')\ -+ && (((F)->line)[i] != '\012')\ -+ && (tmp_20k_buf[i] = ((F)->line)[i]); i++);\ -+ tmp_20k_buf[i] = '\0';\ -+ GF_ADD_QUOTED_LINE((F), line);\ -+ } -+ -+ #define FIRST_LINE_QUOTE_TEST(line, F)\ -+ {\ -+ *p = '\0';\ -+ line = (F)->line;\ -+ (F)->oldline = cpystr(line);\ -+ for (i = 0; line[i] && line[i] != '\015' && line[i] != '\012'; i++); \ -+ if (line[i]){\ -+ (line[i]) = '\0'; \ -+ i+= (line[i+1] == '\012') ? 2 : 1;\ -+ }\ -+ for (j = 0; ((F)->line) \ -+ && ((i + j) < LINE_TEST_BLOCK) \ -+ && (j < SIZEOF_20KBUF) \ -+ && ((F)->line)[i + j] \ -+ && (((F)->line)[i + j] != '\015')\ -+ && (((F)->line)[i + j] != '\012')\ -+ && (tmp_20k_buf[j] = ((F)->line)[i + j]); j++);\ -+ tmp_20k_buf[j] = '\0';\ -+ GF_ADD_QUOTED_LINE((F), line);\ -+ } -+ -+ -+ void -+ gf_quote_test(f, flg) -+ FILTER_S *f; -+ int flg; -+ { -+ register char *p = f->linep; -+ register char *eobuf = GF_LINE_TEST_EOB(f); -+ char *line = NULL; -+ int i, j; -+ GF_INIT(f, f->next); -+ -+ if(flg == GF_DATA){ -+ register unsigned char c; -+ register int state = f->f1; -+ -+ while(GF_GETC(f, c)){ -+ -+ if(state == 2){ /* two full lines read */ -+ state = 0; -+ -+ /* first process the second line of an old line */ -+ if (f->oldline && f->oldline[0]) -+ SECOND_LINE_QUOTE_TEST(line, f); -+ -+ /* now we process the first line */ -+ FIRST_LINE_QUOTE_TEST(line, f); - -+ p = f->line; -+ continue; -+ } -+ if(c == '\015'){ -+ state++; -+ if (state == 1) -+ GF_LINE_TEST_ADD(f, c); -+ } -+ else -+ GF_LINE_TEST_ADD(f, c); -+ } -+ -+ f->f1 = state; -+ GF_END(f, f->next); -+ } -+ else if(flg == GF_EOD){ -+ /* first process the second line of an old line */ -+ if (f->oldline && f->oldline[0]) -+ SECOND_LINE_QUOTE_TEST(line, f); -+ -+ /* now we process the first line */ -+ FIRST_LINE_QUOTE_TEST(line, f); -+ -+ /* We are out of data. In this case we have processed the second -+ * line of an oldline, then the first line of a line, but we need -+ * to process the second line of the given line. We do this by -+ * processing it now!. -+ */ -+ if (line[i]){ -+ tmp_20k_buf[0] = '\0'; /* No next line */ -+ GF_ADD_QUOTED_LINE(f, line+i); -+ } -+ -+ fs_give((void **) &f->oldline); /* free old line buffer */ -+ fs_give((void **) &f->line); /* free line buffer */ -+ fs_give((void **) &f->opt); /* free test struct */ -+ GF_FLUSH(f->next); -+ (*f->next->f)(f->next, GF_EOD); -+ } -+ else if(flg == GF_RESET){ -+ dprint(9, (debugfile, "-- gf_reset line_test\n")); -+ f->f1 = 0; /* state */ -+ f->n = 0L; /* line number */ -+ f->f2 = LINE_TEST_BLOCK; /* size of alloc'd line */ -+ f->line = p = (char *) fs_get(f->f2 * sizeof(char)); -+ } -+ -+ f->linep = p; -+ } - - /* - * this simple filter accumulates characters until a newline, offers it -*************** -*** 8355,8361 **** - if(state){ - state = 0; - if(c == '\012'){ -! int done; - - GF_LINE_TEST_TEST(f, done); - ---- 8614,8625 ---- - if(state){ - state = 0; - if(c == '\012'){ -! int done, i, j = 0; -! -! for (i = 0; op && op[i] && (i < LINE_TEST_BLOCK) && -! (i < SIZEOF_20KBUF) && (op[i] != '\015') && -! (tmp_20k_buf[i] = op[i]); i++); -! tmp_20k_buf[i] = '\0'; - - GF_LINE_TEST_TEST(f, done); - -*************** -*** 8417,8422 **** ---- 8681,8687 ---- - else if(flg == GF_EOD){ - int i; - -+ tmp_20k_buf[0] = '\0'; - GF_LINE_TEST_TEST(f, i); /* examine remaining data */ - fs_give((void **) &f->line); /* free line buffer */ - fs_give((void **) &f->opt); /* free test struct */ -diff -rc pine4.63/pine/folder.c pine4.63.I.USE/pine/folder.c -*** pine4.63/pine/folder.c Mon Apr 4 11:42:52 2005 ---- pine4.63.I.USE/pine/folder.c Thu May 19 19:57:31 2005 -*************** -*** 94,100 **** - #define FLW_SLCT 0x02 - #define FLW_LIST 0x04 - -! - - - /*---------------------------------------------------------------------- ---- 94,100 ---- - #define FLW_SLCT 0x02 - #define FLW_LIST 0x04 - -! static int max_slot_size = 0; - - - /*---------------------------------------------------------------------- -*************** -*** 224,229 **** ---- 224,230 ---- - gf_io_t, HANDLE_S **, int)); - int folder_list_write_folder PROTO((gf_io_t, CONTEXT_S *, - int, char *, int)); -+ int folder_list_write_count PROTO((FOLDER_S *, CONTEXT_S *, gf_io_t, int)); - int folder_list_write_prefix PROTO((FOLDER_S *, int, gf_io_t)); - int folder_list_ith PROTO((int, CONTEXT_S *)); - char *folder_list_center_space PROTO((char *, int)); -*************** -*** 469,475 **** - - HELP_MENU, - OTHER_MENU, -! NULL_MENU, - NULL_MENU, - NULL_MENU, - NULL_MENU, ---- 470,476 ---- - - HELP_MENU, - OTHER_MENU, -! {"^H","ChkIncFld",{MC_FORCECHECK,1,ctrl('H')}, KS_NONE}, - NULL_MENU, - NULL_MENU, - NULL_MENU, -*************** -*** 1708,1713 **** ---- 1709,1715 ---- - gf_io_t pc; - - dprint(1, (debugfile, "\n\n ---- FOLDER LISTER ----\n")); -+ ps->in_fld_list = 1; - - memset(&folder_proc_data, 0, sizeof(FPROC_S)); - folder_proc_data.fs = fs; -*************** -*** 1842,1847 **** ---- 1844,1850 ---- - *fs->cache_streamp = NULL; - } - -+ ps->in_fld_list = 0; - return(folder_proc_data.rv); - } - -*************** -*** 1955,1960 **** ---- 1958,1975 ---- - gf_puts("\n", pc); - } - -+ if (c_list->use & CNTXT_INCMNG && -+ F_ON(F_ENABLE_INCOMING_CHECK,ps_global) && -+ F_ON(F_ENABLE_INCOMING,ps_global) && -+ F_OFF(F_ENABLE_FAST_RECENT, ps_global)){ -+ sprintf(tmp_20k_buf, -+ "Format: Folder-name [Total New Messages/Total Messages]"); -+ gf_puts(folder_list_center_space(tmp_20k_buf, cols), pc); -+ gf_puts(tmp_20k_buf, pc); -+ gf_puts("\n", pc); -+ } -+ -+ - gf_puts(repeat_char(cols, '-'), pc); - gf_puts("\n\n", pc); - } -*************** -*** 1992,1999 **** ---- 2007,2027 ---- - else if(c_list == fp->fs->list_cntxt) - len += 4; /* "[X] " */ - -+ if (c_list->use & CNTXT_INCMNG && -+ F_ON(F_ENABLE_INCOMING_CHECK,ps_global) && -+ F_ON(F_ENABLE_INCOMING,ps_global) && -+ F_OFF(F_ENABLE_FAST_RECENT, ps_global)) -+ if (need_folder_report(FLDR_NAME(f))){ -+ len += 5; /* "[/]" + " " */ -+ len += strlen(comatose(f->countrecent)); -+ len += strlen(comatose(f->messages)); -+ } -+ else -+ len += 1; -+ - if(slot_size < len) - slot_size = len; -+ max_slot_size = slot_size; - } - - if(F_ON(F_SINGLE_FOLDER_LIST, ps_global)){ -*************** -*** 2098,2104 **** - int flags; - { - char buf[256]; -! int l = 0; - FOLDER_S *fp; - HANDLE_S *h; - ---- 2126,2132 ---- - int flags; - { - char buf[256]; -! int l = 0, s = 0; - FOLDER_S *fp; - HANDLE_S *h; - -*************** -*** 2121,2126 **** ---- 2149,2155 ---- - && (*pc)(strlen(buf)) && gf_puts(buf, pc)) : 1) - && (fp ? ((l = folder_list_write_prefix(fp, flags, pc)) >= 0 - && gf_puts(FLDR_NAME(fp), pc) -+ && (s = folder_list_write_count(fp, ctxt, pc, l)) >= 0 - && ((fp->isdir && fp->isfolder) ? (*pc)('[') : 1) - && ((fp->isdir) ? (*pc)(ctxt->dir->delim) : 1) - && ((fp->isdir && fp->isfolder) ? (*pc)(']') : 1)) -*************** -*** 2128,2134 **** - && (h ? ((*pc)(TAG_EMBED) && (*pc)(TAG_BOLDOFF) - && (*pc)(TAG_EMBED) && (*pc)(TAG_INVOFF)) : 1)){ - if(fp){ -! l += strlen(FLDR_NAME(fp)); - if(fp->isdir) - l += (fp->isfolder) ? 3 : 1; - } ---- 2157,2163 ---- - && (h ? ((*pc)(TAG_EMBED) && (*pc)(TAG_BOLDOFF) - && (*pc)(TAG_EMBED) && (*pc)(TAG_INVOFF)) : 1)){ - if(fp){ -! l += strlen(FLDR_NAME(fp)) + s; - if(fp->isdir) - l += (fp->isfolder) ? 3 : 1; - } -*************** -*** 2139,2144 **** ---- 2168,2203 ---- - return(l); - } - -+ int -+ folder_list_write_count(f, ctxt, pc, l) -+ FOLDER_S *f; -+ CONTEXT_S *ctxt; -+ gf_io_t pc; -+ int l; -+ { -+ int rv = 0, i; -+ int offset = 1; -+ -+ if (ctxt->use & CNTXT_INCMNG && -+ F_ON(F_ENABLE_INCOMING_CHECK,ps_global) && -+ F_ON(F_ENABLE_INCOMING,ps_global) && -+ F_OFF(F_ENABLE_FAST_RECENT, ps_global) && -+ need_folder_report(FLDR_NAME(f))){ -+ rv = max_slot_size - strlen(FLDR_NAME(f)) - l; -+ rv -= strlen(comatose(f->countrecent)); -+ rv -= strlen(comatose(f->messages)); -+ rv -= 5 + offset; -+ for (i = 0; i <= rv; i++) gf_puts(" ", pc); -+ gf_puts("[", pc); -+ gf_puts(comatose(f->countrecent), pc); -+ gf_puts("/", pc); -+ gf_puts(comatose(f->messages), pc); -+ gf_puts("]", pc); -+ rv = max_slot_size - strlen(FLDR_NAME(f)) - l - offset -1; -+ } -+ return rv; -+ } -+ - - int - folder_list_write_prefix(f, flags, pc) -*************** -*** 2224,2229 **** ---- 2283,2301 ---- - p = strchr(p, fs->context->dir->delim)) - name = ++p; - -+ if(fs->context->use & CNTXT_INCMNG){ -+ FOLDER_S *f; -+ int total = folder_total(FOLDERS(fs->context)), index; -+ for(index = folder_index(ps_global->inbox_name, fs->context, FI_FOLDER); -+ index >= 0 && index < total -+ && (f = folder_entry(index, FOLDERS(fs->context))) -+ && !f->isdir; index++) -+ if(!strcmp(fs->first_folder, f->name)){ -+ name = FLDR_NAME(f); -+ break; -+ } -+ } -+ - for(h = handles; h; h = h->next) - if(h->h.f.context == fs->context){ - if(!h_found) /* match at least given context */ -*************** -*** 2462,2468 **** - "Empty folder collection. No folder to rename!"); - - break; -! - - /*-------------- Delete --------------------*/ - case MC_DELETE : ---- 2534,2549 ---- - "Empty folder collection. No folder to rename!"); - - break; -! -! -! /*------- Check incoming forlders -------*/ -! case MC_FORCECHECK: -! ps_global->force_check_now = 1; -! rv = (new_mail_incfolder(ps_global,MC_FORCECHECK) && -! ps_global->refresh_list > 0) ? 1 : 0; -! ps_global->refresh_list = 0; -! break; -! - - /*-------------- Delete --------------------*/ - case MC_DELETE : -*************** -*** 2783,2792 **** - if(we_cancel) - cancel_busy_alarm(-1); - -! if(gotit) - sprintf(tmp_output, - "%lu total message%.2s, %lu of them recent", - tot, plural(tot), rec); - } - }else - strncpy(tmp_output, "No folder to check! Can't get recent info", ---- 2864,2880 ---- - if(we_cancel) - cancel_busy_alarm(-1); - -! if(gotit){ - sprintf(tmp_output, - "%lu total message%.2s, %lu of them recent", - tot, plural(tot), rec); -+ folder->countrecent = rec; -+ folder->messages = tot; -+ if (rec > 0L) -+ folder->notified = 1; -+ folder->selected = rec > 0L ? 1 : folder->user_selected; -+ ps_global->refresh_list++; -+ } - } - }else - strncpy(tmp_output, "No folder to check! Can't get recent info", -*************** -*** 3323,3330 **** - case 'f' : /* flip selection */ - n = folder_total(FOLDERS(context)); - for(total = i = 0; i < n; i++) -! if(f = folder_entry(i, FOLDERS(context))) - f->selected = !f->selected; - - return(1); /* repaint */ - ---- 3411,3420 ---- - case 'f' : /* flip selection */ - n = folder_total(FOLDERS(context)); - for(total = i = 0; i < n; i++) -! if(f = folder_entry(i, FOLDERS(context))){ - f->selected = !f->selected; -+ f->user_selected = f->selected; -+ } - - return(1); /* repaint */ - -*************** -*** 3467,3481 **** - CONTEXT_S *context; - { - int i, n, total; - - n = folder_total(FOLDERS(context)); -! for(total = i = 0; i < n; i++) -! if(folder_entry(i, FOLDERS(context))->selected) - total++; - - return(total); - } - - - SELECTED_S * - new_selected() ---- 3557,3620 ---- - CONTEXT_S *context; - { - int i, n, total; -+ FOLDER_S *f; - - n = folder_total(FOLDERS(context)); -! for(total = i = 0; i < n; i++){ -! f = folder_entry(i, FOLDERS(context)); -! if(f->selected) - total++; -+ } - - return(total); - } - -+ void -+ update_incoming_folder_data(stream, context) -+ MAILSTREAM *stream; -+ CONTEXT_S *context; -+ { -+ FOLDER_S *f = incoming_folder_data(stream, context); -+ -+ if(f){ -+ f->origrecent = f->recent = stream->recent; -+ f->messages = stream->nmsgs; -+ } -+ } -+ -+ -+ FOLDER_S * -+ incoming_folder_data(stream, cntxt) -+ MAILSTREAM *stream; -+ CONTEXT_S *cntxt; -+ { -+ long index, total, done = 0; -+ FOLDER_S *f = NULL; -+ -+ if (cntxt && cntxt->use & CNTXT_INCMNG){ -+ total = folder_total(FOLDERS(cntxt)); -+ for (index = 0L; index < total ; index++){ -+ f = folder_entry(index, FOLDERS(cntxt)); -+ if (!strcmp(STREAMNAME(stream), FLDR_NAME(f))){ -+ done++; -+ break; -+ } -+ } -+ } -+ if (!done) -+ f = NULL; -+ return f; -+ } -+ -+ int -+ need_folder_report(folder) -+ char *folder; -+ { -+ return (ps_global->VAR_INCOMING_FOLDERS_CHECK && -+ ((ps_global->VAR_INCOMING_FOLDERS_CHECK[0] == '*') || -+ strstr(ps_global->VAR_INCOMING_FOLDERS_CHECK, folder))); -+ } -+ - - SELECTED_S * - new_selected() -*************** -*** 4204,4209 **** ---- 4343,4349 ---- - - if(f = folder_entry(index, FOLDERS(context))){ - f->selected = !f->selected; -+ f->user_selected = f->selected; - return((*func)(context, index)); - } - return 1; -*************** -*** 7223,7228 **** ---- 7363,7371 ---- - FOLDERS(context) = init_folder_entries(); - init_incoming_folder_list(ps_global, context); - init_inbox_mapping(ps_global->VAR_INBOX_PATH, context); -+ ps_global->force_check_now = 1; /* sorry about this */ -+ new_mail_incfolder(ps_global,MC_FORCECHECK); -+ ps_global->refresh_list += 1; - } - - -*************** -*** 8406,8416 **** - long *find_recent; - int *did_cancel; - { -! int index, recent = 0, failed_status = 0, try_fast; - char prompt[128]; - FOLDER_S *f = NULL; - char tmp[MAILTMPLEN]; -! - - /* note: find_folders may assign "stream" */ - build_folder_list(streamp, cntxt, NULL, NULL, ---- 8549,8565 ---- - long *find_recent; - int *did_cancel; - { -! int index, recent = 0, failed_status = 0, try_fast, done = 0; - char prompt[128]; - FOLDER_S *f = NULL; - char tmp[MAILTMPLEN]; -! char *test_current = cpystr(current); -! int cur_indx = folder_index(ps_global->cur_folder, cntxt, FI_FOLDER); -! int loop = !strcmp(next, ps_global->cur_folder) ? 0 : -! (folder_index(test_current, cntxt, FI_FOLDER) <= cur_indx -! ? 1 : 0); -! int last = !strcmp(ps_global->cur_folder, ps_global->inbox_name) -! ? 1 : cur_indx; - - /* note: find_folders may assign "stream" */ - build_folder_list(streamp, cntxt, NULL, NULL, -*************** -*** 8421,8427 **** - if(find_recent) - *find_recent = 0L; - -! for(index = folder_index(current, cntxt, FI_FOLDER) + 1; - index > 0 - && index < folder_total(FOLDERS(cntxt)) - && (f = folder_entry(index, FOLDERS(cntxt))) ---- 8570,8578 ---- - if(find_recent) - *find_recent = 0L; - -! -! find_new_message: -! for(index = folder_index(test_current, cntxt, FI_FOLDER) + 1; - index > 0 - && index < folder_total(FOLDERS(cntxt)) - && (f = folder_entry(index, FOLDERS(cntxt))) -*************** -*** 8432,8437 **** ---- 8583,8593 ---- - int rv, we_cancel = 0, mlen, match; - char msg_buf[MAX_BM+1], mbuf[MAX_BM+1]; - -+ if (loop && (index == last)){ -+ done++; -+ break; -+ } -+ - /* must be a folder and it can't be the current one */ - if(ps_global->context_current == ps_global->context_list - && !strcmp(ps_global->cur_folder, FLDR_NAME(f))) -*************** -*** 8583,8601 **** - } - } - -! if(f && (!find_recent || recent)) - strcpy(next, FLDR_NAME(f)); - else - *next = '\0'; - - /* BUG: how can this be made smarter so we cache the list? */ - free_folder_list(cntxt); - return((*next) ? next : NULL); - } - - - - /* - * folder_is_nick - check to see if the given name is a nickname - * for some folder in the given context... - * ---- 8739,8906 ---- - } - } - -! if(f && (!find_recent || recent)){ - strcpy(next, FLDR_NAME(f)); -+ done++; -+ } - else - *next = '\0'; - -+ if (!done && F_ON(F_AUTO_CIRCULAR_TAB,ps_global) -+ && strcmp(test_current,ps_global->inbox_name)){ -+ done++; loop++; -+ if (test_current) -+ fs_give((void **)&test_current); -+ test_current = cpystr(ps_global->inbox_name); -+ goto find_new_message; -+ } -+ - /* BUG: how can this be made smarter so we cache the list? */ - free_folder_list(cntxt); -+ if (test_current) -+ fs_give((void **)&test_current); - return((*next) ? next : NULL); - } - - - - /* -+ * next_folder - given a current folder in a context, return the next in -+ * the list, or NULL if no more or there's a problem. -+ */ -+ int -+ next_folder_check(streamp, cntxt, find_recent, find_messages, f, opstrm) -+ MAILSTREAM **streamp; -+ CONTEXT_S *cntxt; -+ long *find_recent, *find_messages; -+ FOLDER_S *f; -+ int *opstrm; -+ { -+ char *next; -+ int index, failed_status = 0; -+ -+ /* note: find_folders may assign "stream" */ -+ build_folder_list(streamp, cntxt, NULL, NULL, BFL_NONE); -+ -+ if(find_recent && find_messages && opstrm){ -+ MAILSTREAM *stream = NULL; -+ int rv, we_cancel = 0; -+ char msg_buf[MAX_SCREEN_COLS+1] = {'\0'}; -+ char tmp[MAILTMPLEN]; -+ -+ *opstrm = 0; /* default value */ -+ *find_recent = f->recent; /* default value. Return this if */ -+ *find_messages = f->messages; /* not requested */ -+ -+ if((stream = sp_stream_get(context_apply(tmp, cntxt, f->name,sizeof(tmp)), -+ SP_MATCH)) != NULL){ -+ *opstrm = 1; -+ (void) pine_mail_ping(stream); -+ next = new_mail_in_open_stream(stream, find_recent, find_messages); -+ free_folder_list(cntxt); -+ return next ? 1 : 0; -+ } -+ else if ((F_ON(F_ENABLE_FAST_RECENT, ps_global) && -+ F_OFF(F_ENABLE_INCOMING_RECHECK,ps_global) && -+ (f->notified || f->selected)) -+ || (f->selected && f->user_selected)){ -+ -+ next = f->notified ? FLDR_NAME(f) : NULL; -+ free_folder_list(cntxt); -+ return next ? 1 : 0; -+ } -+ else if (need_folder_report(FLDR_NAME(f)) -+ && (strcmp(ps_global->cur_folder, FLDR_NAME(f)) || !stream)){ -+ -+ we_cancel = busy_alarm(1, msg_buf, NULL, 1); -+ -+ /* First, get a stream for the test */ -+ if(streamp && *streamp){ -+ if(context_same_stream(cntxt, f->name, *streamp)) -+ stream = *streamp; -+ else{ -+ mail_close(*streamp); -+ *streamp = NULL; -+ } -+ } -+ -+ if(!stream) -+ stream = sp_stream_get(context_apply(tmp, cntxt, f->name, -+ sizeof(tmp)), SP_SAME); -+ -+ if(!stream){ -+ if(!(stream = sp_stream_status_get( -+ context_apply(tmp, cntxt, f->name, -+ sizeof(tmp))))){ -+ stream = (*f->name == '{') -+ ? mail_open (NIL,f->name,OP_HALFOPEN) : NIL; -+ sp_add_status(stream); -+ } -+ } -+ -+ if(F_OFF(F_ENABLE_FAST_RECENT, ps_global) -+ || !((rv = folder_exists(cntxt,f->name)) -+ & (FEX_ISMARKED | FEX_UNMARKED))){ -+ extern MAILSTATUS mm_status_result; -+ -+ if((F_ON(F_ENABLE_FAST_RECENT, ps_global) && -+ (rv == 0 || rv & FEX_ERROR))){ -+ failed_status = 1; -+ mm_status_result.flags = 0L; -+ } -+ else{ -+ if(stream){ -+ if(!context_status_full(cntxt, stream, -+ f->name, SA_RECENT | SA_MESSAGES, -+ &f->uidvalidity, -+ &f->uidnext)){ -+ failed_status = 1; -+ mm_status_result.flags = 0L; -+ } -+ } -+ else{ -+ if(!context_status_streamp_full(cntxt, streamp, f->name, -+ SA_RECENT | SA_MESSAGES, -+ &f->uidvalidity, -+ &f->uidnext)){ -+ failed_status = 1; -+ mm_status_result.flags = 0L; -+ } -+ } -+ } -+ -+ if (!failed_status){ -+ *find_messages = mm_status_result.messages; -+ *find_recent = mm_status_result.recent; -+ } -+ else{ -+ *find_recent = *find_messages = 0; -+ } -+ rv = (((mm_status_result.flags & SA_RECENT) || -+ (F_OFF(F_ENABLE_FAST_RECENT,ps_global) -+ && (mm_status_result.recent != f->recent))) -+ && (*find_recent = mm_status_result.recent)) -+ ? FEX_ISMARKED : 0; -+ } -+ -+ if(we_cancel) -+ cancel_busy_alarm(0); -+ -+ failed_status = 0; -+ -+ if(rv & FEX_ISMARKED){ -+ next = f ? FLDR_NAME(f) : NULL; -+ free_folder_list(cntxt); -+ return next ? 1 : 0; -+ } -+ } -+ return 0; -+ } -+ } -+ -+ -+ -+ /* - * folder_is_nick - check to see if the given name is a nickname - * for some folder in the given context... - * -diff -rc pine4.63/pine/imap.c pine4.63.I.USE/pine/imap.c -*** pine4.63/pine/imap.c Fri Jan 21 17:31:32 2005 ---- pine4.63.I.USE/pine/imap.c Thu May 19 19:57:33 2005 -*************** -*** 704,710 **** - q_line = -(ps_global->ttyo ? ps_global->ttyo->footer_rows : 3); - - /* make sure errors are seen */ -! if(ps_global->ttyo) - flush_status_messages(0); - - /* ---- 704,710 ---- - q_line = -(ps_global->ttyo ? ps_global->ttyo->footer_rows : 3); - - /* make sure errors are seen */ -! if(ps_global->ttyo && !ps_global->checking_incfld) - flush_status_messages(0); - - /* -*************** -*** 1949,1959 **** ---- 1949,1963 ---- - #endif - - if(elapsed >= (long)ps_global->tcp_query_timeout){ -+ if(!ps_global->checking_incfld){ - sprintf(pmt, - "Waited %s seconds for server reply. Break connection to server", - long2string(elapsed)); - if(want_to(pmt, 'n', 'n', NO_HELP, WT_FLUSH_IN) == 'y') - return(0L); -+ } -+ else -+ rv = 0L; - } - - return(rv); -*************** -*** 1995,2000 **** ---- 1999,2005 ---- - if(elapsed >= (long)ps_global->tcp_query_timeout){ - int clear_inverse; - -+ if(!ps_global->checking_incfld){ - ClearLine(ps_global->ttyo->screen_rows - FOOTER_ROWS(ps_global)); - if(clear_inverse = !InverseState()) - StartInverse(); -*************** -*** 2015,2020 **** ---- 2020,2028 ---- - EndInverse(); - - ClearLine(ps_global->ttyo->screen_rows - FOOTER_ROWS(ps_global)); -+ } -+ else -+ rv = 0L; - } - - if(rv == 1L){ /* just warn 'em something's up */ -*************** -*** 2031,2036 **** ---- 2039,2074 ---- - return(rv); - } - -+ QUOTALIST *pine_quotalist_copy (pquota) -+ QUOTALIST *pquota; -+ { -+ QUOTALIST *cquota = NULL; -+ -+ if(pquota){ -+ cquota = mail_newquotalist(); -+ if (pquota->name && *pquota->name){ -+ cquota->name = (char *) fs_get((strlen(pquota->name) + 1)*sizeof(char)); -+ cquota->name = cpystr(pquota->name); -+ } -+ cquota->usage = pquota->usage; -+ cquota->limit = pquota->limit; -+ if (pquota->next) -+ cquota->next = pine_quotalist_copy(pquota->next); -+ } -+ return cquota; -+ } -+ -+ -+ /* C-client callback to handle quota */ -+ -+ void -+ pine_parse_quota (stream, msg, pquota) -+ MAILSTREAM *stream; -+ unsigned char *msg; -+ QUOTALIST *pquota; -+ { -+ ps_global->quota = pine_quotalist_copy (pquota); -+ } - - /* - * C-client callback to handle SSL/TLS certificate validation failures -diff -rc pine4.63/pine/init.c pine4.63.I.USE/pine/init.c -*** pine4.63/pine/init.c Thu Apr 7 11:01:42 2005 ---- pine4.63.I.USE/pine/init.c Thu May 19 19:57:32 2005 -*************** -*** 71,76 **** ---- 71,77 ---- - typedef enum {Sapling, Seedling, Seasoned} FeatureLevel; - - #define TO_BAIL_THRESHOLD 60 -+ #define INCFLD_THRESHOLD 5 - - #define METASTR "\nremote-abook-metafile=" - static char meta_prefix[] = ".ab"; -*************** -*** 158,163 **** ---- 159,166 ---- - - CONF_TXT_T cf_text_incoming_folders[] = "List of incoming msg folders besides INBOX, e.g. ={host2}inbox, {host3}inbox\n# Syntax: optnl-label {optnl-imap-host-name}folder-path"; - -+ CONF_TXT_T cf_incoming_folders_check[] = "List of incoming folders to be checked for new mail"; -+ - CONF_TXT_T cf_text_folder_collections[] = "List of directories where saved-message folders may be. First one is\n# the default for Saves. Example: Main {host1}mail/[], Desktop mail\\[]\n# Syntax: optnl-label {optnl-imap-hostname}optnl-directory-path[]"; - - CONF_TXT_T cf_text_news_collections[] = "List, only needed if nntp-server not set, or news is on a different host\n# than used for NNTP posting. Examples: News *[] or News *{host3/nntp}[]\n# Syntax: optnl-label *{news-host/protocol}[]"; -*************** -*** 214,223 **** ---- 217,256 ---- - - CONF_TXT_T cf_text_sort_key[] = "Sets presentation order of messages in Index. Choices:\n# Subject, From, Arrival, Date, Size, To, Cc, OrderedSubj, Score, and Thread.\n# Order may be reversed by appending /Reverse. Default: \"Arrival\"."; - -+ CONF_TXT_T cf_text_thread_sort_key[] = "#Sets presentation order of threads in thread index. Choices:\n#arrival, and thread."; -+ - CONF_TXT_T cf_text_addrbook_sort_rule[] = "Sets presentation order of address book entries. Choices: dont-sort,\n# fullname-with-lists-last, fullname, nickname-with-lists-last, nickname\n# Default: \"fullname-with-lists-last\"."; - - CONF_TXT_T cf_text_folder_sort_rule[] = "Sets presentation order of folder list entries. Choices: alphabetical,\n# alpha-with-dirs-last, alpha-with-dirs-first.\n# Default: \"alpha-with-directories-last\"."; - -+ CONF_TXT_T cf_text_compose_rules[] = "Allows a user to set rules when composing messages."; -+ -+ CONF_TXT_T cf_text_forward_rules[] = "Allows a user to set rules when forwarding messages."; -+ -+ CONF_TXT_T cf_text_reply_rules[] = "Allows a user to set rules when replying messages."; -+ -+ CONF_TXT_T cf_text_index_rules[] = "Allows a user to supercede global index format variable in designated folders."; -+ -+ CONF_TXT_T cf_text_replace_rules[] = "Allows a user to change the form a specify field in the index-format is \n# displayed."; -+ -+ CONF_TXT_T cf_text_reply_indent_rules[] = "Allows a user to change the form a specify a reply-indent-string\n# based of rules."; -+ -+ CONF_TXT_T cf_text_reply_leadin_rules[] = "Allows a user to replace the reply-leadin message based on different parameters."; -+ -+ CONF_TXT_T cf_text_reply_subject_rules[] = "Allows a user to replace the subject of a message in a customs based way"; -+ -+ CONF_TXT_T cf_text_thread_displaystyle_rule[] = "Allows a user to specify the threading style of specific folders"; -+ -+ CONF_TXT_T cf_text_thread_indexstyle_rule[] = "Allows a user to specify the threading index style of specific folders"; -+ -+ CONF_TXT_T cf_text_save_rules[] = "Allows a user to specify a save folder message for specific senders or folders."; -+ -+ CONF_TXT_T cf_text_smtp_rules[] = "Allows a user to specify a smtp server to be used when sending e-mail,\n# according to the rules specified here."; -+ -+ CONF_TXT_T cf_text_sort_rules[] = "Allows a user to specify the sort default order of a specific folder."; -+ -+ CONF_TXT_T cf_text_startup_rules[] = "Allows a user to specify the position of a highlighted message when opening a \n# folder."; -+ - CONF_TXT_T cf_text_character_set[] = "Reflects capabilities of the display you have. Default: US-ASCII.\n# Typical alternatives include ISO-8859-x, (x is a number between 1 and 9)."; - - CONF_TXT_T cf_text_editor[] = "Specifies the program invoked by ^_ in the Composer,\n# or the \"enable-alternate-editor-implicitly\" feature."; -*************** -*** 228,233 **** ---- 261,268 ---- - - CONF_TXT_T cf_text_fillcol[] = "Specifies the column of the screen where the composer should wrap."; - -+ CONF_TXT_T cf_special_text_color[] = "Specifies a comma separated list of text and regular expresions that Pine\n# will highlight"; -+ - CONF_TXT_T cf_text_replystr[] = "Specifies the string to insert when replying to a message."; - - CONF_TXT_T cf_text_quotereplstr[] = "Specifies the string to replace quotes with when viewing a message."; -*************** -*** 242,247 **** ---- 277,284 ---- - - CONF_TXT_T cf_text_inc_startup[] = "Sets message which cursor begins on. Choices: first-unseen, first-recent,\n# first-important, first-important-or-unseen, first-important-or-recent,\n# first, last. Default: \"first-unseen\"."; - -+ CONF_TXT_T cf_text_inc_check[] = "Sets how and when checks for new mail should happen. Choices: automatic,\n# automatic-after-first-manual-check, manual-only, Default: automatic"; -+ - CONF_TXT_T cf_pruning_rule[] = "Allows a default answer for the prune folder questions. Choices: yes-ask,\n# yes-no, no-ask, no-no, ask-ask, ask-no. Default: \"ask-ask\"."; - - CONF_TXT_T cf_reopen_rule[] = "Controls behavior when reopening an already open folder."; -*************** -*** 378,383 **** ---- 415,422 ---- - - CONF_TXT_T cf_text_tcp_query_timeo[] = "If this much time has elapsed at the time of a tcp read or write\n# timeout, pine will ask if you want to break the connection.\n# Default is 60 seconds, minimum is 5, maximum is 1000."; - -+ CONF_TXT_T cf_text_inc_fld_timeout[] = "If this much time has elapsed at the time of a tcp read or write\n# timeout while checking for new mail in an incoming folder, pine will break the connection.\n# Default is 5 seconds, minimum is 2, maximum is 60."; -+ - CONF_TXT_T cf_text_rsh_open_timeo[] = "Sets the time in seconds that Pine will attempt to open a UNIX remote\n# shell connection. The default is 15, min is 5, and max is unlimited.\n# Zero disables rsh altogether."; - - CONF_TXT_T cf_text_rsh_path[] = "Sets the name of the command used to open a UNIX remote shell connection.\n# The default is typically /usr/ucb/rsh."; -*************** -*** 418,423 **** ---- 457,465 ---- - - CONF_TXT_T cf_text_newsrc_path[] = "Full path and name of NEWSRC file"; - -+ CONF_TXT_T cf_text_maildir_location[] = "Location relative to your HOME directory of the directory where your INBOX\n# for the maildir format is located. Default value is \"Maildir\". If your\n# inbox is located at \"~/Maildir\" you do not need to change this value.\n# A common value is also \".maildir\""; -+ -+ - /* these are used to report folder directory creation problems */ - CONF_TXT_T init_md_exists[] = "The \"%s\" subdirectory already exists, but it is not writable by Pine so Pine cannot run. Please correct the permissions and restart Pine."; - -*************** -*** 471,476 **** ---- 513,520 ---- - cf_text_nntp_server}, - {"inbox-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, - cf_text_inbox_path}, -+ {"incoming-folders-to-check", 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, -+ cf_incoming_folders_check}, - {"incoming-archive-folders", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, - cf_text_archived_folders}, - {"pruned-folders", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -*************** -*** 511,516 **** ---- 555,562 ---- - cf_text_fcc_name_rule}, - {"sort-key", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, - cf_text_sort_key}, -+ {"thread-sort-key", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, -+ cf_text_thread_sort_key}, - {"addrbook-sort-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, - cf_text_addrbook_sort_rule}, - {"folder-sort-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, -*************** -*** 519,524 **** ---- 565,572 ---- - cf_text_goto_default}, - {"incoming-startup-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, - cf_text_inc_startup}, -+ {"incoming-check-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, -+ cf_text_inc_check}, - {"pruning-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, - cf_pruning_rule}, - {"folder-reopen-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, -*************** -*** 533,538 **** ---- 581,612 ---- - cf_text_thread_exp_char}, - {"threading-lastreply-character", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, - cf_text_thread_lastreply_char}, -+ {"threading-display-style-rule", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_text_thread_displaystyle_rule}, -+ {"threading-index-style-rule", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_text_thread_indexstyle_rule}, -+ {"compose-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_text_compose_rules}, -+ {"forward-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_text_forward_rules}, -+ {"index-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_text_index_rules}, -+ {"replace-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_text_replace_rules}, -+ {"reply-indent-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_text_reply_indent_rules}, -+ {"reply-leadin-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_text_reply_leadin_rules}, -+ {"reply-subject-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_text_reply_subject_rules}, -+ {"save-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_text_save_rules}, -+ {"smtp-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_text_smtp_rules}, -+ {"sort-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_text_sort_rules}, -+ {"startup-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_text_startup_rules}, - {"character-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, - cf_text_character_set}, - {"editor", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -*************** -*** 541,546 **** ---- 615,622 ---- - cf_text_speller}, - {"composer-wrap-column", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, - cf_text_fillcol}, -+ {"special-text-color", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, -+ cf_special_text_color}, - {"reply-indent-string", 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, - cf_text_replystr}, - {"reply-leadin", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, -*************** -*** 605,610 **** ---- 681,688 ---- - cf_text_news_active}, - {"news-spool-directory", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, - cf_text_news_spooldir}, -+ {"maildir-location", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, -+ cf_text_maildir_location}, - {"upload-command", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, - cf_text_upload_cmd}, - {"upload-command-prefix", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, -*************** -*** 673,678 **** ---- 751,758 ---- - cf_text_tcp_write_timeo}, - {"tcp-query-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, - cf_text_tcp_query_timeo}, -+ {"inc-fld-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, -+ cf_text_inc_fld_timeout}, - {"rsh-command", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, - cf_text_rsh_command}, - {"rsh-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, -*************** -*** 772,777 **** ---- 852,859 ---- - {"quote3-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, NULL}, - {"signature-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, NULL}, - {"signature-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, NULL}, -+ {"special-text-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, NULL}, -+ {"special-text-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, NULL}, - {"prompt-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, NULL}, - {"prompt-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, NULL}, - {"index-to-me-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, NULL}, -*************** -*** 1475,1481 **** - register struct variable *vars = ps->vars; - int obs_header_in_reply, /* the obs_ variables are to */ - obs_old_style_reply, /* support backwards compatibility */ -! obs_save_by_sender, i, def_sort_rev; - long rvl; - PINERC_S *fixedprc = NULL; - FeatureLevel obs_feature_level; ---- 1557,1563 ---- - register struct variable *vars = ps->vars; - int obs_header_in_reply, /* the obs_ variables are to */ - obs_old_style_reply, /* support backwards compatibility */ -! obs_save_by_sender, i, def_sort_rev, thread_def_sort_rev; - long rvl; - PINERC_S *fixedprc = NULL; - FeatureLevel obs_feature_level; -*************** -*** 1497,1502 **** ---- 1579,1585 ---- - GLO_FEATURE_LEVEL = cpystr(DF_FEATURE_LEVEL); - GLO_OLD_STYLE_REPLY = cpystr(DF_OLD_STYLE_REPLY); - GLO_SORT_KEY = cpystr(DF_SORT_KEY); -+ GLO_THREAD_SORT_KEY = cpystr(DF_THREAD_SORT_KEY); - GLO_SAVED_MSG_NAME_RULE = cpystr(DF_SAVED_MSG_NAME_RULE); - GLO_FCC_RULE = cpystr(DF_FCC_RULE); - GLO_AB_SORT_RULE = cpystr(DF_AB_SORT_RULE); -*************** -*** 1507,1512 **** ---- 1590,1596 ---- - GLO_REMOTE_ABOOK_VALIDITY = cpystr(DF_REMOTE_ABOOK_VALIDITY); - GLO_GOTO_DEFAULT_RULE = cpystr(DF_GOTO_DEFAULT_RULE); - GLO_INCOMING_STARTUP = cpystr(DF_INCOMING_STARTUP); -+ GLO_INCOMING_RULE = cpystr(DF_INCOMING_RULE); - GLO_PRUNING_RULE = cpystr(DF_PRUNING_RULE); - GLO_REOPEN_RULE = cpystr(DF_REOPEN_RULE); - GLO_THREAD_DISP_STYLE = cpystr(DF_THREAD_DISP_STYLE); -*************** -*** 1856,1863 **** ---- 1940,1959 ---- - set_current_val(&vars[V_POSTPONED_FOLDER], TRUE, TRUE); - set_current_val(&vars[V_READ_MESSAGE_FOLDER], TRUE, TRUE); - set_current_val(&vars[V_FORM_FOLDER], TRUE, TRUE); -+ set_current_val(&vars[V_COMPOSE_RULES], TRUE, TRUE); -+ set_current_val(&vars[V_FORWARD_RULES], TRUE, TRUE); -+ set_current_val(&vars[V_INDEX_RULES], TRUE, TRUE); -+ set_current_val(&vars[V_REPLACE_RULES], TRUE, TRUE); -+ set_current_val(&vars[V_REPLY_INDENT_RULES], TRUE, TRUE); -+ set_current_val(&vars[V_REPLY_LEADIN_RULES], TRUE, TRUE); -+ set_current_val(&vars[V_RESUB_RULES], TRUE, TRUE); -+ set_current_val(&vars[V_SAVE_RULES], TRUE, TRUE); -+ set_current_val(&vars[V_SMTP_RULES], TRUE, TRUE); -+ set_current_val(&vars[V_SORT_RULES], TRUE, TRUE); -+ set_current_val(&vars[V_STARTUP_RULES], TRUE, TRUE); - set_current_val(&vars[V_EDITOR], TRUE, TRUE); - set_current_val(&vars[V_SPELLER], TRUE, TRUE); -+ set_current_val(&vars[V_SPECIAL_TEXT], TRUE, TRUE); - set_current_val(&vars[V_IMAGE_VIEWER], TRUE, TRUE); - set_current_val(&vars[V_BROWSER], TRUE, TRUE); - set_current_val(&vars[V_SMTP_SERVER], TRUE, TRUE); -*************** -*** 2076,2081 **** ---- 2172,2184 ---- - else - ps->tcp_query_timeout = i; - -+ set_current_val(&vars[V_INCFLDTIMEO], TRUE, TRUE); -+ ps->incfld_timeout = i = INCFLD_THRESHOLD; -+ if(VAR_INCFLDTIMEO && SVAR_INCFLDQUERY(ps, i, tmp_20k_buf)) -+ init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf); -+ else -+ ps->incfld_timeout = i; -+ - set_current_val(&vars[V_NEWSRC_PATH], TRUE, TRUE); - if(VAR_NEWSRC_PATH && VAR_NEWSRC_PATH[0]) - mail_parameters(NULL, SET_NEWSRC, (void *)VAR_NEWSRC_PATH); -*************** -*** 2090,2095 **** ---- 2193,2202 ---- - mail_parameters(NULL, SET_NEWSSPOOL, - (void *)VAR_NEWS_SPOOL_DIR); - -+ set_current_val(&vars[V_MAILDIR_LOCATION], TRUE, TRUE); -+ if(VAR_MAILDIR_LOCATION && VAR_MAILDIR_LOCATION[0]) -+ maildir_parameters(SET_INBOXPATH, (void *)VAR_MAILDIR_LOCATION); -+ - /* guarantee a save default */ - set_current_val(&vars[V_DEFAULT_SAVE_FOLDER], TRUE, TRUE); - if(!VAR_DEFAULT_SAVE_FOLDER || !VAR_DEFAULT_SAVE_FOLDER[0]) -*************** -*** 2323,2330 **** - set_current_val(&vars[V_PRUNED_FOLDERS], TRUE, TRUE); - set_current_val(&vars[V_ARCHIVED_FOLDERS], TRUE, TRUE); - set_current_val(&vars[V_INCOMING_FOLDERS], TRUE, TRUE); - set_current_val(&vars[V_SORT_KEY], TRUE, TRUE); -! if(decode_sort(VAR_SORT_KEY, &ps->def_sort, &def_sort_rev) == -1){ - sprintf(tmp_20k_buf, "Sort type \"%.200s\" is invalid", VAR_SORT_KEY); - init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf); - ps->def_sort = SortArrival; ---- 2430,2438 ---- - set_current_val(&vars[V_PRUNED_FOLDERS], TRUE, TRUE); - set_current_val(&vars[V_ARCHIVED_FOLDERS], TRUE, TRUE); - set_current_val(&vars[V_INCOMING_FOLDERS], TRUE, TRUE); -+ set_current_val(&vars[V_INCOMING_FOLDERS_CHECK], TRUE, TRUE); - set_current_val(&vars[V_SORT_KEY], TRUE, TRUE); -! if(decode_sort(VAR_SORT_KEY, &ps->def_sort, &def_sort_rev,0) == -1){ - sprintf(tmp_20k_buf, "Sort type \"%.200s\" is invalid", VAR_SORT_KEY); - init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf); - ps->def_sort = SortArrival; -*************** -*** 2333,2338 **** ---- 2441,2457 ---- - else - ps->def_sort_rev = def_sort_rev; - -+ set_current_val(&vars[V_THREAD_SORT_KEY], TRUE, TRUE); -+ if(decode_sort(VAR_THREAD_SORT_KEY, &ps->thread_def_sort, -+ &thread_def_sort_rev, 1) == -1){ -+ sprintf(tmp_20k_buf, "Sort type \"%s\" is invalid", VAR_THREAD_SORT_KEY); -+ init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf); -+ ps->thread_def_sort = SortThread; -+ ps->thread_def_sort_rev = 0; -+ } -+ else -+ ps->thread_def_sort_rev = thread_def_sort_rev; -+ - cur_rule_value(&vars[V_SAVED_MSG_NAME_RULE], TRUE, TRUE); - {NAMEVAL_S *v; int i; - for(i = 0; v = save_msg_rules(i); i++) -*************** -*** 2360,2370 **** ---- 2479,2492 ---- - cur_rule_value(&vars[V_TITLEBAR_COLOR_STYLE], TRUE, TRUE); - cur_rule_value(&vars[V_FLD_SORT_RULE], TRUE, TRUE); - cur_rule_value(&vars[V_INCOMING_STARTUP], TRUE, TRUE); -+ cur_rule_value(&vars[V_INCOMING_RULE], TRUE, TRUE); - cur_rule_value(&vars[V_PRUNING_RULE], TRUE, TRUE); - cur_rule_value(&vars[V_REOPEN_RULE], TRUE, TRUE); - cur_rule_value(&vars[V_GOTO_DEFAULT_RULE], TRUE, TRUE); - cur_rule_value(&vars[V_THREAD_DISP_STYLE], TRUE, TRUE); - cur_rule_value(&vars[V_THREAD_INDEX_STYLE], TRUE, TRUE); -+ cur_rule_value(&vars[V_THREAD_DISP_STYLE_RULES], TRUE, TRUE); -+ cur_rule_value(&vars[V_THREAD_INDEX_STYLE_RULES], TRUE, TRUE); - - set_current_val(&vars[V_THREAD_MORE_CHAR], TRUE, TRUE); - if(VAR_THREAD_MORE_CHAR[0] && VAR_THREAD_MORE_CHAR[1]){ -*************** -*** 2418,2423 **** ---- 2540,2546 ---- - if(VAR_INIT_CMD_LIST && VAR_INIT_CMD_LIST[0] && VAR_INIT_CMD_LIST[0][0]) - process_init_cmds(ps, VAR_INIT_CMD_LIST); - -+ create_rule_list(); - #ifdef _WINDOWS - mswin_set_quit_confirm (F_OFF(F_QUIT_WO_CONFIRM, ps_global)); - if(ps_global->update_registry != UREG_NEVER_SET){ -*************** -*** 2607,2612 **** ---- 2730,2737 ---- - F_STRIP_WS_BEFORE_SEND, h_config_strip_ws_before_send, PREF_COMP}, - - /* Reply Prefs */ -+ {"alternate-reply-menu", -+ F_ALT_REPLY_MENU, h_config_alt_reply_menu, PREF_RPLY}, - {"enable-reply-indent-string-editing", - F_ENABLE_EDIT_REPLY_INDENT, h_config_prefix_editing, PREF_RPLY}, - {"include-attachments-in-reply", -*************** -*** 2641,2646 **** ---- 2766,2773 ---- - F_AUTO_FCC_ONLY, h_config_auto_fcc_only, PREF_SEND}, - {"fcc-without-attachments", - F_NO_FCC_ATTACH, h_config_no_fcc_attach, PREF_SEND}, -+ {"return-path-uses-domain-name", -+ F_USE_DOMAIN_NAME, h_config_use_domain, PREF_SEND}, - {"mark-fcc-seen", - F_MARK_FCC_SEEN, h_config_mark_fcc_seen, PREF_SEND}, - {"send-without-confirm", -*************** -*** 2661,2666 **** ---- 2788,2797 ---- - F_ENABLE_DOT_FOLDERS, h_config_enable_dot_folders, PREF_FLDR}, - {"enable-incoming-folders", - F_ENABLE_INCOMING, h_config_enable_incoming, PREF_FLDR}, -+ {"enable-check-incoming-folders", -+ F_ENABLE_INCOMING_CHECK, h_config_enable_check_incoming, PREF_FLDR}, -+ {"recheck-all-incoming-folders", -+ F_ENABLE_INCOMING_RECHECK, h_config_enable_recheck_incoming,PREF_FLDR}, - {"enable-lame-list-mode", - F_FIX_BROKEN_LIST, h_config_lame_list_mode, PREF_FLDR}, - {"expanded-view-of-folders", -*************** -*** 2677,2682 **** ---- 2808,2815 ---- - F_SORT_DEFAULT_SAVE_ALPHA, h_config_sort_save_alpha, PREF_FLDR}, - {"vertical-folder-list", - F_VERTICAL_FOLDER_LIST, h_config_vertical_list, PREF_FLDR}, -+ {"use-courier-folder-list", -+ F_COURIER_FOLDER_LIST, h_config_courier_list, PREF_FLDR}, - - /* Addr book */ - {"combined-addrbook-display", -*************** -*** 2693,2698 **** ---- 2826,2833 ---- - /* Index prefs */ - {"auto-open-next-unread", - F_AUTO_OPEN_NEXT_UNREAD, h_config_auto_open_unread, PREF_INDX}, -+ {"enable-circular-tab", -+ F_AUTO_CIRCULAR_TAB, h_config_circular_tab, PREF_INDX}, - {"continue-tab-without-confirm", - F_TAB_NO_CONFIRM, h_config_tab_no_prompt, PREF_INDX}, - {"delete-skips-deleted", -*************** -*** 2715,2720 **** ---- 2850,2857 ---- - F_TAB_TO_NEW, h_config_tab_new_only, PREF_INDX}, - {"thread-index-shows-important-color", - F_COLOR_LINE_IMPORTANT, h_config_color_thrd_import, PREF_INDX}, -+ {"enhanced-fancy-thread-support", -+ F_ENHANCED_THREAD, h_config_enhanced_thread, PREF_INDX}, - - /* Viewer prefs */ - {"enable-msg-view-addresses", -*************** -*** 2820,2825 **** ---- 2957,2964 ---- - F_FORCE_LOW_SPEED, h_config_force_low_speed, PREF_OS_LWSD}, - {"auto-move-read-msgs", - F_AUTO_READ_MSGS, h_config_auto_read_msgs, PREF_MISC}, -+ {"auto-move-read-msgs-using-rules", -+ F_AUTO_READ_MSGS_RULES, h_config_auto_read_msgs_rules, PREF_MISC}, - {"auto-unzoom-after-apply", - F_AUTO_UNZOOM, h_config_auto_unzoom, PREF_MISC}, - {"auto-zoom-after-select", -*************** -*** 3767,3772 **** ---- 3906,3928 ---- - ? &is_rules[index] : NULL); - } - -+ /* -+ * Standard way to get incoming check rules... -+ */ -+ NAMEVAL_S * -+ incoming_check_rules(index) -+ int index; -+ { -+ static NAMEVAL_S is_rules[] = { -+ {"automatic", NULL, IC_AUTO}, -+ {"automatic-after-first-manual-check", NULL, IC_MAN_AUTO}, -+ {"manual-only", NULL, IC_MAN} -+ }; -+ -+ return((index >= 0 && index < (sizeof(is_rules)/sizeof(is_rules[0]))) -+ ? &is_rules[index] : NULL); -+ } -+ - - NAMEVAL_S * - startup_rules(index) -*************** -*** 4201,4210 **** - if(i > 0){ - ps->initial_cmds = (int *)fs_get((i+1) * sizeof(int)); - ps->free_initial_cmds = ps->initial_cmds; - for(j = 0; j < i; j++) -! ps->initial_cmds[j] = i_cmds[j]; -! -! ps->initial_cmds[i] = 0; - ps->in_init_seq = ps->save_in_init_seq = 1; - } - } ---- 4357,4371 ---- - if(i > 0){ - ps->initial_cmds = (int *)fs_get((i+1) * sizeof(int)); - ps->free_initial_cmds = ps->initial_cmds; -+ ps->initial_cmds_backup = (int *)fs_get((i+1) * sizeof(int)); -+ ps->free_initial_cmds_backup = ps->initial_cmds_backup; - for(j = 0; j < i; j++) -! ps->initial_cmds[j] = ps->initial_cmds_backup[j] = i_cmds[j]; -! #define ctrl_x 24 -! if (i > 1) -! ps->send_immediately = i_cmds[i - 2] == ctrl_x -! && ((i_cmds[i - 1] == 'y') || (i_cmds[i-1] == 'Y')); -! ps->initial_cmds[i] = ps->initial_cmds_backup[i] = 0; - ps->in_init_seq = ps->save_in_init_seq = 1; - } - } -*************** -*** 6442,6464 **** - * argument also means arrival/reverse. - */ - int -! decode_sort(sort_spec, def_sort, def_sort_rev) - char *sort_spec; - SortOrder *def_sort; - int *def_sort_rev; - { - char *sep; - char *fix_this = NULL; -! int x, reverse; - - if(!sort_spec || !*sort_spec){ -! *def_sort = SortArrival; - *def_sort_rev = 0; - return(0); - } - - if(struncmp(sort_spec, "reverse", strlen(sort_spec)) == 0){ -! *def_sort = SortArrival; - *def_sort_rev = 1; - return(0); - } ---- 6603,6626 ---- - * argument also means arrival/reverse. - */ - int -! decode_sort(sort_spec, def_sort, def_sort_rev, thread) - char *sort_spec; - SortOrder *def_sort; - int *def_sort_rev; -+ int thread; - { - char *sep; - char *fix_this = NULL; -! int x = 0, reverse; - - if(!sort_spec || !*sort_spec){ -! *def_sort = thread ? SortThread : SortArrival; - *def_sort_rev = 0; - return(0); - } - - if(struncmp(sort_spec, "reverse", strlen(sort_spec)) == 0){ -! *def_sort = thread ? SortThread : SortArrival; - *def_sort_rev = 1; - return(0); - } -*************** -*** 6481,6493 **** - sort_spec, strlen(sort_spec)) == 0) - break; - - if(fix_this) - *fix_this = '/'; - - if(ps_global->sort_types[x] == EndofList) - return(-1); - -! *def_sort = ps_global->sort_types[x]; - *def_sort_rev = reverse; - return(0); - } ---- 6643,6661 ---- - sort_spec, strlen(sort_spec)) == 0) - break; - -+ if (thread && ps_global->sort_types[x] != SortArrival -+ && ps_global->sort_types[x] != SortDate -+ && ps_global->sort_types[x] != SortThread) -+ for(x = 0; ps_global->sort_types[x] != EndofList; x++); -+ - if(fix_this) - *fix_this = '/'; - - if(ps_global->sort_types[x] == EndofList) - return(-1); - -! *def_sort = (thread && ps_global->sort_types[x] == SortDate) -! ? SortThread : ps_global->sort_types[x]; - *def_sort_rev = reverse; - return(0); - } -*************** -*** 11038,11043 **** ---- 11206,11219 ---- - break; - } - } -+ else if(var == &ps_global->vars[V_INCOMING_RULE]){ -+ if(ps_global->VAR_INCOMING_RULE) -+ for(i = 0; v = incoming_check_rules(i); i++) -+ if(!strucmp(ps_global->VAR_INCOMING_RULE, S_OR_L(v))){ -+ ps_global->inc_check_rule = v->value; -+ break; -+ } -+ } - else if(var == &ps_global->vars[V_PRUNING_RULE]){ - if(ps_global->VAR_PRUNING_RULE) - for(i = 0; v = pruning_rules(i); i++) -diff -rc pine4.63/pine/mailcmd.c pine4.63.I.USE/pine/mailcmd.c -*** pine4.63/pine/mailcmd.c Wed Apr 27 11:54:59 2005 ---- pine4.63.I.USE/pine/mailcmd.c Thu May 19 19:57:34 2005 -*************** -*** 58,63 **** ---- 58,64 ---- - /* - * Internal Prototypes - */ -+ void cmd_quota PROTO((struct pine *)); - void cmd_delete PROTO((struct pine *, MSGNO_S *, int, CmdWhere)); - void cmd_undelete PROTO((struct pine *, MSGNO_S *, int)); - void cmd_reply PROTO((struct pine *, MSGNO_S *, int)); -*************** -*** 89,99 **** - int save_ex_explain_body PROTO((BODY *, unsigned long *, gf_io_t)); - int save_ex_explain_parts PROTO((BODY *, int, unsigned long *, gf_io_t)); - int save_ex_output_line PROTO((char *, unsigned long *, gf_io_t)); - int create_for_save PROTO((MAILSTREAM *, CONTEXT_S *, char *)); - void set_keywords_in_msgid_msg PROTO((MAILSTREAM *, MESSAGECACHE *, - MAILSTREAM *, char *, long)); - long get_msgno_by_msg_id PROTO((MAILSTREAM *, char *, MSGNO_S *)); -! int select_sort PROTO((struct pine *, int, SortOrder *, int *)); - void aggregate_select PROTO((struct pine *, MSGNO_S *, int, CmdWhere,int)); - int select_number PROTO((MAILSTREAM *, MSGNO_S *, SEARCHSET **)); - int select_thrd_number PROTO((MAILSTREAM *, MSGNO_S *, SEARCHSET **)); ---- 90,103 ---- - int save_ex_explain_body PROTO((BODY *, unsigned long *, gf_io_t)); - int save_ex_explain_parts PROTO((BODY *, int, unsigned long *, gf_io_t)); - int save_ex_output_line PROTO((char *, unsigned long *, gf_io_t)); -+ void total_messages_status PROTO ((MAILSTREAM *, int, unsigned long *, -+ unsigned long *)); -+ char *any_report_message PROTO ((MAILSTREAM *)); - int create_for_save PROTO((MAILSTREAM *, CONTEXT_S *, char *)); - void set_keywords_in_msgid_msg PROTO((MAILSTREAM *, MESSAGECACHE *, - MAILSTREAM *, char *, long)); - long get_msgno_by_msg_id PROTO((MAILSTREAM *, char *, MSGNO_S *)); -! int select_sort PROTO((struct pine *, int, SortOrder *, int *, int)); - void aggregate_select PROTO((struct pine *, MSGNO_S *, int, CmdWhere,int)); - int select_number PROTO((MAILSTREAM *, MSGNO_S *, SEARCHSET **)); - int select_thrd_number PROTO((MAILSTREAM *, MSGNO_S *, SEARCHSET **)); -*************** -*** 109,114 **** ---- 113,139 ---- - char *currentf_sequence PROTO((MAILSTREAM *, MSGNO_S *, long, long *, - int, char **, char **)); - char *invalid_elt_sequence PROTO((MAILSTREAM *, MSGNO_S *)); -+ long top_thread PROTO((MAILSTREAM *, long)); -+ void move_top_thread PROTO((MAILSTREAM *, MSGNO_S *, long)); -+ long top_this_thread PROTO((MAILSTREAM *, long)); -+ void move_top_this_thread PROTO((MAILSTREAM *, MSGNO_S *, long)); -+ void cmd_delete_this_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *)); -+ void cmd_delete_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *)); -+ void cmd_undelete_this_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *)); -+ void cmd_undelete_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *)); -+ void cmd_select_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *)); -+ void kolapse_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, char, int)); -+ int count_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, long)); -+ int count_this_thread PROTO((MAILSTREAM *, unsigned long)); -+ int this_thread_is_kolapsed PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, long)); -+ int thread_is_kolapsed PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, long)); -+ int collapse_this_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, int, int)); -+ void collapse_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, int)); -+ int expand_this_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, int, int)); -+ void expand_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, int)); -+ int move_next_this_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, int)); -+ int move_next_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, int)); -+ int move_prev_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, int)); - char *selected_sequence PROTO((MAILSTREAM *, MSGNO_S *, long *, int)); - int any_messages PROTO((MSGNO_S *, char *, char *)); - int can_set_flag PROTO((struct pine *, char *, int)); -*************** -*** 119,124 **** ---- 144,155 ---- - int read_msg_prompt PROTO((long, char *)); - char *move_read_incoming PROTO((MAILSTREAM *, CONTEXT_S *, char *, - char **, char *)); -+ char *move_read_msgs_using_rules PROTO((MAILSTREAM *, char *, char *)); -+ unsigned get_perfolder_startup_rule PROTO((MAILSTREAM *, int, char *)); -+ void setup_threading_index_style PROTO(()); -+ int find_startup_position PROTO((int, MAILSTREAM *, long)); -+ char *get_rule_result PROTO((int, char *, int)); -+ char *get_folder_to_save PROTO((MAILSTREAM *, long, char *)); - void cross_delete_crossposts PROTO((MAILSTREAM *)); - void menu_clear_cmd_binding PROTO((struct key_menu *, int)); - int update_folder_spec PROTO((char *, char *)); -*************** -*** 141,146 **** ---- 172,180 ---- - #define SV_FOR_FILT 0x2 - #define SV_FIX_DELS 0x4 - -+ static MAILSTREAM *saved_stream; -+ static unsigned long rule_curpos = 0L; -+ - typedef struct append_package { - MAILSTREAM *stream; - char *flags; -*************** -*** 267,272 **** ---- 301,307 ---- - {'r', 'r', "R", "Recipient"}, - {'p', 'p', "P", "Participant"}, - {'b', 'b', "B", "Body"}, -+ {'h', 'h', "H", "Header"}, - {-1, 0, NULL, NULL} - }; - -*************** -*** 936,942 **** - state->context_current, &recent_cnt, - F_ON(F_TAB_NO_CONFIRM,state) - ? NULL : &did_cancel))){ -! if(!in_inbox){ - static ESCKEY_S inbox_opt[] = { - {'y', 'y', "Y", "Yes"}, - {'n', 'n', "N", "No"}, ---- 971,977 ---- - state->context_current, &recent_cnt, - F_ON(F_TAB_NO_CONFIRM,state) - ? NULL : &did_cancel))){ -! if(!in_inbox && F_OFF(F_AUTO_CIRCULAR_TAB,state)){ - static ESCKEY_S inbox_opt[] = { - {'y', 'y', "Y", "Yes"}, - {'n', 'n', "N", "No"}, -*************** -*** 1186,1191 **** ---- 1221,1230 ---- - if(SORT_IS_THREADED(msgmap)) - refresh_sort(stream, msgmap, SRT_NON); - -+ if (msgmap->nmsgs -+ && F_ON(F_ENHANCED_THREAD, state) && COLL_THRDS()) -+ kolapse_thread(state, stream, msgmap, '[', 0); -+ - state->mangled_body = 1; - state->mangled_header = 1; - q_status_message2(SM_ORDER, 0, 4, -*************** -*** 1256,1261 **** ---- 1295,1301 ---- - ps_global->expunge_in_progress = 0; - if(we_cancel) - cancel_busy_alarm((sp_expunge_count(stream) > 0) ? 0 : -1); -+ update_incoming_folder_data(stream, state->context_current); - - dprint(2,(debugfile,"expunge complete cur:%ld max:%ld\n", - mn_get_cur(msgmap), mn_get_total(msgmap))); -*************** -*** 1298,1303 **** ---- 1338,1346 ---- - */ - if(SORT_IS_THREADED(msgmap)) - refresh_sort(stream, msgmap, SRT_NON); -+ if (msgmap->nmsgs -+ && F_ON(F_ENHANCED_THREAD, state) && COLL_THRDS()) -+ kolapse_thread(state, stream, msgmap, '[', 0); - } - else{ - if(del_count) -*************** -*** 1434,1440 **** - if(any_messages(msgmap, NULL, NULL)){ - if(any_lflagged(msgmap, MN_SLCT) > 0L){ - if(apply_command(state, stream, msgmap, 0, -! AC_NONE, question_line) - && F_ON(F_AUTO_UNZOOM, state)) - unzoom_index(state, stream, msgmap); - } ---- 1477,1483 ---- - if(any_messages(msgmap, NULL, NULL)){ - if(any_lflagged(msgmap, MN_SLCT) > 0L){ - if(apply_command(state, stream, msgmap, 0, -! AC_NONE, question_line, 1) - && F_ON(F_AUTO_UNZOOM, state)) - unzoom_index(state, stream, msgmap); - } -*************** -*** 1447,1464 **** - - /*-------- Sort command -------*/ - case MC_SORT : - { - int were_threading = THREADING(); - SortOrder sort = mn_get_sort(msgmap); - int rev = mn_get_revsort(msgmap); - - dprint(1, (debugfile,"MAIL_CMD: sort\n")); -! if(select_sort(state, question_line, &sort, &rev)){ - /* $ command reinitializes threading collapsed/expanded info */ - if(SORT_IS_THREADED(msgmap) && !SEP_THRDINDX()) - erase_threading_info(stream, msgmap); - -! sort_folder(stream, msgmap, sort, rev, SRT_VRB|SRT_MAN); - } - - state->mangled_footer = 1; ---- 1490,1514 ---- - - /*-------- Sort command -------*/ - case MC_SORT : -+ case MC_SORTHREAD : - { - int were_threading = THREADING(); - SortOrder sort = mn_get_sort(msgmap); - int rev = mn_get_revsort(msgmap); -+ int thread = (command == MC_SORT) ? 0 : 1; - -+ if (sort == SortThread) -+ sort = ps_global->thread_cur_sort; - dprint(1, (debugfile,"MAIL_CMD: sort\n")); -! if(select_sort(state, question_line, &sort, &rev, thread)){ - /* $ command reinitializes threading collapsed/expanded info */ - if(SORT_IS_THREADED(msgmap) && !SEP_THRDINDX()) - erase_threading_info(stream, msgmap); - -! if (command == MC_SORTHREAD) -! ps_global->thread_cur_sort = sort; -! sort = (command == MC_SORT) ? sort : SortThread; -! sort_folder(stream, msgmap, sort, rev, SRT_VRB|SRT_MAN, 1); - } - - state->mangled_footer = 1; -*************** -*** 1533,1538 **** ---- 1583,1594 ---- - break; - - -+ /*--------Incoming Folders Auto Check --------*/ -+ case MC_FORCECHECK: -+ state->force_check_now = 1; -+ new_mail_incfolder(state,command); -+ break; -+ - /*--------- Default, unknown command ----------*/ - default: - panic("Unexpected command case"); -*************** -*** 1940,1945 **** ---- 1996,2163 ---- - } - - -+ static struct key quota_keys[] = -+ {HELP_MENU, -+ NULL_MENU, -+ {"E","Exit",{MC_EXIT,3,{'e','i',ctrl('C')}},KS_EXITMODE}, -+ NULL_MENU, -+ NULL_MENU, -+ NULL_MENU, -+ NULL_MENU, -+ NULL_MENU, -+ NULL_MENU, -+ NULL_MENU, -+ NULL_MENU, -+ NULL_MENU}; -+ INST_KEY_MENU(pine_quota_keymenu, quota_keys); -+ -+ int process_quota_cmd(cmd, msgmap, sparms) -+ int cmd; -+ MSGNO_S *msgmap; -+ SCROLL_S *sparms; -+ { -+ return cmd; -+ } -+ -+ -+ void cmd_quota (state) -+ struct pine *state; -+ { -+ QUOTALIST *imapquota; -+ NETMBX mb; -+ unsigned long len, storageuse, storagelim, messageuse, messagelim; -+ STORE_S *store; -+ SCROLL_S sargs; -+ char *linedata; -+ char *storageq = NULL, *messageq = NULL; -+ int storage=0, message=0, other=0, storagelen = 0, messagelen = 0; -+ -+ if(!state->mail_stream || !is_imap_stream(state->mail_stream)){ -+ q_status_message(SM_ORDER, 1, 5, "Quota only available for IMAP folders"); -+ return; -+ } -+ -+ if (state->mail_stream -+ && !sp_dead_stream(state->mail_stream) -+ && state->mail_stream->mailbox -+ && *state->mail_stream->mailbox -+ && mail_valid_net_parse(state->mail_stream->mailbox, &mb)) -+ imap_getquotaroot(state->mail_stream, mb.mailbox); -+ -+ if(!state->quota) /* failed ? */ -+ return; /* go back... */ -+ -+ if(!(store = so_get(CharStar, NULL, EDIT_ACCESS))){ -+ q_status_message(SM_ORDER | SM_DING, 3, 3, "Error allocating space."); -+ return; -+ } -+ -+ if (state->mail_stream && state->mail_stream->original_mailbox){ -+ len = strlen(state->mail_stream->original_mailbox) + 18; -+ linedata = (char *) fs_get(len*sizeof(char)); -+ sprintf(linedata,"Quota Report for %s\n", -+ state->mail_stream->original_mailbox); -+ so_puts(store,linedata); -+ if (linedata) -+ fs_give((void **)&linedata); -+ } -+ else -+ so_puts(store,"Quota Report:\n"); -+ so_puts(store,"\n"); -+ -+ for (imapquota = state->quota; imapquota; imapquota = imapquota->next){ -+ if(!strucmp(imapquota->name,"STORAGE")){ -+ storage++; -+ storagelen = strlen(long2string(imapquota->limit)) + 1; -+ storageuse = imapquota->usage; -+ storagelim = imapquota->limit; -+ } -+ if(!strucmp(imapquota->name,"MESSAGE")){ -+ message++; -+ messagelen = strlen(long2string(imapquota->limit)) + 1; -+ messageuse = imapquota->usage; -+ messagelim = imapquota->limit; -+ } -+ other += strucmp(imapquota->name,"STORAGE") && -+ strucmp(imapquota->name,"MESSAGE") ? 0 : 1; -+ } -+ -+ storageq = (char *) fs_get(storagelen*sizeof(char)); -+ if (storage) -+ sprintf(storageq, "%lu KB", storageuse); -+ messageq = (char *) fs_get(messagelen*sizeof(char)); -+ if (message) -+ sprintf(messageq, "%lu message%s", messageuse, plural(messageuse)); -+ len = strlen("Usage: ") + storagelen + messagelen + 20; -+ linedata = (char *) fs_get(len*sizeof(char)); -+ sprintf(linedata,"Usage: %s%s%s%s\n", storage ? storageq : "", -+ message ? (storage ? " (" : "") : "", -+ message ? messageq : "", -+ message ? (storage ? ")" : "") : ""); -+ so_puts(store, linedata); -+ if (storageq) -+ fs_give((void **)&storageq); -+ if (messageq) -+ fs_give((void **)&messageq); -+ if (linedata) -+ fs_give((void **)&linedata); -+ -+ storageq = (char *) fs_get(storagelen*sizeof(char)); -+ if (storage) -+ sprintf(storageq, "%lu KB", storagelim); -+ messageq = (char *) fs_get(messagelen*sizeof(char)); -+ if (message) -+ sprintf(messageq, "%lu message%s", messagelim, plural(messagelim)); -+ len = strlen("Limit: ") + storagelen + messagelen + 20; -+ linedata = (char *) fs_get(len*sizeof(char)); -+ sprintf(linedata,"Limit: %s%s%s%s", storage ? storageq : "", -+ message ? (storage ? " (" : "") : "", -+ message ? messageq : "", -+ message ? (storage ? ")" : "") : ""); -+ so_puts(store, linedata); -+ if (storageq) -+ fs_give((void **)&storageq); -+ if (messageq) -+ fs_give((void **)&messageq); -+ if (linedata) -+ fs_give((void **)&linedata); -+ -+ for (imapquota = state->quota; other && imapquota; -+ imapquota = imapquota->next){ -+ if (strucmp(imapquota->name,"STORAGE") && -+ strucmp(imapquota->name,"MESSAGE")){ -+ len = (imapquota->name ? strlen(imapquota->name) : strlen("No Name")) -+ + 2*strlen(long2string(imapquota->limit)) + 46; -+ linedata = (char *) fs_get(len*sizeof(char)); -+ sprintf(linedata, -+ "Resource : %s\nUsage : %lu (%lu%%)\nLimit : %lu\n\n", -+ imapquota->name ? imapquota->name : "No Name", -+ imapquota->usage, 100*imapquota->usage/imapquota->limit, -+ imapquota->limit); -+ so_puts(store,linedata); -+ if (linedata) -+ fs_give((void **)&linedata); -+ } -+ } -+ -+ memset(&sargs, 0, sizeof(SCROLL_S)); -+ sargs.text.text = so_text(store); -+ sargs.text.src = CharStar; -+ sargs.text.desc = "Quota Resources Summary"; -+ sargs.bar.title = cpystr("QUOTA SUMMARY"); -+ sargs.proc.tool = process_quota_cmd; -+ sargs.help.text = NO_HELP; -+ sargs.help.title = NULL; -+ sargs.keys.menu = &pine_quota_keymenu; -+ setbitmap(sargs.keys.bitmap); -+ -+ scrolltool(&sargs); -+ so_give(&store); -+ -+ if (state->quota) -+ mail_free_quotalist(&(state->quota)); -+ } -+ - /*---------------------------------------------------------------------- - Execute DELETE message command - -*************** -*** 2928,2933 **** ---- 3146,3152 ---- - - dprint(4, (debugfile, "\n - saving message -\n")); - -+ saved_stream = stream; /* ugly hack! */ - state->ugly_consider_advancing_bit = 0; - if(F_OFF(F_SAVE_PARTIAL_WO_CONFIRM, state) - && msgno_any_deletedparts(stream, msgmap) -*************** -*** 3175,3181 **** - { - static char folder[MAILTMPLEN+1] = {'\0'}; - static CONTEXT_S *last_context = NULL; -! int rc, n, flags, last_rc = 0, saveable_count = 0, done = 0; - int context_was_set, delindex; - char prompt[MAX_SCREEN_COLS+1], *p, expanded[MAILTMPLEN]; - char *buf = tmp_20k_buf; ---- 3394,3400 ---- - { - static char folder[MAILTMPLEN+1] = {'\0'}; - static CONTEXT_S *last_context = NULL; -! int rc, n=0, flags, last_rc = 0, saveable_count = 0, done = 0; - int context_was_set, delindex; - char prompt[MAX_SCREEN_COLS+1], *p, expanded[MAILTMPLEN]; - char *buf = tmp_20k_buf; -*************** -*** 3184,3189 **** ---- 3403,3411 ---- - char *deltext = NULL; - CONTEXT_S *tc; - ESCKEY_S ekey[9]; -+ RULE_RESULT *rule; -+ -+ saved_stream = state->mail_stream; - - if(!cntxt) - panic("no context ptr in save_prompt"); -*************** -*** 3214,3219 **** ---- 3436,3448 ---- - return(0); - } - -+ if (rule = get_result_rule(V_SAVE_RULES, FOR_RULE | FOR_SAVE, env)){ -+ strncpy(folder,rule->result,sizeof(folder)-1); -+ folder[sizeof(folder)-1] = '\0'; -+ if (rule->result) -+ fs_give((void **)&rule->result); -+ fs_give((void **)&rule); -+ } - - /* how many context's can be saved to... */ - for(tc = state->context_list; tc; tc = tc->next) -*************** -*** 4134,4140 **** - *date = '\0'; - - rv = save_fetch_append(stream, mn_m2raw(msgmap, i), -! NULL, save_stream, save_folder, context, - mc ? mc->rfc822_size : 0L, flags, date, so); - - if(sp_expunge_count(stream)) ---- 4363,4369 ---- - *date = '\0'; - - rv = save_fetch_append(stream, mn_m2raw(msgmap, i), -! NULL, save_stream, folder, context, - mc ? mc->rfc822_size : 0L, flags, date, so); - - if(sp_expunge_count(stream)) -*************** -*** 7265,7270 **** ---- 7494,7558 ---- - return(newfolder); - } - -+ char * -+ any_report_message (stream) -+ MAILSTREAM *stream; -+ { -+ char message[40] = {'\0'}, *report; -+ unsigned long new, unseen; -+ int i, imapstatus = 0; -+ -+ for (i = 0; ps_global->index_disp_format[i].ctype != iNothing -+ && ps_global->index_disp_format[i].ctype != iIStatus; i++); -+ imapstatus = ps_global->index_disp_format[i].ctype == iIStatus; -+ -+ report = (char *) fs_get(41*sizeof(char)); -+ total_messages_status(stream, imapstatus, &new, &unseen); -+ -+ if (new > 0L || (unseen > 0L && imapstatus)){ -+ sprintf(message," - %s%s%s%s%s", new > 0L ? comatose(new) : "", -+ new > 0L ? " new" : "", -+ new > 0L && unseen > 0L && imapstatus ? ", " : "", -+ unseen > 0L && imapstatus ? comatose(unseen) : "", -+ unseen > 0L && imapstatus ? " unseen" : ""); -+ } -+ report = *message ? cpystr(message) : cpystr(""); -+ -+ return report; -+ } -+ -+ void -+ total_messages_status (stream, imapstatus, new, unseen) -+ MAILSTREAM *stream; -+ int imapstatus; -+ unsigned long *new, *unseen; -+ { -+ MESSAGECACHE *mc; -+ unsigned long i; -+ int *searched; -+ -+ if (new) *new = imapstatus ? count_flagged(stream, F_RECENT | F_UNDEL) -+ : count_flagged(stream, F_UNSEEN | F_UNDEL); -+ if (unseen) *unseen = 0L; -+ -+ if (!imapstatus || !unseen) -+ return; -+ -+ searched = (int *) fs_get(stream->nmsgs*sizeof(int)); -+ memset(searched, 0, stream->nmsgs*sizeof(searched)); -+ for (i = 1L; stream && i <= stream->nmsgs && (mc = mail_elt(stream, i)); i++) -+ if (mc->searched -+ || (mc->valid && !get_lflag(stream, NULL, i, MN_EXLD) -+ && mc->recent && !mc->deleted)) -+ searched[i-1] = 1; -+ count_flagged(stream, F_UNSEEN | F_UNDEL); -+ for (i = 1L; stream && i <= stream->nmsgs && (mc = mail_elt(stream, i)); i++) -+ if (!searched[i-1] && (mc->searched -+ || (mc->valid && !get_lflag(stream, NULL, i, MN_EXLD) -+ && !mc->seen && !mc->recent && !mc->deleted))) -+ (*unseen)++; -+ fs_give((void **)&searched); -+ } - - /*---------------------------------------------------------------------- - Check to see if user input is in form of old c-client mailbox speck -*************** -*** 7322,7327 **** ---- 7610,7821 ---- - return(FALSE); - } - -+ void -+ setup_threading_index_style() -+ { -+ RULE_RESULT *rule; -+ NAMEVAL_S *v; -+ int i; -+ -+ rule = get_result_rule(V_THREAD_INDEX_STYLE_RULES, -+ FOR_RULE | FOR_THREAD, (ENVELOPE *) NULL); -+ if (rule || ps_global->VAR_THREAD_INDEX_STYLE){ -+ for(i = 0; v = thread_index_styles(i); i++) -+ if(!strucmp(rule ? rule->result : ps_global->VAR_THREAD_INDEX_STYLE, -+ rule ? (v ? v->name : "" ) : S_OR_L(v))){ -+ ps_global->thread_index_style = v->value; -+ break; -+ } -+ if (rule){ -+ if (rule->result) -+ fs_give((void **)&rule->result); -+ fs_give((void **)&rule); -+ } -+ } -+ } -+ -+ -+ char *get_rule_result(rule_context, newfolder, code) -+ int rule_context; -+ char *newfolder; -+ int code; -+ { char *rule_result = NULL; -+ ENVELOPE *news_envelope; -+ RULE_RESULT *rule; -+ -+ if (IS_NEWS(ps_global->mail_stream)){ -+ news_envelope = mail_newenvelope(); -+ news_envelope->newsgroups = cpystr(newfolder); -+ } -+ else -+ news_envelope = (ENVELOPE *) NULL; -+ -+ rule = get_result_rule(code, rule_context, news_envelope); -+ -+ if (news_envelope) -+ mail_free_envelope (&news_envelope); -+ -+ if (rule){ -+ rule_result = cpystr(rule->result); -+ if (rule->result) -+ fs_give((void **)&rule->result); -+ fs_give((void **)&rule); -+ } -+ -+ return rule_result; -+ } -+ -+ find_startup_position(rule, m, pc) -+ int rule; -+ MAILSTREAM *m; -+ long pc; -+ { -+ long n; -+ switch(rule){ -+ /* -+ * For news in incoming collection we're doing the same thing -+ * for first-unseen and first-recent. In both those cases you -+ * get first-unseen if FAKE_NEW is off and first-recent if -+ * FAKE_NEW is on. If FAKE_NEW is on, first unseen is the -+ * same as first recent because all recent msgs are unseen -+ * and all unrecent msgs are seen (see pine_mail_open). -+ */ -+ case IS_FIRST_UNSEEN: -+ first_unseen: -+ mn_set_cur(ps_global->msgmap, -+ (sp_first_unseen(m) -+ && mn_get_sort(ps_global->msgmap) == SortArrival -+ && !mn_get_revsort(ps_global->msgmap) -+ && !get_lflag(ps_global->mail_stream, NULL, -+ sp_first_unseen(m), MN_EXLD) -+ && (n = mn_raw2m(ps_global->msgmap, -+ sp_first_unseen(m)))) -+ ? n -+ : first_sorted_flagged(F_UNSEEN | F_UNDEL, m, pc, -+ THREADING() ? 0 : FSF_SKIP_CHID)); -+ break; -+ -+ case IS_FIRST_RECENT: -+ first_recent: -+ /* -+ * We could really use recent for news but this is the way -+ * it has always worked, so we'll leave it. That is, if -+ * the FAKE_NEW feature is on, recent and unseen are -+ * equivalent, so it doesn't matter. If the feature isn't -+ * on, all the undeleted messages are unseen and we start -+ * at the first one. User controls with the FAKE_NEW feature. -+ */ -+ if(IS_NEWS(ps_global->mail_stream)){ -+ mn_set_cur(ps_global->msgmap, -+ first_sorted_flagged(F_UNSEEN|F_UNDEL, m, pc, -+ THREADING() ? 0 : FSF_SKIP_CHID)); -+ } -+ else{ -+ mn_set_cur(ps_global->msgmap, -+ first_sorted_flagged(F_RECENT | F_UNSEEN -+ | F_UNDEL, -+ m, pc, -+ THREADING() ? 0 : FSF_SKIP_CHID)); -+ } -+ break; -+ -+ case IS_FIRST_IMPORTANT: -+ mn_set_cur(ps_global->msgmap, -+ first_sorted_flagged(F_FLAG|F_UNDEL, m, pc, -+ THREADING() ? 0 : FSF_SKIP_CHID)); -+ break; -+ -+ case IS_FIRST_IMPORTANT_OR_UNSEEN: -+ -+ if(IS_NEWS(ps_global->mail_stream)) -+ goto first_unseen; -+ -+ { -+ MsgNo flagged, first_unseen; -+ -+ flagged = first_sorted_flagged(F_FLAG|F_UNDEL, m, pc, -+ THREADING() ? 0 : FSF_SKIP_CHID); -+ first_unseen = (sp_first_unseen(m) -+ && mn_get_sort(ps_global->msgmap) == SortArrival -+ && !mn_get_revsort(ps_global->msgmap) -+ && !get_lflag(ps_global->mail_stream, NULL, -+ sp_first_unseen(m), MN_EXLD) -+ && (n = mn_raw2m(ps_global->msgmap, -+ sp_first_unseen(m)))) -+ ? n -+ : first_sorted_flagged(F_UNSEEN|F_UNDEL, m, pc, -+ THREADING() ? 0 : FSF_SKIP_CHID); -+ mn_set_cur(ps_global->msgmap, -+ (MsgNo) min((int) flagged, (int) first_unseen)); -+ -+ } -+ -+ break; -+ -+ case IS_FIRST_IMPORTANT_OR_RECENT: -+ -+ if(IS_NEWS(ps_global->mail_stream)) -+ goto first_recent; -+ -+ { -+ MsgNo flagged, first_recent; -+ -+ flagged = first_sorted_flagged(F_FLAG|F_UNDEL, m, pc, -+ THREADING() ? 0 : FSF_SKIP_CHID); -+ first_recent = first_sorted_flagged(F_RECENT | F_UNSEEN -+ | F_UNDEL, -+ m, pc, -+ THREADING() ? 0 : FSF_SKIP_CHID); -+ mn_set_cur(ps_global->msgmap, -+ (MsgNo) min((int) flagged, (int) first_recent)); -+ } -+ -+ break; -+ -+ case IS_FIRST: -+ mn_set_cur(ps_global->msgmap, -+ first_sorted_flagged(F_UNDEL, m, pc, -+ THREADING() ? 0 : FSF_SKIP_CHID)); -+ break; -+ -+ case IS_LAST: -+ mn_set_cur(ps_global->msgmap, -+ first_sorted_flagged(F_UNDEL, m, pc, -+ FSF_LAST | (THREADING() ? 0 : FSF_SKIP_CHID))); -+ break; -+ -+ default: -+ panic("Unexpected incoming startup case"); -+ break; -+ -+ } -+ } -+ -+ unsigned -+ get_perfolder_startup_rule(stream, rule_type, folder) -+ MAILSTREAM *stream; -+ int rule_type; -+ char *folder; -+ { -+ unsigned startup_rule; -+ char *rule_result; -+ -+ startup_rule = reset_startup_rule(stream); -+ rule_result = get_rule_result(FOR_RULE | FOR_STARTUP, folder, rule_type); -+ if (rule_result && *rule_result){ -+ int i; -+ NAMEVAL_S *v; -+ -+ for(i = 0; v = incoming_startup_rules(i); i++) -+ if(!strucmp(rule_result, v->name)){ -+ startup_rule = v->value; -+ break; -+ } -+ fs_give((void **)&rule_result); -+ } -+ return startup_rule; -+ } -+ - - /*---------------------------------------------------------------------- - Actually attempt to open given folder -*************** -*** 7356,7362 **** - int open_inbox, rv, old_tros, we_cancel = 0, - do_reopen = 0, n, was_dead = 0, cur_already_set = 0; - char expanded_file[max(MAXPATH,MAILTMPLEN)+1], -! *old_folder, *old_path, *p; - long openmode, rflags = 0L, pc = 0L, cur, raw; - ENVELOPE *env = NULL; - char status_msg[81]; ---- 7850,7856 ---- - int open_inbox, rv, old_tros, we_cancel = 0, - do_reopen = 0, n, was_dead = 0, cur_already_set = 0; - char expanded_file[max(MAXPATH,MAILTMPLEN)+1], -! *old_folder, *old_path, *p, *report; - long openmode, rflags = 0L, pc = 0L, cur, raw; - ENVELOPE *env = NULL; - char status_msg[81]; -*************** -*** 7690,7704 **** - sizeof(ps_global->cur_folder)-1); - ps_global->cur_folder[sizeof(ps_global->cur_folder)-1] = '\0'; - ps_global->context_current = ps_global->context_list; - reset_index_format(); - clear_index_cache(); - /* MUST sort before restoring msgno! */ - refresh_sort(ps_global->mail_stream, ps_global->msgmap, SRT_NON); -! q_status_message3(SM_ORDER, 0, 3, -! "Opened folder \"%.200s\" with %.200s message%.200s", -! ps_global->inbox_name, -! long2string(mn_get_total(ps_global->msgmap)), -! plural(mn_get_total(ps_global->msgmap))); - #ifdef _WINDOWS - mswin_settitle(ps_global->inbox_name); - #endif ---- 8184,8203 ---- - sizeof(ps_global->cur_folder)-1); - ps_global->cur_folder[sizeof(ps_global->cur_folder)-1] = '\0'; - ps_global->context_current = ps_global->context_list; -+ setup_threading_index_style(); - reset_index_format(); - clear_index_cache(); - /* MUST sort before restoring msgno! */ - refresh_sort(ps_global->mail_stream, ps_global->msgmap, SRT_NON); -! report = any_report_message(ps_global->mail_stream); -! q_status_message4(SM_ORDER, 0, 3, -! "Opened folder \"%.200s\" with %.200s message%.200s%.200s", -! ps_global->inbox_name, -! long2string(mn_get_total(ps_global->msgmap)), -! plural(mn_get_total(ps_global->msgmap)), -! report); -! if (report) -! fs_give((void **)&report); - #ifdef _WINDOWS - mswin_settitle(ps_global->inbox_name); - #endif -*************** -*** 7999,8004 **** ---- 8498,8504 ---- - - clear_index_cache(); - reset_index_format(); -+ setup_threading_index_style(); - - /* - * Start news reading with messages the user's marked deleted -*************** -*** 8018,8025 **** - if(!sp_flagged(ps_global->mail_stream, SP_FILTERED)) - process_filter_patterns(ps_global->mail_stream, ps_global->msgmap, 0L); - -! q_status_message6(SM_ORDER, 0, 4, -! "%.20s \"%.200s\" opened with %.20s message%.20s%.20s%.20s", - IS_NEWS(ps_global->mail_stream) - ? "News group" : "Folder", - pretty_fn(newfolder), ---- 8518,8533 ---- - if(!sp_flagged(ps_global->mail_stream, SP_FILTERED)) - process_filter_patterns(ps_global->mail_stream, ps_global->msgmap, 0L); - -! if(!(rflags & SP_MATCH) || !(rflags & SP_LOCKED)) -! reset_sort_order(SRT_VRB); -! else if(sp_new_mail_count(ps_global->mail_stream) > 0L -! || sp_unsorted_newmail(ps_global->mail_stream) -! || sp_need_to_rethread(ps_global->mail_stream)) -! refresh_sort(ps_global->mail_stream, ps_global->msgmap, SRT_NON); -! -! report = any_report_message(ps_global->mail_stream); -! q_status_message7(SM_ORDER, 0, 4, -! "%.20s \"%.200s\" opened with %.20s message%.20s%.20s%.20s%.20s", - IS_NEWS(ps_global->mail_stream) - ? "News group" : "Folder", - pretty_fn(newfolder), -*************** -*** 8029,8048 **** - && sp_flagged(ps_global->mail_stream, SP_PERMLOCKED)) - ? " (StayOpen)" : "", - READONLY_FOLDER(ps_global->mail_stream) -! ? " READONLY" : ""); - - #ifdef _WINDOWS - mswin_settitle(pretty_fn(newfolder)); - #endif - -- if(!(rflags & SP_MATCH) || !(rflags & SP_LOCKED)) -- reset_sort_order(SRT_VRB); -- else if(sp_new_mail_count(ps_global->mail_stream) > 0L -- || sp_unsorted_newmail(ps_global->mail_stream) -- || sp_need_to_rethread(ps_global->mail_stream)) -- refresh_sort(ps_global->mail_stream, ps_global->msgmap, SRT_NON); -- -- - /* - * Set current message number when re-opening Stay-Open or - * cached folders. ---- 8537,8551 ---- - && sp_flagged(ps_global->mail_stream, SP_PERMLOCKED)) - ? " (StayOpen)" : "", - READONLY_FOLDER(ps_global->mail_stream) -! ? " READONLY" : "", -! report); -! if (report) -! fs_give((void **)&report); - - #ifdef _WINDOWS - mswin_settitle(pretty_fn(newfolder)); - #endif - - /* - * Set current message number when re-opening Stay-Open or - * cached folders. -*************** -*** 8106,8112 **** - - if(!cur_already_set && mn_get_total(ps_global->msgmap) > 0L){ - -! perfolder_startup_rule = reset_startup_rule(ps_global->mail_stream); - - if(ps_global->start_entry > 0){ - mn_set_cur(ps_global->msgmap, mn_get_revsort(ps_global->msgmap) ---- 8609,8618 ---- - - if(!cur_already_set && mn_get_total(ps_global->msgmap) > 0L){ - -! perfolder_startup_rule = get_perfolder_startup_rule(ps_global->mail_stream, -! V_STARTUP_RULES, newfolder); -! -! reset_startup_rule(ps_global->mail_stream); - - if(ps_global->start_entry > 0){ - mn_set_cur(ps_global->msgmap, mn_get_revsort(ps_global->msgmap) -*************** -*** 8128,8267 **** - else - use_this_startup_rule = ps_global->inc_startup_rule; - -! switch(use_this_startup_rule){ -! /* -! * For news in incoming collection we're doing the same thing -! * for first-unseen and first-recent. In both those cases you -! * get first-unseen if FAKE_NEW is off and first-recent if -! * FAKE_NEW is on. If FAKE_NEW is on, first unseen is the -! * same as first recent because all recent msgs are unseen -! * and all unrecent msgs are seen (see pine_mail_open). -! */ -! case IS_FIRST_UNSEEN: -! first_unseen: -! mn_set_cur(ps_global->msgmap, -! (sp_first_unseen(m) -! && mn_get_sort(ps_global->msgmap) == SortArrival -! && !mn_get_revsort(ps_global->msgmap) -! && !get_lflag(ps_global->mail_stream, NULL, -! sp_first_unseen(m), MN_EXLD) -! && (n = mn_raw2m(ps_global->msgmap, -! sp_first_unseen(m)))) -! ? n -! : first_sorted_flagged(F_UNSEEN | F_UNDEL, m, pc, -! THREADING() ? 0 : FSF_SKIP_CHID)); -! break; - -! case IS_FIRST_RECENT: -! first_recent: -! /* -! * We could really use recent for news but this is the way -! * it has always worked, so we'll leave it. That is, if -! * the FAKE_NEW feature is on, recent and unseen are -! * equivalent, so it doesn't matter. If the feature isn't -! * on, all the undeleted messages are unseen and we start -! * at the first one. User controls with the FAKE_NEW feature. -! */ -! if(IS_NEWS(ps_global->mail_stream)){ -! mn_set_cur(ps_global->msgmap, -! first_sorted_flagged(F_UNSEEN|F_UNDEL, m, pc, -! THREADING() ? 0 : FSF_SKIP_CHID)); -! } -! else{ -! mn_set_cur(ps_global->msgmap, -! first_sorted_flagged(F_RECENT | F_UNSEEN -! | F_UNDEL, -! m, pc, - THREADING() ? 0 : FSF_SKIP_CHID)); -! } -! break; -! -! case IS_FIRST_IMPORTANT: -! mn_set_cur(ps_global->msgmap, -! first_sorted_flagged(F_FLAG|F_UNDEL, m, pc, -! THREADING() ? 0 : FSF_SKIP_CHID)); -! break; -! -! case IS_FIRST_IMPORTANT_OR_UNSEEN: -! -! if(IS_NEWS(ps_global->mail_stream)) -! goto first_unseen; -! -! { -! MsgNo flagged, first_unseen; -! -! flagged = first_sorted_flagged(F_FLAG|F_UNDEL, m, pc, -! THREADING() ? 0 : FSF_SKIP_CHID); -! first_unseen = (sp_first_unseen(m) -! && mn_get_sort(ps_global->msgmap) == SortArrival -! && !mn_get_revsort(ps_global->msgmap) -! && !get_lflag(ps_global->mail_stream, NULL, -! sp_first_unseen(m), MN_EXLD) -! && (n = mn_raw2m(ps_global->msgmap, -! sp_first_unseen(m)))) -! ? n -! : first_sorted_flagged(F_UNSEEN|F_UNDEL, m, pc, -! THREADING() ? 0 : FSF_SKIP_CHID); -! mn_set_cur(ps_global->msgmap, -! (MsgNo) min((int) flagged, (int) first_unseen)); -! -! } -! -! break; -! -! case IS_FIRST_IMPORTANT_OR_RECENT: -! -! if(IS_NEWS(ps_global->mail_stream)) -! goto first_recent; -! -! { -! MsgNo flagged, first_recent; -! -! flagged = first_sorted_flagged(F_FLAG|F_UNDEL, m, pc, -! THREADING() ? 0 : FSF_SKIP_CHID); -! first_recent = first_sorted_flagged(F_RECENT | F_UNSEEN -! | F_UNDEL, -! m, pc, -! THREADING() ? 0 : FSF_SKIP_CHID); -! mn_set_cur(ps_global->msgmap, -! (MsgNo) min((int) flagged, (int) first_recent)); -! } -! -! break; -! -! case IS_FIRST: -! mn_set_cur(ps_global->msgmap, -! first_sorted_flagged(F_UNDEL, m, pc, -! THREADING() ? 0 : FSF_SKIP_CHID)); -! break; -! -! case IS_LAST: -! mn_set_cur(ps_global->msgmap, -! first_sorted_flagged(F_UNDEL, m, pc, -! FSF_LAST | (THREADING() ? 0 : FSF_SKIP_CHID))); -! break; -! -! default: -! panic("Unexpected incoming startup case"); -! break; -! -! } -! } -! else if(IS_NEWS(ps_global->mail_stream)){ -! /* -! * This will go to two different places depending on the FAKE_NEW -! * feature (see pine_mail_open). -! */ -! mn_set_cur(ps_global->msgmap, -! first_sorted_flagged(F_UNSEEN|F_UNDEL, m, pc, -! THREADING() ? 0 : FSF_SKIP_CHID)); -! } -! else{ -! mn_set_cur(ps_global->msgmap, -! mn_get_revsort(ps_global->msgmap) -! ? 1L -! : mn_get_total(ps_global->msgmap)); -! } - - adjust_cur_to_visible(ps_global->mail_stream, ps_global->msgmap); - } ---- 8634,8657 ---- - else - use_this_startup_rule = ps_global->inc_startup_rule; - -! find_startup_position(use_this_startup_rule, m, pc); - -! } -! else if(IS_NEWS(ps_global->mail_stream)){ -! /* -! * This will go to two different places depending on the FAKE_NEW -! * feature (see pine_mail_open). -! */ -! mn_set_cur(ps_global->msgmap, -! first_sorted_flagged(F_UNSEEN|F_UNDEL, m, pc, - THREADING() ? 0 : FSF_SKIP_CHID)); -! } -! else{ -! mn_set_cur(ps_global->msgmap, -! mn_get_revsort(ps_global->msgmap) -! ? 1L -! : mn_get_total(ps_global->msgmap)); -! } - - adjust_cur_to_visible(ps_global->mail_stream, ps_global->msgmap); - } -*************** -*** 8284,8290 **** - PAT_S *pat; - int we_set_it = 0; - -! if(ps_global->mail_stream && nonempty_patterns(rflags, &pstate)){ - for(pat = first_pattern(&pstate); pat; pat = next_pattern(&pstate)){ - if(match_pattern(pat->patgrp, ps_global->mail_stream, NULL, - NULL, NULL, SO_NOSERVER|SE_NOPREFETCH)) ---- 8674,8683 ---- - PAT_S *pat; - int we_set_it = 0; - -! if(find_index_rule()) -! return; -! -! if(ps_global->mail_stream && nonempty_patterns(rflags, &pstate)){ - for(pat = first_pattern(&pstate); pat; pat = next_pattern(&pstate)){ - if(match_pattern(pat->patgrp, ps_global->mail_stream, NULL, - NULL, NULL, SO_NOSERVER|SE_NOPREFETCH)) -*************** -*** 8314,8323 **** - PAT_S *pat; - SortOrder the_sort_order; - int sort_is_rev; -! - /* set default order */ - the_sort_order = ps_global->def_sort; -! sort_is_rev = ps_global->def_sort_rev; - - if(ps_global->mail_stream && nonempty_patterns(rflags, &pstate)){ - for(pat = first_pattern(&pstate); pat; pat = next_pattern(&pstate)){ ---- 8707,8733 ---- - PAT_S *pat; - SortOrder the_sort_order; - int sort_is_rev; -! char *rule_result; -! SortOrder new_sort = EndofList; -! int is_rev; -! -! rule_result = get_rule_result(FOR_RULE | FOR_SORT, ps_global->cur_folder, -! V_SORT_RULES); -! if (rule_result && *rule_result){ -! new_sort = (SortOrder) translate(rule_result, 1); -! is_rev = (SortOrder) translate(rule_result, 0) == EndofList ? 0 : 1; -! fs_give((void **)&rule_result); -! } -! if (new_sort != EndofList){ -! the_sort_order = new_sort; -! sort_is_rev = is_rev; -! } -! else{ - /* set default order */ - the_sort_order = ps_global->def_sort; -! sort_is_rev = the_sort_order == SortThread -! ? (ps_global->thread_def_sort_rev + ps_global->def_sort_rev) % 2 -! : ps_global->def_sort_rev; - - if(ps_global->mail_stream && nonempty_patterns(rflags, &pstate)){ - for(pat = first_pattern(&pstate); pat; pat = next_pattern(&pstate)){ -*************** -*** 8329,8340 **** - if(pat && pat->action && !pat->action->bogus - && pat->action->sort_is_set){ - the_sort_order = pat->action->sortorder; -! sort_is_rev = pat->action->revsort; - } - } - - sort_folder(ps_global->mail_stream, ps_global->msgmap, -! the_sort_order, sort_is_rev, flags); - } - - ---- 8739,8756 ---- - if(pat && pat->action && !pat->action->bogus - && pat->action->sort_is_set){ - the_sort_order = pat->action->sortorder; -! sort_is_rev = the_sort_order == SortThread -! ? (ps_global->thread_def_sort_rev + pat->action->revsort) % 2 -! : pat->action->revsort; - } - } -+ } -+ if (ps_global->thread_cur_sort != SortArrival -+ && ps_global->thread_cur_sort != SortThread) -+ ps_global->thread_cur_sort = ps_global->thread_def_sort; - - sort_folder(ps_global->mail_stream, ps_global->msgmap, -! the_sort_order, sort_is_rev, flags, 1); - } - - -*************** -*** 8420,8425 **** ---- 8836,8842 ---- - temp[MAILTMPLEN+1], buff1[MAX_SCREEN_COLS+1], *moved_msg = NULL, - buff2[MAX_SCREEN_COLS+1], *folder; - CONTEXT_S *context; -+ FOLDER_S *f; - struct variable *vars = ps_global->vars; - int ret, expunge = FALSE, no_close = 0; - char ing[4]; -*************** -*** 8436,8442 **** - } - - if(stream != NULL){ -! context = sp_context(stream); - folder = STREAMNAME(stream); - - dprint(2, (debugfile, "expunge_and_close: \"%s\"%s\n", ---- 8853,8859 ---- - } - - if(stream != NULL){ -! context = ps_global->context_current; - folder = STREAMNAME(stream); - - dprint(2, (debugfile, "expunge_and_close: \"%s\"%s\n", -*************** -*** 8449,8454 **** ---- 8866,8879 ---- - buff1[0] = '\0'; - buff2[0] = '\0'; - -+ if(F_OFF(F_ENABLE_FAST_RECENT,ps_global) && -+ (f = incoming_folder_data(stream, context))){ -+ new_mail_in_open_stream(stream, &(f->recent), &(f->messages)); -+ f->notified = 0; -+ f->countrecent = 0L; -+ f->selected = f->user_selected; -+ } -+ - if(!stream->rdonly){ - - if(!no_close){ -*************** -*** 8476,8484 **** - /* Save read messages? */ - if(VAR_READ_MESSAGE_FOLDER && VAR_READ_MESSAGE_FOLDER[0] - && sp_flagged(stream, SP_INBOX) -! && (seen_not_del = count_flagged(stream, F_SEEN | F_UNDEL))){ - - if(F_ON(F_AUTO_READ_MSGS,ps_global) - || read_msg_prompt(seen_not_del, VAR_READ_MESSAGE_FOLDER)) - /* move inbox's read messages */ - moved_msg = move_read_msgs(stream, VAR_READ_MESSAGE_FOLDER, ---- 8901,8911 ---- - /* Save read messages? */ - if(VAR_READ_MESSAGE_FOLDER && VAR_READ_MESSAGE_FOLDER[0] - && sp_flagged(stream, SP_INBOX) -! && (F_ON(F_AUTO_READ_MSGS_RULES, ps_global) || -! (seen_not_del = count_flagged(stream, F_SEEN | F_UNDEL)))){ - - if(F_ON(F_AUTO_READ_MSGS,ps_global) -+ || F_ON(F_AUTO_READ_MSGS_RULES, ps_global) - || read_msg_prompt(seen_not_del, VAR_READ_MESSAGE_FOLDER)) - /* move inbox's read messages */ - moved_msg = move_read_msgs(stream, VAR_READ_MESSAGE_FOLDER, -*************** -*** 10133,10138 **** ---- 10560,10568 ---- - char *bufp = NULL; - MESSAGECACHE *mc; - -+ if (F_ON(F_AUTO_READ_MSGS_RULES, ps_global)) -+ return move_read_msgs_using_rules(stream, dstfldr, buf); -+ - if(!is_absolute_path(dstfldr) - && !(save_context = default_save_context(ps_global->context_list))) - save_context = ps_global->context_list; -*************** -*** 10174,10181 **** - sprintf(buf, "Moving %s read message%s to \"%.45s\"", - comatose(searched), plural(searched), dstfldr); - we_cancel = busy_alarm(1, buf, NULL, 1); -! if(save(ps_global, stream, save_context, dstfldr, msgmap, -! SV_DELETE | SV_FIX_DELS) == searched) - strncpy(bufp = buf + 1, "Moved", 5); /* change Moving to Moved */ - - mn_give(&msgmap); ---- 10604,10612 ---- - sprintf(buf, "Moving %s read message%s to \"%.45s\"", - comatose(searched), plural(searched), dstfldr); - we_cancel = busy_alarm(1, buf, NULL, 1); -! ps_global->exiting = 1; -! if((save(ps_global, stream, save_context, dstfldr, msgmap, -! SV_DELETE | SV_FIX_DELS) == searched)) - strncpy(bufp = buf + 1, "Moved", 5); /* change Moving to Moved */ - - mn_give(&msgmap); -*************** -*** 10186,10191 **** ---- 10617,10759 ---- - return(bufp); - } - -+ char * -+ move_read_msgs_using_rules(stream, dstfldr,buf) -+ MAILSTREAM *stream; -+ char *dstfldr; -+ char *buf; -+ { -+ CONTEXT_S *save_context = NULL; -+ char **folder_to_save = NULL; -+ int num, we_cancel; -+ long i, j, success, nmsgs = 0L; -+ MSGNO_S *msgmap = NULL; -+ -+ saved_stream = stream; /* horrible hack! */ -+ if(!is_absolute_path(dstfldr) -+ && !(save_context = default_save_context(ps_global->context_list))) -+ save_context = ps_global->context_list; -+ -+ folder_to_save = (char **)fs_get((stream->nmsgs + 1)*sizeof(char *)); -+ folder_to_save[0] = NULL; -+ mn_init(&msgmap, stream->nmsgs); -+ for (i = 1L; i <= stream->nmsgs ; i++){ -+ set_lflag(stream, msgmap, i, MN_SLCT, 0); -+ folder_to_save[i] = get_lflag(stream, NULL, i, MN_EXLD) -+ ? NULL : get_folder_to_save(stream, i, dstfldr); -+ } -+ for (i = 1L; i <= stream->nmsgs; i++){ -+ num = 0; -+ if (folder_to_save[i]){ -+ mn_init(&msgmap, stream->nmsgs); -+ for (j = i; j <= stream->nmsgs ; j++){ -+ if (folder_to_save[j]){ -+ if (!strcmp(folder_to_save[i], folder_to_save[j])){ -+ set_lflag(stream, msgmap, j, MN_SLCT, 1); -+ num++; -+ if (j != i) -+ fs_give((void **)&folder_to_save[j]); -+ } -+ } -+ } -+ pseudo_selected(msgmap); -+ sprintf(buf, "Moving %s read message%s to \"%.45s\"", -+ comatose(num), plural(num), folder_to_save[i]); -+ we_cancel = busy_alarm(1, buf, NULL, 1); -+ ps_global->exiting = 1; -+ if(success = save(ps_global, stream,save_context, folder_to_save[i], -+ msgmap, SV_DELETE | SV_FIX_DELS)) -+ nmsgs += success; -+ if(we_cancel) -+ cancel_busy_alarm(success ? 0 : -1); -+ for (j = i; j <= stream->nmsgs ; j++) -+ set_lflag(stream, msgmap, j, MN_SLCT, 0); -+ fs_give((void **)&folder_to_save[i]); -+ mn_give(&msgmap); -+ } -+ } -+ ps_global->exiting = 0; /* useful if we call from aggregate operations */ -+ sprintf(buf, "Moved automatically %s message%s", -+ comatose(nmsgs), plural(nmsgs)); -+ if (folder_to_save) -+ fs_give((void **)folder_to_save); -+ rule_curpos = 0L; -+ return buf; -+ } -+ -+ unsigned long -+ rules_cursor_pos(stream) -+ MAILSTREAM *stream; -+ { -+ MSGNO_S *msgmap = sp_msgmap(stream); -+ return rule_curpos != 0L ? rule_curpos : mn_m2raw(msgmap,mn_get_cur(msgmap)); -+ } -+ -+ -+ MAILSTREAM * -+ find_open_stream() -+ { -+ return saved_stream; -+ } -+ -+ char * -+ get_folder_to_save(stream, i, dstfldr) -+ MAILSTREAM *stream; -+ long i; -+ char *dstfldr; -+ { -+ MESSAGECACHE *mc = NULL; -+ RULE_RESULT *rule; -+ MSGNO_S *msgmap = NULL; -+ char *folder_to_save = NULL, *save_folder = NULL; -+ int n; -+ long msgno; -+ -+ /* The plan is as follows: Select each message of the folder. We -+ * need to set the cursor correctly so that iFlag gets the value -+ * correctly too, otherwise iFlag will get the value of the position -+ * of the cursor. After that we need to look for a rule that applies -+ * to the message and get the saving folder. If we get a saving folder, -+ * and we used the _FLAG_ token, use that folder, if no -+ * _FLAG_ token was used, move only if seen and not deleted, to the -+ * folder specified in the saving rule. If we did not get a saving -+ * folder from the rule, just save in the default folder. -+ */ -+ -+ mn_init(&msgmap, stream->nmsgs); -+ rule_curpos = i; -+ msgno = mn_m2raw(msgmap, i); -+ if (msgno > 0L){ -+ mc = mail_elt(stream, msgno); -+ rule = (RULE_RESULT *) -+ get_result_rule(V_SAVE_RULES, FOR_RULE | FOR_SAVE, -+ (ENVELOPE *) mc->private.msg.env); -+ if (rule){ -+ folder_to_save = cpystr(rule->result); -+ n = rule->number; -+ fs_give((void **)&rule->result); -+ fs_give((void **)&rule); -+ } -+ } -+ -+ if (folder_to_save && *folder_to_save){ -+ RULELIST *list = get_rulelist_from_code(V_SAVE_RULES, -+ ps_global->rule_list); -+ RULE_S *prule = get_rule(list, n); -+ if (condition_contains_token(prule->condition, "_FLAG_") -+ || (mc->valid && mc->seen && !mc->deleted) -+ || (!mc->valid && mc->searched)) -+ save_folder = cpystr(folder_to_save); -+ else -+ save_folder = NULL; -+ } -+ else -+ if (!mc || (mc->seen && !mc->deleted)) -+ save_folder = cpystr(dstfldr); -+ mn_give(&msgmap); -+ rule_curpos = 0L; -+ return save_folder; -+ } - - - /*---------------------------------------------------------------------- -*************** -*** 10232,10238 **** - && ((context_isambig(folder) - && folder_is_nick(folder, FOLDERS(context), 0)) - || folder_index(folder, context, FI_FOLDER) > 0) -! && (seen_undel = count_flagged(stream, F_SEEN | F_UNDEL))){ - - for(; f && *archive; archive++){ - char *p; ---- 10800,10808 ---- - && ((context_isambig(folder) - && folder_is_nick(folder, FOLDERS(context), 0)) - || folder_index(folder, context, FI_FOLDER) > 0) -! && ((seen_undel = count_flagged(stream, F_SEEN | F_UNDEL)) -! || (F_ON(F_AUTO_READ_MSGS,ps_global) && -! F_ON(F_AUTO_READ_MSGS_RULES, ps_global)))){ - - for(; f && *archive; archive++){ - char *p; -*************** -*** 11514,11526 **** - - ----*/ - int -! apply_command(state, stream, msgmap, preloadkeystroke, flags, q_line) - struct pine *state; - MAILSTREAM *stream; - MSGNO_S *msgmap; - int preloadkeystroke; - int flags; - int q_line; - { - int i = 8, /* number of static entries in sel_opts3 */ - rv = 1, ---- 12084,12097 ---- - - ----*/ - int -! apply_command(state, stream, msgmap, preloadkeystroke, flags, q_line, display) - struct pine *state; - MAILSTREAM *stream; - MSGNO_S *msgmap; - int preloadkeystroke; - int flags; - int q_line; -+ int display; - { - int i = 8, /* number of static entries in sel_opts3 */ - rv = 1, -*************** -*** 11647,11655 **** - collapse_or_expand(state, stream, msgmap, - F_ON(F_SLASH_COLL_ENTIRE, ps_global) - ? 0L -! : mn_get_cur(msgmap)); - break; - - case ':' : - select_thread_stmp(state, stream, msgmap); - break; ---- 12218,12236 ---- - collapse_or_expand(state, stream, msgmap, - F_ON(F_SLASH_COLL_ENTIRE, ps_global) - ? 0L -! : mn_get_cur(msgmap), -! display); - break; - -+ case '[' : -+ collapse_this_thread(state, stream, msgmap, display, 0); -+ break; -+ -+ case ']' : -+ expand_this_thread(state, stream, msgmap, display, 0); -+ break; -+ -+ - case ':' : - select_thread_stmp(state, stream, msgmap); - break; -*************** -*** 12167,12172 **** ---- 12748,12754 ---- - SEARCHSET **msgset; - { - PINETHRD_S *nthrd, *bthrd; -+ unsigned long next, branch; - - if(!(stream && thrd)) - return; -*************** -*** 12175,12188 **** - && (!(msgset && *msgset) || in_searchset(*msgset, thrd->rawno))) - mm_searched(stream, thrd->rawno); - -! if(thrd->next){ -! nthrd = fetch_thread(stream, thrd->next); - if(nthrd) - set_search_bit_for_thread(stream, nthrd, msgset); - } - -! if(thrd->branch){ -! bthrd = fetch_thread(stream, thrd->branch); - if(bthrd) - set_search_bit_for_thread(stream, bthrd, msgset); - } ---- 12757,12770 ---- - && (!(msgset && *msgset) || in_searchset(*msgset, thrd->rawno))) - mm_searched(stream, thrd->rawno); - -! if(next= get_next(stream, thrd)){ -! nthrd = fetch_thread(stream, next); - if(nthrd) - set_search_bit_for_thread(stream, nthrd, msgset); - } - -! if(branch = get_branch(stream, thrd)){ -! bthrd = fetch_thread(stream, branch); - if(bthrd) - set_search_bit_for_thread(stream, bthrd, msgset); - } -*************** -*** 12390,12396 **** - { - int r, type, we_cancel = 0, not = 0, flags, old_imap; - char sstring[80], savedsstring[80], origcharset[16], tmp[128]; -! char *sval = NULL, *cset = NULL, *charset = NULL; - char buftmp[MAILTMPLEN]; - ESCKEY_S ekey[4]; - ENVELOPE *env = NULL; ---- 12972,12978 ---- - { - int r, type, we_cancel = 0, not = 0, flags, old_imap; - char sstring[80], savedsstring[80], origcharset[16], tmp[128]; -! char namehdr[80], *sval = NULL, *cset = NULL, *charset = NULL; - char buftmp[MAILTMPLEN]; - ESCKEY_S ekey[4]; - ENVELOPE *env = NULL; -*************** -*** 12464,12469 **** ---- 13046,13085 ---- - sval = "BODYTEXT"; - break; - -+ case 'h' : -+ sprintf(tmp, "Name of HEADER to match : "); -+ flags = OE_APPEND_CURRENT; -+ namehdr[0] = '\0'; -+ r = 'x'; -+ while (r == 'x'){ -+ int done = 0; -+ -+ r = optionally_enter(namehdr, -FOOTER_ROWS(ps_global), 0, -+ sizeof(namehdr), tmp, ekey, NO_HELP, &flags); -+ if (r == 1){ -+ cmd_cancelled("Selection by text"); -+ return(1); -+ } -+ removing_leading_white_space(namehdr); -+ while(!done){ -+ while ((namehdr[0] != '\0') && /* remove trailing ":" */ -+ (namehdr[strlen(namehdr) - 1] == ':')) -+ namehdr[strlen(namehdr) - 1] = '\0'; -+ if ((namehdr[0] != '\0') -+ && isspace((unsigned char) namehdr[strlen(namehdr) - 1])) -+ removing_trailing_white_space(namehdr); -+ else -+ done++; -+ } -+ if (strchr(namehdr,' ') || strchr(namehdr,'\t') || -+ strchr(namehdr,':')) -+ namehdr[0] = '\0'; -+ if (namehdr[0] == '\0') -+ r = 'x'; -+ } -+ sval = namehdr; -+ break; -+ - case 'x': - break; - -*************** -*** 12587,12592 **** ---- 13203,13211 ---- - } - - switch(type){ -+ case 'h' : /* Any header */ -+ pgm->header = mail_newsearchheader (namehdr,sstring); -+ break; - case 'r' : /* TO or CC */ - if(old_imap){ - /* No OR on old servers */ -*************** -*** 13764,13777 **** - Returns 0 if it was cancelled, 1 otherwise. - ----*/ - int -! select_sort(state, ql, sort, rev) - struct pine *state; - int ql; - SortOrder *sort; - int *rev; - { - char prompt[200], tmp[3], *p; -! int s, i; - int deefault = 'a', retval = 1; - HelpType help; - ESCKEY_S sorts[14]; ---- 14383,14397 ---- - Returns 0 if it was cancelled, 1 otherwise. - ----*/ - int -! select_sort(state, ql, sort, rev, thread) - struct pine *state; - int ql; - SortOrder *sort; - int *rev; -+ int thread; - { - char prompt[200], tmp[3], *p; -! int s, i, j; - int deefault = 'a', retval = 1; - HelpType help; - ESCKEY_S sorts[14]; -*************** -*** 13805,13821 **** - strncpy(prompt, "Choose type of sort, or 'R' to reverse current sort : ", - sizeof(prompt)); - -! for(i = 0; state->sort_types[i] != EndofList; i++) { -! sorts[i].rval = i; -! p = sorts[i].label = sort_name(state->sort_types[i]); -! while(*(p+1) && islower((unsigned char)*p)) -! p++; -! -! sorts[i].ch = tolower((unsigned char)(tmp[0] = *p)); -! sorts[i].name = cpystr(tmp); -! -! if(mn_get_sort(state->msgmap) == state->sort_types[i]) -! deefault = sorts[i].rval; - } - - sorts[i].ch = 'r'; ---- 14425,14451 ---- - strncpy(prompt, "Choose type of sort, or 'R' to reverse current sort : ", - sizeof(prompt)); - -! for(i = 0, j = 0; state->sort_types[i] != EndofList; i++) { -! sorts[i].rval = i; -! sorts[i].name = cpystr(""); -! sorts[i].label = ""; -! sorts[i].ch = -2; -! if (!thread || state->sort_types[i] == SortArrival -! || state->sort_types[i] == SortThread){ -! p = sorts[j].label = sort_name(state->sort_types[i]); -! while(*(p+1) && islower((unsigned char)*p)) -! p++; -! sorts[j].ch = tolower((unsigned char)(tmp[0] = *p)); -! sorts[j++].name = cpystr(tmp); -! } -! -! if (thread){ -! if (state->thread_def_sort == state->sort_types[i]) -! deefault = sorts[j-1].rval; -! } -! else -! if(mn_get_sort(state->msgmap) == state->sort_types[i]) -! deefault = sorts[i].rval; - } - - sorts[i].ch = 'r'; -*************** -*** 13840,13846 **** - if(s == 'r') - *rev = !mn_get_revsort(state->msgmap); - else -! *sort = state->sort_types[s]; - - if(F_ON(F_SHOW_SORT, ps_global)) - ps_global->mangled_header = 1; ---- 14470,14476 ---- - if(s == 'r') - *rev = !mn_get_revsort(state->msgmap); - else -! *sort = state->sort_types[thread ? (s == 0 ? 1 : 9) : s]; - - if(F_ON(F_SHOW_SORT, ps_global)) - ps_global->mangled_header = 1; -*************** -*** 13854,13859 **** ---- 14484,14492 ---- - fs_give((void **)&sorts[i].name); - - blank_keymenu(ps_global->ttyo->screen_rows - 2, 0); -+ if(*sort == SortScore) -+ scores_are_used(SCOREUSE_INVALID); -+ - return(retval); - } - -*************** -*** 14524,14526 **** ---- 15157,15855 ---- - return(flag_submenu); - } - #endif /* _WINDOWS */ -+ -+ /* Extra Fancy Thread support */ -+ -+ long -+ top_thread(stream, rawmsgno) -+ MAILSTREAM *stream; -+ long rawmsgno; -+ { -+ PINETHRD_S *thrd = NULL; -+ unsigned long rawno; -+ -+ if(!stream) -+ return -1L; -+ -+ if(rawmsgno) -+ thrd = fetch_thread(stream, rawmsgno); -+ -+ if(!thrd) -+ return -1L; -+ -+ return F_ON(F_ENHANCED_THREAD, ps_global) -+ ? (thrd->toploose ? thrd->toploose : thrd->top) -+ : thrd->top; -+ } -+ -+ void -+ move_top_thread(stream, msgmap, rawmsgno) -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ long rawmsgno; -+ { -+ mn_set_cur(msgmap,mn_raw2m(msgmap, top_thread(stream, rawmsgno))); -+ } -+ -+ long -+ top_this_thread(stream, rawmsgno) -+ MAILSTREAM *stream; -+ long rawmsgno; -+ { -+ PINETHRD_S *thrd = NULL; -+ unsigned long rawno; -+ -+ if(!stream) -+ return -1L; -+ -+ if(rawmsgno) -+ thrd = fetch_thread(stream, rawmsgno); -+ -+ if(!thrd) -+ return -1L; -+ -+ return thrd->top; -+ } -+ -+ void -+ move_top_this_thread(stream, msgmap, rawmsgno) -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ long rawmsgno; -+ { -+ mn_set_cur(msgmap,mn_raw2m(msgmap, top_this_thread(stream, rawmsgno))); -+ } -+ -+ -+ void -+ cmd_delete_this_thread(state, stream, msgmap) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ { -+ unsigned long rawno, top, save_kolapsed; -+ PINETHRD_S *thrd = NULL, *nxthrd; -+ -+ if(!stream) -+ return; -+ -+ rawno = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ move_top_this_thread(stream, msgmap, rawno); -+ top = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ if(top) -+ thrd = fetch_thread(stream, top); -+ -+ if(!thrd) -+ return; -+ -+ save_kolapsed = this_thread_is_kolapsed(state, stream, msgmap, top); -+ collapse_this_thread(state, stream, msgmap, 0, 0); -+ thread_command(state, stream, msgmap, 'd', -FOOTER_ROWS(state), 1); -+ if (!save_kolapsed) -+ expand_this_thread(state, stream, msgmap, 0, 0); -+ } -+ -+ void -+ cmd_delete_thread(state, stream, msgmap) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ { -+ unsigned long rawno, top, orig_top, topnxt, save_kolapsed; -+ PINETHRD_S *thrd = NULL, *nxthrd; -+ int done = 0, count; -+ -+ if(!stream) -+ return; -+ -+ rawno = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ move_top_thread(stream, msgmap, rawno); -+ top = orig_top = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ if(top) -+ thrd = fetch_thread(stream, top); -+ -+ if(!thrd) -+ return; -+ -+ while (!done){ -+ cmd_delete_this_thread(state, stream, msgmap); -+ if (F_OFF(F_ENHANCED_THREAD, state) -+ || (move_next_this_thread(state, stream, msgmap, 0) <= 0) -+ || !(top = mn_m2raw(msgmap, mn_get_cur(msgmap))) -+ || (orig_top != top_thread(stream, top))) -+ done++; -+ } -+ mn_set_cur(msgmap,mn_raw2m(msgmap, rawno)); -+ cmd_delete(state, msgmap, 0, MsgIndx); -+ count = count_thread(state, stream, msgmap, rawno); -+ q_status_message2(SM_ORDER, 0, 1, "%s message%s marked deleted", -+ int2string(count), plural(count)); -+ } -+ -+ -+ -+ int -+ thread_is_kolapsed(state, stream, msgmap, rawmsgno) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ long rawmsgno; -+ { -+ int collapsed; -+ PINETHRD_S *thrd = NULL; -+ unsigned long rawno, orig, orig_rawno; -+ -+ if(!stream) -+ return -1; -+ -+ orig = mn_get_cur(msgmap); -+ move_top_thread(stream, msgmap, rawmsgno); -+ rawno = orig_rawno = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ if(rawno) -+ thrd = fetch_thread(stream, rawno); -+ -+ if(!thrd) -+ return -1; -+ -+ while(collapsed = this_thread_is_kolapsed(state, stream, msgmap, rawno)) -+ if (F_OFF(F_ENHANCED_THREAD, state) -+ || (move_next_this_thread(state, stream, msgmap, 0) <= 0) -+ || !(rawno = mn_m2raw(msgmap, mn_get_cur(msgmap))) -+ || (orig_rawno != top_thread(stream, rawno))) -+ break; -+ -+ mn_set_cur(msgmap,orig); /* return home */ -+ -+ return collapsed; -+ } -+ -+ /* this function tells us if the thread (or branch in the case of loose threads) -+ * is collapsed -+ */ -+ -+ int -+ this_thread_is_kolapsed(state, stream, msgmap, rawmsgno) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ long rawmsgno; -+ { -+ int collapsed; -+ PINETHRD_S *thrd = NULL; -+ unsigned long rawno, orig; -+ -+ if(!stream) -+ return -1; -+ -+ rawno = rawmsgno; -+ if(rawno) -+ thrd = fetch_thread(stream, rawno); -+ -+ if(!thrd) -+ return -1; -+ -+ collapsed = get_lflag(stream, NULL, rawno, MN_COLL | MN_CHID); -+ -+ if (!thrd->next){ -+ if (thrd->rawno != top_thread(stream, thrd->rawno)) -+ collapsed = get_lflag(stream, NULL, rawno, MN_CHID); -+ else -+ collapsed = get_lflag(stream, NULL, rawno, MN_COLL); -+ } -+ -+ return collapsed; -+ } -+ -+ int -+ collapse_this_thread(state, stream, msgmap, display, special) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ int display; -+ int special; -+ { -+ int collapsed, rv = 1, done = 0; -+ PINETHRD_S *thrd = NULL, *nthrd; -+ unsigned long rawno, orig, msgno; -+ -+ if(!stream) -+ return 0; -+ -+ rawno = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ -+ if(rawno) -+ thrd = fetch_thread(stream, rawno); -+ -+ if(!thrd) -+ return rv; -+ -+ collapsed = this_thread_is_kolapsed(state, stream, msgmap, rawno); -+ -+ if (special && collapsed){ -+ expand_this_thread(state, stream, msgmap, 0, 0); -+ collapsed = 0; -+ } -+ -+ clear_index_cache_ent(mn_raw2m(msgmap,rawno)); -+ -+ if (!collapsed && thrd->next){ -+ if (thrd->rawno == top_thread(stream, thrd->rawno)) -+ collapse_or_expand(state, stream, msgmap, mn_get_cur(msgmap), display); -+ else{ -+ set_lflag(stream, msgmap, mn_raw2m(msgmap,thrd->rawno), MN_COLL, 1); -+ set_thread_subtree(stream, thrd, msgmap, 1, MN_CHID); -+ } -+ } -+ else{ -+ if (!collapsed && special -+ && ((F_OFF(F_ENHANCED_THREAD, state) && !thrd->next) -+ || F_ON(F_ENHANCED_THREAD, state))){ -+ if (thrd->toploose){ -+ if (thrd->rawno != thrd->toploose) -+ set_lflag(stream, msgmap, mn_raw2m(msgmap,thrd->rawno),MN_CHID, -+ 1); -+ else -+ set_lflag(stream, msgmap, mn_raw2m(msgmap,thrd->rawno),MN_COLL, -+ 1); -+ } -+ } -+ else{ -+ rv = 0; -+ if (display) -+ q_status_message(SM_ORDER, 0, 1, "Thread already collapsed"); -+ } -+ } -+ return rv; -+ } -+ -+ void -+ collapse_thread(state, stream, msgmap, display) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ int display; -+ { -+ int collapsed, rv = 1, done = 0; -+ PINETHRD_S *thrd = NULL; -+ unsigned long orig, orig_top, top; -+ -+ if(!stream) -+ return; -+ -+ expand_this_thread(state, stream, msgmap, display, 1); -+ orig = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ move_top_thread(stream, msgmap,orig); -+ top = orig_top = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ -+ if(top) -+ thrd = fetch_thread(stream, top); -+ -+ if(!thrd) -+ return; -+ -+ while (!done){ -+ collapse_this_thread(state, stream, msgmap, display, 1); -+ if (F_OFF(F_ENHANCED_THREAD, state) -+ || (move_next_this_thread(state, stream, msgmap, 0) <= 0) -+ || !(top = mn_m2raw(msgmap, mn_get_cur(msgmap))) -+ || (orig_top != top_thread(stream, top))) -+ done++; -+ } -+ mn_set_cur(msgmap,mn_raw2m(msgmap, orig_top)); -+ } -+ -+ int -+ expand_this_thread(state, stream, msgmap, display, special) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ int display; -+ int special; -+ { -+ int collapsed, rv = 1, done = 0; -+ PINETHRD_S *thrd = NULL, *nthrd; -+ unsigned long rawno, orig, msgno; -+ -+ if(!stream) -+ return 0; -+ -+ orig = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ move_top_this_thread(stream, msgmap,orig); -+ rawno = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ -+ if(rawno) -+ thrd = fetch_thread(stream, rawno); -+ -+ if(!thrd) -+ return rv; -+ -+ collapsed = this_thread_is_kolapsed(state, stream, msgmap, rawno); -+ -+ if (special && !collapsed){ -+ collapse_this_thread(state, stream, msgmap, 0, 0); -+ collapsed = 1; -+ } -+ -+ clear_index_cache_ent(mn_raw2m(msgmap,rawno)); -+ -+ if (collapsed && thrd->next){ -+ if (thrd->rawno == top_thread(stream, thrd->rawno)) -+ collapse_or_expand(state, stream, msgmap, mn_get_cur(msgmap), display); -+ else{ -+ set_lflag(stream, msgmap, mn_raw2m(msgmap,thrd->rawno), MN_COLL, 0); -+ set_thread_subtree(stream, thrd, msgmap, 0, MN_CHID); -+ } -+ } -+ else{ -+ if (collapsed && special -+ && ((F_OFF(F_ENHANCED_THREAD, state) && !thrd->next) -+ || F_ON(F_ENHANCED_THREAD, state))){ -+ if (thrd->toploose) -+ if (thrd->rawno != thrd->toploose) -+ set_lflag(stream, msgmap, mn_raw2m(msgmap,thrd->rawno),MN_CHID, 0); -+ else -+ set_lflag(stream, msgmap, mn_raw2m(msgmap,thrd->rawno),MN_COLL, 0); -+ } -+ else{ -+ rv = 0; -+ if (display) -+ q_status_message(SM_ORDER, 0, 1, "Thread already expanded"); -+ } -+ } -+ return rv; -+ } -+ -+ void -+ expand_thread(state, stream, msgmap, display) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ int display; -+ { -+ int collapsed, rv = 1, done = 0; -+ PINETHRD_S *thrd = NULL; -+ unsigned long orig, orig_top, top; -+ -+ if(!stream) -+ return; -+ -+ orig = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ top = orig_top = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ -+ if(top) -+ thrd = fetch_thread(stream, top); -+ -+ if(!thrd) -+ return; -+ -+ while (!done){ -+ expand_this_thread(state, stream, msgmap, display, 1); -+ if (F_OFF(F_ENHANCED_THREAD, state) -+ || (move_next_this_thread(state, stream, msgmap, 0) <= 0) -+ || !(top = mn_m2raw(msgmap, mn_get_cur(msgmap))) -+ || (orig_top != top_thread(stream, top))) -+ done++; -+ } -+ mn_set_cur(msgmap,mn_raw2m(msgmap, orig_top)); -+ } -+ -+ -+ void -+ cmd_undelete_this_thread(state, stream, msgmap) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ { -+ unsigned long rawno; -+ int save_kolapsed; -+ -+ rawno = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ save_kolapsed = this_thread_is_kolapsed(state, stream, msgmap, rawno); -+ collapse_this_thread(state, stream, msgmap, 0, 0); -+ thread_command(state, stream, msgmap, 'u', -FOOTER_ROWS(state), 1); -+ if (!save_kolapsed) -+ expand_this_thread(state, stream, msgmap, 0, 0); -+ } -+ -+ void -+ cmd_undelete_thread(state, stream, msgmap) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ { -+ PINETHRD_S *thrd = NULL; -+ unsigned long rawno, top, orig_top; -+ int done = 0, count; -+ -+ rawno = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ move_top_thread(stream, msgmap, rawno); -+ top = orig_top = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ if(top) -+ thrd = fetch_thread(stream, top); -+ -+ if(!thrd) -+ return; -+ -+ while (!done){ -+ cmd_undelete_this_thread(state, stream, msgmap); -+ if (F_OFF(F_ENHANCED_THREAD, state) -+ || (move_next_this_thread(state, stream, msgmap, 0) <= 0) -+ || !(top = mn_m2raw(msgmap, mn_get_cur(msgmap))) -+ || (orig_top != top_thread(stream, top))) -+ done++; -+ } -+ mn_set_cur(msgmap,mn_raw2m(msgmap, rawno)); -+ count = count_thread(state, stream, msgmap, rawno); -+ q_status_message2(SM_ORDER, 0, 1, "Deletion mark removed from %s message%s", -+ int2string(count), plural(count)); -+ } -+ -+ void -+ kolapse_thread(state, stream, msgmap, ch, display) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ char ch; -+ int display; -+ { -+ PINETHRD_S *thrd = NULL; -+ unsigned long rawno; -+ int rv = 1, done = 0; -+ -+ if(!stream) -+ return; -+ -+ rawno = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ if(rawno) -+ thrd = fetch_thread(stream, rawno); -+ -+ if(!thrd) -+ return; -+ -+ clear_index_cache(); -+ mn_set_cur(msgmap,1); /* go to the first message */ -+ while (!done){ -+ if (ch == '[') -+ collapse_thread(state, stream, msgmap, display); -+ else -+ expand_thread(state, stream, msgmap, display); -+ if ((rv = move_next_thread(state, stream, msgmap, 0)) <= 0) -+ done++; -+ } -+ -+ if (rv < 0){ -+ if (display) -+ q_status_message(SM_ORDER, 0, 1, (ch == '[') -+ ? "Error while collapsing thread" -+ : "Error while expanding thread"); -+ } -+ else -+ if(display) -+ q_status_message(SM_ORDER, 0, 1, (ch == '[') -+ ? "All threads collapsed. Use \"}\" to expand them" -+ : "All threads expanded. Use \"{\" to collapse them"); -+ -+ mn_set_cur(msgmap,mn_raw2m(msgmap, top_thread(stream,rawno))); -+ } -+ -+ int -+ move_next_this_thread(state, stream, msgmap, display) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ int display; -+ { -+ PINETHRD_S *thrd = NULL, *thrdnxt; -+ unsigned long rawno, top; -+ int rv = 1; -+ -+ if(!stream) -+ return -1; -+ -+ rawno = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ if(rawno) -+ thrd = fetch_thread(stream, rawno); -+ -+ if(!thrd) -+ return -1; -+ -+ top = top_thread(stream, rawno); -+ -+ thrdnxt = (top == rawno) ? fetch_thread(stream, top) : thrd; -+ if (thrdnxt->nextthd) -+ mn_set_cur(msgmap,mn_raw2m(msgmap, thrdnxt->nextthd)); -+ else{ -+ rv = 0; -+ if (display) -+ q_status_message(SM_ORDER, 0, 1, "No more Threads to advance"); -+ } -+ return rv; -+ } -+ -+ int -+ move_next_thread(state, stream, msgmap, display) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ int display; -+ { -+ int collapsed, rv = 1, done = 0; -+ PINETHRD_S *thrd = NULL; -+ unsigned long orig, orig_top, top; -+ -+ if(!stream) -+ return 0; -+ -+ orig = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ move_top_thread(stream, msgmap,orig); -+ top = orig_top = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ -+ if(top) -+ thrd = fetch_thread(stream, top); -+ -+ if(!thrd) -+ return 0; -+ -+ while (rv > 0 && !done){ -+ rv = move_next_this_thread(state, stream, msgmap, display); -+ if (F_OFF(F_ENHANCED_THREAD, state) -+ || !(top = mn_m2raw(msgmap, mn_get_cur(msgmap))) -+ || (orig_top != top_thread(stream, top))) -+ done++; -+ } -+ if (display){ -+ if (rv > 0 && SEP_THRDINDX()) -+ q_status_message(SM_ORDER, 0, 2, "Viewing next thread"); -+ if (!rv) -+ q_status_message(SM_ORDER, 0, 2, "No more threads to advance"); -+ } -+ if(rv <= 0){ -+ rv = 0; -+ mn_set_cur(msgmap, mn_raw2m(msgmap, orig)); -+ } -+ -+ return rv; -+ } -+ -+ int -+ move_prev_thread(state, stream, msgmap, display) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ int display; -+ { -+ PINETHRD_S *thrd = NULL; -+ unsigned long rawno, top; -+ int rv = 1; -+ -+ if(!stream) -+ return -1; -+ -+ rawno = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ if(rawno) -+ thrd = fetch_thread(stream, rawno); -+ -+ if(!thrd) -+ return -1; -+ -+ top = top_thread(stream, rawno); -+ -+ if (top != rawno) -+ mn_set_cur(msgmap,mn_raw2m(msgmap, top)); -+ else if (thrd->prevthd) -+ mn_set_cur(msgmap,mn_raw2m(msgmap, top_thread(stream,thrd->prevthd))); -+ else -+ rv = 0; -+ if (display){ -+ if (rv && SEP_THRDINDX()) -+ q_status_message(SM_ORDER, 0, 2, "Viewing previous thread"); -+ if (!rv) -+ q_status_message(SM_ORDER, 0, 2, "No more threads to go back"); -+ } -+ -+ return rv; -+ } -+ -+ void -+ cmd_select_thread(state, stream, msgmap) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ { -+ unsigned long rawno; -+ int save_kolapsed; -+ -+ rawno = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ save_kolapsed = thread_is_kolapsed(state, stream, msgmap, rawno); -+ collapse_thread(state, stream, msgmap, 0); -+ thread_command(state, stream, msgmap, ':', -FOOTER_ROWS(state), 1); -+ if (!save_kolapsed) -+ expand_thread(state, stream, msgmap, 0); -+ } -+ -+ /* -+ * This function assumes that it is called at a top of a thread in its -+ * first call -+ */ -+ -+ int -+ count_this_thread(stream, rawno) -+ MAILSTREAM *stream; -+ unsigned long rawno; -+ { -+ unsigned long top, orig_top, topnxt; -+ PINETHRD_S *thrd = NULL; -+ int count = 1; -+ -+ if(!stream) -+ return 0; -+ -+ if(rawno) -+ thrd = fetch_thread(stream, rawno); -+ -+ if(!thrd) -+ return 0; -+ -+ if (thrd->next) -+ count += count_this_thread(stream, thrd->next); -+ -+ if (thrd->branch) -+ count += count_this_thread(stream, thrd->branch); -+ -+ return count; -+ } -+ -+ int -+ count_thread(state, stream, msgmap, rawno) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ long rawno; -+ { -+ unsigned long top, orig, orig_top; -+ PINETHRD_S *thrd = NULL; -+ int done = 0, count = 0; -+ -+ if(!stream) -+ return 0; -+ -+ orig = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ move_top_thread(stream, msgmap,rawno); -+ top = orig_top = top_thread(stream, rawno); -+ if(top) -+ thrd = fetch_thread(stream, top); -+ -+ if(!thrd) -+ return 0; -+ -+ while (!done){ -+ count += count_this_thread(stream, top); -+ if (F_OFF(F_ENHANCED_THREAD, state) -+ || (move_next_this_thread(state, stream, msgmap, 0) <= 0) -+ || !(top = mn_m2raw(msgmap, mn_get_cur(msgmap))) -+ || (orig_top != top_thread(stream, top))) -+ done++; -+ } -+ mn_set_cur(msgmap,mn_raw2m(msgmap, orig)); -+ return count; -+ } -diff -rc pine4.63/pine/mailindx.c pine4.63.I.USE/pine/mailindx.c -*** pine4.63/pine/mailindx.c Wed Apr 27 11:55:00 2005 ---- pine4.63.I.USE/pine/mailindx.c Thu May 19 19:57:34 2005 -*************** -*** 112,120 **** - RCOMPOSE_MENU, - HOMEKEY_MENU, - ENDKEY_MENU, -! NULL_MENU, - {"/","Collapse/Expand",{MC_COLLAPSE,1,{'/'}},KS_NONE}, -! NULL_MENU, - NULL_MENU}; - INST_KEY_MENU(index_keymenu, index_keys); - #define BACK_KEY 2 ---- 112,133 ---- - RCOMPOSE_MENU, - HOMEKEY_MENU, - ENDKEY_MENU, -! {"K","Sort Thread",{MC_SORTHREAD,1,{'k'}},KS_NONE}, - {"/","Collapse/Expand",{MC_COLLAPSE,1,{'/'}},KS_NONE}, -! {"{","Collapse All",{MC_KOLAPSE,1,{'{'}},KS_NONE}, -! {"}","Expand All", {MC_EXPTHREAD,1,{'}'}},KS_NONE}, -! -! HELP_MENU, -! OTHER_MENU, -! {")","Next Threa",{MC_NEXTHREAD,1,{')'}},KS_NONE}, -! {"(","Prev Threa",{MC_PRETHREAD,1,{'('}},KS_NONE}, -! {"^D","Delete Thr",{MC_DELTHREAD,1,{ctrl('D')}},KS_NONE}, -! {"^U","Undel Thre",{MC_UNDTHREAD,1,{ctrl('U')}},KS_NONE}, -! {"^T","Select Thr",{MC_SELTHREAD,1,{ctrl('T')}},KS_NONE}, -! {"^H","ChkIncFl",{MC_FORCECHECK,1,{ctrl('H')}},KS_NONE}, -! {"[","Close Thre",{MC_CTHREAD,1,{'['}},KS_NONE}, -! {"]","Open Threa",{MC_OTHREAD,1,{']'}},KS_NONE}, -! QUOTA_MENU, - NULL_MENU}; - INST_KEY_MENU(index_keymenu, index_keys); - #define BACK_KEY 2 -*************** -*** 197,205 **** - RCOMPOSE_MENU, - HOMEKEY_MENU, - ENDKEY_MENU, -! NULL_MENU, - {"/","Collapse/Expand",{MC_COLLAPSE,1,{'/'}},KS_NONE}, - NULL_MENU, - NULL_MENU}; - INST_KEY_MENU(thread_keymenu, thread_keys); - ---- 210,231 ---- - RCOMPOSE_MENU, - HOMEKEY_MENU, - ENDKEY_MENU, -! {"]","Open Threa",{MC_OTHREAD,1,{']'}},KS_NONE}, - {"/","Collapse/Expand",{MC_COLLAPSE,1,{'/'}},KS_NONE}, -+ {")","Next Threa",{MC_NEXTHREAD,1,{')'}},KS_NONE}, -+ {"(","Prev Threa",{MC_PRETHREAD,1,{'('}},KS_NONE}, -+ -+ HELP_MENU, -+ OTHER_MENU, - NULL_MENU, -+ NULL_MENU, -+ {"^D","Delete Thr",{MC_DELTHREAD,1,{ctrl('D')}},KS_NONE}, -+ {"^U","Undel Thre",{MC_UNDTHREAD,1,{ctrl('U')}},KS_NONE}, -+ {"^T","Select Thr",{MC_SELTHREAD,1,{ctrl('T')}},KS_NONE}, -+ NULL_MENU, -+ {"^H","ChkIncFl",{MC_FORCECHECK,1,{ctrl('H')}},KS_NONE}, -+ QUOTA_MENU, -+ {"K","Sort Thread",{MC_SORTHREAD,1,{'k'}},KS_NONE}, - NULL_MENU}; - INST_KEY_MENU(thread_keymenu, thread_keys); - -*************** -*** 315,326 **** - - HLINE_S *(*format_index_line) PROTO((INDEXDATA_S *)); - void (*setup_header_widths) PROTO((void)); -! - - - /* - * Internal prototypes - */ - void index_index_screen PROTO((struct pine *)); - void thread_index_screen PROTO((struct pine *)); - void setup_for_index_index_screen PROTO((void)); ---- 341,357 ---- - - HLINE_S *(*format_index_line) PROTO((INDEXDATA_S *)); - void (*setup_header_widths) PROTO((void)); -! static int erase_thread_info = 1; - - - /* - * Internal prototypes - */ -+ SortOrder translate PROTO ((char *, int)); -+ ENVELOPE *make_envelope PROTO ((INDEXDATA_S *, int)); -+ char *find_value PROTO ((char *,char *, int, char *, int, char *, int, INDEXDATA_S *, int)); -+ int find_index_rule PROTO((void)); -+ void setup_threading_display_style PROTO((void)); - void index_index_screen PROTO((struct pine *)); - void thread_index_screen PROTO((struct pine *)); - void setup_for_index_index_screen PROTO((void)); -*************** -*** 346,351 **** ---- 377,390 ---- - void index_data_env PROTO((INDEXDATA_S *, ENVELOPE *)); - int set_index_addr PROTO((INDEXDATA_S *, char *, ADDRESS *, - char *, int, char *)); -+ unsigned long get_next PROTO((MAILSTREAM *,PINETHRD_S *)); -+ unsigned long get_branch PROTO((MAILSTREAM *,PINETHRD_S *)); -+ long get_length_branch PROTO((MAILSTREAM *, long)); -+ THREADNODE *copy_tree PROTO((THREADNODE *)); -+ void find_msgmap PROTO((MAILSTREAM *, MSGNO_S *, int, SortOrder, -+ unsigned)); -+ void move_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, int)); -+ void relink_threads PROTO((MAILSTREAM *, MSGNO_S *, long *)); - int i_cache_size PROTO((long)); - int i_cache_width PROTO(()); - int ctype_is_fixed_length PROTO((IndexColType)); -*************** -*** 390,406 **** - struct pass_along - *sort_thread_flatten PROTO((THREADNODE *, MAILSTREAM *, - struct pass_along *, -! PINETHRD_S *, unsigned)); - void make_thrdflags_consistent PROTO((MAILSTREAM *, MSGNO_S *, - PINETHRD_S *, int)); - THREADNODE *collapse_threadnode_tree PROTO((THREADNODE *)); - PINETHRD_S *msgno_thread_info PROTO((MAILSTREAM *, unsigned long, - PINETHRD_S *, unsigned)); - long calculate_visible_threads PROTO((MAILSTREAM *)); - void set_thread_subtree PROTO((MAILSTREAM *, PINETHRD_S *, - MSGNO_S *, int, int)); - void thread_command PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, -! int, int)); - void set_flags_for_thread PROTO((MAILSTREAM *, MSGNO_S *, int, - PINETHRD_S *, int)); - unsigned long count_flags_in_thread PROTO((MAILSTREAM *, PINETHRD_S *, long)); ---- 429,447 ---- - struct pass_along - *sort_thread_flatten PROTO((THREADNODE *, MAILSTREAM *, - struct pass_along *, -! PINETHRD_S *, unsigned, int, -! long,long)); - void make_thrdflags_consistent PROTO((MAILSTREAM *, MSGNO_S *, - PINETHRD_S *, int)); - THREADNODE *collapse_threadnode_tree PROTO((THREADNODE *)); -+ THREADNODE *copy_tree PROTO((THREADNODE *)); - PINETHRD_S *msgno_thread_info PROTO((MAILSTREAM *, unsigned long, - PINETHRD_S *, unsigned)); - long calculate_visible_threads PROTO((MAILSTREAM *)); - void set_thread_subtree PROTO((MAILSTREAM *, PINETHRD_S *, - MSGNO_S *, int, int)); - void thread_command PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, -! int, int, int)); - void set_flags_for_thread PROTO((MAILSTREAM *, MSGNO_S *, int, - PINETHRD_S *, int)); - unsigned long count_flags_in_thread PROTO((MAILSTREAM *, PINETHRD_S *, long)); -*************** -*** 592,600 **** ---- 633,644 ---- - return; - } - -+ state->redrawer = redraw_index_body; - state->prev_screen = mail_index_screen; - state->next_screen = SCREEN_FUN_NULL; - -+ setup_threading_display_style(); -+ - if(THRD_AUTO_VIEW() && sp_viewing_a_thread(state->mail_stream) - && state->view_skipped_index) - unview_thread(state, state->mail_stream, state->msgmap); -*************** -*** 702,720 **** - MAILSTREAM *stream; - MSGNO_S *msgmap; - { -! int ch, cmd, which_keys, force, - cur_row, cur_col, km_popped, paint_status; - int old_day = -1; -! long i, j, k, old_max_msgno; - IndexType style, old_style = MsgIndex; - struct index_state id; - struct key_menu *km = NULL; - #if defined(DOS) || defined(OS2) - extern void (*while_waiting)(); - #endif - - dprint(1, (debugfile, "\n\n ---- INDEX MANAGER ----\n")); -! - ch = 'x'; /* For displaying msg 1st time thru */ - force = 0; - km_popped = 0; ---- 746,770 ---- - MAILSTREAM *stream; - MSGNO_S *msgmap; - { -! int ch, cmd, which_keys, force, skip = 0, - cur_row, cur_col, km_popped, paint_status; - int old_day = -1; -! long i, j, k, old_max_msgno, nm; - IndexType style, old_style = MsgIndex; - struct index_state id; - struct key_menu *km = NULL; -+ FOLDER_S *f; - #if defined(DOS) || defined(OS2) - extern void (*while_waiting)(); - #endif - - dprint(1, (debugfile, "\n\n ---- INDEX MANAGER ----\n")); -! if (f = incoming_folder_data(stream, cntxt)){ -! f->selected = f->user_selected; /* unselect this folder now */ -! f->origrecent = stream->recent; /* more accurate than f->recent */ -! f->notified = 1; /* no updates in this screen */ -! f->countrecent = 0; -! } - ch = 'x'; /* For displaying msg 1st time thru */ - force = 0; - km_popped = 0; -*************** -*** 749,757 **** - } - - /*------- Check for new mail -------*/ -! new_mail(force, NM_TIMING(ch), NM_STATUS_MSG); -! force = 0; /* may not need to next time around */ -! - /* - * If the width of the message number field in the display changes - * we need to flush the cache and redraw. When the cache is cleared ---- 799,822 ---- - } - - /*------- Check for new mail -------*/ -! nm = new_mail(force, NM_TIMING(ch), NM_STATUS_MSG); -! if (!skip || nm > 0L){ -! if(nm > 0L) -! state->force_check_now = 1; -! if(f) -! f->notified = 1; -! new_mail_incfolder(state, MC_IFAUTOCHECK); -! } -! if (f){ -! long rec, tot; -! new_mail_in_open_stream(stream, &rec, &tot); -! f->countrecent = rec > f->recent ? rec - f->countrecent : 0; -! f->selected = f->user_selected; -! f->recent = rec; -! f->messages = tot; -! } -! ps_global->refresh_list = 0; /* reset refresh_list */ -! force = skip = 0; /* may not need to next time around */ - /* - * If the width of the message number field in the display changes - * we need to flush the cache and redraw. When the cache is cleared -*************** -*** 943,948 **** ---- 1008,1016 ---- - break; - } - -+ if ((cmd != MC_NONE) && (cmd != MC_FORCECHECK)) -+ state->force_check_now = 0; -+ - /*----------- Execute the command ------------------*/ - switch(cmd){ - -*************** -*** 958,963 **** ---- 1026,1032 ---- - - /*---------- Scroll line up ----------*/ - case MC_CHARUP : -+ previtem: - (void) process_cmd(state, stream, msgmap, MC_PREVITEM, - (style == MsgIndex - || style == MultiMsgIndex -*************** -*** 975,980 **** ---- 1044,1050 ---- - - /*---------- Scroll line down ----------*/ - case MC_CHARDOWN : -+ nextitem: - /* - * Special Page framing handling here. If we - * did something that should scroll-by-a-line, frame -*************** -*** 1192,1197 **** ---- 1262,1268 ---- - - - case MC_THRDINDX : -+ mc_thrdindx: - msgmap->top = msgmap->top_after_thrd; - if(unview_thread(state, stream, msgmap)){ - ps_global->redrawer = NULL; -*************** -*** 1239,1245 **** - && mp.col == id.plus_col - && style != ThreadIndex){ - collapse_or_expand(state, stream, msgmap, -! mn_get_cur(msgmap)); - } - else if (mp.doubleclick){ - if(mp.button == M_BUTTON_LEFT){ ---- 1310,1316 ---- - && mp.col == id.plus_col - && style != ThreadIndex){ - collapse_or_expand(state, stream, msgmap, -! mn_get_cur(msgmap), 1); - } - else if (mp.doubleclick){ - if(mp.button == M_BUTTON_LEFT){ -*************** -*** 1309,1314 **** ---- 1380,1387 ---- - reset_index_border(); - break; - -+ case MC_QUOTA: -+ cmd_quota(state); - - /*---------- Redraw ----------*/ - case MC_REPAINT : -*************** -*** 1333,1341 **** - - - case MC_COLLAPSE : -! thread_command(state, stream, msgmap, ch, -FOOTER_ROWS(state)); - break; - - case MC_DELETE : - case MC_UNDELETE : - case MC_REPLY : ---- 1406,1511 ---- - - - case MC_COLLAPSE : -! thread_command(state, stream, msgmap, ch, -FOOTER_ROWS(state), 1); - break; - -+ case MC_CTHREAD : -+ if (SEP_THRDINDX()) -+ goto mc_thrdindx; -+ else -+ if (THREADING()){ -+ if (any_messages(ps_global->msgmap, NULL, -+ "to collapse a thread")) -+ collapse_thread(state, stream,msgmap, 1); -+ } -+ else -+ q_status_message(SM_ORDER, 0, 1, -+ "Command available in threaded mode only"); -+ break; -+ -+ case MC_OTHREAD : -+ if (SEP_THRDINDX()) -+ goto view_a_thread; -+ else -+ if (THREADING()){ -+ if (any_messages(ps_global->msgmap, NULL, "to expand a thread")) -+ expand_thread(state, stream,msgmap, 1); -+ } -+ else -+ q_status_message(SM_ORDER, 0, 1, -+ "Command available in threaded mode only"); -+ break; -+ -+ case MC_NEXTHREAD: -+ case MC_PRETHREAD: -+ if (THRD_INDX()){ -+ if (cmd == MC_NEXTHREAD) -+ goto nextitem; -+ else -+ goto previtem; -+ } -+ else -+ if (THREADING()){ -+ if (any_messages(ps_global->msgmap, NULL, -+ "to move to other thread")) -+ move_thread(state, stream, msgmap, -+ cmd == MC_NEXTHREAD ? 1 : -1); -+ } -+ else -+ q_status_message(SM_ORDER, 0, 1, -+ "Command available in threaded mode only"); -+ break; -+ -+ case MC_KOLAPSE: -+ case MC_EXPTHREAD: -+ if (SEP_THRDINDX()){ -+ q_status_message(SM_ORDER, 0, 1, -+ "Command not available in this screen"); -+ } -+ else{ -+ if (THREADING()){ -+ if (any_messages(ps_global->msgmap, NULL, -+ cmd == MC_KOLAPSE ? "to collapse" : "to expand")) -+ kolapse_thread(state, stream, msgmap, -+ (cmd == MC_KOLAPSE) ? '[' : ']', 1); -+ } -+ else -+ q_status_message(SM_ORDER, 0, 1, -+ "Command available in threaded mode only"); -+ } -+ break; -+ -+ case MC_DELTHREAD: -+ if (THREADING()){ -+ if (any_messages(ps_global->msgmap, NULL, "to delete")) -+ cmd_delete_thread(state, stream, msgmap); -+ } -+ else -+ q_status_message(SM_ORDER, 0, 1, -+ "Command available in threaded mode only"); -+ break; -+ -+ case MC_UNDTHREAD: -+ if (THREADING()){ -+ if (any_messages(ps_global->msgmap, NULL, "to undelete")) -+ cmd_undelete_thread(state, stream, msgmap); -+ } -+ else -+ q_status_message(SM_ORDER, 0, 1, -+ "Command available in threaded mode only"); -+ break; -+ -+ -+ case MC_SELTHREAD: -+ if (THREADING()){ -+ if (any_messages(ps_global->msgmap, NULL, "to undelete")) -+ cmd_select_thread(state, stream, msgmap); -+ } -+ else -+ q_status_message(SM_ORDER, 0, 1, -+ "Command available in threaded mode only"); -+ break; -+ - case MC_DELETE : - case MC_UNDELETE : - case MC_REPLY : -*************** -*** 1356,1368 **** - if(rawno) - thrd = fetch_thread(stream, rawno); - -! collapsed = thrd && thrd->next -! && get_lflag(stream, NULL, rawno, MN_COLL); - } - - if(collapsed){ - thread_command(state, stream, msgmap, -! ch, -FOOTER_ROWS(state)); - /* increment current */ - if(cmd == MC_DELETE){ - advance_cur_after_delete(state, stream, msgmap, ---- 1526,1537 ---- - if(rawno) - thrd = fetch_thread(stream, rawno); - -! collapsed = thread_is_kolapsed(ps_global, stream, msgmap, rawno); - } - - if(collapsed){ - thread_command(state, stream, msgmap, -! ch, -FOOTER_ROWS(state),1); - /* increment current */ - if(cmd == MC_DELETE){ - advance_cur_after_delete(state, stream, msgmap, -*************** -*** 1401,1407 **** - } - /* else fall thru to normal default */ - -! - /*---------- Default -- all other command ----------*/ - default: - do_the_default: ---- 1570,1579 ---- - } - /* else fall thru to normal default */ - -! case MC_TAB: -! skip++; -! /* do not check for new mail in inc fldrs and fall through */ -! - /*---------- Default -- all other command ----------*/ - default: - do_the_default: -*************** -*** 2772,2777 **** ---- 2944,2950 ---- - n = mn_raw2m(msgs, thrd->rawno); - - while(thrd){ -+ unsigned long branch; - if(!msgline_hidden(stream, msgs, n, 0) - && (++m % lines_per_page) == 1L) - t = n; -*************** -*** 2840,2850 **** - - /* n is the end of this thread */ - while(thrd){ - n = mn_raw2m(msgs, thrd->rawno); -! if(thrd->branch) -! thrd = fetch_thread(stream, thrd->branch); -! else if(thrd->next) -! thrd = fetch_thread(stream, thrd->next); - else - thrd = NULL; - } ---- 3013,3024 ---- - - /* n is the end of this thread */ - while(thrd){ -+ unsigned long next = 0L, branch = 0L; - n = mn_raw2m(msgs, thrd->rawno); -! if(branch = get_branch(stream,thrd)) -! thrd = fetch_thread(stream, branch); -! else if(next = get_next(stream,thrd)) -! thrd = fetch_thread(stream, next); - else - thrd = NULL; - } -*************** -*** 2998,3003 **** ---- 3172,3178 ---- - case iSTime: - case iKSize: - case iSize: -+ case iSizeThread: - (*answer)[column].req_width = 7; - break; - case iS1Date: -*************** -*** 3034,3047 **** - static INDEX_PARSE_T itokens[] = { - {"STATUS", iStatus, FOR_INDEX}, - {"MSGNO", iMessNo, FOR_INDEX}, -! {"DATE", iDate, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"FROMORTO", iFromTo, FOR_INDEX}, - {"FROMORTONOTNEWS", iFromToNotNews, FOR_INDEX}, - {"SIZE", iSize, FOR_INDEX}, - {"SIZECOMMA", iSizeComma, FOR_INDEX}, - {"SIZENARROW", iSizeNarrow, FOR_INDEX}, - {"KSIZE", iKSize, FOR_INDEX}, -! {"SUBJECT", iSubject, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"FULLSTATUS", iFStatus, FOR_INDEX}, - {"IMAPSTATUS", iIStatus, FOR_INDEX}, - {"SUBJKEY", iSubjKey, FOR_INDEX}, ---- 3209,3223 ---- - static INDEX_PARSE_T itokens[] = { - {"STATUS", iStatus, FOR_INDEX}, - {"MSGNO", iMessNo, FOR_INDEX}, -! {"DATE", iDate, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, - {"FROMORTO", iFromTo, FOR_INDEX}, - {"FROMORTONOTNEWS", iFromToNotNews, FOR_INDEX}, - {"SIZE", iSize, FOR_INDEX}, - {"SIZECOMMA", iSizeComma, FOR_INDEX}, -+ {"SIZETHREAD", iSizeThread, FOR_INDEX}, - {"SIZENARROW", iSizeNarrow, FOR_INDEX}, - {"KSIZE", iKSize, FOR_INDEX}, -! {"SUBJECT", iSubject, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_TRIM}, - {"FULLSTATUS", iFStatus, FOR_INDEX}, - {"IMAPSTATUS", iIStatus, FOR_INDEX}, - {"SUBJKEY", iSubjKey, FOR_INDEX}, -*************** -*** 3051,3076 **** - {"DESCRIPSIZE", iDescripSize, FOR_INDEX}, - {"ATT", iAtt, FOR_INDEX}, - {"SCORE", iScore, FOR_INDEX}, -! {"LONGDATE", iLDate, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"SHORTDATE1", iS1Date, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"SHORTDATE2", iS2Date, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"SHORTDATE3", iS3Date, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"SHORTDATE4", iS4Date, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"DATEISO", iDateIso, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"SHORTDATEISO", iDateIsoS, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"SMARTDATE", iSDate, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"SMARTTIME", iSTime, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"SMARTDATETIME", iSDateTime, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"TIME24", iTime24, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"TIME12", iTime12, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"TIMEZONE", iTimezone, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"MONTHABBREV", iMonAbb, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"DAYOFWEEKABBREV", iDayOfWeekAbb, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"DAYOFWEEK", iDayOfWeek, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"FROM", iFrom, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"TO", iTo, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"SENDER", iSender, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"CC", iCc, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"RECIPS", iRecips, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"NEWS", iNews, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"TOANDNEWS", iToAndNews, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, ---- 3227,3255 ---- - {"DESCRIPSIZE", iDescripSize, FOR_INDEX}, - {"ATT", iAtt, FOR_INDEX}, - {"SCORE", iScore, FOR_INDEX}, -! {"LONGDATE", iLDate, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"SHORTDATE1", iS1Date, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"SHORTDATE2", iS2Date, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"SHORTDATE3", iS3Date, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"SHORTDATE4", iS4Date, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"DATEISO", iDateIso, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"SHORTDATEISO", iDateIsoS, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"SMARTDATE", iSDate, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"SMARTTIME", iSTime, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"SMARTDATETIME", iSDateTime, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"TIME24", iTime24, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"TIME12", iTime12, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"TIMEZONE", iTimezone, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"MONTHABBREV", iMonAbb, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"DAYOFWEEKABBREV", iDayOfWeekAbb, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"DAYOFWEEK", iDayOfWeek, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"FROM", iFrom, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_SAVE|FOR_RULE|FOR_COMPOSE}, -! {"TO", iTo, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_SAVE|FOR_RULE|FOR_COMPOSE}, -! {"SENDER", iSender, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_SAVE|FOR_RULE}, -! {"CC", iCc, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_SAVE|FOR_RULE}, -! {"ADDRESSTO", iAddressTo, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_SAVE|FOR_RULE}, -! {"ADDRESSCC", iAddressCc, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_SAVE|FOR_RULE}, -! {"ADDRESSRECIPS", iAddressRecip, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_SAVE|FOR_RULE}, - {"RECIPS", iRecips, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"NEWS", iNews, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"TOANDNEWS", iToAndNews, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -*************** -*** 3079,3124 **** - {"NEWSANDRECIPS", iNewsAndRecips, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"MSGID", iMsgID, FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"CURNEWS", iCurNews, FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"DAYDATE", iRDate, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"DAY", iDay, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"DAYORDINAL", iDayOrdinal, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"DAY2DIGIT", iDay2Digit, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"MONTHLONG", iMonLong, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"MONTH", iMon, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"MONTH2DIGIT", iMon2Digit, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"YEAR", iYear, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"YEAR2DIGIT", iYear2Digit, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"ADDRESS", iAddress, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"MAILBOX", iMailbox, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"ROLENICK", iRoleNick, FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"INIT", iInit, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"CURDATE", iCurDate, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"CURDATEISO", iCurDateIso, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"CURDATEISOS", iCurDateIsoS, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"CURTIME24", iCurTime24, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"CURTIME12", iCurTime12, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"CURDAY", iCurDay, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"CURDAY2DIGIT", iCurDay2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"CURDAYOFWEEK", iCurDayOfWeek, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, - {"CURDAYOFWEEKABBREV", iCurDayOfWeekAbb, -! FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"CURMONTH", iCurMon, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"CURMONTH2DIGIT", iCurMon2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"CURMONTHLONG", iCurMonLong, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"CURMONTHABBREV", iCurMonAbb, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"CURYEAR", iCurYear, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"CURYEAR2DIGIT", iCurYear2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"LASTMONTH", iLstMon, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"LASTMONTH2DIGIT", iLstMon2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"LASTMONTHLONG", iLstMonLong, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"LASTMONTHABBREV", iLstMonAbb, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"LASTMONTHYEAR", iLstMonYear, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, - {"LASTMONTHYEAR2DIGIT", iLstMonYear2Digit, -! FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"LASTYEAR", iLstYear, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, -! {"LASTYEAR2DIGIT", iLstYear2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT}, - {"ARROW", iArrow, FOR_INDEX}, - {"CURSORPOS", iCursorPos, FOR_TEMPLATE}, - {NULL, iNothing, FOR_NOTHING} - }; - ---- 3258,3312 ---- - {"NEWSANDRECIPS", iNewsAndRecips, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"MSGID", iMsgID, FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"CURNEWS", iCurNews, FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"DAYDATE", iRDate, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"DAY", iDay, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"DAYORDINAL", iDayOrdinal, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"DAY2DIGIT", iDay2Digit, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"MONTHLONG", iMonLong, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"MONTH", iMon, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"MONTH2DIGIT", iMon2Digit, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"YEAR", iYear, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"YEAR2DIGIT", iYear2Digit, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE}, -! {"ADDRESS", iAddress, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE}, - {"MAILBOX", iMailbox, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"ROLENICK", iRoleNick, FOR_REPLY_INTRO|FOR_TEMPLATE}, - {"INIT", iInit, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE}, -! {"CURDATE", iCurDate, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"CURDATEISO", iCurDateIso, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"CURDATEISOS", iCurDateIsoS, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"CURTIME24", iCurTime24, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"CURTIME12", iCurTime12, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"CURDAY", iCurDay, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"CURDAY2DIGIT", iCurDay2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"CURDAYOFWEEK", iCurDayOfWeek, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, - {"CURDAYOFWEEKABBREV", iCurDayOfWeekAbb, -! FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"CURMONTH", iCurMon, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"CURMONTH2DIGIT", iCurMon2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"CURMONTHLONG", iCurMonLong, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"CURMONTHABBREV", iCurMonAbb, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"CURYEAR", iCurYear, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"CURYEAR2DIGIT", iCurYear2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"LASTMONTH", iLstMon, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"LASTMONTH2DIGIT", iLstMon2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"LASTMONTHLONG", iLstMonLong, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"LASTMONTHABBREV", iLstMonAbb, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"LASTMONTHYEAR", iLstMonYear, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, - {"LASTMONTHYEAR2DIGIT", iLstMonYear2Digit, -! FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"LASTYEAR", iLstYear, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, -! {"LASTYEAR2DIGIT", iLstYear2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE|FOR_FILT}, - {"ARROW", iArrow, FOR_INDEX}, - {"CURSORPOS", iCursorPos, FOR_TEMPLATE}, -+ {"NICK", iNick, FOR_RULE|FOR_SAVE}, -+ {"FOLDER", iFolder, FOR_RULE|FOR_SAVE|FOR_FOLDER}, -+ {"ROLE", iRole, FOR_RULE|FOR_RESUB|FOR_TRIM|FOR_TEMPLATE}, -+ {"FLAG", iFlag, FOR_RULE|FOR_SAVE|FOR_FLAG}, -+ {"COLLECTION", iCollection, FOR_RULE|FOR_SAVE|FOR_COMPOSE|FOR_FOLDER}, -+ {"BCC", iBcc, FOR_COMPOSE|FOR_RULE}, -+ {"LCC", iLcc, FOR_COMPOSE|FOR_RULE}, -+ {"FORWARDFROM", iFfrom, FOR_COMPOSE|FOR_RULE}, -+ {"FORWARDADDRESS", iFadd, FOR_COMPOSE|FOR_RULE}, - {NULL, iNothing, FOR_NOTHING} - }; - -*************** -*** 3286,3292 **** - */ - static IndexColType fixed_ctypes[] = { - iArrow, iMessNo, iStatus, iFStatus, iIStatus, iDate, iSDate, iSDateTime, -! iSTime, iLDate, - iS1Date, iS2Date, iS3Date, iS4Date, iDateIso, iDateIsoS, - iSize, iSizeComma, iSizeNarrow, iKSize, iDescripSize, - iAtt, iTime24, iTime12, iTimezone, iMonAbb, iYear, iYear2Digit, ---- 3474,3480 ---- - */ - static IndexColType fixed_ctypes[] = { - iArrow, iMessNo, iStatus, iFStatus, iIStatus, iDate, iSDate, iSDateTime, -! iSTime, iLDate, iSizeThread, - iS1Date, iS2Date, iS3Date, iS4Date, iDateIso, iDateIsoS, - iSize, iSizeComma, iSizeNarrow, iKSize, iDescripSize, - iAtt, iTime24, iTime12, iTimezone, iMonAbb, iYear, iYear2Digit, -*************** -*** 3457,3462 **** ---- 3645,3651 ---- - case iTime12: - case iSize: - case iKSize: -+ case iSizeThread: - cdesc->actual_length = 7; - cdesc->adjustment = Right; - break; -*************** -*** 3521,3527 **** - cdesc->ctype != iNothing; - cdesc++) - if(cdesc->ctype == iSize || cdesc->ctype == iKSize || -! cdesc->ctype == iSizeNarrow || - cdesc->ctype == iSizeComma || cdesc->ctype == iDescripSize){ - if(cdesc->actual_length == 0){ - if((fix=cdesc->width) > 0){ /* had this reserved */ ---- 3710,3716 ---- - cdesc->ctype != iNothing; - cdesc++) - if(cdesc->ctype == iSize || cdesc->ctype == iKSize || -! cdesc->ctype == iSizeNarrow || cdesc->ctype == iSizeThread || - cdesc->ctype == iSizeComma || cdesc->ctype == iDescripSize){ - if(cdesc->actual_length == 0){ - if((fix=cdesc->width) > 0){ /* had this reserved */ -*************** -*** 3813,3818 **** ---- 4002,4081 ---- - } - } - -+ ENVELOPE *make_envelope(idata, index) -+ INDEXDATA_S *idata; -+ int index; -+ { -+ ENVELOPE *result; -+ -+ result = mail_newenvelope(); -+ -+ result->from = rfc822_cpy_adr(idata->from); -+ result->to = rfc822_cpy_adr(idata->to); -+ result->cc = rfc822_cpy_adr(idata->cc); -+ result->sender = rfc822_cpy_adr(idata->sender); -+ result->subject = cpystr(idata->subject); -+ result->newsgroups = index ? cpystr(idata->newsgroups) : -+ IS_NEWS(idata->stream) ? cpystr(ps_global->cur_folder) -+ : NULL; -+ return result; -+ } -+ -+ /*--------------------------------- -+ -+ -----------*/ -+ -+ char *find_value(token,function1, context1, function2, context2, function3, context3, idata, code) -+ char *token; -+ char *function1; -+ int context1; -+ char *function2; -+ int context2; -+ char *function3; -+ int context3; -+ INDEXDATA_S *idata; -+ int code; -+ { int n = 0, done = 0, next_step = 0; -+ char *rule_result; -+ int rule_context; -+ RULELIST *rule = get_rulelist_from_code(code, ps_global->rule_list); -+ RULE_S *prule; -+ -+ if (rule){ -+ rule_context = FOR_RULE; -+ while (!done && (prule = get_rule(rule,n++))){ -+ if (context1 && prule->action->token && -+ !strcmp(prule->action->token, token) -+ && !strcmp(prule->action->function, function1)){ -+ rule_context |= context1; -+ next_step++; -+ } -+ if (context2 && prule->action->token && -+ !strcmp(prule->action->token, token) -+ && !strcmp(prule->action->function, function2)){ -+ rule_context |= context2; -+ next_step++; -+ } -+ if (context3 && prule->action->token && -+ !strcmp(prule->action->token, token) -+ && !strcmp(prule->action->function, function3)){ -+ rule_context |= context3; -+ next_step++; -+ } -+ if (next_step){ -+ ENVELOPE *local_env = make_envelope(idata,1); -+ next_step = FALSE; -+ rule_result = process_rule(prule, rule_context, local_env); -+ if (local_env) -+ mail_free_envelope(&local_env); -+ if (rule_result) -+ done++; -+ } -+ } -+ } -+ return done ? rule_result : NULL; -+ } -+ - - /*---------------------------------------------------------------------- - Create a string summarizing the message header for index on screen -*************** -*** 3945,3954 **** - - /* find next thread which is visible */ - do{ - if(mn_get_revsort(msgmap) && thrd->prevthd) - thrd = fetch_thread(stream, thrd->prevthd); -! else if(!mn_get_revsort(msgmap) && thrd->nextthd) -! thrd = fetch_thread(stream, thrd->nextthd); - else - thrd = NULL; - } while(thrd ---- 4208,4218 ---- - - /* find next thread which is visible */ - do{ -+ unsigned long branch; - if(mn_get_revsort(msgmap) && thrd->prevthd) - thrd = fetch_thread(stream, thrd->prevthd); -! else if(!mn_get_revsort(msgmap) && thrd->branch) -! thrd = fetch_thread(stream, thrd->branch); - else - thrd = NULL; - } while(thrd -*************** -*** 4404,4414 **** - } - - /* is this a collapsed thread index line? */ - if(!idata->bogus && THREADING()){ -! thrd = fetch_thread(idata->stream, idata->rawno); -! collapsed = thrd && thrd->next -! && get_lflag(idata->stream, NULL, -! idata->rawno, MN_COLL); - } - - /* calculate contents of the required fields */ ---- 4668,4676 ---- - } - - /* is this a collapsed thread index line? */ -+ thrd = fetch_thread(idata->stream, idata->rawno); - if(!idata->bogus && THREADING()){ -! collapsed = thrd && thread_is_kolapsed(ps_global, idata->stream, ps_global->msgmap, idata->rawno); - } - - /* calculate contents of the required fields */ -*************** -*** 4940,4946 **** ---- 5202,5232 ---- - - break; - -+ case iSizeThread: -+ if (!THREADING()){ -+ goto getsize; -+ } else if (collapsed){ -+ l = count_flags_in_thread(idata->stream, thrd, F_NONE); -+ sprintf(str, "(%lu)", l); -+ } -+ else{ -+ thrd = fetch_thread(idata->stream, idata->rawno); -+ if(!thrd) -+ sprintf(str,"Error"); -+ else{ -+ long lengthb; -+ lengthb = get_length_branch(idata->stream, idata->rawno); -+ -+ if (lengthb > 0L) -+ sprintf(str,"(%lu)", lengthb); -+ else -+ sprintf(str," "); -+ } -+ } -+ break; -+ - case iSize: -+ getsize: - /* 0 ... 9999 */ - if((l = fetch_size(idata)) < 10*1000L) - sprintf(str, "(%lu)", l); -*************** -*** 7031,7041 **** - unsigned long rawno; - unsigned char buf[MAILTMPLEN]; - OFFCOLOR_S myoffs[OFFS]; -! int mynoff = 0; - - memset(str, 0, (width+1) * sizeof(*str)); - origstr = str; -! origsubj = fetch_subject(idata); - if(!origsubj) - origsubj = ""; - ---- 7317,7335 ---- - unsigned long rawno; - unsigned char buf[MAILTMPLEN]; - OFFCOLOR_S myoffs[OFFS]; -! int mynoff = 0, we_clear = 0; -! char *rule_result; - - memset(str, 0, (width+1) * sizeof(*str)); - origstr = str; -! rule_result = find_value("_SUBJECT_", "_REPLACE_", FOR_REPLACE, "_TRIM_", FOR_TRIM, "_REXTRIM_", FOR_TRIM, idata, V_REPLACE_RULES); -! if (rule_result){ -! we_clear++; -! origsubj = cpystr(rule_result); -! fs_give((void **)&rule_result); -! } -! else -! origsubj = fetch_subject(idata); - if(!origsubj) - origsubj = ""; - -*************** -*** 7060,7067 **** - thdorig = thd = fetch_thread(idata->stream, idata->rawno); - border = str + width; - if(current_index_state->plus_col >= 0 && !THRD_INDX()){ -! collapsed = thd && thd->next && -! get_lflag(idata->stream, NULL, idata->rawno, MN_COLL); - hline = get_index_cache(idata->msgno); - hline->plus = collapsed ? ps_global->VAR_THREAD_MORE_CHAR[0] - : (thd && thd->next) ---- 7354,7361 ---- - thdorig = thd = fetch_thread(idata->stream, idata->rawno); - border = str + width; - if(current_index_state->plus_col >= 0 && !THRD_INDX()){ -! collapsed = this_thread_is_kolapsed(ps_global, idata->stream, ps_global->msgmap, idata->rawno); -! collapsed = collapsed && (count_thread(ps_global,idata->stream, ps_global->msgmap, idata->rawno) != 1); - hline = get_index_cache(idata->msgno); - hline->plus = collapsed ? ps_global->VAR_THREAD_MORE_CHAR[0] - : (thd && thd->next) -*************** -*** 7316,7321 **** ---- 7610,7617 ---- - - if(free_subj) - fs_give((void **) &free_subj); -+ if (we_clear && origsubj) -+ fs_give((void **)&origsubj); - - /* adjust offsets for indents and subject truncation */ - if(offs && noff && *noff < OFFS && mynoff && pico_usingcolor()){ -*************** -*** 7543,7550 **** - thdorig = thd = fetch_thread(idata->stream, idata->rawno); - border = str + width; - if(current_index_state->plus_col >= 0 && !THRD_INDX()){ -! collapsed = thd && thd->next && -! get_lflag(idata->stream, NULL, idata->rawno, MN_COLL); - hline = get_index_cache(idata->msgno); - hline->plus = collapsed ? ps_global->VAR_THREAD_MORE_CHAR[0] - : (thd && thd->next) ---- 7839,7846 ---- - thdorig = thd = fetch_thread(idata->stream, idata->rawno); - border = str + width; - if(current_index_state->plus_col >= 0 && !THRD_INDX()){ -! collapsed = this_thread_is_kolapsed(ps_global, idata->stream, ps_global->msgmap, idata->rawno); -! collapsed = collapsed && (count_thread (ps_global,idata->stream, ps_global->msgmap, idata->rawno) != 1); - hline = get_index_cache(idata->msgno); - hline->plus = collapsed ? ps_global->VAR_THREAD_MORE_CHAR[0] - : (thd && thd->next) -*************** -*** 7635,7650 **** - ? "To" - : (addr = fetch_cc(idata)) - ? "Cc" -! : NULL)) -! && set_index_addr(idata, field, addr, "To: ", -! width, fptr)) -! break; -! - if(ctype == iFromTo && - (newsgroups = fetch_newsgroups(idata)) && - *newsgroups){ -! sprintf(fptr, "To: %-*.*s", width-4, width-4, -! newsgroups); - break; - } - ---- 7931,7960 ---- - ? "To" - : (addr = fetch_cc(idata)) - ? "Cc" -! : NULL))){ -! char *rule_result; -! rule_result = find_value("_FROM_","_REPLACE_",FOR_REPLACE, NULL,0,NULL,0, idata,V_REPLACE_RULES); -! if (!rule_result) -! set_index_addr(idata, field, addr, "To: ", -! width, str); -! else{ -! sprintf(str, "%-*.*s", width, width, rule_result); -! fs_give((void **)&rule_result); -! } -! break; -! } - if(ctype == iFromTo && - (newsgroups = fetch_newsgroups(idata)) && - *newsgroups){ -! char *rule_result; -! rule_result = find_value("_FROM_","_REPLACE_",FOR_REPLACE, NULL,0,NULL, 0, idata, V_REPLACE_RULES); -! if (!rule_result) -! sprintf(str, "To: %-*.*s", width-4, width-4, -! newsgroups); -! else{ -! sprintf(str, "%-*.*s", width, width, rule_result); -! fs_give((void **)&rule_result); -! } - break; - } - -*************** -*** 7657,7664 **** - break; - - case iFrom: -! set_index_addr(idata, "From", fetch_from(idata), -! NULL, width, fptr); - break; - - case iAddress: ---- 7967,7983 ---- - break; - - case iFrom: -! { char *rule_result; -! rule_result = find_value("_FROM_","_REPLACE_", FOR_REPLACE, "_TRIM_", FOR_TRIM, "_REXTRIM_", FOR_TRIM, idata, V_REPLACE_RULES); -! if (!rule_result) -! set_index_addr(idata, "From", fetch_from(idata), -! NULL, width, str); -! else{ -! sprintf(str, "%-*.*s", width, width, rule_result); -! fs_give((void **)&rule_result); -! } -! } -! - break; - - case iAddress: -*************** -*** 7741,7746 **** ---- 8060,8083 ---- - return(1); - } - -+ void -+ insert_pattern_in_string(buf, last, maxbuf) -+ char *buf; -+ char *last; -+ int maxbuf; -+ { -+ if (last[0] != '\0'){ -+ int lenlast, lenbuf; -+ lenlast = strlen(last); -+ lenbuf = buf[0] == '\0' ? 0 : strlen(buf); -+ if (lenlast + lenbuf <= maxbuf){ -+ if (buf[0] == '\0') -+ strcpy(buf, last); -+ else -+ strcat(buf, last); -+ } -+ } -+ } - - - /*---------------------------------------------------------------------- -*************** -*** 7765,7773 **** ---- 8102,8112 ---- - long i, sorted_msg, selected = 0L; - char prompt[MAX_SEARCH+50], new_string[MAX_SEARCH+1]; - HelpType help; -+ static char last_search_pat[MAX_SEARCH+1] = {'\0'}; - static char search_string[MAX_SEARCH+1] = { '\0' }; - HLINE_S *hl; - static ESCKEY_S header_search_key[] = { {0, 0, NULL, NULL }, -+ {ctrl('N'), 9, "^N","Ins Pat"}, - {ctrl('Y'), 10, "^Y", "First Msg"}, - {ctrl('V'), 11, "^V", "Last Msg"}, - {-1, 0, NULL, NULL} }; -*************** -*** 7814,7819 **** ---- 8153,8160 ---- - : h_os_index_whereis; - continue; - } -+ else if(rc == 9) -+ insert_pattern_in_string(new_string, last_search_pat, MAX_SEARCH); - else if(rc == 10){ - q_status_message(SM_ORDER, 0, 3, "Searched to First Message."); - if(any_lflagged(msgmap, MN_HIDE | MN_CHID)){ -*************** -*** 7851,7857 **** - break; - } - -! if(rc != 4) /* redraw */ - break; /* redraw */ - } - ---- 8192,8198 ---- - break; - } - -! if(rc != 4 && rc != 9) /* redraw */ - break; /* redraw */ - } - -*************** -*** 7868,7873 **** ---- 8209,8217 ---- - strncpy(search_string, new_string, sizeof(search_string)); - search_string[sizeof(search_string)-1] = '\0'; - -+ strncpy(last_search_pat, new_string, sizeof(last_search_pat)); -+ last_search_pat[sizeof(last_search_pat)-1] = '\0'; -+ - #ifndef DOS - intr_handling_on(); - #endif -*************** -*** 8054,8059 **** ---- 8398,8440 ---- - : ((mdiff = *mess_a - *mess_b) ? ((mdiff > 0) ? 1 : -1) : 0)); - } - -+ SortOrder translate(order, is_rev) -+ char *order; -+ int is_rev; -+ { -+ int rev = 0; -+ if (!strncmp(order,"tHread", 6) -+ || (rev = !strncmp(order,"Reverse tHread", 14))) -+ return is_rev || rev ? SortThread : EndofList; -+ if (!strncmp(order,"OrderedSubj", 11) -+ || (rev = !strncmp(order,"Reverse OrderedSubj", 19))) -+ return is_rev || rev ? SortSubject2 : EndofList; -+ if (!strncmp(order,"Subject", 7) -+ || (rev = !strncmp(order,"Reverse SortSubject", 15))) -+ return is_rev || rev ? SortSubject : EndofList; -+ if (!strncmp(order,"Arrival", 7) -+ || (rev = !strncmp(order,"Reverse Arrival", 15))) -+ return is_rev || rev ? SortArrival : EndofList; -+ if (!strncmp(order,"From", 4) -+ || (rev = !strncmp(order,"Reverse From", 12))) -+ return is_rev || rev ? SortFrom : EndofList; -+ if (!strncmp(order,"To", 2) -+ || (rev = !strncmp(order,"Reverse To", 10))) -+ return is_rev || rev ? SortTo : EndofList; -+ if (!strncmp(order,"Cc", 2) -+ || (rev = !strncmp(order,"Reverse Cc", 10))) -+ return is_rev || rev ? SortCc : EndofList; -+ if (!strncmp(order,"Date", 4) -+ || (rev = !strncmp(order,"Reverse Date", 12))) -+ return is_rev || rev ? SortDate : EndofList; -+ if (!strncmp(order,"siZe", 4) -+ || (rev = !strncmp(order,"Reverse siZe", 12))) -+ return is_rev || rev ? SortSize : EndofList; -+ if (!strncmp(order,"scorE", 5) -+ || (rev = !strncmp(order,"Reverse scorE", 13))) -+ return is_rev || rev ? SortScore : EndofList; -+ return EndofList; -+ } - - /*---------------------------------------------------------------------- - Sort the current folder into the order set in the msgmap -*************** -*** 8069,8080 **** - causes the sort to happen if it is still needed. - ----*/ - void -! sort_folder(stream, msgmap, new_sort, new_rev, flags) - MAILSTREAM *stream; - MSGNO_S *msgmap; - SortOrder new_sort; - int new_rev; - unsigned flags; - { - long raw_current, i, j; - unsigned long *sort = NULL; ---- 8450,8462 ---- - causes the sort to happen if it is still needed. - ----*/ - void -! sort_folder(stream, msgmap, new_sort, new_rev, flags, first) - MAILSTREAM *stream; - MSGNO_S *msgmap; - SortOrder new_sort; - int new_rev; - unsigned flags; -+ int first; - { - long raw_current, i, j; - unsigned long *sort = NULL; -*************** -*** 8084,8089 **** ---- 8466,8480 ---- - int current_rev; - MESSAGECACHE *mc; - -+ if (first){ -+ if (new_sort == SortThread) -+ find_msgmap(stream, msgmap, flags, -+ ps_global->thread_cur_sort, new_rev); -+ else -+ sort_folder(stream, msgmap, new_sort, new_rev, flags, 0); -+ return; -+ } -+ - dprint(2, (debugfile, "Sorting by %s%s\n", - sort_name(new_sort), new_rev ? "/reverse" : "")); - -*************** -*** 8446,8451 **** ---- 8837,8843 ---- - - thrd = fetch_head_thread(stream); - for(j = msgmap->max_thrdno; thrd && j >= 1L; j--){ -+ unsigned long branch; - thrd->thrdno = j; - - if(thrd->nextthd) -*************** -*** 8512,8518 **** - MESSAGECACHE *mc; - PINELT_S *peltp; - -! if(!(stream && stream->spare)) - return; - - ps_global->view_skipped_index = 0; ---- 8904,8910 ---- - MESSAGECACHE *mc; - PINELT_S *peltp; - -! if(!(stream && stream->spare) || !erase_thread_info) - return; - - ps_global->view_skipped_index = 0; -*************** -*** 8574,8580 **** - unsigned long msgno, rawno, set_in_thread, in_thread; - int bail, this_is_vis; - int un_view_thread = 0; -! long raw_current; - - - dprint(2, (debugfile, "sort_thread_callback\n")); ---- 8966,8972 ---- - unsigned long msgno, rawno, set_in_thread, in_thread; - int bail, this_is_vis; - int un_view_thread = 0; -! long raw_current, branch; - - - dprint(2, (debugfile, "sort_thread_callback\n")); -*************** -*** 8593,8601 **** - * way. If the dummy node is at the top-level, then its children are - * promoted to the top-level as separate threads. - */ -! collapsed_tree = collapse_threadnode_tree(tree); -! (void) sort_thread_flatten(collapsed_tree, stream, thrd_flatten_array, -! NULL, THD_TOP); - mail_free_threadnode(&collapsed_tree); - - if(any_lflagged(g_sort.msgmap, MN_HIDE)) ---- 8985,8995 ---- - * way. If the dummy node is at the top-level, then its children are - * promoted to the top-level as separate threads. - */ -! collapsed_tree = F_ON(F_ENHANCED_THREAD, ps_global) ? -! copy_tree(tree) : collapse_threadnode_tree(tree); -! (void) sort_thread_flatten(collapsed_tree, -! stream, thrd_flatten_array, -! NULL, THD_TOP, 0, 1L, 0L); - mail_free_threadnode(&collapsed_tree); - - if(any_lflagged(g_sort.msgmap, MN_HIDE)) -*************** -*** 8760,8771 **** - else{ - thrd = fetch_head_thread(stream); - while(thrd){ - /* - * The top-level threads aren't hidden by collapse. - */ - msgno = mn_raw2m(g_sort.msgmap, thrd->rawno); -! if(msgno) -! set_lflag(stream, g_sort.msgmap, msgno, MN_CHID, 0); - - if(thrd->next){ - PINETHRD_S *nthrd; ---- 9154,9167 ---- - else{ - thrd = fetch_head_thread(stream); - while(thrd){ -+ unsigned long raw = thrd->rawno; -+ unsigned long top = top_thread(stream, raw); - /* - * The top-level threads aren't hidden by collapse. - */ - msgno = mn_raw2m(g_sort.msgmap, thrd->rawno); -! if(msgno && !get_lflag(stream, NULL,thrd->rawno, MN_COLL)) -! set_lflag(stream, g_sort.msgmap, msgno, MN_CHID, 0); - - if(thrd->next){ - PINETHRD_S *nthrd; -*************** -*** 8779,8787 **** - MN_COLL)); - } - -! if(thrd->nextthd) - thrd = fetch_thread(stream, thrd->nextthd); -! else - thrd = NULL; - } - } ---- 9175,9184 ---- - MN_COLL)); - } - -! while (thrd && top_thread(stream, thrd->rawno) == top -! && thrd->nextthd) - thrd = fetch_thread(stream, thrd->nextthd); -! if (!(thrd && thrd->nextthd)) - thrd = NULL; - } - } -*************** -*** 8802,8811 **** - PINETHRD_S *not_this_thread; - { - PINETHRD_S *thrd = NULL, *nthrd; -! unsigned long msgno; - - dprint(9, (debugfile, "collapse_threads\n")); - - thrd = fetch_head_thread(stream); - while(thrd){ - if(thrd != not_this_thread){ ---- 9199,9215 ---- - PINETHRD_S *not_this_thread; - { - PINETHRD_S *thrd = NULL, *nthrd; -! unsigned long msgno, branch; - - dprint(9, (debugfile, "collapse_threads\n")); - -+ /* if(F_ON(F_ENHANCED_THREAD, ps_global)){*/ -+ kolapse_thread(ps_global, stream, msgmap, '[', 0); -+ if (not_this_thread) -+ expand_thread(ps_global, stream, msgmap, 0); -+ return; -+ /* }*/ -+ - thrd = fetch_head_thread(stream); - while(thrd){ - if(thrd != not_this_thread){ -*************** -*** 8840,8846 **** - int a_parent_is_collapsed; - { - PINETHRD_S *nthrd, *bthrd; -! unsigned long msgno; - - if(!thrd) - return; ---- 9244,9250 ---- - int a_parent_is_collapsed; - { - PINETHRD_S *nthrd, *bthrd; -! unsigned long msgno, next, branch; - - if(!thrd) - return; -*************** -*** 8858,8865 **** - set_lflag(stream, msgmap, msgno, MN_CHID, 0); - } - -! if(thrd->next){ -! nthrd = fetch_thread(stream, thrd->next); - if(nthrd) - make_thrdflags_consistent(stream, msgmap, nthrd, - a_parent_is_collapsed ---- 9262,9269 ---- - set_lflag(stream, msgmap, msgno, MN_CHID, 0); - } - -! if(next = get_next(stream, thrd)){ -! nthrd = fetch_thread(stream, next); - if(nthrd) - make_thrdflags_consistent(stream, msgmap, nthrd, - a_parent_is_collapsed -*************** -*** 8868,8875 **** - MN_COLL)); - } - -! if(thrd->branch){ -! bthrd = fetch_thread(stream, thrd->branch); - if(bthrd) - make_thrdflags_consistent(stream, msgmap, bthrd, - a_parent_is_collapsed); ---- 9272,9279 ---- - MN_COLL)); - } - -! if(branch = get_branch(stream, thrd)){ -! bthrd = fetch_thread(stream, branch); - if(bthrd) - make_thrdflags_consistent(stream, msgmap, bthrd, - a_parent_is_collapsed); -*************** -*** 8882,8888 **** - MAILSTREAM *stream; - { - PINETHRD_S *thrd = NULL; -! long vis = 0L; - - thrd = fetch_head_thread(stream); - while(thrd){ ---- 9286,9292 ---- - MAILSTREAM *stream; - { - PINETHRD_S *thrd = NULL; -! long vis = 0L, branch; - - thrd = fetch_head_thread(stream); - while(thrd){ -*************** -*** 8899,8945 **** - - - struct pass_along * -! sort_thread_flatten(node, stream, entry, thrd, flags) - THREADNODE *node; - MAILSTREAM *stream; - struct pass_along *entry; - PINETHRD_S *thrd; - unsigned flags; - { - long n = 0L; -! PINETHRD_S *newthrd = NULL; - - if(node){ -! if(node->num){ /* holes happen */ - n = (long) (entry - thrd_flatten_array); - - for(; n > 0; n--) - if(thrd_flatten_array[n].rawno == node->num) - break; /* duplicate */ - -! if(!n) -! entry->rawno = node->num; -! } -! -! /* -! * Build a richer threading structure that will help us paint -! * and operate on threads and subthreads. -! */ -! if(!n && node->num){ -! newthrd = msgno_thread_info(stream, node->num, thrd, flags); -! if(newthrd){ -! entry->thrd = newthrd; -! entry++; -! -! if(node->next) - entry = sort_thread_flatten(node->next, stream, entry, -! newthrd, THD_NEXT); -! - if(node->branch) - entry = sort_thread_flatten(node->branch, stream, entry, -! newthrd, -! (flags == THD_TOP) ? THD_TOP -! : THD_BRANCH); - } - } - } ---- 9303,9388 ---- - - - struct pass_along * -! sort_thread_flatten(node, stream, entry, thrd, flags, adopted, top, threadno) - THREADNODE *node; - MAILSTREAM *stream; - struct pass_along *entry; - PINETHRD_S *thrd; - unsigned flags; -+ int adopted; -+ long top; -+ long threadno; - { - long n = 0L; -! PINETHRD_S *newthrd = NULL, *save_thread = NULL; - - if(node){ -! if(node->num){ - n = (long) (entry - thrd_flatten_array); - -+ if (adopted == 2) -+ top = node->num; -+ - for(; n > 0; n--) - if(thrd_flatten_array[n].rawno == node->num) - break; /* duplicate */ - -! if(!n){ -! entry->rawno = node->num; -! newthrd = msgno_thread_info(stream, node->num, thrd, flags); -! if(newthrd){ -! if (adopted == 2) -! threadno = newthrd->thrdno; -! if (adopted){ -! newthrd->toploose = top; -! newthrd->thrdno = threadno; -! } -! entry->thrd = newthrd; -! entry++; -! } -! adopted = adopted ? 1 : 0; -! if (node->next) - entry = sort_thread_flatten(node->next, stream, entry, -! newthrd, THD_NEXT, adopted, top, -! threadno); - if(node->branch) - entry = sort_thread_flatten(node->branch, stream, entry, -! newthrd, -! (flags == THD_TOP) ? THD_TOP: THD_BRANCH, -! adopted, top, threadno); -! } -! } -! else{ -! adopted = 2; -! if(node->next) -! entry = sort_thread_flatten(node->next, stream, entry, -! thrd, THD_TOP, adopted, top, threadno); -! adopted = 0; -! if(node->branch){ -! if(entry){ -! struct pass_along *last_entry = entry; -! int i = 0; -! -! /* -! * Next moved up to replace "tree" in the tree. -! * If next has no branches, then we want to branch off -! * of next. If next has branches, we want to branch off -! * of the last of those branches instead. -! */ -! last_entry--; -! while(last_entry->thrd->parent) -! last_entry--; -! save_thread = last_entry->thrd; -! last_entry += i+1; -! -! last_entry = sort_thread_flatten(node->branch, stream, entry, -! save_thread, -! (flags == THD_TOP) ? THD_TOP: THD_BRANCH, -! adopted, top, threadno); -! } -! else -! entry = sort_thread_flatten(node->branch, stream, entry, -! NULL, THD_TOP, adopted, top, threadno); - } - } - } -*************** -*** 8947,8952 **** ---- 9390,9415 ---- - return(entry); - } - -+ /* -+ * Make a copy of c-client's THREAD tree -+ */ -+ THREADNODE * -+ copy_tree(tree) -+ THREADNODE *tree; -+ { -+ THREADNODE *newtree = NULL; -+ -+ if(tree){ -+ newtree = mail_newthreadnode(NULL); -+ newtree->num = tree->num; -+ if(tree->next) -+ newtree->next = copy_tree(tree->next); -+ -+ if(tree->branch) -+ newtree->branch = copy_tree(tree->branch); -+ } -+ return(newtree); -+ } - - /* - * Make a copy of c-client's THREAD tree while eliminating dummy nodes. -*************** -*** 10694,10705 **** - - - void -! thread_command(state, stream, msgmap, preloadkeystroke, q_line) - struct pine *state; - MAILSTREAM *stream; - MSGNO_S *msgmap; - int preloadkeystroke; - int q_line; - { - PINETHRD_S *thrd = NULL; - unsigned long rawno, save_branch; ---- 11157,11169 ---- - - - void -! thread_command(state, stream, msgmap, preloadkeystroke, q_line, display) - struct pine *state; - MAILSTREAM *stream; - MSGNO_S *msgmap; - int preloadkeystroke; - int q_line; -+ int display; - { - PINETHRD_S *thrd = NULL; - unsigned long rawno, save_branch; -*************** -*** 10748,10754 **** - cancel_busy_alarm(0); - - (void ) apply_command(state, stream, msgmap, preloadkeystroke, flags, -! q_line); - - /* restore the original flags */ - copy_lflags(stream, msgmap, MN_STMP, MN_SLCT); ---- 11212,11218 ---- - cancel_busy_alarm(0); - - (void ) apply_command(state, stream, msgmap, preloadkeystroke, flags, -! q_line, display); - - /* restore the original flags */ - copy_lflags(stream, msgmap, MN_STMP, MN_SLCT); -*************** -*** 10786,10805 **** - int v; - { - PINETHRD_S *nthrd, *bthrd; - - if(!(stream && thrd && msgmap)) - return; - - set_lflag(stream, msgmap, mn_raw2m(msgmap, thrd->rawno), f, v); - -! if(thrd->next){ -! nthrd = fetch_thread(stream, thrd->next); - if(nthrd) - set_flags_for_thread(stream, msgmap, f, nthrd, v); - } - -! if(thrd->branch){ -! bthrd = fetch_thread(stream, thrd->branch); - if(bthrd) - set_flags_for_thread(stream, msgmap, f, bthrd, v); - } ---- 11250,11270 ---- - int v; - { - PINETHRD_S *nthrd, *bthrd; -+ unsigned long next = 0L, branch = 0L; - - if(!(stream && thrd && msgmap)) - return; - - set_lflag(stream, msgmap, mn_raw2m(msgmap, thrd->rawno), f, v); - -! if(next = get_next(stream,thrd)){ -! nthrd = fetch_thread(stream, next); - if(nthrd) - set_flags_for_thread(stream, msgmap, f, nthrd, v); - } - -! if(branch = get_branch(stream, thrd)){ -! bthrd = fetch_thread(stream, branch); - if(bthrd) - set_flags_for_thread(stream, msgmap, f, bthrd, v); - } -*************** -*** 10854,10864 **** - * index. - */ - void -! collapse_or_expand(state, stream, msgmap, msgno) - struct pine *state; - MAILSTREAM *stream; - MSGNO_S *msgmap; - unsigned long msgno; - { - int collapsed, adjust_current = 0; - PINETHRD_S *thrd = NULL, *nthrd; ---- 11319,11330 ---- - * index. - */ - void -! collapse_or_expand(state, stream, msgmap, msgno, display) - struct pine *state; - MAILSTREAM *stream; - MSGNO_S *msgmap; - unsigned long msgno; -+ int display; - { - int collapsed, adjust_current = 0; - PINETHRD_S *thrd = NULL, *nthrd; -*************** -*** 10912,10918 **** - if(!thrd) - return; - -! collapsed = get_lflag(stream, NULL, thrd->rawno, MN_COLL) && thrd->next; - - if(collapsed){ - msgno = mn_raw2m(msgmap, thrd->rawno); ---- 11378,11384 ---- - if(!thrd) - return; - -! collapsed = this_thread_is_kolapsed(ps_global, stream, msgmap, thrd->rawno); - - if(collapsed){ - msgno = mn_raw2m(msgmap, thrd->rawno); -*************** -*** 10930,10942 **** - msgno = mn_raw2m(msgmap, thrd->rawno); - if(msgno > 0L && msgno <= mn_get_total(msgmap)){ - set_lflag(stream, msgmap, msgno, MN_COLL, 1); -! if(nthrd = fetch_thread(stream, thrd->next)) - set_thread_subtree(stream, nthrd, msgmap, 1, MN_CHID); - - clear_index_cache_ent(msgno); - } - } -! else - q_status_message(SM_ORDER, 0, 1, - "No thread to collapse or expand on this line"); - ---- 11396,11408 ---- - msgno = mn_raw2m(msgmap, thrd->rawno); - if(msgno > 0L && msgno <= mn_get_total(msgmap)){ - set_lflag(stream, msgmap, msgno, MN_COLL, 1); -! if((thrd->next) && (nthrd = fetch_thread(stream, thrd->next))) - set_thread_subtree(stream, nthrd, msgmap, 1, MN_CHID); - - clear_index_cache_ent(msgno); - } - } -! else if (display) - q_status_message(SM_ORDER, 0, 1, - "No thread to collapse or expand on this line"); - -*************** -*** 11018,11035 **** - unsigned long rawno, count = 0; - PINETHRD_S *nthrd, *bthrd; - MESSAGECACHE *mc; - - if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs) - return count; - -! if(thrd->next){ -! nthrd = fetch_thread(stream, thrd->next); - if(nthrd) - count += count_flags_in_thread(stream, nthrd, flags); - } - -! if(thrd->branch){ -! bthrd = fetch_thread(stream, thrd->branch); - if(bthrd) - count += count_flags_in_thread(stream, bthrd, flags); - } ---- 11484,11502 ---- - unsigned long rawno, count = 0; - PINETHRD_S *nthrd, *bthrd; - MESSAGECACHE *mc; -+ unsigned long next = 0L, branch = 0L; - - if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs) - return count; - -! if(next = get_next(stream, thrd)){ -! nthrd = fetch_thread(stream, next); - if(nthrd) - count += count_flags_in_thread(stream, nthrd, flags); - } - -! if(branch = get_branch(stream, thrd)){ -! bthrd = fetch_thread(stream, branch); - if(bthrd) - count += count_flags_in_thread(stream, bthrd, flags); - } -*************** -*** 11060,11079 **** - MSGNO_S *msgmap; - int flags; /* flag to count */ - { -! unsigned long rawno, count = 0; - PINETHRD_S *nthrd, *bthrd; - - if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs) - return count; - -! if(thrd->next){ -! nthrd = fetch_thread(stream, thrd->next); - if(nthrd) - count += count_lflags_in_thread(stream, nthrd, msgmap, flags); - } - -! if(thrd->branch){ -! bthrd = fetch_thread(stream, thrd->branch); - if(bthrd) - count += count_lflags_in_thread(stream, bthrd, msgmap,flags); - } ---- 11527,11546 ---- - MSGNO_S *msgmap; - int flags; /* flag to count */ - { -! unsigned long rawno, count = 0, next, branch; - PINETHRD_S *nthrd, *bthrd; - - if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs) - return count; - -! if(next = get_next(stream, thrd)){ -! nthrd = fetch_thread(stream, next); - if(nthrd) - count += count_lflags_in_thread(stream, nthrd, msgmap, flags); - } - -! if(branch = get_branch(stream, thrd)){ -! bthrd = fetch_thread(stream, branch); - if(bthrd) - count += count_lflags_in_thread(stream, bthrd, msgmap,flags); - } -*************** -*** 11095,11101 **** - MAILSTREAM *stream; - PINETHRD_S *thrd; - { -! unsigned long rawno, count = 0; - PINETHRD_S *nthrd, *bthrd; - - if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs) ---- 11562,11568 ---- - MAILSTREAM *stream; - PINETHRD_S *thrd; - { -! unsigned long rawno, count = 0, next, branch; - PINETHRD_S *nthrd, *bthrd; - - if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs) -*************** -*** 11104,11117 **** - if(get_lflag(stream, NULL, thrd->rawno, MN_HIDE) == 0) - return 1; - -! if(thrd->next){ -! nthrd = fetch_thread(stream, thrd->next); - if(nthrd && thread_has_some_visible(stream, nthrd)) - return 1; - } - -! if(thrd->branch){ -! bthrd = fetch_thread(stream, thrd->branch); - if(bthrd && thread_has_some_visible(stream, bthrd)) - return 1; - } ---- 11571,11584 ---- - if(get_lflag(stream, NULL, thrd->rawno, MN_HIDE) == 0) - return 1; - -! if(next = get_next(stream, thrd)){ -! nthrd = fetch_thread(stream, next); - if(nthrd && thread_has_some_visible(stream, nthrd)) - return 1; - } - -! if(branch = get_branch(stream, thrd)){ -! bthrd = fetch_thread(stream, branch); - if(bthrd && thread_has_some_visible(stream, bthrd)) - return 1; - } -*************** -*** 11186,11205 **** - MSGNO_S *msgmap; - { - int count = 0; - PINETHRD_S *nthrd, *bthrd; - MESSAGECACHE *mc; - - if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs) - return count; - -! if(thrd->next){ -! nthrd = fetch_thread(stream, thrd->next); - if(nthrd) - count += mark_msgs_in_thread(stream, nthrd, msgmap); - } - -! if(thrd->branch){ -! bthrd = fetch_thread(stream, thrd->branch); - if(bthrd) - count += mark_msgs_in_thread(stream, bthrd, msgmap); - } ---- 11653,11673 ---- - MSGNO_S *msgmap; - { - int count = 0; -+ long next, branch; - PINETHRD_S *nthrd, *bthrd; - MESSAGECACHE *mc; - - if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs) - return count; - -! if(next = get_next(stream, thrd)){ -! nthrd = fetch_thread(stream, next); - if(nthrd) - count += mark_msgs_in_thread(stream, nthrd, msgmap); - } - -! if(branch = get_branch(stream, thrd)){ -! bthrd = fetch_thread(stream, branch); - if(bthrd) - count += mark_msgs_in_thread(stream, bthrd, msgmap); - } -*************** -*** 11233,11239 **** - int flags; /* flags to set or clear */ - int v; /* set or clear? */ - { -! unsigned long rawno, msgno; - PINETHRD_S *nthrd, *bthrd; - - if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs) ---- 11701,11707 ---- - int flags; /* flags to set or clear */ - int v; /* set or clear? */ - { -! unsigned long rawno, msgno, next, branch; - PINETHRD_S *nthrd, *bthrd; - - if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs) -*************** -*** 11259,11272 **** - && v == 1 && get_index_cache(msgno)->line[0]) - clear_index_cache_ent(msgno); - -! if(thrd->next){ -! nthrd = fetch_thread(stream, thrd->next); - if(nthrd) - set_thread_lflags(stream, nthrd, msgmap, flags, v); - } - -! if(thrd->branch){ -! bthrd = fetch_thread(stream, thrd->branch); - if(bthrd) - set_thread_lflags(stream, bthrd, msgmap, flags, v); - } ---- 11727,11740 ---- - && v == 1 && get_index_cache(msgno)->line[0]) - clear_index_cache_ent(msgno); - -! if(next = get_next(stream, thrd)){ -! nthrd = fetch_thread(stream, next); - if(nthrd) - set_thread_lflags(stream, nthrd, msgmap, flags, v); - } - -! if(branch = get_branch(stream,thrd)){ -! bthrd = fetch_thread(stream, branch); - if(bthrd) - set_thread_lflags(stream, bthrd, msgmap, flags, v); - } -*************** -*** 11353,11371 **** - { - char to_us = ' '; - PINETHRD_S *nthrd, *bthrd; - MESSAGECACHE *mc; - - if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs) - return to_us; - -! if(thrd->next){ -! nthrd = fetch_thread(stream, thrd->next); - if(nthrd) - to_us = to_us_symbol_for_thread(stream, nthrd, consider_flagged); - } - -! if(to_us == ' ' && thrd->branch){ -! bthrd = fetch_thread(stream, thrd->branch); - if(bthrd) - to_us = to_us_symbol_for_thread(stream, bthrd, consider_flagged); - } ---- 11821,11840 ---- - { - char to_us = ' '; - PINETHRD_S *nthrd, *bthrd; -+ unsigned long next = 0L, branch = 0L; - MESSAGECACHE *mc; - - if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs) - return to_us; - -! if(next = get_next(stream,thrd)){ -! nthrd = fetch_thread(stream, next); - if(nthrd) - to_us = to_us_symbol_for_thread(stream, nthrd, consider_flagged); - } - -! if(to_us == ' ' && (branch = get_branch(stream, thrd))){ -! bthrd = fetch_thread(stream, branch); - if(bthrd) - to_us = to_us_symbol_for_thread(stream, bthrd, consider_flagged); - } -*************** -*** 11400,11406 **** - break; - } - -! if(to_us != '+' && resent_to_us(&idata)) - to_us = '+'; - - if(to_us == ' ' && F_ON(F_MARK_FOR_CC,ps_global)) ---- 11869,11875 ---- - break; - } - -! if(to_us != '+' && !idata.bogus && resent_to_us(&idata)) - to_us = '+'; - - if(to_us == ' ' && F_ON(F_MARK_FOR_CC,ps_global)) -*************** -*** 11436,11442 **** - int flags; /* flags to set or clear */ - { - int hiding; -! unsigned long rawno, msgno; - PINETHRD_S *nthrd, *bthrd; - - hiding = (flags == MN_CHID) && v; ---- 11905,11911 ---- - int flags; /* flags to set or clear */ - { - int hiding; -! unsigned long rawno, msgno, next, branch; - PINETHRD_S *nthrd, *bthrd; - - hiding = (flags == MN_CHID) && v; -*************** -*** 11448,11454 **** - - set_lflag(stream, msgmap, msgno, flags, v); - -! if(thrd->next && (hiding || !get_lflag(stream,NULL,thrd->rawno,MN_COLL))){ - nthrd = fetch_thread(stream, thrd->next); - if(nthrd) - set_thread_subtree(stream, nthrd, msgmap, v, flags); ---- 11917,11924 ---- - - set_lflag(stream, msgmap, msgno, flags, v); - -! if(thrd->next -! && (hiding || !get_lflag(stream,NULL,thrd->rawno,MN_COLL))){ - nthrd = fetch_thread(stream, thrd->next); - if(nthrd) - set_thread_subtree(stream, nthrd, msgmap, v, flags); -*************** -*** 11492,11499 **** - if(rawno) - thrd = fetch_thread(stream, rawno); - -! if(thrd && thrd->top && thrd->top != thrd->rawno) -! thrd = fetch_thread(stream, thrd->top); - - if(!thrd) - return 0; ---- 11962,11969 ---- - if(rawno) - thrd = fetch_thread(stream, rawno); - -! if(thrd && thrd->top && top_thread(stream,thrd->top) != thrd->rawno) -! thrd = fetch_thread(stream, top_thread(stream,thrd->top)); - - if(!thrd) - return 0; -*************** -*** 11509,11516 **** - set_thread_lflags(stream, thrd, msgmap, MN_CHID2, 1); - } - -! if(current_index_state) -! msgmap->top_after_thrd = current_index_state->msg_at_top; - - /* - * If this is one of those wacky users who like to sort backwards ---- 11979,11987 ---- - set_thread_lflags(stream, thrd, msgmap, MN_CHID2, 1); - } - -! /* if(current_index_state) -! msgmap->top_after_thrd = current_index_state->msg_at_top;*/ -! msgmap->top_after_thrd = mn_raw2m(msgmap, thrd->top); - - /* - * If this is one of those wacky users who like to sort backwards -*************** -*** 11563,11569 **** - thrd = fetch_thread(stream, rawno); - - if(thrd && thrd->top) -! topthrd = fetch_thread(stream, thrd->top); - - if(!topthrd) - return 0; ---- 12034,12040 ---- - thrd = fetch_thread(stream, rawno); - - if(thrd && thrd->top) -! topthrd = fetch_thread(stream, top_thread(stream,thrd->top)); - - if(!topthrd) - return 0; -*************** -*** 11700,11702 **** ---- 12171,12508 ---- - } - } - } -+ -+ unsigned long -+ get_branch(stream,thrd) -+ MAILSTREAM *stream; -+ PINETHRD_S *thrd; -+ { -+ PINETHRD_S *nthrd = NULL; -+ unsigned long top; -+ -+ if (thrd->toploose && thrd->nextthd) -+ nthrd = fetch_thread(stream, thrd->nextthd); -+ if (!nthrd) -+ return thrd->branch; -+ top = top_thread(stream, thrd->rawno); -+ return thrd->branch -+ ? thrd->branch -+ : (F_ON(F_ENHANCED_THREAD, ps_global) -+ ? (top == top_thread(stream, nthrd->rawno) ? thrd->nextthd : 0L) -+ : 0L); -+ } -+ -+ unsigned long -+ get_next(stream,thrd) -+ MAILSTREAM *stream; -+ PINETHRD_S *thrd; -+ { -+ return thrd->next; -+ } -+ -+ long -+ get_length_branch(stream, rawno) -+ MAILSTREAM *stream; -+ long rawno; -+ { -+ int branchp = 0, done = 0; -+ long top, count = 1L, raw; -+ PINETHRD_S *thrd, *pthrd = NULL, *nthrd; -+ -+ thrd = fetch_thread(stream, rawno); -+ -+ if (!thrd) -+ return -1L; -+ -+ top = thrd->top; -+ -+ if (thrd->parent) -+ pthrd = fetch_thread(stream, thrd->parent); -+ -+ if (thrd->rawno == top) -+ branchp++; -+ -+ if (!branchp && !pthrd){ /* what!!?? */ -+ raw = top; -+ while (!done){ -+ pthrd = fetch_thread(stream, raw); -+ if ((pthrd->next == rawno) || (pthrd->branch == rawno)) -+ done++; -+ else{ -+ if (pthrd->next) -+ raw = pthrd->next; -+ else if (pthrd->branch) -+ raw = pthrd->branch; -+ } -+ } -+ } -+ -+ if (pthrd && pthrd->next == thrd->rawno && thrd->branch) -+ branchp++; -+ -+ if (pthrd && pthrd->next && pthrd->next != thrd->rawno){ -+ nthrd = fetch_thread(stream, pthrd->next); -+ while (nthrd && nthrd->branch && nthrd->branch != thrd->rawno) -+ nthrd = fetch_thread(stream, nthrd->branch); -+ if(nthrd && nthrd->branch && nthrd->branch == thrd->rawno) -+ branchp++; -+ } -+ -+ if(branchp){ -+ int entry = 0; -+ while(thrd && thrd->next){ -+ entry = 1; -+ count++; -+ thrd = fetch_thread(stream, thrd->next); -+ if (thrd->branch) -+ break; -+ } -+ if (entry && thrd->branch) -+ count--; -+ } -+ return branchp ? (count ? count : 1L) : 0L; -+ } -+ -+ void -+ find_msgmap(stream, msgmap, flags, ordersort, is_rev) -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ int flags; -+ SortOrder ordersort; -+ unsigned is_rev; -+ { -+ int we_cancel; -+ long *old_arrival,*new_arrival; -+ long init_thread, end_thread, current; -+ long k = 1L, j, last_thread = 0L; -+ long i, tmsg, ntmsg, nthreads; -+ int nflags = (SRT_VRB | SRT_MAN); -+ char sort_msg[MAX_SCREEN_COLS+1] = {'\0'}; -+ PINETHRD_S *thrd, *tthrd, *nthrd; -+ -+ erase_thread_info = 0; -+ current = mn_m2raw(msgmap, mn_get_cur(msgmap)); -+ -+ /* now sort by arrival */ -+ sort_folder(stream, msgmap, ordersort, 0, nflags, 0); -+ -+ tmsg = mn_get_total(msgmap) + 1; -+ -+ if (tmsg <= 1) -+ return; -+ -+ old_arrival = (long *) fs_get(tmsg * sizeof(long)); -+ memset(old_arrival, 0, tmsg*sizeof(long)); -+ for (i= 1L;(i <= mn_get_total(msgmap)) && (old_arrival[i] = msgmap->sort[i]); i++); -+ -+ /* now sort by thread */ -+ sort_folder(stream, msgmap, SortThread, 0, nflags, 0); -+ ntmsg = mn_get_total(msgmap) + 1; -+ -+ if (tmsg != ntmsg){ /* oh oh, something happened,we better try again */ -+ fs_give((void **)&old_arrival); -+ find_msgmap(stream, msgmap, flags, ordersort, is_rev); -+ return; -+ } -+ -+ /* reconstruct the msgmap */ -+ -+ new_arrival = (long *) fs_get(tmsg * sizeof(long)); -+ memset(new_arrival, 0, tmsg*sizeof(long)); -+ i = mn_get_total(msgmap); -+ while (new_arrival[1] == 0){ /* think of this as (tmsg > 0) */ -+ int done = 0; -+ long n = mn_get_total(msgmap); -+ -+ init_thread = top_thread(stream, old_arrival[i]); -+ thrd = fetch_thread(stream, init_thread); -+ while ((new_arrival[n] != 0) && !done){ /* compare raw numbers */ -+ done = (new_arrival[n] == init_thread); -+ n--; -+ } -+ if (!done){ -+ k = 1L; -+ mn_set_cur(msgmap, mn_raw2m(msgmap, init_thread)); -+ if (move_next_thread(ps_global, stream, msgmap, 0) <= 0) -+ j = mn_get_total(msgmap) - mn_raw2m(msgmap, init_thread) + 1; -+ else -+ j = mn_get_cur(msgmap) - mn_raw2m(msgmap, init_thread); -+ end_thread = mn_raw2m(msgmap, init_thread) + j; -+ while (k <= j){ -+ new_arrival[tmsg - k] = msgmap->sort[end_thread - k]; -+ k++; -+ } -+ tmsg -= j; -+ } -+ i--; -+ } -+ relink_threads(stream, msgmap, new_arrival); -+ for (i = 1; (i <= mn_get_total(msgmap)) -+ && (msgmap->sort[i] = new_arrival[i]); i++); -+ msgno_reset_isort(msgmap); -+ -+ fs_give((void **)&new_arrival); -+ fs_give((void **)&old_arrival); -+ -+ -+ if(is_rev && (mn_get_total(msgmap) > 1L)){ -+ long *rev_sort; -+ long i = 1L, l = mn_get_total(msgmap); -+ -+ rev_sort = (long *) fs_get((mn_get_total(msgmap)+1L) * sizeof(long)); -+ memset(rev_sort, 0, (mn_get_total(msgmap)+1L)*sizeof(long)); -+ while (l > 0L){ -+ if (top_thread(stream, msgmap->sort[l]) == msgmap->sort[l]){ -+ long init_thread = msgmap->sort[l]; -+ long j, k; -+ -+ mn_set_cur(msgmap, mn_raw2m(msgmap, init_thread)); -+ if (move_next_thread(ps_global, stream, msgmap, 0) <= 0) -+ j = mn_get_total(msgmap) - mn_raw2m(msgmap, init_thread) + 1; -+ else -+ j = mn_get_cur(msgmap) - mn_raw2m(msgmap, init_thread); -+ for (k = 0L; (k < j) && (rev_sort[i+k] = msgmap->sort[l+k]); k++); -+ i += j; -+ } -+ l--; -+ } -+ relink_threads(stream, msgmap, rev_sort); -+ for (i = 1L; i <= mn_get_total(msgmap); i++) -+ msgmap->sort[i] = rev_sort[i]; -+ msgno_reset_isort(msgmap); -+ fs_give((void **)&rev_sort); -+ } -+ mn_reset_cur(msgmap, first_sorted_flagged(is_rev ? F_NONE : F_SRCHBACK, -+ stream, mn_raw2m(msgmap, current), FSF_SKIP_CHID)); -+ msgmap->top = -1L; -+ -+ sp_set_unsorted_newmail(ps_global->mail_stream, 0); -+ -+ for(i = 1L; i <= ps_global->mail_stream->nmsgs; i++) -+ mail_elt(ps_global->mail_stream, i)->spare7 = 0; -+ -+ mn_set_sort(msgmap, SortThread); -+ mn_set_revsort(msgmap, is_rev); -+ erase_thread_info = 1; -+ clear_index_cache(); -+ } -+ -+ void -+ move_thread(state, stream, msgmap, direction) -+ struct pine *state; -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ int direction; -+ { -+ long new_cursor, old_cursor = mn_get_cur(msgmap); -+ int rv; -+ PINETHRD_S *thrd; -+ -+ rv = direction > 0 ? move_next_thread(state, stream, msgmap, 1): -+ move_prev_thread(state, stream, msgmap, 1); -+ if (rv > 0 && THRD_INDX_ENABLED()){ -+ new_cursor = mn_get_cur(msgmap); -+ mn_set_cur(msgmap, old_cursor); -+ unview_thread(state, stream, msgmap); -+ thrd = fetch_thread(stream,mn_m2raw(msgmap, new_cursor)); -+ mn_set_cur(msgmap, new_cursor); -+ view_thread(state, stream, msgmap, 1); -+ state->next_screen = SCREEN_FUN_NULL; -+ } -+ } -+ -+ void -+ relink_threads(stream, msgmap, new_arrival) -+ MAILSTREAM *stream; -+ MSGNO_S *msgmap; -+ long *new_arrival; -+ { -+ long last_thread = 0L; -+ long i = 0L, j = 1L, k; -+ PINETHRD_S *thrd, *nthrd; -+ -+ while (j <= mn_get_total(msgmap)){ -+ i++; -+ thrd = fetch_thread(stream, new_arrival[j]); -+ if (!thrd) /* sort failed!, better leave from here now!!! */ -+ break; -+ thrd->prevthd = last_thread; -+ thrd->thrdno = i; -+ thrd->head = new_arrival[1]; -+ last_thread = thrd->rawno; -+ mn_set_cur(msgmap, mn_raw2m(msgmap,thrd->top)); -+ k = mn_get_cur(msgmap); -+ if (move_next_thread(ps_global, stream, msgmap, 0) <= 0) -+ j += mn_get_total(msgmap) + 1 - k; -+ else -+ j += mn_get_cur(msgmap) - k; -+ if (!thrd->toploose) -+ thrd->nextthd = (j <= mn_get_total(msgmap)) ? new_arrival[j] : 0L; -+ else{ -+ int done = 0; -+ while(thrd->nextthd && !done){ -+ thrd->thrdno = i; -+ thrd->head = new_arrival[1]; -+ if (thrd->nextthd) -+ nthrd = fetch_thread(stream, thrd->nextthd); -+ else -+ done++; -+ if(top_thread(stream, thrd->rawno) == top_thread(stream, nthrd->rawno)) -+ thrd = nthrd; -+ else -+ done++; -+ } -+ thrd->nextthd = (j <= mn_get_total(msgmap)) ? new_arrival[j] : 0L; -+ last_thread = thrd->rawno; -+ } -+ } -+ } -+ -+ -+ int -+ find_index_rule() -+ { -+ int found = 0; -+ RULE_RESULT *rule; -+ INDEXDATA_S idata; -+ ENVELOPE *local_env; -+ -+ memset(&idata, 0, sizeof(INDEXDATA_S)); -+ idata.stream = ps_global->mail_stream; -+ local_env = (ENVELOPE *)make_envelope(&idata, 0); -+ rule = get_result_rule(V_INDEX_RULES, FOR_RULE | FOR_INDEX, local_env); -+ if (local_env) -+ mail_free_envelope(&local_env); -+ if (rule){ -+ init_index_format(rule->result, &ps_global->index_disp_format); -+ found = 1; -+ if (rule->result) -+ fs_give((void **)&rule->result); -+ fs_give((void **)&rule); -+ } -+ return found; -+ } -+ -+ void -+ setup_threading_display_style() -+ { -+ RULE_RESULT *rule; -+ NAMEVAL_S *v; -+ int i; -+ -+ rule = get_result_rule(V_THREAD_DISP_STYLE_RULES, -+ FOR_RULE | FOR_THREAD, (ENVELOPE *) NULL); -+ if (rule || ps_global->VAR_THREAD_DISP_STYLE){ -+ for(i = 0; v = thread_disp_styles(i); i++) -+ if(!strucmp(rule ? rule->result : ps_global->VAR_THREAD_DISP_STYLE, -+ rule ? (v ? v->name : "" ) : S_OR_L(v))){ -+ ps_global->thread_disp_style = v->value; -+ break; -+ } -+ if (rule){ -+ if (rule->result) -+ fs_give((void **)&rule->result); -+ fs_give((void **)&rule); -+ } -+ } -+ } -diff -rc pine4.63/pine/mailpart.c pine4.63.I.USE/pine/mailpart.c -*** pine4.63/pine/mailpart.c Wed Apr 27 11:55:01 2005 ---- pine4.63.I.USE/pine/mailpart.c Thu May 19 19:57:32 2005 -*************** -*** 815,822 **** ---- 815,828 ---- - /*--- get string ---*/ - {int rc, found = 0; - char *result = NULL, buf[64]; -+ static char last_pat[64] = {'\0'}; - static char last[64], tmp[64]; - HelpType help; -+ static ESCKEY_S ekey[] = { -+ {0, 0, "", ""}, -+ {ctrl('N'), 9, "^N", "Ins Pat"}, -+ {-1, 0, NULL, NULL}}; -+ - - ps->mangled_footer = 1; - buf[0] = '\0'; -*************** -*** 829,846 **** - int flags = OE_APPEND_CURRENT | OE_SEQ_SENSITIVE; - - rc = optionally_enter(buf,-FOOTER_ROWS(ps),0,sizeof(buf), -! tmp,NULL,help,&flags); - if(rc == 3) - help = help == NO_HELP ? h_attach_index_whereis : NO_HELP; -! else if(rc == 0 || rc == 1 || !buf[0]){ - if(rc == 0 && !buf[0] && last[0]) - strcpy(buf, last); -! -! break; - } - } - - if(rc == 0 && buf[0]){ - ctmp = current; - while(ctmp = next_attline(ctmp)) - if(srchstr(ctmp->dstring, buf)){ ---- 835,857 ---- - int flags = OE_APPEND_CURRENT | OE_SEQ_SENSITIVE; - - rc = optionally_enter(buf,-FOOTER_ROWS(ps),0,sizeof(buf), -! tmp,ekey,help,&flags); - if(rc == 3) - help = help == NO_HELP ? h_attach_index_whereis : NO_HELP; -! else if(rc == 0 || rc == 1 || rc == 9 || !buf[0]){ - if(rc == 0 && !buf[0] && last[0]) - strcpy(buf, last); -! if (rc == 9) -! insert_pattern_in_string(buf, last_pat, 63); -! else -! break; - } - } - - if(rc == 0 && buf[0]){ -+ strncpy(last_pat, buf, sizeof(last_pat)); -+ last_pat[sizeof(last_pat)-1] = '\0'; -+ - ctmp = current; - while(ctmp = next_attline(ctmp)) - if(srchstr(ctmp->dstring, buf)){ -*************** -*** 3463,3469 **** - /* - * For consistency, the first question is always "include text?" - */ -! if((include_text = reply_text_query(ps_global, 1, &prefix)) >= 0 - && reply_news_test(a->body->nested.msg->env, outgoing) > 0 - && reply_harvest(ps_global, msgno, a->number, - a->body->nested.msg->env, &saved_from, ---- 3474,3480 ---- - /* - * For consistency, the first question is always "include text?" - */ -! if((include_text = reply_text_query(ps_global, 1, NULL, &prefix)) >= 0 - && reply_news_test(a->body->nested.msg->env, outgoing) > 0 - && reply_harvest(ps_global, msgno, a->number, - a->body->nested.msg->env, &saved_from, -diff -rc pine4.63/pine/mailview.c pine4.63.I.USE/pine/mailview.c -*** pine4.63/pine/mailview.c Wed Apr 27 11:55:02 2005 ---- pine4.63.I.USE/pine/mailview.c Thu May 19 19:57:34 2005 -*************** -*** 75,80 **** ---- 75,89 ---- - int len; - } SCRLFILE_S; - -+ #include <regex.h> -+ -+ #define REGERROR 128 -+ -+ typedef struct IVAL { -+ int start; -+ int end; -+ struct IVAL *next; -+ } IVAL_S; - - /* - * Struct to help write lines do display as they're decoded -*************** -*** 152,157 **** ---- 161,167 ---- - #define SS_CUR 2 - #define SS_FREE 3 - -+ static ACTION_S *role_chosen = NULL; - - /* - * Def's to help page reframing based on handles -*************** -*** 235,246 **** - HOMEKEY_MENU, - ENDKEY_MENU, - RCOMPOSE_MENU, -! NULL_MENU, -! NULL_MENU, -! NULL_MENU, -! NULL_MENU, -! NULL_MENU, -! NULL_MENU, - NULL_MENU}; - INST_KEY_MENU(view_keymenu, view_keys); - #define VIEW_ATT_KEY 3 ---- 245,256 ---- - HOMEKEY_MENU, - ENDKEY_MENU, - RCOMPOSE_MENU, -! {"(","Prev Threa",{MC_PRETHREAD,1,{'('}},KS_NONE}, -! {")","Next Threa",{MC_NEXTHREAD,1,{')'}},KS_NONE}, -! {"^D","Delete Thr",{MC_DELTHREAD,1,{ctrl('D')}},KS_NONE}, -! {"^U","Undel Thre",{MC_UNDTHREAD,1,{ctrl('U')}},KS_NONE}, -! {"^T","selcT Thre",{MC_SELTHREAD,1,{ctrl('T')}},KS_NONE}, -! {"^H","ChkIncFl",{MC_FORCECHECK,1,{ctrl('H')}},KS_NONE}, - NULL_MENU}; - INST_KEY_MENU(view_keymenu, view_keys); - #define VIEW_ATT_KEY 3 -*************** -*** 268,274 **** - {"S", "Save", {MC_SAVETEXT,1,{'s'}}, KS_SAVE}}; - INST_KEY_MENU(simple_text_keymenu, simple_text_keys); - -! - - - /* ---- 278,289 ---- - {"S", "Save", {MC_SAVETEXT,1,{'s'}}, KS_SAVE}}; - INST_KEY_MENU(simple_text_keymenu, simple_text_keys); - -! static char *prefix; -! #define NO_FLOWED 0x0000 -! #define IS_FLOWED 0x0001 -! #define DELETEQUO 0x0010 -! #define COLORAQUO 0x0100 -! #define RAWSTRING 0x1000 - - - /* -*************** -*** 362,367 **** ---- 377,392 ---- - void embed_color PROTO((COLOR_PAIR *, gf_io_t)); - int color_a_quote PROTO((long, char *, LT_INS_S **, void *)); - int color_signature PROTO((long, char *, LT_INS_S **, void *)); -+ IVAL_S *copy_ival PROTO((IVAL_S *)); -+ IVAL_S * compute_interval PROTO((char *, char *, int)); -+ void remove_spaces_ival PROTO((IVAL_S **, char *)); -+ void interval_free PROTO((IVAL_S **)); -+ char * regex_pattern PROTO((char **)); -+ LT_INS_S ** insert_color_special_text PROTO((LT_INS_S **, char **, IVAL_S *, -+ int, COLOR_PAIR *)); -+ int any_color_in_string PROTO((char *)); -+ int length_color PROTO((char *, int)); -+ int color_this_text PROTO((long, char *, LT_INS_S **, void *)); - int color_headers PROTO((long, char *, LT_INS_S **, void *)); - int url_hilite_hdr PROTO((long, char *, LT_INS_S **, void *)); - int url_launch PROTO((HANDLE_S *)); -*************** -*** 386,391 **** ---- 411,418 ---- - int pcpine_resize_scroll PROTO((void)); - int pcpine_view_cursor PROTO((int, long)); - #endif -+ int is_word PROTO((char [], int, int)); -+ int is_mailbox PROTO((char [], int, int)); - - - -*************** -*** 420,425 **** ---- 447,453 ---- - HANDLE_S *handles = NULL; - SCROLL_S scrollargs; - SourceType src = CharStar; -+ FOLDER_S *f = NULL; - - dprint(1, (debugfile, "\n\n ----- MAIL VIEW -----\n")); - -*************** -*** 473,478 **** ---- 501,517 ---- - else - ps->unseen_in_view = !mc->seen; - -+ prefix = reply_quote_str(env); -+ /* Make sure the prefix is not only made of spaces, so that we do not -+ * paint the screen incorrectly -+ */ -+ if (prefix && *prefix){ -+ int i; -+ for (i = 0; isspace((unsigned char) prefix[i]); i++); -+ if (i == strlen(prefix)) -+ fs_give((void **)&prefix); -+ } -+ - #if defined(DOS) && !defined(WIN32) - /* - * Handle big text for DOS here. -*************** -*** 634,639 **** ---- 673,680 ---- - } - while(ps->next_screen == SCREEN_FUN_NULL); - -+ if (prefix && *prefix) -+ fs_give((void **)&prefix); - if(we_cancel) - cancel_busy_alarm(-1); - -*************** -*** 1590,1595 **** ---- 1631,1644 ---- - if((flgs & FM_DISPLAY) - && !(flgs & FM_NOCOLOR) - && pico_usingcolor() -+ && ps_global->VAR_SPECIAL_TEXT_FORE_COLOR -+ && ps_global->VAR_SPECIAL_TEXT_BACK_COLOR){ -+ gf_link_filter(gf_line_test, gf_line_test_opt(color_this_text, NULL)); -+ } -+ -+ if((flgs & FM_DISPLAY) -+ && !(flgs & FM_NOCOLOR) -+ && pico_usingcolor() - && ps_global->VAR_SIGNATURE_FORE_COLOR - && ps_global->VAR_SIGNATURE_BACK_COLOR){ - gf_link_filter(gf_line_test, gf_line_test_opt(color_signature, &is_in_sig)); -*************** -*** 1600,1607 **** - && pico_usingcolor() - && ps_global->VAR_QUOTE1_FORE_COLOR - && ps_global->VAR_QUOTE1_BACK_COLOR){ -! gf_link_filter(gf_line_test, gf_line_test_opt(color_a_quote, NULL)); - } - - wrapflags = (flgs & FM_DISPLAY) ? GFW_HANDLES : 0; - if(flgs & FM_DISPLAY ---- 1649,1658 ---- - && pico_usingcolor() - && ps_global->VAR_QUOTE1_FORE_COLOR - && ps_global->VAR_QUOTE1_BACK_COLOR){ -! gf_link_filter(gf_quote_test,gf_line_test_opt(color_a_quote, NULL)); - } -+ else -+ gf_link_filter(gf_quote_test,gf_line_test_opt(select_quote, NULL)); - - wrapflags = (flgs & FM_DISPLAY) ? GFW_HANDLES : 0; - if(flgs & FM_DISPLAY -*************** -*** 2691,2696 **** ---- 2742,2749 ---- - {0, 'a', "A", "editApp"}, - {-1, 0, NULL, NULL}}; - -+ if (role_chosen) -+ free_action(&role_chosen); - if(handle->type == URL){ - launch_opts[4].ch = 'u'; - -*************** -*** 2801,2811 **** - * sense if you just say View selected URL ... - */ - if(handle->type == URL && -! !struncmp(handle->h.url.path, "mailto:", 7)) -! sprintf(prompt, "Compose mail to \"%.*s%s\" ? ", -! min(max(0,sc - 25), sizeof(prompt)-50), handle->h.url.path+7, -! (strlen(handle->h.url.path+7) > max(0,sc-25)) ? "..." : ""); -! else - sprintf(prompt, "View selected %s %s%.*s%s ? ", - (handle->type == URL) ? "URL" : "Attachment", - (handle->type == URL) ? "\"" : "", ---- 2854,2894 ---- - * sense if you just say View selected URL ... - */ - if(handle->type == URL && -! !struncmp(handle->h.url.path, "mailto:", 7)){ -! int rolenick = role_chosen ? strlen(role_chosen->nick) : 0; -! int offset = 25 + (role_chosen ? 20 : 0); -! int offset2 = max(0, sc - offset) - strlen(handle->h.url.path+7); -! int offset3 = sc - strlen(handle->h.url.path+7) - rolenick - offset; -! int laddress = min(max(0,sc - offset), sizeof(prompt)-50); -! int lrole = rolenick; -! -! if (offset3 < 0){ -! lrole = rolenick; -! laddress = sc - offset - lrole; -! offset3 = laddress - 20; /* redefine offset3 */ -! if (offset3 < 0){ -! laddress = 20; -! lrole = sc - offset - laddress; -! } -! } -! launch_opts[2].ch = 'r'; -! launch_opts[2].rval = 'r'; -! launch_opts[2].name = "R"; -! launch_opts[2].label = "Set Role"; -! sprintf(prompt, "Compose mail to \"%.*s%s\" %s%.*s%s%s? ", -! laddress, handle->h.url.path+7, -! offset2 < 0 ? "..." : "", -! role_chosen ? "using role \"" : "", -! role_chosen ? lrole : 0, -! role_chosen ? role_chosen->nick : "", -! role_chosen ? (rolenick > lrole ? "..." : "") : "", -! role_chosen ? "\" " : ""); -! } -! else{ -! launch_opts[2].ch = -2; -! launch_opts[2].rval = 0; -! launch_opts[2].name = NULL; -! launch_opts[2].label = NULL; - sprintf(prompt, "View selected %s %s%.*s%s ? ", - (handle->type == URL) ? "URL" : "Attachment", - (handle->type == URL) ? "\"" : "", -*************** -*** 2814,2825 **** ---- 2897,2931 ---- - (handle->type == URL) - ? ((strlen(handle->h.url.path) > max(0,sc-27)) - ? "...\"" : "\"") : ""); -+ } - - switch(radio_buttons(prompt, -FOOTER_ROWS(ps_global), - launch_opts, 'y', 'n', NO_HELP, RB_SEQ_SENSITIVE)){ - case 'y' : - return(1); - -+ case 'r': -+ { -+ void (*prev_screen)() = ps_global->prev_screen, -+ (*redraw)() = ps_global->redrawer; -+ ps_global->redrawer = NULL; -+ ps_global->next_screen = SCREEN_FUN_NULL; -+ if(role_select_screen(ps_global, &role_chosen, 1) < 0){ -+ cmd_cancelled("Compose"); -+ ps_global->next_screen = prev_screen; -+ ps_global->redrawer = redraw; -+ if(ps_global->redrawer) -+ (*ps_global->redrawer)(); -+ return 0; -+ } -+ ps_global->next_screen = prev_screen; -+ ps_global->redrawer = redraw; -+ if(role_chosen) -+ role_chosen = combine_inherited_role(role_chosen); -+ if(ps_global->redrawer) -+ (*ps_global->redrawer)(); -+ } -+ - case 'u' : - strncpy(tmp, handle->h.url.path, sizeof(tmp)-1); - tmp[sizeof(tmp)-1] = '\0'; -*************** -*** 3481,3486 **** ---- 3587,3621 ---- - return(buf); - } - -+ #define is_digit(c) ((((c) >= '0') && ((c) <= '9')) ? 1 : 0) -+ -+ #define is_letter(c) (((c) >= 'a' && (c) <= 'z') || \ -+ ((c) >= 'A' && (c) <= 'Z')) -+ -+ #define next(w,i) ((((w)[(i)]) != 0) ? ((w)[(i) + 1]) : 0) -+ -+ #define single_level(c) (((c) == '>') || ((c) == '|') || ((c) == '~') || \ -+ ((c) == ']')) -+ -+ int -+ is_word (buf, i, j) -+ char buf[NSTRING]; -+ int i; -+ int j; -+ { -+ return i <= j && is_letter(buf[i]) ? -+ (i < j ? is_word(buf,i+1,j) : 1) : 0; -+ } -+ -+ int -+ is_mailbox(buf,i,j) -+ char buf[NSTRING]; -+ int i; -+ int j; -+ { -+ return i <= j && (is_letter(buf[i]) || is_digit(buf[i]) || buf[i] == '.') -+ ? (i < j ? is_mailbox(buf,i+1,j) : 1) : 0; -+ } - - int - colorcmp(color1, color2) -*************** -*** 3503,3508 **** ---- 3638,3710 ---- - struct quote_colors *next; - }; - -+ -+ int -+ next_level_quote(buf, line, i, is_flowed) -+ char *buf; -+ char **line; -+ int i; -+ int is_flowed; -+ { -+ int j; -+ -+ if (!single_level(buf[i])){ -+ if(is_mailbox(buf,i,i)){ -+ for (j = i; buf[j] && !isspace(buf[j]); j++); -+ if (is_word(buf,i,j-1) || is_mailbox(buf,i,j-1)) -+ j += isspace(buf[j]) ? 2 : 1; -+ } -+ else{ -+ switch(buf[i]){ -+ case ':' : -+ if (next(buf,i) != RPAREN) -+ j = i + 1; -+ else -+ j = i + 2; -+ break; -+ -+ case '-' : -+ if (next(buf,i) != '-') -+ j = i + 2; -+ else -+ j = i + 3; -+ break; -+ -+ case '+' : -+ case '*' : -+ if (next(buf,i) != ' ') -+ j = i + 2; -+ else -+ j = i + 3; -+ break; -+ -+ default : -+ for (j = i; buf[j] && !isspace(buf[j]) -+ && (!single_level(buf[i]) && !is_letter(buf[j])); j++); -+ j += isspace(buf[j]) ? 1 : 0; -+ break; -+ } -+ } -+ if (line && *line) -+ (*line) += j - i; -+ } -+ else{ -+ j = i+1; -+ if (line && *line) -+ (*line)++; -+ } -+ if(!is_flowed){ -+ if(line && *line) -+ for(; isspace((unsigned char)*(*line)); (*line)++); -+ for (i = j; isspace((unsigned char) buf[i]); i++); -+ } -+ else i = j; -+ if (is_flowed && i != j) -+ buf[i] = '\0'; -+ return i; -+ } -+ -+ - int - color_a_quote(linenum, line, ins, is_flowed_msg) - long linenum; -*************** -*** 3510,3528 **** - LT_INS_S **ins; - void *is_flowed_msg; - { -! int countem = 0; - struct variable *vars = ps_global->vars; - char *p; - struct quote_colors *colors = NULL, *cp, *next; - COLOR_PAIR *col = NULL; - int is_flowed = is_flowed_msg ? *((int *)is_flowed_msg) : 0; - - p = line; -! if(!is_flowed) -! while(isspace((unsigned char)*p)) -! p++; - -! if(p[0] == '>'){ - struct quote_colors *c; - - /* ---- 3712,3736 ---- - LT_INS_S **ins; - void *is_flowed_msg; - { -! int countem = 0, i, j = 0; - struct variable *vars = ps_global->vars; - char *p; -+ char buf[NSTRING] = {'\0'}; - struct quote_colors *colors = NULL, *cp, *next; - COLOR_PAIR *col = NULL; -+ int code; - int is_flowed = is_flowed_msg ? *((int *)is_flowed_msg) : 0; - -+ code = (is_flowed ? IS_FLOWED : NO_FLOWED) | COLORAQUO; -+ select_quote(linenum, line, ins, (void *)code); -+ for (i = 0; tmp_20k_buf[i] && (buf[i] = tmp_20k_buf[i]); i++); -+ buf[i] = '\0'; -+ - p = line; -! for(i = 0; isspace((unsigned char)buf[i]); i++) -! p++; /*(i = is_flowed ? (buf[j] ? j : 0): j);*/ - -! if(buf[i]){ - struct quote_colors *c; - - /* -*************** -*** 3571,3577 **** - free_color_pair(&col); - - cp = NULL; -! while(*p == '>'){ - cp = (cp && cp->next) ? cp->next : colors; - - if(countem > 0) ---- 3779,3785 ---- - free_color_pair(&col); - - cp = NULL; -! while(buf[i]){ - cp = (cp && cp->next) ? cp->next : colors; - - if(countem > 0) -*************** -*** 3581,3590 **** - - countem = (countem == 1) ? 0 : countem; - -! p++; -! if(!is_flowed) -! for(; isspace((unsigned char)*p); p++) -! ; - } - - if(colors){ ---- 3789,3797 ---- - - countem = (countem == 1) ? 0 : countem; - -! i = next_level_quote(buf, &p, i, is_flowed); -! for (; isspace((unsigned char)*p); p++); -! for (; isspace((unsigned char)buf[i]); i++); - } - - if(colors){ -*************** -*** 3648,3653 **** ---- 3855,3919 ---- - return(0); - } - -+ /* This filter gives a quote string of a line. It sends its reply back to the -+ calling filter in the tmp_20k_buf variable. This filter replies with -+ the full quote string including tailing spaces if any. It is the -+ responsibility of the calling filter to figure out if thos spaces are -+ useful for that filter or if they should be removed before doing any -+ useful work. For example, color_a_quote does not require the trailing -+ spaces, but gf_wrap does. -+ */ -+ int -+ select_quote(linenum, line, ins, code) -+ long linenum; -+ char *line; -+ LT_INS_S **ins; -+ void *code; -+ { -+ int i; -+ char buf[NSTRING] = {'\0'}; -+ char GLine[NSTRING] = {'\0'}; -+ char PLine[NSTRING] = {'\0'}; -+ char NLine[NSTRING] = {'\0'}; -+ static char GLine1[NSTRING] = {'\0'}; -+ static char PLine1[NSTRING] = {'\0'}; -+ static char GLine2[NSTRING] = {'\0'}; -+ static char PLine2[NSTRING] = {'\0'}; -+ QSTRING_S *qs; -+ int buflen = NSTRING < SIZEOF_20KBUF ? NSTRING - 1: SIZEOF_20KBUF - 1; -+ int who = ((int) code) & COLORAQUO; /* may I ask who is calling? */ -+ int raw = ((int) code) & RAWSTRING; /* return raw string */ -+ -+ strncpy(GLine, who ? GLine1 : GLine2, buflen); -+ strncpy(PLine, who ? PLine1 : PLine2, buflen); -+ -+ if (linenum != 0) -+ strncpy(PLine, GLine, buflen); -+ -+ strncpy(NLine, tmp_20k_buf, buflen); -+ -+ if (line) -+ strncpy(GLine, line, buflen); -+ else -+ GLine[0] = '\0'; -+ -+ qs = do_quote_match(prefix && *prefix ? prefix : ">", -+ GLine, NLine, PLine, raw); -+ flatten_qstring(qs, buf); -+ free_qs(&qs); -+ /* do not paint an extra level for a line with a >From string at the -+ * begining of it -+ */ -+ if (buf[0]){ -+ i = strlen(buf); -+ if (strlen(line) >= i + 6 && !strncmp(line+i-1,">From ", 6)) -+ buf[i - 1] = '\0'; -+ } -+ strncpy(tmp_20k_buf, buf, buflen); -+ strncpy((who ? GLine1 : GLine2), GLine, buflen); -+ strncpy((who ? PLine1 : PLine2), PLine, buflen); -+ return -1; -+ } - - /* - * Paint the signature. -*************** -*** 3660,3686 **** - void *is_in_sig; - { - struct variable *vars = ps_global->vars; -! int *in_sig_block; - COLOR_PAIR *col = NULL; - - if(is_in_sig == NULL) - return 0; - - in_sig_block = (int *) is_in_sig; -! -! if(!strcmp(line, SIGDASHES)) -! *in_sig_block = START_SIG_BLOCK; -! else if(*line == '\0') - /* - * Suggested by Eduardo: allow for a blank line right after - * the sigdashes. - */ - *in_sig_block = (*in_sig_block == START_SIG_BLOCK) - ? IN_SIG_BLOCK : OUT_SIG_BLOCK; - else -! *in_sig_block = (*in_sig_block != OUT_SIG_BLOCK) - ? IN_SIG_BLOCK : OUT_SIG_BLOCK; - - if(*in_sig_block != OUT_SIG_BLOCK - && VAR_SIGNATURE_FORE_COLOR && VAR_SIGNATURE_BACK_COLOR - && (col = new_color_pair(VAR_SIGNATURE_FORE_COLOR, ---- 3926,4005 ---- - void *is_in_sig; - { - struct variable *vars = ps_global->vars; -! int *in_sig_block, i, j,same_qstr = 0; - COLOR_PAIR *col = NULL; -+ static char GLine[NSTRING] = {'\0'}; -+ static char PLine[NSTRING] = {'\0'}; -+ char NLine[NSTRING] = {'\0'}; -+ static char *buf, buf2[NSTRING] = {'\0'}; -+ QSTRING_S *qs; -+ static qstrlen = 0; - - if(is_in_sig == NULL) - return 0; - -+ if (linenum != 0){ -+ for (i = 0; GLine[i] && (PLine[i] = GLine[i]); i++); -+ PLine[i] = '\0'; -+ } -+ -+ for (i = 0; tmp_20k_buf[i] && (tmp_20k_buf[i] != '\015') && (i < NSTRING) -+ && (i < SIZEOF_20KBUF) -+ && (NLine[i] = tmp_20k_buf[i]); i++); -+ NLine[i] = '\0'; -+ -+ for (i = 0; (i < NSTRING) && ((GLine[i] = line[i]) != 0); i++); -+ GLine[NSTRING - 1] = '\0'; -+ qs = do_quote_match(prefix && *prefix ? prefix : ">", -+ GLine, NLine, PLine, 1); -+ flatten_qstring(qs, buf2); -+ i = buf2 && buf2[0] ? strlen(buf2) : 0; -+ free_qs(&qs); -+ -+ /* determine if buf and buf2 are the same quote string */ -+ if (!struncmp(buf, buf2, qstrlen)){ -+ for (j = qstrlen; buf2[j] && isspace((unsigned char)buf2[j]); j++); -+ if (!buf2[j] || buf2[j] == '|' || (buf2[j] == '*' && buf2[j+1] != '>')) -+ same_qstr++; -+ } -+ - in_sig_block = (int *) is_in_sig; -! -! if (*in_sig_block != OUT_SIG_BLOCK){ -! if (line && *line && (strlen(line) >= qstrlen) && same_qstr) -! line += qstrlen; -! else if (strlen(line) < qstrlen) -! line += i; -! else if (!same_qstr) -! *in_sig_block = OUT_SIG_BLOCK; -! } -! else -! line += i; -! -! if(!strcmp(line, SIGDASHES) || !strcmp(line, "--")){ -! *in_sig_block = START_SIG_BLOCK; -! buf = (char *) fs_get((i + 1)*sizeof(char)); -! buf = cpystr(buf2); -! qstrlen = i; -! } -! else if(*line == '\0'){ - /* - * Suggested by Eduardo: allow for a blank line right after - * the sigdashes. - */ - *in_sig_block = (*in_sig_block == START_SIG_BLOCK) - ? IN_SIG_BLOCK : OUT_SIG_BLOCK; -+ } - else -! *in_sig_block = (*in_sig_block != OUT_SIG_BLOCK) - ? IN_SIG_BLOCK : OUT_SIG_BLOCK; - -+ if (*in_sig_block == OUT_SIG_BLOCK){ -+ qstrlen = 0; /* reset back in case there's another paragraph */ -+ if (buf) -+ fs_give((void **)&buf); -+ } -+ - if(*in_sig_block != OUT_SIG_BLOCK - && VAR_SIGNATURE_FORE_COLOR && VAR_SIGNATURE_BACK_COLOR - && (col = new_color_pair(VAR_SIGNATURE_FORE_COLOR, -*************** -*** 3751,3756 **** ---- 4070,4316 ---- - return 0; - } - -+ IVAL_S * -+ copy_ival(ival) -+ IVAL_S *ival; -+ { -+ IVAL_S *cp; -+ -+ if (!ival) -+ return (IVAL_S *)NULL; -+ -+ cp = (IVAL_S *) malloc (sizeof(IVAL_S)); -+ memset (cp, 0, sizeof(IVAL_S)); -+ -+ cp->start = ival->start; -+ cp->end = ival->end; -+ cp->next = copy_ival(ival->next); -+ return cp; -+ } -+ -+ void -+ interval_free(ival) -+ IVAL_S **ival; -+ { -+ if (!(*ival)) -+ return; -+ -+ if ((*ival)->next) -+ interval_free(&((*ival)->next)); -+ -+ (*ival)->next = (IVAL_S *) NULL; -+ -+ free((void *)(*ival)); -+ *ival = (IVAL_S *) NULL; -+ } -+ -+ IVAL_S * -+ compute_interval (string, pattern, endm) -+ char *string; -+ char *pattern; -+ int endm; -+ { -+ IVAL_S *ival = NULL, *nextival= NULL; -+ int error, sizerror; -+ regex_t preg; -+ regmatch_t pmatch; -+ -+ if (error = regcomp(&preg, pattern, REG_EXTENDED)){ -+ /* char message[REGERROR]; -+ sizerror = regerror(error, &preg, message, REGERROR); -+ printf("%s\n", message);*/ -+ regfree(&preg); -+ return (IVAL_S *) NULL; -+ } -+ else{ -+ if (((error = regexec(&preg, string, 1, &pmatch, 0)) != REG_NOMATCH) -+ && !error){ -+ ival = (IVAL_S *) malloc(sizeof(IVAL_S)); -+ memset (ival, 0, sizeof(IVAL_S)); -+ ival->start = endm + pmatch.rm_so; -+ ival->end = endm + pmatch.rm_eo; -+ nextival = compute_interval(string+pmatch.rm_so+1, pattern, ival->start+1); -+ if (nextival){ -+ if (nextival->start <= ival->end){ -+ ival->end = nextival->end; -+ ival->next = copy_ival(nextival->next); -+ interval_free(&nextival); -+ } -+ else -+ ival->next = nextival; -+ } -+ } -+ } -+ regfree(&preg); -+ return ival; -+ } -+ -+ char * -+ regex_pattern(plist) -+ char **plist; -+ { -+ int i = 0, j = 0, k = 0, n = 0, len = 0; -+ char *pattern = NULL; -+ -+ if(plist && plist[0] && plist[0][0]){ -+ for (i = 0; plist[i] && plist[i][0]; i++) -+ len += strlen(plist[i]) + 1; -+ pattern = (char *) fs_get(len * sizeof(char)); -+ for (j = 0; j < i; j++){ -+ for(k = 0; plist[j][k]; k++) -+ pattern[n++] = plist[j][k]; -+ pattern[n++] = (j == i - 1) ? '\0' : '|'; -+ } -+ } -+ return pattern; -+ } -+ -+ LT_INS_S ** -+ insert_color_special_text(ins, p, ival, last_end, col) -+ LT_INS_S **ins; -+ char **p; -+ IVAL_S *ival; -+ int last_end; -+ COLOR_PAIR *col; -+ { -+ struct variable *vars = ps_global->vars; -+ -+ if (ival){ -+ *p += ival->start - last_end; -+ ins = gf_line_test_new_ins(ins, *p, color_embed(col->fg, col->bg), -+ (2 * RGBLEN) + 4); -+ *p += ival->end - ival->start; -+ ins = gf_line_test_new_ins(ins, *p, color_embed(VAR_NORM_FORE_COLOR, -+ VAR_NORM_BACK_COLOR), (2 * RGBLEN) + 4); -+ ins = insert_color_special_text(ins, p, ival->next, ival->end, col); -+ } -+ return ins; -+ } -+ -+ int -+ length_color(p, begin_color) -+ char *p; -+ int begin_color; -+ { -+ int len = 0, done = begin_color ? 0 : -1; -+ char *orig = p; -+ -+ while (*p && done <= 0){ -+ switch(*p++){ -+ case TAG_HANDLE : -+ p += *p + 1; -+ done++; -+ break; -+ -+ case TAG_FGCOLOR : -+ case TAG_BGCOLOR : -+ p += RGBLEN; -+ if (!begin_color) -+ done++; -+ break; -+ -+ default : -+ break; -+ } -+ } -+ len = p - orig; -+ return len; -+ } -+ -+ int -+ any_color_in_string(p) -+ char *p; -+ { -+ int rv = 0; -+ char *orig = p; -+ while (*p && !rv) -+ if (*p++ == TAG_EMBED) -+ rv = p - orig; -+ return rv; -+ } -+ -+ void -+ remove_spaces_ival(ivalp, p) -+ IVAL_S **ivalp; -+ char *p; -+ { -+ IVAL_S *ival; -+ int i; -+ if (!ivalp || !*ivalp) -+ return; -+ ival = *ivalp; -+ for (i = 0; isspace((unsigned char) p[ival->start + i]); i++); -+ if (ival->start + i < ival->end) /* do not do this if match only spaces */ -+ ival->start += i; -+ else -+ return; -+ for (i = 0; isspace((unsigned char) p[ival->end - i - 1]); i++); -+ ival->end -= i; -+ if (ival->next) -+ remove_spaces_ival(&(ival->next), p); -+ } -+ -+ int -+ color_this_text(linenum, line, ins, local) -+ long linenum; -+ char *line; -+ LT_INS_S **ins; -+ void *local; -+ { -+ struct variable *vars = ps_global->vars; -+ COLOR_PAIR *col = NULL; -+ char *p; -+ int i; -+ static char *pattern = NULL; -+ -+ select_quote(linenum, line, ins, NULL); -+ p = line + strlen(tmp_20k_buf); -+ -+ if(VAR_SPECIAL_TEXT_FORE_COLOR && VAR_SPECIAL_TEXT_BACK_COLOR -+ && (col = new_color_pair(VAR_SPECIAL_TEXT_FORE_COLOR, -+ VAR_SPECIAL_TEXT_BACK_COLOR)) -+ && !pico_is_good_colorpair(col)) -+ free_color_pair(&col); -+ -+ if (linenum == 0){ -+ if (pattern) -+ fs_give((void **)&pattern); -+ pattern = regex_pattern(ps_global->VAR_SPECIAL_TEXT); -+ } -+ -+ if(pattern && col){ -+ IVAL_S *ival; -+ int done = 0, begin_color = 0; -+ -+ while (!done){ -+ if (i = any_color_in_string(p)){ -+ begin_color = (begin_color + 1) % 2; -+ if (begin_color){ -+ p[i - 1] = '\0'; -+ ival = compute_interval(p, pattern, 0); -+ remove_spaces_ival(&ival, p); -+ p[i - 1] = TAG_EMBED; -+ ins = insert_color_special_text(ins, &p, ival, 0, col); -+ } -+ for (;*p++ != TAG_EMBED; ); -+ p += length_color(p, begin_color); -+ } -+ else{ -+ ival = compute_interval(p, pattern, 0); -+ remove_spaces_ival(&ival, p); -+ ins = insert_color_special_text(ins, &p, ival, 0, col); -+ done++; -+ } -+ interval_free(&ival); -+ if (!*p) -+ done++; -+ } -+ free_color_pair(&col); -+ } -+ -+ return 0; -+ } -+ - - /* - * Replace quotes of nonflowed messages. This needs to happen -*************** -*** 3843,3849 **** - { - DELQ_S *dq; - char *lp; -! int i, lines, not_a_quote = 0; - size_t len; - - dq = (DELQ_S *) local; ---- 4403,4409 ---- - { - DELQ_S *dq; - char *lp; -! int i, lines, not_a_quote = 0, code, feedback; - size_t len; - - dq = (DELQ_S *) local; -*************** -*** 3853,3858 **** ---- 4413,4419 ---- - if(dq->lines > 0 || dq->lines == Q_DEL_ALL){ - - lines = (dq->lines == Q_DEL_ALL) ? 0 : dq->lines; -+ feedback = (dq->lines == Q_DEL_ALL) ? 0 : 1; - - /* - * First determine if this line is part of a quote. -*************** -*** 3863,3868 **** ---- 4424,4432 ---- - for(i = dq->indent_length; i > 0 && !not_a_quote && *lp; i--) - if(*lp++ != SPACE) - not_a_quote++; -+ -+ while(isspace((unsigned char) *lp)) -+ lp++; - - /* skip over leading tags */ - while(!not_a_quote -*************** -*** 3902,3918 **** - } - } - -! /* skip over whitespace */ -! if(!dq->is_flowed) -! while(isspace((unsigned char) *lp)) -! lp++; -! -! /* check first character to see if it is a quote */ -! if(!not_a_quote && *lp != '>') -! not_a_quote++; - - if(not_a_quote){ -! if(dq->in_quote > lines+1){ - char tmp[500]; - - /* ---- 4466,4481 ---- - } - } - -! code = (dq->is_flowed ? IS_FLOWED : NO_FLOWED) | DELETEQUO; -! len = lp - line; -! if(strlen(tmp_20k_buf) > len) -! strcpy(tmp_20k_buf, tmp_20k_buf+len); -! select_quote(linenum, lp, ins, (void *) code); -! if (!not_a_quote && !tmp_20k_buf[0]) -! not_a_quote++; - - if(not_a_quote){ -! if(dq->in_quote > lines+1 && feedback){ - char tmp[500]; - - /* -*************** -*** 5017,5023 **** - fs_give((void **) &urlp); - - rflags = ROLE_COMPOSE; -! if(nonempty_patterns(rflags, &dummy)){ - role = set_role_from_msg(ps_global, rflags, -1L, NULL); - if(confirm_role(rflags, &role)) - role = combine_inherited_role(role); ---- 5580,5586 ---- - fs_give((void **) &urlp); - - rflags = ROLE_COMPOSE; -! if(!(role = copy_action(role_chosen)) && nonempty_patterns(rflags, &dummy)){ - role = set_role_from_msg(ps_global, rflags, -1L, NULL); - if(confirm_role(rflags, &role)) - role = combine_inherited_role(role); -*************** -*** 5093,5098 **** ---- 5656,5662 ---- - - free_redraft_pos(&redraft_pos); - free_action(&role); -+ free_action(&role_chosen); - - return(rv); - } -*************** -*** 5665,5671 **** - char *err, *charset; - int filtcnt = 0, error_found = 0, column, wrapit; - int is_in_sig = OUT_SIG_BLOCK; -! int is_flowed_msg = 0; - int is_delsp_yes = 0; - int filt_only_c0 = 0; - char *parmval; ---- 6229,6235 ---- - char *err, *charset; - int filtcnt = 0, error_found = 0, column, wrapit; - int is_in_sig = OUT_SIG_BLOCK; -! int is_flowed_msg = 0, add_me = 1; - int is_delsp_yes = 0; - int filt_only_c0 = 0; - char *parmval; -*************** -*** 5767,5772 **** ---- 6331,6345 ---- - filters[filtcnt++].data = gf_line_test_opt(url_hilite, handlesp); - } - -+ if((flags & FM_DISPLAY) -+ && !(flags & FM_NOCOLOR) -+ && pico_usingcolor() -+ && VAR_SPECIAL_TEXT_FORE_COLOR -+ && VAR_SPECIAL_TEXT_BACK_COLOR){ -+ filters[filtcnt].filter = gf_line_test; -+ filters[filtcnt++].data = gf_line_test_opt(color_this_text, NULL); -+ } -+ - /* - * First, paint the signature. - * Disclaimers noted below for coloring quotes apply here as well. -*************** -*** 5794,5802 **** - && pico_usingcolor() - && VAR_QUOTE1_FORE_COLOR - && VAR_QUOTE1_BACK_COLOR){ -! filters[filtcnt].filter = gf_line_test; -! filters[filtcnt++].data = gf_line_test_opt(color_a_quote, -! &is_flowed_msg); - } - } - else if(!strucmp(att->body->subtype, "richtext")){ ---- 6367,6375 ---- - && pico_usingcolor() - && VAR_QUOTE1_FORE_COLOR - && VAR_QUOTE1_BACK_COLOR){ -! add_me = 0; -! filters[filtcnt].filter = gf_quote_test; -! filters[filtcnt++].data = gf_line_test_opt(color_a_quote, &is_flowed_msg); - } - } - else if(!strucmp(att->body->subtype, "richtext")){ -*************** -*** 5866,5871 **** ---- 6439,6450 ---- - } - } - -+ if (add_me){ -+ filters[filtcnt].filter = gf_quote_test; -+ filters[filtcnt++].data = gf_line_test_opt(select_quote, -+ (void *) RAWSTRING); -+ } -+ - if(wrapit && !(flags & FM_NOWRAP)){ - int margin = 0, wrapflags = (flags & FM_DISPLAY) ? GFW_HANDLES : 0; - -*************** -*** 5913,5919 **** - dq.saved_line = &free_this; - dq.handlesp = handlesp; - -! filters[filtcnt].filter = gf_line_test; - filters[filtcnt++].data = gf_line_test_opt(delete_quotes, &dq); - } - ---- 6492,6498 ---- - dq.saved_line = &free_this; - dq.handlesp = handlesp; - -! filters[filtcnt].filter = gf_quote_test; - filters[filtcnt++].data = gf_line_test_opt(delete_quotes, &dq); - } - -*************** -*** 6453,6460 **** - format_addr_string(s, n, sect, "Return-Path: ", e->return_path, - flags, pc); - -! if((which & FE_NEWSGROUPS) && e->newsgroups) - format_newsgroup_string("Newsgroups: ", e->newsgroups, flags, pc); - - if((which & FE_FOLLOWUPTO) && e->followup_to) - format_newsgroup_string("Followup-To: ", e->followup_to, flags, pc); ---- 7032,7051 ---- - format_addr_string(s, n, sect, "Return-Path: ", e->return_path, - flags, pc); - -! if((which & FE_NEWSGROUPS) && e->newsgroups){ -! int bogus = NIL; - format_newsgroup_string("Newsgroups: ", e->newsgroups, flags, pc); -+ if (!e->ngpathexists && e->message_id && -+ strncmp (e->message_id,"<Pine.",6) && -+ strncmp (e->message_id,"<MS-C.",6) && -+ strncmp (e->message_id,"<MailManager.",13) && -+ strncmp (e->message_id,"<EasyMail.",11) && -+ strncmp (e->message_id,"<ML-",4)) bogus = T; -+ -+ if(bogus) -+ q_status_message(SM_ORDER, 0, 3, -+ "Unverified Newsgroup header -- Message MAY or MAY NOT have been posted"); -+ } - - if((which & FE_FOLLOWUPTO) && e->followup_to) - format_newsgroup_string("Followup-To: ", e->followup_to, flags, pc); -*************** -*** 7189,7196 **** - { - register long cur_top_line, num_display_lines; - int result, done, ch, cmd, found_on, found_on_col, -! first_view, force, scroll_lines, km_size, -! cursor_row, cursor_col, km_popped; - long jn; - struct key_menu *km; - HANDLE_S *next_handle; ---- 7780,7787 ---- - { - register long cur_top_line, num_display_lines; - int result, done, ch, cmd, found_on, found_on_col, -! first_view, force, scroll_lines, km_size, skip = 0, -! cursor_row, cursor_col, km_popped, nm; - long jn; - struct key_menu *km; - HANDLE_S *next_handle; -*************** -*** 7397,7403 **** - - /*============ Check for New Mail and CheckPoint ============*/ - if(!sparms->quell_newmail && -! new_mail(force, NM_TIMING(ch), NM_STATUS_MSG) >= 0){ - update_scroll_titlebar(cur_top_line, 1); - if(ps_global->mangled_footer) - draw_keymenu(km, bitmap, ps_global->ttyo->screen_cols, ---- 7988,7996 ---- - - /*============ Check for New Mail and CheckPoint ============*/ - if(!sparms->quell_newmail && -! (nm = new_mail(force, NM_TIMING(ch), NM_STATUS_MSG)) >= 0){ -! skip = 0; -! ps_global->force_check_now = nm > 0 ? 1 : 0; - update_scroll_titlebar(cur_top_line, 1); - if(ps_global->mangled_footer) - draw_keymenu(km, bitmap, ps_global->ttyo->screen_cols, -*************** -*** 7405,7410 **** ---- 7998,8015 ---- - - ps_global->mangled_footer = 0; - } -+ ps_global->in_pico = 0; -+ -+ if (!skip) -+ new_mail_incfolder(ps_global, MC_IFAUTOCHECK); -+ skip = 0; -+ if (ps_global->refresh_list > 0){ -+ ps_global->refresh_list = 0; -+ if (ps_global->in_fld_list){ -+ cmd = MC_RESIZE; -+ goto end; -+ } -+ } - - /* - * If an expunge of the current message happened during the -*************** -*** 7539,7544 **** ---- 8144,8150 ---- - break; - } - -+ ps_global->force_check_now = (((cmd == MC_NONE) || (cmd == MC_FORCECHECK)) ? 1 : 0); - - /*============= Execute command =======================*/ - switch(cmd){ -*************** -*** 8251,8256 **** ---- 8857,8908 ---- - print_to_printer(sparms); - break; - -+ case MC_NEXTHREAD: -+ case MC_PRETHREAD: -+ if (THREADING()){ -+ if (any_messages(ps_global->msgmap, NULL, -+ "to move to other thread")) -+ move_thread(ps_global, ps_global->mail_stream, ps_global->msgmap, -+ cmd == MC_NEXTHREAD ? 1 : -1); -+ done = 1; -+ } -+ else -+ q_status_message(SM_ORDER, 0, 1, -+ "Command available in threaded mode only"); -+ break; -+ -+ case MC_DELTHREAD: -+ if (THREADING()){ -+ if (any_messages(ps_global->msgmap, NULL, "to delete")) -+ cmd_delete_thread(ps_global, ps_global->mail_stream, ps_global->msgmap); -+ done = 1; -+ } -+ else -+ q_status_message(SM_ORDER, 0, 1, -+ "Command available in threaded mode only"); -+ break; -+ -+ case MC_UNDTHREAD: -+ if (THREADING()){ -+ if (any_messages(ps_global->msgmap, NULL, "to undelete")) -+ cmd_undelete_thread(ps_global, ps_global->mail_stream, ps_global->msgmap); -+ done = 1; -+ } -+ else -+ q_status_message(SM_ORDER, 0, 1, -+ "Command available in threaded mode only"); -+ break; -+ -+ case MC_SELTHREAD: -+ if (THREADING()){ -+ if (any_messages(ps_global->msgmap, NULL, "to undelete")) -+ cmd_select_thread(ps_global, ps_global->mail_stream, ps_global->msgmap); -+ done = 1; -+ } -+ else -+ q_status_message(SM_ORDER, 0, 1, -+ "Command available in threaded mode only"); -+ break; - - /* ------- First handle on Line ------ */ - case MC_GOTOBOL : -*************** -*** 8283,8289 **** ---- 8935,8957 ---- - - break; - -+ /*------- Check incoming folders -------*/ -+ case MC_FORCECHECK: -+ ps_global->force_check_now = 1; -+ if (new_mail_incfolder(ps_global,MC_FORCECHECK) && -+ ps_global->refresh_list > 0){ -+ ps_global->refresh_list = 0; -+ if (ps_global->in_fld_list){ -+ cmd = MC_RESIZE; -+ goto end; -+ } -+ } -+ break; - -+ case MC_TAB: -+ skip++; -+ /* do not check for new mail in inc fldrs and fall through */ -+ - /*------- Standard commands ------*/ - default: - whereis_pos.row = 0; -*************** -*** 8355,8360 **** ---- 9023,9029 ---- - - } /* End of while() -- loop executing commands */ - -+ end: - ps_global->redrawer = NULL; /* next statement makes this invalid! */ - zero_scroll_text(); /* very important to zero out on return!!! */ - scroll_state(SS_FREE); -*************** -*** 8463,8470 **** ---- 9132,9141 ---- - char prompt[MAX_SEARCH+50], nsearch_string[MAX_SEARCH+1]; - HelpType help; - int rc, flags; -+ static char last_search_string[MAX_SEARCH+1] = { '\0' }; - static char search_string[MAX_SEARCH+1] = { '\0' }; - static ESCKEY_S word_search_key[] = { { 0, 0, "", "" }, -+ {ctrl('N'), 9, "^N", "Ins Pat"}, - {ctrl('Y'), 10, "^Y", "First Line"}, - {ctrl('V'), 11, "^V", "Last Line"}, - {-1, 0, NULL, NULL} -*************** -*** 8486,8491 **** ---- 9157,9165 ---- - help = help == NO_HELP ? h_oe_searchview : NO_HELP; - continue; - } -+ else if(rc == 9) -+ insert_pattern_in_string(nsearch_string, last_search_string, -+ MAX_SEARCH); - else if(rc == 10){ - strcpy(report, "Searched to First Line."); - return(-4); -*************** -*** 8495,8501 **** - return(-5); - } - -! if(rc != 4) - break; - } - ---- 9169,9175 ---- - return(-5); - } - -! if(rc != 4 && rc != 9) - break; - } - -*************** -*** 8507,8512 **** ---- 9181,9189 ---- - search_string[sizeof(search_string)-1] = '\0'; - } - -+ strncpy(last_search_string, nsearch_string, sizeof(last_search_string)); -+ last_search_string[sizeof(last_search_string)-1] = '\0'; -+ - rc = search_scroll_text(start_line, start_col, search_string, cursor_pos, - offset_in_line); - return(rc); -diff -rc pine4.63/pine/newmail.c pine4.63.I.USE/pine/newmail.c -*** pine4.63/pine/newmail.c Thu Jan 13 16:44:30 2005 ---- pine4.63.I.USE/pine/newmail.c Thu May 19 19:57:28 2005 -*************** -*** 48,53 **** ---- 48,55 ---- - - #include "headers.h" - -+ static long incoming_folders_new_mail = 0L; -+ - - /* - * Internal prototypes -*************** -*** 701,706 **** ---- 703,709 ---- - "subject:" - }; - -+ ps_global->refresh_list += 1; /* Force update in folder screen */ - if(stream) - e = pine_mail_fetchstructure(stream, max_num, NULL); - -*************** -*** 1095,1100 **** ---- 1098,1108 ---- - if(m && sp_flagged(m, SP_LOCKED)) - sp_set_mail_since_cmd(m, 0L); - } -+ -+ if (incoming_folders_new_mail > 0L){ -+ icon_text(NULL, IT_NEWMAIL); -+ incoming_folders_new_mail = 0L; -+ } - } - - -*************** -*** 1299,1301 **** ---- 1307,1545 ---- - } - } - #endif -+ -+ #define ADD_FLD_MSG(m, F, j) \ -+ {\ -+ strcat((m),"\"");\ -+ strcat((m),FLDR_NAME((F)));\ -+ strcat((m),"\"");\ -+ (F)->notified = 1;\ -+ if (j)\ -+ strcat((m),", ");\ -+ } -+ #define MSG(n) (((n) + 30 > SIZEOF_20KBUF) ? message : tmp_20k_buf) -+ #define CODE() ((command == MC_FORCECHECK) ? 1 : ((newflds > 0) ? -1 : 1)) -+ #define NMVAR() ((command == MC_FORCECHECK) ? nflds : \ -+ newflds > 0 ? newflds : nflds) -+ -+ /* Check for new mail in incoming folders */ -+ int -+ new_mail_incfolder(state,command) -+ struct pine *state; -+ int command; -+ { -+ char *message = NULL; -+ int index = 0, i, nflds = 0, tflds, tlflds = 0, newflds = 0, save_state; -+ static time_t now, old = 0; -+ static int check_started = 0; -+ int tcp_query_timeout = state->tcp_query_timeout; -+ int tcp_open_timeout = 30; -+ int offset = !F_OFF(F_ENABLE_FAST_RECENT, state); -+ FOLDER_S *f; -+ -+ if (F_OFF(F_ENABLE_INCOMING,ps_global) -+ || F_OFF(F_ENABLE_INCOMING_CHECK,ps_global) -+ || (state->inc_check_rule == IC_MAN -+ && command != MC_FORCECHECK) -+ || (state->inc_check_rule == IC_MAN_AUTO -+ && check_started == 0 && command != MC_FORCECHECK)) -+ return -1; -+ -+ if ((!state->force_check_now) || (state->checking_incfld)){ -+ state->force_check_now = 1; /* I'll be back, but wait a moment */ -+ return -1; -+ } -+ -+ now = time(0); -+ if ((old != 0) && (command != MC_FORCECHECK) && -+ (state->refresh_list == 0) && -+ (now - old < timeo*state->delay)) -+ return -1; -+ -+ state->checking_incfld = 1; /* point of no return */ -+ check_started = 1; /* checks have already started */ -+ ps_global->mm_log_error = 0; /* turn off display of errors */ -+ ps_global->noshow_error = 1; -+ -+ if(state->VAR_TCPOPENTIMEO) -+ (void)SVAR_TCP_OPEN(state, tcp_open_timeout, tmp_20k_buf); -+ mail_parameters(NULL, SET_OPENTIMEOUT, (void *)(long)state->incfld_timeout); -+ -+ save_state = ps_global->in_init_seq; -+ state->in_init_seq = 0; /* force output of cue during check */ -+ check_cue_display("+"); /* Show something to indicate delay */ -+ MoveCursor(state->ttyo->screen_rows -FOOTER_ROWS(state),0); -+ fflush(stdout); -+ state->tcp_query_timeout = state->incfld_timeout; -+ -+ if(state->context_current){ -+ MAILSTREAM *nxtstrm = NULL; -+ long rec, tot, fslctd; -+ int opstrm, updated; -+ CONTEXT_S *ctxt = sp_context(sp_inbox_stream()); -+ -+ /* Look for the Incoming folder collections, Normally the incoming folders -+ * collection is the first collection, but just to be sure, we back up to -+ * the beginning and go forward from there to try to find it. -+ */ -+ -+ if (!ctxt){ -+ ctxt = state->context_current; -+ while (1){ -+ if (ctxt->prev) -+ ctxt = ctxt->prev; -+ else -+ break; -+ } -+ while (1){ -+ if (ctxt->use & CNTXT_INCMNG) -+ break; -+ else -+ ctxt = ctxt->next; -+ } -+ } -+ -+ tflds = folder_total(FOLDERS(ctxt)); -+ for(index = folder_index(state->inbox_name, ctxt, FI_FOLDER) + offset; -+ index >= offset && index < tflds -+ && (f = folder_entry(index, FOLDERS(ctxt))) -+ && !f->isdir; index++){ -+ -+ rec = tot = fslctd = 0L; -+ -+ fslctd = next_folder_check(&nxtstrm, ctxt, &rec, &tot, f, &opstrm); -+ -+ if(fslctd && !strcmp(FLDR_NAME(f), state->cur_folder) -+ && !state->in_fld_list) -+ fslctd = 0L; -+ -+ updated = (rec != f->recent || tot != f->messages); -+ if ((f->recent + f->messages == 0L && updated) -+ || (((!opstrm && updated) || (!f->notified && opstrm && updated)) -+ && fslctd)) -+ state->refresh_list++; -+ -+ f->countrecent = rec > f->origrecent ? rec - f->origrecent : 0; -+ f->messages = tot; -+ f->recent = rec; -+ -+ if (!offset && f->countrecent == 0L && fslctd) -+ fslctd = 0L; -+ -+ if (fslctd){ /* this folder contains new mail */ -+ state->refresh_list += f->selected ? 0 : 1; -+ f->selected = 1; -+ if (strcmp(FLDR_NAME(f), state->inbox_name)){ -+ tlflds += strlen(FLDR_NAME(f)) + 4; -+ f->new_mail = 1; -+ if(!f->notified){ -+ newflds++; -+ f->new_mail = (command == MC_FORCECHECK) ? 1 : -1; -+ } -+ nflds++; -+ } -+ } -+ else{ -+ if (f->selected) -+ state->refresh_list += f->user_selected ? 0 : 1; -+ if (f->notified) -+ f->selected = f->user_selected ? 1 : 0; -+ f->notified = f->new_mail = 0; /* reset */ -+ } -+ } -+ -+ if(nxtstrm) -+ pine_mail_close(nxtstrm); -+ -+ state->mm_log_error = 1; /* turn display of errors back on */ -+ state->noshow_error = 0; -+ -+ if(nflds == 0){ -+ if (command == MC_FORCECHECK && state->VAR_INCOMING_FOLDERS_CHECK) -+ q_status_message(SM_ORDER, 0, 2, -+ "There are NO new messages in your Incoming Folders"); -+ } -+ else{ /* nflds > 0 */ -+ if (tlflds + 30 > SIZEOF_20KBUF) -+ message = (char *) fs_get((tlflds + 30)*sizeof(char)); -+ if(newflds > 0) -+ state->refresh_list += 1; -+ strcpy(MSG(tlflds),"New message in folder"); -+ strcat(MSG(tlflds),(NMVAR() > 1) ? "s " : " "); -+ for(i = 0, index = folder_index(state->inbox_name, ctxt, FI_FOLDER) -+ + offset; -+ index >= offset && index < tflds -+ && (f = folder_entry(index, FOLDERS(ctxt))); index++) -+ if(f->new_mail == CODE()){ -+ if(NMVAR() > 1){ -+ ADD_FLD_MSG(MSG(tlflds), f, (i < (NMVAR() - 2)) ? 1 : 0); -+ if(i == NMVAR() - 2) -+ strcat(MSG(tlflds)," and "); -+ } -+ else -+ ADD_FLD_MSG(MSG(tlflds), f, 0); -+ f->new_mail = 1; -+ if(++i == NMVAR()) -+ break; -+ } -+ if (newflds > 0 || command == MC_FORCECHECK){ -+ if(strlen(MSG(tlflds)) < state->ttyo->screen_cols - 2){ -+ if (command != MC_FORCECHECK){ -+ q_status_message(SM_ASYNC | SM_DING, 0, 60, MSG(tlflds)); -+ icon_text(MSG(tlflds), IT_NEWMAIL); -+ } -+ else -+ q_status_message(SM_ORDER, 0, 2, MSG(tlflds)); -+ } -+ else{ -+ strcpy(tmp_20k_buf, -+ "You have NEW messages in your Incoming Folders"); -+ if (command != MC_FORCECHECK){ -+ q_status_message(SM_ASYNC | SM_DING, 0, 60, tmp_20k_buf); -+ icon_text(tmp_20k_buf, IT_NEWMAIL); -+ } -+ else -+ q_status_message(SM_ORDER, 0, 2, tmp_20k_buf); -+ } -+ } -+ if (message) -+ fs_give((void **)&message); -+ } /* end of nflds > 0 */ -+ } -+ state->checking_incfld = 0; -+ check_cue_display(" "); /* Erase the "+" added before */ -+ state->in_init_seq = save_state; /* restore original value */ -+ MoveCursor(state->ttyo->screen_rows -FOOTER_ROWS(state),0); -+ incoming_folders_new_mail = nflds; -+ -+ old = time(0); -+ state->delay = time(0) - now + 1; -+ state->tcp_query_timeout = tcp_query_timeout; -+ mail_parameters(NULL, SET_OPENTIMEOUT, (void *)(long)tcp_open_timeout); -+ -+ return nflds; -+ } -+ -+ -+ char * -+ new_mail_in_open_stream(stream, rec, tot) -+ MAILSTREAM *stream; -+ long *rec; -+ long *tot; -+ { -+ long excluded; -+ -+ if((excluded = any_lflagged(sp_msgmap(stream), MN_EXLD))){ -+ *tot = stream->nmsgs - excluded; -+ if(tot) -+ *rec = count_flagged(stream, F_RECENT); -+ else -+ *rec = 0L; -+ } -+ else{ -+ *tot = stream->nmsgs; -+ *rec = sp_recent_since_visited(stream); -+ } -+ -+ return *rec ? STREAMNAME(stream) : NULL; -+ } -diff -rc pine4.63/pine/osdep/termin.gen pine4.63.I.USE/pine/osdep/termin.gen -*** pine4.63/pine/osdep/termin.gen Wed Dec 1 10:56:39 2004 ---- pine4.63.I.USE/pine/osdep/termin.gen Thu May 19 19:57:28 2005 -*************** -*** 6,11 **** ---- 6,28 ---- - int pcpine_oe_cursor PROTO((int, long)); - #endif - -+ void -+ fake_config_screen(tt) -+ struct ttyo **tt; -+ { -+ struct ttyo *ttyo; -+ -+ ttyo = (struct ttyo *)fs_get(sizeof (struct ttyo)); -+ -+ ttyo->header_rows = 2; -+ ttyo->footer_rows = 3; -+ ttyo->screen_rows = 24; -+ ttyo->screen_cols = 80; -+ -+ *tt = ttyo; -+ -+ } -+ - - /* - * Generic tty input routines -*************** -*** 227,233 **** - (escape_list && escape_list[0].ch != -1) - ? escape_list[0].label: "")); - -! if(!ps_global->ttyo) - return(pre_screen_config_opt_enter(string, field_len, prompt, - escape_list, help, flags)); - ---- 244,250 ---- - (escape_list && escape_list[0].ch != -1) - ? escape_list[0].label: "")); - -! if((!ps_global->ttyo) || (ps_global->send_immediately)) - return(pre_screen_config_opt_enter(string, field_len, prompt, - escape_list, help, flags)); - -*************** -*** 1030,1035 **** ---- 1047,1053 ---- - return(0); - - *ch = *ps_global->initial_cmds++; -+ ps_global->initial_cmds_offset++; - if(!*ps_global->initial_cmds && ps_global->free_initial_cmds){ - fs_give((void **)&(ps_global->free_initial_cmds)); - ps_global->initial_cmds = 0; -*************** -*** 1039,1045 **** - } - - if(firsttime) { -! firsttime = 0; - if(ps_global->in_init_seq) { - ps_global->in_init_seq = 0; - ps_global->save_in_init_seq = 0; ---- 1057,1063 ---- - } - - if(firsttime) { -! firsttime = ps_global->checking_incfld ? (char) 1 : 0; - if(ps_global->in_init_seq) { - ps_global->in_init_seq = 0; - ps_global->save_in_init_seq = 0; -diff -rc pine4.63/pine/osdep/termin.unx pine4.63.I.USE/pine/osdep/termin.unx -*** pine4.63/pine/osdep/termin.unx Tue Aug 3 14:46:44 2004 ---- pine4.63.I.USE/pine/osdep/termin.unx Thu May 19 19:57:27 2005 -*************** -*** 46,51 **** ---- 46,53 ---- - init_tty_driver(ps) - struct pine *ps; - { -+ if(ps->send_immediately) -+ return 0; - #ifdef MOUSE - if(F_ON(F_ENABLE_MOUSE, ps_global)) - init_mouse(); -*************** -*** 573,578 **** ---- 575,583 ---- - init_keyboard(use_fkeys) - int use_fkeys; - { -+ if (ps_global->send_immediately) -+ return; -+ - if(use_fkeys && (!strucmp(term_name,"vt102") - || !strucmp(term_name,"vt100"))) - printf("\033\133\071\071\150"); -*************** -*** 591,596 **** ---- 596,604 ---- - end_keyboard(use_fkeys) - int use_fkeys; - { -+ if(ps_global->send_immediately) -+ return; -+ - if(use_fkeys && (!strcmp(term_name, "vt102") - || !strcmp(term_name, "vt100"))){ - printf("\033\133\071\071\154"); -diff -rc pine4.63/pine/osdep/termout.unx pine4.63.I.USE/pine/osdep/termout.unx -*** pine4.63/pine/osdep/termout.unx Tue Nov 30 09:53:57 2004 ---- pine4.63.I.USE/pine/osdep/termout.unx Thu May 19 19:57:27 2005 -*************** -*** 160,165 **** ---- 160,168 ---- - void - init_screen() - { -+ if(ps_global->send_immediately) -+ return; -+ - if(_termcap_init) /* init using termcap's rule */ - tputs(_termcap_init, 1, outchar); - -*************** -*** 267,272 **** ---- 270,278 ---- - { - int footer_rows_was_one = 0; - -+ if(ps_global->send_immediately) -+ return; -+ - if(!panicking){ - - dprint(9, (debugfile, "end_screen called\n")); -*************** -*** 321,327 **** - _line = 0; /* clear leaves us at top... */ - _col = 0; - -! if(ps_global->in_init_seq) - return; - - mark_status_unknown(); ---- 327,333 ---- - _line = 0; /* clear leaves us at top... */ - _col = 0; - -! if(ps_global->in_init_seq || ps_global->send_immediately) - return; - - mark_status_unknown(); -diff -rc pine4.63/pine/other.c pine4.63.I.USE/pine/other.c -*** pine4.63/pine/other.c Fri Apr 15 15:07:11 2005 ---- pine4.63.I.USE/pine/other.c Thu May 19 19:57:32 2005 -*************** -*** 362,369 **** - char *checkbox_pretty_value PROTO((struct pine *, CONF_S *)); - char *color_pretty_value PROTO((struct pine *, CONF_S *)); - char *radio_pretty_value PROTO((struct pine *, CONF_S *)); -! char *sort_pretty_value PROTO((struct pine *, CONF_S *)); -! char *generalized_sort_pretty_value PROTO((struct pine *, CONF_S *, int)); - char *yesno_pretty_value PROTO((struct pine *, CONF_S *)); - char *sigfile_pretty_value PROTO((struct pine *, CONF_S *)); - void set_radio_pretty_vals PROTO((struct pine *, CONF_S **)); ---- 362,369 ---- - char *checkbox_pretty_value PROTO((struct pine *, CONF_S *)); - char *color_pretty_value PROTO((struct pine *, CONF_S *)); - char *radio_pretty_value PROTO((struct pine *, CONF_S *)); -! char *sort_pretty_value PROTO((struct pine *, CONF_S *, int)); -! char *generalized_sort_pretty_value PROTO((struct pine *, CONF_S *, int, int)); - char *yesno_pretty_value PROTO((struct pine *, CONF_S *)); - char *sigfile_pretty_value PROTO((struct pine *, CONF_S *)); - void set_radio_pretty_vals PROTO((struct pine *, CONF_S **)); -*************** -*** 1608,1614 **** - if(lv < (j = strlen(sort_name(ps->sort_types[i])))) - lv = j; - -! decode_sort(pval, &def_sort, &def_sort_rev); - - for(j = 0; j < 2; j++){ - for(i = 0; ps->sort_types[i] != EndofList; i++){ ---- 1608,1614 ---- - if(lv < (j = strlen(sort_name(ps->sort_types[i])))) - lv = j; - -! decode_sort(pval, &def_sort, &def_sort_rev, 0); - - for(j = 0; j < 2; j++){ - for(i = 0; ps->sort_types[i] != EndofList; i++){ -*************** -*** 1623,1628 **** ---- 1623,1678 ---- - } - } - } -+ else if(vtmp == &ps->vars[V_THREAD_SORT_KEY]){ /* radio case */ -+ SortOrder thread_def_sort; -+ int thread_def_sort_rev; -+ -+ ctmpa->flags |= CF_NOSELECT; -+ ctmpa->keymenu = &config_radiobutton_keymenu; -+ ctmpa->tool = NULL; -+ -+ /* put a nice delimiter before list */ -+ new_confline(&ctmpa)->var = NULL; -+ ctmpa->varnamep = ctmpb; -+ ctmpa->keymenu = &config_radiobutton_keymenu; -+ ctmpa->help = NO_HELP; -+ ctmpa->tool = radiobutton_tool; -+ ctmpa->valoffset = 12; -+ ctmpa->flags |= CF_NOSELECT; -+ ctmpa->value = cpystr("Set Thread Sort Options"); -+ -+ new_confline(&ctmpa)->var = NULL; -+ ctmpa->varnamep = ctmpb; -+ ctmpa->keymenu = &config_radiobutton_keymenu; -+ ctmpa->help = NO_HELP; -+ ctmpa->tool = radiobutton_tool; -+ ctmpa->valoffset = 12; -+ ctmpa->flags |= CF_NOSELECT; -+ ctmpa->value = cpystr("--- ----------------------"); -+ -+ /* find longest value's name */ -+ for(lv = 0, i = 0; ps->sort_types[i] != EndofList; i++) -+ if(lv < (j = strlen(sort_name(ps->sort_types[i])))) -+ lv = j; -+ -+ decode_sort(pval, &thread_def_sort, &thread_def_sort_rev, 1); -+ -+ for(j = 0; j < 2; j++){ -+ for(i = 0; ps->sort_types[i] != EndofList; i++){ -+ if (ps->sort_types[i] == SortArrival -+ || ps->sort_types[i] == SortThread){ -+ new_confline(&ctmpa)->var = vtmp; -+ ctmpa->varnamep = ctmpb; -+ ctmpa->keymenu = &config_radiobutton_keymenu; -+ ctmpa->help = config_help(vtmp - ps->vars, 0); -+ ctmpa->tool = radiobutton_tool; -+ ctmpa->valoffset = 12; -+ ctmpa->varmem = i + (j * EndofList); -+ ctmpa->value = pretty_value(ps, ctmpa); -+ } -+ } -+ } -+ } - else if(vtmp == &ps->vars[V_USE_ONLY_DOMAIN_NAME]){ /* yesno case */ - ctmpa->keymenu = &config_yesno_keymenu; - ctmpa->tool = yesno_tool; -*************** -*** 1674,1679 **** ---- 1724,1730 ---- - || vtmp == &ps->vars[V_TCPREADWARNTIMEO] - || vtmp == &ps->vars[V_TCPWRITEWARNTIMEO] - || vtmp == &ps->vars[V_TCPQUERYTIMEO] -+ || vtmp == &ps->vars[V_INCFLDTIMEO] - || vtmp == &ps->vars[V_RSHOPENTIMEO] - || vtmp == &ps->vars[V_SSHOPENTIMEO] - || vtmp == &ps->vars[V_USERINPUTTIMEO] -*************** -*** 1779,1784 **** ---- 1830,1844 ---- - } - } - -+ pval = PVAL(&ps->vars[V_THREAD_SORT_KEY], ew); -+ if(vsave[V_THREAD_SORT_KEY].saved_user_val.p && pval -+ && strcmp(vsave[V_THREAD_SORT_KEY].saved_user_val.p, pval)){ -+ if(!mn_get_mansort(ps_global->msgmap)){ -+ clear_index_cache(); -+ reset_sort_order(SRT_VRB); -+ } -+ } -+ - treat_color_vars_as_text = 0; - free_saved_config(ps, &vsave, expose_hidden_config); - #ifdef _WINDOWS -*************** -*** 1799,1804 **** ---- 1859,1865 ---- - v == &ps->vars[V_FCC_RULE] || - v == &ps->vars[V_GOTO_DEFAULT_RULE] || - v == &ps->vars[V_INCOMING_STARTUP] || -+ v == &ps->vars[V_INCOMING_RULE] || - v == &ps->vars[V_PRUNING_RULE] || - v == &ps->vars[V_REOPEN_RULE] || - v == &ps->vars[V_THREAD_DISP_STYLE] || -*************** -*** 1828,1833 **** ---- 1889,1896 ---- - rulefunc = goto_rules; - else if(v == &ps->vars[V_INCOMING_STARTUP]) - rulefunc = incoming_startup_rules; -+ else if(v == &ps->vars[V_INCOMING_RULE]) -+ rulefunc = incoming_check_rules; - else if(v == startup_ptr) - rulefunc = startup_rules; - else if(v == &ps->vars[V_PRUNING_RULE]) -*************** -*** 1933,1939 **** - CONF_S *ctmp; - - if(!(cl && *cl && -! ((*cl)->var == &ps->vars[V_SORT_KEY] || - standard_radio_var(ps, (*cl)->var) || - (*cl)->var == startup_ptr))) - return; ---- 1996,2003 ---- - CONF_S *ctmp; - - if(!(cl && *cl && -! (((*cl)->var == &ps->vars[V_SORT_KEY]) || -! ((*cl)->var == &ps->vars[V_THREAD_SORT_KEY]) || - standard_radio_var(ps, (*cl)->var) || - (*cl)->var == startup_ptr))) - return; -*************** -*** 1999,2004 **** ---- 2063,2069 ---- - case V_TCPREADWARNTIMEO : - case V_TCPWRITEWARNTIMEO : - case V_TCPQUERYTIMEO : -+ case V_INCFLDTIMEO : - case V_RSHCMD : - case V_RSHPATH : - case V_RSHOPENTIMEO : -*************** -*** 6460,6466 **** - int multicol; - { - char tmp[MAXPATH+1]; -! int cmd, i, j, ch = 'x', done = 0, changes = 0; - int retval = 0; - int km_popped = 0, stay_in_col = 0; - struct key_menu *km = NULL; ---- 6525,6531 ---- - int multicol; - { - char tmp[MAXPATH+1]; -! int cmd, i, j, k = 1, ch = 'x', done = 0, changes = 0; - int retval = 0; - int km_popped = 0, stay_in_col = 0; - struct key_menu *km = NULL; -*************** -*** 6507,6512 **** ---- 6572,6578 ---- - } - - /*----------- Check for new mail -----------*/ -+ if (!ps->send_immediately){ - if(new_mail(0, NM_TIMING(ch), NM_STATUS_MSG | NM_DEFER_SORT) >= 0) - ps->mangled_header = 1; - -*************** -*** 6536,6541 **** ---- 6602,6608 ---- - mark_status_unknown(); - } - -+ } /* send_immediately */ - if(ps->mangled_footer || km != screen->current->keymenu){ - bitmap_t bitmap; - -*************** -*** 6607,6612 **** ---- 6674,6680 ---- - } - } - -+ if(!ps_global->send_immediately){ - MoveCursor(cursor_pos.row, cursor_pos.col); - #ifdef MOUSE - mouse_in_content(KEY_MOUSE, -1, -1, 0, 0); /* prime the handler */ -*************** -*** 6625,6630 **** ---- 6693,6706 ---- - #ifdef _WINDOWS - mswin_setscrollcallback(NULL); - #endif -+ } /* send_immediately */ -+ -+ if (ps->send_immediately){ -+ ps_global->dont_use_init_cmds = 0; -+ process_config_input(&ch); -+ if (ch == '\030') /* ^X, bye */ -+ goto end; -+ } - - cmd = menu_command(ch, km); - -*************** -*** 7046,7055 **** ---- 7122,7133 ---- - #define FOUND_NOSELECT 0x08 - #define FOUND_ABOVE 0x10 - char *result = NULL, buf[64]; -+ static char last_pat[64] = {'\0'}; - static char last[64]; - HelpType help; - static ESCKEY_S ekey[] = { - {0, 0, "", ""}, -+ {ctrl('N'), 9, "^N", "Ins Pat"}, - {ctrl('Y'), 10, "^Y", "Top"}, - {ctrl('V'), 11, "^V", "Bottom"}, - {-1, 0, NULL, NULL}}; -*************** -*** 7068,7080 **** - tmp,ekey,help,&flags); - if(rc == 3) - help = help == NO_HELP ? h_config_whereis : NO_HELP; -! else if(rc == 0 || rc == 1 || rc == 10 || rc == 11 || !buf[0]){ - if(rc == 0 && !buf[0] && last[0]) - strncpy(buf, last, 64); - -! break; - } - } - - screen->current->flags &= ~CF_VAR2; - if(rc == 0 && buf[0]){ ---- 7146,7167 ---- - tmp,ekey,help,&flags); - if(rc == 3) - help = help == NO_HELP ? h_config_whereis : NO_HELP; -! else if(rc == 0 || rc == 1 || rc == 9 || rc == 10 -! || rc == 11 || !buf[0]){ - if(rc == 0 && !buf[0] && last[0]) - strncpy(buf, last, 64); - -! if(rc == 9) -! insert_pattern_in_string(buf, last_pat, 63); -! else -! break; - } - } -+ -+ if (buf[0] != '\0'){ -+ strncpy(last_pat, buf, sizeof(last_pat)); -+ last_pat[sizeof(buf) - 1] = '\0'; -+ } - - screen->current->flags &= ~CF_VAR2; - if(rc == 0 && buf[0]){ -*************** -*** 7286,7292 **** - break; - } - } -! - screen->current = first_confline(screen->current); - free_conflines(&screen->current); - return(retval); ---- 7373,7379 ---- - break; - } - } -! end: - screen->current = first_confline(screen->current); - free_conflines(&screen->current); - return(retval); -*************** -*** 7429,7434 **** ---- 7516,7523 ---- - return(h_config_nntp_server); - case V_INBOX_PATH : - return(h_config_inbox_path); -+ case V_INCOMING_FOLDERS_CHECK : -+ return(h_config_check_inc_fld); - case V_PRUNED_FOLDERS : - return(h_config_pruned_folders); - case V_DEFAULT_FCC : -*************** -*** 7467,7476 **** ---- 7556,7593 ---- - return(h_config_fcc_rule); - case V_SORT_KEY : - return(h_config_sort_key); -+ case V_THREAD_SORT_KEY : -+ return(h_config_thread_sort_key); - case V_AB_SORT_RULE : - return(h_config_ab_sort_rule); - case V_FLD_SORT_RULE : - return(h_config_fld_sort_rule); -+ case V_THREAD_DISP_STYLE_RULES: -+ return(h_config_thread_display_style_rule); -+ case V_THREAD_INDEX_STYLE_RULES: -+ return(h_config_thread_index_style_rule); -+ case V_COMPOSE_RULES: -+ return(h_config_compose_rules); -+ case V_FORWARD_RULES: -+ return(h_config_forward_rules); -+ case V_INDEX_RULES: -+ return(h_config_index_rules); -+ case V_REPLACE_RULES: -+ return(h_config_replace_rules); -+ case V_REPLY_INDENT_RULES: -+ return(h_config_reply_indent_rules); -+ case V_REPLY_LEADIN_RULES: -+ return(h_config_reply_leadin_rules); -+ case V_RESUB_RULES: -+ return(h_config_resub_rules); -+ case V_SAVE_RULES: -+ return(h_config_save_rules); -+ case V_SMTP_RULES: -+ return(h_config_smtp_rules); -+ case V_SORT_RULES: -+ return(h_config_sort_rules); -+ case V_STARTUP_RULES: -+ return(h_config_startup_rules); - case V_CHAR_SET : - return(h_config_char_set); - case V_EDITOR : -*************** -*** 7503,7508 **** ---- 7620,7627 ---- - return(h_config_scroll_margin); - case V_DEADLETS : - return(h_config_deadlets); -+ case V_SPECIAL_TEXT : -+ return(h_config_special_text_to_color); - case V_FILLCOL : - return(h_config_composer_wrap_column); - case V_TCPOPENTIMEO : -*************** -*** 7513,7518 **** ---- 7632,7639 ---- - return(h_config_tcp_writewarn_timeo); - case V_TCPQUERYTIMEO : - return(h_config_tcp_query_timeo); -+ case V_INCFLDTIMEO : -+ return(h_config_inc_fld_timeo); - case V_RSHOPENTIMEO : - return(h_config_rsh_open_timeo); - case V_SSHOPENTIMEO : -*************** -*** 7595,7600 **** ---- 7716,7723 ---- - return(h_config_goto_default); - case V_INCOMING_STARTUP: - return(h_config_inc_startup); -+ case V_INCOMING_RULE: -+ return(h_config_inc_rule); - case V_PRUNING_RULE: - return(h_config_pruning_rule); - case V_REOPEN_RULE: -*************** -*** 7621,7626 **** ---- 7744,7751 ---- - return(h_config_newmailwidth); - case V_NEWSRC_PATH : - return(h_config_newsrc_path); -+ case V_MAILDIR_LOCATION : -+ return(h_config_maildir_location); - case V_BROWSER : - return(h_config_browser); - #if defined(DOS) || defined(OS2) -*************** -*** 7652,7657 **** ---- 7777,7785 ---- - case V_SIGNATURE_FORE_COLOR : - case V_SIGNATURE_BACK_COLOR : - return(h_config_signature_color); -+ case V_SPECIAL_TEXT_FORE_COLOR : -+ case V_SPECIAL_TEXT_BACK_COLOR : -+ return(h_config_special_text_color); - case V_PROMPT_FORE_COLOR : - case V_PROMPT_BACK_COLOR : - return(h_config_prompt_color); -*************** -*** 8045,8050 **** ---- 8173,8182 ---- - lowrange = 5; - hirange = 1000; - } -+ else if((*cl)->var == &ps->vars[V_INCFLDTIMEO]){ -+ lowrange = 2; -+ hirange = 60; -+ } - else if((*cl)->var == &ps->vars[V_TCPWRITEWARNTIMEO] || - (*cl)->var == &ps->vars[V_RSHOPENTIMEO] || - (*cl)->var == &ps->vars[V_SSHOPENTIMEO] || -*************** -*** 9371,9377 **** - } - - set_current_val((*cl)->var, TRUE, TRUE); -! if(decode_sort(ps->VAR_SORT_KEY, &def_sort, &def_sort_rev) != -1){ - ps->def_sort = def_sort; - ps->def_sort_rev = def_sort_rev; - } ---- 9503,9509 ---- - } - - set_current_val((*cl)->var, TRUE, TRUE); -! if(decode_sort(ps->VAR_SORT_KEY, &def_sort, &def_sort_rev,0) != -1){ - ps->def_sort = def_sort; - ps->def_sort_rev = def_sort_rev; - } -*************** -*** 9380,9385 **** ---- 9512,9548 ---- - ps->mangled_body = 1; /* BUG: redraw it all for now? */ - rv = 1; - } -+ else if((*cl)->var == &ps->vars[V_THREAD_SORT_KEY]){ -+ SortOrder thread_def_sort; -+ int thread_def_sort_rev; -+ -+ thread_def_sort_rev = (*cl)->varmem >= (short) EndofList; -+ thread_def_sort = (SortOrder) ((*cl)->varmem - (thread_def_sort_rev -+ * EndofList)); -+ sprintf(tmp_20k_buf, "%s%s", sort_name(thread_def_sort), -+ (thread_def_sort_rev) ? "/Reverse" : ""); -+ -+ if((*cl)->var->cmdline_val.p) -+ fs_give((void **)&(*cl)->var->cmdline_val.p); -+ -+ if(apval){ -+ if(*apval) -+ fs_give((void **)apval); -+ -+ *apval = cpystr(tmp_20k_buf); -+ } -+ -+ set_current_val((*cl)->var, TRUE, TRUE); -+ if(decode_sort(ps->VAR_THREAD_SORT_KEY, &thread_def_sort, -+ &thread_def_sort_rev, 1) != -1){ -+ ps->thread_def_sort = thread_def_sort; -+ ps->thread_def_sort_rev = thread_def_sort_rev; -+ } -+ -+ set_radio_pretty_vals(ps, cl); -+ ps->mangled_body = 1; /* BUG: redraw it all for now? */ -+ rv = 1; -+ } - else - q_status_message(SM_ORDER | SM_DING, 3, 6, - "Programmer botch! Unknown radiobutton type."); -*************** -*** 10903,10909 **** - else if(standard_radio_var(ps, v) || v == startup_ptr) - return(radio_pretty_value(ps, cl)); - else if(v == &ps->vars[V_SORT_KEY]) -! return(sort_pretty_value(ps, cl)); - else if(v == &ps->vars[V_SIGNATURE_FILE]) - return(sigfile_pretty_value(ps, cl)); - else if(v == &ps->vars[V_USE_ONLY_DOMAIN_NAME]) ---- 11066,11074 ---- - else if(standard_radio_var(ps, v) || v == startup_ptr) - return(radio_pretty_value(ps, cl)); - else if(v == &ps->vars[V_SORT_KEY]) -! return(sort_pretty_value(ps, cl, 0)); -! else if(v == &ps->vars[V_THREAD_SORT_KEY]) -! return(sort_pretty_value(ps, cl, 1)); - else if(v == &ps->vars[V_SIGNATURE_FILE]) - return(sigfile_pretty_value(ps, cl)); - else if(v == &ps->vars[V_USE_ONLY_DOMAIN_NAME]) -*************** -*** 11572,11590 **** - - - char * -! sort_pretty_value(ps, cl) - struct pine *ps; - CONF_S *cl; - { -! return(generalized_sort_pretty_value(ps, cl, 1)); - } - - - char * -! generalized_sort_pretty_value(ps, cl, default_ok) - struct pine *ps; - CONF_S *cl; - int default_ok; - { - char tmp[MAXPATH]; - char *pvalnorm, *pvalexc, *pval; ---- 11737,11757 ---- - - - char * -! sort_pretty_value(ps, cl, thread) - struct pine *ps; - CONF_S *cl; -+ int thread; - { -! return(generalized_sort_pretty_value(ps, cl, 1, thread)); - } - - - char * -! generalized_sort_pretty_value(ps, cl, default_ok, thread) - struct pine *ps; - CONF_S *cl; - int default_ok; -+ int thread; - { - char tmp[MAXPATH]; - char *pvalnorm, *pvalexc, *pval; -*************** -*** 11634,11640 **** - } - else if(fixed){ - pval = v->fixed_val.p; -! decode_sort(pval, &var_sort, &var_sort_rev); - is_the_one = (var_sort_rev == line_sort_rev && var_sort == line_sort); - - sprintf(tmp, "(%c) %s%-*s%*s%s", ---- 11801,11807 ---- - } - else if(fixed){ - pval = v->fixed_val.p; -! decode_sort(pval, &var_sort, &var_sort_rev, thread); - is_the_one = (var_sort_rev == line_sort_rev && var_sort == line_sort); - - sprintf(tmp, "(%c) %s%-*s%*s%s", -*************** -*** 11645,11653 **** - is_the_one ? " (value is fixed)" : ""); - } - else if(is_set_for_this_level){ -! decode_sort(pval, &var_sort, &var_sort_rev); - is_the_one = (var_sort_rev == line_sort_rev && var_sort == line_sort); -! decode_sort(pvalexc, &exc_sort, &exc_sort_rev); - the_exc_one = (editing_normal_which_isnt_except && pvalexc && - exc_sort_rev == line_sort_rev && exc_sort == line_sort); - sprintf(tmp, "(%c) %s%-*s%*s%s", ---- 11812,11820 ---- - is_the_one ? " (value is fixed)" : ""); - } - else if(is_set_for_this_level){ -! decode_sort(pval, &var_sort, &var_sort_rev, thread); - is_the_one = (var_sort_rev == line_sort_rev && var_sort == line_sort); -! decode_sort(pvalexc, &exc_sort, &exc_sort_rev, thread); - the_exc_one = (editing_normal_which_isnt_except && pvalexc && - exc_sort_rev == line_sort_rev && exc_sort == line_sort); - sprintf(tmp, "(%c) %s%-*s%*s%s", -*************** -*** 11665,11671 **** - } - else{ - if(pvalexc){ -! decode_sort(pvalexc, &exc_sort, &exc_sort_rev); - is_the_one = (exc_sort_rev == line_sort_rev && - exc_sort == line_sort); - sprintf(tmp, "( ) %s%-*s%*s%s", ---- 11832,11838 ---- - } - else{ - if(pvalexc){ -! decode_sort(pvalexc, &exc_sort, &exc_sort_rev, thread); - is_the_one = (exc_sort_rev == line_sort_rev && - exc_sort == line_sort); - sprintf(tmp, "( ) %s%-*s%*s%s", -*************** -*** 11676,11682 **** - } - else{ - pval = v->current_val.p; -! decode_sort(pval, &var_sort, &var_sort_rev); - is_the_one = ((pval || default_ok) && - var_sort_rev == line_sort_rev && - var_sort == line_sort); ---- 11843,11849 ---- - } - else{ - pval = v->current_val.p; -! decode_sort(pval, &var_sort, &var_sort_rev, thread); - is_the_one = ((pval || default_ok) && - var_sort_rev == line_sort_rev && - var_sort == line_sort); -*************** -*** 11874,11879 **** ---- 12041,12059 ---- - - cl->value = pretty_value(ps, cl); - } -+ if (f->id == F_ENHANCED_THREAD && ps->mail_stream -+ && SORT_IS_THREADED(ps->msgmap)){ -+ refresh_sort(ps->mail_stream, ps->msgmap, SRT_NON); -+ if (COLL_THRDS()) /* sortring by thread destroys collapsed info */ -+ kolapse_thread(ps, ps->mail_stream, ps->msgmap,'[', 0); -+ if(SEP_THRDINDX() && SORT_IS_THREADED(ps->msgmap) -+ && sp_viewing_a_thread(ps->mail_stream)){ -+ unview_thread(ps, ps->mail_stream, ps->msgmap); -+ view_thread(ps, ps->mail_stream, ps->msgmap, 0); -+ ps_global->next_screen = SCREEN_FUN_NULL; -+ } -+ } -+ - - /* - * Handle any features that need special attention here... -*************** -*** 11884,11889 **** ---- 12064,12073 ---- - mail_parameters(NULL,SET_FROMWIDGET,(void *)(F_ON(f->id ,ps) ? 1 : 0)); - break; - -+ case F_COURIER_FOLDER_LIST: -+ mail_parameters(NULL,SET_COURIERSTYLE,(void *)(F_ON(f->id ,ps)? 1 : 0)); -+ break; /* COURIER == 1, CCLIENT == 0, see maildir.h */ -+ - case F_CMBND_ABOOK_DISP : - addrbook_reset(); - break; -*************** -*** 12683,12688 **** ---- 12867,12893 ---- - var == &ps->vars[V_ABOOK_FORMATS]){ - addrbook_reset(); - } -+ else if(var == &ps->vars[V_COMPOSE_RULES] || -+ var == &ps->vars[V_FORWARD_RULES] || -+ var == &ps->vars[V_INDEX_RULES] || -+ var == &ps->vars[V_REPLACE_RULES] || -+ var == &ps->vars[V_REPLY_INDENT_RULES] || -+ var == &ps->vars[V_REPLY_LEADIN_RULES] || -+ var == &ps->vars[V_RESUB_RULES] || -+ var == &ps->vars[V_SAVE_RULES] || -+ var == &ps->vars[V_SMTP_RULES] || -+ var == &ps->vars[V_SORT_RULES] || -+ var == &ps->vars[V_STARTUP_RULES] || -+ var == &ps->vars[V_THREAD_DISP_STYLE_RULES] || -+ var == &ps->vars[V_THREAD_INDEX_STYLE_RULES]){ -+ if(ps_global->rule_list) -+ free_parsed_rule_list(&ps_global->rule_list); -+ create_rule_list(); -+ if(var == &ps->vars[V_INDEX_RULES]){ -+ reset_index_format(); -+ clear_iindex_cache(); -+ } -+ } - else if(var == &ps->vars[V_INDEX_FORMAT]){ - reset_index_format(); - clear_iindex_cache(); -*************** -*** 12849,12854 **** ---- 13054,13065 ---- - if(ps->VAR_TCPQUERYTIMEO && SVAR_TCP_QUERY(ps, val, tmp_20k_buf)) - q_status_message(SM_ORDER, 3, 5, tmp_20k_buf); - } -+ else if(var == &ps->vars[V_INCFLDTIMEO]){ -+ val = 5; -+ if(!revert) -+ if(ps->VAR_INCFLDTIMEO && SVAR_TCP_QUERY(ps, val, tmp_20k_buf)) -+ q_status_message(SM_ORDER, 3, 5, tmp_20k_buf); -+ } - else if(var == &ps->vars[V_RSHOPENTIMEO]){ - val = 15; - if(!revert) -*************** -*** 12890,12895 **** ---- 13101,13111 ---- - fs_give((void **)&ps->vars[V_OPER_DIR].main_user_val.p); - } - } -+ else if(var == &ps->vars[V_INCOMING_FOLDERS_CHECK] && -+ F_OFF(F_ENABLE_FAST_RECENT, ps)){ -+ ps->force_check_now = 1; -+ new_mail_incfolder(ps, MC_FORCECHECK); /* yes, update it now */ -+ } - else if(var == &ps->vars[V_MAILCHECK]){ - timeo = 15; - if(SVAR_MAILCHK(ps, timeo, tmp_20k_buf)){ -*************** -*** 12955,12960 **** ---- 13171,13180 ---- - (void *)var->current_val.p); - } - #endif -+ else if(var == &ps->vars[V_MAILDIR_LOCATION]){ -+ if(var->current_val.p && var->current_val.p[0]) -+ maildir_parameters(SET_INBOXPATH, (void *)var->current_val.p); -+ } - else if(revert && standard_radio_var(ps, var)){ - - cur_rule_value(var, TRUE, FALSE); -*************** -*** 13001,13009 **** - else if(revert && var == &ps->vars[V_SORT_KEY]){ - int def_sort_rev; - -! decode_sort(VAR_SORT_KEY, &ps->def_sort, &def_sort_rev); - ps->def_sort_rev = def_sort_rev; - } - else if(var == &ps->vars[V_THREAD_MORE_CHAR] || - var == &ps->vars[V_THREAD_EXP_CHAR] || - var == &ps->vars[V_THREAD_LASTREPLY_CHAR]){ ---- 13221,13235 ---- - else if(revert && var == &ps->vars[V_SORT_KEY]){ - int def_sort_rev; - -! decode_sort(VAR_SORT_KEY, &ps->def_sort, &def_sort_rev, 0); - ps->def_sort_rev = def_sort_rev; - } -+ else if(revert && var == &ps->vars[V_THREAD_SORT_KEY]){ -+ int thread_def_sort_rev; -+ -+ decode_sort(VAR_THREAD_SORT_KEY, &ps->thread_def_sort, &thread_def_sort_rev, 1); -+ ps->thread_def_sort_rev = thread_def_sort_rev; -+ } - else if(var == &ps->vars[V_THREAD_MORE_CHAR] || - var == &ps->vars[V_THREAD_EXP_CHAR] || - var == &ps->vars[V_THREAD_LASTREPLY_CHAR]){ -*************** -*** 13760,13771 **** - - if(!(nonempty_patterns(rflags, &pstate) && - first_pattern(&pstate))){ -! q_status_message(SM_ORDER, 0, 3, - "No roles available. Use Setup/Rules to add roles."); - return(ret); - } - -- - if(alt_compose){ - menu_init_binding(&role_select_km, - alt_compose == MC_FORWARD ? 'F' : alt_compose == MC_REPLY ? 'R' : 'C', ---- 13986,14001 ---- - - if(!(nonempty_patterns(rflags, &pstate) && - first_pattern(&pstate))){ -! if (!ps->send_immediately) -! q_status_message(SM_ORDER, 0, 3, - "No roles available. Use Setup/Rules to add roles."); -+ else{ -+ printf("No roles available. Use Setup/Rules to add roles."); -+ exit(-1); -+ } - return(ret); - } - - if(alt_compose){ - menu_init_binding(&role_select_km, - alt_compose == MC_FORWARD ? 'F' : alt_compose == MC_REPLY ? 'R' : 'C', -*************** -*** 17979,17985 **** - - pval = PVAL(&sort_act_var, ew); - if(pval) -! decode_sort(pval, &def_sort, &def_sort_rev); - - /* allow user to set their default sort order */ - new_confline(&ctmp)->var = &sort_act_var; ---- 18209,18215 ---- - - pval = PVAL(&sort_act_var, ew); - if(pval) -! decode_sort(pval, &def_sort, &def_sort_rev, 0); - - /* allow user to set their default sort order */ - new_confline(&ctmp)->var = &sort_act_var; -*************** -*** 17989,17995 **** - ctmp->tool = role_sort_tool; - ctmp->valoffset = 12; - ctmp->varmem = -1; -! ctmp->value = generalized_sort_pretty_value(ps, ctmp, 0); - - for(j = 0; j < 2; j++){ - for(i = 0; ps->sort_types[i] != EndofList; i++){ ---- 18219,18225 ---- - ctmp->tool = role_sort_tool; - ctmp->valoffset = 12; - ctmp->varmem = -1; -! ctmp->value = generalized_sort_pretty_value(ps, ctmp, 0, 0); - - for(j = 0; j < 2; j++){ - for(i = 0; ps->sort_types[i] != EndofList; i++){ -*************** -*** 18001,18007 **** - ctmp->valoffset = 12; - ctmp->varmem = i + (j * EndofList); - ctmp->value = generalized_sort_pretty_value(ps, ctmp, -! 0); - } - } - ---- 18231,18237 ---- - ctmp->valoffset = 12; - ctmp->varmem = i + (j * EndofList); - ctmp->value = generalized_sort_pretty_value(ps, ctmp, -! 0, 0); - } - } - -*************** -*** 18906,18912 **** - (*result)->patgrp->stat_boy = PAT_STAT_EITHER; - - if(sort_act){ -! decode_sort(sort_act, &def_sort, &def_sort_rev); - (*result)->action->sort_is_set = 1; - (*result)->action->sortorder = def_sort; - (*result)->action->revsort = (def_sort_rev ? 1 : 0); ---- 19136,19142 ---- - (*result)->patgrp->stat_boy = PAT_STAT_EITHER; - - if(sort_act){ -! decode_sort(sort_act, &def_sort, &def_sort_rev, 0); - (*result)->action->sort_is_set = 1; - (*result)->action->sortorder = def_sort; - (*result)->action->revsort = (def_sort_rev ? 1 : 0); -*************** -*** 21330,21335 **** ---- 21560,21570 ---- - if(apval) - *apval = (role && role->nick) ? cpystr(role->nick) : NULL; - -+ if (ps_global->role) -+ fs_give((void **)&ps_global->role); -+ if (role && role->nick) -+ ps_global->role = cpystr(role->nick); -+ - if((*cl)->value) - fs_give((void **)&((*cl)->value)); - -*************** -*** 24130,24135 **** ---- 24365,24371 ---- - set_color_val(&vars[V_IND_UNS_FORE_COLOR], 0); - set_color_val(&vars[V_IND_ARR_FORE_COLOR], 0); - set_color_val(&vars[V_SIGNATURE_FORE_COLOR], 0); -+ set_color_val(&vars[V_SPECIAL_TEXT_FORE_COLOR], 0); - - set_current_val(&ps->vars[V_VIEW_HDR_COLORS], TRUE, TRUE); - set_current_val(&ps->vars[V_KW_COLORS], TRUE, TRUE); -*************** -*** 24680,24682 **** ---- 24916,24920 ---- - return(TRUE); - } - #endif /* _WINDOWS */ -+ -+ #include "rules.c" -diff -rc pine4.63/pine/pine.c pine4.63.I.USE/pine/pine.c -*** pine4.63/pine/pine.c Wed Apr 27 11:55:02 2005 ---- pine4.63.I.USE/pine/pine.c Thu May 19 19:57:34 2005 -*************** -*** 87,92 **** ---- 87,93 ---- - /* - * Internal prototypes - */ -+ int sp_add_status PROTO((MAILSTREAM *)); - int sp_add PROTO((MAILSTREAM *, int)); - int sp_nusepool_notperm PROTO((void)); - void sp_delete PROTO((MAILSTREAM *)); -*************** -*** 252,257 **** ---- 253,259 ---- - pine_state = (struct pine *)fs_get(sizeof (struct pine)); - memset((void *)pine_state, 0, sizeof(struct pine)); - ps_global = pine_state; -+ ps_global->thread_def_sort = SortDate; - ps_global->def_sort = SortArrival; - ps_global->sort_types[0] = SortSubject; - ps_global->sort_types[1] = SortArrival; -*************** -*** 264,269 **** ---- 266,273 ---- - ps_global->sort_types[8] = SortScore; - ps_global->sort_types[9] = SortThread; - ps_global->sort_types[10] = EndofList; -+ ps_global->force_check_now = 1; -+ ps_global->delay = 1; - ps_global->atmts = (ATTACH_S *) fs_get(sizeof(ATTACH_S)); - ps_global->atmts_allocated = 1; - ps_global->atmts->description = NULL; -*************** -*** 342,348 **** - pine_args(pine_state, argc, argv, &args); - - #ifndef _WINDOWS -! if(!isatty(0)){ - /* - * monkey with descriptors so our normal tty i/o routines don't - * choke... ---- 346,352 ---- - pine_args(pine_state, argc, argv, &args); - - #ifndef _WINDOWS -! if((!pine_state->send_immediately) && !isatty(0)){ - /* - * monkey with descriptors so our normal tty i/o routines don't - * choke... -*************** -*** 366,377 **** ---- 370,384 ---- - exit(-1); - } - -+ mail_parameters(NULL, SET_QUOTA, (void *) pine_parse_quota); -+ - /* set some default timeouts in case pinerc is remote */ - mail_parameters(NULL, SET_OPENTIMEOUT, (void *)(long)30); - mail_parameters(NULL, SET_READTIMEOUT, (void *)(long)15); - mail_parameters(NULL, SET_TIMEOUT, (void *) pine_tcptimeout); - /* could be TO_BAIL_THRESHOLD, 15 seems more appropriate for now */ - pine_state->tcp_query_timeout = 15; -+ pine_state->incfld_timeout = 5; - - mail_parameters(NULL, SET_SENDCOMMAND, (void *) pine_imap_cmd_happened); - mail_parameters(NULL, SET_FREESTREAMSPAREP, (void *) sp_free_callback); -*************** -*** 506,517 **** ---- 513,532 ---- - ps_global->s_pool.max_remstream)); - - init_vars(pine_state); -+ if (args.action == aaFolder && !args.data.folder && -+ ps_global->send_immediately){ -+ printf("No value for To: field specified\n"); -+ exit(-1); -+ } - - if(args.action == aaFolder){ - pine_state->beginning_of_month = first_run_of_month(); - pine_state->beginning_of_year = first_run_of_year(); - } - -+ mail_parameters(NULL,SET_COURIERSTYLE, -+ (void *)(F_ON(F_COURIER_FOLDER_LIST, ps_global) ? 1 : 0)); -+ - set_collation(F_OFF(F_DISABLE_SETLOCALE_COLLATE, ps_global), - F_ON(F_ENABLE_SETLOCALE_CTYPE, ps_global)); - -*************** -*** 559,565 **** - rv = 0; - if(pine_state->VAR_TCPWRITEWARNTIMEO){ - if(!SVAR_TCP_WRITEWARN(pine_state, rv, tmp_20k_buf)) -! if(rv == 0 || rv > 4) /* making sure */ - mail_parameters(NULL, SET_WRITETIMEOUT, (void *)(long)rv); - } - ---- 574,580 ---- - rv = 0; - if(pine_state->VAR_TCPWRITEWARNTIMEO){ - if(!SVAR_TCP_WRITEWARN(pine_state, rv, tmp_20k_buf)) -! if(rv == 0 || rv > 4) /* making sure */ - mail_parameters(NULL, SET_WRITETIMEOUT, (void *)(long)rv); - } - -*************** -*** 717,722 **** ---- 732,738 ---- - - - /*--- output side ---*/ -+ if (!ps_global->send_immediately){ - rv = config_screen(&(pine_state->ttyo)); - #if !defined(DOS) && !defined(OS2) /* always succeeds under DOS! */ - if(rv){ -*************** -*** 741,746 **** ---- 757,765 ---- - exit(-1); - } - #endif -+ } -+ else -+ fake_config_screen(&(pine_state->ttyo)); - - if(F_ON(F_BLANK_KEYMENU,ps_global)) - FOOTER_ROWS(ps_global) = 1; -*************** -*** 787,793 **** - goodnight_gracey(pine_state, exit_val); - } - -! if(args.action == aaFolder - && (pine_state->first_time_user || pine_state->show_new_version)){ - pine_state->mangled_header = 1; - show_main_screen(pine_state, 0, FirstMenu, &main_keymenu, 0, ---- 806,812 ---- - goodnight_gracey(pine_state, exit_val); - } - -! if(!pine_state->send_immediately && args.action == aaFolder - && (pine_state->first_time_user || pine_state->show_new_version)){ - pine_state->mangled_header = 1; - show_main_screen(pine_state, 0, FirstMenu, &main_keymenu, 0, -*************** -*** 941,946 **** ---- 960,971 ---- - int len, good_addr = 1; - int exit_val = 0; - BUILDER_ARG fcc; -+ ACTION_S *role = NULL; -+ -+ if (pine_state->in_init_seq && pine_state->send_immediately -+ && (char) *pine_state->initial_cmds++ == '#' -+ && ++pine_state->initial_cmds_offset) -+ role_select_screen(pine_state, &role, 1); - - if(pine_state->in_init_seq){ - pine_state->in_init_seq = pine_state->save_in_init_seq = 0; -*************** -*** 976,982 **** - memset(&fcc, 0, sizeof(fcc)); - - if(good_addr){ -! compose_mail(addr, fcc.tptr, NULL, - args.data.mail.attachlist, stdin_getc); - } - else{ ---- 1001,1007 ---- - memset(&fcc, 0, sizeof(fcc)); - - if(good_addr){ -! compose_mail(addr, fcc.tptr, role, - args.data.mail.attachlist, stdin_getc); - } - else{ -*************** -*** 1009,1014 **** ---- 1034,1040 ---- - - pine_state->mail_stream = NULL; - pine_state->mangled_screen = 1; -+ pine_state->subject = NULL; - - if(args.action == aaURL){ - url_tool_t f; -*************** -*** 1098,1103 **** ---- 1124,1130 ---- - "mail folder"); - } - -+ if (!pine_state->send_immediately) - fflush(stdout); - - #if !defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO) -*************** -*** 3164,3170 **** - { - int quit = 0; - -! dprint(1, (debugfile, "\n\n ---- QUIT SCREEN ----\n")); - - if(F_ON(F_CHECK_MAIL_ONQUIT,ps_global) - && new_mail(1, VeryBadTime, NM_STATUS_MSG | NM_DEFER_SORT) > 0 ---- 3191,3198 ---- - { - int quit = 0; - -! dprint(1, (debugfile, "\n\n ---- QUIT SCREEN ----\n")); -! ps_global->in_pico = 1; /* we are leaving anyway */ - - if(F_ON(F_CHECK_MAIL_ONQUIT,ps_global) - && new_mail(1, VeryBadTime, NM_STATUS_MSG | NM_DEFER_SORT) > 0 -*************** -*** 3209,3214 **** ---- 3237,3243 ---- - extern KBESC_T *kbesc; - - dprint(2, (debugfile, "goodnight_gracey:\n")); -+ sprintf(pine_state->cur_folder, pine_state->inbox_name); - - /* We want to do this here before we close up the streams */ - trim_remote_adrbks(); -*************** -*** 3311,3316 **** ---- 3340,3346 ---- - dprint(7, (debugfile, "goodnight_gracey: sp_end\n")); - ps_global->noshow_error = 1; - sp_end(); -+ sp_status_end(); - - /* after sp_end, which might call a filter */ - completely_done_with_adrbks(); -*************** -*** 3348,3353 **** ---- 3378,3385 ---- - free_saved_query_parameters(); - #endif - -+ if(pine_state->subject != NULL) -+ fs_give((void **)&pine_state->subject); - if(pine_state->hostname != NULL) - fs_give((void **)&pine_state->hostname); - if(pine_state->localdomain != NULL) -*************** -*** 3409,3414 **** ---- 3441,3449 ---- - - fs_give((void **)&ps_global->atmts); - } -+ -+ if(ps_global->rule_list) -+ free_parsed_rule_list(&ps_global->rule_list); - - dprint(7, (debugfile, "goodnight_gracey: free_vars\n")); - free_vars(pine_state); -*************** -*** 3956,3969 **** - - was_invisible = (mc->spare || mc->spare4) ? 1 : 0; - - if(chk_thrd_cnt = ((msgs->visible_threads >= 0L) - && THRD_INDX_ENABLED() && (f & MN_HIDE) && (mc->spare != v))){ -- thrd = fetch_thread(stream, rawno); - if(thrd && thrd->top){ -! if(thrd->top == thrd->rawno) - topthrd = thrd; - else -! topthrd = fetch_thread(stream, thrd->top); - } - - if(topthrd){ ---- 3991,4005 ---- - - was_invisible = (mc->spare || mc->spare4) ? 1 : 0; - -+ thrd = fetch_thread(stream, rawno); -+ - if(chk_thrd_cnt = ((msgs->visible_threads >= 0L) - && THRD_INDX_ENABLED() && (f & MN_HIDE) && (mc->spare != v))){ - if(thrd && thrd->top){ -! if(top_thread(stream,thrd->top) == thrd->rawno) - topthrd = thrd; - else -! topthrd = fetch_thread(stream, top_thread(stream,thrd->top)); - } - - if(topthrd){ -*************** -*** 6320,6325 **** ---- 6356,6446 ---- - return(NULL); - } - -+ MAILSTREAM * -+ sp_stream_status_get(mailbox) -+ char *mailbox; -+ { -+ int i; -+ MAILSTREAM *m = NULL; -+ -+ for(i = 0; i < ps_global->s_pool_status.nstream; i++){ -+ m = ps_global->s_pool_status.streams[i]; -+ if(m && same_stream(mailbox, m) && pine_mail_ping(m)) -+ return m; -+ } -+ return NULL; -+ } -+ -+ void -+ sp_status_end() -+ { -+ int i; -+ MAILSTREAM *m; -+ -+ for(i = 0; i < ps_global->s_pool_status.nstream; i++){ -+ m = ps_global->s_pool_status.streams[i]; -+ if(m) -+ pine_mail_actually_close(m); -+ } -+ -+ if(ps_global->s_pool_status.streams) -+ fs_give((void **) &ps_global->s_pool_status.streams); -+ -+ ps_global->s_pool_status.nstream = 0; -+ } -+ -+ int -+ sp_add_status(stream) -+ MAILSTREAM *stream; -+ { -+ int i, slot = -1; -+ MAILSTREAM *m; -+ -+ if(!stream) -+ return -1; -+ -+ for(i = 0; i < ps_global->s_pool_status.nstream; i++){ -+ m = ps_global->s_pool_status.streams[i]; -+ if(m == stream){ -+ slot = i; -+ return 0; -+ } -+ } -+ -+ for(i = 0; i < ps_global->s_pool_status.nstream; i++){ -+ m = ps_global->s_pool_status.streams[i]; -+ if(!m){ -+ slot = i; -+ break; -+ } -+ } -+ -+ if(slot < 0){ -+ slot = ps_global->s_pool_status.nstream++; -+ if(ps_global->s_pool_status.streams){ -+ fs_resize((void **) &ps_global->s_pool_status.streams, -+ ps_global->s_pool_status.nstream * -+ sizeof(*ps_global->s_pool_status.streams)); -+ ps_global->s_pool_status.streams[slot] = NULL; -+ } -+ else{ -+ ps_global->s_pool_status.streams = -+ (MAILSTREAM **) fs_get(ps_global->s_pool_status.nstream * -+ sizeof(*ps_global->s_pool_status.streams)); -+ memset(ps_global->s_pool_status.streams, 0, -+ ps_global->s_pool_status.nstream * -+ sizeof(*ps_global->s_pool_status.streams)); -+ } -+ } -+ -+ if(slot >= 0 && slot < ps_global->s_pool_status.nstream){ -+ ps_global->s_pool_status.streams[slot] = stream; -+ return 0; -+ } -+ else -+ return -1; -+ } -+ - - void - sp_end() -diff -rc pine4.63/pine/pine.h pine4.63.I.USE/pine/pine.h -*** pine4.63/pine/pine.h Fri Apr 15 15:07:15 2005 ---- pine4.63.I.USE/pine/pine.h Thu May 19 19:57:34 2005 -*************** -*** 231,236 **** ---- 231,239 ---- - #ifndef DF_INCOMING_STARTUP - #define DF_INCOMING_STARTUP "first-unseen" - #endif -+ #ifndef DF_INCOMING_RULE -+ #define DF_INCOMING_RULE "automatic" -+ #endif - #ifndef DF_PRUNING_RULE - #define DF_PRUNING_RULE "ask-ask" - #endif -*************** -*** 622,627 **** ---- 625,631 ---- - , V_SMTP_SERVER - , V_NNTP_SERVER - , V_INBOX_PATH -+ , V_INCOMING_FOLDERS_CHECK - , V_ARCHIVED_FOLDERS - , V_PRUNED_FOLDERS - , V_DEFAULT_FCC -*************** -*** 642,651 **** ---- 646,657 ---- - , V_SAVED_MSG_NAME_RULE - , V_FCC_RULE - , V_SORT_KEY -+ , V_THREAD_SORT_KEY - , V_AB_SORT_RULE - , V_FLD_SORT_RULE - , V_GOTO_DEFAULT_RULE - , V_INCOMING_STARTUP -+ , V_INCOMING_RULE - , V_PRUNING_RULE - , V_REOPEN_RULE - , V_THREAD_DISP_STYLE -*************** -*** 653,662 **** ---- 659,682 ---- - , V_THREAD_MORE_CHAR - , V_THREAD_EXP_CHAR - , V_THREAD_LASTREPLY_CHAR -+ , V_THREAD_DISP_STYLE_RULES -+ , V_THREAD_INDEX_STYLE_RULES -+ , V_COMPOSE_RULES -+ , V_FORWARD_RULES -+ , V_INDEX_RULES -+ , V_REPLACE_RULES -+ , V_REPLY_INDENT_RULES -+ , V_REPLY_LEADIN_RULES -+ , V_RESUB_RULES -+ , V_SAVE_RULES -+ , V_SMTP_RULES -+ , V_SORT_RULES -+ , V_STARTUP_RULES - , V_CHAR_SET - , V_EDITOR - , V_SPELLER - , V_FILLCOL -+ , V_SPECIAL_TEXT - , V_REPLY_STRING - , V_REPLY_INTRO - , V_QUOTE_REPLACE_STRING -*************** -*** 689,694 **** ---- 709,715 ---- - , V_NEWSRC_PATH - , V_NEWS_ACTIVE_PATH - , V_NEWS_SPOOL_DIR -+ , V_MAILDIR_LOCATION - , V_UPLOAD_CMD - , V_UPLOAD_CMD_PREFIX - , V_DOWNLOAD_CMD -*************** -*** 726,731 **** ---- 747,753 ---- - , V_TCPREADWARNTIMEO - , V_TCPWRITEWARNTIMEO - , V_TCPQUERYTIMEO -+ , V_INCFLDTIMEO - , V_RSHCMD - , V_RSHPATH - , V_RSHOPENTIMEO -*************** -*** 787,792 **** ---- 809,816 ---- - , V_QUOTE3_BACK_COLOR - , V_SIGNATURE_FORE_COLOR - , V_SIGNATURE_BACK_COLOR -+ , V_SPECIAL_TEXT_FORE_COLOR -+ , V_SPECIAL_TEXT_BACK_COLOR - , V_PROMPT_FORE_COLOR - , V_PROMPT_BACK_COLOR - , V_IND_PLUS_FORE_COLOR -*************** -*** 843,848 **** ---- 867,874 ---- - #define VAR_INBOX_PATH vars[V_INBOX_PATH].current_val.p - #define GLO_INBOX_PATH vars[V_INBOX_PATH].global_val.p - #define VAR_INCOMING_FOLDERS vars[V_INCOMING_FOLDERS].current_val.l -+ #define VAR_INCOMING_FOLDERS_CHECK vars[V_INCOMING_FOLDERS_CHECK].current_val.p -+ #define GLO_INCOMING_FOLDERS_CHECK vars[V_INCOMING_FOLDERS_CHECK].global_val.p - #define VAR_FOLDER_SPEC vars[V_FOLDER_SPEC].current_val.l - #define GLO_FOLDER_SPEC vars[V_FOLDER_SPEC].global_val.l - #define VAR_NEWS_SPEC vars[V_NEWS_SPEC].current_val.l -*************** -*** 897,912 **** ---- 923,980 ---- - #define VAR_SORT_KEY vars[V_SORT_KEY].current_val.p - #define GLO_SORT_KEY vars[V_SORT_KEY].global_val.p - #define COM_SORT_KEY vars[V_SORT_KEY].cmdline_val.p -+ #define VAR_THREAD_SORT_KEY vars[V_THREAD_SORT_KEY].current_val.p -+ #define GLO_THREAD_SORT_KEY vars[V_THREAD_SORT_KEY].global_val.p -+ #define COM_THREAD_SORT_KEY vars[V_THREAD_SORT_KEY].cmdline_val.p - #define VAR_AB_SORT_RULE vars[V_AB_SORT_RULE].current_val.p - #define GLO_AB_SORT_RULE vars[V_AB_SORT_RULE].global_val.p - #define VAR_FLD_SORT_RULE vars[V_FLD_SORT_RULE].current_val.p - #define GLO_FLD_SORT_RULE vars[V_FLD_SORT_RULE].global_val.p -+ #define VAR_COMPOSE_RULES vars[V_COMPOSE_RULES].current_val.l -+ #define GLO_COMPOSE_RULES vars[V_COMPOSE_RULES].global_val.l -+ #define USR_COMPOSE_RULES vars[V_COMPOSE_RULES].user_val.l -+ #define VAR_FORWARD_RULES vars[V_FORWARD_RULES].current_val.l -+ #define GLO_FORWARD_RULES vars[V_FORWARD_RULES].global_val.l -+ #define USR_FORWARD_RULES vars[V_FORWARD_RULES].user_val.l -+ #define VAR_INDEX_RULES vars[V_INDEX_RULES].current_val.l -+ #define GLO_INDEX_RULES vars[V_INDEX_RULES].global_val.l -+ #define USR_INDEX_RULES vars[V_INDEX_RULES].user_val.l -+ #define VAR_REPLACE_RULES vars[V_REPLACE_RULES].current_val.l -+ #define GLO_REPLACE_RULES vars[V_REPLACE_RULES].global_val.l -+ #define USR_REPLACE_RULES vars[V_REPLACE_RULES].user_val.l -+ #define VAR_REPLY_INDENT_RULES vars[V_REPLY_INDENT_RULES].current_val.l -+ #define GLO_REPLY_INDENT_RULES vars[V_REPLY_INDENT_RULES].global_val.l -+ #define USR_REPLY_INDENT_RULES vars[V_REPLY_INDENT_RULES].user_val.l -+ #define VAR_REPLY_LEADIN_RULES vars[V_REPLY_LEADIN_RULES].current_val.l -+ #define GLO_REPLY_LEADIN_RULES vars[V_REPLY_LEADIN_RULES].global_val.l -+ #define USR_REPLY_LEADIN_RULES vars[V_REPLY_LEADIN_RULES].user_val.l -+ #define VAR_RESUB_RULES vars[V_RESUB_RULES].current_val.l -+ #define GLO_RESUB_RULES vars[V_RESUB_RULES].global_val.l -+ #define USR_RESUB_RULES vars[V_RESUB_RULES].user_val.l -+ #define VAR_THREAD_DISP_STYLE_RULES vars[V_THREAD_DISP_STYLE_RULES].current_val.l -+ #define GLO_THREAD_DISP_STYLE_RULES vars[V_THREAD_DISP_STYLE_RULES].global_val.l -+ #define VAR_THREAD_INDEX_STYLE_RULES vars[V_THREAD_INDEX_STYLE_RULES].current_val.l -+ #define GLO_THREAD_INDEX_STYLE_RULES vars[V_THREAD_INDEX_STYLE_RULES].global_val.l -+ #define VAR_SAVE_RULES vars[V_SAVE_RULES].current_val.l -+ #define GLO_SAVE_RULES vars[V_SAVE_RULES].global_val.l -+ #define USR_SAVE_RULES vars[V_SAVE_RULES].user_val.l -+ #define VAR_SMTP_RULES vars[V_SMTP_RULES].current_val.l -+ #define GLO_SMTP_RULES vars[V_SMTP_RULES].global_val.l -+ #define USR_SMTP_RULES vars[V_SMTP_RULES].user_val.l -+ #define VAR_SORT_RULES vars[V_SORT_RULES].current_val.l -+ #define GLO_SORT_RULES vars[V_SORT_RULES].global_val.l -+ #define USR_SORT_RULES vars[V_SORT_RULES].user_val.l -+ #define VAR_STARTUP_RULES vars[V_STARTUP_RULES].current_val.l -+ #define GLO_STARTUP_RULES vars[V_STARTUP_RULES].global_val.l -+ #define USR_STARTUP_RULES vars[V_STARTUP_RULES].user_val.l - #define VAR_CHAR_SET vars[V_CHAR_SET].current_val.p - #define GLO_CHAR_SET vars[V_CHAR_SET].global_val.p - #define VAR_EDITOR vars[V_EDITOR].current_val.l - #define GLO_EDITOR vars[V_EDITOR].global_val.l - #define VAR_SPELLER vars[V_SPELLER].current_val.p - #define GLO_SPELLER vars[V_SPELLER].global_val.p -+ #define VAR_SPECIAL_TEXT vars[V_SPECIAL_TEXT].current_val.l -+ #define GLO_SPECIAL_TEXT vars[V_SPECIAL_TEXT].global_val.l - #define VAR_FILLCOL vars[V_FILLCOL].current_val.p - #define GLO_FILLCOL vars[V_FILLCOL].global_val.p - #define VAR_DEADLETS vars[V_DEADLETS].current_val.p -*************** -*** 991,996 **** ---- 1059,1066 ---- - #define GLO_NEWS_ACTIVE_PATH vars[V_NEWS_ACTIVE_PATH].global_val.p - #define VAR_NEWS_SPOOL_DIR vars[V_NEWS_SPOOL_DIR].current_val.p - #define GLO_NEWS_SPOOL_DIR vars[V_NEWS_SPOOL_DIR].global_val.p -+ #define VAR_MAILDIR_LOCATION vars[V_MAILDIR_LOCATION].current_val.p -+ #define GLO_MAILDIR_LOCATION vars[V_MAILDIR_LOCATION].global_val.p - #define VAR_DISABLE_DRIVERS vars[V_DISABLE_DRIVERS].current_val.l - #define VAR_DISABLE_AUTHS vars[V_DISABLE_AUTHS].current_val.l - #define VAR_REMOTE_ABOOK_METADATA vars[V_REMOTE_ABOOK_METADATA].current_val.p -*************** -*** 1035,1040 **** ---- 1105,1111 ---- - #define VAR_TCPREADWARNTIMEO vars[V_TCPREADWARNTIMEO].current_val.p - #define VAR_TCPWRITEWARNTIMEO vars[V_TCPWRITEWARNTIMEO].current_val.p - #define VAR_TCPQUERYTIMEO vars[V_TCPQUERYTIMEO].current_val.p -+ #define VAR_INCFLDTIMEO vars[V_INCFLDTIMEO].current_val.p - #define VAR_RSHOPENTIMEO vars[V_RSHOPENTIMEO].current_val.p - #define VAR_RSHPATH vars[V_RSHPATH].current_val.p - #define VAR_RSHCMD vars[V_RSHCMD].current_val.p -*************** -*** 1045,1050 **** ---- 1116,1123 ---- - #define VAR_BROWSER vars[V_BROWSER].current_val.l - #define VAR_INCOMING_STARTUP vars[V_INCOMING_STARTUP].current_val.p - #define GLO_INCOMING_STARTUP vars[V_INCOMING_STARTUP].global_val.p -+ #define VAR_INCOMING_RULE vars[V_INCOMING_RULE].current_val.p -+ #define GLO_INCOMING_RULE vars[V_INCOMING_RULE].global_val.p - #define VAR_PRUNING_RULE vars[V_PRUNING_RULE].current_val.p - #define GLO_PRUNING_RULE vars[V_PRUNING_RULE].global_val.p - #define VAR_REOPEN_RULE vars[V_REOPEN_RULE].current_val.p -*************** -*** 1122,1127 **** ---- 1195,1202 ---- - #define VAR_QUOTE3_BACK_COLOR vars[V_QUOTE3_BACK_COLOR].current_val.p - #define VAR_SIGNATURE_FORE_COLOR vars[V_SIGNATURE_FORE_COLOR].current_val.p - #define VAR_SIGNATURE_BACK_COLOR vars[V_SIGNATURE_BACK_COLOR].current_val.p -+ #define VAR_SPECIAL_TEXT_FORE_COLOR vars[V_SPECIAL_TEXT_FORE_COLOR].current_val.p -+ #define VAR_SPECIAL_TEXT_BACK_COLOR vars[V_SPECIAL_TEXT_BACK_COLOR].current_val.p - #define VAR_PROMPT_FORE_COLOR vars[V_PROMPT_FORE_COLOR].current_val.p - #define VAR_PROMPT_BACK_COLOR vars[V_PROMPT_BACK_COLOR].current_val.p - #define VAR_VIEW_HDR_COLORS vars[V_VIEW_HDR_COLORS].current_val.l -*************** -*** 1151,1156 **** ---- 1226,1232 ---- - F_FULL_AUTO_EXPUNGE, - F_EXPUNGE_MANUALLY, - F_AUTO_READ_MSGS, -+ F_AUTO_READ_MSGS_RULES, - F_AUTO_FCC_ONLY, - F_READ_IN_NEWSRC_ORDER, - F_SELECT_WO_CONFIRM, -*************** -*** 1168,1173 **** ---- 1244,1250 ---- - F_SHOW_DELAY_CUE, - F_CANCEL_CONFIRM, - F_AUTO_OPEN_NEXT_UNREAD, -+ F_AUTO_CIRCULAR_TAB, - F_SELECTED_SHOWN_BOLD, - F_QUOTE_ALL_FROMS, - F_AUTO_INCLUDE_IN_REPLY, -*************** -*** 1184,1189 **** ---- 1261,1268 ---- - F_DISABLE_PIPES_IN_TEMPLATES, - F_ATTACHMENTS_IN_REPLY, - F_ENABLE_INCOMING, -+ F_ENABLE_INCOMING_CHECK, -+ F_ENABLE_INCOMING_RECHECK, - F_NO_NEWS_VALIDATION, - F_QUELL_EXTRA_POST_PROMPT, - F_DISABLE_TAKE_LASTFIRST, -*************** -*** 1206,1215 **** ---- 1285,1296 ---- - F_PASS_C1_CONTROL_CHARS, - F_SINGLE_FOLDER_LIST, - F_VERTICAL_FOLDER_LIST, -+ F_COURIER_FOLDER_LIST, - F_TAB_CHK_RECENT, - F_AUTO_REPLY_TO, - F_VERBOSE_POST, - F_FCC_ON_BOUNCE, -+ F_USE_DOMAIN_NAME, - F_SEND_WO_CONFIRM, - F_USE_SENDER_NOT_X, - F_BLANK_KEYMENU, -*************** -*** 1314,1323 **** ---- 1395,1406 ---- - F_MAILDROPS_PRESERVE_STATE, - F_EXPOSE_HIDDEN_CONFIG, - F_ALT_COMPOSE_MENU, -+ F_ALT_REPLY_MENU, - F_ALT_ROLE_MENU, - F_ALWAYS_SPELL_CHECK, - F_QUELL_TIMEZONE, - F_COLOR_LINE_IMPORTANT, -+ F_ENHANCED_THREAD, - F_SLASH_COLL_ENTIRE, - F_ENABLE_FULL_HDR_AND_TEXT, - F_QUELL_FULL_HDR_RESET, -*************** -*** 1547,1552 **** ---- 1630,1642 ---- - #define IS_NOTSET 7 /* for reset version */ - - /* -+ * Incoming check rules -+ */ -+ #define IC_AUTO 0 -+ #define IC_MAN_AUTO 1 -+ #define IC_MAN 2 -+ -+ /* - * Pruning rules. If these grow, widen pruning_rule. - */ - #define PRUNE_ASK_AND_ASK 0 -*************** -*** 1830,1835 **** ---- 1920,1929 ---- - #define SVAR_TCP_QUERY(ps, n, e) strtoval((ps)->VAR_TCPQUERYTIMEO, \ - &(n), 5, 30000, 0, (e), \ - "Tcp-Query-Timeout") -+ #define SVAR_INCFLDQUERY(ps, n, e) strtoval((ps)->VAR_INCFLDTIMEO, \ -+ &(n), 2, 60, 0, (e), \ -+ "Inc-fld-timeout") -+ - #define SVAR_RSH_OPEN(ps, n, e) strtoval((ps)->VAR_RSHOPENTIMEO, \ - &(n), 5, 30000, 0, (e), \ - "Rsh-Open-Timeout") -*************** -*** 1930,1936 **** - SortSubject2, SortScore, SortThread, EndofList} SortOrder; - - #define refresh_sort(S,M,F) sort_folder((S), (M), mn_get_sort(M), \ -! mn_get_revsort(M), (F)) - - /* - * The two structs below hold all knowledge regarding ---- 2024,2030 ---- - SortSubject2, SortScore, SortThread, EndofList} SortOrder; - - #define refresh_sort(S,M,F) sort_folder((S), (M), mn_get_sort(M), \ -! mn_get_revsort(M), (F), 1) - - /* - * The two structs below hold all knowledge regarding -*************** -*** 1974,1986 **** - typedef struct pine_thrd { - unsigned long rawno; /* raw msgno of this message */ - unsigned long thrdno; /* thread number */ -- unsigned long flags; - unsigned long next; /* msgno of first reply to us */ - unsigned long branch; /* like THREADNODE branch, next replier */ - unsigned long parent; /* message that this is a reply to */ - unsigned long nextthd; /* next thread, only tops have this */ - unsigned long prevthd; /* previous thread, only tops have this */ - unsigned long top; /* top of this thread */ - unsigned long head; /* head of the whole thread list */ - } PINETHRD_S; - ---- 2068,2080 ---- - typedef struct pine_thrd { - unsigned long rawno; /* raw msgno of this message */ - unsigned long thrdno; /* thread number */ - unsigned long next; /* msgno of first reply to us */ - unsigned long branch; /* like THREADNODE branch, next replier */ - unsigned long parent; /* message that this is a reply to */ - unsigned long nextthd; /* next thread, only tops have this */ - unsigned long prevthd; /* previous thread, only tops have this */ - unsigned long top; /* top of this thread */ -+ unsigned long toploose; /* top of this thread, if is loose */ - unsigned long head; /* head of the whole thread list */ - } PINETHRD_S; - -*************** -*** 2571,2580 **** ---- 2665,2681 ---- - unsigned hasnochildren:1; /* known not to have children */ - unsigned scanned:1; /* scanned by c-client */ - unsigned selected:1; /* selected by user */ -+ unsigned user_selected:1; /* selected by user (not Pine)*/ - unsigned subscribed:1; /* selected by user */ - unsigned long varhash; /* hash of var for incoming */ - unsigned long uidvalidity; /* only for #move folder */ - unsigned long uidnext; /* only for #move folder */ -+ int notified; /* notified the change? */ -+ int new_mail; /* folder has new mail */ -+ long origrecent; /* # recent messages in stream*/ -+ long countrecent; /* # recent messages displayed*/ -+ long recent; /* # recent messages adjusted */ -+ long messages; /* # messages */ - char *nickname; /* folder's short name */ - char name[1]; /* folder's name */ - } FOLDER_S; -*************** -*** 2600,2611 **** - iLstYear, iLstYear2Digit, - iMessNo, iAtt, iMsgID, iSubject, - iSubjKey, iSubjKeyInit, iKey, iKeyInit, -! iSize, iSizeComma, iSizeNarrow, iDescripSize, - iNewsAndTo, iToAndNews, iNewsAndRecips, iRecipsAndNews, - iFromTo, iFromToNotNews, iFrom, iTo, iSender, iCc, iNews, iRecips, - iCurNews, iArrow, - iMailbox, iAddress, iInit, iCursorPos, - iDay2Digit, iMon2Digit, iYear2Digit, - iSTime, iKSize, - iRoleNick, - iScore, iDayOfWeekAbb, iDayOfWeek, ---- 2701,2715 ---- - iLstYear, iLstYear2Digit, - iMessNo, iAtt, iMsgID, iSubject, - iSubjKey, iSubjKeyInit, iKey, iKeyInit, -! iSize, iSizeComma, iSizeNarrow, iDescripSize, iSizeThread, - iNewsAndTo, iToAndNews, iNewsAndRecips, iRecipsAndNews, - iFromTo, iFromToNotNews, iFrom, iTo, iSender, iCc, iNews, iRecips, - iCurNews, iArrow, - iMailbox, iAddress, iInit, iCursorPos, - iDay2Digit, iMon2Digit, iYear2Digit, -+ iFolder, iFlag, iCollection, iRole, -+ iNick, iAddressTo, iAddressCc, iAddressRecip, iBcc, iLcc, -+ iFfrom, iFadd, - iSTime, iKSize, - iRoleNick, - iScore, iDayOfWeekAbb, iDayOfWeek, -*************** -*** 2622,2634 **** - } INDEX_PARSE_T; - - /* these are flags for the what_for field in INDEX_PARSE_T */ -! #define FOR_NOTHING 0x00 -! #define FOR_INDEX 0x01 -! #define FOR_REPLY_INTRO 0x02 -! #define FOR_TEMPLATE 0x04 /* or for signature */ -! #define FOR_FILT 0x08 -! #define DELIM_USCORE 0x10 -! #define DELIM_PAREN 0x20 - - #define DEFAULT_REPLY_INTRO "default" - ---- 2726,2749 ---- - } INDEX_PARSE_T; - - /* these are flags for the what_for field in INDEX_PARSE_T */ -! #define FOR_NOTHING 0x00000 -! #define FOR_INDEX 0x00001 -! #define FOR_REPLY_INTRO 0x00002 -! #define FOR_TEMPLATE 0x00004 /* or for signature */ -! #define FOR_FILT 0x00008 -! #define DELIM_USCORE 0x00010 -! #define DELIM_PAREN 0x00020 -! #define FOR_SAVE 0x00040 /* for rules */ -! #define FOR_FOLDER 0x00080 /* for rules */ -! #define FOR_RULE 0x00100 /* for rules */ -! #define FOR_TRIM 0x00200 /* for rules */ -! #define FOR_RESUB 0x00400 /* for rules */ -! #define FOR_REPLACE 0x00800 /* for rules */ -! #define FOR_SORT 0x01000 /* for rules */ -! #define FOR_FLAG 0x02000 /* for rules */ -! #define FOR_COMPOSE 0x04000 /* for rules */ -! #define FOR_THREAD 0x08000 /* for rules */ -! #define FOR_STARTUP 0x10000 /* for rules */ - - #define DEFAULT_REPLY_INTRO "default" - -*************** -*** 2992,3002 **** - #define MC_NOT 799 - #define MC_COLLAPSE 800 - #define MC_CHK_RECENT 801 -! - - /* - * Some standard Key/Command Bindings - */ - #define NULL_MENU {NULL, NULL, {MC_NONE}, KS_NONE} - #define HELP_MENU {"?", "Help", \ - {MC_HELP, 2, {'?',ctrl('G')}}, \ ---- 3107,3132 ---- - #define MC_NOT 799 - #define MC_COLLAPSE 800 - #define MC_CHK_RECENT 801 -! #define MC_PRETHREAD 802 -! #define MC_CTHREAD 803 -! #define MC_OTHREAD 804 -! #define MC_DELTHREAD 805 -! #define MC_UNDTHREAD 806 -! #define MC_SELTHREAD 807 -! #define MC_SSUTHREAD 808 -! #define MC_DSUTHREAD 809 -! #define MC_USUTHREAD 810 -! #define MC_SORTHREAD 811 -! #define MC_NEXTHREAD 812 -! #define MC_KOLAPSE 813 -! #define MC_EXPTHREAD 814 -! #define MC_QUOTA 815 - - /* - * Some standard Key/Command Bindings - */ -+ #define MC_IFAUTOCHECK 820 -+ #define MC_FORCECHECK 821 - #define NULL_MENU {NULL, NULL, {MC_NONE}, KS_NONE} - #define HELP_MENU {"?", "Help", \ - {MC_HELP, 2, {'?',ctrl('G')}}, \ -*************** -*** 3094,3100 **** - #define TAB_MENU {"Tab", "NextNew", \ - {MC_TAB,1,{TAB}}, \ - KS_NONE} -! - - #define USER_INPUT_TIMEOUT(ps) ((ps->hours_to_timeout > 0) && \ - ((time(0) - time_of_last_input) > 60*60*(ps->hours_to_timeout))) ---- 3224,3232 ---- - #define TAB_MENU {"Tab", "NextNew", \ - {MC_TAB,1,{TAB}}, \ - KS_NONE} -! #define QUOTA_MENU {"@", "Quota", \ -! {MC_QUOTA,1,{'@'}}, \ -! KS_NONE} - - #define USER_INPUT_TIMEOUT(ps) ((ps->hours_to_timeout > 0) && \ - ((time(0) - time_of_last_input) > 60*60*(ps->hours_to_timeout))) -*************** -*** 3681,3688 **** ---- 3813,3872 ---- - #define HEX_CHAR1(C) HEX_ARRAY[((C) & 0xf0) >> 4] - #define HEX_CHAR2(C) HEX_ARRAY[(C) & 0xf] - -+ typedef struct rule { -+ char *result; /* The result of the rule */ -+ int number; /* The number of the rule that succeded, -1 if not */ -+ } RULE_RESULT; -+ -+ #define TOKEN_VALUE struct tokenvalue_s -+ #define CONDITION_S struct condition_s -+ #define RULEACTION_S struct ruleaction_s -+ #define RULE_S struct rule_s -+ #define RULELIST struct rulelist_s -+ #define PRULELIST_S struct parsedrulelist_s -+ -+ TOKEN_VALUE { -+ char *testxt; -+ TOKEN_VALUE *next; -+ }; -+ -+ typedef enum {Equal, Subset, Includes, -+ NotEqual, NotSubset, NotIncludes, -+ EndTypes} TestType; -+ -+ CONDITION_S { -+ char *tname; /* tname ttype {value} */ -+ TestType ttype; /* tname ttype {value} */ -+ TOKEN_VALUE *value; /* value to check against */ -+ CONDITION_S *next; /* next condition to test */ -+ }; -+ -+ RULEACTION_S { -+ char *token; /* token := function{value} or token = null */ -+ char *function; /* token := function{value} or simply function{value}*/ -+ TOKEN_VALUE *value; /* token := function{value} or simply function{value}*/ -+ int context; /* context in which this rule can be used */ -+ char* (*exec)(); -+ unsigned int is_trim:1; -+ unsigned int is_rextrim:1; -+ unsigned int is_replace:1; -+ }; - -+ RULE_S { -+ CONDITION_S *condition; -+ RULEACTION_S *action; -+ }; - -+ RULELIST { -+ RULE_S *prule; -+ RULELIST *next; -+ }; -+ -+ PRULELIST_S { -+ int varnum; /* number associated to the variable */ -+ RULELIST *rlist; -+ PRULELIST_S *next; -+ }; - - /*------------------------------ - Structure to pass optionally_enter to tell it what keystrokes -*************** -*** 3830,3835 **** ---- 4014,4020 ---- - PrivateAffector *affector; - } PrivateTop; - -+ #define DF_THREAD_SORT_KEY "thread" - - typedef enum {OpenFolder, SaveMessage, FolderMaint, GetFcc, - Subscribe, PostNews} FolderFun; -*************** -*** 3954,3959 **** ---- 4139,4146 ---- - unsigned char t; /* temporary char */ - char *line; /* place for temporary storage */ - char *linep; /* pointer into storage space */ -+ char *oldline; /* the previous line to "line" */ -+ char *oldlinep; /* the previous line to "line" */ - void *opt; /* optional per instance data */ - void *data; /* misc internal data pointer */ - unsigned char queue[1 + GF_MAXBUF]; -*************** -*** 4221,4226 **** ---- 4408,4414 ---- - CONTEXT_S *context_last; /* most recently open context */ - - SP_S s_pool; /* stream pool */ -+ SP_S s_pool_status; /* stream pool */ - - char inbox_name[MAXFOLDER+1]; - char pine_pre_vers[10]; /* highest version previously run */ -*************** -*** 4228,4237 **** ---- 4416,4436 ---- - MAILSTREAM *mail_stream; /* ptr to current folder stream */ - MSGNO_S *msgmap; /* ptr to current message map */ - -+ char *role; /* role used when composing */ -+ int exiting; -+ - unsigned read_predicted:1; - - char cur_folder[MAXPATH+1]; -+ QUOTALIST *quota; - char last_unambig_folder[MAXPATH+1]; -+ int refresh_list; -+ int in_pico; -+ int in_fld_list; -+ int force_check_now; -+ int checking_incfld; -+ int incfld_timeout; -+ int delay; - ATTACH_S *atmts; - int atmts_allocated; - int remote_abook_validity; /* minutes, -1=never, 0=only on opens */ -*************** -*** 4255,4260 **** ---- 4454,4461 ---- - unsigned unseen_in_view:1; - unsigned start_in_context:1; /* start fldr_scrn in current cntxt */ - unsigned def_sort_rev:1; /* true if reverse sort is default */ -+ unsigned thread_def_sort_rev:1; /* true if reverse sort is default in thread screen */ -+ unsigned msgmap_thread_def_sort_rev:1; /* true if reverse sort is being used in thread screen */ - unsigned restricted:1; - - unsigned save_msg_rule:5; -*************** -*** 4265,4270 **** ---- 4466,4472 ---- - unsigned titlebar_color_style:3; - unsigned fld_sort_rule:3; - unsigned inc_startup_rule:3; -+ unsigned inc_check_rule:2; - unsigned pruning_rule:3; - unsigned reopen_rule:4; - unsigned goto_default_rule:3; -*************** -*** 4356,4361 **** ---- 4558,4566 ---- - - int *initial_cmds; /* cmds to execute on startup */ - int *free_initial_cmds; /* used to free when done */ -+ int *initial_cmds_backup; /* keep a copy in case they are freed */ -+ int *free_initial_cmds_backup; /* free the copy */ -+ int initial_cmds_offset; /* how many commands we have executed */ - - char c_client_error[300]; /* when nowhow_error is set and PARSE */ - -*************** -*** 4392,4397 **** ---- 4597,4605 ---- - EditWhich ew_for_other_take; - - SortOrder def_sort, /* Default sort type */ -+ thread_def_sort, /* Default Sort Type in Thread Screen */ -+ thread_cur_sort, /* current sort style for threads */ -+ msgmap_thread_sort, - sort_types[22]; - - int last_expire_year, last_expire_month; -*************** -*** 4404,4409 **** ---- 4612,4620 ---- - - int nmw_width; - -+ char *subject; -+ int send_immediately; -+ - int hours_to_timeout; - - int tcp_query_timeout; -*************** -*** 4425,4430 **** ---- 4636,4642 ---- - INIT_ERR_S *init_errs; - - PRINT_S *print; -+ PRULELIST_S *rule_list; - - struct variable *vars; - }; -*************** -*** 4552,4557 **** ---- 4764,4770 ---- - void gf_busy PROTO((FILTER_S *, int)); - void gf_nvtnl_local PROTO((FILTER_S *, int)); - void gf_local_nvtnl PROTO((FILTER_S *, int)); -+ void gf_quote_test PROTO((FILTER_S *, int)); - void gf_line_test PROTO((FILTER_S *, int)); - void *gf_line_test_opt PROTO((linetest_t, void *)); - LT_INS_S **gf_line_test_new_ins PROTO((LT_INS_S **, char *, char *, int)); -*************** -*** 4588,4599 **** ---- 4801,4817 ---- - char *folder_is_nick PROTO((char *, void *, int)); - char *next_folder PROTO((MAILSTREAM **, char *, char *,CONTEXT_S *, - long *, int *)); -+ int next_folder_check PROTO((MAILSTREAM **, CONTEXT_S *, long *, long *, -+ FOLDER_S *, int *)); - void init_inbox_mapping PROTO((char *, CONTEXT_S *)); - int news_build PROTO((char *, char **, char **, BUILDER_ARG *, int *)); - char *news_group_selector PROTO((char **)); - void free_newsgrp_cache PROTO(()); - char *context_edit_screen PROTO((struct pine *, char *, char *, - char *, char *, char *)); -+ void update_incoming_folder_data PROTO((MAILSTREAM *, CONTEXT_S *)); -+ FOLDER_S *incoming_folder_data PROTO((MAILSTREAM *, CONTEXT_S *)); -+ int need_folder_report PROTO ((char *)); - SELECTED_S *new_selected PROTO((void)); - void free_selected PROTO((SELECTED_S **)); - int add_new_folder PROTO((CONTEXT_S *, EditWhich, int, char *, size_t, -*************** -*** 4615,4620 **** ---- 4833,4839 ---- - #endif - - /*-- imap.c --*/ -+ void pine_parse_quota PROTO((MAILSTREAM *, unsigned char *msg,QUOTALIST *)); - char *cached_user_name PROTO((char *)); - void imap_flush_passwd_cache PROTO(()); - long pine_tcptimeout PROTO((long, long)); -*************** -*** 4647,4653 **** - int write_pinerc PROTO((struct pine *, EditWhich, int)); - int var_in_pinerc PROTO((char *)); - void free_pinerc_lines PROTO((PINERC_LINE **)); -! int decode_sort PROTO((char *, SortOrder *, int *)); - void dump_global_conf PROTO((void)); - void dump_new_pinerc PROTO((char *)); - int set_variable PROTO((int, char *, int, int, EditWhich)); ---- 4866,4872 ---- - int write_pinerc PROTO((struct pine *, EditWhich, int)); - int var_in_pinerc PROTO((char *)); - void free_pinerc_lines PROTO((PINERC_LINE **)); -! int decode_sort PROTO((char *, SortOrder *, int *, int)); - void dump_global_conf PROTO((void)); - void dump_new_pinerc PROTO((char *)); - int set_variable PROTO((int, char *, int, int, EditWhich)); -*************** -*** 4678,4683 **** ---- 4897,4903 ---- - NAMEVAL_S *titlebar_col_style PROTO((int)); - NAMEVAL_S *fld_sort_rules PROTO((int)); - NAMEVAL_S *incoming_startup_rules PROTO((int)); -+ NAMEVAL_S *incoming_check_rules PROTO((int)); - NAMEVAL_S *startup_rules PROTO((int)); - NAMEVAL_S *pruning_rules PROTO((int)); - NAMEVAL_S *reopen_rules PROTO((int)); -*************** -*** 4720,4729 **** - int set_mime_extension_by_type PROTO((char *, char *)); - - /*---- mailcmd.c ----*/ - int process_cmd PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, - int, CmdWhere, int *)); - int apply_command PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, int, -! int, int)); - int menu_command PROTO((int, struct key_menu *)); - void menu_init_binding PROTO((struct key_menu *, int, int, - char *, char *, int)); ---- 4940,4950 ---- - int set_mime_extension_by_type PROTO((char *, char *)); - - /*---- mailcmd.c ----*/ -+ MAILSTREAM *find_open_stream PROTO((void)); - int process_cmd PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, - int, CmdWhere, int *)); - int apply_command PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, int, -! int, int, int)); - int menu_command PROTO((int, struct key_menu *)); - void menu_init_binding PROTO((struct key_menu *, int, int, - char *, char *, int)); -*************** -*** 4766,4771 **** ---- 4987,4993 ---- - char *get_uname PROTO((char *, char *, int)); - char *build_updown_cmd PROTO((char *, char *, char *, char*)); - int file_lister PROTO((char *, char *, int, char *, int, int, int)); -+ unsigned long rules_cursor_pos PROTO((MAILSTREAM *)); - int display_folder_list PROTO((CONTEXT_S **, char *, int, - int (*) PROTO((struct pine *, - CONTEXT_S **, -*************** -*** 4790,4795 **** ---- 5012,5018 ---- - #endif - - /*--- mailindx.c ---*/ -+ void insert_pattern_in_string PROTO((char *, char *, int)); - void mail_index_screen PROTO((struct pine *)); - int index_lister PROTO((struct pine *, CONTEXT_S *, char *, - MAILSTREAM *, MSGNO_S *)); -*************** -*** 4820,4826 **** - MSGNO_S *, IndexType, int *, int)); - char *sort_name PROTO((SortOrder)); - void sort_folder PROTO((MAILSTREAM *, MSGNO_S *, -! SortOrder, int, unsigned)); - int percent_sorted PROTO((void)); - void msgno_init PROTO((MSGNO_S **, long)); - void msgno_give PROTO((MSGNO_S **)); ---- 5043,5049 ---- - MSGNO_S *, IndexType, int *, int)); - char *sort_name PROTO((SortOrder)); - void sort_folder PROTO((MAILSTREAM *, MSGNO_S *, -! SortOrder, int, unsigned, int)); - int percent_sorted PROTO((void)); - void msgno_init PROTO((MSGNO_S **, long)); - void msgno_give PROTO((MSGNO_S **)); -*************** -*** 4843,4849 **** - void free_pine_elt PROTO((void **)); - SEARCHSET *build_searchset PROTO((MAILSTREAM *)); - void collapse_or_expand PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, -! unsigned long)); - PINETHRD_S *fetch_thread PROTO((MAILSTREAM *, unsigned long)); - PINETHRD_S *fetch_head_thread PROTO((MAILSTREAM *)); - int view_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, int)); ---- 5066,5072 ---- - void free_pine_elt PROTO((void **)); - SEARCHSET *build_searchset PROTO((MAILSTREAM *)); - void collapse_or_expand PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, -! unsigned long, int)); - PINETHRD_S *fetch_thread PROTO((MAILSTREAM *, unsigned long)); - PINETHRD_S *fetch_head_thread PROTO((MAILSTREAM *)); - int view_thread PROTO((struct pine *, MAILSTREAM *, MSGNO_S *, int)); -*************** -*** 4891,4896 **** ---- 5114,5121 ---- - int, char *)); - - /*--- mailview.c ---*/ -+ int select_quote PROTO((long, char *, LT_INS_S **, void *)); -+ int next_level_quote PROTO((char *, char **, int, int)); - void mail_view_screen PROTO((struct pine *)); - int scrolltool PROTO((SCROLL_S *)); - char *body_type_names PROTO((int)); -*************** -*** 4937,4942 **** ---- 5162,5169 ---- - void check_point_change PROTO((MAILSTREAM *)); - void reset_check_point PROTO((MAILSTREAM *)); - void zero_new_mail_count PROTO((void)); -+ int new_mail_incfolder PROTO((struct pine *, int)); -+ char *new_mail_in_open_stream PROTO((MAILSTREAM *, long *, long *)); - int changes_to_checkpoint PROTO((MAILSTREAM *)); - void close_newmailfifo PROTO((void)); - void init_newmailfifo PROTO((char *)); -*************** -*** 5122,5133 **** ---- 5349,5362 ---- - int sp_flagged PROTO((MAILSTREAM *, unsigned long)); - void sp_mark_stream_dead PROTO((MAILSTREAM *)); - MAILSTREAM *sp_stream_get PROTO((char *, unsigned long)); -+ MAILSTREAM *sp_stream_status_get PROTO((char *)); - int sp_a_locked_stream_is_dead PROTO((void)); - int sp_a_locked_stream_changed PROTO((void)); - MAILSTREAM *sp_inbox_stream PROTO((void)); - void sp_cleanup_dead_streams PROTO((void)); - int sp_nremote_permlocked PROTO((void)); - void sp_end PROTO((void)); -+ void sp_status_end PROTO((void)); - - /*-- reply.c --*/ - void reply PROTO((struct pine *, ACTION_S *)); -*************** -*** 5138,5144 **** - ENVELOPE *, ADDRESS **, ADDRESS **, - ADDRESS **, ADDRESS **,int *)); - int reply_news_test PROTO((ENVELOPE *, ENVELOPE *)); -! int reply_text_query PROTO((struct pine *, long, char **)); - BODY *reply_body PROTO((MAILSTREAM *, ENVELOPE *, BODY *, long, - char *, void *, char *, int, ACTION_S *, int, - REDRAFT_POS_S **)); ---- 5367,5373 ---- - ENVELOPE *, ADDRESS **, ADDRESS **, - ADDRESS **, ADDRESS **,int *)); - int reply_news_test PROTO((ENVELOPE *, ENVELOPE *)); -! int reply_text_query PROTO((struct pine *, long, ENVELOPE *, char **)); - BODY *reply_body PROTO((MAILSTREAM *, ENVELOPE *, BODY *, long, - char *, void *, char *, int, ACTION_S *, int, - REDRAFT_POS_S **)); -*************** -*** 5185,5190 **** ---- 5414,5459 ---- - void standard_picobuf_setup PROTO((PICO *)); - void standard_picobuf_teardown PROTO((PICO *)); - -+ /* -- rules.c -- */ -+ RULE_RESULT *get_result_rule PROTO ((int, int, ENVELOPE *)); -+ char *test_rule PROTO ((RULELIST *, int, ENVELOPE *, int *)); -+ char *process_rule PROTO ((RULE_S *, int, ENVELOPE *)); -+ int test_condition PROTO ((CONDITION_S *, int, ENVELOPE *)); -+ int test_in PROTO ((CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int)); -+ int test_ni PROTO ((CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int)); -+ int test_not_in PROTO ((CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int)); -+ int test_not_ni PROTO ((CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int)); -+ int test_eq PROTO ((CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int)); -+ int test_not_eq PROTO ((CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int)); -+ int isolate_condition PROTO ((char *, char **, int *)); -+ int condition_contains_token PROTO((CONDITION_S *, char *)); -+ char *trim PROTO ((RULEACTION_S *, int, ENVELOPE *)); -+ char *rextrim PROTO ((RULEACTION_S *, int, ENVELOPE *)); -+ char *raw_value PROTO ((RULEACTION_S *, int, ENVELOPE *)); -+ char *extended_value PROTO ((RULEACTION_S *, int, ENVELOPE *)); -+ char *expand PROTO ((char *, char *)); -+ char *get_name_token PROTO ((char *)); -+ char *advance_to_char PROTO ((char *, char, int, int *)); -+ void free_token_value PROTO ((TOKEN_VALUE **)); -+ void free_condition PROTO ((CONDITION_S **)); -+ void free_ruleaction PROTO ((RULEACTION_S **)); -+ void free_rule PROTO ((RULE_S **)); -+ void free_rule_list PROTO ((RULELIST **)); -+ void free_parsed_rule_list PROTO((PRULELIST_S **)); -+ void *alloc_mem PROTO ((size_t)); -+ void add_rule PROTO ((int, int)); -+ void create_rule_list PROTO ((void)); -+ RULE_S *parse_rule PROTO ((char *, int)); -+ RULE_S *get_rule PROTO ((RULELIST *, int)); -+ RULELIST *get_rule_list PROTO ((char **, int, int)); -+ RULELIST *get_rulelist_from_code PROTO((int, PRULELIST_S *)); -+ TOKEN_VALUE *parse_group_data PROTO ((char *,int *)); -+ TOKEN_VALUE *copy_parsed_value PROTO((TOKEN_VALUE *, int, ENVELOPE *)); -+ CONDITION_S *fill_condition PROTO ((char *)); -+ CONDITION_S *parse_condition PROTO ((char *, int *)); -+ PRULELIST_S *add_prule PROTO ((PRULELIST_S *, PRULELIST_S *)); -+ RULEACTION_S *parse_action PROTO ((char *, int)); -+ - /*-- screen.c --*/ - void draw_keymenu PROTO((struct key_menu *, bitmap_t, int, int, - int, OtherMenu)); -*************** -*** 5309,5314 **** ---- 5578,5584 ---- - void removing_leading_white_space PROTO((char *)); - void removing_leading_and_trailing_white_space PROTO((char *)); - int removing_double_quotes PROTO((char *)); -+ void removing_extra_stuff PROTO((char *)); - char *skip_white_space PROTO((char *)); - char *skip_to_white_space PROTO((char *)); - char *removing_quotes PROTO((char *)); -*************** -*** 5490,5495 **** ---- 5760,5766 ---- - void MoveCursor PROTO((int, int)); - void NewLine PROTO((void)); - int config_screen PROTO((struct ttyo **)); -+ void fake_config_screen PROTO((struct ttyo **)); - void init_screen PROTO((void)); - void end_screen PROTO((char *, int)); - void outchar PROTO((int)); -diff -rc pine4.63/pine/pine.hlp pine4.63.I.USE/pine/pine.hlp -*** pine4.63/pine/pine.hlp Thu Apr 28 10:22:02 2005 ---- pine4.63.I.USE/pine/pine.hlp Thu May 19 19:59:15 2005 -*************** -*** 457,462 **** ---- 457,463 ---- - <P> - Some topics of current interest include: - <UL> -+ <P><LI> Information on <A HREF="h_patches">patches for this release</A> - <P><LI> <A HREF="h_maildrop">Mail Drops</A> - <P><LI> Information on <A HREF="h_info_on_locking">Folder Locking</A> - <P><LI> Information on <A HREF="h_info_on_mbox">Missing mail and the mbox driver</A> -*************** -*** 1081,1086 **** ---- 1082,1143 ---- - <End of Configuration Notes> - </BODY> - </HTML> -+ ====== h_patches ====== -+ <html> -+ <head> -+ <TITLE>Information on patches added to this release</TITLE> -+ </head> -+ <body> -+ <H1>Information on patches added to this release</H1> -+ <P> -+ This version of Pine has been modified by including patches from -+ <A HREF="http://www.math.washington.edu/~chappa/pine/"> -+ http://www.math.washington.edu/~chappa/pine/</A>. These patches include -+ new features and bug fixes. More complete information on each patch -+ included in this version can be found in the web. -+ -+ <P>If you have any problems with this release of Pine, please contact -+ Eduardo Chappa <chappa@math.washington.edu>. Include the word -+ "Pine" in the subject of the message to bypass spam filters. -+ -+ <P>The list of patches included in this release are: -+ -+ <P>New Features: -+ -+ <UL> -+ <LI> Maildir Patch. <A HREF="h_config_maildir">(more...)</A> -+ <LI> Enhanced fancy thread interface. -+ <A HREF="h_config_enhanced_thread">(more...)</A> -+ <LI> Pine justifies paragraphs with more than one level of indentation. -+ <A HREF="h_compose_justify">(more...)</A> -+ <LI> Rules patch, to make Pine flexible. -+ <A HREF="h_config_new_rules">(more...)</A> -+ <LI> Send mail from the command line. -+ <LI> Automatic check of new mail in incoming folders. -+ <A HREF="h_config_enable_check_incoming">(more...)</A> -+ <LI> Write accents like áé or other foreing characters: ñ etc. -+ <LI> Tab check folders on cycles. -+ <A HREF="h_config_circular_tab">(more...)</A> -+ <LI> Get the number of new messages when opening a folder. -+ <LI> Reinsert the pattern you searched for last. -+ <LI> New Reply command menu. -+ <A HREF="h_config_alt_reply_menu">(more...)</A> -+ <LI> Change your From header without any effort! -+ <LI> Choose a role when composing a message from a mailto: link. -+ <LI> Paint special text in the body of the message in any custom color. -+ <A HREF="h_config_special_text_to_color">(more...)</A> -+ <LI> Select messages by the content of an arbitrary header. -+ <LI> Delete until the the end of a file, or message (press ^W^X). -+ <LI> Get the QUOTA information from an IMAP server (if such server supports -+ the QUOTA command). -+ </UL> -+ <P> Bug Fixes: -+ <UL> -+ <LI> Fix a bug which could make the sort by score be computed incorrectly. -+ </UL> -+ -+ </body> -+ </html> - ====== h_news_legal ====== - <html> - <head> -*************** -*** 3091,3097 **** ---- 3148,3156 ---- - <li><a href="h_config_alt_role_menu">FEATURE: Alternate-Role-Menu</a> - <li><a href="h_config_force_low_speed">FEATURE: Assume-Slow-Link</a> - <li><a href="h_config_auto_read_msgs">FEATURE: Auto-Move-Read-Msgs</a> -+ <li><a href="h_config_auto_read_msgs_rules">FEATURE: auto-move-read-msgs-using-rules</a> - <li><a href="h_config_auto_open_unread">FEATURE: Auto-Open-Next-Unread</a> -+ <li><a href="h_config_circular_tab">FEATURE: enable-circular-tab</a> - <li><a href="h_config_auto_unzoom">FEATURE: Auto-Unzoom-After-Apply</a> - <li><a href="h_config_auto_zoom">FEATURE: Auto-Zoom-After-Select</a> - <li><a href="h_config_check_mail_onquit">FEATURE: Check-Newmail-When-Quitting</a> -*************** -*** 3349,3354 **** ---- 3408,3414 ---- - <li><a href="h_config_abook_formats">OPTION: Addressbook-Formats</a> - <li><a href="h_config_alt_addresses">OPTION: Alt-Addresses</a> - <li><a href="h_config_char_set">OPTION: Character-Set</a> -+ <li><a href="h_config_special_text_to_color">OPTION: Special Text to Color</a> - <li><a href="h_config_color_style">OPTION: Color-Style</a> - <li><a href="h_config_composer_wrap_column">OPTION: Composer-Wrap-Column</a> - <li><a href="h_config_index_color_style">OPTION: Current-Indexline-Style</a> -*************** -*** 3449,3457 **** ---- 3509,3519 ---- - <li><a href="h_config_sending_filter">OPTION: Sending-Filters</a> - <li><a href="h_config_sendmail_path">OPTION: Sendmail-Path</a> - <li><a href="h_config_signature_color">OPTION: Signature Color</a> -+ <li><a href="h_config_special_text_color">OPTION: Special Text Color</a> - <li><a href="h_config_signature_file">OPTION: Signature-File</a> - <li><a href="h_config_smtp_server">OPTION: SMTP-Server</a> - <li><a href="h_config_sort_key">OPTION: Sort-Key</a> -+ <li><a href="h_config_thread_sort_key">OPTION: Thread-Sort-Key</a> - <li><a href="h_config_speller">OPTION: Speller</a> - <li><a href="h_config_sshcmd">OPTION: Ssh-Command</a> - <li><a href="h_config_ssh_open_timeo">OPTION: Ssh-Open-Timeout</a> -*************** -*** 5297,5302 **** ---- 5359,5517 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ======= h_thread_index_sort_arrival ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Arrival</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Arrival</H1> -+ -+ The <EM>Arrival</EM> sort option arranges threads according to the last -+ time that a message was added to it. In this order the last thread -+ contains the most recent message in the folder. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_date ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Date</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Date</H1> -+ -+ The <EM>Date</EM> sort option in the THREAD INDEX screen is the same -+ as sorting by thread, the most likely thing is that you won't see Pine -+ sorting the folder, because it's already sorted. -+ -+ <P> -+ On a folder like INBOX, sorting by "Date" should be almost -+ identical to sorting by "Arrival". -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_subj ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Subject</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Subject</H1> -+ -+ The <EM>Subject</EM> sort option has not been defined yet. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_ordsubj ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: OrderedSubject</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: OrderedSubject</H1> -+ -+ The <EM>OrderedSubject</EM> sort option in the THREAD INDEX screen is -+ the same as sorting by <A HREF="h_thread_index_sort_subj">Subject</A>. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_thread ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Thread</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Thread</H1> -+ -+ The <EM>Thread</EM> sort option in the THREAD INDEX screen sorts all -+ messages by the proposed algorithm by Crispin and Murchison. In this -+ method of sorting once threads have been isolated they are sorted by the -+ date of their parents, or if that is missing, the first message in that -+ thread. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_from ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: From</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: From</H1> -+ -+ The <EM>From</EM> sort option has not been defined yet. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_size ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Size</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Size</H1> -+ -+ The <EM>Size</EM> sort option has not been defined yet. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_score ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Score</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Score</H1> -+ -+ The <EM>Score</EM> sort option has not been defined yet. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_to ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: To</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: To</H1> -+ -+ The <EM>To</EM> sort option has not been defined yet. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_cc ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Cc</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Cc</H1> -+ -+ The <EM>Cc</EM> sort option has not been defined yet. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ======= h_index_cmd_whereis ======= - <HTML> - <HEAD> -*************** -*** 6515,6520 **** ---- 6730,6775 ---- - not preserved. - - <P> -+ This version of Pine contains an enhanced algorithm for justification, -+ which allows you to justify text that contains more complicated quote -+ strings. This algorithm is based on pragmatics, rather than on a theory, -+ and seems to work well with most messages. Below you will find technical -+ information on how this algorithm works. -+ -+ <P> -+ When justifying, Pine goes through each line of the text and tries to -+ determine for each line what the quote string of that line is. The quote -+ string you provided is always recognized. Among other characters -+ recognized is ">". -+ -+ <P> -+ Some other constructions of quote strings are recognized only if they -+ appear enough in the text. For example "Peter :" is only -+ recognized if it appears in two consecutive lines. -+ -+ <P> -+ Additionaly, Pine recognizes indent-strings and justifies text in a -+ paragraph to the right of indent-string, padding with spaces if necessary. -+ An indent string is one which you use to delimit elements of a list. For -+ example, if you were to write a list of groceries, one may write: -+ -+ <UL> -+ <LI> Fruit -+ <LI> Bread -+ <LI> Eggs -+ </UL> -+ -+ <P> -+ In this case the character "*" is the indent-string. Pine -+ recognizes numbers (0, 1, 2.5, etc) also as indent-strings, and certain -+ combinations of spaces, periods, and parenthesis. In any case, numbers are -+ recognized <B>ONLY</B> if the line preceeding the given line is empty or -+ ends in one of the characters "." or ":". -+ In addition to the explanation of what constitutes a paragraph above, a -+ new paragraph is recognized when an indent-string is found in it (and -+ validated according to the above stated rules). -+ -+ <P> - <End of help on this topic> - </BODY> - </HTML> -*************** -*** 17318,17323 **** ---- 17573,17579 ---- - <A HREF="h_config_index_format">"Index-Format"</A> option, - in the <A HREF="h_config_reply_intro">"Reply-Leadin"</A> option, - in signature files, -+ in the <A HREF="h_config_reply_leadin_rules">"new-rules" option</A>, - in template files used in - <A HREF="h_rules_roles">"roles"</A>, and in the folder name - that is the target of a Filter Rule. -*************** -*** 17330,17336 **** - <P> - <P> - -! <H1><EM>Tokens Available for all Cases (except Filter Rules)</EM></H1> - - <DL> - <DT>SUBJECT</DT> ---- 17586,17592 ---- - <P> - <P> - -! <H1><EM>Tokens Available for all Cases (except Filter Rules or in some cases for new-rules)</EM></H1> - - <DL> - <DT>SUBJECT</DT> -*************** -*** 17352,17357 **** ---- 17608,17622 ---- - For example, "mailbox@domain". - </DD> - -+ <DT>ADDRESSTO</DT> -+ <DD> -+ This is similar to the "TO" token, only it is always the -+ email address of all people listed in the TO: field of the messages. Addresses -+ are separated by a blank space. Example, "mailbox@domain" when -+ the e-mail message contains only one person in the To: field, or -+ "peter@flintstones.com president@world.com". -+ </DD> -+ - <DT>MAILBOX</DT> - <DD> - This is the same as the "ADDRESS" except that the -*************** -*** 17399,17404 **** ---- 17664,17678 ---- - message's "Cc:" header field. - </DD> - -+ <DT>ADDRESSCC</DT> -+ <DD> -+ This is similar to the "CC" token, only it is always the -+ email address of all people listed in the Cc: field of the messages. Addresses -+ are separated by a blank space. Example: "mailbox@domain" when -+ the e-mail message contains only one person in the Cc: field, or -+ "peter@flintstones.com president@world.com". -+ </DD> -+ - <DT>RECIPS</DT> - <DD> - This token represents the personal names (or email addresses if the names -*************** -*** 17407,17412 **** ---- 17681,17694 ---- - the message's "Cc:" header field. - </DD> - -+ <DT>ADDRESSRECIPS</DT> -+ <DD> -+ This token represent the e-mail addresses of the people in the To: and -+ Cc: fields, exactly in that order separated by a space. It is almost obtained -+ by concatenating the ADDRESSTO and ADDRESSCC tokens. -+ </DD> -+ -+ - <DT>NEWSANDRECIPS</DT> - <DD> - This token represents the newsgroups from the -*************** -*** 17779,17784 **** ---- 18061,18074 ---- - <P> - </DD> - -+ <DT>SIZETHREAD</DT> -+ <DD> -+ This token represents the total size of the thread for a collapsed thread -+ or the size of the branch for an expanded thread. The field is omitted for -+ messages that are not top of threads nor branches and it defaults to -+ the SIZE token when your folders is not sorted by thread. -+ </DD> -+ - <DT>SIZENARROW</DT> - <DD> - This token represents the total size, in bytes, of the message. -*************** -*** 18134,18139 **** ---- 18424,18501 ---- - </DL> - - <P> -+ <H1><EM>Tokens Available Only for New-Rules</EM></H1> -+ -+ <DL> -+ <DT>FOLDER</DT> -+ <DD> -+ Name of the folder where the rule will be applied -+ </DD> -+ </DL> -+ -+ <DL> -+ <DT>COLLECTION</DT> -+ <DD> -+ Name of the collection list where the rule will be applied. -+ </DD> -+ </DL> -+ -+ <DL> -+ <DT>ROLE</DT> -+ <DD> -+ Name of the Role used to reply a message. -+ </DD> -+ </DL> -+ -+ <DL> -+ <DT>BCC</DT> -+ <DD> -+ Not implemented yet, but it will be implemented in future versions. It will -+ be used for <A HREF="h_config_compose_rules">compose</A> -+ <A HREF="h_config_reply_rules">reply</A> -+ <A HREF="h_config_forward_rules">forward</A> -+ rules. -+ </DD> -+ </DL> -+ -+ <DL> -+ <DT>LCC</DT> -+ <DD> -+ This is the value of the Lcc: field at the moment that you start the composition. -+ </DD> -+ </DL> -+ -+ <DL> -+ <DT>FORWARDFROM</DT> -+ <DD> -+ This corresponds to the personal name (or address if there's no personal -+ name) of the person who sent the message that you are forwarding. -+ </DD> -+ </DL> -+ -+ <DL> -+ <DT>FORWARDADDRESS</DT> -+ <DD> -+ This is the address of the person that sent the message that you -+ are forwarding. -+ </DD> -+ </DL> -+ -+ -+ -+ -+ <DL> -+ <DT>FLAG</DT> -+ <DD> -+ A string containing the value of all the flags associated to a specific -+ message. The possible values of allowed flags are "*" for Important, "N" -+ for recent or new, "U" for unseen or unread, "R" for seen or read, "A" for -+ answered and "D" for deleted. See an example of its use in the -+ <A HREF="h_config_new_rules">new rules</A> explanation and example help. -+ </DD> -+ </DL> -+ -+ <P> - <H1><EM>Token Available Only for Templates and Signatures</EM></H1> - - <DL> -*************** -*** 18866,18871 **** ---- 19228,19250 ---- - be combined with the other fields if you'd like. - - <End of help on this topic> -+ ====== h_config_check_inc_fld ====== -+ <HTML> -+ <HEAD> -+ <TITLE>OPTION: incoming-folders-to-check</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>OPTION: incoming-folders-to-check</H1> -+ <P> -+ if you set this option and <A HREF="h_config_enable_check_incoming"> -+ enable-check-incoming-folders</A> then you can use this option to write a space -+ separate list of incoming folders where you want new mail to be -+ checked. If you want all your incoming folders to be checked just write a -+ "*" as the value for this option. -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ======= h_address_format ======= - <HTML> - <HEAD> -*************** -*** 19988,20048 **** - <End of help on this topic> - </BODY> - </HTML> -! ====== h_config_literal_sig ===== - <HTML> - <HEAD> -! <TITLE>OPTION: Literal-Signature</TITLE> - </HEAD> - <BODY> -! <H1>OPTION: Literal-Signature</H1> - -- With this option your actual signature, as opposed to -- the name of a file containing your signature, -- is stored in the Pine configuration file. -- If this is defined it takes precedence over the Signature-File option. - <P> - -- This is simply a different way to store the signature. -- The signature is stored inside your Pine configuration file instead of in -- a separate file. -- Tokens work the same way they do with the -- <A HREF="h_config_signature_file">Signature-File</A> so look there for -- help. - <P> - -- The Setup/Signature command on Pine's Main Menu will edit -- the "Literal-Signature" by default. However, if no -- "Literal-Signature" is defined and the file named in the -- "Signature-File" option exists, then the latter will be used -- instead. - <P> -! -! The two character sequence \n (backslash followed by -! the character n) will be used to signify a line-break in your signature. -! You don't have to enter the \n, but it will be visible in the -! SETUP CONFIGURATION window after you are done editing the signature. - - <P> -! <UL> - <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -! </UL><P> - <End of help on this topic> - </BODY> - </HTML> -! ====== h_config_signature_file ===== - <HTML> - <HEAD> -! <TITLE>OPTION: Signature-File</TITLE> - </HEAD> - <BODY> -! <H1>OPTION: Signature-File</H1> - -! If a <A HREF="h_config_literal_sig">Literal-Signature</A> option is defined, -! then this "Signature-File" option will be ignored. -! You can tell that that is the case because the value of the -! "Signature-File" will show up as - <P> -! <CENTER><SAMP><Ignored: using Literal-Signature instead></SAMP></CENTER> - <P> - You may either use all Literal Signatures (signatures stored in your - configuration file) throughout Pine, or all signature files. ---- 20367,20523 ---- - <End of help on this topic> - </BODY> - </HTML> -! ====== h_config_maildir_location ====== - <HTML> - <HEAD> -! <TITLE>OPTION: maildir-location</TITLE> - </HEAD> - <BODY> -! <H1>OPTION: maildir-location</H1> - - <P> -+ This option should be used only if you have a Maildir folder which you -+ want to use as your INBOX. If this is not your case (or don't know what -+ this is), you can safely ignore this option. - - <P> -+ This option overrides the default directory Pine uses to find the location of -+ your INBOX, in case this is in Maildir format. The default value of this -+ option is "Maildir", but in some systems, this directory could have been -+ renamed (e.g. to ".maildir"). If this is your case use this option to change -+ the default. - - <P> -! The value of this option is prefixed with the "~/" string to determine the -! full path to your INBOX. - - <P> -! You should probably <A HREF="h_config_maildir">read</A> a few tips that -! teach you how to configure your maildir for optimal performance. This -! version also has <A HREF="h_config_courier_list">support</A> for the -! Courier style file system when a maildir collection is accessed locally. -! -! <P><UL> - <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -! </UL> -! <P> - <End of help on this topic> - </BODY> - </HTML> -! ====== h_config_maildir ===== - <HTML> - <HEAD> -! <TITLE>Maildir Support</TITLE> - </HEAD> - <BODY> -! <H1>Maildir Support</H1> - -! This version of Pine has been enhanced with Maildir support. This text is -! intended to be a reference on its support. - <P> -! -! A Maildir folder is a directory that contains three directories called -! cur, tmp and new. A program that delivers mail (e.g. postfix) will put new -! mail in the new directory. A program that reads mail will look for for old -! messages in the cur directory, while it will look for new mail in the new -! directory. -! <P> -! -! In order to use maildir support it is better to set your inbox-path to the -! value "#md/inbox" (without quotes). This assumes that your mail -! delivery agent is delivering new mail to ~/Maildir/new. If the directory -! where new mail is being delivered is not called "Maildir", you can set the -! name of the subdirectory of home where it is being delivered in the <A -! HREF="h_config_maildir_location">maildir-location</A> configuration -! variable. Most of the time you will not have to worry about the -! maildir-location variable, because it will probably be set by your -! administrator in the pine.conf configuration file. -! <P> -! -! One of the advantages of the Maildir support of this version of Pine is -! that you do not have to stop using folders in another styles (mbox, mbx, -! etc.). This is desirable since the usage of a specific mail storage system -! is a personal decision. Folders in the maildir format that are part of the -! Mail collection will be recognized without any extra configuration of your -! part. If your mail/ collection is located under the mail/ directory, then -! creating a new maildir folder in this collection is done by pressing "A" -! and entering the string "#driver.md/mail/newfolder". Observe that adding a -! new folder as "newfolder" may not create such folder in maildir format. -! -! <P> -! If you would like to have all folders created in the maildir format by -! default, you do so by adding a Maildir Collection. In order to convert -! your current mail/ collection into a maildir collection, edit the -! collection and change the path variable from "mail/" to -! "#md/mail". In a maildir collection folders of any other format -! are ignored. -! -! <P> Finally, This version also has -! <A HREF="h_config_courier_list">support</A> for the Courier style file system -! when a maildir collection is accessed locally. -! -! <P> -! <UL> -! <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -! </UL><P> -! <End of help on this topic> -! </BODY> -! </HTML> -! ====== h_config_literal_sig ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: Literal-Signature</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: Literal-Signature</H1> -! -! With this option your actual signature, as opposed to -! the name of a file containing your signature, -! is stored in the Pine configuration file. -! If this is defined it takes precedence over the Signature-File option. -! <P> -! -! This is simply a different way to store the signature. -! The signature is stored inside your Pine configuration file instead of in -! a separate file. -! Tokens work the same way they do with the -! <A HREF="h_config_signature_file">Signature-File</A> so look there for -! help. -! <P> -! -! The Setup/Signature command on Pine's Main Menu will edit -! the "Literal-Signature" by default. However, if no -! "Literal-Signature" is defined and the file named in the -! "Signature-File" option exists, then the latter will be used -! instead. -! <P> -! -! The two character sequence \n (backslash followed by -! the character n) will be used to signify a line-break in your signature. -! You don't have to enter the \n, but it will be visible in the -! SETUP CONFIGURATION window after you are done editing the signature. -! -! <P> -! <UL> -! <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -! </UL><P> -! <End of help on this topic> -! </BODY> -! </HTML> -! ====== h_config_signature_file ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: Signature-File</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: Signature-File</H1> -! -! If a <A HREF="h_config_literal_sig">Literal-Signature</A> option is defined, -! then this "Signature-File" option will be ignored. -! You can tell that that is the case because the value of the -! "Signature-File" will show up as -! <P> -! <CENTER><SAMP><Ignored: using Literal-Signature instead></SAMP></CENTER> - <P> - You may either use all Literal Signatures (signatures stored in your - configuration file) throughout Pine, or all signature files. -*************** -*** 20750,20755 **** ---- 21225,21265 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_thread_sort_key ===== -+ <HTML> -+ <HEAD> -+ <TITLE>OPTION: Thread-Sort-Key</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>OPTION: Thread-Sort-Key</H1> -+ -+ This option determines the order in which threads will be displayed. You -+ can choose from the following options. -+ -+ <P> -+ <UL> -+ <LI> <A HREF="h_thread_index_sort_arrival">Arrival</A> -+ <!-- <LI> <A HREF="h_thread_index_sort_date">Date</A> -+ <LI> <A HREF="h_thread_index_sort_subj">Subject</A> -+ <LI> <A HREF="h_thread_index_sort_ordsubj">OrderedSubj</A>--> -+ <LI> <A HREF="h_thread_index_sort_thread">Thread</A> -+ <!-- <LI> <A HREF="h_thread_index_sort_from">From</A> -+ <LI> <A HREF="h_thread_index_sort_size">Size</A> -+ <LI> <A HREF="h_thread_index_sort_score">Score</A> -+ <LI> <A HREF="h_thread_index_sort_to">To</A> -+ <LI> <A HREF="h_thread_index_sort_cc">Cc</A>--> -+ </UL> -+ -+ <P> Each type of sort may also be reversed. Normal default is by -+ "Thread". -+ -+ <P> -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL><P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_other_startup ===== - <HTML> - <HEAD> -*************** -*** 20866,20898 **** - This option controls the order in which address book entries will be - presented. Choose one of the following: - -! <DL> -! <DT>fullname</DT> -! <DD>use fullname field, lists mixed in -! </DD> - -! <DT>fullname-with-lists-last</DT> -! <DD>use fullname field, but put lists at end -! </DD> - -! <DT>nickname</DT> -! <DD>use nickname field, lists mixed in -! </DD> - -! <DT>nickname-with-lists-last</DT> -! <DD>use nickname field, but put lists at end -! </DD> - -! <DT>dont-sort</DT> -! <DD>don't change order of file -! </DD> -! </DL> - - <P> -! The normal default is "fullname-with-lists-last". - - <P> -! <UL> - <LI><A HREF="h_finding_help">Finding more information and requesting help</A> - </UL><P> - <End of help on this topic> ---- 21376,22052 ---- - This option controls the order in which address book entries will be - presented. Choose one of the following: - -! <DL> -! <DT>fullname</DT> -! <DD>use fullname field, lists mixed in -! </DD> -! -! <DT>fullname-with-lists-last</DT> -! <DD>use fullname field, but put lists at end -! </DD> -! -! <DT>nickname</DT> -! <DD>use nickname field, lists mixed in -! </DD> -! -! <DT>nickname-with-lists-last</DT> -! <DD>use nickname field, but put lists at end -! </DD> -! -! <DT>dont-sort</DT> -! <DD>don't change order of file -! </DD> -! </DL> -! -! <P> -! The normal default is "fullname-with-lists-last". -! -! <P> -! <UL> -! <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -! </UL><P> -! <End of help on this topic> -! </BODY> -! </HTML> -! ====== h_config_compose_rules ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: Compose-Rule</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: Compose-Rule</H1> -! -! <P> At this time, this option is used to generate values for signature -! files that is not possible to do with the use of -! <A HREF="h_rules_roles">roles</A>. -! -! <P> For example, you can have a rule like:<BR> -! _TO_ >> {Peter Flinstones} => _SIGNATURE_{~/.petersignature} -! -! <P> This configuration option is just one of many that allow you to -! override the value of some global configurations within Pine. There is a -! help text explaining how to define all of them, which you can read by -! following this <A HREF="h_config_new_rules">link</A>. -! -! <P><End of help on this topic> -! </BODY> -! </HTML> -! ====== h_config_forward_rules ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: Forward-Rule</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: Forward-Rule</H1> -! -! <P> At this time this option can be used to trim values of some fields, -! for example it can be used in the following way: -! -! <P> -! _ROLE_ == {work} => _LCC_ := _TRIM_{_FORWARDFROM_ <_FORWARDADDRESS_>} -! -! <P> This configuration option is just one of many that allow you to -! override the value of some global configurations within Pine. There is a -! help text explaining how to define all of them, which you can read by -! following this <A HREF="h_config_new_rules">link</A>. -! -! <P><End of help on this topic> -! </BODY> -! </HTML> -! ====== h_config_index_rules ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: Index-Rule</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: Index-Rule</H1> -! -! <P> This option is used to supercede the value of the option <A -! HREF="h_config_index_format">index-format</A> for specific folders. In -! this form you can have different index-formats for different folders. For -! example an entry here may be: -! -! <P> -! _FOLDER_ == {INBOX} => _INDEX_{IMAPSTATUS DATE FROM(33%) SIZE SUBJECT(67%)} -! -! <P> This configuration option is just one of many that allow you to -! override the value of some global configurations within Pine. There is a -! help text explaining how to define all of them, which you can read by -! following this <A HREF="h_config_new_rules">link</A>. -! -! <P><End of help on this topic> -! </BODY> -! </HTML> -! ====== h_config_replace_rules ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: Replace-Rule</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: Replace-Rule</H1> -! -! <P> This option is used to have Pine print different values for specific -! tokens in the <A HREF="h_config_index_format">index-format</A>. For example you -! can replace strings like "To: newsgroup" by your name. -! -! <P> Here are examples of possible rules:<BR> -! _FOLDER_ != {sent-mail} && _NICK_ != {} => _FROM_ := _REPLACE_{_FROM_ (_NICK_)} -! -! <P> or if you receive messages with tags that contain arbitrary numbers, and -! you want them removed from the index (but not from the subject), use a rule -! like the following<BR> -! _FOLDER_ == {INBOX} => _SUBJECT_ := _REXTRIM_{\[some-tag-here #[0-9].*\]} -! -! <P> You can also use this configuration option to remove specific strings of -! the index display screen, so that you can trim unnecessary information in -! your index. -! -! <P> This configuration option is just one of many that allow you to -! override the value of some global configurations within Pine. There is a -! help text explaining how to define all of them, which you can read by -! following this <A HREF="h_config_new_rules">link</A>. -! -! <P><End of help on this topic> -! </BODY> -! </HTML> -! ====== h_config_reply_leadin_rules ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: Reply-Leadin-Rule</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: Reply-Leadin-Rule</H1> -! -! <P> This option is used to have Pine generate a different -! <A HREF="h_config_reply_intro">reply-leadin</A> string dependent either on -! the person you are replying to, or the folder where the message is being -! replied is in, or both. -! -! <P> Here there are examples of how this can be used. One can use the definition -! below to post to newsgroups and the pine-info mailing list, say: -! <P> -! _FOLDER_ << {pine-info;_NEWS_} => _REPLY_{*** _FROM_ _ADDRESS_("_FROM_" "" "(_ADDRESS_) ")wrote in_NEWS_("" " the" "") _FOLDER_ _NEWS_("" "list " "")_SMARTDATE_("Today" "today" "on _LONGDATE_"):} -! -! <P> Here there is an example that one can use to change the reply indent string -! to reply people that speak spanish. -! <P> -! _FROM_{Condorito;Quico} => _REPLY_{*** _FROM_ (_ADDRESS_) escribió _SMARTDATE_("Today" "hoy" "en _LONGDATE_"):} -! -! <P> This configuration option is just one of many that allow you to -! override the value of some global configurations within Pine. There is a -! help text explaining how to define all of them, which you can read by -! following this <A HREF="h_config_new_rules">link</A>. -! -! <P><End of help on this topic> -! </BODY> -! </HTML> -! ====== h_config_resub_rules ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: Replace-Subject-Rule</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: Replace-Subject-Rule</H1> -! -! <P> This option is used to have Pine generate a different subject when -! replying rather than the one Pine would generate automatically. -! -! <P> Here there are a couple of examples about how to use this -! configuration option: -! -! <P> In order to have messages with empty subject to be replied with the message -! "your message" use the rule<BR> -! <center>_SUBJECT_ == {} => _RESUB_{Re: your message}</center> -! -! <P> If you want to trim some parts of the subject when you reply use the -! rule<BR> -! <center>_SUBJECT_ >> {[one];two} => _SUBJECT_ := _TRIM_{[;];two}</center> -! -! <P>this rule removes the brackets "[" and "]" whenever the string "[one]" -! appears in it, it also removes the word "two" from it. -! -! <P>Another example where you may want to use this rule is when you -! correspond with people that change the reply string from "Re:" -! to "AW:" or "Sv:". In this case a rule like<BR> -! <center>_SUBJECT_ >> {Sv: ;AW: } => _SUBJECT_ := _TRIM_{Sv: ;AW: }</center> -! <P> -! would eliminate undesired strings in replies. -! -! <P> You can also use this configuration option to customize reply subjects -! according to the sender of the message. -! -! <P> This configuration option is just one of many that allow you to -! override the value of some global configurations within Pine. There is a -! help text explaining how to define all of them, which you can read by -! following this <A HREF="h_config_new_rules">link</A>. -! -! <P><End of help on this topic> -! </BODY> -! </HTML> -! ====== h_config_sort_rules ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: Sort-Rule</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: Sort-Rule</H1> -! -! <P> This option is used to have Pine sort different folders in different orders -! and thus override the value already set in the -! <A HREF="h_config_sort_key">sort-key</A> configuration option. -! -! <P> Here's an example of the way it can be used. In this case all incoming -! folders are mailing lists, except for INBOX, so we sort INBOX by arrival -! (which is the default type of sort), but we want all the rest of mailing -! lists and newsgroups to be sorted by thread. -! -! <P> -! _COLLECTION_ >> {Incoming-Folders;News} && _FOLDER_ != {INBOX} => _SORT_{tHread} -! -! <P> Another example could be<BR> -! _FOLDER_ == {Mailing List} => _SORT_{Reverse tHread} -! -! <P> This configuration option is just one of many that allow you to -! override the value of some global configurations within Pine. There is a -! help text explaining how to define all of them, which you can read by -! following this <A HREF="h_config_new_rules">link</A>. -! -! <P><End of help on this topic> -! -! </BODY> -! </HTML> -! ====== h_config_save_rules ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: Save-Rules</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: Save-Rules</H1> -! -! <P> This option is used to specify which folder should be used to save a -! message depending either on the folder the message is in, who the message -! is from, or text that the message contains in specific headers (Cc:, -! Subject:, etc). -! -! <P> If this option is set and the -! <A HREF="h_config_auto_read_msgs">auto-move-read-msgs</A> configuration -! option is also set then these definitions will be used to move messages -! from your INBOX when exiting Pine. -! -! <P>Here there are some examples<BR> -! _FLAG_ >> {D} -> Trash<BR> -! _FROM_ == {U2} -> Bono<BR> -! _FOLDER_ == {comp.mail.pine} -> pine-stuff<BR> -! _NICK_ != {} -> _NICK_/_NICK_<BR> -! _DATEISO_ >> {02-10;02-11} -> archive-oct-nov-2002 -! -! <P> This configuration option is just one of many that allow you to -! override the value of some global configurations within Pine. There is a -! help text explaining how to define all of them, which you can read by -! following this <A HREF="h_config_new_rules">link</A>. -! -! <P><End of help on this topic> -! -! </BODY> -! </HTML> -! ====== h_config_reply_indent_rules ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: Reply-indent-Rule</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: Reply-indent-Rule</H1> -! -! <P> This option is used to specify which reply-indent-string is to be used -! when replying to an e-mail. If none of the rules are successful, the result in -! the variable <a href="h_config_reply_indent_string">reply-indent-string</a> -! is used. -! -! <P> The associated function to this configuration option is called "RESTR" (for -! REply STRing). Some examples of its use are:<BR> -! _FROM_ == {Your Boss} => _RESTR_{"> "}<BR> -! _FROM_ == {My Wife} => _RESTR_{":* "}<BR> -! _FROM_ == {Perter Flinstone;Wilma Flinstone} => _RESTR_{"_INIT_ > "}<BR> -! -! <P> This configuration option is just one of many that allow you to -! override the value of some global configurations within Pine. There is a -! help text explaining how to define all of them, which you can read by -! following this <A HREF="h_config_new_rules">link</A>. -! -! <P><End of help on this topic> -! -! </BODY> -! </HTML> -! ====== h_config_smtp_rules ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: SMTP-Rule</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: SMTP-Rule</H1> -! -! <P> This option is used to specify which SMTP server should be used when -! sending a message, if this rule is not defined, or the execution of the rule -! results in no server selected, then Pine will look for -! the value from the role that is being used to compose the message. If no smtp -! server is defined in that role or you are not using a role, then Pine will get -! the name of the server from the -! <A HREF="h_config_smtp_server">"smtp-server"</A> configuration -! option according to the rules used in that variable. -! -! <P> The function associated to this configuration option is _SMTP_, an example -! of the use of this function is<BR> -! _ADDRESSTO_ == {peter@bedrock.com} => _SMTP_{smtp.bedrock.com} -! -! <P> This configuration option is just one of many that allow you to -! override the value of some global configurations within Pine. There is a -! help text explaining how to define all of them, which you can read by -! following this <A HREF="h_config_new_rules">link</A>. -! -! <P><End of help on this topic> -! -! </BODY> -! </HTML> -! ====== h_config_startup_rules ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: Startup-Rule</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: Startup-Rule</H1> -! -! <P> This option is used when a folder is being opened. You can use it to -! specify its <A HREF="h_config_inc_startup">incoming-startup-rule</A> and override -! Pine's global value set for all folders. -! -! <P> An example of the usage of this option is:<BR> -! _FOLDER_ == {Lynx;pine-info;_NEWS_} => _STARTUP_{first-unseen} -! -! <P> This configuration option is just one of many that allow you to -! override the value of some global configurations within Pine. There is a -! help text explaining how to define all of them, which you can read by -! following this <A HREF="h_config_new_rules">link</A>. -! -! <P><End of help on this topic> -! -! </BODY> -! </HTML> -! ====== h_config_new_rules ===== -! <HTML> -! <HEAD> -! <TITLE>OPTION: New Rules Explained</TITLE> -! </HEAD> -! <BODY> -! <H1>OPTION: New Rules Explained</H1> -! -! This is a quite powerful option. Here you can define rules that override -! the values of any other global rule you have globally set in pine. -! -! <P> -! For example, you can set your folders to be sorted in a certain way when -! you open them (say by Arrival). You may not want to be this the behavior -! of, say, a Newsgroup, maybe you would like there to have your folder to be -! automatically ordered by Ordered Subject. The purpose of this feature is -! to accomplish exactly that. You can use this option for defining such -! exception and make Pine automatically sort your favorite Newsgroup by -! Ordered Subject. -! -! <P> -! On the other hand you may be suscribed to a mailing list, and maybe you -! don't care to see in the index the size of the messages, however in other -! lists you may want to see the size of the messages. You can use this -! configuration for changing the way the index is displayed in a folder. -! -! <P> -! Also there may be a mailing list that identifies itself by adding a -! certain string to its subject which makes difficult to read the total -! subject, so you may want to delete that string from the subject whenever -! it appears. You can do that also with this configuration. -! -! <P> -! You may also want to make your reply-leadin-string person or folder -! dependent. You can do this with this feature (part of this feature can be -! accomplised with the roles definitions, but roles are not the right tool -! to do this as you will see). -! -! <P> -! Every rule has three parts, a condition, a separator and an action. The -! action is what will happen if the condition of the rule is satisified. -! -! <P> -! Here is an example: -! -! <P> -! _FROM_ == {Fred Flinstone} => _SAVE_{Fred} -! -! <P> -! Here the separator is "=>". Whatever is to the left of the separator -! is the condition (that is to say _FROM_ == {Fred Flinstone}) and to the -! right is the action (_SAVE_{Fred}). The condition means that the rule will -! be applied only if the message that you are reading is from "Fred -! Flinstone", and the action will be that you will be offered to save it in -! the folder "Fred", whenever you press the letter "S" to save a message. -! -! <P> -! The separator is always "=>", with one exception to be seen later. -! But for the most part this will be the only one you'll ever need. -! -! <P> -! Now let us see how to do it. There are 12 functions already defined for -! you. These are: _INDEX_, _REPLACE_, _REPLY_, _RESUB_, _SAVE_, _SIGNATURE_, -! _SORT_, _STARTUP_, _TRIM_, _REXTRIM_, _THREADSTYLE and _THREADINDEX_. The -! parameter of a function has to be enclosed between "{" and "}", so for -! example you can specify _SAVE_{saved-messages} as a valid sentence. -! -! <P> -! At the end of the document you will find more examples.Here is a short -! description of what each function does: -! -! <P> -! <UL> -! <LI> _INDEX_ : This function takes as an argument an index-format, and -! makes that the index-format for the specified folder. -! <LI> _REPLACE_ : This function replaces the subject/from of the given e-mail by -! another subject/from only when displaying the index. -! <LI> _REPLY_ : This function takes as an argument a definition of a -! reply-leadin-string and makes this the reply-leading-string of the -! specified folder or person. -! <LI> _RESTR_ : This function takes as an argument the value of the -! reply-indent-string to be used to answer the message being replied to. -! <LI> _RESUB_ : This function replaces the subject of the given e-mail by -! another subject only when replying to a message. -! <LI> _SAVE_ : The save function takes as an argument the name of a -! possibly non existing folder, whenever you want to save a message, that -! folder will be offered for you to save. -! <LI> _SIGNATURE_ : This function takes as an argument a signature file and -! uses that file as the signature for the message you are about to -! compose/reply/forward. -! <LI> _SMTP_ : This function takes as an argument the definition of a -! SMTP server. -! <LI> _SORT_ : This function takes as an argument a Sort Style, and sorts a -! specified folder in that sort order. -! <LI> _TRIM_ : This function takes as an argument a list of strings that -! you want removed from another string. At this time this only works for -! _FROM_ and _SUBJECT_. -! <LI> _REXTRIM_ : Same as _TRIM_ but its argument is one and -! only one extended regular expression. -! <LI> _STARTUP_ : This function takes as an argument an -! incoming-startup-rule, and open an specified folder using that rule. -! <LI> _THREADSTYLE_ : This function takes as an argument a -! threading-display-style and uses it to display threads in a folder. -! <LI> _THREADINDEX_ : This function takes as an argument a -! threading-index-style and uses it to display threads in a folder. -! </UL> -! -! <P> -! You must me wondering how to define the person/folder over who to apply -! the action. This is done in the condition. When you specify a rule, the -! rule is only executed if the condition is satisfied. In another words for -! the rule: -! -! <P> -! _FROM_ == {Fred Flinstone} => _SAVE_{Fred} -! -! <P> -! it will only be applied if the from is "Fred Flinstone", if the From is -! "Wilma Flinstone" the rule will be skipped. -! -! <P> In order to test a condition you can use the following tokens (in -! alphabetical order): _ADDRESS_,_CC_, _FOLDER_, _FROM_,_NICK_, _ROLE, -! _SENDER_, _SUBJECT_ and _TO_. The token will always be tested against what -! it is between "{" and "}" in the condition, this part of the condition is -! called the "condition set". The definition of each token can be found -! <A HREF="h_index_tokens">here</A>. -! -! <P> -! You can also test in different ways, you can -! use the following "test operands": <<, !<, >>, !>, == -! and !=. All of them are two strings long. Here is the meaning of them: -! -! <P> -! <UL> -! <LI> << : It tests if the value of the token is contained in -! the condition set. Here for example if the condition set were equal to -! "Freddy", then the condition: _NICK_ << {Freddy}, would be true if -! the value of _NICK_ were "Fred", "red" or "Freddy". You are just looking -! for substrings here. -! <LI> >> : It tests if the value of the token contains the value of -! the condition set. Here for example if the condittion set were equal to -! "Fred", then the condition: _FROM_ >> {Fred}, would be true if -! the value of _FROM_ were "Fred Flinstone" or "Fred P. Flinstone" or "Freddy". -! <LI> == : It tests if the value of the token is exactly equal to the value -! of the set condition. For example _NICK_ == {Fred} will be false if the value -! of _NICK_ is "Freddy" or "red". -! <LI> !< : This is true only when << is false and viceversa. -! <LI> !> : This is true only when >> is false and viceversa. -! <LI> != : This is true only when == is false and viceversa. -! </UL> -! -! <P> -! Now let us say that you want the same action to be applied to more than -! one person or folder, say you want "folder1" and "folder2" to be sorted by -! Ordered Subject upon entering. Then you can list them all of them in the -! condition part separting them by a ";". Here is the way to do it. -! -! <P> -! _FOLDER_ << {folder1; folder2} => _SORT_{OrderedSubj} -! -! <P> -! Here is the first subtelty about these definitions. Notice that the -! following rule: -! -! <P> -! _FOLDER_ == {folder1; folder2} => _SORT_{Reverse OrderedSubj} -! -! <P> works only for "folder1" but not for "folder2". This is because the -! comparison of the name of the folder is done with whatever is in between -! "{", ";" or "}", so in the above rule you would be testing <BR> -! "folder2" == " folder2". The extra space makes the difference. -! The reason why the first rule does not fail is because -! "folder2" << " folder2" is actually -! true. If something ever fails this may be something to look into. -! -! <P> -! Here are a few examples of what we have talked about before. -! -! <P> -! _NICK_ == {lisa;kika} => _SAVE_{_NICK_/_NICK_} <BR> -! This means that if the nick is lisa, it will -! save the message in the folder "lisa/lisa", and if the nick -! is "kika", it will save the message in the folder "kika/kika" -! -! <P> -! _FOLDER_ == {Lynx} -> lynx <BR> -! This, is an abreviation of the following rule:<BR> -! _FOLDER_ == {Lynx} => _SAVE_{lynx} <BR> -! (note the change in separator from "=>" to "->"). In the future -! I will use that abreviation. -! -! <P> _FOLDER_ << {comp.mail.pine; pine-info; pine-alpha} -> pine <BR> -! Any message in the folders "comp.mail.pine", "pine-info" or "pine-alpha" -! will be saved to the folder "pine". -! -! <P> _FROM_ << {Pine Master} -> pine <BR> -! Any message whose From field contains -! "Pine Master" will be saved in the folder pine. -! -! <P> _FOLDER_ << {Lynx; pine-info; comp.mail.pine} => -! _INDEX_{IMAPSTATUS MSGNO DATE FROMORTO(33%) SUBJECT(66%)} <BR> Use a -! different index-format for the folders "Lynx", "pine-info" and -! "comp.mail.pine", where the size is not present. -! -! <P> _FOLDER_ == {Lynx;pine-info} => _REPLY_{*** _FROM_ (_ADDRESS_) -! wrote in the _FOLDER_ list _SMARTDATE_("Today" "today" "on -! _LONGDATE_"):}<BR> If a message is in one of the incoming folders "Lynx" -! or "pine-info", create a reply-leadin-string that acknowledges that. Note -! the absence of "," in the function _SMARTDATE_. For example answering to a -! message in the pine-info list would look like: -! -! <P> -! *** Steve Hubert (hubert@cac.washington.edu) wrote in the pine-info list today: -! -! <P> -! However replying for a message in the Lynx list would look: -! -! <P> -! *** mattack@area.com (mattack@area.com) wrote in the Lynx list today: -! -! <P> -! If you write in more than one language you can use this feature to create -! Reply-leadin-strings in different languages. -! -! <P> Note that at least for people you can create particular -! reply-leadin-string using the role features, but it does not work as this -! one does. This seems to be the right way to do it. -! -! <P> _FOLDER_ << {Lynx; comp.mail.pine; pine_info; pine-alpha} => -! _SORT_{OrderedSubj}<BR> This means upon opening, sort the folders "Lynx", -! "comp.mail.pine", etc in ordered subject. All the others use the default -! sort order. You can not sort in reverse in this form. The possible -! arguments of this function are listed in the definition of the -! default-sort-rule (Arrival, scorE, siZe, etc). -! -! <P> The last examples use the function _TRIM_ which has a special form. -! This function can only be used in the index list. -! -! <P> _FOLDER_ << {Lynx} => _SUBJECT_ := _TRIM_{lynx-dev }<BR> In -! the folder "Lynx" eliminate from the subject the string "lynx-dev " (with -! the space at the end). For example a message whose subject is "Re: -! lynx-dev unvisited Visited Links", would be shown in the index with -! subject: "Re: unvisited Visited Links", making the subject shorter and -! giving the same information. -! -! <P> _FROM_ >> {Name (Comment)} => _FROM_ := -! _TRIM_{ (Comment)}<BR> Remove the part " (Comment)" -! from the _FROM_, so when displaying in the index the real From "Name" -! will appear. -! -! <P> _SUBJECT_ == {} => _RESUB_{Re: your mail without subject} -! If there is no subject in the message, use the subject "Re: your mail -! wiyhout subject" as a subject for the reply message. -! -! <P> You can add more complexity to your rules by checking more than one -! conditions before a rule is executed. For example: Assume that you want to -! answer every email that contains the string "bug report", with the subject -! "Re: About your bug report", you could make -! -! <P> -! _SUBJECT_ == {bug report} => _RESUB_{Re: About your _SUBJECT_} -! -! <P> The problem with this construction is that if the person emails you -! back, then the next time you answer the message the subject will be: "Re: -! About your Re: About your bug report", so it grew. You may want to avoid -! this growth by using the following rule: -! -! <P> -! _SUBJECT_ >> {bug report} && _SUBJECT_ !> {Re: } => _RESUB_{Re: About your _SUBJECT_}<BR> - -! <P> -! which will only add the string "Re: About your" only the first time the -! message is replied. - -! <P> -! Say your personal name is "Fred Flinstones", and assume that you don't -! like to see "To: comp.mail.pine" in every post you make to this newsgroup, -! but instead would like to see it as everyone else sees it. <BR> -! _FOLDER_ == {comp.mail.pine} && _FROM_ == {Fred Flinstones} => _FROM_ := _REPLACE_{_FROM_} - -! <P> -! You can also list your index by nick, in the following way:<BR> -! _NICK_ != {} => _FROM_ := _REPLACE_{_NICK_} - -! <P> -! If you want to open the folder "pine-info" in the first non-read message -! use the rule:<BR> -! _FOLDER_ == {pine-info} => _STARTUP_{first-unseen} - - <P> -! If you want to move your deleted messages to a folder, called "Trash", use -! the following rule:<BR> -! _FLAG_ >> {D} -> Trash - - <P> -! The reason why the above test is not "_FLAG_ == {D}" is because that would mean -! that this is the only flag set in the message. It's better to test by containment in this case. -! -! <P> If you want to use a specific signature when you are in a specific collection -! use the following rule:<BR> -! _COLLECTION_ == {Mail} => _SIGNATURE_{/full/path/to/.signature} -! -! <P> Finally about the question of which rule will be executed. Only the -! first rule that matches will be executed. It is important to notice though -! that "saving" rules do not compete with "sorting" rules. So the first -! "saving" rule that matches will be executed in the case of saving and so -! on. -! -! <P> Here are some things to do still: -! <UL> -! <LI> To make _TRIM_ compatible with more tokens (_TO_, _SENDER_, etc) -! <LI> To make this list dissapear! -! </UL> -! -! <P> -! <UL> - <LI><A HREF="h_finding_help">Finding more information and requesting help</A> - </UL><P> - <End of help on this topic> -*************** -*** 21032,21037 **** ---- 22186,22227 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_special_text_to_color ===== -+ <HTML> -+ <HEAD> -+ <TITLE>OPTION: Special Text to Color</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>OPTION: Specil Text to Color</H1> -+ -+ Use this option to enter patterns (text or regular expressions) that Pine -+ will highlight in the body of the text that is not part of a handle (and -+ internal or external link that Pine paints in a different color). -+ -+ <P> -+ Enter each pattern in a different line. Pine will internally merge these -+ patterns (by adding a "|" character), or you can add them all in one line -+ by separating them by a "|" character. -+ -+ <P> -+ Pine will use the colors defined in the -+ <A HREF="h_config_special_text_color"> Special Text Color</A> variable. -+ to paint any match. -+ -+ <P> -+ If the Special Text Color is not set, setting this variable will not -+ cause that special text to be indicated in any special way. It will look -+ like any normal text. You must set those colors in order to make Pine -+ paint the screen differently when it finds the patterns specified in this -+ variable. -+ -+ <P> -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL><P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_display_filters ===== - <HTML> - <HEAD> -*************** -*** 21850,21855 **** ---- 23040,23077 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_inc_fld_timeo ===== -+ <HTML> -+ <HEAD> -+ <TITLE>OPTION: inc-fld-timeout</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>OPTION: inc-fld-timeout</H1> -+ -+ When Pine is checking for new mail in an external incoming folder, and the -+ amount of time specified in this variable has elapsed without Pine being -+ able to connect to the server holding that mailbox, Pine will drop the -+ connection to that server and continue checking for new mail in other -+ incoming folders, if any. -+ -+ <P> -+ Observe that Pine will not print an error message in this case, but it -+ will silently drop the connection. If your connections are fast setting -+ this to a large value will not cause you any problem, but if your -+ connections are slow setting this to a small value will make Pine speed -+ checking for new mail, although it is possible that not all of your -+ incoming folders will be checked for new mail. -+ -+ <P> -+ The default is 5 seconds, which is also the minimum and the maximum is 60. -+ -+ <P> -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL><P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_incoming_folders ===== - <HTML> - <HEAD> -*************** -*** 24123,24128 **** ---- 25345,25420 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_thread_display_style_rule ===== -+ <HTML> -+ <HEAD> -+ <TITLE>OPTION: Threading-Display-Style-Rule</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>OPTION: Threading-Display-Style-Rule</H1> -+ -+ This option is very similar to <A HREF="h_config_thread_disp_style"> -+ threading-display-style</A>, but it is a rule which specifies the -+ display styles for a thread that you want displayed in a specific -+ folder or collection. -+ <P> -+ The token to be used in this function is _THREADSTYLE_. Here there is -+ an example of its use -+ <P> -+ _FOLDER_ == {pine-info} => _THREADSTYLE_{mutt-like} -+ <P> -+ The values that can be given for the _THREADSTYLE_ function are the -+ values of the threading-display-style function, which can be found -+ listed in the <A HREF="h_config_thread_disp_style">threading-display-style</A> -+ configuration option. -+ -+ <P> This configuration option is just one of many that allow you to -+ override the value of some global configurations within Pine. There is a -+ help text explaining how to define all of them, which you can read by -+ following this <A HREF="h_config_new_rules">link</A>. -+ -+ <P> -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL><P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ====== h_config_thread_index_style_rule ===== -+ <HTML> -+ <HEAD> -+ <TITLE>OPTION: Threading-Index-Style-Rule</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>OPTION: Threading-Index-Style-Rule</H1> -+ -+ This option is very similar to <A HREF="h_config_thread_index_style"> -+ threading-index-style</A>, but it is a rule which specifies the -+ index styles for a thread that you want displayed in a specific -+ folder or collection. -+ <P> -+ The token to be used in this function is _THREADINDEX_. Here there is -+ an example of its use -+ <P> -+ _FOLDER_ == {pine-info} => _THREADINDEX_{regular-index-with-expanded-threads} -+ <P> -+ The values that can be given for the _THREADINDEX_ function are the -+ values of the threading-index-display function, which can be found -+ listed in the <A HREF="h_config_thread_index_style">threading-index-display</A> -+ configuration option. -+ -+ <P> This configuration option is just one of many that allow you to -+ override the value of some global configurations within Pine. There is a -+ help text explaining how to define all of them, which you can read by -+ following this <A HREF="h_config_new_rules">link</A>. -+ -+ <P> -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL><P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_pruning_rule ===== - <HTML> - <HEAD> -*************** -*** 24416,24421 **** ---- 25708,25758 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_inc_rule ===== -+ <HTML> -+ <HEAD> -+ <TITLE>OPTION: Incoming-Check-Rule</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>OPTION: Incoming-Check-Rule</H1> -+ -+ This value affects Pine's behavior when starting Pine. It determines -+ how and when Pine will check for new mail in your incoming folders. The -+ default value is "automatic". -+ -+ <P> -+ The three possible values for this option are: -+ -+ <DL> -+ <DT>automatic</DT> -+ <DD>This is the default. When this is selected the first check for new -+ mail will be done when Pine is starting up and you either go to the -+ INDEX or FOLDER LIST screens. -+ </DD> -+ -+ <DT>automatic-after-first-manual-check</DT> -+ <DD>Similar to the default, but no check is done until you force the first -+ one by pressing CTRL-H. All checks are automatic after the first one. Observe -+ that this feature does not work once an automatic check has been done. -+ </DD> -+ -+ <DT>manual-only</DT> -+ <DD>This forces Pine to do only manual checks. This will probably speed -+ Pine, since checks will only happen when they are forced by pressing CTRL-H. -+ </DD> -+ </DL> -+ -+ <P> -+ If you just want to stop Pine from checking in one folder, then simply -+ select that folder. Checks on that folder will be skipped. -+ -+ <P> -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL><P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_browser ===== - <HTML> - <HEAD> -*************** -*** 25490,25495 **** ---- 26827,26909 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_enable_check_incoming ====== -+ <HTML> -+ <HEAD> -+ <TITLE>FEATURE: enable-check-incoming-folders</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>FEATURE: enable-check-incoming-folders</H1> -+ If you have enabled <A HREF="h_config_enable_incoming">incoming -+ folders</A> then setting this feature allows you to check for new mail in -+ these. A message stating that new mail was received and in which folders -+ will be written in the screen. You can decide which incoming folders you -+ want to check for new mail, and the list of them has to be entered in the -+ setting <A HREF="h_config_check_inc_fld">incoming-folders-to-check</A>. -+ -+ <P> If you have the option -+ <A HREF="h_config_fast_recent">enable-fast-recent-test</A> -+ <B>disabled</B>, but have this feature enabled, then a full report on the -+ total number of messages, and the number of new messages in the folder is -+ printed in the <A HREF="h_folder_maint">FOLDER LIST</A> screen -+ for each folder listed in the variable -+ <A HREF="h_config_check_inc_fld">incoming-folders-to-check</A>. The report for each -+ folder is made in the format -+ -+ <P> -+ folder-name [Number of new messages/Number of messages in the folder] -+ -+ <P> -+ If an incoming folder is not listed in the variable -+ <A HREF="h_config_check_inc_fld">incoming-folders-to-check</A>, then only -+ the name of the folder and no other report is made about that folder. -+ -+ <P> -+ Other important features related to this feature are: -+ <OL> -+ <LI><A HREF="h_config_enable_recheck_incoming">recheck-all-incoming-folders</A>, -+ which allows you to decide if you want to check all folders every check, -+ <LI><A HREF="h_config_inc_rule">incoming-check-rule</A>, which determines -+ how and when Pine will check for new mail in your incoming folders. -+ </OL> -+ -+ <P> -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL> -+ </BODY> -+ </HTML> -+ ====== h_config_enable_recheck_incoming ====== -+ <HTML> -+ <HEAD> -+ <TITLE>FEATURE: recheck-all-incoming-folders</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>FEATURE: recheck-all-incoming-folders</H1> -+ If you have enabled <A HREF="h_config_enable_incoming">incoming folders</A> -+ and <A HREF="h_config_enable_check_incoming">enable-check-incoming-folder</A> -+ then setting this feature will force Pine to recheck all incoming folders -+ for new mail. The normal behavior (that is to say, when this feature -+ is not enabled) is that Pine will skip checking for new mail in folders -+ where it already found. This is done to speed checking for new mail. -+ -+ <P> -+ The default behavior, however, can cause problems if you use two clients -+ to access the same incoming folders, because Pine will not realize that -+ new mail does not exist in one folder where it already reported new mail, -+ but was opened with the other client. Setting this feature will cause Pine -+ to recheck all folders all the time. In this way Pine will know for sure -+ which folders DO contain new mail. -+ -+ <P> If you only use Pine to access your incoming folders, then DO NOT -+ enable this feature. -+ -+ <P> -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL> -+ </BODY> -+ </HTML> - ====== h_config_attach_in_reply ====== - <HTML> - <HEAD> -*************** -*** 25788,25793 **** ---- 27202,27223 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_use_domain ===== -+ <HTML> -+ <HEAD> -+ <TITLE>FEATURE: return-path-uses-domain-name </TITLE> -+ </HEAD> -+ <BODY> -+ <H1>FEATURE: return-path-uses-domain-name</H1> -+ -+ If you enable this configuration option Pine will use your domain name and your -+ username in that domain name to construct your Return-Path header, if not Pine -+ will use the address that you have set in the From: field to construct it. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_use_sender_not_x ===== - <HTML> - <HEAD> -*************** -*** 25954,25959 **** ---- 27384,27416 ---- - successes. You will usually receive the full message back when there is - a failure. - -+ <P> When this feature is <B>disabled</B>, and the feature -+ <A HREF="h_config_enable_check_incoming">enable-check-incoming-folders</A> -+ is enabled, then a full report of the number of messages and number of -+ new messages in each incoming folder listed in the option -+ <A HREF="h_config_check_inc_fld">incoming-folders-to-check</A> is made. This -+ report is printed in the <A HREF="h_folder_maint">FOLDER LIST</A> screen. The -+ report is given in the form -+ -+ <P> -+ folder-name [Number of New Messages/Number of messages in the folder] -+ -+ <P> If an incoming-folder is not listed in the variable -+ <A HREF="h_config_check_inc_fld">incoming-folders-to-check</A>, no check for -+ that folder is made, so only the folder name, and no other information is -+ printed about that folder. -+ -+ <P> If this feature is enabled and the feature -+ <A HREF="h_config_enable_recheck_incoming">recheck-all-incoming-folders</A> -+ is disabled, then selecting a folder will cancel further checks on that -+ folder. This is useful if checks to a particular incoming folder are slow -+ and want to be avoided (until the folder is unselected and a new cycle of -+ checks is done) without changing the list of folders to be checked. -+ Selecting a folder in order to avoid checks for new mail does not work in -+ other cases, since it is either explicitly requested this way or because -+ it is necessary to update the count of new and total number of messages of -+ every requested folder. -+ - <P> - If you turn on the DSNOpts the default is to return as much information as - possible to you. That is, by default, the Success and Delay options are -*************** -*** 26332,26337 **** ---- 27789,27846 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_alt_reply_menu ===== -+ <HTML> -+ <HEAD> -+ <TITLE>FEATURE: alternate-reply-menu</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>FEATURE: alternate-reply-menu</H1> -+ -+ This feature controls the menu that is displayed when Reply is selected. -+ If set, a list of options will be presented, with each option representing -+ the type of composition that could be used. This feature is most useful -+ for users who want to avoid being prompted with each option separately, or -+ would like to override some defaults set in your configuration for the -+ message that you are replying (e.g. you may have set the option to strip -+ signatures, but for the message you are answering you would like not to do -+ that) -+ -+ <P> -+ The way this feature works is as follows. Initially you get the question -+ if you want to include the message, and in the menu you will see several -+ options, each option is accompanied by some text explaining what will -+ happen if you press the associated command. For example, if you read the -+ text "S Strip Sig", it means that if you press the letter -+ "S" the signature will be stripped off the message you are -+ replying. Observer that the menu will change to -+ "S No Strip", which means that if you press "S", the -+ signature will not be stripped off from the message. Your choices are -+ activated when you press RETURN. -+ -+ <P> -+ Another way to remember what Pine will do, is that what will be done is -+ exactly the opposite of what you read in the menu. -+ -+ <P> -+ The possible options are: -+ -+ <OL> -+ <LI> F: To decide if you want to send flowed text or not. This option appears -+ unless you have quelled sending flowed text. -+ -+ <LI> S: To strip the signature from a message, only available is the feature -+ <a href="h_config_sigdashes">enable-sigdashes</a> or the -+ <a href="h_config_strip_sigdashes">strip-from-sigdashes-on-reply</a> option are -+ enabled. -+ -+ <LI> R: To set a role, if you do not want Pine to set one automatically for you -+ or would like to set one when you can not select any. -+ </OL> -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_del_from_dot ===== - <HTML> - <HEAD> -*************** -*** 27077,27082 **** ---- 28586,28634 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_courier_list ===== -+ <HTML> -+ <HEAD> -+ <TITLE>FEATURE: Courier-Folder-List</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>FEATURE: Courier-Folder-List</H1> -+ -+ In a maildir collection, a folder could be used as a directory to store -+ folders. In the Courier server if you create a folder, then a directory -+ with the same name is created. If you use this patch to access a -+ collection created by the Courier server, then the display of such -+ collection will look confusing. The best way to access a maildir -+ collection created by the Courier server is by using the "#mc/" -+ prefix instead of the "#md/" prefix. If you use this alternate -+ prefix, then this feature applies to you, otherwise you can safely ignore -+ the text that follows. -+ <P> -+ Depending on if you have enabled the option -+ <a href="h_config_separate_yold_dir_view">separate-folder-and-firectory-entries</a> -+ a folder may be listed as "folder[.]", or as two entries in the -+ list by "folder" and "folder.". -+ <P> -+ If this option is disabled, Pine will list local folders that are in Courier -+ style format, as "folder", and those that are also directories as -+ "folder[.]". This makes the default display cleaner. -+ <P> -+ If this feature is enabled then creating folders in a maildir collection -+ will create a directory with the same name. If this feature is disabled, then -+ a folder is considered a directory only if it contains subfolders, so you can -+ not create a directory with the same name as an exisiting folder unless -+ you create a subfolder of that folder first (e.g. if you have a folder -+ called "foo" simply add "foo.bar" directly. This will -+ create the directory "foo" and the subfolder "bar" of it). -+ <P> -+ Observe that this feature works only for maildir collections that are accessed -+ locally. If a collection is accessed remotely then this feature has no value, -+ as the report is created in a server, and Pine only reports what received -+ from the server in this case. -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_verbose_post ===== - <HTML> - <HEAD> -*************** -*** 27228,27233 **** ---- 28780,28808 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_auto_read_msgs_rules ===== -+ <HTML> -+ <HEAD> -+ <TITLE>FEATURE: auto-move-read-msgs-using-rules</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>FEATURE: auto-move-read-msgs-using-rules</H1> -+ This feature controls an aspect of Pine's behavior upon quitting. If set, -+ and the -+ <A HREF="h_config_read_message_folder">"read-message-folder"</A> -+ option is also set, then Pine will automatically transfer all read -+ messages to the designated folder using the rules that you have defined in -+ your -+ <A HREF="h_config_save_rules">"save-rules"</A> and mark -+ them as deleted in the INBOX. Messages in the INBOX marked with an -+ "N" (meaning New, or unseen) are not affected. -+ <P> -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL><P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_auto_fcc_only ===== - <HTML> - <HEAD> -*************** -*** 27616,27621 **** ---- 29191,29213 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_enhanced_thread ===== -+ <HTML> -+ <HEAD> -+ <TITLE>FEATURE: enhanced-fancy-thread-support</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>FEATURE: enhanced-fancy-thread-support</H1> -+ -+ If this option is set certain commands in Pine will operate in loose -+ threads too. For example, the command ^D marks a thread deleted, but if -+ this feature is set, it will remove all threads that share the same missing -+ parent with this thread. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_news_cross_deletes ===== - <HTML> - <HEAD> -*************** -*** 28224,28229 **** ---- 29816,29842 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_circular_tab ===== -+ <HTML> -+ <HEAD> -+ <TITLE>FEATURE: enable-circular-tab</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>FEATURE: enable-circular-tab</H1> -+ -+ <P> -+ This Feature is like -+ <A HREF="h_config_auto_open_unread">"auto-open-next-unread"</A>, -+ in the sense that you can use TAB to browse through all of your Incoming -+ Folders checking for new mail. Once it gets to the last folder of the -+ collection it goes back to check again until it returns to the original -+ folder where it started. -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL><P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_auto_include_reply ===== - <HTML> - <HEAD> -*************** -*** 28715,28720 **** ---- 30328,30357 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_special_text_color ===== -+ <HTML> -+ <HEAD> -+ <TITLE>OPTION: Special Text Color</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>OPTION: Special Text Color</H1> -+ -+ Sets the color Pine uses for coloring any text in the body of the message -+ that is not part of a handle (and internal or external link that Pine -+ paints in a different color). By default, this variable is not defined, -+ which means that text that matches the pattern is not painted in any -+ particular way. This variable must be set in a special form if you -+ want text to be painted. -+ -+ <P> -+ <A HREF="h_color_setup">Descriptions of the available commands</A> -+ <P> -+ Look <A HREF="h_edit_nav_cmds">here</A> -+ to see the available Editing and Navigation commands. -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_prompt_color ===== - <HTML> - <HEAD> -diff -rc pine4.63/pine/reply.c pine4.63.I.USE/pine/reply.c -*** pine4.63/pine/reply.c Thu Apr 28 10:22:03 2005 ---- pine4.63.I.USE/pine/reply.c Thu May 19 19:57:34 2005 -*************** -*** 62,67 **** ---- 62,69 ---- - - #include "headers.h" - -+ static ACTION_S *role_chosen; -+ static int strip, send_flowed = 1; - - - /* -*************** -*** 276,282 **** - if(!times){ /* only first time */ - char *p = cpystr(prefix); - -! if((include_text=reply_text_query(pine_state,totalm,&prefix)) < 0) - goto done_early; - - /* edited prefix? */ ---- 278,284 ---- - if(!times){ /* only first time */ - char *p = cpystr(prefix); - -! if((include_text=reply_text_query(pine_state,totalm,env,&prefix)) < 0) - goto done_early; - - /* edited prefix? */ -*************** -*** 307,312 **** ---- 309,355 ---- - else if(i == 0) - goto done_early; - -+ if (ps_global->role) -+ fs_give((void **)&ps_global->role); -+ -+ /* Setup possible role */ -+ if (role_chosen) -+ role = role_chosen; -+ else if(role_arg) -+ role = copy_action(role_arg); -+ -+ if(!role){ -+ rflags = ROLE_REPLY; -+ if(!role_chosen && nonempty_patterns(rflags, &dummy)){ -+ /* setup default role */ -+ nrole = NULL; -+ j = mn_first_cur(pine_state->msgmap); -+ do { -+ role = nrole; -+ nrole = set_role_from_msg(pine_state, rflags, -+ mn_m2raw(pine_state->msgmap, j), -+ NULL); -+ } while(nrole && (!role || nrole == role) -+ && (j=mn_next_cur(pine_state->msgmap)) > 0L); -+ -+ if(!role || nrole == role) -+ role = nrole; -+ else -+ role = NULL; -+ -+ if(confirm_role(rflags, &role)) -+ role = combine_inherited_role(role); -+ else{ /* cancel reply */ -+ role = NULL; -+ cmd_cancelled("Reply"); -+ goto done_early; -+ } -+ } -+ } -+ -+ if (role) -+ ps_global->role = cpystr(role->nick); /* remember the role */ -+ - /*------------ Format the subject line ---------------*/ - if(outgoing->subject){ - /* -*************** -*** 319,326 **** - outgoing->subject = cpystr("Re: several messages"); - } - } -! else -! outgoing->subject = reply_subject(env->subject, NULL, 0); - } - - ---- 362,380 ---- - outgoing->subject = cpystr("Re: several messages"); - } - } -! else{ -! RULE_RESULT *rule; -! rule = get_result_rule(V_RESUB_RULES, -! FOR_RULE|FOR_RESUB|FOR_TRIM , env); -! if (rule){ -! outgoing->subject = reply_subject(rule->result, NULL, 0); -! if (rule->result) -! fs_give((void **)&rule->result); -! fs_give((void **)&rule); -! } -! else -! outgoing->subject = reply_subject(env->subject, NULL, 0); -! } - } - - -*************** -*** 331,369 **** - if(sp_expunge_count(pine_state->mail_stream)) /* cur msg expunged */ - goto done_early; - -- /* Setup possible role */ -- if(role_arg) -- role = copy_action(role_arg); -- -- if(!role){ -- rflags = ROLE_REPLY; -- if(nonempty_patterns(rflags, &dummy)){ -- /* setup default role */ -- nrole = NULL; -- j = mn_first_cur(pine_state->msgmap); -- do { -- role = nrole; -- nrole = set_role_from_msg(pine_state, rflags, -- mn_m2raw(pine_state->msgmap, j), -- NULL); -- } while(nrole && (!role || nrole == role) -- && (j=mn_next_cur(pine_state->msgmap)) > 0L); -- -- if(!role || nrole == role) -- role = nrole; -- else -- role = NULL; -- -- if(confirm_role(rflags, &role)) -- role = combine_inherited_role(role); -- else{ /* cancel reply */ -- role = NULL; -- cmd_cancelled("Reply"); -- goto done_early; -- } -- } -- } -- - /* - * Reply_seed may call c-client in get_fcc_based_on_to, so env may - * no longer be valid. Get it again. ---- 385,390 ---- -*************** -*** 995,1001 **** - prompt_fodder); - } - -! cmd = radio_buttons(prompt, -FOOTER_ROWS(ps_global), ekey, - 'y', 'x', help, RB_NORM); - - switch(cmd){ ---- 1016,1023 ---- - prompt_fodder); - } - -! cmd = ps_global->send_immediately ? 'n' : -! radio_buttons(prompt, -FOOTER_ROWS(ps_global), ekey, - 'y', 'x', help, RB_NORM); - - switch(cmd){ -*************** -*** 1623,1630 **** - ENVELOPE *env; - { - char *prefix, *repl, *p, buf[MAX_PREFIX+1], pbf[MAX_SUBSTITUTION+1]; - -! strncpy(buf, ps_global->VAR_REPLY_STRING, sizeof(buf)-1); - buf[sizeof(buf)-1] = '\0'; - - /* set up the prefix to quote included text */ ---- 1645,1671 ---- - ENVELOPE *env; - { - char *prefix, *repl, *p, buf[MAX_PREFIX+1], pbf[MAX_SUBSTITUTION+1]; -+ char reply_string[MAX_PREFIX+1]; -+ -+ { RULE_RESULT *rule; -+ rule = get_result_rule(V_REPLY_INDENT_RULES, FOR_RULE|FOR_COMPOSE , env); -+ if (rule){ -+ strncpy(reply_string,rule->result,sizeof(reply_string)); -+ reply_string[sizeof(reply_string)-1] = '\0'; -+ if (rule->result) -+ fs_give((void **)&rule->result); -+ fs_give((void **)&rule); -+ } -+ else -+ if ((ps_global->VAR_REPLY_STRING) && (ps_global->VAR_REPLY_STRING[0])){ -+ strncpy(reply_string,ps_global->VAR_REPLY_STRING, sizeof(reply_string)-1); -+ reply_string[sizeof(reply_string)-1] = '\0'; -+ } -+ else -+ strncpy(reply_string,"> ",sizeof("> ")); -+ } - -! strncpy(buf, reply_string, sizeof(buf)-1); - buf[sizeof(buf)-1] = '\0'; - - /* set up the prefix to quote included text */ -*************** -*** 1680,1689 **** - int - reply_quote_str_contains_tokens() - { -! return(ps_global->VAR_REPLY_STRING && ps_global->VAR_REPLY_STRING[0] && -! (strstr(ps_global->VAR_REPLY_STRING, from_token) || -! strstr(ps_global->VAR_REPLY_STRING, nick_token) || -! strstr(ps_global->VAR_REPLY_STRING, init_token))); - } - - /* ---- 1721,1750 ---- - int - reply_quote_str_contains_tokens() - { -! char *reply_string; -! -! reply_string = (char *) malloc( 80*sizeof(char)); -! { RULE_RESULT *rule; -! rule = get_result_rule(V_REPLY_INDENT_RULES, -! FOR_RULE | FOR_COMPOSE, (ENVELOPE *)NULL); -! if (rule){ -! reply_string = cpystr(rule->result); -! if (rule->result) -! fs_give((void **)&rule->result); -! fs_give((void **)&rule); -! } -! else -! if ((ps_global->VAR_REPLY_STRING) && (ps_global->VAR_REPLY_STRING[0])){ -! strncpy(reply_string,ps_global->VAR_REPLY_STRING, sizeof(reply_string)-1); -! reply_string[sizeof(reply_string)-1] = '\0'; -! } -! else -! reply_string = cpystr("> "); -! } -! return(reply_string && reply_string[0] && -! (strstr(reply_string, from_token) || -! strstr(reply_string, nick_token) || -! strstr(reply_string, init_token))); - } - - /* -*************** -*** 1693,1738 **** - * 0 if we're NOT to include the text - * -1 on cancel or error - */ - int -! reply_text_query(ps, many, prefix) - struct pine *ps; - long many; - char **prefix; - { - int ret, edited = 0; -! static ESCKEY_S rtq_opts[] = { -! {'y', 'y', "Y", "Yes"}, -! {'n', 'n', "N", "No"}, -! {-1, 0, NULL, NULL}, /* may be overridden below */ -! {-1, 0, NULL, NULL} -! }; - - if(F_ON(F_AUTO_INCLUDE_IN_REPLY, ps) -! && F_OFF(F_ENABLE_EDIT_REPLY_INDENT, ps)) - return(1); - - while(1){ -! sprintf(tmp_20k_buf, "Include %s%soriginal message%s in Reply%s%s%s? ", - (many > 1L) ? comatose(many) : "", - (many > 1L) ? " " : "", - (many > 1L) ? "s" : "", - F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps) ? " (using \"" : "", - F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps) ? *prefix : "", - F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps) ? "\")" : ""); - -! if(F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps)){ -! rtq_opts[2].ch = ctrl('R'); -! rtq_opts[2].rval = 'r'; -! rtq_opts[2].name = "^R"; -! rtq_opts[2].label = "Edit Indent String"; -! } -! else -! rtq_opts[2].ch = -1; - - switch(ret = radio_buttons(tmp_20k_buf, - ps->ttyo->screen_rows > 4 - ? -FOOTER_ROWS(ps_global) : -1, -! rtq_opts, - (edited || F_ON(F_AUTO_INCLUDE_IN_REPLY, ps)) - ? 'y' : 'n', - 'x', NO_HELP, RB_SEQ_SENSITIVE)){ ---- 1754,1854 ---- - * 0 if we're NOT to include the text - * -1 on cancel or error - */ -+ -+ #define MAX_REPLY_OPTIONS 8 -+ - int -! reply_text_query(ps, many, env, prefix) - struct pine *ps; - long many; -+ ENVELOPE *env; - char **prefix; - { - int ret, edited = 0; -! static ESCKEY_S compose_style[MAX_REPLY_OPTIONS]; -! int ekey_num; -! int orig_sf; -! -! orig_sf = send_flowed = *prefix && **prefix ? (F_OFF(F_QUELL_FLOWED_TEXT, ps) -! && F_OFF(F_STRIP_WS_BEFORE_SEND, ps) -! && (strcmp(*prefix, "> ") == 0 -! || strcmp(*prefix, ">") == 0)) : 0; -! -! role_chosen = NULL; -! strip = F_ON(F_ENABLE_STRIP_SIGDASHES, ps) || F_ON(F_ENABLE_SIGDASHES, ps); - - if(F_ON(F_AUTO_INCLUDE_IN_REPLY, ps) -! && F_OFF(F_ENABLE_EDIT_REPLY_INDENT, ps) && F_OFF(F_ALT_REPLY_MENU,ps)) - return(1); - - while(1){ -! sprintf(tmp_20k_buf,"Include %s%soriginal message%s in Reply%s%s%s%s%s? ", - (many > 1L) ? comatose(many) : "", - (many > 1L) ? " " : "", - (many > 1L) ? "s" : "", - F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps) ? " (using \"" : "", - F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps) ? *prefix : "", -+ role_chosen ? "\" and role \"" : "", -+ role_chosen ? role_chosen->nick : "", - F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps) ? "\")" : ""); - -! ekey_num = 0; -! compose_style[ekey_num].ch = 'y'; -! compose_style[ekey_num].rval = 'y'; -! compose_style[ekey_num].name = "Y"; -! compose_style[ekey_num++].label = "Yes"; -! -! compose_style[ekey_num].ch = 'n'; -! compose_style[ekey_num].rval = 'n'; -! compose_style[ekey_num].name = "N"; -! compose_style[ekey_num++].label = "No"; -! -! if (F_ON(F_ENABLE_EDIT_REPLY_INDENT, ps)){ -! compose_style[ekey_num].ch = ctrl('R'); -! compose_style[ekey_num].rval = 'r'; -! compose_style[ekey_num].name = "^R"; -! compose_style[ekey_num++].label = "Indent Str" ; -! } -! -! /***** Alternate Reply Menu ********/ -! -! if (F_ON(F_ALT_REPLY_MENU, ps)){ -! unsigned which_help; -! -! if (F_ON(F_ENABLE_STRIP_SIGDASHES, ps) || -! F_ON(F_ENABLE_SIGDASHES, ps)){ -! compose_style[ekey_num].ch = 's'; -! compose_style[ekey_num].rval = 's'; -! compose_style[ekey_num].name = "S"; -! compose_style[ekey_num++].label = strip ? "No Strip" -! : "Strip Sig"; -! } -! -! compose_style[ekey_num].ch = 'r'; -! compose_style[ekey_num].rval = 'R'; -! compose_style[ekey_num].name = "R"; -! compose_style[ekey_num++].label = "Set Role"; -! -! if(orig_sf){ -! compose_style[ekey_num].ch = 'f'; -! compose_style[ekey_num].rval = 'F'; -! compose_style[ekey_num].name = "F"; -! compose_style[ekey_num++].label = send_flowed ? "Quell Flowed" -! : "Send Flowed"; -! } -! -! } -! compose_style[ekey_num].ch = -1; -! compose_style[ekey_num].name = NULL; -! compose_style[ekey_num].label = NULL; -! -! -! /***** End Alt Reply Menu *********/ - - switch(ret = radio_buttons(tmp_20k_buf, - ps->ttyo->screen_rows > 4 - ? -FOOTER_ROWS(ps_global) : -1, -! compose_style, - (edited || F_ON(F_AUTO_INCLUDE_IN_REPLY, ps)) - ? 'y' : 'n', - 'x', NO_HELP, RB_SEQ_SENSITIVE)){ -*************** -*** 1740,1745 **** ---- 1856,1892 ---- - cmd_cancelled("Reply"); - return(-1); - -+ case 'F': -+ send_flowed = (send_flowed + 1) % 2; -+ break; -+ -+ case 's': -+ strip = (strip + 1) % 2; -+ break; -+ -+ case 'R': -+ { -+ void (*prev_screen)() = ps->prev_screen, -+ (*redraw)() = ps->redrawer; -+ ps->redrawer = NULL; -+ ps->next_screen = SCREEN_FUN_NULL; -+ if(role_select_screen(ps, &role_chosen, 1) < 0){ -+ cmd_cancelled("Reply"); -+ ps->next_screen = prev_screen; -+ ps->redrawer = redraw; -+ if (ps->redrawer) -+ (*ps->redrawer)(); -+ continue; -+ } -+ ps->next_screen = prev_screen; -+ ps->redrawer = redraw; -+ if(role_chosen) -+ role_chosen = combine_inherited_role(role_chosen); -+ } -+ if (ps->redrawer) -+ (*ps->redrawer)(); -+ break; -+ - case 'r': - if(prefix && *prefix){ - int done = 0; -*************** -*** 1763,1768 **** ---- 1910,1921 ---- - if(flags & OE_USER_MODIFIED){ - fs_give((void **)prefix); - *prefix = removing_quotes(cpystr(buf)); -+ orig_sf = *prefix && **prefix ? -+ (F_OFF(F_QUELL_FLOWED_TEXT, ps) -+ && F_OFF(F_STRIP_WS_BEFORE_SEND, ps) -+ && (strcmp(*prefix, "> ") == 0 -+ || strcmp(*prefix, ">") == 0)) : 0; -+ send_flowed = orig_sf; - edited = 1; - } - -*************** -*** 2251,2256 **** ---- 2404,2413 ---- - buf[0] = '\0'; - - switch(type){ -+ case iFfrom: -+ addr = env && env->sparep ? env->sparep : NULL; -+ break; -+ - case iFrom: - addr = env ? env->from : NULL; - break; -*************** -*** 2682,2702 **** - - break; - - case iFrom: - case iTo: - case iCc: - case iSender: - case iRecips: - case iInit: - get_addr_data(env, type, buf, maxlen); - break; - -! case iRoleNick: -! if(role && role->nick){ -! strncpy(buf, role->nick, maxlen); -! buf[maxlen] = '\0'; -! } -! break; - - case iAddress: - case iMailbox: ---- 2839,2959 ---- - - break; - -+ case iRole: -+ if (ps_global->role) -+ sprintf(buf, ps_global->role); -+ break; -+ -+ case iRoleNick: -+ if(role && role->nick){ -+ strncpy(buf, role->nick, maxlen); -+ buf[maxlen] = '\0'; -+ } -+ break; -+ -+ case iFfrom: - case iFrom: - case iTo: - case iCc: - case iSender: - case iRecips: - case iInit: -+ if (env) - get_addr_data(env, type, buf, maxlen); - break; - -! case iFolder: -! sprintf(buf,ps_global->cur_folder); -! break; -! -! case iCollection: -! sprintf(buf,ps_global->context_current->nickname); -! break; -! -! case iFlag: -! {MAILSTREAM *stream = find_open_stream(); -! MSGNO_S *msgmap = NULL; -! long msgno; -! MESSAGECACHE *mc; -! strcpy(buf, "_FLAG_"); /* default value */ -! if (stream){ -! mn_init(&msgmap, stream->nmsgs); -! msgno = mn_m2raw(msgmap, rules_cursor_pos(stream)); -! if (msgno > 0L) mc = stream ? mail_elt(stream, msgno) : NULL; -! if (mc) -! sprintf(buf,"%s%s%s%s",mc->flagged ? "*" : "", -! mc->recent ? (mc->seen ? "R" : "N") : (mc->seen) ? "R" : "U", -! mc->answered ? "A" : "", -! mc->deleted ? "D" : "" ); -! mn_give(&msgmap); -! } -! } -! break; -! -! case iNick: -! { -! ADDRESS *tmp_adr = NULL; -! if (env){ -! tmp_adr = env->from ? copyaddr(env->from) -! : env->sender ? copyaddr(env->sender) : NULL; -! get_nickname_from_addr(tmp_adr,buf,maxlen); -! mail_free_address(&tmp_adr); -! } -! } -! break; -! -! case iAddressCc: -! case iAddressRecip: -! case iAddressTo: -! case iFadd: -! { -! int plen = 0; /* partial length */ -! ADDRESS *sparep2 = (type == iAddressTo || type == iAddressRecip) -! ? ((env && env->to) -! ? copyaddrlist(env->to) -! : NULL) -! : (type == iAddressCc) -! ? ((env && env->cc) -! ? copyaddrlist(env->cc) -! : NULL) -! : ((env && env->sparep) -! ? copyaddr((ADDRESS *)env->sparep) -! : NULL); -! ADDRESS *sparep; -! -! if (type == iAddressRecip){ -! ADDRESS *last_to = NULL; -! -! for(last_to = sparep2;last_to && last_to->next; last_to= last_to->next); -! -! /* Make the end of To list point to cc list */ -! if(last_to) -! last_to->next = (env && env->cc ? copyaddrlist(env->cc) : NULL); -! -! } -! sparep = sparep2; -! for(; sparep ; sparep = sparep->next) -! if(sparep && sparep->mailbox && sparep->mailbox[0] && -! (plen ? plen + 1 : plen) + strlen(sparep->mailbox) <= maxlen){ -! if (plen == 0) -! strcpy(buf, sparep->mailbox); -! else{ -! strcat(buf, " "); -! strcat(buf, sparep->mailbox); -! } -! if(sparep->host && -! sparep->host[0] && -! sparep->host[0] != '.' && -! strlen(buf) + strlen(sparep->host) + 1 <= maxlen){ -! strcat(buf, "@"); -! strcat(buf, sparep->host); -! } -! plen = strlen(buf); -! } -! mail_free_address(&sparep2); -! } -! -! break; - - case iAddress: - case iMailbox: -*************** -*** 2715,2720 **** ---- 2972,2982 ---- - - break; - -+ case iLcc: /* fake it, there are not enough spare pointers */ -+ if (env && env->date) -+ sprintf(buf,env->date); -+ break; -+ - case iNews: - case iCurNews: - get_news_data(env, type, buf, maxlen); -*************** -*** 2826,2832 **** - if(!env) - return; - -! strncpy(buf, ps_global->VAR_REPLY_INTRO, MAX_DELIM); - buf[MAX_DELIM] = '\0'; - /* preserve exact default behavior from before */ - if(!strcmp(buf, DEFAULT_REPLY_INTRO)){ ---- 3088,3106 ---- - if(!env) - return; - -! { RULE_RESULT *rule; -! rule = get_result_rule(V_REPLY_LEADIN_RULES, -! FOR_RULE | FOR_REPLY_INTRO, env); -! if(rule){ -! strncpy(buf, rule->result, MAX_DELIM); -! if (rule->result) -! fs_give((void **)&rule->result); -! fs_give((void **)&rule); -! } -! else -! strncpy(buf, ps_global->VAR_REPLY_INTRO, MAX_DELIM); -! } -! - buf[MAX_DELIM] = '\0'; - /* preserve exact default behavior from before */ - if(!strcmp(buf, DEFAULT_REPLY_INTRO)){ -*************** -*** 2988,2996 **** - } - else if(!outgoing->newsgroups) - outgoing->newsgroups = cpystr(env->newsgroups); -- if(!IS_NEWS(ps_global->mail_stream)) -- q_status_message(SM_ORDER, 2, 3, -- "Replying to message that MAY or MAY NOT have been posted to newsgroup"); - } - - return(ret); ---- 3262,3267 ---- -*************** -*** 3051,3056 **** ---- 3322,3329 ---- - - if(is_sig){ - /* -+ * First we check if there is a rule about signatures, if there is -+ * use it, otherwise keep going and do the following: - * If role->litsig is set, we use it; - * Else, if VAR_LITERAL_SIG is set, we use that; - * Else, if role->sig is set, we use that; -*************** -*** 3064,3077 **** - * there is no reason to mix them, so we don't provide support to - * do so. - */ -! if(role && role->litsig) -! literal_sig = role->litsig; -! else if(ps_global->VAR_LITERAL_SIG) -! literal_sig = ps_global->VAR_LITERAL_SIG; -! else if(role && role->sig) -! sigfile = role->sig; -! else -! sigfile = ps_global->VAR_SIGNATURE_FILE; - } - else if(role && role->template) - sigfile = role->template; ---- 3337,3361 ---- - * there is no reason to mix them, so we don't provide support to - * do so. - */ -! { RULE_RESULT *rule; -! rule = get_result_rule(V_COMPOSE_RULES, FOR_RULE|FOR_COMPOSE, env); -! if (rule){ -! sigfile = cpystr(rule->result); -! if (rule->result) -! fs_give((void **)&rule->result); -! fs_give((void **)&rule); -! } -! } -! if (!sigfile){ -! if(role && role->litsig) -! literal_sig = role->litsig; -! else if(ps_global->VAR_LITERAL_SIG) -! literal_sig = ps_global->VAR_LITERAL_SIG; -! else if(role && role->sig) -! sigfile = role->sig; -! else -! sigfile = ps_global->VAR_SIGNATURE_FILE; -! } - } - else if(role && role->template) - sigfile = role->template; -*************** -*** 3269,3275 **** - } - } - } -! else if(pt->what_for & FOR_REPLY_INTRO) - repl = get_reply_data(env, role, pt->ctype, - subbuf, sizeof(subbuf)-1); - ---- 3553,3559 ---- - } - } - } -! else if(pt->what_for & (FOR_REPLY_INTRO|FOR_RULE)) - repl = get_reply_data(env, role, pt->ctype, - subbuf, sizeof(subbuf)-1); - -*************** -*** 3747,3755 **** - } - } - -! if(role) - q_status_message1(SM_ORDER, 3, 4, - "Forwarding using role \"%.200s\"", role->nick); - - if(role && role->template){ - char *filtered; ---- 4031,4044 ---- - } - } - -! if (ps_global->role) -! fs_give((void **)&ps_global->role); -! -! if(role){ - q_status_message1(SM_ORDER, 3, 4, - "Forwarding using role \"%.200s\"", role->nick); -+ ps_global->role = cpystr(role->nick); -+ } - - if(role && role->template){ - char *filtered; -*************** -*** 3953,3958 **** ---- 4242,4248 ---- - #if defined(DOS) && !defined(_WINDOWS) - free((void *)reserve); - #endif -+ outgoing->sparep = env && env->from ? (ADDRESS *)copyaddr(env->from) : NULL; - pine_send(outgoing, &body, "FORWARD MESSAGE", - role, NULL, reply.flags ? &reply : NULL, redraft_pos, - NULL, NULL, FALSE); -*************** -*** 4873,4881 **** - * tied our hands, alter the prefix to continue flowed - * formatting... - */ -! if(flow_res) - wrapflags |= GFW_FLOW_RESULT; - - filters[i].filter = gf_wrap; - /* - * The 80 will cause longer lines than what is likely ---- 5163,5174 ---- - * tied our hands, alter the prefix to continue flowed - * formatting... - */ -! if(flow_res && send_flowed) - wrapflags |= GFW_FLOW_RESULT; - -+ filters[i].filter = gf_quote_test; -+ filters[i++].data = gf_line_test_opt(select_quote, NULL); -+ - filters[i].filter = gf_wrap; - /* - * The 80 will cause longer lines than what is likely -*************** -*** 4909,4916 **** - * We also want to fold "> " quotes so we get the - * attributions correct. - */ -! if(flow_res && prefix && !strucmp(prefix, "> ")) - *(prefix_p = prefix + 1) = '\0'; - if(!(wrapflags & GFW_FLOWED) - && flow_res){ - filters[i].filter = gf_line_test; ---- 5202,5210 ---- - * We also want to fold "> " quotes so we get the - * attributions correct. - */ -! if(flow_res && send_flowed && prefix && !strucmp(prefix, "> ")) - *(prefix_p = prefix + 1) = '\0'; -+ send_flowed = 1; /* reset for next call */ - if(!(wrapflags & GFW_FLOWED) - && flow_res){ - filters[i].filter = gf_line_test; -*************** -*** 4938,4945 **** - } - - if(prefix){ -! if(F_ON(F_ENABLE_SIGDASHES, ps_global) || -! F_ON(F_ENABLE_STRIP_SIGDASHES, ps_global)){ - dashdata = 0; - filters[i].filter = gf_line_test; - filters[i++].data = gf_line_test_opt(sigdash_strip, &dashdata); ---- 5232,5239 ---- - } - - if(prefix){ -! if(strip && (F_ON(F_ENABLE_SIGDASHES, ps_global) || -! F_ON(F_ENABLE_STRIP_SIGDASHES, ps_global))){ - dashdata = 0; - filters[i].filter = gf_line_test; - filters[i++].data = gf_line_test_opt(sigdash_strip, &dashdata); -diff -rc pine4.63/pine/rules.c pine4.63.I.USE/pine/rules.c -*** pine4.63/pine/rules.c Thu May 19 19:59:15 2005 ---- pine4.63.I.USE/pine/rules.c Thu May 19 19:57:27 2005 -*************** -*** 0 **** ---- 1,905 ---- -+ /* This module was written by -+ * -+ * Eduardo Chappa (chappa@math.washington.edu) -+ * http://www.math.washington.edu/~chappa/pine/ -+ * -+ * Original Version: November 1999 -+ * Last Modified : December 14, 2004 -+ * -+ * Send bug reports about this module to the address above. -+ */ -+ -+ #include "rules.h" -+ -+ void free_token_value(token) -+ TOKEN_VALUE **token; -+ { -+ if(token && *token){ -+ if ((*token)->testxt) -+ fs_give((void **)&((*token)->testxt)); -+ if((*token)->next) -+ free_token_value(&((*token)->next)); -+ fs_give((void **)token); -+ } -+ } -+ -+ void free_condition(condition) -+ CONDITION_S **condition; -+ { -+ if(condition && *condition){ -+ if ((*condition)->tname) -+ fs_give((void **)&((*condition)->tname)); -+ if ((*condition)->value) -+ free_token_value(&((*condition)->value)); -+ if((*condition)->next) -+ free_condition(&((*condition)->next)); -+ fs_give((void **)condition); -+ } -+ } -+ -+ void free_ruleaction(raction) -+ RULEACTION_S **raction; -+ { -+ if(raction && *raction){ -+ if ((*raction)->token) -+ fs_give((void **)&((*raction)->token)); -+ if ((*raction)->function) -+ fs_give((void **)&((*raction)->function)); -+ if ((*raction)->value) -+ fs_give((void **)&((*raction)->value)); -+ fs_give((void **)raction); -+ } -+ } -+ -+ void free_rule(rule) -+ RULE_S **rule; -+ { -+ if(rule && *rule){ -+ free_condition(&((*rule)->condition)); -+ free_ruleaction(&((*rule)->action)); -+ fs_give((void **)rule); -+ } -+ } -+ -+ void free_rule_list(rule) -+ RULELIST **rule; -+ { -+ if(!*rule) -+ return; -+ -+ if((*rule)->next) -+ free_rule_list(&((*rule)->next)); -+ -+ if((*rule)->prule) -+ free_rule(&((*rule)->prule)); -+ -+ fs_give((void **)rule); -+ } -+ -+ void -+ free_parsed_rule_list(rule) -+ PRULELIST_S **rule; -+ { -+ if(!*rule) -+ return; -+ -+ if((*rule)->next) -+ free_parsed_rule_list(&((*rule)->next)); -+ -+ if((*rule)->rlist) -+ free_rule_list(&((*rule)->rlist)); -+ -+ fs_give((void **)rule); -+ } -+ -+ void * -+ alloc_mem (amount) -+ size_t amount; -+ { -+ void *genmem; -+ memset(genmem = fs_get(amount), 0, amount); -+ return genmem; -+ } -+ -+ int -+ isolate_condition (data, cvalue, len) -+ char *data, **cvalue; -+ int *len; -+ { -+ char *p = data; -+ int done = 0, error = 0, next_condition = 0, l; -+ -+ *cvalue = NULL; -+ while (*p && !done){ -+ switch (*p){ -+ case '_': *cvalue = advance_to_char(p,'}', STRICT, NULL); -+ if(*cvalue){ -+ strcat(*cvalue,"}"); -+ p += strlen(*cvalue); -+ } -+ else -+ error++; -+ done++; -+ case ' ': p++; -+ break; -+ case '&': if (*(p+1) == '&'){ /* looking for && */ -+ p += 2; -+ next_condition++; -+ } -+ else{ -+ error++; -+ done++; -+ } -+ break; -+ case '=': /* looking for => or -> */ -+ case '-': if ((*(p+1) == '>') && (!next_condition)){ -+ is_save = (*p == '-'); -+ p += 2; -+ } -+ else -+ error++; -+ done++; -+ break; -+ default : done++; -+ error++; -+ break; -+ } -+ } -+ *len = p - data; -+ return error ? -1 : (*cvalue ? 1 : 0); -+ } -+ -+ TOKEN_VALUE * -+ parse_group_data (data, error) -+ char *data; -+ int *error; -+ { -+ TOKEN_VALUE *rvalue; -+ char *p; -+ int offset, err = 0; -+ -+ if(error) -+ *error = 0; -+ -+ if (!data) -+ return (TOKEN_VALUE *) NULL; -+ -+ rvalue = (TOKEN_VALUE *) alloc_mem(sizeof(TOKEN_VALUE)); -+ if (p = advance_to_char(data,';', STRICT, &offset)){ -+ rvalue->testxt = cpystr(p); -+ data += strlen(p) + 1 + offset; -+ rvalue->next = parse_group_data(data, error); -+ } -+ else if (p = advance_to_char(data,'}', STRICT, NULL)) -+ rvalue->testxt = cpystr(p); -+ else{ -+ err++; -+ free_token_value(&rvalue); -+ } -+ if (error) -+ *error += err; -+ return(rvalue); -+ } -+ -+ CONDITION_S * -+ fill_condition(data) -+ char *data; -+ { -+ CONDITION_S *condition; -+ int i, done, error = 0; -+ char *group; -+ -+ for (i = 0, done = 0; !done && (i < NTOKENS); i++) -+ done = strncmp(data,token_rules[i], strlen(token_rules[i])) ? 0 : 1; -+ if (done){ -+ condition = (CONDITION_S *) alloc_mem(sizeof(CONDITION_S)); -+ condition->tname = cpystr(token_rules[--i]); -+ } -+ else -+ return (CONDITION_S *)NULL; -+ -+ data += strlen(token_rules[i]); -+ for (; *data && *data == ' '; data++); -+ if (*data){ -+ for (i = 0, done = 0; !done && (i < NREL); i++) -+ done = strncmp(data, rel_rules_test[i].value, 2) ? 0 : 1; -+ if (done) -+ condition->ttype = rel_rules_test[--i].ttype; -+ else{ -+ free_condition(&condition); -+ return (CONDITION_S *) NULL; -+ } -+ } -+ data += 2; -+ for (; *data && *data == ' '; data++); -+ if (*data++ != '{'){ -+ free_condition(&condition); -+ return (CONDITION_S *) NULL; -+ } -+ group = advance_to_char(data,'}', STRICT, &error); -+ if (group || (!group && error < 0)){ -+ condition->value = parse_group_data(data, &error); -+ if(group && error) -+ free_condition(&condition); -+ if(group) -+ fs_give((void **) &group); -+ } -+ else -+ free_condition(&condition); -+ return condition; -+ } -+ -+ CONDITION_S * -+ parse_condition (data, eoc) -+ char *data; -+ int *eoc; /* end of condition, equal to -1 on error */ -+ { -+ CONDITION_S *condition = NULL; -+ char *p = data, *cvalue; -+ int len, error = 0, rv; -+ -+ if((rv = isolate_condition(data, &cvalue, &len)) > 0){ -+ if(condition = fill_condition(cvalue)) -+ condition->next = parse_condition(data+len, eoc); -+ else -+ error++; -+ } -+ *eoc += len; -+ if (error) -+ *eoc = -1; -+ return condition; -+ } -+ -+ RULEACTION_S * -+ parse_action (data, context) -+ char *data; -+ int context; -+ { -+ int i, done; -+ RULEACTION_S *raction = NULL; -+ char *function, *p = data; -+ -+ if (!p) -+ return (RULEACTION_S *) NULL; -+ -+ for (; *p && *p == ' '; p++); -+ if (!*p) -+ return (RULEACTION_S *) NULL; -+ -+ if (is_save){ -+ raction = (RULEACTION_S *) alloc_mem(sizeof(RULEACTION_S)); -+ raction->function = cpystr("_SAVE_"); -+ raction->value = (TOKEN_VALUE *) alloc_mem(sizeof(TOKEN_VALUE)); -+ raction->context |= FOR_SAVE; -+ raction->exec = extended_value; -+ raction->value->testxt = cpystr(p); -+ return raction; -+ } -+ for (i = 0, done = 0; !done && (i < NFCN); i++) -+ done = (strstr(p,rule_fcns[i].name) == p); -+ p += done ? strlen(rule_fcns[--i].name) + 1 : 0; -+ if(!*p || (rule_fcns[i].what_for && !(rule_fcns[i].what_for & context))) -+ return (RULEACTION_S *) NULL; -+ if (done){ -+ raction = (RULEACTION_S *) alloc_mem(sizeof(RULEACTION_S)); -+ raction->function = cpystr(rule_fcns[i].name); -+ raction->context = rule_fcns[i].what_for; -+ raction->exec = rule_fcns[i].execute; -+ raction->value = (TOKEN_VALUE *) alloc_mem(sizeof(TOKEN_VALUE)); -+ raction->value->testxt = advance_to_char(p,'}', STRICT, NULL); -+ if(!raction->value->testxt) -+ free_ruleaction(&raction); -+ return raction; -+ } -+ -+ done = (((function = strstr(p, "_TRIM_")) != NULL) -+ ? 1 : ((function = strstr(p, "_REXTRIM_")) != NULL) -+ ? 2 : ((function = strstr(p, "_REPLACE_")) != NULL) -+ ? 3 : 0); -+ -+ if(!function) -+ return (RULEACTION_S *) NULL; -+ -+ *function = '\0'; -+ raction = (RULEACTION_S *) alloc_mem(sizeof(RULEACTION_S)); -+ raction->token = get_name_token(p); -+ *function = '_'; -+ p += strlen(raction->token) + 1; -+ for (; *p && *p == ' '; p++); -+ if (!strncmp(p,":=",2)) -+ p += 2; -+ else{ -+ free_ruleaction(&raction); -+ return (RULEACTION_S *) NULL; -+ } -+ for (; *p && *p == ' '; p++); -+ if (p != function){ -+ free_ruleaction(&raction); -+ return (RULEACTION_S *) NULL; -+ } -+ p += done == 1 ? 6: 9; -+ if (*p != '{'){ -+ free_ruleaction(&raction); -+ return (RULEACTION_S *) NULL; -+ } -+ *p = '\0'; -+ for(i = 0; i < NFCN && strcmp(function, rule_fcns[i].name);i++); -+ raction->function = cpystr(function); -+ raction->is_trim = strcmp(function,"_TRIM_") ? 0 : 1; -+ raction->is_rextrim = strcmp(function,"_REXTRIM_") ? 0 : 1; -+ raction->is_replace = strcmp(function,"_REPLACE_") ? 0 : 1; -+ raction->context = rule_fcns[i].what_for; -+ raction->exec = rule_fcns[i].execute; -+ *p++ = '{'; -+ raction->value = parse_group_data(p, NULL); -+ if(!raction->value->testxt) -+ free_ruleaction(&raction); -+ return raction; -+ } -+ -+ RULE_S * -+ parse_rule (data, context) -+ char *data; -+ int context; -+ { -+ RULE_S *prule; /*parsed rule */ -+ int len = 0; -+ -+ if (!(prule = (RULE_S *) alloc_mem(sizeof(RULE_S))) || -+ !(prule->condition = parse_condition(data, &len)) || -+ !(prule->action = parse_action(data+len, context))) -+ free_rule(&prule); -+ -+ return prule; -+ } -+ -+ RULELIST * -+ get_rule_list(list, context, i) -+ char **list; -+ int context, i; -+ { -+ RULE_S *rule; -+ RULELIST *trulelist = NULL; -+ -+ if (list[i] && *list[i]){ -+ if(rule = parse_rule(list[i], context)){ -+ trulelist = (RULELIST *)alloc_mem(sizeof(RULELIST)); -+ trulelist->prule = rule; -+ trulelist->next = get_rule_list(list, context, i+1); -+ } -+ else -+ trulelist = get_rule_list(list, context, i+1); -+ } -+ return trulelist; -+ } -+ -+ PRULELIST_S * -+ add_prule(rule_list, rule) -+ PRULELIST_S *rule_list; -+ PRULELIST_S *rule; -+ { -+ if (!rule_list) -+ rule_list = (PRULELIST_S *) alloc_mem(sizeof(PRULELIST_S)); -+ -+ if(rule_list->next) -+ rule_list->next = add_prule(rule_list->next, rule); -+ else{ -+ if (rule_list->rlist) -+ rule_list->next = rule; -+ else -+ rule_list = rule; -+ } -+ return rule_list; -+ } -+ -+ void -+ add_rule(code, context) -+ int code, context; -+ { -+ char **list = ps_global->vars[code].current_val.l; -+ PRULELIST_S *prulelist, *trulelist, *orulelist; -+ -+ if (list && *list && **list){ -+ trulelist = (PRULELIST_S *)alloc_mem(sizeof(PRULELIST_S)); -+ trulelist->varnum = code; -+ if (trulelist->rlist = get_rule_list(list, context, 0)) -+ ps_global->rule_list = add_prule(ps_global->rule_list, trulelist); -+ else -+ free_parsed_rule_list(&trulelist); -+ } -+ } -+ -+ void -+ create_rule_list(void) -+ { -+ add_rule(V_THREAD_DISP_STYLE_RULES,FOR_RULE|FOR_THREAD); -+ add_rule(V_THREAD_INDEX_STYLE_RULES,FOR_RULE|FOR_THREAD); -+ add_rule(V_COMPOSE_RULES,FOR_RULE|FOR_COMPOSE); -+ add_rule(V_FORWARD_RULES,FOR_RULE|FOR_COMPOSE); -+ add_rule(V_INDEX_RULES,FOR_RULE|FOR_INDEX); -+ add_rule(V_REPLACE_RULES,FOR_RULE|FOR_REPLACE); -+ add_rule(V_REPLY_INDENT_RULES,FOR_RULE|FOR_COMPOSE); -+ add_rule(V_REPLY_LEADIN_RULES,FOR_RULE|FOR_REPLY_INTRO); -+ add_rule(V_RESUB_RULES,FOR_RULE|FOR_RESUB|FOR_TRIM); -+ add_rule(V_SAVE_RULES,FOR_RULE|FOR_SAVE); -+ add_rule(V_SMTP_RULES,FOR_RULE|FOR_COMPOSE); -+ add_rule(V_SORT_RULES,FOR_RULE|FOR_SORT); -+ add_rule(V_STARTUP_RULES,FOR_RULE|FOR_STARTUP); -+ } -+ -+ int -+ condition_contains_token(condition, token) -+ CONDITION_S *condition; -+ char *token; -+ { -+ if (!condition) -+ return 0; -+ -+ if (!strcmp(condition->tname, token)) -+ return 1; -+ else -+ return condition_contains_token(condition->next, token); -+ } -+ -+ RULELIST * -+ get_rulelist_from_code(code, list) -+ int code; -+ PRULELIST_S *list; -+ { -+ if (!list) -+ return (RULELIST *) NULL; -+ -+ if(list->varnum == code) -+ return list->rlist; -+ else -+ return get_rulelist_from_code(code, list->next); -+ } -+ -+ char * -+ test_rule(rlist, ctxt, env, n) -+ RULELIST *rlist; -+ int ctxt, *n; -+ ENVELOPE *env; -+ { -+ char *result; -+ -+ if(!rlist) -+ return NULL; -+ -+ if (result = process_rule(rlist->prule, ctxt, env)) -+ return result; -+ else{ -+ (*n)++; -+ return test_rule(rlist->next, ctxt, env, n); -+ } -+ } -+ -+ RULE_S * -+ get_rule (rule, n) -+ RULELIST *rule; -+ int n; -+ { -+ if (!rule) -+ return (RULE_S *) NULL; -+ -+ return n ? get_rule(rule->next, n-1) : rule->prule; -+ } -+ -+ /* get_result_rule: -+ * Parameters: list: the list of rules to be passed to the function to check -+ * rule_context: context of the rule -+ * env : envelope used to check the rule, if needed. -+ * -+ * Returns: The value of the first rule that is satisfied in the list, or -+ * NULL if not. This function should be called in the following -+ * way (notice that memory is freed by caller). -+ * -+ * You should use this function to obtain the result of a rule. You can -+ * also call directly "process_rule", but I advice to use this function if -+ * there's no difference on which function to call. -+ -+ RULE_RESULT *rule; -+ -+ rule = (RULE_RESULT *) -+ get_result_rule(V_SOME_RULE, context, envelope); -+ -+ if (rule){ -+ assign the value of rule->result; -+ if (rule->result) -+ fs_give((void **)&rule->result); -+ fs_give((void **)&rule); -+ } -+ */ -+ -+ RULE_RESULT * -+ get_result_rule(code, rule_context, env) -+ int code, rule_context; -+ ENVELOPE *env; -+ { -+ char *rule_result; -+ RULE_RESULT *rule = NULL; -+ RULELIST *rlist; -+ int n = 0; -+ -+ rlist = get_rulelist_from_code(code, ps_global->rule_list); -+ if (rlist){ -+ rule_result = test_rule(rlist, rule_context, env, &n); -+ if (rule_result && *rule_result){ -+ rule = (RULE_RESULT *) fs_get (sizeof(RULE_RESULT)); -+ rule->result = rule_result; -+ rule->number = n; -+ } -+ } -+ return rule; -+ } -+ -+ /* process_rule: -+ Parameters: rule_data, is a rule. It's obtained as -+ rule_data = ps_global->VAR_SOME_RULE[n], for -+ some integer n -+ rule_context: context of the rule, and -+ env: An envelope if needed. -+ -+ Returns : The value of the processed rule_data if the processing was -+ successful and matches context and possibly the envelope, or -+ NULL if there's no match -+ */ -+ -+ char * -+ process_rule (prule, rule_context, env) -+ RULE_S *prule; -+ int rule_context; -+ ENVELOPE *env; -+ { -+ int rv; -+ char *result = NULL; -+ CONDITION_S *condition; -+ -+ if(!prule) -+ return NULL; -+ -+ for(condition = prule->condition; -+ condition && -+ (rv = test_condition(condition, rule_context, env)); -+ condition = condition->next); -+ -+ if(rv && !condition) -+ result = (prule->action->exec)(prule->action, rule_context, env); -+ -+ return result; -+ } -+ -+ TOKEN_VALUE * -+ copy_parsed_value(value, ctxt, env) -+ TOKEN_VALUE *value; -+ int ctxt; -+ ENVELOPE *env; -+ { -+ TOKEN_VALUE *tval = NULL; -+ -+ if(!value) -+ return NULL; -+ -+ if(value->testxt){ -+ tval = (TOKEN_VALUE *) alloc_mem(sizeof(TOKEN_VALUE)); -+ tval->testxt = detoken_src(value->testxt, ctxt, env, NULL, NULL, NULL); -+ } -+ if(value->next) -+ tval->next = copy_parsed_value(value->next, ctxt, env); -+ -+ return tval; -+ } -+ -+ int -+ test_condition(condition, rule_context, env) -+ CONDITION_S *condition; -+ int rule_context; -+ ENVELOPE *env; -+ { -+ int next_step; -+ TOKEN_VALUE *group; -+ -+ group = copy_parsed_value(condition->value, rule_context, env); -+ next_step = (*rel_rules_test[condition->ttype].execute)(condition, group, env, rule_context); -+ free_token_value(&group); -+ return next_step; -+ } -+ -+ /* returns the name of the token it found or NULL if there is no token, the -+ * real value of the token is obtained by calling the detoken_src function. -+ */ -+ -+ char * -+ get_name_token (condition) -+ char *condition; -+ { -+ char *p = NULL, *q, *s; -+ -+ if ((q = strchr(condition,'_')) && (s = strchr(q+1,'_'))){ -+ char c = *++s; -+ *s = '\0'; -+ p = cpystr(q); -+ *s = c; -+ } -+ return p; -+ } -+ -+ /* This function tests if a string contained in the variable "group" is -+ * in the "condition" -+ */ -+ int test_in (condition, group, env, context) -+ TOKEN_VALUE *group; -+ CONDITION_S *condition; -+ ENVELOPE *env; -+ int context; -+ { -+ int rv = 0; -+ char *test; -+ TOKEN_VALUE *test_group = group; -+ -+ test = detoken_src(condition->tname, context, env, NULL, NULL, NULL); -+ if (test){ -+ while (rv == 0 && test_group){ -+ if(!*test || strstr(test_group->testxt, test)) -+ rv++; -+ else -+ test_group = test_group->next; -+ } -+ } -+ return rv; -+ } -+ -+ int test_ni (condition, group, env, context) -+ TOKEN_VALUE *group; -+ CONDITION_S *condition; -+ ENVELOPE *env; -+ int context; -+ { -+ int rv = 0; -+ char *test; -+ TOKEN_VALUE *test_group = group; -+ -+ test = detoken_src(condition->tname, context, env, NULL, NULL, NULL); -+ if (test){ -+ if(!test_group) -+ rv++; -+ while (rv == 0 && test_group){ -+ if(!*test_group->testxt || strstr(test, test_group->testxt)) -+ rv++; -+ else -+ test_group = test_group->next; -+ } -+ } -+ return rv; -+ } -+ -+ int test_not_in (condition, group, env, context) -+ TOKEN_VALUE *group; -+ CONDITION_S *condition; -+ ENVELOPE *env; -+ int context; -+ { -+ return !test_in(condition, group, env, context); -+ } -+ -+ int test_not_ni (condition, group, env, context) -+ TOKEN_VALUE *group; -+ CONDITION_S *condition; -+ ENVELOPE *env; -+ int context; -+ { -+ return !test_ni(condition, group, env, context); -+ } -+ -+ int test_eq (condition, group, env, context) -+ CONDITION_S *condition; -+ TOKEN_VALUE *group; -+ ENVELOPE *env; -+ int context; -+ { -+ int rv = 0; -+ char *test; -+ TOKEN_VALUE *test_group = group; -+ -+ test = detoken_src(condition->tname, context, env, NULL, NULL, NULL); -+ if (test){ -+ while (rv == 0 && test_group){ -+ if((!*test && !*test_group->testxt) || !strcmp(test_group->testxt, test)) -+ rv++; -+ else -+ test_group = test_group->next; -+ } -+ } -+ return rv; -+ } -+ -+ int test_not_eq (condition, group, env, context) -+ CONDITION_S *condition; -+ TOKEN_VALUE *group; -+ ENVELOPE *env; -+ int context; -+ { -+ return !test_eq(condition, group, env, context); -+ } -+ -+ char * -+ do_trim (test, tval) -+ char *test; -+ TOKEN_VALUE *tval; -+ { -+ char *begin_text; -+ int offset = 0; -+ -+ if (!tval) -+ return test; -+ -+ while(begin_text = strstr(test+offset,tval->testxt)){ -+ strcpy(begin_text, begin_text+strlen(tval->testxt)); -+ offset = begin_text - test; -+ } -+ -+ return do_trim(test, tval->next); -+ } -+ -+ char * -+ trim (action, context, env) -+ RULEACTION_S *action; -+ int context; -+ ENVELOPE *env; -+ { -+ char *begin_text, *test; -+ RULEACTION_S *taction = action; -+ int offset; -+ -+ if (taction->context & context){ -+ test = detoken_src(taction->token, context, env, NULL, NULL, NULL); -+ if (test) -+ test = do_trim(test, taction->value); -+ return test; -+ } -+ return NULL; -+ } -+ -+ -+ char * -+ do_rextrim (test, tval) -+ char *test; -+ TOKEN_VALUE *tval; -+ { -+ char *begin_text, *trim_text; -+ int offset = 0; -+ -+ if (!tval) -+ return test; -+ -+ trim_text = expand(test, tval->testxt); -+ while(trim_text && (begin_text = strstr(test+offset,trim_text))){ -+ strcpy(begin_text, begin_text+strlen(trim_text)); -+ offset = begin_text - test; -+ } -+ -+ return do_rextrim(test, tval->next); -+ } -+ -+ char * -+ rextrim (action, context, env) -+ RULEACTION_S *action; -+ int context; -+ ENVELOPE *env; -+ { -+ char *begin_text, *trim_text, *test; -+ RULEACTION_S *taction = action; -+ TOKEN_VALUE **token = NULL; -+ int offset; -+ -+ if (taction->context & context){ -+ test = detoken_src(taction->token, context, env, NULL, NULL, NULL); -+ if (test){ -+ test = do_rextrim(test, taction->value); -+ } -+ return test; -+ } -+ else -+ return NULL; -+ } -+ -+ char * -+ raw_value (action, context,env) -+ RULEACTION_S *action; -+ int context; -+ ENVELOPE *env; -+ { -+ return (action->context & context) ? cpystr(action->value->testxt) : NULL; -+ } -+ -+ char * -+ extended_value (action, ctxt,env) -+ RULEACTION_S *action; -+ int ctxt; -+ ENVELOPE *env; -+ { -+ return (action->context & ctxt) -+ ? detoken_src(action->value->testxt, ctxt, env, NULL, NULL, NULL) -+ : NULL; -+ } -+ -+ /* advances given_string until it finds given_char */ -+ char * -+ advance_to_char(given_string,given_char, flag, error) -+ char *given_string; -+ char given_char; -+ int flag; -+ int *error; -+ { -+ char *b, *s, c; -+ int i, err = 0, quoted ; -+ -+ if (error) -+ *error = 0; -+ -+ if (!given_string || !*given_string) -+ return NULL; -+ -+ b = s = cpystr(given_string); -+ for(i = 0, quoted = 0, c = *s; c ; c = *++s){ -+ if(c == '\\'){ -+ quoted++; -+ continue; -+ } -+ if(quoted){ -+ quoted = 0; -+ if (c == given_char){ -+ err += flag & STRICT ? 0 : 1; -+ err++; -+ break; -+ } -+ b[i++] = '\\'; -+ } -+ if(c == given_char){ -+ err += flag & STRICT ? 0 : 1; -+ break; -+ } -+ b[i++] = c; -+ } -+ b[i] = '\0'; -+ if (b && (strlen(b) == strlen(given_string)) && (flag & STRICT)) -+ return NULL; /* character not found */ -+ -+ if(b && !*b){ -+ fs_give((void **)&b); -+ err = -1; -+ } -+ -+ if (error) -+ *error = err; -+ -+ return b; -+ } -+ -+ /* Regular Expressions Support */ -+ -+ char * -+ expand (string, pattern) -+ char *string; -+ char *pattern; -+ { -+ char tmp[1000]; -+ int error, i = 0; -+ char *new_start, c; -+ char *ret_string = NULL; -+ regex_t preg; -+ regmatch_t pmatch; -+ -+ if (error = regcomp(&preg, pattern, REG_EXTENDED)){ -+ regerror(error, &preg, tmp, 1000); -+ return NULL; -+ } -+ -+ if(((error = regexec(&preg, string, 1, &pmatch, 0)) != REG_NOMATCH)&& !error){ -+ c = string[pmatch.rm_eo]; -+ string[pmatch.rm_eo] = '\0'; -+ ret_string = cpystr(string+pmatch.rm_so); -+ string[pmatch.rm_eo] = c; -+ } -+ return ret_string; -+ } -diff -rc pine4.63/pine/rules.h pine4.63.I.USE/pine/rules.h -*** pine4.63/pine/rules.h Thu May 19 19:59:15 2005 ---- pine4.63.I.USE/pine/rules.h Thu May 19 19:57:27 2005 -*************** -*** 0 **** ---- 1,204 ---- -+ #include "headers.h" -+ #ifndef _REGEX_H_ -+ #include <regex.h> -+ #endif -+ -+ int is_save; /* this rule has the form condition -> folder */ -+ typedef struct { -+ char *value; -+ int type; -+ } RULE_ACTION; -+ -+ -+ RULE_RESULT *get_result_rule PROTO ((int, int, ENVELOPE *)); -+ char *test_rule PROTO ((RULELIST *, int, ENVELOPE *, int *)); -+ char *process_rule PROTO ((RULE_S *, int, ENVELOPE *)); -+ int test_condition PROTO ((CONDITION_S *, int, ENVELOPE *)); -+ int test_in PROTO ((CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int)); -+ int test_ni PROTO ((CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int)); -+ int test_not_in PROTO ((CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int)); -+ int test_not_ni PROTO ((CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int)); -+ int test_eq PROTO ((CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int)); -+ int test_not_eq PROTO ((CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int)); -+ char *trim PROTO ((RULEACTION_S *, int, ENVELOPE *)); -+ char *rextrim PROTO ((RULEACTION_S *, int, ENVELOPE *)); -+ char *raw_value PROTO ((RULEACTION_S *, int, ENVELOPE *)); -+ char *extended_value PROTO ((RULEACTION_S *, int, ENVELOPE *)); -+ char *expand PROTO((char *, char *)); -+ char *get_name_token PROTO((char *)); -+ char *advance_to_char PROTO ((char *, char, int, int *)); -+ -+ /* Separators: -+ * -+ * A separator is a string that separates the rule condition with the rule -+ * action. Below is the list of separators -+ * -+ */ -+ -+ #define SAVE_TO_SEP "->" -+ #define APPLY_SEP "=>" -+ -+ /*------- Definitions of tokens -------*/ -+ /*------ Keep the list alphabetically sorted, thanks -------*/ -+ -+ #define ADDR_TOKEN "_ADDRESS_" -+ #define ADDCC_TOKEN "_ADDRESSCC_" -+ #define ADDRECIP_TOKEN "_ADDRESSRECIPS_" -+ #define ADDTO_TOKEN "_ADDRESSTO_" -+ #define BCC_TOKEN "_BCC_" -+ #define CC_TOKEN "_CC_" -+ #define COLLECT_TOKEN "_COLLECTION_" -+ #define FLAG_TOKEN "_FLAG_" -+ #define FOLDER_TOKEN "_FOLDER_" -+ #define FADDRESS_TOKEN "_FORWARDADDRESS_" -+ #define FFROM_TOKEN "_FORWARDFROM_" -+ #define FROM_TOKEN "_FROM_" -+ #define LCC_TOKEN "_LCC_" -+ #define NICK_TOKEN "_NICK_" -+ #define ROLE_TOKEN "_ROLE_" -+ #define SEND_TOKEN "_SENDER_" -+ #define SUBJ_TOKEN "_SUBJECT_" -+ #define THDDSPSTY_TOKEN "_THREADSTYLE_" -+ #define THDNDXSTY_TOKEN "_THREADINDEX_" -+ #define TO_TOKEN "_TO_" -+ -+ /* Mail related tokens -+ * -+ * The following is an array with the list of tokens. -+ */ -+ -+ char* token_rules[] = { -+ FROM_TOKEN, -+ NICK_TOKEN, -+ ROLE_TOKEN, -+ FOLDER_TOKEN, -+ SUBJ_TOKEN, -+ THDDSPSTY_TOKEN, -+ THDNDXSTY_TOKEN, -+ FLAG_TOKEN, -+ COLLECT_TOKEN, -+ THDDSPSTY_TOKEN, -+ ADDR_TOKEN, -+ TO_TOKEN, -+ ADDTO_TOKEN, -+ ADDCC_TOKEN, -+ ADDRECIP_TOKEN, -+ SEND_TOKEN, -+ CC_TOKEN, -+ LCC_TOKEN, -+ BCC_TOKEN, -+ FFROM_TOKEN, -+ FADDRESS_TOKEN, -+ NULL -+ }; -+ -+ #define NTOKENS (sizeof(token_rules)/sizeof(token_rules[0]) - 1) -+ -+ /*------ Definitions of relational operands -------------*/ -+ -+ typedef struct { -+ char *value; -+ TestType ttype; -+ int (*execute)(); -+ } REL_TOKEN; -+ -+ /* Relational Operands */ -+ #define AND_REL "&&" /* For putting more than one condition */ -+ #define IN_REL "<<" /* For belonging relation */ -+ #define NI_REL ">>" /* For contain relation */ -+ #define NOT_IN_REL "!<" /* Negation of IN_REL */ -+ #define NOT_NI_REL "!>" /* Negation of NI_REL */ -+ #define EQ_REL "==" /* Test of equality */ -+ #define NOT_EQ_REL "!=" /* Test of inequality */ -+ #define OPEN_SET "{" /* Braces to open a set */ -+ #define CLOSE_SET "}" /* Braces to close a set*/ -+ -+ REL_TOKEN rel_rules_test[] = { -+ {EQ_REL, Equal, test_eq}, -+ {IN_REL, Subset, test_in}, -+ {NI_REL, Includes, test_ni}, -+ {NOT_EQ_REL, NotEqual, test_not_eq}, -+ {NOT_IN_REL, NotSubset, test_not_in}, -+ {NOT_NI_REL, NotIncludes, test_not_ni}, -+ {NULL, EndTypes, NULL} -+ }; -+ -+ #define NREL (sizeof(rel_rules_test)/sizeof(rel_rules_test[0]) - 1) -+ -+ /*--- Context in which these variables can be used ---*/ -+ -+ typedef struct use_context { -+ char *name; -+ int what_for; -+ } USE_IN_CONTEXT; -+ -+ -+ static USE_IN_CONTEXT tokens_use[] = { -+ {NICK_TOKEN, FOR_SAVE}, -+ {FROM_TOKEN, FOR_SAVE}, -+ {ROLE_TOKEN, FOR_COMPOSE}, -+ {FOLDER_TOKEN, FOR_SAVE|FOR_FOLDER|FOR_THREAD}, -+ {SUBJ_TOKEN, FOR_SAVE|FOR_FOLDER}, -+ {FLAG_TOKEN, FOR_SAVE|FOR_FLAG}, -+ {COLLECT_TOKEN, FOR_SAVE|FOR_COMPOSE|FOR_FOLDER|FOR_THREAD}, -+ {THDDSPSTY_TOKEN, FOR_THREAD}, -+ {THDNDXSTY_TOKEN, FOR_THREAD}, -+ {ADDR_TOKEN, FOR_SAVE|FOR_FOLDER}, -+ {TO_TOKEN, FOR_SAVE}, -+ {ADDTO_TOKEN, FOR_SAVE|FOR_COMPOSE}, -+ {ADDCC_TOKEN, FOR_SAVE|FOR_COMPOSE}, -+ {ADDRECIP_TOKEN, FOR_SAVE|FOR_COMPOSE}, -+ {SEND_TOKEN, FOR_SAVE}, -+ {CC_TOKEN, FOR_SAVE}, -+ {BCC_TOKEN, FOR_COMPOSE}, -+ {LCC_TOKEN, FOR_COMPOSE}, -+ {FFROM_TOKEN, FOR_COMPOSE}, -+ {FADDRESS_TOKEN, FOR_COMPOSE}, -+ {NULL, FOR_NOTHING} -+ }; -+ -+ -+ typedef struct { -+ char *name; -+ char* (*execute)(); -+ int what_for; -+ } RULE_FCN; -+ -+ #define INDEX_FCN "_INDEX_" -+ #define REPLACE_FCN "_REPLACE_" -+ #define REPLYSTR_FCN "_RESTR_" -+ #define REPLY_FCN "_REPLY_" -+ #define RESUB_FCN "_RESUB_" -+ #define REXTRIM_FCN "_REXTRIM_" -+ #define SAVE_FCN "_SAVE_" -+ #define SIGNATURE_FCN "_SIGNATURE_" -+ #define SMTP_FCN "_SMTP_" -+ #define SORT_FCN "_SORT_" -+ #define STARTUP_FCN "_STARTUP_" -+ #define THRDSTYLE_FCN "_THREADSTYLE_" -+ #define THRDINDEX_FCN "_THREADINDEX_" -+ #define TRIM_FCN "_TRIM_" -+ -+ -+ RULE_FCN rule_fcns[] = { -+ {SAVE_FCN, extended_value, FOR_SAVE}, -+ {REPLY_FCN, extended_value, FOR_REPLY_INTRO}, -+ {TRIM_FCN, trim, FOR_TRIM | FOR_RESUB}, -+ {REPLACE_FCN, extended_value, FOR_REPLACE}, -+ {SORT_FCN, raw_value, FOR_SORT}, -+ {INDEX_FCN, raw_value, FOR_INDEX}, -+ {REPLYSTR_FCN, raw_value, FOR_COMPOSE}, -+ {SIGNATURE_FCN, raw_value, FOR_COMPOSE}, -+ {RESUB_FCN, extended_value, FOR_RESUB}, -+ {STARTUP_FCN, raw_value, FOR_STARTUP}, -+ {REXTRIM_FCN, rextrim, FOR_TRIM | FOR_RESUB}, -+ {THRDSTYLE_FCN, raw_value, FOR_THREAD}, -+ {THRDINDEX_FCN, raw_value, FOR_THREAD}, -+ {SMTP_FCN, raw_value, FOR_COMPOSE} -+ }; -+ -+ #define NFCN (sizeof(rule_fcns)/sizeof(rule_fcns[0])) -+ -+ #define STRICT 0x1 -+ #define RELAXED 0x2 -+ -diff -rc pine4.63/pine/send.c pine4.63.I.USE/pine/send.c -*** pine4.63/pine/send.c Mon Mar 21 12:14:41 2005 ---- pine4.63.I.USE/pine/send.c Thu May 19 19:57:31 2005 -*************** -*** 377,382 **** ---- 377,387 ---- - role->nick = cpystr("Default Role"); - } - -+ if (ps_global->role) -+ fs_give((void **)&ps_global->role); -+ -+ ps_global->role = cpystr(role->nick); -+ - pine_state->redrawer = NULL; - compose_mail(NULL, NULL, role, NULL, NULL); - free_action(&role); -*************** -*** 581,588 **** - } - ps_global->next_screen = prev_screen; - ps_global->redrawer = redraw; -! if(role) - role = combine_inherited_role(role); - } - break; - case 'f': ---- 586,597 ---- - } - ps_global->next_screen = prev_screen; - ps_global->redrawer = redraw; -! if (ps_global->role) -! fs_give((void **)&ps_global->role); -! if(role){ - role = combine_inherited_role(role); -+ ps_global->role = cpystr(role->nick); -+ } - } - break; - case 'f': -*************** -*** 675,680 **** ---- 684,694 ---- - - if(exists & FEX_ISFILE){ - context_apply(tmp, p_cntxt, mbox, sizeof(tmp)); -+ if (!strncmp(tmp, "#md/",4) || !struncmp(tmp, "#mc/", 4)){ -+ char tmp2[MAILTMPLEN]; -+ maildir_file_path(tmp, tmp2); -+ strcpy(tmp, tmp2); -+ } - if(!(IS_REMOTE(tmp) || is_absolute_path(tmp))){ - /* - * The mbox is relative to the home directory. -*************** -*** 775,780 **** ---- 789,799 ---- - - if(exists & FEX_ISFILE){ - context_apply(tmp, p_cntxt, mbox, sizeof(tmp)); -+ if (!strncmp(tmp, "#md/",4) || !struncmp(tmp, "#mc/", 4)){ -+ char tmp2[MAILTMPLEN]; -+ maildir_file_path(tmp, tmp2); -+ strcpy(tmp, tmp2); -+ } - if(!(IS_REMOTE(tmp) || is_absolute_path(tmp))){ - /* - * The mbox is relative to the home directory. -*************** -*** 864,869 **** ---- 883,889 ---- - if(given_to) - rfc822_parse_adrlist(&outgoing->to, given_to, ps_global->maildomain); - -+ outgoing->subject = cpystr(ps_global->subject); - outgoing->message_id = generate_message_id(); - - /* -*************** -*** 894,902 **** - } - } - -! if(role) - q_status_message1(SM_ORDER, 3, 4, "Composing using role \"%.200s\"", - role->nick); - - /* - * The type of storage object allocated below is vitally ---- 914,928 ---- - } - } - -! if (ps_global->role) -! fs_give((void **)&ps_global->role); -! -! -! if(role){ - q_status_message1(SM_ORDER, 3, 4, "Composing using role \"%.200s\"", - role->nick); -+ ps_global->role = cpystr(role->nick); -+ } - - /* - * The type of storage object allocated below is vitally -*************** -*** 2195,2201 **** - static struct headerentry he_template[]={ - {"From : ", "From", h_composer_from, 10, 0, NULL, - build_address, NULL, NULL, addr_book_compose, "To AddrBk", NULL, -! 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, KS_TOADDRBOOK}, - {"Reply-To: ", "Reply To", h_composer_reply_to, 10, 0, NULL, - build_address, NULL, NULL, addr_book_compose, "To AddrBk", NULL, - 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, KS_TOADDRBOOK}, ---- 2221,2227 ---- - static struct headerentry he_template[]={ - {"From : ", "From", h_composer_from, 10, 0, NULL, - build_address, NULL, NULL, addr_book_compose, "To AddrBk", NULL, -! 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, KS_TOADDRBOOK}, - {"Reply-To: ", "Reply To", h_composer_reply_to, 10, 0, NULL, - build_address, NULL, NULL, addr_book_compose, "To AddrBk", NULL, - 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, KS_TOADDRBOOK}, -*************** -*** 2302,2308 **** - #define N_OURREPLYTO 21 - #define N_OURHDRS 22 - #define N_SENDER 23 -! - #define TONAME "To" - #define CCNAME "cc" - #define SUBJNAME "Subject" ---- 2328,2335 ---- - #define N_OURREPLYTO 21 - #define N_OURHDRS 22 - #define N_SENDER 23 -! #define CAN_EDIT(x) (!((x)->never_allow_changing_from) && \ -! F_ON(F_ALLOW_CHANGING_FROM, (x))) - #define TONAME "To" - #define CCNAME "cc" - #define SUBJNAME "Subject" -*************** -*** 2310,2316 **** - /* this is used in pine_send and pine_simple_send */ - /* name::type::canedit::writehdr::localcopy::rcptto */ - static PINEFIELD pf_template[] = { -! {"From", Address, 0, 1, 1, 0}, - {"Reply-To", Address, 0, 1, 1, 0}, - {TONAME, Address, 1, 1, 1, 1}, - {CCNAME, Address, 1, 1, 1, 1}, ---- 2337,2343 ---- - /* this is used in pine_send and pine_simple_send */ - /* name::type::canedit::writehdr::localcopy::rcptto */ - static PINEFIELD pf_template[] = { -! {"From", Address, 1, 1, 1, 0}, - {"Reply-To", Address, 0, 1, 1, 0}, - {TONAME, Address, 1, 1, 1, 1}, - {CCNAME, Address, 1, 1, 1, 1}, -*************** -*** 2459,2465 **** - *p = *(p+4); - - pf->type = pf_template[i].type; -! pf->canedit = pf_template[i].canedit; - pf->rcptto = pf_template[i].rcptto; - pf->writehdr = pf_template[i].writehdr; - pf->localcopy = pf_template[i].localcopy; ---- 2486,2492 ---- - *p = *(p+4); - - pf->type = pf_template[i].type; -! pf->canedit = (i == N_FROM) ? CAN_EDIT(ps_global) : pf_template[i].canedit; - pf->rcptto = pf_template[i].rcptto; - pf->writehdr = pf_template[i].writehdr; - pf->localcopy = pf_template[i].localcopy; -*************** -*** 3175,3180 **** ---- 3202,3210 ---- - pbf = &pbuf1; - standard_picobuf_setup(pbf); - -+ pbf->auto_cmds = ps_global->initial_cmds_backup + -+ ps_global->initial_cmds_offset; -+ - /* - * Cancel any pending initial commands since pico uses a different - * input routine. If we didn't cancel them, they would happen after -*************** -*** 3662,3667 **** ---- 3692,3702 ---- - he->rich_header = 0; - } - } -+ if (F_ON(F_ALLOW_CHANGING_FROM, ps_global) && -+ !ps_global->never_allow_changing_from){ -+ he->display_it = 1; /* show it */ -+ he->rich_header = 0; -+ } - - he_from = he; - break; -*************** -*** 3769,3774 **** ---- 3804,3827 ---- - removing_trailing_white_space(pf->textbuf); - (void)removing_double_quotes(pf->textbuf); - build_address(pf->textbuf, &addr, NULL, NULL, NULL); -+ if (!strncmp(pf->name,"Lcc",3) && addr && *addr){ -+ RULE_RESULT *rule; -+ -+ outgoing->date = cpystr(addr); -+ rule = get_result_rule(V_FORWARD_RULES, -+ FOR_RULE|FOR_COMPOSE|FOR_TRIM, outgoing); -+ if (rule){ -+ addr = cpystr(rule->result); -+ removing_trailing_white_space(addr); -+ (void)removing_extra_stuff(addr); -+ if (rule->result) -+ fs_give((void **)&rule->result); -+ fs_give((void **)&rule); -+ } -+ if (outgoing->date) -+ fs_give((void **)&outgoing->date); -+ } -+ - rfc822_parse_adrlist(pf->addr, addr, - ps_global->maildomain); - fs_give((void **)&addr); -*************** -*** 4274,4282 **** ---- 4327,4338 ---- - /* turn off user input timeout when in composer */ - saved_user_timeout = ps_global->hours_to_timeout; - ps_global->hours_to_timeout = 0; -+ ps_global->in_pico = 1; /* in */ - dprint(1, (debugfile, "\n ---- COMPOSER ----\n")); - editor_result = pico(pbf); -+ ps_global->force_check_now = 0; /* do not check incoming folders now */ - dprint(4, (debugfile, "... composer returns (0x%x)\n", editor_result)); -+ ps_global->in_pico = 0; /* out */ - ps_global->hours_to_timeout = saved_user_timeout; - - #if defined(DOS) && !defined(_WINDOWS) -*************** -*** 4285,4291 **** - #ifdef _WINDOWS - mswin_setwindowmenu (MENU_DEFAULT); - #endif -! fix_windsize(ps_global); - /* - * Only reinitialize signals if we didn't receive an interesting - * one while in pico, since pico's return is part of processing that ---- 4341,4352 ---- - #ifdef _WINDOWS - mswin_setwindowmenu (MENU_DEFAULT); - #endif -! if (ps_global->send_immediately){ -! if(ps_global->free_initial_cmds_backup) -! fs_give((void **)&ps_global->free_initial_cmds_backup); -! } -! else -! fix_windsize(ps_global); - /* - * Only reinitialize signals if we didn't receive an interesting - * one while in pico, since pico's return is part of processing that -*************** -*** 4345,4351 **** - if(outgoing->return_path) - mail_free_address(&outgoing->return_path); - -! outgoing->return_path = rfc822_cpy_adr(outgoing->from); - - /* - * Don't ever believe the sender that is there. ---- 4406,4414 ---- - if(outgoing->return_path) - mail_free_address(&outgoing->return_path); - -! outgoing->return_path = F_ON(F_USE_DOMAIN_NAME,ps_global) -! ? rfc822_cpy_adr(generate_from()) -! : rfc822_cpy_adr(outgoing->from); - - /* - * Don't ever believe the sender that is there. -*************** -*** 4947,4956 **** - if(sending_filter_requested - && !filter_message_text(sending_filter_requested, outgoing, - *body, &orig_so, &header)){ -! q_status_message1(SM_ORDER, 3, 3, - "Problem filtering! Nothing sent%.200s.", - fcc ? " or saved to fcc" : ""); -! continue; - } - - /*------ Actually post -------*/ ---- 5010,5025 ---- - if(sending_filter_requested - && !filter_message_text(sending_filter_requested, outgoing, - *body, &orig_so, &header)){ -! if (!ps_global->send_immediately){ -! q_status_message1(SM_ORDER, 3, 3, - "Problem filtering! Nothing sent%.200s.", - fcc ? " or saved to fcc" : ""); -! continue; -! } -! else{ -! fprintf(stderr, "Problem filtering! Nothing sent or saved to Fcc\n"); -! exit(-1); -! } - } - - /*------ Actually post -------*/ -*************** -*** 5171,5176 **** ---- 5240,5247 ---- - /*----- Mail Post FAILED, back to composer -----*/ - if(result & (P_MAIL_LOSE | P_FCC_LOSE)){ - dprint(1, (debugfile, "Send failed, continuing\n")); -+ if (ps_global->send_immediately) -+ exit(1); - - if(result & P_FCC_LOSE){ - /* -*************** -*** 5205,5210 **** ---- 5276,5282 ---- - update_answered_flags(reply); - - /*----- Signed, sealed, delivered! ------*/ -+ if (!ps_global->send_immediately) - q_status_message(SM_ORDER, 0, 3, - pine_send_status(result, fcc, tmp_20k_buf, NULL)); - -*************** -*** 5789,5795 **** - if(background_posting(FALSE)) - return("Can't send while background posting. Use postpone."); - -! if(F_ON(F_SEND_WO_CONFIRM, ps_global)) - return(NULL); - - ps_global->redrawer = redraw_pico; ---- 5861,5867 ---- - if(background_posting(FALSE)) - return("Can't send while background posting. Use postpone."); - -! if(!ps_global->send_immediately && F_ON(F_SEND_WO_CONFIRM, ps_global)) - return(NULL); - - ps_global->redrawer = redraw_pico; -*************** -*** 5940,5946 **** - - opts[i].ch = -1; - -! fix_windsize(ps_global); - - while(1){ - if(filters && filters->filter && (p = strindex(filters->filter, ' '))) ---- 6012,6019 ---- - - opts[i].ch = -1; - -! if (!ps_global->send_immediately) -! fix_windsize(ps_global); - - while(1){ - if(filters && filters->filter && (p = strindex(filters->filter, ' '))) -*************** -*** 6075,6081 **** - - if(double_rad + - (dsn_requested ? 4 : F_ON(F_DSN, ps_global) ? 1 : 0) > 11) -! rv = double_radio_buttons(tmp_20k_buf, -FOOTER_ROWS(ps_global), opts, - 'y', 'z', - (F_ON(F_DSN, ps_global) && allow_flowed) - ? h_send_prompt_dsn_flowed : ---- 6148,6155 ---- - - if(double_rad + - (dsn_requested ? 4 : F_ON(F_DSN, ps_global) ? 1 : 0) > 11) -! rv = ps_global->send_immediately ? 'y' : -! double_radio_buttons(tmp_20k_buf, -FOOTER_ROWS(ps_global), opts, - 'y', 'z', - (F_ON(F_DSN, ps_global) && allow_flowed) - ? h_send_prompt_dsn_flowed : -*************** -*** 6084,6090 **** - h_send_prompt, - RB_NORM); - else -! rv = radio_buttons(tmp_20k_buf, -FOOTER_ROWS(ps_global), opts, - 'y', 'z', - (double_rad + - (dsn_requested ? 4 : F_ON(F_DSN, ps_global) ---- 6158,6165 ---- - h_send_prompt, - RB_NORM); - else -! rv = ps_global->send_immediately ? 'y' : -! radio_buttons(tmp_20k_buf, -FOOTER_ROWS(ps_global), opts, - 'y', 'z', - (double_rad + - (dsn_requested ? 4 : F_ON(F_DSN, ps_global) -*************** -*** 6671,6679 **** - if(tmp_so = so_get(PicoText, NULL, EDIT_ACCESS)){ - gf_set_so_writec(&pc, tmp_so); - ps_global->mangled_screen = 1; -! suspend_busy_alarm(); -! ClearScreen(); -! fflush(stdout); - if(tmpf){ - PIPE_S *fpipe; - ---- 6746,6756 ---- - if(tmp_so = so_get(PicoText, NULL, EDIT_ACCESS)){ - gf_set_so_writec(&pc, tmp_so); - ps_global->mangled_screen = 1; -! if (!ps_global->send_immediately){ -! suspend_busy_alarm(); -! ClearScreen(); -! fflush(stdout); -! } - if(tmpf){ - PIPE_S *fpipe; - -*************** -*** 6779,6787 **** - b->encoding = ENCOTHER; - set_mime_type_by_grope(b, NULL); - } -! -! ClearScreen(); -! resume_busy_alarm(0); - } - else - errstr = "Can't create space for filtered text."; ---- 6856,6865 ---- - b->encoding = ENCOTHER; - set_mime_type_by_grope(b, NULL); - } -! if (!ps_global->send_immediately){ -! ClearScreen(); -! resume_busy_alarm(0); -! } - } - else - errstr = "Can't create space for filtered text."; -*************** -*** 6812,6821 **** - if(tmp_so) - so_give(&tmp_so); - -! q_status_message1(SM_ORDER | SM_DING, 3, 6, "Problem filtering: %.200s", - errstr); -! dprint(1, (debugfile, "Filter FAILED: %s\n", - errstr ? errstr : "?")); - } - - return(errstr == NULL); ---- 6890,6905 ---- - if(tmp_so) - so_give(&tmp_so); - -! if (!ps_global->send_immediately){ -! q_status_message1(SM_ORDER | SM_DING, 3, 6, "Problem filtering: %.200s", - errstr); -! dprint(1, (debugfile, "Filter FAILED: %s\n", - errstr ? errstr : "?")); -+ } -+ else{ -+ fprintf(stderr, "Filter FAILED: %s\n", errstr ? errstr : "?"); -+ exit(-1); -+ } - } - - return(errstr == NULL); -*************** -*** 6971,6979 **** - char error_buf[200], *error_mess = NULL, *postcmd; - ADDRESS *a; - ENVELOPE *fake_env = NULL; -! int addr_error_count, we_cancel = 0; - long smtp_opts = 0L; -! char *verbose_file = NULL; - BODY *bp = NULL; - PINEFIELD *pf; - ---- 7055,7063 ---- - char error_buf[200], *error_mess = NULL, *postcmd; - ADDRESS *a; - ENVELOPE *fake_env = NULL; -! int addr_error_count, we_cancel = 0, choice, num_rules = 0, added_rules = -1; - long smtp_opts = 0L; -! char *verbose_file = NULL, **smtp_list; - BODY *bp = NULL; - PINEFIELD *pf; - -*************** -*** 7101,7119 **** - * was either none specified or we decided not to use it. So, - * if there's an smtp-server defined anywhere, - */ -! if(alt_smtp_servers && alt_smtp_servers[0] && alt_smtp_servers[0][0]){ -! /*---------- SMTP ----------*/ -! dprint(4, (debugfile, "call_mailer: via TCP (%s)\n", -! alt_smtp_servers[0])); -! TIME_STAMP("smtp-open start (tcp)", 1); -! sending_stream = smtp_open(alt_smtp_servers, smtp_opts); - } -! else if(ps_global->VAR_SMTP_SERVER && ps_global->VAR_SMTP_SERVER[0] -! && ps_global->VAR_SMTP_SERVER[0][0]){ - /*---------- SMTP ----------*/ -! dprint(4, (debugfile, "call_mailer: via TCP\n")); - TIME_STAMP("smtp-open start (tcp)", 1); -! sending_stream = smtp_open(ps_global->VAR_SMTP_SERVER, smtp_opts); - } - else if(postcmd = smtp_command(ps_global->c_client_error)){ - char *cmdlist[2]; ---- 7185,7234 ---- - * was either none specified or we decided not to use it. So, - * if there's an smtp-server defined anywhere, - */ -! -! /* First we check for rules and make a list using the rules */ -! if(ps_global->VAR_SMTP_RULES && ps_global->VAR_SMTP_RULES[0] -! && ps_global->VAR_SMTP_RULES[0][0]) -! while (ps_global->VAR_SMTP_RULES[num_rules]) num_rules++; -! -! if(num_rules){ -! int i = 0, j = 0; -! -! added_rules = 0; -! smtp_list = (char **) fs_get ((num_rules + 1)*sizeof(char*)); -! for (i = 0; i < num_rules; i++){ -! RULELIST *rule = get_rulelist_from_code(V_SMTP_RULES, -! ps_global->rule_list); -! RULE_S *prule = get_rule(rule, i); -! if(prule){ -! char *rule_result = process_rule(prule, FOR_RULE|FOR_COMPOSE, -! header->env); -! if (rule_result && *rule_result){ -! smtp_list[j++] = cpystr(rule_result); -! added_rules++; -! } -! } -! } - } -! -! if (added_rules < 0){ -! smtp_list = (char **) fs_get (sizeof(char*)); -! added_rules = 0; -! } -! smtp_list[added_rules] = NULL; -! -! choice = smtp_list && smtp_list[0] && smtp_list[0][0] ? 3 : -! (alt_smtp_servers && alt_smtp_servers[0] && alt_smtp_servers[0][0] ? 2 : -! (ps_global->VAR_SMTP_SERVER && ps_global->VAR_SMTP_SERVER[0] && ps_global->VAR_SMTP_SERVER[0][0] ? 1 : -1)); -! -! if(choice > 0){ - /*---------- SMTP ----------*/ -! dprint(4, (debugfile, "call_mailer: via TCP (%s)\n", -! smtp_list[0])); - TIME_STAMP("smtp-open start (tcp)", 1); -! sending_stream = smtp_open(choice == 3 ? smtp_list -! : (choice == 2 ? alt_smtp_servers -! : ps_global->VAR_SMTP_SERVER), smtp_opts); - } - else if(postcmd = smtp_command(ps_global->c_client_error)){ - char *cmdlist[2]; -*************** -*** 7313,7318 **** ---- 7428,7435 ---- - - q_status_message(SM_ORDER | SM_DING, 4, 7, error_mess); - dprint(1, (debugfile, "call_mailer ERROR: %s\n", error_mess)); -+ if (ps_global->send_immediately) -+ printf("%s\n",error_mess); - return(-1); - } - else{ -diff -rc pine4.63/pine/signals.c pine4.63.I.USE/pine/signals.c -*** pine4.63/pine/signals.c Thu Nov 4 14:33:05 2004 ---- pine4.63.I.USE/pine/signals.c Thu May 19 19:57:34 2005 -*************** -*** 673,679 **** - - add_review_message(buf, -1); - } -! else{ - q_status_message(SM_ORDER, 0, 1, progress); - - /* ---- 673,680 ---- - - add_review_message(buf, -1); - } -! else if (!ps_global->send_immediately -! && !ps_global->checking_incfld){ - q_status_message(SM_ORDER, 0, 1, progress); - - /* -*************** -*** 683,700 **** - * its min display time yet. In that case, we don't want - * to force out the initial message. - */ -! display_message('x'); - } - } - - #ifdef _WINDOWS - mswin_setcursor (MSWIN_CURSOR_BUSY); - #endif - fflush(stdout); - } - - /* set alarm */ -! if(F_OFF(F_DISABLE_ALARM, ps_global)) - alarm(seconds); - - return(retval); ---- 684,703 ---- - * its min display time yet. In that case, we don't want - * to force out the initial message. - */ -! display_message('x'); - } - } - - #ifdef _WINDOWS - mswin_setcursor (MSWIN_CURSOR_BUSY); - #endif -+ if (!ps_global->send_immediately) - fflush(stdout); - } - - /* set alarm */ -! if(F_OFF(F_DISABLE_ALARM, ps_global) && !ps_global->send_immediately -! && !ps_global->checking_incfld) - alarm(seconds); - - return(retval); -*************** -*** 731,748 **** - - right = (slots_used - 4)/2; - left = slots_used - 4 - right; - sprintf(progress, "%s |%*s100%%%*s|", - busy_message, left, "", right, ""); - q_status_message(SM_ORDER, - message_pri>=2 ? max(message_pri,3) : 0, -! message_pri+2, progress); - } - else{ - sprintf(progress, "%s%*sDONE", busy_message, - DISPLAY_CHARS_COLS - 4 + 1, ""); - q_status_message(SM_ORDER, - message_pri>=2 ? max(message_pri,3) : 0, -! message_pri+2, progress); - } - } - else ---- 734,755 ---- - - right = (slots_used - 4)/2; - left = slots_used - 4 - right; -+ if (!ps_global->send_immediately){ - sprintf(progress, "%s |%*s100%%%*s|", - busy_message, left, "", right, ""); -+ if (!ps_global->checking_incfld) - q_status_message(SM_ORDER, - message_pri>=2 ? max(message_pri,3) : 0, -! message_pri+2, progress);} - } - else{ -+ if (!ps_global->send_immediately){ - sprintf(progress, "%s%*sDONE", busy_message, - DISPLAY_CHARS_COLS - 4 + 1, ""); -+ if (!ps_global->checking_incfld) - q_status_message(SM_ORDER, - message_pri>=2 ? max(message_pri,3) : 0, -! message_pri+2, progress);} - } - } - else -diff -rc pine4.63/pine/status.c pine4.63.I.USE/pine/status.c -*** pine4.63/pine/status.c Tue Apr 26 15:15:45 2005 ---- pine4.63.I.USE/pine/status.c Thu May 19 19:57:28 2005 -*************** -*** 142,147 **** ---- 142,150 ---- - char *clean_msg; - size_t mlen; - -+ if (ps_global->send_immediately) -+ return; -+ - /* - * By convention, we have min_time equal to zero in messages which we - * think are not as important, so-called comfort messages. We have -*************** -*** 1184,1190 **** - char *q2; - int rv; - -! if(!ps_global->ttyo) - return(pre_screen_config_want_to(question, dflt, on_ctrl_C)); - #ifdef _WINDOWS - if (mswin_usedialog ()) { ---- 1187,1193 ---- - char *q2; - int rv; - -! if((!ps_global->ttyo) || (ps_global->send_immediately)) - return(pre_screen_config_want_to(question, dflt, on_ctrl_C)); - #ifdef _WINDOWS - if (mswin_usedialog ()) { -diff -rc pine4.63/pine/strings.c pine4.63.I.USE/pine/strings.c -*** pine4.63/pine/strings.c Fri Apr 15 15:07:17 2005 ---- pine4.63.I.USE/pine/strings.c Thu May 19 19:57:27 2005 -*************** -*** 6069,6075 **** - SortOrder def_sort; - int def_sort_rev; - -! if(decode_sort(p, &def_sort, &def_sort_rev) != -1){ - action->sort_is_set = 1; - action->sortorder = def_sort; - action->revsort = (def_sort_rev ? 1 : 0); ---- 6069,6075 ---- - SortOrder def_sort; - int def_sort_rev; - -! if(decode_sort(p, &def_sort, &def_sort_rev, 0) != -1){ - action->sort_is_set = 1; - action->sortorder = def_sort; - action->revsort = (def_sort_rev ? 1 : 0); -*************** -*** 9624,9629 **** ---- 9624,9635 ---- - break; - - case '#': -+ if(!struncmp(patfolder, "#md/", 4) -+ || !struncmp(patfolder, "#mc/", 4)){ -+ maildir_file_path(patfolder, tmp1); -+ strncpy(patfolder, tmp1, sizeof(patfolder)); -+ patfolder[sizeof(patfolder)-1] = '\0'; -+ } - if(!strcmp(patfolder, stream->mailbox)) - match++; - -*************** -*** 11417,11419 **** ---- 11423,11457 ---- - - return(idata); - } -+ -+ -+ void -+ removing_extra_stuff(string) -+ char *string; -+ { -+ char *p = NULL; -+ int change = 0, length = 0; -+ -+ -+ if(!string) -+ return; -+ -+ for(; *string; string++, length++) -+ p = ((unsigned char)*string != ',') ? NULL : (!p) ? string : p; -+ -+ if(p) -+ *p = '\0'; -+ -+ string -= length; -+ for (; *string; string++){ -+ if (change){ -+ *string = ' '; -+ change = 0; -+ } -+ if ((((unsigned char)*string == ' ') || -+ ((unsigned char)*string == ',')) && -+ ((unsigned char)*(string + 1) == ',')) -+ change++; -+ } -+ } -+ -diff -rc pine4.63/pine/takeaddr.c pine4.63.I.USE/pine/takeaddr.c -*** pine4.63/pine/takeaddr.c Mon Mar 7 15:16:41 2005 ---- pine4.63.I.USE/pine/takeaddr.c Thu May 19 19:57:32 2005 -*************** -*** 1782,1791 **** ---- 1782,1793 ---- - TA_S *p; - int rc, found = 0, wrapped = 0, flags; - char *result = NULL, buf[MAX_SEARCH+1], tmp[MAX_SEARCH+20]; -+ static char last_pat[MAX_SEARCH+1] = {'\0'}; - static char last[MAX_SEARCH+1]; - HelpType help; - static ESCKEY_S ekey[] = { - {0, 0, "", ""}, -+ {ctrl('N'), 9, "^N", "Ins Pat"}, - {ctrl('Y'), 10, "^Y", "Top"}, - {ctrl('V'), 11, "^V", "Bottom"}, - {-1, 0, NULL, NULL}}; -*************** -*** 1806,1822 **** - tmp,ekey,help,&flags); - if(rc == 3) - help = help == NO_HELP ? h_config_whereis : NO_HELP; -! else if(rc == 0 || rc == 1 || rc == 10 || rc == 11 || !buf[0]){ - if(rc == 0 && !buf[0] && last[0]){ - strncpy(buf, last, sizeof(buf)-1); - buf[sizeof(buf)-1] = '\0'; - } -! -! break; - } - } - - if(rc == 0 && buf[0]){ - p = current; - while(p = next_taline(p)) - if(srchstr((char *)rfc1522_decode((unsigned char *)tmp_20k_buf, ---- 1808,1828 ---- - tmp,ekey,help,&flags); - if(rc == 3) - help = help == NO_HELP ? h_config_whereis : NO_HELP; -! else if(rc == 0 || rc == 1 || rc == 10 || rc == 11 || rc == 9 || !buf[0]){ - if(rc == 0 && !buf[0] && last[0]){ - strncpy(buf, last, sizeof(buf)-1); - buf[sizeof(buf)-1] = '\0'; - } -! if (rc == 9) -! insert_pattern_in_string(buf, last_pat, MAX_SEARCH); -! else -! break; - } - } - - if(rc == 0 && buf[0]){ -+ strncpy(last_pat, buf, sizeof(last_pat)); -+ last_pat[sizeof(last_pat)-1] = '\0'; - p = current; - while(p = next_taline(p)) - if(srchstr((char *)rfc1522_decode((unsigned char *)tmp_20k_buf, diff --git a/packages/pine/pine-4.63/pine-ldap3.patch b/packages/pine/pine-4.63/pine-ldap3.patch deleted file mode 100644 index a824438fbd..0000000000 --- a/packages/pine/pine-4.63/pine-ldap3.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- pine4.63/pine/bldaddr.c.orig 2005-07-12 15:40:04.000000000 +0200 -+++ pine4.63/pine/bldaddr.c 2005-07-12 15:40:14.000000000 +0200 -@@ -6504,7 +6504,7 @@ - ldap_v3_is_supported(ld) - LDAP *ld; - { -- int v3_is_supported_by_server = 0; -+ int v3_is_supported_by_server = 1; - #ifdef NO_VERSION3_PROTO_YET - /* - * When we use version 3 protocol we will be getting back utf8 results. diff --git a/packages/pine/pine-4.63/transparency.patch b/packages/pine/pine-4.63/transparency.patch deleted file mode 100644 index 890cf13f6c..0000000000 --- a/packages/pine/pine-4.63/transparency.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -ru pine4.55-orig/pico/osdep/unix pine4.55/pico/osdep/unix ---- pine4.55-orig/pico/osdep/unix 2003-04-15 17:20:22.000000000 -0500 -+++ pine4.55/pico/osdep/unix 2003-06-23 13:05:19.000000000 -0500 -@@ -998,7 +998,9 @@ - if(ANSI_COLOR()){ - char buf[10]; - -- if(color < 8) -+ if(color == 0) -+ memcpy(buf, "\033[49m", 6); -+ else if(color < 8) - sprintf(buf, "\033[4%cm", color + '0'); - else - sprintf(buf, "\033[10%cm", (color-8) + '0'); diff --git a/packages/pine/pine_4.63.bb b/packages/pine/pine_4.63.bb deleted file mode 100644 index 87cf602c96..0000000000 --- a/packages/pine/pine_4.63.bb +++ /dev/null @@ -1,82 +0,0 @@ -DESCRIPTION = "Pine(R) - a Program for Internet News & Email" -PR = "r1" -SECTION = "console/network" -LICENSE = "Pine" -DEPENDS = "ncurses libldap" -RDEPENDS_pine = "pico" -HOMEPAGE = "http://www.washington.edu/pine/" -MAINTAINER = "Michael 'Mickey' Lauer <mickey_at_Vanille.de>" - -SRC_URI = "ftp://ftp.cac.washington.edu/pine/pine.tar.bz2 \ - file://pine-4.63/pine-4.63-r2-chappa-all.patch;patch=1 \ - file://pine-4.63/pine-4.62-spooldir-permissions.patch;patch=1 \ - file://pine-4.63/pine-4.30-ldap.patch;patch=1 \ - file://pine-4.63/pine-ldap3.patch;patch=1 \ - file://pine-4.63/pine-4.56-passfile.patch;patch=1 \ - file://pine-4.63/pine-4.61-largeterminal.patch;patch=1 \ - file://pine-4.63/pine-4.31-segfix.patch;patch=1 \ - file://pine-4.63/pine-4.40-lockfile-perm.patch;patch=1 \ - file://pine-4.63/imap-2000-time.patch;patch=1 \ - file://pine-4.63/transparency.patch;patch=1 \ - file://pine-4.63/pine-4.61-subjectlength.patch;patch=1" - -S = "${WORKDIR}/pine${PV}" - -inherit autotools - -# -# ~lart Pine's build structure... -# -PARALLEL_MAKE = "" -EXTRA_OEMAKE = "-e" -export MAKE = 'MAKE="make -e" make -e' - -CFLAGS += "-I${S}/imap/c-client" -LDFLAGS += "${S}/imap/c-client/c-client.a -lssl -lcrypt" - -export SSLDEFINES = "-DSSL_CERT_DIRECTORY=\\"/etc/ssl/certs\\" -DSSL_KEY_DIRECTORY=\\"/etc/ssl/private\\"" -export SSLCFLAGS = "${CFLAGS} -I${STAGING_INCDIR}/openssl ${SSLDEFINES}" -export SSLLDFLAGS = "-lssl -lcrypt ${LDFLAGS} -L${STAGING_LIBDIR}/openssl" -export LDAPCFLAGS = "-DENABLE_LDAP" -export LDAPLIBS = "-lldap -llber" -export EXTRALDFLAGS = "${LDFLAGS}" - -do_configure() { - ln -sf ${S}/imap/c-client ${S}/c-client - cd ${S}/pico/osdep && \ - ${BUILD_CC} -o includer includer.c - cd ${S}/pine/osdep && \ - ${BUILD_CC} -o includer includer.c - mkdir ${S}/ldap - cd ${S}/ldap && - ln -sf ${STAGING_INCDIR} include && - ln -sf ${STAGING_LIBDIR} libraries - cd ${S} - sed -e "s:/usr/local/lib/pine.conf:/etc/pine.conf:" \ - -i "${S}/pine/osdep/os-lnx.h" || exit 1 - ls -l ${S}/contrib/ldap-setup -} - -do_compile() { - unset CFLAGS && unset LDFLAGS - cd ${S}/imap && oe_runmake slx - - for i in pico pine - do - cd ${S}/$i && oe_runmake -f makefile.lnx - done -} - -BINARIES = "imap/mailutil/mailutil imap/mlock/mlock pico/pico pico/pilot pine/pine" - -do_install() { - install -d 0644 ${D}${bindir} - for binary in ${BINARIES} - do - install -m 0755 $binary ${D}${bindir} - done -} - -PACKAGES = "pico pine" -FILES_pico = "${bindir}/pico ${bindir}/pilot" - |