diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2015-03-11 09:20:01 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2015-03-11 09:20:01 +0000 |
commit | f293739e0db7bbddff5199f74b6150312c16a6cc (patch) | |
tree | b08354d610b2d0254de3398cb4f13ce093bb7e94 /main/alpine/all_p84.patch | |
parent | ebcf082a79f5b36210d7191ce461cc3a9384472e (diff) | |
download | aports-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.patch | 26592 |
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(®ion, 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 "Alternatively Licensed Program for Internet - News and Email" produced by the University of Washington. - It is intended to be an easy-to-use program for -*************** -*** 919,924 **** ---- 928,1016 ---- - <End of Configuration Notes> - </BODY> - </HTML> -+ ====== h_patches ====== -+ <html> -+ <head> -+ <TITLE>Information on patches added to this release</TITLE> -+ </head> -+ <body> -+ <H1>Information on patches added to this release</H1> -+ <P> -+ This version of 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"><chappa@washington.edu></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 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ======= h_thread_index_sort_arrival ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Arrival</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Arrival</H1> -+ -+ The <EM>Arrival</EM> sort option arranges threads according to the last -+ time that a message was added to it. In this order the last thread -+ contains the most recent message in the folder. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_date ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Date</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Date</H1> -+ -+ The <EM>Date</EM> sort option in the THREAD INDEX screen sorts -+ threads by the date in which messages were sent. The thread containing the -+ last message in this order is displayed last. -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_subj ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Subject</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Subject</H1> -+ -+ The <EM>Subject</EM> sort option has not been defined yet. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_ordsubj ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: OrderedSubject</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: OrderedSubject</H1> -+ -+ The <EM>OrderedSubject</EM> sort option in the THREAD INDEX screen is -+ the same as sorting by <A HREF="h_thread_index_sort_subj">Subject</A>. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_thread ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Thread</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Thread</H1> -+ -+ The <EM>Thread</EM> sort option in the THREAD INDEX screen sorts all -+ messages by the proposed algorithm by Crispin and Murchison. In this -+ method of sorting once threads have been isolated they are sorted by the -+ date of their parents, or if that is missing, the first message in that -+ thread. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_from ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: From</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: From</H1> -+ -+ The <EM>From</EM> sort option has not been defined yet. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_size ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Size</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Size</H1> -+ -+ The <EM>Size</EM> sort option has not been defined yet. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_score ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Score</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Score</H1> -+ -+ The <EM>Score</EM> sort option 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> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_to ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: To</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: To</H1> -+ -+ The <EM>To</EM> sort option has not been defined yet. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ======= h_thread_index_sort_cc ======= -+ <HTML> -+ <HEAD> -+ <TITLE>SORT OPTION: Cc</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>SORT OPTION: Cc</H1> -+ -+ The <EM>Cc</EM> sort option has not been defined yet. -+ -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ======= h_index_cmd_whereis ======= - <HTML> - <HEAD> -*************** -*** 6503,6508 **** ---- 6765,6810 ---- - "type the character ^". - - <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 ">". -+ -+ <P> -+ Some other constructions of quote strings are recognized only if they -+ appear enough in the text. For example "Peter :" is only -+ recognized if it appears in two consecutive lines. -+ -+ <P> -+ Additionaly, 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 "*" 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 "." or ":". -+ In addition to the explanation of what constitutes a paragraph above, a -+ new paragraph is recognized when an indent-string is found in it (and -+ validated according to the above stated rules). -+ -+ <P> - <End of help on this topic> - </BODY> - </HTML> -*************** -*** 18069,18074 **** ---- 18371,18377 ---- - <A HREF="h_config_index_format">"<!--#echo var="VAR_index-format"-->"</A> option, - in the <A HREF="h_config_reply_intro">"<!--#echo var="VAR_reply-leadin"-->"</A> option, - in signature files, -+ in the <A HREF="h_config_reply_leadin_rules">"new-rules" option</A>, - in template files used in - <A HREF="h_rules_roles">"roles"</A>, and in the folder name - that is the target of a Filter Rule. -*************** -*** 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, "mailbox@domain". - </DD> - -+ <DT>ADDRESSTO</DT> -+ <DD> -+ This is similar to the "TO" token, only it is always the -+ email address of all people listed in the TO: field of the messages. Addresses -+ are separated by a blank space. Example, "mailbox@domain" when -+ the e-mail message contains only one person in the To: field, or -+ "peter@flintstones.com president@world.com". -+ </DD> -+ - <DT>MAILBOX</DT> - <DD> - This is the same as the "ADDRESS" except that the -*************** -*** 18161,18166 **** ---- 18473,18487 ---- - message's "Cc:" header field. - </DD> - -+ <DT>ADDRESSCC</DT> -+ <DD> -+ This is similar to the "CC" token, only it is always the -+ email address of all people listed in the Cc: field of the messages. Addresses -+ are separated by a blank space. Example: "mailbox@domain" when -+ the e-mail message contains only one person in the Cc: field, or -+ "peter@flintstones.com president@world.com". -+ </DD> -+ - <DT>RECIPS</DT> - <DD> - This token represents the personal names (or email addresses if the names -*************** -*** 18169,18174 **** ---- 18490,18503 ---- - the message's "Cc:" header field. - </DD> - -+ <DT>ADDRESSRECIPS</DT> -+ <DD> -+ This token represent the e-mail addresses of the people in the To: and -+ Cc: fields, exactly in that order separated by a space. It is almost obtained -+ by concatenating the ADDRESSTO and ADDRESSCC tokens. -+ </DD> -+ -+ - <DT>NEWSANDRECIPS</DT> - <DD> - This token represents the newsgroups from the -*************** -*** 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 ---- - <End of help on this topic> - </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> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ====== h_config_maildir ===== -+ <HTML> -+ <HEAD> -+ <TITLE>Maildir Support</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>Maildir Support</H1> -+ -+ This version of 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 "#md/inbox" (without quotes). This assumes that your mail -+ delivery agent is delivering new mail to ~/Maildir/new. If the directory -+ where new mail is being delivered is not called "Maildir", you can set the -+ name of the subdirectory of home where it is being delivered in the <A -+ HREF="h_config_maildir_location"><!--#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 "mail/" to -+ "#md/mail". In a maildir collection folders of any other format -+ are ignored. -+ -+ <P> Finally, This version also has -+ <A HREF="h_config_courier_list">support</A> for the Courier style file system -+ when a maildir collection is accessed locally. -+ -+ <P> -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL><P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_literal_sig ===== - <HTML> - <HEAD> -*************** -*** 22015,22020 **** ---- 22520,22564 ---- - <End of help on this topic> - </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 "removed" 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 -+ "Thread". -+ -+ <P> -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL><P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_other_startup ===== - <HTML> - <HEAD> -*************** -*** 22285,22290 **** ---- 22829,23726 ---- - <End of help on this topic> - </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} => _SUBJECT_ := _COPY_{[tag] _SUBJECT_} -+ -+ <P> -+ and -+ -+ <P> -+ _ROLE_ == {work} => _LCC_ := _TRIM_{_FORWARDFROM_ <_FORWARDADDRESS_>} -+ -+ <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} => _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><End of help on this topic> -+ </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><End of help on this topic> -+ </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_ !> {[tag] } => _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_ <_FORWARDADDRESS_>} -+ -+ <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><End of help on this topic> -+ </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><End of help on this topic> -+ </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 "RETURN" 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><End of help on this topic> -+ </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 "index", -+ "text" and -+ "folder" 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 "pressed key"). For -+ example you could use _PKEY_ == {~}, to designate the "~" -+ 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 -+ "$" and "h". 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> -+ "_SCREEN_ == {index} && _PKEY_ == {~} => _COMMAND_{$,h}" -+ -+ <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_{"$h"} -+ -+ <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><End of help on this topic> -+ </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_{\[some-tag-here #[0-9].*\]} -+ -+ <P> You can also use this configuration option to remove specific strings of -+ the index display screen, so that you can trim unnecessary information in -+ your index, 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><End of help on this topic> -+ </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ó _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><End of help on this topic> -+ </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 "Re:" -+ to "AW:" or "Sv:". In this case a rule like<BR> -+ <center>_SUBJECT_ >> {Sv: ;AW: } => _SUBJECT_ := _TRIM_{Sv: ;AW: }</center> -+ <P> -+ would eliminate undesired strings in replies. -+ -+ <P> 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 "a" 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 "$1" 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 "$1". This is the kind of behavior -+ that your program is expected to have. -+ -+ <P> -+ The content of the input file ("$1" 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} => _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><End of help on this topic> -+ </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><End of help on this topic> -+ -+ </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><End of help on this topic> -+ -+ </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><End of help on this topic> -+ -+ </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">"<!--#echo var="VAR_smtp-server"-->"</A> configuration -+ option according to the rules used in that variable. -+ -+ <P> The function associated to this configuration option is _SMTP_, an example -+ of the use of this function is<BR> -+ _ADDRESSTO_ == {peter@bedrock.com} => _SMTP_{smtp.bedrock.com} -+ -+ <P> This configuration option is just one of many that allow you to -+ override the value of some global configurations within 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><End of help on this topic> -+ -+ </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><End of help on this topic> -+ -+ </BODY> -+ </HTML> -+ ====== h_config_new_rules ===== -+ <HTML> -+ <HEAD> -+ <TITLE>OPTION: New Rules Explained</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>OPTION: New Rules Explained</H1> -+ -+ This is a quite powerful option. Here you can define rules that override -+ the values of any other 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 "rules" 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} => _SAVE_{Fred} -+ -+ <P> -+ Here the separator is "=>". 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 "Fred -+ Flinstone", and the action will be that you will be offered to save -+ it in the folder "Fred", whenever you press the letter -+ "S" to save a message. -+ -+ <P> -+ The separator is always "=>", with one exception to be seen -+ later. But for the most part this will be the only one you 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 -+ "{" and "}", 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> <BR> -+ <LI> _INDEX_ : This function takes as an argument an index-format, and -+ makes that the index-format for the specified folder. -+ <BR> <BR> -+ <LI> _REPLACE_ : This function replaces the subject/from of the given e-mail by -+ another subject/from only when displaying the index. -+ <BR> <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> <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> <BR> -+ <LI> _RESUB_ : This function replaces the subject of the given e-mail by -+ another subject only when replying to a message. -+ <BR> <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> <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> <BR> -+ <LI> _SMTP_ : This function takes as an argument the definition of a -+ SMTP server. -+ <BR> <BR> -+ <LI> _SORT_ : This function takes as an argument a Sort Style, and sorts a -+ specified folder in that sort order. -+ <BR> <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> <BR> -+ <LI> _REXTRIM_ : Same as _TRIM_ but its argument is one and -+ only one extended regular expression. -+ <BR> <BR> -+ <LI> _STARTUP_ : This function takes as an argument an -+ incoming-startup-rule, and open an specified folder using that rule. -+ <BR> <BR> -+ <LI> _THREADSTYLE_ : This function takes as an argument a -+ threading-display-style and uses it to display threads in a folder. -+ <BR> <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} => _SAVE_{Fred} -+ -+ <P> it will only be applied if the from is "Fred Flinstone". If -+ the From is "Wilma Flinstone" the rule will be skipped. -+ -+ <P> In order to test a condition you can use the following tokens (in -+ alphabetical order): _ADDRESS_, _CC_, _FOLDER_, _FROM_,_NICK_, _ROLE, -+ _SENDER_, _SUBJECT_ and _TO_. The token will always be tested against what -+ it is between "{" and "}" in the condition, this part -+ of the condition is called the "condition set". The definition -+ of each token can be found <A HREF="h_index_tokens">here</A>. -+ -+ <P> 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 -+ "test operands": <<, !<, >>, !>, == and !=. -+ All of them are two strings long. Here is the meaning of them: -+ -+ <P> -+ <UL> -+ <LI> << : It tests if the value of the token is contained in -+ the condition set. Here for example if the condition set were equal to -+ "Freddy", then the condition: _NICK_ << {Freddy}, would be true if -+ the value of _NICK_ were "Fred", "red" or "Freddy". You are just looking -+ for substrings here. -+ <LI> >> : It tests if the value of the token contains the value of -+ the condition set. Here for example if the condittion set were equal to -+ "Fred", then the condition: _FROM_ >> {Fred}, would be true if -+ the value of _FROM_ were "Fred Flinstone" or "Fred P. Flinstone" or "Freddy". -+ <LI> == : It tests if the value of the token is exactly equal to the value -+ of the set condition. For example _NICK_ == {Fred} will be false if the value -+ of _NICK_ is "Freddy" or "red". -+ <LI> !< : This is true only when << is false and viceversa. -+ <LI> !> : This is true only when >> is false and viceversa. -+ <LI> != : This is true only when == is false and viceversa. -+ </UL> -+ -+ <P> -+ Now let us say that you want the same action to be applied to more than -+ one person or folder, say you want "folder1" and "folder2" to be sorted by -+ Ordered Subject upon entering. Then you can list them all of them in the -+ condition part separting them by a ";". Here is the way to do it. -+ -+ <P> -+ _FOLDER_ << {folder1; folder2} => _SORT_{OrderedSubj} -+ -+ <P> -+ Here is the first subtelty about these definitions. Notice that the -+ following rule: -+ -+ <P> -+ _FOLDER_ == {folder1; folder2} => _SORT_{Reverse OrderedSubj} -+ -+ <P> works only for "folder1" but not for "folder2". This is because the -+ comparison of the name of the folder is done with whatever is in between -+ "{", ";" or "}", so in the above rule you would be testing <BR> -+ "folder2" == " folder2". The extra space makes the difference. -+ The reason why the first rule does not fail is because -+ "folder2" << " folder2" is actually -+ true. If something ever fails this may be something to look into. -+ -+ <P> -+ Here are a few examples of what we have talked about before. -+ -+ <P> -+ _NICK_ == {lisa;kika} => _SAVE_{_NICK_/_NICK_} <BR> -+ This means that if the nick is lisa, it will -+ save the message in the folder "lisa/lisa", and if the nick -+ is "kika", it will save the message in the folder "kika/kika" -+ -+ <P> -+ _FOLDER_ == {Lynx} -> lynx <BR> -+ This, is an abreviation of the following rule:<BR> -+ _FOLDER_ == {Lynx} => _SAVE_{lynx} <BR> -+ (note the change in separator from "=>" to "->"). In the future -+ I will use that abreviation. -+ -+ <P> _FOLDER_ << {comp.mail.pine; pine-info; pine-alpha} -> pine <BR> -+ Any message in the folders "comp.mail.pine", "pine-info" or "pine-alpha" -+ will be saved to the folder "pine". -+ -+ <P> _FROM_ << {Pine Master} -> pine <BR> -+ Any message whose From field contains -+ "Pine Master" will be saved in the folder pine. -+ -+ <P> _FOLDER_ << {Lynx; pine-info; comp.mail.pine} => -+ _INDEX_{IMAPSTATUS MSGNO DATE FROMORTO(33%) SUBJECT(66%)} <BR> Use a -+ different index-format for the folders "Lynx", "pine-info" and -+ "comp.mail.pine", where the size is not present. -+ -+ <P> _FOLDER_ == {Lynx;pine-info} => _REPLY_{*** _FROM_ (_ADDRESS_) -+ wrote in the _FOLDER_ list _SMARTDATE_("Today" "today" "on -+ _LONGDATE_"):}<BR> If a message is in one of the incoming folders "Lynx" -+ or "pine-info", create a reply-leadin-string that acknowledges that. Note -+ the absence of "," in the function _SMARTDATE_. For example answering to a -+ message in the pine-info list would look like: -+ -+ <P> -+ *** Steve Hubert (hubert@cac.washington.edu) wrote in the pine-info list today: -+ -+ <P> -+ However replying for a message in the Lynx list would look: -+ -+ <P> -+ *** mattack@area.com (mattack@area.com) wrote in the Lynx list today: -+ -+ <P> -+ If you write in more than one language you can use this feature to create -+ Reply-leadin-strings in different languages. -+ -+ <P> Note that at least for people you can create particular -+ reply-leadin-string using the role features, but it does not work as this -+ one does. This seems to be the right way to do it. -+ -+ <P> _FOLDER_ << {Lynx; comp.mail.pine; pine_info; pine-alpha} => -+ _SORT_{OrderedSubj}<BR> This means upon opening, sort the folders "Lynx", -+ "comp.mail.pine", etc in ordered subject. All the others use the default -+ sort order. You can not sort in reverse in this form. The possible -+ arguments of this function are listed in the definition of the -+ default-sort-rule (Arrival, scorE, siZe, etc). -+ -+ <P> The last examples use the function _TRIM_ which has a special form. -+ This function can only be used in the index list. -+ -+ <P> _FOLDER_ << {Lynx} => _SUBJECT_ := _TRIM_{lynx-dev }<BR> In -+ the folder "Lynx" eliminate from the subject the string "lynx-dev " (with -+ the space at the end). For example a message whose subject is "Re: -+ lynx-dev unvisited Visited Links", would be shown in the index with -+ subject: "Re: unvisited Visited Links", making the subject shorter and -+ giving the same information. -+ -+ <P> _FROM_ >> {Name (Comment)} => _FROM_ := -+ _TRIM_{ (Comment)}<BR> Remove the part " (Comment)" -+ from the _FROM_, so when displaying in the index the real From "Name" -+ will appear. -+ -+ <P> _SUBJECT_ == {} => _RESUB_{Re: your mail without subject} -+ If there is no subject in the message, use the subject "Re: your mail -+ wiyhout subject" as a subject for the reply message. -+ -+ <P> You can add more complexity to your rules by checking more than one -+ conditions before a rule is executed. For example: Assume that you want to -+ answer every email that contains the string "bug report", with the subject -+ "Re: About your bug report", you could make -+ -+ <P> -+ _SUBJECT_ == {bug report} => _RESUB_{Re: About your _SUBJECT_} -+ -+ <P> The problem with this construction is that if the person emails you -+ back, then the next time you answer the message the subject will be: "Re: -+ About your Re: About your bug report", so it grew. You may want to avoid -+ this growth by using the following rule: -+ -+ <P> -+ _SUBJECT_ >> {bug report} && _SUBJECT_ !> {Re: } => _RESUB_{Re: About your _SUBJECT_}<BR> -+ -+ <P> -+ which will only add the string "Re: About your" only the first time the -+ message is replied. -+ -+ <P> -+ Say your personal name is "Fred Flinstones", and assume that you don't -+ like to see "To: comp.mail.pine" in every post you make to this newsgroup, -+ but instead would like to see it as everyone else sees it. <BR> -+ _FOLDER_ == {comp.mail.pine} && _FROM_ == {Fred Flinstones} => _FROM_ := _REPLACE_{_FROM_} -+ -+ <P> -+ You can also list your index by nick, in the following way:<BR> -+ _NICK_ != {} => _FROM_ := _REPLACE_{_NICK_} -+ -+ <P> -+ If you want to open the folder "pine-info" in the first non-read message -+ use the rule:<BR> -+ _FOLDER_ == {pine-info} => _STARTUP_{first-unseen} -+ -+ <P> -+ If you want to move your deleted messages to a folder, called "Trash", use -+ the following rule:<BR> -+ _FLAG_ >> {D} -> Trash -+ -+ <P> -+ The reason why the above test is not "_FLAG_ == {D}" is because that would mean -+ that this is the only flag set in the message. It's better to test by containment in this case. -+ -+ <P> If you want to use a specific signature when you are in a specific collection -+ use the following rule:<BR> -+ _COLLECTION_ == {Mail} => _SIGNATURE_{/full/path/to/.signature} -+ -+ <P> Finally about the question of which rule will be executed. Only the -+ first rule that matches will be executed. It is important to notice though -+ that "saving" rules do not compete with "sorting" rules. So the first -+ "saving" rule that matches will be executed in the case of saving and so -+ on. -+ -+ <P> -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL><P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_char_set ===== - <HTML> - <HEAD> -*************** -*** 22592,22597 **** ---- 24028,24070 ---- - <End of help on this topic> - </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> -+ <End of help on this topic> -+ </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 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_thread_display_style_rule ===== -+ <HTML> -+ <HEAD> -+ <TITLE>OPTION: Threading-Display-Style-Rule</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>OPTION: Threading-Display-Style-Rule</H1> -+ -+ This option is very similar to <A HREF="h_config_thread_disp_style"> -+ <!--#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> -+ <End of help on this topic> -+ </BODY> -+ </HTML> -+ ====== h_config_thread_index_style_rule ===== -+ <HTML> -+ <HEAD> -+ <TITLE>OPTION: Threading-Index-Style-Rule</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>OPTION: Threading-Index-Style-Rule</H1> -+ -+ This option is very similar to <A HREF="h_config_thread_index_style"> -+ <!--#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> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_pruning_rule ===== - <HTML> - <HEAD> -*************** -*** 27467,27472 **** ---- 29023,29058 ---- - <End of help on this topic> - </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> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_strip_sigdashes ===== - <HTML> - <HEAD> -*************** -*** 27517,27522 **** ---- 29103,29144 ---- - <End of help on this topic> - </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 "Reply to all -+ recipients?" question. In this case, pressing "p" 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> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_sub_lists ===== - <HTML> - <HEAD> -*************** -*** 27701,27706 **** ---- 29323,29344 ---- - <End of help on this topic> - </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> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_use_sender_not_x ===== - <HTML> - <HEAD> -*************** -*** 28297,28302 **** ---- 29935,30005 ---- - <End of help on this topic> - </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 "S Strip Sig", it means that if you press the letter -+ "S" the signature will be stripped off the message you are -+ replying. Observer that the menu will change to -+ "S No Strip", which means that if you press "S", the -+ signature will not be stripped off from the message. Your choices are -+ activated when you press RETURN. -+ -+ <P> -+ Another way to remember what Pine will do, is that what will be done is -+ exactly the opposite of what you read in the menu. -+ -+ <P> -+ The possible options are: -+ -+ <OL> -+ <LI> 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> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_del_from_dot ===== - <HTML> - <HEAD> -*************** -*** 28820,28825 **** ---- 30523,30560 ---- - <End of help on this topic> - </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 "<" and ">". -+ -+ <P>The normal behavior in Alpine is that if a URL is preceeded by the "<" -+ 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 ">" 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> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_enable_view_addresses ===== - <HTML> - <HEAD> -*************** -*** 29127,29132 **** ---- 30862,30910 ---- - <End of help on this topic> - </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 "#mc/" -+ prefix instead of the "#md/" prefix. If you use this alternate -+ prefix, then this feature applies to you, otherwise you can safely ignore -+ the text that follows. -+ <P> -+ Depending on if you have enabled the option -+ <a href="h_config_separate_fold_dir_view"><!--#echo var="FEAT_separate-folder-and-directory-entries"--></a> -+ a folder may be listed as "folder[.]", or as two entries in the -+ list by "folder" and "folder.". -+ <P> -+ If this option is disabled, Pine will list local folders that are in Courier -+ style format, as "folder", and those that are also directories as -+ "folder[.]". This makes the default display cleaner. -+ <P> -+ If this feature is enabled then creating folders in a maildir collection -+ will create a directory with the same name. If this feature is disabled, then -+ a folder is considered a directory only if it contains subfolders, so you can -+ not create a directory with the same name as an exisiting folder unless -+ you create a subfolder of that folder first (e.g. if you have a folder -+ called "foo" simply add "foo.bar" directly. This will -+ create the directory "foo" and the subfolder "bar" of it). -+ <P> -+ Observe that this feature works only for maildir collections that are accessed -+ locally. If a collection is accessed remotely then this feature has no value, -+ as the report is created in a server, and Pine only reports what received -+ from the server in this case. -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_verbose_post ===== - <HTML> - <HEAD> -*************** -*** 29281,29286 **** ---- 31059,31087 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_auto_read_msgs_rules ===== -+ <HTML> -+ <HEAD> -+ <TITLE>FEATURE: auto-move-read-msgs-using-rules</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>FEATURE: auto-move-read-msgs-using-rules</H1> -+ This feature controls an aspect of Alpine's behavior upon quitting. If set, -+ and the -+ <A HREF="h_config_read_message_folder">"<!--#echo var="VAR_read-message-folder"-->"</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">"<!--#echo var="VAR_save-rules"-->"</A> and mark -+ them as deleted in the INBOX. Messages in the INBOX marked with an -+ "N" (meaning New, or unseen) are not affected. -+ <P> -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL><P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_auto_fcc_only ===== - <HTML> - <HEAD> -*************** -*** 29731,29736 **** ---- 31532,31554 ---- - <End of help on this topic> - </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> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_news_cross_deletes ===== - <HTML> - <HEAD> -*************** -*** 30209,30214 **** ---- 32027,32066 ---- - <End of help on this topic> - </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> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_force_low_speed ===== - <HTML> - <HEAD> -*************** -*** 30479,30484 **** ---- 32331,32357 ---- - <End of help on this topic> - </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">"<!--#echo var="FEAT_auto-open-next-unread"-->"</A>, -+ in the sense that you can use TAB to browse through all of your Incoming -+ Folders checking for new mail. Once it gets to the last folder of the -+ collection it goes back to check again until it returns to the original -+ folder where it started. -+ <UL> -+ <LI><A HREF="h_finding_help">Finding more information and requesting help</A> -+ </UL><P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_auto_include_reply ===== - <HTML> - <HEAD> -*************** -*** 31142,31147 **** ---- 33015,33113 ---- - <End of help on this topic> - </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 "/" or ".") 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 "/" or ".") 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> -+ <End of help on this topic> -+ </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 "/" or ".") 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 "/" or ".") will be added -+ after the name. That -+ indicator will be painted according to the color defined in this -+ option. -+ <P> -+ <End of help on this topic> -+ </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> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_incunseen_color ===== - <HTML> - <HEAD> -*************** -*** 31197,31202 **** ---- 33163,33192 ---- - <End of help on this topic> - </BODY> - </HTML> -+ ====== h_config_special_text_color ===== -+ <HTML> -+ <HEAD> -+ <TITLE>OPTION: Special Text Color</TITLE> -+ </HEAD> -+ <BODY> -+ <H1>OPTION: Special Text Color</H1> -+ -+ Sets the color Pine uses for coloring any text in the body of the message -+ that is not part of a handle (and internal or external link that Pine -+ paints in a different color). By default, this variable is not defined, -+ which means that text that matches the pattern is not painted in any -+ particular way. This variable must be set in a special form if you -+ want text to be painted. -+ -+ <P> -+ <A HREF="h_color_setup">Descriptions of the available commands</A> -+ <P> -+ Look <A HREF="h_edit_nav_cmds">here</A> -+ to see the available Editing and Navigation commands. -+ <P> -+ <End of help on this topic> -+ </BODY> -+ </HTML> - ====== h_config_prompt_color ===== - <HTML> - <HEAD> -*************** -*** 31464,31469 **** ---- 33454,33488 ---- - <End of help on this topic> - </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 "I" <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> -+ <End of help on this topic> -+ </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: |