<?
  
/****************************************************************************
   * Frost Jedi Graemlin Creator v2.1.3 (Dec 10, 2004)
   *  MMIII - MMIV by TerraFrost. All rights reserved.
   *
   * http://www.frostjedi.com/terra/scripts/graemlin/
   *
   * Comments, criticisms, suggestions, and additions welcome! Post them 
   * here:
   *
   * http://www.frostjedi.com/phpbb/viewforum.php?f=6
   *
   * Released under the GNU General Public License 2.0:
   * http://creativecommons.org/licenses/GPL/2.0/
   ***************************************************************************/

   
error_reporting(E_ALL); 

   
define('IN_GRAEMLIN'true);

   
$filename htmlspecialchars($_SERVER['PHP_SELF']); // protect against XSS
   
$pathname 'graemlin/';
   
$sourceLink $pathname.'viewsource.php?file=graemlin.php';
   
$graemlinFiles = array('happy.gif','glad.gif','biggrin.gif','wink.gif','lila.gif','eek0.gif','mad.gif','sad_blue0.gif','neutral.gif');
   
$insertableSubdir 'sub/';
   
$insertableGraemlins = array(':)' => 'happy.gif',
                                
'^_^'=> 'glad.gif'
                                
':(' => 'sad.gif',
                                
':D' => 'biggrin.gif',
                                
':|' => 'neutral.gif',
                                
';)' => 'wink.gif',
                                
':p' => 'lila.gif',
                                
':P' => 'lila.gif');
   
