INCLUDE(CheckLibraryExists)
INCLUDE(GNUInstallDirs)
+###########################################################################
+
+add_compile_options(-Wall -Wextra -Wconversion)
+add_compile_options(-Wno-unused-parameter) # frankly not using a parameter does it care?
+add_compile_options(-Werror=maybe-uninitialized)
+#add_compile_options(-Werror=implicit-function-declaration)
+add_compile_options(-ffunction-sections -fdata-sections)
+add_compile_options(-Wl,--gc-sections)
+add_compile_options(-fPIC)
+
+set(CMAKE_C_FLAGS_PROFILING "-g -O0 -pg -Wp,-U_FORTIFY_SOURCE")
+set(CMAKE_C_FLAGS_DEBUG "-g -O0 -ggdb -Wp,-U_FORTIFY_SOURCE")
+set(CMAKE_C_FLAGS_RELEASE "-g -O2")
+set(CMAKE_C_FLAGS_CCOV "-g -O2 --coverage")
+
+###########################################################################
+
+
CHECK_INCLUDE_FILES(magic.h HAVE_MAGIC_H)
CHECK_LIBRARY_EXISTS(magic magic_load "" HAVE_LIBMAGIC_SO)
IF(HAVE_MAGIC_H)
return result;
}
-static struct json_object *call(AFB_request *request, AFB_PostItem *item, const char *tag, struct json_object *(*fun)(AFB_request*,AFB_PostItem*))
-{
- return embed(request, tag, fun(request, item));
-}
-
static struct json_object *call_void(AFB_request *request, AFB_PostItem *item)
{
struct json_object *obj = jbus_call_sj_sync(jbus, request->api, "true");
}
STATIC void freeCtxCB (MyClientContextT *ctx, MyPluginHandleT *handle, char *uuid) {
- fprintf (stderr, "FreeCtxCB uuid=[%s] Plugin=[%s] count=[%d]", uuid, handle->anythingYouWant, ctx->count);
+ fprintf (stderr, "FreeCtxCB uuid=[%s] Plugin=[%s] count=[%d]", uuid, (char*)handle->anythingYouWant, ctx->count);
free (ctx);
// Note: handle should be free it is a static resource attached to plugin and not to session
#include "local-def.h"
STATIC json_object* pingSample (AFB_request *request) {
- static pingcount = 0;
+ static int pingcount = 0;
json_object *response;
char query [512];
int len;
}
// Close and Free context
STATIC json_object* clientGetPing (AFB_request *request) {
- static count=0;
+ static int count=0;
json_object *jresp;
jresp = json_object_new_object();
#include "../include/local-def.h"
#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
// handle to hold queryAll values
// Sample Generic Ping Debug API
PUBLIC json_object* getPingTest(AFB_request *request) {
- static pingcount = 0;
+ static int pingcount = 0;
json_object *response;
char query [256];
char session[256];
queryHandleT *query = (queryHandleT*)handle;
query->idx += snprintf (&query->msg[query->idx],query->len," %s: \'%s\',", key, value);
+ return MHD_YES; /* continue to iterate */
}
// Helper to retrieve argument from connection
AFB_PostHandle *postHandle = getPostHandle(request);
AFB_PostCtx *postFileCtx;
char filepath[512];
- int len;
+ ssize_t len;
// This is called after PostForm and then after DonePostForm
if (item == NULL) {
free (postFileCtx);
return (jresp);
}
-
+#if defined(PLEASE_FIX_ME_THE_ERROR_IS_postFileCtx_NOT_INITIALIZED)
// Make sure it's a valid PostForm request
if (!request->post && request->post->type != AFB_POST_FORM) {
postFileCtx->jresp= jsonNewMessage(AFB_FAIL,"This is not a valid PostForm request\n");
postFileCtx->jresp= jsonNewMessage(AFB_FAIL,"Buffer size NULL key=%s]\n", item->key);
goto ExitOnError;
}
-
+#endif
// Extract Application Context from posthandle [NULL == 1st iteration]
postFileCtx = (AFB_PostCtx*) postHandle->ctx;
// Check we successfully wrote full buffer
len = write (postFileCtx->fd, item->data, item->len);
- if (item->len != len) {
+ if ((ssize_t)item->len != len) {
postFileCtx->jresp= jsonNewMessage(AFB_FAIL,"Fail to write file [%s] at [%s] error=\n", item->filename, strerror(errno));
goto ExitOnError;
}
POST https://www.gnu.org/software/libmicrohttpd/manual/html_node/microhttpd_002dpost.html#microhttpd_002dpost
*/
+#define _GNU_SOURCE
#include <microhttpd.h>
#include "../include/local-def.h"
// let's compute fixed URL length only once
-static apiUrlLen=0;
-static baseUrlLen=0;
-static rootUrlLen=0;
-
-// proto missing from GCC
-char *strcasestr(const char *haystack, const char *needle);
-
-static int rqtcount = 0; // dummy request rqtcount to make each message be different
-static int postcount = 0;
+static size_t apiUrlLen=0;
+static size_t baseUrlLen=0;
+static size_t rootUrlLen=0;
// try to open libmagic to handle mime types
static AFB_error initLibMagic (AFB_session *session) {
// Create check etag value
-STATIC void computeEtag(char *etag, int maxlen, struct stat *sbuf) {
- int time;
+STATIC void computeEtag(char *etag, size_t maxlen, struct stat *sbuf) {
+ long time;
time = sbuf->st_mtim.tv_sec;
- snprintf(etag, maxlen, "%d", time);
+ snprintf(etag, maxlen, "%ld", time);
}
STATIC int servFile (struct MHD_Connection *connection, AFB_session *session, const char *url, AFB_staticfile *staticfile) {
const char *etagCache, *mimetype;
char etagValue[15];
- struct MHD_Response *response;
+ struct MHD_Response *response = NULL;
struct stat sbuf;
- int ret;
if (fstat (staticfile->fd, &sbuf) != 0) {
fprintf(stderr, "Fail to stat file: [%s] error:%s\n", staticfile->path, strerror(errno));
// this function return either Index.htlm or a redirect to /#!route to make angular happy
STATIC int redirectHTML5(struct MHD_Connection *connection, AFB_session *session, const char* url) {
- int fd;
- int ret;
struct MHD_Response *response;
AFB_staticfile staticfile;
// minimal httpd file server for static HTML,JS,CSS,etc...
STATIC int requestFile(struct MHD_Connection *connection, AFB_session *session, const char* url) {
- int fd, ret, idx;
+ int ret, idx;
AFB_staticfile staticfile;
char *requestdir, *requesturl;
| MHD_USE_TCP_FASTOPEN
| MHD_USE_DEBUG
,
- session->config->httpdPort, // port
+ (uint16_t)session->config->httpdPort, // port
&newClient, NULL, // Tcp Accept call back + extra attribute
&newRequest, session, // Http Request Call back + extra attribute
MHD_OPTION_NOTIFY_COMPLETED, &endRequest, NULL,
{SET_MODE ,1,"mode" , "set the mode: either local, remote or global"},
{SET_READYFD ,1,"readyfd" , "set the #fd to signal when ready"},
- {0, 0, 0}
+ {0, 0, NULL, NULL}
};
static AFB_aliasdir aliasdir[MAX_ALIAS];
// build GNU getopt info from cliOptions
nbcmd = sizeof (cliOptions) / sizeof (AFB_options);
- gnuOptions = malloc (sizeof (ggcOption) * nbcmd);
+ gnuOptions = malloc (sizeof (ggcOption) * (unsigned)nbcmd);
for (ind=0; ind < nbcmd;ind++) {
gnuOptions [ind].name = cliOptions[ind].name;
gnuOptions [ind].has_arg = cliOptions[ind].has_arg;
aliascount++;
}
} else {
- fprintf(stderr, "Too many aliases [max:%s] %s ignored\n", optarg, MAX_ALIAS-1);
+ fprintf(stderr, "Too many aliases [max:%d] %s ignored\n", MAX_ALIAS, optarg);
}
break;
case SET_USERID:
if (optarg == 0) goto needValueForOption;
- if (!sscanf (optarg, "%s", &cliconfig.setuid)) goto notAnInteger;
+ cliconfig.setuid = optarg;
break;
case SET_FAKE_MOD:
fprintf (stderr,"\nERR:AFB-daemon cannot read/write session dir\n\n");
exit (-1);
-errSoundCard:
- fprintf (stderr,"\nERR:AFB-daemon fail to probe sound cards\n\n");
- exit (-1);
-
exitInitLoop:
// try to unlink pid file if any
if (session->background && session->config->pidfile != NULL) unlink (session->config->pidfile);
exit (-1);
-}; /* END AFB-daemon() */
+} /* END AFB-daemon() */
}
}
// Trigger a timer to protect from unacceptable long time execution
- alarm (request->config->apiTimeout);
+ alarm ((unsigned)request->config->apiTimeout);
}
// Out of SessionNone every call get a client context session
goto ExitOnDone;
};
- if (verbose) fprintf(stderr, "Plugin=[%s] Api=[%s] Middleware=[%d] Client=[0x%x] Uuid=[%s] Token=[%s]\n"
+ if (verbose) fprintf(stderr, "Plugin=[%s] Api=[%s] Middleware=[%d] Client=[%p] Uuid=[%s] Token=[%s]\n"
, request->prefix, request->api, plugin->apis[idx].session, clientCtx, clientCtx->uuid, clientCtx->token);
switch(plugin->apis[idx].session) {
AFB_PostRequest postRequest;
if (verbose)
- fprintf (stderr, "postHandle key=%s filename=%s len=%d mime=%s\n", key, filename, size, mimetype);
+ fprintf (stderr, "postHandle key=%s filename=%s len=%zu mime=%s\n", key, filename, size, mimetype);
// Create and Item value for Plugin API
item.kind = kind;
STATIC AFB_request *createRequest (struct MHD_Connection *connection, AFB_session *session, const char* url) {
AFB_request *request;
- int idx;
// Start with a clean request
request = calloc (1, sizeof (AFB_request));
AFB_PostRequest postRequest;
int ret;
- // fprintf (stderr, "doRestAPI method=%s posthandle=0x%x\n", method, con_cls);
+ // fprintf (stderr, "doRestAPI method=%s posthandle=%p\n", method, con_cls);
// if post data may come in multiple calls
if (0 == strcmp(method, MHD_HTTP_METHOD_POST)) {
// Form post is handle through a PostProcessor and call API once per form key
if (strcasestr(encoding, FORM_CONTENT) != NULL) {
- if (verbose) fprintf(stderr, "Create doPostIterate[uid=%d posthandle=0x%x]\n", postHandle->uid, postHandle);
+ if (verbose) fprintf(stderr, "Create doPostIterate[uid=%d posthandle=%p]\n", postHandle->uid, postHandle);
request = createRequest (connection, session, url);
if (request->jresp != NULL) goto ProcessApiCall;
// Size is OK, let's allocate a buffer to hold post data
postHandle->type = AFB_POST_JSON;
- postHandle->privatebuf = malloc(contentlen + 1); // allocate memory for full POST data + 1 for '\0' enf of string
+ postHandle->privatebuf = malloc((unsigned)contentlen + 1); // allocate memory for full POST data + 1 for '\0' enf of string
// if (verbose) fprintf(stderr, "Create PostJson[uid=%d] Size=%d\n", postHandle->uid, contentlen);
return MHD_YES;
for (jdx = 0; plugins[idx]->apis[jdx].name != NULL; jdx++) {
AFB_privateApi *privateapi = malloc (sizeof (AFB_privateApi));
if (plugins[idx]->apis[jdx].privateapi != NULL) {
- fprintf (stderr, "WARNING: plugin=%s api=%s private handle should be NULL=0x%x\n"
+ fprintf (stderr, "WARNING: plugin=%s api=%s private handle should be NULL=%p\n"
,plugins[idx]->prefix,plugins[idx]->apis[jdx].name, plugins[idx]->apis[jdx].privateapi);
}
- privateapi->len = strlen (plugins[idx]->apis[jdx].name);
+ privateapi->len = (int)strlen (plugins[idx]->apis[jdx].name);
privateapi->jtype=json_object_new_string(plugins[idx]->apis[jdx].name);
json_object_get(privateapi->jtype); // increase reference count to make it permanent
plugins[idx]->apis[jdx].privateapi = privateapi;
// if max plugin is reached let's stop searching
if (*count == AFB_MAX_PLUGINS) {
- fprintf(stderr, "[%s] is not loaded [Max Count=%d reached]\n", *count);
+ fprintf(stderr, "[%s] is not loaded [Max Count=%d reached]\n", pluginDir.d_name, *count);
continue;
}
plugins = (AFB_plugin **) malloc (AFB_MAX_PLUGINS *sizeof(AFB_plugin*));
// Loop on every directory passed in --plugins=xxx
- while (dirpath = strsep(&session->config->ldpaths, ":")) {
+ while ((dirpath = strsep(&session->config->ldpaths, ":"))) {
// Ignore any directory we fail to open
if ((dirfd = open(dirpath, O_DIRECTORY)) <= 0) {
fprintf(stderr, "Invalid directory path=[%s]\n", dirpath);
}
// downsize structure to effective number of loaded plugins
- plugins = (AFB_plugin **)realloc (plugins, (count+1)*sizeof(AFB_plugin*));
+ plugins = (AFB_plugin **)realloc (plugins, (unsigned)(count+1)*sizeof(AFB_plugin*));
plugins[count] = NULL;
// complete plugins and save them within current sessions
// Create a new store in RAM, not that is too small it will be automatically extended
PUBLIC void ctxStoreInit (int nbSession) {
- int res;
// let's create as store as hashtable does not have any
- sessions.store = calloc (nbSession+1, sizeof(AFB_clientCtx));
+ sessions.store = calloc (1 + (unsigned)nbSession, sizeof(AFB_clientCtx));
sessions.max=nbSession;
}
}
// Loop on every entry and remove old context sessions.hash
-PUBLIC int ctxStoreGarbage (const int timeout) {
+PUBLIC void ctxStoreGarbage (const int timeout) {
AFB_clientCtx *ctx;
long idx;
AFB_clientCtx *clientCtx=NULL;
const char *uuid;
uuid_t newuuid;
- int ret;
if (request->config->token == NULL) return NULL;
// Warning when no cookie defined MHD_lookup_connection_value may return something !!!
if ((uuid != NULL) && (strnlen (uuid, 10) >= 10)) {
- int search;
// search if client context exist and it not timeout let's use it
clientCtx = ctxStoreSearch (uuid);
// we have no session let's create one otherwise let's clean any exiting values
if (clientCtx == NULL) {
clientCtx = calloc(1, sizeof(AFB_clientCtx)); // init NULL clientContext
- clientCtx->contexts = calloc (1, request->config->pluginCount * (sizeof (void*)));
+ clientCtx->contexts = calloc (1, (unsigned)request->config->pluginCount * (sizeof (void*)));
clientCtx->plugins = request->plugins;
}
// Free Client Session Context
PUBLIC AFB_error ctxTokenReset (AFB_clientCtx *clientCtx, AFB_request *request) {
- int ret;
if (clientCtx == NULL) return AFB_EMPTY;
//if (verbose) fprintf (stderr, "ctxClientReset New uuid=[%s] token=[%s] timestamp=%d\n", clientCtx->uuid, clientCtx->token, clientCtx->timeStamp);
// generate a new token
PUBLIC AFB_error ctxTokenCreate (AFB_clientCtx *clientCtx, AFB_request *request) {
- int oldTnkValid;
- const char *ornew;
uuid_t newuuid;
const char *token;
// generate a new token and update client context
PUBLIC AFB_error ctxTokenRefresh (AFB_clientCtx *clientCtx, AFB_request *request) {
- int oldTnkValid;
- const char *oldornew;
uuid_t newuuid;
if (clientCtx == NULL) return AFB_EMPTY;