This commit is contained in:
Ralf Corsepius committed 2010-06-09 08:06:08 +00:00
1 parent c7bdd7749c
commit dc35201765
36 files changed
-8068

No files matched your search

-12
View File
@@ -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])
])
-2
View File
@@ -1,2 +0,0 @@
Makefile.in
Makefile
-70
View File
@@ -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
-50
View File
@@ -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
File diff suppressed because it is too large. Load diff
-292
View File
File diff suppressed because it is too large. Load diff
-200
View File
@@ -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
-69
View File
@@ -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
-123
View File
@@ -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 */
-33
View File
@@ -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)
File diff suppressed because it is too large. Load diff
-93
View File
@@ -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);
File diff suppressed because it is too large. Load diff
-145
View File
@@ -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 */
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
-97
View File
@@ -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 */
-124
View File
@@ -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
};
-143
View File
@@ -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
};
File diff suppressed because it is too large. Load diff
-156
View File
@@ -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
};
-41
View File
@@ -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
};
-85
View File
@@ -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 */
-59
View File
@@ -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 */
-141
View File
@@ -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 */
}
-249
View File
File diff suppressed because it is too large. Load diff
-24
View File
@@ -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 */
-108
View File
@@ -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);
}
-39
View File
@@ -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
-135
View File
@@ -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 .
File diff suppressed because it is too large. Load diff
-129
View File
@@ -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 */
-52
View File
@@ -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))
-92
View File
@@ -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);
}
-41
View File
@@ -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 */
-85
View File
@@ -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);
}