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 <a...@netbsd.org> + * 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 <a...@netbsd.org> + * 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) +} +'