moved more files to si
This commit is contained in:
@ -63,10 +63,6 @@ libqsecmn_la_SOURCES = \
|
||||
mbwc.c \
|
||||
mbwc-str.c \
|
||||
mem.c \
|
||||
nwad.c \
|
||||
nwad-skad.c \
|
||||
nwif.c \
|
||||
nwif-cfg.c \
|
||||
oht.c \
|
||||
opt.c \
|
||||
path-base.c \
|
||||
@ -76,7 +72,6 @@ libqsecmn_la_SOURCES = \
|
||||
pma.c \
|
||||
rbt.c \
|
||||
rex.c \
|
||||
sck.c \
|
||||
sll.c \
|
||||
slmb.c \
|
||||
str-beg.c \
|
||||
|
@ -136,17 +136,16 @@ am__libqsecmn_la_SOURCES_DIST = alg-base64.c alg-rand.c alg-search.c \
|
||||
alg-sort.c assert.c chr.c dir.c dll.c env.c gdl.c htb.c fma.c \
|
||||
fmt-intmax.c fmt-out.c fs.c fs-attr.c fs-copy.c fs-delete.c \
|
||||
fs-err.c fs-make.c fs-move.c glob.c hton.c ipad.c lda.c main.c \
|
||||
mb8.c mbwc.c mbwc-str.c mem.c nwad.c nwad-skad.c nwif.c \
|
||||
nwif-cfg.c oht.c opt.c path-base.c path-canon.c path-core.c \
|
||||
path-merge.c pma.c rbt.c rex.c sck.c sll.c slmb.c str-beg.c \
|
||||
str-cat.c str-chr.c str-cnv.c str-cmp.c str-cpy.c str-del.c \
|
||||
str-dup.c str-dyn.c str-end.c str-excl.c str-fcpy.c str-fmt.c \
|
||||
str-fnmat.c str-incl.c str-join.c str-len.c str-pac.c \
|
||||
str-pbrk.c str-put.c str-rev.c str-rot.c str-set.c str-spl.c \
|
||||
str-spn.c str-str.c str-subst.c str-tok.c str-trm.c str-word.c \
|
||||
time.c tmr.c tre.c tre-ast.c tre-compile.c tre-match-bt.c \
|
||||
tre-match-pa.c tre-parse.c tre-stack.c uri.c utf8.c xma.c \
|
||||
uni.c cp949.c cp950.c
|
||||
mb8.c mbwc.c mbwc-str.c mem.c oht.c opt.c path-base.c \
|
||||
path-canon.c path-core.c path-merge.c pma.c rbt.c rex.c sll.c \
|
||||
slmb.c str-beg.c str-cat.c str-chr.c str-cnv.c str-cmp.c \
|
||||
str-cpy.c str-del.c str-dup.c str-dyn.c str-end.c str-excl.c \
|
||||
str-fcpy.c str-fmt.c str-fnmat.c str-incl.c str-join.c \
|
||||
str-len.c str-pac.c str-pbrk.c str-put.c str-rev.c str-rot.c \
|
||||
str-set.c str-spl.c str-spn.c str-str.c str-subst.c str-tok.c \
|
||||
str-trm.c str-word.c time.c tmr.c tre.c tre-ast.c \
|
||||
tre-compile.c tre-match-bt.c tre-match-pa.c tre-parse.c \
|
||||
tre-stack.c uri.c utf8.c xma.c uni.c cp949.c cp950.c
|
||||
@ENABLE_BUNDLED_UNICODE_TRUE@am__objects_1 = uni.lo
|
||||
@ENABLE_XCMGRS_TRUE@am__objects_2 = cp949.lo cp950.lo
|
||||
am_libqsecmn_la_OBJECTS = alg-base64.lo alg-rand.lo alg-search.lo \
|
||||
@ -154,9 +153,8 @@ am_libqsecmn_la_OBJECTS = alg-base64.lo alg-rand.lo alg-search.lo \
|
||||
htb.lo fma.lo fmt-intmax.lo fmt-out.lo fs.lo fs-attr.lo \
|
||||
fs-copy.lo fs-delete.lo fs-err.lo fs-make.lo fs-move.lo \
|
||||
glob.lo hton.lo ipad.lo lda.lo main.lo mb8.lo mbwc.lo \
|
||||
mbwc-str.lo mem.lo nwad.lo nwad-skad.lo nwif.lo nwif-cfg.lo \
|
||||
oht.lo opt.lo path-base.lo path-canon.lo path-core.lo \
|
||||
path-merge.lo pma.lo rbt.lo rex.lo sck.lo sll.lo slmb.lo \
|
||||
mbwc-str.lo mem.lo oht.lo opt.lo path-base.lo path-canon.lo \
|
||||
path-core.lo path-merge.lo pma.lo rbt.lo rex.lo sll.lo slmb.lo \
|
||||
str-beg.lo str-cat.lo str-chr.lo str-cnv.lo str-cmp.lo \
|
||||
str-cpy.lo str-del.lo str-dup.lo str-dyn.lo str-end.lo \
|
||||
str-excl.lo str-fcpy.lo str-fmt.lo str-fnmat.lo str-incl.lo \
|
||||
@ -477,17 +475,16 @@ libqsecmn_la_SOURCES = alg-base64.c alg-rand.c alg-search.c alg-sort.c \
|
||||
assert.c chr.c dir.c dll.c env.c gdl.c htb.c fma.c \
|
||||
fmt-intmax.c fmt-out.c fs.c fs-attr.c fs-copy.c fs-delete.c \
|
||||
fs-err.c fs-make.c fs-move.c glob.c hton.c ipad.c lda.c main.c \
|
||||
mb8.c mbwc.c mbwc-str.c mem.c nwad.c nwad-skad.c nwif.c \
|
||||
nwif-cfg.c oht.c opt.c path-base.c path-canon.c path-core.c \
|
||||
path-merge.c pma.c rbt.c rex.c sck.c sll.c slmb.c str-beg.c \
|
||||
str-cat.c str-chr.c str-cnv.c str-cmp.c str-cpy.c str-del.c \
|
||||
str-dup.c str-dyn.c str-end.c str-excl.c str-fcpy.c str-fmt.c \
|
||||
str-fnmat.c str-incl.c str-join.c str-len.c str-pac.c \
|
||||
str-pbrk.c str-put.c str-rev.c str-rot.c str-set.c str-spl.c \
|
||||
str-spn.c str-str.c str-subst.c str-tok.c str-trm.c str-word.c \
|
||||
time.c tmr.c tre.c tre-ast.c tre-compile.c tre-match-bt.c \
|
||||
tre-match-pa.c tre-parse.c tre-stack.c uri.c utf8.c xma.c \
|
||||
$(am__append_1) $(am__append_2)
|
||||
mb8.c mbwc.c mbwc-str.c mem.c oht.c opt.c path-base.c \
|
||||
path-canon.c path-core.c path-merge.c pma.c rbt.c rex.c sll.c \
|
||||
slmb.c str-beg.c str-cat.c str-chr.c str-cnv.c str-cmp.c \
|
||||
str-cpy.c str-del.c str-dup.c str-dyn.c str-end.c str-excl.c \
|
||||
str-fcpy.c str-fmt.c str-fnmat.c str-incl.c str-join.c \
|
||||
str-len.c str-pac.c str-pbrk.c str-put.c str-rev.c str-rot.c \
|
||||
str-set.c str-spl.c str-spn.c str-str.c str-subst.c str-tok.c \
|
||||
str-trm.c str-word.c time.c tmr.c tre.c tre-ast.c \
|
||||
tre-compile.c tre-match-bt.c tre-match-pa.c tre-parse.c \
|
||||
tre-stack.c uri.c utf8.c xma.c $(am__append_1) $(am__append_2)
|
||||
libqsecmn_la_LDFLAGS = -version-info 1:0:0 -no-undefined
|
||||
libqsecmn_la_LIBADD = $(SOCKET_LIBS) $(QUADMATH_LIBS)
|
||||
@ENABLE_CXX_TRUE@libqsecmnxx_la_SOURCES = \
|
||||
@ -615,10 +612,6 @@ distclean-compile:
|
||||
@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)/mem.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nwad-skad.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nwad.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nwif-cfg.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nwif.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)/path-base.Plo@am__quote@
|
||||
@ -628,7 +621,6 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pma.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rbt.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rex.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sck.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sll.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slmb.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-beg.Plo@am__quote@
|
||||
|
@ -218,7 +218,7 @@ void qse_assert_failed (
|
||||
QSE_MT("|_____|_____|__| |_____|__|\n"),
|
||||
QSE_MT(" \n")
|
||||
};
|
||||
static qse_mchar_t* static_header = QSE_MT("=[ASSERTION FAILURE]============================================================\n"),
|
||||
static qse_mchar_t* static_header = QSE_MT("=[ASSERTION FAILURE]============================================================\n");
|
||||
static qse_mchar_t* static_bthdr = QSE_MT("=[BACKTRACES]===================================================================\n");
|
||||
static qse_mchar_t* static_footer = QSE_MT("================================================================================\n");
|
||||
|
||||
|
@ -1,294 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <qse/cmn/nwad.h>
|
||||
#include "mem.h"
|
||||
#include <qse/cmn/mbwc.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h> /* sockaddr_in6 */
|
||||
# include <windows.h>
|
||||
# undef AF_UNIX
|
||||
# if defined(__WATCOMC__) && (__WATCOMC__ < 1200)
|
||||
/* the header files shipped with watcom 11 doesn't contain
|
||||
* proper inet6 support. note using the compiler version
|
||||
* in the contidional isn't that good idea since you
|
||||
* can use newer header files with this old compiler.
|
||||
* never mind it for the time being.
|
||||
*/
|
||||
# undef AF_INET6
|
||||
# endif
|
||||
#elif defined(__OS2__)
|
||||
# include <types.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
/* though AF_INET6 is defined, there is no support
|
||||
* for it. so undefine it */
|
||||
# undef AF_INET6
|
||||
# undef AF_UNIX
|
||||
# pragma library("tcpip32.lib")
|
||||
#elif defined(__DOS__)
|
||||
# include <tcp.h> /* watt-32 */
|
||||
# undef AF_UNIX
|
||||
#else
|
||||
# if defined(HAVE_SYS_TYPES_H)
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# if defined(HAVE_SYS_UN_H)
|
||||
# include <sys/un.h>
|
||||
# endif
|
||||
|
||||
# if defined(QSE_SIZEOF_STRUCT_SOCKADDR_IN6) && (QSE_SIZEOF_STRUCT_SOCKADDR_IN6 <= 0)
|
||||
# undef AF_INET6
|
||||
# endif
|
||||
|
||||
# if defined(QSE_SIZEOF_STRUCT_SOCKADDR_UN) && (QSE_SIZEOF_STRUCT_SOCKADDR_UN <= 0)
|
||||
# undef AF_UNIX
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
union sockaddr_t
|
||||
{
|
||||
#if defined(AF_INET) || defined(AF_INET6) || defined(AF_UNIX)
|
||||
#if defined(AF_INET)
|
||||
struct sockaddr_in in4;
|
||||
#endif
|
||||
#if defined(AF_INET6)
|
||||
struct sockaddr_in6 in6;
|
||||
#endif
|
||||
#if defined(AF_UNIX)
|
||||
struct sockaddr_un un;
|
||||
#endif
|
||||
#else
|
||||
int dummy;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef union sockaddr_t sockaddr_t;
|
||||
|
||||
#if defined(AF_INET)
|
||||
# define FAMILY(x) (((struct sockaddr_in*)(x))->sin_family)
|
||||
#elif defined(AF_INET6)
|
||||
# define FAMILY(x) (((struct sockaddr_in6*)(x))->sin6_family)
|
||||
#elif defined(AF_UNIX)
|
||||
# define FAMILY(x) (((struct sockaddr_un*)(x))->sun_family)
|
||||
#else
|
||||
# define FAMILY(x) (-1)
|
||||
#endif
|
||||
|
||||
static QSE_INLINE int skad_to_nwad (const sockaddr_t* skad, qse_nwad_t* nwad)
|
||||
{
|
||||
int addrsize = -1;
|
||||
|
||||
switch (FAMILY(skad))
|
||||
{
|
||||
#if defined(AF_INET)
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in* in;
|
||||
in = (struct sockaddr_in*)skad;
|
||||
addrsize = QSE_SIZEOF(*in);
|
||||
|
||||
QSE_MEMSET (nwad, 0, QSE_SIZEOF(*nwad));
|
||||
nwad->type = QSE_NWAD_IN4;
|
||||
nwad->u.in4.addr.value = in->sin_addr.s_addr;
|
||||
nwad->u.in4.port = in->sin_port;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(AF_INET6)
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6* in;
|
||||
in = (struct sockaddr_in6*)skad;
|
||||
addrsize = QSE_SIZEOF(*in);
|
||||
|
||||
QSE_MEMSET (nwad, 0, QSE_SIZEOF(*nwad));
|
||||
nwad->type = QSE_NWAD_IN6;
|
||||
QSE_MEMCPY (&nwad->u.in6.addr, &in->sin6_addr, QSE_SIZEOF(nwad->u.in6.addr));
|
||||
#if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID)
|
||||
nwad->u.in6.scope = in->sin6_scope_id;
|
||||
#endif
|
||||
nwad->u.in6.port = in->sin6_port;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(AF_UNIX)
|
||||
case AF_UNIX:
|
||||
{
|
||||
struct sockaddr_un* un;
|
||||
un = (struct sockaddr_un*)skad;
|
||||
addrsize = QSE_SIZEOF(*un);
|
||||
|
||||
QSE_MEMSET (nwad, 0, QSE_SIZEOF(*nwad));
|
||||
nwad->type = QSE_NWAD_LOCAL;
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
qse_mbsxcpy (nwad->u.local.path, QSE_COUNTOF(nwad->u.local.path), un->sun_path);
|
||||
#else
|
||||
{
|
||||
qse_size_t wcslen, mbslen;
|
||||
mbslen = QSE_COUNTOF(nwad->u.local.path);
|
||||
qse_wcstombs (un->sun_path, &wcslen, nwad->u.local.path, &mbslen);
|
||||
/* don't care about conversion errors */
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return addrsize;
|
||||
}
|
||||
|
||||
static QSE_INLINE int nwad_to_skad (const qse_nwad_t* nwad, sockaddr_t* skad)
|
||||
{
|
||||
int addrsize = -1;
|
||||
|
||||
switch (nwad->type)
|
||||
{
|
||||
case QSE_NWAD_IN4:
|
||||
{
|
||||
#if defined(AF_INET)
|
||||
struct sockaddr_in* in;
|
||||
|
||||
in = (struct sockaddr_in*)skad;
|
||||
addrsize = QSE_SIZEOF(*in);
|
||||
QSE_MEMSET (in, 0, addrsize);
|
||||
|
||||
in->sin_family = AF_INET;
|
||||
in->sin_addr.s_addr = nwad->u.in4.addr.value;
|
||||
in->sin_port = nwad->u.in4.port;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_NWAD_IN6:
|
||||
{
|
||||
#if defined(AF_INET6)
|
||||
struct sockaddr_in6* in;
|
||||
|
||||
in = (struct sockaddr_in6*)skad;
|
||||
addrsize = QSE_SIZEOF(*in);
|
||||
QSE_MEMSET (in, 0, addrsize);
|
||||
|
||||
in->sin6_family = AF_INET6;
|
||||
QSE_MEMCPY (&in->sin6_addr, &nwad->u.in6.addr, QSE_SIZEOF(nwad->u.in6.addr));
|
||||
#if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID)
|
||||
in->sin6_scope_id = nwad->u.in6.scope;
|
||||
#endif
|
||||
in->sin6_port = nwad->u.in6.port;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case QSE_NWAD_LOCAL:
|
||||
{
|
||||
#if defined(AF_UNIX)
|
||||
struct sockaddr_un* un;
|
||||
|
||||
un = (struct sockaddr_un*)skad;
|
||||
addrsize = QSE_SIZEOF(*un);
|
||||
QSE_MEMSET (un, 0, addrsize);
|
||||
|
||||
un->sun_family = AF_UNIX;
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
qse_mbsxcpy (un->sun_path, QSE_COUNTOF(un->sun_path), nwad->u.local.path);
|
||||
#else
|
||||
{
|
||||
qse_size_t wcslen, mbslen;
|
||||
mbslen = QSE_COUNTOF(un->sun_path);
|
||||
qse_wcstombs (nwad->u.local.path, &wcslen, un->sun_path, &mbslen);
|
||||
/* don't care about conversion errors */
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return addrsize;
|
||||
}
|
||||
|
||||
int qse_skadtonwad (const qse_skad_t* skad, qse_nwad_t* nwad)
|
||||
{
|
||||
QSE_ASSERT (QSE_SIZEOF(*skad) >= QSE_SIZEOF(sockaddr_t));
|
||||
return skad_to_nwad ((const sockaddr_t*)skad, nwad);
|
||||
}
|
||||
|
||||
int qse_nwadtoskad (const qse_nwad_t* nwad, qse_skad_t* skad)
|
||||
{
|
||||
QSE_ASSERT (QSE_SIZEOF(*skad) >= QSE_SIZEOF(sockaddr_t));
|
||||
return nwad_to_skad (nwad, (sockaddr_t*)skad);
|
||||
}
|
||||
|
||||
int qse_skadfamily (const qse_skad_t* skad)
|
||||
{
|
||||
QSE_ASSERT (QSE_SIZEOF(*skad) >= QSE_SIZEOF(sockaddr_t));
|
||||
return FAMILY(skad);
|
||||
}
|
||||
|
||||
int qse_skadsize (const qse_skad_t* skad)
|
||||
{
|
||||
switch (FAMILY(skad))
|
||||
{
|
||||
#if defined(AF_INET)
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in in;
|
||||
return QSE_SIZEOF(in);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(AF_INET6)
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in in6;
|
||||
return QSE_SIZEOF(in6);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(AF_UNIX)
|
||||
case AF_UNIX:
|
||||
{
|
||||
struct sockaddr_un un;
|
||||
return QSE_SIZEOF(un);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,718 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <qse/cmn/nwad.h>
|
||||
#include <qse/cmn/hton.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/cmn/fmt.h>
|
||||
#include <qse/cmn/mbwc.h>
|
||||
#include <qse/si/nwif.h>
|
||||
#include "mem.h"
|
||||
|
||||
int qse_nwadequal (const qse_nwad_t* x, const qse_nwad_t* y)
|
||||
{
|
||||
if (x->type != y->type) return 0;
|
||||
|
||||
switch (x->type)
|
||||
{
|
||||
case QSE_NWAD_IN4:
|
||||
return (x->u.in4.port == y->u.in4.port &&
|
||||
QSE_MEMCMP (&x->u.in4.addr, &y->u.in4.addr, QSE_SIZEOF(x->u.in4.addr)) == 0)? 1: 0;
|
||||
|
||||
case QSE_NWAD_IN6:
|
||||
return (x->u.in6.port == y->u.in6.port &&
|
||||
x->u.in6.scope == y->u.in6.scope &&
|
||||
QSE_MEMCMP (&x->u.in6.addr, &y->u.in6.addr, QSE_SIZEOF(x->u.in6.addr)) == 0)? 1: 0;
|
||||
|
||||
case QSE_NWAD_LOCAL:
|
||||
return qse_strcmp (x->u.local.path, y->u.local.path) == 0;
|
||||
|
||||
default:
|
||||
/* can't compare */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void qse_clearnwad (qse_nwad_t* nwad, qse_nwad_type_t type)
|
||||
{
|
||||
QSE_MEMSET (nwad, 0, QSE_SIZEOF(*nwad));
|
||||
nwad->type = type;
|
||||
}
|
||||
|
||||
void qse_setnwadport (qse_nwad_t* nwad, qse_uint16_t port)
|
||||
{
|
||||
switch (nwad->type)
|
||||
{
|
||||
case QSE_NWAD_IN4:
|
||||
nwad->u.in4.port = port;
|
||||
break;
|
||||
|
||||
case QSE_NWAD_IN6:
|
||||
nwad->u.in6.port = port;
|
||||
break;
|
||||
|
||||
case QSE_NWAD_LOCAL:
|
||||
/* no port for QSE_NWAD_LOCAL */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
qse_uint16_t qse_getnwadport (qse_nwad_t* nwad)
|
||||
{
|
||||
switch (nwad->type)
|
||||
{
|
||||
case QSE_NWAD_IN4:
|
||||
return nwad->u.in4.port;
|
||||
|
||||
case QSE_NWAD_IN6:
|
||||
return nwad->u.in6.port;
|
||||
|
||||
case QSE_NWAD_LOCAL:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int qse_mbstonwad (const qse_mchar_t* str, qse_nwad_t* nwad)
|
||||
{
|
||||
return qse_mbsntonwad (str, qse_mbslen(str), nwad);
|
||||
}
|
||||
|
||||
int qse_mbsntonwad (const qse_mchar_t* str, qse_size_t len, qse_nwad_t* nwad)
|
||||
{
|
||||
const qse_mchar_t* p;
|
||||
const qse_mchar_t* end;
|
||||
qse_mcstr_t tmp;
|
||||
qse_nwad_t tmpad;
|
||||
|
||||
QSE_MEMSET (&tmpad, 0, QSE_SIZEOF(tmpad));
|
||||
|
||||
p = str;
|
||||
end = str + len;
|
||||
|
||||
if (p >= end) return -1;
|
||||
|
||||
if (*p == QSE_MT('@') && len >= 2)
|
||||
{
|
||||
/* the string begins with @. it's a local name */
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
qse_mbsxncpy (tmpad.u.local.path, QSE_COUNTOF(tmpad.u.local.path), p + 1, len - 1);
|
||||
#else
|
||||
qse_size_t mbslen = len - 1;
|
||||
qse_size_t wcslen = QSE_COUNTOF(tmpad.u.local.path) - 1;
|
||||
if (qse_mbsntowcsn (p + 1, &mbslen, tmpad.u.local.path, &wcslen) <= -1) return -1;
|
||||
tmpad.u.local.path[wcslen] = QSE_WT('\0');
|
||||
#endif
|
||||
|
||||
tmpad.type = QSE_NWAD_LOCAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (*p == QSE_MT('['))
|
||||
{
|
||||
/* IPv6 address */
|
||||
tmp.ptr = ++p; /* skip [ and remember the position */
|
||||
while (p < end && *p != QSE_MT('%') && *p != QSE_MT(']')) p++;
|
||||
|
||||
if (p >= end) return -1;
|
||||
|
||||
tmp.len = p - tmp.ptr;
|
||||
if (*p == QSE_MT('%'))
|
||||
{
|
||||
/* handle scope id */
|
||||
qse_uint32_t x;
|
||||
|
||||
p++; /* skip % */
|
||||
|
||||
if (p >= end)
|
||||
{
|
||||
/* premature end */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*p >= QSE_MT('0') && *p <= QSE_MT('9'))
|
||||
{
|
||||
/* numeric scope id */
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_MT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
}
|
||||
while (p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9'));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* interface name as a scope id? */
|
||||
const qse_mchar_t* stmp = p;
|
||||
unsigned int index;
|
||||
do p++; while (p < end && *p != QSE_MT(']'));
|
||||
if (qse_nwifmbsntoindex (stmp, p - stmp, &index) <= -1) return -1;
|
||||
tmpad.u.in6.scope = index;
|
||||
}
|
||||
|
||||
if (p >= end || *p != QSE_MT(']')) return -1;
|
||||
}
|
||||
p++; /* skip ] */
|
||||
|
||||
if (qse_mbsntoip6ad (tmp.ptr, tmp.len, &tmpad.u.in6.addr) <= -1) return -1;
|
||||
tmpad.type = QSE_NWAD_IN6;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* host name or IPv4 address */
|
||||
tmp.ptr = p;
|
||||
while (p < end && *p != QSE_MT(':')) p++;
|
||||
tmp.len = p - tmp.ptr;
|
||||
|
||||
if (qse_mbsntoip4ad (tmp.ptr, tmp.len, &tmpad.u.in4.addr) <= -1)
|
||||
{
|
||||
if (p >= end || *p != QSE_MT(':')) return -1;
|
||||
|
||||
/* check if it is an IPv6 address not enclosed in [].
|
||||
* the port number can't be specified in this format. */
|
||||
|
||||
while (p < end && *p != QSE_MT('%')) p++;
|
||||
tmp.len = p - tmp.ptr;
|
||||
|
||||
if (qse_mbsntoip6ad (tmp.ptr, tmp.len, &tmpad.u.in6.addr) <= -1)
|
||||
return -1;
|
||||
|
||||
if (p < end && *p == QSE_MT('%'))
|
||||
{
|
||||
/* handle scope id */
|
||||
qse_uint32_t x;
|
||||
|
||||
p++; /* skip % */
|
||||
|
||||
if (p >= end)
|
||||
{
|
||||
/* premature end */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*p >= QSE_MT('0') && *p <= QSE_MT('9'))
|
||||
{
|
||||
/* numeric scope id */
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_MT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
}
|
||||
while (p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9'));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* interface name as a scope id? */
|
||||
const qse_mchar_t* stmp = p;
|
||||
unsigned int index;
|
||||
do p++; while (p < end);
|
||||
if (qse_nwifmbsntoindex (stmp, p - stmp, &index) <= -1) return -1;
|
||||
tmpad.u.in6.scope = index;
|
||||
}
|
||||
}
|
||||
|
||||
if (p < end) return -1;
|
||||
|
||||
tmpad.type = QSE_NWAD_IN6;
|
||||
goto done;
|
||||
}
|
||||
|
||||
tmpad.type = QSE_NWAD_IN4;
|
||||
}
|
||||
|
||||
if (p < end && *p == QSE_MT(':'))
|
||||
{
|
||||
/* port number */
|
||||
qse_uint32_t port = 0;
|
||||
|
||||
p++; /* skip : */
|
||||
|
||||
tmp.ptr = p;
|
||||
while (p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9'))
|
||||
{
|
||||
port = port * 10 + (*p - QSE_MT('0'));
|
||||
p++;
|
||||
}
|
||||
|
||||
tmp.len = p - tmp.ptr;
|
||||
if (tmp.len <= 0 || tmp.len >= 6 ||
|
||||
port > QSE_TYPE_MAX(qse_uint16_t)) return -1;
|
||||
|
||||
if (tmpad.type == QSE_NWAD_IN4)
|
||||
tmpad.u.in4.port = qse_hton16 (port);
|
||||
else
|
||||
tmpad.u.in6.port = qse_hton16 (port);
|
||||
}
|
||||
|
||||
done:
|
||||
if (nwad) *nwad = tmpad;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qse_wcstonwad (const qse_wchar_t* str, qse_nwad_t* nwad)
|
||||
{
|
||||
return qse_wcsntonwad (str, qse_wcslen(str), nwad);
|
||||
}
|
||||
|
||||
int qse_wcsntonwad (const qse_wchar_t* str, qse_size_t len, qse_nwad_t* nwad)
|
||||
{
|
||||
const qse_wchar_t* p;
|
||||
const qse_wchar_t* end;
|
||||
qse_wcstr_t tmp;
|
||||
qse_nwad_t tmpad;
|
||||
|
||||
QSE_MEMSET (&tmpad, 0, QSE_SIZEOF(tmpad));
|
||||
|
||||
p = str;
|
||||
end = str + len;
|
||||
|
||||
if (p >= end) return -1;
|
||||
|
||||
if (*p == QSE_WT('@') && len >= 2)
|
||||
{
|
||||
/* the string begins with @. it's a local name */
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
qse_size_t wcslen = len - 1;
|
||||
qse_size_t mbslen = QSE_COUNTOF(tmpad.u.local.path) - 1;
|
||||
if (qse_wcsntombsn (p + 1, &wcslen, tmpad.u.local.path, &mbslen) <= -1) return -1;
|
||||
tmpad.u.local.path[mbslen] = QSE_MT('\0');
|
||||
#else
|
||||
qse_wcsxncpy (tmpad.u.local.path, QSE_COUNTOF(tmpad.u.local.path), p + 1, len - 1);
|
||||
#endif
|
||||
|
||||
tmpad.type = QSE_NWAD_LOCAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (*p == QSE_WT('['))
|
||||
{
|
||||
/* IPv6 address */
|
||||
tmp.ptr = ++p; /* skip [ and remember the position */
|
||||
while (p < end && *p != QSE_WT('%') && *p != QSE_WT(']')) p++;
|
||||
|
||||
if (p >= end) return -1;
|
||||
|
||||
tmp.len = p - tmp.ptr;
|
||||
if (*p == QSE_WT('%'))
|
||||
{
|
||||
/* handle scope id */
|
||||
qse_uint32_t x;
|
||||
|
||||
p++; /* skip % */
|
||||
|
||||
if (p >= end)
|
||||
{
|
||||
/* premature end */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*p >= QSE_WT('0') && *p <= QSE_WT('9'))
|
||||
{
|
||||
/* numeric scope id */
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_WT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
}
|
||||
while (p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9'));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* interface name as a scope id? */
|
||||
const qse_wchar_t* stmp = p;
|
||||
unsigned int index;
|
||||
do p++; while (p < end && *p != QSE_WT(']'));
|
||||
if (qse_nwifwcsntoindex (stmp, p - stmp, &index) <= -1) return -1;
|
||||
tmpad.u.in6.scope = index;
|
||||
}
|
||||
|
||||
if (p >= end || *p != QSE_WT(']')) return -1;
|
||||
}
|
||||
p++; /* skip ] */
|
||||
|
||||
if (qse_wcsntoip6ad (tmp.ptr, tmp.len, &tmpad.u.in6.addr) <= -1) return -1;
|
||||
tmpad.type = QSE_NWAD_IN6;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* host name or IPv4 address */
|
||||
tmp.ptr = p;
|
||||
while (p < end && *p != QSE_WT(':')) p++;
|
||||
tmp.len = p - tmp.ptr;
|
||||
|
||||
if (qse_wcsntoip4ad (tmp.ptr, tmp.len, &tmpad.u.in4.addr) <= -1)
|
||||
{
|
||||
if (p >= end || *p != QSE_WT(':')) return -1;
|
||||
|
||||
/* check if it is an IPv6 address not enclosed in [].
|
||||
* the port number can't be specified in this format. */
|
||||
|
||||
while (p < end && *p != QSE_WT('%')) p++;
|
||||
tmp.len = p - tmp.ptr;
|
||||
|
||||
if (qse_wcsntoip6ad (tmp.ptr, tmp.len, &tmpad.u.in6.addr) <= -1)
|
||||
return -1;
|
||||
|
||||
if (p < end && *p == QSE_WT('%'))
|
||||
{
|
||||
/* handle scope id */
|
||||
qse_uint32_t x;
|
||||
|
||||
p++; /* skip % */
|
||||
|
||||
if (p >= end)
|
||||
{
|
||||
/* premature end */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*p >= QSE_WT('0') && *p <= QSE_WT('9'))
|
||||
{
|
||||
/* numeric scope id */
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_WT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
}
|
||||
while (p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9'));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* interface name as a scope id? */
|
||||
const qse_wchar_t* stmp = p;
|
||||
unsigned int index;
|
||||
do p++; while (p < end);
|
||||
if (qse_nwifwcsntoindex (stmp, p - stmp, &index) <= -1) return -1;
|
||||
tmpad.u.in6.scope = index;
|
||||
}
|
||||
}
|
||||
|
||||
if (p < end) return -1;
|
||||
|
||||
tmpad.type = QSE_NWAD_IN6;
|
||||
goto done;
|
||||
}
|
||||
|
||||
tmpad.type = QSE_NWAD_IN4;
|
||||
}
|
||||
|
||||
if (p < end && *p == QSE_WT(':'))
|
||||
{
|
||||
/* port number */
|
||||
qse_uint32_t port = 0;
|
||||
|
||||
p++; /* skip : */
|
||||
|
||||
tmp.ptr = p;
|
||||
while (p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9'))
|
||||
{
|
||||
port = port * 10 + (*p - QSE_WT('0'));
|
||||
p++;
|
||||
}
|
||||
|
||||
tmp.len = p - tmp.ptr;
|
||||
if (tmp.len <= 0 || tmp.len >= 6 ||
|
||||
port > QSE_TYPE_MAX(qse_uint16_t)) return -1;
|
||||
|
||||
if (tmpad.type == QSE_NWAD_IN4)
|
||||
tmpad.u.in4.port = qse_hton16 (port);
|
||||
else
|
||||
tmpad.u.in6.port = qse_hton16 (port);
|
||||
}
|
||||
|
||||
done:
|
||||
if (nwad) *nwad = tmpad;
|
||||
return 0;
|
||||
}
|
||||
|
||||
qse_size_t qse_nwadtombs (
|
||||
const qse_nwad_t* nwad, qse_mchar_t* buf, qse_size_t len, int flags)
|
||||
{
|
||||
qse_size_t xlen = 0;
|
||||
|
||||
/* unsupported types will result in an empty string */
|
||||
|
||||
switch (nwad->type)
|
||||
{
|
||||
case QSE_NWAD_IN4:
|
||||
if (flags & QSE_NWADTOMBS_ADDR)
|
||||
{
|
||||
if (xlen + 1 >= len) goto done;
|
||||
xlen += qse_ip4adtombs (&nwad->u.in4.addr, buf, len);
|
||||
}
|
||||
|
||||
if (flags & QSE_NWADTOMBS_PORT)
|
||||
{
|
||||
if (!(flags & QSE_NWADTOMBS_ADDR) ||
|
||||
nwad->u.in4.port != 0)
|
||||
{
|
||||
if (flags & QSE_NWADTOMBS_ADDR)
|
||||
{
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_MT(':');
|
||||
}
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
xlen += qse_fmtuintmaxtombs (
|
||||
&buf[xlen], len - xlen,
|
||||
qse_ntoh16(nwad->u.in4.port),
|
||||
10, 0, QSE_MT('\0'), QSE_NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case QSE_NWAD_IN6:
|
||||
if (flags & QSE_NWADTOMBS_PORT)
|
||||
{
|
||||
if (!(flags & QSE_NWADTOMBS_ADDR) ||
|
||||
nwad->u.in6.port != 0)
|
||||
{
|
||||
if (flags & QSE_NWADTOMBS_ADDR)
|
||||
{
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_MT('[');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & QSE_NWADTOMBS_ADDR)
|
||||
{
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
xlen += qse_ip6adtombs (&nwad->u.in6.addr, &buf[xlen], len - xlen);
|
||||
|
||||
if (nwad->u.in6.scope != 0)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_MT('%');
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
|
||||
tmp = qse_nwifindextombs (nwad->u.in6.scope, &buf[xlen], len - xlen);
|
||||
if (tmp <= -1)
|
||||
{
|
||||
xlen += qse_fmtuintmaxtombs (
|
||||
&buf[xlen], len - xlen,
|
||||
nwad->u.in6.scope, 10, 0, QSE_MT('\0'), QSE_NULL);
|
||||
}
|
||||
else xlen += tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & QSE_NWADTOMBS_PORT)
|
||||
{
|
||||
if (!(flags & QSE_NWADTOMBS_ADDR) ||
|
||||
nwad->u.in6.port != 0)
|
||||
{
|
||||
if (flags & QSE_NWADTOMBS_ADDR)
|
||||
{
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_MT(']');
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_MT(':');
|
||||
}
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
xlen += qse_fmtuintmaxtombs (
|
||||
&buf[xlen], len - xlen,
|
||||
qse_ntoh16(nwad->u.in6.port),
|
||||
10, 0, QSE_MT('\0'), QSE_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case QSE_NWAD_LOCAL:
|
||||
if (flags & QSE_NWADTOMBS_ADDR)
|
||||
{
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_MT('@');
|
||||
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
if (xlen + 1 >= len) goto done;
|
||||
xlen += qse_mbsxcpy (&buf[xlen], len - xlen, nwad->u.local.path);
|
||||
#else
|
||||
if (xlen + 1 >= len) goto done;
|
||||
else
|
||||
{
|
||||
qse_size_t wcslen, mbslen = len - xlen;
|
||||
qse_wcstombs (nwad->u.local.path, &wcslen, &buf[xlen], &mbslen);
|
||||
/* i don't care about conversion errors */
|
||||
xlen += mbslen;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
if (xlen < len) buf[xlen] = QSE_MT('\0');
|
||||
return xlen;
|
||||
}
|
||||
|
||||
|
||||
qse_size_t qse_nwadtowcs (
|
||||
const qse_nwad_t* nwad, qse_wchar_t* buf, qse_size_t len, int flags)
|
||||
{
|
||||
qse_size_t xlen = 0;
|
||||
|
||||
/* unsupported types will result in an empty string */
|
||||
|
||||
switch (nwad->type)
|
||||
{
|
||||
case QSE_NWAD_IN4:
|
||||
if (flags & QSE_NWADTOWCS_ADDR)
|
||||
{
|
||||
if (xlen + 1 >= len) goto done;
|
||||
xlen += qse_ip4adtowcs (&nwad->u.in4.addr, buf, len);
|
||||
}
|
||||
|
||||
if (flags & QSE_NWADTOWCS_PORT)
|
||||
{
|
||||
if (!(flags & QSE_NWADTOMBS_ADDR) ||
|
||||
nwad->u.in4.port != 0)
|
||||
{
|
||||
if (flags & QSE_NWADTOMBS_ADDR)
|
||||
{
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_WT(':');
|
||||
}
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
xlen += qse_fmtuintmaxtowcs (
|
||||
&buf[xlen], len - xlen,
|
||||
qse_ntoh16(nwad->u.in4.port),
|
||||
10, 0, QSE_WT('\0'), QSE_NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case QSE_NWAD_IN6:
|
||||
if (flags & QSE_NWADTOWCS_PORT)
|
||||
{
|
||||
if (!(flags & QSE_NWADTOMBS_ADDR) ||
|
||||
nwad->u.in6.port != 0)
|
||||
{
|
||||
if (flags & QSE_NWADTOMBS_ADDR)
|
||||
{
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_WT('[');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & QSE_NWADTOWCS_ADDR)
|
||||
{
|
||||
if (xlen + 1 >= len) goto done;
|
||||
xlen += qse_ip6adtowcs (&nwad->u.in6.addr, &buf[xlen], len - xlen);
|
||||
|
||||
if (nwad->u.in6.scope != 0)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_WT('%');
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
|
||||
tmp = qse_nwifindextowcs (nwad->u.in6.scope, &buf[xlen], len - xlen);
|
||||
if (tmp <= -1)
|
||||
{
|
||||
xlen += qse_fmtuintmaxtowcs (
|
||||
&buf[xlen], len - xlen,
|
||||
nwad->u.in6.scope, 10, 0, QSE_WT('\0'), QSE_NULL);
|
||||
}
|
||||
else xlen += tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & QSE_NWADTOWCS_PORT)
|
||||
{
|
||||
if (!(flags & QSE_NWADTOMBS_ADDR) ||
|
||||
nwad->u.in6.port != 0)
|
||||
{
|
||||
if (flags & QSE_NWADTOMBS_ADDR)
|
||||
{
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_WT(']');
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_WT(':');
|
||||
}
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
xlen += qse_fmtuintmaxtowcs (
|
||||
&buf[xlen], len - xlen,
|
||||
qse_ntoh16(nwad->u.in6.port),
|
||||
10, 0, QSE_WT('\0'), QSE_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case QSE_NWAD_LOCAL:
|
||||
if (flags & QSE_NWADTOMBS_ADDR)
|
||||
{
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_WT('@');
|
||||
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
if (xlen + 1 >= len) goto done;
|
||||
else
|
||||
{
|
||||
qse_size_t wcslen = len - xlen, mbslen;
|
||||
qse_mbstowcs (nwad->u.local.path, &mbslen, &buf[xlen], &wcslen);
|
||||
/* i don't care about conversion errors */
|
||||
xlen += wcslen;
|
||||
}
|
||||
#else
|
||||
if (xlen + 1 >= len) goto done;
|
||||
xlen += qse_wcsxcpy (&buf[xlen], len - xlen, nwad->u.local.path);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (xlen < len) buf[xlen] = QSE_WT('\0');
|
||||
return xlen;
|
||||
}
|
||||
|
@ -1,407 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <qse/cmn/sck.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h> /* sockaddr_in6 */
|
||||
# include <windows.h>
|
||||
#elif defined(__OS2__)
|
||||
# if defined(TCPV40HDRS)
|
||||
# define BSD_SELECT
|
||||
# endif
|
||||
# include <types.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <nerrno.h>
|
||||
# if defined(TCPV40HDRS)
|
||||
# define USE_SELECT
|
||||
# include <sys/select.h>
|
||||
# else
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
#elif defined(__DOS__)
|
||||
# include <tcp.h> /* watt-32 */
|
||||
|
||||
#elif defined(HAVE_T_CONNECT) && !defined(HAVE_CONNECT) && defined(HAVE_TIUSER_H)
|
||||
|
||||
# include "syscall.h"
|
||||
# include <tiuser.h>
|
||||
# define USE_TLI
|
||||
|
||||
#else
|
||||
# include "syscall.h"
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# if defined(HAVE_NETINET_SCTP_H)
|
||||
# include <netinet/sctp.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(SHUT_RD)
|
||||
# define SHUT_RD 0
|
||||
#endif
|
||||
|
||||
#if !defined(SHUT_WR)
|
||||
# define SHUT_WR 1
|
||||
#endif
|
||||
|
||||
#if !defined(SHUT_RDWR)
|
||||
# define SHUT_RDWR 2
|
||||
#endif
|
||||
|
||||
QSE_INLINE int qse_isvalidsckhnd (qse_sck_hnd_t handle)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return handle != QSE_INVALID_SCKHND;
|
||||
|
||||
#elif defined(__OS2__)
|
||||
return handle >= 0;
|
||||
|
||||
#elif defined(__DOS__)
|
||||
return handle >= 0;
|
||||
|
||||
#elif defined(USE_TLI)
|
||||
return handle >= 0;
|
||||
|
||||
#else
|
||||
return handle >= 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
QSE_INLINE void qse_closesckhnd (qse_sck_hnd_t handle)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
closesocket (handle);
|
||||
|
||||
#elif defined(__OS2__)
|
||||
soclose (handle);
|
||||
|
||||
#elif defined(__DOS__)
|
||||
close_s (handle);
|
||||
|
||||
#elif defined(USE_TLI)
|
||||
t_close (handle);
|
||||
|
||||
#else
|
||||
QSE_CLOSE (handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
QSE_INLINE void qse_shutsckhnd (qse_sck_hnd_t handle, qse_shutsckhnd_how_t how)
|
||||
{
|
||||
static int how_v[] = { SHUT_RD, SHUT_WR, SHUT_RDWR };
|
||||
|
||||
#if defined(_WIN32)
|
||||
shutdown (handle, how_v[how]);
|
||||
|
||||
#elif defined(__OS2__)
|
||||
shutdown (handle, how_v[how]);
|
||||
|
||||
#elif defined(__DOS__)
|
||||
shutdown (handle, how_v[how]);
|
||||
|
||||
#elif defined(USE_TLI)
|
||||
/* Is this correct? */
|
||||
switch (how)
|
||||
{
|
||||
case QSE_SHUTSCKHND_R:
|
||||
t_rcvrel (handle);
|
||||
break;
|
||||
case QSE_SHUTSCKHND_W:
|
||||
t_sndrel (handle);
|
||||
break;
|
||||
case QSE_SHUTSCKHND_RW:
|
||||
t_rcvrel (handle);
|
||||
t_sndrel (handle);
|
||||
break;
|
||||
}
|
||||
|
||||
#else
|
||||
shutdown (handle, how_v[how]);
|
||||
#endif
|
||||
}
|
||||
|
||||
int qse_setscknonblock (qse_sck_hnd_t handle, int enabled)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
if (ioctlsocket (handle, FIONBIO, &enabled) == SOCKET_ERROR) return -1;
|
||||
return 0;
|
||||
|
||||
#elif defined(__OS2__)
|
||||
|
||||
if (ioctl (handle, FIONBIO, (char*)&enabled, sizeof(enabled)) <= -1) return -1;
|
||||
return 0;
|
||||
|
||||
#elif defined(__DOS__)
|
||||
|
||||
if (ioctlsocket (handle, FIONBIO, (char*)&enabled) == SOCKET_ERROR) return -1;
|
||||
return 0;
|
||||
|
||||
#elif defined(O_NONBLOCK)
|
||||
|
||||
int flag = fcntl (handle, F_GETFL);
|
||||
if (flag >= 0) flag = fcntl (handle, F_SETFL, (enabled? (flag | O_NONBLOCK): (flag & ~O_NONBLOCK)));
|
||||
if (flag <= -1) return -1;
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int qse_initsckconn (qse_sck_hnd_t handle, const qse_nwad_t* nwad)
|
||||
{
|
||||
int n;
|
||||
#if defined(_WIN32)
|
||||
unsigned long cmd;
|
||||
#elif defined(__OS2__)
|
||||
int enabled;
|
||||
#else
|
||||
int saved = 0;
|
||||
#endif
|
||||
qse_skad_t skad;
|
||||
int skadlen;
|
||||
|
||||
skadlen = qse_nwadtoskad (nwad, &skad);
|
||||
if (skadlen <= -1) return -1;
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* switch to the non-blocking mode */
|
||||
cmd = 1;
|
||||
if (ioctlsocket(handle, FIONBIO, &cmd) == SOCKET_ERROR)
|
||||
{
|
||||
/* error code in WSAGetLastError() */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* attempt to connet */
|
||||
n = connect (handle, (struct sockaddr*)&skad, skadlen);
|
||||
if (n == -1 && WSAGetLastError() != WSAEWOULDBLOCK)
|
||||
{
|
||||
/* attempt to restore to the blocking mode upon failure.
|
||||
* there is no guarantee that this was the previous mode. */
|
||||
cmd = 0;
|
||||
ioctlsocket (handle, FIONBIO, &cmd);
|
||||
return -1;
|
||||
}
|
||||
#elif defined(__OS2__)
|
||||
|
||||
enabled = 1;
|
||||
if (ioctl (handle, FIONBIO, (char*)&enabled, sizeof(enabled)) <= -1) return -1;
|
||||
|
||||
/* attempt to connet */
|
||||
n = connect (handle, (struct sockaddr*)&skad, skadlen);
|
||||
if (n == -1 && sock_errno() != EINPROGRESS)
|
||||
{
|
||||
/* attempt to restore to the blocking mode upon failure.
|
||||
* there is no guarantee that this was the previous mode. */
|
||||
enabled = 0;
|
||||
ioctl (handle, FIONBIO, (char*)&enabled, sizeof(enabled));
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* switch to the non-blocking mode */
|
||||
saved = fcntl (handle, F_GETFL, 0);
|
||||
if (saved == -1) return -1;
|
||||
if (fcntl (handle, F_SETFL, saved | O_NONBLOCK) == -1) return -1;
|
||||
|
||||
/* attempt to connet */
|
||||
do
|
||||
{
|
||||
n = connect (handle, (struct sockaddr*)&skad, skadlen);
|
||||
}
|
||||
while (n == -1 && errno == EINTR);
|
||||
|
||||
if (n == -1 && errno != EINPROGRESS)
|
||||
{
|
||||
fcntl (handle, F_SETFL, saved); /* restore the flags upon failure */
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* the socket still remains in the non-blocking mode */
|
||||
return (n == 0)? 1: 0; /* 1: connected, 0: in progress */
|
||||
}
|
||||
|
||||
int qse_finisckconn (qse_sck_hnd_t handle)
|
||||
{
|
||||
int ret;
|
||||
qse_sck_len_t len;
|
||||
|
||||
len = (qse_sck_len_t)QSE_SIZEOF (ret);
|
||||
if (getsockopt (handle, SOL_SOCKET, SO_ERROR, (char*)&ret, &len) == -1) return -1;
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (ret == WSAETIMEDOUT)
|
||||
#else
|
||||
if (ret == ETIMEDOUT)
|
||||
#endif
|
||||
{
|
||||
return -1; /* failure - timed out */
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
else if (ret == WSAEWOULDBLOCK)
|
||||
#else
|
||||
else if (ret == EINPROGRESS)
|
||||
#endif
|
||||
{
|
||||
return 0; /* in preogress */
|
||||
}
|
||||
else if (ret != 0)
|
||||
{
|
||||
return -1; /* failure */
|
||||
}
|
||||
|
||||
return 1; /* connected */
|
||||
}
|
||||
|
||||
#if 0
|
||||
qse_sck_hnd_t
|
||||
|
||||
|
||||
int qse_sck_open (qse_mmgr_t* mmgr, qse_sck_type_t type)
|
||||
{
|
||||
}
|
||||
|
||||
void qse_sck_close (qse_sck_t* sck)
|
||||
{
|
||||
}
|
||||
|
||||
int qse_sck_init (qse_sck_t* sck, qse_mmgr_t* mmgr, qse_sck_type_t type)
|
||||
{
|
||||
int domain, type, proto = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case QSE_SCK_TCP4:
|
||||
domain = AF_INET;
|
||||
type = SOCK_STREAM;
|
||||
break;
|
||||
|
||||
case QSE_SCK_TCP6:
|
||||
domain = AF_INET6;
|
||||
type = SOCK_STREAM;
|
||||
break;
|
||||
|
||||
case QSE_SCK_UDP4:
|
||||
domain = AF_INET;
|
||||
type = SOCK_DGRAM;
|
||||
break;
|
||||
|
||||
case QSE_SCK_UDP6:
|
||||
domain = AF_INET6;
|
||||
type = SOCK_DGRAM;
|
||||
break;
|
||||
|
||||
case QSE_SCK_SCTP4:
|
||||
domain = AF_INET;
|
||||
type = SCOK_SEQPACKET;
|
||||
proto = IPPROTO_SCTP;
|
||||
break;
|
||||
|
||||
case QSE_SCK_SCTP6:
|
||||
domain = AF_INET6;
|
||||
type = SCOK_SEQPACKET;
|
||||
proto = IPPROTO_SCTP;
|
||||
break;
|
||||
|
||||
case QSE_SCK_SCTP4:
|
||||
domain = AF_INET;
|
||||
type = SCOK_STREAM;
|
||||
proto = IPPROTO_SCTP;
|
||||
break;
|
||||
|
||||
case QSE_SCK_SCTP6:
|
||||
domain = AF_INET6;
|
||||
type = SCOK_STREAM;
|
||||
proto = IPPROTO_SCTP;
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case QSE_SCK_RAW4:
|
||||
domain = AF_INET;
|
||||
type = SOCK_RAW;
|
||||
break;
|
||||
|
||||
case QSE_SCK_RAW6:
|
||||
domain = AF_INET6;
|
||||
type = SOCK_RAW;
|
||||
break;
|
||||
|
||||
case QSE_SCK_PACKET:
|
||||
domain = AF_PACKET;
|
||||
type = SOCK_RAW;
|
||||
proto = qse_hton16(ETH_P_ALL);
|
||||
break;
|
||||
|
||||
case QSE_SCK_PACKET:
|
||||
domain = AF_PACKET;
|
||||
type = SOCK_DGRAM; /* cooked packet with the link level header removed */
|
||||
proto = qse_hton16(ETH_P_ALL);
|
||||
break;
|
||||
|
||||
case QSE_SCK_ARP:
|
||||
domain = AF_PACKET;
|
||||
type = SOCK_RAW;
|
||||
proto = qse_hton16(ETH_P_ARP);
|
||||
proto =
|
||||
#endif
|
||||
}
|
||||
|
||||
sck->handle = socket (domain, type, proto);
|
||||
}
|
||||
|
||||
void qse_sck_fini (qse_sck_t* sck)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
closesocket (sck->handle);
|
||||
#elif defined(__OS2__)
|
||||
soclose (sck->handle);
|
||||
#elif defined(__DOS__)
|
||||
close_s (sck->handle)
|
||||
#else
|
||||
QSE_CLOSE (sck->handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
qse_ssize_t qse_recvsocket ()
|
||||
|
||||
qse_ssize_t recvfromsocket ()
|
||||
|
||||
qse_ssize_t sendsocket ()
|
||||
qse_ssize_t sendtosocket ()
|
||||
#endif
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user