#!/usr/bin/php -q

<?php

######## N1.1 ADDITIONS: ############################
# changed Emmmail Enterprise Server to $fromname Neterprise Server
# added $domain_name to incoming vars
#
#
##############################################



### LOGGING:
$logging = "yes";

function logf($filename,$string) {
	//echo "$string<br><br>";
 
 	if((is_array($string)) || (is_object($string))) {
 		$outstring = date("Y-m-d H:i:s",time()) . " A: " . var_export($string, true) . "\n\n";
 	} else {
 		$outstring = date("Y-m-d H:i:s",time()) . " B: $string\n\n";
 	}
	$fp = fopen($filename,"a");
	if($fp) {
		fwrite($fp,$outstring);
		fclose($fp);
	}
}


if($logging) logf("/tmp/emmmailer.txt","Got to EMMMAIL_N1.1\n");




Function throttle() {
  $fp = popen("ps auxww|grep -i nc|wc -l","r");
  $restr = fgets($fp,256);
  pclose($fp);
  $restr = trim($restr);
  return $restr;
}



if($logging) {
  logf("/tmp/emmmailer.txt","Incoming vars................\n");
  logf("/tmp/emmmailer.txt","1. to_address: " . $argv[1] . "\n");
  logf("/tmp/emmmailer.txt","2. from_address: " . $argv[2] . "\n");
  logf("/tmp/emmmailer.txt","3. from_name: " . $argv[3] . "\n");
  logf("/tmp/emmmailer.txt","4. subject: " . $argv[4] . "\n\n");
  logf("/tmp/emmmailer.txt","5. text_message: " . $argv[5] . "\n\n");
  logf("/tmp/emmmailer.txt","6. html_message: " . $argv[6] . "\n\n");
  logf("/tmp/emmmailer.txt","7. return_path: " . $argv[7] . "\n");
  logf("/tmp/emmmailer.txt","8. from_id: " . $argv[8] . "\n");
  logf("/tmp/emmmailer.txt","9. received_from: " . $argv[9] . "\n");
  logf("/tmp/emmmailer.txt","10. source_ip: " . $argv[10] . "\n");
  logf("/tmp/emmmailer.txt","11. domain_name: " . $argv[11] . "\n");

  logf("/tmp/emmmailer.txt","..................and spent!\n\n\n\n");
}
##############################################
### START Emmmail Enterprise Server Config ###
##############################################

$emmmail_version = "Network Version 1.1";

$to = $argv[1];
$from_addr = $argv[2];
$from_name = $argv[3];
$subject = $argv[4];
$text_message = $argv[5];
$html_message = $argv[6];
$return_path = $argv[7];
$from_id = $argv[8];
$received_from = $argv[9];
$source_ip = $argv[10];
$domain_name = $argv[11];

$cc = ""; ## (NOT USED)
$bcc = ""; ## (NOT USED)

if(!$from_id) $from_id = $source_ip;


############################################
### END Emmmail Enterprise Server Config ###
############################################




### LOG INCOMING VARS:



function encodeHeader($string) {
    global $default_charset;

    // Encode only if the string contains 8-bit characters or =?
    $j = strlen( $string  );
    $l = strstr($string, '=?');         // Must be encoded ?
    $ret = '';
    for( $i=0; $i < $j; ++$i) {
        switch( $string{$i} ) {
           case '=':
          $ret .= '=3D';
          break;
        case '?':
          $ret .= '=3F';
          break;
        case '_':
          $ret .= '=5F';
          break;
        case ' ':
          $ret .= '_';
          break;
        default:
          $k = ord( $string{$i} );
          if ( $k > 126 ) {
             $ret .= sprintf("=%02X", $k);
             $l = TRUE;
          } else
             $ret .= $string{$i};

  }
    }

    if ( $l ) {
        $string = "=?$default_charset?Q?$ret?=";
    }

    return( $string );
}






#### Time offset for correct timezone ###
function timezone () {
  global $invert_time;
    
  $diff_second = date('Z');
  
  if ($invert_time) {
    $diff_second = - $diff_second;
  }
  
  if ($diff_second > 0) {
    $sign = '+';
  } else {
    $sign = '-';
  }

  $diff_second = abs($diff_second);
  $diff_hour = floor ($diff_second / 3600);
  $diff_minute = floor (($diff_second-3600*$diff_hour) / 60);
  $zonename = '('.strftime('%Z').')';
  $result = sprintf ("%s%02d%02d %s", $sign, $diff_hour, $diff_minute, $zonename);
  return ($result);
}






