~ubuntu-branches/ubuntu/saucy/links2/saucy-proposed

« back to all changes in this revision

Viewing changes to .pc/links2-instead-of-links.diff/default.c

  • Committer: Bazaar Package Importer
  • Author(s): Axel Beckert
  • Date: 2011-08-18 23:35:41 UTC
  • mfrom: (3.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110818233541-3x10px37rwkortla
Tags: 2.3-1
* New upstream release.
  + Refreshed patches links2-instead-of-links.diff and ipv6.diff
  + Fixes downloads of files larger than 4GB (Closes: #610418)
* Fix debian/watch so that upstream versions are sorted properly; add
  and prefer bzip2 compressed upstream tarballs.
* Add missing bug number for IPv6 patch in the previous changelog entry.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* default.c
 
2
 * (c) 2002 Mikulas Patocka, Petr 'Brain' Kulhavy
 
3
 * This file is a part of the Links program, released under GPL
 
4
 *
 
5
 * Does the configuration file.
 
6
 */
 
7
 
 
8
#include "links.h"
 
9
 
 
10
static void get_system_name(void)
 
11
{
 
12
        FILE *f;
 
13
        unsigned char *p;
 
14
#if defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME)
 
15
        struct utsname name;
 
16
        memset(&name, 0, sizeof name);
 
17
        if (!uname(&name)) {
 
18
                unsigned char *str = init_str();
 
19
                int l = 0;
 
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);
 
27
                mem_free(str);
 
28
                return;
 
29
        }
 
30
#endif
 
31
#ifdef HAVE_POPEN
 
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) {
 
35
                pclose(f);
 
36
                goto fail;
 
37
        }
 
38
        pclose(f);
 
39
        for (p = system_name; *p; p++) if (*p < ' ') {
 
40
                *p = 0;
 
41
                break;
 
42
        }
 
43
        if (system_name[0]) return;
 
44
        fail:
 
45
#endif
 
46
        strcpy(system_name, SYSTEM_NAME);
 
47
}
 
48
 
 
49
struct option {
 
50
        int p;
 
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) */
 
55
        void *ptr;
 
56
        unsigned char *cfg_name;
 
57
        unsigned char *cmd_name;
 
58
};
 
59
 
 
60
extern struct option links_options[];
 
61
extern struct option html_options[];
 
62
 
 
63
struct option *all_options[] = { links_options, html_options, NULL, };
 
64
 
 
65
 
 
66
/* prototypes */
 
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 *);
 
109
 
 
110
unsigned char *p_arse_options(int argc, unsigned char *argv[], struct option **opt)
 
111
{
 
112
        unsigned char *e, *u = NULL;
 
113
        while (argc) {
 
114
                int i;
 
115
                argv++, argc--;
 
116
                if (argv[-1][0] == '-') {
 
117
                        struct option *options;
 
118
                        struct option **op;
 
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);
 
124
                                                return NULL;
 
125
                                        }
 
126
                                        goto found;
 
127
                                }
 
128
                        uu:
 
129
#ifdef GRDRV_DIRECTFB
 
130
                        if (!strncmp(argv[-1], "--dfb:", 6))
 
131
                                goto found;
 
132
#endif
 
133
                        fprintf(stderr, "Unknown option %s\n", argv[-1]);
 
134
                        return NULL;
 
135
                } else if (!u) u = argv[-1];
 
136
                else goto uu;
 
137
                found:;
 
138
        }
 
139
        if (u) return u;
 
140
        return "";
 
141
}
 
142
 
 
143
unsigned char *parse_options(int argc, unsigned char *argv[])
 
144
{
 
145
        return p_arse_options(argc, argv, all_options);
 
146
}
 
147
 
 
148
unsigned char *get_token(unsigned char **line)
 
149
{
 
150
        unsigned char *s = NULL;
 
151
        int l = 0;
 
152
        int escape = 0;
 
153
        int quote = 0;
 
154
        
 
155
        while (**line == ' ' || **line == 9) (*line)++;
 
156
        if (**line) {
 
157
                for (s = init_str(); **line; (*line)++) {
 
158
                        if (escape)
 
159
                                escape = 0;
 
160
                        else if (**line == '\\') {
 
161
                                escape = 1;
 
162
                                continue;
 
163
                        }       
 
164
                        else if (**line == '"') {
 
165
                                quote = !quote;
 
166
                                continue;
 
167
                        }
 
168
                        else if ((**line == ' ' || **line == 9) && !quote)
 
169
                                break;
 
170
                        add_chr_to_str(&s, &l, **line);
 
171
                }
 
172
        }
 
173
        return s;
 
174
}
 
175
 
 
176
void parse_config_file(unsigned char *name, unsigned char *file, struct option **opt)
 
177
{
 
178
        struct option *options;
 
179
        struct option **op;
 
180
        int err = 0;
 
181
        int line = 0;
 
182
        unsigned char *e;
 
183
        int i;
 
184
        unsigned char *n, *p;
 
185
        unsigned char *tok;
 
186
        int nl, pl;
 
187
        while (file[0]) {
 
188
                line++;
 
189
                while (file[0] && (file[0] == ' ' || file[0] == 9)) file++;
 
190
                n = file;
 
191
                while (file[0] && file[0] > ' ') file++;
 
192
                if (file == n) {
 
193
                        if (file[0]) file++;
 
194
                        continue;
 
195
                }
 
196
                nl = file - n;
 
197
                while (file[0] == 9 || file[0] == ' ') file++;
 
198
                p = file;
 
199
                while (file[0] && file[0] != 10 && file[0] != 13) file++;
 
200
                pl = file - p;
 
201
                if (file[0]) {
 
202
                        if ((file[1] == 10 || file[1] == 13) && file[0] != file[1]) file++;
 
203
                        file++;
 
204
                }
 
205
                tok = NULL;
 
206
                if (n[0] == '#') goto f;
 
207
                if (!(tok = get_token(&n))) goto f;
 
208
                nl = strlen(tok);
 
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;
 
214
                                }
 
215
                                mem_free(o);
 
216
                                goto f;
 
217
                        }
 
218
                fprintf(stderr, "Unknown option in config file %s, line %d\n", name, line);
 
