/*
 * © Copyright 1996-2017 ECMWF.
 *
 * This software is licensed under the terms of the Apache Licence Version 2.0
 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
 * In applying this licence, ECMWF does not waive the privileges and immunities
 * granted to it by virtue of its status as an intergovernmental organisation nor
 * does it submit to any jurisdiction.
 */

#include "mars_client_config.h"

#include "hash.h"

/* tcp.c */
void socket_buffers(int s);
int writetcp(void *p, void *buf, u_int len);
boolean tcp_read_ready(int soc);
int readtcp(void *p, void *buf, u_int len);
boolean is_hostname(const char *host);
void traceroute(struct sockaddr_in *from);
int call_server(const char *host, int port, int retries);
int socket_close(int s);
int socket_file_close(FILE *f);

/* server.c */
struct sockaddr_in *addr_of(int soc);
int tcp_server(int port);
const char *host_of(struct sockaddr_in *from);
int port_of(struct sockaddr_in *from);
void print_address(const char *name, struct sockaddr_in *from);
void server_run(int port, taskproc task, void *data);
int server_mode(int *port, char *address);

/* udp.c */
int readudp(void *p, void *buf, u_int len);
int writeudp(void *p, void *buf, u_int len);
int udp_socket(int port);
udpinfo *udp_server(int port);
udpinfo *udp_call(const char *host, int port);
void udp_free(udpinfo *info);

/* service.c */
#if mars_client_HAVE_RPC
err encode_request(const request *r, XDR *x);
request *decode_request(XDR *x);
#endif /* mars_client_HAVE_RPC */
void destroy_service(svc *s);
err svc_connect(svc *s);
svc *create_service(const char *name);
void set_svc_err(svcid *id, err e);
err get_svc_err(svcid *id);
void set_svc_ref(svcid *id, long r);
long get_svc_ref(svcid *id);
const char *get_svc_target(svcid *id);
const char *get_svc_source(svcid *id);
const char *get_svc_msg(svcid *id, int n);
void set_svc_msg(svcid *id, const char *fmt, ...);
err send_drop_info(svc *s, char *target, request *r, long ref);
err send_message(svc *s, request *r);
err send_progress(svcid *id, const char *msg, request *r);
int fork_service(svcid *id);
err send_reply(svcid *id, request *r);
err send_later(svcid *id);
err send_number_reply(svcid *id, double d);
err send_string_reply(svcid *id, char *p);
err call_switchboard(svc *s, request *r);
err call_service(svc *s, const char *target, const request *r, long ref);
request *wait_service(svc *s, char *target, request *r, err *e);
err call_function(svc *s, const char *target, const request *r, long ref);
void keep_alive(svc *s, int alive);
void stop_all(svc *s, const char *p, int code);
void set_maximum(svc *s, int max);
void exit_timeout(svc *s, int timeout);
void add_progress_callback(svc *s, const char *name, svcproc p, void *data);
void add_reply_callback(svc *s, const char *name, svcproc p, void *data);
void add_drop_callback(svc *s, const char *name, svcproc p, void *data);
void add_message_callback(svc *s, const char *name, svcproc p, void *data);
void add_function_callback(svc *s, const char *name, svcproc p, const char *cmt, argdef *args, void *data);
void add_input_callback(svc *s, FILE *f, inputproc p, void *data);
void add_service_callback(svc *s, const char *name, svcproc p, void *data);
boolean service_ready(svc *s);
err re_dispatch(svcid *id, request *r);
err process_service(svc *s);
int service_sync(svc *s);
void service_run(svc *s);
request *pool_fetch(svc *s, const char *name, const char *clss);
void pool_store(svc *s, const char *name, const char *clss, const request *r);
void pool_link(svc *s, const char *name1, const char *name2);
void pool_link_objects(svc *s, request *r);
void recording(svc *s, boolean on);
void support_recording(svc *s);
void record_request(svc *s, char *name, request *r);
void record_function(svc *s, const char *name, argdef *args, va_list list);
void record_line(svc *s, const char *fmt, ...);
void show_help_page(svc *s, const char *page, char *topic);
void show_help_text(svc *s, const char *page, const char *topic, const char *fmt, ...);
void show_help_file(svc *s, const char *page, const char *topic, const char *file);
request *get_preferences(svc *s, const char *name);
void set_preferences(svc *s, request *r, const char *name);

