#ifndef _DW_OPTIONS_H
#define _DW_OPTIONS_H

/*--------------------------------------------------------------------------
 *  Copyright (c) 2001-2004 Igor Daniloff. 
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at this directory.
 *------------------------------------------------------------------------*/
 
/* $Id: dw_options.h,v 1.81 2008/11/11 19:12:26 akorkov Exp $ */

#include <stdio.h>
#if defined(__UNIX_DW)
#include <syslog.h>
#endif /* __UNIX_DW */
#if defined(DW_SENDMAIL)
#include "libmilter/mfapi.h"
#endif /* SENDMAIL */
#include "dwc_type.h"
#include "dwc_strings.h"
#include "dwc_conf.h"
#include "dwc_ipc.h"
#if defined(DW_COURIER)
#include "dwc_unix.h"
#endif /* COURIER */
#if !defined(DW_SAMBA)
#include "dw_users.h"
#include "dw_viruses.h"
#include "dw_addresses.h"
#endif /* not SAMBA */

#if !defined(DW_CGP) && !defined(DW_ZMAILER) && !defined(DW_COURIER) && !defined(DW_MIO) && !defined(DW_SAMBA)
#define DW_HAVE_SPOOL
#else /* CGP or ZMAILER or COURIER or SAMBA or MIO */    
#undef  DW_HAVE_SPOOL
#endif /* not CGP and not ZMAILER and not COURIER and not SAMBA and not MIO */    

#if !defined(DW_ZMAILER) && !defined(DW_MIO) 
#define DW_HAVE_DISCARD
#else /* ZMAILER or MIO */    
#undef  DW_HAVE_DISCARD
#endif /* not ZMAILER and not MIO */    

#define DW_HAVE_A_PATH( p ) ( ((p) && (strlen((p)) > 0)) ? TRUE : FALSE )

#if defined(DW_SAMBA)
typedef dwc_bitset_t        dwc_scanmode_t;
#define DW_SM_ON_READ       (1<<0)
#define DW_SM_ON_WRITE      (1<<1)
#define DW_SM_ON_READWRITE  (DW_SM_ON_READ | DW_SM_ON_WRITE)
#define DW_SM_ON_ACCESS     DW_SM_ON_READWRITE
#endif /* SAMBA */

typedef int                 dwc_level_t;

typedef int                 dwc_naming_t;
#define DW_NAME_STD         (1) /* mkstemp (6 symbols) */
#define DW_NAME_RAND48      (2) /* lrand48 instead mkstemp (8 symbols) */
#define DW_NAME_TAI         (3) /* tai format */

typedef struct {
    dwc_path_t      tf_path;
    dwc_string_t    tf_prefix;
    dwc_naming_t    tf_naming;
    dwc_mode_t      tf_access;
} dwc_tmpfiles_t;

#if !defined(DW_MIO) && !defined(DW_SAMBA)
typedef int                 dwc_deny_mode_t;
#define DW_DM_INTERNAL_ERROR0      0
#define DW_DM_ALL                  1 /* block if: sender and all recipients - DenyOnOne = no */
#define DW_DM_ONE                  2 /* block if: sender or one recipient - DenyOnOne = yes */
#define DW_DM_SENDER_AND_ONE_RCPT  3 /* block if: sender and one recipient */
#define DW_DM_SENDER               4 /* block if: sender, recipients aren`t checked */
#define DW_DM_ONE_RCPT             5 /* block if: one recipient, sender isn`t checked */
#define DW_DM_ALL_RCPTS            6 /* block if: all recipient, sender isn`t checked */
#define DW_DM_INTERNAL_ERRORM      7
#endif /* not MIO and not SAMBA */

typedef enum {
    DW_ACT_INTERNAL_ERROR0,
    DW_ACT_PASS,
    DW_ACT_REJECT,
    DW_ACT_QUARANTINE,
#if !defined(DW_MIO) 
    DW_ACT_DELETE,
    DW_ACT_CURE,
    DW_ACT_DISCARD,
#if !defined(DW_SAMBA)
    DW_ACT_TEMPFAIL,
    DW_ACT_CONTINUE,
    DW_ACT_REDIRECT,
#else /* SAMBA */
    DW_ACT_RENAME,
#endif /* not SAMBA */    
#else /* MIO */
    DW_ACT_ERROR,
#endif /* MIO */
#if defined(__WIN32_DW) && defined(DW_CGP)
    DW_ACT_LICENSE,
#endif /* WIN32 and CGP */
    DW_ACT_INTERNAL_ERRORM
} dwc_action_t;