219
                err = 1;
 
220
                f:
 
221
                if (tok) mem_free(tok);
 
222
        }
 
223
        if (err) fprintf(stderr, "\007"), sleep(1);
 
224
}
 
225
 
 
226
unsigned char *create_config_string(struct option *options)
 
227
{
 
228
        unsigned char *s = init_str();
 
229
        int l = 0;
 
230
        int i;
 
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);
 
235
        return s;
 
236
}
 
237
 
 
238
#define FILE_BUF        1024
 
239
 
 
240
unsigned char cfg_buffer[FILE_BUF];
 
241
 
 
242
unsigned char *read_config_file(unsigned char *name)
 
243
{
 
244
        int h, r;
 
245
        int l = 0;
 
246
        unsigned char *s;
 
247
        if ((h = open(name, O_RDONLY | O_NOCTTY)) == -1) return NULL;
 
248
        set_bin(h);
 
249
        s = init_str();
 
250
        while ((r = read(h, cfg_buffer, FILE_BUF)) > 0) {
 
251
                int i;
 
252
                for (i = 0; i < r; i++) if (!cfg_buffer[i]) cfg_buffer[i] = ' ';
 
253
                add_bytes_to_str(&s, &l, cfg_buffer, r);
 
254
        }
 
255
        if (r == -1) mem_free(s), s = NULL;
 
256
        close(h);
 
257
        return s;
 
258
}
 
259
 
 
260
int write_to_config_file(unsigned char *name, unsigned char *c)
 
261
{
 
262
        int rr;
 
263
        int r;
 
264
        int h, w;
 
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) {
 
271
                mem_free(tmp_name);
 
272
                return errno;
 
273
        }
 
274
        set_bin(h);
 
275
        rr = strlen(c);
 
276
        r = rr;
 
277
        while (r > 0) {
 
278
                if ((w = write(h, c + rr - r, r)) <= 0) {
 
279
                        int err = !w ? ENOSPC : errno;
 
280
                        close(h);
 
281
                        unlink(tmp_name);
 
282
                        mem_free(tmp_name);
 
283
                        return err;
 
284
                }
 
285
                r -= w;
 
286
        }
 
287
        close(h);
 
288
#ifndef RENAME_OVER_EXISTING_FILES
 
289
        unlink(name);
 
290
#endif
 
291
        if (rename(tmp_name, name)) {
 
292
                int err = errno;
 
293
                unlink(tmp_name);
 
294
                mem_free(tmp_name);
 
295
                return err;
 
296
        }
 
297
        mem_free(tmp_name);
 
298
        return 0;
 
299
}
 
300
 
 
301
unsigned char *get_home(int *n)
 
302
{
 
303
        struct stat st;
 
304
        unsigned char *home = NULL;
 
305
        unsigned char *home_links;
 
306
        unsigned char *config_dir = stracpy(getenv("CONFIG_DIR"));
 
307
 
 
308
        if (n) *n = 1;
 
309
#ifdef WIN32
 
310
        if (!home) {
 
311
                home = stracpy(getenv("APPDATA"));
 
312
                if (home && (stat(home, &st) == -1 || !S_ISDIR(st.st_mode))) {
 
313
                        mem_free(home);
 
314
                        home = NULL;
 
315
                }
 
316
        }
 
317
#endif
 
318
        if (!home) home = stracpy(getenv("HOME"));
 
319
        if (!home
 
320
#ifdef WIN32
 
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, "/")
 
324
#endif
 
325
                ) {
 
326
                int i;
 
327
                home = stracpy(path_to_exe);
 
328
                if (!home) {
 
329
                        if (config_dir) mem_free(config_dir);
 
330
                        return NULL;
 
331
                }
 
332
                for (i = strlen(home) - 1; i >= 0; i--) if (dir_sep(home[i])) {
 
333
                        home[i + 1] = 0;
 
334
                        goto br;
 
335
                }
 
336
                home[0] = 0;
 
337
                br:;
 
338
        }
 
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);
 
342
        if (config_dir)
 
343
        {
 
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");
 
348
                } else {
 
349
                        fprintf(stderr, "CONFIG_DIR set to %s. But directory %s doesn't exist.\n\007", config_dir, home_links);
 
350
                        sleep(3);
 
351
                        mem_free(home_links);
 
352
                        home_links = stracpy(home);
 
353
                        add_to_strn(&home_links, ".links");             
 
354
                }
 
355
                mem_free(config_dir);
 
356
        } else add_to_strn(&home_links, ".links");
 
357
        if (stat(home_links, &st)) {
 
358
#ifdef HAVE_MKDIR
 
359
                if (!mkdir(home_links, 0777)) goto home_creat;
 
360
#endif
 
361
                if (config_dir) goto failed;
 
362
                goto first_failed;
 
363
        }
 
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
 
367
           anyway. */
 
368
        if (!mkdir(home_links, 0777)) goto home_creat;
 
369
        first_failed:
 
370
        mem_free(home_links);
 
371
        home_links = stracpy(home);
 
372
        add_to_strn(&home_links, "links");
 
373
        if (stat(home_links, &st)) {
 
374
#ifdef HAVE_MKDIR
 
375
                if (!mkdir(home_links, 0777)) goto home_creat;
 
376
#else
 
377
                mem_free(home_links);
 
378
                home_links = stracpy(home);
 
379
                goto home_ok;
 
380
#endif
 
381
                goto failed;
 
382
        }
 
383
        if (S_ISDIR(st.st_mode)) goto home_ok;
 
384
        if (!mkdir(home_links, 0777)) goto home_creat;
 
385
        failed:
 
386
        mem_free(home_links);
 
387
        mem_free(home);
 
388
        return NULL;
 
389
 
 
390
        home_ok:
 
391
        if (n) *n = 0;
 
392
        home_creat:
 
393
#ifdef HAVE_CHMOD
 
394
        chmod(home_links, 0700);
 
395
#endif
 
396
        add_to_strn(&home_links, "/");
 
397
        mem_free(home);
 
398
        return home_links;
 
399
}
 
400
 
 
401
void init_home(void)
 