/* queue.c */
#if mars_client_HAVE_RPC
err encode_netblk(XDR *x, netblk *blk);
err decode_netblk(XDR *x, netblk *blk);
void free_netblk(netblk *blk);
#endif
err qmonitor(char *fmt, ...);
err qenter(request *r);
err qleave(void);
err qslave(int port);
err qsync(void);
err qflush(int code);

/* request.c */
void str2range(const char *l, stepRange *r);
void patch_steprange(request *r);
boolean eq_range(const char *l, const char *r);
void paramtable(const char *p, long *param, long *table, boolean paramIdMode);
boolean eq_param(const char *l, const char *r);
boolean eq_string(const char *l, const char *r);
boolean eq_integer(const char *l, const char *r);
boolean eq_real(const char *l, const char *r);
boolean eq_coord(const char *l, const char *r);
boolean eq_null(const char *l, const char *r);
boolean eq_date(const char *l, const char *r);
boolean eq_time(const char *l, const char *r);
boolean eq_default(const char *l, const char *r);
char **mars_order(void);
int mars_order_count(void);
namecmp compare_parameters(const char *name);
boolean parsetime(const char *name, int *h, int *m, int *s);
boolean parsedate(const char *name, long *julian, long *second, boolean *isjul);
boolean isdate(const char *name);
boolean istime(const char *name);
boolean is_integer(const char *name);
boolean is_number(const char *name);
boolean isrange(const char *name);
long mars_julian_to_date(long jdate, boolean century);
long today(void);
long mars_date_to_julian(long ddate);
void check_for_to_by_list(parameter *p);
long get_julian_from_request(const request *req, int i);
boolean fetch(const request *r);
boolean observation(const request *r);
boolean image(const request *r);
boolean simulated_image(const request *r);
boolean gridded_observations(const request *r);
boolean feedback(const request *r);
boolean bias(const request *r);
boolean track(const request *r);
boolean is_bufr(const request *r);
boolean is_odb(const request *r);
boolean is_ocean(const request *r);
boolean is_grib(const request *r);
boolean wave2d(const request *r);
parameter *find_parameter(const request *r, const char *parname);
parameter *find_case_parameter(const request *r, const char *parname);
boolean value_exist(const request *r, const char *param, const char *val);
int count_values(const request *r, const char *parname);
const char *get_value(const request *r, const char *parname, int nth);
const char *case_get_param(const request *r, const char *parname);
const char *case_get_value(const request *r, const char *parname, int nth);
int case_count_values(const request *r, const char *parname, int nth);
const char *get_operator(const request *r, const char *parname, int nth);
void unset_value(request *r, const char *parname);
void set_value(request *r, const char *parname, const char *fmt, ...);
void set_value_int(request *r, const char *p, long64 v);
void add_value_int(request *r, const char *p, long64 v);
void set_list(request *r, const char *parname, const char *plist);
void add_unique_value(request *r, const char *parname, const char *fmt, ...);
void add_ordered_value(request *r, const char *parname, const char *fmt, ...);
void add_unique_ordered_value(request *r, const char *parname, const char *fmt, ...);
void add_value(request *r, const char *parname, const char *fmt, ...);
void set_value_long64(request *r, const char *parname, long64 l);
void add_value_long64(request *r, const char *parname, long64 l);
const char *request_verb(const request *r);
void values_loop(const request *r, int count, char *parnames[], loopproc callback, void *data);
request *new_request(char *name, parameter *p);
request *empty_request(const char *name);
parameter *new_parameter(char *name, value *v);
value *new_value(char *name);
value *new_expansion(value *val);
value *new_reference(const char *refname, char *name);
void save_one_request(FILE *f, const request *r);
void save_all_requests(FILE *f, const request *r);
void print_one_request(const request *r);
void print_all_requests(const request *r);
request *read_request_file(const char *fname);
request *unwind_one_request(const request *r);
request *custom_unwind_one_request(const request *r, int cnt, char *names[]);
void names_loop(const request *r, loopproc proc, void *data);
boolean all_is_used(const request *r);
int count_fields(request *r);
int count_fields_in_request(request *r);
int reqcmp(const request *a, const request *b, boolean verbose);
int field_order(const request *r, const request *u);
void valcpy(request *a, request *b, char *aname, char *bname);
void reqcpy(request *a, const request *b);
void reqmerge(request *a, const request *b);
void unset_param_value(request *r, const char *param, const char *par_val);
request *string2request(const char *p);
void value2string(value *r, char *buf);
void parameter2string(parameter *r, char *buf);
char *request2string(const request *r);
request *mars_language(void);
rule *mars_rules(void);
request *build_mars_request(request *r);
request *read_mars_request(const char *fname);
err handle_default(request *r, void *data);
void add_subrequest(request *r, const char *name, const request *s);
void set_subrequest(request *r, const char *name, const request *s);
request *get_subrequest(const request *r, const char *name, int n);
void notify_missing_field(const request *r, const char *name);
void sort_request(const request *r, int count, char *names[], char *vals[], void *data);
int count_requests(const request *r);
void reqcpy_no_underscores(request *a,const request *b);