### Print all the needed RFC822 headers ###
function write822Header ($fp, $to, $from_addr, $cc, $bcc, $subject, $from_name, $isHtml) {
  
  ### DEFINE GLOBALS:
  global $emmmail_version;
  global $received_from;
  global $return_path;
  global $from_id;
  global $source_ip;
  global $from_name;
  global $domain_name;
  
  ### Storing the header to make sure the header is the same everytime the header is printed.
   
  if($from_name) {
    $from = "\"" . encodeHeader($domain_name) . "\" " . "<" . $from_addr . ">"; 
  } else {
    $from = "<$from_addr>"; 
  }

  
  /*
  if($from_name) {
    $from = '"' . encodeHeader($from_name) . "\" <g_addr>"; 
  } else {
    $from = "<$from_addr>"; 
  }
  */
  
       
        
  ### This creates an RFC 822 date ###
  
        
  ### Create a message-id ### 
  $message_id = "<" . time() . "@" . $from_id . ">";
        
  ### Make an RFC822 Received: line ###
  $header  = "Received: from $received_from\r\n";
        
  ### Insert the rest of the header fields ###
  $header .= "Message-ID: $message_id\r\n";
  $header .= "Date: " . date("D, j M Y H:i:s ", mktime()) . timezone() . "\r\n";
  $header .= "Subject: =?utf-8?B?" . base64_encode($subject) . "?=\r\n"; # encodes the subject - enables SPAM words - cool ;)
  $header .= "From: $from\r\n";
  $header .= "To: $to\r\n";             ### Who it's TO
    
  if ($cc) {
    $header .= "Cc: $cc\r\n"; // Who the CCs are
  }
        
  if ($from_addr != '') {
    $header .= "Reply-To: $from_addr\r\n";
  }
  
  $header .= "X-Note: \r\n";
  $header .= "X-Note: $domain_name Email Server ($emmmail_version)\r\n";
  $header .= "X-Note: How are we driving:\r\n";
  $header .= "X-Note: http://spamcop.net/w3m?action=checkblock&ip=" . $source_ip . "\r\n";
  $header .= "X-Note: " . base64_encode($to) . "\r\n";
  $header .= "X-Note: \r\n";
  



  ### Do the MIME-stuff ###
  $header .= "MIME-Version: 1.0\r\n";

  if($isHtml) {
    
    $header .= "Content-Description: Main Header\r\n";
    $header .= "Content-Type: multipart/alternative; boundary=Snip...snip...snip...\r\n";
    $header .= "\r\n";
    $header .= "Your greatest dreams shall be realized...\r\n";
    $header .= "\r\n";
    $header .= "--Snip...snip...snip...\r\n";
    $header .= "Content-Description: ### Respectful Text-Only Version ### \r\n";
    $header .= "Content-type: text/plain; charset=\"US-ASCII\"\r\n";
    $header .= "Content-Transfer-Encoding: 7bit\r\n";
    $header .= "\r\n";
  } else {
    $header .= "Content-Description: Main Header\r\n";
    $header .= "Content-type: text/plain; charset=\"US-ASCII\"\r\n";
    $header .= "Content-Transfer-Encoding: 7bit\r\n";
    $header .= "\r\n";
  }


  ### Write the header ###
  fwrite($fp, $header);
  
  $headerlength = strlen($header);    
  return $headerlength;
}