402
{
 
403
        get_system_name();
 
404
        links_home = get_home(&first_use);
 
405
        if (!links_home) {
 
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");
 
407
                sleep(3);
 
408
                return;
 
409
        }
 
410
}
 
411
 
 
412
void load_config_file(unsigned char *prefix, unsigned char *name)
 
413
{
 
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);
 
426
        return;
 
427
        ok:
 
428
        parse_config_file(config_file, c, all_options);
 
429
        mem_free(c);
 
430
        mem_free(config_file);
 
431
}
 
432
 
 
433
void load_config(void)
 
434
{
 
435
#ifdef SHARED_CONFIG_DIR
 
436
        load_config_file(SHARED_CONFIG_DIR, "links.cfg");
 
437
#endif
 
438
        load_config_file(links_home, "links.cfg");
 
439
        load_config_file(links_home, "html.cfg");
 
440
        load_config_file(links_home, "user.cfg");
 
441
}
 
442
 
 
443
/* prefix: directory
 
444
 * name: name of the configuration file (typ. links.cfg)
 
445
 */
 
446
int write_config_data(unsigned char *prefix, unsigned char *name, struct option *o, struct terminal *term)
 
447
{
 
448
        int err;
 
449
        unsigned char *c, *config_file;
 
450
        if (!(c = create_config_string(o))) return -1;
 
451
        config_file = stracpy(prefix);
 
452
        if (!config_file) {
 
453
                mem_free(c);
 
454
                return -1;
 
455
        }
 
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);
 
459
                mem_free(c);
 
460
                mem_free(config_file);
 
461
                return -1;
 
462
        }
 
463
        mem_free(c);
 
464
        mem_free(config_file);
 
465
        return 0;
 
466
}
 
467
 
 
468
void write_config(struct terminal *term)
 
469
{
 
470
#ifdef G
 
471
        if (F) update_driver_param();
 
472
#endif
 
473
        write_config_data(links_home, "links.cfg", links_options, term);
 
474
}
 
475
 
 
476
void write_html_config(struct terminal *term)
 
477
{
 
478
        write_config_data(links_home, "html.cfg", html_options, term);
 
479
}
 
480
 
 
481
void add_nm(struct option *o, unsigned char **s, int *l)
 
482
{
 
483
        if (*l) add_to_str(s, l, NEWLINE);
 
484
        add_to_str(s, l, o->cfg_name);
 
485
        add_to_str(s, l, " ");
 
486
}
 
487
 
 
488
void add_quoted_to_str(unsigned char **s, int *l, unsigned char *q)
 
489
{
 
490
        add_chr_to_str(s, l, '"');
 
491
        while (*q) {
 
492
                if (*q == '"' || *q == '\\') add_chr_to_str(s, l, '\\');
 
493
                add_chr_to_str(s, l, *q);
 
494
                q++;
 
495
        }
 
496
        add_chr_to_str(s, l, '"');
 
497
}
 
498
 
 
499
unsigned char *num_rd(struct option *o, unsigned char *c)
 
500
{
 
501
        unsigned char *tok = get_token(&c);
 
502
        unsigned char *end;
 
503
        long l;
 
504
        if (!tok) return "Missing argument";
 
505
        l = strtolx(tok, &end);
 
506
        if (*end) {
 
507
                mem_free(tok);
 
508
                return "Number expected";
 
509
        }
 
510
        if (l < o->min || l > o->max) {
 
511
                mem_free(tok);
 
512
                return "Out of range";
 
513
        }
 
514
        *(int *)o->ptr = l;
 
515
        mem_free(tok);
 
516
        return NULL;
 
517
}
 
518
 
 
519
void num_wr(struct option *o, unsigned char **s, int *l)
 
520
{
 
521
        add_nm(o, s, l);
 
522
        add_knum_to_str(s, l, *(int *)o->ptr);
 
523
}
 
524
 
 
525
unsigned char *dbl_rd(struct option *o, unsigned char *c)
 
526
{
 
527
        unsigned char *tok = get_token(&c);
 
528
        char *end;
 
529
        double d;
 
530
        
 
531
        if (!tok) return "Missing argument";
 
532
        d = strtod(tok, &end);
 
533
 
 
534
        if (*end) {
 
535
                mem_free(tok);
 
536
                return "Number expected";
 
537
        }
 
538
        if (100*d < o->min || 100*d > o->max) {
 
539
                mem_free(tok);
 
540
                return "Out of range";
 
541
        }
 
542
        *(double *)o->ptr = d;
 
543
        mem_free(tok);
 
544
        return NULL;
 
545
}
 
546
 
 
547
void dbl_wr(struct option *o, unsigned char **s, int *l)
 
548
{
 
549
        char number[80];
 
550
        snprintf(number, sizeof number, "%.4f", *(double*)o->ptr);
 
551
 
 
552
        add_nm(o, s, l);
 
553
        add_to_str(s, l, number);
 
554
}
 
555
 
 
556
unsigned char *str_rd(struct option *o, unsigned char *c)
 
557
{
 
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);
 
563
        mem_free(tok);
 
564
        return e;
 
565
}
 
566
 
 
567
void str_wr(struct option *o, unsigned char **s, int *l)
 
568
{
 
569
        add_nm(o, s, l);
 
570
        if (strlen(o->ptr) + 1 > (size_t)o->max) {
 
571
                unsigned char *s1 = init_str();
 
572
                int l1 = 0;
 
573
                add_bytes_to_str(&s1, &l1, o->ptr, o->max - 1);
 
574
                add_quoted_to_str(s, l, s1);
 
575
                mem_free(s1);
 
576
        }
 
577
        else add_quoted_to_str(s, l, o->ptr);
 
578
}
 
579
 
 
580
unsigned char *cp_rd(struct option *o, unsigned char *c)
 
581
{
 
582
        unsigned char *tok = get_token(&c);
 
583
        unsigned char *e = NULL;
 
584
        int i;
 
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;
 
589
        mem_free(tok);
 
590
        return e;
 
591
}
 
592
 
 
593
void cp_wr(struct option *o, unsigned char **s, int *l)
 
