<?
/****************************************************************************
* 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'] == 7 || $_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($fsock, 1024) != "\r\n");
while (!feof($fsock)) {
$signtext .= fread($fsock, 1024);
if (strlen($signtext) > (1024 * $size_limit - 1024))
break;
}
}
else
$signtext = "$url\r\nis unaccessable.";
$signtext = rtrim(str_replace(' ',' ',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']) ? floor( hexdec($_GET['color']) / 65536) % 256 : 0;
$fontgreen = isset($_GET['color']) ? floor( hexdec($_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] + 6 < $length) ? $length : $subLength[$num] + 6;
$subHeight[] = $subHeight[$num] + (($containsGraemlins && $fontsize < 15) ? 15 : $fontsize) + (($num == 0) ? 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');
?>