* clear out some warnings by gcc 9.3.1.
[alpine.git] / pith / conf.c
blobe4f64c717b8afb3e6b7f4572d7a2a6bccbeb69d1
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: conf.c 1266 2009-07-14 18:39:12Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2013-2020 Eduardo Chappa
8 * Copyright 2006-2009 University of Washington
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
19 /*======================================================================
20 conf.c
21 Implements the Pine configuration management routines
22 ====*/
25 #include "../pith/headers.h"
26 #include "../pith/init.h"
27 #include "../pith/conf.h"
28 #include "../pith/state.h"
29 #include "../pith/remote.h"
30 #include "../pith/keyword.h"
31 #include "../pith/mailview.h"
32 #include "../pith/list.h"
33 #include "../pith/status.h"
34 #include "../pith/ldap.h"
35 #include "../pith/folder.h"
36 #include "../pith/thread.h"
37 #include "../pith/news.h"
38 #include "../pith/util.h"
39 #include "../pith/pattern.h"
40 #include "../pith/color.h"
41 #include "../pith/options.h"
42 #include "../pith/busy.h"
43 #include "../pith/readfile.h"
44 #include "../pith/hist.h"
45 #include "../pith/mailindx.h"
46 #include "../pith/tempfile.h"
47 #include "../pith/icache.h"
48 #include "../pith/sort.h"
49 #include "../pith/smime.h"
50 #include "../pith/charconv/utf8.h"
51 #ifdef _WINDOWS
52 #include "../pico/osdep/mswin.h"
53 #endif
55 #define TO_BAIL_THRESHOLD 60
59 * Internal prototypes
61 void convert_configvars_to_utf8(struct variable *, char *);
62 void convert_configvar_to_utf8(struct variable *, char *);
63 void set_current_pattern_vals(struct pine *);
64 void convert_pattern_data(void);
65 void convert_filts_pattern_data(void);
66 void convert_scores_pattern_data(void);
67 void convert_pinerc_patterns(long);
68 void convert_pinerc_filts_patterns(long);
69 void convert_pinerc_scores_patterns(long);
70 void set_old_growth_bits(struct pine *, int);
71 int var_is_in_rest_of_file(char *, char *);
72 char *skip_over_this_var(char *, char *);
73 char *native_nl(char *);
74 void set_color_val(struct variable *, int);
75 int copy_localfile_to_remotefldr(RemType, char *, char *, char *, char **);
76 char *backcompat_convert_from_utf8(char **, size_t, char *);
77 #ifdef _WINDOWS
78 char *transformed_color(char *);
79 int convert_pc_gray_names(struct pine *, PINERC_S *, EditWhich);
80 int unix_color_style_in_pinerc(PINERC_S *);
81 char *pcpine_general_help(char *);
82 char *pcpine_help(HelpType); /* defined in alpine/help */
83 #endif /* _WINDOWS */
86 /* hook too allow caller to decide what to do about failure */
87 int (*pith_opt_remote_pinerc_failure)(void);
90 /*------------------------------------
91 Some definitions to keep the static "variable" array below
92 a bit more readable...
93 ----*/
94 CONF_TXT_T cf_text_comment[] = "#\n# Alpine configuration file\n#\n# This file sets the configuration options used by Alpine and PC-Alpine. These\n# options are usually set from within Alpine or PC-Alpine. There may be a\n# system-wide configuration file which sets the defaults for some of the\n# variables. On Unix, run alpine -conf to see how system defaults have been set.\n# For variables that accept multiple values, list elements are\
95 separated by\n# commas. A line beginning with a space or tab is considered to be a\n# continuation of the previous line. For a variable to be unset its value must\n# be blank. To set a variable to the empty string its value should be \"\".\n# You can override system defaults by setting a variable to the empty string.\n# Lines beginning with \"#\" are comments, and ignored by Alpine.\n";
98 CONF_TXT_T cf_text_personal_name[] = "Over-rides your full name from Unix password file. Required for PC-Alpine.";
100 CONF_TXT_T cf_text_user_id[] = "Your login/e-mail user name";
102 CONF_TXT_T cf_text_user_domain[] = "Sets domain part of From: and local addresses in outgoing mail.";
104 CONF_TXT_T cf_text_smtp_server[] = "List of SMTP servers for sending mail. If blank: Unix Alpine uses sendmail.";
106 CONF_TXT_T cf_text_nntp_server[] = "NNTP server for posting news. Also sets news-collections for news reading.";
108 CONF_TXT_T cf_html_directory[] = "Directory used by Alpine to save copies of html messages before they are\n#opened by an external web browser. The default directory is .alpine-html\n# in unix systems and alpine-html in a windows system.";
110 #ifdef SMIME
112 CONF_TXT_T cf_text_publiccertdir[] = "Public certificates are kept in files in this directory. The files should\n# contain certificates in PEM format. The name of each file should look\n# like <emailaddress>.crt. The default directory is .alpine-smime/public.";
114 CONF_TXT_T cf_text_privatekeydir[] = "Private keys are kept in files in this directory. The files are in PEM format.\n# The name of a file should look like <emailaddress>.key.\n# The default directory is .alpine-smime/private.";
116 CONF_TXT_T cf_text_cacertdir[] = "Certificate Authority certificates (in addition to the normal CACerts for the\n# system) are kept in files in this directory. The files are in PEM format.\n# Filenames should end with .crt. The default directory is .alpine-smime/ca.";
118 CONF_TXT_T cf_text_publiccertcontainer[] = "If this option is set then public certificates are kept in a single container\n# \"file\" similar to a remote configuration file instead of in the\n# smime-publiccert-directory. The value can be a remote or local folder\n# specification like for a non-standard pinerc value. The default\n# is that it is not set.";
120 CONF_TXT_T cf_text_privatekeycontainer[] = "If this option is set then private keys are kept in a single container\n# \"file\" similar to a remote configuration file instead of in the\n# private-key-directory. The value can be a remote or local folder\n# specification like for a non-standard pinerc value. The default\n# is that it is not set.";
122 CONF_TXT_T cf_text_cacertcontainer[] = "If this option is set then CAcerts are kept in a single container\n# \"file\" similar to a remote configuration file instead of in the\n# ca-cert-directory. The value can be a remote or local folder\n# specification like for a non-standard pinerc value. The default\n# is that it is not set.";
124 #endif /* SMIME */
126 #ifdef ENABLE_LDAP
127 CONF_TXT_T cf_text_ldap_server[] = "LDAP servers for looking up addresses.";
128 #endif /* ENABLE_LDAP */
130 CONF_TXT_T cf_text_rss_news[] = "RSS News feed";
132 CONF_TXT_T cf_text_rss_weather[] = "RSS Weather feed";
134 CONF_TXT_T cf_text_wp_indexheight[] = "Web Alpine index table row height";
136 CONF_TXT_T cf_text_wp_indexlines[] = "Web Alpine number of index lines in table";
138 CONF_TXT_T cf_text_wp_aggstate[] = "Web Alpine aggregate operations tab state";
140 CONF_TXT_T cf_text_wp_state[] = "Web Alpine various aspects of cross-session state";
142 CONF_TXT_T cf_text_wp_columns[] = "Web Alpine preferred width for message display in characters";
144 CONF_TXT_T cf_text_inbox_path[] = "Path of (local or remote) INBOX, e.g. ={mail.somewhere.edu}inbox\n# Normal Unix default is the local INBOX (usually /usr/spool/mail/$USER).";
146 CONF_TXT_T cf_text_incoming_folders[] = "List of incoming msg folders besides INBOX, e.g. ={host2}inbox, {host3}inbox\n# Syntax: optnl-label {optnl-imap-host-name}folder-path";
148 CONF_TXT_T cf_text_folder_collections[] = "List of directories where saved-message folders may be. First one is\n# the default for Saves. Example: Main {host1}mail/[], Desktop mail\\[]\n# Syntax: optnl-label {optnl-imap-hostname}optnl-directory-path[]";
150 CONF_TXT_T cf_text_news_collections[] = "List, only needed if nntp-server not set, or news is on a different host\n# than used for NNTP posting. Examples: News *[] or News *{host3/nntp}[]\n# Syntax: optnl-label *{news-host/protocol}[]";
152 CONF_TXT_T cf_text_pruned_folders[] = "List of folders, assumed to be in first folder collection,\n# offered for pruning each month. For example: mumble";
154 CONF_TXT_T cf_text_default_fcc[] = "Over-rides default path for sent-mail folder, e.g. =old-mail (using first\n# folder collection dir) or ={host2}sent-mail or =\"\" (to suppress saving).\n# Default: sent-mail (Unix) or SENTMAIL.MTX (PC) in default folder collection.";
156 CONF_TXT_T cf_text_default_saved[] = "Over-rides default path for saved-msg folder, e.g. =saved-messages (using 1st\n# folder collection dir) or ={host2}saved-mail or =\"\" (to suppress saving).\n# Default: saved-messages (Unix) or SAVEMAIL.MTX (PC) in default collection.";
158 CONF_TXT_T cf_text_postponed_folder[] = "Over-rides default path for postponed messages folder, e.g. =pm (which uses\n# first folder collection dir) or ={host4}pm (using home dir on host4).\n# Default: postponed-msgs (Unix) or POSTPOND.MTX (PC) in default fldr coltn.";
160 CONF_TXT_T cf_text_mail_directory[] = "Alpine compares this value with the first folder collection directory.\n# If they match (or no folder collections are defined), and the directory\n# does not exist, Alpine will create and use it. Default: ~/mail";
162 CONF_TXT_T cf_text_read_message_folder[] = "If set, specifies where already-read messages will be moved upon quitting.";
164 CONF_TXT_T cf_text_form_letter_folder[] = "If set, specifies where form letters should be stored.";
166 CONF_TXT_T cf_text_trash_folder[] = "If set, specifies where trash is moved to in Web Alpine.";
168 CONF_TXT_T cf_text_signature_file[] = "Over-rides default path for signature file. Default is ~/.signature";
170 CONF_TXT_T cf_text_literal_sig[] = "Contains the actual signature contents as opposed to the signature filename.\n# If defined, this overrides the signature-file. Default is undefined.";
172 CONF_TXT_T cf_text_global_address_book[] = "List of file or path names for global/shared addressbook(s).\n# Default: none\n# Syntax: optnl-label path-name";
174 CONF_TXT_T cf_text_address_book[] = "List of file or path names for personal addressbook(s).\n# Default: ~/.addressbook (Unix) or \\PINE\\ADDRBOOK (PC)\n# Syntax: optnl-label path-name";
176 CONF_TXT_T cf_text_feature_list[] = "List of features; see Alpine's Setup/options menu for the current set.\n# e.g. feature-list= select-without-confirm, signature-at-bottom\n# Default condition for all of the features is no-.";
178 CONF_TXT_T cf_text_initial_keystroke_list[] = "Alpine executes these keys upon startup (e.g. to view msg 13: i,j,1,3,CR,v)";
180 CONF_TXT_T cf_text_default_composer_hdrs[] = "Only show these headers (by default) when composing messages";
182 CONF_TXT_T cf_text_customized_hdrs[] = "Add these customized headers (and possible default values) when composing";
184 CONF_TXT_T cf_text_view_headers[] = "When viewing messages, include this list of headers";
186 CONF_TXT_T cf_text_view_margin_left[] = "When viewing messages, number of blank spaces between left display edge and text";
188 CONF_TXT_T cf_text_view_margin_right[] = "When viewing messages, number of blank spaces between right display edge and text";
190 CONF_TXT_T cf_text_quote_suppression[] = "When viewing messages, number of lines of quote displayed before suppressing";
192 CONF_TXT_T cf_text_wordsep[] = "When these characters appear in the middle of a word in the composer\n# the forward word function will stop at the first text following (as happens\n# with SPACE characters by default)";
194 CONF_TXT_T cf_text_color_style[] = "Controls display of color";
196 CONF_TXT_T cf_text_current_indexline_style[] = "Controls display of color for current index line";
198 CONF_TXT_T cf_text_titlebar_color_style[] = "Controls display of color for the titlebar at top of screen";
200 CONF_TXT_T cf_text_view_hdr_color[] = "When viewing messages, these are the header colors";
202 CONF_TXT_T cf_text_index_token_color[] = "Colors in which tokens will be displayed in the index screen";
204 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).";
206 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.)";
208 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\".";
210 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\".";
212 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\".";
214 CONF_TXT_T cf_text_old_char_set[] = "Character-set is obsolete, use display-character-set, keyboard-character-set,\n# and posting-character-set.";
216 CONF_TXT_T cf_text_disp_char_set[] = "Reflects capabilities of the display you have.\n# If unset, the default is taken from your locale. That is usually the right\n# thing to use. Typical alternatives include UTF-8, ISO-8859-x, and EUC-JP\n# (where x is a number between 1 and 9).";
218 CONF_TXT_T cf_text_key_char_set[] = "Reflects capabilities of the keyboard you have.\n# If unset, the default is to use the same value\n# used for the display-character-set.";
220 CONF_TXT_T cf_text_post_character_set[] = "Defaults to UTF-8. This is used for outgoing messages.\n# It is usually correct to leave this unset.";
222 CONF_TXT_T cf_text_unk_character_set[] = "Defaults to nothing, which is equivalent to US-ASCII. This is used for\n# unlabeled incoming messages. It is ok to leave this unset but if you receive\n# unlabeled mail that is usually in some known character set, set that here.";
224 CONF_TXT_T cf_text_editor[] = "Specifies the program invoked by ^_ in the Composer,\n# or the \"enable-alternate-editor-implicitly\" feature.";
226 CONF_TXT_T cf_text_speller[] = "Specifies the program invoked by ^T in the Composer.";
228 #ifdef _WINDOWS
229 CONF_TXT_T cf_text_speller_dictionary[] = "Specifies the list of dictionaries used by Aspell.";
230 #endif /* _WINDOWS */
232 CONF_TXT_T cf_text_deadlets[] = "Specifies the number of dead letter files to keep when canceling.";
234 CONF_TXT_T cf_text_fillcol[] = "Specifies the column of the screen where the composer should wrap.";
236 CONF_TXT_T cf_text_replystr[] = "Specifies the string to insert when replying to a message.";
238 CONF_TXT_T cf_text_quotereplstr[] = "Specifies the string to replace quotes with when viewing a message.";
240 CONF_TXT_T cf_text_replyintro[] = "Specifies the introduction to insert when replying to a message.";
242 CONF_TXT_T cf_text_emptyhdr[] = "Specifies the string to use when sending a message with no to or cc.";
244 CONF_TXT_T cf_text_image_viewer[] = "Program to view images (e.g. GIF or TIFF attachments).";
246 CONF_TXT_T cf_text_browser[] = "List of programs to open Internet URLs (e.g. http or ftp references).";
248 CONF_TXT_T cf_text_history[] = "List of directories that are preferred locations to save or export attachments.";
250 CONF_TXT_T cf_text_inc_startup[] = "Sets message which cursor begins on. Choices: first-unseen, first-recent,\n# first-important, first-important-or-unseen, first-important-or-recent,\n# first, last. Default: \"first-unseen\".";
252 CONF_TXT_T cf_pruning_rule[] = "Allows a default answer for the prune folder questions. Choices: yes-ask,\n# yes-no, no-ask, no-no, ask-ask, ask-no. Default: \"ask-ask\".";
254 CONF_TXT_T cf_reopen_rule[] = "Controls behavior when reopening an already open folder.";
256 CONF_TXT_T cf_text_thread_disp_style[] = "Style that MESSAGE INDEX is displayed in when threading.";
258 CONF_TXT_T cf_text_thread_index_style[] = "Style of THREAD INDEX or default MESSAGE INDEX when threading.";
260 CONF_TXT_T cf_text_thread_more_char[] = "When threading, character used to indicate collapsed messages underneath.";
262 CONF_TXT_T cf_text_thread_exp_char[] = "When threading, character used to indicate expanded messages underneath.";
264 CONF_TXT_T cf_text_thread_lastreply_char[] = "When threading, character used to indicate this is the last reply\n# to the parent of this message.";
266 CONF_TXT_T cf_text_use_only_domain_name[] = "If \"user-domain\" not set, strips hostname in FROM address. (Unix only)";
268 CONF_TXT_T cf_text_printer[] = "Your default printer selection";
270 CONF_TXT_T cf_text_personal_print_command[] = "List of special print commands";
272 CONF_TXT_T cf_text_personal_print_cat[] = "Which category default print command is in";
274 CONF_TXT_T cf_text_standard_printer[] = "The system wide standard printers";
276 CONF_TXT_T cf_text_xoauth2_info[] = "Your client-id and client-secret information to authenticate using XOAUTH2";
278 CONF_TXT_T cf_text_last_time_prune_quest[] = "Set by Alpine; controls beginning-of-month sent-mail pruning.";
280 CONF_TXT_T cf_text_last_version_used[] = "Set by Alpine; controls display of \"new version\" message.";
282 CONF_TXT_T cf_text_disable_drivers[] = "List of mail drivers to disable.";
284 CONF_TXT_T cf_text_disable_auths[] = "List of SASL authenticators to disable.";
286 CONF_TXT_T cf_text_encryption_range[] = "A range in the form min,max that sets the minimum amd maximum versions of the\n# SSL protocol that Alpine will use when connecting to a secure server.";
288 CONF_TXT_T cf_text_remote_abook_metafile[] = "Set by Alpine; contains data for caching remote address books.";
290 CONF_TXT_T cf_text_old_patterns[] = "Patterns is obsolete, use patterns-xxx";
292 CONF_TXT_T cf_text_old_filters[] = "Patterns-filters is obsolete, use patterns-filters2";
294 CONF_TXT_T cf_text_old_scores[] = "Patterns-scores is obsolete, use patterns-scores2";
296 CONF_TXT_T cf_text_patterns[] = "Patterns and their actions are stored here.";
298 CONF_TXT_T cf_text_remote_abook_history[] = "How many extra copies of remote address book should be kept. Default: 3";
300 CONF_TXT_T cf_text_remote_abook_validity[] = "Minimum number of minutes between checks for remote address book changes.\n# 0 means never check except when opening a remote address book.\n# -1 means never check. Default: 5";
302 CONF_TXT_T cf_text_bugs_fullname[] = "Full name for bug report address used by \"Report Bug\" command";
304 CONF_TXT_T cf_text_bugs_address[] = "Email address used to send bug reports";
306 CONF_TXT_T cf_text_bugs_extras[] = "Program/Script used by \"Report Bug\" command. No default.";
308 CONF_TXT_T cf_text_suggest_fullname[] = "Full name for suggestion address used by \"Report Bug\" command";
310 CONF_TXT_T cf_text_suggest_address[] = "Email address used to send suggestions";
312 CONF_TXT_T cf_text_local_fullname[] = "Full name for \"local support\" address used by \"Report Bug\" command.\n# Default: Local Support";
314 CONF_TXT_T cf_text_local_address[] = "Email address used to send to \"local support\".\n# Default: postmaster";
316 CONF_TXT_T cf_text_forced_abook[] = "Force these address book entries into all writable personal address books.\n# Syntax is forced-abook-entry=nickname|fullname|address\n# This is a comma-separated list of entries, each with syntax above.\n# Existing entries with same nickname are not replaced.\n# Example: help|Help Desk|help@ourdomain.com";
318 CONF_TXT_T cf_text_kblock_passwd[] = "This is a number between 1 and 5. It is the number of times a user will\n# have to enter a password when they run the keyboard lock command in the\n# main menu. Default is 1.";
320 CONF_TXT_T cf_text_sendmail_path[] = "This names the path to an alternative program, and any necessary arguments,\n# to be used in posting mail messages. Example:\n# /usr/lib/sendmail -oem -t -oi\n# or,\n# /usr/local/bin/sendit.sh\n# The latter a script found in Alpine distribution's contrib/util directory.\n# NOTE: The program MUST read the message to be posted on standard input,\n# AND operate in the style of sendmail's \"-t\" option.";
322 CONF_TXT_T cf_text_oper_dir[] = "This names the root of the tree to which the user is restricted when reading\n# and writing folders and files. For example, on Unix ~/work confines the\n# user to the subtree beginning with their work subdirectory.\n# (Note: this alone is not sufficient for preventing access. You will also\n# need to restrict shell access and so on, see Alpine Technical Notes.)\n# Default: not set (so no restriction)";
324 CONF_TXT_T cf_text_in_fltr[] = "This variable takes a list of programs that message text is piped into\n# after MIME decoding, prior to display.";
326 CONF_TXT_T cf_text_out_fltr[] = "This defines a program that message text is piped into before MIME\n# encoding, prior to sending";
328 CONF_TXT_T cf_text_alt_addrs[] = "A list of alternate addresses the user is known by";
330 CONF_TXT_T cf_text_keywords[] = "A list of keywords for use in categorizing messages";
332 CONF_TXT_T cf_text_kw_colors[] = "Colors used to display keywords in the index";
334 CONF_TXT_T cf_text_kw_braces[] = "Characters which surround keywords in SUBJKEY token.\n# Default is \"{\" \"} \"";
336 CONF_TXT_T cf_text_opening_sep[] = "Characters between subject and opening text in SUBJECTTEXT token.\n# Default is \" - \"";
338 CONF_TXT_T cf_text_abook_formats[] = "This is a list of formats for address books. Each entry in the list is made\n# up of space-delimited tokens telling which fields are displayed and in\n# which order. See help text";
340 CONF_TXT_T cf_text_index_format[] = "This gives a format for displaying the index. It is made\n# up of space-delimited tokens telling which fields are displayed and in\n# which order. See help text";
342 CONF_TXT_T cf_text_overlap[] = "The number of lines of overlap when scrolling through message text";
344 CONF_TXT_T cf_text_maxremstreams[] = "The maximum number of non-stayopen remote connections that Alpine will use";
346 CONF_TXT_T cf_text_permlocked[] = "A list of folders that should be left open once opened (INBOX is implicit)";
348 CONF_TXT_T cf_text_margin[] = "Number of lines from top and bottom of screen where single\n# line scrolling occurs.";
350 CONF_TXT_T cf_text_stat_msg_delay[] = "The number of seconds to sleep after writing a status message";
352 CONF_TXT_T cf_text_busy_cue_rate[] = "Number of times per-second to update busy cue messages";
354 CONF_TXT_T cf_text_mailcheck[] = "The approximate number of seconds between checks for new mail";
356 CONF_TXT_T cf_text_mailchecknoncurr[] = "The approximate number of seconds between checks for new mail in folders\n# other than the current folder and inbox.\n# Default is same as mail-check-interval";
358 CONF_TXT_T cf_text_maildropcheck[] = "The minimum number of seconds between checks for new mail in a Mail Drop.\n# This is always effectively at least as large as the mail-check-interval";
360 CONF_TXT_T cf_text_nntprange[] = "For newsgroups accessed using NNTP, only messages numbered in the range\n# lastmsg-range+1 to lastmsg will be considered";
362 CONF_TXT_T cf_text_news_active[] = "Path and filename of news configuration's active file.\n# The default is typically \"/usr/lib/news/active\".";
364 CONF_TXT_T cf_text_news_spooldir[] = "Directory containing system's news data.\n# The default is typically \"/usr/spool/news\"";
366 CONF_TXT_T cf_text_upload_cmd[] = "Path and filename of the program used to upload text from your terminal\n# emulator's into Alpine's composer.";
368 CONF_TXT_T cf_text_upload_prefix[] = "Text sent to terminal emulator prior to invoking the program defined by\n# the upload-command variable.\n# Note: _FILE_ will be replaced with the temporary file used in the upload.";
370 CONF_TXT_T cf_text_download_cmd[] = "Path and filename of the program used to download text via your terminal\n# emulator from Alpine's export and save commands.";
372 CONF_TXT_T cf_text_download_prefix[] = "Text sent to terminal emulator prior to invoking the program defined by\n# the download-command variable.\n# Note: _FILE_ will be replaced with the temporary file used in the download.";
374 CONF_TXT_T cf_text_goto_default[] = "Sets the default folder and collection offered at the Goto Command's prompt.";
376 CONF_TXT_T cf_text_mailcap_path[] = "Sets the search path for the mailcap configuration file.\n# NOTE: colon delimited under UNIX, semi-colon delimited under DOS/Windows/OS2.";
378 CONF_TXT_T cf_text_mimetype_path[] = "Sets the search path for the mimetypes configuration file.\n# NOTE: colon delimited under UNIX, semi-colon delimited under DOS/Windows/OS2.";
380 #if !defined(_WINDOWS) || defined(WINDOWS_UNIXSSL_CERTS)
381 CONF_TXT_T cf_text_system_certs_path[] = "Sets the path for the system ssl certificates issued by a trusted\n# certificate authority. Note that this could be a list of paths, if the same\n# pinerc is used in different systems. Alpine always chooses the first one that\n# it finds. Value must be an absolute path.";
383 CONF_TXT_T cf_text_system_certs_file[] = "Sets the path for the system ssl file container of certificates issued by a\n# certificate authority. Note that this could be a list of container files,\n# if the same pinerc is used in different systems. Alpine always chooses the,\n# first one that it finds. Value must be an absolute path.";
385 CONF_TXT_T cf_text_user_certs_path[] = "Sets the path for additional ssl certificates that the user trusts. Note\n#that this could be a list of paths, if the same\n# pinerc is used in different systems. Alpine always chooses the first one that\n# it finds. Value must be an absolute path.";
387 CONF_TXT_T cf_text_user_certs_file[] = "Sets the path for a file that contains certificates that a user trusts.\nNote that this could be a list of container files,\n# if the same pinerc is used in different systems. Alpine always chooses the,\n# first one that it finds. Value must be an absolute path.";
388 #endif
390 CONF_TXT_T cf_text_newmail_fifo_path[] = "Sets the filename for the newmail fifo (named pipe). Unix only.";
392 CONF_TXT_T cf_text_nmw_width[] = "Sets the width for the NewMail screen.";
394 CONF_TXT_T cf_text_user_input_timeo[] = "If no user input for this many hours, Alpine will exit if in an idle loop\n# waiting for a new command. If set to zero (the default), then there will\n# be no timeout.";
396 CONF_TXT_T cf_text_debug_mem[] = "Debug-memory is obsolete";
398 CONF_TXT_T cf_text_tcp_open_timeo[] = "Sets the time in seconds that Alpine will attempt to open a network\n# connection. The default is 30, the minimum is 5, and the maximum is\n# system defined (typically 75).";
400 CONF_TXT_T cf_text_tcp_read_timeo[] = "Network read warning timeout. The default is 15, the minimum is 5, and the\n# maximum is 1000.";
402 CONF_TXT_T cf_text_tcp_write_timeo[] = "Network write warning timeout. The default is 0 (unset), the minimum\n# is 5 (if not 0), and the maximum is 1000.";
404 CONF_TXT_T cf_text_tcp_query_timeo[] = "If this much time has elapsed at the time of a tcp read or write\n# timeout, Alpine will ask if you want to break the connection.\n# Default is 60 seconds, minimum is 5, maximum is 1000.";
406 CONF_TXT_T cf_text_close_connection_timeo[] = "If this much time has elapsed at the time of a tcp read or write timeout,\n# Alpine will close the connection automatically without user intervention.\n# Setting this value to zero (the default) disables this. Setting this variable\n# to a smaller value than tcp-query-timeout will close the connection\n# automatically, and you will never be asked if you want to wait.";
408 CONF_TXT_T cf_text_rsh_open_timeo[] = "Sets the time in seconds that Alpine will attempt to open a UNIX remote\n# shell connection. The default is 15, min is 5, and max is unlimited.\n# Zero disables rsh altogether.";
410 CONF_TXT_T cf_text_rsh_path[] = "Sets the name of the command used to open a UNIX remote shell connection.\n# The default is typically /usr/ucb/rsh.";
412 CONF_TXT_T cf_text_rsh_command[] = "Sets the format of the command used to open a UNIX remote\n# shell connection. The default is \"%s %s -l %s exec /etc/r%sd\"\n# NOTE: the 4 (four) \"%s\" entries MUST exist in the provided command\n# where the first is for the command's path, the second is for the\n# host to connect to, the third is for the user to connect as, and the\n# fourth is for the connection method (typically \"imap\")";
414 CONF_TXT_T cf_text_ssh_open_timeo[] = "Sets the time in seconds that Alpine will attempt to open a UNIX secure\n# shell connection. The default is 15, min is 5, and max is unlimited.\n# Zero disables ssh altogether.";
416 CONF_TXT_T cf_text_inc_check_timeo[] = "Sets the time in seconds that Alpine will attempt to open a network\n# connection when checking for new unseen messages in an incoming folder.\n# The default is 5.";
418 CONF_TXT_T cf_text_inc_check_interval[] = "Sets the approximate number of seconds between checks for unseen messages\n# in incoming folders. The default is 180.";
420 CONF_TXT_T cf_text_inc_second_check_interval[] = "Sets the approximate number of seconds between checks for unseen messages\n# for other than local or IMAP folders. The default is 180.";
422 CONF_TXT_T cf_text_inc_check_list[] = "List of incoming folders to check for unseen messages. The default if left\n# blank is to check all incoming folders.";
424 CONF_TXT_T cf_text_ssh_path[] = "Sets the name of the command used to open a UNIX secure shell connection.\n# Typically this is /usr/bin/ssh.";
426 CONF_TXT_T cf_text_ssh_command[] = "Sets the format of the command used to open a UNIX secure\n# shell connection. The default is \"%s %s -l %s exec /etc/r%sd\"\n# NOTE: the 4 (four) \"%s\" entries MUST exist in the provided command\n# where the first is for the command's path, the second is for the\n# host to connect to, the third is for the user to connect as, and the\n# fourth is for the connection method (typically \"imap\")";
428 CONF_TXT_T cf_text_version_threshold[] = "Sets the version number Alpine will use as a threshold for offering\n# its new version message on startup.";
430 CONF_TXT_T cf_text_archived_folders[] = "List of folder pairs; the first indicates a folder to archive, and the\n# second indicates the folder read messages in the first should\n# be moved to.";
432 CONF_TXT_T cf_text_elm_style_save[] = "Elm-style-save is obsolete, use saved-msg-name-rule";
434 CONF_TXT_T cf_text_header_in_reply[] = "Header-in-reply is obsolete, use include-header-in-reply in feature-list";
436 CONF_TXT_T cf_text_feature_level[] = "Feature-level is obsolete, use feature-list";
438 CONF_TXT_T cf_text_old_style_reply[] = "Old-style-reply is obsolete, use signature-at-bottom in feature-list";
440 CONF_TXT_T cf_text_compose_mime[] = "Compose-mime is obsolete";
442 CONF_TXT_T cf_text_show_all_characters[] = "Show-all-characters is obsolete";
444 CONF_TXT_T cf_text_save_by_sender[] = "Save-by-sender is obsolete, use saved-msg-name-rule";
446 CONF_TXT_T cf_text_file_dir[] = "Default directory used for Attachment handling (attach and save)\n# and Export command output";
448 CONF_TXT_T cf_text_folder_extension[] = "Folder-extension is obsolete";
450 CONF_TXT_T cf_text_normal_foreground_color[] = "Choose: black, blue, green, cyan, red, magenta, yellow, or white.";
452 CONF_TXT_T cf_text_window_position[] = "Window position in the format: CxR+X+Y\n# Where C and R are the window size in characters and X and Y are the\n# screen position of the top left corner of the window.\n# This is no longer used unless position is not set in registry.";
454 CONF_TXT_T cf_text_newsrc_path[] = "Full path and name of NEWSRC file";
457 /*----------------------------------------------------------------------
458 These are the variables that control a number of pine functions. They
459 come out of the .pinerc and the /usr/local/lib/pine.conf files. Some can
460 be set by the user while in Alpine. Eventually all the local ones should
461 be so and maybe the global ones too.
463 Each variable can have a command-line, user, global, and current value.
464 All of these values are malloc'd. The user value is the one read out of
465 the user's .pinerc, the global value is the one from the system pine
466 configuration file. There are often defaults for the global values, set
467 at the start of init_vars(). Perhaps someday there will be group values.
468 The current value is the one that is actually in use.
469 ----*/
470 /* name is_changed_val
471 remove_quotes |
472 is_outermost | |
473 is_onlymain | | |
474 is_fixed | | | |
475 is_list | | | | |
476 is_global | | | | | |
477 is_user | | | | | | |
478 been_written | | | | | | | |
479 is_used | | | | | | | | |
480 is_obsolete | | | | | | | | | |
481 | | | | | | | | | | |
482 (on following line) description | | | | | | | | | | |
483 | | | | | | | | | | | |
484 | | | | | | | | | | | | */
485 static struct variable variables[] = {
486 {"personal-name", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
487 NULL, cf_text_personal_name},
489 #if defined(DOS) || defined(OS2)
490 /* Have to have this on DOS, PC's, Macs, etc... */
491 "user-id", 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
492 #else /* Don't allow on UNIX machines for some security */
493 "user-id", 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
494 #endif
495 "User ID", cf_text_user_id},
496 {"user-domain", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
497 NULL, cf_text_user_domain},
498 {"smtp-server", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
499 "SMTP Server (for sending)", cf_text_smtp_server},
500 {"nntp-server", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
501 "NNTP Server (for news)", cf_text_nntp_server},
502 {"inbox-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
503 NULL, cf_text_inbox_path},
504 {"incoming-archive-folders", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
505 NULL, cf_text_archived_folders},
506 {"pruned-folders", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
507 NULL, cf_text_pruned_folders},
508 {"default-fcc", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
509 "Default Fcc (File carbon copy)", cf_text_default_fcc},
510 {"default-saved-msg-folder", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
511 "Default Saved Message Folder", cf_text_default_saved},
512 {"postponed-folder", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
513 NULL, cf_text_postponed_folder},
514 {"read-message-folder", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
515 NULL, cf_text_read_message_folder},
516 {"form-letter-folder", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
517 NULL, cf_text_form_letter_folder},
518 {"trash-folder", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
519 NULL, cf_text_trash_folder},
520 {"literal-signature", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
521 NULL, cf_text_literal_sig},
522 {"signature-file", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
523 NULL, cf_text_signature_file},
524 {"feature-list", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
525 NULL, cf_text_feature_list},
526 {"initial-keystroke-list", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
527 NULL, cf_text_initial_keystroke_list},
528 {"default-composer-hdrs", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
529 "Default Composer Headers", cf_text_default_composer_hdrs},
530 {"customized-hdrs", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
531 "Customized Headers", cf_text_customized_hdrs},
532 {"viewer-hdrs", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
533 "Viewer Headers", cf_text_view_headers},
534 {"viewer-margin-left", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
535 NULL, cf_text_view_margin_left},
536 {"viewer-margin-right", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
537 NULL, cf_text_view_margin_right},
538 {"quote-suppression-threshold", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
539 NULL, cf_text_quote_suppression},
540 {"saved-msg-name-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
541 "Saved Message Name Rule", cf_text_save_msg_name_rule},
542 {"fcc-name-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
543 NULL, cf_text_fcc_name_rule},
544 {"sort-key", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
545 NULL, cf_text_sort_key},
546 {"addrbook-sort-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
547 "Address Book Sort Rule", cf_text_addrbook_sort_rule},
548 {"folder-sort-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
549 NULL, cf_text_folder_sort_rule},
550 {"goto-default-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
551 NULL, cf_text_goto_default},
552 {"incoming-startup-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
553 NULL, cf_text_inc_startup},
554 {"pruning-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
555 NULL, cf_pruning_rule},
556 {"folder-reopen-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
557 NULL, cf_reopen_rule},
558 {"threading-display-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
559 NULL, cf_text_thread_disp_style},
560 {"threading-index-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
561 NULL, cf_text_thread_index_style},
562 {"threading-indicator-character", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
563 NULL, cf_text_thread_more_char},
564 {"threading-expanded-character", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
565 NULL, cf_text_thread_exp_char},
566 {"threading-lastreply-character", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
567 "Threading Last Reply Character", cf_text_thread_lastreply_char},
568 #ifndef _WINDOWS
569 {"display-character-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
570 NULL, cf_text_disp_char_set},
571 {"character-set", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
572 NULL, cf_text_old_char_set},
573 {"keyboard-character-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
574 NULL, cf_text_key_char_set},
575 #endif /* ! _WINDOWS */
576 {"posting-character-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
577 NULL, cf_text_post_character_set},
578 {"unknown-character-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
579 NULL, cf_text_unk_character_set},
580 {"editor", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
581 NULL, cf_text_editor},
582 {"speller", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
583 NULL, cf_text_speller},
584 #ifdef _WINDOWS
585 {"aspell-dictionary-list", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
586 "Aspell Dictionaries", cf_text_speller_dictionary},
587 #endif /* _WINDOWS */
588 {"composer-wrap-column", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
589 NULL, cf_text_fillcol},
590 {"reply-indent-string", 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
591 NULL, cf_text_replystr},
592 {"reply-leadin", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
593 NULL, cf_text_replyintro},
594 {"quote-replace-string", 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
595 NULL, cf_text_quotereplstr},
596 {"composer-word-separators", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
597 NULL, cf_text_wordsep},
598 {"empty-header-message", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
599 NULL, cf_text_emptyhdr},
600 {"image-viewer", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
601 NULL, cf_text_image_viewer},
602 {"use-only-domain-name", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
603 NULL, cf_text_use_only_domain_name},
604 {"bugs-fullname", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
605 NULL, cf_text_bugs_fullname},
606 {"bugs-address", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
607 NULL, cf_text_bugs_address},
608 {"bugs-additional-data", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
609 NULL, cf_text_bugs_extras},
610 {"suggest-fullname", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
611 NULL, cf_text_suggest_fullname},
612 {"suggest-address", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
613 NULL, cf_text_suggest_address},
614 {"local-fullname", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
615 NULL, cf_text_local_fullname},
616 {"local-address", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
617 NULL, cf_text_local_address},
618 {"forced-abook-entry", 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0,
619 NULL, cf_text_forced_abook},
620 {"kblock-passwd-count", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
621 NULL, cf_text_kblock_passwd},
622 {"display-filters", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
623 NULL, cf_text_in_fltr},
624 {"sending-filters", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
625 NULL, cf_text_out_fltr},
626 {"alt-addresses", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
627 "Alternate Addresses", cf_text_alt_addrs},
628 {"keywords", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
629 NULL, cf_text_keywords},
630 {"keyword-surrounding-chars", 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
631 "Keyword Surrounding Characters", cf_text_kw_braces},
632 {"opening-text-separator-chars", 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
633 "Opening Text Separator Characters", cf_text_opening_sep},
634 {"addressbook-formats", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
635 "Address Book Formats", cf_text_abook_formats},
636 {"index-format", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
637 NULL, cf_text_index_format},
638 {"viewer-overlap", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
639 NULL, cf_text_overlap},
640 {"scroll-margin", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
641 NULL, cf_text_margin},
642 {"status-message-delay", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
643 NULL, cf_text_stat_msg_delay},
644 {"busy-cue-rate", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
645 NULL, cf_text_busy_cue_rate},
646 {"mail-check-interval", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
647 NULL, cf_text_mailcheck},
648 {"mail-check-interval-noncurrent", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
649 NULL, cf_text_mailchecknoncurr},
650 {"maildrop-check-minimum", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
651 NULL, cf_text_maildropcheck},
652 {"nntp-range", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
653 "NNTP Range", cf_text_nntprange},
654 {"newsrc-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
655 NULL, cf_text_newsrc_path},
656 {"news-active-file-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
657 NULL, cf_text_news_active},
658 {"news-spool-directory", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
659 NULL, cf_text_news_spooldir},
660 {"upload-command", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
661 NULL, cf_text_upload_cmd},
662 {"upload-command-prefix", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
663 NULL, cf_text_upload_prefix},
664 {"download-command", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
665 NULL, cf_text_download_cmd},
666 {"download-command-prefix", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
667 NULL, cf_text_download_prefix},
668 {"mailcap-search-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
669 NULL, cf_text_mailcap_path},
670 {"mimetype-search-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
671 NULL, cf_text_mimetype_path},
672 #if !defined(_WINDOWS) || defined(WINDOWS_UNIXSSL_CERTS)
673 {"system-certs-path", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
674 "System CACerts Dir", cf_text_system_certs_path},
675 {"system-certs-file", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
676 "System CACerts File", cf_text_system_certs_file},
677 {"user-certs-path", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
678 "User Certs Dir", cf_text_user_certs_file},
679 {"user-certs-file", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
680 "User Certs File", cf_text_user_certs_file},
681 #endif
682 {"url-viewers", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
683 "URL-Viewers", cf_text_browser},
684 {"default-directories", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
685 "Extra Directories for Save", cf_text_history},
686 {"max-remote-connections", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
687 "Maximum Remote Connections", cf_text_maxremstreams},
688 {"stay-open-folders", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
689 "Stayopen Folders", cf_text_permlocked},
690 {"incoming-check-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
691 NULL, cf_text_inc_check_timeo},
692 {"incoming-check-interval", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
693 NULL, cf_text_inc_check_interval},
694 {"incoming-check-interval-secondary", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
695 NULL, cf_text_inc_second_check_interval},
696 {"incoming-check-list", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
697 NULL, cf_text_inc_check_list},
698 {"dead-letter-files", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
699 NULL, cf_text_deadlets},
700 #if !defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO)
701 {"newmail-fifo-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
702 "NewMail FIFO Path", cf_text_newmail_fifo_path},
703 #endif
704 {"newmail-window-width", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
705 "NewMail Window Width", cf_text_nmw_width},
707 * Starting here, the variables are hidden in the Setup/Config screen.
708 * They are exposed if feature expose-hidden-config is set.
710 {"incoming-folders", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
711 NULL, cf_text_incoming_folders},
712 {"mail-directory", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
713 NULL, cf_text_mail_directory},
714 {"folder-collections", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
715 NULL, cf_text_folder_collections},
716 {"news-collections", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
717 NULL, cf_text_news_collections},
718 {"address-book", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
719 NULL, cf_text_address_book},
720 {"global-address-book", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
721 NULL, cf_text_global_address_book},
722 {"standard-printer", 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0,
723 NULL, cf_text_standard_printer},
724 {"last-time-prune-questioned", 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0,
725 NULL, cf_text_last_time_prune_quest},
726 {"last-version-used", 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0,
727 NULL, cf_text_last_version_used},
728 {"sendmail-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
729 NULL, cf_text_sendmail_path},
730 {"operating-dir", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
731 NULL, cf_text_oper_dir},
732 {"user-input-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
733 NULL, cf_text_user_input_timeo},
734 /* OBSOLETE */
735 #ifdef DEBUGJOURNAL
736 {"debug-memory", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
737 NULL, cf_text_debug_mem},
738 #endif
739 {"tcp-open-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
740 "TCP Open Timeout", cf_text_tcp_open_timeo},
741 {"tcp-read-warning-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
742 "TCP Read Warning Timeout", cf_text_tcp_read_timeo},
743 {"tcp-write-warning-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
744 "TCP Write Warning Timeout", cf_text_tcp_write_timeo},
745 {"tcp-query-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
746 "TCP Query Timeout", cf_text_tcp_query_timeo},
747 {"close-connection-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
748 NULL, cf_text_close_connection_timeo},
749 {"rsh-command", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
750 NULL, cf_text_rsh_command},
751 {"rsh-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
752 NULL, cf_text_rsh_path},
753 {"rsh-open-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
754 NULL, cf_text_rsh_open_timeo},
755 {"ssh-command", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
756 NULL, cf_text_ssh_command},
757 {"ssh-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
758 NULL, cf_text_ssh_path},
759 {"ssh-open-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
760 NULL, cf_text_ssh_open_timeo},
761 {"new-version-threshold", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
762 NULL, cf_text_version_threshold},
763 {"disable-these-drivers", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
764 NULL, cf_text_disable_drivers},
765 {"disable-these-authenticators", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
766 NULL, cf_text_disable_auths},
767 {"encryption-protocol-range", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
768 NULL, cf_text_encryption_range},
769 {"remote-abook-metafile", 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0,
770 NULL, cf_text_remote_abook_metafile},
771 {"remote-abook-history", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
772 NULL, cf_text_remote_abook_history},
773 {"remote-abook-validity", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
774 NULL, cf_text_remote_abook_validity},
775 {"printer", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
776 NULL, cf_text_printer},
777 {"personal-print-command", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
778 NULL, cf_text_personal_print_command},
779 {"personal-print-category", 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
780 NULL, cf_text_personal_print_cat},
781 {"xoauth2-info", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
782 "XOAUTH2 Info", cf_text_xoauth2_info},
783 {"patterns", 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
784 NULL, cf_text_old_patterns},
785 {"patterns-roles", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
786 NULL, cf_text_patterns},
787 {"patterns-filters2", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
788 "Patterns Filters", cf_text_patterns},
789 {"patterns-filters", 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
790 NULL, cf_text_old_filters},
791 {"patterns-scores2", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
792 "Patterns Scores", cf_text_patterns},
793 {"patterns-scores", 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
794 NULL, cf_text_old_scores},
795 {"patterns-indexcolors", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
796 NULL, cf_text_patterns},
797 {"patterns-other", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
798 NULL, cf_text_patterns},
799 {"patterns-search", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
800 NULL, cf_text_patterns},
801 /* OBSOLETE VARS */
802 {"elm-style-save", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
803 NULL, cf_text_elm_style_save},
804 {"header-in-reply", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
805 NULL, cf_text_header_in_reply},
806 {"feature-level", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
807 NULL, cf_text_feature_level},
808 {"old-style-reply", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
809 NULL, cf_text_old_style_reply},
810 {"compose-mime", 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
811 NULL, cf_text_compose_mime},
812 {"show-all-characters", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
813 NULL, cf_text_show_all_characters},
814 {"save-by-sender", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
815 NULL, cf_text_save_by_sender},
816 #if defined(DOS) || defined(OS2)
817 {"file-directory", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
818 NULL, cf_text_file_dir},
819 {"folder-extension", 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0,
820 NULL, cf_text_folder_extension},
821 #endif
822 #ifndef _WINDOWS
823 {"color-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
824 NULL, cf_text_color_style},
825 #endif
826 {"current-indexline-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
827 NULL, cf_text_current_indexline_style},
828 {"titlebar-color-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
829 NULL, cf_text_titlebar_color_style},
830 {"normal-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
831 NULL, cf_text_normal_foreground_color},
832 {"normal-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
833 {"reverse-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
834 {"reverse-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
835 {"title-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
836 {"title-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
837 {"title-closed-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
838 {"title-closed-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
839 {"folder-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
840 {"folder-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
841 {"directory-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
842 {"directory-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
843 {"folder-list-text-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
844 {"folder-list-text-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
845 {"status-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
846 {"status-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
847 {"keylabel-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
848 {"keylabel-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
849 {"keyname-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
850 {"keyname-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
851 {"selectable-item-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
852 {"selectable-item-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
853 {"meta-message-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
854 {"meta-message-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
855 {"quote1-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
856 {"quote1-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
857 {"quote2-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
858 {"quote2-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
859 {"quote3-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
860 {"quote3-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
861 {"incoming-unseen-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
862 {"incoming-unseen-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
863 {"signature-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
864 {"signature-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
865 {"prompt-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
866 {"prompt-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
867 {"header-general-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
868 {"header-general-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
869 {"index-to-me-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
870 {"index-to-me-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
871 {"index-important-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
872 {"index-important-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
873 {"index-deleted-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
874 {"index-deleted-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
875 {"index-answered-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
876 {"index-answered-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
877 {"index-new-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
878 {"index-new-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
879 {"index-recent-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
880 {"index-recent-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
881 {"index-forward-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
882 {"index-forward-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
883 {"index-unseen-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
884 {"index-unseen-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
885 {"index-highpriority-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
886 {"index-highpriority-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
887 {"index-lowpriority-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
888 {"index-lowpriority-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
889 {"index-arrow-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
890 {"index-arrow-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
891 {"index-subject-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
892 {"index-subject-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
893 {"index-from-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
894 {"index-from-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
895 {"index-opening-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
896 {"index-opening-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
897 {"index-token-colors", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
898 NULL, cf_text_index_token_color},
899 {"viewer-hdr-colors", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
900 "Viewer Header Colors", cf_text_view_hdr_color},
901 {"keyword-colors", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
902 NULL, cf_text_kw_colors},
903 #ifdef _WINDOWS
904 {"font-name", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
905 NULL, "name and size of font."},
906 {"font-size", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
907 {"font-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
908 {"font-char-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
909 {"print-font-name", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
910 NULL, "name and size of printer font."},
911 {"print-font-size", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
912 {"print-font-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
913 {"print-font-char-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
914 {"window-position", 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0,
915 NULL, cf_text_window_position},
916 {"cursor-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
917 #endif /* _WINDOWS */
918 {"html-messages-directory", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
919 NULL, cf_html_directory},
920 #ifdef SMIME
921 {"smime-public-cert-directory", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
922 "S/MIME - Public Cert Directory", cf_text_publiccertdir},
923 {"smime-public-cert-container", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
924 "S/MIME - Public Cert Container", cf_text_publiccertcontainer},
925 {"smime-private-key-directory", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
926 "S/MIME - Private Key Directory", cf_text_privatekeydir},
927 {"smime-private-key-container", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
928 "S/MIME - Private Key Container", cf_text_privatekeycontainer},
929 {"smime-cacert-directory", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
930 "S/MIME - Cert Authority Directory", cf_text_cacertdir},
931 {"smime-cacert-container", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
932 "S/MIME - Cert Authority Container", cf_text_cacertcontainer},
933 #endif /* SMIME */
934 #ifdef ENABLE_LDAP
935 {"ldap-servers", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
936 "LDAP Servers", cf_text_ldap_server},
937 #endif /* ENABLE_LDAP */
938 {"rss-news", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
939 "WEB ALPINE - RSS News", cf_text_rss_news},
940 {"rss-weather", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
941 "WEB ALPINE - RSS Weather", cf_text_rss_weather},
942 {"wp-indexheight", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
943 "WEB ALPINE - Index Height", cf_text_wp_indexheight},
944 {"wp-indexlines", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
945 "WEB ALPINE - Index Lines", cf_text_wp_indexlines},
946 {"wp-aggstate", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
947 "WEB ALPINE - Aggregate State", cf_text_wp_aggstate},
948 {"wp-state", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
949 "WEB ALPINE - Cross Session State", cf_text_wp_state},
950 {"wp-columns", 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
951 "WEB ALPINE - Columns", cf_text_wp_columns},
952 {NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,NULL}
956 struct variable *
957 var_from_name(char *name)
959 struct variable *v;
960 int i;
962 if(!(name && name[0]))
963 return(NULL);
965 for(i = 0; (v = &variables[i]) && v->name; i++)
966 if(!strucmp(v->name,name))
967 return(v);
969 return(NULL);
973 void
974 init_init_vars(struct pine *ps)
976 ps->vars = variables;
980 #define DSIZE (25000)
981 /* this is just like dprint except it prints to a char * */
982 #ifdef DEBUG
983 #define mprint(n,x) { \
984 if(debug >= (n)){ \
985 snprintf x ; \
986 db += strlen(db); \
989 #else
990 #define mprint(n,x)
991 #endif
994 * this was split out from init_vars so we can get at the
995 * pinerc location sooner.
997 void
998 init_pinerc(struct pine *ps, char **debug_out)
1000 char buf[MAXPATH+1], *p, *db;
1001 #if defined(DOS) || defined(OS2)
1002 char buf2[MAXPATH+1], l_pinerc[MAXPATH+1];
1003 int nopinerc = 0, confregset = -1;
1004 register struct variable *vars = ps->vars;
1005 #endif
1007 #ifdef DEBUG
1009 * Since this routine is called before we've had a chance to set up
1010 * the debug file for output, we put the debugging into memory and
1011 * pass it back to the caller for use after init_debug(). We just
1012 * allocate plenty of space.
1014 if(debug_out){
1015 db = *debug_out = (char *)fs_get(DSIZE * sizeof(char));
1016 db[0] = '\0';
1018 #endif
1020 mprint(2, (db, DSIZE-(db-(*debug_out)), "\n -- init_pinerc --\n\n"));
1022 #if defined(DOS) || defined(OS2)
1024 * Rules for the config/support file locations under DOS are:
1026 * 1) The location of the PINERC is searched for in the following
1027 * order of precedence:
1028 * - File pointed to by '-p' command line option
1029 * - File pointed to by PINERC environment variable
1030 * - $HOME\pine
1031 * - same dir as argv[0]
1033 * 2) The HOME environment variable, if not set, defaults to
1034 * root of the current working drive (see alpine.c)
1036 * 3) The default for external files (PINE.SIG and ADDRBOOK) is the
1037 * same directory as the pinerc
1039 * 4) The support files (PINE.HLP and PINE.NDX) are expected to be in
1040 * the same directory as PINE.EXE.
1043 if(ps->prc){
1044 mprint(2, (db, DSIZE-(db-(*debug_out)),
1045 "Personal config \"%.100s\" comes from command line\n",
1046 (ps->prc && ps->prc->name) ? ps->prc->name : "<no name>"));
1048 else{
1049 mprint(2, (db, DSIZE-(db-(*debug_out)),
1050 "Personal config not set on cmdline, checking for $PINERC\n"));
1054 * First, if prc hasn't been set by a command-line -p, check to see
1055 * if PINERC is in the environment. If so, treat it just like we
1056 * would have treated it if it were a command-line arg.
1058 if(!ps->prc && (p = getenv("PINERC")) && *p){
1059 char path[MAXPATH], dir[MAXPATH];
1061 if(IS_REMOTE(p) || is_absolute_path(p)){
1062 strncpy(path, p, sizeof(path)-1);
1063 path[sizeof(path)-1] = '\0';
1065 else{
1066 getcwd(dir, sizeof(dir));
1067 build_path(path, dir, p, sizeof(path));
1070 if(!IS_REMOTE(p))
1071 ps->pinerc = cpystr(path);
1073 ps->prc = new_pinerc_s(path);
1075 if(ps->prc){
1076 mprint(2, (db, DSIZE-(db-(*debug_out)),
1077 " yes, personal config \"%.100s\" comes from $PINERC\n",
1078 (ps->prc && ps->prc->name) ? ps->prc->name : "<no name>"));
1083 * Pinerc used to be the name of the pinerc file. Then we added
1084 * the possibility of the pinerc file being remote, and we replaced
1085 * the variable pinerc with the structure prc. Unfortunately, some
1086 * parts of pine rely on the fact that pinerc is the name of the
1087 * pinerc _file_, and use the directory that the pinerc file is located
1088 * in for their own purposes. We want to preserve that so things will
1089 * keep working. So, even if the real pinerc is remote, we need to
1090 * put the name of a pinerc file in the pinerc variable so that the
1091 * directory which contains that file is writable. The file itself
1092 * doesn't have to exist for this purpose, since we are really only
1093 * using the name of the directory containing the file. Twisted.
1094 * (Alternatively, we could fix all of the code that uses the pinerc
1095 * variable for this purpose to use a new variable which really is
1096 * just a directory.) hubert 2000-sep
1098 * There are 3 cases. If pinerc is already set that means that the user
1099 * gave either a -p pinerc or an environment pinerc that is a local file,
1100 * and we are done. If pinerc is not set, then either prc is set or not.
1101 * If prc is set then the -p arg or PINERC value is a remote pinerc.
1102 * In that case we need to find a local directory to use, and put that
1103 * directory in the pinerc variable (with a fake filename tagged on).
1104 * If prc is not set, then user hasn't told us anything so we have to
1105 * try to find the default pinerc file by looking down the path of
1106 * possibilities. When we find it, we'll also use that directory.
1108 if(!ps->pinerc){
1109 *l_pinerc = '\0';
1110 *buf = '\0';
1112 if(ps->prc){ /* remote pinerc case */
1114 * We don't give them an l_pinerc unless they tell us where
1115 * to put it.
1117 if(ps->aux_files_dir)
1118 build_path(l_pinerc, ps->aux_files_dir, SYSTEM_PINERC,
1119 sizeof(l_pinerc));
1120 else{
1122 * Search for a writable directory.
1123 * Mimic what happens in !prc for local case, except we
1124 * don't need to look for the actual file.
1127 /* check if $HOME\PINE is writable */
1128 build_path(buf2, ps->home_dir, DF_PINEDIR, sizeof(buf2));
1129 if(is_writable_dir(buf2) == 0)
1130 build_path(l_pinerc, buf2, SYSTEM_PINERC, sizeof(l_pinerc));
1131 else{ /* $HOME\PINE not a writable dir */
1132 /* use this unless registry redirects us */
1133 build_path(l_pinerc, ps->pine_dir, SYSTEM_PINERC,
1134 sizeof(l_pinerc));
1135 #ifdef _WINDOWS
1136 /* if in registry, use that value */
1137 if(mswin_reg(MSWR_OP_GET, MSWR_PINE_RC, buf2, sizeof(buf2))
1138 && !IS_REMOTE(buf2)){
1139 strncpy(l_pinerc, buf2, sizeof(l_pinerc)-1);
1140 l_pinerc[sizeof(l_pinerc)-1] = '\0';
1142 #endif
1146 else{ /* searching for pinerc file to use */
1148 * Buf2 is $HOME\PINE. If $HOME is not explicitly set,
1149 * it defaults to the current working drive (often C:).
1150 * See alpine.c to see how it is initially set.
1153 mprint(2, (db, DSIZE-(db-(*debug_out)), " no, searching...\n"));
1154 build_path(buf2, ps->home_dir, DF_PINEDIR, sizeof(buf2));
1155 mprint(2, (db, DSIZE-(db-(*debug_out)),
1156 " checking for writable %.100s dir \"%.100s\" off of homedir\n",
1157 DF_PINEDIR, buf2));
1158 if(is_writable_dir(buf2) == 0){
1160 * $HOME\PINE exists and is writable.
1161 * See if $HOME\PINE\PINERC exists.
1163 build_path(buf, buf2, SYSTEM_PINERC, sizeof(buf));
1164 strncpy(l_pinerc, buf, sizeof(l_pinerc)-1);
1165 l_pinerc[sizeof(l_pinerc)-1] = '\0';
1166 mprint(2, (db, DSIZE-(db-(*debug_out)), " yes, now checking for file \"%.100s\"\n",
1167 buf));
1168 if(can_access(buf, ACCESS_EXISTS) == 0){ /* found it! */
1170 * Buf is what we were looking for.
1171 * It is local and can be used for the directory, too.
1173 mprint(2, (db, DSIZE-(db-(*debug_out)), " found it\n"));
1175 else{
1177 * No $HOME\PINE\PINERC, look for
1178 * one in same dir as PINE.EXE.
1180 build_path(buf2, ps->pine_dir, SYSTEM_PINERC,
1181 sizeof(buf2));
1182 mprint(2, (db, DSIZE-(db-(*debug_out)),
1183 " no, checking for \"%.100s\" in pine.exe dir\n",
1184 buf2));
1185 if(can_access(buf2, ACCESS_EXISTS) == 0){
1186 /* found it! */
1187 mprint(2, (db, DSIZE-(db-(*debug_out)), " found it\n"));
1188 strncpy(buf, buf2, sizeof(buf)-1);
1189 buf[sizeof(buf)-1] = '\0';
1190 strncpy(l_pinerc, buf2, sizeof(l_pinerc)-1);
1191 l_pinerc[sizeof(l_pinerc)-1] = '\0';
1193 else{
1194 #ifdef _WINDOWS
1195 mprint(2, (db, DSIZE-(db-(*debug_out)), " no, checking in registry\n"));
1196 if(mswin_reg(MSWR_OP_GET, MSWR_PINE_RC,
1197 buf2, sizeof(buf2))){
1198 strncpy(buf, buf2, sizeof(buf)-1);
1199 buf[sizeof(buf)-1] = '\0';
1200 if(!IS_REMOTE(buf2)){
1201 strncpy(l_pinerc, buf2, sizeof(l_pinerc)-1);
1202 l_pinerc[sizeof(l_pinerc)-1] = '\0';
1205 * Now buf is the pinerc to be used, l_pinerc is
1206 * the directory, which may be either same as buf
1207 * or it may be $HOME\PINE if registry gives us
1208 * a remote pinerc.
1210 mprint(2, (db, DSIZE-(db-(*debug_out)), " found \"%.100s\" in registry\n",
1211 buf));
1213 else{
1214 nopinerc = 1;
1215 mprint(2, (db, DSIZE-(db-(*debug_out)), " not found, asking user\n"));
1217 #else
1218 mprint(2, (db, DSIZE-(db-(*debug_out)), " not found\n"));
1219 #endif
1224 * Buf is the pinerc (could be remote if from registry)
1225 * and l_pinerc is the local pinerc, which may not exist.
1228 else{ /* $HOME\PINE not a writable dir */
1230 * We notice that the order of checking in the registry
1231 * and checking in the ALPINE.EXE directory are different
1232 * in this case versus the is_writable_dir(buf2) case, and
1233 * that does sort of look like a bug. However,
1234 * we don't think this is a bug since we did it on purpose
1235 * a long time ago. So even though we can't remember why
1236 * it is this way, we think we would rediscover why if we
1237 * changed it! So we won't change it.
1241 * Change the default to use to the ALPINE.EXE directory.
1243 build_path(buf, ps->pine_dir, SYSTEM_PINERC, sizeof(buf));
1244 strncpy(l_pinerc, buf, sizeof(l_pinerc)-1);
1245 l_pinerc[sizeof(l_pinerc)-1] = '\0';
1246 #ifdef _WINDOWS
1247 mprint(2, (db, DSIZE-(db-(*debug_out)), " no, not writable, checking in registry\n"));
1248 /* if in registry, use that value */
1249 if(mswin_reg(MSWR_OP_GET, MSWR_PINE_RC, buf2, sizeof(buf2))){
1250 strncpy(buf, buf2, sizeof(buf)-1);
1251 buf[sizeof(buf)-1] = '\0';
1252 mprint(2, (db, DSIZE-(db-(*debug_out)), " found \"%.100s\" in registry\n",
1253 buf));
1254 if(!IS_REMOTE(buf)){
1255 strncpy(l_pinerc, buf, sizeof(l_pinerc)-1);
1256 l_pinerc[sizeof(l_pinerc)-1] = '\0';
1259 else{
1260 mprint(2, (db, DSIZE-(db-(*debug_out)),
1261 " no, checking for \"%.100s\" in alpine.exe dir\n",
1262 buf));
1264 if(can_access(buf, ACCESS_EXISTS) == 0){
1265 mprint(2, (db, DSIZE-(db-(*debug_out)), " found it\n"));
1267 else{
1268 nopinerc = 1;
1269 mprint(2, (db, DSIZE-(db-(*debug_out)), " not found, asking user\n"));
1272 #else
1273 mprint(2, (db, DSIZE-(db-(*debug_out)),
1274 " no, checking for \"%.100s\" in alpine.exe dir\n",
1275 buf));
1277 if(can_access(buf, ACCESS_EXISTS) == 0){
1278 mprint(2, (db, DSIZE-(db-(*debug_out)), " found it\n"));
1280 else{
1281 mprint(2, (db, DSIZE-(db-(*debug_out)), " not found, creating it\n"));
1283 #endif
1287 * When we get here we have buf set to the name of the
1288 * pinerc, which could be local or remote. We have l_pinerc
1289 * set to the same as buf if buf is local, and set to another
1290 * name otherwise, hopefully contained in a writable directory.
1292 #ifdef _WINDOWS
1293 if(nopinerc || ps_global->install_flag){
1294 char buf3[MAXPATH+1];
1296 confregset = 0;
1297 strncpy(buf3, buf, MAXPATH);
1298 buf3[MAXPATH] = '\0';
1299 if(os_config_dialog(buf3, MAXPATH,
1300 &confregset, nopinerc) == 0){
1301 strncpy(buf, buf3, MAXPATH);
1302 buf[MAXPATH] = '\0';
1303 mprint(2, (db, DSIZE-(db-(*debug_out)), " not found, creating it\n"));
1304 mprint(2, (db, DSIZE-(db-(*debug_out)), " user says use \"%.100s\"\n", buf));
1305 if(!IS_REMOTE(buf)){
1306 strncpy(l_pinerc, buf, MAXPATH);
1307 l_pinerc[MAXPATH] = '\0';
1310 else{
1311 exit(-1);
1314 #endif
1315 ps->prc = new_pinerc_s(buf);
1318 ps->pinerc = cpystr(l_pinerc);
1321 #if defined(DOS) || defined(OS2)
1323 * The goal here is to set the auxiliary directory in the pinerc variable.
1324 * We are making the assumption that any reference to the pinerc variable
1325 * after this point is used only as a directory in which to store things,
1326 * with the prc variable being the preferred place to store pinerc location.
1327 * If -aux isn't set, then there is no change. -jpf 08/2001
1329 if(ps->aux_files_dir){
1330 l_pinerc[0] = '\0';
1331 build_path(l_pinerc, ps->aux_files_dir, SYSTEM_PINERC,
1332 sizeof(l_pinerc));
1333 if(ps->pinerc) fs_give((void **)&ps->pinerc);
1334 ps->pinerc = cpystr(l_pinerc);
1335 mprint(2, (db, DSIZE-(db-(*debug_out)), "Setting aux_files_dir to \"%.100s\"\n",
1336 ps->aux_files_dir));
1338 #endif
1340 #ifdef _WINDOWS
1341 if(confregset && (ps->update_registry != UREG_NEVER_SET))
1342 mswin_reg(MSWR_OP_SET | ((ps->update_registry == UREG_ALWAYS_SET)
1343 || confregset == 1 ? MSWR_OP_FORCE : 0),
1344 MSWR_PINE_RC,
1345 (ps->prc && ps->prc->name) ?
1346 ps->prc->name : ps->pinerc, (size_t)NULL);
1347 #endif
1350 * Now that we know the default for the PINERC, build NEWSRC default.
1351 * Backward compatibility makes this kind of funky. If what the
1352 * c-client thinks the NEWSRC should be exists *AND* it doesn't
1353 * already exist in the PINERC's dir, use c-client's default, otherwise
1354 * use the one next to the PINERC...
1356 p = last_cmpnt(ps->pinerc);
1357 buf[0] = '\0';
1358 if(p != NULL){
1359 strncpy(buf, ps->pinerc, MIN(p - ps->pinerc, sizeof(buf)-1));
1360 buf[MIN(p - ps->pinerc, sizeof(buf)-1)] = '\0';
1363 mprint(2, (db, DSIZE-(db-(*debug_out)), "Using directory \"%.100s\" for auxiliary files\n", buf));
1364 strncat(buf, "NEWSRC", sizeof(buf)-1-strlen(buf));
1366 if(!(p = (void *) mail_parameters(NULL, GET_NEWSRC, (void *)NULL))
1367 || can_access(p, ACCESS_EXISTS) < 0
1368 || can_access(buf, ACCESS_EXISTS) == 0){
1369 mail_parameters(NULL, SET_NEWSRC, (void *)buf);
1370 GLO_NEWSRC_PATH = cpystr(buf);
1372 else
1373 GLO_NEWSRC_PATH = cpystr(p);
1375 if(ps->pconf){
1376 mprint(2, (db, DSIZE-(db-(*debug_out)), "Global config \"%.100s\" comes from command line\n",
1377 (ps->pconf && ps->pconf->name) ? ps->pconf->name : "<no name>"));
1379 else{
1380 mprint(2, (db, DSIZE-(db-(*debug_out)),
1381 "Global config not set on cmdline, checking for $PINECONF\n"));
1384 if(!ps->pconf && (p = getenv("PINECONF"))){
1385 ps->pconf = new_pinerc_s(p);
1386 if(ps->pconf){
1387 mprint(2, (db, DSIZE-(db-(*debug_out)),
1388 " yes, global config \"%.100s\" comes from $PINECONF\n",
1389 (ps->pconf && ps->pconf->name) ? ps->pconf->name : "<no name>"));
1392 #ifdef _WINDOWS
1393 else if(!ps->pconf
1394 && mswin_reg(MSWR_OP_GET, MSWR_PINE_CONF, buf2, sizeof(buf2))){
1395 ps->pconf = new_pinerc_s(buf2);
1396 if(ps->pconf){
1397 mprint(2, (db, DSIZE-(db-(*debug_out)),
1398 " yes, global config \"%.100s\" comes from Registry\n",
1399 (ps->pconf && ps->pconf->name) ? ps->pconf->name : "<no name>"));
1402 #endif
1403 if(!ps->pconf){
1404 mprint(2, (db, DSIZE-(db-(*debug_out)), " no, there is no global config\n"));
1406 #ifdef _WINDOWS
1407 else if (ps->pconf && ps->pconf->name &&
1408 (ps->update_registry != UREG_NEVER_SET)){
1409 mswin_reg(MSWR_OP_SET | ((ps->update_registry == UREG_ALWAYS_SET)
1410 ? MSWR_OP_FORCE : 0),
1411 MSWR_PINE_CONF,
1412 ps->pconf->name, (size_t)NULL);
1414 #endif
1416 if(!ps->prc)
1417 ps->prc = new_pinerc_s(ps->pinerc);
1419 if(ps->exceptions){
1420 mprint(2, (db, DSIZE-(db-(*debug_out)),
1421 "Exceptions config \"%.100s\" comes from command line\n",
1422 ps->exceptions));
1424 else{
1425 mprint(2, (db, DSIZE-(db-(*debug_out)),
1426 "Exceptions config not set on cmdline, checking for $PINERCEX\n"));
1430 * Exceptions is done slightly differently from pinerc. Instead of setting
1431 * post_prc in args.c we just set the string and use it here. We do
1432 * that so that we can put it in the same directory as the pinerc if
1433 * exceptions is a relative name, and pinerc may not be set until here.
1435 * First, just like for pinerc, check environment variable if it wasn't
1436 * set on the command line.
1438 if(!ps->exceptions && (p = getenv("PINERCEX")) && *p){
1439 ps->exceptions = cpystr(p);
1440 if(ps->exceptions){
1441 mprint(2, (db, DSIZE-(db-(*debug_out)),
1442 " yes, exceptions config \"%.100s\" comes from $PINERCEX\n",
1443 ps->exceptions));
1448 * If still not set, try specific file in same dir as pinerc.
1449 * Only use it if the file exists.
1451 if(!ps->exceptions){
1452 p = last_cmpnt(ps->pinerc);
1453 buf[0] = '\0';
1454 if(p != NULL){
1455 strncpy(buf, ps->pinerc, MIN(p - ps->pinerc, sizeof(buf)-1));
1456 buf[MIN(p - ps->pinerc, sizeof(buf)-1)] = '\0';
1459 strncat(buf, "PINERCEX", sizeof(buf)-1-strlen(buf));
1461 mprint(2, (db, DSIZE-(db-(*debug_out)),
1462 " no, checking for default \"%.100s\" in pinerc dir\n", buf));
1463 if(can_access(buf, ACCESS_EXISTS) == 0) /* found it! */
1464 ps->exceptions = cpystr(buf);
1466 if(ps->exceptions){
1467 mprint(2, (db, DSIZE-(db-(*debug_out)),
1468 " yes, exceptions config \"%.100s\" comes from default\n",
1469 ps->exceptions));
1471 else{
1472 mprint(2, (db, DSIZE-(db-(*debug_out)), " no, there is no exceptions config\n"));
1476 #else /* unix */
1478 if(ps->pconf){
1479 mprint(2, (db, DSIZE-(db-(*debug_out)), "Global config \"%.100s\" comes from command line\n",
1480 (ps->pconf && ps->pconf->name) ? ps->pconf->name : "<no name>"));
1483 if(!ps->pconf){
1484 ps->pconf = new_pinerc_s(SYSTEM_PINERC);
1485 if(ps->pconf){
1486 mprint(2, (db, DSIZE-(db-(*debug_out)), "Global config \"%.100s\" is default\n",
1487 (ps->pconf && ps->pconf->name) ? ps->pconf->name : "<no name>"));
1491 if(!ps->pconf){
1492 mprint(2, (db, DSIZE-(db-(*debug_out)), "No global config!\n"));
1495 if(ps->prc){
1496 mprint(2, (db, DSIZE-(db-(*debug_out)), "Personal config \"%.100s\" comes from command line\n",
1497 (ps->prc && ps->prc->name) ? ps->prc->name : "<no name>"));
1500 if(!ps->pinerc){
1501 build_path(buf, ps->home_dir, ".pinerc", sizeof(buf));
1502 ps->pinerc = cpystr(buf);
1505 if(!ps->prc){
1506 ps->prc = new_pinerc_s(ps->pinerc);
1507 if(ps->prc){
1508 mprint(2, (db, DSIZE-(db-(*debug_out)), "Personal config \"%.100s\" is default\n",
1509 (ps->prc && ps->prc->name) ? ps->prc->name : "<no name>"));
1513 if(!ps->prc){
1514 mprint(2, (db, DSIZE-(db-(*debug_out)), "No personal config!\n"));
1517 if(ps->exceptions){
1518 mprint(2, (db, DSIZE-(db-(*debug_out)),
1519 "Exceptions config \"%.100s\" comes from command line\n",
1520 ps->exceptions));
1524 * If not set, try specific file in same dir as pinerc.
1525 * Only use it if the file exists.
1527 if(!ps->exceptions){
1528 p = last_cmpnt(ps->pinerc);
1529 buf[0] = '\0';
1530 if(p != NULL){
1531 strncpy(buf, ps->pinerc, MIN(p - ps->pinerc, sizeof(buf)-1));
1532 buf[MIN(p - ps->pinerc, sizeof(buf)-1)] = '\0';
1535 strncat(buf, ".pinercex", sizeof(buf)-1-strlen(buf));
1536 mprint(2, (db, DSIZE-(db-(*debug_out)), "Exceptions config not set on cmdline\n checking for default \"%.100s\" in pinerc dir\n", buf));
1538 if(can_access(buf, ACCESS_EXISTS) == 0) /* found it! */
1539 ps->exceptions = cpystr(buf);
1541 if(ps->exceptions){
1542 mprint(2, (db, DSIZE-(db-(*debug_out)),
1543 " yes, exceptions config \"%.100s\" is default\n",
1544 ps->exceptions));
1546 else{
1547 mprint(2, (db, DSIZE-(db-(*debug_out)), " no, there is no exceptions config\n"));
1551 #endif /* unix */
1553 if(ps->exceptions){
1555 if(!IS_REMOTE(ps->exceptions) &&
1556 !is_absolute_path(ps->exceptions)){
1557 #if defined(DOS) || defined(OS2)
1558 p = last_cmpnt(ps->pinerc);
1559 buf[0] = '\0';
1560 if(p != NULL){
1561 strncpy(buf, ps->pinerc, MIN(p - ps->pinerc, sizeof(buf)-1));
1562 buf[MIN(p - ps->pinerc, sizeof(buf)-1)] = '\0';
1565 strncat(buf, ps->exceptions, sizeof(buf)-1-strlen(buf));
1566 #else
1567 build_path(buf, ps->home_dir, ps->exceptions, sizeof(buf));
1568 #endif
1570 else{
1571 strncpy(buf, ps->exceptions, sizeof(buf)-1);
1572 buf[sizeof(buf)-1] = '\0';
1575 ps->post_prc = new_pinerc_s(buf);
1577 fs_give((void **)&ps->exceptions);
1580 mprint(2, (db, DSIZE-(db-(*debug_out)), "\n Global config: %.100s\n",
1581 (ps->pconf && ps->pconf->name) ? ps->pconf->name : "<none>"));
1582 mprint(2, (db, DSIZE-(db-(*debug_out)), " Personal config: %.100s\n",
1583 (ps->prc && ps->prc->name) ? ps->prc->name : "<none>"));
1584 mprint(2, (db, DSIZE-(db-(*debug_out)), " Exceptions config: %.100s\n",
1585 (ps->post_prc && ps->post_prc->name) ? ps->post_prc->name
1586 : "<none>"));
1587 #if !defined(DOS) && !defined(OS2)
1588 if(SYSTEM_PINERC_FIXED){
1589 mprint(2, (db, DSIZE-(db-(*debug_out)), " Fixed config: %.100s\n", SYSTEM_PINERC_FIXED));
1591 #endif
1593 mprint(2, (db, DSIZE-(db-(*debug_out)), "\n"));
1597 /*----------------------------------------------------------------------
1598 Initialize the variables
1600 Args: ps -- The usual pine structure
1602 Result:
1604 This reads the system pine configuration file and the user's pine
1605 configuration file ".pinerc" and places the results in the variables
1606 structure. It sorts out what was read and sets a few other variables
1607 based on the contents.
1608 ----*/
1609 void
1610 init_vars(struct pine *ps, void (*cmds_f) (struct pine *, char **))
1612 char buf[MAXPATH+1], *p, *q, **s, *comma_index;
1613 register struct variable *vars = ps->vars;
1614 int obs_header_in_reply = 0, /* the obs_ variables are to */
1615 obs_old_style_reply = 0, /* support backwards compatibility */
1616 obs_save_by_sender, i, def_sort_rev;
1617 long rvl;
1618 PINERC_S *fixedprc = NULL;
1619 FeatureLevel obs_feature_level;
1620 char *fromcharset = NULL;
1621 char *err = NULL;
1623 dprint((5, "init_vars:\n"));
1625 /*--- The defaults here are defined in os-xxx.h so they can vary
1626 per machine ---*/
1628 GLO_PRINTER = cpystr(DF_DEFAULT_PRINTER);
1629 GLO_ELM_STYLE_SAVE = cpystr(DF_ELM_STYLE_SAVE);
1630 GLO_ENCRYPTION_RANGE = cpystr(DF_ENCRYPTION_RANGE);
1631 GLO_SAVE_BY_SENDER = cpystr(DF_SAVE_BY_SENDER);
1632 GLO_HEADER_IN_REPLY = cpystr(DF_HEADER_IN_REPLY);
1633 GLO_INBOX_PATH = cpystr("inbox");
1634 GLO_DEFAULT_FCC = cpystr(DF_DEFAULT_FCC);
1635 GLO_DEFAULT_SAVE_FOLDER = cpystr(DEFAULT_SAVE);
1636 GLO_POSTPONED_FOLDER = cpystr(POSTPONED_MSGS);
1637 GLO_TRASH_FOLDER = cpystr(TRASH_FOLDER);
1638 GLO_USE_ONLY_DOMAIN_NAME = cpystr(DF_USE_ONLY_DOMAIN_NAME);
1639 GLO_FEATURE_LEVEL = cpystr("sappling");
1640 GLO_OLD_STYLE_REPLY = cpystr(DF_OLD_STYLE_REPLY);
1641 GLO_SORT_KEY = cpystr(DF_SORT_KEY);
1642 GLO_SAVED_MSG_NAME_RULE = cpystr(DF_SAVED_MSG_NAME_RULE);
1643 GLO_FCC_RULE = cpystr(DF_FCC_RULE);
1644 GLO_AB_SORT_RULE = cpystr(DF_AB_SORT_RULE);
1645 GLO_FLD_SORT_RULE = cpystr(DF_FLD_SORT_RULE);
1646 GLO_SIGNATURE_FILE = cpystr(DF_SIGNATURE_FILE);
1647 GLO_MAIL_DIRECTORY = cpystr(DF_MAIL_DIRECTORY);
1648 GLO_REMOTE_ABOOK_HISTORY = cpystr(DF_REMOTE_ABOOK_HISTORY);
1649 GLO_REMOTE_ABOOK_VALIDITY = cpystr(DF_REMOTE_ABOOK_VALIDITY);
1650 GLO_GOTO_DEFAULT_RULE = cpystr(DF_GOTO_DEFAULT_RULE);
1651 GLO_INCOMING_STARTUP = cpystr(DF_INCOMING_STARTUP);
1652 GLO_PRUNING_RULE = cpystr(DF_PRUNING_RULE);
1653 GLO_REOPEN_RULE = cpystr(DF_REOPEN_RULE);
1654 GLO_THREAD_DISP_STYLE = cpystr(DF_THREAD_DISP_STYLE);
1655 GLO_THREAD_INDEX_STYLE = cpystr(DF_THREAD_INDEX_STYLE);
1656 GLO_THREAD_MORE_CHAR = cpystr(DF_THREAD_MORE_CHAR);
1657 GLO_THREAD_EXP_CHAR = cpystr(DF_THREAD_EXP_CHAR);
1658 GLO_THREAD_LASTREPLY_CHAR = cpystr(DF_THREAD_LASTREPLY_CHAR);
1659 GLO_BUGS_FULLNAME = cpystr("Sorry No Address");
1660 GLO_BUGS_ADDRESS = cpystr("nobody");
1661 GLO_SUGGEST_FULLNAME = cpystr("Sorry No Address");
1662 GLO_SUGGEST_ADDRESS = cpystr("nobody");
1663 GLO_LOCAL_FULLNAME = cpystr(DF_LOCAL_FULLNAME);
1664 GLO_LOCAL_ADDRESS = cpystr(DF_LOCAL_ADDRESS);
1665 GLO_OVERLAP = cpystr(DF_OVERLAP);
1666 GLO_MAXREMSTREAM = cpystr(DF_MAXREMSTREAM);
1667 GLO_MARGIN = cpystr(DF_MARGIN);
1668 GLO_FILLCOL = cpystr(DF_FILLCOL);
1669 GLO_DEADLETS = cpystr(DF_DEADLETS);
1670 GLO_NMW_WIDTH = cpystr(DF_NMW_WIDTH);
1671 GLO_REPLY_STRING = cpystr("> ");
1672 GLO_REPLY_INTRO = cpystr(DEFAULT_REPLY_INTRO);
1673 GLO_EMPTY_HDR_MSG = cpystr("undisclosed-recipients");
1674 GLO_STATUS_MSG_DELAY = cpystr("0");
1675 GLO_ACTIVE_MSG_INTERVAL = cpystr("12");
1676 GLO_USERINPUTTIMEO = cpystr("0");
1677 GLO_INCCHECKTIMEO = cpystr("5");
1678 GLO_INCCHECKINTERVAL = cpystr("180");
1679 GLO_INC2NDCHECKINTERVAL = cpystr("180");
1680 GLO_MAILCHECK = cpystr(DF_MAILCHECK);
1681 GLO_MAILCHECKNONCURR = cpystr("0");
1682 GLO_MAILDROPCHECK = cpystr(DF_MAILDROPCHECK);
1683 GLO_NNTPRANGE = cpystr("0");
1684 GLO_KBLOCK_PASSWD_COUNT = cpystr(DF_KBLOCK_PASSWD_COUNT);
1685 GLO_INDEX_COLOR_STYLE = cpystr("flip-colors");
1686 GLO_TITLEBAR_COLOR_STYLE = cpystr("default");
1687 GLO_POST_CHAR_SET = cpystr("UTF-8");
1688 #ifdef DF_FOLDER_EXTENSION
1689 GLO_FOLDER_EXTENSION = cpystr(DF_FOLDER_EXTENSION);
1690 #endif
1691 #ifdef DF_SMTP_SERVER
1692 GLO_SMTP_SERVER = parse_list(DF_SMTP_SERVER, 1,
1693 PL_REMSURRQUOT, NULL);
1694 #endif
1696 #ifdef DF_SSHPATH
1697 GLO_SSHPATH = cpystr(DF_SSHPATH);
1698 #endif
1699 #ifdef DF_SSHCMD
1700 GLO_SSHCMD = cpystr(DF_SSHCMD);
1701 #endif
1703 #ifndef _WINDOWS
1704 GLO_COLOR_STYLE = cpystr("no-color");
1705 GLO_NORM_FORE_COLOR = cpystr(DEFAULT_NORM_FORE_RGB);
1706 GLO_NORM_BACK_COLOR = cpystr(DEFAULT_NORM_BACK_RGB);
1707 #endif
1708 GLO_TITLE_FORE_COLOR = cpystr(DEFAULT_TITLE_FORE_RGB);
1709 GLO_TITLE_BACK_COLOR = cpystr(DEFAULT_TITLE_BACK_RGB);
1710 GLO_TITLECLOSED_FORE_COLOR = cpystr(DEFAULT_TITLECLOSED_FORE_RGB);
1711 GLO_TITLECLOSED_BACK_COLOR = cpystr(DEFAULT_TITLECLOSED_BACK_RGB);
1712 GLO_FOLDER_FORE_COLOR = cpystr(DEFAULT_NORM_FORE_RGB);
1713 GLO_DIRECTORY_FORE_COLOR = cpystr(DEFAULT_NORM_FORE_RGB);
1714 GLO_FOLDER_LIST_FORE_COLOR = cpystr(DEFAULT_NORM_FORE_RGB);
1715 GLO_METAMSG_FORE_COLOR = cpystr(DEFAULT_METAMSG_FORE_RGB);
1716 GLO_METAMSG_BACK_COLOR = cpystr(DEFAULT_METAMSG_BACK_RGB);
1717 GLO_QUOTE1_FORE_COLOR = cpystr(DEFAULT_QUOTE1_FORE_RGB);
1718 GLO_QUOTE1_BACK_COLOR = cpystr(DEFAULT_QUOTE1_BACK_RGB);
1719 GLO_QUOTE2_FORE_COLOR = cpystr(DEFAULT_QUOTE2_FORE_RGB);
1720 GLO_QUOTE2_BACK_COLOR = cpystr(DEFAULT_QUOTE2_BACK_RGB);
1721 GLO_QUOTE3_FORE_COLOR = cpystr(DEFAULT_QUOTE3_FORE_RGB);
1722 GLO_QUOTE3_BACK_COLOR = cpystr(DEFAULT_QUOTE3_BACK_RGB);
1723 GLO_SIGNATURE_FORE_COLOR = cpystr(DEFAULT_SIGNATURE_FORE_RGB);
1724 GLO_SIGNATURE_BACK_COLOR = cpystr(DEFAULT_SIGNATURE_BACK_RGB);
1725 GLO_IND_PLUS_FORE_COLOR = cpystr(DEFAULT_IND_PLUS_FORE_RGB);
1726 GLO_IND_PLUS_BACK_COLOR = cpystr(DEFAULT_IND_PLUS_BACK_RGB);
1727 GLO_IND_IMP_FORE_COLOR = cpystr(DEFAULT_IND_IMP_FORE_RGB);
1728 GLO_IND_IMP_BACK_COLOR = cpystr(DEFAULT_IND_IMP_BACK_RGB);
1729 GLO_IND_ANS_FORE_COLOR = cpystr(DEFAULT_IND_ANS_FORE_RGB);
1730 GLO_IND_ANS_BACK_COLOR = cpystr(DEFAULT_IND_ANS_BACK_RGB);
1731 GLO_IND_NEW_FORE_COLOR = cpystr(DEFAULT_IND_NEW_FORE_RGB);
1732 GLO_IND_NEW_BACK_COLOR = cpystr(DEFAULT_IND_NEW_BACK_RGB);
1733 GLO_IND_OP_FORE_COLOR = cpystr(DEFAULT_IND_OP_FORE_RGB);
1734 GLO_IND_OP_BACK_COLOR = cpystr(DEFAULT_IND_OP_BACK_RGB);
1735 GLO_VIEW_MARGIN_LEFT = cpystr("0");
1736 GLO_VIEW_MARGIN_RIGHT = cpystr(DF_VIEW_MARGIN_RIGHT);
1737 GLO_QUOTE_SUPPRESSION = cpystr(DF_QUOTE_SUPPRESSION);
1738 GLO_KW_BRACES = cpystr("\"{\" \"} \"");
1739 GLO_OPENING_SEP = cpystr(" - ");
1740 GLO_WP_INDEXHEIGHT = cpystr("24");
1741 GLO_WP_AGGSTATE = cpystr("1");
1742 GLO_WP_STATE = cpystr("");
1743 #ifdef DEFAULT_SSLCAPATH
1744 GLO_SSLCAPATH = parse_list(DEFAULT_SSLCAPATH, 1,
1745 PL_REMSURRQUOT, NULL);
1746 #endif /* DEFAULT_SSLCAPATH */
1747 #ifdef DEFAULT_SSLCAFILE
1748 GLO_SSLCAFILE = parse_list(DEFAULT_SSLCAFILE, 1,
1749 PL_REMSURRQUOT, NULL);
1750 #endif /* DEFAULT_SSLCAFILE */
1751 #ifdef DEFAULT_SSLUSERCAPATH
1752 { char **l, path[MAXPATH+1];
1753 int i;
1754 l = parse_list(DEFAULT_SSLUSERCAPATH, 1,
1755 PL_REMSURRQUOT, NULL);
1756 if(l && *l && **l){
1757 for(i = 0; l[i] && *l[i]; i++){
1758 path[0] = '\0';
1759 if(ps_global->VAR_OPER_DIR){
1760 if(strlen(ps_global->VAR_OPER_DIR) + strlen(l[i]) < MAXPATH)
1761 build_path(path, ps_global->VAR_OPER_DIR, l[i], MAXPATH);
1763 else if(ps_global->home_dir){
1764 if(strlen(ps_global->home_dir) + strlen(l[i]) < MAXPATH)
1765 build_path(path, ps_global->home_dir, l[i], MAXPATH);
1767 if(path[0]){
1768 fs_give((void **) &l[i]);
1769 l[i] = cpystr(path);
1773 GLO_SSLUSERCAPATH = l;
1775 #endif /* DEFAULT_SSLUSERCAPATH */
1776 #ifdef DEFAULT_SSLUSERCAFILE
1777 { char **l, path[MAXPATH+1];
1778 int i;
1779 l = parse_list(DEFAULT_SSLUSERCAFILE, 1,
1780 PL_REMSURRQUOT, NULL);
1781 if(l && *l && **l){
1782 for(i = 0; l[i] && *l[i]; i++){
1783 path[0] = '\0';
1784 if(ps_global->VAR_OPER_DIR){
1785 if(strlen(ps_global->VAR_OPER_DIR) + strlen(l[i]) < MAXPATH)
1786 build_path(path, ps_global->VAR_OPER_DIR, l[i], MAXPATH);
1788 else if(ps_global->home_dir){
1789 if(strlen(ps_global->home_dir) + strlen(l[i]) < MAXPATH)
1790 build_path(path, ps_global->home_dir, l[i], MAXPATH);
1792 if(path[0]){
1793 fs_give((void **) &l[i]);
1794 l[i] = cpystr(path);
1798 GLO_SSLUSERCAFILE = l;
1800 #endif /* DEFAULT_SSLUSERCAFILE */
1801 #ifdef DF_VAR_SPELLER
1802 GLO_SPELLER = cpystr(DF_VAR_SPELLER);
1803 #endif
1804 GLO_HTML_DIRECTORY = cpystr(DF_HTML_DIRECTORY);
1805 #ifdef SMIME
1806 if(ps->smimedir){
1807 snprintf(tmp_20k_buf, SIZEOF_20KBUF, "%s/public", ps->smimedir);
1808 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1809 GLO_PUBLICCERT_DIR = cpystr(tmp_20k_buf);
1811 snprintf(tmp_20k_buf, SIZEOF_20KBUF, "%s/private", ps->smimedir);
1812 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1813 GLO_PRIVATEKEY_DIR = cpystr(tmp_20k_buf);
1815 snprintf(tmp_20k_buf, SIZEOF_20KBUF, "%s/ca", ps->smimedir);
1816 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1817 GLO_CACERT_DIR = cpystr(tmp_20k_buf);
1819 else{
1820 GLO_PUBLICCERT_DIR = cpystr(DF_PUBLICCERT_DIR);
1821 GLO_PRIVATEKEY_DIR = cpystr(DF_PRIVATEKEY_DIR);
1822 GLO_CACERT_DIR = cpystr(DF_CACERT_DIR);
1824 #endif /* SMIME */
1827 * Default first value for addrbook list if none set.
1828 * We also want to be sure to set global_val to the default
1829 * if is_fixed, so that address-book= will cause the default to happen.
1831 if(!GLO_ADDRESSBOOK && !FIX_ADDRESSBOOK)
1832 GLO_ADDRESSBOOK = parse_list(DF_ADDRESSBOOK, 1, 0, NULL);
1835 * Default first value if none set.
1837 if(!GLO_STANDARD_PRINTER && !FIX_STANDARD_PRINTER)
1838 GLO_STANDARD_PRINTER = parse_list(DF_STANDARD_PRINTER, 1, 0, NULL);
1841 * Defining this default sshpath should cause ssh to be preferred over rsh
1842 * when attempting imapd preauth calls.
1844 #ifdef DF_SSHPATH
1845 if(DF_SSHPATH
1846 && is_absolute_path(DF_SSHPATH)
1847 && can_access(DF_SSHPATH, EXECUTE_ACCESS) == 0){
1848 mail_parameters(NULL, SET_SSHPATH, (void *) DF_SSHPATH);
1850 #endif
1852 * It isn't usually necessary to define this.
1854 #ifdef DF_SSHCMD
1855 if(DF_SSHCMD){
1856 mail_parameters(NULL, SET_SSHCOMMAND, (void *) DF_SSHCMD);
1858 #endif
1860 #if !defined(DOS) && !defined(OS2)
1862 * This is here instead of in init_pinerc so that we can get by without
1863 * having a global fixedprc, since we don't need it anymore after this.
1865 fixedprc = new_pinerc_s(SYSTEM_PINERC_FIXED);
1866 #endif
1868 if(ps->pconf){
1869 read_pinerc(ps->pconf, vars, ParseGlobal);
1870 if(ps->pconf->type != Loc)
1871 rd_close_remote(ps->pconf->rd);
1874 if(ps->prc){
1875 read_pinerc(ps->prc, vars, ParsePers);
1876 if(ps->prc->type != Loc)
1877 rd_close_remote(ps->prc->rd);
1880 if(ps->post_prc){
1881 read_pinerc(ps->post_prc, vars, ParsePersPost);
1882 if(ps->post_prc->type != Loc)
1883 rd_close_remote(ps->post_prc->rd);
1886 if(fixedprc){
1887 read_pinerc(fixedprc, vars, ParseFixed);
1888 free_pinerc_s(&fixedprc);
1891 ps->ew_for_except_vars = ps->post_prc ? Post : Main;
1893 if(ps->exit_if_no_pinerc && ps->first_time_user){
1895 /* TRANSLATORS: -bail is a literal option name, don't change it. */
1896 exceptional_exit(_("Exiting because -bail option is set and config file doesn't exist."), -1);
1900 * Convert everything having to do with the config to UTF-8
1901 * in order to avoid having to worry about it all over the
1902 * place.
1903 * Set the character-set first so that we may use that in
1904 * the conversion process.
1906 set_collation(0, 1);
1908 #ifndef _WINDOWS
1909 #if (HAVE_LANGINFO_H && defined(CODESET))
1911 if(output_charset_is_supported(nl_langinfo_codeset_wrapper()))
1912 ps->GLO_CHAR_SET = cpystr(nl_langinfo_codeset_wrapper());
1913 else{
1914 ps->GLO_CHAR_SET = cpystr("UTF-8");
1915 dprint((1,"nl_langinfo(CODESET) returns unrecognized value=\"%s\", using UTF-8 as default\n", (p=nl_langinfo(CODESET)) ? p : ""));
1917 #else
1918 ps->GLO_CHAR_SET = cpystr("UTF-8");
1919 #endif
1921 set_current_val(&vars[V_CHAR_SET], TRUE, TRUE);
1922 set_current_val(&vars[V_OLD_CHAR_SET], TRUE, TRUE);
1923 set_current_val(&vars[V_KEY_CHAR_SET], TRUE, TRUE);
1924 #endif /* ! _WINDOWS */
1926 set_current_val(&vars[V_POST_CHAR_SET], TRUE, TRUE);
1929 * Also set up the feature list because we need the
1930 * Use-System-Translation feature to set up the charmaps.
1933 /* way obsolete, backwards compatibility */
1934 set_current_val(&vars[V_FEATURE_LEVEL], TRUE, TRUE);
1935 if(strucmp(VAR_FEATURE_LEVEL, "seedling") == 0)
1936 obs_feature_level = Seedling;
1937 else if(strucmp(VAR_FEATURE_LEVEL, "old-growth") == 0)
1938 obs_feature_level = Seasoned;
1939 else
1940 obs_feature_level = Sapling;
1942 /* obsolete, backwards compatibility */
1943 set_current_val(&vars[V_OLD_STYLE_REPLY], TRUE, TRUE);
1944 obs_old_style_reply = !strucmp(VAR_OLD_STYLE_REPLY, "yes");
1946 set_feature_list_current_val(&vars[V_FEATURE_LIST]);
1947 process_feature_list(ps, VAR_FEATURE_LIST,
1948 (obs_feature_level == Seasoned) ? 1 : 0,
1949 obs_header_in_reply, obs_old_style_reply);
1953 * Redo set_collation call with correct value for collation,
1954 * but we're hardwiring ctype on now. That's because nl_langinfo()
1955 * call needs it and system-dependent wcwidth and wcrtomb functions
1956 * need it.
1958 set_collation(F_OFF(F_DISABLE_SETLOCALE_COLLATE, ps_global), 1);
1961 * Set up to send the correct sequence of bytes to the display terminal.
1964 if(reset_character_set_stuff(&err) == -1)
1965 alpine_panic(err ? err : "trouble with character set setup");
1966 else if(err){
1967 init_error(ps, SM_ORDER | SM_DING, 3, 5, err);
1968 fs_give((void **) &err);
1972 * Now we use the configvars from above to convert the rest
1973 * to UTF-8. That should be ok because the ones above should
1974 * be ASCII.
1976 if(ps->keyboard_charmap && strucmp(ps->keyboard_charmap, "UTF-8")
1977 && strucmp(ps->keyboard_charmap, "US-ASCII"))
1978 fromcharset = ps->keyboard_charmap;
1979 else if(ps->display_charmap && strucmp(ps->display_charmap, "UTF-8")
1980 && strucmp(ps->display_charmap, "US-ASCII"))
1981 fromcharset = ps->display_charmap;
1982 #ifndef _WINDOWS
1983 else if(VAR_OLD_CHAR_SET && strucmp(VAR_OLD_CHAR_SET, "UTF-8")
1984 && strucmp(VAR_OLD_CHAR_SET, "US-ASCII"))
1985 fromcharset = VAR_OLD_CHAR_SET;
1986 #endif /* ! _WINDOWS */
1988 convert_configvars_to_utf8(vars, fromcharset);
1991 * If we already set this while reading the remote pinerc, don't
1992 * change it.
1994 if(!VAR_REMOTE_ABOOK_METADATA || !VAR_REMOTE_ABOOK_METADATA[0])
1995 set_current_val(&vars[V_REMOTE_ABOOK_METADATA], TRUE, TRUE);
1998 * mail-directory variable is obsolete, put its value in
1999 * default folder-collection list
2001 set_current_val(&vars[V_MAIL_DIRECTORY], TRUE, TRUE);
2002 if(!GLO_FOLDER_SPEC){
2003 build_path(tmp_20k_buf, VAR_MAIL_DIRECTORY, "[]", SIZEOF_20KBUF);
2004 GLO_FOLDER_SPEC = parse_list(tmp_20k_buf, 1, 0, NULL);
2007 set_current_val(&vars[V_FOLDER_SPEC], TRUE, TRUE);
2009 set_current_val(&vars[V_NNTP_SERVER], TRUE, TRUE);
2010 for(i = 0; VAR_NNTP_SERVER && VAR_NNTP_SERVER[i]; i++)
2011 removing_quotes(VAR_NNTP_SERVER[i]);
2013 set_news_spec_current_val(TRUE, TRUE);
2015 set_current_val(&vars[V_INBOX_PATH], TRUE, TRUE);
2017 set_current_val(&vars[V_USER_DOMAIN], TRUE, TRUE);
2018 if(VAR_USER_DOMAIN
2019 && VAR_USER_DOMAIN[0]
2020 && (p = strrindex(VAR_USER_DOMAIN, '@'))){
2021 if(*(++p)){
2022 char *q;
2024 snprintf(tmp_20k_buf, SIZEOF_20KBUF,
2025 "User-domain (%s) cannot contain \"@\", using \"%s\"",
2026 VAR_USER_DOMAIN, p);
2027 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2028 q = VAR_USER_DOMAIN;
2029 while((*q++ = *p++) != '\0')
2030 ;/* do nothing */
2032 else{
2033 snprintf(tmp_20k_buf, SIZEOF_20KBUF,
2034 "User-domain (%s) cannot contain \"@\", deleting",
2035 VAR_USER_DOMAIN);
2036 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2037 if(ps->vars[V_USER_DOMAIN].post_user_val.p){
2038 fs_give((void **)&ps->vars[V_USER_DOMAIN].post_user_val.p);
2039 set_current_val(&vars[V_USER_DOMAIN], TRUE, TRUE);
2042 if(VAR_USER_DOMAIN
2043 && VAR_USER_DOMAIN[0]
2044 && (p = strrindex(VAR_USER_DOMAIN, '@'))){
2045 if(ps->vars[V_USER_DOMAIN].main_user_val.p){
2046 fs_give((void **)&ps->vars[V_USER_DOMAIN].main_user_val.p);
2047 set_current_val(&vars[V_USER_DOMAIN], TRUE, TRUE);
2053 set_current_val(&vars[V_USE_ONLY_DOMAIN_NAME], TRUE, TRUE);
2054 set_current_val(&vars[V_REPLY_STRING], TRUE, TRUE);
2055 set_current_val(&vars[V_WORDSEPS], TRUE, TRUE);
2056 set_current_val(&vars[V_QUOTE_REPLACE_STRING], TRUE, TRUE);
2057 set_current_val(&vars[V_REPLY_INTRO], TRUE, TRUE);
2058 set_current_val(&vars[V_EMPTY_HDR_MSG], TRUE, TRUE);
2060 #ifdef ENABLE_LDAP
2061 set_current_val(&vars[V_LDAP_SERVERS], TRUE, TRUE);
2062 #endif /* ENABLE_LDAP */
2064 /* obsolete, backwards compatibility */
2065 set_current_val(&vars[V_HEADER_IN_REPLY], TRUE, TRUE);
2066 obs_header_in_reply=!strucmp(VAR_HEADER_IN_REPLY, "yes");
2068 set_current_val(&vars[V_PERSONAL_PRINT_COMMAND], TRUE, TRUE);
2069 set_current_val(&vars[V_STANDARD_PRINTER], TRUE, TRUE);
2070 set_current_val(&vars[V_PRINTER], TRUE, TRUE);
2071 if(vars[V_PERSONAL_PRINT_COMMAND].is_fixed && !vars[V_PRINTER].is_fixed)
2072 printer_value_check_and_adjust();
2074 set_current_val(&vars[V_LAST_TIME_PRUNE_QUESTION], TRUE, TRUE);
2075 if(VAR_LAST_TIME_PRUNE_QUESTION != NULL &&
2076 (comma_index = strindex(VAR_LAST_TIME_PRUNE_QUESTION, '.')) != NULL){
2077 /* The month value in the file runs from 1-12, the variable here
2078 runs from 0-11; the value in the file used to be 0-11, but we're
2079 fixing it in January */
2080 ps->last_expire_year = atoi(VAR_LAST_TIME_PRUNE_QUESTION);
2081 ps->last_expire_month = atoi(comma_index + 1);
2082 if(ps->last_expire_month == 0){
2083 /* Fix for 0 because of old bug */
2084 snprintf(buf, sizeof(buf), "%d.%d", ps_global->last_expire_year,
2085 ps_global->last_expire_month + 1);
2086 set_variable(V_LAST_TIME_PRUNE_QUESTION, buf, 1, 1, Main);
2087 }else{
2088 ps->last_expire_month--;
2090 }else{
2091 ps->last_expire_year = -1;
2092 ps->last_expire_month = -1;
2095 set_current_val(&vars[V_BUGS_FULLNAME], TRUE, TRUE);
2096 set_current_val(&vars[V_BUGS_ADDRESS], TRUE, TRUE);
2097 set_current_val(&vars[V_SUGGEST_FULLNAME], TRUE, TRUE);
2098 set_current_val(&vars[V_SUGGEST_ADDRESS], TRUE, TRUE);
2099 set_current_val(&vars[V_LOCAL_FULLNAME], TRUE, TRUE);
2100 set_current_val(&vars[V_LOCAL_ADDRESS], TRUE, TRUE);
2101 set_current_val(&vars[V_BUGS_EXTRAS], TRUE, TRUE);
2102 set_current_val(&vars[V_KBLOCK_PASSWD_COUNT], TRUE, TRUE);
2103 set_current_val(&vars[V_DEFAULT_FCC], TRUE, TRUE);
2104 set_current_val(&vars[V_POSTPONED_FOLDER], TRUE, TRUE);
2105 set_current_val(&vars[V_TRASH_FOLDER], TRUE, TRUE);
2106 set_current_val(&vars[V_READ_MESSAGE_FOLDER], TRUE, TRUE);
2107 set_current_val(&vars[V_FORM_FOLDER], TRUE, TRUE);
2108 set_current_val(&vars[V_EDITOR], TRUE, TRUE);
2109 set_current_val(&vars[V_SPELLER], TRUE, TRUE);
2110 #ifdef _WINDOWS
2111 set_current_val(&vars[V_DICTIONARY], TRUE, TRUE);
2112 #endif /* _WINDOWS */
2113 set_current_val(&vars[V_IMAGE_VIEWER], TRUE, TRUE);
2114 set_current_val(&vars[V_BROWSER], TRUE, TRUE);
2115 set_current_val(&vars[V_HISTORY], TRUE, TRUE);
2116 set_current_val(&vars[V_SMTP_SERVER], TRUE, TRUE);
2117 set_current_val(&vars[V_COMP_HDRS], TRUE, TRUE);
2118 set_current_val(&vars[V_CUSTOM_HDRS], TRUE, TRUE);
2119 set_current_val(&vars[V_SENDMAIL_PATH], TRUE, TRUE);
2120 set_current_val(&vars[V_DISPLAY_FILTERS], TRUE, TRUE);
2121 set_current_val(&vars[V_SEND_FILTER], TRUE, TRUE);
2122 set_current_val(&vars[V_ALT_ADDRS], TRUE, TRUE);
2123 set_current_val(&vars[V_ABOOK_FORMATS], TRUE, TRUE);
2124 set_current_val(&vars[V_KW_BRACES], TRUE, TRUE);
2125 set_current_val(&vars[V_OPENING_SEP], TRUE, TRUE);
2126 set_current_val(&vars[V_UNK_CHAR_SET], TRUE, TRUE);
2127 #ifdef SMIME
2128 set_current_val(&vars[V_PUBLICCERT_DIR], TRUE, TRUE);
2129 set_current_val(&vars[V_PUBLICCERT_CONTAINER], TRUE, TRUE);
2130 set_current_val(&vars[V_PRIVATEKEY_DIR], TRUE, TRUE);
2131 set_current_val(&vars[V_PRIVATEKEY_CONTAINER], TRUE, TRUE);
2132 set_current_val(&vars[V_CACERT_DIR], TRUE, TRUE);
2133 set_current_val(&vars[V_CACERT_CONTAINER], TRUE, TRUE);
2134 #endif /* SMIME */
2136 set_current_val(&vars[V_KEYWORDS], TRUE, TRUE);
2137 ps_global->keywords = init_keyword_list(VAR_KEYWORDS);
2139 set_current_val(&vars[V_OPER_DIR], TRUE, TRUE);
2140 if(VAR_OPER_DIR && !VAR_OPER_DIR[0]){
2141 init_error(ps, SM_ORDER | SM_DING, 3, 5,
2142 "Setting operating-dir to the empty string is not allowed. Will be ignored.");
2143 fs_give((void **)&VAR_OPER_DIR);
2144 if(FIX_OPER_DIR)
2145 fs_give((void **)&FIX_OPER_DIR);
2146 if(GLO_OPER_DIR)
2147 fs_give((void **)&GLO_OPER_DIR);
2148 if(COM_OPER_DIR)
2149 fs_give((void **)&COM_OPER_DIR);
2150 if(ps_global->vars[V_OPER_DIR].post_user_val.p)
2151 fs_give((void **)&ps_global->vars[V_OPER_DIR].post_user_val.p);
2152 if(ps_global->vars[V_OPER_DIR].main_user_val.p)
2153 fs_give((void **)&ps_global->vars[V_OPER_DIR].main_user_val.p);
2156 set_current_val(&vars[V_HTML_DIRECTORY], TRUE, TRUE);
2157 set_current_val(&vars[V_PERSONAL_PRINT_CATEGORY], TRUE, TRUE);
2158 ps->printer_category = -1;
2159 if(VAR_PERSONAL_PRINT_CATEGORY != NULL)
2160 ps->printer_category = atoi(VAR_PERSONAL_PRINT_CATEGORY);
2162 if(ps->printer_category < 1 || ps->printer_category > 3){
2163 char **tt;
2164 char aname[100], wname[100];
2166 strncpy(aname, ANSI_PRINTER, sizeof(aname));
2167 aname[sizeof(aname)-1] = '\0';
2168 strncat(aname, "-no-formfeed", sizeof(aname)-strlen(aname)-1);
2169 strncpy(wname, WYSE_PRINTER, sizeof(wname));
2170 wname[sizeof(wname)-1] = '\0';
2171 strncat(wname, "-no-formfeed", sizeof(wname)-strlen(wname)-1);
2172 if(strucmp(VAR_PRINTER, ANSI_PRINTER) == 0
2173 || strucmp(VAR_PRINTER, aname) == 0
2174 || strucmp(VAR_PRINTER, WYSE_PRINTER) == 0
2175 || strucmp(VAR_PRINTER, wname) == 0)
2176 ps->printer_category = 1;
2177 else if(VAR_STANDARD_PRINTER && VAR_STANDARD_PRINTER[0]){
2178 for(tt = VAR_STANDARD_PRINTER; *tt; tt++)
2179 if(strucmp(VAR_PRINTER, *tt) == 0)
2180 break;
2182 if(*tt)
2183 ps->printer_category = 2;
2186 /* didn't find it yet */
2187 if(ps->printer_category < 1 || ps->printer_category > 3){
2188 if(VAR_PERSONAL_PRINT_COMMAND && VAR_PERSONAL_PRINT_COMMAND[0]){
2189 for(tt = VAR_PERSONAL_PRINT_COMMAND; *tt; tt++)
2190 if(strucmp(VAR_PRINTER, *tt) == 0)
2191 break;
2193 if(*tt)
2194 ps->printer_category = 3;
2199 set_current_val(&vars[V_OVERLAP], TRUE, TRUE);
2200 ps->viewer_overlap = i = atoi(DF_OVERLAP);
2201 if(SVAR_OVERLAP(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2202 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2203 else
2204 ps->viewer_overlap = i;
2206 set_current_val(&vars[V_MARGIN], TRUE, TRUE);
2207 ps->scroll_margin = i = atoi(DF_MARGIN);
2208 if(SVAR_MARGIN(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2209 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2210 else
2211 ps->scroll_margin = i;
2213 set_current_val(&vars[V_FILLCOL], TRUE, TRUE);
2214 ps->composer_fillcol = i = atoi(DF_FILLCOL);
2215 if(SVAR_FILLCOL(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2216 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2217 else
2218 ps->composer_fillcol = i;
2220 set_current_val(&vars[V_QUOTE_SUPPRESSION], TRUE, TRUE);
2221 ps->quote_suppression_threshold = i = atoi(DF_QUOTE_SUPPRESSION);
2222 if(SVAR_QUOTE_SUPPRESSION(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2223 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2224 else{
2225 if(i > 0 && i < Q_SUPP_LIMIT){
2226 snprintf(tmp_20k_buf, SIZEOF_20KBUF,
2227 "Ignoring Quote-Suppression-Threshold value of %.50s, see help",
2228 VAR_QUOTE_SUPPRESSION);
2229 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2231 else{
2232 if(i < 0 && i != Q_DEL_ALL)
2233 ps->quote_suppression_threshold = -i;
2234 else
2235 ps->quote_suppression_threshold = i;
2239 set_current_val(&vars[V_DEADLETS], TRUE, TRUE);
2240 ps->deadlets = i = atoi(DF_DEADLETS);
2241 if(SVAR_DEADLETS(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2242 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2243 else
2244 ps->deadlets = i;
2246 set_current_val(&vars[V_STATUS_MSG_DELAY], TRUE, TRUE);
2247 ps->status_msg_delay = i = 0;
2248 if(SVAR_MSGDLAY(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2249 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2250 else
2251 ps->status_msg_delay = i;
2253 set_current_val(&vars[V_ACTIVE_MSG_INTERVAL], TRUE, TRUE);
2254 ps->active_status_interval = i = 8;
2255 if(SVAR_ACTIVEINTERVAL(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2256 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2257 else
2258 ps->active_status_interval = i;
2260 set_current_val(&vars[V_REMOTE_ABOOK_HISTORY], TRUE, TRUE);
2261 ps->remote_abook_history = i = atoi(DF_REMOTE_ABOOK_HISTORY);
2262 if(SVAR_AB_HIST(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2263 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2264 else
2265 ps->remote_abook_history = i;
2267 set_current_val(&vars[V_REMOTE_ABOOK_VALIDITY], TRUE, TRUE);
2268 ps->remote_abook_validity = i = atoi(DF_REMOTE_ABOOK_VALIDITY);
2269 if(SVAR_AB_VALID(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2270 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2271 else
2272 ps->remote_abook_validity = i;
2274 set_current_val(&vars[V_USERINPUTTIMEO], TRUE, TRUE);
2275 ps->hours_to_timeout = i = 0;
2276 if(SVAR_USER_INPUT(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2277 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2278 else
2279 ps->hours_to_timeout = i;
2281 /* timeo is a regular extern int because it is referenced in pico */
2282 set_current_val(&vars[V_MAILCHECK], TRUE, TRUE);
2283 set_input_timeout(i = 15);
2284 if(SVAR_MAILCHK(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2285 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2286 else
2287 set_input_timeout(i);
2289 set_current_val(&vars[V_MAILCHECKNONCURR], TRUE, TRUE);
2290 ps->check_interval_for_noncurr = i = 0;
2291 if(SVAR_MAILCHKNONCURR(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2292 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2293 else
2294 ps->check_interval_for_noncurr = i;
2296 #ifdef DEBUGJOURNAL
2297 ps->debugmem = 1;
2298 #else
2299 ps->debugmem = 0;
2300 #endif
2302 i = 30;
2303 set_current_val(&vars[V_TCPOPENTIMEO], TRUE, TRUE);
2304 /* this is just for the error, we don't save the result */
2305 if(VAR_TCPOPENTIMEO && SVAR_TCP_OPEN(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2306 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2308 i = 15;
2309 set_current_val(&vars[V_TCPREADWARNTIMEO], TRUE, TRUE);
2310 /* this is just for the error, we don't save the result */
2311 if(VAR_TCPREADWARNTIMEO && SVAR_TCP_READWARN(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2312 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2314 i = 0;
2315 set_current_val(&vars[V_TCPWRITEWARNTIMEO], TRUE, TRUE);
2316 /* this is just for the error, we don't save the result */
2317 if(VAR_TCPWRITEWARNTIMEO && SVAR_TCP_WRITEWARN(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2318 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2320 i = 15;
2321 set_current_val(&vars[V_RSHOPENTIMEO], TRUE, TRUE);
2322 /* this is just for the error, we don't save the result */
2323 if(VAR_RSHOPENTIMEO && SVAR_RSH_OPEN(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2324 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2326 i = 15;
2327 set_current_val(&vars[V_SSHOPENTIMEO], TRUE, TRUE);
2328 /* this is just for the error, we don't save the result */
2329 if(VAR_SSHOPENTIMEO && SVAR_SSH_OPEN(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2330 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2332 set_current_val(&vars[V_INCCHECKLIST], TRUE, TRUE);
2334 set_current_val(&vars[V_INCCHECKTIMEO], TRUE, TRUE);
2335 ps->inc_check_timeout = i = 5;
2336 if(SVAR_INC_CHECK_TIMEO(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2337 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2338 else
2339 ps->inc_check_timeout = i;
2341 set_current_val(&vars[V_INCCHECKINTERVAL], TRUE, TRUE);
2342 ps->inc_check_interval = i = 180;
2343 if(SVAR_INC_CHECK_INTERV(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2344 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2345 else
2346 ps->inc_check_interval = i;
2348 set_current_val(&vars[V_INC2NDCHECKINTERVAL], TRUE, TRUE);
2349 ps->inc_second_check_interval = i = 180;
2350 if(SVAR_INC_2NDCHECK_INTERV(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2351 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2352 else
2353 ps->inc_second_check_interval = i;
2355 rvl = 60L;
2356 set_current_val(&vars[V_MAILDROPCHECK], TRUE, TRUE);
2357 /* this is just for the error, we don't save the result */
2358 if(VAR_MAILDROPCHECK && SVAR_MAILDCHK(ps, rvl, tmp_20k_buf, SIZEOF_20KBUF))
2359 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2361 rvl = 0L;
2362 set_current_val(&vars[V_NNTPRANGE], TRUE, TRUE);
2363 /* this is just for the error, we don't save the result */
2364 if(VAR_NNTPRANGE && SVAR_NNTPRANGE(ps, rvl, tmp_20k_buf, SIZEOF_20KBUF))
2365 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2367 set_current_val(&vars[V_TCPQUERYTIMEO], TRUE, TRUE);
2368 ps->tcp_query_timeout = i = TO_BAIL_THRESHOLD;
2369 if(VAR_TCPQUERYTIMEO && SVAR_TCP_QUERY(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2370 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2371 else
2372 ps->tcp_query_timeout = i;
2374 set_current_val(&vars[V_QUITQUERYTIMEO], TRUE, TRUE);
2375 ps->close_connection_timeout = i = 0;
2376 if(VAR_QUITQUERYTIMEO && SVAR_QUIT_QUERY_TIMEO(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2377 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2378 else
2379 ps->close_connection_timeout = i;
2381 set_current_val(&vars[V_NEWSRC_PATH], TRUE, TRUE);
2382 if(VAR_NEWSRC_PATH && VAR_NEWSRC_PATH[0])
2383 mail_parameters(NULL, SET_NEWSRC, (void *)VAR_NEWSRC_PATH);
2385 set_current_val(&vars[V_NEWS_ACTIVE_PATH], TRUE, TRUE);
2386 if(VAR_NEWS_ACTIVE_PATH)
2387 mail_parameters(NULL, SET_NEWSACTIVE,
2388 (void *)VAR_NEWS_ACTIVE_PATH);
2390 set_current_val(&vars[V_NEWS_SPOOL_DIR], TRUE, TRUE);
2391 if(VAR_NEWS_SPOOL_DIR)
2392 mail_parameters(NULL, SET_NEWSSPOOL,
2393 (void *)VAR_NEWS_SPOOL_DIR);
2395 /* guarantee a save default */
2396 set_current_val(&vars[V_DEFAULT_SAVE_FOLDER], TRUE, TRUE);
2397 if(!VAR_DEFAULT_SAVE_FOLDER || !VAR_DEFAULT_SAVE_FOLDER[0])
2398 set_variable(V_DEFAULT_SAVE_FOLDER,
2399 (GLO_DEFAULT_SAVE_FOLDER && GLO_DEFAULT_SAVE_FOLDER[0])
2400 ? GLO_DEFAULT_SAVE_FOLDER
2401 : DEFAULT_SAVE, 1, 0, Main);
2403 set_current_val(&vars[V_SIGNATURE_FILE], TRUE, TRUE);
2404 set_current_val(&vars[V_LITERAL_SIG], TRUE, TRUE);
2405 set_current_val(&vars[V_GLOB_ADDRBOOK], TRUE, TRUE);
2406 set_current_val(&vars[V_ADDRESSBOOK], TRUE, TRUE);
2407 set_current_val(&vars[V_FORCED_ABOOK_ENTRY], TRUE, TRUE);
2408 set_current_val(&vars[V_DISABLE_DRIVERS], TRUE, TRUE);
2409 set_current_val(&vars[V_DISABLE_AUTHS], TRUE, TRUE);
2410 set_current_val(&vars[V_ENCRYPTION_RANGE], TRUE, TRUE);
2412 set_current_val(&vars[V_VIEW_HEADERS], TRUE, TRUE);
2413 /* strip spaces and colons */
2414 if(ps->VAR_VIEW_HEADERS){
2415 for(s = ps->VAR_VIEW_HEADERS; (q = *s) != NULL; s++){
2416 if(q[0]){
2417 removing_leading_white_space(q);
2418 /* look for colon or space or end */
2419 for(p = q; *p && !isspace((unsigned char)*p) && *p != ':'; p++)
2420 ;/* do nothing */
2422 *p = '\0';
2423 if(strucmp(q, ALL_EXCEPT) == 0)
2424 ps->view_all_except = 1;
2429 set_current_val(&vars[V_VIEW_MARGIN_LEFT], TRUE, TRUE);
2430 set_current_val(&vars[V_VIEW_MARGIN_RIGHT], TRUE, TRUE);
2431 set_current_val(&vars[V_UPLOAD_CMD], TRUE, TRUE);
2432 set_current_val(&vars[V_UPLOAD_CMD_PREFIX], TRUE, TRUE);
2433 set_current_val(&vars[V_DOWNLOAD_CMD], TRUE, TRUE);
2434 set_current_val(&vars[V_DOWNLOAD_CMD_PREFIX], TRUE, TRUE);
2435 set_current_val(&vars[V_MAILCAP_PATH], TRUE, TRUE);
2436 set_current_val(&vars[V_MIMETYPE_PATH], TRUE, TRUE);
2437 #if !defined(_WINDOWS) || defined(WINDOWS_UNIXSSL_CERTS)
2438 set_current_val(&vars[V_SSLCAPATH], TRUE, TRUE);
2439 set_current_val(&vars[V_SSLCAFILE], TRUE, TRUE);
2440 set_current_val(&vars[V_USERSSLCAPATH], TRUE, TRUE);
2441 set_current_val(&vars[V_USERSSLCAFILE], TRUE, TRUE);
2442 #endif
2443 #if !defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO)
2444 set_current_val(&vars[V_FIFOPATH], TRUE, TRUE);
2445 #endif
2447 set_current_val(&vars[V_RSHPATH], TRUE, TRUE);
2448 if(VAR_RSHPATH
2449 && is_absolute_path(VAR_RSHPATH)
2450 && can_access(VAR_RSHPATH, EXECUTE_ACCESS) == 0){
2451 mail_parameters(NULL, SET_RSHPATH, (void *) VAR_RSHPATH);
2454 set_current_val(&vars[V_RSHCMD], TRUE, TRUE);
2455 if(VAR_RSHCMD){
2456 mail_parameters(NULL, SET_RSHCOMMAND, (void *) VAR_RSHCMD);
2459 set_current_val(&vars[V_SSHPATH], TRUE, TRUE);
2460 if(VAR_SSHPATH) {
2461 if(is_absolute_path(VAR_SSHPATH)
2462 && can_access(VAR_SSHPATH, EXECUTE_ACCESS) == 0){
2463 mail_parameters(NULL, SET_SSHPATH, (void *) VAR_SSHPATH);
2465 else {
2466 mail_parameters(NULL, SET_SSHPATH, (void *) NULL);
2470 set_current_val(&vars[V_SSHCMD], TRUE, TRUE);
2471 if(VAR_SSHCMD) {
2472 if(VAR_SSHCMD[0]) {
2473 mail_parameters(NULL, SET_SSHCOMMAND, (void *) VAR_SSHCMD);
2475 else {
2476 mail_parameters(NULL, SET_SSHCOMMAND, (void *) NULL);
2480 #if defined(DOS) || defined(OS2)
2482 set_current_val(&vars[V_FILE_DIR], TRUE, TRUE);
2484 #ifdef _WINDOWS
2485 set_current_val(&vars[V_FONT_NAME], TRUE, TRUE);
2486 set_current_val(&vars[V_FONT_SIZE], TRUE, TRUE);
2487 set_current_val(&vars[V_FONT_STYLE], TRUE, TRUE);
2488 set_current_val(&vars[V_FONT_CHAR_SET], TRUE, TRUE);
2489 set_current_val(&vars[V_CURSOR_STYLE], TRUE, TRUE);
2490 set_current_val(&vars[V_WINDOW_POSITION], TRUE, TRUE);
2492 if(F_OFF(F_STORE_WINPOS_IN_CONFIG, ps_global)){
2493 /* if win position is in the registry, use it */
2494 if(mswin_reg(MSWR_OP_GET, MSWR_PINE_POS, buf, sizeof(buf))){
2495 if(VAR_WINDOW_POSITION)
2496 fs_give((void **)&VAR_WINDOW_POSITION);
2498 VAR_WINDOW_POSITION = cpystr(buf);
2500 else if(VAR_WINDOW_POSITION
2501 && (ps->update_registry != UREG_NEVER_SET)){
2502 /* otherwise, put it there */
2503 mswin_reg(MSWR_OP_SET | ((ps->update_registry == UREG_ALWAYS_SET)
2504 ? MSWR_OP_FORCE : 0),
2505 MSWR_PINE_POS,
2506 VAR_WINDOW_POSITION, (size_t)NULL);
2510 mswin_setwindow (VAR_FONT_NAME, VAR_FONT_SIZE,
2511 VAR_FONT_STYLE, VAR_WINDOW_POSITION,
2512 VAR_CURSOR_STYLE, VAR_FONT_CHAR_SET);
2514 /* this is no longer used */
2515 if(VAR_WINDOW_POSITION)
2516 fs_give((void **)&VAR_WINDOW_POSITION);
2518 set_current_val(&vars[V_PRINT_FONT_NAME], TRUE, TRUE);
2519 set_current_val(&vars[V_PRINT_FONT_SIZE], TRUE, TRUE);
2520 set_current_val(&vars[V_PRINT_FONT_STYLE], TRUE, TRUE);
2521 set_current_val(&vars[V_PRINT_FONT_CHAR_SET], TRUE, TRUE);
2522 mswin_setprintfont (VAR_PRINT_FONT_NAME,
2523 VAR_PRINT_FONT_SIZE,
2524 VAR_PRINT_FONT_STYLE,
2525 VAR_PRINT_FONT_CHAR_SET);
2527 mswin_setgenhelptextcallback(pcpine_general_help);
2529 mswin_setclosetext ("Use the \"Q\" command to exit Alpine.");
2532 char foreColor[64], backColor[64];
2534 mswin_getwindow(NULL, 0, NULL, 0, NULL, 0, NULL, 0,
2535 foreColor, sizeof(foreColor), backColor, sizeof(backColor),
2536 NULL, 0, NULL, 0);
2537 if(!GLO_NORM_FORE_COLOR)
2538 GLO_NORM_FORE_COLOR = cpystr(foreColor);
2540 if(!GLO_NORM_BACK_COLOR)
2541 GLO_NORM_BACK_COLOR = cpystr(backColor);
2543 #endif /* _WINDOWS */
2544 #endif /* DOS */
2547 * We want the version number to start out as 1.0 for Alpine, but
2548 * we also want to use the same old config file that was used
2549 * with Pine. The Pine version numbers made it up to 4.64 and we
2550 * want Alpine's 1.0 to be larger than 4.64 so we keep a separate
2551 * internal version number which is the real version number
2552 * plus 4. That's what gets written in LAST_VERS_USED.
2554 strncpy(ps->vers_internal, ALPINE_VERSION, sizeof(ps->vers_internal));
2555 ps->vers_internal[sizeof(ps->vers_internal)-1] = '\0';
2556 if(isdigit(ps->vers_internal[0]) && ps->vers_internal[0] < '6')
2557 ps->vers_internal[0] = ps->vers_internal[0] + 4;
2559 set_current_val(&vars[V_LAST_VERS_USED], TRUE, TRUE);
2560 /* Check for special cases first */
2561 if(VAR_LAST_VERS_USED
2562 && (isdigit(ps->vers_internal[0])
2563 && ps->vers_internal[1] == '.'
2564 && isdigit((unsigned char)ps->vers_internal[2])
2565 && isdigit((unsigned char)ps->vers_internal[3])
2566 && isalpha((unsigned char)ps->vers_internal[4])
2567 && strncmp(VAR_LAST_VERS_USED, ps->vers_internal, 4) >= 0)){
2568 ps->show_new_version = 0;
2570 /* Otherwise just do lexicographic comparison... */
2571 else if(VAR_LAST_VERS_USED
2572 && strcmp(VAR_LAST_VERS_USED, ps->vers_internal) >= 0){
2573 ps->show_new_version = 0;
2575 else{
2576 #ifdef _WINDOWS
2578 * If this is the first time we've run a version > 4.40, and there
2579 * is evidence that the config file has not been used by unix pine,
2580 * then we convert color008 to colorlgr, color009 to colormgr, and
2581 * color010 to colordgr. If the config file is being used by
2582 * unix pine then color009 may really supposed to be red, etc.
2583 * Same if we've already run 4.41 or higher. We don't have to do
2584 * anything if we are new to alpine.
2586 ps->pre441 = (VAR_LAST_VERS_USED
2587 && strcmp(VAR_LAST_VERS_USED, "4.40") <= 0);
2588 #endif /* _WINDOWS */
2591 * Don't offer the new version message if we're told not to.
2593 set_current_val(&vars[V_NEW_VER_QUELL], TRUE, TRUE);
2594 ps->show_new_version = !(VAR_NEW_VER_QUELL
2595 && strcmp(ps->vers_internal,
2596 VAR_NEW_VER_QUELL) < 0);
2598 #ifdef _WINDOWS
2599 if(!ps_global->install_flag)
2600 #endif /* _WINDOWS */
2602 if(VAR_LAST_VERS_USED){
2603 strncpy(ps_global->pine_pre_vers, VAR_LAST_VERS_USED,
2604 sizeof(ps_global->pine_pre_vers));
2605 ps_global->pine_pre_vers[sizeof(ps_global->pine_pre_vers)-1] = '\0';
2608 set_variable(V_LAST_VERS_USED, ps->vers_internal, 1, 1,
2609 ps_global->ew_for_except_vars);
2613 /* Obsolete, backwards compatibility */
2614 set_current_val(&vars[V_ELM_STYLE_SAVE], TRUE, TRUE);
2615 /* Also obsolete */
2616 set_current_val(&vars[V_SAVE_BY_SENDER], TRUE, TRUE);
2617 if(!strucmp(VAR_ELM_STYLE_SAVE, "yes"))
2618 set_variable(V_SAVE_BY_SENDER, "yes", 1, 1, Main);
2619 obs_save_by_sender = !strucmp(VAR_SAVE_BY_SENDER, "yes");
2621 set_current_val(&vars[V_XOAUTH2_INFO], TRUE, TRUE);
2623 set_current_pattern_vals(ps);
2625 set_current_val(&vars[V_INDEX_FORMAT], TRUE, TRUE);
2626 init_index_format(VAR_INDEX_FORMAT, &ps->index_disp_format);
2628 /* this should come after pre441 is set or not */
2629 set_current_color_vals(ps);
2631 set_current_val(&vars[V_RSS_NEWS], TRUE, TRUE);
2632 set_current_val(&vars[V_RSS_WEATHER], TRUE, TRUE);
2633 set_current_val(&vars[V_WP_INDEXHEIGHT], TRUE, TRUE);
2634 set_current_val(&vars[V_WP_INDEXLINES], TRUE, TRUE);
2635 set_current_val(&vars[V_WP_AGGSTATE], TRUE, TRUE);
2636 set_current_val(&vars[V_WP_STATE], TRUE, TRUE);
2637 set_current_val(&vars[V_WP_COLUMNS], TRUE, TRUE);
2639 set_current_val(&vars[V_PRUNED_FOLDERS], TRUE, TRUE);
2640 set_current_val(&vars[V_ARCHIVED_FOLDERS], TRUE, TRUE);
2641 set_current_val(&vars[V_INCOMING_FOLDERS], TRUE, TRUE);
2642 set_current_val(&vars[V_SORT_KEY], TRUE, TRUE);
2643 if(decode_sort(VAR_SORT_KEY, &ps->def_sort, &def_sort_rev) == -1){
2644 snprintf(tmp_20k_buf, SIZEOF_20KBUF, "Sort type \"%.200s\" is invalid", VAR_SORT_KEY);
2645 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2646 ps->def_sort = SortArrival;
2647 ps->def_sort_rev = 0;
2649 else
2650 ps->def_sort_rev = def_sort_rev;
2652 cur_rule_value(&vars[V_SAVED_MSG_NAME_RULE], TRUE, TRUE);
2653 {NAMEVAL_S *v; int i;
2654 for(i = 0; (v = save_msg_rules(i)); i++)
2655 if(v->value == ps_global->save_msg_rule)
2656 break;
2658 /* if save_msg_rule is not default, or is explicitly set to default */
2659 if((ps_global->save_msg_rule != SAV_RULE_DEFLT) ||
2660 (v && v->name &&
2661 (!strucmp(ps_global->vars[V_SAVED_MSG_NAME_RULE].post_user_val.p,
2662 v->name) ||
2663 !strucmp(ps_global->vars[V_SAVED_MSG_NAME_RULE].main_user_val.p,
2664 v->name))))
2665 obs_save_by_sender = 0; /* don't overwrite */
2668 cur_rule_value(&vars[V_FCC_RULE], TRUE, TRUE);
2669 cur_rule_value(&vars[V_AB_SORT_RULE], TRUE, TRUE);
2671 #ifndef _WINDOWS
2672 cur_rule_value(&vars[V_COLOR_STYLE], TRUE, TRUE);
2673 #endif
2675 cur_rule_value(&vars[V_INDEX_COLOR_STYLE], TRUE, TRUE);
2676 cur_rule_value(&vars[V_TITLEBAR_COLOR_STYLE], TRUE, TRUE);
2677 cur_rule_value(&vars[V_FLD_SORT_RULE], TRUE, TRUE);
2678 cur_rule_value(&vars[V_INCOMING_STARTUP], TRUE, TRUE);
2679 cur_rule_value(&vars[V_PRUNING_RULE], TRUE, TRUE);
2680 cur_rule_value(&vars[V_REOPEN_RULE], TRUE, TRUE);
2681 cur_rule_value(&vars[V_GOTO_DEFAULT_RULE], TRUE, TRUE);
2682 cur_rule_value(&vars[V_THREAD_DISP_STYLE], TRUE, TRUE);
2683 cur_rule_value(&vars[V_THREAD_INDEX_STYLE], TRUE, TRUE);
2685 set_current_val(&vars[V_THREAD_MORE_CHAR], TRUE, TRUE);
2686 if(VAR_THREAD_MORE_CHAR[0] && VAR_THREAD_MORE_CHAR[1]){
2687 init_error(ps, SM_ORDER | SM_DING, 3, 5,
2688 _("Only using first character of threading-indicator-character option"));
2689 VAR_THREAD_MORE_CHAR[1] = '\0';
2692 set_current_val(&vars[V_THREAD_EXP_CHAR], TRUE, TRUE);
2693 if(VAR_THREAD_EXP_CHAR[0] && VAR_THREAD_EXP_CHAR[1]){
2694 init_error(ps, SM_ORDER | SM_DING, 3, 5,
2695 _("Only using first character of threading-expanded-character option"));
2696 VAR_THREAD_EXP_CHAR[1] = '\0';
2699 set_current_val(&vars[V_THREAD_LASTREPLY_CHAR], TRUE, TRUE);
2700 if(!VAR_THREAD_LASTREPLY_CHAR[0])
2701 VAR_THREAD_LASTREPLY_CHAR = cpystr(DF_THREAD_LASTREPLY_CHAR);
2703 if(VAR_THREAD_LASTREPLY_CHAR[0] && VAR_THREAD_LASTREPLY_CHAR[1]){
2704 init_error(ps, SM_ORDER | SM_DING, 3, 5,
2705 _("Only using first character of threading-lastreply-character option"));
2706 VAR_THREAD_LASTREPLY_CHAR[1] = '\0';
2709 set_current_val(&vars[V_MAXREMSTREAM], TRUE, TRUE);
2710 ps->s_pool.max_remstream = i = atoi(DF_MAXREMSTREAM);
2711 if(SVAR_MAXREMSTREAM(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2712 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2713 else
2714 ps->s_pool.max_remstream = i;
2716 set_current_val(&vars[V_PERMLOCKED], TRUE, TRUE);
2718 set_current_val(&vars[V_NMW_WIDTH], TRUE, TRUE);
2719 ps->nmw_width = i = atoi(DF_NMW_WIDTH);
2720 if(SVAR_NMW_WIDTH(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2721 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2722 else
2723 ps->nmw_width = i;
2725 /* backwards compatibility */
2726 if(obs_save_by_sender){
2727 ps->save_msg_rule = SAV_RULE_FROM;
2728 set_variable(V_SAVED_MSG_NAME_RULE, "by-from", 1, 1, Main);
2731 /* this should come after process_feature_list because of use_fkeys */
2732 if(!ps->start_in_index)
2733 set_current_val(&vars[V_INIT_CMD_LIST], FALSE, TRUE);
2734 if(VAR_INIT_CMD_LIST && VAR_INIT_CMD_LIST[0] && VAR_INIT_CMD_LIST[0][0])
2735 if(cmds_f)
2736 (*cmds_f)(ps, VAR_INIT_CMD_LIST);
2738 #ifdef _WINDOWS
2739 mswin_set_quit_confirm (F_OFF(F_QUIT_WO_CONFIRM, ps_global));
2740 #endif /* _WINDOWS */
2742 #ifdef DEBUG
2743 dump_configuration(0);
2744 #endif /* DEBUG */
2748 void
2749 convert_configvars_to_utf8(struct variable *vars, char *fromcharset)
2751 struct variable *v;
2754 * Make sure that everything is UTF-8.
2756 for(v = vars; v->name; v++)
2757 convert_configvar_to_utf8(v, fromcharset);
2761 void
2762 convert_configvar_to_utf8(struct variable *v, char *fromcharset)
2764 char **p, *conv, **valptr;
2765 int i;
2768 * Make sure that everything is UTF-8.
2770 if(v->is_list){
2771 for(i = 0; i < 7; i++){
2772 switch(i){
2773 case 1: valptr = v->current_val.l; break;
2774 case 0: valptr = v->main_user_val.l; break;
2775 case 2: valptr = v->changed_val.l; break;
2776 case 3: valptr = v->post_user_val.l; break;
2777 case 4: valptr = v->global_val.l; break;
2778 case 5: valptr = v->fixed_val.l; break;
2779 case 6: valptr = v->cmdline_val.l; break;
2780 default: alpine_panic("bad case in convert_configvar");
2783 if(valptr){
2784 for(p = valptr; *p; p++){
2785 if(**p){
2786 conv = convert_to_utf8(*p, fromcharset, 0);
2787 if(conv){
2788 fs_give((void **) p);
2789 *p = conv;
2796 else{
2797 for(i = 0; i < 7; i++){
2798 switch(i){
2799 case 1: valptr = &v->current_val.p; break;
2800 case 0: valptr = &v->main_user_val.p; break;
2801 case 2: valptr = &v->changed_val.p; break;
2802 case 3: valptr = &v->post_user_val.p; break;
2803 case 4: valptr = &v->global_val.p; break;
2804 case 5: valptr = &v->fixed_val.p; break;
2805 case 6: valptr = &v->cmdline_val.p; break;
2806 default: alpine_panic("bad case in convert_configvar");
2809 if(valptr && *valptr && (*valptr)[0]){
2810 conv = convert_to_utf8(*valptr, fromcharset, 0);
2811 if(conv){
2812 fs_give((void **) valptr);
2813 *valptr = conv;
2823 * Standard feature name sections
2825 char *
2826 feature_list_section(FEATURE_S *feature)
2828 #define PREF_NONE -1
2829 static char *feat_sect[] = {
2830 #define PREF_MISC 0
2831 /* TRANSLATORS: section heading in configuration screen */
2832 N_("Advanced User Preferences"),
2833 #define PREF_FLDR 1
2834 /* TRANSLATORS: section heading in configuration screen */
2835 N_("Folder Preferences"),
2836 #define PREF_ADDR 2
2837 /* TRANSLATORS: section heading in configuration screen */
2838 N_("Address Book Preferences"),
2839 #define PREF_COMP 3
2840 /* TRANSLATORS: section heading in configuration screen */
2841 N_("Composer Preferences"),
2842 #define PREF_NEWS 4
2843 /* TRANSLATORS: section heading in configuration screen */
2844 N_("News Preferences"),
2845 #define PREF_VIEW 5
2846 /* TRANSLATORS: section heading in configuration screen */
2847 N_("Viewer Preferences"),
2848 #define PREF_ACMD 6
2849 /* TRANSLATORS: section heading in configuration screen */
2850 N_("Advanced Command Preferences"),
2851 #define PREF_PRNT 7
2852 /* TRANSLATORS: section heading in configuration screen */
2853 N_("Printer Preferences"),
2854 #define PREF_RPLY 8
2855 /* TRANSLATORS: section heading in configuration screen */
2856 N_("Reply Preferences"),
2857 #define PREF_SEND 9
2858 /* TRANSLATORS: section heading in configuration screen */
2859 N_("Sending Preferences"),
2860 #define PREF_INDX 10
2861 /* TRANSLATORS: section heading in configuration screen */
2862 N_("Message Index Preferences"),
2863 #define PREF_HIDDEN 11
2864 HIDDEN_PREF
2867 return((feature && feature->section > PREF_NONE
2868 && feature->section < (sizeof(feat_sect)/sizeof(feat_sect[0])))
2869 ? _(feat_sect[feature->section]) : NULL);
2873 /* any os-specific exclusions */
2874 #if defined(DOS) || defined(OS2)
2875 #define PREF_OS_LWSD PREF_NONE
2876 #define PREF_OS_LCLK PREF_NONE
2877 #define PREF_OS_STSP PREF_NONE
2878 #define PREF_OS_SPWN PREF_NONE
2879 #define PREF_OS_XNML PREF_NONE
2880 #define PREF_OS_USFK PREF_MISC
2881 #define PREF_OS_MOUSE PREF_NONE
2882 #else
2883 #define PREF_OS_LWSD PREF_MISC
2884 #define PREF_OS_LCLK PREF_COMP
2885 #define PREF_OS_STSP PREF_MISC
2886 #define PREF_OS_SPWN PREF_MISC
2887 #define PREF_OS_XNML PREF_MISC
2888 #define PREF_OS_USFK PREF_NONE
2889 #define PREF_OS_MOUSE PREF_MISC
2890 #endif
2894 * Standard way to get at feature list members...
2896 FEATURE_S *
2897 feature_list(int index)
2900 * This list is alphabatized by feature string, but the
2901 * macro values need not be ordered.
2903 static FEATURE_S feat_list[] = {
2904 /* Composer prefs */
2905 {"allow-changing-from", NULL,
2906 F_ALLOW_CHANGING_FROM, h_config_allow_chg_from, PREF_COMP, 1},
2907 {"alternate-compose-menu", NULL,
2908 F_ALT_COMPOSE_MENU, h_config_alt_compose_menu, PREF_COMP, 0},
2909 {"alternate-role-menu", "Alternate Role (#) Menu",
2910 F_ALT_ROLE_MENU, h_config_alt_role_menu, PREF_COMP, 0},
2911 {"compose-cancel-confirm-uses-yes", NULL,
2912 F_CANCEL_CONFIRM, h_config_cancel_confirm, PREF_COMP, 0},
2913 {"compose-rejects-unqualified-addrs", "Compose Rejects Unqualified Addresses",
2914 F_COMPOSE_REJECTS_UNQUAL, h_config_compose_rejects_unqual, PREF_COMP, 0},
2915 {"compose-send-offers-first-filter", NULL,
2916 F_FIRST_SEND_FILTER_DFLT, h_config_send_filter_dflt, PREF_COMP, 0},
2917 {"compose-cut-from-cursor", "Ctrl-K Cuts From Cursor",
2918 F_DEL_FROM_DOT, h_config_del_from_dot, PREF_COMP, 0},
2919 {"compose-maps-delete-key-to-ctrl-d", "Delete Key Maps to Ctrl-D",
2920 F_COMPOSE_MAPS_DEL, h_config_compose_maps_del, PREF_COMP, 0},
2921 {"quell-dead-letter-on-cancel", "Do Not Save to Deadletter on Cancel",
2922 F_QUELL_DEAD_LETTER, h_config_quell_dead_letter, PREF_COMP, 0},
2923 {"enable-alternate-editor-cmd", "Enable Alternate Editor Command",
2924 F_ENABLE_ALT_ED, h_config_enable_alt_ed, PREF_COMP, 1},
2925 {"enable-alternate-editor-implicitly", NULL,
2926 F_ALT_ED_NOW, h_config_alt_ed_now, PREF_COMP, 0},
2927 {"enable-search-and-replace", "Enable Search and Replace",
2928 F_ENABLE_SEARCH_AND_REPL, h_config_enable_search_and_repl, PREF_COMP, 1},
2929 {"enable-sigdashes", NULL,
2930 F_ENABLE_SIGDASHES, h_config_sigdashes, PREF_COMP, 0},
2931 {"quell-mailchecks-composing-except-inbox", "Prevent Mailchecks While Composing Except for INBOX",
2932 F_QUELL_PINGS_COMPOSING, h_config_quell_checks_comp, PREF_COMP, 0},
2933 {"quell-mailchecks-composing-inbox", "Prevent Mailchecks While Composing for INBOX",
2934 F_QUELL_PINGS_COMPOSING_INBOX, h_config_quell_checks_comp_inbox, PREF_COMP, 0},
2935 {"quell-user-lookup-in-passwd-file", "Prevent User Lookup in Password File",
2936 F_QUELL_LOCAL_LOOKUP, h_config_quell_local_lookup, PREF_OS_LCLK, 0},
2937 {"spell-check-before-sending", NULL,
2938 F_ALWAYS_SPELL_CHECK, h_config_always_spell_check, PREF_COMP, 0},
2940 /* Reply Prefs */
2941 {"alternate-reply-menu", NULL,
2942 F_ALT_REPLY_MENU, h_config_alt_reply_menu, PREF_RPLY, 0},
2943 {"copy-to-address-to-from-if-it-is-us", "Copy To Address to From if it is Us",
2944 F_COPY_TO_TO_FROM, h_config_copy_to_to_from, PREF_RPLY, 0},
2945 {"enable-reply-indent-string-editing", NULL,
2946 F_ENABLE_EDIT_REPLY_INDENT, h_config_prefix_editing, PREF_RPLY, 0},
2947 {"include-attachments-in-reply", "Include Attachments in Reply",
2948 F_ATTACHMENTS_IN_REPLY, h_config_attach_in_reply, PREF_RPLY, 0},
2949 {"include-header-in-reply", "Include Header in Reply",
2950 F_INCLUDE_HEADER, h_config_include_header, PREF_RPLY, 0},
2951 {"include-text-in-reply", "Include Text in Reply",
2952 F_AUTO_INCLUDE_IN_REPLY, h_config_auto_include_reply, PREF_RPLY, 0},
2953 {"reply-always-uses-reply-to", "Reply Always Uses Reply-To",
2954 F_AUTO_REPLY_TO, h_config_auto_reply_to, PREF_RPLY, 0},
2955 {"signature-at-bottom", "Signature at Bottom",
2956 F_SIG_AT_BOTTOM, h_config_sig_at_bottom, PREF_RPLY, 0},
2957 {"strip-from-sigdashes-on-reply", "Strip From Sigdashes on Reply",
2958 F_ENABLE_STRIP_SIGDASHES, h_config_strip_sigdashes, PREF_RPLY, 0},
2959 {"forward-as-attachment", "Forward messages as attachments",
2960 F_FORWARD_AS_ATTACHMENT, h_config_forward_as_attachment, PREF_RPLY, 0},
2961 {"preserve-original-fields", NULL,
2962 F_PRESERVE_ORIGINAL_FIELD, h_config_preserve_field, PREF_RPLY, 0},
2964 /* Sending Prefs */
2965 {"disable-sender", "Do Not Generate Sender Header",
2966 F_DISABLE_SENDER, h_config_disable_sender, PREF_SEND, 1},
2967 {"use-sender-not-x-sender", "Use Sender Instead of X-X-Sender",
2968 F_USE_SENDER_NOT_X, h_config_use_sender_not_x, PREF_SEND, 0},
2969 {"quell-flowed-text", "Do Not Send Flowed Text",
2970 F_QUELL_FLOWED_TEXT, h_config_quell_flowed_text, PREF_SEND, 0},
2971 {"downgrade-multipart-to-text", "Downgrade Multipart to Text",
2972 F_COMPOSE_ALWAYS_DOWNGRADE, h_downgrade_multipart_to_text, PREF_SEND, 0},
2973 {"enable-8bit-esmtp-negotiation", "Enable 8bit ESMTP Negotiation",
2974 F_ENABLE_8BIT, h_config_8bit_smtp, PREF_SEND, 1},
2975 #ifdef BACKGROUND_POST
2976 {"enable-background-sending", NULL,
2977 F_BACKGROUND_POST, h_config_compose_bg_post, PREF_SEND, 0},
2978 #endif
2979 {"enable-delivery-status-notification", NULL,
2980 F_DSN, h_config_compose_dsn, PREF_SEND, 0},
2981 {"enable-verbose-smtp-posting", "Enable Verbose SMTP Posting",
2982 F_VERBOSE_POST, h_config_verbose_post, PREF_SEND, 0},
2983 {"fcc-without-attachments", "Fcc Does Not Include Attachments",
2984 F_NO_FCC_ATTACH, h_config_no_fcc_attach, PREF_SEND, 0},
2985 {"fcc-on-bounce", "Include Fcc When Bouncing Messages",
2986 F_FCC_ON_BOUNCE, h_config_fcc_on_bounce, PREF_SEND, 0},
2987 {"mark-fcc-seen", NULL,
2988 F_MARK_FCC_SEEN, h_config_mark_fcc_seen, PREF_SEND, 0},
2989 {"fcc-only-without-confirm", "Send to Fcc Only Without Confirming",
2990 F_AUTO_FCC_ONLY, h_config_auto_fcc_only, PREF_SEND, 0},
2991 {"send-without-confirm", "Send Without Confirming",
2992 F_SEND_WO_CONFIRM, h_config_send_wo_confirm, PREF_SEND, 0},
2993 {"strip-whitespace-before-send", "Strip Whitespace Before Sending",
2994 F_STRIP_WS_BEFORE_SEND, h_config_strip_ws_before_send, PREF_SEND, 0},
2995 {"warn-if-blank-fcc", "Warn if Blank Fcc",
2996 F_WARN_ABOUT_NO_FCC, h_config_warn_if_fcc_blank, PREF_SEND, 0},
2997 {"warn-if-blank-subject", "Warn if Blank Subject",
2998 F_WARN_ABOUT_NO_SUBJECT, h_config_warn_if_subj_blank, PREF_SEND, 0},
2999 {"warn-if-blank-to-and-cc-and-newsgroups", "Warn if Blank To and CC and Newsgroups",
3000 F_WARN_ABOUT_NO_TO_OR_CC, h_config_warn_if_no_to_or_cc, PREF_SEND, 0},
3002 /* Folder */
3003 {"combined-folder-display", NULL,
3004 F_CMBND_FOLDER_DISP, h_config_combined_folder_display, PREF_FLDR, 0},
3005 {"combined-subdirectory-display", NULL,
3006 F_CMBND_SUBDIR_DISP, h_config_combined_subdir_display, PREF_FLDR, 0},
3007 {"enable-lame-list-mode", "Compensate for Deficient IMAP servers",
3008 F_FIX_BROKEN_LIST, h_config_lame_list_mode, PREF_FLDR, 0},
3009 {"enable-dot-folders", "Enable Hidden Folders",
3010 F_ENABLE_DOT_FOLDERS, h_config_enable_dot_folders, PREF_FLDR, 0},
3011 {"enable-incoming-folders", "Enable Incoming Folders Collection",
3012 F_ENABLE_INCOMING, h_config_enable_incoming, PREF_FLDR, 0},
3013 {"enable-incoming-folders-checking", NULL,
3014 F_ENABLE_INCOMING_CHECKING, h_config_enable_incoming_checking, PREF_FLDR, 0},
3015 {"incoming-checking-includes-total", NULL,
3016 F_INCOMING_CHECKING_TOTAL, h_config_incoming_checking_total, PREF_FLDR, 0},
3017 {"incoming-checking-uses-recent", NULL,
3018 F_INCOMING_CHECKING_RECENT, h_config_incoming_checking_recent, PREF_FLDR, 0},
3019 {"expanded-view-of-folders", "Expanded View of Folders",
3020 F_EXPANDED_FOLDERS, h_config_expanded_folders, PREF_FLDR, 0},
3021 {"quell-empty-directories", "Hide Empty Directories",
3022 F_QUELL_EMPTY_DIRS, h_config_quell_empty_dirs, PREF_FLDR, 0},
3023 {"separate-folder-and-directory-entries", "Separate Folder and Directory Entries",
3024 F_SEPARATE_FLDR_AS_DIR, h_config_separate_fold_dir_view, PREF_FLDR, 0},
3025 {"single-column-folder-list", NULL,
3026 F_SINGLE_FOLDER_LIST, h_config_single_list, PREF_FLDR, 0},
3027 {"sort-default-fcc-alpha", "Sort Default Fcc Folder Alphabetically",
3028 F_SORT_DEFAULT_FCC_ALPHA, h_config_sort_fcc_alpha, PREF_FLDR, 0},
3029 {"sort-default-save-alpha", "Sort Default Save Folder Alphabetically",
3030 F_SORT_DEFAULT_SAVE_ALPHA, h_config_sort_save_alpha, PREF_FLDR, 0},
3031 {"vertical-folder-list", "Use Vertical Folder List",
3032 F_VERTICAL_FOLDER_LIST, h_config_vertical_list, PREF_FLDR, 0},
3034 /* Addr book */
3035 {"combined-addrbook-display", "Combined Address Book Display",
3036 F_CMBND_ABOOK_DISP, h_config_combined_abook_display, PREF_ADDR, 0},
3037 {"expanded-view-of-addressbooks", "Expanded View of Address Books",
3038 F_EXPANDED_ADDRBOOKS, h_config_expanded_addrbooks, PREF_ADDR, 0},
3039 {"expanded-view-of-distribution-lists", "Expanded View of Distribution Lists",
3040 F_EXPANDED_DISTLISTS, h_config_expanded_distlists, PREF_ADDR, 0},
3041 #ifdef ENABLE_LDAP
3042 {"ldap-result-to-addrbook-add", "LDAP Result to Addressbook Add",
3043 F_ADD_LDAP_TO_ABOOK, h_config_add_ldap, PREF_ADDR, 0},
3044 #endif
3046 /* Index prefs */
3047 {"auto-open-next-unread", NULL,
3048 F_AUTO_OPEN_NEXT_UNREAD, h_config_auto_open_unread, PREF_INDX, 0},
3049 {"continue-tab-without-confirm", "Continue NextNew Without Confirming",
3050 F_TAB_NO_CONFIRM, h_config_tab_no_prompt, PREF_INDX, 0},
3051 {"convert-dates-to-localtime", NULL,
3052 F_DATES_TO_LOCAL, h_config_dates_to_local, PREF_INDX, 0},
3053 {"delete-skips-deleted", NULL,
3054 F_DEL_SKIPS_DEL, h_config_del_skips_del, PREF_INDX, 1},
3055 {"disable-index-locale-dates", NULL,
3056 F_DISABLE_INDEX_LOCALE_DATES, h_config_disable_index_locale_dates, PREF_INDX, 0},
3057 {"enable-cruise-mode", NULL,
3058 F_ENABLE_SPACE_AS_TAB, h_config_cruise_mode, PREF_INDX, 0},
3059 {"enable-cruise-mode-delete", "Enable Cruise Mode With Deleting",
3060 F_ENABLE_TAB_DELETES, h_config_cruise_mode_delete, PREF_INDX, 0},
3061 {"mark-for-cc", "Mark for CC",
3062 F_MARK_FOR_CC, h_config_mark_for_cc, PREF_INDX, 1},
3063 {"next-thread-without-confirm", "Read Next Thread Without Confirming",
3064 F_NEXT_THRD_WO_CONFIRM, h_config_next_thrd_wo_confirm, PREF_INDX, 0},
3065 {"return-to-inbox-without-confirm", "Return to INBOX Without Confirming",
3066 F_RET_INBOX_NO_CONFIRM, h_config_inbox_no_confirm, PREF_INDX, 0},
3067 {"show-sort", "Show Sort in Titlebar",
3068 F_SHOW_SORT, h_config_show_sort, PREF_INDX, 0},
3069 {"tab-uses-unseen-for-next-folder", "Tab Uses Unseen for Next Folder",
3070 F_TAB_USES_UNSEEN, h_config_tab_uses_unseen, PREF_INDX, 0},
3071 {"tab-visits-next-new-message-only", NULL,
3072 F_TAB_TO_NEW, h_config_tab_new_only, PREF_INDX, 0},
3073 {"thread-index-shows-important-color", NULL,
3074 F_COLOR_LINE_IMPORTANT, h_config_color_thrd_import, PREF_INDX, 0},
3075 {"thread-sorts-by-arrival", "Thread Sorts by Arrival",
3076 F_THREAD_SORTS_BY_ARRIVAL, h_config_thread_sorts_by_arrival, PREF_INDX, 0},
3078 /* Viewer prefs */
3079 {"enable-msg-view-addresses", "Enable Message View Address Links",
3080 F_SCAN_ADDR, h_config_enable_view_addresses, PREF_VIEW, 0},
3081 {"enable-msg-view-attachments", "Enable Message View Attachment Links",
3082 F_VIEW_SEL_ATTACH, h_config_enable_view_attach, PREF_VIEW, 0},
3083 {"enable-msg-view-urls", "Enable Message View URL Links",
3084 F_VIEW_SEL_URL, h_config_enable_view_url, PREF_VIEW, 1},
3085 {"enable-msg-view-web-hostnames", "Enable Message View Web Hostname Links",
3086 F_VIEW_SEL_URL_HOST, h_config_enable_view_web_host, PREF_VIEW, 1},
3087 {"enable-msg-view-forced-arrows", "Enable Message View Forced Arrows",
3088 F_FORCE_ARROWS, h_config_enable_view_arrows, PREF_VIEW, 0},
3089 {"external-command-loads-inline-images-only", NULL,
3090 F_EXTERNAL_INLINE_IMAGES, h_external_loads_inline_images_only, PREF_VIEW, 1},
3091 /* set to TRUE for windows */
3092 {"pass-c1-control-characters-as-is", NULL,
3093 F_PASS_C1_CONTROL_CHARS, h_config_pass_c1_control, PREF_VIEW, 0},
3094 {"pass-control-characters-as-is", NULL,
3095 F_PASS_CONTROL_CHARS, h_config_pass_control, PREF_VIEW, 0},
3096 {"prefer-plain-text", NULL,
3097 F_PREFER_PLAIN_TEXT, h_config_prefer_plain_text, PREF_VIEW, 0},
3098 {"quell-charset-warning", "Suppress Character Set Warning",
3099 F_QUELL_CHARSET_WARNING, h_config_quell_charset_warning, PREF_VIEW, 0},
3100 {"quell-server-after-link-in-html", "Suppress Server After Link in HTML",
3101 F_QUELL_HOST_AFTER_URL, h_config_quell_host_after_url, PREF_VIEW, 0},
3103 /* News */
3104 {"compose-sets-newsgroup-without-confirm", "Compose Sets Newsgroup Without Confirming",
3105 F_COMPOSE_TO_NEWSGRP, h_config_compose_news_wo_conf, PREF_NEWS, 0},
3106 {"enable-8bit-nntp-posting", "Enable 8bit NNTP Posting",
3107 F_ENABLE_8BIT_NNTP, h_config_8bit_nntp, PREF_NEWS, 0},
3108 {"enable-multiple-newsrcs", NULL,
3109 F_ENABLE_MULNEWSRCS, h_config_enable_mulnewsrcs, PREF_NEWS, 0},
3110 {"mult-newsrc-hostnames-as-typed", "Multiple Newsrc Hostnames as Typed",
3111 F_MULNEWSRC_HOSTNAMES_AS_TYPED, h_config_mulnews_as_typed, PREF_NEWS, 0},
3112 {"hide-nntp-path", "Hide NNTP Path",
3113 F_HIDE_NNTP_PATH, h_config_hide_nntp_path, PREF_NEWS, 0},
3114 {"news-approximates-new-status", NULL,
3115 F_FAKE_NEW_IN_NEWS, h_config_news_uses_recent, PREF_NEWS, 1},
3116 {"news-deletes-across-groups", NULL,
3117 F_NEWS_CROSS_DELETE, h_config_news_cross_deletes, PREF_NEWS, 0},
3118 {"news-offers-catchup-on-close", "News Offers Catchup on Close",
3119 F_NEWS_CATCHUP, h_config_news_catchup, PREF_NEWS, 0},
3120 {"news-post-without-validation", NULL,
3121 F_NO_NEWS_VALIDATION, h_config_post_wo_validation, PREF_NEWS, 0},
3122 {"news-read-in-newsrc-order", "News Read in Newsrc Order",
3123 F_READ_IN_NEWSRC_ORDER, h_config_read_in_newsrc_order, PREF_NEWS, 0},
3124 {"nntp-search-uses-overview", "NNTP Search Uses Overview",
3125 F_NNTP_SEARCH_USES_OVERVIEW, h_config_nntp_search_uses_overview, PREF_NEWS, 1},
3126 {"predict-nntp-server", "Predict NNTP Server",
3127 F_PREDICT_NNTP_SERVER, h_config_predict_nntp_server, PREF_NEWS, 0},
3128 {"quell-extra-post-prompt", "Suppress Extra Posting Prompt",
3129 F_QUELL_EXTRA_POST_PROMPT, h_config_quell_post_prompt, PREF_NEWS, 0},
3131 /* Print */
3132 {"enable-print-via-y-command", NULL,
3133 F_ENABLE_PRYNT, h_config_enable_y_print, PREF_PRNT, 0},
3134 {"print-formfeed-between-messages", NULL,
3135 F_AGG_PRINT_FF, h_config_ff_between_msgs, PREF_PRNT, 0},
3136 {"print-includes-from-line", NULL,
3137 F_FROM_DELIM_IN_PRINT, h_config_print_from, PREF_PRNT, 0},
3138 {"print-index-enabled", NULL,
3139 F_PRINT_INDEX, h_config_print_index, PREF_PRNT, 0},
3140 {"print-offers-custom-cmd-prompt", "Print Offers Custom Command Prompt",
3141 F_CUSTOM_PRINT, h_config_custom_print, PREF_PRNT, 0},
3143 /* adv cmd prefs */
3144 {"enable-aggregate-command-set", NULL,
3145 F_ENABLE_AGG_OPS, h_config_enable_agg_ops, PREF_ACMD, 1},
3146 {"enable-arrow-navigation", NULL,
3147 F_ARROW_NAV, h_config_arrow_nav, PREF_ACMD, 1},
3148 {"enable-arrow-navigation-relaxed", NULL,
3149 F_RELAXED_ARROW_NAV, h_config_relaxed_arrow_nav, PREF_ACMD, 1},
3150 {"enable-bounce-cmd", "Enable Bounce Command",
3151 F_ENABLE_BOUNCE, h_config_enable_bounce, PREF_ACMD, 1},
3152 {"enable-exit-via-lessthan-command", NULL,
3153 F_ENABLE_LESSTHAN_EXIT, h_config_enable_lessthan_exit, PREF_ACMD, 1},
3154 {"enable-flag-cmd", "Enable Flag Command",
3155 F_ENABLE_FLAG, h_config_enable_flag, PREF_ACMD, 1},
3156 {"enable-flag-screen-implicitly", NULL,
3157 F_FLAG_SCREEN_DFLT, h_config_flag_screen_default, PREF_ACMD, 0},
3158 {"enable-flag-screen-keyword-shortcut", NULL,
3159 F_FLAG_SCREEN_KW_SHORTCUT, h_config_flag_screen_kw_shortcut,PREF_ACMD, 1},
3160 {"enable-full-header-and-text", "Enable Full Header and Text",
3161 F_ENABLE_FULL_HDR_AND_TEXT, h_config_enable_full_hdr_and_text, PREF_ACMD, 0},
3162 {"enable-full-header-cmd", "Enable Full Header Command",
3163 F_ENABLE_FULL_HDR, h_config_enable_full_hdr, PREF_ACMD, 1},
3164 {"enable-goto-in-file-browser", "Enable Goto in File Browser",
3165 F_ALLOW_GOTO, h_config_allow_goto, PREF_ACMD, 1},
3166 {"enable-jump-shortcut", NULL,
3167 F_ENABLE_JUMP, h_config_enable_jump, PREF_ACMD, 1},
3168 {"enable-partial-match-lists", NULL,
3169 F_ENABLE_SUB_LISTS, h_config_sub_lists, PREF_ACMD, 1},
3170 {"enable-tab-completion", NULL,
3171 F_ENABLE_TAB_COMPLETE, h_config_enable_tab_complete, PREF_ACMD, 1},
3172 {"enable-unix-pipe-cmd", "Enable Unix Pipe Command",
3173 F_ENABLE_PIPE, h_config_enable_pipe, PREF_ACMD, 1},
3174 {"quell-full-header-auto-reset", "Suppress Full Header Auto Reset",
3175 F_QUELL_FULL_HDR_RESET, h_config_quell_full_hdr_reset, PREF_ACMD, 0},
3177 /* Adv user prefs */
3178 #if !defined(DOS) && !defined(OS2)
3179 {"allow-talk", NULL,
3180 F_ALLOW_TALK, h_config_allow_talk, PREF_MISC, 0},
3181 #endif
3182 {"assume-slow-link", NULL,
3183 F_FORCE_LOW_SPEED, h_config_force_low_speed, PREF_OS_LWSD, 0},
3184 {"auto-move-read-msgs", "Auto Move Read Messages",
3185 F_AUTO_READ_MSGS, h_config_auto_read_msgs, PREF_MISC, 0},
3186 {"auto-unselect-after-apply", NULL,
3187 F_AUTO_UNSELECT, h_config_auto_unselect, PREF_MISC, 0},
3188 {"auto-unzoom-after-apply", NULL,
3189 F_AUTO_UNZOOM, h_config_auto_unzoom, PREF_MISC, 1},
3190 {"auto-zoom-after-select", NULL,
3191 F_AUTO_ZOOM, h_config_auto_zoom, PREF_MISC, 1},
3192 {"busy-cue-spinner-only", NULL,
3193 F_USE_BORING_SPINNER, h_config_use_boring_spinner, PREF_MISC, 0},
3194 {"check-newmail-when-quitting", NULL,
3195 F_CHECK_MAIL_ONQUIT, h_config_check_mail_onquit, PREF_MISC, 0},
3196 {"confirm-role-even-for-default", "Confirm Role Even for Default",
3197 F_ROLE_CONFIRM_DEFAULT, h_config_confirm_role, PREF_MISC, 0},
3198 {"disable-keymenu", NULL,
3199 F_BLANK_KEYMENU, h_config_blank_keymenu, PREF_MISC, 0},
3200 {"disable-password-caching", NULL,
3201 F_DISABLE_PASSWORD_CACHING, h_config_disable_password_caching,
3202 PREF_MISC, 0},
3203 #ifdef LOCAL_PASSWD_CACHE
3204 {"disable-password-file-saving", NULL,
3205 F_DISABLE_PASSWORD_FILE_SAVING, h_config_disable_password_file_saving,
3206 PREF_MISC, 0},
3207 #endif /* LOCAL_PASSWD_CACHE */
3208 {"disable-regular-expression-matching-for-alternate-addresses", NULL,
3209 F_DISABLE_REGEX, h_config_disable_regex, PREF_MISC, 0},
3210 {"disable-save-input-history", NULL,
3211 F_DISABLE_SAVE_INPUT_HISTORY, h_config_input_history, PREF_MISC, 0},
3212 {"disable-take-fullname-in-addresses", "Disable Take Fullname in Addresses",
3213 F_DISABLE_TAKE_FULLNAMES, h_config_take_fullname, PREF_MISC, 0},
3214 {"disable-take-last-comma-first", NULL,
3215 F_DISABLE_TAKE_LASTFIRST, h_config_take_lastfirst, PREF_MISC, 0},
3216 {"disable-terminal-reset-for-display-filters", "Disable Terminal Reset for Display Filters",
3217 F_DISABLE_TERM_RESET_DISP, h_config_disable_reset_disp, PREF_MISC, 0},
3218 {"enable-dot-files", NULL,
3219 F_ENABLE_DOT_FILES, h_config_enable_dot_files, PREF_MISC, 0},
3220 {"enable-fast-recent-test", NULL,
3221 F_ENABLE_FAST_RECENT, h_config_fast_recent, PREF_MISC, 0},
3222 {"enable-mail-check-cue", NULL,
3223 F_SHOW_DELAY_CUE, h_config_show_delay_cue, PREF_MISC, 0},
3224 {"enable-mailcap-param-substitution", "Enable Mailcap Parameter Substitution",
3225 F_DO_MAILCAP_PARAM_SUBST, h_config_mailcap_params, PREF_MISC, 0},
3226 {"enable-mouse-in-xterm", "Enable Mouse in Xterm",
3227 F_ENABLE_MOUSE, h_config_enable_mouse, PREF_OS_MOUSE, 0},
3228 {"enable-newmail-in-xterm-icon", "Enable Newmail in Xterm Icon",
3229 F_ENABLE_XTERM_NEWMAIL, h_config_enable_xterm_newmail, PREF_OS_XNML, 0},
3230 {"enable-newmail-short-text-in-icon", "Enable Newmail Short Text in Icon",
3231 F_ENABLE_NEWMAIL_SHORT_TEXT, h_config_enable_newmail_short_text, PREF_OS_XNML, 0},
3232 {"enable-suspend", NULL,
3233 F_CAN_SUSPEND, h_config_can_suspend, PREF_MISC, 0},
3234 {"enable-take-export", NULL,
3235 F_ENABLE_TAKE_EXPORT, h_config_enable_take_export, PREF_MISC, 0},
3236 {"enable-rules-under-take", "Enable Take Rules",
3237 F_ENABLE_ROLE_TAKE, h_config_enable_role_take, PREF_MISC, 0},
3238 #ifdef _WINDOWS
3239 {"enable-tray-icon", NULL,
3240 F_ENABLE_TRAYICON, h_config_tray_icon, PREF_MISC, 0},
3241 #endif
3242 {"expose-hidden-config", NULL,
3243 F_EXPOSE_HIDDEN_CONFIG, h_config_expose_hidden_config, PREF_MISC, 0},
3244 {"expunge-only-manually", NULL,
3245 F_EXPUNGE_MANUALLY, h_config_expunge_manually, PREF_MISC, 0},
3246 {"expunge-without-confirm", "Expunge Without Confirming",
3247 F_AUTO_EXPUNGE, h_config_auto_expunge, PREF_MISC, 0},
3248 {"expunge-without-confirm-everywhere", "Expunge Without Confirming Everywhere",
3249 F_FULL_AUTO_EXPUNGE, h_config_full_auto_expunge, PREF_MISC, 0},
3250 {"force-arrow-cursor", NULL,
3251 F_FORCE_ARROW, h_config_force_arrow, PREF_MISC, 0},
3252 {"ignore-size-changes", NULL,
3253 F_IGNORE_SIZE, h_config_ignore_size, PREF_MISC, 0},
3254 {"maildrops-preserve-state", NULL,
3255 F_MAILDROPS_PRESERVE_STATE, h_config_maildrops_preserve_state,
3256 PREF_MISC, 0},
3257 {"offer-expunge-of-inbox", "Offer Expunge of INBOX",
3258 F_EXPUNGE_INBOX, h_config_expunge_inbox, PREF_MISC, 0},
3259 {"offer-expunge-of-stayopen-folders", "Offer Expunge of Stayopen Folders",
3260 F_EXPUNGE_STAYOPENS, h_config_expunge_stayopens, PREF_MISC, 0},
3261 {"preopen-stayopen-folders", NULL,
3262 F_PREOPEN_STAYOPENS, h_config_preopen_stayopens, PREF_MISC, 0},
3263 {"preserve-start-stop-characters", "Preserve Start/Stop Characters",
3264 F_PRESERVE_START_STOP, h_config_preserve_start_stop, PREF_OS_STSP, 0},
3265 {"quell-folder-internal-msg", "Prevent Folder Internal Message",
3266 F_QUELL_INTERNAL_MSG, h_config_quell_folder_internal_msg, PREF_MISC, 0},
3267 {"quell-partial-fetching", "Prevent Partial Fetching",
3268 F_QUELL_PARTIAL_FETCH, h_config_quell_partial, PREF_MISC, 0},
3269 {"prune-uses-yyyy-mm", "Prune Uses YYYY-MM",
3270 F_PRUNE_USES_ISO, h_config_prune_uses_iso, PREF_MISC, 0},
3271 {"quit-without-confirm", "Quit Without Confirming",
3272 F_QUIT_WO_CONFIRM, h_config_quit_wo_confirm, PREF_MISC, 0},
3273 {"quote-replace-nonflowed", NULL,
3274 F_QUOTE_REPLACE_NOFLOW, h_config_quote_replace_noflow, PREF_MISC, 0},
3275 {"save-aggregates-copy-sequence", "Save Combines Copies (may be out of order)",
3276 F_AGG_SEQ_COPY, h_config_save_aggregates, PREF_MISC, 1},
3277 {"save-partial-msg-without-confirm", "Save Partial Message Without Confirming",
3278 F_SAVE_PARTIAL_WO_CONFIRM, h_config_save_part_wo_confirm, PREF_MISC, 0},
3279 {"save-will-advance", NULL,
3280 F_SAVE_ADVANCES, h_config_save_advances, PREF_MISC, 0},
3281 {"save-will-not-delete", NULL,
3282 F_SAVE_WONT_DELETE, h_config_save_wont_delete, PREF_MISC, 0},
3283 {"save-will-quote-leading-froms", NULL,
3284 F_QUOTE_ALL_FROMS, h_config_quote_all_froms, PREF_MISC, 0},
3285 {"scramble-message-id", "Scramble the Message-ID When Sending",
3286 F_ROT13_MESSAGE_ID, h_config_scramble_message_id, PREF_MISC, 0},
3287 {"select-without-confirm", "Select Ctrl-T Foldername Without Confirming",
3288 F_SELECT_WO_CONFIRM, h_config_select_wo_confirm, PREF_MISC, 0},
3289 {"show-cursor", NULL,
3290 F_SHOW_CURSOR, h_config_show_cursor, PREF_MISC, 0},
3291 {"show-plain-text-internally", NULL,
3292 F_SHOW_TEXTPLAIN_INT, h_config_textplain_int, PREF_MISC, 0},
3293 {"show-selected-in-boldface", "Show Selected in Boldface",
3294 F_SELECTED_SHOWN_BOLD, h_config_select_in_bold, PREF_MISC, 0},
3295 {"slash-collapses-entire-thread", NULL,
3296 F_SLASH_COLL_ENTIRE, h_config_slash_coll_entire, PREF_MISC, 0},
3297 #ifdef _WINDOWS
3298 {"store-window-position-in-config", "Store Window Position in Config",
3299 F_STORE_WINPOS_IN_CONFIG, h_config_winpos_in_config, PREF_MISC, 0},
3300 #endif
3301 {"suppress-asterisks-in-password-prompt", "Suppress Asterisks in Password Prompt",
3302 F_QUELL_ASTERISKS, h_config_quell_asterisks,
3303 PREF_MISC, 0},
3304 {"quell-attachment-extension-warn", "Suppress Attachment Extension Warning",
3305 F_QUELL_ATTACH_EXT_WARN, h_config_quell_attach_ext_warn,
3306 PREF_MISC, 0},
3307 {"quell-attachment-extra-prompt", "Suppress Attachment Extra Prompt",
3308 F_QUELL_ATTACH_EXTRA_PROMPT, h_config_quell_attach_extra_prompt,
3309 PREF_MISC, 0},
3310 {"quell-berkeley-format-timezone", "Suppress Berkeley Format Timezone",
3311 F_QUELL_BEZERK_TIMEZONE, h_config_no_bezerk_zone, PREF_MISC, 0},
3312 {"quell-content-id", "Suppress Content-ID",
3313 F_QUELL_CONTENT_ID, h_config_quell_content_id, PREF_MISC, 0},
3314 {"quell-filtering-done-message", "Suppress Filtering Done Message",
3315 F_QUELL_FILTER_DONE_MSG, h_config_quell_filtering_done_message,
3316 PREF_MISC, 0},
3317 {"quell-filtering-messages", "Suppress Filtering Messages",
3318 F_QUELL_FILTER_MSGS, h_config_quell_filtering_messages,
3319 PREF_MISC, 0},
3320 {"quell-imap-envelope-update", "Suppress IMAP Envelope Update",
3321 F_QUELL_IMAP_ENV_CB, h_config_quell_imap_env, PREF_MISC, 0},
3322 {"quell-lock-failure-warnings", "Suppress Lock Failure Warnings",
3323 F_QUELL_LOCK_FAILURE_MSGS, h_config_quell_lock_failure_warnings,
3324 PREF_MISC, 0},
3325 {"quell-maildomain-warning", "Suppress Maildomain Warning",
3326 F_QUELL_MAILDOMAIN_WARNING, h_config_quell_domain_warn, PREF_MISC, 0},
3327 {"quell-news-envelope-update", "Suppress News Envelope Update",
3328 F_QUELL_NEWS_ENV_CB, h_config_quell_news_env, PREF_MISC, 0},
3329 #ifdef _WINDOWS
3330 {"quell-ssl-largeblocks", "Prevent SSL Largeblocks",
3331 F_QUELL_SSL_LARGEBLOCKS, h_config_quell_ssl_largeblocks, PREF_MISC, 0},
3332 #endif
3333 {"quell-status-message-beeping", "Suppress Status Message Beeping",
3334 F_QUELL_BEEPS, h_config_quell_beeps, PREF_MISC, 0},
3335 {"quell-timezone-comment-when-sending", "Suppress Timezone Comment When Sending",
3336 F_QUELL_TIMEZONE, h_config_quell_tz_comment, PREF_MISC, 0},
3337 {"suppress-user-agent-when-sending", NULL,
3338 F_QUELL_USERAGENT, h_config_suppress_user_agent, PREF_MISC, 1},
3339 {"tab-checks-recent", "Tab Checks for Recent Messages",
3340 F_TAB_CHK_RECENT, h_config_tab_checks_recent, PREF_MISC, 0},
3341 {"termdef-takes-precedence", NULL,
3342 F_TCAP_WINS, h_config_termcap_wins, PREF_MISC, 0},
3343 {"try-alternative-authentication-driver-first", NULL,
3344 F_PREFER_ALT_AUTH, h_config_alt_auth, PREF_MISC, 0},
3345 {"unselect-will-not-advance", NULL,
3346 F_UNSELECT_WONT_ADVANCE, h_config_unsel_wont_advance, PREF_MISC, 0},
3347 {"use-current-dir", "Use Current Directory",
3348 F_USE_CURRENT_DIR, h_config_use_current_dir, PREF_MISC, 0},
3349 {"use-function-keys", NULL,
3350 F_USE_FK, h_config_use_fk, PREF_OS_USFK, 0},
3351 {"use-regular-startup-rule-for-stayopen-folders", "Use Regular Startup Rule for Stayopen Folders",
3352 F_STARTUP_STAYOPEN, h_config_use_reg_start_for_stayopen, PREF_MISC, 0},
3353 {"use-resent-to-in-rules", "Use Resent-To in Rules",
3354 F_USE_RESENTTO, h_config_use_resentto, PREF_MISC, 0},
3355 {"use-subshell-for-suspend", "Use Subshell for Suspend",
3356 F_SUSPEND_SPAWNS, h_config_suspend_spawns, PREF_OS_SPWN, 0},
3357 #ifndef _WINDOWS
3358 {"use-system-translation", NULL,
3359 F_USE_SYSTEM_TRANS, h_config_use_system_translation, PREF_MISC, 0},
3360 #endif
3362 /* Hidden Features */
3363 {"old-growth", NULL,
3364 F_OLD_GROWTH, NO_HELP, PREF_NONE, 0},
3365 {"disable-config-cmd", NULL,
3366 F_DISABLE_CONFIG_SCREEN, h_config_disable_config_cmd, PREF_HIDDEN, 0},
3367 {"disable-keyboard-lock-cmd", NULL,
3368 F_DISABLE_KBLOCK_CMD, h_config_disable_kb_lock, PREF_HIDDEN, 0},
3369 {"disable-password-cmd", NULL,
3370 F_DISABLE_PASSWORD_CMD, h_config_disable_password_cmd, PREF_HIDDEN, 0},
3371 {"disable-pipes-in-sigs", NULL,
3372 F_DISABLE_PIPES_IN_SIGS, h_config_disable_pipes_in_sigs, PREF_HIDDEN, 0},
3373 {"disable-pipes-in-templates", NULL,
3374 F_DISABLE_PIPES_IN_TEMPLATES, h_config_disable_pipes_in_templates,
3375 PREF_HIDDEN, 0},
3376 {"disable-roles-setup-cmd", NULL,
3377 F_DISABLE_ROLES_SETUP, h_config_disable_roles_setup, PREF_HIDDEN, 0},
3378 {"disable-roles-sig-edit", NULL,
3379 F_DISABLE_ROLES_SIGEDIT, h_config_disable_roles_sigedit, PREF_HIDDEN, 0},
3380 {"disable-roles-template-edit", NULL,
3381 F_DISABLE_ROLES_TEMPLEDIT, h_config_disable_roles_templateedit,
3382 PREF_HIDDEN, 0},
3383 {"disable-setlocale-collate", NULL,
3384 F_DISABLE_SETLOCALE_COLLATE, h_config_disable_collate, PREF_HIDDEN, 0},
3385 {"disable-shared-namespaces", NULL,
3386 F_DISABLE_SHARED_NAMESPACES, h_config_disable_shared, PREF_HIDDEN, 0},
3387 {"disable-signature-edit-cmd", NULL,
3388 F_DISABLE_SIGEDIT_CMD, h_config_disable_signature_edit, PREF_HIDDEN, 0},
3389 {"new-thread-on-blank-subject", "New Thread on Blank Subject",
3390 F_NEW_THREAD_ON_BLANK_SUBJECT, h_config_new_thread_blank_subject, PREF_HIDDEN, 1},
3391 {"quell-personal-name-prompt", NULL,
3392 F_QUELL_PERSONAL_NAME_PROMPT, h_config_quell_personal_name_prompt, PREF_HIDDEN, 0},
3393 {"quell-user-id-prompt", "Quell User ID Prompt",
3394 F_QUELL_USER_ID_PROMPT, h_config_quell_user_id_prompt, PREF_HIDDEN, 0},
3395 #ifdef SMIME
3396 {"smime-dont-do-smime", "S/MIME -- Turn off S/MIME",
3397 F_DONT_DO_SMIME, h_config_smime_dont_do_smime, PREF_HIDDEN, 0},
3398 {"smime-encrypt-by-default", "S/MIME -- Encrypt by Default",
3399 F_ENCRYPT_DEFAULT_ON, h_config_smime_encrypt_by_default, PREF_HIDDEN, 0},
3400 {"smime-remember-passphrase", "S/MIME -- Remember S/MIME Passphrase",
3401 F_REMEMBER_SMIME_PASSPHRASE, h_config_smime_remember_passphrase, PREF_HIDDEN, 0},
3402 {"smime-sign-by-default", "S/MIME -- Sign by Default",
3403 F_SIGN_DEFAULT_ON, h_config_smime_sign_by_default, PREF_HIDDEN, 0},
3404 {"smime-use-store-only", "S/MIME -- Validate Using Certificate Store Only",
3405 F_USE_CERT_STORE_ONLY, h_config_smime_use_cert_store, PREF_HIDDEN, 1},
3406 #ifdef APPLEKEYCHAIN
3407 {"publiccerts-in-keychain", "S/MIME -- Public Certs in MacOS Keychain",
3408 F_PUBLICCERTS_IN_KEYCHAIN, h_config_smime_pubcerts_in_keychain, PREF_HIDDEN, 0},
3409 #endif
3410 #endif
3411 {"selectable-item-nobold", NULL,
3412 F_SLCTBL_ITEM_NOBOLD, NO_HELP, PREF_NONE, 0},
3413 {"send-confirms-only-expanded", NULL, /* exposed in Web Alpine */
3414 F_SEND_CONFIRM_ON_EXPAND, h_config_send_confirms_only_expanded, PREF_HIDDEN, 0},
3415 {"enable-jump-cmd", NULL, /* exposed in Web Alpine */
3416 F_ENABLE_JUMP_CMD, h_config_enable_jump_command, PREF_HIDDEN, 0},
3417 {"enable-newmail-sound", NULL, /* exposed in Web Alpine */
3418 F_ENABLE_NEWMAIL_SOUND, h_config_enable_newmail_sound, PREF_HIDDEN, 0},
3419 {"render-html-internally", NULL, /* exposed in Web Alpine */
3420 F_RENDER_HTML_INTERNALLY, h_config_render_html_internally, PREF_HIDDEN, 0}
3423 return((index >= 0 && index < (sizeof(feat_list)/sizeof(feat_list[0])))
3424 ? &feat_list[index] : NULL);
3429 * feature_list_index -- return index of given feature id in
3430 * feature list
3433 feature_list_index(int id)
3435 FEATURE_S *feature;
3436 int i;
3438 for(i = 0; (feature = feature_list(i)); i++)
3439 if(id == feature->id)
3440 return(i);
3442 return(-1);
3447 * feature_list_name -- return the given feature id's corresponding name
3449 char *
3450 feature_list_name(int id)
3452 FEATURE_S *f;
3454 return((f = feature_list(feature_list_index(id))) ? f->name : "");
3459 feature_list_id(char *name)
3461 FEATURE_S *f;
3462 int i;
3464 for(i = 0; (f = feature_list(i)); i++)
3465 if(!strucmp(f->name, name))
3466 return(f->id);
3468 return(-1);
3473 * feature_list_help -- return the given feature id's corresponding help
3475 HelpType
3476 feature_list_help(int id)
3478 FEATURE_S *f;
3480 return((f = feature_list(feature_list_index(id))) ? f->help : NO_HELP);
3485 * All the arguments past "list" are the backwards compatibility hacks.
3487 void
3488 process_feature_list(struct pine *ps, char **list, int old_growth, int hir, int osr)
3490 register char *q;
3491 char **p,
3492 *lvalue[BM_SIZE * 8];
3493 int i,
3494 yorn;
3495 long l;
3496 FEATURE_S *feat;
3499 /* clear all previous settings and reset them to default */
3500 for(i = 0; (feat = feature_list(i)) != NULL; i++)
3501 F_SET(feat->id, ps, feat->defval);
3503 /* backwards compatibility */
3504 if(hir)
3505 F_TURN_ON(F_INCLUDE_HEADER, ps);
3507 /* ditto */
3508 if(osr)
3509 F_TURN_ON(F_SIG_AT_BOTTOM, ps);
3511 /* ditto */
3512 if(old_growth)
3513 set_old_growth_bits(ps, 0);
3515 /* now run through the list (global, user, and cmd_line lists are here) */
3516 if(list){
3517 for(p = list; (q = *p) != NULL; p++){
3518 if(struncmp(q, "no-", 3) == 0){
3519 yorn = 0;
3520 q += 3;
3521 }else{
3522 yorn = 1;
3525 for(i = 0; (feat = feature_list(i)) != NULL; i++){
3526 if(strucmp(q, feat->name) == 0){
3527 if(feat->id == F_OLD_GROWTH){
3528 set_old_growth_bits(ps, yorn);
3529 }else{
3530 F_SET(feat->id, ps, yorn);
3532 break;
3536 /* if it wasn't in that list */
3537 if(feat == NULL)
3538 dprint((1,"Unrecognized feature in feature-list (%s%s)\n",
3539 (yorn ? "" : "no-"), q ? q : "?"));
3544 * Turn on gratuitous '>From ' quoting, if requested...
3546 mail_parameters(NULL, SET_FROMWIDGET,
3547 F_ON(F_QUOTE_ALL_FROMS, ps) ? VOIDT : NIL);
3550 * Turn off .lock creation complaints...
3552 if(F_ON(F_QUELL_LOCK_FAILURE_MSGS, ps))
3553 mail_parameters(NULL, SET_LOCKEACCESERROR, (void *) 0);
3556 * Turn on quelling of pseudo message.
3558 if(F_ON(F_QUELL_INTERNAL_MSG,ps_global))
3559 mail_parameters(NULL, SET_USERHASNOLIFE, (void *) 1);
3561 l = F_ON(F_MULNEWSRC_HOSTNAMES_AS_TYPED,ps_global) ? 0L : 1L;
3562 mail_parameters(NULL, SET_NEWSRCCANONHOST, (void *) l);
3564 ps->pass_ctrl_chars = F_ON(F_PASS_CONTROL_CHARS,ps_global) ? 1 : 0;
3565 ps->pass_c1_ctrl_chars = F_ON(F_PASS_C1_CONTROL_CHARS,ps_global) ? 1 : 0;
3567 #ifndef _WINDOWS
3568 if(F_ON(F_QUELL_BEZERK_TIMEZONE,ps_global))
3569 mail_parameters(NULL, SET_NOTIMEZONES, (void *) 1);
3570 #endif
3572 if(F_ON(F_USE_FK, ps))
3573 ps->orig_use_fkeys = 1;
3575 /* Will we have to build a new list? */
3576 if(!(old_growth || hir || osr))
3577 return;
3580 * Build a new list for feature-list. The only reason we ever need to
3581 * do this is if one of the obsolete options is being converted
3582 * into a feature-list item, and it isn't already included in the user's
3583 * feature-list.
3585 i = 0;
3586 for(p = LVAL(&ps->vars[V_FEATURE_LIST], Main);
3587 p && (q = *p); p++){
3588 /* already have it or cancelled it, don't need to add later */
3589 if(hir && (strucmp(q, "include-header-in-reply") == 0 ||
3590 strucmp(q, "no-include-header-in-reply") == 0)){
3591 hir = 0;
3592 }else if(osr && (strucmp(q, "signature-at-bottom") == 0 ||
3593 strucmp(q, "no-signature-at-bottom") == 0)){
3594 osr = 0;
3595 }else if(old_growth && (strucmp(q, "old-growth") == 0 ||
3596 strucmp(q, "no-old-growth") == 0)){
3597 old_growth = 0;
3599 lvalue[i++] = cpystr(q);
3602 /* check to see if we still need to build a new list */
3603 if(!(old_growth || hir || osr))
3604 return;
3606 if(hir)
3607 lvalue[i++] = "include-header-in-reply";
3608 if(osr)
3609 lvalue[i++] = "signature-at-bottom";
3610 if(old_growth)
3611 lvalue[i++] = "old-growth";
3612 lvalue[i] = NULL;
3613 set_variable_list(V_FEATURE_LIST, lvalue, TRUE, Main);
3617 void
3618 set_current_pattern_vals(struct pine *ps)
3620 struct variable *vars = ps->vars;
3622 set_current_val(&vars[V_PATTERNS], TRUE, TRUE);
3623 set_current_val(&vars[V_PAT_ROLES], TRUE, TRUE);
3624 set_current_val(&vars[V_PAT_FILTS], TRUE, TRUE);
3625 set_current_val(&vars[V_PAT_FILTS_OLD], TRUE, TRUE);
3626 set_current_val(&vars[V_PAT_SCORES], TRUE, TRUE);
3627 set_current_val(&vars[V_PAT_SCORES_OLD], TRUE, TRUE);
3628 set_current_val(&vars[V_PAT_INCOLS], TRUE, TRUE);
3629 set_current_val(&vars[V_PAT_OTHER], TRUE, TRUE);
3630 set_current_val(&vars[V_PAT_SRCH], TRUE, TRUE);
3633 * If old pattern variable (V_PATTERNS) is set and the new ones aren't
3634 * in the config file, then convert the old data into the new variables.
3635 * It isn't quite that simple, though, because we don't store unset
3636 * variables in remote pinercs. Check for the variables but if we
3637 * don't find any of them, also check the version number. This change was
3638 * made in version 4.30. We could just check that except that we're
3639 * worried somebody will make an incompatible version number change in
3640 * their local version, and will break this. So we check both the
3641 * version # and the var_in_pinerc things to be safer.
3643 if(vars[V_PATTERNS].current_val.l
3644 && vars[V_PATTERNS].current_val.l[0]
3645 && !var_in_pinerc(vars[V_PAT_ROLES].name)
3646 && !var_in_pinerc(vars[V_PAT_FILTS].name)
3647 && !var_in_pinerc(vars[V_PAT_FILTS_OLD].name)
3648 && !var_in_pinerc(vars[V_PAT_SCORES].name)
3649 && !var_in_pinerc(vars[V_PAT_SCORES_OLD].name)
3650 && !var_in_pinerc(vars[V_PAT_INCOLS].name)
3651 && isdigit((unsigned char) ps->pine_pre_vers[0])
3652 && ps->pine_pre_vers[1] == '.'
3653 && isdigit((unsigned char) ps->pine_pre_vers[2])
3654 && isdigit((unsigned char) ps->pine_pre_vers[3])
3655 && strncmp(ps->pine_pre_vers, "4.30", 4) < 0){
3656 convert_pattern_data();
3660 * Otherwise, if FILTS_OLD is set and FILTS isn't in the config file,
3661 * convert FILTS_OLD to FILTS. Same for SCORES.
3662 * The reason FILTS was changed was so we could change the
3663 * semantics of how rules work when there are pieces in the rule that
3664 * we don't understand. At the same time as the FILTS change we added
3665 * a rule to detect 8bitSubjects. So a user might have a filter that
3666 * deletes messages with 8bitSubjects. The problem is that that same
3667 * filter in a FILTS_OLD pine would match because it would ignore the
3668 * 8bitSubject part of the pattern and match on the rest. So we changed
3669 * the semantics so that rules with unknown bits would be ignored
3670 * instead of used. We had to change variable names at the same time
3671 * because we were adding the 8bit thing and the old pines are still
3672 * out there. Filters and Scores can both be dangerous. Roles, Colors,
3673 * and Other seem less dangerous so not worth adding a new variable.
3674 * This was changed in 4.50.
3676 else{
3677 if(vars[V_PAT_FILTS_OLD].current_val.l
3678 && vars[V_PAT_FILTS_OLD].current_val.l[0]
3679 && !var_in_pinerc(vars[V_PAT_FILTS].name)
3680 && !var_in_pinerc(vars[V_PAT_SCORES].name)
3681 && isdigit((unsigned char) ps->pine_pre_vers[0])
3682 && ps->pine_pre_vers[1] == '.'
3683 && isdigit((unsigned char) ps->pine_pre_vers[2])
3684 && isdigit((unsigned char) ps->pine_pre_vers[3])
3685 && strncmp(ps->pine_pre_vers, "4.50", 4) < 0){
3686 convert_filts_pattern_data();
3689 if(vars[V_PAT_SCORES_OLD].current_val.l
3690 && vars[V_PAT_SCORES_OLD].current_val.l[0]
3691 && !var_in_pinerc(vars[V_PAT_FILTS].name)
3692 && !var_in_pinerc(vars[V_PAT_SCORES].name)
3693 && isdigit((unsigned char) ps->pine_pre_vers[0])
3694 && ps->pine_pre_vers[1] == '.'
3695 && isdigit((unsigned char) ps->pine_pre_vers[2])
3696 && isdigit((unsigned char) ps->pine_pre_vers[3])
3697 && strncmp(ps->pine_pre_vers, "4.50", 4) < 0){
3698 convert_scores_pattern_data();
3702 if(vars[V_PAT_ROLES].post_user_val.l)
3703 ps_global->ew_for_role_take = Post;
3704 else
3705 ps_global->ew_for_role_take = Main;
3707 if(vars[V_PAT_FILTS].post_user_val.l)
3708 ps_global->ew_for_filter_take = Post;
3709 else
3710 ps_global->ew_for_filter_take = Main;
3712 if(vars[V_PAT_SCORES].post_user_val.l)
3713 ps_global->ew_for_score_take = Post;
3714 else
3715 ps_global->ew_for_score_take = Main;
3717 if(vars[V_PAT_INCOLS].post_user_val.l)
3718 ps_global->ew_for_incol_take = Post;
3719 else
3720 ps_global->ew_for_incol_take = Main;
3722 if(vars[V_PAT_OTHER].post_user_val.l)
3723 ps_global->ew_for_other_take = Post;
3724 else
3725 ps_global->ew_for_other_take = Main;
3727 if(vars[V_PAT_SRCH].post_user_val.l)
3728 ps_global->ew_for_srch_take = Post;
3729 else
3730 ps_global->ew_for_srch_take = Main;
3735 * Foreach of the config files;
3736 * transfer the data to the new variables.
3738 void
3739 convert_pattern_data(void)
3741 convert_pinerc_patterns(PAT_USE_MAIN);
3742 convert_pinerc_patterns(PAT_USE_POST);
3746 void
3747 convert_filts_pattern_data(void)
3749 convert_pinerc_filts_patterns(PAT_USE_MAIN);
3750 convert_pinerc_filts_patterns(PAT_USE_POST);
3754 void
3755 convert_scores_pattern_data(void)
3757 convert_pinerc_scores_patterns(PAT_USE_MAIN);
3758 convert_pinerc_scores_patterns(PAT_USE_POST);
3763 * Foreach of the four variables, transfer the data for this config file
3764 * from the old patterns variable. We don't have to convert OTHER patterns
3765 * or SRCH patterns because they didn't exist in pines without patterns-other.
3767 * If the original variable had patlines with type File then we convert
3768 * all of the individual patterns to type Lit, because each pattern can
3769 * be of any category. Lit patterns are better tested, anyway.
3771 void
3772 convert_pinerc_patterns(long int use_flags)
3774 long old_rflags;
3775 long rflags;
3776 PAT_S *pat;
3777 PAT_STATE pstate;
3778 ACTION_S *act;
3780 old_rflags = (ROLE_OLD_PAT | use_flags);
3782 rflags = 0L;
3783 if(any_patterns(old_rflags, &pstate)){
3784 dprint((2, "converting old patterns to new (%s)\n", (use_flags == PAT_USE_MAIN) ? "Main" : "Post"));
3785 for(pat = first_pattern(&pstate);
3786 pat;
3787 pat = next_pattern(&pstate)){
3788 if((act = pat->action) != NULL){
3789 if(act->is_a_role &&
3790 add_to_pattern(pat, ROLE_DO_ROLES | use_flags))
3791 rflags |= ROLE_DO_ROLES;
3792 if(act->is_a_incol &&
3793 add_to_pattern(pat, ROLE_DO_INCOLS | use_flags))
3794 rflags |= ROLE_DO_INCOLS;
3795 if(act->is_a_score &&
3796 add_to_pattern(pat, ROLE_DO_SCORES | use_flags))
3797 rflags |= ROLE_DO_SCORES;
3798 if(act->is_a_filter &&
3799 add_to_pattern(pat, ROLE_DO_FILTER | use_flags))
3800 rflags |= ROLE_DO_FILTER;
3804 if(rflags)
3805 if(write_patterns(rflags | use_flags))
3806 dprint((1,
3807 "Trouble converting patterns to new variable\n"));
3813 * If the original variable had patlines with type File then we convert
3814 * all of the individual patterns to type Lit, because each pattern can
3815 * be of any category. Lit patterns are better tested, anyway.
3817 void
3818 convert_pinerc_filts_patterns(long int use_flags)
3820 long old_rflags;
3821 long rflags;
3822 PAT_S *pat;
3823 PAT_STATE pstate;
3824 ACTION_S *act;
3826 old_rflags = (ROLE_OLD_FILT | use_flags);
3828 rflags = 0L;
3829 if(any_patterns(old_rflags, &pstate)){
3830 dprint((2, "converting old filter patterns to new (%s)\n", (use_flags == PAT_USE_MAIN) ? "Main" : "Post"));
3831 for(pat = first_pattern(&pstate);
3832 pat;
3833 pat = next_pattern(&pstate)){
3834 if((act = pat->action) != NULL){
3835 if(act->is_a_filter &&
3836 add_to_pattern(pat, ROLE_DO_FILTER | use_flags))
3837 rflags |= ROLE_DO_FILTER;
3841 if(rflags)
3842 if(write_patterns(rflags | use_flags))
3843 dprint((1,
3844 "Trouble converting filter patterns to new variable\n"));
3850 * If the original variable had patlines with type File then we convert
3851 * all of the individual patterns to type Lit, because each pattern can
3852 * be of any category. Lit patterns are better tested, anyway.
3854 void
3855 convert_pinerc_scores_patterns(long int use_flags)
3857 long old_rflags;
3858 long rflags;
3859 PAT_S *pat;
3860 PAT_STATE pstate;
3861 ACTION_S *act;
3863 old_rflags = (ROLE_OLD_SCORE | use_flags);
3865 rflags = 0L;
3866 if(any_patterns(old_rflags, &pstate)){
3867 dprint((2, "converting old scores patterns to new (%s)\n", (use_flags == PAT_USE_MAIN) ? "Main" : "Post"));
3868 for(pat = first_pattern(&pstate);
3869 pat;
3870 pat = next_pattern(&pstate)){
3871 if((act = pat->action) != NULL){
3872 if(act->is_a_score &&
3873 add_to_pattern(pat, ROLE_DO_SCORES | use_flags))
3874 rflags |= ROLE_DO_SCORES;
3878 if(rflags)
3879 if(write_patterns(rflags | use_flags))
3880 dprint((1,
3881 "Trouble converting scores patterns to new variable\n"));
3887 * set_old_growth_bits - Command used to set or unset old growth set
3888 * of features
3890 void
3891 set_old_growth_bits(struct pine *ps, int val)
3893 int i;
3895 for(i = 1; i <= F_FEATURE_LIST_COUNT; i++)
3896 if(test_old_growth_bits(ps, i))
3897 F_SET(i, ps, val);
3903 * test_old_growth_bits - Test to see if all the old growth bits are on,
3904 * *or* if a particular feature index is in the old
3905 * growth set.
3907 * WEIRD ALERT: if index == F_OLD_GROWTH bit values are tested
3908 * otherwise a bits existence in the set is tested!!!
3910 * BUG: this will break if an old growth feature number is ever >= 32.
3913 test_old_growth_bits(struct pine *ps, int index)
3916 * this list defines F_OLD_GROWTH set
3918 static unsigned long old_growth_bits = ((1 << F_ENABLE_FULL_HDR) |
3919 (1 << F_ENABLE_PIPE) |
3920 (1 << F_ENABLE_TAB_COMPLETE) |
3921 (1 << F_QUIT_WO_CONFIRM) |
3922 (1 << F_ENABLE_JUMP) |
3923 (1 << F_ENABLE_ALT_ED) |
3924 (1 << F_ENABLE_BOUNCE) |
3925 (1 << F_ENABLE_AGG_OPS) |
3926 (1 << F_ENABLE_FLAG) |
3927 (1 << F_CAN_SUSPEND));
3928 if(index >= 32)
3929 return(0);
3931 if(index == F_OLD_GROWTH){
3932 for(index = 1; index <= F_FEATURE_LIST_COUNT; index++)
3933 if(((1 << index) & old_growth_bits) && F_OFF(index, ps))
3934 return(0);
3936 return(1);
3938 else
3939 return((1 << index) & old_growth_bits);
3944 * Side effect is that the appropriate global variable is set, and the
3945 * appropriate current_val is set.
3947 void
3948 cur_rule_value(struct variable *var, int expand, int cmdline)
3950 int i;
3951 NAMEVAL_S *v;
3953 set_current_val(var, expand, cmdline);
3955 if(var == &ps_global->vars[V_SAVED_MSG_NAME_RULE]){
3956 if(ps_global->VAR_SAVED_MSG_NAME_RULE)
3957 for(i = 0; (v = save_msg_rules(i)); i++)
3958 if(!strucmp(ps_global->VAR_SAVED_MSG_NAME_RULE, S_OR_L(v))){
3959 ps_global->save_msg_rule = v->value;
3960 break;
3963 #ifndef _WINDOWS
3964 else if(var == &ps_global->vars[V_COLOR_STYLE]){
3965 if(ps_global->VAR_COLOR_STYLE)
3966 for(i = 0; (v = col_style(i)); i++)
3967 if(!strucmp(ps_global->VAR_COLOR_STYLE, S_OR_L(v))){
3968 ps_global->color_style = v->value;
3969 break;
3972 #endif
3973 else if(var == &ps_global->vars[V_INDEX_COLOR_STYLE]){
3974 if(ps_global->VAR_INDEX_COLOR_STYLE)
3975 for(i = 0; (v = index_col_style(i)); i++)
3976 if(!strucmp(ps_global->VAR_INDEX_COLOR_STYLE, S_OR_L(v))){
3977 ps_global->index_color_style = v->value;
3978 break;
3981 else if(var == &ps_global->vars[V_TITLEBAR_COLOR_STYLE]){
3982 if(ps_global->VAR_TITLEBAR_COLOR_STYLE)
3983 for(i = 0; (v = titlebar_col_style(i)); i++)
3984 if(!strucmp(ps_global->VAR_TITLEBAR_COLOR_STYLE, S_OR_L(v))){
3985 ps_global->titlebar_color_style = v->value;
3986 break;
3989 else if(var == &ps_global->vars[V_FCC_RULE]){
3990 if(ps_global->VAR_FCC_RULE)
3991 for(i = 0; (v = fcc_rules(i)); i++)
3992 if(!strucmp(ps_global->VAR_FCC_RULE, S_OR_L(v))){
3993 ps_global->fcc_rule = v->value;
3994 break;
3997 else if(var == &ps_global->vars[V_GOTO_DEFAULT_RULE]){
3998 if(ps_global->VAR_GOTO_DEFAULT_RULE)
3999 for(i = 0; (v = goto_rules(i)); i++)
4000 if(!strucmp(ps_global->VAR_GOTO_DEFAULT_RULE, S_OR_L(v))){
4001 ps_global->goto_default_rule = v->value;
4002 break;
4005 else if(var == &ps_global->vars[V_INCOMING_STARTUP]){
4006 if(ps_global->VAR_INCOMING_STARTUP)
4007 for(i = 0; (v = incoming_startup_rules(i)); i++)
4008 if(!strucmp(ps_global->VAR_INCOMING_STARTUP, S_OR_L(v))){
4009 ps_global->inc_startup_rule = v->value;
4010 break;
4013 else if(var == &ps_global->vars[V_PRUNING_RULE]){
4014 if(ps_global->VAR_PRUNING_RULE)
4015 for(i = 0; (v = pruning_rules(i)); i++)
4016 if(!strucmp(ps_global->VAR_PRUNING_RULE, S_OR_L(v))){
4017 ps_global->pruning_rule = v->value;
4018 break;
4021 else if(var == &ps_global->vars[V_REOPEN_RULE]){
4022 if(ps_global->VAR_REOPEN_RULE)
4023 for(i = 0; (v = reopen_rules(i)); i++)
4024 if(!strucmp(ps_global->VAR_REOPEN_RULE, S_OR_L(v))){
4025 ps_global->reopen_rule = v->value;
4026 break;
4029 else if(var == &ps_global->vars[V_FLD_SORT_RULE]){
4030 if(ps_global->VAR_FLD_SORT_RULE)
4031 for(i = 0; (v = fld_sort_rules(i)); i++)
4032 if(!strucmp(ps_global->VAR_FLD_SORT_RULE, S_OR_L(v))){
4033 ps_global->fld_sort_rule = v->value;
4034 break;
4037 else if(var == &ps_global->vars[V_AB_SORT_RULE]){
4038 if(ps_global->VAR_AB_SORT_RULE)
4039 for(i = 0; (v = ab_sort_rules(i)); i++)
4040 if(!strucmp(ps_global->VAR_AB_SORT_RULE, S_OR_L(v))){
4041 ps_global->ab_sort_rule = v->value;
4042 break;
4045 else if(var == &ps_global->vars[V_THREAD_DISP_STYLE]){
4046 if(ps_global->VAR_THREAD_DISP_STYLE)
4047 for(i = 0; (v = thread_disp_styles(i)); i++)
4048 if(!strucmp(ps_global->VAR_THREAD_DISP_STYLE, S_OR_L(v))){
4049 ps_global->thread_disp_style = v->value;
4050 break;
4053 else if(var == &ps_global->vars[V_THREAD_INDEX_STYLE]){
4054 if(ps_global->VAR_THREAD_INDEX_STYLE)
4055 for(i = 0; (v = thread_index_styles(i)); i++)
4056 if(!strucmp(ps_global->VAR_THREAD_INDEX_STYLE, S_OR_L(v))){
4057 ps_global->thread_index_style = v->value;
4058 break;
4065 * Standard way to get at save message rules...
4067 NAMEVAL_S *
4068 save_msg_rules(int index)
4070 static NAMEVAL_S save_rules[] = {
4071 {"by-from", NULL, SAV_RULE_FROM},
4072 {"by-nick-of-from", NULL, SAV_RULE_NICK_FROM_DEF},
4073 {"by-nick-of-from-then-from", NULL, SAV_RULE_NICK_FROM},
4074 {"by-fcc-of-from", NULL, SAV_RULE_FCC_FROM_DEF},
4075 {"by-fcc-of-from-then-from", NULL, SAV_RULE_FCC_FROM},
4076 {"by-realname-of-from", NULL, SAV_RULE_RN_FROM_DEF},
4077 {"by-realname-of-from-then-from", NULL, SAV_RULE_RN_FROM},
4078 {"by-sender", NULL, SAV_RULE_SENDER},
4079 {"by-nick-of-sender", NULL, SAV_RULE_NICK_SENDER_DEF},
4080 {"by-nick-of-sender-then-sender", NULL, SAV_RULE_NICK_SENDER},
4081 {"by-fcc-of-sender", NULL, SAV_RULE_FCC_SENDER_DEF},
4082 {"by-fcc-of-sender-then-sender", NULL, SAV_RULE_FCC_SENDER},
4083 {"by-realname-of-sender", NULL, SAV_RULE_RN_SENDER_DEF},
4084 {"by-realname-of-sender-then-sender", NULL, SAV_RULE_RN_SENDER},
4085 {"by-recipient", NULL, SAV_RULE_RECIP},
4086 {"by-nick-of-recip", NULL, SAV_RULE_NICK_RECIP_DEF},
4087 {"by-nick-of-recip-then-recip", NULL, SAV_RULE_NICK_RECIP},
4088 {"by-fcc-of-recip", NULL, SAV_RULE_FCC_RECIP_DEF},
4089 {"by-fcc-of-recip-then-recip", NULL, SAV_RULE_FCC_RECIP},
4090 {"by-realname-of-recip", NULL, SAV_RULE_RN_RECIP_DEF},
4091 {"by-realname-of-recip-then-recip", NULL, SAV_RULE_RN_RECIP},
4092 {"by-replyto", NULL, SAV_RULE_REPLYTO},
4093 {"by-nick-of-replyto", NULL, SAV_RULE_NICK_REPLYTO_DEF},
4094 {"by-nick-of-replyto-then-replyto", NULL, SAV_RULE_NICK_REPLYTO},
4095 {"by-fcc-of-replyto", NULL, SAV_RULE_FCC_REPLYTO_DEF},
4096 {"by-fcc-of-replyto-then-replyto", NULL, SAV_RULE_FCC_REPLYTO},
4097 {"by-realname-of-replyto", NULL, SAV_RULE_RN_REPLYTO_DEF},
4098 {"by-realname-of-replyto-then-replyto", NULL, SAV_RULE_RN_REPLYTO},
4099 {"last-folder-used", NULL, SAV_RULE_LAST},
4100 {"default-folder", NULL, SAV_RULE_DEFLT}
4103 return((index >= 0 && index < (sizeof(save_rules)/sizeof(save_rules[0])))
4104 ? &save_rules[index] : NULL);
4109 * Standard way to get at fcc rules...
4111 NAMEVAL_S *
4112 fcc_rules(int index)
4114 static NAMEVAL_S f_rules[] = {
4115 {"default-fcc", NULL, FCC_RULE_DEFLT},
4116 {"last-fcc-used", NULL, FCC_RULE_LAST},
4117 {"by-recipient", NULL, FCC_RULE_RECIP},
4118 {"by-nickname", NULL, FCC_RULE_NICK},
4119 {"by-nick-then-recip", NULL, FCC_RULE_NICK_RECIP},
4120 {"current-folder", NULL, FCC_RULE_CURRENT}
4123 return((index >= 0 && index < (sizeof(f_rules)/sizeof(f_rules[0])))
4124 ? &f_rules[index] : NULL);
4129 * Standard way to get at addrbook sort rules...
4131 NAMEVAL_S *
4132 ab_sort_rules(int index)
4134 static NAMEVAL_S ab_rules[] = {
4135 {"fullname-with-lists-last", NULL, AB_SORT_RULE_FULL_LISTS},
4136 {"fullname", NULL, AB_SORT_RULE_FULL},
4137 {"nickname-with-lists-last", NULL, AB_SORT_RULE_NICK_LISTS},
4138 {"nickname", NULL, AB_SORT_RULE_NICK},
4139 {"dont-sort", NULL, AB_SORT_RULE_NONE}
4142 return((index >= 0 && index < (sizeof(ab_rules)/sizeof(ab_rules[0])))
4143 ? &ab_rules[index] : NULL);
4148 * Standard way to get at color styles.
4150 NAMEVAL_S *
4151 col_style(int index)
4153 static NAMEVAL_S col_styles[] = {
4154 {"no-color", NULL, COL_NONE},
4155 {"use-termdef", NULL, COL_TERMDEF},
4156 {"force-ansi-8color", NULL, COL_ANSI8},
4157 {"force-ansi-16color", NULL, COL_ANSI16},
4158 {"force-xterm-256color", NULL, COL_ANSI256}
4161 return((index >= 0 && index < (sizeof(col_styles)/sizeof(col_styles[0])))
4162 ? &col_styles[index] : NULL);
4167 * Standard way to get at index color styles.
4169 NAMEVAL_S *
4170 index_col_style(int index)
4172 static NAMEVAL_S ind_col_styles[] = {
4173 {"flip-colors", NULL, IND_COL_FLIP},
4174 {"reverse", NULL, IND_COL_REV},
4175 {"reverse-fg", NULL, IND_COL_FG},
4176 {"reverse-fg-no-ambiguity", NULL, IND_COL_FG_NOAMBIG},
4177 {"reverse-bg", NULL, IND_COL_BG},
4178 {"reverse-bg-no-ambiguity", NULL, IND_COL_BG_NOAMBIG}
4181 return((index >= 0 && index < (sizeof(ind_col_styles)/sizeof(ind_col_styles[0]))) ? &ind_col_styles[index] : NULL);
4186 * Standard way to get at titlebar color styles.
4188 NAMEVAL_S *
4189 titlebar_col_style(int index)
4191 static NAMEVAL_S tbar_col_styles[] = {
4192 {"default", NULL, TBAR_COLOR_DEFAULT},
4193 {"indexline", NULL, TBAR_COLOR_INDEXLINE},
4194 {"reverse-indexline", NULL, TBAR_COLOR_REV_INDEXLINE}
4197 return((index >= 0 && index < (sizeof(tbar_col_styles)/sizeof(tbar_col_styles[0]))) ? &tbar_col_styles[index] : NULL);
4202 * Standard way to get at folder sort rules...
4204 NAMEVAL_S *
4205 fld_sort_rules(int index)
4207 static NAMEVAL_S fdl_rules[] = {
4208 {"alphabetical", NULL, FLD_SORT_ALPHA},
4209 {"alpha-with-dirs-last", NULL, FLD_SORT_ALPHA_DIR_LAST},
4210 {"alpha-with-dirs-first", NULL, FLD_SORT_ALPHA_DIR_FIRST}
4213 return((index >= 0 && index < (sizeof(fdl_rules)/sizeof(fdl_rules[0])))
4214 ? &fdl_rules[index] : NULL);
4219 * Standard way to get at incoming startup rules...
4221 NAMEVAL_S *
4222 incoming_startup_rules(int index)
4224 static NAMEVAL_S is_rules[] = {
4225 {"first-unseen", NULL, IS_FIRST_UNSEEN},
4226 {"first-recent", NULL, IS_FIRST_RECENT},
4227 {"first-important", NULL, IS_FIRST_IMPORTANT},
4228 {"first-important-or-unseen", NULL, IS_FIRST_IMPORTANT_OR_UNSEEN},
4229 {"first-important-or-recent", NULL, IS_FIRST_IMPORTANT_OR_RECENT},
4230 {"first", NULL, IS_FIRST},
4231 {"last", NULL, IS_LAST}
4234 return((index >= 0 && index < (sizeof(is_rules)/sizeof(is_rules[0])))
4235 ? &is_rules[index] : NULL);
4239 NAMEVAL_S *
4240 startup_rules(int index)
4242 static NAMEVAL_S is2_rules[] = {
4243 {"first-unseen", NULL, IS_FIRST_UNSEEN},
4244 {"first-recent", NULL, IS_FIRST_RECENT},
4245 {"first-important", NULL, IS_FIRST_IMPORTANT},
4246 {"first-important-or-unseen", NULL, IS_FIRST_IMPORTANT_OR_UNSEEN},
4247 {"first-important-or-recent", NULL, IS_FIRST_IMPORTANT_OR_RECENT},
4248 {"first", NULL, IS_FIRST},
4249 {"last", NULL, IS_LAST},
4250 {"default", NULL, IS_NOTSET}
4253 return((index >= 0 && index < (sizeof(is2_rules)/sizeof(is2_rules[0])))
4254 ? &is2_rules[index] : NULL);
4259 * Standard way to get at pruning-rule values.
4261 NAMEVAL_S *
4262 pruning_rules(int index)
4264 static NAMEVAL_S pr_rules[] = {
4265 {"ask about rename, ask about deleting","ask-ask", PRUNE_ASK_AND_ASK},
4266 {"ask about rename, don't delete", "ask-no", PRUNE_ASK_AND_NO},
4267 {"always rename, ask about deleting", "yes-ask", PRUNE_YES_AND_ASK},
4268 {"always rename, don't delete", "yes-no", PRUNE_YES_AND_NO},
4269 {"don't rename, ask about deleting", "no-ask", PRUNE_NO_AND_ASK},
4270 {"don't rename, don't delete", "no-no", PRUNE_NO_AND_NO}
4273 return((index >= 0 && index < (sizeof(pr_rules)/sizeof(pr_rules[0])))
4274 ? &pr_rules[index] : NULL);
4279 * Standard way to get at reopen-rule values.
4281 NAMEVAL_S *
4282 reopen_rules(int index)
4284 static NAMEVAL_S ro_rules[] = {
4285 /* TRANSLATORS: short description of a feature option */
4286 {"Always reopen", "yes-yes",
4287 REOPEN_YES_YES},
4288 /* TRANSLATORS: short description of a feature option, default in brackets */
4289 {"Yes for POP/NNTP, Ask about other remote [Yes]", "yes-ask-y",
4290 REOPEN_YES_ASK_Y},
4291 /* TRANSLATORS: short description of a feature option, default in brackets */
4292 {"Yes for POP/NNTP, Ask about other remote [No]", "yes-ask-n",
4293 REOPEN_YES_ASK_N},
4294 /* TRANSLATORS: short description of a feature option */
4295 {"Yes for POP/NNTP, No for other remote", "yes-no",
4296 REOPEN_YES_NO},
4297 /* TRANSLATORS: short description of a feature option, default in brackets */
4298 {"Always ask [Yes]", "ask-ask-y",
4299 REOPEN_ASK_ASK_Y},
4300 /* TRANSLATORS: short description of a feature option, default in brackets */
4301 {"Always ask [No]", "ask-ask-n",
4302 REOPEN_ASK_ASK_N},
4303 /* TRANSLATORS: short description of a feature option, default in brackets */
4304 {"Ask about POP/NNTP [Yes], No for other remote", "ask-no-y",
4305 REOPEN_ASK_NO_Y},
4306 /* TRANSLATORS: short description of a feature option, default in brackets */
4307 {"Ask about POP/NNTP [No], No for other remote", "ask-no-n",
4308 REOPEN_ASK_NO_N},
4309 /* TRANSLATORS: short description of a feature option */
4310 {"Never reopen", "no-no",
4311 REOPEN_NO_NO},
4314 return((index >= 0 && index < (sizeof(ro_rules)/sizeof(ro_rules[0])))
4315 ? &ro_rules[index] : NULL);
4320 * Standard way to get at thread_disp_style values.
4322 NAMEVAL_S *
4323 thread_disp_styles(int index)
4325 static NAMEVAL_S td_styles[] = {
4326 {"none", "none", THREAD_NONE},
4327 {"show-thread-structure", "struct", THREAD_STRUCT},
4328 {"mutt-like", "mutt", THREAD_MUTTLIKE},
4329 {"indent-subject-1", "subj1", THREAD_INDENT_SUBJ1},
4330 {"indent-subject-2", "subj2", THREAD_INDENT_SUBJ2},
4331 {"indent-from-1", "from1", THREAD_INDENT_FROM1},
4332 {"indent-from-2", "from2", THREAD_INDENT_FROM2},
4333 {"show-structure-in-from", "struct-from", THREAD_STRUCT_FROM}
4336 return((index >= 0 && index < (sizeof(td_styles)/sizeof(td_styles[0])))
4337 ? &td_styles[index] : NULL);
4342 * Standard way to get at thread_index_style values.
4344 NAMEVAL_S *
4345 thread_index_styles(int index)
4347 static NAMEVAL_S ti_styles[] = {
4348 {"regular-index-with-expanded-threads", "exp", THRDINDX_EXP},
4349 {"regular-index-with-collapsed-threads","coll", THRDINDX_COLL},
4350 {"separate-index-screen-always", "sep", THRDINDX_SEP},
4351 {"separate-index-screen-except-for-single-messages","sep-auto",
4352 THRDINDX_SEP_AUTO}
4355 return((index >= 0 && index < (sizeof(ti_styles)/sizeof(ti_styles[0])))
4356 ? &ti_styles[index] : NULL);
4361 * Standard way to get at goto default rules...
4363 NAMEVAL_S *
4364 goto_rules(int index)
4366 static NAMEVAL_S g_rules[] = {
4367 {"folder-in-first-collection", NULL, GOTO_FIRST_CLCTN},
4368 {"inbox-or-folder-in-first-collection", NULL, GOTO_INBOX_FIRST_CLCTN},
4369 {"inbox-or-folder-in-recent-collection", NULL, GOTO_INBOX_RECENT_CLCTN},
4370 {"first-collection-with-inbox-default", NULL, GOTO_FIRST_CLCTN_DEF_INBOX},
4371 {"most-recent-folder", NULL, GOTO_LAST_FLDR}
4374 return((index >= 0 && index < (sizeof(g_rules)/sizeof(g_rules[0])))
4375 ? &g_rules[index] : NULL);
4379 NAMEVAL_S *
4380 pat_fldr_types(int index)
4382 static NAMEVAL_S pat_fldr_list[] = {
4383 {"Any", "ANY", FLDR_ANY},
4384 {"News", "NEWS", FLDR_NEWS},
4385 {"Email", "EMAIL", FLDR_EMAIL},
4386 {"Specific (Enter Incoming Nicknames or use ^T)", "SPEC", FLDR_SPECIFIC}
4389 return((index >= 0 &&
4390 index < (sizeof(pat_fldr_list)/sizeof(pat_fldr_list[0])))
4391 ? &pat_fldr_list[index] : NULL);
4395 NAMEVAL_S *
4396 inabook_fldr_types(int indexarg)
4398 static NAMEVAL_S inabook_fldr_list[] = {
4399 {"Don't care, always matches", "E", IAB_EITHER},
4400 {"Yes, in any address book", "YES", IAB_YES},
4401 {"No, not in any address book", "NO", IAB_NO},
4402 {"Yes, in specific address books", "SYES", IAB_SPEC_YES},
4403 {"No, not in any of specific address books", "SNO", IAB_SPEC_NO}
4406 int index = indexarg & IAB_TYPE_MASK;
4408 return((index >= 0 &&
4409 index < (sizeof(inabook_fldr_list)/sizeof(inabook_fldr_list[0])))
4410 ? &inabook_fldr_list[index] : NULL);
4414 NAMEVAL_S *
4415 filter_types(int index)
4417 static NAMEVAL_S filter_type_list[] = {
4418 {"Just Set Message Status", "NONE", FILTER_STATE},
4419 {"Delete", "DEL", FILTER_KILL},
4420 {"Move (Enter folder name(s) in primary collection, or use ^T)",
4421 "FLDR", FILTER_FOLDER}
4424 return((index >= 0 &&
4425 index < (sizeof(filter_type_list)/sizeof(filter_type_list[0])))
4426 ? &filter_type_list[index] : NULL);
4430 NAMEVAL_S *
4431 role_repl_types(int index)
4433 static NAMEVAL_S role_repl_list[] = {
4434 {"Never", "NO", ROLE_REPL_NO},
4435 {"With confirmation", "YES", ROLE_REPL_YES},
4436 {"Without confirmation", "NC", ROLE_REPL_NOCONF}
4439 return((index >= 0 &&
4440 index < (sizeof(role_repl_list)/sizeof(role_repl_list[0])))
4441 ? &role_repl_list[index] : NULL);
4445 NAMEVAL_S *
4446 role_forw_types(int index)
4448 static NAMEVAL_S role_forw_list[] = {
4449 {"Never", "NO", ROLE_FORW_NO},
4450 {"With confirmation", "YES", ROLE_FORW_YES},
4451 {"Without confirmation", "NC", ROLE_FORW_NOCONF}
4454 return((index >= 0 &&
4455 index < (sizeof(role_forw_list)/sizeof(role_forw_list[0])))
4456 ? &role_forw_list[index] : NULL);
4460 NAMEVAL_S *
4461 role_comp_types(int index)
4463 static NAMEVAL_S role_comp_list[] = {
4464 {"Never", "NO", ROLE_COMP_NO},
4465 {"With confirmation", "YES", ROLE_COMP_YES},
4466 {"Without confirmation", "NC", ROLE_COMP_NOCONF}
4469 return((index >= 0 &&
4470 index < (sizeof(role_comp_list)/sizeof(role_comp_list[0])))
4471 ? &role_comp_list[index] : NULL);
4475 NAMEVAL_S *
4476 role_status_types(int index)
4478 static NAMEVAL_S role_status_list[] = {
4479 {"Don't care, always matches", "E", PAT_STAT_EITHER},
4480 {"Yes", "YES", PAT_STAT_YES},
4481 {"No", "NO", PAT_STAT_NO}
4484 return((index >= 0 &&
4485 index < (sizeof(role_status_list)/sizeof(role_status_list[0])))
4486 ? &role_status_list[index] : NULL);
4490 NAMEVAL_S *
4491 msg_state_types(int index)
4493 static NAMEVAL_S msg_state_list[] = {
4494 {"Don't change it", "LV", ACT_STAT_LEAVE},
4495 {"Set this state", "SET", ACT_STAT_SET},
4496 {"Clear this state", "CLR", ACT_STAT_CLEAR}
4499 return((index >= 0 &&
4500 index < (sizeof(msg_state_list)/sizeof(msg_state_list[0])))
4501 ? &msg_state_list[index] : NULL);
4505 #ifdef ENABLE_LDAP
4506 NAMEVAL_S *
4507 ldap_search_rules(int index)
4509 static NAMEVAL_S ldap_search_list[] = {
4510 {"contains", NULL, LDAP_SRCH_CONTAINS},
4511 {"equals", NULL, LDAP_SRCH_EQUALS},
4512 {"begins-with", NULL, LDAP_SRCH_BEGINS},
4513 {"ends-with", NULL, LDAP_SRCH_ENDS}
4516 return((index >= 0 &&
4517 index < (sizeof(ldap_search_list)/sizeof(ldap_search_list[0])))
4518 ? &ldap_search_list[index] : NULL);
4522 NAMEVAL_S *
4523 ldap_search_types(int index)
4525 static NAMEVAL_S ldap_types_list[] = {
4526 {"name", NULL, LDAP_TYPE_CN},
4527 {"surname", NULL, LDAP_TYPE_SUR},
4528 {"givenname", NULL, LDAP_TYPE_GIVEN},
4529 {"email", NULL, LDAP_TYPE_EMAIL},
4530 {"name-or-email", NULL, LDAP_TYPE_CN_EMAIL},
4531 {"surname-or-givenname", NULL, LDAP_TYPE_SUR_GIVEN},
4532 {"sur-or-given-or-name-or-email", NULL, LDAP_TYPE_SEVERAL}
4535 return((index >= 0 &&
4536 index < (sizeof(ldap_types_list)/sizeof(ldap_types_list[0])))
4537 ? &ldap_types_list[index] : NULL);
4541 NAMEVAL_S *
4542 ldap_search_scope(int index)
4544 static NAMEVAL_S ldap_scope_list[] = {
4545 {"base", NULL, LDAP_SCOPE_BASE},
4546 {"onelevel", NULL, LDAP_SCOPE_ONELEVEL},
4547 {"subtree", NULL, LDAP_SCOPE_SUBTREE}
4550 return((index >= 0 &&
4551 index < (sizeof(ldap_scope_list)/sizeof(ldap_scope_list[0])))
4552 ? &ldap_scope_list[index] : NULL);
4554 #endif
4558 * Choose from the global default, command line args, pinerc values to set
4559 * the actual value of the variable that we will use. Start at the top
4560 * and work down from higher to lower precedence.
4561 * For lists, we may inherit values from lower precedence
4562 * versions if that's the way the user specifies it.
4563 * The user can put INHERIT_DEFAULT as the first entry in a list and that
4564 * means it will inherit the current values, for example the values
4565 * from the global_val, or the value from the main_user_val could be
4566 * inherited in the post_user_val.
4568 void
4569 set_current_val(struct variable *var, int expand, int cmdline)
4571 int is_set[5], is_inherit[5];
4572 int i, j, k, cnt, start;
4573 char **tmp, **t, **list[5];
4574 char *p;
4576 dprint((9,
4577 "set_current_val(var=%s%s, expand=%d, cmdline=%d)\n",
4578 (var && var->name) ? var->name : "?",
4579 (var && var->is_list) ? " (list)" : "",
4580 expand, cmdline));
4582 if(!var)
4583 return;
4585 if(var->is_list){ /* variable is a list */
4587 for(j = 0; j < 5; j++){
4588 t = j==0 ? var->global_val.l :
4589 j==1 ? var->main_user_val.l :
4590 j==2 ? var->post_user_val.l :
4591 j==3 ? ((cmdline) ? var->cmdline_val.l : NULL) :
4592 var->fixed_val.l;
4594 is_set[j] = is_inherit[j] = 0;
4595 list[j] = NULL;
4597 if(t){
4598 if(!expand){
4599 is_set[j]++;
4600 list[j] = t;
4602 else{
4603 for(i = 0; t[i]; i++){
4604 if(expand_variables(tmp_20k_buf, SIZEOF_20KBUF, t[i],
4605 0)){
4606 /* successful expand */
4607 is_set[j]++;
4608 list[j] = t;
4609 break;
4614 if(list[j] && list[j][0] && !strcmp(list[j][0],INHERIT))
4615 is_inherit[j]++;
4619 cnt = 0;
4620 start = 0;
4621 /* count how many items in current_val list */
4622 /* Admin wants default, which is global_val. */
4623 if(var->is_fixed && var->fixed_val.l == NULL){
4624 cnt = 0;
4625 if(is_set[0]){
4626 for(; list[0][cnt]; cnt++)
4630 else{
4631 for(j = 0; j < 5; j++){
4632 if(is_set[j]){
4633 if(!is_inherit[j]){
4634 cnt = 0; /* reset */
4635 start = j;
4638 for(i = is_inherit[j] ? 1 : 0; list[j][i]; i++)
4639 cnt++;
4644 free_list_array(&var->current_val.l); /* clean up any old values */
4646 /* check to see if anything is set */
4647 if(is_set[0] + is_set[1] + is_set[2] + is_set[3] + is_set[4] > 0){
4648 var->current_val.l = (char **)fs_get((cnt+1)*sizeof(char *));
4649 tmp = var->current_val.l;
4650 if(var->is_fixed && var->fixed_val.l == NULL){
4651 if(is_set[0]){
4652 for(i = 0; list[0][i]; i++){
4653 if(!expand)
4654 *tmp++ = cpystr(list[0][i]);
4655 else if(expand_variables(tmp_20k_buf, SIZEOF_20KBUF,
4656 list[0][i], 0))
4657 *tmp++ = cpystr(tmp_20k_buf);
4661 else{
4662 for(j = start; j < 5; j++){
4663 if(is_set[j]){
4664 for(i = is_inherit[j] ? 1 : 0; list[j][i]; i++){
4665 if(!expand)
4666 *tmp++ = cpystr(list[j][i]);
4667 else if(expand_variables(tmp_20k_buf,SIZEOF_20KBUF,
4668 list[j][i], 0))
4669 *tmp++ = cpystr(tmp_20k_buf);
4675 *tmp = NULL;
4677 else
4678 var->current_val.l = NULL;
4680 else{ /* variable is not a list */
4681 char *strvar = NULL;
4683 for(j = 0; j < 5; j++){
4685 p = j==0 ? var->fixed_val.p :
4686 j==1 ? ((cmdline) ? var->cmdline_val.p : NULL) :
4687 j==2 ? var->post_user_val.p :
4688 j==3 ? var->main_user_val.p :
4689 var->global_val.p;
4691 is_set[j] = 0;
4693 if(p){
4694 if(!expand){
4695 is_set[j]++;
4696 if(!strvar)
4697 strvar = p;
4699 else if(expand_variables(tmp_20k_buf, SIZEOF_20KBUF, p,
4700 (var == &ps_global->vars[V_MAILCAP_PATH] ||
4701 var == &ps_global->vars[V_MIMETYPE_PATH]))){
4702 is_set[j]++;
4703 if(!strvar)
4704 strvar = p;
4709 /* Admin wants default, which is global_val. */
4710 if(var->is_fixed && var->fixed_val.p == NULL)
4711 strvar = var->global_val.p;
4713 if(var->current_val.p) /* free previous value */
4714 fs_give((void **)&var->current_val.p);
4716 if(strvar){
4717 if(!expand)
4718 var->current_val.p = cpystr(strvar);
4719 else{
4720 expand_variables(tmp_20k_buf, SIZEOF_20KBUF, strvar,
4721 (var == &ps_global->vars[V_MAILCAP_PATH] ||
4722 var == &ps_global->vars[V_MIMETYPE_PATH]));
4723 var->current_val.p = cpystr(tmp_20k_buf);
4726 else
4727 var->current_val.p = NULL;
4730 if(var->is_fixed && !is_inherit[4]){
4731 char **flist;
4732 int fixed_len, user_len;
4735 * sys mgr fixed this variable and user is trying to change it
4737 for(k = 1; !(ps_global->give_fixed_warning &&
4738 ps_global->fix_fixed_warning) && k <= 3; k++){
4739 if(is_set[k]){
4740 if(var->is_list){
4741 t = k==1 ? ((cmdline) ? var->cmdline_val.l : NULL) :
4742 k==2 ? var->post_user_val.l :
4743 var->main_user_val.l;
4745 /* If same length and same contents, don't warn. */
4746 for(flist=var->fixed_val.l; flist && *flist; flist++)
4747 ;/* just counting */
4749 fixed_len = var->fixed_val.l ? (flist - var->fixed_val.l)
4750 : 0;
4751 for(flist=t; flist && *flist; flist++)
4752 ;/* just counting */
4754 user_len = t ? (flist - t) : 0;
4755 if(user_len == fixed_len){
4756 for(i=0; i < user_len; i++){
4757 for(j=0; j < user_len; j++)
4758 if(!strucmp(t[i], var->fixed_val.l[j]))
4759 break;
4761 if(j == user_len){
4762 ps_global->give_fixed_warning = 1;
4763 if(k != 1)
4764 ps_global->fix_fixed_warning = 1;
4766 break;
4770 else{
4771 ps_global->give_fixed_warning = 1;
4772 if(k != 1)
4773 ps_global->fix_fixed_warning = 1;
4776 else{
4777 p = k==1 ? ((cmdline) ? var->cmdline_val.p : NULL) :
4778 k==2 ? var->post_user_val.p :
4779 var->main_user_val.p;
4781 if((var->fixed_val.p && !p) ||
4782 (!var->fixed_val.p && p) ||
4783 (var->fixed_val.p && p && strucmp(var->fixed_val.p, p))){
4784 ps_global->give_fixed_warning = 1;
4785 if(k != 1)
4786 ps_global->fix_fixed_warning = 1;
4795 void
4796 set_news_spec_current_val(int expand, int cmdline)
4798 struct variable *newsvar = &ps_global->vars[V_NEWS_SPEC];
4799 struct variable *fvar = &ps_global->vars[V_FOLDER_SPEC];
4801 /* check to see if it has a value */
4802 set_current_val(newsvar, expand, cmdline);
4805 * If no value, we might want to fake a value. We'll do that if
4806 * there is no news collection already defined in FOLDER_SPEC and if
4807 * there is also an NNTP_SERVER defined.
4809 if(!newsvar->current_val.l && ps_global->VAR_NNTP_SERVER &&
4810 ps_global->VAR_NNTP_SERVER[0] && ps_global->VAR_NNTP_SERVER[0][0] &&
4811 !news_in_folders(fvar)){
4812 char buf[MAXPATH];
4814 newsvar->global_val.l = (char **)fs_get(2 * sizeof(char *));
4815 snprintf(buf, sizeof(buf), "{%.*s/nntp}#news.[]", MAXPATH-20,
4816 ps_global->VAR_NNTP_SERVER[0]); /* MAXPATH = sizeof(buf) */
4817 newsvar->global_val.l[0] = cpystr(buf);
4818 newsvar->global_val.l[1] = NULL;
4819 set_current_val(newsvar, expand, cmdline);
4821 * But we're going to get rid of the fake global_val in case
4822 * things change.
4824 free_list_array(&newsvar->global_val.l);
4830 * Feature-list has to be handled separately from the other variables
4831 * because it is additive. The other variables choose one of command line,
4832 * or pine.conf, or pinerc. Feature list adds them. This could easily be
4833 * converted to a general purpose routine if we add more additive variables.
4835 * This works by replacing earlier values with later ones. That is, command
4836 * line settings have higher precedence than global settings and that is
4837 * accomplished by putting the command line features after the global
4838 * features in the list. When they are processed, the last one wins.
4840 * Feature-list also has a backwards compatibility hack.
4842 void
4843 set_feature_list_current_val(struct variable *var)
4845 char **list;
4846 char **list_fixed;
4847 char no_allow[50];
4848 int i, j, k, m,
4849 elems = 0;
4851 /* count the lists so we can allocate */
4852 for(m = 0; m < 6; m++){
4853 list = m==0 ? var->global_val.l :
4854 m==1 ? var->main_user_val.l :
4855 m==2 ? var->post_user_val.l :
4856 m==3 ? ps_global->feat_list_back_compat :
4857 m==4 ? var->cmdline_val.l :
4858 var->fixed_val.l;
4859 if(list)
4860 for(i = 0; list[i]; i++)
4861 elems++;
4864 list_fixed = var->fixed_val.l;
4866 if(var->current_val.l)
4867 free_list_array(&var->current_val.l);
4869 var->current_val.l = (char **)fs_get((elems+1) * sizeof(char *));
4872 * We need to warn the user if the sys mgr has restricted him or her
4873 * from changing a feature that he or she is trying to change.
4875 * We're not catching the old-growth macro since we're just comparing
4876 * strings. That is, it works correctly, but the user won't be warned
4877 * if the user old-growth and the mgr says no-quit-without-confirm.
4880 j = 0;
4881 strncpy(no_allow, "no-", 3);
4882 strncpy(no_allow+3, feature_list_name(F_ALLOW_CHANGING_FROM), sizeof(no_allow)-3-1);
4883 no_allow[sizeof(no_allow)-1] = '\0';
4885 for(m = 0; m < 6; m++){
4886 list = m==0 ? var->global_val.l :
4887 m==1 ? var->main_user_val.l :
4888 m==2 ? var->post_user_val.l :
4889 m==3 ? ps_global->feat_list_back_compat :
4890 m==4 ? var->cmdline_val.l :
4891 var->fixed_val.l;
4892 if(list)
4893 for(i = 0; list[i]; i++){
4894 var->current_val.l[j++] = cpystr(list[i]);
4896 /* this is the warning section */
4897 if(m >= 1 && m <= 4){
4898 for(k = 0; list_fixed && list_fixed[k]; k++){
4899 char *p, *q;
4900 p = list[i];
4901 q = list_fixed[k];
4902 if(!struncmp(p, "no-", 3))
4903 p += 3;
4904 if(!struncmp(q, "no-", 3))
4905 q += 3;
4906 if(!strucmp(q, p) && strucmp(list[i], list_fixed[k])){
4907 ps_global->give_fixed_warning = 1;
4908 if(m <= 2)
4909 ps_global->fix_fixed_warning = 1;
4913 else if(m == 5 && !strucmp(list[i], no_allow))
4914 ps_global->never_allow_changing_from = 1;
4918 #ifdef NEVER_ALLOW_CHANGING_FROM
4919 ps_global->never_allow_changing_from = 1;
4920 #endif
4922 var->current_val.l[j] = NULL;
4927 /*----------------------------------------------------------------------
4929 Expand Metacharacters/variables in file-names
4931 Read input line and expand shell-variables/meta-characters
4933 <input> <replaced by>
4934 $variable getenv("variable")
4935 ${variable} getenv("variable")
4936 ${variable:-defvalue} is getenv("variable") if variable is defined and
4937 is defvalue otherwise
4938 ~ getenv("HOME")
4939 \c c
4940 <others> <just copied>
4942 NOTE handling of braces in ${name} doesn't check much or do error recovery
4944 If colon_path is set, then we expand ~ not only at the start of linein,
4945 but also after each : in the path.
4947 ----*/
4948 #define is_allowed_envchar(C, S) ((S) == 0 ? !isspace((C)) && (C) != '/'\
4949 : (((C) >= 'a' && (C) <= 'z') \
4950 || ((C) >= 'A' && (C) <= 'Z') \
4951 || ((C) >= '0' && (C) <= '9')))
4953 char *
4954 expand_variables(char *lineout, size_t lineoutlen, char *linein, int colon_path)
4956 char *src = linein, *dest = lineout, *p;
4957 char *limit = lineout + lineoutlen;
4958 int envexpand = 0, sp;
4960 if(!linein)
4961 return(NULL);
4963 sp = strncmp(src,"LIT:pattern=\"/NICK=", strlen("LIT:pattern=\"/NICK=")) == 0;
4964 while(*src ){ /* something in input string */
4965 if(*src == '$' && *(src+1) == '$'){
4967 * $$ to escape chars we're interested in, else
4968 * it's up to the user of the variable to handle the
4969 * backslash...
4971 if(dest < limit)
4972 *dest++ = *++src; /* copy next as is */
4973 }else
4974 #if !(defined(DOS) || defined(OS2))
4975 if(*src == '\\' && *(src+1) == '$'){
4977 * backslash to escape chars we're interested in, else
4978 * it's up to the user of the variable to handle the
4979 * backslash...
4981 if(dest < limit)
4982 *dest++ = *++src; /* copy next as is */
4983 }else if(*src == '~' &&
4984 (src == linein || (colon_path && *(src-1) == ':'))){
4985 char buf[MAXPATH];
4986 int i;
4988 for(i = 0; i < sizeof(buf)-1 && src[i] && src[i] != '/'; i++)
4989 buf[i] = src[i];
4991 src += i; /* advance src pointer */
4992 buf[i] = '\0'; /* tie off buf string */
4993 fnexpand(buf, sizeof(buf)); /* expand the path */
4995 for(p = buf; dest < limit && (*dest = *p); p++, dest++)
4998 continue;
4999 }else
5000 #endif
5001 if(*src == '$'){ /* shell variable */
5002 char word[128+1], *colon = NULL, *rbrace = NULL;
5004 envexpand++; /* signal that we've expanded a var */
5005 src++; /* skip dollar */
5006 if(*src == '{'){ /* starts with brace? */
5007 src++;
5008 rbrace = strindex(src, '}');
5009 if(rbrace){
5010 /* look for default value */
5011 colon = strstr(src, ":-");
5012 if(colon && (rbrace < colon))
5013 colon = NULL;
5017 p = word;
5019 /* put the env variable to be looked up in word */
5020 if(rbrace){
5021 while(*src
5022 && (p-word < sizeof(word)-1)
5023 && ((colon && src < colon) || (!colon && src < rbrace))){
5024 if(isspace((unsigned char) *src)){
5026 * Illegal input. This should be an error of some
5027 * sort but instead of that we'll just backup to the
5028 * $ and treat it like it wasn't there.
5030 while(*src != '$')
5031 src--;
5033 envexpand--;
5034 goto just_copy;
5036 else
5037 *p++ = *src++;
5040 /* adjust src for next char */
5041 src = rbrace + 1;
5043 else{
5044 while(*src && is_allowed_envchar((unsigned char) *src, sp)
5045 && (p-word < sizeof(word)-1))
5046 *p++ = *src++;
5049 *p = '\0';
5051 if((p = getenv(word)) != NULL){ /* check for word in environment */
5052 while(*p && dest < limit)
5053 *dest++ = *p++;
5055 else if(colon){ /* else possible default value */
5056 p = colon + 2;
5057 while(*p && p < rbrace && dest < limit)
5058 *dest++ = *p++;
5061 continue;
5062 }else{ /* other cases: just copy */
5063 just_copy:
5064 if(dest < limit)
5065 *dest++ = *src;
5068 if(*src) /* next character (if any) */
5069 src++;
5072 if(dest < limit)
5073 *dest = '\0';
5074 else
5075 lineout[lineoutlen-1] = '\0';
5077 return((envexpand && lineout[0] == '\0') ? NULL : lineout);
5081 /*----------------------------------------------------------------------
5082 Sets login, full_username and home_dir
5084 Args: ps -- The Pine structure to put the user name, etc in
5086 Result: sets the fullname, login and home_dir field of the pine structure
5087 returns 0 on success, -1 if not.
5088 ----*/
5089 #define MAX_INIT_ERRS 10
5090 void
5091 init_error(struct pine *ps, int flags, int min_time, int max_time, char *message)
5093 int i;
5095 if(!ps->init_errs){
5096 ps->init_errs = (INIT_ERR_S *)fs_get((MAX_INIT_ERRS + 1) *
5097 sizeof(*ps->init_errs));
5098 memset(ps->init_errs, 0, (MAX_INIT_ERRS + 1) * sizeof(*ps->init_errs));
5101 for(i = 0; i < MAX_INIT_ERRS; i++)
5102 if(!(ps->init_errs)[i].message){
5103 (ps->init_errs)[i].message = cpystr(message);
5104 (ps->init_errs)[i].min_time = min_time;
5105 (ps->init_errs)[i].max_time = max_time;
5106 (ps->init_errs)[i].flags = flags;
5107 dprint((2, "%s\n", message ? message : "?"));
5108 break;
5113 /*----------------------------------------------------------------------
5114 Read and parse a pinerc file
5116 Args: Filename -- name of the .pinerc file to open and read
5117 vars -- The vars structure to store values in
5118 which_vars -- Whether the local or global values are being read
5120 Result:
5122 This may be the local file or the global file. The values found are
5123 merged with the values currently in vars. All values are strings and
5124 are malloced; and existing values will be freed before the assignment.
5125 Those that are <unset> will be left unset; their values will be NULL.
5126 ----*/
5127 void
5128 read_pinerc(PINERC_S *prc, struct variable *vars, ParsePinerc which_vars)
5130 char *filename, *file, *value, **lvalue, *line, *error;
5131 char *p, *p1, *free_file = NULL;
5132 struct variable *v;
5133 PINERC_LINE *pline = NULL;
5134 int line_count, was_quoted;
5135 int i;
5137 if(!prc)
5138 return;
5140 dprint((2, "reading_pinerc \"%s\"\n",
5141 prc->name ? prc->name : "?"));
5143 if(prc->type == Loc){
5144 filename = prc->name ? prc->name : "";
5145 file = free_file = read_file(filename, 0);
5148 * This is questionable. In case the user edits the pinerc
5149 * in Windows and adds a UTF-8 BOM, we skip it here. If the
5150 * user adds a Unicode BOM we're in trouble. We could write it
5151 * with the BOM ourselves but so far we leave it BOMless in
5152 * order that it's the same on Unix and Windows.
5154 if(BOM_UTF8(file))
5155 file += 3;
5157 else{
5158 if((file = read_remote_pinerc(prc, which_vars)) != NULL)
5159 ps_global->c_client_error[0] = '\0';
5161 free_file = file;
5164 if(file == NULL || *file == '\0'){
5165 #ifdef DEBUG
5166 if(file == NULL){
5167 dprint((2, "Open failed: %s\n", error_description(errno)));
5169 else{
5170 if(prc->type == Loc){
5171 dprint((1, "Read_pinerc: empty pinerc (new?)\n"));
5173 else{
5174 dprint((1, "Read_pinerc: new remote pinerc\n"));
5177 #endif /* DEBUG */
5179 if(which_vars == ParsePers){
5180 /* problems getting remote config */
5181 if(file == NULL && prc->type == RemImap){
5182 if(!pith_opt_remote_pinerc_failure
5183 || !(*pith_opt_remote_pinerc_failure)())
5184 exceptional_exit(_("Unable to read or write remote configuration"), -1);
5187 ps_global->first_time_user = 1;
5188 prc->outstanding_pinerc_changes = 1;
5191 return;
5193 else{
5194 if(prc->type == Loc &&
5195 (which_vars == ParseFixed || which_vars == ParseGlobal ||
5196 (can_access(filename, ACCESS_EXISTS) == 0 &&
5197 can_access(filename, EDIT_ACCESS) != 0))){
5198 prc->readonly = 1;
5199 if(prc == ps_global->prc)
5200 ps_global->readonly_pinerc = 1;
5204 * accept CRLF or LF newlines
5206 for(p = file; *p && *p != '\012'; p++)
5209 if(p > file && *p && *(p-1) == '\015') /* cvt crlf to lf */
5210 for(p1 = p - 1; (*p1 = *p) != '\0'; p++)
5211 if(!(*p == '\015' && *(p+1) == '\012'))
5212 p1++;
5215 dprint((2, "Read %d characters:\n", strlen(file)));
5217 if(which_vars == ParsePers || which_vars == ParsePersPost){
5218 /*--- Count up lines and allocate structures */
5219 for(line_count = 0, p = file; *p != '\0'; p++)
5220 if(*p == '\n')
5221 line_count++;
5223 prc->pinerc_lines = (PINERC_LINE *)
5224 fs_get((3 + line_count) * sizeof(PINERC_LINE));
5225 memset((void *)prc->pinerc_lines, 0,
5226 (3 + line_count) * sizeof(PINERC_LINE));
5227 pline = prc->pinerc_lines;
5230 for(p = file, line = file; *p != '\0';){
5231 /*----- Grab the line ----*/
5232 line = p;
5233 while(*p && *p != '\n')
5234 p++;
5235 if(*p == '\n'){
5236 *p++ = '\0';
5239 /*----- Comment Line -----*/
5240 if(*line == '#'){
5241 /* no comments in remote pinercs */
5242 if(pline && prc->type == Loc){
5243 pline->is_var = 0;
5244 pline->line = cpystr(line);
5245 pline++;
5247 continue;
5250 if(*line == '\0' || *line == '\t' || *line == ' '){
5251 p1 = line;
5252 while(*p1 == '\t' || *p1 == ' ')
5253 p1++;
5254 if(pline){
5256 * This could be a continuation line from some future
5257 * version of pine, or it could be a continuation line
5258 * from a PC-Pine variable we don't know about in unix.
5260 if(*p1 != '\0')
5261 pline->line = cpystr(line);
5262 else
5263 pline->line = cpystr("");
5264 pline->is_var = 0;
5265 pline++;
5267 continue;
5270 /*----- look up matching 'v' and leave "value" after '=' ----*/
5271 for(v = vars; *line && v->name; v++)
5272 if((i = strlen(v->name)) < strlen(line) && !struncmp(v->name,line,i)){
5273 int j;
5275 for(j = i; line[j] == ' ' || line[j] == '\t'; j++)
5278 if(line[j] == '='){ /* bingo! */
5279 for(value = &line[j+1];
5280 *value == ' ' || *value == '\t';
5281 value++)
5284 break;
5286 /* else either unrecognized var or bogus line */
5289 /*----- Didn't match any variable or bogus format -----*/
5291 * This could be a variable from some future
5292 * version of pine, or it could be a PC-Pine variable
5293 * we don't know about in unix. Either way, we want to preserve
5294 * it in the file.
5296 if(!v->name){
5297 if(pline){
5298 pline->is_var = 0;
5299 pline->line = cpystr(line);
5300 pline++;
5302 continue;
5306 * Previous versions have caused duplicate pinerc data to be
5307 * written to pinerc files. This clause erases the duplicate
5308 * information when we read it, and it will be removed from the file
5309 * if we call write_pinerc. We test to see if the same variable
5310 * appears later in the file, if so, we skip over it here.
5311 * We don't care about duplicates if this isn't a pinerc we might
5312 * write out, so include pline in the conditional.
5313 * Note that we will leave all of the duplicate comments and blank
5314 * lines in the file unless it is a remote pinerc. Luckily, the
5315 * bug that caused the duplicates only applied to remote pinercs,
5316 * so we should have that case covered.
5318 * If we find a duplicate, we point p to the start
5319 * of the next line that should be considered, and then skip back
5320 * to the top of the loop.
5322 if(pline && var_is_in_rest_of_file(v->name, p)){
5323 if(v->is_list)
5324 p = skip_over_this_var(line, p);
5326 continue;
5330 /*----- Obsolete variable, read it anyway below, might use it -----*/
5331 if(v->is_obsolete){
5332 if(pline){
5333 pline->obsolete_var = 1;
5334 pline->line = cpystr(line);
5335 pline->var = v;
5339 /*----- Variable is in the list but unused for some reason -----*/
5340 if(!v->is_used){
5341 if(pline){
5342 pline->is_var = 0;
5343 pline->line = cpystr(line);
5344 pline++;
5346 continue;
5349 /*--- Var is not user controlled, leave it alone for back compat ---*/
5350 if(!v->is_user && pline){
5351 pline->is_var = 0;
5352 pline->line = cpystr(line);
5353 pline++;
5354 continue;
5357 if(which_vars == ParseFixed)
5358 v->is_fixed = 1;
5360 /*---- variable is unset, or it's global but expands to nothing ----*/
5361 if(!*value
5362 || (which_vars == ParseGlobal
5363 && !expand_variables(tmp_20k_buf, SIZEOF_20KBUF, value,
5364 (v == &ps_global->vars[V_MAILCAP_PATH] ||
5365 v == &ps_global->vars[V_MIMETYPE_PATH])))){
5366 if(v->is_user && pline){
5367 pline->is_var = 1;
5368 pline->var = v;
5369 pline++;
5371 continue;
5374 /*--value is non-empty, store it handling quotes and trailing space--*/
5375 if(*value == '"' && !v->is_list && v->del_quotes){
5376 was_quoted = 1;
5377 value++;
5378 for(p1 = value; *p1 && *p1 != '"'; p1++);
5379 if(*p1 == '"')
5380 *p1 = '\0';
5381 else
5382 removing_trailing_white_space(value);
5383 }else
5384 was_quoted = 0;
5387 * List Entry Parsing
5389 * The idea is to parse a comma separated list of
5390 * elements, preserving quotes, and understanding
5391 * continuation lines (that is ',' == "\n ").
5392 * Quotes must be balanced within elements. Space
5393 * within elements is preserved, but leading and trailing
5394 * space is trimmed. This is a generic function, and it's
5395 * left to the the functions that use the lists to make sure
5396 * they contain valid data...
5398 if(v->is_list){
5400 was_quoted = 0;
5401 line_count = 0;
5402 p1 = value;
5403 while(1){ /* generous count of list elements */
5404 if(*p1 == '"') /* ignore ',' if quoted */
5405 was_quoted = (was_quoted) ? 0 : 1 ;
5407 if((*p1 == ',' && !was_quoted) || *p1 == '\n' || *p1 == '\0')
5408 line_count++; /* count this element */
5410 if(*p1 == '\0' || *p1 == '\n'){ /* deal with EOL */
5411 if(p1 < p || *p1 == '\n'){
5412 *p1++ = ','; /* fix null or newline */
5414 if(*p1 != '\t' && *p1 != ' '){
5415 *(p1-1) = '\0'; /* tie off list */
5416 p = p1; /* reset p */
5417 break;
5419 }else{
5420 p = p1; /* end of pinerc */
5421 break;
5423 }else
5424 p1++;
5427 error = NULL;
5428 lvalue = parse_list(value, line_count,
5429 v->del_quotes ? PL_REMSURRQUOT : PL_NONE,
5430 &error);
5431 if(error){
5432 dprint((1,
5433 "read_pinerc: ERROR: %s in %s = \"%s\"\n",
5434 error ? error : "?",
5435 v->name ? v->name : "?",
5436 value ? value : "?"));
5439 * Special case: turn "" strings into empty strings.
5440 * This allows users to turn off default lists. For example,
5441 * if smtp-server is set then a user could override smtp-server
5442 * with smtp-server="".
5444 for(i = 0; lvalue[i]; i++)
5445 if(lvalue[i][0] == '"' &&
5446 lvalue[i][1] == '"' &&
5447 lvalue[i][2] == '\0')
5448 lvalue[i][0] = '\0';
5451 if(pline){
5452 if(v->is_user && (which_vars == ParsePers || !v->is_onlymain)){
5453 if(v->is_list){
5454 char ***l;
5456 l = (which_vars == ParsePers) ? &v->main_user_val.l
5457 : &v->post_user_val.l;
5458 free_list_array(l);
5459 *l = lvalue;
5461 else{
5462 char **p;
5464 p = (which_vars == ParsePers) ? &v->main_user_val.p
5465 : &v->post_user_val.p;
5466 if(p && *p != NULL)
5467 fs_give((void **)p);
5469 *p = cpystr(value);
5472 if(pline){
5473 pline->is_var = 1;
5474 pline->var = v;
5475 pline->is_quoted = was_quoted;
5476 pline++;
5480 else if(which_vars == ParseGlobal){
5481 if(v->is_global){
5482 if(v->is_list){
5483 free_list_array(&v->global_val.l);
5484 v->global_val.l = lvalue;
5486 else{
5487 if(v->global_val.p != NULL)
5488 fs_give((void **) &(v->global_val.p));
5490 v->global_val.p = cpystr(value);
5494 else{ /* which_vars == ParseFixed */
5495 if(v->is_user || v->is_global){
5496 if(v->is_list){
5497 free_list_array(&v->fixed_val.l);
5498 v->fixed_val.l = lvalue;
5500 else{
5501 if(v->fixed_val.p != NULL)
5502 fs_give((void **) &(v->fixed_val.p));
5504 v->fixed_val.p = cpystr(value);
5509 #ifdef DEBUG
5510 if(v->is_list){
5511 char **l;
5512 l = (which_vars == ParsePers) ? v->main_user_val.l :
5513 (which_vars == ParsePersPost) ? v->post_user_val.l :
5514 (which_vars == ParseGlobal) ? v->global_val.l :
5515 v->fixed_val.l;
5516 if(l && *l && **l){
5517 dprint((5, " %20.20s : %s\n",
5518 v->name ? v->name : "?",
5519 *l ? *l : "?"));
5520 while(++l && *l && **l)
5521 dprint((5, " %20.20s : %s\n", "",
5522 *l ? *l : "?"));
5524 }else{
5525 char *p;
5526 p = (which_vars == ParsePers) ? v->main_user_val.p :
5527 (which_vars == ParsePersPost) ? v->post_user_val.p :
5528 (which_vars == ParseGlobal) ? v->global_val.p :
5529 v->fixed_val.p;
5530 if(p && *p)
5531 dprint((5, " %20.20s : %s\n",
5532 v->name ? v->name : "?",
5533 p ? p : "?"));
5535 #endif /* DEBUG */
5538 if(pline){
5539 pline->line = NULL;
5540 pline->is_var = 0;
5541 if(!prc->pinerc_written && prc->type == Loc){
5542 prc->pinerc_written = name_file_mtime(filename);
5543 dprint((5, "read_pinerc: time_pinerc_written = %ld\n",
5544 (long) prc->pinerc_written));
5548 if(free_file)
5549 fs_give((void **) &free_file);
5554 * Args varname The variable name we're looking for
5555 * begin Begin looking here
5557 * Returns 1 if variable varname appears in the rest of the file
5558 * 0 if not
5561 var_is_in_rest_of_file(char *varname, char *begin)
5563 char *p;
5565 if(!(varname && *varname && begin && *begin))
5566 return 0;
5568 p = begin;
5570 while((p = srchstr(p, varname)) != NULL){
5571 /* beginning of a line? */
5572 if(p > begin && (*(p-1) != '\n' && *(p-1) != '\r')){
5573 p++;
5574 continue;
5577 /* followed by [ SPACE ] < = > ? */
5578 p += strlen(varname);
5579 while(*p == ' ' || *p == '\t')
5580 p++;
5582 if(*p == '=')
5583 return 1;
5586 return 0;
5591 * Args begin Variable to skip starts here.
5592 * nextline This is where the next line starts. We need to know this
5593 * because the input has been mangled a little. A \0 has
5594 * replaced the \n at the end of the first line, but we can
5595 * use nextline to help us out of that quandry.
5597 * Return a pointer to the start of the first line after this variable
5598 * and all of its continuation lines.
5600 char *
5601 skip_over_this_var(char *begin, char *nextline)
5603 char *p;
5605 p = begin;
5607 while(1){
5608 if(*p == '\0' || *p == '\n'){ /* EOL */
5609 if(p < nextline || *p == '\n'){ /* there may be another line */
5610 p++;
5611 if(*p != ' ' && *p != '\t') /* no continuation line */
5612 return(p);
5614 else /* end of file */
5615 return(p);
5617 else
5618 p++;
5623 static char quotes[3] = {'"', '"', '\0'};
5624 /*----------------------------------------------------------------------
5625 Write out the .pinerc state information
5627 Args: ps -- The pine structure to take state to be written from
5628 which -- Which pinerc to write
5629 flags -- If bit WRP_NOUSER is set, then assume that there is
5630 not a user present to answer questions.
5632 This writes to a temporary file first, and then renames that to
5633 be the new .pinerc file to protect against disk error. This has the
5634 problem of possibly messing up file protections, ownership and links.
5635 ----*/
5637 write_pinerc(struct pine *ps, EditWhich which, int flags)
5639 char *p, *dir, *tmp = NULL, *pinrc;
5640 char *pval, **lval;
5641 char *linep = NULL, *lineq = NULL;
5642 int bc = 1;
5643 int buflen;
5644 PINERC_LINE *pline;
5645 struct variable *var;
5646 time_t mtime;
5647 char *filename;
5648 REMDATA_S *rd = NULL;
5649 PINERC_S *prc = NULL;
5650 STORE_S *so = NULL;
5651 #ifndef _WINDOWS
5652 struct stat sbuf;
5653 char *slink = NULL;
5654 #endif
5656 #define MAXPLINESIZE 10000
5658 dprint((2,"---- write_pinerc(%s) ----\n",
5659 (which == Main) ? "Main" : "Post"));
5661 switch(which){
5662 case Main:
5663 prc = ps ? ps->prc : NULL;
5664 break;
5665 case Post:
5666 prc = ps ? ps->post_prc : NULL;
5667 break;
5668 default:
5669 break;
5672 if(!prc)
5673 return(-1);
5675 if(prc->quit_to_edit){
5676 if(!(flags & WRP_NOUSER))
5677 quit_to_edit_msg(prc);
5679 return(-1);
5682 if(prc->type != Loc && !prc->readonly){
5684 bc = 0; /* don't do backcompat conversion */
5685 rd = prc->rd;
5686 if(!rd)
5687 return(-1);
5689 rd_check_remvalid(rd, -10L);
5691 if(rd->flags & REM_OUTOFDATE){
5692 if((flags & WRP_NOUSER) || unexpected_pinerc_change()){
5693 prc->outstanding_pinerc_changes = 1;
5694 if(!(flags & WRP_NOUSER))
5695 q_status_message1(SM_ORDER | SM_DING, 3, 3,
5696 "Pinerc \"%.200s\" NOT saved",
5697 prc->name ? prc->name : "");
5698 dprint((2, "write_pinerc: remote pinerc changed\n"));
5699 return(-1);
5701 else
5702 rd->flags &= ~REM_OUTOFDATE;
5705 rd_open_remote(rd);
5707 if(rd->access == ReadWrite){
5708 int ro;
5710 if((ro=rd_remote_is_readonly(rd)) || rd->flags & REM_OUTOFDATE){
5711 if(ro == 1){
5712 if(!(flags & WRP_NOUSER))
5713 q_status_message(SM_ORDER | SM_DING, 5, 15,
5714 _("Can't access remote config, changes NOT saved!"));
5715 dprint((1,
5716 "write_pinerc: Can't write to remote pinerc %s, aborting write\n",
5717 rd->rn ? rd->rn : "?"));
5719 else if(ro == 2){
5720 if(!(rd->flags & NO_META_UPDATE)){
5721 unsigned long save_chk_nmsgs;
5723 switch(rd->type){
5724 case RemImap:
5725 save_chk_nmsgs = rd->t.i.chk_nmsgs;
5726 rd->t.i.chk_nmsgs = 0;
5727 rd_write_metadata(rd, 0);
5728 rd->t.i.chk_nmsgs = save_chk_nmsgs;
5729 break;
5731 default:
5732 q_status_message(SM_ORDER | SM_DING, 3, 5,
5733 "Write_pinerc: Type not supported");
5734 break;
5738 if(!(flags & WRP_NOUSER))
5739 q_status_message1(SM_ORDER | SM_DING, 5, 15,
5740 _("No write permission for remote config %.200s, changes NOT saved!"),
5741 rd->rn);
5743 else{
5744 if(!(flags & WRP_NOUSER))
5745 q_status_message(SM_ORDER | SM_DING, 5, 15,
5746 _("Remote config changed, aborting our change to avoid damage..."));
5747 dprint((1,
5748 "write_pinerc: remote config %s changed since we started pine, aborting write\n",
5749 prc->name ? prc->name : "?"));
5752 rd->flags &= ~DO_REMTRIM;
5753 return(-1);
5756 filename = rd->lf;
5758 else{
5759 prc->readonly = 1;
5760 if(prc == ps->prc)
5761 ps->readonly_pinerc = 1;
5764 else
5765 filename = prc->name ? prc->name : "";
5767 pinrc = prc->name ? prc->name : "";
5769 if(prc->type == Loc){
5770 mtime = name_file_mtime(filename);
5771 if(prc->pinerc_written
5772 && prc->pinerc_written != mtime
5773 && ((flags & WRP_NOUSER) || unexpected_pinerc_change())){
5774 prc->outstanding_pinerc_changes = 1;
5776 if(!(flags & WRP_NOUSER))
5777 q_status_message1(SM_ORDER | SM_DING, 3, 3,
5778 "Pinerc \"%.200s\" NOT saved", pinrc);
5780 dprint((2,"write_pinerc: mtime mismatch: \"%s\": %ld != %ld\n",
5781 filename ? filename : "?",
5782 (long) prc->pinerc_written, (long) mtime));
5783 return(-1);
5787 /* don't write if pinerc is read-only */
5788 if(prc->readonly ||
5789 (filename &&
5790 can_access(filename, ACCESS_EXISTS) == 0 &&
5791 can_access(filename, EDIT_ACCESS) != 0)){
5792 prc->readonly = 1;
5793 if(prc == ps->prc)
5794 ps->readonly_pinerc = 1;
5796 if(!(flags & WRP_NOUSER))
5797 q_status_message1(SM_ORDER | SM_DING, 0, 5,
5798 _("Can't modify configuration file \"%.200s\": ReadOnly"),
5799 pinrc);
5800 dprint((2, "write_pinerc: fail because can't access pinerc\n"));
5802 if(rd)
5803 rd->flags &= ~DO_REMTRIM;
5805 return(-1);
5808 if(rd && rd->flags & NO_FILE){
5809 so = rd->sonofile;
5810 so_truncate(rd->sonofile, 0L); /* reset storage object */
5812 else{
5813 dir = ".";
5814 if((p = last_cmpnt(filename)) != NULL){
5815 *--p = '\0';
5816 dir = filename;
5819 #if defined(DOS) || defined(OS2)
5820 if(!(isalpha((unsigned char)dir[0]) && dir[1] == ':' && dir[2] == '\0')
5821 && (can_access(dir, EDIT_ACCESS) < 0 &&
5822 our_mkdir(dir, 0700) < 0))
5824 if(!(flags & WRP_NOUSER))
5825 q_status_message2(SM_ORDER | SM_DING, 3, 5,
5826 /* TRANSLATORS: first argument is a filename, second
5827 arg is the text of the error message */
5828 _("Error creating \"%.200s\" : %.200s"), dir,
5829 error_description(errno));
5830 if(rd)
5831 rd->flags &= ~DO_REMTRIM;
5833 return(-1);
5836 tmp = temp_nam(dir, "rc");
5838 if(*dir && tmp && !in_dir(dir, tmp)){
5839 our_unlink(tmp);
5840 fs_give((void **)&tmp);
5843 if(p)
5844 *p = '\\';
5846 if(tmp == NULL)
5847 goto io_err;
5849 #else /* !DOS */
5850 tmp = temp_nam((*dir) ? dir : "/", "pinerc");
5853 * If temp_nam can't write in dir it puts the temp file in a
5854 * temp directory, which won't help us when we go to rename.
5856 if(*dir && tmp && !in_dir(dir, tmp)){
5857 our_unlink(tmp);
5858 fs_give((void **)&tmp);
5861 if(p)
5862 *p = '/';
5864 if(tmp == NULL)
5865 goto io_err;
5867 #endif /* !DOS */
5869 if((so = so_get(FileStar, tmp, WRITE_ACCESS)) == NULL)
5870 goto io_err;
5873 if(!(flags & WRP_PRESERV_WRITTEN))
5874 for(var = ps->vars; var->name != NULL; var++)
5875 var->been_written = 0;
5877 if(prc->type == Loc && ps->first_time_user &&
5878 !so_puts(so, native_nl(cf_text_comment)))
5879 goto io_err;
5881 linep = fs_get((MAXPLINESIZE+1)*sizeof(char));
5882 lineq = fs_get((MAXPLINESIZE+1)*sizeof(char));
5883 buflen = MAXPLINESIZE;
5885 /* Write out what was in the .pinerc */
5886 for(pline = prc->pinerc_lines;
5887 pline && (pline->is_var || pline->line); pline++){
5888 if(pline->is_var){
5889 var = pline->var;
5891 if(var->is_list)
5892 lval = LVAL(var, which);
5893 else
5894 pval = PVAL(var, which);
5896 /* variable is not set */
5897 if((var->is_list && (!lval || !lval[0])) ||
5898 (!var->is_list && !pval)){
5899 /* leave null variables out of remote pinerc */
5900 if(prc->type == Loc &&
5901 (!so_puts(so, var->name) || !so_puts(so, "=") ||
5902 !so_puts(so, NEWLINE)))
5903 goto io_err;
5905 /* var is set to empty string */
5906 else if((var->is_list && lval[0][0] == '\0') ||
5907 (!var->is_list && pval[0] == '\0')){
5908 if(!so_puts(so, var->name) || !so_puts(so, "=") ||
5909 !so_puts(so, quotes) || !so_puts(so, NEWLINE))
5910 goto io_err;
5912 else{
5913 if(var->is_list){
5914 int i = 0;
5916 for(i = 0; lval[i]; i++){
5917 if(strlen(var->name)
5918 + (lval[i][0] ? strlen(lval[i]) : 5) > buflen){
5919 buflen = strlen(var->name)
5920 + (lval[i][0] ? strlen(lval[i]) : 5);
5921 fs_resize((void **)&linep, (buflen+1)*sizeof(char));
5922 fs_resize((void **)&lineq, (buflen+1)*sizeof(char));
5924 snprintf(linep, buflen+1, "%s%s%s%s%s",
5925 (i) ? "\t" : var->name,
5926 (i) ? "" : "=",
5927 lval[i][0] ? lval[i] : quotes,
5928 lval[i+1] ? "," : "", NEWLINE);
5929 linep[buflen] = '\0';
5930 if(!so_puts(so, bc ? backcompat_convert_from_utf8(&lineq, buflen+1, linep) : linep))
5931 goto io_err;
5934 else{
5935 if(strlen(var->name)
5936 + (pval[0] ? strlen(pval) : 5) > buflen){
5937 buflen = strlen(var->name)
5938 + (pval[0] ? strlen(pval) : 5);
5939 fs_resize((void **)&linep, (buflen+1)*sizeof(char));
5940 fs_resize((void **)&lineq, (buflen+1)*sizeof(char));
5942 snprintf(linep, buflen+1, "%s=%s%s%s%s",
5943 var->name,
5944 (pline->is_quoted && pval[0] != '\"')
5945 ? "\"" : "",
5946 pval,
5947 (pline->is_quoted && pval[0] != '\"')
5948 ? "\"" : "", NEWLINE);
5949 linep[buflen] = '\0';
5950 if(!so_puts(so, bc ? backcompat_convert_from_utf8(&lineq, buflen+1, linep) : linep))
5951 goto io_err;
5955 var->been_written = 1;
5957 }else{
5959 * The description text should be changed into a message
5960 * about the variable being obsolete when a variable is
5961 * moved to obsolete status. We add that message before
5962 * the variable unless it is already there. However, we
5963 * leave the variable itself in case the user runs an old
5964 * version of pine again. Note that we have read in the
5965 * value of the variable in read_pinerc and translated it
5966 * into a new variable if appropriate.
5968 if(pline->obsolete_var && prc->type == Loc){
5969 if(pline <= prc->pinerc_lines || (pline-1)->line == NULL ||
5970 strlen((pline-1)->line) < 3 ||
5971 strucmp((pline-1)->line+2, pline->var->descrip) != 0)
5972 if(!so_puts(so, "# ") ||
5973 !so_puts(so, native_nl(pline->var->descrip)) ||
5974 !so_puts(so, NEWLINE))
5975 goto io_err;
5978 /* remove comments from remote pinercs */
5979 if((prc->type == Loc ||
5980 (pline->line[0] != '#' && pline->line[0] != '\0')) &&
5981 (!so_puts(so, pline->line) || !so_puts(so, NEWLINE)))
5982 goto io_err;
5986 /* Now write out all the variables not in the .pinerc */
5987 for(var = ps->vars; var->name != NULL; var++){
5988 if(!var->is_user || var->been_written || !var->is_used ||
5989 var->is_obsolete || (var->is_onlymain && which != Main))
5990 continue;
5992 if(var->is_list)
5993 lval = LVAL(var, which);
5994 else
5995 pval = PVAL(var, which);
5998 * set description to NULL to eliminate preceding
5999 * blank and comment line.
6001 if(prc->type == Loc && var->descrip && *var->descrip &&
6002 (!so_puts(so, NEWLINE) || !so_puts(so, "# ") ||
6003 !so_puts(so, native_nl(var->descrip)) || !so_puts(so, NEWLINE)))
6004 goto io_err;
6006 /* variable is not set */
6007 /** Don't know what the global_val thing is for. SH, Mar 00 **/
6008 if((var->is_list && (!lval || (!lval[0] && !var->global_val.l))) ||
6009 (!var->is_list && !pval)){
6010 /* leave null variables out of remote pinerc */
6011 if(prc->type == Loc &&
6012 (!so_puts(so, var->name) || !so_puts(so, "=") ||
6013 !so_puts(so, NEWLINE)))
6014 goto io_err;
6016 /* var is set to empty string */
6017 else if((var->is_list && (!lval[0] || !lval[0][0]))
6018 || (!var->is_list && pval[0] == '\0')){
6019 if(!so_puts(so, var->name) || !so_puts(so, "=") ||
6020 !so_puts(so, quotes) || !so_puts(so, NEWLINE))
6021 goto io_err;
6023 else if(var->is_list){
6024 int i = 0;
6026 for(i = 0; lval[i] ; i++){
6027 if(strlen(var->name)
6028 + (lval[i][0] ? strlen(lval[i]) : 5) > buflen){
6029 buflen = strlen(var->name)
6030 + (lval[i][0] ? strlen(lval[i]) : 5);
6031 fs_resize((void **)&linep, (buflen+1)*sizeof(char));
6032 fs_resize((void **)&lineq, (buflen+1)*sizeof(char));
6034 snprintf(linep, buflen+1, "%s%s%s%s%s",
6035 (i) ? "\t" : var->name,
6036 (i) ? "" : "=",
6037 lval[i],
6038 lval[i+1] ? "," : "", NEWLINE);
6039 linep[buflen] = '\0';
6040 if(!so_puts(so, bc ? backcompat_convert_from_utf8(&lineq, buflen+1, linep) : linep))
6041 goto io_err;
6044 else{
6045 char *pconverted;
6047 if(strlen(pval) > buflen){
6048 buflen = strlen(pval) + 1;
6049 fs_resize((void **)&linep, (buflen+1)*sizeof(char));
6050 fs_resize((void **)&lineq, (buflen+1)*sizeof(char));
6052 pconverted = bc ? backcompat_convert_from_utf8(&lineq, buflen+1, pval) : pval;
6054 if(!so_puts(so, var->name) || !so_puts(so, "=") ||
6055 !so_puts(so, pconverted) || !so_puts(so, NEWLINE))
6056 goto io_err;
6060 if(!(rd && rd->flags & NO_FILE)){
6061 char *realfilename;
6062 int realfilename_malloced;
6064 if(so_give(&so)) goto io_err;
6066 #ifndef _WINDOWS
6067 realfilename = fs_get(MAXPATH+1);
6068 if(realfilename != NULL){
6069 if(realpath(filename, realfilename) == NULL)
6070 fs_give((void **) &realfilename);
6071 realfilename_malloced = realfilename != NULL ? 1 : 0;
6073 else
6074 realfilename_malloced = 0;
6075 if (realfilename_malloced == 0){
6076 if(our_stat(filename, &sbuf) < 0 && errno == ENOENT){
6077 realfilename = filename;
6078 realfilename_malloced = 0;
6080 else
6081 goto io_err;
6083 #else
6084 realfilename = filename;
6085 realfilename_malloced = 0;
6086 #endif /* _WINDOWS */
6087 if(realfilename != NULL){
6088 int r;
6089 file_attrib_copy(tmp, realfilename);
6090 r = rename_file(tmp, realfilename);
6091 if(realfilename_malloced != 0)
6092 fs_give((void **) &realfilename);
6093 if(r < 0) goto io_err;
6097 if(prc->type != Loc){
6098 int e, we_cancel;
6099 char datebuf[200];
6101 datebuf[0] = '\0';
6102 we_cancel = 0;
6104 if(!(flags & WRP_NOUSER))
6105 we_cancel = busy_cue(_("Copying to remote config"), NULL, 1);
6107 if((e = rd_update_remote(rd, datebuf)) != 0){
6108 dprint((1,
6109 "write_pinerc: error copying from %s to %s\n",
6110 rd->lf ? rd->lf : "<memory>", rd->rn ? rd->rn : "?"));
6111 if(!(flags & WRP_NOUSER)){
6112 q_status_message2(SM_ORDER | SM_DING, 3, 5,
6113 _("Error copying to %.200s: %.200s"),
6114 rd->rn, error_description(errno));
6116 q_status_message(SM_ORDER | SM_DING, 5, 5,
6117 _("Copy of config to remote folder failed, changes NOT saved remotely"));
6120 else{
6121 rd_update_metadata(rd, datebuf);
6122 rd->read_status = 'W';
6123 rd_trim_remdata(&rd);
6124 rd_close_remote(rd);
6127 if(we_cancel)
6128 cancel_busy_cue(-1);
6131 prc->outstanding_pinerc_changes = 0;
6133 if(prc->type == Loc){
6134 prc->pinerc_written = name_file_mtime(filename);
6135 dprint((2, "wrote pinerc: %s: time_pinerc_written = %ld\n",
6136 pinrc ? pinrc : "?", (long) prc->pinerc_written));
6138 else{
6139 dprint((2, "wrote pinerc: %s\n", pinrc ? pinrc : "?"));
6142 if(tmp){
6143 our_unlink(tmp);
6144 fs_give((void **)&tmp);
6147 if(linep) fs_give((void **)&linep);
6148 if(lineq) fs_give((void **)&lineq);
6150 return(0);
6152 io_err:
6153 if(!(flags & WRP_NOUSER))
6154 q_status_message2(SM_ORDER | SM_DING, 3, 5,
6155 _("Error saving configuration in \"%.200s\": %.200s"),
6156 pinrc, error_description(errno));
6158 dprint((1, "Error writing %s : %s\n", pinrc ? pinrc : "?",
6159 error_description(errno)));
6160 if(rd)
6161 rd->flags &= ~DO_REMTRIM;
6162 if(tmp){
6163 our_unlink(tmp);
6164 fs_give((void **)&tmp);
6167 if(linep) fs_give((void **)&linep);
6168 if(lineq) fs_give((void **)&lineq);
6170 return(-1);
6175 * The srcstr is UTF-8. In order to help the user with
6176 * running this pine and an old pre-alpine pine on the same config
6177 * file we attempt to convert the values of the config variables
6178 * to the user's character set before writing.
6179 * parameters: char **buf. Memory of size_t buflen allocated by caller.
6181 char *
6182 backcompat_convert_from_utf8(char **buf, size_t buflen, char *srcstr)
6184 char *converted = NULL;
6185 char *p;
6186 int its_ascii = 1;
6189 for(p = srcstr; *p && its_ascii; p++)
6190 if(*p & 0x80)
6191 its_ascii = 0;
6193 /* if it is ascii, go with that */
6194 if(its_ascii){
6195 strncpy(*buf, srcstr, buflen);
6196 converted = *buf;
6197 (*buf)[buflen-1] = '\0';
6199 else{
6200 char *trythischarset = NULL;
6203 * If it is possible to translate the UTF-8
6204 * string into the user's character set then
6205 * do that. For backwards compatibility with
6206 * old pines.
6208 if(ps_global->keyboard_charmap && ps_global->keyboard_charmap[0])
6209 trythischarset = ps_global->keyboard_charmap;
6210 else if(ps_global->display_charmap && ps_global->display_charmap[0])
6211 trythischarset = ps_global->display_charmap;
6213 if(trythischarset){
6214 SIZEDTEXT src, dst;
6216 src.data = (unsigned char *) srcstr;
6217 src.size = strlen(srcstr);
6218 memset(&dst, 0, sizeof(dst));
6219 if(utf8_cstext(&src, trythischarset, &dst, 0)){
6220 if(dst.data){
6221 strncpy(*buf, (char *) dst.data, buflen);
6222 (*buf)[buflen-1] = '\0';
6223 fs_give((void **) &dst.data);
6228 if(!converted){
6229 strncpy(*buf, srcstr, buflen);
6230 (*buf)[buflen-1] = '\0';
6231 converted = *buf;
6235 return(converted);
6240 * Given a unix-style source string which may contain LFs,
6241 * convert those to CRLFs if appropriate.
6243 * Returns a pointer to the converted string. This will be a string
6244 * stored in tmp_20k_buf.
6246 * This is just used for the variable descriptions in the pinerc file. It
6247 * could certainly be fancier. It simply converts all \n to NEWLINE.
6249 char *
6250 native_nl(char *src)
6252 char *q, *p;
6254 tmp_20k_buf[0] = '\0';
6256 if(src){
6257 for(q = (char *)tmp_20k_buf; *src; src++){
6258 if(*src == '\n'){
6259 for(p = NEWLINE; *p; p++)
6260 *q++ = *p;
6262 else
6263 *q++ = *src;
6266 *q = '\0';
6269 return((char *)tmp_20k_buf);
6273 void
6274 quit_to_edit_msg(PINERC_S *prc)
6276 /* TRANSLATORS: The %s is either "Postload " or nothing. A Postload config file
6277 is a type of config file. */
6278 q_status_message1(SM_ORDER, 3, 4, _("Must quit Alpine to change %sconfig file."),
6279 (prc == ps_global->post_prc) ? "Postload " : "");
6283 /*------------------------------------------------------------
6284 Return TRUE if the given string was a feature name present in the
6285 pinerc as it was when pine was started...
6286 ----*/
6288 var_in_pinerc(char *s)
6290 PINERC_LINE *pline;
6292 for(pline = ps_global->prc ? ps_global->prc->pinerc_lines : NULL;
6293 pline && (pline->var || pline->line); pline++)
6294 if(pline->var && pline->var->name && !strucmp(s, pline->var->name))
6295 return(1);
6297 for(pline = ps_global->post_prc ? ps_global->post_prc->pinerc_lines : NULL;
6298 pline && (pline->var || pline->line); pline++)
6299 if(pline->var && pline->var->name && !strucmp(s, pline->var->name))
6300 return(1);
6302 return(0);
6306 /*------------------------------------------------------------
6307 Free resources associated with pinerc_lines data
6308 ----*/
6309 void
6310 free_pinerc_lines(PINERC_LINE **pinerc_lines)
6312 PINERC_LINE *pline;
6314 if(pinerc_lines && *pinerc_lines){
6315 for(pline = *pinerc_lines; pline->var || pline->line; pline++)
6316 if(pline->line)
6317 fs_give((void **)&pline->line);
6319 fs_give((void **)pinerc_lines);
6324 /*------------------------------------------------------------
6325 Dump out a global pine.conf on the standard output with fresh
6326 comments. Preserves variables currently set in SYSTEM_PINERC, if any.
6327 ----*/
6328 void
6329 dump_global_conf(void)
6331 FILE *f;
6332 struct variable *var;
6333 PINERC_S *prc;
6335 prc = new_pinerc_s(SYSTEM_PINERC);
6336 read_pinerc(prc, variables, ParseGlobal);
6337 if(prc)
6338 free_pinerc_s(&prc);
6340 f = stdout;
6341 if(f == NULL)
6342 goto io_err;
6344 fprintf(f, "# %s -- system wide pine configuration\n#\n",
6345 SYSTEM_PINERC);
6346 fprintf(f, "# Values here affect all pine users unless they've overridden the values\n");
6347 fprintf(f, "# in their .pinerc files. A copy of this file with current comments may\n");
6348 fprintf(f, "# be obtained by running \"pine -conf\". It will be printed to standard output.\n#\n");
6349 fprintf(f,"# For a variable to be unset its value must be null/blank. This is not the\n");
6350 fprintf(f,"# same as the value of \"empty string\", which can be used to effectively\n");
6351 fprintf(f,"# \"unset\" a variable that has a default or previously assigned value.\n");
6352 fprintf(f,"# To set a variable to the empty string its value should be \"\".\n");
6353 fprintf(f,"# Switch variables are set to either \"yes\" or \"no\", and default to \"no\".\n");
6354 fprintf(f,"# Except for feature-list items, which are additive, values set in the\n");
6355 fprintf(f,"# .pinerc file replace those in pine.conf, and those in pine.conf.fixed\n");
6356 fprintf(f,"# over-ride all others. Features can be over-ridden in .pinerc or\n");
6357 fprintf(f,"# pine.conf.fixed by pre-pending the feature name with \"no-\".\n#\n");
6358 fprintf(f,"# (These comments are automatically inserted.)\n");
6360 for(var = variables; var->name != NULL; var++){
6361 if(!var->is_global || !var->is_used || var->is_obsolete)
6362 continue;
6364 if(var->descrip && *var->descrip){
6365 if(fprintf(f, "\n# %s\n", var->descrip) == EOF)
6366 goto io_err;
6369 if(var->is_list){
6370 if(var->global_val.l == NULL){
6371 if(fprintf(f, "%s=\n", var->name) == EOF)
6372 goto io_err;
6373 }else{
6374 int i;
6376 for(i=0; var->global_val.l[i]; i++)
6377 if(fprintf(f, "%s%s%s%s\n", (i) ? "\t" : var->name,
6378 (i) ? "" : "=", var->global_val.l[i],
6379 var->global_val.l[i+1] ? ",":"") == EOF)
6380 goto io_err;
6382 }else{
6383 if(var->global_val.p == NULL){
6384 if(fprintf(f, "%s=\n", var->name) == EOF)
6385 goto io_err;
6386 }else if(strlen(var->global_val.p) == 0){
6387 if(fprintf(f, "%s=\"\"\n", var->name) == EOF)
6388 goto io_err;
6389 }else{
6390 if(fprintf(f,"%s=%s\n",var->name,var->global_val.p) == EOF)
6391 goto io_err;
6395 exit(0);
6398 io_err:
6399 fprintf(stderr, "Error writing config to stdout: %s\n",
6400 error_description(errno));
6401 exit(-1);
6405 /*------------------------------------------------------------
6406 Dump out a pinerc to filename with fresh
6407 comments. Preserves variables currently set in pinerc, if any.
6408 ----*/
6409 void
6410 dump_new_pinerc(char *filename)
6412 FILE *f;
6413 struct variable *var;
6414 char buf[MAXPATH], *p;
6415 PINERC_S *prc;
6418 p = ps_global->pinerc;
6420 #if defined(DOS) || defined(OS2)
6421 if(!ps_global->pinerc){
6422 char *p;
6424 if(p = getenv("PINERC")){
6425 ps_global->pinerc = cpystr(p);
6426 }else{
6427 char buf2[MAXPATH];
6428 build_path(buf2, ps_global->home_dir, DF_PINEDIR, sizeof(buf2));
6429 build_path(buf, buf2, SYSTEM_PINERC, sizeof(buf));
6432 p = buf;
6434 #else /* !DOS */
6435 if(!ps_global->pinerc){
6436 build_path(buf, ps_global->home_dir, ".pinerc", sizeof(buf));
6437 p = buf;
6439 #endif /* !DOS */
6441 prc = new_pinerc_s(p);
6442 read_pinerc(prc, variables, ParsePers);
6443 if(prc)
6444 free_pinerc_s(&prc);
6446 f = NULL;;
6447 if(filename[0] == '\0'){
6448 fprintf(stderr, "Missing argument to \"-pinerc\".\n");
6449 }else if(!strcmp(filename, "-")){
6450 f = stdout;
6451 }else{
6452 f = our_fopen(filename, "wb");
6455 if(f == NULL)
6456 goto io_err;
6458 if(fprintf(f, "%s", cf_text_comment) == EOF)
6459 goto io_err;
6461 for(var = variables; var->name != NULL; var++){
6462 dprint((7,"write_pinerc: %s = %s\n",
6463 var->name ? var->name : "?",
6464 var->main_user_val.p ? var->main_user_val.p : "<not set>"));
6465 if(!var->is_user || !var->is_used || var->is_obsolete)
6466 continue;
6469 * set description to NULL to eliminate preceding
6470 * blank and comment line.
6472 if(var->descrip && *var->descrip){
6473 if(fprintf(f, "\n# %s\n", var->descrip) == EOF)
6474 goto io_err;
6477 if(var->is_list){
6478 if(var->main_user_val.l == NULL){
6479 if(fprintf(f, "%s=\n", var->name) == EOF)
6480 goto io_err;
6481 }else{
6482 int i;
6484 for(i=0; var->main_user_val.l[i]; i++)
6485 if(fprintf(f, "%s%s%s%s\n", (i) ? "\t" : var->name,
6486 (i) ? "" : "=", var->main_user_val.l[i],
6487 var->main_user_val.l[i+1] ? ",":"") == EOF)
6488 goto io_err;
6490 }else{
6491 if(var->main_user_val.p == NULL){
6492 if(fprintf(f, "%s=\n", var->name) == EOF)
6493 goto io_err;
6494 }else if(strlen(var->main_user_val.p) == 0){
6495 if(fprintf(f, "%s=\"\"\n", var->name) == EOF)
6496 goto io_err;
6497 }else{
6498 if(fprintf(f,"%s=%s\n",var->name,var->main_user_val.p) == EOF)
6499 goto io_err;
6503 exit(0);
6506 io_err:
6507 snprintf(buf, sizeof(buf), "Error writing config to %s: %s\n",
6508 filename, error_description(errno));
6509 exceptional_exit(buf, -1);
6513 /*----------------------------------------------------------------------
6514 Set a user variable and save the .pinerc
6516 Args: var -- The index of the variable to set from conftype.h (V_....)
6517 value -- The string to set the value to
6519 Result: -1 is returned on failure and 0 is returned on success
6521 The vars data structure is updated and the pinerc saved.
6522 ----*/
6524 set_variable(int var, char *value, int expand, int commit, EditWhich which)
6526 struct variable *v;
6527 char **apval;
6528 PINERC_S *prc;
6530 v = &ps_global->vars[var];
6532 if(!v->is_user)
6533 panic1("Trying to set non-user variable %s", v->name);
6535 /* Override value of which, at most one of these should be set */
6536 if(v->is_onlymain)
6537 which = Main;
6538 else if(v->is_outermost)
6539 which = ps_global->ew_for_except_vars;
6541 apval = APVAL(v, which);
6543 if(!apval)
6544 return(-1);
6546 if(*apval)
6547 fs_give((void **)apval);
6549 *apval = value ? cpystr(value) : NULL;
6550 set_current_val(v, expand, FALSE);
6552 switch(which){
6553 case Main:
6554 prc = ps_global->prc;
6555 break;
6556 case Post:
6557 prc = ps_global->post_prc;
6558 break;
6559 default:
6560 break;
6563 if(prc)
6564 prc->outstanding_pinerc_changes = 1;
6566 return(commit ? write_pinerc(ps_global, which, WRP_NONE) : 0);
6570 /*----------------------------------------------------------------------
6571 Set a user variable list and save the .pinerc
6573 Args: var -- The index of the variable to set from conftype.h (V_....)
6574 lvalue -- The list to set the value to
6576 Result: -1 is returned on failure and 0 is returned on success
6578 The vars data structure is updated and if write_it, the pinerc is saved.
6579 ----*/
6581 set_variable_list(int var, char **lvalue, int write_it, EditWhich which)
6583 char ***alval;
6584 int i;
6585 struct variable *v = &ps_global->vars[var];
6586 PINERC_S *prc;
6588 if(!v->is_user || !v->is_list)
6589 panic1("BOTCH: Trying to set non-user or non-list variable %s", v->name);
6591 /* Override value of which, at most one of these should be set */
6592 if(v->is_onlymain)
6593 which = Main;
6594 else if(v->is_outermost)
6595 which = ps_global->ew_for_except_vars;
6597 alval = ALVAL(v, which);
6598 if(!alval)
6599 return(-1);
6601 if(*alval)
6602 free_list_array(alval);
6604 if(lvalue){
6605 for(i = 0; lvalue[i] ; i++) /* count elements */
6608 *alval = (char **) fs_get((i+1) * sizeof(char *));
6610 for(i = 0; lvalue[i] ; i++)
6611 (*alval)[i] = cpystr(lvalue[i]);
6613 (*alval)[i] = NULL;
6616 set_current_val(v, TRUE, FALSE);
6618 switch(which){
6619 case Main:
6620 prc = ps_global->prc;
6621 break;
6622 case Post:
6623 prc = ps_global->post_prc;
6624 break;
6625 default:
6626 break;
6629 if(prc)
6630 prc->outstanding_pinerc_changes = 1;
6632 return(write_it ? write_pinerc(ps_global, which, WRP_NONE) : 0);
6636 void
6637 set_current_color_vals(struct pine *ps)
6639 struct variable *vars = ps->vars;
6640 int later_color_is_set = 0;
6642 set_current_val(&vars[V_NORM_FORE_COLOR], TRUE, TRUE);
6643 set_current_val(&vars[V_NORM_BACK_COLOR], TRUE, TRUE);
6644 pico_nfcolor(VAR_NORM_FORE_COLOR);
6645 pico_nbcolor(VAR_NORM_BACK_COLOR);
6647 set_current_val(&vars[V_REV_FORE_COLOR], TRUE, TRUE);
6648 set_current_val(&vars[V_REV_BACK_COLOR], TRUE, TRUE);
6649 pico_rfcolor(VAR_REV_FORE_COLOR);
6650 pico_rbcolor(VAR_REV_BACK_COLOR);
6652 set_color_val(&vars[V_TITLE_FORE_COLOR], 1);
6653 set_color_val(&vars[V_TITLECLOSED_FORE_COLOR], 0);
6654 set_color_val(&vars[V_FOLDER_FORE_COLOR], 0);
6655 set_color_val(&vars[V_DIRECTORY_FORE_COLOR], 0);
6656 set_color_val(&vars[V_FOLDER_LIST_FORE_COLOR], 0);
6657 set_color_val(&vars[V_STATUS_FORE_COLOR], 1);
6658 set_color_val(&vars[V_KEYLABEL_FORE_COLOR], 1);
6659 set_color_val(&vars[V_KEYNAME_FORE_COLOR], 1);
6660 set_color_val(&vars[V_SLCTBL_FORE_COLOR], 1);
6661 set_color_val(&vars[V_METAMSG_FORE_COLOR], 1);
6662 set_color_val(&vars[V_PROMPT_FORE_COLOR], 1);
6663 set_color_val(&vars[V_HEADER_GENERAL_FORE_COLOR], 1);
6664 set_color_val(&vars[V_IND_PLUS_FORE_COLOR], 0);
6665 set_color_val(&vars[V_IND_IMP_FORE_COLOR], 0);
6666 set_color_val(&vars[V_IND_DEL_FORE_COLOR], 0);
6667 set_color_val(&vars[V_IND_HIPRI_FORE_COLOR], 0);
6668 set_color_val(&vars[V_IND_LOPRI_FORE_COLOR], 0);
6669 set_color_val(&vars[V_IND_ANS_FORE_COLOR], 0);
6670 set_color_val(&vars[V_IND_NEW_FORE_COLOR], 0);
6671 set_color_val(&vars[V_IND_REC_FORE_COLOR], 0);
6672 set_color_val(&vars[V_IND_FWD_FORE_COLOR], 0);
6673 set_color_val(&vars[V_IND_UNS_FORE_COLOR], 0);
6674 set_color_val(&vars[V_IND_ARR_FORE_COLOR], 0);
6675 set_color_val(&vars[V_IND_SUBJ_FORE_COLOR], 0);
6676 set_color_val(&vars[V_IND_FROM_FORE_COLOR], 0);
6677 set_color_val(&vars[V_IND_OP_FORE_COLOR], 0);
6678 set_color_val(&vars[V_INCUNSEEN_FORE_COLOR], 0);
6679 set_color_val(&vars[V_SIGNATURE_FORE_COLOR], 0);
6681 set_current_val(&ps->vars[V_INDEX_TOKEN_COLORS], TRUE, TRUE);
6682 set_current_val(&ps->vars[V_VIEW_HDR_COLORS], TRUE, TRUE);
6683 set_current_val(&ps->vars[V_KW_COLORS], TRUE, TRUE);
6684 set_custom_spec_colors(ps);
6687 * Set up the quoting colors. If a later color is set but not an earlier
6688 * color we set the earlier color to Normal to make it easier when
6689 * we go to use the colors. However, if the only quote colors set are
6690 * Normal that is the same as no settings, so delete them.
6692 set_color_val(&vars[V_QUOTE1_FORE_COLOR], 0);
6693 set_color_val(&vars[V_QUOTE2_FORE_COLOR], 0);
6694 set_color_val(&vars[V_QUOTE3_FORE_COLOR], 0);
6696 if((!(VAR_QUOTE3_FORE_COLOR && VAR_QUOTE3_BACK_COLOR) ||
6697 (!strucmp(VAR_QUOTE3_FORE_COLOR, VAR_NORM_FORE_COLOR) &&
6698 !strucmp(VAR_QUOTE3_BACK_COLOR, VAR_NORM_BACK_COLOR))) &&
6699 (!(VAR_QUOTE2_FORE_COLOR && VAR_QUOTE2_BACK_COLOR) ||
6700 (!strucmp(VAR_QUOTE2_FORE_COLOR, VAR_NORM_FORE_COLOR) &&
6701 !strucmp(VAR_QUOTE2_BACK_COLOR, VAR_NORM_BACK_COLOR))) &&
6702 (!(VAR_QUOTE1_FORE_COLOR && VAR_QUOTE1_BACK_COLOR) ||
6703 (!strucmp(VAR_QUOTE1_FORE_COLOR, VAR_NORM_FORE_COLOR) &&
6704 !strucmp(VAR_QUOTE1_BACK_COLOR, VAR_NORM_BACK_COLOR)))){
6706 * They are all either Normal or not set. Delete them all.
6708 if(VAR_QUOTE3_FORE_COLOR)
6709 fs_give((void **)&VAR_QUOTE3_FORE_COLOR);
6710 if(VAR_QUOTE3_BACK_COLOR)
6711 fs_give((void **)&VAR_QUOTE3_BACK_COLOR);
6712 if(VAR_QUOTE2_FORE_COLOR)
6713 fs_give((void **)&VAR_QUOTE2_FORE_COLOR);
6714 if(VAR_QUOTE2_BACK_COLOR)
6715 fs_give((void **)&VAR_QUOTE2_BACK_COLOR);
6716 if(VAR_QUOTE1_FORE_COLOR)
6717 fs_give((void **)&VAR_QUOTE1_FORE_COLOR);
6718 if(VAR_QUOTE1_BACK_COLOR)
6719 fs_give((void **)&VAR_QUOTE1_BACK_COLOR);
6721 else{ /* something is non-Normal */
6722 if(VAR_QUOTE3_FORE_COLOR && VAR_QUOTE3_BACK_COLOR)
6723 later_color_is_set++;
6725 /* if 3 is set but not 2, set 2 to Normal */
6726 if(VAR_QUOTE2_FORE_COLOR && VAR_QUOTE2_BACK_COLOR)
6727 later_color_is_set++;
6728 else if(later_color_is_set)
6729 set_color_val(&vars[V_QUOTE2_FORE_COLOR], 1);
6731 /* if 3 or 2 is set but not 1, set 1 to Normal */
6732 if(VAR_QUOTE1_FORE_COLOR && VAR_QUOTE1_BACK_COLOR)
6733 later_color_is_set++;
6734 else if(later_color_is_set)
6735 set_color_val(&vars[V_QUOTE1_FORE_COLOR], 1);
6738 #ifdef _WINDOWS
6739 if(ps->pre441){
6740 int conv_main = 0, conv_post = 0;
6742 ps->pre441 = 0;
6743 if(ps->prc && !unix_color_style_in_pinerc(ps->prc)){
6744 conv_main = convert_pc_gray_names(ps, ps->prc, Main);
6745 if(conv_main)
6746 ps->prc->outstanding_pinerc_changes = 1;
6750 if(ps->post_prc && !unix_color_style_in_pinerc(ps->post_prc)){
6751 conv_post = convert_pc_gray_names(ps, ps->post_prc, Post);
6752 if(conv_post)
6753 ps->post_prc->outstanding_pinerc_changes = 1;
6756 if(conv_main || conv_post){
6757 if(conv_main)
6758 write_pinerc(ps, Main, WRP_NONE);
6760 if(conv_post)
6761 write_pinerc(ps, Post, WRP_NONE);
6763 set_current_color_vals(ps);
6766 #endif /* _WINDOWS */
6768 pico_set_normal_color();
6773 * Set current_val for the foreground and background color vars, which
6774 * are assumed to be in order. If a set_current_val on them doesn't
6775 * produce current_vals, then use the colors from defvar to set those
6776 * current_vals.
6778 void
6779 set_color_val(struct variable *v, int use_default)
6781 set_current_val(v, TRUE, TRUE);
6782 set_current_val(v+1, TRUE, TRUE);
6784 if(!(v->current_val.p && v->current_val.p[0] &&
6785 (v+1)->current_val.p && (v+1)->current_val.p[0])){
6786 struct variable *defvar;
6788 if(v->current_val.p)
6789 fs_give((void **)&v->current_val.p);
6790 if((v+1)->current_val.p)
6791 fs_give((void **)&(v+1)->current_val.p);
6793 if(!use_default)
6794 return;
6796 if(var_defaults_to_rev(v))
6797 defvar = &ps_global->vars[V_REV_FORE_COLOR];
6798 else
6799 defvar = &ps_global->vars[V_NORM_FORE_COLOR];
6801 /* use default vars values instead */
6802 if(defvar && defvar->current_val.p && defvar->current_val.p[0] &&
6803 (defvar+1)->current_val.p && (defvar+1)->current_val.p[0]){
6804 v->current_val.p = cpystr(defvar->current_val.p);
6805 (v+1)->current_val.p = cpystr((defvar+1)->current_val.p);
6812 var_defaults_to_rev(struct variable *v)
6814 return(v == &ps_global->vars[V_REV_FORE_COLOR] ||
6815 v == &ps_global->vars[V_TITLE_FORE_COLOR] ||
6816 v == &ps_global->vars[V_STATUS_FORE_COLOR] ||
6817 v == &ps_global->vars[V_KEYNAME_FORE_COLOR] ||
6818 v == &ps_global->vars[V_PROMPT_FORE_COLOR]);
6824 * Each item in the list looks like:
6826 * /HDR=<header>/FG=<foreground color>/BG=<background color>
6828 * We separate the three pieces into an array of structures to make
6829 * it easier to deal with later.
6831 void
6832 set_custom_spec_colors(struct pine *ps)
6834 if(ps->index_token_colors)
6835 free_spec_colors(&ps->index_token_colors);
6837 ps->index_token_colors = spec_colors_from_varlist(ps->VAR_INDEX_TOKEN_COLORS, 1);
6839 if(ps->hdr_colors)
6840 free_spec_colors(&ps->hdr_colors);
6842 ps->hdr_colors = spec_colors_from_varlist(ps->VAR_VIEW_HDR_COLORS, 1);
6844 /* fit keyword colors into the same structures for code re-use */
6845 if(ps->kw_colors)
6846 free_spec_colors(&ps->kw_colors);
6848 ps->kw_colors = spec_colors_from_varlist(ps->VAR_KW_COLORS, 1);
6853 * Input is one item from config variable.
6855 * Return value must be freed by caller. The return is a single SPEC_COLOR_S,
6856 * not a list.
6858 SPEC_COLOR_S *
6859 spec_color_from_var(char *t, int already_expanded)
6861 char *p, *spec, *fg, *bg;
6862 PATTERN_S *val;
6863 SPEC_COLOR_S *new_hcolor = NULL;
6865 if(t && t[0] && !strcmp(t, INHERIT)){
6866 new_hcolor = (SPEC_COLOR_S *)fs_get(sizeof(*new_hcolor));
6867 memset((void *)new_hcolor, 0, sizeof(*new_hcolor));
6868 new_hcolor->inherit = 1;
6870 else if(t && t[0]){
6871 char tbuf[10000];
6873 if(!already_expanded){
6874 tbuf[0] = '\0';
6875 if(expand_variables(tbuf, sizeof(tbuf), t, 0))
6876 t = tbuf;
6879 spec = fg = bg = NULL;
6880 val = NULL;
6881 if((p = srchstr(t, "/HDR=")) != NULL)
6882 spec = remove_backslash_escapes(p+5);
6883 if((p = srchstr(t, "/FG=")) != NULL)
6884 fg = remove_backslash_escapes(p+4);
6885 if((p = srchstr(t, "/BG=")) != NULL)
6886 bg = remove_backslash_escapes(p+4);
6887 val = parse_pattern("VAL", t, 0);
6889 if(spec && *spec){
6890 /* remove colons */
6891 if((p = strindex(spec, ':')) != NULL)
6892 *p = '\0';
6894 new_hcolor = (SPEC_COLOR_S *)fs_get(sizeof(*new_hcolor));
6895 memset((void *)new_hcolor, 0, sizeof(*new_hcolor));
6896 new_hcolor->spec = spec;
6897 new_hcolor->fg = fg;
6898 new_hcolor->bg = bg;
6899 new_hcolor->val = val;
6901 else{
6902 if(spec)
6903 fs_give((void **)&spec);
6904 if(fg)
6905 fs_give((void **)&fg);
6906 if(bg)
6907 fs_give((void **)&bg);
6908 if(val)
6909 free_pattern(&val);
6913 return(new_hcolor);
6918 * Input is a list from config file.
6920 * Return value may be a list of SPEC_COLOR_S and must be freed by caller.
6922 SPEC_COLOR_S *
6923 spec_colors_from_varlist(char **varlist, int already_expanded)
6925 char **s, *t;
6926 SPEC_COLOR_S *new_hc = NULL;
6927 SPEC_COLOR_S *new_hcolor, **nexthc;
6929 nexthc = &new_hc;
6930 if(varlist){
6931 for(s = varlist; (t = *s) != NULL; s++){
6932 if(t[0]){
6933 new_hcolor = spec_color_from_var(t, already_expanded);
6934 if(new_hcolor){
6935 *nexthc = new_hcolor;
6936 nexthc = &new_hcolor->next;
6942 return(new_hc);
6947 * Returns allocated charstar suitable for config var for a single
6948 * SPEC_COLOR_S.
6950 char *
6951 var_from_spec_color(SPEC_COLOR_S *hc)
6953 char *ret_val = NULL;
6954 char *p, *spec = NULL, *fg = NULL, *bg = NULL, *val = NULL;
6955 size_t len;
6957 if(hc && hc->inherit)
6958 ret_val = cpystr(INHERIT);
6959 else if(hc){
6960 if(hc->spec)
6961 spec = add_viewerhdr_escapes(hc->spec);
6962 if(hc->fg)
6963 fg = add_viewerhdr_escapes(hc->fg);
6964 if(hc->bg)
6965 bg = add_viewerhdr_escapes(hc->bg);
6966 if(hc->val){
6967 p = pattern_to_string(hc->val);
6968 if(p){
6969 val = add_viewerhdr_escapes(p);
6970 fs_give((void **)&p);
6974 len = strlen("/HDR=/FG=/BG=") + strlen(spec ? spec : "") +
6975 strlen(fg ? fg : "") + strlen(bg ? bg : "") +
6976 strlen(val ? "/VAL=" : "") + strlen(val ? val : "");
6977 ret_val = (char *) fs_get(len + 1);
6978 snprintf(ret_val, len+1, "/HDR=%s/FG=%s/BG=%s%s%s",
6979 spec ? spec : "", fg ? fg : "", bg ? bg : "",
6980 val ? "/VAL=" : "", val ? val : "");
6982 if(spec)
6983 fs_give((void **)&spec);
6984 if(fg)
6985 fs_give((void **)&fg);
6986 if(bg)
6987 fs_give((void **)&bg);
6988 if(val)
6989 fs_give((void **)&val);
6992 return(ret_val);
6997 * Returns allocated charstar suitable for config var for a single
6998 * SPEC_COLOR_S.
7000 char **
7001 varlist_from_spec_colors(SPEC_COLOR_S *hcolors)
7003 SPEC_COLOR_S *hc;
7004 char **ret_val = NULL;
7005 int i;
7007 /* count how many */
7008 for(hc = hcolors, i = 0; hc; hc = hc->next, i++)
7011 ret_val = (char **)fs_get((i+1) * sizeof(*ret_val));
7012 memset((void *)ret_val, 0, (i+1) * sizeof(*ret_val));
7013 for(hc = hcolors, i = 0; hc; hc = hc->next, i++)
7014 ret_val[i] = var_from_spec_color(hc);
7016 return(ret_val);
7020 void
7021 update_posting_charset(struct pine *ps, int revert)
7023 #ifndef _WINDOWS
7024 if(F_ON(F_USE_SYSTEM_TRANS, ps)){
7025 if(!revert)
7026 q_status_message(SM_ORDER, 5, 5, _("This change has no effect because feature Use-System-Translation is on"));
7028 else{
7029 #endif /* ! _WINDOWS */
7030 if(ps->posting_charmap)
7031 fs_give((void **) &ps->posting_charmap);
7033 if(ps->VAR_POST_CHAR_SET){
7034 ps->posting_charmap = cpystr(ps->VAR_POST_CHAR_SET);
7035 if(!posting_charset_is_supported(ps->posting_charmap)){
7036 snprintf(tmp_20k_buf, SIZEOF_20KBUF,
7037 _("Posting-Character set \"%s\" is unsupported, using UTF-8"),
7038 ps->posting_charmap);
7039 q_status_message(SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
7040 fs_give((void **) &ps->posting_charmap);
7041 ps->posting_charmap = cpystr("UTF-8");
7044 else
7045 ps->posting_charmap = cpystr("UTF-8");
7046 #ifndef _WINDOWS
7048 #endif /* ! _WINDOWS */
7052 #define FIXED_COMMENT _("(fixed)")
7053 #define DEFAULT_COMMENT _("(default)")
7054 #define OVERRIDE_COMMENT _("(overridden)")
7057 feature_gets_an_x(struct pine *ps, struct variable *var, FEATURE_S *feature,
7058 char **comment, EditWhich ew)
7060 char **lval, **lvalexc, **lvalnorm;
7061 char *def = DEFAULT_COMMENT;
7062 int j, done = 0;
7063 int feature_fixed_on = 0, feature_fixed_off = 0;
7065 if(comment)
7066 *comment = NULL;
7068 lval = LVAL(var, ew);
7069 lvalexc = LVAL(var, ps->ew_for_except_vars);
7070 lvalnorm = LVAL(var, Main);
7072 /* feature value is administratively fixed */
7073 if((j = feature_in_list(var->fixed_val.l, feature->name)) != 0){
7074 if(j == 1)
7075 feature_fixed_on++;
7076 else if(j == -1)
7077 feature_fixed_off++;
7079 done++;
7080 if(comment)
7081 *comment = FIXED_COMMENT;
7085 * We have an exceptions config setting which overrides anything
7086 * we do here, in the normal config.
7088 if(!done &&
7089 ps->ew_for_except_vars != Main && ew == Main &&
7090 feature_in_list(lvalexc, feature->name)){
7091 done++;
7092 if(comment)
7093 *comment = OVERRIDE_COMMENT;
7097 * Feature is set On in default but not set here.
7099 if(!done &&
7100 !feature_in_list(lval, feature->name) &&
7101 ((feature_in_list(var->global_val.l, feature->name) == 1) ||
7102 ((ps->ew_for_except_vars != Main &&
7103 ew == ps->ew_for_except_vars &&
7104 feature_in_list(lvalnorm, feature->name) == 1)))){
7105 done = 17;
7106 if(comment)
7107 *comment = def;
7110 if(!done &&
7111 feature->defval &&
7112 !feature_in_list(lval, feature->name) &&
7113 !feature_in_list(var->global_val.l, feature->name) &&
7114 (ps->ew_for_except_vars == Main ||
7115 ew != ps->ew_for_except_vars ||
7116 !feature_in_list(lvalnorm, feature->name))){
7117 done = 17;
7118 if(comment)
7119 *comment = def;
7122 return(feature_fixed_on ||
7123 (!feature_fixed_off &&
7124 (done == 17 ||
7125 test_feature(lval, feature->name,
7126 test_old_growth_bits(ps, feature->id)))));
7129 #if !defined(_WINDOWS) || defined(WINDOWS_UNIXSSL_CERTS)
7130 void
7131 set_system_certs_path(struct pine *ps)
7133 char **l;
7135 for (l = ps->vars[V_SSLCAPATH].current_val.l; l && *l; l++){
7136 if(is_absolute_path(*l)
7137 && can_access(*l, ACCESS_EXISTS) == 0
7138 && can_access(*l, READ_ACCESS) == 0){
7139 mail_parameters(NULL, SET_SSLCAPATH, (void *) *l);
7140 break;
7146 void
7147 set_system_certs_container(struct pine *ps)
7149 char **l;
7151 for (l = ps->vars[V_SSLCAFILE].current_val.l; l && *l; l++){
7152 if(is_absolute_path(*l)
7153 && can_access(*l, ACCESS_EXISTS) == 0
7154 && can_access(*l, READ_ACCESS) == 0){
7155 mail_parameters(NULL, SET_SSLCAFILE, (void *) *l);
7156 break;
7161 void
7162 set_user_certs_path(struct pine *ps)
7164 char **l;
7166 for (l = ps->vars[V_USERSSLCAPATH].current_val.l; l && *l; l++){
7167 if(is_absolute_path(*l)
7168 && can_access(*l, ACCESS_EXISTS) == 0
7169 && can_access(*l, READ_ACCESS) == 0){
7170 mail_parameters(NULL, SET_SSLAPPCAPATH, (void *) *l);
7171 break;
7177 void
7178 set_user_certs_container(struct pine *ps)
7180 char **l;
7182 for (l = ps->vars[V_USERSSLCAFILE].current_val.l; l && *l; l++){
7183 if(is_absolute_path(*l)
7184 && can_access(*l, ACCESS_EXISTS) == 0
7185 && can_access(*l, READ_ACCESS) == 0){
7186 mail_parameters(NULL, SET_SSLAPPCAFILE, (void *) *l);
7187 break;
7191 #endif
7194 longest_feature_comment(struct pine *ps, EditWhich ew)
7196 int lc = 0;
7198 lc = MAX(lc, utf8_width(FIXED_COMMENT));
7199 lc = MAX(lc, utf8_width(DEFAULT_COMMENT));
7200 if(ps->ew_for_except_vars != Main && ew == Main)
7201 lc = MAX(lc, utf8_width(OVERRIDE_COMMENT));
7203 return(lc);
7207 void
7208 toggle_feature(struct pine *ps, struct variable *var, FEATURE_S *f,
7209 int just_flip_value, EditWhich ew)
7211 char **vp, *p, **lval, ***alval;
7212 int og, on_before, was_set;
7213 char *err;
7214 long l;
7216 og = test_old_growth_bits(ps, f->id);
7219 * if this feature is in the fixed set, or old-growth is in the fixed
7220 * set and this feature is in the old-growth set, don't alter it...
7222 for(vp = var->fixed_val.l; vp && *vp; vp++){
7223 p = (struncmp(*vp, "no-", 3)) ? *vp : *vp + 3;
7224 if(!strucmp(p, f->name) || (og && !strucmp(p, "old-growth"))){
7225 q_status_message(SM_ORDER, 3, 3,
7226 /* TRANSLATORS: In the configuration screen, telling the user we
7227 can't change this option because the system administrator
7228 prohibits it. */
7229 _("Can't change value fixed by sys-admin."));
7230 return;
7234 on_before = F_ON(f->id, ps);
7236 lval = LVAL(var, ew);
7237 alval = ALVAL(var, ew);
7238 if(just_flip_value)
7239 was_set = test_feature(lval, f->name, og);
7240 else
7241 was_set = feature_gets_an_x(ps, var, f, NULL, ew);
7243 if(alval)
7244 set_feature(alval, f->name, !was_set);
7246 set_feature_list_current_val(var);
7247 process_feature_list(ps, var->current_val.l, 0, 0, 0);
7250 * Handle any features that need special attention here...
7252 if(on_before != F_ON(f->id, ps))
7253 switch(f->id){
7254 case F_QUOTE_ALL_FROMS :
7255 mail_parameters(NULL,SET_FROMWIDGET,F_ON(f->id,ps) ? VOIDT : NIL);
7256 break;
7258 case F_FAKE_NEW_IN_NEWS :
7259 if(IS_NEWS(ps->mail_stream))
7260 q_status_message(SM_ORDER | SM_DING, 3, 4,
7261 "news-approximates-new-status won't affect current newsgroup until next open");
7263 break;
7265 case F_COLOR_LINE_IMPORTANT :
7266 case F_DATES_TO_LOCAL :
7267 clear_index_cache(ps->mail_stream, 0);
7268 break;
7270 case F_DISABLE_INDEX_LOCALE_DATES :
7271 reset_index_format();
7272 clear_index_cache(ps->mail_stream, 0);
7273 break;
7275 case F_MARK_FOR_CC :
7276 clear_index_cache(ps->mail_stream, 0);
7277 if(THREADING() && sp_viewing_a_thread(ps->mail_stream))
7278 unview_thread(ps, ps->mail_stream, ps->msgmap);
7280 break;
7282 case F_HIDE_NNTP_PATH :
7283 mail_parameters(NULL, SET_NNTPHIDEPATH,
7284 F_ON(f->id, ps) ? VOIDT : NIL);
7285 break;
7287 case F_MAILDROPS_PRESERVE_STATE :
7288 mail_parameters(NULL, SET_SNARFPRESERVE,
7289 F_ON(f->id, ps) ? VOIDT : NIL);
7290 break;
7292 case F_DISABLE_SHARED_NAMESPACES :
7293 mail_parameters(NULL, SET_DISABLEAUTOSHAREDNS,
7294 F_ON(f->id, ps) ? VOIDT : NIL);
7295 break;
7297 case F_QUELL_LOCK_FAILURE_MSGS :
7298 mail_parameters(NULL, SET_LOCKEACCESERROR,
7299 F_ON(f->id, ps) ? VOIDT : NIL);
7300 break;
7302 case F_MULNEWSRC_HOSTNAMES_AS_TYPED :
7303 l = F_ON(f->id, ps) ? 0L : 1L;
7304 mail_parameters(NULL, SET_NEWSRCCANONHOST, (void *) l);
7305 break;
7307 case F_QUELL_INTERNAL_MSG :
7308 mail_parameters(NULL, SET_USERHASNOLIFE,
7309 F_ON(f->id, ps) ? VOIDT : NIL);
7310 break;
7312 case F_DISABLE_SETLOCALE_COLLATE :
7313 set_collation(F_OFF(F_DISABLE_SETLOCALE_COLLATE, ps), 1);
7314 break;
7316 #ifndef _WINDOWS
7317 case F_USE_SYSTEM_TRANS :
7318 err = NULL;
7319 reset_character_set_stuff(&err);
7320 if(err){
7321 q_status_message(SM_ORDER | SM_DING, 3, 4, err);
7322 fs_give((void **) &err);
7325 break;
7326 #endif /* ! _WINDOWS */
7328 case F_ENABLE_INCOMING_CHECKING :
7329 if(!on_before && F_OFF(F_ENABLE_INCOMING, ps))
7330 q_status_message(SM_ORDER, 0, 3, _("This option has no effect without Enable-Incoming-Folders"));
7332 clear_incoming_valid_bits();
7333 break;
7335 case F_INCOMING_CHECKING_TOTAL :
7336 case F_INCOMING_CHECKING_RECENT :
7337 if(!on_before && F_OFF(F_ENABLE_INCOMING_CHECKING, ps))
7338 q_status_message(SM_ORDER, 0, 3, _("This option has no effect without Enable-Incoming-Folders-Checking"));
7340 clear_incoming_valid_bits();
7341 break;
7343 case F_THREAD_SORTS_BY_ARRIVAL :
7344 clear_index_cache(ps->mail_stream, 0);
7345 refresh_sort(ps->mail_stream, sp_msgmap(ps->mail_stream), SRT_NON);
7346 break;
7348 #ifdef SMIME
7349 case F_DONT_DO_SMIME :
7350 smime_deinit();
7351 break;
7353 #ifdef APPLEKEYCHAIN
7354 case F_PUBLICCERTS_IN_KEYCHAIN :
7355 smime_deinit();
7356 break;
7357 #endif
7358 #endif
7360 default :
7361 break;
7367 * Returns 1 -- Feature is in the list and positive
7368 * 0 -- Feature is not in the list at all
7369 * -1 -- Feature is in the list and negative (no-)
7372 feature_in_list(char **l, char *f)
7374 char *p;
7375 int rv = 0, forced_off;
7377 for(; l && *l; l++){
7378 p = (forced_off = !struncmp(*l, "no-", 3)) ? *l + 3 : *l;
7379 if(!strucmp(p, f))
7380 rv = forced_off ? -1 : 1;
7383 return(rv);
7388 * test_feature - runs thru a feature list, and returns:
7389 * 1 if feature explicitly set and matches 'v'
7390 * 0 if feature not explicitly set *or* doesn't match 'v'
7393 test_feature(char **l, char *f, int g)
7395 char *p;
7396 int rv = 0, forced_off;
7398 for(; l && *l; l++){
7399 p = (forced_off = !struncmp(*l, "no-", 3)) ? *l + 3 : *l;
7400 if(!strucmp(p, f))
7401 rv = !forced_off;
7402 else if(g && !strucmp(p, "old-growth"))
7403 rv = !forced_off;
7406 return(rv);
7410 void
7411 set_feature(char ***l, char *f, int v)
7413 char **list = l ? *l : NULL, newval[256];
7414 int count = 0;
7416 snprintf(newval, sizeof(newval), "%s%s", v ? "" : "no-", f);
7417 for(; list && *list; list++, count++)
7418 if((**list == '\0') /* anything can replace an empty value */
7419 || !strucmp(((!struncmp(*list, "no-", 3)) ? *list + 3 : *list), f)){
7420 fs_give((void **)list); /* replace with new value */
7421 *list = cpystr(newval);
7422 return;
7426 * if we got here, we didn't find it in the list, so grow the list
7427 * and add it..
7429 if(!*l)
7430 *l = (char **)fs_get((count + 2) * sizeof(char *));
7431 else
7432 fs_resize((void **)l, (count + 2) * sizeof(char *));
7434 (*l)[count] = cpystr(newval);
7435 (*l)[count + 1] = NULL;
7440 reset_character_set_stuff(char **err)
7442 int use_system = 0;
7443 char buf[1000];
7445 if(err)
7446 *err = NULL;
7448 if(ps_global->display_charmap)
7449 fs_give((void **) &ps_global->display_charmap);
7451 if(ps_global->keyboard_charmap)
7452 fs_give((void **) &ps_global->keyboard_charmap);
7454 if(ps_global->posting_charmap)
7455 fs_give((void **) &ps_global->posting_charmap);
7457 #ifdef _WINDOWS
7458 ps_global->display_charmap = cpystr("UTF-8");
7459 #else /* UNIX */
7460 if(ps_global->VAR_CHAR_SET)
7461 ps_global->display_charmap = cpystr(ps_global->VAR_CHAR_SET);
7462 else{
7463 #if HAVE_LANGINFO_H && defined(CODESET)
7464 ps_global->display_charmap = cpystr(nl_langinfo_codeset_wrapper());
7465 #else
7466 ps_global->display_charmap = cpystr("UTF-8");
7467 #endif
7469 #endif /* UNIX */
7471 if(!ps_global->display_charmap)
7472 ps_global->display_charmap = cpystr("US-ASCII");
7474 #ifdef _WINDOWS
7475 ps_global->keyboard_charmap = cpystr("UTF-8");
7476 #else /* UNIX */
7477 if(ps_global->VAR_KEY_CHAR_SET)
7478 ps_global->keyboard_charmap = cpystr(ps_global->VAR_KEY_CHAR_SET);
7479 else
7480 ps_global->keyboard_charmap = cpystr(ps_global->display_charmap);
7482 if(!ps_global->keyboard_charmap)
7483 ps_global->keyboard_charmap = cpystr("US-ASCII");
7485 if(F_ON(F_USE_SYSTEM_TRANS, ps_global)){
7486 #if PREREQ_FOR_SYS_TRANSLATION
7487 use_system++;
7488 /* This modifies its arguments */
7489 if(setup_for_input_output(use_system, &ps_global->display_charmap,
7490 &ps_global->keyboard_charmap,
7491 &ps_global->input_cs, (err && *err) ? NULL : err) == -1)
7492 return -1;
7493 #endif
7495 #endif /* UNIX */
7497 if(!use_system){
7498 if(setup_for_input_output(use_system, &ps_global->display_charmap,
7499 &ps_global->keyboard_charmap,
7500 &ps_global->input_cs, (err && *err) ? NULL : err) == -1)
7501 return -1;
7504 if(!use_system && ps_global->VAR_POST_CHAR_SET){
7505 ps_global->posting_charmap = cpystr(ps_global->VAR_POST_CHAR_SET);
7506 if(!posting_charset_is_supported(ps_global->posting_charmap)){
7507 if(err && !*err){
7508 snprintf(buf, sizeof(buf),
7509 _("Posting-Character-Set \"%s\" is unsupported, using UTF-8"),
7510 ps_global->posting_charmap);
7511 *err = cpystr(buf);
7514 fs_give((void **) &ps_global->posting_charmap);
7515 ps_global->posting_charmap = cpystr("UTF-8");
7518 else{
7519 if(use_system && ps_global->VAR_POST_CHAR_SET
7520 && strucmp(ps_global->VAR_POST_CHAR_SET, "UTF-8"))
7521 if(err && !*err)
7522 *err = cpystr(_("Posting-Character-Set is ignored with Use-System-Translation turned on"));
7524 ps_global->posting_charmap = cpystr("UTF-8");
7527 set_locale_charmap(ps_global->keyboard_charmap);
7529 return(0);
7534 * Given a single printer string from the config file, returns pointers
7535 * to alloc'd strings containing the printer nickname, the command,
7536 * the init string, the trailer string, everything but the nickname string,
7537 * and everything but the command string. All_but_cmd includes the trailing
7538 * space at the end (the one before the command) but all_but_nick does not
7539 * include the leading space (the one before the [).
7540 * If you pass in a pointer it is guaranteed to come back pointing to an
7541 * allocated string, even if it is just an empty string. It is ok to pass
7542 * NULL for any of the six return strings.
7544 void
7545 parse_printer(char *input, char **nick, char **cmd, char **init, char **trailer,
7546 char **all_but_nick, char **all_but_cmd)
7548 char *p, *q, *start, *saved_options = NULL;
7549 int tmpsave, cnt;
7551 if(!input)
7552 input = "";
7554 if(nick || all_but_nick){
7555 if((p = srchstr(input, " [")) != NULL){
7556 if(all_but_nick)
7557 *all_but_nick = cpystr(p+1);
7559 if(nick){
7560 while(p-1 > input && isspace((unsigned char)*(p-1)))
7561 p--;
7563 tmpsave = *p;
7564 *p = '\0';
7565 *nick = cpystr(input);
7566 *p = tmpsave;
7569 else{
7570 if(nick)
7571 *nick = cpystr("");
7573 if(all_but_nick)
7574 *all_but_nick = cpystr(input);
7578 if((p = srchstr(input, "] ")) != NULL){
7580 ++p;
7581 }while(isspace((unsigned char)*p));
7583 tmpsave = *p;
7584 *p = '\0';
7585 saved_options = cpystr(input);
7586 *p = tmpsave;
7588 else
7589 p = input;
7591 if(cmd)
7592 *cmd = cpystr(p);
7594 if(init){
7595 if(saved_options && (p = srchstr(saved_options, "INIT="))){
7596 start = p + strlen("INIT=");
7597 for(cnt=0, p = start; *p && *(p+1) && isxpair(p); p += 2)
7598 cnt++;
7600 q = *init = (char *)fs_get((cnt + 1) * sizeof(char));
7601 for(p = start; *p && *(p+1) && isxpair(p); p += 2)
7602 *q++ = read_hex(p);
7604 *q = '\0';
7606 else
7607 *init = cpystr("");
7610 if(trailer){
7611 if(saved_options && (p = srchstr(saved_options, "TRAILER="))){
7612 start = p + strlen("TRAILER=");
7613 for(cnt=0, p = start; *p && *(p+1) && isxpair(p); p += 2)
7614 cnt++;
7616 q = *trailer = (char *)fs_get((cnt + 1) * sizeof(char));
7617 for(p = start; *p && *(p+1) && isxpair(p); p += 2)
7618 *q++ = read_hex(p);
7620 *q = '\0';
7622 else
7623 *trailer = cpystr("");
7626 if(all_but_cmd){
7627 if(saved_options)
7628 *all_but_cmd = saved_options;
7629 else
7630 *all_but_cmd = cpystr("");
7632 else if(saved_options)
7633 fs_give((void **)&saved_options);
7638 copy_pinerc(char *local, char *remote, char **err_msg)
7640 return(copy_localfile_to_remotefldr(RemImap, local, remote,
7641 REMOTE_PINERC_SUBTYPE,
7642 err_msg));
7647 copy_abook(char *local, char *remote, char **err_msg)
7649 return(copy_localfile_to_remotefldr(RemImap, local, remote,
7650 REMOTE_ABOOK_SUBTYPE,
7651 err_msg));
7656 * Copy local file to remote folder.
7658 * Args remotetype -- type of remote folder
7659 * local -- name of local file
7660 * remote -- name of remote folder
7661 * subtype --
7663 * Returns 0 on success.
7666 copy_localfile_to_remotefldr(RemType remotetype, char *local, char *remote,
7667 char *subtype, char **err_msg)
7669 int retfail = -1;
7670 unsigned flags;
7671 REMDATA_S *rd;
7673 dprint((9, "copy_localfile_to_remotefldr(%s,%s)\n",
7674 local ? local : "<null>",
7675 remote ? remote : "<null>"));
7677 *err_msg = (char *)fs_get(MAXPATH * sizeof(char));
7679 if(!local || !*local){
7680 snprintf(*err_msg, MAXPATH, _("No local file specified"));
7681 return(retfail);
7684 if(!remote || !*remote){
7685 snprintf(*err_msg, MAXPATH, _("No remote folder specified"));
7686 return(retfail);
7689 if(!IS_REMOTE(remote)){
7690 snprintf(*err_msg, MAXPATH, _("Remote folder name \"%s\" %s"), remote,
7691 (*remote != '{') ? _("must begin with \"{\"") : _("not valid"));
7692 return(retfail);
7695 if(IS_REMOTE(local)){
7696 snprintf(*err_msg, MAXPATH, _("First argument \"%s\" must be a local filename"),
7697 local);
7698 return(retfail);
7701 if(can_access(local, ACCESS_EXISTS) != 0){
7702 snprintf(*err_msg, MAXPATH, _("Local file \"%s\" does not exist"), local);
7703 return(retfail);
7706 if(can_access(local, READ_ACCESS) != 0){
7707 snprintf(*err_msg, MAXPATH, _("Can't read local file \"%s\": %s"),
7708 local, error_description(errno));
7709 return(retfail);
7713 * Check if remote folder exists and create it if it doesn't.
7715 flags = 0;
7716 rd = rd_create_remote(remotetype, remote, subtype,
7717 &flags, _("Error: "), _("Can't copy to remote folder."));
7719 if(!rd || rd->access == NoExists){
7720 snprintf(*err_msg, MAXPATH, _("Can't create \"%s\""), remote);
7721 if(rd)
7722 rd_free_remdata(&rd);
7724 return(retfail);
7727 if(rd->access == MaybeRorW)
7728 rd->access = ReadWrite;
7730 rd->flags |= (NO_META_UPDATE | DO_REMTRIM);
7731 rd->lf = cpystr(local);
7733 rd_open_remote(rd);
7734 if(!rd_stream_exists(rd)){
7735 snprintf(*err_msg, MAXPATH, _("Can't open remote folder \"%s\""), rd->rn);
7736 rd_free_remdata(&rd);
7737 return(retfail);
7740 if(rd_remote_is_readonly(rd)){
7741 snprintf(*err_msg, MAXPATH, _("Remote folder \"%s\" is readonly"), rd->rn);
7742 rd_free_remdata(&rd);
7743 return(retfail);
7746 switch(rd->type){
7747 case RemImap:
7749 * Empty folder, add a header msg.
7751 if(rd->t.i.stream->nmsgs == 0){
7752 if(rd_init_remote(rd, 1) != 0){
7753 snprintf(*err_msg, MAXPATH,
7754 _("Failed initializing remote folder \"%s\", check debug file"),
7755 rd->rn);
7756 rd_free_remdata(&rd);
7757 return(retfail);
7761 fs_give((void **)err_msg);
7762 *err_msg = NULL;
7763 if(rd_chk_for_hdr_msg(&(rd->t.i.stream), rd, err_msg)){
7764 rd_free_remdata(&rd);
7765 return(retfail);
7768 break;
7770 default:
7771 break;
7774 if(rd_update_remote(rd, NULL) != 0){
7775 snprintf(*err_msg, MAXPATH, _("Error copying to remote folder \"%s\""), rd->rn);
7776 rd_free_remdata(&rd);
7777 return(retfail);
7780 rd_update_metadata(rd, NULL);
7781 rd_close_remdata(&rd);
7783 fs_give((void **)err_msg);
7784 return(0);
7788 /*----------------------------------------------------------------------
7789 Panic pine - call on detected programmatic errors to exit pine, with arg
7791 Input: message -- printf styule string for panic message (see above)
7792 arg -- argument for printf string
7794 Result: The various tty modes are restored
7795 If debugging is active a core dump will be generated
7796 Exits Pine
7797 ----*/
7798 void
7799 panic1(char *message, char *arg)
7801 #define SIZEOFBUF 1001
7802 char buf1[SIZEOFBUF], buf2[SIZEOFBUF];
7804 snprintf(buf1, sizeof(buf1), "%.*s", (int) MAX(SIZEOFBUF - 1 - strlen(message), 0), arg);
7805 snprintf(buf2, sizeof(buf2), message, buf1);
7806 alpine_panic(buf2);
7813 HelpType
7814 config_help(int var, int feature)
7816 switch(var){
7817 case V_FEATURE_LIST :
7818 return(feature_list_help(feature));
7819 break;
7821 case V_PERSONAL_NAME :
7822 return(h_config_pers_name);
7823 case V_USER_ID :
7824 return(h_config_user_id);
7825 case V_USER_DOMAIN :
7826 return(h_config_user_dom);
7827 case V_SMTP_SERVER :
7828 return(h_config_smtp_server);
7829 case V_NNTP_SERVER :
7830 return(h_config_nntp_server);
7831 case V_INBOX_PATH :
7832 return(h_config_inbox_path);
7833 case V_PRUNED_FOLDERS :
7834 return(h_config_pruned_folders);
7835 case V_DEFAULT_FCC :
7836 return(h_config_default_fcc);
7837 case V_DEFAULT_SAVE_FOLDER :
7838 return(h_config_def_save_folder);
7839 case V_POSTPONED_FOLDER :
7840 return(h_config_postponed_folder);
7841 case V_READ_MESSAGE_FOLDER :
7842 return(h_config_read_message_folder);
7843 case V_FORM_FOLDER :
7844 return(h_config_form_folder);
7845 case V_ARCHIVED_FOLDERS :
7846 return(h_config_archived_folders);
7847 case V_SIGNATURE_FILE :
7848 return(h_config_signature_file);
7849 case V_LITERAL_SIG :
7850 return(h_config_literal_sig);
7851 case V_INIT_CMD_LIST :
7852 return(h_config_init_cmd_list);
7853 case V_COMP_HDRS :
7854 return(h_config_comp_hdrs);
7855 case V_CUSTOM_HDRS :
7856 return(h_config_custom_hdrs);
7857 case V_VIEW_HEADERS :
7858 return(h_config_viewer_headers);
7859 case V_VIEW_MARGIN_LEFT :
7860 return(h_config_viewer_margin_left);
7861 case V_VIEW_MARGIN_RIGHT :
7862 return(h_config_viewer_margin_right);
7863 case V_QUOTE_SUPPRESSION :
7864 return(h_config_quote_suppression);
7865 case V_SAVED_MSG_NAME_RULE :
7866 return(h_config_saved_msg_name_rule);
7867 case V_FCC_RULE :
7868 return(h_config_fcc_rule);
7869 case V_SORT_KEY :
7870 return(h_config_sort_key);
7871 case V_AB_SORT_RULE :
7872 return(h_config_ab_sort_rule);
7873 case V_FLD_SORT_RULE :
7874 return(h_config_fld_sort_rule);
7875 case V_POST_CHAR_SET :
7876 return(h_config_post_char_set);
7877 case V_UNK_CHAR_SET :
7878 return(h_config_unk_char_set);
7879 #ifndef _WINDOWS
7880 case V_KEY_CHAR_SET :
7881 return(h_config_key_char_set);
7882 case V_CHAR_SET :
7883 return(h_config_char_set);
7884 #endif /* ! _WINDOWS */
7885 case V_EDITOR :
7886 return(h_config_editor);
7887 case V_SPELLER :
7888 return(h_config_speller);
7889 #ifdef _WINDOWS
7890 case V_DICTIONARY :
7891 return(h_config_aspell_dictionary);
7892 #endif /* _WINDOWS */
7893 case V_DISPLAY_FILTERS :
7894 return(h_config_display_filters);
7895 case V_SEND_FILTER :
7896 return(h_config_sending_filter);
7897 case V_ALT_ADDRS :
7898 return(h_config_alt_addresses);
7899 case V_KEYWORDS :
7900 return(h_config_keywords);
7901 case V_KW_BRACES :
7902 return(h_config_kw_braces);
7903 case V_OPENING_SEP :
7904 return(h_config_opening_sep);
7905 case V_KW_COLORS :
7906 return(h_config_kw_color);
7907 case V_ABOOK_FORMATS :
7908 return(h_config_abook_formats);
7909 case V_INDEX_FORMAT :
7910 return(h_config_index_format);
7911 case V_INCCHECKTIMEO :
7912 return(h_config_incoming_timeo);
7913 case V_INCCHECKINTERVAL :
7914 return(h_config_incoming_interv);
7915 case V_INC2NDCHECKINTERVAL :
7916 return(h_config_incoming_second_interv);
7917 case V_INCCHECKLIST :
7918 return(h_config_incoming_list);
7919 case V_OVERLAP :
7920 return(h_config_viewer_overlap);
7921 case V_MAXREMSTREAM :
7922 return(h_config_maxremstream);
7923 case V_PERMLOCKED :
7924 return(h_config_permlocked);
7925 case V_MARGIN :
7926 return(h_config_scroll_margin);
7927 case V_DEADLETS :
7928 return(h_config_deadlets);
7929 case V_FILLCOL :
7930 return(h_config_composer_wrap_column);
7931 case V_TCPOPENTIMEO :
7932 return(h_config_tcp_open_timeo);
7933 case V_TCPREADWARNTIMEO :
7934 return(h_config_tcp_readwarn_timeo);
7935 case V_TCPWRITEWARNTIMEO :
7936 return(h_config_tcp_writewarn_timeo);
7937 case V_TCPQUERYTIMEO :
7938 return(h_config_tcp_query_timeo);
7939 case V_QUITQUERYTIMEO :
7940 return(h_config_quit_query_timeo);
7941 case V_RSHOPENTIMEO :
7942 return(h_config_rsh_open_timeo);
7943 case V_SSHOPENTIMEO :
7944 return(h_config_ssh_open_timeo);
7945 case V_USERINPUTTIMEO :
7946 return(h_config_user_input_timeo);
7947 case V_REMOTE_ABOOK_VALIDITY :
7948 return(h_config_remote_abook_validity);
7949 case V_REMOTE_ABOOK_HISTORY :
7950 return(h_config_remote_abook_history);
7951 case V_INCOMING_FOLDERS :
7952 return(h_config_incoming_folders);
7953 case V_FOLDER_SPEC :
7954 return(h_config_folder_spec);
7955 case V_NEWS_SPEC :
7956 return(h_config_news_spec);
7957 case V_ADDRESSBOOK :
7958 return(h_config_address_book);
7959 case V_GLOB_ADDRBOOK :
7960 return(h_config_glob_addrbook);
7961 case V_LAST_VERS_USED :
7962 return(h_config_last_vers);
7963 case V_SENDMAIL_PATH :
7964 return(h_config_sendmail_path);
7965 case V_OPER_DIR :
7966 return(h_config_oper_dir);
7967 case V_RSHPATH :
7968 return(h_config_rshpath);
7969 case V_RSHCMD :
7970 return(h_config_rshcmd);
7971 case V_SSHPATH :
7972 return(h_config_sshpath);
7973 case V_SSHCMD :
7974 return(h_config_sshcmd);
7975 case V_NEW_VER_QUELL :
7976 return(h_config_new_ver_quell);
7977 case V_DISABLE_DRIVERS :
7978 return(h_config_disable_drivers);
7979 case V_DISABLE_AUTHS :
7980 return(h_config_disable_auths);
7981 case V_ENCRYPTION_RANGE :
7982 return(h_config_encryption_range);
7983 case V_REMOTE_ABOOK_METADATA :
7984 return(h_config_abook_metafile);
7985 case V_REPLY_STRING :
7986 return(h_config_reply_indent_string);
7987 case V_WORDSEPS :
7988 return(h_config_wordseps);
7989 case V_QUOTE_REPLACE_STRING :
7990 return(h_config_quote_replace_string);
7991 case V_REPLY_INTRO :
7992 return(h_config_reply_intro);
7993 case V_EMPTY_HDR_MSG :
7994 return(h_config_empty_hdr_msg);
7995 case V_STATUS_MSG_DELAY :
7996 return(h_config_status_msg_delay);
7997 case V_ACTIVE_MSG_INTERVAL :
7998 return(h_config_active_msg_interval);
7999 case V_MAILCHECK :
8000 return(h_config_mailcheck);
8001 case V_MAILCHECKNONCURR :
8002 return(h_config_mailchecknoncurr);
8003 case V_MAILDROPCHECK :
8004 return(h_config_maildropcheck);
8005 case V_NNTPRANGE :
8006 return(h_config_nntprange);
8007 case V_NEWS_ACTIVE_PATH :
8008 return(h_config_news_active);
8009 case V_NEWS_SPOOL_DIR :
8010 return(h_config_news_spool);
8011 case V_IMAGE_VIEWER :
8012 return(h_config_image_viewer);
8013 case V_USE_ONLY_DOMAIN_NAME :
8014 return(h_config_domain_name);
8015 case V_LAST_TIME_PRUNE_QUESTION :
8016 return(h_config_prune_date);
8017 case V_UPLOAD_CMD:
8018 return(h_config_upload_cmd);
8019 case V_UPLOAD_CMD_PREFIX:
8020 return(h_config_upload_prefix);
8021 case V_DOWNLOAD_CMD:
8022 return(h_config_download_cmd);
8023 case V_DOWNLOAD_CMD_PREFIX:
8024 return(h_config_download_prefix);
8025 case V_GOTO_DEFAULT_RULE:
8026 return(h_config_goto_default);
8027 case V_INCOMING_STARTUP:
8028 return(h_config_inc_startup);
8029 case V_PRUNING_RULE:
8030 return(h_config_pruning_rule);
8031 case V_REOPEN_RULE:
8032 return(h_config_reopen_rule);
8033 case V_THREAD_DISP_STYLE:
8034 return(h_config_thread_disp_style);
8035 case V_THREAD_INDEX_STYLE:
8036 return(h_config_thread_index_style);
8037 case V_THREAD_MORE_CHAR:
8038 return(h_config_thread_indicator_char);
8039 case V_THREAD_EXP_CHAR:
8040 return(h_config_thread_exp_char);
8041 case V_THREAD_LASTREPLY_CHAR:
8042 return(h_config_thread_lastreply_char);
8043 case V_MAILCAP_PATH :
8044 return(h_config_mailcap_path);
8045 case V_MIMETYPE_PATH :
8046 return(h_config_mimetype_path);
8047 #if !defined(_WINDOWS) || defined(WINDOWS_UNIXSSL_CERTS)
8048 case V_SSLCAPATH :
8049 return(h_config_system_certs_path);
8050 case V_SSLCAFILE :
8051 return(h_config_system_certs_file);
8052 case V_USERSSLCAPATH :
8053 return(h_config_user_certs_path);
8054 case V_USERSSLCAFILE :
8055 return(h_config_user_certs_file);
8056 #endif
8057 #if !defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO)
8058 case V_FIFOPATH :
8059 return(h_config_fifopath);
8060 #endif
8061 case V_NMW_WIDTH :
8062 return(h_config_newmailwidth);
8063 case V_NEWSRC_PATH :
8064 return(h_config_newsrc_path);
8065 case V_BROWSER :
8066 return(h_config_browser);
8067 case V_HISTORY :
8068 return(h_config_history);
8069 #if defined(DOS) || defined(OS2)
8070 case V_FILE_DIR :
8071 return(h_config_file_dir);
8072 #endif
8073 case V_NORM_FORE_COLOR :
8074 case V_NORM_BACK_COLOR :
8075 return(h_config_normal_color);
8076 case V_REV_FORE_COLOR :
8077 case V_REV_BACK_COLOR :
8078 return(h_config_reverse_color);
8079 case V_TITLE_FORE_COLOR :
8080 case V_TITLE_BACK_COLOR :
8081 return(h_config_title_color);
8082 case V_TITLECLOSED_FORE_COLOR :
8083 case V_TITLECLOSED_BACK_COLOR :
8084 return(h_config_titleclosed_color);
8085 case V_FOLDER_FORE_COLOR:
8086 return(h_config_folder_color);
8087 case V_DIRECTORY_FORE_COLOR:
8088 return(h_config_directory_color);
8089 case V_FOLDER_LIST_FORE_COLOR:
8090 return(h_config_folder_list_color);
8091 case V_STATUS_FORE_COLOR :
8092 case V_STATUS_BACK_COLOR :
8093 return(h_config_status_color);
8094 case V_SLCTBL_FORE_COLOR :
8095 case V_SLCTBL_BACK_COLOR :
8096 return(h_config_slctbl_color);
8097 case V_QUOTE1_FORE_COLOR :
8098 case V_QUOTE2_FORE_COLOR :
8099 case V_QUOTE3_FORE_COLOR :
8100 case V_QUOTE1_BACK_COLOR :
8101 case V_QUOTE2_BACK_COLOR :
8102 case V_QUOTE3_BACK_COLOR :
8103 return(h_config_quote_color);
8104 case V_INCUNSEEN_FORE_COLOR :
8105 case V_INCUNSEEN_BACK_COLOR :
8106 return(h_config_incunseen_color);
8107 case V_SIGNATURE_FORE_COLOR :
8108 case V_SIGNATURE_BACK_COLOR :
8109 return(h_config_signature_color);
8110 case V_PROMPT_FORE_COLOR :
8111 case V_PROMPT_BACK_COLOR :
8112 return(h_config_prompt_color);
8113 case V_HEADER_GENERAL_FORE_COLOR :
8114 case V_HEADER_GENERAL_BACK_COLOR :
8115 return(h_config_header_general_color);
8116 case V_IND_PLUS_FORE_COLOR :
8117 case V_IND_IMP_FORE_COLOR :
8118 case V_IND_DEL_FORE_COLOR :
8119 case V_IND_ANS_FORE_COLOR :
8120 case V_IND_NEW_FORE_COLOR :
8121 case V_IND_UNS_FORE_COLOR :
8122 case V_IND_REC_FORE_COLOR :
8123 case V_IND_FWD_FORE_COLOR :
8124 case V_IND_PLUS_BACK_COLOR :
8125 case V_IND_IMP_BACK_COLOR :
8126 case V_IND_DEL_BACK_COLOR :
8127 case V_IND_ANS_BACK_COLOR :
8128 case V_IND_NEW_BACK_COLOR :
8129 case V_IND_UNS_BACK_COLOR :
8130 case V_IND_REC_BACK_COLOR :
8131 case V_IND_FWD_BACK_COLOR :
8132 return(h_config_index_color);
8133 case V_IND_OP_FORE_COLOR :
8134 case V_IND_OP_BACK_COLOR :
8135 return(h_config_index_opening_color);
8136 case V_IND_SUBJ_FORE_COLOR :
8137 case V_IND_SUBJ_BACK_COLOR :
8138 return(h_config_index_subject_color);
8139 case V_IND_FROM_FORE_COLOR :
8140 case V_IND_FROM_BACK_COLOR :
8141 return(h_config_index_from_color);
8142 case V_IND_HIPRI_FORE_COLOR :
8143 case V_IND_HIPRI_BACK_COLOR :
8144 case V_IND_LOPRI_FORE_COLOR :
8145 case V_IND_LOPRI_BACK_COLOR :
8146 return(h_config_index_pri_color);
8147 case V_IND_ARR_FORE_COLOR :
8148 case V_IND_ARR_BACK_COLOR :
8149 return(h_config_index_arrow_color);
8150 case V_KEYLABEL_FORE_COLOR :
8151 case V_KEYLABEL_BACK_COLOR :
8152 return(h_config_keylabel_color);
8153 case V_KEYNAME_FORE_COLOR :
8154 case V_KEYNAME_BACK_COLOR :
8155 return(h_config_keyname_color);
8156 case V_METAMSG_FORE_COLOR :
8157 case V_METAMSG_BACK_COLOR :
8158 return(h_config_metamsg_color);
8159 case V_VIEW_HDR_COLORS :
8160 return(h_config_customhdr_color);
8161 case V_INDEX_TOKEN_COLORS :
8162 return(h_config_indextoken_color);
8163 case V_PRINTER :
8164 return(h_config_printer);
8165 case V_PERSONAL_PRINT_CATEGORY :
8166 return(h_config_print_cat);
8167 case V_PERSONAL_PRINT_COMMAND :
8168 return(h_config_print_command);
8169 case V_PAT_ROLES :
8170 return(h_config_pat_roles);
8171 case V_PAT_FILTS :
8172 return(h_config_pat_filts);
8173 case V_PAT_SCORES :
8174 return(h_config_pat_scores);
8175 case V_PAT_INCOLS :
8176 return(h_config_pat_incols);
8177 case V_PAT_OTHER :
8178 return(h_config_pat_other);
8179 case V_PAT_SRCH :
8180 return(h_config_pat_srch);
8181 case V_INDEX_COLOR_STYLE :
8182 return(h_config_index_color_style);
8183 case V_TITLEBAR_COLOR_STYLE :
8184 return(h_config_titlebar_color_style);
8185 #ifdef _WINDOWS
8186 case V_FONT_NAME :
8187 return(h_config_font_name);
8188 case V_FONT_SIZE :
8189 return(h_config_font_size);
8190 case V_FONT_STYLE :
8191 return(h_config_font_style);
8192 case V_FONT_CHAR_SET :
8193 return(h_config_font_char_set);
8194 case V_PRINT_FONT_NAME :
8195 return(h_config_print_font_name);
8196 case V_PRINT_FONT_SIZE :
8197 return(h_config_print_font_size);
8198 case V_PRINT_FONT_STYLE :
8199 return(h_config_print_font_style);
8200 case V_PRINT_FONT_CHAR_SET :
8201 return(h_config_print_font_char_set);
8202 case V_WINDOW_POSITION :
8203 return(h_config_window_position);
8204 case V_CURSOR_STYLE :
8205 return(h_config_cursor_style);
8206 #else
8207 case V_COLOR_STYLE :
8208 return(h_config_color_style);
8209 #endif
8210 #ifdef ENABLE_LDAP
8211 case V_LDAP_SERVERS :
8212 return(h_config_ldap_servers);
8213 #endif
8214 #ifdef SMIME
8215 case V_PUBLICCERT_DIR :
8216 return(h_config_smime_pubcertdir);
8217 case V_PUBLICCERT_CONTAINER :
8218 return(h_config_smime_pubcertcon);
8219 case V_PRIVATEKEY_DIR :
8220 return(h_config_smime_privkeydir);
8221 case V_PRIVATEKEY_CONTAINER :
8222 return(h_config_smime_privkeycon);
8223 case V_CACERT_DIR :
8224 return(h_config_smime_cacertdir);
8225 case V_CACERT_CONTAINER :
8226 return(h_config_smime_cacertcon);
8227 #endif
8228 case V_RSS_NEWS :
8229 return(h_config_rss_news);
8230 case V_RSS_WEATHER :
8231 return(h_config_rss_weather);
8232 case V_WP_INDEXHEIGHT :
8233 return(h_config_wp_indexheight);
8234 case V_WP_INDEXLINES :
8235 return(h_config_wp_indexlines);
8236 case V_WP_AGGSTATE :
8237 return(h_config_wp_aggstate);
8238 case V_WP_STATE :
8239 return(h_config_wp_state);
8240 case V_WP_COLUMNS :
8241 return(h_config_wp_columns);
8242 default :
8243 return(NO_HELP);
8249 * We don't want the user to be able to edit their pinerc and set
8250 * printer to whatever they want if personal-print-command is fixed.
8251 * So make sure printer is set to something legitimate. If it isn't,
8252 * set it to something standard and return non-zero.
8255 printer_value_check_and_adjust(void)
8257 char **tt;
8258 char aname[100], wname[100];
8259 int ok = 0;
8260 struct variable *vars = ps_global->vars;
8262 if(vars[V_PERSONAL_PRINT_COMMAND].is_fixed && !vars[V_PRINTER].is_fixed){
8263 strncpy(aname, ANSI_PRINTER, sizeof(aname));
8264 aname[sizeof(aname)-1] = '\0';
8265 strncat(aname, "-no-formfeed", sizeof(aname)-strlen(aname)-1);
8266 strncpy(wname, WYSE_PRINTER, sizeof(wname));
8267 wname[sizeof(wname)-1] = '\0';
8268 strncat(wname, "-no-formfeed", sizeof(wname)-strlen(wname)-1);
8269 if(strucmp(VAR_PRINTER, ANSI_PRINTER) == 0
8270 || strucmp(VAR_PRINTER, aname) == 0
8271 || strucmp(VAR_PRINTER, WYSE_PRINTER) == 0
8272 || strucmp(VAR_PRINTER, wname) == 0)
8273 ok++;
8274 else if(VAR_STANDARD_PRINTER && VAR_STANDARD_PRINTER[0]){
8275 for(tt = VAR_STANDARD_PRINTER; *tt; tt++)
8276 if(strucmp(VAR_PRINTER, *tt) == 0)
8277 break;
8279 if(*tt)
8280 ok++;
8283 if(!ok){
8284 char *val;
8285 struct variable *v;
8287 if(VAR_STANDARD_PRINTER && VAR_STANDARD_PRINTER[0])
8288 val = VAR_STANDARD_PRINTER[0];
8289 else
8290 val = ANSI_PRINTER;
8292 v = &vars[V_PRINTER];
8293 if(v->main_user_val.p)
8294 fs_give((void **)&v->main_user_val.p);
8295 if(v->post_user_val.p)
8296 fs_give((void **)&v->post_user_val.p);
8297 if(v->current_val.p)
8298 fs_give((void **)&v->current_val.p);
8300 v->main_user_val.p = cpystr(val);
8301 v->current_val.p = cpystr(val);
8305 return(!ok);
8308 #ifdef _WINDOWS
8309 #include <schannel.h>
8310 #include <Schnlsp.h>
8311 #else
8312 #include <openssl/ssl.h>
8313 #endif /* _WINDOWS */
8315 char **
8316 get_supported_options(void)
8318 char **config;
8319 DRIVER *d;
8320 AUTHENTICATOR *a;
8321 char *title = _("Supported features in this Alpine");
8322 char sbuf[MAX_SCREEN_COLS+1], tmp[128];
8323 int cnt, alcnt, len, cols, disabled, any_disabled = 0, i;
8326 * Line count:
8327 * Title + blank = 2
8328 * SSL Title + SSL lines + blank = 5
8329 * Auth title + blank = 2
8330 * Driver title + blank = 2
8331 * LDAP title + LDAP line = 2
8332 * Disabled explanation + blank line = 4
8333 * end = 1
8335 cnt = 18;
8336 for(a = mail_lookup_auth(1); a; a = a->next)
8337 cnt++;
8338 for(d = (DRIVER *)mail_parameters(NIL, GET_DRIVERS, NIL);
8339 d; d = d->next)
8340 cnt++;
8342 alcnt = cnt;
8343 config = (char **) fs_get(alcnt * sizeof(char *));
8344 memset(config, 0, alcnt * sizeof(char *));
8346 cols = ps_global->ttyo ? ps_global->ttyo->screen_cols : 0;
8347 len = utf8_width(title);
8348 snprintf(sbuf, sizeof(sbuf), "%*s%s", cols > len ? (cols-len)/2 : 0, "", title);
8350 cnt = 0;
8351 if(cnt < alcnt)
8352 config[cnt] = cpystr(sbuf);
8354 if(++cnt < alcnt)
8355 config[cnt] = cpystr("");
8357 if(++cnt < alcnt)
8358 /* TRANSLATORS: headings */
8359 config[cnt] = cpystr(_("Encryption:"));
8361 if(++cnt < alcnt && mail_parameters(NIL, GET_SSLDRIVER, NIL)){
8362 config[cnt] = cpystr(_(" TLS and SSL"));
8363 tmp[0] = tmp[1] = ' ';
8364 tmp[2] = '\0';
8365 #ifdef _WINDOWS
8366 #ifdef SP_PROT_SSL3
8367 strcat(tmp, "SSLv3, ");
8368 #endif /* SP_PROT_SSL3 */
8369 #ifdef SP_PROT_TLS1
8370 strcat(tmp, "TLSv1, ");
8371 #endif /* SP_PROT_TLS1 */
8372 #ifdef SP_PROT_TLS1_1
8373 strcat(tmp, "TLSv1.1, ");
8374 #endif /* SP_PROT_TLS1 */
8375 #ifdef SP_PROT_TLS1_2
8376 strcat(tmp, "TLSv1.2, ");
8377 #endif /* SP_PROT_TLS1_2 */
8378 #ifdef SP_PROT_TLS1_3
8379 strcat(tmp, "TLSv1.3, ");
8380 #endif /* SP_PROT_TLS1_3 */
8381 #else
8382 #ifdef SSL3_VERSION
8383 #ifndef OPENSSL_NO_SSL3_METHOD
8384 strcat(tmp, "SSLv3, ");
8385 #endif /* OPENSSL_NO_SSL3_METHOD */
8386 #endif /* SSL3_VERSION */
8387 #ifdef TLS1_VERSION
8388 #ifndef OPENSSL_NO_TLS1_METHOD
8389 strcat(tmp, "TLSv1, ");
8390 #endif /* OPENSSL_NO_TLS1_METHOD */
8391 #endif /* TLS1_VERSION */
8392 #ifdef TLS1_1_VERSION
8393 #ifndef OPENSSL_NO_TLS1_1_METHOD
8394 strcat(tmp, "TLSv1.1, ");
8395 #endif /* OPENSSL_NO_TLS1_1_METHOD */
8396 #endif /* TLS1_1_VERSION */
8397 #ifdef TLS1_2_VERSION
8398 #ifndef OPENSSL_NO_TLS1_2_METHOD
8399 strcat(tmp, "TLSv1.2, ");
8400 #endif /* OPENSSL_NO_TLS1_2_METHOD */
8401 #endif /* TLS1_2_VERSION */
8402 #ifdef TLS1_3_VERSION
8403 #ifndef OPENSSL_NO_TLS1_3_METHOD
8404 strcat(tmp, "TLSv1.3, ");
8405 #endif /* OPENSSL_NO_TLS1_3_METHOD */
8406 #endif /* TLS1_3_VERSION */
8407 #endif /* _WINDOWS */
8408 tmp[strlen(tmp)-2] = '\0';
8410 else
8411 config[cnt] = cpystr(_(" None (no TLS or SSL)"));
8413 if(++cnt < alcnt)
8414 config[cnt] = cpystr(tmp);
8415 #ifdef SMIME
8416 if(++cnt < alcnt)
8417 config[cnt] = cpystr(" S/MIME");
8418 #endif
8420 if(++cnt < alcnt)
8421 config[cnt] = cpystr("");
8423 if(++cnt < alcnt)
8424 config[cnt] = cpystr(_("Authenticators:"));
8426 for(a = mail_lookup_auth(1); a; a = a->next){
8427 disabled = (a->client == NULL && a->server == NULL);
8428 any_disabled += disabled;
8429 snprintf(sbuf, sizeof(sbuf), " %s%s", a->name, disabled ? " (disabled)" : "");
8430 if(++cnt < alcnt)
8431 config[cnt] = cpystr(sbuf);
8434 if(++cnt < alcnt)
8435 config[cnt] = cpystr("");
8437 if(++cnt < alcnt)
8438 config[cnt] = cpystr(_("Mailbox drivers:"));
8440 for(d = (DRIVER *)mail_parameters(NIL, GET_DRIVERS, NIL);
8441 d; d = d->next){
8442 disabled = (d->flags & DR_DISABLE);
8443 any_disabled += disabled;
8444 snprintf(sbuf, sizeof(sbuf), " %s%s", d->name, disabled ? " (disabled)" : "");
8445 if(++cnt < alcnt)
8446 config[cnt] = cpystr(sbuf);
8449 if(++cnt < alcnt)
8450 config[cnt] = cpystr("");
8452 if(++cnt < alcnt)
8453 config[cnt] = cpystr(_("Directories:"));
8455 #ifdef ENABLE_LDAP
8456 if(++cnt < alcnt)
8457 config[cnt] = cpystr(" LDAP");
8458 #else
8459 if(++cnt < alcnt)
8460 config[cnt] = cpystr(" None (no LDAP)");
8461 #endif
8463 if(any_disabled){
8464 if(++cnt < alcnt)
8465 config[cnt] = cpystr("");
8467 if(ps_global->ttyo){
8468 if(++cnt < alcnt)
8469 config[cnt] = cpystr(_("Authenticators may be disabled because of the \"disable-these-authenticators\" hidden config option. Mailbox drivers may be disabled because of the \"disable-these-drivers\" hidden config option."));
8471 else{
8472 if(++cnt < alcnt)
8473 config[cnt] = cpystr(_("Authenticators may be disabled because of the \"disable-these-authenticators\""));
8474 if(++cnt < alcnt)
8475 config[cnt] = cpystr(_("hidden config option. Mailbox drivers may be disabled because of the"));
8476 if(++cnt < alcnt)
8477 config[cnt] = cpystr(_("\"disable-these-drivers\" hidden config option."));
8481 if(++cnt < alcnt)
8482 config[cnt] = NULL;
8484 return(config);
8488 unsigned
8489 reset_startup_rule(MAILSTREAM *stream)
8491 long rflags = ROLE_DO_OTHER;
8492 PAT_STATE pstate;
8493 PAT_S *pat;
8494 unsigned startup_rule;
8496 startup_rule = IS_NOTSET;
8498 if(stream && nonempty_patterns(rflags, &pstate)){
8499 for(pat = first_pattern(&pstate); pat; pat = next_pattern(&pstate)){
8500 if(match_pattern(pat->patgrp, stream, NULL, NULL, NULL,
8501 SE_NOSERVER|SE_NOPREFETCH))
8502 break;
8505 if(pat && pat->action && !pat->action->bogus)
8506 startup_rule = pat->action->startup_rule;
8509 return(startup_rule);
8513 #ifdef _WINDOWS
8515 char *
8516 transformed_color(old)
8517 char *old;
8519 if(!old)
8520 return("");
8522 if(!struncmp(old, "color008", 8))
8523 return("colorlgr");
8524 else if(!struncmp(old, "color009", 8))
8525 return("colormgr");
8526 else if(!struncmp(old, "color010", 8))
8527 return("colordgr");
8529 return("");
8534 * If this is the first time we've run a version > 4.40, and there
8535 * is evidence that the config file has not been used by unix pine,
8536 * then we convert color008 to colorlgr, color009 to colormgr, and
8537 * color010 to colordgr. If the config file is being used by
8538 * unix pine then color008 may really supposed to be color008, color009
8539 * may really supposed to be red, and color010 may really supposed to be
8540 * green. Same if we've already run 4.41 or higher previously.
8542 * Returns 0 if no changes, > 0 if something was changed.
8545 convert_pc_gray_names(ps, prc, which)
8546 struct pine *ps;
8547 PINERC_S *prc;
8548 EditWhich which;
8550 struct variable *v;
8551 int ret = 0, ic = 0;
8552 char **s, *t, *p, *pstr, *new, *pval, **apval, **lval;
8554 for(v = ps->vars; v->name; v++){
8555 if(!color_holding_var(ps, v) || v == &ps->vars[V_KW_COLORS])
8556 continue;
8558 if(v == &ps->vars[V_VIEW_HDR_COLORS]){
8560 if((lval = LVAL(v,which)) != NULL){
8561 /* fix these in place */
8562 for(s = lval; (t = *s) != NULL; s++){
8563 if((p = srchstr(t, "FG=color008")) ||
8564 (p = srchstr(t, "FG=color009")) ||
8565 (p = srchstr(t, "FG=color010"))){
8566 strncpy(p+3, transformed_color(p+3), 8);
8567 ret++;
8570 if((p = srchstr(t, "BG=color008")) ||
8571 (p = srchstr(t, "BG=color009")) ||
8572 (p = srchstr(t, "BG=color010"))){
8573 strncpy(p+3, transformed_color(p+3), 8);
8574 ret++;
8579 else{
8580 if((pval = PVAL(v,which)) != NULL){
8581 apval = APVAL(v,which);
8582 if(apval && (!strucmp(pval, "color008") ||
8583 !strucmp(pval, "color009") ||
8584 !strucmp(pval, "color010"))){
8585 new = transformed_color(pval);
8586 if(*apval)
8587 fs_give((void **)apval);
8589 *apval = cpystr(new);
8590 ret++;
8596 v = &ps->vars[V_PAT_INCOLS];
8597 if((lval = LVAL(v,which)) != NULL){
8598 for(s = lval; (t = *s) != NULL; s++){
8599 if((pstr = srchstr(t, "action=")) != NULL){
8600 if((p = srchstr(pstr, "FG=color008")) ||
8601 (p = srchstr(pstr, "FG=color009")) ||
8602 (p = srchstr(pstr, "FG=color010"))){
8603 strncpy(p+3, transformed_color(p+3), 8);
8604 ic++;
8607 if((p = srchstr(pstr, "BG=color008")) ||
8608 (p = srchstr(pstr, "BG=color009")) ||
8609 (p = srchstr(pstr, "BG=color010"))){
8610 strncpy(p+3, transformed_color(p+3), 8);
8611 ic++;
8617 if(ic)
8618 set_current_val(&ps->vars[V_PAT_INCOLS], TRUE, TRUE);
8620 return(ret+ic);
8625 unix_color_style_in_pinerc(prc)
8626 PINERC_S *prc;
8628 PINERC_LINE *pline;
8630 for(pline = prc ? prc->pinerc_lines : NULL;
8631 pline && (pline->var || pline->line); pline++)
8632 if(pline->line && !struncmp("color-style=", pline->line, 12))
8633 return(1);
8635 return(0);
8638 char *
8639 pcpine_general_help(titlebuf)
8640 char *titlebuf;
8642 if(titlebuf)
8643 strcpy(titlebuf, "PC Alpine For Windows");
8645 return(pcpine_help(h_pine_for_windows));
8648 #endif /* _WINDOWS */