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 
main(int argc,char ** argv,char ** envp)25 int 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