<?php
@include('./ban.php');
################################
##### PHPS Pastebin by edK #####
################################
#Version: 0.24 RELEASE+~pb0251
#Rev 28.02.2010
#Please report any bugs 2 In /*47*/ CaribbeanBlue /*d0t*/ ru
#My nicks @ irc.freenode.net(ORDER BY `total_time_used` DESC): _AnywhereIs_, InCaribbeanBlue, Web31337
#More: http://phps.web31337.org/info/

# Great thanx to many irc.freenode.net##php users & ops ;)
# <3 phr33n0d3!
# Special thanx to InAjaxer a-ka T1AM0

# Why use PHPS Pastebin?
# * No SQL, no any other server extentions required to run it!
# * Has no vulnerabilities! (Or has if you discoved one in PHP functions used here or zlib)
# * No client capabilities required except for HTML rendering! No cookies, no javascript, no external plugins binding!
# * Very light-all in one script!

# How to install:
# 1. Set a file creating permission for webserver to a sources directory.
# 2. Copy this file to root directory or any other directory where you want pastebin script to be accessible from.
# 3. Set a paste index file secret location(DO NOT EXPOSE IT OR USE REGULAR EASY LOCATIONS FOR INDEX FILE!)
# ~ 4. (OPTIONAL) Tune up settings inside script. You can also use "valid html" image (html.png) from the package on the pages.
# 4. Enjoy!

# License: ./LICENSE
#
##########################################################################
## Copyright (C) 2009 edK                                                ##
## This program is free software: you can redistribute it and/or modify ##
## it under the terms of the GNU General Public License as published by ##
## the Free Software Foundation, either version 3 of the License, or    ##
## (at your option) any later version.                                    ##
##                                                                        ##
## This program is distributed in the hope that it will be useful,        ##
## but WITHOUT ANY WARRANTY; without even the implied warranty of        ##
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        ##
## GNU General Public License for more details.                            ##
##                                                                        ##
## You should have received a copy of the GNU General Public License    ##
## along with this program. If not, see <http://www.gnu.org/licenses/>. ##
##########################################################################

#####################################
########### CONFIGURATION ###########
#####################################

$ext='.php';

$path='./';

//$passwd='nospa111';
$passwd='';

$index='./.htpastes';

$index_show=1;

$index_limit=20;

$index_width=200;

$index_js=0;

$maxlen=12;

$title='PHPS.Web31337.org [Powered by PHPS Pastebin 0.25.1]';

$sources_title='PHPS Pastebin - Source Review';

$gzlvl=5;

$limit_source=65536;

$limit_title=64;

$index_show_time=1;

$index_show_ip=0;

$debug=0;

######################################
################ MAIN ################
######################################

    
if($debug) {
        
//go to maximum debugging level [PHPS Pastebin(since v 0.24) is tested against this level]
        
ini_set('display_errors','on'); 
        
error_reporting(E_ALL E_STRICT);
        }
    
    @
ini_set('default_charset','utf-8');
    
    
//some definitions
    
    
$bl='<a href="'.$_SERVER['SCRIPT_NAME'].'">Go back</a>';//backlink template
    
$h=$_SERVER['HTTP_HOST'];
    
$sn=$_SERVER['SCRIPT_NAME'];
    
$ip=$_SERVER['REMOTE_ADDR'].':'.$_SERVER['REMOTE_PORT'];
    
    
//pre-filter input
    
if(function_exists('get_magic_quotes_gpc') and get_magic_quotes_gpc()) {
        
$_POST array_map('stripslashes_deep'$_POST);
        }
    
    
