Skip to content
Snippets Groups Projects
mailsrvr.c 84.6 KiB
Newer Older
/* mailsrvr.c */

/* Synchronet Mail (SMTP/POP3) server and sendmail threads */

/* $Id$ */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
 * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html		*
 *																			*
 * 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.					*
 * See the GNU General Public License for more details: gpl.txt or			*
 * http://www.fsf.org/copyleft/gpl.html										*
 *																			*
 * Anonymous FTP access to the most recent released source is available at	*
 * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net	*
 *																			*
 * Anonymous CVS access to the development source and modification history	*
 * is available at cvs.synchro.net:/cvsroot/sbbs, example:					*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login			*
 *     (just hit return, no password is necessary)							*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src		*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * You are encouraged to submit any modifications (preferably in Unix diff	*
 * format) via e-mail to mods@synchro.net									*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

rswindell's avatar
rswindell committed
/* Platform-specific headers */
#ifdef _WIN32
	#include <io.h>			/* open/close */
	#include <share.h>		/* share open flags */
	#include <process.h>	/* _beginthread */
	#include <windows.h>	/* required for mmsystem.h */
	#include <mmsystem.h>	/* SND_ASYNC */

#elif defined(__unix__)

	#include <signal.h>		/* signal/SIGPIPE */

rswindell's avatar
rswindell committed
#endif

rswindell's avatar
rswindell committed
/* ANSI C Library headers */
#include <stdio.h>
#include <stdlib.h>			/* ltoa in GNU C lib */
#include <stdarg.h>			/* va_list */
#include <string.h>			/* strrchr */
#include <ctype.h>			/* isdigit */
#include <fcntl.h>			/* Open flags */
#include <errno.h>			/* errno */
rswindell's avatar
rswindell committed

/* Synchronet-specific headers */
rswindell's avatar
rswindell committed
#include "mailsrvr.h"
#include "crc32.h"
rswindell's avatar
rswindell committed
/* Constants */
#define MAIL_VERSION	"1.11"
#define FORWARD			"forward:"
#define NO_FORWARD		"local:"
int dns_getmx(char* name, char* mx, char* mx2
			  ,DWORD intf, DWORD ip_addr, BOOL use_tcp, int timeout);

#define SMTP_OK		"250 OK"
#define SMTP_BADSEQ	"503 Bad sequence of commands"

#define TIMEOUT_THREAD_WAIT		60		/* Seconds */
#define MAX_RECIPIENTS			100		/* 0xffff = abs max */
#define LINES_PER_YIELD			100		/* Yield every this many lines of text */

#define STATUS_WFC	"Listening"

static mail_startup_t* startup=NULL;
static scfg_t	scfg;
static SOCKET	server_socket=INVALID_SOCKET;
static SOCKET	pop3_socket=INVALID_SOCKET;
static int		active_sendmail=0;
static BOOL		sendmail_running=FALSE;
static DWORD	sockets=0;
static BOOL		recycle_server=FALSE;

typedef struct {
	SOCKET			socket;
	SOCKADDR_IN		client_addr;
} smtp_t,pop3_t;

static int lprintf(char *fmt, ...)
{
	va_list argptr;
	char sbuf[1024];

    if(startup==NULL || startup->lputs==NULL)
        return(0);

#if defined(_WIN32) && defined(_DEBUG)
	if(IsBadCodePtr((FARPROC)startup->lputs)) {
		DebugBreak();
	va_start(argptr,fmt);
    vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
	sbuf[sizeof(sbuf)-1]=0;
    va_end(argptr);
    return(startup->lputs(sbuf));
}

#ifdef _WINSOCKAPI_

static WSADATA WSAData;
static BOOL WSAInitialized=FALSE;

static BOOL winsock_startup(void)
{
	int		status;             /* Status Code */

    if((status = WSAStartup(MAKEWORD(1,1), &WSAData))==0) {
		lprintf("%s %s",WSAData.szDescription, WSAData.szSystemStatus);
		return (TRUE);
	}

    lprintf("!WinSock startup ERROR %d", status);
	return (FALSE);
}

#else /* No WINSOCK */

rswindell's avatar
rswindell committed
#define winsock_startup()	(TRUE)

#endif

static void update_clients(void)
{
	if(startup!=NULL && startup->clients!=NULL) {
#if defined(_WIN32) && defined(_DEBUG)
		if(IsBadCodePtr((FARPROC)startup->clients)) {
			DebugBreak();
			return;
		}
#endif
		startup->clients(active_clients+active_sendmail);
static void client_on(SOCKET sock, client_t* client, BOOL update)
	if(startup!=NULL && startup->client_on!=NULL) {
#if defined(_WIN32) && defined(_DEBUG)
		if(IsBadCodePtr((FARPROC)startup->client_on)) {
			DebugBreak();
			return;
		}
#endif
		startup->client_on(TRUE,sock,client,update);
}

static void client_off(SOCKET sock)
{
	if(startup!=NULL && startup->client_on!=NULL) {
#if defined(_WIN32) && defined(_DEBUG)
		if(IsBadCodePtr((FARPROC)startup->client_on)) {
			DebugBreak();
			return;
		}
#endif
		startup->client_on(FALSE,sock,NULL,FALSE);
	if(startup!=NULL && startup->thread_up!=NULL)
		startup->thread_up(TRUE);
}

static void thread_down(void)
{
Loading
Loading full blame...