/* expand.c */
void free_one_value(value *p);
void free_all_values(value *p);
void free_one_parameter(parameter *p);
void free_all_parameters(parameter *p);
void free_one_request(request *r);
void free_all_requests(request *p);
value *clone_one_value(const value *p);
value *clone_all_values(const value *p);
parameter *clone_one_parameter(const parameter *p);
parameter *clone_all_parameters(const parameter *p);
request *clone_one_request(const request *r);
request *clone_all_requests(const request *p);
void update_step_list(int p, int n, int by, value *v);
void check_for_date(parameter *p, value *r);
void check_for_time(parameter *p, value *r);
request *read_language_file(const char *name);
long expand_flags(long flags);
request *expand_all_requests(request *lang, rule *test, const request *r);
void reset_language(request *lang);
request *closest_verb(request *lang, const char *name);
parameter *closest_parameter(request *lang, const char *name);
void loopuk_language(request *lang, const char *v, const char *p, lookupproc c, void *d);
request *trim_all_requests(request *lang, request *r);
request *expand_mars_request(const request *r);
request *mars_language_from_request(const request *r);
void copy_to_ibm_values(request *r, const char *name);
void move_to_ibm_values(request *source, request *dest, const char *name);

/* calc.c */
func *mars_functions(void);
void print_math(math *m);
math *clone_math(math *m);
math *compmath(const char *formula);
void free_math(math *m);
err calculate(math *c, const char *f, void *data);
err handle_compute(request *r, void *data);

/* hidden.c */
request *un_first_guess(const request *r);
request *un_first_guess_all(const request *r);
void ensemble_to_number(request *r);
err add_hidden_parameters(request *r);
void patch_ranges(request *r);

/* environ.c */
void add_groups(const char *u, request *r);
boolean user_in_ABC_account(const char *user, const char *account, const request *env);
request *get_environ(void);
void set_environ(request *e);
void new_user(const char *u);

/* check.c */
void print_conditions(condition *c);
boolean old_expver_func(request *r, char *n, char *a);
boolean call_func(request *c, char *f, char *a);
boolean condition_check(request *c, condition *t);
rule *read_check_file(const char *fname);
void print_actions(action *a);
void print_rules(rule *r);
boolean doaction(rule *c, request *r, action *a);
boolean check_one_request(rule *c, request *r);
rule *new_rule(condition *c, action *a);
condition *new_condition(testop op, condition *l, condition *r);
action *new_action(actop op, void *parm);
condition *clone_condition(condition *c);
void free_action(action *a);
void free_condition(condition *c);
void free_rule(rule *r);

