📄 default.c
字号:
/* default.c * (c) 2002 Mikulas Patocka, Petr 'Brain' Kulhavy * This file is a part of the Links program, released under GPL * * Does the configuration file. */#include "links.h"/* prototypes */void get_system_name(void);void get_system_name(void){ FILE *f; unsigned char *p;#if defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME) struct utsname name; memset(&name, 0, sizeof name); if (!uname(&name)) { unsigned char *str = init_str(); int l = 0; add_to_str(&str, &l, name.sysname); add_to_str(&str, &l, " "); add_to_str(&str, &l, name.release); add_to_str(&str, &l, " "); add_to_str(&str, &l, name.machine); if (l >= MAX_STR_LEN) str[MAX_STR_LEN - 1] = 0; strcpy(system_name, str); mem_free(str); return; }#endif#ifdef HAVE_POPEN memset(system_name, 0, MAX_STR_LEN); if (!(f = popen("uname -srm", "r"))) goto fail; if (fread(system_name, 1, MAX_STR_LEN - 1, f) <= 0) { pclose(f); goto fail; } pclose(f); for (p = system_name; *p; p++) if (*p < ' ') { *p = 0; break; } if (system_name[0]) return; fail:#endif strcpy(system_name, SYSTEM_NAME);}struct option { int p; unsigned char *(*rd_cmd)(struct option *, unsigned char ***, int *); unsigned char *(*rd_cfg)(struct option *, unsigned char *); void (*wr_cfg)(struct option *, unsigned char **, int *); int min, max; /* for double min and max are in 1/100's (e.g. 0.1 is min==10) */ void *ptr; unsigned char *cfg_name; unsigned char *cmd_name;};extern struct option links_options[];extern struct option html_options[];struct option *all_options[] = { links_options, html_options, NULL, };/* prototypes */unsigned char *get_token(unsigned char **);void parse_config_file(unsigned char *, unsigned char *, struct option **);unsigned char *create_config_string(struct option *);unsigned char *get_home(int *);void load_config_file(unsigned char *, unsigned char *);int write_config_data(unsigned char *, unsigned char *, struct option *, struct terminal *);void add_nm(struct option *, unsigned char **, int *);void add_quoted_to_str(unsigned char **, int *, unsigned char *);unsigned char *num_rd(struct option *, unsigned char *);void num_wr(struct option *, unsigned char **, int *);unsigned char *dbl_rd(struct option *, unsigned char *);void dbl_wr(struct option *, unsigned char **, int *);unsigned char *str_rd(struct option *, unsigned char *);void str_wr(struct option *, unsigned char **, int *);unsigned char *cp_rd(struct option *, unsigned char *);void cp_wr(struct option *, unsigned char **, int *);unsigned char *lang_rd(struct option *, unsigned char *);void lang_wr(struct option *, unsigned char **, int *);int getnum(unsigned char *, int *, int, int);unsigned char *type_rd(struct option *, unsigned char *);void type_wr(struct option *, unsigned char **, int *);unsigned char *ext_rd(struct option *, unsigned char *);void ext_wr(struct option *, unsigned char **, int *);unsigned char *prog_rd(struct option *, unsigned char *);void prog_wr(struct option *, unsigned char **, int *);unsigned char *term_rd(struct option *, unsigned char *);unsigned char *term2_rd(struct option *, unsigned char *);void term_wr(struct option *, unsigned char **, int *);unsigned char *dp_rd(struct option *, unsigned char *);void dp_wr(struct option *, unsigned char **, int *);unsigned char *gen_cmd(struct option *, unsigned char ***, int *);unsigned char *lookup_cmd(struct option *, unsigned char ***, int *);unsigned char *version_cmd(struct option *, unsigned char ***, int *);unsigned char *set_cmd(struct option *, unsigned char ***, int *);unsigned char *unset_cmd(struct option *, unsigned char ***, int *);unsigned char *setstr_cmd(struct option *, unsigned char ***, int *);unsigned char *force_html_cmd(struct option *, unsigned char ***, int *);unsigned char *dump_cmd(struct option *, unsigned char ***, int *);unsigned char *printhelp_cmd(struct option *, unsigned char ***, int *);unsigned char *p_arse_options(int, unsigned char *[], struct option **);unsigned char *block_rd(struct option *, unsigned char *);void block_wr(struct option *, unsigned char **, int *);unsigned char *p_arse_options(int argc, unsigned char *argv[], struct option **opt){ unsigned char *e, *u = NULL; while (argc) { int i; argv++, argc--; if (argv[-1][0] == '-') { struct option *options; struct option **op; for (op = opt; (options = *op); op++) for (i = 0; options[i].p; i++) if (options[i].rd_cmd && options[i].cmd_name && !strcasecmp(options[i].cmd_name, &argv[-1][1])) { if ((e = options[i].rd_cmd(&options[i], &argv, &argc))) { if (e[0]) fprintf(stderr, "Error parsing option %s: %s\n", argv[-1], e); return NULL; } goto found; } uu:#ifdef GRDRV_DIRECTFB if (!strncmp(argv[-1], "--dfb:", 6)) goto found;#endif fprintf(stderr, "Unknown option %s\n", argv[-1]); return NULL; } else if (!u) u = argv[-1]; else goto uu; found:; } if (u) return u; return "";}unsigned char *parse_options(int argc, unsigned char *argv[]){ return p_arse_options(argc, argv, all_options);}unsigned char *get_token(unsigned char **line){ unsigned char *s = NULL; int l = 0; int escape = 0; int quote = 0; while (**line == ' ' || **line == 9) (*line)++; if (**line) { for (s = init_str(); **line; (*line)++) { if (escape) escape = 0; else if (**line == '\\') { escape = 1; continue; } else if (**line == '"') { quote = !quote; continue; } else if ((**line == ' ' || **line == 9) && !quote) break; add_chr_to_str(&s, &l, **line); } } return s;}void parse_config_file(unsigned char *name, unsigned char *file, struct option **opt){ struct option *options; struct option **op; int err = 0; int line = 0; unsigned char *e; int i; unsigned char *n, *p; unsigned char *tok; int nl, pl; while (file[0]) { line++; while (file[0] && (file[0] == ' ' || file[0] == 9)) file++; n = file; while (file[0] && file[0] > ' ') file++; if (file == n) { if (file[0]) file++; continue; } nl = file - n; while (file[0] == 9 || file[0] == ' ') file++; p = file; while (file[0] && file[0] != 10 && file[0] != 13) file++; pl = file - p; if (file[0]) { if ((file[1] == 10 || file[1] == 13) && file[0] != file[1]) file++; file++; } tok = NULL; if (n[0] == '#') goto f; if (!(tok = get_token(&n))) goto f; nl = strlen(tok); for (op = opt; (options = *op); op++) 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)) { unsigned char *o = memacpy(p, pl); if ((e = options[i].rd_cfg(&options[i], o))) { if (e[0]) fprintf(stderr, "Error parsing config file %s, line %d: %s\n", name, line, e), err = 1; } mem_free(o); goto f; } fprintf(stderr, "Unknown option in config file %s, line %d\n", name, line); err = 1; f: if (tok) mem_free(tok); } if (err) fprintf(stderr, "\007"), sleep(1);}unsigned char *create_config_string(struct option *options){ unsigned char *s = init_str(); int l = 0; int i; add_to_str(&s, &l, "# This file is automatically generated by Links -- please do not edit."); for (i = 0; options[i].p; i++) if (options[i].wr_cfg) options[i].wr_cfg(&options[i], &s, &l); add_to_str(&s, &l, NEWLINE); return s;}#define FILE_BUF 1024unsigned char cfg_buffer[FILE_BUF];unsigned char *read_config_file(unsigned char *name){ int h, r; int l = 0; unsigned char *s; if ((h = open(name, O_RDONLY | O_NOCTTY)) == -1) return NULL; set_bin(h); s = init_str(); while ((r = read(h, cfg_buffer, FILE_BUF)) > 0) { int i; for (i = 0; i < r; i++) if (!cfg_buffer[i]) cfg_buffer[i] = ' '; add_bytes_to_str(&s, &l, cfg_buffer, r); } if (r == -1) mem_free(s), s = NULL; close(h); return s;}int write_to_config_file(unsigned char *name, unsigned char *c){ int rr; int r; int h, w; unsigned char *tmp_name = stracpy(name); unsigned char *ds, *dt, *dot; for (dt = ds = tmp_name; *dt; dt++) if (dir_sep(*dt)) ds = dt; if ((dot = strchr(ds, '.'))) *dot = 0; add_to_strn(&tmp_name, ".tmp"); if ((h = open(tmp_name, O_WRONLY | O_NOCTTY | O_CREAT | O_TRUNC, 0666)) == -1) { mem_free(tmp_name); return errno; } set_bin(h); rr = strlen(c); r = rr; while (r > 0) { if ((w = write(h, c + rr - r, r)) <= 0) { int err = !w ? ENOSPC : errno; close(h); unlink(tmp_name); mem_free(tmp_name); return err; } r -= w; } close(h);#ifndef RENAME_OVER_EXISTING_FILES unlink(name);#endif if (rename(tmp_name, name)) { int err = errno; unlink(tmp_name); mem_free(tmp_name); return err; } mem_free(tmp_name); return 0;}unsigned char *get_home(int *n){ struct stat st; unsigned char *home = NULL; unsigned char *home_links; unsigned char *config_dir = stracpy(getenv("CONFIG_DIR")); if (n) *n = 1;#ifdef WIN32 if (!home) home = stracpy(getenv("APPDATA"));#endif if (!home) home = stracpy(getenv("HOME")); if (!home#ifdef WIN32/* When we run in Cygwin without Cygwin environment, it reports home "/". Unfortunatelly, it can't write anything to that directory */ || !strcmp(home, "/")#endif ) { int i; home = stracpy(path_to_exe); if (!home) { if (config_dir) mem_free(config_dir); return NULL; } for (i = strlen(home) - 1; i >= 0; i--) if (dir_sep(home[i])) { home[i + 1] = 0; goto br; } home[0] = 0; br:; } while (home[0] && dir_sep(home[strlen(home) - 1])) home[strlen(home) - 1] = 0; if (home[0]) add_to_strn(&home, "/"); home_links = stracpy(home); if (config_dir) { add_to_strn(&home_links, config_dir); while (home_links[0] && dir_sep(home_links[strlen(home_links) - 1])) home_links[strlen(home_links) - 1] = 0; if (stat(home_links, &st) != -1 && S_ISDIR(st.st_mode)) { add_to_strn(&home_links, "/links"); } else { fprintf(stderr, "CONFIG_DIR set to %s. But directory %s doesn't exist.\n\007", config_dir, home_links); sleep(3); mem_free(home_links); home_links = stracpy(home); add_to_strn(&home_links, ".links"); } mem_free(config_dir); } else add_to_strn(&home_links, ".links"); if (stat(home_links, &st)) {#ifdef HAVE_MKDIR if (!mkdir(home_links, 0777)) goto home_creat;#endif if (config_dir) goto failed; goto first_failed; } if (S_ISDIR(st.st_mode)) goto home_ok; /* This is a Cygwin hack! Cygwin reports stat for "links" if no "links" exists and only "links.exe" does. So try to create directory anyway. */ if (!mkdir(home_links, 0777)) goto home_creat; first_failed: mem_free(home_links); home_links = stracpy(home); add_to_strn(&home_links, "links"); if (stat(home_links, &st)) {#ifdef HAVE_MKDIR if (!mkdir(home_links, 0777)) goto home_creat;#else mem_free(home_links); home_links = stracpy(home); goto home_ok;#endif goto failed; } if (S_ISDIR(st.st_mode)) goto home_ok; if (!mkdir(home_links, 0777)) goto home_creat; failed: mem_free(home_links); mem_free(home); return NULL; home_ok: if (n) *n = 0; home_creat:#ifdef HAVE_CHMOD chmod(home_links, 0700);#endif add_to_strn(&home_links, "/"); mem_free(home); return home_links;}void init_home(void){ get_system_name(); links_home = get_home(&first_use); if (!links_home) { 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"); sleep(3); return; }}void load_config_file(unsigned char *prefix, unsigned char *name){ unsigned char *c, *config_file; config_file = stracpy(prefix); if (!config_file) return; add_to_strn(&config_file, name);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -