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 //Replace with whatever holds the 'data'
19 typedef struct Data Data;
20 enum {RESPONSE_OK = 200, RESPONSE_BADREQUEST = 400,
21 RESPONSE_UNAUTHORIZED = 401};
23 typedef void (*ModuleHandler) (Data *data, char *params);
26 * Extracts a key/value pair from a request string.
27 * Note that the input is modified by this function.
28 * @param in The string from which to extract the pair
29 * @param key A pointer to a variable to hold the key string
30 * @param value A pointer to a variable to hold the value string
31 * @return A pointer to the start of the next search location, or NULL if
34 static char *KeyPair(char *in, const char **key, const char **value) {
36 if (!in || !*in) { //Invalid input or string is EOL
41 //Must be first so value will be empty if it's not specified
42 if ((next = strchr(in, '&'))) {
44 } else { //Don't return NULL as current pair needs to be returned
47 if ((split = strchr(in, '='))) {
52 //Split was not found, set to default value
57 static void BeginResponse(int response_code, const char *module) {
58 switch (response_code) {
61 case RESPONSE_UNAUTHORIZED:
62 printf("Status: 401 Unauthorized\r\n");
65 printf("Status: 400 Bad Request\r\n");
67 printf("Content-type: application/json; charset=utf-8\r\n\r\n");
69 printf("\t\"module\" : \"%s\"", module);
72 static void BuildResponse(const char *key, const char *value) {
73 printf(",\r\n\t\"%s\" : \"%s\"", key, value);
76 static void EndResponse() {
80 static void SensorsHandler(Data *data, char *params) {
81 const char *key, *value;
82 BeginResponse(RESPONSE_OK, "sensors");
84 while ((params = KeyPair(params, &key, &value))) {
85 BuildResponse(key, value);
91 void FCGI_RequestLoop (Data *data)
94 while (FCGI_Accept() >= 0) {
95 ModuleHandler module_handler = NULL;
96 char module[BUFSIZ], params[BUFSIZ];
98 //strncpy doesn't zero-truncate properly
99 snprintf(module, BUFSIZ, "%s", getenv("DOCUMENT_URI_LOCAL"));
100 snprintf(params, BUFSIZ, "%s", getenv("QUERY_STRING"));
102 //Remove trailing slashes (if present) from module query
103 size_t lastchar = strlen(module) - 1;
104 if (lastchar > 0 && module[lastchar] == '/')
105 module[lastchar] = '\0';
108 if (!strcmp("sensors", module)) {
109 module_handler = SensorsHandler;
110 } else if (!strcmp("admin", module)) {
111 //module_handler = AdminHandlerReplace with pointer to admin handler
114 if (module_handler) {
115 module_handler(data, params);
119 BeginResponse(400, module);
120 BuildResponse("description", "400 Invalid response");
121 snprintf(buf, BUFSIZ, "%d", count);
122 BuildResponse("request-number", buf);
123 BuildResponse("params", params);
124 BuildResponse("host", getenv("SERVER_HOSTNAME"));
130 //printf("Module: %s, Params: %s<br>\n", module, params);
131 //printf("Request number %d, host <i>%s</i>\n",
132 // count++, getenv("SERVER_HOSTNAME"));
136 int main(int argc, char *argv[]) {
137 FCGI_RequestLoop(NULL);