uhttpd: switch to external git repo + cmake build system
authorJo-Philipp Wich <jow@openwrt.org>
Mon, 15 Oct 2012 12:31:33 +0000 (12:31 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Mon, 15 Oct 2012 12:31:33 +0000 (12:31 +0000)
SVN-Revision: 33775

17 files changed:
package/network/services/uhttpd/Makefile
package/network/services/uhttpd/src/Makefile [deleted file]
package/network/services/uhttpd/src/uhttpd-cgi.c [deleted file]
package/network/services/uhttpd/src/uhttpd-cgi.h [deleted file]
package/network/services/uhttpd/src/uhttpd-file.c [deleted file]
package/network/services/uhttpd/src/uhttpd-file.h [deleted file]
package/network/services/uhttpd/src/uhttpd-lua.c [deleted file]
package/network/services/uhttpd/src/uhttpd-lua.h [deleted file]
package/network/services/uhttpd/src/uhttpd-mimetypes.h [deleted file]
package/network/services/uhttpd/src/uhttpd-tls.c [deleted file]
package/network/services/uhttpd/src/uhttpd-tls.h [deleted file]
package/network/services/uhttpd/src/uhttpd-ubus.c [deleted file]
package/network/services/uhttpd/src/uhttpd-ubus.h [deleted file]
package/network/services/uhttpd/src/uhttpd-utils.c [deleted file]
package/network/services/uhttpd/src/uhttpd-utils.h [deleted file]
package/network/services/uhttpd/src/uhttpd.c [deleted file]
package/network/services/uhttpd/src/uhttpd.h [deleted file]

index 245426b..b2f0879 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2010-2012 Jo-Philipp Wich <xm@subsignal.org>
+# Copyright (C) 2010-2012 Jo-Philipp Wich <jow@openwrt.org>
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,9 +8,16 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=uhttpd
-PKG_RELEASE:=40
+PKG_VERSION:=2012-10-15
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://nbd.name/uhttpd.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=fa43d1a62864f912e4450affb9c86f3accbe026a
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
 
-PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
 PKG_CONFIG_DEPENDS := \
        CONFIG_PACKAGE_uhttpd_debug \
        CONFIG_PACKAGE_uhttpd-mod-lua \
@@ -20,13 +27,14 @@ PKG_CONFIG_DEPENDS := \
        CONFIG_PACKAGE_uhttpd-mod-ubus
 
 include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
 
 define Package/uhttpd/default
   SECTION:=net
   CATEGORY:=Network
   SUBMENU:=Web Servers/Proxies
   TITLE:=uHTTPd - tiny, single threaded HTTP server
-  MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org>
 endef
 
 define Package/uhttpd
@@ -71,19 +79,18 @@ define Package/uhttpd-mod-tls/config
   endchoice
 endef
 
-UHTTPD_TLS:=
+UHTTPD_TLS:=none
 TLS_CFLAGS:=
 TLS_LDFLAGS:=
 
 ifneq ($(CONFIG_PACKAGE_uhttpd-mod-tls_cyassl),)
   UHTTPD_TLS:=cyassl
-  TLS_CFLAGS:=-I$(STAGING_DIR)/usr/include/cyassl -DTLS_IS_CYASSL
+  TLS_CFLAGS:=-I$(STAGING_DIR)/usr/include/cyassl
   TLS_LDFLAGS:=-lcyassl -lm
 endif
 
 ifneq ($(CONFIG_PACKAGE_uhttpd-mod-tls_openssl),)
   UHTTPD_TLS:=openssl
-  TLS_CFLAGS:=-DTLS_IS_OPENSSL
   TLS_LDFLAGS:=-lssl
 endif
 
@@ -111,21 +118,16 @@ define Package/uhttpd-mod-ubus/description
 endef
 
 
-TARGET_CFLAGS += $(TLS_CFLAGS) $(if $(CONFIG_PACKAGE_uhttpd_debug),-DDEBUG) -ggdb3
-TARGET_LDFLAGS += -lubox -Wl,-rpath-link=$(STAGING_DIR)/usr/lib
-MAKE_VARS += \
-       FPIC="$(FPIC)" \
-       LUA_SUPPORT="$(if $(CONFIG_PACKAGE_uhttpd-mod-lua),1)" \
-       TLS_SUPPORT="$(if $(CONFIG_PACKAGE_uhttpd-mod-tls),1)" \
-       UBUS_SUPPORT="$(if $(CONFIG_PACKAGE_uhttpd-mod-ubus),1)" \
-       UHTTPD_TLS="$(UHTTPD_TLS)" \
-       TLS_CFLAGS="$(TLS_CFLAGS)" \
-       TLS_LDFLAGS="$(TLS_LDFLAGS)"
+TARGET_LDFLAGS += -lubox -lcrypt
+
+CMAKE_OPTIONS += \
+       -DDEBUG=$(if $(CONFIG_PACKAGE_uhttpd_debug),ON,OFF) \
+       -DLUA_SUPPORT=$(if $(CONFIG_PACKAGE_uhttpd-mod-lua),ON,OFF) \
+       -DUBUS_SUPPORT=$(if $(CONFIG_PACKAGE_uhttpd-mod-ubus),ON,OFF) \
+       -DTLS_SUPPORT=$(UHTTPD_TLS) \
+       -DTLS_CFLAGS="$(TLS_CFLAGS)" \
+       -DTLS_LDFLAGS="$(TLS_LDFLAGS)" \
 
-define Build/Prepare
-       mkdir -p $(PKG_BUILD_DIR)
-       $(CP) ./src/* $(PKG_BUILD_DIR)/
-endef
 
 define Package/uhttpd/conffiles
 /etc/config/uhttpd
diff --git a/package/network/services/uhttpd/src/Makefile b/package/network/services/uhttpd/src/Makefile
deleted file mode 100644 (file)
index 98226ed..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-CGI_SUPPORT ?= 1
-LUA_SUPPORT ?= 1
-TLS_SUPPORT ?= 1
-UHTTPD_TLS ?= cyassl
-
-CFLAGS ?= -I./lua-5.1.4/src $(TLS_CFLAGS) -O0 -ggdb3
-LDFLAGS ?= -L./lua-5.1.4/src
-
-CFLAGS += -Wall --std=gnu99
-
-ifeq ($(UHTTPD_TLS),openssl)
-  TLS_LDFLAGS ?= -L./openssl-0.9.8m -lssl
-  TLS_CFLAGS ?= -I./openssl-0.9.8m/include -DTLS_IS_OPENSSL
-else
-  TLS_LDFLAGS ?= -L./cyassl-1.4.0/src/.libs -lcyassl
-  TLS_CFLAGS ?= -I./cyassl-1.4.0/include -DTLS_IS_CYASSL
-endif
-
-OBJ := uhttpd.o uhttpd-file.o uhttpd-utils.o
-LIB := -Wl,--export-dynamic -lcrypt -ldl
-
-TLSLIB :=
-LUALIB :=
-
-HAVE_SHADOW=$(shell echo 'int main(void){ return !getspnam("root"); }' | \
-       $(CC) -include shadow.h -xc -o/dev/null - 2>/dev/null && echo yes)
-
-ifeq ($(HAVE_SHADOW),yes)
-  CFLAGS += -DHAVE_SHADOW
-endif
-
-ifeq ($(TLS_SUPPORT),1)
-  CFLAGS += -DHAVE_TLS
-endif
-
-ifeq ($(CGI_SUPPORT),1)
-  CFLAGS += -DHAVE_CGI
-endif
-
-ifeq ($(LUA_SUPPORT),1)
-  CFLAGS += -DHAVE_LUA
-endif
-
-ifeq ($(UBUS_SUPPORT),1)
-  CFLAGS += -DHAVE_UBUS
-endif
-
-
-world: compile
-
-ifeq ($(CGI_SUPPORT),1)
-  OBJ += uhttpd-cgi.o
-endif
-
-ifeq ($(LUA_SUPPORT),1)
-  LUALIB := uhttpd_lua.so
-
-  $(LUALIB): uhttpd-lua.c
-               $(CC) $(CFLAGS) $(LDFLAGS) $(FPIC) \
-                       -shared -lm -llua -ldl \
-                       -o $(LUALIB) uhttpd-lua.c
-endif
-
-ifeq ($(TLS_SUPPORT),1)
-  TLSLIB := uhttpd_tls.so
-
-  $(TLSLIB): uhttpd-tls.c
-               $(CC) $(CFLAGS) $(LDFLAGS) $(FPIC) \
-                       -shared $(TLS_LDFLAGS) \
-                       -o $(TLSLIB) uhttpd-tls.c
-endif
-
-ifeq ($(UBUS_SUPPORT),1)
-  UBUSLIB := uhttpd_ubus.so
-
-  $(UBUSLIB): uhttpd-ubus.c
-               $(CC) $(CFLAGS) $(LDFLAGS) $(FPIC) \
-                       -shared -lubus -ljson -lblobmsg_json \
-                       -o $(UBUSLIB) uhttpd-ubus.c
-endif
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $<
-
-compile: $(OBJ) $(TLSLIB) $(LUALIB) $(UBUSLIB)
-       $(CC) -o uhttpd $(LDFLAGS) $(OBJ) $(LIB)
-
-clean:
-       rm -f *.o *.so uhttpd
diff --git a/package/network/services/uhttpd/src/uhttpd-cgi.c b/package/network/services/uhttpd/src/uhttpd-cgi.c
deleted file mode 100644 (file)
index 69af90d..0000000
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - CGI handler
- *
- *   Copyright (C) 2010-2012 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#include "uhttpd.h"
-#include "uhttpd-utils.h"
-#include "uhttpd-cgi.h"
-
-
-static bool
-uh_cgi_header_parse(struct http_response *res, char *buf, int len, int *off)
-{
-       char *bufptr = NULL;
-       char *hdrname = NULL;
-       int hdrcount = 0;
-       int pos = 0;
-
-       if (((bufptr = strfind(buf, len, "\r\n\r\n", 4)) != NULL) ||
-           ((bufptr = strfind(buf, len, "\n\n", 2)) != NULL))
-       {
-               *off = (int)(bufptr - buf) + ((bufptr[0] == '\r') ? 4 : 2);
-
-               memset(res, 0, sizeof(*res));
-
-               res->statuscode = 200;
-               res->statusmsg  = "OK";
-
-               bufptr = &buf[0];
-
-               for (pos = 0; pos < *off; pos++)
-               {
-                       if (!hdrname && (buf[pos] == ':'))
-                       {
-                               buf[pos++] = 0;
-
-                               if ((pos < len) && (buf[pos] == ' '))
-                                       pos++;
-
-                               if (pos < len)
-                               {
-                                       hdrname = bufptr;
-                                       bufptr = &buf[pos];
-                               }
-                       }
-
-                       else if ((buf[pos] == '\r') || (buf[pos] == '\n'))
-                       {
-                               if (! hdrname)
-                                       break;
-
-                               buf[pos++] = 0;
-
-                               if ((pos < len) && (buf[pos] == '\n'))
-                                       pos++;
-
-                               if (pos <= len)
-                               {
-                                       if ((hdrcount+1) < array_size(res->headers))
-                                       {
-                                               if (!strcasecmp(hdrname, "Status"))
-                                               {
-                                                       res->statuscode = atoi(bufptr);
-
-                                                       if (res->statuscode < 100)
-                                                               res->statuscode = 200;
-
-                                                       if (((bufptr = strchr(bufptr, ' ')) != NULL) &&
-                                                               (&bufptr[1] != 0))
-                                                       {
-                                                               res->statusmsg = &bufptr[1];
-                                                       }
-
-                                                       D("CGI: HTTP/1.x %03d %s\n",
-                                                         res->statuscode, res->statusmsg);
-                                               }
-                                               else
-                                               {
-                                                       D("CGI: HTTP: %s: %s\n", hdrname, bufptr);
-
-                                                       res->headers[hdrcount++] = hdrname;
-                                                       res->headers[hdrcount++] = bufptr;
-                                               }
-
-                                               bufptr = &buf[pos];
-                                               hdrname = NULL;
-                                       }
-                                       else
-                                       {
-                                               return false;
-                                       }
-                               }
-                       }
-               }
-
-               return true;
-       }
-
-       return false;
-}
-
-static char * uh_cgi_header_lookup(struct http_response *res,
-                                                                  const char *hdrname)
-{
-       int i;
-
-       foreach_header(i, res->headers)
-       {
-               if (!strcasecmp(res->headers[i], hdrname))
-                       return res->headers[i+1];
-       }
-
-       return NULL;
-}
-
-static void uh_cgi_shutdown(struct uh_cgi_state *state)
-{
-       free(state);
-}
-
-static bool uh_cgi_socket_cb(struct client *cl)
-{
-       int i, len, blen, hdroff;
-       char buf[UH_LIMIT_MSGHEAD];
-
-       struct uh_cgi_state *state = (struct uh_cgi_state *)cl->priv;
-       struct http_response *res = &cl->response;
-       struct http_request *req = &cl->request;
-
-       /* there is unread post data waiting */
-       while (state->content_length > 0)
-       {
-               /* remaining data in http head buffer ... */
-               if (cl->httpbuf.len > 0)
-               {
-                       len = min(state->content_length, cl->httpbuf.len);
-
-                       D("CGI: Child(%d) feed %d HTTP buffer bytes\n", cl->proc.pid, len);
-
-                       memcpy(buf, cl->httpbuf.ptr, len);
-
-                       cl->httpbuf.len -= len;
-                       cl->httpbuf.ptr +=len;
-               }
-
-               /* read it from socket ... */
-               else
-               {
-                       len = uh_tcp_recv(cl, buf,
-                                                         min(state->content_length, sizeof(buf)));
-
-                       if ((len < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
-                               break;
-
-                       D("CGI: Child(%d) feed %d/%d TCP socket bytes\n",
-                         cl->proc.pid, len, min(state->content_length, sizeof(buf)));
-               }
-
-               if (len)
-                       state->content_length -= len;
-               else
-                       state->content_length = 0;
-
-               /* ... write to CGI process */
-               len = uh_raw_send(cl->wpipe.fd, buf, len,
-                                                 cl->server->conf->script_timeout);
-
-               /* explicit EOF notification for the child */
-               if (state->content_length <= 0)
-                       uh_ufd_remove(&cl->wpipe);
-       }
-
-       /* try to read data from child */
-       while ((len = uh_raw_recv(cl->rpipe.fd, buf, state->header_sent
-                                 ? sizeof(buf) : state->httpbuf.len, -1)) > 0)
-       {
-               /* we have not pushed out headers yet, parse input */
-               if (!state->header_sent)
-               {
-                       /* try to parse header ... */
-                       memcpy(state->httpbuf.ptr, buf, len);
-                       state->httpbuf.len -= len;
-                       state->httpbuf.ptr += len;
-
-                       blen = state->httpbuf.ptr - state->httpbuf.buf;
-
-                       if (uh_cgi_header_parse(res, state->httpbuf.buf, blen, &hdroff))
-                       {
-                               /* write status */
-                               ensure_out(uh_http_sendf(cl, NULL,
-                                       "%s %03d %s\r\n"
-                                       "Connection: close\r\n",
-                                       http_versions[req->version],
-                                       res->statuscode, res->statusmsg));
-
-                               /* add Content-Type if no Location or Content-Type */
-                               if (!uh_cgi_header_lookup(res, "Location") &&
-                                       !uh_cgi_header_lookup(res, "Content-Type"))
-                               {
-                                       ensure_out(uh_http_send(cl, NULL,
-                                               "Content-Type: text/plain\r\n", -1));
-                               }
-
-                               /* if request was HTTP 1.1 we'll respond chunked */
-                               if ((req->version > UH_HTTP_VER_1_0) &&
-                                       !uh_cgi_header_lookup(res, "Transfer-Encoding"))
-                               {
-                                       ensure_out(uh_http_send(cl, NULL,
-                                               "Transfer-Encoding: chunked\r\n", -1));
-                               }
-
-                               /* write headers from CGI program */
-                               foreach_header(i, res->headers)
-                               {
-                                       ensure_out(uh_http_sendf(cl, NULL, "%s: %s\r\n",
-                                               res->headers[i], res->headers[i+1]));
-                               }
-
-                               /* terminate header */
-                               ensure_out(uh_http_send(cl, NULL, "\r\n", -1));
-
-                               state->header_sent = true;
-
-                               /* push out remaining head buffer */
-                               if (hdroff < blen)
-                               {
-                                       D("CGI: Child(%d) relaying %d rest bytes\n",
-                                         cl->proc.pid, blen - hdroff);
-
-                                       ensure_out(uh_http_send(cl, req,
-                                                               state->httpbuf.buf + hdroff,
-                                                               blen - hdroff));
-                               }
-                       }
-
-                       /* ... failed and head buffer exceeded */
-                       else if (!state->httpbuf.len)
-                       {
-                               /* I would do this ...
-                                *
-                                *    uh_cgi_error_500(cl, req,
-                                *        "The CGI program generated an "
-                                *        "invalid response:\n\n");
-                                *
-                                * ... but in order to stay as compatible as possible,
-                                * treat whatever we got as text/plain response and
-                                * build the required headers here.
-                                */
-
-                               ensure_out(uh_http_sendf(cl, NULL,
-                                                                                "%s 200 OK\r\n"
-                                                                                "Content-Type: text/plain\r\n"
-                                                                                "%s\r\n",
-                                                                                http_versions[req->version],
-                                                                                (req->version > UH_HTTP_VER_1_0)
-                                                                                ? "Transfer-Encoding: chunked\r\n" : ""
-                               ));
-
-                               state->header_sent = true;
-
-                               D("CGI: Child(%d) relaying %d invalid bytes\n",
-                                 cl->proc.pid, len);
-
-                               ensure_out(uh_http_send(cl, req, buf, len));
-                       }
-               }
-               else
-               {
-                       /* headers complete, pass through buffer to socket */
-                       D("CGI: Child(%d) relaying %d normal bytes\n", cl->proc.pid, len);
-                       ensure_out(uh_http_send(cl, req, buf, len));
-               }
-       }
-
-       /* got EOF or read error from child */
-       if ((len == 0) ||
-               ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (len == -1)))
-       {
-               D("CGI: Child(%d) presumed dead [%s]\n", cl->proc.pid, strerror(errno));
-
-               goto out;
-       }
-
-       return true;
-
-out:
-       if (!state->header_sent)
-       {
-               if (cl->timeout.pending)
-                       uh_http_sendhf(cl, 502, "Bad Gateway",
-                                                  "The CGI process did not produce any response\n");
-               else
-                       uh_http_sendhf(cl, 504, "Gateway Timeout",
-                                                  "The CGI process took too long to produce a "
-                                                  "response\n");
-       }
-       else
-       {
-               uh_http_send(cl, req, "", 0);
-       }
-
-       uh_cgi_shutdown(state);
-       return false;
-}
-
-bool uh_cgi_request(struct client *cl, struct path_info *pi,
-                                       struct interpreter *ip)
-{
-       int i;
-
-       int rfd[2] = { 0, 0 };
-       int wfd[2] = { 0, 0 };
-
-       pid_t child;
-
-       struct uh_cgi_state *state;
-       struct http_request *req = &cl->request;
-
-       /* allocate state */
-       if (!(state = malloc(sizeof(*state))))
-       {
-               uh_http_sendhf(cl, 500, "Internal Server Error", "Out of memory");
-               return false;
-       }
-
-       /* spawn pipes for me->child, child->me */
-       if ((pipe(rfd) < 0) || (pipe(wfd) < 0))
-       {
-               if (rfd[0] > 0) close(rfd[0]);
-               if (rfd[1] > 0) close(rfd[1]);
-               if (wfd[0] > 0) close(wfd[0]);
-               if (wfd[1] > 0) close(wfd[1]);
-
-               uh_http_sendhf(cl, 500, "Internal Server Error",
-                                               "Failed to create pipe: %s\n", strerror(errno));
-
-               return false;
-       }
-
-       /* fork off child process */
-       switch ((child = fork()))
-       {
-       /* oops */
-       case -1:
-               uh_http_sendhf(cl, 500, "Internal Server Error",
-                                               "Failed to fork child: %s\n", strerror(errno));
-
-               return false;
-
-       /* exec child */
-       case 0:
-#ifdef DEBUG
-               sleep(atoi(getenv("UHTTPD_SLEEP_ON_FORK") ?: "0"));
-#endif
-
-               /* do not leak parent epoll descriptor */
-               uloop_done();
-
-               /* close loose pipe ends */
-               close(rfd[0]);
-               close(wfd[1]);
-
-               /* patch stdout and stdin to pipes */
-               dup2(rfd[1], 1);
-               dup2(wfd[0], 0);
-
-               /* avoid leaking our pipe into child-child processes */
-               fd_cloexec(rfd[1]);
-               fd_cloexec(wfd[0]);
-
-               /* check for regular, world-executable file _or_ interpreter */
-               if (((pi->stat.st_mode & S_IFREG) &&
-                        (pi->stat.st_mode & S_IXOTH)) || (ip != NULL))
-               {
-                       /* build environment */
-                       clearenv();
-
-                       /* common information */
-                       setenv("GATEWAY_INTERFACE", "CGI/1.1", 1);
-                       setenv("SERVER_SOFTWARE", "uHTTPd", 1);
-                       setenv("PATH", "/sbin:/usr/sbin:/bin:/usr/bin", 1);
-
-#ifdef HAVE_TLS
-                       /* https? */
-                       if (cl->tls)
-                               setenv("HTTPS", "on", 1);
-#endif
-
-                       /* addresses */
-                       setenv("SERVER_NAME", sa_straddr(&cl->servaddr), 1);
-                       setenv("SERVER_ADDR", sa_straddr(&cl->servaddr), 1);
-                       setenv("SERVER_PORT", sa_strport(&cl->servaddr), 1);
-                       setenv("REMOTE_HOST", sa_straddr(&cl->peeraddr), 1);
-                       setenv("REMOTE_ADDR", sa_straddr(&cl->peeraddr), 1);
-                       setenv("REMOTE_PORT", sa_strport(&cl->peeraddr), 1);
-
-                       /* path information */
-                       setenv("SCRIPT_NAME", pi->name, 1);
-                       setenv("SCRIPT_FILENAME", pi->phys, 1);
-                       setenv("DOCUMENT_ROOT", pi->root, 1);
-                       setenv("QUERY_STRING", pi->query ? pi->query : "", 1);
-
-                       if (pi->info)
-                               setenv("PATH_INFO", pi->info, 1);
-
-                       /* REDIRECT_STATUS, php-cgi wants it */
-                       switch (req->redirect_status)
-                       {
-                               case 404:
-                                       setenv("REDIRECT_STATUS", "404", 1);
-                                       break;
-
-                               default:
-                                       setenv("REDIRECT_STATUS", "200", 1);
-                                       break;
-                       }
-
-                       /* http version */
-                       setenv("SERVER_PROTOCOL", http_versions[req->version], 1);
-
-                       /* request method */
-                       setenv("REQUEST_METHOD", http_methods[req->method], 1);
-
-                       /* request url */
-                       setenv("REQUEST_URI", req->url, 1);
-
-                       /* remote user */
-                       if (req->realm)
-                               setenv("REMOTE_USER", req->realm->user, 1);
-
-                       /* request message headers */
-                       foreach_header(i, req->headers)
-                       {
-                               if (!strcasecmp(req->headers[i], "Accept"))
-                                       setenv("HTTP_ACCEPT", req->headers[i+1], 1);
-
-                               else if (!strcasecmp(req->headers[i], "Accept-Charset"))
-                                       setenv("HTTP_ACCEPT_CHARSET", req->headers[i+1], 1);
-
-                               else if (!strcasecmp(req->headers[i], "Accept-Encoding"))
-                                       setenv("HTTP_ACCEPT_ENCODING", req->headers[i+1], 1);
-
-                               else if (!strcasecmp(req->headers[i], "Accept-Language"))
-                                       setenv("HTTP_ACCEPT_LANGUAGE", req->headers[i+1], 1);
-
-                               else if (!strcasecmp(req->headers[i], "Authorization"))
-                                       setenv("HTTP_AUTHORIZATION", req->headers[i+1], 1);
-
-                               else if (!strcasecmp(req->headers[i], "Connection"))
-                                       setenv("HTTP_CONNECTION", req->headers[i+1], 1);
-
-                               else if (!strcasecmp(req->headers[i], "Cookie"))
-                                       setenv("HTTP_COOKIE", req->headers[i+1], 1);
-
-                               else if (!strcasecmp(req->headers[i], "Host"))
-                                       setenv("HTTP_HOST", req->headers[i+1], 1);
-
-                               else if (!strcasecmp(req->headers[i], "Referer"))
-                                       setenv("HTTP_REFERER", req->headers[i+1], 1);
-
-                               else if (!strcasecmp(req->headers[i], "User-Agent"))
-                                       setenv("HTTP_USER_AGENT", req->headers[i+1], 1);
-
-                               else if (!strcasecmp(req->headers[i], "Content-Type"))
-                                       setenv("CONTENT_TYPE", req->headers[i+1], 1);
-
-                               else if (!strcasecmp(req->headers[i], "Content-Length"))
-                                       setenv("CONTENT_LENGTH", req->headers[i+1], 1);
-                       }
-
-
-                       /* execute child code ... */
-                       if (chdir(pi->root))
-                               perror("chdir()");
-
-                       if (ip != NULL)
-                               execl(ip->path, ip->path, pi->phys, NULL);
-                       else
-                               execl(pi->phys, pi->phys, NULL);
-
-                       /* in case it fails ... */
-                       printf("Status: 500 Internal Server Error\r\n\r\n"
-                                  "Unable to launch the requested CGI program:\n"
-                                  "  %s: %s\n", ip ? ip->path : pi->phys, strerror(errno));
-               }
-
-               /* 403 */
-               else
-               {
-                       printf("Status: 403 Forbidden\r\n\r\n"
-                                  "Access to this resource is forbidden\n");
-               }
-
-               close(wfd[0]);
-               close(rfd[1]);
-               exit(0);
-
-               break;
-
-       /* parent; handle I/O relaying */
-       default:
-               memset(state, 0, sizeof(*state));
-
-               cl->rpipe.fd = rfd[0];
-               cl->wpipe.fd = wfd[1];
-               cl->proc.pid = child;
-
-               /* make pipe non-blocking */
-               fd_nonblock(cl->rpipe.fd);
-               fd_nonblock(cl->wpipe.fd);
-
-               /* close unneeded pipe ends */
-               close(rfd[1]);
-               close(wfd[0]);
-
-               D("CGI: Child(%d) created: rfd(%d) wfd(%d)\n", child, rfd[0], wfd[1]);
-
-               state->httpbuf.ptr = state->httpbuf.buf;
-               state->httpbuf.len = sizeof(state->httpbuf.buf);
-
-               state->content_length = cl->httpbuf.len;
-
-               /* find content length */
-               if (req->method == UH_HTTP_MSG_POST)
-               {
-                       foreach_header(i, req->headers)
-                       {
-                               if (!strcasecmp(req->headers[i], "Content-Length"))
-                               {
-                                       state->content_length = atoi(req->headers[i+1]);
-                                       break;
-                               }
-                       }
-               }
-
-               cl->cb = uh_cgi_socket_cb;
-               cl->priv = state;
-
-               break;
-       }
-
-       return true;
-}
diff --git a/package/network/services/uhttpd/src/uhttpd-cgi.h b/package/network/services/uhttpd/src/uhttpd-cgi.h
deleted file mode 100644 (file)
index c7094da..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - CGI header
- *
- *   Copyright (C) 2010-2012 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#ifndef _UHTTPD_CGI_
-
-#include <errno.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <linux/limits.h>
-
-#include <time.h>
-
-
-struct uh_cgi_state {
-       struct {
-               char buf[UH_LIMIT_MSGHEAD];
-               char *ptr;
-               int len;
-       } httpbuf;
-       int content_length;
-       bool header_sent;
-};
-
-bool uh_cgi_request(struct client *cl, struct path_info *pi,
-                                       struct interpreter *ip);
-
-#endif
diff --git a/package/network/services/uhttpd/src/uhttpd-file.c b/package/network/services/uhttpd/src/uhttpd-file.c
deleted file mode 100644 (file)
index 0bafc2b..0000000
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - Static file handler
- *
- *   Copyright (C) 2010-2012 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#define _XOPEN_SOURCE 500      /* strptime() */
-#define _BSD_SOURCE                    /* scandir(), timegm() */
-
-#include "uhttpd.h"
-#include "uhttpd-utils.h"
-#include "uhttpd-file.h"
-
-#include "uhttpd-mimetypes.h"
-
-
-static const char * uh_file_mime_lookup(const char *path)
-{
-       struct mimetype *m = &uh_mime_types[0];
-       const char *e;
-
-       while (m->extn)
-       {
-               e = &path[strlen(path)-1];
-
-               while (e >= path)
-               {
-                       if ((*e == '.' || *e == '/') && !strcasecmp(&e[1], m->extn))
-                               return m->mime;
-
-                       e--;
-               }
-
-               m++;
-       }
-
-       return "application/octet-stream";
-}
-
-static const char * uh_file_mktag(struct stat *s)
-{
-       static char tag[128];
-
-       snprintf(tag, sizeof(tag), "\"%x-%x-%x\"",
-                        (unsigned int) s->st_ino,
-                        (unsigned int) s->st_size,
-                        (unsigned int) s->st_mtime);
-
-       return tag;
-}
-
-static time_t uh_file_date2unix(const char *date)
-{
-       struct tm t;
-
-       memset(&t, 0, sizeof(t));
-
-       if (strptime(date, "%a, %d %b %Y %H:%M:%S %Z", &t) != NULL)
-               return timegm(&t);
-
-       return 0;
-}
-
-static char * uh_file_unix2date(time_t ts)
-{
-       static char str[128];
-       struct tm *t = gmtime(&ts);
-
-       strftime(str, sizeof(str), "%a, %d %b %Y %H:%M:%S GMT", t);
-
-       return str;
-}
-
-static char * uh_file_header_lookup(struct client *cl, const char *name)
-{
-       int i;
-
-       foreach_header(i, cl->request.headers)
-       {
-               if (!strcasecmp(cl->request.headers[i], name))
-                       return cl->request.headers[i+1];
-       }
-
-       return NULL;
-}
-
-
-static int uh_file_response_ok_hdrs(struct client *cl, struct stat *s)
-{
-       ensure_ret(uh_http_sendf(cl, NULL, "Connection: close\r\n"));
-
-       if (s)
-       {
-               ensure_ret(uh_http_sendf(cl, NULL, "ETag: %s\r\n", uh_file_mktag(s)));
-               ensure_ret(uh_http_sendf(cl, NULL, "Last-Modified: %s\r\n",
-                                                                uh_file_unix2date(s->st_mtime)));
-       }
-
-       return uh_http_sendf(cl, NULL, "Date: %s\r\n", uh_file_unix2date(time(NULL)));
-}
-
-static int uh_file_response_200(struct client *cl, struct stat *s)
-{
-       ensure_ret(uh_http_sendf(cl, NULL, "%s 200 OK\r\n",
-                                                        http_versions[cl->request.version]));
-
-       return uh_file_response_ok_hdrs(cl, s);
-}
-
-static int uh_file_response_304(struct client *cl, struct stat *s)
-{
-       ensure_ret(uh_http_sendf(cl, NULL, "%s 304 Not Modified\r\n",
-                                                        http_versions[cl->request.version]));
-
-       return uh_file_response_ok_hdrs(cl, s);
-}
-
-static int uh_file_response_412(struct client *cl)
-{
-       return uh_http_sendf(cl, NULL,
-                                                "%s 412 Precondition Failed\r\n"
-                                                "Connection: close\r\n",
-                            http_versions[cl->request.version]);
-}
-
-static int uh_file_if_match(struct client *cl, struct stat *s, int *ok)
-{
-       const char *tag = uh_file_mktag(s);
-       char *hdr = uh_file_header_lookup(cl, "If-Match");
-       char *p;
-       int i;
-
-       if (hdr)
-       {
-               p = &hdr[0];
-
-               for (i = 0; i < strlen(hdr); i++)
-               {
-                       if ((hdr[i] == ' ') || (hdr[i] == ','))
-                       {
-                               hdr[i++] = 0;
-                               p = &hdr[i];
-                       }
-                       else if (!strcmp(p, "*") || !strcmp(p, tag))
-                       {
-                               *ok = 1;
-                               return *ok;
-                       }
-               }
-
-               *ok = 0;
-               ensure_ret(uh_file_response_412(cl));
-               return *ok;
-       }
-
-       *ok = 1;
-       return *ok;
-}
-
-static int uh_file_if_modified_since(struct client *cl, struct stat *s, int *ok)
-{
-       char *hdr = uh_file_header_lookup(cl, "If-Modified-Since");
-       *ok = 1;
-
-       if (hdr)
-       {
-               if (uh_file_date2unix(hdr) >= s->st_mtime)
-               {
-                       *ok = 0;
-                       ensure_ret(uh_file_response_304(cl, s));
-               }
-       }
-
-       return *ok;
-}
-
-static int uh_file_if_none_match(struct client *cl, struct stat *s, int *ok)
-{
-       const char *tag = uh_file_mktag(s);
-       char *hdr = uh_file_header_lookup(cl, "If-None-Match");
-       char *p;
-       int i;
-       *ok = 1;
-
-       if (hdr)
-       {
-               p = &hdr[0];
-
-               for (i = 0; i < strlen(hdr); i++)
-               {
-                       if ((hdr[i] == ' ') || (hdr[i] == ','))
-                       {
-                               hdr[i++] = 0;
-                               p = &hdr[i];
-                       }
-                       else if (!strcmp(p, "*") || !strcmp(p, tag))
-                       {
-                               *ok = 0;
-
-                               if ((cl->request.method == UH_HTTP_MSG_GET) ||
-                                   (cl->request.method == UH_HTTP_MSG_HEAD))
-                               {
-                                       ensure_ret(uh_file_response_304(cl, s));
-                               }
-                               else
-                               {
-                                       ensure_ret(uh_file_response_412(cl));
-                               }
-
-                               break;
-                       }
-               }
-       }
-
-       return *ok;
-}
-
-static int uh_file_if_range(struct client *cl, struct stat *s, int *ok)
-{
-       char *hdr = uh_file_header_lookup(cl, "If-Range");
-       *ok = 1;
-
-       if (hdr)
-       {
-               *ok = 0;
-               ensure_ret(uh_file_response_412(cl));
-       }
-
-       return *ok;
-}
-
-static int uh_file_if_unmodified_since(struct client *cl, struct stat *s,
-                                                                          int *ok)
-{
-       char *hdr = uh_file_header_lookup(cl, "If-Unmodified-Since");
-       *ok = 1;
-
-       if (hdr)
-       {
-               if (uh_file_date2unix(hdr) <= s->st_mtime)
-               {
-                       *ok = 0;
-                       ensure_ret(uh_file_response_412(cl));
-               }
-       }
-
-       return *ok;
-}
-
-
-static int uh_file_scandir_filter_dir(const struct dirent *e)
-{
-       return strcmp(e->d_name, ".") ? 1 : 0;
-}
-
-static void uh_file_dirlist(struct client *cl, struct path_info *pi)
-{
-       int i;
-       int count = 0;
-       char filename[PATH_MAX];
-       char *pathptr;
-       struct dirent **files = NULL;
-       struct stat s;
-
-       ensure_out(uh_http_sendf(cl, &cl->request,
-                                                        "<html><head><title>Index of %s</title></head>"
-                                                        "<body><h1>Index of %s</h1><hr /><ol>",
-                                                        pi->name, pi->name));
-
-       if ((count = scandir(pi->phys, &files, uh_file_scandir_filter_dir,
-                                                alphasort)) > 0)
-       {
-               memset(filename, 0, sizeof(filename));
-               memcpy(filename, pi->phys, sizeof(filename));
-               pathptr = &filename[strlen(filename)];
-
-               /* list subdirs */
-               for (i = 0; i < count; i++)
-               {
-                       strncat(filename, files[i]->d_name,
-                                       sizeof(filename) - strlen(files[i]->d_name));
-
-                       if (!stat(filename, &s) &&
-                               (s.st_mode & S_IFDIR) && (s.st_mode & S_IXOTH))
-                       {
-                               ensure_out(uh_http_sendf(cl, &cl->request,
-                                                                                "<li><strong><a href='%s%s'>%s</a>/"
-                                                                                "</strong><br /><small>modified: %s"
-                                                                                "<br />directory - %.02f kbyte<br />"
-                                                                                "<br /></small></li>",
-                                                                                pi->name, files[i]->d_name,
-                                                                                files[i]->d_name,
-                                                                                uh_file_unix2date(s.st_mtime),
-                                                                                s.st_size / 1024.0));
-                       }
-
-                       *pathptr = 0;
-               }
-
-               /* list files */
-               for (i = 0; i < count; i++)
-               {
-                       strncat(filename, files[i]->d_name,
-                                       sizeof(filename) - strlen(files[i]->d_name));
-
-                       if (!stat(filename, &s) &&
-                               !(s.st_mode & S_IFDIR) && (s.st_mode & S_IROTH))
-                       {
-                               ensure_out(uh_http_sendf(cl, &cl->request,
-                                                                                "<li><strong><a href='%s%s'>%s</a>"
-                                                                                "</strong><br /><small>modified: %s"
-                                                                                "<br />%s - %.02f kbyte<br />"
-                                                                                "<br /></small></li>",
-                                                                                pi->name, files[i]->d_name,
-                                                                                files[i]->d_name,
-                                                                                uh_file_unix2date(s.st_mtime),
-                                                                                uh_file_mime_lookup(filename),
-                                                                                s.st_size / 1024.0));
-                       }
-
-                       *pathptr = 0;
-               }
-       }
-
-       ensure_out(uh_http_sendf(cl, &cl->request, "</ol><hr /></body></html>"));
-       ensure_out(uh_http_sendf(cl, &cl->request, ""));
-
-out:
-       if (files)
-       {
-               for (i = 0; i < count; i++)
-                       free(files[i]);
-
-               free(files);
-       }
-}
-
-
-bool uh_file_request(struct client *cl, struct path_info *pi)
-{
-       int rlen;
-       int ok = 1;
-       int fd = -1;
-       char buf[UH_LIMIT_MSGHEAD];
-
-       /* we have a file */
-       if ((pi->stat.st_mode & S_IFREG) && ((fd = open(pi->phys, O_RDONLY)) > 0))
-       {
-               /* test preconditions */
-               if (ok) ensure_out(uh_file_if_modified_since(cl, &pi->stat, &ok));
-               if (ok) ensure_out(uh_file_if_match(cl, &pi->stat, &ok));
-               if (ok) ensure_out(uh_file_if_range(cl, &pi->stat, &ok));
-               if (ok) ensure_out(uh_file_if_unmodified_since(cl, &pi->stat, &ok));
-               if (ok) ensure_out(uh_file_if_none_match(cl, &pi->stat, &ok));
-
-               if (ok > 0)
-               {
-                       /* write status */
-                       ensure_out(uh_file_response_200(cl, &pi->stat));
-
-                       ensure_out(uh_http_sendf(cl, NULL, "Content-Type: %s\r\n",
-                                                                        uh_file_mime_lookup(pi->name)));
-
-                       ensure_out(uh_http_sendf(cl, NULL, "Content-Length: %i\r\n",
-                                                                        pi->stat.st_size));
-
-                       /* if request was HTTP 1.1 we'll respond chunked */
-                       if ((cl->request.version > 1.0) &&
-                               (cl->request.method != UH_HTTP_MSG_HEAD))
-                       {
-                               ensure_out(uh_http_send(cl, NULL,
-                                                                               "Transfer-Encoding: chunked\r\n", -1));
-                       }
-
-                       /* close header */
-                       ensure_out(uh_http_send(cl, NULL, "\r\n", -1));
-
-                       /* send body */
-                       if (cl->request.method != UH_HTTP_MSG_HEAD)
-                       {
-                               /* pump file data */
-                               while ((rlen = read(fd, buf, sizeof(buf))) > 0)
-                                       ensure_out(uh_http_send(cl, &cl->request, buf, rlen));
-
-                               /* send trailer in chunked mode */
-                               ensure_out(uh_http_send(cl, &cl->request, "", 0));
-                       }
-               }
-
-               /* one of the preconditions failed, terminate opened header and exit */
-               else
-               {
-                       ensure_out(uh_http_send(cl, NULL, "\r\n", -1));
-               }
-       }
-
-       /* directory */
-       else if ((pi->stat.st_mode & S_IFDIR) && !cl->server->conf->no_dirlists)
-       {
-               /* write status */
-               ensure_out(uh_file_response_200(cl, NULL));
-
-               if (cl->request.version > 1.0)
-                       ensure_out(uh_http_send(cl, NULL,
-                                                                       "Transfer-Encoding: chunked\r\n", -1));
-
-               ensure_out(uh_http_send(cl, NULL,
-                                                               "Content-Type: text/html\r\n\r\n", -1));
-
-               /* content */
-               uh_file_dirlist(cl, pi);
-       }
-
-       /* 403 */
-       else
-       {
-               ensure_out(uh_http_sendhf(cl, 403, "Forbidden",
-                                                                 "Access to this resource is forbidden"));
-       }
-
-out:
-       if (fd > -1)
-               close(fd);
-
-       return false;
-}
diff --git a/package/network/services/uhttpd/src/uhttpd-file.h b/package/network/services/uhttpd/src/uhttpd-file.h
deleted file mode 100644 (file)
index 08dbe2c..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - Static file header
- *
- *   Copyright (C) 2010 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#ifndef _UHTTPD_FILE_
-
-#include <fcntl.h>
-#include <time.h>
-#include <strings.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <linux/limits.h>
-
-struct mimetype {
-       const char *extn;
-       const char *mime;
-};
-
-bool uh_file_request(struct client *cl, struct path_info *pi);
-
-#endif
diff --git a/package/network/services/uhttpd/src/uhttpd-lua.c b/package/network/services/uhttpd/src/uhttpd-lua.c
deleted file mode 100644 (file)
index e113937..0000000
+++ /dev/null
@@ -1,579 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - Lua handler
- *
- *   Copyright (C) 2010-2012 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#include "uhttpd.h"
-#include "uhttpd-utils.h"
-#include "uhttpd-lua.h"
-
-
-static int uh_lua_recv(lua_State *L)
-{
-       size_t length;
-
-       char buffer[UH_LIMIT_MSGHEAD];
-
-       int to = 1;
-       int fd = fileno(stdin);
-       int rlen = 0;
-
-       length = luaL_checknumber(L, 1);
-
-       if ((length > 0) && (length <= sizeof(buffer)))
-       {
-               /* receive data */
-               rlen = uh_raw_recv(fd, buffer, length, to);
-
-               /* data read */
-               if (rlen > 0)
-               {
-                       lua_pushnumber(L, rlen);
-                       lua_pushlstring(L, buffer, rlen);
-                       return 2;
-               }
-
-               /* eof */
-               else if (rlen == 0)
-               {
-                       lua_pushnumber(L, 0);
-                       return 1;
-               }
-
-               /* no, timeout and actually no data */
-               else
-               {
-                       lua_pushnumber(L, -1);
-                       return 1;
-               }
-       }
-
-       /* parameter error */
-       lua_pushnumber(L, -2);
-       return 1;
-}
-
-static int uh_lua_send_common(lua_State *L, bool chunked)
-{
-       size_t length;
-
-       char chunk[16];
-       const char *buffer;
-
-       int rv;
-       int to = 1;
-       int fd = fileno(stdout);
-       int slen = 0;
-
-       buffer = luaL_checklstring(L, 1, &length);
-
-       if (chunked)
-       {
-               if (length > 0)
-               {
-                       snprintf(chunk, sizeof(chunk), "%X\r\n", length);
-
-                       ensure_out(rv = uh_raw_send(fd, chunk, strlen(chunk), to));
-                       slen += rv;
-
-                       ensure_out(rv = uh_raw_send(fd, buffer, length, to));
-                       slen += rv;
-
-                       ensure_out(rv = uh_raw_send(fd, "\r\n", 2, to));
-                       slen += rv;
-               }
-               else
-               {
-                       slen = uh_raw_send(fd, "0\r\n\r\n", 5, to);
-               }
-       }
-       else
-       {
-               slen = uh_raw_send(fd, buffer, length, to);
-       }
-
-out:
-       lua_pushnumber(L, slen);
-       return 1;
-}
-
-static int uh_lua_send(lua_State *L)
-{
-       return uh_lua_send_common(L, false);
-}
-
-static int uh_lua_sendc(lua_State *L)
-{
-       return uh_lua_send_common(L, true);
-}
-
-static int uh_lua_str2str(lua_State *L, int (*xlate_func) (char *, int, const char *, int))
-{
-       size_t inlen;
-       int outlen;
-       const char *inbuf;
-       char outbuf[UH_LIMIT_MSGHEAD];
-
-       inbuf = luaL_checklstring(L, 1, &inlen);
-       outlen = (* xlate_func)(outbuf, sizeof(outbuf), inbuf, inlen);
-       if (outlen < 0)
-               luaL_error(L, "%s on URL-encode codec",
-                                  (outlen==-1) ? "buffer overflow" : "malformed string");
-
-       lua_pushlstring(L, outbuf, outlen);
-       return 1;
-}
-
-static int uh_lua_urldecode(lua_State *L)
-{
-       return uh_lua_str2str( L, uh_urldecode );
-}
-
-
-static int uh_lua_urlencode(lua_State *L)
-{
-       return uh_lua_str2str( L, uh_urlencode );
-}
-
-
-lua_State * uh_lua_init(const struct config *conf)
-{
-       lua_State *L = lua_open();
-       const char *err_str = NULL;
-
-       /* Load standard libaries */
-       luaL_openlibs(L);
-
-       /* build uhttpd api table */
-       lua_newtable(L);
-
-       /* register global send and receive functions */
-       lua_pushcfunction(L, uh_lua_recv);
-       lua_setfield(L, -2, "recv");
-
-       lua_pushcfunction(L, uh_lua_send);
-       lua_setfield(L, -2, "send");
-
-       lua_pushcfunction(L, uh_lua_sendc);
-       lua_setfield(L, -2, "sendc");
-
-       lua_pushcfunction(L, uh_lua_urldecode);
-       lua_setfield(L, -2, "urldecode");
-
-       lua_pushcfunction(L, uh_lua_urlencode);
-       lua_setfield(L, -2, "urlencode");
-
-       /* Pass the document-root to the Lua handler by placing it in
-       ** uhttpd.docroot.  It could alternatively be placed in env.DOCUMENT_ROOT
-       ** which would more closely resemble the CGI protocol; but would mean that
-       ** it is not available at the time when the handler-chunk is loaded but
-       ** rather not until the handler is called, without any code savings. */
-       lua_pushstring(L, conf->docroot);
-       lua_setfield(L, -2, "docroot");
-
-       /* _G.uhttpd = { ... } */
-       lua_setfield(L, LUA_GLOBALSINDEX, "uhttpd");
-
-
-       /* load Lua handler */
-       switch (luaL_loadfile(L, conf->lua_handler))
-       {
-               case LUA_ERRSYNTAX:
-                       fprintf(stderr,
-                                       "Lua handler contains syntax errors, unable to continue\n");
-                       exit(1);
-
-               case LUA_ERRMEM:
-                       fprintf(stderr,
-                                       "Lua handler ran out of memory, unable to continue\n");
-                       exit(1);
-
-               case LUA_ERRFILE:
-                       fprintf(stderr,
-                                       "Lua cannot open the handler script, unable to continue\n");
-                       exit(1);
-
-               default:
-                       /* compile Lua handler */
-                       switch (lua_pcall(L, 0, 0, 0))
-                       {
-                               case LUA_ERRRUN:
-                                       err_str = luaL_checkstring(L, -1);
-                                       fprintf(stderr,
-                                                       "Lua handler had runtime error, "
-                                                       "unable to continue\n"
-                                                       "Error: %s\n", err_str);
-                                       exit(1);
-
-                               case LUA_ERRMEM:
-                                       err_str = luaL_checkstring(L, -1);
-                                       fprintf(stderr,
-                                                       "Lua handler ran out of memory, "
-                                                       "unable to continue\n"
-                                                       "Error: %s\n", err_str);
-                                       exit(1);
-
-                               default:
-                                       /* test handler function */
-                                       lua_getglobal(L, UH_LUA_CALLBACK);
-
-                                       if (! lua_isfunction(L, -1))
-                                       {
-                                               fprintf(stderr,
-                                                               "Lua handler provides no "UH_LUA_CALLBACK"(), "
-                                                               "unable to continue\n");
-                                               exit(1);
-                                       }
-
-                                       lua_pop(L, 1);
-                                       break;
-                       }
-
-                       break;
-       }
-
-       return L;
-}
-
-static void uh_lua_shutdown(struct uh_lua_state *state)
-{
-       free(state);
-}
-
-static bool uh_lua_socket_cb(struct client *cl)
-{
-       int len;
-       char buf[UH_LIMIT_MSGHEAD];
-
-       struct uh_lua_state *state = (struct uh_lua_state *)cl->priv;
-
-       /* there is unread post data waiting */
-       while (state->content_length > 0)
-       {
-               /* remaining data in http head buffer ... */
-               if (cl->httpbuf.len > 0)
-               {
-                       len = min(state->content_length, cl->httpbuf.len);
-
-                       D("Lua: Child(%d) feed %d HTTP buffer bytes\n", cl->proc.pid, len);
-
-                       memcpy(buf, cl->httpbuf.ptr, len);
-
-                       cl->httpbuf.len -= len;
-                       cl->httpbuf.ptr += len;
-               }
-
-               /* read it from socket ... */
-               else
-               {
-                       len = uh_tcp_recv(cl, buf, min(state->content_length, sizeof(buf)));
-
-                       if ((len < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
-                               break;
-
-                       D("Lua: Child(%d) feed %d/%d TCP socket bytes\n",
-                         cl->proc.pid, len, min(state->content_length, sizeof(buf)));
-               }
-
-               if (len)
-                       state->content_length -= len;
-               else
-                       state->content_length = 0;
-
-               /* ... write to Lua process */
-               len = uh_raw_send(cl->wpipe.fd, buf, len,
-                                                 cl->server->conf->script_timeout);
-
-               /* explicit EOF notification for the child */
-               if (state->content_length <= 0)
-                       uh_ufd_remove(&cl->wpipe);
-       }
-
-       /* try to read data from child */
-       while ((len = uh_raw_recv(cl->rpipe.fd, buf, sizeof(buf), -1)) > 0)
-       {
-               /* pass through buffer to socket */
-               D("Lua: Child(%d) relaying %d normal bytes\n", cl->proc.pid, len);
-               ensure_out(uh_tcp_send(cl, buf, len));
-               state->data_sent = true;
-       }
-
-       /* got EOF or read error from child */
-       if ((len == 0) ||
-               ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (len == -1)))
-       {
-               D("Lua: Child(%d) presumed dead [%s]\n",
-                 cl->proc.pid, strerror(errno));
-
-               goto out;
-       }
-
-       return true;
-
-out:
-       if (!state->data_sent)
-       {
-               if (cl->timeout.pending)
-                       uh_http_sendhf(cl, 502, "Bad Gateway",
-                                                  "The Lua process did not produce any response\n");
-               else
-                       uh_http_sendhf(cl, 504, "Gateway Timeout",
-                                                  "The Lua process took too long to produce a "
-                                                  "response\n");
-       }
-
-       uh_lua_shutdown(state);
-       return false;
-}
-
-bool uh_lua_request(struct client *cl, lua_State *L)
-{
-       int i;
-       char *query_string;
-       const char *prefix = cl->server->conf->lua_prefix;
-       const char *err_str = NULL;
-
-       int rfd[2] = { 0, 0 };
-       int wfd[2] = { 0, 0 };
-
-       pid_t child;
-
-       struct uh_lua_state *state;
-       struct http_request *req = &cl->request;
-
-       int content_length = cl->httpbuf.len;
-
-
-       /* allocate state */
-       if (!(state = malloc(sizeof(*state))))
-       {
-               uh_client_error(cl, 500, "Internal Server Error", "Out of memory");
-               return false;
-       }
-
-       /* spawn pipes for me->child, child->me */
-       if ((pipe(rfd) < 0) || (pipe(wfd) < 0))
-       {
-               if (rfd[0] > 0) close(rfd[0]);
-               if (rfd[1] > 0) close(rfd[1]);
-               if (wfd[0] > 0) close(wfd[0]);
-               if (wfd[1] > 0) close(wfd[1]);
-
-               uh_client_error(cl, 500, "Internal Server Error",
-                                               "Failed to create pipe: %s", strerror(errno));
-
-               return false;
-       }
-
-
-       switch ((child = fork()))
-       {
-       case -1:
-               uh_client_error(cl, 500, "Internal Server Error",
-                                               "Failed to fork child: %s", strerror(errno));
-
-               return false;
-
-       case 0:
-#ifdef DEBUG
-               sleep(atoi(getenv("UHTTPD_SLEEP_ON_FORK") ?: "0"));
-#endif
-
-               /* do not leak parent epoll descriptor */
-               uloop_done();
-
-               /* close loose pipe ends */
-               close(rfd[0]);
-               close(wfd[1]);
-
-               /* patch stdout and stdin to pipes */
-               dup2(rfd[1], 1);
-               dup2(wfd[0], 0);
-
-               /* avoid leaking our pipe into child-child processes */
-               fd_cloexec(rfd[1]);
-               fd_cloexec(wfd[0]);
-
-               /* put handler callback on stack */
-               lua_getglobal(L, UH_LUA_CALLBACK);
-
-               /* build env table */
-               lua_newtable(L);
-
-               /* request method */
-               lua_pushstring(L, http_methods[req->method]);
-               lua_setfield(L, -2, "REQUEST_METHOD");
-
-               /* request url */
-               lua_pushstring(L, req->url);
-               lua_setfield(L, -2, "REQUEST_URI");
-
-               /* script name */
-               lua_pushstring(L, cl->server->conf->lua_prefix);
-               lua_setfield(L, -2, "SCRIPT_NAME");
-
-               /* query string, path info */
-               if ((query_string = strchr(req->url, '?')) != NULL)
-               {
-                       lua_pushstring(L, query_string + 1);
-                       lua_setfield(L, -2, "QUERY_STRING");
-
-                       if ((int)(query_string - req->url) > strlen(prefix))
-                       {
-                               lua_pushlstring(L,
-                                       &req->url[strlen(prefix)],
-                                       (int)(query_string - req->url) - strlen(prefix)
-                               );
-
-                               lua_setfield(L, -2, "PATH_INFO");
-                       }
-               }
-               else if (strlen(req->url) > strlen(prefix))
-               {
-                       lua_pushstring(L, &req->url[strlen(prefix)]);
-                       lua_setfield(L, -2, "PATH_INFO");
-               }
-
-               /* http protcol version */
-               lua_pushnumber(L, 0.9 + (req->version / 10.0));
-               lua_setfield(L, -2, "HTTP_VERSION");
-
-               lua_pushstring(L, http_versions[req->version]);
-               lua_setfield(L, -2, "SERVER_PROTOCOL");
-
-
-               /* address information */
-               lua_pushstring(L, sa_straddr(&cl->peeraddr));
-               lua_setfield(L, -2, "REMOTE_ADDR");
-
-               lua_pushinteger(L, sa_port(&cl->peeraddr));
-               lua_setfield(L, -2, "REMOTE_PORT");
-
-               lua_pushstring(L, sa_straddr(&cl->servaddr));
-               lua_setfield(L, -2, "SERVER_ADDR");
-
-               lua_pushinteger(L, sa_port(&cl->servaddr));
-               lua_setfield(L, -2, "SERVER_PORT");
-
-               /* essential env vars */
-               foreach_header(i, req->headers)
-               {
-                       if (!strcasecmp(req->headers[i], "Content-Length"))
-                       {
-                               content_length = atoi(req->headers[i+1]);
-                       }
-                       else if (!strcasecmp(req->headers[i], "Content-Type"))
-                       {
-                               lua_pushstring(L, req->headers[i+1]);
-                               lua_setfield(L, -2, "CONTENT_TYPE");
-                       }
-               }
-
-               lua_pushnumber(L, content_length);
-               lua_setfield(L, -2, "CONTENT_LENGTH");
-
-               /* misc. headers */
-               lua_newtable(L);
-
-               foreach_header(i, req->headers)
-               {
-                       if( strcasecmp(req->headers[i], "Content-Length") &&
-                               strcasecmp(req->headers[i], "Content-Type"))
-                       {
-                               lua_pushstring(L, req->headers[i+1]);
-                               lua_setfield(L, -2, req->headers[i]);
-                       }
-               }
-
-               lua_setfield(L, -2, "headers");
-
-
-               /* call */
-               switch (lua_pcall(L, 1, 0, 0))
-               {
-                       case LUA_ERRMEM:
-                       case LUA_ERRRUN:
-                               err_str = luaL_checkstring(L, -1);
-
-                               if (! err_str)
-                                       err_str = "Unknown error";
-
-                               printf("%s 500 Internal Server Error\r\n"
-                                          "Connection: close\r\n"
-                                          "Content-Type: text/plain\r\n"
-                                          "Content-Length: %i\r\n\r\n"
-                                          "Lua raised a runtime error:\n  %s\n",
-                                          http_versions[req->version],
-                                          31 + strlen(err_str), err_str);
-
-                               break;
-
-                       default:
-                               break;
-               }
-
-               close(wfd[0]);
-               close(rfd[1]);
-               exit(0);
-
-               break;
-
-       /* parent; handle I/O relaying */
-       default:
-               memset(state, 0, sizeof(*state));
-
-               cl->rpipe.fd = rfd[0];
-               cl->wpipe.fd = wfd[1];
-               cl->proc.pid = child;
-
-               /* make pipe non-blocking */
-               fd_nonblock(cl->rpipe.fd);
-               fd_nonblock(cl->wpipe.fd);
-
-               /* close unneeded pipe ends */
-               close(rfd[1]);
-               close(wfd[0]);
-
-               D("Lua: Child(%d) created: rfd(%d) wfd(%d)\n", child, rfd[0], wfd[1]);
-
-               state->content_length = cl->httpbuf.len;
-
-               /* find content length */
-               if (req->method == UH_HTTP_MSG_POST)
-               {
-                       foreach_header(i, req->headers)
-                       {
-                               if (!strcasecmp(req->headers[i], "Content-Length"))
-                               {
-                                       state->content_length = atoi(req->headers[i+1]);
-                                       break;
-                               }
-                       }
-               }
-
-               cl->cb = uh_lua_socket_cb;
-               cl->priv = state;
-
-               break;
-       }
-
-       return true;
-}
-
-void uh_lua_close(lua_State *L)
-{
-       lua_close(L);
-}
diff --git a/package/network/services/uhttpd/src/uhttpd-lua.h b/package/network/services/uhttpd/src/uhttpd-lua.h
deleted file mode 100644 (file)
index 780d845..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - Lua header
- *
- *   Copyright (C) 2010-2012 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#ifndef _UHTTPD_LUA_
-
-#include <math.h>  /* floor() */
-#include <errno.h>
-
-#include <lua.h>
-#include <lauxlib.h>
-#include <lualib.h>
-
-#define UH_LUA_CALLBACK                "handle_request"
-
-#define UH_LUA_ERR_TIMEOUT -1
-#define UH_LUA_ERR_TOOBIG  -2
-#define UH_LUA_ERR_PARAM   -3
-
-
-struct uh_lua_state {
-       int content_length;
-       bool data_sent;
-};
-
-lua_State * uh_lua_init(const struct config *conf);
-bool uh_lua_request(struct client *cl, lua_State *L);
-void uh_lua_close(lua_State *L);
-
-#endif
diff --git a/package/network/services/uhttpd/src/uhttpd-mimetypes.h b/package/network/services/uhttpd/src/uhttpd-mimetypes.h
deleted file mode 100644 (file)
index 21717c0..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - MIME type definitions
- *
- *   Copyright (C) 2010 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#ifndef _UHTTPD_MIMETYPES_
-
-static struct mimetype uh_mime_types[] = {
-
-       { "txt",     "text/plain" },
-       { "log",     "text/plain" },
-       { "js",      "text/javascript" },
-       { "css",     "text/css" },
-       { "htm",     "text/html" },
-       { "html",    "text/html" },
-       { "diff",    "text/x-patch" },
-       { "patch",   "text/x-patch" },
-       { "c",       "text/x-csrc" },
-       { "h",       "text/x-chdr" },
-       { "o",       "text/x-object" },
-       { "ko",      "text/x-object" },
-
-       { "bmp",     "image/bmp" },
-       { "gif",     "image/gif" },
-       { "png",     "image/png" },
-       { "jpg",     "image/jpeg" },
-       { "jpeg",    "image/jpeg" },
-       { "svg",     "image/svg+xml" },
-
-       { "zip",     "application/zip" },
-       { "pdf",     "application/pdf" },
-       { "xml",     "application/xml" },
-       { "xsl",     "application/xml" },
-       { "doc",     "application/msword" },
-       { "ppt",     "application/vnd.ms-powerpoint" },
-       { "xls",     "application/vnd.ms-excel" },
-       { "odt",     "application/vnd.oasis.opendocument.text" },
-       { "odp",     "application/vnd.oasis.opendocument.presentation" },
-       { "pl",      "application/x-perl" },
-       { "sh",      "application/x-shellscript" },
-       { "php",     "application/x-php" },
-       { "deb",     "application/x-deb" },
-       { "iso",     "application/x-cd-image" },
-       { "tar.gz",  "application/x-compressed-tar" },
-       { "tgz",     "application/x-compressed-tar" },
-       { "gz",      "application/x-gzip" },
-       { "tar.bz2", "application/x-bzip-compressed-tar" },
-       { "tbz",     "application/x-bzip-compressed-tar" },
-       { "bz2",     "application/x-bzip" },
-       { "tar",     "application/x-tar" },
-       { "rar",     "application/x-rar-compressed" },
-
-       { "mp3",     "audio/mpeg" },
-       { "ogg",     "audio/x-vorbis+ogg" },
-       { "wav",     "audio/x-wav" },
-
-       { "mpg",     "video/mpeg" },
-       { "mpeg",    "video/mpeg" },
-       { "avi",     "video/x-msvideo" },
-
-       { "README",  "text/plain" },
-       { "log",     "text/plain" },
-       { "cfg",     "text/plain" },
-       { "conf",    "text/plain" },
-
-       { "pac",                "application/x-ns-proxy-autoconfig" },
-       { "wpad.dat",   "application/x-ns-proxy-autoconfig" },
-
-       { NULL, NULL }
-};
-
-#endif
-
diff --git a/package/network/services/uhttpd/src/uhttpd-tls.c b/package/network/services/uhttpd/src/uhttpd-tls.c
deleted file mode 100644 (file)
index 9c6eb81..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - TLS helper
- *
- *   Copyright (C) 2010 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#include "uhttpd.h"
-#include "uhttpd-tls.h"
-#include "uhttpd-utils.h"
-
-#include <syslog.h>
-#define dbg(...) syslog(LOG_INFO, __VA_ARGS__)
-
-SSL_CTX * uh_tls_ctx_init(void)
-{
-       SSL_CTX *c;
-
-       SSL_load_error_strings();
-       SSL_library_init();
-
-#if TLS_IS_OPENSSL
-       if ((c = SSL_CTX_new(SSLv23_server_method())) != NULL)
-#else
-       if ((c = SSL_CTX_new(TLSv1_server_method())) != NULL)
-#endif
-               SSL_CTX_set_verify(c, SSL_VERIFY_NONE, NULL);
-
-       return c;
-}
-
-int uh_tls_ctx_cert(SSL_CTX *c, const char *file)
-{
-       int rv;
-
-       if( (rv = SSL_CTX_use_certificate_file(c, file, SSL_FILETYPE_PEM)) < 1 )
-               rv = SSL_CTX_use_certificate_file(c, file, SSL_FILETYPE_ASN1);
-
-       return rv;
-}
-
-int uh_tls_ctx_key(SSL_CTX *c, const char *file)
-{
-       int rv;
-
-       if( (rv = SSL_CTX_use_PrivateKey_file(c, file, SSL_FILETYPE_PEM)) < 1 )
-               rv = SSL_CTX_use_PrivateKey_file(c, file, SSL_FILETYPE_ASN1);
-
-       return rv;
-}
-
-void uh_tls_ctx_free(struct listener *l)
-{
-       SSL_CTX_free(l->tls);
-}
-
-
-int uh_tls_client_accept(struct client *c)
-{
-       int rv, err;
-       int fd = c->fd.fd;
-
-       if (!c->server || !c->server->tls)
-       {
-               c->tls = NULL;
-               return 1;
-       }
-
-       if ((c->tls = SSL_new(c->server->tls)))
-       {
-               if ((rv = SSL_set_fd(c->tls, fd)) < 1)
-               {
-                       SSL_free(c->tls);
-                       c->tls = NULL;
-               }
-               else
-               {
-                       while (true)
-                       {
-                               rv = SSL_accept(c->tls);
-                               err = SSL_get_error(c->tls, rv);
-
-                               if ((rv != 1) &&
-                                       (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE))
-                               {
-                                       if (uh_socket_wait(fd, c->server->conf->network_timeout,
-                                                                          (err == SSL_ERROR_WANT_WRITE)))
-                                       {
-                                               D("TLS: accept(%d) = retry\n", fd);
-                                               continue;
-                                       }
-
-                                       D("TLS: accept(%d) = timeout\n", fd);
-                               }
-                               else if (rv == 1)
-                               {
-                                       D("TLS: accept(%d) = %p\n", fd, c->tls);
-                                       return 1;
-                               }
-
-#ifdef TLS_IS_OPENSSL
-                               D("TLS: accept(%d) = failed: %s\n",
-                                 fd, ERR_error_string(ERR_get_error(), NULL));
-#endif
-
-                               SSL_free(c->tls);
-                               c->tls = NULL;
-                               break;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-int uh_tls_client_recv(struct client *c, char *buf, int len)
-{
-       int rv = SSL_read(c->tls, buf, len);
-       int err = SSL_get_error(c->tls, 0);
-
-       if ((rv == -1) && (err == SSL_ERROR_WANT_READ))
-       {
-               D("TLS: recv(%d, %d) = retry\n", c->fd.fd, len);
-               errno = EAGAIN;
-               return -1;
-       }
-
-       D("TLS: recv(%d, %d) = %d\n", c->fd.fd, len, rv);
-       return rv;
-}
-
-int uh_tls_client_send(struct client *c, const char *buf, int len)
-{
-       int rv = SSL_write(c->tls, buf, len);
-       int err = SSL_get_error(c->tls, 0);
-
-       if ((rv == -1) && (err == SSL_ERROR_WANT_WRITE))
-       {
-               D("TLS: send(%d, %d) = retry\n", c->fd.fd, len);
-               errno = EAGAIN;
-               return -1;
-       }
-
-       D("TLS: send(%d, %d) = %d\n", c->fd.fd, len, rv);
-       return rv;
-}
-
-void uh_tls_client_close(struct client *c)
-{
-       if (c->tls)
-       {
-               D("TLS: close(%d)\n", c->fd.fd);
-
-               SSL_shutdown(c->tls);
-               SSL_free(c->tls);
-
-               c->tls = NULL;
-       }
-}
diff --git a/package/network/services/uhttpd/src/uhttpd-tls.h b/package/network/services/uhttpd/src/uhttpd-tls.h
deleted file mode 100644 (file)
index 8644c2a..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - TLS header
- *
- *   Copyright (C) 2010 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#ifndef _UHTTPD_TLS_
-
-#include <openssl/ssl.h>
-#ifdef TLS_IS_OPENSSL
-#include <openssl/err.h>
-#endif
-
-SSL_CTX * uh_tls_ctx_init();
-int uh_tls_ctx_cert(SSL_CTX *c, const char *file);
-int uh_tls_ctx_key(SSL_CTX *c, const char *file);
-void uh_tls_ctx_free(struct listener *l);
-
-int uh_tls_client_accept(struct client *c);
-int uh_tls_client_recv(struct client *c, char *buf, int len);
-int uh_tls_client_send(struct client *c, const char *buf, int len);
-void uh_tls_client_close(struct client *c);
-
-#endif
diff --git a/package/network/services/uhttpd/src/uhttpd-ubus.c b/package/network/services/uhttpd/src/uhttpd-ubus.c
deleted file mode 100644 (file)
index 2078162..0000000
+++ /dev/null
@@ -1,957 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - ubus handler
- *
- *   Copyright (C) 2012 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#include "uhttpd.h"
-#include "uhttpd-utils.h"
-#include "uhttpd-ubus.h"
-
-
-enum {
-       UH_UBUS_SN_TIMEOUT,
-       __UH_UBUS_SN_MAX,
-};
-
-static const struct blobmsg_policy new_policy[__UH_UBUS_SN_MAX] = {
-       [UH_UBUS_SN_TIMEOUT] = { .name = "timeout", .type = BLOBMSG_TYPE_INT32 },
-};
-
-
-enum {
-       UH_UBUS_SI_SID,
-       __UH_UBUS_SI_MAX,
-};
-
-static const struct blobmsg_policy sid_policy[__UH_UBUS_SI_MAX] = {
-       [UH_UBUS_SI_SID] = { .name = "sid", .type = BLOBMSG_TYPE_STRING },
-};
-
-
-enum {
-       UH_UBUS_SS_SID,
-       UH_UBUS_SS_VALUES,
-       __UH_UBUS_SS_MAX,
-};
-
-static const struct blobmsg_policy set_policy[__UH_UBUS_SS_MAX] = {
-       [UH_UBUS_SS_SID] = { .name = "sid", .type = BLOBMSG_TYPE_STRING },
-       [UH_UBUS_SS_VALUES] = { .name = "values", .type = BLOBMSG_TYPE_TABLE },
-};
-
-
-enum {
-       UH_UBUS_SG_SID,
-       UH_UBUS_SG_KEYS,
-       __UH_UBUS_SG_MAX,
-};
-
-static const struct blobmsg_policy get_policy[__UH_UBUS_SG_MAX] = {
-       [UH_UBUS_SG_SID] = { .name = "sid", .type = BLOBMSG_TYPE_STRING },
-       [UH_UBUS_SG_KEYS] = { .name = "keys", .type = BLOBMSG_TYPE_ARRAY },
-};
-
-
-enum {
-       UH_UBUS_SA_SID,
-       UH_UBUS_SA_OBJECTS,
-       __UH_UBUS_SA_MAX,
-};
-
-static const struct blobmsg_policy acl_policy[__UH_UBUS_SA_MAX] = {
-       [UH_UBUS_SA_SID] = { .name = "sid", .type = BLOBMSG_TYPE_STRING },
-       [UH_UBUS_SA_OBJECTS] = { .name = "objects", .type = BLOBMSG_TYPE_ARRAY },
-};
-
-
-static bool
-uh_ubus_strmatch(const char *str, const char *pat)
-{
-       while (*pat)
-       {
-               if (*pat == '?')
-               {
-                       if (!*str)
-                               return false;
-
-                       str++;
-                       pat++;
-               }
-               else if (*pat == '*')
-               {
-                       if (uh_ubus_strmatch(str, pat+1))
-                               return true;
-
-                       if (*str && uh_ubus_strmatch(str+1, pat))
-                               return true;
-
-                       return false;
-               }
-               else if (*str++ != *pat++)
-               {
-                       return false;
-               }
-       }
-
-       return (!*str && !*pat);
-}
-
-static int
-uh_ubus_avlcmp(const void *k1, const void *k2, void *ptr)
-{
-       return strcmp((char *)k1, (char *)k2);
-}
-
-static void
-uh_ubus_random(char *dest)
-{
-       int i;
-       unsigned char buf[16] = { 0 };
-       FILE *f;
-
-       if ((f = fopen("/dev/urandom", "r")) != NULL)
-       {
-               fread(buf, 1, sizeof(buf), f);
-               fclose(f);
-       }
-
-       for (i = 0; i < sizeof(buf); i++)
-               sprintf(dest + (i<<1), "%02x", buf[i]);
-}
-
-static void
-uh_ubus_session_dump_data(struct uh_ubus_session *ses, struct blob_buf *b)
-{
-       struct uh_ubus_session_data *d;
-
-       avl_for_each_element(&ses->data, d, avl)
-       {
-               blobmsg_add_field(b, blobmsg_type(d->attr), blobmsg_name(d->attr),
-                                                 blobmsg_data(d->attr), blobmsg_data_len(d->attr));
-       }
-}
-
-static void
-uh_ubus_session_dump_acls(struct uh_ubus_session *ses, struct blob_buf *b)
-{
-       struct uh_ubus_session_acl *acl;
-       const char *lastobj = NULL;
-       void *c = NULL;
-
-       avl_for_each_element(&ses->acls, acl, avl)
-       {
-               if (!lastobj || strcmp(acl->object, lastobj))
-               {
-                       if (c) blobmsg_close_array(b, c);
-                       c = blobmsg_open_array(b, acl->object);
-               }
-
-               blobmsg_add_string(b, NULL, acl->function);
-               lastobj = acl->object;
-       }
-
-       if (c) blobmsg_close_array(b, c);
-}
-
-static void
-uh_ubus_session_dump(struct uh_ubus_session *ses,
-                                        struct ubus_context *ctx,
-                                        struct ubus_request_data *req)
-{
-       void *c;
-       struct blob_buf b;
-
-       memset(&b, 0, sizeof(b));
-       blob_buf_init(&b, 0);
-
-       blobmsg_add_string(&b, "sid", ses->id);
-       blobmsg_add_u32(&b, "timeout", ses->timeout);
-       blobmsg_add_u32(&b, "touched", ses->touched.tv_sec);
-
-       c = blobmsg_open_table(&b, "acls");
-       uh_ubus_session_dump_acls(ses, &b);
-       blobmsg_close_table(&b, c);
-
-       c = blobmsg_open_table(&b, "data");
-       uh_ubus_session_dump_data(ses, &b);
-       blobmsg_close_table(&b, c);
-
-       ubus_send_reply(ctx, req, b.head);
-       blob_buf_free(&b);
-}
-
-static struct uh_ubus_session *
-uh_ubus_session_create(struct uh_ubus_state *state, int timeout)
-{
-       struct uh_ubus_session *ses;
-
-       ses = malloc(sizeof(*ses));
-
-       /* failed to allocate memory... */
-       if (!ses)
-               return NULL;
-
-       memset(ses, 0, sizeof(*ses));
-
-       uh_ubus_random(ses->id);
-
-       ses->timeout  = timeout;
-       ses->avl.key  = ses->id;
-
-       avl_insert(&state->sessions, &ses->avl);
-       avl_init(&ses->acls, uh_ubus_avlcmp, true, NULL);
-       avl_init(&ses->data, uh_ubus_avlcmp, false, NULL);
-       clock_gettime(CLOCK_MONOTONIC, &ses->touched);
-
-       return ses;
-}
-
-
-static struct uh_ubus_session *
-uh_ubus_session_get(struct uh_ubus_state *state, const char *id)
-{
-       struct uh_ubus_session *ses;
-
-       ses = avl_find_element(&state->sessions, id, ses, avl);
-
-       if (ses)
-               clock_gettime(CLOCK_MONOTONIC, &ses->touched);
-
-       return ses;
-}
-
-static void
-uh_ubus_session_destroy(struct uh_ubus_state *state,
-                                               struct uh_ubus_session *ses)
-{
-       struct uh_ubus_session_acl *acl, *nacl;
-       struct uh_ubus_session_data *data, *ndata;
-
-       avl_remove_all_elements(&ses->acls, acl, avl, nacl)
-               free(acl);
-
-       avl_remove_all_elements(&ses->data, data, avl, ndata)
-               free(data);
-
-       avl_delete(&state->sessions, &ses->avl);
-       free(ses);
-}
-
-static void
-uh_ubus_session_cleanup(struct uh_ubus_state *state)
-{
-       struct timespec now;
-       struct uh_ubus_session *ses, *nses;
-
-       clock_gettime(CLOCK_MONOTONIC, &now);
-
-       avl_for_each_element_safe(&state->sessions, ses, avl, nses)
-       {
-               if ((now.tv_sec - ses->touched.tv_sec) >= ses->timeout)
-                       uh_ubus_session_destroy(state, ses);
-       }
-}
-
-
-static int
-uh_ubus_handle_create(struct ubus_context *ctx, struct ubus_object *obj,
-                                         struct ubus_request_data *req, const char *method,
-                                         struct blob_attr *msg)
-{
-       struct uh_ubus_state *state = container_of(obj, struct uh_ubus_state, ubus);
-       struct uh_ubus_session *ses;
-       struct blob_attr *tb[__UH_UBUS_SN_MAX];
-
-       int timeout = state->timeout;
-
-       blobmsg_parse(new_policy, __UH_UBUS_SN_MAX, tb, blob_data(msg), blob_len(msg));
-
-       /* TODO: make this a uloop timeout */
-       uh_ubus_session_cleanup(state);
-
-       if (tb[UH_UBUS_SN_TIMEOUT])
-               timeout = *(uint32_t *)blobmsg_data(tb[UH_UBUS_SN_TIMEOUT]);
-
-       ses = uh_ubus_session_create(state, timeout);
-
-       if (ses)
-               uh_ubus_session_dump(ses, ctx, req);
-
-       return 0;
-}
-
-static int
-uh_ubus_handle_list(struct ubus_context *ctx, struct ubus_object *obj,
-                                       struct ubus_request_data *req, const char *method,
-                                       struct blob_attr *msg)
-{
-       struct uh_ubus_state *state = container_of(obj, struct uh_ubus_state, ubus);
-       struct uh_ubus_session *ses;
-       struct blob_attr *tb[__UH_UBUS_SI_MAX];
-
-       blobmsg_parse(sid_policy, __UH_UBUS_SI_MAX, tb, blob_data(msg), blob_len(msg));
-
-       /* TODO: make this a uloop timeout */
-       uh_ubus_session_cleanup(state);
-
-       if (!tb[UH_UBUS_SI_SID])
-       {
-               avl_for_each_element(&state->sessions, ses, avl)
-                       uh_ubus_session_dump(ses, ctx, req);
-       }
-       else
-       {
-               ses = uh_ubus_session_get(state, blobmsg_data(tb[UH_UBUS_SI_SID]));
-
-               if (!ses)
-                       return UBUS_STATUS_NOT_FOUND;
-
-               uh_ubus_session_dump(ses, ctx, req);
-       }
-
-       return 0;
-}
-
-
-static int
-uh_ubus_session_grant(struct uh_ubus_session *ses, struct ubus_context *ctx,
-                                         const char *object, const char *function)
-{
-       struct uh_ubus_session_acl *acl, *nacl;
-
-       acl = avl_find_element(&ses->acls, object, acl, avl);
-
-       if (acl)
-       {
-               avl_for_element_to_last(&ses->acls, acl, acl, avl)
-               {
-                       if (!strcmp(acl->function, function))
-                               return 1;
-               }
-       }
-
-       nacl = malloc(sizeof(*nacl) + strlen(object) + strlen(function) + 2);
-
-       if (nacl)
-       {
-               memset(nacl, 0, sizeof(*nacl));
-               nacl->function = nacl->object + 1;
-               nacl->function += sprintf(nacl->object, "%s", object);
-               sprintf(nacl->function, "%s", function);
-
-               nacl->avl.key = nacl->object;
-               avl_insert(&ses->acls, &nacl->avl);
-       }
-
-       return 0;
-}
-
-static int
-uh_ubus_session_revoke(struct uh_ubus_session *ses, struct ubus_context *ctx,
-                                          const char *object, const char *function)
-{
-       struct uh_ubus_session_acl *acl, *nacl;
-
-       if (!object && !function)
-       {
-               avl_remove_all_elements(&ses->acls, acl, avl, nacl)
-                       free(acl);
-       }
-       else
-       {
-               avl_for_each_element_safe(&ses->acls, acl, avl, nacl)
-               {
-                       if (uh_ubus_strmatch(acl->object, object) &&
-                               uh_ubus_strmatch(acl->function, function))
-                       {
-                               avl_delete(&ses->acls, &acl->avl);
-                               free(acl);
-                       }
-               }
-       }
-
-       return 0;
-}
-
-
-static int
-uh_ubus_handle_grant(struct ubus_context *ctx, struct ubus_object *obj,
-                                        struct ubus_request_data *req, const char *method,
-                                        struct blob_attr *msg)
-{
-       struct uh_ubus_state *state = container_of(obj, struct uh_ubus_state, ubus);
-       struct uh_ubus_session *ses;
-       struct blob_attr *tb[__UH_UBUS_SA_MAX];
-       struct blob_attr *attr, *sattr;
-       const char *object, *function;
-       int rem1, rem2;
-
-       blobmsg_parse(acl_policy, __UH_UBUS_SA_MAX, tb, blob_data(msg), blob_len(msg));
-
-       if (!tb[UH_UBUS_SA_SID] || !tb[UH_UBUS_SA_OBJECTS])
-               return UBUS_STATUS_INVALID_ARGUMENT;
-
-       ses = uh_ubus_session_get(state, blobmsg_data(tb[UH_UBUS_SA_SID]));
-
-       if (!ses)
-               return UBUS_STATUS_NOT_FOUND;
-
-       blobmsg_for_each_attr(attr, tb[UH_UBUS_SA_OBJECTS], rem1)
-       {
-               if (blob_id(attr) != BLOBMSG_TYPE_ARRAY)
-                       continue;
-
-               object = NULL;
-               function = NULL;
-
-               blobmsg_for_each_attr(sattr, attr, rem2)
-               {
-                       if (blob_id(sattr) != BLOBMSG_TYPE_STRING)
-                               continue;
-
-                       if (!object)
-                               object = blobmsg_data(sattr);
-                       else if (!function)
-                               function = blobmsg_data(sattr);
-                       else
-                               break;
-               }
-
-               if (object && function)
-                       uh_ubus_session_grant(ses, ctx, object, function);
-       }
-
-       return 0;
-}
-
-static int
-uh_ubus_handle_revoke(struct ubus_context *ctx, struct ubus_object *obj,
-                                         struct ubus_request_data *req, const char *method,
-                                         struct blob_attr *msg)
-{
-       struct uh_ubus_state *state = container_of(obj, struct uh_ubus_state, ubus);
-       struct uh_ubus_session *ses;
-       struct blob_attr *tb[__UH_UBUS_SA_MAX];
-       struct blob_attr *attr, *sattr;
-       const char *object, *function;
-       int rem1, rem2;
-
-       blobmsg_parse(acl_policy, __UH_UBUS_SA_MAX, tb, blob_data(msg), blob_len(msg));
-
-       if (!tb[UH_UBUS_SA_SID])
-               return UBUS_STATUS_INVALID_ARGUMENT;
-
-       ses = uh_ubus_session_get(state, blobmsg_data(tb[UH_UBUS_SA_SID]));
-
-       if (!ses)
-               return UBUS_STATUS_NOT_FOUND;
-
-       if (!tb[UH_UBUS_SA_OBJECTS])
-       {
-               uh_ubus_session_revoke(ses, ctx, NULL, NULL);
-       }
-       else
-       {
-               blobmsg_for_each_attr(attr, tb[UH_UBUS_SA_OBJECTS], rem1)
-               {
-                       if (blob_id(attr) != BLOBMSG_TYPE_ARRAY)
-                               continue;
-
-                       object = NULL;
-                       function = NULL;
-
-                       blobmsg_for_each_attr(sattr, attr, rem2)
-                       {
-                               if (blob_id(sattr) != BLOBMSG_TYPE_STRING)
-                                       continue;
-
-                               if (!object)
-                                       object = blobmsg_data(sattr);
-                               else if (!function)
-                                       function = blobmsg_data(sattr);
-                               else
-                                       break;
-                       }
-
-                       if (object && function)
-                               uh_ubus_session_revoke(ses, ctx, object, function);
-               }
-       }
-
-       return 0;
-}
-
-static int
-uh_ubus_handle_set(struct ubus_context *ctx, struct ubus_object *obj,
-                                  struct ubus_request_data *req, const char *method,
-                                  struct blob_attr *msg)
-{
-       struct uh_ubus_state *state = container_of(obj, struct uh_ubus_state, ubus);
-       struct uh_ubus_session *ses;
-       struct uh_ubus_session_data *data;
-       struct blob_attr *tb[__UH_UBUS_SA_MAX];
-       struct blob_attr *attr;
-       int rem;
-
-       blobmsg_parse(set_policy, __UH_UBUS_SS_MAX, tb, blob_data(msg), blob_len(msg));
-
-       if (!tb[UH_UBUS_SS_SID] || !tb[UH_UBUS_SS_VALUES])
-               return UBUS_STATUS_INVALID_ARGUMENT;
-
-       ses = uh_ubus_session_get(state, blobmsg_data(tb[UH_UBUS_SS_SID]));
-
-       if (!ses)
-               return UBUS_STATUS_NOT_FOUND;
-
-       blobmsg_for_each_attr(attr, tb[UH_UBUS_SS_VALUES], rem)
-       {
-               if (!blobmsg_name(attr)[0])
-                       continue;
-
-               data = avl_find_element(&ses->data, blobmsg_name(attr), data, avl);
-
-               if (data)
-               {
-                       avl_delete(&ses->data, &data->avl);
-                       free(data);
-               }
-
-               data = malloc(sizeof(*data) + blob_pad_len(attr));
-
-               if (!data)
-                       break;
-
-               memset(data, 0, sizeof(*data) + blob_pad_len(attr));
-               memcpy(data->attr, attr, blob_pad_len(attr));
-
-               data->avl.key = blobmsg_name(data->attr);
-               avl_insert(&ses->data, &data->avl);
-       }
-
-       return 0;
-}
-
-static int
-uh_ubus_handle_get(struct ubus_context *ctx, struct ubus_object *obj,
-                                  struct ubus_request_data *req, const char *method,
-                                  struct blob_attr *msg)
-{
-       struct uh_ubus_state *state = container_of(obj, struct uh_ubus_state, ubus);
-       struct uh_ubus_session *ses;
-       struct uh_ubus_session_data *data;
-       struct blob_attr *tb[__UH_UBUS_SA_MAX];
-       struct blob_attr *attr;
-       struct blob_buf b;
-       void *c;
-       int rem;
-
-       blobmsg_parse(get_policy, __UH_UBUS_SG_MAX, tb, blob_data(msg), blob_len(msg));
-
-       if (!tb[UH_UBUS_SG_SID])
-               return UBUS_STATUS_INVALID_ARGUMENT;
-
-       ses = uh_ubus_session_get(state, blobmsg_data(tb[UH_UBUS_SG_SID]));
-
-       if (!ses)
-               return UBUS_STATUS_NOT_FOUND;
-
-       memset(&b, 0, sizeof(b));
-       blob_buf_init(&b, 0);
-       c = blobmsg_open_table(&b, "values");
-
-       if (!tb[UH_UBUS_SG_KEYS])
-       {
-               uh_ubus_session_dump_data(ses, &b);
-       }
-       else
-       {
-               blobmsg_for_each_attr(attr, tb[UH_UBUS_SG_KEYS], rem)
-               {
-                       if (blob_id(attr) != BLOBMSG_TYPE_STRING)
-                               continue;
-
-                       data = avl_find_element(&ses->data, blobmsg_data(attr), data, avl);
-
-                       if (!data)
-                               continue;
-
-                       blobmsg_add_field(&b, blobmsg_type(data->attr),
-                                                         blobmsg_name(data->attr),
-                                                         blobmsg_data(data->attr),
-                                                         blobmsg_data_len(data->attr));
-               }
-       }
-
-       blobmsg_close_table(&b, c);
-       ubus_send_reply(ctx, req, b.head);
-       blob_buf_free(&b);
-
-       return 0;
-}
-
-static int
-uh_ubus_handle_unset(struct ubus_context *ctx, struct ubus_object *obj,
-                                    struct ubus_request_data *req, const char *method,
-                                    struct blob_attr *msg)
-{
-       struct uh_ubus_state *state = container_of(obj, struct uh_ubus_state, ubus);
-       struct uh_ubus_session *ses;
-       struct uh_ubus_session_data *data, *ndata;
-       struct blob_attr *tb[__UH_UBUS_SA_MAX];
-       struct blob_attr *attr;
-       int rem;
-
-       blobmsg_parse(get_policy, __UH_UBUS_SG_MAX, tb, blob_data(msg), blob_len(msg));
-
-       if (!tb[UH_UBUS_SG_SID])
-               return UBUS_STATUS_INVALID_ARGUMENT;
-
-       ses = uh_ubus_session_get(state, blobmsg_data(tb[UH_UBUS_SG_SID]));
-
-       if (!ses)
-               return UBUS_STATUS_NOT_FOUND;
-
-       if (!tb[UH_UBUS_SG_KEYS])
-       {
-               avl_remove_all_elements(&ses->data, data, avl, ndata)
-                       free(data);
-       }
-       else
-       {
-               blobmsg_for_each_attr(attr, tb[UH_UBUS_SG_KEYS], rem)
-               {
-                       if (blob_id(attr) != BLOBMSG_TYPE_STRING)
-                               continue;
-
-                       data = avl_find_element(&ses->data, blobmsg_data(attr), data, avl);
-
-                       if (!data)
-                               continue;
-
-                       avl_delete(&ses->data, &data->avl);
-                       free(data);
-               }
-       }
-
-       return 0;
-}
-
-static int
-uh_ubus_handle_destroy(struct ubus_context *ctx, struct ubus_object *obj,
-                                          struct ubus_request_data *req, const char *method,
-                                          struct blob_attr *msg)
-{
-       struct uh_ubus_state *state = container_of(obj, struct uh_ubus_state, ubus);
-       struct uh_ubus_session *ses;
-       struct blob_attr *tb[__UH_UBUS_SA_MAX];
-
-       blobmsg_parse(sid_policy, __UH_UBUS_SI_MAX, tb, blob_data(msg), blob_len(msg));
-
-       if (!tb[UH_UBUS_SI_SID])
-               return UBUS_STATUS_INVALID_ARGUMENT;
-
-       ses = uh_ubus_session_get(state, blobmsg_data(tb[UH_UBUS_SI_SID]));
-
-       if (!ses)
-               return UBUS_STATUS_NOT_FOUND;
-
-       uh_ubus_session_destroy(state, ses);
-
-       return 0;
-}
-
-
-struct uh_ubus_state *
-uh_ubus_init(const struct config *conf)
-{
-       int rv;
-       struct uh_ubus_state *state;
-       struct ubus_object *session_object;
-
-       static struct ubus_method session_methods[] = {
-               UBUS_METHOD("create",  uh_ubus_handle_create,  new_policy),
-               UBUS_METHOD("list",    uh_ubus_handle_list,    sid_policy),
-               UBUS_METHOD("grant",   uh_ubus_handle_grant,   acl_policy),
-               UBUS_METHOD("revoke",  uh_ubus_handle_revoke,  acl_policy),
-               UBUS_METHOD("set",     uh_ubus_handle_set,     set_policy),
-               UBUS_METHOD("get",     uh_ubus_handle_get,     get_policy),
-               UBUS_METHOD("unset",   uh_ubus_handle_unset,   get_policy),
-               UBUS_METHOD("destroy", uh_ubus_handle_destroy, sid_policy),
-       };
-
-       static struct ubus_object_type session_type =
-               UBUS_OBJECT_TYPE("uhttpd", session_methods);
-
-       state = malloc(sizeof(*state));
-
-       if (!state)
-       {
-               fprintf(stderr, "Unable to allocate memory for ubus state\n");
-               exit(1);
-       }
-
-       memset(state, 0, sizeof(*state));
-       state->ctx = ubus_connect(conf->ubus_socket);
-       state->timeout = conf->script_timeout;
-
-       if (!state->ctx)
-       {
-               fprintf(stderr, "Unable to connect to ubus socket\n");
-               exit(1);
-       }
-
-       ubus_add_uloop(state->ctx);
-
-       session_object = &state->ubus;
-       session_object->name = "session";
-       session_object->type = &session_type;
-       session_object->methods = session_methods;
-       session_object->n_methods = ARRAY_SIZE(session_methods);
-
-       rv = ubus_add_object(state->ctx, &state->ubus);
-
-       if (rv)
-       {
-               fprintf(stderr, "Unable to publish ubus object: %s\n",
-                               ubus_strerror(rv));
-               exit(1);
-       }
-
-       blob_buf_init(&state->buf, 0);
-       avl_init(&state->sessions, uh_ubus_avlcmp, false, NULL);
-
-       return state;
-}
-
-
-static bool
-uh_ubus_request_parse_url(struct client *cl, char **sid, char **obj, char **fun)
-{
-       char *url = cl->request.url + strlen(cl->server->conf->ubus_prefix);
-
-       for (; url && *url == '/'; *url++ = 0);
-       *sid = url;
-
-       for (url = url ? strchr(url, '/') : NULL; url && *url == '/'; *url++ = 0);
-       *obj = url;
-
-       for (url = url ? strchr(url, '/') : NULL; url && *url == '/'; *url++ = 0);
-       *fun = url;
-
-       for (url = url ? strchr(url, '/') : NULL; url && *url == '/'; *url++ = 0);
-       return (*sid && *obj && *fun);
-}
-
-static bool
-uh_ubus_request_parse_post(struct client *cl, int len, struct blob_buf *b)
-{
-       int rlen;
-       bool rv = false;
-       char buf[UH_LIMIT_MSGHEAD];
-
-       struct json_object *obj = NULL;
-       struct json_tokener *tok = NULL;
-
-       if (!len)
-               return NULL;
-
-       memset(b, 0, sizeof(*b));
-       blob_buf_init(b, 0);
-
-       tok = json_tokener_new();
-
-       while (len > 0)
-       {
-               /* remaining data in http head buffer ... */
-               if (cl->httpbuf.len > 0)
-               {
-                       rlen = min(len, cl->httpbuf.len);
-
-                       D("ubus: feed %d HTTP buffer bytes\n", rlen);
-
-                       memcpy(buf, cl->httpbuf.ptr, rlen);
-
-                       cl->httpbuf.len -= rlen;
-                       cl->httpbuf.ptr += rlen;
-               }
-
-               /* read it from socket ... */
-               else
-               {
-                       ensure_out(rlen = uh_tcp_recv(cl, buf, min(len, sizeof(buf))));
-
-                       if ((rlen < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
-                               break;
-
-                       D("ubus: feed %d/%d TCP socket bytes\n",
-                         rlen, min(len, sizeof(buf)));
-               }
-
-               obj = json_tokener_parse_ex(tok, buf, rlen);
-               len -= rlen;
-
-               if (tok->err != json_tokener_continue && !is_error(obj))
-                       break;
-       }
-
-out:
-       if (!is_error(obj))
-       {
-               if (json_object_get_type(obj) == json_type_object)
-               {
-                       rv = true;
-                       json_object_object_foreach(obj, key, val)
-                       {
-                               if (!blobmsg_add_json_element(b, key, val))
-                               {
-                                       rv = false;
-                                       break;
-                               }
-                       }
-               }
-
-               json_object_put(obj);
-       }
-
-       json_tokener_free(tok);
-
-       if (!rv)
-               blob_buf_free(b);
-
-       return rv;
-}
-
-static void
-uh_ubus_request_cb(struct ubus_request *req, int type, struct blob_attr *msg)
-{
-       int len;
-       char *str;
-       struct client *cl = (struct client *)req->priv;
-
-       if (!msg)
-       {
-               uh_http_sendhf(cl, 204, "No content", "Function did not return data\n");
-               return;
-       }
-
-       str = blobmsg_format_json_indent(msg, true, 0);
-       len = strlen(str);
-
-       ensure_out(uh_http_sendf(cl, NULL, "HTTP/1.0 200 OK\r\n"));
-       ensure_out(uh_http_sendf(cl, NULL, "Content-Type: application/json\r\n"));
-       ensure_out(uh_http_sendf(cl, NULL, "Content-Length: %i\r\n\r\n", len));
-       ensure_out(uh_http_send(cl, NULL, str, len));
-
-out:
-       free(str);
-}
-
-bool
-uh_ubus_request(struct client *cl, struct uh_ubus_state *state)
-{
-       int i, len = 0;
-       bool access = false;
-       char *sid, *obj, *fun;
-
-       struct blob_buf buf;
-       struct uh_ubus_session *ses;
-       struct uh_ubus_session_acl *acl;
-
-       uint32_t obj_id;
-
-
-       memset(&buf, 0, sizeof(buf));
-       blob_buf_init(&buf, 0);
-
-       if (!uh_ubus_request_parse_url(cl, &sid, &obj, &fun))
-       {
-               uh_http_sendhf(cl, 400, "Bad Request", "Invalid Request\n");
-               goto out;
-       }
-
-       if (!(ses = uh_ubus_session_get(state, sid)))
-       {
-               uh_http_sendhf(cl, 404, "Not Found", "No such session\n");
-               goto out;
-       }
-
-       avl_for_each_element(&ses->acls, acl, avl)
-       {
-               if (uh_ubus_strmatch(obj, acl->object) &&
-                       uh_ubus_strmatch(fun, acl->function))
-               {
-                       access = true;
-                       break;
-               }
-       }
-
-       if (!access)
-       {
-               uh_http_sendhf(cl, 403, "Denied", "Access to object denied\n");
-               goto out;
-       }
-
-       /* find content length */
-       if (cl->request.method == UH_HTTP_MSG_POST)
-       {
-               foreach_header(i, cl->request.headers)
-               {
-                       if (!strcasecmp(cl->request.headers[i], "Content-Length"))
-                       {
-                               len = atoi(cl->request.headers[i+1]);
-                               break;
-                       }
-               }
-       }
-
-       if (len > UH_UBUS_MAX_POST_SIZE)
-       {
-               uh_http_sendhf(cl, 413, "Too Large", "Message too big\n");
-               goto out;
-       }
-
-       if (len && !uh_ubus_request_parse_post(cl, len, &buf))
-       {
-               uh_http_sendhf(cl, 400, "Bad Request", "Invalid JSON data\n");
-               goto out;
-       }
-
-       if (ubus_lookup_id(state->ctx, obj, &obj_id))
-       {
-               uh_http_sendhf(cl, 500, "Internal Error", "Unable to lookup object\n");
-               goto out;
-       }
-
-       if (ubus_invoke(state->ctx, obj_id, fun, buf.head,
-                                       uh_ubus_request_cb, cl, state->timeout * 1000))
-       {
-               uh_http_sendhf(cl, 500, "Internal Error", "Unable to invoke function\n");
-               goto out;
-       }
-
-out:
-       blob_buf_free(&buf);
-       return false;
-}
-
-void
-uh_ubus_close(struct uh_ubus_state *state)
-{
-       if (state->ctx)
-               ubus_free(state->ctx);
-
-       free(state);
-}
diff --git a/package/network/services/uhttpd/src/uhttpd-ubus.h b/package/network/services/uhttpd/src/uhttpd-ubus.h
deleted file mode 100644 (file)
index 777ce27..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - ubus header
- *
- *   Copyright (C) 2012 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#ifndef _UHTTPD_UBUS_
-
-#include <time.h>
-
-#include <libubus.h>
-#include <libubox/avl.h>
-#include <libubox/blobmsg_json.h>
-#include <json/json.h>
-
-
-#define UH_UBUS_MAX_POST_SIZE  4096
-
-
-struct uh_ubus_state {
-       struct ubus_context *ctx;
-       struct ubus_object ubus;
-       struct blob_buf buf;
-       struct avl_tree sessions;
-       int timeout;
-};
-
-struct uh_ubus_request_data {
-       const char *sid;
-       const char *object;
-       const char *function;
-};
-
-struct uh_ubus_session {
-       char id[33];
-       int timeout;
-       struct avl_node avl;
-       struct avl_tree data;
-       struct avl_tree acls;
-       struct timespec touched;
-};
-
-struct uh_ubus_session_data {
-       struct avl_node avl;
-       struct blob_attr attr[];
-};
-
-struct uh_ubus_session_acl {
-       struct avl_node avl;
-       char *function;
-       char object[];
-};
-
-struct uh_ubus_state * uh_ubus_init(const struct config *conf);
-bool uh_ubus_request(struct client *cl, struct uh_ubus_state *state);
-void uh_ubus_close(struct uh_ubus_state *state);
-
-#endif
diff --git a/package/network/services/uhttpd/src/uhttpd-utils.c b/package/network/services/uhttpd/src/uhttpd-utils.c
deleted file mode 100644 (file)
index c8d3bb4..0000000
+++ /dev/null
@@ -1,1081 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - Utility functions
- *
- *   Copyright (C) 2010-2012 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#define _XOPEN_SOURCE 500      /* crypt() */
-#define _BSD_SOURCE                    /* strcasecmp(), strncasecmp() */
-
-#include "uhttpd.h"
-#include "uhttpd-utils.h"
-
-#ifdef HAVE_TLS
-#include "uhttpd-tls.h"
-#endif
-
-
-static char *uh_index_files[] = {
-       "index.html",
-       "index.htm",
-       "default.html",
-       "default.htm"
-};
-
-
-const char * sa_straddr(void *sa)
-{
-       static char str[INET6_ADDRSTRLEN];
-       struct sockaddr_in *v4 = (struct sockaddr_in *)sa;
-       struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)sa;
-
-       if (v4->sin_family == AF_INET)
-               return inet_ntop(AF_INET, &(v4->sin_addr), str, sizeof(str));
-       else
-               return inet_ntop(AF_INET6, &(v6->sin6_addr), str, sizeof(str));
-}
-
-const char * sa_strport(void *sa)
-{
-       static char str[6];
-       snprintf(str, sizeof(str), "%i", sa_port(sa));
-       return str;
-}
-
-int sa_port(void *sa)
-{
-       return ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
-}
-
-int sa_rfc1918(void *sa)
-{
-       struct sockaddr_in *v4 = (struct sockaddr_in *)sa;
-       unsigned long a = htonl(v4->sin_addr.s_addr);
-
-       if (v4->sin_family == AF_INET)
-       {
-               return ((a >= 0x0A000000) && (a <= 0x0AFFFFFF)) ||
-                      ((a >= 0xAC100000) && (a <= 0xAC1FFFFF)) ||
-                      ((a >= 0xC0A80000) && (a <= 0xC0A8FFFF));
-       }
-
-       return 0;
-}
-
-/* Simple strstr() like function that takes len arguments for both haystack and needle. */
-char *strfind(char *haystack, int hslen, const char *needle, int ndlen)
-{
-       int match = 0;
-       int i, j;
-
-       for (i = 0; i < hslen; i++)
-       {
-               if (haystack[i] == needle[0])
-               {
-                       match = ((ndlen == 1) || ((i + ndlen) <= hslen));
-
-                       for (j = 1; (j < ndlen) && ((i + j) < hslen); j++)
-                       {
-                               if (haystack[i+j] != needle[j])
-                               {
-                                       match = 0;
-                                       break;
-                               }
-                       }
-
-                       if (match)
-                               return &haystack[i];
-               }
-       }
-
-       return NULL;
-}
-
-bool uh_socket_wait(int fd, int sec, bool write)
-{
-       int rv;
-       struct timeval timeout;
-
-       fd_set fds;
-
-       FD_ZERO(&fds);
-       FD_SET(fd, &fds);
-
-       timeout.tv_sec = sec;
-       timeout.tv_usec = 0;
-
-       while (((rv = select(fd+1, write ? NULL : &fds, write ? &fds : NULL,
-                                                NULL, &timeout)) < 0) && (errno == EINTR))
-       {
-               D("IO: FD(%d) select interrupted: %s\n",
-                               fd, strerror(errno));
-
-               continue;
-       }
-
-       if (rv <= 0)
-       {
-               D("IO: FD(%d) appears dead (rv=%d)\n", fd, rv);
-               return false;
-       }
-
-       return true;
-}
-
-static int __uh_raw_send(struct client *cl, const char *buf, int len, int sec,
-                                                int (*wfn) (struct client *, const char *, int))
-{
-       ssize_t rv;
-       int fd = cl->fd.fd;
-
-       while (true)
-       {
-               if ((rv = wfn(cl, buf, len)) < 0)
-               {
-                       if (errno == EINTR)
-                       {
-                               D("IO: FD(%d) interrupted\n", cl->fd.fd);
-                               continue;
-                       }
-                       else if ((sec > 0) && (errno == EAGAIN || errno == EWOULDBLOCK))
-                       {
-                               if (!uh_socket_wait(fd, sec, true))
-                                       return -1;
-                       }
-                       else
-                       {
-                               D("IO: FD(%d) write error: %s\n", fd, strerror(errno));
-                               return -1;
-                       }
-               }
-               /*
-                * It is not entirely clear whether rv = 0 on nonblocking sockets
-                * is an error. In real world fuzzing tests, not handling it as close
-                * led to tight infinite loops in this send procedure, so treat it as
-                * closed and break out.
-                */
-               else if (rv == 0)
-               {
-                       D("IO: FD(%d) appears closed\n", fd);
-                       return 0;
-               }
-               else if (rv < len)
-               {
-                       D("IO: FD(%d) short write %d/%d bytes\n", fd, rv, len);
-                       len -= rv;
-                       buf += rv;
-                       continue;
-               }
-               else
-               {
-                       D("IO: FD(%d) sent %d/%d bytes\n", fd, rv, len);
-                       return rv;
-               }
-       }
-}
-
-int uh_tcp_send_lowlevel(struct client *cl, const char *buf, int len)
-{
-       return write(cl->fd.fd, buf, len);
-}
-
-int uh_raw_send(int fd, const char *buf, int len, int sec)
-{
-       struct client_light cl = { .fd = { .fd = fd } };
-       return __uh_raw_send((struct client *)&cl, buf, len, sec,
-                                                uh_tcp_send_lowlevel);
-}
-
-int uh_tcp_send(struct client *cl, const char *buf, int len)
-{
-       int seconds = cl->server->conf->network_timeout;
-#ifdef HAVE_TLS
-       if (cl->tls)
-               return __uh_raw_send(cl, buf, len, seconds,
-                                                        cl->server->conf->tls_send);
-#endif
-       return __uh_raw_send(cl, buf, len, seconds, uh_tcp_send_lowlevel);
-}
-
-static int __uh_raw_recv(struct client *cl, char *buf, int len, int sec,
-                                                int (*rfn) (struct client *, char *, int))
-{
-       ssize_t rv;
-       int fd = cl->fd.fd;
-
-       while (true)
-       {
-               if ((rv = rfn(cl, buf, len)) < 0)
-               {
-                       if (errno == EINTR)
-                       {
-                               continue;
-                       }
-                       else if ((sec > 0) && (errno == EAGAIN || errno == EWOULDBLOCK))
-                       {
-                               if (!uh_socket_wait(fd, sec, false))
-                                       return -1;
-                       }
-                       else
-                       {
-                               D("IO: FD(%d) read error: %s\n", fd, strerror(errno));
-                               return -1;
-                       }
-               }
-               else if (rv == 0)
-               {
-                       D("IO: FD(%d) appears closed\n", fd);
-                       return 0;
-               }
-               else
-               {
-                       D("IO: FD(%d) read %d bytes\n", fd, rv);
-                       return rv;
-               }
-       }
-}
-
-int uh_tcp_recv_lowlevel(struct client *cl, char *buf, int len)
-{
-       return read(cl->fd.fd, buf, len);
-}
-
-int uh_raw_recv(int fd, char *buf, int len, int sec)
-{
-       struct client_light cl = { .fd = { .fd = fd } };
-       return __uh_raw_recv((struct client *)&cl, buf, len, sec,
-                                                uh_tcp_recv_lowlevel);
-}
-
-int uh_tcp_recv(struct client *cl, char *buf, int len)
-{
-       int seconds = cl->server->conf->network_timeout;
-#ifdef HAVE_TLS
-       if (cl->tls)
-               return __uh_raw_recv(cl, buf, len, seconds,
-                                                        cl->server->conf->tls_recv);
-#endif
-       return __uh_raw_recv(cl, buf, len, seconds, uh_tcp_recv_lowlevel);
-}
-
-
-int uh_http_sendhf(struct client *cl, int code, const char *summary,
-                                  const char *fmt, ...)
-{
-       va_list ap;
-
-       char buffer[UH_LIMIT_MSGHEAD];
-       int len;
-
-       len = snprintf(buffer, sizeof(buffer),
-               "HTTP/1.1 %03i %s\r\n"
-               "Connection: close\r\n"
-               "Content-Type: text/plain\r\n"
-               "Transfer-Encoding: chunked\r\n\r\n",
-                       code, summary
-       );
-
-       ensure_ret(uh_tcp_send(cl, buffer, len));
-
-       va_start(ap, fmt);
-       len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
-       va_end(ap);
-
-       ensure_ret(uh_http_sendc(cl, buffer, len));
-       ensure_ret(uh_http_sendc(cl, NULL, 0));
-
-       return 0;
-}
-
-
-int uh_http_sendc(struct client *cl, const char *data, int len)
-{
-       char chunk[8];
-       int clen;
-
-       if (len == -1)
-               len = strlen(data);
-
-       if (len > 0)
-       {
-               clen = snprintf(chunk, sizeof(chunk), "%X\r\n", len);
-               ensure_ret(uh_tcp_send(cl, chunk, clen));
-               ensure_ret(uh_tcp_send(cl, data, len));
-               ensure_ret(uh_tcp_send(cl, "\r\n", 2));
-       }
-       else
-       {
-               ensure_ret(uh_tcp_send(cl, "0\r\n\r\n", 5));
-       }
-
-       return 0;
-}
-
-int uh_http_sendf(struct client *cl, struct http_request *req,
-                                 const char *fmt, ...)
-{
-       va_list ap;
-       char buffer[UH_LIMIT_MSGHEAD];
-       int len;
-
-       va_start(ap, fmt);
-       len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
-       va_end(ap);
-
-       if ((req != NULL) && (req->version > UH_HTTP_VER_1_0))
-               ensure_ret(uh_http_sendc(cl, buffer, len));
-       else if (len > 0)
-               ensure_ret(uh_tcp_send(cl, buffer, len));
-
-       return 0;
-}
-
-int uh_http_send(struct client *cl, struct http_request *req,
-                                const char *buf, int len)
-{
-       if (len < 0)
-               len = strlen(buf);
-
-       if ((req != NULL) && (req->version > UH_HTTP_VER_1_0))
-               ensure_ret(uh_http_sendc(cl, buf, len));
-       else if (len > 0)
-               ensure_ret(uh_tcp_send(cl, buf, len));
-
-       return 0;
-}
-
-
-/* blen is the size of buf; slen is the length of src.  The input-string need
-** not be, and the output string will not be, null-terminated.  Returns the
-** length of the decoded string, -1 on buffer overflow, -2 on malformed string. */
-int uh_urldecode(char *buf, int blen, const char *src, int slen)
-{
-       int i;
-       int len = 0;
-
-#define hex(x) \
-       (((x) <= '9') ? ((x) - '0') : \
-               (((x) <= 'F') ? ((x) - 'A' + 10) : \
-                       ((x) - 'a' + 10)))
-
-       for (i = 0; (i < slen) && (len < blen); i++)
-       {
-               if (src[i] == '%')
-               {
-                       if (((i+2) < slen) && isxdigit(src[i+1]) && isxdigit(src[i+2]))
-                       {
-                               buf[len++] = (char)(16 * hex(src[i+1]) + hex(src[i+2]));
-                               i += 2;
-                       }
-                       else
-                       {
-                               /* Encoding error: it's hard to think of a
-                               ** scenario in which returning an incorrect
-                               ** 'decoding' of the malformed string is
-                               ** preferable to signaling an error condition. */
-                               #if 0 /* WORSE_IS_BETTER */
-                                   buf[len++] = '%';
-                               #else
-                                   return -2;
-                               #endif
-                       }
-               }
-               else
-               {
-                       buf[len++] = src[i];
-               }
-       }
-
-       return (i == slen) ? len : -1;
-}
-
-/* blen is the size of buf; slen is the length of src.  The input-string need
-** not be, and the output string will not be, null-terminated.  Returns the
-** length of the encoded string, or -1 on error (buffer overflow) */
-int uh_urlencode(char *buf, int blen, const char *src, int slen)
-{
-       int i;
-       int len = 0;
-       const char hex[] = "0123456789abcdef";
-
-       for (i = 0; (i < slen) && (len < blen); i++)
-       {
-               if( isalnum(src[i]) || (src[i] == '-') || (src[i] == '_') ||
-                   (src[i] == '.') || (src[i] == '~') )
-               {
-                       buf[len++] = src[i];
-               }
-               else if ((len+3) <= blen)
-               {
-                       buf[len++] = '%';
-                       buf[len++] = hex[(src[i] >> 4) & 15];
-                       buf[len++] = hex[ src[i]       & 15];
-               }
-               else
-               {
-                       len = -1;
-                       break;
-               }
-       }
-
-       return (i == slen) ? len : -1;
-}
-
-int uh_b64decode(char *buf, int blen, const unsigned char *src, int slen)
-{
-       int i = 0;
-       int len = 0;
-
-       unsigned int cin  = 0;
-       unsigned int cout = 0;
-
-
-       for (i = 0; (i <= slen) && (src[i] != 0); i++)
-       {
-               cin = src[i];
-
-               if ((cin >= '0') && (cin <= '9'))
-                       cin = cin - '0' + 52;
-               else if ((cin >= 'A') && (cin <= 'Z'))
-                       cin = cin - 'A';
-               else if ((cin >= 'a') && (cin <= 'z'))
-                       cin = cin - 'a' + 26;
-               else if (cin == '+')
-                       cin = 62;
-               else if (cin == '/')
-                       cin = 63;
-               else if (cin == '=')
-                       cin = 0;
-               else
-                       continue;
-
-               cout = (cout << 6) | cin;
-
-               if ((i % 4) == 3)
-               {
-                       if ((len + 3) < blen)
-                       {
-                               buf[len++] = (char)(cout >> 16);
-                               buf[len++] = (char)(cout >> 8);
-                               buf[len++] = (char)(cout);
-                       }
-                       else
-                       {
-                               break;
-                       }
-               }
-       }
-
-       buf[len++] = 0;
-       return len;
-}
-
-static char * canonpath(const char *path, char *path_resolved)
-{
-       char path_copy[PATH_MAX];
-       char *path_cpy = path_copy;
-       char *path_res = path_resolved;
-
-       struct stat s;
-
-
-       /* relative -> absolute */
-       if (*path != '/')
-       {
-               getcwd(path_copy, PATH_MAX);
-               strncat(path_copy, "/", PATH_MAX - strlen(path_copy));
-               strncat(path_copy, path, PATH_MAX - strlen(path_copy));
-       }
-       else
-       {
-               strncpy(path_copy, path, PATH_MAX);
-       }
-
-       /* normalize */
-       while ((*path_cpy != '\0') && (path_cpy < (path_copy + PATH_MAX - 2)))
-       {
-               if (*path_cpy == '/')
-               {
-                       /* skip repeating / */
-                       if (path_cpy[1] == '/')
-                       {
-                               path_cpy++;
-                               continue;
-                       }
-
-                       /* /./ or /../ */
-                       else if (path_cpy[1] == '.')
-                       {
-                               /* skip /./ */
-                               if ((path_cpy[2] == '/') || (path_cpy[2] == '\0'))
-                               {
-                                       path_cpy += 2;
-                                       continue;
-                               }
-
-                               /* collapse /x/../ */
-                               else if ((path_cpy[2] == '.') &&
-                                                ((path_cpy[3] == '/') || (path_cpy[3] == '\0')))
-                               {
-                                       while ((path_res > path_resolved) && (*--path_res != '/'))
-                                               ;
-
-                                       path_cpy += 3;
-                                       continue;
-                               }
-                       }
-               }
-
-               *path_res++ = *path_cpy++;
-       }
-
-       /* remove trailing slash if not root / */
-       if ((path_res > (path_resolved+1)) && (path_res[-1] == '/'))
-               path_res--;
-       else if (path_res == path_resolved)
-               *path_res++ = '/';
-
-       *path_res = '\0';
-
-       /* test access */
-       if (!stat(path_resolved, &s) && (s.st_mode & S_IROTH))
-               return path_resolved;
-
-       return NULL;
-}
-
-/* Returns NULL on error.
-** NB: improperly encoded URL should give client 400 [Bad Syntax]; returning
-** NULL here causes 404 [Not Found], but that's not too unreasonable. */
-struct path_info * uh_path_lookup(struct client *cl, const char *url)
-{
-       static char path_phys[PATH_MAX];
-       static char path_info[PATH_MAX];
-       static struct path_info p;
-
-       char buffer[UH_LIMIT_MSGHEAD];
-       char *docroot = cl->server->conf->docroot;
-       char *pathptr = NULL;
-
-       int slash = 0;
-       int no_sym = cl->server->conf->no_symlinks;
-       int i = 0;
-       struct stat s;
-
-       /* back out early if url is undefined */
-       if (url == NULL)
-               return NULL;
-
-       memset(path_phys, 0, sizeof(path_phys));
-       memset(path_info, 0, sizeof(path_info));
-       memset(buffer, 0, sizeof(buffer));
-       memset(&p, 0, sizeof(p));
-
-       /* copy docroot */
-       memcpy(buffer, docroot,
-                  min(strlen(docroot), sizeof(buffer) - 1));
-
-       /* separate query string from url */
-       if ((pathptr = strchr(url, '?')) != NULL)
-       {
-               p.query = pathptr[1] ? pathptr + 1 : NULL;
-
-               /* urldecode component w/o query */
-               if (pathptr > url)
-               {
-                       if (uh_urldecode(&buffer[strlen(docroot)],
-                                                        sizeof(buffer) - strlen(docroot) - 1,
-                                                        url, pathptr - url ) < 0)
-                       {
-                               return NULL; /* bad URL */
-                       }
-               }
-       }
-
-       /* no query string, decode all of url */
-       else
-       {
-               if (uh_urldecode(&buffer[strlen(docroot)],
-                                                sizeof(buffer) - strlen(docroot) - 1,
-                                                url, strlen(url) ) < 0)
-               {
-                       return NULL; /* bad URL */
-               }
-       }
-
-       /* create canon path */
-       for (i = strlen(buffer), slash = (buffer[max(0, i-1)] == '/'); i >= 0; i--)
-       {
-               if ((buffer[i] == 0) || (buffer[i] == '/'))
-               {
-                       memset(path_info, 0, sizeof(path_info));
-                       memcpy(path_info, buffer, min(i + 1, sizeof(path_info) - 1));
-
-                       if (no_sym ? realpath(path_info, path_phys)
-                                  : canonpath(path_info, path_phys))
-                       {
-                               memset(path_info, 0, sizeof(path_info));
-                               memcpy(path_info, &buffer[i],
-                                          min(strlen(buffer) - i, sizeof(path_info) - 1));
-
-                               break;
-                       }
-               }
-       }
-
-       /* check whether found path is within docroot */
-       if (strncmp(path_phys, docroot, strlen(docroot)) ||
-               ((path_phys[strlen(docroot)] != 0) &&
-                (path_phys[strlen(docroot)] != '/')))
-       {
-               return NULL;
-       }
-
-       /* test current path */
-       if (!stat(path_phys, &p.stat))
-       {
-               /* is a regular file */
-               if (p.stat.st_mode & S_IFREG)
-               {
-                       p.root = docroot;
-                       p.phys = path_phys;
-                       p.name = &path_phys[strlen(docroot)];
-                       p.info = path_info[0] ? path_info : NULL;
-               }
-
-               /* is a directory */
-               else if ((p.stat.st_mode & S_IFDIR) && !strlen(path_info))
-               {
-                       /* ensure trailing slash */
-                       if (path_phys[strlen(path_phys)-1] != '/')
-                               path_phys[strlen(path_phys)] = '/';
-
-                       /* try to locate index file */
-                       memset(buffer, 0, sizeof(buffer));
-                       memcpy(buffer, path_phys, sizeof(buffer));
-                       pathptr = &buffer[strlen(buffer)];
-
-                       /* if requested url resolves to a directory and a trailing slash
-                          is missing in the request url, redirect the client to the same
-                          url with trailing slash appended */
-                       if (!slash)
-                       {
-                               uh_http_sendf(cl, NULL,
-                                       "HTTP/1.1 302 Found\r\n"
-                                       "Location: %s%s%s\r\n"
-                                       "Connection: close\r\n\r\n",
-                                               &path_phys[strlen(docroot)],
-                                               p.query ? "?" : "",
-                                               p.query ? p.query : ""
-                               );
-
-                               p.redirected = 1;
-                       }
-                       else if (cl->server->conf->index_file)
-                       {
-                               strncat(buffer, cl->server->conf->index_file, sizeof(buffer));
-
-                               if (!stat(buffer, &s) && (s.st_mode & S_IFREG))
-                               {
-                                       memcpy(path_phys, buffer, sizeof(path_phys));
-                                       memcpy(&p.stat, &s, sizeof(p.stat));
-                               }
-                       }
-                       else
-                       {
-                               for (i = 0; i < array_size(uh_index_files); i++)
-                               {
-                                       strncat(buffer, uh_index_files[i], sizeof(buffer));
-
-                                       if (!stat(buffer, &s) && (s.st_mode & S_IFREG))
-                                       {
-                                               memcpy(path_phys, buffer, sizeof(path_phys));
-                                               memcpy(&p.stat, &s, sizeof(p.stat));
-                                               break;
-                                       }
-
-                                       *pathptr = 0;
-                               }
-                       }
-
-                       p.root = docroot;
-                       p.phys = path_phys;
-                       p.name = &path_phys[strlen(docroot)];
-               }
-       }
-
-       return p.phys ? &p : NULL;
-}
-
-
-static struct auth_realm *uh_realms = NULL;
-
-struct auth_realm * uh_auth_add(char *path, char *user, char *pass)
-{
-       struct auth_realm *new = NULL;
-       struct passwd *pwd;
-
-#ifdef HAVE_SHADOW
-       struct spwd *spwd;
-#endif
-
-       if((new = (struct auth_realm *)malloc(sizeof(struct auth_realm))) != NULL)
-       {
-               memset(new, 0, sizeof(struct auth_realm));
-
-               memcpy(new->path, path,
-                          min(strlen(path), sizeof(new->path) - 1));
-
-               memcpy(new->user, user,
-                          min(strlen(user), sizeof(new->user) - 1));
-
-               /* given password refers to a passwd entry */
-               if ((strlen(pass) > 3) && !strncmp(pass, "$p$", 3))
-               {
-#ifdef HAVE_SHADOW
-                       /* try to resolve shadow entry */
-                       if (((spwd = getspnam(&pass[3])) != NULL) && spwd->sp_pwdp)
-                       {
-                               memcpy(new->pass, spwd->sp_pwdp,
-                                          min(strlen(spwd->sp_pwdp), sizeof(new->pass) - 1));
-                       }
-
-                       else
-#endif
-
-                       /* try to resolve passwd entry */
-                       if (((pwd = getpwnam(&pass[3])) != NULL) && pwd->pw_passwd &&
-                               (pwd->pw_passwd[0] != '!') && (pwd->pw_passwd[0] != 0))
-                       {
-                               memcpy(new->pass, pwd->pw_passwd,
-                                          min(strlen(pwd->pw_passwd), sizeof(new->pass) - 1));
-                       }
-               }
-
-               /* ordinary pwd */
-               else
-               {
-                       memcpy(new->pass, pass,
-                               min(strlen(pass), sizeof(new->pass) - 1));
-               }
-
-               if (new->pass[0])
-               {
-                       new->next = uh_realms;
-                       uh_realms = new;
-
-                       return new;
-               }
-
-               free(new);
-       }
-
-       return NULL;
-}
-
-int uh_auth_check(struct client *cl, struct http_request *req,
-                                 struct path_info *pi)
-{
-       int i, plen, rlen, protected;
-       char buffer[UH_LIMIT_MSGHEAD];
-       char *user = NULL;
-       char *pass = NULL;
-
-       struct auth_realm *realm = NULL;
-
-       plen = strlen(pi->name);
-       protected = 0;
-
-       /* check whether at least one realm covers the requested url */
-       for (realm = uh_realms; realm; realm = realm->next)
-       {
-               rlen = strlen(realm->path);
-
-               if ((plen >= rlen) && !strncasecmp(pi->name, realm->path, rlen))
-               {
-                       req->realm = realm;
-                       protected = 1;
-                       break;
-               }
-       }
-
-       /* requested resource is covered by a realm */
-       if (protected)
-       {
-               /* try to get client auth info */
-               foreach_header(i, req->headers)
-               {
-                       if (!strcasecmp(req->headers[i], "Authorization") &&
-                               (strlen(req->headers[i+1]) > 6) &&
-                               !strncasecmp(req->headers[i+1], "Basic ", 6))
-                       {
-                               memset(buffer, 0, sizeof(buffer));
-                               uh_b64decode(buffer, sizeof(buffer) - 1,
-                                       (unsigned char *) &req->headers[i+1][6],
-                                       strlen(req->headers[i+1]) - 6);
-
-                               if ((pass = strchr(buffer, ':')) != NULL)
-                               {
-                                       user = buffer;
-                                       *pass++ = 0;
-                               }
-
-                               break;
-                       }
-               }
-
-               /* have client auth */
-               if (user && pass)
-               {
-                       /* find matching realm */
-                       for (realm = uh_realms; realm; realm = realm->next)
-                       {
-                               rlen = strlen(realm->path);
-
-                               if ((plen >= rlen) &&
-                                       !strncasecmp(pi->name, realm->path, rlen) &&
-                                       !strcmp(user, realm->user))
-                               {
-                                       req->realm = realm;
-                                       break;
-                               }
-                       }
-
-                       /* found a realm matching the username */
-                       if (realm)
-                       {
-                               /* check user pass */
-                               if (!strcmp(pass, realm->pass) ||
-                                   !strcmp(crypt(pass, realm->pass), realm->pass))
-                                       return 1;
-                       }
-               }
-
-               /* 401 */
-               uh_http_sendf(cl, NULL,
-                             "%s 401 Authorization Required\r\n"
-                             "WWW-Authenticate: Basic realm=\"%s\"\r\n"
-                             "Content-Type: text/plain\r\n"
-                             "Content-Length: 23\r\n\r\n"
-                             "Authorization Required\n",
-                             http_versions[req->version],
-                             cl->server->conf->realm);
-
-               return 0;
-       }
-
-       return 1;
-}
-
-
-static struct listener *uh_listeners = NULL;
-static struct client *uh_clients = NULL;
-
-struct listener * uh_listener_add(int sock, struct config *conf)
-{
-       struct listener *new = NULL;
-       socklen_t sl;
-
-       if ((new = (struct listener *)malloc(sizeof(struct listener))) != NULL)
-       {
-               memset(new, 0, sizeof(struct listener));
-
-               new->fd.fd = sock;
-               new->conf  = conf;
-
-
-               /* get local endpoint addr */
-               sl = sizeof(struct sockaddr_in6);
-               memset(&(new->addr), 0, sl);
-               getsockname(sock, (struct sockaddr *) &(new->addr), &sl);
-
-               new->next = uh_listeners;
-               uh_listeners = new;
-
-               return new;
-       }
-
-       return NULL;
-}
-
-struct listener * uh_listener_lookup(int sock)
-{
-       struct listener *cur = NULL;
-
-       for (cur = uh_listeners; cur; cur = cur->next)
-               if (cur->fd.fd == sock)
-                       return cur;
-
-       return NULL;
-}
-
-
-struct client * uh_client_add(int sock, struct listener *serv,
-                              struct sockaddr_in6 *peer)
-{
-       struct client *new = NULL;
-       socklen_t sl;
-
-       if ((new = (struct client *)malloc(sizeof(struct client))) != NULL)
-       {
-               memset(new, 0, sizeof(struct client));
-               memcpy(&new->peeraddr, peer, sizeof(new->peeraddr));
-
-               new->fd.fd  = sock;
-               new->server = serv;
-
-               new->rpipe.fd = -1;
-               new->wpipe.fd = -1;
-
-               /* get local endpoint addr */
-               sl = sizeof(struct sockaddr_in6);
-               getsockname(sock, (struct sockaddr *) &(new->servaddr), &sl);
-
-               new->next = uh_clients;
-               uh_clients = new;
-
-               serv->n_clients++;
-
-               D("IO: Client(%d) allocated\n", new->fd.fd);
-       }
-
-       return new;
-}
-
-struct client * uh_client_lookup(int sock)
-{
-       struct client *cur = NULL;
-
-       for (cur = uh_clients; cur; cur = cur->next)
-               if (cur->fd.fd == sock)
-                       return cur;
-
-       return NULL;
-}
-
-void uh_client_shutdown(struct client *cl)
-{
-#ifdef HAVE_TLS
-       /* free client tls context */
-       if (cl->server && cl->server->conf->tls)
-               cl->server->conf->tls_close(cl);
-#endif
-
-       /* remove from global client list */
-       uh_client_remove(cl);
-}
-
-void uh_client_remove(struct client *cl)
-{
-       struct client *cur = NULL;
-       struct client *prv = NULL;
-
-       for (cur = uh_clients; cur; prv = cur, cur = cur->next)
-       {
-               if (cur == cl)
-               {
-                       if (prv)
-                               prv->next = cur->next;
-                       else
-                               uh_clients = cur->next;
-
-                       if (cur->timeout.pending)
-                               uloop_timeout_cancel(&cur->timeout);
-
-                       if (cur->proc.pid)
-                               uloop_process_delete(&cur->proc);
-
-                       D("IO: Client(%d) freeing\n", cur->fd.fd);
-
-                       uh_ufd_remove(&cur->rpipe);
-                       uh_ufd_remove(&cur->wpipe);
-                       uh_ufd_remove(&cur->fd);
-
-                       cur->server->n_clients--;
-
-                       free(cur);
-                       break;
-               }
-       }
-}
-
-
-void uh_ufd_add(struct uloop_fd *u, uloop_fd_handler h, unsigned int ev)
-{
-       if (h != NULL)
-       {
-               u->cb = h;
-               uloop_fd_add(u, ev);
-               D("IO: FD(%d) added to uloop\n", u->fd);
-       }
-}
-
-void uh_ufd_remove(struct uloop_fd *u)
-{
-       if (u->cb != NULL)
-       {
-               uloop_fd_delete(u);
-               D("IO: FD(%d) removed from uloop\n", u->fd);
-               u->cb = NULL;
-       }
-
-       if (u->fd > -1)
-       {
-               close(u->fd);
-               D("IO: FD(%d) closed\n", u->fd);
-               u->fd = -1;
-       }
-}
-
-
-#ifdef HAVE_CGI
-static struct interpreter *uh_interpreters = NULL;
-
-struct interpreter * uh_interpreter_add(const char *extn, const char *path)
-{
-       struct interpreter *new = NULL;
-
-       if ((new = (struct interpreter *)malloc(sizeof(struct interpreter))) != NULL)
-       {
-               memset(new, 0, sizeof(struct interpreter));
-
-               memcpy(new->extn, extn, min(strlen(extn), sizeof(new->extn)-1));
-               memcpy(new->path, path, min(strlen(path), sizeof(new->path)-1));
-
-               new->next = uh_interpreters;
-               uh_interpreters = new;
-
-               return new;
-       }
-
-       return NULL;
-}
-
-struct interpreter * uh_interpreter_lookup(const char *path)
-{
-       struct interpreter *cur = NULL;
-       const char *e;
-
-       for (cur = uh_interpreters; cur; cur = cur->next)
-       {
-               e = &path[max(strlen(path) - strlen(cur->extn), 0)];
-
-               if (!strcmp(e, cur->extn))
-                       return cur;
-       }
-
-       return NULL;
-}
-#endif
diff --git a/package/network/services/uhttpd/src/uhttpd-utils.h b/package/network/services/uhttpd/src/uhttpd-utils.h
deleted file mode 100644 (file)
index 9de9191..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - Utility header
- *
- *   Copyright (C) 2010-2012 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#ifndef _UHTTPD_UTILS_
-
-#include <stdarg.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <sys/stat.h>
-
-#include <libubox/uloop.h>
-
-
-#ifdef HAVE_SHADOW
-#include <shadow.h>
-#endif
-
-#define min(x, y) (((x) < (y)) ? (x) : (y))
-#define max(x, y) (((x) > (y)) ? (x) : (y))
-
-#define array_size(x) \
-       (sizeof(x) / sizeof(x[0]))
-
-#define foreach_header(i, h) \
-       for( i = 0; (i + 1) < (sizeof(h) / sizeof(h[0])) && h[i]; i += 2 )
-
-#define fd_cloexec(fd) \
-       fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC)
-
-#define fd_nonblock(fd) \
-       fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK)
-
-#define ensure_out(x) \
-       do { if((x) < 0) goto out; } while(0)
-
-#define ensure_ret(x) \
-       do { if((x) < 0) return -1; } while(0)
-
-
-struct path_info {
-       char *root;
-       char *phys;
-       char *name;
-       char *info;
-       char *query;
-       int redirected;
-       struct stat stat;
-};
-
-
-const char * sa_straddr(void *sa);
-const char * sa_strport(void *sa);
-int sa_port(void *sa);
-int sa_rfc1918(void *sa);
-
-char *strfind(char *haystack, int hslen, const char *needle, int ndlen);
-
-bool uh_socket_wait(int fd, int sec, bool write);
-
-int uh_raw_send(int fd, const char *buf, int len, int seconds);
-int uh_raw_recv(int fd, char *buf, int len, int seconds);
-int uh_tcp_send(struct client *cl, const char *buf, int len);
-int uh_tcp_send_lowlevel(struct client *cl, const char *buf, int len);
-int uh_tcp_recv(struct client *cl, char *buf, int len);
-int uh_tcp_recv_lowlevel(struct client *cl, char *buf, int len);
-
-int uh_http_sendhf(struct client *cl, int code, const char *summary,
-                                  const char *fmt, ...);
-
-#define uh_http_response(cl, code, message) \
-       uh_http_sendhf(cl, code, message, message)
-
-int uh_http_sendc(struct client *cl, const char *data, int len);
-
-int uh_http_sendf(
-       struct client *cl, struct http_request *req,
-       const char *fmt, ...
-);
-
-int uh_http_send(
-       struct client *cl, struct http_request *req,
-       const char *buf, int len
-);
-
-
-int uh_urldecode(char *buf, int blen, const char *src, int slen);
-int uh_urlencode(char *buf, int blen, const char *src, int slen);
-int uh_b64decode(char *buf, int blen, const unsigned char *src, int slen);
-
-
-struct auth_realm * uh_auth_add(char *path, char *user, char *pass);
-
-int uh_auth_check(
-       struct client *cl, struct http_request *req, struct path_info *pi
-);
-
-
-struct path_info * uh_path_lookup(struct client *cl, const char *url);
-
-struct listener * uh_listener_add(int sock, struct config *conf);
-struct listener * uh_listener_lookup(int sock);
-
-struct client * uh_client_add(int sock, struct listener *serv,
-                              struct sockaddr_in6 *peer);
-
-struct client * uh_client_lookup(int sock);
-
-#define uh_client_error(cl, code, status, ...) do { \
-       uh_http_sendhf(cl, code, status, __VA_ARGS__);  \
-       uh_client_shutdown(cl);                         \
-} while(0)
-
-void uh_client_shutdown(struct client *cl);
-void uh_client_remove(struct client *cl);
-
-void uh_ufd_add(struct uloop_fd *u, uloop_fd_handler h, unsigned int ev);
-void uh_ufd_remove(struct uloop_fd *u);
-
-
-#ifdef HAVE_CGI
-struct interpreter * uh_interpreter_add(const char *extn, const char *path);
-struct interpreter * uh_interpreter_lookup(const char *path);
-#endif
-
-#endif
diff --git a/package/network/services/uhttpd/src/uhttpd.c b/package/network/services/uhttpd/src/uhttpd.c
deleted file mode 100644 (file)
index 1efcbf0..0000000
+++ /dev/null
@@ -1,1288 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - Main component
- *
- *   Copyright (C) 2010 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#define _XOPEN_SOURCE 500      /* crypt() */
-
-#include "uhttpd.h"
-#include "uhttpd-utils.h"
-#include "uhttpd-file.h"
-
-#ifdef HAVE_CGI
-#include "uhttpd-cgi.h"
-#endif
-
-#ifdef HAVE_LUA
-#include "uhttpd-lua.h"
-#endif
-
-#ifdef HAVE_TLS
-#include "uhttpd-tls.h"
-#endif
-
-
-const char * http_methods[] = { "GET", "POST", "HEAD", };
-const char * http_versions[] = { "HTTP/0.9", "HTTP/1.0", "HTTP/1.1", };
-
-static int run = 1;
-
-static void uh_sigterm(int sig)
-{
-       run = 0;
-}
-
-static void uh_config_parse(struct config *conf)
-{
-       FILE *c;
-       char line[512];
-       char *col1 = NULL;
-       char *col2 = NULL;
-       char *eol  = NULL;
-
-       const char *path = conf->file ? conf->file : "/etc/httpd.conf";
-
-
-       if ((c = fopen(path, "r")) != NULL)
-       {
-               memset(line, 0, sizeof(line));
-
-               while (fgets(line, sizeof(line) - 1, c))
-               {
-                       if ((line[0] == '/') && (strchr(line, ':') != NULL))
-                       {
-                               if (!(col1 = strchr(line, ':')) || (*col1++ = 0) ||
-                                   !(col2 = strchr(col1, ':')) || (*col2++ = 0) ||
-                                       !(eol = strchr(col2, '\n')) || (*eol++  = 0))
-                               {
-                                       continue;
-                               }
-
-                               if (!uh_auth_add(line, col1, col2))
-                               {
-                                       fprintf(stderr,
-                                                       "Notice: No password set for user %s, ignoring "
-                                                       "authentication on %s\n", col1, line
-                                       );
-                               }
-                       }
-                       else if (!strncmp(line, "I:", 2))
-                       {
-                               if (!(col1 = strchr(line, ':')) || (*col1++ = 0) ||
-                                   !(eol = strchr(col1, '\n')) || (*eol++  = 0))
-                               {
-                                       continue;
-                               }
-
-                               conf->index_file = strdup(col1);
-                       }
-                       else if (!strncmp(line, "E404:", 5))
-                       {
-                               if (!(col1 = strchr(line, ':')) || (*col1++ = 0) ||
-                                   !(eol = strchr(col1, '\n')) || (*eol++  = 0))
-                               {
-                                       continue;
-                               }
-
-                               conf->error_handler = strdup(col1);
-                       }
-#ifdef HAVE_CGI
-                       else if ((line[0] == '*') && (strchr(line, ':') != NULL))
-                       {
-                               if (!(col1 = strchr(line, '*')) || (*col1++ = 0) ||
-                                   !(col2 = strchr(col1, ':')) || (*col2++ = 0) ||
-                                   !(eol = strchr(col2, '\n')) || (*eol++  = 0))
-                               {
-                                       continue;
-                               }
-
-                               if (!uh_interpreter_add(col1, col2))
-                               {
-                                       fprintf(stderr,
-                                                       "Unable to add interpreter %s for extension %s: "
-                                                       "Out of memory\n", col2, col1
-                                       );
-                               }
-                       }
-#endif
-               }
-
-               fclose(c);
-       }
-}
-
-static void uh_listener_cb(struct uloop_fd *u, unsigned int events);
-
-static int uh_socket_bind(const char *host, const char *port,
-                          struct addrinfo *hints, int do_tls,
-                          struct config *conf)
-{
-       int sock = -1;
-       int yes = 1;
-       int status;
-       int bound = 0;
-
-       int tcp_ka_idl, tcp_ka_int, tcp_ka_cnt;
-
-       struct listener *l = NULL;
-       struct addrinfo *addrs = NULL, *p = NULL;
-
-       if ((status = getaddrinfo(host, port, hints, &addrs)) != 0)
-       {
-               fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(status));
-       }
-
-       /* try to bind a new socket to each found address */
-       for (p = addrs; p; p = p->ai_next)
-       {
-               /* get the socket */
-               if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
-               {
-                       perror("socket()");
-                       goto error;
-               }
-
-               /* "address already in use" */
-               if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
-               {
-                       perror("setsockopt()");
-                       goto error;
-               }
-
-               /* TCP keep-alive */
-               if (conf->tcp_keepalive > 0)
-               {
-                       tcp_ka_idl = 1;
-                       tcp_ka_cnt = 3;
-                       tcp_ka_int = conf->tcp_keepalive;
-
-                       if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes)) ||
-                           setsockopt(sock, SOL_TCP, TCP_KEEPIDLE,  &tcp_ka_idl, sizeof(tcp_ka_idl)) ||
-                           setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &tcp_ka_int, sizeof(tcp_ka_int)) ||
-                           setsockopt(sock, SOL_TCP, TCP_KEEPCNT,   &tcp_ka_cnt, sizeof(tcp_ka_cnt)))
-                       {
-                           fprintf(stderr, "Notice: Unable to enable TCP keep-alive: %s\n",
-                               strerror(errno));
-                       }
-               }
-
-               /* required to get parallel v4 + v6 working */
-               if (p->ai_family == AF_INET6)
-               {
-                       if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes)) == -1)
-                       {
-                               perror("setsockopt()");
-                               goto error;
-                       }
-               }
-
-               /* bind */
-               if (bind(sock, p->ai_addr, p->ai_addrlen) == -1)
-               {
-                       perror("bind()");
-                       goto error;
-               }
-
-               /* listen */
-               if (listen(sock, UH_LIMIT_CLIENTS) == -1)
-               {
-                       perror("listen()");
-                       goto error;
-               }
-
-               /* add listener to global list */
-               if (!(l = uh_listener_add(sock, conf)))
-               {
-                       fprintf(stderr, "uh_listener_add(): Failed to allocate memory\n");
-                       goto error;
-               }
-
-#ifdef HAVE_TLS
-               /* init TLS */
-               l->tls = do_tls ? conf->tls : NULL;
-#endif
-
-               /* add socket to uloop */
-               fd_cloexec(sock);
-               uh_ufd_add(&l->fd, uh_listener_cb, ULOOP_READ);
-
-               bound++;
-               continue;
-
-               error:
-               if (sock > 0)
-                       close(sock);
-       }
-
-       freeaddrinfo(addrs);
-
-       return bound;
-}
-
-static struct http_request * uh_http_header_parse(struct client *cl,
-                                                                                                 char *buffer, int buflen)
-{
-       char *method  = buffer;
-       char *path    = NULL;
-       char *version = NULL;
-
-       char *headers = NULL;
-       char *hdrname = NULL;
-       char *hdrdata = NULL;
-
-       int i;
-       int hdrcount = 0;
-
-       struct http_request *req = &cl->request;
-
-
-       /* terminate initial header line */
-       if ((headers = strfind(buffer, buflen, "\r\n", 2)) != NULL)
-       {
-               buffer[buflen-1] = 0;
-
-               *headers++ = 0;
-               *headers++ = 0;
-
-               /* find request path */
-               if ((path = strchr(buffer, ' ')) != NULL)
-                       *path++ = 0;
-
-               /* find http version */
-               if ((path != NULL) && ((version = strchr(path, ' ')) != NULL))
-                       *version++ = 0;
-
-
-               /* check method */
-               if (method && !strcmp(method, "GET"))
-                       req->method = UH_HTTP_MSG_GET;
-               else if (method && !strcmp(method, "POST"))
-                       req->method = UH_HTTP_MSG_POST;
-               else if (method && !strcmp(method, "HEAD"))
-                       req->method = UH_HTTP_MSG_HEAD;
-               else
-               {
-                       /* invalid method */
-                       uh_http_response(cl, 405, "Method Not Allowed");
-                       return NULL;
-               }
-
-               /* check path */
-               if (!path || !strlen(path))
-               {
-                       /* malformed request */
-                       uh_http_response(cl, 400, "Bad Request");
-                       return NULL;
-               }
-               else
-               {
-                       req->url = path;
-               }
-
-               /* check version */
-               if (version && !strcmp(version, "HTTP/0.9"))
-                       req->version = UH_HTTP_VER_0_9;
-               else if (version && !strcmp(version, "HTTP/1.0"))
-                       req->version = UH_HTTP_VER_1_0;
-               else if (version && !strcmp(version, "HTTP/1.1"))
-                       req->version = UH_HTTP_VER_1_1;
-               else
-               {
-                       /* unsupported version */
-                       uh_http_response(cl, 400, "Bad Request");
-                       return NULL;
-               }
-
-               D("SRV: %s %s %s\n",
-                 http_methods[req->method], req->url, http_versions[req->version]);
-
-               /* process header fields */
-               for (i = (int)(headers - buffer); i < buflen; i++)
-               {
-                       /* found eol and have name + value, push out header tuple */
-                       if (hdrname && hdrdata && (buffer[i] == '\r' || buffer[i] == '\n'))
-                       {
-                               buffer[i] = 0;
-
-                               /* store */
-                               if ((hdrcount + 1) < array_size(req->headers))
-                               {
-                                       D("SRV: HTTP: %s: %s\n", hdrname, hdrdata);
-
-                                       req->headers[hdrcount++] = hdrname;
-                                       req->headers[hdrcount++] = hdrdata;
-
-                                       hdrname = hdrdata = NULL;
-                               }
-
-                               /* too large */
-                               else
-                               {
-                                       D("SRV: HTTP: header too big (too many headers)\n");
-                                       uh_http_response(cl, 413, "Request Entity Too Large");
-                                       return NULL;
-                               }
-                       }
-
-                       /* have name but no value and found a colon, start of value */
-                       else if (hdrname && !hdrdata &&
-                                        ((i+1) < buflen) && (buffer[i] == ':'))
-                       {
-                               buffer[i] = 0;
-                               hdrdata = &buffer[i+1];
-
-                               while ((hdrdata + 1) < (buffer + buflen) && *hdrdata == ' ')
-                                       hdrdata++;
-                       }
-
-                       /* have no name and found [A-Za-z], start of name */
-                       else if (!hdrname && isalpha(buffer[i]))
-                       {
-                               hdrname = &buffer[i];
-                       }
-               }
-
-               /* valid enough */
-               req->redirect_status = 200;
-               return req;
-       }
-
-       /* Malformed request */
-       uh_http_response(cl, 400, "Bad Request");
-       return NULL;
-}
-
-
-static struct http_request * uh_http_header_recv(struct client *cl)
-{
-       char *bufptr = cl->httpbuf.buf;
-       char *idxptr = NULL;
-
-       ssize_t blen = sizeof(cl->httpbuf.buf)-1;
-       ssize_t rlen = 0;
-
-       memset(bufptr, 0, sizeof(cl->httpbuf.buf));
-
-       while (blen > 0)
-       {
-               /* receive data */
-               ensure_out(rlen = uh_tcp_recv(cl, bufptr, blen));
-               D("SRV: Client(%d) peek(%d) = %d\n", cl->fd.fd, blen, rlen);
-
-               if (rlen <= 0)
-               {
-                       D("SRV: Client(%d) dead [%s]\n", cl->fd.fd, strerror(errno));
-                       return NULL;
-               }
-
-               blen -= rlen;
-               bufptr += rlen;
-
-               if ((idxptr = strfind(cl->httpbuf.buf, sizeof(cl->httpbuf.buf),
-                                                         "\r\n\r\n", 4)))
-               {
-                       /* header read complete ... */
-                       cl->httpbuf.ptr = idxptr + 4;
-                       cl->httpbuf.len = bufptr - cl->httpbuf.ptr;
-
-                       return uh_http_header_parse(cl, cl->httpbuf.buf,
-                                                                               (cl->httpbuf.ptr - cl->httpbuf.buf));
-               }
-       }
-
-       /* request entity too large */
-       D("SRV: HTTP: header too big (buffer exceeded)\n");
-       uh_http_response(cl, 413, "Request Entity Too Large");
-
-out:
-       return NULL;
-}
-
-#if defined(HAVE_LUA) || defined(HAVE_CGI)
-static int uh_path_match(const char *prefix, const char *url)
-{
-       if ((strstr(url, prefix) == url) &&
-               ((prefix[strlen(prefix)-1] == '/') ||
-                (strlen(url) == strlen(prefix))   ||
-                (url[strlen(prefix)] == '/')))
-       {
-               return 1;
-       }
-
-       return 0;
-}
-#endif
-
-static bool uh_dispatch_request(struct client *cl, struct http_request *req)
-{
-       struct path_info *pin;
-       struct interpreter *ipr = NULL;
-       struct config *conf = cl->server->conf;
-
-#ifdef HAVE_LUA
-       /* Lua request? */
-       if (conf->lua_state &&
-               uh_path_match(conf->lua_prefix, req->url))
-       {
-               return conf->lua_request(cl, conf->lua_state);
-       }
-       else
-#endif
-
-#ifdef HAVE_UBUS
-       /* ubus request? */
-       if (conf->ubus_state &&
-               uh_path_match(conf->ubus_prefix, req->url))
-       {
-               return conf->ubus_request(cl, conf->ubus_state);
-       }
-       else
-#endif
-
-       /* dispatch request */
-       if ((pin = uh_path_lookup(cl, req->url)) != NULL)
-       {
-               /* auth ok? */
-               if (!pin->redirected && uh_auth_check(cl, req, pin))
-               {
-#ifdef HAVE_CGI
-                       if (uh_path_match(conf->cgi_prefix, pin->name) ||
-                               (ipr = uh_interpreter_lookup(pin->phys)) != NULL)
-                       {
-                               return uh_cgi_request(cl, pin, ipr);
-                       }
-#endif
-                       return uh_file_request(cl, pin);
-               }
-       }
-
-       /* 404 - pass 1 */
-       else
-       {
-               /* Try to invoke an error handler */
-               if ((pin = uh_path_lookup(cl, conf->error_handler)) != NULL)
-               {
-                       /* auth ok? */
-                       if (uh_auth_check(cl, req, pin))
-                       {
-                               req->redirect_status = 404;
-#ifdef HAVE_CGI
-                               if (uh_path_match(conf->cgi_prefix, pin->name) ||
-                                       (ipr = uh_interpreter_lookup(pin->phys)) != NULL)
-                               {
-                                       return uh_cgi_request(cl, pin, ipr);
-                               }
-#endif
-                               return uh_file_request(cl, pin);
-                       }
-               }
-
-               /* 404 - pass 2 */
-               else
-               {
-                       uh_http_sendhf(cl, 404, "Not Found", "No such file or directory");
-               }
-       }
-
-       return false;
-}
-
-static void uh_socket_cb(struct uloop_fd *u, unsigned int events);
-
-static void uh_listener_cb(struct uloop_fd *u, unsigned int events)
-{
-       int new_fd;
-       struct listener *serv;
-       struct client *cl;
-       struct config *conf;
-
-       struct sockaddr_in6 sa;
-       socklen_t sl = sizeof(sa);
-
-       serv = container_of(u, struct listener, fd);
-       conf = serv->conf;
-
-       /* defer client if maximum number of requests is exceeded */
-       if (serv->n_clients >= conf->max_requests)
-               return;
-
-       /* handle new connections */
-       if ((new_fd = accept(u->fd, (struct sockaddr *)&sa, &sl)) != -1)
-       {
-               D("SRV: Server(%d) accept => Client(%d)\n", u->fd, new_fd);
-
-               /* add to global client list */
-               if ((cl = uh_client_add(new_fd, serv, &sa)) != NULL)
-               {
-                       /* add client socket to global fdset */
-                       uh_ufd_add(&cl->fd, uh_socket_cb, ULOOP_READ);
-                       fd_cloexec(cl->fd.fd);
-
-#ifdef HAVE_TLS
-                       /* setup client tls context */
-                       if (conf->tls)
-                       {
-                               if (conf->tls_accept(cl) < 1)
-                               {
-                                       D("SRV: Client(%d) SSL handshake failed, drop\n", new_fd);
-
-                                       /* remove from global client list */
-                                       uh_client_remove(cl);
-                                       return;
-                               }
-                       }
-#endif
-               }
-
-               /* insufficient resources */
-               else
-               {
-                       fprintf(stderr, "uh_client_add(): Cannot allocate memory\n");
-                       close(new_fd);
-               }
-       }
-}
-
-static void uh_client_cb(struct client *cl, unsigned int events);
-
-static void uh_rpipe_cb(struct uloop_fd *u, unsigned int events)
-{
-       struct client *cl = container_of(u, struct client, rpipe);
-
-       D("SRV: Client(%d) rpipe readable\n", cl->fd.fd);
-
-       uh_client_cb(cl, ULOOP_WRITE);
-}
-
-static void uh_socket_cb(struct uloop_fd *u, unsigned int events)
-{
-       struct client *cl = container_of(u, struct client, fd);
-
-       D("SRV: Client(%d) socket readable\n", cl->fd.fd);
-
-       uh_client_cb(cl, ULOOP_READ);
-}
-
-static void uh_child_cb(struct uloop_process *p, int rv)
-{
-       struct client *cl = container_of(p, struct client, proc);
-
-       D("SRV: Client(%d) child(%d) dead\n", cl->fd.fd, cl->proc.pid);
-
-       uh_client_cb(cl, ULOOP_READ | ULOOP_WRITE);
-}
-
-static void uh_kill9_cb(struct uloop_timeout *t)
-{
-       struct client *cl = container_of(t, struct client, timeout);
-
-       if (!kill(cl->proc.pid, 0))
-       {
-               D("SRV: Client(%d) child(%d) kill(SIGKILL)...\n",
-                 cl->fd.fd, cl->proc.pid);
-
-               kill(cl->proc.pid, SIGKILL);
-       }
-}
-
-static void uh_timeout_cb(struct uloop_timeout *t)
-{
-       struct client *cl = container_of(t, struct client, timeout);
-
-       D("SRV: Client(%d) child(%d) timed out\n", cl->fd.fd, cl->proc.pid);
-
-       if (!kill(cl->proc.pid, 0))
-       {
-               D("SRV: Client(%d) child(%d) kill(SIGTERM)...\n",
-                 cl->fd.fd, cl->proc.pid);
-
-               kill(cl->proc.pid, SIGTERM);
-
-               cl->timeout.cb = uh_kill9_cb;
-               uloop_timeout_set(&cl->timeout, 1000);
-       }
-}
-
-static void uh_client_cb(struct client *cl, unsigned int events)
-{
-       int i;
-       struct config *conf;
-       struct http_request *req;
-
-       conf = cl->server->conf;
-
-       D("SRV: Client(%d) enter callback\n", cl->fd.fd);
-
-       /* undispatched yet */
-       if (!cl->dispatched)
-       {
-               /* we have no headers yet and this was a write event, ignore... */
-               if (!(events & ULOOP_READ))
-               {
-                       D("SRV: Client(%d) ignoring write event before headers\n", cl->fd.fd);
-                       return;
-               }
-
-               /* attempt to receive and parse headers */
-               if (!(req = uh_http_header_recv(cl)))
-               {
-                       D("SRV: Client(%d) failed to receive header\n", cl->fd.fd);
-                       uh_client_shutdown(cl);
-                       return;
-               }
-
-               /* process expect headers */
-               foreach_header(i, req->headers)
-               {
-                       if (strcasecmp(req->headers[i], "Expect"))
-                               continue;
-
-                       if (strcasecmp(req->headers[i+1], "100-continue"))
-                       {
-                               D("SRV: Client(%d) unknown expect header (%s)\n",
-                                 cl->fd.fd, req->headers[i+1]);
-
-                               uh_http_response(cl, 417, "Precondition Failed");
-                               uh_client_shutdown(cl);
-                               return;
-                       }
-                       else
-                       {
-                               D("SRV: Client(%d) sending HTTP/1.1 100 Continue\n", cl->fd.fd);
-
-                               uh_http_sendf(cl, NULL, "HTTP/1.1 100 Continue\r\n\r\n");
-                               cl->httpbuf.len = 0; /* client will re-send the body */
-                               break;
-                       }
-               }
-
-               /* RFC1918 filtering */
-               if (conf->rfc1918_filter &&
-                       sa_rfc1918(&cl->peeraddr) && !sa_rfc1918(&cl->servaddr))
-               {
-                       uh_http_sendhf(cl, 403, "Forbidden",
-                                                  "Rejected request from RFC1918 IP "
-                                                  "to public server address");
-
-                       uh_client_shutdown(cl);
-                       return;
-               }
-
-               /* dispatch request */
-               if (!uh_dispatch_request(cl, req))
-               {
-                       D("SRV: Client(%d) failed to dispach request\n", cl->fd.fd);
-                       uh_client_shutdown(cl);
-                       return;
-               }
-
-               /* request handler spawned a pipe, register handler */
-               if (cl->rpipe.fd > -1)
-               {
-                       D("SRV: Client(%d) pipe(%d) spawned\n", cl->fd.fd, cl->rpipe.fd);
-
-                       uh_ufd_add(&cl->rpipe, uh_rpipe_cb, ULOOP_READ);
-               }
-
-               /* request handler spawned a child, register handler */
-               if (cl->proc.pid)
-               {
-                       D("SRV: Client(%d) child(%d) spawned\n", cl->fd.fd, cl->proc.pid);
-
-                       cl->proc.cb = uh_child_cb;
-                       uloop_process_add(&cl->proc);
-
-                       cl->timeout.cb = uh_timeout_cb;
-                       uloop_timeout_set(&cl->timeout, conf->script_timeout * 1000);
-               }
-
-               /* header processing complete */
-               D("SRV: Client(%d) dispatched\n", cl->fd.fd);
-               cl->dispatched = true;
-       }
-
-       if (!cl->cb(cl))
-       {
-               D("SRV: Client(%d) response callback signalized EOF\n", cl->fd.fd);
-               uh_client_shutdown(cl);
-               return;
-       }
-}
-
-#ifdef HAVE_TLS
-static inline int uh_inittls(struct config *conf)
-{
-       /* library handle */
-       void *lib;
-
-       /* already loaded */
-       if (conf->tls != NULL)
-               return 0;
-
-       /* load TLS plugin */
-       if (!(lib = dlopen("uhttpd_tls.so", RTLD_LAZY | RTLD_GLOBAL)))
-       {
-               fprintf(stderr,
-                               "Notice: Unable to load TLS plugin - disabling SSL support! "
-                               "(Reason: %s)\n", dlerror()
-               );
-
-               return 1;
-       }
-       else
-       {
-               /* resolve functions */
-               if (!(conf->tls_init   = dlsym(lib, "uh_tls_ctx_init"))      ||
-                   !(conf->tls_cert   = dlsym(lib, "uh_tls_ctx_cert"))      ||
-                   !(conf->tls_key    = dlsym(lib, "uh_tls_ctx_key"))       ||
-                   !(conf->tls_free   = dlsym(lib, "uh_tls_ctx_free"))      ||
-                   !(conf->tls_accept = dlsym(lib, "uh_tls_client_accept")) ||
-                   !(conf->tls_close  = dlsym(lib, "uh_tls_client_close"))  ||
-                   !(conf->tls_recv   = dlsym(lib, "uh_tls_client_recv"))   ||
-                   !(conf->tls_send   = dlsym(lib, "uh_tls_client_send")))
-               {
-                       fprintf(stderr,
-                                       "Error: Failed to lookup required symbols "
-                                       "in TLS plugin: %s\n", dlerror()
-                       );
-                       exit(1);
-               }
-
-               /* init SSL context */
-               if (!(conf->tls = conf->tls_init()))
-               {
-                       fprintf(stderr, "Error: Failed to initalize SSL context\n");
-                       exit(1);
-               }
-       }
-
-       return 0;
-}
-#endif
-
-int main (int argc, char **argv)
-{
-       /* working structs */
-       struct addrinfo hints;
-       struct sigaction sa;
-       struct config conf;
-
-       /* maximum file descriptor number */
-       int cur_fd = 0;
-
-#ifdef HAVE_TLS
-       int tls = 0;
-       int keys = 0;
-#endif
-
-       int bound = 0;
-       int nofork = 0;
-
-       /* args */
-       int opt;
-       char addr[128];
-       char *port = NULL;
-
-#if defined(HAVE_LUA) || defined(HAVE_TLS) || defined(HAVE_UBUS)
-       /* library handle */
-       void *lib;
-#endif
-
-       /* handle SIGPIPE, SIGINT, SIGTERM */
-       sa.sa_flags = 0;
-       sigemptyset(&sa.sa_mask);
-
-       sa.sa_handler = SIG_IGN;
-       sigaction(SIGPIPE, &sa, NULL);
-
-       sa.sa_handler = uh_sigterm;
-       sigaction(SIGINT,  &sa, NULL);
-       sigaction(SIGTERM, &sa, NULL);
-
-       /* prepare addrinfo hints */
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_family   = AF_UNSPEC;
-       hints.ai_socktype = SOCK_STREAM;
-       hints.ai_flags    = AI_PASSIVE;
-
-       /* parse args */
-       memset(&conf, 0, sizeof(conf));
-
-       uloop_init();
-
-       while ((opt = getopt(argc, argv,
-                                                "fSDRC:K:E:I:p:s:h:c:l:L:d:r:m:n:x:i:t:T:A:u:U:")) > 0)
-       {
-               switch(opt)
-               {
-                       /* [addr:]port */
-                       case 'p':
-                       case 's':
-                               memset(addr, 0, sizeof(addr));
-
-                               if ((port = strrchr(optarg, ':')) != NULL)
-                               {
-                                       if ((optarg[0] == '[') && (port > optarg) && (port[-1] == ']'))
-                                               memcpy(addr, optarg + 1,
-                                                       min(sizeof(addr), (int)(port - optarg) - 2));
-                                       else
-                                               memcpy(addr, optarg,
-                                                       min(sizeof(addr), (int)(port - optarg)));
-
-                                       port++;
-                               }
-                               else
-                               {
-                                       port = optarg;
-                               }
-
-#ifdef HAVE_TLS
-                               if (opt == 's')
-                               {
-                                       if (uh_inittls(&conf))
-                                       {
-                                               fprintf(stderr,
-                                                       "Notice: TLS support is disabled, "
-                                                       "ignoring '-s %s'\n", optarg
-                                               );
-                                               continue;
-                                       }
-
-                                       tls = 1;
-                               }
-#endif
-
-                               /* bind sockets */
-                               bound += uh_socket_bind(addr[0] ? addr : NULL, port, &hints,
-                                                       (opt == 's'), &conf);
-                               break;
-
-#ifdef HAVE_TLS
-                       /* certificate */
-                       case 'C':
-                               if (!uh_inittls(&conf))
-                               {
-                                       if (conf.tls_cert(conf.tls, optarg) < 1)
-                                       {
-                                               fprintf(stderr,
-                                                               "Error: Invalid certificate file given\n");
-                                               exit(1);
-                                       }
-
-                                       keys++;
-                               }
-
-                               break;
-
-                       /* key */
-                       case 'K':
-                               if (!uh_inittls(&conf))
-                               {
-                                       if (conf.tls_key(conf.tls, optarg) < 1)
-                                       {
-                                               fprintf(stderr,
-                                                               "Error: Invalid private key file given\n");
-                                               exit(1);
-                                       }
-
-                                       keys++;
-                               }
-
-                               break;
-#else
-                       case 'C':
-                       case 'K':
-                               fprintf(stderr,
-                                       "Notice: TLS support not compiled, ignoring -%c\n",
-                                       opt);
-                               break;
-#endif
-
-                       /* docroot */
-                       case 'h':
-                               if (! realpath(optarg, conf.docroot))
-                               {
-                                       fprintf(stderr, "Error: Invalid directory %s: %s\n",
-                                                       optarg, strerror(errno));
-                                       exit(1);
-                               }
-                               break;
-
-                       /* error handler */
-                       case 'E':
-                               if ((strlen(optarg) == 0) || (optarg[0] != '/'))
-                               {
-                                       fprintf(stderr, "Error: Invalid error handler: %s\n",
-                                                       optarg);
-                                       exit(1);
-                               }
-                               conf.error_handler = optarg;
-                               break;
-
-                       /* index file */
-                       case 'I':
-                               if ((strlen(optarg) == 0) || (optarg[0] == '/'))
-                               {
-                                       fprintf(stderr, "Error: Invalid index page: %s\n",
-                                                       optarg);
-                                       exit(1);
-                               }
-                               conf.index_file = optarg;
-                               break;
-
-                       /* don't follow symlinks */
-                       case 'S':
-                               conf.no_symlinks = 1;
-                               break;
-
-                       /* don't list directories */
-                       case 'D':
-                               conf.no_dirlists = 1;
-                               break;
-
-                       case 'R':
-                               conf.rfc1918_filter = 1;
-                               break;
-
-                       case 'n':
-                               conf.max_requests = atoi(optarg);
-                               break;
-
-#ifdef HAVE_CGI
-                       /* cgi prefix */
-                       case 'x':
-                               conf.cgi_prefix = optarg;
-                               break;
-
-                       /* interpreter */
-                       case 'i':
-                               if ((optarg[0] == '.') && (port = strchr(optarg, '=')))
-                               {
-                                       *port++ = 0;
-                                       uh_interpreter_add(optarg, port);
-                               }
-                               else
-                               {
-                                       fprintf(stderr, "Error: Invalid interpreter: %s\n",
-                                                       optarg);
-                                       exit(1);
-                               }
-                               break;
-#else
-                       case 'x':
-                       case 'i':
-                               fprintf(stderr,
-                                       "Notice: CGI support not compiled, ignoring -%c\n",
-                                       opt);
-                               break;
-#endif
-
-#ifdef HAVE_LUA
-                       /* lua prefix */
-                       case 'l':
-                               conf.lua_prefix = optarg;
-                               break;
-
-                       /* lua handler */
-                       case 'L':
-                               conf.lua_handler = optarg;
-                               break;
-#else
-                       case 'l':
-                       case 'L':
-                               fprintf(stderr,
-                                       "Notice: Lua support not compiled, ignoring -%c\n",
-                                       opt);
-                               break;
-#endif
-
-#ifdef HAVE_UBUS
-                       /* ubus prefix */
-                       case 'u':
-                               conf.ubus_prefix = optarg;
-                               break;
-
-                       /* ubus socket */
-                       case 'U':
-                               conf.ubus_socket = optarg;
-                               break;
-#else
-                       case 'u':
-                       case 'U':
-                               fprintf(stderr,
-                                       "Notice: UBUS support not compiled, ignoring -%c\n",
-                                       opt);
-                               break;
-#endif
-
-#if defined(HAVE_CGI) || defined(HAVE_LUA)
-                       /* script timeout */
-                       case 't':
-                               conf.script_timeout = atoi(optarg);
-                               break;
-#endif
-
-                       /* network timeout */
-                       case 'T':
-                               conf.network_timeout = atoi(optarg);
-                               break;
-
-                       /* tcp keep-alive */
-                       case 'A':
-                               conf.tcp_keepalive = atoi(optarg);
-                               break;
-
-                       /* no fork */
-                       case 'f':
-                               nofork = 1;
-                               break;
-
-                       /* urldecode */
-                       case 'd':
-                               if ((port = malloc(strlen(optarg)+1)) != NULL)
-                               {
-                                       /* "decode" plus to space to retain compat */
-                                       for (opt = 0; optarg[opt]; opt++)
-                                               if (optarg[opt] == '+')
-                                                       optarg[opt] = ' ';
-                                       /* opt now contains strlen(optarg) -- no need to re-scan */
-                                       memset(port, 0, opt+1);
-                                       if (uh_urldecode(port, opt, optarg, opt) < 0)
-                                           fprintf(stderr, "uhttpd: invalid encoding\n");
-
-                                       printf("%s", port);
-                                       free(port);
-                                       exit(0);
-                               }
-                               break;
-
-                       /* basic auth realm */
-                       case 'r':
-                               conf.realm = optarg;
-                               break;
-
-                       /* md5 crypt */
-                       case 'm':
-                               printf("%s\n", crypt(optarg, "$1$"));
-                               exit(0);
-                               break;
-
-                       /* config file */
-                       case 'c':
-                               conf.file = optarg;
-                               break;
-
-                       default:
-                               fprintf(stderr,
-                                       "Usage: %s -p [addr:]port [-h docroot]\n"
-                                       "       -f              Do not fork to background\n"
-                                       "       -c file         Configuration file, default is '/etc/httpd.conf'\n"
-                                       "       -p [addr:]port  Bind to specified address and port, multiple allowed\n"
-#ifdef HAVE_TLS
-                                       "       -s [addr:]port  Like -p but provide HTTPS on this port\n"
-                                       "       -C file         ASN.1 server certificate file\n"
-                                       "       -K file         ASN.1 server private key file\n"
-#endif
-                                       "       -h directory    Specify the document root, default is '.'\n"
-                                       "       -E string       Use given virtual URL as 404 error handler\n"
-                                       "       -I string       Use given filename as index page for directories\n"
-                                       "       -S              Do not follow symbolic links outside of the docroot\n"
-                                       "       -D              Do not allow directory listings, send 403 instead\n"
-                                       "       -R              Enable RFC1918 filter\n"
-                                       "       -n count        Maximum allowed number of concurrent requests\n"
-#ifdef HAVE_LUA
-                                       "       -l string       URL prefix for Lua handler, default is '/lua'\n"
-                                       "       -L file         Lua handler script, omit to disable Lua\n"
-#endif
-#ifdef HAVE_UBUS
-                                       "       -u string       URL prefix for HTTP/JSON handler\n"
-                                       "       -U file         Override ubus socket path\n"
-#endif
-#ifdef HAVE_CGI
-                                       "       -x string       URL prefix for CGI handler, default is '/cgi-bin'\n"
-                                       "       -i .ext=path    Use interpreter at path for files with the given extension\n"
-#endif
-#if defined(HAVE_CGI) || defined(HAVE_LUA) || defined(HAVE_UBUS)
-                                       "       -t seconds      CGI, Lua and UBUS script timeout in seconds, default is 60\n"
-#endif
-                                       "       -T seconds      Network timeout in seconds, default is 30\n"
-                                       "       -d string       URL decode given string\n"
-                                       "       -r string       Specify basic auth realm\n"
-                                       "       -m string       MD5 crypt given string\n"
-                                       "\n", argv[0]
-                               );
-
-                               exit(1);
-               }
-       }
-
-#ifdef HAVE_TLS
-       if ((tls == 1) && (keys < 2))
-       {
-               fprintf(stderr, "Error: Missing private key or certificate file\n");
-               exit(1);
-       }
-#endif
-
-       if (bound < 1)
-       {
-               fprintf(stderr, "Error: No sockets bound, unable to continue\n");
-               exit(1);
-       }
-
-       /* default docroot */
-       if (!conf.docroot[0] && !realpath(".", conf.docroot))
-       {
-               fprintf(stderr, "Error: Can not determine default document root: %s\n",
-                       strerror(errno));
-               exit(1);
-       }
-
-       /* default realm */
-       if (!conf.realm)
-               conf.realm = "Protected Area";
-
-       /* config file */
-       uh_config_parse(&conf);
-
-       /* default max requests */
-       if (conf.max_requests <= 0)
-               conf.max_requests = 3;
-
-       /* default network timeout */
-       if (conf.network_timeout <= 0)
-               conf.network_timeout = 30;
-
-#if defined(HAVE_CGI) || defined(HAVE_LUA) || defined(HAVE_UBUS)
-       /* default script timeout */
-       if (conf.script_timeout <= 0)
-               conf.script_timeout = 60;
-#endif
-
-#ifdef HAVE_CGI
-       /* default cgi prefix */
-       if (!conf.cgi_prefix)
-               conf.cgi_prefix = "/cgi-bin";
-#endif
-
-#ifdef HAVE_LUA
-       /* load Lua plugin */
-       if (!(lib = dlopen("uhttpd_lua.so", RTLD_LAZY | RTLD_GLOBAL)))
-       {
-               fprintf(stderr,
-                               "Notice: Unable to load Lua plugin - disabling Lua support! "
-                               "(Reason: %s)\n", dlerror());
-       }
-       else
-       {
-               /* resolve functions */
-               if (!(conf.lua_init    = dlsym(lib, "uh_lua_init"))    ||
-                   !(conf.lua_close   = dlsym(lib, "uh_lua_close"))   ||
-                   !(conf.lua_request = dlsym(lib, "uh_lua_request")))
-               {
-                       fprintf(stderr,
-                                       "Error: Failed to lookup required symbols "
-                                       "in Lua plugin: %s\n", dlerror()
-                       );
-                       exit(1);
-               }
-
-               /* init Lua runtime if handler is specified */
-               if (conf.lua_handler)
-               {
-                       /* default lua prefix */
-                       if (!conf.lua_prefix)
-                               conf.lua_prefix = "/lua";
-
-                       conf.lua_state = conf.lua_init(&conf);
-               }
-       }
-#endif
-
-#ifdef HAVE_UBUS
-       /* load ubus plugin */
-       if (!(lib = dlopen("uhttpd_ubus.so", RTLD_LAZY | RTLD_GLOBAL)))
-       {
-               fprintf(stderr,
-                               "Notice: Unable to load ubus plugin - disabling ubus support! "
-                               "(Reason: %s)\n", dlerror());
-       }
-       else if (conf.ubus_prefix)
-       {
-               /* resolve functions */
-               if (!(conf.ubus_init    = dlsym(lib, "uh_ubus_init"))    ||
-                   !(conf.ubus_close   = dlsym(lib, "uh_ubus_close"))   ||
-                   !(conf.ubus_request = dlsym(lib, "uh_ubus_request")))
-               {
-                       fprintf(stderr,
-                                       "Error: Failed to lookup required symbols "
-                                       "in ubus plugin: %s\n", dlerror()
-                       );
-                       exit(1);
-               }
-
-               /* initialize ubus */
-               conf.ubus_state = conf.ubus_init(&conf);
-       }
-#endif
-
-       /* fork (if not disabled) */
-       if (!nofork)
-       {
-               switch (fork())
-               {
-                       case -1:
-                               perror("fork()");
-                               exit(1);
-
-                       case 0:
-                               /* daemon setup */
-                               if (chdir("/"))
-                                       perror("chdir()");
-
-                               if ((cur_fd = open("/dev/null", O_WRONLY)) > -1)
-                                       dup2(cur_fd, 0);
-
-                               if ((cur_fd = open("/dev/null", O_RDONLY)) > -1)
-                                       dup2(cur_fd, 1);
-
-                               if ((cur_fd = open("/dev/null", O_RDONLY)) > -1)
-                                       dup2(cur_fd, 2);
-
-                               break;
-
-                       default:
-                               exit(0);
-               }
-       }
-
-       /* server main loop */
-       uloop_run();
-
-#ifdef HAVE_LUA
-       /* destroy the Lua state */
-       if (conf.lua_state != NULL)
-               conf.lua_close(conf.lua_state);
-#endif
-
-#ifdef HAVE_UBUS
-       /* destroy the ubus state */
-       if (conf.ubus_state != NULL)
-               conf.ubus_close(conf.ubus_state);
-#endif
-
-       return 0;
-}
diff --git a/package/network/services/uhttpd/src/uhttpd.h b/package/network/services/uhttpd/src/uhttpd.h
deleted file mode 100644 (file)
index f6982db..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * uhttpd - Tiny single-threaded httpd - Main header
- *
- *   Copyright (C) 2010 Jo-Philipp Wich <xm@subsignal.org>
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#ifndef _UHTTPD_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/wait.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <linux/limits.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <errno.h>
-#include <dlfcn.h>
-
-#include <libubox/list.h>
-#include <libubox/uloop.h>
-
-
-#ifdef HAVE_LUA
-#include <lua.h>
-#endif
-
-#ifdef HAVE_TLS
-#include <openssl/ssl.h>
-#endif
-
-/* uClibc... */
-#ifndef SOL_TCP
-#define SOL_TCP        6
-#endif
-
-#ifdef DEBUG
-#define D(...) fprintf(stderr, __VA_ARGS__)
-#else
-#define D(...)
-#endif
-
-
-#define UH_LIMIT_MSGHEAD       4096
-#define UH_LIMIT_HEADERS       64
-#define UH_LIMIT_CLIENTS       64
-
-
-struct listener;
-struct client;
-struct interpreter;
-struct http_request;
-struct uh_ubus_state;
-
-struct config {
-       char docroot[PATH_MAX];
-       char *realm;
-       char *file;
-       char *index_file;
-       char *error_handler;
-       int no_symlinks;
-       int no_dirlists;
-       int network_timeout;
-       int rfc1918_filter;
-       int tcp_keepalive;
-       int max_requests;
-#ifdef HAVE_CGI
-       char *cgi_prefix;
-#endif
-#ifdef HAVE_LUA
-       char *lua_prefix;
-       char *lua_handler;
-       lua_State *lua_state;
-       lua_State * (*lua_init) (const struct config *conf);
-       void (*lua_close) (lua_State *L);
-       bool (*lua_request) (struct client *cl, lua_State *L);
-#endif
-#ifdef HAVE_UBUS
-       char *ubus_prefix;
-       char *ubus_socket;
-       void *ubus_state;
-       struct uh_ubus_state * (*ubus_init) (const struct config *conf);
-       void (*ubus_close) (struct uh_ubus_state *state);
-       bool (*ubus_request) (struct client *cl, struct uh_ubus_state *state);
-#endif
-#if defined(HAVE_CGI) || defined(HAVE_LUA) || defined(HAVE_UBUS)
-       int script_timeout;
-#endif
-#ifdef HAVE_TLS
-       char *cert;
-       char *key;
-       SSL_CTX *tls;
-       SSL_CTX * (*tls_init) (void);
-       int (*tls_cert) (SSL_CTX *c, const char *file);
-       int (*tls_key) (SSL_CTX *c, const char *file);
-       void (*tls_free) (struct listener *l);
-       int (*tls_accept) (struct client *c);
-       void (*tls_close) (struct client *c);
-       int (*tls_recv) (struct client *c, char *buf, int len);
-       int (*tls_send) (struct client *c, const char *buf, int len);
-#endif
-};
-
-enum http_method {
-       UH_HTTP_MSG_GET,
-       UH_HTTP_MSG_POST,
-       UH_HTTP_MSG_HEAD,
-};
-
-extern const char *http_methods[];
-
-enum http_version {
-       UH_HTTP_VER_0_9,
-       UH_HTTP_VER_1_0,
-       UH_HTTP_VER_1_1,
-};
-
-extern const char *http_versions[];
-
-struct http_request {
-       enum http_method method;
-       enum http_version version;
-       int redirect_status;
-       char *url;
-       char *headers[UH_LIMIT_HEADERS];
-       struct auth_realm *realm;
-};
-
-struct http_response {
-       int statuscode;
-       char *statusmsg;
-       char *headers[UH_LIMIT_HEADERS];
-};
-
-struct listener {
-       struct uloop_fd fd;
-       int socket;
-       int n_clients;
-       struct sockaddr_in6 addr;
-       struct config *conf;
-#ifdef HAVE_TLS
-       SSL_CTX *tls;
-#endif
-       struct listener *next;
-};
-
-struct client {
-#ifdef HAVE_TLS
-       SSL *tls;
-#endif
-       struct uloop_fd fd;
-       struct uloop_fd rpipe;
-       struct uloop_fd wpipe;
-       struct uloop_process proc;
-       struct uloop_timeout timeout;
-       bool (*cb)(struct client *);
-       void *priv;
-       bool dispatched;
-       struct {
-               char buf[UH_LIMIT_MSGHEAD];
-               char *ptr;
-               int len;
-       } httpbuf;
-       struct listener *server;
-       struct http_request request;
-       struct http_response response;
-       struct sockaddr_in6 servaddr;
-       struct sockaddr_in6 peeraddr;
-       struct client *next;
-};
-
-struct client_light {
-#ifdef HAVE_TLS
-       SSL *tls;
-#endif
-       struct uloop_fd fd;
-};
-
-struct auth_realm {
-       char path[PATH_MAX];
-       char user[32];
-       char pass[128];
-       struct auth_realm *next;
-};
-
-#ifdef HAVE_CGI
-struct interpreter {
-       char path[PATH_MAX];
-       char extn[32];
-       struct interpreter *next;
-};
-#endif
-
-#endif