594
{
 
595
        unsigned char *n = get_cp_mime_name(*(int *)o->ptr);
 
596
        add_nm(o, s, l);
 
597
        add_to_str(s, l, n);
 
598
}
 
599
 
 
600
unsigned char *lang_rd(struct option *o, unsigned char *c)
 
601
{
 
602
        int i;
 
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))) {
 
607
                        set_language(i);
 
608
                        mem_free(tok);
 
609
                        return NULL;
 
610
                }
 
611
        mem_free(tok);
 
612
        return "Unknown language";
 
613
}
 
614
 
 
615
void lang_wr(struct option *o, unsigned char **s, int *l)
 
616
{
 
617
        add_nm(o, s, l);
 
618
        add_quoted_to_str(s, l, language_name(current_language));
 
619
}
 
620
 
 
621
int getnum(unsigned char *s, int *n, int r1, int r2)
 
622
{
 
623
        unsigned char *e;
 
624
        long l = strtol(s, (char **)(void *)&e, 10);
 
625
        if (*e || !*s) return -1;
 
626
        if (l < r1 || l >= r2) return -1;
 
627
        *n = (int)l;
 
628
        return 0;
 
629
}
 
630
 
 
631
unsigned char *type_rd(struct option *o, unsigned char *c)
 
632
{
 
633
        unsigned char *err = "Error reading association specification";
 
634
        struct assoc new;
 
635
        unsigned char *w;
 
636
        int n;
 
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;
 
643
        mem_free(w);
 
644
        new.cons = !!(n & 1);
 
645
        new.xwin = !!(n & 2);
 
646
        new.ask = !!(n & 4);
 
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';
 
654
        mem_free(w);
 
655
        update_assoc(&new);
 
656
        err = NULL;
 
657
        err:
 
658
        if (new.label) mem_free(new.label);
 
659
        if (new.ct) mem_free(new.ct);
 
660
        if (new.prog) mem_free(new.prog);
 
661
        return err;
 
662
        err_f:
 
663
        mem_free(w);
 
664
        goto err;
 
665
}
 
666
 
 
667
unsigned char *block_rd(struct option *o, unsigned char *c)
 
668
{
 
669
        unsigned char *err = "Error reading image block specification";
 
670
        unsigned char* url;
 
671
 
 
672
        if(!(url = get_token(&c)))
 
673
                return err;
 
674
        
 
675
        block_add_URL_fn(NULL, url);
 
676
 
 
677
        mem_free(url);
 
678
 
 
679
        return NULL;
 
680
}
 
681
 
 
682
void block_wr(struct option *o, unsigned char **s, int *l)
 
683
{
 
684
        struct block *a;
 
685
        foreachback(a, blocks) {
 
686
                add_nm(o, s, l);
 
687
                add_quoted_to_str(s, l, a->url);
 
688
        }
 
689
}
 
690
 
 
691
void type_wr(struct option *o, unsigned char **s, int *l)
 
692
{
 
693
        struct assoc *a;
 
694
        foreachback(a, assoc) {
 
695
                add_nm(o, s, l);
 
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);
 
705
        }
 
706
}
 
707
 
 
708
unsigned char *ext_rd(struct option *o, unsigned char *c)
 
709
{
 
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;
 
715
        update_ext(&new);
 
716
        err = NULL;
 
717
        err:
 
718
        if (new.ext) mem_free(new.ext);
 
719
        if (new.ct) mem_free(new.ct);
 
720
        return err;
 
721
}
 
722
 
 
723
void ext_wr(struct option *o, unsigned char **s, int *l)
 
724
{
 
725
        struct extension *a;
 
726
        foreachback(a, extensions) {
 
727
                add_nm(o, s, l);
 
728
                add_quoted_to_str(s, l, a->ext);
 
729
                add_to_str(s, l, " ");
 
730
                add_quoted_to_str(s, l, a->ct);
 
731
        }
 
732
}
 
733
 
 
734
unsigned char *prog_rd(struct option *o, unsigned char *c)
 
735
{
 
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');
 
742
        err = NULL;
 
743
        err_3:
 
744
        mem_free(w);
 
745
        err_2:
 
746
        mem_free(prog);
 
747
        err_1:
 
748
        return err;
 
749
}
 
750
 
 
751
void prog_wr(struct option *o, unsigned char **s, int *l)
 
752
{
 
753
        struct protocol_program *a;
 
754
        foreachback(a, *(struct list_head *)o->ptr) {
 
755
                if (!*a->prog) continue;
 
756
                add_nm(o, s, l);
 
757
                add_quoted_to_str(s, l, a->prog);
 
758
                add_to_str(s, l, " ");
 
759
                add_num_to_str(s, l, a->system);
 
760
        }
 
761
}
 
762
 
 
763
unsigned char *term_rd(struct option *o, unsigned char *c)
 
764
{
 
765
        struct term_spec *ts;
 
766
        unsigned char *w;
 
767
        int i;
 
768
        if (!(w = get_token(&c))) goto err;
 
769
        if (!(ts = new_term_spec(w))) {
 
770
                mem_free(w);
 
771
                goto end;
 
772
        }
 
773
        mem_free(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';
 
777
        mem_free(w);
 
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);
 
782
        mem_free(w);
 
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);
 
788
        mem_free(w);
 
789
        if (!(w = get_token(&c))) goto err;
 
790
        if ((i = get_cp_index(w)) == -1) goto err_f;
 
791
#ifndef ENABLE_UTF8
 
792
        if ((is_cp_special(i))) {
 
793
                i = 0;
 
794
        }
 
795
#endif
 
796
        ts->charset = i;
 
797
        mem_free(w);
 
798
        end:
 
799
        return NULL;
 
800
        err_f:
 
801
        mem_free(w);
 
802
        err:
 
803
        return "Error reading terminal specification";
 
804
}
 
805
 
 
806
unsigned char *term2_rd(struct option *o, unsigned char *c)
 