$graemlinCodes array_keys($insertableGraemlins);

   include(
$pathname.'functions.php');
   include(
$pathname.'quotes.php');
   include(
$pathname.'predefined.php');

   if (isset(
$_GET['graemlin']) || (isset($_GET['text']) || isset($_GET['url'])))   {
      
$_GET['graemlin'] = ($_GET['graemlin'] < count($graemlinFiles)) ? $_GET['graemlin'] : 0;

      
/* because some webpages don't allow dynamic images, we have to trick them into thinking that they're static.
         this is done by converting the graemlin variables into a filename, and then redirecting the user to a non-existant
         file possessing that filename.  at this point, mod_rewrite is used in .htaccess to parse the filename and
         transparently redirect to this script.
        
         more information on mod_rewrite can be found here:
         http://www.sitepoint.com/article/guide-url-rewriting

         information on all the flags can be found here:
         http://nanoweb.si.kz/manual/mod_rewrite.html

         a helpful forum where mod_rewrite questions can be asked:
         http://www.mod-rewrite.com/forum/ */
      
if (isset($_GET['mode']) && $_GET['mode'] == 'convert') {
         if (isset(
$_GET['size']) && ($_GET['size'] == || $_GET['size'] == 0))
            unset(
$_GET['size']);
         if (
$_GET['color'] == '000000')
            unset(
$_GET['color']);
         
// protect against http response splitting ($_GET['url'] and $_GET['text'] don't need protection since they're passed through urlencode)
         
if (!is_numeric($_GET['graemlin']) || (isset($_GET['size']) && !is_numeric($_GET['size'])) || (isset($_GET['color']) && !preg_match('#[0-9abcdef]{6}#i',$_GET['color'])) )
            exit();
         if (!empty(
$_GET['url'])) {
            @
header("Location: {$pathname}u{$_GET['graemlin']}.{$_GET['size']}.{$_GET['color']}.".str_replace('%2F','/',urlencode(stripslashes($_GET['url']))).'.png');
         } else {
            
/* replacing $_GET['text'] with stripslashes($_GET['text']) would be ideal, but since something equivalent to
             two stripslashes was done in earlier versions, we won't, less we risk breaking backwards compatability. */
            
@header("Location: $pathname{$_GET['graemlin']}.{$_GET['size']}.{$_GET['color']}.".str_replace('%2F','/',urlencode($_GET['text'])).'.png');
         }
         exit();
      }

      
# Show Graemlin
      /* Creates a Graemlin from user inputed text and displays it as a PNG, via the GD Library [1][2].
         I would like to eventually make this script output in GIF's, and even animated GIFs, but neither 
         are support by the GD Library since, as of this writting, the algorithims behind GIF's aren't 
         public domain, everywhere, yet [3]. 
        
         [1] http://nyphp.org/content/presentations/GDintro/
         [2] http://www.devshed.com/Server_Side/PHP/ImageGeneration/page2.html
         [3] http://www.boutell.com/gd/faq.html  */

      
if (isset($_GET['text'])) {
        
/* when originally developing this script, I didn't know about urlencode or how user-inputed variables are passed
          through addslashes when magic_quotes_gpc is enabled.  to work around this, i replaced things that couldn't
          normally be encoded in url's.  now, although the following isn't necessary for the graemlins that this script now
          generates, it is necessary for the ones that it did generate.  hence, the following is included, now, for
          backwards compatability.  backwards compatability is also the reason why stripslashes is done twice */
         
$signtext stripslashes(stripslashes($_GET['text']));
         
$signtext preg_replace('/_(i(p|sp)|os|browser)/',"%$1",$signtext);
         
$signtext strtr($signtext,
                           array(
'_dq' => '"',
                                 
'_nbsp' => "\r\n",
                                 
'_excl' => '!',
                                 
'_semi' => ';',
                                 
'_ques' => '?',
                                 
'_perc' => '%',
                                 
'_sq' => "'" ));
      } else {
         
// this is the code that is responsible for getting the contents of remote urls...
         
$size_limit 1024;
         if (isset(
$_GET['url'])) {
            
$url stripslashes($_GET['url']);
            
$server_name preg_replace('#^([\w]+?://)?([^/]+)/?.*$#i','$2',$url);
            if (
$fsock = @fsockopen("tcp://$server_name",80,$errno,$errstr,1) ) 
            {
               @
fputs($fsock,"GET ".substr($_GET['url'],strpos($url,$server_name)+strlen($server_name))." HTTP/1.0\r\n");
               @
fputs($fsock,"Host: $server_name\r\n");
               @
fputs($fsock,"Referer: http://www.frostjedi.com/terra/scripts/graemlin.php\r\n");
               @
fputs($fsock,"User-Agent: Frost Jedi Graemlin Creator\r\n");
               @
fputs($fsock,"Connection: close\r\n\r\n");

               
$signtext '';
               while (!
feof($fsock) && fgets($fsock1024) != "\r\n");
               while (!
feof($fsock)) {
                  
$signtext .= fread($fsock1024);
                  if (
strlen($signtext) > (1024 $size_limit 1024))
                     break;
               }
            }
            else
               
$signtext "$url\r\nis unaccessable.";
            
$signtext rtrim(str_replace('&nbsp;',' ',strip_tags(str_replace('<br>',"\r\n",$signtext))));
         }
      }

      
header('Content-type: image/png');

      
// $HTTP_SERVER_VARS['REDIRECT_URL'] is set when either mod_rewrite or ErrorDocument commands are used in .htaccess.

      
srand(time());

      @
$ipAddress $HTTP_SERVER_VARS['REMOTE_ADDR'];
      @
$browserOS $HTTP_SERVER_VARS['HTTP_USER_AGENT'];

      
# $isp isn't defined in-line because the regex that it's equal to is used twice in-line.
      
$isp = isset($ipAddress) ? preg_replace('/.*\.([^\.]*\.[^\.]*)$/',"$1",gethostbyaddr($ipAddress)) : 'an odd ISP';

      
$signtext strtr($signtext,
                        array(
'%ip' => isset($ipAddress) ? $ipAddress 'x.x.x.x',
                              
'%isp' => preg_match('/\.[0-9]+$/',$isp) ? 'an Unknown ISP' $isp,
                              
'%os' => isset($browserOS) ? identify_os($browserOS) : 'an Unknown OS',
                              
'%browser' => isset($browserOS) ? identify_browser($browserOS) : 'an Unknown Browser'));
      
# replace only the first instance of %quote.
      
$signtext preg_replace("/%quote/",$quotes[rand() % count($quotes)],$signtext,1);
      
$signtext array_map('trim',explode("\r\n",$signtext));
      
$length 20;
      
$height 0;
      
$fontsize = (isset($_GET['size']) && $_GET['size'] != 0) ? $_GET['size'] : 7;
      
$fontred = isset($_GET['color']) ? floorhexdec($_GET['color']) / 65536) % 256 0;
      
$fontgreen = isset($_GET['color']) ? floorhexdec($_GET['color']) / 256) % 256 0;
      
$fontblue = isset($_GET['color']) ? hexdec($_GET['color']) % 256 0;
      
$midSpace 3;
      
$bottomSpace 2;
      
$topSpace 7;
      
$graemlinSpace 1;
      
# international font support requires the use of a unicode font, such as the Arial Unicode MS TTF font:
      # http://support.microsoft.com/support/kb/articles/q287/2/47.asp
      
