added hton,ntoh
renamed qse_getcmgrbyname() to qse_findcmgr() added qse_setcmgrfinder()/qse_getcmgrfinder() started adding ipad,nwad
This commit is contained in:
parent
35ac9924ac
commit
b330d2c350
@ -651,7 +651,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
|
|
||||||
if (qse_strcmp(opt.lngopt, QSE_T("script-encoding")) == 0)
|
if (qse_strcmp(opt.lngopt, QSE_T("script-encoding")) == 0)
|
||||||
{
|
{
|
||||||
arg->script_cmgr = qse_getcmgrbyname (opt.arg);
|
arg->script_cmgr = qse_findcmgr (opt.arg);
|
||||||
if (arg->script_cmgr == QSE_NULL)
|
if (arg->script_cmgr == QSE_NULL)
|
||||||
{
|
{
|
||||||
print_err (QSE_T("unknown script encoding - %s\n"), opt.arg);
|
print_err (QSE_T("unknown script encoding - %s\n"), opt.arg);
|
||||||
@ -660,7 +660,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
}
|
}
|
||||||
else if (qse_strcmp(opt.lngopt, QSE_T("console-encoding")) == 0)
|
else if (qse_strcmp(opt.lngopt, QSE_T("console-encoding")) == 0)
|
||||||
{
|
{
|
||||||
arg->console_cmgr = qse_getcmgrbyname (opt.arg);
|
arg->console_cmgr = qse_findcmgr (opt.arg);
|
||||||
if (arg->console_cmgr == QSE_NULL)
|
if (arg->console_cmgr == QSE_NULL)
|
||||||
{
|
{
|
||||||
print_err (QSE_T("unknown console encoding - %s\n"), opt.arg);
|
print_err (QSE_T("unknown console encoding - %s\n"), opt.arg);
|
||||||
|
@ -11,11 +11,14 @@ pkginclude_HEADERS = \
|
|||||||
fs.h \
|
fs.h \
|
||||||
gdl.h \
|
gdl.h \
|
||||||
htb.h \
|
htb.h \
|
||||||
|
hton.h \
|
||||||
|
ipad.h \
|
||||||
lda.h \
|
lda.h \
|
||||||
main.h \
|
main.h \
|
||||||
map.h \
|
map.h \
|
||||||
mbwc.h \
|
mbwc.h \
|
||||||
mem.h \
|
mem.h \
|
||||||
|
nwad.h \
|
||||||
oht.h \
|
oht.h \
|
||||||
opt.h \
|
opt.h \
|
||||||
path.h \
|
path.h \
|
||||||
|
@ -52,10 +52,10 @@ CONFIG_CLEAN_VPATH_FILES =
|
|||||||
SOURCES =
|
SOURCES =
|
||||||
DIST_SOURCES =
|
DIST_SOURCES =
|
||||||
am__pkginclude_HEADERS_DIST = alg.h chr.h dll.h env.h fio.h fma.h \
|
am__pkginclude_HEADERS_DIST = alg.h chr.h dll.h env.h fio.h fma.h \
|
||||||
fmt.h fs.h gdl.h htb.h lda.h main.h map.h mbwc.h mem.h oht.h \
|
fmt.h fs.h gdl.h htb.h hton.h ipad.h lda.h main.h map.h mbwc.h \
|
||||||
opt.h path.h pio.h pma.h rbt.h rex.h sio.h sll.h slmb.h \
|
mem.h nwad.h oht.h opt.h path.h pio.h pma.h rbt.h rex.h sio.h \
|
||||||
stdio.h str.h time.h tio.h tre.h utf8.h xma.h Mmgr.hpp \
|
sll.h slmb.h stdio.h str.h time.h tio.h tre.h utf8.h xma.h \
|
||||||
StdMmgr.hpp Mmged.hpp
|
Mmgr.hpp StdMmgr.hpp Mmged.hpp
|
||||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||||
am__vpath_adj = case $$p in \
|
am__vpath_adj = case $$p in \
|
||||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||||
@ -229,9 +229,10 @@ top_build_prefix = @top_build_prefix@
|
|||||||
top_builddir = @top_builddir@
|
top_builddir = @top_builddir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
pkginclude_HEADERS = alg.h chr.h dll.h env.h fio.h fma.h fmt.h fs.h \
|
pkginclude_HEADERS = alg.h chr.h dll.h env.h fio.h fma.h fmt.h fs.h \
|
||||||
gdl.h htb.h lda.h main.h map.h mbwc.h mem.h oht.h opt.h path.h \
|
gdl.h htb.h hton.h ipad.h lda.h main.h map.h mbwc.h mem.h \
|
||||||
pio.h pma.h rbt.h rex.h sio.h sll.h slmb.h stdio.h str.h \
|
nwad.h oht.h opt.h path.h pio.h pma.h rbt.h rex.h sio.h sll.h \
|
||||||
time.h tio.h tre.h utf8.h xma.h $(am__append_1)
|
slmb.h stdio.h str.h time.h tio.h tre.h utf8.h xma.h \
|
||||||
|
$(am__append_1)
|
||||||
all: all-am
|
all: all-am
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
|
75
qse/include/qse/cmn/hton.h
Normal file
75
qse/include/qse/cmn/hton.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
|
This file is part of QSE.
|
||||||
|
|
||||||
|
QSE is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
QSE is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _QSE_CMN_HTON_H_
|
||||||
|
#define _QSE_CMN_HTON_H_
|
||||||
|
|
||||||
|
#include <qse/types.h>
|
||||||
|
#include <qse/macros.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(QSE_HAVE_UINT16_T)
|
||||||
|
qse_uint16_t qse_ntoh16 (
|
||||||
|
qse_uint16_t x
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_uint16_t qse_hton16 (
|
||||||
|
qse_uint16_t x
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(QSE_HAVE_UINT32_T)
|
||||||
|
qse_uint32_t qse_ntoh32 (
|
||||||
|
qse_uint32_t x
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_uint32_t qse_hton32 (
|
||||||
|
qse_uint32_t x
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(QSE_HAVE_UINT64_T)
|
||||||
|
qse_uint64_t qse_ntoh64 (
|
||||||
|
qse_uint64_t x
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_uint64_t qse_hton64 (
|
||||||
|
qse_uint64_t x
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(QSE_HAVE_UINT128_T)
|
||||||
|
qse_uint128_t qse_ntoh128 (
|
||||||
|
qse_uint128_t x
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_uint128_t qse_hton128 (
|
||||||
|
qse_uint128_t x
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
66
qse/include/qse/cmn/ipad.h
Normal file
66
qse/include/qse/cmn/ipad.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
|
This file is part of QSE.
|
||||||
|
|
||||||
|
QSE is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
QSE is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _QSE_CMN_IPAD_H_
|
||||||
|
#define _QSE_CMN_IPAD_H_
|
||||||
|
|
||||||
|
#include <qse/types.h>
|
||||||
|
#include <qse/macros.h>
|
||||||
|
|
||||||
|
typedef struct qse_ipad_t qse_ipad_t;
|
||||||
|
typedef struct qse_ipad4_t qse_ipad4_t;
|
||||||
|
typedef struct qse_ipad6_t qse_ipad6_t;
|
||||||
|
|
||||||
|
#include <qse/pack1.h>
|
||||||
|
struct qse_ipad4_t
|
||||||
|
{
|
||||||
|
qse_uint32_t value;
|
||||||
|
};
|
||||||
|
struct qse_ipad6_t
|
||||||
|
{
|
||||||
|
qse_uint8_t value[16];
|
||||||
|
};
|
||||||
|
#include <qse/unpack.h>
|
||||||
|
|
||||||
|
struct qse_ipad_t
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
QSE_IPAD_IP4,
|
||||||
|
QSE_IPAD_IP6
|
||||||
|
} type;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
qse_ipad4_t ip4;
|
||||||
|
qse_ipad4_t ip6;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -28,6 +28,8 @@
|
|||||||
#include <qse/types.h>
|
#include <qse/types.h>
|
||||||
#include <qse/macros.h>
|
#include <qse/macros.h>
|
||||||
|
|
||||||
|
typedef qse_cmgr_t* (*qse_cmgr_finder_t) (const qse_char_t* name);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -39,15 +41,23 @@ extern qse_cmgr_t* qse_utf8cmgr;
|
|||||||
extern qse_cmgr_t* qse_slmbcmgr;
|
extern qse_cmgr_t* qse_slmbcmgr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_getcmgrbyname() function find a builtin cmgr matching a given
|
* The qse_getfindcmgr() function find a builtin cmgr matching a given
|
||||||
* @a name and returns it. It returns #QSE_NULL if no match is found.
|
* @a name and returns it. It returns #QSE_NULL if no match is found.
|
||||||
* The @a name can be one of "utf8", "slmb", and an empty string. Calling this
|
* The @a name can be one of "utf8", "slmb", and an empty string. Calling this
|
||||||
* function with an empty string is the same as calling qse_getdflcmgr().
|
* function with an empty string is the same as calling qse_getdflcmgr().
|
||||||
*/
|
*/
|
||||||
qse_cmgr_t* qse_getcmgrbyname (
|
qse_cmgr_t* qse_findcmgr (
|
||||||
const qse_char_t* name
|
const qse_char_t* name
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void qse_setcmgrfinder (
|
||||||
|
qse_cmgr_finder_t finder
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_cmgr_finder_t qse_getcmgrfinder (
|
||||||
|
void
|
||||||
|
);
|
||||||
|
|
||||||
/* --------------------------------------------------- */
|
/* --------------------------------------------------- */
|
||||||
/* DEFAULT GLOBAL CMGR */
|
/* DEFAULT GLOBAL CMGR */
|
||||||
/* --------------------------------------------------- */
|
/* --------------------------------------------------- */
|
||||||
|
52
qse/include/qse/cmn/nwad.h
Normal file
52
qse/include/qse/cmn/nwad.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
|
This file is part of QSE.
|
||||||
|
|
||||||
|
QSE is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
QSE is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _QSE_CMN_NWAD_H_
|
||||||
|
#define _QSE_CMN_NWAD_H_
|
||||||
|
|
||||||
|
#include <qse/types.h>
|
||||||
|
#include <qse/macros.h>
|
||||||
|
#include <qse/cmn/ipad.h>
|
||||||
|
|
||||||
|
struct qse_nwad_t
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
QSE_NWAD_IP4,
|
||||||
|
QSE_NWAD_IP6
|
||||||
|
} type;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
qse_ipad4_t addr;
|
||||||
|
qse_uint16_t port;
|
||||||
|
} ip4;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
qse_ipad6_t addr;
|
||||||
|
qse_uint16_t port;
|
||||||
|
} ip6;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -52,6 +52,14 @@ enum qse_httpd_option_t
|
|||||||
QSE_HTTPD_CGINOCLOEXEC = (1 << 1)
|
QSE_HTTPD_CGINOCLOEXEC = (1 << 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct qse_httpd_stat_t qse_httpd_stat_t;
|
||||||
|
struct qse_httpd_stat_t
|
||||||
|
{
|
||||||
|
qse_foff_t size;
|
||||||
|
qse_ntime_t mtime;
|
||||||
|
const qse_mchar_t* mime;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct qse_httpd_cbs_t qse_httpd_cbs_t;
|
typedef struct qse_httpd_cbs_t qse_httpd_cbs_t;
|
||||||
struct qse_httpd_cbs_t
|
struct qse_httpd_cbs_t
|
||||||
{
|
{
|
||||||
@ -65,14 +73,16 @@ struct qse_httpd_cbs_t
|
|||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int (*executable) (qse_httpd_t* httpd, const qse_mchar_t* path);
|
int (*executable) (
|
||||||
} path;
|
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);
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
int (*ropen) (
|
int (*ropen) (
|
||||||
qse_httpd_t* httpd, const qse_mchar_t* path,
|
qse_httpd_t* httpd, const qse_mchar_t* path,
|
||||||
qse_ubi_t* handle, qse_foff_t* size);
|
qse_ubi_t* handle);
|
||||||
int (*wopen) (
|
int (*wopen) (
|
||||||
qse_httpd_t* httpd, const qse_mchar_t* path,
|
qse_httpd_t* httpd, const qse_mchar_t* path,
|
||||||
qse_ubi_t* handle);
|
qse_ubi_t* handle);
|
||||||
@ -115,7 +125,6 @@ struct qse_httpd_cbs_t
|
|||||||
int (*handle_request) (
|
int (*handle_request) (
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req);
|
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req);
|
||||||
|
|
||||||
const qse_mchar_t* (*getmimetype) (qse_httpd_t* httpd, const qse_mchar_t* path);
|
|
||||||
int (*listdir) (qse_httpd_t* httpd, const qse_mchar_t* path);
|
int (*listdir) (qse_httpd_t* httpd, const qse_mchar_t* path);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -313,6 +322,14 @@ qse_httpd_task_t* qse_httpd_entaskcontinue (
|
|||||||
qse_htre_t* req
|
qse_htre_t* req
|
||||||
);
|
);
|
||||||
|
|
||||||
|
qse_httpd_task_t* qse_httpd_entaskauth (
|
||||||
|
qse_httpd_t* httpd,
|
||||||
|
qse_httpd_client_t* client,
|
||||||
|
const qse_httpd_task_t* task,
|
||||||
|
const qse_mchar_t* realm,
|
||||||
|
qse_htre_t* req
|
||||||
|
);
|
||||||
|
|
||||||
qse_httpd_task_t* qse_httpd_entaskdir (
|
qse_httpd_task_t* qse_httpd_entaskdir (
|
||||||
qse_httpd_t* httpd,
|
qse_httpd_t* httpd,
|
||||||
qse_httpd_client_t* client,
|
qse_httpd_client_t* client,
|
||||||
|
@ -238,7 +238,7 @@ int StdAwk::setenc (Run& run, Value& ret, const Value* args, size_t nargs,
|
|||||||
return ret.setInt ((long_t)-1);
|
return ret.setInt ((long_t)-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_cmgr_t* cmgr = qse_getcmgrbyname (ptr[1]);
|
qse_cmgr_t* cmgr = qse_findcmgr (ptr[1]);
|
||||||
if (cmgr == QSE_NULL)
|
if (cmgr == QSE_NULL)
|
||||||
{
|
{
|
||||||
return ret.setInt ((long_t)-1);
|
return ret.setInt ((long_t)-1);
|
||||||
|
@ -124,7 +124,8 @@ typedef struct rxtn_t
|
|||||||
} rxtn_t;
|
} rxtn_t;
|
||||||
|
|
||||||
#if defined(QSE_CHAR_IS_WCHAR)
|
#if defined(QSE_CHAR_IS_WCHAR)
|
||||||
static qse_cmgr_t* getcmgr_from_cmgrtab (qse_awk_rtx_t* rtx, const qse_char_t* ioname);
|
static qse_cmgr_t* getcmgr_from_cmgrtab (
|
||||||
|
qse_awk_rtx_t* rtx, const qse_char_t* ioname);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static qse_flt_t custom_awk_pow (qse_awk_t* awk, qse_flt_t x, qse_flt_t y)
|
static qse_flt_t custom_awk_pow (qse_awk_t* awk, qse_flt_t x, qse_flt_t y)
|
||||||
@ -1562,7 +1563,8 @@ skip_system:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(QSE_CHAR_IS_WCHAR)
|
#if defined(QSE_CHAR_IS_WCHAR)
|
||||||
static qse_cmgr_t* getcmgr_from_cmgrtab (qse_awk_rtx_t* rtx, const qse_char_t* ioname)
|
static qse_cmgr_t* getcmgr_from_cmgrtab (
|
||||||
|
qse_awk_rtx_t* rtx, const qse_char_t* ioname)
|
||||||
{
|
{
|
||||||
rxtn_t* rxtn;
|
rxtn_t* rxtn;
|
||||||
qse_htb_pair_t* pair;
|
qse_htb_pair_t* pair;
|
||||||
@ -1617,7 +1619,7 @@ static int fnc_setenc (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmgr = qse_getcmgrbyname (ptr[1]);
|
cmgr = qse_findcmgr (ptr[1]);
|
||||||
if (cmgr == QSE_NULL) fret = -1;
|
if (cmgr == QSE_NULL) fret = -1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -36,10 +36,13 @@ libqsecmn_la_SOURCES = \
|
|||||||
fs.c \
|
fs.c \
|
||||||
fs-err.c \
|
fs-err.c \
|
||||||
fs-move.c \
|
fs-move.c \
|
||||||
|
hton.c \
|
||||||
|
ipad.c \
|
||||||
main.c \
|
main.c \
|
||||||
mbwc.c \
|
mbwc.c \
|
||||||
mbwc-str.c \
|
mbwc-str.c \
|
||||||
mem.c \
|
mem.c \
|
||||||
|
nwad.c \
|
||||||
oht.c \
|
oht.c \
|
||||||
opt.c \
|
opt.c \
|
||||||
path-basename.c \
|
path-basename.c \
|
||||||
|
@ -77,18 +77,18 @@ LTLIBRARIES = $(lib_LTLIBRARIES)
|
|||||||
libqsecmn_la_DEPENDENCIES =
|
libqsecmn_la_DEPENDENCIES =
|
||||||
am_libqsecmn_la_OBJECTS = alg-rand.lo alg-search.lo alg-sort.lo \
|
am_libqsecmn_la_OBJECTS = alg-rand.lo alg-search.lo alg-sort.lo \
|
||||||
assert.lo chr.lo dll.lo env.lo gdl.lo htb.lo lda.lo fio.lo \
|
assert.lo chr.lo dll.lo env.lo gdl.lo htb.lo lda.lo fio.lo \
|
||||||
fma.lo fmt.lo fs.lo fs-err.lo fs-move.lo main.lo mbwc.lo \
|
fma.lo fmt.lo fs.lo fs-err.lo fs-move.lo hton.lo ipad.lo \
|
||||||
mbwc-str.lo mem.lo oht.lo opt.lo path-basename.lo \
|
main.lo mbwc.lo mbwc-str.lo mem.lo nwad.lo oht.lo opt.lo \
|
||||||
path-canon.lo pio.lo pma.lo rbt.lo rex.lo sio.lo sll.lo \
|
path-basename.lo path-canon.lo pio.lo pma.lo rbt.lo rex.lo \
|
||||||
slmb.lo stdio.lo str-beg.lo str-cat.lo str-chr.lo str-cnv.lo \
|
sio.lo sll.lo slmb.lo stdio.lo str-beg.lo str-cat.lo \
|
||||||
str-cmp.lo str-cpy.lo str-del.lo str-dup.lo str-dynm.lo \
|
str-chr.lo str-cnv.lo str-cmp.lo str-cpy.lo str-del.lo \
|
||||||
str-dynw.lo str-end.lo str-excl.lo str-fcpy.lo str-fnmat.lo \
|
str-dup.lo str-dynm.lo str-dynw.lo str-end.lo str-excl.lo \
|
||||||
str-incl.lo str-len.lo str-pac.lo str-pbrk.lo str-put.lo \
|
str-fcpy.lo str-fnmat.lo str-incl.lo str-len.lo str-pac.lo \
|
||||||
str-rev.lo str-rot.lo str-set.lo str-spl.lo str-spn.lo \
|
str-pbrk.lo str-put.lo str-rev.lo str-rot.lo str-set.lo \
|
||||||
str-str.lo str-subst.lo str-tok.lo str-trm.lo str-word.lo \
|
str-spl.lo str-spn.lo str-str.lo str-subst.lo str-tok.lo \
|
||||||
time.lo tio.lo tio-get.lo tio-put.lo tre.lo tre-ast.lo \
|
str-trm.lo str-word.lo time.lo tio.lo tio-get.lo tio-put.lo \
|
||||||
tre-compile.lo tre-match-backtrack.lo tre-match-parallel.lo \
|
tre.lo tre-ast.lo tre-compile.lo tre-match-backtrack.lo \
|
||||||
tre-parse.lo tre-stack.lo utf8.lo xma.lo
|
tre-match-parallel.lo tre-parse.lo tre-stack.lo utf8.lo xma.lo
|
||||||
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
|
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
|
||||||
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||||
@ -310,10 +310,13 @@ libqsecmn_la_SOURCES = \
|
|||||||
fs.c \
|
fs.c \
|
||||||
fs-err.c \
|
fs-err.c \
|
||||||
fs-move.c \
|
fs-move.c \
|
||||||
|
hton.c \
|
||||||
|
ipad.c \
|
||||||
main.c \
|
main.c \
|
||||||
mbwc.c \
|
mbwc.c \
|
||||||
mbwc-str.c \
|
mbwc-str.c \
|
||||||
mem.c \
|
mem.c \
|
||||||
|
nwad.c \
|
||||||
oht.c \
|
oht.c \
|
||||||
opt.c \
|
opt.c \
|
||||||
path-basename.c \
|
path-basename.c \
|
||||||
@ -468,11 +471,14 @@ distclean-compile:
|
|||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdl.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdl.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hton.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipad.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lda.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lda.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbwc-str.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbwc-str.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbwc.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbwc.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nwad.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oht.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oht.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path-basename.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path-basename.Plo@am__quote@
|
||||||
|
203
qse/lib/cmn/hton.c
Normal file
203
qse/lib/cmn/hton.c
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
|
This file is part of QSE.
|
||||||
|
|
||||||
|
QSE is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
QSE is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <qse/cmn/hton.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if defined(QSE_HAVE_UINT16_T)
|
||||||
|
|
||||||
|
qse_uint16_t qse_ntoh16 (qse_uint16_t x)
|
||||||
|
{
|
||||||
|
#if defined(QSE_ENDIAN_BIG)
|
||||||
|
return x;
|
||||||
|
#elif defined(QSE_ENDIAN_LITTLE)
|
||||||
|
qse_uint8_t* c = (qse_uint8_t*)&x;
|
||||||
|
return (qse_uint16_t)(
|
||||||
|
((qse_uint16_t)c[0] << 8) |
|
||||||
|
((qse_uint16_t)c[1] << 0));
|
||||||
|
#else
|
||||||
|
# error Unknown endian
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_uint16_t qse_hton16 (qse_uint16_t x)
|
||||||
|
{
|
||||||
|
#if defined(QSE_ENDIAN_BIG)
|
||||||
|
return x;
|
||||||
|
#elif defined(QSE_ENDIAN_LITTLE)
|
||||||
|
qse_uint8_t* c = (qse_uint8_t*)&x;
|
||||||
|
return (qse_uint16_t)(
|
||||||
|
((qse_uint16_t)c[0] << 8) |
|
||||||
|
((qse_uint16_t)c[1] << 0));
|
||||||
|
#else
|
||||||
|
# error Unknown endian
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if defined(QSE_HAVE_UINT32_T)
|
||||||
|
|
||||||
|
qse_uint32_t qse_ntoh32 (qse_uint32_t x)
|
||||||
|
{
|
||||||
|
#if defined(QSE_ENDIAN_BIG)
|
||||||
|
return x;
|
||||||
|
#elif defined(QSE_ENDIAN_LITTLE)
|
||||||
|
qse_uint8_t* c = (qse_uint8_t*)&x;
|
||||||
|
return (qse_uint32_t)(
|
||||||
|
((qse_uint32_t)c[0] << 24) |
|
||||||
|
((qse_uint32_t)c[1] << 16) |
|
||||||
|
((qse_uint32_t)c[2] << 8) |
|
||||||
|
((qse_uint32_t)c[3] << 0));
|
||||||
|
#else
|
||||||
|
# error Unknown endian
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_uint32_t qse_hton32 (qse_uint32_t x)
|
||||||
|
{
|
||||||
|
#if defined(QSE_ENDIAN_BIG)
|
||||||
|
return x;
|
||||||
|
#elif defined(QSE_ENDIAN_LITTLE)
|
||||||
|
qse_uint8_t* c = (qse_uint8_t*)&x;
|
||||||
|
return (qse_uint32_t)(
|
||||||
|
((qse_uint32_t)c[0] << 24) |
|
||||||
|
((qse_uint32_t)c[1] << 16) |
|
||||||
|
((qse_uint32_t)c[2] << 8) |
|
||||||
|
((qse_uint32_t)c[3] << 0));
|
||||||
|
#else
|
||||||
|
# error Unknown endian
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if defined(QSE_HAVE_UINT64_T)
|
||||||
|
|
||||||
|
qse_uint64_t qse_ntoh64 (qse_uint64_t x)
|
||||||
|
{
|
||||||
|
#if defined(QSE_ENDIAN_BIG)
|
||||||
|
return x;
|
||||||
|
#elif defined(QSE_ENDIAN_LITTLE)
|
||||||
|
qse_uint8_t* c = (qse_uint8_t*)&x;
|
||||||
|
return (qse_uint64_t)(
|
||||||
|
((qse_uint64_t)c[0] << 56) |
|
||||||
|
((qse_uint64_t)c[1] << 48) |
|
||||||
|
((qse_uint64_t)c[2] << 40) |
|
||||||
|
((qse_uint64_t)c[3] << 32) |
|
||||||
|
((qse_uint64_t)c[4] << 24) |
|
||||||
|
((qse_uint64_t)c[5] << 16) |
|
||||||
|
((qse_uint64_t)c[6] << 8) |
|
||||||
|
((qse_uint64_t)c[7] << 0));
|
||||||
|
#else
|
||||||
|
# error Unknown endian
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_uint64_t qse_hton64 (qse_uint64_t x)
|
||||||
|
{
|
||||||
|
#if defined(QSE_ENDIAN_BIG)
|
||||||
|
return x;
|
||||||
|
#elif defined(QSE_ENDIAN_LITTLE)
|
||||||
|
qse_uint8_t* c = (qse_uint8_t*)&x;
|
||||||
|
return (qse_uint64_t)(
|
||||||
|
((qse_uint64_t)c[0] << 56) |
|
||||||
|
((qse_uint64_t)c[1] << 48) |
|
||||||
|
((qse_uint64_t)c[2] << 40) |
|
||||||
|
((qse_uint64_t)c[3] << 32) |
|
||||||
|
((qse_uint64_t)c[4] << 24) |
|
||||||
|
((qse_uint64_t)c[5] << 16) |
|
||||||
|
((qse_uint64_t)c[6] << 8) |
|
||||||
|
((qse_uint64_t)c[7] << 0));
|
||||||
|
#else
|
||||||
|
# error Unknown endian
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if defined(QSE_HAVE_UINT128_T)
|
||||||
|
|
||||||
|
qse_uint128_t qse_ntoh128 (qse_uint128_t x)
|
||||||
|
{
|
||||||
|
#if defined(QSE_ENDIAN_BIG)
|
||||||
|
return x;
|
||||||
|
#elif defined(QSE_ENDIAN_LITTLE)
|
||||||
|
qse_uint8_t* c = (qse_uint8_t*)&x;
|
||||||
|
return (qse_uint128_t)(
|
||||||
|
((qse_uint128_t)c[0] << 120) |
|
||||||
|
((qse_uint128_t)c[1] << 112) |
|
||||||
|
((qse_uint128_t)c[2] << 104) |
|
||||||
|
((qse_uint128_t)c[3] << 96) |
|
||||||
|
((qse_uint128_t)c[4] << 88) |
|
||||||
|
((qse_uint128_t)c[5] << 80) |
|
||||||
|
((qse_uint128_t)c[6] << 72) |
|
||||||
|
((qse_uint128_t)c[7] << 64) |
|
||||||
|
((qse_uint128_t)c[8] << 56) |
|
||||||
|
((qse_uint128_t)c[9] << 48) |
|
||||||
|
((qse_uint128_t)c[10] << 40) |
|
||||||
|
((qse_uint128_t)c[11] << 32) |
|
||||||
|
((qse_uint128_t)c[12] << 24) |
|
||||||
|
((qse_uint128_t)c[13] << 16) |
|
||||||
|
((qse_uint128_t)c[14] << 8) |
|
||||||
|
((qse_uint128_t)c[15] << 0));
|
||||||
|
#else
|
||||||
|
# error Unknown endian
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_uint128_t qse_hton128 (qse_uint128_t x)
|
||||||
|
{
|
||||||
|
#if defined(QSE_ENDIAN_BIG)
|
||||||
|
return x;
|
||||||
|
#elif defined(QSE_ENDIAN_LITTLE)
|
||||||
|
qse_uint8_t* c = (qse_uint8_t*)&x;
|
||||||
|
return (qse_uint128_t)(
|
||||||
|
((qse_uint128_t)c[0] << 120) |
|
||||||
|
((qse_uint128_t)c[1] << 112) |
|
||||||
|
((qse_uint128_t)c[2] << 104) |
|
||||||
|
((qse_uint128_t)c[3] << 96) |
|
||||||
|
((qse_uint128_t)c[4] << 88) |
|
||||||
|
((qse_uint128_t)c[5] << 80) |
|
||||||
|
((qse_uint128_t)c[6] << 72) |
|
||||||
|
((qse_uint128_t)c[7] << 64) |
|
||||||
|
((qse_uint128_t)c[8] << 56) |
|
||||||
|
((qse_uint128_t)c[9] << 48) |
|
||||||
|
((qse_uint128_t)c[10] << 40) |
|
||||||
|
((qse_uint128_t)c[11] << 32) |
|
||||||
|
((qse_uint128_t)c[12] << 24) |
|
||||||
|
((qse_uint128_t)c[13] << 16) |
|
||||||
|
((qse_uint128_t)c[14] << 8) |
|
||||||
|
((qse_uint128_t)c[15] << 0));
|
||||||
|
#else
|
||||||
|
# error Unknown endian
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------- */
|
573
qse/lib/cmn/ipad.c
Normal file
573
qse/lib/cmn/ipad.c
Normal file
@ -0,0 +1,573 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
|
This file is part of QSE.
|
||||||
|
|
||||||
|
QSE is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
QSE is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (c) 1996-1999 by Internet Software Consortium
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||||
|
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||||
|
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||||
|
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <qse/cmn/ipad.h>
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
const qse_ipad4_t qse_ipad4_any =
|
||||||
|
{
|
||||||
|
0 /* 0.0.0.0 */
|
||||||
|
};
|
||||||
|
|
||||||
|
const qse_ipad4_t qse_ipad4_loopback =
|
||||||
|
{
|
||||||
|
#if defined(QSE_ENDIAN_BIG)
|
||||||
|
0x7F000001u /* 127.0.0.1 */
|
||||||
|
#elif defined(QSE_ENDIAN_LITTLE)
|
||||||
|
0x0100007Fu
|
||||||
|
#else
|
||||||
|
# error Unknown endian
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
const qse_ipad6_t qse_ipad6_any =
|
||||||
|
{
|
||||||
|
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } /* :: */
|
||||||
|
};
|
||||||
|
|
||||||
|
const qse_ipad6_t qse_ipad6_loopback =
|
||||||
|
{
|
||||||
|
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } /* ::1 */
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
int qse_strtoipad4 (const qse_char_t* str, qse_ipad4_t* ipad)
|
||||||
|
{
|
||||||
|
qse_char_t c;
|
||||||
|
int dots = 0, digits = 0;
|
||||||
|
qse_uint32_t acc = 0, addr = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c = *str;
|
||||||
|
|
||||||
|
if (c == QSE_T('\0'))
|
||||||
|
{
|
||||||
|
if (dots < 3 || digits == 0) return -1;
|
||||||
|
addr = (addr << 8) | acc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (c >= QSE_T('0') && c <= QSE_T('9'))
|
||||||
|
{
|
||||||
|
if (digits > 0 && acc == 0) return -1;
|
||||||
|
acc = acc * 10 + (c - QSE_T('0'));
|
||||||
|
if (acc > 255) return -1;
|
||||||
|
digits++;
|
||||||
|
}
|
||||||
|
else if (c == QSE_T('.'))
|
||||||
|
{
|
||||||
|
if (dots >= 3 || digits == 0) return -1;
|
||||||
|
addr = (addr << 8) | acc;
|
||||||
|
dots++; acc = 0; digits = 0;
|
||||||
|
}
|
||||||
|
else return -1;
|
||||||
|
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
while (1);
|
||||||
|
|
||||||
|
if (ipad != QSE_NULL) ipad->value = qse_hton32(addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qse_strxtoipad4 (
|
||||||
|
const qse_char_t* str, qse_size_t len, qse_ipad4_t* ipad)
|
||||||
|
{
|
||||||
|
qse_char_t c;
|
||||||
|
int dots = 0, digits = 0;
|
||||||
|
qse_uint32_t acc = 0, addr = 0;
|
||||||
|
const qse_char_t* end = str + len;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (str >= end)
|
||||||
|
{
|
||||||
|
if (dots < 3 || digits == 0) return -1;
|
||||||
|
addr = (addr << 8) | acc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = *str;
|
||||||
|
|
||||||
|
if (c >= QSE_T('0') && c <= QSE_T('9'))
|
||||||
|
{
|
||||||
|
if (digits > 0 && acc == 0) return -1;
|
||||||
|
acc = acc * 10 + (c - QSE_T('0'));
|
||||||
|
if (acc > 255) return -1;
|
||||||
|
digits++;
|
||||||
|
}
|
||||||
|
else if (c == QSE_T('.'))
|
||||||
|
{
|
||||||
|
if (dots >= 3 || digits == 0) return -1;
|
||||||
|
addr = (addr << 8) | acc;
|
||||||
|
dots++; acc = 0; digits = 0;
|
||||||
|
}
|
||||||
|
else return -1;
|
||||||
|
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
while (1);
|
||||||
|
|
||||||
|
if (ipad != QSE_NULL) ipad->value = qse_hton32(addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __BTOA(b,p,end) \
|
||||||
|
do { \
|
||||||
|
qse_char_t* sp = p; \
|
||||||
|
do { \
|
||||||
|
if (p >= end) { \
|
||||||
|
if (p == sp) break; \
|
||||||
|
if (p - sp > 1) p[-2] = p[-1]; \
|
||||||
|
p[-1] = (b % 10) + QSE_T('0'); \
|
||||||
|
} \
|
||||||
|
else *p++ = (b % 10) + QSE_T('0'); \
|
||||||
|
b /= 10; \
|
||||||
|
} while (b > 0); \
|
||||||
|
if (p - sp > 1) { \
|
||||||
|
qse_char_t t = sp[0]; \
|
||||||
|
sp[0] = p[-1]; \
|
||||||
|
p[-1] = t; \
|
||||||
|
} \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
#define __ADDDOT(p, end) \
|
||||||
|
do { \
|
||||||
|
if (p >= end) break; \
|
||||||
|
*p++ = QSE_T('.'); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
qse_size_t qse_ipad4tostrx (
|
||||||
|
const qse_ipad4_t* ipad, qse_char_t* buf, qse_size_t size)
|
||||||
|
{
|
||||||
|
qse_byte_t b;
|
||||||
|
qse_char_t* p, * end;
|
||||||
|
qse_uint32_t ip;
|
||||||
|
|
||||||
|
if (size <= 0) return 0;
|
||||||
|
|
||||||
|
ip = ipad->value;
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
end = buf + size - 1;
|
||||||
|
|
||||||
|
#if defined(QSE_ENDIAN_BIG)
|
||||||
|
b = (ip >> 24) & 0xFF; __BTOA (b, p, end); __ADDDOT (p, end);
|
||||||
|
b = (ip >> 16) & 0xFF; __BTOA (b, p, end); __ADDDOT (p, end);
|
||||||
|
b = (ip >> 8) & 0xFF; __BTOA (b, p, end); __ADDDOT (p, end);
|
||||||
|
b = (ip >> 0) & 0xFF; __BTOA (b, p, end);
|
||||||
|
#elif defined(QSE_ENDIAN_LITTLE)
|
||||||
|
b = (ip >> 0) & 0xFF; __BTOA (b, p, end); __ADDDOT (p, end);
|
||||||
|
b = (ip >> 8) & 0xFF; __BTOA (b, p, end); __ADDDOT (p, end);
|
||||||
|
b = (ip >> 16) & 0xFF; __BTOA (b, p, end); __ADDDOT (p, end);
|
||||||
|
b = (ip >> 24) & 0xFF; __BTOA (b, p, end);
|
||||||
|
#else
|
||||||
|
# error Unknown Endian
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*p = QSE_T('\0');
|
||||||
|
return p - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qse_strtoipad6 (const qse_char_t* src, qse_ipad6_t* ipad)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
static const qse_char_t xdigits_l[] = QSE_T("0123456789abcdef"),
|
||||||
|
xdigits_u[] = QSE_T("0123456789ABCDEF");
|
||||||
|
const qse_char_t* xdigits;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
qse_ipad6_t tmp;
|
||||||
|
qse_byte_t* tp, * endp, * colonp;
|
||||||
|
const qse_char_t* curtok;
|
||||||
|
qse_char_t ch;
|
||||||
|
int saw_xdigit;
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
qse_memset (&tmp, 0, QSE_SIZEOF(tmp));
|
||||||
|
tp = &tmp.value[0];
|
||||||
|
endp = &tmp.value[QSE_COUNTOF(tmp.value)];
|
||||||
|
colonp = QSE_NULL;
|
||||||
|
|
||||||
|
/* Leading :: requires some special handling. */
|
||||||
|
if (*src == QSE_T(':'))
|
||||||
|
{
|
||||||
|
if (*++src != QSE_T(':')) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
curtok = src;
|
||||||
|
saw_xdigit = 0;
|
||||||
|
val = 0;
|
||||||
|
while ((ch = *src++) != QSE_T('\0'))
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
const char *pch;
|
||||||
|
if ((pch = qse_strchr((xdigits = xdigits_l), ch)) == QSE_NULL)
|
||||||
|
pch = qse_strchr((xdigits = xdigits_u), ch);
|
||||||
|
if (pch != QSE_NULL)
|
||||||
|
{
|
||||||
|
val <<= 4;
|
||||||
|
val |= (pch - xdigits);
|
||||||
|
if (val > 0xffff) return -1;
|
||||||
|
saw_xdigit = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
int v1;
|
||||||
|
if (ch >= QSE_T('0') && ch <= QSE_T('9'))
|
||||||
|
v1 = ch - QSE_T('0');
|
||||||
|
else if (ch >= QSE_T('A') && ch <= QSE_T('F'))
|
||||||
|
v1 = ch - QSE_T('A') + 10;
|
||||||
|
else if (ch >= QSE_T('a') && ch <= QSE_T('f'))
|
||||||
|
v1 = ch - QSE_T('a') + 10;
|
||||||
|
else v1 = -1;
|
||||||
|
if (v1 >= 0)
|
||||||
|
{
|
||||||
|
val <<= 4;
|
||||||
|
val |= v1;
|
||||||
|
if (val > 0xffff) return -1;
|
||||||
|
saw_xdigit = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == QSE_T(':'))
|
||||||
|
{
|
||||||
|
curtok = src;
|
||||||
|
if (!saw_xdigit)
|
||||||
|
{
|
||||||
|
if (colonp) return -1;
|
||||||
|
colonp = tp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (*src == QSE_T('\0'))
|
||||||
|
{
|
||||||
|
/* a colon can't be the last character */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp + QSE_SIZEOF(qse_uint16_t) > endp) return -1;
|
||||||
|
*tp++ = (qse_byte_t) (val >> 8) & 0xff;
|
||||||
|
*tp++ = (qse_byte_t) val & 0xff;
|
||||||
|
saw_xdigit = 0;
|
||||||
|
val = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
if (ch == QSE_T('.') && ((tp + NS_INADDRSZ) <= endp) &&
|
||||||
|
inet_pton4(curtok, tp) > 0)
|
||||||
|
{
|
||||||
|
tp += NS_INADDRSZ;
|
||||||
|
saw_xdigit = 0;
|
||||||
|
break; /* '\0' was seen by inet_pton4(). */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (ch == QSE_T('.') && ((tp + QSE_SIZEOF(qse_ipad4_t)) <= endp) &&
|
||||||
|
qse_strtoipad4(curtok, (qse_ipad4_t*)tp) == 0)
|
||||||
|
{
|
||||||
|
tp += QSE_SIZEOF(qse_ipad4_t);
|
||||||
|
saw_xdigit = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saw_xdigit)
|
||||||
|
{
|
||||||
|
if (tp + QSE_SIZEOF(qse_uint16_t) > endp) return -1;
|
||||||
|
*tp++ = (qse_byte_t) (val >> 8) & 0xff;
|
||||||
|
*tp++ = (qse_byte_t) val & 0xff;
|
||||||
|
}
|
||||||
|
if (colonp != QSE_NULL)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Since some memmove()'s erroneously fail to handle
|
||||||
|
* overlapping regions, we'll do the shift by hand.
|
||||||
|
*/
|
||||||
|
qse_size_t n = tp - colonp;
|
||||||
|
qse_size_t i;
|
||||||
|
|
||||||
|
for (i = 1; i <= n; i++)
|
||||||
|
{
|
||||||
|
endp[-i] = colonp[n - i];
|
||||||
|
colonp[n - i] = 0;
|
||||||
|
}
|
||||||
|
tp = endp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp != endp) return -1;
|
||||||
|
|
||||||
|
*ipad = tmp;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qse_strxtoipad6 (const qse_char_t* src, qse_size_t len, qse_ipad6_t* ipad)
|
||||||
|
{
|
||||||
|
qse_ipad6_t tmp;
|
||||||
|
qse_byte_t* tp, * endp, * colonp;
|
||||||
|
const qse_char_t* curtok;
|
||||||
|
qse_char_t ch;
|
||||||
|
int saw_xdigit;
|
||||||
|
unsigned int val;
|
||||||
|
const qse_char_t* src_end;
|
||||||
|
|
||||||
|
src_end = src + len;
|
||||||
|
|
||||||
|
qse_memset (&tmp, 0, QSE_SIZEOF(tmp));
|
||||||
|
tp = &tmp.value[0];
|
||||||
|
endp = &tmp.value[QSE_COUNTOF(tmp.value)];
|
||||||
|
colonp = QSE_NULL;
|
||||||
|
|
||||||
|
/* Leading :: requires some special handling. */
|
||||||
|
if (src < src_end && *src == QSE_T(':'))
|
||||||
|
{
|
||||||
|
src++;
|
||||||
|
if (src >= src_end || *src != QSE_T(':')) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
curtok = src;
|
||||||
|
saw_xdigit = 0;
|
||||||
|
val = 0;
|
||||||
|
|
||||||
|
while (src < src_end)
|
||||||
|
{
|
||||||
|
int v1;
|
||||||
|
|
||||||
|
ch = *src++;
|
||||||
|
|
||||||
|
if (ch >= QSE_T('0') && ch <= QSE_T('9'))
|
||||||
|
v1 = ch - QSE_T('0');
|
||||||
|
else if (ch >= QSE_T('A') && ch <= QSE_T('F'))
|
||||||
|
v1 = ch - QSE_T('A') + 10;
|
||||||
|
else if (ch >= QSE_T('a') && ch <= QSE_T('f'))
|
||||||
|
v1 = ch - QSE_T('a') + 10;
|
||||||
|
else v1 = -1;
|
||||||
|
if (v1 >= 0)
|
||||||
|
{
|
||||||
|
val <<= 4;
|
||||||
|
val |= v1;
|
||||||
|
if (val > 0xffff) return -1;
|
||||||
|
saw_xdigit = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == QSE_T(':'))
|
||||||
|
{
|
||||||
|
curtok = src;
|
||||||
|
if (!saw_xdigit)
|
||||||
|
{
|
||||||
|
if (colonp) return -1;
|
||||||
|
colonp = tp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (src >= src_end)
|
||||||
|
{
|
||||||
|
/* a colon can't be the last character */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*tp++ = (qse_byte_t) (val >> 8) & 0xff;
|
||||||
|
*tp++ = (qse_byte_t) val & 0xff;
|
||||||
|
saw_xdigit = 0;
|
||||||
|
val = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == QSE_T('.') && ((tp + QSE_SIZEOF(qse_ipad4_t)) <= endp) &&
|
||||||
|
qse_strxtoipad4(curtok, src_end - curtok, (qse_ipad4_t*)tp) == 0)
|
||||||
|
{
|
||||||
|
tp += QSE_SIZEOF(qse_ipad4_t);
|
||||||
|
saw_xdigit = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saw_xdigit)
|
||||||
|
{
|
||||||
|
if (tp + QSE_SIZEOF(qse_uint16_t) > endp) return -1;
|
||||||
|
*tp++ = (qse_byte_t) (val >> 8) & 0xff;
|
||||||
|
*tp++ = (qse_byte_t) val & 0xff;
|
||||||
|
}
|
||||||
|
if (colonp != QSE_NULL)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Since some memmove()'s erroneously fail to handle
|
||||||
|
* overlapping regions, we'll do the shift by hand.
|
||||||
|
*/
|
||||||
|
qse_size_t n = tp - colonp;
|
||||||
|
qse_size_t i;
|
||||||
|
|
||||||
|
for (i = 1; i <= n; i++)
|
||||||
|
{
|
||||||
|
endp[-i] = colonp[n - i];
|
||||||
|
colonp[n - i] = 0;
|
||||||
|
}
|
||||||
|
tp = endp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp != endp) return -1;
|
||||||
|
|
||||||
|
*ipad = tmp;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t qse_ipad6tostrx (
|
||||||
|
const qse_ipad6_t* ipad, qse_char_t* buf, qse_size_t size)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Note that int32_t and int16_t need only be "at least" large enough
|
||||||
|
* to contain a value of the specified size. On some systems, like
|
||||||
|
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||||
|
* Keep this in mind if you think this function should have been coded
|
||||||
|
* to use pointer overlays. All the world's not a VAX.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define IP6ADDR_NWORDS (QSE_SIZEOF(ipad->value) / QSE_SIZEOF(qse_uint16_t))
|
||||||
|
|
||||||
|
qse_char_t tmp[QSE_COUNTOF(QSE_T("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"))], *tp;
|
||||||
|
struct { int base, len; } best, cur;
|
||||||
|
qse_uint16_t words[IP6ADDR_NWORDS];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (size <= 0) return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Preprocess:
|
||||||
|
* Copy the input (bytewise) array into a wordwise array.
|
||||||
|
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||||
|
*/
|
||||||
|
qse_memset (words, 0, QSE_SIZEOF(words));
|
||||||
|
for (i = 0; i < QSE_SIZEOF(ipad->value); i++)
|
||||||
|
words[i / 2] |= (ipad->value[i] << ((1 - (i % 2)) << 3));
|
||||||
|
best.base = -1;
|
||||||
|
cur.base = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < IP6ADDR_NWORDS; i++)
|
||||||
|
{
|
||||||
|
if (words[i] == 0)
|
||||||
|
{
|
||||||
|
if (cur.base == -1)
|
||||||
|
{
|
||||||
|
cur.base = i;
|
||||||
|
cur.len = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cur.len++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cur.base != -1)
|
||||||
|
{
|
||||||
|
if (best.base == -1 || cur.len > best.len) best = cur;
|
||||||
|
cur.base = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cur.base != -1)
|
||||||
|
{
|
||||||
|
if (best.base == -1 || cur.len > best.len) best = cur;
|
||||||
|
}
|
||||||
|
if (best.base != -1 && best.len < 2) best.base = -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Format the result.
|
||||||
|
*/
|
||||||
|
tp = tmp;
|
||||||
|
for (i = 0; i < IP6ADDR_NWORDS; i++)
|
||||||
|
{
|
||||||
|
/* Are we inside the best run of 0x00's? */
|
||||||
|
if (best.base != -1 && i >= best.base &&
|
||||||
|
i < (best.base + best.len))
|
||||||
|
{
|
||||||
|
if (i == best.base) *tp++ = QSE_T(':');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Are we following an initial run of 0x00s or any real hex? */
|
||||||
|
if (i != 0) *tp++ = QSE_T(':');
|
||||||
|
|
||||||
|
/* Is this address an encapsulated IPv4? ipv4-compatible or ipv4-mapped */
|
||||||
|
if (i == 6 && best.base == 0 &&
|
||||||
|
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
|
||||||
|
{
|
||||||
|
qse_ipad4_t ipad4;
|
||||||
|
qse_memcpy (&ipad4.value, ipad->value+12, QSE_SIZEOF(ipad4.value));
|
||||||
|
tp += qse_ipad4tostrx (&ipad4, tp, QSE_SIZEOF(tmp) - (tp - tmp));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tp += qse_uint16tostr_lower (words[i], tp, QSE_SIZEOF(tmp) - (tp - tmp), 16, QSE_T('\0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Was it a trailing run of 0x00's? */
|
||||||
|
if (best.base != -1 &&
|
||||||
|
(best.base + best.len) == IP6ADDR_NWORDS) *tp++ = QSE_T(':');
|
||||||
|
*tp++ = QSE_T('\0');
|
||||||
|
|
||||||
|
return qse_strxcpy (buf, size, tmp);
|
||||||
|
|
||||||
|
#undef IP6ADDR_NWORDS
|
||||||
|
}
|
||||||
|
|
||||||
|
int qse_strtoipad (const qse_char_t* str, qse_ipad_t* ipad)
|
||||||
|
{
|
||||||
|
if (qse_strtoipad4 (str, &ipad->u.ip4) <= -1)
|
||||||
|
{
|
||||||
|
if (qse_strtoipad6 (str, &ipad->u.ip6) <= -1) return -1;
|
||||||
|
ipad->type = QSE_IPAD_IP6;
|
||||||
|
}
|
||||||
|
else ipad->type = QSE_IPAD_IP4;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qse_strxtoipad (const qse_char_t* str, qse_size_t len, qse_ipad_t* ipad)
|
||||||
|
{
|
||||||
|
if (qse_strxtoipad4 (str, len, &ipad->u.ip4) <= -1)
|
||||||
|
{
|
||||||
|
if (qse_strxtoipad6 (str, len, &ipad->u.ip6) <= -1) return -1;
|
||||||
|
ipad->type = QSE_IPAD_IP6;
|
||||||
|
}
|
||||||
|
else ipad->type = QSE_IPAD_IP4;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
@ -47,6 +47,7 @@ qse_cmgr_t* qse_slmbcmgr = &builtin_cmgr[0];
|
|||||||
qse_cmgr_t* qse_utf8cmgr = &builtin_cmgr[1];
|
qse_cmgr_t* qse_utf8cmgr = &builtin_cmgr[1];
|
||||||
|
|
||||||
static qse_cmgr_t* dfl_cmgr = &builtin_cmgr[0];
|
static qse_cmgr_t* dfl_cmgr = &builtin_cmgr[0];
|
||||||
|
static qse_cmgr_finder_t cmgr_finder = QSE_NULL;
|
||||||
|
|
||||||
qse_cmgr_t* qse_getdflcmgr (void)
|
qse_cmgr_t* qse_getdflcmgr (void)
|
||||||
{
|
{
|
||||||
@ -58,24 +59,34 @@ void qse_setdflcmgr (qse_cmgr_t* cmgr)
|
|||||||
dfl_cmgr = (cmgr? cmgr: &builtin_cmgr[0]);
|
dfl_cmgr = (cmgr? cmgr: &builtin_cmgr[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO:
|
qse_cmgr_t* qse_findcmgr (const qse_char_t* name)
|
||||||
qse_addcmgr (const qse_char_t* name, qse_cmgr_t* cmgr);
|
|
||||||
qse_delcmgr (const qse_char_t* name);
|
|
||||||
*/
|
|
||||||
|
|
||||||
qse_cmgr_t* qse_getcmgrbyname (const qse_char_t* name)
|
|
||||||
{
|
{
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
/* TODO: binary search */
|
if (cmgr_finder)
|
||||||
|
{
|
||||||
|
qse_cmgr_t* cmgr;
|
||||||
|
cmgr = cmgr_finder (name);
|
||||||
|
if (cmgr) return cmgr;
|
||||||
|
}
|
||||||
|
|
||||||
if (qse_strcmp(name, QSE_T("")) == 0) return dfl_cmgr;
|
if (qse_strcmp(name, QSE_T("")) == 0) return dfl_cmgr;
|
||||||
if (qse_strcmp(name, QSE_T("utf8")) == 0) return qse_utf8cmgr;
|
if (qse_strcmp(name, QSE_T("utf8")) == 0) return qse_utf8cmgr;
|
||||||
if (qse_strcmp(name, QSE_T("slmb")) == 0) return qse_slmbcmgr;
|
if (qse_strcmp(name, QSE_T("slmb")) == 0) return qse_slmbcmgr;
|
||||||
/* TODO: add more - handle those added with qse_addcmgr() */
|
|
||||||
}
|
}
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qse_setcmgrfinder (qse_cmgr_finder_t finder)
|
||||||
|
{
|
||||||
|
cmgr_finder = finder;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_cmgr_finder_t qse_getcmgrfinder (void)
|
||||||
|
{
|
||||||
|
return cmgr_finder;
|
||||||
|
}
|
||||||
|
|
||||||
/* string conversion function using default character conversion manager */
|
/* string conversion function using default character conversion manager */
|
||||||
|
|
||||||
int qse_mbstowcs (
|
int qse_mbstowcs (
|
||||||
|
37
qse/lib/cmn/nwad.c
Normal file
37
qse/lib/cmn/nwad.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
|
This file is part of QSE.
|
||||||
|
|
||||||
|
QSE is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
QSE is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (c) 1996-1999 by Internet Software Consortium
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||||
|
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||||
|
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||||
|
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <qse/cmn/nwad.h>
|
@ -49,7 +49,6 @@ static qse_ssize_t pio_output (
|
|||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
static qse_pio_errnum_t syserr_to_errnum (DWORD e)
|
static qse_pio_errnum_t syserr_to_errnum (DWORD e)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (e)
|
switch (e)
|
||||||
{
|
{
|
||||||
case ERROR_INVALID_PARAMETER:
|
case ERROR_INVALID_PARAMETER:
|
||||||
@ -573,13 +572,18 @@ int qse_pio_init (
|
|||||||
if (flags & QSE_PIO_WRITEIN)
|
if (flags & QSE_PIO_WRITEIN)
|
||||||
{
|
{
|
||||||
/* child reads, parent writes */
|
/* child reads, parent writes */
|
||||||
if (CreatePipe (
|
if (CreatePipe (&handle[0], &handle[1], &secattr, 0) == FALSE)
|
||||||
&handle[0], &handle[1],
|
{
|
||||||
&secattr, 0) == FALSE) goto oops;
|
pio->errnum = syserr_to_errnum (GetLastError());
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
/* don't inherit write handle */
|
/* don't inherit write handle */
|
||||||
if (SetHandleInformation (
|
if (SetHandleInformation (handle[1], HANDLE_FLAG_INHERIT, 0) == FALSE)
|
||||||
handle[1], HANDLE_FLAG_INHERIT, 0) == FALSE) goto oops;
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (GetLastError());
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
minidx = 0; maxidx = 1;
|
minidx = 0; maxidx = 1;
|
||||||
}
|
}
|
||||||
@ -587,13 +591,18 @@ int qse_pio_init (
|
|||||||
if (flags & QSE_PIO_READOUT)
|
if (flags & QSE_PIO_READOUT)
|
||||||
{
|
{
|
||||||
/* child writes, parent reads */
|
/* child writes, parent reads */
|
||||||
if (CreatePipe (
|
if (CreatePipe (&handle[2], &handle[3], &secattr, 0) == FALSE)
|
||||||
&handle[2], &handle[3],
|
{
|
||||||
&secattr, 0) == FALSE) goto oops;
|
pio->errnum = syserr_to_errnum (GetLastError());
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
/* don't inherit read handle */
|
/* don't inherit read handle */
|
||||||
if (SetHandleInformation (
|
if (SetHandleInformation (handle[2], HANDLE_FLAG_INHERIT, 0) == FALSE)
|
||||||
handle[2], HANDLE_FLAG_INHERIT, 0) == FALSE) goto oops;
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (GetLastError());
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
if (minidx == -1) minidx = 2;
|
if (minidx == -1) minidx = 2;
|
||||||
maxidx = 3;
|
maxidx = 3;
|
||||||
@ -602,13 +611,18 @@ int qse_pio_init (
|
|||||||
if (flags & QSE_PIO_READERR)
|
if (flags & QSE_PIO_READERR)
|
||||||
{
|
{
|
||||||
/* child writes, parent reads */
|
/* child writes, parent reads */
|
||||||
if (CreatePipe (
|
if (CreatePipe (&handle[4], &handle[5], &secattr, 0) == FALSE)
|
||||||
&handle[4], &handle[5],
|
{
|
||||||
&secattr, 0) == FALSE) goto oops;
|
pio->errnum = syserr_to_errnum (GetLastError());
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
/* don't inherit read handle */
|
/* don't inherit read handle */
|
||||||
if (SetHandleInformation (
|
if (SetHandleInformation (handle[4], HANDLE_FLAG_INHERIT, 0) == FALSE)
|
||||||
handle[4], HANDLE_FLAG_INHERIT, 0) == FALSE) goto oops;
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (GetLastError());
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
if (minidx == -1) minidx = 4;
|
if (minidx == -1) minidx = 4;
|
||||||
maxidx = 5;
|
maxidx = 5;
|
||||||
@ -629,7 +643,11 @@ int qse_pio_init (
|
|||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
&secattr, OPEN_EXISTING, 0, NULL
|
&secattr, OPEN_EXISTING, 0, NULL
|
||||||
);
|
);
|
||||||
if (windevnul == INVALID_HANDLE_VALUE) goto oops;
|
if (windevnul == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (GetLastError());
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QSE_MEMSET (&procinfo, 0, QSE_SIZEOF(procinfo));
|
QSE_MEMSET (&procinfo, 0, QSE_SIZEOF(procinfo));
|
||||||
@ -743,25 +761,7 @@ int qse_pio_init (
|
|||||||
|
|
||||||
QSE_MMGR_FREE (mmgr, dupcmd);
|
QSE_MMGR_FREE (mmgr, dupcmd);
|
||||||
if (x == FALSE)
|
if (x == FALSE)
|
||||||
{
|
pio->errnum = syserr_to_errnum (GetLastError());
|
||||||
DWORD e = GetLastError ();
|
|
||||||
switch (e)
|
|
||||||
{
|
|
||||||
case ERROR_ACCESS_DENIED:
|
|
||||||
pio->errnum = QSE_PIO_EACCES;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ERROR_FILE_NOT_FOUND:
|
|
||||||
case ERROR_PATH_NOT_FOUND:
|
|
||||||
pio->errnum = QSE_PIO_ENOENT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ERROR_NOT_ENOUGH_MEMORY:
|
|
||||||
case ERROR_OUTOFMEMORY:
|
|
||||||
pio->errnum = QSE_PIO_ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (windevnul != INVALID_HANDLE_VALUE)
|
if (windevnul != INVALID_HANDLE_VALUE)
|
||||||
@ -792,18 +792,32 @@ int qse_pio_init (
|
|||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
|
|
||||||
#define DOS_DUP_HANDLE(x,y) QSE_BLOCK ( \
|
#define DOS_DUP_HANDLE(x,y) QSE_BLOCK ( \
|
||||||
if (DosDupHandle(x,y) != NO_ERROR) goto oops; \
|
rc = DosDupHandle(x,y); \
|
||||||
|
if (rc != NO_ERROR) \
|
||||||
|
{ \
|
||||||
|
pio->errnum = syserr_to_errnum (rc); \
|
||||||
|
goto oops; \
|
||||||
|
} \
|
||||||
)
|
)
|
||||||
|
|
||||||
if (flags & QSE_PIO_WRITEIN)
|
if (flags & QSE_PIO_WRITEIN)
|
||||||
{
|
{
|
||||||
/* child reads, parent writes */
|
/* child reads, parent writes */
|
||||||
if (DosCreatePipe (
|
rc = DosCreatePipe (&handle[0], &handle[1], pipe_size);
|
||||||
&handle[0], &handle[1], pipe_size) != NO_ERROR) goto oops;
|
if (rc != NO_ERROR)
|
||||||
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (rc);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
/* the parent writes to handle[1] and the child reads from
|
/* the parent writes to handle[1] and the child reads from
|
||||||
* handle[0] inherited. set the flag not to inherit handle[1]. */
|
* handle[0] inherited. set the flag not to inherit handle[1]. */
|
||||||
if (DosSetFHState (handle[1], OPEN_FLAGS_NOINHERIT) != NO_ERROR) goto oops;
|
rc = DosSetFHState (handle[1], OPEN_FLAGS_NOINHERIT);
|
||||||
|
if (rc != NO_ERROR)
|
||||||
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (rc);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
/* Need to do somthing like this to set the flag instead?
|
/* Need to do somthing like this to set the flag instead?
|
||||||
ULONG state;
|
ULONG state;
|
||||||
@ -816,12 +830,21 @@ int qse_pio_init (
|
|||||||
if (flags & QSE_PIO_READOUT)
|
if (flags & QSE_PIO_READOUT)
|
||||||
{
|
{
|
||||||
/* child writes, parent reads */
|
/* child writes, parent reads */
|
||||||
if (DosCreatePipe (
|
rc = DosCreatePipe (&handle[2], &handle[3], pipe_size);
|
||||||
&handle[2], &handle[3], pipe_size) != NO_ERROR) goto oops;
|
if (rc != NO_ERROR)
|
||||||
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (rc);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
/* the parent reads from handle[2] and the child writes to
|
/* the parent reads from handle[2] and the child writes to
|
||||||
* handle[3] inherited. set the flag not to inherit handle[2] */
|
* handle[3] inherited. set the flag not to inherit handle[2] */
|
||||||
if (DosSetFHState (handle[2], OPEN_FLAGS_NOINHERIT) != NO_ERROR) goto oops;
|
rc = DosSetFHState (handle[2], OPEN_FLAGS_NOINHERIT);
|
||||||
|
if (rc != NO_ERROR)
|
||||||
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (rc);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
if (minidx == -1) minidx = 2;
|
if (minidx == -1) minidx = 2;
|
||||||
maxidx = 3;
|
maxidx = 3;
|
||||||
@ -830,12 +853,21 @@ int qse_pio_init (
|
|||||||
if (flags & QSE_PIO_READERR)
|
if (flags & QSE_PIO_READERR)
|
||||||
{
|
{
|
||||||
/* child writes, parent reads */
|
/* child writes, parent reads */
|
||||||
if (DosCreatePipe (
|
rc = DosCreatePipe (&handle[4], &handle[5], pipe_size);
|
||||||
&handle[4], &handle[5], pipe_size) != NO_ERROR) goto oops;
|
if (rc != NO_ERROR)
|
||||||
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (rc);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
/* the parent reads from handle[4] and the child writes to
|
/* the parent reads from handle[4] and the child writes to
|
||||||
* handle[5] inherited. set the flag not to inherit handle[4] */
|
* handle[5] inherited. set the flag not to inherit handle[4] */
|
||||||
if (DosSetFHState (handle[4], OPEN_FLAGS_NOINHERIT) != NO_ERROR) goto oops;
|
rc = DosSetFHState (handle[4], OPEN_FLAGS_NOINHERIT);
|
||||||
|
if (rc != NO_ERROR)
|
||||||
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (rc);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
if (minidx == -1) minidx = 4;
|
if (minidx == -1) minidx = 4;
|
||||||
maxidx = 5;
|
maxidx = 5;
|
||||||
@ -867,22 +899,32 @@ int qse_pio_init (
|
|||||||
OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE,
|
OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE,
|
||||||
0L
|
0L
|
||||||
);
|
);
|
||||||
if (rc != NO_ERROR) goto oops;
|
if (rc != NO_ERROR)
|
||||||
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (rc);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* duplicate the current stdin/out/err to old_in/out/err as a new handle */
|
/* duplicate the current stdin/out/err to old_in/out/err as a new handle */
|
||||||
|
|
||||||
if (DosDupHandle (std_in, &old_in) != NO_ERROR)
|
rc = DosDupHandle (std_in, &old_in);
|
||||||
|
if (rc != NO_ERROR)
|
||||||
{
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (rc);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
if (DosDupHandle (std_out, &old_out) != NO_ERROR)
|
rc = DosDupHandle (std_out, &old_out);
|
||||||
|
if (rc != NO_ERROR)
|
||||||
{
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (rc);
|
||||||
DosClose (old_in); old_in = QSE_PIO_HND_NIL;
|
DosClose (old_in); old_in = QSE_PIO_HND_NIL;
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
if (DosDupHandle (std_err, &old_err) != NO_ERROR)
|
rc = DosDupHandle (std_err, &old_err);
|
||||||
|
if (rc != NO_ERROR)
|
||||||
{
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (rc);
|
||||||
DosClose (old_out); old_out = QSE_PIO_HND_NIL;
|
DosClose (old_out); old_out = QSE_PIO_HND_NIL;
|
||||||
DosClose (old_in); old_in = QSE_PIO_HND_NIL;
|
DosClose (old_in); old_in = QSE_PIO_HND_NIL;
|
||||||
goto oops;
|
goto oops;
|
||||||
@ -1060,8 +1102,6 @@ int qse_pio_init (
|
|||||||
cmd_file
|
cmd_file
|
||||||
);
|
);
|
||||||
|
|
||||||
/* TODO: translate error code ... */
|
|
||||||
|
|
||||||
QSE_MMGR_FREE (mmgr, cmd_line);
|
QSE_MMGR_FREE (mmgr, cmd_line);
|
||||||
cmd_line = QSE_NULL;
|
cmd_line = QSE_NULL;
|
||||||
|
|
||||||
@ -1074,7 +1114,11 @@ int qse_pio_init (
|
|||||||
DosDupHandle (old_err, &std_err);
|
DosDupHandle (old_err, &std_err);
|
||||||
DosClose (old_err); old_err = QSE_PIO_HND_NIL;
|
DosClose (old_err); old_err = QSE_PIO_HND_NIL;
|
||||||
|
|
||||||
if (rc != NO_ERROR) goto oops;
|
if (rc != NO_ERROR)
|
||||||
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (rc);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
pio->child = child_rc.codeTerminate;
|
pio->child = child_rc.codeTerminate;
|
||||||
|
|
||||||
#elif defined(__DOS__)
|
#elif defined(__DOS__)
|
||||||
@ -1085,20 +1129,32 @@ int qse_pio_init (
|
|||||||
#elif defined(HAVE_POSIX_SPAWN)
|
#elif defined(HAVE_POSIX_SPAWN)
|
||||||
if (flags & QSE_PIO_WRITEIN)
|
if (flags & QSE_PIO_WRITEIN)
|
||||||
{
|
{
|
||||||
if (QSE_PIPE(&handle[0]) <= -1) goto oops;
|
if (QSE_PIPE(&handle[0]) <= -1)
|
||||||
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (errno);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
minidx = 0; maxidx = 1;
|
minidx = 0; maxidx = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & QSE_PIO_READOUT)
|
if (flags & QSE_PIO_READOUT)
|
||||||
{
|
{
|
||||||
if (QSE_PIPE(&handle[2]) <= -1) goto oops;
|
if (QSE_PIPE(&handle[2]) <= -1)
|
||||||
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (errno);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
if (minidx == -1) minidx = 2;
|
if (minidx == -1) minidx = 2;
|
||||||
maxidx = 3;
|
maxidx = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & QSE_PIO_READERR)
|
if (flags & QSE_PIO_READERR)
|
||||||
{
|
{
|
||||||
if (QSE_PIPE(&handle[4]) <= -1) goto oops;
|
if (QSE_PIPE(&handle[4]) <= -1)
|
||||||
|
{
|
||||||
|
pio->errnum = syserr_to_errnum (errno);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
if (minidx == -1) minidx = 4;
|
if (minidx == -1) minidx = 4;
|
||||||
maxidx = 5;
|
maxidx = 5;
|
||||||
}
|
}
|
||||||
|
@ -411,94 +411,21 @@ qse_httpd_task_t* qse_httpd_entaskcontinue (
|
|||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#if 0
|
qse_httpd_task_t* qse_httpd_entaskauth (
|
||||||
typedef struct task_file_t task_file_t;
|
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||||
struct task_file_t
|
const qse_httpd_task_t* task, const qse_mchar_t* realm, qse_htre_t* req)
|
||||||
{
|
{
|
||||||
qse_ubi_t handle;
|
const qse_http_version_t* version = qse_htre_getversion(req);
|
||||||
qse_foff_t left;
|
/* TODO: */
|
||||||
qse_foff_t offset;
|
return qse_httpd_entaskformat (
|
||||||
};
|
httpd, client, task,
|
||||||
|
QSE_MT("HTTP/%d.%d 401 Unauthorized\r\nContent-Length: 0\r\nWWW-Authenticate: Digest realm=\"%s\", qop=\"auth\", nonce=\"%s\""),
|
||||||
static int task_init_file (
|
version->major, version->minor);
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
|
||||||
{
|
|
||||||
task_file_t* xtn = qse_httpd_gettaskxtn (httpd, task);
|
|
||||||
QSE_MEMCPY (xtn, task->ctx, QSE_SIZEOF(*xtn));
|
|
||||||
task->ctx = xtn;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void task_fini_file (
|
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
|
||||||
{
|
|
||||||
task_file_t* ctx = (task_file_t*)task->ctx;
|
|
||||||
qse_printf (QSE_T("closing file %d\n"), ctx->handle.i);
|
|
||||||
QSE_CLOSE (ctx->handle.i);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int task_main_file (
|
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
|
||||||
{
|
|
||||||
qse_ssize_t n;
|
|
||||||
qse_size_t count;
|
|
||||||
task_file_t* ctx = (task_file_t*)task->ctx;
|
|
||||||
|
|
||||||
count = MAX_SEND_SIZE;
|
|
||||||
if (count >= ctx->left) count = ctx->left;
|
|
||||||
|
|
||||||
/* TODO: more adjustment needed for OS with different sendfile semantics... */
|
|
||||||
n = httpd->cbs->client.sendfile (
|
|
||||||
httpd, client, ctx->handle, &ctx->offset, count);
|
|
||||||
if (n <= -1)
|
|
||||||
{
|
|
||||||
// HANDLE EGAIN specially???
|
|
||||||
return -1; /* TODO: any logging */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n == 0 && count > 0)
|
|
||||||
{
|
|
||||||
/* The file could be truncated when this condition is set.
|
|
||||||
* The content-length sent in the header can't be fulfilled.
|
|
||||||
* So let's return an error here so that the main loop abort
|
|
||||||
* the connection. */
|
|
||||||
/* TODO: any logging....??? */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->left -= n;
|
|
||||||
if (ctx->left <= 0) return 0;
|
|
||||||
|
|
||||||
return 1; /* more work to do */
|
|
||||||
}
|
|
||||||
|
|
||||||
qse_httpd_task_t* qse_httpd_entaskfile (
|
|
||||||
qse_httpd_t* httpd,
|
|
||||||
qse_httpd_client_t* client,
|
|
||||||
const qse_httpd_task_t* pred,
|
|
||||||
qse_ubi_t handle,
|
|
||||||
qse_foff_t offset,
|
|
||||||
qse_foff_t size)
|
|
||||||
{
|
|
||||||
qse_httpd_task_t task;
|
|
||||||
task_file_t data;
|
|
||||||
|
|
||||||
QSE_MEMSET (&data, 0, QSE_SIZEOF(data));
|
|
||||||
data.handle = handle;
|
|
||||||
data.offset = offset;
|
|
||||||
data.left = size;
|
|
||||||
|
|
||||||
QSE_MEMSET (&task, 0, QSE_SIZEOF(task));
|
|
||||||
task.init = task_init_file;
|
|
||||||
task.main = task_main_file;
|
|
||||||
task.fini = task_fini_file;
|
|
||||||
task.ctx = &data;
|
|
||||||
|
|
||||||
qse_printf (QSE_T("Debug: entasking file (%d)\n"), client->handle.i);
|
|
||||||
return qse_httpd_entask (httpd, client, pred, &task, QSE_SIZEOF(data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if 0
|
||||||
typedef struct task_dir_t task_dir_t;
|
typedef struct task_dir_t task_dir_t;
|
||||||
struct task_dir_t
|
struct task_dir_t
|
||||||
{
|
{
|
||||||
@ -867,161 +794,6 @@ static int task_init_path (
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QSE_INLINE int task_main_path_file (
|
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
|
||||||
qse_httpd_task_t* task, qse_foff_t filesize)
|
|
||||||
{
|
|
||||||
task_path_t* data = (task_path_t*)task->ctx;
|
|
||||||
qse_httpd_task_t* x = task;
|
|
||||||
qse_ubi_t handle;
|
|
||||||
int oflags;
|
|
||||||
|
|
||||||
/* TODO: if you should deal with files on a network-mounted drive,
|
|
||||||
setting a trigger or non-blocking I/O are needed. */
|
|
||||||
|
|
||||||
/* when it comes to the file size, using fstat after opening
|
|
||||||
* can be more accurate. but this function uses information
|
|
||||||
* set into the task context before the call to this function */
|
|
||||||
|
|
||||||
qse_printf (QSE_T("opening file %hs\n"), data->name);
|
|
||||||
|
|
||||||
oflags = O_RDONLY;
|
|
||||||
#if defined(O_LARGEFILE)
|
|
||||||
oflags |= O_LARGEFILE;
|
|
||||||
#endif
|
|
||||||
handle.i = QSE_OPEN (data->name, oflags, 0);
|
|
||||||
if (handle.i <= -1)
|
|
||||||
{
|
|
||||||
x = entask_error (
|
|
||||||
httpd, client, x, 404, &data->version, data->keepalive);
|
|
||||||
goto no_file_send;
|
|
||||||
}
|
|
||||||
oflags = QSE_FCNTL (handle.i, F_GETFD, 0);
|
|
||||||
if (oflags >= 0)
|
|
||||||
QSE_FCNTL (handle.i, F_SETFD, oflags | FD_CLOEXEC);
|
|
||||||
|
|
||||||
if (data->range.type != QSE_HTTP_RANGE_NONE)
|
|
||||||
{
|
|
||||||
const qse_mchar_t* mime_type = QSE_NULL;
|
|
||||||
|
|
||||||
if (data->range.type == QSE_HTTP_RANGE_SUFFIX)
|
|
||||||
{
|
|
||||||
if (data->range.to > filesize) data->range.to = filesize;
|
|
||||||
data->range.from = filesize - data->range.to;
|
|
||||||
data->range.to = data->range.to + data->range.from;
|
|
||||||
if (filesize > 0) data->range.to--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data->range.from >= filesize)
|
|
||||||
{
|
|
||||||
x = entask_error (
|
|
||||||
httpd, client, x, 416, &data->version, data->keepalive);
|
|
||||||
goto no_file_send;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data->range.to >= filesize) data->range.to = filesize - 1;
|
|
||||||
|
|
||||||
if (httpd->cbs->getmimetype)
|
|
||||||
{
|
|
||||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
|
||||||
mime_type = httpd->cbs->getmimetype (httpd, data->name);
|
|
||||||
/*TODO: how to handle an error... */
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (QSE_SIZEOF_LONG_LONG > 0)
|
|
||||||
x = qse_httpd_entaskformat (
|
|
||||||
httpd, client, x,
|
|
||||||
QSE_MT("HTTP/%d.%d 206 Partial Content\r\nConnection: %s\r\n%s%s%sContent-Length: %llu\r\nContent-Range: bytes %llu-%llu/%llu\r\n\r\n"),
|
|
||||||
data->version.major,
|
|
||||||
data->version.minor,
|
|
||||||
(data->keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
|
||||||
(mime_type? QSE_MT("Content-Type: "): QSE_MT("")),
|
|
||||||
(mime_type? mime_type: QSE_MT("")),
|
|
||||||
(mime_type? QSE_MT("\r\n"): QSE_MT("")),
|
|
||||||
(unsigned long long)(data->range.to - data->range.from + 1),
|
|
||||||
(unsigned long long)data->range.from,
|
|
||||||
(unsigned long long)data->range.to,
|
|
||||||
(unsigned long long)filesize
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
x = qse_httpd_entaskformat (
|
|
||||||
httpd, client, x,
|
|
||||||
QSE_MT("HTTP/%d.%d 206 Partial Content\r\nConnection: %s\r\n%s%s%sContent-Length: %lu\r\nContent-Range: bytes %lu-%lu/%lu\r\n\r\n"),
|
|
||||||
data->version.major,
|
|
||||||
data->version.minor,
|
|
||||||
(data->keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
|
||||||
(mime_type? QSE_MT("Content-Type: "): QSE_MT("")),
|
|
||||||
(mime_type? mime_type: QSE_MT("")),
|
|
||||||
(mime_type? QSE_MT("\r\n"): QSE_MT("")),
|
|
||||||
(unsigned long)(data->range.to - data->range.from + 1),
|
|
||||||
(unsigned long)data->range.from,
|
|
||||||
(unsigned long)data->range.to,
|
|
||||||
(unsigned long)filesize
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
if (x)
|
|
||||||
{
|
|
||||||
x = qse_httpd_entaskfile (
|
|
||||||
httpd, client, x,
|
|
||||||
handle,
|
|
||||||
data->range.from,
|
|
||||||
(data->range.to - data->range.from + 1)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* TODO: int64 format.... don't hard code it llu */
|
|
||||||
const qse_mchar_t* mime_type = QSE_NULL;
|
|
||||||
|
|
||||||
if (httpd->cbs->getmimetype)
|
|
||||||
{
|
|
||||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
|
||||||
mime_type = httpd->cbs->getmimetype (httpd, data->name);
|
|
||||||
/*TODO: how to handle an error... */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* wget 1.8.2 set 'Connection: keep-alive' in the http 1.0 header.
|
|
||||||
* if the reply doesn't contain 'Connection: keep-alive', it didn't
|
|
||||||
* close connection.*/
|
|
||||||
#if (QSE_SIZEOF_LONG_LONG > 0)
|
|
||||||
x = qse_httpd_entaskformat (
|
|
||||||
httpd, client, x,
|
|
||||||
QSE_MT("HTTP/%d.%d 200 OK\r\nConnection: %s\r\n%s%s%sContent-Length: %llu\r\n\r\n"),
|
|
||||||
data->version.major, data->version.minor,
|
|
||||||
(data->keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
|
||||||
(mime_type? QSE_MT("Content-Type: "): QSE_MT("")),
|
|
||||||
(mime_type? mime_type: QSE_MT("")),
|
|
||||||
(mime_type? QSE_MT("\r\n"): QSE_MT("")),
|
|
||||||
(unsigned long long)filesize
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
x = qse_httpd_entaskformat (
|
|
||||||
httpd, client, x,
|
|
||||||
QSE_MT("HTTP/%d.%d 200 OK\r\nConnection: %s\r\n%s%s%sContent-Length: %lu\r\n\r\n"),
|
|
||||||
data->version.major,
|
|
||||||
data->version.minor,
|
|
||||||
(data->keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
|
||||||
(mime_type? QSE_MT("Content-Type: "): QSE_MT("")),
|
|
||||||
(mime_type? mime_type: QSE_MT("")),
|
|
||||||
(mime_type? QSE_MT("\r\n"): QSE_MT("")),
|
|
||||||
(unsigned long)filesize
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
if (x)
|
|
||||||
{
|
|
||||||
x = qse_httpd_entaskfile (
|
|
||||||
httpd, client, x, handle, 0, filesize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (x == QSE_NULL)? -1: 0;
|
|
||||||
|
|
||||||
no_file_send:
|
|
||||||
if (handle.i >= 0) close (handle.i);
|
|
||||||
return (x == QSE_NULL)? -1: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QSE_INLINE int task_main_path_dir (
|
static QSE_INLINE int task_main_path_dir (
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
||||||
{
|
{
|
||||||
@ -1259,8 +1031,8 @@ static QSE_INLINE int task_main_file (
|
|||||||
task_file_t* file;
|
task_file_t* file;
|
||||||
qse_httpd_task_t* x;
|
qse_httpd_task_t* x;
|
||||||
qse_ubi_t handle;
|
qse_ubi_t handle;
|
||||||
qse_foff_t filesize;
|
|
||||||
int fileopen = 0;
|
int fileopen = 0;
|
||||||
|
qse_httpd_stat_t st;
|
||||||
|
|
||||||
file = (task_file_t*)task->ctx;
|
file = (task_file_t*)task->ctx;
|
||||||
x = task;
|
x = task;
|
||||||
@ -1271,7 +1043,19 @@ static QSE_INLINE int task_main_file (
|
|||||||
qse_printf (QSE_T("opening file %hs\n"), file->path);
|
qse_printf (QSE_T("opening file %hs\n"), file->path);
|
||||||
|
|
||||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||||
if (httpd->cbs->file.ropen (httpd, file->path, &handle, &filesize) <= -1)
|
if (httpd->cbs->file.stat (httpd, file->path, &st) <= -1)
|
||||||
|
{
|
||||||
|
int http_errnum;
|
||||||
|
http_errnum = (httpd->errnum == QSE_HTTPD_ENOENT)? 404:
|
||||||
|
(httpd->errnum == QSE_HTTPD_EACCES)? 403: 500;
|
||||||
|
x = entask_error (
|
||||||
|
httpd, client, x, http_errnum,
|
||||||
|
&file->version, file->keepalive);
|
||||||
|
goto no_file_send;
|
||||||
|
}
|
||||||
|
|
||||||
|
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||||
|
if (httpd->cbs->file.ropen (httpd, file->path, &handle) <= -1)
|
||||||
{
|
{
|
||||||
int http_errnum;
|
int http_errnum;
|
||||||
http_errnum = (httpd->errnum == QSE_HTTPD_ENOENT)? 404:
|
http_errnum = (httpd->errnum == QSE_HTTPD_ENOENT)? 404:
|
||||||
@ -1285,31 +1069,22 @@ qse_printf (QSE_T("opening file %hs\n"), file->path);
|
|||||||
|
|
||||||
if (file->range.type != QSE_HTTP_RANGE_NONE)
|
if (file->range.type != QSE_HTTP_RANGE_NONE)
|
||||||
{
|
{
|
||||||
const qse_mchar_t* mime_type = QSE_NULL;
|
|
||||||
|
|
||||||
if (file->range.type == QSE_HTTP_RANGE_SUFFIX)
|
if (file->range.type == QSE_HTTP_RANGE_SUFFIX)
|
||||||
{
|
{
|
||||||
if (file->range.to > filesize) file->range.to = filesize;
|
if (file->range.to > st.size) file->range.to = st.size;
|
||||||
file->range.from = filesize - file->range.to;
|
file->range.from = st.size - file->range.to;
|
||||||
file->range.to = file->range.to + file->range.from;
|
file->range.to = file->range.to + file->range.from;
|
||||||
if (filesize > 0) file->range.to--;
|
if (st.size > 0) file->range.to--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file->range.from >= filesize)
|
if (file->range.from >= st.size)
|
||||||
{
|
{
|
||||||
x = entask_error (
|
x = entask_error (
|
||||||
httpd, client, x, 416, &file->version, file->keepalive);
|
httpd, client, x, 416, &file->version, file->keepalive);
|
||||||
goto no_file_send;
|
goto no_file_send;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file->range.to >= filesize) file->range.to = filesize - 1;
|
if (file->range.to >= st.size) file->range.to = st.size - 1;
|
||||||
|
|
||||||
if (httpd->cbs->getmimetype)
|
|
||||||
{
|
|
||||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
|
||||||
mime_type = httpd->cbs->getmimetype (httpd, file->path);
|
|
||||||
/*TODO: how to handle an error... */
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (QSE_SIZEOF_LONG_LONG > 0)
|
#if (QSE_SIZEOF_LONG_LONG > 0)
|
||||||
x = qse_httpd_entaskformat (
|
x = qse_httpd_entaskformat (
|
||||||
@ -1318,13 +1093,13 @@ qse_printf (QSE_T("opening file %hs\n"), file->path);
|
|||||||
file->version.major,
|
file->version.major,
|
||||||
file->version.minor,
|
file->version.minor,
|
||||||
(file->keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
(file->keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||||
(mime_type? QSE_MT("Content-Type: "): QSE_MT("")),
|
(st.mime? QSE_MT("Content-Type: "): QSE_MT("")),
|
||||||
(mime_type? mime_type: QSE_MT("")),
|
(st.mime? st.mime: QSE_MT("")),
|
||||||
(mime_type? QSE_MT("\r\n"): QSE_MT("")),
|
(st.mime? QSE_MT("\r\n"): QSE_MT("")),
|
||||||
(unsigned long long)(file->range.to - file->range.from + 1),
|
(unsigned long long)(file->range.to - file->range.from + 1),
|
||||||
(unsigned long long)file->range.from,
|
(unsigned long long)file->range.from,
|
||||||
(unsigned long long)file->range.to,
|
(unsigned long long)file->range.to,
|
||||||
(unsigned long long)filesize
|
(unsigned long long)st.size
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
x = qse_httpd_entaskformat (
|
x = qse_httpd_entaskformat (
|
||||||
@ -1333,13 +1108,13 @@ qse_printf (QSE_T("opening file %hs\n"), file->path);
|
|||||||
file->version.major,
|
file->version.major,
|
||||||
file->version.minor,
|
file->version.minor,
|
||||||
(file->keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
(file->keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||||
(mime_type? QSE_MT("Content-Type: "): QSE_MT("")),
|
(st.mime? QSE_MT("Content-Type: "): QSE_MT("")),
|
||||||
(mime_type? mime_type: QSE_MT("")),
|
(st.mime? st.mime: QSE_MT("")),
|
||||||
(mime_type? QSE_MT("\r\n"): QSE_MT("")),
|
(st.mime? QSE_MT("\r\n"): QSE_MT("")),
|
||||||
(unsigned long)(file->range.to - file->range.from + 1),
|
(unsigned long)(file->range.to - file->range.from + 1),
|
||||||
(unsigned long)file->range.from,
|
(unsigned long)file->range.from,
|
||||||
(unsigned long)file->range.to,
|
(unsigned long)file->range.to,
|
||||||
(unsigned long)filesize
|
(unsigned long)st.size
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
if (x)
|
if (x)
|
||||||
@ -1355,15 +1130,6 @@ qse_printf (QSE_T("opening file %hs\n"), file->path);
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* TODO: int64 format.... don't hard code it llu */
|
/* TODO: int64 format.... don't hard code it llu */
|
||||||
const qse_mchar_t* mime_type = QSE_NULL;
|
|
||||||
|
|
||||||
if (httpd->cbs->getmimetype)
|
|
||||||
{
|
|
||||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
|
||||||
mime_type = httpd->cbs->getmimetype (httpd, file->path);
|
|
||||||
/*TODO: how to handle an error... */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* wget 1.8.2 set 'Connection: keep-alive' in the http 1.0 header.
|
/* wget 1.8.2 set 'Connection: keep-alive' in the http 1.0 header.
|
||||||
* if the reply doesn't contain 'Connection: keep-alive', it didn't
|
* if the reply doesn't contain 'Connection: keep-alive', it didn't
|
||||||
* close connection.*/
|
* close connection.*/
|
||||||
@ -1373,10 +1139,10 @@ qse_printf (QSE_T("opening file %hs\n"), file->path);
|
|||||||
QSE_MT("HTTP/%d.%d 200 OK\r\nConnection: %s\r\n%s%s%sContent-Length: %llu\r\n\r\n"),
|
QSE_MT("HTTP/%d.%d 200 OK\r\nConnection: %s\r\n%s%s%sContent-Length: %llu\r\n\r\n"),
|
||||||
file->version.major, file->version.minor,
|
file->version.major, file->version.minor,
|
||||||
(file->keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
(file->keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||||
(mime_type? QSE_MT("Content-Type: "): QSE_MT("")),
|
(st.mime? QSE_MT("Content-Type: "): QSE_MT("")),
|
||||||
(mime_type? mime_type: QSE_MT("")),
|
(st.mime? st.mime: QSE_MT("")),
|
||||||
(mime_type? QSE_MT("\r\n"): QSE_MT("")),
|
(st.mime? QSE_MT("\r\n"): QSE_MT("")),
|
||||||
(unsigned long long)filesize
|
(unsigned long long)st.size
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
x = qse_httpd_entaskformat (
|
x = qse_httpd_entaskformat (
|
||||||
@ -1385,16 +1151,15 @@ qse_printf (QSE_T("opening file %hs\n"), file->path);
|
|||||||
file->version.major,
|
file->version.major,
|
||||||
file->version.minor,
|
file->version.minor,
|
||||||
(file->keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
(file->keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||||
(mime_type? QSE_MT("Content-Type: "): QSE_MT("")),
|
(st.mime? QSE_MT("Content-Type: "): QSE_MT("")),
|
||||||
(mime_type? mime_type: QSE_MT("")),
|
(st.mime? st.mime: QSE_MT("")),
|
||||||
(mime_type? QSE_MT("\r\n"): QSE_MT("")),
|
(st.mime? QSE_MT("\r\n"): QSE_MT("")),
|
||||||
(unsigned long)filesize
|
(unsigned long)st.size
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
if (x)
|
if (x)
|
||||||
{
|
{
|
||||||
x = entask_file_segment (
|
x = entask_file_segment (httpd, client, x, handle, 0, st.size);
|
||||||
httpd, client, x, handle, 0, filesize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1772,6 +1537,7 @@ qse_mbsxncpy (tmp, QSE_COUNTOF(tmp), qse_htre_getqpathptr(req), qse_htre_getqpat
|
|||||||
qse_env_insertmbs (env, QSE_MT("SERVER_PROTOCOL"), proto);
|
qse_env_insertmbs (env, QSE_MT("SERVER_PROTOCOL"), proto);
|
||||||
}
|
}
|
||||||
// TODO: HTTP_ headers.
|
// TODO: HTTP_ headers.
|
||||||
|
// TODO: REMOTE_USER ...
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
qse_env_insertmbs (env, "SERVER_NAME",
|
qse_env_insertmbs (env, "SERVER_NAME",
|
||||||
@ -2573,19 +2339,6 @@ static QSE_INLINE qse_httpd_task_t* entask_cgi (
|
|||||||
qse_httpd_task_t task;
|
qse_httpd_task_t task;
|
||||||
task_cgi_arg_t arg;
|
task_cgi_arg_t arg;
|
||||||
|
|
||||||
#if 0
|
|
||||||
int x;
|
|
||||||
|
|
||||||
/* TODO: NEED TO CHECK IF it's a regular file and executable??
|
|
||||||
directory may be treated as executable???
|
|
||||||
*/
|
|
||||||
x = httpd->cbs->path.executable (httpd, path);
|
|
||||||
if (x == 0)
|
|
||||||
return qse_httpd_entaskerror (httpd, client, pred, 403, req);
|
|
||||||
else if (x <= -1)
|
|
||||||
return qse_httpd_entaskerror (httpd, client, pred, 404, req);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
arg.path = path;
|
arg.path = path;
|
||||||
arg.req = req;
|
arg.req = req;
|
||||||
arg.nph = nph;
|
arg.nph = nph;
|
||||||
|
@ -5,9 +5,11 @@
|
|||||||
#include <qse/cmn/str.h>
|
#include <qse/cmn/str.h>
|
||||||
#include <qse/cmn/mem.h>
|
#include <qse/cmn/mem.h>
|
||||||
#include <qse/cmn/mbwc.h>
|
#include <qse/cmn/mbwc.h>
|
||||||
|
#include <qse/cmn/time.h>
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
#include <string.h>
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#else
|
#else
|
||||||
@ -18,6 +20,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/engine.h>
|
||||||
|
|
||||||
|
|
||||||
// TODO: remove this and export structured needed like qse_httpd_client_t
|
// TODO: remove this and export structured needed like qse_httpd_client_t
|
||||||
@ -226,22 +230,59 @@ static int mux_writable (qse_httpd_t* httpd, qse_ubi_t handle, qse_ntoff_t msec)
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int path_executable (qse_httpd_t* httpd, const qse_mchar_t* path)
|
static int file_executable (qse_httpd_t* httpd, const qse_mchar_t* path)
|
||||||
{
|
{
|
||||||
if (access (path, X_OK) == -1)
|
if (access (path, X_OK) == -1)
|
||||||
return (errno == EACCES)? 0 /*no*/: -1 /*error*/;
|
return (errno == EACCES)? 0 /*no*/: -1 /*error*/;
|
||||||
return 1; /* yes */
|
return 1; /* yes */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------- */
|
static int file_stat (
|
||||||
|
qse_httpd_t* httpd, const qse_mchar_t* path, qse_httpd_stat_t* hst)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
/* TODO: lstat? or stat? */
|
||||||
|
if (stat (path, &st) <= -1)
|
||||||
|
{
|
||||||
|
qse_httpd_seterrnum (httpd,
|
||||||
|
(errno == ENOENT? QSE_HTTPD_ENOENT:
|
||||||
|
errno == EACCES? QSE_HTTPD_EACCES: QSE_HTTPD_ESUBSYS));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stating for a file. it should be a regular file.
|
||||||
|
* i don't allow other file types. */
|
||||||
|
if (!S_ISREG(st.st_mode))
|
||||||
|
{
|
||||||
|
qse_httpd_seterrnum (httpd, QSE_HTTPD_EACCES);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (hst, 0, QSE_SIZEOF(*hst));
|
||||||
|
|
||||||
|
hst->size = st.st_size;
|
||||||
|
#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
|
||||||
|
hst->mtime = QSE_SECNSEC_TO_MSEC(st.st_mtim.tv_sec,st.st_mtim.tv_nsec);
|
||||||
|
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
|
||||||
|
hst->mtime = QSE_SECNSEC_TO_MSEC(st.st_mtimespec.tv_sec,st.st_mtimespec.tv_nsec);
|
||||||
|
#else
|
||||||
|
hst->mtime = st.st_mtime * QSE_MSECS_PER_SEC;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hst->mime = qse_mbsend (path, QSE_MT(".html"))? QSE_MT("text/html"):
|
||||||
|
qse_mbsend (path, QSE_MT(".txt"))? QSE_MT("text/plain"):
|
||||||
|
qse_mbsend (path, QSE_MT(".jpg"))? QSE_MT("image/jpeg"):
|
||||||
|
qse_mbsend (path, QSE_MT(".mp4"))? QSE_MT("video/mp4"):
|
||||||
|
qse_mbsend (path, QSE_MT(".mp3"))? QSE_MT("audio/mpeg"): QSE_NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int file_ropen (
|
static int file_ropen (
|
||||||
qse_httpd_t* httpd, const qse_mchar_t* path,
|
qse_httpd_t* httpd, const qse_mchar_t* path, qse_ubi_t* handle)
|
||||||
qse_ubi_t* handle, qse_foff_t* size)
|
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int flags;
|
int flags;
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
flags = O_RDONLY;
|
flags = O_RDONLY;
|
||||||
#if defined(O_LARGEFILE)
|
#if defined(O_LARGEFILE)
|
||||||
@ -261,25 +302,6 @@ qse_printf (QSE_T("opening file [%hs] for reading\n"), path);
|
|||||||
flags = fcntl (fd, F_GETFD);
|
flags = fcntl (fd, F_GETFD);
|
||||||
if (flags >= 0) fcntl (fd, F_SETFD, flags | FD_CLOEXEC);
|
if (flags >= 0) fcntl (fd, F_SETFD, flags | FD_CLOEXEC);
|
||||||
|
|
||||||
/* TODO: fstat64??? */
|
|
||||||
if (fstat (fd, &st) <= -1)
|
|
||||||
{
|
|
||||||
qse_httpd_seterrnum (httpd,
|
|
||||||
(errno == ENOENT? QSE_HTTPD_ENOENT:
|
|
||||||
errno == EACCES? QSE_HTTPD_EACCES: QSE_HTTPD_ESUBSYS));
|
|
||||||
close (fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check if it is a link. symbolic link??? */
|
|
||||||
if (!S_ISREG(st.st_mode))
|
|
||||||
{
|
|
||||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_EACCES);
|
|
||||||
close (fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*size = (st.st_size <= 0)? 0: st.st_size;
|
|
||||||
handle->i = fd;
|
handle->i = fd;
|
||||||
qse_printf (QSE_T("opened file %hs\n"), path);
|
qse_printf (QSE_T("opened file %hs\n"), path);
|
||||||
return 0;
|
return 0;
|
||||||
@ -617,16 +639,6 @@ static int handle_request (
|
|||||||
return process_request (httpd, client, req, 0);
|
return process_request (httpd, client, req, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const qse_mchar_t* get_mime_type (qse_httpd_t* httpd, const qse_mchar_t* path)
|
|
||||||
{
|
|
||||||
if (qse_mbsend (path, QSE_MT(".html"))) return QSE_MT("text/html");
|
|
||||||
if (qse_mbsend (path, QSE_MT(".txt"))) return QSE_MT("text/plain");
|
|
||||||
if (qse_mbsend (path, QSE_MT(".jpg"))) return QSE_MT("image/jpeg");
|
|
||||||
if (qse_mbsend (path, QSE_MT(".mp4"))) return QSE_MT("video/mp4");
|
|
||||||
if (qse_mbsend (path, QSE_MT(".mp3"))) return QSE_MT("audio/mpeg");
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int list_directory (qse_httpd_t* httpd, const qse_mchar_t* path)
|
int list_directory (qse_httpd_t* httpd, const qse_mchar_t* path)
|
||||||
{
|
{
|
||||||
return 404;
|
return 404;
|
||||||
@ -637,11 +649,10 @@ static qse_httpd_cbs_t httpd_cbs =
|
|||||||
/* multiplexer */
|
/* multiplexer */
|
||||||
{ mux_readable, mux_writable },
|
{ mux_readable, mux_writable },
|
||||||
|
|
||||||
/* path operation */
|
|
||||||
{ path_executable },
|
|
||||||
|
|
||||||
/* file operation */
|
/* file operation */
|
||||||
{ file_ropen,
|
{ file_executable,
|
||||||
|
file_stat,
|
||||||
|
file_ropen,
|
||||||
file_wopen,
|
file_wopen,
|
||||||
file_close,
|
file_close,
|
||||||
file_read,
|
file_read,
|
||||||
@ -659,7 +670,6 @@ static qse_httpd_cbs_t httpd_cbs =
|
|||||||
peek_request,
|
peek_request,
|
||||||
handle_request,
|
handle_request,
|
||||||
|
|
||||||
get_mime_type,
|
|
||||||
list_directory
|
list_directory
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user