807
{
 
808
        struct term_spec *ts;
 
809
        unsigned char *w;
 
810
        int i;
 
811
        if (!(w = get_token(&c))) goto err;
 
812
        if (!(ts = new_term_spec(w))) {
 
813
                mem_free(w);
 
814
                goto end;
 
815
        }
 
816
        mem_free(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';
 
820
        mem_free(w);
 
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';
 
824
        mem_free(w);
 
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';
 
828
        mem_free(w);
 
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';
 
832
        mem_free(w);
 
833
        if (!(w = get_token(&c))) goto err;
 
834
        if ((i = get_cp_index(w)) == -1) goto err_f;
 
835
#ifndef ENABLE_UTF8
 
836
        if ((is_cp_special(i))) {
 
837
                i = 0;
 
838
        }
 
839
#endif
 
840
        ts->charset = i;
 
841
        mem_free(w);
 
842
        end:
 
843
        return NULL;
 
844
        err_f:
 
845
        mem_free(w);
 
846
        err:
 
847
        return "Error reading terminal specification";
 
848
}
 
849
 
 
850
void term_wr(struct option *o, unsigned char **s, int *l)
 
851
{
 
852
        struct term_spec *ts;
 
853
        foreachback(ts, term_specs) {
 
854
                add_nm(o, s, l);
 
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));
 
864
        }
 
865
}
 
866
 
 
867
struct list_head driver_params = { &driver_params, &driver_params };
 
868
 
 
869
struct driver_param *get_driver_param(unsigned char *n)
 
870
{
 
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");
 
875
        strcpy(dp->name, n);
 
876
        dp->shell = mem_calloc(1);
 
877
        dp->nosave = 1;
 
878
        add_to_list(driver_params, dp);
 
879
        return dp;
 
880
}
 
881
 
 
882
unsigned char *dp_rd(struct option *o, unsigned char *c)
 
883
{
 
884
        int cc;
 
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))) {
 
889
                mem_free(n);
 
890
                goto err;
 
891
        }
 
892
        if (!(shell = get_token(&c))){
 
893
                mem_free(n);
 
894
                mem_free(param);
 
895
                goto err;
 
896
        }
 
897
        if (!(cp = get_token(&c))) {
 
898
                mem_free(n);
 
899
                mem_free(param);
 
900
                mem_free(shell);
 
901
                goto err;
 
902
        }
 
903
        if ((cc=get_cp_index(cp)) == -1) {
 
904
                mem_free(n);
 
905
                mem_free(param);
 
906
                mem_free(shell);
 
907
                mem_free(cp);
 
908
                goto err;
 
909
        }
 
910
        dp=get_driver_param(n);
 
911
        dp->codepage=cc;
 
912
        if (dp->param) mem_free(dp->param);
 
913
        dp->param=param;
 
914
        if (dp->shell) mem_free(dp->shell);
 
915
        dp->shell=shell;
 
916
        dp->nosave = 0;
 
917
        mem_free(cp);
 
918
        mem_free(n);
 
919
        return NULL;
 
920
        err:
 
921
        return "Error reading driver mode specification";
 
922
}
 
923
 
 
924
void dp_wr(struct option *o, unsigned char **s, int *l)
 
925
{
 
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;
 
930
                add_nm(o, s, l);
 
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));
 
938
        }
 
939
}
 
940
 
 
941
unsigned char *gen_cmd(struct option *o, unsigned char ***argv, int *argc)
 
942
{
 
943
        unsigned char *e;
 
944
        int l;
 
945
        unsigned char *r;
 
946
        if (!*argc) return "Parameter expected";
 
947
        e = init_str();
 
948
        l = 0;
 
949
        add_quoted_to_str(&e, &l, **argv);
 
950
        r = o->rd_cfg(o, e);
 
951
        mem_free(e);
 
952
        if (r) return r;
 
953
        (*argv)++; (*argc)--;
 
954
        return NULL;
 
955
}
 
956
 
 
957
unsigned char *lookup_cmd(struct option *o, unsigned char ***argv, int *argc)
 
958
{
 
959
        ip__address addr;
 
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)) {
 
965
#ifdef HAVE_HERROR
 
966
                herror("error");
 
967
#else
 
968
                fprintf(stderr, "error: host not found\n");
 
969
#endif
 
970
                return "";
 
971
        }
 
972
        printf("%d.%d.%d.%d\n", (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
 
973
        fflush(stdout);
 
974
        return "";
 
975
}
 
976
 
 
977
unsigned char *version_cmd(struct option *o, unsigned char ***argv, int *argc)
 
978
{
 
979
        printf("Links " VERSION_STRING "\n");
 
980
        fflush(stdout);
 
981
        return "";
 
982
}
 
983
 
 
984
unsigned char *set_cmd(struct option *o, unsigned char ***argv, int *argc)
 
985
{
 
986
        *(int *)o->ptr = 1;
 
987
        return NULL;
 
988
}
 
989
 
 
990
unsigned char *unset_cmd(struct option *o, unsigned char ***argv, int *argc)
 
991
{
 
992
        *(int *)o->ptr = 0;
 
993
        return NULL;
 
994
}
 
995
 
 
996
unsigned char *setstr_cmd(struct option *o, unsigned char ***argv, int *argc)
 
997
{
 
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)--;
 
1002
        return NULL;
 
1003
}
 
1004
 
 
1005
unsigned char *force_html_cmd(struct option *o, unsigned char ***argv, int *argc)
 
1006
{
 
1007
        force_html = 1;
 
1008
        return NULL;
 
1009
}
 
1010
 
 
1011
unsigned char *dump_cmd(struct option *o, unsigned char ***argv, int *argc)
 
1012
{
 
1013
        if (dmp != o->min && dmp) return "Can't use both -dump and -source";
 
1014
        dmp = o->min;
 
1015
        no_connect = 1;
 
1016
        return NULL;
 
1017
}
 
1018
 
 
1019
unsigned char *printhelp_cmd(struct option *o, unsigned char ***argv, int *argc)
 
1020
{
 
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'').
 
1024
 */
 
