1 /* $Id: rc.c,v 1.116 2010/08/20 09:47:09 htrb Exp $ */
2 /*
3  * Initialization file etc.
4  */
5 #include "fm.h"
6 #include "myctype.h"
7 #include "proto.h"
8 #include <stdio.h>
9 #include <errno.h>
10 #include "parsetag.h"
11 #include "local.h"
12 #include "regex.h"
13 #include <stdlib.h>
14 #include <stddef.h>
15 
16 struct param_ptr {
17     char *name;
18     int type;
19     int inputtype;
20     void *varptr;
21     char *comment;
22     void *select;
23 };
24 
25 struct param_section {
26     char *name;
27     struct param_ptr *params;
28 };
29 
30 struct rc_search_table {
31     struct param_ptr *param;
32     short uniq_pos;
33 };
34 
35 static struct rc_search_table *RC_search_table;
36 static int RC_table_size;
37 
38 #define P_INT      0
39 #define P_SHORT    1
40 #define P_CHARINT  2
41 #define P_CHAR     3
42 #define P_STRING   4
43 #if defined(USE_SSL) && defined(USE_SSL_VERIFY)
44 #define P_SSLPATH  5
45 #endif
46 #ifdef USE_COLOR
47 #define P_COLOR    6
48 #endif
49 #ifdef USE_M17N
50 #define P_CODE     7
51 #endif
52 #define P_PIXELS   8
53 #define P_NZINT    9
54 #define P_SCALE    10
55 
56 /* FIXME: gettextize here */
57 #ifdef USE_M17N
58 static wc_ces OptionCharset = WC_CES_US_ASCII;	/* FIXME: charset of source code */
59 static int OptionEncode = FALSE;
60 #endif
61 
62 #define CMT_HELPER	 N_("External Viewer Setup")
63 #define CMT_TABSTOP      N_("Tab width in characters")
64 #define CMT_INDENT_INCR  N_("Indent for HTML rendering")
65 #define CMT_PIXEL_PER_CHAR N_("Number of pixels per character (4.0...32.0)")
66 #define CMT_PIXEL_PER_LINE N_("Number of pixels per line (4.0...64.0)")
67 #define CMT_PAGERLINE    N_("Number of remembered lines when used as a pager")
68 #define CMT_HISTORY	 N_("Use URL history")
69 #define CMT_HISTSIZE     N_("Number of remembered URL")
70 #define CMT_SAVEHIST     N_("Save URL history")
71 #define CMT_FRAME        N_("Render frames automatically")
72 #define CMT_ARGV_IS_URL  N_("Treat argument without scheme as URL")
73 #define CMT_TSELF        N_("Use _self as default target")
74 #define CMT_OPEN_TAB_BLANK N_("Open link on new tab if target is _blank or _new")
75 #define CMT_OPEN_TAB_DL_LIST N_("Open download list panel on new tab")
76 #define CMT_DISPLINK     N_("Display link URL automatically")
77 #define CMT_DISPLINKNUMBER N_("Display link numbers")
78 #define CMT_DECODE_URL   N_("Display decoded URL")
79 #define CMT_DISPLINEINFO N_("Display current line number")
80 #define CMT_DISP_IMAGE   N_("Display inline images")
81 #define CMT_PSEUDO_INLINES N_("Display pseudo-ALTs for inline images with no ALT or TITLE string")
82 #ifdef USE_IMAGE
83 #define CMT_AUTO_IMAGE   N_("Load inline images automatically")
84 #define CMT_MAX_LOAD_IMAGE N_("Maximum processes for parallel image loading")
85 #define CMT_EXT_IMAGE_VIEWER   N_("Use external image viewer")
86 #define CMT_IMAGE_SCALE  N_("Scale of image (%)")
87 #define CMT_IMGDISPLAY   N_("External command to display image")
88 #define CMT_IMAGE_MAP_LIST N_("Use link list of image map")
89 #define CMT_INLINE_IMG_PROTOCOL N_("Inline image display method")
90 #endif
91 #define CMT_MULTICOL     N_("Display file names in multi-column format")
92 #define CMT_ALT_ENTITY   N_("Use ASCII equivalents to display entities")
93 #define CMT_GRAPHIC_CHAR N_("Character type for border of table and menu")
94 #define CMT_DISP_BORDERS N_("Display table borders, ignore value of BORDER")
95 #define CMT_DISABLE_CENTER N_("Disable center alignment")
96 #define CMT_FOLD_TEXTAREA N_("Fold lines in TEXTAREA")
97 #define CMT_DISP_INS_DEL N_("Display INS, DEL, S and STRIKE element")
98 #define CMT_COLOR        N_("Display with color")
99 #define CMT_B_COLOR      N_("Color of normal character")
100 #define CMT_A_COLOR      N_("Color of anchor")
101 #define CMT_I_COLOR      N_("Color of image link")
102 #define CMT_F_COLOR      N_("Color of form")
103 #define CMT_ACTIVE_STYLE N_("Enable coloring of active link")
104 #define CMT_C_COLOR	 N_("Color of currently active link")
105 #define CMT_VISITED_ANCHOR N_("Use visited link color")
106 #define CMT_V_COLOR	 N_("Color of visited link")
107 #define CMT_BG_COLOR     N_("Color of background")
108 #define CMT_MARK_COLOR   N_("Color of mark")
109 #define CMT_USE_PROXY    N_("Use proxy")
110 #define CMT_HTTP_PROXY   N_("URL of HTTP proxy host")
111 #ifdef USE_SSL
112 #define CMT_HTTPS_PROXY  N_("URL of HTTPS proxy host")
113 #endif				/* USE_SSL */
114 #ifdef USE_GOPHER
115 #define CMT_GOPHER_PROXY N_("URL of GOPHER proxy host")
116 #endif				/* USE_GOPHER */
117 #define CMT_FTP_PROXY    N_("URL of FTP proxy host")
118 #define CMT_NO_PROXY     N_("Domains to be accessed directly (no proxy)")
119 #define CMT_NOPROXY_NETADDR	N_("Check noproxy by network address")
120 #define CMT_NO_CACHE     N_("Disable cache")
121 #ifdef USE_NNTP
122 #define CMT_NNTP_SERVER  N_("News server")
123 #define CMT_NNTP_MODE    N_("Mode of news server")
124 #define CMT_MAX_NEWS     N_("Number of news messages")
125 #endif
126 #define CMT_DNS_ORDER	N_("Order of name resolution")
127 #define CMT_DROOT       N_("Directory corresponding to / (document root)")
128 #define CMT_PDROOT      N_("Directory corresponding to /~user")
129 #define CMT_CGIBIN      N_("Directory corresponding to /cgi-bin")
130 #define CMT_CONFIRM_QQ  N_("Confirm when quitting with q")
131 #define CMT_CLOSE_TAB_BACK N_("Close tab if buffer is last when back")
132 #ifdef USE_MARK
133 #define CMT_USE_MARK	N_("Enable mark operations")
134 #endif
135 #define CMT_EMACS_LIKE_LINEEDIT	N_("Enable Emacs-style line editing")
136 #define CMT_SPACE_AUTOCOMPLETE  N_("Space key triggers file completion while editing URLs")
137 #define CMT_VI_PREC_NUM	 N_("Enable vi-like numeric prefix")
138 #define CMT_LABEL_TOPLINE N_("Move cursor to top line when going to label")
139 #define CMT_NEXTPAGE_TOPLINE N_("Move cursor to top line when moving to next page")
140 #define CMT_FOLD_LINE    N_("Fold lines of plain text file")
141 #define CMT_SHOW_NUM     N_("Show line numbers")
142 #define CMT_SHOW_SRCH_STR N_("Show search string")
143 #define CMT_MIMETYPES    N_("List of mime.types files")
144 #define CMT_MAILCAP      N_("List of mailcap files")
145 #define CMT_URIMETHODMAP N_("List of urimethodmap files")
146 #define CMT_EDITOR       N_("Editor")
147 #define CMT_MAILER       N_("Mailer")
148 #define CMT_MAILTO_OPTIONS N_("How to call Mailer for mailto URLs with options")
149 #define CMT_EXTBRZ       N_("External browser")
150 #define CMT_EXTBRZ2      N_("2nd external browser")
151 #define CMT_EXTBRZ3      N_("3rd external browser")
152 #define CMT_EXTBRZ4      N_("4th external browser")
153 #define CMT_EXTBRZ5      N_("5th external browser")
154 #define CMT_EXTBRZ6      N_("6th external browser")
155 #define CMT_EXTBRZ7      N_("7th external browser")
156 #define CMT_EXTBRZ8      N_("8th external browser")
157 #define CMT_EXTBRZ9      N_("9th external browser")
158 #define CMT_DISABLE_SECRET_SECURITY_CHECK	N_("Disable secret file security check")
159 #define CMT_PASSWDFILE	 N_("Password file")
160 #define CMT_PRE_FORM_FILE	N_("File for setting form on loading")
161 #define CMT_SITECONF_FILE	N_("File for preferences for each site")
162 #define CMT_FTPPASS      N_("Password for anonymous FTP (your mail address)")
163 #define CMT_FTPPASS_HOSTNAMEGEN N_("Generate domain part of password for FTP")
164 #define CMT_USERAGENT    N_("User-Agent identification string")
165 #define CMT_ACCEPTENCODING	N_("Accept-Encoding header")
166 #define CMT_ACCEPTMEDIA	 N_("Accept header")
167 #define CMT_ACCEPTLANG   N_("Accept-Language header")
168 #define CMT_MARK_ALL_PAGES N_("Treat URL-like strings as links in all pages")
169 #define CMT_WRAP         N_("Wrap search")
170 #define CMT_VIEW_UNSEENOBJECTS N_("Display unseen objects (e.g. bgimage tag)")
171 #define CMT_AUTO_UNCOMPRESS	N_("Uncompress compressed data automatically when downloading")
172 #ifdef __EMX__
173 #define CMT_BGEXTVIEW	 N_("Run external viewer in a separate session")
174 #else
175 #define CMT_BGEXTVIEW    N_("Run external viewer in the background")
176 #endif
177 #define CMT_EXT_DIRLIST  N_("Use external program for directory listing")
178 #define CMT_DIRLIST_CMD  N_("URL of directory listing command")
179 #ifdef USE_DICT
180 #define CMT_USE_DICTCOMMAND  N_("Enable dictionary lookup through CGI")
181 #define CMT_DICTCOMMAND  N_("URL of dictionary lookup command")
182 #endif				/* USE_DICT */
183 #define CMT_IGNORE_NULL_IMG_ALT	N_("Display link name for images lacking ALT")
184 #define CMT_IFILE        N_("Index file for directories")
185 #define CMT_RETRY_HTTP   N_("Prepend http:// to URL automatically")
186 #define CMT_DEFAULT_URL  N_("Default value for open-URL command")
187 #define CMT_DECODE_CTE   N_("Decode Content-Transfer-Encoding when saving")
188 #define CMT_PRESERVE_TIMESTAMP N_("Preserve timestamp when saving")
189 #ifdef USE_MOUSE
190 #define CMT_MOUSE         N_("Enable mouse")
191 #define CMT_REVERSE_MOUSE N_("Scroll in reverse direction of mouse drag")
192 #define CMT_RELATIVE_WHEEL_SCROLL N_("Behavior of wheel scroll speed")
193 #define CMT_RELATIVE_WHEEL_SCROLL_RATIO N_("(A only)Scroll by # (%) of screen")
194 #define CMT_FIXED_WHEEL_SCROLL_COUNT N_("(B only)Scroll by # lines")
195 #endif				/* USE_MOUSE */
196 #define CMT_CLEAR_BUF     N_("Free memory of undisplayed buffers")
197 #define CMT_NOSENDREFERER N_("Suppress `Referer:' header")
198 #define CMT_CROSSORIGINREFERER N_("Exclude pathname and query string from `Referer:' header when cross domain communication")
199 #define CMT_IGNORE_CASE N_("Search case-insensitively")
200 #define CMT_USE_LESSOPEN N_("Use LESSOPEN")
201 #ifdef USE_SSL
202 #ifdef USE_SSL_VERIFY
203 #define CMT_SSL_VERIFY_SERVER N_("Perform SSL server verification")
204 #define CMT_SSL_CERT_FILE N_("PEM encoded certificate file of client")
205 #define CMT_SSL_KEY_FILE N_("PEM encoded private key file of client")
206 #define CMT_SSL_CA_PATH N_("Path to directory for PEM encoded certificates of CAs")
207 #define CMT_SSL_CA_FILE N_("File consisting of PEM encoded certificates of CAs")
208 #define CMT_SSL_CA_DEFAULT N_("Use default locations for PEM encoded certificates of CAs")
209 #endif				/* USE_SSL_VERIFY */
210 #define CMT_SSL_FORBID_METHOD N_("List of forbidden SSL methods (2: SSLv2, 3: SSLv3, t: TLSv1.0, 5: TLSv1.1, 6: TLSv1.2, 7: TLSv1.3)")
211 #ifdef SSL_CTX_set_min_proto_version
212 #define CMT_SSL_MIN_VERSION N_("Minimum SSL version (all, TLSv1.0, TLSv1.1, TLSv1.2, or TLSv1.3)")
213 #endif
214 #define CMT_SSL_CIPHER N_("SSL ciphers for TLSv1.2 and below (e.g. DEFAULT:@SECLEVEL=2)")
215 #endif				/* USE_SSL */
216 #ifdef USE_COOKIE
217 #define CMT_USECOOKIE   N_("Enable cookie processing")
218 #define CMT_SHOWCOOKIE  N_("Print a message when receiving a cookie")
219 #define CMT_ACCEPTCOOKIE N_("Accept cookies")
220 #define CMT_ACCEPTBADCOOKIE N_("Action to be taken on invalid cookie")
221 #define CMT_COOKIE_REJECT_DOMAINS N_("Domains to reject cookies from")
222 #define CMT_COOKIE_ACCEPT_DOMAINS N_("Domains to accept cookies from")
223 #define CMT_COOKIE_AVOID_WONG_NUMBER_OF_DOTS N_("Domains to avoid [wrong number of dots]")
224 #endif
225 #define CMT_FOLLOW_REDIRECTION N_("Number of redirections to follow")
226 #define CMT_META_REFRESH N_("Enable processing of meta-refresh tag")
227 #define CMT_LOCALHOST_ONLY N_("Restrict connections only to localhost")
228 
229 #ifdef USE_MIGEMO
230 #define CMT_USE_MIGEMO N_("Enable Migemo (Roma-ji search)")
231 #define CMT_MIGEMO_COMMAND N_("Migemo command")
232 #endif				/* USE_MIGEMO */
233 
234 #ifdef USE_M17N
235 #define CMT_DISPLAY_CHARSET  N_("Display charset")
236 #define CMT_DOCUMENT_CHARSET N_("Default document charset")
237 #define CMT_AUTO_DETECT      N_("Automatic charset detect when loading")
238 #define CMT_SYSTEM_CHARSET   N_("System charset")
239 #define CMT_FOLLOW_LOCALE    N_("System charset follows locale(LC_CTYPE)")
240 #define CMT_EXT_HALFDUMP     N_("Output halfdump with display charset")
241 #define CMT_USE_WIDE         N_("Use multi column characters")
242 #define CMT_USE_COMBINING    N_("Use combining characters")
243 #define CMT_EAST_ASIAN_WIDTH N_("Use double width for some Unicode characters")
244 #define CMT_USE_LANGUAGE_TAG N_("Use Unicode language tags")
245 #define CMT_UCS_CONV         N_("Charset conversion using Unicode map")
246 #define CMT_PRE_CONV         N_("Charset conversion when loading")
247 #define CMT_SEARCH_CONV      N_("Adjust search string for document charset")
248 #define CMT_FIX_WIDTH_CONV   N_("Fix character width when conversion")
249 #define CMT_USE_GB12345_MAP  N_("Use GB 12345 Unicode map instead of GB 2312's")
250 #define CMT_USE_JISX0201     N_("Use JIS X 0201 Roman for ISO-2022-JP")
251 #define CMT_USE_JISC6226     N_("Use JIS C 6226:1978 for ISO-2022-JP")
252 #define CMT_USE_JISX0201K    N_("Use JIS X 0201 Katakana")
253 #define CMT_USE_JISX0212     N_("Use JIS X 0212:1990 (Supplemental Kanji)")
254 #define CMT_USE_JISX0213     N_("Use JIS X 0213:2000 (2000JIS)")
255 #define CMT_STRICT_ISO2022   N_("Strict ISO-2022-JP/KR/CN")
256 #define CMT_GB18030_AS_UCS   N_("Treat 4 bytes char. of GB18030 as Unicode")
257 #define CMT_SIMPLE_PRESERVE_SPACE N_("Simple Preserve space")
258 #endif
259 
260 #define CMT_KEYMAP_FILE N_("keymap file")
261 
262 #define PI_TEXT    0
263 #define PI_ONOFF   1
264 #define PI_SEL_C   2
265 #ifdef USE_M17N
266 #define PI_CODE    3
267 #endif
268 
269 struct sel_c {
270     int value;
271     char *cvalue;
272     char *text;
273 };
274 
275 #ifdef USE_COLOR
276 static struct sel_c colorstr[] = {
277     {0, "black", N_("black")},
278     {1, "red", N_("red")},
279     {2, "green", N_("green")},
280     {3, "yellow", N_("yellow")},
281     {4, "blue", N_("blue")},
282     {5, "magenta", N_("magenta")},
283     {6, "cyan", N_("cyan")},
284     {7, "white", N_("white")},
285     {8, "terminal", N_("terminal")},
286     {0, NULL, NULL}
287 };
288 #endif				/* USE_COLOR */
289 
290 #if 1				/* ANSI-C ? */
291 #define N_STR(x)	#x
292 #define N_S(x)	(x), N_STR(x)
293 #else				/* for traditional cpp? */
294 static char n_s[][2] = {
295     {'0', 0},
296     {'1', 0},
297     {'2', 0},
298 };
299 #define N_S(x) (x), n_s[(x)]
300 #endif
301 
302 
303 static struct sel_c defaulturls[] = {
304     {N_S(DEFAULT_URL_EMPTY), N_("none")},
305     {N_S(DEFAULT_URL_CURRENT), N_("current URL")},
306     {N_S(DEFAULT_URL_LINK), N_("link URL")},
307     {0, NULL, NULL}
308 };
309 
310 static struct sel_c displayinsdel[] = {
311     {N_S(DISPLAY_INS_DEL_SIMPLE), N_("simple")},
312     {N_S(DISPLAY_INS_DEL_NORMAL), N_("use tag")},
313     {N_S(DISPLAY_INS_DEL_FONTIFY), N_("fontify")},
314     {0, NULL, NULL}
315 };
316 
317 #ifdef USE_MOUSE
318 static struct sel_c wheelmode[] = {
319     {TRUE, "1", N_("A:relative to screen height")},
320     {FALSE, "0", N_("B:fixed speed")},
321     {0, NULL, NULL}
322 };
323 #endif				/* MOUSE */
324 
325 #ifdef INET6
326 static struct sel_c dnsorders[] = {
327     {N_S(DNS_ORDER_UNSPEC), N_("unspecified")},
328     {N_S(DNS_ORDER_INET_INET6), N_("inet inet6")},
329     {N_S(DNS_ORDER_INET6_INET), N_("inet6 inet")},
330     {N_S(DNS_ORDER_INET_ONLY), N_("inet only")},
331     {N_S(DNS_ORDER_INET6_ONLY), N_("inet6 only")},
332     {0, NULL, NULL}
333 };
334 #endif				/* INET6 */
335 
336 #ifdef USE_COOKIE
337 static struct sel_c badcookiestr[] = {
338     {N_S(ACCEPT_BAD_COOKIE_DISCARD), N_("discard")},
339 #if 0
340     {N_S(ACCEPT_BAD_COOKIE_ACCEPT), N_("accept")},
341 #endif
342     {N_S(ACCEPT_BAD_COOKIE_ASK), N_("ask")},
343     {0, NULL, NULL}
344 };
345 #endif				/* USE_COOKIE */
346 
347 static struct sel_c mailtooptionsstr[] = {
348 #ifdef USE_W3MMAILER
349     {N_S(MAILTO_OPTIONS_USE_W3MMAILER), N_("use internal mailer instead")},
350 #endif
351     {N_S(MAILTO_OPTIONS_IGNORE), N_("ignore options and use only the address")},
352     {N_S(MAILTO_OPTIONS_USE_MAILTO_URL), N_("use full mailto URL")},
353     {0, NULL, NULL}
354 };
355 
356 #ifdef USE_M17N
357 static wc_ces_list *display_charset_str = NULL;
358 static wc_ces_list *document_charset_str = NULL;
359 static wc_ces_list *system_charset_str = NULL;
360 static struct sel_c auto_detect_str[] = {
361     {N_S(WC_OPT_DETECT_OFF), N_("OFF")},
362     {N_S(WC_OPT_DETECT_ISO_2022), N_("Only ISO 2022")},
363     {N_S(WC_OPT_DETECT_ON), N_("ON")},
364     {0, NULL, NULL}
365 };
366 #endif
367 
368 static struct sel_c graphic_char_str[] = {
369     {N_S(GRAPHIC_CHAR_ASCII), N_("ASCII")},
370     {N_S(GRAPHIC_CHAR_CHARSET), N_("charset specific")},
371     {N_S(GRAPHIC_CHAR_DEC), N_("DEC special graphics")},
372     {0, NULL, NULL}
373 };
374 
375 #ifdef USE_IMAGE
376 static struct sel_c inlineimgstr[] = {
377     {N_S(INLINE_IMG_NONE), N_("external command")},
378     {N_S(INLINE_IMG_OSC5379), N_("OSC 5379 (mlterm)")},
379     {N_S(INLINE_IMG_SIXEL), N_("sixel (img2sixel)")},
380     {N_S(INLINE_IMG_ITERM2), N_("OSC 1337 (iTerm2)")},
381     {N_S(INLINE_IMG_KITTY), N_("kitty (ImageMagick)")},
382     {0, NULL, NULL}
383 };
384 #endif				/* USE_IMAGE */
385 
386 struct param_ptr params1[] = {
387     {"tabstop", P_NZINT, PI_TEXT, (void *)&Tabstop, CMT_TABSTOP, NULL},
388     {"indent_incr", P_NZINT, PI_TEXT, (void *)&IndentIncr, CMT_INDENT_INCR,
389      NULL},
390     {"pixel_per_char", P_PIXELS, PI_TEXT, (void *)&pixel_per_char,
391      CMT_PIXEL_PER_CHAR, NULL},
392 #ifdef USE_IMAGE
393     {"pixel_per_line", P_PIXELS, PI_TEXT, (void *)&pixel_per_line,
394      CMT_PIXEL_PER_LINE, NULL},
395 #endif
396     {"frame", P_CHARINT, PI_ONOFF, (void *)&RenderFrame, CMT_FRAME, NULL},
397     {"target_self", P_CHARINT, PI_ONOFF, (void *)&TargetSelf, CMT_TSELF, NULL},
398     {"open_tab_blank", P_INT, PI_ONOFF, (void *)&open_tab_blank,
399      CMT_OPEN_TAB_BLANK, NULL},
400     {"open_tab_dl_list", P_INT, PI_ONOFF, (void *)&open_tab_dl_list,
401      CMT_OPEN_TAB_DL_LIST, NULL},
402     {"display_link", P_INT, PI_ONOFF, (void *)&displayLink, CMT_DISPLINK,
403      NULL},
404     {"display_link_number", P_INT, PI_ONOFF, (void *)&displayLinkNumber,
405      CMT_DISPLINKNUMBER, NULL},
406     {"decode_url", P_INT, PI_ONOFF, (void *)&DecodeURL, CMT_DECODE_URL, NULL},
407     {"display_lineinfo", P_INT, PI_ONOFF, (void *)&displayLineInfo,
408      CMT_DISPLINEINFO, NULL},
409     {"ext_dirlist", P_INT, PI_ONOFF, (void *)&UseExternalDirBuffer,
410      CMT_EXT_DIRLIST, NULL},
411     {"dirlist_cmd", P_STRING, PI_TEXT, (void *)&DirBufferCommand,
412      CMT_DIRLIST_CMD, NULL},
413 #ifdef USE_DICT
414     {"use_dictcommand", P_INT, PI_ONOFF, (void *)&UseDictCommand,
415      CMT_USE_DICTCOMMAND, NULL},
416     {"dictcommand", P_STRING, PI_TEXT, (void *)&DictCommand,
417      CMT_DICTCOMMAND, NULL},
418 #endif				/* USE_DICT */
419     {"multicol", P_INT, PI_ONOFF, (void *)&multicolList, CMT_MULTICOL, NULL},
420     {"alt_entity", P_CHARINT, PI_ONOFF, (void *)&UseAltEntity, CMT_ALT_ENTITY,
421      NULL},
422     {"graphic_char", P_CHARINT, PI_SEL_C, (void *)&UseGraphicChar,
423      CMT_GRAPHIC_CHAR, (void *)graphic_char_str},
424     {"display_borders", P_CHARINT, PI_ONOFF, (void *)&DisplayBorders,
425      CMT_DISP_BORDERS, NULL},
426     {"disable_center", P_CHARINT, PI_ONOFF, (void *)&DisableCenter,
427      CMT_DISABLE_CENTER, NULL},
428     {"fold_textarea", P_CHARINT, PI_ONOFF, (void *)&FoldTextarea,
429      CMT_FOLD_TEXTAREA, NULL},
430     {"display_ins_del", P_INT, PI_SEL_C, (void *)&displayInsDel,
431      CMT_DISP_INS_DEL, displayinsdel},
432     {"ignore_null_img_alt", P_INT, PI_ONOFF, (void *)&ignore_null_img_alt,
433      CMT_IGNORE_NULL_IMG_ALT, NULL},
434     {"view_unseenobject", P_INT, PI_ONOFF, (void *)&view_unseenobject,
435      CMT_VIEW_UNSEENOBJECTS, NULL},
436     /* XXX: emacs-w3m force to off display_image even if image options off */
437     {"display_image", P_INT, PI_ONOFF, (void *)&displayImage, CMT_DISP_IMAGE,
438      NULL},
439     {"pseudo_inlines", P_INT, PI_ONOFF, (void *)&pseudoInlines,
440      CMT_PSEUDO_INLINES, NULL},
441 #ifdef USE_IMAGE
442     {"auto_image", P_INT, PI_ONOFF, (void *)&autoImage, CMT_AUTO_IMAGE, NULL},
443     {"max_load_image", P_INT, PI_TEXT, (void *)&maxLoadImage,
444      CMT_MAX_LOAD_IMAGE, NULL},
445     {"ext_image_viewer", P_INT, PI_ONOFF, (void *)&useExtImageViewer,
446      CMT_EXT_IMAGE_VIEWER, NULL},
447     {"image_scale", P_SCALE, PI_TEXT, (void *)&image_scale, CMT_IMAGE_SCALE,
448      NULL},
449     {"inline_img_protocol", P_INT, PI_SEL_C, (void *)&enable_inline_image,
450      CMT_INLINE_IMG_PROTOCOL, (void *)inlineimgstr},
451     {"imgdisplay", P_STRING, PI_TEXT, (void *)&Imgdisplay, CMT_IMGDISPLAY,
452      NULL},
453     {"image_map_list", P_INT, PI_ONOFF, (void *)&image_map_list,
454      CMT_IMAGE_MAP_LIST, NULL},
455 #endif
456     {"fold_line", P_INT, PI_ONOFF, (void *)&FoldLine, CMT_FOLD_LINE, NULL},
457     {"show_lnum", P_INT, PI_ONOFF, (void *)&showLineNum, CMT_SHOW_NUM, NULL},
458     {"show_srch_str", P_INT, PI_ONOFF, (void *)&show_srch_str,
459      CMT_SHOW_SRCH_STR, NULL},
460     {"label_topline", P_INT, PI_ONOFF, (void *)&label_topline,
461      CMT_LABEL_TOPLINE, NULL},
462     {"nextpage_topline", P_INT, PI_ONOFF, (void *)&nextpage_topline,
463      CMT_NEXTPAGE_TOPLINE, NULL},
464     {NULL, 0, 0, NULL, NULL, NULL},
465 };
466 
467 #ifdef USE_COLOR
468 struct param_ptr params2[] = {
469     {"color", P_INT, PI_ONOFF, (void *)&useColor, CMT_COLOR, NULL},
470     {"basic_color", P_COLOR, PI_SEL_C, (void *)&basic_color, CMT_B_COLOR,
471      (void *)colorstr},
472     {"anchor_color", P_COLOR, PI_SEL_C, (void *)&anchor_color, CMT_A_COLOR,
473      (void *)colorstr},
474     {"image_color", P_COLOR, PI_SEL_C, (void *)&image_color, CMT_I_COLOR,
475      (void *)colorstr},
476     {"form_color", P_COLOR, PI_SEL_C, (void *)&form_color, CMT_F_COLOR,
477      (void *)colorstr},
478 #ifdef USE_BG_COLOR
479     {"mark_color", P_COLOR, PI_SEL_C, (void *)&mark_color, CMT_MARK_COLOR,
480      (void *)colorstr},
481     {"bg_color", P_COLOR, PI_SEL_C, (void *)&bg_color, CMT_BG_COLOR,
482      (void *)colorstr},
483 #endif				/* USE_BG_COLOR */
484     {"active_style", P_INT, PI_ONOFF, (void *)&useActiveColor,
485      CMT_ACTIVE_STYLE, NULL},
486     {"active_color", P_COLOR, PI_SEL_C, (void *)&active_color, CMT_C_COLOR,
487      (void *)colorstr},
488     {"visited_anchor", P_INT, PI_ONOFF, (void *)&useVisitedColor,
489      CMT_VISITED_ANCHOR, NULL},
490     {"visited_color", P_COLOR, PI_SEL_C, (void *)&visited_color, CMT_V_COLOR,
491      (void *)colorstr},
492     {NULL, 0, 0, NULL, NULL, NULL},
493 };
494 #endif				/* USE_COLOR */
495 
496 
497 struct param_ptr params3[] = {
498     {"pagerline", P_NZINT, PI_TEXT, (void *)&PagerMax, CMT_PAGERLINE, NULL},
499 #ifdef USE_HISTORY
500     {"use_history", P_INT, PI_ONOFF, (void *)&UseHistory, CMT_HISTORY, NULL},
501     {"history", P_INT, PI_TEXT, (void *)&URLHistSize, CMT_HISTSIZE, NULL},
502     {"save_hist", P_INT, PI_ONOFF, (void *)&SaveURLHist, CMT_SAVEHIST, NULL},
503 #endif				/* USE_HISTORY */
504     {"confirm_qq", P_INT, PI_ONOFF, (void *)&confirm_on_quit, CMT_CONFIRM_QQ,
505      NULL},
506     {"close_tab_back", P_INT, PI_ONOFF, (void *)&close_tab_back,
507      CMT_CLOSE_TAB_BACK, NULL},
508 #ifdef USE_MARK
509     {"mark", P_INT, PI_ONOFF, (void *)&use_mark, CMT_USE_MARK, NULL},
510 #endif
511     {"emacs_like_lineedit", P_INT, PI_ONOFF, (void *)&emacs_like_lineedit,
512      CMT_EMACS_LIKE_LINEEDIT, NULL},
513     {"space_autocomplete", P_INT, PI_ONOFF, (void *)&space_autocomplete,
514      CMT_SPACE_AUTOCOMPLETE, NULL},
515     {"vi_prec_num", P_INT, PI_ONOFF, (void *)&vi_prec_num, CMT_VI_PREC_NUM,
516      NULL},
517     {"mark_all_pages", P_INT, PI_ONOFF, (void *)&MarkAllPages,
518      CMT_MARK_ALL_PAGES, NULL},
519     {"wrap_search", P_INT, PI_ONOFF, (void *)&WrapDefault, CMT_WRAP, NULL},
520     {"ignorecase_search", P_INT, PI_ONOFF, (void *)&IgnoreCase,
521      CMT_IGNORE_CASE, NULL},
522 #ifdef USE_MIGEMO
523     {"use_migemo", P_INT, PI_ONOFF, (void *)&use_migemo, CMT_USE_MIGEMO,
524      NULL},
525     {"migemo_command", P_STRING, PI_TEXT, (void *)&migemo_command,
526      CMT_MIGEMO_COMMAND, NULL},
527 #endif				/* USE_MIGEMO */
528 #ifdef USE_MOUSE
529     {"use_mouse", P_INT, PI_ONOFF, (void *)&use_mouse, CMT_MOUSE, NULL},
530     {"reverse_mouse", P_INT, PI_ONOFF, (void *)&reverse_mouse,
531      CMT_REVERSE_MOUSE, NULL},
532     {"relative_wheel_scroll", P_INT, PI_SEL_C, (void *)&relative_wheel_scroll,
533      CMT_RELATIVE_WHEEL_SCROLL, (void *)wheelmode},
534     {"relative_wheel_scroll_ratio", P_INT, PI_TEXT,
535      (void *)&relative_wheel_scroll_ratio,
536      CMT_RELATIVE_WHEEL_SCROLL_RATIO, NULL},
537     {"fixed_wheel_scroll_count", P_INT, PI_TEXT,
538      (void *)&fixed_wheel_scroll_count,
539      CMT_FIXED_WHEEL_SCROLL_COUNT, NULL},
540 #endif				/* USE_MOUSE */
541     {"clear_buffer", P_INT, PI_ONOFF, (void *)&clear_buffer, CMT_CLEAR_BUF,
542      NULL},
543     {"decode_cte", P_CHARINT, PI_ONOFF, (void *)&DecodeCTE, CMT_DECODE_CTE,
544      NULL},
545     {"auto_uncompress", P_CHARINT, PI_ONOFF, (void *)&AutoUncompress,
546      CMT_AUTO_UNCOMPRESS, NULL},
547     {"preserve_timestamp", P_CHARINT, PI_ONOFF, (void *)&PreserveTimestamp,
548      CMT_PRESERVE_TIMESTAMP, NULL},
549     {"keymap_file", P_STRING, PI_TEXT, (void *)&keymap_file, CMT_KEYMAP_FILE,
550      NULL},
551     {NULL, 0, 0, NULL, NULL, NULL},
552 };
553 
554 struct param_ptr params4[] = {
555     {"use_proxy", P_CHARINT, PI_ONOFF, (void *)&use_proxy, CMT_USE_PROXY,
556      NULL},
557     {"http_proxy", P_STRING, PI_TEXT, (void *)&HTTP_proxy, CMT_HTTP_PROXY,
558      NULL},
559 #ifdef USE_SSL
560     {"https_proxy", P_STRING, PI_TEXT, (void *)&HTTPS_proxy, CMT_HTTPS_PROXY,
561      NULL},
562 #endif				/* USE_SSL */
563 #ifdef USE_GOPHER
564     {"gopher_proxy", P_STRING, PI_TEXT, (void *)&GOPHER_proxy,
565      CMT_GOPHER_PROXY, NULL},
566 #endif				/* USE_GOPHER */
567     {"ftp_proxy", P_STRING, PI_TEXT, (void *)&FTP_proxy, CMT_FTP_PROXY, NULL},
568     {"no_proxy", P_STRING, PI_TEXT, (void *)&NO_proxy, CMT_NO_PROXY, NULL},
569     {"noproxy_netaddr", P_INT, PI_ONOFF, (void *)&NOproxy_netaddr,
570      CMT_NOPROXY_NETADDR, NULL},
571     {"no_cache", P_CHARINT, PI_ONOFF, (void *)&NoCache, CMT_NO_CACHE, NULL},
572 
573     {NULL, 0, 0, NULL, NULL, NULL},
574 };
575 
576 struct param_ptr params5[] = {
577     {"document_root", P_STRING, PI_TEXT, (void *)&document_root, CMT_DROOT,
578      NULL},
579     {"personal_document_root", P_STRING, PI_TEXT,
580      (void *)&personal_document_root, CMT_PDROOT, NULL},
581     {"cgi_bin", P_STRING, PI_TEXT, (void *)&cgi_bin, CMT_CGIBIN, NULL},
582     {"index_file", P_STRING, PI_TEXT, (void *)&index_file, CMT_IFILE, NULL},
583     {NULL, 0, 0, NULL, NULL, NULL},
584 };
585 
586 struct param_ptr params6[] = {
587     {"mime_types", P_STRING, PI_TEXT, (void *)&mimetypes_files, CMT_MIMETYPES,
588      NULL},
589     {"mailcap", P_STRING, PI_TEXT, (void *)&mailcap_files, CMT_MAILCAP, NULL},
590 #ifdef USE_EXTERNAL_URI_LOADER
591     {"urimethodmap", P_STRING, PI_TEXT, (void *)&urimethodmap_files,
592      CMT_URIMETHODMAP, NULL},
593 #endif
594     {"editor", P_STRING, PI_TEXT, (void *)&Editor, CMT_EDITOR, NULL},
595     {"mailto_options", P_INT, PI_SEL_C, (void *)&MailtoOptions,
596      CMT_MAILTO_OPTIONS, (void *)mailtooptionsstr},
597     {"mailer", P_STRING, PI_TEXT, (void *)&Mailer, CMT_MAILER, NULL},
598     {"extbrowser", P_STRING, PI_TEXT, (void *)&ExtBrowser, CMT_EXTBRZ, NULL},
599     {"extbrowser2", P_STRING, PI_TEXT, (void *)&ExtBrowser2, CMT_EXTBRZ2,
600      NULL},
601     {"extbrowser3", P_STRING, PI_TEXT, (void *)&ExtBrowser3, CMT_EXTBRZ3,
602      NULL},
603     {"extbrowser4", P_STRING, PI_TEXT, (void *)&ExtBrowser4, CMT_EXTBRZ4,
604      NULL},
605     {"extbrowser5", P_STRING, PI_TEXT, (void *)&ExtBrowser5, CMT_EXTBRZ5,
606      NULL},
607     {"extbrowser6", P_STRING, PI_TEXT, (void *)&ExtBrowser6, CMT_EXTBRZ6,
608      NULL},
609     {"extbrowser7", P_STRING, PI_TEXT, (void *)&ExtBrowser7, CMT_EXTBRZ7,
610      NULL},
611     {"extbrowser8", P_STRING, PI_TEXT, (void *)&ExtBrowser8, CMT_EXTBRZ8,
612      NULL},
613     {"extbrowser9", P_STRING, PI_TEXT, (void *)&ExtBrowser9, CMT_EXTBRZ9,
614      NULL},
615     {"bgextviewer", P_INT, PI_ONOFF, (void *)&BackgroundExtViewer,
616      CMT_BGEXTVIEW, NULL},
617     {"use_lessopen", P_INT, PI_ONOFF, (void *)&use_lessopen, CMT_USE_LESSOPEN,
618      NULL},
619     {NULL, 0, 0, NULL, NULL, NULL},
620 };
621 
622 #ifdef USE_SSL
623 struct param_ptr params7[] = {
624     {"ssl_forbid_method", P_STRING, PI_TEXT, (void *)&ssl_forbid_method,
625      CMT_SSL_FORBID_METHOD, NULL},
626 #ifdef SSL_CTX_set_min_proto_version
627     {"ssl_min_version", P_STRING, PI_TEXT, (void *)&ssl_min_version,
628      CMT_SSL_MIN_VERSION, NULL},
629 #endif
630     {"ssl_cipher", P_STRING, PI_TEXT, (void *)&ssl_cipher, CMT_SSL_CIPHER,
631      NULL},
632 #ifdef USE_SSL_VERIFY
633     {"ssl_verify_server", P_INT, PI_ONOFF, (void *)&ssl_verify_server,
634      CMT_SSL_VERIFY_SERVER, NULL},
635     {"ssl_cert_file", P_SSLPATH, PI_TEXT, (void *)&ssl_cert_file,
636      CMT_SSL_CERT_FILE, NULL},
637     {"ssl_key_file", P_SSLPATH, PI_TEXT, (void *)&ssl_key_file,
638      CMT_SSL_KEY_FILE, NULL},
639     {"ssl_ca_path", P_SSLPATH, PI_TEXT, (void *)&ssl_ca_path, CMT_SSL_CA_PATH,
640      NULL},
641     {"ssl_ca_file", P_SSLPATH, PI_TEXT, (void *)&ssl_ca_file, CMT_SSL_CA_FILE,
642      NULL},
643     {"ssl_ca_default", P_INT, PI_ONOFF, (void *)&ssl_ca_default,
644      CMT_SSL_CA_DEFAULT, NULL},
645 #endif				/* USE_SSL_VERIFY */
646     {NULL, 0, 0, NULL, NULL, NULL},
647 };
648 #endif				/* USE_SSL */
649 
650 #ifdef USE_COOKIE
651 struct param_ptr params8[] = {
652     {"use_cookie", P_INT, PI_ONOFF, (void *)&use_cookie, CMT_USECOOKIE, NULL},
653     {"show_cookie", P_INT, PI_ONOFF, (void *)&show_cookie,
654      CMT_SHOWCOOKIE, NULL},
655     {"accept_cookie", P_INT, PI_ONOFF, (void *)&accept_cookie,
656      CMT_ACCEPTCOOKIE, NULL},
657     {"accept_bad_cookie", P_INT, PI_SEL_C, (void *)&accept_bad_cookie,
658      CMT_ACCEPTBADCOOKIE, (void *)badcookiestr},
659     {"cookie_reject_domains", P_STRING, PI_TEXT,
660      (void *)&cookie_reject_domains, CMT_COOKIE_REJECT_DOMAINS, NULL},
661     {"cookie_accept_domains", P_STRING, PI_TEXT,
662      (void *)&cookie_accept_domains, CMT_COOKIE_ACCEPT_DOMAINS, NULL},
663     {"cookie_avoid_wrong_number_of_dots", P_STRING, PI_TEXT,
664      (void *)&cookie_avoid_wrong_number_of_dots,
665      CMT_COOKIE_AVOID_WONG_NUMBER_OF_DOTS, NULL},
666     {NULL, 0, 0, NULL, NULL, NULL},
667 };
668 #endif
669 
670 struct param_ptr params9[] = {
671     {"passwd_file", P_STRING, PI_TEXT, (void *)&passwd_file, CMT_PASSWDFILE,
672      NULL},
673     {"disable_secret_security_check", P_INT, PI_ONOFF,
674      (void *)&disable_secret_security_check, CMT_DISABLE_SECRET_SECURITY_CHECK,
675      NULL},
676     {"ftppasswd", P_STRING, PI_TEXT, (void *)&ftppasswd, CMT_FTPPASS, NULL},
677     {"ftppass_hostnamegen", P_INT, PI_ONOFF, (void *)&ftppass_hostnamegen,
678      CMT_FTPPASS_HOSTNAMEGEN, NULL},
679     {"pre_form_file", P_STRING, PI_TEXT, (void *)&pre_form_file,
680      CMT_PRE_FORM_FILE, NULL},
681     {"siteconf_file", P_STRING, PI_TEXT, (void *)&siteconf_file,
682      CMT_SITECONF_FILE, NULL},
683     {"user_agent", P_STRING, PI_TEXT, (void *)&UserAgent, CMT_USERAGENT, NULL},
684     {"no_referer", P_INT, PI_ONOFF, (void *)&NoSendReferer, CMT_NOSENDREFERER,
685      NULL},
686     {"cross_origin_referer", P_INT, PI_ONOFF, (void *)&CrossOriginReferer,
687      CMT_CROSSORIGINREFERER, NULL},
688     {"accept_language", P_STRING, PI_TEXT, (void *)&AcceptLang, CMT_ACCEPTLANG,
689      NULL},
690     {"accept_encoding", P_STRING, PI_TEXT, (void *)&AcceptEncoding,
691      CMT_ACCEPTENCODING,
692      NULL},
693     {"accept_media", P_STRING, PI_TEXT, (void *)&AcceptMedia, CMT_ACCEPTMEDIA,
694      NULL},
695     {"argv_is_url", P_CHARINT, PI_ONOFF, (void *)&ArgvIsURL, CMT_ARGV_IS_URL,
696      NULL},
697     {"retry_http", P_INT, PI_ONOFF, (void *)&retryAsHttp, CMT_RETRY_HTTP,
698      NULL},
699     {"default_url", P_INT, PI_SEL_C, (void *)&DefaultURLString,
700      CMT_DEFAULT_URL, (void *)defaulturls},
701     {"follow_redirection", P_INT, PI_TEXT, &FollowRedirection,
702      CMT_FOLLOW_REDIRECTION, NULL},
703     {"meta_refresh", P_CHARINT, PI_ONOFF, (void *)&MetaRefresh,
704      CMT_META_REFRESH, NULL},
705     {"localhost_only", P_CHARINT, PI_ONOFF, (void *)&LocalhostOnly,
706      CMT_LOCALHOST_ONLY, NULL},
707 #ifdef INET6
708     {"dns_order", P_INT, PI_SEL_C, (void *)&DNS_order, CMT_DNS_ORDER,
709      (void *)dnsorders},
710 #endif				/* INET6 */
711 #ifdef USE_NNTP
712     {"nntpserver", P_STRING, PI_TEXT, (void *)&NNTP_server, CMT_NNTP_SERVER,
713      NULL},
714     {"nntpmode", P_STRING, PI_TEXT, (void *)&NNTP_mode, CMT_NNTP_MODE, NULL},
715     {"max_news", P_INT, PI_TEXT, (void *)&MaxNewsMessage, CMT_MAX_NEWS, NULL},
716 #endif
717     {NULL, 0, 0, NULL, NULL, NULL},
718 };
719 
720 #ifdef USE_M17N
721 struct param_ptr params10[] = {
722     {"display_charset", P_CODE, PI_CODE, (void *)&DisplayCharset,
723      CMT_DISPLAY_CHARSET, (void *)&display_charset_str},
724     {"document_charset", P_CODE, PI_CODE, (void *)&DocumentCharset,
725      CMT_DOCUMENT_CHARSET, (void *)&document_charset_str},
726     {"auto_detect", P_CHARINT, PI_SEL_C, (void *)&WcOption.auto_detect,
727      CMT_AUTO_DETECT, (void *)auto_detect_str},
728     {"system_charset", P_CODE, PI_CODE, (void *)&SystemCharset,
729      CMT_SYSTEM_CHARSET, (void *)&system_charset_str},
730     {"follow_locale", P_CHARINT, PI_ONOFF, (void *)&FollowLocale,
731      CMT_FOLLOW_LOCALE, NULL},
732     {"ext_halfdump", P_CHARINT, PI_ONOFF, (void *)&ExtHalfdump,
733      CMT_EXT_HALFDUMP, NULL},
734     {"use_wide", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_wide, CMT_USE_WIDE,
735      NULL},
736     {"use_combining", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_combining,
737      CMT_USE_COMBINING, NULL},
738 #ifdef USE_UNICODE
739     {"east_asian_width", P_CHARINT, PI_ONOFF,
740      (void *)&WcOption.east_asian_width, CMT_EAST_ASIAN_WIDTH, NULL},
741     {"use_language_tag", P_CHARINT, PI_ONOFF,
742      (void *)&WcOption.use_language_tag, CMT_USE_LANGUAGE_TAG, NULL},
743     {"ucs_conv", P_CHARINT, PI_ONOFF, (void *)&WcOption.ucs_conv, CMT_UCS_CONV,
744      NULL},
745 #endif
746     {"pre_conv", P_CHARINT, PI_ONOFF, (void *)&WcOption.pre_conv, CMT_PRE_CONV,
747      NULL},
748     {"search_conv", P_CHARINT, PI_ONOFF, (void *)&SearchConv, CMT_SEARCH_CONV,
749      NULL},
750     {"fix_width_conv", P_CHARINT, PI_ONOFF, (void *)&WcOption.fix_width_conv,
751      CMT_FIX_WIDTH_CONV, NULL},
752 #ifdef USE_UNICODE
753     {"use_gb12345_map", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_gb12345_map,
754      CMT_USE_GB12345_MAP, NULL},
755 #endif
756     {"use_jisx0201", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_jisx0201,
757      CMT_USE_JISX0201, NULL},
758     {"use_jisc6226", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_jisc6226,
759      CMT_USE_JISC6226, NULL},
760     {"use_jisx0201k", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_jisx0201k,
761      CMT_USE_JISX0201K, NULL},
762     {"use_jisx0212", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_jisx0212,
763      CMT_USE_JISX0212, NULL},
764     {"use_jisx0213", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_jisx0213,
765      CMT_USE_JISX0213, NULL},
766     {"strict_iso2022", P_CHARINT, PI_ONOFF, (void *)&WcOption.strict_iso2022,
767      CMT_STRICT_ISO2022, NULL},
768 #ifdef USE_UNICODE
769     {"gb18030_as_ucs", P_CHARINT, PI_ONOFF, (void *)&WcOption.gb18030_as_ucs,
770      CMT_GB18030_AS_UCS, NULL},
771 #endif
772     {"simple_preserve_space", P_CHARINT, PI_ONOFF, (void *)&SimplePreserveSpace,
773      CMT_SIMPLE_PRESERVE_SPACE, NULL},
774     {NULL, 0, 0, NULL, NULL, NULL},
775 };
776 #endif
777 
778 struct param_section sections[] = {
779     {N_("Display Settings"), params1},
780 #ifdef USE_COLOR
781     {N_("Color Settings"), params2},
782 #endif				/* USE_COLOR */
783     {N_("Miscellaneous Settings"), params3},
784     {N_("Directory Settings"), params5},
785     {N_("External Program Settings"), params6},
786     {N_("Network Settings"), params9},
787     {N_("Proxy Settings"), params4},
788 #ifdef USE_SSL
789     {N_("SSL Settings"), params7},
790 #endif
791 #ifdef USE_COOKIE
792     {N_("Cookie Settings"), params8},
793 #endif
794 #ifdef USE_M17N
795     {N_("Charset Settings"), params10},
796 #endif
797     {NULL, NULL}
798 };
799 
800 static Str to_str(struct param_ptr *p);
801 
802 static int
compare_table(struct rc_search_table * a,struct rc_search_table * b)803 compare_table(struct rc_search_table *a, struct rc_search_table *b)
804 {
805     return strcmp(a->param->name, b->param->name);
806 }
807 
808 static void
create_option_search_table()809 create_option_search_table()
810 {
811     int i, j, k;
812     int diff1, diff2;
813     char *p, *q;
814 
815     /* count table size */
816     RC_table_size = 0;
817     for (j = 0; sections[j].name != NULL; j++) {
818 	i = 0;
819 	while (sections[j].params[i].name) {
820 	    i++;
821 	    RC_table_size++;
822 	}
823     }
824 
825     RC_search_table = New_N(struct rc_search_table, RC_table_size);
826     k = 0;
827     for (j = 0; sections[j].name != NULL; j++) {
828 	i = 0;
829 	while (sections[j].params[i].name) {
830 	    RC_search_table[k].param = &sections[j].params[i];
831 	    k++;
832 	    i++;
833 	}
834     }
835 
836     qsort(RC_search_table, RC_table_size, sizeof(struct rc_search_table),
837 	  (int (*)(const void *, const void *))compare_table);
838 
839     diff2 = 0;
840     for (i = 0; i < RC_table_size - 1; i++) {
841 	p = RC_search_table[i].param->name;
842 	q = RC_search_table[i + 1].param->name;
843 	for (j = 0; p[j] != '\0' && q[j] != '\0' && p[j] == q[j]; j++) ;
844 	diff1 = j;
845 	if (diff1 > diff2)
846 	    RC_search_table[i].uniq_pos = diff1 + 1;
847 	else
848 	    RC_search_table[i].uniq_pos = diff2 + 1;
849 	diff2 = diff1;
850     }
851 }
852 
853 struct param_ptr *
search_param(char * name)854 search_param(char *name)
855 {
856     size_t b, e, i;
857     int cmp;
858     int len = strlen(name);
859 
860     for (b = 0, e = RC_table_size - 1; b <= e;) {
861 	i = (b + e) / 2;
862 	cmp = strncmp(name, RC_search_table[i].param->name, len);
863 
864 	if (!cmp) {
865 	    if (len >= RC_search_table[i].uniq_pos) {
866 		return RC_search_table[i].param;
867 	    }
868 	    else {
869 		while ((cmp =
870 			strcmp(name, RC_search_table[i].param->name)) <= 0)
871 		    if (!cmp)
872 			return RC_search_table[i].param;
873 		    else if (i == 0)
874 			return NULL;
875 		    else
876 			i--;
877 		/* ambiguous */
878 		return NULL;
879 	    }
880 	}
881 	else if (cmp < 0) {
882 	    if (i == 0)
883 		return NULL;
884 	    e = i - 1;
885 	}
886 	else
887 	    b = i + 1;
888     }
889     return NULL;
890 }
891 
892 /* show parameter with bad options invokation */
893 void
show_params(FILE * fp)894 show_params(FILE * fp)
895 {
896     int i, j, l;
897     const char *t = "";
898     char *cmt;
899 
900 #ifdef USE_M17N
901 #ifdef ENABLE_NLS
902     OptionCharset = SystemCharset;	/* FIXME */
903 #endif
904 #endif
905 
906     fputs("\nconfiguration parameters\n", fp);
907     for (j = 0; sections[j].name != NULL; j++) {
908 #ifdef USE_M17N
909 	if (!OptionEncode)
910 	    cmt =
911 		wc_conv(_(sections[j].name), OptionCharset,
912 			InnerCharset)->ptr;
913 	else
914 #endif
915 	    cmt = sections[j].name;
916 	fprintf(fp, "  section[%d]: %s\n", j, conv_to_system(cmt));
917 	i = 0;
918 	while (sections[j].params[i].name) {
919 	    switch (sections[j].params[i].type) {
920 	    case P_INT:
921 	    case P_SHORT:
922 	    case P_CHARINT:
923 	    case P_NZINT:
924 		t = (sections[j].params[i].inputtype ==
925 		     PI_ONOFF) ? "bool" : "number";
926 		break;
927 	    case P_CHAR:
928 		t = "char";
929 		break;
930 	    case P_STRING:
931 		t = "string";
932 		break;
933 #if defined(USE_SSL) && defined(USE_SSL_VERIFY)
934 	    case P_SSLPATH:
935 		t = "path";
936 		break;
937 #endif
938 #ifdef USE_COLOR
939 	    case P_COLOR:
940 		t = "color";
941 		break;
942 #endif
943 #ifdef USE_M17N
944 	    case P_CODE:
945 		t = "charset";
946 		break;
947 #endif
948 	    case P_PIXELS:
949 		t = "number";
950 		break;
951 	    case P_SCALE:
952 		t = "percent";
953 		break;
954 	    }
955 #ifdef USE_M17N
956 	    if (!OptionEncode)
957 		cmt = wc_conv(_(sections[j].params[i].comment),
958 			      OptionCharset, InnerCharset)->ptr;
959 	    else
960 #endif
961 		cmt = sections[j].params[i].comment;
962 	    l = 30 - (strlen(sections[j].params[i].name) + strlen(t));
963 	    if (l < 0)
964 		l = 1;
965 	    fprintf(fp, "    -o %s=<%s>%*s%s\n",
966 		    sections[j].params[i].name, t, l, " ",
967 		    conv_to_system(cmt));
968 	    i++;
969 	}
970     }
971 }
972 
973 int
str_to_bool(char * value,int old)974 str_to_bool(char *value, int old)
975 {
976     if (value == NULL)
977 	return 1;
978     switch (TOLOWER(*value)) {
979     case '0':
980     case 'f':			/* false */
981     case 'n':			/* no */
982     case 'u':			/* undef */
983 	return 0;
984     case 'o':
985 	if (TOLOWER(value[1]) == 'f')	/* off */
986 	    return 0;
987 	return 1;		/* on */
988     case 't':
989 	if (TOLOWER(value[1]) == 'o')	/* toggle */
990 	    return !old;
991 	return 1;		/* true */
992     case '!':
993     case 'r':			/* reverse */
994     case 'x':			/* exchange */
995 	return !old;
996     }
997     return 1;
998 }
999 
1000 #ifdef USE_COLOR
1001 static int
str_to_color(char * value)1002 str_to_color(char *value)
1003 {
1004     if (value == NULL)
1005 	return 8;		/* terminal */
1006     switch (TOLOWER(*value)) {
1007     case '0':
1008 	return 0;		/* black */
1009     case '1':
1010     case 'r':
1011 	return 1;		/* red */
1012     case '2':
1013     case 'g':
1014 	return 2;		/* green */
1015     case '3':
1016     case 'y':
1017 	return 3;		/* yellow */
1018     case '4':
1019 	return 4;		/* blue */
1020     case '5':
1021     case 'm':
1022 	return 5;		/* magenta */
1023     case '6':
1024     case 'c':
1025 	return 6;		/* cyan */
1026     case '7':
1027     case 'w':
1028 	return 7;		/* white */
1029     case '8':
1030     case 't':
1031 	return 8;		/* terminal */
1032     case 'b':
1033 	if (!strncasecmp(value, "blu", 3))
1034 	    return 4;		/* blue */
1035 	else
1036 	    return 0;		/* black */
1037     }
1038     return 8;			/* terminal */
1039 }
1040 #endif
1041 
1042 static int
set_param(char * name,char * value)1043 set_param(char *name, char *value)
1044 {
1045     struct param_ptr *p;
1046     double ppc;
1047 
1048     if (value == NULL)
1049 	return 0;
1050     p = search_param(name);
1051     if (p == NULL)
1052 	return 0;
1053     switch (p->type) {
1054     case P_INT:
1055 	if (atoi(value) >= 0)
1056 	    *(int *)p->varptr = (p->inputtype == PI_ONOFF)
1057 		? str_to_bool(value, *(int *)p->varptr) : atoi(value);
1058 	break;
1059     case P_NZINT:
1060 	if (atoi(value) > 0)
1061 	    *(int *)p->varptr = atoi(value);
1062 	break;
1063     case P_SHORT:
1064 	*(short *)p->varptr = (p->inputtype == PI_ONOFF)
1065 	    ? str_to_bool(value, *(short *)p->varptr) : atoi(value);
1066 	break;
1067     case P_CHARINT:
1068 	*(char *)p->varptr = (p->inputtype == PI_ONOFF)
1069 	    ? str_to_bool(value, *(char *)p->varptr) : atoi(value);
1070 	break;
1071     case P_CHAR:
1072 	*(char *)p->varptr = value[0];
1073 	break;
1074     case P_STRING:
1075 	*(char **)p->varptr = value;
1076 	break;
1077 #if defined(USE_SSL) && defined(USE_SSL_VERIFY)
1078     case P_SSLPATH:
1079 	if (value != NULL && value[0] != '\0')
1080 	    *(char **)p->varptr = rcFile(value);
1081 	else
1082 	    *(char **)p->varptr = NULL;
1083 	ssl_path_modified = 1;
1084 	break;
1085 #endif
1086 #ifdef USE_COLOR
1087     case P_COLOR:
1088 	*(int *)p->varptr = str_to_color(value);
1089 	break;
1090 #endif
1091 #ifdef USE_M17N
1092     case P_CODE:
1093 	*(wc_ces *) p->varptr =
1094 	    wc_guess_charset_short(value, *(wc_ces *) p->varptr);
1095 	break;
1096 #endif
1097     case P_PIXELS:
1098 	ppc = atof(value);
1099 	if (ppc >= MINIMUM_PIXEL_PER_CHAR && ppc <= MAXIMUM_PIXEL_PER_CHAR * 2)
1100 	    *(double *)p->varptr = ppc;
1101 	break;
1102     case P_SCALE:
1103 	ppc = atof(value);
1104 	if (ppc >= 10 && ppc <= 1000)
1105 	    *(double *)p->varptr = ppc;
1106 	break;
1107     }
1108     return 1;
1109 }
1110 
1111 int
set_param_option(char * option)1112 set_param_option(char *option)
1113 {
1114     Str tmp = Strnew();
1115     char *p = option, *q;
1116 
1117     while (*p && !IS_SPACE(*p) && *p != '=')
1118 	Strcat_char(tmp, *p++);
1119     while (*p && IS_SPACE(*p))
1120 	p++;
1121     if (*p == '=') {
1122 	p++;
1123 	while (*p && IS_SPACE(*p))
1124 	    p++;
1125     }
1126     Strlower(tmp);
1127     if (set_param(tmp->ptr, p))
1128 	goto option_assigned;
1129     q = tmp->ptr;
1130     if (!strncmp(q, "no", 2)) {	/* -o noxxx, -o no-xxx, -o no_xxx */
1131 	q += 2;
1132 	if (*q == '-' || *q == '_')
1133 	    q++;
1134     }
1135     else if (tmp->ptr[0] == '-')	/* -o -xxx */
1136 	q++;
1137     else
1138 	return 0;
1139     if (set_param(q, "0"))
1140 	goto option_assigned;
1141     return 0;
1142   option_assigned:
1143     return 1;
1144 }
1145 
1146 char *
get_param_option(char * name)1147 get_param_option(char *name)
1148 {
1149     struct param_ptr *p;
1150 
1151     p = search_param(name);
1152     return p ? to_str(p)->ptr : NULL;
1153 }
1154 
1155 static void
interpret_rc(FILE * f)1156 interpret_rc(FILE * f)
1157 {
1158     Str line;
1159     Str tmp;
1160     char *p;
1161 
1162     for (;;) {
1163 	line = Strfgets(f);
1164 	if (line->length == 0)		/* end of file */
1165 	    break;
1166 	Strchop(line);
1167 	if (line->length == 0)		/* blank line */
1168 	    continue;
1169 	Strremovefirstspaces(line);
1170 	if (line->ptr[0] == '#')	/* comment */
1171 	    continue;
1172 	tmp = Strnew();
1173 	p = line->ptr;
1174 	while (*p && !IS_SPACE(*p))
1175 	    Strcat_char(tmp, *p++);
1176 	while (*p && IS_SPACE(*p))
1177 	    p++;
1178 	Strlower(tmp);
1179 	set_param(tmp->ptr, p);
1180     }
1181 }
1182 
1183 void
parse_proxy()1184 parse_proxy()
1185 {
1186     if (non_null(HTTP_proxy))
1187 	parseURL(HTTP_proxy, &HTTP_proxy_parsed, NULL);
1188 #ifdef USE_SSL
1189     if (non_null(HTTPS_proxy))
1190 	parseURL(HTTPS_proxy, &HTTPS_proxy_parsed, NULL);
1191 #endif				/* USE_SSL */
1192 #ifdef USE_GOPHER
1193     if (non_null(GOPHER_proxy))
1194 	parseURL(GOPHER_proxy, &GOPHER_proxy_parsed, NULL);
1195 #endif
1196     if (non_null(FTP_proxy))
1197 	parseURL(FTP_proxy, &FTP_proxy_parsed, NULL);
1198     if (non_null(NO_proxy))
1199 	set_no_proxy(NO_proxy);
1200 }
1201 
1202 #ifdef USE_COOKIE
1203 void
parse_cookie()1204 parse_cookie()
1205 {
1206     if (non_null(cookie_reject_domains))
1207 	Cookie_reject_domains = make_domain_list(cookie_reject_domains);
1208     if (non_null(cookie_accept_domains))
1209 	Cookie_accept_domains = make_domain_list(cookie_accept_domains);
1210     if (non_null(cookie_avoid_wrong_number_of_dots))
1211 	Cookie_avoid_wrong_number_of_dots_domains
1212 	       	= make_domain_list(cookie_avoid_wrong_number_of_dots);
1213 }
1214 #endif
1215 
1216 #ifdef __EMX__
1217 static int
do_mkdir(const char * dir,long mode)1218 do_mkdir(const char *dir, long mode)
1219 {
1220     char *r, abs[_MAX_PATH];
1221     size_t n;
1222 
1223     _abspath(abs, rc_dir, _MAX_PATH);	/* Translate '\\' to '/' */
1224 
1225     if (!(n = strlen(abs)))
1226 	return -1;
1227 
1228     if (*(r = abs + n - 1) == '/')	/* Ignore tailing slash if it is */
1229 	*r = 0;
1230 
1231     return mkdir(abs, mode);
1232 }
1233 #else				/* not __EMX__ */
1234 #ifdef __MINGW32_VERSION
1235 #define do_mkdir(dir,mode) mkdir(dir)
1236 #else
1237 #define do_mkdir(dir,mode) mkdir(dir,mode)
1238 #endif				/* not __MINW32_VERSION */
1239 #endif				/* not __EMX__ */
1240 
1241 static void loadSiteconf(void);
1242 
1243 void
sync_with_option(void)1244 sync_with_option(void)
1245 {
1246     if (PagerMax < LINES)
1247 	PagerMax = LINES;
1248     WrapSearch = WrapDefault;
1249     parse_proxy();
1250 #ifdef USE_COOKIE
1251     parse_cookie();
1252 #endif
1253     initMailcap();
1254     initMimeTypes();
1255 #ifdef USE_EXTERNAL_URI_LOADER
1256     initURIMethods();
1257 #endif
1258 #ifdef USE_MIGEMO
1259     init_migemo();
1260 #endif
1261 #ifdef USE_IMAGE
1262     if (fmInitialized && (displayImage || enable_inline_image))
1263 	initImage();
1264 #else
1265     displayImage = FALSE;	/* XXX */
1266 #endif
1267     loadPasswd();
1268     loadPreForm();
1269     loadSiteconf();
1270 
1271     if (AcceptLang == NULL || *AcceptLang == '\0') {
1272 	/* TRANSLATORS:
1273 	 * AcceptLang default: this is used in Accept-Language: HTTP request
1274 	 * header. For example, ja.po should translate it as
1275 	 * "ja;q=1.0, en;q=0.5" like that.
1276 	 */
1277 	AcceptLang = _("en;q=1.0");
1278     }
1279     if (AcceptEncoding == NULL || *AcceptEncoding == '\0')
1280 	AcceptEncoding = acceptableEncoding();
1281     if (AcceptMedia == NULL || *AcceptMedia == '\0')
1282 	AcceptMedia = acceptableMimeTypes();
1283 #ifdef USE_UNICODE
1284     update_utf8_symbol();
1285 #endif
1286     if (fmInitialized) {
1287 	initKeymap(FALSE);
1288 #ifdef USE_MOUSE
1289 	initMouseAction();
1290 #endif				/* MOUSE */
1291 #ifdef USE_MENU
1292 	initMenu();
1293 #endif				/* MENU */
1294     }
1295 }
1296 
1297 void
init_rc(void)1298 init_rc(void)
1299 {
1300     int i;
1301     struct stat st;
1302     FILE *f;
1303 
1304     if (rc_dir != NULL)
1305 	goto open_rc;
1306 
1307     rc_dir = expandPath(RC_DIR);
1308     i = strlen(rc_dir);
1309     if (i > 1 && rc_dir[i - 1] == '/')
1310 	rc_dir[i - 1] = '\0';
1311 
1312 #ifdef USE_M17N
1313     display_charset_str = wc_get_ces_list();
1314     document_charset_str = display_charset_str;
1315     system_charset_str = display_charset_str;
1316 #endif
1317 
1318     if (stat(rc_dir, &st) < 0) {
1319 	if (errno == ENOENT) {	/* no directory */
1320 	    if (do_mkdir(rc_dir, 0700) < 0) {
1321 		/* fprintf(stderr, "Can't create config directory (%s)!\n", rc_dir); */
1322 		goto rc_dir_err;
1323 	    }
1324 	    else {
1325 		stat(rc_dir, &st);
1326 	    }
1327 	}
1328 	else {
1329 	    /* fprintf(stderr, "Can't open config directory (%s)!\n", rc_dir); */
1330 	    goto rc_dir_err;
1331 	}
1332     }
1333     if (!S_ISDIR(st.st_mode)) {
1334 	/* not a directory */
1335 	/* fprintf(stderr, "%s is not a directory!\n", rc_dir); */
1336 	goto rc_dir_err;
1337     }
1338     if (!(st.st_mode & S_IWUSR)) {
1339 	/* fprintf(stderr, "%s is not writable!\n", rc_dir); */
1340 	goto rc_dir_err;
1341     }
1342     no_rc_dir = FALSE;
1343     tmp_dir = rc_dir;
1344 
1345     if (config_file == NULL)
1346 	config_file = rcFile(CONFIG_FILE);
1347 
1348     create_option_search_table();
1349 
1350   open_rc:
1351     /* open config file */
1352     if ((f = fopen(etcFile(W3MCONFIG), "rt")) != NULL) {
1353 	interpret_rc(f);
1354 	fclose(f);
1355     }
1356     if ((f = fopen(confFile(CONFIG_FILE), "rt")) != NULL) {
1357 	interpret_rc(f);
1358 	fclose(f);
1359     }
1360     if (config_file && (f = fopen(config_file, "rt")) != NULL) {
1361 	interpret_rc(f);
1362 	fclose(f);
1363     }
1364     return;
1365 
1366   rc_dir_err:
1367     no_rc_dir = TRUE;
1368     if (((tmp_dir = getenv("TMPDIR")) == NULL || *tmp_dir == '\0') &&
1369 	((tmp_dir = getenv("TMP")) == NULL || *tmp_dir == '\0') &&
1370 	((tmp_dir = getenv("TEMP")) == NULL || *tmp_dir == '\0'))
1371 	tmp_dir = "/tmp";
1372 #ifdef HAVE_MKDTEMP
1373     tmp_dir = mkdtemp(Strnew_m_charp(tmp_dir, "/w3m-XXXXXX", NULL)->ptr);
1374     if (tmp_dir == NULL)
1375 	tmp_dir = rc_dir;
1376 #endif
1377     create_option_search_table();
1378     goto open_rc;
1379 }
1380 
1381 
1382 static char optionpanel_src1[] =
1383     "<html><head><title>Option Setting Panel</title></head><body>\
1384 <h1 align=center>Option Setting Panel<br>(w3m version %s)</b></h1>\
1385 <form method=post action=\"file:///$LIB/" W3MHELPERPANEL_CMDNAME "\">\
1386 <input type=hidden name=mode value=panel>\
1387 <input type=hidden name=cookie value=\"%s\">\
1388 <input type=submit value=\"%s\">\
1389 </form><br>\
1390 <form method=internal action=option>";
1391 
1392 static Str optionpanel_str = NULL;
1393 
1394 static Str
to_str(struct param_ptr * p)1395 to_str(struct param_ptr *p)
1396 {
1397     switch (p->type) {
1398     case P_INT:
1399 #ifdef USE_COLOR
1400     case P_COLOR:
1401 #endif
1402 #ifdef USE_M17N
1403     case P_CODE:
1404 	return Sprintf("%d", (int)(*(wc_ces *) p->varptr));
1405 #endif
1406     case P_NZINT:
1407 	return Sprintf("%d", *(int *)p->varptr);
1408     case P_SHORT:
1409 	return Sprintf("%d", *(short *)p->varptr);
1410     case P_CHARINT:
1411 	return Sprintf("%d", *(char *)p->varptr);
1412     case P_CHAR:
1413 	return Sprintf("%c", *(char *)p->varptr);
1414     case P_STRING:
1415 #if defined(USE_SSL) && defined(USE_SSL_VERIFY)
1416     case P_SSLPATH:
1417 #endif
1418 	/*  SystemCharset -> InnerCharset */
1419 	return Strnew_charp(conv_from_system(*(char **)p->varptr));
1420     case P_PIXELS:
1421     case P_SCALE:
1422 	return Sprintf("%g", *(double *)p->varptr);
1423     }
1424     /* not reached */
1425     return NULL;
1426 }
1427 
1428 Buffer *
load_option_panel(void)1429 load_option_panel(void)
1430 {
1431     Str src;
1432     struct param_ptr *p;
1433     struct sel_c *s;
1434 #ifdef USE_M17N
1435     wc_ces_list *c;
1436 #endif
1437     int x, i;
1438     Str tmp;
1439     Buffer *buf;
1440 
1441     if (optionpanel_str == NULL)
1442 	optionpanel_str = Sprintf(optionpanel_src1, w3m_version,
1443 			      html_quote(localCookie()->ptr), _(CMT_HELPER));
1444 #ifdef USE_M17N
1445 #ifdef ENABLE_NLS
1446     OptionCharset = SystemCharset;	/* FIXME */
1447 #endif
1448     if (!OptionEncode) {
1449 	optionpanel_str =
1450 	    wc_Str_conv(optionpanel_str, OptionCharset, InnerCharset);
1451 	for (i = 0; sections[i].name != NULL; i++) {
1452 	    sections[i].name =
1453 		wc_conv(_(sections[i].name), OptionCharset,
1454 			InnerCharset)->ptr;
1455 	    for (p = sections[i].params; p->name; p++) {
1456 		p->comment =
1457 		    wc_conv(_(p->comment), OptionCharset,
1458 			    InnerCharset)->ptr;
1459 		if (p->inputtype == PI_SEL_C
1460 #ifdef USE_COLOR
1461 			&& p->select != colorstr
1462 #endif
1463 			) {
1464 		    for (s = (struct sel_c *)p->select; s->text != NULL; s++) {
1465 			s->text =
1466 			    wc_conv(_(s->text), OptionCharset,
1467 				    InnerCharset)->ptr;
1468 		    }
1469 		}
1470 	    }
1471 	}
1472 #ifdef USE_COLOR
1473 	for (s = colorstr; s->text; s++)
1474 	    s->text = wc_conv(_(s->text), OptionCharset,
1475 			      InnerCharset)->ptr;
1476 #endif
1477 	OptionEncode = TRUE;
1478     }
1479 #endif
1480     src = Strdup(optionpanel_str);
1481 
1482     Strcat_charp(src, "<table><tr><td>");
1483     for (i = 0; sections[i].name != NULL; i++) {
1484 	Strcat_m_charp(src, "<h1>", sections[i].name, "</h1>", NULL);
1485 	p = sections[i].params;
1486 	Strcat_charp(src, "<table width=100% cellpadding=0>");
1487 	while (p->name) {
1488 	    Strcat_m_charp(src, "<tr><td>", p->comment, NULL);
1489 	    Strcat(src, Sprintf("</td><td width=%d>",
1490 				(int)(28 * pixel_per_char)));
1491 	    switch (p->inputtype) {
1492 	    case PI_TEXT:
1493 		Strcat_m_charp(src, "<input type=text name=",
1494 			       p->name,
1495 			       " value=\"",
1496 			       html_quote(to_str(p)->ptr), "\">", NULL);
1497 		break;
1498 	    case PI_ONOFF:
1499 		x = atoi(to_str(p)->ptr);
1500 		Strcat_m_charp(src, "<input type=radio name=",
1501 			       p->name,
1502 			       " value=1",
1503 			       (x ? " checked" : ""),
1504 			       ">YES&nbsp;&nbsp;<input type=radio name=",
1505 			       p->name,
1506 			       " value=0", (x ? "" : " checked"), ">NO", NULL);
1507 		break;
1508 	    case PI_SEL_C:
1509 		tmp = to_str(p);
1510 		Strcat_m_charp(src, "<select name=", p->name, ">", NULL);
1511 		for (s = (struct sel_c *)p->select; s->text != NULL; s++) {
1512 		    Strcat_charp(src, "<option value=");
1513 		    Strcat(src, Sprintf("%s\n", s->cvalue));
1514 		    if ((p->type != P_CHAR && s->value == atoi(tmp->ptr)) ||
1515 			(p->type == P_CHAR && (char)s->value == *(tmp->ptr)))
1516 			Strcat_charp(src, " selected");
1517 		    Strcat_char(src, '>');
1518 		    Strcat_charp(src, s->text);
1519 		}
1520 		Strcat_charp(src, "</select>");
1521 		break;
1522 #ifdef USE_M17N
1523 	    case PI_CODE:
1524 		tmp = to_str(p);
1525 		Strcat_m_charp(src, "<select name=", p->name, ">", NULL);
1526 		for (c = *(wc_ces_list **) p->select; c->desc != NULL; c++) {
1527 		    Strcat_charp(src, "<option value=");
1528 		    Strcat(src, Sprintf("%s\n", c->name));
1529 		    if (c->id == atoi(tmp->ptr))
1530 			Strcat_charp(src, " selected");
1531 		    Strcat_char(src, '>');
1532 		    Strcat_charp(src, c->desc);
1533 		}
1534 		Strcat_charp(src, "</select>");
1535 		break;
1536 #endif
1537 	    }
1538 	    Strcat_charp(src, "</td></tr>\n");
1539 	    p++;
1540 	}
1541 	Strcat_charp(src,
1542 		     "<tr><td></td><td><p><input type=submit value=\"OK\"></td></tr>");
1543 	Strcat_charp(src, "</table><hr width=50%>");
1544     }
1545     Strcat_charp(src, "</table></form></body></html>");
1546     buf = loadHTMLString(src);
1547 #ifdef USE_M17N
1548     if (buf)
1549 	buf->document_charset = OptionCharset;
1550 #endif
1551     return buf;
1552 }
1553 
1554 void
panel_set_option(struct parsed_tagarg * arg)1555 panel_set_option(struct parsed_tagarg *arg)
1556 {
1557     FILE *f = NULL;
1558     char *p;
1559     Str s = Strnew(), tmp;
1560 
1561     if (config_file == NULL) {
1562 	disp_message("There's no config file... config not saved", FALSE);
1563     }
1564     else {
1565 	f = fopen(config_file, "wt");
1566 	if (f == NULL) {
1567 	    disp_message("Can't write option!", FALSE);
1568 	}
1569     }
1570     while (arg) {
1571 	/*  InnerCharset -> SystemCharset */
1572 	if (arg->value) {
1573 	    p = conv_to_system(arg->value);
1574 	    if (set_param(arg->arg, p)) {
1575 		tmp = Sprintf("%s %s\n", arg->arg, p);
1576 		Strcat(tmp, s);
1577 		s = tmp;
1578 	    }
1579 	}
1580 	arg = arg->next;
1581     }
1582     if (f) {
1583 	fputs(s->ptr, f);
1584 	fclose(f);
1585     }
1586     sync_with_option();
1587     backBf();
1588 }
1589 
1590 char *
rcFile(char * base)1591 rcFile(char *base)
1592 {
1593     if (base &&
1594 	(base[0] == '/' ||
1595 	 (base[0] == '.'
1596 	  && (base[1] == '/' || (base[1] == '.' && base[2] == '/')))
1597 	 || (base[0] == '~' && base[1] == '/')))
1598 	/* /file, ./file, ../file, ~/file */
1599 	return expandPath(base);
1600     return expandPath(Strnew_m_charp(rc_dir, "/", base, NULL)->ptr);
1601 }
1602 
1603 char *
auxbinFile(char * base)1604 auxbinFile(char *base)
1605 {
1606     return expandPath(Strnew_m_charp(w3m_auxbin_dir(), "/", base, NULL)->ptr);
1607 }
1608 
1609 #if 0				/* not used */
1610 char *
1611 libFile(char *base)
1612 {
1613     return expandPath(Strnew_m_charp(w3m_lib_dir(), "/", base, NULL)->ptr);
1614 }
1615 #endif
1616 
1617 char *
etcFile(char * base)1618 etcFile(char *base)
1619 {
1620     return expandPath(Strnew_m_charp(w3m_etc_dir(), "/", base, NULL)->ptr);
1621 }
1622 
1623 char *
confFile(char * base)1624 confFile(char *base)
1625 {
1626     return expandPath(Strnew_m_charp(w3m_conf_dir(), "/", base, NULL)->ptr);
1627 }
1628 
1629 #ifndef USE_HELP_CGI
1630 char *
helpFile(char * base)1631 helpFile(char *base)
1632 {
1633     return expandPath(Strnew_m_charp(w3m_help_dir(), "/", base, NULL)->ptr);
1634 }
1635 #endif
1636 
1637 /* siteconf */
1638 /*
1639  * url "<url>"|/<re-url>/|m@<re-url>@i [exact]
1640  * substitute_url "<destination-url>"
1641  * url_charset <charset>
1642  * no_referer_from on|off
1643  * no_referer_to on|off
1644  * user_agent "<string>"
1645  *
1646  * The last match wins.
1647  */
1648 
1649 struct siteconf_rec {
1650     struct siteconf_rec *next;
1651     char *url;
1652     Regex *re_url;
1653     int url_exact;
1654     unsigned char mask[(SCONF_N_FIELD + 7) >> 3];
1655 
1656     char *substitute_url;
1657     char *user_agent;
1658 #ifdef USE_M17N
1659     wc_ces url_charset;
1660 #endif
1661     int no_referer_from;
1662     int no_referer_to;
1663 };
1664 #define SCONF_TEST(ent, f) ((ent)->mask[(f)>>3] & (1U<<((f)&7)))
1665 #define SCONF_SET(ent, f) ((ent)->mask[(f)>>3] |= (1U<<((f)&7)))
1666 #define SCONF_CLEAR(ent, f) ((ent)->mask[(f)>>3] &= ~(1U<<((f)&7)))
1667 
1668 static struct siteconf_rec *siteconf_head = NULL;
1669 static struct siteconf_rec *newSiteconfRec(void);
1670 
1671 static struct siteconf_rec *
newSiteconfRec(void)1672 newSiteconfRec(void)
1673 {
1674     struct siteconf_rec *ent;
1675 
1676     ent = New(struct siteconf_rec);
1677     ent->next = NULL;
1678     ent->url = NULL;
1679     ent->re_url = NULL;
1680     ent->url_exact = FALSE;
1681     memset(ent->mask, 0, sizeof(ent->mask));
1682 
1683     ent->substitute_url = NULL;
1684     ent->user_agent = NULL;
1685 #ifdef USE_M17N
1686     ent->url_charset = 0;
1687 #endif
1688     return ent;
1689 }
1690 
1691 static void
loadSiteconf(void)1692 loadSiteconf(void)
1693 {
1694     char *efname;
1695     FILE *fp;
1696     Str line;
1697     struct siteconf_rec *ent = NULL;
1698 
1699     siteconf_head = NULL;
1700     if (!siteconf_file)
1701 	return;
1702     if ((efname = expandPath(siteconf_file)) == NULL)
1703 	return;
1704     fp = fopen(efname, "r");
1705     if (fp == NULL)
1706 	return;
1707     while (line = Strfgets(fp), line->length > 0) {
1708 	char *p, *s;
1709 
1710 	Strchop(line);
1711 	p = line->ptr;
1712 	SKIP_BLANKS(p);
1713 	if (*p == '#' || *p == '\0')
1714 	    continue;
1715 	s = getWord(&p);
1716 
1717 	/* The "url" begins a new record. */
1718 	if (strcmp(s, "url") == 0) {
1719 	    char *url, *opt;
1720 	    struct siteconf_rec *newent;
1721 
1722 	    /* First, register the current record. */
1723 	    if (ent) {
1724 		ent->next = siteconf_head;
1725 		siteconf_head = ent;
1726 		ent = NULL;
1727 	    }
1728 
1729 	    /* Second, create a new record. */
1730 	    newent = newSiteconfRec();
1731 	    url = getRegexWord((const char **)&p, &newent->re_url);
1732 	    opt = getWord(&p);
1733 	    SKIP_BLANKS(p);
1734 	    if (!newent->re_url) {
1735 		ParsedURL pu;
1736 		if (!url || !*url)
1737 		    continue;
1738 		parseURL2(url, &pu, NULL);
1739 		newent->url = parsedURL2Str(&pu)->ptr;
1740 	    }
1741 	    /* If we have an extra or unknown option, ignore this record
1742 	     * for future extensions. */
1743 	    if (strcmp(opt, "exact") == 0) {
1744 		newent->url_exact = TRUE;
1745 	    }
1746 	    else if (*opt != 0)
1747 		    continue;
1748 	    if (*p)
1749 		continue;
1750 	    ent = newent;
1751 	    continue;
1752 	}
1753 
1754 	/* If the current record is broken, skip to the next "url". */
1755 	if (!ent)
1756 	    continue;
1757 
1758 	/* Fill the new record. */
1759 	if (strcmp(s, "substitute_url") == 0) {
1760 	    ent->substitute_url = getQWord(&p);
1761 	    SCONF_SET(ent, SCONF_SUBSTITUTE_URL);
1762 	}
1763 	if (strcmp(s, "user_agent") == 0) {
1764 	    ent->user_agent = getQWord(&p);
1765 	    SCONF_SET(ent, SCONF_USER_AGENT);
1766 	}
1767 #ifdef USE_M17N
1768 	else if (strcmp(s, "url_charset") == 0) {
1769 	    char *charset = getWord(&p);
1770 	    ent->url_charset = (charset && *charset) ?
1771 		wc_charset_to_ces(charset) : 0;
1772 	    SCONF_SET(ent, SCONF_URL_CHARSET);
1773 	}
1774 #endif /* USE_M17N */
1775 	else if (strcmp(s, "no_referer_from") == 0) {
1776 	    ent->no_referer_from = str_to_bool(getWord(&p), 0);
1777 	    SCONF_SET(ent, SCONF_NO_REFERER_FROM);
1778 	}
1779 	else if (strcmp(s, "no_referer_to") == 0) {
1780 	    ent->no_referer_to = str_to_bool(getWord(&p), 0);
1781 	    SCONF_SET(ent, SCONF_NO_REFERER_TO);
1782 	}
1783     }
1784     if (ent) {
1785 	ent->next = siteconf_head;
1786 	siteconf_head = ent;
1787 	ent = NULL;
1788     }
1789     fclose(fp);
1790 }
1791 
1792 const void *
querySiteconf(const ParsedURL * query_pu,int field)1793 querySiteconf(const ParsedURL *query_pu, int field)
1794 {
1795     const struct siteconf_rec *ent;
1796     Str u;
1797     char *firstp, *lastp;
1798 
1799     if (field < 0 || field >= SCONF_N_FIELD)
1800 	return NULL;
1801     if (!query_pu || IS_EMPTY_PARSED_URL(query_pu))
1802 	return NULL;
1803     u = parsedURL2Str((ParsedURL *)query_pu);
1804     if (u->length == 0)
1805 	return NULL;
1806 
1807     for (ent = siteconf_head; ent; ent = ent->next) {
1808 	if (!SCONF_TEST(ent, field))
1809 	    continue;
1810 	if (ent->re_url) {
1811 	    if (RegexMatch(ent->re_url, u->ptr, u->length, 1)) {
1812 		MatchedPosition(ent->re_url, &firstp, &lastp);
1813 		if (!ent->url_exact)
1814 		    goto url_found;
1815 		if (firstp != u->ptr || lastp == firstp)
1816 		    continue;
1817 		if (*lastp == 0 || *lastp == '?' || *(lastp - 1) == '?' ||
1818 		    *lastp == '#' || *(lastp - 1) == '#')
1819 		    goto url_found;
1820 	    }
1821 	} else {
1822 	    int matchlen = strmatchlen(ent->url, u->ptr, u->length);
1823 	    if (matchlen == 0 || ent->url[matchlen] != 0)
1824 		continue;
1825 	    firstp = u->ptr;
1826 	    lastp = u->ptr + matchlen;
1827 	    if (*lastp == 0 || *lastp == '?' || *(lastp - 1) == '?' ||
1828 		*lastp == '#' || *(lastp - 1) == '#')
1829 		goto url_found;
1830 	    if (!ent->url_exact && (*lastp == '/' || *(lastp - 1) == '/'))
1831 		goto url_found;
1832 	}
1833     }
1834     return NULL;
1835 
1836 url_found:
1837     switch (field) {
1838     case SCONF_SUBSTITUTE_URL:
1839 	if (ent->substitute_url && *ent->substitute_url) {
1840 	    Str tmp = Strnew_charp_n(u->ptr, firstp - u->ptr);
1841 	    Strcat_charp(tmp, ent->substitute_url);
1842 	    Strcat_charp(tmp, lastp);
1843 	    return tmp->ptr;
1844 	}
1845 	return NULL;
1846     case SCONF_USER_AGENT:
1847 	if (ent->user_agent && *ent->user_agent) {
1848 	    return ent->user_agent;
1849 	}
1850 	return NULL;
1851 #ifdef USE_M17N
1852     case SCONF_URL_CHARSET:
1853 	return &ent->url_charset;
1854 #endif
1855     case SCONF_NO_REFERER_FROM:
1856 	return &ent->no_referer_from;
1857     case SCONF_NO_REFERER_TO:
1858 	return &ent->no_referer_to;
1859     }
1860     return NULL;
1861 }
1862