/* Core mail-sending module.
 *
 * IRC Services is copyright (c) 1996-2009 Andrew Church.
 *     E-mail: <achurch@achurch.org>
 * Parts written by Andrew Kempe and others.
 * This program is free but copyrighted software; see the file COPYING for
 * details.
 */

#include "services.h"
#include "modules.h"
#include "conffile.h"
#include "language.h"
#include "mail.h"
#include "mail-local.h"

/*************************************************************************/

static Module *module;

static char *FromAddress;
static char def_FromName[] = "";
static char *FromName = def_FromName;

EXPORT_VAR(void *,low_send)
int (*low_send)(const char *from, const char *fromname, const char *to,
		const char *subject, const char *body) = NULL;

/*************************************************************************/
/***************************** Mail sending ******************************/
/*************************************************************************/

/* The function to actually send mail.  All parameters must be filled in,
 * `to' must be a valid E-mail address, and only the body may contain
 * newlines.  Return value is 0 for success, 1 for temporary failure (no
 * resources), and -1 for permanent failure (invalid parameter, no such
 * user).
 *
 * NOTE: A return value of 0 does not guarantee that the mail was
 *       successfully sent!  It only indicates that the mail subsystem
 *       accepted the mail and will attempt to deliver it.
 */

EXPORT_FUNC(sendmail)
int sendmail(const char *to, const char *subject, const char *body)
{
    if (!low_send) {
	module_log("sendmail(): No low-level mail module installed!");
	return -1;
    }
    if (!to || !subject || !body) {
	module_log("sendmail(): Got a NULL parameter!");
	return -1;
    }
    if (!valid_email(to)) {
	module_log("sendmail(): Destination address is invalid: %s", to);
	return -1;
    }
    if (strchr(subject, '\n')) {
	module_log("sendmail(): Subject contains newlines (invalid)");
	return -1;
    }
    if (debug)
	module_log("debug: sendmail: from=%s to=%s subject=[%s]",
		   FromAddress, to, subject);
    if (debug >= 2)
	module_log("debug: sendmail: body=[%s]", body);
    return low_send(FromAddress, FromName, to, subject, body);
}

/*************************************************************************/
/***************************** Module stuff ******************************/
/*************************************************************************/

const int32 module_version = MODULE_VERSION_CODE;

static int do_FromAddress(const char *filename, int linenum, char *param);
static int do_FromName(const char *filename, int linenum, char *param);
ConfigDirective module_config[] = {
    { "FromAddress",      { { CD_FUNC, CF_DIRREQ, do_FromAddress } } },
    { "FromName",         { { CD_FUNC, 0, do_FromName } } },
    { NULL }
};

/*************************************************************************/

static int do_FromAddress(const char *filename, int linenum, char *param)
{
    static char *new_FromAddress = NULL;

    if (filename) {
	/* Check parameter for validity and save */
	if (!valid_email(param)) {
	    config_error(filename, linenum,
			 "FromAddress requires a valid E-mail address");
	    return 0;
	}
	free(new_FromAddress);
	new_FromAddress = strdup(param);
	if (!new_FromAddress) {
	    config_error(filename, linenum, "Out of memory");
	    return 0;
	}
    } else if (linenum == CDFUNC_SET) {
	/* Copy new values to config variables and clear */
	if (new_FromAddress) {  /* paranoia */
	    free(FromAddress);
	    FromAddress = new_FromAddress;
	} else {
	    free(new_FromAddress);
	}
	new_FromAddress = NULL;
    } else if (linenum == CDFUNC_DECONFIG) {
	/* Reset to defaults */
	free(FromAddress);
	FromAddress = NULL;
    }
    return 1;
}

/*************************************************************************/

static int do_FromName(const char *filename, int linenum, char *param)
{
    static char *new_FromName = NULL;

    if (filename) {
	/* Check parameter for validity and save */
	if (strchr(param, '\n')) {
	    config_error(filename, linenum,
			 "FromName may not contain newlines");
	    return 0;
	}
	free(new_FromName);
	new_FromName = strdup(param);
	if (!new_FromName) {
	    config_error(filename, linenum, "Out of memory");
	    return 0;
	}
    } else if (linenum == CDFUNC_SET) {
	/* Copy new values to config variables and clear */
	if (new_FromName) {  /* paranoia */
	    if (FromName != def_FromName)
		free(FromName);
	    FromName = new_FromName;
	} else {
	    free(new_FromName);
	}
	new_FromName = NULL;
    } else if (linenum == CDFUNC_DECONFIG) {
	/* Reset to defaults */
	if (FromName != def_FromName)
	    free(FromName);
	FromName = def_FromName;
    }
    return 1;
}

/*************************************************************************/

int init_module(Module *module_)
{
    module = module_;
    return 1;
}

/*************************************************************************/

int exit_module(int shutdown_unused)
{
#ifdef CLEAN_COMPILE
    shutdown_unused = shutdown_unused;
#endif
    return 1;
}

/*************************************************************************/
