/* * Intermud mail server, used by Huthar's mailer daemon * Original author: Huthar * Rewritten to conform to new socket efun specs, Blackthorn (10/31/92) * Modified by Truilkan for use in Basis mudlib (11/01/92) * Modified by Pinkfish for use in the Discworld mudlib (5 jan 92) * (Stupid american date formats). */ #include "mail.h" #include "nameserver.h" #define SAVE "/net/save/" #define report(x) log_file("MAIL",ctime(time())+" "+x+"\n") #define log(x) log_file("MS", x) #define MS_SAVE "mail-queue" #define FLUSH_TIME 86400 #define AGE_TIME 604800 #define EOF "%EOF%" #define EOT "%EOT%" #undef DEBUG #ifdef DEBUG #define TP(STR) tell_object(find_player("brandobas"), STR) #else #define TP(STR) #endif static string upd; static mapping new_mail_queue, sockets; static string receiver, from, to, subject, message, cc; static int date; static string mud; static mixed mqi; static mixed outgoing; mixed mail_queue; int date_last_flushed; void process_message( int fd ); void flush_mail_queue(); void age_queue(); void bad_port( string mud, string from, string message ); void create() { seteuid( (string)"/secure/master"->creator_file( this_object() ) ); sockets = ([ ]); } /* create() */ /* * This adds on the lmud and lname bit if it is not in name@address * format. */ string convert_name( string lname, string lmud ) { string tmp, tmpaddr; if( sscanf( lname, "%s@%s", tmp, tmpaddr ) != 2 ) { tmp = lname; tmpaddr = lmud; } /* * this doe not handle aliases for the same mud at the moment. I * will add in some new code here real soon now. Maybe... */ if( tmpaddr != MUD_NAME ) return tmp + "@" + tmpaddr; return tmp; } /* convert_name() */ void dest_me() { destruct( this_object() ); } /* dest_me() */ void close_callback( int id ) { TP( "Doing close.\n" ); process_message( id ); map_delete( sockets, id ); return; } /* close_callback() */ void connected( int id ) { sockets[ id ] = ([ "msg":"" ]); } /* connected() */ void read_callback( int id, string data ) { string str1, str2; /* Hmm. I dont think we actually nedd this here... if (sscanf(data, "%s"+EOF+"%s", str1, str2) == 2) { sockets[id]["msg"] += data; process_message(id); return; } */ sockets[ id ][ "msg" ] += data; } /* read_callback() */ void process_message( int id ) { mixed tmp, tmp2; string *totmp, *cctmp; int i, j, res; TP( sprintf( "%O\n", sockets[ id ][ "msg" ] ) ); sscanf( sockets[ id ][ "msg" ], "%s\n%s", mud, tmp ); sockets[ id ][ "msg" ] = tmp; TP( "Processing message, mud name " + mud + "\n" ); tmp = explode( sockets[ id ][ "msg" ], EOF ); tmp = tmp[ 0..sizeof( tmp ) - 2 ]; tmp2 = allocate( sizeof( tmp ) ); TP( "Number of messages " + sizeof( tmp ) + "\n" ); for( i = 0; i < sizeof( tmp ); i++ ) { tmp2[ i ] = explode( tmp[ i ], "\n" ); } for( i = 0; i < sizeof( tmp2 ); i++ ) { receiver = convert_name( tmp2[ i ][ 0 ], MUD_NAME ); totmp = explode( tmp2[ i ][ 1 ], " " ); for( j = 0; j < sizeof( totmp ); j++ ) totmp[ j ] = convert_name( totmp[ j ], mud ); cctmp = explode( tmp2[ i ][ 2 ], " " ); if( cctmp[ 0 ] ) for( j = 0; j < sizeof( cctmp ); j++ ) cctmp[ j ] = convert_name( cctmp[ j ], mud ); else cctmp = ({ }); from = convert_name( tmp2[ i ][ 3 ], mud ); subject = tmp2[ i ][ 4 ]; sscanf( tmp2[ i ][ 5 ], "%d", date ); report( "R " + from + " " + receiver ); TP( "To: " + receiver + " From: " + from + " Cc: " + tmp2[ i ][ 2 ] + " Subject: " + subject + "\n" ); message = implode( tmp2[ i ][ 6..sizeof( tmp2[ i ] ) - 1 ], "\n" ); /* * Ok... IN here we need to do a call out to check the validity * of the mud this is comming from. * */ NAME_D->lookup_mud( mud, "got_address", ({ socket_address( id ), receiver, totmp, cctmp, from, subject, date, message }) ); } } /* process_message() */ void mail_postmaster( string from, string subject, mixed *args ) { MAILER->do_mail_message( "postmaster", from, subject, 0, ">From: " + args[ 4 ] + "\nTo: " + implode( args[ 2 ], ", " ) + "\nCc: " + implode( args[ 3 ], ", " ) + "\nSubject: " + args[ 5 ] + "\nDate: " + ctime( args[ 6 ] ) + "\n" + args[ 7 ], 1 ); } /* mail_postmaster() */ void got_address( string host, string addr, mixed *args ) { object ob; string *to, name, name2; int port; if( !addr ) { /* Unknown mud just tried to mail us... */ /* * Now, what exactly should I do about it? Mail it to the postmaster? * Yeah, sounds good to me... */ mail_postmaster( args[ 4 ], "From unknown mud", args ); /* Don't bother returning it to them. */ return; } sscanf( addr, "%s %d", name, port ); sscanf( args[ 0 ], "%s %d", name2, port ); if( !name || !name2 ) { mail_postmaster( args[ 4 ], "Strange error", args ); return; } if( name != name2 ) { mail_postmaster( args[ 4 ], "Forged mail", args ); return; } /* Ok, its right. Now deliver it... */ report( "D " + args[ 4 ] + " " + implode( args[ 2 ], "," ) ); MAILER->do_mail_message( implode( args[ 2 ], "," ), args[ 4 ], args[ 5 ], implode( args[ 3 ], "," ), args[ 7 ], 0, args[ 1 ] ); } /* got_address() */