/* This file is part of GNU Dico. Copyright (C) 1998-2019 Sergey Poznyakoff GNU Dico is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Dico is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Dico. If not, see . */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "grecs.h" #include "wordsplit.h" #include #include #include #include #include #define EXIT_TIMEOUT 2 #define UINTMAX_STRSIZE_BOUND INT_BUFSIZE_BOUND(uintmax_t) extern int mode; extern int foreground; /* Run in foreground mode */ extern int single_process; /* Single process mode */ extern int log_to_stderr; /* Log to stderr */ extern char *config_file; extern int config_lint_option; extern char *pidfile_name; extern dico_list_t listen_addr; extern uid_t user_id; extern gid_t group_id; extern dico_list_t /* of gid_t */ group_list; extern unsigned int max_children; extern unsigned int shutdown_timeout; extern unsigned int inactivity_timeout; extern char *hostname; extern const char *program_version; extern char *initial_banner_text; extern int got_quit; extern char *help_text; extern const char *server_info; extern char *msg_id; extern dico_list_t module_load_path; extern dico_list_t prepend_load_path; extern dico_list_t modinst_list; extern dico_list_t database_list; extern int timing_option; extern char *client_id; extern char *user_name; extern dico_list_t user_groups; extern int transcript; extern char *debug_level_str; extern unsigned long total_forks; extern char *access_log_format; extern char *access_log_file; extern int identity_check; extern char *identity_name; extern char *ident_keyfile; extern long ident_timeout; extern struct sockaddr server_addr; extern socklen_t server_addrlen; extern struct sockaddr_storage client_addr; extern socklen_t client_addrlen; extern const char *program_version; struct dico_stat { unsigned long defines; unsigned long matches; unsigned long compares; }; extern struct dico_stat current_stat, total_stat; #ifndef LOG_FACILITY # define LOG_FACILITY LOG_LOCAL1 #endif #define DICTD_DEFAULT_STRATEGY "lev" #define DICTD_LOGGING_ENVAR "__DICTD_LOGGING__" #define MODE_DAEMON 0 #define MODE_INETD 1 #define MODE_PREPROC 2 #define MODE_TEST 3 struct dicod_conf_override { int transcript; }; void get_options(int *argc, char **argv[], struct dicod_conf_override *conf); /* acl.c */ typedef struct dicod_acl *dicod_acl_t; dicod_acl_t dicod_acl_create(const char *name, grecs_locus_t *locus); int dicod_acl_check(dicod_acl_t acl, int res); int parse_acl_line(grecs_locus_t *locus, int allow, dicod_acl_t acl, grecs_value_t *value); int dicod_acl_install(dicod_acl_t acl, grecs_locus_t *locus); dicod_acl_t dicod_acl_lookup(const char *name); extern dicod_acl_t connect_acl; /* */ typedef struct dicod_module_instance { char *ident; char *command; struct dico_database_module *module; lt_dlhandle handle; } dicod_module_instance_t; #define DICO_DBF_LANG 0x10000 struct dicod_database { int flags; char *name; /* Dictionary name */ char *descr; /* Description (SHOW DB) */ char *info; /* Info (SHOW INFO) */ dico_list_t langlist[2]; /* List of "source/dest" languages */ dicod_acl_t acl; /* ACL for this database */ int visible; /* Is this database (administratively) visible */ int session_visible; /* Is this database visible in the current session. This depends on the value of visible and on the result of dicod_acl_check and dicod_lang_check */ dico_handle_t mod_handle; /* Dico module handle */ dico_assoc_list_t mime_headers; dicod_module_instance_t *instance; /* Pointer to the module instance structure */ int argc; /* Handler arguments: count */ char **argv; /* ... and pointers */ char *command; /* Handler command line (for diagnostics) */ void *extra; }; #define CONTENT_TRANSFER_ENCODING_HEADER "Content-transfer-encoding" /* dicod.c */ void dicod_server(int argc, char **argv); void replace_io_stream(dico_stream_t str); dico_stream_t dicod_iostream(int ifd, int ofd); int dicod_loop(dico_stream_t stream); int dicod_inetd(void); void dicod_init_strategies(void); void dicod_server_init(void); void dicod_server_cleanup(void); int get_input_line(dico_stream_t str, char **buf, size_t *size, size_t *rdbytes); dicod_database_t *find_database(const char *name); void database_remove_dependent(dicod_module_instance_t *inst); size_t database_count(void); int database_iterate(dico_list_iterator_t fun, void *data); int show_sys_info_p(void); void dicod_log_setup(void); void dicod_log_pre_setup(void); void dicod_log_encode_envar(void); char *get_full_hostname(void); void check_db_visibility(void); void reset_db_visibility(void); static inline int database_is_visible(dicod_database_t const *db) { return db->session_visible; } static inline int database_is_virtual(dicod_database_t const *db) { return db->flags & DICO_DBF_VIRTUAL; } int dicod_any_lang_list_p(dico_list_t list); typedef void (*dicod_cmd_fn) (dico_stream_t str, int argc, char **argv); struct dicod_command { const char *keyword; int minparam; int maxparam; char *param; char *help; dicod_cmd_fn handler; }; #define DICOD_MAXPARAM_INF (-1) void dicod_handle_command(dico_stream_t str, int argc, char **argv); void dicod_init_command_tab(void); void dicod_add_command(struct dicod_command *cmd); void dicod_remove_command(const char *name); /* capa.c */ void dicod_capa_register(const char *name, struct dicod_command *cmd, int (*init)(void*), void *closure); int dicod_capa_add(const char *name); void dicod_capa_iterate(int (*fun)(const char*, int, void *), void *closure); int dicod_capa_flush(void); int dicod_capa_is_enabled(const char *name); /* lang.c */ void register_lang(void); int dicod_lang_check(dico_list_t list[2]); /* mime.c */ extern int option_mime; void register_mime(void); /* markup.c */ void register_markup(void); void markup_flush_capa(void); /* xidle.c */ void register_xidle(void); /* xversion.c */ void register_xversion(void); /* lev.c */ void register_lev(void); /* regex.c */ void register_regex(void); /* dbtext.c */ extern struct dico_udb_def text_udb_def; extern dico_udb_t user_db; /* auth.c */ void register_auth(void); void init_auth_data(void); /* loader.c */ void dicod_loader_init(void); int dicod_load_module(dicod_module_instance_t *hptr); dico_list_t dicod_langlist_copy(dico_list_t src); void dicod_match_word_db(dicod_database_t *db, dico_stream_t stream, const dico_strategy_t strat, const char *word); void dicod_match_word_first(dico_stream_t stream, const dico_strategy_t strat, const char *word); void dicod_match_word_all(dico_stream_t stream, const dico_strategy_t strat, const char *word); void dicod_define_word_db(dicod_database_t *db, dico_stream_t stream, const char *word); void dicod_define_word_first(dico_stream_t stream, const char *word); void dicod_define_word_all(dico_stream_t stream, const char *word); int dicod_module_test(int argc, char **argv); void dicod_builtin_module_init(void); /* result.c */ typedef struct dicod_db_result { int flags; dicod_database_t *db; dico_result_t res; size_t rcount; size_t ccount; } dicod_db_result_t; dicod_db_result_t *dicod_db_result_alloc(dicod_database_t *db, dico_result_t res); void dicod_db_result_free(dicod_db_result_t *dbr); size_t dicod_db_result_count(dicod_db_result_t *dbr); size_t dicod_db_result_compare_count(dicod_db_result_t *dbr); int dicod_db_result_output(dicod_db_result_t *dbr, size_t n, dico_stream_t str); dico_assoc_list_t dicod_db_result_mime_header(dicod_db_result_t *dbr, size_t n); /* Flag values for dicod_db_result_db: */ enum { result_db_all, /* Return the database no matter what its visibility */ result_db_visible /* Return only visible databases */ }; dicod_database_t *dicod_db_result_db(dicod_db_result_t *dbr, size_t n, int flag); /* database.c */ int dicod_database_init(dicod_database_t *dp); int dicod_database_open(dicod_database_t *dp); int dicod_database_close(dicod_database_t *dp); int dicod_database_deinit(dicod_database_t *dp); void dicod_database_free(dicod_database_t *dp); char *dicod_database_get_descr(dicod_database_t *db); void dicod_database_free_descr(dicod_database_t *db, char *descr); char *dicod_database_get_info(dicod_database_t *db); void dicod_database_free_info(dicod_database_t *db, char *info); void dicod_database_get_languages(dicod_database_t *db, dico_list_t list[]); dicod_db_result_t *dicod_database_match(dicod_database_t *db, const dico_strategy_t strat, const char *word); dicod_db_result_t *dicod_database_define(dicod_database_t *db, const char *word); char *dicod_database_get_info(dicod_database_t *db); void dicod_database_free_info(dicod_database_t *db, char *info); char *dicod_database_get_descr(dicod_database_t *db); void dicod_database_free_descr(dicod_database_t *db, char *descr); int dicod_database_flags(dicod_database_t const *db); void dicod_database_print_definitions(const char *word, dicod_db_result_t *res, size_t count, dico_stream_t stream); /* ostream.c */ extern off_t total_bytes_out; dico_stream_t dicod_ostream_create(dico_stream_t str, dico_assoc_list_t headers); /* stat.c */ void begin_timing(const char *name); void report_timing(dico_stream_t stream, xdico_timer_t t, struct dico_stat *sp); void report_current_timing(dico_stream_t stream, const char *name); /* xscript.c */ dico_stream_t transcript_stream_create(dico_stream_t transport, dico_stream_t logstr, const char *prefix[]); /* getopt.m4 */ extern void print_help(void); extern void print_usage(void); /* pp.c */ void include_path_setup(void); void add_include_dir(char *dir); int pp_init(const char *name); void pp_done(void); int preprocess_config(const char *extpp); void pp_make_argcv(int *pargc, const char ***pargv); FILE *pp_extrn_start(int argc, const char **argv, pid_t *ppid); void pp_extrn_shutdown(pid_t pid); size_t pp_fill_buffer(char *buf, size_t size); void run_lint(); char *install_text(const char *str); /* accesslog.c */ void access_log_status(const char *first, const char *last); void access_log(int argc, char **argv); void compile_access_log(void); void access_log_free_cache(void); /* ident.c */ char *query_ident_name(struct sockaddr_in *srv_addr, struct sockaddr_in *clt_addr); /* alias.c */ int alias_install(const char *kw, int argc, char **argv, grecs_locus_t *ploc); int alias_expand(int argc, char **argv, int *pargc, char ***pargv); /* gsasl.c */ extern int sasl_enable; extern dico_list_t sasl_enabled_mech; extern dico_list_t sasl_disabled_mech; extern char *sasl_service; extern char *sasl_realm; extern dico_list_t sasl_anon_groups; void register_sasl(void); /* stratcl.c */ enum cmp_op { cmp_eq, cmp_ne, cmp_lt, cmp_le, cmp_gt, cmp_ge }; void stratcl_add_word(dico_list_t list, const char *word); void stratcl_add_cmp(dico_list_t list, enum cmp_op op, size_t len); void stratcl_add_disable(dico_list_t list); int stratcl_check_word(dico_list_t list, const char *word); /* ckpass.c */ int dicod_check_password(const char *db_pass, const char *pass); /* main.c */ void config_help(void); int database_session_visibility(dicod_database_t *db); /* virtual.c */ extern struct dico_database_module virtual_builtin_module; enum mime_cond { cond_any = -1, cond_mime, cond_nomime }; struct vdb_member { char *name; dicod_database_t *db; int cond; }; dico_list_t vdb_list_create(void);