summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorRalf Corsepius <ralf.corsepius@rtems.org>2010-06-09 08:06:08 +0000
committerRalf Corsepius <ralf.corsepius@rtems.org>2010-06-09 08:06:08 +0000
commitdc35201765459ae69c0becccdc4cace5ce246da2 (patch)
tree5b01dff6a33fd36a3b2215611b8f61faffadeeec /cpukit
parentRemove. (diff)
downloadrtems-dc35201765459ae69c0becccdc4cace5ce246da2.tar.bz2
Remove.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/aclocal/enable-shttpd.m412
-rw-r--r--cpukit/shttpd/.cvsignore2
-rw-r--r--cpukit/shttpd/Makefile.am70
-rw-r--r--cpukit/shttpd/Makefile.shttpd50
-rw-r--r--cpukit/shttpd/auth.c397
-rw-r--r--cpukit/shttpd/cgi.c292
-rw-r--r--cpukit/shttpd/compat_rtems.c200
-rw-r--r--cpukit/shttpd/compat_rtems.h69
-rw-r--r--cpukit/shttpd/compat_unix.c123
-rw-r--r--cpukit/shttpd/compat_unix.h33
-rw-r--r--cpukit/shttpd/compat_win32.c923
-rw-r--r--cpukit/shttpd/compat_win32.h93
-rw-r--r--cpukit/shttpd/compat_wince.c1593
-rw-r--r--cpukit/shttpd/compat_wince.h145
-rw-r--r--cpukit/shttpd/config.c334
-rw-r--r--cpukit/shttpd/defs.h492
-rw-r--r--cpukit/shttpd/io.h97
-rw-r--r--cpukit/shttpd/io_cgi.c124
-rw-r--r--cpukit/shttpd/io_dir.c143
-rw-r--r--cpukit/shttpd/io_emb.c305
-rw-r--r--cpukit/shttpd/io_file.c156
-rw-r--r--cpukit/shttpd/io_socket.c41
-rw-r--r--cpukit/shttpd/io_ssl.c85
-rw-r--r--cpukit/shttpd/llist.h59
-rw-r--r--cpukit/shttpd/log.c141
-rw-r--r--cpukit/shttpd/md5.c249
-rw-r--r--cpukit/shttpd/md5.h24
-rw-r--r--cpukit/shttpd/mime_type.c108
-rw-r--r--cpukit/shttpd/preinstall.am39
-rw-r--r--cpukit/shttpd/shttpd.1135
-rw-r--r--cpukit/shttpd/shttpd.c1135
-rw-r--r--cpukit/shttpd/shttpd.h129
-rw-r--r--cpukit/shttpd/ssl.h52
-rw-r--r--cpukit/shttpd/standalone.c92
-rw-r--r--cpukit/shttpd/std_includes.h41
-rw-r--r--cpukit/shttpd/string.c85
36 files changed, 0 insertions, 8068 deletions
diff --git a/cpukit/aclocal/enable-shttpd.m4 b/cpukit/aclocal/enable-shttpd.m4
deleted file mode 100644
index 5398c5308a..0000000000
--- a/cpukit/aclocal/enable-shttpd.m4
+++ /dev/null
@@ -1,12 +0,0 @@
-dnl $Id$
-
-AC_DEFUN([RTEMS_ENABLE_SHTTPD],
-[
-AC_ARG_ENABLE([shttpd],
-AS_HELP_STRING([--enable-shttpd],[enable (small httpd) shttpd (DEPRECATED)]),
-[case "${enableval}" in
- yes) enable_shttpd=yes ;;
- no) enable_shttpd=no ;;
- *) AC_MSG_ERROR(bad value ${enableval} for enable-shttpd option) ;;
-esac],[enable_shttpd=no])
-])
diff --git a/cpukit/shttpd/.cvsignore b/cpukit/shttpd/.cvsignore
deleted file mode 100644
index 3dda72986f..0000000000
--- a/cpukit/shttpd/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Makefile.in
-Makefile
diff --git a/cpukit/shttpd/Makefile.am b/cpukit/shttpd/Makefile.am
deleted file mode 100644
index 8496e7b132..0000000000
--- a/cpukit/shttpd/Makefile.am
+++ /dev/null
@@ -1,70 +0,0 @@
-# DEPRECATED, don't use.
-
-include $(top_srcdir)/automake/compile.am
-
-if LIBSHTTPD
-include_shttpddir = $(includedir)/shttpd
-
-project_lib_LIBRARIES = libshttpd.a
-libshttpd_a_CPPFLAGS = $(AM_CPPFLAGS) -DHAVE_MD5
-
-# HACK ALERT:
-# prefix all non-public symbols with _shttp_
-# FIXME: There must be something better than this
-libshttpd_a_CPPFLAGS += -Dcheck_authorization=_shttpd_check_authorization
-libshttpd_a_CPPFLAGS += -Ddecode_url_encoded_string=_shttpd_decode_url_encoded_string
-libshttpd_a_CPPFLAGS += -Dedit_passwords=_shttpd_edit_passwords
-libshttpd_a_CPPFLAGS += -Delog=_shttpd_elog
-libshttpd_a_CPPFLAGS += -Dget_dir=_shttpd_get_dir
-libshttpd_a_CPPFLAGS += -Dget_file=_shttpd_get_file
-libshttpd_a_CPPFLAGS += -Dget_headers_len=_shttpd_get_headers_len
-libshttpd_a_CPPFLAGS += -Dget_mime_type=_shttpd_get_mime_type
-libshttpd_a_CPPFLAGS += -Dinit_from_argc_argv=_shttpd_init_from_argc_argv
-libshttpd_a_CPPFLAGS += -Dis_authorized_for_put=_shttpd_is_authorized_for_put
-libshttpd_a_CPPFLAGS += -Dis_registered_uri=_shttpd_is_registered_uri
-libshttpd_a_CPPFLAGS += -Dlog_access=_shttpd_log_access
-libshttpd_a_CPPFLAGS += -Dparse_headers=_shttpd_parse_headers
-libshttpd_a_CPPFLAGS += -Dput_dir=_shttpd_put_dir
-libshttpd_a_CPPFLAGS += -Dsend_authorization_request=_shttpd_send_authorization_request
-libshttpd_a_CPPFLAGS += -Dsend_server_error=_shttpd_send_server_error
-libshttpd_a_CPPFLAGS += -Dset_close_on_exec=_shttpd_set_close_on_exec
-libshttpd_a_CPPFLAGS += -Dset_mime_types=_shttpd_set_mime_types
-libshttpd_a_CPPFLAGS += -Dset_non_blocking_mode=_shttpd_set_non_blocking_mode
-libshttpd_a_CPPFLAGS += -Dsetup_embedded_stream=_shttpd_setup_embedded_stream
-libshttpd_a_CPPFLAGS += -Dstop_stream=_shttpd_stop_stream
-libshttpd_a_CPPFLAGS += -Dusage=_shttpd_usage
-
-libshttpd_a_CPPFLAGS += -Dknown_http_methods=_shttpd_known_http_methods
-libshttpd_a_CPPFLAGS += -Doptions=_shttpd_options
-libshttpd_a_CPPFLAGS += -Dio_file=_shttpd_io_file
-libshttpd_a_CPPFLAGS += -Dio_socket=_shttpd_io_socket
-libshttpd_a_CPPFLAGS += -Dio_embedded=_shttpd_io_embedded
-libshttpd_a_CPPFLAGS += -Dio_dir=_shttpd_io_dir
-libshttpd_a_CPPFLAGS += -Dio_cgi=_shttpd_io_cgi
-
-libshttpd_a_CPPFLAGS += -Dcurrent_time=_shttpd_current_time
-libshttpd_a_CPPFLAGS += -Dtz_offset=_shttpd_tz_offset
-
-SRCS= string.c shttpd.c log.c auth.c md5.c \
- cgi.c mime_type.c config.c \
- io_file.c io_socket.c io_ssl.c io_emb.c io_dir.c io_cgi.c
-HDRS= defs.h llist.h shttpd.h std_includes.h io.h md5.h ssl.h \
- compat_unix.h compat_win32.h compat_rtems.h
-
-libshttpd_a_SOURCES = $(SRCS) $(HDRS)
-libshttpd_a_SOURCES += compat_rtems.c
-include_shttpd_HEADERS = shttpd.h
-
-# Possible flags: (in brackets are rough numbers for 'gcc -O2' on i386)
-# -DHAVE_MD5 - use system md5 library (-2kb)
-# -DNDEBUG - strip off all debug code (-5kb)
-# -D_DEBUG - build debug version (very noisy) (+6kb)
-# -DNO_CGI - disable CGI support (-5kb)
-# -DNO_SSL - disable SSL functionality (-2kb)
-# -DNO_AUTH - disable authorization support (-4kb)
-# -DNO_GUI - Win32 only. Build console version, no GUI
-# -DCONFIG=\"file\" - use `file' as the default config file
-endif
-
-include $(srcdir)/preinstall.am
-include $(top_srcdir)/automake/local.am
diff --git a/cpukit/shttpd/Makefile.shttpd b/cpukit/shttpd/Makefile.shttpd
deleted file mode 100644
index 31e8da228e..0000000000
--- a/cpukit/shttpd/Makefile.shttpd
+++ /dev/null
@@ -1,50 +0,0 @@
-SRCS= string.c shttpd.c log.c auth.c md5.c \
- cgi.c mime_type.c config.c \
- io_file.c io_socket.c io_ssl.c io_emb.c io_dir.c io_cgi.c
-HDRS= defs.h llist.h shttpd.h std_includes.h io.h md5.h ssl.h \
- compat_unix.h compat_win32.h compat_rtems.h
-PROG= shttpd
-
-# Possible flags: (in brackets are rough numbers for 'gcc -O2' on i386)
-# -DHAVE_MD5 - use system md5 library (-2kb)
-# -DNDEBUG - strip off all debug code (-5kb)
-# -D_DEBUG - build debug version (very noisy) (+6kb)
-# -DNO_CGI - disable CGI support (-5kb)
-# -DNO_SSL - disable SSL functionality (-2kb)
-# -DNO_AUTH - disable authorization support (-4kb)
-# -DNO_GUI - Win32 only. Build console version, no GUI
-# -DCONFIG=\"file\" - use `file' as the default config file
-
-CL_FLAGS= /O1 /MD /TC /nologo /DNDEBUG
-
-all:
- @echo "make (unix|msvc|mingw|rtems)"
-
-unix:
- $(CC) -c $(CFLAGS) -DEMBEDDED $(SRCS) compat_unix.c
- $(AR) -r lib$(PROG).a *.o && ranlib lib$(PROG).a
- $(CC) $(CFLAGS) $(SRCS) compat_unix.c standalone.c -o $(PROG) $(LIBS)
-
-rtems:
- $(CC) -c $(CFLAGS) -DEMBEDDED $(SRCS) compat_rtems.c
- $(AR) -r lib$(PROG).a *.o && ranlib lib$(PROG).a
-
-msvc:
- cl $(SRCS) /c $(CL_FLAGS) /DEMBEDDED
- lib *.obj /out:shttpd.lib
- rc resources.rc
- cl $(SRCS) compat_win32.c standalone.c $(CL_FLAGS) \
- /link resources.res /out:$(PROG).exe /machine:ix86
-
-mingw:
- $(CC) -c $(CFLAGS) -DEMBEDDED $(SRCS) compat_win32.c
- $(AR) -r lib$(PROG).a *.o && ranlib lib$(PROG).a
- windres resources.rc resources.o
- $(CC) $(CFLAGS) $(SRCS) compat_win32.c standalone.c resources.o -o $(PROG) $(LIBS) -lws2_32 -lcomdlg32 -lcomctl32
-
-man:
- cat shttpd.1 | tbl | groff -man -Tascii | col -b > shttpd.1.txt
- cat shttpd.1 | tbl | groff -man -Tascii | less
-
-clean:
- rm -rf *.o *.core $(PROG) lib$(PROG).a
diff --git a/cpukit/shttpd/auth.c b/cpukit/shttpd/auth.c
deleted file mode 100644
index 745f8ed709..0000000000
--- a/cpukit/shttpd/auth.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-#include <unistd.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#if !defined(NO_AUTH)
-/*
- * Stringify binary data. Output buffer must be twice as big as input,
- * because each byte takes 2 bytes in string representation
- */
-static void
-bin2str(char *to, const unsigned char *p, size_t len)
-{
- const char *hex = "0123456789abcdef";
-
- for (;len--; p++) {
- *to++ = hex[p[0] >> 4];
- *to++ = hex[p[0] & 0x0f];
- }
-}
-
-/*
- * Return stringified MD5 hash for list of vectors.
- * buf must point to at least 32-bytes long buffer
- */
-static void
-md5(char *buf, ...)
-{
- unsigned char hash[16];
- const struct vec *v;
- va_list ap;
- MD5_CTX ctx;
- int i;
-
- MD5Init(&ctx);
-
- va_start(ap, buf);
- for (i = 0; (v = va_arg(ap, const struct vec *)) != NULL; i++) {
- assert(v->len >= 0);
- if (v->len == 0)
- continue;
- if (i > 0)
- MD5Update(&ctx, (unsigned char *) ":", 1);
- MD5Update(&ctx,(unsigned char *)v->ptr,(unsigned int)v->len);
- }
- va_end(ap);
-
- MD5Final(hash, &ctx);
- bin2str(buf, hash, sizeof(hash));
-}
-
-/*
- * Compare to vectors. Return 1 if they are equal
- */
-static int
-vcmp(const struct vec *v1, const struct vec *v2)
-{
- return (v1->len == v2->len && !memcmp(v1->ptr, v2->ptr, v1->len));
-}
-
-struct digest {
- struct vec user;
- struct vec uri;
- struct vec nonce;
- struct vec cnonce;
- struct vec resp;
- struct vec qop;
- struct vec nc;
-};
-
-static const struct auth_keyword {
- size_t offset;
- struct vec vec;
-} known_auth_keywords[] = {
- {offsetof(struct digest, user), {"username=", 9}},
- {offsetof(struct digest, cnonce), {"cnonce=", 7}},
- {offsetof(struct digest, resp), {"response=", 9}},
- {offsetof(struct digest, uri), {"uri=", 4}},
- {offsetof(struct digest, qop), {"qop=", 4}},
- {offsetof(struct digest, nc), {"nc=", 3}},
- {offsetof(struct digest, nonce), {"nonce=", 6}},
- {0, {NULL, 0}}
-};
-
-static void
-parse_authorization_header(const struct vec *h, struct digest *dig)
-{
- const unsigned char *p, *e, *s;
- struct vec *v, vec;
- const struct auth_keyword *kw;
-
- (void) memset(dig, 0, sizeof(*dig));
- p = (unsigned char *) h->ptr + 7;
- e = (unsigned char *) h->ptr + h->len;
-
- while (p < e) {
-
- /* Skip spaces */
- while (p < e && (*p == ' ' || *p == ','))
- p++;
-
- /* Skip to "=" */
- for (s = p; s < e && *s != '='; )
- s++;
- s++;
-
- /* Is it known keyword ? */
- for (kw = known_auth_keywords; kw->vec.len > 0; kw++)
- if (kw->vec.len <= s - p &&
- !memcmp(p, kw->vec.ptr, kw->vec.len))
- break;
-
- if (kw->vec.len == 0)
- v = &vec; /* Dummy placeholder */
- else
- v = (struct vec *) ((char *) dig + kw->offset);
-
- if (*s == '"') {
- p = ++s;
- while (p < e && *p != '"')
- p++;
- } else {
- p = s;
- while (p < e && *p != ' ' && *p != ',')
- p++;
- }
-
- v->ptr = (char *) s;
- v->len = p - s;
-
- if (*p == '"')
- p++;
-
- DBG(("auth field [%.*s]", v->len, v->ptr));
- }
-}
-
-/*
- * Check the user's password, return 1 if OK
- */
-static int
-check_password(int method, const struct vec *ha1, const struct digest *digest)
-{
- char a2[32], resp[32];
- struct vec vec_a2;
-
- /* XXX Due to a bug in MSIE, we do not compare the URI */
- /* Also, we do not check for authentication timeout */
- if (/*strcmp(dig->uri, c->ouri) != 0 || */
- digest->resp.len != 32 /*||
- now - strtoul(dig->nonce, NULL, 10) > 3600 */)
- return (0);
-
- md5(a2, &known_http_methods[method], &digest->uri, NULL);
- vec_a2.ptr = a2;
- vec_a2.len = sizeof(a2);
- md5(resp, ha1, &digest->nonce, &digest->nc,
- &digest->cnonce, &digest->qop, &vec_a2, NULL);
-
- return (!memcmp(resp, digest->resp.ptr, 32));
-}
-
-static FILE *
-open_auth_file(struct shttpd_ctx *ctx, const char *path)
-{
- char name[FILENAME_MAX];
- const char *p, *e;
- FILE *fp = NULL;
- int fd;
-
- if (ctx->global_passwd_file) {
- /* Use global passwords file */
- my_snprintf(name, sizeof(name), "%s", ctx->global_passwd_file);
- } else {
- /* Try to find .htpasswd in requested directory */
- for (p = path, e = p + strlen(p) - 1; e > p; e--)
- if (IS_DIRSEP_CHAR(*e))
- break;
-
- assert(IS_DIRSEP_CHAR(*e));
- (void) my_snprintf(name, sizeof(name), "%.*s/%s",
- (int) (e - p), p, HTPASSWD);
- }
-
- if ((fd = my_open(name, O_RDONLY, 0)) == -1) {
- DBG(("open_auth_file: open(%s)", name));
- } else if ((fp = fdopen(fd, "r")) == NULL) {
- DBG(("open_auth_file: fdopen(%s)", name));
- (void) close(fd);
- }
-
- return (fp);
-}
-
-/*
- * Parse the line from htpasswd file. Line should be in form of
- * "user:domain:ha1". Fill in the vector values. Return 1 if successful.
- */
-static int
-parse_htpasswd_line(const char *s, struct vec *user,
- struct vec *domain, struct vec *ha1)
-{
- user->len = domain->len = ha1->len = 0;
-
- for (user->ptr = s; *s != '\0' && *s != ':'; s++, user->len++);
- if (*s++ != ':')
- return (0);
-
- for (domain->ptr = s; *s != '\0' && *s != ':'; s++, domain->len++);
- if (*s++ != ':')
- return (0);
-
- for (ha1->ptr = s; *s != '\0' && !isspace(* (unsigned char *) s);
- s++, ha1->len++);
-
- DBG(("parse_htpasswd_line: [%.*s] [%.*s] [%.*s]", user->len, user->ptr,
- domain->len, domain->ptr, ha1->len, ha1->ptr));
-
- return (user->len > 0 && domain->len > 0 && ha1->len > 0);
-}
-
-/*
- * Authorize against the opened passwords file. Return 1 if authorized.
- */
-static int
-authorize(struct conn *c, FILE *fp)
-{
- struct vec *auth_vec = &c->ch.auth.v_vec;
- struct vec *user_vec = &c->ch.user.v_vec;
- struct vec user, domain, ha1;
- struct digest digest;
- int ok = 0;
- char line[256];
-
- if (auth_vec->len > 20 &&
- !my_strncasecmp(auth_vec->ptr, "Digest ", 7)) {
-
- parse_authorization_header(auth_vec, &digest);
- *user_vec = digest.user;
-
- while (fgets(line, sizeof(line), fp) != NULL) {
-
- if (!parse_htpasswd_line(line, &user, &domain, &ha1))
- continue;
-
- DBG(("[%.*s] [%.*s] [%.*s]", user.len, user.ptr,
- domain.len, domain.ptr, ha1.len, ha1.ptr));
-
- if (vcmp(user_vec, &user) && !memcmp(c->ctx->auth_realm,
- domain.ptr, domain.len)) {
- ok = check_password(c->method, &ha1, &digest);
- break;
- }
- }
- }
-
- return (ok);
-}
-
-int
-check_authorization(struct conn *c, const char *path)
-{
- FILE *fp = NULL;
- int authorized = 1;
-
-#ifdef EMBEDDED
- struct llhead *lp;
- struct uri_auth *auth;
-
- /* Check, is this URL protected by shttpd_protect_url() */
- LL_FOREACH(&c->ctx->uri_auths, lp) {
- auth = LL_ENTRY(lp, struct uri_auth, link);
- if (!strncmp(c->uri, auth->uri, auth->uri_len)) {
- fp = fopen(auth->file_name, "r");
- break;
- }
- }
-#endif /* EMBEDDED */
-
- if (fp == NULL)
- fp = open_auth_file(c->ctx, path);
-
- if (fp != NULL) {
- authorized = authorize(c, fp);
- (void) fclose(fp);
- }
-
- return (authorized);
-}
-
-int
-is_authorized_for_put(struct conn *c)
-{
- FILE *fp;
- int ret = 0;
-
- if ((fp = fopen(c->ctx->put_auth_file, "r")) != NULL) {
- ret = authorize(c, fp);
- (void) fclose(fp);
- }
-
- return (ret);
-}
-
-void
-send_authorization_request(struct conn *c)
-{
- char buf[512];
-
- (void) my_snprintf(buf, sizeof(buf), "Unauthorized\r\n"
- "WWW-Authenticate: Digest qop=\"auth\", realm=\"%s\", "
- "nonce=\"%lu\"", c->ctx->auth_realm, (unsigned long) current_time);
-
- send_server_error(c, 401, buf);
-}
-
-/*
- * Edit the passwords file.
- */
-int
-edit_passwords(const char *fname, const char *domain,
- const char *user, const char *pass)
-{
- int ret = EXIT_SUCCESS, found = 0;
- struct vec u, d, p;
- char line[512], tmp[FILENAME_MAX], ha1[32];
- FILE *fp = NULL, *fp2 = NULL;
-
- (void) my_snprintf(tmp, sizeof(tmp), "%s.tmp", fname);
-
- /* Create the file if does not exist */
- if ((fp = fopen(fname, "a+")))
- (void) fclose(fp);
-
- /* Open the given file and temporary file */
- if ((fp = fopen(fname, "r")) == NULL)
- elog(E_FATAL, 0, "Cannot open %s: %s", fname, strerror(errno));
- else if ((fp2 = fopen(tmp, "w+")) == NULL)
- elog(E_FATAL, 0, "Cannot open %s: %s", tmp, strerror(errno));
-
- p.ptr = pass;
- p.len = strlen(pass);
-
- /* Copy the stuff to temporary file */
- while (fgets(line, sizeof(line), fp) != NULL) {
- u.ptr = line;
- if ((d.ptr = strchr(line, ':')) == NULL)
- continue;
- u.len = d.ptr - u.ptr;
- d.ptr++;
- if (strchr(d.ptr, ':') == NULL)
- continue;
- d.len = strchr(d.ptr, ':') - d.ptr;
-
- if ((int) strlen(user) == u.len &&
- !memcmp(user, u.ptr, u.len) &&
- (int) strlen(domain) == d.len &&
- !memcmp(domain, d.ptr, d.len)) {
- found++;
- md5(ha1, &u, &d, &p, NULL);
- (void) fprintf(fp2, "%s:%s:%.32s\n", user, domain, ha1);
- } else {
- (void) fprintf(fp2, "%s", line);
- }
- }
-
- /* If new user, just add it */
- if (found == 0) {
- u.ptr = user; u.len = strlen(user);
- d.ptr = domain; d.len = strlen(domain);
- md5(ha1, &u, &d, &p, NULL);
- (void) fprintf(fp2, "%s:%s:%.32s\n", user, domain, ha1);
- }
-
- /* Close files */
- (void) fclose(fp);
- (void) fclose(fp2);
-
- /* Put the temp file in place of real file */
- (void) my_remove(fname);
- (void) my_rename(tmp, fname);
-
- return (ret);
-}
-#endif /* NO_AUTH */
diff --git a/cpukit/shttpd/cgi.c b/cpukit/shttpd/cgi.c
deleted file mode 100644
index 98d83db241..0000000000
--- a/cpukit/shttpd/cgi.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-#if !defined(NO_CGI)
-struct env_block {
- char buf[ENV_MAX]; /* Environment buffer */
- int len; /* Space taken */
- char *vars[CGI_ENV_VARS]; /* Point into the buffer */
- int nvars; /* Number of variables */
-};
-
-/*
- * Verify that given file has CGI extension
- */
-int
-is_cgi(struct shttpd_ctx *ctx, const char *path)
-{
- size_t len, path_len;
- const char *s = ctx->cgi_extensions;
-
- path_len = strlen(path);
-
- FOR_EACH_WORD_IN_LIST(s, len)
- if (len < path_len &&
- !my_strncasecmp(path + path_len - len, s, len))
- return (1);
-
- return (0);
-}
-
-/*
- * UNIX socketpair() implementation. Why? Because Windows does not have it.
- * Return 0 on success, -1 on error.
- */
-static int
-my_socketpair(struct conn *c, int sp[2])
-{
- struct sockaddr_in sa;
- int sock, ret = -1;
- socklen_t len = sizeof(sa);
-
- (void) memset(&sa, 0, sizeof(sa));
- sa.sin_family = AF_INET;
- sa.sin_port = htons(0);
- sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
- elog(E_LOG, c, "mysocketpair: socket(): %d", ERRNO);
- } else if (bind(sock, (struct sockaddr *) &sa, len) != 0) {
- elog(E_LOG, c, "mysocketpair: bind(): %d", ERRNO);
- (void) closesocket(sock);
- } else if (listen(sock, 1) != 0) {
- elog(E_LOG, c, "mysocketpair: listen(): %d", ERRNO);
- (void) closesocket(sock);
- } else if (getsockname(sock, (struct sockaddr *) &sa, &len) != 0) {
- elog(E_LOG, c, "mysocketpair: getsockname(): %d", ERRNO);
- (void) closesocket(sock);
- } else if ((sp[0] = socket(AF_INET, SOCK_STREAM, 6)) == -1) {
- elog(E_LOG, c, "mysocketpair: socket(): %d", ERRNO);
- (void) closesocket(sock);
- } else if (connect(sp[0], (struct sockaddr *) &sa, len) != 0) {
- elog(E_LOG, c, "mysocketpair: connect(): %d", ERRNO);
- (void) closesocket(sock);
- (void) closesocket(sp[0]);
- } else if ((sp[1] = accept(sock,(struct sockaddr *) &sa, &len)) == -1) {
- elog(E_LOG, c, "mysocketpair: accept(): %d", ERRNO);
- (void) closesocket(sock);
- (void) closesocket(sp[0]);
- } else {
- /* Success */
- ret = 0;
- (void) closesocket(sock);
- }
-
-#ifndef _WIN32
- (void) fcntl(sp[0], F_SETFD, FD_CLOEXEC);
- (void) fcntl(sp[1], F_SETFD, FD_CLOEXEC);
-#endif /* _WIN32*/
-
- return (ret);
-}
-
-static void
-addenv(struct env_block *block, const char *fmt, ...)
-{
- int n, space;
- va_list ap;
-
- space = sizeof(block->buf) - block->len - 2;
- assert(space >= 0);
-
- va_start(ap, fmt);
- n = vsnprintf(block->buf + block->len, space, fmt, ap);
- va_end(ap);
-
- if (n > 0 && n < space && block->nvars < CGI_ENV_VARS - 2) {
- block->vars[block->nvars++] = block->buf + block->len;
- block->len += n + 1; /* Include \0 terminator */
- }
-}
-
-static void
-add_http_headers_to_env(struct env_block *b, const char *s, int len)
-{
- const char *p, *v, *e = s + len;
- int space, n, i, ch;
-
- /* Loop through all headers in the request */
- while (s < e) {
-
- /* Find where this header ends. Remember where value starts */
- for (p = s, v = NULL; p < e && *p != '\n'; p++)
- if (v == NULL && *p == ':')
- v = p;
-
- /* 2 null terminators and "HTTP_" */
- space = (sizeof(b->buf) - b->len) - (2 + 5);
- assert(space >= 0);
-
- /* Copy header if enough space in the environment block */
- if (v > s && p > v + 2 && space > p - s) {
-
- /* Store var */
- if (b->nvars < (int) NELEMS(b->vars) - 1)
- b->vars[b->nvars++] = b->buf + b->len;
-
- (void) memcpy(b->buf + b->len, "HTTP_", 5);
- b->len += 5;
-
- /* Copy header name. Substitute '-' to '_' */
- n = v - s;
- for (i = 0; i < n; i++) {
- ch = s[i] == '-' ? '_' : s[i];
- b->buf[b->len++] = toupper(ch);
- }
-
- b->buf[b->len++] = '=';
-
- /* Copy header value */
- v += 2;
- n = p[-1] == '\r' ? (p - v) - 1 : p - v;
- for (i = 0; i < n; i++)
- b->buf[b->len++] = v[i];
-
- /* Null-terminate */
- b->buf[b->len++] = '\0';
- }
-
- s = p + 1; /* Shift to the next header */
- }
-}
-
-static void
-prepare_environment(const struct conn *c, const char *prog,
- struct env_block *blk)
-{
- const struct headers *h = &c->ch;
- const char *s;
- size_t len;
-
- blk->len = blk->nvars = 0;
-
- /* Prepare the environment block */
- addenv(blk, "%s", "GATEWAY_INTERFACE=CGI/1.1");
- addenv(blk, "%s", "SERVER_PROTOCOL=HTTP/1.1");
- addenv(blk, "%s", "REDIRECT_STATUS=200"); /* PHP */
- addenv(blk, "SERVER_PORT=%d", c->ctx->port);
- addenv(blk, "SERVER_NAME=%s", c->ctx->auth_realm);
- addenv(blk, "SERVER_ROOT=%s", c->ctx->document_root);
- addenv(blk, "DOCUMENT_ROOT=%s", c->ctx->document_root);
- addenv(blk, "REQUEST_METHOD=%s", known_http_methods[c->method].ptr);
- addenv(blk, "REMOTE_ADDR=%s", inet_ntoa(c->sa.u.sin.sin_addr));
- addenv(blk, "REMOTE_PORT=%hu", ntohs(c->sa.u.sin.sin_port));
- addenv(blk, "REQUEST_URI=%s", c->uri);
- addenv(blk, "SCRIPT_NAME=%s", prog + strlen(c->ctx->document_root));
- addenv(blk, "SCRIPT_FILENAME=%s", prog); /* PHP */
- addenv(blk, "PATH_TRANSLATED=%s", prog);
-
- if (h->ct.v_vec.len > 0)
- addenv(blk, "CONTENT_TYPE=%.*s",
- h->ct.v_vec.len, h->ct.v_vec.ptr);
-
- if (c->query != NULL)
- addenv(blk, "QUERY_STRING=%s", c->query);
-
- if (c->path_info != NULL)
- addenv(blk, "PATH_INFO=/%s", c->path_info);
-
- if (h->cl.v_big_int > 0)
- addenv(blk, "CONTENT_LENGTH=%lu", h->cl.v_big_int);
-
- if ((s = getenv("PATH")) != NULL)
- addenv(blk, "PATH=%s", s);
-
-#ifdef _WIN32
- if ((s = getenv("COMSPEC")) != NULL)
- addenv(blk, "COMSPEC=%s", s);
- if ((s = getenv("SYSTEMROOT")) != NULL)
- addenv(blk, "SYSTEMROOT=%s", s);
-#else
- if ((s = getenv("LD_LIBRARY_PATH")) != NULL)
- addenv(blk, "LD_LIBRARY_PATH=%s", s);
-#endif /* _WIN32 */
-
- if ((s = getenv("PERLLIB")) != NULL)
- addenv(blk, "PERLLIB=%s", s);
-
- if (h->user.v_vec.len > 0) {
- addenv(blk, "REMOTE_USER=%.*s",
- h->user.v_vec.len, h->user.v_vec.ptr);
- addenv(blk, "%s", "AUTH_TYPE=Digest");
- }
-
- /* Add user-specified variables */
- s = c->ctx->cgi_vars;
- FOR_EACH_WORD_IN_LIST(s, len)
- addenv(blk, "%.*s", len, s);
-
- /* Add all headers as HTTP_* variables */
- add_http_headers_to_env(blk, c->headers,
- c->rem.headers_len - (c->headers - c->request));
-
- blk->vars[blk->nvars++] = NULL;
- blk->buf[blk->len++] = '\0';
-
- assert(blk->nvars < CGI_ENV_VARS);
- assert(blk->len > 0);
- assert(blk->len < (int) sizeof(blk->buf));
-
- /* Debug stuff to view passed environment */
- DBG(("%s: %d vars, %d env size", prog, blk->nvars, blk->len));
- {
- int i;
- for (i = 0 ; i < blk->nvars; i++)
- DBG(("[%s]", blk->vars[i] ? blk->vars[i] : "null"));
- }
-}
-
-int
-run_cgi(struct conn *c, const char *prog)
-{
- struct env_block blk;
- char dir[FILENAME_MAX], *p;
- int ret, pair[2];
-
- prepare_environment(c, prog, &blk);
-
- /* CGI must be executed in its own directory */
- (void) my_snprintf(dir, sizeof(dir), "%s", prog);
- for (p = dir + strlen(dir) - 1; p > dir; p--)
- if (*p == '/') {
- *p++ = '\0';
- break;
- }
-
- if (my_socketpair(c, pair) != 0) {
- ret = -1;
- } else if (spawn_process(c, prog, blk.buf, blk.vars, pair[1], dir)) {
- ret = -1;
- (void) closesocket(pair[0]);
- (void) closesocket(pair[1]);
- } else {
- ret = 0;
- c->loc.chan.sock = pair[0];
- }
-
- return (ret);
-}
-
-void
-do_cgi(struct conn *c)
-{
- DBG(("running CGI: [%s]", c->uri));
- assert(c->loc.io.size > CGI_REPLY_LEN);
- memcpy(c->loc.io.buf, CGI_REPLY, CGI_REPLY_LEN);
- c->loc.io.head = c->loc.io.tail = c->loc.io.total = CGI_REPLY_LEN;
- c->loc.io_class = &io_cgi;
- c->loc.flags = FLAG_R;
- if (c->method == METHOD_POST)
- c->loc.flags |= FLAG_W;
-}
-
-#endif /* !NO_CGI */
diff --git a/cpukit/shttpd/compat_rtems.c b/cpukit/shttpd/compat_rtems.c
deleted file mode 100644
index 19f28d045c..0000000000
--- a/cpukit/shttpd/compat_rtems.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/**********************************************************************
- *
- * rtems shttpd management
- *
- * FILE NAME : rtems_shttpd.c
- *
- * AUTHOR : Steven Johnson
- *
- * DESCRIPTION : Defines the interface functions to the shttp daemon
- *
- * REVISION : $Id$
- *
- * COMMENTS :
- *
- **********************************************************************/
-
- /**********************************************************************
- * INCLUDED MODULES
- **********************************************************************/
-#include <rtems.h>
-#include "defs.h"
-
-#define MAX_WEB_BASE_PATH_LENGTH 256
-#define MIN_SHTTPD_STACK (8*1024)
-
-typedef struct RTEMS_HTTPD_ARGS {
- rtems_shttpd_init init_callback;
- rtems_shttpd_addpages addpages_callback;
- unsigned int port;
- char webroot[MAX_WEB_BASE_PATH_LENGTH];
-} RTEMS_HTTPD_ARGS;
-
-static int rtems_webserver_running = FALSE; /* not running. */
-
-static rtems_task rtems_httpd_daemon(rtems_task_argument args)
-{
- RTEMS_HTTPD_ARGS *httpd_args = (RTEMS_HTTPD_ARGS*)args;
-
- struct shttpd_ctx *ctx;
-
- if (httpd_args != NULL)
- if (httpd_args->init_callback != NULL)
- httpd_args->init_callback();
-
-/**************************************
- * Initialize the web server
- */
- /*
- * Initialize SHTTPD context.
- * Set WWW root to current WEB_ROOT_PATH.
- */
- ctx = shttpd_init(NULL, "document_root", httpd_args->webroot, NULL);
-
- if (httpd_args != NULL)
- if (httpd_args->addpages_callback != NULL)
- httpd_args->addpages_callback(ctx);
-
- /* Finished with args, so free them */
- if (httpd_args != NULL)
- free(httpd_args);
-
- /* Open listening socket */
- shttpd_listen(ctx, httpd_args->port);
-
- rtems_webserver_running = TRUE;
-
- /* Serve connections infinitely until someone kills us */
- while (rtems_webserver_running)
- shttpd_poll(ctx, 1000);
-
- /* Unreached, because we will be killed by a signal */
- shttpd_fini(ctx);
-
- rtems_task_delete( RTEMS_SELF );
-}
-
-rtems_status_code rtems_initialize_webserver(
- rtems_task_priority initial_priority,
- size_t stack_size,
- rtems_mode initial_modes,
- rtems_attribute attribute_set,
- rtems_shttpd_init init_callback,
- rtems_shttpd_addpages addpages_callback,
- char *webroot,
- unsigned int port
-)
-{
- rtems_status_code sc;
- rtems_id tid;
- RTEMS_HTTPD_ARGS *args;
-
- if (stack_size < MIN_SHTTPD_STACK)
- stack_size = MIN_SHTTPD_STACK;
-
- args = malloc(sizeof(RTEMS_HTTPD_ARGS));
-
- if (args != NULL) {
- args->init_callback = init_callback;
- args->addpages_callback = addpages_callback;
- args->port = port;
- strncpy(args->webroot,webroot,MAX_WEB_BASE_PATH_LENGTH);
-
- sc = rtems_task_create(rtems_build_name('H', 'T', 'P', 'D'),
- initial_priority,
- stack_size,
- initial_modes,
- attribute_set,
- &tid);
-
- if (sc == RTEMS_SUCCESSFUL) {
- sc = rtems_task_start(tid, rtems_httpd_daemon, (rtems_task_argument)args);
- }
- } else {
- sc = RTEMS_NO_MEMORY;
- }
-
- return sc;
-}
-
-void rtems_terminate_webserver(void)
-{
- rtems_webserver_running = FALSE; /* not running, so terminate */
-}
-
-int rtems_webserver_ok(void)
-{
- return rtems_webserver_running;
-}
-
-void
-set_close_on_exec(int fd)
-{
- /*
- * RTEMS Does not have a functional "execve"
- * so technically this call does not do anything,
- * but it doesnt hurt either.
- */
- (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
-}
-#ifndef __rtems__
-int
-my_stat(const char *path, struct stat *stp)
-{
- return (stat(path, stp));
-}
-
-int
-my_open(const char *path, int flags, int mode)
-{
- return (open(path, flags, mode));
-}
-
-int
-my_remove(const char *path)
-{
- return (remove(path));
-}
-
-int
-my_rename(const char *path1, const char *path2)
-{
- return (rename(path1, path2));
-}
-
-int
-my_mkdir(const char *path, int mode)
-{
- return (mkdir(path, mode));
-}
-
-char *
-my_getcwd(char *buffer, int maxlen)
-{
- return (getcwd(buffer, maxlen));
-}
-#endif
-int
-set_non_blocking_mode(int fd)
-{
- int ret = -1;
- int flags;
-
- if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
- DBG(("nonblock: fcntl(F_GETFL): %d", ERRNO));
- } else if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) {
- DBG(("nonblock: fcntl(F_SETFL): %d", ERRNO));
- } else {
- ret = 0; /* Success */
- }
-
- return (ret);
-}
-
-#if !defined(NO_CGI)
-int
-spawn_process(struct conn *c, const char *prog, char *envblk, char **envp)
-{
- return (-1); // RTEMS does not have subprocess support as standard.
-}
-#endif
diff --git a/cpukit/shttpd/compat_rtems.h b/cpukit/shttpd/compat_rtems.h
deleted file mode 100644
index aae550ca4b..0000000000
--- a/cpukit/shttpd/compat_rtems.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * @file rtems/rtems-shttpd.h
- */
-
-#ifndef _rtems_rtems_webserver_h
-#define _rtems_rtems_webserver_h
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "shttpd.h"
-
-#include <rtems.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <netinet/in.h>
-#include <dirent.h>
-#include <arpa/inet.h>
-
-/* RTEMS is an Real Time Embedded operating system, for operation in hardware.
- It does not have SSL or CGI support, as it does not have dynamic library
- loading or sub-processes. */
-#define EMBEDDED
-#define NO_SSL
-#define NO_CGI
-
-#define DIRSEP '/'
-#define IS_DIRSEP_CHAR(c) ((c) == '/')
-#define O_BINARY 0
-#define closesocket(a) close(a)
-#define ERRNO errno
-
-/* RTEMS version is Thread Safe */
-#define InitializeCriticalSection(x) rtems_semaphore_create( \
- rtems_build_name('H','T','P','X'), \
- 1, /* Not Held Yet.*/ \
- RTEMS_FIFO | \
- RTEMS_BINARY_SEMAPHORE, \
- 0, \
- x);
-#define EnterCriticalSection(x) rtems_semaphore_obtain(*(x),RTEMS_WAIT,RTEMS_NO_TIMEOUT)
-#define LeaveCriticalSection(x) rtems_semaphore_release(*(x))
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void (*rtems_shttpd_addpages)(struct shttpd_ctx *ctx);
-typedef void (*rtems_shttpd_init)(void);
-
-rtems_status_code rtems_initialize_webserver(rtems_task_priority initial_priority,
- size_t stack_size,
- rtems_mode initial_modes,
- rtems_attribute attribute_set,
- rtems_shttpd_init init_callback,
- rtems_shttpd_addpages addpages_callback,
- char *webroot,
- unsigned int port
- );
-void rtems_terminate_webserver(void);
-int rtems_webserver_ok(void);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/cpukit/shttpd/compat_unix.c b/cpukit/shttpd/compat_unix.c
deleted file mode 100644
index 819361fd8c..0000000000
--- a/cpukit/shttpd/compat_unix.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-void
-set_close_on_exec(int fd)
-{
- (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
-}
-
-int
-my_stat(const char *path, struct stat *stp)
-{
- return (stat(path, stp));
-}
-
-int
-my_open(const char *path, int flags, int mode)
-{
- return (open(path, flags, mode));
-}
-
-int
-my_remove(const char *path)
-{
- return (remove(path));
-}
-
-int
-my_rename(const char *path1, const char *path2)
-{
- return (rename(path1, path2));
-}
-
-int
-my_mkdir(const char *path, int mode)
-{
- return (mkdir(path, mode));
-}
-
-char *
-my_getcwd(char *buffer, int maxlen)
-{
- return (getcwd(buffer, maxlen));
-}
-
-int
-set_non_blocking_mode(int fd)
-{
- int ret = -1;
- int flags;
-
- if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
- DBG(("nonblock: fcntl(F_GETFL): %d", ERRNO));
- } else if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) {
- DBG(("nonblock: fcntl(F_SETFL): %d", ERRNO));
- } else {
- ret = 0; /* Success */
- }
-
- return (ret);
-}
-
-#ifndef NO_CGI
-int
-spawn_process(struct conn *c, const char *prog, char *envblk,
- char *envp[], int sock, const char *dir)
-{
- int ret;
- pid_t pid;
-
- envblk = NULL; /* unused */
-
- if ((pid = vfork()) == -1) {
-
- ret = -1;
- elog(E_LOG, c, "redirect: fork: %s", strerror(errno));
-
- } else if (pid == 0) {
-
- /* Child */
- (void) chdir(dir);
- (void) dup2(sock, 0);
- (void) dup2(sock, 1);
- (void) closesocket(sock);
-
- /* If error file is specified, send errors there */
- if (c->ctx->error_log)
- (void) dup2(fileno(c->ctx->error_log), 2);
-
- /* Execute CGI program */
- if (c->ctx->cgi_interpreter == NULL) {
- (void) execle(prog, prog, NULL, envp);
- elog(E_FATAL, c, "redirect: exec(%s)", prog);
- } else {
- (void) execle(c->ctx->cgi_interpreter,
- c->ctx->cgi_interpreter, prog, NULL, envp);
- elog(E_FATAL, c, "redirect: exec(%s %s)",
- c->ctx->cgi_interpreter, prog);
- }
-
- /* UNREACHED */
- ret = -1;
- exit(EXIT_FAILURE);
-
- } else {
-
- /* Parent */
- ret = 0;
- (void) closesocket(sock);
- }
-
- return (ret);
-}
-#endif /* !NO_CGI */
diff --git a/cpukit/shttpd/compat_unix.h b/cpukit/shttpd/compat_unix.h
deleted file mode 100644
index 67c935faaf..0000000000
--- a/cpukit/shttpd/compat_unix.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2004-2007 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/mman.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-
-#include <pwd.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <dlfcn.h>
-#define SSL_LIB "libssl.so"
-#define DIRSEP '/'
-#define IS_DIRSEP_CHAR(c) ((c) == '/')
-#define O_BINARY 0
-#define closesocket(a) close(a)
-#define ERRNO errno
-#define NO_GUI
-
-#define InitializeCriticalSection(x) /* FIXME UNIX version is not MT safe */
-#define EnterCriticalSection(x)
-#define LeaveCriticalSection(x)
diff --git a/cpukit/shttpd/compat_win32.c b/cpukit/shttpd/compat_win32.c
deleted file mode 100644
index ee1221e7a2..0000000000
--- a/cpukit/shttpd/compat_win32.c
+++ /dev/null
@@ -1,923 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-static const char *config_file = CONFIG;
-
-#if !defined(NO_GUI)
-
-static HICON hIcon; /* SHTTPD icon handle */
-HWND hLog; /* Log window */
-
-/*
- * Dialog box control IDs
- */
-#define ID_GROUP 100
-#define ID_SAVE 101
-#define ID_STATUS 102
-#define ID_STATIC 103
-#define ID_SETTINGS 104
-#define ID_QUIT 105
-#define ID_TRAYICON 106
-#define ID_TIMER 107
-#define ID_ICON 108
-#define ID_ADVANCED 109
-#define ID_SHOWLOG 110
-#define ID_LOG 111
-
-#define ID_USER 200
-#define ID_DELTA 1000
-
-static void
-run_server(void *param)
-{
- struct shttpd_ctx *ctx = param;
-
- if (shttpd_listen(ctx, ctx->port) == -1)
- elog(E_FATAL, NULL, "Cannot open socket on port %d", ctx->port);
-
- while (WaitForSingleObject(ctx->ev[0], 0) != WAIT_OBJECT_0)
- shttpd_poll(ctx, 1000);
-
- SetEvent(ctx->ev[1]);
- shttpd_fini(ctx);
-}
-
-/*
- * Save the configuration back into config file
- */
-static void
-save_config(HWND hDlg, FILE *fp)
-{
- const struct opt *opt;
- char text[FILENAME_MAX];
- int id;
-
- if (fp == NULL)
- elog(E_FATAL, NULL, "save_config: cannot open %s", config_file);
-
- for (opt = options; opt->name != NULL; opt++) {
- id = ID_USER + (opt - options); /* Control ID */
-
- /* Do not save if the text is the same as default */
-
- if (opt->flags & OPT_BOOL)
- (void) fprintf(fp, "%s\t%d\n",
- opt->name, IsDlgButtonChecked(hDlg, id));
- else if (GetDlgItemText(hDlg, id, text, sizeof(text)) != 0 &&
- (opt->def == NULL || strcmp(text, opt->def) != 0))
- (void) fprintf(fp, "%s\t%s\n", opt->name, text);
- }
-
- (void) fclose(fp);
-}
-
-static void
-set_control_values(HWND hDlg, const struct shttpd_ctx *ctx)
-{
- const struct opt *opt;
- const union variant *v;
- char buf[FILENAME_MAX];
- int id;
-
- for (opt = options; opt->name != NULL; opt++) {
- id = ID_USER + (opt - options);
- v = (union variant *) ((char *) ctx + opt->ofs);
- if (opt->flags & OPT_BOOL) {
- CheckDlgButton(hDlg, id,
- v->v_int ? BST_CHECKED : BST_UNCHECKED);
- } else if (opt->flags & OPT_INT) {
- my_snprintf(buf, sizeof(buf), "%d", v->v_int);
- SetDlgItemText(hDlg, id, buf);
- } else {
- SetDlgItemText(hDlg, id, v->v_str);
- }
- }
-
-}
-
-static BOOL CALLBACK
-DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- static struct shttpd_ctx *ctx, **pctx;
- HANDLE ev;
- const struct opt *opt;
- DWORD tid;
- int id, up;
- char text[256];
-
- switch (msg) {
-
- case WM_CLOSE:
- KillTimer(hDlg, ID_TIMER);
- DestroyWindow(hDlg);
- break;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case ID_SAVE:
- EnableWindow(GetDlgItem(hDlg, ID_SAVE), FALSE);
- save_config(hDlg, fopen(config_file, "w+"));
- ev = ctx->ev[1];
- SetEvent(ctx->ev[0]);
- WaitForSingleObject(ev, INFINITE);
- *pctx = ctx = init_from_argc_argv(config_file, 0, NULL);
- shttpd_listen(ctx, ctx->port);
- _beginthread(run_server, 0, ctx);
- EnableWindow(GetDlgItem(hDlg, ID_SAVE), TRUE);
-
- break;
- }
-
- id = ID_USER + ID_DELTA;
- for (opt = options; opt->name != NULL; opt++, id++)
- if (LOWORD(wParam) == id) {
- OPENFILENAME of;
- BROWSEINFO bi;
- char path[FILENAME_MAX] = "";
-
- memset(&of, 0, sizeof(of));
- of.lStructSize = sizeof(of);
- of.hwndOwner = (HWND) hDlg;
- of.lpstrFile = path;
- of.nMaxFile = sizeof(path);
- of.lpstrInitialDir = ctx->document_root;
- of.Flags = OFN_CREATEPROMPT | OFN_NOCHANGEDIR;
-
- memset(&bi, 0, sizeof(bi));
- bi.hwndOwner = (HWND) hDlg;
- bi.lpszTitle = "Choose WWW root directory:";
- bi.ulFlags = BIF_RETURNONLYFSDIRS;
-
- if (opt->flags & OPT_DIR)
- SHGetPathFromIDList(
- SHBrowseForFolder(&bi), path);
- else
- GetOpenFileName(&of);
-
- if (path[0] != '\0')
- SetWindowText(GetDlgItem(hDlg,
- id - ID_DELTA), path);
- }
-
- break;
-
- case WM_INITDIALOG:
- pctx = (struct shttpd_ctx **) lParam;
- ctx = *pctx;
- SendMessage(hDlg,WM_SETICON,(WPARAM)ICON_SMALL,(LPARAM)hIcon);
- SendMessage(hDlg,WM_SETICON,(WPARAM)ICON_BIG,(LPARAM)hIcon);
- SetWindowText(hDlg, "SHTTPD settings");
- SetFocus(GetDlgItem(hDlg, ID_SAVE));
- set_control_values(hDlg, ctx);
- break;
- default:
- break;
- }
-
- return FALSE;
-}
-
-static void *
-align(void *ptr, DWORD alig)
-{
- ULONG ul = (ULONG) ptr;
-
- ul += alig;
- ul &= ~alig;
-
- return ((void *) ul);
-}
-
-
-static void
-add_control(unsigned char **mem, DLGTEMPLATE *dia, WORD type, DWORD id,
- DWORD style, WORD x, WORD y, WORD cx, WORD cy, const char *caption)
-{
- DLGITEMTEMPLATE *tp;
- LPWORD p;
-
- dia->cdit++;
-
- *mem = align(*mem, 3);
- tp = (DLGITEMTEMPLATE *) *mem;
-
- tp->id = (WORD)id;
- tp->style = style;
- tp->dwExtendedStyle = 0;
- tp->x = x;
- tp->y = y;
- tp->cx = cx;
- tp->cy = cy;
-
- p = align(*mem + sizeof(*tp), 1);
- *p++ = 0xffff;
- *p++ = type;
-
- while (*caption != '\0')
- *p++ = (WCHAR) *caption++;
- *p++ = 0;
- p = align(p, 1);
-
- *p++ = 0;
- *mem = (unsigned char *) p;
-}
-
-static void
-show_settings_dialog(struct shttpd_ctx **ctxp)
-{
-#define HEIGHT 15
-#define WIDTH 400
-#define LABEL_WIDTH 70
-
- unsigned char mem[4096], *p;
- DWORD style;
- DLGTEMPLATE *dia = (DLGTEMPLATE *) mem;
- WORD cl, x, y, width, nelems = 0;
- const struct opt *opt;
- static int guard;
-
- static struct {
- DLGTEMPLATE template; /* 18 bytes */
- WORD menu, class;
- wchar_t caption[1];
- WORD fontsiz;
- wchar_t fontface[7];
- } dialog_header = {{WS_CAPTION | WS_POPUP | WS_SYSMENU | WS_VISIBLE |
- DS_SETFONT | WS_DLGFRAME, WS_EX_TOOLWINDOW,
- 0, 200, 200, WIDTH, 0}, 0, 0, L"", 8, L"Tahoma"};
-
- if (guard == 0)
- guard++;
- else
- return;
-
- (void) memset(mem, 0, sizeof(mem));
- (void) memcpy(mem, &dialog_header, sizeof(dialog_header));
- p = mem + sizeof(dialog_header);
-
- for (opt = options; opt->name != NULL; opt++) {
-
- style = WS_CHILD | WS_VISIBLE | WS_TABSTOP;
- x = 10 + (WIDTH / 2) * (nelems % 2);
- y = (nelems/2 + 1) * HEIGHT + 5;
- width = WIDTH / 2 - 20 - LABEL_WIDTH;
- if (opt->flags & OPT_INT) {
- style |= ES_NUMBER;
- cl = 0x81;
- style |= WS_BORDER | ES_AUTOHSCROLL;
- } else if (opt->flags & OPT_BOOL) {
- cl = 0x80;
- style |= BS_AUTOCHECKBOX;
- } else if (opt->flags & (OPT_DIR | OPT_FILE)) {
- style |= WS_BORDER | ES_AUTOHSCROLL;
- width -= 20;
- cl = 0x81;
- add_control(&p, dia, 0x80,
- ID_USER + ID_DELTA + (opt - options),
- WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
- (WORD) (x + width + LABEL_WIDTH + 5),
- y, 15, 12, "...");
- } else {
- cl = 0x81;
- style |= WS_BORDER | ES_AUTOHSCROLL;
- }
- add_control(&p, dia, 0x82, ID_STATIC, WS_VISIBLE | WS_CHILD,
- x, y, LABEL_WIDTH, HEIGHT, opt->desc);
- add_control(&p, dia, cl, ID_USER + (opt - options), style,
- (WORD) (x + LABEL_WIDTH), y, width, 12, "");
- nelems++;
- }
-
- y = (WORD) (((nelems + 1)/2 + 1) * HEIGHT + 5);
- add_control(&p, dia, 0x80, ID_GROUP, WS_CHILD | WS_VISIBLE |
- BS_GROUPBOX, 5, 5, WIDTH - 10, y, "Settings");
- y += 10;
- add_control(&p, dia, 0x80, ID_SAVE,
- WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP,
- WIDTH - 70, y, 65, 12, "Save Settings");
-#if 0
- add_control(&p, dia, 0x80, ID_ADVANCED,
- WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP,
- WIDTH - 190, y, 110, 12, "Show Advanced Settings >>");
-#endif
- add_control(&p, dia, 0x82, ID_STATIC,
- WS_CHILD | WS_VISIBLE | WS_DISABLED,
- 5, y, 180, 12,"SHTTPD v." VERSION
- " (http://shttpd.sourceforge.net)");
-
- dia->cy = ((nelems + 1)/2 + 1) * HEIGHT + 30;
- DialogBoxIndirectParam(NULL, dia, NULL, DlgProc, (LPARAM) ctxp);
- guard--;
-}
-
-static BOOL CALLBACK
-LogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- static struct shttpd_ctx *ctx;
- static HWND hStatus;
- HWND hEdit;
- RECT rect, rect2, rect3, rect4;
- int len, up, widths[] = {120, 220, 330, 460, -1};
- char text[256], buf[1024 * 64];
-
- switch (msg) {
-
- case WM_CLOSE:
- KillTimer(hDlg, ID_TIMER);
- DestroyWindow(hDlg);
- break;
-
- case WM_APP:
- hEdit = GetDlgItem(hDlg, ID_LOG);
- len = GetWindowText(hEdit, buf, sizeof(buf));
- if (len > sizeof(buf) * 4 / 5)
- len = sizeof(buf) * 4 / 5;
- my_snprintf(buf + len, sizeof(buf) - len,
- "%s\r\n", (char *) lParam);
- SetWindowText(hEdit, buf);
- SendMessage(hEdit, WM_VSCROLL, SB_BOTTOM, 0);
- break;
-
- case WM_TIMER:
- /* Print statistics on a status bar */
- up = current_time - ctx->start_time;
- (void) my_snprintf(text, sizeof(text),
- " Up: %3d h %2d min %2d sec",
- up / 3600, up / 60 % 60, up % 60);
- SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM) text);
- (void) my_snprintf(text, sizeof(text),
- " Requests: %u", ctx->nrequests);
- SendMessage(hStatus, SB_SETTEXT, 1, (LPARAM) text);
- (void) my_snprintf(text, sizeof(text),
- " Sent: %4.2f Mb", (double) ctx->out / 1048576);
- SendMessage(hStatus, SB_SETTEXT, 2, (LPARAM) text);
- (void) my_snprintf(text, sizeof(text),
- " Received: %4.2f Mb", (double) ctx->in / 1048576);
- SendMessage(hStatus, SB_SETTEXT, 3, (LPARAM) text);
- break;
-
- case WM_INITDIALOG:
- ctx = (struct shttpd_ctx *) lParam;
- SendMessage(hDlg,WM_SETICON,(WPARAM)ICON_SMALL,(LPARAM)hIcon);
- SendMessage(hDlg,WM_SETICON,(WPARAM)ICON_BIG,(LPARAM)hIcon);
- hStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE,
- "", hDlg, ID_STATUS);
- SendMessage(hStatus, SB_SETPARTS, 5, (LPARAM) widths);
- SendMessage(hStatus, SB_SETTEXT, 4, (LPARAM) " Running");
- SetWindowText(hDlg, "SHTTPD web server log");
- SetTimer(hDlg, ID_TIMER, 1000, NULL);
- GetWindowRect(GetDesktopWindow(), &rect3);
- GetWindowRect(hDlg, &rect4);
- GetClientRect(hDlg, &rect);
- GetClientRect(hStatus, &rect2);
- SetWindowPos(GetDlgItem(hDlg, ID_LOG), 0,
- 0, 0, rect.right, rect.bottom - rect2.bottom, 0);
- SetWindowPos(hDlg, HWND_TOPMOST,
- rect3.right - (rect4.right - rect4.left),
- rect3.bottom - (rect4.bottom - rect4.top) - 30,
- 0, 0, SWP_NOSIZE);
- SetFocus(hStatus);
- SendMessage(hDlg, WM_TIMER, 0, 0);
- hLog = hDlg;
- break;
- default:
- break;
- }
-
-
- return (FALSE);
-}
-
-static void
-show_log_window(struct shttpd_ctx *ctx)
-{
- unsigned char mem[4096], *p;
- DWORD style;
- DLGTEMPLATE *dia = (DLGTEMPLATE *) mem;
- WORD cl, x, y, width, nelems = 0;
-
- static struct {
- DLGTEMPLATE template; /* 18 bytes */
- WORD menu, class;
- wchar_t caption[1];
- WORD fontsiz;
- wchar_t fontface[7];
- } dialog_header = {{WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_SYSMENU |
- DS_SETFONT | WS_DLGFRAME, WS_EX_TOOLWINDOW,
- 0, 200, 200, 400, 100}, 0, 0, L"", 8, L"Tahoma"};
-
- if (hLog != NULL)
- return;
-
- (void) memset(mem, 0, sizeof(mem));
- (void) memcpy(mem, &dialog_header, sizeof(dialog_header));
- p = mem + sizeof(dialog_header);
-
- add_control(&p, dia, 0x81, ID_LOG, WS_CHILD | WS_VISIBLE |
- WS_BORDER | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL |
- ES_READONLY, 5, 5, WIDTH - 10, 60, "");
-
- DialogBoxIndirectParam(NULL, dia, NULL, LogProc, (LPARAM) ctx);
-
- hLog = NULL;
-}
-
-static LRESULT CALLBACK
-WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- static NOTIFYICONDATA ni;
- static struct shttpd_ctx *ctx;
- DWORD tid; /* Thread ID */
- HMENU hMenu;
- POINT pt;
-
- switch (msg) {
- case WM_CREATE:
- ctx = ((CREATESTRUCT *) lParam)->lpCreateParams;
- memset(&ni, 0, sizeof(ni));
- ni.cbSize = sizeof(ni);
- ni.uID = ID_TRAYICON;
- ni.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
- ni.hIcon = hIcon;
- ni.hWnd = hWnd;
- my_snprintf(ni.szTip, sizeof(ni.szTip), "SHTTPD web server");
- ni.uCallbackMessage = WM_USER;
- Shell_NotifyIcon(NIM_ADD, &ni);
- ctx->ev[0] = CreateEvent(0, TRUE, FALSE, 0);
- ctx->ev[1] = CreateEvent(0, TRUE, FALSE, 0);
- _beginthread(run_server, 0, ctx);
- break;
- case WM_CLOSE:
- Shell_NotifyIcon(NIM_DELETE, &ni);
- PostQuitMessage(0);
- break;
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case ID_SETTINGS:
- show_settings_dialog(&ctx);
- break;
- case ID_QUIT:
- SendMessage(hWnd, WM_CLOSE, wParam, lParam);
- PostQuitMessage(0);
- break;
- case ID_SHOWLOG:
- show_log_window(ctx);
- break;
- }
- break;
- case WM_USER:
- switch (lParam) {
- case WM_RBUTTONUP:
- case WM_LBUTTONUP:
- case WM_LBUTTONDBLCLK:
- hMenu = CreatePopupMenu();
- AppendMenu(hMenu, 0, ID_SETTINGS, "Settings");
- AppendMenu(hMenu, 0, ID_SHOWLOG, "Show Log");
- AppendMenu(hMenu, 0, ID_QUIT, "Exit SHTTPD");
- GetCursorPos(&pt);
- TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hWnd, NULL);
- DestroyMenu(hMenu);
- break;
- }
- break;
- }
-
- return (DefWindowProc(hWnd, msg, wParam, lParam));
-}
-
-int WINAPI
-WinMain(HINSTANCE h, HINSTANCE prev, char *cmdline, int show)
-{
- struct shttpd_ctx *ctx;
- WNDCLASS cls;
- HWND hWnd;
- MSG msg;
-
- ctx = init_from_argc_argv(config_file, 0, NULL);
- (void) memset(&cls, 0, sizeof(cls));
-
- hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(ID_ICON));
- if (hIcon == NULL)
- hIcon = LoadIcon(NULL, IDI_APPLICATION);
- cls.lpfnWndProc = (WNDPROC) WindowProc;
- cls.hIcon = hIcon;
- cls.lpszClassName = "shttpd v." VERSION;
-
- if (!RegisterClass(&cls))
- elog(E_FATAL, NULL, "RegisterClass: %d", ERRNO);
- else if ((hWnd = CreateWindow(cls.lpszClassName, "",WS_OVERLAPPEDWINDOW,
- 0, 0, 0, 0, NULL, NULL, NULL, ctx)) == NULL)
- elog(E_FATAL, NULL, "CreateWindow: %d", ERRNO);
-
- while (GetMessage(&msg, (HWND) NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- return (0);
-}
-#endif /* NO_GUI */
-
-static void
-fix_directory_separators(char *path)
-{
- for (; *path != '\0'; path++) {
- if (*path == '/')
- *path = '\\';
- if (*path == '\\')
- while (path[1] == '\\' || path[1] == '/')
- (void) memmove(path + 1,
- path + 2, strlen(path + 2) + 1);
- }
-}
-
-int
-my_open(const char *path, int flags, int mode)
-{
- char buf[FILENAME_MAX];
- wchar_t wbuf[FILENAME_MAX];
-
- my_strlcpy(buf, path, sizeof(buf));
- fix_directory_separators(buf);
- MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, sizeof(wbuf));
-
- return (_wopen(wbuf, flags));
-}
-
-int
-my_stat(const char *path, struct stat *stp)
-{
- char buf[FILENAME_MAX], *p;
- wchar_t wbuf[FILENAME_MAX];
-
- my_strlcpy(buf, path, sizeof(buf));
- fix_directory_separators(buf);
-
- p = buf + strlen(buf) - 1;
- while (p > buf && *p == '\\' && p[-1] != ':')
- *p-- = '\0';
-
- MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, sizeof(wbuf));
-
- return (_wstat(wbuf, (struct _stat *) stp));
-}
-
-int
-my_remove(const char *path)
-{
- char buf[FILENAME_MAX];
- wchar_t wbuf[FILENAME_MAX];
-
- my_strlcpy(buf, path, sizeof(buf));
- fix_directory_separators(buf);
-
- MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, sizeof(wbuf));
-
- return (_wremove(wbuf));
-}
-
-int
-my_rename(const char *path1, const char *path2)
-{
- char buf1[FILENAME_MAX];
- char buf2[FILENAME_MAX];
- wchar_t wbuf1[FILENAME_MAX];
- wchar_t wbuf2[FILENAME_MAX];
-
- my_strlcpy(buf1, path1, sizeof(buf1));
- my_strlcpy(buf2, path2, sizeof(buf2));
- fix_directory_separators(buf1);
- fix_directory_separators(buf2);
-
- MultiByteToWideChar(CP_UTF8, 0, buf1, -1, wbuf1, sizeof(wbuf1));
- MultiByteToWideChar(CP_UTF8, 0, buf2, -1, wbuf2, sizeof(wbuf2));
-
- return (_wrename(wbuf1, wbuf2));
-}
-
-int
-my_mkdir(const char *path, int mode)
-{
- char buf[FILENAME_MAX];
- wchar_t wbuf[FILENAME_MAX];
-
- my_strlcpy(buf, path, sizeof(buf));
- fix_directory_separators(buf);
-
- MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, sizeof(wbuf));
-
- return (_wmkdir(wbuf));
-}
-
-static char *
-wide_to_utf8(const wchar_t *str)
-{
- char *buf = NULL;
- if (str) {
- int nchar = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
- if (nchar > 0) {
- buf = malloc(nchar);
- if (!buf)
- errno = ENOMEM;
- else if (!WideCharToMultiByte(CP_UTF8, 0, str, -1, buf, nchar, NULL, NULL)) {
- free(buf);
- buf = NULL;
- errno = EINVAL;
- }
- } else
- errno = EINVAL;
- } else
- errno = EINVAL;
- return buf;
-}
-
-char *
-my_getcwd(char *buffer, int maxlen)
-{
- char *result = NULL;
- wchar_t *wbuffer, *wresult;
-
- if (buffer) {
- /* User-supplied buffer */
- wbuffer = malloc(maxlen * sizeof(wchar_t));
- if (wbuffer == NULL)
- return NULL;
- } else
- /* Dynamically allocated buffer */
- wbuffer = NULL;
- wresult = _wgetcwd(wbuffer, maxlen);
- if (wresult) {
- int err = errno;
- if (buffer) {
- /* User-supplied buffer */
- int n = WideCharToMultiByte(CP_UTF8, 0, wresult, -1, buffer, maxlen, NULL, NULL);
- if (n == 0)
- err = ERANGE;
- free(wbuffer);
- result = buffer;
- } else {
- /* Buffer allocated by _wgetcwd() */
- result = wide_to_utf8(wresult);
- err = errno;
- free(wresult);
- }
- errno = err;
- }
- return result;
-}
-
-DIR *
-opendir(const char *name)
-{
- DIR *dir = NULL;
- char path[FILENAME_MAX];
- wchar_t wpath[FILENAME_MAX];
-
- if (name == NULL || name[0] == '\0') {
- errno = EINVAL;
- } else if ((dir = malloc(sizeof(*dir))) == NULL) {
- errno = ENOMEM;
- } else {
- my_snprintf(path, sizeof(path), "%s/*", name);
- fix_directory_separators(path);
- MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, sizeof(wpath));
- dir->handle = FindFirstFileW(wpath, &dir->info);
-
- if (dir->handle != INVALID_HANDLE_VALUE) {
- dir->result.d_name[0] = '\0';
- } else {
- free(dir);
- dir = NULL;
- }
- }
-
- return (dir);
-}
-
-int
-closedir(DIR *dir)
-{
- int result = -1;
-
- if (dir != NULL) {
- if (dir->handle != INVALID_HANDLE_VALUE)
- result = FindClose(dir->handle) ? 0 : -1;
-
- free(dir);
- }
-
- if (result == -1)
- errno = EBADF;
-
- return (result);
-}
-
-struct dirent *
-readdir(DIR *dir)
-{
- struct dirent *result = 0;
-
- if (dir && dir->handle != INVALID_HANDLE_VALUE) {
- if(!dir->result.d_name ||
- FindNextFileW(dir->handle, &dir->info)) {
- result = &dir->result;
-
- WideCharToMultiByte(CP_UTF8, 0, dir->info.cFileName,
- -1, result->d_name,
- sizeof(result->d_name), NULL, NULL);
- }
- } else {
- errno = EBADF;
- }
-
- return (result);
-}
-
-int
-set_non_blocking_mode(int fd)
-{
- unsigned long on = 1;
-
- return (ioctlsocket(fd, FIONBIO, &on));
-}
-
-void
-set_close_on_exec(int fd)
-{
- fd = 0; /* Do nothing. There is no FD_CLOEXEC on Windows */
-}
-
-#if !defined(NO_CGI)
-
-struct threadparam {
- SOCKET s;
- HANDLE hPipe;
- big_int_t content_len;
-};
-
-/*
- * Thread function that reads POST data from the socket pair
- * and writes it to the CGI process.
- */
-static void//DWORD WINAPI
-stdoutput(void *arg)
-{
- struct threadparam *tp = arg;
- int n, sent, stop = 0;
- big_int_t total = 0;
- DWORD k;
- char buf[BUFSIZ];
- size_t max_recv;
-
- max_recv = min(sizeof(buf), tp->content_len - total);
- while (!stop && max_recv > 0 && (n = recv(tp->s, buf, max_recv, 0)) > 0) {
- for (sent = 0; !stop && sent < n; sent += k)
- if (!WriteFile(tp->hPipe, buf + sent, n - sent, &k, 0))
- stop++;
- total += n;
- max_recv = min(sizeof(buf), tp->content_len - total);
- }
-
- CloseHandle(tp->hPipe); /* Suppose we have POSTed everything */
- free(tp);
-}
-
-/*
- * Thread function that reads CGI output and pushes it to the socket pair.
- */
-static void
-stdinput(void *arg)
-{
- struct threadparam *tp = arg;
- static int ntotal;
- int k, stop = 0;
- DWORD n, sent;
- char buf[BUFSIZ];
-
- while (!stop && ReadFile(tp->hPipe, buf, sizeof(buf), &n, NULL)) {
- ntotal += n;
- for (sent = 0; !stop && sent < n; sent += k)
- if ((k = send(tp->s, buf + sent, n - sent, 0)) <= 0)
- stop++;
- }
- CloseHandle(tp->hPipe);
-
- /*
- * Windows is a piece of crap. When this thread closes its end
- * of the socket pair, the other end (get_cgi() function) may loose
- * some data. I presume, this happens if get_cgi() is not fast enough,
- * and the data written by this end does not "push-ed" to the other
- * end socket buffer. So after closesocket() the remaining data is
- * gone. If I put shutdown() before closesocket(), that seems to
- * fix the problem, but I am not sure this is the right fix.
- * XXX (submitted by James Marshall) we do not do shutdown() on UNIX.
- * If fork() is called from user callback, shutdown() messes up things.
- */
- shutdown(tp->s, 2);
-
- closesocket(tp->s);
- free(tp);
-
- _endthread();
-}
-
-static void
-spawn_stdio_thread(int sock, HANDLE hPipe, void (*func)(void *),
- big_int_t content_len)
-{
- struct threadparam *tp;
- DWORD tid;
-
- tp = malloc(sizeof(*tp));
- assert(tp != NULL);
-
- tp->s = sock;
- tp->hPipe = hPipe;
- tp->content_len = content_len;
- _beginthread(func, 0, tp);
-}
-
-int
-spawn_process(struct conn *c, const char *prog, char *envblk,
- char *envp[], int sock, const char *dir)
-{
- HANDLE a[2], b[2], h[2], me;
- DWORD flags;
- char *p, cmdline[FILENAME_MAX], line[FILENAME_MAX];
- FILE *fp;
- STARTUPINFOA si;
- PROCESS_INFORMATION pi;
-
- me = GetCurrentProcess();
- flags = DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS;
-
- /* FIXME add error checking code here */
- CreatePipe(&a[0], &a[1], NULL, 0);
- CreatePipe(&b[0], &b[1], NULL, 0);
- DuplicateHandle(me, a[0], me, &h[0], 0, TRUE, flags);
- DuplicateHandle(me, b[1], me, &h[1], 0, TRUE, flags);
-
- (void) memset(&si, 0, sizeof(si));
- (void) memset(&pi, 0, sizeof(pi));
-
- /* XXX redirect CGI errors to the error log file */
- si.cb = sizeof(si);
- si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_HIDE;
- si.hStdOutput = si.hStdError = h[1];
- si.hStdInput = h[0];
-
- /* If CGI file is a script, try to read the interpreter line */
- if (c->ctx->cgi_interpreter == NULL) {
- if ((fp = fopen(prog, "r")) != NULL) {
- (void) fgets(line, sizeof(line), fp);
- if (memcmp(line, "#!", 2) != 0)
- line[2] = '\0';
- /* Trim whitespaces from interpreter name */
- for (p = &line[strlen(line) - 1]; p > line &&
- isspace(*p); p--)
- *p = '\0';
- (void) fclose(fp);
- }
- (void) my_snprintf(cmdline, sizeof(cmdline), "%s%s%s",
- line + 2, line[2] == '\0' ? "" : " ", prog);
- } else {
- (void) my_snprintf(cmdline, sizeof(cmdline), "%s %s",
- c->ctx->cgi_interpreter, prog);
- }
-
- (void) my_snprintf(line, sizeof(line), "%s", dir);
- fix_directory_separators(line);
- fix_directory_separators(cmdline);
-
- /*
- * Spawn reader & writer threads before we create CGI process.
- * Otherwise CGI process may die too quickly, loosing the data
- */
- spawn_stdio_thread(sock, b[0], stdinput, 0);
- spawn_stdio_thread(sock, a[1], stdoutput, c->rem.content_len);
-
- if (CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
- CREATE_NEW_PROCESS_GROUP, envblk, line, &si, &pi) == 0) {
- elog(E_LOG, c,"redirect: CreateProcess(%s): %d",cmdline,ERRNO);
- return (-1);
- } else {
- CloseHandle(h[0]);
- CloseHandle(h[1]);
- CloseHandle(pi.hThread);
- CloseHandle(pi.hProcess);
- }
-
- return (0);
-}
-
-#endif /* !NO_CGI */
diff --git a/cpukit/shttpd/compat_win32.h b/cpukit/shttpd/compat_win32.h
deleted file mode 100644
index b45b713048..0000000000
--- a/cpukit/shttpd/compat_win32.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2004-2007 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-/* Tip from Justin Maximilian, suppress errors from winsock2.h */
-#define _WINSOCKAPI_
-
-#include <windows.h>
-#include <winsock2.h>
-#include <commctrl.h>
-#include <winnls.h>
-#include <shlobj.h>
-#include <shellapi.h>
-
-#ifndef _WIN32_WCE
-
-#ifdef _MSC_VER /* pragmas not valid on MinGW */
-#pragma comment(lib,"ws2_32")
-#pragma comment(lib,"user32")
-#pragma comment(lib,"comctl32")
-#pragma comment(lib,"comdlg32")
-#pragma comment(lib,"shell32")
-#ifdef NO_GUI
-#pragma comment(linker,"/subsystem:console")
-#else
-#pragma comment(linker,"/subsystem:windows")
-#endif /* NO_GUI */
-#endif /* _MSC_VER */
-#include <process.h>
-#include <direct.h>
-#include <io.h>
-
-#else /* _WIN32_WCE */
-
-/* Windows CE-specific definitions */
-#define NO_CGI /* WinCE has no pipes */
-#define NO_GUI /* temporarily until it is fixed */
-#pragma comment(lib,"ws2")
-/* WinCE has both Unicode and ANSI versions of GetProcAddress */
-#undef GetProcAddress
-#define GetProcAddress GetProcAddressA
-#include "compat_wince.h"
-
-#endif /* _WIN32_WCE */
-
-#define ERRNO GetLastError()
-#define NO_SOCKLEN_T
-#define SSL_LIB L"libssl32.dll"
-#define DIRSEP '\\'
-#define IS_DIRSEP_CHAR(c) ((c) == '/' || (c) == '\\')
-#define O_NONBLOCK 0
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#define mkdir(x,y) _mkdir(x)
-#define dlopen(x,y) LoadLibraryW(x)
-#define dlsym(x,y) (void *) GetProcAddress(x,y)
-#define _POSIX_
-
-#ifdef __LCC__
-#include <stdint.h>
-#endif /* __LCC__ */
-
-#ifdef _MSC_VER /* MinGW already has these */
-typedef unsigned int uint32_t;
-typedef unsigned short uint16_t;
-typedef __int64 uint64_t;
-#define S_ISDIR(x) ((x) & _S_IFDIR)
-#endif /* _MSC_VER */
-
-/*
- * POSIX dirent interface
- */
-struct dirent {
- char d_name[FILENAME_MAX];
-};
-
-typedef struct DIR {
- HANDLE handle;
- WIN32_FIND_DATAW info;
- struct dirent result;
- char *name;
-} DIR;
-
-extern DIR *opendir(const char *name);
-extern int closedir(DIR *dir);
-extern struct dirent *readdir(DIR *dir);
diff --git a/cpukit/shttpd/compat_wince.c b/cpukit/shttpd/compat_wince.c
deleted file mode 100644
index edf8da21fa..0000000000
--- a/cpukit/shttpd/compat_wince.c
+++ /dev/null
@@ -1,1593 +0,0 @@
-/*
- vi:ts=8:sw=8:noet
- * Copyright (c) 2006 Luke Dunstan <infidel@users.sourceforge.net>
- * Partly based on code by David Kashtan, Validus Medical Systems
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * This file provides various functions that are available on desktop Windows
- * but not on Windows CE
- */
-
-#ifdef _MSC_VER
-/* Level 4 warnings caused by windows.h */
-#pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int
-#pragma warning(disable : 4115) // named type definition in parentheses
-#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
-#pragma warning(disable : 4514) // unreferenced inline function has been removed
-#pragma warning(disable : 4244) // conversion from 'int ' to 'unsigned short ', possible loss of data
-#pragma warning(disable : 4100) // unreferenced formal parameter
-#endif
-
-#include <windows.h>
-#include <stdlib.h>
-
-#include "compat_wince.h"
-
-
-static WCHAR *to_wide_string(LPCSTR pStr)
-{
- int nwide;
- WCHAR *buf;
-
- if(pStr == NULL)
- return NULL;
- nwide = MultiByteToWideChar(CP_ACP, 0, pStr, -1, NULL, 0);
- if(nwide == 0)
- return NULL;
- buf = malloc(nwide * sizeof(WCHAR));
- if(buf == NULL) {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return NULL;
- }
- if(MultiByteToWideChar(CP_ACP, 0, pStr, -1, buf, nwide) == 0) {
- free(buf);
- return NULL;
- }
- return buf;
-}
-
-FILE *fdopen(int handle, const char *mode)
-{
- WCHAR *wmode = to_wide_string(mode);
- FILE *result;
-
- if(wmode != NULL)
- result = _wfdopen((void *)handle, wmode);
- else
- result = NULL;
- free(wmode);
- return result;
-}
-
-/*
- * Time conversion constants
- */
-#define FT_EPOCH (116444736000000000i64)
-#define FT_TICKS (10000000i64)
-
- /*
- * Convert a FILETIME to a time_t
- */
-static time_t convert_FILETIME_to_time_t(FILETIME *File_Time)
-{
- __int64 Temp;
-
- /*
- * Convert the FILETIME structure to 100nSecs since 1601 (as a 64-bit value)
- */
- Temp = (((__int64)File_Time->dwHighDateTime) << 32) + (__int64)File_Time->dwLowDateTime;
- /*
- * Convert to seconds from 1970
- */
- return((time_t)((Temp - FT_EPOCH) / FT_TICKS));
-}
-
-/*
- * Convert a FILETIME to a tm structure
- */
-static struct tm *Convert_FILETIME_To_tm(FILETIME *File_Time)
-{
- SYSTEMTIME System_Time;
- static struct tm tm = {0};
- static const short Day_Of_Year_By_Month[12] = {(short)(0),
- (short)(31),
- (short)(31 + 28),
- (short)(31 + 28 + 31),
- (short)(31 + 28 + 31 + 30),
- (short)(31 + 28 + 31 + 30 + 31),
- (short)(31 + 28 + 31 + 30 + 31 + 30),
- (short)(31 + 28 + 31 + 30 + 31 + 30 + 31),
- (short)(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31),
- (short)(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30),
- (short)(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31),
- (short)(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30)};
-
-
- /*
- * Turn the FILETIME into a SYSTEMTIME
- */
- FileTimeToSystemTime(File_Time, &System_Time);
- /*
- * Use SYSTEMTIME to fill in the tm structure
- */
- tm.tm_sec = System_Time.wSecond;
- tm.tm_min = System_Time.wMinute;
- tm.tm_hour = System_Time.wHour;
- tm.tm_mday = System_Time.wDay;
- tm.tm_mon = System_Time.wMonth - 1;
- tm.tm_year = System_Time.wYear - 1900;
- tm.tm_wday = System_Time.wDayOfWeek;
- tm.tm_yday = Day_Of_Year_By_Month[tm.tm_mon] + tm.tm_mday - 1;
- if (tm.tm_mon >= 2) {
- /*
- * Check for leap year (every 4 years but not every 100 years but every 400 years)
- */
- if ((System_Time.wYear % 4) == 0) {
- /*
- * It Is a 4th year
- */
- if ((System_Time.wYear % 100) == 0) {
- /*
- * It is a 100th year
- */
- if ((System_Time.wYear % 400) == 0) {
- /*
- * It is a 400th year: It is a leap year
- */
- tm.tm_yday++;
- }
- } else {
- /*
- * It is not a 100th year: It is a leap year
- */
- tm.tm_yday++;
- }
- }
- }
- return(&tm);
-}
-
-/*
- * Convert a time_t to a FILETIME
- */
-static void Convert_time_t_To_FILETIME(time_t Time, FILETIME *File_Time)
-{
- __int64 Temp;
-
- /*
- * Use 64-bit calculation to convert seconds since 1970 to
- * 100nSecs since 1601
- */
- Temp = ((__int64)Time * FT_TICKS) + FT_EPOCH;
- /*
- * Put it into the FILETIME structure
- */
- File_Time->dwLowDateTime = (DWORD)Temp;
- File_Time->dwHighDateTime = (DWORD)(Temp >> 32);
-}
-
-/*
- * Convert a tm structure to a FILETIME
- */
-static FILETIME *Convert_tm_To_FILETIME(struct tm *tm)
-{
- SYSTEMTIME System_Time;
- static FILETIME File_Time = {0};
-
- /*
- * Use the tm structure to fill in a SYSTEM
- */
- System_Time.wYear = tm->tm_year + 1900;
- System_Time.wMonth = tm->tm_mon + 1;
- System_Time.wDayOfWeek = tm->tm_wday;
- System_Time.wDay = tm->tm_mday;
- System_Time.wHour = tm->tm_hour;
- System_Time.wMinute = tm->tm_min;
- System_Time.wSecond = tm->tm_sec;
- System_Time.wMilliseconds = 0;
- /*
- * Convert it to a FILETIME and return it
- */
- SystemTimeToFileTime(&System_Time, &File_Time);
- return(&File_Time);
-}
-
-
-/************************************************************************/
-/* */
-/* Errno emulation: There is no errno on Windows/CE and we need */
-/* to make it per-thread. So we have a function */
-/* that returns a pointer to the errno for the */
-/* current thread. */
-/* */
-/* If there is ONLY the main thread then we can */
-/* quickly return some static storage. */
-/* */
-/* If we have multiple threads running, we use */
-/* Thread-Local Storage to hold the pointer */
-/* */
-/************************************************************************/
-
-/*
- * Function pointer for returning errno pointer
- */
-static int *Initialize_Errno(void);
-int *(*__WinCE_Errno_Pointer_Function)(void) = Initialize_Errno;
-
-/*
- * Static errno storage for the main thread
- */
-static int Errno_Storage = 0;
-
-/*
- * Thread-Local storage slot for errno
- */
-static int TLS_Errno_Slot = 0xffffffff;
-
-/*
- * Number of threads we have running and critical section protection
- * for manipulating it
- */
-static int Number_Of_Threads = 0;
-static CRITICAL_SECTION Number_Of_Threads_Critical_Section;
-
-/*
- * For the main thread only -- return the errno pointer
- */
-static int *Get_Main_Thread_Errno(void)
-{
- return &Errno_Storage;
-}
-
-/*
- * When there is more than one thread -- return the errno pointer
- */
-static int *Get_Thread_Errno(void)
-{
- return (int *)TlsGetValue(TLS_Errno_Slot);
-}
-
-/*
- * Initialize a thread's errno
- */
-static void Initialize_Thread_Errno(int *Errno_Pointer)
-{
- /*
- * Make sure we have a slot
- */
- if (TLS_Errno_Slot == 0xffffffff) {
- /*
- * No: Get one
- */
- TLS_Errno_Slot = (int)TlsAlloc();
- if (TLS_Errno_Slot == 0xffffffff) ExitProcess(3);
- }
- /*
- * We can safely check for 0 threads, because
- * only the main thread will be initializing
- * at this point. Make sure the critical
- * section that protects the number of threads
- * is initialized
- */
- if (Number_Of_Threads == 0)
- InitializeCriticalSection(&Number_Of_Threads_Critical_Section);
- /*
- * Store the errno pointer
- */
- if (TlsSetValue(TLS_Errno_Slot, (LPVOID)Errno_Pointer) == 0) ExitProcess(3);
- /*
- * Bump the number of threads
- */
- EnterCriticalSection(&Number_Of_Threads_Critical_Section);
- Number_Of_Threads++;
- if (Number_Of_Threads > 1) {
- /*
- * We have threads other than the main thread:
- * Use thread-local storage
- */
- __WinCE_Errno_Pointer_Function = Get_Thread_Errno;
- }
- LeaveCriticalSection(&Number_Of_Threads_Critical_Section);
-}
-
-/*
- * Initialize errno emulation on Windows/CE (Main thread)
- */
-static int *Initialize_Errno(void)
-{
- /*
- * Initialize the main thread's errno in thread-local storage
- */
- Initialize_Thread_Errno(&Errno_Storage);
- /*
- * Set the errno function to be the one that returns the
- * main thread's errno
- */
- __WinCE_Errno_Pointer_Function = Get_Main_Thread_Errno;
- /*
- * Return the main thread's errno
- */
- return &Errno_Storage;
-}
-
-/*
- * Initialize errno emulation on Windows/CE (New thread)
- */
-void __WinCE_Errno_New_Thread(int *Errno_Pointer)
-{
- Initialize_Thread_Errno(Errno_Pointer);
-}
-
-/*
- * Note that a thread has exited
- */
-void __WinCE_Errno_Thread_Exit(void)
-{
- /*
- * Decrease the number of threads
- */
- EnterCriticalSection(&Number_Of_Threads_Critical_Section);
- Number_Of_Threads--;
- if (Number_Of_Threads <= 1) {
- /*
- * We only have the main thread
- */
- __WinCE_Errno_Pointer_Function = Get_Main_Thread_Errno;
- }
- LeaveCriticalSection(&Number_Of_Threads_Critical_Section);
-}
-
-
-char *
-strerror(int errnum)
-{
- return "(strerror not implemented)";
-}
-
-#define FT_EPOCH (116444736000000000i64)
-#define FT_TICKS (10000000i64)
-
-int
-_wstat(const WCHAR *path, struct _stat *buffer)
-{
- WIN32_FIND_DATA data;
- HANDLE handle;
- WCHAR *p;
-
- /* Fail if wildcard characters are specified */
- if (wcscspn(path, L"?*") != wcslen(path))
- return -1;
-
- handle = FindFirstFile(path, &data);
- if (handle == INVALID_HANDLE_VALUE) {
- errno = GetLastError();
- return -1;
- }
- FindClose(handle);
-
- /* Found: Convert the file times */
- buffer->st_mtime = convert_FILETIME_to_time_t(&data.ftLastWriteTime);
- if (data.ftLastAccessTime.dwLowDateTime || data.ftLastAccessTime.dwHighDateTime)
- buffer->st_atime = convert_FILETIME_to_time_t(&data.ftLastAccessTime);
- else
- buffer->st_atime = buffer->st_mtime;
- if (data.ftCreationTime.dwLowDateTime || data.ftCreationTime.dwHighDateTime)
- buffer->st_ctime = convert_FILETIME_to_time_t(&data.ftCreationTime);
- else
- buffer->st_ctime = buffer->st_mtime;
-
- /* Convert the file modes */
- buffer->st_mode = (unsigned short)((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? (S_IFDIR | S_IEXEC) : S_IFREG);
- buffer->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? S_IREAD : (S_IREAD | S_IWRITE);
- if((p = wcsrchr(path, L'.')) != NULL) {
- p++;
- if (_wcsicmp(p, L".exe") == 0)
- buffer->st_mode |= S_IEXEC;
- }
- buffer->st_mode |= (buffer->st_mode & 0700) >> 3;
- buffer->st_mode |= (buffer->st_mode & 0700) >> 6;
- /* Set the other information */
- buffer->st_nlink = 1;
- buffer->st_size = (unsigned long int)data.nFileSizeLow;
- buffer->st_uid = 0;
- buffer->st_gid = 0;
- buffer->st_ino = 0 /*data.dwOID ?*/;
- buffer->st_dev = 0;
-
- return 0; /* success */
-}
-
-/*
- * Helper function for cemodule -- do an fstat() operation on a Win32 File Handle
- */
-int
-_fstat(int handle, struct _stat *st)
-{
- BY_HANDLE_FILE_INFORMATION Data;
-
- /*
- * Get the file information
- */
- if (!GetFileInformationByHandle((HANDLE)handle, &Data)) {
- /*
- * Return error
- */
- errno = GetLastError();
- return(-1);
- }
- /*
- * Found: Convert the file times
- */
- st->st_mtime=(time_t)((*(__int64*)&Data.ftLastWriteTime-FT_EPOCH)/FT_TICKS);
- if(Data.ftLastAccessTime.dwLowDateTime || Data.ftLastAccessTime.dwHighDateTime)
- st->st_atime=(time_t)((*(__int64*)&Data.ftLastAccessTime-FT_EPOCH)/FT_TICKS);
- else
- st->st_atime=st->st_mtime ;
- if(Data.ftCreationTime.dwLowDateTime || Data.ftCreationTime.dwHighDateTime )
- st->st_ctime=(time_t)((*(__int64*)&Data.ftCreationTime-FT_EPOCH)/FT_TICKS);
- else
- st->st_ctime=st->st_mtime ;
- /*
- * Convert the file modes
- */
- st->st_mode = (unsigned short)((Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? (S_IFDIR | S_IEXEC) : S_IFREG);
- st->st_mode |= (Data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? S_IREAD : (S_IREAD | S_IWRITE);
- st->st_mode |= (st->st_mode & 0700) >> 3;
- st->st_mode |= (st->st_mode & 0700) >> 6;
- /*
- * Set the other information
- */
- st->st_nlink=1;
- st->st_size=(unsigned long int)Data.nFileSizeLow;
- st->st_uid=0;
- st->st_gid=0;
- st->st_ino=0;
- st->st_dev=0;
- /*
- * Return success
- */
- return(0);
-}
-
-int _wopen(const wchar_t *filename, int oflag, ...)
-{
- DWORD Access, ShareMode, CreationDisposition;
- HANDLE Handle;
- static int Modes[4] = {0, (GENERIC_READ | GENERIC_WRITE), GENERIC_READ, GENERIC_WRITE};
-
- /*
- * Calculate the CreateFile arguments
- */
- Access = Modes[oflag & O_MODE_MASK];
- ShareMode = (oflag & O_EXCL) ? 0 : (FILE_SHARE_READ | FILE_SHARE_WRITE);
- if (oflag & O_TRUNC)
- CreationDisposition = (oflag & O_CREAT) ? CREATE_ALWAYS : TRUNCATE_EXISTING;
- else
- CreationDisposition = (oflag & O_CREAT) ? CREATE_NEW : OPEN_EXISTING;
-
- Handle = CreateFileW(filename, Access, ShareMode, NULL, CreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);
-
- /*
- * Deal with errors
- */
- if (Handle == INVALID_HANDLE_VALUE) {
- errno = GetLastError();
- if ((errno == ERROR_ALREADY_EXISTS) || (errno == ERROR_FILE_EXISTS))
- errno = ERROR_ALREADY_EXISTS;
- return -1;
- }
- /*
- * Return the handle
- */
- return (int)Handle;
-}
-
-int
-_close(int handle)
-{
- if(CloseHandle((HANDLE)handle))
- return 0;
- errno = GetLastError();
- return -1;
-}
-
-int
-_write(int handle, const void *buffer, unsigned int count)
-{
- DWORD numwritten = 0;
- if(!WriteFile((HANDLE)handle, buffer, count, &numwritten, NULL)) {
- errno = GetLastError();
- return -1;
- }
- return numwritten;
-}
-
-int
-_read(int handle, void *buffer, unsigned int count)
-{
- DWORD numread = 0;
- if(!ReadFile((HANDLE)handle, buffer, count, &numread, NULL)) {
- errno = GetLastError();
- return -1;
- }
- return numread;
-}
-
-long
-_lseek(int handle, long offset, int origin)
-{
- DWORD dwMoveMethod;
- DWORD result;
-
- switch(origin) {
- default:
- errno = EINVAL;
- return -1L;
- case SEEK_SET:
- dwMoveMethod = FILE_BEGIN;
- break;
- case SEEK_CUR:
- dwMoveMethod = FILE_CURRENT;
- break;
- case SEEK_END:
- dwMoveMethod = FILE_END;
- break;
- }
- result = SetFilePointer((HANDLE)handle, offset, NULL, dwMoveMethod);
- if(result == 0xFFFFFFFF) {
- errno = GetLastError();
- return -1;
- }
- return (long)result;
-}
-
-int
-_wmkdir(const wchar_t *dirname)
-{
- if(!CreateDirectoryW(dirname, NULL)) {
- errno = GetLastError();
- return -1;
- }
- return 0;
-}
-
-int
-_wremove(const wchar_t *filename)
-{
- if(!DeleteFileW(filename)) {
- errno = GetLastError();
- return -1;
- }
- return 0;
-}
-
-int
-_wrename(const wchar_t *oldname, const wchar_t *newname)
-{
- if(!MoveFileW(oldname, newname)) {
- errno = GetLastError();
- return -1;
- }
- return 0;
-}
-
-wchar_t *
-_wgetcwd(wchar_t *buffer, int maxlen)
-{
- wchar_t *result;
- WCHAR wszPath[MAX_PATH + 1];
- WCHAR *p;
-
- if(!GetModuleFileNameW(NULL, wszPath, MAX_PATH + 1)) {
- errno = GetLastError();
- return NULL;
- }
- /* Remove the filename part of the path to leave the directory */
- p = wcsrchr(wszPath, L'\\');
- if(p)
- *p = L'\0';
-
- if(buffer == NULL)
- result = _wcsdup(wszPath);
- else if(wcslen(wszPath) + 1 > (size_t)maxlen) {
- result = NULL;
- errno = ERROR_INSUFFICIENT_BUFFER;
- } else {
- wcsncpy(buffer, wszPath, maxlen);
- buffer[maxlen - 1] = L'\0';
- result = buffer;
- }
- return result;
-}
-
-/*
- * The missing "C" runtime gmtime() function
- */
-struct tm *gmtime(const time_t *TimeP)
-{
- FILETIME File_Time;
-
- /*
- * Deal with null time pointer
- */
- if (!TimeP) return(NULL);
- /*
- * time_t -> FILETIME -> tm
- */
- Convert_time_t_To_FILETIME(*TimeP, &File_Time);
- return(Convert_FILETIME_To_tm(&File_Time));
-}
-
-/*
- * The missing "C" runtime localtime() function
- */
-struct tm *localtime(const time_t *TimeP)
-{
- FILETIME File_Time, Local_File_Time;
-
- /*
- * Deal with null time pointer
- */
- if (!TimeP) return(NULL);
- /*
- * time_t -> FILETIME -> Local FILETIME -> tm
- */
- Convert_time_t_To_FILETIME(*TimeP, &File_Time);
- FileTimeToLocalFileTime(&File_Time, &Local_File_Time);
- return(Convert_FILETIME_To_tm(&Local_File_Time));
-}
-
-/*
- * The missing "C" runtime mktime() function
- */
-time_t mktime(struct tm *tm)
-{
- FILETIME *Local_File_Time;
- FILETIME File_Time;
-
- /*
- * tm -> Local FILETIME -> FILETIME -> time_t
- */
- Local_File_Time = Convert_tm_To_FILETIME(tm);
- LocalFileTimeToFileTime(Local_File_Time, &File_Time);
- return(convert_FILETIME_to_time_t(&File_Time));
-}
-
-/*
- * Missing "C" runtime time() function
- */
-time_t time(time_t *TimeP)
-{
- SYSTEMTIME System_Time;
- FILETIME File_Time;
- time_t Result;
-
- /*
- * Get the current system time
- */
- GetSystemTime(&System_Time);
- /*
- * SYSTEMTIME -> FILETIME -> time_t
- */
- SystemTimeToFileTime(&System_Time, &File_Time);
- Result = convert_FILETIME_to_time_t(&File_Time);
- /*
- * Return the time_t
- */
- if (TimeP) *TimeP = Result;
- return(Result);
-}
-
-static char Standard_Name[32] = "GMT";
-static char Daylight_Name[32] = "GMT";
-char *tzname[2] = {Standard_Name, Daylight_Name};
-long timezone = 0;
-int daylight = 0;
-
-void tzset(void)
-{
- TIME_ZONE_INFORMATION Info;
- int Result;
-
- /*
- * Get our current timezone information
- */
- Result = GetTimeZoneInformation(&Info);
- switch(Result) {
- /*
- * We are on standard time
- */
- case TIME_ZONE_ID_STANDARD:
- daylight = 0;
- break;
- /*
- * We are on daylight savings time
- */
- case TIME_ZONE_ID_DAYLIGHT:
- daylight = 1;
- break;
- /*
- * We don't know the timezone information (leave it GMT)
- */
- default: return;
- }
- /*
- * Extract the timezone information
- */
- timezone = Info.Bias * 60;
- if (Info.StandardName[0])
- WideCharToMultiByte(CP_ACP, 0, Info.StandardName, -1, Standard_Name, sizeof(Standard_Name) - 1, NULL, NULL);
- if (Info.DaylightName[0])
- WideCharToMultiByte(CP_ACP, 0, Info.DaylightName, -1, Daylight_Name, sizeof(Daylight_Name) - 1, NULL, NULL);
-}
-
-/*** strftime() from newlib libc/time/strftime.c ***/
-
-/*
- * Sane snprintf(). Acts like snprintf(), but never return -1 or the
- * value bigger than supplied buffer.
- */
-static int
-Snprintf(char *buf, size_t buflen, const char *fmt, ...)
-{
- va_list ap;
- int n;
-
- if (buflen == 0)
- return (0);
-
- va_start(ap, fmt);
- n = _vsnprintf(buf, buflen, fmt, ap);
- va_end(ap);
-
- if (n < 0 || n > (int) buflen - 1) {
- n = buflen - 1;
- }
- buf[n] = '\0';
-
- return (n);
-}
-
-#define snprintf Snprintf
-
-/* from libc/include/_ansi.h */
-#define _CONST const
-#define _DEFUN(name, arglist, args) name(args)
-#define _AND ,
-/* from libc/time/local.h */
-#define TZ_LOCK
-#define TZ_UNLOCK
-#define _tzname tzname
-#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
-#define YEAR_BASE 1900
-#define SECSPERMIN 60L
-#define MINSPERHOUR 60L
-#define HOURSPERDAY 24L
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
-
-/*
- * strftime.c
- * Original Author: G. Haley
- * Additions from: Eric Blake
- *
- * Places characters into the array pointed to by s as controlled by the string
- * pointed to by format. If the total number of resulting characters including
- * the terminating null character is not more than maxsize, returns the number
- * of characters placed into the array pointed to by s (not including the
- * terminating null character); otherwise zero is returned and the contents of
- * the array indeterminate.
- */
-
-/*
-FUNCTION
-<<strftime>>---flexible calendar time formatter
-
-INDEX
- strftime
-
-ANSI_SYNOPSIS
- #include <time.h>
- size_t strftime(char *<[s]>, size_t <[maxsize]>,
- const char *<[format]>, const struct tm *<[timp]>);
-
-TRAD_SYNOPSIS
- #include <time.h>
- size_t strftime(<[s]>, <[maxsize]>, <[format]>, <[timp]>)
- char *<[s]>;
- size_t <[maxsize]>;
- char *<[format]>;
- struct tm *<[timp]>;
-
-DESCRIPTION
-<<strftime>> converts a <<struct tm>> representation of the time (at
-<[timp]>) into a null-terminated string, starting at <[s]> and occupying
-no more than <[maxsize]> characters.
-
-You control the format of the output using the string at <[format]>.
-<<*<[format]>>> can contain two kinds of specifications: text to be
-copied literally into the formatted string, and time conversion
-specifications. Time conversion specifications are two- and
-three-character sequences beginning with `<<%>>' (use `<<%%>>' to
-include a percent sign in the output). Each defined conversion
-specification selects only the specified field(s) of calendar time
-data from <<*<[timp]>>>, and converts it to a string in one of the
-following ways:
-
-o+
-o %a
-A three-letter abbreviation for the day of the week. [tm_wday]
-
-o %A
-The full name for the day of the week, one of `<<Sunday>>',
-`<<Monday>>', `<<Tuesday>>', `<<Wednesday>>', `<<Thursday>>',
-`<<Friday>>', or `<<Saturday>>'. [tm_wday]
-
-o %b
-A three-letter abbreviation for the month name. [tm_mon]
-
-o %B
-The full name of the month, one of `<<January>>', `<<February>>',
-`<<March>>', `<<April>>', `<<May>>', `<<June>>', `<<July>>',
-`<<August>>', `<<September>>', `<<October>>', `<<November>>',
-`<<December>>'. [tm_mon]
-
-o %c
-A string representing the complete date and time, in the form
-`<<"%a %b %e %H:%M:%S %Y">>' (example "Mon Apr 01 13:13:13
-1992"). [tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year, tm_wday]
-
-o %C
-The century, that is, the year divided by 100 then truncated. For
-4-digit years, the result is zero-padded and exactly two characters;
-but for other years, there may a negative sign or more digits. In
-this way, `<<%C%y>>' is equivalent to `<<%Y>>'. [tm_year]
-
-o %d
-The day of the month, formatted with two digits (from `<<01>>' to
-`<<31>>'). [tm_mday]
-
-o %D
-A string representing the date, in the form `<<"%m/%d/%y">>'.
-[tm_mday, tm_mon, tm_year]
-
-o %e
-The day of the month, formatted with leading space if single digit
-(from `<<1>>' to `<<31>>'). [tm_mday]
-
-o %E<<x>>
-In some locales, the E modifier selects alternative representations of
-certain modifiers <<x>>. But in the "C" locale supported by newlib,
-it is ignored, and treated as %<<x>>.
-
-o %F
-A string representing the ISO 8601:2000 date format, in the form
-`<<"%Y-%m-%d">>'. [tm_mday, tm_mon, tm_year]
-
-o %g
-The last two digits of the week-based year, see specifier %G (from
-`<<00>>' to `<<99>>'). [tm_year, tm_wday, tm_yday]
-
-o %G
-The week-based year. In the ISO 8601:2000 calendar, week 1 of the year
-includes January 4th, and begin on Mondays. Therefore, if January 1st,
-2nd, or 3rd falls on a Sunday, that day and earlier belong to the last
-week of the previous year; and if December 29th, 30th, or 31st falls
-on Monday, that day and later belong to week 1 of the next year. For
-consistency with %Y, it always has at least four characters.
-Example: "%G" for Saturday 2nd January 1999 gives "1998", and for
-Tuesday 30th December 1997 gives "1998". [tm_year, tm_wday, tm_yday]
-
-o %h
-A three-letter abbreviation for the month name (synonym for
-"%b"). [tm_mon]
-
-o %H
-The hour (on a 24-hour clock), formatted with two digits (from
-`<<00>>' to `<<23>>'). [tm_hour]
-
-o %I
-The hour (on a 12-hour clock), formatted with two digits (from
-`<<01>>' to `<<12>>'). [tm_hour]
-
-o %j
-The count of days in the year, formatted with three digits
-(from `<<001>>' to `<<366>>'). [tm_yday]
-
-o %k
-The hour (on a 24-hour clock), formatted with leading space if single
-digit (from `<<0>>' to `<<23>>'). Non-POSIX extension. [tm_hour]
-
-o %l
-The hour (on a 12-hour clock), formatted with leading space if single
-digit (from `<<1>>' to `<<12>>'). Non-POSIX extension. [tm_hour]
-
-o %m
-The month number, formatted with two digits (from `<<01>>' to `<<12>>').
-[tm_mon]
-
-o %M
-The minute, formatted with two digits (from `<<00>>' to `<<59>>'). [tm_min]
-
-o %n
-A newline character (`<<\n>>').
-
-o %O<<x>>
-In some locales, the O modifier selects alternative digit characters
-for certain modifiers <<x>>. But in the "C" locale supported by newlib, it
-is ignored, and treated as %<<x>>.
-
-o %p
-Either `<<AM>>' or `<<PM>>' as appropriate. [tm_hour]
-
-o %r
-The 12-hour time, to the second. Equivalent to "%I:%M:%S %p". [tm_sec,
-tm_min, tm_hour]
-
-o %R
-The 24-hour time, to the minute. Equivalent to "%H:%M". [tm_min, tm_hour]
-
-o %S
-The second, formatted with two digits (from `<<00>>' to `<<60>>'). The
-value 60 accounts for the occasional leap second. [tm_sec]
-
-o %t
-A tab character (`<<\t>>').
-
-o %T
-The 24-hour time, to the second. Equivalent to "%H:%M:%S". [tm_sec,
-tm_min, tm_hour]
-
-o %u
-The weekday as a number, 1-based from Monday (from `<<1>>' to
-`<<7>>'). [tm_wday]
-
-o %U
-The week number, where weeks start on Sunday, week 1 contains the first
-Sunday in a year, and earlier days are in week 0. Formatted with two
-digits (from `<<00>>' to `<<53>>'). See also <<%W>>. [tm_wday, tm_yday]
-
-o %V
-The week number, where weeks start on Monday, week 1 contains January 4th,
-and earlier days are in the previous year. Formatted with two digits
-(from `<<01>>' to `<<53>>'). See also <<%G>>. [tm_year, tm_wday, tm_yday]
-
-o %w
-The weekday as a number, 0-based from Sunday (from `<<0>>' to `<<6>>').
-[tm_wday]
-
-o %W
-The week number, where weeks start on Monday, week 1 contains the first
-Monday in a year, and earlier days are in week 0. Formatted with two
-digits (from `<<00>>' to `<<53>>'). [tm_wday, tm_yday]
-
-o %x
-A string representing the complete date, equivalent to "%m/%d/%y".
-[tm_mon, tm_mday, tm_year]
-
-o %X
-A string representing the full time of day (hours, minutes, and
-seconds), equivalent to "%H:%M:%S". [tm_sec, tm_min, tm_hour]
-
-o %y
-The last two digits of the year (from `<<00>>' to `<<99>>'). [tm_year]
-
-o %Y
-The full year, equivalent to <<%C%y>>. It will always have at least four
-characters, but may have more. The year is accurate even when tm_year
-added to the offset of 1900 overflows an int. [tm_year]
-
-o %z
-The offset from UTC. The format consists of a sign (negative is west of
-Greewich), two characters for hour, then two characters for minutes
-(-hhmm or +hhmm). If tm_isdst is negative, the offset is unknown and no
-output is generated; if it is zero, the offset is the standard offset for
-the current time zone; and if it is positive, the offset is the daylight
-savings offset for the current timezone. The offset is determined from
-the TZ environment variable, as if by calling tzset(). [tm_isdst]
-
-o %Z
-The time zone name. If tm_isdst is negative, no output is generated.
-Otherwise, the time zone name is based on the TZ environment variable,
-as if by calling tzset(). [tm_isdst]
-
-o %%
-A single character, `<<%>>'.
-o-
-
-RETURNS
-When the formatted time takes up no more than <[maxsize]> characters,
-the result is the length of the formatted string. Otherwise, if the
-formatting operation was abandoned due to lack of room, the result is
-<<0>>, and the string starting at <[s]> corresponds to just those
-parts of <<*<[format]>>> that could be completely filled in within the
-<[maxsize]> limit.
-
-PORTABILITY
-ANSI C requires <<strftime>>, but does not specify the contents of
-<<*<[s]>>> when the formatted string would require more than
-<[maxsize]> characters. Unrecognized specifiers and fields of
-<<timp>> that are out of range cause undefined results. Since some
-formats expand to 0 bytes, it is wise to set <<*<[s]>>> to a nonzero
-value beforehand to distinguish between failure and an empty string.
-This implementation does not support <<s>> being NULL, nor overlapping
-<<s>> and <<format>>.
-
-<<strftime>> requires no supporting OS subroutines.
-*/
-
-static _CONST int dname_len[7] =
-{6, 6, 7, 9, 8, 6, 8};
-
-static _CONST char *_CONST dname[7] =
-{"Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday"};
-
-static _CONST int mname_len[12] =
-{7, 8, 5, 5, 3, 4, 4, 6, 9, 7, 8, 8};
-
-static _CONST char *_CONST mname[12] =
-{"January", "February", "March", "April",
- "May", "June", "July", "August", "September", "October", "November",
- "December"};
-
-/* Using the tm_year, tm_wday, and tm_yday components of TIM_P, return
- -1, 0, or 1 as the adjustment to add to the year for the ISO week
- numbering used in "%g%G%V", avoiding overflow. */
-static int
-_DEFUN (iso_year_adjust, (tim_p),
- _CONST struct tm *tim_p)
-{
- /* Account for fact that tm_year==0 is year 1900. */
- int leap = isleap (tim_p->tm_year + (YEAR_BASE
- - (tim_p->tm_year < 0 ? 0 : 2000)));
-
- /* Pack the yday, wday, and leap year into a single int since there are so
- many disparate cases. */
-#define PACK(yd, wd, lp) (((yd) << 4) + (wd << 1) + (lp))
- switch (PACK (tim_p->tm_yday, tim_p->tm_wday, leap))
- {
- case PACK (0, 5, 0): /* Jan 1 is Fri, not leap. */
- case PACK (0, 6, 0): /* Jan 1 is Sat, not leap. */
- case PACK (0, 0, 0): /* Jan 1 is Sun, not leap. */
- case PACK (0, 5, 1): /* Jan 1 is Fri, leap year. */
- case PACK (0, 6, 1): /* Jan 1 is Sat, leap year. */
- case PACK (0, 0, 1): /* Jan 1 is Sun, leap year. */
- case PACK (1, 6, 0): /* Jan 2 is Sat, not leap. */
- case PACK (1, 0, 0): /* Jan 2 is Sun, not leap. */
- case PACK (1, 6, 1): /* Jan 2 is Sat, leap year. */
- case PACK (1, 0, 1): /* Jan 2 is Sun, leap year. */
- case PACK (2, 0, 0): /* Jan 3 is Sun, not leap. */
- case PACK (2, 0, 1): /* Jan 3 is Sun, leap year. */
- return -1; /* Belongs to last week of previous year. */
- case PACK (362, 1, 0): /* Dec 29 is Mon, not leap. */
- case PACK (363, 1, 1): /* Dec 29 is Mon, leap year. */
- case PACK (363, 1, 0): /* Dec 30 is Mon, not leap. */
- case PACK (363, 2, 0): /* Dec 30 is Tue, not leap. */
- case PACK (364, 1, 1): /* Dec 30 is Mon, leap year. */
- case PACK (364, 2, 1): /* Dec 30 is Tue, leap year. */
- case PACK (364, 1, 0): /* Dec 31 is Mon, not leap. */
- case PACK (364, 2, 0): /* Dec 31 is Tue, not leap. */
- case PACK (364, 3, 0): /* Dec 31 is Wed, not leap. */
- case PACK (365, 1, 1): /* Dec 31 is Mon, leap year. */
- case PACK (365, 2, 1): /* Dec 31 is Tue, leap year. */
- case PACK (365, 3, 1): /* Dec 31 is Wed, leap year. */
- return 1; /* Belongs to first week of next year. */
- }
- return 0; /* Belongs to specified year. */
-#undef PACK
-}
-
-size_t
-_DEFUN (strftime, (s, maxsize, format, tim_p),
- char *s _AND
- size_t maxsize _AND
- _CONST char *format _AND
- _CONST struct tm *tim_p)
-{
- size_t count = 0;
- int i;
-
- for (;;)
- {
- while (*format && *format != '%')
- {
- if (count < maxsize - 1)
- s[count++] = *format++;
- else
- return 0;
- }
-
- if (*format == '\0')
- break;
-
- format++;
- if (*format == 'E' || *format == 'O')
- format++;
-
- switch (*format)
- {
- case 'a':
- for (i = 0; i < 3; i++)
- {
- if (count < maxsize - 1)
- s[count++] =
- dname[tim_p->tm_wday][i];
- else
- return 0;
- }
- break;
- case 'A':
- for (i = 0; i < dname_len[tim_p->tm_wday]; i++)
- {
- if (count < maxsize - 1)
- s[count++] =
- dname[tim_p->tm_wday][i];
- else
- return 0;
- }
- break;
- case 'b':
- case 'h':
- for (i = 0; i < 3; i++)
- {
- if (count < maxsize - 1)
- s[count++] =
- mname[tim_p->tm_mon][i];
- else
- return 0;
- }
- break;
- case 'B':
- for (i = 0; i < mname_len[tim_p->tm_mon]; i++)
- {
- if (count < maxsize - 1)
- s[count++] =
- mname[tim_p->tm_mon][i];
- else
- return 0;
- }
- break;
- case 'c':
- {
- /* Length is not known because of %C%y, so recurse. */
- size_t adjust = strftime (&s[count], maxsize - count,
- "%a %b %e %H:%M:%S %C%y", tim_p);
- if (adjust > 0)
- count += adjust;
- else
- return 0;
- }
- break;
- case 'C':
- {
- /* Examples of (tm_year + YEAR_BASE) that show how %Y == %C%y
- with 32-bit int.
- %Y %C %y
- 2147485547 21474855 47
- 10000 100 00
- 9999 99 99
- 0999 09 99
- 0099 00 99
- 0001 00 01
- 0000 00 00
- -001 -0 01
- -099 -0 99
- -999 -9 99
- -1000 -10 00
- -10000 -100 00
- -2147481748 -21474817 48
-
- Be careful of both overflow and sign adjustment due to the
- asymmetric range of years.
- */
- int neg = tim_p->tm_year < -YEAR_BASE;
- int century = tim_p->tm_year >= 0
- ? tim_p->tm_year / 100 + YEAR_BASE / 100
- : abs (tim_p->tm_year + YEAR_BASE) / 100;
- count += snprintf (&s[count], maxsize - count, "%s%.*d",
- neg ? "-" : "", 2 - neg, century);
- if (count >= maxsize)
- return 0;
- }
- break;
- case 'd':
- case 'e':
- if (count < maxsize - 2)
- {
- sprintf (&s[count], *format == 'd' ? "%.2d" : "%2d",
- tim_p->tm_mday);
- count += 2;
- }
- else
- return 0;
- break;
- case 'D':
- case 'x':
- /* %m/%d/%y */
- if (count < maxsize - 8)
- {
- sprintf (&s[count], "%.2d/%.2d/%.2d",
- tim_p->tm_mon + 1, tim_p->tm_mday,
- tim_p->tm_year >= 0 ? tim_p->tm_year % 100
- : abs (tim_p->tm_year + YEAR_BASE) % 100);
- count += 8;
- }
- else
- return 0;
- break;
- case 'F':
- {
- /* Length is not known because of %C%y, so recurse. */
- size_t adjust = strftime (&s[count], maxsize - count,
- "%C%y-%m-%d", tim_p);
- if (adjust > 0)
- count += adjust;
- else
- return 0;
- }
- break;
- case 'g':
- if (count < maxsize - 2)
- {
- /* Be careful of both overflow and negative years, thanks to
- the asymmetric range of years. */
- int adjust = iso_year_adjust (tim_p);
- int year = tim_p->tm_year >= 0 ? tim_p->tm_year % 100
- : abs (tim_p->tm_year + YEAR_BASE) % 100;
- if (adjust < 0 && tim_p->tm_year <= -YEAR_BASE)
- adjust = 1;
- else if (adjust > 0 && tim_p->tm_year < -YEAR_BASE)
- adjust = -1;
- sprintf (&s[count], "%.2d",
- ((year + adjust) % 100 + 100) % 100);
- count += 2;
- }
- else
- return 0;
- break;
- case 'G':
- {
- /* See the comments for 'C' and 'Y'; this is a variable length
- field. Although there is no requirement for a minimum number
- of digits, we use 4 for consistency with 'Y'. */
- int neg = tim_p->tm_year < -YEAR_BASE;
- int adjust = iso_year_adjust (tim_p);
- int century = tim_p->tm_year >= 0
- ? tim_p->tm_year / 100 + YEAR_BASE / 100
- : abs (tim_p->tm_year + YEAR_BASE) / 100;
- int year = tim_p->tm_year >= 0 ? tim_p->tm_year % 100
- : abs (tim_p->tm_year + YEAR_BASE) % 100;
- if (adjust < 0 && tim_p->tm_year <= -YEAR_BASE)
- neg = adjust = 1;
- else if (adjust > 0 && neg)
- adjust = -1;
- year += adjust;
- if (year == -1)
- {
- year = 99;
- --century;
- }
- else if (year == 100)
- {
- year = 0;
- ++century;
- }
- count += snprintf (&s[count], maxsize - count, "%s%.*d%.2d",
- neg ? "-" : "", 2 - neg, century, year);
- if (count >= maxsize)
- return 0;
- }
- break;
- case 'H':
- case 'k':
- if (count < maxsize - 2)
- {
- sprintf (&s[count], *format == 'k' ? "%2d" : "%.2d",
- tim_p->tm_hour);
- count += 2;
- }
- else
- return 0;
- break;
- case 'I':
- case 'l':
- if (count < maxsize - 2)
- {
- if (tim_p->tm_hour == 0 ||
- tim_p->tm_hour == 12)
- {
- s[count++] = '1';
- s[count++] = '2';
- }
- else
- {
- sprintf (&s[count], *format == 'I' ? "%.2d" : "%2d",
- tim_p->tm_hour % 12);
- count += 2;
- }
- }
- else
- return 0;
- break;
- case 'j':
- if (count < maxsize - 3)
- {
- sprintf (&s[count], "%.3d",
- tim_p->tm_yday + 1);
- count += 3;
- }
- else
- return 0;
- break;
- case 'm':
- if (count < maxsize - 2)
- {
- sprintf (&s[count], "%.2d",
- tim_p->tm_mon + 1);
- count += 2;
- }
- else
- return 0;
- break;
- case 'M':
- if (count < maxsize - 2)
- {
- sprintf (&s[count], "%.2d",
- tim_p->tm_min);
- count += 2;
- }
- else
- return 0;
- break;
- case 'n':
- if (count < maxsize - 1)
- s[count++] = '\n';
- else
- return 0;
- break;
- case 'p':
- if (count < maxsize - 2)
- {
- if (tim_p->tm_hour < 12)
- s[count++] = 'A';
- else
- s[count++] = 'P';
-
- s[count++] = 'M';
- }
- else
- return 0;
- break;
- case 'r':
- if (count < maxsize - 11)
- {
- if (tim_p->tm_hour == 0 ||
- tim_p->tm_hour == 12)
- {
- s[count++] = '1';
- s[count++] = '2';
- }
- else
- {
- sprintf (&s[count], "%.2d", tim_p->tm_hour % 12);
- count += 2;
- }
- s[count++] = ':';
- sprintf (&s[count], "%.2d",
- tim_p->tm_min);
- count += 2;
- s[count++] = ':';
- sprintf (&s[count], "%.2d",
- tim_p->tm_sec);
- count += 2;
- s[count++] = ' ';
- if (tim_p->tm_hour < 12)
- s[count++] = 'A';
- else
- s[count++] = 'P';
-
- s[count++] = 'M';
- }
- else
- return 0;
- break;
- case 'R':
- if (count < maxsize - 5)
- {
- sprintf (&s[count], "%.2d:%.2d", tim_p->tm_hour, tim_p->tm_min);
- count += 5;
- }
- else
- return 0;
- break;
- case 'S':
- if (count < maxsize - 2)
- {
- sprintf (&s[count], "%.2d",
- tim_p->tm_sec);
- count += 2;
- }
- else
- return 0;
- break;
- case 't':
- if (count < maxsize - 1)
- s[count++] = '\t';
- else
- return 0;
- break;
- case 'T':
- case 'X':
- if (count < maxsize - 8)
- {
- sprintf (&s[count], "%.2d:%.2d:%.2d", tim_p->tm_hour,
- tim_p->tm_min, tim_p->tm_sec);
- count += 8;
- }
- else
- return 0;
- break;
- case 'u':
- if (count < maxsize - 1)
- {
- if (tim_p->tm_wday == 0)
- s[count++] = '7';
- else
- s[count++] = '0' + tim_p->tm_wday;
- }
- else
- return 0;
- break;
- case 'U':
- if (count < maxsize - 2)
- {
- sprintf (&s[count], "%.2d",
- (tim_p->tm_yday + 7 -
- tim_p->tm_wday) / 7);
- count += 2;
- }
- else
- return 0;
- break;
- case 'V':
- if (count < maxsize - 2)
- {
- int adjust = iso_year_adjust (tim_p);
- int wday = (tim_p->tm_wday) ? tim_p->tm_wday - 1 : 6;
- int week = (tim_p->tm_yday + 10 - wday) / 7;
- if (adjust > 0)
- week = 1;
- else if (adjust < 0)
- /* Previous year has 53 weeks if current year starts on
- Fri, and also if current year starts on Sat and
- previous year was leap year. */
- week = 52 + (4 >= (wday - tim_p->tm_yday
- - isleap (tim_p->tm_year
- + (YEAR_BASE - 1
- - (tim_p->tm_year < 0
- ? 0 : 2000)))));
- sprintf (&s[count], "%.2d", week);
- count += 2;
- }
- else
- return 0;
- break;
- case 'w':
- if (count < maxsize - 1)
- s[count++] = '0' + tim_p->tm_wday;
- else
- return 0;
- break;
- case 'W':
- if (count < maxsize - 2)
- {
- int wday = (tim_p->tm_wday) ? tim_p->tm_wday - 1 : 6;
- sprintf (&s[count], "%.2d",
- (tim_p->tm_yday + 7 - wday) / 7);
- count += 2;
- }
- else
- return 0;
- break;
- case 'y':
- if (count < maxsize - 2)
- {
- /* Be careful of both overflow and negative years, thanks to
- the asymmetric range of years. */
- int year = tim_p->tm_year >= 0 ? tim_p->tm_year % 100
- : abs (tim_p->tm_year + YEAR_BASE) % 100;
- sprintf (&s[count], "%.2d", year);
- count += 2;
- }
- else
- return 0;
- break;
- case 'Y':
- {
- /* Length is not known because of %C%y, so recurse. */
- size_t adjust = strftime (&s[count], maxsize - count,
- "%C%y", tim_p);
- if (adjust > 0)
- count += adjust;
- else
- return 0;
- }
- break;
- case 'z':
-#ifndef _WIN32_WCE
- if (tim_p->tm_isdst >= 0)
- {
- if (count < maxsize - 5)
- {
- long offset;
- __tzinfo_type *tz = __gettzinfo ();
- TZ_LOCK;
- /* The sign of this is exactly opposite the envvar TZ. We
- could directly use the global _timezone for tm_isdst==0,
- but have to use __tzrule for daylight savings. */
- offset = -tz->__tzrule[tim_p->tm_isdst > 0].offset;
- TZ_UNLOCK;
- sprintf (&s[count], "%+03ld%.2ld", offset / SECSPERHOUR,
- labs (offset / SECSPERMIN) % 60L);
- count += 5;
- }
- else
- return 0;
- }
- break;
-#endif
- case 'Z':
- if (tim_p->tm_isdst >= 0)
- {
- int size;
- TZ_LOCK;
- size = strlen(_tzname[tim_p->tm_isdst > 0]);
- for (i = 0; i < size; i++)
- {
- if (count < maxsize - 1)
- s[count++] = _tzname[tim_p->tm_isdst > 0][i];
- else
- {
- TZ_UNLOCK;
- return 0;
- }
- }
- TZ_UNLOCK;
- }
- break;
- case '%':
- if (count < maxsize - 1)
- s[count++] = '%';
- else
- return 0;
- break;
- }
- if (*format)
- format++;
- else
- break;
- }
- if (maxsize)
- s[count] = '\0';
-
- return count;
-}
diff --git a/cpukit/shttpd/compat_wince.h b/cpukit/shttpd/compat_wince.h
deleted file mode 100644
index 02f655707d..0000000000
--- a/cpukit/shttpd/compat_wince.h
+++ /dev/null
@@ -1,145 +0,0 @@
-
-#ifndef INCLUDE_WINCE_COMPAT_H
-#define INCLUDE_WINCE_COMPAT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*** ANSI C library ***/
-
-/* Missing ANSI C definitions */
-
-#define BUFSIZ 4096
-
-#define ENOMEM ERROR_NOT_ENOUGH_MEMORY
-#define EBADF ERROR_INVALID_HANDLE
-#define EINVAL ERROR_INVALID_PARAMETER
-#define ENOENT ERROR_FILE_NOT_FOUND
-#define ERANGE ERROR_INSUFFICIENT_BUFFER
-#define EINTR WSAEINTR
-
-/*
- * Because we need a per-thread errno, we define a function
- * pointer that we can call to return a pointer to the errno
- * for the current thread. Then we define a macro for errno
- * that dereferences this function's result.
- *
- * This makes it syntactically just like the "real" errno.
- *
- * Using a function pointer allows us to use a very fast
- * function when there are no threads running and a slower
- * function when there are multiple threads running.
- */
-void __WinCE_Errno_New_Thread(int *Errno_Pointer);
-void __WinCE_Errno_Thread_Exit(void);
-extern int *(*__WinCE_Errno_Pointer_Function)(void);
-
-#define errno (*(*__WinCE_Errno_Pointer_Function)())
-
-char *strerror(int errnum);
-
-struct tm {
- int tm_sec; /* seconds after the minute - [0,59] */
- int tm_min; /* minutes after the hour - [0,59] */
- int tm_hour; /* hours since midnight - [0,23] */
- int tm_mday; /* day of the month - [1,31] */
- int tm_mon; /* months since January - [0,11] */
- int tm_year; /* years since 1900 */
- int tm_wday; /* days since Sunday - [0,6] */
- int tm_yday; /* days since January 1 - [0,365] */
- int tm_isdst; /* daylight savings time flag */
-};
-
-struct tm *gmtime(const time_t *TimeP); /* for future use */
-struct tm *localtime(const time_t *TimeP);
-time_t mktime(struct tm *tm);
-time_t time(time_t *TimeP);
-
-size_t strftime(char *s, size_t maxsize, const char *format, const struct tm *tim_p);
-
-int _wrename(const wchar_t *oldname, const wchar_t *newname);
-int _wremove(const wchar_t *filename);
-
-/* Environment variables are not supported */
-#define getenv(x) (NULL)
-
-/* Redefine fileno so that it returns an integer */
-#undef fileno
-#define fileno(f) (int)_fileno(f)
-
-/* Signals are not supported */
-#define signal(num, handler) (0)
-#define SIGTERM 0
-#define SIGINT 0
-
-
-/*** POSIX API ***/
-
-/* Missing POSIX definitions */
-
-#define FILENAME_MAX MAX_PATH
-
-struct _stat {
- unsigned long st_size;
- unsigned long st_ino;
- int st_mode;
- unsigned long st_atime;
- unsigned long st_mtime;
- unsigned long st_ctime;
- unsigned short st_dev;
- unsigned short st_nlink;
- unsigned short st_uid;
- unsigned short st_gid;
-};
-
-#define S_IFMT 0170000
-#define S_IFDIR 0040000
-#define S_IFREG 0100000
-#define S_IEXEC 0000100
-#define S_IWRITE 0000200
-#define S_IREAD 0000400
-
-#define _S_IFDIR S_IFDIR /* MSVCRT compatibilit */
-
-int _fstat(int handle, struct _stat *buffer);
-int _wstat(const wchar_t *path, struct _stat *buffer);
-
-#define stat _stat /* NOTE: applies to _stat() and also struct _stat */
-#define fstat _fstat
-
-#define O_RDWR (1<<0)
-#define O_RDONLY (2<<0)
-#define O_WRONLY (3<<0)
-#define O_MODE_MASK (3<<0)
-#define O_TRUNC (1<<2)
-#define O_EXCL (1<<3)
-#define O_CREAT (1<<4)
-#define O_BINARY 0
-
-int _wopen(const wchar_t *filename, int oflag, ...);
-int _close(int handle);
-int _write(int handle, const void *buffer, unsigned int count);
-int _read(int handle, void *buffer, unsigned int count);
-long _lseek(int handle, long offset, int origin);
-
-#define close _close
-#define write _write
-#define read _read
-#define lseek _lseek
-
-/* WinCE has only a Unicode version of this function */
-FILE *fdopen(int handle, const char *mode);
-
-int _wmkdir(const wchar_t *dirname);
-
-/* WinCE has no concept of current directory so we return a constant path */
-wchar_t *_wgetcwd(wchar_t *buffer, int maxlen);
-
-#define freopen(path, mode, stream) assert(0)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* INCLUDE_WINCE_COMPAT_H */
diff --git a/cpukit/shttpd/config.c b/cpukit/shttpd/config.c
deleted file mode 100644
index e9240e549e..0000000000
--- a/cpukit/shttpd/config.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-#include <unistd.h>
-
-/*
- * Configuration parameters setters
- */
-static void
-set_int(struct shttpd_ctx *ctx, void *ptr, const char *string)
-{
- ctx = NULL; /* Unused */
- * (int *) ptr = atoi(string);
-}
-
-static void
-set_str(struct shttpd_ctx *ctx, void *ptr, const char *string)
-{
- ctx = NULL; /* Unused */
- * (char **) ptr = my_strdup(string);
-}
-
-static void
-set_log_file(struct shttpd_ctx *ctx, void *ptr, const char *string)
-{
- FILE **fp = ptr;
- ctx = NULL;
-
- if ((*fp = fopen(string, "a")) == NULL)
- elog(E_FATAL, NULL, "cannot open log file %s: %s",
- string, strerror(errno));
-}
-
-#ifndef NO_SSL
-/*
- * Dynamically load SSL library. Set up ctx->ssl_ctx pointer.
- */
-static void
-set_ssl(struct shttpd_ctx *ctx, void *arg, const char *pem)
-{
- SSL_CTX *CTX;
- void *lib;
- struct ssl_func *fp;
-
- arg = NULL; /* Unused */
-
- /* Load SSL library dynamically */
- if ((lib = dlopen(SSL_LIB, RTLD_LAZY)) == NULL)
- elog(E_FATAL, NULL, "set_ssl: cannot load %s", SSL_LIB);
-
- for (fp = ssl_sw; fp->name != NULL; fp++)
- if ((fp->ptr.v_void = dlsym(lib, fp->name)) == NULL)
- elog(E_FATAL, NULL,"set_ssl: cannot find %s", fp->name);
-
- /* Initialize SSL crap */
- SSL_library_init();
-
- if ((CTX = SSL_CTX_new(SSLv23_server_method())) == NULL)
- elog(E_FATAL, NULL, "SSL_CTX_new error");
- else if (SSL_CTX_use_certificate_file(CTX, pem, SSL_FILETYPE_PEM) == 0)
- elog(E_FATAL, NULL, "cannot open %s", pem);
- else if (SSL_CTX_use_PrivateKey_file(CTX, pem, SSL_FILETYPE_PEM) == 0)
- elog(E_FATAL, NULL, "cannot open %s", pem);
- ctx->ssl_ctx = CTX;
-}
-#endif /* NO_SSL */
-
-static void
-set_mime(struct shttpd_ctx *ctx, void *arg, const char *string)
-{
- arg = NULL;
- set_mime_types(ctx, string);
-}
-
-#define OFS(x) offsetof(struct shttpd_ctx, x)
-#define BOOL_OPT "0|1"
-const struct opt options[] = {
- {'d', "document_root", "Web root directory", set_str,
- OFS(document_root), "directory", NULL, OPT_DIR},
- {'i', "index_files", "Index files", set_str, OFS(index_files),
- "file_list", INDEX_FILES, OPT_ADVANCED},
- {'p', "listen_port", "Listening port", set_int,
- OFS(port), "port", HTTP_PORT, OPT_INT | OPT_ADVANCED},
- {'D', "list_directories", "Directory listing", set_int,
- OFS(dirlist), BOOL_OPT, "1", OPT_BOOL | OPT_ADVANCED},
-#ifndef NO_CGI
- {'c', "cgi_extensions", "CGI extensions", set_str,
- OFS(cgi_extensions), "ext_list", CGI_EXT, OPT_ADVANCED},
- {'C', "cgi_interpreter", "CGI interpreter", set_str,
- OFS(cgi_interpreter), "file", NULL, OPT_FILE | OPT_ADVANCED},
- {'V', "cgi_envvar", "CGI envir variables", set_str,
- OFS(cgi_vars), "X=Y,....", NULL, OPT_ADVANCED},
-#endif /* NO_CGI */
- {'N', "auth_realm", "Authentication realm", set_str,
- OFS(auth_realm), "auth_realm", REALM, OPT_ADVANCED},
- {'l', "access_log", "Access log file", set_log_file,
- OFS(access_log), "file", NULL, OPT_FILE | OPT_ADVANCED},
- {'e', "error_log", "Error log file", set_log_file,
- OFS(error_log), "file", NULL, OPT_FILE | OPT_ADVANCED},
- {'m', "mime_types", "Mime types file", set_mime,
- OFS(mime_file), "file", NULL, OPT_FILE | OPT_ADVANCED},
- {'P', "global_htpasswd", "Global passwords file", set_str,
- OFS(global_passwd_file), "file", NULL, OPT_FILE | OPT_ADVANCED},
-#ifndef NO_SSL
- {'s', "ssl_certificate", "SSL certificate file", set_ssl,
- OFS(ssl_ctx), "pem_file", NULL, OPT_FILE | OPT_ADVANCED},
-#endif /* NO_SSL */
- {'U', "put_auth", "PUT,DELETE auth file",set_str,
- OFS(put_auth_file), "file", NULL, OPT_FILE | OPT_ADVANCED},
- {'a', "aliases", "Aliases", set_str,
- OFS(aliases), "X=Y,...", NULL, OPT_ADVANCED},
- {'b', "io_buf_size", "IO buffer size", set_int, OFS(io_buf_size),
- "bytes", DFLT_IO_SIZ, OPT_INT | OPT_ADVANCED},
-#ifdef _WIN32
- {'S', "auto_start", "Autostart with Windows", set_int,
- OFS(auto_start), BOOL_OPT, "1", OPT_BOOL},
-#else
- {'I', "inetd_mode", "Inetd mode", set_int,
- OFS(inetd_mode), BOOL_OPT, NULL, OPT_BOOL },
- {'u', "runtime_uid", "Run as user", set_str,
- OFS(uid), "user_name", NULL, 0 },
-#endif /* _WIN32 */
- {0, NULL, NULL, NULL, 0, NULL, NULL, 0 }
-};
-
-static const struct opt *
-find_option(int sw, const char *name)
-{
- const struct opt *opt;
-
- for (opt = options; opt->sw != 0; opt++)
- if (sw == opt->sw || (name && strcmp(opt->name, name) == 0))
- return (opt);
-
- return (NULL);
-}
-
-static void
-set_option(const struct opt *opt, const char *val, char **tmpvars)
-{
- tmpvars += opt - options;
-
- if (*tmpvars != NULL)
- free(*tmpvars);
-
- *tmpvars = my_strdup(val);
-}
-
-/*
- * Initialize shttpd context
- */
-static void
-initialize_context(struct shttpd_ctx *ctx, const char *config_file,
- int argc, char *argv[], char **tmpvars)
-{
- char line[FILENAME_MAX], root[FILENAME_MAX],
- var[sizeof(line)], val[sizeof(line)];
- const char *arg;
- size_t i;
- const struct opt *opt;
- FILE *fp;
- struct tm *tm;
-
- current_time = time(NULL);
- tm = localtime(&current_time);
- tz_offset = 0;
-#if 0
- tm->tm_gmtoff - 3600 * (tm->tm_isdst > 0 ? 1 : 0);
-#endif
-
- (void) memset(ctx, 0, sizeof(*ctx));
-
- ctx->start_time = current_time;
- InitializeCriticalSection(&ctx->mutex);
-
- LL_INIT(&ctx->connections);
- LL_INIT(&ctx->mime_types);
- LL_INIT(&ctx->registered_uris);
- LL_INIT(&ctx->uri_auths);
- LL_INIT(&ctx->error_handlers);
-
- /* First pass: set the defaults */
- for (opt = options; opt->sw != 0; opt++)
- if (opt->def != NULL)
- tmpvars[opt - options] = my_strdup(opt->def);
-
- /* Second pass: load config file */
- if (config_file != NULL && (fp = fopen(config_file, "r")) != NULL) {
- DBG(("init_ctx: config file %s", config_file));
-
- /* Loop through the lines in config file */
- while (fgets(line, sizeof(line), fp) != NULL) {
-
- /* Skip comments and empty lines */
- if (line[0] == '#' || line[0] == '\n')
- continue;
-
- /* Trim trailing newline character */
- line[strlen(line) - 1] = '\0';
-
- if (sscanf(line, "%s %[^#\n]", var, val) != 2)
- elog(E_FATAL,0,"init_ctx: bad line: [%s]",line);
-
- if ((opt = find_option(0, var)) == NULL)
- elog(E_FATAL, NULL,
- "set_option: unknown variable [%s]", var);
- set_option(opt, val, tmpvars);
- }
- (void) fclose(fp);
- }
-
- /* Third pass: process command line args */
- for (i = 1; i < (size_t) argc && argv[i][0] == '-'; i++)
- if ((opt = find_option(argv[i][1], NULL)) != NULL) {
- arg = argv[i][2] ? &argv[i][2] : argv[++i];
-
- if (arg == NULL)
- usage(argv[0]);
-
- set_option(opt, arg, tmpvars);
- } else {
- usage(argv[0]);
- }
-
- /* Call setters functions now */
- for (i = 0; i < NELEMS(options); i++)
- if (tmpvars[i] != NULL) {
- options[i].setter(ctx,
- ((char *) ctx) + options[i].ofs, tmpvars[i]);
- free(tmpvars[i]);
- }
-
-#ifndef NO_SSL
- /* If SSL is wanted and port is not overridden, set it to 443 */
- if (ctx->port == atoi(HTTP_PORT) && ctx->ssl_ctx != NULL)
- ctx->port = 443;
-#endif /* NO_SSL */
-
- /* If document_root is not set, set it to current directory */
- if (ctx->document_root == NULL) {
- (void) my_getcwd(root, sizeof(root));
- ctx->document_root = my_strdup(root);
- }
-
-#ifdef _WIN32
- {WSADATA data; WSAStartup(MAKEWORD(2,2), &data);}
-#endif /* _WIN32 */
-
- DBG(("init_ctx: initialized context %p", (void *) ctx));
-}
-
-/*
- * Show usage string and exit.
- */
-void
-usage(const char *prog)
-{
- const struct opt *opt;
-
- (void) fprintf(stderr,
- "SHTTPD version %s (c) Sergey Lyubka\n"
- "usage: %s [OPTIONS] [config_file]\n"
- "Note: config line keyword for every option is in the "
- "round brackets\n", VERSION, prog);
-
-#if !defined(NO_AUTH)
- (void) fprintf(stderr, "-A <htpasswd_file> <realm> <user> <passwd>\n");
-#endif /* NO_AUTH */
-
- for (opt = options; opt->name != NULL; opt++)
- (void) fprintf(stderr, "-%c <%s>\t\t%s (%s)\n",
- opt->sw, opt->arg, opt->desc, opt->name);
-
- exit(EXIT_FAILURE);
-}
-
-struct shttpd_ctx *
-init_from_argc_argv(const char *config_file, int argc, char *argv[])
-{
- struct shttpd_ctx *ctx;
- char *tmpvars[NELEMS(options)];
- size_t i;
-
- /* Initialize all temporary holders to NULL */
- for (i = 0; i < NELEMS(tmpvars); i++)
- tmpvars[i] = NULL;
-
- if ((ctx = malloc(sizeof(*ctx))) != NULL)
- initialize_context(ctx, config_file, argc, argv, tmpvars);
-
- return (ctx);
-}
-
-struct shttpd_ctx *
-shttpd_init(const char *config_file, ...)
-{
- struct shttpd_ctx *ctx;
- va_list ap;
- const char *opt_name, *opt_value;
- char *tmpvars[NELEMS(options)];
- const struct opt *opt;
- size_t i;
-
- /* Initialize all temporary holders to NULL */
- for (i = 0; i < NELEMS(tmpvars); i++)
- tmpvars[i] = NULL;
-
- if ((ctx = malloc(sizeof(*ctx))) != NULL) {
-
- va_start(ap, config_file);
- while ((opt_name = va_arg(ap, const char *)) != NULL) {
- opt_value = va_arg(ap, const char *);
-
- if ((opt = find_option(0, opt_name)) == NULL)
- elog(E_FATAL, NULL, "shttpd_init: "
- "unknown variable [%s]", opt_name);
- set_option(opt, opt_value, tmpvars);
- }
- va_end(ap);
-
- initialize_context(ctx, config_file, 0, NULL, tmpvars);
- }
-
- return (ctx);
-}
diff --git a/cpukit/shttpd/defs.h b/cpukit/shttpd/defs.h
deleted file mode 100644
index 593dd8bbd0..0000000000
--- a/cpukit/shttpd/defs.h
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#ifndef DEFS_HEADER_DEFINED
-#define DEFS_HEADER_DEFINED
-
-#include "std_includes.h"
-#include "llist.h"
-#include "io.h"
-#include "shttpd.h"
-#include "md5.h"
-
-#define VERSION "1.37" /* Version */
-
-#ifndef CONFIG
-#define CONFIG "shttpd.conf" /* Configuration file */
-#endif /* CONFIG */
-
-#define HTPASSWD ".htpasswd" /* Passwords file name */
-#define DFLT_IO_SIZ "16384" /* Default max request size */
-#define HTTP_PORT "80" /* Default listening port */
-#define INDEX_FILES "index.html index.htm index.php index.cgi"
-#define CGI_EXT ".cgi .pl .php" /* Default CGI extensions */
-#define REALM "mydomain.com" /* Default authentication realm */
-#define DELIM_CHARS " ," /* Separators for lists */
-
-#define EXPIRE_TIME 3600 /* Expiration time, seconds */
-#define ENV_MAX 4096 /* Size of environment block */
-#define CGI_ENV_VARS 64 /* Maximum vars passed to CGI */
-#ifdef __rtems__
-#if defined(__SIZEOF_SIZE_T__) && (__SIZEOF_SIZE_T__ <= 2)
-/* HACK: Reduce the array size on targets with 16bit size_t */
-# if defined(__AVR__)
-/* FIXME: 1500 is sufficient to avoid compilation breakdown. */
-# define URI_MAX (32767-1500)
-# elif defined(__m32c__)
-/* FIXME: 1500 is sufficient to avoid compilation breakdown. */
-# define URI_MAX (32767-1500)
-# else
-/* Theoretically, this should work on all targets with 16bit size_t
- * In practice, it trips over other compiler limitations. */
-# define URI_MAX 32767
-# endif
-#else // __SIZEOF_SIZE_T__ > 2
-/* HACK: 32768 is 1 too much to fit into 16bit array indices. */
-#define URI_MAX 32767 /* Maximum URI size */
-#endif
-#else // __rtems__
-#define URI_MAX 32768 /* Maximum URI size */
-#endif
-#define MIN_REQ_LEN 16 /* "GET / HTTP/1.1\n\n" */
-
-#define NELEMS(ar) (sizeof(ar) / sizeof(ar[0]))
-
-#ifdef _DEBUG
-#define DBG(x) do { printf x ; putchar('\n'); fflush(stdout); } while (0)
-#else
-#define DBG(x)
-#endif /* DEBUG */
-
-#ifdef EMBEDDED
-#include "shttpd.h"
-#endif /* EMBEDDED */
-
-/*
- * Darwin prior to 7.0 and Win32 do not have socklen_t
- */
-#ifdef NO_SOCKLEN_T
-typedef int socklen_t;
-#endif /* NO_SOCKLEN_T */
-
-/*
- * For parsing. This guy represents a substring.
- */
-struct vec {
- const char *ptr;
- int len;
-};
-
-enum {METHOD_GET, METHOD_POST, METHOD_PUT, METHOD_DELETE, METHOD_HEAD};
-enum {HDR_DATE, HDR_INT, HDR_STRING}; /* HTTP header types */
-enum {E_FATAL = 1, E_LOG = 2}; /* Flags for elog() function */
-typedef unsigned long big_int_t; /* Type for Content-Length */
-
-/*
- * Unified socket address
- */
-struct usa {
- socklen_t len;
- union {
- struct sockaddr sa;
- struct sockaddr_in sin;
- } u;
-};
-
-/*
- * This thing is aimed to hold values of any type.
- * Used to store parsed headers' values.
- */
-union variant {
- char *v_str;
- int v_int;
- big_int_t v_big_int;
- time_t v_time;
- void (*v_func)(void);
- void *v_void;
- struct vec v_vec;
-};
-
-/*
- * This structure is used to hold mime types and associated file extensions.
- */
-struct mime_type {
- const char *ext;
- int ext_len;
- const char *mime;
-};
-
-struct mime_type_link {
- struct llhead link;
- char *ext;
- int ext_len;
- char *mime;
-};
-
-/*
- * This is used only in embedded configuration. This structure holds a
- * registered URI, associated callback function with callback data.
- * For non-embedded compilation shttpd_callback_t is not defined, so
- * we use union variant to keep the compiler silent.
- */
-struct registered_uri {
- struct llhead link;
- const char *uri;
- union variant callback;
- void *callback_data;
-};
-
-/*
- * User may bind a passwords file to any URI. This makes that URI password
- * protected: anybody who accesses that URI will be asked to authorize.
- */
-struct uri_auth {
- struct llhead link;
- const char *uri;
- const char *file_name;
- size_t uri_len;
-};
-
-/*
- * User may want to handle certain errors. This structure holds the
- * handlers for corresponding error codes.
- */
-struct error_handler {
- struct llhead link;
- int code;
- union variant callback;
- void *callback_data;
-};
-
-struct http_header {
- int len; /* Header name length */
- int type; /* Header type */
- size_t offset; /* Value placeholder */
- const char *name; /* Header name */
-};
-
-/*
- * This guy holds parsed HTTP headers
- */
-struct headers {
- union variant cl; /* Content-Length: */
- union variant ct; /* Content-Type: */
- union variant connection; /* Connection: */
- union variant ims; /* If-Modified-Since: */
- union variant user; /* Remote user name */
- union variant auth; /* Authorization */
- union variant useragent; /* User-Agent: */
- union variant referer; /* Referer: */
- union variant cookie; /* Cookie: */
- union variant location; /* Location: */
- union variant range; /* Range: */
- union variant status; /* Status: */
- union variant transenc; /* Transfer-Encoding: */
-};
-
-/* Must go after union variant definition */
-#include "ssl.h"
-
-/*
- * The communication channel
- */
-union channel {
- int fd; /* Regular static file */
- int sock; /* Connected socket */
- struct {
- int sock; /* XXX important. must be first */
- SSL *ssl; /* shttpd_poll() assumes that */
- } ssl; /* SSL-ed socket */
- struct {
- DIR *dirp;
- char *path;
- } dir; /* Opened directory */
- struct {
- void *state; /* For keeping state */
- union variant func; /* User callback function */
- void *data; /* User defined parameters */
- } emb; /* Embedded, user callback */
-};
-
-struct stream;
-
-/*
- * IO class descriptor (file, directory, socket, SSL, CGI, etc)
- * These classes are defined in io_*.c files.
- */
-struct io_class {
- const char *name;
- int (*read)(struct stream *, void *buf, size_t len);
- int (*write)(struct stream *, const void *buf, size_t len);
- void (*close)(struct stream *);
-};
-
-/*
- * Data exchange stream. It is backed by some communication channel:
- * opened file, socket, etc. The 'read' and 'write' methods are
- * determined by a communication channel.
- */
-struct stream {
- struct conn *conn;
- union channel chan; /* Descriptor */
- struct io io; /* IO buffer */
- const struct io_class *io_class; /* IO class */
- int nread_last; /* Bytes last read */
- int headers_len;
- big_int_t content_len;
- unsigned int flags;
-#define FLAG_HEADERS_PARSED 1
-#define FLAG_SSL_ACCEPTED 2
-#define FLAG_R 4 /* Can read in general */
-#define FLAG_W 8 /* Can write in general */
-#define FLAG_CLOSED 16
-#define FLAG_DONT_CLOSE 32
-#define FLAG_ALWAYS_READY 64 /* File, dir, user_func */
-};
-
-struct conn {
- struct llhead link; /* Connections chain */
- struct shttpd_ctx *ctx; /* Context this conn belongs to */
- struct usa sa; /* Remote socket address */
- time_t birth_time; /* Creation time */
- time_t expire_time; /* Expiration time */
-
- int status; /* Reply status code */
- int method; /* Request method */
- char *uri; /* Decoded URI */
- unsigned long major_version; /* Major HTTP version number */
- unsigned long minor_version; /* Minor HTTP version number */
- char *request; /* Request line */
- char *headers; /* Request headers */
- char *query; /* QUERY_STRING part of the URI */
- char *path_info; /* PATH_INFO thing */
- const char *mime_type; /* Mime type */
-
- struct headers ch; /* Parsed client headers */
-
- struct stream loc; /* Local stream */
- struct stream rem; /* Remote stream */
-};
-
-
-/*
- * SHTTPD context
- */
-struct shttpd_ctx {
- time_t start_time; /* Start time */
- int nactive; /* # of connections now */
- unsigned long nrequests; /* Requests made */
- uint64_t in, out; /* IN/OUT traffic counters */
-#if !defined(NO_SSL)
- SSL_CTX *ssl_ctx; /* SSL context */
-#endif /* NO_SSL */
- struct llhead connections; /* List of connections */
-
- struct llhead mime_types; /* Known mime types */
- struct llhead registered_uris;/* User urls */
- struct llhead uri_auths; /* User auth files */
- struct llhead error_handlers; /* Embedded error handlers */
-
- FILE *access_log; /* Access log stream */
- FILE *error_log; /* Error log stream */
- char *put_auth_file; /* PUT auth file */
- char *document_root; /* Document root */
- char *index_files; /* Index files */
- char *aliases; /* Aliases */
- char *mime_file; /* Mime types file */
-#if !defined(NO_CGI)
- char *cgi_vars; /* CGI environment variables */
- char *cgi_extensions; /* CGI extensions */
- char *cgi_interpreter; /* CGI script interpreter */
-#endif /* NO_CGI */
- char *auth_realm; /* Auth realm */
- char *global_passwd_file; /* Global passwords file */
- char *uid; /* Run as user */
- int port; /* Listening port */
- int dirlist; /* Directory listing */
- int gui; /* Show GUI flag */
- int auto_start; /* Start on OS boot */
- int io_buf_size; /* IO buffer size */
- int inetd_mode; /* Inetd flag */
-#if defined(_WIN32)
- CRITICAL_SECTION mutex; /* For MT case */
- HANDLE ev[2]; /* For thread synchronization */
-#elif defined(__rtems__)
- rtems_id mutex;
-#endif /* _WIN32 */
-};
-
-struct listener {
- struct llhead link;
- struct shttpd_ctx *ctx; /* Context that socket belongs */
- int sock; /* Listening socket */
-};
-
-/* Option setter function */
-typedef void (*optset_t)(struct shttpd_ctx *, void *ptr, const char *string);
-struct opt {
- int sw; /* Command line switch */
- const char *name; /* Option name in config file */
- const char *desc; /* Description */
- optset_t setter; /* Option setter function */
- size_t ofs; /* Value offset in context */
- const char *arg; /* Argument format */
- const char *def; /* Default option value */
- unsigned int flags; /* Flags */
-#define OPT_BOOL 1
-#define OPT_INT 2
-#define OPT_FILE 4
-#define OPT_DIR 8
-#define OPT_ADVANCED 16
-};
-
-extern const struct opt options[];
-
-/*
- * In SHTTPD, list of values are represented as comma or space separated
- * string. For example, list of CGI extensions can be represented as
- * ".cgi,.php,.pl", or ".cgi .php .pl". The macro that follows allows to
- * loop through the individual values in that list.
- * A "const char *" pointer and size_t variable must be passed to the macro.
- * Spaces or commas can be used as delimiters (macro DELIM_CHARS)
- */
-#define FOR_EACH_WORD_IN_LIST(s,len) \
- for (; s != NULL && (len = strcspn(s, DELIM_CHARS)) != 0; s += len + 1)
-
-/*
- * shttpd.c
- */
-extern time_t current_time; /* Current UTC time */
-extern int tz_offset; /* Offset from GMT time zone */
-extern const struct vec known_http_methods[];
-
-extern void stop_stream(struct stream *stream);
-extern void decode_url_encoded_string(const char *, int, char *dst, int);
-extern void send_server_error(struct conn *, int code, const char *reason);
-extern int get_headers_len(const char *buf, size_t buflen);
-extern void parse_headers(const char *s, int len, struct headers *parsed);
-
-/*
- * mime_type.c
- */
-extern const char *get_mime_type(struct shttpd_ctx *, const char *uri, int len);
-extern void set_mime_types(struct shttpd_ctx *ctx, const char *path);
-
-/*
- * config.c
- */
-extern void usage(const char *prog);
-extern struct shttpd_ctx *init_from_argc_argv(const char *, int, char *[]);
-
-/*
- * log.c
- */
-extern void elog(int flags, struct conn *c, const char *fmt, ...);
-extern void log_access(FILE *fp, const struct conn *c);
-
-/*
- * string.c
- */
-#ifndef HAVE_STRLCPY
-extern void my_strlcpy(register char *, register const char *, size_t);
-#else
-#include <string.h>
-#define my_strlcpy(d,s,l) strlcpy(d,s,l)
-#endif
-
-#ifndef HAVE_STRNCASECMP
-extern int my_strncasecmp(register const char *,
- register const char *, size_t);
-#else
-#ifdef __rtems__
-/* strncasecmp should be in strings.h, but newlib has it in <string.h> */
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-#define my_strncasecmp(s1,s2,l) strncasecmp(s1,s2,l)
-#endif
-
-#ifndef HAVE_STRNDUP
-extern char *my_strndup(const char *ptr, size_t len);
-#else
-#include <string.h>
-#define my_strndup(x,l) strndup((x),(l))
-#endif
-
-#ifndef HAVE_STRDUP
-extern char *my_strdup(const char *str);
-#else
-#include <string.h>
-#define my_strdup(x) strdup(x)
-#endif
-extern int my_snprintf(char *buf, size_t buflen, const char *fmt, ...);
-
-/*
- * compat_*.c
- */
-extern void set_close_on_exec(int fd);
-extern int set_non_blocking_mode(int fd);
-#if __rtems__
-#define my_stat stat
-#define my_open open
-#define my_remove remove
-#define my_rename rename
-#define my_mkdir mkdir
-#define my_getcwd getcwd
-#else
-extern int my_stat(const char *, struct stat *stp);
-extern int my_open(const char *, int flags, int mode);
-extern int my_remove(const char *);
-extern int my_rename(const char *, const char *);
-extern int my_mkdir(const char *, int);
-extern char * my_getcwd(char *, int);
-#endif
-extern int spawn_process(struct conn *c, const char *prog,
- char *envblk, char *envp[], int sock, const char *dir);
-
-/*
- * io_*.c
- */
-extern const struct io_class io_file;
-extern const struct io_class io_socket;
-extern const struct io_class io_ssl;
-extern const struct io_class io_cgi;
-extern const struct io_class io_dir;
-extern const struct io_class io_embedded;
-
-extern int put_dir(const char *path);
-extern void get_dir(struct conn *c);
-extern void get_file(struct conn *c, struct stat *stp);
-extern void ssl_handshake(struct stream *stream);
-extern void setup_embedded_stream(struct conn *, union variant, void *);
-extern struct registered_uri *is_registered_uri(struct shttpd_ctx *,
- const char *uri);
-
-/*
- * auth.c
- */
-extern int check_authorization(struct conn *c, const char *path);
-extern int is_authorized_for_put(struct conn *c);
-extern void send_authorization_request(struct conn *c);
-extern int edit_passwords(const char *fname, const char *domain,
- const char *user, const char *pass);
-
-/*
- * cgi.c
- */
-extern int is_cgi(struct shttpd_ctx *ctx, const char *path);
-extern int run_cgi(struct conn *c, const char *prog);
-extern void do_cgi(struct conn *c);
-
-#define CGI_REPLY "HTTP/1.1 OK\r\n"
-#define CGI_REPLY_LEN (sizeof(CGI_REPLY) - 1)
-
-#endif /* DEFS_HEADER_DEFINED */
diff --git a/cpukit/shttpd/io.h b/cpukit/shttpd/io.h
deleted file mode 100644
index d774cc2724..0000000000
--- a/cpukit/shttpd/io.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#ifndef IO_HEADER_INCLUDED
-#define IO_HEADER_INCLUDED
-
-#include <assert.h>
-#include <stddef.h>
-
-/*
- * I/O buffer descriptor
- */
-struct io {
- char *buf; /* IO Buffer */
- size_t size; /* IO buffer size */
- size_t head; /* Bytes read */
- size_t tail; /* Bytes written */
- size_t total; /* Total bytes read */
-};
-
-static __inline void
-io_clear(struct io *io)
-{
- assert(io->buf != NULL);
- assert(io->size > 0);
- io->total = io->tail = io->head = 0;
-}
-
-static __inline char *
-io_space(struct io *io)
-{
- assert(io->buf != NULL);
- assert(io->size > 0);
- assert(io->head <= io->size);
- return (io->buf + io->head);
-}
-
-static __inline char *
-io_data(struct io *io)
-{
- assert(io->buf != NULL);
- assert(io->size > 0);
- assert(io->tail <= io->size);
- return (io->buf + io->tail);
-}
-
-static __inline size_t
-io_space_len(const struct io *io)
-{
- assert(io->buf != NULL);
- assert(io->size > 0);
- assert(io->head <= io->size);
- return (io->size - io->head);
-}
-
-static __inline size_t
-io_data_len(const struct io *io)
-{
- assert(io->buf != NULL);
- assert(io->size > 0);
- assert(io->head <= io->size);
- assert(io->tail <= io->head);
- return (io->head - io->tail);
-}
-
-static __inline void
-io_inc_tail(struct io *io, size_t n)
-{
- assert(io->buf != NULL);
- assert(io->size > 0);
- assert(io->tail <= io->head);
- assert(io->head <= io->size);
- io->tail += n;
- assert(io->tail <= io->head);
- if (io->tail == io->head)
- io->head = io->tail = 0;
-}
-
-static __inline void
-io_inc_head(struct io *io, size_t n)
-{
- assert(io->buf != NULL);
- assert(io->size > 0);
- assert(io->tail <= io->head);
- io->head += n;
- io->total += n;
- assert(io->head <= io->size);
-}
-
-#endif /* IO_HEADER_INCLUDED */
diff --git a/cpukit/shttpd/io_cgi.c b/cpukit/shttpd/io_cgi.c
deleted file mode 100644
index 70ff2725fc..0000000000
--- a/cpukit/shttpd/io_cgi.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-#include <unistd.h>
-
-static int
-write_cgi(struct stream *stream, const void *buf, size_t len)
-{
- assert(stream->chan.sock != -1);
- assert(stream->flags & FLAG_W);
-
- return (send(stream->chan.sock, buf, len, 0));
-}
-
-static int
-read_cgi(struct stream *stream, void *buf, size_t len)
-{
- struct headers parsed;
- char status[4];
- int n;
-
- assert(stream->chan.sock != -1);
- assert(stream->flags & FLAG_R);
-
- stream->flags &= ~FLAG_DONT_CLOSE;
-
- n = recv(stream->chan.sock, buf, len, 0);
-
- if (stream->flags & FLAG_HEADERS_PARSED)
- return (n);
-
- if (n <= 0 && ERRNO != EWOULDBLOCK) {
- send_server_error(stream->conn, 500, "Error running CGI");
- return (n);
- }
-
- /*
- * CGI script may output Status: and Location: headers, which
- * may alter the status code. Buffer in headers, parse
- * them, send correct status code and then forward all data
- * from CGI script back to the remote end.
- * Reply line was alredy appended to the IO buffer in
- * decide_what_to_do(), with blank status code.
- */
-
- stream->flags |= FLAG_DONT_CLOSE;
- io_inc_head(&stream->io, n);
-
- stream->headers_len = get_headers_len(stream->io.buf, stream->io.head);
- if (stream->headers_len < 0) {
- stream->flags &= ~FLAG_DONT_CLOSE;
- send_server_error(stream->conn, 500, "Bad headers sent");
- elog(E_LOG, stream->conn, "CGI script sent invalid headers: "
- "[%.*s]", stream->io.head - CGI_REPLY_LEN,
- stream->io.buf + CGI_REPLY_LEN);
- return (0);
- }
-
- /*
- * If we did not received full headers yet, we must not send any
- * data read from the CGI back to the client. Suspend sending by
- * setting tail = head, which tells that there is no data in IO buffer
- */
-
- if (stream->headers_len == 0) {
- stream->io.tail = stream->io.head;
- return (0);
- }
-
- /* Received all headers. Set status code for the connection. */
- (void) memset(&parsed, 0, sizeof(parsed));
- parse_headers(stream->io.buf, stream->headers_len, &parsed);
- stream->content_len = parsed.cl.v_big_int;
- stream->conn->status = (int) parsed.status.v_big_int;
-
- /* If script outputs 'Location:' header, set status code to 302 */
- if (parsed.location.v_vec.len > 0)
- stream->conn->status = 302;
-
- /*
- * If script did not output neither 'Location:' nor 'Status' headers,
- * set the default status code 200, which means 'success'.
- */
- if (stream->conn->status == 0)
- stream->conn->status = 200;
-
- /* Append the status line to the beginning of the output */
- (void) my_snprintf(status, sizeof(status), "%3d", stream->conn->status);
- (void) memcpy(stream->io.buf + 9, status, 3);
- DBG(("read_cgi: content len %lu status %s",
- stream->content_len, status));
-
- /* Next time, pass output directly back to the client */
- assert((big_int_t) stream->headers_len <= stream->io.total);
- stream->io.total -= stream->headers_len;
- stream->io.tail = 0;
- stream->flags |= FLAG_HEADERS_PARSED;
-
- /* Return 0 because we've already shifted the head */
- return (0);
-}
-
-static void
-close_cgi(struct stream *stream)
-{
- assert(stream->chan.sock != -1);
- (void) closesocket(stream->chan.sock);
-}
-
-const struct io_class io_cgi = {
- "cgi",
- read_cgi,
- write_cgi,
- close_cgi
-};
diff --git a/cpukit/shttpd/io_dir.c b/cpukit/shttpd/io_dir.c
deleted file mode 100644
index ab331c7fc7..0000000000
--- a/cpukit/shttpd/io_dir.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-/*
- * For a given PUT path, create all intermediate subdirectories
- * for given path. Return 0 if the path itself is a directory,
- * or -1 on error, 1 if OK.
- */
-int
-put_dir(const char *path)
-{
- char buf[FILENAME_MAX];
- const char *s, *p;
- struct stat st;
- size_t len;
-
- for (s = p = path + 2; (p = strchr(s, '/')) != NULL; s = ++p) {
- len = p - path;
- assert(len < sizeof(buf));
- (void) memcpy(buf, path, len);
- buf[len] = '\0';
-
- /* Try to create intermediate directory */
- if (my_stat(buf, &st) == -1 && my_mkdir(buf, 0755) != 0)
- return (-1);
-
- /* Is path itself a directory ? */
- if (p[1] == '\0')
- return (0);
- }
-
- return (1);
-}
-
-static int
-read_dir(struct stream *stream, void *buf, size_t len)
-{
- struct dirent *dp = NULL;
- char file[FILENAME_MAX], line[FILENAME_MAX + 512],
- size[64], mod[64];
- struct stat st;
- struct conn *c = stream->conn;
- int n, nwritten = 0;
- const char *slash = "";
-
- assert(stream->chan.dir.dirp != NULL);
- assert(stream->conn->uri[0] != '\0');
-
- do {
- if (len < sizeof(line))
- break;
-
- if ((dp = readdir(stream->chan.dir.dirp)) == NULL) {
- stream->flags |= FLAG_CLOSED;
- break;
- }
- DBG(("read_dir: %s", dp->d_name));
-
- /* Do not show current dir and passwords file */
- if (strcmp(dp->d_name, ".") == 0 ||
- strcmp(dp->d_name, HTPASSWD) == 0)
- continue;
-
- (void) my_snprintf(file, sizeof(file),
- "%s%s%s", stream->chan.dir.path, slash, dp->d_name);
- (void) my_stat(file, &st);
- if (S_ISDIR(st.st_mode)) {
- my_snprintf(size,sizeof(size),"%s","&lt;DIR&gt;");
- } else {
- if (st.st_size < 1024)
- (void) my_snprintf(size, sizeof(size),
- "%lu", (unsigned long) st.st_size);
- else if (st.st_size < ((size_t)1024 * (size_t)1024))
- (void) my_snprintf(size, sizeof(size), "%luk",
- (unsigned long) (st.st_size >> 10) + 1);
- else
- (void) my_snprintf(size, sizeof(size),
- "%.1fM", (float) st.st_size / 1048576);
- }
- (void) strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M",
- localtime(&st.st_mtime));
-
- n = my_snprintf(line, sizeof(line),
- "<tr><td><a href=\"%s%s%s\">%s%s</a></td>"
- "<td>&nbsp;%s</td><td>&nbsp;&nbsp;%s</td></tr>\n",
- c->uri, slash, dp->d_name, dp->d_name,
- S_ISDIR(st.st_mode) ? "/" : "", mod, size);
- (void) memcpy(buf, line, n);
- buf = (char *) buf + n;
- nwritten += n;
- len -= n;
- } while (dp != NULL);
-
- return (nwritten);
-}
-
-static void
-close_dir(struct stream *stream)
-{
- assert(stream->chan.dir.dirp != NULL);
- assert(stream->chan.dir.path != NULL);
- (void) closedir(stream->chan.dir.dirp);
- free(stream->chan.dir.path);
-}
-
-void
-get_dir(struct conn *c)
-{
- if ((c->loc.chan.dir.dirp = opendir(c->loc.chan.dir.path)) == NULL) {
- (void) free(c->loc.chan.dir.path);
- send_server_error(c, 500, "Cannot open directory");
- } else {
- c->loc.io.head = my_snprintf(c->loc.io.buf, c->loc.io.size,
- "HTTP/1.1 200 OK\r\n"
- "Content-Type: text/html; charset=utf-8\r\n\r\n"
- "<html><head><title>Index of %s</title>"
- "<style>th {text-align: left;}</style></head>"
- "<body><h1>Index of %s</h1><pre><table cellpadding=\"0\">"
- "<tr><th>Name</th><th>Modified</th><th>Size</th></tr>"
- "<tr><td colspan=\"3\"><hr></td></tr>",
- c->uri, c->uri);
- io_clear(&c->rem.io);
- c->status = 200;
- c->loc.io_class = &io_dir;
- c->loc.flags |= FLAG_R | FLAG_ALWAYS_READY;
- }
-}
-
-const struct io_class io_dir = {
- "dir",
- read_dir,
- NULL,
- close_dir
-};
diff --git a/cpukit/shttpd/io_emb.c b/cpukit/shttpd/io_emb.c
deleted file mode 100644
index ea5d036a6c..0000000000
--- a/cpukit/shttpd/io_emb.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#if defined(EMBEDDED)
-const char *
-shttpd_version(void)
-{
- return (VERSION);
-}
-
-static void
-call_user(struct conn *c, struct shttpd_arg *arg, shttpd_callback_t func)
-{
- arg->priv = c;
- arg->state = c->loc.chan.emb.state;
- arg->out.buf = io_space(&c->loc.io);
- arg->out.len = io_space_len(&c->loc.io);
- arg->out.num_bytes = 0;
- arg->in.buf = io_data(&c->rem.io);;
- arg->in.len = io_data_len(&c->rem.io);
- arg->in.num_bytes = 0;
-
- func(arg);
-
- io_inc_head(&c->loc.io, arg->out.num_bytes);
- io_inc_tail(&c->rem.io, arg->in.num_bytes);
- c->loc.chan.emb.state = arg->state; /* Save state */
-
- /*
- * If callback finished output, that means it did all cleanup.
- * If the connection is terminated unexpectedly, we canna call
- * the callback via the stream close() method from disconnect.
- * However, if cleanup is already done, we set close() method to
- * NULL, to prevent the call from disconnect().
- */
-
- if (arg->flags & SHTTPD_END_OF_OUTPUT)
- c->loc.flags &= ~FLAG_DONT_CLOSE;
- else
- c->loc.flags |= FLAG_DONT_CLOSE;
-}
-
-static int
-do_embedded(struct stream *stream, void *buf, size_t len)
-{
- struct shttpd_arg arg;
- buf = NULL; len = 0; /* Squash warnings */
-
- arg.user_data = stream->conn->loc.chan.emb.data;
- arg.flags = 0;
-
- call_user(stream->conn, &arg, (shttpd_callback_t)
- stream->conn->loc.chan.emb.func.v_func);
-
- return (0);
-}
-
-static void
-close_embedded(struct stream *stream)
-{
- struct shttpd_arg arg;
- struct conn *c = stream->conn;
-
- arg.flags = SHTTPD_CONNECTION_ERROR;
- arg.user_data = c->loc.chan.emb.data;
-
- /*
- * Do not call the user function if SHTTPD_END_OF_OUTPUT was set,
- * i.e. the callback already terminated correctly
- */
- if (stream->flags & FLAG_DONT_CLOSE)
- call_user(stream->conn, &arg, (shttpd_callback_t)
- c->loc.chan.emb.func.v_func);
-}
-
-size_t
-shttpd_printf(struct shttpd_arg *arg, const char *fmt, ...)
-{
- struct conn *c = arg->priv;
- struct io *io = &c->loc.io;
- char *buf = io_space(io) + arg->out.num_bytes;
- int buflen, len = 0;
- va_list ap;
-
- assert(buf <= io->buf + io->size);
-
- if ((buflen = (io->buf + io->size) - buf) > 0) {
- va_start(ap, fmt);
- len = vsnprintf(buf, buflen, fmt, ap);
- va_end(ap);
-
- if (len < 0 || len > buflen)
- len = buflen;
- arg->out.num_bytes += len;
- }
-
- return (len);
-}
-
-const char *
-shttpd_get_header(struct shttpd_arg *arg, const char *header_name)
-{
- struct conn *c = arg->priv;
- char *p, *s, *e;
- size_t len;
-
- p = c->headers;
- e = c->request + c->rem.headers_len;
- len = strlen(header_name);
-
- while (p < e) {
- if ((s = strchr(p, '\n')) != NULL)
- s[s[-1] == '\r' ? -1 : 0] = '\0';
- if (my_strncasecmp(header_name, p, len) == 0)
- return (p + len + 2);
-
- p += strlen(p) + 1;
- }
-
- return (NULL);
-}
-
-const char *
-shttpd_get_env(struct shttpd_arg *arg, const char *env_name)
-{
- struct conn *c = arg->priv;
- struct vec *vec;
-
- if (strcmp(env_name, "REQUEST_METHOD") == 0) {
- return (known_http_methods[c->method].ptr);
- } else if (strcmp(env_name, "REQUEST_URI") == 0) {
- return (c->uri);
- } else if (strcmp(env_name, "QUERY_STRING") == 0) {
- return (c->query);
- } else if (strcmp(env_name, "REMOTE_USER") == 0) {
- vec = &c->ch.user.v_vec;
- if (vec->len > 0) {
- ((char *) vec->ptr)[vec->len] = '\0';
- return (vec->ptr);
- }
- } else if (strcmp(env_name, "REMOTE_ADDR") == 0) {
- return (inet_ntoa(c->sa.u.sin.sin_addr));/* FIXME NOT MT safe */
- }
-
- return (NULL);
-}
-
-void
-shttpd_get_http_version(struct shttpd_arg *arg, unsigned long *major, unsigned long *minor)
-{
- struct conn *c = arg->priv;
-
- *major = c->major_version;
- *minor = c->minor_version;
-}
-
-void
-shttpd_register_uri(struct shttpd_ctx *ctx,
- const char *uri, shttpd_callback_t callback, void *data)
-{
- struct registered_uri *e;
-
- if ((e = malloc(sizeof(*e))) != NULL) {
- e->uri = my_strdup(uri);
- e->callback.v_func = (void (*)(void)) callback;
- e->callback_data = data;
- LL_TAIL(&ctx->registered_uris, &e->link);
- }
-}
-
-#if 0
-struct shttpd_ctx *
-shttpd_init2(const char *config_file, char *names[], char *values[], size_t n)
-{
- size_t i;
-
- for (i = 0; i < n; i++)
- set_option(names[i], values[i]);
-
- return (init_ctx(config_file, 0, NULL));
-}
-#endif
-
-void
-shttpd_protect_uri(struct shttpd_ctx *ctx, const char *uri, const char *file)
-{
- struct uri_auth *auth;
-
- if ((auth = malloc(sizeof(*auth))) != NULL) {
- auth->uri = my_strdup(uri);
- auth->file_name = my_strdup(file);
- auth->uri_len = strlen(uri);
- LL_ADD(&ctx->uri_auths, &auth->link);
- }
-}
-
-int
-shttpd_get_var(const char *var, const char *buf, int buf_len,
- char *value, int value_len)
-{
- const char *p, *e, *s;
- size_t var_len;
-
- var_len = strlen(var);
- e = buf + buf_len - var_len;
-
- /* buf is "var1=val1&var2=val2...". Find variable first */
- for (p = buf; p < e; p++)
- if (!my_strncasecmp(var, p, var_len) && p[var_len] == '=') {
-
- /* Found. Shift to variable value */
- e = buf + buf_len;
- p += var_len + 1;
-
- /* Find where the value ends */
- if ((s = memchr(p, '&', e - p)) == NULL)
- s = e;
-
- /* Copy value into the buffer, decoding it */
- decode_url_encoded_string(p, s - p, value, value_len);
-
- return (1);
- }
-
- return (0);
-}
-
-static int
-match_regexp(const char *regexp, const char *text)
-{
- if (*regexp == '\0')
- return (*text == '\0');
-
- if (*regexp == '*')
- do {
- if (match_regexp(regexp + 1, text))
- return (1);
- } while (*text++ != '\0');
-
- if (*text != '\0' && *regexp == *text)
- return (match_regexp(regexp + 1, text + 1));
-
- return (0);
-}
-
-struct registered_uri *
-is_registered_uri(struct shttpd_ctx *ctx, const char *uri)
-{
- struct llhead *lp;
- struct registered_uri *reg_uri;
-
- LL_FOREACH(&ctx->registered_uris, lp) {
- reg_uri = LL_ENTRY(lp, struct registered_uri, link);
- if (match_regexp(reg_uri->uri, uri))
- return (reg_uri);
- }
-
- return (NULL);
-}
-
-void
-setup_embedded_stream(struct conn *c, union variant func, void *data)
-{
- c->loc.chan.emb.state = NULL;
- c->loc.chan.emb.func = func;
- c->loc.chan.emb.data = data;
- c->loc.io_class = &io_embedded;
- c->loc.flags |= FLAG_R | FLAG_W |FLAG_ALWAYS_READY;
-}
-
-void
-shttpd_handle_error(struct shttpd_ctx *ctx, int code,
- shttpd_callback_t func, void *data)
-{
- struct error_handler *e;
-
- if ((e = malloc(sizeof(*e))) != NULL) {
- e->code = code;
- e->callback.v_func = (void (*)(void)) func;
- e->callback_data = data;
- LL_TAIL(&ctx->error_handlers, &e->link);
- }
-}
-
-const struct io_class io_embedded = {
- "embedded",
- do_embedded,
- (int (*)(struct stream *, const void *, size_t)) do_embedded,
- close_embedded
-};
-
-#endif /* EMBEDDED */
diff --git a/cpukit/shttpd/io_file.c b/cpukit/shttpd/io_file.c
deleted file mode 100644
index fedc2df28c..0000000000
--- a/cpukit/shttpd/io_file.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-#include <unistd.h>
-
-static int
-write_file(struct stream *stream, const void *buf, size_t len)
-{
- struct stat st;
- struct stream *rem = &stream->conn->rem;
- int n, fd = stream->chan.fd;
-
- assert(fd != -1);
- n = write(fd, buf, len);
-
- DBG(("put_file(%p, %d): %d bytes", (void *) stream, len, n));
-
- if (n <= 0 || (rem->io.total >= (big_int_t) rem->headers_len)) {
- (void) fstat(fd, &st);
- stream->io.head = stream->headers_len =
- my_snprintf(stream->io.buf,
- stream->io.size, "HTTP/1.1 %d OK\r\n"
- "Content-Length: %lu\r\nConnection: close\r\n\r\n",
- stream->conn->status, st.st_size);
- stop_stream(stream);
- }
-
- return (n);
-}
-
-static int
-read_file(struct stream *stream, void *buf, size_t len)
-{
-#ifdef USE_SENDFILE
- struct iovec vec;
- struct sf_hdtr hd = {&vec, 1, NULL, 0}, *hdp = &hd;
- int sock, fd, n;
- size_t nbytes;
- off_t sent;
-
- sock = stream->conn->rem.chan.sock;
- fd = stream->chan.fd;
-
- /* If this is the first call for this file, send the headers */
- vec.iov_base = stream->io.buf;
- vec.iov_len = stream->headers_len;
- if (stream->io.total > 0)
- hdp = NULL;
-
- nbytes = stream->content_len - stream->io.total;
- n = sendfile(fd, sock, lseek(fd, 0, SEEK_CUR), nbytes, hdp, &sent, 0);
-
- if (n == -1 && ERRNO != EAGAIN) {
- stream->flags &= ~FLAG_DONT_CLOSE;
- return (n);
- }
-
- stream->conn->ctx->out += sent;
-
- /* If we have sent the HTTP headers in this turn, clear them off */
- if (stream->io.total == 0) {
- assert(sent >= stream->headers_len);
- sent -= stream->headers_len;
- io_clear(&stream->io);
- }
-
- (void) lseek(fd, sent, SEEK_CUR);
- stream->io.total += sent;
- stream->flags |= FLAG_DONT_CLOSE;
-
- return (0);
-#endif /* USE_SENDFILE */
-
- assert(stream->chan.fd != -1);
- return (read(stream->chan.fd, buf, len));
-}
-
-static void
-close_file(struct stream *stream)
-{
- assert(stream->chan.fd != -1);
- (void) close(stream->chan.fd);
-}
-
-void
-get_file(struct conn *c, struct stat *stp)
-{
- char date[64], lm[64], etag[64], range[64] = "";
- size_t n, status = 200;
- unsigned long r1, r2;
- const char *fmt = "%a, %d %b %Y %H:%M:%S GMT", *msg = "OK";
- big_int_t cl; /* Content-Length */
-
- if (c->mime_type == NULL)
- c->mime_type = get_mime_type(c->ctx, c->uri, strlen(c->uri));
- cl = (big_int_t) stp->st_size;
-
- /* If Range: header specified, act accordingly */
- if (c->ch.range.v_vec.len > 0 &&
- (n = sscanf(c->ch.range.v_vec.ptr,"bytes=%lu-%lu",&r1, &r2)) > 0) {
- status = 206;
- (void) lseek(c->loc.chan.fd, r1, SEEK_SET);
- cl = n == 2 ? r2 - r1 + 1: cl - r1;
- (void) my_snprintf(range, sizeof(range),
- "Content-Range: bytes %lu-%lu/%lu\r\n",
- r1, r1 + cl - 1, (unsigned long) stp->st_size);
- msg = "Partial Content";
- }
-
- /* Prepare Etag, Date, Last-Modified headers */
- (void) strftime(date, sizeof(date), fmt, localtime(&current_time));
- (void) strftime(lm, sizeof(lm), fmt, localtime(&stp->st_mtime));
- (void) my_snprintf(etag, sizeof(etag), "%lx.%lx",
- (unsigned long) stp->st_mtime, (unsigned long) stp->st_size);
-
- /*
- * We do not do io_inc_head here, because it will increase 'total'
- * member in io. We want 'total' to be equal to the content size,
- * and exclude the headers length from it.
- */
- c->loc.io.head = c->loc.headers_len = my_snprintf(c->loc.io.buf,
- c->loc.io.size,
- "HTTP/1.1 %d %s\r\n"
- "Date: %s\r\n"
- "Last-Modified: %s\r\n"
- "Etag: \"%s\"\r\n"
- "Content-Type: %s\r\n"
- "Content-Length: %lu\r\n"
- "Connection: close\r\n"
- "%s\r\n",
- status, msg, date, lm, etag, c->mime_type, cl, range);
-
- c->status = status;
- c->loc.content_len = cl;
- c->loc.io_class = &io_file;
- c->loc.flags |= FLAG_R | FLAG_ALWAYS_READY;
-
- if (c->method == METHOD_HEAD)
- stop_stream(&c->loc);
-}
-
-const struct io_class io_file = {
- "file",
- read_file,
- write_file,
- close_file
-};
diff --git a/cpukit/shttpd/io_socket.c b/cpukit/shttpd/io_socket.c
deleted file mode 100644
index 151419af51..0000000000
--- a/cpukit/shttpd/io_socket.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-#include <unistd.h>
-
-static int
-read_socket(struct stream *stream, void *buf, size_t len)
-{
- assert(stream->chan.sock != -1);
- return (recv(stream->chan.sock, buf, len, 0));
-}
-
-static int
-write_socket(struct stream *stream, const void *buf, size_t len)
-{
- assert(stream->chan.sock != -1);
- return (send(stream->chan.sock, buf, len, 0));
-}
-
-static void
-close_socket(struct stream *stream)
-{
- assert(stream->chan.sock != -1);
- (void) closesocket(stream->chan.sock);
-}
-
-const struct io_class io_socket = {
- "socket",
- read_socket,
- write_socket,
- close_socket
-};
diff --git a/cpukit/shttpd/io_ssl.c b/cpukit/shttpd/io_ssl.c
deleted file mode 100644
index 753257fd8d..0000000000
--- a/cpukit/shttpd/io_ssl.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-#if !defined(NO_SSL)
-struct ssl_func ssl_sw[] = {
- {"SSL_free", {0}},
- {"SSL_accept", {0}},
- {"SSL_connect", {0}},
- {"SSL_read", {0}},
- {"SSL_write", {0}},
- {"SSL_get_error", {0}},
- {"SSL_set_fd", {0}},
- {"SSL_new", {0}},
- {"SSL_CTX_new", {0}},
- {"SSLv23_server_method", {0}},
- {"SSL_library_init", {0}},
- {"SSL_CTX_use_PrivateKey_file", {0}},
- {"SSL_CTX_use_certificate_file",{0}},
- {NULL, {0}}
-};
-
-void
-ssl_handshake(struct stream *stream)
-{
- int n;
-
- if ((n = SSL_accept(stream->chan.ssl.ssl)) == 0) {
- n = SSL_get_error(stream->chan.ssl.ssl, n);
- if (n != SSL_ERROR_WANT_READ && n != SSL_ERROR_WANT_WRITE)
- stream->flags |= FLAG_CLOSED;
- elog(E_LOG, stream->conn, "SSL_accept error %d", n);
- } else {
- DBG(("handshake: SSL accepted"));
- stream->flags |= FLAG_SSL_ACCEPTED;
- }
-}
-
-static int
-read_ssl(struct stream *stream, void *buf, size_t len)
-{
- int nread = 0;
-
- assert(stream->chan.ssl.ssl != NULL);
-
- if (!(stream->flags & FLAG_SSL_ACCEPTED))
- ssl_handshake(stream);
-
- if (stream->flags & FLAG_SSL_ACCEPTED)
- nread = SSL_read(stream->chan.ssl.ssl, buf, len);
-
- return (nread);
-}
-
-static int
-write_ssl(struct stream *stream, const void *buf, size_t len)
-{
- assert(stream->chan.ssl.ssl != NULL);
- return (SSL_write(stream->chan.ssl.ssl, buf, len));
-}
-
-static void
-close_ssl(struct stream *stream)
-{
- assert(stream->chan.ssl.sock != -1);
- assert(stream->chan.ssl.ssl != NULL);
- (void) closesocket(stream->chan.ssl.sock);
- SSL_free(stream->chan.ssl.ssl);
-}
-
-const struct io_class io_ssl = {
- "ssl",
- read_ssl,
- write_ssl,
- close_ssl
-};
-#endif /* !NO_SSL */
diff --git a/cpukit/shttpd/llist.h b/cpukit/shttpd/llist.h
deleted file mode 100644
index 04e79bba12..0000000000
--- a/cpukit/shttpd/llist.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#ifndef LLIST_HEADER_INCLUDED
-#define LLIST_HEADER_INCLUDED
-
-/*
- * Linked list macros.
- */
-struct llhead {
- struct llhead *prev;
- struct llhead *next;
-};
-
-#define LL_INIT(N) ((N)->next = (N)->prev = (N))
-
-#define LL_HEAD(H) struct llhead H = { &H, &H }
-
-#define LL_ENTRY(P,T,N) ((T *)((char *)(P) - offsetof(T, N)))
-
-#define LL_ADD(H, N) \
- do { \
- ((H)->next)->prev = (N); \
- (N)->next = ((H)->next); \
- (N)->prev = (H); \
- (H)->next = (N); \
- } while (0)
-
-#define LL_TAIL(H, N) \
- do { \
- ((H)->prev)->next = (N); \
- (N)->prev = ((H)->prev); \
- (N)->next = (H); \
- (H)->prev = (N); \
- } while (0)
-
-#define LL_DEL(N) \
- do { \
- ((N)->next)->prev = ((N)->prev); \
- ((N)->prev)->next = ((N)->next); \
- LL_INIT(N); \
- } while (0)
-
-#define LL_EMPTY(N) ((N)->next == (N))
-
-#define LL_FOREACH(H,N) for (N = (H)->next; N != (H); N = (N)->next)
-
-#define LL_FOREACH_SAFE(H,N,T) \
- for (N = (H)->next, T = (N)->next; N != (H); \
- N = (T), T = (N)->next)
-
-#endif /* LLIST_HEADER_INCLUDED */
diff --git a/cpukit/shttpd/log.c b/cpukit/shttpd/log.c
deleted file mode 100644
index 4786daec1e..0000000000
--- a/cpukit/shttpd/log.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-/*
- * Log function
- */
-void
-elog(int flags, struct conn *c, const char *fmt, ...)
-{
- char date[64], buf[URI_MAX];
- int len;
- FILE *fp = c == NULL ? NULL : c->ctx->error_log;
- va_list ap;
-
- /* Print to stderr */
- if (c == NULL || c->ctx->inetd_mode == 0) {
- va_start(ap, fmt);
- (void) vfprintf(stderr, fmt, ap);
- (void) fputc('\n', stderr);
- va_end(ap);
- }
-
- strftime(date, sizeof(date), "%a %b %d %H:%M:%S %Y",
- localtime(&current_time));
-
- len = my_snprintf(buf, sizeof(buf),
- "[%s] [error] [client %s] \"%s\" ",
- date, c ? inet_ntoa(c->sa.u.sin.sin_addr) : "-",
- c && c->request ? c->request : "-");
-
- va_start(ap, fmt);
- (void) vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
- va_end(ap);
-
- buf[sizeof(buf) - 1] = '\0';
-
- if (fp != NULL && (flags & (E_FATAL | E_LOG))) {
- (void) fprintf(fp, "%s\n", buf);
- (void) fflush(fp);
- }
-
-#if defined(_WIN32) && !defined(NO_GUI)
- {
- extern HWND hLog;
-
- if (hLog != NULL)
- SendMessage(hLog, WM_APP, 0, (LPARAM) buf);
- }
-#endif /* _WIN32 */
-
- if (flags & E_FATAL)
- exit(EXIT_FAILURE);
-}
-
-/*
- * HACK: m68k-gcc <= 4.2.1 ICEs on the snprintf below for some
- * coldfire variants for yet unknown reasons.
- * C.f.: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32307
-
- * T.S, 2008/3/25 -- 4.2.3 still has this problem
- */
-#if defined(__GNUC__) && \
- ( (__GNUC__ < 4 ) || \
- ( (__GNUC__ == 4 ) && (__GNUC_MINOR__ < 2 ) ) || \
- ( (__GNUC__ == 4 ) && (__GNUC_MINOR__ == 2 ) && (__GNUC_PATCHLEVEL__ <= 3 ) ) )
-#if defined(__mcoldfire__)
-#define SPLIT_SNPRINTF 1
-#endif /* __mcoldfire__ */
-#endif /* __GNUC__ */
-
-void
-log_access(FILE *fp, const struct conn *c)
-{
- static const struct vec dash = {"-", 1};
-
- const struct vec *user = &c->ch.user.v_vec;
- const struct vec *referer = &c->ch.referer.v_vec;
- const struct vec *user_agent = &c->ch.useragent.v_vec;
- char date[64], buf[URI_MAX], *q1 = "\"", *q2 = "\"";
-
- if (user->len == 0)
- user = &dash;
-
- if (referer->len == 0) {
- referer = &dash;
- q1 = "";
- }
-
- if (user_agent->len == 0) {
- user_agent = &dash;
- q2 = "";
- }
-
- (void) strftime(date, sizeof(date), "%d/%b/%Y:%H:%M:%S",
- localtime(&current_time));
-
-#if SPLIT_SNPRINTF
- {
- int num;
- num = my_snprintf(buf, sizeof(buf),
- "%s - %.*s [%s %+05d] \"%s\" %d %lu",
- inet_ntoa(c->sa.u.sin.sin_addr), user->len, user->ptr,
- date, tz_offset, c->request ? c->request : "-",
- c->status, c->loc.io.total );
- my_snprintf(&buf[num], sizeof(buf)-num, " %s%.*s%s" " %s%.*s%s",
- q1, referer->len, referer->ptr, q1,
- q2, user_agent->len, user_agent->ptr, q2);
- }
-#else
- (void) my_snprintf(buf, sizeof(buf),
- "%s - %.*s [%s %+05d] \"%s\" %d %lu %s%.*s%s %s%.*s%s",
- inet_ntoa(c->sa.u.sin.sin_addr), user->len, user->ptr,
- date, tz_offset, c->request ? c->request : "-",
- c->status, (unsigned long) c->loc.io.total,
- q1, referer->len, referer->ptr, q1,
- q2, user_agent->len, user_agent->ptr, q2);
-#endif
-
- if (fp != NULL) {
- (void) fprintf(fp, "%s\n", buf);
- (void) fflush(fp);
- }
-
-#if defined(_WIN32) && !defined(NO_GUI)
- {
- extern HWND hLog;
-
- if (hLog != NULL)
- SendMessage(hLog, WM_APP, 0, (LPARAM) buf);
- }
-#endif /* _WIN32 */
-}
diff --git a/cpukit/shttpd/md5.c b/cpukit/shttpd/md5.c
deleted file mode 100644
index 4e9c4701d6..0000000000
--- a/cpukit/shttpd/md5.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest. This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- */
-
-#include "defs.h"
-
-#ifndef HAVE_MD5
-#if __BYTE_ORDER == 1234
-#define byteReverse(buf, len) /* Nothing */
-#else
-/*
- * Note: this code is harmless on little-endian machines.
- */
-static void byteReverse(unsigned char *buf, unsigned longs)
-{
- uint32_t t;
- do {
- t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
- ((unsigned) buf[1] << 8 | buf[0]);
- *(uint32_t *) buf = t;
- buf += 4;
- } while (--longs);
-}
-#endif /* __BYTE_ORDER */
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f, w, x, y, z, data, s) \
-( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
-
-/*
- * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-void MD5Init(MD5_CTX *ctx)
-{
- ctx->buf[0] = 0x67452301;
- ctx->buf[1] = 0xefcdab89;
- ctx->buf[2] = 0x98badcfe;
- ctx->buf[3] = 0x10325476;
-
- ctx->bits[0] = 0;
- ctx->bits[1] = 0;
-}
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data. MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-static void MD5Transform(uint32_t buf[4], uint32_t const in[16])
-{
- register uint32_t a, b, c, d;
-
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
- MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
- MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
- MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
- MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
- MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
- MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
- MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
- MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
- MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
- MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
- MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
- MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
- MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
- MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
- MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
- MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
- MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
- MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
- MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
- MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
- MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
- MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
- MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
- MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
- MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
- MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
- MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
- MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
- MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
- MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
- MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
- MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
- MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
- MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
- MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
- MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
- MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
- MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
- MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
- MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
- MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
- MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
- MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
- MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
- MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
- MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
- MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
- MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
- MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
- MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
- MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
- MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
- MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
- MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
- MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
- MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
- MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
- MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
- MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
- MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
- MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
- MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
- MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
-}
-
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void
-MD5Update(MD5_CTX *ctx, unsigned char const *buf, unsigned len)
-{
- uint32_t t;
-
- /* Update bitcount */
-
- t = ctx->bits[0];
- if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
- ctx->bits[1]++; /* Carry from low to high */
- ctx->bits[1] += len >> 29;
-
- t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
-
- /* Handle any leading odd-sized chunks */
-
- if (t) {
- unsigned char *p = (unsigned char *) ctx->in + t;
-
- t = 64 - t;
- if (len < t) {
- memcpy(p, buf, len);
- return;
- }
- memcpy(p, buf, t);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
- buf += t;
- len -= t;
- }
- /* Process data in 64-byte chunks */
-
- while (len >= 64) {
- memcpy(ctx->in, buf, 64);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
- buf += 64;
- len -= 64;
- }
-
- /* Handle any remaining bytes of data. */
-
- memcpy(ctx->in, buf, len);
-}
-
-/*
- * Final wrapup - pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-void
-MD5Final(unsigned char digest[16], MD5_CTX *ctx)
-{
- unsigned count;
- unsigned char *p;
-
- /* Compute number of bytes mod 64 */
- count = (ctx->bits[0] >> 3) & 0x3F;
-
- /* Set the first char of padding to 0x80. This is safe since there is
- always at least one byte free */
- p = ctx->in + count;
- *p++ = 0x80;
-
- /* Bytes of padding needed to make 64 bytes */
- count = 64 - 1 - count;
-
- /* Pad out to 56 mod 64 */
- if (count < 8) {
- /* Two lots of padding: Pad the first block to 64 bytes */
- memset(p, 0, count);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
-
- /* Now fill the next block with 56 bytes */
- memset(ctx->in, 0, 56);
- } else {
- /* Pad block to 56 bytes */
- memset(p, 0, count - 8);
- }
- byteReverse(ctx->in, 14);
-
- /* Append length in bits and transform */
- ((uint32_t *) ctx->in)[14] = ctx->bits[0];
- ((uint32_t *) ctx->in)[15] = ctx->bits[1];
-
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
- byteReverse((unsigned char *) ctx->buf, 4);
- memcpy(digest, ctx->buf, 16);
- memset((char *) ctx, 0, sizeof(ctx)); /* In case it's sensitive */
-}
-
-#endif /* !HAVE_MD5 */
diff --git a/cpukit/shttpd/md5.h b/cpukit/shttpd/md5.h
deleted file mode 100644
index fcca00ecfb..0000000000
--- a/cpukit/shttpd/md5.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#ifndef MD5_HEADER_INCLUDED
-#define MD5_HEADER_INCLUDED
-
-typedef struct MD5Context {
- uint32_t buf[4];
- uint32_t bits[2];
- unsigned char in[64];
-} MD5_CTX;
-
-extern void MD5Init(MD5_CTX *ctx);
-extern void MD5Update(MD5_CTX *ctx, unsigned char const *buf, unsigned len);
-extern void MD5Final(unsigned char digest[16], MD5_CTX *ctx);
-
-#endif /*MD5_HEADER_INCLUDED */
diff --git a/cpukit/shttpd/mime_type.c b/cpukit/shttpd/mime_type.c
deleted file mode 100644
index 7c9422d284..0000000000
--- a/cpukit/shttpd/mime_type.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-static const struct mime_type default_mime_types[] = {
- {"html", 4, "text/html" },
- {"htm", 3, "text/html" },
- {"txt", 3, "text/plain" },
- {"css", 3, "text/css" },
- {"ico", 3, "image/x-icon" },
- {"gif", 3, "image/gif" },
- {"jpg", 3, "image/jpeg" },
- {"jpeg", 4, "image/jpeg" },
- {"png", 3, "image/png" },
- {"svg", 3, "image/svg+xml" },
- {"torrent", 7, "application/x-bittorrent" },
- {"wav", 3, "audio/x-wav" },
- {"mp3", 3, "audio/x-mp3" },
- {"mid", 3, "audio/mid" },
- {"m3u", 3, "audio/x-mpegurl" },
- {"ram", 3, "audio/x-pn-realaudio" },
- {"ra", 2, "audio/x-pn-realaudio" },
- {"doc", 3, "application/msword", },
- {"exe", 3, "application/octet-stream" },
- {"zip", 3, "application/x-zip-compressed" },
- {"xls", 3, "application/excel" },
- {"tgz", 3, "application/x-tar-gz" },
- {"tar.gz", 6, "application/x-tar-gz" },
- {"tar", 3, "application/x-tar" },
- {"gz", 2, "application/x-gunzip" },
- {"arj", 3, "application/x-arj-compressed" },
- {"rar", 3, "application/x-arj-compressed" },
- {"rtf", 3, "application/rtf" },
- {"pdf", 3, "application/pdf" },
- {"mpg", 3, "video/mpeg" },
- {"mpeg", 4, "video/mpeg" },
- {"asf", 3, "video/x-ms-asf" },
- {"avi", 3, "video/x-msvideo" },
- {"bmp", 3, "image/bmp" },
- {NULL, 0, NULL }
-};
-
-const char *
-get_mime_type(struct shttpd_ctx *ctx, const char *uri, int len)
-{
- struct llhead *lp;
- const struct mime_type *mt;
- struct mime_type_link *mtl;
- const char *s;
-
- /* Firt, loop through the custom mime types if any */
- LL_FOREACH(&ctx->mime_types, lp) {
- mtl = LL_ENTRY(lp, struct mime_type_link, link);
- s = uri + len - mtl->ext_len;
- if (s > uri && s[-1] == '.' &&
- !my_strncasecmp(mtl->ext, s, mtl->ext_len))
- return (mtl->mime);
- }
-
- /* If no luck, try built-in mime types */
- for (mt = default_mime_types; mt->ext != NULL; mt++) {
- s = uri + len - mt->ext_len;
- if (s > uri && s[-1] == '.' &&
- !my_strncasecmp(mt->ext, s, mt->ext_len))
- return (mt->mime);
- }
-
- /* Oops. This extension is unknown to us. Fallback to text/plain */
- return ("text/plain");
-}
-
-void
-set_mime_types(struct shttpd_ctx *ctx, const char *path)
-{
- FILE *fp;
- char line[512], ext[sizeof(line)], mime[sizeof(line)], *s;
-
- if ((fp = fopen(path, "r")) == NULL)
- elog(E_FATAL, NULL, "set_mime_types: fopen(%s): %s",
- path, strerror(errno));
-
- while (fgets(line, sizeof(line), fp) != NULL) {
- /* Skip empty lines */
- if (line[0] == '#' || line[0] == '\n')
- continue;
- if (sscanf(line, "%s", mime)) {
- s = line + strlen(mime);
- while (*s && *s != '\n' && sscanf(s, "%s", ext)) {
- shttpd_add_mime_type(ctx, ext, mime);
- s += strlen(mime);
- }
- }
- }
-
- (void) fclose(fp);
-}
diff --git a/cpukit/shttpd/preinstall.am b/cpukit/shttpd/preinstall.am
deleted file mode 100644
index 9983a14e70..0000000000
--- a/cpukit/shttpd/preinstall.am
+++ /dev/null
@@ -1,39 +0,0 @@
-## Automatically generated by ampolish3 - Do not edit
-
-if AMPOLISH3
-$(srcdir)/preinstall.am: Makefile.am
- $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
-endif
-
-PREINSTALL_DIRS =
-DISTCLEANFILES = $(PREINSTALL_DIRS)
-
-all-local: $(TMPINSTALL_FILES)
-
-TMPINSTALL_FILES =
-CLEANFILES = $(TMPINSTALL_FILES)
-
-all-am: $(PREINSTALL_FILES)
-
-PREINSTALL_FILES =
-CLEANFILES += $(PREINSTALL_FILES)
-
-$(PROJECT_LIB)/$(dirstamp):
- @$(MKDIR_P) $(PROJECT_LIB)
- @: > $(PROJECT_LIB)/$(dirstamp)
-PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
-
-if LIBSHTTPD
-$(PROJECT_INCLUDE)/shttpd/$(dirstamp):
- @$(MKDIR_P) $(PROJECT_INCLUDE)/shttpd
- @: > $(PROJECT_INCLUDE)/shttpd/$(dirstamp)
-PREINSTALL_DIRS += $(PROJECT_INCLUDE)/shttpd/$(dirstamp)
-
-$(PROJECT_LIB)/libshttpd.a: libshttpd.a $(PROJECT_LIB)/$(dirstamp)
- $(INSTALL_DATA) $< $(PROJECT_LIB)/libshttpd.a
-TMPINSTALL_FILES += $(PROJECT_LIB)/libshttpd.a
-
-$(PROJECT_INCLUDE)/shttpd/shttpd.h: shttpd.h $(PROJECT_INCLUDE)/shttpd/$(dirstamp)
- $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/shttpd/shttpd.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/shttpd/shttpd.h
-endif
diff --git a/cpukit/shttpd/shttpd.1 b/cpukit/shttpd/shttpd.1
deleted file mode 100644
index a7ec641ab5..0000000000
--- a/cpukit/shttpd/shttpd.1
+++ /dev/null
@@ -1,135 +0,0 @@
-.\" Process this file with
-.\" groff -man -Tascii shttpd.1
-.\" $Id$
-.Dd Nov 10, 2006
-.Dt SHTTPD 1
-.Sh NAME
-.Nm shttpd
-.Nd lightweight web server
-.Sh SYNOPSIS
-.Nm
-.Op Ar OPTIONS
-.Op Ar config_file
-.Nm
-.Fl A Ar htpasswd_file realm username password
-.Sh DESCRIPTION
-.Nm
-is small, fast and easy to use web server with CGI, SSL, Digest Authorization
-support. It can be run as stand-alone server, be managed by
-.Xr inetd 8
-, or be embedded into existing C/C++ application.
-.Pp
-Unlike other web servers,
-.Nm
-does not expect CGI scirpts to be put in a special directory. They may be
-anywhere. CGI files are recognized by an extension, which is
-.Dq .cgi
-by default.
-.Pp
-By default
-.Nm
-does not use SSL and starts listening on port 80. Specifying the
-.Fl s Ar pem_file
-option automatically switches
-.Nm
-to SSL mode on port 443.
-.Pp
-.Nm
-can take configuration parameters from two sources: from the command
-line and from the configuration file. Command line parameters have
-higher priority. Every command line parameter has associated configuration
-file keyword, except
-.Fl A
-parameter.
-In the configuration file, blank lines and lines started with
-.Dq #
-character are ignored. All other lines must start with the keyword
-followed by a whitespace followed by keyword's value.
-If both command line parameter and configuration
-file option are not specified, the default value is taken. The configuration
-file may not be present at all.
-.Pp
-If
-.Nm
-should be managed by
-.Xr inetd 8 ,
-add this line to
-.Pa inetd.conf :
-.Pp
-.Dl http stream tcp nowait nobody /path/to/shttpd shttpd -I1 -d /my/www
-.Pp
-.Sh OPTIONS
-Below is the list of command line parameters. In the brackets there are
-corresponding configuration file keywords.
-.Bl -tag -width indent
-.It Fl A Ar htpasswd server_name user_name user_password
-Edit the passwords file. Functionality similar to Apache's
-.Ic htdigest
-utility.
-.It Fl C Ar file ( Cm cgi_interpreter Ar file )
-Force
-.Ar file
-to be a CGI interpreter for all CGI scripts. Default: none.
-.It Fl D Ar 0|1 ( Cm list_directories Ar 0|1 )
-Disable directory listing. Default: enabled.
-.It Fl I Ar 0|1 ( Cm inetd_mode Ar 0|1 )
-Enable inetd mode. Default: disabled.
-.It Fl N Ar realm ( Cm server_name Ar realm )
-Authorization realm. Default:
-.Dq mydomain.com .
-.It Fl P Ar file ( Cm global_htpasswd Ar file )
-Location of global passwords file. Per-directory .htpasswd files are
-ignored, if this option is set. Default: not set.
-.It Fl U Ar file ( Cm put_auth Ar file )
-PUT and DELETE passwords file. This must be specified if PUT or
-DELETE methods are used. Default: none.
-.It Fl V Ar string ( Cm cgi_envvar Ar string )
-Pass additional environment variables to the CGI script. These must be
-comma-separated list of var=val pairs, like this: "VAR1=VAL1,VAR2=VAL2".
-Default: not set.
-.It Fl a Ar string ( Cm aliases Ar string )
-Attach directories (even those outside document_root) to URIs. The
-.Ar string
-must be comma-separated list of var=val pairs, like this:
-"/etc/=/my_etc,/tmp=/my_tmp". Default: not set.
-.It Fl c Ar string ( Cm cgi_extension Ar string )
-CGI filename pattern. For every requested file,
-.Nm
-uses the pattern to figure out whether to return the file content,
-ot run the file as CGI application. Default:
-.Dq .cgi .
-.It Fl d Ar directory ( Cm document_root Ar directory )
-Location of the WWW root directory. Default: working directory from which
-.Nm
-has been started.
-.It Fl e Ar file ( Cm error_log Ar file )
-Error log file. Default: not set, no errors are logged.
-.It Fl l Ar file ( Cm access_log Ar file )
-Access log file. Default: not set, no logging is done.
-.It Fl m Ar file ( Cm mime_types Ar file )
-Location of mime types file. Default: not set, builtins are used.
-.It Fl p Ar port ( Cm listen_port Ar port )
-Listening port. Default: 80 for non-SSL and 443 for SSL mode.
-.It Fl s Ar pem_file ( Cm ssl_certificate Ar pem_file )
-Location of SSL certificate file. Default: not set.
-.It Fl u Ar login ( Cm runtime_uid Ar login )
-Switch to given user ID after startup. Default: not set
-.El
-.Pp
-.Sh EMBEDDING
-.Nm
-can be built as a library to embed web server functionality
-into C/C++ application. The API functions are declared in a header
-file
-.Pa shttpd.h .
-Please refer to the source package for a header file and the examples.
-.Sh FILES
-.Pa /usr/local/etc/shttpd.conf
-.br
-.Sh SEE ALSO
-.Xr inetd 8 .
-.Sh COPYRIGHT
-.Nm
-is licensed under the terms of beerware license.
-.Sh AUTHOR
-.An Sergey Lyubka Aq valenok@gmail.com .
diff --git a/cpukit/shttpd/shttpd.c b/cpukit/shttpd/shttpd.c
deleted file mode 100644
index 66dc7fd846..0000000000
--- a/cpukit/shttpd/shttpd.c
+++ /dev/null
@@ -1,1135 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-/*
- * Small and portable HTTP server, http://shttpd.sourceforge.net
- * $Id$
- */
-
-#include "defs.h"
-
-#include <unistd.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-time_t current_time; /* Current UTC time */
-int tz_offset; /* Time zone offset from UTC */
-
-static LL_HEAD(listeners); /* List of listening sockets */
-
-const struct vec known_http_methods[] = {
- {"GET", 3},
- {"POST", 4},
- {"PUT", 3},
- {"DELETE", 6},
- {"HEAD", 4},
- {NULL, 0}
-};
-
-/*
- * This structure tells how HTTP headers must be parsed.
- * Used by parse_headers() function.
- */
-#define OFFSET(x) offsetof(struct headers, x)
-static const struct http_header http_headers[] = {
- {16, HDR_INT, OFFSET(cl), "Content-Length: " },
- {14, HDR_STRING, OFFSET(ct), "Content-Type: " },
- {12, HDR_STRING, OFFSET(useragent), "User-Agent: " },
- {19, HDR_DATE, OFFSET(ims), "If-Modified-Since: " },
- {15, HDR_STRING, OFFSET(auth), "Authorization: " },
- {9, HDR_STRING, OFFSET(referer), "Referer: " },
- {8, HDR_STRING, OFFSET(cookie), "Cookie: " },
- {10, HDR_STRING, OFFSET(location), "Location: " },
- {8, HDR_INT, OFFSET(status), "Status: " },
- {7, HDR_STRING, OFFSET(range), "Range: " },
- {12, HDR_STRING, OFFSET(connection), "Connection: " },
- {19, HDR_STRING, OFFSET(transenc), "Transfer-Encoding: " },
- {0, HDR_INT, 0, NULL }
-};
-
-struct shttpd_ctx *init_ctx(const char *config_file, int argc, char *argv[]);
-
-void
-decode_url_encoded_string(const char *src, int src_len, char *dst, int dst_len)
-{
- int i, j, a, b;
-#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
-
- for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++)
- switch (src[i]) {
- case '%':
- if (isxdigit(((unsigned char *) src)[i + 1]) &&
- isxdigit(((unsigned char *) src)[i + 2])) {
- a = tolower(((unsigned char *)src)[i + 1]);
- b = tolower(((unsigned char *)src)[i + 2]);
- dst[j] = (HEXTOI(a) << 4) | HEXTOI(b);
- i += 2;
- } else {
- dst[j] = '%';
- }
- break;
- case '+':
- dst[j] = ' ';
- break;
- default:
- dst[j] = src[i];
- break;
- }
-
- dst[j] = '\0'; /* Null-terminate the destination */
-}
-
-void
-shttpd_add_mime_type(struct shttpd_ctx *ctx, const char *ext, const char *mime)
-{
- struct mime_type_link *e;
- const char *error_msg = "shttpd_add_mime_type: no memory";
-
- if ((e = malloc(sizeof(*e))) == NULL) {
- elog(E_FATAL, 0, error_msg);
- } else if ((e->ext= my_strdup(ext)) == NULL) {
- elog(E_FATAL, 0, error_msg);
- } else if ((e->mime = my_strdup(mime)) == NULL) {
- elog(E_FATAL, 0, error_msg);
- } else {
- e->ext_len = strlen(ext);
- LL_TAIL(&ctx->mime_types, &e->link);
- }
-}
-
-
-static const char *
-is_alias(struct shttpd_ctx *ctx, const char *uri,
- struct vec *a_uri, struct vec *a_path)
-{
- const char *p, *s = ctx->aliases;
- size_t len;
-
- DBG(("is_alias: aliases [%s]", s == NULL ? "" : s));
-
- FOR_EACH_WORD_IN_LIST(s, len) {
- if ((p = memchr(s, '=', len)) != NULL &&
- memcmp(uri, s, p - s) == 0) {
- a_uri->ptr = s;
- a_uri->len = p - s;
- a_path->ptr = ++p;
- a_path->len = (s + len) - p;
- return (s);
- }
- }
-
- return (NULL);
-}
-
-void
-stop_stream(struct stream *stream)
-{
- if (stream->io_class != NULL && stream->io_class->close != NULL)
- stream->io_class->close(stream);
-
- stream->io_class= NULL;
- stream->flags |= FLAG_CLOSED;
- stream->flags &= ~(FLAG_R | FLAG_W | FLAG_ALWAYS_READY);
-
- DBG(("%d %s stopped. %lu of content data, %d now in a buffer",
- stream->conn->rem.chan.sock,
- stream->io_class ? stream->io_class->name : "(null)",
- (unsigned long) stream->io.total, io_data_len(&stream->io)));
-}
-
-/*
- * Setup listening socket on given port, return socket
- */
-static int
-open_listening_port(int port)
-{
- int sock, on = 1;
- struct usa sa;
-
-#ifdef _WIN32
- {WSADATA data; WSAStartup(MAKEWORD(2,2), &data);}
-#endif /* _WIN32 */
-
- sa.len = sizeof(sa.u.sin);
- sa.u.sin.sin_family = AF_INET;
- sa.u.sin.sin_port = htons((uint16_t) port);
- sa.u.sin.sin_addr.s_addr = htonl(INADDR_ANY);
-
- if ((sock = socket(PF_INET, SOCK_STREAM, 6)) == -1)
- goto fail;
- if (set_non_blocking_mode(sock) != 0)
- goto fail;
- if (setsockopt(sock, SOL_SOCKET,
- SO_REUSEADDR,(char *) &on, sizeof(on)) != 0)
- goto fail;
- if (bind(sock, &sa.u.sa, sa.len) < 0)
- goto fail;
- if (listen(sock, 128) != 0)
- goto fail;
-
-#ifndef _WIN32
- (void) fcntl(sock, F_SETFD, FD_CLOEXEC);
-#endif /* !_WIN32 */
-
- return (sock);
-fail:
- if (sock != -1)
- (void) closesocket(sock);
- elog(E_LOG, NULL, "open_listening_port(%d): %s", port, strerror(errno));
- return (-1);
-}
-
-/*
- * Check whether full request is buffered Return headers length, or 0
- */
-int
-get_headers_len(const char *buf, size_t buflen)
-{
- const char *s, *e;
- int len = 0;
-
- for (s = buf, e = s + buflen - 1; len == 0 && s < e; s++)
- /* Control characters are not allowed but >=128 is. */
- if (!isprint(*(unsigned char *)s) && *s != '\r' && *s != '\n' && *(unsigned char *)s < 128)
- len = -1;
- else if (s[0] == '\n' && s[1] == '\n')
- len = s - buf + 2;
- else if (s[0] == '\n' && &s[1] < e &&
- s[1] == '\r' && s[2] == '\n')
- len = s - buf + 3;
-
- return (len);
-}
-
-/*
- * Send error message back to a client.
- */
-void
-send_server_error(struct conn *c, int status, const char *reason)
-{
-#ifdef EMBEDDED
- struct llhead *lp;
- struct error_handler *e;
-
- LL_FOREACH(&c->ctx->error_handlers, lp) {
- e = LL_ENTRY(lp, struct error_handler, link);
-
- if (e->code == status) {
- if (c->loc.io_class != NULL &&
- c->loc.io_class->close != NULL)
- c->loc.io_class->close(&c->loc);
- io_clear(&c->loc.io);
- setup_embedded_stream(c, e->callback, NULL);
- return;
- }
- }
-#endif /* EMBEDDED */
-
- io_clear(&c->loc.io);
- c->loc.headers_len = c->loc.io.head = my_snprintf(c->loc.io.buf,
- c->loc.io.size, "HTTP/1.1 %d %s\r\n\r\n%d %s",
- status, reason, status, reason);
- c->status = status;
- stop_stream(&c->loc);
-}
-
-/*
- * Convert month to the month number. Return -1 on error, or month number
- */
-static int
-montoi(const char *s)
-{
- static const char *ar[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
- size_t i;
-
- for (i = 0; i < sizeof(ar) / sizeof(ar[0]); i++)
- if (!strcmp(s, ar[i]))
- return (i);
-
- return (-1);
-}
-
-/*
- * Parse date-time string, and return the corresponding time_t value
- */
-static time_t
-date_to_epoch(const char *s)
-{
- struct tm tm, *tmp;
- char mon[32];
- int sec, min, hour, mday, month, year;
-
- (void) memset(&tm, 0, sizeof(tm));
- sec = min = hour = mday = month = year = 0;
-
- if (((sscanf(s, "%d/%3s/%d %d:%d:%d",
- &mday, mon, &year, &hour, &min, &sec) == 6) ||
- (sscanf(s, "%d %3s %d %d:%d:%d",
- &mday, mon, &year, &hour, &min, &sec) == 6) ||
- (sscanf(s, "%*3s, %d %3s %d %d:%d:%d",
- &mday, mon, &year, &hour, &min, &sec) == 6) ||
- (sscanf(s, "%d-%3s-%d %d:%d:%d",
- &mday, mon, &year, &hour, &min, &sec) == 6)) &&
- (month = montoi(mon)) != -1) {
- tm.tm_mday = mday;
- tm.tm_mon = month;
- tm.tm_year = year;
- tm.tm_hour = hour;
- tm.tm_min = min;
- tm.tm_sec = sec;
- }
-
- if (tm.tm_year > 1900)
- tm.tm_year -= 1900;
- else if (tm.tm_year < 70)
- tm.tm_year += 100;
-
- /* Set Daylight Saving Time field */
- tmp = localtime(&current_time);
- tm.tm_isdst = tmp->tm_isdst;
-
- return (mktime(&tm));
-}
-
-static void
-remove_double_dots(char *s)
-{
- char *p = s;
-
- while (*s != '\0') {
- *p++ = *s++;
- if (s[-1] == '/')
- while (*s == '.' || *s == '/')
- s++;
- }
- *p = '\0';
-}
-
-void
-parse_headers(const char *s, int len, struct headers *parsed)
-{
- const struct http_header *h;
- union variant *v;
- const char *p, *e = s + len;
-
- DBG(("parsing headers (len %d): [%.*s]", len, len, s));
-
- /* Loop through all headers in the request */
- while (s < e) {
-
- /* Find where this header ends */
- for (p = s; p < e && *p != '\n'; ) p++;
-
- /* Is this header known to us ? */
- for (h = http_headers; h->len != 0; h++)
- if (e - s > h->len &&
- !my_strncasecmp(s, h->name, h->len))
- break;
-
- /* If the header is known to us, store its value */
- if (h->len != 0) {
-
- /* Shift to where value starts */
- s += h->len;
-
- /* Find place to store the value */
- v = (union variant *) ((char *) parsed + h->offset);
-
- /* Fetch header value into the connection structure */
- if (h->type == HDR_STRING) {
- v->v_vec.ptr = s;
- v->v_vec.len = p - s;
- if (p[-1] == '\r' && v->v_vec.len > 0)
- v->v_vec.len--;
- } else if (h->type == HDR_INT) {
- v->v_big_int = strtoul(s, NULL, 10);
- } else if (h->type == HDR_DATE) {
- v->v_time = date_to_epoch(s);
- }
- }
-
- s = p + 1; /* Shift to the next header */
- }
-}
-
-/*
- * For given directory path, substitute it to valid index file.
- * Return 0 if index file has been found, -1 if not found
- */
-static int
-find_index_file(struct conn *c, char *path, size_t maxpath, struct stat *stp)
-{
- char buf[FILENAME_MAX];
- const char *s = c->ctx->index_files;
- size_t len;
-
- FOR_EACH_WORD_IN_LIST(s, len) {
- my_snprintf(buf, sizeof(buf), "%s%c%.*s",path, DIRSEP, len, s);
- if (my_stat(buf, stp) == 0) {
- my_strlcpy(path, buf, maxpath);
- c->mime_type = get_mime_type(c->ctx, s, len);
- return (0);
- }
- }
-
- return (-1);
-}
-
-/*
- * Try to open requested file, return 0 if OK, -1 if error.
- * If the file is given arguments using PATH_INFO mechanism,
- * initialize pathinfo pointer.
- */
-static int
-get_path_info(struct conn *c, char *path, struct stat *stp)
-{
- char *p, *e;
-
- if (my_stat(path, stp) == 0)
- return (0);
-
- p = path + strlen(path);
- e = path + strlen(c->ctx->document_root) + 2;
-
- /* Strip directory parts of the path one by one */
- for (; p > e; p--)
- if (*p == '/') {
- *p = '\0';
- if (!my_stat(path, stp) && !S_ISDIR(stp->st_mode)) {
- c->path_info = p + 1;
- return (0);
- } else {
- *p = '/';
- }
- }
-
- return (-1);
-}
-
-
-static void
-decide_what_to_do(struct conn *c)
-{
- char path[URI_MAX], buf[1024];
- struct vec alias_uri, alias_path;
- struct stat st;
- int rc;
-#ifdef EMBEDDED
- struct registered_uri *ruri;
-#endif /* EMBEDDED */
-
- DBG(("decide_what_to_do: [%s]", c->uri));
-
- if ((c->query = strchr(c->uri, '?')) != NULL)
- *c->query++ = '\0';
-
- decode_url_encoded_string(c->uri, strlen(c->uri),
- c->uri, strlen(c->uri) + 1);
- remove_double_dots(c->uri);
-
- if (strlen(c->uri) + strlen(c->ctx->document_root) >= sizeof(path)) {
- send_server_error(c, 400, "URI is too long");
- return;
- }
-
- (void) my_snprintf(path, sizeof(path), "%s%s",
- c->ctx->document_root, c->uri);
-
- /* User may use the aliases - check URI for mount point */
- if (is_alias(c->ctx, c->uri, &alias_uri, &alias_path) != NULL) {
- (void) my_snprintf(path, sizeof(path), "%.*s%s",
- alias_path.len, alias_path.ptr, c->uri + alias_uri.len);
- DBG(("using alias %.*s -> %.*s", alias_uri.len, alias_uri.ptr,
- alias_path.len, alias_path.ptr));
- }
-
-#if !defined(NO_AUTH)
- if (check_authorization(c, path) != 1) {
- send_authorization_request(c);
- } else
-#endif /* NO_AUTH */
-#ifdef EMBEDDED
- if ((ruri = is_registered_uri(c->ctx, c->uri)) != NULL) {
- setup_embedded_stream(c, ruri->callback, ruri->callback_data);
- } else
-#endif /* EMBEDDED */
- if (strstr(path, HTPASSWD)) {
- /* Do not allow to view passwords files */
- send_server_error(c, 403, "Forbidden");
- } else
-#if !defined(NO_AUTH)
- if ((c->method == METHOD_PUT || c->method == METHOD_DELETE) &&
- (c->ctx->put_auth_file == NULL || !is_authorized_for_put(c))) {
- send_authorization_request(c);
- } else
-#endif /* NO_AUTH */
- if (c->method == METHOD_PUT) {
- c->status = my_stat(path, &st) == 0 ? 200 : 201;
-
- if (c->ch.range.v_vec.len > 0) {
- send_server_error(c, 501, "PUT Range Not Implemented");
- } else if ((rc = put_dir(path)) == 0) {
- send_server_error(c, 200, "OK");
- } else if (rc == -1) {
- send_server_error(c, 500, "PUT Directory Error");
- } else if (c->rem.content_len == 0) {
- send_server_error(c, 411, "Length Required");
- } else if ((c->loc.chan.fd = my_open(path, O_WRONLY | O_BINARY |
- O_CREAT | O_NONBLOCK | O_TRUNC, 0644)) == -1) {
- send_server_error(c, 500, "PUT Error");
- } else {
- DBG(("PUT file [%s]", c->uri));
- c->loc.io_class = &io_file;
- c->loc.flags |= FLAG_W | FLAG_ALWAYS_READY ;
- }
- } else if (c->method == METHOD_DELETE) {
- DBG(("DELETE [%s]", c->uri));
- if (my_remove(path) == 0)
- send_server_error(c, 200, "OK");
- else
- send_server_error(c, 500, "DELETE Error");
- } else if (get_path_info(c, path, &st) != 0) {
- send_server_error(c, 404, "Not Found");
- } else if (S_ISDIR(st.st_mode) && path[strlen(path) - 1] != '/') {
- (void) my_snprintf(buf, sizeof(buf),
- "Moved Permanently\r\nLocation: %s/", c->uri);
- send_server_error(c, 301, buf);
- } else if (S_ISDIR(st.st_mode) &&
- find_index_file(c, path, sizeof(path) - 1, &st) == -1 &&
- c->ctx->dirlist == 0) {
- send_server_error(c, 403, "Directory Listing Denied");
- } else if (S_ISDIR(st.st_mode) && c->ctx->dirlist) {
- if ((c->loc.chan.dir.path = my_strdup(path)) != NULL)
- get_dir(c);
- else
- send_server_error(c, 500, "GET Directory Error");
- } else if (S_ISDIR(st.st_mode) && c->ctx->dirlist == 0) {
- send_server_error(c, 403, "Directory listing denied");
-#ifndef NO_CGI
- } else if (is_cgi(c->ctx, path)) {
- if (c->method != METHOD_POST && c->method != METHOD_GET) {
- send_server_error(c, 501, "Bad method ");
- } else if ((run_cgi(c, path)) == -1) {
- send_server_error(c, 500, "Cannot exec CGI");
- } else {
- do_cgi(c);
- }
-#endif /* NO_CGI */
- } else if (c->ch.ims.v_time && st.st_mtime <= c->ch.ims.v_time) {
- send_server_error(c, 304, "Not Modified");
- } else if ((c->loc.chan.fd = my_open(path,
- O_RDONLY | O_BINARY, 0644)) != -1) {
- get_file(c, &st);
- } else {
- send_server_error(c, 500, "Internal Error");
- }
-}
-
-static int
-set_request_method(struct conn *c)
-{
- const struct vec *v;
-
- assert(c->rem.io.head >= MIN_REQ_LEN);
-
- /* Set the request method */
- for (v = known_http_methods; v->ptr != NULL; v++)
- if (!memcmp(c->rem.io.buf, v->ptr, v->len)) {
- c->method = v - known_http_methods;
- break;
- }
-
- return (v->ptr == NULL);
-}
-
-static void
-parse_http_request(struct conn *c)
-{
- char *s, *e, *p, *start;
- char *end_number;
- int uri_len, req_len;
-
- s = c->rem.io.buf;
- req_len = c->rem.headers_len = get_headers_len(s, c->rem.io.head);
-
- if (req_len == 0 && io_space_len(&c->rem.io) == 0)
- send_server_error(c, 400, "Request is too big");
-
- if (req_len == 0)
- return;
- else if (req_len < MIN_REQ_LEN)
- send_server_error(c, 400, "Bad request");
- else if (set_request_method(c))
- send_server_error(c, 501, "Method Not Implemented");
- else if ((c->request = my_strndup(s, req_len)) == NULL)
- send_server_error(c, 500, "Cannot allocate request");
-
- if (c->loc.flags & FLAG_CLOSED)
- return;
-
- DBG(("Conn %d: parsing request: [%.*s]", c->rem.chan.sock, req_len, s));
- c->rem.flags |= FLAG_HEADERS_PARSED;
-
- /* Set headers pointer. Headers follow the request line */
- c->headers = memchr(c->request, '\n', req_len);
- assert(c->headers != NULL);
- assert(c->headers < c->request + req_len);
- if (c->headers > c->request && c->headers[-1] == '\r')
- c->headers[-1] = '\0';
- *c->headers++ = '\0';
-
- /*
- * Now make a copy of the URI, because it will be URL-decoded,
- * and we need a copy of unmodified URI for the access log.
- * First, we skip the REQUEST_METHOD and shift to the URI.
- */
- for (p = c->request, e = p + req_len; *p != ' ' && p < e; p++);
- while (p < e && *p == ' ') p++;
-
- /* Now remember where URI starts, and shift to the end of URI */
- for (start = p; p < e && !isspace((unsigned char)*p); ) p++;
- uri_len = p - start;
- /* Skip space following the URI */
- while (p < e && *p == ' ') p++;
-
- /* Now comes the HTTP-Version in the form HTTP/<major>.<minor> */
- if (strncmp(p, "HTTP/", 5) != 0) {
- send_server_error(c, 400, "Bad HTTP version");
- return;
- }
- p += 5;
- /* Parse the HTTP major version number */
- c->major_version = strtoul(p, &end_number, 10);
- if (end_number == p || *end_number != '.') {
- send_server_error(c, 400, "Bad HTTP major version");
- return;
- }
- p = end_number + 1;
- /* Parse the minor version number */
- c->minor_version = strtoul(p, &end_number, 10);
- if (end_number == p || *end_number != '\0') {
- send_server_error(c, 400, "Bad HTTP minor version");
- return;
- }
- /* Version must be <=1.1 */
- if (c->major_version > 1 ||
- (c->major_version == 1 && c->minor_version > 1)) {
- send_server_error(c, 505, "HTTP version not supported");
- return;
- }
-
- if (uri_len <= 0) {
- send_server_error(c, 400, "Bad URI");
- } else if ((c->uri = malloc(uri_len + 1)) == NULL) {
- send_server_error(c, 500, "Cannot allocate URI");
- } else {
- my_strlcpy(c->uri, (char *) start, uri_len + 1);
- parse_headers(c->headers,
- (c->request + req_len) - c->headers, &c->ch);
-
- /* Remove the length of request from total, count only data */
- assert(c->rem.io.total >= (big_int_t) req_len);
- c->rem.io.total -= req_len;
-
- c->rem.content_len = c->ch.cl.v_big_int;
- io_inc_tail(&c->rem.io, req_len);
-
- decide_what_to_do(c);
- }
-}
-
-void
-shttpd_add_socket(struct shttpd_ctx *ctx, int sock)
-{
- struct conn *c;
- struct usa sa;
- int l = ctx->inetd_mode ? E_FATAL : E_LOG;
-#if !defined(NO_SSL)
- SSL *ssl = NULL;
-#endif /* NO_SSL */
-
- sa.len = sizeof(sa.u.sin);
- (void) set_non_blocking_mode(sock);
-
- if (getpeername(sock, &sa.u.sa, &sa.len)) {
- elog(l, NULL, "add_socket: %s", strerror(errno));
-#if !defined(NO_SSL)
- } else if (ctx->ssl_ctx && (ssl = SSL_new(ctx->ssl_ctx)) == NULL) {
- elog(l, NULL, "add_socket: SSL_new: %s", strerror(ERRNO));
- (void) closesocket(sock);
- } else if (ctx->ssl_ctx && SSL_set_fd(ssl, sock) == 0) {
- elog(l, NULL, "add_socket: SSL_set_fd: %s", strerror(ERRNO));
- (void) closesocket(sock);
- SSL_free(ssl);
-#endif /* NO_SSL */
- } else if ((c = calloc(1, sizeof(*c) + 2 * ctx->io_buf_size)) == NULL) {
-
-#if !defined(NO_SSL)
- if (ssl)
- SSL_free(ssl);
-#endif /* NO_SSL */
- (void) closesocket(sock);
- elog(l, NULL, "add_socket: calloc: %s", strerror(ERRNO));
- } else {
- ctx->nrequests++;
- c->rem.conn = c->loc.conn = c;
- c->ctx = ctx;
- c->sa = sa;
- c->birth_time = current_time;
- c->expire_time = current_time + EXPIRE_TIME;
-
- set_close_on_exec(sock);
-
- c->loc.io_class = NULL;
-
- c->rem.io_class = &io_socket;
- c->rem.chan.sock = sock;
-
- /* Set IO buffers */
- c->loc.io.buf = (char *) (c + 1);
- c->rem.io.buf = c->loc.io.buf + ctx->io_buf_size;
- c->loc.io.size = c->rem.io.size = ctx->io_buf_size;
-
-#if !defined(NO_SSL)
- if (ssl) {
- c->rem.io_class = &io_ssl;
- c->rem.chan.ssl.sock = sock;
- c->rem.chan.ssl.ssl = ssl;
- ssl_handshake(&c->rem);
- }
-#endif /* NO_SSL */
-
- EnterCriticalSection(&ctx->mutex);
- LL_TAIL(&ctx->connections, &c->link);
- ctx->nactive++;
- LeaveCriticalSection(&ctx->mutex);
-
- DBG(("%s:%hu connected (socket %d)",
- inet_ntoa(* (struct in_addr *) &sa.u.sin.sin_addr.s_addr),
- ntohs(sa.u.sin.sin_port), sock));
- }
-}
-
-int
-shttpd_active(struct shttpd_ctx *ctx)
-{
- return (ctx->nactive);
-}
-
-/*
- * Setup a listening socket on given port. Return opened socket or -1
- */
-int
-shttpd_listen(struct shttpd_ctx *ctx, int port)
-{
- struct listener *l;
- int sock;
-
- if ((sock = open_listening_port(port)) == -1) {
- } else if ((l = calloc(1, sizeof(*l))) == NULL) {
- (void) closesocket(sock);
- } else {
- l->sock = sock;
- l->ctx = ctx;
- LL_TAIL(&listeners, &l->link);
- DBG(("shttpd_listen: added socket %d", sock));
- }
-
- return (sock);
-}
-
-int
-shttpd_accept(int lsn_sock, int milliseconds)
-{
- struct timeval tv;
- struct usa sa;
- fd_set read_set;
- int sock = -1;
-
- tv.tv_sec = milliseconds / 1000;
- tv.tv_usec = milliseconds % 1000;
- sa.len = sizeof(sa.u.sin);
- FD_ZERO(&read_set);
- FD_SET(lsn_sock, &read_set);
-
- if (select(lsn_sock + 1, &read_set, NULL, NULL, &tv) == 1)
- sock = accept(lsn_sock, &sa.u.sa, &sa.len);
-
- return (sock);
-}
-
-static void
-read_stream(struct stream *stream)
-{
- int n, len;
-
- len = io_space_len(&stream->io);
- assert(len > 0);
-
- /* Do not read more that needed */
- if (stream->content_len > 0 &&
- stream->io.total + len > stream->content_len)
- len = stream->content_len - stream->io.total;
-
- /* Read from underlying channel */
- n = stream->nread_last = stream->io_class->read(stream,
- io_space(&stream->io), len);
-
- if (n > 0)
- io_inc_head(&stream->io, n);
- else if (n == -1 && (ERRNO == EINTR || ERRNO == EWOULDBLOCK))
- n = n; /* Ignore EINTR and EAGAIN */
- else if (!(stream->flags & FLAG_DONT_CLOSE))
- stop_stream(stream);
-
- DBG(("read_stream (%d %s): read %d/%d/%lu bytes (errno %d)",
- stream->conn->rem.chan.sock,
- stream->io_class ? stream->io_class->name : "(null)",
- n, len, (unsigned long) stream->io.total, ERRNO));
-
- /*
- * Close the local stream if everything was read
- * XXX We do not close the remote stream though! It may be
- * a POST data completed transfer, we do not want the socket
- * to be closed.
- */
- if (stream->content_len > 0 && stream == &stream->conn->loc) {
- assert(stream->io.total <= stream->content_len);
- if (stream->io.total == stream->content_len)
- stop_stream(stream);
- }
-
- stream->conn->expire_time = current_time + EXPIRE_TIME;
-}
-
-static void
-write_stream(struct stream *from, struct stream *to)
-{
- int n, len;
-
- len = io_data_len(&from->io);
- assert(len > 0);
-
- /* TODO: should be assert on CAN_WRITE flag */
- n = to->io_class->write(to, io_data(&from->io), len);
- to->conn->expire_time = current_time + EXPIRE_TIME;
- DBG(("write_stream (%d %s): written %d/%d bytes (errno %d)",
- to->conn->rem.chan.sock,
- to->io_class ? to->io_class->name : "(null)", n, len, ERRNO));
-
- if (n > 0)
- io_inc_tail(&from->io, n);
- else if (n == -1 && (ERRNO == EINTR || ERRNO == EWOULDBLOCK))
- n = n; /* Ignore EINTR and EAGAIN */
- else if (!(to->flags & FLAG_DONT_CLOSE))
- stop_stream(to);
-}
-
-
-static void
-disconnect(struct conn *c)
-{
- static const struct vec ka = {"keep-alive", 10};
- int dont_close;
-
- DBG(("Disconnecting %d (%.*s)", c->rem.chan.sock,
- c->ch.connection.v_vec.len, c->ch.connection.v_vec.ptr));
-
-#if !defined(_WIN32) || defined(NO_GUI)
- if (c->ctx->access_log != NULL)
-#endif /* _WIN32 */
- log_access(c->ctx->access_log, c);
-
- /* In inetd mode, exit if request is finished. */
- if (c->ctx->inetd_mode)
- exit(0);
-
- if (c->loc.io_class != NULL && c->loc.io_class->close != NULL)
- c->loc.io_class->close(&c->loc);
-
- /*
- * Check the "Connection: " header before we free c->request
- * If it its 'keep-alive', then do not close the connection
- */
- dont_close = c->ch.connection.v_vec.len >= ka.len &&
- !my_strncasecmp(ka.ptr, c->ch.connection.v_vec.ptr, ka.len);
-
- if (c->request)
- free(c->request);
- if (c->uri)
- free(c->uri);
-
- /* Handle Keep-Alive */
- dont_close = 0;
- if (dont_close) {
- c->loc.io_class = NULL;
- c->loc.flags = c->rem.flags = 0;
- c->query = c->request = c->uri = c->path_info = NULL;
- c->mime_type = NULL;
- (void) memset(&c->ch, 0, sizeof(c->ch));
- io_clear(&c->rem.io);
- io_clear(&c->loc.io);
- c->rem.io.total = c->loc.io.total = 0;
- } else {
- if (c->rem.io_class != NULL)
- c->rem.io_class->close(&c->rem);
-
- EnterCriticalSection(&c->ctx->mutex);
- LL_DEL(&c->link);
- c->ctx->nactive--;
- assert(c->ctx->nactive >= 0);
- LeaveCriticalSection(&c->ctx->mutex);
-
- free(c);
- }
-}
-
-static void
-add_to_set(int fd, fd_set *set, int *max_fd)
-{
- FD_SET(fd, set);
- if (fd > *max_fd)
- *max_fd = fd;
-}
-
-/*
- * One iteration of server loop. This is the core of the data exchange.
- */
-void
-shttpd_poll(struct shttpd_ctx *ctx, int milliseconds)
-{
- struct llhead *lp, *tmp;
- struct listener *l;
- struct conn *c;
- struct timeval tv; /* Timeout for select() */
- fd_set read_set, write_set;
- int sock, max_fd = -1, msec = milliseconds;
- struct usa sa;
-
- current_time = time(0);
- FD_ZERO(&read_set);
- FD_ZERO(&write_set);
-
- /* Add listening sockets to the read set */
- LL_FOREACH(&listeners, lp) {
- l = LL_ENTRY(lp, struct listener, link);
- FD_SET(l->sock, &read_set);
- if (l->sock > max_fd)
- max_fd = l->sock;
- DBG(("FD_SET(%d) (listening)", l->sock));
- }
-
- /* Multiplex streams */
- LL_FOREACH(&ctx->connections, lp) {
- c = LL_ENTRY(lp, struct conn, link);
-
- /* If there is a space in remote IO, check remote socket */
- if (io_space_len(&c->rem.io))
- add_to_set(c->rem.chan.fd, &read_set, &max_fd);
-
-#if !defined(NO_CGI)
- /*
- * If there is a space in local IO, and local endpoint is
- * CGI, check local socket for read availability
- */
- if (io_space_len(&c->loc.io) && (c->loc.flags & FLAG_R) &&
- c->loc.io_class == &io_cgi)
- add_to_set(c->loc.chan.fd, &read_set, &max_fd);
-
- /*
- * If there is some data read from remote socket, and
- * local endpoint is CGI, check local for write availability
- */
- if (io_data_len(&c->rem.io) && (c->loc.flags & FLAG_W) &&
- c->loc.io_class == &io_cgi)
- add_to_set(c->loc.chan.fd, &write_set, &max_fd);
-#endif /* NO_CGI */
-
- /*
- * If there is some data read from local endpoint, check the
- * remote socket for write availability
- */
- if (io_data_len(&c->loc.io))
- add_to_set(c->rem.chan.fd, &write_set, &max_fd);
-
- if (io_space_len(&c->loc.io) && (c->loc.flags & FLAG_R) &&
- (c->loc.flags & FLAG_ALWAYS_READY))
- msec = 0;
-
- if (io_data_len(&c->rem.io) && (c->loc.flags & FLAG_W) &&
- (c->loc.flags & FLAG_ALWAYS_READY))
- msec = 0;
- }
-
- tv.tv_sec = msec / 1000;
- tv.tv_usec = msec % 1000;
-
- /* Check IO readiness */
- if (select(max_fd + 1, &read_set, &write_set, NULL, &tv) < 0) {
-#ifdef _WIN32
- /*
- * On windows, if read_set and write_set are empty,
- * select() returns "Invalid parameter" error
- * (at least on my Windows XP Pro). So in this case,
- * we sleep here.
- */
- Sleep(milliseconds);
-#endif /* _WIN32 */
- DBG(("select: %d", ERRNO));
- return;
- }
-
- /* Check for incoming connections on listener sockets */
- LL_FOREACH(&listeners, lp) {
- l = LL_ENTRY(lp, struct listener, link);
- if (!FD_ISSET(l->sock, &read_set))
- continue;
- do {
- sa.len = sizeof(sa.u.sin);
- if ((sock = accept(l->sock, &sa.u.sa, &sa.len)) != -1) {
-#if defined(_WIN32)
- shttpd_add_socket(ctx, sock);
-#else
- if (sock < FD_SETSIZE) {
- shttpd_add_socket(ctx, sock);
- } else {
- elog(E_LOG, NULL,
- "shttpd_poll: ctx %p: disarding "
- "socket %d, too busy", ctx, sock);
- (void) closesocket(sock);
- }
-#endif /* _WIN32 */
- }
- } while (sock != -1);
- }
-
- /* Process all connections */
- LL_FOREACH_SAFE(&ctx->connections, lp, tmp) {
- c = LL_ENTRY(lp, struct conn, link);
-
- /* Read from remote end if it is ready */
- if (FD_ISSET(c->rem.chan.fd, &read_set) &&
- io_space_len(&c->rem.io))
- read_stream(&c->rem);
-
- /* If the request is not parsed yet, do so */
- if (!(c->rem.flags & FLAG_HEADERS_PARSED))
- parse_http_request(c);
-
- DBG(("loc: %u [%.*s]", io_data_len(&c->loc.io),
- io_data_len(&c->loc.io), io_data(&c->loc.io)));
- DBG(("rem: %u [%.*s]", io_data_len(&c->rem.io),
- io_data_len(&c->rem.io), io_data(&c->rem.io)));
-
- /* Read from the local end if it is ready */
- if (io_space_len(&c->loc.io) &&
- ((c->loc.flags & FLAG_ALWAYS_READY)
-
-#if !defined(NO_CGI)
- ||(c->loc.io_class == &io_cgi &&
- FD_ISSET(c->loc.chan.fd, &read_set))
-#endif /* NO_CGI */
- ))
- read_stream(&c->loc);
-
- if (io_data_len(&c->rem.io) > 0 && (c->loc.flags & FLAG_W) &&
- c->loc.io_class != NULL && c->loc.io_class->write != NULL)
- write_stream(&c->rem, &c->loc);
-
- if (io_data_len(&c->loc.io) > 0 && c->rem.io_class != NULL)
- write_stream(&c->loc, &c->rem);
-
- if (c->rem.nread_last > 0)
- c->ctx->in += c->rem.nread_last;
- if (c->loc.nread_last > 0)
- c->ctx->out += c->loc.nread_last;
-
- /* Check whether we should close this connection */
- if ((current_time > c->expire_time) ||
- (c->rem.flags & FLAG_CLOSED) ||
- ((c->loc.flags & FLAG_CLOSED) && !io_data_len(&c->loc.io)))
- disconnect(c);
- }
-}
-
-/*
- * Deallocate shttpd object, free up the resources
- */
-void
-shttpd_fini(struct shttpd_ctx *ctx)
-{
- struct llhead *lp, *tmp;
- struct mime_type_link *mtl;
- struct conn *c;
- struct listener *l;
- struct registered_uri *ruri;
-
- /* Free configured mime types */
- LL_FOREACH_SAFE(&ctx->mime_types, lp, tmp) {
- mtl = LL_ENTRY(lp, struct mime_type_link, link);
- free(mtl->mime);
- free(mtl->ext);
- free(mtl);
- }
-
-#if 0
- struct opt *opt;
- /* Free strdup-ed temporary vars */
- for (opt = options; opt->sw != 0; opt++)
- if (opt->tmp) {
- free(opt->tmp);
- opt->tmp = NULL;
- }
-#endif
-
- /* Free all connections */
- LL_FOREACH_SAFE(&ctx->connections, lp, tmp) {
- c = LL_ENTRY(lp, struct conn, link);
- disconnect(c);
- }
-
- /* Free registered URIs (must be done after disconnect()) */
- LL_FOREACH_SAFE(&ctx->registered_uris, lp, tmp) {
- ruri = LL_ENTRY(lp, struct registered_uri, link);
- free((void *)ruri->uri);
- free(ruri);
- }
-
- /* Free listener sockets for this context */
- LL_FOREACH_SAFE(&listeners, lp, tmp) {
- l = LL_ENTRY(lp, struct listener, link);
- (void) closesocket(l->sock);
- LL_DEL(&l->link);
- free(l);
- }
-
- if (ctx->access_log) (void) fclose(ctx->access_log);
- if (ctx->error_log) (void) fclose(ctx->error_log);
- if (ctx->put_auth_file) free(ctx->put_auth_file);
- if (ctx->document_root) free(ctx->document_root);
- if (ctx->index_files) free(ctx->index_files);
- if (ctx->aliases) free(ctx->aliases);
-#if !defined(NO_CGI)
- if (ctx->cgi_vars) free(ctx->cgi_vars);
- if (ctx->cgi_extensions) free(ctx->cgi_extensions);
- if (ctx->cgi_interpreter) free(ctx->cgi_interpreter);
-#endif /* NO_CGI */
- if (ctx->auth_realm) free(ctx->auth_realm);
- if (ctx->global_passwd_file) free(ctx->global_passwd_file);
- if (ctx->uid) free(ctx->uid);
-
- /* TODO: free SSL context */
-
- free(ctx);
-}
diff --git a/cpukit/shttpd/shttpd.h b/cpukit/shttpd/shttpd.h
deleted file mode 100644
index 8ac1dd8ff4..0000000000
--- a/cpukit/shttpd/shttpd.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * $Id$
- */
-
-#ifndef SHTTPD_HEADER_INCLUDED
-#define SHTTPD_HEADER_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/*
- * This structure is passed to the user callback function
- */
-struct shttpd_arg {
- void *priv; /* Private! Do not touch! */
- void *state; /* User state */
- void *user_data; /* User-defined data */
-
- struct {
- char *buf; /* Buffer pointer */
- int len; /* Size of a buffer */
- int num_bytes; /* Bytes processed by callback */
- } in, out; /* POST data buffer (in) and output buffer (out) */
-
- unsigned int flags;
-#define SHTTPD_END_OF_OUTPUT 1
-#define SHTTPD_CONNECTION_ERROR 2
-#define SHTTPD_MORE_POST_DATA 4
-#define SHTTPD_POST_BUFFER_FULL 8
-};
-
-/*
- * User callback function. Called when certain registered URLs have been
- * requested. These are the requirements to the callback function:
- *
- * 1. it must copy data into 'out_buf', not more than 'out_buf_max_len' bytes,
- * and record how many bytes are copied, into 'out_buf_written_len'
- * 2. it must not block the execution
- * 3. it must set 'last' in shttpd_arg to 1 if there is no more data
- * 4. for POST requests, it must process the incoming data (in_buf), and
- * set 'in_buf_read_len', which is how many bytes of POST data is read
- * and can be discarded by SHTTPD.
- */
-typedef void (*shttpd_callback_t)(struct shttpd_arg *);
-
-/*
- * shttpd_init Initialize shttpd context. Parameters: configuration
- * file name (may be NULL), then NULL-terminated
- * sequence of pairs "option_name", "option_value".
- * shttpd_init2 Same as shttpd_init, but the list of option/value
- * pairs is passed in arrays
- * shttpd_fini Dealocate the context
- * shttpd_register_uri Setup the callback function for specified URL.
- * shttpd_protect_uri Associate authorization file with an URL.
- * shttpd_add_mime_type Add mime type
- * shtppd_listen Setup a listening socket in the SHTTPD context
- * shttpd_poll Do connections processing
- * shttpd_version return string with SHTTPD version
- * shttpd_get_var Return POST/GET variable value for given variable name.
- * shttpd_get_header return value of the specified HTTP header
- * shttpd_get_env return string values for the following
- * pseudo-variables: "REQUEST_METHOD", "REQUEST_URI",
- * "REMOTE_USER" and "REMOTE_ADDR".
- */
-
-struct shttpd_ctx;
-
-struct shttpd_ctx *shttpd_init(const char *config_file, ...);
-struct shttpd_ctx *shttpd_init2(const char *config_file,
- char *names[], char *values[], size_t num_options);
-void shttpd_fini(struct shttpd_ctx *);
-void shttpd_add_mime_type(struct shttpd_ctx *,
- const char *ext, const char *mime);
-int shttpd_listen(struct shttpd_ctx *ctx, int port);
-void shttpd_register_uri(struct shttpd_ctx *ctx,
- const char *uri, shttpd_callback_t callback, void *user_data);
-void shttpd_protect_uri(struct shttpd_ctx *ctx,
- const char *uri, const char *file);
-void shttpd_poll(struct shttpd_ctx *, int milliseconds);
-const char *shttpd_version(void);
-int shttpd_get_var(const char *var, const char *buf, int buf_len,
- char *value, int value_len);
-const char *shttpd_get_header(struct shttpd_arg *, const char *);
-const char *shttpd_get_env(struct shttpd_arg *, const char *);
-void shttpd_get_http_version(struct shttpd_arg *,
- unsigned long *major, unsigned long *minor);
-size_t shttpd_printf(struct shttpd_arg *, const char *fmt, ...);
-void shttpd_handle_error(struct shttpd_ctx *ctx, int status,
- shttpd_callback_t func, void *data);
-
-/*
- * The following three functions are for applications that need to
- * load-balance the connections on their own. Many threads may be spawned
- * with one SHTTPD context per thread. Boss thread may only wait for
- * new connections by means of shttpd_accept(). Then it may scan thread
- * pool for the idle thread by means of shttpd_active(), and add new
- * connection to the context by means of shttpd_add().
- */
-void shttpd_add_socket(struct shttpd_ctx *, int sock);
-int shttpd_accept(int lsn_sock, int milliseconds);
-int shttpd_active(struct shttpd_ctx *);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* SHTTPD_HEADER_INCLUDED */
diff --git a/cpukit/shttpd/ssl.h b/cpukit/shttpd/ssl.h
deleted file mode 100644
index 5aeae4a99b..0000000000
--- a/cpukit/shttpd/ssl.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-/*
- * Snatched from OpenSSL includes. I put the prototypes here to be independent
- * from the OpenSSL source installation. Having this, shttpd + SSL can be
- * built on any system with binary SSL libraries installed.
- */
-
-typedef struct ssl_st SSL;
-typedef struct ssl_method_st SSL_METHOD;
-typedef struct ssl_ctx_st SSL_CTX;
-
-#define SSL_ERROR_WANT_READ 2
-#define SSL_ERROR_WANT_WRITE 3
-#define SSL_FILETYPE_PEM 1
-
-/*
- * Dynamically loaded SSL functionality
- */
-struct ssl_func {
- const char *name; /* SSL function name */
- union variant ptr; /* Function pointer */
-};
-
-extern struct ssl_func ssl_sw[];
-
-#define FUNC(x) ssl_sw[x].ptr.v_func
-
-#define SSL_free(x) (* (void (*)(SSL *)) FUNC(0))(x)
-#define SSL_accept(x) (* (int (*)(SSL *)) FUNC(1))(x)
-#define SSL_connect(x) (* (int (*)(SSL *)) FUNC(2))(x)
-#define SSL_read(x,y,z) (* (int (*)(SSL *, void *, int)) FUNC(3))((x),(y),(z))
-#define SSL_write(x,y,z) \
- (* (int (*)(SSL *, const void *,int)) FUNC(4))((x), (y), (z))
-#define SSL_get_error(x,y)(* (int (*)(SSL *, int)) FUNC(5))((x), (y))
-#define SSL_set_fd(x,y) (* (int (*)(SSL *, int)) FUNC(6))((x), (y))
-#define SSL_new(x) (* (SSL * (*)(SSL_CTX *)) FUNC(7))(x)
-#define SSL_CTX_new(x) (* (SSL_CTX * (*)(SSL_METHOD *)) FUNC(8))(x)
-#define SSLv23_server_method() (* (SSL_METHOD * (*)(void)) FUNC(9))()
-#define SSL_library_init() (* (int (*)(void)) FUNC(10))()
-#define SSL_CTX_use_PrivateKey_file(x,y,z) (* (int (*)(SSL_CTX *, \
- const char *, int)) FUNC(11))((x), (y), (z))
-#define SSL_CTX_use_certificate_file(x,y,z) (* (int (*)(SSL_CTX *, \
- const char *, int)) FUNC(12))((x), (y), (z))
diff --git a/cpukit/shttpd/standalone.c b/cpukit/shttpd/standalone.c
deleted file mode 100644
index 40e7ef82b8..0000000000
--- a/cpukit/shttpd/standalone.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-static const char *config_file = CONFIG;
-static int exit_flag;
-
-static void
-signal_handler(int sig_num)
-{
- switch (sig_num) {
-#ifndef _WIN32
- case SIGCHLD:
- while (waitpid(-1, &sig_num, WNOHANG) > 0) ;
- break;
-#endif /* !_WIN32 */
- default:
- exit_flag = sig_num;
- break;
- }
-}
-
-int
-main(int argc, char *argv[])
-{
- struct shttpd_ctx *ctx;
-
- current_time = time(NULL);
- if (argc > 1 && argv[argc - 2][0] != '-' && argv[argc - 1][0] != '-')
- config_file = argv[argc - 1];
-
-#if !defined(NO_AUTH)
- if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'A') {
- if (argc != 6)
- usage(argv[0]);
- exit(edit_passwords(argv[2],argv[3],argv[4],argv[5]));
- }
-#endif /* NO_AUTH */
-
- ctx = init_from_argc_argv(config_file, argc, argv);
-
- if (ctx->inetd_mode)
- (void) freopen("/dev/null", "a", stderr);
-
- if (ctx->inetd_mode)
- shttpd_add_socket(ctx, fileno(stdin));
- else if (shttpd_listen(ctx, ctx->port) == -1)
- elog(E_FATAL, NULL, "Cannot open socket on port %d", ctx->port);
-
-#ifndef _WIN32
- /* Switch to alternate UID, it is safe now, after shttpd_listen() */
- if (ctx->uid != NULL) {
- struct passwd *pw;
-
- if ((pw = getpwnam(ctx->uid)) == NULL)
- elog(E_FATAL, 0, "main: unknown user [%s]", ctx->uid);
- else if (setgid(pw->pw_gid) == -1)
- elog(E_FATAL, NULL, "main: setgid(%s): %s",
- ctx->uid, strerror(errno));
- else if (setuid(pw->pw_uid) == -1)
- elog(E_FATAL, NULL, "main: setuid(%s): %s",
- ctx->uid, strerror(errno));
- }
- (void) signal(SIGCHLD, signal_handler);
- (void) signal(SIGPIPE, SIG_IGN);
-#endif /* _WIN32 */
-
- (void) signal(SIGTERM, signal_handler);
- (void) signal(SIGINT, signal_handler);
-
- elog(E_LOG, NULL, "shttpd %s started on port %d, serving %s",
- VERSION, ctx->port, ctx->document_root);
-
- while (exit_flag == 0)
- shttpd_poll(ctx, 5000);
-
- elog(E_LOG, NULL, "%d requests %.2lf Mb in %.2lf Mb out. "
- "Exit on signal %d", ctx->nrequests, (double) (ctx->in / 1048576),
- (double) ctx->out / 1048576, exit_flag);
-
- shttpd_fini(ctx);
-
- return (EXIT_SUCCESS);
-}
diff --git a/cpukit/shttpd/std_includes.h b/cpukit/shttpd/std_includes.h
deleted file mode 100644
index f61503ce69..0000000000
--- a/cpukit/shttpd/std_includes.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#ifndef STD_HEADERS_INCLUDED
-#define STD_HEADERS_INCLUDED
-
-#ifndef _WIN32_WCE /* Some ANSI #includes are not available on Windows CE */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <errno.h>
-#include <signal.h>
-#include <fcntl.h>
-#endif /* _WIN32_WCE */
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <wchar.h>
-
-#if defined(_WIN32) /* Windows specific */
-#include "compat_win32.h"
-#elif defined(__rtems__) /* RTEMS specific */
-#include "compat_rtems.h"
-#else /* UNIX specific */
-#include "compat_unix.h"
-#endif /* _WIN32 */
-
-#endif /* STD_HEADERS_INCLUDED */
diff --git a/cpukit/shttpd/string.c b/cpukit/shttpd/string.c
deleted file mode 100644
index d77f32c417..0000000000
--- a/cpukit/shttpd/string.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
- * All rights reserved
- *
- * "THE BEER-WARE LICENSE" (Revision 42):
- * Sergey Lyubka wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.
- */
-
-#include "defs.h"
-
-#ifndef HAVE_STRLCPY
-void
-my_strlcpy(register char *dst, register const char *src, size_t n)
-{
- for (; *src != '\0' && n > 1; n--)
- *dst++ = *src++;
- *dst = '\0';
-}
-#endif
-
-#ifndef HAVE_STRNCASECMP
-int
-my_strncasecmp(const char *str1, const char *str2, size_t len)
-{
- register const unsigned char *s1 = (unsigned char *) str1,
- *s2 = (unsigned char *) str2, *e;
- int ret;
-
- for (e = s1 + len - 1; s1 < e && *s1 != '\0' && *s2 != '\0' &&
- tolower(*s1) == tolower(*s2); s1++, s2++) ;
- ret = tolower(*s1) - tolower(*s2);
-
- return (ret);
-}
-#endif
-
-#ifndef HAVE_STRNDUP
-char *
-my_strndup(const char *ptr, size_t len)
-{
- char *p;
-
- if ((p = malloc(len + 1)) != NULL)
- my_strlcpy(p, ptr, len + 1);
-
- return (p);
-
-}
-#endif
-
-#ifndef HAVE_STRDUP
-char *
-my_strdup(const char *str)
-{
- return (my_strndup(str, strlen(str)));
-}
-#endif
-
-/*
- * Sane snprintf(). Acts like snprintf(), but never return -1 or the
- * value bigger than supplied buffer.
- * Thanks Adam Zeldis to pointing snprintf()-caused vulnerability
- * in his audit report.
- */
-int
-my_snprintf(char *buf, size_t buflen, const char *fmt, ...)
-{
- va_list ap;
- int n;
-
- if (buflen == 0)
- return (0);
-
- va_start(ap, fmt);
- n = vsnprintf(buf, buflen, fmt, ap);
- va_end(ap);
-
- if (n < 0 || (size_t) n >= buflen)
- n = buflen - 1;
- buf[n] = '\0';
-
- return (n);
-}