3 * @purpose Runs the FCGI request loop to handle web interface requests.
5 * <stdio.h> should not be included, because these functions are handled by
6 * fcgi_stdio.h. If included, it must be included after fcgi_stdio.h.
9 #include <fcgi_stdio.h>
14 But the suggestion was: FunctionName, variable_name (local or member),
15 Structure, ENUMVALUE, Extern_FunctionName, g_global
18 enum {STATUS_OK = 200, STATUS_BADREQUEST = 400,
19 STATUS_UNAUTHORIZED = 401};
21 typedef void (*ModuleHandler) (void *data, char *params);
24 * Extracts a key/value pair from a request string.
25 * Note that the input is modified by this function.
26 * @param in The string from which to extract the pair
27 * @param key A pointer to a variable to hold the key string
28 * @param value A pointer to a variable to hold the value string
29 * @return A pointer to the start of the next search location, or NULL if
32 char *FCGI_KeyPair(char *in, const char **key, const char **value)
35 if (!in || !*in) { //Invalid input or string is EOL
40 //Find either = or &, whichever comes first
41 if ((ptr = strpbrk(in, "=&"))) {
42 if (*ptr == '&') { //No value specified
46 //Stopped at an '=' sign
49 if ((ptr = strchr(ptr,'&'))) {
55 } else { //No value specified and no other pair
62 void FCGI_BeginJSON(int status_code, const char *module)
64 switch (status_code) {
67 case STATUS_UNAUTHORIZED:
68 printf("Status: 401 Unauthorized\r\n");
71 printf("Status: 400 Bad Request\r\n");
73 printf("Content-type: application/json; charset=utf-8\r\n\r\n");
75 printf("\t\"module\" : \"%s\"", module);
78 void FCGI_BuildJSON(const char *key, const char *value)
80 printf(",\r\n\t\"%s\" : \"%s\"", key, value);
88 static void SensorsHandler(void *data, char *params)
90 const char *key, *value;
92 //Begin a request only when you know the final result
93 //E.g whether OK or not.
94 FCGI_BeginJSON(STATUS_OK, "sensors");
95 while ((params = FCGI_KeyPair(params, &key, &value))) {
96 FCGI_BuildJSON(key, value);
101 void FCGI_RequestLoop (void *data)
104 while (FCGI_Accept() >= 0) {
105 ModuleHandler module_handler = NULL;
106 char module[BUFSIZ], params[BUFSIZ];
108 //strncpy doesn't zero-truncate properly
109 snprintf(module, BUFSIZ, "%s", getenv("DOCUMENT_URI_LOCAL"));
110 snprintf(params, BUFSIZ, "%s", getenv("QUERY_STRING"));
112 //Remove trailing slashes (if present) from module query
113 size_t lastchar = strlen(module) - 1;
114 if (lastchar > 0 && module[lastchar] == '/')
115 module[lastchar] = 0;
118 if (!strcmp("sensors", module)) {
119 module_handler = SensorsHandler;
120 } else if (!strcmp("admin", module)) {
121 //module_handler = AdminHandlerReplace with pointer to admin handler
124 if (module_handler) {
125 module_handler(data, params);
129 FCGI_BeginJSON(400, module);
130 FCGI_BuildJSON("description", "400 Invalid response");
131 snprintf(buf, BUFSIZ, "%d", count);
132 FCGI_BuildJSON("request-number", buf);
133 FCGI_BuildJSON("params", params);
134 FCGI_BuildJSON("host", getenv("SERVER_HOSTNAME"));
142 int main(int argc, char *argv[]) {
143 FCGI_RequestLoop(NULL);