You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2018/07/03 20:45:55 UTC

[3/6] celix git commit: CELIX-451: Adds celix_bundle_dir for copying files. Also remove mongoose example and adds a new civetweb example.

http://git-wip-us.apache.org/repos/asf/celix/blob/c4de9077/examples/celix-examples/civetweb/civetweb/md5.inl
----------------------------------------------------------------------
diff --git a/examples/celix-examples/civetweb/civetweb/md5.inl b/examples/celix-examples/civetweb/civetweb/md5.inl
new file mode 100644
index 0000000..beb1cf9
--- /dev/null
+++ b/examples/celix-examples/civetweb/civetweb/md5.inl
@@ -0,0 +1,471 @@
+/*
+ * This an amalgamation of md5.c and md5.h into a single file
+ * with all static declaration to reduce linker conflicts
+ * in Civetweb.
+ *
+ * The MD5_STATIC declaration was added to facilitate static
+ * inclusion.
+ * No Face Press, LLC
+ */
+
+/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+    http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.h is L. Peter Deutsch
+  <gh...@aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Removed support for non-ANSI compilers; removed
+    references to Ghostscript; clarified derivation from RFC 1321;
+    now handles byte order either statically or dynamically.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+    added conditionalization for C++ compilation from Martin
+    Purschke <pu...@bnl.gov>.
+  1999-05-03 lpd Original version.
+ */
+
+#if !defined(md5_INCLUDED)
+#define md5_INCLUDED
+
+/*
+ * This package supports both compile-time and run-time determination of CPU
+ * byte order.  If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
+ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
+ * defined as non-zero, the code will be compiled to run only on big-endian
+ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
+ * run on either big- or little-endian CPUs, but will run slightly less
+ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
+ */
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t;  /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+	md5_word_t count[2]; /* message length in bits, lsw first */
+	md5_word_t abcd[4];  /* digest buffer */
+	md5_byte_t buf[64];  /* accumulate block */
+} md5_state_t;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Initialize the algorithm. */
+MD5_STATIC void md5_init(md5_state_t *pms);
+
+/* Append a string to the message. */
+MD5_STATIC void
+md5_append(md5_state_t *pms, const md5_byte_t *data, size_t nbytes);
+
+/* Finish the message and return the digest. */
+MD5_STATIC void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+
+#if defined(__cplusplus)
+} /* end extern "C" */
+#endif
+
+#endif /* md5_INCLUDED */
+
+/*
+  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost@aladdin.com
+
+ */
+/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+    http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.c is L. Peter Deutsch
+  <gh...@aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
+    either statically or dynamically; added missing #include <string.h>
+    in library.
+  2002-03-11 lpd Corrected argument list for main(), and added int return
+    type, in test program and T value program.
+  2002-02-21 lpd Added missing #include <stdio.h> in test program.
+  2000-07-03 lpd Patched to eliminate warnings about "constant is
+    unsigned in ANSI C, signed in traditional"; made test program
+    self-checking.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+  1999-05-03 lpd Original version.
+ */
+
+#if !defined(MD5_STATIC)
+#include <string.h>
+#endif
+
+#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
+#if defined(ARCH_IS_BIG_ENDIAN)
+#define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
+#else
+#define BYTE_ORDER (0)
+#endif
+
+#define T_MASK ((md5_word_t)~0)
+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
+#define T3 (0x242070db)
+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
+#define T6 (0x4787c62a)
+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
+#define T9 (0x698098d8)
+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
+#define T13 (0x6b901122)
+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
+#define T16 (0x49b40821)
+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
+#define T19 (0x265e5a51)
+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
+#define T22 (0x02441453)
+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
+#define T25 (0x21e1cde6)
+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
+#define T28 (0x455a14ed)
+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
+#define T31 (0x676f02d9)
+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
+#define T35 (0x6d9d6122)
+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
+#define T38 (0x4bdecfa9)
+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
+#define T41 (0x289b7ec6)
+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
+#define T44 (0x04881d05)
+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
+#define T47 (0x1fa27cf8)
+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
+#define T50 (0x432aff97)
+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
+#define T53 (0x655b59c3)
+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
+#define T57 (0x6fa87e4f)
+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
+#define T60 (0x4e0811a1)
+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
+#define T63 (0x2ad7d2bb)
+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+	md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2],
+	           d = pms->abcd[3];
+	md5_word_t t;
+#if BYTE_ORDER > 0
+	/* Define storage only for big-endian CPUs. */
+	md5_word_t X[16];
+#else
+	/* Define storage for little-endian or both types of CPUs. */
+	md5_word_t xbuf[16];
+	const md5_word_t *X;
+#endif
+
+	{
+#if BYTE_ORDER == 0
+		/*
+		 * Determine dynamically whether this is a big-endian or
+		 * little-endian machine, since we can use a more efficient
+		 * algorithm on the latter.
+		 */
+		static const int w = 1;
+
+		if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
+#endif
+#if BYTE_ORDER <= 0 /* little-endian */
+		{
+			/*
+			 * On little-endian machines, we can process properly aligned
+			 * data without copying it.
+			 */
+			if (!((data - (const md5_byte_t *)0) & 3)) {
+				/* data are properly aligned, a direct assignment is possible */
+				/* cast through a (void *) should avoid a compiler warning,
+				   see
+				   https://github.com/bel2125/civetweb/issues/94#issuecomment-98112861
+				   */
+				X = (const md5_word_t *)(const void *)data;
+			} else {
+				/* not aligned */
+				memcpy(xbuf, data, 64);
+				X = xbuf;
+			}
+		}
+#endif
+#if BYTE_ORDER == 0
+		else /* dynamic big-endian */
+#endif
+#if BYTE_ORDER >= 0 /* big-endian */
+		{
+			/*
+			 * On big-endian machines, we must arrange the bytes in the
+			 * right order.
+			 */
+			const md5_byte_t *xp = data;
+			int i;
+
+#if BYTE_ORDER == 0
+			X = xbuf; /* (dynamic only) */
+#else
+#define xbuf X /* (static only) */
+#endif
+			for (i = 0; i < 16; ++i, xp += 4)
+				xbuf[i] = (md5_word_t)(xp[0]) + (md5_word_t)(xp[1] << 8)
+				          + (md5_word_t)(xp[2] << 16)
+				          + (md5_word_t)(xp[3] << 24);
+		}
+#endif
+	}
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+/* Round 1. */
+/* Let [abcd k s i] denote the operation
+   a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)                                              \
+	t = a + F(b, c, d) + X[k] + Ti;                                            \
+	a = ROTATE_LEFT(t, s) + b
+
+	/* Do the following 16 operations. */
+	SET(a, b, c, d, 0, 7, T1);
+	SET(d, a, b, c, 1, 12, T2);
+	SET(c, d, a, b, 2, 17, T3);
+	SET(b, c, d, a, 3, 22, T4);
+	SET(a, b, c, d, 4, 7, T5);
+	SET(d, a, b, c, 5, 12, T6);
+	SET(c, d, a, b, 6, 17, T7);
+	SET(b, c, d, a, 7, 22, T8);
+	SET(a, b, c, d, 8, 7, T9);
+	SET(d, a, b, c, 9, 12, T10);
+	SET(c, d, a, b, 10, 17, T11);
+	SET(b, c, d, a, 11, 22, T12);
+	SET(a, b, c, d, 12, 7, T13);
+	SET(d, a, b, c, 13, 12, T14);
+	SET(c, d, a, b, 14, 17, T15);
+	SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+/* Round 2. */
+/* Let [abcd k s i] denote the operation
+     a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)                                              \
+	t = a + G(b, c, d) + X[k] + Ti;                                            \
+	a = ROTATE_LEFT(t, s) + b
+
+	/* Do the following 16 operations. */
+	SET(a, b, c, d, 1, 5, T17);
+	SET(d, a, b, c, 6, 9, T18);
+	SET(c, d, a, b, 11, 14, T19);
+	SET(b, c, d, a, 0, 20, T20);
+	SET(a, b, c, d, 5, 5, T21);
+	SET(d, a, b, c, 10, 9, T22);
+	SET(c, d, a, b, 15, 14, T23);
+	SET(b, c, d, a, 4, 20, T24);
+	SET(a, b, c, d, 9, 5, T25);
+	SET(d, a, b, c, 14, 9, T26);
+	SET(c, d, a, b, 3, 14, T27);
+	SET(b, c, d, a, 8, 20, T28);
+	SET(a, b, c, d, 13, 5, T29);
+	SET(d, a, b, c, 2, 9, T30);
+	SET(c, d, a, b, 7, 14, T31);
+	SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+/* Round 3. */
+/* Let [abcd k s t] denote the operation
+     a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)                                              \
+	t = a + H(b, c, d) + X[k] + Ti;                                            \
+	a = ROTATE_LEFT(t, s) + b
+
+	/* Do the following 16 operations. */
+	SET(a, b, c, d, 5, 4, T33);
+	SET(d, a, b, c, 8, 11, T34);
+	SET(c, d, a, b, 11, 16, T35);
+	SET(b, c, d, a, 14, 23, T36);
+	SET(a, b, c, d, 1, 4, T37);
+	SET(d, a, b, c, 4, 11, T38);
+	SET(c, d, a, b, 7, 16, T39);
+	SET(b, c, d, a, 10, 23, T40);
+	SET(a, b, c, d, 13, 4, T41);
+	SET(d, a, b, c, 0, 11, T42);
+	SET(c, d, a, b, 3, 16, T43);
+	SET(b, c, d, a, 6, 23, T44);
+	SET(a, b, c, d, 9, 4, T45);
+	SET(d, a, b, c, 12, 11, T46);
+	SET(c, d, a, b, 15, 16, T47);
+	SET(b, c, d, a, 2, 23, T48);
+#undef SET
+
+/* Round 4. */
+/* Let [abcd k s t] denote the operation
+     a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)                                              \
+	t = a + I(b, c, d) + X[k] + Ti;                                            \
+	a = ROTATE_LEFT(t, s) + b
+
+	/* Do the following 16 operations. */
+	SET(a, b, c, d, 0, 6, T49);
+	SET(d, a, b, c, 7, 10, T50);
+	SET(c, d, a, b, 14, 15, T51);
+	SET(b, c, d, a, 5, 21, T52);
+	SET(a, b, c, d, 12, 6, T53);
+	SET(d, a, b, c, 3, 10, T54);
+	SET(c, d, a, b, 10, 15, T55);
+	SET(b, c, d, a, 1, 21, T56);
+	SET(a, b, c, d, 8, 6, T57);
+	SET(d, a, b, c, 15, 10, T58);
+	SET(c, d, a, b, 6, 15, T59);
+	SET(b, c, d, a, 13, 21, T60);
+	SET(a, b, c, d, 4, 6, T61);
+	SET(d, a, b, c, 11, 10, T62);
+	SET(c, d, a, b, 2, 15, T63);
+	SET(b, c, d, a, 9, 21, T64);
+#undef SET
+
+	/* Then perform the following additions. (That is increment each
+	   of the four registers by the value it had before this block
+	   was started.) */
+	pms->abcd[0] += a;
+	pms->abcd[1] += b;
+	pms->abcd[2] += c;
+	pms->abcd[3] += d;
+}
+
+MD5_STATIC void
+md5_init(md5_state_t *pms)
+{
+	pms->count[0] = pms->count[1] = 0;
+	pms->abcd[0] = 0x67452301;
+	pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+	pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+	pms->abcd[3] = 0x10325476;
+}
+
+MD5_STATIC void
+md5_append(md5_state_t *pms, const md5_byte_t *data, size_t nbytes)
+{
+	const md5_byte_t *p = data;
+	size_t left = nbytes;
+	size_t offset = (pms->count[0] >> 3) & 63;
+	md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+	if (nbytes <= 0)
+		return;
+
+	/* Update the message length. */
+	pms->count[1] += (md5_word_t)(nbytes >> 29);
+	pms->count[0] += nbits;
+	if (pms->count[0] < nbits)
+		pms->count[1]++;
+
+	/* Process an initial partial block. */
+	if (offset) {
+		size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+		memcpy(pms->buf + offset, p, copy);
+		if (offset + copy < 64)
+			return;
+		p += copy;
+		left -= copy;
+		md5_process(pms, pms->buf);
+	}
+
+	/* Process full blocks. */
+	for (; left >= 64; p += 64, left -= 64)
+		md5_process(pms, p);
+
+	/* Process a final partial block. */
+	if (left)
+		memcpy(pms->buf, p, left);
+}
+
+MD5_STATIC void
+md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+	static const md5_byte_t pad[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	                                   0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	                                   0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	                                   0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	                                   0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+	md5_byte_t data[8];
+	int i;
+
+	/* Save the length before padding. */
+	for (i = 0; i < 8; ++i)
+		data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+	/* Pad to 56 bytes mod 64. */
+	md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+	/* Append the length. */
+	md5_append(pms, data, 8);
+	for (i = 0; i < 16; ++i)
+		digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}
+
+
+/* End of md5.inl */