//actions
    
    
if(isset($_GET['source'])) die(@highlight_file(__FILE__,1));

    if(!empty(
$_POST['txt'])) {
        if(!empty(
$passwd)) 
            
check_passwd($passwd);//check for password, it is set in config
     
        
$fname=generate_name();
        while(
file_exists($fname)) 
            
$fname=generate_name();//regenerate new, until filename will not exist
     
        
check_length();
        
$lvl=check_gzlevel($gzlvl);
        
$data=print_loader(htmlspecialchars($_POST['title']),$sources_title,1,$lvl);
        if(!
$lvl
            
$data.=$_POST['txt'];//compression disabled or not supported by webserver
        
else 
            
$data.=gzcompress($_POST['txt'],$lvl);
        
$f=@fopen($fname,'w');//make new file 
        
if(!is_resource($f)) 
            die(
'Cannot create a file. Check if webserver has rights to create new files in home directory.<br>'.$bl);
        
$r=@fwrite($f,$data);
        if(
$r!=strlen($data))
            die(
'Cannot write to open file. Something is completely wrong on this server. You can still '.$bl.' to try again.');
        @
fclose($f);
     
        
//Prepare view and remove URLs
        
if($fname[0]=='.'
            
$uri=substr($fname,1);//replace ./ with / in URL. ./ is taken from global $path, from conf.php.
        
$fp=maybe_addslash(dirname($sn));//get the path from URI
        //Now add path to actual path in URL.
        //This is a bugfix.
        //Example of bug: if you use THIS file in /somedir/, when you paste source, you will get $fname1="./somefile.php", and after, /somefile.php, but remind that $path is a relative path of THIS script but no a server root. So it will result in linking to /somefile.php while it meant to be /somedir/somefile.php.
        
$uri=substr($fp,0,-1).$uri;//kill slash from URI dirname and add actual file name after it.
        
$url=make_abs_url($uri);//finally, create paste view url
        
if(!empty($index)) {
            
//prepare data for adding to index.
            
$rm_key=sha1(generate_garbage(mt_rand(32,64),1).$fname);//some unpredictable random key to remove paste
            
$rm_url=make_abs_url($sn.'?rm='.$rm_key);
            
$rm_url='<br>You can remove your post using the following link(save it if you are planning to remove this post!): <a href="'.$rm_url.'">'.$rm_url.'</a>';//paste remove note with an URL
            
$private=(!empty($_POST['private']) && $_POST['private']=='on') ? 0;//private paste?
            //Add this paste into index.
            
$st=(!empty($_POST['title'])) ? htmlspecialchars($_POST['title']) : 'Untitled';
            
$data=serialize(array(
                
$fname,            /* Actual filename in order to remove it */
                
$uri,            /* URI to create link */
                
$st,            /* Paste title */
                
sha1($rm_key),    /* Hash of remove key, hashed in order to protect pastes from being removed by just reading index file. */
                
time(),
                
$ip,            /* Paster IP:Port */
                
$private        /* Private paste? */
                
));
            
$f=@fopen($index,'a');
            if(!
is_resource($f))
                die(
'Cannot open index file for writing. Failed to add post to index.<br>'.$bl);
            
$r=@fwrite($f,$data."\n");
            if(
$r!=strlen($data)+1)
                die(
'Cannot correctly add new entry to index file: error while writing file.<br>'.$bl);
            @
fclose($f);
            
            die(
'Your code is available at <a href="'.$url.'">'.$url.'</a>.'.$rm_url.'<br><a href="'.$sn.'">Have more source to add?</a>');
            }
        }

    if(!empty(
$_GET['rm'])) {
        
//remove paste request.
        //look through the index to find out if there was post with this key
        
if(!empty($index)) {
            
//index file is set. Using index system
            
if(!file_exists($index)) die('Unable to locate the index file. Check your config!<br>'.$bl);
            
$list=file($index);
            
$cnt=sizeof($list)-1;
            for(
$i=0;$i<=$cnt;$i++) {
                
$a=unserialize($list[$i]);
                if(
$a[3]==sha1($_GET['rm'])) {
                    
//found it! remove the file and index entry
                    
if(!@unlink($a[0])) 
                        die(
'Failed to remove the file!<br>'.$bl);//removing of actual file failed
                    
unset($list[$i]);//remove entry from index
                    //remove empty lines
                    
$data=implode($list);
                    
$f=@fopen($index,'w');
                    if(!
is_resource($f))
                        die(
'Cannot open index file for overwriting. Failed to rebuild index file.<br>'.$bl);
                    
$r=@fwrite($f,$data);
                    if(
$r!=strlen($data))
                        die(
'Cannot correctly update index file: error while writing file.<br>'.$bl);
                    @
fclose($f);
                    die(
'Your entry titled "'.$a[2].'" located at "'.$a[1].'" successfully removed!<br>'.$bl);
                    }
                }
            die(
'The key is invalid or the post already removed.<br>'.$bl);
            }
        
//no index defined, ignore request.
        
}

#####################################
############# FUNCTIONS #############
#####################################

//general stuff
 
    
function maybe_addslash($p) {
        if(
$p[strlen($p)-1]!='/')$p.='/';
        return 
$p;
        }

    function 
stripslashes_deep($value) {
        
$value is_array($value) ?
        
array_map('stripslashes_deep'$value) :
        
stripslashes($value);
        return 
$value;
        }
    
    function 
generate_garbage($sz,$base64it=0,$dev_urandom=0) {
        
//binary garbage generator.
        //to explicitly use unix-way (/dev/urandom) set $dev_urandom.
        
$garbage='';
        if(
$dev_urandom or @is_readable('/dev/urandom')) {
            
$f=@fopen('/dev/urandom','r');
            if(!
is_resource($f))
                return 
0;
            
$garbage=@fread($f,$sz);
            @
fclose($f);
            return ((
$base64it) ? base64_encode($garbage) : $garbage);
        }
        
        for(
$i=0;$i<$sz;$i++) {
                
//ugly mess for windoze, and other torture-tools
                
$garbage.=chr(mt_rand(0,255));
            }
        return ((
$base64it) ? base64_encode($garbage) : $garbage);
    }
    
    function 
make_abs_url($uri='',$hostname='') {
    
//make URL to current page
        
        
if(empty($hostname))
            
$hostname=$_SERVER['HTTP_HOST'];
            
        
$port=$_SERVER['SERVER_PORT'];
        if(empty(
$uri)) 
            
$uri=$_SERVER['REQUEST_URI'];
            
        if(!empty(
$_SERVER['HTTPS'])) {
                
$proto='https://';
                
$port=($port!=443) ? ':'.$port '';
            } else {
                
$proto='http://';
                
$port=($port!=80) ? ':'.$port '';
            }
        return 
$proto.$hostname.$port.strip_tags($uri);//a basic measure to avoid XSS. You'd better take care of filtering $uri before passing here.
    
}

    function 
truncstr($str,$cnt) {
        
//simple string truncate :)
        
if(iconv_strlen($str,'utf-8')>$cnt
            return 
iconv_substr($str,0,$cnt-3,'utf-8').'...';
        return 
$str;
        }
        
//system stuff

    
function check_length() {
        global 
$limit_source,$limit_title,$bl;
        
//check if limits are set and if source/title is longer than limit
        
if($limit_source and (!empty($_POST['txt'])) and iconv_strlen($_POST['txt'],'utf-8')>$limit_source
            die(
'Too long source! You can add max '.$limit_source.'-characters long code.<br>'.$bl);
        if(
$limit_title and (!empty($_POST['title'])) and iconv_strlen($_POST['title'],'utf-8')>$limit_title
            die(
'Too long title! You can set max '.$limit_title.'-characters long title.<br>'.$bl);
        }

    function 
check_gzlevel($lvl) {
        
//check gzip compression level and set valid value
        
if(!function_exists('gzcompress') or !$lvl
            return 
0;
        if(
$lvl<or $lvl>9) return 5;
        return 
$lvl;
        }

    function 
check_passwd($passwd) {
        global 
$bl;
        if(empty(
$_POST['pass']) or $_POST['pass']!=$passwd
            die(
'Password incorrect!<br>'.$bl);
        }

    function 
generate_name() {
        
//generates random filename
        
global $path,$maxlen,$ext;
        if(empty(
$ext)) 
            
$ext='.php';
        if(
$maxlen<or $maxlen>=40
            
$maxlen=8;
        return 
$path.substr(md5(generate_garbage(40,1)),0,8+mt_rand(0,$maxlen-8)).$ext;
    }
    
//HTML generators

    
function print_index($return=0) {
        
//prints HTML table and recent pastes index in it
        
global $index,$index_js,$index_show_time,$index_show_ip,$index_width,$index_limit;
        
$output=(($index_js) ? "\n<script language=\"javascript\" type=\"text/javascript\">function viewpaste(pasteurl){document.location=pasteurl;}</script>\n" "")."<table>\n<tr>\n<td valign=\"top\" width=\"$index_width\">\n<b>Recent Entries</b><br><br>\n\n<table>\n";
        
//index file existance has been checked before this function call
        
$idx=@file($index);
        if(empty(
$idx))
            return 
0;//index is empty, nothing to return. Actually that is checked before calling this function in HTML template.
        
$idx=array_reverse($idx);//most recent entries are last!
        
$c=sizeof($idx);
        for(
$i=0;$i<$c;$i++) {
            if(
$i==$index_limit) break;
            
$entry=unserialize($idx[$i]);
            if(!empty(
$entry[6])) continue;//this should not be listed, marked as private paste
            
$time=($index_show_time) ? '<br><span class=small>At '.gmdate("d.m.y H:i:s",$entry[4]).' GMT</span>' '';
            
$ip=($index_show_ip) ? '<br><span class=small>['.$entry[5].']</span>' '';
            
$output.=" <tr><td class=c2".(($index_js) ? " onclick=\"viewpaste('{$entry[1]}')\"" '').">-&nbsp;<a href=\"{$entry[1]}\" style=\"font-weight:bold;\">".truncstr($entry[2],30)."</a>".$time.$ip."</td></tr>\n";
            }
        
$output.="</table>\n\n</td>\n<td valign=\"top\">\n";
        if(
$return
            return 
$output;
        echo 
$output;
        return 
1;
    }

    function 
print_loader($title='',$sources_title='PHPS Pastebin - Source Review',$return=1,$gz=1)
    {
#get loader source
        
$img=maybe_addslash(dirname($_SERVER['SCRIPT_NAME']))."html.png";#image should be stored in the path of this script
        
$src=<<<LDR_SRC
<?php
################################
##### PHPS Pastebin by edK #####
################################

#This file is a print code for pasted PHP source.
#WARNING: This is a generated file! Do not edit! It may fail to parse after editing with standard tools like windows's notepad.
#The source pasted is gzipped and is placed just after __halt_compiler();

if(isset(\$_GET['source'])) die(@highlight_file(__FILE__,1));#show source

\$title="
{$title}";
\$gz=
{$gz};#is source gzipped?
\$image_path="
{$img}";
\$addsource="
{$_SERVER['SCRIPT_NAME']}";
\$endhtml='<br><a href="'.htmlspecialchars(\$_SERVER['SCRIPT_NAME'].'?source').'">[View source of this file]</a> <a href="'.\$addsource.'">[Paste new source]</a><br>This site is powered by <a href="http://phps.web31337.org/info/">PHPS Pastebin</a> coded by edK<br><br><a href="http://validator.w3.org/check?uri=referer"><img src="'.\$image_path.'" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a></p></body></html>';

\$output='<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>'; 
 #set the title
 if(!empty(\$title)) \$output.=\$title; 
 else \$output.="
{$sources_title}";
\$output.='</title>
</head>
<body>';

\$thecode=file_get_contents(__FILE__);#get THIS FILE
\$thecode=substr(\$thecode,strpos(\$thecode,'__halt_compiler();'.'?>')+20,strlen(\$thecode));
if((\$gz) and (function_exists('gzuncompress'))) 
 {#compression available, try to unpack source
 \$thecode=gzuncompress(\$thecode);
 if(\$thecode===FALSE) die(\$output.'<p align="center">Cannot unpack source-something is wrong with zlib or packed data is not well-formatted.'.\$endhtml);
 }
if((\$gz) and (!function_exists('gzuncompress'))) die(\$output.'<p align="center">Your webserver has no zlib required to unpack the data in script.'.\$endhtml);
\$output.=highlight_string(\$thecode,1);
\$output.='<p align="center"><a href="'.htmlspecialchars(\$_SERVER['SCRIPT_NAME'].'?source').'">[View source of this file]</a> <a href="'.\$addsource.'">[Paste new source]</a><br>This site is powered by <a href="http://phps.web31337.org/info/">PHPS Pastebin</a> coded by edK<br><br><a href="http://validator.w3.org/check?uri=referer"><img src="'.\$image_path.'" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a></p></body></html>';
print \$output;
__halt_compiler();?>
LDR_SRC;
if(!
$return
    echo 
$src;
else 
    return 
$src;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title><?php echo (empty($title)) ? 'PHPS Pastebin' $title;?></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="google-site-verification" content="tb63uWnoHUofa6hAbnM57p7Qiafe0T1lOgdfcJP2cxU">
<meta name="description" content="PHPS Pastebin - PHP-based opensource pastebin for PHP code and plaintext notes">
<meta name="keywords" content="foss,opensource,open source,free software,php,phps pastebin,php pastebin,php-based,php-based pastebin,open pastebin,paste site,paste board,live demo pastebin">
<style type="text/css">
body{font-family: Verdana;}
.c1{border: 1px solid #CCCCCC; color: #cccccc; background-color: #202020;}
.c2{background-color: #202020;}
.c2:hover{background-color: #404040;}
.small{color:green;font-family:'Courier New';font-size:10pt;}
</style>
</head>
<body bgcolor="#202020" text="#CCCCCC" alink="#909090" vlink="#909090" link="#909090"><?php if($index_show && file_exists($index) && filesize($index)) $pr=print_index();  ?>
<form action="<?php echo htmlspecialchars($_SERVER['REQUEST_URI']);?>" method="POST">
Title: <input class=c1 style="width: 600px" name="title"><br><br>
<?php /*dealing with spambots*/ if(!empty($passwd)) echo 'Enter "nospa111" w/o quotes: <input class=c1 name="pass"><br><br>'."\n"?>Your PHP source:<br><textarea class=c1 rows=30 cols=95 name="txt"></textarea><br><br>
<label><input type="checkbox" name="private">&nbsp;Make this paste private(do not show in Recent Entries)</label><br><br>
<input type="submit" style="width: 180px; height: 50px; font-family: Verdana; font-size: 28pt;" value="Paste!"><?php if($index_show_ip && $index_show) echo '<p style="width:800px;border:1px solid red;background-color:#201616;font-weight:bold;">&nbsp;<br>&nbsp;Warning: Site administrator enabled option that your IP is logged and publicy visible at the pastes index!<br>&nbsp;</p>'?>
</form><?php if(!empty($pr)) echo "\n</td></tr></table>\n";?>
<p align=center>This site is powered by PHPS Pastebin 0.25.1<br><!--[<a href="/?source" target="_blank">This page's source</a>] -->[<a href="/get/phpspastebin-0.25.1.tar.gz">Download 0.25.1</a>] [<a href="/info/">About PHPS Pastebin</a>]<br>Coded by <b>edK</b><br>This site has valid HTML 4.01!</p>
<p align=center><a href="http://validator.w3.org/check?uri=referer"><img src="html.png" alt="Valid HTML 4.01 Transitional" height="31" width="88" border="0"></a>&nbsp;&nbsp;<script type="text/javascript"><!--
document.write("<img src='//counter.yadro.ru/hit?t17.5;r"+
escape(document.referrer)+((typeof(screen)=="undefined")?"":
";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?
screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+
";"+Math.random()+
"' alt='' title='LiveInternet: number of pageviews for 24 hours,"+
" of visitors for 24 hours and for today is shown' "+
"border='0' width='88' height='31'>")
//--></script>

</p>
</body>
</html>