aboutsummaryrefslogtreecommitdiffstats
path: root/main/alpine/all_p84.patch
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2015-03-11 09:20:01 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2015-03-11 09:20:01 +0000
commitf293739e0db7bbddff5199f74b6150312c16a6cc (patch)
treeb08354d610b2d0254de3398cb4f13ce093bb7e94 /main/alpine/all_p84.patch
parentebcf082a79f5b36210d7191ce461cc3a9384472e (diff)
downloadaports-f293739e0db7bbddff5199f74b6150312c16a6cc.tar.bz2
aports-f293739e0db7bbddff5199f74b6150312c16a6cc.tar.xz
main/alpine: upgrade to 2.20
Diffstat (limited to 'main/alpine/all_p84.patch')
-rw-r--r--main/alpine/all_p84.patch26592
1 files changed, 0 insertions, 26592 deletions
diff --git a/main/alpine/all_p84.patch b/main/alpine/all_p84.patch
deleted file mode 100644
index c025fc435d..0000000000
--- a/main/alpine/all_p84.patch
+++ /dev/null
@@ -1,26592 +0,0 @@
-diff -rc alpine-2.00/alpine/adrbkcmd.c alpine-2.00.I.USE/alpine/adrbkcmd.c
-*** alpine-2.00/alpine/adrbkcmd.c 2008-05-30 09:52:41.000000000 -0700
---- alpine-2.00.I.USE/alpine/adrbkcmd.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 57,62 ****
---- 57,64 ----
- #include "../pith/send.h"
- #include "../pith/list.h"
- #include "../pith/busy.h"
-+ #include "../pith/icache.h"
-+ #include "../pith/osdep/color.h"
-
-
- /* internal prototypes */
-***************
-*** 1146,1151 ****
---- 1148,1155 ----
- q_status_message1(SM_INFO, 0, 2, _("Address book %s cancelled"), cmd);
- }
- else if(editor_result & COMP_EXIT){
-+ if(pico_usingcolor())
-+ clear_index_cache(ps_global->mail_stream, 0);
- removing_leading_and_trailing_white_space(nick);
- removing_leading_and_trailing_white_space(full);
- removing_leading_and_trailing_white_space(fcc);
-***************
-*** 4123,4128 ****
---- 4127,4134 ----
- * 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{
-***************
-*** 4130,4135 ****
---- 4136,4142 ----
- 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 alpine-2.00/alpine/alpine.c alpine-2.00.I.USE/alpine/alpine.c
-*** alpine-2.00/alpine/alpine.c 2008-06-03 15:31:05.000000000 -0700
---- alpine-2.00.I.USE/alpine/alpine.c 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 193,198 ****
---- 193,199 ----
- #endif
-
- status_message_lock_init();
-+ inverse_itokens();
-
- #if HAVE_SRANDOM
- /*
-***************
-*** 293,298 ****
---- 294,300 ----
- 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);
-***************
-*** 303,308 ****
---- 305,311 ----
- mail_parameters(NULL, SET_SENDCOMMAND, (void *) pine_imap_cmd_happened);
- mail_parameters(NULL, SET_FREESTREAMSPAREP, (void *) sp_free_callback);
- mail_parameters(NULL, SET_FREEELTSPAREP, (void *) free_pine_elt);
-+ mail_parameters(NULL, SET_ERASEPASSWORD, (void *) pine_delete_pwd);
- #ifdef SMIME
- mail_parameters(NULL, SET_FREEBODYSPAREP, (void *) free_smime_body_sparep);
- #endif
-***************
-*** 454,459 ****
---- 457,467 ----
-
- convert_args_to_utf8(pine_state, &args);
-
-+ 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();
-***************
-*** 462,467 ****
---- 470,476 ----
- /* Set up optional for user-defined display filtering */
- pine_state->tools.display_filter = dfilter;
- pine_state->tools.display_filter_trigger = dfilter_trigger;
-+ pine_state->tools.exec_rule = exec_function_rule;
-
- #ifdef _WINDOWS
- if(ps_global->install_flag){
-***************
-*** 553,558 ****
---- 562,572 ----
- if(F_ON(F_MAILDROPS_PRESERVE_STATE, ps_global))
- mail_parameters(NULL, SET_SNARFPRESERVE, (void *) TRUE);
-
-+ #ifndef _WINDOWS
-+ mail_parameters(NULL,SET_COURIERSTYLE,
-+ (void *)(F_ON(F_COURIER_FOLDER_LIST, ps_global) ? 1 : 0));
-+ #endif
-+
- rvl = 0L;
- if(pine_state->VAR_NNTPRANGE){
- if(!SVAR_NNTPRANGE(pine_state, rvl, tmp_20k_buf, SIZEOF_20KBUF))
-***************
-*** 672,677 ****
---- 686,692 ----
-
-
- /*--- output side ---*/
-+ if (!ps_global->send_immediately){
- rv = config_screen(&(pine_state->ttyo));
- #ifndef _WINDOWS /* always succeeds under _WINDOWS */
- if(rv){
-***************
-*** 712,723 ****
- /* initialize titlebar in case we use it */
- set_titlebar("", NULL, NULL, NULL, NULL, 0, FolderName, 0, 0, NULL);
-
-- /*
-- * Prep storage object driver for PicoText
-- */
-- so_register_external_driver(pine_pico_get, pine_pico_give, pine_pico_writec, pine_pico_readc,
-- pine_pico_puts, pine_pico_seek, NULL, NULL);
--
- #ifdef DEBUG
- if(ps_global->debug_imap > 4 || debug > 9){
- q_status_message(SM_ORDER | SM_DING, 5, 9,
---- 727,732 ----
-***************
-*** 725,730 ****
---- 734,752 ----
- flush_status_messages(0);
- }
- #endif
-+ }
-+ else{
-+ fake_config_screen(&(pine_state->ttyo));
-+ init_folders(pine_state); /* digest folder spec's */
-+ }
-+
-+ /*
-+ * Prep storage object driver for PicoText
-+ */
-+ so_register_external_driver(pine_pico_get, pine_pico_give,
-+ (args.noutf8 == 0 ? pine_pico_writec : pine_pico_writec_noucs),
-+ (args.noutf8 == 0 ? pine_pico_readc : pine_pico_readc_noucs),
-+ (args.noutf8 == 0 ? pine_pico_puts : pine_pico_puts_noucs), pine_pico_seek, NULL, NULL);
-
- if(args.action == aaPrcCopy || args.action == aaAbookCopy){
- int exit_val = -1;
-***************
-*** 900,905 ****
---- 922,933 ----
- 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;
-***************
-*** 938,944 ****
- memset(&fcc, 0, sizeof(fcc));
-
- if(good_addr){
-! compose_mail(addr, fcc.tptr, NULL,
- args.data.mail.attachlist, stdin_getc);
- }
- else{
---- 966,972 ----
- memset(&fcc, 0, sizeof(fcc));
-
- if(good_addr){
-! compose_mail(addr, fcc.tptr, role,
- args.data.mail.attachlist, stdin_getc);
- }
- else{
-***************
-*** 972,977 ****
---- 1000,1006 ----
-
- pine_state->mail_stream = NULL;
- pine_state->mangled_screen = 1;
-+ pine_state->subject = NULL;
-
- if(args.action == aaURL){
- url_tool_t f;
-***************
-*** 1087,1092 ****
---- 1116,1122 ----
- }
- }
-
-+ if (!pine_state->send_immediately)
- fflush(stdout);
-
- #if !defined(_WINDOWS) && !defined(LEAVEOUTFIFO)
-***************
-*** 2975,2984 ****
- 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;
- }
- }
---- 3005,3019 ----
- 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;
- }
- }
-***************
-*** 3134,3139 ****
---- 3169,3177 ----
- extern KBESC_T *kbesc;
-
- dprint((2, "goodnight_gracey:\n"));
-+ strncpy(pine_state->cur_folder, pine_state->inbox_name,
-+ sizeof(pine_state->cur_folder));
-+ pine_state->cur_folder[sizeof(pine_state->cur_folder) - 1] = '\0';
-
- /* We want to do this here before we close up the streams */
- trim_remote_adrbks();
-diff -rc alpine-2.00/alpine/arg.c alpine-2.00.I.USE/alpine/arg.c
-*** alpine-2.00/alpine/arg.c 2008-01-04 14:49:15.000000000 -0800
---- alpine-2.00.I.USE/alpine/arg.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 59,64 ****
---- 59,65 ----
- static char args_err_non_abs_passfile[] = N_("argument to \"-passfile\" should be fully-qualified");
- #endif
- static char args_err_missing_sort[] = N_("missing argument for option \"-sort\"");
-+ static char args_err_missing_thread_sort[] = N_("missing argument for option \"-threadsort\"");
- static char args_err_missing_flag_arg[] = N_("missing argument for flag \"%c\"");
- static char args_err_missing_flag_num[] = N_("Non numeric argument for flag \"%c\"");
- static char args_err_missing_debug_num[] = N_("Non numeric argument for \"%s\"");
-***************
-*** 102,112 ****
---- 103,115 ----
- N_(" -z \t\tSuspend - allow use of ^Z suspension"),
- N_(" -r \t\tRestricted - can only send mail to oneself"),
- N_(" -sort <sort>\tSort - Specify sort order of folder:"),
-+ N_(" -threadsort <sort>\tSort - Specify sort order of thread index screen:"),
- N_("\t\t\tarrival, subject, threaded, orderedsubject, date,"),
- N_("\t\t\tfrom, size, score, to, cc, /reverse"),
- N_(" -i\t\tIndex - Go directly to index, bypassing main menu"),
- N_(" -I <keystroke_list> Initial keystrokes to be executed"),
- N_(" -n <number>\tEntry in index to begin on"),
-+ N_(" -noutf8\t Warns Alpine that piped input is not encoded in utf-8"),
- N_(" -o \t\tReadOnly - Open first folder read-only"),
- N_(" -conf\t\tConfiguration - Print out fresh global configuration. The"),
- N_("\t\tvalues of your global configuration affect all Alpine users"),
-***************
-*** 191,196 ****
---- 194,200 ----
- char *cmd_list = NULL;
- char *debug_str = NULL;
- char *sort = NULL;
-+ char *threadsort = NULL;
- char *pinerc_file = NULL;
- char *lc = NULL;
- int do_help = 0;
-***************
-*** 362,367 ****
---- 366,382 ----
-
- 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;
-***************
-*** 468,473 ****
---- 483,492 ----
-
- goto Loop;
- }
-+ else if(strcmp(*av, "noutf8") == 0){
-+ args->noutf8++;
-+ goto Loop;
-+ }
- else if(strcmp(*av, "bail") == 0){
- pine_state->exit_if_no_pinerc = 1;
- goto Loop;
-***************
-*** 476,481 ****
---- 495,506 ----
- 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){
- pine_state->install_flag = 1;
-***************
-*** 826,839 ****
- exit(-1);
-
- if(do_version){
-! extern char datestamp[], hoststamp[];
- char rev[128];
-
-! snprintf(tmp_20k_buf, SIZEOF_20KBUF, "Alpine %s (%s %s) built %s on %s",
- ALPINE_VERSION,
- SYSTYPE ? SYSTYPE : "?",
- get_alpine_revision_string(rev, sizeof(rev)),
-! datestamp, hoststamp);
- tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
- display_args_err(tmp_20k_buf, NULL, 0);
- exit(0);
---- 851,864 ----
- exit(-1);
-
- if(do_version){
-! extern char datestamp[], hoststamp[], plevstamp[];
- char rev[128];
-
-! snprintf(tmp_20k_buf, SIZEOF_20KBUF, "Alpine %s (%s %s) built %s on %s, using patchlevel %s.",
- ALPINE_VERSION,
- SYSTYPE ? SYSTYPE : "?",
- get_alpine_revision_string(rev, sizeof(rev)),
-! datestamp, hoststamp, plevstamp);
- tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
- display_args_err(tmp_20k_buf, NULL, 0);
- exit(0);
-diff -rc alpine-2.00/alpine/arg.h alpine-2.00.I.USE/alpine/arg.h
-*** alpine-2.00/alpine/arg.h 2006-09-22 13:06:05.000000000 -0700
---- alpine-2.00.I.USE/alpine/arg.h 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 27,32 ****
---- 27,33 ----
- typedef struct argdata {
- enum {aaFolder = 0, aaMore, aaURL, aaMail,
- aaPrcCopy, aaAbookCopy} action;
-+ int noutf8;
- union {
- char *folder;
- char *file;
-diff -rc alpine-2.00/alpine/busy.c alpine-2.00.I.USE/alpine/busy.c
-*** alpine-2.00/alpine/busy.c 2007-10-15 14:02:56.000000000 -0700
---- alpine-2.00.I.USE/alpine/busy.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 194,200 ****
-
- add_review_message(buf, -1);
- }
-! else{
- q_status_message(SM_ORDER, 0, 1, progress);
-
- /*
---- 194,200 ----
-
- add_review_message(buf, -1);
- }
-! else if (!ps_global->send_immediately){
- q_status_message(SM_ORDER, 0, 1, progress);
-
- /*
-***************
-*** 206,213 ****
- */
- display_message('x');
- }
-!
-! fflush(stdout);
- }
-
- /*
---- 206,213 ----
- */
- display_message('x');
- }
-! if (!ps_global->send_immediately)
-! fflush(stdout);
- }
-
- /*
-***************
-*** 255,261 ****
- (*ap)->cf = done_busy_cue;
- ap = &(*ap)->next;
-
-! start_after(a); /* launch cue handler */
-
- #ifdef _WINDOWS
- mswin_setcursor(MSWIN_CURSOR_BUSY);
---- 255,262 ----
- (*ap)->cf = done_busy_cue;
- ap = &(*ap)->next;
-
-! if(!ps_global->send_immediately)
-! start_after(a); /* launch cue handler */
-
- #ifdef _WINDOWS
- mswin_setcursor(MSWIN_CURSOR_BUSY);
-***************
-*** 404,409 ****
---- 405,415 ----
- {
- int space_left, slots_used;
-
-+ if (ps_global->send_immediately){
-+ mark_status_dirty();
-+ return;
-+ }
-+
- if(final_message && final_message_pri >= 0){
- char progress[MAX_SCREEN_COLS+1];
-
-diff -rc alpine-2.00/alpine/colorconf.c alpine-2.00.I.USE/alpine/colorconf.c
-*** alpine-2.00/alpine/colorconf.c 2008-02-08 10:39:55.000000000 -0800
---- alpine-2.00.I.USE/alpine/colorconf.c 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 28,33 ****
---- 28,34 ----
- #include "../pith/color.h"
- #include "../pith/icache.h"
- #include "../pith/mailcmd.h"
-+ #include "../pith/mailindx.h"
- #include "../pith/list.h"
-
-
-***************
-*** 39,45 ****
- SAVED_CONFIG_S *save_color_config_vars(struct pine *);
- void free_saved_color_config(struct pine *, SAVED_CONFIG_S **);
- void color_config_init_display(struct pine *, CONF_S **, CONF_S **);
-! void add_header_color_line(struct pine *, CONF_S **, char *, int);
- int is_rgb_color(char *);
- char *new_color_line(char *, int, int, int);
- int color_text_tool(struct pine *, int, CONF_S **, unsigned);
---- 40,46 ----
- SAVED_CONFIG_S *save_color_config_vars(struct pine *);
- void free_saved_color_config(struct pine *, SAVED_CONFIG_S **);
- void color_config_init_display(struct pine *, CONF_S **, CONF_S **);
-! void add_header_color_line(struct pine *, CONF_S **, char *, int, int);
- int is_rgb_color(char *);
- char *new_color_line(char *, int, int, int);
- int color_text_tool(struct pine *, int, CONF_S **, unsigned);
-***************
-*** 141,147 ****
- if((v && v->name &&
- srchstr(v->name, "-foreground-color") &&
- pvalfg && pvalfg[0] && pvalbg && pvalbg[0]) ||
-! (v == &ps->vars[V_VIEW_HDR_COLORS] || v == &ps->vars[V_KW_COLORS]))
- ret = SAMP1;
-
- return(ret);
---- 142,149 ----
- if((v && v->name &&
- srchstr(v->name, "-foreground-color") &&
- pvalfg && pvalfg[0] && pvalbg && pvalbg[0]) ||
-! (v == &ps->vars[V_INDEX_TOKEN_COLORS] ||
-! v == &ps->vars[V_VIEW_HDR_COLORS] || v == &ps->vars[V_KW_COLORS]))
- ret = SAMP1;
-
- return(ret);
-***************
-*** 486,491 ****
---- 488,513 ----
- }
-
- /*
-+ * custom index tokens colors
-+ */
-+ vtmp = &ps->vars[V_INDEX_TOKEN_COLORS];
-+ lval = LVAL(vtmp, ew);
-+
-+ if(lval && lval[0] && lval[0][0]){
-+ for(i = 0; lval && lval[i]; i++)
-+ add_header_color_line(ps, ctmp, lval[i], i, V_INDEX_TOKEN_COLORS);
-+ }
-+ else{
-+ new_confline(ctmp); /* Blank line */
-+ (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
-+ new_confline(ctmp);
-+ (*ctmp)->help = NO_HELP;
-+ (*ctmp)->flags |= CF_NOSELECT;
-+ (*ctmp)->value = cpystr(_(ADDINDEXTOKEN_COMMENT));
-+ (*ctmp)->valoffset = COLOR_INDENT;
-+ }
-+
-+ /*
- * custom header colors
- */
- new_confline(ctmp); /* Blank line */
-***************
-*** 497,503 ****
- new_confline(ctmp);
- (*ctmp)->help = NO_HELP;
- (*ctmp)->flags |= CF_NOSELECT;
-! (*ctmp)->value = cpystr(_("HEADER COLORS"));
- new_confline(ctmp);
- (*ctmp)->help = NO_HELP;
- (*ctmp)->flags |= CF_NOSELECT;
---- 519,525 ----
- new_confline(ctmp);
- (*ctmp)->help = NO_HELP;
- (*ctmp)->flags |= CF_NOSELECT;
-! (*ctmp)->value = cpystr(_(HDR_COLORS));
- new_confline(ctmp);
- (*ctmp)->help = NO_HELP;
- (*ctmp)->flags |= CF_NOSELECT;
-***************
-*** 526,532 ****
-
- if(lval && lval[0] && lval[0][0]){
- for(i = 0; lval && lval[i]; i++)
-! add_header_color_line(ps, ctmp, lval[i], i);
- }
- else{
- new_confline(ctmp); /* Blank line */
---- 548,554 ----
-
- if(lval && lval[0] && lval[0][0]){
- for(i = 0; lval && lval[i]; i++)
-! add_header_color_line(ps, ctmp, lval[i], i, V_VIEW_HDR_COLORS);
- }
- else{
- new_confline(ctmp); /* Blank line */
-***************
-*** 696,701 ****
---- 718,724 ----
- char **lval, *ret = "";
-
- if(var == &ps_global->vars[V_VIEW_HDR_COLORS]
-+ || var == &ps_global->vars[V_INDEX_TOKEN_COLORS]
- || var == &ps_global->vars[V_KW_COLORS]){
- norm = (LVAL(var, Main) != NULL);
- exc = (LVAL(var, ps_global->ew_for_except_vars) != NULL);
-***************
-*** 722,736 ****
-
-
- void
-! add_header_color_line(struct pine *ps, CONF_S **ctmp, char *val, int which)
- {
- struct variable *vtmp;
- SPEC_COLOR_S *hc;
- char tmp[100+1];
- int l;
-
-! vtmp = &ps->vars[V_VIEW_HDR_COLORS];
-! l = strlen(HEADER_WORD);
-
- /* Blank line */
- new_confline(ctmp);
---- 745,765 ----
-
-
- void
-! add_header_color_line(struct pine *ps, CONF_S **ctmp, char *val, int which, int varnum)
- {
- struct variable *vtmp;
- SPEC_COLOR_S *hc;
- char tmp[100+1];
- int l;
-
-! hc = spec_color_from_var(val, 0);
-! if(varnum == V_INDEX_TOKEN_COLORS){
-! if(hc == NULL || hc->spec == NULL
-! || itoktype(hc->spec, FOR_INDEX) == NULL)
-! return;
-! }
-! vtmp = &ps->vars[varnum];
-! l = strlen(varnum == V_VIEW_HDR_COLORS ? HEADER_WORD : TOKEN_WORD);
-
- /* Blank line */
- new_confline(ctmp);
-***************
-*** 748,754 ****
- /* which is an index into the variable list */
- (*ctmp)->varmem = CFC_SET_COLOR(which, 0);
-
-- hc = spec_color_from_var(val, 0);
- if(hc && hc->inherit)
- (*ctmp)->flags = (CF_NOSELECT | CF_INHERIT);
- else{
---- 777,782 ----
-***************
-*** 759,765 ****
- * with all this. It probably doesn't happen in real life.
- */
- utf8_snprintf(tmp, sizeof(tmp), "%s%c%.*w Color%*w %s%s",
-! HEADER_WORD,
- (hc && hc->spec) ? (islower((unsigned char)hc->spec[0])
- ? toupper((unsigned char)hc->spec[0])
- : hc->spec[0]) : '?',
---- 787,793 ----
- * with all this. It probably doesn't happen in real life.
- */
- utf8_snprintf(tmp, sizeof(tmp), "%s%c%.*w Color%*w %s%s",
-! (varnum == V_VIEW_HDR_COLORS ? HEADER_WORD : TOKEN_WORD),
- (hc && hc->spec) ? (islower((unsigned char)hc->spec[0])
- ? toupper((unsigned char)hc->spec[0])
- : hc->spec[0]) : '?',
-***************
-*** 1139,1144 ****
---- 1167,1173 ----
- return(var && var->name &&
- (srchstr(var->name, "-foreground-color") ||
- srchstr(var->name, "-background-color") ||
-+ var == &ps->vars[V_INDEX_TOKEN_COLORS] ||
- var == &ps->vars[V_VIEW_HDR_COLORS] ||
- var == &ps->vars[V_KW_COLORS]));
- }
-***************
-*** 1395,1400 ****
---- 1424,1430 ----
- if(hcolors)
- free_spec_colors(&hcolors);
-
-+ fix_side_effects(ps, (*cl)->var, 0);
- set_current_color_vals(ps);
- ClearScreen();
- rv = ps->mangled_screen = 1;
-***************
-*** 1803,1808 ****
---- 1833,1839 ----
- /* get rid of all user set colors */
- for(v = ps->vars; v->name; v++){
- if(!color_holding_var(ps, v)
-+ || v == &ps->vars[V_INDEX_TOKEN_COLORS]
- || v == &ps->vars[V_VIEW_HDR_COLORS]
- || v == &ps->vars[V_KW_COLORS])
- continue;
-***************
-*** 1856,1861 ****
---- 1887,1930 ----
- free_spec_colors(&hcolors);
- }
-
-+ /* same for index token colors */
-+ alval = ALVAL(&ps->vars[V_INDEX_TOKEN_COLORS], ew);
-+ if(alval && *alval){
-+ SPEC_COLOR_S *global_hcolors = NULL, *hcg;
-+
-+ v = &ps->vars[V_INDEX_TOKEN_COLORS];
-+ if(v->global_val.l && v->global_val.l[0])
-+ global_hcolors = spec_colors_from_varlist(v->global_val.l, 0);
-+
-+ hcolors = spec_colors_from_varlist(*alval, 0);
-+ for(hc = hcolors; hc; hc = hc->next){
-+ if(hc->fg)
-+ fs_give((void **)&hc->fg);
-+ if(hc->bg)
-+ fs_give((void **)&hc->bg);
-+
-+ for(hcg = global_hcolors; hcg; hcg = hcg->next){
-+ if(hc->spec && hcg->spec && !strucmp(hc->spec, hcg->spec)){
-+ hc->fg = hcg->fg;
-+ hcg->fg = NULL;
-+ hc->bg = hcg->bg;
-+ hcg->bg = NULL;
-+ if(hc->val && !hcg->val)
-+ fs_give((void **) &hc->val);
-+ }
-+ }
-+
-+ if(global_hcolors)
-+ free_spec_colors(&global_hcolors);
-+ }
-+
-+ free_list_array(alval);
-+ *alval = varlist_from_spec_colors(hcolors);
-+
-+ if(hcolors)
-+ free_spec_colors(&hcolors);
-+ }
-+
- /*
- * Same for keyword colors.
- */
-***************
-*** 1898,1912 ****
- rv = 1;
- break;
-
- case MC_ADD : /* add custom header color */
- /* get header field name */
- help = NO_HELP;
- while(1){
- i = optionally_enter(sval, -FOOTER_ROWS(ps), 0, sizeof(sval),
-! _("Enter the name of the header field to be added: "),
- NULL, help, NULL);
-! if(i == 0)
- break;
- else if(i == 1){
- cmd_cancelled("Add");
- cancel = 1;
---- 1967,1989 ----
- rv = 1;
- break;
-
-+ case MC_ADDHEADER: /* add custom index token color */
- case MC_ADD : /* add custom header color */
- /* get header field name */
- help = NO_HELP;
- while(1){
- i = optionally_enter(sval, -FOOTER_ROWS(ps), 0, sizeof(sval),
-! (cmd == MC_ADD ? _("Enter the name of the header field to be added: ")
-! : _("Enter the name of the index token to be added: ")),
- NULL, help, NULL);
-! if(i == 0){
-! if(cmd == MC_ADDHEADER && itoktype(sval, FOR_INDEX) == NULL){
-! q_status_message1(SM_ORDER, 1, 3,
-! _("token \"%s\" not recognized"), sval);
-! continue;
-! }
- break;
-+ }
- else if(i == 1){
- cmd_cancelled("Add");
- cancel = 1;
-***************
-*** 1937,1943 ****
- confline = var_from_spec_color(new_hcolor);
-
- /* add it to end of list */
-! alval = ALVAL(&ps->vars[V_VIEW_HDR_COLORS], ew);
- if(alval){
- /* get rid of possible empty value first */
- if((t = *alval) && t[0] && !t[0][0] && !(t+1)[0])
---- 2014,2020 ----
- confline = var_from_spec_color(new_hcolor);
-
- /* add it to end of list */
-! alval = ALVAL(&ps->vars[(cmd == MC_ADD ? V_VIEW_HDR_COLORS : V_INDEX_TOKEN_COLORS)], ew);
- if(alval){
- /* get rid of possible empty value first */
- if((t = *alval) && t[0] && !t[0][0] && !(t+1)[0])
-***************
-*** 1962,1968 ****
- ;
-
- /* back up to the KEYWORD COLORS title line */
-! for(; ctmp && (!ctmp->value || strcmp(ctmp->value, KW_COLORS_HDR))
- && ctmp->prev;
- ctmp = prev_confline(ctmp))
- ;
---- 2039,2045 ----
- ;
-
- /* back up to the KEYWORD COLORS title line */
-! for(; ctmp && (!ctmp->value || strcmp(ctmp->value, (cmd == MC_ADD ? KW_COLORS_HDR : HDR_COLORS)))
- && ctmp->prev;
- ctmp = prev_confline(ctmp))
- ;
-***************
-*** 2000,2006 ****
- free_conflines(&beg);
- }
-
-! add_header_color_line(ps, cl, confline, i);
-
- /* be sure current is on selectable line */
- for(; *cl && ((*cl)->flags & CF_NOSELECT); *cl = next_confline(*cl))
---- 2077,2084 ----
- free_conflines(&beg);
- }
-
-! add_header_color_line(ps, cl, confline, i, cmd == MC_ADD
-! ? V_VIEW_HDR_COLORS : V_INDEX_TOKEN_COLORS);
-
- /* be sure current is on selectable line */
- for(; *cl && ((*cl)->flags & CF_NOSELECT); *cl = next_confline(*cl))
-***************
-*** 2012,2024 ****
- break;
-
- case MC_DELETE : /* delete custom header color */
-! if((*cl)->var != &ps->vars[V_VIEW_HDR_COLORS]){
- q_status_message(SM_ORDER, 0, 2,
- _("Can't delete this color setting"));
- break;
- }
-
-! if(want_to(_("Really delete header color from config"),
- 'y', 'n', NO_HELP, WT_NORM) != 'y'){
- cmd_cancelled("Delete");
- return(rv);
---- 2090,2105 ----
- break;
-
- case MC_DELETE : /* delete custom header color */
-! if((*cl)->var != &ps->vars[V_VIEW_HDR_COLORS]
-! && (*cl)->var != &ps->vars[V_INDEX_TOKEN_COLORS]){
- q_status_message(SM_ORDER, 0, 2,
- _("Can't delete this color setting"));
- break;
- }
-
-! if(want_to(((*cl)->var == &ps->vars[V_VIEW_HDR_COLORS]
-! ? _("Really delete header color from config")
-! : _("Really delete index token color from config")),
- 'y', 'n', NO_HELP, WT_NORM) != 'y'){
- cmd_cancelled("Delete");
- return(rv);
-***************
-*** 2054,2072 ****
- another = 0;
- /* reset current line */
- if(end && end->next && end->next->next &&
-! end->next->next->var == &ps->vars[V_VIEW_HDR_COLORS]){
- *cl = end->next->next; /* next Header Color */
- another++;
- }
- else if(beg && beg->prev &&
-! beg->prev->var == &ps->vars[V_VIEW_HDR_COLORS]){
- *cl = beg->prev; /* prev Header Color */
- another++;
- }
-
- /* adjust SPEC_COLOR_S index (varmem) values */
- for(ctmp = end; ctmp; ctmp = next_confline(ctmp))
-! if(ctmp->var == &ps->vars[V_VIEW_HDR_COLORS])
- ctmp->varmem = CFC_ICUST_DEC(ctmp);
-
- /*
---- 2135,2156 ----
- another = 0;
- /* reset current line */
- if(end && end->next && end->next->next &&
-! end->next->next->var == &ps->vars[(*cl)->var == &ps->vars[V_VIEW_HDR_COLORS]
-! ? V_VIEW_HDR_COLORS : V_INDEX_TOKEN_COLORS]){
- *cl = end->next->next; /* next Header Color */
- another++;
- }
- else if(beg && beg->prev &&
-! beg->prev->var == &ps->vars[(*cl)->var == &ps->vars[V_VIEW_HDR_COLORS]
-! ? V_VIEW_HDR_COLORS : V_INDEX_TOKEN_COLORS]){
- *cl = beg->prev; /* prev Header Color */
- another++;
- }
-
- /* adjust SPEC_COLOR_S index (varmem) values */
- for(ctmp = end; ctmp; ctmp = next_confline(ctmp))
-! if(ctmp->var == &ps->vars[(*cl)->var == &ps->vars[V_VIEW_HDR_COLORS]
-! ? V_VIEW_HDR_COLORS : V_INDEX_TOKEN_COLORS])
- ctmp->varmem = CFC_ICUST_DEC(ctmp);
-
- /*
-***************
-*** 2098,2104 ****
-
- end->flags = CF_NOSELECT;
- end->help = NO_HELP;
-! end->value = cpystr(_(ADDHEADER_COMMENT));
- end->valoffset = COLOR_INDENT;
- end->varnamep = NULL;
- end->varmem = 0;
---- 2182,2189 ----
-
- end->flags = CF_NOSELECT;
- end->help = NO_HELP;
-! end->value = cpystr((*cl)->var == &ps->vars[V_VIEW_HDR_COLORS]
-! ? _(ADDHEADER_COMMENT) : _(ADDINDEXTOKEN_COMMENT));
- end->valoffset = COLOR_INDENT;
- end->varnamep = NULL;
- end->varmem = 0;
-***************
-*** 2556,2562 ****
- OPT_SCREEN_S screen, *saved_screen;
- CONF_S *ctmp = NULL, *first_line = NULL, *ctmpb;
- int rv, is_index = 0, is_hdrcolor = 0, indent = 12;
-! int is_general = 0, is_keywordcol = 0;
- char tmp[1200+1], name[1200], *p;
- struct variable *vtmp, v;
- int i, def;
---- 2641,2647 ----
- OPT_SCREEN_S screen, *saved_screen;
- CONF_S *ctmp = NULL, *first_line = NULL, *ctmpb;
- int rv, is_index = 0, is_hdrcolor = 0, indent = 12;
-! int is_general = 0, is_keywordcol = 0, is_idxtokcol = 0;
- char tmp[1200+1], name[1200], *p;
- struct variable *vtmp, v;
- int i, def;
-***************
-*** 2567,2572 ****
---- 2652,2659 ----
- vtmp = (*cl)->var;
- if(vtmp == &ps->vars[V_VIEW_HDR_COLORS])
- is_hdrcolor++;
-+ else if(vtmp == &ps->vars[V_INDEX_TOKEN_COLORS])
-+ is_idxtokcol++;
- else if(vtmp == &ps->vars[V_KW_COLORS])
- is_keywordcol++;
- else if(color_holding_var(ps, vtmp)){
-***************
-*** 2618,2623 ****
---- 2705,2728 ----
- name[i] = toupper((unsigned char) name[i]);
- }
- }
-+ else if(is_idxtokcol){
-+ char **lval;
-+
-+ lval = LVAL(vtmp, ew);
-+ hcolors = spec_colors_from_varlist(lval, 0);
-+
-+ for(hc = hcolors, i = 0; hc; hc = hc->next, i++)
-+ if(CFC_ICUST(*cl) == i)
-+ break;
-+
-+ if(hc){
-+ snprintf(name, sizeof(name), "%s%s", TOKEN_WORD, hc->spec);
-+ name[sizeof(name)-1] = '\0';
-+ i = sizeof(TOKEN_WORD) - 1;
-+ if(islower((unsigned char) name[i]))
-+ name[i] = toupper((unsigned char) name[i]);
-+ }
-+ }
- else if(is_keywordcol){
- char **lval;
-
-***************
-*** 2663,2669 ****
- ctmp->flags |= (CF_STARTITEM | CF_NOSELECT);
- ctmp->keymenu = &color_changing_keymenu;
-
-! if(is_hdrcolor){
- char **apval;
-
- def = !(hc && hc->fg && hc->fg[0] && hc->bg && hc->bg[0]);
---- 2768,2774 ----
- ctmp->flags |= (CF_STARTITEM | CF_NOSELECT);
- ctmp->keymenu = &color_changing_keymenu;
-
-! if(is_hdrcolor || is_idxtokcol){
- char **apval;
-
- def = !(hc && hc->fg && hc->fg[0] && hc->bg && hc->bg[0]);
-diff -rc alpine-2.00/alpine/colorconf.h alpine-2.00.I.USE/alpine/colorconf.h
-*** alpine-2.00/alpine/colorconf.h 2007-08-16 15:25:10.000000000 -0700
---- alpine-2.00.I.USE/alpine/colorconf.h 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 23,30 ****
---- 23,33 ----
-
-
- #define HEADER_WORD "Header "
-+ #define TOKEN_WORD "Index Token "
- #define KW_COLORS_HDR "KEYWORD COLORS"
-+ #define HDR_COLORS "HEADER COLORS"
- #define ADDHEADER_COMMENT N_("[ Use the AddHeader command to add colored headers in MESSAGE TEXT screen ]")
-+ #define ADDINDEXTOKEN_COMMENT N_("[ Use the IndxHdr command to add colored tokens in MESSAGE INDEX screen ]")
- #define EQ_COL 37
-
- #define SPACE_BETWEEN_DOUBLEVARS 3
-diff -rc alpine-2.00/alpine/confscroll.c alpine-2.00.I.USE/alpine/confscroll.c
-*** alpine-2.00/alpine/confscroll.c 2008-08-21 15:14:45.000000000 -0700
---- alpine-2.00.I.USE/alpine/confscroll.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 50,55 ****
---- 50,56 ----
- #include "../pith/tempfile.h"
- #include "../pith/pattern.h"
- #include "../pith/charconv/utf8.h"
-+ #include "../pith/rules.h"
-
-
- #define CONFIG_SCREEN_HELP_TITLE _("HELP FOR SETUP CONFIGURATION")
-***************
-*** 138,144 ****
- char *radio_pretty_value(struct pine *, CONF_S *);
- char *sigfile_pretty_value(struct pine *, CONF_S *);
- char *color_pretty_value(struct pine *, CONF_S *);
-! char *sort_pretty_value(struct pine *, CONF_S *);
- int longest_feature_name(void);
- COLOR_PAIR *sample_color(struct pine *, struct variable *);
- COLOR_PAIR *sampleexc_color(struct pine *, struct variable *);
---- 139,145 ----
- char *radio_pretty_value(struct pine *, CONF_S *);
- char *sigfile_pretty_value(struct pine *, CONF_S *);
- char *color_pretty_value(struct pine *, CONF_S *);
-! char *sort_pretty_value(struct pine *, CONF_S *, int);
- int longest_feature_name(void);
- COLOR_PAIR *sample_color(struct pine *, struct variable *);
- COLOR_PAIR *sampleexc_color(struct pine *, struct variable *);
-***************
-*** 286,292 ****
- CONF_S *ctmp;
-
- if(!(cl && *cl &&
-! ((*cl)->var == &ps->vars[V_SORT_KEY] ||
- standard_radio_var(ps, (*cl)->var) ||
- (*cl)->var == startup_ptr)))
- return;
---- 287,294 ----
- 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;
-***************
-*** 462,468 ****
- char tmp[MAXPATH+1];
- char *utf8str;
- UCS ch = 'x';
-! int cmd, i, j, done = 0, changes = 0;
- int retval = 0;
- int km_popped = 0, stay_in_col = 0;
- struct key_menu *km = NULL;
---- 464,470 ----
- char tmp[MAXPATH+1];
- char *utf8str;
- UCS ch = 'x';
-! int cmd, i, j, k = 1, done = 0, changes = 0;
- int retval = 0;
- int km_popped = 0, stay_in_col = 0;
- struct key_menu *km = NULL;
-***************
-*** 491,499 ****
---- 493,504 ----
-
- opt_screen = screen;
- ps->mangled_screen = 1;
-+ ps->resize_for_pico= 0;
- ps->redrawer = option_screen_redrawer;
-
- while(!done){
-+ if(ps->resize_for_pico)
-+ ps->mangled_screen = ps->resize_for_pico;
- ps->user_says_cancel = 0;
- if(km_popped){
- km_popped--;
-***************
-*** 507,516 ****
- ps->mangled_header = 1;
- ps->mangled_footer = 1;
- ps->mangled_body = 1;
-! ps->mangled_screen = 0;
- }
-
- /*----------- Check for new mail -----------*/
- if(new_mail(0, NM_TIMING(ch), NM_STATUS_MSG | NM_DEFER_SORT) >= 0)
- ps->mangled_header = 1;
-
---- 512,522 ----
- ps->mangled_header = 1;
- ps->mangled_footer = 1;
- ps->mangled_body = 1;
-! ps->mangled_screen = ps->resize_for_pico = 0;
- }
-
- /*----------- 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;
-
-***************
-*** 540,545 ****
---- 546,552 ----
- mark_status_unknown();
- }
-
-+ } /* send_immediately */
- if(ps->mangled_footer || km != screen->current->keymenu){
- bitmap_t bitmap;
-
-***************
-*** 611,616 ****
---- 618,624 ----
- }
- }
-
-+ 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 */
-***************
-*** 629,634 ****
---- 637,650 ----
- #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);
-
-***************
-*** 1382,1388 ****
- break;
- }
- }
-!
- screen->current = first_confline(screen->current);
- free_conflines(&screen->current);
- return(retval);
---- 1398,1404 ----
- break;
- }
- }
-! end:
- screen->current = first_confline(screen->current);
- free_conflines(&screen->current);
- return(retval);
-***************
-*** 2426,2431 ****
---- 2442,2450 ----
- * Now go and set the current_val based on user_val changes
- * above. Turn off command line settings...
- */
-+ set_current_val((*cl)->var,
-+ (strcmp((*cl)->var->name,"key-definition-rules") ? TRUE : FALSE),
-+ FALSE);
- set_current_val((*cl)->var, TRUE, FALSE);
- fix_side_effects(ps, (*cl)->var, 0);
-
-***************
-*** 2922,2928 ****
- }
-
- 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;
- }
---- 2941,2947 ----
- }
-
- 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;
- }
-***************
-*** 2931,2936 ****
---- 2950,2986 ----
- 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.");
-***************
-*** 3369,3375 ****
- ptr = sample;
-
- /* then the color sample */
-! if(ctmp->var == &ps->vars[V_VIEW_HDR_COLORS]){
- SPEC_COLOR_S *hc, *hcolors;
-
- lastc = newc = NULL;
---- 3419,3426 ----
- ptr = sample;
-
- /* then the color sample */
-! if(ctmp->var == &ps->vars[V_VIEW_HDR_COLORS]
-! || ctmp->var == &ps->vars[V_INDEX_TOKEN_COLORS]){
- SPEC_COLOR_S *hc, *hcolors;
-
- lastc = newc = NULL;
-***************
-*** 3787,3793 ****
- 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])
---- 3838,3846 ----
- 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])
-***************
-*** 4318,4331 ****
-
-
- char *
-! sort_pretty_value(struct pine *ps, CONF_S *cl)
- {
-! return(generalized_sort_pretty_value(ps, cl, 1));
- }
-
-
- char *
-! generalized_sort_pretty_value(struct pine *ps, CONF_S *cl, int default_ok)
- {
- char tmp[6*MAXPATH];
- char *pvalnorm, *pvalexc, *pval;
---- 4371,4384 ----
-
-
- char *
-! sort_pretty_value(struct pine *ps, CONF_S *cl, int thread)
- {
-! return(generalized_sort_pretty_value(ps, cl, 1, thread));
- }
-
-
- char *
-! generalized_sort_pretty_value(struct pine *ps, CONF_S *cl, int default_ok, int thread)
- {
- char tmp[6*MAXPATH];
- char *pvalnorm, *pvalexc, *pval;
-***************
-*** 4375,4381 ****
- }
- 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);
-
- utf8_snprintf(tmp, sizeof(tmp), "(%c) %s%-*w%*s%s",
---- 4428,4434 ----
- }
- 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);
-
- utf8_snprintf(tmp, sizeof(tmp), "(%c) %s%-*w%*s%s",
-***************
-*** 4386,4394 ****
- 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);
- utf8_snprintf(tmp, sizeof(tmp), "(%c) %s%-*w%*s%s",
---- 4439,4447 ----
- 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);
- utf8_snprintf(tmp, sizeof(tmp), "(%c) %s%-*w%*s%s",
-***************
-*** 4406,4412 ****
- }
- else{
- if(pvalexc){
-! decode_sort(pvalexc, &exc_sort, &exc_sort_rev);
- is_the_one = (exc_sort_rev == line_sort_rev &&
- exc_sort == line_sort);
- utf8_snprintf(tmp, sizeof(tmp), "( ) %s%-*w%*s%s",
---- 4459,4465 ----
- }
- 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);
- utf8_snprintf(tmp, sizeof(tmp), "( ) %s%-*w%*s%s",
-***************
-*** 4417,4423 ****
- }
- 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);
---- 4470,4476 ----
- }
- 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);
-***************
-*** 5154,5159 ****
---- 5207,5236 ----
- var == &ps->vars[V_ABOOK_FORMATS]){
- addrbook_reset();
- }
-+ else if(var == &ps->vars[V_INDEX_RULES]){
-+ if(ps_global->rule_list)
-+ free_parsed_rule_list(&ps_global->rule_list);
-+ create_rule_list(ps->vars);
-+ reset_index_format();
-+ clear_index_cache(ps->mail_stream, 0);
-+ }
-+ else if(var == &ps->vars[V_COMPOSE_RULES] ||
-+ var == &ps->vars[V_FORWARD_RULES] ||
-+ var == &ps->vars[V_KEY_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(ps->vars);
-+ }
- else if(var == &ps->vars[V_INDEX_FORMAT]){
- reset_index_format();
- clear_index_cache(ps->mail_stream, 0);
-***************
-*** 5176,5181 ****
---- 5253,5261 ----
-
- clear_index_cache(ps->mail_stream, 0);
- }
-+ else if(var == &ps->vars[V_SPECIAL_TEXT]){
-+ regex_pattern(ps->VAR_SPECIAL_TEXT);
-+ }
- else if(var == &ps->vars[V_INIT_CMD_LIST]){
- if(!revert)
- q_status_message(SM_ASYNC, 0, 3,
-***************
-*** 5489,5494 ****
---- 5569,5580 ----
- (void *)var->current_val.p);
- }
- #endif
-+ #ifndef _WINDOWS
-+ else if(var == &ps->vars[V_MAILDIR_LOCATION]){
-+ if(var->current_val.p && var->current_val.p[0])
-+ mail_parameters(NULL, SET_MDINBOXPATH, (void *)var->current_val.p);
-+ }
-+ #endif
- else if(revert && standard_radio_var(ps, var)){
-
- cur_rule_value(var, TRUE, FALSE);
-***************
-*** 5538,5546 ****
- 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]){
---- 5624,5638 ----
- 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]){
-***************
-*** 5607,5612 ****
---- 5699,5705 ----
- }
- }
- else if(var == &ps->vars[V_KW_COLORS] ||
-+ var == &ps->vars[V_INDEX_TOKEN_COLORS] ||
- var == &ps->vars[V_IND_PLUS_FORE_COLOR] ||
- var == &ps->vars[V_IND_IMP_FORE_COLOR] ||
- var == &ps->vars[V_IND_DEL_FORE_COLOR] ||
-diff -rc alpine-2.00/alpine/confscroll.h alpine-2.00.I.USE/alpine/confscroll.h
-*** alpine-2.00/alpine/confscroll.h 2007-11-09 13:13:47.000000000 -0800
---- alpine-2.00.I.USE/alpine/confscroll.h 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 94,100 ****
- int radiobutton_tool(struct pine *, int, CONF_S **, unsigned);
- int yesno_tool(struct pine *, int, CONF_S **, unsigned);
- int text_toolit(struct pine *, int, CONF_S **, unsigned, int);
-! char *generalized_sort_pretty_value(struct pine *, CONF_S *, int);
- int exclude_config_var(struct pine *, struct variable *, int);
- int config_exit_cmd(unsigned);
- int simple_exit_cmd(unsigned);
---- 94,100 ----
- int radiobutton_tool(struct pine *, int, CONF_S **, unsigned);
- int yesno_tool(struct pine *, int, CONF_S **, unsigned);
- int text_toolit(struct pine *, int, CONF_S **, unsigned, int);
-! char *generalized_sort_pretty_value(struct pine *, CONF_S *, int, int);
- int exclude_config_var(struct pine *, struct variable *, int);
- int config_exit_cmd(unsigned);
- int simple_exit_cmd(unsigned);
-diff -rc alpine-2.00/alpine/dispfilt.c alpine-2.00.I.USE/alpine/dispfilt.c
-*** alpine-2.00/alpine/dispfilt.c 2008-03-18 10:24:31.000000000 -0700
---- alpine-2.00.I.USE/alpine/dispfilt.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 56,68 ****
- dfilter(char *rawcmd, STORE_S *input_so, gf_io_t output_pc, FILTLIST_S *aux_filters)
- {
- char *status = NULL, *cmd, *resultf = NULL, *tmpfile = NULL;
-! int key = 0;
-
-! if((cmd = expand_filter_tokens(rawcmd,NULL,&tmpfile,&resultf,NULL,&key,NULL)) != NULL){
- suspend_busy_cue();
- #ifndef _WINDOWS
-! ps_global->mangled_screen = 1;
-! ClearScreen();
- fflush(stdout);
- #endif
-
---- 56,70 ----
- dfilter(char *rawcmd, STORE_S *input_so, gf_io_t output_pc, FILTLIST_S *aux_filters)
- {
- char *status = NULL, *cmd, *resultf = NULL, *tmpfile = NULL;
-! int key = 0, silent = 0;
-
-! if((cmd = expand_filter_tokens(rawcmd,NULL,&tmpfile,&resultf,NULL,&key,NULL, &silent)) != NULL){
- suspend_busy_cue();
- #ifndef _WINDOWS
-! if(!silent){
-! ps_global->mangled_screen = 1;
-! ClearScreen();
-! }
- fflush(stdout);
- #endif
-
-***************
-*** 99,105 ****
- /* prepare the terminal in case the filter uses it */
- if(status == NULL){
- if((filter_pipe = open_system_pipe(cmd, NULL, NULL,
-! PIPE_USER | PIPE_RESET,
- 0, pipe_callback, NULL)) != NULL){
- if(close_system_pipe(&filter_pipe, NULL, pipe_callback) == 0){
- /* pull result out of tmp file */
---- 101,108 ----
- /* prepare the terminal in case the filter uses it */
- if(status == NULL){
- if((filter_pipe = open_system_pipe(cmd, NULL, NULL,
-! PIPE_USER | (silent ? PIPE_SILENT :
-! (F_ON(F_DISABLE_TERM_RESET_DISP, ps_global) ? 0 : PIPE_RESET)),
- 0, pipe_callback, NULL)) != NULL){
- if(close_system_pipe(&filter_pipe, NULL, pipe_callback) == 0){
- /* pull result out of tmp file */
-***************
-*** 130,136 ****
- status = "Can't open display filter tmp file";
- }
- else if((status = gf_filter(cmd, key ? filter_session_key() : NULL,
-! input_so, output_pc, aux_filters,
- F_ON(F_DISABLE_TERM_RESET_DISP, ps_global),
- pipe_callback)) != NULL){
- unsigned long ch;
---- 133,139 ----
- status = "Can't open display filter tmp file";
- }
- else if((status = gf_filter(cmd, key ? filter_session_key() : NULL,
-! input_so, output_pc, aux_filters, silent,
- F_ON(F_DISABLE_TERM_RESET_DISP, ps_global),
- pipe_callback)) != NULL){
- unsigned long ch;
-***************
-*** 150,156 ****
-
- resume_busy_cue(0);
- #ifndef _WINDOWS
-! ClearScreen();
- #endif
- fs_give((void **)&cmd);
- }
---- 153,160 ----
-
- resume_busy_cue(0);
- #ifndef _WINDOWS
-! if(!silent)
-! ClearScreen();
- #endif
- fs_give((void **)&cmd);
- }
-***************
-*** 165,171 ****
- */
- char *
- expand_filter_tokens(char *filter, ENVELOPE *env, char **tmpf, char **resultf,
-! char **mtypef, int *key, int *hdrs)
- {
- char **array, **q;
- char *bp, *cmd = NULL, *p = NULL,
---- 169,175 ----
- */
- char *
- expand_filter_tokens(char *filter, ENVELOPE *env, char **tmpf, char **resultf,
-! char **mtypef, int *key, int *hdrs, int *silent)
- {
- char **array, **q;
- char *bp, *cmd = NULL, *p = NULL,
-***************
-*** 238,243 ****
---- 242,260 ----
- fs_give((void **)q);
- *q = rl ? rl : cpystr("");
- }
-+ else if(!strcmp(*q, "_ADDRESS_")){
-+ char *r = NULL;
-+
-+ if(env && env->from && env->from->mailbox && env->from->host){
-+ size_t l;
-+ l = strlen(env->from->mailbox) + strlen(env->from->host) + 1;
-+ r = (char *) fs_get((l+1) * sizeof(char));
-+ snprintf(r, l+1, "%s@%s", env->from->mailbox, env->from->host);
-+ }
-+
-+ fs_give((void **)q);
-+ *q = r ? r : cpystr("");
-+ }
- else if(!strcmp(*q, "_TMPFILE_")){
- if(!tfn){
- tfn = temp_nam(NULL, "sf"); /* send filter file */
-***************
-*** 312,317 ****
---- 329,339 ----
- if(hdrs)
- *hdrs = 1;
- }
-+ else if(!strcmp(*q, "_SILENT_")){
-+ (*q)[0] = '\0';
-+ if(silent)
-+ *silent = 1;
-+ }
- }
-
- /* count up required length */
-***************
-*** 451,453 ****
---- 473,535 ----
-
- return(passed);
- }
-+
-+ char *
-+ exec_function_rule(char *rawcmd, gf_io_t input_gc, gf_io_t output_pc)
-+ {
-+ char *status = NULL, *cmd, *tmpfile = NULL;
-+
-+ if((cmd = expand_filter_tokens(rawcmd,NULL,&tmpfile,NULL,NULL,NULL,NULL, NULL)) != NULL){
-+ suspend_busy_cue();
-+ ps_global->mangled_screen = 1;
-+ if(tmpfile){
-+ PIPE_S *filter_pipe;
-+ FILE *fp;
-+ gf_io_t gc, pc;
-+ STORE_S *tmpf_so;
-+
-+ /* write the tmp file */
-+ if((tmpf_so = so_get(FileStar, tmpfile, WRITE_ACCESS|OWNER_ONLY|WRITE_TO_LOCALE)) != NULL){
-+ /* copy input to tmp file */
-+ gf_set_so_writec(&pc, tmpf_so);
-+ gf_filter_init();
-+ status = gf_pipe(input_gc, pc);
-+ gf_clear_so_writec(tmpf_so);
-+ if(so_give(&tmpf_so) != 0 && status == NULL)
-+ status = error_description(errno);
-+
-+ /* prepare the terminal in case the filter uses it */
-+ if(status == NULL){
-+ if((filter_pipe = open_system_pipe(cmd, NULL, NULL,
-+ PIPE_USER|PIPE_PROT|PIPE_NOSHELL|PIPE_SILENT,
-+ 0, pipe_callback, NULL)) != NULL){
-+ if(close_system_pipe(&filter_pipe, NULL, pipe_callback) == 0){
-+ /* pull result out of tmp file */
-+ if((fp = our_fopen(tmpfile, "rb")) != NULL){
-+ gf_set_readc(&gc, fp, 0L, FileStar, READ_FROM_LOCALE);
-+ gf_filter_init();
-+ status = gf_pipe(gc, output_pc);
-+ fclose(fp);
-+ }
-+ else
-+ status = "Can't read result of EXEC command";
-+ }
-+ else
-+ status = "EXEC command command returned error.";
-+ }
-+ else
-+ status = "Can't open pipe for EXEC command";
-+ }
-+
-+ our_unlink(tmpfile);
-+ }
-+ else
-+ status = "Can't open EXEC command tmp file";
-+ }
-+
-+ resume_busy_cue(0);
-+ fs_give((void **)&cmd);
-+ }
-+
-+ return(status);
-+ }
-diff -rc alpine-2.00/alpine/dispfilt.h alpine-2.00.I.USE/alpine/dispfilt.h
-*** alpine-2.00/alpine/dispfilt.h 2006-09-26 12:30:49.000000000 -0700
---- alpine-2.00.I.USE/alpine/dispfilt.h 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 21,30 ****
- /* exported protoypes */
- char *dfilter(char *, STORE_S *, gf_io_t, FILTLIST_S *);
- char *dfilter_trigger(BODY *, char *, size_t);
-! char *expand_filter_tokens(char *, ENVELOPE *, char **, char **, char **, int *, int *);
- char *filter_session_key(void);
- char *filter_data_file(int);
-!
-
-
- #endif /* PINE_DISPFILT_INCLUDED */
---- 21,30 ----
- /* exported protoypes */
- char *dfilter(char *, STORE_S *, gf_io_t, FILTLIST_S *);
- char *dfilter_trigger(BODY *, char *, size_t);
-! char *expand_filter_tokens(char *, ENVELOPE *, char **, char **, char **, int *, int *, int *);
- char *filter_session_key(void);
- char *filter_data_file(int);
-! char *exec_function_rule(char *, gf_io_t, gf_io_t);
-
-
- #endif /* PINE_DISPFILT_INCLUDED */
-diff -rc alpine-2.00/alpine/folder.c alpine-2.00.I.USE/alpine/folder.c
-*** alpine-2.00/alpine/folder.c 2008-08-13 17:51:47.000000000 -0700
---- alpine-2.00.I.USE/alpine/folder.c 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 77,83 ****
- #define FLW_LIST 0x04 /* Allow for ListMode for subscribing */
- #define FLW_UNSEEN 0x08 /* Add (unseen) */
-
-!
-
- /*----------------------------------------------------------------------
- The data needed to redraw the folders screen, including the case where the
---- 77,88 ----
- #define FLW_LIST 0x04 /* Allow for ListMode for subscribing */
- #define FLW_UNSEEN 0x08 /* Add (unseen) */
-
-! /* folder colors */
-! #define CLR_UNSEEN 0x01 /* color folder with unseen/new messages */
-! #define CLR_FOLDER 0x02 /* color a name of folder or directory */
-! #define CLR_DIRECT 0x04 /* color a separator of a directory */
-! #define CLR_FLDRLT 0x08 /* color of explanatory text in list scrn*/
-! #define CLR_NORMAL 0x10 /* use normal color */
-
- /*----------------------------------------------------------------------
- The data needed to redraw the folders screen, including the case where the
-***************
-*** 173,179 ****
- int folder_list_write_prefix(FOLDER_S *, int, gf_io_t);
- int folder_list_write_middle(FOLDER_S *fp, CONTEXT_S *ctxt, gf_io_t pc, HANDLE_S *);
- int folder_list_write_suffix(FOLDER_S *, int, gf_io_t);
-! int color_monitored_unseen(FOLDER_S *, int);
- int folder_list_ith(int, CONTEXT_S *);
- char *folder_list_center_space(char *, int);
- HANDLE_S *folder_list_handle(FSTATE_S *, HANDLE_S *);
---- 178,187 ----
- int folder_list_write_prefix(FOLDER_S *, int, gf_io_t);
- int folder_list_write_middle(FOLDER_S *fp, CONTEXT_S *ctxt, gf_io_t pc, HANDLE_S *);
- int folder_list_write_suffix(FOLDER_S *, int, gf_io_t);
-! int color_monitored(FOLDER_S *, int, int);
-! int color_test_for_folder(char *, char *);
-! int color_write_for_folder(gf_io_t pc, int testtype);
-! int use_color_for_folder(FOLDER_S *fp);
- int folder_list_ith(int, CONTEXT_S *);
- char *folder_list_center_space(char *, int);
- HANDLE_S *folder_list_handle(FSTATE_S *, HANDLE_S *);
-***************
-*** 238,244 ****
- dprint((1, "=== folder_screen called ====\n"));
- mailcap_free(); /* free resources we won't be using for a while */
- ps->next_screen = SCREEN_FUN_NULL;
-!
- /* Initialize folder state and dispatches */
- memset(&fs, 0, sizeof(FSTATE_S));
- fs.context = cntxt;
---- 246,252 ----
- dprint((1, "=== folder_screen called ====\n"));
- mailcap_free(); /* free resources we won't be using for a while */
- ps->next_screen = SCREEN_FUN_NULL;
-! strcpy(ps->screen_name, "folder");
- /* Initialize folder state and dispatches */
- memset(&fs, 0, sizeof(FSTATE_S));
- fs.context = cntxt;
-***************
-*** 335,340 ****
---- 343,349 ----
- pine_mail_close(*fs.cache_streamp);
-
- ps->prev_screen = folder_screen;
-+ strcpy(ps->screen_name, "unknown");
- }
-
-
-***************
-*** 1615,1622 ****
---- 1624,1633 ----
- if(c_list->prev)
- gf_puts("\n", pc); /* blank line */
-
-+ color_write_for_folder(pc, CLR_FLDRLT);
- gf_puts(repeat_char(cols, '-'), pc);
- gf_puts("\n", pc);
-+ color_write_for_folder(pc, CLR_NORMAL);
- }
-
- /* nickname or description */
-***************
-*** 1625,1630 ****
---- 1636,1642 ----
- || F_ON(F_CMBND_SUBDIR_DISP, ps_global))){
- char buf[6*MAX_SCREEN_COLS + 1];
-
-+ color_write_for_folder(pc, CLR_FLDRLT);
- if(cols < 40){
- snprintf(buf, sizeof(buf), "%.*s", cols,
- strsquish(tmp_20k_buf, SIZEOF_20KBUF,
-***************
-*** 1651,1656 ****
---- 1663,1669 ----
-
- gf_puts(buf, pc);
- gf_puts("\n", pc);
-+ color_write_for_folder(pc, CLR_NORMAL);
- }
- else if(c_list->label){
- if(utf8_width(c_list->label) > ps_global->ttyo->screen_cols)
-***************
-*** 1660,1668 ****
---- 1673,1683 ----
-
- lbuf[sizeof(lbuf)-1] = '\0';
-
-+ color_write_for_folder(pc, CLR_FLDRLT);
- gf_puts(folder_list_center_space(lbuf, cols), pc);
- gf_puts(lbuf, pc);
- gf_puts("\n", pc);
-+ color_write_for_folder(pc, CLR_NORMAL);
- }
-
- if(c_list->comment){
-***************
-*** 1673,1681 ****
---- 1688,1698 ----
-
- lbuf[sizeof(lbuf)-1] = '\0';
-
-+ color_write_for_folder(pc, CLR_FLDRLT);
- gf_puts(folder_list_center_space(lbuf, cols), pc);
- gf_puts(lbuf, pc);
- gf_puts("\n", pc);
-+ color_write_for_folder(pc, CLR_NORMAL);
- }
-
- if(c_list->dir->desc){
-***************
-*** 1684,1692 ****
---- 1701,1711 ----
- strncpy(buf, strsquish(tmp_20k_buf,SIZEOF_20KBUF,c_list->dir->desc,cols),
- sizeof(buf)-1);
- buf[sizeof(buf)-1] = '\0';
-+ color_write_for_folder(pc, CLR_FLDRLT);
- gf_puts(folder_list_center_space(buf, cols), pc);
- gf_puts(buf, pc);
- gf_puts("\n", pc);
-+ color_write_for_folder(pc, CLR_NORMAL);
- }
-
- if(c_list->use & CNTXT_ZOOM){
-***************
-*** 1703,1720 ****
---- 1722,1744 ----
-
- lbuf[sizeof(lbuf)-1] = '\0';
-
-+ color_write_for_folder(pc, CLR_FLDRLT);
- gf_puts(folder_list_center_space(lbuf, cols), pc);
- gf_puts(lbuf, pc);
- gf_puts("\n", pc);
-+ color_write_for_folder(pc, CLR_NORMAL);
- }
-
-+ color_write_for_folder(pc, CLR_FLDRLT);
- gf_puts(repeat_char(cols, '-'), pc);
- gf_puts("\n\n", pc);
-+ color_write_for_folder(pc, CLR_NORMAL);
- }
-
- if(shown){
- /* Run thru list formatting as necessary */
- if((ftotal = folder_total(FOLDERS(c_list))) != 0){
-+ int use_color;
- /* If previously selected, mark members of new list */
- selected = selected_folders(c_list);
-
-***************
-*** 1729,1738 ****
- continue;
-
- fcount++;
-!
- width = utf8_width(FLDR_NAME(f));
- if(f->isdir)
-! width += (f->isfolder) ? 3 : 1;
-
- if(NEWS_TEST(c_list) && (c_list->use & CNTXT_FINDALL))
- /* assume listmode so we don't have to reformat */
---- 1753,1762 ----
- continue;
-
- fcount++;
-! use_color = use_color_for_folder(f);
- width = utf8_width(FLDR_NAME(f));
- if(f->isdir)
-! width += (f->isfolder) ? (use_color ? 1 : 3) : (use_color ? 0 : 1);
-
- if(NEWS_TEST(c_list) && (c_list->use & CNTXT_FINDALL))
- /* assume listmode so we don't have to reformat */
-***************
-*** 1866,1874 ****
---- 1890,1900 ----
-
- lbuf[sizeof(lbuf)-1] = '\0';
-
-+ color_write_for_folder(pc, CLR_FLDRLT);
- gf_puts(folder_list_center_space(lbuf, cols), pc);
- (void) folder_list_write(pc, handlesp, c_list, -1, lbuf,
- (handlesp) ? FLW_LUNK : FLW_NONE);
-+ color_write_for_folder(pc, CLR_NORMAL);
- }
- }
- else if(fp->fs->combined_view
-***************
-*** 1883,1891 ****
---- 1909,1919 ----
-
- lbuf[sizeof(lbuf)-1] = '\0';
-
-+ color_write_for_folder(pc, CLR_FLDRLT);
- gf_puts(folder_list_center_space(lbuf, cols), pc);
- (void) folder_list_write(pc, handlesp, c_list, -1, lbuf,
- (handlesp) ? FLW_LUNK : FLW_NONE);
-+ color_write_for_folder(pc, CLR_NORMAL);
- }
-
- gf_puts("\n", pc); /* blank line */
-***************
-*** 1932,1948 ****
-
- if(h1){
- /* color unseen? */
-! if(color_monitored_unseen(fp, flags)){
- h1->color_unseen = 1;
- if(h2)
- h2->color_unseen = 1;
- }
- }
-
- /* embed handle pointer */
-! if(((h1 && h1->color_unseen) ?
-! gf_puts(color_embed(ps_global->VAR_INCUNSEEN_FORE_COLOR,
-! ps_global->VAR_INCUNSEEN_BACK_COLOR), pc) : 1)
- && (h1 ? ((*pc)(TAG_EMBED) && (*pc)(TAG_HANDLE)
- && (*pc)(strlen(buf)) && gf_puts(buf, pc)) : 1)
- && (fp ? ((lprefix = folder_list_write_prefix(fp, flags, pc)) >= 0
---- 1960,1983 ----
-
- if(h1){
- /* color unseen? */
-! if(color_monitored(fp, flags, CLR_UNSEEN)){
- h1->color_unseen = 1;
- if(h2)
- h2->color_unseen = 1;
- }
-+ /* color folder? */
-+ if(color_monitored(fp, flags, CLR_FOLDER)){
-+ h1->color_folder = 1;
-+ if(h2)
-+ h2->color_folder = 1;
-+ }
- }
-
- /* embed handle pointer */
-! if(((h1 && h1->color_unseen) ? color_write_for_folder(pc, CLR_UNSEEN)
-! : ((h1 && h1->color_folder)
-! ? color_write_for_folder(pc, fp->isfolder ? CLR_FOLDER : CLR_DIRECT)
-! : 1))
- && (h1 ? ((*pc)(TAG_EMBED) && (*pc)(TAG_HANDLE)
- && (*pc)(strlen(buf)) && gf_puts(buf, pc)) : 1)
- && (fp ? ((lprefix = folder_list_write_prefix(fp, flags, pc)) >= 0
-***************
-*** 1951,1959 ****
- : (alt_name ? gf_puts(alt_name, pc) : 0))
- && (h1 ? ((*pc)(TAG_EMBED) && (*pc)(TAG_BOLDOFF)
- && (*pc)(TAG_EMBED) && (*pc)(TAG_INVOFF)) : 1)
-! && ((h1 && h1->color_unseen) ?
-! gf_puts(color_embed(ps_global->VAR_NORM_FORE_COLOR,
-! ps_global->VAR_NORM_BACK_COLOR), pc) : 1)){
- if(fp)
- width = lprefix + lmiddle + lsuffix;
- else if(alt_name)
---- 1986,1993 ----
- : (alt_name ? gf_puts(alt_name, pc) : 0))
- && (h1 ? ((*pc)(TAG_EMBED) && (*pc)(TAG_BOLDOFF)
- && (*pc)(TAG_EMBED) && (*pc)(TAG_INVOFF)) : 1)
-! && ((h1 && (h1->color_unseen || h1->color_folder)) ?
-! color_write_for_folder(pc, CLR_NORMAL): 1)){
- if(fp)
- width = lprefix + lmiddle + lsuffix;
- else if(alt_name)
-***************
-*** 1992,2002 ****
- return(rv);
- }
-
--
- int
- folder_list_write_middle(FOLDER_S *fp, CONTEXT_S *ctxt, gf_io_t pc, HANDLE_S *h2)
- {
-! int rv = -1;
- char buf[256];
-
- if(h2){
---- 2026,2035 ----
- return(rv);
- }
-
- int
- folder_list_write_middle(FOLDER_S *fp, CONTEXT_S *ctxt, gf_io_t pc, HANDLE_S *h2)
- {
-! int rv = -1, use_color;
- char buf[256];
-
- if(h2){
-***************
-*** 2007,2023 ****
- if(!fp)
- return(rv);
-
- if(gf_puts(FLDR_NAME(fp), pc)
- && (h2 ? ((*pc)(TAG_EMBED) && (*pc)(TAG_BOLDOFF) /* tie off handle 1 */
- && (*pc)(TAG_EMBED) && (*pc)(TAG_INVOFF)) : 1)
- && (h2 ? ((*pc)(TAG_EMBED) && (*pc)(TAG_HANDLE) /* start handle 2 */
- && (*pc)(strlen(buf)) && gf_puts(buf, pc)) : 1)
-! && ((fp->isdir && fp->isfolder) ? (*pc)('[') : 1)
-! && ((fp->isdir) ? (*pc)(ctxt->dir->delim) : 1)
-! && ((fp->isdir && fp->isfolder) ? (*pc)(']') : 1)){
- rv = utf8_width(FLDR_NAME(fp));
- if(fp->isdir)
-! rv += (fp->isfolder) ? 3 : 1;
- }
-
- return(rv);
---- 2040,2062 ----
- if(!fp)
- return(rv);
-
-+ use_color = use_color_for_folder(fp);
-+
- if(gf_puts(FLDR_NAME(fp), pc)
- && (h2 ? ((*pc)(TAG_EMBED) && (*pc)(TAG_BOLDOFF) /* tie off handle 1 */
- && (*pc)(TAG_EMBED) && (*pc)(TAG_INVOFF)) : 1)
-+ && ((use_color && fp->isdir && fp->isfolder)
-+ ? color_write_for_folder(pc, CLR_DIRECT) : 1)
- && (h2 ? ((*pc)(TAG_EMBED) && (*pc)(TAG_HANDLE) /* start handle 2 */
- && (*pc)(strlen(buf)) && gf_puts(buf, pc)) : 1)
-! && use_color
-! ? (fp->isdir && fp->isfolder ? (*pc)(ctxt->dir->delim) : 1)
-! : (((fp->isdir && fp->isfolder) ? (*pc)('[') : 1)
-! && ((fp->isdir) ? (*pc)(ctxt->dir->delim) : 1)
-! && ((fp->isdir && fp->isfolder) ? (*pc)(']') : 1))){
- rv = utf8_width(FLDR_NAME(fp));
- if(fp->isdir)
-! rv += (fp->isfolder) ? (use_color ? 1 : 3) : (use_color ? 0 : 1);
- }
-
- return(rv);
-***************
-*** 2065,2084 ****
- return(rv);
- }
-
-
- int
-! color_monitored_unseen(FOLDER_S *f, int flags)
- {
-! return((flags & FLW_UNSEEN) && f && f->unseen_valid
- && ((F_ON(F_INCOMING_CHECKING_RECENT, ps_global) && f->new > 0L)
- || (F_OFF(F_INCOMING_CHECKING_RECENT, ps_global) && f->unseen > 0L))
-! && pico_usingcolor()
-! && pico_is_good_color(ps_global->VAR_INCUNSEEN_FORE_COLOR)
-! && pico_is_good_color(ps_global->VAR_INCUNSEEN_BACK_COLOR)
-! && (colorcmp(ps_global->VAR_INCUNSEEN_FORE_COLOR,
-! ps_global->VAR_NORM_FORE_COLOR)
-! || colorcmp(ps_global->VAR_INCUNSEEN_BACK_COLOR,
-! ps_global->VAR_NORM_BACK_COLOR)));
- }
-
-
---- 2104,2188 ----
- return(rv);
- }
-
-+ int
-+ color_write_for_folder(gf_io_t pc, int testtype)
-+ {
-+ int rv;
-+ if(!pico_usingcolor())
-+ return 1;
-+ switch (testtype){
-+ case CLR_UNSEEN:
-+ rv = gf_puts(color_embed(ps_global->VAR_INCUNSEEN_FORE_COLOR,
-+ ps_global->VAR_INCUNSEEN_BACK_COLOR), pc);
-+ break;
-+ case CLR_FOLDER:
-+ rv = gf_puts(color_embed(ps_global->VAR_FOLDER_FORE_COLOR,
-+ ps_global->VAR_FOLDER_BACK_COLOR ), pc);
-+ break;
-+ case CLR_FLDRLT:
-+ rv = gf_puts(color_embed(ps_global->VAR_FOLDER_LIST_FORE_COLOR,
-+ ps_global->VAR_FOLDER_LIST_BACK_COLOR ), pc);
-+ break;
-+ case CLR_DIRECT:
-+ rv = gf_puts(color_embed(ps_global->VAR_DIRECTORY_FORE_COLOR,
-+ ps_global->VAR_DIRECTORY_BACK_COLOR), pc);
-+ break;
-+ case CLR_NORMAL:
-+ rv = gf_puts(color_embed(ps_global->VAR_NORM_FORE_COLOR,
-+ ps_global->VAR_NORM_BACK_COLOR), pc);
-+ break;
-+ default:
-+ rv = 0; /* fail */
-+ break;
-+ }
-+ return rv;
-+ }
-+
-
- int
-! color_test_for_folder(char *color_fore, char *color_back)
- {
-! return pico_usingcolor()
-! && pico_is_good_color(color_fore)
-! && pico_is_good_color(color_back)
-! && (colorcmp(color_fore, ps_global->VAR_NORM_FORE_COLOR)
-! || colorcmp(color_back,
-! ps_global->VAR_NORM_BACK_COLOR)) ? 1 : 0;
-!
-! }
-!
-!
-! int
-! use_color_for_folder(FOLDER_S *fp)
-! {
-! int test1, test2;
-! if(fp->isdir)
-! test1 = color_test_for_folder(ps_global->VAR_DIRECTORY_FORE_COLOR,
-! ps_global->VAR_DIRECTORY_BACK_COLOR);
-! if(fp->isfolder)
-! test2 = color_test_for_folder(ps_global->VAR_FOLDER_FORE_COLOR,
-! ps_global->VAR_FOLDER_BACK_COLOR);
-! return (fp->isdir && fp->isfolder) ? test1 + test2
-! : (fp->isdir ? test1 : (fp->isfolder? test2 : 0));
-! }
-!
-!
-! int
-! color_monitored(FOLDER_S *f, int flags, int testtype)
-! {
-! int rv;
-! switch(testtype){
-! case CLR_UNSEEN: rv = (flags & FLW_UNSEEN) && f && f->unseen_valid
- && ((F_ON(F_INCOMING_CHECKING_RECENT, ps_global) && f->new > 0L)
- || (F_OFF(F_INCOMING_CHECKING_RECENT, ps_global) && f->unseen > 0L))
-! && color_test_for_folder(ps_global->VAR_INCUNSEEN_FORE_COLOR,
-! ps_global->VAR_INCUNSEEN_BACK_COLOR) ? 1 : 0;
-! break;
-! case CLR_FOLDER: rv = f ? use_color_for_folder(f) : 0;
-! break;
-! default: rv = 0;
-! }
-! return rv;
- }
-
-
-***************
-*** 6223,6233 ****
- char *
- next_folder(MAILSTREAM **streamp, char *next, size_t nextlen, char *current, CONTEXT_S *cntxt, long int *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,
---- 6327,6343 ----
- char *
- next_folder(MAILSTREAM **streamp, char *next, size_t nextlen, char *current, CONTEXT_S *cntxt, long int *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,
-***************
-*** 6238,6244 ****
- 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)))
---- 6348,6356 ----
- 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)))
-***************
-*** 6249,6254 ****
---- 6361,6371 ----
- int rv, we_cancel = 0, match;
- char msg_buf[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)))
-***************
-*** 6416,6427 ****
---- 6533,6556 ----
- if(f && (!find_recent || recent)){
- strncpy(next, FLDR_NAME(f), nextlen);
- next[nextlen-1] = '\0';
-+ done++;
- }
- else if(nextlen > 0)
- *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);
- }
-
-diff -rc alpine-2.00/alpine/help.c alpine-2.00.I.USE/alpine/help.c
-*** alpine-2.00/alpine/help.c 2008-04-10 09:50:54.000000000 -0700
---- alpine-2.00.I.USE/alpine/help.c 2011-02-07 20:33:44.000000000 -0800
-***************
-*** 390,395 ****
---- 390,396 ----
- {
- int rv = 0;
- char message[64];
-+ struct help_texts *t;
-
- switch(cmd){
- /*----------- Print all the help ------------*/
-***************
-*** 407,412 ****
---- 408,430 ----
-
- break;
-
-+ case MC_EXPORT: /* reuse old definition, so as not to patch pine.h */
-+ {char help_name[40];
-+ help_name[0] = '\0';
-+ for(t = h_texts; t->help_text != NO_HELP; t++)
-+ if(t->help_text == ((HELP_SCROLL_S *)sparms->proc.data.p)->help_source){
-+ strcpy(help_name,t->tag);
-+ break;
-+ }
-+ if(help_name[0])
-+ q_status_message1(SM_ORDER, 0, 2,
-+ "Internal Name: x-alpine-help:%s", help_name);
-+ else
-+ q_status_message(SM_ORDER|SM_DING, 1, 2,
-+ "Can not find link for text help");
-+ }
-+ break;
-+
- case MC_FINISH :
- rv = 1;
- break;
-***************
-*** 572,578 ****
- int
- url_local_helper(char *url)
- {
-! if(!struncmp(url, "x-alpine-help:", 14) && *(url += 14)){
- char *frag;
- HelpType newhelp;
-
---- 590,597 ----
- int
- url_local_helper(char *url)
- {
-! if((!struncmp(url, "x-alpine-help:", 14) && *(url += 14))
-! || (!struncmp(url, "x-pine-help:", 12) && *(url += 12))){
- char *frag;
- HelpType newhelp;
-
-diff -rc alpine-2.00/alpine/imap.c alpine-2.00.I.USE/alpine/imap.c
-*** alpine-2.00/alpine/imap.c 2008-04-10 14:26:20.000000000 -0700
---- alpine-2.00.I.USE/alpine/imap.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 94,100 ****
- * Internal prototypes
- */
- void mm_login_alt_cue(NETMBX *);
-! long pine_tcptimeout_noscreen(long, long);
- int answer_cert_failure(int, MSGNO_S *, SCROLL_S *);
-
- #ifdef LOCAL_PASSWD_CACHE
---- 94,100 ----
- * Internal prototypes
- */
- void mm_login_alt_cue(NETMBX *);
-! long pine_tcptimeout_noscreen(long, long, char *);
- int answer_cert_failure(int, MSGNO_S *, SCROLL_S *);
-
- #ifdef LOCAL_PASSWD_CACHE
-***************
-*** 350,355 ****
---- 350,356 ----
- HelpType help ;
- int len, rc, q_line, flags;
- int oespace, avail, need, save_dont_use;
-+ int save_in_init;
- struct servent *sv;
- #if defined(_WINDOWS) || defined(LOCAL_PASSWD_CACHE)
- int preserve_password = -1;
-***************
-*** 364,369 ****
---- 365,372 ----
- altuserforcache ? altuserforcache : ""));
- q_line = -(ps_global->ttyo ? ps_global->ttyo->footer_rows : 3);
-
-+ save_in_init = ps_global->in_init_seq;
-+ ps_global->in_init_seq = 0;
- ps_global->no_newmail_check_from_optionally_enter = 1;
-
- /* make sure errors are seen */
-***************
-*** 440,448 ****
-
- /* try last working password associated with this host. */
- if(imap_get_passwd(mm_login_list, pwd, user, hostlist,
-! (mb->sslflag||mb->tlsflag))){
- dprint((9, "mm_login: found a password to try\n"));
- ps_global->no_newmail_check_from_optionally_enter = 0;
- return;
- }
-
---- 443,452 ----
-
- /* try last working password associated with this host. */
- if(imap_get_passwd(mm_login_list, pwd, user, hostlist,
-! (mb->sslflag||mb->tlsflag)) && pwd[0] != '\0'){
- dprint((9, "mm_login: found a password to try\n"));
- ps_global->no_newmail_check_from_optionally_enter = 0;
-+ ps_global->in_init_seq = save_in_init;
- return;
- }
-
-***************
-*** 456,461 ****
---- 460,466 ----
- (mb->sslflag||mb->tlsflag));
- dprint((9, "mm_login: found a password in passfile to try\n"));
- ps_global->no_newmail_check_from_optionally_enter = 0;
-+ ps_global->in_init_seq = save_in_init;
- return;
- }
- #endif /* LOCAL_PASSWD_CACHE */
-***************
-*** 484,489 ****
---- 489,495 ----
- "mm_login: found a password for user=%s to try\n",
- user ? user : "?"));
- ps_global->no_newmail_check_from_optionally_enter = 0;
-+ ps_global->in_init_seq = save_in_init;
- return;
- }
-
-***************
-*** 499,504 ****
---- 505,511 ----
- "mm_login: found a password for user=%s in passfile to try\n",
- user ? user : "?"));
- ps_global->no_newmail_check_from_optionally_enter = 0;
-+ ps_global->in_init_seq = save_in_init;
- return;
- }
- #endif /* LOCAL_PASSWD_CACHE */
-***************
-*** 519,524 ****
---- 526,532 ----
- (mb->sslflag||mb->tlsflag))){
- dprint((9, "mm_login:ui: found a password to try\n"));
- ps_global->no_newmail_check_from_optionally_enter = 0;
-+ ps_global->in_init_seq = save_in_init;
- return;
- }
-
-***************
-*** 532,537 ****
---- 540,546 ----
- (mb->sslflag||mb->tlsflag));
- dprint((9, "mm_login:ui: found a password in passfile to try\n"));
- ps_global->no_newmail_check_from_optionally_enter = 0;
-+ ps_global->in_init_seq = save_in_init;
- return;
- }
- #endif /* LOCAL_PASSWD_CACHE */
-***************
-*** 750,755 ****
---- 759,765 ----
-
- if(!(user[0] || altuserforcache)){
- ps_global->no_newmail_check_from_optionally_enter = 0;
-+ ps_global->in_init_seq = save_in_init;
- return;
- }
-
-***************
-*** 762,767 ****
---- 772,778 ----
- if(imap_get_passwd(mm_login_list, pwd, user, hostlist,
- (mb->sslflag||mb->tlsflag))){
- ps_global->no_newmail_check_from_optionally_enter = 0;
-+ ps_global->in_init_seq = save_in_init;
- return;
- }
-
-***************
-*** 771,776 ****
---- 782,788 ----
- imap_set_passwd(&mm_login_list, pwd, user,
- hostlist, (mb->sslflag||mb->tlsflag), 0, 0);
- ps_global->no_newmail_check_from_optionally_enter = 0;
-+ ps_global->in_init_seq = save_in_init;
- return;
- }
- #endif /* LOCAL_PASSWD_CACHE */
-***************
-*** 779,784 ****
---- 791,797 ----
- if(imap_get_passwd(mm_login_list, pwd, altuserforcache, hostlist,
- (mb->sslflag||mb->tlsflag))){
- ps_global->no_newmail_check_from_optionally_enter = 0;
-+ ps_global->in_init_seq = save_in_init;
- return;
- }
-
-***************
-*** 788,793 ****
---- 801,807 ----
- imap_set_passwd(&mm_login_list, pwd, altuserforcache,
- hostlist, (mb->sslflag||mb->tlsflag), 0, 0);
- ps_global->no_newmail_check_from_optionally_enter = 0;
-+ ps_global->in_init_seq = save_in_init;
- return;
- }
- #endif /* LOCAL_PASSWD_CACHE */
-***************
-*** 976,981 ****
---- 990,996 ----
- ps_global->user_says_cancel = (rc == 1);
- user[0] = pwd[0] = '\0';
- ps_global->no_newmail_check_from_optionally_enter = 0;
-+ ps_global->in_init_seq = save_in_init;
- return;
- }
-
-***************
-*** 1181,1187 ****
-
-
- long
-! pine_tcptimeout_noscreen(long int elapsed, long int sincelast)
- {
- long rv = 1L;
- char pmt[128];
---- 1196,1202 ----
-
-
- long
-! pine_tcptimeout_noscreen(long int elapsed, long int sincelast, char *host)
- {
- long rv = 1L;
- char pmt[128];
-***************
-*** 1192,1199 ****
-
- if(elapsed >= (long)ps_global->tcp_query_timeout){
- snprintf(pmt, sizeof(pmt),
-! _("Waited %s seconds for server reply. Break connection to server"),
-! long2string(elapsed));
- pmt[sizeof(pmt)-1] = '\0';
- if(want_to(pmt, 'n', 'n', NO_HELP, WT_FLUSH_IN) == 'y'){
- ps_global->user_says_cancel = 1;
---- 1207,1214 ----
-
- if(elapsed >= (long)ps_global->tcp_query_timeout){
- snprintf(pmt, sizeof(pmt),
-! _("No reply in %s seconds from server %s. Break connection"),
-! long2string(elapsed), host);
- pmt[sizeof(pmt)-1] = '\0';
- if(want_to(pmt, 'n', 'n', NO_HELP, WT_FLUSH_IN) == 'y'){
- ps_global->user_says_cancel = 1;
-***************
-*** 1216,1222 ****
- * pine_tcptimeout - C-client callback to handle tcp-related timeouts.
- */
- long
-! pine_tcptimeout(long int elapsed, long int sincelast)
- {
- long rv = 1L; /* keep trying by default */
- unsigned long ch;
---- 1231,1237 ----
- * pine_tcptimeout - C-client callback to handle tcp-related timeouts.
- */
- long
-! pine_tcptimeout(long int elapsed, long int sincelast, char *host)
- {
- long rv = 1L; /* keep trying by default */
- unsigned long ch;
-***************
-*** 1236,1242 ****
- return(rv);
-
- if(!ps_global->ttyo)
-! return(pine_tcptimeout_noscreen(elapsed, sincelast));
-
- suspend_busy_cue();
-
---- 1251,1257 ----
- return(rv);
-
- if(!ps_global->ttyo)
-! return(pine_tcptimeout_noscreen(elapsed, sincelast, host));
-
- suspend_busy_cue();
-
-***************
-*** 1253,1261 ****
-
- Writechar(BELL, 0);
-
-! PutLine1(ps_global->ttyo->screen_rows - FOOTER_ROWS(ps_global), 0,
-! _("Waited %s seconds for server reply. Break connection to server? "),
-! long2string(elapsed));
- CleartoEOLN();
- fflush(stdout);
- flush_input();
---- 1268,1276 ----
-
- Writechar(BELL, 0);
-
-! PutLine2(ps_global->ttyo->screen_rows - FOOTER_ROWS(ps_global), 0,
-! _("No reply in %s seconds from server %s. Break connection?"),
-! long2string(elapsed), host);
- CleartoEOLN();
- fflush(stdout);
- flush_input();
-***************
-*** 1272,1280 ****
- }
-
- if(rv == 1L){ /* just warn 'em something's up */
-! q_status_message1(SM_ORDER, 0, 0,
-! _("Waited %s seconds for server reply. Still Waiting..."),
-! long2string(elapsed));
- flush_status_messages(0); /* make sure it's seen */
- }
-
---- 1287,1295 ----
- }
-
- if(rv == 1L){ /* just warn 'em something's up */
-! q_status_message2(SM_ORDER, 0, 0,
-! _("No reply in %s seconds from server %s. Still Waiting..."),
-! long2string(elapsed), host);
- flush_status_messages(0); /* make sure it's seen */
- }
-
-***************
-*** 1285,1290 ****
---- 1300,1335 ----
- 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 alpine-2.00/alpine/imap.h alpine-2.00.I.USE/alpine/imap.h
-*** alpine-2.00/alpine/imap.h 2008-04-23 19:00:26.000000000 -0700
---- alpine-2.00.I.USE/alpine/imap.h 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 21,28 ****
-
-
- /* exported protoypes */
- void *pine_block_notify(int, void *);
-! long pine_tcptimeout(long, long);
- long pine_sslcertquery(char *, char *, char *);
- char *pine_newsrcquery(MAILSTREAM *, char *, char *);
- int url_local_certdetails(char *);
---- 21,30 ----
-
-
- /* exported protoypes */
-+ void pine_parse_quota (MAILSTREAM *, unsigned char *, QUOTALIST *);
-+ QUOTALIST *pine_quotalist_copy (QUOTALIST *);
- void *pine_block_notify(int, void *);
-! long pine_tcptimeout(long, long, char *);
- long pine_sslcertquery(char *, char *, char *);
- char *pine_newsrcquery(MAILSTREAM *, char *, char *);
- int url_local_certdetails(char *);
-diff -rc alpine-2.00/alpine/keymenu.c alpine-2.00.I.USE/alpine/keymenu.c
-*** alpine-2.00/alpine/keymenu.c 2008-06-03 08:54:15.000000000 -0700
---- alpine-2.00.I.USE/alpine/keymenu.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 314,319 ****
---- 314,333 ----
- WHEREIS_MENU};
- INST_KEY_MENU(c_fcc_km, context_fcc_keys);
-
-+ 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);
-
- struct key folder_keys[] =
- {HELP_MENU,
-***************
-*** 482,488 ****
- NEXTPAGE_MENU,
- PRYNTMSG_MENU,
- {"Z",N_("Print All"),{MC_PRINTALL,1,{'z'}},KS_NONE},
-! NULL_MENU,
- WHEREIS_MENU,
-
- HELP_MENU,
---- 496,502 ----
- NEXTPAGE_MENU,
- PRYNTMSG_MENU,
- {"Z",N_("Print All"),{MC_PRINTALL,1,{'z'}},KS_NONE},
-! {"N",N_("Name"),{MC_EXPORT,1,{'n'}},KS_NONE},
- WHEREIS_MENU,
-
- HELP_MENU,
-***************
-*** 650,661 ****
- RCOMPOSE_MENU,
- HOMEKEY_MENU,
- ENDKEY_MENU,
-! NULL_MENU,
- /* TRANSLATORS: toggles a collapsed view or an expanded view
- of a message thread on and off */
- {"/",N_("Collapse/Expand"),{MC_COLLAPSE,1,{'/'}},KS_NONE},
-! NULL_MENU,
- NULL_MENU};
- INST_KEY_MENU(index_keymenu, index_keys);
-
-
---- 664,691 ----
- RCOMPOSE_MENU,
- HOMEKEY_MENU,
- ENDKEY_MENU,
-! {"K","Sort Thread",{MC_SORTHREAD,1,{'k'}},KS_NONE},
- /* TRANSLATORS: toggles a collapsed view or an expanded view
- of a message thread on and off */
- {"/",N_("Collapse/Expand"),{MC_COLLAPSE,1,{'/'}},KS_NONE},
-! /* TRANSLATORS: Collapse all threads */
-! {"{",N_("Collapse All"),{MC_KOLAPSE,1,{'{'}},KS_NONE},
-! /* TRANSLATORS: Expand all threads */
-! {"}",N_("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},
-! NULL_MENU,
-! {"[","Close Thre",{MC_CTHREAD,1,{'['}},KS_NONE},
-! {"]","Open Threa",{MC_OTHREAD,1,{']'}},KS_NONE},
-! {"@", N_("Quota"), {MC_QUOTA,1,{'@'}}, KS_NONE},
- NULL_MENU};
-+
- INST_KEY_MENU(index_keymenu, index_keys);
-
-
-***************
-*** 728,736 ****
- RCOMPOSE_MENU,
- HOMEKEY_MENU,
- ENDKEY_MENU,
-! NULL_MENU,
- {"/",N_("Collapse/Expand"),{MC_COLLAPSE,1,{'/'}},KS_NONE},
- NULL_MENU,
- NULL_MENU};
- INST_KEY_MENU(thread_keymenu, thread_keys);
-
---- 758,779 ----
- RCOMPOSE_MENU,
- HOMEKEY_MENU,
- ENDKEY_MENU,
-! {"]",N_("Open Thread"),{MC_OTHREAD,1,{']'}},KS_NONE},
- {"/",N_("Collapse/Expand"),{MC_COLLAPSE,1,{'/'}},KS_NONE},
-+ {")",N_("Next Thread"),{MC_NEXTHREAD,1,{')'}},KS_NONE},
-+ {"(",N_("Prev Thread"),{MC_PRETHREAD,1,{'('}},KS_NONE},
-+
-+ HELP_MENU,
-+ OTHER_MENU,
-+ {"@", N_("Quota"), {MC_QUOTA,1,{'@'}}, KS_NONE},
-+ NULL_MENU,
-+ {"^D",N_("Delete Thread"),{MC_DELTHREAD,1,{ctrl('D')}},KS_NONE},
-+ {"^U",N_("Undelete Thread"),{MC_UNDTHREAD,1,{ctrl('U')}},KS_NONE},
-+ {"^T",N_("SelecT Thread"),{MC_SELTHREAD,1,{ctrl('T')}},KS_NONE},
-+ NULL_MENU,
-+ NULL_MENU,
- NULL_MENU,
-+ {"K","Sort Thread",{MC_SORTHREAD,1,{'k'}},KS_NONE},
- NULL_MENU};
- INST_KEY_MENU(thread_keymenu, thread_keys);
-
-***************
-*** 880,886 ****
- NULL_MENU,
- NULL_MENU,
- NULL_MENU,
-! NULL_MENU};
- INST_KEY_MENU(view_keymenu, view_keys);
-
-
---- 923,942 ----
- NULL_MENU,
- NULL_MENU,
- NULL_MENU,
-! NULL_MENU,
-!
-! HELP_MENU,
-! OTHER_MENU,
-! NULL_MENU,
-! NULL_MENU,
-! NULL_MENU,
-! NULL_MENU,
-! NULL_MENU,
-! {"(",N_("Prev Thread"),{MC_PRETHREAD,1,{'('}},KS_NONE},
-! {")",N_("Next Thread"),{MC_NEXTHREAD,1,{')'}},KS_NONE},
-! {"^D",N_("Delete Thread"),{MC_DELTHREAD,1,{ctrl('D')}},KS_NONE},
-! {"^U",N_("Undelete Thread"),{MC_UNDTHREAD,1,{ctrl('U')}},KS_NONE},
-! {"^T",N_("selecT Thread"),{MC_SELTHREAD,1,{ctrl('T')}},KS_NONE}};
- INST_KEY_MENU(view_keymenu, view_keys);
-
-
-***************
-*** 2452,2458 ****
-
- HELP_MENU,
- OTHER_MENU,
-! NULL_MENU,
- NULL_MENU,
- NULL_MENU,
- NULL_MENU,
---- 2508,2514 ----
-
- HELP_MENU,
- OTHER_MENU,
-! {"I", N_("IndxHdr"), {MC_ADDHEADER,1,{'i'}}, KS_NONE},
- NULL_MENU,
- NULL_MENU,
- NULL_MENU,
-***************
-*** 2481,2487 ****
-
- HELP_MENU,
- OTHER_MENU,
-! NULL_MENU,
- NULL_MENU,
- {"D", N_("DeleteHdr"), {MC_DELETE,1,{'d'}}, KS_NONE},
- /* TRANSLATORS: shuffle headers (change the order of headers) */
---- 2537,2543 ----
-
- HELP_MENU,
- OTHER_MENU,
-! {"I", N_("IndxHdr"), {MC_ADDHEADER,1,{'i'}}, KS_NONE},
- NULL_MENU,
- {"D", N_("DeleteHdr"), {MC_DELETE,1,{'d'}}, KS_NONE},
- /* TRANSLATORS: shuffle headers (change the order of headers) */
-***************
-*** 2527,2533 ****
-
- HELP_MENU,
- OTHER_MENU,
-! NULL_MENU,
- NULL_MENU,
- NULL_MENU,
- NULL_MENU,
---- 2583,2589 ----
-
- HELP_MENU,
- OTHER_MENU,
-! {"I", N_("IndxHdr"), {MC_ADDHEADER,1,{'i'}}, KS_NONE},
- NULL_MENU,
- NULL_MENU,
- NULL_MENU,
-diff -rc alpine-2.00/alpine/keymenu.h alpine-2.00.I.USE/alpine/keymenu.h
-*** alpine-2.00/alpine/keymenu.h 2008-06-03 08:54:15.000000000 -0700
---- alpine-2.00.I.USE/alpine/keymenu.h 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 212,218 ****
- #define MC_COLLAPSE 800
- #define MC_CHK_RECENT 801
- #define MC_DECRYPT 802
-!
-
- /*
- * Some standard Key/Command Bindings
---- 212,232 ----
- #define MC_COLLAPSE 800
- #define MC_CHK_RECENT 801
- #define MC_DECRYPT 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_PRETHREAD 815
-! #define MC_QUOTA 816
-! #define MC_ADDHEADER 817
-
- /*
- * Some standard Key/Command Bindings
-***************
-*** 559,564 ****
---- 573,579 ----
- c_cfg_km,
- c_sel_km,
- c_fcc_km,
-+ pine_quota_keymenu,
- folder_km,
- folder_sel_km,
- folder_sela_km,
-diff -rc alpine-2.00/alpine/mailcmd.c alpine-2.00.I.USE/alpine/mailcmd.c
-*** alpine-2.00/alpine/mailcmd.c 2008-08-21 15:14:45.000000000 -0700
---- alpine-2.00.I.USE/alpine/mailcmd.c 2011-02-07 20:33:44.000000000 -0800
-***************
-*** 72,77 ****
---- 72,78 ----
- #include "../pith/tempfile.h"
- #include "../pith/search.h"
- #include "../pith/margin.h"
-+ #include "../pith/rules.h"
- #ifdef _WINDOWS
- #include "../pico/osdep/mswin.h"
- #endif
-***************
-*** 112,118 ****
- char *choose_a_rule(int);
- int select_by_keyword(MAILSTREAM *, SEARCHSET **);
- char *choose_a_keyword(void);
-! int select_sort(struct pine *, int, SortOrder *, int *);
- int print_index(struct pine *, MSGNO_S *, int);
-
-
---- 113,119 ----
- char *choose_a_rule(int);
- int select_by_keyword(MAILSTREAM *, SEARCHSET **);
- char *choose_a_keyword(void);
-! int select_sort(struct pine *, int, SortOrder *, int *, int);
- int print_index(struct pine *, MSGNO_S *, int);
-
-
-***************
-*** 253,258 ****
---- 254,260 ----
- {'r', 'r', "R", N_("Recipient")},
- {'p', 'p', "P", N_("Participant")},
- {'b', 'b', "B", N_("Body")},
-+ {'h', 'h', "H", N_("Header")},
- {-1, 0, NULL, NULL}
- };
-
-***************
-*** 972,978 ****
- 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", N_("Yes")},
- {'n', 'n', "N", N_("No")},
---- 974,980 ----
- 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", N_("Yes")},
- {'n', 'n', "N", N_("No")},
-***************
-*** 1333,1339 ****
- if(any_messages(msgmap, NULL, NULL)){
- if(any_lflagged(msgmap, MN_SLCT) > 0L){
- if(apply_command(state, stream, msgmap, 0,
-! AC_NONE, question_line)){
- if(F_ON(F_AUTO_UNSELECT, state)){
- agg_select_all(stream, msgmap, NULL, 0);
- unzoom_index(state, stream, msgmap);
---- 1335,1341 ----
- 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)){
- if(F_ON(F_AUTO_UNSELECT, state)){
- agg_select_all(stream, msgmap, NULL, 0);
- unzoom_index(state, stream, msgmap);
-***************
-*** 1351,1373 ****
-
- /*-------- Sort command -------*/
- case MC_SORT :
- {
- int were_threading = THREADING();
- SortOrder sort = mn_get_sort(msgmap);
- int rev = mn_get_revsort(msgmap);
-
- dprint((1,"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);
-
- if(ps_global && ps_global->ttyo){
- blank_keymenu(ps_global->ttyo->screen_rows - 2, 0);
- ps_global->mangled_footer = 1;
- }
-
-! sort_folder(stream, msgmap, sort, rev, SRT_VRB|SRT_MAN);
- }
-
- state->mangled_footer = 1;
---- 1353,1387 ----
-
- /*-------- 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;
-
- dprint((1,"MAIL_CMD: sort\n"));
-! if(sort == SortThread)
-! sort = ps_global->thread_cur_sort;
-! 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 = SortThread;
-+ }
-+ else if(sort == SortThread) /* command = MC_SORT */
-+ ps_global->thread_cur_sort = F_ON(F_THREAD_SORTS_BY_ARRIVAL, ps_global)
-+ ? SortArrival : ps_global->thread_def_sort;
-+
- if(ps_global && ps_global->ttyo){
- blank_keymenu(ps_global->ttyo->screen_rows - 2, 0);
- ps_global->mangled_footer = 1;
- }
-
-! sort_folder(stream, msgmap, sort, rev, SRT_VRB|SRT_MAN, 1);
- }
-
- state->mangled_footer = 1;
-***************
-*** 2368,2373 ****
---- 2382,2388 ----
-
- dprint((4, "\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)
-***************
-*** 2592,2597 ****
---- 2607,2615 ----
- role->nick = cpystr("Default Role");
- }
-
-+ if(state->role)
-+ fs_give((void **)&state->role);
-+ state->role = cpystr(role->nick); /* remember the role */
- state->redrawer = NULL;
- switch(action){
- case 'c':
-***************
-*** 2642,2653 ****
- char *nmsgs, ENVELOPE *env, long int rawmsgno, char *section,
- SaveDel *dela, SavePreserveOrder *prea)
- {
-! int rc, ku = -1, n, flags, last_rc = 0, saveable_count = 0, done = 0;
- int delindex, preindex, r;
- char prompt[6*MAX_SCREEN_COLS+1], *p, expanded[MAILTMPLEN];
- char *buf = tmp_20k_buf;
- char shortbuf[200];
-! char *folder;
- HelpType help;
- SaveDel del = DontAsk;
- SavePreserveOrder pre = DontAskPreserve;
---- 2660,2671 ----
- char *nmsgs, ENVELOPE *env, long int rawmsgno, char *section,
- SaveDel *dela, SavePreserveOrder *prea)
- {
-! int rc, ku = -1, n = 0, flags, last_rc = 0, saveable_count = 0, done = 0;
- int delindex, preindex, r;
- char prompt[6*MAX_SCREEN_COLS+1], *p, expanded[MAILTMPLEN];
- char *buf = tmp_20k_buf;
- char shortbuf[200];
-! char *folder, folder2[MAXPATH];
- HelpType help;
- SaveDel del = DontAsk;
- SavePreserveOrder pre = DontAskPreserve;
-***************
-*** 2655,2660 ****
---- 2673,2681 ----
- static HISTORY_S *history = NULL;
- CONTEXT_S *tc;
- ESCKEY_S ekey[10];
-+ RULE_RESULT *rule;
-+
-+ saved_stream = state->mail_stream;
-
- if(!cntxt)
- panic("no context ptr in save_prompt");
-***************
-*** 2664,2669 ****
---- 2685,2699 ----
- if(!(folder = save_get_default(state, env, rawmsgno, section, cntxt)))
- return(0); /* message expunged! */
-
-+ if (rule = get_result_rule(V_SAVE_RULES, FOR_SAVE, env)){
-+ strncpy(folder2,rule->result,sizeof(folder2)-1);
-+ folder2[sizeof(folder2)-1] = '\0';
-+ folder = folder2;
-+ 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)
- if(!NEWS_TEST(tc))
-***************
-*** 3172,3177 ****
---- 3202,3211 ----
- 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,
-***************
-*** 3266,3271 ****
---- 3300,3308 ----
- */
- 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)
-***************
-*** 3347,3352 ****
---- 3384,3392 ----
- {-1, 0, NULL, NULL}
- };
-
-+ if(F_ON(F_IGNORE_SIZE, ps_global))
-+ return 'y';
-+
- if(flags & SSCP_INIT || flags & SSCP_END){
- if(flags & SSCP_END && possible_corruption)
- q_status_message(SM_ORDER, 3, 3, "There is possible data corruption, check the results");
-***************
-*** 6933,6939 ****
- * Maybe it makes sense to zoom after a select but not after a colon
- * command even though they are very similar.
- */
-! thread_command(state, state->mail_stream, msgmap, ':', -FOOTER_ROWS(state));
- }
- else{
- if((all_selected =
---- 6973,6979 ----
- * Maybe it makes sense to zoom after a select but not after a colon
- * command even though they are very similar.
- */
-! thread_command(state, state->mail_stream, msgmap, ':', -FOOTER_ROWS(state), 1);
- }
- else{
- if((all_selected =
-***************
-*** 6989,6995 ****
- ----*/
- int
- apply_command(struct pine *state, MAILSTREAM *stream, MSGNO_S *msgmap,
-! UCS preloadkeystroke, int flags, int q_line)
- {
- int i = 8, /* number of static entries in sel_opts3 */
- rv = 0,
---- 7029,7035 ----
- ----*/
- int
- apply_command(struct pine *state, MAILSTREAM *stream, MSGNO_S *msgmap,
-! UCS preloadkeystroke, int flags, int q_line, int display)
- {
- int i = 8, /* number of static entries in sel_opts3 */
- rv = 0,
-***************
-*** 7141,7149 ****
- 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;
---- 7181,7199 ----
- 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;
-***************
-*** 7670,7676 ****
- int not = 0, me = 0;
- char sstring[80], savedsstring[80], tmp[128];
- char *p, *sval = NULL;
-! char buftmp[MAILTMPLEN];
- ESCKEY_S ekey[8];
- ENVELOPE *env = NULL;
- HelpType help;
---- 7720,7726 ----
- int not = 0, me = 0;
- char sstring[80], savedsstring[80], tmp[128];
- char *p, *sval = NULL;
-! char buftmp[MAILTMPLEN], namehdr[80];
- ESCKEY_S ekey[8];
- ENVELOPE *env = NULL;
- HelpType help;
-***************
-*** 7757,7762 ****
---- 7807,7846 ----
- sval = "BODYTEXT";
- break;
-
-+ case 'h' :
-+ strcpy(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;
-
-***************
-*** 7953,7959 ****
- flagsforhist = (not ? 0x1 : 0) + (me ? 0x2 : 0);
- save_hist(history, sstring, flagsforhist, NULL);
-
-! rv = agg_text_select(stream, msgmap, type, not, me, sstring, "utf-8", limitsrch);
- if(we_cancel)
- cancel_busy_cue(0);
-
---- 8037,8043 ----
- flagsforhist = (not ? 0x1 : 0) + (me ? 0x2 : 0);
- save_hist(history, sstring, flagsforhist, NULL);
-
-! rv = agg_text_select(stream, msgmap, type, namehdr, not, me, sstring, "utf-8", limitsrch);
- if(we_cancel)
- cancel_busy_cue(0);
-
-***************
-*** 8874,8879 ****
---- 8958,9102 ----
- return(ret);
- }
-
-+ int process_quota_cmd(int cmd, MSGNO_S *msgmap, SCROLL_S *sparms)
-+ {
-+ return cmd;
-+ }
-+
-+ void cmd_quota (struct pine *state)
-+ {
-+ QUOTALIST *imapquota;
-+ NETMBX mb;
-+ unsigned long len, storageuse, storagelim, messageuse, messagelim;
-+ STORE_S *store;
-+ SCROLL_S sargs;
-+ char *linedata, *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) + 19;
-+ 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+3;
-+ storageuse = imapquota->usage;
-+ storagelim = imapquota->limit;
-+ }
-+ if(!strucmp(imapquota->name,"MESSAGE")){
-+ message++;
-+ messagelen = strlen(long2string(imapquota->limit)) + 1+9;
-+ 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 + 9;
-+ 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 + 9;
-+ 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"));
-+ 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 = _("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));
-+ }
-
- /*----------------------------------------------------------------------
- Prompt the user for the type of sort he desires
-***************
-*** 8884,8893 ****
- Returns 0 if it was cancelled, 1 otherwise.
- ----*/
- int
-! select_sort(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];
---- 9107,9116 ----
- Returns 0 if it was cancelled, 1 otherwise.
- ----*/
- int
-! select_sort(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];
-***************
-*** 8920,8936 ****
- 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';
---- 9143,9168 ----
- 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 || allowed_thread_key(state->sort_types[i])){
-! 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';
-***************
-*** 8954,8961 ****
- state->mangled_body = 1; /* signal screen's changed */
- 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;
---- 9186,9202 ----
- state->mangled_body = 1; /* signal screen's changed */
- if(s == 'r')
- *rev = !mn_get_revsort(state->msgmap);
-! else{
-! if(thread){
-! for(i = 0; state->sort_types[i] != EndofList; i++){
-! if(struncmp(sort_name(state->sort_types[i]),
-! sorts[s].label, strlen(sorts[s].label)) == 0)
-! break;
-! }
-! s = i;
-! }
- *sort = state->sort_types[s];
-+ }
-
- if(F_ON(F_SHOW_SORT, ps_global))
- ps_global->mangled_header = 1;
-***************
-*** 9340,9342 ****
---- 9581,9958 ----
- }
-
- #endif /* _WINDOWS */
-+
-+ 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, MCMD_NONE, cmd_delete_index);
-+ count = count_thread(state, stream, msgmap, rawno);
-+ q_status_message2(SM_ORDER, 0, 1, "%s message%s marked deleted",
-+ int2string(count), plural(count));
-+ }
-+
-+ 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(stream, rawno, 0);
-+
-+ 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(stream, rawno, 0);
-+
-+ 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(stream, 0);
-+ 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)));
-+ }
-+
-+ 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);
-+ }
-+
-diff -rc alpine-2.00/alpine/mailcmd.h alpine-2.00.I.USE/alpine/mailcmd.h
-*** alpine-2.00/alpine/mailcmd.h 2008-03-19 12:43:03.000000000 -0700
---- alpine-2.00.I.USE/alpine/mailcmd.h 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 83,89 ****
- int ask_mailbox_reopen(struct pine *, int *);
- void visit_folder(struct pine *, char *, CONTEXT_S *, MAILSTREAM *, unsigned long);
- int select_by_current(struct pine *, MSGNO_S *, CmdWhere);
-! int apply_command(struct pine *, MAILSTREAM *, MSGNO_S *, UCS, int, int);
- char **choose_list_of_keywords(void);
- char *choose_a_charset(int);
- char **choose_list_of_charsets(void);
---- 83,89 ----
- int ask_mailbox_reopen(struct pine *, int *);
- void visit_folder(struct pine *, char *, CONTEXT_S *, MAILSTREAM *, unsigned long);
- int select_by_current(struct pine *, MSGNO_S *, CmdWhere);
-! int apply_command(struct pine *, MAILSTREAM *, MSGNO_S *, UCS, int, int, int);
- char **choose_list_of_keywords(void);
- char *choose_a_charset(int);
- char **choose_list_of_charsets(void);
-***************
-*** 101,106 ****
- int flag_callback(int, long);
- MPopup *flag_submenu(MESSAGECACHE *);
- #endif
-!
-
- #endif /* PINE_MAILCMD_INCLUDED */
---- 101,115 ----
- int flag_callback(int, long);
- MPopup *flag_submenu(MESSAGECACHE *);
- #endif
-! void cmd_delete_thread(struct pine *, MAILSTREAM *, MSGNO_S *);
-! void cmd_delete_this_thread(struct pine *, MAILSTREAM *, MSGNO_S *);
-! void cmd_undelete_this_thread(struct pine *, MAILSTREAM *, MSGNO_S *);
-! void cmd_undelete_thread(struct pine *, MAILSTREAM *, MSGNO_S *);
-! void cmd_select_thread(struct pine *, MAILSTREAM *, MSGNO_S *);
-! void kolapse_thread(struct pine *, MAILSTREAM *, MSGNO_S *, char, int);
-! void collapse_thread(struct pine *, MAILSTREAM *, MSGNO_S *, int);
-! void expand_thread(struct pine *, MAILSTREAM *, MSGNO_S *, int);
-! int collapse_this_thread(struct pine *, MAILSTREAM *, MSGNO_S *, int, int);
-! int expand_this_thread(struct pine *, MAILSTREAM *, MSGNO_S *, int, int);
-
- #endif /* PINE_MAILCMD_INCLUDED */
-diff -rc alpine-2.00/alpine/mailindx.c alpine-2.00.I.USE/alpine/mailindx.c
-*** alpine-2.00/alpine/mailindx.c 2008-07-09 22:01:13.000000000 -0700
---- alpine-2.00.I.USE/alpine/mailindx.c 2011-02-07 20:33:44.000000000 -0800
-***************
-*** 228,233 ****
---- 228,235 ----
- 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
-***************
-*** 239,248 ****
---- 241,254 ----
-
- adjust_cur_to_visible(state->mail_stream, state->msgmap);
-
-+ strcpy(state->screen_name,"index");
-+
- if(THRD_INDX())
- thread_index_screen(state);
- else
- index_index_screen(state);
-+
-+ strcpy(state->screen_name,"unknown");
- }
-
-
-***************
-*** 560,565 ****
---- 566,572 ----
-
- /*---------- Scroll line up ----------*/
- case MC_CHARUP :
-+ previtem:
- (void) process_cmd(state, stream, msgmap, MC_PREVITEM,
- (style == MsgIndex
- || style == MultiMsgIndex
-***************
-*** 577,582 ****
---- 584,590 ----
-
- /*---------- Scroll line down ----------*/
- case MC_CHARDOWN :
-+ nextitem:
- /*
- * Special Page framing handling here. If we
- * did something that should scroll-by-a-line, frame
-***************
-*** 794,799 ****
---- 802,808 ----
-
-
- case MC_THRDINDX :
-+ mc_thrdindx:
- msgmap->top = msgmap->top_after_thrd;
- if(unview_thread(state, stream, msgmap)){
- state->next_screen = mail_index_screen;
-***************
-*** 844,850 ****
- && 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){
---- 853,859 ----
- && 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){
-***************
-*** 923,928 ****
---- 932,939 ----
- reset_index_border();
- break;
-
-+ case MC_QUOTA:
-+ cmd_quota(state);
-
- /*---------- Redraw ----------*/
- case MC_REPAINT :
-***************
-*** 951,959 ****
-
-
- case MC_COLLAPSE :
-! thread_command(state, stream, msgmap, ch, -FOOTER_ROWS(state));
- break;
-
- case MC_DELETE :
- case MC_UNDELETE :
- case MC_REPLY :
---- 962,1066 ----
-
-
- 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 :
-***************
-*** 974,986 ****
- 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,
---- 1081,1092 ----
- 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,
-***************
-*** 2672,2677 ****
---- 2778,2784 ----
- 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;
-***************
-*** 2740,2750 ****
-
- /* 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;
- }
---- 2847,2858 ----
-
- /* 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;
- }
-***************
-*** 2852,2858 ****
-
- void
- thread_command(struct pine *state, MAILSTREAM *stream, MSGNO_S *msgmap,
-! UCS preloadkeystroke, int q_line)
- {
- PINETHRD_S *thrd = NULL;
- unsigned long rawno, save_branch;
---- 2960,2966 ----
-
- void
- thread_command(struct pine *state, MAILSTREAM *stream, MSGNO_S *msgmap,
-! UCS preloadkeystroke, int q_line, int display)
- {
- PINETHRD_S *thrd = NULL;
- unsigned long rawno, save_branch;
-***************
-*** 2901,2907 ****
- cancel_busy_cue(0);
-
- (void ) apply_command(state, stream, msgmap, preloadkeystroke, flags,
-! q_line);
-
- /* restore the original flags */
- copy_lflags(stream, msgmap, MN_STMP, MN_SLCT);
---- 3009,3015 ----
- cancel_busy_cue(0);
-
- (void ) apply_command(state, stream, msgmap, preloadkeystroke, flags,
-! q_line, display);
-
- /* restore the original flags */
- copy_lflags(stream, msgmap, MN_STMP, MN_SLCT);
-***************
-*** 3395,3401 ****
- if(set){
- sort_folder(ps_global->mail_stream, ps_global->msgmap,
- order & 0x000000ff,
-! (order & 0x00000100) != 0, SRT_VRB);
- mswin_beginupdate();
- update_titlebar_message();
- update_titlebar_status();
---- 3503,3509 ----
- if(set){
- sort_folder(ps_global->mail_stream, ps_global->msgmap,
- order & 0x000000ff,
-! (order & 0x00000100) != 0, SRT_VRB, 1);
- mswin_beginupdate();
- update_titlebar_message();
- update_titlebar_status();
-diff -rc alpine-2.00/alpine/mailindx.h alpine-2.00.I.USE/alpine/mailindx.h
-*** alpine-2.00/alpine/mailindx.h 2007-10-15 14:02:56.000000000 -0700
---- alpine-2.00.I.USE/alpine/mailindx.h 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 102,108 ****
- void paint_index_hline(MAILSTREAM *, long, ICE_S *);
- void setup_index_state(int);
- void warn_other_cmds(void);
-! void thread_command(struct pine *, MAILSTREAM *, MSGNO_S *, UCS, int);
- COLOR_PAIR *apply_rev_color(COLOR_PAIR *, int);
- #ifdef _WINDOWS
- int index_sort_callback(int, long);
---- 102,108 ----
- void paint_index_hline(MAILSTREAM *, long, ICE_S *);
- void setup_index_state(int);
- void warn_other_cmds(void);
-! void thread_command(struct pine *, MAILSTREAM *, MSGNO_S *, UCS, int, int);
- COLOR_PAIR *apply_rev_color(COLOR_PAIR *, int);
- #ifdef _WINDOWS
- int index_sort_callback(int, long);
-diff -rc alpine-2.00/alpine/mailpart.c alpine-2.00.I.USE/alpine/mailpart.c
-*** alpine-2.00/alpine/mailpart.c 2008-06-03 08:54:15.000000000 -0700
---- alpine-2.00.I.USE/alpine/mailpart.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 2145,2150 ****
---- 2145,2155 ----
- return(1);
- }
-
-+ /* ok, we have a filename. Now check if there is a template, and if
-+ * so, rename the file accordingly
-+ */
-+ filename = mc_template(filename, a->body, a->can_display & MCD_EXT_PROMPT);
-+
- if((store = so_get(FileStar, filename, WRITE_ACCESS|OWNER_ONLY)) == NULL){
- q_status_message2(SM_ORDER | SM_DING, 3, 5,
- _("Error \"%s\", Can't write file %s"),
-***************
-*** 3307,3313 ****
- /*
- * 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,
---- 3312,3318 ----
- /*
- * 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 alpine-2.00/alpine/mailview.c alpine-2.00.I.USE/alpine/mailview.c
-*** alpine-2.00/alpine/mailview.c 2008-08-01 17:32:26.000000000 -0700
---- alpine-2.00.I.USE/alpine/mailview.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 44,49 ****
---- 44,50 ----
- #include "dispfilt.h"
- #include "busy.h"
- #include "smime.h"
-+ #include "roleconf.h"
- #include "../pith/conf.h"
- #include "../pith/filter.h"
- #include "../pith/msgno.h"
-***************
-*** 129,134 ****
---- 130,136 ----
- #define SS_CUR 2
- #define SS_FREE 3
-
-+ static ACTION_S *role_chosen = NULL;
-
- /*
- * Handle hints.
-***************
-*** 203,209 ****
---- 205,219 ----
- int pcpine_view_cursor(int, long);
- #endif
-
-+ static char *prefix;
-+ #define NO_FLOWED 0x0000
-+ #define IS_FLOWED 0x0001
-+ #define DELETEQUO 0x0010
-+ #define COLORAQUO 0x0100
-+ #define RAWSTRING 0x1000
-
-+ int is_word (char *, int, int);
-+ int is_mailbox(char *, int, int);
-
- /*----------------------------------------------------------------------
- Format a buffer with the text of the current message for browser
-***************
-*** 242,247 ****
---- 252,259 ----
- ps->prev_screen = mail_view_screen;
- ps->force_prefer_plain = ps->force_no_prefer_plain = 0;
-
-+ strcpy(ps->screen_name, "text");
-+
- if(ps->ttyo->screen_rows - HEADER_ROWS(ps) - FOOTER_ROWS(ps) < 1){
- q_status_message(SM_ORDER | SM_DING, 0, 3,
- _("Screen too small to view message"));
-***************
-*** 294,299 ****
---- 306,322 ----
- 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);
-+ }
-+
- init_handles(&handles);
-
- store = so_get(src, NULL, EDIT_ACCESS);
-***************
-*** 478,483 ****
---- 501,510 ----
- }
- while(ps->next_screen == SCREEN_FUN_NULL);
-
-+ strcpy(ps->screen_name, "unknown");
-+
-+ if (prefix && *prefix)
-+ fs_give((void **)&prefix);
- if(we_cancel)
- cancel_busy_cue(-1);
-
-***************
-*** 732,741 ****
- {0, 'a', "A", N_("editApp")},
- {-1, 0, NULL, NULL}};
-
- if(handle->type == URL){
- launch_opts[4].ch = 'u';
-
-! if(!(local_h = !struncmp(handle->h.url.path, "x-alpine-", 9))
- && (handle->h.url.tool
- || ((local_h = url_local_handler(handle->h.url.path) != NULL)
- && (handle->h.url.tool = url_external_handler(handle,1)))
---- 759,771 ----
- {0, 'a', "A", N_("editApp")},
- {-1, 0, NULL, NULL}};
-
-+ if (role_chosen)
-+ free_action(&role_chosen);
- if(handle->type == URL){
- launch_opts[4].ch = 'u';
-
-! if((!(local_h = !struncmp(handle->h.url.path, "x-alpine-", 9))
-! || !(local_h = !struncmp(handle->h.url.path, "x-pine-help", 11)))
- && (handle->h.url.tool
- || ((local_h = url_local_handler(handle->h.url.path) != NULL)
- && (handle->h.url.tool = url_external_handler(handle,1)))
-***************
-*** 833,839 ****
-
- if(force
- || (handle->type == URL
-! && !struncmp(handle->h.url.path, "x-alpine-", 9)))
- return(1);
-
- while(1){
---- 863,870 ----
-
- if(force
- || (handle->type == URL
-! && !struncmp(handle->h.url.path, "x-alpine-", 9)
-! || !struncmp(handle->h.url.path, "x-pine-help", 11)))
- return(1);
-
- while(1){
-***************
-*** 844,855 ****
- * sense if you just say View selected URL ...
- */
- if(handle->type == URL &&
-! !struncmp(handle->h.url.path, "mailto:", 7))
-! snprintf(prompt, sizeof(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
-! snprintf(prompt, sizeof(prompt), "View selected %s %s%.*s%s ? ",
- (handle->type == URL) ? "URL" : "Attachment",
- (handle->type == URL) ? "\"" : "",
- MIN(MAX(0,sc-27), sizeof(prompt)-50),
---- 875,916 ----
- * 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 = N_("Set Role");
-! snprintf(prompt, sizeof(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;
-! snprintf(prompt, sizeof(prompt), "View selected %s %s%.*s%s ? ",
- (handle->type == URL) ? "URL" : "Attachment",
- (handle->type == URL) ? "\"" : "",
- MIN(MAX(0,sc-27), sizeof(prompt)-50),
-***************
-*** 857,862 ****
---- 918,924 ----
- (handle->type == URL)
- ? ((strlen(handle->h.url.path) > MAX(0,sc-27))
- ? "...\"" : "\"") : "");
-+ }
-
- prompt[sizeof(prompt)-1] = '\0';
-
-***************
-*** 865,870 ****
---- 927,955 ----
- case 'y' :
- return(1);
-
-+ case 'r':
-+ {
-+ void (*prev_screen)(struct pine *) = ps_global->prev_screen,
-+ (*redraw)(void) = 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)();
-+ break;
-+ }
-+
- case 'u' :
- strncpy(tmp, handle->h.url.path, sizeof(tmp)-1);
- tmp[sizeof(tmp)-1] = '\0';
-***************
-*** 1697,1702 ****
---- 1782,1788 ----
- {"news:", 5, url_local_news},
- {"x-alpine-gripe:", 15, gripe_gripe_to},
- {"x-alpine-help:", 14, url_local_helper},
-+ {"x-pine-help:", 12, url_local_helper},
- {"x-alpine-phone-home:", 20, url_local_phone_home},
- {"x-alpine-config:", 16, url_local_config},
- {"x-alpine-cert:", 14, url_local_certdetails},
-***************
-*** 1812,1818 ****
- 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);
---- 1898,1904 ----
- 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);
-***************
-*** 1888,1893 ****
---- 1974,1980 ----
-
- free_redraft_pos(&redraft_pos);
- free_action(&role);
-+ free_action(&role_chosen);
-
- return(rv);
- }
-***************
-*** 2603,2608 ****
---- 2690,2696 ----
- }
-
- if(ps_global->noticed_change_in_unseen){
-+ ps_global->noticed_change_in_unseen = 0; /* redraw only once */
- cmd = MC_RESIZE; /* causes cursor to be saved in folder_lister */
- done = 1;
- continue;
-***************
-*** 3449,3454 ****
---- 3537,3588 ----
- 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 :
-diff -rc alpine-2.00/alpine/Makefile.am alpine-2.00.I.USE/alpine/Makefile.am
-*** alpine-2.00/alpine/Makefile.am 2008-06-03 08:54:15.000000000 -0700
---- alpine-2.00.I.USE/alpine/Makefile.am 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 46,48 ****
---- 46,49 ----
- date.c:
- echo "char datestamp[]="\"`date`\"";" > date.c
- echo "char hoststamp[]="\"`hostname`\"";" >> date.c
-+ cat ../patchlevel >> date.c
-diff -rc alpine-2.00/alpine/Makefile.in alpine-2.00.I.USE/alpine/Makefile.in
-*** alpine-2.00/alpine/Makefile.in 2008-06-03 08:54:15.000000000 -0700
---- alpine-2.00.I.USE/alpine/Makefile.in 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 724,729 ****
---- 724,730 ----
- date.c:
- echo "char datestamp[]="\"`date`\"";" > date.c
- echo "char hoststamp[]="\"`hostname`\"";" >> date.c
-+ cat ../patchlevel >> date.c
- # Tell versions [3.59,3.63) of GNU make to not export all variables.
- # Otherwise a system limit (for SysV at least) may be exceeded.
- .NOEXPORT:
-diff -rc alpine-2.00/alpine/osdep/debuging.c alpine-2.00.I.USE/alpine/osdep/debuging.c
-*** alpine-2.00/alpine/osdep/debuging.c 2008-01-04 14:49:15.000000000 -0800
---- alpine-2.00.I.USE/alpine/osdep/debuging.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 104,109 ****
---- 104,110 ----
-
- if(debugfile != NULL){
- char rev[128];
-+ extern char plevstamp[];
- time_t now = time((time_t *)0);
- if(ps_global->debug_flush)
- setvbuf(debugfile, (char *)NULL, _IOLBF, BUFSIZ);
-***************
-*** 126,131 ****
---- 127,134 ----
- get_alpine_revision_string(rev, sizeof(rev)),
- ctime(&now)));
-
-+ dprint((0, "This version uses all.patch:\n%s\n\n", plevstamp));
-+
- dprint((0, "Starting after the reading_pinerc calls, the data in this file should\nbe encoded as UTF-8. Before that it will be in the user's native charset.\n"));
- if(dfile && (debug > DEFAULT_DEBUG ||
- ps_global->debug_imap > 0 ||
-diff -rc alpine-2.00/alpine/osdep/termin.gen.c alpine-2.00.I.USE/alpine/osdep/termin.gen.c
-*** alpine-2.00/alpine/osdep/termin.gen.c 2008-03-26 10:27:45.000000000 -0700
---- alpine-2.00.I.USE/alpine/osdep/termin.gen.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 32,37 ****
---- 32,39 ----
- #include "../../pith/newmail.h"
- #include "../../pith/conf.h"
- #include "../../pith/busy.h"
-+ #include "../../pith/list.h"
-+ #include "../../pith/rules.h"
-
- #include "../../pico/estruct.h"
- #include "../../pico/pico.h"
-***************
-*** 66,77 ****
- int pcpine_oe_cursor(int, long);
- #endif
-
-
- /*
- * Generic tty input routines
- */
-
-!
- /*----------------------------------------------------------------------
- Read a character from keyboard with timeout
- Input: none
---- 68,97 ----
- int pcpine_oe_cursor(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
- */
-
-! void process_init_cmds(struct pine *, char **);
-! void queue_init_errors(struct pine *);
- /*----------------------------------------------------------------------
- Read a character from keyboard with timeout
- Input: none
-***************
-*** 113,118 ****
---- 133,173 ----
- *utf8str = NULL;
-
- ucs = read_char(tm);
-+ if(!ps_global->initial_cmds){
-+ RULE_RESULT *rule;
-+ char **list = NULL, *error = NULL;
-+ int commas = 0, k; /* From args.c */
-+
-+ ps_global->pressed_key = cpystr(pretty_command(ucs));
-+ rule = (RULE_RESULT *)get_result_rule(V_KEY_RULES, FOR_KEY, NULL);
-+ if(ps_global->pressed_key)
-+ fs_give((void **)&ps_global->pressed_key);
-+ if (rule){
-+ for(k = 0; rule->result[k]; k++)
-+ if(rule->result[k] == ',') commas++;
-+ list = parse_list(rule->result, commas+1, 0, &error);
-+ if(error)
-+ sprintf(tmp_20k_buf, "Error in parsing command list: %s, %s",
-+ rule->result, error);
-+ if (rule->result)
-+ fs_give((void **)&rule->result);
-+ fs_give((void **)&rule);
-+ if(error){
-+ q_status_message(SM_ORDER | SM_DING, 0, 2, tmp_20k_buf);
-+ return (NO_OP_COMMAND);
-+ }
-+ process_init_cmds(ps_global, list);
-+ if(ps_global->init_errs){
-+ queue_init_errors(ps_global);
-+ return (NO_OP_COMMAND);
-+ }
-+ ucs = read_char(tm);
-+ ps_global->in_init_seq = 1; /* no output please */
-+ for(k = 0; k < commas; k++)
-+ if(list[k]) fs_give((void **)&list[k]);
-+ if (list) fs_give((void **)list);
-+ }
-+ }
- if(ucs != NO_OP_COMMAND && ucs != NO_OP_IDLE && ucs != KEY_RESIZE)
- zero_new_mail_count();
-
-***************
-*** 306,312 ****
- (escape_list && escape_list[0].ch != -1 && escape_list[0].label)
- ? escape_list[0].label: ""));
-
-! if(!ps_global->ttyo)
- return(pre_screen_config_opt_enter(utf8string, utf8string_size, utf8prompt,
- escape_list, help, flags));
-
---- 361,367 ----
- (escape_list && escape_list[0].ch != -1 && escape_list[0].label)
- ? escape_list[0].label: ""));
-
-! if(!ps_global->ttyo || ps_global->send_immediately)
- return(pre_screen_config_opt_enter(utf8string, utf8string_size, utf8prompt,
- escape_list, help, flags));
-
-***************
-*** 1153,1162 ****
- }
- }
- }
-!
- if(!*ps_global->initial_cmds && ps_global->free_initial_cmds){
- fs_give((void **) &ps_global->free_initial_cmds);
- ps_global->initial_cmds = NULL;
- }
-
- return(ret);
---- 1208,1218 ----
- }
- }
- }
-! 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 = NULL;
-+ firsttime = (char) 1;
- }
-
- return(ret);
-diff -rc alpine-2.00/alpine/osdep/termin.gen.h alpine-2.00.I.USE/alpine/osdep/termin.gen.h
-*** alpine-2.00/alpine/osdep/termin.gen.h 2007-12-18 10:29:24.000000000 -0800
---- alpine-2.00.I.USE/alpine/osdep/termin.gen.h 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 32,37 ****
---- 32,38 ----
- int key_recorder(int);
- int key_playback(int);
- int recent_keystroke(int *, char *, size_t);
-+ void fake_config_screen(struct ttyo **);
- int init_tty_driver(struct pine *);
- void end_tty_driver(struct pine *);
- int PineRaw(int);
-diff -rc alpine-2.00/alpine/osdep/termin.unx.c alpine-2.00.I.USE/alpine/osdep/termin.unx.c
-*** alpine-2.00/alpine/osdep/termin.unx.c 2008-03-26 10:27:45.000000000 -0700
---- alpine-2.00.I.USE/alpine/osdep/termin.unx.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 110,115 ****
---- 110,117 ----
- int
- init_tty_driver(struct pine *ps)
- {
-+ if(ps->send_immediately)
-+ return 0;
- #ifdef MOUSE
- if(F_ON(F_ENABLE_MOUSE, ps_global))
- init_mouse();
-***************
-*** 676,681 ****
---- 678,686 ----
- void
- init_keyboard(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");
-***************
-*** 693,698 ****
---- 698,706 ----
- void
- end_keyboard(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 alpine-2.00/alpine/osdep/termout.unx.c alpine-2.00.I.USE/alpine/osdep/termout.unx.c
-*** alpine-2.00/alpine/osdep/termout.unx.c 2008-03-04 12:41:47.000000000 -0800
---- alpine-2.00.I.USE/alpine/osdep/termout.unx.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 205,210 ****
---- 205,213 ----
- void
- init_screen(void)
- {
-+ if(ps_global->send_immediately)
-+ return;
-+
- if(_termcap_init) /* init using termcap's rule */
- tputs(_termcap_init, 1, outchar);
-
-***************
-*** 312,317 ****
---- 315,323 ----
- {
- int footer_rows_was_one = 0;
-
-+ if(ps_global->send_immediately)
-+ return;
-+
- if(!panicking()){
-
- dprint((9, "end_screen called\n"));
-***************
-*** 366,372 ****
- _line = 0; /* clear leaves us at top... */
- _col = 0;
-
-! if(ps_global->in_init_seq)
- return;
-
- mark_status_unknown();
---- 372,378 ----
- _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 alpine-2.00/alpine/radio.c alpine-2.00.I.USE/alpine/radio.c
-*** alpine-2.00/alpine/radio.c 2007-08-16 15:25:10.000000000 -0700
---- alpine-2.00.I.USE/alpine/radio.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 121,127 ****
- int rv, width;
- size_t len;
-
-! if(!ps_global->ttyo)
- return(pre_screen_config_want_to(question, dflt, on_ctrl_C));
- #ifdef _WINDOWS
- if (mswin_usedialog ()) {
---- 121,127 ----
- int rv, width;
- size_t len;
-
-! 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 alpine-2.00/alpine/reply.c alpine-2.00.I.USE/alpine/reply.c
-*** alpine-2.00/alpine/reply.c 2008-06-03 08:54:15.000000000 -0700
---- alpine-2.00.I.USE/alpine/reply.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 61,67 ****
- #include "../pith/tempfile.h"
- #include "../pith/busy.h"
- #include "../pith/ablookup.h"
-!
-
- /*
- * Internal Prototypes
---- 61,68 ----
- #include "../pith/tempfile.h"
- #include "../pith/busy.h"
- #include "../pith/ablookup.h"
-! #include "../pith/copyaddr.h"
-! #include "../pith/rules.h"
-
- /*
- * Internal Prototypes
-***************
-*** 108,118 ****
- long msgno, j, totalm, rflags, *seq = NULL;
- int i, include_text = 0, times = -1, warned = 0, rv = 0,
- flags = RSF_QUERY_REPLY_ALL, reply_raw_body = 0;
-! int rolemsg = 0, copytomsg = 0;
- gf_io_t pc;
- PAT_STATE dummy;
- REDRAFT_POS_S *redraft_pos = NULL;
- ACTION_S *role = NULL, *nrole;
- #if defined(DOS) && !defined(_WINDOWS)
- char *reserve;
- #endif
---- 109,120 ----
- long msgno, j, totalm, rflags, *seq = NULL;
- int i, include_text = 0, times = -1, warned = 0, rv = 0,
- flags = RSF_QUERY_REPLY_ALL, reply_raw_body = 0;
-! int rolemsg = 0, copytomsg = 0, do_role_early = 0;
- gf_io_t pc;
- PAT_STATE dummy;
- REDRAFT_POS_S *redraft_pos = NULL;
- ACTION_S *role = NULL, *nrole;
-+ RULE_RESULT *rule;
- #if defined(DOS) && !defined(_WINDOWS)
- char *reserve;
- #endif
-***************
-*** 138,143 ****
---- 140,208 ----
- && F_ON(F_ENABLE_FULL_HDR_AND_TEXT, ps_global))
- reply_raw_body = 1;
-
-+ /* Setup possible role */
-+ if(role_arg)
-+ role = copy_action(role_arg);
-+
-+ if(!role && F_ON(F_ENABLE_EDIT_REPLY_INDENT, pine_state)){
-+ for(msgno = mn_first_cur(pine_state->msgmap);
-+ msgno > 0L; msgno = mn_next_cur(pine_state->msgmap)){
-+
-+ env = pine_mail_fetchstructure(pine_state->mail_stream,
-+ mn_m2raw(pine_state->msgmap, msgno),
-+ NULL);
-+ if(!env) {
-+ q_status_message1(SM_ORDER,3,4,
-+ _("Error fetching message %s. Can't reply to it."),
-+ long2string(msgno));
-+ goto done_early;
-+ }
-+
-+ if(rule = get_result_rule(V_REPLY_INDENT_RULES, FOR_COMPOSE , env)){
-+ RULELIST *list = get_rulelist_from_code(V_REPLY_INDENT_RULES,
-+ ps_global->rule_list);
-+ RULE_S *prule = get_rule(list, rule->number);
-+ if(condition_contains_token(prule->condition, ROLE_TOKEN))
-+ do_role_early++;
-+ if(rule->result)
-+ fs_give((void **)&rule->result);
-+ fs_give((void **)&rule);
-+ }
-+ }
-+ }
-+
-+ if(do_role_early){
-+ rflags = ROLE_REPLY;
-+ if(!role && 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 */
-+
- /*
- * We may have to loop through first to figure out what default
- * reply-indent-string to offer...
-***************
-*** 229,235 ****
- 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? */
---- 294,300 ----
- 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? */
-***************
-*** 285,292 ****
- outgoing->subject = cpystr("Re: several messages");
- }
- }
-! else
-! outgoing->subject = reply_subject(env->subject, NULL, 0);
- }
-
- /* fill reply header */
---- 350,367 ----
- outgoing->subject = cpystr("Re: several messages");
- }
- }
-! else{
-! RULE_RESULT *rule;
-! rule = get_result_rule(V_RESUB_RULES,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);
-! }
- }
-
- /* fill reply header */
-***************
-*** 305,315 ****
- 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 */
---- 380,392 ----
- if(sp_expunge_count(pine_state->mail_stream)) /* cur msg expunged */
- goto done_early;
-
-! if (ps_global->reply.role_chosen){
-! if(role_arg)
-! free_action(&role);
-! role = ps_global->reply.role_chosen;
-! }
-
-! if(!role && !do_role_early){
- rflags = ROLE_REPLY;
- if(nonempty_patterns(rflags, &dummy)){
- /* setup default role */
-***************
-*** 545,553 ****
- goto done_early;
- }
-
-! if(orig_body == NULL || orig_body->type == TYPETEXT || reply_raw_body) {
- reply_delimiter(env, role, pc);
-! if(F_ON(F_INCLUDE_HEADER, pine_state))
- reply_forward_header(pine_state->mail_stream,
- mn_m2raw(pine_state->msgmap,msgno),
- NULL, env, pc, prefix);
---- 622,631 ----
- goto done_early;
- }
-
-! if(orig_body == NULL || orig_body->type == TYPETEXT || reply_raw_body
-! || !ps_global->reply.attach) {
- reply_delimiter(env, role, pc);
-! if(ps_global->reply.inchdr)
- reply_forward_header(pine_state->mail_stream,
- mn_m2raw(pine_state->msgmap,msgno),
- NULL, env, pc, prefix);
-***************
-*** 566,572 ****
- && orig_body->nested.part->body.type == TYPETEXT) {
- /*---- First part of the message is text -----*/
- reply_delimiter(env, role, pc);
-! if(F_ON(F_INCLUDE_HEADER, pine_state))
- reply_forward_header(pine_state->mail_stream,
- mn_m2raw(pine_state->msgmap,
- msgno),
---- 644,650 ----
- && orig_body->nested.part->body.type == TYPETEXT) {
- /*---- First part of the message is text -----*/
- reply_delimiter(env, role, pc);
-! if(ps_global->reply.inchdr)
- reply_forward_header(pine_state->mail_stream,
- mn_m2raw(pine_state->msgmap,
- msgno),
-***************
-*** 720,725 ****
---- 798,806 ----
- if(prefix)
- fs_give((void **)&prefix);
-
-+ if (ps_global->role)
-+ fs_give((void **)&ps_global->role);
-+
- if(fcc)
- fs_give((void **) &fcc);
-
-***************
-*** 875,881 ****
-
- prompt[sizeof(prompt)-1] = '\0';
-
-! cmd = radio_buttons(prompt, -FOOTER_ROWS(ps_global), ekey,
- 'y', 'x', help, RB_NORM);
-
- switch(cmd){
---- 956,963 ----
-
- prompt[sizeof(prompt)-1] = '\0';
-
-! cmd = ps_global->send_immediately ? 'n' :
-! radio_buttons(prompt, -FOOTER_ROWS(ps_global), ekey,
- 'y', 'x', help, RB_NORM);
-
- switch(cmd){
-***************
-*** 930,937 ****
- int
- reply_to_all_query(int *flagp)
- {
-! switch(want_to("Reply to all recipients",
-! 'n', 'x', NO_HELP, WT_SEQ_SENSITIVE)){
- case 'x' :
- return(-1);
-
---- 1012,1047 ----
- int
- reply_to_all_query(int *flagp)
- {
-! char prompt[80];
-! ESCKEY_S ekey[4];
-! char cmd;
-!
-! ekey[0].name = "Y";
-! ekey[0].ch = 'y';
-! ekey[0].rval = 'y';
-! ekey[0].label = N_("Yes");
-! ekey[1].name = "N";
-! ekey[1].ch = 'n';
-! ekey[1].rval = 'n';
-! ekey[1].label = N_("No");
-! ekey[2].name = "P";
-! ekey[2].ch = 'p';
-! ekey[2].rval = 'p';
-! ekey[3].ch = -1;
-!
-! ps_global->preserve = F_ON(F_PRESERVE_ORIGINAL_FIELD, ps_global);
-!
-!
-! loop:
-! ekey[2].label = ps_global->preserve ? N_("Not Preserve") : N_("Preserve");
-! snprintf(prompt, sizeof(prompt), _("Reply to all recipients%s"),
-! ps_global->preserve ? _(" (preserving fields)? ") : "? ");
-!
-! prompt[sizeof(prompt)-1] = '\0';
-!
-! switch(cmd = radio_buttons(prompt, -FOOTER_ROWS(ps_global), ekey,
-! 'n', 'x', h_preserve_field, RB_NORM)){
-!
- case 'x' :
- return(-1);
-
-***************
-*** 942,947 ****
---- 1052,1062 ----
- case 'n' : /* clear reply-all bit */
- (*flagp) &= ~RSF_FORCE_REPLY_ALL;
- break;
-+
-+ case 'p' :
-+ ps_global->preserve = !ps_global->preserve;
-+ goto loop; /* ugly, but saves me a variable */
-+ break;
- }
-
- return(0);
-***************
-*** 969,1016 ****
- * 0 if we're NOT to include the text
- * -1 on cancel or error
- */
- int
-! reply_text_query(struct pine *ps, long int many, char **prefix)
- {
- int ret, edited = 0;
-! static ESCKEY_S rtq_opts[] = {
-! {'y', 'y', "Y", N_("Yes")},
-! {'n', '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){
-! if(many > 1L)
-! /* TRANSLATORS: The final three %s's can probably be safely ignored */
-! snprintf(tmp_20k_buf, SIZEOF_20KBUF, _("Include %s original messages in Reply%s%s%s? "),
-! comatose(many),
-! 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) ? "\")" : "");
-! else
-! snprintf(tmp_20k_buf, SIZEOF_20KBUF, _("Include original message in Reply%s%s%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 = N_("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)){
---- 1084,1195 ----
- * 0 if we're NOT to include the text
- * -1 on cancel or error
- */
-+ #define MAX_REPLY_OPTIONS 8
- int
-! reply_text_query(struct pine *ps, long int 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 = *prefix && **prefix ? (F_OFF(F_QUELL_FLOWED_TEXT, ps)
-! && F_OFF(F_STRIP_WS_BEFORE_SEND, ps)
-! && (strcmp(*prefix, "> ") == 0
-! || strcmp(*prefix, ">") == 0)) : 0;
-!
-! ps_global->reply.no_send_flowed = !orig_sf;
-! ps_global->reply.role_chosen = NULL;
-! ps_global->reply.strip = ps->full_header == 0
-! && (F_ON(F_ENABLE_STRIP_SIGDASHES, ps)
-! || F_ON(F_ENABLE_SIGDASHES, ps));
-! ps_global->reply.attach = F_ON(F_ATTACHMENTS_IN_REPLY, ps);
-! ps_global->reply.inchdr = F_ON(F_INCLUDE_HEADER, 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){
-! /* TRANSLATORS: The final five %s's can probably be safely ignored */
-! snprintf(tmp_20k_buf, SIZEOF_20KBUF, _("Include %s original messages in Reply%s%s%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 : "",
-+ ps_global->reply.role_chosen ? "\" and role \"" : "",
-+ ps_global->reply.role_chosen ? ps_global->reply.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 = N_("Yes");
-!
-! compose_style[ekey_num].ch = 'n';
-! compose_style[ekey_num].rval = 'n';
-! compose_style[ekey_num].name = "N";
-! compose_style[ekey_num++].label = N_("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 = N_("Edit Indent String");
-! }
-!
-! /***** 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 = ps_global->reply.strip
-! ? N_("No Strip"): N_("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 = N_("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 = ps_global->reply.no_send_flowed
-! ? N_("Quell Flow") : N_("Send Flowd");
-! }
-!
-! compose_style[ekey_num].ch = 'a';
-! compose_style[ekey_num].rval = 'A';
-! compose_style[ekey_num].name = "A";
-! compose_style[ekey_num++].label = ps_global->reply.attach
-! ? N_("No Attach"): N_("Inc Attac");
-!
-! compose_style[ekey_num].ch = 'h';
-! compose_style[ekey_num].rval = 'H';
-! compose_style[ekey_num].name = "H";
-! compose_style[ekey_num++].label = ps_global->reply.inchdr
-! ? N_("No Header") : N_("Inc Head");
-!
-! }
-! 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)){
-***************
-*** 1018,1023 ****
---- 1197,1242 ----
- cmd_cancelled("Reply");
- return(-1);
-
-+ case 'F':
-+ ps_global->reply.no_send_flowed = (ps_global->reply.no_send_flowed + 1) % 2;
-+ break;
-+
-+ case 'S':
-+ ps_global->reply.strip = (ps_global->reply.strip + 1) % 2;
-+ break;
-+
-+ case 'A':
-+ ps_global->reply.attach = (ps_global->reply.attach + 1) % 2;
-+ break;
-+
-+ case 'H':
-+ ps_global->reply.inchdr = (ps_global->reply.inchdr + 1) % 2;
-+ break;
-+
-+
-+ case 'R':
-+ {
-+ void (*prev_screen)(struct pine *) = ps->prev_screen,
-+ (*redraw)(void) = ps->redrawer;
-+ ps->redrawer = NULL;
-+ ps->next_screen = SCREEN_FUN_NULL;
-+ if(role_select_screen(ps, &ps_global->reply.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(ps_global->reply.role_chosen)
-+ ps_global->reply.role_chosen = combine_inherited_role(ps_global->reply.role_chosen);
-+ }
-+ if (ps->redrawer)
-+ (*ps->redrawer)();
-+ break;
-+
- case 'r':
- if(prefix && *prefix){
- int done = 0;
-***************
-*** 1041,1046 ****
---- 1260,1271 ----
- 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;
-+ ps_global->reply.no_send_flowed = !orig_sf;
- edited = 1;
- }
-
-***************
-*** 1164,1172 ****
- }
- 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);
---- 1389,1394 ----
-***************
-*** 1440,1448 ****
- }
- }
-
-! if(role)
- q_status_message1(SM_ORDER, 3, 4,
- _("Forwarding using role \"%s\""), role->nick);
-
- if(role && role->template){
- char *filtered;
---- 1662,1675 ----
- }
- }
-
-! if (ps_global->role)
-! fs_give((void **)&ps_global->role);
-!
-! if(role){
- q_status_message1(SM_ORDER, 3, 4,
- _("Forwarding using role \"%s\""), role->nick);
-+ ps_global->role = cpystr(role->nick);
-+ }
-
- if(role && role->template){
- char *filtered;
-***************
-*** 1674,1679 ****
---- 1901,1907 ----
- #if defined(DOS) && !defined(_WINDOWS)
- free((void *)reserve);
- #endif
-+ outgoing->sparep = env && env->from ? copyaddr(env->from) : NULL;
- pine_send(outgoing, &body, "FORWARD MESSAGE",
- role, NULL, &reply, redraft_pos,
- NULL, NULL, 0);
-***************
-*** 2426,2431 ****
---- 2654,2661 ----
- {
- int rv;
-
-+ if(ps_global->send_immediately)
-+ return 0;
- clear_cursor_pos(); /* can't know where cursor is */
- mark_status_dirty(); /* don't count on cached text */
- fix_windsize(ps_global);
-***************
-*** 2485,2490 ****
---- 2715,2721 ----
- resize_for_pico(void)
- {
- fix_windsize(ps_global);
-+ ps_global->resize_for_pico = 1;
- }
-
-
-diff -rc alpine-2.00/alpine/reply.h alpine-2.00.I.USE/alpine/reply.h
-*** alpine-2.00/alpine/reply.h 2006-11-15 20:08:15.000000000 -0800
---- alpine-2.00.I.USE/alpine/reply.h 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 28,34 ****
- int confirm_role(long, ACTION_S **);
- int reply_to_all_query(int *);
- int reply_using_replyto_query(void);
-! int reply_text_query(struct pine *, long, char **);
- int reply_news_test(ENVELOPE *, ENVELOPE *);
- char *get_signature_file(char *, int, int, int);
- int forward(struct pine *, ACTION_S *);
---- 28,34 ----
- int confirm_role(long, ACTION_S **);
- int reply_to_all_query(int *);
- int reply_using_replyto_query(void);
-! int reply_text_query(struct pine *, long, ENVELOPE *, char **);
- int reply_news_test(ENVELOPE *, ENVELOPE *);
- char *get_signature_file(char *, int, int, int);
- int forward(struct pine *, ACTION_S *);
-diff -rc alpine-2.00/alpine/roleconf.c alpine-2.00.I.USE/alpine/roleconf.c
-*** alpine-2.00/alpine/roleconf.c 2008-02-27 17:04:46.000000000 -0800
---- alpine-2.00.I.USE/alpine/roleconf.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 139,146 ****
---- 139,151 ----
-
- 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);
- }
-
-***************
-*** 4477,4487 ****
- ctmp->tool = role_sort_tool;
- ctmp->valoffset = rindent;
- ctmp->flags |= CF_NOSELECT;
-! ctmp->value = cpystr(set_choose); \
-
- 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;
---- 4482,4492 ----
- ctmp->tool = role_sort_tool;
- ctmp->valoffset = rindent;
- ctmp->flags |= CF_NOSELECT;
-! ctmp->value = cpystr(set_choose);
-
- 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;
-***************
-*** 4491,4497 ****
- ctmp->tool = role_sort_tool;
- ctmp->valoffset = rindent;
- 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++){
---- 4496,4502 ----
- ctmp->tool = role_sort_tool;
- ctmp->valoffset = rindent;
- 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++){
-***************
-*** 4503,4509 ****
- ctmp->valoffset = rindent;
- ctmp->varmem = i + (j * EndofList);
- ctmp->value = generalized_sort_pretty_value(ps, ctmp,
-! 0);
- }
- }
-
---- 4508,4514 ----
- ctmp->valoffset = rindent;
- ctmp->varmem = i + (j * EndofList);
- ctmp->value = generalized_sort_pretty_value(ps, ctmp,
-! 0, 0);
- }
- }
-
-***************
-*** 5436,5442 ****
- (*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);
---- 5441,5447 ----
- (*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);
-***************
-*** 7705,7710 ****
---- 7710,7720 ----
- 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));
-
-diff -rc alpine-2.00/alpine/send.c alpine-2.00.I.USE/alpine/send.c
-*** alpine-2.00/alpine/send.c 2008-06-30 15:03:35.000000000 -0700
---- alpine-2.00.I.USE/alpine/send.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 62,68 ****
- #include "../pith/mimetype.h"
- #include "../pith/send.h"
- #include "../pith/smime.h"
-!
-
- typedef struct body_particulars {
- unsigned short type, encoding, had_csp;
---- 62,68 ----
- #include "../pith/mimetype.h"
- #include "../pith/send.h"
- #include "../pith/smime.h"
-! #include "../pith/rules.h"
-
- typedef struct body_particulars {
- unsigned short type, encoding, had_csp;
-***************
-*** 98,103 ****
---- 98,104 ----
- void free_body_particulars(BODY_PARTICULARS_S *);
- long message_format_for_pico(long, int (*)(int));
- int send_exit_for_pico(struct headerentry *, void (*)(void), int, char **);
-+ void new_thread_on_blank_subject(void);
- char *choose_a_priority(char *);
- int dont_flow_this_time(void);
- int mime_type_for_pico(char *);
-***************
-*** 237,242 ****
---- 238,248 ----
- 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);
-***************
-*** 446,453 ****
-
- ps_global->next_screen = prev_screen;
- ps_global->redrawer = redraw;
-! if(role)
- role = combine_inherited_role(role);
- }
- break;
-
---- 452,463 ----
-
- 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;
-
-***************
-*** 612,617 ****
---- 622,628 ----
- 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();
-
- /*
-***************
-*** 642,650 ****
- }
- }
-
-! if(role)
- q_status_message1(SM_ORDER, 3, 4, _("Composing using role \"%s\""),
- role->nick);
-
- /*
- * The type of storage object allocated below is vitally
---- 653,666 ----
- }
- }
-
-! if (ps_global->role)
-! fs_give((void **)&ps_global->role);
-!
-! if(role){
- q_status_message1(SM_ORDER, 3, 4, _("Composing using role \"%s\""),
- role->nick);
-+ ps_global->role = cpystr(role->nick);
-+ }
-
- /*
- * The type of storage object allocated below is vitally
-***************
-*** 910,916 ****
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KS_NONE},
- {"From : ", "From", h_composer_from, 10, 0, NULL,
- build_address, NULL, NULL, addr_book_compose, "To AddrBk", NULL, abook_nickname_complete,
-! 0, 1, 0, 1, 0, 0, 0, 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, abook_nickname_complete,
- 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, KS_TOADDRBOOK},
---- 926,932 ----
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KS_NONE},
- {"From : ", "From", h_composer_from, 10, 0, NULL,
- build_address, NULL, NULL, addr_book_compose, "To AddrBk", NULL, abook_nickname_complete,
-! 0, 1, 0, 0, 0, 0, 0, 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, abook_nickname_complete,
- 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, KS_TOADDRBOOK},
-***************
-*** 1780,1785 ****
---- 1796,1804 ----
- 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
-***************
-*** 1816,1821 ****
---- 1835,1842 ----
- pbf->mimetype = mime_type_for_pico;
- pbf->exittest = send_exit_for_pico;
- pbf->user_says_noflow = dont_flow_this_time;
-+ pbf->newthread = new_thread_on_blank_subject;
-+ ps_global->newthread = 0; /* reset this value */
- if(F_OFF(F_CANCEL_CONFIRM, ps_global))
- pbf->canceltest = cancel_for_pico;
-
-***************
-*** 2301,2306 ****
---- 2322,2332 ----
- 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;
-***************
-*** 2410,2415 ****
---- 2436,2461 ----
- 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 = (unsigned char *) cpystr(addr);
-+ ps_global->procid = cpystr("fwd-lcc");
-+ rule = get_result_rule(V_FORWARD_RULES,
-+ 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);
-+ }
-+ fs_give((void **)&ps_global->procid);
-+ if (outgoing->date)
-+ fs_give((void **)&outgoing->date);
-+ }
-+
- rfc822_parse_adrlist(pf->addr, addr,
- ps_global->maildomain);
- fs_give((void **)&addr);
-***************
-*** 2979,2985 ****
- #ifdef _WINDOWS
- mswin_setwindowmenu (MENU_DEFAULT);
- #endif
-! fix_windsize(ps_global);
-
- /*
- * Only reinitialize signals if we didn't receive an interesting
---- 3025,3036 ----
- #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
-***************
-*** 3038,3044 ****
- 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.
---- 3089,3097 ----
- 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.
-***************
-*** 3068,3073 ****
---- 3121,3131 ----
- outgoing->sender->host = cpystr(ps_global->hostname);
- }
-
-+ if(ps_global->newthread){
-+ if(outgoing->in_reply_to) fs_give((void **)&outgoing->in_reply_to);
-+ if(outgoing->references) fs_give((void **)&outgoing->references);
-+ }
-+
- /*----- Message is edited, now decide what to do with it ----*/
- if(editor_result & (COMP_SUSPEND | COMP_GOTHUP | COMP_CANCEL)){
- /*=========== Postpone or Interrupted message ============*/
-***************
-*** 3710,3719 ****
- 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%s."),
- fcc ? " or saved to fcc" : "");
-! continue;
- }
-
- /*------ Actually post -------*/
---- 3768,3783 ----
- 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%s."),
- fcc ? " or saved to fcc" : "");
-! continue;
-! }
-! else{
-! fprintf(stderr, _("Problem filtering! Nothing sent or saved to Fcc\n"));
-! exit(-1);
-! }
- }
-
- /*------ Actually post -------*/
-***************
-*** 3957,3962 ****
---- 4021,4028 ----
- /*----- Mail Post FAILED, back to composer -----*/
- if(result & (P_MAIL_LOSE | P_FCC_LOSE)){
- dprint((1, "Send failed, continuing\n"));
-+ if (ps_global->send_immediately)
-+ exit(1);
-
- if(result & P_FCC_LOSE){
- /*
-***************
-*** 3991,3996 ****
---- 4057,4063 ----
- 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, SIZEOF_20KBUF, NULL));
-
-***************
-*** 4360,4365 ****
---- 4427,4442 ----
- return(buf);
- }
-
-+ /* Callback from Pico to set the conditions for Alpine to start a new thread
-+ */
-+
-+ void
-+ new_thread_on_blank_subject(void)
-+ {
-+ ps_global->newthread = F_ON(F_NEW_THREAD_ON_BLANK_SUBJECT, ps_global);
-+ }
-+
-+
-
- /*----------------------------------------------------------------------
- Call back for pico to insert the specified message's text
-***************
-*** 4447,4453 ****
- return(1);
- }
-
-! if(F_ON(F_SEND_WO_CONFIRM, ps_global)){
- if(result)
- *result = NULL;
-
---- 4524,4530 ----
- return(1);
- }
-
-! if(!ps_global->send_immediately && F_ON(F_SEND_WO_CONFIRM, ps_global)){
- if(result)
- *result = NULL;
-
-***************
-*** 4627,4633 ****
-
- opts[i].ch = -1;
-
-! fix_windsize(ps_global);
-
- while(1){
- if(filters && filters->filter && (p = strindex(filters->filter, ' ')))
---- 4704,4711 ----
-
- opts[i].ch = -1;
-
-! if (!ps_global->send_immediately)
-! fix_windsize(ps_global);
-
- while(1){
- if(filters && filters->filter && (p = strindex(filters->filter, ' ')))
-***************
-*** 4809,4815 ****
- if(double_rad +
- ((call_mailer_flags & CM_DSN_SHOW)
- ? 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 :
---- 4887,4894 ----
- if(double_rad +
- ((call_mailer_flags & CM_DSN_SHOW)
- ? 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 :
-***************
-*** 4818,4824 ****
- h_send_prompt,
- RB_NORM);
- else
-! rv = radio_buttons(tmp_20k_buf, -FOOTER_ROWS(ps_global), opts,
- 'y', 'z',
- (double_rad +
- ((call_mailer_flags & CM_DSN_SHOW)
---- 4897,4904 ----
- 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 +
- ((call_mailer_flags & CM_DSN_SHOW)
-***************
-*** 5155,5165 ****
---- 5235,5247 ----
- {'c', 'c', "C", N_("Confirm")},
- {'n', 'n', "N", N_("No")},
- {'y', 'y', "", ""},
-+ {'t', 't', "T", N_("CounT")},
- {-1, 0, NULL, NULL}
- };
-
- ps_global->redrawer = redraw_pico;
- fix_windsize(ps_global);
-+ pbf->curpos[0] = '\0';
-
- while(1){
- rv = radio_buttons(prompt, -FOOTER_ROWS(ps_global), opts,
-***************
-*** 5172,5183 ****
- q_status_message(SM_INFO, 1, 3, _(" Type \"C\" to cancel message "));
- display_message('x');
- }
- else
- break;
- }
-
- ps_global->redrawer = redraw;
-! return(rstr);
- }
-
-
---- 5254,5269 ----
- q_status_message(SM_INFO, 1, 3, _(" Type \"C\" to cancel message "));
- display_message('x');
- }
-+ else if(rv == 't'){
-+ showcpos(1,0);
-+ break;
-+ }
- else
- break;
- }
-
- ps_global->redrawer = redraw;
-! return(pbf->curpos[0] ? pbf->curpos : rstr);
- }
-
-
-***************
-*** 5204,5210 ****
-
- if(fcmd
- && (cmd=expand_filter_tokens(fcmd, outgoing, &tmpf, &resultf, &mtf,
-! &key, &include_hdrs))){
- if(tmpf){
- /*
- * We need WRITE_TO_LOCALE here because the user is going to
---- 5290,5296 ----
-
- if(fcmd
- && (cmd=expand_filter_tokens(fcmd, outgoing, &tmpf, &resultf, &mtf,
-! &key, &include_hdrs, NULL))){
- if(tmpf){
- /*
- * We need WRITE_TO_LOCALE here because the user is going to
-***************
-*** 5281,5289 ****
- if((tmp_so = so_get(PicoText, NULL, EDIT_ACCESS)) != NULL){
- gf_set_so_writec(&pc, tmp_so);
- ps_global->mangled_screen = 1;
-! suspend_busy_cue();
-! ClearScreen();
-! fflush(stdout);
- if(tmpf){
- PIPE_S *fpipe;
-
---- 5367,5377 ----
- if((tmp_so = so_get(PicoText, NULL, EDIT_ACCESS)) != NULL){
- gf_set_so_writec(&pc, tmp_so);
- ps_global->mangled_screen = 1;
-! if (!ps_global->send_immediately){
-! suspend_busy_cue();
-! ClearScreen();
-! fflush(stdout);
-! }
- if(tmpf){
- PIPE_S *fpipe;
-
-***************
-*** 5311,5317 ****
- }
- else
- errstr = gf_filter(cmd, key ? filter_session_key() : NULL,
-! readthis_so, pc, NULL, 0,
- pipe_callback);
-
- if(our_tmpf_so)
---- 5399,5405 ----
- }
- else
- errstr = gf_filter(cmd, key ? filter_session_key() : NULL,
-! readthis_so, pc, NULL, 0, 0,
- pipe_callback);
-
- if(our_tmpf_so)
-***************
-*** 5395,5402 ****
- set_mime_type_by_grope(b);
- }
-
-! ClearScreen();
-! resume_busy_cue(0);
- }
- else
- errstr = "Can't create space for filtered text.";
---- 5483,5492 ----
- set_mime_type_by_grope(b);
- }
-
-! if (!ps_global->send_immediately){
-! ClearScreen();
-! resume_busy_cue(0);
-! }
- }
- else
- errstr = "Can't create space for filtered text.";
-***************
-*** 5427,5436 ****
- if(tmp_so)
- so_give(&tmp_so);
-
-! q_status_message1(SM_ORDER | SM_DING, 3, 6, _("Problem filtering: %s"),
- errstr);
-! dprint((1, "Filter FAILED: %s\n",
- errstr ? errstr : "?"));
- }
-
- return(errstr == NULL);
---- 5517,5532 ----
- if(tmp_so)
- so_give(&tmp_so);
-
-! if (!ps_global->send_immediately){
-! q_status_message1(SM_ORDER | SM_DING, 3, 6, _("Problem filtering: %s"),
- errstr);
-! dprint((1, "Filter FAILED: %s\n",
- errstr ? errstr : "?"));
-+ }
-+ else{
-+ fprintf(stderr, _("Filter FAILED: %s\n"), errstr ? errstr : "?");
-+ exit(-1);
-+ }
- }
-
- return(errstr == NULL);
-diff -rc alpine-2.00/alpine/setup.c alpine-2.00.I.USE/alpine/setup.c
-*** alpine-2.00/alpine/setup.c 2008-01-23 11:15:36.000000000 -0800
---- alpine-2.00.I.USE/alpine/setup.c 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 257,263 ****
- ctmpa->flags |= CF_NOSELECT;
- ctmpa->value = cpystr("--- ----------------------");
-
-! decode_sort(pval, &def_sort, &def_sort_rev);
-
- for(j = 0; j < 2; j++){
- for(i = 0; ps->sort_types[i] != EndofList; i++){
---- 257,263 ----
- ctmpa->flags |= CF_NOSELECT;
- ctmpa->value = cpystr("--- ----------------------");
-
-! decode_sort(pval, &def_sort, &def_sort_rev, 0);
-
- for(j = 0; j < 2; j++){
- for(i = 0; ps->sort_types[i] != EndofList; i++){
-***************
-*** 272,277 ****
---- 272,326 ----
- }
- }
- }
-+ else if(vtmp == &ps->vars[V_THREAD_SORT_KEY]){ /* radio case */
-+ SortOrder thread_def_sort;
-+ int thread_def_sort_rev, lv;
-+
-+ 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 (allowed_thread_key(ps->sort_types[i])){
-+ 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;
-***************
-*** 463,468 ****
---- 512,526 ----
- }
- }
-
-+ 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(ps_global->mail_stream, 0);
-+ reset_sort_order(SRT_VRB);
-+ }
-+ }
-+
- treat_color_vars_as_text = 0;
- free_saved_config(ps, &vsave, expose_hidden_config);
- #ifdef _WINDOWS
-diff -rc alpine-2.00/alpine/signal.c alpine-2.00.I.USE/alpine/signal.c
-*** alpine-2.00/alpine/signal.c 2008-04-07 15:58:40.000000000 -0700
---- alpine-2.00.I.USE/alpine/signal.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 819,826 ****
- #else
- if(F_ON(F_SUSPEND_SPAWNS, ps_global)){
- PIPE_S *syspipe;
-
-! if((syspipe = open_system_pipe(NULL, NULL, NULL, PIPE_USER|PIPE_RESET,
- 0, pipe_callback, pipe_report_error)) != NULL){
- suspend_notice("exit");
- #ifndef SIGCHLD
---- 819,828 ----
- #else
- if(F_ON(F_SUSPEND_SPAWNS, ps_global)){
- PIPE_S *syspipe;
-+ int flag = some_stream_is_locked() ? PIPE_NONEWMAIL : 0;
-
-! flag |= PIPE_USER|PIPE_RESET;
-! if((syspipe = open_system_pipe(NULL, NULL, NULL, flag,
- 0, pipe_callback, pipe_report_error)) != NULL){
- suspend_notice("exit");
- #ifndef SIGCHLD
-***************
-*** 867,873 ****
- _("Error loading \"%s\""), shell);
- #endif
-
-! if(isremote && !pine_mail_ping(ps_global->mail_stream))
- q_status_message(SM_ORDER | SM_DING, 4, 9,
- _("Suspended for too long, IMAP connection broken"));
-
---- 869,876 ----
- _("Error loading \"%s\""), shell);
- #endif
-
-! if(isremote && !ps_global->mail_stream->lock
-! && !pine_mail_ping(ps_global->mail_stream))
- q_status_message(SM_ORDER | SM_DING, 4, 9,
- _("Suspended for too long, IMAP connection broken"));
-
-diff -rc alpine-2.00/alpine/status.c alpine-2.00.I.USE/alpine/status.c
-*** alpine-2.00/alpine/status.c 2007-11-28 09:57:15.000000000 -0800
---- alpine-2.00.I.USE/alpine/status.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 110,115 ****
---- 110,118 ----
- char *clean_msg;
- size_t mlen;
-
-+ if (ps_global->send_immediately)
-+ return;
-+
- status_message_lock();
-
- /*
-***************
-*** 604,609 ****
---- 607,615 ----
- SMQ_T *q, *copy_of_q;
- int ding;
-
-+ if(ps_global->send_immediately)
-+ return;
-+
- start_over:
- status_message_lock();
-
-diff -rc alpine-2.00/doc/alpine.1 alpine-2.00.I.USE/doc/alpine.1
-*** alpine-2.00/doc/alpine.1 2008-08-22 13:40:16.000000000 -0700
---- alpine-2.00.I.USE/doc/alpine.1 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 164,169 ****
---- 164,171 ----
- .IP \fB-n\ \fInumber\fR 20
- Start up with current message-number set to
- .I number.
-+ .IP \fB-noutf8\fR 20
-+ Warns Alpine that piped input is not encoded in UTF-8.
- .IP \fB-o\fR 20
- Open first folder read-only.
- .IP \fB-p\ \fIconfig-file\fR 20
-diff -rc alpine-2.00/imap/src/c-client/imap4r1.c alpine-2.00.I.USE/imap/src/c-client/imap4r1.c
-*** alpine-2.00/imap/src/c-client/imap4r1.c 2008-06-04 11:39:54.000000000 -0700
---- alpine-2.00.I.USE/imap/src/c-client/imap4r1.c 2011-02-07 20:33:43.000000000 -0800
-***************
-*** 1121,1126 ****
---- 1121,1127 ----
- sprintf (tmp,"Retrying using %s authentication after %.80s",
- at->name,lsterr);
- mm_log (tmp,NIL);
-+ delete_password(mb, usr);
- fs_give ((void **) &lsterr);
- }
- trial = 0; /* initial trial count */
-***************
-*** 1129,1134 ****
---- 1130,1136 ----
- if (lsterr) { /* previous attempt with this one failed? */
- sprintf (tmp,"Retrying %s authentication after %.80s",at->name,lsterr);
- mm_log (tmp,WARN);
-+ delete_password(mb, usr);
- fs_give ((void **) &lsterr);
- }
- LOCAL->saslcancel = NIL;
-***************
-*** 1166,1171 ****
---- 1168,1174 ----
- sprintf (tmp,"Can not authenticate to IMAP server: %.80s",lsterr);
- mm_log (tmp,ERROR);
- }
-+ delete_password(mb, usr);
- fs_give ((void **) &lsterr);
- }
- return NIL; /* ran out of authenticators */
-***************
-*** 1207,1212 ****
---- 1210,1216 ----
- if (imap_OK (stream,reply = imap_send (stream,"LOGIN",args)))
- ret = LONGT; /* success */
- else {
-+ delete_password(mb, usr);
- mm_log (reply->text,WARN);
- if (!LOCAL->referral && (trial == imap_maxlogintrials))
- mm_log ("Too many login failures",ERROR);
-***************
-*** 4527,4532 ****
---- 4531,4537 ----
- 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? */
-***************
-*** 4581,4586 ****
---- 4586,4592 ----
- 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 alpine-2.00/imap/src/c-client/mail.c alpine-2.00.I.USE/imap/src/c-client/mail.c
-*** alpine-2.00/imap/src/c-client/mail.c 2008-06-04 11:39:54.000000000 -0700
---- alpine-2.00.I.USE/imap/src/c-client/mail.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 34,39 ****
---- 34,41 ----
-
- /* c-client global data */
-
-+ static char *pwdfile = NIL; /*password file */
-+ static int xlate_key; /* for password file support */
- /* version of this library */
- static char *mailcclientversion = CCLIENTVERSION;
- /* list of mail drivers */
-***************
-*** 52,57 ****
---- 54,61 ----
- static rfc822out_t mail822out = NIL;
- /* RFC-822 output generator (new style) */
- static rfc822outfull_t mail822outfull = NIL;
-+ /* Erase password (client side) */
-+ static deletepwd_t erase_password = NIL;
- /* SMTP verbose callback */
- static smtpverbose_t mailsmtpverbose = mm_dlog;
- /* proxy copy routine */
-***************
-*** 544,549 ****
---- 548,558 ----
- case GET_SENDCOMMAND:
- ret = (void *) mailsendcommand;
- break;
-+ case SET_ERASEPASSWORD:
-+ erase_password = (deletepwd_t) value;
-+ case GET_ERASEPASSWORD:
-+ ret = (void *) erase_password;
-+ break;
-
- case SET_SERVICENAME:
- servicename = (char *) value;
-***************
-*** 640,645 ****
---- 649,661 ----
- case GET_SNARFMAILBOXNAME:
- if (stream) ret = (void *) stream->snarf.name;
- break;
-+ case SET_PASSWORDFILE:
-+ if (pwdfile) fs_give ((void **) &pwdfile);
-+ pwdfile = cpystr ((char *) value);
-+ break;
-+ case GET_PASSWORDFILE:
-+ ret = (void *) pwdfile;
-+ break;
- default:
- if (r = smtp_parameters (function,value)) ret = r;
- if (r = env_parameters (function,value)) ret = r;
-***************
-*** 991,997 ****
- MAILSTREAM *ts;
- char *s,*t,tmp[MAILTMPLEN];
- size_t i;
-! DRIVER *d;
- /* never allow names with newlines */
- if (s = strpbrk (mailbox,"\015\012")) {
- MM_LOG ("Can't create mailbox with such a name",ERROR);
---- 1007,1013 ----
- MAILSTREAM *ts;
- char *s,*t,tmp[MAILTMPLEN];
- size_t i;
-! DRIVER *d, *md;
- /* never allow names with newlines */
- if (s = strpbrk (mailbox,"\015\012")) {
- MM_LOG ("Can't create mailbox with such a name",ERROR);
-***************
-*** 1015,1020 ****
---- 1031,1038 ----
- return NIL;
- }
-
-+ /* Hack, we should do this better, but it works */
-+ for (md = maildrivers; md && strcmp (md->name, "md"); md = md->next);
- /* see if special driver hack */
- if ((mailbox[0] == '#') && ((mailbox[1] == 'd') || (mailbox[1] == 'D')) &&
- ((mailbox[2] == 'r') || (mailbox[2] == 'R')) &&
-***************
-*** 1045,1050 ****
---- 1063,1075 ----
- (((*mailbox == '{') || (*mailbox == '#')) &&
- (stream = mail_open (NIL,mailbox,OP_PROTOTYPE | OP_SILENT))))
- d = stream->dtb;
-+ else if(mailbox[0] == '#'
-+ && (mailbox[1] == 'm' || mailbox[1] == 'M')
-+ && (mailbox[2] == 'd' || mailbox[2] == 'D'
-+ || mailbox[2] == 'c' || mailbox[2] == 'C')
-+ && mailbox[3] == '/'
-+ && mailbox[4] != '\0')
-+ return (*md->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);
-***************
-*** 3352,3364 ****
- long flags)
- {
- STRINGLIST *hdrs;
-! int notfound;
- unsigned long i;
- char c,*s,*e,*t,tmp[MAILTMPLEN];
- char *src = text;
- char *dst = src;
- char *end = text + len;
-! text[len] = '\012'; /* guard against running off buffer */
- while (src < end) { /* process header */
- /* slurp header line name */
- for (s = src,e = s + MAILTMPLEN - 1,e = (e < end ? e : end),t = tmp;
---- 3377,3389 ----
- long flags)
- {
- STRINGLIST *hdrs;
-! int notfound, fix = text[len - 1] == '\0';
- unsigned long i;
- char c,*s,*e,*t,tmp[MAILTMPLEN];
- char *src = text;
- char *dst = src;
- char *end = text + len;
-! text[fix ? len - 1 : len] = '\012'; /* guard against running off buffer */
- while (src < end) { /* process header */
- /* slurp header line name */
- for (s = src,e = s + MAILTMPLEN - 1,e = (e < end ? e : end),t = tmp;
-***************
-*** 3397,3402 ****
---- 3422,3431 ----
- }
- }
- *dst = '\0'; /* tie off destination */
-+ if(fix){
-+ text[len] = '\012';
-+ text[len-1] = '\0';
-+ }
- return dst - text;
- }
-
-***************
-*** 5108,5114 ****
- unsigned long msgno)
- {
- if (msgno && ov) { /* just in case */
-! MESSAGECACHE telt;
- SORTCACHE *s = (SORTCACHE *) (*mailcache) (stream,msgno,CH_SORTCACHE);
- if (!s->subject && ov->subject) {
- s->refwd = mail_strip_subject (ov->subject,&s->subject);
---- 5137,5144 ----
- unsigned long msgno)
- {
- if (msgno && ov) { /* just in case */
-! MESSAGECACHE telt, *elt;
-! ENVELOPE *env;
- SORTCACHE *s = (SORTCACHE *) (*mailcache) (stream,msgno,CH_SORTCACHE);
- if (!s->subject && ov->subject) {
- s->refwd = mail_strip_subject (ov->subject,&s->subject);
-***************
-*** 5127,5133 ****
- s->dirty = T;
- }
- if (!s->references &&
-! !(s->references = mail_thread_parse_references (ov->references,T))) {
- /* don't do In-Reply-To with NNTP mailboxes */
- s->references = mail_newstringlist ();
- s->dirty = T;
---- 5157,5168 ----
- s->dirty = T;
- }
- if (!s->references &&
-! !(s->references = mail_thread_parse_references (ov->references,T))
-! && stream->dtb && !strcmp(stream->dtb->name, "imap")
-! && (elt = mail_elt (stream, msgno)) != NULL
-! && (env = elt->private.msg.env) != NULL
-! && env->in_reply_to
-! && !(s->references = mail_thread_parse_references(env->in_reply_to, NIL))) {
- /* don't do In-Reply-To with NNTP mailboxes */
- s->references = mail_newstringlist ();
- s->dirty = T;
-***************
-*** 6115,6120 ****
---- 6150,6164 ----
- return i;
- return 0;
- }
-+ /* Client side callback warning to delete wrong password
-+ *
-+ */
-+ void delete_password(NETMBX *mb, char *user)
-+ {
-+ deletepwd_t ep = mail_parameters(NULL, GET_ERASEPASSWORD, NULL);
-+ if (ep) (ep)(mb, user);
-+ }
-+
-
- /* Standard TCP/IP network driver */
-
-***************
-*** 6329,6331 ****
---- 6373,6450 ----
- {
- return (*stream->dtb->localhost) (stream->stream);
- }
-+
-+ /*
-+ *
-+ * 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 alpine-2.00/imap/src/c-client/mail.h alpine-2.00.I.USE/imap/src/c-client/mail.h
-*** alpine-2.00/imap/src/c-client/mail.h 2008-08-08 10:34:22.000000000 -0700
---- alpine-2.00.I.USE/imap/src/c-client/mail.h 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 177,182 ****
---- 177,186 ----
- #define SET_EXTERNALAUTHID (long) 230
- #define GET_SSLCAPATH (long) 231
- #define SET_SSLCAPATH (long) 232
-+ #define GET_ERASEPASSWORD (long) 233
-+ #define SET_ERASEPASSWORD (long) 234
-+ #define SET_PASSWORDFILE (long) 235
-+ #define GET_PASSWORDFILE (long) 236
-
- /* 3xx: TCP/IP */
- #define GET_OPENTIMEOUT (long) 300
-***************
-*** 353,358 ****
---- 357,366 ----
- #define SET_SCANCONTENTS (long) 573
- #define GET_MHALLOWINBOX (long) 574
- #define SET_MHALLOWINBOX (long) 575
-+ #define GET_COURIERSTYLE (long) 576
-+ #define SET_COURIERSTYLE (long) 577
-+ #define SET_MDINBOXPATH (long) 578
-+ #define GET_MDINBOXPATH (long) 579
-
- /* Driver flags */
-
-***************
-*** 685,690 ****
---- 693,699 ----
- /* 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 */
-***************
-*** 1302,1308 ****
- typedef void *(*mailcache_t) (MAILSTREAM *stream,unsigned long msgno,long op);
- typedef long (*mailproxycopy_t) (MAILSTREAM *stream,char *sequence,
- char *mailbox,long options);
-! typedef long (*tcptimeout_t) (long overall,long last);
- typedef void *(*authchallenge_t) (void *stream,unsigned long *len);
- typedef long (*authrespond_t) (void *stream,char *s,unsigned long size);
- typedef long (*authcheck_t) (void);
---- 1311,1317 ----
- typedef void *(*mailcache_t) (MAILSTREAM *stream,unsigned long msgno,long op);
- typedef long (*mailproxycopy_t) (MAILSTREAM *stream,char *sequence,
- char *mailbox,long options);
-! typedef long (*tcptimeout_t) (long overall,long last, char *host);
- typedef void *(*authchallenge_t) (void *stream,unsigned long *len);
- typedef long (*authrespond_t) (void *stream,char *s,unsigned long size);
- typedef long (*authcheck_t) (void);
-***************
-*** 1325,1330 ****
---- 1334,1340 ----
- typedef void *(*blocknotify_t) (int reason,void *data);
- typedef long (*kinit_t) (char *host,char *reason);
- typedef void (*sendcommand_t) (MAILSTREAM *stream,char *cmd,long flags);
-+ typedef void (*deletepwd_t) (NETMBX *mb,char *user);
- typedef char *(*newsrcquery_t) (MAILSTREAM *stream,char *mulname,char *name);
- typedef void (*getacl_t) (MAILSTREAM *stream,char *mailbox,ACLLIST *acl);
- typedef void (*listrights_t) (MAILSTREAM *stream,char *mailbox,char *id,
-***************
-*** 1604,1609 ****
---- 1614,1621 ----
- void mm_fatal (char *string);
- void *mm_cache (MAILSTREAM *stream,unsigned long msgno,long op);
-
-+ void delete_password (NETMBX *mb, char *user);
-+
- extern STRINGDRIVER mail_string;
- void mail_versioncheck (char *version);
- void mail_link (DRIVER *driver);
-diff -rc alpine-2.00/imap/src/c-client/nntp.c alpine-2.00.I.USE/imap/src/c-client/nntp.c
-*** alpine-2.00/imap/src/c-client/nntp.c 2008-06-04 11:18:34.000000000 -0700
---- alpine-2.00.I.USE/imap/src/c-client/nntp.c 2011-02-07 20:33:43.000000000 -0800
-***************
-*** 2031,2036 ****
---- 2031,2037 ----
- sprintf (tmp,"Retrying using %s authentication after %.80s",
- at->name,lsterr);
- mm_log (tmp,NIL);
-+ delete_password(mb, mb ? mb->user : NULL);
- fs_give ((void **) &lsterr);
- }
- trial = 0; /* initial trial count */
-***************
-*** 2039,2044 ****
---- 2040,2046 ----
- if (lsterr) {
- sprintf (tmp,"Retrying %s authentication after %.80s",at->name,lsterr);
- mm_log (tmp,WARN);
-+ delete_password(mb, mb ? mb->user : NULL);
- fs_give ((void **) &lsterr);
- }
- stream->saslcancel = NIL;
-***************
-*** 2064,2069 ****
---- 2066,2072 ----
- sprintf (tmp,"Can not authenticate to NNTP server: %.80s",lsterr);
- mm_log (tmp,ERROR);
- }
-+ delete_password(mb, mb ? mb->user : NULL);
- fs_give ((void **) &lsterr);
- }
- else if (mb->secflag) /* no SASL, can't do /secure */
-***************
-*** 2092,2097 ****
---- 2095,2102 ----
- stream->sensitive = T; /* hide this command */
- if (nntp_send_work (stream,"AUTHINFO PASS",pwd) == NNTPAUTHED)
- ret = LONGT; /* password OK */
-+ else
-+ delete_password(mb, mb ? mb->user : NULL);
- stream->sensitive = NIL; /* unhide */
- if (ret) break; /* OK if successful */
- default: /* authentication failed */
-diff -rc alpine-2.00/imap/src/c-client/pop3.c alpine-2.00.I.USE/imap/src/c-client/pop3.c
-*** alpine-2.00/imap/src/c-client/pop3.c 2008-06-04 11:18:34.000000000 -0700
---- alpine-2.00.I.USE/imap/src/c-client/pop3.c 2011-02-07 20:33:43.000000000 -0800
-***************
-*** 615,620 ****
---- 615,621 ----
- sprintf (pwd,"Retrying using %.80s authentication after %.80s",
- at->name,t);
- mm_log (pwd,NIL);
-+ delete_password(mb, usr);
- fs_give ((void **) &t);
- }
- trial = 0; /* initial trial count */
-***************
-*** 622,627 ****
---- 623,629 ----
- if (t) {
- sprintf (pwd,"Retrying %s authentication after %.80s",at->name,t);
- mm_log (pwd,WARN);
-+ delete_password(mb, usr);
- fs_give ((void **) &t);
- }
- LOCAL->saslcancel = NIL;
-***************
-*** 667,672 ****
---- 669,675 ----
- LOCAL->sensitive=NIL; /* unhide */
- }
- if (!ret) { /* failure */
-+ delete_password(mb, usr);
- mm_log (LOCAL->reply,WARN);
- if (trial == pop3_maxlogintrials)
- mm_log ("Too many login failures",ERROR);
-diff -rc alpine-2.00/imap/src/c-client/rfc822.c alpine-2.00.I.USE/imap/src/c-client/rfc822.c
-*** alpine-2.00/imap/src/c-client/rfc822.c 2008-06-04 11:46:10.000000000 -0700
---- alpine-2.00.I.USE/imap/src/c-client/rfc822.c 2011-02-07 20:33:43.000000000 -0800
-***************
-*** 128,133 ****
---- 128,134 ----
- 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 */
-***************
-*** 230,235 ****
---- 231,239 ----
- *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 alpine-2.00/imap/src/osdep/mac/tcp_mac.c alpine-2.00.I.USE/imap/src/osdep/mac/tcp_mac.c
-*** alpine-2.00/imap/src/osdep/mac/tcp_mac.c 2008-06-04 11:18:34.000000000 -0700
---- alpine-2.00.I.USE/imap/src/osdep/mac/tcp_mac.c 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 383,389 ****
- if (stream->pb.ioResult) { /* punt if got an error */
- time_t tc = time (0);
- if ((stream->pb.ioResult == commandTimeout) && tmoh &&
-! ((*tmoh) (tc - t,tc - tl))) continue;
- /* nuke connection */
- stream->pb.csCode = TCPAbort;
- abortpb->userDataPtr = NIL;
---- 383,389 ----
- if (stream->pb.ioResult) { /* punt if got an error */
- time_t tc = time (0);
- if ((stream->pb.ioResult == commandTimeout) && tmoh &&
-! ((*tmoh) (tc - t,tc - tl, stream->host))) continue;
- /* nuke connection */
- stream->pb.csCode = TCPAbort;
- abortpb->userDataPtr = NIL;
-diff -rc alpine-2.00/imap/src/osdep/nt/tcp_nt.c alpine-2.00.I.USE/imap/src/osdep/nt/tcp_nt.c
-*** alpine-2.00/imap/src/osdep/nt/tcp_nt.c 2008-06-04 11:18:34.000000000 -0700
---- alpine-2.00.I.USE/imap/src/osdep/nt/tcp_nt.c 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 430,436 ****
- SOCKET_ERROR) &&
- ((errno = WSAGetLastError ()) == WSAEINTR));
- else if (!i) { /* timeout, ignore if told to resume */
-! if (tmoh && (*tmoh) ((long) (now - t),(long) (now - tl))) continue;
- /* otherwise punt */
- if (tcpdebug) mm_log ("TCP buffer read timeout",TCPDEBUG);
- return tcp_abort (stream);
---- 430,438 ----
- SOCKET_ERROR) &&
- ((errno = WSAGetLastError ()) == WSAEINTR));
- else if (!i) { /* timeout, ignore if told to resume */
-! if (tmoh && (*tmoh) ((long) (now - t),(long) (now - tl),
-! stream->host))
-! continue;
- /* otherwise punt */
- if (tcpdebug) mm_log ("TCP buffer read timeout",TCPDEBUG);
- return tcp_abort (stream);
-***************
-*** 498,504 ****
- SOCKET_ERROR) &&
- ((errno = WSAGetLastError ()) == WSAEINTR));
- else if (!i) { /* timeout, ignore if told to resume */
-! if (tmoh && (*tmoh) ((long) (now - t),(long) (now - tl))) continue;
- /* otherwise punt */
- if (tcpdebug) mm_log ("TCP data read timeout",TCPDEBUG);
- return tcp_abort (stream);
---- 500,507 ----
- SOCKET_ERROR) &&
- ((errno = WSAGetLastError ()) == WSAEINTR));
- else if (!i) { /* timeout, ignore if told to resume */
-! if (tmoh && (*tmoh) ((long) (now - t),(long) (now - tl), stream->host))
-! continue;
- /* otherwise punt */
- if (tcpdebug) mm_log ("TCP data read timeout",TCPDEBUG);
- return tcp_abort (stream);
-***************
-*** 582,588 ****
- SOCKET_ERROR) &&
- ((errno = WSAGetLastError ()) == WSAEINTR));
- else if (!i) { /* timeout, ignore if told to resume */
-! if (tmoh && (*tmoh) ((long) (now - t),(long) (now - tl))) continue;
- /* otherwise punt */
- if (tcpdebug) mm_log ("TCP write timeout",TCPDEBUG);
- return tcp_abort (stream);
---- 585,592 ----
- SOCKET_ERROR) &&
- ((errno = WSAGetLastError ()) == WSAEINTR));
- else if (!i) { /* timeout, ignore if told to resume */
-! if (tmoh && (*tmoh) ((long) (now - t),(long) (now - tl), stream->host))
-! continue;
- /* otherwise punt */
- if (tcpdebug) mm_log ("TCP write timeout",TCPDEBUG);
- return tcp_abort (stream);
-diff -rc alpine-2.00/imap/src/osdep/unix/dummy.c alpine-2.00.I.USE/imap/src/osdep/unix/dummy.c
-*** alpine-2.00/imap/src/osdep/unix/dummy.c 2008-06-04 11:18:34.000000000 -0700
---- alpine-2.00.I.USE/imap/src/osdep/unix/dummy.c 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 106,118 ****
- * Accepts: mailbox name
- * Returns: our driver if name is valid, NIL otherwise
- */
-!
- DRIVER *dummy_valid (char *name)
- {
-! char *s,tmp[MAILTMPLEN];
- struct stat sbuf;
- /* must be valid local mailbox */
-! if (name && *name && (*name != '{') && (s = mailboxfile (tmp,name))) {
- /* indeterminate clearbox INBOX */
- if (!*s) return &dummydriver;
- else if (!stat (s,&sbuf)) switch (sbuf.st_mode & S_IFMT) {
---- 106,124 ----
- * Accepts: mailbox name
- * Returns: our driver if name is valid, NIL otherwise
- */
-! char * maildir_remove_root(char *);
- DRIVER *dummy_valid (char *name)
- {
-! char *s,tmp[MAILTMPLEN], *rname;
- struct stat sbuf;
-+
-+ if(strlen(name) > MAILTMPLEN)
-+ name[MAILTMPLEN] = '\0';
-+
-+ strcpy(tmp, name);
-+ rname = maildir_remove_root(tmp);
- /* must be valid local mailbox */
-! if (rname && *rname && (*rname != '{') && (s = mailboxfile (tmp,rname))) {
- /* indeterminate clearbox INBOX */
- if (!*s) return &dummydriver;
- else if (!stat (s,&sbuf)) switch (sbuf.st_mode & S_IFMT) {
-***************
-*** 121,128 ****
- return &dummydriver;
- }
- /* blackbox INBOX does not exist yet */
-! else if (!compare_cstring (name,"INBOX")) return &dummydriver;
- }
- return NIL;
- }
-
---- 127,135 ----
- return &dummydriver;
- }
- /* blackbox INBOX does not exist yet */
-! else if (!compare_cstring (rname,"INBOX")) return &dummydriver;
- }
-+ if(rname) fs_give((void **)&rname);
- return NIL;
- }
-
-***************
-*** 454,459 ****
---- 461,468 ----
- {
- 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);
-***************
-*** 519,524 ****
---- 528,541 ----
- {
- 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);
-***************
-*** 544,555 ****
- long dummy_rename (MAILSTREAM *stream,char *old,char *newname)
- {
- struct stat sbuf;
-! char c,*s,tmp[MAILTMPLEN],mbx[MAILTMPLEN],oldname[MAILTMPLEN];
- /* no trailing / allowed */
-! if (!dummy_file (oldname,old) || !(s = dummy_file (mbx,newname)) ||
- stat (oldname,&sbuf) || ((s = strrchr (s,'/')) && !s[1] &&
- ((sbuf.st_mode & S_IFMT) != S_IFDIR))) {
-! sprintf (mbx,"Can't rename %.80s to %.80s: invalid name",old,newname);
- MM_LOG (mbx,ERROR);
- return NIL;
- }
---- 561,583 ----
- long dummy_rename (MAILSTREAM *stream,char *old,char *newname)
- {
- struct stat sbuf;
-! char c,*s,tmp[MAILTMPLEN],mbx[MAILTMPLEN],oldname[MAILTMPLEN], *rold, *rnewname;
-!
-! if(strlen(old) > MAILTMPLEN)
-! old[MAILTMPLEN] = '\0';
-!
-! if(strlen(newname) > MAILTMPLEN)
-! newname[MAILTMPLEN] = '\0';
-!
-! strcpy(tmp, old);
-! rold = maildir_remove_root(tmp);
-! strcpy(tmp, newname);
-! rnewname = maildir_remove_root(tmp);
- /* no trailing / allowed */
-! if (!dummy_file (oldname,rold) || !(s = dummy_file (mbx,rnewname)) ||
- stat (oldname,&sbuf) || ((s = strrchr (s,'/')) && !s[1] &&
- ((sbuf.st_mode & S_IFMT) != S_IFDIR))) {
-! sprintf (mbx,"Can't rename %.80s to %.80s: invalid name",rold,rnewname);
- MM_LOG (mbx,ERROR);
- return NIL;
- }
-***************
-*** 565,578 ****
- }
- }
- /* rename of non-ex INBOX creates dest */
-! if (!compare_cstring (old,"INBOX") && stat (oldname,&sbuf))
- return dummy_create (NIL,mbx);
- if (rename (oldname,mbx)) {
-! sprintf (tmp,"Can't rename mailbox %.80s to %.80s: %.80s",old,newname,
- strerror (errno));
- MM_LOG (tmp,ERROR);
- return NIL;
- }
- return T; /* return success */
- }
-
---- 593,608 ----
- }
- }
- /* rename of non-ex INBOX creates dest */
-! if (!compare_cstring (rold,"INBOX") && stat (oldname,&sbuf))
- return dummy_create (NIL,mbx);
- if (rename (oldname,mbx)) {
-! sprintf (tmp,"Can't rename mailbox %.80s to %.80s: %.80s",rold,rnewname,
- strerror (errno));
- MM_LOG (tmp,ERROR);
- return NIL;
- }
-+ if(rold) fs_give((void **)&rold);
-+ if(rnewname) fs_give((void **)&rnewname);
- return T; /* return success */
- }
-
-diff -rc alpine-2.00/imap/src/osdep/unix/maildir.c alpine-2.00.I.USE/imap/src/osdep/unix/maildir.c
-*** alpine-2.00/imap/src/osdep/unix/maildir.c 2011-02-07 20:34:02.000000000 -0800
---- alpine-2.00.I.USE/imap/src/osdep/unix/maildir.c 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 0 ****
---- 1,2584 ----
-+ /*
-+ * Maildir driver for Alpine 2.00
-+ *
-+ * Written by Eduardo Chappa <chappa@washington.edu>
-+ * Last Update: November 6, 2010.
-+ *
-+ */
-+
-+ #include <stdio.h>
-+ #include <ctype.h>
-+ #include <errno.h>
-+ extern int errno; /* just in case */
-+ #include "mail.h"
-+ #include <pwd.h>
-+ #include <sys/stat.h>
-+ #include <sys/time.h>
-+ #include "osdep.h"
-+ #include "rfc822.h"
-+ #include "fdstring.h"
-+ #include "misc.h"
-+ #include "dummy.h"
-+ #include "maildir.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_DIRFMT,
-+ (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_DIRFMT,
-+ (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 */
-+
-+ long maildir_dirfmttest (char *name)
-+ {
-+ int i;
-+ for (i = 0; mdstruct[i] && strcmp(name, mdstruct[i]); i++);
-+ return (i < EndDir) || !strcmp(name, MDDIR)
-+ || !strncmp(name, MDUIDLAST, strlen(MDUIDLAST))
-+ || !strncmp(name, MDUIDTEMP, strlen(MDUIDTEMP)) ? LONGT : NIL;
-+ }
-+
-+ 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';
-+ }
-+
-+ char *
-+ myrootdir(char *name)
-+ {
-+ return myhomedir();
-+ }
-+
-+ char *
-+ mdirpath(void)
-+ {
-+ char *path = maildir_parameters(GET_MDINBOXPATH,NIL);
-+ return path ? (path[0] ? path : ".") : "Maildir";
-+ }
-+
-+ /* remove the "#md/" or "#mc/" part from a folder name */
-+ char *
-+ maildir_remove_root (char *name)
-+ {
-+ int courier = IS_COURIER(name), offset;
-+ char realname[MAILTMPLEN];
-+
-+ offset = maildir_valid_name(name) ? (name[3] == '/' ? 4 : 3) : 0;
-+ if(courier)
-+ courier_realname(name+offset, realname);
-+ else
-+ strcpy(realname, name+offset);
-+ return 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 = mdirpath(), *rname;
-+ 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 */
-+
-+ if(strlen(name) >= MAILTMPLEN)
-+ name[MAILTMPLEN] = '\0';
-+ strcpy(tmp, name);
-+ rname = maildir_remove_root(tmp);
-+ tmp[0] = '\0'; /* just in case something fails */
-+
-+ if (strlen(myrootdir(rname)) +
-+ max(strlen(rname), strlen(maildirpath)) > MAILTMPLEN){
-+ errno = ENAMETOOLONG;
-+ sprintf(tmp,"Error opening \"%s\": %s", rname, 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(*rname == '/') /* full path */
-+ strcpy(tmp, rname); /* do nothing */
-+ else{
-+ sprintf (tmp,"%s/%s%s%s", myrootdir (rname),
-+ strncmp (ucase (strcpy (tmp, rname)), "INBOX", 5)
-+ ? rname : maildirpath,
-+ strncmp (ucase (strcpy (tmp, rname)), "INBOX", 5)
-+ ? "" : (courier ? "/" : ""),
-+ strncmp (ucase (strcpy (tmp, rname)), "INBOX", 5)
-+ ? "" : (*(rname+5) == MDSEPARATOR(courier) ? rname+5 : ""));
-+ }
-+ if(rname) fs_give((void **)&rname);
-+ 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, myrootdir (*name), strlen(myrootdir(*name)))){
-+ (*name) += strlen(myrootdir(*name));
-+ 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;
-+ }
-+
-+ 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 = 1L; 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);
-+ }
-+ }
-+ }
-+
-+ int
-+ maildir_eliminate_duplicate (char *name, struct direct ***flist, unsigned long *nfiles)
-+ {
-+ int i, j, k, error = 0, scanr;
-+ char new[MAILTMPLEN], old[MAILTMPLEN], tmp[MAILTMPLEN], *str;
-+ struct direct **names = NIL;
-+
-+ if((scanr = maildir_doscandir(name, &names, CCLIENT)) < 0)
-+ return -1;
-+
-+ if(nfiles) *nfiles = scanr;
-+ for(i = 0, j = 1, k = 0; j < scanr; i++, j++){
-+ if(k)
-+ names[i] = names[i+k];
-+ if(same_maildir_file(names[i]->d_name, names[j]->d_name)){
-+ int d, f, r, s;
-+ maildir_getflag(names[i]->d_name, &d, &f, &r, &s, NIL);
-+ sprintf(old,"%s/%s", name, names[i]->d_name);
-+ sprintf(new,"%s/.%s", name, names[i]->d_name);
-+ if(rename(old, new) < 0 && errno != EEXIST)
-+ error++;
-+ if(!error){
-+ for(; j < scanr
-+ && same_maildir_file(names[i]->d_name, names[j]->d_name)
-+ ; j++, k++){
-+ maildir_getflag(names[j]->d_name, (d ? NIL : &d),
-+ (f ? NIL : &f), (r ? NIL : &r), (s ? NIL : &s), NIL);
-+ sprintf(tmp,"%s/%s", name, names[j]->d_name);
-+ if(unlink(tmp) < 0){ /* Hmmm... a problem, let's see */
-+ struct stat sbuf;
-+ if (stat(tmp, &sbuf) == 0 && (sbuf.st_mode & S_IFMT) == S_IFREG)
-+ error++;
-+ }
-+ }
-+ if((str = strrchr(names[i]->d_name,FLAGSEP)) != NULL) *str = '\0';
-+ sprintf (old,"%s/%s%s%s%s%s%s", name, names[i]->d_name, MDSEP(2),
-+ MDFLAG(Draft, d), MDFLAG(Flagged, f), MDFLAG(Replied, r),
-+ MDFLAG(Seen, s));
-+ if(rename(new, old) < 0)
-+ error++;
-+ }
-+ }
-+
-+ }
-+ if(k > 0)
-+ fs_give((void **)&names);
-+ else
-+ *flist = names;
-+ return error ? -1 : k;
-+ }
-+
-+ int
-+ maildir_doscandir(char *name, struct direct ***flist, int flag)
-+ {
-+ return scandir(name, flist,
-+ flag == CCLIENT ? maildir_select : courier_dir_select,
-+ flag == CCLIENT ? maildir_namesort : courier_dir_sort);
-+ }
-+
-+ /*
-+ * 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;
-+ int rv = -2; /* impossible value */
-+
-+ if (scand)
-+ *scand = -1; /* assume error for safety */
-+ *nfiles = 0;
-+ if((stat(name,&sbuf) < 0)
-+ || (flag == CCLIENT
-+ && ((rv = maildir_eliminate_duplicate(name, flist, nfiles)) < 0)))
-+ return 0L;
-+
-+ if (scand && (rv > 0 || rv == -2))
-+ *nfiles = maildir_doscandir(name, flist, flag);
-+
-+ if(scand) *scand = *nfiles;
-+
-+ return (unsigned long) 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 */
-+ if(mypid == (pid_t) 0)
-+ mypid = getpid();
-+ if (!stream->rdonly){
-+ stream->perm_seen = stream->perm_deleted = stream->perm_flagged =
-+ stream->perm_answered = stream->perm_draft = T;
-+ }
-+ 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);
-+ LOCAL->candouid = maildir_can_assign_uid(stream);
-+ maildir_read_uid(stream, &stream->uid_last, &stream->uid_validity);
-+ 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 = SENDBUFLEN) + 1);
-+ stream->sequence++;
-+ stream->nmsgs = stream->recent = 0L;
-+
-+ maildir_parse_folder(stream, 1);
-+
-+ return stream;
-+ }
-+
-+ /* Maildir initial parsing of the folder */
-+ void
-+ maildir_parse_folder (MAILSTREAM *stream, int full)
-+ {
-+ char tmp[MAILTMPLEN], tmp2[MAILTMPLEN];
-+ struct direct **namescur = NIL, **namesnew = NIL;
-+ unsigned long i, nfilescur = 0L, nfilesnew = 0L, oldpos, newpos, total;
-+ int scan_err, rescan, loop = 0;
-+
-+ if (!stream) /* what??? */
-+ return;
-+
-+ MM_CRITICAL(stream);
-+
-+ MDFLD(tmp, LOCAL->dir, New);
-+ maildir_scandir (tmp, &namesnew, &nfilesnew, &scan_err, CCLIENT);
-+ if (scan_err < 0)
-+ maildir_abort(stream);
-+
-+ /* Scan old messages first, escoba! */
-+ if(stream->rdonly ||
-+ (LOCAL && ((maildir_initial_check(stream, Cur) == 0)
-+ || nfilesnew > 0L))){
-+ MDFLD(tmp, LOCAL->dir, Cur);
-+ LOCAL->scantime = maildir_scandir (tmp, &namescur, &nfilescur,
-+ &scan_err, CCLIENT);
-+ if (scan_err < 0){
-+ if(namesnew){
-+ for(i = 0L; i < nfilesnew; i++)
-+ fs_give((void **)&namesnew[i]);
-+ fs_give((void **) &namesnew);
-+ }
-+ maildir_abort(stream);
-+ }
-+ }
-+ if(LOCAL && (maildir_initial_check(stream, New) == 0)
-+ && (nfilescur > 0L)){
-+ MDFLD(tmp, LOCAL->dir, New);
-+ while(LOCAL && loop < 10){
-+ if(nfilesnew == 0L)
-+ maildir_scandir (tmp, &namesnew, &nfilesnew, &scan_err, CCLIENT);
-+ if (scan_err < 0){
-+ if(namesnew){
-+ for(i = 0L; i < nfilesnew; i++)
-+ fs_give((void **)&namesnew[i]);
-+ fs_give((void **) &namesnew);
-+ }
-+ maildir_abort(stream);
-+ break;
-+ }
-+ for(i = 0L, rescan = 0, newpos = oldpos = 0L;
-+ newpos < nfilescur && i < nfilesnew; i++){
-+ if(maildir_message_in_list(namesnew[i]->d_name, namescur, oldpos,
-+ nfilescur - 1L, &newpos)){
-+ oldpos = newpos;
-+ sprintf(tmp2,"%s/%s",tmp,namesnew[i]->d_name);
-+ if(unlink(tmp2) < 0)
-+ scan_err = -1;
-+ rescan++;
-+ }
-+ else
-+ newpos = oldpos;
-+ }
-+ if(scan_err < 0)
-+ maildir_abort(stream);
-+ if(rescan == 0)
-+ break;
-+ else{ /* restart */
-+ if(namesnew){
-+ for(i = 0L; i < nfilesnew; i++)
-+ fs_give((void **)&namesnew[i]);
-+ fs_give((void **) &namesnew);
-+ }
-+ nfilesnew = 0L;
-+ loop++;
-+ }
-+ }
-+ }
-+ if(loop == 10)
-+ maildir_abort(stream);
-+ if(LOCAL){
-+ if(stream->rdonly)
-+ stream->recent = 0L;
-+ total = namescur || stream->rdonly
-+ ? maildir_parse_dir(stream, 0L, Cur, namescur,
-+ nfilescur, full) : stream->nmsgs;
-+ stream->nmsgs = maildir_parse_dir(stream, total, New, namesnew,
-+ nfilesnew, full);
-+ }
-+ if(namesnew){
-+ for(i = 0L; i < nfilesnew; i++)
-+ fs_give((void **)&namesnew[i]);
-+ fs_give((void **) &namesnew);
-+ }
-+ if(namescur){
-+ for(i = 0L; i < nfilescur; i++)
-+ fs_give((void **)&namescur[i]);
-+ fs_give((void **) &namescur);
-+ }
-+ MM_NOCRITICAL(stream);
-+ }
-+
-+ int
-+ maildir_initial_check (MAILSTREAM *stream, DirNamesType dirtype)
-+ {
-+ char tmp[MAILTMPLEN];
-+ struct stat sbuf;
-+
-+ MDFLD(tmp, LOCAL->dir, dirtype);
-+ if (access (tmp, R_OK|W_OK|X_OK) != 0){
-+ maildir_abort(stream);
-+ return -1;
-+ }
-+
-+ MDFLD(tmp, LOCAL->dir, Cur);
-+ if (dirtype != New &&
-+ (stat(tmp, &sbuf) < 0 || sbuf.st_ctime == LOCAL->scantime))
-+ return -1;
-+ return 0;
-+ }
-+
-+
-+ /* 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, struct direct **names,
-+ unsigned long nfiles, int full)
-+ {
-+ char tmp[MAILTMPLEN], tmp2[MAILTMPLEN], file[MAILTMPLEN],
-+ newfile[MAILTMPLEN], *mdstr;
-+ struct stat sbuf;
-+ unsigned long i, new = 0L, l, uid_last;
-+ unsigned long recent = stream ? stream->recent : 0L;
-+ int d = 0, f = 0, r = 0, s = 0, t = 0;
-+ int we_compute, in_list;
-+ int silent = stream ? stream->silent : NIL;
-+ MESSAGECACHE *elt;
-+
-+ MDFLD(tmp, LOCAL->dir, dirtype);
-+ if (dirtype == Cur && !stream->rdonly)
-+ for (i = 1L; i <= stream->nmsgs;){
-+ elt = mail_elt(stream, i);
-+ in_list = elt && elt->private.spare.ptr && 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->private.spare.ptr)
-+ maildir_free_file ((void **) &elt->private.spare.ptr);
-+
-+ if (elt->recent) --recent;
-+ mail_expunged(stream,i);
-+ }
-+ else i++;
-+ }
-+
-+ stream->silent = T;
-+ uid_last = 0L;
-+ for (we_compute = 0, i = l = 1L; l <= nfiles; l++){
-+ unsigned long pos, uid;
-+ if (dirtype == New && !stream->rdonly){ /* move new messages to cur */
-+ pos = l - 1L;
-+ sprintf (file,"%s/%s", tmp, names[pos]->d_name);
-+ if(lstat(file,&sbuf) == 0)
-+ switch(sbuf.st_mode & S_IFMT){
-+ case S_IFREG:
-+ strcpy(tmp2, names[pos]->d_name);
-+ if((mdstr = strstr(tmp2,MDSEP(3)))
-+ || (mdstr = strstr(tmp2,MDSEP(2))))
-+ *(mdstr+1) = '2';
-+ else
-+ strcat(tmp2, MDSEP(2));
-+ sprintf(newfile, "%s/%s",LOCAL->curdir, tmp2);
-+ if(rename (file, newfile) != 0){
-+ mm_log("Unable to read new mail!", WARN);
-+ continue;
-+ }
-+ unlink (file);
-+ new++;
-+ break;
-+ case S_IFLNK: /* clean up, clean up, everybody, everywhere */
-+ if(unlink(file) < 0){
-+ if(LOCAL->link == NIL){
-+ mm_log("Unable to remove symbolic link", WARN);
-+ LOCAL->link = T;
-+ }
-+ }
-+ continue;
-+ break;
-+ default:
-+ if(LOCAL && LOCAL->link == NIL){
-+ mm_log("Unrecognized file or link in folder", WARN);
-+ LOCAL->link = T;
-+ }
-+ continue;
-+ break;
-+ }
-+ }
-+ mail_exists(stream, i + nmsgs);
-+ elt = mail_elt(stream, i + nmsgs);
-+ pos = (elt && elt->private.spare.ptr) ? MDPOS(elt) : l - 1L;
-+ if (dirtype == New) elt->recent = T;
-+ maildir_getflag(names[pos]->d_name, &d, &f, &r ,&s, &t);
-+ if (elt->private.spare.ptr)
-+ maildir_free_file_only ((void **)&elt->private.spare.ptr);
-+ else{
-+ maildir_get_file((MAILDIRFILE **)&elt->private.spare.ptr);
-+ we_compute++;
-+ }
-+ MDFILE(elt) = cpystr(names[pos]->d_name);
-+ MDPOS(elt) = pos;
-+ MDLOC(elt) = dirtype;
-+ if (dirtype == Cur){ /* deal with UIDs */
-+ if(elt->private.uid == 0L)
-+ elt->private.uid = maildir_get_uid(MDFILE(elt));
-+ if(elt->private.uid <= uid_last){
-+ uid = (we_compute ? uid_last : stream->uid_last) + 1L;
-+ if(LOCAL->candouid)
-+ maildir_assign_uid(stream, i + nmsgs, uid);
-+ else
-+ elt->private.uid = uid;
-+ }
-+ else
-+ uid = elt->private.uid;
-+ uid_last = uid;
-+ if(uid_last > stream->uid_last)
-+ stream->uid_last = uid_last;
-+ }
-+ if(dirtype == New && !stream->rdonly){
-+ maildir_free_file_only((void **)&elt->private.spare.ptr);
-+ MDFILE(elt) = cpystr(tmp2);
-+ MDSIZE(elt) = sbuf.st_size;
-+ MDMTIME(elt) = sbuf.st_mtime;
-+ MDLOC(elt) = Cur;
-+ }
-+ 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);
-+ elt->valid = T;
-+ i++;
-+ }
-+ stream->silent = silent;
-+ if(LOCAL->candouid && dirtype == Cur)
-+ maildir_read_uid(stream, NULL, &stream->uid_validity);
-+ if (dirtype == New && stream->rdonly)
-+ new = nfiles;
-+ mail_exists(stream, nmsgs + ((dirtype == New) ? new : nfiles));
-+ mail_recent(stream, recent + ((dirtype == New) ? new : 0L));
-+
-+ return (nmsgs + (dirtype == New ? new : nfiles));
-+ }
-+
-+ long maildir_ping (MAILSTREAM *stream)
-+ {
-+ maildir_parse_folder(stream, 0);
-+ if(stream && LOCAL){
-+ if(LOCAL->candouid)
-+ maildir_uid_renew_tempfile(stream);
-+ else /* try again to get uids */
-+ LOCAL->candouid = maildir_can_assign_uid(stream);
-+ }
-+ return stream && LOCAL ? LONGT : NIL;
-+ }
-+
-+ int maildir_select (const struct direct *name)
-+ {
-+ return (name->d_name[0] != '.');
-+ }
-+
-+ /*
-+ * 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 = *(const struct direct **) d1;
-+ const struct direct *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 = 1L; i <= stream->nmsgs; i++)
-+ if((elt = (MESSAGECACHE *) (*mc)(stream,i,CH_ELT)) && elt->private.spare.ptr)
-+ maildir_free_file ((void **) &elt->private.spare.ptr);
-+ stream->silent = T;
-+ if (options & CL_EXPUNGE) maildir_expunge (stream, NIL, NIL);
-+ maildir_abort(stream);
-+ if (mdfpath) fs_give((void **)&mdfpath);
-+ if (mypid) mypid = (pid_t) 0;
-+ 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);
-+
-+ if (!(flags & FT_PEEK) && !elt->seen){
-+ elt->seen = T;
-+ maildir_flagmsg (stream, elt);
-+ MM_FLAGS(stream, elt->msgno);
-+ }
-+
-+ MSGPATH(tmp, LOCAL->dir, MDFILE(elt), MDLOC(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;
-+ }
-+
-+ s = maildir_text_work(stream, elt, &i, flags);
-+ INIT (bs, mail_string, s, i);
-+ return LONGT;
-+ }
-+
-+ char *maildir_text_work (MAILSTREAM *stream,MESSAGECACHE *elt,
-+ unsigned long *length,long flags)
-+ {
-+ FDDATA d;
-+ STRING bs;
-+ char *s,tmp[CHUNK];
-+ unsigned long msgno = elt->msgno;
-+ static int try = 0;
-+
-+ if (length)
-+ *length = 0L;
-+ LOCAL->buf[0] = '\0';
-+
-+ MSGPATH(tmp, LOCAL->dir, MDFILE(elt), MDLOC(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, *t, c;
-+ char tmp[MAILTMPLEN];
-+ struct stat sbuf;
-+ unsigned long i, len;
-+ int 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);
-+ 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';
-+ t = s + strlen(s); /* make t point to the end of s */
-+ for (i = 0L, b = s; b < t && !(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 = 0L, b = s, c = *b; b &&
-+ ((c < '\016' && ((c == '\012' && ++i)
-+ ||(c == '\015' && *(b+1) == '\012' && ++b && (i +=2))))
-+ || b < t); 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->private.spare.ptr);
-+ 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, MDLOC(elt));
-+
-+ MSGPATH(tmp, LOCAL->dir, MDFILE(elt), MDLOC(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){
-+ if(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);
-+ }
-+ read (LOCAL->fd, (void *)LOCAL->buf, elt->private.msg.header.text.size);
-+ LOCAL->buf[*length = elt->private.msg.header.text.size] = '\0';
-+ }
-+ else{
-+ s = (char *) fs_get(elt->private.msg.header.text.size+1);
-+ read (LOCAL->fd, (void *)s, elt->private.msg.header.text.size);
-+ s[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;
-+ 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 = 0L;
-+
-+ if((!pat || !*pat) && maildir_canonicalize (test,ref,"*")
-+ && maildir_valid_name(test)){ /* there is a #md/ leading here */
-+ for (i = 3L; test[i] && test[i] != '/'; i++);
-+ if ((s = strchr (test+i+1,'/')) != NULL) *++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,"%*")) != NULL){
-+ /* 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, '/')) != NULL){
-+ *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_MDINBOXPATH:
-+ if(strlen((char *) value ) > 49)
-+ strcpy(myMdInboxDir, "Maildir");
-+ else
-+ strcpy(myMdInboxDir, (char *) value);
-+ case GET_MDINBOXPATH:
-+ if (myMdInboxDir[0] == '\0') strcpy(myMdInboxDir,"Maildir");
-+ ret = (void *) myMdInboxDir;
-+ break;
-+ case SET_COURIERSTYLE:
-+ CourierStyle = (long) value;
-+ case GET_COURIERSTYLE:
-+ ret = (void *) CourierStyle;
-+ break;
-+ case GET_DIRFMTTEST:
-+ ret = (void *) maildir_dirfmttest;
-+ 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, 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))) != NULL){
-+ 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];
-+ int rv, 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 ? LONGT : NIL;
-+ }
-+
-+ #define MAXTRY 10000
-+ void maildir_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt)
-+ {
-+ char oldfile[MAILTMPLEN],newfile[MAILTMPLEN],fn[MAILTMPLEN];
-+ char *s;
-+ int ren, try = 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 = strrchr (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);
-+ return;
-+ }
-+ #ifdef __CYGWIN__
-+ utime(LOCAL->curdir, NIL); /* make sure next scan will catch the change */
-+ #endif
-+ maildir_free_file_only ((void **) &elt->private.spare.ptr);
-+ MDFILE(elt) = cpystr (fn);
-+ }
-+ }
-+
-+ long maildir_expunge (MAILSTREAM *stream, char *sequence, long options)
-+ {
-+ long ret;
-+ MESSAGECACHE *elt;
-+ unsigned long i, n = 0L;
-+ unsigned long recent = stream->recent;
-+ char tmp[MAILTMPLEN];
-+
-+ mm_critical (stream); /* go critical */
-+ ret = sequence ? ((options & EX_UID) ?
-+ mail_uid_sequence (stream,sequence) :
-+ mail_sequence (stream,sequence)) : LONGT;
-+ if(ret == 0L)
-+ return 0L;
-+ for (i = 1L; i <= stream->nmsgs;){
-+ elt = mail_elt (stream,i);
-+ if (elt->deleted && (sequence ? elt->sequence : T)){
-+ sprintf (tmp,"%s/%s",LOCAL->curdir, MDFILE(elt));
-+ if (unlink (tmp) < 0) {/* 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;
-+ }
-+ if (elt->private.spare.ptr)
-+ maildir_free_file ((void **) &elt->private.spare.ptr);
-+ 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);
-+ return ret;
-+ }
-+
-+ long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options)
-+ {
-+ STRING st;
-+ MESSAGECACHE *elt;
-+ unsigned long len;
-+ int fd;
-+ unsigned long i;
-+ struct stat sbuf;
-+ char tmp[MAILTMPLEN], flags[MAILTMPLEN], path[MAILTMPLEN], *s;
-+ /* copy the messages */
-+ if ((options & CP_UID) ? mail_uid_sequence (stream, sequence) :
-+ mail_sequence (stream,sequence))
-+ for (i = 1L; i <= stream->nmsgs; i++)
-+ if ((elt = mail_elt (stream,i))->sequence){
-+ MSGPATH(path, LOCAL->dir, MDFILE(elt), MDLOC(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 LONGT; /* return success */
-+ }
-+
-+ long maildir_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data)
-+ {
-+ int fd, k;
-+ STRING *message;
-+ char c,*s, *flags, *date;
-+ char tmp[MAILTMPLEN],file[MAILTMPLEN],path1[MAILTMPLEN],path2[MAILTMPLEN];
-+ MESSAGECACHE elt;
-+ long i, size = 0L, ret = LONGT, f;
-+ unsigned long uf, ti;
-+ 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 (mypid == (pid_t) 0)
-+ mypid = getpid();
-+
-+ if (!stream){
-+ stream = &maildirproto;
-+
-+ for (k = 0; k < NUSERFLAGS && stream->user_flags[k]; ++k)
-+ fs_give ((void **) &stream->user_flags[k]);
-+ }
-+
-+ if (!(*af) (stream,data,&flags,&date,&message)) return NIL;
-+
-+ mm_critical (stream); /* go critical */
-+ /* call time(0) only once, use transact to distinguish instead */
-+ ti = time(0);
-+ 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,"%lu.%d_%09u.%s%s%s%s%s%s",
-+ ti, mypid, 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 (rename (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;
-+ 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 LONGT;
-+ }
-+ /* 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)) != NULL){
-+ 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)) != NULL){
-+ if (strcmp(d->d_name, ".") && strcmp(d->d_name,"..")
-+ && (!strcmp(d->d_name, MDDIR)
-+ || !strncmp(d->d_name, MDUIDLAST, strlen(MDUIDLAST))
-+ || !strncmp(d->d_name, MDUIDTEMP, strlen(MDUIDTEMP)))){
-+ if(strcmp(d->d_name, MDDIR) == 0)
-+ mddir++;
-+ sprintf(tmp,"%s/%s", realname, d->d_name);
-+ 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 LONGT;
-+ }
-+
-+ long maildir_rename (MAILSTREAM *stream, char *old, char *new)
-+ {
-+ char tmp[MAILTMPLEN],tmpnew[MAILTMPLEN], realold[MAILTMPLEN];
-+ char realnew[MAILTMPLEN];
-+ int courier = IS_COURIER(old) && IS_COURIER(new);
-+ int i;
-+ long rv = LONGT;
-+ 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 LONGT; /* 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)) != NULL); /* 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) ? LONGT : NIL;
-+ }
-+
-+ void maildir_list_work (MAILSTREAM *stream,char *dir,char *pat,long level)
-+ {
-+ DIR *dp;
-+ struct direct *d;
-+ struct stat sbuf;
-+ char curdir[MAILTMPLEN],name[MAILTMPLEN], tmp[MAILTMPLEN];
-+ char realpat[MAILTMPLEN];
-+ long i;
-+ char *maildirpath = mdirpath();
-+
-+ sprintf(curdir,"%s/%s/", myrootdir(pat), dir ? dir : maildirpath);
-+ if ((dp = opendir (curdir)) != NULL){
-+ if (dir) sprintf (name,"%s%s/",MDPREFIX(CCLIENT),dir);
-+ else strcpy (name, pat);
-+
-+ if (level == 0 && !strpbrk(pat,"%*")){
-+ if(maildir_valid(pat)){
-+ i = maildir_contains_folder(pat, NULL)
-+ ? LATT_HASCHILDREN
-+ : (maildir_is_dir(pat, NULL)
-+ ? LATT_HASNOCHILDREN : LATT_NOINFERIORS);
-+ maildir_file_path(pat, realpat);
-+ i += maildir_any_new_msgs(realpat)
-+ ? LATT_MARKED : LATT_UNMARKED;
-+ mm_list (stream,'/', pat, i);
-+ }
-+ else
-+ if(pat[strlen(pat) - 1] == '/')
-+ mm_list (stream,'/', pat, LATT_NOSELECT);
-+ }
-+
-+ while ((d = readdir (dp)) != NULL)
-+ 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", myrootdir(d->d_name),
-+ (dir ? dir : maildirpath), 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)
-+ {
-+ char c, curdir[MAILTMPLEN], tmp[MAILTMPLEN];
-+ char realname[MAILTMPLEN], realpat[MAILTMPLEN] = {'\0'};
-+ int i, found;
-+ long style = (long) maildir_parameters(GET_COURIERSTYLE, NIL), j;
-+ char *maildirpath = mdirpath();
-+ COURIER_S *cdir;
-+
-+ if(!strpbrk(pat,"%*")){ /* a mailbox */
-+ maildir_file_path(pat, curdir);
-+ i = strlen(curdir) - 1;
-+ if(curdir[i] == '/')
-+ curdir[i] = '\0';
-+ cdir = courier_list_dir(curdir);
-+ if(cdir){
-+ found = 0; j = 0L;
-+ if(maildir_valid_name(pat)){
-+ for(i = 0; !found && i < cdir->total; i++)
-+ if(strstr(curdir, cdir->data[i]->name)){
-+ if(strlen(curdir) < strlen(cdir->data[i]->name))
-+ found += 2;
-+ else if(strlen(curdir) == strlen(cdir->data[i]->name))
-+ found -= 1;
-+ }
-+ if(found > 0)
-+ j = LATT_HASCHILDREN;
-+ else if(found == 0)
-+ j = (style == COURIER) ? LATT_HASNOCHILDREN : LATT_NOINFERIORS;
-+ }
-+ else
-+ j = LATT_NOSELECT;
-+ j += maildir_any_new_msgs(curdir) ? LATT_MARKED : LATT_UNMARKED;
-+ if (found)
-+ mm_list (stream, '.', pat, j);
-+ courier_free_cdir(&cdir);
-+ }
-+ return;
-+ }
-+
-+ strcpy(tmp,pat + 4); /* a directory */
-+ 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 ? "" : myrootdir(pat)), (dir ? "" : "/"),
-+ (dir ? realname : maildirpath), (dir ? "" : "."));
-+ sprintf(tmp, "%s%s/.", MDPREFIX(COURIER), dir ? dir : maildirpath);
-+ 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);
-+ courier_list_info(&cdir, tmp, i);
-+ 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 = strrchr(tmp1, FLAGSEP)) != NULL)
-+ *s = '\0';
-+ if (((s = strrchr(tmp1, SIZESEP)) != NULL) && (strchr(s,'.') == NULL))
-+ *s = '\0';
-+ if ((s = strrchr(tmp2, FLAGSEP)) != NULL)
-+ *s = '\0';
-+ if (((s = strrchr(tmp2, SIZESEP)) != NULL) && (strchr(s,'.') == NULL))
-+ *s = '\0';
-+
-+ return !strcmp(tmp1, tmp2);
-+ }
-+
-+ unsigned long antoul(char *seed)
-+ {
-+ int i, error = 0;
-+ unsigned long val = 0L, rv1 = 0L, t;
-+ char c, *p;
-+ if(!seed)
-+ return 0L;
-+ t = strtoul(seed, &p, 10);
-+ if(p && (*p == '.' || *p == '_'))
-+ return t;
-+ /* else */
-+ if((p = strchr(seed,'.')) != NULL)
-+ *p = '\0';
-+ error = (strlen(seed) > 6); /* too long */
-+ for(i= strlen(seed)-1; error == 0 && i >= 0; i--){
-+ c = seed[i];
-+ if (c >= 'A' && c <= 'Z') val = c - 'A';
-+ else if (c >= 'a' && c <= 'z') val = c - 'a' + 26;
-+ else if (c >= '0' && c <= '9') val = c - '0' + 26 + 26;
-+ else if (c == '-') val = c - '-' + 26 + 26 + 10;
-+ else if (c == '_') val = c - '_' + 26 + 26 + 10 + 1;
-+ else error++;
-+ rv1 = val + (rv1 << 6);
-+ }
-+ if(p)
-+ *p = '.';
-+ return error ? 0L : rv1;
-+ }
-+
-+ unsigned long mdfntoul (char *name)
-+ {
-+ unsigned long t;
-+ char *r, last;
-+
-+ if((*name == '_') && ((r = strpbrk(name,".,%+")) != NULL)){ /* Grrr!!! */
-+ last = *r;
-+ *r = '\0';
-+ t = antoul(r+1);
-+ *r = last;
-+ }
-+ else
-+ t = antoul(name);
-+ return t;
-+ }
-+
-+ int comp_maildir_file(char *name1, char *name2)
-+ {
-+ int uset1 = 1, uset2 = 1, i, j, cmp;
-+ unsigned long t1, t2;
-+ char *s1, *s2;
-+
-+ if (!(name1 && *name1))
-+ return (name2 && *name2) ? (*name2 == FLAGSEP ? 0 : -1) : 0;
-+
-+ if (!(name2 && *name2))
-+ return (name1 && *name1) ? (*name1 == FLAGSEP ? 0 : 1) : 0;
-+
-+ if((cmp = strcmp(name1,name2)) == 0)
-+ return 0;
-+
-+ t1 = strtoul(name1, &s1, 10);
-+ t2 = strtoul(name2, &s2, 10);
-+
-+ if(!s1 || *s1 != '.')
-+ uset1 = 0;
-+
-+ if(!s2 || *s2 != '.')
-+ uset2 = 0;
-+
-+ if(uset1 && uset2) /* normal sort order */
-+ return (t1 < t2) ? -1 : (t1 > t2 ? 1 : (cmp < 0 ? -1 : 1));
-+
-+ /* If we make it here we say Grrrr.... first, then we try to figure out
-+ * how to sort this mess.
-+ * These are the rules.
-+ * If there is a number at the beginning it is bigger than anything else.
-+ * If there are digits, then the number of digits decides which one is bigger.
-+ */
-+
-+ for(i = 0; isdigit(name1[i]); i++);
-+ for(j = 0; isdigit(name2[j]); j++);
-+
-+ return(uset1 ? 1
-+ : (uset2 ? -1
-+ : (i < j ? -1 : (i > j ? 1 : (cmp < 0 ? -1 : 1)))));
-+ }
-+
-+ void
-+ maildir_getflag(char *name, int *d, int *f, int *r ,int *s, int *t)
-+ {
-+ char tmp[MAILTMPLEN], *b;
-+ int offset = 0;
-+ int tmpd, tmpf, tmpr, tmps, tmpt;
-+
-+ if(d) *d = 0;
-+ if(f) *f = 0;
-+ if(r) *r = 0;
-+ if(s) *s = 0;
-+ if(t) *t = 0;
-+
-+ tmpd = tmpf = tmpr = tmps = tmpt = NIL; /* no flags set by default */
-+ strcpy(tmp,name);
-+ while ((b = strrchr(tmp+offset, FLAGSEP)) != NULL){
-+ char flag,last;
-+ int 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'){
-+ tmpd = strchr (b, MDFLAGC(Draft)) ? T : NIL;
-+ tmpf = strchr (b, MDFLAGC(Flagged)) ? T : NIL;
-+ tmpr = strchr (b, MDFLAGC(Replied)) ? T : NIL;
-+ tmps = strchr (b, MDFLAGC(Seen)) ? T : NIL;
-+ tmpt = 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 */
-+ }
-+ }
-+ if(d) *d = tmpd;
-+ if(f) *f = tmpf;
-+ if(r) *r = tmpr;
-+ if(s) *s = tmps;
-+ if(t) *t = tmpt;
-+ }
-+
-+ 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->candouid)
-+ maildir_read_uid(stream, NULL, &stream->uid_validity);
-+ if (LOCAL->dir) fs_give ((void **) &LOCAL->dir);
-+ if (LOCAL->curdir) fs_give ((void **) &LOCAL->curdir);
-+ if (LOCAL->buf) fs_give ((void **) &LOCAL->buf);
-+ if(LOCAL->uidtempfile){
-+ unlink(LOCAL->uidtempfile);
-+ fs_give ((void **) &LOCAL->uidtempfile);
-+ }
-+ 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;
-+
-+ maildir_file_path(dirname, tmp2);
-+ if(name){
-+ strcat(tmp2,"/");
-+ strcat(tmp2, name);
-+ }
-+
-+ if (!(dir = opendir (tmp2)))
-+ return NIL;
-+
-+ while ((d = readdir(dir)) != NULL){
-+ 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;
-+
-+ maildir_file_path(dirname, tmp);
-+ if(name){
-+ strcat(tmp,"/");
-+ strcat(tmp,name);
-+ }
-+ strcat(tmp,"/");
-+ strcat(tmp,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], tmp3[MAILTMPLEN],*s;
-+ int rv = 1, courier = IS_COURIER(mailbox);
-+ DIR *dir;
-+ struct direct *d;
-+ struct stat sbuf;
-+
-+ maildir_file_path(mailbox, tmp2);
-+
-+ if(courier){
-+ strcpy(tmp3, tmp2);
-+ if(s = strrchr(tmp2, '/'))
-+ *s = '\0';
-+ }
-+
-+ if (!(dir = opendir (tmp2)))
-+ return rv;
-+
-+ if(courier){
-+ while((d = readdir(dir)) != NULL){
-+ sprintf(tmp,"%s/%s", tmp2, d->d_name);
-+ if(!strncmp(tmp, tmp3, strlen(tmp3))
-+ && tmp[strlen(tmp3)] == '.'){
-+ rv = 0;
-+ break;
-+ }
-+ }
-+ }
-+ else
-+ while ((d = readdir(dir)) != NULL){
-+ 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;
-+
-+ MDFLD(tmp, mailbox, New);
-+
-+ if (!(dir = opendir (tmp)))
-+ return rv;
-+
-+ while ((d = readdir(dir)) != NULL){
-+ if (d->d_name[0] == '.')
-+ continue;
-+ rv = T;
-+ break;
-+ }
-+ closedir(dir);
-+ return rv;
-+ }
-+
-+
-+ void
-+ maildir_get_date(MAILSTREAM *stream, unsigned long msgno)
-+ {
-+ MESSAGECACHE *elt;
-+ struct tm *t;
-+ time_t ti;
-+ int i,k;
-+
-+ elt = mail_elt (stream,msgno);
-+ if(elt && elt->year != 0)
-+ return;
-+ if ((ti = mdfntoul(MDFILE(elt))) > 0L && (t = gmtime(&ti))){
-+ i = t->tm_hour * 60 + t->tm_min;
-+ k = t->tm_yday;
-+ t = localtime(&ti);
-+ i = t->tm_hour * 60 + t->tm_min - i;
-+ if((k = t->tm_yday - k) != 0)
-+ i += ((k < 0) == (abs (k) == 1)) ? -24*60 : 24*60;
-+ k = abs (i);
-+ elt->hours = t->tm_hour;
-+ elt->minutes = t->tm_min;
-+ elt->seconds = t->tm_sec;
-+ elt->day = t->tm_mday; elt->month = t->tm_mon + 1;
-+ elt->year = t->tm_year - (BASEYEAR - 1900);
-+ elt->zoccident = (k == i) ? 0 : 1;
-+ elt->zhours = k/60;
-+ elt->zminutes = k % 60;
-+ }
-+ }
-+
-+ /* 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 (const 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 = *(const struct direct **) d1;
-+ const struct direct *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 *));
-+ memset(cdir->data, 0, 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 = NULL;
-+ char tmp[MAILTMPLEN], tmp2[MAILTMPLEN], pathname[MAILTMPLEN],
-+ realname[MAILTMPLEN];
-+ int i, j, scand, td;
-+
-+ /* 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++){
-+ td = realname[strlen(realname) - 1] == '.'
-+ && *names[i]->d_name == '.';
-+ sprintf(tmp2,"%s%s", tmp, names[i]->d_name+1);
-+ sprintf(pathname,"%s%s", realname, names[i]->d_name + td);
-+ 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]);
-+ }
-+ cdir->total = j;
-+ if(cdir->total == 0)
-+ courier_free_cdir(&cdir);
-+ }
-+ if(names)
-+ fs_give((void **) &names);
-+ return cdir;
-+ }
-+
-+ void
-+ courier_list_info(COURIER_S **cdirp, char *data, int i)
-+ {
-+ long style = (long) maildir_parameters(GET_COURIERSTYLE, NIL);
-+ COURIER_S *cdir = *cdirp;
-+
-+ if(maildir_valid(cdir->data[i]->name)){
-+ if(courier_search_list(cdir->data, data, 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;
-+ }
-+
-+ /* UID Support */
-+ /* Yes, I know I procastinated a lot about this, but here it is finally */
-+
-+ unsigned int
-+ maildir_can_assign_uid (MAILSTREAM *stream)
-+ {
-+ unsigned int rv = 0;
-+ int createtemp;
-+ unsigned long t;
-+ char tmp[MAILTMPLEN], *s;
-+ DIR *dir;
-+ struct direct *d;
-+
-+ if(!stream || stream->rdonly
-+ || !LOCAL || !LOCAL->dir || !(dir = opendir(LOCAL->dir)))
-+ return rv;
-+
-+ sprintf(tmp, "%s.%d", MDUIDTEMP, mypid);
-+ while ((d = readdir(dir)) != NULL){
-+ if(!strncmp(d->d_name, tmp, strlen(tmp))
-+ || !strncmp(d->d_name, MDUIDTEMP, strlen(MDUIDTEMP)))
-+ break;
-+ }
-+ rv = d ? !strncmp(d->d_name, tmp, strlen(tmp)) : 1;
-+ createtemp = d ? 0 : 1;
-+ if (d && rv == 0){ /* is there a temp file that is not ours? */
-+ s = strrchr(d->d_name, '.');
-+ t = strtoul(s+1, &s, 10);
-+ if(s != NULL && *s != '\0')
-+ createtemp++;
-+ if(time(0) > t + MAXTEMPUID){
-+ createtemp++;
-+ sprintf(tmp,"%s/%s", LOCAL->dir, d->d_name);
-+ unlink(tmp);
-+ }
-+ }
-+ closedir(dir);
-+ if(createtemp){
-+ FILE *fp;
-+ sprintf(tmp,"%s/%s.%d.%lu", LOCAL->dir, MDUIDTEMP, mypid, time(0));
-+ if(fp = fopen(tmp, "w")){
-+ fclose(fp);
-+ if(LOCAL->uidtempfile)
-+ fs_give((void **)&LOCAL->uidtempfile);
-+ LOCAL->uidtempfile = cpystr(tmp);
-+ rv++;
-+ }
-+ }
-+ return rv;
-+ }
-+
-+ void
-+ maildir_read_uid(MAILSTREAM *stream, unsigned long *uid_last,
-+ unsigned long *uid_validity)
-+ {
-+ int createuid, deleteuid = 0;
-+ char tmp[MAILTMPLEN], *s = NULL;
-+ DIR *dir;
-+ struct direct *d;
-+
-+ if(uid_last) *uid_last = 0L;
-+ if(uid_last && uid_validity) *uid_validity = time(0);
-+ if(!stream || !LOCAL || !LOCAL->dir || !(dir = opendir(LOCAL->dir)))
-+ return;
-+
-+ while ((d = readdir(dir)) != NULL){
-+ if(!strncmp(d->d_name, MDUIDLAST, strlen(MDUIDLAST)))
-+ break;
-+ }
-+ createuid = d == NULL ? 1 : 0;
-+ if(uid_last == NULL)
-+ deleteuid++;
-+ if(d){
-+ if(uid_last){
-+ s = d->d_name + strlen(MDUIDLAST) + 1;
-+ *uid_last = strtoul(s, &s, 10);
-+ if(!s || *s != '.'){
-+ deleteuid++;
-+ createuid++;
-+ *uid_last = 0L;
-+ }
-+ }
-+ if(s && *s == '.'){
-+ if(uid_validity){
-+ s++;
-+ *uid_validity = strtoul(s, &s, 10);
-+ if(s && *s != '\0'){
-+ *uid_validity = time(0);
-+ deleteuid++;
-+ createuid++;
-+ }
-+ }
-+ }
-+ else{
-+ deleteuid++;
-+ createuid++;
-+ }
-+ }
-+ if(deleteuid){
-+ sprintf(tmp,"%s/%s", LOCAL->dir, d->d_name);
-+ unlink(tmp);
-+ }
-+ if(createuid)
-+ maildir_write_uid(stream, (uid_last ? *uid_last : stream->uid_last),
-+ uid_validity ? *uid_validity : time(0));
-+ closedir(dir);
-+ }
-+
-+ void
-+ maildir_write_uid(MAILSTREAM *stream, unsigned long uid_last,
-+ unsigned long uid_validity)
-+ {
-+ char tmp[MAILTMPLEN];
-+ FILE *fp;
-+
-+ if(!stream || stream->rdonly || !LOCAL || !LOCAL->dir)
-+ return;
-+
-+ sprintf(tmp,"%s/%s.%010lu.%010lu", LOCAL->dir, MDUIDLAST,
-+ uid_last, uid_validity);
-+ if(fp = fopen(tmp, "w"))
-+ fclose(fp);
-+ }
-+
-+ unsigned long
-+ maildir_get_uid(char *name)
-+ {
-+ char *s;
-+ unsigned long rv = 0L;
-+
-+ if(!name || (s = strstr(name,MDUIDSEP)) == NULL)
-+ return rv;
-+
-+ s += strlen(MDUIDSEP);
-+ rv = strtoul(s, NULL, 10);
-+ return rv;
-+ }
-+
-+
-+ void
-+ maildir_delete_uid(MAILSTREAM *stream, unsigned long msgno)
-+ {
-+ char old[MAILTMPLEN], new[MAILTMPLEN], *s, *t;
-+ MESSAGECACHE *elt;
-+
-+ elt = mail_elt(stream, msgno);
-+ if(!stream || !elt || !elt->private.spare.ptr || !LOCAL || !LOCAL->dir)
-+ return;
-+
-+ sprintf(old, "%s/%s/%s", LOCAL->dir, MDNAME(Cur), MDFILE(elt));
-+ t = MDFILE(elt);
-+ if(s = strstr(MDFILE(elt), MDUIDSEP)){
-+ *s = '\0';
-+ s += strlen(MDUIDSEP);
-+ strtoul(s, &s, 10);
-+ sprintf(new, "%s/%s/%s%s", LOCAL->dir, MDNAME(Cur), t, s);
-+ if(rename(old, new) == 0){
-+ maildir_free_file_only ((void **)&elt->private.spare.ptr);
-+ s = strrchr(new, '/');
-+ MDFILE(elt) = cpystr(s+1);
-+ }
-+ elt->private.uid = 0L;
-+ }
-+ }
-+
-+ void
-+ maildir_assign_uid(MAILSTREAM *stream, unsigned long msgno, unsigned long uid)
-+ {
-+ int createuid, deleteuid = 0;
-+ char old[MAILTMPLEN], new[MAILTMPLEN], *s, *t;
-+ MESSAGECACHE *elt;
-+
-+ elt = mail_elt(stream, msgno);
-+ if(!stream || !elt || !elt->private.spare.ptr || !LOCAL || !LOCAL->dir)
-+ return;
-+
-+ maildir_delete_uid(stream, msgno);
-+ sprintf(old, "%s/%s/%s", LOCAL->dir, MDNAME(Cur), MDFILE(elt));
-+ t = MDFILE(elt);
-+ if((s = strrchr(MDFILE(elt),FLAGSEP)) != NULL){
-+ *s++ = '\0';
-+ sprintf(new, "%s/%s/%s%s%lu%c%s",
-+ LOCAL->dir, MDNAME(Cur), t, MDUIDSEP, uid, FLAGSEP, s);
-+ if(rename(old, new) == 0){
-+ maildir_free_file_only ((void **)&elt->private.spare.ptr);
-+ s = strrchr(new, '/');
-+ MDFILE(elt) = cpystr(s+1);
-+ stream->uid_validity = time(0);
-+ }
-+ elt->private.uid = uid;
-+ }
-+ }
-+
-+ void
-+ maildir_uid_renew_tempfile(MAILSTREAM *stream)
-+ {
-+ char tmp[MAILTMPLEN];
-+
-+ if(!stream || stream->rdonly
-+ || !LOCAL || !LOCAL->candouid || !LOCAL->dir || !LOCAL->uidtempfile)
-+ return;
-+
-+ sprintf(tmp,"%s/%s.%d.%lu", LOCAL->dir, MDUIDTEMP, mypid, time(0));
-+ if(rename(LOCAL->uidtempfile, tmp) == 0){
-+ fs_give((void **)&LOCAL->uidtempfile);
-+ LOCAL->uidtempfile = cpystr(tmp);
-+ }
-+ }
-diff -rc alpine-2.00/imap/src/osdep/unix/maildir.h alpine-2.00.I.USE/imap/src/osdep/unix/maildir.h
-*** alpine-2.00/imap/src/osdep/unix/maildir.h 2011-02-07 20:34:02.000000000 -0800
---- alpine-2.00.I.USE/imap/src/osdep/unix/maildir.h 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 0 ****
---- 1,226 ----
-+ /*
-+ * 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 ','
-+
-+ 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))
-+
-+ /* Files associated to a maildir directory */
-+
-+ #define MDUIDVALIDITY ".uidvalidity" /* support for old maildirs */
-+ #define MDDIR ".mdir" /* this folder is a directory */
-+ #define MDUIDLAST ".uidlast" /* last assigned uid */
-+ #define MDUIDTEMP ".uidtemp" /* We assign uid's no one else */
-+
-+
-+
-+ /* 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) ? '.' : '/')
-+
-+ /* UID Support */
-+
-+ #define MAXTEMPUID (unsigned long) 180L
-+ const char mduid[] = {',','u','=','\0'};
-+ #define MDUIDSEP mduid
-+
-+
-+ /* Now we deal with messages filenames */
-+ char mdlocaldomain[MAILTMPLEN+1] = {'\0'};
-+ pid_t mypid = (pid_t) 0;
-+ static char *mdfpath = NULL;
-+ static char myMdInboxDir[50] = { '\0' };/* 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 */
-+ unsigned int link : 1; /* There is a symbolic link */
-+ unsigned int candouid; /* we can assign uids and no one else */
-+ char *uidtempfile; /* path to uid temp file */
-+ 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 */
-+ DirNamesType loc; /* location of this 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)->private.spare.ptr))->name)
-+ #define MDLOC(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->loc)
-+ #define MDPOS(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->pos)
-+ #define MDSIZE(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->size)
-+ #define MDATIME(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->atime)
-+ #define MDMTIME(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->mtime)
-+ #define MDCTIME(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->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 */
-+ long maildir_expunge (MAILSTREAM *stream, char *sequence, long options);
-+ 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);
-+ long maildir_dirfmttest (char *name);
-+ char *maildir_file (char *dst,char *name);
-+ int maildir_select (const struct direct *name);
-+ int maildir_namesort (const void *d1, const void *d2);
-+ unsigned long antoul (char *seed);
-+ unsigned long mdfntoul (char *name);
-+ int courier_dir_select (const 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);
-+ char *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);
-+ int maildir_eliminate_duplicate (char *name, struct direct ***flist,
-+ unsigned long *nfiles);
-+ int maildir_doscandir (char *name, struct direct ***flist, int flag);
-+ 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);
-+ char *myrootdir (char *name);
-+ char *mdirpath (void);
-+ int maildir_initial_check (MAILSTREAM *stream, DirNamesType dirtype);
-+ unsigned long maildir_parse_dir(MAILSTREAM *stream, unsigned long nmsgs,
-+ DirNamesType dirtype, struct direct **names, unsigned long nfiles, 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);
-+ void maildir_fast (MAILSTREAM *stream,char *sequence,long flags);
-+
-+ /* Courier server support */
-+ 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);
-+ void courier_list_info(COURIER_S **cdirp, char *data, int i);
-+
-+ /* UID Support */
-+ unsigned int maildir_can_assign_uid (MAILSTREAM *stream);
-+ void maildir_read_uid(MAILSTREAM *stream, unsigned long *uid_last,
-+ unsigned long *uid_validity);
-+ void maildir_write_uid(MAILSTREAM *stream, unsigned long uid_last,
-+ unsigned long uid_validity);
-+ unsigned long maildir_get_uid(char *name);
-+ void maildir_delete_uid(MAILSTREAM *stream, unsigned long msgno);
-+ void maildir_assign_uid(MAILSTREAM *stream, unsigned long msgno, unsigned long uid);
-+ void maildir_uid_renew_tempfile(MAILSTREAM *stream);
-+
-diff -rc alpine-2.00/imap/src/osdep/unix/Makefile alpine-2.00.I.USE/imap/src/osdep/unix/Makefile
-*** alpine-2.00/imap/src/osdep/unix/Makefile 2008-06-04 11:18:34.000000000 -0700
---- alpine-2.00.I.USE/imap/src/osdep/unix/Makefile 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 144,150 ****
- # However, mh needs to be before any sysinbox formats (such as mmdf or unix)
- # since otherwise INBOX won't work correctly when mh_allow_inbox is set.
- #
-! DEFAULTDRIVERS=imap nntp pop3 mix mx mbx tenex mtx mh mmdf unix news phile
- CHUNKSIZE=65536
-
- # Normally no need to change any of these
---- 144,150 ----
- # However, mh needs to be before any sysinbox formats (such as mmdf or unix)
- # since otherwise INBOX won't work correctly when mh_allow_inbox is set.
- #
-! DEFAULTDRIVERS=maildir courier imap nntp pop3 mix mx mbx tenex mtx mh mmdf unix news phile
- CHUNKSIZE=65536
-
- # Normally no need to change any of these
-***************
-*** 153,159 ****
- BINARIES=osdep.o mail.o misc.o newsrc.o smanager.o utf8.o utf8aux.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 mix.o
- CFLAGS=-g
-
- CAT=cat
---- 153,159 ----
- BINARIES=osdep.o mail.o misc.o newsrc.o smanager.o utf8.o utf8aux.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 mix.o maildir.o
- CFLAGS=-g
-
- CAT=cat
-***************
-*** 282,288 ****
-
- 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 \
---- 282,288 ----
-
- 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 \
-***************
-*** 892,898 ****
- unix.o: mail.h misc.h osdep.h unix.h pseudo.h dummy.h
- utf8.o: mail.h misc.h osdep.h utf8.h tmap.c widths.c
- utf8aux.o: mail.h misc.h osdep.h utf8.h
-!
-
- # OS-dependent
-
---- 892,898 ----
- unix.o: mail.h misc.h osdep.h unix.h pseudo.h dummy.h
- utf8.o: mail.h misc.h osdep.h utf8.h tmap.c widths.c
- utf8aux.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 alpine-2.00/imap/src/osdep/unix/os_cyg.h alpine-2.00.I.USE/imap/src/osdep/unix/os_cyg.h
-*** alpine-2.00/imap/src/osdep/unix/os_cyg.h 2008-06-04 11:18:34.000000000 -0700
---- alpine-2.00.I.USE/imap/src/osdep/unix/os_cyg.h 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 47,52 ****
---- 47,53 ----
- #define setpgrp setpgid
-
- #define SYSTEMUID 18 /* Cygwin returns this for SYSTEM */
-+ #define FLAGSEP ';'
- #define geteuid Geteuid
- uid_t Geteuid (void);
-
-diff -rc alpine-2.00/imap/src/osdep/unix/ssl_unix.c alpine-2.00.I.USE/imap/src/osdep/unix/ssl_unix.c
-*** alpine-2.00/imap/src/osdep/unix/ssl_unix.c 2008-06-04 11:18:34.000000000 -0700
---- alpine-2.00.I.USE/imap/src/osdep/unix/ssl_unix.c 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 524,530 ****
- if (tcpdebug) mm_log ("Successfully read SSL data",TCPDEBUG);
- }
- /* timeout, punt unless told not to */
-! else if (!tmoh || !(*tmoh) (now - t,now - tl)) {
- if (tcpdebug) mm_log ("SSL data read timeout",TCPDEBUG);
- return ssl_abort (stream);
- }
---- 524,530 ----
- if (tcpdebug) mm_log ("Successfully read SSL data",TCPDEBUG);
- }
- /* timeout, punt unless told not to */
-! else if (!tmoh || !(*tmoh) (now - t,now - tl, stream->tcpstream->host)) {
- if (tcpdebug) mm_log ("SSL data read timeout",TCPDEBUG);
- return ssl_abort (stream);
- }
-diff -rc alpine-2.00/imap/src/osdep/unix/tcp_unix.c alpine-2.00.I.USE/imap/src/osdep/unix/tcp_unix.c
-*** alpine-2.00/imap/src/osdep/unix/tcp_unix.c 2008-06-04 11:18:34.000000000 -0700
---- alpine-2.00.I.USE/imap/src/osdep/unix/tcp_unix.c 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 585,591 ****
- if (tcpdebug) mm_log ("Successfully read TCP buffer",TCPDEBUG);
- }
- /* timeout, punt unless told not to */
-! else if (!tmoh || !(*tmoh) (now - t,now - tl)) {
- if (tcpdebug) mm_log ("TCP buffer read timeout",TCPDEBUG);
- return tcp_abort (stream);
- }
---- 585,591 ----
- if (tcpdebug) mm_log ("Successfully read TCP buffer",TCPDEBUG);
- }
- /* timeout, punt unless told not to */
-! else if (!tmoh || !(*tmoh) (now - t,now - tl, stream->host)) {
- if (tcpdebug) mm_log ("TCP buffer read timeout",TCPDEBUG);
- return tcp_abort (stream);
- }
-***************
-*** 645,651 ****
- if (tcpdebug) mm_log ("Successfully read TCP data",TCPDEBUG);
- }
- /* timeout, punt unless told not to */
-! else if (!tmoh || !(*tmoh) (now - t,now - tl)) {
- if (tcpdebug) mm_log ("TCP data read timeout",TCPDEBUG);
- return tcp_abort (stream);/* error or timeout no-continue */
- }
---- 645,651 ----
- if (tcpdebug) mm_log ("Successfully read TCP data",TCPDEBUG);
- }
- /* timeout, punt unless told not to */
-! else if (!tmoh || !(*tmoh) (now - t,now - tl, stream->host)) {
- if (tcpdebug) mm_log ("TCP data read timeout",TCPDEBUG);
- return tcp_abort (stream);/* error or timeout no-continue */
- }
-***************
-*** 716,722 ****
- if (tcpdebug) mm_log ("successfully wrote to TCP",TCPDEBUG);
- }
- /* timeout, punt unless told not to */
-! else if (!tmoh || !(*tmoh) (now - t,now - tl)) {
- if (tcpdebug) mm_log ("TCP write timeout",TCPDEBUG);
- return tcp_abort (stream);
- }
---- 716,722 ----
- if (tcpdebug) mm_log ("successfully wrote to TCP",TCPDEBUG);
- }
- /* timeout, punt unless told not to */
-! else if (!tmoh || !(*tmoh) (now - t,now - tl, stream->host)) {
- if (tcpdebug) mm_log ("TCP write timeout",TCPDEBUG);
- return tcp_abort (stream);
- }
-diff -rc alpine-2.00/include/general.h alpine-2.00.I.USE/include/general.h
-*** alpine-2.00/include/general.h 2007-01-25 12:29:45.000000000 -0800
---- alpine-2.00.I.USE/include/general.h 2011-02-07 20:33:44.000000000 -0800
-***************
-*** 32,37 ****
---- 32,38 ----
- #undef TRUE
- #define TRUE 1 /* True, yes, good, etc. */
- #define ABORT 2 /* Death, ^G, abort, etc. */
-+ #define COUNT 3 /* For control-c command */
-
-
- #undef MIN
-diff -rc alpine-2.00/patchlevel alpine-2.00.I.USE/patchlevel
-*** alpine-2.00/patchlevel 2011-02-07 20:34:02.000000000 -0800
---- alpine-2.00.I.USE/patchlevel 2011-02-07 20:34:02.000000000 -0800
-***************
-*** 0 ****
---- 1 ----
-+ char plevstamp[]="VERSION=84 created on Mon Feb 07 2011 20:34:02 PST";
-diff -rc alpine-2.00/pico/attach.c alpine-2.00.I.USE/pico/attach.c
-*** alpine-2.00/pico/attach.c 2008-06-11 10:21:24.000000000 -0700
---- alpine-2.00.I.USE/pico/attach.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 108,115 ****
- switch(status){
- case HELPCH:
- if(Pmaster){
-- VARS_TO_SAVE *saved_state;
--
- saved_state = save_pico_state();
- (*Pmaster->helper)(Pmaster->attach_help, _("Attach Help"), 1);
- if(saved_state){
---- 108,113 ----
-diff -rc alpine-2.00/pico/basic.c alpine-2.00.I.USE/pico/basic.c
-*** alpine-2.00/pico/basic.c 2007-11-26 15:45:22.000000000 -0800
---- alpine-2.00.I.USE/pico/basic.c 2011-02-07 20:33:44.000000000 -0800
-***************
-*** 25,33 ****
- * framing, are hard.
- */
- #include "headers.h"
-!
- #include "osdep/terminal.h"
-
-
- /*
- * Move the cursor to the
---- 25,34 ----
- * framing, are hard.
- */
- #include "headers.h"
-! #include "../pith/osdep/color.h"
- #include "osdep/terminal.h"
-
-+ int indent_match(char *, LINE *, char *, int, int);
-
- /*
- * Move the cursor to the
-***************
-*** 284,290 ****
- gotobop(int f, int n)
- {
- int quoted, qlen;
-! UCS qstr[NLINE], qstr2[NLINE];
-
- if (n < 0) /* the other way...*/
- return(gotoeop(f, -n));
---- 285,291 ----
- gotobop(int f, int n)
- {
- int quoted, qlen;
-! char qstr[NLINE], qstr2[NLINE], ind_str[NLINE], pqstr[NLINE];;
-
- if (n < 0) /* the other way...*/
- return(gotoeop(f, -n));
-***************
-*** 296,301 ****
---- 297,310 ----
- curwp->w_dotp = lback(curwp->w_dotp);
- curwp->w_doto = 0;
- }
-+
-+ if (indent_match(default_qstr(), 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>
-***************
-*** 303,322 ****
- * PLUS: if there's a quote string, a quoted-to-non-quoted
- * line transition.
- */
-! quoted = glo_quote_str ? quote_match(glo_quote_str, curwp->w_dotp, qstr, NLINE) : 0;
-! qlen = quoted ? ucs4_strlen(qstr) : 0;
- while(lback(curwp->w_dotp) != curbp->b_linep
- && llength(lback(curwp->w_dotp)) > qlen
-! && (glo_quote_str
-! ? (quoted == quote_match(glo_quote_str,
-! lback(curwp->w_dotp),
-! qstr2, NLINE)
-! && !ucs4_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)
---- 312,369 ----
- * PLUS: if there's a quote string, a quoted-to-non-quoted
- * line transition.
- */
-! quoted = quote_match(default_qstr(), 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
-! && (quoted == quote_match(default_qstr(),
-! lback(curwp->w_dotp), qstr2, NLINE, 0))
-! && !strcmp(qstr, qstr2) /* processed string */
-! && (quoted == quote_match(default_qstr(),
-! lback(curwp->w_dotp), qstr2, NLINE, 1))
-! && !strcmp(qstr, qstr2) /* raw string */
-! && !indent_match(default_qstr(),
-! lback(curwp->w_dotp),ind_str, NLINE, 0)
-! && !ISspace(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 i, j;
-+
-+ /*
-+ * First we test if the preceding line is indented.
-+ * for the following test we need to have the raw values,
-+ * not the processed values
-+ */
-+ quote_match(default_qstr(), curwp->w_dotp, qstr, NLINE, 1);
-+ quote_match(default_qstr(), lback(curwp->w_dotp), qstr2, NLINE, 1);
-+ 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 ((indent_match(default_qstr(), lback(curwp->w_dotp),
-+ ind_str, NLINE, 1)
-+ && (strlenis(qstr2)
-+ + strlenis(ind_str) >= strlenis(qstr)))
-+ || (lback(curwp->w_dotp) != curbp->b_linep
-+ && llength(lback(curwp->w_dotp)) > qlen
-+ && (quoted == quote_match(default_qstr(),
-+ lback(curwp->w_dotp), pqstr, NLINE, 0))
-+ && !strcmp(qstr, pqstr)
-+ && !ISspace(lgetc(curwp->w_dotp, qlen).c)
-+ && (strlenis(qstr2) > strlenis(qstr)))
-+ && !qstr2[i] && !qstr[j])
-+ curwp->w_dotp = lback(curwp->w_dotp);
-+ }
-+
- if(n){
- /* keep looking */
- if(lback(curwp->w_dotp) == curbp->b_linep)
-***************
-*** 329,335 ****
- else{
- /* leave cursor on first word in para */
- curwp->w_doto = 0;
-! while(ucs4_isspace(lgetc(curwp->w_dotp, curwp->w_doto).c))
- if(++curwp->w_doto >= llength(curwp->w_dotp)){
- curwp->w_doto = 0;
- curwp->w_dotp = lforw(curwp->w_dotp);
---- 376,382 ----
- else{
- /* leave cursor on first word in para */
- curwp->w_doto = 0;
-! while(ISspace(lgetc(curwp->w_dotp, curwp->w_doto).c))
- if(++curwp->w_doto >= llength(curwp->w_dotp)){
- curwp->w_doto = 0;
- curwp->w_dotp = lforw(curwp->w_dotp);
-***************
-*** 343,348 ****
---- 390,578 ----
- return(TRUE);
- }
-
-+ unsigned char GetAccent()
-+ {
-+ UCS c,d;
-+ c = 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 = GetKey();
-+ return accent(c,d);
-+ }
-+
-+ int pineaccent(f,n)
-+ int f,n;
-+ { unsigned char e;
-+
-+ if (e = GetAccent())
-+ execute(e, 0, 1);
-+ return 1;
-+ }
-+
-+ unsigned char accent(f,n)
-+ UCS f,n;
-+ { UCS c,d;
-+
-+ c = f;
-+ d = 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 forword to the end of the current paragraph
-***************
-*** 352,359 ****
- int
- gotoeop(int f, int n)
- {
-! int quoted, qlen;
-! UCS qstr[NLINE], qstr2[NLINE];
-
- if (n < 0) /* the other way...*/
- return(gotobop(f, -n));
---- 582,590 ----
- int
- gotoeop(int f, int n)
- {
-! int quoted, qlen, indented, changeqstr = 0;
-! int i,j, fli = 0; /* fli = first line indented a boolean variable */
-! char qstr[NLINE], qstr2[NLINE], ind_str[NLINE];
-
- if (n < 0) /* the other way...*/
- return(gotobop(f, -n));
-***************
-*** 366,392 ****
- break;
- }
-
- /* scan line by line until we come to a line ending with
- * a <NL><NL> or <NL><TAB> or <NL><SPACE>
- *
- * PLUS: if there's a quote string, a quoted-to-non-quoted
- * line transition.
- */
-! quoted = glo_quote_str
-! ? quote_match(glo_quote_str,
-! curwp->w_dotp, qstr, NLINE) : 0;
-! qlen = quoted ? ucs4_strlen(qstr) : 0;
-
- while(curwp->w_dotp != curbp->b_linep
- && llength(lforw(curwp->w_dotp)) > qlen
-! && (glo_quote_str
-! ? (quoted == quote_match(glo_quote_str,
-! lforw(curwp->w_dotp),
-! qstr2, NLINE)
-! && !ucs4_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);
-
- curwp->w_doto = llength(curwp->w_dotp);
---- 597,666 ----
- 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){
-+ quote_match(default_qstr(), curwp->w_dotp, qstr, NLINE, 1);
-+ quote_match(default_qstr(), lforw(curwp->w_dotp), qstr2, NLINE, 1);
-+ indented = indent_match(default_qstr(), curwp->w_dotp, ind_str,
-+ NLINE, 1);
-+ if (strlenis(qstr)
-+ + strlenis(ind_str) < strlenis(qstr2)){
-+ curwp->w_doto = llength(curwp->w_dotp);
-+ 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){
-+ fli++;
-+ if (indent_match(default_qstr(), 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>
- *
- * PLUS: if there's a quote string, a quoted-to-non-quoted
- * line transition.
- */
-! /* if the first line is indented (fli == 1), then the test below
-! is on the second line, and in that case we will need the raw
-! string, not the processed string
-! */
-! quoted = quote_match(default_qstr(), curwp->w_dotp, qstr, NLINE, fli);
-! qlen = quoted ? strlen(qstr) : 0;
-
- while(curwp->w_dotp != curbp->b_linep
- && llength(lforw(curwp->w_dotp)) > qlen
-! && (quoted == quote_match(default_qstr(),
-! lforw(curwp->w_dotp), qstr2, NLINE, fli))
-! && !strcmp(qstr, qstr2)
-! && (quoted == quote_match(default_qstr(),
-! lforw(curwp->w_dotp), qstr2, NLINE, 1))
-! && !strcmp(qstr, qstr2)
-! && !indent_match(default_qstr(),
-! lforw(curwp->w_dotp), ind_str, NLINE, 0)
-! && !ISspace(lgetc(lforw(curwp->w_dotp), qlen).c))
- curwp->w_dotp = lforw(curwp->w_dotp);
-
- curwp->w_doto = llength(curwp->w_dotp);
-***************
-*** 683,689 ****
---- 957,1013 ----
- return (scrollforw (1, FALSE));
- }
-
-+ /* 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;
-+ static int firsttime = 0;
-+
-+ 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{
-+ if(lforw(curwp->w_dotp) != curbp->b_linep)
-+ curwp->w_dotp = lforw(curwp->w_dotp);
-+ else{
-+ curwp->w_doto = llength(curwp->w_dotp);
-+ break;
-+ }
-+ }
-+ }
-+ killregion(FALSE,1);
-+ lastflag |= CFKILL;
-+ if(firsttime == 0)
-+ emlwrite("Deleted text can be recovered with the ^U command", NULL);
-+ firsttime = 1;
-+ return TRUE;
-+ }
-
- /*
- * Scroll to a position.
-diff -rc alpine-2.00/pico/bind.c alpine-2.00.I.USE/pico/bind.c
-*** alpine-2.00/pico/bind.c 2007-12-07 15:45:22.000000000 -0800
---- alpine-2.00.I.USE/pico/bind.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 132,139 ****
- }
-
- if(Pmaster){
-- VARS_TO_SAVE *saved_state;
--
- saved_state = save_pico_state();
- (*Pmaster->helper)(Pmaster->composer_help,
- Pmaster->headents
---- 132,137 ----
-diff -rc alpine-2.00/pico/blddate.c alpine-2.00.I.USE/pico/blddate.c
-*** alpine-2.00/pico/blddate.c 2006-11-22 14:50:13.000000000 -0800
---- alpine-2.00.I.USE/pico/blddate.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 19,25 ****
- char **argv;
- {
- struct tm *t;
-! FILE *outfile=stdout;
- time_t ltime;
-
- if(argc > 1 && (outfile = fopen(argv[1], "w")) == NULL){
---- 19,25 ----
- char **argv;
- {
- struct tm *t;
-! FILE *outfile=stdout, *infile;
- time_t ltime;
-
- if(argc > 1 && (outfile = fopen(argv[1], "w")) == NULL){
-***************
-*** 46,51 ****
---- 46,57 ----
- 1900 + t->tm_year);
-
- fprintf(outfile, "char hoststamp[]=\"random-pc\";\n");
-+ if((infile = fopen("../patchlevel", "r")) != NULL){
-+ int c;
-+ while ((c = getc(infile)) != EOF) putc(c, outfile);
-+ fclose(infile);
-+ }
-+ else fprintf(outfile, "char plevstamp[]=\"No information available\";\n");
-
- fclose(outfile);
-
-diff -rc alpine-2.00/pico/browse.c alpine-2.00.I.USE/pico/browse.c
-*** alpine-2.00/pico/browse.c 2008-02-26 15:07:15.000000000 -0800
---- alpine-2.00.I.USE/pico/browse.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 931,938 ****
- }
-
- if(Pmaster){
-- VARS_TO_SAVE *saved_state;
--
- saved_state = save_pico_state();
- (*Pmaster->helper)(Pmaster->browse_help,
- _("Help for Browsing"), 1);
---- 931,936 ----
-diff -rc alpine-2.00/pico/composer.c alpine-2.00.I.USE/pico/composer.c
-*** alpine-2.00/pico/composer.c 2008-03-21 14:31:58.000000000 -0700
---- alpine-2.00.I.USE/pico/composer.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 93,98 ****
---- 93,103 ----
- */
- struct on_display ods; /* global on_display struct */
-
-+ /* a pointer to the subject line. This is so that we do not have to compute
-+ * the header line in every call. It saves a few CPU cycles
-+ */
-+
-+ struct hdr_line *subject_line = NULL;
-
- /*
- * useful macros
-***************
-*** 495,500 ****
---- 500,510 ----
- mswin_setscrollrange (0, 0);
- #endif /* _WINDOWS */
-
-+ if(Pmaster)
-+ for (subject_line = NULL, i=0; headents[i].name; i++)
-+ if(strcmp(headents[i].name, "Subject") == 0)
-+ subject_line = headents[i].hd_text;
-+
- /*
- * Decide where to begin editing. if f == TRUE begin editing
- * at the bottom. this case results from the cursor backing
-***************
-*** 794,802 ****
- len += lmp->fname ? strlen(lmp->fname) : 0;
-
- if(len+3 > sizeof(buf)){
-- bfp = malloc(len+3);
- space = len+3;
-! if((bfp=malloc(len+3)) == NULL){
- emlwrite("\007Can't malloc space for filename",
- NULL);
- continue;
---- 804,812 ----
- len += lmp->fname ? strlen(lmp->fname) : 0;
-
- if(len+3 > sizeof(buf)){
- space = len+3;
-! bfp = malloc(space*sizeof(char));
-! if(bfp == NULL){
- emlwrite("\007Can't malloc space for filename",
- NULL);
- continue;
-***************
-*** 1270,1278 ****
- len += strlen(lmp->size);
-
- if(len+3 > sizeof(buf)){
-- bfp = malloc(len+3);
- space = len+3;
-! if((bfp=malloc(len+3)) == NULL){
- emlwrite("\007Can't malloc space for filename",
- NULL);
- continue;
---- 1280,1288 ----
- len += strlen(lmp->size);
-
- if(len+3 > sizeof(buf)){
- space = len+3;
-! bfp = malloc(space*sizeof(char));
-! if(bfp == NULL){
- emlwrite("\007Can't malloc space for filename",
- NULL);
- continue;
-***************
-*** 1309,1316 ****
- zotlmlist(lm);
- } /* else, nothing of interest */
- } else if (headents[ods.cur_e].selector != NULL) {
-- VARS_TO_SAVE *saved_state;
--
- /*---- General selector for non-attachments -----*/
-
- /*
---- 1319,1324 ----
-***************
-*** 1485,1491 ****
- struct hdr_line *line;
- int sz = 0;
- char *filename = NULL;
-- VARS_TO_SAVE *saved_state;
-
- /*
- * Since the fileedit will make a new call back to pico()
---- 1493,1498 ----
-***************
-*** 1852,1857 ****
---- 1859,1866 ----
- }
-
- UpdateHeader(0);
-+ if(sendnow)
-+ return(status !=0);
- PaintHeader(COMPOSER_TOP_LINE, status != 0);
- PaintBody(1);
- return(status != 0);
-***************
-*** 1899,1904 ****
---- 1908,1918 ----
-
- while(1){ /* edit the line... */
-
-+ if(Pmaster && subject_line != NULL
-+ && ods.cur_l == subject_line
-+ && ods.cur_l->text[0] == 0)
-+ (*Pmaster->newthread)();
-+
- if(skipmove)
- skipmove = 0;
- else
-***************
-*** 1990,1996 ****
- tbufp = &strng[ods.p_len];
-
- 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
---- 2004,2010 ----
- tbufp = &strng[ods.p_len];
-
- 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
-***************
-*** 2070,2075 ****
---- 2084,2096 ----
- }
- 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|KEY_LEFT): /* word skip left */
- if(ods.p_ind > 0) /* Scoot one char left if possible */
- ods.p_ind--;
-***************
-*** 2937,2943 ****
- ComposerHelp(int level)
- {
- char buf[80];
-- VARS_TO_SAVE *saved_state;
-
- curwp->w_flag |= WFMODE;
- sgarbf = TRUE;
---- 2958,2963 ----
-***************
-*** 3337,3342 ****
---- 3357,3365 ----
- {
- UCS *bufp, *buf;
-
-+ if (sendnow)
-+ return;
-+
- if(ComposerTopLine - 1 >= BOTTOM()) /* silently forget it */
- return;
-
-***************
-*** 3393,3398 ****
---- 3416,3424 ----
- UCS *end;
- int i;
-
-+ if (sendnow)
-+ return(TRUE);
-+
- buf = utf8_to_ucs4_cpystr(headents[entry].prompt); /* fresh prompt paint */
- if(!buf)
- return(-1);
-***************
-*** 3606,3612 ****
- char *tmp;
- struct headerentry *e;
- BUILDER_ARG *nextarg, *arg = NULL, *headarg = NULL;
-- VARS_TO_SAVE *saved_state;
-
- if(!entry->builder)
- return(0);
---- 3632,3637 ----
-***************
-*** 3826,3832 ****
- call_expander(void)
- {
- char **s = NULL;
-- VARS_TO_SAVE *saved_state;
- int expret;
-
- if(!Pmaster->expander)
---- 3851,3856 ----
-***************
-*** 4348,4353 ****
---- 4372,4380 ----
- void
- ShowPrompt(void)
- {
-+ 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;
-***************
-*** 4716,4721 ****
---- 4743,4750 ----
- free(state->opertree);
-
- free(state);
-+
-+ state = NULL;
- }
-
-
-diff -rc alpine-2.00/pico/display.c alpine-2.00.I.USE/pico/display.c
-*** alpine-2.00/pico/display.c 2008-03-26 10:27:45.000000000 -0700
---- alpine-2.00.I.USE/pico/display.c 2011-02-07 20:33:44.000000000 -0800
-***************
-*** 386,391 ****
---- 386,394 ----
- int scroll = 0;
- CELL c;
-
-+ if (sendnow)
-+ return;
-+
- #if TYPEAH
- if (typahead())
- return;
-***************
-*** 915,921 ****
- int nbflag; /* non-blanks to the right flag? */
- int cleartoeol = 0;
-
-! if(row < 0 || row > term.t_nrow)
- return;
-
- /* set up pointers to virtual and physical lines */
---- 918,924 ----
- int nbflag; /* non-blanks to the right flag? */
- int cleartoeol = 0;
-
-! if(row < 0 || row > term.t_nrow || sendnow)
- return;
-
- /* set up pointers to virtual and physical lines */
-***************
-*** 1284,1290 ****
- void
- mlerase(void)
- {
-! if (term.t_nrow < term.t_mrow)
- return;
-
- movecursor(term.t_nrow - term.t_mrow, 0);
---- 1287,1293 ----
- void
- mlerase(void)
- {
-! if (term.t_nrow < term.t_mrow || sendnow)
- return;
-
- movecursor(term.t_nrow - term.t_mrow, 0);
-***************
-*** 1359,1364 ****
---- 1362,1371 ----
- menu_yesno[6].label = N_("Cancel");
- menu_yesno[7].name = "N";
- menu_yesno[7].label = (dflt == FALSE) ? "[" N_("No") "]" : N_("No");
-+ if(Pmaster && Pmaster->onctrlc){
-+ menu_yesno[8].name = "T";
-+ menu_yesno[8].label = N_("counT");
-+ }
- wkeyhelp(menu_yesno); /* paint generic menu */
- sgarbk = TRUE; /* mark menu dirty */
- if(Pmaster && curwp)
-***************
-*** 1437,1442 ****
---- 1444,1457 ----
- km_popped++;
- break;
- }
-+
-+ case 'T':
-+ case 't':
-+ if(Pmaster && Pmaster->onctrlc){
-+ pputs_utf8(_("counT"), 1);
-+ rv = COUNT;
-+ break;
-+ }
- /* else fall through */
-
- default:
-***************
-*** 1750,1755 ****
---- 1765,1775 ----
- b = &buf[ucs4_strlen(buf)];
- continue;
-
-+ case (CTRL|'\\'):
-+ if (c = GetAccent())
-+ goto text;
-+ continue;
-+
- case (CTRL|'F') : /* CTRL-F forward a char*/
- case KEY_RIGHT :
- if(*b == '\0')
-***************
-*** 1759,1764 ****
---- 1779,1796 ----
-
- continue;
-
-+ case (CTRL|'N'): /* Insert pattern */
-+ if (pat[0] != '\0'){
-+ ucs4_strncpy(buf+ucs4_strlen(buf), pat, NPAT);
-+ pputs(pat,1);
-+ b = &buf[ucs4_strlen(buf)];
-+ dline.vused += ucs4_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);
-***************
-*** 1868,1874 ****
- #endif
-
- default :
-!
- /* look for match in extra_v */
- for(i = 0; i < 12; i++)
- if(c && c == extra_v[i]){
---- 1900,1906 ----
- #endif
-
- default :
-! text:
- /* look for match in extra_v */
- for(i = 0; i < 12; i++)
- if(c && c == extra_v[i]){
-***************
-*** 1962,1968 ****
-
- mlerase();
-
-! if(!(message && *message) || term.t_nrow < 2)
- return; /* nothing to write or no space to write, bag it */
-
- bufp = message;
---- 1994,2000 ----
-
- mlerase();
-
-! if(!(message && *message) || term.t_nrow < 2 || sendnow)
- return; /* nothing to write or no space to write, bag it */
-
- bufp = message;
-***************
-*** 2151,2158 ****
- }
-
- ret = ttcol;
-! while(ttcol < term.t_ncol)
-! pputc(' ', 0);
-
- movecursor(term.t_nrow - term.t_mrow, ret);
-
---- 2183,2191 ----
- }
-
- ret = ttcol;
-! if(sendnow == 0)
-! while(ttcol < term.t_ncol)
-! pputc(' ', 0);
-
- movecursor(term.t_nrow - term.t_mrow, ret);
-
-***************
-*** 2631,2636 ****
---- 2664,2671 ----
- {
- int ind, width, printable_ascii = 0;
-
-+ if(sendnow)
-+ return;
- /*
- * This is necessary but not sufficient to allow us to draw. Note that
- * ttrow runs from 0 to t_nrow (so total number of rows is t_nrow+1)
-***************
-*** 2685,2690 ****
---- 2720,2727 ----
- pputs(UCS *s, /* string to write */
- int a) /* and its attribute */
- {
-+ if(sendnow)
-+ return;
- while (*s != '\0')
- pputc(*s++, a);
- }
-***************
-*** 2695,2700 ****
---- 2732,2739 ----
- {
- UCS *ucsstr = NULL;
-
-+ if(sendnow)
-+ return;
- if(s && *s){
- ucsstr = utf8_to_ucs4_cpystr(s);
- if(ucsstr){
-***************
-*** 2995,3000 ****
---- 3034,3042 ----
- char nbuf[NLINE];
- #endif
-
-+ if(sendnow)
-+ return;
-+
- #ifdef _WINDOWS
- pico_config_menu_items (keymenu);
- #endif
-diff -rc alpine-2.00/pico/ebind.h alpine-2.00.I.USE/pico/ebind.h
-*** alpine-2.00/pico/ebind.h 2007-11-06 15:51:13.000000000 -0800
---- alpine-2.00.I.USE/pico/ebind.h 2011-02-07 20:33:43.000000000 -0800
-***************
-*** 61,67 ****
- #ifdef MOUSE
- {KEY_MOUSE, mousepress},
- #ifndef _WINDOWS
-! {CTRL|'\\', toggle_xterm_mouse},
- #endif
- #endif
- {CTRL|'A', gotobol},
---- 61,67 ----
- #ifdef MOUSE
- {KEY_MOUSE, mousepress},
- #ifndef _WINDOWS
-! {CTRL|'|', toggle_xterm_mouse},
- #endif
- #endif
- {CTRL|'A', gotobol},
-***************
-*** 100,106 ****
- {CTRL|KEY_HOME, gotobob},
- {CTRL|KEY_END, gotoeob},
- {0x7F, backdel},
-! {0, NULL}
- };
-
-
---- 100,108 ----
- {CTRL|KEY_HOME, gotobob},
- {CTRL|KEY_END, gotoeob},
- {0x7F, backdel},
-! {CTRL|'\\', pineaccent},
-! {0,
-! NULL}
- };
-
-
-***************
-*** 123,129 ****
- #ifdef MOUSE
- {KEY_MOUSE, mousepress},
- #ifndef _WINDOWS
-! {CTRL|'\\', toggle_xterm_mouse},
- #endif
- #endif
- {CTRL|'A', gotobol},
---- 125,131 ----
- #ifdef MOUSE
- {KEY_MOUSE, mousepress},
- #ifndef _WINDOWS
-! {CTRL|'|', toggle_xterm_mouse},
- #endif
- #endif
- {CTRL|'A', gotobol},
-diff -rc alpine-2.00/pico/edef.h alpine-2.00.I.USE/pico/edef.h
-*** alpine-2.00/pico/edef.h 2008-01-04 16:41:49.000000000 -0800
---- alpine-2.00.I.USE/pico/edef.h 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 32,37 ****
---- 32,38 ----
-
- /* initialized global definitions */
-
-+ int sendnow = 0; /* should we send now */
- int fillcol = 72; /* Current fill column */
- int userfillcol = -1; /* Fillcol set from cmd line */
- UCS pat[NPAT]; /* Search pattern */
-***************
-*** 55,60 ****
---- 56,62 ----
- char *keyboard_character_set = NULL;
- UCS *glo_wordseps = NULL; /* points to word separators if set */
- char *glo_wordseps_orig = NULL;
-+ VARS_TO_SAVE *saved_state = NULL;
-
- /* uninitialized global definitions */
- int currow; /* Cursor row */
-***************
-*** 84,89 ****
---- 86,92 ----
-
- /* 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 UCS pat[]; /* Search pattern */
-***************
-*** 149,154 ****
---- 152,158 ----
- extern KBESC_T *kbesc; /* keyboard esc sequence trie */
- #endif /* HAS_TERMCAP/HAS_TERMINFO/VMS */
- extern void *input_cs; /* passed to mbtow() via kbseq() */
-+ extern VARS_TO_SAVE *saved_state;
-
- #endif /* maindef */
-
-diff -rc alpine-2.00/pico/efunc.h alpine-2.00.I.USE/pico/efunc.h
-*** alpine-2.00/pico/efunc.h 2007-11-06 15:51:13.000000000 -0800
---- alpine-2.00.I.USE/pico/efunc.h 2011-02-07 20:33:44.000000000 -0800
-***************
-*** 53,60 ****
---- 53,64 ----
- extern int backline(int, int);
- extern int gotobop(int, int);
- extern int gotoeop(int, int);
-+ extern int pineaccent(int, int);
-+ extern unsigned char accent(UCS, UCS);
-+ extern unsigned char GetAccent(void);
- extern int forwpage(int, int);
- extern int backpage(int, int);
-+ extern int deltext (int, int);
- extern int scrollupline(int, int);
- extern int scrolldownline(int, int);
- extern int scrollto(int, int);
-***************
-*** 248,257 ****
- extern int fillpara(int, int);
- extern int fillbuf(int, int);
- extern int inword(void);
-! extern int quote_match(UCS *, LINE *, UCS *, size_t);
- extern int ucs4_isalnum(UCS);
- extern int ucs4_isalpha(UCS);
- extern int ucs4_isspace(UCS);
- extern int ucs4_ispunct(UCS);
-
- #endif /* EFUNC_H */
---- 252,268 ----
- extern int fillpara(int, int);
- extern int fillbuf(int, int);
- extern int inword(void);
-! extern int quote_match(char *, LINE *, char *, size_t, int);
-! extern char *default_qstr(void);
-! extern void flatten_qstring(QSTRING_S *, char *, int);
-! extern void free_qs(QSTRING_S **);
-! extern QSTRING_S *do_quote_match (char *, char *, char *, char *, char *, int, int);
-! extern QSTRING_S *do_raw_quote_match(char *, char *, char *, char *, QSTRING_S **, QSTRING_S **);
-! extern int indent_match(char *, LINE *, char *, int, int);
- extern int ucs4_isalnum(UCS);
- extern int ucs4_isalpha(UCS);
- extern int ucs4_isspace(UCS);
- extern int ucs4_ispunct(UCS);
-
- #endif /* EFUNC_H */
-+
-diff -rc alpine-2.00/pico/file.c alpine-2.00.I.USE/pico/file.c
-*** alpine-2.00/pico/file.c 2008-06-11 10:21:24.000000000 -0700
---- alpine-2.00.I.USE/pico/file.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 331,338 ****
- #endif /* !(DOS || MAC) */
- case HELPCH:
- if(Pmaster){
-- VARS_TO_SAVE *saved_state;
--
- saved_state = save_pico_state();
- (*Pmaster->helper)(msg ? Pmaster->ins_m_help
- : Pmaster->ins_help,
---- 331,336 ----
-diff -rc alpine-2.00/pico/line.c alpine-2.00.I.USE/pico/line.c
-*** alpine-2.00/pico/line.c 2007-08-15 16:07:18.000000000 -0700
---- alpine-2.00.I.USE/pico/line.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 607,620 ****
- lisblank(LINE *line)
- {
- int n = 0;
-! UCS qstr[NLINE];
-
-! n = (glo_quote_str
-! && quote_match(glo_quote_str, line, qstr, NLINE))
-! ? ucs4_strlen(qstr) : 0;
-
- for(; n < llength(line); n++)
-! if(!ucs4_isspace(lgetc(line, n).c))
- return(FALSE);
-
- return(TRUE);
---- 607,618 ----
- lisblank(LINE *line)
- {
- int n = 0;
-! char qstr[NLINE];
-
-! n = quote_match(default_qstr(), line, qstr, NLINE, 1);
-
- for(; n < llength(line); n++)
-! if(!ISspace(lgetc(line, n).c))
- return(FALSE);
-
- return(TRUE);
-diff -rc alpine-2.00/pico/main.c alpine-2.00.I.USE/pico/main.c
-*** alpine-2.00/pico/main.c 2008-04-02 15:09:20.000000000 -0700
---- alpine-2.00.I.USE/pico/main.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 162,167 ****
---- 162,168 ----
- char *file_to_edit = NULL;
- char *display_charmap = NULL;
- char *keyboard_charmap = NULL;
-+ int line_information_on = FALSE;
- int use_system = 0;
- char *err = NULL;
-
-***************
-*** 187,193 ****
- if(display_character_set)
- display_charmap = cpstr(display_character_set);
- #if HAVE_LANGINFO_H && defined(CODESET)
-! else
- display_charmap = cpstr(nl_langinfo_codeset_wrapper());
- #endif
-
---- 188,194 ----
- if(display_character_set)
- display_charmap = cpstr(display_character_set);
- #if HAVE_LANGINFO_H && defined(CODESET)
-! else if (nl_langinfo_codeset_wrapper() != NULL)
- display_charmap = cpstr(nl_langinfo_codeset_wrapper());
- #endif
-
-***************
-*** 415,420 ****
---- 416,427 ----
- emlwrite(_("You may possibly have new mail."), NULL);
- }
-
-+ if (c == (CTRL|'\\')){
-+ c = GetAccent();
-+ if (!c)
-+ c = NODATA;
-+ }
-+
- if(km_popped)
- switch(c){
- case NODATA:
-***************
-*** 436,449 ****
- mlerase();
- }
-
-! f = FALSE;
- n = 1;
-
- #ifdef MOUSE
- clear_mfunc(mouse_in_content);
- #endif
- /* Do it. */
- execute(normalize_cmd(c, fkm, 1), f, n);
- }
- }
-
---- 443,471 ----
- 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|'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'));
-
- #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 alpine-2.00/pico/osdep/getkey.c alpine-2.00.I.USE/pico/osdep/getkey.c
-*** alpine-2.00/pico/osdep/getkey.c 2007-08-20 12:46:37.000000000 -0700
---- alpine-2.00.I.USE/pico/osdep/getkey.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 130,135 ****
---- 130,145 ----
- {
- UCS ch, status, cc;
-
-+ if(sendnow){
-+ ch = Pmaster && Pmaster->auto_cmds && *Pmaster->auto_cmds
-+ ? *Pmaster->auto_cmds++ : NODATA;
-+
-+ if (ch >= 0x00 && ch <= 0x1F)
-+ ch = CTRL | (ch+'@');
-+
-+ return(ch);
-+ }
-+
- if(!ReadyForKey(FUDGE-5))
- return(NODATA);
-
-diff -rc alpine-2.00/pico/osdep/terminal.c alpine-2.00.I.USE/pico/osdep/terminal.c
-*** alpine-2.00/pico/osdep/terminal.c 2008-01-29 15:21:10.000000000 -0800
---- alpine-2.00.I.USE/pico/osdep/terminal.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 25,30 ****
---- 25,31 ----
- #include "../keydefs.h"
- #include "../pico.h"
- #include "../mode.h"
-+ #include "../edef.h"
-
- #include "raw.h"
- #include "color.h"
-***************
-*** 477,482 ****
---- 478,489 ----
- {
- 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 ...
-***************
-*** 1252,1257 ****
---- 1259,1270 ----
- {
- 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 alpine-2.00/pico/osdep/tty.c alpine-2.00.I.USE/pico/osdep/tty.c
-*** alpine-2.00/pico/osdep/tty.c 2007-08-15 16:07:18.000000000 -0700
---- alpine-2.00.I.USE/pico/osdep/tty.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 223,229 ****
- int row = -1, col = -1;
-
- ttgetwinsz(&row, &col);
-! resize_pico(row, col);
- }
-
-
---- 223,236 ----
- int row = -1, col = -1;
-
- ttgetwinsz(&row, &col);
-! if(saved_state == NULL || wheadp != NULL)
-! resize_pico(row, col);
-! else{ /* this is awkward */
-! restore_pico_state(saved_state);
-! free_pico_state(saved_state);
-! resize_pico(row,col);
-! saved_state = save_pico_state();
-! }
- }
-
-
-diff -rc alpine-2.00/pico/pico.c alpine-2.00.I.USE/pico/pico.c
-*** alpine-2.00/pico/pico.c 2008-01-30 16:44:12.000000000 -0800
---- alpine-2.00.I.USE/pico/pico.c 2011-02-07 20:33:44.000000000 -0800
-***************
-*** 137,142 ****
---- 137,151 ----
- 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);
-
-***************
-*** 637,648 ****
- result = "";
-
- Pmaster->arm_winch_cleanup++;
- if(Pmaster->canceltest){
- if(((Pmaster->pine_flags & MDHDRONLY) && !any_header_changes())
- || (result = (*Pmaster->canceltest)(redraw_pico_for_callback))){
-- pico_all_done = COMP_CANCEL;
- emlwrite(result, NULL);
- Pmaster->arm_winch_cleanup--;
- return(TRUE);
- }
- else{
---- 646,664 ----
- result = "";
-
- Pmaster->arm_winch_cleanup++;
-+ Pmaster->onctrlc++;
- if(Pmaster->canceltest){
- if(((Pmaster->pine_flags & MDHDRONLY) && !any_header_changes())
- || (result = (*Pmaster->canceltest)(redraw_pico_for_callback))){
- emlwrite(result, NULL);
- Pmaster->arm_winch_cleanup--;
-+ if(Pmaster->curpos[0]){
-+ curwp->w_flag |= WFMODE; /* and modeline so we */
-+ sgarbk = TRUE; /* redraw the keymenu */
-+ pclear(term.t_nrow - 1, term.t_nrow + 1);
-+ return(FALSE);
-+ }
-+ pico_all_done = COMP_CANCEL;
- return(TRUE);
- }
- else{
-***************
-*** 671,676 ****
---- 687,698 ----
- emlwrite(_("\007Cancel Cancelled"), NULL);
- break;
-
-+ case COUNT:
-+ showcpos(1,0);
-+ emlwrite(Pmaster->curpos, NULL);
-+ Pmaster->onctrlc--;
-+ break;
-+
- default:
- mlerase();
- }
-***************
-*** 713,718 ****
---- 735,753 ----
- 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 he already
-+ did */
-+ if (sendnow){
-+ ret = (*Pmaster->exittest)(Pmaster->headents,
-+ redraw_pico_for_callback,
-+ Pmaster->allow_flowed_text,
-+ &result);
-+ if (!ret)
-+ pico_all_done = COMP_EXIT;
-+ return(result ? FALSE : TRUE);
-+ }
-+
- #ifdef SPELLER
- if(Pmaster->always_spell_check)
- if(spell(0, 0) == -1)
-diff -rc alpine-2.00/pico/pico.h alpine-2.00.I.USE/pico/pico.h
-*** alpine-2.00/pico/pico.h 2008-08-22 13:40:16.000000000 -0700
---- alpine-2.00.I.USE/pico/pico.h 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 198,208 ****
---- 198,210 ----
- PCOLORS *colors; /* colors for titlebar and keymenu */
- void *input_cs; /* passed to mbtow() via kbseq() */
- long pine_flags; /* entry mode flags */
-+ char curpos[80]; /* where are we now? */
- /* The next few bits are features that don't fit in pine_flags */
- /* If we had this to do over, it would probably be one giant bitmap */
- unsigned always_spell_check:1; /* always spell-checking upon quit */
- unsigned strip_ws_before_send:1; /* don't default strip bc of flowed */
- unsigned allow_flowed_text:1; /* clean text when done to keep flowed */
-+ unsigned onctrlc; /* are we on ctrl-c command? */
- int (*helper)(); /* Pine's help function */
- int (*showmsg)(); /* Pine's display_message */
- UCS (*suspend)(); /* Pine's suspend */
-***************
-*** 219,225 ****
---- 221,229 ----
- int (*user_says_noflow)(); /* callback to tell us we're not flowing */
- void (*resize)(); /* callback handling screen resize */
- void (*winch_cleanup)(); /* callback handling screen resize */
-+ void (*newthread)(); /* callback to create new thread */
- 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;
-diff -rc alpine-2.00/pico/pilot.c alpine-2.00.I.USE/pico/pilot.c
-*** alpine-2.00/pico/pilot.c 2008-04-02 15:09:20.000000000 -0700
---- alpine-2.00.I.USE/pico/pilot.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 142,148 ****
- if(display_character_set)
- display_charmap = cpstr(display_character_set);
- #if HAVE_LANGINFO_H && defined(CODESET)
-! else
- display_charmap = cpstr(nl_langinfo_codeset_wrapper());
- #endif
-
---- 142,148 ----
- if(display_character_set)
- display_charmap = cpstr(display_character_set);
- #if HAVE_LANGINFO_H && defined(CODESET)
-! else if (nl_langinfo_codeset_wrapper() != NULL)
- display_charmap = cpstr(nl_langinfo_codeset_wrapper());
- #endif
-
-diff -rc alpine-2.00/pico/random.c alpine-2.00.I.USE/pico/random.c
-*** alpine-2.00/pico/random.c 2007-08-15 16:07:18.000000000 -0700
---- alpine-2.00.I.USE/pico/random.c 2011-02-07 20:33:44.000000000 -0800
-***************
-*** 73,79 ****
- thisline+1, lines+1, (int)((100L*(thisline+1))/(lines+1)),
- nbc, nch, (nch) ? (int)((100L*nbc)/nch) : 0);
-
-! emlwrite(buffer, NULL);
- return (TRUE);
- }
-
---- 73,82 ----
- thisline+1, lines+1, (int)((100L*(thisline+1))/(lines+1)),
- nbc, nch, (nch) ? (int)((100L*nbc)/nch) : 0);
-
-! if(Pmaster)
-! strcpy(Pmaster->curpos, buffer);
-! else
-! emlwrite(buffer, NULL);
- return (TRUE);
- }
-
-diff -rc alpine-2.00/pico/search.c alpine-2.00.I.USE/pico/search.c
-*** alpine-2.00/pico/search.c 2008-01-04 14:49:15.000000000 -0800
---- alpine-2.00.I.USE/pico/search.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 35,41 ****
- int readpattern(char *, int);
- int replace_pat(UCS *, int *);
- int replace_all(UCS *, UCS *);
-!
-
- #define FWS_RETURN(RV) { \
- thisflag |= CFSRCH; \
---- 35,41 ----
- int readpattern(char *, int);
- int replace_pat(UCS *, int *);
- int replace_all(UCS *, UCS *);
-! int deletepara(int, int);
-
- #define FWS_RETURN(RV) { \
- thisflag |= CFSRCH; \
-***************
-*** 75,80 ****
---- 75,84 ----
- N_("~ Hitting only ~R~e~t~u~r~n or at the prompt will cause the"),
- N_(" search to be made with the default value."),
- " ",
-+ N_("~ Hitting ~^~N will reinsert the last string you searched for"),
-+ N_(" so that you can edit it (in case you made a mistake entering the"),
-+ N_(" search pattern the first time)."),
-+ " ",
- N_(" The text search is not case sensitive, and will examine the"),
- N_(" entire message."),
- " ",
-***************
-*** 139,146 ****
-
- case HELPCH: /* help requested */
- if(Pmaster){
-- VARS_TO_SAVE *saved_state;
--
- saved_state = save_pico_state();
- (*Pmaster->helper)(Pmaster->search_help,
- _("Help for Searching"), 1);
---- 143,148 ----
-***************
-*** 231,240 ****
---- 233,251 ----
- 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);
-+ FWS_RETURN(TRUE);
-+
- default:
- if(status == ABORT)
- emlwrite(_("Search Cancelled"), NULL);
-***************
-*** 273,279 ****
- }
-
- 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++;
- }
---- 284,290 ----
- }
-
- 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++;
- }
-***************
-*** 430,437 ****
-
- case HELPCH: /* help requested */
- if(Pmaster){
-- VARS_TO_SAVE *saved_state;
--
- saved_state = save_pico_state();
- (*Pmaster->helper)(Pmaster->search_help,
- _("Help for Searching"), 1);
---- 441,446 ----
-***************
-*** 463,470 ****
- break;
-
- default:
-! if(status == ABORT)
- emlwrite(_("Replacement Cancelled"), NULL);
- else{
- mlerase();
- chword(defpat, origpat);
---- 472,481 ----
- break;
-
- default:
-! if(status == ABORT){
- emlwrite(_("Replacement Cancelled"), NULL);
-+ pico_refresh(FALSE, 1);
-+ }
- else{
- mlerase();
- chword(defpat, origpat);
-***************
-*** 597,603 ****
- UCS *b;
- UCS prompt[NPMT];
- UCS *promptp;
-! EXTRAKEYS menu_pat[8];
-
- menu_pat[i = 0].name = "^Y";
- menu_pat[i].label = N_("FirstLine");
---- 608,614 ----
- UCS *b;
- UCS prompt[NPMT];
- UCS *promptp;
-! EXTRAKEYS menu_pat[10];
-
- menu_pat[i = 0].name = "^Y";
- menu_pat[i].label = N_("FirstLine");
-***************
-*** 615,620 ****
---- 626,636 ----
- KS_OSDATASET(&menu_pat[i], KS_NONE);
-
- if(!repl_mode){
-+ menu_pat[++i].name = "^X";
-+ menu_pat[i].label = N_("DelEnd");
-+ menu_pat[i].key = (CTRL|'X');
-+ KS_OSDATASET(&menu_pat[i], KS_NONE);
-+
- menu_pat[++i].name = "^T";
- menu_pat[i].label = N_("LineNumber");
- menu_pat[i].key = (CTRL|'T');
-***************
-*** 631,636 ****
---- 647,657 ----
- menu_pat[i].key = (CTRL|'O');
- KS_OSDATASET(&menu_pat[i], KS_NONE);
-
-+ menu_pat[++i].name = "^P";
-+ menu_pat[i].label = N_("Delete Para");
-+ menu_pat[i].key = (CTRL|'P');
-+ KS_OSDATASET(&menu_pat[i], KS_NONE);
-+
- menu_pat[++i].name = "^U";
- /* TRANSLATORS: Instead of justifying (formatting) just a
- single paragraph, Full Justify justifies the entire
-***************
-*** 766,772 ****
- UCS *b;
- UCS tpat[NPAT+20];
- UCS *tpatp;
-! EXTRAKEYS menu_pat[7];
-
- menu_pat[i = 0].name = "^Y";
- menu_pat[i].label = N_("FirstLine");
---- 787,793 ----
- UCS *b;
- UCS tpat[NPAT+20];
- UCS *tpatp;
-! EXTRAKEYS menu_pat[9];
-
- menu_pat[i = 0].name = "^Y";
- menu_pat[i].label = N_("FirstLine");
-***************
-*** 779,784 ****
---- 800,810 ----
- KS_OSDATASET(&menu_pat[i], KS_NONE);
-
- if(text_mode){
-+ menu_pat[++i].name = "^X";
-+ menu_pat[i].label = N_("DelEnd");
-+ menu_pat[i].key = (CTRL|'X');
-+ KS_OSDATASET(&menu_pat[i], KS_NONE);
-+
- menu_pat[++i].name = "^T";
- menu_pat[i].label = N_("LineNumber");
- menu_pat[i].key = (CTRL|'T');
-***************
-*** 794,799 ****
---- 820,830 ----
- menu_pat[i].key = (CTRL|'O');
- KS_OSDATASET(&menu_pat[i], KS_NONE);
-
-+ menu_pat[++i].name = "^P";
-+ menu_pat[i].label = N_("Delete Para");
-+ menu_pat[i].key = (CTRL|'P');
-+ KS_OSDATASET(&menu_pat[i], KS_NONE);
-+
- menu_pat[++i].name = "^U";
- menu_pat[i].label = N_("FullJustify");
- menu_pat[i].key = (CTRL|'U');
-***************
-*** 924,930 ****
- 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;
---- 955,961 ----
- 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;
-***************
-*** 945,951 ****
- return(FALSE);
-
- /* and test it against the pattern */
-! if (eq(*patptr, c) == FALSE)
- goto fail;
- }
-
---- 976,982 ----
- return(FALSE);
-
- /* and test it against the pattern */
-! if (eq((unsigned char) *patptr, c) == FALSE)
- goto fail;
- }
-
-***************
-*** 1032,1034 ****
---- 1063,1087 ----
-
- curwp->w_flag |= WFEDIT;
- }
-+
-+ int
-+ deletepara(int f, int n) /* Delete the current paragraph */
-+ {
-+ 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 = 0;
-+
-+ 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 alpine-2.00/pico/word.c alpine-2.00.I.USE/pico/word.c
-*** alpine-2.00/pico/word.c 2007-08-20 12:46:37.000000000 -0700
---- alpine-2.00.I.USE/pico/word.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 24,33 ****
- */
-
- #include "headers.h"
-!
-
- int fpnewline(UCS *quote);
-! int fillregion(UCS *qstr, REGION *addedregion);
- int setquotelevelinregion(int quotelevel, REGION *addedregion);
- int is_user_separator(UCS c);
-
---- 24,33 ----
- */
-
- #include "headers.h"
-! #include "../pith/osdep/color.h"
-
- int fpnewline(UCS *quote);
-! int fillregion(UCS *qstr, UCS *istr, REGION *addedregion);
- int setquotelevelinregion(int quotelevel, REGION *addedregion);
- int is_user_separator(UCS c);
-
-***************
-*** 430,471 ****
- return 0;
- }
-
-
- /*
- * Return number of quotes if whatever starts the line matches the quote string
- */
- int
-! quote_match(UCS *q, LINE *l, UCS *buf, size_t buflen)
- {
-! register int i, n, j, qb;
-
-! *buf = '\0';
-! if(*q == '\0')
-! return(1);
-!
-! qb = (ucs4_strlen(q) > 1 && q[ucs4_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(ucs4_strlen(buf) + ucs4_strlen(q) + 1 < buflen){
-! ucs4_strncat(buf, q, buflen-ucs4_strlen(q)-1);
-! buf[buflen-1] = '\0';
-! if(qb && (j > llength(l) || lgetc(l, j).c != ' '))
-! buf[ucs4_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 */
- int
---- 430,600 ----
- return 0;
- }
-
-+ /* Support of indentation of paragraphs */
-+ #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 indent_match(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 iscontrol(c) (iscntrl(((int) (c)) & 0x7f) ? 1 : 0)
-+ #define forbidden(c) (((c) == '\"') || ((c) == '\'') || ((c) == '$') ||\
-+ ((c) == ',') || ((c) == '.') || ((c) == '-') ||\
-+ ((c) == LPAREN) || ((c) == '/')|| ((c) == '`') ||\
-+ ((c) == '{') || ((c) == '\\') || (iscontrol((c))) ||\
-+ (((c) >= '0') && ((c) <= '9')) || ((c) == '?'))
-+ #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_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))
-+ #define qs_allowed(a) (((a)->qstype != qsGdb) && ((a)->qstype != qsProg))
-+
-+ /* Internal justification functions */
-+ QSTRING_S *qs_quote_match(char *, LINE *, char *, int);
-+ int ucs4_strlenis(UCS *);
-+ void linencpy(char *, LINE *, int);
-+
-+
-+ char *
-+ default_qstr(void)
-+ {
-+ char *default_qs;
-+ static char ucs_def[NSTRING] = {'\0'};
-+
-+ if(ucs_def[0] == '\0'){
-+ default_qs = ucs4_to_utf8_cpystr(glo_quote_str);
-+ strncpy(ucs_def, (default_qs ? default_qs : ""), NSTRING);
-+ fs_give((void **)&default_qs);
-+ }
-+
-+ return glo_quote_str ? ucs_def : "";
-+ }
-+
-+ void
-+ linencpy(word, l, buflen)
-+ char word[NSTRING];
-+ LINE *l;
-+ int buflen;
-+ {
-+ int i;
-+ UCS ucs_word[NSTRING];
-+ char *utf_word;
-+
-+ word[0] = '\0';
-+ if(l){
-+ for (i = 0; i < buflen && i < llength(l)
-+ && (ucs_word[i] = lgetc(l,i).c); i++);
-+ ucs_word[i == buflen ? i-1 : i] = '\0';
-+ utf_word = ucs4_to_utf8_cpystr(ucs_word);
-+ strncpy(word, utf_word, (NSTRING < buflen ? NSTRING : buflen));
-+ word[NSTRING-1] = '\0';
-+ if(utf_word) fs_give((void **)&utf_word);
-+ }
-+ }
-+
-+ /*
-+ * 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(char *q, LINE *l, char *rqstr, int rqstrlen)
-+ {
-+ char GLine[NSTRING], NLine[NSTRING], PLine[NSTRING];
-+ LINE *nl = l != curbp->b_linep ? lforw(l) : NULL;
-+ LINE *pl = lback(l) != curbp->b_linep ? lback(l) : NULL;
-+ int plb = 1;
-+
-+ linencpy(GLine, l, NSTRING);
-+ linencpy(NLine, nl, NSTRING);
-+
-+ if (pl){
-+ linencpy(PLine, pl, NSTRING);
-+ if(lback(pl) != curbp->b_linep){
-+ char PPLine[NSTRING];
-+
-+ linencpy(PPLine, lback(pl), NSTRING);
-+ plb = line_isblank(q, PLine, GLine, PPLine, NSTRING);
-+ }
-+ }
-+ return do_quote_match(q, GLine, NLine, PLine, rqstr, rqstrlen, plb);
-+ }
-
- /*
- * Return number of quotes if whatever starts the line matches the quote string
-+ * rqstring is pointer to raw qstring, buf points to processed qstring
- */
- int
-! quote_match(char *q, LINE *l, char *buf, size_t buflen, int raw)
- {
-! QSTRING_S *qs;
-! char rqstr[NSTRING];
-
-! qs = qs_quote_match(q, l, rqstr, NSTRING);
-! flatten_qstring(qs, buf, buflen);
-! if (qs)
-! free_qs(&qs);
-!
-! if(raw){
-! strncpy(buf, rqstr, buflen < NSTRING ? buflen : NSTRING);
-! buf[buflen-1] = '\0';
- }
-!
-! return buf && buf[0] ? strlen(buf) : 0;
- }
-
-+ int ucs4_strlenis(UCS *ucs_qstr)
-+ {
-+ char *str = ucs4_to_utf8_cpystr(ucs_qstr);
-+ int i = (int) strlenis(str);
-+
-+ if(str) fs_give((void **)&str);
-+ return i;
-+ }
-
- /* Justify the entire buffer instead of just a paragraph */
- int
-***************
-*** 720,725 ****
---- 849,855 ----
- }
-
- if(action == 'R' && curwp->w_markp){
-+ char qstrfl[NSTRING];
- /* let yank() know that it may be restoring a paragraph */
- thisflag |= CFFILL;
-
-***************
-*** 732,752 ****
-
- /* determine if we're justifying quoted text or not */
- qstr = (glo_quote_str
-! && quote_match(glo_quote_str,
-! curwp->w_doto > 0 ? curwp->w_dotp->l_fp : curwp->w_dotp,
-! qstr2, NSTRING)
-! && *qstr2) ? qstr2 : NULL;
-!
-
- /*
- * Fillregion moves dot to the end of the filled region.
- */
-! if(!fillregion(qstr, &addedregion))
- return(FALSE);
-
- set_last_region_added(&addedregion);
- }
- else if(action == 'P'){
-
- /*
- * Justfiy the current paragraph.
---- 862,886 ----
-
- /* determine if we're justifying quoted text or not */
- qstr = (glo_quote_str
-! && quote_match(default_qstr(),
-! (curwp->w_doto > 0 ? curwp->w_dotp->l_fp : curwp->w_dotp),
-! qstrfl, NSTRING, 0)
-! && *qstrfl) ? utf8_to_ucs4_cpystr(qstrfl) : NULL;
-
- /*
- * Fillregion moves dot to the end of the filled region.
- */
-! if(!fillregion(qstr, NULL, &addedregion))
- return(FALSE);
-
- set_last_region_added(&addedregion);
-+
-+ if(qstr)
-+ fs_give((void **)&qstr);
- }
- else if(action == 'P'){
-+ char ind_str[NSTRING], qstrfl[NSTRING];
-+ UCS *istr;
-
- /*
- * Justfiy the current paragraph.
-***************
-*** 758,774 ****
- if(gotoeop(FALSE, 1) == FALSE)
- return(FALSE);
-
-- /* determine if we're justifying quoted text or not */
-- qstr = (glo_quote_str
-- && quote_match(glo_quote_str,
-- curwp->w_dotp, qstr2, NSTRING)
-- && *qstr2) ? qstr2 : NULL;
--
- setmark(0,0); /* mark last line of para */
-
- /* jump back to the beginning of the paragraph */
- gotobop(FALSE, 1);
-
- /* let yank() know that it may be restoring a paragraph */
- thisflag |= (CFFILL | CFFLPA);
-
---- 892,907 ----
- if(gotoeop(FALSE, 1) == FALSE)
- return(FALSE);
-
- setmark(0,0); /* mark last line of para */
-
- /* jump back to the beginning of the paragraph */
- gotobop(FALSE, 1);
-
-+ istr = indent_match(default_qstr(), curwp->w_dotp, ind_str, NSTRING, 0)
-+ && *ind_str ? utf8_to_ucs4_cpystr(ind_str) : NULL;
-+ qstr = (quote_match(default_qstr(), curwp->w_dotp, qstrfl, NSTRING, 0)
-+ && *qstrfl) ? utf8_to_ucs4_cpystr(qstrfl) : NULL;
-+
- /* let yank() know that it may be restoring a paragraph */
- thisflag |= (CFFILL | CFFLPA);
-
-***************
-*** 782,790 ****
- /*
- * Fillregion moves dot to the end of the filled region.
- */
-! if(!fillregion(qstr, &addedregion))
- return(FALSE);
-
- set_last_region_added(&addedregion);
-
- /* Leave cursor on first char of first line after justified region */
---- 915,929 ----
- /*
- * Fillregion moves dot to the end of the filled region.
- */
-! if(!fillregion(qstr, istr, &addedregion))
- return(FALSE);
-
-+ if(qstr)
-+ fs_give((void **)&qstr);
-+
-+ if(istr)
-+ fs_give((void **)&istr);
-+
- set_last_region_added(&addedregion);
-
- /* Leave cursor on first char of first line after justified region */
-***************
-*** 826,841 ****
- * can delete it and restore the saved part.
- */
- int
-! fillregion(UCS *qstr, REGION *addedregion)
- {
- long c, sz, last_char = 0;
-! int i, j, qlen, same_word,
- spaces, word_len, word_ind, line_len, ww;
- int starts_midline = 0;
- int ends_midline = 0;
- int offset_into_start;
- LINE *line_before_start, *lp;
-! UCS line_last, word[NSTRING];
- REGION region;
-
- /* if region starts midline insert a newline */
---- 965,980 ----
- * can delete it and restore the saved part.
- */
- int
-! fillregion(UCS *qstr, UCS *istr, REGION *addedregion)
- {
- long c, sz, last_char = 0;
-! int i, j, qlen, same_word, qi, pqi, qlenis,
- spaces, word_len, word_ind, line_len, ww;
- int starts_midline = 0;
- int ends_midline = 0;
- int offset_into_start;
- LINE *line_before_start, *lp;
-! UCS line_last, word[NSTRING], quoid[NSTRING], qstr2[NSTRING];
- REGION region;
-
- /* if region starts midline insert a newline */
-***************
-*** 846,851 ****
---- 985,1019 ----
- if(curwp->w_marko > 0 && curwp->w_marko < llength(curwp->w_markp))
- ends_midline++;
-
-+ for (i = 0; (i < NSTRING) && qstr && (quoid[i] = qstr[i]); i++);
-+ for (j = 0; ((i + j) < NSTRING) && istr && (quoid[i] = istr[j]); i++,j++);
-+ quoid[i] = '\0';
-+ qi = ucs4_strlen(quoid);
-+ if (istr) /* strip trailing spaces */
-+ for (;ISspace(quoid[qi - 1]); qi--);
-+ quoid[qi] = '\0'; /* we have closed quoid at "X" in the first line */
-+
-+ if (ucs4_strlenis(quoid) > fillcol)
-+ return FALSE; /* Too wide, we can't justify this! */
-+
-+ if (qstr && istr){
-+ for (i = ucs4_strlen(qstr) - 1; ISspace(qstr[i]); i--);
-+ qstr[i + 1] = '\0'; /* qstrfl */
-+ }
-+ qlen = ucs4_strlen(qstr); /* qstrfl*/
-+ qlenis = ucs4_strlenis(qstr);
-+
-+ for(i = 0, qstr2[0] = '\0'; qstr && qstr[i] && (qstr2[i] = qstr[i]); i++);
-+
-+ if (istr && ((j = ucs4_strlenis(quoid) - ucs4_strlenis(qstr)) > 0)){
-+ pqi = ucs4_strlen(qstr);
-+ for (i = 0; (i < j) && (qstr2[pqi + i] = ' '); i++);
-+ if (ISspace(istr[ucs4_strlen(istr) - 1]))
-+ qstr2[pqi + i++] = ' ';
-+ qstr2[pqi + i] = '\0';
-+ qstr = qstr2;
-+ }
-+
- /* cut the paragraph into our fill buffer */
- fdelete();
- if(!getregion(&region, curwp->w_markp, curwp->w_marko))
-***************
-*** 862,889 ****
-
- /* Now insert it back wrapped */
- spaces = word_len = word_ind = line_len = same_word = 0;
-- qlen = qstr ? ucs4_strlen(qstr) : 0;
-
- /* Beginning with leading quoting... */
-! if(qstr){
-! i = 0;
-! while(qstr[i]){
-! ww = wcellwidth(qstr[i]);
-! line_len += (ww >= 0 ? ww : 1);
-! linsert(1, qstr[i++]);
-! }
-
- line_last = ' '; /* no word-flush space! */
- }
-
- /* remove first leading quotes if any */
- if(starts_midline)
- i = 0;
-! else
-! for(i = qlen; (c = fremove(i)) == ' ' || c == TAB; i++){
- linsert(1, line_last = (UCS) c);
- line_len += ((c == TAB) ? (~line_len & 0x07) + 1 : 1);
- }
-
- /* then digest the rest... */
- while((c = fremove(i++)) >= 0){
---- 1030,1065 ----
-
- /* Now insert it back wrapped */
- spaces = word_len = word_ind = line_len = same_word = 0;
-
- /* Beginning with leading quoting... */
-! if(qstr || istr){
-! for(i = 0; quoid[i] != '\0' ; i++)
-! linsert(1, quoid[i]);
-
- line_last = ' '; /* no word-flush space! */
-+ line_len = ucs4_strlenis(quoid); /* we demand a recount! */
- }
-
- /* remove first leading quotes if any */
- if(starts_midline)
- i = 0;
-! else{
-! if(qstr || istr){
-! for (i = 0; (c = fremove(i)) != '\0'; i++){
-! word[i] = c;
-! word[i+1] = '\0';
-! if(ucs4_strlenis(word) >= ucs4_strlenis(quoid))
-! break;
-! }
-! i++;
-! }
-! else
-! i = 0;
-! for(; ISspace(c = fremove(i)); i++){
- linsert(1, line_last = (UCS) c);
- line_len += ((c == TAB) ? (~line_len & 0x07) + 1 : 1);
- }
-+ }
-
- /* then digest the rest... */
- while((c = fremove(i++)) >= 0){
-***************
-*** 905,925 ****
-
- case TAB :
- case ' ' :
- spaces++;
- same_word = 0;
- break;
-
- default :
- if(spaces){ /* flush word? */
-! if((line_len - qlen > 0)
- && line_len + word_len + 1 > fillcol
-! && ((ucs4_isspace(line_last))
- || (linsert(1, ' ')))
- && (line_len = fpnewline(qstr)))
- line_last = ' '; /* no word-flush space! */
-
- if(word_len){ /* word to write? */
-! if(line_len && !ucs4_isspace(line_last)){
- linsert(1, ' '); /* need padding? */
- line_len++;
- }
---- 1081,1102 ----
-
- case TAB :
- case ' ' :
-+ case NBSP:
- spaces++;
- same_word = 0;
- break;
-
- default :
- if(spaces){ /* flush word? */
-! if((line_len - qlenis > 0)
- && line_len + word_len + 1 > fillcol
-! && ((ISspace(line_last))
- || (linsert(1, ' ')))
- && (line_len = fpnewline(qstr)))
- line_last = ' '; /* no word-flush space! */
-
- if(word_len){ /* word to write? */
-! if(line_len && !ISspace(line_last)){
- linsert(1, ' '); /* need padding? */
- line_len++;
- }
-***************
-*** 941,948 ****
-
- if(word_ind + 1 >= NSTRING){
- /* Magic! Fake that we output a wrapped word */
-! if((line_len - qlen > 0) && !same_word++){
-! if(!ucs4_isspace(line_last))
- linsert(1, ' ');
- line_len = fpnewline(qstr);
- }
---- 1118,1125 ----
-
- if(word_ind + 1 >= NSTRING){
- /* Magic! Fake that we output a wrapped word */
-! if((line_len - qlenis > 0) && !same_word++){
-! if(!ISspace(line_last))
- linsert(1, ' ');
- line_len = fpnewline(qstr);
- }
-***************
-*** 964,975 ****
- }
-
- if(word_len){
-! if((line_len - qlen > 0) && (line_len + word_len + 1 > fillcol)){
-! if(!ucs4_isspace(line_last))
- linsert(1, ' ');
- (void) fpnewline(qstr);
- }
-! else if(line_len && !ucs4_isspace(line_last))
- linsert(1, ' ');
-
- for(j = 0; j < word_ind; j++)
---- 1141,1152 ----
- }
-
- if(word_len){
-! if((line_len - qlenis > 0) && (line_len + word_len + 1 > fillcol)){
-! if(!ISspace(line_last))
- linsert(1, ' ');
- (void) fpnewline(qstr);
- }
-! else if(line_len && !ISspace(line_last))
- linsert(1, ' ');
-
- for(j = 0; j < word_ind; j++)
-***************
-*** 1027,1037 ****
- int len;
-
- lnewline();
-! for(len = 0; quote && *quote; quote++){
- int ww;
-
-! ww = wcellwidth(*quote);
-! len += (ww >= 0 ? ww : 1);
- linsert(1, *quote);
- }
-
---- 1204,1214 ----
- int len;
-
- lnewline();
-! for(len = ucs4_strlenis(quote); quote && *quote; quote++){
- int ww;
-
-! /* ww = wcellwidth(*quote);
-! len += (ww >= 0 ? ww : 1);*/
- linsert(1, *quote);
- }
-
-***************
-*** 1175,1179 ****
---- 1352,1396 ----
- markregion(1);
- }
-
-+ /*
-+ * This puts us at the end of the quoted region instead
-+ * of on the following line. This makes it convenient
-+ * for the user to follow a quotelevel adjustment with
-+ * a Justify if desired.
-+ */
-+ if(backuptoprevline){
-+ curwp->w_doto = 0;
-+ backchar(0, 1);
-+ }
-+
-+ if(ends_midline){ /* doesn't need fixing otherwise */
-+ unmarkbuffer();
-+ markregion(1);
-+ }
-+
- return (TRUE);
- }
-+
-+ /*
-+ * If there is an indent string this function returns
-+ * its length
-+ */
-+ int
-+ indent_match(char *q, LINE *l, char *buf, int buflen, int raw)
-+ {
-+ char GLine[NSTRING];
-+ int i, 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(lgetc(lback(l), i).c); i--);
-+ if (EOLchar(lgetc(lback(l), i).c))
-+ plb++;
-+ }
-+
-+ return get_indent_raw_line(q, GLine, buf, buflen, k, plb);
-+ }
-+
-diff -rc alpine-2.00/pith/adrbklib.c alpine-2.00.I.USE/pith/adrbklib.c
-*** alpine-2.00/pith/adrbklib.c 2008-06-03 08:54:15.000000000 -0700
---- alpine-2.00.I.USE/pith/adrbklib.c 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 5119,5126 ****
- 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;
---- 5119,5132 ----
- 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 alpine-2.00/pith/charconv/utf8.c alpine-2.00.I.USE/pith/charconv/utf8.c
-*** alpine-2.00/pith/charconv/utf8.c 2008-04-02 15:09:20.000000000 -0700
---- alpine-2.00.I.USE/pith/charconv/utf8.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 1048,1053 ****
---- 1048,1103 ----
-
-
- /*
-+ * Returns the screen cells width of the UTF-8 string argument, treating tabs
-+ * in a special way.
-+ */
-+ unsigned
-+ utf8_widthis(char *str)
-+ {
-+ unsigned width = 0;
-+ int this_width;
-+ UCS ucs;
-+ unsigned long remaining_octets;
-+ char *readptr;
-+
-+ if(!(str && *str))
-+ return(width);
-+
-+ readptr = str;
-+ remaining_octets = readptr ? strlen(readptr) : 0;
-+
-+ while(remaining_octets > 0 && *readptr){
-+
-+ ucs = (UCS) utf8_get((unsigned char **) &readptr, &remaining_octets);
-+
-+ if(ucs & U8G_ERROR){
-+ /*
-+ * This should not happen, but do something to handle it anyway.
-+ * Treat each character as a single width character, which is what should
-+ * probably happen when we actually go to write it out.
-+ */
-+ remaining_octets--;
-+ readptr++;
-+ this_width = 1;
-+ }
-+ else{
-+ this_width = (ucs == TAB) ? ((~width & 0x07) + 1) : wcellwidth(ucs);
-+
-+ /*
-+ * If this_width is -1 that means we can't print this character
-+ * with our current locale. Writechar will print a '?'.
-+ */
-+ if(this_width < 0)
-+ this_width = 1;
-+ }
-+
-+ width += (unsigned) this_width;
-+ }
-+
-+ return(width);
-+ }
-+
-+ /*
- * Copy UTF-8 characters from src into dst.
- * This is intended to be used if you want to truncate a string at
- * the start instead of the end. For example, you have a long string
-diff -rc alpine-2.00/pith/charconv/utf8.h alpine-2.00.I.USE/pith/charconv/utf8.h
-*** alpine-2.00/pith/charconv/utf8.h 2008-04-02 15:09:20.000000000 -0700
---- alpine-2.00.I.USE/pith/charconv/utf8.h 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 80,85 ****
---- 80,86 ----
- UCS *ucs4_strchr(UCS *s, UCS c);
- UCS *ucs4_strrchr(UCS *s, UCS c);
- unsigned utf8_width(char *);
-+ unsigned utf8_widthis(char *);
- size_t utf8_to_width_rhs(char *, char *, size_t, unsigned);
- int utf8_snprintf(char *, size_t, char *, ...);
- size_t utf8_to_width(char *, char *, size_t, unsigned, unsigned *);
-diff -rc alpine-2.00/pith/color.c alpine-2.00.I.USE/pith/color.c
-*** alpine-2.00/pith/color.c 2007-08-15 13:28:09.000000000 -0700
---- alpine-2.00.I.USE/pith/color.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 20,26 ****
- #include "../pith/state.h"
- #include "../pith/conf.h"
- #include "../pith/filter.h"
-!
-
- char *
- color_embed(char *fg, char *bg)
---- 20,27 ----
- #include "../pith/state.h"
- #include "../pith/conf.h"
- #include "../pith/filter.h"
-! #include "../pith/mailview.h"
-! #include "../pico/estruct.h"
-
- char *
- color_embed(char *fg, char *bg)
-***************
-*** 69,91 ****
- struct quote_colors *next;
- };
-
-
- int
- color_a_quote(long int linenum, char *line, 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;
-
- /*
---- 70,179 ----
- struct quote_colors *next;
- };
-
-+ int
-+ is_word (buf, i, j)
-+ char buf[NSTRING];
-+ int i, 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, 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
-+ 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(long int linenum, char *line, LT_INS_S **ins, void *is_flowed_msg)
- {
-! int countem = 0, i, j = 0;
- struct variable *vars = ps_global->vars;
-! char *p, buf[NSTRING] = {'\0'};
- struct quote_colors *colors = NULL, *cp, *next;
- COLOR_PAIR *col = NULL;
- int is_flowed = is_flowed_msg ? *((int *)is_flowed_msg) : 0;
-+ int code;
-+
-+ code = (is_flowed ? IS_FLOWED : NO_FLOWED) | COLORAQUO;
-+ select_quote(linenum, line, ins, (void *) &code);
-+ strncpy(buf, tmp_20k_buf, NSTRING < SIZEOF_20KBUF ? NSTRING : SIZEOF_20KBUF);
-+ buf[sizeof(buf)-1] = '\0';
-
- p = line;
-! for(i = 0; isspace((unsigned char)buf[i]); i++, p++);
-
-! if(buf[i]){
- struct quote_colors *c;
-
- /*
-***************
-*** 134,140 ****
- free_color_pair(&col);
-
- cp = NULL;
-! while(*p == '>'){
- cp = (cp && cp->next) ? cp->next : colors;
-
- if(countem > 0)
---- 222,228 ----
- free_color_pair(&col);
-
- cp = NULL;
-! while(buf[i]){
- cp = (cp && cp->next) ? cp->next : colors;
-
- if(countem > 0)
-***************
-*** 144,153 ****
-
- countem = (countem == 1) ? 0 : countem;
-
-! p++;
-! if(!is_flowed)
-! for(; isspace((unsigned char)*p); p++)
-! ;
- }
-
- if(colors){
---- 232,240 ----
-
- 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){
-***************
-*** 210,216 ****
- }
- }
-
-! return(0);
- }
-
-
---- 297,303 ----
- }
- }
-
-! return(1);
- }
-
-
-diff -rc alpine-2.00/pith/color.h alpine-2.00.I.USE/pith/color.h
-*** alpine-2.00/pith/color.h 2007-05-08 16:38:08.000000000 -0700
---- alpine-2.00.I.USE/pith/color.h 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 21,26 ****
---- 21,44 ----
- #include "../pith/pattern.h"
- #include "../pith/osdep/color.h"
-
-+ #define NO_FLOWED 0x0000
-+ #define IS_FLOWED 0x0001
-+ #define DELETEQUO 0x0010
-+ #define COLORAQUO 0x0100
-+ #define RAWSTRING 0x1000
-+
-+ /* This is needed for justification, I will move it to a better place later
-+ * or maybe not
-+ */
-+ #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) == ']'))
-
- typedef struct spec_color_s {
- int inherit; /* this isn't a color, it is INHERIT */
-***************
-*** 80,85 ****
---- 98,104 ----
- /* exported protoypes */
- char *color_embed(char *, char *);
- int colorcmp(char *, char *);
-+ int next_level_quote(char *, char **, int, int);
- int color_a_quote(long, char *, LT_INS_S **, void *);
- void free_spec_colors(SPEC_COLOR_S **);
-
-diff -rc alpine-2.00/pith/conf.c alpine-2.00.I.USE/pith/conf.c
-*** alpine-2.00/pith/conf.c 2008-08-22 17:07:05.000000000 -0700
---- alpine-2.00.I.USE/pith/conf.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 28,33 ****
---- 28,34 ----
- #include "../pith/remote.h"
- #include "../pith/keyword.h"
- #include "../pith/mailview.h"
-+ #include "../pith/rules.h"
- #include "../pith/list.h"
- #include "../pith/status.h"
- #include "../pith/ldap.h"
-***************
-*** 197,208 ****
---- 198,213 ----
-
- CONF_TXT_T cf_text_view_hdr_color[] = "When viewing messages, these are the header colors";
-
-+ CONF_TXT_T cf_text_index_token_color[] = "Colors in which tokens will be displayed in the index screen";
-+
- CONF_TXT_T cf_text_save_msg_name_rule[] = "Determines default folder name for Saves...\n# Choices: default-folder, by-sender, by-from, by-recipient, last-folder-used.\n# Default: \"default-folder\", i.e. \"saved-messages\" (Unix) or \"SAVEMAIL\" (PC).";
-
- CONF_TXT_T cf_text_fcc_name_rule[] = "Determines default name for Fcc...\n# Choices: default-fcc, by-recipient, last-fcc-used.\n# Default: \"default-fcc\" (see also \"default-fcc=\" variable.)";
-
- 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\".";
-***************
-*** 219,230 ****
---- 224,267 ----
-
- CONF_TXT_T cf_text_editor[] = "Specifies the program invoked by ^_ in the Composer,\n# or the \"enable-alternate-editor-implicitly\" feature.";
-
-+ 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 supersede global index format variable in designated folders.";
-+
-+ CONF_TXT_T cf_text_key_def_rules[] = "Allows a user to override keystrokes in certain screens.";
-+
-+ 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_speller[] = "Specifies the program invoked by ^T in the Composer.";
-
- CONF_TXT_T cf_text_deadlets[] = "Specifies the number of dead letter files to keep when canceling.";
-
- 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.";
-***************
-*** 427,432 ****
---- 464,472 ----
-
- CONF_TXT_T cf_text_newsrc_path[] = "Full path and name of NEWSRC file";
-
-+ #ifndef _WINDOWS
-+ 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\"";
-+ #endif
-
- /*----------------------------------------------------------------------
- These are the variables that control a number of pine functions. They
-***************
-*** 517,522 ****
---- 557,564 ----
- NULL, cf_text_fcc_name_rule},
- {"sort-key", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
- NULL, cf_text_sort_key},
-+ {"thread-sort-key", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
-+ NULL, cf_text_thread_sort_key},
- {"addrbook-sort-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
- "Address Book Sort Rule", cf_text_addrbook_sort_rule},
- {"folder-sort-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
-***************
-*** 539,544 ****
---- 581,614 ----
- NULL, cf_text_thread_exp_char},
- {"threading-lastreply-character", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
- "Threading Last Reply Character", cf_text_thread_lastreply_char},
-+ {"threading-display-style-rule", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
-+ "Threading Display Style Rule", cf_text_thread_displaystyle_rule},
-+ {"threading-index-style-rule", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
-+ "Threading Index Style Rule", cf_text_thread_indexstyle_rule},
-+ {"compose-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
-+ "Compose Rules", cf_text_compose_rules},
-+ {"forward-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
-+ "Forward Rules", cf_text_forward_rules},
-+ {"index-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
-+ "Index Rules", cf_text_index_rules},
-+ {"key-definition-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
-+ "Key Definition Rules", cf_text_key_def_rules},
-+ {"replace-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
-+ "Replace Rules", cf_text_replace_rules},
-+ {"reply-indent-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
-+ "Reply Indent Rules", cf_text_reply_indent_rules},
-+ {"reply-leadin-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
-+ "Reply Leadin Rules", cf_text_reply_leadin_rules},
-+ {"reply-subject-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
-+ "Reply Subject Rules", cf_text_reply_subject_rules},
-+ {"save-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
-+ "Save Rules", cf_text_save_rules},
-+ {"smtp-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
-+ "Smtp Rules", cf_text_smtp_rules},
-+ {"sort-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
-+ "Sort Rules", cf_text_sort_rules},
-+ {"startup-rules", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
-+ "Startup Rules", cf_text_startup_rules},
- #ifndef _WINDOWS
- {"display-character-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
- NULL, cf_text_disp_char_set},
-***************
-*** 557,562 ****
---- 627,634 ----
- NULL, cf_text_speller},
- {"composer-wrap-column", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
- NULL, cf_text_fillcol},
-+ {"special-text-color", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
-+ NULL, cf_special_text_color},
- {"reply-indent-string", 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
- NULL, cf_text_replystr},
- {"reply-leadin", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
-***************
-*** 627,632 ****
---- 699,708 ----
- NULL, cf_text_news_active},
- {"news-spool-directory", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
- NULL, cf_text_news_spooldir},
-+ #ifndef _WINDOWS
-+ {"maildir-location", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
-+ "Maildir Location", cf_text_maildir_location},
-+ #endif
- {"upload-command", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
- NULL, cf_text_upload_cmd},
- {"upload-command-prefix", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
-***************
-*** 788,793 ****
---- 864,875 ----
- {"title-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
- {"title-closed-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
- {"title-closed-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
-+ {"folder-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
-+ {"folder-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
-+ {"directory-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
-+ {"directory-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
-+ {"folder-list-text-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
-+ {"folder-list-text-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
- {"status-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
- {"status-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
- {"keylabel-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
-***************
-*** 808,813 ****
---- 890,897 ----
- {"incoming-unseen-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
- {"signature-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
- {"signature-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
-+ {"special-text-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
-+ {"special-text-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
- {"prompt-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
- {"prompt-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
- {"header-general-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
-***************
-*** 840,845 ****
---- 924,931 ----
- {"index-from-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
- {"index-opening-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
- {"index-opening-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
-+ {"index-token-colors", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
-+ NULL, cf_text_index_token_color},
- {"viewer-hdr-colors", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
- "Viewer Header Colors", cf_text_view_hdr_color},
- {"keyword-colors", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
-***************
-*** 1555,1561 ****
- register struct variable *vars = ps->vars;
- int obs_header_in_reply = 0, /* the obs_ variables are to */
- obs_old_style_reply = 0, /* support backwards compatibility */
-! obs_save_by_sender, i, def_sort_rev;
- long rvl;
- PINERC_S *fixedprc = NULL;
- FeatureLevel obs_feature_level;
---- 1641,1647 ----
- register struct variable *vars = ps->vars;
- int obs_header_in_reply = 0, /* the obs_ variables are to */
- obs_old_style_reply = 0, /* 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;
-***************
-*** 1580,1585 ****
---- 1666,1672 ----
- GLO_FEATURE_LEVEL = cpystr("sappling");
- 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);
-***************
-*** 1642,1647 ****
---- 1729,1737 ----
- GLO_TITLE_BACK_COLOR = cpystr(DEFAULT_TITLE_BACK_RGB);
- GLO_TITLECLOSED_FORE_COLOR = cpystr(DEFAULT_TITLECLOSED_FORE_RGB);
- GLO_TITLECLOSED_BACK_COLOR = cpystr(DEFAULT_TITLECLOSED_BACK_RGB);
-+ GLO_FOLDER_FORE_COLOR = cpystr(DEFAULT_NORM_FORE_RGB);
-+ GLO_DIRECTORY_FORE_COLOR = cpystr(DEFAULT_NORM_FORE_RGB);
-+ GLO_FOLDER_LIST_FORE_COLOR = cpystr(DEFAULT_NORM_FORE_RGB);
- GLO_METAMSG_FORE_COLOR = cpystr(DEFAULT_METAMSG_FORE_RGB);
- GLO_METAMSG_BACK_COLOR = cpystr(DEFAULT_METAMSG_BACK_RGB);
- GLO_QUOTE1_FORE_COLOR = cpystr(DEFAULT_QUOTE1_FORE_RGB);
-***************
-*** 1943,1948 ****
---- 2033,2040 ----
- set_current_val(&vars[V_FORM_FOLDER], 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);
-+ regex_pattern(VAR_SPECIAL_TEXT);
- 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);
-***************
-*** 2216,2221 ****
---- 2308,2319 ----
- mail_parameters(NULL, SET_NEWSSPOOL,
- (void *)VAR_NEWS_SPOOL_DIR);
-
-+ #ifndef _WINDOWS
-+ set_current_val(&vars[V_MAILDIR_LOCATION], TRUE, TRUE);
-+ if(VAR_MAILDIR_LOCATION && VAR_MAILDIR_LOCATION[0])
-+ mail_parameters(NULL, SET_MDINBOXPATH, (void *)VAR_MAILDIR_LOCATION);
-+ #endif
-+
- /* guarantee a save default */
- set_current_val(&vars[V_DEFAULT_SAVE_FOLDER], TRUE, TRUE);
- if(!VAR_DEFAULT_SAVE_FOLDER || !VAR_DEFAULT_SAVE_FOLDER[0])
-***************
-*** 2446,2452 ****
- 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){
- snprintf(tmp_20k_buf, SIZEOF_20KBUF, "Sort type \"%.200s\" is invalid", VAR_SORT_KEY);
- init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
- ps->def_sort = SortArrival;
---- 2544,2550 ----
- 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,0) == -1){
- snprintf(tmp_20k_buf, SIZEOF_20KBUF, "Sort type \"%.200s\" is invalid", VAR_SORT_KEY);
- init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
- ps->def_sort = SortArrival;
-***************
-*** 2455,2460 ****
---- 2553,2569 ----
- 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++)
-***************
-*** 2541,2546 ****
---- 2650,2656 ----
- if(cmds_f)
- (*cmds_f)(ps, VAR_INIT_CMD_LIST);
-
-+ (void)create_rule_list(ps_global->vars);
- #ifdef _WINDOWS
- mswin_set_quit_confirm (F_OFF(F_QUIT_WO_CONFIRM, ps_global));
- #endif /* _WINDOWS */
-***************
-*** 2744,2749 ****
---- 2854,2861 ----
- F_ALWAYS_SPELL_CHECK, h_config_always_spell_check, PREF_COMP, 0},
-
- /* Reply Prefs */
-+ {"alternate-reply-menu", NULL,
-+ F_ALT_REPLY_MENU, h_config_alt_reply_menu, PREF_RPLY, 0},
- {"copy-to-address-to-from-if-it-is-us", "Copy To Address to From if it is Us",
- F_COPY_TO_TO_FROM, h_config_copy_to_to_from, PREF_RPLY, 0},
- {"enable-reply-indent-string-editing", NULL,
-***************
-*** 2762,2767 ****
---- 2874,2881 ----
- F_ENABLE_STRIP_SIGDASHES, h_config_strip_sigdashes, PREF_RPLY, 0},
- {"forward-as-attachment", "Forward messages as attachments",
- F_FORWARD_AS_ATTACHMENT, h_config_forward_as_attachment, PREF_RPLY, 0},
-+ {"preserve-original-fields", NULL,
-+ F_PRESERVE_ORIGINAL_FIELD, h_config_preserve_field, PREF_RPLY, 0},
-
- /* Sending Prefs */
- {"disable-sender", "Do Not Generate Sender Header",
-***************
-*** 2786,2791 ****
---- 2900,2907 ----
- F_NO_FCC_ATTACH, h_config_no_fcc_attach, PREF_SEND, 0},
- {"fcc-on-bounce", "Include Fcc When Bouncing Messages",
- F_FCC_ON_BOUNCE, h_config_fcc_on_bounce, PREF_SEND, 0},
-+ {"return-path-uses-domain-name", NULL,
-+ F_USE_DOMAIN_NAME, h_config_use_domain, PREF_SEND, 0},
- {"mark-fcc-seen", NULL,
- F_MARK_FCC_SEEN, h_config_mark_fcc_seen, PREF_SEND, 0},
- {"fcc-only-without-confirm", "Send to Fcc Only Without Confirming",
-***************
-*** 2832,2837 ****
---- 2948,2957 ----
- F_SORT_DEFAULT_SAVE_ALPHA, h_config_sort_save_alpha, PREF_FLDR, 0},
- {"vertical-folder-list", "Use Vertical Folder List",
- F_VERTICAL_FOLDER_LIST, h_config_vertical_list, PREF_FLDR, 0},
-+ #ifndef _WINDOWS
-+ {"use-courier-folder-list", "Courier Style Folder List",
-+ F_COURIER_FOLDER_LIST, h_config_courier_list, PREF_FLDR, 0},
-+ #endif
-
- /* Addr book */
- {"combined-addrbook-display", "Combined Address Book Display",
-***************
-*** 2848,2853 ****
---- 2968,2975 ----
- /* Index prefs */
- {"auto-open-next-unread", NULL,
- F_AUTO_OPEN_NEXT_UNREAD, h_config_auto_open_unread, PREF_INDX, 0},
-+ {"enable-circular-tab", NULL,
-+ F_AUTO_CIRCULAR_TAB, h_config_circular_tab, PREF_INDX, 0},
- {"continue-tab-without-confirm", "Continue NextNew Without Confirming",
- F_TAB_NO_CONFIRM, h_config_tab_no_prompt, PREF_INDX, 0},
- {"convert-dates-to-localtime", NULL,
-***************
-*** 2876,2881 ****
---- 2998,3005 ----
- F_COLOR_LINE_IMPORTANT, h_config_color_thrd_import, PREF_INDX, 0},
- {"thread-sorts-by-arrival", "Thread Sorts by Arrival",
- F_THREAD_SORTS_BY_ARRIVAL, h_config_thread_sorts_by_arrival, PREF_INDX, 0},
-+ {"enhanced-fancy-thread-support", "Enhanced Fancy Thread Support",
-+ F_ENHANCED_THREAD, h_config_enhanced_thread, PREF_INDX, 0},
-
- /* Viewer prefs */
- {"enable-msg-view-addresses", "Enable Message View Address Links",
-***************
-*** 2886,2891 ****
---- 3010,3017 ----
- F_VIEW_SEL_URL, h_config_enable_view_url, PREF_VIEW, 1},
- {"enable-msg-view-web-hostnames", "Enable Message View Web Hostname Links",
- F_VIEW_SEL_URL_HOST, h_config_enable_view_web_host, PREF_VIEW, 1},
-+ {"enable-msg-view-long-url", "Enable Recognition of Long URLS without Delimiter",
-+ F_VIEW_LONG_URL, h_config_enable_long_url, PREF_VIEW, 0},
- {"enable-msg-view-forced-arrows", "Enable Message View Forced Arrows",
- F_FORCE_ARROWS, h_config_enable_view_arrows, PREF_VIEW, 0},
- /* set to TRUE for windows */
-***************
-*** 2983,2988 ****
---- 3109,3116 ----
- F_FORCE_LOW_SPEED, h_config_force_low_speed, PREF_OS_LWSD, 0},
- {"auto-move-read-msgs", "Auto Move Read Messages",
- F_AUTO_READ_MSGS, h_config_auto_read_msgs, PREF_MISC, 0},
-+ {"auto-move-read-msgs-using-rules", "Auto Move Read Messages Using Rules",
-+ F_AUTO_READ_MSGS_RULES, h_config_auto_read_msgs_rules, PREF_MISC, 0},
- {"auto-unselect-after-apply", NULL,
- F_AUTO_UNSELECT, h_config_auto_unselect, PREF_MISC, 0},
- {"auto-unzoom-after-apply", NULL,
-***************
-*** 3044,3049 ****
---- 3172,3179 ----
- F_FULL_AUTO_EXPUNGE, h_config_full_auto_expunge, PREF_MISC, 0},
- {"force-arrow-cursor", NULL,
- F_FORCE_ARROW, h_config_force_arrow, PREF_MISC, 0},
-+ {"ignore-size-changes", NULL,
-+ F_IGNORE_SIZE, h_config_ignore_size, PREF_MISC, 0},
- {"maildrops-preserve-state", NULL,
- F_MAILDROPS_PRESERVE_STATE, h_config_maildrops_preserve_state,
- PREF_MISC, 0},
-***************
-*** 3179,3184 ****
---- 3309,3316 ----
- F_DISABLE_SHARED_NAMESPACES, h_config_disable_shared, PREF_HIDDEN, 0},
- {"disable-signature-edit-cmd", NULL,
- F_DISABLE_SIGEDIT_CMD, h_config_disable_signature_edit, PREF_HIDDEN, 0},
-+ {"new-thread-on-blank-subject", "New Thread on Blank Subject",
-+ F_NEW_THREAD_ON_BLANK_SUBJECT, h_config_new_thread_blank_subject, PREF_HIDDEN, 1},
- {"quell-personal-name-prompt", NULL,
- F_QUELL_PERSONAL_NAME_PROMPT, h_config_quell_personal_name_prompt, PREF_HIDDEN, 0},
- {"quell-user-id-prompt", "Quell User ID Prompt",
-***************
-*** 4734,4750 ****
- but also after each : in the path.
-
- ----*/
-
- char *
- expand_variables(char *lineout, size_t lineoutlen, char *linein, int colon_path)
- {
- char *src = linein, *dest = lineout, *p;
- char *limit = lineout + lineoutlen;
-! int envexpand = 0;
-
- if(!linein)
- return(NULL);
-
- while(*src ){ /* something in input string */
- if(*src == '$' && *(src+1) == '$'){
- /*
---- 4866,4887 ----
- but also after each : in the path.
-
- ----*/
-+ #define is_allowed_envchar(C, S) ((S) == 0 ? !isspace((C)) \
-+ : (((C) >= 'a' && (C) <= 'z') \
-+ || ((C) >= 'A' && (C) <= 'Z') \
-+ || ((C) >= '0' && (C) <= '9')))
-
- char *
- expand_variables(char *lineout, size_t lineoutlen, char *linein, int colon_path)
- {
- char *src = linein, *dest = lineout, *p;
- char *limit = lineout + lineoutlen;
-! int envexpand = 0, sp;
-
- if(!linein)
- return(NULL);
-
-+ sp = strncmp(src,"LIT:pattern=\"/NICK=", strlen("LIT:pattern=\"/NICK=")) == 0;
- while(*src ){ /* something in input string */
- if(*src == '$' && *(src+1) == '$'){
- /*
-***************
-*** 4825,4831 ****
- src = rbrace + 1;
- }
- else{
-! while(*src && !isspace((unsigned char) *src)
- && (p-word < sizeof(word)-1))
- *p++ = *src++;
- }
---- 4962,4968 ----
- src = rbrace + 1;
- }
- else{
-! while(*src && is_allowed_envchar((unsigned char) *src, sp)
- && (p-word < sizeof(word)-1))
- *p++ = *src++;
- }
-***************
-*** 6356,6361 ****
---- 6493,6501 ----
-
- set_color_val(&vars[V_TITLE_FORE_COLOR], 1);
- set_color_val(&vars[V_TITLECLOSED_FORE_COLOR], 0);
-+ set_color_val(&vars[V_FOLDER_FORE_COLOR], 0);
-+ set_color_val(&vars[V_DIRECTORY_FORE_COLOR], 0);
-+ set_color_val(&vars[V_FOLDER_LIST_FORE_COLOR], 0);
- set_color_val(&vars[V_STATUS_FORE_COLOR], 1);
- set_color_val(&vars[V_KEYLABEL_FORE_COLOR], 1);
- set_color_val(&vars[V_KEYNAME_FORE_COLOR], 1);
-***************
-*** 6379,6385 ****
---- 6519,6527 ----
- set_color_val(&vars[V_IND_OP_FORE_COLOR], 0);
- set_color_val(&vars[V_INCUNSEEN_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_INDEX_TOKEN_COLORS], TRUE, TRUE);
- set_current_val(&ps->vars[V_VIEW_HDR_COLORS], TRUE, TRUE);
- set_current_val(&ps->vars[V_KW_COLORS], TRUE, TRUE);
- set_custom_spec_colors(ps);
-***************
-*** 6532,6537 ****
---- 6674,6684 ----
- void
- set_custom_spec_colors(struct pine *ps)
- {
-+ if(ps->index_token_colors)
-+ free_spec_colors(&ps->index_token_colors);
-+
-+ ps->index_token_colors = spec_colors_from_varlist(ps->VAR_INDEX_TOKEN_COLORS, 1);
-+
- if(ps->hdr_colors)
- free_spec_colors(&ps->hdr_colors);
-
-***************
-*** 6895,6900 ****
---- 7042,7053 ----
-
- break;
-
-+ #ifndef _WINDOWS
-+ 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 */
-+ #endif
-+
- case F_COLOR_LINE_IMPORTANT :
- case F_DATES_TO_LOCAL :
- clear_index_cache(ps->mail_stream, 0);
-***************
-*** 7500,7509 ****
---- 7653,7692 ----
- 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_KEY_RULES:
-+ return(h_config_key_macro_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_POST_CHAR_SET :
- return(h_config_post_char_set);
- case V_UNK_CHAR_SET :
-***************
-*** 7554,7559 ****
---- 7737,7744 ----
- 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 :
-***************
-*** 7676,7681 ****
---- 7861,7870 ----
- return(h_config_newmailwidth);
- case V_NEWSRC_PATH :
- return(h_config_newsrc_path);
-+ #ifndef _WINDOWS
-+ case V_MAILDIR_LOCATION :
-+ return(h_config_maildir_location);
-+ #endif
- case V_BROWSER :
- return(h_config_browser);
- #if defined(DOS) || defined(OS2)
-***************
-*** 7694,7699 ****
---- 7883,7894 ----
- case V_TITLECLOSED_FORE_COLOR :
- case V_TITLECLOSED_BACK_COLOR :
- return(h_config_titleclosed_color);
-+ case V_FOLDER_FORE_COLOR:
-+ return(h_config_folder_color);
-+ case V_DIRECTORY_FORE_COLOR:
-+ return(h_config_directory_color);
-+ case V_FOLDER_LIST_FORE_COLOR:
-+ return(h_config_folder_list_color);
- case V_STATUS_FORE_COLOR :
- case V_STATUS_BACK_COLOR :
- return(h_config_status_color);
-***************
-*** 7713,7718 ****
---- 7908,7916 ----
- 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);
-***************
-*** 7764,7769 ****
---- 7962,7969 ----
- return(h_config_metamsg_color);
- case V_VIEW_HDR_COLORS :
- return(h_config_customhdr_color);
-+ case V_INDEX_TOKEN_COLORS :
-+ return(h_config_indextoken_color);
- case V_PRINTER :
- return(h_config_printer);
- case V_PERSONAL_PRINT_CATEGORY :
-***************
-*** 8194,8196 ****
---- 8394,8397 ----
- }
-
- #endif /* _WINDOWS */
-+
-diff -rc alpine-2.00/pith/conf.h alpine-2.00.I.USE/pith/conf.h
-*** alpine-2.00/pith/conf.h 2008-08-19 17:27:11.000000000 -0700
---- alpine-2.00.I.USE/pith/conf.h 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 143,152 ****
---- 143,195 ----
- #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_KEY_RULES vars[V_KEY_RULES].current_val.l
-+ #define GLO_KEY_RULES vars[V_KEY_RULES].global_val.l
-+ #define USR_KEY_RULES vars[V_KEY_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
- #ifndef _WINDOWS
- #define VAR_CHAR_SET vars[V_CHAR_SET].current_val.p
- #define GLO_CHAR_SET vars[V_CHAR_SET].global_val.p
-***************
-*** 160,165 ****
---- 203,210 ----
- #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
-***************
-*** 249,254 ****
---- 294,303 ----
- #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
-+ #ifndef _WINDOWS
-+ #define VAR_MAILDIR_LOCATION vars[V_MAILDIR_LOCATION].current_val.p
-+ #define GLO_MAILDIR_LOCATION vars[V_MAILDIR_LOCATION].global_val.p
-+ #endif
- #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
-***************
-*** 373,378 ****
---- 422,439 ----
- #define GLO_TITLECLOSED_FORE_COLOR vars[V_TITLECLOSED_FORE_COLOR].global_val.p
- #define VAR_TITLECLOSED_BACK_COLOR vars[V_TITLECLOSED_BACK_COLOR].current_val.p
- #define GLO_TITLECLOSED_BACK_COLOR vars[V_TITLECLOSED_BACK_COLOR].global_val.p
-+ #define VAR_FOLDER_FORE_COLOR vars[V_FOLDER_FORE_COLOR].current_val.p
-+ #define GLO_FOLDER_FORE_COLOR vars[V_FOLDER_FORE_COLOR].global_val.p
-+ #define VAR_FOLDER_BACK_COLOR vars[V_FOLDER_BACK_COLOR].current_val.p
-+ #define GLO_FOLDER_BACK_COLOR vars[V_FOLDER_BACK_COLOR].global_val.p
-+ #define VAR_DIRECTORY_FORE_COLOR vars[V_DIRECTORY_FORE_COLOR].current_val.p
-+ #define GLO_DIRECTORY_FORE_COLOR vars[V_DIRECTORY_FORE_COLOR].global_val.p
-+ #define VAR_DIRECTORY_BACK_COLOR vars[V_DIRECTORY_BACK_COLOR].current_val.p
-+ #define GLO_DIRECTORY_BACK_COLOR vars[V_DIRECTORY_BACK_COLOR].global_val.p
-+ #define VAR_FOLDER_LIST_FORE_COLOR vars[V_FOLDER_LIST_FORE_COLOR].current_val.p
-+ #define GLO_FOLDER_LIST_FORE_COLOR vars[V_FOLDER_LIST_FORE_COLOR].global_val.p
-+ #define VAR_FOLDER_LIST_BACK_COLOR vars[V_FOLDER_LIST_BACK_COLOR].current_val.p
-+ #define GLO_FOLDER_LIST_BACK_COLOR vars[V_FOLDER_LIST_BACK_COLOR].global_val.p
- #define VAR_STATUS_FORE_COLOR vars[V_STATUS_FORE_COLOR].current_val.p
- #define VAR_STATUS_BACK_COLOR vars[V_STATUS_BACK_COLOR].current_val.p
- #define VAR_HEADER_GENERAL_FORE_COLOR vars[V_HEADER_GENERAL_FORE_COLOR].current_val.p
-***************
-*** 443,451 ****
---- 504,515 ----
- #define GLO_SIGNATURE_FORE_COLOR vars[V_SIGNATURE_FORE_COLOR].global_val.p
- #define VAR_SIGNATURE_BACK_COLOR vars[V_SIGNATURE_BACK_COLOR].current_val.p
- #define GLO_SIGNATURE_BACK_COLOR vars[V_SIGNATURE_BACK_COLOR].global_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
-+ #define VAR_INDEX_TOKEN_COLORS vars[V_INDEX_TOKEN_COLORS].current_val.l
- #ifdef SMIME
- #define VAR_PUBLICCERT_DIR vars[V_PUBLICCERT_DIR].current_val.p
- #define GLO_PUBLICCERT_DIR vars[V_PUBLICCERT_DIR].global_val.p
-diff -rc alpine-2.00/pith/conftype.h alpine-2.00.I.USE/pith/conftype.h
-*** alpine-2.00/pith/conftype.h 2008-08-19 17:27:11.000000000 -0700
---- alpine-2.00.I.USE/pith/conftype.h 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 58,63 ****
---- 58,64 ----
- , 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
-***************
-*** 69,74 ****
---- 70,89 ----
- , 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_KEY_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
- #ifndef _WINDOWS
- , V_CHAR_SET
- , V_OLD_CHAR_SET
-***************
-*** 79,84 ****
---- 94,100 ----
- , V_EDITOR
- , V_SPELLER
- , V_FILLCOL
-+ , V_SPECIAL_TEXT
- , V_REPLY_STRING
- , V_REPLY_INTRO
- , V_QUOTE_REPLACE_STRING
-***************
-*** 114,119 ****
---- 130,138 ----
- , V_NEWSRC_PATH
- , V_NEWS_ACTIVE_PATH
- , V_NEWS_SPOOL_DIR
-+ #ifndef _WINDOWS
-+ , V_MAILDIR_LOCATION
-+ #endif
- , V_UPLOAD_CMD
- , V_UPLOAD_CMD_PREFIX
- , V_DOWNLOAD_CMD
-***************
-*** 203,208 ****
---- 222,233 ----
- , V_TITLE_BACK_COLOR
- , V_TITLECLOSED_FORE_COLOR
- , V_TITLECLOSED_BACK_COLOR
-+ , V_FOLDER_FORE_COLOR
-+ , V_FOLDER_BACK_COLOR
-+ , V_DIRECTORY_FORE_COLOR
-+ , V_DIRECTORY_BACK_COLOR
-+ , V_FOLDER_LIST_FORE_COLOR
-+ , V_FOLDER_LIST_BACK_COLOR
- , V_STATUS_FORE_COLOR
- , V_STATUS_BACK_COLOR
- , V_KEYLABEL_FORE_COLOR
-***************
-*** 223,228 ****
---- 248,255 ----
- , V_INCUNSEEN_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_HEADER_GENERAL_FORE_COLOR
-***************
-*** 255,260 ****
---- 282,288 ----
- , V_IND_FROM_BACK_COLOR
- , V_IND_OP_FORE_COLOR
- , V_IND_OP_BACK_COLOR
-+ , V_INDEX_TOKEN_COLORS
- , V_VIEW_HDR_COLORS
- , V_KW_COLORS
- #if defined(DOS) || defined(OS2)
-***************
-*** 319,324 ****
---- 347,353 ----
- 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,
-***************
-*** 334,342 ****
---- 363,373 ----
- F_FORCE_ARROW,
- F_PRUNE_USES_ISO,
- F_ALT_ED_NOW,
-+ F_IGNORE_SIZE,
- F_SHOW_DELAY_CUE,
- F_CANCEL_CONFIRM,
- F_AUTO_OPEN_NEXT_UNREAD,
-+ F_AUTO_CIRCULAR_TAB,
- F_DISABLE_INDEX_LOCALE_DATES,
- F_SELECTED_SHOWN_BOLD,
- F_QUOTE_ALL_FROMS,
-***************
-*** 380,389 ****
---- 411,424 ----
- F_PASS_C1_CONTROL_CHARS,
- F_SINGLE_FOLDER_LIST,
- F_VERTICAL_FOLDER_LIST,
-+ #ifndef _WINDOWS
-+ F_COURIER_FOLDER_LIST,
-+ #endif
- 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,
-***************
-*** 428,439 ****
---- 463,476 ----
- F_TCAP_WINS,
- F_ENABLE_SIGDASHES,
- F_ENABLE_STRIP_SIGDASHES,
-+ F_NEW_THREAD_ON_BLANK_SUBJECT,
- F_QUELL_PARTIAL_FETCH,
- F_QUELL_PERSONAL_NAME_PROMPT,
- F_QUELL_USER_ID_PROMPT,
- F_VIEW_SEL_ATTACH,
- F_VIEW_SEL_URL,
- F_VIEW_SEL_URL_HOST,
-+ F_VIEW_LONG_URL,
- F_SCAN_ADDR,
- F_FORCE_ARROWS,
- F_PREFER_PLAIN_TEXT,
-***************
-*** 492,502 ****
---- 529,541 ----
- 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_QUELL_USERAGENT,
- F_COLOR_LINE_IMPORTANT,
-+ F_ENHANCED_THREAD,
- F_SLASH_COLL_ENTIRE,
- F_ENABLE_FULL_HDR_AND_TEXT,
- F_QUELL_FULL_HDR_RESET,
-***************
-*** 514,519 ****
---- 553,559 ----
- F_RENDER_HTML_INTERNALLY,
- F_ENABLE_JUMP_CMD,
- F_FORWARD_AS_ATTACHMENT,
-+ F_PRESERVE_ORIGINAL_FIELD,
- #ifndef _WINDOWS
- F_USE_SYSTEM_TRANS,
- #endif /* ! _WINDOWS */
-***************
-*** 703,707 ****
---- 743,748 ----
-
- /* exported protoypes */
-
-+ #define DF_THREAD_SORT_KEY "thread"
-
- #endif /* PITH_CONFTYPE_INCLUDED */
-diff -rc alpine-2.00/pith/detoken.c alpine-2.00.I.USE/pith/detoken.c
-*** alpine-2.00/pith/detoken.c 2007-08-14 12:02:07.000000000 -0700
---- alpine-2.00.I.USE/pith/detoken.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 24,30 ****
- #include "../pith/reply.h"
- #include "../pith/mailindx.h"
- #include "../pith/options.h"
-!
-
- /*
- * Hook to read signature from local file
---- 24,30 ----
- #include "../pith/reply.h"
- #include "../pith/mailindx.h"
- #include "../pith/options.h"
-! #include "../pith/rules.h"
-
- /*
- * Hook to read signature from local file
-***************
-*** 90,95 ****
---- 90,97 ----
-
- 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;
-***************
-*** 103,116 ****
- * 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;
---- 105,129 ----
- * 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_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;
-***************
-*** 301,307 ****
- }
- }
- }
-! else if(pt->what_for & FOR_REPLY_INTRO)
- repl = get_reply_data(env, role, pt->ctype,
- subbuf, sizeof(subbuf)-1);
-
---- 314,320 ----
- }
- }
- }
-! else if(pt->what_for & (FOR_REPLY_INTRO | FOR_RULE))
- repl = get_reply_data(env, role, pt->ctype,
- subbuf, sizeof(subbuf)-1);
-
-diff -rc alpine-2.00/pith/filter.c alpine-2.00.I.USE/pith/filter.c
-*** alpine-2.00/pith/filter.c 2008-08-21 16:50:47.000000000 -0700
---- alpine-2.00.I.USE/pith/filter.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 45,50 ****
---- 45,51 ----
- #include "../pith/conf.h"
- #include "../pith/store.h"
- #include "../pith/color.h"
-+ #include "../pith/osdep/color.h"
- #include "../pith/escapes.h"
- #include "../pith/pipe.h"
- #include "../pith/status.h"
-***************
-*** 1020,1026 ****
- */
- char *
- gf_filter(char *cmd, char *prepend, STORE_S *source_so, gf_io_t pc,
-! FILTLIST_S *aux_filters, int disable_reset,
- void (*pipecb_f)(PIPE_S *, int, void *))
- {
- unsigned char c, obuf[MAX(MB_LEN_MAX,32)];
---- 1021,1027 ----
- */
- char *
- gf_filter(char *cmd, char *prepend, STORE_S *source_so, gf_io_t pc,
-! FILTLIST_S *aux_filters, int silent, int disable_reset,
- void (*pipecb_f)(PIPE_S *, int, void *))
- {
- unsigned char c, obuf[MAX(MB_LEN_MAX,32)];
-***************
-*** 1057,1064 ****
- * Spawn filter feeding it data, and reading what it writes.
- */
- so_seek(source_so, 0L, 0);
-! flags = PIPE_WRITE | PIPE_READ | PIPE_NOSHELL |
-! (!disable_reset ? PIPE_RESET : 0);
-
- if((fpipe = open_system_pipe(cmd, NULL, NULL, flags, 0, pipecb_f, pipe_report_error)) != NULL){
-
---- 1058,1066 ----
- * Spawn filter feeding it data, and reading what it writes.
- */
- so_seek(source_so, 0L, 0);
-! flags = PIPE_WRITE | PIPE_READ | PIPE_NOSHELL
-! | (silent ? PIPE_SILENT : 0)
-! | (!disable_reset ? PIPE_RESET : 0);
-
- if((fpipe = open_system_pipe(cmd, NULL, NULL, flags, 0, pipecb_f, pipe_report_error)) != NULL){
-
-***************
-*** 1373,1386 ****
- register unsigned char t = f->t;
- register int n = (int) f->n;
- register int state = f->f1;
-
- while(GF_GETC(f, c)){
-
- if(state){
- state = 0;
- if (c != '=') {
-! gf_error("Illegal '=' in base64 text");
-! /* NO RETURN */
- }
- }
-
---- 1375,1398 ----
- register unsigned char t = f->t;
- register int n = (int) f->n;
- register int state = f->f1;
-+ register unsigned char lastc;
-
- while(GF_GETC(f, c)){
-
-+ lastc = c;
-+ if(f->f2){
-+ GF_PUTC(f->next, c);
-+ continue;
-+ }
-+
- if(state){
- state = 0;
- if (c != '=') {
-! f->f2++;
-! GF_PUTC(f->next, c);
-! q_status_message(SM_ORDER,3,3,
-! _("Warning: Illegal '=' in base64 text"));
-! continue;
- }
- }
-
-***************
-*** 1397,1404 ****
- break;
-
- default: /* impossible quantum position */
-! gf_error("Internal base64 decoder error");
-! /* NO RETURN */
- }
- }
- }
---- 1409,1419 ----
- break;
-
- default: /* impossible quantum position */
-! f->f2++;
-! GF_PUTC(f->next, lastc);
-! q_status_message(SM_ORDER,3,3,
-! _("Warning: Internal base64 decode error"));
-! break;
- }
- }
- }
-***************
-*** 1439,1444 ****
---- 1454,1460 ----
- dprint((9, "-- gf_reset b64_binary\n"));
- f->n = 0L; /* quantum position */
- f->f1 = 0; /* state holder: equal seen? */
-+ f->f2 = 0; /* No errors when we start */
- }
- }
-
-***************
-*** 4979,4984 ****
---- 4995,5001 ----
- && p->value
- && (HANDLES_LOC(hd->html_data)
- || struncmp(p->value, "x-alpine-", 9)
-+ || struncmp(p->value, "x-pine-help", 11)
- || p->value[0] == '#'))
- href = p;
- else if(!strucmp(p->attribute, "NAME"))
-***************
-*** 7587,7592 ****
---- 7604,7610 ----
- char *p, buf[MAILTMPLEN];
- ADDRESS *adr;
- extern char datestamp[];
-+ extern char plevstamp[];
-
- if(!strcmp(s = removing_quotes(s + 4), "ALPINE_VERSION")){
- p = ALPINE_VERSION;
-***************
-*** 7600,7605 ****
---- 7618,7626 ----
- else if(!strcmp(s, "ALPINE_COMPILE_DATE")){
- p = datestamp;
- }
-+ else if(!strcmp(s, "ALPINE_PATCHLEVEL")){
-+ p = plevstamp;
-+ }
- else if(!strcmp(s, "ALPINE_TODAYS_DATE")){
- rfc822_date(p = buf);
- }
-***************
-*** 9155,9160 ****
---- 9176,9186 ----
- 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)
-***************
-*** 9196,9201 ****
---- 9222,9233 ----
- #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,W) { \
- if((F)->linep == WRAP_LASTC(F)){ \
- size_t offset = (F)->linep - (F)->line; \
-***************
-*** 9273,9278 ****
---- 9305,9312 ----
- case CCR : /* CRLF or CR in text ? */
- state = BOL; /* either way, handle start */
-
-+ WRAP_CURLINE(f)++;
-+ WRAP_CURPOS(f) = 0;
- if(WRAP_FLOW(f)){
- /* wrapped line? */
- if(f->f2 == 0 && WRAP_SPC_LEN(f) && WRAP_TRL_SPC(f)){
-***************
-*** 9366,9372 ****
-
- case BOL :
- if(WRAP_FLOW(f)){
-! if(c == '>'){
- WRAP_FL_QC(f) = 1; /* init it */
- state = FL_QLEV; /* go collect it */
- }
---- 9400,9410 ----
-
- case BOL :
- if(WRAP_FLOW(f)){
-! if(WRAP_CURLINE(f) < WRAP_QSTRLEN(f)
-! && 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 */
- }
-***************
-*** 9380,9386 ****
- }
-
- /* 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;
---- 9418,9433 ----
- }
-
- /* 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;
-***************
-*** 9432,9439 ****
- break;
-
- case FL_QLEV :
-! if(c == '>'){ /* another level */
-! WRAP_FL_QC(f)++;
- }
- else {
- /* if EMBEDed, process it and return here */
---- 9479,9490 ----
- break;
-
- case FL_QLEV :
-! if(WRAP_CURLINE(f) < WRAP_QSTRLEN(f)
-! && 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 */
-***************
-*** 9445,9451 ****
- }
-
- /* 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 */
---- 9496,9511 ----
- }
-
- /* 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 */
-***************
-*** 9502,9507 ****
---- 9562,9574 ----
- state = FL_SIG;
- break;
-
-+ case ' ' : /* what? */
-+ if (WRAP_CURLINE(f) < WRAP_QSTRLEN(f)
-+ && 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 */
-***************
-*** 9518,9524 ****
- &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 */
- }
-
---- 9585,9591 ----
- &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 */
- }
-
-***************
-*** 10015,10021 ****
- 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 */
- }
-
---- 10082,10088 ----
- 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 */
- }
-
-***************
-*** 10088,10093 ****
---- 10155,10167 ----
- 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 */
-***************
-*** 10438,10444 ****
- {
- 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);
---- 10512,10519 ----
- {
- 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);
-***************
-*** 10447,10456 ****
- 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,
---- 10522,10543 ----
- last_prefix = NULL;
- }
- }
-!
-! if(WRAP_CURLINE(f) < WRAP_QSTRLEN(f) && 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,
-***************
-*** 10458,10464 ****
- && 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,
---- 10545,10551 ----
- && 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,
-***************
-*** 10466,10472 ****
- && 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,
---- 10553,10559 ----
- && 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,
-***************
-*** 10480,10522 ****
- }
- }
-
- if(!WRAP_LV_FLD(f)){
- if(!WRAP_FOR_CMPS(f) && ps_global->VAR_QUOTE_REPLACE_STRING && prefix){
- for(i = 0; prefix[i]; i++)
- GF_PUTC_GLO(f->next, prefix[i]);
-! f->n += utf8_width(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 += utf8_width(last_prefix);
- }
-
- if(prefix)
- fs_give((void **)&prefix);
- if(last_prefix)
- fs_give((void **)&last_prefix);
-
- return 0;
- }
---- 10567,10626 ----
- }
- }
-
-+ if (j > 1 && wrap_qstr[j-1] == ' ')
-+ j -= 1;
-+
- if(!WRAP_LV_FLD(f)){
- if(!WRAP_FOR_CMPS(f) && ps_global->VAR_QUOTE_REPLACE_STRING && prefix){
- for(i = 0; prefix[i]; i++)
- GF_PUTC_GLO(f->next, prefix[i]);
-! f->n += utf8_widthis(prefix);
- }
- else{
-! for (i = oldj; i < j; i++)
-! GF_PUTC_GLO(f->next, wrap_qstr[i]);
-! f->n += j - oldj;
- }
- }
- 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 += utf8_widthis(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;
- }
-***************
-*** 10548,10553 ****
---- 10652,10663 ----
- wrap->hdr_color = (GFW_HDRCOLOR & flags) == GFW_HDRCOLOR;
- wrap->for_compose = (GFW_FORCOMPOSE & flags) == GFW_FORCOMPOSE;
- wrap->handle_soft_hyphen = (GFW_SOFTHYPHEN & flags) == GFW_SOFTHYPHEN;
-+ 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);
- }
-***************
-*** 10991,10997 ****
---- 11101,11315 ----
- } \
- }
-
-+ #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)++; \
-+ } \
-+ }
-+
-+ int end_of_line(char *line)
-+ {
-+ int i;
-+
-+ for(i= 0; line && line[i]; i++){
-+ if((line[i] == '\015' && line[i+1] == '\012') || line[i] == '\012')
-+ break;
-+ }
-+ return i;
-+ }
-+
-+ /* This macro is used in gf_quote_test. It receives a return code
-+ from a filter. All filters that will print something must send
-+ return code 0, except color_a_quote which must send return code
-+ 1
-+ */
-+
-+ #define GF_ADD_QUOTED_LINE(F, line) \
-+ { \
-+ LT_INS_S *ins = NULL, *insp; \
-+ int done; \
-+ char *gline, *cline;\
-+ unsigned char ch;\
-+ register char *cp;\
-+ register int l;\
-+ \
-+ for (gline = cline = line; gline && cline; ){\
-+ if(cline = strchr(gline,'\012'))\
-+ *cline = '\0';\
-+ done = (*((LINETEST_S *) (F)->opt)->f)((F)->n++, gline, &ins,\
-+ ((LINETEST_S *) (F)->opt)->local);\
-+ if (done < 2){ \
-+ if(done == 1)\
-+ ADD_QUOTE_STRING((F));\
-+ for(insp = ins, cp = gline; *cp ; ){\
-+ if(insp && cp == insp->where){\
-+ if(insp->len > 0){ \
-+ for(l = 0; l < insp->len; l++){\
-+ ch = (unsigned char) insp->text[l];\
-+ GF_PUTC((F)->next, ch);\
-+ }\
-+ insp = insp->next;\
-+ continue; \
-+ } else if(insp->len < 0){ \
-+ cp -= insp->len; \
-+ insp = insp->next; \
-+ continue; \
-+ } \
-+ }\
-+ 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);\
-+ if(cline){ \
-+ *cline = '\012';\
-+ gline += cline - gline + 1;\
-+ }\
-+ 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';\
-+ i = end_of_line((F)->oldline); \
-+ if (((F)->oldline)[i]){\
-+ i += (((F)->oldline)[i] == '\015') ? 2 : 1;\
-+ line = (F)->oldline + i;\
-+ i = end_of_line(line); \
-+ if(line[i])\
-+ line[i] = '\0'; \
-+ }\
-+ 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;\
-+ if ((F)->oldline)\
-+ fs_give((void **)&(F)->oldline);\
-+ (F)->oldline = cpystr(line);\
-+ i = end_of_line(line); \
-+ if (line[i]){ \
-+ j = (line[i] == '\015') ? 2 : 1;\
-+ line[i] = '\0'; \
-+ i += j; \
-+ }\
-+ 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)){
-+
-+ GF_LINE_TEST_ADD(f, c);
-+ if(c == '\012')
-+ state++;
-+ 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;
-+ }
-+ }
-+
-+ 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){
-+ 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
-diff -rc alpine-2.00/pith/filter.h alpine-2.00.I.USE/pith/filter.h
-*** alpine-2.00/pith/filter.h 2008-08-22 12:46:13.000000000 -0700
---- alpine-2.00.I.USE/pith/filter.h 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 175,181 ****
- char *gf_pipe(gf_io_t, gf_io_t);
- long gf_bytes_piped(void);
- char *gf_filter(char *, char *, STORE_S *, gf_io_t, FILTLIST_S *, int,
-! void (*)(PIPE_S *, int, void *));
- void gf_binary_b64(FILTER_S *, int);
- void gf_b64_binary(FILTER_S *, int);
- void gf_qp_8bit(FILTER_S *, int);
---- 175,181 ----
- char *gf_pipe(gf_io_t, gf_io_t);
- long gf_bytes_piped(void);
- char *gf_filter(char *, char *, STORE_S *, gf_io_t, FILTLIST_S *, int,
-! int, void (*)(PIPE_S *, int, void *));
- void gf_binary_b64(FILTER_S *, int);
- void gf_b64_binary(FILTER_S *, int);
- void gf_qp_8bit(FILTER_S *, int);
-***************
-*** 215,220 ****
---- 215,221 ----
- void *gf_prepend_editorial_opt(prepedtest_t, char *);
- void gf_nvtnl_local(FILTER_S *, int);
- void gf_local_nvtnl(FILTER_S *, int);
-+ void gf_quote_test(FILTER_S *, int);
- void *gf_url_hilite_opt(URL_HILITE_S *, HANDLE_S **, int);
-
-
-diff -rc alpine-2.00/pith/filttype.h alpine-2.00.I.USE/pith/filttype.h
-*** alpine-2.00/pith/filttype.h 2007-04-25 21:06:02.000000000 -0700
---- alpine-2.00.I.USE/pith/filttype.h 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 35,40 ****
---- 35,42 ----
- 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];
-diff -rc alpine-2.00/pith/flag.c alpine-2.00.I.USE/pith/flag.c
-*** alpine-2.00/pith/flag.c 2008-07-14 11:01:54.000000000 -0700
---- alpine-2.00.I.USE/pith/flag.c 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 593,606 ****
-
- was_invisible = (pelt->hidden || pelt->colhid) ? 1 : 0;
-
- if((chk_thrd_cnt = ((msgs->visible_threads >= 0L)
- && THRD_INDX_ENABLED() && (f & MN_HIDE) && (pelt->hidden != v))) != 0){
- 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){
---- 593,608 ----
-
- was_invisible = (pelt->hidden || pelt->colhid) ? 1 : 0;
-
-+ thrd = fetch_thread(stream, rawno);
-+
- if((chk_thrd_cnt = ((msgs->visible_threads >= 0L)
- && THRD_INDX_ENABLED() && (f & MN_HIDE) && (pelt->hidden != v))) != 0){
- thrd = fetch_thread(stream, rawno);
- 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){
-diff -rc alpine-2.00/pith/handle.h alpine-2.00.I.USE/pith/handle.h
-*** alpine-2.00/pith/handle.h 2007-11-13 16:47:15.000000000 -0800
---- alpine-2.00.I.USE/pith/handle.h 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 39,44 ****
---- 39,45 ----
- unsigned using_is_used:1; /* bit below is being used */
- unsigned is_used:1; /* if not, remove it from list */
- unsigned color_unseen:1; /* we're coloring folders with unseen */
-+ unsigned color_folder:1; /* and just folders for that matter... */
- unsigned is_dual_do_open:1; /* choosing this handle means open */
- union {
- struct { /* URL corresponding to this handle */
-diff -rc alpine-2.00/pith/imap.c alpine-2.00.I.USE/pith/imap.c
-*** alpine-2.00/pith/imap.c 2008-07-14 11:01:54.000000000 -0700
---- alpine-2.00.I.USE/pith/imap.c 2011-02-07 20:33:43.000000000 -0800
-***************
-*** 1108,1110 ****
---- 1108,1172 ----
-
- return(block);
- }
-+
-+
-+ void
-+ pine_delete_pwd(NETMBX *mb, char *user)
-+ {
-+ char hostlist0[MAILTMPLEN], hostlist1[MAILTMPLEN];
-+ char port[20], non_def_port[20], insecure[20];
-+ STRLIST_S hostlist[2];
-+ MMLOGIN_S *l;
-+ struct servent *sv;
-+
-+
-+ dprint((9, "pine_delete_pwd\n"));
-+
-+ /* setup hostlist */
-+ non_def_port[0] = '\0';
-+ if(mb->port && mb->service &&
-+ (sv = getservbyname(mb->service, "tcp")) &&
-+ (mb->port != ntohs(sv->s_port))){
-+ snprintf(non_def_port, sizeof(non_def_port), ":%lu", mb->port);
-+ non_def_port[sizeof(non_def_port)-1] = '\0';
-+ dprint((9, "mm_login: using non-default port=%s\n",
-+ non_def_port ? non_def_port : "?"));
-+ }
-+
-+ if(*non_def_port){
-+ strncpy(hostlist0, mb->host, sizeof(hostlist0)-1);
-+ hostlist0[sizeof(hostlist0)-1] = '\0';
-+ strncat(hostlist0, non_def_port, sizeof(hostlist0)-strlen(hostlist0)-1);
-+ hostlist0[sizeof(hostlist0)-1] = '\0';
-+ hostlist[0].name = hostlist0;
-+ if(mb->orighost && mb->orighost[0] && strucmp(mb->host, mb->orighost)){
-+ strncpy(hostlist1, mb->orighost, sizeof(hostlist1)-1);
-+ hostlist1[sizeof(hostlist1)-1] = '\0';
-+ strncat(hostlist1, non_def_port, sizeof(hostlist1)-strlen(hostlist1)-1);
-+ hostlist1[sizeof(hostlist1)-1] = '\0';
-+ hostlist[0].next = &hostlist[1];
-+ hostlist[1].name = hostlist1;
-+ hostlist[1].next = NULL;
-+ }
-+ else
-+ hostlist[0].next = NULL;
-+ }
-+ else{
-+ hostlist[0].name = mb->host;
-+ if(mb->orighost && mb->orighost[0] && strucmp(mb->host, mb->orighost)){
-+ hostlist[0].next = &hostlist[1];
-+ hostlist[1].name = mb->orighost;
-+ hostlist[1].next = NULL;
-+ }
-+ else
-+ hostlist[0].next = NULL;
-+ }
-+
-+ for(l = mm_login_list; l; l = l->next)
-+ if(imap_same_host(l->hosts, hostlist)
-+ && !strcmp(l->user, user ? user : "")
-+ && l->passwd){
-+ l->passwd[0] = '\0';
-+ break;
-+ }
-+ }
-diff -rc alpine-2.00/pith/imap.h alpine-2.00.I.USE/pith/imap.h
-*** alpine-2.00/pith/imap.h 2008-04-23 19:00:26.000000000 -0700
---- alpine-2.00.I.USE/pith/imap.h 2011-02-07 20:33:43.000000000 -0800
-***************
-*** 123,129 ****
- int imap_get_passwd(MMLOGIN_S *, char *, char *, STRLIST_S *, int);
- void imap_set_passwd(MMLOGIN_S **, char *, char *, STRLIST_S *, int, int, int);
- void imap_flush_passwd_cache(int);
-!
-
- /* currently mandatory to implement stubs */
-
---- 123,129 ----
- int imap_get_passwd(MMLOGIN_S *, char *, char *, STRLIST_S *, int);
- void imap_set_passwd(MMLOGIN_S **, char *, char *, STRLIST_S *, int, int, int);
- void imap_flush_passwd_cache(int);
-! void pine_delete_pwd(NETMBX *mb, char *user);
-
- /* currently mandatory to implement stubs */
-
-diff -rc alpine-2.00/pith/indxtype.h alpine-2.00.I.USE/pith/indxtype.h
-*** alpine-2.00/pith/indxtype.h 2008-05-28 13:19:56.000000000 -0700
---- alpine-2.00.I.USE/pith/indxtype.h 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 75,86 ****
- iKey, iKeyInit,
- iPrefDate, iPrefTime, iPrefDateTime,
- iCurPrefDate, iCurPrefTime, iCurPrefDateTime,
-! 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, iNewLine,
- iHeader, iText,
---- 75,89 ----
- iKey, iKeyInit,
- iPrefDate, iPrefTime, iPrefDateTime,
- iCurPrefDate, iCurPrefTime, iCurPrefDateTime,
-! 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, iProcid, iScreen, iPkey,
-+ iNick, iAddressTo, iAddressCc, iAddressRecip, iBcc, iLcc,
-+ iFfrom, iFadd,
- iSTime, iKSize,
- iRoleNick, iNewLine,
- iHeader, iText,
-***************
-*** 102,116 ****
-
-
- /* 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 DELIM_COLON 0x40
-!
-
- #define DEFAULT_REPLY_INTRO "default"
-
---- 105,130 ----
-
-
- /* 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 DELIM_COLON 0x00040
-! #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 FOR_KEY 0x20000 /* for rules */
-! #define FOR_SAVE 0x40000 /* for rules */
-
- #define DEFAULT_REPLY_INTRO "default"
-
-diff -rc alpine-2.00/pith/init.c alpine-2.00.I.USE/pith/init.c
-*** alpine-2.00/pith/init.c 2007-08-16 15:25:10.000000000 -0700
---- alpine-2.00.I.USE/pith/init.c 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 407,412 ****
---- 407,415 ----
- && stricmp(filename, folder_base)){
- #else
- if(strncmp(filename, folder_base, folder_base_len) == 0
-+ #ifndef _WINDOWS
-+ && filename[folder_base_len] != list_cntxt->dir->delim
-+ #endif
- && strcmp(filename, folder_base)){
- #endif
- #endif
-diff -rc alpine-2.00/pith/mailcap.c alpine-2.00.I.USE/pith/mailcap.c
-*** alpine-2.00/pith/mailcap.c 2008-03-18 10:24:31.000000000 -0700
---- alpine-2.00.I.USE/pith/mailcap.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 52,57 ****
---- 52,58 ----
- int needsterminal;
- char *contenttype;
- char *command;
-+ char *nametemplate;
- char *testcommand;
- char *label; /* unused */
- char *printcommand; /* unused */
-***************
-*** 212,217 ****
---- 213,221 ----
- if(mc->printcommand)
- dprint((11, " printcommand: %s",
- mc->printcommand ? mc->printcommand : "?"));
-+ if(mc->nametemplate)
-+ dprint((11, " nametemplate: %s",
-+ mc->nametemplate ? mc->nametemplate : "?"));
- dprint((11, " needsterminal %d\n", mc->needsterminal));
- }
- }
-***************
-*** 487,492 ****
---- 491,501 ----
- dprint((9, "mailcap: printcommand=%s\n",
- mc->printcommand ? mc->printcommand : "?"));
- }
-+ else if(arg && !strucmp(*tokens, "nametemplate")){
-+ mc->nametemplate = arg;
-+ dprint((9, "mailcap: nametemplate=%s\n",
-+ arg ? arg : "?"));
-+ }
- else if(arg && !strucmp(*tokens, "compose")){
- /* not used */
- dprint((9, "mailcap: not using compose=%s\n",
-***************
-*** 973,975 ****
---- 982,1041 ----
- mail_free_stringlist(&MailcapData.raw);
- mc_free_entry(&MailcapData.head);
- }
-+
-+ char *
-+ mc_template(char *tmp_file, BODY *body, int chk_extension)
-+ {
-+ MailcapEntry *mc;
-+ int quoted = 0;
-+ char *s, *to, *namefile = NULL;
-+
-+ mc = mc_get_command(body->type, body->subtype, body, chk_extension, NULL);
-+ if(!mc || !mc->nametemplate || !tmp_file)
-+ return tmp_file;
-+
-+ /* remove extension if requested for a specific extension */
-+ if(mc->nametemplate && tmp_file && (s = strrchr(tmp_file, '.')) != NULL
-+ && strchr(s, C_FILESEP) == NULL)
-+ *s = '\0';
-+
-+ to = tmp_20k_buf;
-+ if((s = strrchr(tmp_file, C_FILESEP)) != NULL){
-+ *s++ = '\0';
-+ sstrncpy(&to, tmp_file, SIZEOF_20KBUF-(to-tmp_20k_buf));
-+ if(to-tmp_20k_buf < SIZEOF_20KBUF)
-+ *to++ = C_FILESEP;
-+ namefile = s;
-+ }
-+
-+ for(s = mc->nametemplate; *s; s++)
-+ if(quoted){
-+ quoted = 0;
-+ switch(*s){
-+ case '%':
-+ if(to-tmp_20k_buf < SIZEOF_20KBUF)
-+ *to++ = '%';
-+ break;
-+
-+ case 's':
-+ sstrncpy(&to, namefile ? namefile : tmp_file, SIZEOF_20KBUF-(to-tmp_20k_buf));
-+ break;
-+
-+ default:
-+ dprint((9,
-+ "Ignoring unercognized format code in nametemplate: %%%c\n", *s ));
-+ break;
-+ }
-+ }
-+ else if(*s == '%')
-+ quoted = 1;
-+ else if(to-tmp_20k_buf < SIZEOF_20KBUF)
-+ *to++ = *s;
-+
-+ *to++ = '\0';
-+
-+ fs_give((void **)&tmp_file);
-+ tmp_file = cpystr(tmp_20k_buf);
-+ return tmp_file;
-+ }
-+
-diff -rc alpine-2.00/pith/mailcap.h alpine-2.00.I.USE/pith/mailcap.h
-*** alpine-2.00/pith/mailcap.h 2008-03-18 10:24:31.000000000 -0700
---- alpine-2.00.I.USE/pith/mailcap.h 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 28,33 ****
---- 28,34 ----
- int mailcap_can_display(int, char *, BODY *, int);
- MCAP_CMD_S *mailcap_build_command(int, char *, BODY *, char *, int *, int);
- void mailcap_free(void);
-+ char *mc_template(char *, BODY *, int);
-
- /* currently mandatory to implement stubs */
-
-diff -rc alpine-2.00/pith/mailcmd.c alpine-2.00.I.USE/pith/mailcmd.c
-*** alpine-2.00/pith/mailcmd.c 2008-07-09 22:01:13.000000000 -0700
---- alpine-2.00.I.USE/pith/mailcmd.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 38,43 ****
---- 38,44 ----
- #include "../pith/ablookup.h"
- #include "../pith/search.h"
- #include "../pith/charconv/utf8.h"
-+ #include "../pith/rules.h"
-
- #ifdef _WINDOWS
- #include "../pico/osdep/mswin.h"
-***************
-*** 659,664 ****
---- 660,666 ----
- strncpy(ps_global->cur_folder, p, 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(ps_global->mail_stream, 0);
- /* MUST sort before restoring msgno! */
-***************
-*** 771,776 ****
---- 773,783 ----
- if(stream)
- sp_set_first_unseen(stream, 0L);
-
-+ /* in case we closed the old stream by cancelling the connection, do
-+ * not let that interfere with opening the new stream.
-+ */
-+ ps_global->user_says_cancel = 0;
-+
- m = context_open((new_context && !open_inbox) ? new_context : NULL,
- stream,
- open_inbox ? ps_global->VAR_INBOX_PATH : expanded_file,
-***************
-*** 974,979 ****
---- 981,987 ----
-
- clear_index_cache(ps_global->mail_stream, 0);
- reset_index_format();
-+ setup_threading_index_style();
-
- /*
- * Start news reading with messages the user's marked deleted
-***************
-*** 1092,1098 ****
-
- 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)
---- 1100,1109 ----
-
- 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)
-***************
-*** 1114,1237 ****
- 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)){
- /*
---- 1125,1131 ----
- 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)){
- /*
-***************
-*** 1409,1417 ****
- /* 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)
- || (pith_opt_read_msg_prompt
- && (*pith_opt_read_msg_prompt)(seen_not_del, VAR_READ_MESSAGE_FOLDER)))
- /* move inbox's read messages */
---- 1303,1313 ----
- /* 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)
- || (pith_opt_read_msg_prompt
- && (*pith_opt_read_msg_prompt)(seen_not_del, VAR_READ_MESSAGE_FOLDER)))
- /* move inbox's read messages */
-***************
-*** 1682,1687 ****
---- 1578,1586 ----
- 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;
-***************
-*** 1721,1728 ****
- snprintf(buf, buflen, "Moving %s read message%s to \"%s\"",
- comatose(searched), plural(searched), dstfldr);
- we_cancel = busy_cue(buf, NULL, 0);
-! if(save(ps_global, stream, save_context, dstfldr, msgmap,
-! SV_DELETE | SV_FIX_DELS | SV_INBOXWOCNTXT) == searched)
- strncpy(bufp = buf + 1, "Moved", MIN(5,buflen)); /* change Moving to Moved */
-
- buf[buflen-1] = '\0';
---- 1620,1628 ----
- snprintf(buf, buflen, "Moving %s read message%s to \"%s\"",
- comatose(searched), plural(searched), dstfldr);
- we_cancel = busy_cue(buf, NULL, 0);
-! ps_global->exiting = 1;
-! if((save(ps_global, stream, save_context, dstfldr, msgmap,
-! SV_DELETE | SV_FIX_DELS | SV_INBOXWOCNTXT) == searched))
- strncpy(bufp = buf + 1, "Moved", MIN(5,buflen)); /* change Moving to Moved */
-
- buf[buflen-1] = '\0';
-***************
-*** 1760,1766 ****
- && ((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;
---- 1660,1668 ----
- && ((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;
-***************
-*** 2158,2165 ****
-
-
- int
-! agg_text_select(MAILSTREAM *stream, MSGNO_S *msgmap, char type, int not,
-! int check_for_my_addresses,
- char *sstring, char *charset, SEARCHSET **limitsrch)
- {
- int old_imap, we_cancel;
---- 2060,2067 ----
-
-
- int
-! agg_text_select(MAILSTREAM *stream, MSGNO_S *msgmap, char type, char *namehdr,
-! int not, int check_for_my_addresses,
- char *sstring, char *charset, SEARCHSET **limitsrch)
- {
- int old_imap, we_cancel;
-***************
-*** 2308,2313 ****
---- 2210,2219 ----
-
- if(!mepgm)
- 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 */
-***************
-*** 2714,2716 ****
---- 2620,2921 ----
-
- return(*target ? target : NULL);
- }
-+
-+ char *
-+ move_read_msgs_using_rules(MAILSTREAM *stream, char *dstfldr, char *buf)
-+ {
-+ CONTEXT_S *save_context = NULL;
-+ char **folder_to_save = NULL;
-+ int num, we_cancel;
-+ long i, j, success;
-+ MSGNO_S *msgmap = NULL;
-+ unsigned long nmsgs = 0L, stream_nmsgs;
-+
-+ 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);
-+ stream_nmsgs = 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(stream, msgmap);
-+ sprintf(buf, "Moving %s read message%s to \"%.45s\"",
-+ comatose(num), plural(num), folder_to_save[i]);
-+ we_cancel = busy_cue(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_cue(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;
-+ }
-+
-+ char *
-+ get_folder_to_save(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_SAVE, 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;
-+ }
-+
-+ MAILSTREAM *
-+ find_open_stream(void)
-+ {
-+ return saved_stream;
-+ }
-+
-+ unsigned long
-+ rules_cursor_pos(MAILSTREAM *stream)
-+ {
-+ MSGNO_S *msgmap = sp_msgmap(stream);
-+ return rule_curpos != 0L ? rule_curpos : mn_m2raw(msgmap,mn_get_cur(msgmap));
-+ }
-+
-+ void
-+ setup_threading_index_style(void)
-+ {
-+ RULE_RESULT *rule;
-+ NAMEVAL_S *v;
-+ int i;
-+
-+ rule = get_result_rule(V_THREAD_INDEX_STYLE_RULES, FOR_THREAD, 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);
-+ }
-+ }
-+ }
-+
-+ unsigned
-+ get_perfolder_startup_rule(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_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;
-+ }
-+
-+ void
-+ find_startup_position(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;
-+
-+ }
-+ }
-diff -rc alpine-2.00/pith/mailcmd.h alpine-2.00.I.USE/pith/mailcmd.h
-*** alpine-2.00/pith/mailcmd.h 2008-07-09 22:01:13.000000000 -0700
---- alpine-2.00.I.USE/pith/mailcmd.h 2011-02-07 20:33:44.000000000 -0800
-***************
-*** 41,46 ****
---- 41,48 ----
- #define DB_FROMTAB 0x02 /* opening because of TAB command */
- #define DB_INBOXWOCNTXT 0x04 /* interpret inbox as one true inbox */
-
-+ static MAILSTREAM *saved_stream;
-+ static unsigned long rule_curpos = 0L;
-
- /*
- * generic "is aggregate message command?" test
-***************
-*** 53,58 ****
---- 55,61 ----
- void bogus_utf8_command(char *, char *);
- int can_set_flag(struct pine *, char *, int);
- void cmd_cancelled(char *);
-+ void cmd_quota(struct pine *);
- int cmd_delete(struct pine *, MSGNO_S *, int, char *(*)(struct pine *, MSGNO_S *));
- int cmd_undelete(struct pine *, MSGNO_S *, int);
- int cmd_expunge_work(MAILSTREAM *, MSGNO_S *);
-***************
-*** 61,71 ****
- void expunge_and_close(MAILSTREAM *, char **, unsigned long);
- void agg_select_all(MAILSTREAM *, MSGNO_S *, long *, int);
- char *move_read_msgs(MAILSTREAM *, char *, char *, size_t, long);
- char *move_read_incoming(MAILSTREAM *, CONTEXT_S *, char *, char **, char *, size_t);
- void cross_delete_crossposts(MAILSTREAM *);
- long zoom_index(struct pine *, MAILSTREAM *, MSGNO_S *, int);
- int unzoom_index(struct pine *, MAILSTREAM *, MSGNO_S *);
-! int agg_text_select(MAILSTREAM *, MSGNO_S *, char, int, int, char *,
- char *, SEARCHSET **);
- int agg_flag_select(MAILSTREAM *, int, int, SEARCHSET **);
- char *get_uname(char *, char *, int);
---- 64,81 ----
- void expunge_and_close(MAILSTREAM *, char **, unsigned long);
- void agg_select_all(MAILSTREAM *, MSGNO_S *, long *, int);
- char *move_read_msgs(MAILSTREAM *, char *, char *, size_t, long);
-+ char *move_read_msgs_using_rules (MAILSTREAM *, char *, char *);
-+ unsigned get_perfolder_startup_rule (MAILSTREAM *, int, char *);
-+ void setup_threading_index_style (void);
-+ void find_startup_position (int, MAILSTREAM *, long);
-+ char *get_folder_to_save (MAILSTREAM *, long, char *);
- char *move_read_incoming(MAILSTREAM *, CONTEXT_S *, char *, char **, char *, size_t);
-+ MAILSTREAM *find_open_stream (void);
-+ unsigned long rules_cursor_pos (MAILSTREAM *);
- void cross_delete_crossposts(MAILSTREAM *);
- long zoom_index(struct pine *, MAILSTREAM *, MSGNO_S *, int);
- int unzoom_index(struct pine *, MAILSTREAM *, MSGNO_S *);
-! int agg_text_select(MAILSTREAM *, MSGNO_S *, char, char *, int, int, char *,
- char *, SEARCHSET **);
- int agg_flag_select(MAILSTREAM *, int, int, SEARCHSET **);
- char *get_uname(char *, char *, int);
-diff -rc alpine-2.00/pith/mailindx.c alpine-2.00.I.USE/pith/mailindx.c
-*** alpine-2.00/pith/mailindx.c 2008-03-03 09:52:11.000000000 -0800
---- alpine-2.00.I.USE/pith/mailindx.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 16,21 ****
---- 16,22 ----
-
- #include "../pith/headers.h"
- #include "../pith/mailindx.h"
-+ #include "../pith/pineelt.h"
- #include "../pith/mailview.h"
- #include "../pith/flag.h"
- #include "../pith/icache.h"
-***************
-*** 39,44 ****
---- 40,46 ----
- #include "../pith/send.h"
- #include "../pith/options.h"
- #include "../pith/ablookup.h"
-+ #include "../pith/rules.h"
- #ifdef _WINDOWS
- #include "../pico/osdep/mswin.h"
- #endif
-***************
-*** 103,109 ****
- void set_print_format(IELEM_S *, int, int);
- void set_ielem_widths_in_field(IFIELD_S *);
-
--
- #define BIGWIDTH 2047
-
-
---- 105,110 ----
-***************
-*** 227,232 ****
---- 228,234 ----
- case iSTime:
- case iKSize:
- case iSize:
-+ case iSizeThread:
- case iPrioAlpha:
- (*answer)[column].req_width = 7;
- break;
-***************
-*** 291,296 ****
---- 293,301 ----
- case iSDate:
- case iSDateTime:
- case iSDateTime24:
-+ case iPrefDate:
-+ case iPrefTime:
-+ case iPrefDateTime:
- {
- /*
- * Format a date to see how long it is.
-***************
-*** 299,312 ****
- * of the translated yesterdays and friends but...
- */
- struct tm tm;
- char ss[100];
-
- memset(&tm, 0, sizeof(tm));
- tm.tm_year = 106;
- tm.tm_mon = 11;
- tm.tm_mday = 31;
-! our_strftime(ss, sizeof(ss), "%x", &tm);
-! (*answer)[column].req_width = MIN(MAX(9, utf8_width(ss)), 20);
- }
-
- (*answer)[column].monabb_width = monabb_width;
---- 304,332 ----
- * of the translated yesterdays and friends but...
- */
- struct tm tm;
-+ int len = 20;
- char ss[100];
-
- memset(&tm, 0, sizeof(tm));
- tm.tm_year = 106;
- tm.tm_mon = 11;
- tm.tm_mday = 31;
-! tm.tm_hour = 3;
-! tm.tm_min = 23;
-! tm.tm_wday = 3;
-! switch((*answer)[column].ctype){
-! case iPrefTime:
-! our_strftime(ss, sizeof(ss), "%X", &tm);
-! break;
-! case iPrefDateTime:
-! our_strftime(ss, sizeof(ss), "%c", &tm);
-! len = 32;
-! break;
-! default:
-! our_strftime(ss, sizeof(ss), "%x", &tm);
-! break;
-! }
-! (*answer)[column].req_width = MIN(MAX(9, utf8_width(ss)), len);
- }
-
- (*answer)[column].monabb_width = monabb_width;
-***************
-*** 355,360 ****
---- 375,387 ----
- PAT_STATE pstate;
- PAT_S *pat;
- int we_set_it = 0;
-+ char *rule;
-+
-+ if(rule = get_rule_result(FOR_INDEX, ps_global->cur_folder, V_INDEX_RULES)){
-+ init_index_format(rule, &ps_global->index_disp_format);
-+ fs_give((void **)&rule);
-+ return;
-+ }
-
- if(ps_global->mail_stream && nonempty_patterns(rflags, &pstate)){
- for(pat = first_pattern(&pstate); pat; pat = next_pattern(&pstate)){
-***************
-*** 428,441 ****
- 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},
- {"SHORTIMAPSTATUS", iSIStatus, FOR_INDEX},
---- 455,469 ----
- 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},
- {"SHORTIMAPSTATUS", iSIStatus, FOR_INDEX},
-***************
-*** 444,498 ****
- {"SUBJECTTEXT", iSubjectText, FOR_INDEX},
- {"SUBJKEYTEXT", iSubjKeyText, FOR_INDEX},
- {"SUBJKEYINITTEXT", iSubjKeyInitText, FOR_INDEX},
-! {"OPENINGTEXT", iOpeningText, FOR_INDEX},
-! {"OPENINGTEXTNQ", iOpeningTextNQ, FOR_INDEX},
-! {"KEY", iKey, FOR_INDEX},
-! {"KEYINIT", iKeyInit, FOR_INDEX},
- {"DESCRIPSIZE", iDescripSize, FOR_INDEX},
- {"ATT", iAtt, FOR_INDEX},
- {"SCORE", iScore, FOR_INDEX},
- {"PRIORITY", iPrio, FOR_INDEX},
- {"PRIORITYALPHA", iPrioAlpha, FOR_INDEX},
-! {"PRIORITY!", iPrioBang, 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},
-! {"SMARTDATEISO", iSDateIso, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATESHORTISO",iSDateIsoS, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATES1", iSDateS1, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATES2", iSDateS2, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATES3", iSDateS3, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATES4", iSDateS4, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIME", iSDateTime, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIMEISO",iSDateTimeIso, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIMESHORTISO",iSDateTimeIsoS,FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIMES1", iSDateTimeS1, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIMES2", iSDateTimeS2, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIMES3", iSDateTimeS3, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIMES4", iSDateTimeS4, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIME24", iSDateTime24, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIMEISO24", iSDateTimeIso24,FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIMESHORTISO24",iSDateTimeIsoS24,FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIMES124", iSDateTimeS124, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIMES224", iSDateTimeS224, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIMES324", iSDateTimeS324, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"SMARTDATETIMES424", iSDateTimeS424, 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},
---- 472,529 ----
- {"SUBJECTTEXT", iSubjectText, FOR_INDEX},
- {"SUBJKEYTEXT", iSubjKeyText, FOR_INDEX},
- {"SUBJKEYINITTEXT", iSubjKeyInitText, FOR_INDEX},
-! {"OPENINGTEXT", iOpeningText, FOR_INDEX|FOR_RULE|FOR_SAVE|FOR_TRIM},
-! {"OPENINGTEXTNQ", iOpeningTextNQ, FOR_INDEX|FOR_RULE|FOR_SAVE|FOR_TRIM},
-! {"KEY", iKey, FOR_INDEX|FOR_RULE|FOR_SAVE|FOR_COMPOSE},
-! {"KEYINIT", iKeyInit, FOR_INDEX|FOR_RULE|FOR_SAVE|FOR_COMPOSE},
- {"DESCRIPSIZE", iDescripSize, FOR_INDEX},
- {"ATT", iAtt, FOR_INDEX},
- {"SCORE", iScore, FOR_INDEX},
- {"PRIORITY", iPrio, FOR_INDEX},
- {"PRIORITYALPHA", iPrioAlpha, FOR_INDEX},
-! {"PRIORITY!", iPrioBang, 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},
-! {"SMARTDATEISO", iSDateIso, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATESHORTISO",iSDateIsoS, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATES1", iSDateS1, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATES2", iSDateS2, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATES3", iSDateS3, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATES4", iSDateS4, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIME", iSDateTime, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIMEISO",iSDateTimeIso, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIMESHORTISO",iSDateTimeIsoS,FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIMES1", iSDateTimeS1, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIMES2", iSDateTimeS2, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIMES3", iSDateTimeS3, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIMES4", iSDateTimeS4, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIME24", iSDateTime24, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIMEISO24", iSDateTimeIso24,FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIMESHORTISO24",iSDateTimeIsoS24,FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIMES124", iSDateTimeS124, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIMES224", iSDateTimeS224, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIMES324", iSDateTimeS324, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"SMARTDATETIMES424", iSDateTimeS424, 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_RULE|FOR_COMPOSE},
-! {"TO", iTo, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_COMPOSE},
-! {"SENDER", iSender, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"CC", iCc, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_SAVE|FOR_SAVE},
-! {"ADDRESSTO", iAddressTo, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"ADDRESSCC", iAddressCc, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"ADDRESSRECIPS", iAddressRecip, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
- {"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},
-***************
-*** 501,559 ****
- {"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},
-! {"PREFDATE", iPrefDate, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"PREFTIME", iPrefTime, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE},
-! {"PREFDATETIME", iPrefDateTime, 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},
-! {"CURPREFDATE", iCurPrefDate, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT},
-! {"CURPREFTIME", iCurPrefTime, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT},
- {"CURPREFDATETIME", iCurPrefDateTime,
-! 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},
- {"HEADER", iHeader, FOR_INDEX},
- {"TEXT", iText, FOR_INDEX},
- {"ARROW", iArrow, FOR_INDEX},
- {"NEWLINE", iNewLine, FOR_REPLY_INTRO},
- {"CURSORPOS", iCursorPos, FOR_TEMPLATE},
- {NULL, iNothing, FOR_NOTHING}
- };
-
- INDEX_PARSE_T *
- itoken(int i)
- {
---- 532,613 ----
- {"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},
-! {"PREFDATE", iPrefDate, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"PREFTIME", iPrefTime, FOR_INDEX|FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_RULE|FOR_SAVE},
-! {"PREFDATETIME", iPrefDateTime, 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_FILT|FOR_RULE|FOR_SAVE},
-! {"CURDATEISO", iCurDateIso, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURDATEISOS", iCurDateIsoS, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURTIME24", iCurTime24, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURTIME12", iCurTime12, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURDAY", iCurDay, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURDAY2DIGIT", iCurDay2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURDAYOFWEEK", iCurDayOfWeek, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
- {"CURDAYOFWEEKABBREV", iCurDayOfWeekAbb,
-! FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURMONTH", iCurMon, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURMONTH2DIGIT", iCurMon2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURMONTHLONG", iCurMonLong, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURMONTHABBREV", iCurMonAbb, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURYEAR", iCurYear, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURYEAR2DIGIT", iCurYear2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURPREFDATE", iCurPrefDate, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"CURPREFTIME", iCurPrefTime, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
- {"CURPREFDATETIME", iCurPrefDateTime,
-! FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"LASTMONTH", iLstMon, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"LASTMONTH2DIGIT", iLstMon2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"LASTMONTHLONG", iLstMonLong, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"LASTMONTHABBREV", iLstMonAbb, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"LASTMONTHYEAR", iLstMonYear, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
- {"LASTMONTHYEAR2DIGIT", iLstMonYear2Digit,
-! FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"LASTYEAR", iLstYear, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
-! {"LASTYEAR2DIGIT", iLstYear2Digit, FOR_REPLY_INTRO|FOR_TEMPLATE|FOR_FILT|FOR_RULE|FOR_SAVE},
- {"HEADER", iHeader, FOR_INDEX},
- {"TEXT", iText, FOR_INDEX},
- {"ARROW", iArrow, FOR_INDEX},
- {"NEWLINE", iNewLine, FOR_REPLY_INTRO},
- {"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},
-+ {"PROCID", iProcid, FOR_RULE|FOR_RESUB|FOR_FLAG|FOR_COMPOSE|FOR_TRIM|FOR_TEMPLATE},
-+ {"PKEY", iPkey, FOR_RULE|FOR_KEY},
-+ {"SCREEN", iScreen, FOR_RULE|FOR_KEY},
-+ {"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}
- };
-
-+ INDEX_PARSE_T itokensinv[sizeof(itokens)/sizeof(itokens[0])];
-+
-+ void
-+ inverse_itokens(void)
-+ {
-+ INDEX_PARSE_T *pt;
-+ for (pt = itokens; pt->name; pt++)
-+ itokensinv[pt->ctype].ctype = pt - itokens;
-+
-+ }
-+
- INDEX_PARSE_T *
- itoken(int i)
- {
-***************
-*** 913,919 ****
- iSDateTimeS1, iSDateTimeS2, iSDateTimeS3, iSDateTimeS4,
- iSDateTimeIso24, iSDateTimeIsoS24,
- iSDateTimeS124, iSDateTimeS224, iSDateTimeS324, iSDateTimeS424,
-! iSize, iSizeComma, iSizeNarrow, iKSize, iDescripSize,
- iPrio, iPrioBang, iPrioAlpha,
- iAtt, iTime24, iTime12, iTimezone, iMonAbb, iYear, iYear2Digit,
- iDay2Digit, iMon2Digit, iDayOfWeekAbb, iScore, iMonLong, iDayOfWeek
---- 967,973 ----
- iSDateTimeS1, iSDateTimeS2, iSDateTimeS3, iSDateTimeS4,
- iSDateTimeIso24, iSDateTimeIsoS24,
- iSDateTimeS124, iSDateTimeS224, iSDateTimeS324, iSDateTimeS424,
-! iSize, iSizeComma, iSizeNarrow, iKSize, iDescripSize, iSizeThread,
- iPrio, iPrioBang, iPrioAlpha,
- iAtt, iTime24, iTime12, iTimezone, iMonAbb, iYear, iYear2Digit,
- iDay2Digit, iMon2Digit, iDayOfWeekAbb, iScore, iMonLong, iDayOfWeek
-***************
-*** 1105,1110 ****
---- 1159,1165 ----
- case iTime12:
- case iSize:
- case iKSize:
-+ case iSizeThread:
- cdesc->actual_length = 7;
- cdesc->adjustment = Right;
- break;
-***************
-*** 1198,1204 ****
- 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 */
---- 1253,1259 ----
- 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 */
-***************
-*** 1581,1590 ****
-
- /* 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
---- 1636,1647 ----
-
- /* find next thread which is visible */
- do{
-+ unsigned long branch;
- if(mn_get_revsort(msgmap) && thrd->prevthd)
- thrd = fetch_thread(stream, thrd->prevthd);
-! /*branch = get_branch(stream,thrd)*/
-! else if(!mn_get_revsort(msgmap) && thrd->branch)
-! thrd = fetch_thread(stream, thrd->branch);
- else
- thrd = NULL;
- } while(thrd
-***************
-*** 1970,1975 ****
---- 2027,2033 ----
- ICE_S *ice, **icep;
- IFIELD_S *ifield;
- IELEM_S *ielem;
-+ COLOR_PAIR *color = NULL;
- struct variable *vars = ps_global->vars;
-
- dprint((8, "=== format_index_line(msgno=%ld,rawno=%ld) ===\n",
-***************
-*** 1995,2007 ****
- */
- ice = copy_ice(ice);
-
- /* 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 */
- for(cdesc = ps_global->index_disp_format; cdesc->ctype != iNothing; cdesc++)
---- 2053,2062 ----
- */
- ice = copy_ice(ice);
-
-+ thrd = fetch_thread(idata->stream, idata->rawno);
- /* is this a collapsed thread index line? */
-! if(!idata->bogus && THREADING())
-! collapsed = thrd && thread_is_kolapsed(ps_global, idata->stream, ps_global->msgmap, idata->rawno);
-
- /* calculate contents of the required fields */
- for(cdesc = ps_global->index_disp_format; cdesc->ctype != iNothing; cdesc++)
-***************
-*** 2433,2438 ****
---- 2488,2511 ----
- from_str(cdesc->ctype, idata, str, sizeof(str), ice);
- break;
-
-+ case iAddressTo:
-+ case iAddressCc:
-+ case iAddressRecip:
-+ {ENVELOPE *env;
-+ int we_clear;
-+ env = rules_fetchenvelope(idata, &we_clear);
-+ sprintf(str, "%-*.*s", ifield->width, ifield->width,
-+ detoken_src((cdesc->ctype == iAddressTo
-+ ? "_ADDRESSTO_"
-+ : (cdesc->ctype == iAddressCc
-+ ? "_ADRESSCC_"
-+ : "_ADRESSRECIPS_")), FOR_INDEX,
-+ env, NULL, NULL, NULL));
-+ if(we_clear)
-+ mail_free_envelope(&env);
-+ }
-+ break;
-+
- case iTo:
- if(((field = ((addr = fetch_to(idata))
- ? "To"
-***************
-*** 2499,2505 ****
---- 2572,2601 ----
-
- break;
-
-+ case iSizeThread:
-+ if (!THREADING()){
-+ goto getsize;
-+ } else if (collapsed){
-+ l = count_flags_in_thread(idata->stream, thrd, F_NONE);
-+ snprintf(str, sizeof(str), "(%lu)", l);
-+ }
-+ else{
-+ thrd = fetch_thread(idata->stream, idata->rawno);
-+ if(!thrd)
-+ snprintf(str, sizeof(str), "%s", "Error");
-+ else{
-+ long lengthb;
-+ lengthb = get_length_branch(idata->stream, idata->rawno);
-+ if (lengthb > 0L)
-+ snprintf(str, sizeof(str), "(%lu)", lengthb);
-+ else
-+ snprintf(str,sizeof(str), "%s", " ");
-+ }
-+ }
-+ break;
-+
- case iSize:
-+ getsize:
- /* 0 ... 9999 */
- if((l = fetch_size(idata)) < 10*1000L)
- snprintf(str, sizeof(str), "(%lu)", l);
-***************
-*** 2753,2759 ****
- if(first_text){
- strncpy(str, first_text, BIGWIDTH);
- str[BIGWIDTH] = '\0';
-- fs_give((void **) &first_text);
- }
- }
-
---- 2849,2854 ----
-***************
-*** 2913,2918 ****
---- 3008,3021 ----
- if(!ifield->ielem){
- ielem = new_ielem(&ifield->ielem);
-
-+ if(color = hdr_color(itokens[itokensinv[cdesc->ctype].ctype].name, NULL, ps_global->index_token_colors)){
-+ if(pico_usingcolor()){
-+ ielem->color = new_color_pair(color->fg, color->bg);
-+ ielem->type = eTypeCol;
-+ }
-+ free_color_pair(&color);
-+ }
-+
- ielem->freedata = 1;
- ielem->data = cpystr(str);
- ielem->datalen = strlen(str);
-***************
-*** 3670,3675 ****
---- 3773,3829 ----
- gf_io_t pc;
- long partial_fetch_len = 0L;
- SEARCHSET *ss, **sset;
-+ MESSAGECACHE *mc;
-+ PINELT_S *pelt;
-+
-+ /* we cache the result we get from this function, so that we do not have to
-+ * refetch the text in case there is a change. We could cache in the envelope
-+ * but c-client does not have a special field for that, nor we want to use the
-+ * sparep pointer, since there could be other uses for sparep later, and even
-+ * if we add a pointer to the ENVELOPE structure, we would be caching the same
-+ * text twice (one in a private pointer, and the new pointer) and that would
-+ * not make sense. Instead we will use an elt for this
-+ */
-+
-+ if((mc = mail_elt(idata->stream, idata->rawno))
-+ && ((pelt = (PINELT_S *) mc->sparep) == NULL)){
-+ pelt = (PINELT_S *) fs_get(sizeof(PINELT_S));
-+ memset(pelt, 0, sizeof(PINELT_S));
-+ }
-+
-+ /* If there were no rules, we would just return the firsttext
-+ * as cached in the pelt pointer, but if we are here and there
-+ * is a rule, and the firsttext that is cached changes as a
-+ * result of the rule, we need to refetch the text and process it
-+ * again
-+ */
-+
-+ if(pelt && pelt->firsttextraw != NULL){
-+ char buf[4*1024+1], ftext[6*1024+1], *rule_result;
-+ strncpy(buf, pelt->firsttextraw, sizeof(buf));
-+ buf[sizeof(buf)-1] = '\0';
-+ if(rule_result = find_value((delete_quotes
-+ ? "_OPENINGTEXTNQ_" : "_OPENINGTEXT_"),
-+ buf, PROCESS_SP, idata, 4)){
-+ collspaces(rule_result);
-+ strncpy(buf, rule_result, sizeof(buf));
-+ buf[sizeof(buf) - 1] = '\0';
-+ fs_give((void **) &rule_result);
-+ }
-+ ftext[0] = '\0';
-+ iutf8ncpy(ftext, buf, sizeof(ftext));
-+ ftext[sizeof(ftext)-1] = '\0';
-+ removing_trailing_white_space(ftext);
-+ if(!strcmp(ftext, pelt->firsttext)) /* same as last pass */
-+ return(pelt->firsttext);
-+ if(strlen(pelt->firsttextraw) > 256 /* not the same, but long enough */
-+ && utf8_width(ftext) >= 50){
-+ fs_give((void **)&pelt->firsttext);
-+ pelt->firsttext = cpystr(ftext);
-+ return pelt->firsttext;
-+ }
-+ fs_give((void **)&pelt->firsttext); /* do it again */
-+ }
-
- try_again:
-
-***************
-*** 3706,3712 ****
- && ALLOWED_SUBTYPE(subtype))){
-
- if((so = so_get(CharStar, NULL, EDIT_ACCESS)) != NULL){
-! char buf[1025], *p;
- unsigned char c;
- int success;
- int one_space_done = 0;
---- 3860,3866 ----
- && ALLOWED_SUBTYPE(subtype))){
-
- if((so = so_get(CharStar, NULL, EDIT_ACCESS)) != NULL){
-! char buf[4*1024+1], rawbuf[6*1024+1], *p;
- unsigned char c;
- int success;
- int one_space_done = 0;
-***************
-*** 3763,3769 ****
---- 3917,3939 ----
-
- if(p > buf){
- size_t l;
-+ ENVELOPE *env;
-+ char *rule_result;
-
-+ if(pelt && pelt->firsttextraw)
-+ fs_give((void **)&pelt->firsttextraw);
-+ iutf8ncpy(rawbuf, buf, sizeof(rawbuf));
-+ rawbuf[sizeof(rawbuf)-1] = '\0';
-+ removing_trailing_white_space(rawbuf);
-+ pelt->firsttextraw = cpystr(rawbuf);
-+ if(rule_result = find_value((delete_quotes
-+ ? "_OPENINGTEXTNQ_" : "_OPENINGTEXT_"),
-+ buf, PROCESS_SP, idata, 4)){
-+ collspaces(rule_result);
-+ strncpy(buf, rule_result, sizeof(buf));
-+ buf[sizeof(buf) - 1] = '\0';
-+ fs_give((void **) &rule_result);
-+ }
- l = strlen(buf);
- l += 100;
- firsttext = fs_get((l+1) * sizeof(char));
-***************
-*** 3787,3792 ****
---- 3957,3964 ----
- goto try_again;
- }
- }
-+ if(mc && pelt)
-+ pelt->firsttext = firsttext;
- }
- }
- }
-***************
-*** 4271,4276 ****
---- 4443,4449 ----
- tm.tm_mday = MIN(MAX(d.day, 1), 31);
- tm.tm_hour = MIN(MAX(d.hour, 0), 23);
- tm.tm_min = MIN(MAX(d.minute, 0), 59);
-+ tm.tm_wday = MIN(MAX(d.wkday, 0), 6);
- tmptr = &tm;
- }
-
-***************
-*** 5226,5235 ****
- {
- char *subject, *origsubj, *origstr, *rawsubj, *sptr = NULL;
- char *p, *border, *q = NULL, *free_subj = NULL;
-! char *sp;
- size_t len;
- int width = -1;
-! int depth = 0, mult = 2;
- int save;
- int do_subj = 0, truncated_tree = 0;
- PINETHRD_S *thd, *thdorig;
---- 5399,5408 ----
- {
- char *subject, *origsubj, *origstr, *rawsubj, *sptr = NULL;
- char *p, *border, *q = NULL, *free_subj = NULL;
-! char *sp, *rule_result;
- size_t len;
- int width = -1;
-! int depth = 0, mult = 2, collapsed, i, we_clear = 0;
- int save;
- int do_subj = 0, truncated_tree = 0;
- PINETHRD_S *thd, *thdorig;
-***************
-*** 5283,5289 ****
- * origsubj is the original subject but it has been decoded. We need
- * to free it at the end of this routine.
- */
-!
-
- /*
- * prepend_keyword will put the keyword stuff before the subject
---- 5456,5468 ----
- * origsubj is the original subject but it has been decoded. We need
- * to free it at the end of this routine.
- */
-! if (rule_result = find_value("_SUBJECT_", origsubj, PROCESS_SP, idata, 4)){
-! if(origsubj)
-! fs_give((void **)&origsubj);
-! we_clear++;
-! origsubj = cpystr(rule_result);
-! fs_give((void **)&rule_result);
-! }
-
- /*
- * prepend_keyword will put the keyword stuff before the subject
-***************
-*** 5371,5380 ****
-
- if(pith_opt_condense_thread_cue)
- width = (*pith_opt_condense_thread_cue)(thd, ice, &str, &strsize, width,
-! thd && thd->next
-! && get_lflag(idata->stream,
-! NULL,idata->rawno,
-! MN_COLL));
-
- /*
- * width is < available strsize and
---- 5550,5557 ----
-
- if(pith_opt_condense_thread_cue)
- width = (*pith_opt_condense_thread_cue)(thd, ice, &str, &strsize, width,
-! this_thread_is_kolapsed(ps_global, idata->stream, ps_global->msgmap, idata->rawno) &&
-! (count_thread(ps_global,idata->stream, ps_global->msgmap, idata->rawno) != 1));
-
- /*
- * width is < available strsize and
-***************
-*** 5724,5729 ****
---- 5901,5909 ----
-
- if(free_subj)
- fs_give((void **) &free_subj);
-+
-+ if (we_clear && origsubj)
-+ fs_give((void **)&origsubj);
- }
-
-
-***************
-*** 6002,6012 ****
- border = str + width;
- if(pith_opt_condense_thread_cue)
- width = (*pith_opt_condense_thread_cue)(thd, ice, &str, &strsize, width,
-! thd && thd->next
-! && get_lflag(idata->stream,
-! NULL,idata->rawno,
-! MN_COLL));
-!
- fptr = str;
-
- if(thd)
---- 6182,6189 ----
- border = str + width;
- if(pith_opt_condense_thread_cue)
- width = (*pith_opt_condense_thread_cue)(thd, ice, &str, &strsize, width,
-! this_thread_is_kolapsed(ps_global, idata->stream, ps_global->msgmap, idata->rawno) &&
-! (count_thread(ps_global,idata->stream, ps_global->msgmap, idata->rawno) != 1));
- fptr = str;
-
- if(thd)
-***************
-*** 6092,6107 ****
- ? "To"
- : (addr = fetch_cc(idata))
- ? "Cc"
-! : NULL))
-! && set_index_addr(idata, field, addr, "To: ",
-! strsize-1, fptr))
-! break;
-
- if(ctype == iFromTo &&
- (newsgroups = fetch_newsgroups(idata)) &&
- *newsgroups){
-! snprintf(fptr, strsize, "To: %-*.*s", strsize-1-4, strsize-1-4,
-! newsgroups);
- break;
- }
-
---- 6269,6301 ----
- ? "To"
- : (addr = fetch_cc(idata))
- ? "Cc"
-! : NULL))){
-! char *rule_result;
-! rule_result = find_value("_FROM_", NULL, 0, idata, 1);
-! if (!rule_result)
-! set_index_addr(idata, field, addr, "To: ",
-! strsize-1, fptr);
-! else{
-! sprintf(str, "%-*.*s", strsize-1, strsize-1,
-! rule_result);
-! fs_give((void **)&rule_result);
-! }
-
-+ break;
-+ }
- if(ctype == iFromTo &&
- (newsgroups = fetch_newsgroups(idata)) &&
- *newsgroups){
-! char *rule_result;
-! rule_result = find_value("_FROM_", NULL, 0, idata, 1);
-! if (!rule_result)
-! sprintf(str, "To: %-*.*s", strsize-1-4,
-! strsize-1-4, newsgroups);
-! else{
-! sprintf(str, "%-*.*s", strsize-1, strsize-1,
-! rule_result);
-! fs_give((void **)&rule_result);
-! }
- break;
- }
-
-***************
-*** 6114,6120 ****
- break;
-
- case iFrom:
-! set_index_addr(idata, "From", fetch_from(idata), NULL, strsize-1, fptr);
- break;
-
- case iAddress:
---- 6308,6322 ----
- break;
-
- case iFrom:
-! { char *rule_result;
-! rule_result = find_value("_FROM_", NULL, 0, idata, 4);
-! if (!rule_result)
-! set_index_addr(idata, "From", fetch_from(idata), NULL, strsize-1, fptr);
-! else{
-! sprintf(str, "%-*.*s", strsize-1, strsize-1, rule_result);
-! fs_give((void **)&rule_result);
-! }
-! }
- break;
-
- case iAddress:
-***************
-*** 6411,6413 ****
---- 6613,6676 ----
- }
- }
- }
-+
-+ void
-+ setup_threading_display_style(void)
-+ {
-+ RULE_RESULT *rule;
-+ NAMEVAL_S *v;
-+ int i;
-+
-+ rule = get_result_rule(V_THREAD_DISP_STYLE_RULES, FOR_THREAD, 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);
-+ }
-+ }
-+ }
-+
-+ char *
-+ find_value(char *token, char *use_this, int flag, INDEXDATA_S *idata, int nfcn)
-+ {
-+ int n = 0, i, rule_context, we_clear;
-+ char *rule_result = NULL, **list;
-+ ENVELOPE *env;
-+ RULELIST *rule;
-+ RULE_S *prule;
-+
-+ env = rules_fetchenvelope(idata, &we_clear);
-+ if(env && env->sparep)
-+ fs_give((void **)&env->sparep);
-+ if(we_clear)
-+ mail_free_envelope(&env);
-+ if(rule = get_rulelist_from_code(V_REPLACE_RULES, ps_global->rule_list)){
-+ list = functions_for_token(token);
-+ while(rule_result == NULL && (prule = get_rule(rule,n++))){
-+ rule_context = 0;
-+ if (prule->action->token && !strcmp(prule->action->token, token)){
-+ for (i = 0; i < nfcn; i++)
-+ if(list[i+1] && !strcmp(prule->action->function, list[i+1]))
-+ rule_context |= context_for_function(list[i+1]);
-+ if (rule_context){
-+ env = rules_fetchenvelope(idata, &we_clear);
-+ if(use_this)
-+ env->sparep = get_sparep_for_rule(use_this, flag);
-+ rule_result = process_rule(prule, rule_context, env);
-+ if(env->sparep)
-+ free_sparep_for_rule(&env->sparep);
-+ if(we_clear)
-+ mail_free_envelope(&env);
-+ }
-+ }
-+ }
-+ }
-+ return rule_result;
-+ }
-diff -rc alpine-2.00/pith/mailindx.h alpine-2.00.I.USE/pith/mailindx.h
-*** alpine-2.00/pith/mailindx.h 2008-02-01 10:42:29.000000000 -0800
---- alpine-2.00.I.USE/pith/mailindx.h 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 29,34 ****
---- 29,37 ----
-
-
- /* exported prototypes */
-+ SortOrder translate (char *, int);
-+ char *find_value (char *, char *, int, INDEXDATA_S *, int);
-+ void setup_threading_display_style (void);
- int msgline_hidden(MAILSTREAM *, MSGNO_S *, long, int);
- void adjust_cur_to_visible(MAILSTREAM *, MSGNO_S *);
- unsigned long line_hash(char *);
-***************
-*** 36,41 ****
---- 39,45 ----
- void free_index_format(INDEX_COL_S **);
- void reset_index_format(void);
- INDEX_PARSE_T *itoktype(char *, int);
-+ void inverse_itokens(void);
- char *prepend_keyword_subject(MAILSTREAM *, long, char *, SubjKW, IELEM_S **, char *);
- int get_index_line_color(MAILSTREAM *, SEARCHSET *, PAT_STATE **, COLOR_PAIR **);
- void setup_for_index_index_screen(void);
-diff -rc alpine-2.00/pith/mailview.c alpine-2.00.I.USE/pith/mailview.c
-*** alpine-2.00/pith/mailview.c 2008-07-11 16:20:32.000000000 -0700
---- alpine-2.00.I.USE/pith/mailview.c 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 51,57 ****
- #include "../pith/escapes.h"
- #include "../pith/keyword.h"
- #include "../pith/smime.h"
-!
-
- #define FBUF_LEN (50)
-
---- 51,60 ----
- #include "../pith/escapes.h"
- #include "../pith/keyword.h"
- #include "../pith/smime.h"
-! #include "../pith/osdep/color.h"
-! #include "../pico/estruct.h"
-! #include "../pico/pico.h"
-! #include "../pico/efunc.h"
-
- #define FBUF_LEN (50)
-
-***************
-*** 281,289 ****
- 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));
- }
-
- if((flgs & FM_DISPLAY)
---- 284,300 ----
- 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_quote_test, gf_line_test_opt(color_signature, &is_in_sig));
- }
-
- if((flgs & FM_DISPLAY)
-***************
-*** 291,298 ****
- && 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));
- }
-
- if(!(flgs & FM_NOWRAP)){
- wrapflags = (flgs & FM_DISPLAY) ? (GFW_HANDLES|GFW_SOFTHYPHEN) : GFW_NONE;
---- 302,311 ----
- && 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));
-
- if(!(flgs & FM_NOWRAP)){
- wrapflags = (flgs & FM_DISPLAY) ? (GFW_HANDLES|GFW_SOFTHYPHEN) : GFW_NONE;
-***************
-*** 1096,1122 ****
- color_signature(long int linenum, char *line, LT_INS_S **ins, 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,
---- 1109,1197 ----
- color_signature(long int linenum, char *line, LT_INS_S **ins, void *is_in_sig)
- {
- struct variable *vars = ps_global->vars;
-! int *in_sig_block, i, j,same_qstr = 0, plb;
- COLOR_PAIR *col = NULL;
-+ static char GLine[NSTRING] = {'\0'};
-+ static char PLine[NSTRING] = {'\0'};
-+ static char PPLine[NSTRING] = {'\0'};
-+ char NLine[NSTRING] = {'\0'};
-+ char rqstr[NSTRING] = {'\0'};
-+ char *p;
-+ static char *buf, buf2[NSTRING] = {'\0'};
-+ QSTRING_S *qs;
-+ static int qstrlen = 0;
-
- if(is_in_sig == NULL)
- return 0;
-
-+ if (linenum > 0){
-+ strncpy(PLine, GLine, sizeof(PLine));
-+ PLine[sizeof(PLine)-1] = '\0';
-+ }
-+
-+ if(p = strchr(tmp_20k_buf, '\015')) *p = '\0';
-+ strncpy(NLine, tmp_20k_buf, sizeof(NLine));
-+ NLine[sizeof(NLine) - 1] = '\0';
-+ if (p) *p = '\015';
-+
-+ strncpy(GLine, line, sizeof(GLine));
-+ GLine[sizeof(GLine) - 1] = '\0';
-+
-+ plb = line_isblank((ps_global->prefix && *ps_global->prefix
-+ ? ps_global->prefix : ">"), PLine, GLine, PPLine, NSTRING);
-+ qs = do_quote_match((ps_global->prefix && *ps_global->prefix
-+ ? ps_global->prefix : ">"),
-+ GLine, NLine, PLine, rqstr, NSTRING, plb);
-+ if(linenum > 0)
-+ strncpy(PPLine, PLine, NSTRING);
-+ strncpy(buf2, rqstr, NSTRING);
-+ 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,
-***************
-*** 1480,1497 ****
- return(0);
- }
-
-
- int
- url_hilite(long int linenum, char *line, LT_INS_S **ins, void *local)
- {
- register char *lp, *up = NULL, *urlp = NULL,
- *weburlp = NULL, *mailurlp = NULL;
-! int n, n1, n2, n3, l;
- char buf[256], color[256];
- HANDLE_S *h;
- URL_HILITE_S *uh;
-
-! for(lp = line; ; lp = up + n){
- /* scan for all of them so we can choose the first */
- if(F_ON(F_VIEW_SEL_URL,ps_global))
- urlp = rfc1738_scan(lp, &n1);
---- 1555,1632 ----
- return(0);
- }
-
-+ int
-+ incomplete_url(char *up, int n, int delim)
-+ {
-+ char *line, *line2;
-+ int rv = 0, len;
-+
-+ if(*(up + n) != '\0')
-+ return 0;
-+
-+ if(delim > 0)
-+ return 1;
-+
-+ if(F_ON(F_VIEW_LONG_URL, ps_global)){
-+ line = up;
-+ if(!strncmp(line, "http://", 7))
-+ line += 7;
-+ else if(!strncmp(line, "https://", 8))
-+ line += 8;
-+ if(strchr(line, '/') != NULL && (line = strrchr(line, '/')) != NULL){
-+ line++;
-+ line2 = strrchr(line, '.');
-+ rv = (strpbrk(line,"+#?=&") != NULL)
-+ || (!line2 || line-line2 > 4);
-+ }
-+ }
-+ return rv;
-+ }
-+
-
- int
- url_hilite(long int linenum, char *line, LT_INS_S **ins, void *local)
- {
- register char *lp, *up = NULL, *urlp = NULL,
- *weburlp = NULL, *mailurlp = NULL;
-! char *use_this_line, c, *begin_line, *end_line;
-! static int scannextline, delim = -1;
-! int n, n1, n2, n3, l, len;
-! int we_clear = 0, newhandle = 1, tie_off = 0;
- char buf[256], color[256];
- HANDLE_S *h;
- URL_HILITE_S *uh;
-
-! uh = (URL_HILITE_S *) local;
-! if((uh && uh->handlesp && ((h = *(uh->handlesp)) == NULL) || h->key == 0) ||
-! (!line || !*line) || linenum == 0)
-! scannextline = 0; /* initialize scannextline */
-!
-! if(scannextline != 0){
-! up = rfc1738_scan(line, &n1);
-!
-! /* if we found a url in the current line, but it is not at the beginning of
-! * the next line, or if there is no url in this line, we check if the url
-! * in the previous line continues in this line.
-! */
-!
-! if(line != up){
-! if(*uh->handlesp == NULL)
-! h = new_handle(uh->handlesp);
-! for(h = *uh->handlesp; h->next; h = h->next); /* get last handle */
-! len = h->h.url.path ? strlen(h->h.url.path) : 0;
-! use_this_line = (char *) fs_get((len + strlen(line) + 1)*sizeof(char));
-! sprintf(use_this_line,"%s%s", (h->h.url.path ? h->h.url.path : ""), line);
-! we_clear++;
-! newhandle = 0;
-! }
-! else
-! use_this_line = line;
-! }
-! else
-! use_this_line = line;
-!
-! for(lp = use_this_line; ; lp = up + n){
- /* scan for all of them so we can choose the first */
- if(F_ON(F_VIEW_SEL_URL,ps_global))
- urlp = rfc1738_scan(lp, &n1);
-***************
-*** 1501,1506 ****
---- 1636,1645 ----
- mailurlp = mail_addr_scan(lp, &n3);
-
- if(urlp || weburlp || mailurlp){
-+ if(scannextline == 0){
-+ newhandle++;
-+ delim = -1;
-+ }
- up = urlp ? urlp :
- weburlp ? weburlp : mailurlp;
- if(up == urlp && weburlp && weburlp < up)
-***************
-*** 1509,1515 ****
---- 1648,1663 ----
- up = mailurlp;
-
- if(up == urlp){
-+ if(delim < 0)
-+ delim = up > use_this_line && *(up - 1) == '<';
- n = n1;
-+ if(incomplete_url(up,n, delim))
-+ scannextline++;
-+ else{
-+ if(scannextline)
-+ tie_off++;
-+ scannextline = 0;
-+ }
- weburlp = mailurlp = NULL;
- }
- else if(up == weburlp){
-***************
-*** 1526,1561 ****
-
- uh = (URL_HILITE_S *) local;
-
-! h = new_handle(uh->handlesp);
-! h->type = URL;
-! h->h.url.path = (char *) fs_get((n + 10) * sizeof(char));
-! snprintf(h->h.url.path, n+10, "%s%.*s",
- weburlp ? "http://" : (mailurlp ? "mailto:" : ""), n, up);
-! h->h.url.path[n+10-1] = '\0';
-
- if(handle_start_color(color, sizeof(color), &l, uh->hdr_color))
-! ins = gf_line_test_new_ins(ins, up, color, l);
- else if(F_OFF(F_SLCTBL_ITEM_NOBOLD, ps_global))
-! ins = gf_line_test_new_ins(ins, up, url_embed(TAG_BOLDON), 2);
-
- buf[0] = TAG_EMBED;
- buf[1] = TAG_HANDLE;
- snprintf(&buf[3], sizeof(buf)-3, "%d", h->key);
- buf[sizeof(buf)-1] = '\0';
- buf[2] = strlen(&buf[3]);
-! ins = gf_line_test_new_ins(ins, up, buf, (int) buf[2] + 3);
-
- /* in case it was the current selection */
-! ins = gf_line_test_new_ins(ins, up + n, url_embed(TAG_INVOFF), 2);
-
- if(scroll_handle_end_color(color, sizeof(color), &l, uh->hdr_color))
-! ins = gf_line_test_new_ins(ins, up + n, color, l);
- else
-! ins = gf_line_test_new_ins(ins, up + n, url_embed(TAG_BOLDOFF), 2);
-
- urlp = weburlp = mailurlp = NULL;
- }
-
- return(0);
- }
-
---- 1674,1731 ----
-
- uh = (URL_HILITE_S *) local;
-
-! if(tie_off){
-! tie_off = 0; /* do only once */
-! begin_line = line;
-! end_line = line + n - strlen(h->h.url.path);
-! fs_give((void **)&h->h.url.path);
-! c = *(use_this_line + n);
-! *(use_this_line+n) = '\0';
-! h->h.url.path = cpystr(use_this_line);
-! *(use_this_line+n) = c;
-! }
-! else{
-! if(newhandle){
-! h = new_handle(uh->handlesp);
-! h->type = URL;
-! }
-! begin_line = newhandle ? (we_clear ? line + strlen(line) - strlen(up)
-! : up) : line;
-! end_line = newhandle ? begin_line + n : line + strlen(line);
-! if(scannextline && h->h.url.path)
-! fs_give((void **)&h->h.url.path);
-! h->h.url.path = (char *) fs_get((n + 10) * sizeof(char));
-! snprintf(h->h.url.path, n+10, "%s%.*s",
- weburlp ? "http://" : (mailurlp ? "mailto:" : ""), n, up);
-! h->h.url.path[n+10-1] = '\0';
-! }
-
- if(handle_start_color(color, sizeof(color), &l, uh->hdr_color))
-! ins = gf_line_test_new_ins(ins, begin_line, color, l);
- else if(F_OFF(F_SLCTBL_ITEM_NOBOLD, ps_global))
-! ins = gf_line_test_new_ins(ins, begin_line, url_embed(TAG_BOLDON), 2);
-
- buf[0] = TAG_EMBED;
- buf[1] = TAG_HANDLE;
- snprintf(&buf[3], sizeof(buf)-3, "%d", h->key);
- buf[sizeof(buf)-1] = '\0';
- buf[2] = strlen(&buf[3]);
-! ins = gf_line_test_new_ins(ins, begin_line, buf, (int) buf[2] + 3);
-
- /* in case it was the current selection */
-! ins = gf_line_test_new_ins(ins, end_line, url_embed(TAG_INVOFF), 2);
-
- if(scroll_handle_end_color(color, sizeof(color), &l, uh->hdr_color))
-! ins = gf_line_test_new_ins(ins, end_line, color, l);
- else
-! ins = gf_line_test_new_ins(ins, end_line, url_embed(TAG_BOLDOFF), 2);
-
- urlp = weburlp = mailurlp = NULL;
- }
-
-+ if(we_clear)
-+ fs_give((void **)&use_this_line);
-+
- return(0);
- }
-
-***************
-*** 1676,1681 ****
---- 1846,1922 ----
- }
-
-
-+ /* 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(long linenum, char *line, LT_INS_S **ins, void *local)
-+ {
-+ int i, plb, *code;
-+ char rqstr[NSTRING] = {'\0'}, buf[NSTRING] = {'\0'};
-+ char GLine[NSTRING] = {'\0'}, PLine[NSTRING] = {'\0'};
-+ char PPLine[NSTRING] = {'\0'}, NLine[NSTRING] = {'\0'};
-+ static char GLine1[NSTRING] = {'\0'};
-+ static char PLine1[NSTRING] = {'\0'};
-+ static char PPLine1[NSTRING] = {'\0'};
-+ static char GLine2[NSTRING] = {'\0'};
-+ static char PLine2[NSTRING] = {'\0'};
-+ static char PPLine2[NSTRING] = {'\0'};
-+ QSTRING_S *qs;
-+ int buflen = NSTRING < SIZEOF_20KBUF ? NSTRING - 1: SIZEOF_20KBUF - 1;
-+ int who, raw;
-+
-+ code = (int *)local;
-+ who = code ? (*code & COLORAQUO) : 0; /* may I ask who is calling? */
-+ raw = code ? (*code & RAWSTRING) : 0; /* return raw string */
-+ strncpy(GLine, (who ? GLine1 : GLine2), buflen);
-+ strncpy(PLine, (who ? PLine1 : PLine2), buflen);
-+ strncpy(PPLine, (who ? PPLine1 : PPLine2), buflen);
-+
-+ if (linenum > 0)
-+ strncpy(PLine, GLine, buflen);
-+
-+ strncpy(NLine, tmp_20k_buf, buflen);
-+
-+ if (line)
-+ strncpy(GLine, line, buflen);
-+ else
-+ GLine[0] = '\0';
-+
-+
-+ plb = line_isblank((ps_global->prefix && *ps_global->prefix
-+ ? ps_global->prefix : ">"), PLine, GLine, PPLine, NSTRING);
-+
-+ qs = do_quote_match((ps_global->prefix && *ps_global->prefix
-+ ? ps_global->prefix : ">"), GLine, NLine, PLine,
-+ rqstr, NSTRING, plb);
-+ if (raw)
-+ strncpy(buf, rqstr, NSTRING);
-+ else
-+ flatten_qstring(qs, buf, NSTRING);
-+ 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);
-+ if (linenum > 0)
-+ strncpy((who ? PPLine1 : PPLine2), PLine, buflen);
-+ strncpy((who ? GLine1 : GLine2), GLine, buflen);
-+ strncpy((who ? PLine1 : PLine2), PLine, buflen);
-+ return 1;
-+ }
-+
-
- #define UES_LEN 12
- #define UES_MAX 32
-***************
-*** 2377,2384 ****
- format_addr_string(s, n, sect, "Return-Path: ", e->return_path,
- flags, oacs, 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);
---- 2618,2638 ----
- format_addr_string(s, n, sect, "Return-Path: ", e->return_path,
- flags, oacs, 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,"<alpine.",8) &&
-+ 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);
-***************
-*** 2488,2493 ****
---- 2742,2962 ----
- return(color_pair);
- }
-
-+ void
-+ interval_free(ival)
-+ IVAL_S **ival;
-+ {
-+ if (!(*ival))
-+ return;
-+
-+ if ((*ival)->next)
-+ interval_free(&((*ival)->next));
-+
-+ fs_give((void **)(ival));
-+ }
-+
-+ IVAL_S *
-+ compute_interval (string, endm)
-+ char *string;
-+ int endm;
-+ {
-+ IVAL_S *ival = NULL, *nextival= NULL, *d;
-+ regmatch_t pmatch;
-+
-+ if(ps_global->paterror == 0)
-+ if (regexec(&ps_global->colorpat, string, 1, &pmatch, 0) == 0){
-+ ival = (IVAL_S *) fs_get(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, ival->start+1);
-+ if (nextival){
-+ if (nextival->start <= ival->end){
-+ ival->end = nextival->end;
-+ d = nextival->next;
-+ nextival->next = NULL;
-+ ival->next = d;
-+ interval_free(&nextival);
-+ }
-+ else
-+ ival->next = nextival;
-+ }
-+ }
-+ return ival;
-+ }
-+
-+ void
-+ regex_pattern(plist)
-+ char **plist;
-+ {
-+ int i = 0, j = 0, len = 0;
-+ char *pattern = NULL;
-+ regex_t preg;
-+
-+ if(ps_global->paterror == 0)
-+ regfree(&ps_global->colorpat);
-+
-+ if(plist && *plist && *plist){
-+ for (i = 0; plist[i] && plist[i][0]; i++)
-+ len += strlen(plist[i]) + 1;
-+ pattern = (char *) fs_get(len * sizeof(char));
-+ *pattern = '\0';
-+ for (j = 0; j < i; j++){
-+ strcat(pattern, plist[j]);
-+ strcat(pattern, (j < i - 1) ? "|" : "");
-+ }
-+ if ((ps_global->paterror = regcomp(&preg, pattern, REG_EXTENDED)) != 0)
-+ regfree(&preg);
-+ else
-+ ps_global->colorpat = preg;
-+ }
-+ if(pattern)
-+ fs_give((void **)&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 = 0;
-+ static char *pattern = NULL;
-+ /* char *buf;
-+
-+ 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 + i;
-+
-+ 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(ps_global->VAR_SPECIAL_TEXT && *ps_global->VAR_SPECIAL_TEXT
-+ && **ps_global->VAR_SPECIAL_TEXT && 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, 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, 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;
-+ }
-
- /*
- * The argument fieldname is something like "Subject:..." or "Subject".
-diff -rc alpine-2.00/pith/mailview.h alpine-2.00.I.USE/pith/mailview.h
-*** alpine-2.00/pith/mailview.h 2008-06-03 08:54:15.000000000 -0700
---- alpine-2.00.I.USE/pith/mailview.h 2011-02-07 20:33:43.000000000 -0800
-***************
-*** 29,34 ****
---- 29,40 ----
- #include "../pith/color.h"
-
-
-+ typedef struct IVAL {
-+ int start;
-+ int end;
-+ struct IVAL *next;
-+ } IVAL_S;
-+
- /* format_message flags */
- #define FM_DISPLAY 0x0001 /* result is headed for display */
- #define FM_NEW_MESS 0x0002 /* a new message so zero out attachment descrip */
-***************
-*** 125,130 ****
---- 131,145 ----
- int url_hilite(long, char *, LT_INS_S **, void *);
- int handle_start_color(char *, size_t, int *, int);
- int handle_end_color(char *, size_t, int *);
-+ IVAL_S *compute_interval(char *, int);
-+ void remove_spaces_ival(IVAL_S **, char *);
-+ void interval_free(IVAL_S **);
-+ void regex_pattern(char **);
-+ LT_INS_S **insert_color_special_text(LT_INS_S **, char **, IVAL_S *,
-+ int, COLOR_PAIR *);
-+ int any_color_in_string(char *);
-+ int length_color(char *, int);
-+ int color_this_text(long, char *, LT_INS_S **, void *);
-
- /*
- * BUG: BELOW IS UNIX/PC ONLY since config'd browser means nothing to webpine
-***************
-*** 141,146 ****
---- 156,162 ----
- char *display_parameters(PARAMETER *);
- char *pine_fetch_header(MAILSTREAM *, long, char *, char **, long);
- int color_signature(long, char *, LT_INS_S **, void *);
-+ int select_quote(long, char *, LT_INS_S **, void *);
- int scroll_handle_start_color(char *, size_t, int *);
- int scroll_handle_end_color(char *, size_t, int *, int);
- int width_at_this_position(unsigned char *, unsigned long);
-diff -rc alpine-2.00/pith/Makefile.am alpine-2.00.I.USE/pith/Makefile.am
-*** alpine-2.00/pith/Makefile.am 2008-06-03 08:54:15.000000000 -0700
---- alpine-2.00.I.USE/pith/Makefile.am 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 25,31 ****
- filter.c flag.c folder.c handle.c help.c helpindx.c hist.c icache.c imap.c init.c \
- keyword.c ldap.c list.c mailcap.c mailcmd.c mailindx.c maillist.c mailview.c \
- margin.c mimedesc.c mimetype.c msgno.c newmail.c news.c pattern.c pipe.c \
-! readfile.c remote.c reply.c rfc2231.c save.c search.c sequence.c send.c sort.c \
- state.c status.c store.c stream.c string.c strlst.c takeaddr.c tempfile.c text.c \
- thread.c adjtime.c url.c util.c helptext.c smkeys.c smime.c
-
---- 25,31 ----
- filter.c flag.c folder.c handle.c help.c helpindx.c hist.c icache.c imap.c init.c \
- keyword.c ldap.c list.c mailcap.c mailcmd.c mailindx.c maillist.c mailview.c \
- margin.c mimedesc.c mimetype.c msgno.c newmail.c news.c pattern.c pipe.c \
-! readfile.c remote.c reply.c rfc2231.c rules.c save.c search.c sequence.c send.c sort.c \
- state.c status.c store.c stream.c string.c strlst.c takeaddr.c tempfile.c text.c \
- thread.c adjtime.c url.c util.c helptext.c smkeys.c smime.c
-
-diff -rc alpine-2.00/pith/Makefile.in alpine-2.00.I.USE/pith/Makefile.in
-*** alpine-2.00/pith/Makefile.in 2008-06-03 08:54:15.000000000 -0700
---- alpine-2.00.I.USE/pith/Makefile.in 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 77,83 ****
- margin.$(OBJEXT) mimedesc.$(OBJEXT) mimetype.$(OBJEXT) \
- msgno.$(OBJEXT) newmail.$(OBJEXT) news.$(OBJEXT) \
- pattern.$(OBJEXT) pipe.$(OBJEXT) readfile.$(OBJEXT) \
-! remote.$(OBJEXT) reply.$(OBJEXT) rfc2231.$(OBJEXT) \
- save.$(OBJEXT) search.$(OBJEXT) sequence.$(OBJEXT) \
- send.$(OBJEXT) sort.$(OBJEXT) state.$(OBJEXT) status.$(OBJEXT) \
- store.$(OBJEXT) stream.$(OBJEXT) string.$(OBJEXT) \
---- 77,83 ----
- margin.$(OBJEXT) mimedesc.$(OBJEXT) mimetype.$(OBJEXT) \
- msgno.$(OBJEXT) newmail.$(OBJEXT) news.$(OBJEXT) \
- pattern.$(OBJEXT) pipe.$(OBJEXT) readfile.$(OBJEXT) \
-! remote.$(OBJEXT) reply.$(OBJEXT) rfc2231.$(OBJEXT) rules.$(OBJEXT) \
- save.$(OBJEXT) search.$(OBJEXT) sequence.$(OBJEXT) \
- send.$(OBJEXT) sort.$(OBJEXT) state.$(OBJEXT) status.$(OBJEXT) \
- store.$(OBJEXT) stream.$(OBJEXT) string.$(OBJEXT) \
-***************
-*** 275,281 ****
- filter.c flag.c folder.c handle.c help.c helpindx.c hist.c icache.c imap.c init.c \
- keyword.c ldap.c list.c mailcap.c mailcmd.c mailindx.c maillist.c mailview.c \
- margin.c mimedesc.c mimetype.c msgno.c newmail.c news.c pattern.c pipe.c \
-! readfile.c remote.c reply.c rfc2231.c save.c search.c sequence.c send.c sort.c \
- state.c status.c store.c stream.c string.c strlst.c takeaddr.c tempfile.c text.c \
- thread.c adjtime.c url.c util.c helptext.c smkeys.c smime.c
-
---- 275,281 ----
- filter.c flag.c folder.c handle.c help.c helpindx.c hist.c icache.c imap.c init.c \
- keyword.c ldap.c list.c mailcap.c mailcmd.c mailindx.c maillist.c mailview.c \
- margin.c mimedesc.c mimetype.c msgno.c newmail.c news.c pattern.c pipe.c \
-! readfile.c remote.c reply.c rfc2231.c rules.c save.c search.c sequence.c send.c sort.c \
- state.c status.c store.c stream.c string.c strlst.c takeaddr.c tempfile.c text.c \
- thread.c adjtime.c url.c util.c helptext.c smkeys.c smime.c
-
-***************
-*** 404,409 ****
---- 404,410 ----
- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread.Po@am__quote@
- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/url.Po@am__quote@
- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@
-+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rules.Po@am__quote@
-
- .c.o:
- @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-diff -rc alpine-2.00/pith/makefile.wnt alpine-2.00.I.USE/pith/makefile.wnt
-*** alpine-2.00/pith/makefile.wnt 2007-10-24 14:58:00.000000000 -0700
---- alpine-2.00.I.USE/pith/makefile.wnt 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 44,50 ****
- init.h keyword.h ldap.h list.h mailcap.h mailcmd.h mailindx.h maillist.h \
- mailpart.h mailview.h margin.h mimedesc.h mimetype.h msgno.h newmail.h news.h \
- options.h pattern.h pineelt.h pipe.h readfile.h remote.h remtype.h repltype.h reply.h \
-! rfc2231.h save.h savetype.h search.h send.h sequence.h signal.h sort.h sorttype.h \
- state.h status.h store.h stream.h string.h strlst.h takeaddr.h tempfile.h text.h \
- thread.h url.h user.h util.h
-
---- 44,50 ----
- init.h keyword.h ldap.h list.h mailcap.h mailcmd.h mailindx.h maillist.h \
- mailpart.h mailview.h margin.h mimedesc.h mimetype.h msgno.h newmail.h news.h \
- options.h pattern.h pineelt.h pipe.h readfile.h remote.h remtype.h repltype.h reply.h \
-! rfc2231.h rules.h save.h savetype.h search.h send.h sequence.h signal.h sort.h sorttype.h \
- state.h status.h store.h stream.h string.h strlst.h takeaddr.h tempfile.h text.h \
- thread.h url.h user.h util.h
-
-***************
-*** 53,59 ****
- filter.obj flag.obj folder.obj handle.obj help.obj helptext.obj hist.obj icache.obj imap.obj init.obj \
- keyword.obj ldap.obj list.obj mailcap.obj mailcmd.obj mailindx.obj maillist.obj mailview.obj \
- margin.obj mimedesc.obj mimetype.obj msgno.obj newmail.obj news.obj pattern.obj pipe.obj \
-! readfile.obj remote.obj reply.obj rfc2231.obj save.obj search.obj sequence.obj send.obj sort.obj state.obj \
- status.obj store.obj stream.obj string.obj strlst.obj takeaddr.obj tempfile.obj text.obj \
- thread.obj adjtime.obj url.obj util.obj
-
---- 53,59 ----
- filter.obj flag.obj folder.obj handle.obj help.obj helptext.obj hist.obj icache.obj imap.obj init.obj \
- keyword.obj ldap.obj list.obj mailcap.obj mailcmd.obj mailindx.obj maillist.obj mailview.obj \
- margin.obj mimedesc.obj mimetype.obj msgno.obj newmail.obj news.obj pattern.obj pipe.obj \
-! readfile.obj remote.obj reply.obj rfc2231.obj rules.obj save.obj search.obj sequence.obj send.obj sort.obj state.obj \
- status.obj store.obj stream.obj string.obj strlst.obj takeaddr.obj tempfile.obj text.obj \
- thread.obj adjtime.obj url.obj util.obj
-
-diff -rc alpine-2.00/pith/mimetype.c alpine-2.00.I.USE/pith/mimetype.c
-*** alpine-2.00/pith/mimetype.c 2008-03-06 12:54:01.000000000 -0800
---- alpine-2.00.I.USE/pith/mimetype.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 178,183 ****
---- 178,212 ----
- panic("Unhandled mime type search");
- }
-
-+ /* if we still can not find the type, but it is a .docx (or alike) extension
-+ set the type here. Do not use the grope function.
-+ */
-+ if(rv == 0){
-+ rv = 1; /* assume success */
-+ mt_map->to.mime.type = TYPEAPPLICATION;
-+ if(!strucmp(mt_map->from.ext, "docx"))
-+ mt_map->to.mime.subtype = cpystr("VND.OPENXMLFORMATS-OFFICEDOCUMENT.WORDPROCESSINGML.DOCUMENT");
-+ else if(!strucmp(mt_map->from.ext, "xslx"))
-+ mt_map->to.mime.subtype = cpystr("VND.OPENXMLFORMATS-OFFICEDOCUMENT.SPREADSHEETML.SHEET");
-+ else if(!strucmp(mt_map->from.ext, "xltx"))
-+ mt_map->to.mime.subtype = cpystr("VND.OPENXMLFORMATS-OFFICEDOCUMENT.SPREADSHEETML.TEMPLATE");
-+ else if(!strucmp(mt_map->from.ext, "potx"))
-+ mt_map->to.mime.subtype = cpystr("VND.OPENXMLFORMATS-OFFICEDOCUMENT.PRESENTATIONML.TEMPLATE");
-+ else if(!strucmp(mt_map->from.ext, "ppsx"))
-+ mt_map->to.mime.subtype = cpystr("VND.OPENXMLFORMATS-OFFICEDOCUMENT.PRESENTATIONML.SLIDESHOW");
-+ else if(!strucmp(mt_map->from.ext, "pptx"))
-+ mt_map->to.mime.subtype = cpystr("VND.OPENXMLFORMATS-OFFICEDOCUMENT.PRESENTATIONML.PRESENTATION");
-+ else if(!strucmp(mt_map->from.ext, "sldx"))
-+ mt_map->to.mime.subtype = cpystr("VND.OPENXMLFORMATS-OFFICEDOCUMENT.PRESENTATIONML.SLIDE");
-+ else if(!strucmp(mt_map->from.ext, "dotx"))
-+ mt_map->to.mime.subtype = cpystr("VND.OPENXMLFORMATS-OFFICEDOCUMENT.WORDPROCESSINGML.TEMPLATE");
-+ else if(!strucmp(mt_map->from.ext, "xlam"))
-+ mt_map->to.mime.subtype = cpystr("VND.MS-EXCEL.ADDIN.MACROENABLED.12");
-+ else if(!strucmp(mt_map->from.ext, "xslb"))
-+ mt_map->to.mime.subtype = cpystr("VND.MS-EXCEL.SHEET.BINARY.MACROENABLED.12");
-+ else rv = 0; /* else, failure */
-+ }
-+
-
- return(rv);
- }
-diff -rc alpine-2.00/pith/msgno.c alpine-2.00.I.USE/pith/msgno.c
-*** alpine-2.00/pith/msgno.c 2007-12-03 16:13:55.000000000 -0800
---- alpine-2.00.I.USE/pith/msgno.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 932,937 ****
---- 932,943 ----
- if((*peltp)->pthrd)
- fs_give((void **) &(*peltp)->pthrd);
-
-+ if((*peltp)->firsttext)
-+ fs_give((void **) &(*peltp)->firsttext);
-+
-+ if((*peltp)->firsttextraw)
-+ fs_give((void **) &(*peltp)->firsttextraw);
-+
- if((*peltp)->ice)
- free_ice(&(*peltp)->ice);
-
-diff -rc alpine-2.00/pith/newmail.c alpine-2.00.I.USE/pith/newmail.c
-*** alpine-2.00/pith/newmail.c 2008-07-14 11:01:54.000000000 -0700
---- alpine-2.00.I.USE/pith/newmail.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 684,692 ****
- if(!for_new_mail_win)
- q_status_message5(SM_ASYNC | SM_DING, 0, 60,
- "%s%s%s%.80s%.80s", intro,
-! from ? ((number > 1L) ? " Most recent f" : " F") : "",
-! from ? "rom " : "",
-! from ? from : "",
- subjtext);
- #if (!defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO)) || defined(_WINDOWS)
- else {
---- 684,692 ----
- if(!for_new_mail_win)
- q_status_message5(SM_ASYNC | SM_DING, 0, 60,
- "%s%s%s%.80s%.80s", intro,
-! from && from[0] ? ((number > 1L) ? " Most recent f" : " F") : "",
-! from && from[0] ? "rom " : "",
-! from && from[0] ? from : "",
- subjtext);
- #if (!defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO)) || defined(_WINDOWS)
- else {
-***************
-*** 724,732 ****
- }
- else
- snprintf(tmp_20k_buf, SIZEOF_20KBUF, "%s%s%s%.80s", intro,
-! from ? ((number > 1L) ? " Most recent f" : " F") : "",
-! from ? "rom " : "",
-! from ? from : "");
-
- (*pith_opt_icon_text)(tmp_20k_buf, IT_NEWMAIL);
- }
---- 724,732 ----
- }
- else
- snprintf(tmp_20k_buf, SIZEOF_20KBUF, "%s%s%s%.80s", intro,
-! from && from[0] ? ((number > 1L) ? " Most recent f" : " F") : "",
-! from && from[0] ? "rom " : "",
-! from && from[0] ? from : "");
-
- (*pith_opt_icon_text)(tmp_20k_buf, IT_NEWMAIL);
- }
-diff -rc alpine-2.00/pith/osdep/color.c alpine-2.00.I.USE/pith/osdep/color.c
-*** alpine-2.00/pith/osdep/color.c 2006-09-26 12:30:49.000000000 -0700
---- alpine-2.00.I.USE/pith/osdep/color.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 31,37 ****
-
- #include <system.h>
- #include "./color.h"
-!
-
-
- /*
---- 31,37 ----
-
- #include <system.h>
- #include "./color.h"
-! #include "./collate.h"
-
-
- /*
-***************
-*** 91,93 ****
---- 91,1278 ----
- {
- return(pico_set_colors(col ? col->fg : NULL, col ? col->bg : NULL, flags));
- }
-+
-+
-+ /*
-+ * Extended Justification support also does not belong here
-+ * but otherwise webpine will not build, so we move everything
-+ * here. Hopefully this will be the permanent place for these
-+ * routines. This routines used to be in pico/word.c
-+ */
-+ #define NSTRING 256
-+ #include "../../include/general.h"
-+
-+ /* Support of indentation of paragraphs */
-+ #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)
-+
-+
-+ /* 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 iscontrol(c) (iscntrl(((int) (c)) & 0x7f) ? 1 : 0)
-+ #define forbidden(c) (((c) == '\"') || ((c) == '\'') || ((c) == '$') ||\
-+ ((c) == ',') || ((c) == '.') || ((c) == '-') ||\
-+ ((c) == LPAREN) || ((c) == '/')|| ((c) == '`') ||\
-+ ((c) == '{') || ((c) == '\\') || (iscontrol((c))) ||\
-+ (((c) >= '0') && ((c) <= '9')) || ((c) == '?'))
-+ #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_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))
-+ #define qs_allowed(a) (((a)->qstype != qsGdb) && ((a)->qstype != qsProg))
-+
-+ /* Internal justification functions */
-+ QSTRING_S *is_quote(char *, char *, int);
-+ QSTRING_S *qs_normal_part(QSTRING_S *);
-+ QSTRING_S *qs_remove_trailing_spaces(QSTRING_S *);
-+ QSTRING_S *trim_qs_from_cl(QSTRING_S *, QSTRING_S *, QSTRING_S *);
-+ QSTRING_S *fix_qstring(QSTRING_S *, QSTRING_S *, QSTRING_S *);
-+ QSTRING_S *fix_qstring_allowed(QSTRING_S *, QSTRING_S *, QSTRING_S *);
-+ QSTRING_S *qs_add(char *, char *, QStrType, int, int, int, int);
-+ QSTRING_S *remove_qsword(QSTRING_S *);
-+ QSTRING_S *do_raw_quote_match(char *, char *, char *, char *, QSTRING_S **, QSTRING_S **);
-+ void free_qs(QSTRING_S **);
-+ int word_is_prog(char *);
-+ int qstring_is_normal(QSTRING_S *);
-+ int exists_good_part(QSTRING_S *);
-+ int strcmp_qs(char *, char *);
-+ int count_levels_qstring(QSTRING_S *);
-+ int same_qstring(QSTRING_S *, QSTRING_S *);
-+ int advance_quote_string(char *, char *, int);
-+ int isaword(char *,int ,int);
-+ int isamailbox(char *,int ,int);
-+
-+
-+ int
-+ word_is_prog(char *word)
-+ {
-+ static char *list1[] = {"#include",
-+ "#define",
-+ "#ifdef",
-+ "#ifndef",
-+ "#elif",
-+ "#if",
-+ NULL};
-+ static char *list2[] = {"#else",
-+ "#endif",
-+ NULL};
-+ int i, j = strlen(word), k, rv = 0;
-+
-+ for(i = 0; rv == 0 && list1[i] && (k = strlen(list1[i])) && k < j; i++)
-+ if(!strncmp(list1[i], word, k) && ISspace(word[k]))
-+ rv++;
-+
-+ if(rv)
-+ return rv;
-+
-+ for(i = 0; rv == 0 && list2[i] && (k = strlen(list2[i])) && k <= j; i++)
-+ if(!strncmp(list2[i], word, k) && (!word[k] || ISspace(word[k])))
-+ rv++;
-+
-+ return rv;
-+ }
-+
-+ /*
-+ * 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, endw, offset, neednext;
-+ {
-+ QSTRING_S *qstring, *nextqs;
-+ 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;
-+ }
-+
-+ nextqs = neednext ? is_quote(qs, word+beginw, 1) : NULL;
-+
-+ 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;
-+ }
-+
-+ /*
-+ * 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;
-+ }
-+
-+ /*
-+ * 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(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(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;
-+ }
-+
-+ int
-+ value_is_space(char *value)
-+ {
-+ for (; value && *value && ISspace(*value); value++);
-+
-+ return value && *value ? 0 : 1;
-+ }
-+
-+ void
-+ free_qs(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;
-+ }
-+
-+ /*
-+ * 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(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(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(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 && cl->qstype == pl->qstype
-+ && !strucmp(cl->value, pl->value)){
-+ cl = cl->next;
-+ pl = pl->next;
-+ }
-+ if (pl && cl && cl->qstype == pl->qstype
-+ && 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;
-+ }
-+
-+ QSTRING_S *
-+ fix_qstring_allowed(QSTRING_S *cl, QSTRING_S *nl, QSTRING_S *pl)
-+ {
-+ if(!cl)
-+ return (QSTRING_S *) NULL;
-+
-+ if (qs_allowed(cl))
-+ cl->next = fix_qstring_allowed(cl->next, (nl ? nl->next : NULL),
-+ (pl ? pl->next : NULL));
-+ else
-+ if((nl && cl->qstype == nl->qstype) || (pl && cl->qstype == pl->qstype)
-+ || (!nl && !pl))
-+ free_qs(&cl);
-+ return cl;
-+ }
-+
-+ /*
-+ * This function flattens the quote string returned to us by is_quote. A
-+ * crash in this function implies a bug elsewhere.
-+ */
-+ void
-+ flatten_qstring(QSTRING_S *qs, char *buff, int bufflen)
-+ {
-+ int i, j;
-+ if(!buff || bufflen <= 0)
-+ return;
-+
-+ for (i = 0; qs; qs = qs->next)
-+ for (j = 0; i < bufflen - 1
-+ && (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 (char *qs,char *word, int been_here)
-+ {
-+ int i = 0, j, nxt, prev, finished = 0, offset;
-+ unsigned char c;
-+ 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 = (unsigned char) now(word,i)){
-+ case NBSP:
-+ case TAB :
-+ case ' ' : { QSTRING_S *nextqs, *d;
-+
-+ for (; ISspace(word[i]); i++); /* FIX ME */
-+ 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 "^ ^").
-+ */
-+ i += nextqs && nextqs->qstype == qsNormal
-+ ? strlen(nextqs->value) : 0;
-+ 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;
-+ if(nextqs && nextqs->qstype == qsNormal){
-+ d = nextqs->next;
-+ nextqs->next = NULL;
-+ qstring->next = d;
-+ free_qs(&nextqs);
-+ }
-+ else
-+ qstring->next = nextqs;
-+
-+ 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 ':': /* colon */
-+ case '~': nxt = next(word,i);
-+ if ((is_tilde(c) && (nxt == '/'))
-+ || (is_colon(c) && !is_cquote(nxt)
-+ && !is_cword(nxt) && nxt != RPAREN))
-+ finished++;
-+ else if (is_cquote(c)
-+ || is_cquote(nxt)
-+ || (c != '~' && nxt == RPAREN)
-+ || (i != 0 && ISspace(nxt))
-+ || is_cquote(prev = before(word,i))
-+ || (ISspace(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 */
-+ (ISspace(nxt) && is_rarrow(next(word,i+1))))
-+ i++;
-+ else
-+ finished++;
-+ break;
-+
-+ case '^' :
-+ case '!' :
-+ case '%' : if (next(word,i) != c)
-+ return qs_add(qs, word, qsChar, i, i+1, 0, 1);
-+ else
-+ finished++;
-+ break;
-+
-+ case '_' : if(ISspace(next(word, i)))
-+ return qs_add(qs, word, qsChar, i, i+1, 0, 1);
-+ else
-+ finished++;
-+ break;
-+
-+ case '#' : { QStrType qstype = qsChar;
-+ if((nxt = next(word, i)) != c){
-+ if(isdigit((int) nxt))
-+ qstype = qsGdb;
-+ else
-+ if(word_is_prog(word))
-+ qstype = qsProg;
-+ return qs_add(qs, word, qstype, 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))
-+ && !(ISspace(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
-+ : ((ISspace(c)
-+ && is_cquote(next(word,j+1))) ? 3 : -1);
-+
-+ qstype = (is_cquote(c) || (c == RPAREN))
-+ ? (is_qsword(c) ? qsWord : qsString)
-+ : ((ISspace(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(i > 0)
-+ return qs_add(qs, word, qsNormal, 0, i, 0, 1);
-+ 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;
-+ }
-+
-+ 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, 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 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)
-+ && qs_allowed(cl) && !value_is_space(cl->value))
-+ ? 1 : exists_good_part(cl->next))
-+ : 0);
-+ }
-+
-+ int
-+ line_isblank(char *q, char *GLine, char *NLine, char *PLine, int buflen)
-+ {
-+ int n = 0;
-+ QSTRING_S *cl;
-+ char qstr[NSTRING];
-+
-+ cl = do_raw_quote_match(q, GLine, NLine, PLine, NULL, NULL);
-+
-+ flatten_qstring(cl, qstr, NSTRING);
-+
-+ free_qs(&cl);
-+
-+ for(n = strlen(qstr); n < buflen && GLine[n]; n++)
-+ if(!ISspace((unsigned char) GLine[n]))
-+ return(FALSE);
-+
-+ return(TRUE);
-+ }
-+
-+ QSTRING_S *
-+ do_raw_quote_match(char *q, char *GLine, char *NLine, char *PLine, QSTRING_S **nlp, QSTRING_S **plp)
-+ {
-+ QSTRING_S *cl, *nl = NULL, *pl = NULL;
-+ char nbuf[NSTRING], pbuf[NSTRING], buf[NSTRING];
-+ int emptypl = 0, emptynl = 0;
-+
-+ if (!(cl = is_quote(q, GLine, 0))) /* if nothing in, nothing out */
-+ return cl;
-+
-+ nl = is_quote(q, NLine, 0); /* Next Line */
-+ if (nlp) *nlp = nl;
-+ pl = is_quote(q, PLine, 0); /* Previous Line */
-+ if (plp) *plp = pl;
-+ /*
-+ * 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, NSTRING);
-+ emptypl = (!PLine || !PLine[0] ||
-+ (pl && value_is_space(pbuf)) && !PLine[strlen(pbuf)]) ? 1 : 0;
-+ if (emptypl){
-+ flatten_qstring(nl, nbuf, NSTRING);
-+ emptynl = (!NLine || !NLine[0] ||
-+ (nl && value_is_space(nbuf) && !NLine[strlen(nbuf)])) ? 1 : 0;
-+ if (emptynl){
-+ cl = remove_qsword(cl);
-+ if((cl = fix_qstring_allowed(cl, NULL, NULL)) != NULL)
-+ cl = qs_remove_trailing_spaces(cl);
-+ free_qs(&nl);
-+ free_qs(&pl);
-+ if(nlp) *nlp = NULL;
-+ if(plp) *plp = NULL;
-+
-+ 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);
-+ if((cl = fix_qstring_allowed(cl, nl, pl)) != NULL){
-+ nl = trim_qs_from_cl(cl, nl, NULL);
-+ pl = trim_qs_from_cl(cl, NULL, pl);
-+ }
-+ else{
-+ free_qs(&nl);
-+ free_qs(&pl);
-+ }
-+ if(nlp)
-+ *nlp = nl;
-+ else
-+ free_qs(&nl);
-+ if(plp)
-+ *plp = pl;
-+ else
-+ free_qs(&pl);
-+ return cl;
-+ }
-+
-+ QSTRING_S *
-+ do_quote_match(q, GLine, NLine, PLine, rqstr, rqstrlen, plb)
-+ char *q, *GLine, *NLine, *PLine, *rqstr;
-+ int rqstrlen, plb;
-+ {
-+ QSTRING_S *cl, *nl = NULL, *pl = NULL;
-+ int c, n, p,i, j, NewP, NewC, NewN, clength, same = 0;
-+ char nbuf[NSTRING], pbuf[NSTRING], buf[NSTRING];
-+
-+ if(rqstr)
-+ *rqstr = '\0';
-+
-+ /* if nothing in, nothing out */
-+ cl = do_raw_quote_match(q, GLine, NLine, PLine, &nl, &pl);
-+ if(cl == NULL){
-+ free_qs(&nl);
-+ free_qs(&pl);
-+ return cl;
-+ }
-+
-+ flatten_qstring(cl, rqstr, rqstrlen);
-+ flatten_qstring(cl, buf, NSTRING);
-+ flatten_qstring(nl, nbuf, NSTRING);
-+ flatten_qstring(pl, pbuf, NSTRING);
-+
-+ /*
-+ * 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)
-+ */
-+ NewP = strlenis(pbuf);
-+ 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){
-+ int agree = 0;
-+ for (j = 0; (j < n) && (GLine[j] == NLine[j]); j++);
-+ clength = j;
-+ /* clength is the common length in which Gline and Nline agree */
-+ /* j < n means that they do not agree fully */
-+ /* GLine = " \tText"
-+ NLine = " Text" */
-+ if(j == n)
-+ agree++;
-+ if (clength < n){ /* see if buf and nbuf are padded with spaces and tabs */
-+ for (i = clength; i < n && ISspace(NLine[i]); i++);
-+ if (i == n){/* padded NLine until the end of spaces? */
-+ for (i = clength; i < c && ISspace(GLine[i]); i++);
-+ if (i == c) /* Padded CLine until the end of spaces? */
-+ agree++;
-+ }
-+ }
-+ if (agree){
-+ for (j = clength; j < c && ISspace(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.
-+ * Example when it should not free_qs(cl)
-+ * " Text in Paragraph 1" (PLine)
-+ * " Text in Paragraph 1" (GLine)
-+ * " Other Paragraph Number 2" (NLine)
-+ *
-+ * Example when it should free_qs(cl):
-+ * ":) " (PLine) p = 3, j = 3
-+ * ":) Text" (GLine) c = 5
-+ * ":) More text" (NLine) n = 3
-+ *
-+ * Example when it should free_qs(cl):
-+ * ":) " (PLine) p = 3, j = 3
-+ * ":) > > > Text" (GLine) c = 11
-+ * ":) > > > More text" (NLine) n = 9
-+ *
-+ * Example when it should free_qs(cl):
-+ * ":) :) " (PLine) p = 6, j = 3
-+ * ":) > > > Text" (GLine) c = 11
-+ * ":) > > > More text" (NLine) n = 9
-+ *
-+ * Example when it should free_qs(cl):
-+ * ":) > > > " (PLine) p = 13, j = 11
-+ * ":) > > > Text" (GLine) c = 11
-+ * ":) > > > More text" (NLine) n = 9
-+ *
-+ * The following example is very interesting. The "Other Text"
-+ * line below should free the quote string an make it equal to the
-+ * quote string of the line below it, but any algorithm trying
-+ * to advance past that line should make it stop there, so
-+ * we need one more check, to check the raw quote string and the
-+ * processed quote string at the same time.
-+ * FREE qs in this example.
-+ * " Some Text" (PLine) p = 3, j = 0
-+ * "\tOther Text" (GLine) c = 1
-+ * " More Text" (NLine) n = 3
-+ *
-+ */
-+ for (j = 0; (j < p) && (GLine[j] == PLine[j]); j++);
-+ if ((p != c || j != p) && NLine[n])
-+ if(!get_indent_raw_line(q, PLine, nbuf, NSTRING, p, plb)
-+ || NewP + strlenis(nbuf) != NewC){
-+ free_qs(&cl);
-+ free_qs(&pl);
-+ return 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; ISspace(l[i + k]); k++);
-+ k -= k % es;
-+ return k;
-+ }
-+ for (is = 0; ISspace(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; ISspace(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; ISspace(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(char *qstr)
-+ {
-+ int i, rv = 0;
-+ for (i = 0; qstr && qstr[i]; i++)
-+ rv += ((qstr[i] == TAB) ? (~rv & 0x07) + 1 : 1);
-+ return rv;
-+ }
-+
-+ int
-+ is_indent (word, plb)
-+ char word[NSTRING];
-+ int plb;
-+ {
-+ int i = 0, finished = 0, c, nxt, j, k, digit = 0, bdigits = -1, alpha = 0;
-+
-+ if (!word || !word[0])
-+ return i;
-+
-+ for (i = 0, j = 0; ISspace(word[i]); i++, j++);
-+ while ((i < NSTRING - 2) && !finished){
-+ switch (c = now(word,i)){
-+ case NBSP:
-+ case TAB :
-+ case ' ' : for (; ISspace(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) && alpha)
-+ || (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)){
-+ alpha++;
-+ 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;
-+ }
-+
-+ int
-+ get_indent_raw_line(char *q, char *GLine, char *buf, int buflen, int k, int plb)
-+ {
-+ int i, j;
-+ char testline[1024];
-+
-+ if(k > 0){
-+ for(j = 0; GLine[j] != '\0'; j++){
-+ testline[j] = GLine[j];
-+ testline[j+1] = '\0';
-+ if(strlenis(testline) >= strlenis(buf))
-+ break;
-+ }
-+ k = ++j; /* reset k */
-+ }
-+ i = is_indent(GLine+k, plb);
-+
-+ for (j = 0; j < i && j < buflen && (buf[j] = GLine[j + k]); j++);
-+ buf[j] = '\0';
-+
-+ return i;
-+ }
-+
-diff -rc alpine-2.00/pith/osdep/color.h alpine-2.00.I.USE/pith/osdep/color.h
-*** alpine-2.00/pith/osdep/color.h 2008-03-24 12:35:31.000000000 -0700
---- alpine-2.00.I.USE/pith/osdep/color.h 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 43,48 ****
---- 43,69 ----
- #define PSC_REV 0x2
- #define PSC_RET 0x4 /* return an allocated copy of previous color */
-
-+ /*
-+ * 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,
-+ qsGdb, qsProg, qsText} QStrType;
-+
-+ typedef struct QSTRING {
-+ char *value; /* possible quote string */
-+ QStrType qstype; /* type of quote string */
-+ struct QSTRING *next; /* possible continuation */
-+ } QSTRING_S;
-+
-+ #define UCH(c) ((unsigned char) (c))
-+ #define NBSP UCH('\240')
-+ #define ISspace(c) (UCH(c) == ' ' || UCH(c) == TAB || UCH(c) == NBSP)
-+
-+
-
- /*
- * MATCH_NORM_COLOR means that the color that is set to this value
-***************
-*** 92,97 ****
---- 113,123 ----
- char *pico_get_last_bg_color(void);
- char *color_to_canonical_name(char *);
- int pico_count_in_color_table(void);
-+ int is_indent(char *, int);
-+ int get_indent_raw_line (char *, char *, char *, int, int, int);
-+ int line_isblank(char *, char *, char *, char *, int);
-+ int strlenis(char *);
-+ int value_is_space(char *);
-
-
- #endif /* PITH_OSDEP_COLOR_INCLUDED */
-diff -rc alpine-2.00/pith/osdep/domnames.c alpine-2.00.I.USE/pith/osdep/domnames.c
-*** alpine-2.00/pith/osdep/domnames.c 2006-11-17 18:46:41.000000000 -0800
---- alpine-2.00.I.USE/pith/osdep/domnames.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 51,57 ****
- char **alias;
- char *maybe = NULL;
-
-! gethostname(hname, MAX_ADDRESS);
- he = gethostbyname(hname);
- hostname[0] = '\0';
-
---- 51,70 ----
- char **alias;
- char *maybe = NULL;
-
-! if (gethostname(hname, MAX_ADDRESS)) hname[0] = 0xff;
-! /* sanity check of hostname string */
-! for (dn = hname; (*dn > 0x20) && (*dn < 0x7f); ++dn);
-! if (*dn) { /* only if invalid string returned */
-! #if 0
-! hostname[0] = domainname[0] = '\0';
-! #else
-! /* Contrary to the comments above, the UNIX code does not expect
-! these strings to be blank.
-! */
-! strcpy (hostname, (strcpy (domainname,"unknown")));
-! #endif
-! return;
-! }
- he = gethostbyname(hname);
- hostname[0] = '\0';
-
-diff -rc alpine-2.00/pith/osdep/hostname.c alpine-2.00.I.USE/pith/osdep/hostname.c
-*** alpine-2.00/pith/osdep/hostname.c 2006-12-11 10:06:32.000000000 -0800
---- alpine-2.00.I.USE/pith/osdep/hostname.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 47,53 ****
- {
- #if HAVE_GETHOSTNAME
-
-! return(gethostname(hostname, size));
-
- #elif HAVE_UNAME
-
---- 47,57 ----
- {
- #if HAVE_GETHOSTNAME
-
-! if(gethostname(hostname, size)) return -1;
-! /* sanity check of hostname string */
-! for (*dn = hname; (*dn > 0x20) && (*dn < 0x7f); ++dn);
-! if (*dn) strcpy (hostname,"unknown");
-! return 0;
-
- #elif HAVE_UNAME
-
-diff -rc alpine-2.00/pith/pattern.c alpine-2.00.I.USE/pith/pattern.c
-*** alpine-2.00/pith/pattern.c 2008-07-14 11:01:54.000000000 -0700
---- alpine-2.00.I.USE/pith/pattern.c 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 1755,1761 ****
- 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);
---- 1755,1761 ----
- 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);
-***************
-*** 5482,5487 ****
---- 5482,5496 ----
- break;
-
- case '#':
-+ #ifndef _WINDOWS
-+ if(!struncmp(patfolder, "#md/", 4)
-+ || !struncmp(patfolder, "#mc/", 4)){
-+ maildir_file_path(patfolder, tmp1);
-+ if(!strcmp(patfolder, stream->mailbox))
-+ match++;
-+ break;
-+ }
-+ #endif
- if(!strcmp(patfolder, stream->mailbox))
- match++;
-
-***************
-*** 7894,7900 ****
- int we_cancel = 0, width;
- CONTEXT_S *save_context = NULL;
- char buf[MAX_SCREEN_COLS+1], sbuf[MAX_SCREEN_COLS+1];
-! char *save_ref = NULL;
- #define FILTMSG_MAX 30
-
- if(!stream)
---- 7903,7909 ----
- int we_cancel = 0, width;
- CONTEXT_S *save_context = NULL;
- char buf[MAX_SCREEN_COLS+1], sbuf[MAX_SCREEN_COLS+1];
-! char *save_ref = NULL, *save_dstfldr = NULL, *save_dstfldr2 = NULL;
- #define FILTMSG_MAX 30
-
- if(!stream)
-***************
-*** 7928,7933 ****
---- 7937,7952 ----
- if(F_OFF(F_QUELL_FILTER_MSGS, ps_global))
- we_cancel = busy_cue(buf, NULL, 0);
-
-+ #ifndef _WINDOWS
-+ if(!struncmp(dstfldr, "#md/", 4) || !struncmp(dstfldr, "#mc/", 4)){
-+ char tmp1[MAILTMPLEN];
-+ maildir_file_path(dstfldr, tmp1);
-+ save_dstfldr2 = dstfldr;
-+ save_dstfldr = cpystr(tmp1);
-+ dstfldr = save_dstfldr;
-+ }
-+ #endif
-+
- if(!is_absolute_path(dstfldr)
- && !(save_context = default_save_context(ps_global->context_list)))
- save_context = ps_global->context_list;
-***************
-*** 7991,7996 ****
---- 8010,8020 ----
- if(we_cancel)
- cancel_busy_cue(buf[0] ? 0 : -1);
-
-+ if(save_dstfldr){
-+ fs_give((void **)&save_dstfldr);
-+ dstfldr = save_dstfldr2;
-+ }
-+
- return(buf[0] != '\0');
- }
-
-diff -rc alpine-2.00/pith/pineelt.h alpine-2.00.I.USE/pith/pineelt.h
-*** alpine-2.00/pith/pineelt.h 2008-07-09 22:01:13.000000000 -0700
---- alpine-2.00.I.USE/pith/pineelt.h 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 40,45 ****
---- 40,47 ----
- PINETHRD_S *pthrd;
- PARTEX_S *exceptions;
- ICE_S *ice;
-+ char *firsttext;
-+ char *firsttextraw;
- /* per-message pine state bits */
- unsigned int hidden:1;
- unsigned int excluded:1;
-diff -rc alpine-2.00/pith/pine.hlp alpine-2.00.I.USE/pith/pine.hlp
-*** alpine-2.00/pith/pine.hlp 2008-08-22 17:07:05.000000000 -0700
---- alpine-2.00.I.USE/pith/pine.hlp 2011-02-07 20:33:48.000000000 -0800
-***************
-*** 88,93 ****
---- 88,94 ----
- ALPINE_VERSION
- ALPINE_REVISION
- ALPINE_COMPILE_DATE
-+ ALPINE_PATCHLEVEL
- ALPINE_TODAYS_DATE
- C_CLIENT_VERSION
- _LOCAL_FULLNAME_
-***************
-*** 158,163 ****
---- 159,172 ----
- </DIV>
-
- <P>
-+ This version was modified from its original source code. More information
-+ about some of the patches applied to this version can be found <A HREF="h_patches">here</A>.
-+ <!--chtml if pinemode="running"-->
-+ The patch level of this version, including creation date of the patch is:
-+ <!--#echo var=ALPINE_PATCHLEVEL-->.
-+ <!--chtml endif-->
-+
-+ <P>
- Alpine is an &quot;Alternatively Licensed Program for Internet
- News and Email&quot; produced by the University of Washington.
- It is intended to be an easy-to-use program for
-***************
-*** 919,924 ****
---- 928,1016 ----
- &lt;End of Configuration Notes&gt;
- </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 Alpine has been modified by including patches from
-+ <A HREF="http://staff.washington.edu/chappa/alpine/">
-+ http://staff.washington.edu/chappa/alpine/</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 Alpine, please contact
-+ Eduardo Chappa <A HREF="mailto:chappa@washington.edu">&lt;chappa@washington.edu&gt;</A>.
-+
-+ <P>The list of patches included in this release are:
-+ <P>New Features:
-+
-+ <UL>
-+ <LI> Enhanced Fancy thread interface. <A HREF="http://staff.washington.edu/chappa/alpine/info/fancy.html">(more)</A>
-+ <!--chtml if pinemode="os_windows"-->
-+
-+ <!--chtml else-->
-+ <LI> Patch that gives support for the maildir driver in Alpine <A HREF="h_config_maildir">(more)</A>
-+ <!--chtml endif-->
-+ <LI> Rules patch, to make Alpine flexible. <A HREF="h_config_new_rules">(more)</A>
-+ <LI> Send mail from the command Line. <A HREF="http://staff.washington.edu/chappa/alpine/info/outgoing.html">(more)</A>
-+ <LI> Add a few more options when replying to a message <A HREF="h_config_alt_reply_menu">(more)</A>
-+ <LI> Choose a role when composing a message from a mailto: link <A HREF="http://staff.washington.edu/chappa/alpine/info/composeurl.html">(more)</A>
-+ <LI> Alpine justifies paragraphs with more than one level of indentation. <A HREF="h_compose_justify">(more)</A>
-+ <LI> Patch to write accents and foreign characters <A HREF="http://staff.washington.edu/chappa/alpine/info/WrtAcc.html">(more)</A>
-+ <LI> Change your From Header without any effort! <A HREF="http://staff.washington.edu/chappa/alpine/info/fromheader.html">(more)</A>
-+ <LI> Tab checks folders on cycles <A HREF="h_config_circular_tab">(more)</A>
-+ <LI> Patch for Pico to update its status line according to cursor movements <A HREF="http://staff.washington.edu/chappa/alpine/info/status.html">(more)</A>
-+ <LI> Reuse your old search pattern to create a new one <A HREF="http://staff.washington.edu/chappa/alpine/info/insertpat.html">(more)</A>
-+ <LI> Paint special text in the body of a message in any color. <A HREF="h_config_special_text_to_color">(more)</A>
-+ <LI> Select messages by the content of an arbitrary header. <A HREF="http://staff.washington.edu/chappa/alpine/info/searchheader.html">(more)</A>
-+ <LI> Remove incorrect passwords from memory <A HREF="http://staff.washington.edu/chappa/alpine/info/delpassword.html">(more)</A>
-+ <LI> Get the quota report in an IMAP server <A HREF="http://staff.washington.edu/chappa/alpine/info/quota.html">(more)</A>
-+ <LI> Remove text until the end of the file or a message <A HREF="http://staff.washington.edu/chappa/alpine/info/DelText.html">(more)</A>
-+ <LI> Get the internal name of a help topic to use it with a x-alpine-help or x-pine-help URL scheme. <A HREF="http://staff.washington.edu/chappa/alpine/info/help.html">(more)</A>
-+ <LI> Get the number of characters in a composed message <A HREF="http://staff.washington.edu/chappa/alpine/info/count.html">(more)</A>
-+ <LI> Configure ignoring change in size of a message <A HREF="h_config_ignore_size">(more)</A>
-+ <LI> Add one more token to a sending filter <A HREF="http://staff.washington.edu/chappa/alpine/info/addressfilter.html">(more)</A>
-+ <LI> Make Alpine preserve To: and Cc: fields <A HREF="h_config_preserve_field">(more)</A>
-+ <LI> Allow non utf-8 piped input in Alpine <A HREF="http://staff.washington.edu/chappa/alpine/info/noutf8.html">(more)</A>
-+ <LI> Allow errors in base64 encoding <A HREF="http://staff.washington.edu/chappa/alpine/info/base64errors.html">(more)</A>
-+ <LI> Get the name of the slow server <A HREF="http://staff.washington.edu/chappa/alpine/info/streaminfo.html">(more)</A>
-+ <LI> Color the text in the folder list screen <A HREF="http://staff.washington.edu/chappa/alpine/info/colorfolder.html">(more)</A>
-+ <LI> Color text in the index screen <A HREF="http://staff.washington.edu/chappa/alpine/info/tokencolor.html">(more)</A>
-+ <LI> Avoid clearing the screen when executing a display filter <A HREF="http://staff.washington.edu/chappa/alpine/info/silenttoken.html">(more)</A>
-+ <LI> Cache OPENINGTEXT information <A HREF="http://staff.washington.edu/chappa/alpine/info/cachefirsttext.html">(more)</A>
-+ <LI> Recognize multiline URLs <A HREF="http://staff.washington.edu/chappa/alpine/info/longurl.html">(more)</A>
-+ <LI> Recognize the nametemplate token in a mailcap file <A HREF="http://staff.washington.edu/chappa/alpine/info/nametemplate.html">(more)</A>
-+ <LI> Create new threads even when replying to a message <A HREF="http://staff.washington.edu/chappa/alpine/info/newthread.html">(more)</A>
-+ </UL>
-+
-+ <P>Bug Fixes:
-+
-+ <UL>
-+ <LI> Fix a bug that makes Alpine not to give a warning if the Newsgroup header is present <A HREF="http://staff.washington.edu/chappa/alpine/info/unverified.html">(more)</A>
-+ <LI> Fix a bug in Pico which makes it not update the screen <A HREF="http://staff.washington.edu/chappa/alpine/info/replacebug.html">(more)</A>
-+ <LI> Fix a bug in Pico and Pilot that makes them crash for bad locale information <A HREF="http://staff.washington.edu/chappa/alpine/info/nlinfobug.html">(more)</A>
-+ <LI> Fix a bug in Alpine that makes it not to set a flag in a filtered message <A HREF="http://staff.washington.edu/chappa/alpine/info/filterflagbug.html">(more)</A>
-+ <LI> Fix a bug that makes Alpine crash when suspending it <A HREF="http://staff.washington.edu/chappa/alpine/info/streamlock.html">(more)</A>
-+ <LI> Fix a bug that makes Alpine crash when opening a unix type folder <A HREF="http://staff.washington.edu/chappa/alpine/info/unixnullbug.html">(more)</A>
-+ <LI> Force update of the index screen after adding an address to the addressbook <A HREF="http://staff.washington.edu/chappa/alpine/info/updateindexcolors.html">(more)</A>
-+ <LI> Fix a bug that makes Alpine ignore the week day of a preftime token <A HREF="http://staff.washington.edu/chappa/alpine/info/preftimebug.html">(more)</A>
-+ <LI> Fix the type of a .docx document <A HREF="http://staff.washington.edu/chappa/alpine/info/docxmimetype.html">(more)</A>
-+ <LI> Parse environment variables correctly <A HREF="http://staff.washington.edu/chappa/alpine/info/envvar.html">(more)</A>
-+ <LI> Do not reopen a folder that is meant to be closed <A HREF="http://staff.washington.edu/chappa/alpine/info/closebug.html">(more)</A>
-+ <LI> Fix a bug that makes Alpine crash when the screen is resized <A HREF="http://staff.washington.edu/chappa/alpine/info/resizeldap.html">(more)</A>
-+ <LI> Fix a bug in the threading algorithm <A HREF="http://staff.washington.edu/chappa/alpine/info/threadbug.html">(more)</A>
-+ <LI> Fix a memory leak in Alpine <A HREF="http://staff.washington.edu/chappa/alpine/info/composerleak.html">(more)</A>
-+ <LI> Fix a bug that sends Alpine in an infinite loop <A HREF="http://staff.washington.edu/chappa/alpine/info/scrolltool.html">(more)</A>
-+ <LI> Fix a bug that makes Alpine not give a correct new mail message <A HREF="http://staff.washington.edu/chappa/alpine/info/newmailmsg.html">(more)</A>
-+ <LI> Fix a bug that makes Alpine not show a login prompt <A HREF="http://staff.washington.edu/chappa/alpine/info/loginbug.html">(more)</A>
-+ <LI> Patch by Mark Crispin, which fixes a bug which makes Alpine not generate correct headers for servers that return UTF-8 names. <A HREF="http://staff.washington.edu/chappa/alpine/patches/others.html#markhostbug-2.00">(more)</A>
-+ </UL>
-+ </body>
-+ </html>
- ====== h_news_legal ======
- <html>
- <head>
-***************
-*** 3035,3043 ****
---- 3127,3137 ----
- <li><a href="h_config_alt_role_menu">FEATURE: <!--#echo var="FEAT_alternate-role-menu"--></a>
- <li><a href="h_config_force_low_speed">FEATURE: <!--#echo var="FEAT_assume-slow-link"--></a>
- <li><a href="h_config_auto_read_msgs">FEATURE: <!--#echo var="FEAT_auto-move-read-msgs"--></a>
-+ <li><a href="h_config_auto_read_msgs_rules">FEATURE: <!--#echo var="FEAT_auto-move-read-msgs-using-rules"--></a>
- <li><a href="h_config_auto_open_unread">FEATURE: <!--#echo var="FEAT_auto-open-next-unread"--></a>
- <li><a href="h_config_auto_unselect">FEATURE: <!--#echo var="FEAT_auto-unselect-after-apply"--></a>
- <li><a href="h_config_auto_unzoom">FEATURE: <!--#echo var="FEAT_auto-unzoom-after-apply"--></a>
-+ <li><a href="h_config_circular_tab">FEATURE: <!--#echo var="FEAT_enable-circular-tab"--></a>
- <li><a href="h_config_auto_zoom">FEATURE: <!--#echo var="FEAT_auto-zoom-after-select"--></a>
- <li><a href="h_config_use_boring_spinner">FEATURE: <!--#echo var="FEAT_busy-cue-spinner-only"--></a>
- <li><a href="h_config_check_mail_onquit">FEATURE: <!--#echo var="FEAT_check-newmail-when-quitting"--></a>
-***************
-*** 3120,3125 ****
---- 3214,3220 ----
- <li><a href="h_config_prefix_editing">FEATURE: <!--#echo var="FEAT_enable-reply-indent-string-editing"--></a>
- <li><a href="h_config_enable_search_and_repl">FEATURE: <!--#echo var="FEAT_enable-search-and-replace"--></a>
- <li><a href="h_config_sigdashes">FEATURE: <!--#echo var="FEAT_enable-sigdashes"--></a>
-+ <li><a href="h_config_new_thread_blank_subject">FEATURE: <!--#echo var="FEAT_new-thread-on-blank-subject"--></a>
- <li><a href="h_config_can_suspend">FEATURE: <!--#echo var="FEAT_enable-suspend"--></a>
- <li><a href="h_config_enable_tab_complete">FEATURE: <!--#echo var="FEAT_enable-tab-completion"--></a>
- <li><a href="h_config_enable_take_export">FEATURE: <!--#echo var="FEAT_enable-take-export"--></a>
-***************
-*** 3136,3142 ****
---- 3231,3239 ----
- <li><a href="h_config_full_auto_expunge">FEATURE: <!--#echo var="FEAT_expunge-without-confirm-everywhere"--></a>
- <li><a href="h_config_no_fcc_attach">FEATURE: <!--#echo var="FEAT_fcc-without-attachments"--></a>
- <li><a href="h_config_force_arrow">FEATURE: <!--#echo var="FEAT_force-arrow-cursor"--></a>
-+ <li><a href="h_config_ignore_size">FEATURE: <!--#echo var="FEAT_ignore-size-changes"--></a>
- <li><a href="h_config_forward_as_attachment">FEATURE: <!--#echo var="FEAT_forward-as-attachment"--></a>
-+ <li><a href="h_config_preserve_field">FEATURE: <!--#echo var="FEAT_preserve-original-fields"--></a>
- <li><a href="h_config_quell_empty_dirs">FEATURE: <!--#echo var="FEAT_quell-empty-directories"--></a>
- <li><a href="h_config_hide_nntp_path">FEATURE: <!--#echo var="FEAT_hide-nntp-path"--></a>
- <li><a href="h_config_attach_in_reply">FEATURE: <!--#echo var="FEAT_include-attachments-in-reply"--></a>
-***************
-*** 3402,3407 ****
---- 3499,3505 ----
- <li><a href="h_config_print_cat">OPTION: <!--#echo var="VAR_personal-print-category"--></a>
- <li><a href="h_config_print_command">OPTION: <!--#echo var="VAR_personal-print-command"--></a>
- <li><a href="h_config_post_char_set">OPTION: <!--#echo var="VAR_posting-character-set"--></a>
-+ <li><a href="h_config_special_text_to_color">OPTION: <!--#echo var="VAR_h_config_special_text_to_color"--></a>
- <li><a href="h_config_postponed_folder">OPTION: <!--#echo var="VAR_postponed-folder"--></a>
- <li><a href="h_config_print_font_char_set">OPTION: Print-Font-Char-Set</a>
- <li><a href="h_config_print_font_name">OPTION: Print-Font-Name</a>
-***************
-*** 3430,3438 ****
---- 3528,3538 ----
- <li><a href="h_config_sending_filter">OPTION: <!--#echo var="VAR_sending-filters"--></a>
- <li><a href="h_config_sendmail_path">OPTION: <!--#echo var="VAR_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: <!--#echo var="VAR_signature-file"--></a>
- <li><a href="h_config_smtp_server">OPTION: <!--#echo var="VAR_smtp-server"--></a>
- <li><a href="h_config_sort_key">OPTION: <!--#echo var="VAR_sort-key"--></a>
-+ <li><a href="h_config_thread_sort_key">OPTION: <!--#echo var="VAR_thread-sort-key"--></a>
- <li><a href="h_config_speller">OPTION: <!--#echo var="VAR_speller"--></a>
- <li><a href="h_config_sshcmd">OPTION: <!--#echo var="VAR_ssh-command"--></a>
- <li><a href="h_config_ssh_open_timeo">OPTION: <!--#echo var="VAR_ssh-open-timeout"--></a>
-***************
-*** 4058,4063 ****
---- 4158,4172 ----
- key will Exit the Help system altogether.
-
- <P>
-+ The "N" command will tell you the internal name of the help text you are
-+ reading each time, so that you can send this name in the text of a message
-+ and create a direct link to that internal help using the x-pine-help URL
-+ scheme. For example, the direct link to this item is
-+ x-pine-help:h_special_help_nav. If you add this text to a message, then
-+ a person using Pine to read such message would have a direct link to this
-+ help text.
-+
-+ <P>
- When you are finished reading this help text, you can press the
- <!--chtml if pinemode="function_key"-->
- F3 function
-***************
-*** 5316,5321 ****
---- 5425,5583 ----
- &lt;End of help on this topic&gt;
- </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>
-+ &lt;End of help on this topic&gt;
-+ </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&nbsp;INDEX screen sorts
-+ threads by the date in which messages were sent. The thread containing the
-+ last message in this order is displayed last.
-+ <P>
-+ &lt;End of help on this topic&gt;
-+ </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>
-+ &lt;End of help on this topic&gt;
-+ </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&nbsp;INDEX screen is
-+ the same as sorting by <A HREF="h_thread_index_sort_subj">Subject</A>.
-+
-+ <P>
-+ &lt;End of help on this topic&gt;
-+ </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&nbsp;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>
-+ &lt;End of help on this topic&gt;
-+ </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>
-+ &lt;End of help on this topic&gt;
-+ </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>
-+ &lt;End of help on this topic&gt;
-+ </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 means that threads are sorted according to
-+ the maximum score of a message in that thread. A thread all of whose
-+ messages contain a smaller score than a message in some other thread is
-+ placed in an earlier place in the list of messages for that folder; that
-+ is, threads with the highest scores appear at the bottom of the index
-+ list.
-+
-+ <P>
-+ &lt;End of help on this topic&gt;
-+ </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>
-+ &lt;End of help on this topic&gt;
-+ </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>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ======= h_index_cmd_whereis =======
- <HTML>
- <HEAD>
-***************
-*** 6503,6508 ****
---- 6765,6810 ----
- &quot;type the character ^&quot;.
-
- <P>
-+ This version of Alpine 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, Alpine 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 &quot;&gt;&quot;.
-+
-+ <P>
-+ Some other constructions of quote strings are recognized only if they
-+ appear enough in the text. For example &quot;Peter :&quot; is only
-+ recognized if it appears in two consecutive lines.
-+
-+ <P>
-+ Additionaly, Alpine 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 &quot;*&quot; is the indent-string. Aline
-+ 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 &quot;.&quot; or &quot;:&quot;.
-+ 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>
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-***************
-*** 18069,18074 ****
---- 18371,18377 ----
- <A HREF="h_config_index_format">&quot;<!--#echo var="VAR_index-format"-->&quot;</A> option,
- in the <A HREF="h_config_reply_intro">&quot;<!--#echo var="VAR_reply-leadin"-->&quot;</A> option,
- in signature files,
-+ in the <A HREF="h_config_reply_leadin_rules">&quot;new-rules&quot; option</A>,
- in template files used in
- <A HREF="h_rules_roles">&quot;roles&quot;</A>, and in the folder name
- that is the target of a Filter Rule.
-***************
-*** 18081,18087 ****
- <P>
- <P>
-
-! <H1><EM>Tokens Available for all Cases (except Filter Rules)</EM></H1>
-
- <DL>
- <DT>SUBJECT</DT>
---- 18384,18390 ----
- <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>
-***************
-*** 18114,18119 ****
---- 18417,18431 ----
- For example, &quot;mailbox@domain&quot;.
- </DD>
-
-+ <DT>ADDRESSTO</DT>
-+ <DD>
-+ This is similar to the &quot;TO&quot; 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, &quot;mailbox@domain&quot; when
-+ the e-mail message contains only one person in the To: field, or
-+ &quot;peter@flintstones.com president@world.com&quot;.
-+ </DD>
-+
- <DT>MAILBOX</DT>
- <DD>
- This is the same as the &quot;ADDRESS&quot; except that the
-***************
-*** 18161,18166 ****
---- 18473,18487 ----
- message's &quot;Cc:&quot; header field.
- </DD>
-
-+ <DT>ADDRESSCC</DT>
-+ <DD>
-+ This is similar to the &quot;CC&quot; 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: &quot;mailbox@domain&quot; when
-+ the e-mail message contains only one person in the Cc: field, or
-+ &quot;peter@flintstones.com president@world.com&quot;.
-+ </DD>
-+
- <DT>RECIPS</DT>
- <DD>
- This token represents the personal names (or email addresses if the names
-***************
-*** 18169,18174 ****
---- 18490,18503 ----
- the message's &quot;Cc:&quot; 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
-***************
-*** 18650,18655 ****
---- 18979,18992 ----
- <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.
-***************
-*** 19265,19270 ****
---- 19602,19679 ----
- </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>
-***************
-*** 21253,21258 ****
---- 21662,21763 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_maildir_location ======
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_maildir-location"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_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>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
-+ ====== h_config_maildir =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>Maildir Support</TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>Maildir Support</H1>
-+
-+ This version of Alpine 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 &quot;#md/inbox&quot; (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"><!--#echo var="VAR_maildir-location"--></A> configuration
-+ variable. Most of the time you will not have to worry about the
-+ <!--#echo var="VAR_maildirlocation"--> 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 Alpine 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 &quot;mail/&quot; to
-+ &quot;#md/mail&quot;. 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>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_literal_sig =====
- <HTML>
- <HEAD>
-***************
-*** 22015,22020 ****
---- 22520,22564 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_thread_sort_key =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_thread-sort-key--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_thread-sort-key--></TITLE></H1>
-+
-+ This option determines the order in which threads will be displayed. You
-+ can choose from the options listed below. Each folder is sorted in one of
-+ the sort orders displayed below first, then the thread containing the last
-+ message of that sorted list is put at the end of the index. All messages
-+ of that thread are &quot;removed&quot; from the sorted list and the
-+ process is repeated with the remaining messages in that list.
-+
-+ <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
-+ &quot;Thread&quot;.
-+
-+ <P>
-+ <UL>
-+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A>
-+ </UL><P>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_other_startup =====
- <HTML>
- <HEAD>
-***************
-*** 22285,22290 ****
---- 22829,23726 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_procid =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>Token: PROCID</TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>TOKEN: PROCID explained</H1>
-+
-+ <P>
-+ The PROCID token is a way in which the user and the program can differentiate
-+ between different parts of a program. It allows the user to tell the
-+ program when to use a specific rule, and only use it at that specific
-+ moment.
-+
-+ <P> The normal way in which this is done is by adding a new configuration
-+ variable. The idea behind the PROCID token is that instead of adding a new
-+ configuration variable (which means the user has to go through more
-+ configuration variables just to tune the program to his liking), we reuse
-+ an old variable and let the user look inside that variable for the desired
-+ behavior, which is actually set by setting the PROCID token.
-+
-+ <P>
-+ Consider the following examples for forward-rules:
-+
-+ <P>
-+ _ROLE_ == {work} =&gt; _SUBJECT_ := _COPY_{[tag] _SUBJECT_}
-+
-+ <P>
-+ and
-+
-+ <P>
-+ _ROLE_ == {work} =&gt; _LCC_ := _TRIM_{_FORWARDFROM_ &lt;_FORWARDADDRESS_&gt;}
-+
-+ <P>
-+ both are triggered by the same condition. Since both are configured in the
-+ same variable, only one of them will be executed all the time (whichever
-+ is first). Therefore in order to differentiate, we add a _PROCID_ token.
-+ So, for example, the first example above will be executed only when we are
-+ determining the subject. In this case, the following rule will accomplish
-+ this task
-+
-+ <P>
-+ _PROCID_ == {fwd-subject} && _ROLE_ == {work} =&gt; _SUBJECT_ := _COPY_{[tag] _SUBJECT_}
-+
-+ <P>
-+ In this case, this rule will be tested fully only when we are determining
-+ the subject line of a forwarded message, not otherwise.
-+
-+ <P>
-+ It is wise to add the _PROCID_ token as the first condition in a rule, so
-+ that other conditions will not be tested in a long list of rules.
-+
-+ <P>&lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
-+ ====== h_config_compose_rules =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_compose-rules"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_compose-rules"--></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 Alpine. 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>&lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
-+ ====== h_config_forward_rules =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_forward-rules"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_forward-rules"--></H1>
-+
-+ <P> This option has several uses. This feature uses the PROCID function
-+ to identify different features of forwarding. You can read more about PROCID
-+ by following <A HREF="h_config_procid">this link</A>.
-+
-+ <P> If you want to edit the subject of a forwarded message, use the
-+ PROCID <I>fwd-subject</I>. For example you could have a rule like
-+
-+ <P>
-+ _ROLE_ == {admin} && _SUBJECT_ !&gt; {[tag] } =&gt; _COPY_{[tag] _SUBJECT_}
-+
-+ <P> Another way in which this option can be used, is to trim the values of
-+ some fields. For this application the PROCID is <I>fwd-lcc</I>. For
-+ example it can be used in the following way:
-+
-+ <P>
-+ _ROLE_ == {work} => _LCC_ := _TRIM_{_FORWARDFROM_ &lt;_FORWARDADDRESS_&gt;}
-+
-+ <P> Other functions that can be used in this option are _EXEC_ and _REXTRIM_.
-+
-+ <P> You can also use the _EXEC_ function. The documentation for this function
-+ is in the
-+ <A HREF="h_config_resub_rules"><!--#echo var="VAR_reply-subject-rules"--></A>
-+ help text.
-+
-+ <P> This configuration option is just one of many that allow you to
-+ override the value of some global configurations within Alpine. 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>&lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
-+ ====== h_config_index_rules =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_index-rules"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_index-rules"--></H1>
-+
-+ <P> This option is used to supersede the value of the option <A
-+ HREF="h_config_index_format"><!--#echo var="VAR_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 Alpine. 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>&lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
-+ ====== h_config_pretty_command =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>Pretty-Command Explained</TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>Pretty Command Explained</H1>
-+
-+ <P> This text explains how to encode keys so that they will be recognized
-+ by Alpine in the _PKEY_ token. Most direct keystrokes are recognized in the
-+ same way. For example, the key ~ is recognized by the same character. The
-+ issue is how control, or functions keys are recognized. The internal code
-+ is most times easy to find out. If the key you want to use is not already
-+ recognized by Alpine simply press it. Alpine will print its code. For example,
-+ the return key is not recognized in this screen, so if you press it, you
-+ will see the following message.
-+
-+ <P> [Command &quot;RETURN&quot; not defined for this screen. Use ? for help]
-+
-+ <P> from here you can guess that the code for the return command is
-+ RETURN. You can try other commands, like Control-C, the TAB key, F4, etc.
-+ to see their codes.
-+
-+ <P>&lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
-+ ====== h_config_key_macro_rules =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_key-definition-rules"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_key-definition-rules"--></H1>
-+
-+ <P> This option can be used to define macros, that is, to define a key that
-+ when pressed executes a group of predetermined keystrokes. Since Alpine is
-+ a menu driven program, sometimes the same key may have different meanings
-+ in different screens, so a global redefinition of a key although possible
-+ is not advisable.
-+
-+ <P> <B>Always use the _SCREEN_ token as defined below.</B>. You have been
-+ warned!
-+
-+ <P> In each screen, every time you press a recognized key a command is
-+ activated. In order to understand this feature, think of commands instead
-+ of keystrokes. For example, you can think of the sort by thread command.
-+ This command is associated to the keystrokes $ and h. You may want to
-+ associate this command to a specific keystroke, like ~, so every time you
-+ press the ~ key, Alpine understand the $ and h keystrokes, which activates
-+ the sort by thread command.
-+
-+ <P> Therefore, in order to use this option you must think of three
-+ components. The screen where you will use the macro, the keystroke you
-+ want to use and the set of keystrokes used by Alpine to accomplish the task
-+ you want to accomplish. We will talk about these three components in what
-+ follows.
-+
-+ <P> First you must decide in which screen the macro will be used. This
-+ feature is currently only available for the screen where your messages
-+ are listed in index form (<A HREF="h_mail_index">MESSAGE INDEX</A>),
-+ the screen where your message is displayed
-+ (<A HREF="h_mail_view">MESSAGE TEXT</A>) and the screen where the list of
-+ folders is displayed (<A HREF="h_folder_maint">FOLDER LIST</A>). The
-+ internal names of these screens for this patch are &quot;index&quot;,
-+ &quot;text&quot; and
-+ &quot;folder&quot; respectively. Please note that the internal names are
-+ all in lowercase are are case sensitive.
-+
-+ <P> In order to define the screen, you use the _SCREEN_ token, so for
-+ example, you can write _SCREEN_ == {index}.
-+
-+ <P> Second you must think of which key you will use to activate the macro.
-+ Here you can use any key of your choice. The token you use to designate a
-+ key is the _PKEY_ token (PKEY stands for &quot;pressed key&quot;). For
-+ example you could use _PKEY_ == {~}, to designate the &quot;~&quot;
-+ character to activate the command. Some keystrokes (like control, or
-+ function keys) are encoded in special ways. You should read the
-+ <A HREF="h_config_pretty_command">full explanation</A> on how to find
-+ out the encoding for each keystroke.
-+
-+ <P> Last, you must think of the list of keys you will use to accomplish
-+ the task you want Alpine to perform. Say for example you want to have the
-+ folder sorted by thread. That means you want Aline to execute the keys
-+ &quot;$&quot; and &quot;h&quot;. You use the _COMMAND_ function to specify
-+ this. The syntax in this case is _COMMAND_{$,h}.
-+
-+ <P> Observe that in the above example the different inputs are separated
-+ by commas. This is the standard way in which the
-+ <A HREF="h_config_init_cmd_list"><!--#echo var="VAR_initial-keystroke-list"--></A> command works from
-+ the command line. Due to restrictions in the way Alpine works, a comma is a
-+ special character, which when added to a configuration option like this
-+ will cause the configuration to split into several lines in the
-+ configuration screen. This has the effect of producing several
-+ configuration options, all of which are incorrect. This is undesirable
-+ because what you want is to have it all in one line. In order to force the
-+ configuration into one line you must quote the comma. The best way to
-+ accomplish this is by quoting the full definition of the rule. For
-+ example.
-+
-+ <P>
-+ &quot;_SCREEN_ == {index} && _PKEY_ == {~} => _COMMAND_{$,h}&quot;
-+
-+ <P> Another way to accomplish the same effect is by quoting the command and
-+ not using quotes for the full command, nor commas to separate the
-+ keystrokes in the command, for example
-+
-+ <P>
-+ _SCREEN_ == {index} && _PKEY_ == {~} => _COMMAND_{&quot;$h&quot;}
-+
-+ <P> For more information on how to define the argument of the _COMMAND_
-+ token see the help of
-+ <A HREF="h_config_init_cmd_list"><!--#echo var="VAR_initial-keystroke-list"--></A>.
-+
-+ <P> Because the $ command can also be used as the first character in the
-+ definition of an environemnt variable, no expansion of environment variables
-+ is done when parsing this variable. The $ character does not need quoting
-+ and quoting it will make Alpine fail to produce the correct result.
-+
-+ <P> This configuration option is just one of many that allow you to
-+ override the value of some global configurations within Alpine. 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>&lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
-+ ====== h_config_replace_rules =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_replace-rules"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_replace-rules"--></H1>
-+
-+ <P> This option is used to have Alpine print different values for specific
-+ tokens in the <A HREF="h_config_index_format"><!--#echo var="VAR_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_{&#92;[some-tag-here #[0-9].*&#92;]}
-+
-+ <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, like the reply leadin string in the OPENINGTEXTNQ token of the index.
-+ <BR>
-+ _FOLDER_ == {mailing-list} => _OPENINGTEXTNQ_ := _REXTRIM_{On.*wrote: }
-+
-+ <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>
-+
-+ <P> You can also use the _EXEC_ function. The documentation for this function
-+ is in the
-+ <A HREF="h_config_resub_rules"><!--#echo var="VAR_reply-subject-rules"--></A>
-+ help text.
-+
-+ <P> This configuration option is just one of many that allow you to
-+ override the value of some global configurations within Alpine. 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>&lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
-+ ====== h_config_reply_leadin_rules =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_reply-leadin-rules"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_reply-leadin-rules"--></H1>
-+
-+ <P> This option is used to have Alpine generate a different
-+ <A HREF="h_config_reply_intro"><!--#echo var="VAR_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&oacute; _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 Alpine. 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>&lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
-+ ====== h_config_resub_rules =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_reply-subject-rules"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_reply-subject-rules"--></H1>
-+
-+ <P> This option is used to have Alpine generate a different subject when
-+ replying rather than the one Alpine 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 &quot;Re:&quot;
-+ to &quot;AW:&quot; or &quot;Sv:&quot;. In this case a rule like<BR>
-+ <center>_SUBJECT_ >> {Sv: ;AW: } => _SUBJECT_ := _TRIM_{Sv: ;AW: }</center>
-+ <P>
-+ would eliminate undesired strings in replies.
-+
-+ <P> Another interesting use of this option is the use of the _EXEC_ function.
-+ This function takes as an argument a program or a script. This program
-+ must take as the input a file, and write its output to that file. For example,
-+ below is a sample of a script that removes the letter &quot;a&quot; of a file.
-+
-+ <PRE>
-+ #!/bin/sh
-+ sed 's/a//g' $1 > /tmp/mytest
-+ mv /tmp/mytest $1
-+ </PRE>
-+
-+ <P>
-+ As you can see this script took &quot;$1&quot; as input file, the sed program
-+ wrote its output to /tmp/mytest, and then the move program moved the file
-+ /tmp/mytest to the input file &quot;$1&quot;. This is the kind of behavior
-+ that your program is expected to have.
-+
-+ <P>
-+ The content of the input file (&quot;$1&quot; above) is the value of a token
-+ like _SUBJECT_. In order to indicate this, we use the notation
-+
-+ <P>
-+ _SUBJECT_ := _EXEC_{/path/to/script}
-+
-+ <P> for the action. So for example
-+
-+ <P>
-+ _FOLDER_ := {sent-mail} =&gt; _SUBJECT_ := _EXEC_{/path/to/script}
-+
-+ <P> is a valid rule.
-+
-+ <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 Alpine. 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>&lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
-+ ====== h_config_sort_rules =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_sort-rules"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_sort-rules"--></H1>
-+
-+ <P> This option is used to have Alpine sort different folders in different orders
-+ and thus override the value already set in the
-+ <A HREF="h_config_sort_key"><!--#echo var="VAR_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 Alpine. 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>&lt;End of help on this topic&gt;
-+
-+ </BODY>
-+ </HTML>
-+ ====== h_config_save_rules =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_save-rules"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_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"><!--#echo var="FEAT_auto-move-read-msgs"--></A> configuration
-+ option is also enabled then these definitions will be used to move messages
-+ from your INBOX when exiting Alpine.
-+
-+ <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 Alpine. 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>&lt;End of help on this topic&gt;
-+
-+ </BODY>
-+ </HTML>
-+ ====== h_config_reply_indent_rules =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_reply-indent-rules"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_reply-indent-rules"--></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"><!--#echo var="VAR_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 Alpine. 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>&lt;End of help on this topic&gt;
-+
-+ </BODY>
-+ </HTML>
-+ ====== h_config_smtp_rules =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_smtp-rules"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_smtp-rules"--></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 Alpine 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 Alpine will get
-+ the name of the server from the
-+ <A HREF="h_config_smtp_server">&quot;<!--#echo var="VAR_smtp-server"-->&quot;</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 Alpine. 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>&lt;End of help on this topic&gt;
-+
-+ </BODY>
-+ </HTML>
-+ ====== h_config_startup_rules =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_startup-rules"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_startup-rules"--></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"><!--#echo var="VAR_incoming-startup-rule"--></A> and override
-+ Alpine'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 Alpine. 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>&lt;End of help on this topic&gt;
-+
-+ </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 option you have set in Alpine.
-+
-+ <P>
-+ For example, you can set your folders to be sorted in a certain way when
-+ you open them (say by Arrival). You may want, however, your newsgroups to
-+ be sorted by thread. The set of &quot;rules&quot; options allows you to
-+ configure this and many other options, including the index-format for
-+ specific folders, the way the subject is displayed in the index screen or
-+ the reply-leadin-string, to name a few.
-+
-+ <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} =&gt; _SAVE_{Fred}
-+
-+ <P>
-+ Here the separator is "=&gt;". Whatever is to the left of the separator
-+ is the condition (that is _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 &quot;Fred
-+ Flinstone&quot;, and the action will be that you will be offered to save
-+ it in the folder &quot;Fred&quot;, whenever you press the letter
-+ &quot;S&quot; to save a message.
-+
-+ <P>
-+ The separator is always &quot;=&gt;&quot;, with one exception to be seen
-+ later. But for the most part this will be the only one you will ever need.
-+
-+ <P>
-+ Now let us see how to do it. There are 13 functions already defined for
-+ you. These are: _EXEC_, _INDEX_, _REPLACE_, _REPLY_, _RESUB_, _SAVE_,
-+ _SIGNATURE_, _SORT_, _STARTUP_, _TRIM_, _REXTRIM_, _THREADSTYLE and
-+ _THREADINDEX_. The parameter of a function has to be enclosed between
-+ &quot;{&quot; and &quot;}&quot;, so for example you can specify
-+ _SAVE_{saved-messages} as a valid sentence.
-+
-+ <P>
-+ Later in the document you will find examples. Here is a short
-+ description of what each function does:
-+
-+ <P>
-+ <UL>
-+ <LI> _EXEC_ : This function takes as an argument a program. This program
-+ gets as the input a file and must rewrite its output to that file, which
-+ is then taken as the value to replace from the contents of that file. You
-+ can use this function with
-+ <A HREF="h_config_resub_rules"><!--#echo var="VAR_reply-subject-rules"--></A>,
-+ <A HREF="h_config_replace_rules"><!--#echo var="VAR_replace-rules"--></A> and
-+ <A HREF="h_config_forward_rules"><!--#echo var="VAR_forward-rules"--></A>.
-+ See the help of those options for examples of how to use this function
-+ and configure these rules.
-+ <BR>&nbsp;<BR>
-+ <LI> _INDEX_ : This function takes as an argument an index-format, and
-+ makes that the index-format for the specified folder.
-+ <BR>&nbsp;<BR>
-+ <LI> _REPLACE_ : This function replaces the subject/from of the given e-mail by
-+ another subject/from only when displaying the index.
-+ <BR>&nbsp;<BR>
-+ <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.
-+ <BR>&nbsp;<BR>
-+ <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.
-+ <BR>&nbsp;<BR>
-+ <LI> _RESUB_ : This function replaces the subject of the given e-mail by
-+ another subject only when replying to a message.
-+ <BR>&nbsp;<BR>
-+ <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.
-+ <BR>&nbsp;<BR>
-+ <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.
-+ <BR>&nbsp;<BR>
-+ <LI> _SMTP_ : This function takes as an argument the definition of a
-+ SMTP server.
-+ <BR>&nbsp;<BR>
-+ <LI> _SORT_ : This function takes as an argument a Sort Style, and sorts a
-+ specified folder in that sort order.
-+ <BR>&nbsp;<BR>
-+ <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_.
-+ <BR>&nbsp;<BR>
-+ <LI> _REXTRIM_ : Same as _TRIM_ but its argument is one and
-+ only one extended regular expression.
-+ <BR>&nbsp;<BR>
-+ <LI> _STARTUP_ : This function takes as an argument an
-+ incoming-startup-rule, and open an specified folder using that rule.
-+ <BR>&nbsp;<BR>
-+ <LI> _THREADSTYLE_ : This function takes as an argument a
-+ threading-display-style and uses it to display threads in a folder.
-+ <BR>&nbsp;<BR>
-+ <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} =&gt; _SAVE_{Fred}
-+
-+ <P> it will only be applied if the from is &quot;Fred Flinstone&quot;. If
-+ the From is &quot;Wilma Flinstone&quot; 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 &quot;{&quot; and &quot;}&quot; in the condition, this part
-+ of the condition is called the &quot;condition set&quot;. The definition
-+ of each token can be found <A HREF="h_index_tokens">here</A>.
-+
-+ <P> A special testing token called _PROCID_ can be used to differentiate
-+ inside a rule, between two rules that are triggered by the same condition.
-+ A full explanation of the _PROCID_ token can be found in
-+ <A HREF="h_config_procid">this link</A>.
-+
-+ <P> There are two more tokens related to the option
-+ <A HREF="h_config_key_macro_rules">key-definition-rules</A>. Those tokens
-+ are only specific to that option, and hence are not explained here.
-+
-+ <P> You can also test in different ways, you can use the following
-+ &quot;test operands&quot;: &lt;&lt;, !&lt;, &gt;&gt;, !&gt;, == and !=.
-+ All of them are two strings long. Here is the meaning of them:
-+
-+ <P>
-+ <UL>
-+ <LI> &lt;&lt; : It tests if the value of the token is contained in
-+ the condition set. Here for example if the condition set were equal to
-+ &quot;Freddy&quot;, then the condition: _NICK_ &lt;&lt; {Freddy}, would be true if
-+ the value of _NICK_ were &quot;Fred&quot;, &quot;red&quot; or &quot;Freddy&quot;. You are just looking
-+ for substrings here.
-+ <LI> &gt;&gt; : 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
-+ &quot;Fred&quot;, then the condition: _FROM_ &gt;&gt; {Fred}, would be true if
-+ the value of _FROM_ were &quot;Fred Flinstone&quot; or &quot;Fred P. Flinstone&quot; or &quot;Freddy&quot;.
-+ <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 &quot;Freddy&quot; or &quot;red&quot;.
-+ <LI> !&lt; : This is true only when &lt;&lt; is false and viceversa.
-+ <LI> !&gt; : This is true only when &gt;&gt; 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 &quot;folder1&quot; and &quot;folder2&quot; to be sorted by
-+ Ordered Subject upon entering. Then you can list them all of them in the
-+ condition part separting them by a &quot;;&quot;. Here is the way to do it.
-+
-+ <P>
-+ _FOLDER_ &lt;&lt; {folder1; folder2} =&gt; _SORT_{OrderedSubj}
-+
-+ <P>
-+ Here is the first subtelty about these definitions. Notice that the
-+ following rule:
-+
-+ <P>
-+ _FOLDER_ == {folder1; folder2} =&gt; _SORT_{Reverse OrderedSubj}
-+
-+ <P> works only for &quot;folder1&quot; but not for &quot;folder2&quot;. This is because the
-+ comparison of the name of the folder is done with whatever is in between
-+ &quot;{&quot;, &quot;;&quot; or &quot;}&quot;, so in the above rule you would be testing <BR>
-+ &quot;folder2&quot; == &quot; folder2&quot;. The extra space makes the difference.
-+ The reason why the first rule does not fail is because
-+ &quot;folder2&quot; &lt;&lt; &quot; folder2&quot; 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} =&gt; _SAVE_{_NICK_/_NICK_} <BR>
-+ This means that if the nick is lisa, it will
-+ save the message in the folder &quot;lisa/lisa&quot;, and if the nick
-+ is &quot;kika&quot;, it will save the message in the folder &quot;kika/kika&quot;
-+
-+ <P>
-+ _FOLDER_ == {Lynx} -&gt; lynx <BR>
-+ This, is an abreviation of the following rule:<BR>
-+ _FOLDER_ == {Lynx} =&gt; _SAVE_{lynx} <BR>
-+ (note the change in separator from &quot;=&gt;&quot; to &quot;-&gt;&quot;). In the future
-+ I will use that abreviation.
-+
-+ <P> _FOLDER_ &lt;&lt; {comp.mail.pine; pine-info; pine-alpha} -&gt; pine <BR>
-+ Any message in the folders &quot;comp.mail.pine&quot;, &quot;pine-info&quot; or &quot;pine-alpha&quot;
-+ will be saved to the folder &quot;pine&quot;.
-+
-+ <P> _FROM_ &lt;&lt; {Pine Master} -&gt; pine <BR>
-+ Any message whose From field contains
-+ &quot;Pine Master&quot; will be saved in the folder pine.
-+
-+ <P> _FOLDER_ &lt;&lt; {Lynx; pine-info; comp.mail.pine} =&gt;
-+ _INDEX_{IMAPSTATUS MSGNO DATE FROMORTO(33%) SUBJECT(66%)} <BR> Use a
-+ different index-format for the folders &quot;Lynx&quot;, &quot;pine-info&quot; and
-+ &quot;comp.mail.pine&quot;, where the size is not present.
-+
-+ <P> _FOLDER_ == {Lynx;pine-info} =&gt; _REPLY_{*** _FROM_ (_ADDRESS_)
-+ wrote in the _FOLDER_ list _SMARTDATE_(&quot;Today&quot; &quot;today&quot; &quot;on
-+ _LONGDATE_&quot;):}<BR> If a message is in one of the incoming folders &quot;Lynx&quot;
-+ or &quot;pine-info&quot;, create a reply-leadin-string that acknowledges that. Note
-+ the absence of &quot;,&quot; 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_ &lt;&lt; {Lynx; comp.mail.pine; pine_info; pine-alpha} =&gt;
-+ _SORT_{OrderedSubj}<BR> This means upon opening, sort the folders &quot;Lynx&quot;,
-+ &quot;comp.mail.pine&quot;, 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_ &lt;&lt; {Lynx} =&gt; _SUBJECT_ := _TRIM_{lynx-dev }<BR> In
-+ the folder &quot;Lynx&quot; eliminate from the subject the string &quot;lynx-dev &quot; (with
-+ the space at the end). For example a message whose subject is &quot;Re:
-+ lynx-dev unvisited Visited Links&quot;, would be shown in the index with
-+ subject: &quot;Re: unvisited Visited Links&quot;, making the subject shorter and
-+ giving the same information.
-+
-+ <P> _FROM_ &gt;&gt; {Name (Comment)} =&gt; _FROM_ :=
-+ _TRIM_{ (Comment)}<BR> Remove the part &quot; (Comment)&quot;
-+ from the _FROM_, so when displaying in the index the real From &quot;Name&quot;
-+ will appear.
-+
-+ <P> _SUBJECT_ == {} =&gt; _RESUB_{Re: your mail without subject}
-+ If there is no subject in the message, use the subject &quot;Re: your mail
-+ wiyhout subject&quot; 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 &quot;bug report&quot;, with the subject
-+ &quot;Re: About your bug report&quot;, you could make
-+
-+ <P>
-+ _SUBJECT_ == {bug report} =&gt; _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: &quot;Re:
-+ About your Re: About your bug report&quot;, so it grew. You may want to avoid
-+ this growth by using the following rule:
-+
-+ <P>
-+ _SUBJECT_ &gt;&gt; {bug report} && _SUBJECT_ !&gt; {Re: } =&gt; _RESUB_{Re: About your _SUBJECT_}<BR>
-+
-+ <P>
-+ which will only add the string &quot;Re: About your&quot; only the first time the
-+ message is replied.
-+
-+ <P>
-+ Say your personal name is &quot;Fred Flinstones&quot;, and assume that you don't
-+ like to see &quot;To: comp.mail.pine&quot; 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 &quot;pine-info&quot; 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 &quot;Trash&quot;, use
-+ the following rule:<BR>
-+ _FLAG_ >> {D} -> Trash
-+
-+ <P>
-+ The reason why the above test is not &quot;_FLAG_ == {D}&quot; 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 &quot;saving&quot; rules do not compete with &quot;sorting&quot; rules. So the first
-+ &quot;saving&quot; rule that matches will be executed in the case of saving and so
-+ on.
-+
-+ <P>
-+ <UL>
-+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A>
-+ </UL><P>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_char_set =====
- <HTML>
- <HEAD>
-***************
-*** 22592,22597 ****
---- 24028,24070 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_special_text_to_color =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_special-text-color"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_special-text-color"--></H1>
-+
-+ Use this option to enter patterns (text or regular expressions) that
-+ Alpine will highlight in the body of the text that is not part of a handle
-+ (an internal or external link that Alpine 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. There is only a <A
-+ HREF="h_regex_text">set</A> of regular expressions that are matched.
-+
-+ <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>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_display_filters =====
- <HTML>
- <HEAD>
-***************
-*** 22713,22718 ****
---- 24186,24198 ----
- improve security. The number is unique to the current Alpine session
- and is only generated once per session.
- </DD>
-+
-+ <DT>_SILENT_</DT>
-+ <DD>When the filter is executed, this token tells Alpine not to repaint
-+ the screen while the command is being executed. This can be used with
-+ filters that do not interact with the user, and therefore repainting
-+ the screen is not necessary.
-+ </DD>
- </DL>
-
- <P>
-***************
-*** 22749,22754 ****
---- 24229,24240 ----
- Command Modifying Tokens:
-
- <DL>
-+ <DT>_ADDRESS_</DT>
-+ <DD>When the command is executed, this token is replaced
-+ with the address of the person sending the message in the format
-+ mailbox@host.
-+ </DD>
-+
- <DT>_RECIPIENTS_</DT>
- <DD>When the command is executed, this token is replaced
- with the space delimited list of recipients of the
-***************
-*** 25861,25866 ****
---- 27347,27422 ----
- &lt;End of help on this topic&gt;
- </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">
-+ <!--#echo var="VAR_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 Alpine. 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>
-+ &lt;End of help on this topic&gt;
-+ </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">
-+ <!--#echo var="VAR_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"><!--#echo var="VAR_threading-index-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 Alpine. 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>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_pruning_rule =====
- <HTML>
- <HEAD>
-***************
-*** 27467,27472 ****
---- 29023,29058 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_new_thread_blank_subject =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>FEATURE: <!--#echo var="FEAT_new-thread-on-blank-subject"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>FEATURE: <!--#echo var="FEAT_new-thread-on-blank-subject"--></H1>
-+
-+ When this feature is enabled (the default) Alpine will create a new thread
-+ every time that the subject line becomes empty at any time during composition.
-+
-+ <P>
-+ This behavior is particularly useful in case you are replying to a message.
-+ Replying to a message causes the message to be in the same thread than the
-+ original message that is being replied to. However, many authors want to create
-+ a new message (in a different thread) while replying to a message, and they do
-+ this by changing the full subject, by first deleting the original subject and
-+ typing the new subject of the current message.
-+
-+ <P>
-+ Enabling this feature causes that any time that the subject is deleted, the
-+ message being composed will be considered the first message of a new thread.
-+
-+ <P>
-+ <UL>
-+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A>
-+ </UL><P>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_strip_sigdashes =====
- <HTML>
- <HEAD>
-***************
-*** 27517,27522 ****
---- 29103,29144 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_preserve_field =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>FEATURE: <!--#echo var="FEAT_preserve-original-fields"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>FEATURE: <!--#echo var="FEAT_preserve-original-fields"--></H1>
-+
-+ When you reply to a message that has been sent to several recipients, some of
-+ them may have been added in different parts of the headers. For example,
-+ some of the recipients will be listed in the To: header, while others will
-+ be listed in the Cc: header.
-+ <P>
-+ If this feature is disabled, the default behavior of Alpine will be used,
-+ and that is, that almost all recipients of the message will be
-+ listed in the Cc: field. However, if you enable this feature, then,
-+ excepting you, recipients originally listed in the Cc: field will be
-+ listed again in the Cc: field, and those listed in the To: field in the
-+ original message will be listed in the To: field again. The person in the
-+ From: field will be added to the To: field.
-+ <P>
-+ Note that this will cause some messages that you send in Alpine to look
-+ different. In particular, the To: field of a message will not be put in the
-+ Cc: field, as is normally done. In fact, most people expect this to happen.
-+ If you find that this is a problem you should disable this feature. You can
-+ still make Alpine have this behavior on a per message basis. In order to do
-+ this, you will see a new option in the menu for the &quot;Reply to all
-+ recipients?&quot; question. In this case, pressing &quot;p&quot; will make
-+ Alpine toggle its question so you can preserve the To: and Cc: fields for that
-+ message.
-+ <UL>
-+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A>
-+ </UL><P>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_sub_lists =====
- <HTML>
- <HEAD>
-***************
-*** 27701,27706 ****
---- 29323,29344 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_use_domain =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>FEATURE: <!--#echo var="FEAT_return-path-uses-domain-name"--> </TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>FEATURE: <!--#echo var="FEAT_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>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_use_sender_not_x =====
- <HTML>
- <HEAD>
-***************
-*** 28297,28302 ****
---- 29935,30005 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_alt_reply_menu =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>FEATURE: <!--#echo var="FEAT_alternate-reply-menu"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>FEATURE: <!--#echo var="FEAT_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 &quot;S Strip Sig&quot;, it means that if you press the letter
-+ &quot;S&quot; the signature will be stripped off the message you are
-+ replying. Observer that the menu will change to
-+ &quot;S No Strip&quot;, which means that if you press &quot;S&quot;, 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> A: This determines if Pine will include or not the attachments sent to
-+ you in the message that you are replying. By default Pine will use the value
-+ of the configuration option
-+ <A HREF="h_config_attach_in_reply"><!--#echo var="FEAT_include-attachments-in-reply"--></A>, but
-+ you can use this option to override such behavior in a per message basis.
-+
-+ <LI> F: To decide if you want to send flowed text or not. This option appears
-+ unless you have quelled sending flowed text.
-+
-+ <LI> H: This option determines if the headers of a message are to be
-+ included in the body of the message that is being replied. By default Pine
-+ will use the value of the configuration option
-+ <A HREF="h_config_include_header"><!--#echo var="FEAT_include-header-in-reply"--></A>, but
-+ you can use this option to override such behavior in a per message basis.
-+
-+ <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.
-+
-+ <LI> S: To strip the signature from a message, only available is the feature
-+ <a href="h_config_sigdashes"><!--#echo var="FEAT_enable-sigdashes"--></a> or the
-+ <a href="h_config_strip_sigdashes"><!--#echo var="FEAT_strip-from-sigdashes-on-reply"--></a> option are
-+ enabled.
-+
-+ </OL>
-+ <P>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_del_from_dot =====
- <HTML>
- <HEAD>
-***************
-*** 28820,28825 ****
---- 30523,30560 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_enable_long_url =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>FEATURE: <!--#echo var="FEAT_enable-msg-view-long-url"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>FEATURE: <!--#echo var="FEAT_enable-msg-view-long-url"--></H1>
-+
-+ This feature modifies the behavior of Alpine's MESSAGE TEXT screen. When this feature
-+ is set alpine will attempt to recognize long urls (those that spread over several
-+ lines in the text) for the HTTP protocol, even when they have not been enclosed between
-+ delimiters &quot;&lt;&quot; and &quot;&gt;&quot;.
-+
-+ <P>The normal behavior in Alpine is that if a URL is preceeded by the &quot;&lt;&quot;
-+ character and this URL was not finished before the end of the line, then a
-+ continuation of the URL is searched in the following line(s). Normally, this type of
-+ URLs will be ended by the &quot;&gt;&quot; character, and if it is not, there is a
-+ possibility of including erroneous text into the URL.
-+
-+ <P>Enabling this feature will make Alpine search for a continuation of certain URLs in
-+ lines following its location. This will be of great help most times, but in some cases
-+ the algorithm will catch some text into the URL that is not part of the URL.
-+
-+ <P>If you find that Alpine failed to recognize correctly a URL simply edit the URL before
-+ passing it to your browser.
-+
-+ <UL>
-+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A>
-+ </UL><P>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_enable_view_addresses =====
- <HTML>
- <HEAD>
-***************
-*** 29127,29132 ****
---- 30862,30910 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_courier_list =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>FEATURE: <!--#echo var="FEAT_courier-folder-list"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>FEATURE: <!--#echo var="FEAT_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 &quot;#mc/&quot;
-+ prefix instead of the &quot;#md/&quot; 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_fold_dir_view"><!--#echo var="FEAT_separate-folder-and-directory-entries"--></a>
-+ a folder may be listed as &quot;folder[.]&quot;, or as two entries in the
-+ list by &quot;folder&quot; and &quot;folder.&quot;.
-+ <P>
-+ If this option is disabled, Pine will list local folders that are in Courier
-+ style format, as &quot;folder&quot;, and those that are also directories as
-+ &quot;folder[.]&quot;. 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 &quot;foo&quot; simply add &quot;foo.bar&quot; directly. This will
-+ create the directory &quot;foo&quot; and the subfolder &quot;bar&quot; 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>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_verbose_post =====
- <HTML>
- <HEAD>
-***************
-*** 29281,29286 ****
---- 31059,31087 ----
- &lt;End of help on this topic&gt;
- </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 Alpine's behavior upon quitting. If set,
-+ and the
-+ <A HREF="h_config_read_message_folder">&quot;<!--#echo var="VAR_read-message-folder"-->&quot;</A>
-+ option is also set, then Alpine 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">&quot;<!--#echo var="VAR_save-rules"-->&quot;</A> and mark
-+ them as deleted in the INBOX. Messages in the INBOX marked with an
-+ &quot;N&quot; (meaning New, or unseen) are not affected.
-+ <P>
-+ <UL>
-+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A>
-+ </UL><P>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_auto_fcc_only =====
- <HTML>
- <HEAD>
-***************
-*** 29731,29736 ****
---- 31532,31554 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_enhanced_thread =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>FEATURE: <!--#echo var="FEAT_enhanced-fancy-thread-support"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>FEATURE: <!--#echo var="FEAT_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>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_news_cross_deletes =====
- <HTML>
- <HEAD>
-***************
-*** 30209,30214 ****
---- 32027,32066 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_ignore_size =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>FEATURE: <!--#echo var="FEAT_ignore-size-changes"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>FEATURE: <!--#echo var="FEAT_ignore-size-changes"--></H1>
-+
-+ When you have an account residing in an IMAP server, Alpine gets the size of
-+ each message from the server. However, when Alpine saves a message residing
-+ in an IMAP server, Alpine computes the size of the message independently. If
-+ these two numbers do not match for a message, Alpine asks you if you still
-+ want to take the risk of saving the message, since data corruption or loss
-+ of data could result of this save.
-+
-+ <P>
-+ Sometimes the root of this problem is that the server is defective, and
-+ there will not be loss of information when saving such message. Enabling
-+ this feature will make Aline ignore such error and continue saving the
-+ message. If you can determine that this is the case, enable this feature
-+ so that the saving operation will succeed. An example of a defective server
-+ is the Gmail IMAP server. Another example is some versions of the Exchange
-+ server.
-+
-+ <P>
-+ It is recommended that this feature be disabled most of the time and only
-+ enabled when you find a server which you can determine that has the above
-+ mentioned defect, but be disabled again after making this operation
-+ succeed.
-+
-+ <P>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_force_low_speed =====
- <HTML>
- <HEAD>
-***************
-*** 30479,30484 ****
---- 32331,32357 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_circular_tab =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>FEATURE: <!--#echo var="FEAT_enable-circular-tab"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>FEATURE: <!--#echo var="FEAT_enable-circular-tab"--></H1>
-+
-+ <P>
-+ This Feature is like
-+ <A HREF="h_config_auto_open_unread">&quot;<!--#echo var="FEAT_auto-open-next-unread"-->&quot;</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>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_auto_include_reply =====
- <HTML>
- <HEAD>
-***************
-*** 31142,31147 ****
---- 33015,33113 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_folder_color =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: Folder Color</TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: Folder Color</H1>
-+
-+ Sets the colors Alpine uses for coloring a folder in the FOLDER LIST
-+ screen. By default, the Folder Color is the normal text color.
-+
-+ <P>
-+ If you set a color for this feature, other than the normal color
-+ (the default), or a color for
-+ <A HREF="h_config_directory_color">Directory Color</A>, then directories
-+ will be colored according to the color specified in the
-+ <A HREF="h_config_directory_color">Directory Color</A> option. In this
-+ case, the color will be the only indication that the colored name
-+ refers to a directory. The normal behavior is that Alpine
-+ indicates that a name refers to a directory by appending a
-+ separator (like &quot;/&quot; or &quot;.&quot;) to the name of
-+ the folder.
-+
-+ <P>
-+ If a folder is a directory, then the folder name will be painted
-+ according to the color defined by this variable, and a separator
-+ indicator (like &quot;/&quot; or &quot;.&quot;) will be added
-+ to the name. That
-+ indicator will be painted according to the color defined in the
-+ <A HREF="h_config_directory_color">Directory Color</A> option.
-+
-+ <P>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
-+ ====== h_config_directory_color =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: Directory Color</TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: Directory Color</H1>
-+
-+ Sets the colors Alpine uses for coloring a directory in the FOLDER LIST
-+ screen. By default, the Folder Color is the normal text color.
-+ <P>
-+ If you set a color for this feature, other than the normal color
-+ (the default), or a color for
-+ <A HREF="h_config_folder_color">Folder Color</A>, then folders
-+ will be colored according to the color specified in the
-+ <A HREF="h_config_folder_color">Folder Color</A> option. In this
-+ case, the color will be the only indication that the colored name
-+ refers to a directory. The normal behavior is that Alpine
-+ indicates that a name refers to a directory by appending a
-+ separator (like &quot;/&quot; or &quot;.&quot;) to the name of
-+ the folder.
-+ <P>
-+ If a folder is a directory, then the folder name will be painted
-+ according to the color defined by the option
-+ <A HREF="h_config_folder_color">Folder Color</A>, and the separator
-+ indicator (like &quot;/&quot; or &quot;.&quot;) will be added
-+ after the name. That
-+ indicator will be painted according to the color defined in this
-+ option.
-+ <P>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
-+ ====== h_config_folder_list_color =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: Folder-List Color</TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: Folder-List Color</H1>
-+
-+ Sets the colors Alpine uses for coloring normal text in the FOLDER LIST
-+ screen. By default, the Folder-List Color is the normal text color.
-+ <P>
-+ This text refers to the informative text that Alpine displays so you
-+ can recognize each collection. The color of the content of each collection
-+ is determined by the options <A HREF="h_config_folder_color">Folder Color</A>
-+ and <A HREF="h_config_directory_color">Directory Color</A>.
-+ <P>
-+ Unlike the options
-+ <A HREF="h_config_folder_color">Folder Color</A>
-+ and <A HREF="h_config_directory_color">Directory Color</A>, configuring
-+ this option does not affect the way that it tradinionally reports folders,
-+ directories and folders that are directories.
-+ <P>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_incunseen_color =====
- <HTML>
- <HEAD>
-***************
-*** 31197,31202 ****
---- 33163,33192 ----
- &lt;End of help on this topic&gt;
- </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>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_prompt_color =====
- <HTML>
- <HEAD>
-***************
-*** 31464,31469 ****
---- 33454,33488 ----
- &lt;End of help on this topic&gt;
- </BODY>
- </HTML>
-+ ====== h_config_indextoken_color =====
-+ <HTML>
-+ <HEAD>
-+ <TITLE>OPTION: <!--#echo var="VAR_index-token-colors"--></TITLE>
-+ </HEAD>
-+ <BODY>
-+ <H1>OPTION: <!--#echo var="VAR_index-token-colors"--></H1>
-+
-+ This option allows you to set up the color in which any token, not specified by the
-+ previous options, will be colored in the MESSAGE INDEX screen.
-+ <P>
-+ In order to use this option, you must press the &quot;I&quot; <B>IndxHdr</B> command, and add
-+ a token that can be used in the index format.
-+ The list of available tokens is <A HREF="h_index_tokens">here</A>.
-+ <P>
-+ If you fail to enter a valid token your entry will be ignored, and you will be asked to
-+ enter a new one. Once you have entered a valid token, a line will be added to the
-+ configuration screen that you can use to set up the colors in which that token will
-+ be painted. This is done in the same way that you configure colors for other
-+ variables.
-+
-+ <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>
-+ &lt;End of help on this topic&gt;
-+ </BODY>
-+ </HTML>
- ====== h_config_customhdr_pattern =====
- <HTML>
- <HEAD>
-***************
-*** 35075,35077 ****
---- 37094,37099 ----
- ========== h_select_by_smaller_size ==========
- Enter a number or ^C to cancel. All messages less than this many characters
- in size will be selected. Examples: 2176, 1.53K (1530), or 3M (3000000).
-+ ========== h_preserve_field ==========
-+ Use 'p' to toggle between preserving or not preserving the original To:
-+ and Cc: fields of the message. Enter ^C to cancel message.
-diff -rc alpine-2.00/pith/reply.c alpine-2.00.I.USE/pith/reply.c
-*** alpine-2.00/pith/reply.c 2008-06-03 12:27:23.000000000 -0700
---- alpine-2.00.I.USE/pith/reply.c 2011-02-07 20:33:44.000000000 -0800
-***************
-*** 45,50 ****
---- 45,52 ----
- #include "../pith/ablookup.h"
- #include "../pith/mailcmd.h"
- #include "../pith/margin.h"
-+ #include "../pith/copyaddr.h"
-+ #include "../pith/rules.h"
-
-
- /*
-***************
-*** 372,391 ****
- /* Put Reply-To or From in To. */
- *to_tail = reply_cp_addr(ps, 0, NULL, NULL, outgoing->to,
- (ADDRESS *) NULL, saved_from, RCA_ALL);
-- /* and the rest in cc */
- if(replytoall){
-! *cc_tail = reply_cp_addr(ps, 0, NULL, NULL, outgoing->cc,
- outgoing->to, saved_to, RCA_ALL);
-! while(*cc_tail) /* stay on last address */
-! cc_tail = &(*cc_tail)->next;
-
-! *cc_tail = reply_cp_addr(ps, 0, NULL, NULL, outgoing->cc,
- outgoing->to, saved_cc, RCA_ALL);
-! while(*cc_tail)
-! cc_tail = &(*cc_tail)->next;
-
-! *cc_tail = reply_cp_addr(ps, 0, NULL, NULL, outgoing->cc,
- outgoing->to, saved_resent, RCA_ALL);
- }
- }
- else if(saved_to){
---- 374,410 ----
- /* Put Reply-To or From in To. */
- *to_tail = reply_cp_addr(ps, 0, NULL, NULL, outgoing->to,
- (ADDRESS *) NULL, saved_from, RCA_ALL);
- if(replytoall){
-! if(ps->preserve){
-! while(*to_tail)
-! to_tail = &(*to_tail)->next;
-!
-! *to_tail = reply_cp_addr(ps, 0, NULL, NULL, outgoing->to,
-! (ADDRESS *) NULL, saved_to, RCA_ALL);
-!
-! while(*to_tail)
-! to_tail = &(*to_tail)->next;
-!
-! *to_tail = reply_cp_addr(ps, 0, NULL, NULL, outgoing->cc,
-! outgoing->to, saved_resent, RCA_ALL);
-!
-! *cc_tail = reply_cp_addr(ps, 0, NULL, NULL, outgoing->cc,
-! outgoing->to, saved_cc, RCA_ALL);
-! }
-! else{ /* and the rest in cc */
-! *cc_tail = reply_cp_addr(ps, 0, NULL, NULL, outgoing->cc,
- outgoing->to, saved_to, RCA_ALL);
-! while(*cc_tail) /* stay on last address */
-! cc_tail = &(*cc_tail)->next;
-
-! *cc_tail = reply_cp_addr(ps, 0, NULL, NULL, outgoing->cc,
- outgoing->to, saved_cc, RCA_ALL);
-! while(*cc_tail)
-! cc_tail = &(*cc_tail)->next;
-
-! *cc_tail = reply_cp_addr(ps, 0, NULL, NULL, outgoing->cc,
- outgoing->to, saved_resent, RCA_ALL);
-+ }
- }
- }
- else if(saved_to){
-***************
-*** 796,803 ****
- reply_quote_str(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 */
---- 815,841 ----
- reply_quote_str(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_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 */
-***************
-*** 849,858 ****
- int
- reply_quote_str_contains_tokens(void)
- {
-! 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)));
- }
-
-
---- 887,915 ----
- int
- reply_quote_str_contains_tokens(void)
- {
-! char *reply_string;
-!
-! reply_string = (char *) malloc( 80*sizeof(char));
-! { RULE_RESULT *rule;
-! rule = get_result_rule(V_REPLY_INDENT_RULES, FOR_COMPOSE, 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)));
- }
-
-
-***************
-*** 954,960 ****
- if(!orig_body
- || orig_body->type == TYPETEXT
- || reply_raw_body
-! || F_OFF(F_ATTACHMENTS_IN_REPLY, ps_global)){
- char *charset = NULL;
-
- /*------ Simple text-only message ----*/
---- 1011,1017 ----
- if(!orig_body
- || orig_body->type == TYPETEXT
- || reply_raw_body
-! || !ps_global->reply.attach){
- char *charset = NULL;
-
- /*------ Simple text-only message ----*/
-***************
-*** 962,968 ****
- body->type = TYPETEXT;
- body->contents.text.data = msgtext;
- reply_delimiter(env, role, pc);
-! if(F_ON(F_INCLUDE_HEADER, ps_global))
- reply_forward_header(stream, msgno, sect_prefix,
- env, pc, prefix);
-
---- 1019,1025 ----
- body->type = TYPETEXT;
- body->contents.text.data = msgtext;
- reply_delimiter(env, role, pc);
-! if(ps_global->reply.inchdr)
- reply_forward_header(stream, msgno, sect_prefix,
- env, pc, prefix);
-
-***************
-*** 1020,1026 ****
-
- if(reply_body_text(orig_body, &tmp_body)){
- reply_delimiter(env, role, pc);
-! if(F_ON(F_INCLUDE_HEADER, ps_global))
- reply_forward_header(stream, msgno, sect_prefix,
- env, pc, prefix);
-
---- 1077,1083 ----
-
- if(reply_body_text(orig_body, &tmp_body)){
- reply_delimiter(env, role, pc);
-! if(ps_global->reply.inchdr)
- reply_forward_header(stream, msgno, sect_prefix,
- env, pc, prefix);
-
-***************
-*** 1058,1064 ****
- body->nested.part->body.subtype = cpystr("Plain");
- }
- reply_delimiter(env, role, pc);
-! if(F_ON(F_INCLUDE_HEADER, ps_global))
- reply_forward_header(stream, msgno, sect_prefix,
- env, pc, prefix);
-
---- 1115,1121 ----
- body->nested.part->body.subtype = cpystr("Plain");
- }
- reply_delimiter(env, role, pc);
-! if(ps_global->reply.inchdr)
- reply_forward_header(stream, msgno, sect_prefix,
- env, pc, prefix);
-
-***************
-*** 1081,1087 ****
- int partnum;
-
- reply_delimiter(env, role, pc);
-! if(F_ON(F_INCLUDE_HEADER, ps_global))
- reply_forward_header(stream, msgno, sect_prefix,
- env, pc, prefix);
-
---- 1138,1144 ----
- int partnum;
-
- reply_delimiter(env, role, pc);
-! if(ps_global->reply.inchdr)
- reply_forward_header(stream, msgno, sect_prefix,
- env, pc, prefix);
-
-***************
-*** 1316,1321 ****
---- 1373,1382 ----
- buf[0] = '\0';
-
- switch(type){
-+ case iFfrom:
-+ addr = env && env->sparep ? env->sparep : NULL;
-+ break;
-+
- case iFrom:
- addr = env ? env->from : NULL;
- break;
-***************
-*** 1701,1721 ****
-
- 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 iNewLine:
- if(maxlen >= strlen(NEWLINE)){
---- 1762,1912 ----
-
- break;
-
-+ case iProcid:
-+ if(ps_global->procid){
-+ strncpy(buf, ps_global->procid, maxlen);
-+ buf[maxlen] = '\0';
-+ }
-+ break;
-+
-+ case iRole:
-+ if (ps_global->role){
-+ strncpy(buf, ps_global->role, maxlen);
-+ buf[maxlen] = '\0';
-+ }
-+ break;
-+
-+ case iRoleNick:
-+ if(role && role->nick){
-+ strncpy(buf, role->nick, maxlen);
-+ buf[maxlen] = '\0';
-+ }
-+ break;
-+
-+ case iPkey:
-+ if(ps_global->pressed_key){
-+ strcpy(buf, ps_global->pressed_key);
-+ buf[maxlen] = '\0';
-+ }
-+ break;
-+
-+ case iScreen:
-+ if(ps_global->screen_name){
-+ strncpy(buf, ps_global->screen_name, 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:
-! if(ps_global->cur_folder){
-! strncpy(buf,ps_global->cur_folder, maxlen);
-! buf[maxlen] = '\0';
-! }
-! break;
-!
-! case iCollection:
-! if(ps_global->context_current->nickname){
-! strncpy(buf,ps_global->context_current->nickname, maxlen);
-! buf[maxlen] = '\0';
-! }
-! break;
-!
-! case iFlag:
-! {MAILSTREAM *stream = find_open_stream();
-! MSGNO_S *msgmap = NULL;
-! long msgno;
-! MESSAGECACHE *mc;
-! strncpy(buf, "_FLAG_", maxlen); /* 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);
-! }
-! buf[maxlen] = '\0';
-! }
-! 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 iNewLine:
- if(maxlen >= strlen(NEWLINE)){
-***************
-*** 1744,1749 ****
---- 1935,1945 ----
-
- break;
-
-+ case iLcc: /* fake it, there are not enough spare pointers */
-+ if (env && env->date)
-+ sprintf(buf,"%s",env->date);
-+ break;
-+
- case iNews:
- case iCurNews:
- get_news_data(env, type, buf, maxlen);
-***************
-*** 1793,1798 ****
---- 1989,2002 ----
-
- break;
-
-+ case iOpeningText:
-+ case iOpeningTextNQ:
-+ if(env && env->sparep){
-+ strncpy(buf, ((SPAREP_S *)env->sparep)->value, maxlen);
-+ buf[maxlen] = '\0';
-+ }
-+ break;
-+
- case iSubject:
- if(env && env->subject){
- size_t n, len;
-***************
-*** 1851,1857 ****
- 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)){
---- 2055,2072 ----
- if(!env)
- return;
-
-! { RULE_RESULT *rule;
-! rule = get_result_rule(V_REPLY_LEADIN_RULES, 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)){
-***************
-*** 2110,2115 ****
---- 2325,2331 ----
- {
- size_t l;
- char *p, buftmp[MAILTMPLEN];
-+ RULE_RESULT *rule;
-
- if(!env)
- return(NULL);
-***************
-*** 2117,2125 ****
- dprint((9, "checking subject: \"%s\"\n",
- env->subject ? env->subject : "NULL"));
-
-! if(env->subject && env->subject[0]){ /* add (fwd)? */
-! snprintf(buftmp, sizeof(buftmp), "%s", env->subject);
-! buftmp[sizeof(buftmp)-1] = '\0';
- /* decode any 8bit (copy to the temp buffer if decoding doesn't) */
- if(rfc1522_decode_to_utf8((unsigned char *) tmp_20k_buf,
- SIZEOF_20KBUF, buftmp) == (unsigned char *) buftmp)
---- 2333,2352 ----
- dprint((9, "checking subject: \"%s\"\n",
- env->subject ? env->subject : "NULL"));
-
-! buftmp[0] = '\0';
-! ps_global->procid = cpystr("fwd-subject");
-! if (rule = get_result_rule(V_FORWARD_RULES,FOR_COMPOSE, env)){
-! sprintf(buftmp, "%.200s", rule->result);
-! if(rule->result)
-! fs_give((void **)&rule->result);
-! fs_give((void **)&rule);
-! }
-! else if(env->subject)
-! sprintf(buftmp, "%.200s", env->subject);
-! buftmp[sizeof(buftmp)-1] = '\0';
-! fs_give((void **)&ps_global->procid);
-!
-! if(buftmp[0]){ /* add (fwd)? */
- /* decode any 8bit (copy to the temp buffer if decoding doesn't) */
- if(rfc1522_decode_to_utf8((unsigned char *) tmp_20k_buf,
- SIZEOF_20KBUF, buftmp) == (unsigned char *) buftmp)
-***************
-*** 2620,2628 ****
- * tied our hands, alter the prefix to continue flowed
- * formatting...
- */
-! if(flow_res)
- wrapflags |= GFW_FLOW_RESULT;
-
- filters[filtcnt].filter = gf_wrap;
- /*
- * The 80 will cause longer lines than what is likely
---- 2847,2858 ----
- * tied our hands, alter the prefix to continue flowed
- * formatting...
- */
-! if(flow_res && !ps_global->reply.no_send_flowed)
- wrapflags |= GFW_FLOW_RESULT;
-
-+ filters[filtcnt].filter = gf_quote_test;
-+ filters[filtcnt++].data = gf_line_test_opt(select_quote, NULL);
-+
- filters[filtcnt].filter = gf_wrap;
- /*
- * The 80 will cause longer lines than what is likely
-***************
-*** 2656,2664 ****
- * 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[filtcnt].filter = gf_line_test;
---- 2886,2894 ----
- * We also want to fold "> " quotes so we get the
- * attributions correct.
- */
-! if(flow_res && !ps_global->reply.no_send_flowed && prefix && !strucmp(prefix, "> "))
- *(prefix_p = prefix + 1) = '\0';
-! ps_global->reply.no_send_flowed = 0; /* reset for next call */
- if(!(wrapflags & GFW_FLOWED)
- && flow_res){
- filters[filtcnt].filter = gf_line_test;
-***************
-*** 2691,2699 ****
- }
-
- if(prefix){
-! if(ps_global->full_header != 2
-! && (F_ON(F_ENABLE_SIGDASHES, ps_global)
-! || F_ON(F_ENABLE_STRIP_SIGDASHES, ps_global))){
- dashdata = 0;
- filters[filtcnt].filter = gf_line_test;
- filters[filtcnt++].data = gf_line_test_opt(sigdash_strip, &dashdata);
---- 2921,2927 ----
- }
-
- if(prefix){
-! if(ps_global->reply.strip){
- dashdata = 0;
- filters[filtcnt].filter = gf_line_test;
- filters[filtcnt++].data = gf_line_test_opt(sigdash_strip, &dashdata);
-***************
-*** 2718,2724 ****
- dq.do_color = 0;
- dq.delete_all = 1;
-
-! filters[filtcnt].filter = gf_line_test;
- filters[filtcnt++].data = gf_line_test_opt(delete_quotes, &dq);
- }
-
---- 2946,2952 ----
- dq.do_color = 0;
- dq.delete_all = 1;
-
-! filters[filtcnt].filter = gf_quote_test;
- filters[filtcnt++].data = gf_line_test_opt(delete_quotes, &dq);
- }
-
-diff -rc alpine-2.00/pith/rules.c alpine-2.00.I.USE/pith/rules.c
-*** alpine-2.00/pith/rules.c 2011-02-07 20:34:02.000000000 -0800
---- alpine-2.00.I.USE/pith/rules.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 0 ****
---- 1,1149 ----
-+ /* This module was written by
-+ *
-+ * Eduardo Chappa (chappa@washington.edu)
-+ * http://staff.washington.edu/chappa/pine/
-+ *
-+ * Original Version: November 1999
-+ * Last Modified : January 24, 2008
-+ *
-+ * Send bug reports about this module to the address above.
-+ */
-+
-+ #include "../pith/headers.h"
-+ #include "../pith/state.h"
-+ #include "../pith/conf.h"
-+ #include "../pith/copyaddr.h"
-+ #include "../pith/rules.h"
-+
-+ /* Internal Prototypes */
-+
-+ int test_condition (CONDITION_S *, int, ENVELOPE *);
-+ int test_in (CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int);
-+ int test_ni (CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int);
-+ int test_not_in (CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int);
-+ int test_not_ni (CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int);
-+ int test_eq (CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int);
-+ int test_not_eq (CONDITION_S *, TOKEN_VALUE *, ENVELOPE *, int);
-+ int isolate_condition (char *, char **, int *);
-+ char *test_rule (RULELIST *, int, ENVELOPE *, int *);
-+ char *trim (RULEACTION_S *, int, ENVELOPE *);
-+ char *rextrim (RULEACTION_S *, int, ENVELOPE *);
-+ char *raw_value (RULEACTION_S *, int, ENVELOPE *);
-+ char *extended_value (RULEACTION_S *, int, ENVELOPE *);
-+ char *exec_fcn (RULEACTION_S *, int, ENVELOPE *);
-+ char *expand (char *, void *);
-+ char *get_name_token (char *);
-+ char *advance_to_char (char *, char, int, int *);
-+ char **functions_for_token (char *);
-+ void free_token_value (TOKEN_VALUE **);
-+ void free_condition (CONDITION_S **);
-+ void free_ruleaction (RULEACTION_S **);
-+ void free_rule (RULE_S **);
-+ void free_rule_list (RULELIST **);
-+ void free_alloc_rule (void **, int);
-+ void *alloc_mem (size_t);
-+ void add_rule (int, int);
-+ void set_rule_list (struct variable *);
-+ void parse_patterns_into_action(TOKEN_VALUE **);
-+ void free_parsed_value(TOKEN_VALUE **value);
-+ RULE_S *parse_rule (char *, int);
-+ RULELIST *get_rule_list (char **, int, int);
-+ TOKEN_VALUE *parse_group_data (char *,int *);
-+ TOKEN_VALUE *copy_parsed_value (TOKEN_VALUE *, int, ENVELOPE *);
-+ CONDITION_S *fill_condition (char *);
-+ CONDITION_S *parse_condition (char *, int *);
-+ PRULELIST_S *add_prule (PRULELIST_S *, PRULELIST_S *);
-+ RULEACTION_S *parse_action (char *, int);
-+
-+ 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)
-+
-+ RULE_FCN rule_fcns[] = {
-+ {COPY_FCN, extended_value, FOR_SAVE|FOR_COMPOSE},
-+ {SAVE_FCN, extended_value, FOR_SAVE},
-+ {EXEC_FCN, exec_fcn, FOR_REPLACE|FOR_TRIM|FOR_RESUB|FOR_COMPOSE},
-+ {REPLY_FCN, extended_value, FOR_REPLY_INTRO},
-+ {TRIM_FCN, trim, FOR_TRIM|FOR_RESUB|FOR_COMPOSE},
-+ {REPLACE_FCN, extended_value, FOR_REPLACE},
-+ {SORT_FCN, raw_value, FOR_SORT},
-+ {INDEX_FCN, raw_value, FOR_INDEX},
-+ {COMMAND_FCN, raw_value, FOR_KEY},
-+ {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|FOR_COMPOSE},
-+ {THRDSTYLE_FCN, raw_value, FOR_THREAD},
-+ {THRDINDEX_FCN, raw_value, FOR_THREAD},
-+ {SMTP_FCN, raw_value, FOR_COMPOSE},
-+ {NULL, 0, FOR_NOTHING}
-+ };
-+
-+ char* token_rules[] = {
-+ FROM_TOKEN,
-+ NICK_TOKEN,
-+ OTEXT_TOKEN,
-+ OTEXTNQ_TOKEN,
-+ ROLE_TOKEN,
-+ FOLDER_TOKEN,
-+ SUBJ_TOKEN,
-+ PROCID_TOKEN,
-+ THDDSPSTY_TOKEN,
-+ THDNDXSTY_TOKEN,
-+ FLAG_TOKEN,
-+ COLLECT_TOKEN,
-+ THDDSPSTY_TOKEN,
-+ ADDR_TOKEN,
-+ TO_TOKEN,
-+ ADDTO_TOKEN,
-+ ADDCC_TOKEN,
-+ ADDRECIP_TOKEN,
-+ SCREEN_TOKEN,
-+ KEY_TOKEN,
-+ SEND_TOKEN,
-+ CC_TOKEN,
-+ LCC_TOKEN,
-+ BCC_TOKEN,
-+ FFROM_TOKEN,
-+ FADDRESS_TOKEN,
-+ NULL
-+ };
-+
-+ #define NTOKENS (sizeof(token_rules)/sizeof(token_rules[0]) - 1)
-+ #define NFCN (sizeof(rule_fcns)/sizeof(rule_fcns[0]) - 1)
-+
-+ char *subj_fcn[] = {SUBJ_TOKEN, REPLACE_FCN, TRIM_FCN, REXTRIM_FCN, EXEC_FCN};
-+ char *from_fcn[] = {FROM_TOKEN, REPLACE_FCN, TRIM_FCN, REXTRIM_FCN, EXEC_FCN};
-+ char *otext_fcn[] = {OTEXT_TOKEN, REPLACE_FCN, TRIM_FCN, REXTRIM_FCN, EXEC_FCN};
-+ char *otextnq_fcn[] = {OTEXTNQ_TOKEN, REPLACE_FCN, TRIM_FCN, REXTRIM_FCN, EXEC_FCN};
-+
-+ char *adto_fcn[] = {ADDTO_TOKEN, EXEC_FCN, NULL, NULL, NULL};
-+
-+ char **fcns_for_index[] = {subj_fcn, from_fcn, otext_fcn, otextnq_fcn};
-+
-+ #define NFCNFI (sizeof(fcns_for_index)/sizeof(fcns_for_index[0])) /*for idx*/
-+ #define NFPT (sizeof(fcns_for_index[0])) /* functions pert token */
-+
-+ SPAREP_S *
-+ get_sparep_for_rule(char *value, int flag)
-+ {
-+ SPAREP_S *rv;
-+ rv = (SPAREP_S *) alloc_mem(sizeof(SPAREP_S));
-+ rv->flag = flag;
-+ rv->value = value ? cpystr(value) : NULL;
-+ return rv;
-+ }
-+
-+ void free_sparep_for_rule(void **sparep)
-+ {
-+ SPAREP_S *spare = (SPAREP_S *) *sparep;
-+ if(!spare) return;
-+ if(spare->value)
-+ fs_give((void **)&spare->value);
-+ fs_give((void **)sparep);
-+ }
-+
-+
-+ int context_for_function(char *name)
-+ {
-+ int i, j;
-+ for (i = 0; i < NFCN && strcmp(rule_fcns[i].name, name); i++);
-+ return i == NFCN ? 0 : rule_fcns[i].what_for;
-+
-+ }
-+
-+ char **functions_for_token(char *name)
-+ {
-+ int i;
-+ for (i = 0; i < NFCNFI && strcmp(fcns_for_index[i][0], name); i++);
-+ return i == NFCNFI ? NULL : fcns_for_index[i];
-+ }
-+
-+ void
-+ free_alloc_rule (void **voidtext, int code)
-+ {
-+ switch(code){
-+ case FREEREGEX : regfree((regex_t *)*voidtext);
-+ break;
-+ default: break;
-+ }
-+ }
-+
-+
-+
-+ void free_token_value(TOKEN_VALUE **token)
-+ {
-+ if(token && *token){
-+ if ((*token)->testxt)
-+ fs_give((void **)&(*token)->testxt);
-+ free_alloc_rule (&(*token)->voidtxt, (*token)->codefcn);
-+ if((*token)->next)
-+ free_token_value(&(*token)->next);
-+ fs_give((void **)token);
-+ }
-+ }
-+
-+ void free_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(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)
-+ free_token_value(&(*raction)->value);
-+ fs_give((void **)raction);
-+ }
-+ }
-+
-+ void free_rule(RULE_S **rule)
-+ {
-+ if(rule && *rule){
-+ free_condition(&((*rule)->condition));
-+ free_ruleaction(&((*rule)->action));
-+ fs_give((void **)rule);
-+ }
-+ }
-+
-+ void free_rule_list(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(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 (size_t amount)
-+ {
-+ void *genmem;
-+ memset(genmem = fs_get(amount), 0, amount);
-+ return genmem;
-+ }
-+
-+
-+ void
-+ parse_patterns_into_action(TOKEN_VALUE **tokenp)
-+ {
-+ if(!*tokenp)
-+ return;
-+
-+ if((*tokenp)->testxt){
-+ regex_t preg;
-+
-+ (*tokenp)->voidtxt = NULL;
-+ (*tokenp)->voidtxt = fs_get(sizeof(regex_t));
-+ if (regcomp((regex_t *)(*tokenp)->voidtxt,
-+ (*tokenp)->testxt, REG_EXTENDED) != 0){
-+ regfree((regex_t *)(*tokenp)->voidtxt);
-+ (*tokenp)->voidtxt = NULL;
-+ }
-+ }
-+ if((*tokenp)->voidtxt)
-+ (*tokenp)->codefcn = FREEREGEX;
-+ if((*tokenp)->next)
-+ parse_patterns_into_action(&(*tokenp)->next);
-+ }
-+
-+
-+ int
-+ isolate_condition (char *data, char **cvalue, int *len)
-+ {
-+ char *p = data;
-+ int done = 0, error = 0, next_condition = 0, l;
-+
-+ if(*p == '"' && p[strlen(p) - 1] == '"'){
-+ p[strlen(p) - 1] = '\0';
-+ p++;
-+ }
-+ *cvalue = NULL;
-+ while (*p && !done){
-+ switch (*p){
-+ case '_': *cvalue = advance_to_char(p,'}', STRICTLY, 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 (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,';', STRICTLY, &offset)){
-+ rvalue->testxt = cpystr(p);
-+ data += strlen(p) + 1 + offset;
-+ rvalue->next = parse_group_data(data, error);
-+ }
-+ else if (p = advance_to_char(data,'}', STRICTLY, NULL))
-+ rvalue->testxt = cpystr(p);
-+ else if (data && *data == '}')
-+ rvalue->testxt = cpystr("");
-+ else{
-+ err++;
-+ free_token_value(&rvalue);
-+ }
-+ if (error)
-+ *error += err;
-+ return(rvalue);
-+ }
-+
-+ CONDITION_S *
-+ fill_condition(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,'}', STRICTLY, &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;
-+ }
-+
-+ /* eoc = end of condition, equal to -1 on error */
-+ CONDITION_S *
-+ parse_condition (char *data, int *eoc)
-+ {
-+ 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 (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));
-+ /* We assign raction->token to be subject. This is not necessary for
-+ most rules. It is done only for rules that need it and will not
-+ make any difference in rules that do not need it. It will hopefully
-+ reduce complexity in the language
-+ */
-+ raction->token = cpystr(SUBJ_TOKEN);
-+ 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,'}', STRICTLY, NULL);
-+ if(!raction->value->testxt)
-+ free_ruleaction(&raction);
-+ return raction;
-+ }
-+
-+ done = (((function = strstr(p, "_TRIM_")) != NULL)
-+ ? 1 : ((function = strstr(p, "_COPY_")) != NULL)
-+ ? 2 : ((function = strstr(p, "_EXEC_")) != NULL)
-+ ? 3 : ((function = strstr(p, "_REXTRIM_")) != NULL)
-+ ? 4 : ((function = strstr(p, "_REPLACE_")) != NULL)
-+ ? 5 : 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 <= 3 ? 6 : 9; /* 6 = strlen("_EXEC_"), 9 = strlen("_REPLACE_") */
-+ 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++ = '{';
-+ if((raction->value = parse_group_data(p, NULL)) == NULL
-+ || raction->value->testxt == NULL)
-+ free_ruleaction(&raction);
-+ if(raction && raction->is_rextrim)
-+ parse_patterns_into_action(&raction->value);
-+ return raction;
-+ }
-+
-+ RULE_S *
-+ parse_rule (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(char **list, int context, int 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(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(int code, int 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);
-+ }
-+ }
-+
-+ /* see create_rule_list below */
-+ void
-+ set_rule_list(struct variable *vars)
-+ {
-+ set_current_val(&vars[V_THREAD_DISP_STYLE_RULES], TRUE, TRUE);
-+ set_current_val(&vars[V_THREAD_INDEX_STYLE_RULES], 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_KEY_RULES], FALSE, 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);
-+ }
-+
-+ /* see set_rule_list above */
-+ void
-+ create_rule_list(struct variable *vars)
-+ {
-+ set_rule_list(vars);
-+ add_rule(V_THREAD_DISP_STYLE_RULES, FOR_THREAD);
-+ add_rule(V_THREAD_INDEX_STYLE_RULES, FOR_THREAD);
-+ add_rule(V_COMPOSE_RULES, FOR_COMPOSE);
-+ add_rule(V_FORWARD_RULES, FOR_COMPOSE);
-+ add_rule(V_INDEX_RULES, FOR_INDEX);
-+ add_rule(V_KEY_RULES, FOR_KEY);
-+ add_rule(V_REPLACE_RULES, FOR_REPLACE);
-+ add_rule(V_REPLY_INDENT_RULES, FOR_COMPOSE);
-+ add_rule(V_REPLY_LEADIN_RULES, FOR_REPLY_INTRO);
-+ add_rule(V_RESUB_RULES, FOR_RESUB|FOR_TRIM);
-+ add_rule(V_SAVE_RULES, FOR_SAVE);
-+ add_rule(V_SMTP_RULES, FOR_COMPOSE);
-+ add_rule(V_SORT_RULES, FOR_SORT);
-+ add_rule(V_STARTUP_RULES, FOR_STARTUP);
-+ }
-+
-+ int
-+ condition_contains_token(CONDITION_S *condition, char *token)
-+ {
-+ return condition ? (!strcmp(condition->tname, token)
-+ ? 1
-+ : condition_contains_token(condition->next, token))
-+ : 0;
-+ }
-+
-+ RULELIST *
-+ get_rulelist_from_code(int code, PRULELIST_S *list)
-+ {
-+ return list ? (list->varnum == code ? list->rlist
-+ : get_rulelist_from_code(code, list->next))
-+ : (RULELIST *) NULL;
-+ }
-+
-+ char *
-+ test_rule(RULELIST *rlist, int ctxt, ENVELOPE *env, int *n)
-+ {
-+ 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 (RULELIST *rule, int n)
-+ {
-+ return rule ? (n ? get_rule(rule->next, n-1) : rule->prule)
-+ : (RULE_S *) NULL;
-+ }
-+
-+ /* 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(int code, int rule_context, ENVELOPE *env)
-+ {
-+ char *rule_result;
-+ RULE_RESULT *rule = NULL;
-+ RULELIST *rlist;
-+ int n = 0;
-+
-+ if(!(rule_context & FOR_RULE))
-+ rule_context |= FOR_RULE;
-+ 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;
-+ }
-+
-+ char *get_rule_result(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 = 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;
-+ }
-+
-+ /* 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 (RULE_S *prule, int rule_context, ENVELOPE *env)
-+ {
-+ char *result = NULL;
-+ int rv;
-+ CONDITION_S *condition;
-+
-+ if(!prule)
-+ return NULL;
-+
-+ if(!(rule_context & FOR_RULE))
-+ rule_context |= FOR_RULE;
-+
-+ 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(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);
-+ tval->voidtxt = value->voidtxt;
-+ tval->codefcn = value->codefcn;
-+ }
-+ if(value->next)
-+ tval->next = copy_parsed_value(value->next, ctxt, env);
-+
-+ return tval;
-+ }
-+
-+ void
-+ free_parsed_value(TOKEN_VALUE **value)
-+ {
-+ TOKEN_VALUE *tval = NULL;
-+
-+ if(!*value)
-+ return;
-+
-+ if((*value)->testxt)
-+ fs_give((void **)&(*value)->testxt);
-+
-+ if((*value)->next)
-+ free_parsed_value(&(*value)->next);
-+
-+ fs_give((void **)value);
-+ }
-+
-+
-+ int
-+ test_condition(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_parsed_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 (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_S *condition, TOKEN_VALUE *group, ENVELOPE *env,
-+ int context)
-+ {
-+ int rv = 0;
-+ char *test;
-+ TOKEN_VALUE *test_group = group;
-+
-+ test = env && env->sparep && ((SPAREP_S *)env->sparep)->flag & USE_RAW_SP
-+ ? cpystr(((SPAREP_S *)env->sparep)->value)
-+ : 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;
-+ }
-+ fs_give((void **)&test);
-+ }
-+ return rv;
-+ }
-+
-+ int test_ni (CONDITION_S *condition, TOKEN_VALUE *group,
-+ ENVELOPE *env, int context)
-+ {
-+ int rv = 0;
-+ char *test;
-+ TOKEN_VALUE *test_group = group;
-+
-+ test = env && env->sparep && ((SPAREP_S *)env->sparep)->flag & USE_RAW_SP
-+ ? cpystr(((SPAREP_S *)env->sparep)->value)
-+ : 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;
-+ }
-+ fs_give((void **)&test);
-+ }
-+ return rv;
-+ }
-+
-+ int test_not_in (CONDITION_S *condition, TOKEN_VALUE *group,
-+ ENVELOPE *env, int context)
-+ {
-+ return !test_in(condition, group, env, context);
-+ }
-+
-+ int test_not_ni (CONDITION_S *condition, TOKEN_VALUE *group,
-+ ENVELOPE *env, int context)
-+ {
-+ return !test_ni(condition, group, env, context);
-+ }
-+
-+ int test_eq (CONDITION_S *condition, TOKEN_VALUE *group,
-+ ENVELOPE *env, int context)
-+ {
-+ int rv = 0;
-+ char *test;
-+ TOKEN_VALUE *test_group = group;
-+
-+ test = env && env->sparep && ((SPAREP_S *)env->sparep)->flag & USE_RAW_SP
-+ ? cpystr(((SPAREP_S *)env->sparep)->value)
-+ :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;
-+ }
-+ fs_give((void **)&test);
-+ }
-+ return rv;
-+ }
-+
-+ int test_not_eq (CONDITION_S *condition, TOKEN_VALUE *group,
-+ ENVELOPE *env, int context)
-+ {
-+ return !test_eq(condition, group, env, context);
-+ }
-+
-+ char *
-+ do_trim (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 (RULEACTION_S *action, int context, ENVELOPE *env)
-+ {
-+ char *begin_text, *test;
-+ RULEACTION_S *taction = action;
-+ int offset;
-+
-+ if (taction->context & context){
-+ if (test = detoken_src(taction->token, context, env, NULL, NULL, NULL))
-+ test = do_trim(test, taction->value);
-+ return test;
-+ }
-+ return NULL;
-+ }
-+
-+
-+ char *
-+ do_rextrim (char *test, TOKEN_VALUE *tval)
-+ {
-+ char *begin_text, *trim_text;
-+ int offset = 0;
-+
-+ if (!tval)
-+ return test;
-+
-+ trim_text = expand(test, tval->voidtxt);
-+ 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 (RULEACTION_S *action, int context, ENVELOPE *env)
-+ {
-+ char *test = NULL;
-+ RULEACTION_S *taction = action;
-+
-+ if (taction->context & context &&
-+ (test = detoken_src(taction->token, context, env, NULL, NULL, NULL)))
-+ test = do_rextrim(test, taction->value);
-+ return test;
-+ }
-+
-+ char *
-+ raw_value (RULEACTION_S *action, int context, ENVELOPE *env)
-+ {
-+ return (action->context & context) ? cpystr(action->value->testxt) : NULL;
-+ }
-+
-+ char *
-+ extended_value (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(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 & STRICTLY ? 0 : 1;
-+ err++;
-+ break;
-+ }
-+ b[i++] = '\\';
-+ }
-+ if(c == given_char){
-+ err += flag & STRICTLY ? 0 : 1;
-+ break;
-+ }
-+ b[i++] = c;
-+ }
-+ b[i] = '\0';
-+ if (b && (strlen(b) == strlen(given_string)) && (flag & STRICTLY))
-+ 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 (char *string, void *pattern)
-+ {
-+ char c, *ret_string = NULL;
-+ regmatch_t pmatch;
-+
-+ if((regex_t *)pattern == NULL)
-+ return NULL;
-+
-+ if(regexec((regex_t *)pattern, string , 1, &pmatch, 0) == 0
-+ && pmatch.rm_so < pmatch.rm_eo){
-+ 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;
-+ }
-+
-+
-+ char *
-+ exec_fcn (RULEACTION_S *action, int ctxt, ENVELOPE *env)
-+ {
-+ STORE_S *output_so;
-+ gf_io_t gc, pc;
-+ char *status, *rv, *cmd, *test;
-+
-+ if(!(action->context & ctxt))
-+ return NULL;
-+
-+ if((test = detoken_src(action->token, ctxt, env, NULL, NULL, NULL)) != NULL)
-+ gf_set_readc(&gc, test, (unsigned long)strlen(test), CharStar, 0);
-+
-+ if((output_so = so_get(CharStar, NULL, EDIT_ACCESS)) != NULL)
-+ gf_set_so_writec(&pc, output_so);
-+
-+ cmd = (char *)fs_get((strlen(action->value->testxt) + strlen("_TMPFILE_") + 2)*sizeof(char));
-+ sprintf(cmd,"%s _TMPFILE_", action->value->testxt);
-+ status = (*ps_global->tools.exec_rule)(cmd, gc, pc);
-+
-+ so_seek(output_so, 0L, 0);
-+ rv = cpystr(output_so->dp);
-+ gf_clear_so_writec(output_so);
-+ so_give(&output_so);
-+ if(test)
-+ fs_give((void **)&test);
-+
-+ return status ? NULL : rv;
-+ }
-+
-+ ENVELOPE *
-+ rules_fetchenvelope(INDEXDATA_S *idata, int *we_clear)
-+ {
-+ ENVELOPE *env;
-+
-+ if (idata->no_fetch){
-+ if(we_clear)
-+ *we_clear = 1;
-+ env = mail_newenvelope();
-+ env->from = copyaddrlist(idata->from);
-+ env->to = copyaddrlist(idata->to);
-+ env->cc = copyaddrlist(idata->cc);
-+ env->sender = copyaddrlist(idata->sender);
-+ env->subject = cpystr(idata->subject);
-+ env->date = cpystr((unsigned char *) idata->date);
-+ env->newsgroups = cpystr(idata->newsgroups);
-+ return env;
-+ }
-+ if(we_clear)
-+ *we_clear = 0;
-+ env = pine_mail_fetchenvelope(idata->stream, idata->rawno);
-+ return env;
-+ }
-diff -rc alpine-2.00/pith/rules.h alpine-2.00.I.USE/pith/rules.h
-*** alpine-2.00/pith/rules.h 2011-02-07 20:34:02.000000000 -0800
---- alpine-2.00.I.USE/pith/rules.h 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 0 ****
---- 1,151 ----
-+ /* Included file rules.h */
-+
-+ #ifndef PITH_RULES_INCLUDED
-+ #define PITH_RULES_INCLUDED
-+
-+ #include "../pith/conftype.h"
-+ #include "../pith/detoken.h"
-+ #include "../pith/indxtype.h"
-+ #include "../pith/rulestype.h"
-+
-+ int is_save; /* this rule has the form condition -> folder */
-+
-+ /* Exported prototypes */
-+
-+ void create_rule_list (struct variable *);
-+ SPAREP_S *get_sparep_for_rule(char *, int);
-+ void free_sparep_for_rule(void **);
-+ void free_parsed_rule_list (PRULELIST_S **);
-+ RULE_RESULT *get_result_rule (int, int, ENVELOPE *);
-+ char *get_rule_result (int , char *, int);
-+ char *process_rule (RULE_S *, int, ENVELOPE *);
-+ char **functions_for_token (char *);
-+ RULELIST *get_rulelist_from_code (int, PRULELIST_S *);
-+ RULE_S *get_rule (RULELIST *, int);
-+ int condition_contains_token (CONDITION_S *, char *);
-+ int context_for_function (char *);
-+ ENVELOPE *rules_fetchenvelope(INDEXDATA_S *idata, int *we_clear);
-+
-+ /* 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 KEY_TOKEN "_PKEY_"
-+ #define LCC_TOKEN "_LCC_"
-+ #define NICK_TOKEN "_NICK_"
-+ #define OTEXT_TOKEN "_OPENINGTEXT_"
-+ #define OTEXTNQ_TOKEN "_OPENINGTEXTNQ_"
-+ #define PROCID_TOKEN "_PROCID_"
-+ #define ROLE_TOKEN "_ROLE_"
-+ #define SCREEN_TOKEN "_SCREEN_"
-+ #define SEND_TOKEN "_SENDER_"
-+ #define SUBJ_TOKEN "_SUBJECT_"
-+ #define THDDSPSTY_TOKEN "_THREADSTYLE_"
-+ #define THDNDXSTY_TOKEN "_THREADINDEX_"
-+ #define TO_TOKEN "_TO_"
-+
-+ /*------ 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*/
-+
-+ /*--- 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},
-+ {OTEXT_TOKEN, FOR_SAVE|FOR_FOLDER},
-+ {OTEXTNQ_TOKEN, FOR_SAVE|FOR_FOLDER},
-+ {ROLE_TOKEN, FOR_COMPOSE},
-+ {FOLDER_TOKEN, FOR_SAVE|FOR_FOLDER|FOR_THREAD|FOR_COMPOSE},
-+ {SUBJ_TOKEN, FOR_SAVE|FOR_FOLDER|FOR_COMPOSE},
-+ {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},
-+ {SCREEN_TOKEN, FOR_KEY},
-+ {KEY_TOKEN, FOR_KEY},
-+ {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 COMMAND_FCN "_COMMAND_"
-+ #define COPY_FCN "_COPY_"
-+ #define EXEC_FCN "_EXEC_"
-+ #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_"
-+
-+ #define STRICTLY 0x1
-+ #define RELAXED 0x2
-+
-+ #endif /* PITH_RULES_INCLUDED */
-diff -rc alpine-2.00/pith/rulestype.h alpine-2.00.I.USE/pith/rulestype.h
-*** alpine-2.00/pith/rulestype.h 2011-02-07 20:34:02.000000000 -0800
---- alpine-2.00.I.USE/pith/rulestype.h 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 0 ****
---- 1,78 ----
-+ #ifndef PITH_RULESTYPE_INCLUDED
-+ #define PITH_RULESTYPE_INCLUDED
-+
-+ typedef struct rule {
-+ char *result; /* The result of the rule */
-+ int number; /* The number of the rule that succeded, -1 if not */
-+ } RULE_RESULT;
-+
-+ typedef struct {
-+ char *value;
-+ int type;
-+ } RULE_ACTION;
-+
-+
-+ #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
-+
-+ #define FREEREGEX 1
-+
-+ TOKEN_VALUE {
-+ char *testxt;
-+ void *voidtxt;
-+ int codefcn;
-+ 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;
-+ };
-+
-+ #define USE_RAW_SP 0x001
-+ #define PROCESS_SP 0x010
-+
-+ typedef struct sparep {
-+ int flag;
-+ char *value;
-+ } SPAREP_S;
-+
-+
-+ #endif /* PITH_RULESTYPE_INCLUDED */
-diff -rc alpine-2.00/pith/save.c alpine-2.00.I.USE/pith/save.c
-*** alpine-2.00/pith/save.c 2008-05-02 14:58:34.000000000 -0700
---- alpine-2.00.I.USE/pith/save.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 421,426 ****
---- 421,427 ----
- {
- int rv, rc, j, our_stream = 0, cancelled = 0;
- int delete, filter, k, worry_about_keywords = 0;
-+ int flags_for_save = F_ANS|F_FWD|F_FLAG|F_SEEN|F_KEYWORD;
- char *save_folder, *seq, *flags = NULL, date[64], tmp[MAILTMPLEN];
- long i, nmsgs, rawno;
- size_t len;
-***************
-*** 864,870 ****
- STRING msg;
-
- pkg.stream = stream;
-! pkg.flags = NULL;
- pkg.date = date;
- pkg.msg = &msg;
- pkg.msgmap = msgmap;
---- 865,871 ----
- STRING msg;
-
- pkg.stream = stream;
-! pkg.flags = flgs & SV_FIX_DELS ? NULL : cpystr("\\DELETED");
- pkg.date = date;
- pkg.msg = &msg;
- pkg.msgmap = msgmap;
-***************
-*** 938,944 ****
- mc = (rawno > 0L && stream && rawno <= stream->nmsgs)
- ? mail_elt(stream, rawno) : NULL;
-
-! flags = flag_string(stream, rawno, F_ANS|F_FWD|F_FLAG|F_SEEN|F_KEYWORD);
-
- if(mc && mc->day)
- mail_date(date, mc);
---- 939,946 ----
- mc = (rawno > 0L && stream && rawno <= stream->nmsgs)
- ? mail_elt(stream, rawno) : NULL;
-
-! flags_for_save |= flgs & SV_FIX_DELS ? 0 : F_DEL;
-! flags = flag_string(stream, rawno, flags_for_save);
-
- if(mc && mc->day)
- mail_date(date, mc);
-***************
-*** 946,952 ****
- *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(flags)
---- 948,954 ----
- *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(flags)
-***************
-*** 1043,1048 ****
---- 1045,1051 ----
- MESSAGECACHE *mc;
- char *fetch;
- int rc;
-+ int flags_for_save = F_ANS|F_FWD|F_FLAG|F_SEEN|F_KEYWORD;
- unsigned long raw, hlen, tlen, mlen;
-
- if(pkg->so && (pkg->msgno > 0L)) {
-***************
-*** 1051,1060 ****
- ? mail_elt(pkg->stream, raw) : NULL;
- if(mc){
- size = mc->rfc822_size;
-! if(pkg->flags)
- fs_give((void **) &pkg->flags);
-!
-! pkg->flags = flag_string(pkg->stream, raw, F_ANS|F_FWD|F_FLAG|F_SEEN|F_KEYWORD);
- }
-
- if(mc && mc->day)
---- 1054,1065 ----
- ? mail_elt(pkg->stream, raw) : NULL;
- if(mc){
- size = mc->rfc822_size;
-! if(pkg->flags){
-! if(strstr(pkg->flags,"\\DELETED"))
-! flags_for_save |= F_DEL;
- fs_give((void **) &pkg->flags);
-! }
-! pkg->flags = flag_string(pkg->stream, raw, flags_for_save);
- }
-
- if(mc && mc->day)
-***************
-*** 1136,1141 ****
---- 1141,1147 ----
- snprintf(buf, sizeof(buf),
- "Message to save shrank: source msg # %ld may be saved incorrectly",
- mn_raw2m(pkg->msgmap, raw));
-+ if(F_OFF(F_IGNORE_SIZE, ps_global))
- q_status_message(SM_ORDER, 0, 3, buf);
- }
- else{
-diff -rc alpine-2.00/pith/send.c alpine-2.00.I.USE/pith/send.c
-*** alpine-2.00/pith/send.c 2008-08-06 11:25:58.000000000 -0700
---- alpine-2.00.I.USE/pith/send.c 2011-02-07 20:33:43.000000000 -0800
-***************
-*** 43,48 ****
---- 43,49 ----
- #include "../pith/ablookup.h"
- #include "../pith/sort.h"
- #include "../pith/smime.h"
-+ #include "../pith/rules.h"
-
- #include "../c-client/smtp.h"
- #include "../c-client/nntp.h"
-***************
-*** 52,58 ****
- /* name::type::canedit::writehdr::localcopy::rcptto */
- PINEFIELD pf_template[] = {
- {"X-Auth-Received", FreeText, 0, 1, 1, 0}, /* N_AUTHRCVD */
-! {"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},
---- 53,59 ----
- /* name::type::canedit::writehdr::localcopy::rcptto */
- PINEFIELD pf_template[] = {
- {"X-Auth-Received", FreeText, 0, 1, 1, 0}, /* N_AUTHRCVD */
-! {"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},
-***************
-*** 256,261 ****
---- 257,269 ----
-
- if(exists & FEX_ISFILE){
- context_apply(tmp, p_cntxt, mbox, sizeof(tmp));
-+ #ifndef _WINDOWS
-+ if (!struncmp(tmp, "#md/",4) || !struncmp(tmp, "#mc/", 4)){
-+ char tmp2[MAILTMPLEN];
-+ maildir_file_path(tmp, tmp2);
-+ strcpy(tmp, tmp2);
-+ }
-+ #endif
- if(!(IS_REMOTE(tmp) || is_absolute_path(tmp))){
- /*
- * The mbox is relative to the home directory.
-***************
-*** 1228,1234 ****
- *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;
---- 1236,1242 ----
- *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;
-***************
-*** 1737,1745 ****
- 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;
- BODY *origBody = body;
---- 1745,1753 ----
- 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;
- BODY *origBody = body;
-***************
-*** 1892,1911 ****
- * OK, who posts what? We tried an mta_handoff above, but there
- * 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, "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, "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, sizeof(ps_global->c_client_error))) != NULL){
- char *cmdlist[2];
---- 1900,1948 ----
- * OK, who posts what? We tried an mta_handoff above, but there
- * 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, j;
-!
-! added_rules = 0;
-! smtp_list = (char **) fs_get ((num_rules + 1)*sizeof(char*));
-! for (i = 0, j = 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_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, "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, sizeof(ps_global->c_client_error))) != NULL){
- char *cmdlist[2];
-***************
-*** 2141,2146 ****
---- 2178,2185 ----
- if(error_mess){
- q_status_message(SM_ORDER | SM_DING, 4, 7, error_mess);
- dprint((1, "call_mailer ERROR: %s\n", error_mess));
-+ if (ps_global->send_immediately)
-+ printf("%s\n",error_mess);
- }
-
- return(-1);
-diff -rc alpine-2.00/pith/send.h alpine-2.00.I.USE/pith/send.h
-*** alpine-2.00/pith/send.h 2008-06-30 15:03:35.000000000 -0700
---- alpine-2.00.I.USE/pith/send.h 2011-02-07 20:33:43.000000000 -0800
-***************
-*** 158,163 ****
---- 158,165 ----
- unsigned text_written:1;
- };
-
-+ #define CAN_EDIT(x) (!((x)->never_allow_changing_from) && \
-+ F_ON(F_ALLOW_CHANGING_FROM, (x)))
-
- #define TONAME "To"
- #define CCNAME "cc"
-diff -rc alpine-2.00/pith/sort.c alpine-2.00.I.USE/pith/sort.c
-*** alpine-2.00/pith/sort.c 2008-07-09 22:01:13.000000000 -0700
---- alpine-2.00.I.USE/pith/sort.c 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 29,35 ****
- #include "../pith/signal.h"
- #include "../pith/busy.h"
- #include "../pith/icache.h"
-!
-
- /*
- * global place to store mail_sort and mail_thread results
---- 29,35 ----
- #include "../pith/signal.h"
- #include "../pith/busy.h"
- #include "../pith/icache.h"
-! #include "../pith/rules.h"
-
- /*
- * global place to store mail_sort and mail_thread results
-***************
-*** 90,96 ****
- ----*/
- void
- sort_folder(MAILSTREAM *stream, MSGNO_S *msgmap, SortOrder new_sort,
-! int new_rev, unsigned int flags)
- {
- long raw_current, i, j;
- unsigned long *sort = NULL;
---- 90,96 ----
- ----*/
- void
- sort_folder(MAILSTREAM *stream, MSGNO_S *msgmap, SortOrder new_sort,
-! int new_rev, unsigned int flags, int first)
- {
- long raw_current, i, j;
- unsigned long *sort = NULL;
-***************
-*** 100,105 ****
---- 100,114 ----
- 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, "Sorting by %s%s\n",
- sort_name(new_sort), new_rev ? "/reverse" : ""));
-
-***************
-*** 529,548 ****
- * argument also means arrival/reverse.
- */
- int
-! decode_sort(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);
- }
---- 538,557 ----
- * argument also means arrival/reverse.
- */
- int
-! decode_sort(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);
- }
-***************
-*** 571,577 ****
- if(ps_global->sort_types[x] == EndofList)
- return(-1);
-
-! *def_sort = ps_global->sort_types[x];
- *def_sort_rev = reverse;
- return(0);
- }
---- 580,586 ----
- if(ps_global->sort_types[x] == EndofList)
- return(-1);
-
-! *def_sort = ps_global->sort_types[x];
- *def_sort_rev = reverse;
- return(0);
- }
-***************
-*** 685,694 ****
- 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)){
---- 694,719 ----
- 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_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)){
-***************
-*** 701,709 ****
- && 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);
- }
---- 726,776 ----
- && pat->action->sort_is_set){
- the_sort_order = pat->action->sortorder;
- sort_is_rev = pat->action->revsort;
-+ sort_is_rev = the_sort_order == SortThread
-+ ? (ps_global->thread_def_sort_rev + pat->action->revsort) % 2
-+ : pat->action->revsort;
- }
- }
-+ }
-+ if(the_sort_order == SortThread && !(flags & SRT_MAN))
-+ 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);
-! }
-!
-! SortOrder translate(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;
- }
-diff -rc alpine-2.00/pith/sort.h alpine-2.00.I.USE/pith/sort.h
-*** alpine-2.00/pith/sort.h 2006-09-22 13:06:05.000000000 -0700
---- alpine-2.00.I.USE/pith/sort.h 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 22,28 ****
-
-
- #define refresh_sort(S,M,F) sort_folder((S), (M), mn_get_sort(M), \
-! mn_get_revsort(M), (F))
-
- struct global_sort_data {
- MSGNO_S *msgmap;
---- 22,28 ----
-
-
- #define refresh_sort(S,M,F) sort_folder((S), (M), mn_get_sort(M), \
-! mn_get_revsort(M), (F), 1)
-
- struct global_sort_data {
- MSGNO_S *msgmap;
-***************
-*** 41,49 ****
-
- /* exported protoypes */
- char *sort_name(SortOrder);
-! void sort_folder(MAILSTREAM *, MSGNO_S *, SortOrder, int, unsigned);
-! int decode_sort(char *, SortOrder *, int *);
- void reset_sort_order(unsigned);
-!
-
- #endif /* PITH_SORT_INCLUDED */
---- 41,49 ----
-
- /* exported protoypes */
- char *sort_name(SortOrder);
-! void sort_folder(MAILSTREAM *, MSGNO_S *, SortOrder, int, unsigned, int);
-! int decode_sort(char *, SortOrder *, int *, int);
- void reset_sort_order(unsigned);
-! SortOrder translate(char *, int);
-
- #endif /* PITH_SORT_INCLUDED */
-diff -rc alpine-2.00/pith/state.c alpine-2.00.I.USE/pith/state.c
-*** alpine-2.00/pith/state.c 2008-06-03 15:31:05.000000000 -0700
---- alpine-2.00.I.USE/pith/state.c 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 32,38 ****
- #include "../pith/remote.h"
- #include "../pith/list.h"
- #include "../pith/smime.h"
-!
-
- /*
- * Globals referenced throughout pine...
---- 32,38 ----
- #include "../pith/remote.h"
- #include "../pith/list.h"
- #include "../pith/smime.h"
-! #include "../pith/rules.h"
-
- /*
- * Globals referenced throughout pine...
-***************
-*** 73,78 ****
---- 73,79 ----
-
- p = (struct pine *)fs_get(sizeof (struct pine));
- memset((void *) p, 0, sizeof(struct pine));
-+ p->thread_def_sort = SortDate;
- p->def_sort = SortArrival;
- p->sort_types[0] = SortSubject;
- p->sort_types[1] = SortArrival;
-***************
-*** 115,120 ****
---- 116,124 ----
- if(!(pps && (*pps)))
- return;
-
-+ if((*pps)->subject != NULL)
-+ fs_give((void **)&(*pps)->subject);
-+
- if((*pps)->hostname != NULL)
- fs_give((void **)&(*pps)->hostname);
-
-***************
-*** 130,135 ****
---- 134,142 ----
- if((*pps)->folders_dir != NULL)
- fs_give((void **)&(*pps)->folders_dir);
-
-+ if((*pps)->paterror == 0)
-+ regfree(&(*pps)->colorpat);
-+
- if((*pps)->ui.homedir)
- fs_give((void **)&(*pps)->ui.homedir);
-
-***************
-*** 182,187 ****
---- 189,197 ----
- if((*pps)->hdr_colors)
- free_spec_colors(&(*pps)->hdr_colors);
-
-+ if((*pps)->index_token_colors)
-+ free_spec_colors(&(*pps)->index_token_colors);
-+
- if((*pps)->keywords)
- free_keyword_list(&(*pps)->keywords);
-
-***************
-*** 202,207 ****
---- 212,220 ----
- if((*pps)->msgmap)
- msgno_give(&(*pps)->msgmap);
-
-+ if((*pps)->rule_list)
-+ free_parsed_rule_list(&(*pps)->rule_list);
-+
- free_vars(*pps);
-
- fs_give((void **) pps);
-diff -rc alpine-2.00/pith/state.h alpine-2.00.I.USE/pith/state.h
-*** alpine-2.00/pith/state.h 2008-06-03 08:54:15.000000000 -0700
---- alpine-2.00.I.USE/pith/state.h 2011-02-07 20:33:47.000000000 -0800
-***************
-*** 32,38 ****
- #include "../pith/stream.h"
- #include "../pith/color.h"
- #include "../pith/user.h"
-!
-
- /*
- * Printing control structure
---- 32,38 ----
- #include "../pith/stream.h"
- #include "../pith/color.h"
- #include "../pith/user.h"
-! #include "../pith/rulestype.h"
-
- /*
- * Printing control structure
-***************
-*** 104,112 ****
---- 104,118 ----
- MAILSTREAM *mail_stream; /* ptr to current folder stream */
- MSGNO_S *msgmap; /* ptr to current message map */
-
-+ char screen_name[10]; /* name of current screen */
-+ char *role; /* role used when composing */
-+ char *procid; /* procedure id when needed */
-+ int exiting;
-+
- unsigned read_predicted:1;
-
- char cur_folder[MAXPATH+1];
-+ QUOTALIST *quota;
- char last_unambig_folder[MAXPATH+1];
- char last_save_folder[MAXPATH+1];
- CONTEXT_S *last_save_context;
-***************
-*** 122,127 ****
---- 128,134 ----
- unsigned mangled_header:1; /* header needs repainting */
- unsigned mangled_body:1; /* body of screen needs repainting */
- unsigned mangled_screen:1; /* whole screen needs repainting */
-+ unsigned resize_for_pico:1; /* screen needs repainting due to resizing */
-
- unsigned in_init_seq:1; /* executing initial cmd list */
- unsigned save_in_init_seq:1;
-***************
-*** 135,140 ****
---- 142,149 ----
- 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;
-***************
-*** 168,173 ****
---- 177,183 ----
- unsigned intr_pending:1; /* received SIGINT and haven't acted */
- unsigned expunge_in_progress:1; /* don't want to re-enter c-client */
- unsigned never_allow_changing_from:1; /* not even for roles */
-+ unsigned newthread:1; /* start a new thread on composing */
-
- unsigned readonly_pinerc:1;
- unsigned view_all_except:1;
-***************
-*** 239,249 ****
---- 249,272 ----
- char **feat_list_back_compat;
-
- SPEC_COLOR_S *hdr_colors; /* list of configed colors for view */
-+ SPEC_COLOR_S *index_token_colors; /* list of configed colors for index */
-
-+ char *prefix; /* prefix for fillpara */
- short init_context;
-
-+ struct {
-+ ACTION_S *role_chosen;
-+ int attach;
-+ int strip;
-+ int no_send_flowed;
-+ int inchdr;
-+ } reply;
-+
- 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 */
-
-***************
-*** 281,288 ****
---- 304,316 ----
- EditWhich ew_for_srch_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 preserve;
-+
- int last_expire_year, last_expire_month;
-
- int printer_category;
-***************
-*** 295,300 ****
---- 323,332 ----
-
- int nmw_width;
-
-+ char *subject;
-+ int send_immediately;
-+ int failed_read;
-+
- int hours_to_timeout;
-
- int tcp_query_timeout;
-***************
-*** 317,322 ****
---- 349,356 ----
- char *display_charmap; /* needs to be freed */
- char *keyboard_charmap; /* needs to be freed */
- void *input_cs;
-+ regex_t colorpat;
-+ int paterror;
-
- char *posting_charmap; /* needs to be freed */
-
-***************
-*** 328,333 ****
---- 362,368 ----
- struct {
- char *(*display_filter)(char *, STORE_S *, gf_io_t, FILTLIST_S *);
- char *(*display_filter_trigger)(BODY *, char *, size_t);
-+ char *(*exec_rule)(char *, gf_io_t, gf_io_t);
- } tools;
-
- KEYWORD_S *keywords;
-***************
-*** 338,343 ****
---- 373,381 ----
- char last_error[500];
- INIT_ERR_S *init_errs;
-
-+ PRULELIST_S *rule_list;
-+ char *pressed_key;
-+
- PRINT_S *print;
-
- #ifdef SMIME
-diff -rc alpine-2.00/pith/store.c alpine-2.00.I.USE/pith/store.c
-*** alpine-2.00/pith/store.c 2008-06-03 12:27:23.000000000 -0700
---- alpine-2.00.I.USE/pith/store.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 170,175 ****
---- 170,183 ----
- if(source == TmpFileStar)
- our_unlink(so->name);
-
-+ if (ps_global->send_immediately){
-+ ps_global->failed_read++;
-+ if(ps_global->failed_read == 5){
-+ printf("No configurationf file found. Where is your .pinerc file?\n");
-+ exit(1);
-+ }
-+ }
-+
- fs_give((void **)&so->name);
- fs_give((void **)&so); /* so freed & set to NULL */
- }
-diff -rc alpine-2.00/pith/stream.c alpine-2.00.I.USE/pith/stream.c
-*** alpine-2.00/pith/stream.c 2008-03-25 11:57:53.000000000 -0700
---- alpine-2.00.I.USE/pith/stream.c 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 3318,3323 ****
---- 3318,3342 ----
- }
-
-
-+ /* Some stream is locked checks to see if there is any stream for which we
-+ * are in a callback from c-client
-+ */
-+
-+ int
-+ some_stream_is_locked(void)
-+ {
-+ int rv = 0, i;
-+ MAILSTREAM *m;
-+
-+ for(i = 0; rv == 0 && i < ps_global->s_pool.nstream; i++){
-+ m = ps_global->s_pool.streams[i];
-+ if(m && m->lock)
-+ rv++;
-+ }
-+
-+ return(rv);
-+ }
-+
- /*
- * Very simple version of appenduid_cb until we need something
- * more complex.
-diff -rc alpine-2.00/pith/stream.h alpine-2.00.I.USE/pith/stream.h
-*** alpine-2.00/pith/stream.h 2007-06-15 16:23:02.000000000 -0700
---- alpine-2.00.I.USE/pith/stream.h 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 460,465 ****
---- 460,466 ----
- int is_imap_stream(MAILSTREAM *);
- int modern_imap_stream(MAILSTREAM *);
- int streams_died(void);
-+ int some_stream_is_locked(void);
- void appenduid_cb(char *mailbox,unsigned long uidvalidity, SEARCHSET *set);
- imapuid_t get_last_append_uid(void);
- MAILSTREAM *mail_cmd_stream(CONTEXT_S *, int *);
-diff -rc alpine-2.00/pith/string.c alpine-2.00.I.USE/pith/string.c
-*** alpine-2.00/pith/string.c 2008-01-09 12:45:31.000000000 -0800
---- alpine-2.00.I.USE/pith/string.c 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 19,24 ****
---- 19,25 ----
- string.c
- Misc extra and useful string functions
- - rplstr replace a substring with another string
-+ - collspaces consecutive spaces are reduced to one space.
- - sqzspaces Squeeze out the extra blanks in a string
- - sqznewlines Squeeze out \n and \r.
- - removing_trailing_white_space
-***************
-*** 131,136 ****
---- 132,162 ----
- return(x3);
- }
-
-+ /*----------------------------------------------------------------------
-+ collapse blank space
-+ ----------------------------------------------------------------------*/
-+ void
-+ collspaces(char *string)
-+ {
-+ char *p = string;
-+ int only_one_space = 0;
-+
-+ if(!string)
-+ return;
-+
-+ for(;isspace(*p); p++);
-+
-+ while(*string = *p++)
-+ if(!isspace((unsigned char)*string)){
-+ only_one_space = 0;
-+ string++;
-+ }
-+ else if(!only_one_space){
-+ string++;
-+ only_one_space++;
-+ }
-+ *string = '\0';
-+ }
-
-
- /*----------------------------------------------------------------------
-***************
-*** 2859,2861 ****
---- 2885,2919 ----
- fs_give((void **) strp);
- }
- }
-+
-+
-+ 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 alpine-2.00/pith/string.h alpine-2.00.I.USE/pith/string.h
-*** alpine-2.00/pith/string.h 2007-08-15 13:28:09.000000000 -0700
---- alpine-2.00.I.USE/pith/string.h 2011-02-07 20:33:42.000000000 -0800
-***************
-*** 85,96 ****
---- 85,98 ----
-
- /* exported protoypes */
- char *rplstr(char *, size_t, int, char *);
-+ void collspaces(char *);
- void sqzspaces(char *);
- void sqznewlines(char *);
- void removing_leading_white_space(char *);
- void removing_trailing_white_space(char *);
- void removing_leading_and_trailing_white_space(char *);
- int removing_double_quotes(char *);
-+ void removing_extra_stuff (char *);
- char *skip_white_space(char *);
- char *skip_to_white_space(char *);
- char *removing_quotes(char *);
-diff -rc alpine-2.00/pith/text.c alpine-2.00.I.USE/pith/text.c
-*** alpine-2.00/pith/text.c 2008-03-18 10:24:31.000000000 -0700
---- alpine-2.00.I.USE/pith/text.c 2011-02-07 20:33:43.000000000 -0800
-***************
-*** 91,97 ****
- 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;
---- 91,97 ----
- 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, doraw = RAWSTRING;
- int is_delsp_yes = 0;
- int filt_only_c0 = 0;
- char *parmval;
-***************
-*** 170,175 ****
---- 170,184 ----
- gf_url_hilite_opt(&uh,handlesp,0));
- }
-
-+ 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.
-***************
-*** 179,185 ****
- && pico_usingcolor()
- && VAR_SIGNATURE_FORE_COLOR
- && VAR_SIGNATURE_BACK_COLOR){
-! filters[filtcnt].filter = gf_line_test;
- filters[filtcnt++].data = gf_line_test_opt(color_signature,
- &is_in_sig);
- }
---- 188,194 ----
- && pico_usingcolor()
- && VAR_SIGNATURE_FORE_COLOR
- && VAR_SIGNATURE_BACK_COLOR){
-! filters[filtcnt].filter = gf_quote_test;
- filters[filtcnt++].data = gf_line_test_opt(color_signature,
- &is_in_sig);
- }
-***************
-*** 197,205 ****
- && 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")){
---- 206,214 ----
- && 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")){
-***************
-*** 280,285 ****
---- 289,299 ----
- }
- }
-
-+ if (add_me){
-+ filters[filtcnt].filter = gf_quote_test;
-+ filters[filtcnt++].data = gf_line_test_opt(select_quote, &doraw);
-+ }
-+
- /*
- * If the message is not flowed, we do the quote suppression before
- * the wrapping, because the wrapping does not preserve the quote
-***************
-*** 304,310 ****
- dq.handlesp = handlesp;
- dq.do_color = (!(flags & FM_NOCOLOR) && pico_usingcolor());
-
-! filters[filtcnt].filter = gf_line_test;
- filters[filtcnt++].data = gf_line_test_opt(delete_quotes, &dq);
- }
- if(ps_global->VAR_QUOTE_REPLACE_STRING
---- 318,324 ----
- dq.handlesp = handlesp;
- dq.do_color = (!(flags & FM_NOCOLOR) && pico_usingcolor());
-
-! filters[filtcnt].filter = gf_quote_test;
- filters[filtcnt++].data = gf_line_test_opt(delete_quotes, &dq);
- }
- if(ps_global->VAR_QUOTE_REPLACE_STRING
-***************
-*** 363,369 ****
- dq.handlesp = handlesp;
- dq.do_color = (!(flags & FM_NOCOLOR) && pico_usingcolor());
-
-! filters[filtcnt].filter = gf_line_test;
- filters[filtcnt++].data = gf_line_test_opt(delete_quotes, &dq);
- }
-
---- 377,383 ----
- dq.handlesp = handlesp;
- dq.do_color = (!(flags & FM_NOCOLOR) && pico_usingcolor());
-
-! filters[filtcnt].filter = gf_quote_test;
- filters[filtcnt++].data = gf_line_test_opt(delete_quotes, &dq);
- }
-
-***************
-*** 568,574 ****
- {
- DELQ_S *dq;
- char *lp;
-! int i, lines, not_a_quote = 0;
- size_t len;
-
- dq = (DELQ_S *) local;
---- 582,588 ----
- {
- DELQ_S *dq;
- char *lp;
-! int i, lines, not_a_quote = 0, code;
- size_t len;
-
- dq = (DELQ_S *) local;
-***************
-*** 588,593 ****
---- 602,609 ----
- 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
-***************
-*** 627,639 ****
- }
- }
-
-! /* 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){
---- 643,654 ----
- }
- }
-
-! len = lp - line;
-! if(strlen(tmp_20k_buf) > len)
-! strcpy(tmp_20k_buf, tmp_20k_buf+len);
-! code = (dq->is_flowed ? IS_FLOWED : NO_FLOWED) | DELETEQUO;
-! select_quote(linenum, lp, ins, &code);
-! if (!not_a_quote && !tmp_20k_buf[0])
- not_a_quote++;
-
- if(not_a_quote){
-diff -rc alpine-2.00/pith/thread.c alpine-2.00.I.USE/pith/thread.c
-*** alpine-2.00/pith/thread.c 2008-03-03 09:52:11.000000000 -0800
---- alpine-2.00.I.USE/pith/thread.c 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 29,40 ****
- #include "../pith/mailcmd.h"
- #include "../pith/ablookup.h"
-
-
- /*
- * Internal prototypes
- */
- long *sort_thread_flatten(THREADNODE *, MAILSTREAM *, long *,
-! char *, long, PINETHRD_S *, unsigned);
- void make_thrdflags_consistent(MAILSTREAM *, MSGNO_S *, PINETHRD_S *, int);
- THREADNODE *collapse_threadnode_tree(THREADNODE *);
- THREADNODE *collapse_threadnode_tree_sorted(THREADNODE *);
---- 29,41 ----
- #include "../pith/mailcmd.h"
- #include "../pith/ablookup.h"
-
-+ static int erase_thread_info = 1;
-
- /*
- * Internal prototypes
- */
- long *sort_thread_flatten(THREADNODE *, MAILSTREAM *, long *,
-! char *, long, PINETHRD_S *, unsigned, int, long, long);
- void make_thrdflags_consistent(MAILSTREAM *, MSGNO_S *, PINETHRD_S *, int);
- THREADNODE *collapse_threadnode_tree(THREADNODE *);
- THREADNODE *collapse_threadnode_tree_sorted(THREADNODE *);
-***************
-*** 94,113 ****
- set_flags_for_thread(MAILSTREAM *stream, MSGNO_S *msgmap, int f, PINETHRD_S *thrd, 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);
- }
---- 95,116 ----
- set_flags_for_thread(MAILSTREAM *stream, MSGNO_S *msgmap, int f, PINETHRD_S *thrd, 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);
- }
-***************
-*** 121,127 ****
- MESSAGECACHE *mc;
- PINELT_S *peltp;
-
-! if(!(stream && stream->spare))
- return;
-
- ps_global->view_skipped_index = 0;
---- 124,130 ----
- MESSAGECACHE *mc;
- PINELT_S *peltp;
-
-! if(!(stream && stream->spare) || !erase_thread_info)
- return;
-
- ps_global->view_skipped_index = 0;
-***************
-*** 154,160 ****
- PINETHRD_S *thrd = NULL;
- unsigned long msgno, rawno;
- int un_view_thread = 0;
-! long raw_current;
- char *dup_chk = NULL;
-
-
---- 157,163 ----
- PINETHRD_S *thrd = NULL;
- unsigned long msgno, rawno;
- int un_view_thread = 0;
-! long raw_current, branch;
- char *dup_chk = NULL;
-
-
-***************
-*** 167,176 ****
- * way. If the dummy node is at the top-level, then its children are
- * promoted to the top-level as separate threads.
- */
-! if(F_ON(F_THREAD_SORTS_BY_ARRIVAL, ps_global))
-! collapsed_tree = collapse_threadnode_tree_sorted(tree);
-! else
-! collapsed_tree = collapse_threadnode_tree(tree);
-
- /* dup_chk is like sort with an origin of 1 */
- dup_chk = (char *) fs_get((mn_get_nmsgs(g_sort.msgmap)+1) * sizeof(char));
---- 170,180 ----
- * 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)
-! : (F_ON(F_THREAD_SORTS_BY_ARRIVAL, ps_global)
-! ? collapse_threadnode_tree_sorted(tree)
-! : collapse_threadnode_tree(tree));
-
- /* dup_chk is like sort with an origin of 1 */
- dup_chk = (char *) fs_get((mn_get_nmsgs(g_sort.msgmap)+1) * sizeof(char));
-***************
-*** 181,187 ****
- (void) sort_thread_flatten(collapsed_tree, stream,
- &g_sort.msgmap->sort[1],
- dup_chk, mn_get_nmsgs(g_sort.msgmap),
-! NULL, THD_TOP);
-
- /* reset the inverse array */
- msgno_reset_isort(g_sort.msgmap);
---- 185,191 ----
- (void) sort_thread_flatten(collapsed_tree, stream,
- &g_sort.msgmap->sort[1],
- dup_chk, mn_get_nmsgs(g_sort.msgmap),
-! NULL, THD_TOP, 0, 1L, 0L);
-
- /* reset the inverse array */
- msgno_reset_isort(g_sort.msgmap);
-***************
-*** 339,350 ****
- 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;
---- 343,356 ----
- 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;
-***************
-*** 358,366 ****
- MN_COLL));
- }
-
-! if(thrd->nextthd)
-! thrd = fetch_thread(stream, thrd->nextthd);
-! else
- thrd = NULL;
- }
- }
---- 364,373 ----
- MN_COLL));
- }
-
-! while (thrd && top_thread(stream, thrd->rawno) == top
-! && thrd->nextthd)
-! thrd = fetch_thread(stream, thrd->nextthd);
-! if (!(thrd && thrd->nextthd))
- thrd = NULL;
- }
- }
-***************
-*** 411,417 ****
- int a_parent_is_collapsed)
- {
- PINETHRD_S *nthrd, *bthrd;
-! unsigned long msgno;
-
- if(!thrd)
- return;
---- 418,424 ----
- int a_parent_is_collapsed)
- {
- PINETHRD_S *nthrd, *bthrd;
-! unsigned long msgno, next, branch;
-
- if(!thrd)
- return;
-***************
-*** 429,436 ****
- 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
---- 436,443 ----
- 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
-***************
-*** 439,446 ****
- MN_COLL));
- }
-
-! if(thrd->branch){
-! bthrd = fetch_thread(stream, thrd->branch);
- if(bthrd)
- make_thrdflags_consistent(stream, msgmap, bthrd,
- a_parent_is_collapsed);
---- 446,453 ----
- 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);
-***************
-*** 487,495 ****
- long *
- sort_thread_flatten(THREADNODE *node, MAILSTREAM *stream,
- long *entry, char *dup_chk, long maxno,
-! PINETHRD_S *thrd, unsigned int flags)
- {
-! PINETHRD_S *newthrd = NULL;
-
- if(node){
- if(node->num > 0L && node->num <= maxno){ /* holes happen */
---- 494,503 ----
- long *
- sort_thread_flatten(THREADNODE *node, MAILSTREAM *stream,
- long *entry, char *dup_chk, long maxno,
-! PINETHRD_S *thrd, unsigned int flags,
-! int adopted, long top, long threadno)
- {
-! PINETHRD_S *newthrd = NULL, *save_thread = NULL;
-
- if(node){
- if(node->num > 0L && node->num <= maxno){ /* holes happen */
-***************
-*** 497,502 ****
---- 505,513 ----
- *entry = node->num;
- dup_chk[node->num] = 1;
-
-+ if(adopted == 2)
-+ top = node->num;
-+
- /*
- * Build a richer threading structure that will help us paint
- * and operate on threads and subthreads.
-***************
-*** 505,524 ****
- if(newthrd){
- entry++;
-
- if(node->next)
- entry = sort_thread_flatten(node->next, stream,
- entry, dup_chk, maxno,
-! newthrd, THD_NEXT);
-
- if(node->branch)
- entry = sort_thread_flatten(node->branch, stream,
- entry, dup_chk, maxno,
- newthrd,
-! (flags == THD_TOP) ? THD_TOP
-! : THD_BRANCH);
- }
- }
- }
- }
-
- return(entry);
---- 516,566 ----
- if(newthrd){
- entry++;
-
-+ if(adopted == 2)
-+ threadno = newthrd->thrdno;
-+ if(adopted){
-+ newthrd->toploose = top;
-+ newthrd->thrdno = threadno;
-+ }
-+ adopted = adopted ? 1 : 0;
- if(node->next)
- entry = sort_thread_flatten(node->next, stream,
- entry, dup_chk, maxno,
-! newthrd, THD_NEXT, adopted, top, threadno);
-
- if(node->branch)
- entry = sort_thread_flatten(node->branch, stream,
- entry, dup_chk, maxno,
- 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, dup_chk,
-+ maxno, thrd, THD_TOP, adopted, top, threadno);
-+ adopted = 0;
-+ if(node->branch){
-+ if(entry){
-+ long *last_entry = entry;
-+
-+ do{
-+ last_entry--;
-+ save_thread = ((PINELT_S *)mail_elt(stream, *last_entry)->sparep)->pthrd;
-+ } while (save_thread->parent != 0L);
-+ entry = sort_thread_flatten(node->branch, stream, entry, dup_chk,
-+ maxno, save_thread, (flags == THD_TOP ? THD_TOP : THD_BRANCH),
-+ adopted, top, threadno);
-+ }
-+ else
-+ entry = sort_thread_flatten(node->branch, stream, entry, dup_chk,
-+ maxno, NULL, THD_TOP, adopted, top, threadno);
-+ }
-+ }
- }
-
- return(entry);
-***************
-*** 787,793 ****
- */
- void
- collapse_or_expand(struct pine *state, MAILSTREAM *stream, MSGNO_S *msgmap,
-! long unsigned int msgno)
- {
- int collapsed, adjust_current = 0;
- PINETHRD_S *thrd = NULL, *nthrd;
---- 829,835 ----
- */
- void
- collapse_or_expand(struct pine *state, MAILSTREAM *stream, MSGNO_S *msgmap,
-! long unsigned int msgno, int display)
- {
- int collapsed, adjust_current = 0;
- PINETHRD_S *thrd = NULL, *nthrd;
-***************
-*** 840,846 ****
- if(!thrd)
- return;
-
-! collapsed = get_lflag(stream, NULL, thrd->rawno, MN_COLL) && thrd->next;
-
- if(collapsed){
- msgno = mn_raw2m(msgmap, thrd->rawno);
---- 882,888 ----
- if(!thrd)
- return;
-
-! collapsed = this_thread_is_kolapsed(ps_global, stream, msgmap, thrd->rawno);
-
- if(collapsed){
- msgno = mn_raw2m(msgmap, thrd->rawno);
-***************
-*** 858,870 ****
- 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)) != NULL)
- set_thread_subtree(stream, nthrd, msgmap, 1, MN_CHID);
-
- clear_index_cache_ent(stream, msgno, 0);
- }
- }
-! else
- q_status_message(SM_ORDER, 0, 1,
- _("No thread to collapse or expand on this line"));
-
---- 900,912 ----
- 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)) != NULL))
- set_thread_subtree(stream, nthrd, msgmap, 1, MN_CHID);
-
- clear_index_cache_ent(stream, msgno, 0);
- }
- }
-! else if(display)
- q_status_message(SM_ORDER, 0, 1,
- _("No thread to collapse or expand on this line"));
-
-***************
-*** 951,968 ****
- unsigned long 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);
- }
---- 993,1011 ----
- unsigned long 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);
- }
-***************
-*** 1050,1069 ****
- mark_msgs_in_thread(MAILSTREAM *stream, PINETHRD_S *thrd, 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);
- }
---- 1093,1113 ----
- mark_msgs_in_thread(MAILSTREAM *stream, PINETHRD_S *thrd, 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);
- }
-***************
-*** 1097,1103 ****
- /* flags to set or clear */
- /* set or clear? */
- {
-! unsigned long msgno;
- PINETHRD_S *nthrd, *bthrd;
-
- if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs)
---- 1141,1147 ----
- /* flags to set or clear */
- /* set or clear? */
- {
-! unsigned long msgno, next, branch;
- PINETHRD_S *nthrd, *bthrd;
-
- if(!thrd || !stream || thrd->rawno < 1L || thrd->rawno > stream->nmsgs)
-***************
-*** 1121,1134 ****
- if(msgno > 0L && flags == MN_CHID2 && v == 1)
- clear_index_cache_ent(stream, msgno, 0);
-
-! 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);
- }
---- 1165,1178 ----
- if(msgno > 0L && flags == MN_CHID2 && v == 1)
- clear_index_cache_ent(stream, msgno, 0);
-
-! 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);
- }
-***************
-*** 1217,1235 ****
- char to_us = ' ';
- char branch_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(((consider_flagged && to_us != '*') || (!consider_flagged && to_us != '+'))
-! && thrd->branch){
- bthrd = fetch_thread(stream, thrd->branch);
- if(bthrd)
- branch_to_us = to_us_symbol_for_thread(stream, bthrd, consider_flagged);
---- 1261,1280 ----
- char to_us = ' ';
- char branch_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(((consider_flagged && to_us != '*') || (!consider_flagged && to_us != '+'))
-! && (branch = get_branch(stream, thrd))){
- bthrd = fetch_thread(stream, thrd->branch);
- if(bthrd)
- branch_to_us = to_us_symbol_for_thread(stream, bthrd, consider_flagged);
-***************
-*** 1279,1285 ****
- break;
- }
-
-! if(to_us != '+' && resent_to_us(&idata))
- to_us = '+';
-
- if(to_us == ' ' && F_ON(F_MARK_FOR_CC,ps_global))
---- 1324,1330 ----
- break;
- }
-
-! if(to_us != '+' && !idata.bogus && resent_to_us(&idata))
- to_us = '+';
-
- if(to_us == ' ' && F_ON(F_MARK_FOR_CC,ps_global))
-***************
-*** 1327,1333 ****
-
- 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);
---- 1372,1379 ----
-
- 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);
-***************
-*** 1367,1374 ****
- 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;
---- 1413,1420 ----
- 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;
-***************
-*** 1432,1438 ****
- thrd = fetch_thread(stream, rawno);
-
- if(thrd && thrd->top)
-! topthrd = fetch_thread(stream, thrd->top);
-
- if(!topthrd)
- return 0;
---- 1478,1484 ----
- thrd = fetch_thread(stream, rawno);
-
- if(thrd && thrd->top)
-! topthrd = fetch_thread(stream, top_thread(stream,thrd->top));
-
- if(!topthrd)
- return 0;
-***************
-*** 1538,1543 ****
---- 1584,1590 ----
- set_search_bit_for_thread(MAILSTREAM *stream, PINETHRD_S *thrd, SEARCHSET **msgset)
- {
- PINETHRD_S *nthrd, *bthrd;
-+ unsigned long next, branch;
-
- if(!(stream && thrd))
- return;
-***************
-*** 1546,1560 ****
- && (!(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);
- }
- }
---- 1593,2185 ----
- && (!(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);
- }
- }
-+
-+ /*
-+ * Make a copy of c-client's THREAD tree
-+ */
-+ THREADNODE *
-+ copy_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);
-+ }
-+
-+ long
-+ top_thread(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(MAILSTREAM *stream, MSGNO_S *msgmap, long rawmsgno)
-+ {
-+ mn_set_cur(msgmap,mn_raw2m(msgmap, top_thread(stream, rawmsgno)));
-+ }
-+
-+ long
-+ top_this_thread(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(MAILSTREAM *stream, MSGNO_S *msgmap, long rawmsgno)
-+ {
-+ mn_set_cur(msgmap,mn_raw2m(msgmap, top_this_thread(stream, rawmsgno)));
-+ }
-+
-+ int
-+ thread_is_kolapsed(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(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;
-+ }
-+
-+ /*
-+ * This function assumes that it is called at a top of a thread in its
-+ * first call
-+ */
-+
-+ int
-+ count_this_thread(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(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;
-+ }
-+
-+ unsigned long
-+ get_branch(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(MAILSTREAM *stream, PINETHRD_S *thrd)
-+ {
-+ return thrd->next;
-+ }
-+
-+ long
-+ get_length_branch(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(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;
-+ 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));
-+
-+ sort_folder(stream, msgmap, ordersort, 0, SRT_VRB, 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, SRT_VRB, 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(stream, 0);
-+ }
-+
-+ void
-+ move_thread(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(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
-+ move_next_this_thread(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(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(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;
-+ }
-+
-+ /* add more keys to this list */
-+ int
-+ allowed_thread_key(SortOrder sort)
-+ {
-+ return sort == SortArrival
-+ || sort == SortDate
-+ || sort == SortScore
-+ || sort == SortThread;
-+ }
-+
-diff -rc alpine-2.00/pith/thread.h alpine-2.00.I.USE/pith/thread.h
-*** alpine-2.00/pith/thread.h 2006-09-22 13:06:05.000000000 -0700
---- alpine-2.00.I.USE/pith/thread.h 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 37,42 ****
---- 37,43 ----
- 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;
-
-***************
-*** 92,98 ****
- void sort_thread_callback(MAILSTREAM *, THREADNODE *);
- void collapse_threads(MAILSTREAM *, MSGNO_S *, PINETHRD_S *);
- PINETHRD_S *msgno_thread_info(MAILSTREAM *, unsigned long, PINETHRD_S *, unsigned);
-! void collapse_or_expand(struct pine *, MAILSTREAM *, MSGNO_S *, unsigned long);
- void select_thread_stmp(struct pine *, MAILSTREAM *, MSGNO_S *);
- unsigned long count_flags_in_thread(MAILSTREAM *, PINETHRD_S *, long);
- unsigned long count_lflags_in_thread(MAILSTREAM *, PINETHRD_S *, MSGNO_S *, int);
---- 93,99 ----
- void sort_thread_callback(MAILSTREAM *, THREADNODE *);
- void collapse_threads(MAILSTREAM *, MSGNO_S *, PINETHRD_S *);
- PINETHRD_S *msgno_thread_info(MAILSTREAM *, unsigned long, PINETHRD_S *, unsigned);
-! void collapse_or_expand(struct pine *, MAILSTREAM *, MSGNO_S *, unsigned long, int);
- void select_thread_stmp(struct pine *, MAILSTREAM *, MSGNO_S *);
- unsigned long count_flags_in_thread(MAILSTREAM *, PINETHRD_S *, long);
- unsigned long count_lflags_in_thread(MAILSTREAM *, PINETHRD_S *, MSGNO_S *, int);
-***************
-*** 106,111 ****
- int unview_thread(struct pine *, MAILSTREAM *, MSGNO_S *);
- PINETHRD_S *find_thread_by_number(MAILSTREAM *, MSGNO_S *, long, PINETHRD_S *);
- void set_search_bit_for_thread(MAILSTREAM *, PINETHRD_S *, SEARCHSET **);
-!
-
- #endif /* PITH_THREAD_INCLUDED */
---- 107,130 ----
- int unview_thread(struct pine *, MAILSTREAM *, MSGNO_S *);
- PINETHRD_S *find_thread_by_number(MAILSTREAM *, MSGNO_S *, long, PINETHRD_S *);
- void set_search_bit_for_thread(MAILSTREAM *, PINETHRD_S *, SEARCHSET **);
-! void find_msgmap(MAILSTREAM *, MSGNO_S *, int, SortOrder, unsigned);
-! void move_thread(struct pine *, MAILSTREAM *, MSGNO_S *, int);
-! void relink_threads(MAILSTREAM *, MSGNO_S *, long *);
-! long top_thread(MAILSTREAM *, long);
-! long top_this_thread(MAILSTREAM *, long);
-! long get_length_branch(MAILSTREAM *, long);
-! unsigned long get_next(MAILSTREAM *,PINETHRD_S *);
-! unsigned long get_branch(MAILSTREAM *,PINETHRD_S *);
-! int count_thread(struct pine *, MAILSTREAM *, MSGNO_S *, long);
-! int count_this_thread(MAILSTREAM *, unsigned long);
-! int this_thread_is_kolapsed(struct pine *, MAILSTREAM *, MSGNO_S *, long);
-! int thread_is_kolapsed(struct pine *, MAILSTREAM *, MSGNO_S *, long);
-! int move_prev_thread(struct pine *, MAILSTREAM *, MSGNO_S *, int);
-! int move_next_thread(struct pine *, MAILSTREAM *, MSGNO_S *, int);
-! int move_next_this_thread(struct pine *, MAILSTREAM *, MSGNO_S *, int);
-! void move_top_thread(MAILSTREAM *, MSGNO_S *, long);
-! void move_top_this_thread(MAILSTREAM *, MSGNO_S *, long);
-! THREADNODE *copy_tree(THREADNODE *);
-! int allowed_thread_key(SortOrder sort);
-
- #endif /* PITH_THREAD_INCLUDED */
-diff -rc alpine-2.00/pith/url.c alpine-2.00.I.USE/pith/url.c
-*** alpine-2.00/pith/url.c 2007-08-29 15:31:51.000000000 -0700
---- alpine-2.00.I.USE/pith/url.c 2011-02-07 20:33:45.000000000 -0800
-***************
-*** 52,58 ****
- rfc1738_scan(char *line, int *len)
- {
- char *colon, *start, *end;
-! int n;
-
- /* process each : in the line */
- for(; (colon = strindex(line, ':')) != NULL; line = end){
---- 52,58 ----
- rfc1738_scan(char *line, int *len)
- {
- char *colon, *start, *end;
-! int n, delim;
-
- /* process each : in the line */
- for(; (colon = strindex(line, ':')) != NULL; line = end){
-***************
-*** 113,119 ****
- && !struncmp(start + 1, "elnet", 5))))
- || (n == 8
- && (*start == 'P' || *start == 'p')
-! && !struncmp(start + 1, "rospero", 7)))
- || url_external_specific_handler(start, n))){
- /*
- * Second, make sure that everything to the right of the
---- 113,125 ----
- && !struncmp(start + 1, "elnet", 5))))
- || (n == 8
- && (*start == 'P' || *start == 'p')
-! && !struncmp(start + 1, "rospero", 7))
-! || (n == 11
-! && (*start == 'x' || *start == 'X')
-! && !struncmp(start + 1, "-pine-help", 10))
-! || (n == 13
-! && (*start == 'x' || *start == 'X')
-! && !struncmp(start + 1, "-alpine-help", 12)))
- || url_external_specific_handler(start, n))){
- /*
- * Second, make sure that everything to the right of the
-***************
-*** 130,135 ****
---- 136,142 ----
-
- if(i != j){
- *len = end - start;
-+ delim = start > line && *(start - 1) == '<';
-
- /*
- * Special case handling for comma.
-***************
-*** 139,146 ****
- * In most cases any way, that's why we have the
- * exception.
- */
-! if(*(end - 1) == ','
-! || (*(end - 1) == '.' && (!*end || *end == ' ')))
- (*len)--;
-
- if(*len - (colon - start) > 0)
---- 146,153 ----
- * In most cases any way, that's why we have the
- * exception.
- */
-! if(delim == 0 && (*(end - 1) == ','
-! || (*(end - 1) == '.' && (!*end || *end == ' '))))
- (*len)--;
-
- if(*len - (colon - start) > 0)
-diff -rc alpine-2.00/README.maildir alpine-2.00.I.USE/README.maildir
-*** alpine-2.00/README.maildir 2011-02-07 20:34:02.000000000 -0800
---- alpine-2.00.I.USE/README.maildir 2011-02-07 20:33:41.000000000 -0800
-***************
-*** 0 ****
---- 1,153 ----
-+ ---------------------------------------
-+
-+ Maildir Driver for Alpine 1.0
-+ By Eduardo Chappa <chappa@washington.edu>
-+ http://staff.washington.edu/chappa/alpine/
-+
-+ ---------------------------------------
-+ 1. General Information About This Patch
-+ ---------------------------------------
-+
-+ This patch adds support for the maildir format to Alpine. We take the
-+ approach that this patch is one more driver among the number of formats
-+ supported by Alpine (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, mix, 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 other 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 Alpine 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 Alpine to make this driver do its work, unless such patching is for
-+ fixing bugs in Alpine or to pass parameters to the driver.
-+
-+ ------------------------------------------------------------------------
-+ 3. 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. A complete list of updates
-+ for this patch, which includes bug fixes, improvements and addition of new
-+ features can be found at
-+
-+ http://staff.washington.edu/chappa/alpine/updates/maildir.html
-+
-+ ----------
-+ 4. On UIDs
-+ ----------
-+
-+ This patch keeps uids in the name of the file that contains the message,
-+ by adding a ",u=" string to the file name to save the uid of a message. A
-+ file is kept between sessions to save information on the last uid assigned
-+ and its time of validity. Only one session with writing access can write
-+ uids, all others must wait for the other session to assign them. The
-+ session assigning uids creates a ".uidtemp" file which other sessions must
-+ not disturb.
-+
-+ Uid support appeared in Alpine 1.00 (snapshot 925), and is experimental,
-+ please report any problems.
-+
-+ --------------------------------------------
-+ 5. Configuring Alpine 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 Alpine 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.
-+
-+ -----------------------------------
-+ 6. 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 Alpine 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 Alpine search for your collection in ~/Courier.
-+
-+ You can not add this directly into Alpine because Alpine 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 February 9, 2008
-diff -rc alpine-2.00/web/src/alpined.d/alpined.c alpine-2.00.I.USE/web/src/alpined.d/alpined.c
-*** alpine-2.00/web/src/alpined.d/alpined.c 2008-08-22 13:41:37.000000000 -0700
---- alpine-2.00.I.USE/web/src/alpined.d/alpined.c 2011-02-07 20:33:43.000000000 -0800
-***************
-*** 2795,2801 ****
- init_save_defaults();
- break;
- case V_SORT_KEY:
-! decode_sort(ps_global->VAR_SORT_KEY, &ps_global->def_sort, &def_sort_rev);
- break;
- case V_VIEW_HDR_COLORS :
- set_custom_spec_colors(ps_global);
---- 2795,2801 ----
- init_save_defaults();
- break;
- case V_SORT_KEY:
-! decode_sort(ps_global->VAR_SORT_KEY, &ps_global->def_sort, &def_sort_rev, 0);
- break;
- case V_VIEW_HDR_COLORS :
- set_custom_spec_colors(ps_global);
-***************
-*** 6271,6277 ****
- && mn_get_revsort(sp_msgmap(ps_global->mail_stream)) == reversed))
- sort_folder(ps_global->mail_stream, sp_msgmap(ps_global->mail_stream),
- ps_global->sort_types[i],
-! reversed, 0);
-
- break;
- }
---- 6271,6277 ----
- && mn_get_revsort(sp_msgmap(ps_global->mail_stream)) == reversed))
- sort_folder(ps_global->mail_stream, sp_msgmap(ps_global->mail_stream),
- ps_global->sort_types[i],
-! reversed, 0, 1);
-
- break;
- }
-***************
-*** 6848,6854 ****
- /* BUG: fix charset not to be NULL below */
- if(agg_text_select(ps_global->mail_stream,
- sp_msgmap(ps_global->mail_stream),
-! field, not, 0, text, NULL, NULL))
- /* BUG: plug in "charset" above? */
- return(peSelectError(interp, "programmer botch"));
- }
---- 6848,6854 ----
- /* BUG: fix charset not to be NULL below */
- if(agg_text_select(ps_global->mail_stream,
- sp_msgmap(ps_global->mail_stream),
-! field, NULL, not, 0, text, NULL, NULL))
- /* BUG: plug in "charset" above? */
- return(peSelectError(interp, "programmer botch"));
- }
-diff -rc alpine-2.00/web/src/alpined.d/Makefile.am alpine-2.00.I.USE/web/src/alpined.d/Makefile.am
-*** alpine-2.00/web/src/alpined.d/Makefile.am 2008-08-12 13:47:04.000000000 -0700
---- alpine-2.00.I.USE/web/src/alpined.d/Makefile.am 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 50,52 ****
---- 50,53 ----
- debug.c status.c stubs.c alpined.h color.h ldap.h
- echo "char datestamp[]="\"`date`\"";" > local.c
- echo "char hoststamp[]="\"`hostname`\"";" >> local.c
-+ cat ../../../patchlevel >> local.c
-diff -rc alpine-2.00/web/src/alpined.d/Makefile.in alpine-2.00.I.USE/web/src/alpined.d/Makefile.in
-*** alpine-2.00/web/src/alpined.d/Makefile.in 2008-08-13 08:44:42.000000000 -0700
---- alpine-2.00.I.USE/web/src/alpined.d/Makefile.in 2011-02-07 20:33:46.000000000 -0800
-***************
-*** 619,624 ****
---- 619,625 ----
- debug.c status.c stubs.c alpined.h color.h ldap.h
- echo "char datestamp[]="\"`date`\"";" > local.c
- echo "char hoststamp[]="\"`hostname`\"";" >> local.c
-+ cat ../../../patchlevel >> local.c
- # Tell versions [3.59,3.63) of GNU make to not export all variables.
- # Otherwise a system limit (for SysV at least) may be exceeded.
- .NOEXPORT: