ossp-pkg/lmtp2nntp/lmtp2nntp_dotconf.h
#ifndef DOTCONF_H
#define DOTCONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* stdio.h should be included by the application - as the manual page says */
#ifndef _STDIO_H
#include <stdio.h> /* needed for FILE* */
#endif
#ifdef WIN32
# ifndef R_OK
#define R_OK 0
# endif
#endif
/* some buffersize definitions */
#define CFG_BUFSIZE 4096 /* max length of one line */
#define CFG_MAX_OPTION 32 /* max length of any option name */
#define CFG_MAX_VALUE 4064 /* max length of any options value */
#define CFG_MAX_FILENAME 256 /* max length of a filename */
#define CFG_VALUES 16 /* max # of arguments an option takes */
#define CFG_INCLUDEPATH_ENV "DC_INCLUDEPATH"
#define WILDCARDS "*?" /* list of supported wild-card characters */
/* constants for type of option */
#define ARG_TOGGLE 0 /* TOGGLE on,off; yes,no; 1, 0; */
#define ARG_INT 1 /* callback wants an integer */
#define ARG_STR 2 /* callback expects a \0 terminated str */
#define ARG_LIST 3 /* wants list of strings */
#define ARG_NAME 4 /* wants option name plus ARG_LIST stuff */
#define ARG_RAW 5 /* wants raw argument data */
#define ARG_NONE 6 /* does not expect ANY args */
#define CTX_ALL 0 /* context: option can be used anywhere */
/* for convenience of terminating the dotconf_options list */
#define LAST_OPTION { "", 0, NULL, NULL }
#define LAST_CONTEXT_OPTION { "", 0, NULL, NULL, 0 }
#define DOTCONF_CB(__name) const char *__name(command_t *cmd, \
context_t *ctx)
#define FUNC_ERRORHANDLER(_name) int _name(configfile_t * configfile, \
int type, long dc_errno, const char *msg)
/* some flags that change the runtime behaviour of dotconf */
#define NONE 0
#define CASE_INSENSITIVE 1<<0 /* match option names case insensitive */
#define DONT_SUBSTITUTE 1<<1 /* do not call substitute_env after read_arg */
/* syslog style errors as suggested by Sander Steffann <sander@steffann.nl> */
#ifdef HAVE_SYSLOG
#include <syslog.h>
#define DCLOG_EMERG LOG_EMERG /* system is unusable */
#define DCLOG_ALERT LOG_ALERT /* action must be taken immediately */
#define DCLOG_CRIT LOG_CRIT /* critical conditions */
#define DCLOG_ERR LOG_ERR /* error conditions */
#define DCLOG_WARNING LOG_WARNING /* warning conditions */
#define DCLOG_NOTICE LOG_NOTICE /* normal but significant condition */
#define DCLOG_INFO LOG_INFO /* informational */
#define DCLOG_DEBUG LOG_DEBUG /* debug-level messages */
#define DCLOG_LEVELMASK LOG_PRIMASK /* mask off the level value */
#else /* HAVE_SYSLOG */
#define DCLOG_EMERG 0 /* system is unusable */
#define DCLOG_ALERT 1 /* action must be taken immediately */
#define DCLOG_CRIT 2 /* critical conditions */
#define DCLOG_ERR 3 /* error conditions */
#define DCLOG_WARNING 4 /* warning conditions */
#define DCLOG_NOTICE 5 /* normal but significant condition */
#define DCLOG_INFO 6 /* informational */
#define DCLOG_DEBUG 7 /* debug-level messages */
#define DCLOG_LEVELMASK 7 /* mask off the level value */
#endif /* HAVE_SYSLOG */
/* callback types for dotconf_callback */
/* error constants */
#define ERR_NOERROR 0x0000
#define ERR_PARSE_ERROR 0x0001
#define ERR_UNKNOWN_OPTION 0x0002
#define ERR_WRONG_ARG_COUNT 0x0003
#define ERR_INCLUDE_ERROR 0x0004
#define ERR_NOACCESS 0x0005
#define ERR_USER 0x1000 /* base for userdefined errno's */
/* i needed this to check an ARG_LIST entry if it's toggled in one of my apps; maybe you do too */
#define CFG_TOGGLED(_val) ( (_val[0] == 'Y' \
|| _val[0] == 'y') \
|| (_val[0] == '1') \
|| ((_val[0] == 'o' \
|| _val[0] == 'O') \
&& (_val[1] == 'n' \
|| _val[1] == 'N')))
enum callback_types
{
ERROR_HANDLER = 1,
CONTEXT_CHECKER
};
typedef enum callback_types callback_types;
typedef struct configfile_t configfile_t;
typedef struct configoption_t configoption_t;
typedef struct configoption_t ConfigOption;
typedef struct command_t command_t;
typedef void context_t;
typedef void info_t;
typedef const char *(*dotconf_callback_t)(command_t *, context_t *);
typedef int (*dotconf_errorhandler_t)(configfile_t *, int, unsigned long, const char *);
typedef const char *(*dotconf_contextchecker_t)(command_t *, unsigned long);
struct configfile_t
{
/* ------ the fields in configfile_t are provided to the app via command_t's ; READ ONLY! --- */
FILE *stream;
char eof; /* end of file reached ? */
size_t size; /* file size; cached on-demand for here-documents */
context_t *context;
configoption_t const **config_options;
int config_option_count;
/* ------ misc read-only fields ------------------------------------------------------------- */
char *filename; /* name of file this option was found in */
unsigned long line; /* line number we're currently at */
unsigned long flags; /* runtime flags given to dotconf_open */
char *includepath;
/* ------ some callbacks for interactivity -------------------------------------------------- */
dotconf_errorhandler_t errorhandler;
dotconf_contextchecker_t contextchecker;
int (*cmp_func)(const char *, const char *, size_t);
};
struct configoption_t
{
const char *name; /* name of configuration option */
int type; /* for possible values, see above */
dotconf_callback_t callback; /* callback function */
info_t *info; /* additional info for multi-option callbacks */
unsigned long context; /* context sensitivity flags */
};
struct command_t
{
const char *name; /* name of the command */
configoption_t *option; /* the option as given in the app; READ ONLY */
/* ------ argument data filled in for each line / command ----------------------------------- */
struct {
long value; /* ARG_INT, ARG_TOGGLE */
char *str; /* ARG_STR */
char **list; /* ARG_LIST */
} data;
int arg_count; /* number of arguments (in data.list) */
/* ------ misc context information ---------------------------------------------------------- */
configfile_t *configfile;
context_t *context;
};
/* ------ dotconf_create() - create the configfile_t needed for further dot.conf fun ------------ */
configfile_t *dotconf_create(char *, const configoption_t *, context_t *, unsigned long);
/* ------ dotconf_cleanup() - tidy up behind dotconf_create and the parser dust ----------------- */
void dotconf_cleanup(configfile_t *configfile);
/* ------ dotconf_command_loop() - iterate through each line of file and handle the commands ---- */
int dotconf_command_loop(configfile_t *configfile);
/* ------ dotconf_command_loop_until_error() - like continue_line but return on the first error - */
const char *dotconf_command_loop_until_error(configfile_t *configfile);
/* ------ dotconf_continue_line() - check if line continuation is to be handled ----------------- */
int dotconf_continue_line(char *buffer, size_t length);
/* ------ dotconf_get_next_line() - read in the next line of the configfile_t ------------------- */
int dotconf_get_next_line(char *buffer, size_t bufsize, configfile_t *configfile);
/* ------ dotconf_get_here_document() - read the here document until delimit is found ----------- */
char *dotconf_get_here_document(configfile_t *configfile, const char *delimit);
/* ------ dotconf_invoke_command() - call the callback for command_t ---------------------------- */
const char *dotconf_invoke_command(configfile_t *configfile, command_t *cmd);
/* ------ dotconf_find_command() - iterate through all registered options trying to match ------- */
configoption_t *dotconf_find_command(configfile_t *configfile, const char *command);
/* ------ dotconf_read_arg() - read one argument from the line handling quoting and escaping ---- */
/*
side effects: the char* returned by dotconf_read_arg is malloc() before, hence that pointer
will have to be free()ed later.
*/
char *dotconf_read_arg(configfile_t *configfile, char **line);
/* ------ dotconf_handle_command() - parse, substitute, find, invoke the command found in buffer */
const char *dotconf_handle_command(configfile_t *configfile, char *buffer);
/* ------ dotconf_register_option() - add a new option table to the list of commands ------------ */
void dotconf_register_options(configfile_t *configfile, const configoption_t *options);
/* ------ dotconf_warning() - handle the dispatch of error messages of various levels ----------- */
int dotconf_warning(configfile_t *configfile, int level, unsigned long errnum, const char *, ...);
/* ------ dotconf_callback() - register a special callback -------------------------------------- */
void dotconf_callback(configfile_t *configfile, callback_types type, dotconf_callback_t);
/* ------ dotconf_substitute_env() - handle the substitution on environment variables ----------- */
char *dotconf_substitute_env(configfile_t *, char *);
/* ------ internal utility function that verifies if a character is in the WILDCARDS list -- */
int dotconf_is_wild_card(char value);
/* ------ internal utility function that calls the appropriate routine for the wildcard passed in -- */
int dotconf_handle_wild_card(command_t* cmd, char wild_card, char* path, char* pre, char* ext);
/* ------ internal utility function that frees allocated memory from dotcont_find_wild_card -- */
void dotconf_wild_card_cleanup(char* path, char* pre);
/* ------ internal utility function to check for wild cards in file path -- */
/* ------ path and pre must be freed by the developer ( dotconf_wild_card_cleanup) -- */
int dotconf_find_wild_card(char* filename, char* wildcard, char** path, char** pre, char** ext);
/* ------ internal utility function that compares two stings from back to front -- */
int dotconf_strcmp_from_back(const char* s1, const char* s2);
/* ------ internal utility function that determins if a string matches the '?' criteria -- */
int dotconf_question_mark_match(char* dir_name, char* pre, char* ext);
/* ------ internal utility function that determins if a string matches the '*' criteria -- */
int dotconf_star_match(char* dir_name, char* pre, char* ext);
/* ------ internal utility function that determins matches for filenames with -- */
/* ------ a '?' in name and calls the Internal Include function on that filename -- */
int dotconf_handle_question_mark(command_t* cmd, char* path, char* pre, char* ext);
/* ------ internal utility function that determins matches for filenames with -- */
/* ------ a '*' in name and calls the Internal Include function on that filename -- */
int dotconf_handle_star(command_t* cmd, char* path, char* pre, char* ext);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* DOTCONF_H */