//-*-c++-*-
//
//  $Id: spamass-milter.h,v 1.23 2005/04/07 02:04:24 dnelson Exp $
//
//  Main include file for SpamAss-Milter
//
//  Copyright (c) 2002 Georg C. F. Greve <greve@gnu.org>,
//   all rights maintained by FSF Europe e.V., 
//   Villa Vogelsang, Antonienallee 1, 45279 Essen, Germany
//
//   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
//
//   Contact:
//            Michael Brown <michaelb@opentext.com>
//
#ifndef _SPAMASS_MILTER_H
#define _SPAMASS_MILTER_H

#ifdef HAVE_CDEFS_H
#include <sys/cdefs.h>
#endif
#if !defined(__printflike)
#define __printflike(a,b)
#endif

#include <list>

using namespace std;

string retrieve_field(const string&, const string&);

sfsistat mlfi_connect(SMFICTX*, char*, _SOCK_ADDR*);
sfsistat mlfi_helo(SMFICTX*, char*);
sfsistat mlfi_envrcpt(SMFICTX*, char**);
sfsistat mlfi_envfrom(SMFICTX*, char**);
sfsistat mlfi_header(SMFICTX*, char*, char*);
sfsistat mlfi_eoh(SMFICTX*);
sfsistat mlfi_body(SMFICTX*, u_char *, size_t);
sfsistat mlfi_eom(SMFICTX*);
sfsistat mlfi_close(SMFICTX*);
sfsistat mlfi_abort(SMFICTX*);
sfsistat mlfi_abort(SMFICTX*);

extern struct smfiDesc smfilter;

/* struct describing a single network */
struct net
{
	struct in_addr network;
	struct in_addr netmask;
};

/* an array of networks */
struct networklist
{
	struct net *nets;
	int num_nets;
};


// Debug tokens.
enum debuglevel 
{
	D_ALWAYS, D_FUNC, D_POLL, D_UORI, D_STR, D_MISC, D_NET, D_SPAMC, D_RCPT,
	D_COPY,
	D_MAX // must be last
};

class SpamAssassin {
public:
  SpamAssassin();
  ~SpamAssassin();

  void Connect();
  void output(const void*, long);
  void output(const void*);
  void output(string);
  void close_output();
  void input();

  string& d();

  string& spam_status();
  string& spam_flag();
  string& spam_report();
  string& spam_prev_content_type();
  string& spam_checker_version();
  string& spam_level();
  string& content_type();
  string& subject();
  string& rcpt();		/* first RCPT TO: recipient (raw) */
  string& from();		/* MAIL FROM: sender (raw) */
  string& connectip();	/* IP of sending machine */
  string  local_user();	/* username part of first expanded recipient */
  string  full_user();	/* full first expanded recipient */
  int     numrcpt();	/* total RCPT TO: recpients */
  int     set_numrcpt();	/* increment total RCPT count */
  int     set_numrcpt(const int);	/* set total RCPT count to n */
  string::size_type set_spam_status(const string&);
  string::size_type set_spam_flag(const string&);
  string::size_type set_spam_report(const string&);
  string::size_type set_spam_prev_content_type(const string&);
  string::size_type set_spam_checker_version(const string&);
  string::size_type set_spam_level(const string&);
  string::size_type set_content_type(const string&);
  string::size_type set_subject(const string&);
  string::size_type set_rcpt(const string&);
  string::size_type set_from(const string&);
  string::size_type set_connectip(const string&);

private:
  void empty_and_close_pipe();
  int read_pipe();

public:  
  // flags
  bool error;
  bool running;		/* XXX merge running, connected, and pid */
  bool connected;	/* are we connected to spamc? */

  // This is where we store the mail after it
  // was piped through SpamAssassin
  string mail;

  // Data written via output() but before Connect() is stored here
  string outputbuffer;

  // Variables for SpamAssassin influenced fields
  string x_spam_status, x_spam_flag, x_spam_report, x_spam_prev_content_type;
  string x_spam_checker_version, x_spam_level, _content_type, _subject;
  
  // Envelope info: MAIL FROM:, RCPT TO:, and IP address of remote host
  // _rcpt only holds the first recipient if there are more than one
  string _from, _rcpt, _connectip;
  
  // Counter to keep track of the number of recipients
  int    _numrcpt;

  // The list of recipients for the current message
  list <string> recipients;

  // List of recipients after alias/virtusertable expansion
  list <string> expandedrcpt;

  // the sendmail queue id for this message; used for logging
  string queueid;

  // Process handling variables
  pid_t pid;
  int pipe_io[2][2];
};
  
/* Private data structure to carry per-client data between calls */
struct context
{
	struct in_addr connect_ip;	// remote IP address
	char *helo;
	SpamAssassin *assassin; // pointer to the SA object if we're processing a message
};

/* This hack is the only way to call pointers to member functions! */
typedef string::size_type (SpamAssassin::*t_setter)(const string &val);
#define callsetter(object, ptrToMember)  ((object).*(ptrToMember))
       
int assassinate(SMFICTX*, SpamAssassin*);

void throw_error(const string&);
void debug(enum debuglevel, const char* fmt, ...) __printflike(2, 3);
string::size_type find_nocase(const string&, const string&, string::size_type = 0);
int cmp_nocase_partial(const string&, const string&);
void closeall(int fd);
void parse_networklist(char *string, struct networklist *list);
int ip_in_networklist(struct in_addr ip, struct networklist *list);
void parse_debuglevel(char* string);
char *strlwr(char *str);
void warnmacro(char *macro, char *scope);

#endif


syntax highlighted by Code2HTML, v. 0.9.1