/*
 * 
 * POP3-Virusscan-Proxy
 *
 * (C) 2002 by Folke Ashberg <folke@ashberg.de>
 *
 * $Id: scanner_sample.c,v 1.7 2002/06/11 23:09:16 folke Exp $ 
 *
 * This file explains howto write your own scanner-frontend.
 * This is just a demo, don't expect any work! *g*
 * 
 * This program 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 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/un.h>
#include <sys/socket.h>


/* we need pop3vscan.h */
#include "pop3vscan.h"

/* place some definitions */
#define	DEFAULT_SOCKET_PATH "/var/run/xyz-scanner.sock"

/* usually we need pop3vscan's config, so make it global */
struct configuration_t * config;

/* if you need some globals, make them static! */
static int  connected;
struct sockaddr_un scanner_socket;

/* if you need some functions, make them static */
static int function(void){
    return 0;
}
    
/* If you need initialization, use init1 . It is called after config parsing,
 * setuid and daemonizing.  You can check the parameters (config->xxxx), set
 * defaults if nothing is given, and so on.
 * 
 * Return values:
 *   -1 : Error. Scanning will be completely disabled.
 *        No further functions (init2, scan, uninit1, uninit2) will be called
 *    0 : OK
 */
static int init1(void){
    do_log(LOG_DEBUG, "SAMPLE Init1");
    if (strlen(NONULL(config->virusscanner))<1){
	do_log(LOG_CRIT, "no scanner was defined. we're using " DEFAULT_SOCKET_PATH);
	config->virusscanner=strdup(DEFAULT_SOCKET_PATH);
    }
    do_log(LOG_DEBUG, "AVP Init1 Done");

    return 0;
}

/* If you need initialization before scanning, use init2. Init2 is called before
 * the first mail has to be scanned (not when a client only checks if he has new
 * mails).  Here you can connect for example to a socket (which makes more sense
 * then doing that in init1).
 * 
 * Return values:
 *   -1 : Error. Scanning is temporarily disabled for further mails over that
 *        connection.
 *        No further functions (scan, uninit2) will be called, but uninit1.
 *    0 : OK
 */

static int init2(struct proxycontext *p){
    do_log(LOG_DEBUG, "Init2");

    /* Connect to socket */
    if (socket_connect(p)!=0) return -1;

    do_log(LOG_DEBUG, "Init2 Done");

    return 0;
}

/* if you need to uninitialize what init2 has initialized, use uninit2, which is
 * called only if init2 is set and init2 was called!
 */
static void uninit2(struct proxycontext *p){
    socket_close();
}

/* if you need to uninitialize when pop3vscan terminates, use uninit1, which is
 * called only if init1 has returned 0 OR was not set.
 */

static void uninit1(void){
    
}

/* now the scanner...
 * Depending on demime (can be configured by user) and dirscan (can only be set
 * below in scanner_t by you) we have to scan the mailfile, a directory or the
 * deMIMEd files.
 *
 * +--------+---------+--------------------------------------------------------+
 * | demime | dirscan |                                                        |
 * +--------+---------+--------------------------------------------------------+
 * |   0    |    0    | scan is called once, p->scanthis points to p->mailfile |
 * +--------+---------+--------------------------------------------------------+
 * |   1    |    0    | scan is called for every MIME-file                     |
 * |        |         | p->scanthis points to the actual file in maildir       |
 * +--------+---------+--------------------------------------------------------+
 * |   1    |    1    | scan is called once, p->scanthis points to maildir     |
 * +--------+---------+--------------------------------------------------------+
 * |   0    |    1    | when the user have not set dirscan, you will get       |
 * |        |         | p->scanthis pointing to mailfile                       |
 * +--------+---------+--------------------------------------------------------+
 *
 * You can set virname to a description of the virus. If scan is invoked
 * multiple times and if you should find more than one virus we append all
 * virusnames together (seperated with ' & '). virname is not malloced (it
 * wouldn't be char**).  If you can't examime the virusname set it to NULL, when
 * no virus is found you can let them untouched.
 * 
 * Return Codes:
 *   SCANNER_RET_VIRUS : The file contains a virus
 *   SCANNER_RET_OK    : The file contains NO virus
 *   SCANNER_RET_ERR   : Can't say if it's a virus
 *
 * If scan is invoked multiple times, we automatically collect the returncodes,
 * that means that if one of the files has a virus, then anything else is
 * ignored (further ERRs and OKs).
 *    
 */
static int scan(struct proxycontext *p, char **virname){
    int ret;
    do_log(LOG_DEBUG, "SAMPLE scanner says hello");

    ret=scanfile(p->scanthis, virname);
    if (ret==3 || ret==4) ret = SCANNER_RET_VIRUS; /* virus */
    else if (ret<0) ret=SCANNER_RET_ERR;
    else ret = SCANNER_RET_OK;

    do_log(LOG_DEBUG, "SAMPLE scanner says goodbye");
    return ret;
}

/* Tell us your name (used for scannertype) and a brief description (shown at
 * startup and in --help).  Set the functions you need, or just NULL if not (and
 * remove the above functions).  For infos about dirscan see the scan()
 * description above.
 * 
 */
scanner_t scanner_sample = {
    "sample",				    /* name */
    "A sample scanner frontend",	    /* description */
    &init1,				    /* init1 (once, after startup) */
    &init2,				    /* init2 (every connection before first mail) */
    &scan,				    /* scan */
    &uninit2,				    /* uninit2 */
    &uninit1,				    /* uninit1 */
    0					    /* dirscan */
};

/* 
 * to tell pop3vscan what we are exists, add scanner_sample.o to Makefile
 * (append to OBJECTS) and define scanner_sample as extern in scanner.h and
 * place them in scannerlist[]
 * 
 *   That's all! Happy coding! :)
 *
 */


syntax highlighted by Code2HTML, v. 0.9.1