<?
//=============================//
// //
// MSNStatus v0.2 //
// MSNStatus Class file //
// MSNStatus.Class.php //
// by Stanga Razvan //
// hide@address.com //
// http://www.phprebel.org //
// //
// MADE IN ROMANIA //
// //
//=============================//
class MSNStatus {
var $config;
var $socket;
var $connected;
var $usesockets;
var $nr;
var $state;
var $nrconnect;
var $msn;
var $status;
var $faze;
var $ftp_conn;
var $buffer;
var $loginAddress;
var $loginPath;
var $loginKey;
function MSNStatus () {
$this->config = array ();
$this->socket = array ();
$this->connected = array ();
$this->usesockets;
$this->nr = array ();
$this->nrconnect = array ();
$this->msn = array ();
$this->status = 0;
$this->faze = 0;
$this->ftp_conn;
$this->buffer = array ();
$this->loginAddress = '';
$this->loginPath = '';
$this->loginKey = '';
}
//-------------------------------
// Connect to a given host / port
//-------------------------------
function connect ($host, $port, $connection='msn') {
$address = gethostbyname ($host);
if ( empty ($this->nr[ $connection ]) ) {
$this->nr[ $connection ] = 1;
}
if ( empty ($this->nrconnect[ $connection ]) ) {
$this->nrconnect[ $connection ] = 1;
}
if ( array_search('sockets',get_loaded_extensions()) !== FALSE ) {
$this->debuglog ("NR Connect [".$connection."] : ".$this->nrconnect[ $connection ], 1, "\r\n");
$this->debuglog ("WARNING: your PHP build supports real sockets.", 1);
$this->usesockets = 1;
$this->nrconnect[ $connection ]++;
$this->socket[ $connection ] = socket_create (AF_INET, SOCK_STREAM, 0);
if (!$this->socket[ $connection ]) {
$this->debuglog ('Failed to create socket ', 1);
$this->debuglog ('Error : '. socket_strerror(socket_last_error()) , 1);
$this->debuglog ('Error NR : '. socket_last_error() , 1);
$this->connected[ $connection ] = FALSE;
}
if (!socket_connect($this->socket[ $connection ], $address, $port)) {
$this->debuglog ('Failed to connect to '.$adress, 1);
$this->debuglog ('Error : '. socket_strerror(socket_last_error()) , 1);
$this->debuglog ('Error NR : '. socket_last_error() , 1);
$this->connected[ $connection ] = FALSE;
} else {
$this->debuglog ('CONNECTED ['.$connection.'] '. $host .' ('.$address.'), port '.$port, 2);
$this->connected[ $connection ] = TRUE;
}
} else {
$this->debuglog ("NR Connect [".$connection."] : ".$this->nrconnect[ $connection ], 1, "\r\n");
$this->debuglog ("WARNING: your PHP build doesn't support real sockets.", 1);
$this->usesockets = 0;
$this->nrconnect[ $connection ]++;
if (!$this->socket[ $connection ] = @fsockopen ($address , $port, $errno, $errstr, 30)) {
$this->debuglog ('Failed to connect to '.$adress, 1);
$this->debuglog ('Error : '. $errstr , 1);
$this->debuglog ('Error NR : '. $errno , 1);
$this->connected[ $connection ] = FALSE;
} else {
$this->debuglog ('CONNECTED ['.$connection.'] '. $host .' ('.$address.'), port '.$port, 2);
$this->connected[ $connection ] = TRUE;
}
}
if ($connection == 'msn') {
$this->firstContact ( $connection );
$this->listen ( $host, $port, $connection );
}
}
//--------------
// First Contact
//--------------
function firstContact ( $connection ) {
if ($this->nr[ $connection ] == 1) {
$this->send ("VER ".$this->nr[ $connection ]." MSNP8 CVR0");
} elseif ($this->nr[ $connection ] > 1) {
$this->send ("USR ".$this->nr[ $connection ]." ".$this->config['msnuser']." ".$this->msn['msncki']."");
$this->faze = 1;
}
}
//-------------
// Close socket
//-------------
function close ( $host, $port, $connection='msn' ) {
if ($this->usesockets == 1) {
socket_close( $this->socket[ $connection ] );
$this->connected[ $connection ] = FALSE;
} else {
fclose ($this->socket[ $connection ]);
$this->connected[ $connection ] = FALSE;
}
$this->debuglog ("DISCONNECTED [".$connection."] ".$host.":".$port, 2);
}
//------------------
// Close ALL sockets
//------------------
function closeALL () {
foreach ( $this->socket as $k => $v ) {
if ($this->usesockets == 1) {
socket_close ( $this->socket[ $k ] );
} else {
fclose ( $this->socket[ $k ] );
}
$this->debuglog ("DISCONNECTED [".$connection."] ".$k." -> ".$v, 2);
}
exit ();
}
//-------
// Listen
//-------
function listen ( $host, $port, $connection ) {
if ($this->getState ( $connection ) == TRUE) {
$this->receive ( $host, $port, $connection );
return TRUE;
} else {
return FALSE;
}
}
//------
// State
//------
function getState ( $connection ) {
if ( ( $this->config['time'] + $this->config['timetostay'] ) <= time () ) {
$this->closeALL ();
}
$result = $this->updateState ( $connection );
if ($result == TRUE) {
return TRUE;
} else {
return FALSE;
}
}
//-------------
// Update State
//-------------
function updateState ( $connection ) {
$type = get_resource_type ( $this->socket[ $connection ] );
if( is_resource ($this->socket[ $connection ]) && $this->socket[ $connection ] !== FALSE && ( $type == 'socket' || $type == 'Socket' || $type == 'stream' || $type == 'Stream') ) {
$this->connected[ $connection ] = TRUE;
return TRUE;
} else {
$this->connected[ $connection ] = FALSE;
return FALSE;
}
}
//-------------
// Recieve data
//-------------
function receive ( $host, $port, $connection ) {
while( $this->getState( $connection ) == TRUE ) {
usleep ( $this->config['receivesleep'] );
if ( $this->usesockets == 1 ) {
if ( str_replace ( ".", "", phpversion () ) >= 430 ) {
$r = array ( $this->socket[ $connection ] );
socket_select( $r, $w, $except = NULL, 1 );
}
if ( $_DATA = @socket_read ( $this->socket[ $connection ], 1024 ) ) {
flush ();
$buffer .= $_DATA;
if ( $buffer = ereg_replace("\r\n", "", $buffer ) ) {
$this->do_stuff ( $buffer, $host, $port, $connection );
$buffer = "";
}
} else {
$this->close ( $host, $port, $connection );
sleep($this->config['reconnect_after']);
$this->connect ( $host, $port, $connection );
}
} else {
if ( $_DATA = @fgets ($this->socket[ $connection ], 1024 ) ) {
flush();
$buffer .= $_DATA;
if ( $buffer = ereg_replace("\r\n", "", $buffer ) ) {
$this->do_stuff ( $buffer, $host, $port, $connection );
$buffer = "";
}
} else {
$this->close ( $host, $port, $connection );
sleep($this->config['reconnect_after']);
$this->connect ( $host, $port, $connection );
}
}
}
}
//-------------
// Recieve data
//-------------
function receiveAll ( $host, $port, $connection ) {
while ( !feof ( $this->socket[ $connection ] ) ) {
if ( $this->usesockets == 1 ) {
if ( str_replace ( ".", "", phpversion () ) >= 430 ) {
$r = array ( $this->socket[ $connection ] );
socket_select( $r, $w, $except = NULL, 1 );
}
$_DATA = @socket_read ( $this->socket[ $connection ], 1024 );
flush ();
$buffer .= $_DATA;
} else {
$_DATA = @fgets ($this->socket[ $connection ], 1024 );
flush();
$buffer .= $_DATA;
}
}
$this->buffer[ $connection ] = $buffer;
}
//--------------------
// Send data to socket
//--------------------
function send ($str, $connection='msn') {
usleep ($this->config['sendsleep']);
$str = $str."\r\n";
if ($this->usesockets == 1) {
$res = @socket_write ($this->socket[ $connection ], $str, strlen($str));
if (!$res) {
$this->debuglog ("CAN'T SEND : ". $str, 3);
}
} else {
$res = @fwrite($this->socket[ $connection ], $str, strlen($str));
if (!$res) {
$this->debuglog ("CAN'T SEND : ". $str, 3);
}
}
$this->debuglog ('S >>> : '.$str, 4);
$this->nr[ $connection ]++;
}
//---------
// Do Stuff
//---------
function do_stuff ($buffer, $host, $port, $connection) {
$this->debuglog('R <<< : '.$buffer, 5);
$msg = explode(" ", $buffer);
$msg[0] = strtolower ( $msg[0] );
$msg[2] = strtolower ( $msg[2] );
if ($msg[0] == "ver") {
$this->send("CVR ".$this->nr[ $connection ]." 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS ".$this->config['msnuser']."", $connection);
} elseif($msg[0] == "cvr") {
$this->send("USR ".$this->nr[ $connection ]." TWN I ".$this->config['msnuser']."", $connection);
} elseif ($msg[0] == "usr" AND $msg[2] == "twn") {
$this->loginKey = $msg[4];
$nexus = $this->openNexus ();
if ($nexus) {
$this->send("USR ".$this->nr[ $connection ]." TWN S ".$nexus."", $connection);
} else {
$this->debuglog ('ERROR -> Could not get nexus key', 1);
$this->closeALL ();
}
} elseif ($msg[0] == "usr" AND $msg[2] == "ok") {
if ($this->faze == 0) {
$this->send("CHG ".$this->nr[ $connection ]." NLN 0", $connection);
} else {
$this->send("CAL ".$this->nr[ $connection ]." ".$this->config['checkemail']."", $connection);
}
} elseif ($msg[0] == "chg" AND $msg[2] == "nln") {
$this->send("XFR ".$this->nr[ $connection ]." SB", $connection);
} elseif ($msg[0] == "xfr" AND $msg[2] == "sb") {
$tmp = explode(":", $msg[3]);
$this->msn['msnhost'] = $tmp[0];
$this->msn['msnport'] = $tmp[1];
$this->msn['msncki'] = $msg[5];
$this->close ( $host, $port, $connection );
$this->connect($this->msn['msnhost'], $this->msn['msnport']);
} elseif ($msg[0] == "xfr" AND $msg[2] == "ns") {
$tmp = explode(":", $msg[5]);
$this->msn['msnhost'] = $tmp[0];
$this->msn['msnport'] = $tmp[1];
$this->close ( $host, $port, $connection );
$this->connect($this->msn['msnhost'], $this->msn['msnport']);
} elseif ($msg[0] == "217") {
$this->status = 0;
$this->do_stats ();
$this->closeALL ();
} elseif ($msg[0] == "joi") {
$this->status = 1;
$this->do_stats ();
$this->closeALL ();
}
}
//----------
// Debug Log
//----------
function debuglog ($stuff, $color=1, $f='') {
if ($this->config['debug']) {
$this->writetolog ($f.$stuff."\r\n");
flush ();
echo "<font color=\"".$this->config['colors'][$color]."\">".$stuff."</font><br>";
flush ();
}
}
//--------------
// Write to file
//--------------
function writetolog ($data) {
if ($data!="") {
$filenum=fopen("logs/".$this->config['log']."", "a");
fwrite($filenum, $data);
fclose($filenum);
}
}
//-----------
// FTP Upload
//-----------
function ftp_start () {
$this->ftp_conn = ftp_connect ($this->config['ftp_server'], $this->config['ftp_port']);
$login_result = ftp_login($this->ftp_conn, $this->config['ftp_user'], $this->config['ftp_pass']);
}
function ftp_upload ($filename, $filesource) {
$upload = ftp_put ($this->ftp_conn, $filename, $filesource, FTP_BINARY);
}
function ftp_dir () {
$upload = ftp_chdir($this->ftp_conn, $this->config['ftp_dir']);
}
function ftp_end () {
ftp_quit ($this->ftp_conn);
}
//---------------
// Make The Stats
//---------------
function do_stats () {
if ($this->status) {
$img = "online.gif";
} else {
$img = "offline.gif";
}
if ($this->config['post']) {
$this->sendData();
}
if ($this->config['ftp_active']) {
$this->ftp_start ();
$this->ftp_dir();
$this->ftp_upload ($this->config['imagename'], "templates/".$img."");
$this->ftp_end ();
}
if ($this->config['imagereplace']) {
if ( file_exists ($this->config['imagepath']."/".$this->config['imagename']) ) {
unlink ($this->config['imagepath']."/".$this->config['imagename']);
}
copy ($this->config['templates']."/".$img."", $this->config['imagepath']."/".$this->config['imagename']);
}
}
//--------
// Send To
//--------
function sendTo ($host, $method, $path, $data, $useragent=0) {
if (empty($method)) {
$method = 'GET';
}
$method = strtoupper($method);
$connection = 'sendTO';
$this->connect($host, 80, $connection);
if ($method == 'GET') {
$path .= '?' . $data;
}
$msg = '';
$msg .= "".$method." ".$path." HTTP/1.0\r\n";
$msg .= "Host: ".$host."\r\n";
$msg .= "Content-type: application/x-www-form-urlencoded\r\n";
$msg .= "Content-length: " . strlen($data) . "\r\n";
if ($useragent) {
$msg .= "User-Agent: MSIE\r\n";
$msg .= "Connection: close\r\n\r\n";
}
$this->send ($msg, $connection);
if ($method == 'POST') {
$this->send ($data, $connection);
}
$this->close ($host, 80, $connection);
}
function sendData () {
$host = $this->config['posttourl'];
$method = "POST";
$path = $this->config['posttopath'];
$data = "email=".$this->config['checkemail']."&status=".$this->status."";
$useragent = 1;
$buffer = $this->sendTo ($host,$method,$path,$data,$useragent);
$this->debuglog ("Data Sent : ".$buffer, 4);
}
function openNexus () {
$host = 'ssl://'.$this->config['nexushost'];
$port = $this->config['nexusport'];
$connection = 'nexus';
$this->connect ( $host, $port, $connection );
if ( $this->connected[ $connection ] == FALSE ) {
$this->debuglog ('ERROR -> could not connect to nexus', 1);
$this->closeALL ();
} else {
$this->send ("GET /rdr/pprdr.asp HTTP/1.0\r\n\r\n", $connection);
$this->receiveAll ( $host, $port, $connection );
$this->debuglog('R <<< [NEXUS] : '.$this->buffer[ $connection ], 5);
$this->close ($host, $port, $connection);
if ( preg_match( '/DALogin=(.*)\/(.*),DAReg/i', $this->buffer[ $connection ], $matches ) ) {
$this->loginAddress = $matches[1];
$this->loginPath = $matches[2];
$ret = $this->loginServer ();
if ($ret) {
return $ret;
} else {
$this->debuglog ('ERROR -> error getting key', 1);
$this->closeALL ();
}
} else {
$this->debuglog ('ERROR -> nexus error', 1);
$this->closeALL ();
}
}
}
function loginServer () {
$ret = FALSE;
$host = 'ssl://'.$this->loginAddress;
$port = 443;
$connection = 'login';
$this->connect ( $host, $port, $connection );
if ( ! $this->connected[ $connection ] ) {
$this->debuglog ('ERROR -> could not connect to login server', 1);
$this->closeALL ();
} else {
$msg = '';
$msg .= "GET /" . $this->loginPath . " HTTP/1.1\r\n";
$msg .= "Authorization: Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=" . $this->config['msnuser'] . ",pwd=" . $this->config['msnpassword'] . "," . $this->loginKey . "\r\n";
$msg .= "Host: " . $this->loginAddress . "\r\n";
$msg .= "\r\n";
$this->send ($msg, $connection);
$this->receiveAll ( $host, $port, $connection );
$this->debuglog('R <<< [LOGIN] : '.$this->buffer[ $connection ], 5);
$this->close ( $host, $port, $connection );
if ( substr_count( $this->buffer[ $connection ], 'HTTP/1.1 302 Found' ) == 1 ) {
if ( preg_match( '/Location: https:\/\/(.*)\/(.*)\r\n/i', $this->buffer[ $connection ], $matches ) ) {
$this->loginAddress = $matches[ 1 ];
$this->loginPath = $matches[ 2 ];
$this->loginServer ();
} else {
$this->debuglog ('ERROR -> no login server', 1);
$this->closeALL ();
}
} else if ( substr_count( $this->buffer[ $connection ], 'HTTP/1.1 200 OK' ) == 1 ) {
if ( preg_match( '/from-PP=\'(.*)\',ru/i', $this->buffer[ $connection ], $matches ) ) {
$ret = $matches[ 1 ];
return $ret;
} else {
$this->debuglog ('ERROR -> no key', 1);
$this->closeALL ();
}
} else if ( substr_count( $this->buffer[ $connection ], 'HTTP/1.1 401 Unauthorized' ) == 1 ) {
$this->debuglog ('ERROR -> authentication failed', 1);
$this->closeALL ();
} else {
$this->debuglog ('ERROR -> unknown', 1);
$this->closeALL ();
}
}
return $ret;
}
} // End Class
?>