commit 22882261f7ca98640332b928ac256430a9652d11
parent f7190c8b12741c04b8fe6c6e402da6b1b004e706
Author: Joris Vink <joris@coders.se>
Date: Mon, 31 Mar 2014 11:29:51 +0200
Properly use pg_config --includedirs + move modules to contrib
Diffstat:
32 files changed, 1079 insertions(+), 1079 deletions(-)
diff --git a/Makefile b/Makefile
@@ -21,7 +21,7 @@ endif
ifneq ("$(PGSQL)", "")
S_SRC+=contrib/postgres/kore_pgsql.c
LDFLAGS+=-lpq
- CFLAGS+=-DKORE_USE_PGSQL
+ CFLAGS+=-I$(shell pg_config --includedir) -DKORE_USE_PGSQL
endif
OSNAME=$(shell uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
diff --git a/contrib/modules/example/build.sh b/contrib/modules/example/build.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+#
+# Copyright (c) 2013 Joris Vink <joris@coders.se>
+#
+# Kore module build script, use this as a base for building
+# your own modules for kore.
+
+# The name of the module you will be building
+MODULE=example.module
+
+# The directory containing all your media files (HTML, CSS, ...).
+# These files will be compiled into the module and symbols will
+# be exported for you to use in your code.
+MEDIA_DIR=media
+
+# The directory containing your module source.
+SOURCE_DIR=src
+
+# The directory containing the Kore source code.
+KORE_DIR=../../../
+
+# Compiler settings.
+CC=gcc
+CFLAGS="-I. -I${KORE_DIR}/includes -Wall -Wstrict-prototypes \
+ -Wmissing-prototypes -Wmissing-declarations -Wshadow \
+ -Wpointer-arith -Wcast-qual -Wsign-compare -g"
+
+OSNAME=$(uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
+if [ "${OSNAME}" = "darwin" ]; then
+ LDFLAGS="-dynamiclib -undefined suppress -flat_namespace"
+else
+ LDFLAGS="-shared"
+fi
+
+MODULE_BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S")
+
+### Begin building ####
+echo "Building module ${MODULE}..."
+rm -f ${MODULE}
+
+${CC} ${CFLAGS} tools/inject.c -o tools/inject
+
+if [ ! -d ${SOURCE_DIR}/${MEDIA_DIR} ]; then
+ mkdir ${SOURCE_DIR}/${MEDIA_DIR};
+fi
+rm -f ${SOURCE_DIR}/${MEDIA_DIR}/*
+
+if [ ! -d .objs ]; then
+ mkdir .objs;
+fi
+rm -f .objs/*
+
+rm -f static.h
+
+for file in `find ${MEDIA_DIR} -type f \( ! -name \*.swp \)`; do
+ echo "Injecting $file";
+ base=`basename $file`;
+ ./tools/inject $file $base > ${SOURCE_DIR}/${MEDIA_DIR}/${base}.c;
+ if [ $? -ne 0 ]; then
+ echo "Injection error, check above messages for clues.";
+ exit 1;
+ fi
+done
+
+echo "#define MODULE_BUILD_DATE \"${MODULE_BUILD_DATE}\"" >> static.h
+
+for src in `find ${SOURCE_DIR} -type f -name \*.c`; do
+ base=`basename $src`;
+ ${CC} ${CFLAGS} -fPIC -c $src -o .objs/${base}.o
+ if [ $? -ne 0 ]; then
+ echo "Build error, check above messages for clues.";
+ exit 1;
+ fi
+done
+
+${CC} ${LDFLAGS} `find .objs -name \*.o -type f` -o ${MODULE}
+echo "Building completed!"
+
+rm -rf ${SOURCE_DIR}/${MEDIA_DIR}
+rm -rf .objs
+rm -f tools/inject
+rm -f static.h
diff --git a/contrib/modules/example/media/index.html b/contrib/modules/example/media/index.html
@@ -0,0 +1,15 @@
+<!DOCTYPE>
+<html>
+<head>
+ <link rel="stylesheet" href="/css/style.css" type="text/css">
+ <title>Your KORE module worked!</title>
+</head>
+
+<body>
+
+<div class="content">
+ <p>Your first Kore module worked.</p>
+</div>
+
+</body>
+</html>
diff --git a/contrib/modules/example/media/intro.jpg b/contrib/modules/example/media/intro.jpg
Binary files differ.
diff --git a/contrib/modules/example/media/params.html b/contrib/modules/example/media/params.html
@@ -0,0 +1,33 @@
+<!DOCTYPE>
+<html>
+<head>
+ <link rel="stylesheet" href="/css/style.css" type="text/css">
+ <title>Kore params test</title>
+</head>
+
+<body style="overflow: auto">
+
+<div class="content" style="font-size: 12px; font-weight: normal">
+ <p>You can pass one GET parameter (arg1), any other GET parameter will
+ be filtered out</p>
+ <p>Only two out of the three input fields will be visible to Kore.</p>
+ <p>The first field accepts the input "test"</p>
+ <p>The second field accepts anything like /test/[a-z]*</p>
+ <p>The third field will be removed by Kore, as it is not in the params
+ block configured for this page.</p>
+ <form method="POST">
+ <input type="input" name="test1" value="$test1$">
+ <input type="input" name="test2" value="$test2$">
+ <input type="input" name="test3" value="$test3$">
+ <input type="submit">
+ </form>
+
+ <p style="font-size: 12px; font-weight: normal">GET param arg1: $arg1$</p>
+ <p style="font-size: 12px; font-weight: normal">GET param arg2: $arg2$</p>
+ <p style="font-size: 12px; font-weight: normal">test1: $test1$</p>
+ <p style="font-size: 12px; font-weight: normal">test2: $test2$</p>
+ <p style="font-size: 12px; font-weight: normal">test3: $test3$</p>
+</div>
+
+</body>
+</html>
diff --git a/contrib/modules/example/media/private.html b/contrib/modules/example/media/private.html
@@ -0,0 +1,16 @@
+<!DOCTYPE>
+<html>
+<head>
+ <link rel="stylesheet" href="/css/style.css" type="text/css">
+ <title>Kore Authentication tests</title>
+</head>
+
+<body>
+
+<div class="content">
+ <p style="font-size: small">The cookie session_id should now be set.</p>
+ <p style="font-size: small">You can continue to <a href="/private/test">view page handler in auth block</a></p>
+</div>
+
+</body>
+</html>
diff --git a/contrib/modules/example/media/private_test.html b/contrib/modules/example/media/private_test.html
@@ -0,0 +1,15 @@
+<!DOCTYPE>
+<html>
+<head>
+ <link rel="stylesheet" href="/css/style.css" type="text/css">
+ <title>Kore Authentication tests</title>
+</head>
+
+<body>
+
+<div class="content">
+ <p style="font-size: small">If you see this, the authentication worked. This page should redirect back to /private once you remove your session_id cookie.</p>
+</div>
+
+</body>
+</html>
diff --git a/contrib/modules/example/media/style.css b/contrib/modules/example/media/style.css
@@ -0,0 +1,16 @@
+body {
+ width: 100%;
+ margin: 0px;
+ color: #000;
+ overflow: hidden;
+ background-color: #fff;
+}
+
+.content {
+ width: 800px;
+ margin-left: auto;
+ margin-right: auto;
+ margin-top: 100px;
+ font-size: 60px;
+ text-align: center;
+}
diff --git a/contrib/modules/example/media/upload.html b/contrib/modules/example/media/upload.html
@@ -0,0 +1,22 @@
+<!DOCTYPE>
+<html>
+<head>
+ <link rel="stylesheet" href="/css/style.css" type="text/css">
+ <title>Kore upload test</title>
+</head>
+
+<body style="overflow: auto">
+
+<div class="content">
+ <form method="POST" enctype="multipart/form-data">
+ <input type="input" name="firstname">
+ <input type="file" name="file">
+ <input type="submit" value="upload">
+ </form>
+
+ <p style="font-size: 12px; font-weight: normal">$upload$</p>
+ <p style="font-size: 12px; font-weight: normal">$firstname$</p>
+</div>
+
+</body>
+</html>
diff --git a/contrib/modules/example/module.conf b/contrib/modules/example/module.conf
@@ -0,0 +1,193 @@
+# Example Kore configuration
+
+# Server configuration.
+bind 127.0.0.1 443
+
+# The path worker processes will chroot into after starting.
+chroot /home/joris/src/kore
+
+# Worker processes will run as the specified user.
+runas joris
+
+# Set workers to the amount of CPU's available in your system,
+# kore will automatically distribute all workers on them.
+workers 4
+
+# The number of active connections each worker can handle.
+# You might have to tweak this number based on your hardware.
+#worker_max_connections 250
+
+# Store the main process its pid in this file.
+#pidfile /var/run/kore.pid
+
+# You can define a callback Kore calls from its parent process or
+# workers everytime the kore_cb_interval timer (in milliseconds) is reached.
+#
+# NOTE: Remember that the parent process runs as root and is not chroot().
+# NOTE: If you want the cb to run on a worker, be sure to set kore_cb_worker.
+#kore_cb my_callback
+#kore_cb_interval 1000
+#kore_cb_worker 3
+
+# HTTP specific settings.
+# http_header_max Maximum size of HTTP headers (in bytes).
+#
+# http_postbody_max Maximum size of an HTTP POST body (in bytes).
+#
+# http_keepalive_time Maximum seconds an HTTP connection can be
+# kept alive by the browser.
+# (Set to 0 to disable keepalive completely).
+#
+# http_hsts_enable Send Strict Transport Security header in
+# all responses. Parameter is the age.
+# (Set to 0 to disable sending this header).
+#http_header_max 4096
+#http_postbody_max 10240000
+#http_keepalive_time 0
+#http_hsts_enable 31536000
+
+# Load modules (you can load multiple at the same time).
+# An additional parameter can be specified as the "onload" function
+# which Kore will call when the module is loaded/reloaded.
+load modules/example/example.module example_load
+
+# Validators
+# validator name type regex|function
+#
+validator v_example function v_example_func
+validator v_regex regex ^/test/[a-z]*$
+validator v_number regex ^[0-9]*$
+validator v_session function v_session_validate
+
+# Specify the SSL ciphers that will be used.
+#ssl_cipher ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK
+
+# If you wish to use EDH / ECDH specify a file containing
+# a generated DH key (See OpenSSL dhparam).
+#ssl_dhparam dh2048.pem
+
+# Set this if you want to disable SSL zlib compression.
+ssl_no_compression
+
+# Specify the amount of seconds a SPDY connection is kept open.
+# You can keep it open indefinately by setting this to 0.
+#spdy_idle_time 120
+
+# Authentication configuration
+#
+# Using authentication blocks you can define a standard way for
+# Kore to validate your users. In the example below we create
+# a authentication block called auth_example, which requires
+# a cookie (session_id) to be set.
+#
+# If no cookie is present or the cookie is not valid according
+# to the set validator, Kore will redirect the browser to the
+# URI set in authentication_uri.
+#
+# Page handlers can be bound to authentication by specifying
+# authentication block at the end of the page directive (see below).
+authentication auth_example {
+ # The authentication type denotes the way the user should
+ # be authenticated.
+ #
+ # Allow values:
+ # - cookie (checks for the cookie presence + pass to validator)
+ # - header (checks for header presence + pass to validator)
+ # - requuest (passes the http_request to the validator)
+ #
+ # Use cases for request could for example be IP based ACLs or
+ # any other criteria that can be extracted from a http_request.
+ #
+ # The request type does not need an authentication_validator.
+ #
+ authentication_type cookie
+
+ # The name of whatever we are looking for.
+ authentication_value session_id
+
+ # The validator that will be called to verify the cookie.
+ # Note this is YOUR validator, Kore does not have built-in
+ # session support. You must add this manually using your
+ # preferred method (Storing it in postgres, redis, ...)
+ authentication_validator v_session
+
+ # The URI Kore will redirect to if a authentication fails.
+ # If this is not set, Kore will return a simple 403.
+ authentication_uri /private
+}
+
+# Domain configuration
+#
+# Each domain configuration starts with listing what domain
+# the directives that follow are to be applied upon.
+#
+# Additionally you can specify the following in a domain configuration:
+#
+# accesslog
+# - File where all requests are logged.
+# require_client_cert
+# - Asks the client to present a certificate
+# matching the CA given to require_client_cert
+#
+# Handlers
+#
+# Handlers are either static (for fixed paths) or dynamic.
+# Dynamic handlers take a POSIX regular expression as its path.
+#
+# Syntax:
+# handler path module_callback [auth block]
+#
+# Note that the auth block is optional and if set will force Kore to
+# authenticate the user according to the authentication block its settings
+# before allowing access to the page.
+
+# Example domain that responds to localhost.
+domain localhost {
+ certfile cert/server.crt
+ certkey cert/server.key
+ accesslog /var/log/kore_access.log
+
+ # Page handlers with no authentication required.
+ static /css/style.css serve_style_css
+ static / serve_index
+ static /intro.jpg serve_intro
+ static /b64test serve_b64test
+ static /spdy-reset serve_spdyreset
+ static /upload serve_file_upload
+ static /lock-test serve_lock_test
+ static /validator serve_validator
+ static /params-test serve_params_test
+ static /private serve_private
+
+ # Page handlers with authentication.
+ static /private/test serve_private_test auth_example
+
+ # Configure /params-test POST to only accept the following parameters.
+ # They are automatically tested against the validator listed.
+ # If the validator would fail Kore will automatically remove the
+ # failing parameter, indicating something was wrong with it.
+ # Any parameters not present in the params block are also filtered out.
+ params post /params-test {
+ validate test1 v_example
+ validate test2 v_regex
+ }
+
+ # Configure a GET parameter that /params-test can received. As before
+ # this is validated against the validator and removed if validation
+ # fails. All extra parameters in the GET query are filtered out.
+ params get /params-test {
+ validate arg1 v_example
+ validate id v_number
+ }
+}
+
+#domain domain.com {
+# certfile cert/other/server.crt
+# certkey cert/other/server.key
+# accesslog /var/log/other_kore_access.log
+# require_client_cert cert/other/ca.crt
+
+# static /css/style.css serve_style_css
+# static / serve_index
+# dynamic ^/[a-z0-9_]*$ serve_profile
+#}
diff --git a/contrib/modules/example/src/example.c b/contrib/modules/example/src/example.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2013 Joris Vink <joris@coders.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "kore.h"
+#include "http.h"
+
+#include "static.h"
+
+void example_load(int);
+
+int serve_style_css(struct http_request *);
+int serve_index(struct http_request *);
+int serve_intro(struct http_request *);
+int serve_b64test(struct http_request *);
+int serve_spdyreset(struct http_request *);
+int serve_file_upload(struct http_request *);
+int serve_lock_test(struct http_request *);
+int serve_validator(struct http_request *);
+int serve_params_test(struct http_request *);
+int serve_private(struct http_request *);
+int serve_private_test(struct http_request *);
+
+void my_callback(void);
+int v_example_func(struct http_request *, char *);
+int v_session_validate(struct http_request *, char *);
+void test_base64(u_int8_t *, u_int32_t, struct kore_buf *);
+
+char *b64tests[] = {
+ "1234567890",
+ "One two three four five",
+ "Man",
+ "any carnal pleasure.",
+ "any carnal pleasure",
+ "any carnal pleas",
+ "I am a nobody, nobody is perfect, therefor I am.",
+ NULL
+};
+
+void
+example_load(int state)
+{
+ switch (state) {
+ case KORE_MODULE_LOAD:
+ kore_log(LOG_NOTICE, "module loading");
+ break;
+ case KORE_MODULE_UNLOAD:
+ kore_log(LOG_NOTICE, "module unloading");
+ break;
+ default:
+ kore_log(LOG_NOTICE, "state %d unknown!", state);
+ break;
+ }
+}
+
+int
+serve_style_css(struct http_request *req)
+{
+ char *date;
+ time_t tstamp;
+
+ tstamp = 0;
+ if (http_request_header_get(req, "if-modified-since", &date)) {
+ tstamp = kore_date_to_time(date);
+ kore_mem_free(date);
+
+ kore_debug("header was present with %ld", tstamp);
+ }
+
+ if (tstamp != 0 && tstamp <= static_mtime_css_style) {
+ http_response(req, 304, NULL, 0);
+ } else {
+ date = kore_time_to_date(static_mtime_css_style);
+ if (date != NULL)
+ http_response_header_add(req, "last-modified", date);
+
+ http_response_header_add(req, "content-type", "text/css");
+ http_response(req, 200, static_css_style, static_len_css_style);
+ }
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_index(struct http_request *req)
+{
+ http_response_header_add(req, "content-type", "text/html");
+ http_response(req, 200, static_html_index, static_len_html_index);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_intro(struct http_request *req)
+{
+ http_response_header_add(req, "content-type", "image/jpg");
+ http_response(req, 200, static_jpg_intro, static_len_jpg_intro);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_b64test(struct http_request *req)
+{
+ int i;
+ u_int32_t len;
+ struct kore_buf *res;
+ u_int8_t *data;
+
+ res = kore_buf_create(1024);
+ for (i = 0; b64tests[i] != NULL; i++)
+ test_base64((u_int8_t *)b64tests[i], strlen(b64tests[i]), res);
+
+ data = kore_buf_release(res, &len);
+
+ http_response_header_add(req, "content-type", "text/plain");
+ http_response(req, 200, data, len);
+ kore_mem_free(data);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_spdyreset(struct http_request *req)
+{
+ spdy_session_teardown(req->owner, SPDY_SESSION_ERROR_OK);
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_file_upload(struct http_request *req)
+{
+ int r;
+ u_int8_t *d;
+ struct kore_buf *b;
+ u_int32_t len;
+ char *name, buf[BUFSIZ];
+
+ b = kore_buf_create(static_len_html_upload);
+ kore_buf_append(b, static_html_upload, static_len_html_upload);
+
+ if (req->method == HTTP_METHOD_POST) {
+ http_populate_multipart_form(req, &r);
+ if (http_argument_get_string("firstname", &name, &len)) {
+ kore_buf_replace_string(b, "$firstname$", name, len);
+ } else {
+ kore_buf_replace_string(b, "$firstname$", NULL, 0);
+ }
+
+ if (http_file_lookup(req, "file", &name, &d, &len)) {
+ snprintf(buf, sizeof(buf), "%s is %d bytes", name, len);
+ kore_buf_replace_string(b,
+ "$upload$", buf, strlen(buf));
+ } else {
+ kore_buf_replace_string(b, "$upload$", NULL, 0);
+ }
+ } else {
+ kore_buf_replace_string(b, "$upload$", NULL, 0);
+ kore_buf_replace_string(b, "$firstname$", NULL, 0);
+ }
+
+ d = kore_buf_release(b, &len);
+
+ http_response_header_add(req, "content-type", "text/html");
+ http_response(req, 200, d, len);
+ kore_mem_free(d);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_lock_test(struct http_request *req)
+{
+ kore_log(LOG_NOTICE, "lock-test called on worker %d", worker->id);
+ kore_worker_acceptlock_release();
+
+ http_response(req, 200, "OK", 2);
+ return (KORE_RESULT_OK);
+}
+
+void
+test_base64(u_int8_t *src, u_int32_t slen, struct kore_buf *res)
+{
+ char *in;
+ u_int32_t len;
+ u_int8_t *out;
+
+ kore_buf_appendf(res, "test '%s'\n", src);
+
+ if (!kore_base64_encode(src, slen, &in)) {
+ kore_buf_appendf(res, "encoding '%s' failed\n", src);
+ } else {
+ kore_buf_appendf(res, "encoded: '%s'\n", in);
+
+ if (!kore_base64_decode(in, &out, &len)) {
+ kore_buf_appendf(res, "decoding failed\n");
+ } else {
+ kore_buf_appendf(res, "decoded: ");
+ kore_buf_append(res, out, len);
+ kore_buf_appendf(res, "\n");
+ kore_mem_free(out);
+ }
+
+ kore_mem_free(in);
+ }
+
+ kore_buf_appendf(res, "\n");
+}
+
+int
+serve_validator(struct http_request *req)
+{
+ if (kore_validator_run(NULL, "v_example", "test"))
+ kore_log(LOG_NOTICE, "v_example ok (expected)");
+ else
+ kore_log(LOG_NOTICE, "v_example failed");
+
+ if (kore_validator_run(NULL, "v_regex", "/test/123"))
+ kore_log(LOG_NOTICE, "regex #1 ok");
+ else
+ kore_log(LOG_NOTICE, "regex #1 failed (expected)");
+
+ if (kore_validator_run(NULL, "v_regex", "/test/joris"))
+ kore_log(LOG_NOTICE, "regex #2 ok (expected)");
+ else
+ kore_log(LOG_NOTICE, "regex #2 failed");
+
+ http_response(req, 200, "OK", 2);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_params_test(struct http_request *req)
+{
+ struct kore_buf *b;
+ u_int8_t *d;
+ u_int32_t len;
+ int r, i;
+ char *test, name[10];
+
+ http_populate_arguments(req);
+
+ b = kore_buf_create(static_len_html_params);
+ kore_buf_append(b, static_html_params, static_len_html_params);
+
+ /*
+ * The GET parameters will be filtered out on POST.
+ */
+ if (http_argument_get_string("arg1", &test, &len)) {
+ kore_buf_replace_string(b, "$arg1$", test, len);
+ } else {
+ kore_buf_replace_string(b, "$arg1$", NULL, 0);
+ }
+
+ if (http_argument_get_string("arg2", &test, &len)) {
+ kore_buf_replace_string(b, "$arg2$", test, len);
+ } else {
+ kore_buf_replace_string(b, "$arg2$", NULL, 0);
+ }
+
+ if (req->method == HTTP_METHOD_GET) {
+ kore_buf_replace_string(b, "$test1$", NULL, 0);
+ kore_buf_replace_string(b, "$test2$", NULL, 0);
+ kore_buf_replace_string(b, "$test3$", NULL, 0);
+
+ if (http_argument_get_uint16("id", &r))
+ kore_log(LOG_NOTICE, "id: %d", r);
+ else
+ kore_log(LOG_NOTICE, "No id set");
+
+ http_response_header_add(req, "content-type", "text/html");
+ d = kore_buf_release(b, &len);
+ http_response(req, 200, d, len);
+ kore_mem_free(d);
+
+ return (KORE_RESULT_OK);
+ }
+
+ for (i = 1; i < 4; i++) {
+ snprintf(name, sizeof(name), "test%d", i);
+ if (http_argument_get_string(name, &test, &len)) {
+ snprintf(name, sizeof(name), "$test%d$", i);
+ kore_buf_replace_string(b, name, test, len);
+ } else {
+ snprintf(name, sizeof(name), "$test%d$", i);
+ kore_buf_replace_string(b, name, NULL, 0);
+ }
+ }
+
+ http_response_header_add(req, "content-type", "text/html");
+ d = kore_buf_release(b, &len);
+ http_response(req, 200, d, len);
+ kore_mem_free(d);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_private(struct http_request *req)
+{
+ http_response_header_add(req, "content-type", "text/html");
+ http_response_header_add(req, "set-cookie", "session_id=test123");
+ http_response(req, 200, static_html_private, static_len_html_private);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_private_test(struct http_request *req)
+{
+ http_response_header_add(req, "content-type", "text/html");
+
+ http_response(req, 200, static_html_private_test,
+ static_len_html_private_test);
+
+ return (KORE_RESULT_OK);
+}
+
+void
+my_callback(void)
+{
+ if (worker != NULL)
+ kore_log(LOG_NOTICE, "running on worker %d", worker->id);
+ else
+ kore_log(LOG_NOTICE, "running from parent");
+}
+
+int
+v_example_func(struct http_request *req, char *data)
+{
+ kore_log(LOG_NOTICE, "v_example_func called");
+
+ if (!strcmp(data, "test"))
+ return (KORE_RESULT_OK);
+
+ return (KORE_RESULT_ERROR);
+}
+
+int
+v_session_validate(struct http_request *req, char *data)
+{
+ kore_log(LOG_NOTICE, "v_session_validate: %s", data);
+
+ if (!strcmp(data, "test123"))
+ return (KORE_RESULT_OK);
+
+ return (KORE_RESULT_ERROR);
+}
diff --git a/contrib/modules/example/tools/inject.c b/contrib/modules/example/tools/inject.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2013 Joris Vink <joris@coders.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if defined(OpenBSD)
+#define PRI_TIME_T "d"
+#endif
+
+#if defined(linux)
+#if defined(__x86_64__)
+#define PRI_TIME_T PRIu64
+#else
+#define PRI_TIME_T "ld"
+#endif
+#endif
+
+#if defined(__MACH__)
+#define PRI_TIME_T "ld"
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ struct stat st;
+ ssize_t len;
+ FILE *hdr;
+ char *ext;
+ unsigned char c[1];
+ int fd, newline, count;
+
+ if (argc != 3)
+ exit(1);
+
+ if ((fd = open(argv[1], O_RDONLY)) == -1)
+ err(1, "open() %d", errno);
+ if ((hdr = fopen("static.h", "a+")) == NULL)
+ err(1, "fopen() %d", errno);
+ if ((ext = strchr(argv[2], '.')) != NULL)
+ *(ext)++ = '\0';
+ else
+ ext = "";
+
+ if (stat(argv[1], &st) == -1) {
+ printf("stat(%s) failed: %d\n", argv[1], errno);
+ exit(1);
+ }
+
+ printf("/**** AUTO GENERATED BY MAKEFILE - DO NOT TOUCH ****/\n");
+ printf("#include <sys/param.h>\n\n");
+ printf("u_int8_t static_%s_%s[] = {", ext, argv[2]);
+
+ len = 0;
+ count = 0;
+ newline = 1;
+ for (;;) {
+ if (newline) {
+ printf("\n\t");
+ count = 0;
+ newline = 0;
+ }
+
+ len = read(fd, c, 1);
+ if (len == 0)
+ break;
+
+ if (len == -1) {
+ printf("read(): %d\n", errno);
+ exit(1);
+ }
+
+ if (len != 1)
+ exit(1);
+
+ printf("0x%02x, ", c[0]);
+ if (count++ == 10)
+ newline = 1;
+ }
+
+ close(fd);
+
+ printf("};\n\n");
+ printf("u_int32_t static_len_%s_%s = %" PRIu32 ";\n",
+ ext, argv[2], (u_int32_t)st.st_size);
+
+ printf("time_t static_mtime_%s_%s = %" PRI_TIME_T ";\n",
+ ext, argv[2], st.st_mtime);
+
+ fprintf(hdr, "extern u_int8_t static_%s_%s[];\n", ext, argv[2]);
+ fprintf(hdr, "extern u_int32_t static_len_%s_%s;\n", ext, argv[2]);
+ fprintf(hdr, "extern time_t static_mtime_%s_%s;\n", ext, argv[2]);
+ fclose(hdr);
+
+ return (0);
+}
diff --git a/contrib/modules/skeleton/build.sh b/contrib/modules/skeleton/build.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+#
+# Copyright (c) 2013 Joris Vink <joris@coders.se>
+#
+# Kore module build script, use this as a base for building
+# your own modules for kore.
+
+# The name of the module you will be building
+MODULE=site.module
+
+# The directory containing all your media files (HTML, CSS, ...).
+# These files will be compiled into the module and symbols will
+# be exported for you to use in your code.
+MEDIA_DIR=media
+
+# The directory containing your module source.
+SOURCE_DIR=src
+
+# The directory containing the Kore source code.
+KORE_DIR="notset"
+if [ ${KORE_DIR} = "notset" ]; then
+ echo "Please edit build.sh and set KORE_DIR properly";
+ exit;
+fi
+
+# Compiler settings.
+CC=gcc
+CFLAGS="-I. -I${KORE_DIR}/includes -Wall -Wstrict-prototypes \
+ -Wmissing-prototypes -Wmissing-declarations -Wshadow \
+ -Wpointer-arith -Wcast-qual -Wsign-compare -g"
+
+OSNAME=$(uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
+if [ "${OSNAME}" = "darwin" ]; then
+ LDFLAGS="-dynamiclib -undefined suppress -flat_namespace"
+else
+ LDFLAGS="-shared"
+fi
+
+MODULE_BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S")
+
+### Begin building ####
+echo "Building module ${MODULE}..."
+rm -f ${MODULE}
+
+${CC} ${CFLAGS} tools/inject.c -o tools/inject
+
+if [ ! -d ${SOURCE_DIR}/${MEDIA_DIR} ]; then
+ mkdir ${SOURCE_DIR}/${MEDIA_DIR};
+fi
+rm -f ${SOURCE_DIR}/${MEDIA_DIR}/*
+
+if [ ! -d .objs ]; then
+ mkdir .objs;
+fi
+rm -f .objs/*
+
+rm -f static.h
+
+for file in `find ${MEDIA_DIR} -type f \( ! -name \*.swp \)`; do
+ echo "Injecting $file";
+ base=`basename $file`;
+ ./tools/inject $file $base > ${SOURCE_DIR}/${MEDIA_DIR}/${base}.c;
+ if [ $? -ne 0 ]; then
+ echo "Injection error, check above messages for clues.";
+ exit 1;
+ fi
+done
+
+echo "#define MODULE_BUILD_DATE \"${MODULE_BUILD_DATE}\"" >> static.h
+
+for src in `find ${SOURCE_DIR} -type f -name \*.c`; do
+ base=`basename $src`;
+ ${CC} ${CFLAGS} -fPIC -c $src -o .objs/${base}.o
+ if [ $? -ne 0 ]; then
+ echo "Build error, check above messages for clues.";
+ exit 1;
+ fi
+done
+
+${CC} ${LDFLAGS} `find .objs -name \*.o -type f` -o ${MODULE}
+echo "Building completed!"
+
+rm -rf ${SOURCE_DIR}/${MEDIA_DIR}
+rm -rf .objs
+rm -f tools/inject
+rm -f static.h
diff --git a/contrib/modules/skeleton/media/.gitignore b/contrib/modules/skeleton/media/.gitignore
diff --git a/contrib/modules/skeleton/src/.gitignore b/contrib/modules/skeleton/src/.gitignore
diff --git a/contrib/modules/skeleton/tools/inject.c b/contrib/modules/skeleton/tools/inject.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2013 Joris Vink <joris@coders.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if defined(OpenBSD)
+#define PRI_TIME_T "d"
+#endif
+
+#if defined(linux)
+#if defined(__x86_64__)
+#define PRI_TIME_T PRIu64
+#else
+#define PRI_TIME_T "ld"
+#endif
+#endif
+
+#if defined(__MACH__)
+#define PRI_TIME_T "ld"
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ struct stat st;
+ ssize_t len;
+ FILE *hdr;
+ char *ext;
+ unsigned char c[1];
+ int fd, newline, count;
+
+ if (argc != 3)
+ exit(1);
+
+ if ((fd = open(argv[1], O_RDONLY)) == -1)
+ err(1, "open() %d", errno);
+ if ((hdr = fopen("static.h", "a+")) == NULL)
+ err(1, "fopen() %d", errno);
+ if ((ext = strchr(argv[2], '.')) != NULL)
+ *(ext)++ = '\0';
+ else
+ ext = "";
+
+ if (stat(argv[1], &st) == -1) {
+ printf("stat(%s) failed: %d\n", argv[1], errno);
+ exit(1);
+ }
+
+ printf("/**** AUTO GENERATED BY MAKEFILE - DO NOT TOUCH ****/\n");
+ printf("#include <sys/param.h>\n\n");
+ printf("u_int8_t static_%s_%s[] = {", ext, argv[2]);
+
+ len = 0;
+ count = 0;
+ newline = 1;
+ for (;;) {
+ if (newline) {
+ printf("\n\t");
+ count = 0;
+ newline = 0;
+ }
+
+ len = read(fd, c, 1);
+ if (len == 0)
+ break;
+
+ if (len == -1) {
+ printf("read(): %d\n", errno);
+ exit(1);
+ }
+
+ if (len != 1)
+ exit(1);
+
+ printf("0x%02x, ", c[0]);
+ if (count++ == 10)
+ newline = 1;
+ }
+
+ close(fd);
+
+ printf("};\n\n");
+ printf("u_int32_t static_len_%s_%s = %" PRIu32 ";\n",
+ ext, argv[2], (u_int32_t)st.st_size);
+
+ printf("time_t static_mtime_%s_%s = %" PRI_TIME_T ";\n",
+ ext, argv[2], st.st_mtime);
+
+ fprintf(hdr, "extern u_int8_t static_%s_%s[];\n", ext, argv[2]);
+ fprintf(hdr, "extern u_int32_t static_len_%s_%s;\n", ext, argv[2]);
+ fprintf(hdr, "extern time_t static_mtime_%s_%s;\n", ext, argv[2]);
+ fclose(hdr);
+
+ return (0);
+}
diff --git a/contrib/postgres/kore_pgsql.c b/contrib/postgres/kore_pgsql.c
@@ -233,7 +233,7 @@ pgsql_conn_create(struct http_request *req, int idx)
kore_debug("pgsql_conn_create(): %p", conn);
memset(conn, 0, sizeof(*conn));
- conn->db = PQconnectdb("host=/tmp/ user=joris");
+ conn->db = PQconnectdb("host=/var/run/postgresql/ user=joris");
if (conn->db == NULL || (PQstatus(conn->db) != CONNECTION_OK)) {
req->pgsql[idx]->state = KORE_PGSQL_STATE_ERROR;
req->pgsql[idx]->error = kore_strdup(PQerrorMessage(conn->db));
diff --git a/modules/example/build.sh b/modules/example/build.sh
@@ -1,82 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2013 Joris Vink <joris@coders.se>
-#
-# Kore module build script, use this as a base for building
-# your own modules for kore.
-
-# The name of the module you will be building
-MODULE=example.module
-
-# The directory containing all your media files (HTML, CSS, ...).
-# These files will be compiled into the module and symbols will
-# be exported for you to use in your code.
-MEDIA_DIR=media
-
-# The directory containing your module source.
-SOURCE_DIR=src
-
-# The directory containing the Kore source code.
-KORE_DIR=../../
-
-# Compiler settings.
-CC=gcc
-CFLAGS="-I. -I${KORE_DIR}/includes -Wall -Wstrict-prototypes \
- -Wmissing-prototypes -Wmissing-declarations -Wshadow \
- -Wpointer-arith -Wcast-qual -Wsign-compare -g"
-
-OSNAME=$(uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
-if [ "${OSNAME}" = "darwin" ]; then
- LDFLAGS="-dynamiclib -undefined suppress -flat_namespace"
-else
- LDFLAGS="-shared"
-fi
-
-MODULE_BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S")
-
-### Begin building ####
-echo "Building module ${MODULE}..."
-rm -f ${MODULE}
-
-${CC} ${CFLAGS} tools/inject.c -o tools/inject
-
-if [ ! -d ${SOURCE_DIR}/${MEDIA_DIR} ]; then
- mkdir ${SOURCE_DIR}/${MEDIA_DIR};
-fi
-rm -f ${SOURCE_DIR}/${MEDIA_DIR}/*
-
-if [ ! -d .objs ]; then
- mkdir .objs;
-fi
-rm -f .objs/*
-
-rm -f static.h
-
-for file in `find ${MEDIA_DIR} -type f \( ! -name \*.swp \)`; do
- echo "Injecting $file";
- base=`basename $file`;
- ./tools/inject $file $base > ${SOURCE_DIR}/${MEDIA_DIR}/${base}.c;
- if [ $? -ne 0 ]; then
- echo "Injection error, check above messages for clues.";
- exit 1;
- fi
-done
-
-echo "#define MODULE_BUILD_DATE \"${MODULE_BUILD_DATE}\"" >> static.h
-
-for src in `find ${SOURCE_DIR} -type f -name \*.c`; do
- base=`basename $src`;
- ${CC} ${CFLAGS} -fPIC -c $src -o .objs/${base}.o
- if [ $? -ne 0 ]; then
- echo "Build error, check above messages for clues.";
- exit 1;
- fi
-done
-
-${CC} ${LDFLAGS} `find .objs -name \*.o -type f` -o ${MODULE}
-echo "Building completed!"
-
-rm -rf ${SOURCE_DIR}/${MEDIA_DIR}
-rm -rf .objs
-rm -f tools/inject
-rm -f static.h
diff --git a/modules/example/media/index.html b/modules/example/media/index.html
@@ -1,15 +0,0 @@
-<!DOCTYPE>
-<html>
-<head>
- <link rel="stylesheet" href="/css/style.css" type="text/css">
- <title>Your KORE module worked!</title>
-</head>
-
-<body>
-
-<div class="content">
- <p>Your first Kore module worked.</p>
-</div>
-
-</body>
-</html>
diff --git a/modules/example/media/intro.jpg b/modules/example/media/intro.jpg
Binary files differ.
diff --git a/modules/example/media/params.html b/modules/example/media/params.html
@@ -1,33 +0,0 @@
-<!DOCTYPE>
-<html>
-<head>
- <link rel="stylesheet" href="/css/style.css" type="text/css">
- <title>Kore params test</title>
-</head>
-
-<body style="overflow: auto">
-
-<div class="content" style="font-size: 12px; font-weight: normal">
- <p>You can pass one GET parameter (arg1), any other GET parameter will
- be filtered out</p>
- <p>Only two out of the three input fields will be visible to Kore.</p>
- <p>The first field accepts the input "test"</p>
- <p>The second field accepts anything like /test/[a-z]*</p>
- <p>The third field will be removed by Kore, as it is not in the params
- block configured for this page.</p>
- <form method="POST">
- <input type="input" name="test1" value="$test1$">
- <input type="input" name="test2" value="$test2$">
- <input type="input" name="test3" value="$test3$">
- <input type="submit">
- </form>
-
- <p style="font-size: 12px; font-weight: normal">GET param arg1: $arg1$</p>
- <p style="font-size: 12px; font-weight: normal">GET param arg2: $arg2$</p>
- <p style="font-size: 12px; font-weight: normal">test1: $test1$</p>
- <p style="font-size: 12px; font-weight: normal">test2: $test2$</p>
- <p style="font-size: 12px; font-weight: normal">test3: $test3$</p>
-</div>
-
-</body>
-</html>
diff --git a/modules/example/media/private.html b/modules/example/media/private.html
@@ -1,16 +0,0 @@
-<!DOCTYPE>
-<html>
-<head>
- <link rel="stylesheet" href="/css/style.css" type="text/css">
- <title>Kore Authentication tests</title>
-</head>
-
-<body>
-
-<div class="content">
- <p style="font-size: small">The cookie session_id should now be set.</p>
- <p style="font-size: small">You can continue to <a href="/private/test">view page handler in auth block</a></p>
-</div>
-
-</body>
-</html>
diff --git a/modules/example/media/private_test.html b/modules/example/media/private_test.html
@@ -1,15 +0,0 @@
-<!DOCTYPE>
-<html>
-<head>
- <link rel="stylesheet" href="/css/style.css" type="text/css">
- <title>Kore Authentication tests</title>
-</head>
-
-<body>
-
-<div class="content">
- <p style="font-size: small">If you see this, the authentication worked. This page should redirect back to /private once you remove your session_id cookie.</p>
-</div>
-
-</body>
-</html>
diff --git a/modules/example/media/style.css b/modules/example/media/style.css
@@ -1,16 +0,0 @@
-body {
- width: 100%;
- margin: 0px;
- color: #000;
- overflow: hidden;
- background-color: #fff;
-}
-
-.content {
- width: 800px;
- margin-left: auto;
- margin-right: auto;
- margin-top: 100px;
- font-size: 60px;
- text-align: center;
-}
diff --git a/modules/example/media/upload.html b/modules/example/media/upload.html
@@ -1,22 +0,0 @@
-<!DOCTYPE>
-<html>
-<head>
- <link rel="stylesheet" href="/css/style.css" type="text/css">
- <title>Kore upload test</title>
-</head>
-
-<body style="overflow: auto">
-
-<div class="content">
- <form method="POST" enctype="multipart/form-data">
- <input type="input" name="firstname">
- <input type="file" name="file">
- <input type="submit" value="upload">
- </form>
-
- <p style="font-size: 12px; font-weight: normal">$upload$</p>
- <p style="font-size: 12px; font-weight: normal">$firstname$</p>
-</div>
-
-</body>
-</html>
diff --git a/modules/example/module.conf b/modules/example/module.conf
@@ -1,193 +0,0 @@
-# Example Kore configuration
-
-# Server configuration.
-bind 127.0.0.1 443
-
-# The path worker processes will chroot into after starting.
-chroot /home/joris/src/kore
-
-# Worker processes will run as the specified user.
-runas joris
-
-# Set workers to the amount of CPU's available in your system,
-# kore will automatically distribute all workers on them.
-workers 4
-
-# The number of active connections each worker can handle.
-# You might have to tweak this number based on your hardware.
-#worker_max_connections 250
-
-# Store the main process its pid in this file.
-#pidfile /var/run/kore.pid
-
-# You can define a callback Kore calls from its parent process or
-# workers everytime the kore_cb_interval timer (in milliseconds) is reached.
-#
-# NOTE: Remember that the parent process runs as root and is not chroot().
-# NOTE: If you want the cb to run on a worker, be sure to set kore_cb_worker.
-#kore_cb my_callback
-#kore_cb_interval 1000
-#kore_cb_worker 3
-
-# HTTP specific settings.
-# http_header_max Maximum size of HTTP headers (in bytes).
-#
-# http_postbody_max Maximum size of an HTTP POST body (in bytes).
-#
-# http_keepalive_time Maximum seconds an HTTP connection can be
-# kept alive by the browser.
-# (Set to 0 to disable keepalive completely).
-#
-# http_hsts_enable Send Strict Transport Security header in
-# all responses. Parameter is the age.
-# (Set to 0 to disable sending this header).
-#http_header_max 4096
-#http_postbody_max 10240000
-#http_keepalive_time 0
-#http_hsts_enable 31536000
-
-# Load modules (you can load multiple at the same time).
-# An additional parameter can be specified as the "onload" function
-# which Kore will call when the module is loaded/reloaded.
-load modules/example/example.module example_load
-
-# Validators
-# validator name type regex|function
-#
-validator v_example function v_example_func
-validator v_regex regex ^/test/[a-z]*$
-validator v_number regex ^[0-9]*$
-validator v_session function v_session_validate
-
-# Specify the SSL ciphers that will be used.
-#ssl_cipher ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK
-
-# If you wish to use EDH / ECDH specify a file containing
-# a generated DH key (See OpenSSL dhparam).
-#ssl_dhparam dh2048.pem
-
-# Set this if you want to disable SSL zlib compression.
-ssl_no_compression
-
-# Specify the amount of seconds a SPDY connection is kept open.
-# You can keep it open indefinately by setting this to 0.
-#spdy_idle_time 120
-
-# Authentication configuration
-#
-# Using authentication blocks you can define a standard way for
-# Kore to validate your users. In the example below we create
-# a authentication block called auth_example, which requires
-# a cookie (session_id) to be set.
-#
-# If no cookie is present or the cookie is not valid according
-# to the set validator, Kore will redirect the browser to the
-# URI set in authentication_uri.
-#
-# Page handlers can be bound to authentication by specifying
-# authentication block at the end of the page directive (see below).
-authentication auth_example {
- # The authentication type denotes the way the user should
- # be authenticated.
- #
- # Allow values:
- # - cookie (checks for the cookie presence + pass to validator)
- # - header (checks for header presence + pass to validator)
- # - requuest (passes the http_request to the validator)
- #
- # Use cases for request could for example be IP based ACLs or
- # any other criteria that can be extracted from a http_request.
- #
- # The request type does not need an authentication_validator.
- #
- authentication_type cookie
-
- # The name of whatever we are looking for.
- authentication_value session_id
-
- # The validator that will be called to verify the cookie.
- # Note this is YOUR validator, Kore does not have built-in
- # session support. You must add this manually using your
- # preferred method (Storing it in postgres, redis, ...)
- authentication_validator v_session
-
- # The URI Kore will redirect to if a authentication fails.
- # If this is not set, Kore will return a simple 403.
- authentication_uri /private
-}
-
-# Domain configuration
-#
-# Each domain configuration starts with listing what domain
-# the directives that follow are to be applied upon.
-#
-# Additionally you can specify the following in a domain configuration:
-#
-# accesslog
-# - File where all requests are logged.
-# require_client_cert
-# - Asks the client to present a certificate
-# matching the CA given to require_client_cert
-#
-# Handlers
-#
-# Handlers are either static (for fixed paths) or dynamic.
-# Dynamic handlers take a POSIX regular expression as its path.
-#
-# Syntax:
-# handler path module_callback [auth block]
-#
-# Note that the auth block is optional and if set will force Kore to
-# authenticate the user according to the authentication block its settings
-# before allowing access to the page.
-
-# Example domain that responds to localhost.
-domain localhost {
- certfile cert/server.crt
- certkey cert/server.key
- accesslog /var/log/kore_access.log
-
- # Page handlers with no authentication required.
- static /css/style.css serve_style_css
- static / serve_index
- static /intro.jpg serve_intro
- static /b64test serve_b64test
- static /spdy-reset serve_spdyreset
- static /upload serve_file_upload
- static /lock-test serve_lock_test
- static /validator serve_validator
- static /params-test serve_params_test
- static /private serve_private
-
- # Page handlers with authentication.
- static /private/test serve_private_test auth_example
-
- # Configure /params-test POST to only accept the following parameters.
- # They are automatically tested against the validator listed.
- # If the validator would fail Kore will automatically remove the
- # failing parameter, indicating something was wrong with it.
- # Any parameters not present in the params block are also filtered out.
- params post /params-test {
- validate test1 v_example
- validate test2 v_regex
- }
-
- # Configure a GET parameter that /params-test can received. As before
- # this is validated against the validator and removed if validation
- # fails. All extra parameters in the GET query are filtered out.
- params get /params-test {
- validate arg1 v_example
- validate id v_number
- }
-}
-
-#domain domain.com {
-# certfile cert/other/server.crt
-# certkey cert/other/server.key
-# accesslog /var/log/other_kore_access.log
-# require_client_cert cert/other/ca.crt
-
-# static /css/style.css serve_style_css
-# static / serve_index
-# dynamic ^/[a-z0-9_]*$ serve_profile
-#}
diff --git a/modules/example/src/example.c b/modules/example/src/example.c
@@ -1,361 +0,0 @@
-/*
- * Copyright (c) 2013 Joris Vink <joris@coders.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "kore.h"
-#include "http.h"
-
-#include "static.h"
-
-void example_load(int);
-
-int serve_style_css(struct http_request *);
-int serve_index(struct http_request *);
-int serve_intro(struct http_request *);
-int serve_b64test(struct http_request *);
-int serve_spdyreset(struct http_request *);
-int serve_file_upload(struct http_request *);
-int serve_lock_test(struct http_request *);
-int serve_validator(struct http_request *);
-int serve_params_test(struct http_request *);
-int serve_private(struct http_request *);
-int serve_private_test(struct http_request *);
-
-void my_callback(void);
-int v_example_func(struct http_request *, char *);
-int v_session_validate(struct http_request *, char *);
-void test_base64(u_int8_t *, u_int32_t, struct kore_buf *);
-
-char *b64tests[] = {
- "1234567890",
- "One two three four five",
- "Man",
- "any carnal pleasure.",
- "any carnal pleasure",
- "any carnal pleas",
- "I am a nobody, nobody is perfect, therefor I am.",
- NULL
-};
-
-void
-example_load(int state)
-{
- switch (state) {
- case KORE_MODULE_LOAD:
- kore_log(LOG_NOTICE, "module loading");
- break;
- case KORE_MODULE_UNLOAD:
- kore_log(LOG_NOTICE, "module unloading");
- break;
- default:
- kore_log(LOG_NOTICE, "state %d unknown!", state);
- break;
- }
-}
-
-int
-serve_style_css(struct http_request *req)
-{
- char *date;
- time_t tstamp;
-
- tstamp = 0;
- if (http_request_header_get(req, "if-modified-since", &date)) {
- tstamp = kore_date_to_time(date);
- kore_mem_free(date);
-
- kore_debug("header was present with %ld", tstamp);
- }
-
- if (tstamp != 0 && tstamp <= static_mtime_css_style) {
- http_response(req, 304, NULL, 0);
- } else {
- date = kore_time_to_date(static_mtime_css_style);
- if (date != NULL)
- http_response_header_add(req, "last-modified", date);
-
- http_response_header_add(req, "content-type", "text/css");
- http_response(req, 200, static_css_style, static_len_css_style);
- }
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_index(struct http_request *req)
-{
- http_response_header_add(req, "content-type", "text/html");
- http_response(req, 200, static_html_index, static_len_html_index);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_intro(struct http_request *req)
-{
- http_response_header_add(req, "content-type", "image/jpg");
- http_response(req, 200, static_jpg_intro, static_len_jpg_intro);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_b64test(struct http_request *req)
-{
- int i;
- u_int32_t len;
- struct kore_buf *res;
- u_int8_t *data;
-
- res = kore_buf_create(1024);
- for (i = 0; b64tests[i] != NULL; i++)
- test_base64((u_int8_t *)b64tests[i], strlen(b64tests[i]), res);
-
- data = kore_buf_release(res, &len);
-
- http_response_header_add(req, "content-type", "text/plain");
- http_response(req, 200, data, len);
- kore_mem_free(data);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_spdyreset(struct http_request *req)
-{
- spdy_session_teardown(req->owner, SPDY_SESSION_ERROR_OK);
- return (KORE_RESULT_OK);
-}
-
-int
-serve_file_upload(struct http_request *req)
-{
- int r;
- u_int8_t *d;
- struct kore_buf *b;
- u_int32_t len;
- char *name, buf[BUFSIZ];
-
- b = kore_buf_create(static_len_html_upload);
- kore_buf_append(b, static_html_upload, static_len_html_upload);
-
- if (req->method == HTTP_METHOD_POST) {
- http_populate_multipart_form(req, &r);
- if (http_argument_get_string("firstname", &name, &len)) {
- kore_buf_replace_string(b, "$firstname$", name, len);
- } else {
- kore_buf_replace_string(b, "$firstname$", NULL, 0);
- }
-
- if (http_file_lookup(req, "file", &name, &d, &len)) {
- snprintf(buf, sizeof(buf), "%s is %d bytes", name, len);
- kore_buf_replace_string(b,
- "$upload$", buf, strlen(buf));
- } else {
- kore_buf_replace_string(b, "$upload$", NULL, 0);
- }
- } else {
- kore_buf_replace_string(b, "$upload$", NULL, 0);
- kore_buf_replace_string(b, "$firstname$", NULL, 0);
- }
-
- d = kore_buf_release(b, &len);
-
- http_response_header_add(req, "content-type", "text/html");
- http_response(req, 200, d, len);
- kore_mem_free(d);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_lock_test(struct http_request *req)
-{
- kore_log(LOG_NOTICE, "lock-test called on worker %d", worker->id);
- kore_worker_acceptlock_release();
-
- http_response(req, 200, "OK", 2);
- return (KORE_RESULT_OK);
-}
-
-void
-test_base64(u_int8_t *src, u_int32_t slen, struct kore_buf *res)
-{
- char *in;
- u_int32_t len;
- u_int8_t *out;
-
- kore_buf_appendf(res, "test '%s'\n", src);
-
- if (!kore_base64_encode(src, slen, &in)) {
- kore_buf_appendf(res, "encoding '%s' failed\n", src);
- } else {
- kore_buf_appendf(res, "encoded: '%s'\n", in);
-
- if (!kore_base64_decode(in, &out, &len)) {
- kore_buf_appendf(res, "decoding failed\n");
- } else {
- kore_buf_appendf(res, "decoded: ");
- kore_buf_append(res, out, len);
- kore_buf_appendf(res, "\n");
- kore_mem_free(out);
- }
-
- kore_mem_free(in);
- }
-
- kore_buf_appendf(res, "\n");
-}
-
-int
-serve_validator(struct http_request *req)
-{
- if (kore_validator_run(NULL, "v_example", "test"))
- kore_log(LOG_NOTICE, "v_example ok (expected)");
- else
- kore_log(LOG_NOTICE, "v_example failed");
-
- if (kore_validator_run(NULL, "v_regex", "/test/123"))
- kore_log(LOG_NOTICE, "regex #1 ok");
- else
- kore_log(LOG_NOTICE, "regex #1 failed (expected)");
-
- if (kore_validator_run(NULL, "v_regex", "/test/joris"))
- kore_log(LOG_NOTICE, "regex #2 ok (expected)");
- else
- kore_log(LOG_NOTICE, "regex #2 failed");
-
- http_response(req, 200, "OK", 2);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_params_test(struct http_request *req)
-{
- struct kore_buf *b;
- u_int8_t *d;
- u_int32_t len;
- int r, i;
- char *test, name[10];
-
- http_populate_arguments(req);
-
- b = kore_buf_create(static_len_html_params);
- kore_buf_append(b, static_html_params, static_len_html_params);
-
- /*
- * The GET parameters will be filtered out on POST.
- */
- if (http_argument_get_string("arg1", &test, &len)) {
- kore_buf_replace_string(b, "$arg1$", test, len);
- } else {
- kore_buf_replace_string(b, "$arg1$", NULL, 0);
- }
-
- if (http_argument_get_string("arg2", &test, &len)) {
- kore_buf_replace_string(b, "$arg2$", test, len);
- } else {
- kore_buf_replace_string(b, "$arg2$", NULL, 0);
- }
-
- if (req->method == HTTP_METHOD_GET) {
- kore_buf_replace_string(b, "$test1$", NULL, 0);
- kore_buf_replace_string(b, "$test2$", NULL, 0);
- kore_buf_replace_string(b, "$test3$", NULL, 0);
-
- if (http_argument_get_uint16("id", &r))
- kore_log(LOG_NOTICE, "id: %d", r);
- else
- kore_log(LOG_NOTICE, "No id set");
-
- http_response_header_add(req, "content-type", "text/html");
- d = kore_buf_release(b, &len);
- http_response(req, 200, d, len);
- kore_mem_free(d);
-
- return (KORE_RESULT_OK);
- }
-
- for (i = 1; i < 4; i++) {
- snprintf(name, sizeof(name), "test%d", i);
- if (http_argument_get_string(name, &test, &len)) {
- snprintf(name, sizeof(name), "$test%d$", i);
- kore_buf_replace_string(b, name, test, len);
- } else {
- snprintf(name, sizeof(name), "$test%d$", i);
- kore_buf_replace_string(b, name, NULL, 0);
- }
- }
-
- http_response_header_add(req, "content-type", "text/html");
- d = kore_buf_release(b, &len);
- http_response(req, 200, d, len);
- kore_mem_free(d);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_private(struct http_request *req)
-{
- http_response_header_add(req, "content-type", "text/html");
- http_response_header_add(req, "set-cookie", "session_id=test123");
- http_response(req, 200, static_html_private, static_len_html_private);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_private_test(struct http_request *req)
-{
- http_response_header_add(req, "content-type", "text/html");
-
- http_response(req, 200, static_html_private_test,
- static_len_html_private_test);
-
- return (KORE_RESULT_OK);
-}
-
-void
-my_callback(void)
-{
- if (worker != NULL)
- kore_log(LOG_NOTICE, "running on worker %d", worker->id);
- else
- kore_log(LOG_NOTICE, "running from parent");
-}
-
-int
-v_example_func(struct http_request *req, char *data)
-{
- kore_log(LOG_NOTICE, "v_example_func called");
-
- if (!strcmp(data, "test"))
- return (KORE_RESULT_OK);
-
- return (KORE_RESULT_ERROR);
-}
-
-int
-v_session_validate(struct http_request *req, char *data)
-{
- kore_log(LOG_NOTICE, "v_session_validate: %s", data);
-
- if (!strcmp(data, "test123"))
- return (KORE_RESULT_OK);
-
- return (KORE_RESULT_ERROR);
-}
diff --git a/modules/example/tools/inject.c b/modules/example/tools/inject.c
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2013 Joris Vink <joris@coders.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#if defined(OpenBSD)
-#define PRI_TIME_T "d"
-#endif
-
-#if defined(linux)
-#if defined(__x86_64__)
-#define PRI_TIME_T PRIu64
-#else
-#define PRI_TIME_T "ld"
-#endif
-#endif
-
-#if defined(__MACH__)
-#define PRI_TIME_T "ld"
-#endif
-
-int
-main(int argc, char *argv[])
-{
- struct stat st;
- ssize_t len;
- FILE *hdr;
- char *ext;
- unsigned char c[1];
- int fd, newline, count;
-
- if (argc != 3)
- exit(1);
-
- if ((fd = open(argv[1], O_RDONLY)) == -1)
- err(1, "open() %d", errno);
- if ((hdr = fopen("static.h", "a+")) == NULL)
- err(1, "fopen() %d", errno);
- if ((ext = strchr(argv[2], '.')) != NULL)
- *(ext)++ = '\0';
- else
- ext = "";
-
- if (stat(argv[1], &st) == -1) {
- printf("stat(%s) failed: %d\n", argv[1], errno);
- exit(1);
- }
-
- printf("/**** AUTO GENERATED BY MAKEFILE - DO NOT TOUCH ****/\n");
- printf("#include <sys/param.h>\n\n");
- printf("u_int8_t static_%s_%s[] = {", ext, argv[2]);
-
- len = 0;
- count = 0;
- newline = 1;
- for (;;) {
- if (newline) {
- printf("\n\t");
- count = 0;
- newline = 0;
- }
-
- len = read(fd, c, 1);
- if (len == 0)
- break;
-
- if (len == -1) {
- printf("read(): %d\n", errno);
- exit(1);
- }
-
- if (len != 1)
- exit(1);
-
- printf("0x%02x, ", c[0]);
- if (count++ == 10)
- newline = 1;
- }
-
- close(fd);
-
- printf("};\n\n");
- printf("u_int32_t static_len_%s_%s = %" PRIu32 ";\n",
- ext, argv[2], (u_int32_t)st.st_size);
-
- printf("time_t static_mtime_%s_%s = %" PRI_TIME_T ";\n",
- ext, argv[2], st.st_mtime);
-
- fprintf(hdr, "extern u_int8_t static_%s_%s[];\n", ext, argv[2]);
- fprintf(hdr, "extern u_int32_t static_len_%s_%s;\n", ext, argv[2]);
- fprintf(hdr, "extern time_t static_mtime_%s_%s;\n", ext, argv[2]);
- fclose(hdr);
-
- return (0);
-}
diff --git a/modules/skeleton/build.sh b/modules/skeleton/build.sh
@@ -1,86 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2013 Joris Vink <joris@coders.se>
-#
-# Kore module build script, use this as a base for building
-# your own modules for kore.
-
-# The name of the module you will be building
-MODULE=site.module
-
-# The directory containing all your media files (HTML, CSS, ...).
-# These files will be compiled into the module and symbols will
-# be exported for you to use in your code.
-MEDIA_DIR=media
-
-# The directory containing your module source.
-SOURCE_DIR=src
-
-# The directory containing the Kore source code.
-KORE_DIR="notset"
-if [ ${KORE_DIR} = "notset" ]; then
- echo "Please edit build.sh and set KORE_DIR properly";
- exit;
-fi
-
-# Compiler settings.
-CC=gcc
-CFLAGS="-I. -I${KORE_DIR}/includes -Wall -Wstrict-prototypes \
- -Wmissing-prototypes -Wmissing-declarations -Wshadow \
- -Wpointer-arith -Wcast-qual -Wsign-compare -g"
-
-OSNAME=$(uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
-if [ "${OSNAME}" = "darwin" ]; then
- LDFLAGS="-dynamiclib -undefined suppress -flat_namespace"
-else
- LDFLAGS="-shared"
-fi
-
-MODULE_BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S")
-
-### Begin building ####
-echo "Building module ${MODULE}..."
-rm -f ${MODULE}
-
-${CC} ${CFLAGS} tools/inject.c -o tools/inject
-
-if [ ! -d ${SOURCE_DIR}/${MEDIA_DIR} ]; then
- mkdir ${SOURCE_DIR}/${MEDIA_DIR};
-fi
-rm -f ${SOURCE_DIR}/${MEDIA_DIR}/*
-
-if [ ! -d .objs ]; then
- mkdir .objs;
-fi
-rm -f .objs/*
-
-rm -f static.h
-
-for file in `find ${MEDIA_DIR} -type f \( ! -name \*.swp \)`; do
- echo "Injecting $file";
- base=`basename $file`;
- ./tools/inject $file $base > ${SOURCE_DIR}/${MEDIA_DIR}/${base}.c;
- if [ $? -ne 0 ]; then
- echo "Injection error, check above messages for clues.";
- exit 1;
- fi
-done
-
-echo "#define MODULE_BUILD_DATE \"${MODULE_BUILD_DATE}\"" >> static.h
-
-for src in `find ${SOURCE_DIR} -type f -name \*.c`; do
- base=`basename $src`;
- ${CC} ${CFLAGS} -fPIC -c $src -o .objs/${base}.o
- if [ $? -ne 0 ]; then
- echo "Build error, check above messages for clues.";
- exit 1;
- fi
-done
-
-${CC} ${LDFLAGS} `find .objs -name \*.o -type f` -o ${MODULE}
-echo "Building completed!"
-
-rm -rf ${SOURCE_DIR}/${MEDIA_DIR}
-rm -rf .objs
-rm -f tools/inject
-rm -f static.h
diff --git a/modules/skeleton/media/.gitignore b/modules/skeleton/media/.gitignore
diff --git a/modules/skeleton/src/.gitignore b/modules/skeleton/src/.gitignore
diff --git a/modules/skeleton/tools/inject.c b/modules/skeleton/tools/inject.c
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2013 Joris Vink <joris@coders.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#if defined(OpenBSD)
-#define PRI_TIME_T "d"
-#endif
-
-#if defined(linux)
-#if defined(__x86_64__)
-#define PRI_TIME_T PRIu64
-#else
-#define PRI_TIME_T "ld"
-#endif
-#endif
-
-#if defined(__MACH__)
-#define PRI_TIME_T "ld"
-#endif
-
-int
-main(int argc, char *argv[])
-{
- struct stat st;
- ssize_t len;
- FILE *hdr;
- char *ext;
- unsigned char c[1];
- int fd, newline, count;
-
- if (argc != 3)
- exit(1);
-
- if ((fd = open(argv[1], O_RDONLY)) == -1)
- err(1, "open() %d", errno);
- if ((hdr = fopen("static.h", "a+")) == NULL)
- err(1, "fopen() %d", errno);
- if ((ext = strchr(argv[2], '.')) != NULL)
- *(ext)++ = '\0';
- else
- ext = "";
-
- if (stat(argv[1], &st) == -1) {
- printf("stat(%s) failed: %d\n", argv[1], errno);
- exit(1);
- }
-
- printf("/**** AUTO GENERATED BY MAKEFILE - DO NOT TOUCH ****/\n");
- printf("#include <sys/param.h>\n\n");
- printf("u_int8_t static_%s_%s[] = {", ext, argv[2]);
-
- len = 0;
- count = 0;
- newline = 1;
- for (;;) {
- if (newline) {
- printf("\n\t");
- count = 0;
- newline = 0;
- }
-
- len = read(fd, c, 1);
- if (len == 0)
- break;
-
- if (len == -1) {
- printf("read(): %d\n", errno);
- exit(1);
- }
-
- if (len != 1)
- exit(1);
-
- printf("0x%02x, ", c[0]);
- if (count++ == 10)
- newline = 1;
- }
-
- close(fd);
-
- printf("};\n\n");
- printf("u_int32_t static_len_%s_%s = %" PRIu32 ";\n",
- ext, argv[2], (u_int32_t)st.st_size);
-
- printf("time_t static_mtime_%s_%s = %" PRI_TIME_T ";\n",
- ext, argv[2], st.st_mtime);
-
- fprintf(hdr, "extern u_int8_t static_%s_%s[];\n", ext, argv[2]);
- fprintf(hdr, "extern u_int32_t static_len_%s_%s;\n", ext, argv[2]);
- fprintf(hdr, "extern time_t static_mtime_%s_%s;\n", ext, argv[2]);
- fclose(hdr);
-
- return (0);
-}