0byt3m1n1
Path:
/
data
/
11
/
0
/
19
/
129
/
997781
/
user
/
1027887
/
cgi-bin
/
[
Home
]
File: libps.2.2.pl
################################################################# # PicoStreamer 2.2 # # PS library 2.2 # # Vinz486 (c) 2006 # ################################################################# $libps = 1; $PS_VER = "2.2"; if($libcfg != 1) { &ps_loadmodule("libcfg"); } if($libio != 1) { &ps_loadmodule("libio"); } if($libutl != 1) { &ps_loadmodule("libutl"); } if($libudp != 1) { &ps_loadmodule("libudp"); } if($liblog != 1) { &ps_loadmodule("liblog"); } if($librelay != 1) { &ps_loadmodule("librelay"); } if($libtcp != 1) { &ps_loadmodule("libtcp"); } if($librpc != 1) { &ps_loadmodule("librpc"); } ############################## # some init vars # epoc time stamp of desc file $desc_time = 0; ############################## sub ps_setvideodata { if(($_[0] ne "") && ($_[1] ne "")) { my $mo = 0; if($usr{'winsize'} ne $_ [0]) { $usr{'winsize'} = $_[0]; $mo = 1; } if($usr{'stype'} ne $_ [1]) { $usr{'stype'} = $_[1]; $mo = 1; } if($mo == 1) { &ps_saveuser(); } } } # Load at run-time latest version of [0] library sub ps_loadmodule { if($_[0] eq "") { print "Content-Type: text/html\n\n<html><head><title>FATAL ERROR</title></head><body>Library Not Found</body></html>"; exit; } my @vers = qx(ls $_[0].?.?.pl); my $big = 0; my $va = 0; my $vb = 0; foreach $ver (@vers) { my ($name,$_va,$_vb,$ext) = split(/\./,$ver); my $num = $_va.$_vb; if($num > $big) { $big = $num; $va = $_va; $vb = $_vb; } } if($big == 0) { print "Content-Type: text/html\n\n<html><head><title>FATAL ERROR</title></head><body>Library [".$_[0]."] Not Found</body></html>"; exit; } require $_[0].".".$va.".".$vb.".pl" } # get versions of libs # return vers csv sub ps_ver { my $vss = ""; $vss = "PicoStreamer ".$PS_VER.";"."ps ".&ps_get_ver().";"; $vss .= " cfg " .&cfg_get_ver() .";"; $vss .= " io " .&io_get_ver() .";"; $vss .= " utl " .&utl_get_ver() .";"; $vss .= " udp " .&udp_get_ver() .";"; $vss .= " log " .&log_get_ver() .";"; $vss .= " relay " .&relay_get_ver() .";"; $vss .= " tcp " .&tcp_get_ver() .";"; $vss .= " rpc " .&rpc_get_ver() .";"; return $vss; } # return this file ver sub ps_get_ver { my ($fid,$vma,$vmi) = split(/\./,__FILE__); return $vma.".".$vmi; } # load user description vars # return 0 on error sub ps_loaduser { # if no user defined exit if($f_user eq "") { return 0; } $ps_userdir = $c_users . $c_fs . $f_user . $c_fs; $ps_clientdir = $ps_userdir . "ports" . $c_fs; $ps_descfile = $ps_userdir . "desc.txt"; $ps_logfile = $ps_userdir . &ut_get_MY() . ".log.txt"; $ps_statfile = $ps_userdir . &ut_get_MY() . ".stat.txt"; # if exists the user dir if((-e $ps_userdir) && (-e $ps_descfile)) { # get last modify time of desc file my $_dtime = &ut_get_ftime($ps_descfile); # if we have an updated copy of desc file if($desc_time == $_dtime) { # don't load again return 1; } # save the modify time of desc file $desc_time = $_dtime; # read the description file open(DFILE,$ps_descfile) or return 0; &ut_lokf(DFILE); my @_usr = <DFILE>; &ut_unlokf(DFILE); close(DFILE); undef %usr; my $_line; # put it to @usr foreach $_line (@_usr) { chomp($_line); my ($_ky,$_vl) = split(/\=/,$_line); $_ky = &ut_trim($_ky); $_vl = &ut_trim($_vl); #print "K: ".$_ky."=".$_vl."<br>"; if($_ky ne "") { $usr{$_ky} = $_vl; } } return 1; } else { return 0; } } # check if banned ip # [0] ip addr # return 1 on banned sub ps_is_banned { &logger($T,"ps_is_banned",$_[0]); my $isban = 0; my $tip = $_[0]; open(BAN, $ps_userdir . "banned") or return 0; &ut_lokf(BAN); while($rr = <BAN>) { chomp($rr); &logger($D,"Toc:".$tip,$rr); if($tip =~m/^$rr/) { $isban = 1; last; } } &ut_unlokf(BAN); close(BAN); &logger($D,"ps_is_banned",$_[0],$isban); return $isban; } # get status online/offline # return 0 off, 1 on sub ps_get_status { &logger($T,"ps_get_status"); my @pids = &ut_list($ps_userdir . "*.pid"); if(-e $pids[0]) { my $tn = time(); my $an = &ut_get_ftime($pids[0]); if(($tn - $an) < $c_online_time) { return 1; } else { return 0; } } else { return 0; } } # set new peak if needed sub ps_set_peak { &logger($T,"ps_set_peak"); my $oval = &ps_get_peak(); my $nval = &ps_count_active_clients(); if($oval < $nval) { open(POU, ">" . $ps_userdir . "peak.txt") or return 0; &ut_lokf(POU); print POU $nval . "\n"; print POU time() . "\n"; &ut_unlokf(POU); close(POU); return $nval; } return 0 } # get the peak number and date # return peak number sub ps_get_peak { open(PIN, $ps_userdir . "peak.txt") or return 0; &ut_lokf(PIN); my $pv = <PIN>; my $tm = <PIN>; &ut_unlokf(PIN); close(PIN); chomp($pv); chomp($tm); return $pv; } # create a user named file # [0] type, [1] name sub ps_set_user_file { &logger($T,"ps_set_user_file",$_[0],$_[1]); if(($_[0] eq "") || ($_[1] eq "")) { return; } &ut_touch($ps_userdir.$_[1].".".$_[0]); } # get a list of user named files # [0] type, ([1] name) sub ps_get_user_file { &logger($T,"ps_get_user_file",$_[0],$_[1]); if($_[0] eq "") { return; } my $val = $_[1]; my $nam = $_[0]; if($val eq "") { $val = "*"; } my @grs = &ut_list($ps_userdir.$val.".".$nam); my $of; my @fres; foreach $of (@grs) { my @ufl = split("\/",$of); my $fna = pop(@ufl); $fna =~s/\.$nam$//g; push(@fres,$fna); &logger($T,"ps_get_user_file","item",$fna); } return @fres; } # remove a user named file # [0] type, ([1] name) sub ps_rem_user_file { &logger($T,"ps_rem_user_file",$_[0],$_[1]); if($_[0] eq "") { return 0; } my $val = $_[1]; my $nam = $_[0]; if($val eq "") { $val = "*"; } my @grs = &ut_list($ps_userdir.$val.".".$nam); my $of; my $rcont = 0; foreach $of (@grs) { if(&ut_rem_file($of) == 1) { $rcont++; } } if($rcont == 0) { $! = "File not found."; }; return $rcont; } # kill old instances and set new source sub ps_set_source_pid { my $spid = $$; my @pis = &ps_get_user_file("pid"); my $np; foreach $np (@pis) { if($np ne "") { if($np ne $spid) { &ut_kill($np); &ps_rem_user_file("pid",$np); } } } &ut_touch($ps_userdir . $spid . ".pid"); } # kill the source pid sub ps_zap_source { my @pis = &ps_get_user_file("pid"); my $np; foreach $np (@pis) { if($np ne "") { &ut_kill($np); &ps_rem_user_file("pid",$np); } } } # kill a list of clients # [@] clients sub ps_zap_clients { my @pzap = @_; my $zap; my $zuid, $zport, $zpid; my $znum = @pzap; foreach $zap (@pzap) { ($zuid,$zport,$zpid) = &ps_split_client($zap); &ut_kill($zpid); &ut_rem_file($ps_clientdir . $zuid . "." . $zport . "." . $zpid . ".port"); } return $znum; } # delete a client entry # [0] client number sub ps_rem_client { if($_[0] eq "") { return; }; my $muid = &ps_get_uid(); if($_[1] ne "") { $muid = $_[1]; } &ut_rem_file($ps_clientdir . $muid . "." . $_[0] . "." . $$ . ".port"); } # create a new client entry # [0] client number sub ps_set_client { if($_[0] eq "") { return; }; my $muid = &ps_get_uid(); if($_[1] ne "") { $muid = $_[1]; } &ut_touch($ps_clientdir . $muid . "." . $_[0] . "." . $$ . ".port"); } # get unique id for this process sub ps_get_uid { # uid based on remote ip and port return $ENV{'REMOTE_ADDR'} . "." . $ENV{'REMOTE_PORT'}; } # count the number of active clients sub ps_count_active_clients { my @ppc = &ps_get_active_clients("nr"); my $cnt = @ppc; return $cnt; } # return the list of port|pids # if $_[0] and $_[1] # only newer/older[1] than [0] sub ps_get_clients { my @_pts; undef @_pts; my @fils = &ut_list($ps_clientdir . "*.port"); my $bfile; foreach $bfile (@fils) { my $afile = $bfile; if($_[0] ne "") { my $ptime = &ut_get_ftime($afile); if($_[1] eq "newer") { if($_[0] >= $ptime) { next; } } else { if($_[0] < $ptime) { next; } } } $afile =~m/^.+\/(.+)\.(\d+)\.(\d+)\.port$/; push(@_pts, $1 . "|" . $2 . "|" . $3); } return @_pts; } # return the list of active clients # $_[0] => uid,port,pid sub ps_get_active_clients { my @pps = &ps_get_clients(time() - $c_idle_timeout, "newer"); if($_[0] eq "") { return @pps; } else { my $filter = $_[0]; my @res; undef @res; foreach $ap (@pps) { ($uid,$port,$pid) = &ps_split_client($ap); if($filter eq "nr") { ($_rn) = split(/\./,$uid); if(($_rn ne "relay") && ($_rn ne "ypcheck")) { push(@res,$uid); } } if($filter eq "uid") { push(@res,$uid); } if($filter eq "port") { push(@res,$port); } if($filter eq "pid") { push(@res,$pid); } } return @res; } } # return the list of inactive clients # $_[0] = time offset sub ps_get_inactive_clients { my $offs = 0; if($_[0] eq "") { $offs = 0; } else { $offs = $_[0]; } my @pps = &ps_get_clients((time() - $offs) - $c_idle_timeout, "older"); if($_[1] eq "") { return @pps; } else { my $filter = $_[1]; my @res; undef @res; foreach $ap (@pps) { ($uid,$port,$pid) = &ps_split_client($ap); if($filter eq "uid") { push(@res,$uid); } if($filter eq "port") { push(@res,$port); } if($filter eq "pid") { push(@res,$pid); } } return @res; } } # get all udp clients sub ps_get_all_clients { my @aports = &ps_get_clients(); if($_[0] eq "") { return @aports; } else { my $filter = $_[0]; my @res; undef @res; foreach $ap (@aports) { ($uid,$port,$pid) = split(/\|/, $ap); if($filter eq "uid") { push(@res,$uid); } if($filter eq "port") { push(@res,$port); } if($filter eq "pid") { push(@res,$pid); } } return @res; } } # generate statistics # $_[1] = type sub ps_stats { my $smode = $_[0]; if($smode eq "") { $smode = "simple"; } my $curr = &ps_count_active_clients(); my $peak = &ps_get_peak(); my $umax = &ps_get_maxusers(); my $sinf = &ps_get_info(); my $stus = &ps_get_status(); my $brate = &ps_get_bitrate(); my $cotyp = &ps_get_ctype(); my $genre = &ps_get_genre(); my $winsize = $usr{'winsize'}; my $avt = $usr{'stype'}; my $sta,$stype; if($smode eq "nice") { my $offo; if($stus == 0) { $offo = "<span style=\"color: red\">offline</span>"; } else { $offo = "<span style=\"color: green\">online</span>"; } $stype = "text/html"; $sta = "<html><head><title>Details for ".&ut_html_encode($f_user)."</title></head><body>"; $sta .= "<table style=\"border: 1px solid black; font-family: Tahoma, Verdana; font-size: 12px\" align=\"center\">"; $sta .= "<tr><td align=\"center\">".&ut_html_encode($sinf)."</td></tr>"; $sta .= "<tr><td align=\"center\" style=\"border-bottom: 1px solid black\"><i>".&ut_html_encode($genre)."</i></td></tr>"; $sta .= "<tr><td align=\"center\">".$offo." with ".$curr." listeners on max of ".$umax."</td></tr>"; $sta .= "</table>"; $sta .= "</body></html>"; } if($smode eq "simple") { $stype = "text/html"; $sta = "Status: " . $stus . " - Curr: " . $curr . " - Peak: " . $peak . " - Max: " . $umax . " - Bitrate: " . $brate . " - Type: " . $cotyp ." - Stype: " . $avt . " - Winsize: " . $winsize ."\n"; $sta .= &ut_html_encode($sinf) . "\n" . &ut_html_encode($genre) . "\n"; } if($smode eq "csv") { $stype = "text/plain"; $sta = $stus. "," . $curr . "," . $peak . "," . $umax . "," . $brate . "," . $cotyp . "," . $avt . "," . $winsize ."\n"; $sta .= $sinf . "\n" . $genre . "\n"; } if($smode eq "shout") { $stype = "text/xml"; $sta = "<?xml version=\"1.0\" standalone=\"yes\" ?>"; $sta .= "<!DOCTYPE SHOUTCASTSERVER [<!ELEMENT SHOUTCASTSERVER (CURRENTLISTENERS,PEAKLISTENERS,MAXLISTENERS,REPORTEDLISTENERS,AVERAGETIME,SERVERGENRE,SERVERURL,SERVERTITLE,SONGTITLE,SONGURL,IRC,ICQ,AIM,WEBHITS,STREAMHITS,STREAMSTATUS,BITRATE,CONTENT,VERSION)><!ELEMENT CURRENTLISTENERS (#PCDATA)><!ELEMENT PEAKLISTENERS (#PCDATA)><!ELEMENT MAXLISTENERS (#PCDATA)><!ELEMENT REPORTEDLISTENERS (#PCDATA)><!ELEMENT AVERAGETIME (#PCDATA)><!ELEMENT SERVERGENRE (#PCDATA)><!ELEMENT SERVERURL (#PCDATA)><!ELEMENT SERVERTITLE (#PCDATA)><!ELEMENT SONGTITLE (#PCDATA)><!ELEMENT SONGURL (#PCDATA)><!ELEMENT IRC (#PCDATA)><!ELEMENT ICQ (#PCDATA)><!ELEMENT AIM (#PCDATA)><!ELEMENT WEBHITS (#PCDATA)><!ELEMENT STREAMHITS (#PCDATA)><!ELEMENT STREAMSTATUS (#PCDATA)><!ELEMENT BITRATE (#PCDATA)><!ELEMENT CONTENT (#PCDATA)><!ELEMENT VERSION (#PCDATA)>]>"; $sta .= "<SHOUTCASTSERVER>"; $sta .= "<CURRENTLISTENERS>" . $curr . "</CURRENTLISTENERS>"; $sta .= "<PEAKLISTENERS>" . $peak . "</PEAKLISTENERS>"; $sta .= "<MAXLISTENERS>" . $umax . "</MAXLISTENERS>"; $sta .= "<REPORTEDLISTENERS>1</REPORTEDLISTENERS>"; $sta .= "<AVERAGETIME>1</AVERAGETIME>"; $sta .= "<SERVERGENRE>" . &ut_html_encode($genre) . "</SERVERGENRE>"; $sta .= "<SERVERURL>http://".&ut_this_host()."</SERVERURL>"; $sta .= "<SERVERTITLE>" . &ut_html_encode($sinf) . "</SERVERTITLE>"; $sta .= "<SONGTITLE></SONGTITLE>"; $sta .= "<SONGURL></SONGURL>"; $sta .= "<IRC>NA</IRC>"; $sta .= "<ICQ>NA</ICQ>"; $sta .= "<AIM>NA</AIM>"; $sta .= "<WEBHITS>1</WEBHITS>"; $sta .= "<STREAMHITS>1</STREAMHITS>"; $sta .= "<STREAMSTATUS>" . $stus . "</STREAMSTATUS>"; $sta .= "<BITRATE>" . $brate . "</BITRATE>"; $sta .= "<CONTENT>" . $cotyp . "</CONTENT>"; $sta .= "<VERSION>" . $PS_VER . "</VERSION>"; $sta .= "</SHOUTCASTSERVER>"; } if($smode eq "ice") { $stype = "text/xml"; $sta = "<?xml version=\"1.0\"?>", $sta .= "<icestats>"; $sta .= "<client_connections></client_connections>"; $sta .= "<clients>" . $curr . "</clients>"; $sta .= "<connections></connections>"; $sta .= "<source_connections></source_connections>"; $sta .= "<sources>" . $stus . "</sources>"; $sta .= "<source mount=\"/" . $f_user . "\">"; $sta .= "<audio_info>ice-bitrate=" . $brate . "</audio_info>"; $sta .= "<connections></connections>"; $sta .= "<ice-bitrate>" . $brate . "</ice-bitrate>"; $sta .= "<ice-channels></ice-channels>"; $sta .= "<ice-samplerate></ice-samplerate>"; $sta .= "<listeners>" . $curr . "</listeners>"; $sta .= "<public>1</public>"; $sta .= "<type>" . $cotyp ."</type>"; $sta .= "</source>"; $sta .= "</icestats>"; } return ($sta,$stype); } # split client parameters sub ps_split_client { my @ret = split(/\|/, $_[0]); return @ret; } # set bitrate in desc file sub ps_set_bitrate { &ps_set_numeric_param($_[0], $D_BITRATE); } # check and save a numeric desc param sub ps_set_numeric_param { # get only numeric values my $value = &ut_digits($_[0]); if($value > 0) { return &ps_set_param($value, $_[1]); } else { return 0; } } # save user data in desc file sub ps_saveuser { open(USR,">" . $ps_descfile) or return; &ut_lokf(USR); my $_k; foreach $_k (keys %usr) { print USR $_k . "=" . $usr{$_k} ."\n"; } &ut_unlokf(USR); close(USR); # save the modify time, so next we don't load again $desc_time = &ut_get_ftime($_descfile); } # set info in desc file sub ps_set_info { return &ps_set_string_param(substr($_[0],0,$c_info_max), $D_INFO); } # set ctype in desc file sub ps_set_ctype { return &ps_set_string_param(substr($_[0],0,256), $D_CTYPE); } # set genre in desc file sub ps_set_genre { return &ps_set_string_param(substr($_[0],0,$c_genre_max), $D_GENRE); } # get stream genre sub ps_get_genre { return &ps_get_param($D_GENRE); } # set descritpion in desc file sub ps_set_desc { return &ps_set_string_param($_[0], $D_DESC); } # get stream description sub ps_get_desc { return &ps_get_param($D_DESC); } # set relay host in desc file sub ps_set_rhost { return &ps_set_string_param($_[0], $D_RHOST); } # get relay host sub ps_get_rhost { return &ps_get_param($D_RHOST); } # set relay user in desc file sub ps_set_ruser { return &ps_set_string_param(substr($_[0],0,$c_username_max), $D_RUSER); } # get relay user sub ps_get_ruser { return &ps_get_param($D_RUSER); } # set maxusers in desc file sub ps_set_maxusers { if($_[0] > 99999) { $_[0] = 99999; } return &ps_set_string_param($_[0], $D_MAXUSERS); } # get maxusers sub ps_get_maxusers { return &ps_get_param($D_MAXUSERS); } # set intro in desc file sub ps_set_intro { return &ps_set_string_param($_[0], $D_INTRO); } # set banner in desc file sub ps_set_banner { return &ps_set_string_param($_[0], $D_BANNER); } # check and save a string desc param sub ps_set_string_param { # strip html and carriages my $value = &ut_strip_html($_[0]); $value = &ut_strip_carriage($value); return &ps_set_param($value, $_[1]); } # set a param in desc file # only if differ from old value sub ps_set_param { if(($_[0] eq "") || ($_[1] eq "")) { return 0; } if($usr{$_[1]} ne $_[0]) { $usr{$_[1]} = $_[0]; &ps_saveuser(); return 1; } else { return 0; } } # get stream info sub ps_get_info { my $preinfo = ""; if($_[0] ne "1") { if(&ps_get_rhost() ne "norelay") { $preinfo = "[R] "; } } return $preinfo.&ps_get_param($D_INFO); } # get content type sub ps_get_ctype { return &ps_get_param($D_CTYPE); } # get bitrate sub ps_get_bitrate { return &ps_get_param($D_BITRATE); } # get password sub ps_get_pass { return &ps_get_param($D_PASS); } # get maxusers sub ps_get_maxusers { return &ps_get_param($D_MAXUSERS); } # get intro sub ps_get_intro { return &ps_get_param($D_INTRO); } # get banner sub ps_get_banner { return &ps_get_param($D_BANNER); } # get a generic desc param sub ps_get_param { &ps_loaduser(); return $usr{$_[0]}; } # get file extension from ctype # [0] ctype # return file.ext sub ps_get_ext { if($_[0] eq "") { return "mp3"; } my $pest = $pext{$_[0]}; if($pest eq "") { return "mp3"; } return $pest; } # Format a playlist # [0] type pls,asx,ram,m3u # return the playlist string sub ps_plist { my $type = $_[0]; if($type eq "") { return ""; } my $fex = &ps_get_ext(&ps_get_ctype()); my $pls = ""; # Real player if($type eq "ram") { $pls = "http://".&ut_this_host()."/cgi-bin/picoreader.cgi?title=".&ps_get_info()."&user=".$f_user."&r=".time()."&f=file.".$fex."\n"; } # Winamp if($type eq "pls") { $pls = "[playlist]\n"; $pls .= "NumberOfEntries=1\n"; $pls .= "File1=http://".&ut_this_host()."/cgi-bin/picoreader.cgi?user=".$f_user."&r=".time()."&f=file.".$fex."\n"; $pls .= "Title1=".&ps_get_info()."\n"; $pls .= "Length1=-1\n"; $pls .= "Version=2\n"; } # Generic m3u file if($type eq "m3u") { $pls = "#EXTM3U\n"; $pls .= "#EXTINF:-1,".&ps_get_info()."\n"; $pls .= "http://".&ut_this_host()."/cgi-bin/picoreader.cgi?user=".$f_user."&r=".time()."&f=file.".$fex."\n"; } # Windows Media Player if($type eq "asx") { $pls = "<ASX version=\"3.0\">\n"; $pls .= "<ENTRY>\n"; $pls .= "<TITLE>".&ps_get_info()."</TITLE>\n"; $pls .= "<REF href=\"http://".&ut_this_host()."/cgi-bin/picoreader.cgi?user=".$f_user."&r=".time()."&f=file.".$fex."\" />\n"; $pls .= "</ENTRY>\n"; $pls .= "</ASX>\n"; } if($pls eq "") { return ""; } return $pls; } 1;