### Send the body ###
function writeBody ($fp, $t_message, $h_message) {
  $t_message = str_replace("\r\n","\n",$t_message);
  $t_message = str_replace("\n","\r\n",$t_message);

  if(strlen($h_message) > 5) { # html message
    $passedBody = base64_encode($h_message);
    $passedBody = wordwrap( $passedBody, 80, "\r\n",1);
    $body = "$t_message\r\n";
    $body .= "\r\n";
    $body .="--Snip...snip...snip...\r\n";
    $body .= "Content-Description: ### Colorful HTML Version ###\r\n";
    $body .= "Content-Type: text/html; charset=utf-8\r\n";
    $body .= "Content-Transfer-Encoding: base64\r\n";
    $body .= "\r\n";
    $body .= "$passedBody\r\n";
    $body .= "\r\n";
    $body .= "--Snip...snip...snip...--\r\n";
    
    
    /* 
    ### ADD AOL SUPPORT :
    
    $body .= "\r\n";
    $body .="--Snip...snip...snip...\r\n";
    $body .= "Content-Description: Support For Users Of AOL > v6.0\r\n";
    $body .= "Content-Type: text/x-aol; charset=utf-8\r\n";
    $body .= "Content-Transfer-Encoding: base64\r\n";
    $body .= "\r\n";
    $body .= "$passedBody\r\n";
    $body .= "\r\n";
    $body .= "--Snip...snip...snip...--\r\n"; 
    */
    

  } else {   # text-only  
    $body = $t_message . "\r\n"; 
  }
  
  logf("/tmp/emmmailer.txt","BODY: $body\n");
  fwrite($fp, $body);
  $postbody = "\r\n";
  fwrite($fp, $postbody);
  return (strlen($body) + strlen($postbody));
}