$fontface 'protected/arial.ttf';

      
$graemlinRegex implode('|',array_map('preg_quote',$graemlinCodes));

      
$subHeight[] = $topSpace;
      for (
$num=0;$num<count($signtext);$num++) {
         
$subLength[$num] = 0;
         
$lineText[] = preg_split("/$graemlinRegex/",$signtext[$num]);
         
$containsGraemlins false;
         
//preg_match_all("/$graemlinRegex/",$signtext[$num],$lineGraemlins[$num]); # -- could be used, but the following should be faster.
         //$lineGraemlins[$num] = $lineGraemlins[$num][0]; // ...
         
for ($snum=0;$snum<count($lineText[$num])-1;$snum++) {
            
$containsGraemlins true;
            
$signtext[$num] = substr($signtext[$num],strlen($lineText[$num][$snum]));  # this is what should be faster
            
$lineGraemlins[$num][] = preg_replace("/^($graemlinRegex).*/","$1",$signtext[$num]);  # ...
            
$signtext[$num] = preg_replace("/^($graemlinRegex)(.*)/","$2",$signtext[$num]);  # ...
            
$dims[$num][] = imagettfbbox($fontsize,0,$pathname $fontface,$lineText[$num][$snum]);
            
$subLength[$num] += abs($dims[$num][$snum][2] - $dims[$num][$snum][0]) + 15 2*$graemlinSpace;
         }
         
$dims[$num][] = imagettfbbox($fontsize,0,$pathname $fontface,$lineText[$num][$snum]);
         
$subLength[$num] += abs($dims[$num][$snum][2] - $dims[$num][$snum][0]);
         
$length = ($subLength[$num] + $length) ? $length $subLength[$num] + 6;
         
$subHeight[] = $subHeight[$num] + (($containsGraemlins && $fontsize 15) ? 15 $fontsize) + (($num == 0) ? $midSpace);
      }
      
$height $subHeight[$num] - (($num != 0) ? $midSpace 0) + $bottomSpace;

      
$sign imagecreate(($length 46) ? 46 $length,$height+22);
      
imagecolortransparent($sign,imagecolorallocate($sign,255,255,255));
      
imagefilledrectangle($sign,0,4,$length 1,$height+4,imagecolorallocate($sign,255,255,254));
      
imagefilledpolygon($sign,array(5/33*($length 1),$height+4,$length 1,$height+4,$length 1,4,28/33*($length 1),4),4,imagecolorallocate($sign,235,235,235));
      
imagefilledpolygon($sign,array(9/33*($length 1),$height+4,$length 1,$height+4,$length 1,4,31/33*($length 1),4),3,imagecolorallocate($sign,219,219,219));  
      
imagerectangle($sign,0,4,$length 1,$height+4,imagecolorallocate($sign,0,0,0));

      
imagecopy($sign,imagecreatefromgif($pathname 'top.gif'),floor(($length 1) / 2) - 17,0,0,0,41,4);
      
imagecopy($sign,imagecreatefromgif($pathname $graemlinFiles[$_GET['graemlin']]),floor(($length 1) / 2) - 17,$height+5,0,0,41,17);

      for (
$num=0;$num<count($lineText);$num++) {
         
$subLength[$num] = floor(abs($length-$subLength[$num]-2)/2)+1;
         for (
$snum=0;$snum<count($lineText[$num])-1;$snum++) {
            
imagettftext($sign,$fontsize,0,$subLength[$num],$subHeight[$num+1],imagecolorallocate($sign,$fontred,$fontgreen,$fontblue),$pathname $fontface,$lineText[$num][$snum]);
            
$subLength[$num] += abs($dims[$num][$snum][2] - $dims[$num][$snum][0]) + $graemlinSpace;
            
imagecopy($sign,imagecreatefromgif($pathname.$insertableSubdir.$insertableGraemlins[$lineGraemlins[$num][$snum]]),$subLength[$num],$subHeight[$num+1]-15,0,0,15,15);
            
$subLength[$num] += 15 $graemlinSpace;
         }
         
imagettftext($sign,$fontsize,0,$subLength[$num],$subHeight[$num+1],imagecolorallocate($sign,$fontred,$fontgreen,$fontblue),$pathname $fontface,$lineText[$num][$snum]);
      }

      
ob_start();
      
imagepng($sign);
      
# a weak way to hide strings within png's...
      
if (isset($_GET['hide']))
         echo 
$_GET['hide'];
      
$output ob_get_contents();
      
ob_end_clean();

      echo 
$output;

      
imagedestroy($sign);
   } elseif (isset(
$_GET['mode']) && $_GET['mode'] == 'source') {
      
# View Source -- kept in the very off chance that anyone was linking to this location
      
header("Location: $sourceLink");
      exit();
   } else
      
# Default
      
include($pathname.'frontpage.php');
?>