/* hypercube.c */
int axisindex(const char *name);
namecmp comparator(const char *name);
void print_hypercube_index(const hypercube *h);
int cube_order(const hypercube *h, const request *r);
int _cube_position(const hypercube *h, const request *r, boolean remove_holes);
boolean cube_contains(const hypercube *h, const request *r);
void cube_indexes(const hypercube *h, request *r, int *indexes, int size);
hypercube *new_hypercube(const request *r);
int add_field_to_hypercube(hypercube *h, request *r);
int remove_field_from_hypercube(hypercube *h, request *r, int n);
void remove_name_from_hypercube(hypercube *h, const char *ignore);
void print_hypercube(const hypercube *h);
void free_hypercube(hypercube *h);
request *_get_cubelet(hypercube *h, int index);
request *get_cubelet(hypercube *h, int index);
request *next_cubelet(hypercube *h, int *from, int *last);
hypercube *merge_cube(const hypercube *a, const hypercube *b, int init, int va, int vb);
hypercube *new_hypercube_from_mars_request(const request *r);
hypercube *new_simple_hypercube_from_mars_request(const request *r);
hypercube *new_hypercube_from_fieldset_cb(fieldset *fs, void (*callback )(request *, void *), void *data);
hypercube *new_hypercube_from_fieldset(fieldset *fs);
hypercube *new_hypercube_from_file(const char *path);
hypercube *add_cube(const hypercube *a, const hypercube *b);
hypercube *remove_cube(const hypercube *a, const hypercube *b);
int hypercube_field_count(const hypercube *a);
int hypercube_cube_size(const hypercube *a);
int hypercube_compare(const hypercube *a, const hypercube *b);

/* memory.c */
int getpagesize(void);
void mem_exit_on_failure(boolean n);
void *re_alloc(void *p, long64 size);
char *new_string(const char *p);
void *get_mem(long64 size);
void *get_mem_clear(long64 size);
void *free_mem(void *x);
void *fast_new(long64 s, mempool *pool);
void *fast_realloc(void *p, long64 s, mempool *pool);
void fast_delete(void *p, mempool *pool);
void *reserve_mem(long64 s);
void release_mem(void *p);
void memory_info(void);
void *fast_new(long64 s, mempool *pool);
void *fast_realloc(void *p, long64 s, mempool *pool);
void fast_delete(void *p, mempool *pool);
void fast_memory_info(const char *title, mempool *pool);
void memory_info(void);
void release_mem(void *p);
int purge_mem(void);
void install_memory_proc(memproc proc, void *data);
void remove_memory_proc(memproc proc, void *data);

/* tools.c */
boolean init_process(void);
long64 proc_mem(void);
long64 proc_mem(void);
long64 proc_mem(void);
double proc_cpu(void);
const char *user(const char *s);
err mars_compress(void *in, void *out, long inlen, long *outlen);
err mars_uncompress(void *in, void *out, long inlen, long *outlen);
const char *no_quotes(const char *in);
int casecompare(const char *a, const char *b);
void start_timer(void);
char *timename(double t);
double stop_timer(char *text);
clock_t timer_cpu(void);
const char *bytename(double bytes);
int mkdirp(const char *path, int mode);
const char *makepath(const char *dname, const char *fname);
const char *mbasename(const char *fname);
const char *mdirname(const char *fname);
int deletefile(const char *name);
int movefile(const char *from, const char *to);
int copylink(const char *from, const char *to);
int copydata(const char *from, const char *to);
int copydir(const char *from, const char *to);
int mars_copyfile(const char *from, const char *to);
const char *relpath(const char *from, const char *to);
void dumpenv(void);
int faccess(const char *fname, int flags);
const char *lowcase(const char *p);
const char *upcase(const char *p);
void print_environment(FILE *f);
FILE *mail_open(const char *to, char *fmt, ...);
void notify_user(const char *what, const request *r);
FILE *mail_once(const char *mark, const char *to, char *fmt, ...);
void mail_msg(FILE *f, char *fmt, ...);
void mail_request(FILE *f, const char *msg, const request *r);
void mail_close(FILE *f);
const char *real_name(const char *fname);
void nfs_lookup(const char *fname, char *host, char *path);
boolean if_check(const char *host);
boolean if_check(const char *p);
void check_nfs_target(const char *path);
long grib_length(const char *buffer, long length);
void mars_grib_api_init(void);
void mars_fdb5_init(int *argc, char **argv);
void mars_eckit_init(int *argc, char **argv);
long _readany(FILE *f, char *b, long *l);
long _readgrib(FILE *f, char *b, long *l);
long _readbufr(FILE *f, char *b, long *l);
void touch(const char *path);
time_t age(const char *path);
long preferred_IO_blocksize(const char *path, long base);
double round_decimal(double f);
long64 atoll(const char *str);
void print_memory_usage(char *s);