function sendSMTP($to, $from_addr, $subject, $text_message, $html_message, $cc, $bcc, $from_name, $source_ip,$return_path,$logging,$domain_name) {

logf("/tmp/emmmailer.txt","to: $to\n");
	
  ### DEFINE GLOBALS:
  global $received_from;
   logf("/tmp/emmmailer.txt","received_from: $received_from\n");
  global $return_path;
  logf("/tmp/emmmailer.txt","return_path: $return_path\n");
  global $from_id;
  logf("/tmp/emmmailer.txt","from_id: $from_id\n");
  
  $descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("file", "/tmp/emmmailer_error-output.txt", "a") // stderr is a file to write to
);
  list($user,$domain) = split("@",$to,2);
  logf("/tmp/emmmailer.txt","user: $user\n");
  logf("/tmp/emmmailer.txt","domain: $domain\n");
  
  if(getmxrr($domain,$mx,$weight) == 0) return FALSE;

  //logger3($log_name="2_mx",$log_value=$mx,$action_code="",$log_file="/tmp/emmmailer.txt");
  logf("/tmp/emmmailer.txt","32_mx: $mx\n");
   
   
  ### Try them in order of lowest weight first ###
  array_multisort($mx,$weight);
  $success=0;
  foreach($mx as $smtpServerAddress) {
    
    logf("/tmp/emmmailer.txt","smtpServerAddress: $smtpServerAddress\n");
    
    if(strstr($smtpServerAddress,"hotmail.com")) {$smtpServerAddress = "mx4.hotmail.com"; }
    if($logging) logf("/tmp/emmmailer.txt","1: $to: Connecting to $smtpServerAddress\n");
    
    $process = proc_open("/usr/bin/nc -w 120 -s $source_ip $smtpServerAddress 25", $descriptorspec, $pipes);
    if (!is_resource($process)) {
    if($logging) logf("/tmp/emmmailer.txt","2: $to: not a resource\n");
    continue;
    }

    $tmp = fgets($pipes[1], 1024);
    if (errorCheck($to,$tmp, $pipes[1])!=5) {
    if($logging) logf("/tmp/emmmailer.txt","3: $to: ERROR CHECK: $tmp\n");
    fwrite($pipes[0], "QUIT\r\n");  ### log off ###
    fclose($pipes[0]);
    fclose($pipes[1]);
    $return_value = proc_close($process);
    exit(0);
    }
    
    
    ### Lets introduce ourselves ###
    if($logging) logf("/tmp/emmmailer.txt","4: $to: sending Helo\n");
    if($domain_name) {$my_hello = $domain_name; } else {$my_hello = $source_ip; }    
    fwrite($pipes[0], "HELO " . $my_hello . "\r\n");
    $tmp = fgets($pipes[1], 1024);
    if($logging) logf("/tmp/emmmailer.txt","5: $to: $tmp\n");

    if (errorCheck($to,$tmp, $pipes[1])!=5) {
    if($logging) logf("/tmp/emmmailer.txt","6: $to: ERROR CHECK: $tmp\n");
    fwrite($pipes[0], "QUIT\r\n");  ### log off ###
    fclose($pipes[0]);
    fclose($pipes[1]);
    $return_value = proc_close($process);
    exit(0);
    }

    ### Ok, who is sending the message? ###
	//$IPFROM = str_replace(".","",$source_ip);
    if($logging) logf("/tmp/emmmailer.txt","7: $to: sending mailfrom: <$from_addr>\n");
    
    fwrite($pipes[0], "MAIL FROM: <$from_addr>\r\n");
	//fwrite($pipes[0], "MAIL FROM: <mail@emmmail.net>\r\n");
    $tmp = fgets($pipes[1], 1024);
  
    if($logging) logf("/tmp/emmmailer.txt","8: $to: $tmp\n");
    if (errorCheck($to,$tmp, $pipes[1])!=5) {
    if($logging) logf("/tmp/emmmailer.txt","9: $to: ERROR CHECK: $tmp\n");
    fwrite($pipes[0], "QUIT\r\n");  ### log off ###
    fclose($pipes[0]);
    fclose($pipes[1]);
    $return_value = proc_close($process);
    exit(0);
    }
    
    ### send who the recipients are ###
    if($logging) logf("/tmp/emmmailer.txt","10: $to: sending rcpt to: <$to>\n");
    fwrite($pipes[0], "RCPT TO: <$to>\r\n");
    $tmp = fgets($pipes[1], 1024);
    if($logging) logf("/tmp/emmmailer.txt","11: $to: $tmp\n");

    if (errorCheck($to,$tmp, $pipes[1])!=5) {
    if($logging) logf("/tmp/emmmailer.txt","12: $to: ERROR CHECK: $tmp\n");
    fwrite($pipes[0], "QUIT\r\n");  ### log off ###
    fclose($pipes[0]);
    fclose($pipes[1]);
    $return_value = proc_close($process);
    exit(0);
    }

    if($cc) {
      fwrite($pipes[0], "RCPT TO: $cc\r\n");
      $tmp = fgets($pipes[1], 1024);
      if($logging) logf("/tmp/emmmailer.txt","13: $to: $tmp\n");

      if (errorCheck($to,$tmp, $pipes[1])!=5) {
    if($logging) logf("/tmp/emmmailer.txt","14: $to: ERROR CHECK: $tmp\n");
    fwrite($pipes[0], "QUIT\r\n");  ### log off ###
    fclose($pipes[0]);
    fclose($pipes[1]);
    $return_value = proc_close($process);
    exit(0);
    }

    }
    

    if($bcc) {
      fwrite($pipes[0], "RCPT TO: $bcc\r\n");
      $tmp = fgets($pipes[1], 1024);
      if($logging) logf("/tmp/emmmailer.txt","15: $to: $tmp\n");

      if (errorCheck($to,$tmp, $pipes[1])!=5) {
    if($logging) logf("/tmp/emmmailer.txt","16: $to: ERROR CHECK: $tmp\n");
    fwrite($pipes[0], "QUIT\r\n");  ### log off ###
    fclose($pipes[0]);
    fclose($pipes[1]);
    $return_value = proc_close($process);
    exit(0);
    }

    }


    ### Lets start sending the actual message ###
    # logf("/tmp/emmmailer.txt","sending DATA\n");

    fwrite($pipes[0], "DATA\r\n");
    $tmp = fgets($pipes[1], 1024);
    if($logging) logf("/tmp/emmmailer.txt","17: $to: $tmp\n");

    if (errorCheck($to,$tmp, $pipes[1])!=5) {
    if($logging) logf("/tmp/emmmailer.txt","18: $to: ERROR CHECK: $tmp\n");
    fwrite($pipes[0], "QUIT\r\n");  ### log off ###
    fclose($pipes[0]);
    fclose($pipes[1]);
    $return_value = proc_close($process);
    exit(0);
    }

    ### Send the message ###
    if(strlen($html_message) > 5) {
    $isHtml = 1; } else {
    $isHtml = 0; }
    $headerlength = write822Header ($pipes[0], $to, $from_addr, $cc, $bcc, $subject, $from_name, $isHtml);
    $bodylength = writeBody($pipes[0], $text_message, $html_message);
    
    fwrite($pipes[0], ".\r\n");  ### end the DATA part
    $tmp = fgets($pipes[1], 1024);
    if($logging) logf("/tmp/emmmailer.txt","19: $to: $tmp\n");

    if (errorCheck($to,$tmp, $smtpConnection)!=5) {
    if($logging) logf("/tmp/emmmailer.txt","20: $to: ERROR CHECK: $tmp\n");
    fwrite($pipes[0], "QUIT\r\n");  ### log off ###
    fclose($pipes[0]);
    fclose($pipes[1]);
    $return_value = proc_close($process);
    exit(0);
    }
    fwrite($pipes[0], "QUIT\r\n");  ### log off ###
    fclose($pipes[0]);
    fclose($pipes[1]);
    $return_value = proc_close($process);
    exit(0);
  }
}