1025
fprintf(stdout, "%s%s%s%s%s%s\n",
 
1026
 
 
1027
("links [options] URL\n"
 
1028
"Options are:\n"
 
1029
"\n"
 
1030
" -g\n"
 
1031
"  Run in graphics mode.\n"
 
1032
"\n"
 
1033
" -no-g\n"
 
1034
"  Run in text mode (overrides previous -g).\n"
 
1035
"\n"
 
1036
" -driver <driver name>\n"
 
1037
"  Graphics driver to use. Drivers are: x, svgalib, fb, directfb, pmshell,\n"
 
1038
"    atheos.\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"
 
1041
"\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"
 
1050
"\n"
 
1051
" -display <x-display>\n"
 
1052
"  Set Xwindow display.\n"
 
1053
"\n"
 
1054
" -force-html\n"
 
1055
"  Treat files with unknown type as html rather than text.\n"
 
1056
"    (can be toggled with '\\' key)\n"
 
1057
"\n"
 
1058
" -source <url>\n"
 
1059
"  Write unformatted data stream to stdout.\n"
 
1060
"\n"
 
1061
" -dump <url>\n"
 
1062
"  Write formatted document to stdout.\n"
 
1063
"\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"
 
1067
"\n"
 
1068
" -codepage <codepage>\n"
 
1069
"  For dump, convert output to specified character set --\n"
 
1070
"    for eaxmple iso-8859-2, windows-1250.\n"
 
1071
"\n"
 
1072
" -anonymous\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"
 
1077
"\n"
 
1078
" -no-connect\n"
 
1079
"  Runs links as a separate instance - instead of connecting to\n"
 
1080
"    existing instance.\n"
 
1081
"\n"
 
1082
" -download-utime <0>/<1>\n"
 
1083
"  Set time of downloaded files to last modification time reported by server.\n"
 
1084
"\n"
 
1085
" -async-dns <0>/<1>\n"
 
1086
"  Asynchronous DNS resolver on(1)/off(0).\n"
 
1087
"\n"
 
1088
" -max-connections <max>\n"
 
1089
"  Maximum number of concurrent connections.\n"
 
1090
"    (default: 10)\n"
 
1091
"\n"),
 
1092
(" -max-connections-to-host <max>\n"
 
1093
"  Maximum number of concurrent connection to a given host.\n"
 
1094
"    (default: 2)\n"
 
1095
"\n"
 
1096
" -retries <retry>\n"
 
1097
"  Number of retries.\n"
 
1098
"    (default: 3)\n"
 
1099
"\n"
 
1100
" -receive-timeout <sec>\n"
 
1101
"  Timeout on receive.\n"
 
1102
"    (default: 120)\n"
 
1103
"\n"),
 
1104
(" -unrestartable-receive-timeout <sec>\n"
 
1105
"  Timeout on non restartable connections.\n"
 
1106
"    (default: 600)\n"
 
1107
"\n"
 
1108
" -format-cache-size <num>\n"
 
1109
"  Number of formatted document pages cached.\n"
 
1110
"    (default: 5)\n"
 
1111
"\n"
 
1112
" -memory-cache-size <bytes>\n"
 
1113
"  Cache memory in bytes.\n"
 
1114
"    (default: 1048576)\n"
 
1115
"\n"
 
1116
" -image-cache-size <bytes>\n"
 
1117
"  Cache memory in bytes.\n"
 
1118
"    (default: 1048576)\n"
 
1119
"\n"),
 
1120
(" -http-proxy <host:port>\n"
 
1121
"  Host and port number of the HTTP proxy, or blank.\n"
 
1122
"    (default: blank)\n"
 
1123
"\n"
 
1124
" -ftp-proxy <host:port>\n"
 
1125
"  Host and port number of the FTP proxy, or blank.\n"
 
1126
"    (default: blank)\n"
 
1127
"\n"
 
1128
" -socks-proxy <user@host:port>\n"
 
1129
"  Userid, host and port of Socks4a, or blank.\n"
 
1130
"    (default: blank)\n"
 
1131
"\n"
 
1132
" -append-text-to-dns-lookups <text>\n"
 
1133
"  Append text to dns lookups. It is useful for specifying fixed\n"
 
1134
"    tor exit node.\n"
 
1135
"    (default: blank)\n"
 
1136
"\n"
 
1137
" -only-proxies <0>/<1>\n"
 
1138
"    (default 0)\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"
 
1141
"\n"
 
1142
" -download-dir <path>\n"
 
1143
"  Default download directory.\n"
 
1144
"    (default: actual dir)\n"
 
1145
"\n"
 
1146
" -aggressive-cache <0>/<1>\n"
 
1147
"    (default 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"
 
1151
"\n"),
 
1152
(" -language <language>\n"
 
1153
"  Set user interface language.\n"
 
1154
"\n"
 
1155
" -http-bugs.http10 <0>/<1>\n"
 
1156
"    (default 0)\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"
 
1160
"\n"
 
1161
" -http-bugs.allow-blacklist <0>/<1>\n"
 
1162
"    (default 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"
 
1165
"\n"
 
1166
" -http-bugs.bug-302-redirect <0>/<1>\n"
 
1167
"    (default 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"
 
1170
"\n"
 
1171
" -http-bugs.bug-post-no-keepalive <0>/<1>\n"
 
1172
"    (default 0)\n"
 
1173
"  No keepalive connection after post requests. For some buggy servers.\n"
 
1174
"\n"
 
1175
" -http-bugs.bug-no-accept-charset <0>/<1>\n"
 
1176
"    (default 0)\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"
 
1180
"\n"
 
1181
" -http-bugs.no-compression <0>/<1>\n"
 
1182
"    (default 0)\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"
 
1186
"\n"
 
1187
" -http-bugs.retry-internal-errors <0>/<1>\n"
 
1188
"    (default 0)\n"
 
1189
"  Retry on internal server errors (50x).\n"
 
1190
"\n"
 
1191
" -http.referer <0>/<1>/<2>/<3>\n"
 
1192
"    (default 0)\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"
 
1198
"\n"
 
1199
" -http.fake-referer <string>\n"
 
1200
"  Fake referer value.\n"
 
1201
"\n"
 
1202
" -http.fake-user-agent <string>\n"
 
1203
"  Fake user agent value.\n"
 
1204
"\n"
 
1205
" -http.extra-header <string>\n"
 
1206
"  Extra string added to HTTP header.\n"
 
1207
"\n"
 
1208
" -ftp.anonymous-password <string>\n"
 
1209
"  Password for anonymous ftp access.\n"
 
1210
"\n"
 
1211
" -ftp.use-passive <0>/<1>\n"
 
1212
"  Use ftp PASV command to bypass firewalls.\n"
 
1213
"\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"
 
1218
"\n"
 
1219
" -ftp.set-iptos <0>/<1>\n"
 
1220
"  Set IP Type-of-service to high throughput on ftp connections.\n"
 
1221
"\n"
 
1222
" -menu-font-size <size>\n"
 
1223
"  Size of font in menu.\n"
 
1224
"\n"
 
1225
" -background-color 0xRRGGBB\n"
 
1226
"  Set menu background color in graphics mode, RRGGBB are hex.\n"
 
1227
"\n"
 
1228
" -foreground-color 0xRRGGBB\n"
 
1229
"  Set menu foreground color in graphics mode.\n"
 
1230
"\n"
 
1231
" -scroll-bar-area-color 0xRRGGBB\n"
 
1232
"  Set color of scroll bar area.\n"
 
1233
"\n"
 
1234
" -scroll-bar-bar-color 0xRRGGBB\n"
 
1235
"  Set color of scroll bar.\n"
 
1236
"\n"
 
1237
" -scroll-bar-frame-color 0xRRGGBB\n"
 
1238
"  Set color of scroll bar frame.\n"
 
1239
"\n"
 
1240
" -display-red-gamma <fp-value>\n"
 
1241
"  Red gamma of display.\n"
 
1242
"    (default 2.2)\n"
 
1243
"\n"
 
1244
" -display-green-gamma <fp-value>\n"
 
1245
"  Green gamma of display.\n"
 
1246
"    (default 2.2)\n"
 
1247
"\n"
 
1248
" -display-blue-gamma <fp-value>\n"
 
1249
"  Blue gamma of display.\n"
 
1250
"    (default 2.2)\n"
 
1251
"\n"
 
1252
" -user-gamma <fp-value>\n"
 
1253
"  Additional gamma.\n"
 
1254
"    (default 1)\n"
 
1255
"\n"
 
1256
" -bfu-aspect <fp-value>\n"
 
1257
"  Display aspect ration.\n"
 
1258
"\n"
 
1259
" -aspect-on <0>/<1>\n"
 
1260
"  Enable aspect ratio correction.\n"
 
1261
"\n"
 
1262
" -dither-letters <0>/<1>\n"
 
1263
"  Do letter dithering.\n"
 
1264
"\n"
 
1265
" -dither-images <0>/<1>\n"
 
1266
"  Do image dithering.\n"
 
1267
"\n"
 
1268
" -display-optimize <0>/<1>/<2>\n"
 
1269
"  Optimize for CRT (0), LCD RGB (1), LCD BGR (2).\n"
 
1270
"\n"
 
1271
" -gamma correction <0>/<1>/<2>\n"
 
1272
"  Type of gamma correction:\n"
 
1273
"    (default 2)\n"
 
1274
"  0 - 8-bit (fast).\n"
 
1275
"  1 - 16-bit (slow).\n"
 
1276
"  2 - automatically detect according to speed of FPU.\n"
 
1277
"\n"
 
1278
#ifdef JS
 
1279
" -enable-javascript <0>/<1>\n"
 
1280
"  Enable javascript.\n"
 
1281
"\n"
 
1282
" -js.verbose-errors <0>/<1>\n"
 
1283
"  Display javascript errors.\n"
 
1284
"\n"
 
1285
" -js.verbose-warnings <0>/<1>\n"
 
1286
"  Display javascript warnings.\n"
 
1287
"\n"
 
1288
" -js.enable-all-conversions <0>/<1>\n"
 
1289
"  Enable conversions between all types in javascript.\n"
 
1290
"\n"
 
1291
" -js.enable-global-resolution <0>/<1>\n"
 
1292
"  Resolve global names.\n"
 
1293
"\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"
 
1297
"\n"
 
1298
" -js.recursion-depth <integer>\n"
 
1299
"  Depth of javascript call stack.\n"
 
1300
"\n"
 
1301
" -js.memory-limit <memory amount>\n"
 
1302
"  Amount of kilobytes the javascript may allocate.\n"
 
1303
"\n"
 
1304
#endif
 
1305
" -bookmarks-codepage <codepage>\n"
 
1306
"  Character set of bookmarks file.\n"
 
1307
"\n"
 
1308
" -bookmarks-file <file>\n"
 
1309
"  File to store bookmarks.\n"
 
1310
"\n"
 
1311
" -html-assume-codepage <codepage>\n"
 
1312
"  If server didn't specify document character set, assume this.\n"
 
1313
"\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"
 
1317
"\n"
 
1318
" -html-tables <0>/<1>\n"
 
1319
"  Render tables. (0) causes tables being rendered like in lynx.\n"
 
1320
"\n"
 
1321
" -html-frames <0>/<1>\n"
 
1322
"  Render frames. (0) causes frames  rendered like in lynx.\n"
 
1323
"\n"
 
1324
" -html-images <0>/<1>\n"
 
1325
"  Display links to unnamed images as [IMG].\n"
 
1326
"\n"
 
1327
" -html-image-names <0>/<1>\n"
 
1328
"  Display filename of an image instead of [IMG].\n"
 
1329
"\n"
 
1330
" -html-display-images <0>/<1>\n"
 
1331
"  Display images in graphics mode.\n"
 
1332
"\n"
 
1333
" -html-image-scale <percent>\n"
 
1334
"  Scale images in graphics mode.\n"
 
1335
"\n"
 
1336
" -html-bare-image-autoscale <0>/<1>\n"
 
1337
"  Autoscale images displayed on full screen.\n"
 
1338
"\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"
 
1342
"\n"
 
1343
" -html-table-order <0>/<1>\n"
 
1344
"  In text mode, walk through table by rows (0) or columns (1).\n"
 
1345
"\n"
 
1346
" -html-auto-refresh <0>/<1>\n"
 
1347
"  Process refresh to other page (1), or display link to that page (0).\n"
 
1348
"\n"
 
1349
" -html-target-in-new-window <0>/<1>\n"
 
1350
"  Allow opening new windows from html.\n"
 
1351
"\n"
 
1352
" -html-margin <number of spaces>\n"
 
1353
"  Margin in text mode.\n"
 
1354
"\n"
 
1355
" -html-user-font-size <size>\n"
 
1356
"  Size of font on pages in graphics mode.\n"
 
1357
"\n"
 
1358
" -lookup <hostname>\n"
 
1359
"  Does name lookup, like command \"host\".\n"
 
1360
"\n"
 
1361
" -version\n"
 
1362
"  Prints the links version number and exit.\n"
 
1363
"\n"
 
1364
" -help\n"
 
1365
"  Prints this help screen\n"
 
1366
"\n"
 
1367
"\n"),
 
1368
("Keys:\n"
 
1369
"       ESC       display menu\n"
 
1370
"       ^C        quit\n"
 
1371
"       ^P        scroll up\n"
 
1372
"       ^N        scroll down\n"
 
1373
"       [, ]      scroll left, right\n"
 
1374
"       up, down  select link\n"
 
1375
"       ->, enter follow link\n"
 
1376
"       <-, z     go back\n"
 
1377
"       g         go to url\n"
 
1378
"       G         go to url based on current url\n"
 
1379
"       ^G        go to url based on current link\n"
 
1380
"       ^R        reload\n"
 
1381
"       /         search\n"
 
1382
"       ?         search back\n"
 
1383
"       n         find next\n"
 
1384
"       N         find previous\n"
 
1385
"       =         document info\n"
 
1386
"       \\        document source\n"
 
1387
"       |         HTTP header\n"
 
1388
"       *         toggle displaying of image links (text mode)\n"
 
1389
"       d         download\n"
 
1390
"       s         bookmarks\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"
 
1397
"       Alt-1 .. Alt-9\n"
 
1398
"                 switch virtual screens (svgalib and framebuffer)\n"
 
1399
"\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"
 
1405
"       ^Y        next link\n"
 
1406
"       ^T        previous link\n"
 
1407
"       y         next word\n"
 
1408
"       t         previous word\n"
 
1409
"       ^O        next form field entry\n"
 
1410
));
 
