2
* (c) 2002 Mikulas Patocka, Petr 'Brain' Kulhavy
3
* This file is a part of the Links program, released under GPL
5
* Does the configuration file.
10
static void get_system_name(void)
14
#if defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME)
16
memset(&name, 0, sizeof name);
18
unsigned char *str = init_str();
20
add_to_str(&str, &l, name.sysname);
21
add_to_str(&str, &l, " ");
22
add_to_str(&str, &l, name.release);
23
add_to_str(&str, &l, " ");
24
add_to_str(&str, &l, name.machine);
25
if (l >= MAX_STR_LEN) str[MAX_STR_LEN - 1] = 0;
26
strcpy(system_name, str);
32
memset(system_name, 0, MAX_STR_LEN);
33
if (!(f = popen("uname -srm", "r"))) goto fail;
34
if (fread(system_name, 1, MAX_STR_LEN - 1, f) <= 0) {
39
for (p = system_name; *p; p++) if (*p < ' ') {
43
if (system_name[0]) return;
46
strcpy(system_name, SYSTEM_NAME);
51
unsigned char *(*rd_cmd)(struct option *, unsigned char ***, int *);
52
unsigned char *(*rd_cfg)(struct option *, unsigned char *);
53
void (*wr_cfg)(struct option *, unsigned char **, int *);
54
int min, max; /* for double min and max are in 1/100's (e.g. 0.1 is min==10) */
56
unsigned char *cfg_name;
57
unsigned char *cmd_name;
60
extern struct option links_options[];
61
extern struct option html_options[];
63
struct option *all_options[] = { links_options, html_options, NULL, };
67
unsigned char *get_token(unsigned char **);
68
void parse_config_file(unsigned char *, unsigned char *, struct option **);
69
unsigned char *create_config_string(struct option *);
70
unsigned char *get_home(int *);
71
void load_config_file(unsigned char *, unsigned char *);
72
int write_config_data(unsigned char *, unsigned char *, struct option *, struct terminal *);
73
void add_nm(struct option *, unsigned char **, int *);
74
void add_quoted_to_str(unsigned char **, int *, unsigned char *);
75
unsigned char *num_rd(struct option *, unsigned char *);
76
void num_wr(struct option *, unsigned char **, int *);
77
unsigned char *dbl_rd(struct option *, unsigned char *);
78
void dbl_wr(struct option *, unsigned char **, int *);
79
unsigned char *str_rd(struct option *, unsigned char *);
80
void str_wr(struct option *, unsigned char **, int *);
81
unsigned char *cp_rd(struct option *, unsigned char *);
82
void cp_wr(struct option *, unsigned char **, int *);
83
unsigned char *lang_rd(struct option *, unsigned char *);
84
void lang_wr(struct option *, unsigned char **, int *);
85
int getnum(unsigned char *, int *, int, int);
86
unsigned char *type_rd(struct option *, unsigned char *);
87
void type_wr(struct option *, unsigned char **, int *);
88
unsigned char *ext_rd(struct option *, unsigned char *);
89
void ext_wr(struct option *, unsigned char **, int *);
90
unsigned char *prog_rd(struct option *, unsigned char *);
91
void prog_wr(struct option *, unsigned char **, int *);
92
unsigned char *term_rd(struct option *, unsigned char *);
93
unsigned char *term2_rd(struct option *, unsigned char *);
94
void term_wr(struct option *, unsigned char **, int *);
95
unsigned char *dp_rd(struct option *, unsigned char *);
96
void dp_wr(struct option *, unsigned char **, int *);
97
unsigned char *gen_cmd(struct option *, unsigned char ***, int *);
98
unsigned char *lookup_cmd(struct option *, unsigned char ***, int *);
99
unsigned char *version_cmd(struct option *, unsigned char ***, int *);
100
unsigned char *set_cmd(struct option *, unsigned char ***, int *);
101
unsigned char *unset_cmd(struct option *, unsigned char ***, int *);
102
unsigned char *setstr_cmd(struct option *, unsigned char ***, int *);
103
unsigned char *force_html_cmd(struct option *, unsigned char ***, int *);
104
unsigned char *dump_cmd(struct option *, unsigned char ***, int *);
105
unsigned char *printhelp_cmd(struct option *, unsigned char ***, int *);
106
unsigned char *p_arse_options(int, unsigned char *[], struct option **);
107
unsigned char *block_rd(struct option *, unsigned char *);
108
void block_wr(struct option *, unsigned char **, int *);
110
unsigned char *p_arse_options(int argc, unsigned char *argv[], struct option **opt)
112
unsigned char *e, *u = NULL;
116
if (argv[-1][0] == '-') {
117
struct option *options;
119
for (op = opt; (options = *op); op++) for (i = 0; options[i].p; i++)
120
if (options[i].rd_cmd && options[i].cmd_name &&
121
!strcasecmp(options[i].cmd_name, &argv[-1][1])) {
122
if ((e = options[i].rd_cmd(&options[i], &argv, &argc))) {
123
if (e[0]) fprintf(stderr, "Error parsing option %s: %s\n", argv[-1], e);
129
#ifdef GRDRV_DIRECTFB
130
if (!strncmp(argv[-1], "--dfb:", 6))
133
fprintf(stderr, "Unknown option %s\n", argv[-1]);
135
} else if (!u) u = argv[-1];
143
unsigned char *parse_options(int argc, unsigned char *argv[])
145
return p_arse_options(argc, argv, all_options);
148
unsigned char *get_token(unsigned char **line)
150
unsigned char *s = NULL;
155
while (**line == ' ' || **line == 9) (*line)++;
157
for (s = init_str(); **line; (*line)++) {
160
else if (**line == '\\') {
164
else if (**line == '"') {
168
else if ((**line == ' ' || **line == 9) && !quote)
170
add_chr_to_str(&s, &l, **line);
176
void parse_config_file(unsigned char *name, unsigned char *file, struct option **opt)
178
struct option *options;
184
unsigned char *n, *p;
189
while (file[0] && (file[0] == ' ' || file[0] == 9)) file++;
191
while (file[0] && file[0] > ' ') file++;
197
while (file[0] == 9 || file[0] == ' ') file++;
199
while (file[0] && file[0] != 10 && file[0] != 13) file++;
202
if ((file[1] == 10 || file[1] == 13) && file[0] != file[1]) file++;
206
if (n[0] == '#') goto f;
207
if (!(tok = get_token(&n))) goto f;
209
for (op = opt; (options = *op); op++)
210
for (i = 0; options[i].p; i++) if (options[i].cfg_name && (size_t)nl == strlen(options[i].cfg_name) && !casecmp(tok, options[i].cfg_name, nl)) {
211
unsigned char *o = memacpy(p, pl);
212
if ((e = options[i].rd_cfg(&options[i], o))) {
213
if (e[0]) fprintf(stderr, "Error parsing config file %s, line %d: %s\n", name, line, e), err = 1;
218
fprintf(stderr, "Unknown option in config file %s, line %d\n", name, line);
221
if (tok) mem_free(tok);
223
if (err) fprintf(stderr, "\007"), sleep(1);
226
unsigned char *create_config_string(struct option *options)
228
unsigned char *s = init_str();
231
add_to_str(&s, &l, "# This file is automatically generated by Links -- please do not edit.");
232
for (i = 0; options[i].p; i++) if (options[i].wr_cfg)
233
options[i].wr_cfg(&options[i], &s, &l);
234
add_to_str(&s, &l, NEWLINE);
238
#define FILE_BUF 1024
240
unsigned char cfg_buffer[FILE_BUF];
242
unsigned char *read_config_file(unsigned char *name)
247
if ((h = open(name, O_RDONLY | O_NOCTTY)) == -1) return NULL;
250
while ((r = read(h, cfg_buffer, FILE_BUF)) > 0) {
252
for (i = 0; i < r; i++) if (!cfg_buffer[i]) cfg_buffer[i] = ' ';
253
add_bytes_to_str(&s, &l, cfg_buffer, r);
255
if (r == -1) mem_free(s), s = NULL;
260
int write_to_config_file(unsigned char *name, unsigned char *c)
265
unsigned char *tmp_name = stracpy(name);
266
unsigned char *ds, *dt, *dot;
267
for (dt = ds = tmp_name; *dt; dt++) if (dir_sep(*dt)) ds = dt;
268
if ((dot = strchr(ds, '.'))) *dot = 0;
269
add_to_strn(&tmp_name, ".tmp");
270
if ((h = open(tmp_name, O_WRONLY | O_NOCTTY | O_CREAT | O_TRUNC, 0666)) == -1) {
278
if ((w = write(h, c + rr - r, r)) <= 0) {
279
int err = !w ? ENOSPC : errno;
288
#ifndef RENAME_OVER_EXISTING_FILES
291
if (rename(tmp_name, name)) {
301
unsigned char *get_home(int *n)
304
unsigned char *home = NULL;
305
unsigned char *home_links;
306
unsigned char *config_dir = stracpy(getenv("CONFIG_DIR"));
311
home = stracpy(getenv("APPDATA"));
312
if (home && (stat(home, &st) == -1 || !S_ISDIR(st.st_mode))) {
318
if (!home) home = stracpy(getenv("HOME"));
321
/* When we run in Cygwin without Cygwin environment, it reports home "/".
322
Unfortunatelly, it can't write anything to that directory */
323
|| !strcmp(home, "/")
327
home = stracpy(path_to_exe);
329
if (config_dir) mem_free(config_dir);
332
for (i = strlen(home) - 1; i >= 0; i--) if (dir_sep(home[i])) {
339
while (home[0] && dir_sep(home[strlen(home) - 1])) home[strlen(home) - 1] = 0;
340
if (home[0]) add_to_strn(&home, "/");
341
home_links = stracpy(home);
344
add_to_strn(&home_links, config_dir);
345
while (home_links[0] && dir_sep(home_links[strlen(home_links) - 1])) home_links[strlen(home_links) - 1] = 0;
346
if (stat(home_links, &st) != -1 && S_ISDIR(st.st_mode)) {
347
add_to_strn(&home_links, "/links");
349
fprintf(stderr, "CONFIG_DIR set to %s. But directory %s doesn't exist.\n\007", config_dir, home_links);
351
mem_free(home_links);
352
home_links = stracpy(home);
353
add_to_strn(&home_links, ".links");
355
mem_free(config_dir);
356
} else add_to_strn(&home_links, ".links");
357
if (stat(home_links, &st)) {
359
if (!mkdir(home_links, 0777)) goto home_creat;
361
if (config_dir) goto failed;
364
if (S_ISDIR(st.st_mode)) goto home_ok;
365
/* This is a Cygwin hack! Cygwin reports stat for "links" if no
366
"links" exists and only "links.exe" does. So try to create directory
368
if (!mkdir(home_links, 0777)) goto home_creat;
370
mem_free(home_links);
371
home_links = stracpy(home);
372
add_to_strn(&home_links, "links");
373
if (stat(home_links, &st)) {
375
if (!mkdir(home_links, 0777)) goto home_creat;
377
mem_free(home_links);
378
home_links = stracpy(home);
383
if (S_ISDIR(st.st_mode)) goto home_ok;
384
if (!mkdir(home_links, 0777)) goto home_creat;
386
mem_free(home_links);
394
chmod(home_links, 0700);
396
add_to_strn(&home_links, "/");
404
links_home = get_home(&first_use);
406
fprintf(stderr, "Unable to find or create links config directory. Please check, that you have $HOME variable set correctly and that you have write permission to your home directory.\n\007");
412
void load_config_file(unsigned char *prefix, unsigned char *name)
414
unsigned char *c, *config_file;
415
config_file = stracpy(prefix);
416
if (!config_file) return;
417
add_to_strn(&config_file, name);
418
if ((c = read_config_file(config_file))) goto ok;
419
mem_free(config_file);
420
config_file = stracpy(prefix);
421
if (!config_file) return;
422
add_to_strn(&config_file, ".");
423
add_to_strn(&config_file, name);
424
if ((c = read_config_file(config_file))) goto ok;
425
mem_free(config_file);
428
parse_config_file(config_file, c, all_options);
430
mem_free(config_file);
433
void load_config(void)
435
#ifdef SHARED_CONFIG_DIR
436
load_config_file(SHARED_CONFIG_DIR, "links.cfg");
438
load_config_file(links_home, "links.cfg");
439
load_config_file(links_home, "html.cfg");
440
load_config_file(links_home, "user.cfg");
444
* name: name of the configuration file (typ. links.cfg)
446
int write_config_data(unsigned char *prefix, unsigned char *name, struct option *o, struct terminal *term)
449
unsigned char *c, *config_file;
450
if (!(c = create_config_string(o))) return -1;
451
config_file = stracpy(prefix);
456
add_to_strn(&config_file, name);
457
if ((err = write_to_config_file(config_file, c))) {
458
if (term) msg_box(term, NULL, TEXT(T_CONFIG_ERROR), AL_CENTER | AL_EXTD_TEXT, TEXT(T_UNABLE_TO_WRITE_TO_CONFIG_FILE), ": ", get_err_msg(-err), NULL, NULL, 1, TEXT(T_CANCEL), NULL, B_ENTER | B_ESC);
460
mem_free(config_file);
464
mem_free(config_file);
468
void write_config(struct terminal *term)
471
if (F) update_driver_param();
473
write_config_data(links_home, "links.cfg", links_options, term);
476
void write_html_config(struct terminal *term)
478
write_config_data(links_home, "html.cfg", html_options, term);
481
void add_nm(struct option *o, unsigned char **s, int *l)
483
if (*l) add_to_str(s, l, NEWLINE);
484
add_to_str(s, l, o->cfg_name);
485
add_to_str(s, l, " ");
488
void add_quoted_to_str(unsigned char **s, int *l, unsigned char *q)
490
add_chr_to_str(s, l, '"');
492
if (*q == '"' || *q == '\\') add_chr_to_str(s, l, '\\');
493
add_chr_to_str(s, l, *q);
496
add_chr_to_str(s, l, '"');
499
unsigned char *num_rd(struct option *o, unsigned char *c)
501
unsigned char *tok = get_token(&c);
504
if (!tok) return "Missing argument";
505
l = strtolx(tok, &end);
508
return "Number expected";
510
if (l < o->min || l > o->max) {
512
return "Out of range";
519
void num_wr(struct option *o, unsigned char **s, int *l)
522
add_knum_to_str(s, l, *(int *)o->ptr);
525
unsigned char *dbl_rd(struct option *o, unsigned char *c)
527
unsigned char *tok = get_token(&c);
531
if (!tok) return "Missing argument";
532
d = strtod(tok, &end);
536
return "Number expected";
538
if (100*d < o->min || 100*d > o->max) {
540
return "Out of range";
542
*(double *)o->ptr = d;
547
void dbl_wr(struct option *o, unsigned char **s, int *l)
550
snprintf(number, sizeof number, "%.4f", *(double*)o->ptr);
553
add_to_str(s, l, number);
556
unsigned char *str_rd(struct option *o, unsigned char *c)
558
unsigned char *tok = get_token(&c);
559
unsigned char *e = NULL;
560
if (!tok) return NULL;
561
if (strlen(tok) + 1 > (size_t)o->max) e = "String too long";
562
else strcpy(o->ptr, tok);
567
void str_wr(struct option *o, unsigned char **s, int *l)
570
if (strlen(o->ptr) + 1 > (size_t)o->max) {
571
unsigned char *s1 = init_str();
573
add_bytes_to_str(&s1, &l1, o->ptr, o->max - 1);
574
add_quoted_to_str(s, l, s1);
577
else add_quoted_to_str(s, l, o->ptr);
580
unsigned char *cp_rd(struct option *o, unsigned char *c)
582
unsigned char *tok = get_token(&c);
583
unsigned char *e = NULL;
585
if (!tok) return "Missing argument";
586
if ((i = get_cp_index(tok)) == -1) e = "Unknown codepage";
587
else if (o->min == 1 && is_cp_special(i)) e = "UTF-8 can't be here";
588
else *(int *)o->ptr = i;
593
void cp_wr(struct option *o, unsigned char **s, int *l)
595
unsigned char *n = get_cp_mime_name(*(int *)o->ptr);
600
unsigned char *lang_rd(struct option *o, unsigned char *c)
603
unsigned char *tok = get_token(&c);
604
if (!tok) return "Missing argument";
605
for (i = 0; i < n_languages(); i++)
606
if (!(strcasecmp(language_name(i), tok))) {
612
return "Unknown language";
615
void lang_wr(struct option *o, unsigned char **s, int *l)
618
add_quoted_to_str(s, l, language_name(current_language));
621
int getnum(unsigned char *s, int *n, int r1, int r2)
624
long l = strtol(s, (char **)(void *)&e, 10);
625
if (*e || !*s) return -1;
626
if (l < r1 || l >= r2) return -1;
631
unsigned char *type_rd(struct option *o, unsigned char *c)
633
unsigned char *err = "Error reading association specification";
637
memset(&new, 0, sizeof(struct assoc));
638
if (!(new.label = get_token(&c))) goto err;
639
if (!(new.ct = get_token(&c))) goto err;
640
if (!(new.prog = get_token(&c))) goto err;
641
if (!(w = get_token(&c))) goto err;
642
if (getnum(w, &n, 0, 128)) goto err_f;
644
new.cons = !!(n & 1);
645
new.xwin = !!(n & 2);
647
if ((n & 8) || (n & 16)) new.block = !!(n & 16);
648
else new.block = !new.xwin || new.cons;
649
new.accept_http = !!(n & 32);
650
new.accept_ftp = !!(n & 64);
651
if (!(w = get_token(&c))) goto err;
652
if (strlen(w) != 1 || w[0] < '0' || w[0] > '9') goto err_f;
653
new.system = w[0] - '0';
658
if (new.label) mem_free(new.label);
659
if (new.ct) mem_free(new.ct);
660
if (new.prog) mem_free(new.prog);
667
unsigned char *block_rd(struct option *o, unsigned char *c)
669
unsigned char *err = "Error reading image block specification";
672
if(!(url = get_token(&c)))
675
block_add_URL_fn(NULL, url);
682
void block_wr(struct option *o, unsigned char **s, int *l)
685
foreachback(a, blocks) {
687
add_quoted_to_str(s, l, a->url);
691
void type_wr(struct option *o, unsigned char **s, int *l)
694
foreachback(a, assoc) {
696
add_quoted_to_str(s, l, a->label);
697
add_to_str(s, l, " ");
698
add_quoted_to_str(s, l, a->ct);
699
add_to_str(s, l, " ");
700
add_quoted_to_str(s, l, a->prog);
701
add_to_str(s, l, " ");
702
add_num_to_str(s, l, (!!a->cons) + (!!a->xwin) * 2 + (!!a->ask) * 4 + (!a->block) * 8 + (!!a->block) * 16 + (!!a->accept_http) * 32 + (!!a->accept_ftp) * 64);
703
add_to_str(s, l, " ");
704
add_num_to_str(s, l, a->system);
708
unsigned char *ext_rd(struct option *o, unsigned char *c)
710
unsigned char *err = "Error reading extension specification";
711
struct extension new;
712
memset(&new, 0, sizeof(struct extension));
713
if (!(new.ext = get_token(&c))) goto err;
714
if (!(new.ct = get_token(&c))) goto err;
718
if (new.ext) mem_free(new.ext);
719
if (new.ct) mem_free(new.ct);
723
void ext_wr(struct option *o, unsigned char **s, int *l)
726
foreachback(a, extensions) {
728
add_quoted_to_str(s, l, a->ext);
729
add_to_str(s, l, " ");
730
add_quoted_to_str(s, l, a->ct);
734
unsigned char *prog_rd(struct option *o, unsigned char *c)
736
unsigned char *err = "Error reading program specification";
737
unsigned char *prog, *w;
738
if (!(prog = get_token(&c))) goto err_1;
739
if (!(w = get_token(&c))) goto err_2;
740
if (strlen(w) != 1 || w[0] < '0' || w[0] > '9') goto err_3;
741
update_prog(o->ptr, prog, w[0] - '0');
751
void prog_wr(struct option *o, unsigned char **s, int *l)
753
struct protocol_program *a;
754
foreachback(a, *(struct list_head *)o->ptr) {
755
if (!*a->prog) continue;
757
add_quoted_to_str(s, l, a->prog);
758
add_to_str(s, l, " ");
759
add_num_to_str(s, l, a->system);
763
unsigned char *term_rd(struct option *o, unsigned char *c)
765
struct term_spec *ts;
768
if (!(w = get_token(&c))) goto err;
769
if (!(ts = new_term_spec(w))) {
774
if (!(w = get_token(&c))) goto err;
775
if (strlen(w) != 1 || w[0] < '0' || w[0] > '4') goto err_f;
776
ts->mode = w[0] - '0';
778
if (!(w = get_token(&c))) goto err;
779
if (strlen(w) != 1 || w[0] < '0' || w[0] > '3') goto err_f;
780
ts->m11_hack = (w[0] - '0') & 1;
781
ts->braille = !!((w[0] - '0') & 2);
783
if (!(w = get_token(&c))) goto err;
784
if (strlen(w) != 1 || w[0] < '0' || w[0] > '7') goto err_f;
785
ts->col = (w[0] - '0') & 1;
786
ts->restrict_852 = !!((w[0] - '0') & 2);
787
ts->block_cursor = !!((w[0] - '0') & 4);
789
if (!(w = get_token(&c))) goto err;
790
if ((i = get_cp_index(w)) == -1) goto err_f;
792
if ((is_cp_special(i))) {
803
return "Error reading terminal specification";
806
unsigned char *term2_rd(struct option *o, unsigned char *c)
808
struct term_spec *ts;
811
if (!(w = get_token(&c))) goto err;
812
if (!(ts = new_term_spec(w))) {
817
if (!(w = get_token(&c))) goto err;
818
if (strlen(w) != 1 || w[0] < '0' || w[0] > '3') goto err_f;
819
ts->mode = w[0] - '0';
821
if (!(w = get_token(&c))) goto err;
822
if (strlen(w) != 1 || w[0] < '0' || w[0] > '1') goto err_f;
823
ts->m11_hack = w[0] - '0';
825
if (!(w = get_token(&c))) goto err;
826
if (strlen(w) != 1 || w[0] < '0' || w[0] > '1') goto err_f;
827
ts->restrict_852 = w[0] - '0';
829
if (!(w = get_token(&c))) goto err;
830
if (strlen(w) != 1 || w[0] < '0' || w[0] > '1') goto err_f;
831
ts->col = w[0] - '0';
833
if (!(w = get_token(&c))) goto err;
834
if ((i = get_cp_index(w)) == -1) goto err_f;
836
if ((is_cp_special(i))) {
847
return "Error reading terminal specification";
850
void term_wr(struct option *o, unsigned char **s, int *l)
852
struct term_spec *ts;
853
foreachback(ts, term_specs) {
855
add_quoted_to_str(s, l, ts->term);
856
add_to_str(s, l, " ");
857
add_num_to_str(s, l, ts->mode);
858
add_to_str(s, l, " ");
859
add_num_to_str(s, l, !!ts->m11_hack + !!ts->braille * 2);
860
add_to_str(s, l, " ");
861
add_num_to_str(s, l, !!ts->col + !!ts->restrict_852 * 2 + !!ts->block_cursor * 4);
862
add_to_str(s, l, " ");
863
add_to_str(s, l, get_cp_mime_name(ts->charset));
867
struct list_head driver_params = { &driver_params, &driver_params };
869
struct driver_param *get_driver_param(unsigned char *n)
871
struct driver_param *dp;
872
foreach(dp, driver_params) if (!strcasecmp(dp->name, n)) return dp;
873
dp = mem_calloc(sizeof(struct driver_param) + strlen(n) + 1);
874
dp->codepage = get_cp_index("iso-8859-1");
876
dp->shell = mem_calloc(1);
878
add_to_list(driver_params, dp);
882
unsigned char *dp_rd(struct option *o, unsigned char *c)
885
unsigned char *n, *param, *cp, *shell;
886
struct driver_param *dp;
887
if (!(n = get_token(&c))) goto err;
888
if (!(param = get_token(&c))) {
892
if (!(shell = get_token(&c))){
897
if (!(cp = get_token(&c))) {
903
if ((cc=get_cp_index(cp)) == -1) {
910
dp=get_driver_param(n);
912
if (dp->param) mem_free(dp->param);
914
if (dp->shell) mem_free(dp->shell);
921
return "Error reading driver mode specification";
924
void dp_wr(struct option *o, unsigned char **s, int *l)
926
struct driver_param *dp;
927
foreachback(dp, driver_params) {
928
if ((!dp->param || !*dp->param) && !dp->codepage && !*dp->shell) continue;
929
if (dp->nosave) continue;
931
add_quoted_to_str(s, l, dp->name);
932
add_to_str(s, l, " ");
933
add_quoted_to_str(s, l, dp->param ? dp->param : (unsigned char*)"");
934
add_to_str(s, l, " ");
935
add_quoted_to_str(s, l, dp->shell);
936
add_to_str(s, l, " ");
937
add_to_str(s, l, get_cp_mime_name(dp->codepage));
941
unsigned char *gen_cmd(struct option *o, unsigned char ***argv, int *argc)
946
if (!*argc) return "Parameter expected";
949
add_quoted_to_str(&e, &l, **argv);
953
(*argv)++; (*argc)--;
957
unsigned char *lookup_cmd(struct option *o, unsigned char ***argv, int *argc)
960
unsigned char *p = (unsigned char *)&addr;
961
if (!*argc) return "Parameter expected";
962
if (*argc >= 2) return "Too many parameters";
963
(*argv)++; (*argc)--;
964
if (do_real_lookup(*(*argv - 1), &addr)) {
968
fprintf(stderr, "error: host not found\n");
972
printf("%d.%d.%d.%d\n", (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
977
unsigned char *version_cmd(struct option *o, unsigned char ***argv, int *argc)
979
printf("Links " VERSION_STRING "\n");
984
unsigned char *set_cmd(struct option *o, unsigned char ***argv, int *argc)
990
unsigned char *unset_cmd(struct option *o, unsigned char ***argv, int *argc)
996
unsigned char *setstr_cmd(struct option *o, unsigned char ***argv, int *argc)
998
if (!*argc) return "Parameter expected";
999
strncpy(o->ptr, **argv, o->max);
1000
((unsigned char *)o->ptr)[o->max - 1] = 0;
1001
(*argv)++; (*argc)--;
1005
unsigned char *force_html_cmd(struct option *o, unsigned char ***argv, int *argc)
1011
unsigned char *dump_cmd(struct option *o, unsigned char ***argv, int *argc)
1013
if (dmp != o->min && dmp) return "Can't use both -dump and -source";
1019
unsigned char *printhelp_cmd(struct option *o, unsigned char ***argv, int *argc)
1021
/* Changed and splited - translation is much easier.
1022
* Print to stdout instead stderr (,,links -help | more''
1023
* is much better than ,,links -help 2>&1 | more'').
1025
fprintf(stdout, "%s%s%s%s%s%s\n",
1027
("links [options] URL\n"
1031
" Run in graphics mode.\n"
1034
" Run in text mode (overrides previous -g).\n"
1036
" -driver <driver name>\n"
1037
" Graphics driver to use. Drivers are: x, svgalib, fb, directfb, pmshell,\n"
1039
" List of drivers will be shown if you give it an unknown driver.\n"
1040
" Available drivers depend on your operating system and available libraries.\n"
1042
" -mode <graphics mode>\n"
1043
" Graphics mode. For SVGALIB it is in format COLUMNSxROWSxCOLORS --\n"
1044
" for example 640x480x256, 800x600x64k, 960x720x16M, 1024x768x16M32\n"
1045
" List of modes will be shown if you give it an unknown videomode.\n"
1046
" For framebuffer it is number of pixels in border --- LEFT,TOP,RIGHT,BOTTOM\n"
1047
" other 3 values are optional --- i.e. -mode 10 will set all borders to 10,\n"
1048
" -mode 10,20 will set left & right border to 10 and top & bottom to 20.\n"
1049
" For Xwindow it is size of a window in format WIDTHxHEIGHT.\n"
1051
" -display <x-display>\n"
1052
" Set Xwindow display.\n"
1055
" Treat files with unknown type as html rather than text.\n"
1056
" (can be toggled with '\\' key)\n"
1059
" Write unformatted data stream to stdout.\n"
1062
" Write formatted document to stdout.\n"
1064
" -width <number>\n"
1065
" For dump, document will be formatted to this screen width (but it can still\n"
1066
" exceed it if lines can't be broken).\n"
1068
" -codepage <codepage>\n"
1069
" For dump, convert output to specified character set --\n"
1070
" for eaxmple iso-8859-2, windows-1250.\n"
1073
" Restrict links so that it can run on an anonymous account.\n"
1074
" No local file browsing. No downloads. Executing viewers\n"
1075
" is allowed, but user can't add or modify entries in\n"
1076
" association table.\n"
1079
" Runs links as a separate instance - instead of connecting to\n"
1080
" existing instance.\n"
1082
" -download-utime <0>/<1>\n"
1083
" Set time of downloaded files to last modification time reported by server.\n"
1085
" -async-dns <0>/<1>\n"
1086
" Asynchronous DNS resolver on(1)/off(0).\n"
1088
" -max-connections <max>\n"
1089
" Maximum number of concurrent connections.\n"
1092
(" -max-connections-to-host <max>\n"
1093
" Maximum number of concurrent connection to a given host.\n"
1096
" -retries <retry>\n"
1097
" Number of retries.\n"
1100
" -receive-timeout <sec>\n"
1101
" Timeout on receive.\n"
1104
(" -unrestartable-receive-timeout <sec>\n"
1105
" Timeout on non restartable connections.\n"
1108
" -format-cache-size <num>\n"
1109
" Number of formatted document pages cached.\n"
1112
" -memory-cache-size <bytes>\n"
1113
" Cache memory in bytes.\n"
1114
" (default: 1048576)\n"
1116
" -image-cache-size <bytes>\n"
1117
" Cache memory in bytes.\n"
1118
" (default: 1048576)\n"
1120
(" -http-proxy <host:port>\n"
1121
" Host and port number of the HTTP proxy, or blank.\n"
1122
" (default: blank)\n"
1124
" -ftp-proxy <host:port>\n"
1125
" Host and port number of the FTP proxy, or blank.\n"
1126
" (default: blank)\n"
1128
" -socks-proxy <user@host:port>\n"
1129
" Userid, host and port of Socks4a, or blank.\n"
1130
" (default: blank)\n"
1132
" -append-text-to-dns-lookups <text>\n"
1133
" Append text to dns lookups. It is useful for specifying fixed\n"
1135
" (default: blank)\n"
1137
" -only-proxies <0>/<1>\n"
1139
" \"1\" causes that Links won't initiate any non-proxy connection.\n"
1140
" It is useful for anonymization with tor or similar networks.\n"
1142
" -download-dir <path>\n"
1143
" Default download directory.\n"
1144
" (default: actual dir)\n"
1146
" -aggressive-cache <0>/<1>\n"
1148
" Always cache everything regardless of server's caching recomendations.\n"
1149
" Many servers deny caching even if their content is not changing\n"
1150
" just to get more hits and more money from ads.\n"
1152
(" -language <language>\n"
1153
" Set user interface language.\n"
1155
" -http-bugs.http10 <0>/<1>\n"
1157
" \"1\" forces using only HTTP/1.0 protocol. (useful for buggy servers\n"
1158
" that claim to be HTTP/1.1 compliant but are not)\n"
1159
" \"0\" use both HTTP/1.0 and HTTP/1.1.\n"
1161
" -http-bugs.allow-blacklist <0>/<1>\n"
1163
" \"1\" defaults to using list of servers that have broken HTTP/1.1 support.\n"
1164
" When links finds such server, it will retry the request with HTTP/1.0.\n"
1166
" -http-bugs.bug-302-redirect <0>/<1>\n"
1168
" Process 302 redirect in a way that is incompatible with RFC1945 and RFC2068,\n"
1169
" but the same as Netscape and MSIE. Many pages depend on it.\n"
1171
" -http-bugs.bug-post-no-keepalive <0>/<1>\n"
1173
" No keepalive connection after post requests. For some buggy servers.\n"
1175
" -http-bugs.bug-no-accept-charset <0>/<1>\n"
1177
" Do not send Accept-Charset field of HTTP header. Because it is too long\n"
1178
" some servers will deny the request. Other servers will convert content\n"
1179
" to plain ascii when Accept-Charset is missing.\n"
1181
" -http-bugs.no-compression <0>/<1>\n"
1183
" \"1\" causes that links won't advertise HTTP compression support (but it\n"
1184
" will still accept compressed data). Use it when you communicate with\n"
1185
" server that has broken compression support.\n"
1187
" -http-bugs.retry-internal-errors <0>/<1>\n"
1189
" Retry on internal server errors (50x).\n"
1191
" -http.referer <0>/<1>/<2>/<3>\n"
1193
" 0 - do not send referer\n"
1194
" 1 - send the requested URL as referer\n"
1195
" 2 - send fake referer\n"
1196
" 3 - send real referer\n"
1197
" 4 - send real referer only to the same server\n"
1199
" -http.fake-referer <string>\n"
1200
" Fake referer value.\n"
1202
" -http.fake-user-agent <string>\n"
1203
" Fake user agent value.\n"
1205
" -http.extra-header <string>\n"
1206
" Extra string added to HTTP header.\n"
1208
" -ftp.anonymous-password <string>\n"
1209
" Password for anonymous ftp access.\n"
1211
" -ftp.use-passive <0>/<1>\n"
1212
" Use ftp PASV command to bypass firewalls.\n"
1214
" -ftp.fast <0>/<1>\n"
1215
" Send more ftp commands simultaneously. Faster response when\n"
1216
" browsing ftp directories, but it is incompatible with RFC\n"
1217
" and some servers don't like it.\n"
1219
" -ftp.set-iptos <0>/<1>\n"
1220
" Set IP Type-of-service to high throughput on ftp connections.\n"
1222
" -menu-font-size <size>\n"
1223
" Size of font in menu.\n"
1225
" -background-color 0xRRGGBB\n"
1226
" Set menu background color in graphics mode, RRGGBB are hex.\n"
1228
" -foreground-color 0xRRGGBB\n"
1229
" Set menu foreground color in graphics mode.\n"
1231
" -scroll-bar-area-color 0xRRGGBB\n"
1232
" Set color of scroll bar area.\n"
1234
" -scroll-bar-bar-color 0xRRGGBB\n"
1235
" Set color of scroll bar.\n"
1237
" -scroll-bar-frame-color 0xRRGGBB\n"
1238
" Set color of scroll bar frame.\n"
1240
" -display-red-gamma <fp-value>\n"
1241
" Red gamma of display.\n"
1244
" -display-green-gamma <fp-value>\n"
1245
" Green gamma of display.\n"
1248
" -display-blue-gamma <fp-value>\n"
1249
" Blue gamma of display.\n"
1252
" -user-gamma <fp-value>\n"
1253
" Additional gamma.\n"
1256
" -bfu-aspect <fp-value>\n"
1257
" Display aspect ration.\n"
1259
" -aspect-on <0>/<1>\n"
1260
" Enable aspect ratio correction.\n"
1262
" -dither-letters <0>/<1>\n"
1263
" Do letter dithering.\n"
1265
" -dither-images <0>/<1>\n"
1266
" Do image dithering.\n"
1268
" -display-optimize <0>/<1>/<2>\n"
1269
" Optimize for CRT (0), LCD RGB (1), LCD BGR (2).\n"
1271
" -gamma correction <0>/<1>/<2>\n"
1272
" Type of gamma correction:\n"
1274
" 0 - 8-bit (fast).\n"
1275
" 1 - 16-bit (slow).\n"
1276
" 2 - automatically detect according to speed of FPU.\n"
1279
" -enable-javascript <0>/<1>\n"
1280
" Enable javascript.\n"
1282
" -js.verbose-errors <0>/<1>\n"
1283
" Display javascript errors.\n"
1285
" -js.verbose-warnings <0>/<1>\n"
1286
" Display javascript warnings.\n"
1288
" -js.enable-all-conversions <0>/<1>\n"
1289
" Enable conversions between all types in javascript.\n"
1291
" -js.enable-global-resolution <0>/<1>\n"
1292
" Resolve global names.\n"
1294
" -js.manual-confirmation <0>/<1>\n"
1295
" Ask user to confirm potentially dangerous operations.\n"
1296
" (opening windows, going to url etc.) Default 1.\n"
1298
" -js.recursion-depth <integer>\n"
1299
" Depth of javascript call stack.\n"
1301
" -js.memory-limit <memory amount>\n"
1302
" Amount of kilobytes the javascript may allocate.\n"
1305
" -bookmarks-codepage <codepage>\n"
1306
" Character set of bookmarks file.\n"
1308
" -bookmarks-file <file>\n"
1309
" File to store bookmarks.\n"
1311
" -html-assume-codepage <codepage>\n"
1312
" If server didn't specify document character set, assume this.\n"
1314
" -html-hard-assume <0>/<1>\n"
1315
" Use always character set from \"-html-assume-codepage\" no matter\n"
1316
" what server sent.\n"
1318
" -html-tables <0>/<1>\n"
1319
" Render tables. (0) causes tables being rendered like in lynx.\n"
1321
" -html-frames <0>/<1>\n"
1322
" Render frames. (0) causes frames rendered like in lynx.\n"
1324
" -html-images <0>/<1>\n"
1325
" Display links to unnamed images as [IMG].\n"
1327
" -html-image-names <0>/<1>\n"
1328
" Display filename of an image instead of [IMG].\n"
1330
" -html-display-images <0>/<1>\n"
1331
" Display images in graphics mode.\n"
1333
" -html-image-scale <percent>\n"
1334
" Scale images in graphics mode.\n"
1336
" -html-bare-image-autoscale <0>/<1>\n"
1337
" Autoscale images displayed on full screen.\n"
1339
" -html-numbered-links <0>/<1>\n"
1340
" Number links in text mode. Allow quick link selection by typing\n"
1341
" link number and enter.\n"
1343
" -html-table-order <0>/<1>\n"
1344
" In text mode, walk through table by rows (0) or columns (1).\n"
1346
" -html-auto-refresh <0>/<1>\n"
1347
" Process refresh to other page (1), or display link to that page (0).\n"
1349
" -html-target-in-new-window <0>/<1>\n"
1350
" Allow opening new windows from html.\n"
1352
" -html-margin <number of spaces>\n"
1353
" Margin in text mode.\n"
1355
" -html-user-font-size <size>\n"
1356
" Size of font on pages in graphics mode.\n"
1358
" -lookup <hostname>\n"
1359
" Does name lookup, like command \"host\".\n"
1362
" Prints the links version number and exit.\n"
1365
" Prints this help screen\n"
1369
" ESC display menu\n"
1373
" [, ] scroll left, right\n"
1374
" up, down select link\n"
1375
" ->, enter follow link\n"
1378
" G go to url based on current url\n"
1379
" ^G go to url based on current link\n"
1384
" N find previous\n"
1385
" = document info\n"
1386
" \\ document source\n"
1388
" * toggle displaying of image links (text mode)\n"
1391
" q quit or close current window\n"
1392
" ^X cut to clipboard\n"
1393
" ^V paste from clipboard\n"
1394
" ^K cut line (in textarea) or text to the end (in field)\n"
1395
" ^U cut all text before cursor\n"
1396
" ^W autocomplete url\n"
1398
" switch virtual screens (svgalib and framebuffer)\n"
1400
"Keys for braille terminal:\n"
1401
" arrows move the cursor\n"
1402
" enter follow link\n"
1403
" a cursor to status line\n"
1404
" w cursor to title\n"
1406
" ^T previous link\n"
1408
" t previous word\n"
1409
" ^O next form field entry\n"
1416
void end_config(void)
1418
struct driver_param *dp;
1419
foreach(dp,driver_params)
1421
if (dp->param)mem_free(dp->param);
1422
if (dp->shell)mem_free(dp->shell);
1424
free_list(driver_params);
1425
if (links_home) mem_free(links_home);
1429
unsigned char ggr_drv[MAX_STR_LEN] = "";
1430
unsigned char ggr_mode[MAX_STR_LEN] = "";
1431
unsigned char ggr_display[MAX_STR_LEN] = "";
1435
unsigned char system_name[MAX_STR_LEN];
1437
unsigned char default_target[MAX_STR_LEN] ="";
1439
unsigned char *links_home = NULL;
1441
int created_home = 0;
1444
int base_session = 0;
1448
int async_lookup = 1;
1449
int download_utime = 0;
1450
int max_connections = 10;
1451
int max_connections_to_host = 8;
1453
int receive_timeout = 120;
1454
int unrestartable_receive_timeout = 600;
1456
int screen_width = 80;
1457
int dump_codepage = -1;
1459
int max_format_cache_entries = 5;
1460
int memory_cache_size = 1048576;
1461
int image_cache_size = 1048576;
1463
int enable_html_tables = 1;
1464
int enable_html_frames = 1;
1466
struct document_setup dds = { 0, 0, 1, 1, 0, 0, 3, 0, 0, 0, 18, 1,
1467
100, /* Image scale */
1468
0, /* Porn enable */
1471
struct rgb default_fg = { 191, 191, 191, 0 };
1472
struct rgb default_bg = { 0, 0, 0, 0 };
1473
struct rgb default_link = { 255, 255, 255, 0 };
1474
struct rgb default_vlink = { 255, 255, 0, 0 };
1476
struct rgb default_fg_g = { 0, 0, 0, 0 };
1477
struct rgb default_bg_g = { 192, 192, 192, 0 };
1478
struct rgb default_link_g = { 0, 0, 255, 0 };
1479
struct rgb default_vlink_g = { 0, 0, 128, 0 };
1481
int default_left_margin = HTML_LEFT_MARGIN;
1483
struct proxies proxies = { "", "", "", "", 0 };
1484
int js_enable=1; /* 0=disable javascript */
1485
int js_verbose_errors=0; /* 1=create dialog on every javascript error, 0=be quiet and continue */
1486
int js_verbose_warnings=0; /* 1=create dialog on every javascript warning, 0=be quiet and continue */
1487
int js_all_conversions=1;
1488
int js_global_resolve=1; /* resolvovani v globalnim adresnim prostoru, kdyz BFU vomitne document */
1489
int js_manual_confirmation=1; /* !0==annoying dialog on every goto url etc. */
1490
int js_fun_depth=100;
1491
int js_memory_limit=5*1024; /* in kilobytes, should be in range 1M-20M (1MB=1024*1024B) */
1493
int display_optimize=0; /*0=CRT, 1=LCD RGB, 2=LCD BGR */
1494
int gamma_bits=2; /*0 --- 8, 1 --- 16, 2 --- auto */
1495
double bfu_aspect=1; /* 0.1 to 10.0, 1.0 default. >1 makes circle wider */
1498
unsigned char download_dir[MAX_STR_LEN] = "";
1500
int aggressive_cache = 1;
1502
struct ftp_options ftp_options = { "somebody@host.domain", 0, 0, 1 };
1504
/* These are workarounds for some CGI script bugs */
1505
struct http_options http_options = { 0, 1, 1, 0, 0, 0, 0, { REFERER_NONE, "", "", "" } };
1506
/*int bug_302_redirect = 0;*/
1507
/* When got 301 or 302 from POST request, change it to GET
1508
- this violates RFC2068, but some buggy message board scripts rely on it */
1509
/*int bug_post_no_keepalive = 0;*/
1510
/* No keepalive connection after POST request. Some buggy PHP databases report bad
1511
results if GET wants to retreive data POSTed in the same connection */
1513
struct option links_options[] = {
1514
{1, printhelp_cmd, NULL, NULL, 0, 0, NULL, NULL, "?"},
1515
{1, printhelp_cmd, NULL, NULL, 0, 0, NULL, NULL, "h"},
1516
{1, printhelp_cmd, NULL, NULL, 0, 0, NULL, NULL, "help"},
1517
{1, printhelp_cmd, NULL, NULL, 0, 0, NULL, NULL, "-help"},
1518
{1, lookup_cmd, NULL, NULL, 0, 0, NULL, NULL, "lookup"},
1519
{1, version_cmd, NULL, NULL, 0, 0, NULL, NULL, "version"},
1520
{1, set_cmd, NULL, NULL, 0, 0, &no_connect, NULL, "no-connect"},
1521
{1, set_cmd, NULL, NULL, 0, 0, &anonymous, NULL, "anonymous"},
1522
{1, set_cmd, NULL, NULL, 0, 0, &ggr, NULL, "g"},
1523
{1, unset_cmd, NULL, NULL, 0, 0, &ggr, NULL, "no-g"},
1524
{1, setstr_cmd, NULL, NULL, 0, MAX_STR_LEN, &ggr_drv, NULL, "driver"},
1525
{1, setstr_cmd, NULL, NULL, 0, MAX_STR_LEN, &default_target, NULL, "target"},
1526
{1, setstr_cmd, NULL, NULL, 0, MAX_STR_LEN, &ggr_mode, NULL, "mode"},
1527
{1, setstr_cmd, NULL, NULL, 0, MAX_STR_LEN, &ggr_display, NULL, "display"},
1528
{1, gen_cmd, num_rd, NULL, 0, MAXINT, &base_session, NULL, "base-session"},
1529
{1, force_html_cmd, NULL, NULL, 0, 0, NULL, NULL, "force-html"},
1530
{1, dump_cmd, NULL, NULL, D_SOURCE, 0, NULL, NULL, "source"},
1531
{1, dump_cmd, NULL, NULL, D_DUMP, 0, NULL, NULL, "dump"},
1532
{1, gen_cmd, num_rd, NULL, 10, 512, &screen_width, "dump_width", "width" },
1533
{1, gen_cmd, cp_rd, NULL, 1, 0, &dump_codepage, "dump_codepage", "codepage" },
1534
{1, gen_cmd, num_rd, num_wr, 0, 1, &async_lookup, "async_dns", "async-dns"},
1535
{1, gen_cmd, num_rd, num_wr, 0, 1, &download_utime, "download_utime", "download-utime"},
1536
{1, gen_cmd, num_rd, num_wr, 1, 99, &max_connections, "max_connections", "max-connections"},
1537
{1, gen_cmd, num_rd, num_wr, 1, 99, &max_connections_to_host, "max_connections_to_host", "max-connections-to-host"},
1538
{1, gen_cmd, num_rd, num_wr, 0, 16, &max_tries, "retries", "retries"},
1539
{1, gen_cmd, num_rd, num_wr, 1, 9999, &receive_timeout, "receive_timeout", "receive-timeout"},
1540
{1, gen_cmd, num_rd, num_wr, 1, 9999, &unrestartable_receive_timeout, "unrestartable_receive_timeout", "unrestartable-receive-timeout"},
1541
{1, gen_cmd, num_rd, num_wr, 0, 999, &max_format_cache_entries, "format_cache_size", "format-cache-size"},
1542
{1, gen_cmd, num_rd, num_wr, 0, MAXINT, &memory_cache_size, "memory_cache_size", "memory-cache-size"},
1543
{1, gen_cmd, num_rd, num_wr, 0, MAXINT, &image_cache_size, "image_cache_size", "image-cache-size"},
1544
{1, gen_cmd, str_rd, str_wr, 0, MAX_STR_LEN, proxies.http_proxy, "http_proxy", "http-proxy"},
1545
{1, gen_cmd, str_rd, str_wr, 0, MAX_STR_LEN, proxies.ftp_proxy, "ftp_proxy", "ftp-proxy"},
1546
{1, gen_cmd, str_rd, str_wr, 0, MAX_STR_LEN, proxies.socks_proxy, "socks_proxy", "socks-proxy"},
1547
{1, gen_cmd, str_rd, str_wr, 0, MAX_STR_LEN, proxies.dns_append, "-append_text_to_dns_lookups", "append-text-to-dns-lookups"},
1548
{1, gen_cmd, num_rd, num_wr, 0, 1, &proxies.only_proxies, "only_proxies", "only-proxies"},
1549
{1, gen_cmd, str_rd, str_wr, 0, MAX_STR_LEN, download_dir, "download_dir", "download-dir"},
1550
{1, gen_cmd, lang_rd, lang_wr, 0, 0, ¤t_language, "language", "language"},
1551
{1, gen_cmd, num_rd, num_wr, 0, 1, &http_options.http10, "http_bugs.http10", "http-bugs.http10"},
1552
{1, gen_cmd, num_rd, num_wr, 0, 1, &http_options.allow_blacklist, "http_bugs.allow_blacklist", "http-bugs.allow-blacklist"},
1553
{1, gen_cmd, num_rd, num_wr, 0, 1, &http_options.bug_302_redirect, "http_bugs.bug_302_redirect", "http-bugs.bug-302-redirect"},
1554
{1, gen_cmd, num_rd, num_wr, 0, 1, &http_options.bug_post_no_keepalive, "http_bugs.bug_post_no_keepalive", "http-bugs.bug-post-no-keepalive"},
1555
{1, gen_cmd, num_rd, num_wr, 0, 1, &http_options.no_accept_charset, "http_bugs.no_accept_charset", "http-bugs.bug-no-accept-charset"},
1556
{1, gen_cmd, num_rd, num_wr, 0, 1, &http_options.no_compression, "http_bugs.no_compression", "http-bugs.no-compression"},
1557
{1, gen_cmd, num_rd, num_wr, 0, 1, &http_options.retry_internal_errors, "http_bugs.retry_internal_errors", "http-bugs.retry-internal-errors"},
1558
{1, gen_cmd, num_rd, num_wr, 0, 1, &aggressive_cache, "http_bugs.aggressive_cache", "aggressive-cache"},
1559
{1, gen_cmd, num_rd, num_wr, 0, 4, &http_options.header.referer, "http_referer", "http.referer"},
1560
{1, gen_cmd, str_rd, str_wr, 0, MAX_STR_LEN, http_options.header.fake_referer, "fake_referer", "http.fake-referer"},
1561
{1, gen_cmd, str_rd, str_wr, 0, MAX_STR_LEN, http_options.header.fake_useragent, "fake_useragent", "http.fake-user-agent"},
1562
{1, gen_cmd, str_rd, str_wr, 0, MAX_STR_LEN, http_options.header.extra_header, "http.extra_header", "http.extra-header"},
1563
{1, gen_cmd, str_rd, str_wr, 0, MAX_STR_LEN, ftp_options.anon_pass, "ftp.anonymous_password", "ftp.anonymous-password"},
1564
{1, gen_cmd, num_rd, num_wr, 0, 1, &ftp_options.passive_ftp, "ftp.use_passive", "ftp.use-passive"},
1565
{1, gen_cmd, num_rd, num_wr, 0, 1, &ftp_options.fast_ftp, "ftp.fast", "ftp.fast"},
1566
{1, gen_cmd, num_rd, num_wr, 0, 1, &ftp_options.set_tos, "ftp.set_iptos", "ftp.set-iptos"},
1567
{1, gen_cmd, num_rd, num_wr, 1, MAX_FONT_SIZE, &menu_font_size, "menu_font_size", "menu-font-size"},
1568
{1, gen_cmd, num_rd, num_wr, 0, 0xffffff, &G_BFU_BG_COLOR, "background_color", "background-color"},
1569
{1, gen_cmd, num_rd, num_wr, 0, 0xffffff, &G_BFU_FG_COLOR, "foreground_color", "foreground-color"},
1570
{1, gen_cmd, num_rd, num_wr, 0, 0xffffff, &G_SCROLL_BAR_AREA_COLOR, "scroll_bar_area_color", "scroll-bar-area-color"},
1571
{1, gen_cmd, num_rd, num_wr, 0, 0xffffff, &G_SCROLL_BAR_BAR_COLOR, "scroll_bar_bar_color", "scroll-bar-bar-color"},
1572
{1, gen_cmd, num_rd, num_wr, 0, 0xffffff, &G_SCROLL_BAR_FRAME_COLOR, "scroll_bar_frame_color", "scroll-bar-frame-color"},
1573
{1, gen_cmd, dbl_rd, dbl_wr, 1, 10000, &display_red_gamma, "display_red_gamma", "display-red-gamma"},
1574
{1, gen_cmd, dbl_rd, dbl_wr, 1, 10000, &display_green_gamma, "display_green_gamma", "display-green-gamma"},
1575
{1, gen_cmd, dbl_rd, dbl_wr, 1, 10000, &display_blue_gamma, "display_blue_gamma", "display-blue-gamma"},
1576
{1, gen_cmd, dbl_rd, dbl_wr, 1, 10000, &user_gamma, "user_gamma", "user-gamma"},
1577
{1, gen_cmd, dbl_rd, dbl_wr, 25, 400, &bfu_aspect, "bfu_aspect", "bfu-aspect"},
1578
{1, gen_cmd, num_rd, num_wr, 0, 1, &aspect_on, "aspect_on", "aspect-on"},
1579
{1, gen_cmd, num_rd, num_wr, 0, 1, &dither_letters, "dither_letters", "dither-letters"},
1580
{1, gen_cmd, num_rd, num_wr, 0, 1, &dither_images, "dither_images", "dither-images"},
1581
{1, gen_cmd, num_rd, num_wr, 0, 2, &display_optimize, "display_optimize", "display-optimize"},
1582
{1, gen_cmd, num_rd, num_wr, 0, 2, &gamma_bits, "gamma_correction", "gamma-correction"},
1583
{1, gen_cmd, num_rd, num_wr, 0, 1, &js_enable, "enable_javascript", "enable-javascript"},
1584
{1, gen_cmd, num_rd, num_wr, 0, 1, &js_verbose_errors, "verbose_javascript_errors", "js.verbose-errors"},
1585
{1, gen_cmd, num_rd, num_wr, 0, 1, &js_verbose_warnings, "verbose_javascript_warnings", "js.verbose-warnings"},
1586
{1, gen_cmd, num_rd, num_wr, 0, 1, &js_all_conversions, "enable_all_conversions", "js.enable-all-conversions"},
1587
{1, gen_cmd, num_rd, num_wr, 0, 1, &js_global_resolve, "enable_global_resolution", "js.enable-global-resolution"},
1588
{1, gen_cmd, num_rd, num_wr, 0, 1, &js_manual_confirmation, "javascript_manual_confirmation", "js.manual-confirmation"},
1589
{1, gen_cmd, num_rd, num_wr, 0, 999999, &js_fun_depth, "js_recursion_depth", "js.recursion-depth"},
1590
{1, gen_cmd, num_rd, num_wr, 1024, 30*1024, &js_memory_limit, "js_memory_limit", "js.memory-limit"},
1591
{1, gen_cmd, cp_rd, cp_wr, 0, 0, &bookmarks_codepage, "bookmarks_codepage", "bookmarks-codepage"},
1592
{1, gen_cmd, str_rd, str_wr, 0, MAX_STR_LEN, bookmarks_file, "bookmarks_file", "bookmarks-file"},
1593
{1, gen_cmd, cp_rd, NULL, 0, 0, &dds.assume_cp, "assume_codepage", "assume-codepage"},
1594
{1, NULL, term_rd, term_wr, 0, 0, NULL, "terminal", NULL},
1595
{1, NULL, term2_rd, NULL, 0, 0, NULL, "terminal2", NULL},
1596
{1, NULL, type_rd, type_wr, 0, 0, NULL, "association", NULL},
1597
{1, NULL, ext_rd, ext_wr, 0, 0, NULL, "extension", NULL},
1598
{1, NULL, prog_rd, prog_wr, 0, 0, &mailto_prog, "mailto", NULL},
1599
{1, NULL, prog_rd, prog_wr, 0, 0, &telnet_prog, "telnet", NULL},
1600
{1, NULL, prog_rd, prog_wr, 0, 0, &tn3270_prog, "tn3270", NULL},
1601
{1, NULL, prog_rd, prog_wr, 0, 0, &mms_prog, "mms", NULL},
1602
{1, NULL, prog_rd, prog_wr, 0, 0, &magnet_prog, "magnet", NULL},
1603
{1, NULL, block_rd, block_wr, 0, 0, NULL, "imageblock", NULL},
1604
{1, NULL, dp_rd, dp_wr, 0, 0, NULL, "video_driver", NULL},
1605
{0, NULL, NULL, NULL, 0, 0, NULL, NULL, NULL},
1608
struct option html_options[] = {
1609
{1, gen_cmd, num_rd, num_wr, 0, 1, &dds.hard_assume, "html_hard_assume", "html-hard-assume"},
1610
{1, gen_cmd, cp_rd, cp_wr, 0, 0, &dds.assume_cp, "html_assume_codepage", "html-assume-codepage"},
1611
{1, gen_cmd, num_rd, num_wr, 0, 1, &dds.tables, "html_tables", "html-tables"},
1612
{1, gen_cmd, num_rd, num_wr, 0, 1, &dds.frames, "html_frames", "html-frames"},
1613
{1, gen_cmd, num_rd, num_wr, 0, 1, &dds.images, "html_images", "html-images"},
1614
{1, gen_cmd, num_rd, num_wr, 0, 1, &dds.image_names, "html_image_names", "html-image-names"},
1615
{1, gen_cmd, num_rd, num_wr, 0, 1, &dds.display_images, "html_display_images", "html-display-images"},
1616
{1, gen_cmd, num_rd, num_wr, 1, 500, &dds.image_scale, "html_image_scale", "html-image-scale"},
1617
{1, gen_cmd, num_rd, num_wr, 0, 1, &dds.porn_enable, "html_bare_image_autoscale", "html-bare-image-autoscale"},
1618
{1, gen_cmd, num_rd, num_wr, 0, 1, &dds.num_links, "html_numbered_links", "html-numbered-links"},
1619
{1, gen_cmd, num_rd, num_wr, 0, 1, &dds.table_order, "html_table_order", "html-table-order"},
1620
{1, gen_cmd, num_rd, num_wr, 0, 1, &dds.auto_refresh, "html_auto_refresh", "html-auto-refresh"},
1621
{1, gen_cmd, num_rd, num_wr, 0, 1, &dds.target_in_new_window, "html_target_in_new_window", "html-target-in-new-window"},
1622
{1, gen_cmd, num_rd, num_wr, 0, 9, &dds.margin, "html_margin", "html-margin"},
1623
{1, gen_cmd, num_rd, num_wr, 1, MAX_FONT_SIZE, &dds.font_size, "html_font_size", "html-user-font-size"},
1624
{0, NULL, NULL, NULL, 0, 0, NULL, NULL, NULL},
1627
void load_url_history(void)
1629
unsigned char *history_file, *hs;
1632
if (anonymous) return;
1633
/* Must have been called after init_home */
1634
if (!links_home) return;
1635
history_file = stracpy(links_home);
1636
add_to_strn(&history_file, "links.his");
1637
hs = read_config_file(history_file);
1638
mem_free(history_file);
1640
for (hsp = hs; *hsp; ) {
1641
unsigned char *hsl, *hsc;
1642
for (hsl = hsp; *hsl && *hsl != 10 && *hsl != 13; hsl++) ;
1643
hsc = memacpy(hsp, hsl - hsp);
1644
add_to_history(&goto_url_history, hsc);
1647
while (*hsp == 10 || *hsp == 13) hsp++;
1652
void save_url_history(void)
1654
struct history_item *hi;
1655
unsigned char *history_file;
1659
if (anonymous) return;
1661
/* Must have been called after init_home */
1662
if (!links_home) return;
1663
history_file = stracpy(links_home);
1664
add_to_strn(&history_file, "links.his");
1667
foreachback(hi, goto_url_history.items) {
1668
if (!*hi->d || strchr(hi->d, 10) || strchr(hi->d, 13)) continue;
1669
if (i++ > MAX_HISTORY_ITEMS)
1672
add_to_str(&hs, &hsl, hi->d);
1673
add_to_str(&hs, &hsl, NEWLINE);
1676
write_to_config_file(history_file, hs);
1677
mem_free(history_file);