function errorCheck($to,$line, $smtpConnection, $verbose = false) {
    
     logf("/tmp/emmmailer.txt","to: $to\n");
      logf("/tmp/emmmailer.txt","line: $line\n");
       logf("/tmp/emmmailer.txt","smtpConnection: $smtpConnection\n");
    /* Read new lines on a multiline response */
    $lines = $line;
    while(ereg("^[0-9]+-", $line)) {
        $line = fgets($smtpConnection, 1024);
        $lines .= $line;
    }
    
    /* Status:  0 = fatal
     *          5 = ok
     */
    $err_num = substr($line, 0, strpos($line, " "));
    switch ($err_num) {
    case 500:   $message = 'Syntax error; command not recognized';
        $status = 0;
        break;
    case 501:   $message = 'Syntax error in parameters or arguments';
        $status = 0;
        break;
    case 502:   $message = 'Command not implemented';
        $status = 0;
        break;
    case 503:   $message = 'Bad sequence of commands';
        $status = 0;
        break;
    case 504:   $message = 'Command parameter not implemented';
        $status = 0;
        break;    
        
    case 211:   $message = 'System status, or system help reply';
        $status = 5;
        break;
    case 214:   $message = 'Help message';
        $status = 5;
        break;
        
    case 220:   $message = 'Service ready';
        $status = 5;
        break;
    case 221:   $message = 'Service closing transmission channel';
        $status = 5;
        break;

    case 421:   $message = 'Service not available, closing channel';
        $status = 0;
        break;
        
    case 235:   return(5); 
        break;
    case 250:   $message = 'Requested mail action okay, completed';
        $status = 5;
        break;
    case 251:   $message = 'User not local; will forward';
        $status = 5;
        break;
    case 334:   return(5); break;
    case 450:   $message = 'Requested mail action not taken:  mailbox unavailable';
        $status = 0;
        break;
    case 550:   $message = 'Requested action not taken:  mailbox unavailable'; 
        $status = 0;
        break;
    case 451:   $message = 'Requested action aborted:  error in processing';
        $status = 0;
        break;
    case 551:   $message = 'User not local; please try forwarding';
        $status = 0;
        break;
    case 452:   $message = 'Requested action not taken:  insufficient system storage';
        $status = 0;
        break;
    case 552:   $message = 'Requested mail action aborted:  exceeding storage allocation';
        $status = 0;
        break;
    case 553:   $message = 'Requested action not taken: mailbox name not allowed'; 
        $status = 0;
        break;
    case 354:   $message = 'Start mail input; end with .';
        $status = 5;
        break;
    case 554:   $message = 'Transaction failed';

		/*
		$connect = fopen("http://clients.emmmail.net/unsub2.php?client=554&emailaddress=$to","r");
		logf("/tmp/emmmailer.txt.unsubscribes","554: $message : $to unsubscribed\n");
		fclose($connect);
		*/
        $status = 0;
        break;
    default:    $message = 'Unknown response: '. nl2br(htmlspecialchars($lines));
        $status = 0;
        $error_num = '001';
        break;
    }
    
    return $status;
}
if($logging) logf("/tmp/emmmailer.txt","sendSMTP $to, $from_addr!\n");
sendSMTP($to, $from_addr, $subject, $text_message, $html_message, $cc, $bcc, $from_name,$source_ip,$return_path,$logging,$domain_name);

?>
