-
Notifications
You must be signed in to change notification settings - Fork 0
License
josuah/libgcgi
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
LIBGCGI(3) Library Functions Manual LIBGCGI(3)
NAME
gcgi_handle_request, gcgi_fatal, gcgi_template, gcgi_set_var,
gcgi_get_var, gcgi_free_var_list, gcgi_read_var_list,
gcgi_write_var_list, gcgi_gopher_search, gcgi_gopher_path,
gcgi_gopher_query, gcgi_gopher_host, gcgi_gopher_port, – REST library for
Gopher
SYNOPSIS
#include <libgcgi.h>
void
gcgi_handle_request(struct gcgi_handler h[], char **argv, int argc);
void
gcgi_fatal(char *fmt, ...);
void
gcgi_template(char const *path, struct gcgi_var_list *vars);
void
gcgi_set_var(struct gcgi_var_list *vars, char *key, char *val);
char *
gcgi_get_var(struct gcgi_var_list *vars, char *key);
void
gcgi_free_var_list(struct gcgi_var_list *vars);
void
gcgi_read_var_list(struct gcgi_var_list *vars, char *path);
int
gcgi_write_var_list(struct gcgi_var_list *vars, char *path);
char *gcgi_gopher_search
char *gcgi_gopher_path
char *gcgi_gopher_host
char *gcgi_gopher_port
struct gcgi_var_list gcgi_gopher_query
DESCRIPTION
This library is a C wrapper around the geomyidae(8) new CGI interface,
which permits REST applications to be written for Gopher. In this mode,
geomyidae(8) directs all requests to a single binary in charge of
handling all paths, rather than trying to serve a file.
Request Handling
The central element of the library is an array of structures, using
appropriate handler depending on the query path.
struct gcgi_handler {
char const *glob;
void (*fn)(char **matches);
};
The glob is a string against which the path (everything in the query
before the “?”) will be matched against.
The fn function pointer will be called, with an array of matches passed
as argument. There are as many matches populated as there are “*” in
glob.
void gcgi_handle_request(struct gcgi_handler h[], int argc, char **argv)
Given an array of handlers h, call the first function pointer
that matches. argc and argv should be set to the program ones to
extract the arguments given by geomyidae(8). The h struct is an
array of struct gcgi_handler:
Content Generation
According to geomyidae(8) behavior, the output format will be:
• a raw gophermap if the binary is “index.cgi”,
• a geomyidae(8) ‘gph’ format if the binary is “index.dcgi”.
void gcgi_fatal(char *fmt, ...)
Prints an error message formatted by fmt and exit(3) the program
with status 1.
void gcgi_template(char const *path, struct gcgi_var_list *vars)
Format the template at path replacing every occurence of
“{{key}}” by the matching value by searching in vars.
void gcgi_print_gophermap(char type, char *desc, char *path, char *host,
char *port)
Print a gophermap entry line with type, desc, path, host, port to
be set to the chosen value as described in RFC 1436. Both host
and port are NULL, default values will be used.
void gcgi_print_gph(char type, char *desc, char *path, char *host, char
*port)
Print a gph entry line with type, desc, path, host, port to be
set to the chosen value as described in geomyidae(8) manual page.
If host or port are NULL, default values will be used.
Variable List Handling
A common data format is used for handling lists of variables:
• For parsing a simple text-based database format and writing it back.
• For storing the parsed query string in gcgi_gopher_query.
• For passing variables to expand in the templates.
void gcgi_set_var(struct gcgi_var_list *vars, char *key, char *val)
Overwrite with val the value of a variable matching key of vars.
The key and val buffers are not duplicated, and must remain valid
at all time they need to be accessible, such as through
gcgi_get_var().
char * gcgi_get_var(struct gcgi_var_list *vars, char *key)
Get the value of the variable of vars matching key or NULL if
none match.
void gcgi_free_var_list(struct gcgi_var_list *vars)
Free memory used by a list of variable. This only frees the
memory allocated by this library.
void gcgi_read_var_list(struct gcgi_var_list *vars, char *path)
Store all variables from path onto variables in vars. The file
format is similar to RFC822 messages or HTTP headers:
• One line per variable, with a key=value format.
• The key is everything at the beginning of the line until the
occurence of “:”.
• The value is everything after “: ”.
• After the list of variables, an empty line declares the body
of the message, which continues until the end and is stored in
a “text” key.
int gcgi_write_var_list(struct gcgi_var_list *vars, char *path)
Encode the variable list vars into a new file at path. A
temporary file will be created in the meantime, and the
replacement will be atomic so that no partial write can occur.
The “text” special key will be turned into the body of the
message after an empty line instead of a variable on its own
line.
Global Variables
These variables are filled with the components of the query. They will
only be valid after handle_request() is called.
char *gcgi_gopher_search
From argv[1], this is the search string, passed after a tab in
the gopher protocol for item type “7”.
char *gcgi_gopher_path
From argv[2], this is the query path. It is the full query
without the search string and with the query string removed.
struct gcgi_var_list gcgi_gopher_query
From argv[2], this is the query string stored as a key-value
gcgi_var_list. It is extracted from the part of the query after
the “”?, usually formated as
“?key1=value1&key2=value2&key3=value3”
char *gcgi_gopher_host
From argv[3], this is the current host name configured in
geomyidae(8). It is what to use as a ‘host’ in links printed
out.
char *gcgi_gopher_port
From argv[4], this is the current port number configured in
geomyidae(8). It is what to use as a ‘port’ in links printed
out.
EXAMPLES
#include "libgcgi.h"
/* implementation of each handler here */
static struct gcgi_handler handlers[] = {
{ "/", page_home },
{ "/song", page_song_list },
{ "/song/*", page_song_item },
{ "*", page_not_found },
{ NULL, NULL },
};
int
main(int argc, char **argv)
{
/* privilege dropping, chroot and/or syscall restriction here */
gcgi_handle_request(handlers, argv, argc);
return 0;
}
ENVIRONMENT VARIABLES
libgcgi does not use environment variable, but the application code can
make use of them. The environment variables applied to geomyidae(8) will
be inherited and accessible.
BUGS
To debug libgcgi, it is possible to call it on a command line, which will
show all logging and error messages displayed on stderr:
$ ./index.cgi "" "/song/never-bored-of-adventure?lyrics=1&comments=1" "" ""
CAVEATS
The Gopher protocol is not designed for file upload. A dedicated file
upload protocol such as SFTP or FTP may be used instead.
The Gopher protocol is not designed for dynamic scripting. A dedicated
remote interface protocol such as SSH or telnet may be used instead.
SEE ALSO
geomyidae(8)
AUTHORS
Josuah Demangeon <me@josuah.net>
gopher://bitreich.org: The Bitreich Project
LIBGCGI(3) Library Functions Manual LIBGCGI(3)