Module Name: othersrc
Committed By: agc
Date: Sat Jun 8 10:48:57 UTC 2013
Modified Files:
othersrc/external/historical/eawk/extend: Makefile
Added Files:
othersrc/external/historical/eawk/extend/httpd: Makefile httpd.c
shlib_version tiny.c tiny.h
othersrc/external/historical/eawk/scripts: httpd.sh json.sh
Log Message:
Changes to eawk:
+ add a small script to do some basic json printing
+ add a small http daemon library - which only does GET requests,
but still useful. Also add an eawk script, which acts as a web server
in 9 lines of awk:
env LD_LIBRARY_PATH=lib:extend/httpd bin/eawk -v port=${port} '
BEGIN { use("httpd")
server = httpd_bind_server("localhost", port, "ipv4")
while (1) {
client = httpd_get_connection(server);
uri = httpd_read_request(client);
filename = httpd_parse_uri(uri)
httpd_serve_static_content(client, filename);
httpd_close_client_connection(client);
}
}'
and in use:
% sh scripts/httpd.sh 12345
Client request from: 127.0.0.1
GET /CHANGES HTTP/1.0
Host: localhost:12345
Accept: text/html, text/plain, text/css, text/sgml, */*;q=0.01
Accept-Encoding: gzip, compress, bzip2
Accept-Language: en
User-Agent: Lynx/2.8.7rel.1 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/1.0.1-stable
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 othersrc/external/historical/eawk/extend/Makefile
cvs rdiff -u -r0 -r1.1 \
othersrc/external/historical/eawk/extend/httpd/Makefile \
othersrc/external/historical/eawk/extend/httpd/httpd.c \
othersrc/external/historical/eawk/extend/httpd/shlib_version \
othersrc/external/historical/eawk/extend/httpd/tiny.c \
othersrc/external/historical/eawk/extend/httpd/tiny.h
cvs rdiff -u -r0 -r1.1 othersrc/external/historical/eawk/scripts/httpd.sh \
othersrc/external/historical/eawk/scripts/json.sh
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: othersrc/external/historical/eawk/extend/Makefile
diff -u othersrc/external/historical/eawk/extend/Makefile:1.4 othersrc/external/historical/eawk/extend/Makefile:1.5
--- othersrc/external/historical/eawk/extend/Makefile:1.4 Thu Jun 6 01:45:56 2013
+++ othersrc/external/historical/eawk/extend/Makefile Sat Jun 8 10:48:57 2013
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.4 2013/06/06 01:45:56 agc Exp $
+# $NetBSD: Makefile,v 1.5 2013/06/08 10:48:57 agc Exp $
SUBDIR+= archive
SUBDIR+= base64
@@ -23,6 +23,7 @@ SUBDIR+= hmac
.if exists(/usr/include/http.h)
SUBDIR+= http
.endif
+SUBDIR+= httpd
.if exists(/usr/include/mat.h)
SUBDIR+= mat
.endif
Added files:
Index: othersrc/external/historical/eawk/extend/httpd/Makefile
diff -u /dev/null othersrc/external/historical/eawk/extend/httpd/Makefile:1.1
--- /dev/null Sat Jun 8 10:48:57 2013
+++ othersrc/external/historical/eawk/extend/httpd/Makefile Sat Jun 8 10:48:57 2013
@@ -0,0 +1,15 @@
+# $NetBSD: Makefile,v 1.1 2013/06/08 10:48:57 agc Exp $
+
+.include <bsd.own.mk>
+
+DIST= ${.CURDIR}/../../dist
+.PATH: ${DIST}
+
+LIB= eawk-httpd
+SRCS= httpd.c tiny.c
+CPPFLAGS+= -I. -I${DIST}
+MKMAN= no
+
+WARNS= 5
+
+.include <bsd.lib.mk>
Index: othersrc/external/historical/eawk/extend/httpd/httpd.c
diff -u /dev/null othersrc/external/historical/eawk/extend/httpd/httpd.c:1.1
--- /dev/null Sat Jun 8 10:48:57 2013
+++ othersrc/external/historical/eawk/extend/httpd/httpd.c Sat Jun 8 10:48:57 2013
@@ -0,0 +1,279 @@
+/*-
+ * Copyright (c) 2013 Alistair Crooks <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tiny.h"
+#include "eawk.h"
+
+#ifndef USE_ARG
+#define USE_ARG(x) /*LINTED*/(void)&x
+#endif
+
+/* convert number to ptr */
+static int64_t
+p2num(void *p)
+{
+ union {
+ void *p;
+ int64_t n;
+ } u;
+
+ u.p = p;
+ return u.n;
+}
+
+/* convert ptr to number */
+static void *
+n2ptr(int64_t n)
+{
+ union {
+ void *p;
+ int64_t n;
+ } u;
+
+ u.n = n;
+ return u.p;
+}
+
+/* define the constants which relate to the CPP definitions */
+static int
+eawk_httpd_constants(eawk_t *eawk)
+{
+ /* regcomp flags */
+ eawk_define_constant(eawk, "TINY_BUFSIZE", TINY_BUFSIZE);
+ return 1;
+}
+
+/* extension module to provide tiny httpd functionality to eawk */
+
+/* httpd_error function */
+static awkcell_t *
+eawk_httpd_httpd_error(void *veawk, char *name, int argc, awkcell_t **a)
+{
+ eawk_t *eawk = (eawk_t *)veawk;
+ char *s;
+ int rc;
+
+ USE_ARG(name);
+ rc = 1;
+ if (argc == 1) {
+ s = eawk_getsval(eawk, a[0]);
+ fprintf(stderr, "%s", s);
+ }
+ eawk_setfval(eawk, eawk->fp->retval, (awknum_t)rc);
+ return eawk->fp->retval;
+}
+
+/* httpd_client_error function */
+static awkcell_t *
+eawk_httpd_httpd_client_error(void *veawk, char *name, int argc, awkcell_t **a)
+{
+ eawk_t *eawk = (eawk_t *)veawk;
+ FILE *fp;
+ char *cause;
+ const char *errno;
+ const char *shortmsg;
+ const char *longmsg;
+ int rc;
+
+ USE_ARG(name);
+ rc = 1;
+ if (argc == 5) {
+ fp = n2ptr((int64_t)eawk_getfval(eawk, a[0]));
+ cause = eawk_getsval(eawk, a[1]);
+ errno = (const char *)eawk_getsval(eawk, a[2]);
+ shortmsg = (const char *)eawk_getsval(eawk, a[3]);
+ longmsg = (const char *)eawk_getsval(eawk, a[4]);
+ httpd_client_error(fp, cause, errno, shortmsg, longmsg);
+ }
+ eawk_setfval(eawk, eawk->fp->retval, (awknum_t)rc);
+ return eawk->fp->retval;
+}
+
+/* httpd_bind_server function */
+static awkcell_t *
+eawk_httpd_httpd_bind_server(void *veawk, char *name, int argc, awkcell_t **a)
+{
+ const char *family;
+ const char *host;
+ const char *port;
+ eawk_t *eawk = (eawk_t *)veawk;
+ int rc;
+
+ USE_ARG(name);
+ rc = -1;
+ if (argc == 3) {
+ host = (const char *)eawk_getsval(eawk, a[0]);
+ port = (const char *)eawk_getsval(eawk, a[1]);
+ family = (const char *)eawk_getsval(eawk, a[2]);
+ rc = httpd_bind_server(host, port, family);
+ }
+ eawk_setfval(eawk, eawk->fp->retval, (awknum_t)rc);
+ return eawk->fp->retval;
+}
+
+/* httpd_read_request function */
+static awkcell_t *
+eawk_httpd_httpd_read_request(void *veawk, char *name, int argc, awkcell_t **a)
+{
+ eawk_t *eawk = (eawk_t *)veawk;
+ FILE *fp;
+ char uri[TINY_BUFSIZE];
+
+ USE_ARG(name);
+ uri[0] = 0x0;
+ if (argc == 1) {
+ fp = n2ptr((int64_t)eawk_getfval(eawk, a[0]));
+ httpd_read_request(fp, uri);
+ }
+ eawk_setsval(eawk, eawk->fp->retval, uri);
+ return eawk->fp->retval;
+}
+
+/* httpd_parse_uri function */
+static awkcell_t *
+eawk_httpd_httpd_parse_uri(void *veawk, char *name, int argc, awkcell_t **a)
+{
+ const char *cgiargs;
+ eawk_t *eawk = (eawk_t *)veawk;
+ char filename[TINY_BUFSIZE];
+ char *uri;
+
+ USE_ARG(name);
+ filename[0] = 0x0;
+ if (argc == 1) {
+ uri = eawk_getsval(eawk, a[0]);
+ httpd_parse_uri(uri, filename, sizeof(filename), &cgiargs);
+ }
+ eawk_setsval(eawk, eawk->fp->retval, filename);
+ return eawk->fp->retval;
+}
+
+/* httpd_serve_static_content function */
+static awkcell_t *
+eawk_httpd_httpd_serve_static_content(void *veawk, char *name, int argc, awkcell_t **a)
+{
+ eawk_t *eawk = (eawk_t *)veawk;
+ FILE *fp;
+ char *filename;
+ int rc;
+
+ USE_ARG(name);
+ rc = 0;
+ if (argc == 2) {
+ fp = n2ptr((int64_t)eawk_getfval(eawk, a[0]));
+ filename = eawk_getsval(eawk, a[1]);
+ rc = httpd_serve_static_content(fp, filename);
+ }
+ eawk_setfval(eawk, eawk->fp->retval, (awknum_t)rc);
+ return eawk->fp->retval;
+}
+
+/* httpd_serve_dynamic_content function */
+static awkcell_t *
+eawk_httpd_httpd_serve_dynamic_content(void *veawk, char *name, int argc, awkcell_t **a)
+{
+ const char *cgiargs;
+ eawk_t *eawk = (eawk_t *)veawk;
+ FILE *fp;
+ char *filename;
+ int rc;
+
+ USE_ARG(name);
+ rc = 0;
+ if (argc == 3) {
+ fp = n2ptr((int64_t)eawk_getfval(eawk, a[0]));
+ filename = eawk_getsval(eawk, a[1]);
+ cgiargs = (const char *)eawk_getsval(eawk, a[2]);
+ rc = httpd_serve_dynamic_content(fp, filename, cgiargs);
+ }
+ eawk_setfval(eawk, eawk->fp->retval, (awknum_t)rc);
+ return eawk->fp->retval;
+}
+
+/* httpd_get_connection function */
+static awkcell_t *
+eawk_httpd_httpd_get_connection(void *veawk, char *name, int argc, awkcell_t **a)
+{
+ eawk_t *eawk = (eawk_t *)veawk;
+ FILE *fp;
+ int server;
+
+ USE_ARG(name);
+ fp = NULL;
+ if (argc == 1) {
+ server = (int)eawk_getfval(eawk, a[0]);
+ fp = httpd_get_connection(server);
+ }
+ eawk_setfval(eawk, eawk->fp->retval, (awknum_t)p2num(fp));
+ return eawk->fp->retval;
+}
+
+/* httpd_close_client_connection function */
+static awkcell_t *
+eawk_httpd_httpd_close_client_connection(void *veawk, char *name, int argc, awkcell_t **a)
+{
+ eawk_t *eawk = (eawk_t *)veawk;
+ FILE *fp;
+ int rc;
+
+ USE_ARG(name);
+ rc = 0;
+ if (argc == 1) {
+ fp = n2ptr((int64_t)eawk_getfval(eawk, a[0]));
+ rc = httpd_close_client_connection(fp);
+ }
+ eawk_setfval(eawk, eawk->fp->retval, (awknum_t)rc);
+ return eawk->fp->retval;
+}
+
+
+/**************************************************************/
+/* now the glue to register functions when use("httpd") is called */
+/**************************************************************/
+
+int eawk_use_httpd(eawk_t */*eawk*/);
+
+/* register digest functions */
+int
+eawk_use_httpd(eawk_t *eawk)
+{
+ if (eawk_find_lib(eawk, "httpd") < 0) {
+ eawk_httpd_constants(eawk);
+ eawk_register_func(eawk, "httpd", "httpd_error", eawk_httpd_httpd_error);
+ eawk_register_func(eawk, "httpd", "httpd_client_error", eawk_httpd_httpd_client_error);
+ eawk_register_func(eawk, "httpd", "httpd_bind_server", eawk_httpd_httpd_bind_server);
+ eawk_register_func(eawk, "httpd", "httpd_read_request", eawk_httpd_httpd_read_request);
+ eawk_register_func(eawk, "httpd", "httpd_parse_uri", eawk_httpd_httpd_parse_uri);
+ eawk_register_func(eawk, "httpd", "httpd_serve_static_content", eawk_httpd_httpd_serve_static_content);
+ eawk_register_func(eawk, "httpd", "httpd_serve_dynamic_content", eawk_httpd_httpd_serve_dynamic_content);
+ eawk_register_func(eawk, "httpd", "httpd_get_connection", eawk_httpd_httpd_get_connection);
+ eawk_register_func(eawk, "httpd", "httpd_close_client_connection", eawk_httpd_httpd_close_client_connection);
+ }
+ return 1;
+}
\ No newline at end of file
Index: othersrc/external/historical/eawk/extend/httpd/shlib_version
diff -u /dev/null othersrc/external/historical/eawk/extend/httpd/shlib_version:1.1
--- /dev/null Sat Jun 8 10:48:57 2013
+++ othersrc/external/historical/eawk/extend/httpd/shlib_version Sat Jun 8 10:48:57 2013
@@ -0,0 +1,2 @@
+major=0
+minor=0
Index: othersrc/external/historical/eawk/extend/httpd/tiny.c
diff -u /dev/null othersrc/external/historical/eawk/extend/httpd/tiny.c:1.1
--- /dev/null Sat Jun 8 10:48:57 2013
+++ othersrc/external/historical/eawk/extend/httpd/tiny.c Sat Jun 8 10:48:57 2013
@@ -0,0 +1,246 @@
+/*
+ * tiny.c - a minimal HTTP server that serves static and
+ * dynamic content with the GET method. Neither
+ * robust, secure, nor modular. Use for instructional
+ * purposes only.
+ * Dave O'Hallaron, Carnegie Mellon
+ *
+ * usage: tiny <port>
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <netdb.h>
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tiny.h"
+
+#define MAXERRS 16
+
+extern char **environ; /* the environment */
+
+/*
+ * error - wrapper for perror used for bad syscalls
+ */
+void
+httpd_error(const char *msg)
+{
+ perror(msg);
+}
+
+/*
+ * httpd_client_error - returns an error message to the client
+ */
+void
+httpd_client_error(FILE *fp, char *cause, const char *errno, const char *shortmsg, const char *longmsg)
+{
+ fprintf(fp, "HTTP/1.1 %s %s\r\n"
+ "Content-type: text/html\r\n\r\n"
+ "<html><title>Tiny Error</title><body bgcolor=ffffff>\r\n"
+ "%s: %s\r\n"
+ "<p>%s: %s\r\n"
+ "<hr><em>The Tiny Web server</em>\r\n",
+ errno, shortmsg,
+ errno, shortmsg,
+ longmsg, cause);
+}
+
+/* bind to the server address */
+int
+httpd_bind_server(const char *host, const char *port, const char *family)
+{
+ struct addrinfo hints; /* for binding socket */
+ struct addrinfo *res; /* results from getaddrinfo */
+ const int reusable = 1;
+ int server;
+
+ /* bind to server socket */
+ memset(&hints, 0x0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ if (family) {
+ hints.ai_family = (strcasecmp(family, "ipv6") == 0) ? AF_INET6 : AF_INET;
+ }
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
+ if (getaddrinfo(host, port, &hints, &res) < 0) {
+ httpd_error("ERROR with own getaddrinfo");
+ return -1;
+ }
+ if ((server = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) {
+ httpd_error("ERROR opening socket");
+ return -1;
+ }
+ setsockopt(server, SOL_SOCKET, SO_REUSEADDR, (const void *)&reusable, (socklen_t)sizeof(reusable));
+ if (bind(server, res->ai_addr, res->ai_addrlen) < 0) {
+ httpd_error("ERROR on binding");
+ return -1;
+ }
+ if (listen(server, 5) < 0) {
+ httpd_error("ERROR on listen");
+ return -1;
+ }
+ return server;
+}
+
+/* read (and ignore) the HTTP headers */
+int
+httpd_read_request(FILE *clientfp, char *uri)
+{
+ char method[TINY_BUFSIZE];
+ char version[TINY_BUFSIZE]; /* request version */
+ char buf[TINY_BUFSIZE];
+
+ /* get the HTTP request line */
+ fgets(buf, (int)sizeof(buf), clientfp);
+ printf("%s", buf);
+ sscanf(buf, "%s %s %s\n", method, uri, version);
+ /* tiny only supports the GET method */
+ if (strcasecmp(method, "GET") != 0) {
+ httpd_client_error(clientfp, method, "501", "Not Implemented",
+ "Tiny does not implement this method");
+ return 0;
+ }
+ do {
+ fgets(buf, (int)sizeof(buf), clientfp);
+ printf("%s", buf);
+ } while (strcmp(buf, "\r\n") != 0);
+ return 1;
+}
+
+int
+httpd_parse_uri(char *uri, char *filename, size_t size, const char **cgiargs)
+{
+ char *p;
+ int static_content;
+
+ static_content = (strstr(uri, "cgi-bin") == NULL);
+ if (static_content) {
+ *cgiargs = "";
+ snprintf(filename, size, ".%s%s", uri, (uri[strlen(uri) - 1] == '/') ? "index.html" : "");
+ } else {
+ p = strchr(uri, '?');
+ *cgiargs = (p) ? p + 1 : "";
+ snprintf(filename, size, ".%.*s", (p) ? (int)(p - uri) : (int)strlen(uri), uri);
+ }
+ return static_content;
+}
+
+int
+httpd_serve_static_content(FILE *client, char *filename)
+{
+ struct stat st;
+ char *p;
+ int fd;
+
+ if (stat(filename, &st) < 0) {
+ httpd_client_error(client, filename, "404", "Not found", "Tiny couldn't find this file");
+ return 0;
+ }
+ p = strrchr(filename, '.');
+ /* print response header */
+ fprintf(client, "HTTP/1.1 200 OK\r\n"
+ "Server: Tiny Web Server\r\n"
+ "Content-length: %" PRIu64 "\r\n"
+ "Content-type: %s\r\n\r\n",
+ (uint64_t)st.st_size,
+ (p && strcasecmp(p, ".html") == 0) ? "text/html" :
+ (p && strcasecmp(p, ".gif") == 0) ? "image/gif" :
+ (p && strcasecmp(p, ".jpg") == 0) ? "image/jpg" :
+ "text/plain");
+ fflush(client);
+ /* Use mmap to return arbitrary-sized response body */
+ fd = open(filename, O_RDONLY);
+ p = mmap(0, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ fwrite(p, 1, (size_t)st.st_size, client);
+ munmap(p, (size_t)st.st_size);
+ close(fd);
+ return 1;
+}
+
+int
+httpd_serve_dynamic_content(FILE *client, char *filename, const char *cgiargs)
+{
+ struct stat st;
+ char buf[BUFSIZ];
+ int wait_status; /* status from wait */
+ int pid; /* process id from fork */
+
+ if (stat(filename, &st) < 0) {
+ httpd_client_error(client, filename, "404", "Not found", "Tiny couldn't find this file");
+ return 0;
+ }
+ /* make sure file is a regular executable file */
+ if (!(st.st_mode & S_IFREG) || !(st.st_mode & S_IXUSR)) {
+ httpd_client_error(client, filename, "403", "Forbidden",
+ "You are not allow to access this item");
+ return 0;
+ }
+ /* set other CGI environ vars as well */
+ setenv("QUERY_STRING", cgiargs, 1);
+ /* print first part of response header */
+ snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\r\nServer: Tiny Web Server\r\n");
+ write(fileno(client), buf, strlen(buf));
+ switch(pid = fork()) {
+ case -1:
+ perror("ERROR in fork");
+ exit(EXIT_FAILURE);
+ /*NOTREACHED*/
+ case 0:
+ /* child process */
+ close(STDIN_FILENO);
+ dup2(fileno(client), STDOUT_FILENO);
+ dup2(fileno(client), STDERR_FILENO);
+ if (execve(filename, NULL, environ) < 0) {
+ perror("ERROR in execve");
+ }
+ break;
+ default:
+ /* parent process */
+ if (wait(&wait_status) != pid) {
+ }
+ break;
+ }
+ return 1;
+}
+
+FILE *
+httpd_get_connection(int server)
+{
+ struct sockaddr clientaddr; /* client addr */
+ socklen_t clientlen; /* byte size of client's address */
+ FILE *clientfp;
+ char buf[TINY_BUFSIZE]; /* message buffer */
+ int client;
+
+ clientlen = sizeof(clientaddr);
+ if ((client = accept(server, &clientaddr, &clientlen)) < 0)
+ httpd_error("ERROR on accept");
+ if (getnameinfo(&clientaddr, (socklen_t)clientaddr.sa_len, buf,
+ (socklen_t)sizeof(buf), NULL, 0, NI_NUMERICHOST) < 0)
+ httpd_error("ERROR on getnameinfo");
+ printf("Client request from: %s\n", buf);
+ if ((clientfp = fdopen(client, "r+")) == NULL)
+ httpd_error("ERROR on fdopen");
+ return clientfp;
+}
+
+/* close the client connection */
+int
+httpd_close_client_connection(FILE *client)
+{
+ fclose(client);
+ return 1;
+}
Index: othersrc/external/historical/eawk/extend/httpd/tiny.h
diff -u /dev/null othersrc/external/historical/eawk/extend/httpd/tiny.h:1.1
--- /dev/null Sat Jun 8 10:48:57 2013
+++ othersrc/external/historical/eawk/extend/httpd/tiny.h Sat Jun 8 10:48:57 2013
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2013 Alistair Crooks <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TINY_H_
+#define TINY_H_ 20130607
+
+#include <stdio.h>
+
+#define TINY_BUFSIZE 1024
+
+void httpd_error(const char */*msg*/);
+void httpd_client_error(FILE */*fp*/, char */*cause*/, const char */*errno*/, const char */*shortmsg*/, const char */*longmsg*/);
+int httpd_bind_server(const char */*host*/, const char */*port*/, const char */*family*/);
+int httpd_read_request(FILE */*clientfp*/, char */*uri*/);
+int httpd_parse_uri(char */*uri*/, char */*filename*/, size_t /*size*/, const char **/*cgiargs*/);
+int httpd_serve_static_content(FILE */*clientfp*/, char */*filename*/);
+int httpd_serve_dynamic_content(FILE */*clientfp*/, char */*filename*/, const char */*cgiargs*/);
+FILE *httpd_get_connection(int /*server*/);
+int httpd_close_client_connection(FILE */*client*/);
+
+#endif
Index: othersrc/external/historical/eawk/scripts/httpd.sh
diff -u /dev/null othersrc/external/historical/eawk/scripts/httpd.sh:1.1
--- /dev/null Sat Jun 8 10:48:57 2013
+++ othersrc/external/historical/eawk/scripts/httpd.sh Sat Jun 8 10:48:57 2013
@@ -0,0 +1,19 @@
+#! /bin/sh
+
+port=80
+if [ $# -gt 0 ]; then
+ port=$1
+fi
+
+env LD_LIBRARY_PATH=lib:extend/httpd bin/eawk -v port=${port} '
+BEGIN {
+ use("httpd")
+ server = httpd_bind_server("localhost", port, "ipv4")
+ while (1) {
+ client = httpd_get_connection(server);
+ uri = httpd_read_request(client);
+ filename = httpd_parse_uri(uri)
+ httpd_serve_static_content(client, filename);
+ httpd_close_client_connection(client);
+ }
+}'
Index: othersrc/external/historical/eawk/scripts/json.sh
diff -u /dev/null othersrc/external/historical/eawk/scripts/json.sh:1.1
--- /dev/null Sat Jun 8 10:48:57 2013
+++ othersrc/external/historical/eawk/scripts/json.sh Sat Jun 8 10:48:57 2013
@@ -0,0 +1,42 @@
+#! /bin/sh
+
+env LD_LIBRARY_PATH=lib:extend/c bin/eawk '
+function pnumber(n) {
+ printf("%g", n)
+}
+function pstring(s) {
+ printf("\"%s\"", s)
+}
+function pobject(k, v) {
+ printf("{")
+ pstring(k)
+ printf(":")
+ pstring(v)
+ printf("}")
+}
+function parray(a) {
+ alen = asorti(a, sa)
+ printf("[");
+ for (i = 1 ; i <= alen ; i++) {
+ pobject(sa[i], a[sa[i]])
+ if (i < alen)
+ printf(",");
+ }
+ printf("]");
+}
+function json_print(type, obj, val) {
+ if (type == "array") parray(obj)
+ if (type == "object") pobject(obj, val)
+ if (type == "string") pstring(obj)
+ if (type == "number") pnumber(obj)
+ printf("\n");
+}
+BEGIN {
+ use("c");
+ a[1] = "one"; a[2] = "two"; a[0] = "zero"; a[4] = "four"; a[3] = "three"; a[5] ="five"; a[6] = "six";
+ json_print("number", 1)
+ json_print("string", a[1])
+ json_print("object", 1, a[1])
+ json_print("array", a)
+}
+'