'$estimate'", SQLITE_ASSOC); if ($setid && sqlite_num_rows($setid) > 0) while (sqlite_valid($setid)) { $rowid = sqlite_fetch_single($setid); } else { $rowid = $estimate; } file_put_contents($last_id, $rowid); sqlite_close($db); } } /* ============================ PREVIEW ONLY ========================= */ if (isset($_POST['preview'])) { print "
\n

\nThis is what your entry will look like, roughly:\n

\n"; print "\n"; $temp = array('display' => $display, 'comment' => htmlentities($content), 'date' => time()); makeEntry($temp, false); print "
\n"; print "
\n"; print "Edit the form\n"; } /* ========================= ADDING TO DATABASE ====================== */ if (isset($_POST['add'])) { /* If we have a blacklist running today, check whether the user's IP is in it */ if (file_exists($blockfile)) { $blocked = file_get_contents($blockfile); $blacklisted = strstr($blocked, $ip); if (strlen($blacklisted) > 0) { $btime = substr($blacklisted, strlen($ip) + 1, 11); if ($btime > strtotime("1 hour ago")) { /* Pretty darn sure this is a repeat attack. Fail silently */ $blocked = str_replace($ip, "$ip\n".time()." BANNED (GTK_666)", $blocked); file_put_contents($blockfile, $blocked); unset($usename); unset($email); unset($content); header("Location: $referrer"); exit; } /* It's possible - if unlikely - DHCP is to blame. So just log and flag it */ $flag = true; $blocked = str_replace($ip, "$ip\n".time()." DHCP? (GTK_666)", $blocked); file_put_contents($blockfile, $blocked); } } /* ANTI-SPAM MEASURES (keep updated!) */ /* Very short content - errorcode GTK_111 */ if (strlen($content) < 32) { $spammer = "GTK_111"; $errmsg = "Your note is too short. Trying to test the notes system? Save us the trouble of deleting your test, and don't. It works."; } /* Check data against the 'bad word' list - errorcode GTK_333 */ foreach($badwords as $badword) { if ($spammer) break; if (!$spammer && $email) $spammer = stristr($email, $badword); if (!$spammer) $spammer = stristr($content, $badword); } /* Check whether the content is mostly URLs - errorcode GTK_222 */ if (strlen($spammer) == 0) { $lines = explode("\n", $content); foreach($lines as $no => $line) { $line = rtrim($line); if (preg_match("'(http:\/\/| (sizeof($lines) - $blanklines) / 2) { $spammer = "GTK_222"; } } if (strlen($spammer) > 0) { if (!strstr($spammer, 'GTK_')) { $spammer = "GTK_333"; } if ($flag) { /* We're 100% sure it's spam, the guy reached here once already. Fail silently */ file_put_contents($stats, "$spammer:id not assigned, $ip banned\n", FILE_APPEND); $blocked = file_get_contents($blockfile); $blocked = str_replace($ip, "$ip\n".time()." BANNED ($spammer)", $blocked); file_put_contents($blockfile, $blocked); unset($usename); unset($email); unset($content); header("Location: $referrer"); exit; } /* We're 96.7% sure it's spam. Log the IP and print a failure message just in case */ file_put_contents($blockfile, "$ip\n".time()." ($spammer)\n\n", FILE_APPEND); if (!$errmsg) { $errmsg = "There was an error processing your submission.
\nThe development team have been informed."; } print stretchPage(22); print "

\n$errmsg\n

\n"; print "

Back

\n"; print "\n"; commonFooter(); exit; } /* DEFENSE AGAINST THE REST */ /* Check we aren't currently being flooded by someone else - errorcode GTK_666 */ if (filemtime($queuefile) > $veryrecent) { $queuedb = sqlite_open($queuefile); $result = sqlite_query($queuedb, "SELECT id FROM notes WHERE date > $recent"); $count = sqlite_num_rows($result); if ((int)$count > $likely) { $spammer = "GTK_666"; } sqlite_close($queuedb); } /* * If we got this far all's probably well, so invalid/empty email addresses * are OK to go. We just tag them to ensure we don't try to mail anything * out to them at a later stage */ if (!preg_match($email_regex, $email) || strstr($email, 'lists.php')) { $email = 'GTK_000'.$email; } /* Check and secure contents */ if (strlen($content) > 4096) { print stretchPage(22); print "

Your note is too long to fit on the manual pages! Please review it and try to make it less verbose.

\n"; print "\n"; commonFooter(); exit; } $content = htmlentities($content, ENT_COMPAT, 'UTF-8'); /* Pick up id, insert note data into queue and mail out admin notification */ if (!$lastid = file_get_contents($last_id)) { print stretchPage(22); print "Could not obtain note ID
\n
\n"; print "\n"; commonFooter(); exit; } $id = $lastid + 1; $url = explode('/', $referrer); $lang = $url[sizeof($url) - 2]; $page = $url[sizeof($url) - 1]; $date = time(); $db_string = '("'.$id.'", "'.$page.'", "'.$lang.'", "'.$date.'", "'.$email.'", "'.$display.'", "'.$content.'")'; $db_string = sqlite_escape_string($db_string); $queuedb = sqlite_open($queuefile); $result = sqlite_exec($queuedb, "INSERT INTO notes VALUES $db_string"); sqlite_close($queuedb); if (!file_put_contents($last_id, $id)) { print stretchPage(22); print "New note ID not saved
\n
\n"; print "\n"; commonFooter(); exit; } $printmsg = "

Thank you for contributing! Your note has been queued for processing"; if (!strstr($email, 'GTK_000')) { $printmsg .= ", and you will be notified by email when it goes live"; } $printmsg .= ".

\n"; print stretchPage(20); print $printmsg; print "

Back

\n"; print "\n"; commonFooter(); if (!$result) { /* tell admin there's a problem and create an emergency file to retain the data */ file_put_contents($stats, "GTK_ERROR:$errmsg Backup is in $id.txt\n", FILE_APPEND); $bytes = file_put_contents(DB_DIR."/$id.txt", $id."\n".$page."\n".$lang."\n".$date."\n".$email."\n".$display."\n".$content."\n\n".$ip); $msg = "page: $page\n\n$content\n\n$display - ".date('d-M-Y H:i', $date); if ($mail) mail($mailto, "queue system failed: note $id was backed up ($bytes bytes)", $msg, "From: $mailfrom"); commonFooter(); exit; } /* Mail success notification to the list */ $msg = "page: $page\n\n$content\n\n$display - ".date('d-M-Y H:i', $date); if ($mail) mail($mailto, "note $id has been queued", $msg, "From: $mailfrom"); /* * We can't check for the current id without holding up the page for a whole * unacceptable minute - so we keep the current entry in the queue and * work with the previous successful queue entry from this point instead */ $handle = @fsockopen('216.92.131.4', 119, $errno, $errstr, 10); if ($handle) { $helo = fgets($handle, 1024); if (substr($helo, 0, 3) == '200') { stream_set_timeout($handle, 2); fputs($handle, "GROUP php.gtk.webmaster\r\n"); $groupinfo = fgets($handle, 1024); preg_match("'\d{4,6}'is", $groupinfo, $matches, 0, 10); $last_mail = $matches[0]; fputs($handle, "HEAD $last_mail\r\n"); $headerinfo = fgets($handle, 2048); while ($line != ".\r\n") { $line = fgets($handle, 2048); if (strstr($line, "Subject:")) $subject = $line; $status = socket_get_status($handle); if ($status['timed_out']) { break; } } } fclose($handle); } if ($subject) { $flag = null; if (!strstr($subject, "note ".$lastid)) { /* File an error but hold the data in the queue. errorcode GTK_444 */ file_put_contents($stats, "GTK_444: $lastid held in queue\n", FILE_APPEND); if (strstr($subject, "note ".$id)) { /* NNTP might have been too fast for us! */ $lastid = $id; $lastemail = $email; $lastpage = $page; $flag = true; } } else { /* If we're working with $lastid, we need to get the data out of the queue db first */ $queuedb = sqlite_open($queuefile); $query = sqlite_unbuffered_query($db, "SELECT * FROM notes WHERE id = $lastid", SQLITE_ASSOC, &$errcode); if (!$query || $errcode) { sqlite_close($queuedb); file_put_contents($stats, "$errcode:$lastid (failed SQL query)\n", FILE_APPEND); } else { $last = sqlite_fetch_array($query, SQLITE_ASSOC); $lastpage = $last['page']; $lastemail = $last['email']; $db_string = '("'.$lastid.'", "'.$lastpage.'", "'.$last['lang'].'", "'.$last['date'].'", "'.$lastemail.'", "'.$last['display'].'", "'.$last['note'].'")'; sqlite_close($queuedb); $flag = true; } } if ($flag) { $notesdb = sqlite_open($notesfile); $result = sqlite_exec($notesdb, "INSERT INTO notes VALUES $db_string"); sqlite_close($notesdb); if (!$result) { /* Not being able to write to the notes db is pretty worrying. errorcode GTK_888 */ $errcode = "GTK_888"; file_put_contents($stats, "$errcode:$lastid held in queue (write failed)\n", FILE_APPEND); } else { $queuedb = sqlite_open($queuefile); $result = sqlite_exec($queuedb, "DELETE FROM notes WHERE id = $lastid"); sqlite_close($queuedb); if (!$result) { /* Not being able to write to the queue isn't great either. errorcode GTK_777 */ $errcode = "GTK_777"; file_put_contents($stats, "$errcode:$lastid not deleted from queue\n", FILE_APPEND); } /* Mail the user to confirm good stuff */ if (($errcode != 'GTK_888' && !strstr($last['email'], "GTK_000")) || isset($_COOKIE[$user])) { $msg = "Hi\n\nThis is to confirm that your PHP-GTK manual note reached the top of the queue and will be available for viewing shortly at $referrer.\n\nThank you again for your contribution!\n\nRegards,\nThe PHP-GTK Documentation Group"; if (isset($_COOKIE[$user])) $lastemail = $_COOKIE[$user]; if ($mail) mail($lastemail, "PHP-GTK Manual Note $lastid added", $msg, "From: $mailfrom"); } if (!$errcode) { file_put_contents($stats, "GTK_SUCCESS:$lastid\n", FILE_APPEND); } } } } else { /* no return from NNTP */ file_put_contents($stats, "GTK_444: $lastid held in queue (NNTP response failed)\n", FILE_APPEND); } if ($spammer && $errcode) { /* spammer can only be GTK_666 at this stage (flood) */ /* We're being attacked and they've managed to screw up at least one db */ /* use GTK_999 but preserve the original combo so we know where to look */ $msg = "page: $page\n\n$content\n\n$display - ".date('d-M-Y H:i', $date); if ($mail) mail($mailto, "GTK_999 notification", $msg, "From: $mailfrom"); exit; } if ($spammer) { file_put_contents($blockfile, "$ip\n".time()." ($spammer: note $id)\n\n", FILE_APPEND); } exit; } else { /* ======================= FORM NOT FILLED IN YET ==================== */ ?>

You can contribute to the PHP-GTK manual from the comfort of your own browser! Just add your comment in the big field below, and your name and email address in the little ones.

Thanks to all those hard-working spammers out there, you now have several options when it comes to displaying your email address. By default we will simply replace the @ signs and dots in it (e.g. 'user@example.com' becomes 'user at example dot com'), but we can also add various anti-spam measures at your request - including not displaying it at all. We can only inform you of the progress of your note throughout its lifetime if you use your real email address when submitting it.

We will only display your name if you choose that display option.

Your IP address will be logged when your note is submitted and used during our screening process, but will not be made public at any stage.

Note that HTML tags are not allowed in the notes, but formatting is preserved. URLs signalled by 'http://', 'https://' or 'ftp://' will be turned into clickable links, and PHP code blocks enclosed in the PHP tags <?php and ?> will be source highlighted automatically - so always enclose PHP snippets in those tags. (Double-check that your note appears as you intend during the preview. That's why the preview button is there!)

Please read the following points carefully before submitting your comment. If your post falls into any of the categories mentioned there, it will be rejected by one of the editors.

If you post a note in any of the categories above, it will be removed. However, please feel free to come back and add a note here when your question is answered or you find a solution to your problem!

Please note that there is a chance of the information in the user notes being incorporated into the manual at a later date. This means that any note posted here becomes the property of the PHP-GTK Documentation Group.

>
Please choose a display option for your personal data:
> Obfuscate my email address before displaying it, e.g. 'user at example dot com' (default)
> Add NOSPAM to my email address before displaying it, e.g. 'user at NOSPAM example dot com'
> Randomize part of my email address before displaying it, e.g. 'user at mepelxa dot com'
> Display my name instead of my email address, e.g. 'User L. Schmidt'
Your name:
Your email address:
Your note:
 
The PHP-GTK manual notes system is off-line at present. Please try again later!

\n"; print "

Back

\n"; print "\n"; } commonFooter(); ?>