/* list.c */
boolean in_list(marslist *l, const char *name, void *data);
void add_to_list(marslist **l, const char *name, void *data);

/* timer.c */
timer *get_timer(const char *name, const char *statname, boolean elapsed);
int timer_start(timer *t);
int timer_stop(timer *t, long64 total);
double timer_value(timer *t);
void timer_print_to_file(timer *t, FILE *f);
void timer_print(timer *t);
void timer_partial_rate(timer *t, double start, long64 total);
void print_all_timers(void);
void reset_all_timers(void);
int timed_fread(char *buffer, int n, int length, FILE *f, timer *t);
int timed_wind_next(wind *w, FILE *f, char *buffer, long *length, timer *t);
int timed_fwrite(char *buffer, int n, int length, FILE *f, timer *t);
int timed_fclose(FILE *f, timer *t);
int timed_writetcp(void *data, char *buffer, int n, timer *t);
int timed_readtcp(void *data, char *buffer, int n, timer *t);
int timed_readany(FILE *f, char *buffer, long *length, timer *t);

/* logfile.c */
void marsdebug(boolean on);
FILE *marslogfile(FILE *f);
void mars_grib_api_log(const grib_context *c, int level, const char *msg);
void marslog(int level, const char *fmt, ...);
void log_errors(void);
void install_exit_proc(exitproc p, void *data);
void remove_exit_proc(exitproc p, void *data);
void _marsexit(void);
void marsexit(int code);
void dumpmem(void);

/* options.c */
void get_options(const char *clss, const char *name, void *addr, int count, option opts[]);
char *progname(void);
void trap_all_signals(void);
void marsinit(int *argc, char **argv, void *addr, int count, option opts[]);
const char *config_file(const char *p);

/* files.c */
char *marstmp(void);

/* stream.c */
void stream_write_char(mstream *s, char c);
void stream_write_uchar(mstream *s, unsigned char c);
void stream_write_int(mstream *s, int c);
void stream_write_uint(mstream *s, unsigned int c);
void stream_write_long(mstream *s, long c);
void stream_write_ulong(mstream *s, unsigned long c);
void stream_write_longlong(mstream *s, long64 n);
void stream_write_ulonglong(mstream *s, ulong64 n);
void stream_write_double(mstream *s, double x);
void stream_write_short(mstream *s, short c);
void stream_write_ushort(mstream *s, unsigned short c);
void stream_write_string(mstream *s, const char *p);
void stream_write_blob(mstream *s, const void *d, long len);
void stream_write_start(mstream *s, const char *p);
void stream_write_end(mstream *s);
char stream_read_char(mstream *s);
unsigned char stream_read_uchar(mstream *s);
int stream_read_int(mstream *s);
unsigned int stream_read_uint(mstream *s);
long stream_read_long(mstream *s);
unsigned long stream_read_ulong(mstream *s);
short stream_read_short(mstream *s);
unsigned short stream_read_ushort(mstream *s);
const char *stream_read_string(mstream *s);
const void *stream_read_blob(mstream *s, long *size);
long64 stream_read_longlong(mstream *s);
ulong64 stream_read_ulonglong(mstream *s);
const char *stream_read_start(mstream *s);
void stream_read_end(mstream *s);
void make_socket_stream(mstream *s, int *soc);
void make_file_stream(mstream *s, FILE *f);