#if !defined(DW_SAMBA)
typedef struct {
#if !defined(DW_MIO)
    dwc_bool_t      to_sender;
    dwc_bool_t      to_admin;
    dwc_bool_t      to_rcpts;
    dwc_path_t      rcpts_template;    
    dwc_path_t      admin_template;    
    dwc_path_t      sender_template;    
#else /* MIO */
    dwc_path_t      notify_template;
#endif /* not MIO */
} dwcf_notify_opt_t;
#endif /* not SAMBA */

#if !defined(DW_SAMBA)

#if defined(DW_SENDMAIL)
#define DRWEB_HASH_HEADER       "X-drweb-hash"
#define DRWEB_HASH_FULLHEADER   DRWEB_HASH_HEADER": "
typedef char dwc_hash_t[33]; /* asv: 16 * 2 + 1 */
typedef char dwc_string_16[16];
typedef struct {
    dwc_string_t        addr;
    dwc_timeout_t       timeout;
    int                 dbg_level;
    int                 backlog;
} dwcf_milter_opt_t; 
#endif /* SENDMAIL */

#if defined(DW_COURIER)
typedef struct {
    dwc_path_t          basedir;
    dwc_path_t          socketdir;
    int                 backlog;
    dwc_mode_t          access;
    DWC_unix_socket_t   socket_fd;                 
} dwcf_courier_opt_t;
#endif /* COURIER */

#endif /* not SAMBA */

#if !defined(__WIN32_DW)
/* --- [DaemonCommunication] --- */
typedef struct {
    dwc_multistring_t   addr;   
    dwc_bool_t          cache;
    dwc_timeout_t       timeout;    
    dwc_bool_t          use_tcp_nodelay;
} dwcf_comm_opt_t;
#endif /* not WIN32 */

#if defined(__WIN32_DW)
/* --- [Engine] --- */
typedef struct {
    dwc_path_t           engine_dir;
    dwc_path_t           bases_dir;
    dwc_path_t           tmp_dir;
    dwc_multistring_t    keyfiles;
    dwc_path_t           email_file;
    dwc_timeout_t        update_timeout;
    dwc_count_t          maxload_engines;
    dwc_count_t          preload_engines;
    dwc_timeout_t        unload_timeout;
} dwcf_engine_opt_t;
#endif /* WIN32 */

/* --- [Scanning] --- */
typedef struct {
    dwc_bool_t      heuristic;
#if !defined(__WIN32_DW)
    dwc_bool_t      use_tcp_nodelay;
    dwc_string_t    prefix_path;
    dwc_count_t     strip_path;
#endif /* not WIN32 */
#if !defined(DW_SAMBA)    
    dwc_bitset_t    report_options;
    dwc_count_t     report_size;
#if defined(__UNIX_DW)
    dwc_bool_t      hre_filter;
#endif /* UNIX */
#if defined(__WIN32_DW)
    dwc_timeout_t   scan_timeout;
    dwc_bool_t      check_arx;
    dwc_count_t     max_arx_level;
    dwc_count_t     max_file_size;
    dwc_count_t     max_compression;
#endif /* not WIN32 */
#if defined(DW_HAVE_SPOOL)
#if defined(DW_PIPE)
    dwc_string_t    ram_spool;
    dwc_count_t     ram_threshold;
#endif /* PIPE */
    dwc_tmpfiles_t  spool;
#endif /* HAVE_SPOOL */    
#if !defined(DW_MIO)
    dwc_deny_mode_t deny_mode;
    dwc_bool_t      deny_by_default;
    dwc_userlist_t  users;
    dwc_path_t      users_file;
#endif /* MIO */
#if defined(DW_SENDMAIL)
    dwc_string_t    account;
    dwc_bool_t      stay_fg;
    dwc_string_t    hostname;
    dwc_bool_t      add_headers;
    dwc_bool_t	    can_change_body;
    dwc_bool_t	    add_antispam_headers;
    dwc_bool_t	    add_antispam_cause;
    dwc_string_t    x_header;
#endif /* SENDMAIL */
#else /* SAMBA */
    dwc_count_t     max_size_to_scan;
    dwc_scanmode_t  scan_mode;
    dwc_bool_t      rewrite_data_base;
    dwc_count_t     blocked_cache_size;
    dwc_count_t     allowed_cache_size;
#endif /* not SAMBA */
    dwc_bool_t      local;
} dwcf_scan_opt_t;

