1/*
2 * Copyright 2001-2004 Brandon Long
3 * All Rights Reserved.
4 *
5 * ClearSilver Templating System
6 *
7 * This code is made available under the terms of the ClearSilver License.
8 * http://www.clearsilver.net/license.hdf
9 *
10 */
11
12/* static.cgi
13 * This is a really simple example of how you can map URL requests to a set of
14 * hdf and cs files.
15 */
16
17#include "ClearSilver.h"
18
19#include <unistd.h>
20#include <limits.h>
21#include <string.h>
22#include <stdio.h>
23#include <stdlib.h>
24
25int main(int argc, char **argv, char **envp)
26{
27  NEOERR *err;
28  CGI *cgi;
29  char *cs_file;
30  char hdf_file[_POSIX_PATH_MAX];
31  char *p;
32
33  /* CGI works by passing information from the server to the CGI program via
34   * environment variables and stdin.  cgi_debug_init looks for a file as the
35   * first argument, and loads it.  That file contains key=value pairs which
36   * cgi_debug_init will load into the environment, allowing you to test your
37   * program via the command line. */
38  cgi_debug_init(argc, argv);
39
40  /* The ClearSilver cgi toolkit accesses the CGI environment through a
41   * wrapper.  This allows the program to be used in other environments and
42   * fake the CGI environment, such as FastCGI, mod_python, PyApache, or even
43   * just from Python to access the python objects instead of the libc API.
44   * cgiwrap_init_std just sets up for the default CGI environment using the
45   * libc api. */
46  cgiwrap_init_std(argc, argv, envp);
47
48  /* cgi_init creates a CGI struct, and parses the CGI environment variables.
49   * It creates an HDF structure as well.  */
50  err = cgi_init(&cgi, NULL);
51  if (err != STATUS_OK)
52  {
53    /* cgi_neo_error renders a NEOERR as an error CGI result */
54    cgi_neo_error(cgi, err);
55    /* nerr_log_error logs the error to stderr and cleans up */
56    nerr_log_error(err);
57    return -1;
58  }
59
60  /* CGI.PathTranslated is a CGI env var which maps the URL with the
61   * DocumentRoot to give you the location of the referenced file on disk */
62  cs_file = hdf_get_value(cgi->hdf, "CGI.PathTranslated", NULL);
63  if (cs_file == NULL)
64  {
65    /* cgi_error returns a simple error page */
66    cgi_error(cgi, "No PATH_TRANSLATED var");
67    return -1;
68  }
69
70  /* The hdf.loadpaths variables specify where HDF and ClearSilver look for
71   * files on the file system.  We start setting that up here based on
72   * the directory of the file referenced */
73  p = strrchr (cs_file, '/');
74  if (p)
75  {
76    *p = '\0';
77    err = hdf_set_value(cgi->hdf, "hdf.loadpaths.0", cs_file);
78    chdir(cs_file);
79    *p = '/';
80    if (err)
81    {
82      cgi_neo_error(cgi, err);
83      nerr_log_error(err);
84      return -1;
85    }
86  }
87  /* Next, we look for a shared HDF static dataset in common.hdf */
88  err = hdf_read_file(cgi->hdf, "common.hdf");
89  if (err && !nerr_handle(&err, NERR_NOT_FOUND))
90  {
91    cgi_neo_error(cgi, err);
92    nerr_log_error(err);
93    return -1;
94  }
95  /* Next, we look for an HDF file for this specific page.  We first look
96   * for passedfile.html.hdf, then we check for a file by removing an extension
97   * from the file, so something like passedfile.html we'll look for
98   * passedfile.hdf */
99  snprintf (hdf_file, sizeof(hdf_file), "%s.hdf", cs_file);
100  err = hdf_read_file (cgi->hdf, hdf_file);
101  if (err && !nerr_handle(&err, NERR_NOT_FOUND))
102  {
103    cgi_neo_error(cgi, err);
104    nerr_log_error(err);
105    return -1;
106  }
107  p = strrchr (cs_file, '.');
108  if (p)
109  {
110    *p = '\0';
111    snprintf (hdf_file, sizeof(hdf_file), "%s.hdf", cs_file);
112    *p = '.';
113    err = hdf_read_file (cgi->hdf, hdf_file);
114    if (err && !nerr_handle(&err, NERR_NOT_FOUND))
115    {
116      cgi_neo_error(cgi, err);
117      nerr_log_error(err);
118      return -1;
119    }
120  }
121  /* Lastly, we need to render a template.  The template is either the
122   * file that was passed to us, or its specificed by CGI.StaticContent
123   * in one of the HDF files we loaded above. */
124  cs_file = hdf_get_value (cgi->hdf, "CGI.StaticContent", cs_file);
125  err = cgi_display (cgi, cs_file);
126  if (err != STATUS_OK)
127  {
128    cgi_neo_error(cgi, err);
129    nerr_log_error(err);
130    return -1;
131  }
132  return 0;
133}
134