<?
// Wapmess, originally developed by Gцran (depeh) Johansson, Sweden
//
// Feel free to improve this program in any way you can, but please share your version!
// More info and the latest version is avaiable at:
// http://sourceforge.net/projects/wapmess/
require_once("config.php");
require_once("rtfclass.php");
function icqimage2smiley($data)
{
$sea = array ('<##icqimage0000>',
'<##icqimage0001>',
'<##icqimage0002>',
'<##icqimage0003>',
'<##icqimage0004>',
'<##icqimage0005>',
'<##icqimage0006>',
'<##icqimage0007>',
'<##icqimage0008>',
'<##icqimage0009>',
'<##icqimage000a>',
'<##icqimage000b>',
'<##icqimage000c>',
'<##icqimage000d>',
'<##icqimage000e>',
'<##icqimage000f>');
//:-):-O:-|:-/:-(:-{}:*):'-(;-):-@:-<:-X:-P8-)O-):-D
$repl = array (":)",
":o",
":|",
":/",
":(",
":*",
":}",
";(",
";)",
">:o",
":C",
":X",
":p",
"8)",
"0:)",
":D");
return str_replace($sea,$repl,$data);
}
function rtf2txt($data)
{
$sea = array ("\'e5","\'e4","\'f6","\'c5","\'c4","\'d6");
$repl = array ("е","д","ц","Е","Д","Ц");
if (substr($data,2,4)=="rtf1")
{
$data=str_replace($sea,$repl,$data);
$r = new rtf($data);
$r->output("html");
$r->parse();
$data=$r->out;
$data=strip_tags($data);
}
return $data;
}
function wml_header()
{
header("Content-type: text/vnd.wap.wml");
}
function xml_header()
{
print "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>";
print "<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">";
}
function no_cache_header()
{
#header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
#header("Last-Modified: DD. month YYYY HH:MM:SS GMT");
#header("Cache-Control: no-cache, must-revalidate");
#header("Pragma: no-cache");
}
function send_status_list($uin_status)
{
global $my_uin;
if (count($uin_status)==0)
{
return;
}
$status_str="";
foreach ($uin_status as $key => $value)
{
$status_str.="$key=$value,";
}
$status_str=substr($status_str,0,-1);
$query="SELECT uin FROM uinstatus WHERE uin='".$my_uin."'";
if ($debug)print "sql = $query\n";
$sqlres=mysql_query($query) or die("send_status Invalid query: " . mysql_error());
$num_rows = mysql_num_rows($sqlres);
if ($num_rows>0)
{
$query="UPDATE uinstatus SET statusstr='".$status_str."' WHERE uin=".$my_uin."";
$updres=mysql_query($query) or die("send_status Invalid query: " . mysql_error());
}
else
{
$query="INSERT INTO uinstatus (uin,statusstr) VALUES ('".$my_uin."','".$status_str."')";
$insres=mysql_query($query) or die("send_status Invalid query: " . mysql_error());
}
}
function send_data($fp,$datastr)
{
// Skicka request
if (fwrite($fp, $datastr, strlen($datastr)))
{
return $datastr;
}
else
{
return "CANT SEND ERROR!";
}
}
function recieve_data($fp)
{
// Ta emot request
$str="";
$data_empty=1;
while ($data_empty==1)
{
$str = fread($fp,32767);
//print $data;
if ($str!="")
{
#print "rec datalen:".strlen($str)."\n";
$data_empty=0;
}
//$data_empty=0;
}
return $str;
}
function parse_srv_cookie($str)
{
$srv_cookie_a = Array();
$ps=0;
$uin_len=bsubword2d($str,ps+8);
$srv_cookie_a["uin"]=substr($str,ps+10,$uin_len);
$ps+=6+4+$uin_len;
$ip_len=bsubword2d($str,$ps+2);
$ip_addr=substr($str,$ps+4,$ip_len);
//print "substr =".$ip_addr."=\n";
// Om vi fеr ett http:// - svar sе har fцrmodligen nеgot gеtt fel
if (substr(($ip_addr),0,7) == "http://")
{
$srv_cookie_a["ip"]=$ip_addr;
$srv_cookie_a["port"]="";
}
else
{
$ip_split=split(":",$ip_addr,2);
$srv_cookie_a["ip"]=$ip_split[0];
$srv_cookie_a["port"]=$ip_split[1];
}
//print "ip ".$ip."\n";
$ps+=4+$ip_len;
$cookie_len=bsubword2d($str,$ps+2);
$srv_cookie_a["cookie"]=substr($str,$ps+4,$cookie_len);
//print "cookie ".b2rh($cookie)."\n";
return $srv_cookie_a;
}
function is_disconnect($str)
{
$ps=0;
if (ord($str[$ps+0])==42 && // Flap header
ord($str[$ps+1])==4 && // Channel 4
ord($str[$ps+7])==9 && // SNAC ($9,$2)
ord($str[$ps+9])==2)
{
return ord($str[$ps+11]);
}
else
{
return false;
}
}
function is_msgs($str)
{
$ps=0;
if ((ord($str[$ps+0])==42 && // Flap header
ord($str[$ps+1])==2 && // Channel 2
ord($str[$ps+7])==21 && // SNAC
ord($str[$ps+9])==3) // $15,$3
||
(ord($str[$ps+0])==42 && // Flap header
ord($str[$ps+1])==2 && // Channel 2
ord($str[$ps+7])==4 && // SNAC
ord($str[$ps+9])==7)) //
{
return true;
}
else
{
return false;
}
}
function parse_msgs($str)
{
global $my_uin,$debug,$fp,$cli_seq;
#print "parse_msgs \n";
$msgs_a = Array();
$mcount=0;
$ps=0;
$str_len=strlen($str);
#print "str_len=$str_len \n";
while ($ps<$str_len)
{
$flap_len=bsubword2d($str,$ps+4)+6;
#print "flap_len=$flap_len \n";
// Kolla att flap'en дr ett offline-server-mess
if (ord($str[$ps+0])==42 && // Flap header
ord($str[$ps+1])==2 && // Channel 2
ord($str[$ps+7])==21 && // SNAC
ord($str[$ps+9])==3 && // $15,$3
ord($str[$ps+11])==1) // Tror det betyder att meddelande finns.
{
#print "FLAP:".b2rh(substr($str,$ps,$flap_len))."\n\n";
$from_uin=bsubdwordflip2d($str,$ps+30);
$from_year=bsubwordflip2d($str,$ps+34);
$from_month=sprintf("%02d",ord($str[$ps+36]));
$from_day=sprintf("%02d",ord($str[$ps+37]));
$from_hour=sprintf("%02d",ord($str[$ps+38]));
$from_minute=sprintf("%02d",ord($str[$ps+39]));
$msg_type=bsubwordflip2d($str,$ps+40);
$msg_len=bsubwordflip2d($str,$ps+42)-1;
$msg_text=substr($str,$ps+44,$msg_len);
$msg_text=icqimage2smiley($msg_text);
// Meddelandet дr tomt, avbryt
if (trim($msg_text)=="")break;
$when="$from_year-$from_month-$from_day $from_hour:$from_minute";
if ($debug)print "OFFLINE-MSG:\nfrom: $from_uin\n";
if ($debug)print "time: $when\n";
if ($debug)print "mess: $msg_text\n\n";
/*
$msgs_a[$mcount]["from"]=$from_uin;
$msgs_a[$mcount]["time"]=$when;
$msgs_a[$mcount]["msg"]=$msg_text;
*/
// (fromuin,touin,msg,when)
$query = "INSERT INTO incoming ( `id` , `fromuin` , `touin` , `msg` , `msgtime` , `online` ) VALUES (0,'".$from_uin."','".$my_uin."','".$msg_text."','".$when."',0)";
if ($debug)print "sql=$query\n";
mysql_query($query);
$mcount++;
}
// Kolla om flap'en дr ett offline-mess READY mess
if (ord($str[$ps+0])==42 && // Flap header
ord($str[$ps+1])==2 && // Channel 2
ord($str[$ps+7])==21 && // SNAC
ord($str[$ps+9])==3 && // $15,$3,$0,$1
ord($str[$ps+11])==0 && //
ord($str[$ps+13])==1) // Tror det betyder att meddelande finns.
{
if ($debug)print "OFFLINE-READY!\n";
cli_sendoffline_ack();
}
// Kolla om flap'en дr ett SRV-ROOSTER meddelande
if (ord($str[$ps+0])==42 && // Flap header
ord($str[$ps+1])==2 && // Channel 2
ord($str[$ps+7])==19 && // SNAC
ord($str[$ps+9])==6) // $13,$6
{
if ($debug)print "SRV-ROOSTER!\n";
$query="DELETE FROM contactlist WHERE uin='".$my_uin."'";
$delres=mysql_query($query);
$tps=$ps;
// Flytta pekaren 17 steg framеt
$tps+=17;
$num_items=bsubword2d($str,$tps);
if ($debug)print "num items=".$num_items."\n";
// Flytta pekaren 9 steg framеt
$tps+=9;
if ($debug)print "roster type=".ord($str[$tps])."\n";
// Kolla lдngden pе nдstfцljande TLV
$tlv_len=bsubword2d($str,$tps+1);
if ($debug)print "TLV =".dechex(bsubword2d($str,$tps+3))."\n";
// Rдkna ut hur mеnga olika grupper vi har
$roster_groups=$tlv_len/2-2;
if ($debug)print "roster_groups=".$roster_groups."\n";
// Hдmta upp roster idn
for ($i=0;$i<$roster_groups;$i++)
{
$roster_id[$i]=bsubword2d($str,$tps+7+2*$i);
if ($debug)print "roster_id $i =".dechex($roster_id[$i])."\n";
}
// Flytta pekaren fцrbi tlvn
$tps+=$tlv_len+3;
/*
if ($roster_groups>1)
{
$tps+=6;
if(bsubword2d($str,$tps)==4)
{
$tps+=bsubword2d($str,$tps+2)+4;
$tps+=bsubword2d($str,$tps)+6;
}
if(bsubword2d($str,$tps)==9)
{
$tps+=bsubword2d($str,$tps+2)+4;
}
}
$groupname_len=bsubword2d($str,$tps);
if ($debug)print "groupname_len=".$groupname_len."\n";
// Flytta pekaren fцrbi gruppnamnet
$tps+=$groupname_len+8;
*/
// Flytta pekaren tills man stцter pе 00 00 00 01
while (!(bsubword2d($str,$tps)==0 && bsubword2d($str,$tps+2)==1 && bsubword2d($str,$tps+6)==200))
{
$tps+=1;
}
$tps+=4;
// Kolla hur lеngt man ska gе
$dist=bsubword2d($str,$tps);
#print "Dist: $dist\n";
#print b2rh(substr($str,$tps,16));
// Flytta pekaren fцrbi grupp info fram till fцrsta UIN
$tps+=$dist+2;
// Gе igenom hela flapen
while ($tps<($flap_len+$ps))
{
$uin=get_uinstr($str,$tps);
// Om uin дr tom sе avbryter vi loopen
if ($uin=="")break;
// Flytta pekaren fцrbi uin
$tps+=strlen($uin)+2;
// Gе till nдrmaste 00 00 -word
$tps=scan_zeroword($str,$tps);
$tlv_len=bsubword2d($str,$tps+2);
// tlvs lдngd дr 1 sе дr detta en grupp header?
if ($tlv_len==1)
{
// Hдmta lдngden frеn nдsta WORD
$tlv_len=bsubword2d($str,$tps+4);
// Flytta pekaren fцrbi tlvn
$tps+=$tlv_len+6;
// Lдs in UIN igen
$uin=get_uinstr($str,$tps);
// Flytta pekaren fцrbi uin
$tps+=strlen($uin)+2;
$tps=scan_zeroword($str,$tps);
$tlv_len=bsubword2d($str,$tps+2);
}
// Flytta pekaren fцrbi tlv-header
$tps+=4;
//Kolla efter 01 31 (Nick header)
if (ord($str[$tps])==1 && ord($str[$tps+1])==49)
{
// Hдmta lдngd pе nick
$nick_len=bsubword2d($str,$tps+2);
#if ($debug)print "nick_len=".$nick_len."\n";
$nick=utf8_decode(substr($str,$tps+4,$nick_len));
#if ($debug)print "nick=".$nick."\n";
if ($debug)print $nick." ($uin)\n";
if ($nick!="")
{
$query = "INSERT INTO contactlist ( `id` , `uin` , `cnick` , `cuin` ) VALUES (0,'".$my_uin."','".$nick."','".$uin."')";
if ($debug)print "sql=$query\n";
mysql_query($query);
}
}
$tps+=$tlv_len;
}
}
// Kolla om flap'en дr ett ONLINE mess!
if (ord($str[$ps+0])==42 && // Flap header
ord($str[$ps+1])==2 && // Channel 2
ord($str[$ps+7])==4 && // SNAC
ord($str[$ps+9])==7 && // Tror det betyder att meddelande finns.
ord($str[$ps+25])==1) // Type 1 meddelande = Gammal typ
{
#print "FLAP:".b2rh(substr($str,$ps,$flap_len))."\n\n";
$uin_len=ord($str[$ps+26]);
$from_uin=substr($str,$ps+27,$uin_len);
#print "uin_len = $uin_len \n";
#print "from_uin = $from_uin \n";
// Flytta pekaren framеt tills efter UIN'en och efter 2 tomma bytes
$tmp_ps=$ps+27+$uin_len+2;
//
#print "tmp_ps = $tmp_ps \n";
// Hдmta antalet tlver som fцljer
$tlv_num=bsubword2d($str,$tmp_ps);
#print "tlv_num = $tlv_num \n";
// Flytta pekaren framеt
$tmp_ps+=2;
while ($tlv_num>0)
{
$tlv_id=ord($str[$tmp_ps+1]);
if ($tlv_id==1)$tmp_ps+=6;
if ($tlv_id==4)$tmp_ps+=6;
if ($tlv_id==6)$tmp_ps+=8;
if ($tlv_id==15)$tmp_ps+=8;
if ($tlv_id==2)$tmp_ps+=8;
if ($tlv_id==3)$tmp_ps+=8;
#print "tlv_id = $tlv_id (".$tmp_ps.") \n";
$tlv_num--;
}
#print "tmp_ps = $tmp_ps \n";
// Flytta pekaren
$stlv_len=bsubword2d($str,$tmp_ps+6);
// flytta fцrbi pekare fцrbi sista tlvn
$tmp_ps+=10+$stlv_len;
#print "tmp_ps = $tmp_ps \n";
#print "STLV_LEN = $stlv_len \n";
$msg_len=bsubword2d($str,$tmp_ps)-4;
$msg_text=substr($str,$tmp_ps+6,$msg_len);
$when=date("Y-m-d H:i");
if ($debug)print "ONLINE-MSG1 :\nfrom: $from_uin\n";
if ($debug)print "time: $when\n";
if ($debug)print "mess: (".$msg_len.") $msg_text\n\n";
$msg_text=icqimage2smiley($msg_text);
// Meddelandet дr tomt, avbryt
if (trim($msg_text)=="")break;
/*
$msgs_a[$mcount]["from"]=$from_uin;
$msgs_a[$mcount]["time"]=$when;
$msgs_a[$mcount]["msg"]=$msg_text;
*/
// (fromuin,touin,msg,when)
$query = "INSERT INTO incoming ( `id` , `fromuin` , `touin` , `msg` , `msgtime` , `online` ) VALUES (0,'".$from_uin."','".$my_uin."','".$msg_text."','".$when."',1)";
if ($debug)print "sql=$query\n";
mysql_query($query);
$mcount++;
}
// Kolla om flap'en дr ett ONLINE mess!
if (ord($str[$ps+0])==42 && // Flap header
ord($str[$ps+1])==2 && // Channel 2
ord($str[$ps+7])==4 && // SNAC
ord($str[$ps+9])==7 && // Tror det betyder att meddelande finns.
ord($str[$ps+25])==2) // Type 2 meddelande = Ny typ
{
#print "FLAP:".b2rh(substr($str,$ps,$flap_len))."\n\n";
$uin_len=ord($str[$ps+26]);
$from_uin=substr($str,$ps+27,$uin_len);
#print "uin_len = $uin_len \n";
#print "from_uin = $from_uin \n";
// Flytta pekaren framеt tills efter UIN'en och efter 2 tomma bytes
$tmp_ps=$ps+27+$uin_len+2;
//
#print "tmp_ps = $tmp_ps \n";
// Hдmta antalet tlver som fцljer
$tlv_num=bsubword2d($str,$tmp_ps);
#print "tlv_num = $tlv_num \n";
// Flytta pekaren framеt
$tmp_ps+=2;
while ($tlv_num>0)
{
$tlv_id=ord($str[$tmp_ps+1]);
if ($tlv_id==1)$tmp_ps+=6;
if ($tlv_id==4)$tmp_ps+=6;
if ($tlv_id==6)$tmp_ps+=8;
if ($tlv_id==15)$tmp_ps+=8;
if ($tlv_id==2)$tmp_ps+=8;
if ($tlv_id==3)$tmp_ps+=8;
#print "tlv_id = $tlv_id (".$tmp_ps.") \n";
$tlv_num--;
}
#print "tmp_ps = $tmp_ps \n";
// Om det INTE дr ett meddelande..
if (ord($str[$tmp_ps+5])!=0 || ord($str[$tmp_ps+48])!=0)
{ // avbryt
break;
}
// flytta pekaren 111 steg!
$tmp_ps+=95; // 5F
print "tmp_ps = $tmp_ps \n";
$msg_len=bsubwordflip2d($str,$tmp_ps)-1;
$msg_text=substr($str,$tmp_ps+2,$msg_len);
$msg_text=rtf2txt($msg_text);
$msg_text=icqimage2smiley($msg_text);
// Meddelandet дr tomt, avbryt
if (trim($msg_text)=="")break;
$when=date("Y-m-d H:i");
if ($debug)print "ONLINE-MSG2 :\nfrom: $from_uin\n";
if ($debug)print "time: $when\n";
if ($debug)print "mess: (".$msg_len.") $msg_text\n\n";
/*
$msgs_a[$mcount]["from"]=$from_uin;
$msgs_a[$mcount]["time"]=$when;
$msgs_a[$mcount]["msg"]=$msg_text;
*/
// (fromuin,touin,msg,when)
$query = "INSERT INTO incoming ( `id` , `fromuin` , `touin` , `msg` , `msgtime` , `online` ) VALUES (0,'".$from_uin."','".$my_uin."','".$msg_text."','".$when."',1)";
if ($debug)print "sql=$query\n";
mysql_query($query);
$mcount++;
}
$ps+=$flap_len;
}
// Strunta i att returnera messen och returnera enbart antalet
return $mcount;
}
function parse_onoffline($str)
{
global $uin_status;
#print "parse_msgs \n";
$mcount=0;
$ps=0;
$str_len=strlen($str);
#print "str_len=$str_len \n";
while ($ps<$str_len)
{
$flap_len=bsubword2d($str,$ps+4)+6;
#print "flap_len=$flap_len \n";
// Kolla att flap'en дr en user_online
if (ord($str[$ps+0])==42 && // Flap header
ord($str[$ps+1])==2 && // Channel 2
ord($str[$ps+7])==3 && // SNAC
ord($str[$ps+9])==12) // $3,$C
{
$uin_len=ord($str[$ps+16]);
$uin=substr($str,$ps+17,$uin_len);
$uin_status[$uin]=0;
print "USER: $uin is OFFLINE!\n";
}
// Kolla att flap'en дr en user_online
if (ord($str[$ps+0])==42 && // Flap header
ord($str[$ps+1])==2 && // Channel 2
ord($str[$ps+7])==3 && // SNAC
ord($str[$ps+9])==11) // $3,$B
{
$uin_len=ord($str[$ps+16]);
$uin=substr($str,$ps+17,$uin_len);
$uin_status[$uin]=1;
print "USER: $uin is ONLINE!\n";
}
$ps+=$flap_len;
}
}
function cli_keepalive($seq_no)
{
return (
flap(5,$seq_no,"")
);
}
function cli_dis($seq_no)
{
return (
flap(4,$seq_no,"")
);
}
function cli_toicqsrv($seq_no,$icq_cmd)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (15,2)
h2b("00 15 00 02 00 00 00 01 00 02"). // SNAC (15,2)
h2b("00 01 00 0A").$icq_cmd
)
);
}
function cli_sendoffline_ack()
{
global $cli_seq,$my_uin,$fp;
// Skicka CLI_TOICQSRV ACK_OFFLINEMSGS (Svara att meddelandena дr mottagna)
$icq_cmd=h2b("08 00").
d2bdwordflip($my_uin). // IPadressen hex-baklдnges
h2b("3E 00").
h2b("02 00");
$cli_seq++;
$res=b2rh(send_data($fp,cli_toicqsrv($cli_seq,$icq_cmd)))."\n";
}
function cli_sendmsg($seq_no,$uin,$mess)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (4,6)
h2b("00 04 00 06 00 00 00 00 00 00"). // SNAC (4,6)
h2b("00 00 00 00 01 02 03 04"). //Message cookie
h2b("00 01"). //Msg format
chr(strlen($uin)).$uin. // Mottagare UIN
h2b("00 02").tlvstr
(
h2b("05 01 00 01 01").
h2b("01 01").
tlvsendstr($mess)
).
h2b("00 06 00 00")
)
);
}
//h2b("00 01").tlvstr("52874461")
function cli_setuserinfo($seq_no,$vers)
{
$vers=3;
// 2001
$cap[0]= h2b("09 46 13 49 4C 7F 11 D1 82 22 44 45 53 54 00 00").
h2b("97 B1 27 51 24 3C 43 34 AD 22 D6 AB F7 3F 14 92").
h2b("2E 7A 64 75 FA DF 4D C8 88 6F EA 35 95 FD B6 DF").
h2b("09 46 13 44 4C 7F 11 D1 82 22 44 45 53 54 00 00");
// 2002a
$cap[1]= h2b("09 46 13 49 4c 7f 11 d1 82 22 44 55 53 54 00 00").
h2b("09 46 13 4e 4c 7f 11 d1 82 22 44 45 53 54 00 00").
h2b("97 b1 27 51 24 3c 43 34 ad 22 d6 ab f7 3f 14 92").
h2b("09 46 13 44 4c 7f 11 d1 82 22 44 45 53 54 00 00");
// Trillian
$cap[2]= h2b("09 46 13 49 4C 7F 11 D1 82 22 44 45 53 54 00 00").
h2b("09 46 13 44 4C 7F 11 D1 82 22 44 45 53 54 00 00").
h2b("97 B1 27 51 24 3C 43 34 AD 22 D6 AB F7 3F 14 09").
h2b("2E 7A 64 75 FA DF 4D C8 88 6F EA 35 95 FD B6 DF").
h2b("F2 E7 C7 F4 FE AD 4D FB B2 35 36 79 8B DF 00 00");
$cap[3]= h2b("09 46 13 49 4C 7F 11 D1 82 22 44 45 53 54 00 00").
h2b("09 46 13 4E 4C 7F 11 D1 82 22 44 45 53 54 00 00").
h2b("97 B1 27 51 24 3C 43 34 AD 22 D6 AB F7 3F 14 92").
h2b("09 46 13 44 4C 7F 11 D1 82 22 44 45 53 54 00 00");
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (2,4)
h2b("00 02 00 04 00 00 00 00 00 00"). // SNAC (2,4)
h2b("00 05").tlvstr
(
$cap[$vers]
)
)
);
}
function cli_ready($seq_no)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (1,2)
h2b("00 01 00 02 00 00 00 00 00 00"). // SNAC (1,2)
h2b("00 01 00 03 01 10 04 7B").
h2b("00 13 00 02 01 10 04 7B").
h2b("00 02 00 01 01 01 04 7B").
h2b("00 03 00 01 01 10 04 7B").
h2b("00 15 00 01 01 10 04 7B").
h2b("00 04 00 01 01 10 04 7B").
h2b("00 06 00 01 01 10 04 7B").
h2b("00 09 00 01 01 10 04 7B").
h2b("00 0A 00 01 01 10 04 7B").
h2b("00 0B 00 01 01 10 04 7B")
)
);
}
function cli_seticbm($seq_no)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (4,2)
h2b("00 04 00 02 00 00 00 00 00 00"). // SNAC (4,2)
h2b("00 00").
h2b("00 00").
h2b("00 03").
h2b("1F 40").
h2b("03 E7").
h2b("03 E7").
h2b("00 00").
h2b("00 00")
)
);
}
function cli_unknown1($seq_no)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (13,7)
h2b("00 13 00 07 00 00 00 00 00 00") // SNAC (13,7)
)
);
}
function cli_reqlocation($seq_no)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (2,2)
h2b("00 02 00 02 00 00 00 00 00 00") // SNAC (2,2)
)
);
}
function cli_reqbuddy($seq_no)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (3,2)
h2b("00 03 00 02 00 00 00 00 00 00") // SNAC (3,2)
)
);
}
function cli_reqbos($seq_no)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (9,2)
h2b("00 09 00 02 00 00 00 00 00 00") // SNAC (9,2)
)
);
}
function cli_reqicbm($seq_no)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (4,4)
h2b("00 04 00 04 00 00 00 00 00 00") // SNAC (4,4)
)
);
}
function cli_reqroster($seq_no)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (13,4)
h2b("00 13 00 05 00 00 00 01 00 04"). // SNAC (13,4)
h2b("01 02 03 04").
h2b("00 ff")
)
);
}
function cli_reqroster2($seq_no)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (13,4)
h2b("00 13 00 04 00 00 00 01 00 04") // SNAC (13,4)
)
);
}
function cli_requnknown($seq_no)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (13,2)
h2b("00 13 00 02 00 00 00 00 00 00") // SNAC (13,2)
)
);
}
function cli_reqinfo($seq_no)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (1,E)
h2b("00 01 00 0E 00 00 00 00 00 00") // SNAC (1,E)
)
);
}
function cli_ackrates($seq_no)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (1,8)
h2b("00 01 00 08 00 00 00 00 00 00"). // SNAC (1,8)
h2b("00 01").
h2b("00 02").
h2b("00 03").
h2b("00 04").
h2b("00 05")
)
);
}
function cli_ratesrequest($seq_no)
{
return (
flap(2,$seq_no, // CHANNEL 2 SNAC (1,6)
h2b("00 01 00 06 00 00 00 00 00 00") // SNAC (1,6)
)
);
}
function cli_snac1_11($seq_no)
{
return ( // CHANNEL 2 SNAC (1,11)
flap(2,$seq_no,
h2b("00 01 00 11 00 00 00 00 00 11"). // SNAC (1,11)
h2b("00 00 00 3C")
)
);
}
function cli_setstatus($seq_no)
{
return ( // CHANNEL 2 SNAC (1,1E)
flap(2,$seq_no,
h2b("00 01 00 1E 00 00 00 00 00 00"). // SNAC (1,1E)
h2b("00 06 00 04").
h2b("20 00 00 00"). // Sдtt STATUS
h2b("00 08 00 02 00 00"). // Error code?
h2b("00 0C 00 25").
h2b("7F 00 00 01"). // Sдtt intern ip-adress
h2b("00 00 2E 44"). // Sдtt port
h2b("04 00 08"). // Sдtt vanlig koppling + version 8
h2b("B5 87 DF 58"). // Direct connect cookie
h2b("00 00 00 50 00 00 00 03"). // okдnda params + 3 items
h2b("3B A8 DB AF"). // 3B A8 DB AF
h2b("3B A8 DB AF").
h2b("3B A8 DB AF").
h2b("00 00")
)
);
}
/*
This sets the client's online status and some flags:
00xxxxxx = allow direct connection with everyone
10xxxxxx = allow direct connection upon authorization
20xxxxxx = allow direct connection with users in contact list
xx02xxxx = show IP
xx03xxxx = webaware
xxxx0000 = online
xxxx0100 = invisible
xxxx0001 = away
xxxx0005 = NA
xxxx0011 = Occupied
xxxx0013 = DND
xxxx0020 = Free for chat
STATUS_OFFLINE 0xffffffff The user is offline. / Set status to offline.
STATUS_ONLINE 0x00000000 The user is online. / Set status to online.
STATUS_INVISIBLE 0x00000100 Set status to invisible.
STATUS_DND 0x00000013 Set status to do not disturb.
STATUS_OCCUPIED 0x00000011 Set status to occupied.
STATUS_NA 0x00000005 Set status to not available.
STATUS_AWAY 0x00000001 Set status to away.
STATUS_FFC 0x00000020 Set status to free for chat.
STATUSF_WEBAWARE 0x00010000 The user is web-aware.
STATUSF_IP 0x00020000 The user allows his IP to be shown. (that must actually be wrong)
STATUSF_BIRTH 0x00080000 The user's birthday is today.
STATUSF_UNK 0x00100000 Unknown.
STATUSF_DCAUTH 0x10000000 The user allows direct connections only upon authorization.
STATUSF_DCCONTACT 0x20000000 The user allows direct connections only with contacts.
STATUSF_UNUSED 0xcfe4fec8 As of yet unused flags.
*/
function cli_families($seq_no)
{
return ( // CHANNEL 2 SNAC (1,17)
flap(2,$seq_no,
h2b("00 01 00 17 00 00 00 00 00 00"). // SNAC (1,17)
h2b("00 01 00 03").
h2b("00 13 00 02").
h2b("00 02 00 01").
h2b("00 03 00 01").
h2b("00 15 00 01").
h2b("00 04 00 01").
h2b("00 06 00 01").
h2b("00 09 00 01").
h2b("00 0A 00 01").
h2b("00 0B 00 01")
)
);
}
function cli_cookie($seq_no,$cookie)
{
return (
flap(1,$seq_no,
h2b("00 00 00 01"). // HELLO
h2b("00 06").tlvstr($cookie)
)
);
}
function cli_ident($seq_no,$uin,$pass)
{
return (
flap(1,$seq_no,
h2b("00 00 00 01"). // HELLO
h2b("00 01").tlvstr($uin). // UIN
h2b("00 02").tlvstr(icqcrypt($pass)). // PW
h2b("00 03").tlvstr("ICQ Inc. - Product of ICQ (TM).2003a.5.47.1.3800.85"). // Client version
h2b("00 16 00 02 01 0A").
h2b("00 17 00 02 00 05"). //5 //4 //5 // 5
h2b("00 18 00 02 00 2F"). //15 //55 //55 // 17 // 47
h2b("00 19 00 02 00 01"). //1 //1 // 1 // 1 //
h2b("00 1A 00 02 0E D8"). //3728 //3264 //3800 //3800
h2b("00 14 00 04 00 00 00 55"). // 85 // 85
h2b("00 0F"). tlvstr("en"). // Language
h2b("00 0E"). tlvstr("us") // Country
)
);
// ICQ Inc. - Product of ICQ (TM).2002a.5.37.1.3728.85
}
function icqcrypt($instr)
{
$icqcrypt_s = "f32681c43986db9271a3b9e6537a957c";
$outstr="";
for ($i=0;$i<strlen($instr);$i++)
{
$iccount=$i % 16;
$f1b=ord(substr($instr,$i,1));
$f2b=ord(h2b(substr($icqcrypt_s,$iccount*2,2)));
#print $iccount;
#print $f1b." - ".$f2b."\n";
$f3b = $f1b ^ $f2b;
$outstr.=chr($f3b);
}
return $outstr;
}
function smart_utf8_decode($in_str)
{
// Replace ? with a unique string
$new_str = str_replace("?", "q0u0e0s0t0i0o0n", $in_str);
// Try the utf8_decode
$new_str=utf8_decode($in_str);
// if it contains ? marks
if (strpos($new_str,"?")>0)
{
// Something went wrong, set new_str to the original string.
$new_str=$in_str;
}
else
{
// If not then all is well, put the ?-marks back where is belongs
$new_str = str_replace("q0u0e0s0t0i0o0n", "?", $new_str);
}
return $new_str;
}
function amp($str)
{
return str_replace("&","&",$str);
}
function to_wml($str)
{
$str=htmlspecialchars($str,ENT_QUOTES);
return $str;
}
function h2b($hexdata)
{
$hexdata = str_replace(" ","",$hexdata);
for ($i=0;$i<strlen($hexdata);$i+=2) {
$bindata.=chr(hexdec(substr($hexdata,$i,2)));
}
return $bindata;
}
function b2h($bindata)
{
$hexdata="";
for ($i=0;$i<strlen($bindata);$i++)
{
$hexdata.=sprintf("%02X",ord($bindata[$i]));
}
return $hexdata;
}
function b2rh($bindata)
{
$ss="";
$hexdata="\n";
for ($i=0;$i<strlen($bindata);$i++)
{
//$hexdata.=
//print dechex(ord(substr($bindata,$i,1)));
$subst=substr($bindata,$i,1);
$hexdata.=sprintf("%02X ",ord($subst));
if (ord($subst)<30)
{
$subst=" ";
}
$ss.=$subst;
if (($i%16)==15)
{
$hexdata.=" ".$ss." <br>\n";
$ss="";
}
//sprintf("%02X%02X%02X",$color,$color1,$color2)
}
$hexdata.=" ".$ss."\n";
return $hexdata;
}
function scan_zeroword($str,$tps)
{
// Flytta pekaren tills man stцter pе 00 00
while (bsubword2d($str,$tps)!=0)
{
$tps+=2;
}
return $tps;
}
function bsubword2d($str,$p)
{
return (ord(substr($str,$p,1))*256)+ord(substr($str,$p+1,1));
}
//bsubdwordflip2d
function bsubdwordflip2d($str,$p)
{
return (ord($str[$p+0])+(ord($str[$p+1])*256)+(ord($str[$p+2])*65536)+(ord($str[$p+3])*16777216));
}
function bsubwordflip2d($str,$p)
{
return (ord($str[$p+0])+(ord($str[$p+1])*256));
}
function d2bword($number)
{
return h2b(sprintf("%04X",$number));
}
function d2bwordflip($number)
{
$txtret=h2b(sprintf("%04X",$number));
return ($txtret[1].$txtret[0]);
}
function d2bdwordflip($number)
{
$txtret=h2b(sprintf("%08X",$number));
return ($txtret[3].$txtret[2].$txtret[1].$txtret[0]);
}
function get_uinstr($str,$ps)
{
global $debug;
// Lдs fцrsta UIN-lдngd och UIN
$str_len=bsubword2d($str,$ps);
// Om str_len дr mer дn 32 returnera tom strдng
if ($str_len>32)
{
return "";
}
if ($debug)print "uin_len=".$str_len."\n";
$outstr=substr($str,$ps+2,$str_len);
if ($debug)print "uin str=".$outstr."\n";
return $outstr;
}
function tlvstr($str)
{
$strln=strlen($str);
return d2bword($strln).$str;
//print dechex($strln);
}
function tlvsendstr($str)
{
$strln=strlen($str)+4;
return d2bword($strln).h2b("00 00 00 00").$str;
//print dechex($strln);
}
function flap($channel,$seq_no,$str)
{
$strln=strlen($str);
return h2b("2a").chr($channel).d2bword($seq_no).d2bword($strln).$snac.$str;
}
function icq_login($my_uin,$my_pwd)
{
global $debug;
// Skapa ett klient-sequence nummer
$cli_seq=rand(1, 65000);
// ********** LOGIN-SERVERN *************
// Цppna connection
$fp = fsockopen ("login.icq.com", 5190, $errno, $errstr, 30);
if (!$fp)
{
return false;
//die ($errstr."\n"."Could not connect to: login.icq.com:5190");
}
stream_set_blocking($fp, false);
// Ta emot SRV_HELLO
$res=recieve_data($fp);
if ($debug)print "rec srv_hello:".b2rh($res)."\n";
// Skicka CLI_IDENT
$res=b2rh(send_data($fp,cli_ident($cli_seq,$my_uin,$my_pwd)))."\n";
// Ta emot SRV_COOKIE frеn login-servern
$res=recieve_data($fp);
if ($debug)print "rec srv_cookie:".b2rh($res)."\n";
$srv_cookie_a=parse_srv_cookie($res);
// Stдng ner fцrsta kopplingen
fclose ($fp);
return $srv_cookie_a;
// ********** LOGIN-SERVERN *************
}
function icq_login_cookie($srv_cookie_a)
{
global $cli_seq,$fp;
// Connecta mot angiven ip och port
$fp = fsockopen ($srv_cookie_a["ip"], $srv_cookie_a["port"], $errno, $errstr, 3000);
if (!$fp)
{
die ($errstr."\n"."Could not connect to: ".$srv_cookie_a["ip"].":".$srv_cookie_a["port"]);
}
stream_set_blocking($fp, false);
// Ta emot SRV_HELLO
$res=recieve_data($fp);
// Skapa nytt klient-sequence nummer
$cli_seq=rand(1, 65000);
// Skicka CLI_COOKIE
$res=b2rh(send_data($fp,cli_cookie($cli_seq,$srv_cookie_a["cookie"])))."\n";
// Ta emot SRV_FAMILIES
$res=recieve_data($fp);
print "rec srv_fam:".b2rh($res)."\n";
// цka seq-rдknaren
$cli_seq++;
// Skicka CLI_FAMILIES
$res=b2rh(send_data($fp,cli_families($cli_seq)))."\n";
// Ta emot SRV_FAMILIES2 + MOTD
$res=recieve_data($fp);
print "rec srv_fam2+motd:".b2rh($res)."\n";
// цka seq-rдknaren
$cli_seq++;
// Skicka CLI_RATESREQUEST
$res=b2rh(send_data($fp,cli_ratesrequest($cli_seq)))."\n";
// Ta emot SRV_RATES
$res=recieve_data($fp);
print "rec srv_rates:".b2rh($res)."\n";
// Skicka CLI_ACKRATES
$cli_seq++;
$res=b2rh(send_data($fp,cli_ackrates($cli_seq)))."\n";
$cli_seq++;
$res=b2rh(send_data($fp,cli_reqinfo($cli_seq)))."\n";
$cli_seq++;
$res=b2rh(send_data($fp,cli_requnknown($cli_seq)))."\n";
$cli_seq++;
$res=b2rh(send_data($fp,cli_reqroster($cli_seq)))."\n";
$cli_seq++;
$res=b2rh(send_data($fp,cli_reqlocation($cli_seq)))."\n";
$cli_seq++;
$res=b2rh(send_data($fp,cli_reqbuddy($cli_seq)))."\n";
$cli_seq++;
$res=b2rh(send_data($fp,cli_reqicbm($cli_seq)))."\n";
$cli_seq++;
$res=b2rh(send_data($fp,cli_reqbos($cli_seq)))."\n";
// Ta emot svar
$res=recieve_data($fp);
print "rec svar:".b2rh($res)."\n";
$res=recieve_data($fp);
parse_msgs($res);
print "rec svar:".b2rh($res)."\n";
$cli_seq++;
$res=b2rh(send_data($fp,cli_unknown1($cli_seq)))."\n";
$cli_seq++;
$res=b2rh(send_data($fp,cli_setuserinfo($cli_seq,1)))."\n";
$cli_seq++;
$res=b2rh(send_data($fp,cli_seticbm($cli_seq)))."\n";
$cli_seq++;
$res=b2rh(send_data($fp,cli_setstatus($cli_seq)))."\n";
$cli_seq++;
$res=b2rh(send_data($fp,cli_ready($cli_seq)))."\n";
$res=recieve_data($fp);
#print "rec svar:".b2rh($res)."\n";
}
function cli_unknown2($my_uin)
{
global $cli_seq;
// Skicka CLI_TOICQSRV REQ_OFFLINEMSGS (Hдmta meddelanden)
$icq_cmd=h2b("5A 00").
d2bdwordflip($my_uin). // IPadressen hex-baklдnges
h2b("D0 07").
h2b("0f 00").
h2b("be 0a").
h2b("05 00"). // Client Major v
h2b("0f 00"). // Minor v
h2b("01 00"). // lesser v
h2b("36 0e"). // Build
h2b("55 00 00 00"). // sub-build
h2b("90 7c 21 21").
h2b("91 4d d3 11").
h2b("ad eb 00 04").
h2b("ac 96 aa b2").
h2b("00 00").
h2b("03 00 00 00").
h2b("2c 00").
h2b("01 00").
h2b("00 01").
h2b("00 00 00 00").
h2b("01 00 00 00").
h2b("00 00 00 00 00 00 00 00").
h2b("00 00 00 00 00 00 00 00").
h2b("00 00 00 00 00 00 00 00").
h2b("00 00 00 00 00 00 00 00")
;
$cli_seq++;
$res=b2rh(send_data($fp,cli_toicqsrv($cli_seq,$icq_cmd)))."\n";
}
function icq_get_msgs($my_uin)
{
global $cli_seq,$fp,$debug;
// Hдmta offline meddelanden och sдtt flagga att dom дr hдmtade
// Skicka CLI_TOICQSRV REQ_OFFLINEMSGS (Hдmta meddelanden)
$icq_cmd=h2b("08 00").
d2bdwordflip($my_uin). // IPadressen hex-baklдnges
h2b("3C 00").
h2b("02 00");
$cli_seq++;
$res=b2rh(send_data($fp,cli_toicqsrv($cli_seq,$icq_cmd)))."\n";
// Hдmta ev. meddelande-data
$res=recieve_data($fp);
if ($debug)print "REQOFFLINE svar:".b2rh($res)."\n";
// Parsa ev. meddelanden och lagra in en array ($msgs)
$msgs=parse_msgs($res);
//cli_unknown2($my_uin);
return $msgs;
}
function icq_send_msg($rec_uin,$msg_text)
{
global $cli_seq,$fp;
//$msg_text=$msg_text;
$cli_seq++;
$res=b2rh(send_data($fp,cli_sendmsg($cli_seq,$rec_uin,$msg_text)))."\n";
}
function icq_send_msgs()
{
global $my_uin,$timeout_seconds,$timeend,$ltimeleft,$debug;
// Sцk fram meddelanden som ska skickas TILL ICQ-servern
$query="SELECT * FROM outgoing WHERE fromuin='".$my_uin."' AND seen=0 ORDER BY msgtime";
if ($debug)print "sql = $query\n";
$sqlres=mysql_query($query) or die("send_msgs Invalid query: " . mysql_error());
// Gе igenom varje meddelande och skicka
while ($row = mysql_fetch_array($sqlres))
{
icq_send_msg($row["touin"],$row["msg"]);
#$query="DELETE FROM outgoing WHERE id=".$row["id"];
#$delres=mysql_query($query);
$query="UPDATE outgoing SET seen=1 WHERE id=".$row["id"];
$updres=mysql_query($query) or die("send_alive Invalid query: " . mysql_error());
// Resetta timern
$nowtime=time();
$timeend = $nowtime+$timeout_seconds;
$ltimeleft=-1;
}
}
function icq_receive_incoming()
{
global $cli_seq,$my_uin,$fp,$timeout_seconds,$debug,$nowtime,$timeend,$ltimeleft;
$str="";
$str = fread($fp,32768);
if ($str)
{
print "Incoming...\n";
$msgs=parse_msgs($str);
if ($msgs>0)
{
// Resetta timern
$nowtime=time();
$timeend = $nowtime+$timeout_seconds;
$ltimeleft=-1;
}
parse_onoffline($str);
$dis_id=is_disconnect($str);
if ($dis_id>0)
{
cli_sendoffline_ack();
fclose($fp);
print "DISCONNECT: Reason $dis_id !!";
exit;
}
if ($debug)print b2rh($str);
}
}
function send_alive($my_uin)
{
$query="SELECT lifesign FROM alive WHERE uin='".$my_uin."'";
if ($debug)print "sql = $query\n";
$sqlres=mysql_query($query) or die("send_alive Invalid query: " . mysql_error());
$num_rows = mysql_num_rows($sqlres);
$now=time();
if ($num_rows>0)
{
$query="UPDATE alive SET lifesign='".$now."' WHERE uin=".$my_uin."";
$updres=mysql_query($query) or die("send_alive Invalid query: " . mysql_error());
}
else
{
$query="INSERT INTO alive (uin,lifesign) VALUES ('".$my_uin."',".$now.")";
$insres=mysql_query($query) or die("send_alive Invalid query: " . mysql_error());
}
}
?>