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 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