#ifndef __DWC_LIB_H
#define __DWC_LIB_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: dwc_lib.h,v 1.56.2.1 2009/10/29 18:36:36 akorkov Exp $ */

#include <sys/types.h>
#include "dwc_ipc.h"
#include "dwc_scan.h"
#include "dwc_strings.h"

#ifdef  __cplusplus
extern "C" {
#endif

#define LIB_VERSION( a, b )         ((((a)<<8) & 0xFF00) + ((b) & 0x00FF))
#define CURRENT_LIB_VERSION         LIB_VERSION(4,7)

/* -- RETURN CODES ----------------------------------------------------- */
#define DWL_NOERROR                 (0)   /* no errors */
#define DWL_COMMONERROR             (-1)  /* returned by system */
#define DWL_IPCSYSTEM               (-2)  /* in internal transport system */  
#define DWL_BADFILE                 (-3)  /* on file passed to lib */
#define DWL_BADPARAMS               (-4)  /* incorrect values of parameters */
#define DWL_NOTSUPPORTED            (-5)  /* this option not supported */
#define DWL_ALREADYEXEC             (-6)  /* try make operation that can be performed only once */
#define DWL_RECVERROR               (-7)  /* on recv from daemon */
#define DWL_SENDERROR               (-8)  /* on send to daemon */
#define DWL_NOMEMORY                (-9)  /* no memory for internal use */
#define DWL_NOTINIT                 (-10) /* library was not inited */
#define DWL_TIMEDOUT                (-11) /* operation timed out */
#define DWL_NORESOURCES             (-11) /* no resources for internal use */
#define DWL_NOCONNECTION            (-12) /* cannot connect to daemon address */

/* -- TYPES ----------------------------------------------------------- */
/* Close structure content into the library 
 */
typedef struct dw_viruses_t {
    dwc_multistring_t   known;
    dwc_multistring_t   suspicious;
    dwc_multistring_t   modification;
    dwc_multistring_t   adware;
    dwc_multistring_t   dialer;
    dwc_multistring_t   joke;
    dwc_multistring_t   riskware;
    dwc_multistring_t   hacktool;
}                                   dwc_viruses_t;

typedef struct dw_stats_t {
    unsigned int        dw_scanned;
    unsigned int        dw_infected;
    unsigned int        dw_modifications;
    unsigned int        dw_suspicious;
    unsigned int        dw_cured;
    unsigned int        dw_deleted;
    unsigned int        dw_filter_alert;
    unsigned int        dw_skipped;
    unsigned int        dw_archive_restriction;
    unsigned int        dw_error;
    unsigned int        dw_eval_key;
    unsigned int        dw_adware;
    unsigned int        dw_dialer;
    unsigned int        dw_joke;
    unsigned int        dw_riskware;
    unsigned int        dw_hacktool;
}                                   dwc_scan_stat_t;

#define STAT_FIELDS_NUM             sizeof(dwc_scan_stat_t) / sizeof(unsigned int)
typedef struct dw_scan_result_t*    dwc_scan_result_t;

typedef struct dw_spam_stat_t {
    long		dw_spam_score;
    dwc_string_t	dw_spam_details;
}                                   dwc_spam_stat_t;

/* Callback function prototype for scanCallbackBuffer
 * IN: Buffer - pointer to memory for scan
 * IN: BufferLen - size of buffer
 * IN: CBData - pointer to callback specified data
 * Return: bytes written into Buffer, if 0 - all data has been passed,
 *  -1 indicate an error
 */
typedef void*                       dwc_cb_data_t;
typedef int (*dwc_cb_func_t)(void* Buffer, int BufferLen, dwc_cb_data_t CBData);

/* -- PROTOTYPES ------------------------------------------------------ */
/* Enable/Disable output : Should be used before startup
 * IN: Location - logging to syslog (NULL), console ("console") or to file (name)
 * IN: Level - logging level: 0 - quiet .. 9 - very verbose (see dwc_log.h)
 * IN: Facility - syslog facility (for example LOG_MAIL, LOG_DAEMON)
 * IN: Priority - syslog priority (for example LOG_INFO, LOG_ALERT)
 * DEFAULT OUTPUT MODE: all disabled
 */
extern void outputLib( char* Location, int Level, int Facility, int Priority, const char* ident );

/* Output information, according to output settings 
 * IN: level - level of message (see dwc_log.h)
 * IN: fmt - format string (see doc to printf)
 */ 
extern void printLib( int level, char const* fmt, ... );

/* Return error message appropriate for daemon return codes. May be NULL.
   The string is allocated by malloc and should be freed by caller */
extern char* getDaemonCodeString( int code );

/* Initialize library : made it  before use any belows functions.
 * IN: Version - version of interface CURRENT_LIB_VERSION
 * IN: Address - string that specify daemon address {FAMILY}:{ADDRESS}
 *   if FAMILY: 
 *      inet - TCP/IP socket used, inet:{PORT}@{HOST} 
 *             (i.e. inet:3000@localhost)
 *      local - UNIX socket used, unix:{SOCKETFILE} 
 *             (i.e. local:/usr/local/drweb/run/drwebd.skt)    
 *      pid - get daemon address from pidfile, file:{PIDFILE} 
 *             (i.e. pid:/usr/local/drweb/run/drwebd.pid)
 * IN: Timeout - time in seconds for network operations;
 * IN: Cache - use caching for hostname of daemon (1 - enable, 0 - disable)
 * Return: codes see before
 */
extern int  startupLib( int Version, const char *Address, int Timeout, int Cache );

/* Add another one daemon address to DrWeb daemons addresses list.
 * That allow to have backup daemon, if main daemon busy.
 * IN: Address - string that specify daemon address {FAMILY}:{ADDRESS}
 *   if FAMILY: 
 *      inet - TCP/IP socket used, inet:{PORT}@{HOST} 
 *             (i.e. inet:3000@localhost)
 *      local - UNIX socket used, unix:{SOCKETFILE} 
 *             (i.e. local:/usr/local/drweb/run/drwebd.skt)    
 *      pid - get daemon address from pidfile, file:{PIDFILE} 
 *             (i.e. pid:/usr/local/drweb/run/drwebd.pid) 
 * IN: Timeout - time in seconds for network operations;
 * IN: Cache - use caching for hostname of daemon (1 - enable, 0 - disable)
 * Return: codes see before
 */
extern int  addAddressLib( const char *Address, int Timeout, int Cache );

/* Deinitialize library - do it before exit or startup with new parameters
 * Return: codes see before
 */
extern int  cleanupLib( void );

/* Show daemon ID string
 * OUT: id_string - contains allocated (by malloc) ID string, should be
        freed by caller
 * Return: codes see before
 */
extern int  getDaemonID( char** id_string );

/* Show daemon version 
 * OUT: major - major version
 * OUT: minor - minor version
 * Return: codes see before
 */
extern int  get_version( int* major, int* minor );

/* Send command to start updater
 * Return: codes see before
 */
extern int sendUpdateCmd( int* ret );

/* Show bases loaded by daemon 
 * OUT: list - string contains a list of loaded bases (freed by caller)
 * OUT: total_records - count of virusfinding recordes in bases
 * Return: codes see before
 */
extern int  getBases( char** list, int* total_records );

/* Create result structure
 * Return: pointer to structure or NULL
 */
extern dwc_scan_result_t createResult( void );

/* Set status code to structure
 * IN: Res - pointer to structure with report
 * IN: Code - new code
 * Return: 0 - if fail, 1 - if success
 */
extern int  setResultStatus( dwc_scan_result_t Res, int code );

/* Set report line to structure
 * IN: Res - pointer to structure with report
 * IN: Report - new report
 * Return: 0 - if fail, 1 - if success
 */
extern int  setResultReport( dwc_scan_result_t Res, char* Report );

/* Set quarantine name to structure
 * IN: Res - pointer to structure with report
 * IN: name - quarantine name
 * Return: 0 - if fail, 1 - if success
 */
extern int setResultQuarantine( dwc_scan_result_t Res, dwc_path_t name );

/* Extract status code from structure
 * IN: Res - pointer to structure with report
 * Return: combination of bits from dwc_scan.h
 */
extern int  getResultStatus( dwc_scan_result_t Res );

/* Extract report line from structure
 * IN: Res - pointer to structure with report
 * Return: report line or "report was not requested"
 */
extern char*  getResultReport( dwc_scan_result_t Res );

/* Extract filter rule report line from structure
 * IN: Res - pointer to structure with report
 * Return: report line or "report was not requested"
 */
extern char* getResultFilterReport( dwc_scan_result_t Res );

/* Extract quarantine name from structure
 * IN: Res - pointer to structure with report
 * Return: name or NULL
 */
extern char*  getResultQuarantine( dwc_scan_result_t Res );

/* Extract cured buffer from structure
 * IN: Res - pointer to structure with report
 * Return: name or NULL
 */
extern char*  getResultCuredBuffer( dwc_scan_result_t Res );

/* Extract cured buffer length from structure
 * IN: Res - pointer to structure with report
 * Return: name or NULL
 */
extern int    getResultCuredLength( dwc_scan_result_t Res );

/* Extract viruses names list from structure
 * IN: Res - pointer to structure with report
 * Return: list or NULL (if was not requested)
 */
extern dwc_multistring_t getResultViruses( dwc_scan_result_t Res );

/* Extract typed viruses lists from structure
 * IN: Res - pointer to structure with report
 * Return: list or NULL (if was not requested)
 */
extern dwc_viruses_t* getResultTypedViruses( dwc_scan_result_t Res );

/* Extract scanning stat from structure
 * IN: Res - pointer to structure with report
 * Return: pointer to stat or NULL
 */
extern dwc_scan_stat_t* getResultStat( dwc_scan_result_t Res );
extern dwc_void_t printScanStat( int LogLevel, dwc_scan_stat_t* pStat );

/* Extract scanning spam from structure
 * IN: Res - pointer to structure with report
 * Return: pointer to stat or NULL
 */
extern dwc_spam_stat_t * getResultSpam( dwc_scan_result_t Res );

/* Convert scanning stat to string
 * IN: pStat - pointer to scanning stat 
 * Return: pointer to string or NULL
 * NOTE: string MUST BE freed by caller 
 */
extern char* convertStatToString( dwc_scan_stat_t* pStat );

/* Clear result structure after calling scan* routines and usage
 * IN/OUT: Res - pointer to structure with report, after call not valid pointer
 * Return: codes see before
 */
extern int  clearResult( dwc_scan_result_t Res );
 
/* Scan memory buffer :
 * IN: Buffer - pointer to memory for scan
 * IN: BufferLen - size of buffer
 * IN: ScanOptions - set of options from <dwc_scan.h>     
 * IN: ScanExtOptions - set of extended options from <dwc_scan.h>     
 * IN/OUT: pResult - result of scanning
 * IN: ReportMaxSize - max size of daemon report or 0 if do not have restrictions
 * Return: codes see before
 */
extern int  scanBuffer( void* Buffer, size_t BufferLen, int ScanOptions, int ScanExtOptions, dwc_scan_result_t *pResult, int ReportMaxSize );

/* Scan file :
 * IN: Path - pointer to path name (or filename for normal files)
 * IN: PathLen - length of path name (library dont checks for correct this value)
 * IN: Local - one of
 *        0 - open, read file and send to daemon thru IPC
 *        not 0 - send to daemon only filename and daemon verify it as local file
 * IN: ScanOptions - set of options from <dwc_scan.h>     
 * IN: ScanExtOptions - set of extended options from <dwc_scan.h>     
 * IN/OUT: pResult - results of scanning
 * IN: ReportMaxSize - max size of daemon report or 0 if do not have restrictions
 * Return: codes see before
 */
extern int  scanFile( const char* Path, size_t PathLen, int Local, int ScanOptions, int ScanExtOptions, dwc_scan_result_t *pResult, int ReportMaxSize );

/* Scan mail file :
 * IN: Path - pointer to path name (or filename for normal files)
 * IN: PathLen - length of path name (library dont checks for correct this value)
 * IN: Local - one of
 *        0 - open, read file and send to daemon thru IPC
 *        not 0 - send to daemon only filename and daemon verify it as local file
 * IN: ScanOptions - set of options from <dwc_scan.h>     
 * IN: ScanExtOptions - set of extended options from <dwc_scan.h>     
 * IN/OUT: pResult - results of scanning
 * IN: ReportMaxSize - max size of daemon report or 0 if do not have restrictions
 * IN: sender - smtp-envelope MAIL FROM argument
 * IN: rcpts - list of smtp-envelope RCPT TO arguments
 * Return: codes see before
 */
extern int  scanMail( char* Path, size_t PathLen, int Local, int ScanOptions, int ScanExtOptions, dwc_scan_result_t *pResult, int ReportMaxSize, dwc_string_t sender, dwc_multistring_t rcpts );

/* Scan part file (useful for checks mailboxes - not implemented under not *nix platfroms) :
 * IN: Path - pointer to path name (seen by daemon) to file
 * IN: PathLen - length of path name (library dont checks for correct this value)
 * IN: Offset - offset from head of file to scan
 * IN: Length - length of part file to scan
 * IN: ScanOptions - set of options from <dwc_scan.h>     
 * IN: ScanExtOptions - set of extended options from <dwc_scan.h>     
 * IN/OUT: pResult - results of scanning
 * IN: ReportMaxSize - max size of daemon report or 0 if do not have restrictions
 * Return: codes see before
 */
extern int  scanFilePart( char* Path, size_t PathLen, size_t Offset, size_t Length, int ScanOptions, int ScanExtOptions, dwc_scan_result_t *pResult, int ReportMaxSize );

/* Scan data supplied by callback :
 * IN: BufferName - this instance of callback name (passed to daemon for 
                    logging), can be NULL
 * IN: BufferNameLen - length of BufferName 
 * IN: BufferLen - amount of data that the callback will provide
 * IN: ScanOptions - set of options from <dwc_scan.h>
 * IN: ScanExtOptions - set of extended options from <dwc_scan.h>     
 * IN/OUT: pResult - result of scanning
 * IN: ReportMaxSize - max size of daemon report or 0 if do not have restrictions
 * Return: codes see before
 */
extern int  scanCallbackBuffer( dwc_cb_func_t Callback, dwc_cb_data_t CBData, char* BufferName, int BufferNameLen, int BufferLen, int ScanOptions, int ScanExtOptions, dwc_scan_result_t *pResult, int ReportMaxSize );

/* Portable file_size detection 
 * IN: fd - file descriptor
 * Return: file size
 */
extern int  fileSize( int fd );

/* Return error string for RETURN CODES (see before)
 */
extern const char * dwcStrError( int err_num );

extern DWC_ipc_t            session_open( DWC_bool_t is_local, DWC_bool_t use_nodelay );
extern int                  session_close( DWC_ipc_t ipc );

extern dwc_bool_t dwc_use_full_names_for_report;

#ifdef  __cplusplus
}
#endif

#endif /* __DWC_LIB_H */
