\n\n" . "\n" . " \n" . " Tynian.net\n" . " http://tynian.net/\n" . " Brian Almeida's personal blog.\n" . "\n" . " en-us\n" . " http://blogs.law.harvard.edu/tech/rss\n" . "\n" . " $email\n" . " $email\n" . " 2000-2005 Brian Almeida\n" . "\n" . # this empty domain attribute nonsense is to work around a bug in # the built-in Ruby RSS parser " Personal\n" . " Blog\n" . "\n" . " Pablotron World Enterprises!\n" . " $lbd\n" . " 120\n" . "\n"; foreach ($news_ary as $i => $vals) { $link = filter_content("http://tynian.net/?e={$vals['time']}"); echo " \n" . " " . filter_content(trim($vals['title'])) . "\n" . " $link\n" . " $link\n" . " " . rfc822_time($vals['time']) . "\n" . " $email\n" . " " . filter_content($vals['content']) . "\n" . " \n" . " \n\n"; } echo " \n" . "\n"; # # generate headers # # a lot of this header magic comes from the following page: # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html header('Content-type: text/xml'); header("Last-Modified: $up_str"); # generate header checksums $md5 = md5(ob_get_contents()); # check conditional HTTP GET (1.0 and 1.1) headers if ($up_str == $_SERVER['HTTP_IF_MODIFIED_SINCE']) send_not_modified(); if ($md5 == $_SERVER['HTTP_IF_NONE_MATCH']) send_not_modified(); header('ETag: ' . $md5); header('Content-MD5: ' . $md5); header('Content-Length: ' . ob_get_length()); # flush output if this is a GET request, otherwise # discard contents if ($_SERVER['REQUEST_METHOD'] == 'GET') ob_end_flush(); else ob_end_clean(); # and we're finished exit; ##################### # utility functions # ##################### # # get_news - get a list of news entries in descending order # function get_news($max) { global $NEWS_DIR; # allocate return array $ret = array(); # get list of news entries if (($news_entries = glob("$NEWS_DIR/*")) == FALSE) $news_entries = array(); # iterate over the list of files foreach ($news_entries as $file) { # check to make sure it's a timestamp if (!preg_match('/^[\d]+$/', basename($file))) continue; # get entry time and contents $time = basename($file); $content = @file_get_contents($file); # if we didn't get any content, then skip this entry if (!$content) continue; # build title from content, then strip title from content $title = trim(preg_replace("/^(.*?)\n.*$/", '$1', $content)); $content = preg_replace("/^.*?\n/", '', $content); # build news entry $entry = array( 'title' => $title, 'time' => $time, 'content' => $content, ); # add entry to return array $ret[] = $entry; } # entry reverse-sort callback function entry_reverse_sort_cb($a, $b) { if ($b['time'] < $a['time']) return -1; return ($b['time'] == $a['time']) ? 0 : 1; } # sort return array by descending time usort($ret, 'entry_reverse_sort_cb'); # return results return array_slice($ret, 0, $max); } # # filter_content - encode HTML entities, convert relative img and # anchor URLs to absolute ones. # function filter_content($content) { $ret = preg_replace('/<(a href|img src)=(["\'])(?!http)/', '<\1=\2http://tynian.net/', $content); return htmlentities($ret); } # # rfc822_time - return an RFC822 (HTTP time)-formatted date string. # # Note: this only works for EST! # function rfc822_time($ts) { return strftime('%a, %e %b %Y %T GMT', $ts - 3600 * 5); } # # send_not_modified - send a 304 to the client and exit # function send_not_modified() { header("HTTP/1.0 304 Not Modified"); ob_end_clean(); exit; } ?>