$version, 'key' => $key, 'file' => $file, 'archive' => $archive, 'zipfile' => $zipfile ); } function display_from_archive( $params, $content_map = array(), $override_extractor = null) { $params['template'] = dirname(__FILE__)."/template.php"; $params['title'] = NULL; $params['charset'] = NULL; $params['content'] = NULL; $info_map = array_merge($content_map, array( array('@.*@','@[.](txt|py|rst|jam|v2|bat|sh|xml|qbk)$@i','text','text/plain'), array('@.*@','@[.](c|h|cpp|hpp)$@i','cpp','text/plain'), array('@.*@','@[.]png$@i','raw','image/png'), array('@.*@','@[.]gif$@i','raw','image/gif'), array('@.*@','@[.](jpg|jpeg|jpe)$@i','raw','image/jpeg'), array('@.*@','@[.]css$@i','raw','text/css'), array('@.*@','@[.]js$@i','raw','application/x-javascript'), array('@.*@','@[.]pdf$@i','raw','application/pdf'), array('@.*@','@[.](html|htm)$@i','raw','text/html'), array('@.*@','@[^.](Jamroot|Jamfile|ChangeLog)$@i','text','text/plain'), array('@.*@','@[.]dtd$@i','raw','application/xml-dtd'), )); $preprocess = null; $extractor = null; $type = null; foreach ($info_map as $i) { if (preg_match($i[1],$params['key'])) { $extractor = $i[2]; $type = $i[3]; $preprocess = isset($i[4]) ? $i[4] : NULL; break; } } if ($override_extractor) $extractor = $override_extractor; if (!$extractor) { file_not_found($params); return; } // Check zipfile. $check_file = $params['zipfile'] ? $params['archive'] : $params['file']; if (!is_file($check_file)) { file_not_found($params, $params['zipfile'] ? 'Unable to find zipfile.' : 'Unable to find file.'); return; } $last_modified = max( strtotime("Sun, 11 Jul 2010 18:55:24 +0100"), filemtime($check_file)); if (!conditional_get($last_modified)) return; // Extract the file from the zipfile if ($params['zipfile']) { $unzip = UNZIP .' -p '.escapeshellarg($params['archive']) .' '.escapeshellarg($params['file']); if($extractor == 'raw') { display_raw_file($unzip, $type); return; } // Note: this sets $params['content'] with either the content or an error // message: if(!extract_file($unzip, $params['content'])) { file_not_found($params, $params['content']); return; } } else { if($extractor == 'raw') { display_unzipped_file($params['file'], $type); return; } // Note: this sets $params['content'] with either the content or an error // message: if(!extract_unzipped_file($params['file'], $params['content'])) { file_not_found($params, $params['content']); return; } } if($type == 'text/html') { if(html_headers($params['content'])) { if($_SERVER['REQUEST_METHOD'] != 'HEAD') echo $params['content']; return; } } if($_SERVER['REQUEST_METHOD'] == 'HEAD') return; if ($preprocess) { $params['content'] = call_user_func($preprocess, $params['content']); } echo_filtered($extractor, $params); } function conditional_get($last_modified) { if(!$last_modified) return true; $last_modified_text = date(DATE_RFC2822, $last_modified); $etag = '"'.md5($last_modified).'"'; header("Last-Modified: $last_modified_text"); header("ETag: $etag"); $checked = false; if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $checked = true; $if_modified_since = strtotime(stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE'])); if(!$if_modified_since || $if_modified_since < $last_modified) return true; } if(isset($_SERVER['HTTP_IF_NONE_MATCH'])) { $checked = true; if(stripslashes($_SERVER['HTTP_IF_NONE_MATCH'] != $etag)) return true; } if(!$checked) return true; header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified'); return false; } class boost_archive_render_callbacks { var $content_callback, $params; function boost_archive_render_callbacks($content, $params) { $this->content_callback = $content; $this->archive = $params; } function content_head() { $charset = $this->archive['charset'] ? $this->archive['charset'] : 'us-ascii'; $title = $this->archive['title'] ? 'Boost C++ Libraries - '.$this->archive['title'] : 'Boost C++ Libraries'; print << ${title} HTML; } function content() { if ($this->content_callback) { call_user_func($this->content_callback, $this->archive); } } } function display_raw_file($unzip, $type) { header('Content-type: '.$type); switch($type) { case 'image/png': case 'image/gif': case 'image/jpeg': case 'text/css': case 'application/x-javascript': case 'application/pdf': case 'application/xml-dtd': header('Expires: '.date(DATE_RFC2822, strtotime("+1 year"))); header('Cache-Control: max-age=31556926'); // A year, give or take a day. default: header('Expires: '.date(DATE_RFC2822, strtotime("+1 month"))); header('Cache-Control: max-age=2592000'); // 30 days } // Since we're not returning a HTTP error for non-existant files, // might as well not bother checking for the file if($_SERVER['REQUEST_METHOD'] == 'HEAD') return; ## header('Content-Disposition: attachment; filename="downloaded.pdf"'); $file_handle = popen($unzip,'rb'); fpassthru($file_handle); $exit_status = pclose($file_handle); // Don't display errors for a corrupt zip file, as we seemd to // be getting them for legitimate files. if($exit_status > 3) echo 'Error extracting file: '.unzip_error($exit_status); }; function display_unzipped_file($file, $type) { header('Content-type: '.$type); switch($type) { case 'image/png': case 'image/gif': case 'image/jpeg': case 'text/css': case 'application/x-javascript': case 'application/pdf': case 'application/xml-dtd': header('Expires: '.date(DATE_RFC2822, strtotime("+1 year"))); header('Cache-Control: max-age=31556926'); // A year, give or take a day. } // Since we're not returning a HTTP error for non-existant files, // might as well not bother checking for the file if($_SERVER['REQUEST_METHOD'] == 'HEAD') return; ## header('Content-Disposition: attachment; filename="downloaded.pdf"'); $file_handle = fopen($file,'rb'); // TODO: Check $file_handle (should be okay, because already checked for file). fpassthru($file_handle); $exit_status = fclose($file_handle); // TODO: What if !$exit_status? }; function extract_file($unzip, &$content) { header('Expires: '.date(DATE_RFC2822, strtotime("+1 month"))); header('Cache-Control: max-age=2592000'); // 30 days $file_handle = popen($unzip,'r'); $text = ''; while ($file_handle && !feof($file_handle)) { $text .= fread($file_handle,8*1024); } $exit_status = pclose($file_handle); if($exit_status == 0) { $content = $text; return true; } else { $content = strstr($_SERVER['HTTP_HOST'], 'beta') ? unzip_error($exit_status) : null; return false; } } function extract_unzipped_file($file, &$content) { header('Expires: '.date(DATE_RFC2822, strtotime("+1 month"))); header('Cache-Control: max-age=2592000'); // 30 days $file_handle = fopen($file,'r'); if($file_handle === FALSE) { $content = null; return false; } $text = ''; while ($file_handle && !feof($file_handle)) { $text .= fread($file_handle,8*1024); } $exit_status = fclose($file_handle); if($exit_status) { $content = $text; return true; } else { $content = null; return false; } } // // Filters // function echo_filtered($extractor, $params) { $extractor_name = $extractor.'_filter'; call_user_func($extractor_name, $params); } function text_filter($params) { $params['title'] = htmlentities($params['key']); display_template($params['template'], new boost_archive_render_callbacks('text_filter_content', $params)); } function text_filter_content($params) { print "

".htmlentities($params['key'])."

\n"; print "
\n";
    print_encoded_text($params, 'text');
    print "
\n"; } function cpp_filter($params) { $params['title'] = htmlentities($params['key']); display_template($params['template'], new boost_archive_render_callbacks('cpp_filter_content', $params)); } function cpp_filter_content($params) { print "

".htmlentities($params['key'])."

\n"; print "
\n";
    print_encoded_text($params, 'cpp');
    print "
\n"; } function boost_book_html_filter($params) { html_init($params); display_template($params['template'], new boost_archive_render_callbacks('boost_book_html_filter_content', $params)); } function boost_book_html_filter_content($params) { $text = prepare_html($params['content']); $text = substr($text,strpos($text,'
')); $text = substr($text,0,strpos($text,'')); $text = str_replace('
','',$text); $text = str_replace('','
',$text); $text = str_replace('','
',$text); $text = preg_replace( '@[\s]+(border|cellpadding|cellspacing|width|height|valign|frame|rules|naturalsizeflag|background)=[^\s>]+@i', '', $text ); ## for ($i = 0; $i < 8; $i++) { $text = preg_replace( '@([^@Ssm', '${2}', $text ); } ## print $text; } function boost_libs_filter($params) { html_init($params); $text = extract_html_body($params['content']); if($text) { $text = prepare_html($text); $text = remove_html_banner($text); $text = prepare_themed_html($text); $params['content'] = $text; display_template($params['template'], new boost_archive_render_callbacks('boost_libs_filter_content', $params)); } else { print $params['content']; } } function boost_libs_filter_content($params) { return $params['content']; } function boost_frame1_filter($params) { html_init($params); display_template($params['template'], new boost_archive_render_callbacks(new boost_frame1_filter_content, $params)); } function boost_frame1_filter_content($params) { $text = prepare_html($params['content']); $text = substr($text,strpos($text,'
')); $text = substr($text,0,strpos($text,'')); for ($i = 0; $i < 8; $i++) { $text = preg_replace( '@(.*)@Ssm', '${2}', $text ); } $text = str_replace('
','',$text); $text = str_replace('
','
',$text); $text = preg_replace( '@[\s]+(border|cellpadding|cellspacing|width|height|valign|frame|rules|naturalsizeflag|background)=[^\s>]+@i', '', $text ); print $text; } function simple_filter($params) { print prepare_html($params['content']); } function basic_filter($params) { $text = prepare_html($params['content']); $text = remove_html_banner($text); $is_xhtml = preg_match('@]*xhtml@i', $text); $tag_end = $is_xhtml ? '/>' : '>'; $sections = preg_split('@(|]*>)@i',$text,-1,PREG_SPLIT_DELIM_CAPTURE); $body_index = 0; $index = 0; foreach($sections as $section) { if(stripos($section, '@i',$text,$table_end,PREG_OFFSET_CAPTURE); if (isset($table_begin[0]) && isset($table_end[0])) { $table_contents_start = $table_begin[0][1] + strlen($table_begin[0][0]); $table_contents = substr($text, $table_contents_start, $table_end[0][1] - $table_contents_start); if(strpos($table_contents, 'boost.png') !== FALSE) { preg_match('@]*>?([^<]*<(h[12]|p).*?)@is', $table_contents, $table_contents_header, PREG_OFFSET_CAPTURE); $head = substr($text, 0, $table_begin[0][1]); $header = isset($table_contents_header[1]) ? $table_contents_header[1][0] : ''; $tail = substr($text, $table_end[0][1] + strlen($table_end[0][0])); $tail = preg_replace('@^\s*\s*@', '', $tail); $text = $head.$header.$tail; return $text; } } $parts = preg_split('@(?=<(p|blockquote))@', $text, 2); $header = $parts[0]; $content = $parts[1]; $header = preg_replace('@(\s*)]*src="(\.\.\/)*boost\.png"[^>]*>@', '$1', $header); $header = preg_replace('@]*src="(\.\.\/)*boost\.png"[^>]*>\s*<[hb]r.*?>@', '', $header); return $header.$content; } function prepare_themed_html($text) { $text = preg_replace( '@(]+>[\s]*)?]*>([\s]*)?@i', '', $text ); $text = preg_replace( '@]*>@i', '', $text ); $text = preg_replace( '@]*>@i', '', $text ); /* Remove certain attributes */ $text = preg_replace( '@[\s]+(border|cellpadding|cellspacing|width|height|valign|align|frame|rules|naturalsizeflag|background)=("[^"]*"?|\'[^\']*\'?|[^\s/>]+)@i', '', $text ); $text = preg_replace( '@]*@i', ']*>@i', '', $text ); $text = preg_replace( '@<([^\s]+)[\s]+>@i', '<${1}>', $text ); $text = _preg_replace_bounds( '@
[\s]*(
)@i','@(
)[\s]*
@i', '${1}','${1}', $text ); $text = _preg_replace_bounds( '@
[\s]*(

)@i','@(

)[\s]*
@i', '${1}','${1}', $text ); $text = _preg_replace_bounds( '@
[\s]*()@i','@(
)[\s]*
@i', '${1}','${1}', $text ); $text = _preg_replace_bounds( '@
[\s]*
  • @i','@
  • [\s]*
    @i', '
    • ','
    ', $text ); $text = _preg_replace_bounds( '@(?:
    [\s]*)+

    @i','@

    (?:[\s]*
    )+@i', '

    ','

    ', $text ); $text = preg_replace( '@(]+[\s]*>)[\s]*(${2}', $text ); $text = preg_replace( '@([\s]+[\s]+[\s]+[\s]+[\s]+[\s]+)
    .*_arr.*.*.*
    @i', '${1}
    ', $text ); $text = preg_replace( '@([\s]+[\s]+@i', '
    ${1}>', $text ); $text = preg_replace( '@
    ([\s]+[\s]+)@i', '
    ${1}', $text ); $text = preg_replace( '@src=".*theme/u_arr\.gif"@i', 'src="/gfx/space.png" class="up_image"', $text ); $text = preg_replace( '@src=".*theme/l_arr\.gif"@i', 'src="/gfx/space.png" class="prev_image"', $text ); $text = preg_replace( '@src=".*theme/r_arr\.gif"@i', 'src="/gfx/space.png" class="next_image"', $text ); $text = preg_replace( '@src=".*theme/u_arr_disabled\.gif"@i', 'src="/gfx/space.png" class="up_image_disabled"', $text ); $text = preg_replace( '@src=".*theme/l_arr_disabled\.gif"@i', 'src="/gfx/space.png" class="prev_image_disabled"', $text ); $text = preg_replace( '@src=".*theme/r_arr_disabled\.gif"@i', 'src="/gfx/space.png" class="next_image_disabled"', $text ); $text = preg_replace( '@src=".*theme/note\.gif"@i', 'src="/gfx/space.png" class="note_image"', $text ); $text = preg_replace( '@src=".*theme/alert\.gif"@i', 'src="/gfx/space.png" class="caution_image"', $text ); $text = preg_replace( '@src=".*theme/bulb\.gif"@i', 'src="/gfx/space.png" class="tip_image"', $text ); $text = preg_replace( '@@i', '', $text ); $text = preg_replace( '@(@i', '${1} class="inline">', $text ); return $text; } // This takes a plain text file and outputs encoded html with marked // up links. function print_encoded_text($params, $type) { $root = dirname(preg_replace('@([^/]+/)@','../',$params['key'])); // John Gruber's regular expression for finding urls // http://daringfireball.net/2009/11/liberal_regex_for_matching_urls foreach(preg_split( '@\b((?:[\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|[^[:punct:]\s]|/))@', $params['content'], -1, PREG_SPLIT_DELIM_CAPTURE) as $index => $part) { if($index % 2 == 0) { $html = htmlentities($part); if($type == 'cpp') { $html = preg_replace( '@(#[ ]*include[ ]+<)(boost[^&]+)@Ssm', '${1}${2}', $html ); $html = preg_replace( '@(#[ ]*include[ ]+")(boost[^&]+)@Ssm', '${1}${2}', $html ); } print $html; } else { $url = process_absolute_url($part, $root); if($url) { print ''.htmlentities($part).''; } else { print htmlentities($part); } } } } function process_absolute_url($url, $root = null) { // Simplified version of the 'loose' regular expression from // http://blog.stevenlevithan.com/archives/parseuri // // (c) Steven Levithan // MIT License if(!preg_match( '~^'. // Protocol(1): (Could also remove the userinfo detection stuff?) '(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?'. '(?:\/\/)?'. // Authority(2) '('. // User info '(?:[^:@]*:?[^:@]*@)?'. // Host(3) '([^:\/?#]*)'. // Port '(?::\d*)?'. ')'. // Relative(4) '(\/.*)'. '~', $url, $matches)) { return; } $protocol = $matches[1]; $authority = $matches[2]; $host = $matches[3]; $relative = $matches[4]; if(!$authority) return; if($root && ($host == 'boost.org' || $host == 'www.boost.org') && (strpos($relative, '/lib') === 0)) { $url = $root.$relative; } else { $url = ($protocol ? $protocol : 'http').'://'.$authority.$relative; } return $url; } // Display the content in the standard boost template function display_template($template, $callbacks) { $_file = $callbacks; include($template); } // Return a readable error message for unzip exit state. function unzip_error($exit_status) { switch($exit_status) { case 0: return 'No error.'; case 1: return 'One or more warning errors were encountered.'; case 2: return 'A generic error in the zipfile format was detected.'; case 3: return 'A severe error in the zipfile format was detected.'; case 4: return 'Unzip was unable to allocate memory for one or more buffers during program initialization.'; case 5: return 'Unzip was unable to allocate memory or unable to obtain a tty to read the decryption password(s).'; case 6: return 'Unzip was unable to allocate memory during decompression to disk.'; case 7: return 'Unzip was unable to allocate memory during in-memory decompression.'; case 9: return 'The specified zipfile was not found.'; case 10: return 'Invalid options were specified on the command line.'; case 11: return 'No matching files were found.'; case 50: return 'The disk is (or was) full during extraction.'; case 51: return 'The end of the ZIP archive was encountered prematurely.'; case 80: return 'The user aborted unzip prematurely with control-C (or similar).'; case 81: return 'Testing or extraction of one or more files failed due to unsupported compression methods or unsupported decryption.'; case 82: return 'No files were found due to bad decryption password(s).'; default: return 'Unknown unzip error code: ' + $exit_status; } } ?>