<?php require('template.hack');
/*
imagesrv.hack---picks a random file out of a collection.
Chris K. Young <cky@pobox.com>, October 2002.
$Id: imagesrv.hack,v 1.6 2002/12/18 10:57:54 cky Exp $

Copyright (c) 2002 Chris K. Young. All rights reserved.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public Licence as published by
the Free Software Foundation; either version 2 of the Licence, or (at
your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public Licence for more details.

You should have received a copy of the GNU General Public Licence
along with this program; if not, write to Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
*/

/*
This program reads a CDB database named imagesrv.cdb, which can
contain multiple collections of files. For each collection, named
$FILE in this description, a number of keys should exist:

0$FILE
    Contains as its value a decimal representation of the number
    of files in the collection.

1$FILE
    Contains the first file in the collection, represented as the
    MIME type of the file, a null character, and then the contents
    of the file itself.

10$FILE
    Contains the tenth file in the collection, if there are that
    many.
*/

class imagesrv {
    
/* Once and only once. */
    
function open_cdb() {
        return 
dba_open('imagesrv.cdb''r''cdb');
    }

    function 
print_header() {}

    function 
validate_input() {
        return isset(
$_GET['file']);
    }

    function 
process_input() {
        if (!(
$cdb $this->open_cdb()))
            return;
        
$file $_GET['file'];
        if (!(
$items dba_fetch("0$file"$cdb))) {
            
header('Content-Type: text/plain');
            print(
"Whoa! The file collection $file does not exist.\n");
            
dba_close($cdb);
            return;
        }
        list(
$l$r) = array($_GET['l'], $_GET['r']);
        if (!isset(
$l) || $l 1)
            
$l 1;
        if (!isset(
$r) || $r $items)
            
$r $items;
        if (
$l $r) {
            
header('Content-Type: text/plain');
            
printf("Oops! l (%u) seems to be greater than r (%u).\n"$l$r);
            
dba_close($cdb);
            return;
        }
        
$pos mt_rand($l$r);
        
$data dba_fetch("$pos$file"$cdb);
        
dba_close($cdb);
        if (!
$data) {
            
header('Content-Type: text/plain');
            print(
"Oops! It seems we have an internal error here (key).\n");
            return;
        }
        if (!(
$pos strpos($data"\0"))) {
            
header('Content-Type: text/plain');
            print(
"Oops! It seems we have an internal error here (value).\n");
            return;
        }
        
header(sprintf('Content-Type: %s'substr($data0$pos)));
        if ((
$refresh $_GET['refresh']) > 0)
            
header(sprintf('Refresh: %u'$refresh));
        print(
substr($data$pos 1));
    }

    function 
print_form() {
        
$tmpl = new template('The imagesrv gimmick');
        
$tmpl->set_rcsid('$Id: imagesrv.hack,v 1.6 2002/12/18 10:57:54 cky Exp $');
        
$tmpl->print_header();
        
$files = array();
        if (
$cdb $this->open_cdb()) {
            for (
$key dba_firstkey($cdb); $key$key dba_nextkey($cdb))
                if (
$key[0] == '0')
                    
$files[] = substr($key1);
            
dba_close($cdb);
        }
?>
<p>The <samp>imagesrv</samp> gimmick was originally written to allow serving a random image from a collection of images. However, it is general enough to be able to serve files of any type.</p>
<?php
        
if ($files) {
            
$self $_SERVER['PHP_SELF'];
?>
<p>Currently, the following collections are available:</p>
<ul>
<?php
            
while (list($key$val) = each($files))
                
printf("<li><a href=\"%s?file=%s\">%s</a></li>\n"$self,
                       
urlencode($val), htmlspecialchars($val));
?>
</ul>
<?php
        
} else {
?>
<p>Sorry, there are currently no collections available. Please check again another day!</p>
<?php
        
}
        
$tmpl->print_footer();
    }

    function 
print_footer() {}
}
?>