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