- add missing svn props from svn 1798 commit
[fw/openocd] / src / server / httpd.c
index f36cf437905bbadb9a093aa43b8f1f1883f204e9..6d9851533d8af87ece3c307b3133e810f6a175da 100644 (file)
 #include "config.h"
 #endif
 
-#include "replacements.h"
-
-#include "server.h"
-
-#include "log.h"
 #include "telnet_server.h"
 #include "target.h"
 
-#include <command.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <signal.h>
-
-#include <sys/types.h>
-#include <sys/select.h>
-#include <sys/socket.h>
 #include <microhttpd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
+#include <pthread.h>
+#include <signal.h>
 
 #define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
 
-static const char *appendf(const *prev, const char *format, ...)
+int loadFile(const char *name, void **data, size_t *len);
+
+static const char *appendf(const char *prev, const char *format, ...)
 {
        va_list ap;
        va_start(ap, format);
@@ -69,7 +53,7 @@ static const char *appendf(const *prev, const char *format, ...)
 
        if (prev != NULL)
        {
-               free(prev);
+               free((void *)prev);
        }
 
        if (string == NULL)
@@ -120,7 +104,7 @@ static int httpd_Jim_Command_writeform(Jim_Interp *interp, int argc,
        char *file = (char*) Jim_GetString(argv[2], NULL);
 
        // Find length
-       char *data;
+       const char *data;
        int actual;
 
        int retcode;
@@ -134,23 +118,19 @@ static int httpd_Jim_Command_writeform(Jim_Interp *interp, int argc,
 
        data = Jim_GetString(Jim_GetResult(interp), &actual);
 
-       FILE *f;
-       f = fopen(file, "wb");
-       if (f != NULL)
+       FILE *f = fopen(file, "wb");
+       if (NULL == f)
        {
-               int ok;
-               ok = fwrite(data, 1, actual, f) == actual;
-               fclose(f);
-
-               if (!ok)
-               {
-                       Jim_SetResultString(interp, "Could not write to file", -1);
-                       return JIM_ERR;
-               }
+               Jim_SetResultString(interp, "Could not create file", -1);
+               return JIM_ERR;
        }
-       else
+
+       int result = fwrite(data, 1, actual, f);
+       fclose(f);
+
+       if (result != actual)
        {
-               Jim_SetResultString(interp, "Could not create file", -1);
+               Jim_SetResultString(interp, "Could not write to file", -1);
                return JIM_ERR;
        }
        return JIM_OK;
@@ -243,7 +223,7 @@ static void append_key(struct httpd_request *r, const char *key,
 /* append data to each key */
 static int iterate_post(void *con_cls, enum MHD_ValueKind kind,
                const char *key, const char *filename, const char *content_type,
-               const char *transfer_encoding, const char *data, size_t off,
+               const char *transfer_encoding, const char *data, uint64_t off,
                size_t size)
 {
        struct httpd_request *r = (struct httpd_request*) con_cls;
@@ -261,13 +241,89 @@ static int record_arg(void *cls, enum MHD_ValueKind kind, const char *key,
        return MHD_YES;
 }
 
-static int ahc_echo(void * cls, struct MHD_Connection * connection,
-               const char * url, const char * method, const char * version,
-               const char * upload_data, unsigned int * upload_data_size, void ** ptr)
+
+int handle_request(struct MHD_Connection * connection, const char * url)
 {
        struct MHD_Response * response;
+
        int ret;
+       const char *suffix;
+       suffix = strrchr(url, '.');
+       if ((suffix != NULL) && (strcmp(suffix, ".tcl") == 0))
+       {
+               printf("Run tcl %s\n", url);
+
+               int retcode;
+
+               const char *script = alloc_printf(
+                               "global httpdata; source {%s}; set httpdata", url);
+               retcode = Jim_Eval_Named(interp, script, "httpd.c", __LINE__ );
+               free((void *) script);
+
+               if (retcode == JIM_ERR)
+               {
+                       printf("Tcl failed\n");
+                       const char *t = httpd_exec_cgi_tcl_error(interp);
+                       if (t == NULL)
+                               return MHD_NO;
+
+                       response = MHD_create_response_from_data(strlen(t), (void *) t,
+                                       MHD_YES, MHD_NO);
+                       ret = MHD_queue_response(connection,
+                                       MHD_HTTP_INTERNAL_SERVER_ERROR, response);
+                       MHD_destroy_response(response);
+                       return ret;
+               }
+               else
+               {
+                       LOG_DEBUG("Tcl OK");
+                       /* FIX!!! how to handle mime types??? */
+                       const char *result;
+                       int reslen;
+                       result = Jim_GetString(Jim_GetResult(interp), &reslen);
+
+                       response = MHD_create_response_from_data(reslen, (void *) result,
+                                       MHD_NO, MHD_YES);
+                       ret = MHD_queue_response(connection,
+                                       MHD_HTTP_INTERNAL_SERVER_ERROR, response);
+                       MHD_destroy_response(response);
+                       return ret;
+               }
+       }
+       else
+       {
+               void *data;
+               size_t len;
+
+               int retval = loadFile(url, &data, &len);
+               if (retval != ERROR_OK)
+               {
+                       printf("Did not find %s\n", url);
 
+                       response = MHD_create_response_from_data(strlen(PAGE_NOT_FOUND),
+                                       (void *) PAGE_NOT_FOUND, MHD_NO, MHD_NO);
+                       ret = MHD_queue_response(connection, MHD_HTTP_NOT_FOUND, response);
+                       MHD_destroy_response(response);
+                       return ret;
+               }
+
+               LOG_DEBUG("Serving %s length=%u", url, len);
+               /* serve file directly */
+               response = MHD_create_response_from_data(len, data, MHD_YES, MHD_NO);
+               MHD_add_response_header(response, "Content-Type", "image/png");
+
+               ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
+               MHD_destroy_response(response);
+
+               //free(data);
+               return ret;
+       }
+}
+
+static int ahc_echo(void * cls, struct MHD_Connection * connection,
+               const char * url, const char * method, const char * version,
+               const char * upload_data, unsigned int * upload_data_size, void ** ptr)
+{
        int post = 0;
 
        if (0 == strcmp(method, "POST"))
@@ -305,7 +361,7 @@ static int ahc_echo(void * cls, struct MHD_Connection * connection,
                if (r->post)
                {
                        r->postprocessor = MHD_create_post_processor(connection, 2048
-                                       * 1024, iterate_post, r);
+                                       * 1024, &iterate_post, r);
                }
 
                return MHD_YES;
@@ -337,85 +393,30 @@ static int ahc_echo(void * cls, struct MHD_Connection * connection,
         * being subverted to evil purposes
         */
 
-       url++; /* skip '/' */
+       const char *httpd_dir=PKGLIBDIR "/httpd";
 
-       const char *suffix;
-       suffix = strrchr(url, '.');
-       if ((suffix != NULL) && (strcmp(suffix, ".tcl") == 0))
+       if (*url=='/')
        {
-               printf("Run tcl %s\n", url);
-
-               int retcode;
-
-               const char *script = alloc_printf(
-                               "global httpdata; source {%s}; set httpdata", url);
-               retcode = Jim_Eval_Named(interp, script, "httpd.c", __LINE__ );
-               free((void *) script);
-
-               if (retcode == JIM_ERR)
-               {
-                       printf("Tcl failed\n");
-                       const char *t = httpd_exec_cgi_tcl_error(interp);
-                       if (t == NULL)
-                               return MHD_NO;
-
-                       response = MHD_create_response_from_data(strlen(t), (void *) t,
-                                       MHD_YES, MHD_NO);
-                       ret = MHD_queue_response(connection,
-                                       MHD_HTTP_INTERNAL_SERVER_ERROR, response);
-                       MHD_destroy_response(response);
-                       return ret;
-               }
-               else
-               {
-                       printf("Tcl OK\n");
-                       /* FIX!!! how to handle mime types??? */
-                       const char *result;
-                       int reslen;
-                       result = Jim_GetString(Jim_GetResult(interp), &reslen);
-
-                       response = MHD_create_response_from_data(reslen, (void *) result,
-                                       MHD_NO, MHD_YES);
-                       ret = MHD_queue_response(connection,
-                                       MHD_HTTP_INTERNAL_SERVER_ERROR, response);
-                       MHD_destroy_response(response);
-                       return ret;
-               }
+               url++; /* skip '/' */
        }
-       else
-       {
-               void *data;
-               int len;
+       if (!*url)
+               url="index.tcl";
 
-               int retval = loadFile(url, &data, &len);
-               if (retval != ERROR_OK)
-               {
-                       printf("Did not find %s\n", url);
-
-                       response = MHD_create_response_from_data(strlen(PAGE_NOT_FOUND),
-                                       (void *) PAGE_NOT_FOUND, MHD_NO, MHD_NO);
-                       ret = MHD_queue_response(connection, MHD_HTTP_NOT_FOUND, response);
-                       MHD_destroy_response(response);
-                       return ret;
-               }
-
-               printf("Serving %s length=%d\n", url, len);
-               /* serve file directly */
-               response = MHD_create_response_from_data(len, data, MHD_YES, MHD_NO);
-               MHD_add_response_header(response, "Content-Type", "image/png");
-
-               ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
-               MHD_destroy_response(response);
-
-               //free(data);
-               return ret;
-       }
+       const char *file_name=alloc_printf("%s/%s", httpd_dir, url);
+       int result = handle_request(connection, file_name);
+       free((void *)file_name);
+       return result;
 }
 
 static struct MHD_Daemon * d;
+static pthread_mutex_t mutex;
+
 
 int httpd_start(void)
 {
+       pthread_mutexattr_t attr;
+       pthread_mutexattr_init( &attr );
+       pthread_mutex_init( &mutex, &attr );
 
        int port = 8888;
        LOG_USER("Launching httpd server on port %d", port);
@@ -445,13 +446,16 @@ int httpd_start(void)
 void httpd_stop(void)
 {
        MHD_stop_daemon(d);
+       pthread_mutex_destroy( &mutex );
 }
 
 void openocd_sleep_prelude(void)
 {
+       pthread_mutex_unlock( &mutex );
 }
 
 void openocd_sleep_postlude(void)
 {
+       pthread_mutex_lock( &mutex );
 }