/* cos.c */
COSFILE *cos_open(const char *fname);
int cos_read(COSFILE *cf, char *buf, long *len);
int cos_write(COSFILE *cf, char *buf, long len);
int cos_close(COSFILE *cf);
void COSOPEN(COSFILE **filedesc, char *fname, long *e);
void COSCLOSE(COSFILE **filedesc, long *e);
void COSREAD(COSFILE **filedesc, char *buffer, long *len, long *e);

/* time.c */
datetime date_time_2_datetime(long julian_date, long hour, long min, long sec);
datetime key_2_datetime(const packed_key *keyptr);
void init_time_interval(time_interval *t, datetime begin, long range);

/* guess.c */
char *guess_class(const char *file);

/* statistics.c */
err locked_write(const char *fname, char *str, long len);
void init_statistics(const request *r, const request *e);
void log_statistics(const char *name, const char *fmt, ...);
void log_statistics_unique(const char *name, const char *fmt, ...);
void flush_statistics(const request *r, const request *env);
void test_statistics(void);

/* udp_statistics.cc */
void send_udp_statistics(const request *stats, const request *env, const request *r);

/* metadata.c */
request *read_request(mstream *s);

/* free.c */
err encode_free_format(void *buffer, long *length, const request *r, const void *blob, long bloblen);
request *decode_free_format_request(void *buffer, long length);
long decode_free_format_blob(void *buffer, long length, void *blob, long max);
err encode_free_format_grib(unsigned char *bin, unsigned char *bout, fortint *length, fortint maxlen, request *r, int marsclass, int type, int stream, char *expver);
err decode_free_format_grib(unsigned char *bin, unsigned char *bout, fortint *length, fortint maxlen, request *r);
err original_grib(char *bin, fortint *length);

/* index.c */
void mars_field_index_add(mars_field_index *idx, const char *name, boolean s_ok, const char *s, boolean l_ok, long l, boolean d_ok, double d);
mars_field_index *mars_field_index_new(off_t offset, long length);
err mars_field_index_send(mars_field_index *idx, mstream *s);
void mars_field_index_free(mars_field_index *idx);
void mars_field_index_print(mars_field_index *idx);

/* api.c */
void ecmwf_api_set_msg_callback(ecmwf_api *api, messageproc msgcb, void *data);
void ecmwf_wait_for_data(ecmwf_api *api, size_t size);
size_t ecmwf_api_transfer_read(ecmwf_api *api, void *ptr, size_t size);
const json_value *_ecmwf_api_call(ecmwf_api *api, const char *method, const char *url, const char *json);
const char *ecmwf_api_must_retry(ecmwf_api *api);
const json_value *ecmwf_api_call(ecmwf_api *api, const char *method, const char *url, const char *json);
ecmwf_api *ecmwf_api_create(const char *url, const char *key, const char *email);
void ecmwf_api_add_message_callback(ecmwf_api *api, void (*cb )(const char *));
void ecmwf_api_destroy(ecmwf_api *api);
int ecmwf_api_in_progress(ecmwf_api *api);
int ecmwf_api_transfer_ready(ecmwf_api *api);
void ecmwf_api_in_wait(ecmwf_api *api);
const char *ecmwf_api_location(ecmwf_api *api);
const char *ecmwf_api_content_type(ecmwf_api *api);
int ecmwf_api_error(ecmwf_api *api);
void ecmwf_api_verbose(ecmwf_api *api, int v);
long long ecmwf_api_transfer_start(ecmwf_api *api, const char *url, typeproc typecb, void *typecb_data);
int ecmwf_api_transfer_end(ecmwf_api *api);

/* json.c */
void json_free(json_value *v);
const char *json_get_string(const json_value *v);
long long json_get_integer(json_value *v);
const char *json_encode_string(const char *s, char *out);
void json_save(const json_value *v, FILE *f);
void json_print(const json_value *v);
void json_println(const json_value *v);
json_value *json_new_string(const char *s);
json_value *json_new_array(void);
json_value *json_new_object(void);
void json_object_set_item(json_value *object, const char *key, json_value *value);
void json_array_push_item(json_value *object, json_value *k);
json_value *json_parse_string(const char *str, size_t len);
void json_array_each(json_value *a, void (*proc )(int, json_value *, void *), void *data);
void json_object_each(json_value *a, void (*proc )(const char *, json_value *, void *), void *data);
json_value *json_object_find(const json_value *a, const char *key);
json_value *json_read_file(const char *path);

