* Clear even more warnings from clang 3.5 and MAC OSX.
[alpine.git] / pith / conf.c
blob4b2dc3844030aa41d1474ffeaa324c51bf76579d
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-2015 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
56 #define TO_BAIL_THRESHOLD 60
60 * Internal prototypes
62 void convert_configvars_to_utf8(struct variable *, char *);
63 void convert_configvar_to_utf8(struct variable *, char *);
64 void set_current_pattern_vals(struct pine *);
65 void convert_pattern_data(void);
66 void convert_filts_pattern_data(void);
67 void convert_scores_pattern_data(void);
68 void convert_pinerc_patterns(long);
69 void convert_pinerc_filts_patterns(long);
70 void convert_pinerc_scores_patterns(long);
71 void set_old_growth_bits(struct pine *, int);
72 int var_is_in_rest_of_file(char *, char *);
73 char *skip_over_this_var(char *, char *);
74 char *native_nl(char *);
75 void set_color_val(struct variable *, int);
76 int copy_localfile_to_remotefldr(RemType, char *, char *, char *, char **);
77 char *backcompat_convert_from_utf8(char **, size_t, char *);
78 #ifdef _WINDOWS
79 char *transformed_color(char *);
80 int convert_pc_gray_names(struct pine *, PINERC_S *, EditWhich);
81 int unix_color_style_in_pinerc(PINERC_S *);
82 char *pcpine_general_help(char *);
83 char *pcpine_help(HelpType); /* defined in alpine/help */
84 #endif /* _WINDOWS */
87 /* hook too allow caller to decide what to do about failure */
88 int (*pith_opt_remote_pinerc_failure)(void);
91 /*------------------------------------
92 Some definitions to keep the static "variable" array below
93 a bit more readable...
94 ----*/
95 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\
96 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";
99 CONF_TXT_T cf_text_personal_name[] = "Over-rides your full name from Unix password file. Required for PC-Alpine.";
101 CONF_TXT_T cf_text_user_id[] = "Your login/e-mail user name";
103 CONF_TXT_T cf_text_user_domain[] = "Sets domain part of From: and local addresses in outgoing mail.";
105 CONF_TXT_T cf_text_smtp_server[] = "List of SMTP servers for sending mail. If blank: Unix Alpine uses sendmail.";
107 CONF_TXT_T cf_text_nntp_server[] = "NNTP server for posting news. Also sets news-collections for news reading.";
109 #ifdef SMIME
111 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.";
113 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.";
115 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.";
117 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.";
119 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.";
121 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.";
123 #endif /* SMIME */
125 #ifdef ENABLE_LDAP
126 CONF_TXT_T cf_text_ldap_server[] = "LDAP servers for looking up addresses.";
127 #endif /* ENABLE_LDAP */
129 CONF_TXT_T cf_text_rss_news[] = "RSS News feed";
131 CONF_TXT_T cf_text_rss_weather[] = "RSS Weather feed";
133 CONF_TXT_T cf_text_wp_indexheight[] = "Web Alpine index table row height";
135 CONF_TXT_T cf_text_wp_indexlines[] = "Web Alpine number of index lines in table";
137 CONF_TXT_T cf_text_wp_aggstate[] = "Web Alpine aggregate operations tab state";
139 CONF_TXT_T cf_text_wp_state[] = "Web Alpine various aspects of cross-session state";
141 CONF_TXT_T cf_text_wp_columns[] = "Web Alpine preferred width for message display in characters";
143 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).";
145 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";
147 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[]";
149 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}[]";
151 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";
153 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.";
155 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.";
157 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.";
159 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";
161 CONF_TXT_T cf_text_read_message_folder[] = "If set, specifies where already-read messages will be moved upon quitting.";
163 CONF_TXT_T cf_text_form_letter_folder[] = "If set, specifies where form letters should be stored.";
165 CONF_TXT_T cf_text_trash_folder[] = "If set, specifies where trash is moved to in Web Alpine.";
167 CONF_TXT_T cf_text_signature_file[] = "Over-rides default path for signature file. Default is ~/.signature";
169 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.";
171 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";
173 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";
175 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-.";
177 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)";
179 CONF_TXT_T cf_text_default_composer_hdrs[] = "Only show these headers (by default) when composing messages";
181 CONF_TXT_T cf_text_customized_hdrs[] = "Add these customized headers (and possible default values) when composing";
183 CONF_TXT_T cf_text_view_headers[] = "When viewing messages, include this list of headers";
185 CONF_TXT_T cf_text_view_margin_left[] = "When viewing messages, number of blank spaces between left display edge and text";
187 CONF_TXT_T cf_text_view_margin_right[] = "When viewing messages, number of blank spaces between right display edge and text";
189 CONF_TXT_T cf_text_quote_suppression[] = "When viewing messages, number of lines of quote displayed before suppressing";
191 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)";
193 CONF_TXT_T cf_text_color_style[] = "Controls display of color";
195 CONF_TXT_T cf_text_current_indexline_style[] = "Controls display of color for current index line";
197 CONF_TXT_T cf_text_titlebar_color_style[] = "Controls display of color for the titlebar at top of screen";
199 CONF_TXT_T cf_text_view_hdr_color[] = "When viewing messages, these are the header colors";
201 CONF_TXT_T cf_text_index_token_color[] = "Colors in which tokens will be displayed in the index screen";
203 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).";
205 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.)";
207 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\".";
209 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\".";
211 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\".";
213 CONF_TXT_T cf_text_old_char_set[] = "Character-set is obsolete, use display-character-set, keyboard-character-set,\n# and posting-character-set.";
215 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).";
217 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.";
219 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.";
221 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.";
223 CONF_TXT_T cf_text_editor[] = "Specifies the program invoked by ^_ in the Composer,\n# or the \"enable-alternate-editor-implicitly\" feature.";
225 CONF_TXT_T cf_text_speller[] = "Specifies the program invoked by ^T in the Composer.";
227 CONF_TXT_T cf_text_deadlets[] = "Specifies the number of dead letter files to keep when canceling.";
229 CONF_TXT_T cf_text_fillcol[] = "Specifies the column of the screen where the composer should wrap.";
231 CONF_TXT_T cf_text_replystr[] = "Specifies the string to insert when replying to a message.";
233 CONF_TXT_T cf_text_quotereplstr[] = "Specifies the string to replace quotes with when viewing a message.";
235 CONF_TXT_T cf_text_replyintro[] = "Specifies the introduction to insert when replying to a message.";
237 CONF_TXT_T cf_text_emptyhdr[] = "Specifies the string to use when sending a message with no to or cc.";
239 CONF_TXT_T cf_text_image_viewer[] = "Program to view images (e.g. GIF or TIFF attachments).";
241 CONF_TXT_T cf_text_browser[] = "List of programs to open Internet URLs (e.g. http or ftp references).";
243 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\".";
245 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\".";
247 CONF_TXT_T cf_reopen_rule[] = "Controls behavior when reopening an already open folder.";
249 CONF_TXT_T cf_text_thread_disp_style[] = "Style that MESSAGE INDEX is displayed in when threading.";
251 CONF_TXT_T cf_text_thread_index_style[] = "Style of THREAD INDEX or default MESSAGE INDEX when threading.";
253 CONF_TXT_T cf_text_thread_more_char[] = "When threading, character used to indicate collapsed messages underneath.";
255 CONF_TXT_T cf_text_thread_exp_char[] = "When threading, character used to indicate expanded messages underneath.";
257 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.";
259 CONF_TXT_T cf_text_use_only_domain_name[] = "If \"user-domain\" not set, strips hostname in FROM address. (Unix only)";
261 CONF_TXT_T cf_text_printer[] = "Your default printer selection";
263 CONF_TXT_T cf_text_personal_print_command[] = "List of special print commands";
265 CONF_TXT_T cf_text_personal_print_cat[] = "Which category default print command is in";
267 CONF_TXT_T cf_text_standard_printer[] = "The system wide standard printers";
269 CONF_TXT_T cf_text_last_time_prune_quest[] = "Set by Alpine; controls beginning-of-month sent-mail pruning.";
271 CONF_TXT_T cf_text_last_version_used[] = "Set by Alpine; controls display of \"new version\" message.";
273 CONF_TXT_T cf_text_disable_drivers[] = "List of mail drivers to disable.";
275 CONF_TXT_T cf_text_disable_auths[] = "List of SASL authenticators to disable.";
277 CONF_TXT_T cf_text_remote_abook_metafile[] = "Set by Alpine; contains data for caching remote address books.";
279 CONF_TXT_T cf_text_old_patterns[] = "Patterns is obsolete, use patterns-xxx";
281 CONF_TXT_T cf_text_old_filters[] = "Patterns-filters is obsolete, use patterns-filters2";
283 CONF_TXT_T cf_text_old_scores[] = "Patterns-scores is obsolete, use patterns-scores2";
285 CONF_TXT_T cf_text_patterns[] = "Patterns and their actions are stored here.";
287 CONF_TXT_T cf_text_remote_abook_history[] = "How many extra copies of remote address book should be kept. Default: 3";
289 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";
291 CONF_TXT_T cf_text_bugs_fullname[] = "Full name for bug report address used by \"Report Bug\" command";
293 CONF_TXT_T cf_text_bugs_address[] = "Email address used to send bug reports";
295 CONF_TXT_T cf_text_bugs_extras[] = "Program/Script used by \"Report Bug\" command. No default.";
297 CONF_TXT_T cf_text_suggest_fullname[] = "Full name for suggestion address used by \"Report Bug\" command";
299 CONF_TXT_T cf_text_suggest_address[] = "Email address used to send suggestions";
301 CONF_TXT_T cf_text_local_fullname[] = "Full name for \"local support\" address used by \"Report Bug\" command.\n# Default: Local Support";
303 CONF_TXT_T cf_text_local_address[] = "Email address used to send to \"local support\".\n# Default: postmaster";
305 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";
307 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.";
309 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.";
311 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)";
313 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.";
315 CONF_TXT_T cf_text_out_fltr[] = "This defines a program that message text is piped into before MIME\n# encoding, prior to sending";
317 CONF_TXT_T cf_text_alt_addrs[] = "A list of alternate addresses the user is known by";
319 CONF_TXT_T cf_text_keywords[] = "A list of keywords for use in categorizing messages";
321 CONF_TXT_T cf_text_kw_colors[] = "Colors used to display keywords in the index";
323 CONF_TXT_T cf_text_kw_braces[] = "Characters which surround keywords in SUBJKEY token.\n# Default is \"{\" \"} \"";
325 CONF_TXT_T cf_text_opening_sep[] = "Characters between subject and opening text in SUBJECTTEXT token.\n# Default is \" - \"";
327 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";
329 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";
331 CONF_TXT_T cf_text_overlap[] = "The number of lines of overlap when scrolling through message text";
333 CONF_TXT_T cf_text_maxremstreams[] = "The maximum number of non-stayopen remote connections that Alpine will use";
335 CONF_TXT_T cf_text_permlocked[] = "A list of folders that should be left open once opened (INBOX is implicit)";
337 CONF_TXT_T cf_text_margin[] = "Number of lines from top and bottom of screen where single\n# line scrolling occurs.";
339 CONF_TXT_T cf_text_stat_msg_delay[] = "The number of seconds to sleep after writing a status message";
341 CONF_TXT_T cf_text_busy_cue_rate[] = "Number of times per-second to update busy cue messages";
343 CONF_TXT_T cf_text_psleep[] = "UNIX ONLY (except MAC OSX): When an attachment is opened, this variable controls the number\n#of seconds to wait between checks if the user has ended viewing the attachment.\n#minimun value: 60 seconds, maximum value: 600 seconds (10 minutes). Default: 60 seconds";
345 CONF_TXT_T cf_text_mailcheck[] = "The approximate number of seconds between checks for new mail";
347 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";
349 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";
351 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";
353 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\".";
355 CONF_TXT_T cf_text_news_spooldir[] = "Directory containing system's news data.\n# The default is typically \"/usr/spool/news\"";
357 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.";
359 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.";
361 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.";
363 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.";
365 CONF_TXT_T cf_text_goto_default[] = "Sets the default folder and collection offered at the Goto Command's prompt.";
367 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.";
369 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.";
371 CONF_TXT_T cf_text_newmail_fifo_path[] = "Sets the filename for the newmail fifo (named pipe). Unix only.";
373 CONF_TXT_T cf_text_nmw_width[] = "Sets the width for the NewMail screen.";
375 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.";
377 CONF_TXT_T cf_text_debug_mem[] = "Debug-memory is obsolete";
379 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).";
381 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.";
383 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.";
385 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.";
387 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.";
389 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.";
391 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\")";
393 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.";
395 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.";
397 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.";
399 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.";
401 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.";
403 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.";
405 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\")";
407 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.";
409 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.";
411 CONF_TXT_T cf_text_elm_style_save[] = "Elm-style-save is obsolete, use saved-msg-name-rule";
413 CONF_TXT_T cf_text_header_in_reply[] = "Header-in-reply is obsolete, use include-header-in-reply in feature-list";
415 CONF_TXT_T cf_text_feature_level[] = "Feature-level is obsolete, use feature-list";
417 CONF_TXT_T cf_text_old_style_reply[] = "Old-style-reply is obsolete, use signature-at-bottom in feature-list";
419 CONF_TXT_T cf_text_compose_mime[] = "Compose-mime is obsolete";
421 CONF_TXT_T cf_text_show_all_characters[] = "Show-all-characters is obsolete";
423 CONF_TXT_T cf_text_save_by_sender[] = "Save-by-sender is obsolete, use saved-msg-name-rule";
425 CONF_TXT_T cf_text_file_dir[] = "Default directory used for Attachment handling (attach and save)\n# and Export command output";
427 CONF_TXT_T cf_text_folder_extension[] = "Folder-extension is obsolete";
429 CONF_TXT_T cf_text_normal_foreground_color[] = "Choose: black, blue, green, cyan, red, magenta, yellow, or white.";
431 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.";
433 CONF_TXT_T cf_text_newsrc_path[] = "Full path and name of NEWSRC file";
436 /*----------------------------------------------------------------------
437 These are the variables that control a number of pine functions. They
438 come out of the .pinerc and the /usr/local/lib/pine.conf files. Some can
439 be set by the user while in Alpine. Eventually all the local ones should
440 be so and maybe the global ones too.
442 Each variable can have a command-line, user, global, and current value.
443 All of these values are malloc'd. The user value is the one read out of
444 the user's .pinerc, the global value is the one from the system pine
445 configuration file. There are often defaults for the global values, set
446 at the start of init_vars(). Perhaps someday there will be group values.
447 The current value is the one that is actually in use.
448 ----*/
449 /* name is_changed_val
450 remove_quotes |
451 is_outermost | |
452 is_onlymain | | |
453 is_fixed | | | |
454 is_list | | | | |
455 is_global | | | | | |
456 is_user | | | | | | |
457 been_written | | | | | | | |
458 is_used | | | | | | | | |
459 is_obsolete | | | | | | | | | |
460 | | | | | | | | | | |
461 (on following line) description | | | | | | | | | | |
462 | | | | | | | | | | | |
463 | | | | | | | | | | | | */
464 static struct variable variables[] = {
465 {"personal-name", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
466 NULL, cf_text_personal_name},
468 #if defined(DOS) || defined(OS2)
469 /* Have to have this on DOS, PC's, Macs, etc... */
470 "user-id", 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
471 #else /* Don't allow on UNIX machines for some security */
472 "user-id", 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
473 #endif
474 "User ID", cf_text_user_id},
475 {"user-domain", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
476 NULL, cf_text_user_domain},
477 {"smtp-server", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
478 "SMTP Server (for sending)", cf_text_smtp_server},
479 {"nntp-server", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
480 "NNTP Server (for news)", cf_text_nntp_server},
481 {"inbox-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
482 NULL, cf_text_inbox_path},
483 {"incoming-archive-folders", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
484 NULL, cf_text_archived_folders},
485 {"pruned-folders", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
486 NULL, cf_text_pruned_folders},
487 {"default-fcc", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
488 "Default Fcc (File carbon copy)", cf_text_default_fcc},
489 {"default-saved-msg-folder", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
490 "Default Saved Message Folder", cf_text_default_saved},
491 {"postponed-folder", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
492 NULL, cf_text_postponed_folder},
493 {"read-message-folder", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
494 NULL, cf_text_read_message_folder},
495 {"form-letter-folder", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
496 NULL, cf_text_form_letter_folder},
497 {"trash-folder", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
498 NULL, cf_text_trash_folder},
499 {"literal-signature", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
500 NULL, cf_text_literal_sig},
501 {"signature-file", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
502 NULL, cf_text_signature_file},
503 {"feature-list", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
504 NULL, cf_text_feature_list},
505 {"initial-keystroke-list", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
506 NULL, cf_text_initial_keystroke_list},
507 {"default-composer-hdrs", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
508 "Default Composer Headers", cf_text_default_composer_hdrs},
509 {"customized-hdrs", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
510 "Customized Headers", cf_text_customized_hdrs},
511 {"viewer-hdrs", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
512 "Viewer Headers", cf_text_view_headers},
513 {"viewer-margin-left", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
514 NULL, cf_text_view_margin_left},
515 {"viewer-margin-right", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
516 NULL, cf_text_view_margin_right},
517 {"quote-suppression-threshold", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
518 NULL, cf_text_quote_suppression},
519 {"saved-msg-name-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
520 "Saved Message Name Rule", cf_text_save_msg_name_rule},
521 {"fcc-name-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
522 NULL, cf_text_fcc_name_rule},
523 {"sort-key", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
524 NULL, cf_text_sort_key},
525 {"addrbook-sort-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
526 "Address Book Sort Rule", cf_text_addrbook_sort_rule},
527 {"folder-sort-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
528 NULL, cf_text_folder_sort_rule},
529 {"goto-default-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
530 NULL, cf_text_goto_default},
531 {"incoming-startup-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
532 NULL, cf_text_inc_startup},
533 {"pruning-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
534 NULL, cf_pruning_rule},
535 {"folder-reopen-rule", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
536 NULL, cf_reopen_rule},
537 {"threading-display-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
538 NULL, cf_text_thread_disp_style},
539 {"threading-index-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
540 NULL, cf_text_thread_index_style},
541 {"threading-indicator-character", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
542 NULL, cf_text_thread_more_char},
543 {"threading-expanded-character", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
544 NULL, cf_text_thread_exp_char},
545 {"threading-lastreply-character", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
546 "Threading Last Reply Character", cf_text_thread_lastreply_char},
547 #ifndef _WINDOWS
548 {"display-character-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
549 NULL, cf_text_disp_char_set},
550 {"character-set", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
551 NULL, cf_text_old_char_set},
552 {"keyboard-character-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
553 NULL, cf_text_key_char_set},
554 #endif /* ! _WINDOWS */
555 {"posting-character-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
556 NULL, cf_text_post_character_set},
557 {"unknown-character-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
558 NULL, cf_text_unk_character_set},
559 {"editor", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
560 NULL, cf_text_editor},
561 {"speller", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
562 NULL, cf_text_speller},
563 {"composer-wrap-column", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
564 NULL, cf_text_fillcol},
565 {"reply-indent-string", 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
566 NULL, cf_text_replystr},
567 {"reply-leadin", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
568 NULL, cf_text_replyintro},
569 {"quote-replace-string", 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
570 NULL, cf_text_quotereplstr},
571 {"composer-word-separators", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
572 NULL, cf_text_wordsep},
573 {"empty-header-message", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
574 NULL, cf_text_emptyhdr},
575 {"image-viewer", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
576 NULL, cf_text_image_viewer},
577 {"use-only-domain-name", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
578 NULL, cf_text_use_only_domain_name},
579 {"bugs-fullname", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
580 NULL, cf_text_bugs_fullname},
581 {"bugs-address", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
582 NULL, cf_text_bugs_address},
583 {"bugs-additional-data", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
584 NULL, cf_text_bugs_extras},
585 {"suggest-fullname", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
586 NULL, cf_text_suggest_fullname},
587 {"suggest-address", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
588 NULL, cf_text_suggest_address},
589 {"local-fullname", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
590 NULL, cf_text_local_fullname},
591 {"local-address", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
592 NULL, cf_text_local_address},
593 {"forced-abook-entry", 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0,
594 NULL, cf_text_forced_abook},
595 {"kblock-passwd-count", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
596 NULL, cf_text_kblock_passwd},
597 {"display-filters", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
598 NULL, cf_text_in_fltr},
599 {"sending-filters", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
600 NULL, cf_text_out_fltr},
601 {"alt-addresses", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
602 "Alternate Addresses", cf_text_alt_addrs},
603 {"keywords", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
604 NULL, cf_text_keywords},
605 {"keyword-surrounding-chars", 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
606 "Keyword Surrounding Characters", cf_text_kw_braces},
607 {"opening-text-separator-chars", 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
608 "Opening Text Separator Characters", cf_text_opening_sep},
609 {"addressbook-formats", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
610 "Address Book Formats", cf_text_abook_formats},
611 {"index-format", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
612 NULL, cf_text_index_format},
613 {"viewer-overlap", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
614 NULL, cf_text_overlap},
615 {"scroll-margin", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
616 NULL, cf_text_margin},
617 {"status-message-delay", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
618 NULL, cf_text_stat_msg_delay},
619 {"busy-cue-rate", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
620 NULL, cf_text_busy_cue_rate},
621 {"mailcap-check-interval", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
622 NULL, cf_text_psleep},
623 {"mail-check-interval", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
624 NULL, cf_text_mailcheck},
625 {"mail-check-interval-noncurrent", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
626 NULL, cf_text_mailchecknoncurr},
627 {"maildrop-check-minimum", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
628 NULL, cf_text_maildropcheck},
629 {"nntp-range", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
630 "NNTP Range", cf_text_nntprange},
631 {"newsrc-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
632 NULL, cf_text_newsrc_path},
633 {"news-active-file-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
634 NULL, cf_text_news_active},
635 {"news-spool-directory", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
636 NULL, cf_text_news_spooldir},
637 {"upload-command", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
638 NULL, cf_text_upload_cmd},
639 {"upload-command-prefix", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
640 NULL, cf_text_upload_prefix},
641 {"download-command", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
642 NULL, cf_text_download_cmd},
643 {"download-command-prefix", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
644 NULL, cf_text_download_prefix},
645 {"mailcap-search-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
646 NULL, cf_text_mailcap_path},
647 {"mimetype-search-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
648 NULL, cf_text_mimetype_path},
649 {"url-viewers", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
650 "URL-Viewers", cf_text_browser},
651 {"max-remote-connections", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
652 "Maximum Remote Connections", cf_text_maxremstreams},
653 {"stay-open-folders", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
654 "Stayopen Folders", cf_text_permlocked},
655 {"incoming-check-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
656 NULL, cf_text_inc_check_timeo},
657 {"incoming-check-interval", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
658 NULL, cf_text_inc_check_interval},
659 {"incoming-check-interval-secondary", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
660 NULL, cf_text_inc_second_check_interval},
661 {"incoming-check-list", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
662 NULL, cf_text_inc_check_list},
663 {"dead-letter-files", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
664 NULL, cf_text_deadlets},
665 #if !defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO)
666 {"newmail-fifo-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
667 "NewMail FIFO Path", cf_text_newmail_fifo_path},
668 #endif
669 {"newmail-window-width", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
670 "NewMail Window Width", cf_text_nmw_width},
672 * Starting here, the variables are hidden in the Setup/Config screen.
673 * They are exposed if feature expose-hidden-config is set.
675 {"incoming-folders", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
676 NULL, cf_text_incoming_folders},
677 {"mail-directory", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
678 NULL, cf_text_mail_directory},
679 {"folder-collections", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
680 NULL, cf_text_folder_collections},
681 {"news-collections", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
682 NULL, cf_text_news_collections},
683 {"address-book", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
684 NULL, cf_text_address_book},
685 {"global-address-book", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
686 NULL, cf_text_global_address_book},
687 {"standard-printer", 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0,
688 NULL, cf_text_standard_printer},
689 {"last-time-prune-questioned", 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0,
690 NULL, cf_text_last_time_prune_quest},
691 {"last-version-used", 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0,
692 NULL, cf_text_last_version_used},
693 {"sendmail-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
694 NULL, cf_text_sendmail_path},
695 {"operating-dir", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
696 NULL, cf_text_oper_dir},
697 {"user-input-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
698 NULL, cf_text_user_input_timeo},
699 /* OBSOLETE */
700 #ifdef DEBUGJOURNAL
701 {"debug-memory", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
702 NULL, cf_text_debug_mem},
703 #endif
704 {"tcp-open-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
705 "TCP Open Timeout", cf_text_tcp_open_timeo},
706 {"tcp-read-warning-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
707 "TCP Read Warning Timeout", cf_text_tcp_read_timeo},
708 {"tcp-write-warning-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
709 "TCP Write Warning Timeout", cf_text_tcp_write_timeo},
710 {"tcp-query-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
711 "TCP Query Timeout", cf_text_tcp_query_timeo},
712 {"rsh-command", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
713 NULL, cf_text_rsh_command},
714 {"rsh-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
715 NULL, cf_text_rsh_path},
716 {"rsh-open-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
717 NULL, cf_text_rsh_open_timeo},
718 {"ssh-command", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
719 NULL, cf_text_ssh_command},
720 {"ssh-path", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
721 NULL, cf_text_ssh_path},
722 {"ssh-open-timeout", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
723 NULL, cf_text_ssh_open_timeo},
724 {"new-version-threshold", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
725 NULL, cf_text_version_threshold},
726 {"disable-these-drivers", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
727 NULL, cf_text_disable_drivers},
728 {"disable-these-authenticators", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
729 NULL, cf_text_disable_auths},
730 {"remote-abook-metafile", 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0,
731 NULL, cf_text_remote_abook_metafile},
732 {"remote-abook-history", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
733 NULL, cf_text_remote_abook_history},
734 {"remote-abook-validity", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
735 NULL, cf_text_remote_abook_validity},
736 {"printer", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
737 NULL, cf_text_printer},
738 {"personal-print-command", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
739 NULL, cf_text_personal_print_command},
740 {"personal-print-category", 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
741 NULL, cf_text_personal_print_cat},
742 {"patterns", 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
743 NULL, cf_text_old_patterns},
744 {"patterns-roles", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
745 NULL, cf_text_patterns},
746 {"patterns-filters2", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
747 "Patterns Filters", cf_text_patterns},
748 {"patterns-filters", 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
749 NULL, cf_text_old_filters},
750 {"patterns-scores2", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
751 "Patterns Scores", cf_text_patterns},
752 {"patterns-scores", 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
753 NULL, cf_text_old_scores},
754 {"patterns-indexcolors", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
755 NULL, cf_text_patterns},
756 {"patterns-other", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
757 NULL, cf_text_patterns},
758 {"patterns-search", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
759 NULL, cf_text_patterns},
760 /* OBSOLETE VARS */
761 {"elm-style-save", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
762 NULL, cf_text_elm_style_save},
763 {"header-in-reply", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
764 NULL, cf_text_header_in_reply},
765 {"feature-level", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
766 NULL, cf_text_feature_level},
767 {"old-style-reply", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
768 NULL, cf_text_old_style_reply},
769 {"compose-mime", 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
770 NULL, cf_text_compose_mime},
771 {"show-all-characters", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
772 NULL, cf_text_show_all_characters},
773 {"save-by-sender", 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
774 NULL, cf_text_save_by_sender},
775 #if defined(DOS) || defined(OS2)
776 {"file-directory", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
777 NULL, cf_text_file_dir},
778 {"folder-extension", 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0,
779 NULL, cf_text_folder_extension},
780 #endif
781 #ifndef _WINDOWS
782 {"color-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
783 NULL, cf_text_color_style},
784 #endif
785 {"current-indexline-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
786 NULL, cf_text_current_indexline_style},
787 {"titlebar-color-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
788 NULL, cf_text_titlebar_color_style},
789 {"normal-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
790 NULL, cf_text_normal_foreground_color},
791 {"normal-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
792 {"reverse-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
793 {"reverse-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
794 {"title-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
795 {"title-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
796 {"title-closed-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
797 {"title-closed-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
798 {"folder-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
799 {"folder-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
800 {"directory-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
801 {"directory-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
802 {"folder-list-text-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
803 {"folder-list-text-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
804 {"status-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
805 {"status-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
806 {"keylabel-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
807 {"keylabel-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
808 {"keyname-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
809 {"keyname-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
810 {"selectable-item-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
811 {"selectable-item-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
812 {"meta-message-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
813 {"meta-message-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
814 {"quote1-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
815 {"quote1-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
816 {"quote2-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
817 {"quote2-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
818 {"quote3-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
819 {"quote3-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
820 {"incoming-unseen-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
821 {"incoming-unseen-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
822 {"signature-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
823 {"signature-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
824 {"prompt-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
825 {"prompt-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
826 {"header-general-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
827 {"header-general-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
828 {"index-to-me-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
829 {"index-to-me-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
830 {"index-important-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
831 {"index-important-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
832 {"index-deleted-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
833 {"index-deleted-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
834 {"index-answered-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
835 {"index-answered-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
836 {"index-new-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
837 {"index-new-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
838 {"index-recent-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
839 {"index-recent-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
840 {"index-forward-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
841 {"index-forward-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
842 {"index-unseen-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
843 {"index-unseen-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
844 {"index-highpriority-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
845 {"index-highpriority-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
846 {"index-lowpriority-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
847 {"index-lowpriority-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
848 {"index-arrow-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
849 {"index-arrow-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
850 {"index-subject-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
851 {"index-subject-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
852 {"index-from-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
853 {"index-from-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
854 {"index-opening-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
855 {"index-opening-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0},
856 {"index-token-colors", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
857 NULL, cf_text_index_token_color},
858 {"viewer-hdr-colors", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
859 "Viewer Header Colors", cf_text_view_hdr_color},
860 {"keyword-colors", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
861 NULL, cf_text_kw_colors},
862 #ifdef _WINDOWS
863 {"font-name", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
864 NULL, "name and size of font."},
865 {"font-size", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
866 {"font-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
867 {"font-char-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
868 {"print-font-name", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
869 NULL, "name and size of printer font."},
870 {"print-font-size", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
871 {"print-font-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
872 {"print-font-char-set", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
873 {"window-position", 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0,
874 NULL, cf_text_window_position},
875 {"cursor-style", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL},
876 #endif /* _WINDOWS */
877 #ifdef SMIME
878 {"smime-public-cert-directory", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
879 "S/MIME - Public Cert Directory", cf_text_publiccertdir},
880 {"smime-public-cert-container", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
881 "S/MIME - Public Cert Container", cf_text_publiccertcontainer},
882 {"smime-private-key-directory", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
883 "S/MIME - Private Key Directory", cf_text_privatekeydir},
884 {"smime-private-key-container", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
885 "S/MIME - Private Key Container", cf_text_privatekeycontainer},
886 {"smime-cacert-directory", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
887 "S/MIME - Cert Authority Directory", cf_text_cacertdir},
888 {"smime-cacert-container", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
889 "S/MIME - Cert Authority Container", cf_text_cacertcontainer},
890 #endif /* SMIME */
891 #ifdef ENABLE_LDAP
892 {"ldap-servers", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
893 "LDAP Servers", cf_text_ldap_server},
894 #endif /* ENABLE_LDAP */
895 {"rss-news", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
896 "WEB ALPINE - RSS News", cf_text_rss_news},
897 {"rss-weather", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
898 "WEB ALPINE - RSS Weather", cf_text_rss_weather},
899 {"wp-indexheight", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
900 "WEB ALPINE - Index Height", cf_text_wp_indexheight},
901 {"wp-indexlines", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
902 "WEB ALPINE - Index Lines", cf_text_wp_indexlines},
903 {"wp-aggstate", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
904 "WEB ALPINE - Aggregate State", cf_text_wp_aggstate},
905 {"wp-state", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
906 "WEB ALPINE - Cross Session State", cf_text_wp_state},
907 {"wp-columns", 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
908 "WEB ALPINE - Columns", cf_text_wp_columns},
909 {NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,NULL}
913 struct variable *
914 var_from_name(char *name)
916 struct variable *v;
917 int i;
919 if(!(name && name[0]))
920 return(NULL);
922 for(i = 0; (v = &variables[i]) && v->name; i++)
923 if(!strucmp(v->name,name))
924 return(v);
926 return(NULL);
930 void
931 init_init_vars(struct pine *ps)
933 ps->vars = variables;
937 #define DSIZE (25000)
938 /* this is just like dprint except it prints to a char * */
939 #ifdef DEBUG
940 #define mprint(n,x) { \
941 if(debug >= (n)){ \
942 snprintf x ; \
943 db += strlen(db); \
946 #else
947 #define mprint(n,x)
948 #endif
951 * this was split out from init_vars so we can get at the
952 * pinerc location sooner.
954 void
955 init_pinerc(struct pine *ps, char **debug_out)
957 char buf[MAXPATH+1], *p, *db;
958 #if defined(DOS) || defined(OS2)
959 char buf2[MAXPATH+1], l_pinerc[MAXPATH+1];
960 int nopinerc = 0, confregset = -1;
961 register struct variable *vars = ps->vars;
962 #endif
964 #ifdef DEBUG
966 * Since this routine is called before we've had a chance to set up
967 * the debug file for output, we put the debugging into memory and
968 * pass it back to the caller for use after init_debug(). We just
969 * allocate plenty of space.
971 if(debug_out){
972 db = *debug_out = (char *)fs_get(DSIZE * sizeof(char));
973 db[0] = '\0';
975 #endif
977 mprint(2, (db, DSIZE-(db-(*debug_out)), "\n -- init_pinerc --\n\n"));
979 #if defined(DOS) || defined(OS2)
981 * Rules for the config/support file locations under DOS are:
983 * 1) The location of the PINERC is searched for in the following
984 * order of precedence:
985 * - File pointed to by '-p' command line option
986 * - File pointed to by PINERC environment variable
987 * - $HOME\pine
988 * - same dir as argv[0]
990 * 2) The HOME environment variable, if not set, defaults to
991 * root of the current working drive (see alpine.c)
993 * 3) The default for external files (PINE.SIG and ADDRBOOK) is the
994 * same directory as the pinerc
996 * 4) The support files (PINE.HLP and PINE.NDX) are expected to be in
997 * the same directory as PINE.EXE.
1000 if(ps->prc){
1001 mprint(2, (db, DSIZE-(db-(*debug_out)),
1002 "Personal config \"%.100s\" comes from command line\n",
1003 (ps->prc && ps->prc->name) ? ps->prc->name : "<no name>"));
1005 else{
1006 mprint(2, (db, DSIZE-(db-(*debug_out)),
1007 "Personal config not set on cmdline, checking for $PINERC\n"));
1011 * First, if prc hasn't been set by a command-line -p, check to see
1012 * if PINERC is in the environment. If so, treat it just like we
1013 * would have treated it if it were a command-line arg.
1015 if(!ps->prc && (p = getenv("PINERC")) && *p){
1016 char path[MAXPATH], dir[MAXPATH];
1018 if(IS_REMOTE(p) || is_absolute_path(p)){
1019 strncpy(path, p, sizeof(path)-1);
1020 path[sizeof(path)-1] = '\0';
1022 else{
1023 getcwd(dir, sizeof(dir));
1024 build_path(path, dir, p, sizeof(path));
1027 if(!IS_REMOTE(p))
1028 ps->pinerc = cpystr(path);
1030 ps->prc = new_pinerc_s(path);
1032 if(ps->prc){
1033 mprint(2, (db, DSIZE-(db-(*debug_out)),
1034 " yes, personal config \"%.100s\" comes from $PINERC\n",
1035 (ps->prc && ps->prc->name) ? ps->prc->name : "<no name>"));
1040 * Pinerc used to be the name of the pinerc file. Then we added
1041 * the possibility of the pinerc file being remote, and we replaced
1042 * the variable pinerc with the structure prc. Unfortunately, some
1043 * parts of pine rely on the fact that pinerc is the name of the
1044 * pinerc _file_, and use the directory that the pinerc file is located
1045 * in for their own purposes. We want to preserve that so things will
1046 * keep working. So, even if the real pinerc is remote, we need to
1047 * put the name of a pinerc file in the pinerc variable so that the
1048 * directory which contains that file is writable. The file itself
1049 * doesn't have to exist for this purpose, since we are really only
1050 * using the name of the directory containing the file. Twisted.
1051 * (Alternatively, we could fix all of the code that uses the pinerc
1052 * variable for this purpose to use a new variable which really is
1053 * just a directory.) hubert 2000-sep
1055 * There are 3 cases. If pinerc is already set that means that the user
1056 * gave either a -p pinerc or an environment pinerc that is a local file,
1057 * and we are done. If pinerc is not set, then either prc is set or not.
1058 * If prc is set then the -p arg or PINERC value is a remote pinerc.
1059 * In that case we need to find a local directory to use, and put that
1060 * directory in the pinerc variable (with a fake filename tagged on).
1061 * If prc is not set, then user hasn't told us anything so we have to
1062 * try to find the default pinerc file by looking down the path of
1063 * possibilities. When we find it, we'll also use that directory.
1065 if(!ps->pinerc){
1066 *l_pinerc = '\0';
1067 *buf = '\0';
1069 if(ps->prc){ /* remote pinerc case */
1071 * We don't give them an l_pinerc unless they tell us where
1072 * to put it.
1074 if(ps->aux_files_dir)
1075 build_path(l_pinerc, ps->aux_files_dir, SYSTEM_PINERC,
1076 sizeof(l_pinerc));
1077 else{
1079 * Search for a writable directory.
1080 * Mimic what happens in !prc for local case, except we
1081 * don't need to look for the actual file.
1084 /* check if $HOME\PINE is writable */
1085 build_path(buf2, ps->home_dir, DF_PINEDIR, sizeof(buf2));
1086 if(is_writable_dir(buf2) == 0)
1087 build_path(l_pinerc, buf2, SYSTEM_PINERC, sizeof(l_pinerc));
1088 else{ /* $HOME\PINE not a writable dir */
1089 /* use this unless registry redirects us */
1090 build_path(l_pinerc, ps->pine_dir, SYSTEM_PINERC,
1091 sizeof(l_pinerc));
1092 #ifdef _WINDOWS
1093 /* if in registry, use that value */
1094 if(mswin_reg(MSWR_OP_GET, MSWR_PINE_RC, buf2, sizeof(buf2))
1095 && !IS_REMOTE(buf2)){
1096 strncpy(l_pinerc, buf2, sizeof(l_pinerc)-1);
1097 l_pinerc[sizeof(l_pinerc)-1] = '\0';
1099 #endif
1103 else{ /* searching for pinerc file to use */
1105 * Buf2 is $HOME\PINE. If $HOME is not explicitly set,
1106 * it defaults to the current working drive (often C:).
1107 * See alpine.c to see how it is initially set.
1110 mprint(2, (db, DSIZE-(db-(*debug_out)), " no, searching...\n"));
1111 build_path(buf2, ps->home_dir, DF_PINEDIR, sizeof(buf2));
1112 mprint(2, (db, DSIZE-(db-(*debug_out)),
1113 " checking for writable %.100s dir \"%.100s\" off of homedir\n",
1114 DF_PINEDIR, buf2));
1115 if(is_writable_dir(buf2) == 0){
1117 * $HOME\PINE exists and is writable.
1118 * See if $HOME\PINE\PINERC exists.
1120 build_path(buf, buf2, SYSTEM_PINERC, sizeof(buf));
1121 strncpy(l_pinerc, buf, sizeof(l_pinerc)-1);
1122 l_pinerc[sizeof(l_pinerc)-1] = '\0';
1123 mprint(2, (db, DSIZE-(db-(*debug_out)), " yes, now checking for file \"%.100s\"\n",
1124 buf));
1125 if(can_access(buf, ACCESS_EXISTS) == 0){ /* found it! */
1127 * Buf is what we were looking for.
1128 * It is local and can be used for the directory, too.
1130 mprint(2, (db, DSIZE-(db-(*debug_out)), " found it\n"));
1132 else{
1134 * No $HOME\PINE\PINERC, look for
1135 * one in same dir as PINE.EXE.
1137 build_path(buf2, ps->pine_dir, SYSTEM_PINERC,
1138 sizeof(buf2));
1139 mprint(2, (db, DSIZE-(db-(*debug_out)),
1140 " no, checking for \"%.100s\" in pine.exe dir\n",
1141 buf2));
1142 if(can_access(buf2, ACCESS_EXISTS) == 0){
1143 /* found it! */
1144 mprint(2, (db, DSIZE-(db-(*debug_out)), " found it\n"));
1145 strncpy(buf, buf2, sizeof(buf)-1);
1146 buf[sizeof(buf)-1] = '\0';
1147 strncpy(l_pinerc, buf2, sizeof(l_pinerc)-1);
1148 l_pinerc[sizeof(l_pinerc)-1] = '\0';
1150 else{
1151 #ifdef _WINDOWS
1152 mprint(2, (db, DSIZE-(db-(*debug_out)), " no, checking in registry\n"));
1153 if(mswin_reg(MSWR_OP_GET, MSWR_PINE_RC,
1154 buf2, sizeof(buf2))){
1155 strncpy(buf, buf2, sizeof(buf)-1);
1156 buf[sizeof(buf)-1] = '\0';
1157 if(!IS_REMOTE(buf2)){
1158 strncpy(l_pinerc, buf2, sizeof(l_pinerc)-1);
1159 l_pinerc[sizeof(l_pinerc)-1] = '\0';
1162 * Now buf is the pinerc to be used, l_pinerc is
1163 * the directory, which may be either same as buf
1164 * or it may be $HOME\PINE if registry gives us
1165 * a remote pinerc.
1167 mprint(2, (db, DSIZE-(db-(*debug_out)), " found \"%.100s\" in registry\n",
1168 buf));
1170 else{
1171 nopinerc = 1;
1172 mprint(2, (db, DSIZE-(db-(*debug_out)), " not found, asking user\n"));
1174 #else
1175 mprint(2, (db, DSIZE-(db-(*debug_out)), " not found\n"));
1176 #endif
1181 * Buf is the pinerc (could be remote if from registry)
1182 * and l_pinerc is the local pinerc, which may not exist.
1185 else{ /* $HOME\PINE not a writable dir */
1187 * We notice that the order of checking in the registry
1188 * and checking in the ALPINE.EXE directory are different
1189 * in this case versus the is_writable_dir(buf2) case, and
1190 * that does sort of look like a bug. However,
1191 * we don't think this is a bug since we did it on purpose
1192 * a long time ago. So even though we can't remember why
1193 * it is this way, we think we would rediscover why if we
1194 * changed it! So we won't change it.
1198 * Change the default to use to the ALPINE.EXE directory.
1200 build_path(buf, ps->pine_dir, SYSTEM_PINERC, sizeof(buf));
1201 strncpy(l_pinerc, buf, sizeof(l_pinerc)-1);
1202 l_pinerc[sizeof(l_pinerc)-1] = '\0';
1203 #ifdef _WINDOWS
1204 mprint(2, (db, DSIZE-(db-(*debug_out)), " no, not writable, checking in registry\n"));
1205 /* if in registry, use that value */
1206 if(mswin_reg(MSWR_OP_GET, MSWR_PINE_RC, buf2, sizeof(buf2))){
1207 strncpy(buf, buf2, sizeof(buf)-1);
1208 buf[sizeof(buf)-1] = '\0';
1209 mprint(2, (db, DSIZE-(db-(*debug_out)), " found \"%.100s\" in registry\n",
1210 buf));
1211 if(!IS_REMOTE(buf)){
1212 strncpy(l_pinerc, buf, sizeof(l_pinerc)-1);
1213 l_pinerc[sizeof(l_pinerc)-1] = '\0';
1216 else{
1217 mprint(2, (db, DSIZE-(db-(*debug_out)),
1218 " no, checking for \"%.100s\" in alpine.exe dir\n",
1219 buf));
1221 if(can_access(buf, ACCESS_EXISTS) == 0){
1222 mprint(2, (db, DSIZE-(db-(*debug_out)), " found it\n"));
1224 else{
1225 nopinerc = 1;
1226 mprint(2, (db, DSIZE-(db-(*debug_out)), " not found, asking user\n"));
1229 #else
1230 mprint(2, (db, DSIZE-(db-(*debug_out)),
1231 " no, checking for \"%.100s\" in alpine.exe dir\n",
1232 buf));
1234 if(can_access(buf, ACCESS_EXISTS) == 0){
1235 mprint(2, (db, DSIZE-(db-(*debug_out)), " found it\n"));
1237 else{
1238 mprint(2, (db, DSIZE-(db-(*debug_out)), " not found, creating it\n"));
1240 #endif
1244 * When we get here we have buf set to the name of the
1245 * pinerc, which could be local or remote. We have l_pinerc
1246 * set to the same as buf if buf is local, and set to another
1247 * name otherwise, hopefully contained in a writable directory.
1249 #ifdef _WINDOWS
1250 if(nopinerc || ps_global->install_flag){
1251 char buf3[MAXPATH+1];
1253 confregset = 0;
1254 strncpy(buf3, buf, MAXPATH);
1255 buf3[MAXPATH] = '\0';
1256 if(os_config_dialog(buf3, MAXPATH,
1257 &confregset, nopinerc) == 0){
1258 strncpy(buf, buf3, MAXPATH);
1259 buf[MAXPATH] = '\0';
1260 mprint(2, (db, DSIZE-(db-(*debug_out)), " not found, creating it\n"));
1261 mprint(2, (db, DSIZE-(db-(*debug_out)), " user says use \"%.100s\"\n", buf));
1262 if(!IS_REMOTE(buf)){
1263 strncpy(l_pinerc, buf, MAXPATH);
1264 l_pinerc[MAXPATH] = '\0';
1267 else{
1268 exit(-1);
1271 #endif
1272 ps->prc = new_pinerc_s(buf);
1275 ps->pinerc = cpystr(l_pinerc);
1278 #if defined(DOS) || defined(OS2)
1280 * The goal here is to set the auxiliary directory in the pinerc variable.
1281 * We are making the assumption that any reference to the pinerc variable
1282 * after this point is used only as a directory in which to store things,
1283 * with the prc variable being the preferred place to store pinerc location.
1284 * If -aux isn't set, then there is no change. -jpf 08/2001
1286 if(ps->aux_files_dir){
1287 l_pinerc[0] = '\0';
1288 build_path(l_pinerc, ps->aux_files_dir, SYSTEM_PINERC,
1289 sizeof(l_pinerc));
1290 if(ps->pinerc) fs_give((void **)&ps->pinerc);
1291 ps->pinerc = cpystr(l_pinerc);
1292 mprint(2, (db, DSIZE-(db-(*debug_out)), "Setting aux_files_dir to \"%.100s\"\n",
1293 ps->aux_files_dir));
1295 #endif
1297 #ifdef _WINDOWS
1298 if(confregset && (ps->update_registry != UREG_NEVER_SET))
1299 mswin_reg(MSWR_OP_SET | ((ps->update_registry == UREG_ALWAYS_SET)
1300 || confregset == 1 ? MSWR_OP_FORCE : 0),
1301 MSWR_PINE_RC,
1302 (ps->prc && ps->prc->name) ?
1303 ps->prc->name : ps->pinerc, (size_t)NULL);
1304 #endif
1307 * Now that we know the default for the PINERC, build NEWSRC default.
1308 * Backward compatibility makes this kind of funky. If what the
1309 * c-client thinks the NEWSRC should be exists *AND* it doesn't
1310 * already exist in the PINERC's dir, use c-client's default, otherwise
1311 * use the one next to the PINERC...
1313 p = last_cmpnt(ps->pinerc);
1314 buf[0] = '\0';
1315 if(p != NULL){
1316 strncpy(buf, ps->pinerc, MIN(p - ps->pinerc, sizeof(buf)-1));
1317 buf[MIN(p - ps->pinerc, sizeof(buf)-1)] = '\0';
1320 mprint(2, (db, DSIZE-(db-(*debug_out)), "Using directory \"%.100s\" for auxiliary files\n", buf));
1321 strncat(buf, "NEWSRC", sizeof(buf)-1-strlen(buf));
1323 if(!(p = (void *) mail_parameters(NULL, GET_NEWSRC, (void *)NULL))
1324 || can_access(p, ACCESS_EXISTS) < 0
1325 || can_access(buf, ACCESS_EXISTS) == 0){
1326 mail_parameters(NULL, SET_NEWSRC, (void *)buf);
1327 GLO_NEWSRC_PATH = cpystr(buf);
1329 else
1330 GLO_NEWSRC_PATH = cpystr(p);
1332 if(ps->pconf){
1333 mprint(2, (db, DSIZE-(db-(*debug_out)), "Global config \"%.100s\" comes from command line\n",
1334 (ps->pconf && ps->pconf->name) ? ps->pconf->name : "<no name>"));
1336 else{
1337 mprint(2, (db, DSIZE-(db-(*debug_out)),
1338 "Global config not set on cmdline, checking for $PINECONF\n"));
1341 if(!ps->pconf && (p = getenv("PINECONF"))){
1342 ps->pconf = new_pinerc_s(p);
1343 if(ps->pconf){
1344 mprint(2, (db, DSIZE-(db-(*debug_out)),
1345 " yes, global config \"%.100s\" comes from $PINECONF\n",
1346 (ps->pconf && ps->pconf->name) ? ps->pconf->name : "<no name>"));
1349 #ifdef _WINDOWS
1350 else if(!ps->pconf
1351 && mswin_reg(MSWR_OP_GET, MSWR_PINE_CONF, buf2, sizeof(buf2))){
1352 ps->pconf = new_pinerc_s(buf2);
1353 if(ps->pconf){
1354 mprint(2, (db, DSIZE-(db-(*debug_out)),
1355 " yes, global config \"%.100s\" comes from Registry\n",
1356 (ps->pconf && ps->pconf->name) ? ps->pconf->name : "<no name>"));
1359 #endif
1360 if(!ps->pconf){
1361 mprint(2, (db, DSIZE-(db-(*debug_out)), " no, there is no global config\n"));
1363 #ifdef _WINDOWS
1364 else if (ps->pconf && ps->pconf->name &&
1365 (ps->update_registry != UREG_NEVER_SET)){
1366 mswin_reg(MSWR_OP_SET | ((ps->update_registry == UREG_ALWAYS_SET)
1367 ? MSWR_OP_FORCE : 0),
1368 MSWR_PINE_CONF,
1369 ps->pconf->name, (size_t)NULL);
1371 #endif
1373 if(!ps->prc)
1374 ps->prc = new_pinerc_s(ps->pinerc);
1376 if(ps->exceptions){
1377 mprint(2, (db, DSIZE-(db-(*debug_out)),
1378 "Exceptions config \"%.100s\" comes from command line\n",
1379 ps->exceptions));
1381 else{
1382 mprint(2, (db, DSIZE-(db-(*debug_out)),
1383 "Exceptions config not set on cmdline, checking for $PINERCEX\n"));
1387 * Exceptions is done slightly differently from pinerc. Instead of setting
1388 * post_prc in args.c we just set the string and use it here. We do
1389 * that so that we can put it in the same directory as the pinerc if
1390 * exceptions is a relative name, and pinerc may not be set until here.
1392 * First, just like for pinerc, check environment variable if it wasn't
1393 * set on the command line.
1395 if(!ps->exceptions && (p = getenv("PINERCEX")) && *p){
1396 ps->exceptions = cpystr(p);
1397 if(ps->exceptions){
1398 mprint(2, (db, DSIZE-(db-(*debug_out)),
1399 " yes, exceptions config \"%.100s\" comes from $PINERCEX\n",
1400 ps->exceptions));
1405 * If still not set, try specific file in same dir as pinerc.
1406 * Only use it if the file exists.
1408 if(!ps->exceptions){
1409 p = last_cmpnt(ps->pinerc);
1410 buf[0] = '\0';
1411 if(p != NULL){
1412 strncpy(buf, ps->pinerc, MIN(p - ps->pinerc, sizeof(buf)-1));
1413 buf[MIN(p - ps->pinerc, sizeof(buf)-1)] = '\0';
1416 strncat(buf, "PINERCEX", sizeof(buf)-1-strlen(buf));
1418 mprint(2, (db, DSIZE-(db-(*debug_out)),
1419 " no, checking for default \"%.100s\" in pinerc dir\n", buf));
1420 if(can_access(buf, ACCESS_EXISTS) == 0) /* found it! */
1421 ps->exceptions = cpystr(buf);
1423 if(ps->exceptions){
1424 mprint(2, (db, DSIZE-(db-(*debug_out)),
1425 " yes, exceptions config \"%.100s\" comes from default\n",
1426 ps->exceptions));
1428 else{
1429 mprint(2, (db, DSIZE-(db-(*debug_out)), " no, there is no exceptions config\n"));
1433 #else /* unix */
1435 if(ps->pconf){
1436 mprint(2, (db, DSIZE-(db-(*debug_out)), "Global config \"%.100s\" comes from command line\n",
1437 (ps->pconf && ps->pconf->name) ? ps->pconf->name : "<no name>"));
1440 if(!ps->pconf){
1441 ps->pconf = new_pinerc_s(SYSTEM_PINERC);
1442 if(ps->pconf){
1443 mprint(2, (db, DSIZE-(db-(*debug_out)), "Global config \"%.100s\" is default\n",
1444 (ps->pconf && ps->pconf->name) ? ps->pconf->name : "<no name>"));
1448 if(!ps->pconf){
1449 mprint(2, (db, DSIZE-(db-(*debug_out)), "No global config!\n"));
1452 if(ps->prc){
1453 mprint(2, (db, DSIZE-(db-(*debug_out)), "Personal config \"%.100s\" comes from command line\n",
1454 (ps->prc && ps->prc->name) ? ps->prc->name : "<no name>"));
1457 if(!ps->pinerc){
1458 build_path(buf, ps->home_dir, ".pinerc", sizeof(buf));
1459 ps->pinerc = cpystr(buf);
1462 if(!ps->prc){
1463 ps->prc = new_pinerc_s(ps->pinerc);
1464 if(ps->prc){
1465 mprint(2, (db, DSIZE-(db-(*debug_out)), "Personal config \"%.100s\" is default\n",
1466 (ps->prc && ps->prc->name) ? ps->prc->name : "<no name>"));
1470 if(!ps->prc){
1471 mprint(2, (db, DSIZE-(db-(*debug_out)), "No personal config!\n"));
1474 if(ps->exceptions){
1475 mprint(2, (db, DSIZE-(db-(*debug_out)),
1476 "Exceptions config \"%.100s\" comes from command line\n",
1477 ps->exceptions));
1481 * If not set, try specific file in same dir as pinerc.
1482 * Only use it if the file exists.
1484 if(!ps->exceptions){
1485 p = last_cmpnt(ps->pinerc);
1486 buf[0] = '\0';
1487 if(p != NULL){
1488 strncpy(buf, ps->pinerc, MIN(p - ps->pinerc, sizeof(buf)-1));
1489 buf[MIN(p - ps->pinerc, sizeof(buf)-1)] = '\0';
1492 strncat(buf, ".pinercex", sizeof(buf)-1-strlen(buf));
1493 mprint(2, (db, DSIZE-(db-(*debug_out)), "Exceptions config not set on cmdline\n checking for default \"%.100s\" in pinerc dir\n", buf));
1495 if(can_access(buf, ACCESS_EXISTS) == 0) /* found it! */
1496 ps->exceptions = cpystr(buf);
1498 if(ps->exceptions){
1499 mprint(2, (db, DSIZE-(db-(*debug_out)),
1500 " yes, exceptions config \"%.100s\" is default\n",
1501 ps->exceptions));
1503 else{
1504 mprint(2, (db, DSIZE-(db-(*debug_out)), " no, there is no exceptions config\n"));
1508 #endif /* unix */
1510 if(ps->exceptions){
1512 if(!IS_REMOTE(ps->exceptions) &&
1513 !is_absolute_path(ps->exceptions)){
1514 #if defined(DOS) || defined(OS2)
1515 p = last_cmpnt(ps->pinerc);
1516 buf[0] = '\0';
1517 if(p != NULL){
1518 strncpy(buf, ps->pinerc, MIN(p - ps->pinerc, sizeof(buf)-1));
1519 buf[MIN(p - ps->pinerc, sizeof(buf)-1)] = '\0';
1522 strncat(buf, ps->exceptions, sizeof(buf)-1-strlen(buf));
1523 #else
1524 build_path(buf, ps->home_dir, ps->exceptions, sizeof(buf));
1525 #endif
1527 else{
1528 strncpy(buf, ps->exceptions, sizeof(buf)-1);
1529 buf[sizeof(buf)-1] = '\0';
1532 ps->post_prc = new_pinerc_s(buf);
1534 fs_give((void **)&ps->exceptions);
1537 mprint(2, (db, DSIZE-(db-(*debug_out)), "\n Global config: %.100s\n",
1538 (ps->pconf && ps->pconf->name) ? ps->pconf->name : "<none>"));
1539 mprint(2, (db, DSIZE-(db-(*debug_out)), " Personal config: %.100s\n",
1540 (ps->prc && ps->prc->name) ? ps->prc->name : "<none>"));
1541 mprint(2, (db, DSIZE-(db-(*debug_out)), " Exceptions config: %.100s\n",
1542 (ps->post_prc && ps->post_prc->name) ? ps->post_prc->name
1543 : "<none>"));
1544 #if !defined(DOS) && !defined(OS2)
1545 if(SYSTEM_PINERC_FIXED){
1546 mprint(2, (db, DSIZE-(db-(*debug_out)), " Fixed config: %.100s\n", SYSTEM_PINERC_FIXED));
1548 #endif
1550 mprint(2, (db, DSIZE-(db-(*debug_out)), "\n"));
1554 /*----------------------------------------------------------------------
1555 Initialize the variables
1557 Args: ps -- The usual pine structure
1559 Result:
1561 This reads the system pine configuration file and the user's pine
1562 configuration file ".pinerc" and places the results in the variables
1563 structure. It sorts out what was read and sets a few other variables
1564 based on the contents.
1565 ----*/
1566 void
1567 init_vars(struct pine *ps, void (*cmds_f) (struct pine *, char **))
1569 char buf[MAXPATH+1], *p, *q, **s;
1570 register struct variable *vars = ps->vars;
1571 int obs_header_in_reply = 0, /* the obs_ variables are to */
1572 obs_old_style_reply = 0, /* support backwards compatibility */
1573 obs_save_by_sender, i, def_sort_rev;
1574 long rvl;
1575 PINERC_S *fixedprc = NULL;
1576 FeatureLevel obs_feature_level;
1577 char *fromcharset = NULL;
1578 char *err = NULL;
1580 dprint((5, "init_vars:\n"));
1582 /*--- The defaults here are defined in os-xxx.h so they can vary
1583 per machine ---*/
1585 GLO_PRINTER = cpystr(DF_DEFAULT_PRINTER);
1586 GLO_ELM_STYLE_SAVE = cpystr(DF_ELM_STYLE_SAVE);
1587 GLO_SAVE_BY_SENDER = cpystr(DF_SAVE_BY_SENDER);
1588 GLO_HEADER_IN_REPLY = cpystr(DF_HEADER_IN_REPLY);
1589 GLO_INBOX_PATH = cpystr("inbox");
1590 GLO_DEFAULT_FCC = cpystr(DF_DEFAULT_FCC);
1591 GLO_DEFAULT_SAVE_FOLDER = cpystr(DEFAULT_SAVE);
1592 GLO_POSTPONED_FOLDER = cpystr(POSTPONED_MSGS);
1593 GLO_TRASH_FOLDER = cpystr(TRASH_FOLDER);
1594 GLO_USE_ONLY_DOMAIN_NAME = cpystr(DF_USE_ONLY_DOMAIN_NAME);
1595 GLO_FEATURE_LEVEL = cpystr("sappling");
1596 GLO_OLD_STYLE_REPLY = cpystr(DF_OLD_STYLE_REPLY);
1597 GLO_SORT_KEY = cpystr(DF_SORT_KEY);
1598 GLO_SAVED_MSG_NAME_RULE = cpystr(DF_SAVED_MSG_NAME_RULE);
1599 GLO_FCC_RULE = cpystr(DF_FCC_RULE);
1600 GLO_AB_SORT_RULE = cpystr(DF_AB_SORT_RULE);
1601 GLO_FLD_SORT_RULE = cpystr(DF_FLD_SORT_RULE);
1602 GLO_SIGNATURE_FILE = cpystr(DF_SIGNATURE_FILE);
1603 GLO_MAIL_DIRECTORY = cpystr(DF_MAIL_DIRECTORY);
1604 GLO_REMOTE_ABOOK_HISTORY = cpystr(DF_REMOTE_ABOOK_HISTORY);
1605 GLO_REMOTE_ABOOK_VALIDITY = cpystr(DF_REMOTE_ABOOK_VALIDITY);
1606 GLO_GOTO_DEFAULT_RULE = cpystr(DF_GOTO_DEFAULT_RULE);
1607 GLO_INCOMING_STARTUP = cpystr(DF_INCOMING_STARTUP);
1608 GLO_PRUNING_RULE = cpystr(DF_PRUNING_RULE);
1609 GLO_REOPEN_RULE = cpystr(DF_REOPEN_RULE);
1610 GLO_THREAD_DISP_STYLE = cpystr(DF_THREAD_DISP_STYLE);
1611 GLO_THREAD_INDEX_STYLE = cpystr(DF_THREAD_INDEX_STYLE);
1612 GLO_THREAD_MORE_CHAR = cpystr(DF_THREAD_MORE_CHAR);
1613 GLO_THREAD_EXP_CHAR = cpystr(DF_THREAD_EXP_CHAR);
1614 GLO_THREAD_LASTREPLY_CHAR = cpystr(DF_THREAD_LASTREPLY_CHAR);
1615 GLO_BUGS_FULLNAME = cpystr("Sorry No Address");
1616 GLO_BUGS_ADDRESS = cpystr("nobody");
1617 GLO_SUGGEST_FULLNAME = cpystr("Sorry No Address");
1618 GLO_SUGGEST_ADDRESS = cpystr("nobody");
1619 GLO_LOCAL_FULLNAME = cpystr(DF_LOCAL_FULLNAME);
1620 GLO_LOCAL_ADDRESS = cpystr(DF_LOCAL_ADDRESS);
1621 GLO_OVERLAP = cpystr(DF_OVERLAP);
1622 GLO_SLEEP = cpystr("60");
1623 GLO_MAXREMSTREAM = cpystr(DF_MAXREMSTREAM);
1624 GLO_MARGIN = cpystr(DF_MARGIN);
1625 GLO_FILLCOL = cpystr(DF_FILLCOL);
1626 GLO_DEADLETS = cpystr(DF_DEADLETS);
1627 GLO_NMW_WIDTH = cpystr(DF_NMW_WIDTH);
1628 GLO_REPLY_STRING = cpystr("> ");
1629 GLO_REPLY_INTRO = cpystr(DEFAULT_REPLY_INTRO);
1630 GLO_EMPTY_HDR_MSG = cpystr("undisclosed-recipients");
1631 GLO_STATUS_MSG_DELAY = cpystr("0");
1632 GLO_ACTIVE_MSG_INTERVAL = cpystr("12");
1633 GLO_USERINPUTTIMEO = cpystr("0");
1634 GLO_INCCHECKTIMEO = cpystr("5");
1635 GLO_INCCHECKINTERVAL = cpystr("180");
1636 GLO_INC2NDCHECKINTERVAL = cpystr("180");
1637 GLO_MAILCHECK = cpystr(DF_MAILCHECK);
1638 GLO_MAILCHECKNONCURR = cpystr("0");
1639 GLO_MAILDROPCHECK = cpystr(DF_MAILDROPCHECK);
1640 GLO_NNTPRANGE = cpystr("0");
1641 GLO_KBLOCK_PASSWD_COUNT = cpystr(DF_KBLOCK_PASSWD_COUNT);
1642 GLO_INDEX_COLOR_STYLE = cpystr("flip-colors");
1643 GLO_TITLEBAR_COLOR_STYLE = cpystr("default");
1644 GLO_POST_CHAR_SET = cpystr("UTF-8");
1645 #ifdef DF_FOLDER_EXTENSION
1646 GLO_FOLDER_EXTENSION = cpystr(DF_FOLDER_EXTENSION);
1647 #endif
1648 #ifdef DF_SMTP_SERVER
1649 GLO_SMTP_SERVER = parse_list(DF_SMTP_SERVER, 1,
1650 PL_REMSURRQUOT, NULL);
1651 #endif
1653 #ifdef DF_SSHPATH
1654 GLO_SSHPATH = cpystr(DF_SSHPATH);
1655 #endif
1656 #ifdef DF_SSHCMD
1657 GLO_SSHCMD = cpystr(DF_SSHCMD);
1658 #endif
1660 #ifndef _WINDOWS
1661 GLO_COLOR_STYLE = cpystr("no-color");
1662 GLO_NORM_FORE_COLOR = cpystr(DEFAULT_NORM_FORE_RGB);
1663 GLO_NORM_BACK_COLOR = cpystr(DEFAULT_NORM_BACK_RGB);
1664 #endif
1665 GLO_TITLE_FORE_COLOR = cpystr(DEFAULT_TITLE_FORE_RGB);
1666 GLO_TITLE_BACK_COLOR = cpystr(DEFAULT_TITLE_BACK_RGB);
1667 GLO_TITLECLOSED_FORE_COLOR = cpystr(DEFAULT_TITLECLOSED_FORE_RGB);
1668 GLO_TITLECLOSED_BACK_COLOR = cpystr(DEFAULT_TITLECLOSED_BACK_RGB);
1669 GLO_FOLDER_FORE_COLOR = cpystr(DEFAULT_NORM_FORE_RGB);
1670 GLO_DIRECTORY_FORE_COLOR = cpystr(DEFAULT_NORM_FORE_RGB);
1671 GLO_FOLDER_LIST_FORE_COLOR = cpystr(DEFAULT_NORM_FORE_RGB);
1672 GLO_METAMSG_FORE_COLOR = cpystr(DEFAULT_METAMSG_FORE_RGB);
1673 GLO_METAMSG_BACK_COLOR = cpystr(DEFAULT_METAMSG_BACK_RGB);
1674 GLO_QUOTE1_FORE_COLOR = cpystr(DEFAULT_QUOTE1_FORE_RGB);
1675 GLO_QUOTE1_BACK_COLOR = cpystr(DEFAULT_QUOTE1_BACK_RGB);
1676 GLO_QUOTE2_FORE_COLOR = cpystr(DEFAULT_QUOTE2_FORE_RGB);
1677 GLO_QUOTE2_BACK_COLOR = cpystr(DEFAULT_QUOTE2_BACK_RGB);
1678 GLO_QUOTE3_FORE_COLOR = cpystr(DEFAULT_QUOTE3_FORE_RGB);
1679 GLO_QUOTE3_BACK_COLOR = cpystr(DEFAULT_QUOTE3_BACK_RGB);
1680 GLO_SIGNATURE_FORE_COLOR = cpystr(DEFAULT_SIGNATURE_FORE_RGB);
1681 GLO_SIGNATURE_BACK_COLOR = cpystr(DEFAULT_SIGNATURE_BACK_RGB);
1682 GLO_IND_PLUS_FORE_COLOR = cpystr(DEFAULT_IND_PLUS_FORE_RGB);
1683 GLO_IND_PLUS_BACK_COLOR = cpystr(DEFAULT_IND_PLUS_BACK_RGB);
1684 GLO_IND_IMP_FORE_COLOR = cpystr(DEFAULT_IND_IMP_FORE_RGB);
1685 GLO_IND_IMP_BACK_COLOR = cpystr(DEFAULT_IND_IMP_BACK_RGB);
1686 GLO_IND_ANS_FORE_COLOR = cpystr(DEFAULT_IND_ANS_FORE_RGB);
1687 GLO_IND_ANS_BACK_COLOR = cpystr(DEFAULT_IND_ANS_BACK_RGB);
1688 GLO_IND_NEW_FORE_COLOR = cpystr(DEFAULT_IND_NEW_FORE_RGB);
1689 GLO_IND_NEW_BACK_COLOR = cpystr(DEFAULT_IND_NEW_BACK_RGB);
1690 GLO_IND_OP_FORE_COLOR = cpystr(DEFAULT_IND_OP_FORE_RGB);
1691 GLO_IND_OP_BACK_COLOR = cpystr(DEFAULT_IND_OP_BACK_RGB);
1692 GLO_VIEW_MARGIN_LEFT = cpystr("0");
1693 GLO_VIEW_MARGIN_RIGHT = cpystr(DF_VIEW_MARGIN_RIGHT);
1694 GLO_QUOTE_SUPPRESSION = cpystr(DF_QUOTE_SUPPRESSION);
1695 GLO_KW_BRACES = cpystr("\"{\" \"} \"");
1696 GLO_OPENING_SEP = cpystr(" - ");
1697 GLO_WP_INDEXHEIGHT = cpystr("24");
1698 GLO_WP_AGGSTATE = cpystr("1");
1699 GLO_WP_STATE = cpystr("");
1700 #ifdef DF_VAR_SPELLER
1701 GLO_SPELLER = cpystr(DF_VAR_SPELLER);
1702 #endif
1703 #ifdef SMIME
1704 if(ps->smimedir){
1705 snprintf(tmp_20k_buf, SIZEOF_20KBUF, "%s/public", ps->smimedir);
1706 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1707 GLO_PUBLICCERT_DIR = cpystr(tmp_20k_buf);
1709 snprintf(tmp_20k_buf, SIZEOF_20KBUF, "%s/private", ps->smimedir);
1710 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1711 GLO_PRIVATEKEY_DIR = cpystr(tmp_20k_buf);
1713 snprintf(tmp_20k_buf, SIZEOF_20KBUF, "%s/ca", ps->smimedir);
1714 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1715 GLO_CACERT_DIR = cpystr(tmp_20k_buf);
1717 else{
1718 GLO_PUBLICCERT_DIR = cpystr(DF_PUBLICCERT_DIR);
1719 GLO_PRIVATEKEY_DIR = cpystr(DF_PRIVATEKEY_DIR);
1720 GLO_CACERT_DIR = cpystr(DF_CACERT_DIR);
1722 #endif /* SMIME */
1725 * Default first value for addrbook list if none set.
1726 * We also want to be sure to set global_val to the default
1727 * if is_fixed, so that address-book= will cause the default to happen.
1729 if(!GLO_ADDRESSBOOK && !FIX_ADDRESSBOOK)
1730 GLO_ADDRESSBOOK = parse_list(DF_ADDRESSBOOK, 1, 0, NULL);
1733 * Default first value if none set.
1735 if(!GLO_STANDARD_PRINTER && !FIX_STANDARD_PRINTER)
1736 GLO_STANDARD_PRINTER = parse_list(DF_STANDARD_PRINTER, 1, 0, NULL);
1739 * Defining this default sshpath should cause ssh to be preferred over rsh
1740 * when attempting imapd preauth calls.
1742 #ifdef DF_SSHPATH
1743 if(DF_SSHPATH
1744 && is_absolute_path(DF_SSHPATH)
1745 && can_access(DF_SSHPATH, EXECUTE_ACCESS) == 0){
1746 mail_parameters(NULL, SET_SSHPATH, (void *) DF_SSHPATH);
1748 #endif
1750 * It isn't usually necessary to define this.
1752 #ifdef DF_SSHCMD
1753 if(DF_SSHCMD){
1754 mail_parameters(NULL, SET_SSHCOMMAND, (void *) DF_SSHCMD);
1756 #endif
1758 #if !defined(DOS) && !defined(OS2)
1760 * This is here instead of in init_pinerc so that we can get by without
1761 * having a global fixedprc, since we don't need it anymore after this.
1763 fixedprc = new_pinerc_s(SYSTEM_PINERC_FIXED);
1764 #endif
1766 if(ps->pconf){
1767 read_pinerc(ps->pconf, vars, ParseGlobal);
1768 if(ps->pconf->type != Loc)
1769 rd_close_remote(ps->pconf->rd);
1772 if(ps->prc){
1773 read_pinerc(ps->prc, vars, ParsePers);
1774 if(ps->prc->type != Loc)
1775 rd_close_remote(ps->prc->rd);
1778 if(ps->post_prc){
1779 read_pinerc(ps->post_prc, vars, ParsePersPost);
1780 if(ps->post_prc->type != Loc)
1781 rd_close_remote(ps->post_prc->rd);
1784 if(fixedprc){
1785 read_pinerc(fixedprc, vars, ParseFixed);
1786 free_pinerc_s(&fixedprc);
1789 ps->ew_for_except_vars = ps->post_prc ? Post : Main;
1791 if(ps->exit_if_no_pinerc && ps->first_time_user){
1793 /* TRANSLATORS: -bail is a literal option name, don't change it. */
1794 exceptional_exit(_("Exiting because -bail option is set and config file doesn't exist."), -1);
1798 * Convert everything having to do with the config to UTF-8
1799 * in order to avoid having to worry about it all over the
1800 * place.
1801 * Set the character-set first so that we may use that in
1802 * the conversion process.
1804 set_collation(0, 1);
1806 #ifndef _WINDOWS
1807 #if (HAVE_LANGINFO_H && defined(CODESET))
1809 if(output_charset_is_supported(nl_langinfo_codeset_wrapper()))
1810 ps->GLO_CHAR_SET = cpystr(nl_langinfo_codeset_wrapper());
1811 else{
1812 ps->GLO_CHAR_SET = cpystr("UTF-8");
1813 dprint((1,"nl_langinfo(CODESET) returns unrecognized value=\"%s\", using UTF-8 as default\n", (p=nl_langinfo(CODESET)) ? p : ""));
1815 #else
1816 ps->GLO_CHAR_SET = cpystr("UTF-8");
1817 #endif
1819 set_current_val(&vars[V_CHAR_SET], TRUE, TRUE);
1820 set_current_val(&vars[V_OLD_CHAR_SET], TRUE, TRUE);
1821 set_current_val(&vars[V_KEY_CHAR_SET], TRUE, TRUE);
1822 #endif /* ! _WINDOWS */
1824 set_current_val(&vars[V_POST_CHAR_SET], TRUE, TRUE);
1827 * Also set up the feature list because we need the
1828 * Use-System-Translation feature to set up the charmaps.
1831 /* way obsolete, backwards compatibility */
1832 set_current_val(&vars[V_FEATURE_LEVEL], TRUE, TRUE);
1833 if(strucmp(VAR_FEATURE_LEVEL, "seedling") == 0)
1834 obs_feature_level = Seedling;
1835 else if(strucmp(VAR_FEATURE_LEVEL, "old-growth") == 0)
1836 obs_feature_level = Seasoned;
1837 else
1838 obs_feature_level = Sapling;
1840 /* obsolete, backwards compatibility */
1841 set_current_val(&vars[V_OLD_STYLE_REPLY], TRUE, TRUE);
1842 obs_old_style_reply = !strucmp(VAR_OLD_STYLE_REPLY, "yes");
1844 set_feature_list_current_val(&vars[V_FEATURE_LIST]);
1845 process_feature_list(ps, VAR_FEATURE_LIST,
1846 (obs_feature_level == Seasoned) ? 1 : 0,
1847 obs_header_in_reply, obs_old_style_reply);
1851 * Redo set_collation call with correct value for collation,
1852 * but we're hardwiring ctype on now. That's because nl_langinfo()
1853 * call needs it and system-dependent wcwidth and wcrtomb functions
1854 * need it.
1856 set_collation(F_OFF(F_DISABLE_SETLOCALE_COLLATE, ps_global), 1);
1859 * Set up to send the correct sequence of bytes to the display terminal.
1862 if(reset_character_set_stuff(&err) == -1)
1863 alpine_panic(err ? err : "trouble with character set setup");
1864 else if(err){
1865 init_error(ps, SM_ORDER | SM_DING, 3, 5, err);
1866 fs_give((void **) &err);
1870 * Now we use the configvars from above to convert the rest
1871 * to UTF-8. That should be ok because the ones above should
1872 * be ASCII.
1874 if(ps->keyboard_charmap && strucmp(ps->keyboard_charmap, "UTF-8")
1875 && strucmp(ps->keyboard_charmap, "US-ASCII"))
1876 fromcharset = ps->keyboard_charmap;
1877 else if(ps->display_charmap && strucmp(ps->display_charmap, "UTF-8")
1878 && strucmp(ps->display_charmap, "US-ASCII"))
1879 fromcharset = ps->display_charmap;
1880 #ifndef _WINDOWS
1881 else if(VAR_OLD_CHAR_SET && strucmp(VAR_OLD_CHAR_SET, "UTF-8")
1882 && strucmp(VAR_OLD_CHAR_SET, "US-ASCII"))
1883 fromcharset = VAR_OLD_CHAR_SET;
1884 #endif /* ! _WINDOWS */
1886 convert_configvars_to_utf8(vars, fromcharset);
1889 * If we already set this while reading the remote pinerc, don't
1890 * change it.
1892 if(!VAR_REMOTE_ABOOK_METADATA || !VAR_REMOTE_ABOOK_METADATA[0])
1893 set_current_val(&vars[V_REMOTE_ABOOK_METADATA], TRUE, TRUE);
1896 * mail-directory variable is obsolete, put its value in
1897 * default folder-collection list
1899 set_current_val(&vars[V_MAIL_DIRECTORY], TRUE, TRUE);
1900 if(!GLO_FOLDER_SPEC){
1901 build_path(tmp_20k_buf, VAR_MAIL_DIRECTORY, "[]", SIZEOF_20KBUF);
1902 GLO_FOLDER_SPEC = parse_list(tmp_20k_buf, 1, 0, NULL);
1905 set_current_val(&vars[V_FOLDER_SPEC], TRUE, TRUE);
1907 set_current_val(&vars[V_NNTP_SERVER], TRUE, TRUE);
1908 for(i = 0; VAR_NNTP_SERVER && VAR_NNTP_SERVER[i]; i++)
1909 removing_quotes(VAR_NNTP_SERVER[i]);
1911 set_news_spec_current_val(TRUE, TRUE);
1913 set_current_val(&vars[V_INBOX_PATH], TRUE, TRUE);
1915 set_current_val(&vars[V_USER_DOMAIN], TRUE, TRUE);
1916 if(VAR_USER_DOMAIN
1917 && VAR_USER_DOMAIN[0]
1918 && (p = strrindex(VAR_USER_DOMAIN, '@'))){
1919 if(*(++p)){
1920 char *q;
1922 snprintf(tmp_20k_buf, SIZEOF_20KBUF,
1923 "User-domain (%s) cannot contain \"@\", using \"%s\"",
1924 VAR_USER_DOMAIN, p);
1925 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
1926 q = VAR_USER_DOMAIN;
1927 while((*q++ = *p++) != '\0')
1928 ;/* do nothing */
1930 else{
1931 snprintf(tmp_20k_buf, SIZEOF_20KBUF,
1932 "User-domain (%s) cannot contain \"@\", deleting",
1933 VAR_USER_DOMAIN);
1934 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
1935 if(ps->vars[V_USER_DOMAIN].post_user_val.p){
1936 fs_give((void **)&ps->vars[V_USER_DOMAIN].post_user_val.p);
1937 set_current_val(&vars[V_USER_DOMAIN], TRUE, TRUE);
1940 if(VAR_USER_DOMAIN
1941 && VAR_USER_DOMAIN[0]
1942 && (p = strrindex(VAR_USER_DOMAIN, '@'))){
1943 if(ps->vars[V_USER_DOMAIN].main_user_val.p){
1944 fs_give((void **)&ps->vars[V_USER_DOMAIN].main_user_val.p);
1945 set_current_val(&vars[V_USER_DOMAIN], TRUE, TRUE);
1951 set_current_val(&vars[V_USE_ONLY_DOMAIN_NAME], TRUE, TRUE);
1952 set_current_val(&vars[V_REPLY_STRING], TRUE, TRUE);
1953 set_current_val(&vars[V_WORDSEPS], TRUE, TRUE);
1954 set_current_val(&vars[V_QUOTE_REPLACE_STRING], TRUE, TRUE);
1955 set_current_val(&vars[V_REPLY_INTRO], TRUE, TRUE);
1956 set_current_val(&vars[V_EMPTY_HDR_MSG], TRUE, TRUE);
1958 #ifdef ENABLE_LDAP
1959 set_current_val(&vars[V_LDAP_SERVERS], TRUE, TRUE);
1960 #endif /* ENABLE_LDAP */
1962 /* obsolete, backwards compatibility */
1963 set_current_val(&vars[V_HEADER_IN_REPLY], TRUE, TRUE);
1964 obs_header_in_reply=!strucmp(VAR_HEADER_IN_REPLY, "yes");
1966 set_current_val(&vars[V_PERSONAL_PRINT_COMMAND], TRUE, TRUE);
1967 set_current_val(&vars[V_STANDARD_PRINTER], TRUE, TRUE);
1968 set_current_val(&vars[V_PRINTER], TRUE, TRUE);
1969 if(vars[V_PERSONAL_PRINT_COMMAND].is_fixed && !vars[V_PRINTER].is_fixed)
1970 printer_value_check_and_adjust();
1972 set_current_val(&vars[V_LAST_TIME_PRUNE_QUESTION], TRUE, TRUE);
1973 if(VAR_LAST_TIME_PRUNE_QUESTION != NULL){
1974 /* The month value in the file runs from 1-12, the variable here
1975 runs from 0-11; the value in the file used to be 0-11, but we're
1976 fixing it in January */
1977 ps->last_expire_year = atoi(VAR_LAST_TIME_PRUNE_QUESTION);
1978 ps->last_expire_month =
1979 atoi(strindex(VAR_LAST_TIME_PRUNE_QUESTION, '.') + 1);
1980 if(ps->last_expire_month == 0){
1981 /* Fix for 0 because of old bug */
1982 snprintf(buf, sizeof(buf), "%d.%d", ps_global->last_expire_year,
1983 ps_global->last_expire_month + 1);
1984 set_variable(V_LAST_TIME_PRUNE_QUESTION, buf, 1, 1, Main);
1985 }else{
1986 ps->last_expire_month--;
1988 }else{
1989 ps->last_expire_year = -1;
1990 ps->last_expire_month = -1;
1993 set_current_val(&vars[V_BUGS_FULLNAME], TRUE, TRUE);
1994 set_current_val(&vars[V_BUGS_ADDRESS], TRUE, TRUE);
1995 set_current_val(&vars[V_SUGGEST_FULLNAME], TRUE, TRUE);
1996 set_current_val(&vars[V_SUGGEST_ADDRESS], TRUE, TRUE);
1997 set_current_val(&vars[V_LOCAL_FULLNAME], TRUE, TRUE);
1998 set_current_val(&vars[V_LOCAL_ADDRESS], TRUE, TRUE);
1999 set_current_val(&vars[V_BUGS_EXTRAS], TRUE, TRUE);
2000 set_current_val(&vars[V_KBLOCK_PASSWD_COUNT], TRUE, TRUE);
2001 set_current_val(&vars[V_DEFAULT_FCC], TRUE, TRUE);
2002 set_current_val(&vars[V_POSTPONED_FOLDER], TRUE, TRUE);
2003 set_current_val(&vars[V_TRASH_FOLDER], TRUE, TRUE);
2004 set_current_val(&vars[V_READ_MESSAGE_FOLDER], TRUE, TRUE);
2005 set_current_val(&vars[V_FORM_FOLDER], TRUE, TRUE);
2006 set_current_val(&vars[V_EDITOR], TRUE, TRUE);
2007 set_current_val(&vars[V_SPELLER], TRUE, TRUE);
2008 set_current_val(&vars[V_IMAGE_VIEWER], TRUE, TRUE);
2009 set_current_val(&vars[V_BROWSER], TRUE, TRUE);
2010 set_current_val(&vars[V_SMTP_SERVER], TRUE, TRUE);
2011 set_current_val(&vars[V_COMP_HDRS], TRUE, TRUE);
2012 set_current_val(&vars[V_CUSTOM_HDRS], TRUE, TRUE);
2013 set_current_val(&vars[V_SENDMAIL_PATH], TRUE, TRUE);
2014 set_current_val(&vars[V_DISPLAY_FILTERS], TRUE, TRUE);
2015 set_current_val(&vars[V_SEND_FILTER], TRUE, TRUE);
2016 set_current_val(&vars[V_ALT_ADDRS], TRUE, TRUE);
2017 set_current_val(&vars[V_ABOOK_FORMATS], TRUE, TRUE);
2018 set_current_val(&vars[V_KW_BRACES], TRUE, TRUE);
2019 set_current_val(&vars[V_OPENING_SEP], TRUE, TRUE);
2020 set_current_val(&vars[V_UNK_CHAR_SET], TRUE, TRUE);
2021 #ifdef SMIME
2022 set_current_val(&vars[V_PUBLICCERT_DIR], TRUE, TRUE);
2023 set_current_val(&vars[V_PUBLICCERT_CONTAINER], TRUE, TRUE);
2024 set_current_val(&vars[V_PRIVATEKEY_DIR], TRUE, TRUE);
2025 set_current_val(&vars[V_PRIVATEKEY_CONTAINER], TRUE, TRUE);
2026 set_current_val(&vars[V_CACERT_DIR], TRUE, TRUE);
2027 set_current_val(&vars[V_CACERT_CONTAINER], TRUE, TRUE);
2028 #endif /* SMIME */
2030 set_current_val(&vars[V_KEYWORDS], TRUE, TRUE);
2031 ps_global->keywords = init_keyword_list(VAR_KEYWORDS);
2033 set_current_val(&vars[V_OPER_DIR], TRUE, TRUE);
2034 if(VAR_OPER_DIR && !VAR_OPER_DIR[0]){
2035 init_error(ps, SM_ORDER | SM_DING, 3, 5,
2036 "Setting operating-dir to the empty string is not allowed. Will be ignored.");
2037 fs_give((void **)&VAR_OPER_DIR);
2038 if(FIX_OPER_DIR)
2039 fs_give((void **)&FIX_OPER_DIR);
2040 if(GLO_OPER_DIR)
2041 fs_give((void **)&GLO_OPER_DIR);
2042 if(COM_OPER_DIR)
2043 fs_give((void **)&COM_OPER_DIR);
2044 if(ps_global->vars[V_OPER_DIR].post_user_val.p)
2045 fs_give((void **)&ps_global->vars[V_OPER_DIR].post_user_val.p);
2046 if(ps_global->vars[V_OPER_DIR].main_user_val.p)
2047 fs_give((void **)&ps_global->vars[V_OPER_DIR].main_user_val.p);
2050 set_current_val(&vars[V_PERSONAL_PRINT_CATEGORY], TRUE, TRUE);
2051 ps->printer_category = -1;
2052 if(VAR_PERSONAL_PRINT_CATEGORY != NULL)
2053 ps->printer_category = atoi(VAR_PERSONAL_PRINT_CATEGORY);
2055 if(ps->printer_category < 1 || ps->printer_category > 3){
2056 char **tt;
2057 char aname[100], wname[100];
2059 strncpy(aname, ANSI_PRINTER, sizeof(aname));
2060 aname[sizeof(aname)-1] = '\0';
2061 strncat(aname, "-no-formfeed", sizeof(aname)-strlen(aname)-1);
2062 strncpy(wname, WYSE_PRINTER, sizeof(wname));
2063 wname[sizeof(wname)-1] = '\0';
2064 strncat(wname, "-no-formfeed", sizeof(wname)-strlen(wname)-1);
2065 if(strucmp(VAR_PRINTER, ANSI_PRINTER) == 0
2066 || strucmp(VAR_PRINTER, aname) == 0
2067 || strucmp(VAR_PRINTER, WYSE_PRINTER) == 0
2068 || strucmp(VAR_PRINTER, wname) == 0)
2069 ps->printer_category = 1;
2070 else if(VAR_STANDARD_PRINTER && VAR_STANDARD_PRINTER[0]){
2071 for(tt = VAR_STANDARD_PRINTER; *tt; tt++)
2072 if(strucmp(VAR_PRINTER, *tt) == 0)
2073 break;
2075 if(*tt)
2076 ps->printer_category = 2;
2079 /* didn't find it yet */
2080 if(ps->printer_category < 1 || ps->printer_category > 3){
2081 if(VAR_PERSONAL_PRINT_COMMAND && VAR_PERSONAL_PRINT_COMMAND[0]){
2082 for(tt = VAR_PERSONAL_PRINT_COMMAND; *tt; tt++)
2083 if(strucmp(VAR_PRINTER, *tt) == 0)
2084 break;
2086 if(*tt)
2087 ps->printer_category = 3;
2092 set_current_val(&vars[V_SLEEP], TRUE, TRUE);
2093 ps->sleep = i = 60;
2094 if(SVAR_SLEEP(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2095 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2096 else
2097 ps->sleep = i;
2099 set_current_val(&vars[V_OVERLAP], TRUE, TRUE);
2100 ps->viewer_overlap = i = atoi(DF_OVERLAP);
2101 if(SVAR_OVERLAP(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2102 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2103 else
2104 ps->viewer_overlap = i;
2106 set_current_val(&vars[V_MARGIN], TRUE, TRUE);
2107 ps->scroll_margin = i = atoi(DF_MARGIN);
2108 if(SVAR_MARGIN(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2109 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2110 else
2111 ps->scroll_margin = i;
2113 set_current_val(&vars[V_FILLCOL], TRUE, TRUE);
2114 ps->composer_fillcol = i = atoi(DF_FILLCOL);
2115 if(SVAR_FILLCOL(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2116 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2117 else
2118 ps->composer_fillcol = i;
2120 set_current_val(&vars[V_QUOTE_SUPPRESSION], TRUE, TRUE);
2121 ps->quote_suppression_threshold = i = atoi(DF_QUOTE_SUPPRESSION);
2122 if(SVAR_QUOTE_SUPPRESSION(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2123 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2124 else{
2125 if(i > 0 && i < Q_SUPP_LIMIT){
2126 snprintf(tmp_20k_buf, SIZEOF_20KBUF,
2127 "Ignoring Quote-Suppression-Threshold value of %.50s, see help",
2128 VAR_QUOTE_SUPPRESSION);
2129 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2131 else{
2132 if(i < 0 && i != Q_DEL_ALL)
2133 ps->quote_suppression_threshold = -i;
2134 else
2135 ps->quote_suppression_threshold = i;
2139 set_current_val(&vars[V_DEADLETS], TRUE, TRUE);
2140 ps->deadlets = i = atoi(DF_DEADLETS);
2141 if(SVAR_DEADLETS(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2142 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2143 else
2144 ps->deadlets = i;
2146 set_current_val(&vars[V_STATUS_MSG_DELAY], TRUE, TRUE);
2147 ps->status_msg_delay = i = 0;
2148 if(SVAR_MSGDLAY(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2149 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2150 else
2151 ps->status_msg_delay = i;
2153 set_current_val(&vars[V_ACTIVE_MSG_INTERVAL], TRUE, TRUE);
2154 ps->active_status_interval = i = 8;
2155 if(SVAR_ACTIVEINTERVAL(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2156 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2157 else
2158 ps->active_status_interval = i;
2160 set_current_val(&vars[V_REMOTE_ABOOK_HISTORY], TRUE, TRUE);
2161 ps->remote_abook_history = i = atoi(DF_REMOTE_ABOOK_HISTORY);
2162 if(SVAR_AB_HIST(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2163 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2164 else
2165 ps->remote_abook_history = i;
2167 set_current_val(&vars[V_REMOTE_ABOOK_VALIDITY], TRUE, TRUE);
2168 ps->remote_abook_validity = i = atoi(DF_REMOTE_ABOOK_VALIDITY);
2169 if(SVAR_AB_VALID(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2170 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2171 else
2172 ps->remote_abook_validity = i;
2174 set_current_val(&vars[V_USERINPUTTIMEO], TRUE, TRUE);
2175 ps->hours_to_timeout = i = 0;
2176 if(SVAR_USER_INPUT(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2177 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2178 else
2179 ps->hours_to_timeout = i;
2181 /* timeo is a regular extern int because it is referenced in pico */
2182 set_current_val(&vars[V_MAILCHECK], TRUE, TRUE);
2183 set_input_timeout(i = 15);
2184 if(SVAR_MAILCHK(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2185 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2186 else
2187 set_input_timeout(i);
2189 set_current_val(&vars[V_MAILCHECKNONCURR], TRUE, TRUE);
2190 ps->check_interval_for_noncurr = i = 0;
2191 if(SVAR_MAILCHKNONCURR(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2192 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2193 else
2194 ps->check_interval_for_noncurr = i;
2196 #ifdef DEBUGJOURNAL
2197 ps->debugmem = 1;
2198 #else
2199 ps->debugmem = 0;
2200 #endif
2202 i = 30;
2203 set_current_val(&vars[V_TCPOPENTIMEO], TRUE, TRUE);
2204 /* this is just for the error, we don't save the result */
2205 if(VAR_TCPOPENTIMEO && SVAR_TCP_OPEN(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2206 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2208 i = 15;
2209 set_current_val(&vars[V_TCPREADWARNTIMEO], TRUE, TRUE);
2210 /* this is just for the error, we don't save the result */
2211 if(VAR_TCPREADWARNTIMEO && SVAR_TCP_READWARN(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2212 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2214 i = 0;
2215 set_current_val(&vars[V_TCPWRITEWARNTIMEO], TRUE, TRUE);
2216 /* this is just for the error, we don't save the result */
2217 if(VAR_TCPWRITEWARNTIMEO && SVAR_TCP_WRITEWARN(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2218 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2220 i = 15;
2221 set_current_val(&vars[V_RSHOPENTIMEO], TRUE, TRUE);
2222 /* this is just for the error, we don't save the result */
2223 if(VAR_RSHOPENTIMEO && SVAR_RSH_OPEN(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2224 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2226 i = 15;
2227 set_current_val(&vars[V_SSHOPENTIMEO], TRUE, TRUE);
2228 /* this is just for the error, we don't save the result */
2229 if(VAR_SSHOPENTIMEO && SVAR_SSH_OPEN(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2230 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2232 set_current_val(&vars[V_INCCHECKLIST], TRUE, TRUE);
2234 set_current_val(&vars[V_INCCHECKTIMEO], TRUE, TRUE);
2235 ps->inc_check_timeout = i = 5;
2236 if(SVAR_INC_CHECK_TIMEO(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2237 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2238 else
2239 ps->inc_check_timeout = i;
2241 set_current_val(&vars[V_INCCHECKINTERVAL], TRUE, TRUE);
2242 ps->inc_check_interval = i = 180;
2243 if(SVAR_INC_CHECK_INTERV(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2244 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2245 else
2246 ps->inc_check_interval = i;
2248 set_current_val(&vars[V_INC2NDCHECKINTERVAL], TRUE, TRUE);
2249 ps->inc_second_check_interval = i = 180;
2250 if(SVAR_INC_2NDCHECK_INTERV(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2251 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2252 else
2253 ps->inc_second_check_interval = i;
2255 rvl = 60L;
2256 set_current_val(&vars[V_MAILDROPCHECK], TRUE, TRUE);
2257 /* this is just for the error, we don't save the result */
2258 if(VAR_MAILDROPCHECK && SVAR_MAILDCHK(ps, rvl, tmp_20k_buf, SIZEOF_20KBUF))
2259 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2261 rvl = 0L;
2262 set_current_val(&vars[V_NNTPRANGE], TRUE, TRUE);
2263 /* this is just for the error, we don't save the result */
2264 if(VAR_NNTPRANGE && SVAR_NNTPRANGE(ps, rvl, tmp_20k_buf, SIZEOF_20KBUF))
2265 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2267 set_current_val(&vars[V_TCPQUERYTIMEO], TRUE, TRUE);
2268 ps->tcp_query_timeout = i = TO_BAIL_THRESHOLD;
2269 if(VAR_TCPQUERYTIMEO && SVAR_TCP_QUERY(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2270 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2271 else
2272 ps->tcp_query_timeout = i;
2274 set_current_val(&vars[V_NEWSRC_PATH], TRUE, TRUE);
2275 if(VAR_NEWSRC_PATH && VAR_NEWSRC_PATH[0])
2276 mail_parameters(NULL, SET_NEWSRC, (void *)VAR_NEWSRC_PATH);
2278 set_current_val(&vars[V_NEWS_ACTIVE_PATH], TRUE, TRUE);
2279 if(VAR_NEWS_ACTIVE_PATH)
2280 mail_parameters(NULL, SET_NEWSACTIVE,
2281 (void *)VAR_NEWS_ACTIVE_PATH);
2283 set_current_val(&vars[V_NEWS_SPOOL_DIR], TRUE, TRUE);
2284 if(VAR_NEWS_SPOOL_DIR)
2285 mail_parameters(NULL, SET_NEWSSPOOL,
2286 (void *)VAR_NEWS_SPOOL_DIR);
2288 /* guarantee a save default */
2289 set_current_val(&vars[V_DEFAULT_SAVE_FOLDER], TRUE, TRUE);
2290 if(!VAR_DEFAULT_SAVE_FOLDER || !VAR_DEFAULT_SAVE_FOLDER[0])
2291 set_variable(V_DEFAULT_SAVE_FOLDER,
2292 (GLO_DEFAULT_SAVE_FOLDER && GLO_DEFAULT_SAVE_FOLDER[0])
2293 ? GLO_DEFAULT_SAVE_FOLDER
2294 : DEFAULT_SAVE, 1, 0, Main);
2296 set_current_val(&vars[V_SIGNATURE_FILE], TRUE, TRUE);
2297 set_current_val(&vars[V_LITERAL_SIG], TRUE, TRUE);
2298 set_current_val(&vars[V_GLOB_ADDRBOOK], TRUE, TRUE);
2299 set_current_val(&vars[V_ADDRESSBOOK], TRUE, TRUE);
2300 set_current_val(&vars[V_FORCED_ABOOK_ENTRY], TRUE, TRUE);
2301 set_current_val(&vars[V_DISABLE_DRIVERS], TRUE, TRUE);
2302 set_current_val(&vars[V_DISABLE_AUTHS], TRUE, TRUE);
2304 set_current_val(&vars[V_VIEW_HEADERS], TRUE, TRUE);
2305 /* strip spaces and colons */
2306 if(ps->VAR_VIEW_HEADERS){
2307 for(s = ps->VAR_VIEW_HEADERS; (q = *s) != NULL; s++){
2308 if(q[0]){
2309 removing_leading_white_space(q);
2310 /* look for colon or space or end */
2311 for(p = q; *p && !isspace((unsigned char)*p) && *p != ':'; p++)
2312 ;/* do nothing */
2314 *p = '\0';
2315 if(strucmp(q, ALL_EXCEPT) == 0)
2316 ps->view_all_except = 1;
2321 set_current_val(&vars[V_VIEW_MARGIN_LEFT], TRUE, TRUE);
2322 set_current_val(&vars[V_VIEW_MARGIN_RIGHT], TRUE, TRUE);
2323 set_current_val(&vars[V_UPLOAD_CMD], TRUE, TRUE);
2324 set_current_val(&vars[V_UPLOAD_CMD_PREFIX], TRUE, TRUE);
2325 set_current_val(&vars[V_DOWNLOAD_CMD], TRUE, TRUE);
2326 set_current_val(&vars[V_DOWNLOAD_CMD_PREFIX], TRUE, TRUE);
2327 set_current_val(&vars[V_MAILCAP_PATH], TRUE, TRUE);
2328 set_current_val(&vars[V_MIMETYPE_PATH], TRUE, TRUE);
2329 #if !defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO)
2330 set_current_val(&vars[V_FIFOPATH], TRUE, TRUE);
2331 #endif
2333 set_current_val(&vars[V_RSHPATH], TRUE, TRUE);
2334 if(VAR_RSHPATH
2335 && is_absolute_path(VAR_RSHPATH)
2336 && can_access(VAR_RSHPATH, EXECUTE_ACCESS) == 0){
2337 mail_parameters(NULL, SET_RSHPATH, (void *) VAR_RSHPATH);
2340 set_current_val(&vars[V_RSHCMD], TRUE, TRUE);
2341 if(VAR_RSHCMD){
2342 mail_parameters(NULL, SET_RSHCOMMAND, (void *) VAR_RSHCMD);
2345 set_current_val(&vars[V_SSHPATH], TRUE, TRUE);
2346 if(VAR_SSHPATH) {
2347 if(is_absolute_path(VAR_SSHPATH)
2348 && can_access(VAR_SSHPATH, EXECUTE_ACCESS) == 0){
2349 mail_parameters(NULL, SET_SSHPATH, (void *) VAR_SSHPATH);
2351 else {
2352 mail_parameters(NULL, SET_SSHPATH, (void *) NULL);
2356 set_current_val(&vars[V_SSHCMD], TRUE, TRUE);
2357 if(VAR_SSHCMD) {
2358 if(VAR_SSHCMD[0]) {
2359 mail_parameters(NULL, SET_SSHCOMMAND, (void *) VAR_SSHCMD);
2361 else {
2362 mail_parameters(NULL, SET_SSHCOMMAND, (void *) NULL);
2366 #if defined(DOS) || defined(OS2)
2368 set_current_val(&vars[V_FILE_DIR], TRUE, TRUE);
2370 #ifdef _WINDOWS
2371 set_current_val(&vars[V_FONT_NAME], TRUE, TRUE);
2372 set_current_val(&vars[V_FONT_SIZE], TRUE, TRUE);
2373 set_current_val(&vars[V_FONT_STYLE], TRUE, TRUE);
2374 set_current_val(&vars[V_FONT_CHAR_SET], TRUE, TRUE);
2375 set_current_val(&vars[V_CURSOR_STYLE], TRUE, TRUE);
2376 set_current_val(&vars[V_WINDOW_POSITION], TRUE, TRUE);
2378 if(F_OFF(F_STORE_WINPOS_IN_CONFIG, ps_global)){
2379 /* if win position is in the registry, use it */
2380 if(mswin_reg(MSWR_OP_GET, MSWR_PINE_POS, buf, sizeof(buf))){
2381 if(VAR_WINDOW_POSITION)
2382 fs_give((void **)&VAR_WINDOW_POSITION);
2384 VAR_WINDOW_POSITION = cpystr(buf);
2386 else if(VAR_WINDOW_POSITION
2387 && (ps->update_registry != UREG_NEVER_SET)){
2388 /* otherwise, put it there */
2389 mswin_reg(MSWR_OP_SET | ((ps->update_registry == UREG_ALWAYS_SET)
2390 ? MSWR_OP_FORCE : 0),
2391 MSWR_PINE_POS,
2392 VAR_WINDOW_POSITION, (size_t)NULL);
2396 mswin_setwindow (VAR_FONT_NAME, VAR_FONT_SIZE,
2397 VAR_FONT_STYLE, VAR_WINDOW_POSITION,
2398 VAR_CURSOR_STYLE, VAR_FONT_CHAR_SET);
2400 /* this is no longer used */
2401 if(VAR_WINDOW_POSITION)
2402 fs_give((void **)&VAR_WINDOW_POSITION);
2404 set_current_val(&vars[V_PRINT_FONT_NAME], TRUE, TRUE);
2405 set_current_val(&vars[V_PRINT_FONT_SIZE], TRUE, TRUE);
2406 set_current_val(&vars[V_PRINT_FONT_STYLE], TRUE, TRUE);
2407 set_current_val(&vars[V_PRINT_FONT_CHAR_SET], TRUE, TRUE);
2408 mswin_setprintfont (VAR_PRINT_FONT_NAME,
2409 VAR_PRINT_FONT_SIZE,
2410 VAR_PRINT_FONT_STYLE,
2411 VAR_PRINT_FONT_CHAR_SET);
2413 mswin_setgenhelptextcallback(pcpine_general_help);
2415 mswin_setclosetext ("Use the \"Q\" command to exit Alpine.");
2418 char foreColor[64], backColor[64];
2420 mswin_getwindow(NULL, 0, NULL, 0, NULL, 0, NULL, 0,
2421 foreColor, sizeof(foreColor), backColor, sizeof(backColor),
2422 NULL, 0, NULL, 0);
2423 if(!GLO_NORM_FORE_COLOR)
2424 GLO_NORM_FORE_COLOR = cpystr(foreColor);
2426 if(!GLO_NORM_BACK_COLOR)
2427 GLO_NORM_BACK_COLOR = cpystr(backColor);
2429 #endif /* _WINDOWS */
2430 #endif /* DOS */
2433 * We want the version number to start out as 1.0 for Alpine, but
2434 * we also want to use the same old config file that was used
2435 * with Pine. The Pine version numbers made it up to 4.64 and we
2436 * want Alpine's 1.0 to be larger than 4.64 so we keep a separate
2437 * internal version number which is the real version number
2438 * plus 4. That's what gets written in LAST_VERS_USED.
2440 strncpy(ps->vers_internal, ALPINE_VERSION, sizeof(ps->vers_internal));
2441 ps->vers_internal[sizeof(ps->vers_internal)-1] = '\0';
2442 if(isdigit(ps->vers_internal[0]) && ps->vers_internal[0] < '6')
2443 ps->vers_internal[0] = ps->vers_internal[0] + 4;
2445 set_current_val(&vars[V_LAST_VERS_USED], TRUE, TRUE);
2446 /* Check for special cases first */
2447 if(VAR_LAST_VERS_USED
2448 && (isdigit(ps->vers_internal[0])
2449 && ps->vers_internal[1] == '.'
2450 && isdigit((unsigned char)ps->vers_internal[2])
2451 && isdigit((unsigned char)ps->vers_internal[3])
2452 && isalpha((unsigned char)ps->vers_internal[4])
2453 && strncmp(VAR_LAST_VERS_USED, ps->vers_internal, 4) >= 0)){
2454 ps->show_new_version = 0;
2456 /* Otherwise just do lexicographic comparision... */
2457 else if(VAR_LAST_VERS_USED
2458 && strcmp(VAR_LAST_VERS_USED, ps->vers_internal) >= 0){
2459 ps->show_new_version = 0;
2461 else{
2462 #ifdef _WINDOWS
2464 * If this is the first time we've run a version > 4.40, and there
2465 * is evidence that the config file has not been used by unix pine,
2466 * then we convert color008 to colorlgr, color009 to colormgr, and
2467 * color010 to colordgr. If the config file is being used by
2468 * unix pine then color009 may really supposed to be red, etc.
2469 * Same if we've already run 4.41 or higher. We don't have to do
2470 * anything if we are new to alpine.
2472 ps->pre441 = (VAR_LAST_VERS_USED
2473 && strcmp(VAR_LAST_VERS_USED, "4.40") <= 0);
2474 #endif /* _WINDOWS */
2477 * Don't offer the new version message if we're told not to.
2479 set_current_val(&vars[V_NEW_VER_QUELL], TRUE, TRUE);
2480 ps->show_new_version = !(VAR_NEW_VER_QUELL
2481 && strcmp(ps->vers_internal,
2482 VAR_NEW_VER_QUELL) < 0);
2484 #ifdef _WINDOWS
2485 if(!ps_global->install_flag)
2486 #endif /* _WINDOWS */
2488 if(VAR_LAST_VERS_USED){
2489 strncpy(ps_global->pine_pre_vers, VAR_LAST_VERS_USED,
2490 sizeof(ps_global->pine_pre_vers));
2491 ps_global->pine_pre_vers[sizeof(ps_global->pine_pre_vers)-1] = '\0';
2494 set_variable(V_LAST_VERS_USED, ps->vers_internal, 1, 1,
2495 ps_global->ew_for_except_vars);
2499 /* Obsolete, backwards compatibility */
2500 set_current_val(&vars[V_ELM_STYLE_SAVE], TRUE, TRUE);
2501 /* Also obsolete */
2502 set_current_val(&vars[V_SAVE_BY_SENDER], TRUE, TRUE);
2503 if(!strucmp(VAR_ELM_STYLE_SAVE, "yes"))
2504 set_variable(V_SAVE_BY_SENDER, "yes", 1, 1, Main);
2505 obs_save_by_sender = !strucmp(VAR_SAVE_BY_SENDER, "yes");
2507 set_current_pattern_vals(ps);
2509 set_current_val(&vars[V_INDEX_FORMAT], TRUE, TRUE);
2510 init_index_format(VAR_INDEX_FORMAT, &ps->index_disp_format);
2512 /* this should come after pre441 is set or not */
2513 set_current_color_vals(ps);
2515 set_current_val(&vars[V_RSS_NEWS], TRUE, TRUE);
2516 set_current_val(&vars[V_RSS_WEATHER], TRUE, TRUE);
2517 set_current_val(&vars[V_WP_INDEXHEIGHT], TRUE, TRUE);
2518 set_current_val(&vars[V_WP_INDEXLINES], TRUE, TRUE);
2519 set_current_val(&vars[V_WP_AGGSTATE], TRUE, TRUE);
2520 set_current_val(&vars[V_WP_STATE], TRUE, TRUE);
2521 set_current_val(&vars[V_WP_COLUMNS], TRUE, TRUE);
2523 set_current_val(&vars[V_PRUNED_FOLDERS], TRUE, TRUE);
2524 set_current_val(&vars[V_ARCHIVED_FOLDERS], TRUE, TRUE);
2525 set_current_val(&vars[V_INCOMING_FOLDERS], TRUE, TRUE);
2526 set_current_val(&vars[V_SORT_KEY], TRUE, TRUE);
2527 if(decode_sort(VAR_SORT_KEY, &ps->def_sort, &def_sort_rev) == -1){
2528 snprintf(tmp_20k_buf, SIZEOF_20KBUF, "Sort type \"%.200s\" is invalid", VAR_SORT_KEY);
2529 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2530 ps->def_sort = SortArrival;
2531 ps->def_sort_rev = 0;
2533 else
2534 ps->def_sort_rev = def_sort_rev;
2536 cur_rule_value(&vars[V_SAVED_MSG_NAME_RULE], TRUE, TRUE);
2537 {NAMEVAL_S *v; int i;
2538 for(i = 0; (v = save_msg_rules(i)); i++)
2539 if(v->value == ps_global->save_msg_rule)
2540 break;
2542 /* if save_msg_rule is not default, or is explicitly set to default */
2543 if((ps_global->save_msg_rule != SAV_RULE_DEFLT) ||
2544 (v && v->name &&
2545 (!strucmp(ps_global->vars[V_SAVED_MSG_NAME_RULE].post_user_val.p,
2546 v->name) ||
2547 !strucmp(ps_global->vars[V_SAVED_MSG_NAME_RULE].main_user_val.p,
2548 v->name))))
2549 obs_save_by_sender = 0; /* don't overwrite */
2552 cur_rule_value(&vars[V_FCC_RULE], TRUE, TRUE);
2553 cur_rule_value(&vars[V_AB_SORT_RULE], TRUE, TRUE);
2555 #ifndef _WINDOWS
2556 cur_rule_value(&vars[V_COLOR_STYLE], TRUE, TRUE);
2557 #endif
2559 cur_rule_value(&vars[V_INDEX_COLOR_STYLE], TRUE, TRUE);
2560 cur_rule_value(&vars[V_TITLEBAR_COLOR_STYLE], TRUE, TRUE);
2561 cur_rule_value(&vars[V_FLD_SORT_RULE], TRUE, TRUE);
2562 cur_rule_value(&vars[V_INCOMING_STARTUP], TRUE, TRUE);
2563 cur_rule_value(&vars[V_PRUNING_RULE], TRUE, TRUE);
2564 cur_rule_value(&vars[V_REOPEN_RULE], TRUE, TRUE);
2565 cur_rule_value(&vars[V_GOTO_DEFAULT_RULE], TRUE, TRUE);
2566 cur_rule_value(&vars[V_THREAD_DISP_STYLE], TRUE, TRUE);
2567 cur_rule_value(&vars[V_THREAD_INDEX_STYLE], TRUE, TRUE);
2569 set_current_val(&vars[V_THREAD_MORE_CHAR], TRUE, TRUE);
2570 if(VAR_THREAD_MORE_CHAR[0] && VAR_THREAD_MORE_CHAR[1]){
2571 init_error(ps, SM_ORDER | SM_DING, 3, 5,
2572 _("Only using first character of threading-indicator-character option"));
2573 VAR_THREAD_MORE_CHAR[1] = '\0';
2576 set_current_val(&vars[V_THREAD_EXP_CHAR], TRUE, TRUE);
2577 if(VAR_THREAD_EXP_CHAR[0] && VAR_THREAD_EXP_CHAR[1]){
2578 init_error(ps, SM_ORDER | SM_DING, 3, 5,
2579 _("Only using first character of threading-expanded-character option"));
2580 VAR_THREAD_EXP_CHAR[1] = '\0';
2583 set_current_val(&vars[V_THREAD_LASTREPLY_CHAR], TRUE, TRUE);
2584 if(!VAR_THREAD_LASTREPLY_CHAR[0])
2585 VAR_THREAD_LASTREPLY_CHAR = cpystr(DF_THREAD_LASTREPLY_CHAR);
2587 if(VAR_THREAD_LASTREPLY_CHAR[0] && VAR_THREAD_LASTREPLY_CHAR[1]){
2588 init_error(ps, SM_ORDER | SM_DING, 3, 5,
2589 _("Only using first character of threading-lastreply-character option"));
2590 VAR_THREAD_LASTREPLY_CHAR[1] = '\0';
2593 set_current_val(&vars[V_MAXREMSTREAM], TRUE, TRUE);
2594 ps->s_pool.max_remstream = i = atoi(DF_MAXREMSTREAM);
2595 if(SVAR_MAXREMSTREAM(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2596 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2597 else
2598 ps->s_pool.max_remstream = i;
2600 set_current_val(&vars[V_PERMLOCKED], TRUE, TRUE);
2602 set_current_val(&vars[V_NMW_WIDTH], TRUE, TRUE);
2603 ps->nmw_width = i = atoi(DF_NMW_WIDTH);
2604 if(SVAR_NMW_WIDTH(ps, i, tmp_20k_buf, SIZEOF_20KBUF))
2605 init_error(ps, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
2606 else
2607 ps->nmw_width = i;
2609 /* backwards compatibility */
2610 if(obs_save_by_sender){
2611 ps->save_msg_rule = SAV_RULE_FROM;
2612 set_variable(V_SAVED_MSG_NAME_RULE, "by-from", 1, 1, Main);
2615 /* this should come after process_feature_list because of use_fkeys */
2616 if(!ps->start_in_index)
2617 set_current_val(&vars[V_INIT_CMD_LIST], FALSE, TRUE);
2618 if(VAR_INIT_CMD_LIST && VAR_INIT_CMD_LIST[0] && VAR_INIT_CMD_LIST[0][0])
2619 if(cmds_f)
2620 (*cmds_f)(ps, VAR_INIT_CMD_LIST);
2622 #ifdef _WINDOWS
2623 mswin_set_quit_confirm (F_OFF(F_QUIT_WO_CONFIRM, ps_global));
2624 #endif /* _WINDOWS */
2626 #ifdef DEBUG
2627 dump_configuration(0);
2628 #endif /* DEBUG */
2632 void
2633 convert_configvars_to_utf8(struct variable *vars, char *fromcharset)
2635 struct variable *v;
2638 * Make sure that everything is UTF-8.
2640 for(v = vars; v->name; v++)
2641 convert_configvar_to_utf8(v, fromcharset);
2645 void
2646 convert_configvar_to_utf8(struct variable *v, char *fromcharset)
2648 char **p, *conv, **valptr;
2649 int i;
2652 * Make sure that everything is UTF-8.
2654 if(v->is_list){
2655 for(i = 0; i < 7; i++){
2656 switch(i){
2657 case 1: valptr = v->current_val.l; break;
2658 case 0: valptr = v->main_user_val.l; break;
2659 case 2: valptr = v->changed_val.l; break;
2660 case 3: valptr = v->post_user_val.l; break;
2661 case 4: valptr = v->global_val.l; break;
2662 case 5: valptr = v->fixed_val.l; break;
2663 case 6: valptr = v->cmdline_val.l; break;
2664 default: alpine_panic("bad case in convert_configvar");
2667 if(valptr){
2668 for(p = valptr; *p; p++){
2669 if(**p){
2670 conv = convert_to_utf8(*p, fromcharset, 0);
2671 if(conv){
2672 fs_give((void **) p);
2673 *p = conv;
2680 else{
2681 for(i = 0; i < 7; i++){
2682 switch(i){
2683 case 1: valptr = &v->current_val.p; break;
2684 case 0: valptr = &v->main_user_val.p; break;
2685 case 2: valptr = &v->changed_val.p; break;
2686 case 3: valptr = &v->post_user_val.p; break;
2687 case 4: valptr = &v->global_val.p; break;
2688 case 5: valptr = &v->fixed_val.p; break;
2689 case 6: valptr = &v->cmdline_val.p; break;
2690 default: alpine_panic("bad case in convert_configvar");
2693 if(valptr && *valptr && (*valptr)[0]){
2694 conv = convert_to_utf8(*valptr, fromcharset, 0);
2695 if(conv){
2696 fs_give((void **) valptr);
2697 *valptr = conv;
2707 * Standard feature name sections
2709 char *
2710 feature_list_section(FEATURE_S *feature)
2712 #define PREF_NONE -1
2713 static char *feat_sect[] = {
2714 #define PREF_MISC 0
2715 /* TRANSLATORS: section heading in configuration screen */
2716 N_("Advanced User Preferences"),
2717 #define PREF_FLDR 1
2718 /* TRANSLATORS: section heading in configuration screen */
2719 N_("Folder Preferences"),
2720 #define PREF_ADDR 2
2721 /* TRANSLATORS: section heading in configuration screen */
2722 N_("Address Book Preferences"),
2723 #define PREF_COMP 3
2724 /* TRANSLATORS: section heading in configuration screen */
2725 N_("Composer Preferences"),
2726 #define PREF_NEWS 4
2727 /* TRANSLATORS: section heading in configuration screen */
2728 N_("News Preferences"),
2729 #define PREF_VIEW 5
2730 /* TRANSLATORS: section heading in configuration screen */
2731 N_("Viewer Preferences"),
2732 #define PREF_ACMD 6
2733 /* TRANSLATORS: section heading in configuration screen */
2734 N_("Advanced Command Preferences"),
2735 #define PREF_PRNT 7
2736 /* TRANSLATORS: section heading in configuration screen */
2737 N_("Printer Preferences"),
2738 #define PREF_RPLY 8
2739 /* TRANSLATORS: section heading in configuration screen */
2740 N_("Reply Preferences"),
2741 #define PREF_SEND 9
2742 /* TRANSLATORS: section heading in configuration screen */
2743 N_("Sending Preferences"),
2744 #define PREF_INDX 10
2745 /* TRANSLATORS: section heading in configuration screen */
2746 N_("Message Index Preferences"),
2747 #define PREF_HIDDEN 11
2748 HIDDEN_PREF
2751 return((feature && feature->section > PREF_NONE
2752 && feature->section < (sizeof(feat_sect)/sizeof(feat_sect[0])))
2753 ? _(feat_sect[feature->section]) : NULL);
2757 /* any os-specific exclusions */
2758 #if defined(DOS) || defined(OS2)
2759 #define PREF_OS_LWSD PREF_NONE
2760 #define PREF_OS_LCLK PREF_NONE
2761 #define PREF_OS_STSP PREF_NONE
2762 #define PREF_OS_SPWN PREF_NONE
2763 #define PREF_OS_XNML PREF_NONE
2764 #define PREF_OS_USFK PREF_MISC
2765 #define PREF_OS_MOUSE PREF_NONE
2766 #else
2767 #define PREF_OS_LWSD PREF_MISC
2768 #define PREF_OS_LCLK PREF_COMP
2769 #define PREF_OS_STSP PREF_MISC
2770 #define PREF_OS_SPWN PREF_MISC
2771 #define PREF_OS_XNML PREF_MISC
2772 #define PREF_OS_USFK PREF_NONE
2773 #define PREF_OS_MOUSE PREF_MISC
2774 #endif
2778 * Standard way to get at feature list members...
2780 FEATURE_S *
2781 feature_list(int index)
2784 * This list is alphabatized by feature string, but the
2785 * macro values need not be ordered.
2787 static FEATURE_S feat_list[] = {
2788 /* Composer prefs */
2789 {"allow-changing-from", NULL,
2790 F_ALLOW_CHANGING_FROM, h_config_allow_chg_from, PREF_COMP, 1},
2791 {"alternate-compose-menu", NULL,
2792 F_ALT_COMPOSE_MENU, h_config_alt_compose_menu, PREF_COMP, 0},
2793 {"alternate-role-menu", "Alternate Role (#) Menu",
2794 F_ALT_ROLE_MENU, h_config_alt_role_menu, PREF_COMP, 0},
2795 {"compose-cancel-confirm-uses-yes", NULL,
2796 F_CANCEL_CONFIRM, h_config_cancel_confirm, PREF_COMP, 0},
2797 {"compose-rejects-unqualified-addrs", "Compose Rejects Unqualified Addresses",
2798 F_COMPOSE_REJECTS_UNQUAL, h_config_compose_rejects_unqual, PREF_COMP, 0},
2799 {"compose-send-offers-first-filter", NULL,
2800 F_FIRST_SEND_FILTER_DFLT, h_config_send_filter_dflt, PREF_COMP, 0},
2801 {"compose-cut-from-cursor", "Ctrl-K Cuts From Cursor",
2802 F_DEL_FROM_DOT, h_config_del_from_dot, PREF_COMP, 0},
2803 {"compose-maps-delete-key-to-ctrl-d", "Delete Key Maps to Ctrl-D",
2804 F_COMPOSE_MAPS_DEL, h_config_compose_maps_del, PREF_COMP, 0},
2805 {"quell-dead-letter-on-cancel", "Do Not Save to Deadletter on Cancel",
2806 F_QUELL_DEAD_LETTER, h_config_quell_dead_letter, PREF_COMP, 0},
2807 {"enable-alternate-editor-cmd", "Enable Alternate Editor Command",
2808 F_ENABLE_ALT_ED, h_config_enable_alt_ed, PREF_COMP, 1},
2809 {"enable-alternate-editor-implicitly", NULL,
2810 F_ALT_ED_NOW, h_config_alt_ed_now, PREF_COMP, 0},
2811 {"enable-search-and-replace", "Enable Search and Replace",
2812 F_ENABLE_SEARCH_AND_REPL, h_config_enable_search_and_repl, PREF_COMP, 1},
2813 {"enable-sigdashes", NULL,
2814 F_ENABLE_SIGDASHES, h_config_sigdashes, PREF_COMP, 0},
2815 {"quell-mailchecks-composing-except-inbox", "Prevent Mailchecks While Composing Except for INBOX",
2816 F_QUELL_PINGS_COMPOSING, h_config_quell_checks_comp, PREF_COMP, 0},
2817 {"quell-mailchecks-composing-inbox", "Prevent Mailchecks While Composing for INBOX",
2818 F_QUELL_PINGS_COMPOSING_INBOX, h_config_quell_checks_comp_inbox, PREF_COMP, 0},
2819 {"quell-user-lookup-in-passwd-file", "Prevent User Lookup in Password File",
2820 F_QUELL_LOCAL_LOOKUP, h_config_quell_local_lookup, PREF_OS_LCLK, 0},
2821 {"spell-check-before-sending", NULL,
2822 F_ALWAYS_SPELL_CHECK, h_config_always_spell_check, PREF_COMP, 0},
2824 /* Reply Prefs */
2825 {"copy-to-address-to-from-if-it-is-us", "Copy To Address to From if it is Us",
2826 F_COPY_TO_TO_FROM, h_config_copy_to_to_from, PREF_RPLY, 0},
2827 {"enable-reply-indent-string-editing", NULL,
2828 F_ENABLE_EDIT_REPLY_INDENT, h_config_prefix_editing, PREF_RPLY, 0},
2829 {"include-attachments-in-reply", "Include Attachments in Reply",
2830 F_ATTACHMENTS_IN_REPLY, h_config_attach_in_reply, PREF_RPLY, 0},
2831 {"include-header-in-reply", "Include Header in Reply",
2832 F_INCLUDE_HEADER, h_config_include_header, PREF_RPLY, 0},
2833 {"include-text-in-reply", "Include Text in Reply",
2834 F_AUTO_INCLUDE_IN_REPLY, h_config_auto_include_reply, PREF_RPLY, 0},
2835 {"reply-always-uses-reply-to", "Reply Always Uses Reply-To",
2836 F_AUTO_REPLY_TO, h_config_auto_reply_to, PREF_RPLY, 0},
2837 {"signature-at-bottom", "Signature at Bottom",
2838 F_SIG_AT_BOTTOM, h_config_sig_at_bottom, PREF_RPLY, 0},
2839 {"strip-from-sigdashes-on-reply", "Strip From Sigdashes on Reply",
2840 F_ENABLE_STRIP_SIGDASHES, h_config_strip_sigdashes, PREF_RPLY, 0},
2841 {"forward-as-attachment", "Forward messages as attachments",
2842 F_FORWARD_AS_ATTACHMENT, h_config_forward_as_attachment, PREF_RPLY, 0},
2843 {"preserve-original-fields", NULL,
2844 F_PRESERVE_ORIGINAL_FIELD, h_config_preserve_field, PREF_RPLY, 0},
2846 /* Sending Prefs */
2847 {"disable-sender", "Do Not Generate Sender Header",
2848 F_DISABLE_SENDER, h_config_disable_sender, PREF_SEND, 0},
2849 {"use-sender-not-x-sender", "Use Sender Instead of X-X-Sender",
2850 F_USE_SENDER_NOT_X, h_config_use_sender_not_x, PREF_SEND, 0},
2851 {"quell-flowed-text", "Do Not Send Flowed Text",
2852 F_QUELL_FLOWED_TEXT, h_config_quell_flowed_text, PREF_SEND, 0},
2853 {"downgrade-multipart-to-text", "Downgrade Multipart to Text",
2854 F_COMPOSE_ALWAYS_DOWNGRADE, h_downgrade_multipart_to_text, PREF_SEND, 0},
2855 {"enable-8bit-esmtp-negotiation", "Enable 8bit ESMTP Negotiation",
2856 F_ENABLE_8BIT, h_config_8bit_smtp, PREF_SEND, 1},
2857 #ifdef BACKGROUND_POST
2858 {"enable-background-sending", NULL,
2859 F_BACKGROUND_POST, h_config_compose_bg_post, PREF_SEND, 0},
2860 #endif
2861 {"enable-delivery-status-notification", NULL,
2862 F_DSN, h_config_compose_dsn, PREF_SEND, 0},
2863 {"enable-verbose-smtp-posting", "Enable Verbose SMTP Posting",
2864 F_VERBOSE_POST, h_config_verbose_post, PREF_SEND, 0},
2865 {"fcc-without-attachments", "Fcc Does Not Include Attachments",
2866 F_NO_FCC_ATTACH, h_config_no_fcc_attach, PREF_SEND, 0},
2867 {"fcc-on-bounce", "Include Fcc When Bouncing Messages",
2868 F_FCC_ON_BOUNCE, h_config_fcc_on_bounce, PREF_SEND, 0},
2869 {"mark-fcc-seen", NULL,
2870 F_MARK_FCC_SEEN, h_config_mark_fcc_seen, PREF_SEND, 0},
2871 {"fcc-only-without-confirm", "Send to Fcc Only Without Confirming",
2872 F_AUTO_FCC_ONLY, h_config_auto_fcc_only, PREF_SEND, 0},
2873 {"send-without-confirm", "Send Without Confirming",
2874 F_SEND_WO_CONFIRM, h_config_send_wo_confirm, PREF_SEND, 0},
2875 {"strip-whitespace-before-send", "Strip Whitespace Before Sending",
2876 F_STRIP_WS_BEFORE_SEND, h_config_strip_ws_before_send, PREF_SEND, 0},
2877 {"warn-if-blank-fcc", "Warn if Blank Fcc",
2878 F_WARN_ABOUT_NO_FCC, h_config_warn_if_fcc_blank, PREF_SEND, 0},
2879 {"warn-if-blank-subject", "Warn if Blank Subject",
2880 F_WARN_ABOUT_NO_SUBJECT, h_config_warn_if_subj_blank, PREF_SEND, 0},
2881 {"warn-if-blank-to-and-cc-and-newsgroups", "Warn if Blank To and CC and Newsgroups",
2882 F_WARN_ABOUT_NO_TO_OR_CC, h_config_warn_if_no_to_or_cc, PREF_SEND, 0},
2884 /* Folder */
2885 {"combined-folder-display", NULL,
2886 F_CMBND_FOLDER_DISP, h_config_combined_folder_display, PREF_FLDR, 0},
2887 {"combined-subdirectory-display", NULL,
2888 F_CMBND_SUBDIR_DISP, h_config_combined_subdir_display, PREF_FLDR, 0},
2889 {"enable-lame-list-mode", "Compensate for Deficient IMAP servers",
2890 F_FIX_BROKEN_LIST, h_config_lame_list_mode, PREF_FLDR, 0},
2891 {"enable-dot-folders", "Enable Hidden Folders",
2892 F_ENABLE_DOT_FOLDERS, h_config_enable_dot_folders, PREF_FLDR, 0},
2893 {"enable-incoming-folders", "Enable Incoming Folders Collection",
2894 F_ENABLE_INCOMING, h_config_enable_incoming, PREF_FLDR, 0},
2895 {"enable-incoming-folders-checking", NULL,
2896 F_ENABLE_INCOMING_CHECKING, h_config_enable_incoming_checking, PREF_FLDR, 0},
2897 {"incoming-checking-includes-total", NULL,
2898 F_INCOMING_CHECKING_TOTAL, h_config_incoming_checking_total, PREF_FLDR, 0},
2899 {"incoming-checking-uses-recent", NULL,
2900 F_INCOMING_CHECKING_RECENT, h_config_incoming_checking_recent, PREF_FLDR, 0},
2901 {"expanded-view-of-folders", "Expanded View of Folders",
2902 F_EXPANDED_FOLDERS, h_config_expanded_folders, PREF_FLDR, 0},
2903 {"quell-empty-directories", "Hide Empty Directories",
2904 F_QUELL_EMPTY_DIRS, h_config_quell_empty_dirs, PREF_FLDR, 0},
2905 {"separate-folder-and-directory-entries", "Separate Folder and Directory Entries",
2906 F_SEPARATE_FLDR_AS_DIR, h_config_separate_fold_dir_view, PREF_FLDR, 0},
2907 {"single-column-folder-list", NULL,
2908 F_SINGLE_FOLDER_LIST, h_config_single_list, PREF_FLDR, 0},
2909 {"sort-default-fcc-alpha", "Sort Default Fcc Folder Alphabetically",
2910 F_SORT_DEFAULT_FCC_ALPHA, h_config_sort_fcc_alpha, PREF_FLDR, 0},
2911 {"sort-default-save-alpha", "Sort Default Save Folder Alphabetically",
2912 F_SORT_DEFAULT_SAVE_ALPHA, h_config_sort_save_alpha, PREF_FLDR, 0},
2913 {"vertical-folder-list", "Use Vertical Folder List",
2914 F_VERTICAL_FOLDER_LIST, h_config_vertical_list, PREF_FLDR, 0},
2916 /* Addr book */
2917 {"combined-addrbook-display", "Combined Address Book Display",
2918 F_CMBND_ABOOK_DISP, h_config_combined_abook_display, PREF_ADDR, 0},
2919 {"expanded-view-of-addressbooks", "Expanded View of Address Books",
2920 F_EXPANDED_ADDRBOOKS, h_config_expanded_addrbooks, PREF_ADDR, 0},
2921 {"expanded-view-of-distribution-lists", "Expanded View of Distribution Lists",
2922 F_EXPANDED_DISTLISTS, h_config_expanded_distlists, PREF_ADDR, 0},
2923 #ifdef ENABLE_LDAP
2924 {"ldap-result-to-addrbook-add", "LDAP Result to Addressbook Add",
2925 F_ADD_LDAP_TO_ABOOK, h_config_add_ldap, PREF_ADDR, 0},
2926 #endif
2928 /* Index prefs */
2929 {"auto-open-next-unread", NULL,
2930 F_AUTO_OPEN_NEXT_UNREAD, h_config_auto_open_unread, PREF_INDX, 0},
2931 {"continue-tab-without-confirm", "Continue NextNew Without Confirming",
2932 F_TAB_NO_CONFIRM, h_config_tab_no_prompt, PREF_INDX, 0},
2933 {"convert-dates-to-localtime", NULL,
2934 F_DATES_TO_LOCAL, h_config_dates_to_local, PREF_INDX, 0},
2935 {"delete-skips-deleted", NULL,
2936 F_DEL_SKIPS_DEL, h_config_del_skips_del, PREF_INDX, 1},
2937 {"disable-index-locale-dates", NULL,
2938 F_DISABLE_INDEX_LOCALE_DATES, h_config_disable_index_locale_dates, PREF_INDX, 0},
2939 {"enable-cruise-mode", NULL,
2940 F_ENABLE_SPACE_AS_TAB, h_config_cruise_mode, PREF_INDX, 0},
2941 {"enable-cruise-mode-delete", "Enable Cruise Mode With Deleting",
2942 F_ENABLE_TAB_DELETES, h_config_cruise_mode_delete, PREF_INDX, 0},
2943 {"mark-for-cc", "Mark for CC",
2944 F_MARK_FOR_CC, h_config_mark_for_cc, PREF_INDX, 1},
2945 {"next-thread-without-confirm", "Read Next Thread Without Confirming",
2946 F_NEXT_THRD_WO_CONFIRM, h_config_next_thrd_wo_confirm, PREF_INDX, 0},
2947 {"return-to-inbox-without-confirm", "Return to INBOX Without Confirming",
2948 F_RET_INBOX_NO_CONFIRM, h_config_inbox_no_confirm, PREF_INDX, 0},
2949 {"show-sort", "Show Sort in Titlebar",
2950 F_SHOW_SORT, h_config_show_sort, PREF_INDX, 0},
2951 {"tab-uses-unseen-for-next-folder", "Tab Uses Unseen for Next Folder",
2952 F_TAB_USES_UNSEEN, h_config_tab_uses_unseen, PREF_INDX, 0},
2953 {"tab-visits-next-new-message-only", NULL,
2954 F_TAB_TO_NEW, h_config_tab_new_only, PREF_INDX, 0},
2955 {"thread-index-shows-important-color", NULL,
2956 F_COLOR_LINE_IMPORTANT, h_config_color_thrd_import, PREF_INDX, 0},
2957 {"thread-sorts-by-arrival", "Thread Sorts by Arrival",
2958 F_THREAD_SORTS_BY_ARRIVAL, h_config_thread_sorts_by_arrival, PREF_INDX, 0},
2960 /* Viewer prefs */
2961 {"enable-msg-view-addresses", "Enable Message View Address Links",
2962 F_SCAN_ADDR, h_config_enable_view_addresses, PREF_VIEW, 0},
2963 {"enable-msg-view-attachments", "Enable Message View Attachment Links",
2964 F_VIEW_SEL_ATTACH, h_config_enable_view_attach, PREF_VIEW, 0},
2965 {"enable-msg-view-urls", "Enable Message View URL Links",
2966 F_VIEW_SEL_URL, h_config_enable_view_url, PREF_VIEW, 1},
2967 {"enable-msg-view-web-hostnames", "Enable Message View Web Hostname Links",
2968 F_VIEW_SEL_URL_HOST, h_config_enable_view_web_host, PREF_VIEW, 1},
2969 {"enable-msg-view-forced-arrows", "Enable Message View Forced Arrows",
2970 F_FORCE_ARROWS, h_config_enable_view_arrows, PREF_VIEW, 0},
2971 /* set to TRUE for windows */
2972 {"pass-c1-control-characters-as-is", NULL,
2973 F_PASS_C1_CONTROL_CHARS, h_config_pass_c1_control, PREF_VIEW, 0},
2974 {"pass-control-characters-as-is", NULL,
2975 F_PASS_CONTROL_CHARS, h_config_pass_control, PREF_VIEW, 0},
2976 {"prefer-plain-text", NULL,
2977 F_PREFER_PLAIN_TEXT, h_config_prefer_plain_text, PREF_VIEW, 0},
2978 {"quell-charset-warning", "Suppress Character Set Warning",
2979 F_QUELL_CHARSET_WARNING, h_config_quell_charset_warning, PREF_VIEW, 0},
2980 {"quell-server-after-link-in-html", "Suppress Server After Link in HTML",
2981 F_QUELL_HOST_AFTER_URL, h_config_quell_host_after_url, PREF_VIEW, 0},
2983 /* News */
2984 {"compose-sets-newsgroup-without-confirm", "Compose Sets Newsgroup Without Confirming",
2985 F_COMPOSE_TO_NEWSGRP, h_config_compose_news_wo_conf, PREF_NEWS, 0},
2986 {"enable-8bit-nntp-posting", "Enable 8bit NNTP Posting",
2987 F_ENABLE_8BIT_NNTP, h_config_8bit_nntp, PREF_NEWS, 0},
2988 {"enable-multiple-newsrcs", NULL,
2989 F_ENABLE_MULNEWSRCS, h_config_enable_mulnewsrcs, PREF_NEWS, 0},
2990 {"mult-newsrc-hostnames-as-typed", "Multiple Newsrc Hostnames as Typed",
2991 F_MULNEWSRC_HOSTNAMES_AS_TYPED, h_config_mulnews_as_typed, PREF_NEWS, 0},
2992 {"hide-nntp-path", "Hide NNTP Path",
2993 F_HIDE_NNTP_PATH, h_config_hide_nntp_path, PREF_NEWS, 0},
2994 {"news-approximates-new-status", NULL,
2995 F_FAKE_NEW_IN_NEWS, h_config_news_uses_recent, PREF_NEWS, 1},
2996 {"news-deletes-across-groups", NULL,
2997 F_NEWS_CROSS_DELETE, h_config_news_cross_deletes, PREF_NEWS, 0},
2998 {"news-offers-catchup-on-close", "News Offers Catchup on Close",
2999 F_NEWS_CATCHUP, h_config_news_catchup, PREF_NEWS, 0},
3000 {"news-post-without-validation", NULL,
3001 F_NO_NEWS_VALIDATION, h_config_post_wo_validation, PREF_NEWS, 0},
3002 {"news-read-in-newsrc-order", "News Read in Newsrc Order",
3003 F_READ_IN_NEWSRC_ORDER, h_config_read_in_newsrc_order, PREF_NEWS, 0},
3004 {"nntp-search-uses-overview", "NNTP Search Uses Overview",
3005 F_NNTP_SEARCH_USES_OVERVIEW, h_config_nntp_search_uses_overview, PREF_NEWS, 1},
3006 {"predict-nntp-server", "Predict NNTP Server",
3007 F_PREDICT_NNTP_SERVER, h_config_predict_nntp_server, PREF_NEWS, 0},
3008 {"quell-extra-post-prompt", "Suppress Extra Posting Prompt",
3009 F_QUELL_EXTRA_POST_PROMPT, h_config_quell_post_prompt, PREF_NEWS, 0},
3011 /* Print */
3012 {"enable-print-via-y-command", NULL,
3013 F_ENABLE_PRYNT, h_config_enable_y_print, PREF_PRNT, 0},
3014 {"print-formfeed-between-messages", NULL,
3015 F_AGG_PRINT_FF, h_config_ff_between_msgs, PREF_PRNT, 0},
3016 {"print-includes-from-line", NULL,
3017 F_FROM_DELIM_IN_PRINT, h_config_print_from, PREF_PRNT, 0},
3018 {"print-index-enabled", NULL,
3019 F_PRINT_INDEX, h_config_print_index, PREF_PRNT, 0},
3020 {"print-offers-custom-cmd-prompt", "Print Offers Custom Command Prompt",
3021 F_CUSTOM_PRINT, h_config_custom_print, PREF_PRNT, 0},
3023 /* adv cmd prefs */
3024 {"enable-aggregate-command-set", NULL,
3025 F_ENABLE_AGG_OPS, h_config_enable_agg_ops, PREF_ACMD, 1},
3026 {"enable-arrow-navigation", NULL,
3027 F_ARROW_NAV, h_config_arrow_nav, PREF_ACMD, 1},
3028 {"enable-arrow-navigation-relaxed", NULL,
3029 F_RELAXED_ARROW_NAV, h_config_relaxed_arrow_nav, PREF_ACMD, 1},
3030 {"enable-bounce-cmd", "Enable Bounce Command",
3031 F_ENABLE_BOUNCE, h_config_enable_bounce, PREF_ACMD, 1},
3032 {"enable-exit-via-lessthan-command", NULL,
3033 F_ENABLE_LESSTHAN_EXIT, h_config_enable_lessthan_exit, PREF_ACMD, 1},
3034 {"enable-flag-cmd", "Enable Flag Command",
3035 F_ENABLE_FLAG, h_config_enable_flag, PREF_ACMD, 1},
3036 {"enable-flag-screen-implicitly", NULL,
3037 F_FLAG_SCREEN_DFLT, h_config_flag_screen_default, PREF_ACMD, 0},
3038 {"enable-flag-screen-keyword-shortcut", NULL,
3039 F_FLAG_SCREEN_KW_SHORTCUT, h_config_flag_screen_kw_shortcut,PREF_ACMD, 1},
3040 {"enable-full-header-and-text", "Enable Full Header and Text",
3041 F_ENABLE_FULL_HDR_AND_TEXT, h_config_enable_full_hdr_and_text, PREF_ACMD, 0},
3042 {"enable-full-header-cmd", "Enable Full Header Command",
3043 F_ENABLE_FULL_HDR, h_config_enable_full_hdr, PREF_ACMD, 1},
3044 {"enable-goto-in-file-browser", "Enable Goto in File Browser",
3045 F_ALLOW_GOTO, h_config_allow_goto, PREF_ACMD, 1},
3046 {"enable-jump-shortcut", NULL,
3047 F_ENABLE_JUMP, h_config_enable_jump, PREF_ACMD, 1},
3048 {"enable-partial-match-lists", NULL,
3049 F_ENABLE_SUB_LISTS, h_config_sub_lists, PREF_ACMD, 1},
3050 {"enable-tab-completion", NULL,
3051 F_ENABLE_TAB_COMPLETE, h_config_enable_tab_complete, PREF_ACMD, 1},
3052 {"enable-unix-pipe-cmd", "Enable Unix Pipe Command",
3053 F_ENABLE_PIPE, h_config_enable_pipe, PREF_ACMD, 1},
3054 {"quell-full-header-auto-reset", "Suppress Full Header Auto Reset",
3055 F_QUELL_FULL_HDR_RESET, h_config_quell_full_hdr_reset, PREF_ACMD, 0},
3057 /* Adv user prefs */
3058 #if !defined(DOS) && !defined(OS2)
3059 {"allow-talk", NULL,
3060 F_ALLOW_TALK, h_config_allow_talk, PREF_MISC, 0},
3061 #endif
3062 {"assume-slow-link", NULL,
3063 F_FORCE_LOW_SPEED, h_config_force_low_speed, PREF_OS_LWSD, 0},
3064 {"auto-move-read-msgs", "Auto Move Read Messages",
3065 F_AUTO_READ_MSGS, h_config_auto_read_msgs, PREF_MISC, 0},
3066 {"auto-unselect-after-apply", NULL,
3067 F_AUTO_UNSELECT, h_config_auto_unselect, PREF_MISC, 0},
3068 {"auto-unzoom-after-apply", NULL,
3069 F_AUTO_UNZOOM, h_config_auto_unzoom, PREF_MISC, 1},
3070 {"auto-zoom-after-select", NULL,
3071 F_AUTO_ZOOM, h_config_auto_zoom, PREF_MISC, 1},
3072 {"busy-cue-spinner-only", NULL,
3073 F_USE_BORING_SPINNER, h_config_use_boring_spinner, PREF_MISC, 0},
3074 {"check-newmail-when-quitting", NULL,
3075 F_CHECK_MAIL_ONQUIT, h_config_check_mail_onquit, PREF_MISC, 0},
3076 {"confirm-role-even-for-default", "Confirm Role Even for Default",
3077 F_ROLE_CONFIRM_DEFAULT, h_config_confirm_role, PREF_MISC, 0},
3078 {"disable-keymenu", NULL,
3079 F_BLANK_KEYMENU, h_config_blank_keymenu, PREF_MISC, 0},
3080 {"disable-password-caching", NULL,
3081 F_DISABLE_PASSWORD_CACHING, h_config_disable_password_caching,
3082 PREF_MISC, 0},
3083 #ifdef PASSFILE
3084 {"disable-password-file-saving", NULL,
3085 F_DISABLE_PASSWORD_FILE_SAVING, h_config_disable_password_file_saving,
3086 PREF_MISC, 0},
3087 #endif
3088 {"disable-regular-expression-matching-for-alternate-addresses", NULL,
3089 F_DISABLE_REGEX, h_config_disable_regex, PREF_MISC, 0},
3090 {"disable-save-input-history", NULL,
3091 F_DISABLE_SAVE_INPUT_HISTORY, h_config_input_history, PREF_MISC, 0},
3092 {"disable-take-fullname-in-addresses", "Disable Take Fullname in Addresses",
3093 F_DISABLE_TAKE_FULLNAMES, h_config_take_fullname, PREF_MISC, 0},
3094 {"disable-take-last-comma-first", NULL,
3095 F_DISABLE_TAKE_LASTFIRST, h_config_take_lastfirst, PREF_MISC, 0},
3096 {"disable-terminal-reset-for-display-filters", "Disable Terminal Reset for Display Filters",
3097 F_DISABLE_TERM_RESET_DISP, h_config_disable_reset_disp, PREF_MISC, 0},
3098 {"enable-dot-files", NULL,
3099 F_ENABLE_DOT_FILES, h_config_enable_dot_files, PREF_MISC, 0},
3100 {"enable-fast-recent-test", NULL,
3101 F_ENABLE_FAST_RECENT, h_config_fast_recent, PREF_MISC, 0},
3102 {"enable-mail-check-cue", NULL,
3103 F_SHOW_DELAY_CUE, h_config_show_delay_cue, PREF_MISC, 0},
3104 {"enable-mailcap-param-substitution", "Enable Mailcap Parameter Substitution",
3105 F_DO_MAILCAP_PARAM_SUBST, h_config_mailcap_params, PREF_MISC, 0},
3106 {"enable-mouse-in-xterm", "Enable Mouse in Xterm",
3107 F_ENABLE_MOUSE, h_config_enable_mouse, PREF_OS_MOUSE, 0},
3108 {"enable-newmail-in-xterm-icon", "Enable Newmail in Xterm Icon",
3109 F_ENABLE_XTERM_NEWMAIL, h_config_enable_xterm_newmail, PREF_OS_XNML, 0},
3110 {"enable-newmail-short-text-in-icon", "Enable Newmail Short Text in Icon",
3111 F_ENABLE_NEWMAIL_SHORT_TEXT, h_config_enable_newmail_short_text, PREF_OS_XNML, 0},
3112 {"enable-suspend", NULL,
3113 F_CAN_SUSPEND, h_config_can_suspend, PREF_MISC, 0},
3114 {"enable-take-export", NULL,
3115 F_ENABLE_TAKE_EXPORT, h_config_enable_take_export, PREF_MISC, 0},
3116 {"enable-rules-under-take", "Enable Take Rules",
3117 F_ENABLE_ROLE_TAKE, h_config_enable_role_take, PREF_MISC, 0},
3118 #ifdef _WINDOWS
3119 {"enable-tray-icon", NULL,
3120 F_ENABLE_TRAYICON, h_config_tray_icon, PREF_MISC, 0},
3121 #endif
3122 {"expose-hidden-config", NULL,
3123 F_EXPOSE_HIDDEN_CONFIG, h_config_expose_hidden_config, PREF_MISC, 0},
3124 {"expunge-only-manually", NULL,
3125 F_EXPUNGE_MANUALLY, h_config_expunge_manually, PREF_MISC, 0},
3126 {"expunge-without-confirm", "Expunge Without Confirming",
3127 F_AUTO_EXPUNGE, h_config_auto_expunge, PREF_MISC, 0},
3128 {"expunge-without-confirm-everywhere", "Expunge Without Confirming Everywhere",
3129 F_FULL_AUTO_EXPUNGE, h_config_full_auto_expunge, PREF_MISC, 0},
3130 {"force-arrow-cursor", NULL,
3131 F_FORCE_ARROW, h_config_force_arrow, PREF_MISC, 0},
3132 {"maildrops-preserve-state", NULL,
3133 F_MAILDROPS_PRESERVE_STATE, h_config_maildrops_preserve_state,
3134 PREF_MISC, 0},
3135 {"offer-expunge-of-inbox", "Offer Expunge of INBOX",
3136 F_EXPUNGE_INBOX, h_config_expunge_inbox, PREF_MISC, 0},
3137 {"offer-expunge-of-stayopen-folders", "Offer Expunge of Stayopen Folders",
3138 F_EXPUNGE_STAYOPENS, h_config_expunge_stayopens, PREF_MISC, 0},
3139 {"preopen-stayopen-folders", NULL,
3140 F_PREOPEN_STAYOPENS, h_config_preopen_stayopens, PREF_MISC, 0},
3141 {"preserve-start-stop-characters", "Preserve Start/Stop Characters",
3142 F_PRESERVE_START_STOP, h_config_preserve_start_stop, PREF_OS_STSP, 0},
3143 {"quell-folder-internal-msg", "Prevent Folder Internal Message",
3144 F_QUELL_INTERNAL_MSG, h_config_quell_folder_internal_msg, PREF_MISC, 0},
3145 {"quell-partial-fetching", "Prevent Partial Fetching",
3146 F_QUELL_PARTIAL_FETCH, h_config_quell_partial, PREF_MISC, 0},
3147 {"prune-uses-yyyy-mm", "Prune Uses YYYY-MM",
3148 F_PRUNE_USES_ISO, h_config_prune_uses_iso, PREF_MISC, 0},
3149 {"quit-without-confirm", "Quit Without Confirming",
3150 F_QUIT_WO_CONFIRM, h_config_quit_wo_confirm, PREF_MISC, 0},
3151 {"quote-replace-nonflowed", NULL,
3152 F_QUOTE_REPLACE_NOFLOW, h_config_quote_replace_noflow, PREF_MISC, 0},
3153 {"save-aggregates-copy-sequence", "Save Combines Copies (may be out of order)",
3154 F_AGG_SEQ_COPY, h_config_save_aggregates, PREF_MISC, 1},
3155 {"save-partial-msg-without-confirm", "Save Partial Message Without Confirming",
3156 F_SAVE_PARTIAL_WO_CONFIRM, h_config_save_part_wo_confirm, PREF_MISC, 0},
3157 {"save-will-advance", NULL,
3158 F_SAVE_ADVANCES, h_config_save_advances, PREF_MISC, 0},
3159 {"save-will-not-delete", NULL,
3160 F_SAVE_WONT_DELETE, h_config_save_wont_delete, PREF_MISC, 0},
3161 {"save-will-quote-leading-froms", NULL,
3162 F_QUOTE_ALL_FROMS, h_config_quote_all_froms, PREF_MISC, 0},
3163 {"scramble-message-id", "Scramble the Message-ID When Sending",
3164 F_ROT13_MESSAGE_ID, h_config_scramble_message_id, PREF_MISC, 0},
3165 {"select-without-confirm", "Select Ctrl-T Foldername Without Confirming",
3166 F_SELECT_WO_CONFIRM, h_config_select_wo_confirm, PREF_MISC, 0},
3167 {"show-cursor", NULL,
3168 F_SHOW_CURSOR, h_config_show_cursor, PREF_MISC, 0},
3169 {"show-plain-text-internally", NULL,
3170 F_SHOW_TEXTPLAIN_INT, h_config_textplain_int, PREF_MISC, 0},
3171 {"show-selected-in-boldface", "Show Selected in Boldface",
3172 F_SELECTED_SHOWN_BOLD, h_config_select_in_bold, PREF_MISC, 0},
3173 {"slash-collapses-entire-thread", NULL,
3174 F_SLASH_COLL_ENTIRE, h_config_slash_coll_entire, PREF_MISC, 0},
3175 #ifdef _WINDOWS
3176 {"store-window-position-in-config", "Store Window Position in Config",
3177 F_STORE_WINPOS_IN_CONFIG, h_config_winpos_in_config, PREF_MISC, 0},
3178 #endif
3179 {"suppress-asterisks-in-password-prompt", "Suppress Asterisks in Password Prompt",
3180 F_QUELL_ASTERISKS, h_config_quell_asterisks,
3181 PREF_MISC, 0},
3182 {"quell-attachment-extension-warn", "Suppress Attachment Extension Warning",
3183 F_QUELL_ATTACH_EXT_WARN, h_config_quell_attach_ext_warn,
3184 PREF_MISC, 0},
3185 {"quell-attachment-extra-prompt", "Suppress Attachment Extra Prompt",
3186 F_QUELL_ATTACH_EXTRA_PROMPT, h_config_quell_attach_extra_prompt,
3187 PREF_MISC, 0},
3188 {"quell-berkeley-format-timezone", "Suppress Berkeley Format Timezone",
3189 F_QUELL_BEZERK_TIMEZONE, h_config_no_bezerk_zone, PREF_MISC, 0},
3190 {"quell-content-id", "Suppress Content-ID",
3191 F_QUELL_CONTENT_ID, h_config_quell_content_id, PREF_MISC, 0},
3192 {"quell-filtering-done-message", "Suppress Filtering Done Message",
3193 F_QUELL_FILTER_DONE_MSG, h_config_quell_filtering_done_message,
3194 PREF_MISC, 0},
3195 {"quell-filtering-messages", "Suppress Filtering Messages",
3196 F_QUELL_FILTER_MSGS, h_config_quell_filtering_messages,
3197 PREF_MISC, 0},
3198 {"quell-imap-envelope-update", "Suppress IMAP Envelope Update",
3199 F_QUELL_IMAP_ENV_CB, h_config_quell_imap_env, PREF_MISC, 0},
3200 {"quell-lock-failure-warnings", "Suppress Lock Failure Warnings",
3201 F_QUELL_LOCK_FAILURE_MSGS, h_config_quell_lock_failure_warnings,
3202 PREF_MISC, 0},
3203 {"quell-maildomain-warning", "Suppress Maildomain Warning",
3204 F_QUELL_MAILDOMAIN_WARNING, h_config_quell_domain_warn, PREF_MISC, 0},
3205 {"quell-news-envelope-update", "Suppress News Envelope Update",
3206 F_QUELL_NEWS_ENV_CB, h_config_quell_news_env, PREF_MISC, 0},
3207 #ifdef _WINDOWS
3208 {"quell-ssl-largeblocks", "Prevent SSL Largeblocks",
3209 F_QUELL_SSL_LARGEBLOCKS, h_config_quell_ssl_largeblocks, PREF_MISC, 0},
3210 #endif
3211 {"quell-status-message-beeping", "Suppress Status Message Beeping",
3212 F_QUELL_BEEPS, h_config_quell_beeps, PREF_MISC, 0},
3213 {"quell-timezone-comment-when-sending", "Suppress Timezone Comment When Sending",
3214 F_QUELL_TIMEZONE, h_config_quell_tz_comment, PREF_MISC, 0},
3215 {"suppress-user-agent-when-sending", NULL,
3216 F_QUELL_USERAGENT, h_config_suppress_user_agent, PREF_MISC, 0},
3217 {"tab-checks-recent", "Tab Checks for Recent Messages",
3218 F_TAB_CHK_RECENT, h_config_tab_checks_recent, PREF_MISC, 0},
3219 {"termdef-takes-precedence", NULL,
3220 F_TCAP_WINS, h_config_termcap_wins, PREF_MISC, 0},
3221 {"try-alternative-authentication-driver-first", NULL,
3222 F_PREFER_ALT_AUTH, h_config_alt_auth, PREF_MISC, 0},
3223 {"unselect-will-not-advance", NULL,
3224 F_UNSELECT_WONT_ADVANCE, h_config_unsel_wont_advance, PREF_MISC, 0},
3225 {"use-current-dir", "Use Current Directory",
3226 F_USE_CURRENT_DIR, h_config_use_current_dir, PREF_MISC, 0},
3227 {"use-function-keys", NULL,
3228 F_USE_FK, h_config_use_fk, PREF_OS_USFK, 0},
3229 {"use-regular-startup-rule-for-stayopen-folders", "Use Regular Startup Rule for Stayopen Folders",
3230 F_STARTUP_STAYOPEN, h_config_use_reg_start_for_stayopen, PREF_MISC, 0},
3231 {"use-resent-to-in-rules", "Use Resent-To in Rules",
3232 F_USE_RESENTTO, h_config_use_resentto, PREF_MISC, 0},
3233 {"use-subshell-for-suspend", "Use Subshell for Suspend",
3234 F_SUSPEND_SPAWNS, h_config_suspend_spawns, PREF_OS_SPWN, 0},
3235 #ifndef _WINDOWS
3236 {"use-system-translation", NULL,
3237 F_USE_SYSTEM_TRANS, h_config_use_system_translation, PREF_MISC, 0},
3238 #endif
3240 /* Hidden Features */
3241 {"old-growth", NULL,
3242 F_OLD_GROWTH, NO_HELP, PREF_NONE, 0},
3243 {"disable-config-cmd", NULL,
3244 F_DISABLE_CONFIG_SCREEN, h_config_disable_config_cmd, PREF_HIDDEN, 0},
3245 {"disable-keyboard-lock-cmd", NULL,
3246 F_DISABLE_KBLOCK_CMD, h_config_disable_kb_lock, PREF_HIDDEN, 0},
3247 {"disable-password-cmd", NULL,
3248 F_DISABLE_PASSWORD_CMD, h_config_disable_password_cmd, PREF_HIDDEN, 0},
3249 {"disable-pipes-in-sigs", NULL,
3250 F_DISABLE_PIPES_IN_SIGS, h_config_disable_pipes_in_sigs, PREF_HIDDEN, 0},
3251 {"disable-pipes-in-templates", NULL,
3252 F_DISABLE_PIPES_IN_TEMPLATES, h_config_disable_pipes_in_templates,
3253 PREF_HIDDEN, 0},
3254 {"disable-roles-setup-cmd", NULL,
3255 F_DISABLE_ROLES_SETUP, h_config_disable_roles_setup, PREF_HIDDEN, 0},
3256 {"disable-roles-sig-edit", NULL,
3257 F_DISABLE_ROLES_SIGEDIT, h_config_disable_roles_sigedit, PREF_HIDDEN, 0},
3258 {"disable-roles-template-edit", NULL,
3259 F_DISABLE_ROLES_TEMPLEDIT, h_config_disable_roles_templateedit,
3260 PREF_HIDDEN, 0},
3261 {"disable-setlocale-collate", NULL,
3262 F_DISABLE_SETLOCALE_COLLATE, h_config_disable_collate, PREF_HIDDEN, 0},
3263 {"disable-shared-namespaces", NULL,
3264 F_DISABLE_SHARED_NAMESPACES, h_config_disable_shared, PREF_HIDDEN, 0},
3265 {"disable-signature-edit-cmd", NULL,
3266 F_DISABLE_SIGEDIT_CMD, h_config_disable_signature_edit, PREF_HIDDEN, 0},
3267 {"new-thread-on-blank-subject", "New Thread on Blank Subject",
3268 F_NEW_THREAD_ON_BLANK_SUBJECT, h_config_new_thread_blank_subject, PREF_HIDDEN, 1},
3269 {"quell-personal-name-prompt", NULL,
3270 F_QUELL_PERSONAL_NAME_PROMPT, h_config_quell_personal_name_prompt, PREF_HIDDEN, 0},
3271 {"quell-user-id-prompt", "Quell User ID Prompt",
3272 F_QUELL_USER_ID_PROMPT, h_config_quell_user_id_prompt, PREF_HIDDEN, 0},
3273 #ifdef SMIME
3274 {"smime-dont-do-smime", "S/MIME -- Turn off S/MIME",
3275 F_DONT_DO_SMIME, h_config_smime_dont_do_smime, PREF_HIDDEN, 0},
3276 {"smime-encrypt-by-default", "S/MIME -- Encrypt by Default",
3277 F_ENCRYPT_DEFAULT_ON, h_config_smime_encrypt_by_default, PREF_HIDDEN, 0},
3278 {"smime-remember-passphrase", "S/MIME -- Remember S/MIME Passphrase",
3279 F_REMEMBER_SMIME_PASSPHRASE, h_config_smime_remember_passphrase, PREF_HIDDEN, 0},
3280 {"smime-sign-by-default", "S/MIME -- Sign by Default",
3281 F_SIGN_DEFAULT_ON, h_config_smime_sign_by_default, PREF_HIDDEN, 0},
3282 {"smime-use-store-only", "S/MIME -- Validate Using Certificate Store Only",
3283 F_USE_CERT_STORE_ONLY, h_config_smime_use_cert_store, PREF_HIDDEN, 1},
3284 #ifdef APPLEKEYCHAIN
3285 {"publiccerts-in-keychain", "S/MIME -- Public Certs in MacOS Keychain",
3286 F_PUBLICCERTS_IN_KEYCHAIN, h_config_smime_pubcerts_in_keychain, PREF_HIDDEN, 0},
3287 #endif
3288 #endif
3289 {"selectable-item-nobold", NULL,
3290 F_SLCTBL_ITEM_NOBOLD, NO_HELP, PREF_NONE, 0},
3291 {"send-confirms-only-expanded", NULL, /* exposed in Web Alpine */
3292 F_SEND_CONFIRM_ON_EXPAND, h_config_send_confirms_only_expanded, PREF_HIDDEN, 0},
3293 {"enable-jump-cmd", NULL, /* exposed in Web Alpine */
3294 F_ENABLE_JUMP_CMD, h_config_enable_jump_command, PREF_HIDDEN, 0},
3295 {"enable-newmail-sound", NULL, /* exposed in Web Alpine */
3296 F_ENABLE_NEWMAIL_SOUND, h_config_enable_newmail_sound, PREF_HIDDEN, 0},
3297 {"render-html-internally", NULL, /* exposed in Web Alpine */
3298 F_RENDER_HTML_INTERNALLY, h_config_render_html_internally, PREF_HIDDEN, 0}
3301 return((index >= 0 && index < (sizeof(feat_list)/sizeof(feat_list[0])))
3302 ? &feat_list[index] : NULL);
3307 * feature_list_index -- return index of given feature id in
3308 * feature list
3311 feature_list_index(int id)
3313 FEATURE_S *feature;
3314 int i;
3316 for(i = 0; (feature = feature_list(i)); i++)
3317 if(id == feature->id)
3318 return(i);
3320 return(-1);
3325 * feature_list_name -- return the given feature id's corresponding name
3327 char *
3328 feature_list_name(int id)
3330 FEATURE_S *f;
3332 return((f = feature_list(feature_list_index(id))) ? f->name : "");
3337 feature_list_id(char *name)
3339 FEATURE_S *f;
3340 int i;
3342 for(i = 0; (f = feature_list(i)); i++)
3343 if(!strucmp(f->name, name))
3344 return(f->id);
3346 return(-1);
3351 * feature_list_help -- return the given feature id's corresponding help
3353 HelpType
3354 feature_list_help(int id)
3356 FEATURE_S *f;
3358 return((f = feature_list(feature_list_index(id))) ? f->help : NO_HELP);
3363 * All the arguments past "list" are the backwards compatibility hacks.
3365 void
3366 process_feature_list(struct pine *ps, char **list, int old_growth, int hir, int osr)
3368 register char *q;
3369 char **p,
3370 *lvalue[BM_SIZE * 8];
3371 int i,
3372 yorn;
3373 long l;
3374 FEATURE_S *feat;
3377 /* clear all previous settings and reset them to default */
3378 for(i = 0; (feat = feature_list(i)) != NULL; i++)
3379 F_SET(feat->id, ps, feat->defval);
3381 /* backwards compatibility */
3382 if(hir)
3383 F_TURN_ON(F_INCLUDE_HEADER, ps);
3385 /* ditto */
3386 if(osr)
3387 F_TURN_ON(F_SIG_AT_BOTTOM, ps);
3389 /* ditto */
3390 if(old_growth)
3391 set_old_growth_bits(ps, 0);
3393 /* now run through the list (global, user, and cmd_line lists are here) */
3394 if(list){
3395 for(p = list; (q = *p) != NULL; p++){
3396 if(struncmp(q, "no-", 3) == 0){
3397 yorn = 0;
3398 q += 3;
3399 }else{
3400 yorn = 1;
3403 for(i = 0; (feat = feature_list(i)) != NULL; i++){
3404 if(strucmp(q, feat->name) == 0){
3405 if(feat->id == F_OLD_GROWTH){
3406 set_old_growth_bits(ps, yorn);
3407 }else{
3408 F_SET(feat->id, ps, yorn);
3410 break;
3414 /* if it wasn't in that list */
3415 if(feat == NULL)
3416 dprint((1,"Unrecognized feature in feature-list (%s%s)\n",
3417 (yorn ? "" : "no-"), q ? q : "?"));
3422 * Turn on gratuitous '>From ' quoting, if requested...
3424 mail_parameters(NULL, SET_FROMWIDGET,
3425 F_ON(F_QUOTE_ALL_FROMS, ps) ? VOIDT : NIL);
3428 * Turn off .lock creation complaints...
3430 if(F_ON(F_QUELL_LOCK_FAILURE_MSGS, ps))
3431 mail_parameters(NULL, SET_LOCKEACCESERROR, (void *) 0);
3434 * Turn on quelling of pseudo message.
3436 if(F_ON(F_QUELL_INTERNAL_MSG,ps_global))
3437 mail_parameters(NULL, SET_USERHASNOLIFE, (void *) 1);
3439 l = F_ON(F_MULNEWSRC_HOSTNAMES_AS_TYPED,ps_global) ? 0L : 1L;
3440 mail_parameters(NULL, SET_NEWSRCCANONHOST, (void *) l);
3442 ps->pass_ctrl_chars = F_ON(F_PASS_CONTROL_CHARS,ps_global) ? 1 : 0;
3443 ps->pass_c1_ctrl_chars = F_ON(F_PASS_C1_CONTROL_CHARS,ps_global) ? 1 : 0;
3445 #ifndef _WINDOWS
3446 if(F_ON(F_QUELL_BEZERK_TIMEZONE,ps_global))
3447 mail_parameters(NULL, SET_NOTIMEZONES, (void *) 1);
3448 #endif
3450 if(F_ON(F_USE_FK, ps))
3451 ps->orig_use_fkeys = 1;
3453 /* Will we have to build a new list? */
3454 if(!(old_growth || hir || osr))
3455 return;
3458 * Build a new list for feature-list. The only reason we ever need to
3459 * do this is if one of the obsolete options is being converted
3460 * into a feature-list item, and it isn't already included in the user's
3461 * feature-list.
3463 i = 0;
3464 for(p = LVAL(&ps->vars[V_FEATURE_LIST], Main);
3465 p && (q = *p); p++){
3466 /* already have it or cancelled it, don't need to add later */
3467 if(hir && (strucmp(q, "include-header-in-reply") == 0 ||
3468 strucmp(q, "no-include-header-in-reply") == 0)){
3469 hir = 0;
3470 }else if(osr && (strucmp(q, "signature-at-bottom") == 0 ||
3471 strucmp(q, "no-signature-at-bottom") == 0)){
3472 osr = 0;
3473 }else if(old_growth && (strucmp(q, "old-growth") == 0 ||
3474 strucmp(q, "no-old-growth") == 0)){
3475 old_growth = 0;
3477 lvalue[i++] = cpystr(q);
3480 /* check to see if we still need to build a new list */
3481 if(!(old_growth || hir || osr))
3482 return;
3484 if(hir)
3485 lvalue[i++] = "include-header-in-reply";
3486 if(osr)
3487 lvalue[i++] = "signature-at-bottom";
3488 if(old_growth)
3489 lvalue[i++] = "old-growth";
3490 lvalue[i] = NULL;
3491 set_variable_list(V_FEATURE_LIST, lvalue, TRUE, Main);
3495 void
3496 set_current_pattern_vals(struct pine *ps)
3498 struct variable *vars = ps->vars;
3500 set_current_val(&vars[V_PATTERNS], TRUE, TRUE);
3501 set_current_val(&vars[V_PAT_ROLES], TRUE, TRUE);
3502 set_current_val(&vars[V_PAT_FILTS], TRUE, TRUE);
3503 set_current_val(&vars[V_PAT_FILTS_OLD], TRUE, TRUE);
3504 set_current_val(&vars[V_PAT_SCORES], TRUE, TRUE);
3505 set_current_val(&vars[V_PAT_SCORES_OLD], TRUE, TRUE);
3506 set_current_val(&vars[V_PAT_INCOLS], TRUE, TRUE);
3507 set_current_val(&vars[V_PAT_OTHER], TRUE, TRUE);
3508 set_current_val(&vars[V_PAT_SRCH], TRUE, TRUE);
3511 * If old pattern variable (V_PATTERNS) is set and the new ones aren't
3512 * in the config file, then convert the old data into the new variables.
3513 * It isn't quite that simple, though, because we don't store unset
3514 * variables in remote pinercs. Check for the variables but if we
3515 * don't find any of them, also check the version number. This change was
3516 * made in version 4.30. We could just check that except that we're
3517 * worried somebody will make an incompatible version number change in
3518 * their local version, and will break this. So we check both the
3519 * version # and the var_in_pinerc things to be safer.
3521 if(vars[V_PATTERNS].current_val.l
3522 && vars[V_PATTERNS].current_val.l[0]
3523 && !var_in_pinerc(vars[V_PAT_ROLES].name)
3524 && !var_in_pinerc(vars[V_PAT_FILTS].name)
3525 && !var_in_pinerc(vars[V_PAT_FILTS_OLD].name)
3526 && !var_in_pinerc(vars[V_PAT_SCORES].name)
3527 && !var_in_pinerc(vars[V_PAT_SCORES_OLD].name)
3528 && !var_in_pinerc(vars[V_PAT_INCOLS].name)
3529 && isdigit((unsigned char) ps->pine_pre_vers[0])
3530 && ps->pine_pre_vers[1] == '.'
3531 && isdigit((unsigned char) ps->pine_pre_vers[2])
3532 && isdigit((unsigned char) ps->pine_pre_vers[3])
3533 && strncmp(ps->pine_pre_vers, "4.30", 4) < 0){
3534 convert_pattern_data();
3538 * Otherwise, if FILTS_OLD is set and FILTS isn't in the config file,
3539 * convert FILTS_OLD to FILTS. Same for SCORES.
3540 * The reason FILTS was changed was so we could change the
3541 * semantics of how rules work when there are pieces in the rule that
3542 * we don't understand. At the same time as the FILTS change we added
3543 * a rule to detect 8bitSubjects. So a user might have a filter that
3544 * deletes messages with 8bitSubjects. The problem is that that same
3545 * filter in a FILTS_OLD pine would match because it would ignore the
3546 * 8bitSubject part of the pattern and match on the rest. So we changed
3547 * the semantics so that rules with unknown bits would be ignored
3548 * instead of used. We had to change variable names at the same time
3549 * because we were adding the 8bit thing and the old pines are still
3550 * out there. Filters and Scores can both be dangerous. Roles, Colors,
3551 * and Other seem less dangerous so not worth adding a new variable.
3552 * This was changed in 4.50.
3554 else{
3555 if(vars[V_PAT_FILTS_OLD].current_val.l
3556 && vars[V_PAT_FILTS_OLD].current_val.l[0]
3557 && !var_in_pinerc(vars[V_PAT_FILTS].name)
3558 && !var_in_pinerc(vars[V_PAT_SCORES].name)
3559 && isdigit((unsigned char) ps->pine_pre_vers[0])
3560 && ps->pine_pre_vers[1] == '.'
3561 && isdigit((unsigned char) ps->pine_pre_vers[2])
3562 && isdigit((unsigned char) ps->pine_pre_vers[3])
3563 && strncmp(ps->pine_pre_vers, "4.50", 4) < 0){
3564 convert_filts_pattern_data();
3567 if(vars[V_PAT_SCORES_OLD].current_val.l
3568 && vars[V_PAT_SCORES_OLD].current_val.l[0]
3569 && !var_in_pinerc(vars[V_PAT_FILTS].name)
3570 && !var_in_pinerc(vars[V_PAT_SCORES].name)
3571 && isdigit((unsigned char) ps->pine_pre_vers[0])
3572 && ps->pine_pre_vers[1] == '.'
3573 && isdigit((unsigned char) ps->pine_pre_vers[2])
3574 && isdigit((unsigned char) ps->pine_pre_vers[3])
3575 && strncmp(ps->pine_pre_vers, "4.50", 4) < 0){
3576 convert_scores_pattern_data();
3580 if(vars[V_PAT_ROLES].post_user_val.l)
3581 ps_global->ew_for_role_take = Post;
3582 else
3583 ps_global->ew_for_role_take = Main;
3585 if(vars[V_PAT_FILTS].post_user_val.l)
3586 ps_global->ew_for_filter_take = Post;
3587 else
3588 ps_global->ew_for_filter_take = Main;
3590 if(vars[V_PAT_SCORES].post_user_val.l)
3591 ps_global->ew_for_score_take = Post;
3592 else
3593 ps_global->ew_for_score_take = Main;
3595 if(vars[V_PAT_INCOLS].post_user_val.l)
3596 ps_global->ew_for_incol_take = Post;
3597 else
3598 ps_global->ew_for_incol_take = Main;
3600 if(vars[V_PAT_OTHER].post_user_val.l)
3601 ps_global->ew_for_other_take = Post;
3602 else
3603 ps_global->ew_for_other_take = Main;
3605 if(vars[V_PAT_SRCH].post_user_val.l)
3606 ps_global->ew_for_srch_take = Post;
3607 else
3608 ps_global->ew_for_srch_take = Main;
3613 * Foreach of the config files;
3614 * transfer the data to the new variables.
3616 void
3617 convert_pattern_data(void)
3619 convert_pinerc_patterns(PAT_USE_MAIN);
3620 convert_pinerc_patterns(PAT_USE_POST);
3624 void
3625 convert_filts_pattern_data(void)
3627 convert_pinerc_filts_patterns(PAT_USE_MAIN);
3628 convert_pinerc_filts_patterns(PAT_USE_POST);
3632 void
3633 convert_scores_pattern_data(void)
3635 convert_pinerc_scores_patterns(PAT_USE_MAIN);
3636 convert_pinerc_scores_patterns(PAT_USE_POST);
3641 * Foreach of the four variables, transfer the data for this config file
3642 * from the old patterns variable. We don't have to convert OTHER patterns
3643 * or SRCH patterns because they didn't exist in pines without patterns-other.
3645 * If the original variable had patlines with type File then we convert
3646 * all of the individual patterns to type Lit, because each pattern can
3647 * be of any category. Lit patterns are better tested, anyway.
3649 void
3650 convert_pinerc_patterns(long int use_flags)
3652 long old_rflags;
3653 long rflags;
3654 PAT_S *pat;
3655 PAT_STATE pstate;
3656 ACTION_S *act;
3658 old_rflags = (ROLE_OLD_PAT | use_flags);
3660 rflags = 0L;
3661 if(any_patterns(old_rflags, &pstate)){
3662 dprint((2, "converting old patterns to new (%s)\n", (use_flags == PAT_USE_MAIN) ? "Main" : "Post"));
3663 for(pat = first_pattern(&pstate);
3664 pat;
3665 pat = next_pattern(&pstate)){
3666 if((act = pat->action) != NULL){
3667 if(act->is_a_role &&
3668 add_to_pattern(pat, ROLE_DO_ROLES | use_flags))
3669 rflags |= ROLE_DO_ROLES;
3670 if(act->is_a_incol &&
3671 add_to_pattern(pat, ROLE_DO_INCOLS | use_flags))
3672 rflags |= ROLE_DO_INCOLS;
3673 if(act->is_a_score &&
3674 add_to_pattern(pat, ROLE_DO_SCORES | use_flags))
3675 rflags |= ROLE_DO_SCORES;
3676 if(act->is_a_filter &&
3677 add_to_pattern(pat, ROLE_DO_FILTER | use_flags))
3678 rflags |= ROLE_DO_FILTER;
3682 if(rflags)
3683 if(write_patterns(rflags | use_flags))
3684 dprint((1,
3685 "Trouble converting patterns to new variable\n"));
3691 * If the original variable had patlines with type File then we convert
3692 * all of the individual patterns to type Lit, because each pattern can
3693 * be of any category. Lit patterns are better tested, anyway.
3695 void
3696 convert_pinerc_filts_patterns(long int use_flags)
3698 long old_rflags;
3699 long rflags;
3700 PAT_S *pat;
3701 PAT_STATE pstate;
3702 ACTION_S *act;
3704 old_rflags = (ROLE_OLD_FILT | use_flags);
3706 rflags = 0L;
3707 if(any_patterns(old_rflags, &pstate)){
3708 dprint((2, "converting old filter patterns to new (%s)\n", (use_flags == PAT_USE_MAIN) ? "Main" : "Post"));
3709 for(pat = first_pattern(&pstate);
3710 pat;
3711 pat = next_pattern(&pstate)){
3712 if((act = pat->action) != NULL){
3713 if(act->is_a_filter &&
3714 add_to_pattern(pat, ROLE_DO_FILTER | use_flags))
3715 rflags |= ROLE_DO_FILTER;
3719 if(rflags)
3720 if(write_patterns(rflags | use_flags))
3721 dprint((1,
3722 "Trouble converting filter patterns to new variable\n"));
3728 * If the original variable had patlines with type File then we convert
3729 * all of the individual patterns to type Lit, because each pattern can
3730 * be of any category. Lit patterns are better tested, anyway.
3732 void
3733 convert_pinerc_scores_patterns(long int use_flags)
3735 long old_rflags;
3736 long rflags;
3737 PAT_S *pat;
3738 PAT_STATE pstate;
3739 ACTION_S *act;
3741 old_rflags = (ROLE_OLD_SCORE | use_flags);
3743 rflags = 0L;
3744 if(any_patterns(old_rflags, &pstate)){
3745 dprint((2, "converting old scores patterns to new (%s)\n", (use_flags == PAT_USE_MAIN) ? "Main" : "Post"));
3746 for(pat = first_pattern(&pstate);
3747 pat;
3748 pat = next_pattern(&pstate)){
3749 if((act = pat->action) != NULL){
3750 if(act->is_a_score &&
3751 add_to_pattern(pat, ROLE_DO_SCORES | use_flags))
3752 rflags |= ROLE_DO_SCORES;
3756 if(rflags)
3757 if(write_patterns(rflags | use_flags))
3758 dprint((1,
3759 "Trouble converting scores patterns to new variable\n"));
3765 * set_old_growth_bits - Command used to set or unset old growth set
3766 * of features
3768 void
3769 set_old_growth_bits(struct pine *ps, int val)
3771 int i;
3773 for(i = 1; i <= F_FEATURE_LIST_COUNT; i++)
3774 if(test_old_growth_bits(ps, i))
3775 F_SET(i, ps, val);
3781 * test_old_growth_bits - Test to see if all the old growth bits are on,
3782 * *or* if a particular feature index is in the old
3783 * growth set.
3785 * WEIRD ALERT: if index == F_OLD_GROWTH bit values are tested
3786 * otherwise a bits existence in the set is tested!!!
3788 * BUG: this will break if an old growth feature number is ever >= 32.
3791 test_old_growth_bits(struct pine *ps, int index)
3794 * this list defines F_OLD_GROWTH set
3796 static unsigned long old_growth_bits = ((1 << F_ENABLE_FULL_HDR) |
3797 (1 << F_ENABLE_PIPE) |
3798 (1 << F_ENABLE_TAB_COMPLETE) |
3799 (1 << F_QUIT_WO_CONFIRM) |
3800 (1 << F_ENABLE_JUMP) |
3801 (1 << F_ENABLE_ALT_ED) |
3802 (1 << F_ENABLE_BOUNCE) |
3803 (1 << F_ENABLE_AGG_OPS) |
3804 (1 << F_ENABLE_FLAG) |
3805 (1 << F_CAN_SUSPEND));
3806 if(index >= 32)
3807 return(0);
3809 if(index == F_OLD_GROWTH){
3810 for(index = 1; index <= F_FEATURE_LIST_COUNT; index++)
3811 if(((1 << index) & old_growth_bits) && F_OFF(index, ps))
3812 return(0);
3814 return(1);
3816 else
3817 return((1 << index) & old_growth_bits);
3822 * Side effect is that the appropriate global variable is set, and the
3823 * appropriate current_val is set.
3825 void
3826 cur_rule_value(struct variable *var, int expand, int cmdline)
3828 int i;
3829 NAMEVAL_S *v;
3831 set_current_val(var, expand, cmdline);
3833 if(var == &ps_global->vars[V_SAVED_MSG_NAME_RULE]){
3834 if(ps_global->VAR_SAVED_MSG_NAME_RULE)
3835 for(i = 0; (v = save_msg_rules(i)); i++)
3836 if(!strucmp(ps_global->VAR_SAVED_MSG_NAME_RULE, S_OR_L(v))){
3837 ps_global->save_msg_rule = v->value;
3838 break;
3841 #ifndef _WINDOWS
3842 else if(var == &ps_global->vars[V_COLOR_STYLE]){
3843 if(ps_global->VAR_COLOR_STYLE)
3844 for(i = 0; (v = col_style(i)); i++)
3845 if(!strucmp(ps_global->VAR_COLOR_STYLE, S_OR_L(v))){
3846 ps_global->color_style = v->value;
3847 break;
3850 #endif
3851 else if(var == &ps_global->vars[V_INDEX_COLOR_STYLE]){
3852 if(ps_global->VAR_INDEX_COLOR_STYLE)
3853 for(i = 0; (v = index_col_style(i)); i++)
3854 if(!strucmp(ps_global->VAR_INDEX_COLOR_STYLE, S_OR_L(v))){
3855 ps_global->index_color_style = v->value;
3856 break;
3859 else if(var == &ps_global->vars[V_TITLEBAR_COLOR_STYLE]){
3860 if(ps_global->VAR_TITLEBAR_COLOR_STYLE)
3861 for(i = 0; (v = titlebar_col_style(i)); i++)
3862 if(!strucmp(ps_global->VAR_TITLEBAR_COLOR_STYLE, S_OR_L(v))){
3863 ps_global->titlebar_color_style = v->value;
3864 break;
3867 else if(var == &ps_global->vars[V_FCC_RULE]){
3868 if(ps_global->VAR_FCC_RULE)
3869 for(i = 0; (v = fcc_rules(i)); i++)
3870 if(!strucmp(ps_global->VAR_FCC_RULE, S_OR_L(v))){
3871 ps_global->fcc_rule = v->value;
3872 break;
3875 else if(var == &ps_global->vars[V_GOTO_DEFAULT_RULE]){
3876 if(ps_global->VAR_GOTO_DEFAULT_RULE)
3877 for(i = 0; (v = goto_rules(i)); i++)
3878 if(!strucmp(ps_global->VAR_GOTO_DEFAULT_RULE, S_OR_L(v))){
3879 ps_global->goto_default_rule = v->value;
3880 break;
3883 else if(var == &ps_global->vars[V_INCOMING_STARTUP]){
3884 if(ps_global->VAR_INCOMING_STARTUP)
3885 for(i = 0; (v = incoming_startup_rules(i)); i++)
3886 if(!strucmp(ps_global->VAR_INCOMING_STARTUP, S_OR_L(v))){
3887 ps_global->inc_startup_rule = v->value;
3888 break;
3891 else if(var == &ps_global->vars[V_PRUNING_RULE]){
3892 if(ps_global->VAR_PRUNING_RULE)
3893 for(i = 0; (v = pruning_rules(i)); i++)
3894 if(!strucmp(ps_global->VAR_PRUNING_RULE, S_OR_L(v))){
3895 ps_global->pruning_rule = v->value;
3896 break;
3899 else if(var == &ps_global->vars[V_REOPEN_RULE]){
3900 if(ps_global->VAR_REOPEN_RULE)
3901 for(i = 0; (v = reopen_rules(i)); i++)
3902 if(!strucmp(ps_global->VAR_REOPEN_RULE, S_OR_L(v))){
3903 ps_global->reopen_rule = v->value;
3904 break;
3907 else if(var == &ps_global->vars[V_FLD_SORT_RULE]){
3908 if(ps_global->VAR_FLD_SORT_RULE)
3909 for(i = 0; (v = fld_sort_rules(i)); i++)
3910 if(!strucmp(ps_global->VAR_FLD_SORT_RULE, S_OR_L(v))){
3911 ps_global->fld_sort_rule = v->value;
3912 break;
3915 else if(var == &ps_global->vars[V_AB_SORT_RULE]){
3916 if(ps_global->VAR_AB_SORT_RULE)
3917 for(i = 0; (v = ab_sort_rules(i)); i++)
3918 if(!strucmp(ps_global->VAR_AB_SORT_RULE, S_OR_L(v))){
3919 ps_global->ab_sort_rule = v->value;
3920 break;
3923 else if(var == &ps_global->vars[V_THREAD_DISP_STYLE]){
3924 if(ps_global->VAR_THREAD_DISP_STYLE)
3925 for(i = 0; (v = thread_disp_styles(i)); i++)
3926 if(!strucmp(ps_global->VAR_THREAD_DISP_STYLE, S_OR_L(v))){
3927 ps_global->thread_disp_style = v->value;
3928 break;
3931 else if(var == &ps_global->vars[V_THREAD_INDEX_STYLE]){
3932 if(ps_global->VAR_THREAD_INDEX_STYLE)
3933 for(i = 0; (v = thread_index_styles(i)); i++)
3934 if(!strucmp(ps_global->VAR_THREAD_INDEX_STYLE, S_OR_L(v))){
3935 ps_global->thread_index_style = v->value;
3936 break;
3943 * Standard way to get at save message rules...
3945 NAMEVAL_S *
3946 save_msg_rules(int index)
3948 static NAMEVAL_S save_rules[] = {
3949 {"by-from", NULL, SAV_RULE_FROM},
3950 {"by-nick-of-from", NULL, SAV_RULE_NICK_FROM_DEF},
3951 {"by-nick-of-from-then-from", NULL, SAV_RULE_NICK_FROM},
3952 {"by-fcc-of-from", NULL, SAV_RULE_FCC_FROM_DEF},
3953 {"by-fcc-of-from-then-from", NULL, SAV_RULE_FCC_FROM},
3954 {"by-realname-of-from", NULL, SAV_RULE_RN_FROM_DEF},
3955 {"by-realname-of-from-then-from", NULL, SAV_RULE_RN_FROM},
3956 {"by-sender", NULL, SAV_RULE_SENDER},
3957 {"by-nick-of-sender", NULL, SAV_RULE_NICK_SENDER_DEF},
3958 {"by-nick-of-sender-then-sender", NULL, SAV_RULE_NICK_SENDER},
3959 {"by-fcc-of-sender", NULL, SAV_RULE_FCC_SENDER_DEF},
3960 {"by-fcc-of-sender-then-sender", NULL, SAV_RULE_FCC_SENDER},
3961 {"by-realname-of-sender", NULL, SAV_RULE_RN_SENDER_DEF},
3962 {"by-realname-of-sender-then-sender", NULL, SAV_RULE_RN_SENDER},
3963 {"by-recipient", NULL, SAV_RULE_RECIP},
3964 {"by-nick-of-recip", NULL, SAV_RULE_NICK_RECIP_DEF},
3965 {"by-nick-of-recip-then-recip", NULL, SAV_RULE_NICK_RECIP},
3966 {"by-fcc-of-recip", NULL, SAV_RULE_FCC_RECIP_DEF},
3967 {"by-fcc-of-recip-then-recip", NULL, SAV_RULE_FCC_RECIP},
3968 {"by-realname-of-recip", NULL, SAV_RULE_RN_RECIP_DEF},
3969 {"by-realname-of-recip-then-recip", NULL, SAV_RULE_RN_RECIP},
3970 {"by-replyto", NULL, SAV_RULE_REPLYTO},
3971 {"by-nick-of-replyto", NULL, SAV_RULE_NICK_REPLYTO_DEF},
3972 {"by-nick-of-replyto-then-replyto", NULL, SAV_RULE_NICK_REPLYTO},
3973 {"by-fcc-of-replyto", NULL, SAV_RULE_FCC_REPLYTO_DEF},
3974 {"by-fcc-of-replyto-then-replyto", NULL, SAV_RULE_FCC_REPLYTO},
3975 {"by-realname-of-replyto", NULL, SAV_RULE_RN_REPLYTO_DEF},
3976 {"by-realname-of-replyto-then-replyto", NULL, SAV_RULE_RN_REPLYTO},
3977 {"last-folder-used", NULL, SAV_RULE_LAST},
3978 {"default-folder", NULL, SAV_RULE_DEFLT}
3981 return((index >= 0 && index < (sizeof(save_rules)/sizeof(save_rules[0])))
3982 ? &save_rules[index] : NULL);
3987 * Standard way to get at fcc rules...
3989 NAMEVAL_S *
3990 fcc_rules(int index)
3992 static NAMEVAL_S f_rules[] = {
3993 {"default-fcc", NULL, FCC_RULE_DEFLT},
3994 {"last-fcc-used", NULL, FCC_RULE_LAST},
3995 {"by-recipient", NULL, FCC_RULE_RECIP},
3996 {"by-nickname", NULL, FCC_RULE_NICK},
3997 {"by-nick-then-recip", NULL, FCC_RULE_NICK_RECIP},
3998 {"current-folder", NULL, FCC_RULE_CURRENT}
4001 return((index >= 0 && index < (sizeof(f_rules)/sizeof(f_rules[0])))
4002 ? &f_rules[index] : NULL);
4007 * Standard way to get at addrbook sort rules...
4009 NAMEVAL_S *
4010 ab_sort_rules(int index)
4012 static NAMEVAL_S ab_rules[] = {
4013 {"fullname-with-lists-last", NULL, AB_SORT_RULE_FULL_LISTS},
4014 {"fullname", NULL, AB_SORT_RULE_FULL},
4015 {"nickname-with-lists-last", NULL, AB_SORT_RULE_NICK_LISTS},
4016 {"nickname", NULL, AB_SORT_RULE_NICK},
4017 {"dont-sort", NULL, AB_SORT_RULE_NONE}
4020 return((index >= 0 && index < (sizeof(ab_rules)/sizeof(ab_rules[0])))
4021 ? &ab_rules[index] : NULL);
4026 * Standard way to get at color styles.
4028 NAMEVAL_S *
4029 col_style(int index)
4031 static NAMEVAL_S col_styles[] = {
4032 {"no-color", NULL, COL_NONE},
4033 {"use-termdef", NULL, COL_TERMDEF},
4034 {"force-ansi-8color", NULL, COL_ANSI8},
4035 {"force-ansi-16color", NULL, COL_ANSI16},
4036 {"force-xterm-256color", NULL, COL_ANSI256}
4039 return((index >= 0 && index < (sizeof(col_styles)/sizeof(col_styles[0])))
4040 ? &col_styles[index] : NULL);
4045 * Standard way to get at index color styles.
4047 NAMEVAL_S *
4048 index_col_style(int index)
4050 static NAMEVAL_S ind_col_styles[] = {
4051 {"flip-colors", NULL, IND_COL_FLIP},
4052 {"reverse", NULL, IND_COL_REV},
4053 {"reverse-fg", NULL, IND_COL_FG},
4054 {"reverse-fg-no-ambiguity", NULL, IND_COL_FG_NOAMBIG},
4055 {"reverse-bg", NULL, IND_COL_BG},
4056 {"reverse-bg-no-ambiguity", NULL, IND_COL_BG_NOAMBIG}
4059 return((index >= 0 && index < (sizeof(ind_col_styles)/sizeof(ind_col_styles[0]))) ? &ind_col_styles[index] : NULL);
4064 * Standard way to get at titlebar color styles.
4066 NAMEVAL_S *
4067 titlebar_col_style(int index)
4069 static NAMEVAL_S tbar_col_styles[] = {
4070 {"default", NULL, TBAR_COLOR_DEFAULT},
4071 {"indexline", NULL, TBAR_COLOR_INDEXLINE},
4072 {"reverse-indexline", NULL, TBAR_COLOR_REV_INDEXLINE}
4075 return((index >= 0 && index < (sizeof(tbar_col_styles)/sizeof(tbar_col_styles[0]))) ? &tbar_col_styles[index] : NULL);
4080 * Standard way to get at folder sort rules...
4082 NAMEVAL_S *
4083 fld_sort_rules(int index)
4085 static NAMEVAL_S fdl_rules[] = {
4086 {"alphabetical", NULL, FLD_SORT_ALPHA},
4087 {"alpha-with-dirs-last", NULL, FLD_SORT_ALPHA_DIR_LAST},
4088 {"alpha-with-dirs-first", NULL, FLD_SORT_ALPHA_DIR_FIRST}
4091 return((index >= 0 && index < (sizeof(fdl_rules)/sizeof(fdl_rules[0])))
4092 ? &fdl_rules[index] : NULL);
4097 * Standard way to get at incoming startup rules...
4099 NAMEVAL_S *
4100 incoming_startup_rules(int index)
4102 static NAMEVAL_S is_rules[] = {
4103 {"first-unseen", NULL, IS_FIRST_UNSEEN},
4104 {"first-recent", NULL, IS_FIRST_RECENT},
4105 {"first-important", NULL, IS_FIRST_IMPORTANT},
4106 {"first-important-or-unseen", NULL, IS_FIRST_IMPORTANT_OR_UNSEEN},
4107 {"first-important-or-recent", NULL, IS_FIRST_IMPORTANT_OR_RECENT},
4108 {"first", NULL, IS_FIRST},
4109 {"last", NULL, IS_LAST}
4112 return((index >= 0 && index < (sizeof(is_rules)/sizeof(is_rules[0])))
4113 ? &is_rules[index] : NULL);
4117 NAMEVAL_S *
4118 startup_rules(int index)
4120 static NAMEVAL_S is2_rules[] = {
4121 {"first-unseen", NULL, IS_FIRST_UNSEEN},
4122 {"first-recent", NULL, IS_FIRST_RECENT},
4123 {"first-important", NULL, IS_FIRST_IMPORTANT},
4124 {"first-important-or-unseen", NULL, IS_FIRST_IMPORTANT_OR_UNSEEN},
4125 {"first-important-or-recent", NULL, IS_FIRST_IMPORTANT_OR_RECENT},
4126 {"first", NULL, IS_FIRST},
4127 {"last", NULL, IS_LAST},
4128 {"default", NULL, IS_NOTSET}
4131 return((index >= 0 && index < (sizeof(is2_rules)/sizeof(is2_rules[0])))
4132 ? &is2_rules[index] : NULL);
4137 * Standard way to get at pruning-rule values.
4139 NAMEVAL_S *
4140 pruning_rules(int index)
4142 static NAMEVAL_S pr_rules[] = {
4143 {"ask about rename, ask about deleting","ask-ask", PRUNE_ASK_AND_ASK},
4144 {"ask about rename, don't delete", "ask-no", PRUNE_ASK_AND_NO},
4145 {"always rename, ask about deleting", "yes-ask", PRUNE_YES_AND_ASK},
4146 {"always rename, don't delete", "yes-no", PRUNE_YES_AND_NO},
4147 {"don't rename, ask about deleting", "no-ask", PRUNE_NO_AND_ASK},
4148 {"don't rename, don't delete", "no-no", PRUNE_NO_AND_NO}
4151 return((index >= 0 && index < (sizeof(pr_rules)/sizeof(pr_rules[0])))
4152 ? &pr_rules[index] : NULL);
4157 * Standard way to get at reopen-rule values.
4159 NAMEVAL_S *
4160 reopen_rules(int index)
4162 static NAMEVAL_S ro_rules[] = {
4163 /* TRANSLATORS: short description of a feature option */
4164 {"Always reopen", "yes-yes",
4165 REOPEN_YES_YES},
4166 /* TRANSLATORS: short description of a feature option, default in brackets */
4167 {"Yes for POP/NNTP, Ask about other remote [Yes]", "yes-ask-y",
4168 REOPEN_YES_ASK_Y},
4169 /* TRANSLATORS: short description of a feature option, default in brackets */
4170 {"Yes for POP/NNTP, Ask about other remote [No]", "yes-ask-n",
4171 REOPEN_YES_ASK_N},
4172 /* TRANSLATORS: short description of a feature option */
4173 {"Yes for POP/NNTP, No for other remote", "yes-no",
4174 REOPEN_YES_NO},
4175 /* TRANSLATORS: short description of a feature option, default in brackets */
4176 {"Always ask [Yes]", "ask-ask-y",
4177 REOPEN_ASK_ASK_Y},
4178 /* TRANSLATORS: short description of a feature option, default in brackets */
4179 {"Always ask [No]", "ask-ask-n",
4180 REOPEN_ASK_ASK_N},
4181 /* TRANSLATORS: short description of a feature option, default in brackets */
4182 {"Ask about POP/NNTP [Yes], No for other remote", "ask-no-y",
4183 REOPEN_ASK_NO_Y},
4184 /* TRANSLATORS: short description of a feature option, default in brackets */
4185 {"Ask about POP/NNTP [No], No for other remote", "ask-no-n",
4186 REOPEN_ASK_NO_N},
4187 /* TRANSLATORS: short description of a feature option */
4188 {"Never reopen", "no-no",
4189 REOPEN_NO_NO},
4192 return((index >= 0 && index < (sizeof(ro_rules)/sizeof(ro_rules[0])))
4193 ? &ro_rules[index] : NULL);
4198 * Standard way to get at thread_disp_style values.
4200 NAMEVAL_S *
4201 thread_disp_styles(int index)
4203 static NAMEVAL_S td_styles[] = {
4204 {"none", "none", THREAD_NONE},
4205 {"show-thread-structure", "struct", THREAD_STRUCT},
4206 {"mutt-like", "mutt", THREAD_MUTTLIKE},
4207 {"indent-subject-1", "subj1", THREAD_INDENT_SUBJ1},
4208 {"indent-subject-2", "subj2", THREAD_INDENT_SUBJ2},
4209 {"indent-from-1", "from1", THREAD_INDENT_FROM1},
4210 {"indent-from-2", "from2", THREAD_INDENT_FROM2},
4211 {"show-structure-in-from", "struct-from", THREAD_STRUCT_FROM}
4214 return((index >= 0 && index < (sizeof(td_styles)/sizeof(td_styles[0])))
4215 ? &td_styles[index] : NULL);
4220 * Standard way to get at thread_index_style values.
4222 NAMEVAL_S *
4223 thread_index_styles(int index)
4225 static NAMEVAL_S ti_styles[] = {
4226 {"regular-index-with-expanded-threads", "exp", THRDINDX_EXP},
4227 {"regular-index-with-collapsed-threads","coll", THRDINDX_COLL},
4228 {"separate-index-screen-always", "sep", THRDINDX_SEP},
4229 {"separate-index-screen-except-for-single-messages","sep-auto",
4230 THRDINDX_SEP_AUTO}
4233 return((index >= 0 && index < (sizeof(ti_styles)/sizeof(ti_styles[0])))
4234 ? &ti_styles[index] : NULL);
4239 * Standard way to get at goto default rules...
4241 NAMEVAL_S *
4242 goto_rules(int index)
4244 static NAMEVAL_S g_rules[] = {
4245 {"folder-in-first-collection", NULL, GOTO_FIRST_CLCTN},
4246 {"inbox-or-folder-in-first-collection", NULL, GOTO_INBOX_FIRST_CLCTN},
4247 {"inbox-or-folder-in-recent-collection", NULL, GOTO_INBOX_RECENT_CLCTN},
4248 {"first-collection-with-inbox-default", NULL, GOTO_FIRST_CLCTN_DEF_INBOX},
4249 {"most-recent-folder", NULL, GOTO_LAST_FLDR}
4252 return((index >= 0 && index < (sizeof(g_rules)/sizeof(g_rules[0])))
4253 ? &g_rules[index] : NULL);
4257 NAMEVAL_S *
4258 pat_fldr_types(int index)
4260 static NAMEVAL_S pat_fldr_list[] = {
4261 {"Any", "ANY", FLDR_ANY},
4262 {"News", "NEWS", FLDR_NEWS},
4263 {"Email", "EMAIL", FLDR_EMAIL},
4264 {"Specific (Enter Incoming Nicknames or use ^T)", "SPEC", FLDR_SPECIFIC}
4267 return((index >= 0 &&
4268 index < (sizeof(pat_fldr_list)/sizeof(pat_fldr_list[0])))
4269 ? &pat_fldr_list[index] : NULL);
4273 NAMEVAL_S *
4274 inabook_fldr_types(int indexarg)
4276 static NAMEVAL_S inabook_fldr_list[] = {
4277 {"Don't care, always matches", "E", IAB_EITHER},
4278 {"Yes, in any address book", "YES", IAB_YES},
4279 {"No, not in any address book", "NO", IAB_NO},
4280 {"Yes, in specific address books", "SYES", IAB_SPEC_YES},
4281 {"No, not in any of specific address books", "SNO", IAB_SPEC_NO}
4284 int index = indexarg & IAB_TYPE_MASK;
4286 return((index >= 0 &&
4287 index < (sizeof(inabook_fldr_list)/sizeof(inabook_fldr_list[0])))
4288 ? &inabook_fldr_list[index] : NULL);
4292 NAMEVAL_S *
4293 filter_types(int index)
4295 static NAMEVAL_S filter_type_list[] = {
4296 {"Just Set Message Status", "NONE", FILTER_STATE},
4297 {"Delete", "DEL", FILTER_KILL},
4298 {"Move (Enter folder name(s) in primary collection, or use ^T)",
4299 "FLDR", FILTER_FOLDER}
4302 return((index >= 0 &&
4303 index < (sizeof(filter_type_list)/sizeof(filter_type_list[0])))
4304 ? &filter_type_list[index] : NULL);
4308 NAMEVAL_S *
4309 role_repl_types(int index)
4311 static NAMEVAL_S role_repl_list[] = {
4312 {"Never", "NO", ROLE_REPL_NO},
4313 {"With confirmation", "YES", ROLE_REPL_YES},
4314 {"Without confirmation", "NC", ROLE_REPL_NOCONF}
4317 return((index >= 0 &&
4318 index < (sizeof(role_repl_list)/sizeof(role_repl_list[0])))
4319 ? &role_repl_list[index] : NULL);
4323 NAMEVAL_S *
4324 role_forw_types(int index)
4326 static NAMEVAL_S role_forw_list[] = {
4327 {"Never", "NO", ROLE_FORW_NO},
4328 {"With confirmation", "YES", ROLE_FORW_YES},
4329 {"Without confirmation", "NC", ROLE_FORW_NOCONF}
4332 return((index >= 0 &&
4333 index < (sizeof(role_forw_list)/sizeof(role_forw_list[0])))
4334 ? &role_forw_list[index] : NULL);
4338 NAMEVAL_S *
4339 role_comp_types(int index)
4341 static NAMEVAL_S role_comp_list[] = {
4342 {"Never", "NO", ROLE_COMP_NO},
4343 {"With confirmation", "YES", ROLE_COMP_YES},
4344 {"Without confirmation", "NC", ROLE_COMP_NOCONF}
4347 return((index >= 0 &&
4348 index < (sizeof(role_comp_list)/sizeof(role_comp_list[0])))
4349 ? &role_comp_list[index] : NULL);
4353 NAMEVAL_S *
4354 role_status_types(int index)
4356 static NAMEVAL_S role_status_list[] = {
4357 {"Don't care, always matches", "E", PAT_STAT_EITHER},
4358 {"Yes", "YES", PAT_STAT_YES},
4359 {"No", "NO", PAT_STAT_NO}
4362 return((index >= 0 &&
4363 index < (sizeof(role_status_list)/sizeof(role_status_list[0])))
4364 ? &role_status_list[index] : NULL);
4368 NAMEVAL_S *
4369 msg_state_types(int index)
4371 static NAMEVAL_S msg_state_list[] = {
4372 {"Don't change it", "LV", ACT_STAT_LEAVE},
4373 {"Set this state", "SET", ACT_STAT_SET},
4374 {"Clear this state", "CLR", ACT_STAT_CLEAR}
4377 return((index >= 0 &&
4378 index < (sizeof(msg_state_list)/sizeof(msg_state_list[0])))
4379 ? &msg_state_list[index] : NULL);
4383 #ifdef ENABLE_LDAP
4384 NAMEVAL_S *
4385 ldap_search_rules(int index)
4387 static NAMEVAL_S ldap_search_list[] = {
4388 {"contains", NULL, LDAP_SRCH_CONTAINS},
4389 {"equals", NULL, LDAP_SRCH_EQUALS},
4390 {"begins-with", NULL, LDAP_SRCH_BEGINS},
4391 {"ends-with", NULL, LDAP_SRCH_ENDS}
4394 return((index >= 0 &&
4395 index < (sizeof(ldap_search_list)/sizeof(ldap_search_list[0])))
4396 ? &ldap_search_list[index] : NULL);
4400 NAMEVAL_S *
4401 ldap_search_types(int index)
4403 static NAMEVAL_S ldap_types_list[] = {
4404 {"name", NULL, LDAP_TYPE_CN},
4405 {"surname", NULL, LDAP_TYPE_SUR},
4406 {"givenname", NULL, LDAP_TYPE_GIVEN},
4407 {"email", NULL, LDAP_TYPE_EMAIL},
4408 {"name-or-email", NULL, LDAP_TYPE_CN_EMAIL},
4409 {"surname-or-givenname", NULL, LDAP_TYPE_SUR_GIVEN},
4410 {"sur-or-given-or-name-or-email", NULL, LDAP_TYPE_SEVERAL}
4413 return((index >= 0 &&
4414 index < (sizeof(ldap_types_list)/sizeof(ldap_types_list[0])))
4415 ? &ldap_types_list[index] : NULL);
4419 NAMEVAL_S *
4420 ldap_search_scope(int index)
4422 static NAMEVAL_S ldap_scope_list[] = {
4423 {"base", NULL, LDAP_SCOPE_BASE},
4424 {"onelevel", NULL, LDAP_SCOPE_ONELEVEL},
4425 {"subtree", NULL, LDAP_SCOPE_SUBTREE}
4428 return((index >= 0 &&
4429 index < (sizeof(ldap_scope_list)/sizeof(ldap_scope_list[0])))
4430 ? &ldap_scope_list[index] : NULL);
4432 #endif
4436 * Choose from the global default, command line args, pinerc values to set
4437 * the actual value of the variable that we will use. Start at the top
4438 * and work down from higher to lower precedence.
4439 * For lists, we may inherit values from lower precedence
4440 * versions if that's the way the user specifies it.
4441 * The user can put INHERIT_DEFAULT as the first entry in a list and that
4442 * means it will inherit the current values, for example the values
4443 * from the global_val, or the value from the main_user_val could be
4444 * inherited in the post_user_val.
4446 void
4447 set_current_val(struct variable *var, int expand, int cmdline)
4449 int is_set[5], is_inherit[5];
4450 int i, j, k, cnt, start;
4451 char **tmp, **t, **list[5];
4452 char *p;
4454 dprint((9,
4455 "set_current_val(var=%s%s, expand=%d, cmdline=%d)\n",
4456 (var && var->name) ? var->name : "?",
4457 (var && var->is_list) ? " (list)" : "",
4458 expand, cmdline));
4460 if(!var)
4461 return;
4463 if(var->is_list){ /* variable is a list */
4465 for(j = 0; j < 5; j++){
4466 t = j==0 ? var->global_val.l :
4467 j==1 ? var->main_user_val.l :
4468 j==2 ? var->post_user_val.l :
4469 j==3 ? ((cmdline) ? var->cmdline_val.l : NULL) :
4470 var->fixed_val.l;
4472 is_set[j] = is_inherit[j] = 0;
4473 list[j] = NULL;
4475 if(t){
4476 if(!expand){
4477 is_set[j]++;
4478 list[j] = t;
4480 else{
4481 for(i = 0; t[i]; i++){
4482 if(expand_variables(tmp_20k_buf, SIZEOF_20KBUF, t[i],
4483 0)){
4484 /* successful expand */
4485 is_set[j]++;
4486 list[j] = t;
4487 break;
4492 if(list[j] && list[j][0] && !strcmp(list[j][0],INHERIT))
4493 is_inherit[j]++;
4497 cnt = 0;
4498 start = 0;
4499 /* count how many items in current_val list */
4500 /* Admin wants default, which is global_val. */
4501 if(var->is_fixed && var->fixed_val.l == NULL){
4502 cnt = 0;
4503 if(is_set[0]){
4504 for(; list[0][cnt]; cnt++)
4508 else{
4509 for(j = 0; j < 5; j++){
4510 if(is_set[j]){
4511 if(!is_inherit[j]){
4512 cnt = 0; /* reset */
4513 start = j;
4516 for(i = is_inherit[j] ? 1 : 0; list[j][i]; i++)
4517 cnt++;
4522 free_list_array(&var->current_val.l); /* clean up any old values */
4524 /* check to see if anything is set */
4525 if(is_set[0] + is_set[1] + is_set[2] + is_set[3] + is_set[4] > 0){
4526 var->current_val.l = (char **)fs_get((cnt+1)*sizeof(char *));
4527 tmp = var->current_val.l;
4528 if(var->is_fixed && var->fixed_val.l == NULL){
4529 if(is_set[0]){
4530 for(i = 0; list[0][i]; i++){
4531 if(!expand)
4532 *tmp++ = cpystr(list[0][i]);
4533 else if(expand_variables(tmp_20k_buf, SIZEOF_20KBUF,
4534 list[0][i], 0))
4535 *tmp++ = cpystr(tmp_20k_buf);
4539 else{
4540 for(j = start; j < 5; j++){
4541 if(is_set[j]){
4542 for(i = is_inherit[j] ? 1 : 0; list[j][i]; i++){
4543 if(!expand)
4544 *tmp++ = cpystr(list[j][i]);
4545 else if(expand_variables(tmp_20k_buf,SIZEOF_20KBUF,
4546 list[j][i], 0))
4547 *tmp++ = cpystr(tmp_20k_buf);
4553 *tmp = NULL;
4555 else
4556 var->current_val.l = NULL;
4558 else{ /* variable is not a list */
4559 char *strvar = NULL;
4561 for(j = 0; j < 5; j++){
4563 p = j==0 ? var->fixed_val.p :
4564 j==1 ? ((cmdline) ? var->cmdline_val.p : NULL) :
4565 j==2 ? var->post_user_val.p :
4566 j==3 ? var->main_user_val.p :
4567 var->global_val.p;
4569 is_set[j] = 0;
4571 if(p){
4572 if(!expand){
4573 is_set[j]++;
4574 if(!strvar)
4575 strvar = p;
4577 else if(expand_variables(tmp_20k_buf, SIZEOF_20KBUF, p,
4578 (var == &ps_global->vars[V_MAILCAP_PATH] ||
4579 var == &ps_global->vars[V_MIMETYPE_PATH]))){
4580 is_set[j]++;
4581 if(!strvar)
4582 strvar = p;
4587 /* Admin wants default, which is global_val. */
4588 if(var->is_fixed && var->fixed_val.p == NULL)
4589 strvar = var->global_val.p;
4591 if(var->current_val.p) /* free previous value */
4592 fs_give((void **)&var->current_val.p);
4594 if(strvar){
4595 if(!expand)
4596 var->current_val.p = cpystr(strvar);
4597 else{
4598 expand_variables(tmp_20k_buf, SIZEOF_20KBUF, strvar,
4599 (var == &ps_global->vars[V_MAILCAP_PATH] ||
4600 var == &ps_global->vars[V_MIMETYPE_PATH]));
4601 var->current_val.p = cpystr(tmp_20k_buf);
4604 else
4605 var->current_val.p = NULL;
4608 if(var->is_fixed && !is_inherit[4]){
4609 char **flist;
4610 int fixed_len, user_len;
4613 * sys mgr fixed this variable and user is trying to change it
4615 for(k = 1; !(ps_global->give_fixed_warning &&
4616 ps_global->fix_fixed_warning) && k <= 3; k++){
4617 if(is_set[k]){
4618 if(var->is_list){
4619 t = k==1 ? ((cmdline) ? var->cmdline_val.l : NULL) :
4620 k==2 ? var->post_user_val.l :
4621 var->main_user_val.l;
4623 /* If same length and same contents, don't warn. */
4624 for(flist=var->fixed_val.l; flist && *flist; flist++)
4625 ;/* just counting */
4627 fixed_len = var->fixed_val.l ? (flist - var->fixed_val.l)
4628 : 0;
4629 for(flist=t; flist && *flist; flist++)
4630 ;/* just counting */
4632 user_len = t ? (flist - t) : 0;
4633 if(user_len == fixed_len){
4634 for(i=0; i < user_len; i++){
4635 for(j=0; j < user_len; j++)
4636 if(!strucmp(t[i], var->fixed_val.l[j]))
4637 break;
4639 if(j == user_len){
4640 ps_global->give_fixed_warning = 1;
4641 if(k != 1)
4642 ps_global->fix_fixed_warning = 1;
4644 break;
4648 else{
4649 ps_global->give_fixed_warning = 1;
4650 if(k != 1)
4651 ps_global->fix_fixed_warning = 1;
4654 else{
4655 p = k==1 ? ((cmdline) ? var->cmdline_val.p : NULL) :
4656 k==2 ? var->post_user_val.p :
4657 var->main_user_val.p;
4659 if((var->fixed_val.p && !p) ||
4660 (!var->fixed_val.p && p) ||
4661 (var->fixed_val.p && p && strucmp(var->fixed_val.p, p))){
4662 ps_global->give_fixed_warning = 1;
4663 if(k != 1)
4664 ps_global->fix_fixed_warning = 1;
4673 void
4674 set_news_spec_current_val(int expand, int cmdline)
4676 struct variable *newsvar = &ps_global->vars[V_NEWS_SPEC];
4677 struct variable *fvar = &ps_global->vars[V_FOLDER_SPEC];
4679 /* check to see if it has a value */
4680 set_current_val(newsvar, expand, cmdline);
4683 * If no value, we might want to fake a value. We'll do that if
4684 * there is no news collection already defined in FOLDER_SPEC and if
4685 * there is also an NNTP_SERVER defined.
4687 if(!newsvar->current_val.l && ps_global->VAR_NNTP_SERVER &&
4688 ps_global->VAR_NNTP_SERVER[0] && ps_global->VAR_NNTP_SERVER[0][0] &&
4689 !news_in_folders(fvar)){
4690 char buf[MAXPATH];
4692 newsvar->global_val.l = (char **)fs_get(2 * sizeof(char *));
4693 snprintf(buf, sizeof(buf), "{%.*s/nntp}#news.[]", MAXPATH-20,
4694 ps_global->VAR_NNTP_SERVER[0]); /* MAXPATH = sizeof(buf) */
4695 newsvar->global_val.l[0] = cpystr(buf);
4696 newsvar->global_val.l[1] = NULL;
4697 set_current_val(newsvar, expand, cmdline);
4699 * But we're going to get rid of the fake global_val in case
4700 * things change.
4702 free_list_array(&newsvar->global_val.l);
4708 * Feature-list has to be handled separately from the other variables
4709 * because it is additive. The other variables choose one of command line,
4710 * or pine.conf, or pinerc. Feature list adds them. This could easily be
4711 * converted to a general purpose routine if we add more additive variables.
4713 * This works by replacing earlier values with later ones. That is, command
4714 * line settings have higher precedence than global settings and that is
4715 * accomplished by putting the command line features after the global
4716 * features in the list. When they are processed, the last one wins.
4718 * Feature-list also has a backwards compatibility hack.
4720 void
4721 set_feature_list_current_val(struct variable *var)
4723 char **list;
4724 char **list_fixed;
4725 char no_allow[50];
4726 int i, j, k, m,
4727 elems = 0;
4729 /* count the lists so we can allocate */
4730 for(m = 0; m < 6; m++){
4731 list = m==0 ? var->global_val.l :
4732 m==1 ? var->main_user_val.l :
4733 m==2 ? var->post_user_val.l :
4734 m==3 ? ps_global->feat_list_back_compat :
4735 m==4 ? var->cmdline_val.l :
4736 var->fixed_val.l;
4737 if(list)
4738 for(i = 0; list[i]; i++)
4739 elems++;
4742 list_fixed = var->fixed_val.l;
4744 if(var->current_val.l)
4745 free_list_array(&var->current_val.l);
4747 var->current_val.l = (char **)fs_get((elems+1) * sizeof(char *));
4750 * We need to warn the user if the sys mgr has restricted him or her
4751 * from changing a feature that he or she is trying to change.
4753 * We're not catching the old-growth macro since we're just comparing
4754 * strings. That is, it works correctly, but the user won't be warned
4755 * if the user old-growth and the mgr says no-quit-without-confirm.
4758 j = 0;
4759 strncpy(no_allow, "no-", 3);
4760 strncpy(no_allow+3, feature_list_name(F_ALLOW_CHANGING_FROM), sizeof(no_allow)-3-1);
4761 no_allow[sizeof(no_allow)-1] = '\0';
4763 for(m = 0; m < 6; m++){
4764 list = m==0 ? var->global_val.l :
4765 m==1 ? var->main_user_val.l :
4766 m==2 ? var->post_user_val.l :
4767 m==3 ? ps_global->feat_list_back_compat :
4768 m==4 ? var->cmdline_val.l :
4769 var->fixed_val.l;
4770 if(list)
4771 for(i = 0; list[i]; i++){
4772 var->current_val.l[j++] = cpystr(list[i]);
4774 /* this is the warning section */
4775 if(m >= 1 && m <= 4){
4776 for(k = 0; list_fixed && list_fixed[k]; k++){
4777 char *p, *q;
4778 p = list[i];
4779 q = list_fixed[k];
4780 if(!struncmp(p, "no-", 3))
4781 p += 3;
4782 if(!struncmp(q, "no-", 3))
4783 q += 3;
4784 if(!strucmp(q, p) && strucmp(list[i], list_fixed[k])){
4785 ps_global->give_fixed_warning = 1;
4786 if(m <= 2)
4787 ps_global->fix_fixed_warning = 1;
4791 else if(m == 5 && !strucmp(list[i], no_allow))
4792 ps_global->never_allow_changing_from = 1;
4796 #ifdef NEVER_ALLOW_CHANGING_FROM
4797 ps_global->never_allow_changing_from = 1;
4798 #endif
4800 var->current_val.l[j] = NULL;
4805 /*----------------------------------------------------------------------
4807 Expand Metacharacters/variables in file-names
4809 Read input line and expand shell-variables/meta-characters
4811 <input> <replaced by>
4812 $variable getenv("variable")
4813 ${variable} getenv("variable")
4814 ${variable:-defvalue} is getenv("variable") if variable is defined and
4815 is defvalue otherwise
4816 ~ getenv("HOME")
4817 \c c
4818 <others> <just copied>
4820 NOTE handling of braces in ${name} doesn't check much or do error recovery
4822 If colon_path is set, then we expand ~ not only at the start of linein,
4823 but also after each : in the path.
4825 ----*/
4826 #define is_allowed_envchar(C, S) ((S) == 0 ? !isspace((C)) && (C) != '/'\
4827 : (((C) >= 'a' && (C) <= 'z') \
4828 || ((C) >= 'A' && (C) <= 'Z') \
4829 || ((C) >= '0' && (C) <= '9')))
4831 char *
4832 expand_variables(char *lineout, size_t lineoutlen, char *linein, int colon_path)
4834 char *src = linein, *dest = lineout, *p;
4835 char *limit = lineout + lineoutlen;
4836 int envexpand = 0, sp;
4838 if(!linein)
4839 return(NULL);
4841 sp = strncmp(src,"LIT:pattern=\"/NICK=", strlen("LIT:pattern=\"/NICK=")) == 0;
4842 while(*src ){ /* something in input string */
4843 if(*src == '$' && *(src+1) == '$'){
4845 * $$ to escape chars we're interested in, else
4846 * it's up to the user of the variable to handle the
4847 * backslash...
4849 if(dest < limit)
4850 *dest++ = *++src; /* copy next as is */
4851 }else
4852 #if !(defined(DOS) || defined(OS2))
4853 if(*src == '\\' && *(src+1) == '$'){
4855 * backslash to escape chars we're interested in, else
4856 * it's up to the user of the variable to handle the
4857 * backslash...
4859 if(dest < limit)
4860 *dest++ = *++src; /* copy next as is */
4861 }else if(*src == '~' &&
4862 (src == linein || (colon_path && *(src-1) == ':'))){
4863 char buf[MAXPATH];
4864 int i;
4866 for(i = 0; i < sizeof(buf)-1 && src[i] && src[i] != '/'; i++)
4867 buf[i] = src[i];
4869 src += i; /* advance src pointer */
4870 buf[i] = '\0'; /* tie off buf string */
4871 fnexpand(buf, sizeof(buf)); /* expand the path */
4873 for(p = buf; dest < limit && (*dest = *p); p++, dest++)
4876 continue;
4877 }else
4878 #endif
4879 if(*src == '$'){ /* shell variable */
4880 char word[128+1], *colon = NULL, *rbrace = NULL;
4882 envexpand++; /* signal that we've expanded a var */
4883 src++; /* skip dollar */
4884 if(*src == '{'){ /* starts with brace? */
4885 src++;
4886 rbrace = strindex(src, '}');
4887 if(rbrace){
4888 /* look for default value */
4889 colon = strstr(src, ":-");
4890 if(colon && (rbrace < colon))
4891 colon = NULL;
4895 p = word;
4897 /* put the env variable to be looked up in word */
4898 if(rbrace){
4899 while(*src
4900 && (p-word < sizeof(word)-1)
4901 && ((colon && src < colon) || (!colon && src < rbrace))){
4902 if(isspace((unsigned char) *src)){
4904 * Illegal input. This should be an error of some
4905 * sort but instead of that we'll just backup to the
4906 * $ and treat it like it wasn't there.
4908 while(*src != '$')
4909 src--;
4911 envexpand--;
4912 goto just_copy;
4914 else
4915 *p++ = *src++;
4918 /* adjust src for next char */
4919 src = rbrace + 1;
4921 else{
4922 while(*src && is_allowed_envchar((unsigned char) *src, sp)
4923 && (p-word < sizeof(word)-1))
4924 *p++ = *src++;
4927 *p = '\0';
4929 if((p = getenv(word)) != NULL){ /* check for word in environment */
4930 while(*p && dest < limit)
4931 *dest++ = *p++;
4933 else if(colon){ /* else possible default value */
4934 p = colon + 2;
4935 while(*p && p < rbrace && dest < limit)
4936 *dest++ = *p++;
4939 continue;
4940 }else{ /* other cases: just copy */
4941 just_copy:
4942 if(dest < limit)
4943 *dest++ = *src;
4946 if(*src) /* next character (if any) */
4947 src++;
4950 if(dest < limit)
4951 *dest = '\0';
4952 else
4953 lineout[lineoutlen-1] = '\0';
4955 return((envexpand && lineout[0] == '\0') ? NULL : lineout);
4959 /*----------------------------------------------------------------------
4960 Sets login, full_username and home_dir
4962 Args: ps -- The Pine structure to put the user name, etc in
4964 Result: sets the fullname, login and home_dir field of the pine structure
4965 returns 0 on success, -1 if not.
4966 ----*/
4967 #define MAX_INIT_ERRS 10
4968 void
4969 init_error(struct pine *ps, int flags, int min_time, int max_time, char *message)
4971 int i;
4973 if(!ps->init_errs){
4974 ps->init_errs = (INIT_ERR_S *)fs_get((MAX_INIT_ERRS + 1) *
4975 sizeof(*ps->init_errs));
4976 memset(ps->init_errs, 0, (MAX_INIT_ERRS + 1) * sizeof(*ps->init_errs));
4979 for(i = 0; i < MAX_INIT_ERRS; i++)
4980 if(!(ps->init_errs)[i].message){
4981 (ps->init_errs)[i].message = cpystr(message);
4982 (ps->init_errs)[i].min_time = min_time;
4983 (ps->init_errs)[i].max_time = max_time;
4984 (ps->init_errs)[i].flags = flags;
4985 dprint((2, "%s\n", message ? message : "?"));
4986 break;
4991 /*----------------------------------------------------------------------
4992 Read and parse a pinerc file
4994 Args: Filename -- name of the .pinerc file to open and read
4995 vars -- The vars structure to store values in
4996 which_vars -- Whether the local or global values are being read
4998 Result:
5000 This may be the local file or the global file. The values found are
5001 merged with the values currently in vars. All values are strings and
5002 are malloced; and existing values will be freed before the assignment.
5003 Those that are <unset> will be left unset; their values will be NULL.
5004 ----*/
5005 void
5006 read_pinerc(PINERC_S *prc, struct variable *vars, ParsePinerc which_vars)
5008 char *filename, *file, *value, **lvalue, *line, *error;
5009 char *p, *p1, *free_file = NULL;
5010 struct variable *v;
5011 PINERC_LINE *pline = NULL;
5012 int line_count, was_quoted;
5013 int i;
5015 if(!prc)
5016 return;
5018 dprint((2, "reading_pinerc \"%s\"\n",
5019 prc->name ? prc->name : "?"));
5021 if(prc->type == Loc){
5022 filename = prc->name ? prc->name : "";
5023 file = free_file = read_file(filename, 0);
5026 * This is questionable. In case the user edits the pinerc
5027 * in Windows and adds a UTF-8 BOM, we skip it here. If the
5028 * user adds a Unicode BOM we're in trouble. We could write it
5029 * with the BOM ourselves but so far we leave it BOMless in
5030 * order that it's the same on Unix and Windows.
5032 if(BOM_UTF8(file))
5033 file += 3;
5035 else{
5036 if((file = read_remote_pinerc(prc, which_vars)) != NULL)
5037 ps_global->c_client_error[0] = '\0';
5039 free_file = file;
5042 if(file == NULL || *file == '\0'){
5043 #ifdef DEBUG
5044 if(file == NULL){
5045 dprint((2, "Open failed: %s\n", error_description(errno)));
5047 else{
5048 if(prc->type == Loc){
5049 dprint((1, "Read_pinerc: empty pinerc (new?)\n"));
5051 else{
5052 dprint((1, "Read_pinerc: new remote pinerc\n"));
5055 #endif /* DEBUG */
5057 if(which_vars == ParsePers){
5058 /* problems getting remote config */
5059 if(file == NULL && prc->type == RemImap){
5060 if(!pith_opt_remote_pinerc_failure
5061 || !(*pith_opt_remote_pinerc_failure)())
5062 exceptional_exit(_("Unable to read or write remote configuration"), -1);
5065 ps_global->first_time_user = 1;
5066 prc->outstanding_pinerc_changes = 1;
5069 return;
5071 else{
5072 if(prc->type == Loc &&
5073 (which_vars == ParseFixed || which_vars == ParseGlobal ||
5074 (can_access(filename, ACCESS_EXISTS) == 0 &&
5075 can_access(filename, EDIT_ACCESS) != 0))){
5076 prc->readonly = 1;
5077 if(prc == ps_global->prc)
5078 ps_global->readonly_pinerc = 1;
5082 * accept CRLF or LF newlines
5084 for(p = file; *p && *p != '\012'; p++)
5087 if(p > file && *p && *(p-1) == '\015') /* cvt crlf to lf */
5088 for(p1 = p - 1; (*p1 = *p) != '\0'; p++)
5089 if(!(*p == '\015' && *(p+1) == '\012'))
5090 p1++;
5093 dprint((2, "Read %d characters:\n", strlen(file)));
5095 if(which_vars == ParsePers || which_vars == ParsePersPost){
5096 /*--- Count up lines and allocate structures */
5097 for(line_count = 0, p = file; *p != '\0'; p++)
5098 if(*p == '\n')
5099 line_count++;
5101 prc->pinerc_lines = (PINERC_LINE *)
5102 fs_get((3 + line_count) * sizeof(PINERC_LINE));
5103 memset((void *)prc->pinerc_lines, 0,
5104 (3 + line_count) * sizeof(PINERC_LINE));
5105 pline = prc->pinerc_lines;
5108 for(p = file, line = file; *p != '\0';){
5109 /*----- Grab the line ----*/
5110 line = p;
5111 while(*p && *p != '\n')
5112 p++;
5113 if(*p == '\n'){
5114 *p++ = '\0';
5117 /*----- Comment Line -----*/
5118 if(*line == '#'){
5119 /* no comments in remote pinercs */
5120 if(pline && prc->type == Loc){
5121 pline->is_var = 0;
5122 pline->line = cpystr(line);
5123 pline++;
5125 continue;
5128 if(*line == '\0' || *line == '\t' || *line == ' '){
5129 p1 = line;
5130 while(*p1 == '\t' || *p1 == ' ')
5131 p1++;
5132 if(pline){
5134 * This could be a continuation line from some future
5135 * version of pine, or it could be a continuation line
5136 * from a PC-Pine variable we don't know about in unix.
5138 if(*p1 != '\0')
5139 pline->line = cpystr(line);
5140 else
5141 pline->line = cpystr("");
5142 pline->is_var = 0;
5143 pline++;
5145 continue;
5148 /*----- look up matching 'v' and leave "value" after '=' ----*/
5149 for(v = vars; *line && v->name; v++)
5150 if((i = strlen(v->name)) < strlen(line) && !struncmp(v->name,line,i)){
5151 int j;
5153 for(j = i; line[j] == ' ' || line[j] == '\t'; j++)
5156 if(line[j] == '='){ /* bingo! */
5157 for(value = &line[j+1];
5158 *value == ' ' || *value == '\t';
5159 value++)
5162 break;
5164 /* else either unrecognized var or bogus line */
5167 /*----- Didn't match any variable or bogus format -----*/
5169 * This could be a variable from some future
5170 * version of pine, or it could be a PC-Pine variable
5171 * we don't know about in unix. Either way, we want to preserve
5172 * it in the file.
5174 if(!v->name){
5175 if(pline){
5176 pline->is_var = 0;
5177 pline->line = cpystr(line);
5178 pline++;
5180 continue;
5184 * Previous versions have caused duplicate pinerc data to be
5185 * written to pinerc files. This clause erases the duplicate
5186 * information when we read it, and it will be removed from the file
5187 * if we call write_pinerc. We test to see if the same variable
5188 * appears later in the file, if so, we skip over it here.
5189 * We don't care about duplicates if this isn't a pinerc we might
5190 * write out, so include pline in the conditional.
5191 * Note that we will leave all of the duplicate comments and blank
5192 * lines in the file unless it is a remote pinerc. Luckily, the
5193 * bug that caused the duplicates only applied to remote pinercs,
5194 * so we should have that case covered.
5196 * If we find a duplicate, we point p to the start
5197 * of the next line that should be considered, and then skip back
5198 * to the top of the loop.
5200 if(pline && var_is_in_rest_of_file(v->name, p)){
5201 if(v->is_list)
5202 p = skip_over_this_var(line, p);
5204 continue;
5208 /*----- Obsolete variable, read it anyway below, might use it -----*/
5209 if(v->is_obsolete){
5210 if(pline){
5211 pline->obsolete_var = 1;
5212 pline->line = cpystr(line);
5213 pline->var = v;
5217 /*----- Variable is in the list but unused for some reason -----*/
5218 if(!v->is_used){
5219 if(pline){
5220 pline->is_var = 0;
5221 pline->line = cpystr(line);
5222 pline++;
5224 continue;
5227 /*--- Var is not user controlled, leave it alone for back compat ---*/
5228 if(!v->is_user && pline){
5229 pline->is_var = 0;
5230 pline->line = cpystr(line);
5231 pline++;
5232 continue;
5235 if(which_vars == ParseFixed)
5236 v->is_fixed = 1;
5238 /*---- variable is unset, or it's global but expands to nothing ----*/
5239 if(!*value
5240 || (which_vars == ParseGlobal
5241 && !expand_variables(tmp_20k_buf, SIZEOF_20KBUF, value,
5242 (v == &ps_global->vars[V_MAILCAP_PATH] ||
5243 v == &ps_global->vars[V_MIMETYPE_PATH])))){
5244 if(v->is_user && pline){
5245 pline->is_var = 1;
5246 pline->var = v;
5247 pline++;
5249 continue;
5252 /*--value is non-empty, store it handling quotes and trailing space--*/
5253 if(*value == '"' && !v->is_list && v->del_quotes){
5254 was_quoted = 1;
5255 value++;
5256 for(p1 = value; *p1 && *p1 != '"'; p1++);
5257 if(*p1 == '"')
5258 *p1 = '\0';
5259 else
5260 removing_trailing_white_space(value);
5261 }else
5262 was_quoted = 0;
5265 * List Entry Parsing
5267 * The idea is to parse a comma separated list of
5268 * elements, preserving quotes, and understanding
5269 * continuation lines (that is ',' == "\n ").
5270 * Quotes must be balanced within elements. Space
5271 * within elements is preserved, but leading and trailing
5272 * space is trimmed. This is a generic function, and it's
5273 * left to the the functions that use the lists to make sure
5274 * they contain valid data...
5276 if(v->is_list){
5278 was_quoted = 0;
5279 line_count = 0;
5280 p1 = value;
5281 while(1){ /* generous count of list elements */
5282 if(*p1 == '"') /* ignore ',' if quoted */
5283 was_quoted = (was_quoted) ? 0 : 1 ;
5285 if((*p1 == ',' && !was_quoted) || *p1 == '\n' || *p1 == '\0')
5286 line_count++; /* count this element */
5288 if(*p1 == '\0' || *p1 == '\n'){ /* deal with EOL */
5289 if(p1 < p || *p1 == '\n'){
5290 *p1++ = ','; /* fix null or newline */
5292 if(*p1 != '\t' && *p1 != ' '){
5293 *(p1-1) = '\0'; /* tie off list */
5294 p = p1; /* reset p */
5295 break;
5297 }else{
5298 p = p1; /* end of pinerc */
5299 break;
5301 }else
5302 p1++;
5305 error = NULL;
5306 lvalue = parse_list(value, line_count,
5307 v->del_quotes ? PL_REMSURRQUOT : PL_NONE,
5308 &error);
5309 if(error){
5310 dprint((1,
5311 "read_pinerc: ERROR: %s in %s = \"%s\"\n",
5312 error ? error : "?",
5313 v->name ? v->name : "?",
5314 value ? value : "?"));
5317 * Special case: turn "" strings into empty strings.
5318 * This allows users to turn off default lists. For example,
5319 * if smtp-server is set then a user could override smtp-server
5320 * with smtp-server="".
5322 for(i = 0; lvalue[i]; i++)
5323 if(lvalue[i][0] == '"' &&
5324 lvalue[i][1] == '"' &&
5325 lvalue[i][2] == '\0')
5326 lvalue[i][0] = '\0';
5329 if(pline){
5330 if(v->is_user && (which_vars == ParsePers || !v->is_onlymain)){
5331 if(v->is_list){
5332 char ***l;
5334 l = (which_vars == ParsePers) ? &v->main_user_val.l
5335 : &v->post_user_val.l;
5336 free_list_array(l);
5337 *l = lvalue;
5339 else{
5340 char **p;
5342 p = (which_vars == ParsePers) ? &v->main_user_val.p
5343 : &v->post_user_val.p;
5344 if(p && *p != NULL)
5345 fs_give((void **)p);
5347 *p = cpystr(value);
5350 if(pline){
5351 pline->is_var = 1;
5352 pline->var = v;
5353 pline->is_quoted = was_quoted;
5354 pline++;
5358 else if(which_vars == ParseGlobal){
5359 if(v->is_global){
5360 if(v->is_list){
5361 free_list_array(&v->global_val.l);
5362 v->global_val.l = lvalue;
5364 else{
5365 if(v->global_val.p != NULL)
5366 fs_give((void **) &(v->global_val.p));
5368 v->global_val.p = cpystr(value);
5372 else{ /* which_vars == ParseFixed */
5373 if(v->is_user || v->is_global){
5374 if(v->is_list){
5375 free_list_array(&v->fixed_val.l);
5376 v->fixed_val.l = lvalue;
5378 else{
5379 if(v->fixed_val.p != NULL)
5380 fs_give((void **) &(v->fixed_val.p));
5382 v->fixed_val.p = cpystr(value);
5387 #ifdef DEBUG
5388 if(v->is_list){
5389 char **l;
5390 l = (which_vars == ParsePers) ? v->main_user_val.l :
5391 (which_vars == ParsePersPost) ? v->post_user_val.l :
5392 (which_vars == ParseGlobal) ? v->global_val.l :
5393 v->fixed_val.l;
5394 if(l && *l && **l){
5395 dprint((5, " %20.20s : %s\n",
5396 v->name ? v->name : "?",
5397 *l ? *l : "?"));
5398 while(++l && *l && **l)
5399 dprint((5, " %20.20s : %s\n", "",
5400 *l ? *l : "?"));
5402 }else{
5403 char *p;
5404 p = (which_vars == ParsePers) ? v->main_user_val.p :
5405 (which_vars == ParsePersPost) ? v->post_user_val.p :
5406 (which_vars == ParseGlobal) ? v->global_val.p :
5407 v->fixed_val.p;
5408 if(p && *p)
5409 dprint((5, " %20.20s : %s\n",
5410 v->name ? v->name : "?",
5411 p ? p : "?"));
5413 #endif /* DEBUG */
5416 if(pline){
5417 pline->line = NULL;
5418 pline->is_var = 0;
5419 if(!prc->pinerc_written && prc->type == Loc){
5420 prc->pinerc_written = name_file_mtime(filename);
5421 dprint((5, "read_pinerc: time_pinerc_written = %ld\n",
5422 (long) prc->pinerc_written));
5426 if(free_file)
5427 fs_give((void **) &free_file);
5432 * Args varname The variable name we're looking for
5433 * begin Begin looking here
5435 * Returns 1 if variable varname appears in the rest of the file
5436 * 0 if not
5439 var_is_in_rest_of_file(char *varname, char *begin)
5441 char *p;
5443 if(!(varname && *varname && begin && *begin))
5444 return 0;
5446 p = begin;
5448 while((p = srchstr(p, varname)) != NULL){
5449 /* beginning of a line? */
5450 if(p > begin && (*(p-1) != '\n' && *(p-1) != '\r')){
5451 p++;
5452 continue;
5455 /* followed by [ SPACE ] < = > ? */
5456 p += strlen(varname);
5457 while(*p == ' ' || *p == '\t')
5458 p++;
5460 if(*p == '=')
5461 return 1;
5464 return 0;
5469 * Args begin Variable to skip starts here.
5470 * nextline This is where the next line starts. We need to know this
5471 * because the input has been mangled a little. A \0 has
5472 * replaced the \n at the end of the first line, but we can
5473 * use nextline to help us out of that quandry.
5475 * Return a pointer to the start of the first line after this variable
5476 * and all of its continuation lines.
5478 char *
5479 skip_over_this_var(char *begin, char *nextline)
5481 char *p;
5483 p = begin;
5485 while(1){
5486 if(*p == '\0' || *p == '\n'){ /* EOL */
5487 if(p < nextline || *p == '\n'){ /* there may be another line */
5488 p++;
5489 if(*p != ' ' && *p != '\t') /* no continuation line */
5490 return(p);
5492 else /* end of file */
5493 return(p);
5495 else
5496 p++;
5501 static char quotes[3] = {'"', '"', '\0'};
5502 /*----------------------------------------------------------------------
5503 Write out the .pinerc state information
5505 Args: ps -- The pine structure to take state to be written from
5506 which -- Which pinerc to write
5507 flags -- If bit WRP_NOUSER is set, then assume that there is
5508 not a user present to answer questions.
5510 This writes to a temporary file first, and then renames that to
5511 be the new .pinerc file to protect against disk error. This has the
5512 problem of possibly messing up file protections, ownership and links.
5513 ----*/
5515 write_pinerc(struct pine *ps, EditWhich which, int flags)
5517 char *p, *dir, *tmp = NULL, *pinrc;
5518 char *pval, **lval;
5519 char *linep = NULL, *lineq = NULL;
5520 int bc = 1;
5521 int buflen;
5522 PINERC_LINE *pline;
5523 struct variable *var;
5524 time_t mtime;
5525 char *filename;
5526 REMDATA_S *rd = NULL;
5527 PINERC_S *prc = NULL;
5528 STORE_S *so = NULL;
5529 #ifndef _WINDOWS
5530 struct stat sbuf;
5531 char *slink = NULL;
5532 #endif
5534 #define MAXPLINESIZE 10000
5536 dprint((2,"---- write_pinerc(%s) ----\n",
5537 (which == Main) ? "Main" : "Post"));
5539 switch(which){
5540 case Main:
5541 prc = ps ? ps->prc : NULL;
5542 break;
5543 case Post:
5544 prc = ps ? ps->post_prc : NULL;
5545 break;
5546 default:
5547 break;
5550 if(!prc)
5551 return(-1);
5553 if(prc->quit_to_edit){
5554 if(!(flags & WRP_NOUSER))
5555 quit_to_edit_msg(prc);
5557 return(-1);
5560 if(prc->type != Loc && !prc->readonly){
5562 bc = 0; /* don't do backcompat conversion */
5563 rd = prc->rd;
5564 if(!rd)
5565 return(-1);
5567 rd_check_remvalid(rd, -10L);
5569 if(rd->flags & REM_OUTOFDATE){
5570 if((flags & WRP_NOUSER) || unexpected_pinerc_change()){
5571 prc->outstanding_pinerc_changes = 1;
5572 if(!(flags & WRP_NOUSER))
5573 q_status_message1(SM_ORDER | SM_DING, 3, 3,
5574 "Pinerc \"%.200s\" NOT saved",
5575 prc->name ? prc->name : "");
5576 dprint((2, "write_pinerc: remote pinerc changed\n"));
5577 return(-1);
5579 else
5580 rd->flags &= ~REM_OUTOFDATE;
5583 rd_open_remote(rd);
5585 if(rd->access == ReadWrite){
5586 int ro;
5588 if((ro=rd_remote_is_readonly(rd)) || rd->flags & REM_OUTOFDATE){
5589 if(ro == 1){
5590 if(!(flags & WRP_NOUSER))
5591 q_status_message(SM_ORDER | SM_DING, 5, 15,
5592 _("Can't access remote config, changes NOT saved!"));
5593 dprint((1,
5594 "write_pinerc: Can't write to remote pinerc %s, aborting write\n",
5595 rd->rn ? rd->rn : "?"));
5597 else if(ro == 2){
5598 if(!(rd->flags & NO_META_UPDATE)){
5599 unsigned long save_chk_nmsgs;
5601 switch(rd->type){
5602 case RemImap:
5603 save_chk_nmsgs = rd->t.i.chk_nmsgs;
5604 rd->t.i.chk_nmsgs = 0;
5605 rd_write_metadata(rd, 0);
5606 rd->t.i.chk_nmsgs = save_chk_nmsgs;
5607 break;
5609 default:
5610 q_status_message(SM_ORDER | SM_DING, 3, 5,
5611 "Write_pinerc: Type not supported");
5612 break;
5616 if(!(flags & WRP_NOUSER))
5617 q_status_message1(SM_ORDER | SM_DING, 5, 15,
5618 _("No write permission for remote config %.200s, changes NOT saved!"),
5619 rd->rn);
5621 else{
5622 if(!(flags & WRP_NOUSER))
5623 q_status_message(SM_ORDER | SM_DING, 5, 15,
5624 _("Remote config changed, aborting our change to avoid damage..."));
5625 dprint((1,
5626 "write_pinerc: remote config %s changed since we started pine, aborting write\n",
5627 prc->name ? prc->name : "?"));
5630 rd->flags &= ~DO_REMTRIM;
5631 return(-1);
5634 filename = rd->lf;
5636 else{
5637 prc->readonly = 1;
5638 if(prc == ps->prc)
5639 ps->readonly_pinerc = 1;
5642 else
5643 filename = prc->name ? prc->name : "";
5645 pinrc = prc->name ? prc->name : "";
5647 if(prc->type == Loc){
5648 mtime = name_file_mtime(filename);
5649 if(prc->pinerc_written
5650 && prc->pinerc_written != mtime
5651 && ((flags & WRP_NOUSER) || unexpected_pinerc_change())){
5652 prc->outstanding_pinerc_changes = 1;
5654 if(!(flags & WRP_NOUSER))
5655 q_status_message1(SM_ORDER | SM_DING, 3, 3,
5656 "Pinerc \"%.200s\" NOT saved", pinrc);
5658 dprint((2,"write_pinerc: mtime mismatch: \"%s\": %ld != %ld\n",
5659 filename ? filename : "?",
5660 (long) prc->pinerc_written, (long) mtime));
5661 return(-1);
5665 /* don't write if pinerc is read-only */
5666 if(prc->readonly ||
5667 (filename &&
5668 can_access(filename, ACCESS_EXISTS) == 0 &&
5669 can_access(filename, EDIT_ACCESS) != 0)){
5670 prc->readonly = 1;
5671 if(prc == ps->prc)
5672 ps->readonly_pinerc = 1;
5674 if(!(flags & WRP_NOUSER))
5675 q_status_message1(SM_ORDER | SM_DING, 0, 5,
5676 _("Can't modify configuration file \"%.200s\": ReadOnly"),
5677 pinrc);
5678 dprint((2, "write_pinerc: fail because can't access pinerc\n"));
5680 if(rd)
5681 rd->flags &= ~DO_REMTRIM;
5683 return(-1);
5686 if(rd && rd->flags & NO_FILE){
5687 so = rd->sonofile;
5688 so_truncate(rd->sonofile, 0L); /* reset storage object */
5690 else{
5691 dir = ".";
5692 if((p = last_cmpnt(filename)) != NULL){
5693 *--p = '\0';
5694 dir = filename;
5697 #if defined(DOS) || defined(OS2)
5698 if(!(isalpha((unsigned char)dir[0]) && dir[1] == ':' && dir[2] == '\0')
5699 && (can_access(dir, EDIT_ACCESS) < 0 &&
5700 our_mkdir(dir, 0700) < 0))
5702 if(!(flags & WRP_NOUSER))
5703 q_status_message2(SM_ORDER | SM_DING, 3, 5,
5704 /* TRANSLATORS: first argument is a filename, second
5705 arg is the text of the error message */
5706 _("Error creating \"%.200s\" : %.200s"), dir,
5707 error_description(errno));
5708 if(rd)
5709 rd->flags &= ~DO_REMTRIM;
5711 return(-1);
5714 tmp = temp_nam(dir, "rc");
5716 if(*dir && tmp && !in_dir(dir, tmp)){
5717 our_unlink(tmp);
5718 fs_give((void **)&tmp);
5721 if(p)
5722 *p = '\\';
5724 if(tmp == NULL)
5725 goto io_err;
5727 #else /* !DOS */
5728 tmp = temp_nam((*dir) ? dir : "/", "pinerc");
5731 * If temp_nam can't write in dir it puts the temp file in a
5732 * temp directory, which won't help us when we go to rename.
5734 if(*dir && tmp && !in_dir(dir, tmp)){
5735 our_unlink(tmp);
5736 fs_give((void **)&tmp);
5739 if(p)
5740 *p = '/';
5742 if(tmp == NULL)
5743 goto io_err;
5745 #endif /* !DOS */
5747 if((so = so_get(FileStar, tmp, WRITE_ACCESS)) == NULL)
5748 goto io_err;
5751 if(!(flags & WRP_PRESERV_WRITTEN))
5752 for(var = ps->vars; var->name != NULL; var++)
5753 var->been_written = 0;
5755 if(prc->type == Loc && ps->first_time_user &&
5756 !so_puts(so, native_nl(cf_text_comment)))
5757 goto io_err;
5759 linep = fs_get((MAXPLINESIZE+1)*sizeof(char));
5760 lineq = fs_get((MAXPLINESIZE+1)*sizeof(char));
5761 buflen = MAXPLINESIZE;
5763 /* Write out what was in the .pinerc */
5764 for(pline = prc->pinerc_lines;
5765 pline && (pline->is_var || pline->line); pline++){
5766 if(pline->is_var){
5767 var = pline->var;
5769 if(var->is_list)
5770 lval = LVAL(var, which);
5771 else
5772 pval = PVAL(var, which);
5774 /* variable is not set */
5775 if((var->is_list && (!lval || !lval[0])) ||
5776 (!var->is_list && !pval)){
5777 /* leave null variables out of remote pinerc */
5778 if(prc->type == Loc &&
5779 (!so_puts(so, var->name) || !so_puts(so, "=") ||
5780 !so_puts(so, NEWLINE)))
5781 goto io_err;
5783 /* var is set to empty string */
5784 else if((var->is_list && lval[0][0] == '\0') ||
5785 (!var->is_list && pval[0] == '\0')){
5786 if(!so_puts(so, var->name) || !so_puts(so, "=") ||
5787 !so_puts(so, quotes) || !so_puts(so, NEWLINE))
5788 goto io_err;
5790 else{
5791 if(var->is_list){
5792 int i = 0;
5794 for(i = 0; lval[i]; i++){
5795 if(strlen(var->name)
5796 + (lval[i][0] ? strlen(lval[i]) : 5) > buflen){
5797 buflen = strlen(var->name)
5798 + (lval[i][0] ? strlen(lval[i]) : 5);
5799 fs_resize((void **)&linep, (buflen+1)*sizeof(char));
5800 fs_resize((void **)&lineq, (buflen+1)*sizeof(char));
5802 snprintf(linep, buflen+1, "%s%s%s%s%s",
5803 (i) ? "\t" : var->name,
5804 (i) ? "" : "=",
5805 lval[i][0] ? lval[i] : quotes,
5806 lval[i+1] ? "," : "", NEWLINE);
5807 linep[buflen] = '\0';
5808 if(!so_puts(so, bc ? backcompat_convert_from_utf8(&lineq, buflen+1, linep) : linep))
5809 goto io_err;
5812 else{
5813 if(strlen(var->name)
5814 + (pval[0] ? strlen(pval) : 5) > buflen){
5815 buflen = strlen(var->name)
5816 + (pval[0] ? strlen(pval) : 5);
5817 fs_resize((void **)&linep, (buflen+1)*sizeof(char));
5818 fs_resize((void **)&lineq, (buflen+1)*sizeof(char));
5820 snprintf(linep, buflen+1, "%s=%s%s%s%s",
5821 var->name,
5822 (pline->is_quoted && pval[0] != '\"')
5823 ? "\"" : "",
5824 pval,
5825 (pline->is_quoted && pval[0] != '\"')
5826 ? "\"" : "", NEWLINE);
5827 linep[buflen] = '\0';
5828 if(!so_puts(so, bc ? backcompat_convert_from_utf8(&lineq, buflen+1, linep) : linep))
5829 goto io_err;
5833 var->been_written = 1;
5835 }else{
5837 * The description text should be changed into a message
5838 * about the variable being obsolete when a variable is
5839 * moved to obsolete status. We add that message before
5840 * the variable unless it is already there. However, we
5841 * leave the variable itself in case the user runs an old
5842 * version of pine again. Note that we have read in the
5843 * value of the variable in read_pinerc and translated it
5844 * into a new variable if appropriate.
5846 if(pline->obsolete_var && prc->type == Loc){
5847 if(pline <= prc->pinerc_lines || (pline-1)->line == NULL ||
5848 strlen((pline-1)->line) < 3 ||
5849 strucmp((pline-1)->line+2, pline->var->descrip) != 0)
5850 if(!so_puts(so, "# ") ||
5851 !so_puts(so, native_nl(pline->var->descrip)) ||
5852 !so_puts(so, NEWLINE))
5853 goto io_err;
5856 /* remove comments from remote pinercs */
5857 if((prc->type == Loc ||
5858 (pline->line[0] != '#' && pline->line[0] != '\0')) &&
5859 (!so_puts(so, pline->line) || !so_puts(so, NEWLINE)))
5860 goto io_err;
5864 /* Now write out all the variables not in the .pinerc */
5865 for(var = ps->vars; var->name != NULL; var++){
5866 if(!var->is_user || var->been_written || !var->is_used ||
5867 var->is_obsolete || (var->is_onlymain && which != Main))
5868 continue;
5870 if(var->is_list)
5871 lval = LVAL(var, which);
5872 else
5873 pval = PVAL(var, which);
5876 * set description to NULL to eliminate preceding
5877 * blank and comment line.
5879 if(prc->type == Loc && var->descrip && *var->descrip &&
5880 (!so_puts(so, NEWLINE) || !so_puts(so, "# ") ||
5881 !so_puts(so, native_nl(var->descrip)) || !so_puts(so, NEWLINE)))
5882 goto io_err;
5884 /* variable is not set */
5885 /** Don't know what the global_val thing is for. SH, Mar 00 **/
5886 if((var->is_list && (!lval || (!lval[0] && !var->global_val.l))) ||
5887 (!var->is_list && !pval)){
5888 /* leave null variables out of remote pinerc */
5889 if(prc->type == Loc &&
5890 (!so_puts(so, var->name) || !so_puts(so, "=") ||
5891 !so_puts(so, NEWLINE)))
5892 goto io_err;
5894 /* var is set to empty string */
5895 else if((var->is_list && (!lval[0] || !lval[0][0]))
5896 || (!var->is_list && pval[0] == '\0')){
5897 if(!so_puts(so, var->name) || !so_puts(so, "=") ||
5898 !so_puts(so, quotes) || !so_puts(so, NEWLINE))
5899 goto io_err;
5901 else if(var->is_list){
5902 int i = 0;
5904 for(i = 0; lval[i] ; i++){
5905 if(strlen(var->name)
5906 + (lval[i][0] ? strlen(lval[i]) : 5) > buflen){
5907 buflen = strlen(var->name)
5908 + (lval[i][0] ? strlen(lval[i]) : 5);
5909 fs_resize((void **)&linep, (buflen+1)*sizeof(char));
5910 fs_resize((void **)&lineq, (buflen+1)*sizeof(char));
5912 snprintf(linep, buflen+1, "%s%s%s%s%s",
5913 (i) ? "\t" : var->name,
5914 (i) ? "" : "=",
5915 lval[i],
5916 lval[i+1] ? "," : "", NEWLINE);
5917 linep[buflen] = '\0';
5918 if(!so_puts(so, bc ? backcompat_convert_from_utf8(&lineq, buflen+1, linep) : linep))
5919 goto io_err;
5922 else{
5923 char *pconverted;
5925 if(strlen(pval) > buflen){
5926 buflen = strlen(pval) + 1;
5927 fs_resize((void **)&linep, (buflen+1)*sizeof(char));
5928 fs_resize((void **)&lineq, (buflen+1)*sizeof(char));
5930 pconverted = bc ? backcompat_convert_from_utf8(&lineq, buflen+1, pval) : pval;
5932 if(!so_puts(so, var->name) || !so_puts(so, "=") ||
5933 !so_puts(so, pconverted) || !so_puts(so, NEWLINE))
5934 goto io_err;
5938 if(!(rd && rd->flags & NO_FILE)){
5939 if(so_give(&so))
5940 goto io_err;
5942 #ifndef _WINDOWS
5943 /* if .pinerc is a symbolic link, override symbolic link */
5944 if(our_lstat(filename, &sbuf) == 0
5945 && ((sbuf.st_mode & S_IFMT) == S_IFLNK)){
5946 if((slink = fs_get((sbuf.st_size+1)*sizeof(char))) != NULL){
5947 int r = -1; /* assume error */
5948 if(readlink(filename, slink, sbuf.st_size + 1) >= 0){
5949 char *slpath;
5951 slink[sbuf.st_size] = '\0';
5952 if(*slink == '/')
5953 slpath = cpystr(slink);
5954 else{
5955 char * basep;
5956 int n;
5958 basep = strrchr(filename, '/');
5959 if(basep != NULL){
5960 *basep = '\0';
5961 n = strlen(filename) + strlen(slink) + 2;
5962 slpath = (char *) fs_get(n*sizeof(char));
5963 snprintf(slpath, n, "%s/%s", filename, slink);
5964 *basep = '/';
5965 } else {
5966 n = strlen(ps_global->home_dir) + strlen(slink) + 2;
5967 slpath = (char *) fs_get(n*sizeof(char));
5968 snprintf(slpath, n, "%s/%s", ps_global->home_dir, slink);
5970 slpath[n-1] = '\0';
5972 file_attrib_copy(tmp, slpath);
5973 r = rename_file(tmp, slpath);
5974 fs_give((void **)&slpath);
5976 fs_give((void **)&slink);
5977 if (r < 0) goto io_err;
5980 else
5981 #endif /* _WINDOWS */
5983 file_attrib_copy(tmp, filename);
5984 if(rename_file(tmp, filename) < 0)
5985 goto io_err;
5989 if(prc->type != Loc){
5990 int e, we_cancel;
5991 char datebuf[200];
5993 datebuf[0] = '\0';
5994 we_cancel = 0;
5996 if(!(flags & WRP_NOUSER))
5997 we_cancel = busy_cue(_("Copying to remote config"), NULL, 1);
5999 if((e = rd_update_remote(rd, datebuf)) != 0){
6000 dprint((1,
6001 "write_pinerc: error copying from %s to %s\n",
6002 rd->lf ? rd->lf : "<memory>", rd->rn ? rd->rn : "?"));
6003 if(!(flags & WRP_NOUSER)){
6004 q_status_message2(SM_ORDER | SM_DING, 3, 5,
6005 _("Error copying to %.200s: %.200s"),
6006 rd->rn, error_description(errno));
6008 q_status_message(SM_ORDER | SM_DING, 5, 5,
6009 _("Copy of config to remote folder failed, changes NOT saved remotely"));
6012 else{
6013 rd_update_metadata(rd, datebuf);
6014 rd->read_status = 'W';
6015 rd_trim_remdata(&rd);
6016 rd_close_remote(rd);
6019 if(we_cancel)
6020 cancel_busy_cue(-1);
6023 prc->outstanding_pinerc_changes = 0;
6025 if(prc->type == Loc){
6026 prc->pinerc_written = name_file_mtime(filename);
6027 dprint((2, "wrote pinerc: %s: time_pinerc_written = %ld\n",
6028 pinrc ? pinrc : "?", (long) prc->pinerc_written));
6030 else{
6031 dprint((2, "wrote pinerc: %s\n", pinrc ? pinrc : "?"));
6034 if(tmp){
6035 our_unlink(tmp);
6036 fs_give((void **)&tmp);
6039 if(linep) fs_give((void **)&linep);
6040 if(lineq) fs_give((void **)&lineq);
6042 return(0);
6044 io_err:
6045 if(!(flags & WRP_NOUSER))
6046 q_status_message2(SM_ORDER | SM_DING, 3, 5,
6047 _("Error saving configuration in \"%.200s\": %.200s"),
6048 pinrc, error_description(errno));
6050 dprint((1, "Error writing %s : %s\n", pinrc ? pinrc : "?",
6051 error_description(errno)));
6052 if(rd)
6053 rd->flags &= ~DO_REMTRIM;
6054 if(tmp){
6055 our_unlink(tmp);
6056 fs_give((void **)&tmp);
6059 if(linep) fs_give((void **)&linep);
6060 if(lineq) fs_give((void **)&lineq);
6062 return(-1);
6067 * The srcstr is UTF-8. In order to help the user with
6068 * running this pine and an old pre-alpine pine on the same config
6069 * file we attempt to convert the values of the config variables
6070 * to the user's character set before writing.
6071 * parameters: char **buf. Memory of size_t buflen allocated by caller.
6073 char *
6074 backcompat_convert_from_utf8(char **buf, size_t buflen, char *srcstr)
6076 char *converted = NULL;
6077 char *p;
6078 int its_ascii = 1;
6081 for(p = srcstr; *p && its_ascii; p++)
6082 if(*p & 0x80)
6083 its_ascii = 0;
6085 /* if it is ascii, go with that */
6086 if(its_ascii){
6087 strncpy(*buf, srcstr, buflen);
6088 converted = *buf;
6089 (*buf)[buflen-1] = '\0';
6091 else{
6092 char *trythischarset = NULL;
6095 * If it is possible to translate the UTF-8
6096 * string into the user's character set then
6097 * do that. For backwards compatibility with
6098 * old pines.
6100 if(ps_global->keyboard_charmap && ps_global->keyboard_charmap[0])
6101 trythischarset = ps_global->keyboard_charmap;
6102 else if(ps_global->display_charmap && ps_global->display_charmap[0])
6103 trythischarset = ps_global->display_charmap;
6105 if(trythischarset){
6106 SIZEDTEXT src, dst;
6108 src.data = (unsigned char *) srcstr;
6109 src.size = strlen(srcstr);
6110 memset(&dst, 0, sizeof(dst));
6111 if(utf8_cstext(&src, trythischarset, &dst, 0)){
6112 if(dst.data){
6113 strncpy(*buf, (char *) dst.data, buflen);
6114 (*buf)[buflen-1] = '\0';
6115 fs_give((void **) &dst.data);
6120 if(!converted){
6121 strncpy(*buf, srcstr, buflen);
6122 (*buf)[buflen-1] = '\0';
6123 converted = *buf;
6127 return(converted);
6132 * Given a unix-style source string which may contain LFs,
6133 * convert those to CRLFs if appropriate.
6135 * Returns a pointer to the converted string. This will be a string
6136 * stored in tmp_20k_buf.
6138 * This is just used for the variable descriptions in the pinerc file. It
6139 * could certainly be fancier. It simply converts all \n to NEWLINE.
6141 char *
6142 native_nl(char *src)
6144 char *q, *p;
6146 tmp_20k_buf[0] = '\0';
6148 if(src){
6149 for(q = (char *)tmp_20k_buf; *src; src++){
6150 if(*src == '\n'){
6151 for(p = NEWLINE; *p; p++)
6152 *q++ = *p;
6154 else
6155 *q++ = *src;
6158 *q = '\0';
6161 return((char *)tmp_20k_buf);
6165 void
6166 quit_to_edit_msg(PINERC_S *prc)
6168 /* TRANSLATORS: The %s is either "Postload " or nothing. A Postload config file
6169 is a type of config file. */
6170 q_status_message1(SM_ORDER, 3, 4, _("Must quit Alpine to change %sconfig file."),
6171 (prc == ps_global->post_prc) ? "Postload " : "");
6175 /*------------------------------------------------------------
6176 Return TRUE if the given string was a feature name present in the
6177 pinerc as it was when pine was started...
6178 ----*/
6180 var_in_pinerc(char *s)
6182 PINERC_LINE *pline;
6184 for(pline = ps_global->prc ? ps_global->prc->pinerc_lines : NULL;
6185 pline && (pline->var || pline->line); pline++)
6186 if(pline->var && pline->var->name && !strucmp(s, pline->var->name))
6187 return(1);
6189 for(pline = ps_global->post_prc ? ps_global->post_prc->pinerc_lines : NULL;
6190 pline && (pline->var || pline->line); pline++)
6191 if(pline->var && pline->var->name && !strucmp(s, pline->var->name))
6192 return(1);
6194 return(0);
6198 /*------------------------------------------------------------
6199 Free resources associated with pinerc_lines data
6200 ----*/
6201 void
6202 free_pinerc_lines(PINERC_LINE **pinerc_lines)
6204 PINERC_LINE *pline;
6206 if(pinerc_lines && *pinerc_lines){
6207 for(pline = *pinerc_lines; pline->var || pline->line; pline++)
6208 if(pline->line)
6209 fs_give((void **)&pline->line);
6211 fs_give((void **)pinerc_lines);
6216 /*------------------------------------------------------------
6217 Dump out a global pine.conf on the standard output with fresh
6218 comments. Preserves variables currently set in SYSTEM_PINERC, if any.
6219 ----*/
6220 void
6221 dump_global_conf(void)
6223 FILE *f;
6224 struct variable *var;
6225 PINERC_S *prc;
6227 prc = new_pinerc_s(SYSTEM_PINERC);
6228 read_pinerc(prc, variables, ParseGlobal);
6229 if(prc)
6230 free_pinerc_s(&prc);
6232 f = stdout;
6233 if(f == NULL)
6234 goto io_err;
6236 fprintf(f, "# %s -- system wide pine configuration\n#\n",
6237 SYSTEM_PINERC);
6238 fprintf(f, "# Values here affect all pine users unless they've overridden the values\n");
6239 fprintf(f, "# in their .pinerc files. A copy of this file with current comments may\n");
6240 fprintf(f, "# be obtained by running \"pine -conf\". It will be printed to standard output.\n#\n");
6241 fprintf(f,"# For a variable to be unset its value must be null/blank. This is not the\n");
6242 fprintf(f,"# same as the value of \"empty string\", which can be used to effectively\n");
6243 fprintf(f,"# \"unset\" a variable that has a default or previously assigned value.\n");
6244 fprintf(f,"# To set a variable to the empty string its value should be \"\".\n");
6245 fprintf(f,"# Switch variables are set to either \"yes\" or \"no\", and default to \"no\".\n");
6246 fprintf(f,"# Except for feature-list items, which are additive, values set in the\n");
6247 fprintf(f,"# .pinerc file replace those in pine.conf, and those in pine.conf.fixed\n");
6248 fprintf(f,"# over-ride all others. Features can be over-ridden in .pinerc or\n");
6249 fprintf(f,"# pine.conf.fixed by pre-pending the feature name with \"no-\".\n#\n");
6250 fprintf(f,"# (These comments are automatically inserted.)\n");
6252 for(var = variables; var->name != NULL; var++){
6253 if(!var->is_global || !var->is_used || var->is_obsolete)
6254 continue;
6256 if(var->descrip && *var->descrip){
6257 if(fprintf(f, "\n# %s\n", var->descrip) == EOF)
6258 goto io_err;
6261 if(var->is_list){
6262 if(var->global_val.l == NULL){
6263 if(fprintf(f, "%s=\n", var->name) == EOF)
6264 goto io_err;
6265 }else{
6266 int i;
6268 for(i=0; var->global_val.l[i]; i++)
6269 if(fprintf(f, "%s%s%s%s\n", (i) ? "\t" : var->name,
6270 (i) ? "" : "=", var->global_val.l[i],
6271 var->global_val.l[i+1] ? ",":"") == EOF)
6272 goto io_err;
6274 }else{
6275 if(var->global_val.p == NULL){
6276 if(fprintf(f, "%s=\n", var->name) == EOF)
6277 goto io_err;
6278 }else if(strlen(var->global_val.p) == 0){
6279 if(fprintf(f, "%s=\"\"\n", var->name) == EOF)
6280 goto io_err;
6281 }else{
6282 if(fprintf(f,"%s=%s\n",var->name,var->global_val.p) == EOF)
6283 goto io_err;
6287 exit(0);
6290 io_err:
6291 fprintf(stderr, "Error writing config to stdout: %s\n",
6292 error_description(errno));
6293 exit(-1);
6297 /*------------------------------------------------------------
6298 Dump out a pinerc to filename with fresh
6299 comments. Preserves variables currently set in pinerc, if any.
6300 ----*/
6301 void
6302 dump_new_pinerc(char *filename)
6304 FILE *f;
6305 struct variable *var;
6306 char buf[MAXPATH], *p;
6307 PINERC_S *prc;
6310 p = ps_global->pinerc;
6312 #if defined(DOS) || defined(OS2)
6313 if(!ps_global->pinerc){
6314 char *p;
6316 if(p = getenv("PINERC")){
6317 ps_global->pinerc = cpystr(p);
6318 }else{
6319 char buf2[MAXPATH];
6320 build_path(buf2, ps_global->home_dir, DF_PINEDIR, sizeof(buf2));
6321 build_path(buf, buf2, SYSTEM_PINERC, sizeof(buf));
6324 p = buf;
6326 #else /* !DOS */
6327 if(!ps_global->pinerc){
6328 build_path(buf, ps_global->home_dir, ".pinerc", sizeof(buf));
6329 p = buf;
6331 #endif /* !DOS */
6333 prc = new_pinerc_s(p);
6334 read_pinerc(prc, variables, ParsePers);
6335 if(prc)
6336 free_pinerc_s(&prc);
6338 f = NULL;;
6339 if(filename[0] == '\0'){
6340 fprintf(stderr, "Missing argument to \"-pinerc\".\n");
6341 }else if(!strcmp(filename, "-")){
6342 f = stdout;
6343 }else{
6344 f = our_fopen(filename, "wb");
6347 if(f == NULL)
6348 goto io_err;
6350 if(fprintf(f, "%s", cf_text_comment) == EOF)
6351 goto io_err;
6353 for(var = variables; var->name != NULL; var++){
6354 dprint((7,"write_pinerc: %s = %s\n",
6355 var->name ? var->name : "?",
6356 var->main_user_val.p ? var->main_user_val.p : "<not set>"));
6357 if(!var->is_user || !var->is_used || var->is_obsolete)
6358 continue;
6361 * set description to NULL to eliminate preceding
6362 * blank and comment line.
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->main_user_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->main_user_val.l[i]; i++)
6377 if(fprintf(f, "%s%s%s%s\n", (i) ? "\t" : var->name,
6378 (i) ? "" : "=", var->main_user_val.l[i],
6379 var->main_user_val.l[i+1] ? ",":"") == EOF)
6380 goto io_err;
6382 }else{
6383 if(var->main_user_val.p == NULL){
6384 if(fprintf(f, "%s=\n", var->name) == EOF)
6385 goto io_err;
6386 }else if(strlen(var->main_user_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->main_user_val.p) == EOF)
6391 goto io_err;
6395 exit(0);
6398 io_err:
6399 snprintf(buf, sizeof(buf), "Error writing config to %s: %s\n",
6400 filename, error_description(errno));
6401 exceptional_exit(buf, -1);
6405 /*----------------------------------------------------------------------
6406 Set a user variable and save the .pinerc
6408 Args: var -- The index of the variable to set from conftype.h (V_....)
6409 value -- The string to set the value to
6411 Result: -1 is returned on failure and 0 is returned on success
6413 The vars data structure is updated and the pinerc saved.
6414 ----*/
6416 set_variable(int var, char *value, int expand, int commit, EditWhich which)
6418 struct variable *v;
6419 char **apval;
6420 PINERC_S *prc;
6422 v = &ps_global->vars[var];
6424 if(!v->is_user)
6425 panic1("Trying to set non-user variable %s", v->name);
6427 /* Override value of which, at most one of these should be set */
6428 if(v->is_onlymain)
6429 which = Main;
6430 else if(v->is_outermost)
6431 which = ps_global->ew_for_except_vars;
6433 apval = APVAL(v, which);
6435 if(!apval)
6436 return(-1);
6438 if(*apval)
6439 fs_give((void **)apval);
6441 *apval = value ? cpystr(value) : NULL;
6442 set_current_val(v, expand, FALSE);
6444 switch(which){
6445 case Main:
6446 prc = ps_global->prc;
6447 break;
6448 case Post:
6449 prc = ps_global->post_prc;
6450 break;
6451 default:
6452 break;
6455 if(prc)
6456 prc->outstanding_pinerc_changes = 1;
6458 return(commit ? write_pinerc(ps_global, which, WRP_NONE) : 0);
6462 /*----------------------------------------------------------------------
6463 Set a user variable list and save the .pinerc
6465 Args: var -- The index of the variable to set from conftype.h (V_....)
6466 lvalue -- The list to set the value to
6468 Result: -1 is returned on failure and 0 is returned on success
6470 The vars data structure is updated and if write_it, the pinerc is saved.
6471 ----*/
6473 set_variable_list(int var, char **lvalue, int write_it, EditWhich which)
6475 char ***alval;
6476 int i;
6477 struct variable *v = &ps_global->vars[var];
6478 PINERC_S *prc;
6480 if(!v->is_user || !v->is_list)
6481 panic1("BOTCH: Trying to set non-user or non-list variable %s", v->name);
6483 /* Override value of which, at most one of these should be set */
6484 if(v->is_onlymain)
6485 which = Main;
6486 else if(v->is_outermost)
6487 which = ps_global->ew_for_except_vars;
6489 alval = ALVAL(v, which);
6490 if(!alval)
6491 return(-1);
6493 if(*alval)
6494 free_list_array(alval);
6496 if(lvalue){
6497 for(i = 0; lvalue[i] ; i++) /* count elements */
6500 *alval = (char **) fs_get((i+1) * sizeof(char *));
6502 for(i = 0; lvalue[i] ; i++)
6503 (*alval)[i] = cpystr(lvalue[i]);
6505 (*alval)[i] = NULL;
6508 set_current_val(v, TRUE, FALSE);
6510 switch(which){
6511 case Main:
6512 prc = ps_global->prc;
6513 break;
6514 case Post:
6515 prc = ps_global->post_prc;
6516 break;
6517 default:
6518 break;
6521 if(prc)
6522 prc->outstanding_pinerc_changes = 1;
6524 return(write_it ? write_pinerc(ps_global, which, WRP_NONE) : 0);
6528 void
6529 set_current_color_vals(struct pine *ps)
6531 struct variable *vars = ps->vars;
6532 int later_color_is_set = 0;
6534 set_current_val(&vars[V_NORM_FORE_COLOR], TRUE, TRUE);
6535 set_current_val(&vars[V_NORM_BACK_COLOR], TRUE, TRUE);
6536 pico_nfcolor(VAR_NORM_FORE_COLOR);
6537 pico_nbcolor(VAR_NORM_BACK_COLOR);
6539 set_current_val(&vars[V_REV_FORE_COLOR], TRUE, TRUE);
6540 set_current_val(&vars[V_REV_BACK_COLOR], TRUE, TRUE);
6541 pico_rfcolor(VAR_REV_FORE_COLOR);
6542 pico_rbcolor(VAR_REV_BACK_COLOR);
6544 set_color_val(&vars[V_TITLE_FORE_COLOR], 1);
6545 set_color_val(&vars[V_TITLECLOSED_FORE_COLOR], 0);
6546 set_color_val(&vars[V_FOLDER_FORE_COLOR], 0);
6547 set_color_val(&vars[V_DIRECTORY_FORE_COLOR], 0);
6548 set_color_val(&vars[V_FOLDER_LIST_FORE_COLOR], 0);
6549 set_color_val(&vars[V_STATUS_FORE_COLOR], 1);
6550 set_color_val(&vars[V_KEYLABEL_FORE_COLOR], 1);
6551 set_color_val(&vars[V_KEYNAME_FORE_COLOR], 1);
6552 set_color_val(&vars[V_SLCTBL_FORE_COLOR], 1);
6553 set_color_val(&vars[V_METAMSG_FORE_COLOR], 1);
6554 set_color_val(&vars[V_PROMPT_FORE_COLOR], 1);
6555 set_color_val(&vars[V_HEADER_GENERAL_FORE_COLOR], 1);
6556 set_color_val(&vars[V_IND_PLUS_FORE_COLOR], 0);
6557 set_color_val(&vars[V_IND_IMP_FORE_COLOR], 0);
6558 set_color_val(&vars[V_IND_DEL_FORE_COLOR], 0);
6559 set_color_val(&vars[V_IND_HIPRI_FORE_COLOR], 0);
6560 set_color_val(&vars[V_IND_LOPRI_FORE_COLOR], 0);
6561 set_color_val(&vars[V_IND_ANS_FORE_COLOR], 0);
6562 set_color_val(&vars[V_IND_NEW_FORE_COLOR], 0);
6563 set_color_val(&vars[V_IND_REC_FORE_COLOR], 0);
6564 set_color_val(&vars[V_IND_FWD_FORE_COLOR], 0);
6565 set_color_val(&vars[V_IND_UNS_FORE_COLOR], 0);
6566 set_color_val(&vars[V_IND_ARR_FORE_COLOR], 0);
6567 set_color_val(&vars[V_IND_SUBJ_FORE_COLOR], 0);
6568 set_color_val(&vars[V_IND_FROM_FORE_COLOR], 0);
6569 set_color_val(&vars[V_IND_OP_FORE_COLOR], 0);
6570 set_color_val(&vars[V_INCUNSEEN_FORE_COLOR], 0);
6571 set_color_val(&vars[V_SIGNATURE_FORE_COLOR], 0);
6573 set_current_val(&ps->vars[V_INDEX_TOKEN_COLORS], TRUE, TRUE);
6574 set_current_val(&ps->vars[V_VIEW_HDR_COLORS], TRUE, TRUE);
6575 set_current_val(&ps->vars[V_KW_COLORS], TRUE, TRUE);
6576 set_custom_spec_colors(ps);
6579 * Set up the quoting colors. If a later color is set but not an earlier
6580 * color we set the earlier color to Normal to make it easier when
6581 * we go to use the colors. However, if the only quote colors set are
6582 * Normal that is the same as no settings, so delete them.
6584 set_color_val(&vars[V_QUOTE1_FORE_COLOR], 0);
6585 set_color_val(&vars[V_QUOTE2_FORE_COLOR], 0);
6586 set_color_val(&vars[V_QUOTE3_FORE_COLOR], 0);
6588 if((!(VAR_QUOTE3_FORE_COLOR && VAR_QUOTE3_BACK_COLOR) ||
6589 (!strucmp(VAR_QUOTE3_FORE_COLOR, VAR_NORM_FORE_COLOR) &&
6590 !strucmp(VAR_QUOTE3_BACK_COLOR, VAR_NORM_BACK_COLOR))) &&
6591 (!(VAR_QUOTE2_FORE_COLOR && VAR_QUOTE2_BACK_COLOR) ||
6592 (!strucmp(VAR_QUOTE2_FORE_COLOR, VAR_NORM_FORE_COLOR) &&
6593 !strucmp(VAR_QUOTE2_BACK_COLOR, VAR_NORM_BACK_COLOR))) &&
6594 (!(VAR_QUOTE1_FORE_COLOR && VAR_QUOTE1_BACK_COLOR) ||
6595 (!strucmp(VAR_QUOTE1_FORE_COLOR, VAR_NORM_FORE_COLOR) &&
6596 !strucmp(VAR_QUOTE1_BACK_COLOR, VAR_NORM_BACK_COLOR)))){
6598 * They are all either Normal or not set. Delete them all.
6600 if(VAR_QUOTE3_FORE_COLOR)
6601 fs_give((void **)&VAR_QUOTE3_FORE_COLOR);
6602 if(VAR_QUOTE3_BACK_COLOR)
6603 fs_give((void **)&VAR_QUOTE3_BACK_COLOR);
6604 if(VAR_QUOTE2_FORE_COLOR)
6605 fs_give((void **)&VAR_QUOTE2_FORE_COLOR);
6606 if(VAR_QUOTE2_BACK_COLOR)
6607 fs_give((void **)&VAR_QUOTE2_BACK_COLOR);
6608 if(VAR_QUOTE1_FORE_COLOR)
6609 fs_give((void **)&VAR_QUOTE1_FORE_COLOR);
6610 if(VAR_QUOTE1_BACK_COLOR)
6611 fs_give((void **)&VAR_QUOTE1_BACK_COLOR);
6613 else{ /* something is non-Normal */
6614 if(VAR_QUOTE3_FORE_COLOR && VAR_QUOTE3_BACK_COLOR)
6615 later_color_is_set++;
6617 /* if 3 is set but not 2, set 2 to Normal */
6618 if(VAR_QUOTE2_FORE_COLOR && VAR_QUOTE2_BACK_COLOR)
6619 later_color_is_set++;
6620 else if(later_color_is_set)
6621 set_color_val(&vars[V_QUOTE2_FORE_COLOR], 1);
6623 /* if 3 or 2 is set but not 1, set 1 to Normal */
6624 if(VAR_QUOTE1_FORE_COLOR && VAR_QUOTE1_BACK_COLOR)
6625 later_color_is_set++;
6626 else if(later_color_is_set)
6627 set_color_val(&vars[V_QUOTE1_FORE_COLOR], 1);
6630 #ifdef _WINDOWS
6631 if(ps->pre441){
6632 int conv_main = 0, conv_post = 0;
6634 ps->pre441 = 0;
6635 if(ps->prc && !unix_color_style_in_pinerc(ps->prc)){
6636 conv_main = convert_pc_gray_names(ps, ps->prc, Main);
6637 if(conv_main)
6638 ps->prc->outstanding_pinerc_changes = 1;
6642 if(ps->post_prc && !unix_color_style_in_pinerc(ps->post_prc)){
6643 conv_post = convert_pc_gray_names(ps, ps->post_prc, Post);
6644 if(conv_post)
6645 ps->post_prc->outstanding_pinerc_changes = 1;
6648 if(conv_main || conv_post){
6649 if(conv_main)
6650 write_pinerc(ps, Main, WRP_NONE);
6652 if(conv_post)
6653 write_pinerc(ps, Post, WRP_NONE);
6655 set_current_color_vals(ps);
6658 #endif /* _WINDOWS */
6660 pico_set_normal_color();
6665 * Set current_val for the foreground and background color vars, which
6666 * are assumed to be in order. If a set_current_val on them doesn't
6667 * produce current_vals, then use the colors from defvar to set those
6668 * current_vals.
6670 void
6671 set_color_val(struct variable *v, int use_default)
6673 set_current_val(v, TRUE, TRUE);
6674 set_current_val(v+1, TRUE, TRUE);
6676 if(!(v->current_val.p && v->current_val.p[0] &&
6677 (v+1)->current_val.p && (v+1)->current_val.p[0])){
6678 struct variable *defvar;
6680 if(v->current_val.p)
6681 fs_give((void **)&v->current_val.p);
6682 if((v+1)->current_val.p)
6683 fs_give((void **)&(v+1)->current_val.p);
6685 if(!use_default)
6686 return;
6688 if(var_defaults_to_rev(v))
6689 defvar = &ps_global->vars[V_REV_FORE_COLOR];
6690 else
6691 defvar = &ps_global->vars[V_NORM_FORE_COLOR];
6693 /* use default vars values instead */
6694 if(defvar && defvar->current_val.p && defvar->current_val.p[0] &&
6695 (defvar+1)->current_val.p && (defvar+1)->current_val.p[0]){
6696 v->current_val.p = cpystr(defvar->current_val.p);
6697 (v+1)->current_val.p = cpystr((defvar+1)->current_val.p);
6704 var_defaults_to_rev(struct variable *v)
6706 return(v == &ps_global->vars[V_REV_FORE_COLOR] ||
6707 v == &ps_global->vars[V_TITLE_FORE_COLOR] ||
6708 v == &ps_global->vars[V_STATUS_FORE_COLOR] ||
6709 v == &ps_global->vars[V_KEYNAME_FORE_COLOR] ||
6710 v == &ps_global->vars[V_PROMPT_FORE_COLOR]);
6716 * Each item in the list looks like:
6718 * /HDR=<header>/FG=<foreground color>/BG=<background color>
6720 * We separate the three pieces into an array of structures to make
6721 * it easier to deal with later.
6723 void
6724 set_custom_spec_colors(struct pine *ps)
6726 if(ps->index_token_colors)
6727 free_spec_colors(&ps->index_token_colors);
6729 ps->index_token_colors = spec_colors_from_varlist(ps->VAR_INDEX_TOKEN_COLORS, 1);
6731 if(ps->hdr_colors)
6732 free_spec_colors(&ps->hdr_colors);
6734 ps->hdr_colors = spec_colors_from_varlist(ps->VAR_VIEW_HDR_COLORS, 1);
6736 /* fit keyword colors into the same structures for code re-use */
6737 if(ps->kw_colors)
6738 free_spec_colors(&ps->kw_colors);
6740 ps->kw_colors = spec_colors_from_varlist(ps->VAR_KW_COLORS, 1);
6745 * Input is one item from config variable.
6747 * Return value must be freed by caller. The return is a single SPEC_COLOR_S,
6748 * not a list.
6750 SPEC_COLOR_S *
6751 spec_color_from_var(char *t, int already_expanded)
6753 char *p, *spec, *fg, *bg;
6754 PATTERN_S *val;
6755 SPEC_COLOR_S *new_hcolor = NULL;
6757 if(t && t[0] && !strcmp(t, INHERIT)){
6758 new_hcolor = (SPEC_COLOR_S *)fs_get(sizeof(*new_hcolor));
6759 memset((void *)new_hcolor, 0, sizeof(*new_hcolor));
6760 new_hcolor->inherit = 1;
6762 else if(t && t[0]){
6763 char tbuf[10000];
6765 if(!already_expanded){
6766 tbuf[0] = '\0';
6767 if(expand_variables(tbuf, sizeof(tbuf), t, 0))
6768 t = tbuf;
6771 spec = fg = bg = NULL;
6772 val = NULL;
6773 if((p = srchstr(t, "/HDR=")) != NULL)
6774 spec = remove_backslash_escapes(p+5);
6775 if((p = srchstr(t, "/FG=")) != NULL)
6776 fg = remove_backslash_escapes(p+4);
6777 if((p = srchstr(t, "/BG=")) != NULL)
6778 bg = remove_backslash_escapes(p+4);
6779 val = parse_pattern("VAL", t, 0);
6781 if(spec && *spec){
6782 /* remove colons */
6783 if((p = strindex(spec, ':')) != NULL)
6784 *p = '\0';
6786 new_hcolor = (SPEC_COLOR_S *)fs_get(sizeof(*new_hcolor));
6787 memset((void *)new_hcolor, 0, sizeof(*new_hcolor));
6788 new_hcolor->spec = spec;
6789 new_hcolor->fg = fg;
6790 new_hcolor->bg = bg;
6791 new_hcolor->val = val;
6793 else{
6794 if(spec)
6795 fs_give((void **)&spec);
6796 if(fg)
6797 fs_give((void **)&fg);
6798 if(bg)
6799 fs_give((void **)&bg);
6800 if(val)
6801 free_pattern(&val);
6805 return(new_hcolor);
6810 * Input is a list from config file.
6812 * Return value may be a list of SPEC_COLOR_S and must be freed by caller.
6814 SPEC_COLOR_S *
6815 spec_colors_from_varlist(char **varlist, int already_expanded)
6817 char **s, *t;
6818 SPEC_COLOR_S *new_hc = NULL;
6819 SPEC_COLOR_S *new_hcolor, **nexthc;
6821 nexthc = &new_hc;
6822 if(varlist){
6823 for(s = varlist; (t = *s) != NULL; s++){
6824 if(t[0]){
6825 new_hcolor = spec_color_from_var(t, already_expanded);
6826 if(new_hcolor){
6827 *nexthc = new_hcolor;
6828 nexthc = &new_hcolor->next;
6834 return(new_hc);
6839 * Returns allocated charstar suitable for config var for a single
6840 * SPEC_COLOR_S.
6842 char *
6843 var_from_spec_color(SPEC_COLOR_S *hc)
6845 char *ret_val = NULL;
6846 char *p, *spec = NULL, *fg = NULL, *bg = NULL, *val = NULL;
6847 size_t len;
6849 if(hc && hc->inherit)
6850 ret_val = cpystr(INHERIT);
6851 else if(hc){
6852 if(hc->spec)
6853 spec = add_viewerhdr_escapes(hc->spec);
6854 if(hc->fg)
6855 fg = add_viewerhdr_escapes(hc->fg);
6856 if(hc->bg)
6857 bg = add_viewerhdr_escapes(hc->bg);
6858 if(hc->val){
6859 p = pattern_to_string(hc->val);
6860 if(p){
6861 val = add_viewerhdr_escapes(p);
6862 fs_give((void **)&p);
6866 len = strlen("/HDR=/FG=/BG=") + strlen(spec ? spec : "") +
6867 strlen(fg ? fg : "") + strlen(bg ? bg : "") +
6868 strlen(val ? "/VAL=" : "") + strlen(val ? val : "");
6869 ret_val = (char *) fs_get(len + 1);
6870 snprintf(ret_val, len+1, "/HDR=%s/FG=%s/BG=%s%s%s",
6871 spec ? spec : "", fg ? fg : "", bg ? bg : "",
6872 val ? "/VAL=" : "", val ? val : "");
6874 if(spec)
6875 fs_give((void **)&spec);
6876 if(fg)
6877 fs_give((void **)&fg);
6878 if(bg)
6879 fs_give((void **)&bg);
6880 if(val)
6881 fs_give((void **)&val);
6884 return(ret_val);
6889 * Returns allocated charstar suitable for config var for a single
6890 * SPEC_COLOR_S.
6892 char **
6893 varlist_from_spec_colors(SPEC_COLOR_S *hcolors)
6895 SPEC_COLOR_S *hc;
6896 char **ret_val = NULL;
6897 int i;
6899 /* count how many */
6900 for(hc = hcolors, i = 0; hc; hc = hc->next, i++)
6903 ret_val = (char **)fs_get((i+1) * sizeof(*ret_val));
6904 memset((void *)ret_val, 0, (i+1) * sizeof(*ret_val));
6905 for(hc = hcolors, i = 0; hc; hc = hc->next, i++)
6906 ret_val[i] = var_from_spec_color(hc);
6908 return(ret_val);
6912 void
6913 update_posting_charset(struct pine *ps, int revert)
6915 #ifndef _WINDOWS
6916 if(F_ON(F_USE_SYSTEM_TRANS, ps)){
6917 if(!revert)
6918 q_status_message(SM_ORDER, 5, 5, _("This change has no effect because feature Use-System-Translation is on"));
6920 else{
6921 #endif /* ! _WINDOWS */
6922 if(ps->posting_charmap)
6923 fs_give((void **) &ps->posting_charmap);
6925 if(ps->VAR_POST_CHAR_SET){
6926 ps->posting_charmap = cpystr(ps->VAR_POST_CHAR_SET);
6927 if(!posting_charset_is_supported(ps->posting_charmap)){
6928 snprintf(tmp_20k_buf, SIZEOF_20KBUF,
6929 _("Posting-Character set \"%s\" is unsupported, using UTF-8"),
6930 ps->posting_charmap);
6931 q_status_message(SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
6932 fs_give((void **) &ps->posting_charmap);
6933 ps->posting_charmap = cpystr("UTF-8");
6936 else
6937 ps->posting_charmap = cpystr("UTF-8");
6938 #ifndef _WINDOWS
6940 #endif /* ! _WINDOWS */
6944 #define FIXED_COMMENT _("(fixed)")
6945 #define DEFAULT_COMMENT _("(default)")
6946 #define OVERRIDE_COMMENT _("(overridden)")
6949 feature_gets_an_x(struct pine *ps, struct variable *var, FEATURE_S *feature,
6950 char **comment, EditWhich ew)
6952 char **lval, **lvalexc, **lvalnorm;
6953 char *def = DEFAULT_COMMENT;
6954 int j, done = 0;
6955 int feature_fixed_on = 0, feature_fixed_off = 0;
6957 if(comment)
6958 *comment = NULL;
6960 lval = LVAL(var, ew);
6961 lvalexc = LVAL(var, ps->ew_for_except_vars);
6962 lvalnorm = LVAL(var, Main);
6964 /* feature value is administratively fixed */
6965 if((j = feature_in_list(var->fixed_val.l, feature->name)) != 0){
6966 if(j == 1)
6967 feature_fixed_on++;
6968 else if(j == -1)
6969 feature_fixed_off++;
6971 done++;
6972 if(comment)
6973 *comment = FIXED_COMMENT;
6977 * We have an exceptions config setting which overrides anything
6978 * we do here, in the normal config.
6980 if(!done &&
6981 ps->ew_for_except_vars != Main && ew == Main &&
6982 feature_in_list(lvalexc, feature->name)){
6983 done++;
6984 if(comment)
6985 *comment = OVERRIDE_COMMENT;
6989 * Feature is set On in default but not set here.
6991 if(!done &&
6992 !feature_in_list(lval, feature->name) &&
6993 ((feature_in_list(var->global_val.l, feature->name) == 1) ||
6994 ((ps->ew_for_except_vars != Main &&
6995 ew == ps->ew_for_except_vars &&
6996 feature_in_list(lvalnorm, feature->name) == 1)))){
6997 done = 17;
6998 if(comment)
6999 *comment = def;
7002 if(!done &&
7003 feature->defval &&
7004 !feature_in_list(lval, feature->name) &&
7005 !feature_in_list(var->global_val.l, feature->name) &&
7006 (ps->ew_for_except_vars == Main ||
7007 ew != ps->ew_for_except_vars ||
7008 !feature_in_list(lvalnorm, feature->name))){
7009 done = 17;
7010 if(comment)
7011 *comment = def;
7014 return(feature_fixed_on ||
7015 (!feature_fixed_off &&
7016 (done == 17 ||
7017 test_feature(lval, feature->name,
7018 test_old_growth_bits(ps, feature->id)))));
7023 longest_feature_comment(struct pine *ps, EditWhich ew)
7025 int lc = 0;
7027 lc = MAX(lc, utf8_width(FIXED_COMMENT));
7028 lc = MAX(lc, utf8_width(DEFAULT_COMMENT));
7029 if(ps->ew_for_except_vars != Main && ew == Main)
7030 lc = MAX(lc, utf8_width(OVERRIDE_COMMENT));
7032 return(lc);
7036 void
7037 toggle_feature(struct pine *ps, struct variable *var, FEATURE_S *f,
7038 int just_flip_value, EditWhich ew)
7040 char **vp, *p, **lval, ***alval;
7041 int og, on_before, was_set;
7042 char *err;
7043 long l;
7045 og = test_old_growth_bits(ps, f->id);
7048 * if this feature is in the fixed set, or old-growth is in the fixed
7049 * set and this feature is in the old-growth set, don't alter it...
7051 for(vp = var->fixed_val.l; vp && *vp; vp++){
7052 p = (struncmp(*vp, "no-", 3)) ? *vp : *vp + 3;
7053 if(!strucmp(p, f->name) || (og && !strucmp(p, "old-growth"))){
7054 q_status_message(SM_ORDER, 3, 3,
7055 /* TRANSLATORS: In the configuration screen, telling the user we
7056 can't change this option because the system administrator
7057 prohibits it. */
7058 _("Can't change value fixed by sys-admin."));
7059 return;
7063 on_before = F_ON(f->id, ps);
7065 lval = LVAL(var, ew);
7066 alval = ALVAL(var, ew);
7067 if(just_flip_value)
7068 was_set = test_feature(lval, f->name, og);
7069 else
7070 was_set = feature_gets_an_x(ps, var, f, NULL, ew);
7072 if(alval)
7073 set_feature(alval, f->name, !was_set);
7075 set_feature_list_current_val(var);
7076 process_feature_list(ps, var->current_val.l, 0, 0, 0);
7079 * Handle any features that need special attention here...
7081 if(on_before != F_ON(f->id, ps))
7082 switch(f->id){
7083 case F_QUOTE_ALL_FROMS :
7084 mail_parameters(NULL,SET_FROMWIDGET,F_ON(f->id,ps) ? VOIDT : NIL);
7085 break;
7087 case F_FAKE_NEW_IN_NEWS :
7088 if(IS_NEWS(ps->mail_stream))
7089 q_status_message(SM_ORDER | SM_DING, 3, 4,
7090 "news-approximates-new-status won't affect current newsgroup until next open");
7092 break;
7094 case F_COLOR_LINE_IMPORTANT :
7095 case F_DATES_TO_LOCAL :
7096 clear_index_cache(ps->mail_stream, 0);
7097 break;
7099 case F_DISABLE_INDEX_LOCALE_DATES :
7100 reset_index_format();
7101 clear_index_cache(ps->mail_stream, 0);
7102 break;
7104 case F_MARK_FOR_CC :
7105 clear_index_cache(ps->mail_stream, 0);
7106 if(THREADING() && sp_viewing_a_thread(ps->mail_stream))
7107 unview_thread(ps, ps->mail_stream, ps->msgmap);
7109 break;
7111 case F_HIDE_NNTP_PATH :
7112 mail_parameters(NULL, SET_NNTPHIDEPATH,
7113 F_ON(f->id, ps) ? VOIDT : NIL);
7114 break;
7116 case F_MAILDROPS_PRESERVE_STATE :
7117 mail_parameters(NULL, SET_SNARFPRESERVE,
7118 F_ON(f->id, ps) ? VOIDT : NIL);
7119 break;
7121 case F_DISABLE_SHARED_NAMESPACES :
7122 mail_parameters(NULL, SET_DISABLEAUTOSHAREDNS,
7123 F_ON(f->id, ps) ? VOIDT : NIL);
7124 break;
7126 case F_QUELL_LOCK_FAILURE_MSGS :
7127 mail_parameters(NULL, SET_LOCKEACCESERROR,
7128 F_ON(f->id, ps) ? VOIDT : NIL);
7129 break;
7131 case F_MULNEWSRC_HOSTNAMES_AS_TYPED :
7132 l = F_ON(f->id, ps) ? 0L : 1L;
7133 mail_parameters(NULL, SET_NEWSRCCANONHOST, (void *) l);
7134 break;
7136 case F_QUELL_INTERNAL_MSG :
7137 mail_parameters(NULL, SET_USERHASNOLIFE,
7138 F_ON(f->id, ps) ? VOIDT : NIL);
7139 break;
7141 case F_DISABLE_SETLOCALE_COLLATE :
7142 set_collation(F_OFF(F_DISABLE_SETLOCALE_COLLATE, ps), 1);
7143 break;
7145 #ifndef _WINDOWS
7146 case F_USE_SYSTEM_TRANS :
7147 err = NULL;
7148 reset_character_set_stuff(&err);
7149 if(err){
7150 q_status_message(SM_ORDER | SM_DING, 3, 4, err);
7151 fs_give((void **) &err);
7154 break;
7155 #endif /* ! _WINDOWS */
7157 case F_ENABLE_INCOMING_CHECKING :
7158 if(!on_before && F_OFF(F_ENABLE_INCOMING, ps))
7159 q_status_message(SM_ORDER, 0, 3, _("This option has no effect without Enable-Incoming-Folders"));
7161 clear_incoming_valid_bits();
7162 break;
7164 case F_INCOMING_CHECKING_TOTAL :
7165 case F_INCOMING_CHECKING_RECENT :
7166 if(!on_before && F_OFF(F_ENABLE_INCOMING_CHECKING, ps))
7167 q_status_message(SM_ORDER, 0, 3, _("This option has no effect without Enable-Incoming-Folders-Checking"));
7169 clear_incoming_valid_bits();
7170 break;
7172 case F_THREAD_SORTS_BY_ARRIVAL :
7173 clear_index_cache(ps->mail_stream, 0);
7174 refresh_sort(ps->mail_stream, sp_msgmap(ps->mail_stream), SRT_NON);
7175 break;
7177 #ifdef SMIME
7178 case F_DONT_DO_SMIME :
7179 smime_deinit();
7180 break;
7182 #ifdef APPLEKEYCHAIN
7183 case F_PUBLICCERTS_IN_KEYCHAIN :
7184 smime_deinit();
7185 break;
7186 #endif
7187 #endif
7189 default :
7190 break;
7196 * Returns 1 -- Feature is in the list and positive
7197 * 0 -- Feature is not in the list at all
7198 * -1 -- Feature is in the list and negative (no-)
7201 feature_in_list(char **l, char *f)
7203 char *p;
7204 int rv = 0, forced_off;
7206 for(; l && *l; l++){
7207 p = (forced_off = !struncmp(*l, "no-", 3)) ? *l + 3 : *l;
7208 if(!strucmp(p, f))
7209 rv = forced_off ? -1 : 1;
7212 return(rv);
7217 * test_feature - runs thru a feature list, and returns:
7218 * 1 if feature explicitly set and matches 'v'
7219 * 0 if feature not explicitly set *or* doesn't match 'v'
7222 test_feature(char **l, char *f, int g)
7224 char *p;
7225 int rv = 0, forced_off;
7227 for(; l && *l; l++){
7228 p = (forced_off = !struncmp(*l, "no-", 3)) ? *l + 3 : *l;
7229 if(!strucmp(p, f))
7230 rv = !forced_off;
7231 else if(g && !strucmp(p, "old-growth"))
7232 rv = !forced_off;
7235 return(rv);
7239 void
7240 set_feature(char ***l, char *f, int v)
7242 char **list = l ? *l : NULL, newval[256];
7243 int count = 0;
7245 snprintf(newval, sizeof(newval), "%s%s", v ? "" : "no-", f);
7246 for(; list && *list; list++, count++)
7247 if((**list == '\0') /* anything can replace an empty value */
7248 || !strucmp(((!struncmp(*list, "no-", 3)) ? *list + 3 : *list), f)){
7249 fs_give((void **)list); /* replace with new value */
7250 *list = cpystr(newval);
7251 return;
7255 * if we got here, we didn't find it in the list, so grow the list
7256 * and add it..
7258 if(!*l)
7259 *l = (char **)fs_get((count + 2) * sizeof(char *));
7260 else
7261 fs_resize((void **)l, (count + 2) * sizeof(char *));
7263 (*l)[count] = cpystr(newval);
7264 (*l)[count + 1] = NULL;
7269 reset_character_set_stuff(char **err)
7271 int use_system = 0;
7272 char buf[1000];
7274 if(err)
7275 *err = NULL;
7277 if(ps_global->display_charmap)
7278 fs_give((void **) &ps_global->display_charmap);
7280 if(ps_global->keyboard_charmap)
7281 fs_give((void **) &ps_global->keyboard_charmap);
7283 if(ps_global->posting_charmap)
7284 fs_give((void **) &ps_global->posting_charmap);
7286 #ifdef _WINDOWS
7287 ps_global->display_charmap = cpystr("UTF-8");
7288 #else /* UNIX */
7289 if(ps_global->VAR_CHAR_SET)
7290 ps_global->display_charmap = cpystr(ps_global->VAR_CHAR_SET);
7291 else{
7292 #if HAVE_LANGINFO_H && defined(CODESET)
7293 ps_global->display_charmap = cpystr(nl_langinfo_codeset_wrapper());
7294 #else
7295 ps_global->display_charmap = cpystr("UTF-8");
7296 #endif
7298 #endif /* UNIX */
7300 if(!ps_global->display_charmap)
7301 ps_global->display_charmap = cpystr("US-ASCII");
7303 #ifdef _WINDOWS
7304 ps_global->keyboard_charmap = cpystr("UTF-8");
7305 #else /* UNIX */
7306 if(ps_global->VAR_KEY_CHAR_SET)
7307 ps_global->keyboard_charmap = cpystr(ps_global->VAR_KEY_CHAR_SET);
7308 else
7309 ps_global->keyboard_charmap = cpystr(ps_global->display_charmap);
7311 if(!ps_global->keyboard_charmap)
7312 ps_global->keyboard_charmap = cpystr("US-ASCII");
7314 if(F_ON(F_USE_SYSTEM_TRANS, ps_global)){
7315 #if PREREQ_FOR_SYS_TRANSLATION
7316 use_system++;
7317 /* This modifies its arguments */
7318 if(setup_for_input_output(use_system, &ps_global->display_charmap,
7319 &ps_global->keyboard_charmap,
7320 &ps_global->input_cs, (err && *err) ? NULL : err) == -1)
7321 return -1;
7322 #endif
7324 #endif /* UNIX */
7326 if(!use_system){
7327 if(setup_for_input_output(use_system, &ps_global->display_charmap,
7328 &ps_global->keyboard_charmap,
7329 &ps_global->input_cs, (err && *err) ? NULL : err) == -1)
7330 return -1;
7333 if(!use_system && ps_global->VAR_POST_CHAR_SET){
7334 ps_global->posting_charmap = cpystr(ps_global->VAR_POST_CHAR_SET);
7335 if(!posting_charset_is_supported(ps_global->posting_charmap)){
7336 if(err && !*err){
7337 snprintf(buf, sizeof(buf),
7338 _("Posting-Character-Set \"%s\" is unsupported, using UTF-8"),
7339 ps_global->posting_charmap);
7340 *err = cpystr(buf);
7343 fs_give((void **) &ps_global->posting_charmap);
7344 ps_global->posting_charmap = cpystr("UTF-8");
7347 else{
7348 if(use_system && ps_global->VAR_POST_CHAR_SET
7349 && strucmp(ps_global->VAR_POST_CHAR_SET, "UTF-8"))
7350 if(err && !*err)
7351 *err = cpystr(_("Posting-Character-Set is ignored with Use-System-Translation turned on"));
7353 ps_global->posting_charmap = cpystr("UTF-8");
7356 set_locale_charmap(ps_global->keyboard_charmap);
7358 return(0);
7363 * Given a single printer string from the config file, returns pointers
7364 * to alloc'd strings containing the printer nickname, the command,
7365 * the init string, the trailer string, everything but the nickname string,
7366 * and everything but the command string. All_but_cmd includes the trailing
7367 * space at the end (the one before the command) but all_but_nick does not
7368 * include the leading space (the one before the [).
7369 * If you pass in a pointer it is guaranteed to come back pointing to an
7370 * allocated string, even if it is just an empty string. It is ok to pass
7371 * NULL for any of the six return strings.
7373 void
7374 parse_printer(char *input, char **nick, char **cmd, char **init, char **trailer,
7375 char **all_but_nick, char **all_but_cmd)
7377 char *p, *q, *start, *saved_options = NULL;
7378 int tmpsave, cnt;
7380 if(!input)
7381 input = "";
7383 if(nick || all_but_nick){
7384 if((p = srchstr(input, " [")) != NULL){
7385 if(all_but_nick)
7386 *all_but_nick = cpystr(p+1);
7388 if(nick){
7389 while(p-1 > input && isspace((unsigned char)*(p-1)))
7390 p--;
7392 tmpsave = *p;
7393 *p = '\0';
7394 *nick = cpystr(input);
7395 *p = tmpsave;
7398 else{
7399 if(nick)
7400 *nick = cpystr("");
7402 if(all_but_nick)
7403 *all_but_nick = cpystr(input);
7407 if((p = srchstr(input, "] ")) != NULL){
7409 ++p;
7410 }while(isspace((unsigned char)*p));
7412 tmpsave = *p;
7413 *p = '\0';
7414 saved_options = cpystr(input);
7415 *p = tmpsave;
7417 else
7418 p = input;
7420 if(cmd)
7421 *cmd = cpystr(p);
7423 if(init){
7424 if(saved_options && (p = srchstr(saved_options, "INIT="))){
7425 start = p + strlen("INIT=");
7426 for(cnt=0, p = start; *p && *(p+1) && isxpair(p); p += 2)
7427 cnt++;
7429 q = *init = (char *)fs_get((cnt + 1) * sizeof(char));
7430 for(p = start; *p && *(p+1) && isxpair(p); p += 2)
7431 *q++ = read_hex(p);
7433 *q = '\0';
7435 else
7436 *init = cpystr("");
7439 if(trailer){
7440 if(saved_options && (p = srchstr(saved_options, "TRAILER="))){
7441 start = p + strlen("TRAILER=");
7442 for(cnt=0, p = start; *p && *(p+1) && isxpair(p); p += 2)
7443 cnt++;
7445 q = *trailer = (char *)fs_get((cnt + 1) * sizeof(char));
7446 for(p = start; *p && *(p+1) && isxpair(p); p += 2)
7447 *q++ = read_hex(p);
7449 *q = '\0';
7451 else
7452 *trailer = cpystr("");
7455 if(all_but_cmd){
7456 if(saved_options)
7457 *all_but_cmd = saved_options;
7458 else
7459 *all_but_cmd = cpystr("");
7461 else if(saved_options)
7462 fs_give((void **)&saved_options);
7467 copy_pinerc(char *local, char *remote, char **err_msg)
7469 return(copy_localfile_to_remotefldr(RemImap, local, remote,
7470 REMOTE_PINERC_SUBTYPE,
7471 err_msg));
7476 copy_abook(char *local, char *remote, char **err_msg)
7478 return(copy_localfile_to_remotefldr(RemImap, local, remote,
7479 REMOTE_ABOOK_SUBTYPE,
7480 err_msg));
7485 * Copy local file to remote folder.
7487 * Args remotetype -- type of remote folder
7488 * local -- name of local file
7489 * remote -- name of remote folder
7490 * subtype --
7492 * Returns 0 on success.
7495 copy_localfile_to_remotefldr(RemType remotetype, char *local, char *remote,
7496 char *subtype, char **err_msg)
7498 int retfail = -1;
7499 unsigned flags;
7500 REMDATA_S *rd;
7502 dprint((9, "copy_localfile_to_remotefldr(%s,%s)\n",
7503 local ? local : "<null>",
7504 remote ? remote : "<null>"));
7506 *err_msg = (char *)fs_get(MAXPATH * sizeof(char));
7508 if(!local || !*local){
7509 snprintf(*err_msg, MAXPATH, _("No local file specified"));
7510 return(retfail);
7513 if(!remote || !*remote){
7514 snprintf(*err_msg, MAXPATH, _("No remote folder specified"));
7515 return(retfail);
7518 if(!IS_REMOTE(remote)){
7519 snprintf(*err_msg, MAXPATH, _("Remote folder name \"%s\" %s"), remote,
7520 (*remote != '{') ? _("must begin with \"{\"") : _("not valid"));
7521 return(retfail);
7524 if(IS_REMOTE(local)){
7525 snprintf(*err_msg, MAXPATH, _("First argument \"%s\" must be a local filename"),
7526 local);
7527 return(retfail);
7530 if(can_access(local, ACCESS_EXISTS) != 0){
7531 snprintf(*err_msg, MAXPATH, _("Local file \"%s\" does not exist"), local);
7532 return(retfail);
7535 if(can_access(local, READ_ACCESS) != 0){
7536 snprintf(*err_msg, MAXPATH, _("Can't read local file \"%s\": %s"),
7537 local, error_description(errno));
7538 return(retfail);
7542 * Check if remote folder exists and create it if it doesn't.
7544 flags = 0;
7545 rd = rd_create_remote(remotetype, remote, subtype,
7546 &flags, _("Error: "), _("Can't copy to remote folder."));
7548 if(!rd || rd->access == NoExists){
7549 snprintf(*err_msg, MAXPATH, _("Can't create \"%s\""), remote);
7550 if(rd)
7551 rd_free_remdata(&rd);
7553 return(retfail);
7556 if(rd->access == MaybeRorW)
7557 rd->access = ReadWrite;
7559 rd->flags |= (NO_META_UPDATE | DO_REMTRIM);
7560 rd->lf = cpystr(local);
7562 rd_open_remote(rd);
7563 if(!rd_stream_exists(rd)){
7564 snprintf(*err_msg, MAXPATH, _("Can't open remote folder \"%s\""), rd->rn);
7565 rd_free_remdata(&rd);
7566 return(retfail);
7569 if(rd_remote_is_readonly(rd)){
7570 snprintf(*err_msg, MAXPATH, _("Remote folder \"%s\" is readonly"), rd->rn);
7571 rd_free_remdata(&rd);
7572 return(retfail);
7575 switch(rd->type){
7576 case RemImap:
7578 * Empty folder, add a header msg.
7580 if(rd->t.i.stream->nmsgs == 0){
7581 if(rd_init_remote(rd, 1) != 0){
7582 snprintf(*err_msg, MAXPATH,
7583 _("Failed initializing remote folder \"%s\", check debug file"),
7584 rd->rn);
7585 rd_free_remdata(&rd);
7586 return(retfail);
7590 fs_give((void **)err_msg);
7591 *err_msg = NULL;
7592 if(rd_chk_for_hdr_msg(&(rd->t.i.stream), rd, err_msg)){
7593 rd_free_remdata(&rd);
7594 return(retfail);
7597 break;
7599 default:
7600 break;
7603 if(rd_update_remote(rd, NULL) != 0){
7604 snprintf(*err_msg, MAXPATH, _("Error copying to remote folder \"%s\""), rd->rn);
7605 rd_free_remdata(&rd);
7606 return(retfail);
7609 rd_update_metadata(rd, NULL);
7610 rd_close_remdata(&rd);
7612 fs_give((void **)err_msg);
7613 return(0);
7617 /*----------------------------------------------------------------------
7618 Panic pine - call on detected programmatic errors to exit pine, with arg
7620 Input: message -- printf styule string for panic message (see above)
7621 arg -- argument for printf string
7623 Result: The various tty modes are restored
7624 If debugging is active a core dump will be generated
7625 Exits Pine
7626 ----*/
7627 void
7628 panic1(char *message, char *arg)
7630 #define SIZEOFBUF 1001
7631 char buf1[SIZEOFBUF], buf2[SIZEOFBUF];
7633 snprintf(buf1, sizeof(buf1), "%.*s", (int) MAX(SIZEOFBUF - 1 - strlen(message), 0), arg);
7634 snprintf(buf2, sizeof(buf2), message, buf1);
7635 alpine_panic(buf2);
7642 HelpType
7643 config_help(int var, int feature)
7645 switch(var){
7646 case V_FEATURE_LIST :
7647 return(feature_list_help(feature));
7648 break;
7650 case V_PERSONAL_NAME :
7651 return(h_config_pers_name);
7652 case V_USER_ID :
7653 return(h_config_user_id);
7654 case V_USER_DOMAIN :
7655 return(h_config_user_dom);
7656 case V_SMTP_SERVER :
7657 return(h_config_smtp_server);
7658 case V_NNTP_SERVER :
7659 return(h_config_nntp_server);
7660 case V_INBOX_PATH :
7661 return(h_config_inbox_path);
7662 case V_PRUNED_FOLDERS :
7663 return(h_config_pruned_folders);
7664 case V_DEFAULT_FCC :
7665 return(h_config_default_fcc);
7666 case V_DEFAULT_SAVE_FOLDER :
7667 return(h_config_def_save_folder);
7668 case V_POSTPONED_FOLDER :
7669 return(h_config_postponed_folder);
7670 case V_READ_MESSAGE_FOLDER :
7671 return(h_config_read_message_folder);
7672 case V_FORM_FOLDER :
7673 return(h_config_form_folder);
7674 case V_ARCHIVED_FOLDERS :
7675 return(h_config_archived_folders);
7676 case V_SIGNATURE_FILE :
7677 return(h_config_signature_file);
7678 case V_LITERAL_SIG :
7679 return(h_config_literal_sig);
7680 case V_INIT_CMD_LIST :
7681 return(h_config_init_cmd_list);
7682 case V_COMP_HDRS :
7683 return(h_config_comp_hdrs);
7684 case V_CUSTOM_HDRS :
7685 return(h_config_custom_hdrs);
7686 case V_VIEW_HEADERS :
7687 return(h_config_viewer_headers);
7688 case V_VIEW_MARGIN_LEFT :
7689 return(h_config_viewer_margin_left);
7690 case V_VIEW_MARGIN_RIGHT :
7691 return(h_config_viewer_margin_right);
7692 case V_QUOTE_SUPPRESSION :
7693 return(h_config_quote_suppression);
7694 case V_SAVED_MSG_NAME_RULE :
7695 return(h_config_saved_msg_name_rule);
7696 case V_FCC_RULE :
7697 return(h_config_fcc_rule);
7698 case V_SORT_KEY :
7699 return(h_config_sort_key);
7700 case V_AB_SORT_RULE :
7701 return(h_config_ab_sort_rule);
7702 case V_FLD_SORT_RULE :
7703 return(h_config_fld_sort_rule);
7704 case V_POST_CHAR_SET :
7705 return(h_config_post_char_set);
7706 case V_UNK_CHAR_SET :
7707 return(h_config_unk_char_set);
7708 #ifndef _WINDOWS
7709 case V_KEY_CHAR_SET :
7710 return(h_config_key_char_set);
7711 case V_CHAR_SET :
7712 return(h_config_char_set);
7713 #endif /* ! _WINDOWS */
7714 case V_EDITOR :
7715 return(h_config_editor);
7716 case V_SPELLER :
7717 return(h_config_speller);
7718 case V_DISPLAY_FILTERS :
7719 return(h_config_display_filters);
7720 case V_SEND_FILTER :
7721 return(h_config_sending_filter);
7722 case V_ALT_ADDRS :
7723 return(h_config_alt_addresses);
7724 case V_KEYWORDS :
7725 return(h_config_keywords);
7726 case V_KW_BRACES :
7727 return(h_config_kw_braces);
7728 case V_OPENING_SEP :
7729 return(h_config_opening_sep);
7730 case V_KW_COLORS :
7731 return(h_config_kw_color);
7732 case V_ABOOK_FORMATS :
7733 return(h_config_abook_formats);
7734 case V_INDEX_FORMAT :
7735 return(h_config_index_format);
7736 case V_INCCHECKTIMEO :
7737 return(h_config_incoming_timeo);
7738 case V_INCCHECKINTERVAL :
7739 return(h_config_incoming_interv);
7740 case V_INC2NDCHECKINTERVAL :
7741 return(h_config_incoming_second_interv);
7742 case V_INCCHECKLIST :
7743 return(h_config_incoming_list);
7744 case V_SLEEP :
7745 return(h_config_psleep);
7746 case V_OVERLAP :
7747 return(h_config_viewer_overlap);
7748 case V_MAXREMSTREAM :
7749 return(h_config_maxremstream);
7750 case V_PERMLOCKED :
7751 return(h_config_permlocked);
7752 case V_MARGIN :
7753 return(h_config_scroll_margin);
7754 case V_DEADLETS :
7755 return(h_config_deadlets);
7756 case V_FILLCOL :
7757 return(h_config_composer_wrap_column);
7758 case V_TCPOPENTIMEO :
7759 return(h_config_tcp_open_timeo);
7760 case V_TCPREADWARNTIMEO :
7761 return(h_config_tcp_readwarn_timeo);
7762 case V_TCPWRITEWARNTIMEO :
7763 return(h_config_tcp_writewarn_timeo);
7764 case V_TCPQUERYTIMEO :
7765 return(h_config_tcp_query_timeo);
7766 case V_RSHOPENTIMEO :
7767 return(h_config_rsh_open_timeo);
7768 case V_SSHOPENTIMEO :
7769 return(h_config_ssh_open_timeo);
7770 case V_USERINPUTTIMEO :
7771 return(h_config_user_input_timeo);
7772 case V_REMOTE_ABOOK_VALIDITY :
7773 return(h_config_remote_abook_validity);
7774 case V_REMOTE_ABOOK_HISTORY :
7775 return(h_config_remote_abook_history);
7776 case V_INCOMING_FOLDERS :
7777 return(h_config_incoming_folders);
7778 case V_FOLDER_SPEC :
7779 return(h_config_folder_spec);
7780 case V_NEWS_SPEC :
7781 return(h_config_news_spec);
7782 case V_ADDRESSBOOK :
7783 return(h_config_address_book);
7784 case V_GLOB_ADDRBOOK :
7785 return(h_config_glob_addrbook);
7786 case V_LAST_VERS_USED :
7787 return(h_config_last_vers);
7788 case V_SENDMAIL_PATH :
7789 return(h_config_sendmail_path);
7790 case V_OPER_DIR :
7791 return(h_config_oper_dir);
7792 case V_RSHPATH :
7793 return(h_config_rshpath);
7794 case V_RSHCMD :
7795 return(h_config_rshcmd);
7796 case V_SSHPATH :
7797 return(h_config_sshpath);
7798 case V_SSHCMD :
7799 return(h_config_sshcmd);
7800 case V_NEW_VER_QUELL :
7801 return(h_config_new_ver_quell);
7802 case V_DISABLE_DRIVERS :
7803 return(h_config_disable_drivers);
7804 case V_DISABLE_AUTHS :
7805 return(h_config_disable_auths);
7806 case V_REMOTE_ABOOK_METADATA :
7807 return(h_config_abook_metafile);
7808 case V_REPLY_STRING :
7809 return(h_config_reply_indent_string);
7810 case V_WORDSEPS :
7811 return(h_config_wordseps);
7812 case V_QUOTE_REPLACE_STRING :
7813 return(h_config_quote_replace_string);
7814 case V_REPLY_INTRO :
7815 return(h_config_reply_intro);
7816 case V_EMPTY_HDR_MSG :
7817 return(h_config_empty_hdr_msg);
7818 case V_STATUS_MSG_DELAY :
7819 return(h_config_status_msg_delay);
7820 case V_ACTIVE_MSG_INTERVAL :
7821 return(h_config_active_msg_interval);
7822 case V_MAILCHECK :
7823 return(h_config_mailcheck);
7824 case V_MAILCHECKNONCURR :
7825 return(h_config_mailchecknoncurr);
7826 case V_MAILDROPCHECK :
7827 return(h_config_maildropcheck);
7828 case V_NNTPRANGE :
7829 return(h_config_nntprange);
7830 case V_NEWS_ACTIVE_PATH :
7831 return(h_config_news_active);
7832 case V_NEWS_SPOOL_DIR :
7833 return(h_config_news_spool);
7834 case V_IMAGE_VIEWER :
7835 return(h_config_image_viewer);
7836 case V_USE_ONLY_DOMAIN_NAME :
7837 return(h_config_domain_name);
7838 case V_LAST_TIME_PRUNE_QUESTION :
7839 return(h_config_prune_date);
7840 case V_UPLOAD_CMD:
7841 return(h_config_upload_cmd);
7842 case V_UPLOAD_CMD_PREFIX:
7843 return(h_config_upload_prefix);
7844 case V_DOWNLOAD_CMD:
7845 return(h_config_download_cmd);
7846 case V_DOWNLOAD_CMD_PREFIX:
7847 return(h_config_download_prefix);
7848 case V_GOTO_DEFAULT_RULE:
7849 return(h_config_goto_default);
7850 case V_INCOMING_STARTUP:
7851 return(h_config_inc_startup);
7852 case V_PRUNING_RULE:
7853 return(h_config_pruning_rule);
7854 case V_REOPEN_RULE:
7855 return(h_config_reopen_rule);
7856 case V_THREAD_DISP_STYLE:
7857 return(h_config_thread_disp_style);
7858 case V_THREAD_INDEX_STYLE:
7859 return(h_config_thread_index_style);
7860 case V_THREAD_MORE_CHAR:
7861 return(h_config_thread_indicator_char);
7862 case V_THREAD_EXP_CHAR:
7863 return(h_config_thread_exp_char);
7864 case V_THREAD_LASTREPLY_CHAR:
7865 return(h_config_thread_lastreply_char);
7866 case V_MAILCAP_PATH :
7867 return(h_config_mailcap_path);
7868 case V_MIMETYPE_PATH :
7869 return(h_config_mimetype_path);
7870 #if !defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO)
7871 case V_FIFOPATH :
7872 return(h_config_fifopath);
7873 #endif
7874 case V_NMW_WIDTH :
7875 return(h_config_newmailwidth);
7876 case V_NEWSRC_PATH :
7877 return(h_config_newsrc_path);
7878 case V_BROWSER :
7879 return(h_config_browser);
7880 #if defined(DOS) || defined(OS2)
7881 case V_FILE_DIR :
7882 return(h_config_file_dir);
7883 #endif
7884 case V_NORM_FORE_COLOR :
7885 case V_NORM_BACK_COLOR :
7886 return(h_config_normal_color);
7887 case V_REV_FORE_COLOR :
7888 case V_REV_BACK_COLOR :
7889 return(h_config_reverse_color);
7890 case V_TITLE_FORE_COLOR :
7891 case V_TITLE_BACK_COLOR :
7892 return(h_config_title_color);
7893 case V_TITLECLOSED_FORE_COLOR :
7894 case V_TITLECLOSED_BACK_COLOR :
7895 return(h_config_titleclosed_color);
7896 case V_FOLDER_FORE_COLOR:
7897 return(h_config_folder_color);
7898 case V_DIRECTORY_FORE_COLOR:
7899 return(h_config_directory_color);
7900 case V_FOLDER_LIST_FORE_COLOR:
7901 return(h_config_folder_list_color);
7902 case V_STATUS_FORE_COLOR :
7903 case V_STATUS_BACK_COLOR :
7904 return(h_config_status_color);
7905 case V_SLCTBL_FORE_COLOR :
7906 case V_SLCTBL_BACK_COLOR :
7907 return(h_config_slctbl_color);
7908 case V_QUOTE1_FORE_COLOR :
7909 case V_QUOTE2_FORE_COLOR :
7910 case V_QUOTE3_FORE_COLOR :
7911 case V_QUOTE1_BACK_COLOR :
7912 case V_QUOTE2_BACK_COLOR :
7913 case V_QUOTE3_BACK_COLOR :
7914 return(h_config_quote_color);
7915 case V_INCUNSEEN_FORE_COLOR :
7916 case V_INCUNSEEN_BACK_COLOR :
7917 return(h_config_incunseen_color);
7918 case V_SIGNATURE_FORE_COLOR :
7919 case V_SIGNATURE_BACK_COLOR :
7920 return(h_config_signature_color);
7921 case V_PROMPT_FORE_COLOR :
7922 case V_PROMPT_BACK_COLOR :
7923 return(h_config_prompt_color);
7924 case V_HEADER_GENERAL_FORE_COLOR :
7925 case V_HEADER_GENERAL_BACK_COLOR :
7926 return(h_config_header_general_color);
7927 case V_IND_PLUS_FORE_COLOR :
7928 case V_IND_IMP_FORE_COLOR :
7929 case V_IND_DEL_FORE_COLOR :
7930 case V_IND_ANS_FORE_COLOR :
7931 case V_IND_NEW_FORE_COLOR :
7932 case V_IND_UNS_FORE_COLOR :
7933 case V_IND_REC_FORE_COLOR :
7934 case V_IND_FWD_FORE_COLOR :
7935 case V_IND_PLUS_BACK_COLOR :
7936 case V_IND_IMP_BACK_COLOR :
7937 case V_IND_DEL_BACK_COLOR :
7938 case V_IND_ANS_BACK_COLOR :
7939 case V_IND_NEW_BACK_COLOR :
7940 case V_IND_UNS_BACK_COLOR :
7941 case V_IND_REC_BACK_COLOR :
7942 case V_IND_FWD_BACK_COLOR :
7943 return(h_config_index_color);
7944 case V_IND_OP_FORE_COLOR :
7945 case V_IND_OP_BACK_COLOR :
7946 return(h_config_index_opening_color);
7947 case V_IND_SUBJ_FORE_COLOR :
7948 case V_IND_SUBJ_BACK_COLOR :
7949 return(h_config_index_subject_color);
7950 case V_IND_FROM_FORE_COLOR :
7951 case V_IND_FROM_BACK_COLOR :
7952 return(h_config_index_from_color);
7953 case V_IND_HIPRI_FORE_COLOR :
7954 case V_IND_HIPRI_BACK_COLOR :
7955 case V_IND_LOPRI_FORE_COLOR :
7956 case V_IND_LOPRI_BACK_COLOR :
7957 return(h_config_index_pri_color);
7958 case V_IND_ARR_FORE_COLOR :
7959 case V_IND_ARR_BACK_COLOR :
7960 return(h_config_index_arrow_color);
7961 case V_KEYLABEL_FORE_COLOR :
7962 case V_KEYLABEL_BACK_COLOR :
7963 return(h_config_keylabel_color);
7964 case V_KEYNAME_FORE_COLOR :
7965 case V_KEYNAME_BACK_COLOR :
7966 return(h_config_keyname_color);
7967 case V_METAMSG_FORE_COLOR :
7968 case V_METAMSG_BACK_COLOR :
7969 return(h_config_metamsg_color);
7970 case V_VIEW_HDR_COLORS :
7971 return(h_config_customhdr_color);
7972 case V_INDEX_TOKEN_COLORS :
7973 return(h_config_indextoken_color);
7974 case V_PRINTER :
7975 return(h_config_printer);
7976 case V_PERSONAL_PRINT_CATEGORY :
7977 return(h_config_print_cat);
7978 case V_PERSONAL_PRINT_COMMAND :
7979 return(h_config_print_command);
7980 case V_PAT_ROLES :
7981 return(h_config_pat_roles);
7982 case V_PAT_FILTS :
7983 return(h_config_pat_filts);
7984 case V_PAT_SCORES :
7985 return(h_config_pat_scores);
7986 case V_PAT_INCOLS :
7987 return(h_config_pat_incols);
7988 case V_PAT_OTHER :
7989 return(h_config_pat_other);
7990 case V_PAT_SRCH :
7991 return(h_config_pat_srch);
7992 case V_INDEX_COLOR_STYLE :
7993 return(h_config_index_color_style);
7994 case V_TITLEBAR_COLOR_STYLE :
7995 return(h_config_titlebar_color_style);
7996 #ifdef _WINDOWS
7997 case V_FONT_NAME :
7998 return(h_config_font_name);
7999 case V_FONT_SIZE :
8000 return(h_config_font_size);
8001 case V_FONT_STYLE :
8002 return(h_config_font_style);
8003 case V_FONT_CHAR_SET :
8004 return(h_config_font_char_set);
8005 case V_PRINT_FONT_NAME :
8006 return(h_config_print_font_name);
8007 case V_PRINT_FONT_SIZE :
8008 return(h_config_print_font_size);
8009 case V_PRINT_FONT_STYLE :
8010 return(h_config_print_font_style);
8011 case V_PRINT_FONT_CHAR_SET :
8012 return(h_config_print_font_char_set);
8013 case V_WINDOW_POSITION :
8014 return(h_config_window_position);
8015 case V_CURSOR_STYLE :
8016 return(h_config_cursor_style);
8017 #else
8018 case V_COLOR_STYLE :
8019 return(h_config_color_style);
8020 #endif
8021 #ifdef ENABLE_LDAP
8022 case V_LDAP_SERVERS :
8023 return(h_config_ldap_servers);
8024 #endif
8025 #ifdef SMIME
8026 case V_PUBLICCERT_DIR :
8027 return(h_config_smime_pubcertdir);
8028 case V_PUBLICCERT_CONTAINER :
8029 return(h_config_smime_pubcertcon);
8030 case V_PRIVATEKEY_DIR :
8031 return(h_config_smime_privkeydir);
8032 case V_PRIVATEKEY_CONTAINER :
8033 return(h_config_smime_privkeycon);
8034 case V_CACERT_DIR :
8035 return(h_config_smime_cacertdir);
8036 case V_CACERT_CONTAINER :
8037 return(h_config_smime_cacertcon);
8038 #endif
8039 case V_RSS_NEWS :
8040 return(h_config_rss_news);
8041 case V_RSS_WEATHER :
8042 return(h_config_rss_weather);
8043 case V_WP_INDEXHEIGHT :
8044 return(h_config_wp_indexheight);
8045 case V_WP_INDEXLINES :
8046 return(h_config_wp_indexlines);
8047 case V_WP_AGGSTATE :
8048 return(h_config_wp_aggstate);
8049 case V_WP_STATE :
8050 return(h_config_wp_state);
8051 case V_WP_COLUMNS :
8052 return(h_config_wp_columns);
8053 default :
8054 return(NO_HELP);
8060 * We don't want the user to be able to edit their pinerc and set
8061 * printer to whatever they want if personal-print-command is fixed.
8062 * So make sure printer is set to something legitimate. If it isn't,
8063 * set it to something standard and return non-zero.
8066 printer_value_check_and_adjust(void)
8068 char **tt;
8069 char aname[100], wname[100];
8070 int ok = 0;
8071 struct variable *vars = ps_global->vars;
8073 if(vars[V_PERSONAL_PRINT_COMMAND].is_fixed && !vars[V_PRINTER].is_fixed){
8074 strncpy(aname, ANSI_PRINTER, sizeof(aname));
8075 aname[sizeof(aname)-1] = '\0';
8076 strncat(aname, "-no-formfeed", sizeof(aname)-strlen(aname)-1);
8077 strncpy(wname, WYSE_PRINTER, sizeof(wname));
8078 wname[sizeof(wname)-1] = '\0';
8079 strncat(wname, "-no-formfeed", sizeof(wname)-strlen(wname)-1);
8080 if(strucmp(VAR_PRINTER, ANSI_PRINTER) == 0
8081 || strucmp(VAR_PRINTER, aname) == 0
8082 || strucmp(VAR_PRINTER, WYSE_PRINTER) == 0
8083 || strucmp(VAR_PRINTER, wname) == 0)
8084 ok++;
8085 else if(VAR_STANDARD_PRINTER && VAR_STANDARD_PRINTER[0]){
8086 for(tt = VAR_STANDARD_PRINTER; *tt; tt++)
8087 if(strucmp(VAR_PRINTER, *tt) == 0)
8088 break;
8090 if(*tt)
8091 ok++;
8094 if(!ok){
8095 char *val;
8096 struct variable *v;
8098 if(VAR_STANDARD_PRINTER && VAR_STANDARD_PRINTER[0])
8099 val = VAR_STANDARD_PRINTER[0];
8100 else
8101 val = ANSI_PRINTER;
8103 v = &vars[V_PRINTER];
8104 if(v->main_user_val.p)
8105 fs_give((void **)&v->main_user_val.p);
8106 if(v->post_user_val.p)
8107 fs_give((void **)&v->post_user_val.p);
8108 if(v->current_val.p)
8109 fs_give((void **)&v->current_val.p);
8111 v->main_user_val.p = cpystr(val);
8112 v->current_val.p = cpystr(val);
8116 return(!ok);
8120 char **
8121 get_supported_options(void)
8123 char **config;
8124 DRIVER *d;
8125 AUTHENTICATOR *a;
8126 char *title = _("Supported features in this Alpine");
8127 char sbuf[MAX_SCREEN_COLS+1];
8128 int cnt, alcnt, len, cols, disabled, any_disabled = 0;;
8131 * Line count:
8132 * Title + blank = 2
8133 * SSL Title + SSL lines + blank = 5
8134 * Auth title + blank = 2
8135 * Driver title + blank = 2
8136 * LDAP title + LDAP line = 2
8137 * Disabled explanation + blank line = 4
8138 * end = 1
8140 cnt = 18;
8141 for(a = mail_lookup_auth(1); a; a = a->next)
8142 cnt++;
8143 for(d = (DRIVER *)mail_parameters(NIL, GET_DRIVERS, NIL);
8144 d; d = d->next)
8145 cnt++;
8147 alcnt = cnt;
8148 config = (char **) fs_get(alcnt * sizeof(char *));
8149 memset(config, 0, alcnt * sizeof(char *));
8151 cols = ps_global->ttyo ? ps_global->ttyo->screen_cols : 0;
8152 len = utf8_width(title);
8153 snprintf(sbuf, sizeof(sbuf), "%*s%s", cols > len ? (cols-len)/2 : 0, "", title);
8155 cnt = 0;
8156 if(cnt < alcnt)
8157 config[cnt] = cpystr(sbuf);
8159 if(++cnt < alcnt)
8160 config[cnt] = cpystr("");
8162 if(++cnt < alcnt)
8163 /* TRANSLATORS: headings */
8164 config[cnt] = cpystr(_("Encryption:"));
8166 if(++cnt < alcnt && mail_parameters(NIL, GET_SSLDRIVER, NIL))
8167 config[cnt] = cpystr(_(" TLS and SSL"));
8168 else
8169 config[cnt] = cpystr(_(" None (no TLS or SSL)"));
8170 #ifdef SSL_SUPPORTS_TLSV1_2
8171 if(++cnt < alcnt)
8172 config[cnt] = cpystr(" TLSv1.1, TLSv1.2, and DTLSv1");
8173 #endif
8174 #ifdef SMIME
8175 if(++cnt < alcnt)
8176 config[cnt] = cpystr(" S/MIME");
8177 #endif
8179 if(++cnt < alcnt)
8180 config[cnt] = cpystr("");
8182 if(++cnt < alcnt)
8183 config[cnt] = cpystr(_("Authenticators:"));
8185 for(a = mail_lookup_auth(1); a; a = a->next){
8186 disabled = (a->client == NULL && a->server == NULL);
8187 any_disabled += disabled;
8188 snprintf(sbuf, sizeof(sbuf), " %s%s", a->name, disabled ? " (disabled)" : "");
8189 if(++cnt < alcnt)
8190 config[cnt] = cpystr(sbuf);
8193 if(++cnt < alcnt)
8194 config[cnt] = cpystr("");
8196 if(++cnt < alcnt)
8197 config[cnt] = cpystr(_("Mailbox drivers:"));
8199 for(d = (DRIVER *)mail_parameters(NIL, GET_DRIVERS, NIL);
8200 d; d = d->next){
8201 disabled = (d->flags & DR_DISABLE);
8202 any_disabled += disabled;
8203 snprintf(sbuf, sizeof(sbuf), " %s%s", d->name, disabled ? " (disabled)" : "");
8204 if(++cnt < alcnt)
8205 config[cnt] = cpystr(sbuf);
8208 if(++cnt < alcnt)
8209 config[cnt] = cpystr("");
8211 if(++cnt < alcnt)
8212 config[cnt] = cpystr(_("Directories:"));
8214 #ifdef ENABLE_LDAP
8215 if(++cnt < alcnt)
8216 config[cnt] = cpystr(" LDAP");
8217 #else
8218 if(++cnt < alcnt)
8219 config[cnt] = cpystr(" None (no LDAP)");
8220 #endif
8222 if(any_disabled){
8223 if(++cnt < alcnt)
8224 config[cnt] = cpystr("");
8226 if(ps_global->ttyo){
8227 if(++cnt < alcnt)
8228 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."));
8230 else{
8231 if(++cnt < alcnt)
8232 config[cnt] = cpystr(_("Authenticators may be disabled because of the \"disable-these-authenticators\""));
8233 if(++cnt < alcnt)
8234 config[cnt] = cpystr(_("hidden config option. Mailbox drivers may be disabled because of the"));
8235 if(++cnt < alcnt)
8236 config[cnt] = cpystr(_("\"disable-these-drivers\" hidden config option."));
8240 if(++cnt < alcnt)
8241 config[cnt] = NULL;
8243 return(config);
8247 unsigned
8248 reset_startup_rule(MAILSTREAM *stream)
8250 long rflags = ROLE_DO_OTHER;
8251 PAT_STATE pstate;
8252 PAT_S *pat;
8253 unsigned startup_rule;
8255 startup_rule = IS_NOTSET;
8257 if(stream && nonempty_patterns(rflags, &pstate)){
8258 for(pat = first_pattern(&pstate); pat; pat = next_pattern(&pstate)){
8259 if(match_pattern(pat->patgrp, stream, NULL, NULL, NULL,
8260 SE_NOSERVER|SE_NOPREFETCH))
8261 break;
8264 if(pat && pat->action && !pat->action->bogus)
8265 startup_rule = pat->action->startup_rule;
8268 return(startup_rule);
8272 #ifdef _WINDOWS
8274 char *
8275 transformed_color(old)
8276 char *old;
8278 if(!old)
8279 return("");
8281 if(!struncmp(old, "color008", 8))
8282 return("colorlgr");
8283 else if(!struncmp(old, "color009", 8))
8284 return("colormgr");
8285 else if(!struncmp(old, "color010", 8))
8286 return("colordgr");
8288 return("");
8293 * If this is the first time we've run a version > 4.40, and there
8294 * is evidence that the config file has not been used by unix pine,
8295 * then we convert color008 to colorlgr, color009 to colormgr, and
8296 * color010 to colordgr. If the config file is being used by
8297 * unix pine then color008 may really supposed to be color008, color009
8298 * may really supposed to be red, and color010 may really supposed to be
8299 * green. Same if we've already run 4.41 or higher previously.
8301 * Returns 0 if no changes, > 0 if something was changed.
8304 convert_pc_gray_names(ps, prc, which)
8305 struct pine *ps;
8306 PINERC_S *prc;
8307 EditWhich which;
8309 struct variable *v;
8310 int ret = 0, ic = 0;
8311 char **s, *t, *p, *pstr, *new, *pval, **apval, **lval;
8313 for(v = ps->vars; v->name; v++){
8314 if(!color_holding_var(ps, v) || v == &ps->vars[V_KW_COLORS])
8315 continue;
8317 if(v == &ps->vars[V_VIEW_HDR_COLORS]){
8319 if((lval = LVAL(v,which)) != NULL){
8320 /* fix these in place */
8321 for(s = lval; (t = *s) != NULL; s++){
8322 if((p = srchstr(t, "FG=color008")) ||
8323 (p = srchstr(t, "FG=color009")) ||
8324 (p = srchstr(t, "FG=color010"))){
8325 strncpy(p+3, transformed_color(p+3), 8);
8326 ret++;
8329 if((p = srchstr(t, "BG=color008")) ||
8330 (p = srchstr(t, "BG=color009")) ||
8331 (p = srchstr(t, "BG=color010"))){
8332 strncpy(p+3, transformed_color(p+3), 8);
8333 ret++;
8338 else{
8339 if((pval = PVAL(v,which)) != NULL){
8340 apval = APVAL(v,which);
8341 if(apval && (!strucmp(pval, "color008") ||
8342 !strucmp(pval, "color009") ||
8343 !strucmp(pval, "color010"))){
8344 new = transformed_color(pval);
8345 if(*apval)
8346 fs_give((void **)apval);
8348 *apval = cpystr(new);
8349 ret++;
8355 v = &ps->vars[V_PAT_INCOLS];
8356 if((lval = LVAL(v,which)) != NULL){
8357 for(s = lval; (t = *s) != NULL; s++){
8358 if((pstr = srchstr(t, "action=")) != NULL){
8359 if((p = srchstr(pstr, "FG=color008")) ||
8360 (p = srchstr(pstr, "FG=color009")) ||
8361 (p = srchstr(pstr, "FG=color010"))){
8362 strncpy(p+3, transformed_color(p+3), 8);
8363 ic++;
8366 if((p = srchstr(pstr, "BG=color008")) ||
8367 (p = srchstr(pstr, "BG=color009")) ||
8368 (p = srchstr(pstr, "BG=color010"))){
8369 strncpy(p+3, transformed_color(p+3), 8);
8370 ic++;
8376 if(ic)
8377 set_current_val(&ps->vars[V_PAT_INCOLS], TRUE, TRUE);
8379 return(ret+ic);
8384 unix_color_style_in_pinerc(prc)
8385 PINERC_S *prc;
8387 PINERC_LINE *pline;
8389 for(pline = prc ? prc->pinerc_lines : NULL;
8390 pline && (pline->var || pline->line); pline++)
8391 if(pline->line && !struncmp("color-style=", pline->line, 12))
8392 return(1);
8394 return(0);
8397 char *
8398 pcpine_general_help(titlebuf)
8399 char *titlebuf;
8401 if(titlebuf)
8402 strcpy(titlebuf, "PC Alpine For Windows");
8404 return(pcpine_help(h_pine_for_windows));
8407 #endif /* _WINDOWS */