/* --- [Actions] --- */
typedef struct {
#if !defined(DW_SAMBA) 
#if defined(__UNIX_DW)
    dwc_action_t    on_hre_filter_reject;
#endif /* UNIX */
#else /* SAMBA */
    dwc_bool_t      notify_to_user;
    dwc_bool_t      notify_to_admin;
    dwc_string_t    admin_addr;
    dwc_action_t    on_archive;
    dwc_path_t      script;
#endif /* not SAMBA */
#if !defined(DW_MIO)
#if defined(DW_CGP) || defined(DW_EXIM) || defined(DW_QMAIL)
    dwc_bool_t      pass_empty_from_if_no_daemon;
#endif /* CGP or EXIM or QMAIL */
    dwc_action_t    on_empty_from;
    dwc_action_t    on_cure_fail;
    dwc_action_t    on_incurable;
#endif /* MIO */
    dwc_action_t    on_infected;
    dwc_action_t    on_adware;
    dwc_action_t    on_dialer;
    dwc_action_t    on_joke;
    dwc_action_t    on_riskware;
    dwc_action_t    on_hacktool;
    dwc_action_t    on_suspicious;
    dwc_action_t    on_skip;    
    dwc_action_t    on_archive_restriction;
    dwc_action_t    on_scan_error;
    dwc_action_t    on_proc_error;
    dwc_action_t    on_license_error;
    dwc_bool_t      custom_reply;
    dwc_string_t    reply_infected; 
    dwc_string_t    reply_rule_filter;
    dwc_string_t    reply_empty_from;
    dwc_string_t    reply_suspicious;
    dwc_string_t    reply_malware; 
    dwc_string_t    reply_skip;
    dwc_string_t    reply_archive;
    dwc_string_t    reply_error;
#if !defined(DW_SAMBA)
    dwc_string_t    admin_mail;
#if !defined(DW_MIO)
#if defined(__WIN32_DW)
    dwc_bool_t      on_reload_notify;
    dwc_bool_t      on_stop_notify;
#endif /* WIN32 */
    dwc_string_t    filter_mail;
    dwc_string_t    redirect_mail;
    dwc_viruslist_t non_notified_viruses;
    dwc_path_t      non_notified_viruses_file;
    dwc_maddrlist_t non_notified_addresses;
    dwc_path_t      non_notified_addresses_file;
#endif /* MIO */
    dwc_bool_t      move_to_quarantine;    
#endif /* not SAMBA */    
  dwc_tmpfiles_t  quarantine;
} dwcf_action_opt_t;

/* --- [xxxNotifications] --- */
#if !defined(DW_SAMBA)
typedef struct {
    dwcf_action_opt_t    actions;
    dwcf_notify_opt_t    license_notify;
    dwcf_notify_opt_t    virus_notify;
    dwcf_notify_opt_t    malware_notify;
    dwcf_notify_opt_t    skip_notify;
    dwcf_notify_opt_t    archive_notify;
    dwcf_notify_opt_t    error_notify;
    dwcf_notify_opt_t    rule_notify;
#if !defined(DW_MIO)
    dwcf_notify_opt_t    cured_notify;
#endif /* MIO */
#if defined(DW_SENDMAIL)
    dwc_hash_t           secure_hash;
    dwc_bool_t           fast_notify;
#endif /* SENDMAIL */
} dwcf_postscan_opt_t;
#endif /* not SAMBA */

/* --- [Logging] --- */
typedef struct {
    dwc_level_t     level;
#if defined(__UNIX_DW)    
#if defined(DW_HAVE_SPOOL)
    dwc_bool_t      debug_spool;
#endif /* HAVE_SPOOL */    
    int             sl_facility;
    int             sl_priority;
#endif /* UNIX */
#if defined(__WIN32_DW)
    dwc_bool_t      log_scanned;
    dwc_count_t     max_size;
    dwc_path_t      filename;    
#endif /* WIN32 */
} dwcf_log_opt_t;    