/* base.c */
base_class *base_class_by_name(const char *name);
database *database_of(void *data);
const char *database_name(void *data);
err database_validate(base_class *driver, const char *name, request *r, request *e, int mode);
database *database_open(base_class *driver, const char *name, request *r, request *e, int mode);
err database_read(database *b, request *r, void *buffer, long *length);
err database_write(database *b, request *r, void *buffer, long *length);
err database_control(database *b, int code, void *param, int size);
err database_archive(database *b, request *r);
boolean database_check(database *b, request *r);
err database_close(database *b);
void database_admin(base_class *driver);

/* netbase.c */
void basetask(int soc, int count, void *data);

/* nullbase.c */

/* handler.c */
err handle_request(request *r, void *data);
err handle_end(request *r, void *data);

/* nfdbbase.c */
boolean windgust(request *s);
void request_to_fdb(int ref, request *r, int y2k);

/* msbase.c */

/* gribbase.c */

/* filebase.c */

/* dhsbase.c */
int find_long(long *p, int count, long search);

/* flatfilebase.c */

/* target.c */
char *target_open_mode(const char *target);
err send_remote_targets(void);

/* feedtask.c */
void feedtask(int soc, int count, void *data);

/* rdb.c */

/* multibase.c */

/* odbbase.c */

/* apibase.c */

/* archive.c */
err feed(database *bout, request *r);
err handle_archive(request *r, void *data);

/* retrieve.c */
boolean enough(request *r, int count);
request *findbase(const char *name);
database *openbase(request *s, request *r, const char **name, request **cache, int mode);
void mars_task(void);
err handle_retrieve(request *r, void *data);

/* control.c */
err handle_control(request *r, void *data);

/* remove.c */
err handle_remove(request *r, void *data);

/* grib.c */
err handle_to_request(request *r, grib_handle *g, mars_field_index *idx);
err grib_to_request_index(request *r, char *buffer, long length, mars_field_index *idx);
err grib_to_request(request *r, char *buffer, long length);

/* pproc.c */
err ppstyle(const request *r);
err pprotation(const request *r);
err pparea(request *r);
err makeuv(char *vo, char *d, long inlen, char *u, char *v, long *outlen);
long ppestimate(void);
err ppinit(const request *r, postproc *proc);
err ppdone(void);
err ppcount(int *in, int *out);
fieldset *pp_fieldset(const char *file, request *filter);

/* wind.c */
wind *wind_new(request *r, long64 *total, boolean active);
void wind_free(wind *w);
boolean is_wind(long param);
err wind_next(wind *w, FILE *f, char *buffer, long *length, timer *t);

/* bufr.c */
unsigned long getbits(unsigned char *p, int skip, int len);
unsigned long key_length(const char *buffer, const packed_key *k);
void set_key_length(packed_key *key, unsigned long keylength);
boolean get_packed_key(char *buffer, packed_key *k);
boolean get_packed_section_1(char *buffer, packed_section_1 *section);
int subset_count(char *buffer);
int bufr_sat_id(char *buffer, packed_key *k);
void set_bufr_sat_id(char *buffer, int id, packed_key *k);
boolean replace_key(char *buffer, packed_key *key);
boolean patch_key_date(char *buffer, int y, int m, int d, int H, int M, int S);
boolean patch_key_ident(char *buffer, int ident);
boolean patch_key_length(char *buffer, unsigned int new_value);
boolean shift_packed_key_ident(char *buffer);
void set_bufr_mars_type(request *r, const packed_key *key);
err bufr_to_request(request *r, char *buffer, long length);
boolean verify_bufr_key(const char *buffer, long length, const packed_key *key);
void print_key_date(const packed_key *keyptr, char *s);
void print_key_time(const packed_key *keyptr, char *s);
int build_packed_key(char *buffer, fortint length, packed_key *k);
void print_packed_key(char *buffer, packed_key *k);

