/*
* Copyright 2001-2004 Brandon Long
* All Rights Reserved.
*
* ClearSilver Templating System
*
* This code is made available under the terms of the ClearSilver License.
* http://www.clearsilver.net/license.hdf
*
*/
/* static.cgi
* This is a really simple example of how you can map URL requests to a set of
* hdf and cs files.
*/
#include "ClearSilver.h"
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv, char **envp)
{
NEOERR *err;
CGI *cgi;
char *cs_file;
char hdf_file[_POSIX_PATH_MAX];
char *p;
/* CGI works by passing information from the server to the CGI program via
* environment variables and stdin. cgi_debug_init looks for a file as the
* first argument, and loads it. That file contains key=value pairs which
* cgi_debug_init will load into the environment, allowing you to test your
* program via the command line. */
cgi_debug_init(argc, argv);
/* The ClearSilver cgi toolkit accesses the CGI environment through a
* wrapper. This allows the program to be used in other environments and
* fake the CGI environment, such as FastCGI, mod_python, PyApache, or even
* just from Python to access the python objects instead of the libc API.
* cgiwrap_init_std just sets up for the default CGI environment using the
* libc api. */
cgiwrap_init_std(argc, argv, envp);
/* cgi_init creates a CGI struct, and parses the CGI environment variables.
* It creates an HDF structure as well. */
err = cgi_init(&cgi, NULL);
if (err != STATUS_OK)
{
/* cgi_neo_error renders a NEOERR as an error CGI result */
cgi_neo_error(cgi, err);
/* nerr_log_error logs the error to stderr and cleans up */
nerr_log_error(err);
return -1;
}
/* CGI.PathTranslated is a CGI env var which maps the URL with the
* DocumentRoot to give you the location of the referenced file on disk */
cs_file = hdf_get_value(cgi->hdf, "CGI.PathTranslated", NULL);
if (cs_file == NULL)
{
/* cgi_error returns a simple error page */
cgi_error(cgi, "No PATH_TRANSLATED var");
return -1;
}
/* The hdf.loadpaths variables specify where HDF and ClearSilver look for
* files on the file system. We start setting that up here based on
* the directory of the file referenced */
p = strrchr (cs_file, '/');
if (p)
{
*p = '\0';
err = hdf_set_value(cgi->hdf, "hdf.loadpaths.0", cs_file);
chdir(cs_file);
*p = '/';
if (err)
{
cgi_neo_error(cgi, err);
nerr_log_error(err);
return -1;
}
}
/* Next, we look for a shared HDF static dataset in common.hdf */
err = hdf_read_file(cgi->hdf, "common.hdf");
if (err && !nerr_handle(&err, NERR_NOT_FOUND))
{
cgi_neo_error(cgi, err);
nerr_log_error(err);
return -1;
}
/* Next, we look for an HDF file for this specific page. We first look
* for passedfile.html.hdf, then we check for a file by removing an extension
* from the file, so something like passedfile.html we'll look for
* passedfile.hdf */
snprintf (hdf_file, sizeof(hdf_file), "%s.hdf", cs_file);
err = hdf_read_file (cgi->hdf, hdf_file);
if (err && !nerr_handle(&err, NERR_NOT_FOUND))
{
cgi_neo_error(cgi, err);
nerr_log_error(err);
return -1;
}
p = strrchr (cs_file, '.');
if (p)
{
*p = '\0';
snprintf (hdf_file, sizeof(hdf_file), "%s.hdf", cs_file);
*p = '.';
err = hdf_read_file (cgi->hdf, hdf_file);
if (err && !nerr_handle(&err, NERR_NOT_FOUND))
{
cgi_neo_error(cgi, err);
nerr_log_error(err);
return -1;
}
}
/* Lastly, we need to render a template. The template is either the
* file that was passed to us, or its specificed by CGI.StaticContent
* in one of the HDF files we loaded above. */
cs_file = hdf_get_value (cgi->hdf, "CGI.StaticContent", cs_file);
err = cgi_display (cgi, cs_file);
if (err != STATUS_OK)
{
cgi_neo_error(cgi, err);
nerr_log_error(err);
return -1;
}
return 0;
}