/* --- [Mailer] --- */
#if !defined(DW_SAMBA)
typedef struct {
    dwc_string_t        mailer;
#if defined(DW_SENDMAIL) || defined(DW_COURIER)
    /* for reload and may be stat */
    dwc_string_t        ctl_address;
#endif /* SENDMAIL or COURIER */
#if !defined(DW_CGP)
    /* for CGP - it's submitted directory and is sendmail wrapper for others */
    dwc_path_t          submitter;      
    dwc_string_t        submit_args;
#endif /* not CGP */
#if defined(DW_CGP)    
    dwc_tmpfiles_t      submitting;
#endif /* CGP */    
#if defined(DW_QMAIL)
    dwc_path_t          qmail_queue;
#endif /* QMAIL */    
#if defined(DW_ZMAILER)
    dwc_count_t         interface_version;
#endif /* ZMAILER */
#if defined(DW_SENDMAIL)
    dwcf_milter_opt_t   milter;
#endif /* SENDMAIL */
#if defined(DW_COURIER)
    dwcf_courier_opt_t  courier;
#endif /* COURIER */
} dwcf_submit_opt_t;

/* --- [Agent] --- */
typedef struct {
#if defined(__UNIX_DW)
    dwc_string_t        addr;
    dwc_timeout_t       timeout;
#if defined(DW_SENDMAIL) || defined(DW_CGP) || defined(DW_ZMAILER) || defined(DW_COURIER) || defined(DW_MIO)
    dwc_ipc_t           ipc;
    dwc_mutex_t         ipc_locker;
#endif /* SENDMAIL or CGP or ZMAILER or COURIER or MIO */
#endif /* UNIX */
#if defined(__WIN32_DW)
    int                 pad;
#endif /* WIN */
} dwcf_agent_opt_t;
#endif /* not SAMBA */

/* --- CLIENT SETTINGS --- */
typedef struct {
#if defined(__UNIX_DW)
    dwcf_comm_opt_t     comm;
#endif /* UNIX */
#if defined(__WIN32_DW)
    dwcf_engine_opt_t   engine;
#endif /* WIN32 */
    dwcf_scan_opt_t     scan;
    dwcf_log_opt_t      log;    
#if defined(DW_SAMBA)    
    dwcf_action_opt_t   action;
#else /* not SAMBA */
    dwcf_postscan_opt_t postscan;
    dwcf_submit_opt_t   submit;  
    dwcf_agent_opt_t    agent;
#endif /* not SAMBA */
} dw_filter_settings_t;

#if !defined(DW_SAMBA)
extern dwc_bool_t   dw_check_settings ( dw_filter_settings_t *opt, dwc_bool_t lib_inited );
#endif /* not SAMBA */
extern dwc_bool_t   dw_load_settings ( int argc, char *argv[], dw_filter_settings_t *opt );
#ifdef DW_SAMBA
extern dwc_bool_t dw_file_md5( char * filename, unsigned char * hash );
extern dwc_bool_t   dw_load_settings_agent ( int argc, char *argv[], dw_filter_settings_t *opt );
#endif /* DW_SAMBA */
extern dwc_string_t dw_get_action( dwc_action_t action );

/*
 * Macros DECLARE_PARSE( NAME ) declare two external function:
 * extern dwc_bool_t read_NAME_opt ( FILE *fs, int *pline, const char *sec, void *pdata );
 * extern void       free_NAME_opt ( const char *sec, void *pdata );
 */
DECLARE_PARSER( log )
#if defined(__UNIX_DW)
DECLARE_PARSER( comm )
#ifdef DW_SAMBA
DECLARE_PARSER_AGENT( log )
DECLARE_PARSER_AGENT( comm )
DECLARE_PARSER_AGENT( scan )
DECLARE_PARSER_AGENT( action )
#endif /* DW_SAMBA */
#endif /* UNIX */
#if defined(__WIN32_DW)
DECLARE_PARSER( engine )
#endif /* WIN32 */
DECLARE_PARSER( scan )
DECLARE_PARSER( action )
#if !defined(DW_SAMBA)
#if defined(DW_SENDMAIL)
DECLARE_PARSER( notopt )
#endif /* SENDMAIL */
DECLARE_PARSER( notify )
DECLARE_PARSER( submit )
#if defined(__UNIX_DW)
DECLARE_PARSER( agent )
#endif /* UNIX */
#endif /* not SAMBA */

#endif /* _DW_OPTIONS_H */