/* field.c */
gribfile *new_gribfile(const char *name);
FILE *open_gribfile(gribfile *g, const char *mode);
void close_gribfile(gribfile *g);
void free_gribfile(gribfile *g);
field_request *new_field_request(request *r);
void free_field_request(field_request *g);
void mars_free_field(field *g);
void free_fieldset(fieldset *v);
field *mars_new_field(void);
fieldset *new_fieldset(int n);
field *read_field(gribfile *file, off_t pos, long length);
err add_field(fieldset *v, field *g);
err set_field(fieldset *v, field *g, int pos);
err check_fieldset(fieldset *v, int expect);
field *copy_field(field *gx, boolean copydata);
void copy_missing_vals(field *gc, field *ga, field *gb);
void remove_bitmap(field *gc);
void set_bitmap(field *gc);
fieldset *copy_fieldset(fieldset *x, int count, boolean copydata);
fieldset *merge_fieldsets(fieldset *x, fieldset *y);
fieldset *sub_fieldset(fieldset *v, int from, int to, int step);
int best_packing(fortint current);
void set_field_state(field *g, field_state shape);
field *get_field(fieldset *v, int n, field_state shape);
field *get_nonmissing_field(fieldset *v, field_state shape);
void inform_missing_fieldset(const char *name);
void release_field(field *g);
const void *field_message(field *g, long *s);
err write_field(FILE *f, field *g);
err save_fieldset(fieldset *v);
fieldset *read_fieldset(const char *fname, request *filter);
fieldset *request_to_fieldset(request *r);
request *fieldset_to_request(fieldset *v);
request *fieldset_to_mars_request(fieldset *fs);
request *field_to_request(field *f);

/* variable.c */
err push_scalar(double d);
err push_named_scalar(char *name, double d);
err push_fieldset(fieldset *f);
err push_named_fieldset(char *name, fieldset *f);
err push(variable *v);
variable *pop(void);
variable *stack_top(void);
variable *find_variable(const char *name);
err name_variable(variable *v, char *name);
variable *new_variable(const char *name, fieldset *f, double d);
void free_variable(variable *v);

/* externf.c */
err extern_func(math *p);

/* sh2ll.c */
err write_fieldset(fieldset *v, database *b);
err handle_read(request *r, void *data);
err handle_write(request *r, void *data);

/* account.c */
err ams_validate(request *r, request *e);
err ecmwf_validate(request *r, request *e);
int eccert_validate(request *r, request *e);
err null_validate(request *r, request *e);
err validate_request(request *r, request *e, const char *method);

/* authenticate.c */
boolean handle_restriction(request *req, request *r, request *reply, void *data);
err local_validate_request(request *req, request *env);
void print_user_restrictions(request *env, request *auth);

/* certify.c */
err certify(request *r, request *e, char *data, int length);

/* eccert.c */
char *verify_ecmars_certificate(char *data, int len, char *marsCert, int marsCertLen, eCMarsCertReply *reply);

/* restricted.c */
int restricted(void *p);

/* version.c */
long marsversion(void);
const char *marssourcebranch(void);
long marsgribapi(void);
long marsodbapi(void);

/* schedule.c */
boolean check_dissemination_schedule(request *user, request *env, boolean logstat);

/* netcdf.c */
boolean source_is_netcdf(const request* r);
boolean message_is_netcdf(unsigned char*);
request* netcdf_to_request(const char *path, int merge, mars_field_index *idx, err* e);

/* hdf5.c */
err check_hdf5_superblock(const char* path);

/* nctarget.c */
netcdf_target *netcdf_target_new(const char *path, const char *format, int more_flags);
err netcdf_target_close(netcdf_target *target);
err netcdf_target_add_buffer(netcdf_target *target, const void* message, size_t length);
err netcdf_target_add_file(netcdf_target *target, const char *path);
/*----------*/
netcdf_schema* netcdf_schema_new(const char *path);
void netcdf_schema_delete(netcdf_schema* s);
request* netcdf_schema_to_request(netcdf_schema *s, int merge, mars_field_index *idx, err* e);
