<?php set_time_limit(0); error_reporting(0); require(".htconfig.php"); $db = @new mysqli($db_host,$db_user,$db_pass,$db_data); header( "Content-type: text/html; charset=utf-8"); header( "Last-Modified: " . gmdate( "D, j M Y H:i:s" ) . " GMT" ); header( "Expires: " . gmdate( "D, j M Y H:i:s", time() ) . " GMT" ); header( "Cache-Control: no-store, no-cache, must-revalidate" ); // HTTP/1.1 header( "Cache-Control: post-check=0, pre-check=0", FALSE ); header( "Pragma: no-cache" ); // HTTP/1.0 $lang = 'en'; $offensive = $_GET['off']; if($offensive == 'o') $adult = 2; elseif($offensive == 'a') $adult = 1; else $adult = 0; $length = (($_GET['length']) ? intval($_GET['length']) : 0); $numlines = ((intval($_GET['numlines'])) ? intval($_GET['numlines']) : 0); $cat = (($_GET['cat'] == '1') ? 1 : 0); $equal = (($_GET['equal'] == '1') ? 1 : 0); $stats = (($_GET['stats'] == '1') ? 1 : 0); if(strlen($_GET['lang'])) $lang = @$db->real_escape_string($_GET['lang']); if(strlen($_GET['pattern'])) $pattern = @$db->real_escape_string(urldecode($_GET['pattern'])); if(strlen($_GET['regex'])) $regex = @$db->real_escape_string(urldecode($_GET['regex'])); if(strlen($_GET['db'])) $table = @$db->real_escape_string(urldecode($_GET['db'])); else $table = ''; if($length < 0) $length = 0; if($numlines < 0) $numlines = 0; function do_query($table,$length,$numlines,$adult,$cat,$limit,$lang,$pattern,$regex,$equal) { global $db; $rnd = mt_rand(); $r = []; $typesql = (($table) ? " WHERE `category` = '$table' " : " WHERE 1 "); $lengthsql = (($length) ? " AND LENGTH(`text`) < $length " : "" ); if($adult == 2) $adultsql = " AND offensive = 1 "; elseif($adult == 1) $adultsql = ""; else $adultsql = " AND offensive = 0 "; if($numlines) $lengthsql .= " AND (LENGTH(`text`) - LENGTH(REPLACE(`text`,\"\n\",\"\"))) <= $numlines "; $langsql = " AND lang = '$lang' "; $patsql = ''; if(strlen($pattern)) $patsql = " AND MATCH text AGAINST ('$pattern' IN BOOLEAN MODE) "; $regexsql = ''; if(strlen($regex)) $regexsql = " AND text REGEXP '$regex' "; $eqsql = ''; if($equal) { $catsavail = []; $res = @$db->query("SELECT DISTINCT ( `category` ) FROM `fortune` $typesql $adultsql $lengthsql $langsql $patsql $regexsql "); if($res->num_rows) { while($x = $res->fetch_array(MYSQL_ASSOC)) $catsavail[] = $x['category']; $eqsql = " AND `category` = '" . $catsavail[mt_rand(0,$res->num_rows - 1)] . "' "; } } $result = @$db->query("SELECT `text`, `category` FROM `fortune` $typesql $adultsql $lengthsql $langsql $patsql $regexsql $eqsql ORDER BY RAND($rnd) LIMIT $limit"); if($result->num_rows) { while($x = $result->fetch_array(MYSQL_ASSOC)) $r[] = fortune_to_html($x['text']) .(($cat) ? "<br />[{$x['category']}]<br />" : ""); } return $r; } function do_stats($table,$length,$numlines,$adult,$cat,$limit,$lang,$pattern,$regex,$equal) { global $db; $rnd = mt_rand(); $r = []; $typesql = (($table) ? " WHERE `category` = '$table' " : " WHERE 1 "); $lengthsql = (($length) ? " AND LENGTH(`text`) < $length " : "" ); if($adult == 2) $adultsql = " AND offensive = 1 "; elseif($adult == 1) $adultsql = ""; else $adultsql = " AND offensive = 0 "; if($numlines) $lengthsql .= " AND (LENGTH(`text`) - LENGTH(REPLACE(`text`,\"\n\",\"\"))) <= $numlines "; $langsql = " AND lang = '$lang' "; $patsql = ''; if(strlen($pattern)) $patsql = " AND MATCH text AGAINST ('$pattern' IN BOOLEAN MODE) "; $regexsql = ''; if(strlen($regex)) $regexsql = " AND text REGEXP '$regex' "; $eqsql = ''; $result = @$db->query("SELECT `text`, `category` FROM `fortune` $typesql $adultsql $lengthsql $langsql $patsql $regexsql $eqsql"); echo '<br />' . $result->num_rows . ' matching quotations.<br />'; $res = @$db->query("SELECT DISTINCT ( `category` ) FROM `fortune` $typesql $adultsql $lengthsql $langsql $patsql $regexsql "); if($res->num_rows) { echo '<br />Matching Databases:<br />'; while($x = $res->fetch_array(MYSQL_ASSOC)) echo $x['category'].'<br />'; } else echo '<br />No matching databases using those search parameters - please refine your options.<br />'; } function fortune_to_html($s) { // First pass - escape all the HTML entities, and while we're at it // get rid of any MS-DOS end-of-line characters and expand tabs to // 8 non-breaking spaces, and translate linefeeds to <br />. // We also get rid of ^G which used to sound the terminal beep or bell // on ASCII terminals and were humourous in some fortunes. // We could map these to autoplay a short sound file but browser support // is still sketchy and then there's the issue of where to locate the // URL, and a lot of people find autoplay sounds downright annoying. // So for now, just remove them. $s = str_replace( ["&", "<", ">", '"', "\007", "\t", "\r", "\n"], ["&", "<", ">", """, "", " ", "", "<br />"], $s); // Replace pseudo diacritics // These were used to produce accented characters. For instance an accented // e would have been encoded by '^He - the backspace moving the cursor // backward so both the single quote and the e would appear in the same // character position. Umlauts were quite clever - they used a double quote // as the accent mark over a normal character. $s = preg_replace("/'\010([a-zA-Z])/","&\\1acute;",$s); $s = preg_replace("/\"\010([a-zA-Z])/","&\\1uml;",$s); $s = preg_replace("/\`\010([a-zA-Z])/","&\\1grave;",$s); $s = preg_replace("/\^\010([a-zA-Z])/","&\\1circ;",$s); $s = preg_replace("/\~\010([a-zA-Z])/","&\\1tilde;",$s); // Ignore multiple underlines for the same character. These were // most useful when sent to a line printer back in the day as it // would type over the same character a number of times making it // much darker (e.g. bold). I think there are only one or two // instances of this in the current (2008) fortune cookie database. $s = preg_replace("/(_\010)+/","_\010",$s); // Map the characters which sit underneath a backspace. // If you can come up with a regex to do all of the following // madness - be my guest. // It's not as simple as you think. We need to take something // that has been backspaced over an arbitrary number of times // and wrap a forward looking matching number of characters in // HTML, whilst deciding if it's intended as an underline or // strikeout sequence. // Essentially we produce a string of '1' and '0' characters // the same length as the source text. // Any position which is marked '1' has been backspaced over. $cursor = 0; $dst = $s; $bs_found = false; for($x = 0; $x < strlen($s); $x ++) { if($s[$x] == "\010" && $cursor) { $bs_found = true; $cursor --; $dst[$cursor] = '1'; $dst[$x] = '0'; $continue; } else { if($bs_found) { $bs_found = false; $cursor = $x; } $dst[$cursor] = '0'; $cursor ++; } } $out = ''; $strike = false; $bold = false; // Underline sequence, convert to bold to avoid confusion with links. // These were generally used for emphasis so it's a reasonable choice. // Please note that this logic will fail if there is an underline sequence // and also a strikeout sequence in the same fortune. if(strstr($s,"_\010")) { $len = 0; for($x = 0; $x < strlen($s); $x ++) { if($dst[$x] == '1') { $len ++; $bold = true; } else { if($bold) { $out .= '<strong>'; while($s[$x] == "\010") $x ++; $out .= substr($s,$x,$len); $out .= '</strong>'; $x = $x + $len - 1; $len = 0; $bold = false; } else $out .= $s[$x]; } } } // These aren't seen very often these days - simulation of // backspace/replace. You could occasionally see the original text // on slower terminals before it got replaced. Once modems reached // 4800/9600 baud in the late 70's and early 80's the effect was // mostly lost - but if you find a really old fortune file you might // encounter a few of these. else { for($x = 0; $x < strlen($s); $x ++) { if($dst[$x] == '1') { if($strike) $out .= $s[$x]; else $out .= '<strike>'.$s[$x]; $strike = true; } else { if($strike) $out .= '</strike>'; $strike = false; $out .= $s[$x]; } } } // Many of the underline sequences are also wrapped in asterisks, // which was yet another way of marking ASCII as 'bold'. // So if it's an underline sequence, and there are asterisks // on both ends, strip the asterisks as we've already emboldened the text. $out = preg_replace('/\*(<strong>[^<]*<\/strong>)\*/',"\\1",$out); // Finally, remove the backspace characters which we don't need anymore. return str_replace("\010","",$out); } $result1 = do_query($table,$length,$numlines,$adult,$cat,1,$lang,$pattern,$regex,$equal); if(count($result1)) echo $result1[0]; if($stats) do_stats($table,$length,$numlines,$adult,$cat,1,$lang,$pattern,$regex,$equal);