README - libgcgi - REST library for Gopher HTML git clone git://bitreich.org/libgcgi/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/libgcgi/ DIR Log DIR Files DIR Refs DIR Tags DIR README DIR LICENSE --- README (8346B) --- 1 LIBGCGI(3) Library Functions Manual LIBGCGI(3) 2 3 NAME 4 gcgi_handle_request, gcgi_fatal, gcgi_template, gcgi_set_var, 5 gcgi_get_var, gcgi_free_var_list, gcgi_read_var_list, 6 gcgi_write_var_list, gcgi_gopher_search, gcgi_gopher_path, 7 gcgi_gopher_query, gcgi_gopher_host, gcgi_gopher_port, – REST library for 8 Gopher 9 10 SYNOPSIS 11 #include <libgcgi.h> 12 13 void 14 gcgi_handle_request(struct gcgi_handler h[], char **argv, int argc); 15 16 void 17 gcgi_fatal(char *fmt, ...); 18 19 void 20 gcgi_template(char const *path, struct gcgi_var_list *vars); 21 22 void 23 gcgi_set_var(struct gcgi_var_list *vars, char *key, char *val); 24 25 char * 26 gcgi_get_var(struct gcgi_var_list *vars, char *key); 27 28 void 29 gcgi_free_var_list(struct gcgi_var_list *vars); 30 31 void 32 gcgi_read_var_list(struct gcgi_var_list *vars, char *path); 33 34 int 35 gcgi_write_var_list(struct gcgi_var_list *vars, char *path); 36 37 char *gcgi_gopher_search 38 char *gcgi_gopher_path 39 char *gcgi_gopher_host 40 char *gcgi_gopher_port 41 struct gcgi_var_list gcgi_gopher_query 42 43 DESCRIPTION 44 This library is a C wrapper around the geomyidae(8) new CGI interface, 45 which permits REST applications to be written for Gopher. In this mode, 46 geomyidae(8) directs all requests to a single binary in charge of 47 handling all paths, rather than trying to serve a file. 48 49 Request Handling 50 The central element of the library is an array of structures, using 51 appropriate handler depending on the query path. 52 53 struct gcgi_handler { 54 char const *glob; 55 void (*fn)(char **matches); 56 }; 57 58 The glob is a string against which the path (everything in the query 59 before the “?”) will be matched against. 60 61 The fn function pointer will be called, with an array of matches passed 62 as argument. There are as many matches populated as there are “*” in 63 glob. 64 65 void gcgi_handle_request(struct gcgi_handler h[], int argc, char **argv) 66 Given an array of handlers h, call the first function pointer 67 that matches. argc and argv should be set to the program ones to 68 extract the arguments given by geomyidae(8). The h struct is an 69 array of struct gcgi_handler: 70 71 Content Generation 72 According to geomyidae(8) behavior, the output format will be: 73 • a raw gophermap if the binary is “index.cgi”, 74 • a geomyidae(8) ‘gph’ format if the binary is “index.dcgi”. 75 76 void gcgi_fatal(char *fmt, ...) 77 Prints an error message formatted by fmt and exit(3) the program 78 with status 1. 79 80 void gcgi_template(char const *path, struct gcgi_var_list *vars) 81 Format the template at path replacing every occurence of 82 “{{key}}” by the matching value by searching in vars. 83 84 void gcgi_print_gophermap(char type, char *desc, char *path, char *host, 85 char *port) 86 Print a gophermap entry line with type, desc, path, host, port to 87 be set to the chosen value as described in RFC 1436. Both host 88 and port are NULL, default values will be used. 89 90 91 void gcgi_print_gph(char type, char *desc, char *path, char *host, char 92 *port) 93 Print a gph entry line with type, desc, path, host, port to be 94 set to the chosen value as described in geomyidae(8) manual page. 95 If host or port are NULL, default values will be used. 96 97 Variable List Handling 98 A common data format is used for handling lists of variables: 99 • For parsing a simple text-based database format and writing it back. 100 • For storing the parsed query string in gcgi_gopher_query. 101 • For passing variables to expand in the templates. 102 103 void gcgi_set_var(struct gcgi_var_list *vars, char *key, char *val) 104 Overwrite with val the value of a variable matching key of vars. 105 The key and val buffers are not duplicated, and must remain valid 106 at all time they need to be accessible, such as through 107 gcgi_get_var(). 108 109 char * gcgi_get_var(struct gcgi_var_list *vars, char *key) 110 Get the value of the variable of vars matching key or NULL if 111 none match. 112 113 void gcgi_free_var_list(struct gcgi_var_list *vars) 114 Free memory used by a list of variable. This only frees the 115 memory allocated by this library. 116 117 void gcgi_read_var_list(struct gcgi_var_list *vars, char *path) 118 Store all variables from path onto variables in vars. The file 119 format is similar to RFC822 messages or HTTP headers: 120 • One line per variable, with a key=value format. 121 • The key is everything at the beginning of the line until the 122 occurence of “:”. 123 • The value is everything after “: ”. 124 • After the list of variables, an empty line declares the body 125 of the message, which continues until the end and is stored in 126 a “text” key. 127 128 int gcgi_write_var_list(struct gcgi_var_list *vars, char *path) 129 Encode the variable list vars into a new file at path. A 130 temporary file will be created in the meantime, and the 131 replacement will be atomic so that no partial write can occur. 132 The “text” special key will be turned into the body of the 133 message after an empty line instead of a variable on its own 134 line. 135 136 Global Variables 137 These variables are filled with the components of the query. They will 138 only be valid after handle_request() is called. 139 140 char *gcgi_gopher_search 141 From argv[1], this is the search string, passed after a tab in 142 the gopher protocol for item type “7”. 143 144 char *gcgi_gopher_path 145 From argv[2], this is the query path. It is the full query 146 without the search string and with the query string removed. 147 148 struct gcgi_var_list gcgi_gopher_query 149 From argv[2], this is the query string stored as a key-value 150 gcgi_var_list. It is extracted from the part of the query after 151 the “”?, usually formated as 152 “?key1=value1&key2=value2&key3=value3” 153 154 char *gcgi_gopher_host 155 From argv[3], this is the current host name configured in 156 geomyidae(8). It is what to use as a ‘host’ in links printed 157 out. 158 159 char *gcgi_gopher_port 160 From argv[4], this is the current port number configured in 161 geomyidae(8). It is what to use as a ‘port’ in links printed 162 out. 163 164 EXAMPLES 165 #include "libgcgi.h" 166 167 /* implementation of each handler here */ 168 169 static struct gcgi_handler handlers[] = { 170 { "/", page_home }, 171 { "/song", page_song_list }, 172 { "/song/*", page_song_item }, 173 { "*", page_not_found }, 174 { NULL, NULL }, 175 }; 176 177 int 178 main(int argc, char **argv) 179 { 180 /* privilege dropping, chroot and/or syscall restriction here */ 181 182 gcgi_handle_request(handlers, argv, argc); 183 return 0; 184 } 185 186 ENVIRONMENT VARIABLES 187 libgcgi does not use environment variable, but the application code can 188 make use of them. The environment variables applied to geomyidae(8) will 189 be inherited and accessible. 190 191 BUGS 192 To debug libgcgi, it is possible to call it on a command line, which will 193 show all logging and error messages displayed on stderr: 194 195 $ ./index.cgi "" "/song/never-bored-of-adventure?lyrics=1&comments=1" "" "" 196 197 CAVEATS 198 The Gopher protocol is not designed for file upload. A dedicated file 199 upload protocol such as SFTP or FTP may be used instead. 200 201 The Gopher protocol is not designed for dynamic scripting. A dedicated 202 remote interface protocol such as SSH or telnet may be used instead. 203 204 SEE ALSO 205 geomyidae(8) 206 207 AUTHORS 208 Josuah Demangeon <me@josuah.net> 209 gopher://bitreich.org: The Bitreich Project 210 211 LIBGCGI(3) Library Functions Manual LIBGCGI(3)