1411
 
 
1412
        fflush(stdout);
 
1413
        return "";
 
1414
}
 
1415
 
 
1416
void end_config(void)
 
1417
{
 
1418
        struct driver_param *dp;
 
1419
        foreach(dp,driver_params)
 
1420
        {
 
1421
                if (dp->param)mem_free(dp->param);
 
1422
                if (dp->shell)mem_free(dp->shell);
 
1423
        }
 
1424
        free_list(driver_params);
 
1425
        if (links_home) mem_free(links_home);
 
1426
}
 
1427
 
 
1428
int ggr = 0;
 
1429
unsigned char ggr_drv[MAX_STR_LEN] = "";
 
1430
unsigned char ggr_mode[MAX_STR_LEN] = "";
 
1431
unsigned char ggr_display[MAX_STR_LEN] = "";
 
1432
 
 
1433
int anonymous = 0;
 
1434
 
 
1435
unsigned char system_name[MAX_STR_LEN];
 
1436
 
 
1437
unsigned char default_target[MAX_STR_LEN] ="";
 
1438
 
 
1439
unsigned char *links_home = NULL;
 
1440
int first_use = 0;
 
1441
int created_home = 0;
 
1442
 
 
1443
int no_connect = 0;
 
1444
int base_session = 0;
 
1445
int dmp = 0;
 
