diff --git a/qse/include/qse/cmn/fio.h b/qse/include/qse/cmn/fio.h index 9fd2ac0b..c407541e 100644 --- a/qse/include/qse/cmn/fio.h +++ b/qse/include/qse/cmn/fio.h @@ -44,6 +44,9 @@ enum qse_fio_flag_t /** don't close an I/O handle in qse_fio_fini() and qse_fio_close() */ QSE_FIO_NOCLOSE = (1 << 10), + /** treat the path name as a multi-byte string */ + QSE_FIO_MBSPATH = (1 << 11), + /* normal open flags */ QSE_FIO_READ = (1 << 14), QSE_FIO_WRITE = (1 << 15), diff --git a/qse/include/qse/cmn/mux.h b/qse/include/qse/cmn/mux.h index b35012a7..f0860e0d 100644 --- a/qse/include/qse/cmn/mux.h +++ b/qse/include/qse/cmn/mux.h @@ -50,7 +50,8 @@ enum qse_mux_errnum_t typedef enum qse_mux_errnum_t qse_mux_errnum_t; #if defined(_WIN32) - typedef qse_uintptr_t qse_mux_hnd_t; + /*TODO: typedef qse_uintptr_t qse_mux_hnd_t;*/ + typedef int qse_mux_hnd_t; #elif defined(__OS2__) typedef int qse_mux_hnd_t; #elif defined(__DOS__) @@ -82,36 +83,36 @@ struct qse_mux_evt_t extern "C" { #endif -qse_mux_t* qse_mux_open ( +QSE_EXPORT qse_mux_t* qse_mux_open ( qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_mux_evtfun_t evtfun, qse_size_t capahint ); -void qse_mux_close ( +QSE_EXPORT void qse_mux_close ( qse_mux_t* mux ); -qse_mmgr_t* qse_mux_getmmgr ( +QSE_EXPORT qse_mmgr_t* qse_mux_getmmgr ( qse_mux_t* mux ); -void* qse_mux_getxtn ( +QSE_EXPORT void* qse_mux_getxtn ( qse_mux_t* mux ); -int qse_mux_insert ( +QSE_EXPORT int qse_mux_insert ( qse_mux_t* mux, const qse_mux_evt_t* evt ); -int qse_mux_delete ( +QSE_EXPORT int qse_mux_delete ( qse_mux_t* mux, const qse_mux_evt_t* evt ); -int qse_mux_poll ( +QSE_EXPORT int qse_mux_poll ( qse_mux_t* mux, const qse_ntime_t* tmout ); diff --git a/qse/include/qse/cmn/time.h b/qse/include/qse/cmn/time.h index 6a56cdf4..0d24b4e0 100644 --- a/qse/include/qse/cmn/time.h +++ b/qse/include/qse/cmn/time.h @@ -33,6 +33,11 @@ #define QSE_EPOCH_DAY (1) #define QSE_EPOCH_WDAY (4) +/* windows specific epoch time */ +#define QSE_EPOCH_YEAR_WIN (1601) +#define QSE_EPOCH_MON_WIN (1) +#define QSE_EPOCH_DAY_WIN (1) + #define QSE_BTIME_YEAR_BASE (1900) #define QSE_DAYS_PER_NORMYEAR (365) diff --git a/qse/include/qse/net/httpd.h b/qse/include/qse/net/httpd.h index 1393905a..e0d1f965 100644 --- a/qse/include/qse/net/httpd.h +++ b/qse/include/qse/net/httpd.h @@ -147,9 +147,6 @@ struct qse_httpd_scb_t struct { - int (*executable) ( - qse_httpd_t* httpd, const qse_mchar_t* path); - int (*stat) ( qse_httpd_t* httpd, const qse_mchar_t* path, qse_httpd_stat_t* stat); diff --git a/qse/lib/cmn/fio.c b/qse/lib/cmn/fio.c index 730aa53a..a7617576 100644 --- a/qse/lib/cmn/fio.c +++ b/qse/lib/cmn/fio.c @@ -234,9 +234,10 @@ int qse_fio_init ( { qse_ntime_t now; - if (flags & QSE_FIO_HANDLE) + if (flags & (QSE_FIO_HANDLE | QSE_FIO_MBSPATH)) { - /* QSE_FIO_TEMPORARY and QSE_FIO_HANDLE are mutually exclusive */ + /* QSE_FIO_TEMPORARY and QSE_FIO_HANDLE/QSE_FIO_MBSPATH + * are mutually exclusive */ fio->errnum = QSE_FIO_EINVAL; return -1; } @@ -364,11 +365,22 @@ int qse_fio_init ( if (flags & QSE_FIO_SEQUENTIAL) flag_and_attr |= FILE_FLAG_SEQUENTIAL_SCAN; - handle = CreateFile ( - path, desired_access, share_mode, - QSE_NULL, /* set noinherit by setting no secattr */ - creation_disposition, flag_and_attr, 0 - ); + if (flags & QSE_FIO_MBSPATH) + { + handle = CreateFileA ( + (const qse_mchar_t*)path, desired_access, share_mode, + QSE_NULL, /* set noinherit by setting no secattr */ + creation_disposition, flag_and_attr, 0 + ); + } + else + { + handle = CreateFile ( + path, desired_access, share_mode, + QSE_NULL, /* set noinherit by setting no secattr */ + creation_disposition, flag_and_attr, 0 + ); + } if (handle == INVALID_HANDLE_VALUE) { DWORD e = GetLastError(); @@ -388,11 +400,22 @@ int qse_fio_init ( desired_access |= GENERIC_WRITE; } - handle = CreateFile ( - path, desired_access, share_mode, - QSE_NULL, /* set noinherit by setting no secattr */ - creation_disposition, flag_and_attr, 0 - ); + if (flags & QSE_FIO_MBSPATH) + { + handle = CreateFileA ( + path, desired_access, share_mode, + QSE_NULL, /* set noinherit by setting no secattr */ + creation_disposition, flag_and_attr, 0 + ); + } + else + { + handle = CreateFile ( + path, desired_access, share_mode, + QSE_NULL, /* set noinherit by setting no secattr */ + creation_disposition, flag_and_attr, 0 + ); + } if (handle == INVALID_HANDLE_VALUE) { if (flags & QSE_FIO_TEMPORARY) goto retry_temporary; @@ -442,25 +465,32 @@ int qse_fio_init ( qse_size_t wl, ml; int px; - path_mb = path_mb_buf; - ml = QSE_COUNTOF(path_mb_buf); - px = qse_wcstombs (path, &wl, path_mb, &ml); - if (px == -2) + if (flags & QSE_FIO_MBSPATH) { - /* the static buffer is too small. - * dynamically allocate a buffer */ - path_mb = qse_wcstombsdup (path, QSE_NULL, mmgr); - if (path_mb == QSE_NULL) + path_mb = (qse_mchar_t*)path; + } + else + { + path_mb = path_mb_buf; + ml = QSE_COUNTOF(path_mb_buf); + px = qse_wcstombs (path, &wl, path_mb, &ml); + if (px == -2) { - fio->errnum = QSE_FIO_ENOMEM; + /* the static buffer is too small. + * dynamically allocate a buffer */ + path_mb = qse_wcstombsdup (path, QSE_NULL, mmgr); + if (path_mb == QSE_NULL) + { + fio->errnum = QSE_FIO_ENOMEM; + return -1; + } + } + else if (px <= -1) + { + fio->errnum = QSE_FIO_EINVAL; return -1; } } - else if (px <= -1) - { - fio->errnum = QSE_FIO_EINVAL; - return -1; - } #endif zero.ulLo = 0; @@ -651,25 +681,32 @@ int qse_fio_init ( qse_size_t wl, ml; int px; - path_mb = path_mb_buf; - ml = QSE_COUNTOF(path_mb_buf); - px = qse_wcstombs (path, &wl, path_mb, &ml); - if (px == -2) + if (flags & QSE_FIO_MBSPATH) { - /* the static buffer is too small. - * allocate a buffer */ - path_mb = qse_wcstombsdup (path, mmgr); - if (path_mb == QSE_NULL) + path_mb = (qse_mchar_t*)path; + } + else + { + path_mb = path_mb_buf; + ml = QSE_COUNTOF(path_mb_buf); + px = qse_wcstombs (path, &wl, path_mb, &ml); + if (px == -2) { - fio->errnum = QSE_FIO_ENOMEM; + /* the static buffer is too small. + * allocate a buffer */ + path_mb = qse_wcstombsdup (path, mmgr); + if (path_mb == QSE_NULL) + { + fio->errnum = QSE_FIO_ENOMEM; + return -1; + } + } + else if (px <= -1) + { + fio->errnum = QSE_FIO_EINVAL; return -1; } } - else if (px <= -1) - { - fio->errnum = QSE_FIO_EINVAL; - return -1; - } #endif rab = (struct RAB*)QSE_MMGR_ALLOC ( @@ -775,25 +812,32 @@ int qse_fio_init ( qse_size_t wl, ml; int px; - path_mb = path_mb_buf; - ml = QSE_COUNTOF(path_mb_buf); - px = qse_wcstombs (path, &wl, path_mb, &ml); - if (px == -2) + if (flags & QSE_FIO_MBSPATH) { - /* the static buffer is too small. - * allocate a buffer */ - path_mb = qse_wcstombsdup (path, QSE_NULL, mmgr); - if (path_mb == QSE_NULL) + path_mb = (qse_mchar_t*)path; + } + else + { + path_mb = path_mb_buf; + ml = QSE_COUNTOF(path_mb_buf); + px = qse_wcstombs (path, &wl, path_mb, &ml); + if (px == -2) { - fio->errnum = QSE_FIO_ENOMEM; + /* the static buffer is too small. + * allocate a buffer */ + path_mb = qse_wcstombsdup (path, QSE_NULL, mmgr); + if (path_mb == QSE_NULL) + { + fio->errnum = QSE_FIO_ENOMEM; + return -1; + } + } + else if (px <= -1) + { + fio->errnum = QSE_FIO_EINVAL; return -1; } } - else if (px <= -1) - { - fio->errnum = QSE_FIO_EINVAL; - return -1; - } #endif /* * rwa -> RDWR | APPEND @@ -1098,10 +1142,10 @@ qse_ssize_t qse_fio_read (qse_fio_t* fio, void* buf, qse_size_t size) #if defined(_WIN32) DWORD count; + if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD))) size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD); - if (ReadFile (fio->handle, - buf, (DWORD)size, &count, QSE_NULL) == FALSE) + if (ReadFile (fio->handle, buf, (DWORD)size, &count, QSE_NULL) == FALSE) { fio->errnum = syserr_to_errnum (GetLastError()); return -1; diff --git a/qse/lib/cmn/mux.c b/qse/lib/cmn/mux.c index 677e82dd..c88b0244 100644 --- a/qse/lib/cmn/mux.c +++ b/qse/lib/cmn/mux.c @@ -561,7 +561,7 @@ int qse_mux_poll (qse_mux_t* mux, const qse_ntime_t* tmout) qse_mux_hnd_t i; qse_mux_evt_t* evt, xevt; - for (i = 0 ; i <= mux->maxhnd; i++) + for (i = 0; i <= mux->maxhnd; i++) { evt = mux->me.ptr[i]; if (!evt || evt->hnd != i) continue; diff --git a/qse/lib/cmn/time.c b/qse/lib/cmn/time.c index 98c5d720..75e04867 100644 --- a/qse/lib/cmn/time.c +++ b/qse/lib/cmn/time.c @@ -43,11 +43,7 @@ #endif #if defined(_WIN32) - #define WIN_EPOCH_YEAR (1601) - #define WIN_EPOCH_MON (1) - #define WIN_EPOCH_DAY (1) - - #define EPOCH_DIFF_YEARS (QSE_EPOCH_YEAR-WIN_EPOCH_YEAR) + #define EPOCH_DIFF_YEARS (QSE_EPOCH_YEAR-QSE_EPOCH_YEAR_WIN) #define EPOCH_DIFF_DAYS ((qse_long_t)EPOCH_DIFF_YEARS*365+EPOCH_DIFF_YEARS/4-3) #define EPOCH_DIFF_SECS ((qse_long_t)EPOCH_DIFF_DAYS*24*60*60) #endif diff --git a/qse/lib/net/Makefile.am b/qse/lib/net/Makefile.am index 55471c83..17c1c578 100644 --- a/qse/lib/net/Makefile.am +++ b/qse/lib/net/Makefile.am @@ -24,4 +24,5 @@ libqsenet_la_SOURCES = \ upxd.c libqsenet_la_LDFLAGS = -version-info 1:0:0 -no-undefined -L../cmn -L$(libdir) -libqsenet_la_LIBADD = -lqsecmn +libqsenet_la_LIBADD = -lqsecmn $(SOCKET_LIBS) $(SENDFILE_LIBS) $(SSL_LIBS) + diff --git a/qse/lib/net/Makefile.in b/qse/lib/net/Makefile.in index 63181fc9..c472a219 100644 --- a/qse/lib/net/Makefile.in +++ b/qse/lib/net/Makefile.in @@ -78,7 +78,9 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) -libqsenet_la_DEPENDENCIES = +am__DEPENDENCIES_1 = +libqsenet_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libqsenet_la_OBJECTS = http.lo htre.lo htrd.lo httpd.lo \ httpd-cgi.lo httpd-dir.lo httpd-file.lo httpd-proxy.lo \ httpd-resol.lo httpd-std.lo httpd-task.lo httpd-text.lo \ @@ -301,7 +303,7 @@ libqsenet_la_SOURCES = \ upxd.c libqsenet_la_LDFLAGS = -version-info 1:0:0 -no-undefined -L../cmn -L$(libdir) -libqsenet_la_LIBADD = -lqsecmn +libqsenet_la_LIBADD = -lqsecmn $(SOCKET_LIBS) $(SENDFILE_LIBS) $(SSL_LIBS) all: all-am .SUFFIXES: diff --git a/qse/lib/net/httpd-std.c b/qse/lib/net/httpd-std.c index aad24be5..5ed2d5bd 100644 --- a/qse/lib/net/httpd-std.c +++ b/qse/lib/net/httpd-std.c @@ -30,11 +30,15 @@ #include #include #include +#include #if defined(_WIN32) # include # include /* sockaddr_in6 */ # include +# define EPOCH_DIFF_YEARS (QSE_EPOCH_YEAR-QSE_EPOCH_YEAR_WIN) +# define EPOCH_DIFF_DAYS ((qse_long_t)EPOCH_DIFF_YEARS*365+EPOCH_DIFF_YEARS/4-3) +# define EPOCH_DIFF_SECS ((qse_long_t)EPOCH_DIFF_DAYS*24*60*60) #elif defined(__OS2__) /* TODO */ @@ -232,41 +236,38 @@ static qse_httpd_errnum_t syserr_to_errnum (int e) #define MAX_SEND_SIZE 4096 -#if defined(_WIN32) - /* TODO */ - /* TODO: WIN32 TransmitFile */ -#elif defined(__OS2__) - /* TODO */ -#elif defined(__DOS__) - /* TODO */ +static qse_ssize_t send_file ( + int out_fd, qse_ubi_t in_fd, qse_foff_t* offset, qse_size_t count) +{ +#if defined(HAVE_SENDFILE) && defined(HAVE_SENDFILE64) -#elif defined(HAVE_SENDFILE) && defined(HAVE_SENDFILE64) -# if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64) -# define xsendfile(out,in,offset,count) sendfile64(out,in,offset,count) -# else -# define xsendfile(out,in,offset,count) sendfile(out,in,offset,count) -# endif + qse_ubi_t infd = qse_fio_gethandleasubi (in_fd.ptr); + + #if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64) + return sendfile64 (out_f_fdd, infd.i, offset, count); + #else + return sendfile (out_fd, infd.i, offset, count); + #endif #elif defined(HAVE_SENDFILE) -# define xsendfile(out,in,offset,count) sendfile(out,in,offset,count) + qse_ubi_t infd = qse_fio_gethandleasubi (in_fd.ptr); + return sendfile (out_fd, infd.i, offset, count); #elif defined(HAVE_SENDFILE64) -# define xsendfile(out,in,offset,count) sendfile64(out,in,offset,count) + qse_ubi_t infd = qse_fio_gethandleasubi (in_fd.ptr); + return sendfile64 (out_fd, in_fd.i, offset, count); #elif defined(HAVE_SENDFILEV) || defined(HAVE_SENDFILEV64) -static qse_ssize_t xsendfile ( - int out_fd, int in_fd, qse_foff_t* offset, qse_size_t count) -{ -#if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64) + #if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64) struct sendfilevec64 vec; -#else + #else struct sendfilevec vec; -#endif + #endif size_t xfer; ssize_t n; - vec.sfv_fd = in_fd; + vec.sfv_fd = in_fd.i; vec.sfv_flag = 0; if (offset) { @@ -274,16 +275,16 @@ static qse_ssize_t xsendfile ( } else { - vec.sfv_off = QSE_LSEEK (in_fd, 0, SEEK_CUR); + vec.sfv_off = QSE_LSEEK (in_fd.i, 0, SEEK_CUR); if (vec.sfv_off == (off_t)-1) return (qse_ssize_t)-1; } vec.sfv_len = count; -#if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64) + #if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64) n = sendfilev64 (out_fd, &vec, 1, &xfer); -#else + #else n = sendfilev (out_fd, &vec, 1, &xfer); -#endif + #endif if (offset) *offset = *offset + xfer; /* TODO: xfer contains number of byte written even on failure @@ -291,45 +292,58 @@ on success xfer == n. on failure xfer != n. */ return n; -} #else -static qse_ssize_t xsendfile ( - int out_fd, int in_fd, qse_foff_t* offset, qse_size_t count) -{ qse_mchar_t buf[MAX_SEND_SIZE]; qse_ssize_t n; - if (offset && QSE_LSEEK (in_fd, *offset, SEEK_SET) != *offset) + #if 0 + if (offset && QSE_LSEEK (in_fd.i, *offset, SEEK_SET) != *offset) return (qse_ssize_t)-1; if (count > QSE_COUNTOF(buf)) count = QSE_COUNTOF(buf); - n = read (in_fd, buf, count); + n = QSE_READ (in_fd.i, buf, count); + if (n == (qse_ssize_t)-1 || n == 0) return n; + #endif + + if (offset && qse_fio_seek (in_fd.ptr, *offset, QSE_FIO_BEGIN) != *offset) + return (qse_ssize_t)-1; + + if (count > QSE_COUNTOF(buf)) count = QSE_COUNTOF(buf); + n = qse_fio_read (in_fd.ptr, buf, count); if (n == (qse_ssize_t)-1 || n == 0) return n; n = send (out_fd, buf, n, 0); if (n > 0 && offset) *offset = *offset + n; return n; -} #endif +} /* ------------------------------------------------------------------- */ #if defined(HAVE_SSL) -static qse_ssize_t xsendfile_ssl ( - SSL* out, int in_fd, qse_foff_t* offset, qse_size_t count) +static qse_ssize_t send_file_ssl ( + SSL* out, qse_ubi_t in_fd, qse_foff_t* offset, qse_size_t count) { qse_mchar_t buf[MAX_SEND_SIZE]; qse_ssize_t n; - if (offset && QSE_LSEEK (in_fd, *offset, SEEK_SET) != *offset) +#if 0 + if (offset && QSE_LSEEK (in_fd.i, *offset, SEEK_SET) != *offset) return (qse_ssize_t)-1; if (count > QSE_COUNTOF(buf)) count = QSE_COUNTOF(buf); - n = read (in_fd, buf, count); + n = QSE_READ (in_fd.i, buf, count); + if (n == (qse_ssize_t)-1 || n == 0) return n; +#endif + if (offset && qse_fio_seek (in_fd.ptr, *offset, QSE_FIO_BEGIN) != *offset) + return (qse_ssize_t)-1; + + if (count > QSE_COUNTOF(buf)) count = QSE_COUNTOF(buf); + n = qse_fio_read (in_fd.ptr, buf, count); if (n == (qse_ssize_t)-1 || n == 0) return n; n = SSL_write (out, buf, count); @@ -498,12 +512,12 @@ IP_TRANSPRENT is needed for: if (server->flags & QSE_HTTPD_SERVER_BINDTONWIF) { +#if defined(SO_BINDTODEVICE) qse_mchar_t tmp[64]; qse_size_t len; len = qse_nwifindextombs (server->nwif, tmp, QSE_COUNTOF(tmp)); -#if defined(SO_BINDTODEVICE) if (len <= 0 || setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE, tmp, len) <= -1) { /* TODO: logging ... */ @@ -980,13 +994,84 @@ static int stat_file ( { #if defined(_WIN32) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; + + HANDLE fh; + WIN32_FIND_DATAA fdata; + ULARGE_INTEGER li; + + /* fail if the path name contains a wilecard letter */ + if (qse_mbspbrk (path, QSE_MT("?*")) != QSE_NULL) return -1; + + if (path[0] == QSE_MT('/') && path[1] == QSE_MT('\0')) + { + /* the root directory won't work well with FindFirstFile().*/ + QSE_MEMSET (hst, 0, QSE_SIZEOF(*hst)); + hst->isdir = 1; + /* TODO: hst->dev can be set to the drive letter's index. */ + } + else + { + /* TODO: hst->dev can be set to the drive letter's index. */ + + fh = FindFirstFileA (path, &fdata); + if (fh == INVALID_HANDLE_VALUE) return -1; + + QSE_MEMSET (hst, 0, QSE_SIZEOF(*hst)); + if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) hst->isdir = 1; + + hst->size = ((qse_foff_t)fdata.nFileSizeHigh << 32) | fdata.nFileSizeLow; + li.LowPart = fdata.ftLastWriteTime.dwLowDateTime; + li.HighPart = fdata.ftLastWriteTime.dwHighDateTime; + + /* li.QuadPart is in the 100-nanosecond intervals */ + hst->mtime.sec = (li.QuadPart / (QSE_NSECS_PER_SEC / 100)) - EPOCH_DIFF_SECS; + hst->mtime.nsec = (li.QuadPart % (QSE_NSECS_PER_SEC / 100)) * 100; + + FindClose (fh); + } + + return 0; + #elif defined(__OS2__) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; + APIRET rc; + HDIR h; + FILEFINDBUF3L ffb; + ULONG count; + qse_btime_t bt; + qse_ntime_t nt; + + /* fail if the path name contains a wilecard letter */ + if (qse_mbspbrk (path, QSE_MT("?*")) != QSE_NULL) return -1; + + rc = DosFindFirst ( + mptr, + &h, + FILE_DIRECTORY | FILE_READONLY, + &ffb, + QSE_SIZEOF(ffb), + &count, + FIL_STANDARDL); + if (rc != NO_ERROR) return -1; + + DosFindClose (&h); + + QSE_MEMSET (&bt, 0, QSE_SIZEOF(bt)); + bt.mday = ffb.fdateLastWrite.day; + bt.mon = ffb.fdateLastWrite.month - 1; + bt.year = ffb.fdateLastWrite.year + 80; + bt.hour = ffb.ftimeLastWrite.hours; + bt.min = ffb.ftimeLastWrite.minutes; + bt.min = ffb.ftimeLastWrite.twosecs * 2; + bt.isdst = -1; + if (qse_timelocal (&bt, &nt) <= -1) return -1; + + QSE_MEMSET (hst, 0, QSE_SIZEOF(*hst)); + if (ffb.attrFile & FILE_DIRECTORY) hst->isdir = 1; + hst->size = ffb.cbFile; + hst->mtime = nt; + + return 0; + #elif defined(__DOS__) /* TODO: */ qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); @@ -1032,27 +1117,6 @@ static int stat_file ( /* ------------------------------------------------------------------- */ -static int file_executable (qse_httpd_t* httpd, const qse_mchar_t* path) -{ -#if defined(_WIN32) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#elif defined(__OS2__) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#elif defined(__DOS__) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#else - if (access (path, X_OK) == -1) - return (errno == EACCES)? 0 /*no*/: -1 /*error*/; - return 1; /* yes */ -#endif -} - static int file_stat ( qse_httpd_t* httpd, const qse_mchar_t* path, qse_httpd_stat_t* hst) { @@ -1062,141 +1126,66 @@ static int file_stat ( static int file_ropen ( qse_httpd_t* httpd, const qse_mchar_t* path, qse_ubi_t* handle) { -#if defined(_WIN32) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#elif defined(__OS2__) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#elif defined(__DOS__) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#else + qse_fio_t* fio; - int fd; - int flags; - - flags = O_RDONLY; - #if defined(O_LARGEFILE) - flags |= O_LARGEFILE; - #endif - -qse_printf (QSE_T("opening file [%hs] for reading\n"), path); - fd = QSE_OPEN (path, flags, 0); - if (fd <= -1) + fio = qse_fio_open ( + httpd->mmgr, 0, (const qse_char_t*)path, + QSE_FIO_READ | QSE_FIO_MBSPATH, 0); + if (fio == QSE_NULL) { - qse_httpd_seterrnum (httpd, syserr_to_errnum(errno)); + /* TODO: translate fio error to a proper error code */ + qse_httpd_seterrnum (httpd, QSE_HTTPD_EINVAL); return -1; } - flags = fcntl (fd, F_GETFD); - if (flags >= 0) fcntl (fd, F_SETFD, flags | FD_CLOEXEC); - - handle->i = fd; -qse_printf (QSE_T("opened file %hs\n"), path); + handle->ptr = fio; +qse_printf (QSE_T("opened rfile [%hs][%p][%p]\n"), path, handle->ptr, fio->handle); return 0; -#endif } static int file_wopen ( qse_httpd_t* httpd, const qse_mchar_t* path, qse_ubi_t* handle) { -#if defined(_WIN32) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#elif defined(__OS2__) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#elif defined(__DOS__) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#else - int fd; - int flags; + qse_fio_t* fio; - flags = O_WRONLY | O_CREAT | O_TRUNC; - #if defined(O_LARGEFILE) - flags |= O_LARGEFILE; - #endif - -qse_printf (QSE_T("opening file [%hs] for writing\n"), path); - fd = QSE_OPEN (path, flags, 0644); - if (fd <= -1) + fio = qse_fio_open ( + httpd->mmgr, 0, (const qse_char_t*)path, + QSE_FIO_WRITE | QSE_FIO_CREATE | + QSE_FIO_TRUNCATE | QSE_FIO_MBSPATH, 0644); + if (fio == QSE_NULL) { - qse_httpd_seterrnum (httpd, syserr_to_errnum(errno)); + /* TODO: translate fio error to a proper error code */ + qse_httpd_seterrnum (httpd, QSE_HTTPD_EINVAL); return -1; } - handle->i = fd; + handle->ptr = fio; +qse_printf (QSE_T("opened wfile [%hs][%p][%p]\n"), path, handle->ptr, fio->handle); return 0; -#endif } static void file_close (qse_httpd_t* httpd, qse_ubi_t handle) { -#if defined(_WIN32) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); -#elif defined(__OS2__) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); -#elif defined(__DOS__) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); -#else -qse_printf (QSE_T("closing file %d\n"), handle.i); - QSE_CLOSE (handle.i); -#endif +qse_printf (QSE_T("closed file....%p\n"), handle.ptr); + qse_fio_close (handle.ptr); } static qse_ssize_t file_read ( qse_httpd_t* httpd, qse_ubi_t handle, qse_mchar_t* buf, qse_size_t len) { -#if defined(_WIN32) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#elif defined(__OS2__) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#elif defined(__DOS__) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#else - return QSE_READ (handle.i, buf, len); -#endif + /* TODO: error code conversion */ + return qse_fio_read (handle.ptr, buf, len); } static qse_ssize_t file_write ( qse_httpd_t* httpd, qse_ubi_t handle, const qse_mchar_t* buf, qse_size_t len) { -#if defined(_WIN32) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#elif defined(__OS2__) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#elif defined(__DOS__) - /* TODO: */ - qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); - return -1; -#else - return QSE_WRITE (handle.i, buf, len); -#endif + /* TODO: error code conversion */ + return qse_fio_write (handle.ptr, buf, len); } /* ------------------------------------------------------------------- */ @@ -1227,7 +1216,9 @@ static int dir_open (qse_httpd_t* httpd, const qse_mchar_t* path, qse_ubi_t* han return -1; } - d->dp = qse_dir_open (httpd->mmgr, 0, (const qse_char_t*)path, QSE_DIR_MBSPATH | QSE_DIR_SORT); +qse_printf (QSE_T("OPENDING DIRECTORY [%hs]\n"), path); + d->dp = qse_dir_open (httpd->mmgr, 0, + (const qse_char_t*)path, QSE_DIR_MBSPATH | QSE_DIR_SORT); if (d->dp == QSE_NULL) { qse_httpd_seterrnum (httpd, syserr_to_errnum(errno)); @@ -1236,6 +1227,7 @@ static int dir_open (qse_httpd_t* httpd, const qse_mchar_t* path, qse_ubi_t* han return -1; } +qse_printf (QSE_T("OPENED DIRECTORY [%hs]\n"), path); handle->ptr = d; return 0; } @@ -1380,14 +1372,14 @@ static qse_ssize_t client_sendfile ( if (client->status & CLIENT_SECURE) { #if defined(HAVE_SSL) - return xsendfile_ssl (client->handle2.ptr, handle.i, offset, count); + return send_file_ssl (client->handle2.ptr, handle, offset, count); #else return -1; #endif } else { - return xsendfile (client->handle.i, handle.i, offset, count); + return send_file (client->handle.i, handle, offset, count); } } @@ -1768,8 +1760,7 @@ static qse_httpd_scb_t httpd_system_callbacks = }, /* file operation */ - { file_executable, - file_stat, + { file_stat, file_ropen, file_wopen, file_close, @@ -1947,7 +1938,7 @@ static int make_resource ( const qse_mchar_t* qpath; const qse_mchar_t* idxfile; qse_mchar_t* xpath; - qse_stat_t st; + qse_httpd_stat_t st; qse_size_t i; int n; @@ -1955,6 +1946,7 @@ static int make_resource ( QSE_MEMSET (target, 0, QSE_SIZEOF(*target)); +qse_printf (QSE_T(">>> MAKING RESOURCE [%hs]\n"), qpath); server_xtn = qse_httpd_getserverxtn (httpd, client->server); if (server_xtn->cfg[SERVER_XTN_CFG_REALM] && @@ -1983,17 +1975,10 @@ auth_ok: xpath = merge_paths (httpd, server_xtn->cfg[SERVER_XTN_CFG_DOCROOT], qpath); if (xpath == QSE_NULL) return -1; -#if defined(_WIN32) - /* TODO */ -#elif defined(__OS2__) - /* TODO */ -#elif defined(__DOS__) - - /* TODO */ -#else - if (QSE_STAT (xpath, &st) == 0 && S_ISDIR(st.st_mode)) -#endif +qse_printf (QSE_T(">>> check if [%hs] is a directory\n"), xpath); + if (httpd->scb->file.stat (httpd, xpath, &st) >= 0 && st.isdir) { +qse_printf (QSE_T(">>> [%hs] is a directory\n"), xpath); /* it is a directory */ if (server_xtn->cfg2.s.idxstd) { @@ -2009,16 +1994,7 @@ auth_ok: return -1; } -#if defined(_WIN32) - /* TODO */ -#elif defined(__OS2__) - /* TODO */ -#elif defined(__DOS__) - - /* TODO */ -#else - if (QSE_STAT (tpath, &st) == 0 && S_ISREG(st.st_mode)) -#endif + if (httpd->scb->file.stat (httpd, tpath, &st) >= 0 && st.isdir) { /* the index file is found */ QSE_MMGR_FREE (httpd->mmgr, xpath); @@ -2033,9 +2009,11 @@ auth_ok: target->type = QSE_HTTPD_RSRC_DIR; target->u.dir.path = xpath; +qse_printf (QSE_T(">>> MADE DIREcTORY RESOURCE [%hs]\n"), xpath); } else { +qse_printf (QSE_T(">>> [%hs] is a file\n"), xpath); attempt_file: if (server_xtn->cfg2.s.cgistd) { diff --git a/qse/lib/net/httpd-task.c b/qse/lib/net/httpd-task.c index f074ee22..0a1a206b 100644 --- a/qse/lib/net/httpd-task.c +++ b/qse/lib/net/httpd-task.c @@ -252,12 +252,12 @@ static qse_httpd_task_t* entask_status ( return qse_httpd_entaskformat ( httpd, client, pred, - QSE_MT("HTTP/%d.%d %d %s\r\nServer: %s\r\nDate: %s\r\nConnection: %s\r\nContent-Type: text/html\r\nContent-Length: %lu\r\n%s%s%s\r\n%s"), + QSE_MT("HTTP/%d.%d %d %s\r\nServer: %s\r\nDate: %s\r\nConnection: %s\r\nContent-Type: text/html\r\nContent-Length: %u\r\n%s%s%s\r\n%s"), version->major, version->minor, code, msg, qse_httpd_getname (httpd), qse_httpd_fmtgmtimetobb (httpd, QSE_NULL, 0), (keepalive? QSE_MT("keep-alive"): QSE_MT("close")), - (unsigned long)qse_mbslen(text), + (unsigned int)qse_mbslen(text), /* unsigned int should be large enough since text is small */ extrapre, extraval, extrapst, text); } /*------------------------------------------------------------------------*/ diff --git a/qse/samples/net/httpd01.c b/qse/samples/net/httpd01.c index cf59766d..7e0a2e1a 100644 --- a/qse/samples/net/httpd01.c +++ b/qse/samples/net/httpd01.c @@ -77,7 +77,9 @@ static int httpd_main (int argc, qse_char_t* argv[]) g_httpd = httpd; signal (SIGINT, sigint); +#if defined(SIGPIPE) signal (SIGPIPE, SIG_IGN); +#endif qse_httpd_setoption (httpd, QSE_HTTPD_CGIERRTONUL); @@ -86,7 +88,9 @@ static int httpd_main (int argc, qse_char_t* argv[]) ret = qse_httpd_loopstd (httpd, &tmout); signal (SIGINT, SIG_DFL); +#if defined(SIGPIPE) signal (SIGPIPE, SIG_DFL); +#endif g_httpd = QSE_NULL; if (ret <= -1) qse_fprintf (QSE_STDERR, QSE_T("Httpd error\n")); diff --git a/qse/samples/net/httpd02.c b/qse/samples/net/httpd02.c index ab981841..2eba4244 100644 --- a/qse/samples/net/httpd02.c +++ b/qse/samples/net/httpd02.c @@ -213,7 +213,9 @@ static int httpd_main (int argc, qse_char_t* argv[]) g_httpd = httpd; signal (SIGINT, sigint); +#if defined(SIGPIPE) signal (SIGPIPE, SIG_IGN); +#endif qse_httpd_setname (httpd, QSE_MT("httpd02/qse 1.0")); @@ -224,7 +226,9 @@ static int httpd_main (int argc, qse_char_t* argv[]) ret = qse_httpd_loopstd (httpd, &tmout); signal (SIGINT, SIG_DFL); +#if defined(SIGPIPE) signal (SIGPIPE, SIG_DFL); +#endif g_httpd = QSE_NULL; if (ret <= -1) qse_fprintf (QSE_STDERR, QSE_T("Httpd error\n"));