http://git-wip-us.apache.org/repos/asf/celix/blob/c4de9077/examples/celix-examples/civetweb/civetweb/sha1.inl
----------------------------------------------------------------------
diff --git a/examples/celix-examples/civetweb/civetweb/sha1.inl b/examples/celix-examples/civetweb/civetweb/sha1.inl
new file mode 100644
index 0000000..0a2ae46
--- /dev/null
+++ b/examples/celix-examples/civetweb/civetweb/sha1.inl
@@ -0,0 +1,323 @@
+/*
+SHA-1 in C
+By Steve Reid <sr...@sea-to-sky.net>
+100% Public Domain
+
+-----------------
+Modified 7/98
+By James H. Brown <jb...@burgoyne.com>
+Still 100% Public Domain
+
+Corrected a problem which generated improper hash values on 16 bit machines
+Routine SHA1Update changed from
+    void SHA1Update(SHA_CTX* context, unsigned char* data, unsigned int
+len)
+to
+    void SHA1Update(SHA_CTX* context, unsigned char* data, unsigned
+long len)
+
+The 'len' parameter was declared an int which works fine on 32 bit machines.
+However, on 16 bit machines an int is too small for the shifts being done
+against
+it.  This caused the hash function to generate incorrect values if len was
+greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
+
+Since the file IO in main() reads 16K at a time, any file 8K or larger would
+be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
+"a"s).
+
+I also changed the declaration of variables i & j in SHA1Update to
+unsigned long from unsigned int for the same reason.
+
+These changes should make no difference to any 32 bit implementations since
+an
+int and a long are the same size in those environments.
+
+--
+I also corrected a few compiler warnings generated by Borland C.
+1. Added #include <process.h> for exit() prototype
+2. Removed unused variable 'j' in SHA1Final
+3. Changed exit(0) to return(0) at end of main.
+
+ALL changes I made can be located by searching for comments containing 'JHB'
+-----------------
+Modified 8/98
+By Steve Reid <sr...@sea-to-sky.net>
+Still 100% public domain
+
+1- Removed #include <process.h> and used return() instead of exit()
+2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
+3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
+
+-----------------
+Modified 4/01
+By Saul Kravitz <Sa...@celera.com>
+Still 100% PD
+Modified to run on Compaq Alpha hardware.
+
+-----------------
+Modified 07/2002
+By Ralph Giles <gi...@ghostscript.com>
+Still 100% public domain
+modified for use with stdint types, autoconf
+code cleanup, removed attribution comments
+switched SHA1Final() argument order for consistency
+use SHA1_ prefix for public api
+move public api to sha1.h
+*/
+
+/*
+11/2016 adapted for CivetWeb:
+  include sha1.h in sha1.c,
+  rename to sha1.inl
+  remove unused #ifdef sections
+  make endian independent
+  align buffer to 4 bytes
+  remove unused variable assignments
+*/
+
+/*
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+#include <string.h>
+#include <stdint.h>
+
+typedef struct {
+	uint32_t state[5];
+	uint32_t count[2];
+	uint8_t buffer[64];
+} SHA_CTX;
+
+#define SHA1_DIGEST_SIZE 20
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+
+
+typedef union {
+	uint8_t c[64];
+	uint32_t l[16];
+} CHAR64LONG16;
+
+
+static uint32_t
+blk0(CHAR64LONG16 *block, int i)
+{
+	static const uint32_t n = 1u;
+	if ((*((uint8_t *)(&n))) == 1) {
+		/* little endian / intel byte order */
+		block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00)
+		              | (rol(block->l[i], 8) & 0x00FF00FF);
+	}
+	return block->l[i];
+}
+
+#define blk(block, i)                                                          \
+	((block)->l[(i)&15] =                                                      \
+	     rol((block)->l[((i) + 13) & 15] ^ (block)->l[((i) + 8) & 15]          \
+	             ^ (block)->l[((i) + 2) & 15] ^ (block)->l[(i)&15],            \
+	         1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v, w, x, y, z, i)                                                   \
+	z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5);        \
+	w = rol(w, 30);
+#define R1(v, w, x, y, z, i)                                                   \
+	z += ((w & (x ^ y)) ^ y) + blk(block, i) + 0x5A827999 + rol(v, 5);         \
+	w = rol(w, 30);
+#define R2(v, w, x, y, z, i)                                                   \
+	z += (w ^ x ^ y) + blk(block, i) + 0x6ED9EBA1 + rol(v, 5);                 \
+	w = rol(w, 30);
+#define R3(v, w, x, y, z, i)                                                   \
+	z += (((w | x) & y) | (w & x)) + blk(block, i) + 0x8F1BBCDC + rol(v, 5);   \
+	w = rol(w, 30);
+#define R4(v, w, x, y, z, i)                                                   \
+	z += (w ^ x ^ y) + blk(block, i) + 0xCA62C1D6 + rol(v, 5);                 \
+	w = rol(w, 30);
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+static void
+SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
+{
+	uint32_t a, b, c, d, e;
+
+	/* Must use an aligned, read/write buffer */
+	CHAR64LONG16 block[1];
+	memcpy(block, buffer, sizeof(block));
+
+	/* Copy context->state[] to working vars */
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+	e = state[4];
+
+	/* 4 rounds of 20 operations each. Loop unrolled. */
+	R0(a, b, c, d, e, 0);
+	R0(e, a, b, c, d, 1);
+	R0(d, e, a, b, c, 2);
+	R0(c, d, e, a, b, 3);
+	R0(b, c, d, e, a, 4);
+	R0(a, b, c, d, e, 5);
+	R0(e, a, b, c, d, 6);
+	R0(d, e, a, b, c, 7);
+	R0(c, d, e, a, b, 8);
+	R0(b, c, d, e, a, 9);
+	R0(a, b, c, d, e, 10);
+	R0(e, a, b, c, d, 11);
+	R0(d, e, a, b, c, 12);
+	R0(c, d, e, a, b, 13);
+	R0(b, c, d, e, a, 14);
+	R0(a, b, c, d, e, 15);
+	R1(e, a, b, c, d, 16);
+	R1(d, e, a, b, c, 17);
+	R1(c, d, e, a, b, 18);
+	R1(b, c, d, e, a, 19);
+	R2(a, b, c, d, e, 20);
+	R2(e, a, b, c, d, 21);
+	R2(d, e, a, b, c, 22);
+	R2(c, d, e, a, b, 23);
+	R2(b, c, d, e, a, 24);
+	R2(a, b, c, d, e, 25);
+	R2(e, a, b, c, d, 26);
+	R2(d, e, a, b, c, 27);
+	R2(c, d, e, a, b, 28);
+	R2(b, c, d, e, a, 29);
+	R2(a, b, c, d, e, 30);
+	R2(e, a, b, c, d, 31);
+	R2(d, e, a, b, c, 32);
+	R2(c, d, e, a, b, 33);
+	R2(b, c, d, e, a, 34);
+	R2(a, b, c, d, e, 35);
+	R2(e, a, b, c, d, 36);
+	R2(d, e, a, b, c, 37);
+	R2(c, d, e, a, b, 38);
+	R2(b, c, d, e, a, 39);
+	R3(a, b, c, d, e, 40);
+	R3(e, a, b, c, d, 41);
+	R3(d, e, a, b, c, 42);
+	R3(c, d, e, a, b, 43);
+	R3(b, c, d, e, a, 44);
+	R3(a, b, c, d, e, 45);
+	R3(e, a, b, c, d, 46);
+	R3(d, e, a, b, c, 47);
+	R3(c, d, e, a, b, 48);
+	R3(b, c, d, e, a, 49);
+	R3(a, b, c, d, e, 50);
+	R3(e, a, b, c, d, 51);
+	R3(d, e, a, b, c, 52);
+	R3(c, d, e, a, b, 53);
+	R3(b, c, d, e, a, 54);
+	R3(a, b, c, d, e, 55);
+	R3(e, a, b, c, d, 56);
+	R3(d, e, a, b, c, 57);
+	R3(c, d, e, a, b, 58);
+	R3(b, c, d, e, a, 59);
+	R4(a, b, c, d, e, 60);
+	R4(e, a, b, c, d, 61);
+	R4(d, e, a, b, c, 62);
+	R4(c, d, e, a, b, 63);
+	R4(b, c, d, e, a, 64);
+	R4(a, b, c, d, e, 65);
+	R4(e, a, b, c, d, 66);
+	R4(d, e, a, b, c, 67);
+	R4(c, d, e, a, b, 68);
+	R4(b, c, d, e, a, 69);
+	R4(a, b, c, d, e, 70);
+	R4(e, a, b, c, d, 71);
+	R4(d, e, a, b, c, 72);
+	R4(c, d, e, a, b, 73);
+	R4(b, c, d, e, a, 74);
+	R4(a, b, c, d, e, 75);
+	R4(e, a, b, c, d, 76);
+	R4(d, e, a, b, c, 77);
+	R4(c, d, e, a, b, 78);
+	R4(b, c, d, e, a, 79);
+
+	/* Add the working vars back into context.state[] */
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+	state[4] += e;
+}
+
+
+/* SHA1Init - Initialize new context */
+SHA_API void
+SHA1_Init(SHA_CTX *context)
+{
+	/* SHA1 initialization constants */
+	context->state[0] = 0x67452301;
+	context->state[1] = 0xEFCDAB89;
+	context->state[2] = 0x98BADCFE;
+	context->state[3] = 0x10325476;
+	context->state[4] = 0xC3D2E1F0;
+	context->count[0] = context->count[1] = 0;
+}
+
+
+SHA_API void
+SHA1_Update(SHA_CTX *context, const uint8_t *data, const uint32_t len)
+{
+	uint32_t i, j;
+
+	j = context->count[0];
+	if ((context->count[0] += (len << 3)) < j) {
+		context->count[1]++;
+	}
+	context->count[1] += (len >> 29);
+	j = (j >> 3) & 63;
+	if ((j + len) > 63) {
+		i = 64 - j;
+		memcpy(&context->buffer[j], data, i);
+		SHA1_Transform(context->state, context->buffer);
+		for (; i + 63 < len; i += 64) {
+			SHA1_Transform(context->state, &data[i]);
+		}
+		j = 0;
+	} else {
+		i = 0;
+	}
+	memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+SHA_API void
+SHA1_Final(unsigned char *digest, SHA_CTX *context)
+{
+	uint32_t i;
+	uint8_t finalcount[8];
+
+	for (i = 0; i < 8; i++) {
+		finalcount[i] =
+		    (uint8_t)((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8))
+		              & 255); /* Endian independent */
+	}
+	SHA1_Update(context, (uint8_t *)"\x80", 1);
+	while ((context->count[0] & 504) != 448) {
+		SHA1_Update(context, (uint8_t *)"\x00", 1);
+	}
+	SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */
+	for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
+		digest[i] =
+		    (uint8_t)((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
+	}
+
+	/* Wipe variables */
+	memset(context, '\0', sizeof(*context));
+}
+
+
+/* End of sha1.inl */

http://git-wip-us.apache.org/repos/asf/celix/blob/c4de9077/examples/celix-examples/civetweb/civetweb/timer.inl
----------------------------------------------------------------------
diff --git a/examples/celix-examples/civetweb/civetweb/timer.inl b/examples/celix-examples/civetweb/civetweb/timer.inl
new file mode 100644
index 0000000..eebbec0
--- /dev/null
+++ b/examples/celix-examples/civetweb/civetweb/timer.inl
@@ -0,0 +1,246 @@
+/* This file is part of the CivetWeb web server.
+ * See https://github.com/civetweb/civetweb/
+ * (C) 2014-2018 by the CivetWeb authors, MIT license.
+ */
+
+#if !defined(MAX_TIMERS)
+#define MAX_TIMERS MAX_WORKER_THREADS
+#endif
+
+typedef int (*taction)(void *arg);
+
+struct ttimer {
+	double time;
+	double period;
+	taction action;
+	void *arg;
+};
+
+struct ttimers {
+	pthread_t threadid;               /* Timer thread ID */
+	pthread_mutex_t mutex;            /* Protects timer lists */
+	struct ttimer timers[MAX_TIMERS]; /* List of timers */
+	unsigned timer_count;             /* Current size of timer list */
+};
+
+
+TIMER_API double
+timer_getcurrenttime(void)
+{
+#if defined(_WIN32)
+	/* GetTickCount returns milliseconds since system start as
+	 * unsigned 32 bit value. It will wrap around every 49.7 days.
+	 * We need to use a 64 bit counter (will wrap in 500 mio. years),
+	 * by adding the 32 bit difference since the last call to a
+	 * 64 bit counter. This algorithm will only work, if this
+	 * function is called at least once every 7 weeks. */
+	static DWORD last_tick;
+	static uint64_t now_tick64;
+
+	DWORD now_tick = GetTickCount();
+
+	now_tick64 += ((DWORD)(now_tick - last_tick));
+	last_tick = now_tick;
+	return (double)now_tick64 * 1.0E-3;
+#else
+	struct timespec now_ts;
+
+	clock_gettime(CLOCK_MONOTONIC, &now_ts);
+	return (double)now_ts.tv_sec + (double)now_ts.tv_nsec * 1.0E-9;
+#endif
+}
+
+
+TIMER_API int
+timer_add(struct mg_context *ctx,
+          double next_time,
+          double period,
+          int is_relative,
+          taction action,
+          void *arg)
+{
+	unsigned u, v;
+	int error = 0;
+	double now;
+
+	if (ctx->stop_flag) {
+		return 0;
+	}
+
+	now = timer_getcurrenttime();
+
+	/* HCP24: if is_relative = 0 and next_time < now
+	 *        action will be called so fast as possible
+	 *        if additional period > 0
+	 *        action will be called so fast as possible
+	 *        n times until (next_time + (n * period)) > now
+	 *        then the period is working
+	 * Solution:
+	 *        if next_time < now then we set next_time = now.
+	 *        The first callback will be so fast as possible (now)
+	 *        but the next callback on period
+	*/
+	if (is_relative) {
+		next_time += now;
+	}
+
+	/* You can not set timers into the past */
+	if (next_time < now) {
+		next_time = now;
+	}
+
+	pthread_mutex_lock(&ctx->timers->mutex);
+	if (ctx->timers->timer_count == MAX_TIMERS) {
+		error = 1;
+	} else {
+		/* Insert new timer into a sorted list. */
+		/* The linear list is still most efficient for short lists (small
+		 * number of timers) - if there are many timers, different
+		 * algorithms will work better. */
+		for (u = 0; u < ctx->timers->timer_count; u++) {
+			if (ctx->timers->timers[u].time > next_time) {
+				/* HCP24: moving all timers > next_time */
+				for (v = ctx->timers->timer_count; v > u; v--) {
+					ctx->timers->timers[v] = ctx->timers->timers[v - 1];
+				}
+				break;
+			}
+		}
+		ctx->timers->timers[u].time = next_time;
+		ctx->timers->timers[u].period = period;
+		ctx->timers->timers[u].action = action;
+		ctx->timers->timers[u].arg = arg;
+		ctx->timers->timer_count++;
+	}
+	pthread_mutex_unlock(&ctx->timers->mutex);
+	return error;
+}
+
+
+static void
+timer_thread_run(void *thread_func_param)
+{
+	struct mg_context *ctx = (struct mg_context *)thread_func_param;
+	double d;
+	unsigned u;
+	int re_schedule;
+	struct ttimer t;
+
+	mg_set_thread_name("timer");
+
+	if (ctx->callbacks.init_thread) {
+		/* Timer thread */
+		ctx->callbacks.init_thread(ctx, 2);
+	}
+
+	d = timer_getcurrenttime();
+
+	while (ctx->stop_flag == 0) {
+		pthread_mutex_lock(&ctx->timers->mutex);
+		if ((ctx->timers->timer_count > 0)
+		    && (d >= ctx->timers->timers[0].time)) {
+			t = ctx->timers->timers[0];
+			for (u = 1; u < ctx->timers->timer_count; u++) {
+				ctx->timers->timers[u - 1] = ctx->timers->timers[u];
+			}
+			ctx->timers->timer_count--;
+			pthread_mutex_unlock(&ctx->timers->mutex);
+			re_schedule = t.action(t.arg);
+			if (re_schedule && (t.period > 0)) {
+				timer_add(ctx, t.time + t.period, t.period, 0, t.action, t.arg);
+			}
+			continue;
+		} else {
+			pthread_mutex_unlock(&ctx->timers->mutex);
+		}
+
+/* 10 ms seems reasonable.
+ * A faster loop (smaller sleep value) increases CPU load,
+ * a slower loop (higher sleep value) decreases timer accuracy.
+ */
+#if defined(_WIN32)
+		Sleep(10);
+#else
+		usleep(10000);
+#endif
+
+		d = timer_getcurrenttime();
+	}
+
+	pthread_mutex_lock(&ctx->timers->mutex);
+	ctx->timers->timer_count = 0;
+	pthread_mutex_unlock(&ctx->timers->mutex);
+}
+
+
+#if defined(_WIN32)
+static unsigned __stdcall timer_thread(void *thread_func_param)
+{
+	timer_thread_run(thread_func_param);
+	return 0;
+}
+#else
+static void *
+timer_thread(void *thread_func_param)
+{
+	struct sigaction sa;
+
+	/* Ignore SIGPIPE */
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_handler = SIG_IGN;
+	sigaction(SIGPIPE, &sa, NULL);
+
+	timer_thread_run(thread_func_param);
+	return NULL;
+}
+#endif /* _WIN32 */
+
+
+TIMER_API int
+timers_init(struct mg_context *ctx)
+{
+	/* Initialize timers data structure */
+	ctx->timers =
+	    (struct ttimers *)mg_calloc_ctx(sizeof(struct ttimers), 1, ctx);
+
+	if (!ctx->timers) {
+		return -1;
+	}
+
+	/* Initialize mutex */
+	if (0 != pthread_mutex_init(&ctx->timers->mutex, NULL)) {
+		mg_free((void *)(ctx->timers));
+		return -1;
+	}
+
+	/* For some systems timer_getcurrenttime does some initialization
+	 * during the first call. Call it once now, ignore the result. */
+	(void)timer_getcurrenttime();
+
+	/* Start timer thread */
+	mg_start_thread_with_id(timer_thread, ctx, &ctx->timers->threadid);
+
+	return 0;
+}
+
+
+TIMER_API void
+timers_exit(struct mg_context *ctx)
+{
+	if (ctx->timers) {
+		pthread_mutex_lock(&ctx->timers->mutex);
+		ctx->timers->timer_count = 0;
+
+		mg_join_thread(ctx->timers->threadid);
+
+		/* TODO: Do we really need to unlock the mutex, before
+		 * destroying it, if it's destroyed by the thread currently
+		 * owning the mutex? */
+		pthread_mutex_unlock(&ctx->timers->mutex);
+		(void)pthread_mutex_destroy(&ctx->timers->mutex);
+		mg_free(ctx->timers);
+	}
+}
+
+
+/* End of timer.inl */

http://git-wip-us.apache.org/repos/asf/celix/blob/c4de9077/examples/celix-examples/civetweb/resources/index.html
----------------------------------------------------------------------
diff --git a/examples/celix-examples/civetweb/resources/index.html b/examples/celix-examples/civetweb/resources/index.html
new file mode 100644
index 0000000..ab46896
--- /dev/null
+++ b/examples/celix-examples/civetweb/resources/index.html
@@ -0,0 +1,34 @@
+<!--
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+-->
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8"/>
+    <title>Apache Celix Embedded Civetweb example</title>
+    <script src="script.js"></script>
+</head>
+<body>
+    <div>
+        <input type="text" id="command_input"/>
+        <input type="button" id="command_button" value="send"/>
+    </div>
+    <textarea rows="50" cols="80" id="console_output"></textarea>
+    <script>docReady();</script>
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/c4de9077/examples/celix-examples/civetweb/resources/script.js
----------------------------------------------------------------------
diff --git a/examples/celix-examples/civetweb/resources/script.js b/examples/celix-examples/civetweb/resources/script.js
new file mode 100644
index 0000000..588fbf6
--- /dev/null
+++ b/examples/celix-examples/civetweb/resources/script.js
@@ -0,0 +1,43 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+function docReady() {
+    var host = window.location.host;
+    var shellSocket = new WebSocket("ws://" + host + "/shellsocket");
+
+    shellSocket.onmessage = function (event) {
+        document.getElementById("console_output").value = event.data;
+    };
+    shellSocket.onopen = function (event) {
+        shellSocket.send("lb");
+    };
+
+    document.getElementById("command_button").onclick = function() {
+        input = document.getElementById("command_input").value;
+        shellSocket.send(input);
+    };
+
+    var input = document.getElementById("command_input");
+    input.addEventListener("keyup", function(event) {
+        event.preventDefault();
+        if (event.key === "Enter") {
+            document.getElementById("command_button").click();
+        }
+    });
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/c4de9077/examples/celix-examples/civetweb/src/bundle_activator.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/civetweb/src/bundle_activator.c b/examples/celix-examples/civetweb/src/bundle_activator.c
new file mode 100644
index 0000000..cae9616
--- /dev/null
+++ b/examples/celix-examples/civetweb/src/bundle_activator.c
@@ -0,0 +1,108 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+
+#include "celix_bundle_activator.h"
+#include "celix_bundle.h"
+#include "shell.h"
+
+#include <civetweb.h>
+#include <string.h>
+
+typedef struct activator_data {
+    celix_bundle_context_t *ctx;
+    char *root;
+    struct mg_context *mgCtx;
+} activator_data_t;
+
+struct use_shell_arg {
+    char *command;
+    struct mg_connection *conn;
+};
+
+static void useShell(void *handle, void *svc) {
+    shell_service_t *shell = svc;
+    struct use_shell_arg *arg = handle;
+    char *buf = NULL;
+    size_t size;
+    FILE *out = open_memstream(&buf, &size);
+    shell->executeCommand(shell->shell, (char*)arg->command, out, out);
+    fclose(out);
+    mg_websocket_write(arg->conn, MG_WEBSOCKET_OPCODE_TEXT, buf, size);
+};
+
+static int websocket_data_handler(struct mg_connection *conn, int bits, char *data, size_t data_len, void *handle) {
+    activator_data_t *act = handle;
+    struct use_shell_arg arg;
+    arg.conn = conn;
+
+    //NOTE data is a not null terminated string..
+    arg.command = calloc(data_len+1, sizeof(char));
+    memcpy(arg.command, data, data_len);
+    arg.command[data_len] = '\0';
+
+
+    bool called = celix_bundleContext_useService(act->ctx, OSGI_SHELL_SERVICE_NAME, &arg, useShell);
+    if (!called) {
+        fprintf(stderr, "No shell available!\n");
+    }
+
+    free(arg.command);
+    return 1; //keep open
+}
+
+
+static celix_status_t activator_start(activator_data_t *data, celix_bundle_context_t *ctx) {
+    data->ctx = ctx;
+
+    bundle_t *bnd = celix_bundleContext_getBundle(ctx);
+    data->root = celix_bundle_getEntry(bnd, "resources");
+
+    const char *options[] = {
+            "document_root", data->root,
+            "listening_ports", "8081",
+            "websocket_timeout_ms", "3600000",
+            NULL
+    };
+
+    if (data->root != NULL) {
+        data->mgCtx = mg_start(NULL, data, options);
+        mg_set_websocket_handler(data->mgCtx, "/shellsocket", NULL, NULL, websocket_data_handler, NULL, data);
+    }
+
+    if (data->mgCtx != NULL) {
+        fprintf(stdout, "Started civetweb at port %s\n", mg_get_option(data->mgCtx, "listening_ports"));
+    } else {
+        fprintf(stderr, "Error starting civetweb bundle\n");
+    }
+
+    return CELIX_SUCCESS;
+}
+
+static celix_status_t activator_stop(activator_data_t *data, celix_bundle_context_t *ctx) {
+    if (data->mgCtx != NULL) {
+        printf("Stopping civetweb\n");
+        mg_stop(data->mgCtx);
+        data->mgCtx = NULL;
+    }
+    free(data->root);
+    return CELIX_SUCCESS;
+}
+
+CELIX_GEN_BUNDLE_ACTIVATOR(activator_data_t, activator_start, activator_stop)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/c4de9077/examples/celix-examples/mongoose/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/mongoose/CMakeLists.txt b/examples/celix-examples/mongoose/CMakeLists.txt
deleted file mode 100644
index d0e94ae..0000000
--- a/examples/celix-examples/mongoose/CMakeLists.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-# 
-#   http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-add_library(mongooselib STATIC private/src/mongoose.c)
-SET_TARGET_PROPERTIES(mongooselib PROPERTIES COMPILE_FLAGS -fPIC)
-
-SET(BUNDLE_SYMBOLICNAME "apache_celix_examples_mongoose")
-SET(BUNDLE_VERSION "0.0.1")
-
-include_directories("private/include")
-include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
-
-if(WIN32)
-	  set(LIBS wsock32)
-endif(WIN32)
-
-add_celix_bundle(mongoose
-    VERSION 0.0.1
-    SOURCES
-        private/src/activator
-        private/include/mongoose.h
-)
-
-celix_bundle_files(mongoose ${CMAKE_CURRENT_LIST_DIR}/root)
-
-target_link_libraries(mongoose PRIVATE mongooselib ${LIBS})
-
-add_celix_container("mongoose_deploy" BUNDLES Celix::shell Celix::shell_tui Celix::log_service mongoose)

http://git-wip-us.apache.org/repos/asf/celix/blob/c4de9077/examples/celix-examples/mongoose/private/include/mongoose.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/mongoose/private/include/mongoose.h b/examples/celix-examples/mongoose/private/include/mongoose.h
deleted file mode 100644
index a846df4..0000000
--- a/examples/celix-examples/mongoose/private/include/mongoose.h
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright (c) 2004-2010 Sergey Lyubka
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#ifndef MONGOOSE_HEADER_INCLUDED
-#define  MONGOOSE_HEADER_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-struct mg_context;     // Handle for the HTTP service itself
-struct mg_connection;  // Handle for the individual connection
-
-
-// This structure contains information about the HTTP request.
-struct mg_request_info {
-  char *request_method;  // "GET", "POST", etc
-  char *uri;             // URL-decoded URI
-  char *http_version;    // E.g. "1.0", "1.1"
-  char *query_string;    // \0 - terminated
-  char *remote_user;     // Authenticated user
-  char *log_message;     // Mongoose error log message
-  long remote_ip;        // Client's IP address
-  int remote_port;       // Client's port
-  int status_code;       // HTTP reply status code
-  int is_ssl;            // 1 if SSL-ed, 0 if not
-  int num_headers;       // Number of headers
-  struct mg_header {
-    char *name;          // HTTP header name
-    char *value;         // HTTP header value
-  } http_headers[64];    // Maximum 64 headers
-};
-
-// Various events on which user-defined function is called by Mongoose.
-enum mg_event {
-  MG_NEW_REQUEST,   // New HTTP request has arrived from the client
-  MG_HTTP_ERROR,    // HTTP error must be returned to the client
-  MG_EVENT_LOG,     // Mongoose logs an event, request_info.log_message
-  MG_INIT_SSL,      // Mongoose initializes SSL. Instead of mg_connection *,
-                    // SSL context is passed to the callback function.
-};
-
-// Prototype for the user-defined function. Mongoose calls this function
-// on every event mentioned above.
-//
-// Parameters:
-//   event: which event has been triggered.
-//   conn: opaque connection handler. Could be used to read, write data to the
-//         client, etc. See functions below that accept "mg_connection *".
-//   request_info: Information about HTTP request.
-//
-// Return:
-//   If handler returns non-NULL, that means that handler has processed the
-//   request by sending appropriate HTTP reply to the client. Mongoose treats
-//   the request as served.
-//   If callback returns NULL, that means that callback has not processed
-//   the request. Handler must not send any data to the client in this case.
-//   Mongoose proceeds with request handling as if nothing happened.
-typedef void * (*mg_callback_pt)(enum mg_event event,
-                                struct mg_connection *conn,
-                                const struct mg_request_info *request_info);
-  
-
-// Start web server.
-//
-// Parameters:
-//   callback: user defined event handling function or NULL.
-//   options: NULL terminated list of option_name, option_value pairs that
-//            specify Mongoose configuration parameters.
-//
-// Example:
-//   const char *options[] = {
-//     "document_root", "/var/www",
-//     "listening_ports", "80,443s",
-//     NULL
-//   };
-//   struct mg_context *ctx = mg_start(&my_func, options);
-//
-// Please refer to http://code.google.com/p/mongoose/wiki/MongooseManual
-// for the list of valid option and their possible values.
-//
-// Return:
-//   web server context, or NULL on error.
-struct mg_context *mg_start(mg_callback_pt callback, const char **options);
-
-
-// Stop the web server.
-//
-// Must be called last, when an application wants to stop the web server and
-// release all associated resources. This function blocks until all Mongoose
-// threads are stopped. Context pointer becomes invalid.
-void mg_stop(struct mg_context *);
-
-
-// Get the value of particular configuration parameter.
-// The value returned is read-only. Mongoose does not allow changing
-// configuration at run time.
-// If given parameter name is not valid, NULL is returned. For valid
-// names, return value is guaranteed to be non-NULL. If parameter is not
-// set, zero-length string is returned.
-const char *mg_get_option(const struct mg_context *ctx, const char *name);
-
-
-// Return array of strings that represent valid configuration options.
-// For each option, a short name, long name, and default value is returned.
-// Array is NULL terminated.
-const char **mg_get_valid_option_names(void);
-
-
-// Add, edit or delete the entry in the passwords file.
-//
-// This function allows an application to manipulate .htpasswd files on the
-// fly by adding, deleting and changing user records. This is one of the
-// several ways of implementing authentication on the server side. For another,
-// cookie-based way please refer to the examples/chat.c in the source tree.
-//
-// If password is not NULL, entry is added (or modified if already exists).
-// If password is NULL, entry is deleted.
-//
-// Return:
-//   1 on success, 0 on error.
-int mg_modify_passwords_file(struct mg_context *ctx, 
-    const char *passwords_file_name, const char *user, const char *password);
-
-// Send data to the client.
-int mg_write(struct mg_connection *, const void *buf, size_t len);
-
-
-// Send data to the browser using printf() semantics.
-//
-// Works exactly like mg_write(), but allows to do message formatting.
-// Note that mg_printf() uses internal buffer of size IO_BUF_SIZE
-// (8 Kb by default) as temporary message storage for formatting. Do not
-// print data that is bigger than that, otherwise it will be truncated.
-int mg_printf(struct mg_connection *, const char *fmt, ...);
-
-
-// Read data from the remote end, return number of bytes read.
-int mg_read(struct mg_connection *, void *buf, size_t len);
-
-
-// Get the value of particular HTTP header.
-//
-// This is a helper function. It traverses request_info->http_headers array,
-// and if the header is present in the array, returns its value. If it is
-// not present, NULL is returned.
-const char *mg_get_header(const struct mg_connection *, const char *name);
-
-
-// Get a value of particular form variable.
-//
-// Parameters:
-//   data: pointer to form-uri-encoded buffer. This could be either POST data,
-//         or request_info.query_string.
-//   data_len: length of the encoded data.
-//   var_name: variable name to decode from the buffer
-//   buf: destination buffer for the decoded variable
-//   buf_len: length of the destination buffer
-//
-// Return:
-//   On success, length of the decoded variable.
-//   On error, -1 (variable not found, or destination buffer is too small).
-//
-// Destination buffer is guaranteed to be '\0' - terminated. In case of
-// failure, dst[0] == '\0'.
-int mg_get_var(const char *data, size_t data_len,
-    const char *var_name, char *buf, size_t buf_len);
-
-// Fetch value of certain cookie variable into the destination buffer.
-//
-// Destination buffer is guaranteed to be '\0' - terminated. In case of
-// failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
-// parameter. This function returns only first occurrence.
-//
-// Return:
-//   On success, value length.
-//   On error, -1 (either "Cookie:" header is not present at all, or the
-//   requested parameter is not found, or destination buffer is too small
-//   to hold the value).
-int mg_get_cookie(const struct mg_connection *,
-    const char *cookie_name, char *buf, size_t buf_len);
-
-
-// Return Mongoose version.
-const char *mg_version(void);
-
-
-// MD5 hash given strings.
-// Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
-// asciiz strings. When function returns, buf will contain human-readable
-// MD5 hash. Example:
-//   char buf[33];
-//   mg_md5(buf, "aa", "bb", NULL);
-void mg_md5(char *buf, ...);
-
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif // MONGOOSE_HEADER_INCLUDED

http://git-wip-us.apache.org/repos/asf/celix/blob/c4de9077/examples/celix-examples/mongoose/private/src/activator.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/mongoose/private/src/activator.c b/examples/celix-examples/mongoose/private/src/activator.c
deleted file mode 100644
index beea9df..0000000
--- a/examples/celix-examples/mongoose/private/src/activator.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * activator.c
- *
- *  \date       Aug 20, 2010
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "bundle_activator.h"
-#include "mongoose.h"
-
-struct userData {
-	struct mg_context *ctx;
-    char* entry;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt  __attribute__((unused)) context, void **userData) {
-	*userData = calloc(1, sizeof(struct userData));
-	return CELIX_SUCCESS;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
-	bundle_pt bundle;
-	celix_status_t status = CELIX_SUCCESS;
-	struct userData * data = (struct userData *) userData;
-
-	if (bundleContext_getBundle(context, &bundle) == CELIX_SUCCESS) {
-		bundle_getEntry(bundle, "root", &data->entry);
-		const char *options[] = {
-			"document_root", data->entry,
-			"listening_ports", "8081",
-			NULL
-		};
-
-		data->ctx = mg_start(NULL, options);
-
-		if (data->ctx) {
-			printf("Mongoose started on: %s\n", mg_get_option(data->ctx, "listening_ports"));
-		}
-	} else {
-		status = CELIX_START_ERROR;
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt  __attribute__((unused)) context) {
-	struct userData * data = (struct userData *) userData;
-	mg_stop(data->ctx);
-	printf("Mongoose stopped\n");
-	return CELIX_SUCCESS;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt  __attribute__((unused)) context) {
-	struct userData * data = (struct userData *) userData;
-    free(data->entry);
-	free(data);
-	return CELIX_SUCCESS;
-}