1446
int force_html = 0;
 
1447
 
 
1448
int async_lookup = 1;
 
1449
int download_utime = 0;
 
1450
int max_connections = 10;
 
1451
int max_connections_to_host = 8;
 
1452
int max_tries = 3;
 
1453
int receive_timeout = 120;
 
1454
int unrestartable_receive_timeout = 600;
 
1455
 
 
1456
int screen_width = 80;
 
1457
int dump_codepage = -1;
 
1458
 
 
1459
int max_format_cache_entries = 5;
 
1460
int memory_cache_size = 1048576;
 
1461
int image_cache_size = 1048576;
 
1462
 
 
1463
int enable_html_tables = 1;
 
1464
int enable_html_frames = 1;
 
1465
 
 
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 */
 
1469
        0 };
 
1470
 
 
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 };
 
1475
 
 
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 };
 
1480
 
 
1481
int default_left_margin = HTML_LEFT_MARGIN;
 
1482
 
 
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) */
 
1492
 
 
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 */
 
1496
int aspect_on=1;
 
1497
 
 
1498
unsigned char download_dir[MAX_STR_LEN] = "";
 
1499
 
 
1500
int aggressive_cache = 1;
 
1501
 
 
1502
struct ftp_options ftp_options = { "somebody@host.domain", 0, 0, 1 };
 
1503
 
 
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 */
 
1512
 
 
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, &current_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},
 
1606
};
 
1607
 
 
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},
 
1625
};
 
1626
 
 
1627
void load_url_history(void)
 
1628
{
 
1629
        unsigned char *history_file, *hs;
 
1630
        unsigned char *hsp;
 
1631
 
 
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);
 
1639
        if (!hs) return;
 
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);
 
1645
                mem_free(hsc);
 
1646
                hsp = hsl;
 
1647
                while (*hsp == 10 || *hsp == 13) hsp++;
 
1648
        }
 
1649
        mem_free(hs);
 
1650
}
 
1651
 
 
1652
void save_url_history(void)
 
1653
{
 
1654
        struct history_item *hi;
 
1655
        unsigned char *history_file;
 
1656
        unsigned char *hs;
 
1657
        int hsl = 0;
 
1658
        int i = 0;
 
1659
        if (anonymous) return;
 
1660
 
 
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");
 
1665
        hs = init_str();
 
1666
        hsl = 0;
 
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)
 
1670
                        break;
 
1671
                else {
 
1672
                        add_to_str(&hs, &hsl, hi->d);
 
1673
                        add_to_str(&hs, &hsl, NEWLINE);
 
1674
                }
 
1675
        }
 
1676
        write_to_config_file(history_file, hs);
 
1677
        mem_free(history_file);
 
1678
        mem_free(hs);
 
1679
        return;
 
1680
}
 
1681