diff --git a/mio/Makefile.in b/mio/Makefile.in index 71acc1c..c321188 100644 --- a/mio/Makefile.in +++ b/mio/Makefile.in @@ -164,8 +164,8 @@ am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/ac/ar-lib \ $(top_srcdir)/ac/compile $(top_srcdir)/ac/config.guess \ $(top_srcdir)/ac/config.sub $(top_srcdir)/ac/install-sh \ $(top_srcdir)/ac/ltmain.sh $(top_srcdir)/ac/missing ac/ar-lib \ - ac/compile ac/config.guess ac/config.sub ac/install-sh \ - ac/ltmain.sh ac/missing + ac/compile ac/config.guess ac/config.sub ac/depcomp \ + ac/install-sh ac/ltmain.sh ac/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/mio/bin/t01.c b/mio/bin/t01.c index 6ac7eb3..ec204de 100644 --- a/mio/bin/t01.c +++ b/mio/bin/t01.c @@ -669,7 +669,7 @@ done: static void on_dnc_resolve_brief (mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio_errnum_t status, const void* data, mio_oow_t dlen) { - if (data) /* status must be HAWK_ENOERR */ + if (data) /* status must be MIO_ENOERR */ { mio_dns_brr_t* brr = (mio_dns_brr_t*)data; diff --git a/mio/configure b/mio/configure index cc7c625..c286dac 100755 --- a/mio/configure +++ b/mio/configure @@ -20043,6 +20043,207 @@ _ACEOF + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking numeric value of PATH_MAX" >&5 +$as_echo_n "checking numeric value of PATH_MAX... " >&6; } +if ${ax_cv_numvalof_PATH_MAX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(PATH_MAX)" "ax_cv_numvalof_PATH_MAX" "#include +"; then : + +else + ax_cv_numvalof_PATH_MAX=0 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_numvalof_PATH_MAX" >&5 +$as_echo "$ax_cv_numvalof_PATH_MAX" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define NUMVALOF_PATH_MAX $ax_cv_numvalof_PATH_MAX +_ACEOF + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking numeric value of NSIG" >&5 +$as_echo_n "checking numeric value of NSIG... " >&6; } +if ${ax_cv_numvalof_NSIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(NSIG)" "ax_cv_numvalof_NSIG" "#include +"; then : + +else + ax_cv_numvalof_NSIG=32 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_numvalof_NSIG" >&5 +$as_echo "$ax_cv_numvalof_NSIG" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define NUMVALOF_NSIG $ax_cv_numvalof_NSIG +_ACEOF + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking numeric value of AF_UNSPEC" >&5 +$as_echo_n "checking numeric value of AF_UNSPEC... " >&6; } +if ${ax_cv_numvalof_AF_UNSPEC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(AF_UNSPEC)" "ax_cv_numvalof_AF_UNSPEC" "#include + #include + #include +"; then : + +else + ax_cv_numvalof_AF_UNSPEC=0 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_numvalof_AF_UNSPEC" >&5 +$as_echo "$ax_cv_numvalof_AF_UNSPEC" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define NUMVALOF_AF_UNSPEC $ax_cv_numvalof_AF_UNSPEC +_ACEOF + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking numeric value of AF_INET" >&5 +$as_echo_n "checking numeric value of AF_INET... " >&6; } +if ${ax_cv_numvalof_AF_INET+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(AF_INET)" "ax_cv_numvalof_AF_INET" "#include + #include + #include +"; then : + +else + ax_cv_numvalof_AF_INET=-1 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_numvalof_AF_INET" >&5 +$as_echo "$ax_cv_numvalof_AF_INET" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define NUMVALOF_AF_INET $ax_cv_numvalof_AF_INET +_ACEOF + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking numeric value of AF_INET6" >&5 +$as_echo_n "checking numeric value of AF_INET6... " >&6; } +if ${ax_cv_numvalof_AF_INET6+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(AF_INET6)" "ax_cv_numvalof_AF_INET6" "#include + #include + #include +"; then : + +else + ax_cv_numvalof_AF_INET6=-2 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_numvalof_AF_INET6" >&5 +$as_echo "$ax_cv_numvalof_AF_INET6" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define NUMVALOF_AF_INET6 $ax_cv_numvalof_AF_INET6 +_ACEOF + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking numeric value of AF_PACKET" >&5 +$as_echo_n "checking numeric value of AF_PACKET... " >&6; } +if ${ax_cv_numvalof_AF_PACKET+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(AF_PACKET)" "ax_cv_numvalof_AF_PACKET" "#include + #include + #include +"; then : + +else + ax_cv_numvalof_AF_PACKET=-3 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_numvalof_AF_PACKET" >&5 +$as_echo "$ax_cv_numvalof_AF_PACKET" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define NUMVALOF_AF_PACKET $ax_cv_numvalof_AF_PACKET +_ACEOF + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking numeric value of AF_UNIX" >&5 +$as_echo_n "checking numeric value of AF_UNIX... " >&6; } +if ${ax_cv_numvalof_AF_UNIX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(AF_UNIX)" "ax_cv_numvalof_AF_UNIX" "#include + #include + #include +"; then : + +else + ax_cv_numvalof_AF_UNIX=-4 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_numvalof_AF_UNIX" >&5 +$as_echo "$ax_cv_numvalof_AF_UNIX" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define NUMVALOF_AF_UNIX $ax_cv_numvalof_AF_UNIX +_ACEOF + + + + if test "x${platform_win32}" = "xyes" then # The cast to long int works around a bug in the HP C Compiler @@ -21271,6 +21472,37 @@ cat >>confdefs.h <<_ACEOF _ACEOF +cat >>confdefs.h <<_ACEOF +#define MIO_NSIG ${ax_cv_numvalof_NSIG} +_ACEOF + + + +cat >>confdefs.h <<_ACEOF +#define MIO_AF_UNSPEC (${ax_cv_numvalof_AF_UNSPEC}) +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define MIO_AF_INET (${ax_cv_numvalof_AF_INET}) +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define MIO_AF_INET6 (${ax_cv_numvalof_AF_INET6}) +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define MIO_AF_PACKET (${ax_cv_numvalof_AF_PACKET}) +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define MIO_AF_UNIX (${ax_cv_numvalof_AF_UNIX}) +_ACEOF + + cat >>confdefs.h <<_ACEOF #define MIO_SIZEOF_STRUCT_SOCKADDR_IN ${ac_cv_sizeof_struct_sockaddr_in} diff --git a/mio/configure.ac b/mio/configure.ac index 6c5f93e..898d662 100644 --- a/mio/configure.ac +++ b/mio/configure.ac @@ -444,6 +444,25 @@ AC_CHECK_SIZEOF(off64_t) AC_CHECK_SIZEOF(mbstate_t,,[#include ]) AX_CHECK_NUMVALOF(MB_LEN_MAX,[32],[#include ]) +AX_CHECK_NUMVALOF(PATH_MAX,[0],[#include ]) +AX_CHECK_NUMVALOF(NSIG,[32],[#include ]) + +AX_CHECK_NUMVALOF(AF_UNSPEC, [0], [#include + #include + #include ]) +AX_CHECK_NUMVALOF(AF_INET, [-1], [#include + #include + #include ]) +AX_CHECK_NUMVALOF(AF_INET6, [-2], [#include + #include + #include ]) +AX_CHECK_NUMVALOF(AF_PACKET, [-3], [#include + #include + #include ]) +AX_CHECK_NUMVALOF(AF_UNIX, [-4], [#include + #include + #include ]) + if test "x${platform_win32}" = "xyes" then AC_CHECK_SIZEOF(struct sockaddr_in,,[ @@ -785,6 +804,13 @@ AC_DEFINE_UNQUOTED(MIO_SIZEOF_OFF64_T, ${ac_cv_sizeof_off64_t}, [sizeof(off64_t) AC_DEFINE_UNQUOTED(MIO_SIZEOF_MBSTATE_T, ${ac_cv_sizeof_mbstate_t}, [sizeof(mbstate_t)]) AC_DEFINE_UNQUOTED(MIO_MBLEN_MAX, ${ax_cv_numvalof_MB_LEN_MAX}, [MB_LEN_MAX]) +AC_DEFINE_UNQUOTED(MIO_NSIG, ${ax_cv_numvalof_NSIG}, [NSIG]) + +AC_DEFINE_UNQUOTED(MIO_AF_UNSPEC, (${ax_cv_numvalof_AF_UNSPEC}), [AF_UNSPEC]) +AC_DEFINE_UNQUOTED(MIO_AF_INET, (${ax_cv_numvalof_AF_INET}), [AF_INET]) +AC_DEFINE_UNQUOTED(MIO_AF_INET6, (${ax_cv_numvalof_AF_INET6}), [AF_INET6]) +AC_DEFINE_UNQUOTED(MIO_AF_PACKET, (${ax_cv_numvalof_AF_PACKET}), [AF_PACKET]) +AC_DEFINE_UNQUOTED(MIO_AF_UNIX, (${ax_cv_numvalof_AF_UNIX}), [AF_UNIX]) AC_DEFINE_UNQUOTED(MIO_SIZEOF_STRUCT_SOCKADDR_IN, ${ac_cv_sizeof_struct_sockaddr_in}, [sizeof(struct sockaddr_in)]) AC_DEFINE_UNQUOTED(MIO_SIZEOF_STRUCT_SOCKADDR_IN6, ${ac_cv_sizeof_struct_sockaddr_in6}, [sizeof(struct sockaddr_in6)]) diff --git a/mio/lib/Makefile.am b/mio/lib/Makefile.am index 76c4149..428ca44 100644 --- a/mio/lib/Makefile.am +++ b/mio/lib/Makefile.am @@ -26,6 +26,7 @@ include_HEADERS = \ mio-pac1.h \ mio-pro.h \ mio-sck.h \ + mio-skad.h \ mio-upac.h \ mio-utl.h \ mio.h @@ -40,8 +41,7 @@ libmio_la_SOURCES = \ mio.c \ pro.c \ sck.c \ - sck-addr.c \ - sck-addr.h \ + skad.c \ sys.c \ sys-ass.c \ sys-err.c \ diff --git a/mio/lib/Makefile.in b/mio/lib/Makefile.in index 51af086..c3678b0 100644 --- a/mio/lib/Makefile.in +++ b/mio/lib/Makefile.in @@ -140,7 +140,7 @@ libmio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libmio_la_OBJECTS = libmio_la-dns.lo libmio_la-err.lo \ libmio_la-fmt.lo libmio_la-mio.lo libmio_la-pro.lo \ - libmio_la-sck.lo libmio_la-sck-addr.lo libmio_la-sys.lo \ + libmio_la-sck.lo libmio_la-skad.lo libmio_la-sys.lo \ libmio_la-sys-ass.lo libmio_la-sys-err.lo libmio_la-sys-log.lo \ libmio_la-sys-mux.lo libmio_la-sys-tim.lo libmio_la-tmr.lo \ libmio_la-utf8.lo libmio_la-utl.lo @@ -170,8 +170,7 @@ am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/libmio_la-dns.Plo \ ./$(DEPDIR)/libmio_la-err.Plo ./$(DEPDIR)/libmio_la-fmt.Plo \ ./$(DEPDIR)/libmio_la-mio.Plo ./$(DEPDIR)/libmio_la-pro.Plo \ - ./$(DEPDIR)/libmio_la-sck-addr.Plo \ - ./$(DEPDIR)/libmio_la-sck.Plo \ + ./$(DEPDIR)/libmio_la-sck.Plo ./$(DEPDIR)/libmio_la-skad.Plo \ ./$(DEPDIR)/libmio_la-sys-ass.Plo \ ./$(DEPDIR)/libmio_la-sys-err.Plo \ ./$(DEPDIR)/libmio_la-sys-log.Plo \ @@ -401,6 +400,7 @@ include_HEADERS = \ mio-pac1.h \ mio-pro.h \ mio-sck.h \ + mio-skad.h \ mio-upac.h \ mio-utl.h \ mio.h @@ -415,8 +415,7 @@ libmio_la_SOURCES = \ mio.c \ pro.c \ sck.c \ - sck-addr.c \ - sck-addr.h \ + skad.c \ sys.c \ sys-ass.c \ sys-err.c \ @@ -529,8 +528,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-fmt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-pro.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-sck-addr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-sck.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-skad.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-sys-ass.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-sys-err.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-sys-log.Plo@am__quote@ # am--include-marker @@ -613,12 +612,12 @@ libmio_la-sck.lo: sck.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-sck.lo `test -f 'sck.c' || echo '$(srcdir)/'`sck.c -libmio_la-sck-addr.lo: sck-addr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-sck-addr.lo -MD -MP -MF $(DEPDIR)/libmio_la-sck-addr.Tpo -c -o libmio_la-sck-addr.lo `test -f 'sck-addr.c' || echo '$(srcdir)/'`sck-addr.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-sck-addr.Tpo $(DEPDIR)/libmio_la-sck-addr.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sck-addr.c' object='libmio_la-sck-addr.lo' libtool=yes @AMDEPBACKSLASH@ +libmio_la-skad.lo: skad.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-skad.lo -MD -MP -MF $(DEPDIR)/libmio_la-skad.Tpo -c -o libmio_la-skad.lo `test -f 'skad.c' || echo '$(srcdir)/'`skad.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-skad.Tpo $(DEPDIR)/libmio_la-skad.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='skad.c' object='libmio_la-skad.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-sck-addr.lo `test -f 'sck-addr.c' || echo '$(srcdir)/'`sck-addr.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-skad.lo `test -f 'skad.c' || echo '$(srcdir)/'`skad.c libmio_la-sys.lo: sys.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-sys.lo -MD -MP -MF $(DEPDIR)/libmio_la-sys.Tpo -c -o libmio_la-sys.lo `test -f 'sys.c' || echo '$(srcdir)/'`sys.c @@ -843,8 +842,8 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libmio_la-fmt.Plo -rm -f ./$(DEPDIR)/libmio_la-mio.Plo -rm -f ./$(DEPDIR)/libmio_la-pro.Plo - -rm -f ./$(DEPDIR)/libmio_la-sck-addr.Plo -rm -f ./$(DEPDIR)/libmio_la-sck.Plo + -rm -f ./$(DEPDIR)/libmio_la-skad.Plo -rm -f ./$(DEPDIR)/libmio_la-sys-ass.Plo -rm -f ./$(DEPDIR)/libmio_la-sys-err.Plo -rm -f ./$(DEPDIR)/libmio_la-sys-log.Plo @@ -905,8 +904,8 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libmio_la-fmt.Plo -rm -f ./$(DEPDIR)/libmio_la-mio.Plo -rm -f ./$(DEPDIR)/libmio_la-pro.Plo - -rm -f ./$(DEPDIR)/libmio_la-sck-addr.Plo -rm -f ./$(DEPDIR)/libmio_la-sck.Plo + -rm -f ./$(DEPDIR)/libmio_la-skad.Plo -rm -f ./$(DEPDIR)/libmio_la-sys-ass.Plo -rm -f ./$(DEPDIR)/libmio_la-sys-err.Plo -rm -f ./$(DEPDIR)/libmio_la-sys-log.Plo diff --git a/mio/lib/dns.c b/mio/lib/dns.c index 6923012..62e880c 100644 --- a/mio/lib/dns.c +++ b/mio/lib/dns.c @@ -397,7 +397,7 @@ mio_svc_dnc_t* mio_svc_dnc_start (mio_t* mio, const mio_ntime_t* send_tmout, con /* TODO: bind if requested */ /*if (mio_dev_sck_bind(dev, ....) <= -1) goto oops;*/ { -mio_uint32_t ia = 0x01010199; /* 1.1.1.1 */ /* TODO: accept as parameter ... */ +mio_uint32_t ia = 0x01010101; /* 1.1.1.1 */ /* TODO: accept as parameter ... */ mio_sckaddr_initforip4 (&dnc->serveraddr, 53, (mio_ip4addr_t*)&ia); } diff --git a/mio/lib/err.c b/mio/lib/err.c index 073a8db..61c9803 100644 --- a/mio/lib/err.c +++ b/mio/lib/err.c @@ -276,7 +276,7 @@ void mio_seterrbfmtwithsyserr (mio_t* mio, int syserr_type, int syserr_code, con mio->errmsg.len += mio_copy_bcstr(&mio->errmsg.buf[mio->errmsg.len], MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len, mio->errmsg.tmpbuf.bch); #else ucslen = MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len; - mio_convbtoucstr (mio, mio->errmsg.tmpbuf.bch, &bcslen, &mio->errmsg.buf[mio->errmsg.len], &ucslen); + mio_convbtoucstr (mio, mio->errmsg.tmpbuf.bch, &bcslen, &mio->errmsg.buf[mio->errmsg.len], &ucslen, 1); mio->errmsg.len += ucslen; #endif } @@ -333,7 +333,7 @@ void mio_seterrufmtwithsyserr (mio_t* mio, int syserr_type, int syserr_code, con mio->errmsg.len += mio_copy_bcstr(&mio->errmsg.buf[mio->errmsg.len], MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len, mio->errmsg.tmpbuf.bch); #else ucslen = MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len; - mio_convbtoucstr (mio, mio->errmsg.tmpbuf.bch, &bcslen, &mio->errmsg.buf[mio->errmsg.len], &ucslen); + mio_convbtoucstr (mio, mio->errmsg.tmpbuf.bch, &bcslen, &mio->errmsg.buf[mio->errmsg.len], &ucslen, 1); mio->errmsg.len += ucslen; #endif } diff --git a/mio/lib/mio-cfg.h.in b/mio/lib/mio-cfg.h.in index 87c6888..a7fdd2a 100644 --- a/mio/lib/mio-cfg.h.in +++ b/mio/lib/mio-cfg.h.in @@ -744,6 +744,21 @@ /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR +/* AF_INET */ +#undef MIO_AF_INET + +/* AF_INET6 */ +#undef MIO_AF_INET6 + +/* AF_PACKET */ +#undef MIO_AF_PACKET + +/* AF_UNIX */ +#undef MIO_AF_UNIX + +/* AF_UNSPEC */ +#undef MIO_AF_UNSPEC + /* use libunwind for backtracing stack frames */ #undef MIO_ENABLE_LIBUNWIND @@ -762,6 +777,9 @@ /* MB_LEN_MAX */ #undef MIO_MBLEN_MAX +/* NSIG */ +#undef MIO_NSIG + /* offsetof(struct sockaddr, sa_family) */ #undef MIO_OFFSETOF_SA_FAMILY @@ -873,9 +891,30 @@ /* Unicode character type size */ #undef MIO_UNICODE_SIZE +/* The size of `AF_INET', as computed by valueof. */ +#undef NUMVALOF_AF_INET + +/* The size of `AF_INET6', as computed by valueof. */ +#undef NUMVALOF_AF_INET6 + +/* The size of `AF_PACKET', as computed by valueof. */ +#undef NUMVALOF_AF_PACKET + +/* The size of `AF_UNIX', as computed by valueof. */ +#undef NUMVALOF_AF_UNIX + +/* The size of `AF_UNSPEC', as computed by valueof. */ +#undef NUMVALOF_AF_UNSPEC + /* The size of `MB_LEN_MAX', as computed by valueof. */ #undef NUMVALOF_MB_LEN_MAX +/* The size of `NSIG', as computed by valueof. */ +#undef NUMVALOF_NSIG + +/* The size of `PATH_MAX', as computed by valueof. */ +#undef NUMVALOF_PATH_MAX + /* Name of package */ #undef PACKAGE diff --git a/mio/lib/mio-skad.h b/mio/lib/mio-skad.h new file mode 100644 index 0000000..1f6c0ec --- /dev/null +++ b/mio/lib/mio-skad.h @@ -0,0 +1,86 @@ +/* + * $Id$ + * + Copyright (c) 2006-2019 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. + */ + +#ifndef _MIO_SKAD_H_ +#define _MIO_SKAD_H_ + +#include + + +#define MIO_SIZEOF_SKAD_T 1 +#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN > MIO_SIZEOF_SKAD_T) +# undef MIO_SIZEOF_SKAD_T +# define MIO_SIZEOF_SKAD_T MIO_SIZEOF_STRUCT_SOCKADDR_IN +#endif +#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > MIO_SIZEOF_SKAD_T) +# undef MIO_SIZEOF_SKAD_T +# define MIO_SIZEOF_SKAD_T MIO_SIZEOF_STRUCT_SOCKADDR_IN6 +#endif +#if (MIO_SIZEOF_STRUCT_SOCKADDR_LL > MIO_SIZEOF_SKAD_T) +# undef MIO_SIZEOF_SKAD_T +# define MIO_SIZEOF_SKAD_T MIO_SIZEOF_STRUCT_SOCKADDR_LL +#endif +#if (MIO_SIZEOF_STRUCT_SOCKADDR_UN > MIO_SIZEOF_SKAD_T) +# undef MIO_SIZEOF_SKAD_T +# define MIO_SIZEOF_SKAD_T MIO_SIZEOF_STRUCT_SOCKADDR_UN +#endif + +struct mio_skad_t +{ + mio_uint8_t data[MIO_SIZEOF_SKAD_T]; +}; +typedef struct mio_skad_t mio_skad_t; + + +#define MIO_SKAD_TO_OOCSTR_ADDR (1 << 0) +#define MIO_SKAD_TO_OOCSTR_PORT (1 << 0) +#define MIO_SKAD_TO_UCSTR_ADDR MIO_SKAD_TO_OOCSTR_ADDR +#define MIO_SKAD_TO_UCSTR_PORT MIO_SKAD_TO_OOCSTR_PORT +#define MIO_SKAD_TO_BCSTR_ADDR MIO_SKAD_TO_OOCSTR_ADDR +#define MIO_SKAD_TO_BCSTR_PORT MIO_SKAD_TO_OOCSTR_PORT + + +#if defined(__cplusplus) +extern "C" { +#endif + +MIO_EXPORT int mio_skad_family ( + const mio_skad_t* skad +); + +MIO_EXPORT int mio_skad_size ( + const mio_skad_t* skad +); + +MIO_EXPORT void mio_clear_skad ( + mio_skad_t* skad +); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/mio/lib/mio.h b/mio/lib/mio.h index 1772540..32751dc 100644 --- a/mio/lib/mio.h +++ b/mio/lib/mio.h @@ -907,7 +907,8 @@ MIO_EXPORT int mio_convbtouchars ( const mio_bch_t* bcs, mio_oow_t* bcslen, mio_uch_t* ucs, - mio_oow_t* ucslen + mio_oow_t* ucslen, + int all ); MIO_EXPORT int mio_convutobchars ( @@ -927,7 +928,8 @@ MIO_EXPORT int mio_convbtoucstr ( const mio_bch_t* bcs, mio_oow_t* bcslen, mio_uch_t* ucs, - mio_oow_t* ucslen + mio_oow_t* ucslen, + int all ); @@ -946,23 +948,23 @@ MIO_EXPORT int mio_convutobcstr ( #if defined(MIO_OOCH_IS_UCH) # define mio_dupootobcharswithheadroom(mio,hrb,oocs,oocslen,bcslen) mio_duputobcharswithheadroom(mio,hrb,oocs,oocslen,bcslen) -# define mio_dupbtooocharswithheadroom(mio,hrb,bcs,bcslen,oocslen) mio_dupbtoucharswithheadroom(mio,hrb,bcs,bcslen,oocslen) +# define mio_dupbtooocharswithheadroom(mio,hrb,bcs,bcslen,oocslen,all) mio_dupbtoucharswithheadroom(mio,hrb,bcs,bcslen,oocslen,all) # define mio_dupootobchars(mio,oocs,oocslen,bcslen) mio_duputobchars(mio,oocs,oocslen,bcslen) -# define mio_dupbtooochars(mio,bcs,bcslen,oocslen) mio_dupbtouchars(mio,bcs,bcslen,oocslen) +# define mio_dupbtooochars(mio,bcs,bcslen,oocslen,all) mio_dupbtouchars(mio,bcs,bcslen,oocslen,all) # define mio_dupootobcstrwithheadroom(mio,hrb,oocs,bcslen) mio_duputobcstrwithheadroom(mio,hrb,oocs,bcslen) -# define mio_dupbtooocstrwithheadroom(mio,hrb,bcs,oocslen) mio_dupbtoucstrwithheadroom(mio,hrb,bcs,oocslen) +# define mio_dupbtooocstrwithheadroom(mio,hrb,bcs,oocslen,all) mio_dupbtoucstrwithheadroom(mio,hrb,bcs,oocslen,all) # define mio_dupootobcstr(mio,oocs,bcslen) mio_duputobcstr(mio,oocs,bcslen) -# define mio_dupbtooocstr(mio,bcs,oocslen) mio_dupbtoucstr(mio,bcs,oocslen) +# define mio_dupbtooocstr(mio,bcs,oocslen,all) mio_dupbtoucstr(mio,bcs,oocslen,all) #else -# define mio_dupootoucharswithheadroom(mio,hrb,oocs,oocslen,ucslen) mio_dupbtoucharswithheadroom(mio,hrb,oocs,oocslen,ucslen) +# define mio_dupootoucharswithheadroom(mio,hrb,oocs,oocslen,ucslen,all) mio_dupbtoucharswithheadroom(mio,hrb,oocs,oocslen,ucslen,all) # define mio_duputooocharswithheadroom(mio,hrb,ucs,ucslen,oocslen) mio_duputobcharswithheadroom(mio,hrb,ucs,ucslen,oocslen) -# define mio_dupootouchars(mio,oocs,oocslen,ucslen) mio_dupbtouchars(mio,oocs,oocslen,ucslen) +# define mio_dupootouchars(mio,oocs,oocslen,ucslen,all) mio_dupbtouchars(mio,oocs,oocslen,ucslen,all) # define mio_duputooochars(mio,ucs,ucslen,oocslen) mio_duputobchars(mio,ucs,ucslen,oocslen) -# define mio_dupootoucstrwithheadroom(mio,hrb,oocs,ucslen) mio_dupbtoucstrwithheadroom(mio,hrb,oocs,ucslen) +# define mio_dupootoucstrwithheadroom(mio,hrb,oocs,ucslen,all) mio_dupbtoucstrwithheadroom(mio,hrb,oocs,ucslen,all) # define mio_duputooocstrwithheadroom(mio,hrb,ucs,oocslen) mio_duputobcstrwithheadroom(mio,hrb,ucs,oocslen) -# define mio_dupootoucstr(mio,oocs,ucslen) mio_dupbtoucstr(mio,oocs,ucslen) +# define mio_dupootoucstr(mio,oocs,ucslen,all) mio_dupbtoucstr(mio,oocs,ucslen,all) # define mio_duputooocstr(mio,ucs,oocslen) mio_duputobcstr(mio,ucs,oocslen) #endif @@ -972,7 +974,8 @@ MIO_EXPORT mio_uch_t* mio_dupbtoucharswithheadroom ( mio_oow_t headroom_bytes, const mio_bch_t* bcs, mio_oow_t bcslen, - mio_oow_t* ucslen + mio_oow_t* ucslen, + int all ); MIO_EXPORT mio_bch_t* mio_duputobcharswithheadroom ( @@ -987,7 +990,8 @@ MIO_EXPORT mio_uch_t* mio_dupbtouchars ( mio_t* mio, const mio_bch_t* bcs, mio_oow_t bcslen, - mio_oow_t* ucslen + mio_oow_t* ucslen, + int all ); MIO_EXPORT mio_bch_t* mio_duputobchars ( @@ -1002,7 +1006,8 @@ MIO_EXPORT mio_uch_t* mio_dupbtoucstrwithheadroom ( mio_t* mio, mio_oow_t headroom_bytes, const mio_bch_t* bcs, - mio_oow_t* ucslen + mio_oow_t* ucslen, + int all ); MIO_EXPORT mio_bch_t* mio_duputobcstrwithheadroom ( @@ -1015,7 +1020,8 @@ MIO_EXPORT mio_bch_t* mio_duputobcstrwithheadroom ( MIO_EXPORT mio_uch_t* mio_dupbtoucstr ( mio_t* mio, const mio_bch_t* bcs, - mio_oow_t* ucslen /* optional: length of returned string */ + mio_oow_t* ucslen, /* optional: length of returned string */ + int all ); MIO_EXPORT mio_bch_t* mio_duputobcstr ( diff --git a/mio/lib/sck-addr.c b/mio/lib/sck-addr.c deleted file mode 100644 index 80f9552..0000000 --- a/mio/lib/sck-addr.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * $Id$ - * - Copyright (c) 2015-2016 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 WAfRRANTIES - 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 "mio-prv.h" - -#include -#include -#include -#include -#include - -#if defined(HAVE_NETINET_IN_H) -# include -#endif -#if defined(HAVE_SYS_UN_H) -# include -#endif -#if defined(HAVE_NETPACKET_PACKET_H) -# include -#endif -#if defined(HAVE_NET_IF_DL_H) -# include -#endif - -#include - -union sockaddr_t -{ - struct sockaddr sa; -#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN > 0) - struct sockaddr_in in4; -#endif -#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) - struct sockaddr_in6 in6; -#endif -#if (MIO_SIZEOF_STRUCT_SOCKADDR_LL > 0) - struct sockaddr_ll ll; -#endif -#if (MIO_SIZEOF_STRUCT_SOCKADDR_UN > 0) - struct sockaddr_un un; -#endif -}; -typedef union sockaddr_t sockaddr_t; - -#undef char_t -#undef cstr_t -#undef str_to_sockaddr -#undef str_to_ipv4 -#undef str_to_ipv6 -#define CHAR_T_IS_BCH -#undef CHAR_T_IS_UCH -#define char_t mio_bch_t -#define cstr_t mio_bcs_t -#define str_to_sockaddr bcstr_to_sockaddr -#define str_to_ipv4 bcstr_to_ipv4 -#define str_to_ipv6 bcstr_to_ipv6 -#include "sck-addr.h" - - -#undef char_t -#undef cstr_t -#undef str_to_sockaddr -#undef str_to_ipv4 -#undef str_to_ipv6 -#undef CHAR_T_IS_BCH -#define CHAR_T_IS_UCH -#define char_t mio_uch_t -#define cstr_t mio_ucs_t -#define str_to_sockaddr ucstr_to_sockaddr -#define str_to_ipv4 ucstr_to_ipv4 -#define str_to_ipv6 ucstr_to_ipv6 -#include "sck-addr.h" diff --git a/mio/lib/sck-addr.h b/mio/lib/sck-addr.h deleted file mode 100644 index 011b88d..0000000 --- a/mio/lib/sck-addr.h +++ /dev/null @@ -1,409 +0,0 @@ -/* - * $Id$ - * - Copyright (c) 2015-2016 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. - */ - -/* this file is included by sck-addr.c */ - -static int str_to_ipv4 (const char_t* str, mio_oow_t len, struct in_addr* inaddr) -{ - const char_t* end; - int dots = 0, digits = 0; - mio_uint32_t acc = 0, addr = 0; - char_t c; - - end = str + len; - - do - { - if (str >= end) - { - if (dots < 3 || digits == 0) return -1; - addr = (addr << 8) | acc; - break; - } - - c = *str++; - - if (c >= '0' && c <= '9') - { - if (digits > 0 && acc == 0) return -1; - acc = acc * 10 + (c - '0'); - if (acc > 255) return -1; - digits++; - } - else if (c == '.') - { - if (dots >= 3 || digits == 0) return -1; - addr = (addr << 8) | acc; - dots++; acc = 0; digits = 0; - } - else return -1; - } - while (1); - - inaddr->s_addr = mio_hton32(addr); - return 0; - -} - -#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) -static int str_to_ipv6 (const char_t* src, mio_oow_t len, struct in6_addr* inaddr) -{ - mio_uint8_t* tp, * endp, * colonp; - const char_t* curtok; - char_t ch; - int saw_xdigit; - unsigned int val; - const char_t* src_end; - - src_end = src + len; - - MIO_MEMSET (inaddr, 0, MIO_SIZEOF(*inaddr)); - tp = &inaddr->s6_addr[0]; - endp = &inaddr->s6_addr[MIO_COUNTOF(inaddr->s6_addr)]; - colonp = MIO_NULL; - - /* Leading :: requires some special handling. */ - if (src < src_end && *src == ':') - { - src++; - if (src >= src_end || *src != ':') return -1; - } - - curtok = src; - saw_xdigit = 0; - val = 0; - - while (src < src_end) - { - int v1; - - ch = *src++; - - if (ch >= '0' && ch <= '9') - v1 = ch - '0'; - else if (ch >= 'A' && ch <= 'F') - v1 = ch - 'A' + 10; - else if (ch >= 'a' && ch <= 'f') - v1 = ch - 'a' + 10; - else v1 = -1; - if (v1 >= 0) - { - val <<= 4; - val |= v1; - if (val > 0xffff) return -1; - saw_xdigit = 1; - continue; - } - - if (ch == ':') - { - 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++ = (mio_uint8_t)(val >> 8) & 0xff; - *tp++ = (mio_uint8_t)val & 0xff; - saw_xdigit = 0; - val = 0; - continue; - } - - if (ch == '.' && ((tp + MIO_SIZEOF(struct in_addr)) <= endp) && - str_to_ipv4(curtok, src_end - curtok, (struct in_addr*)tp) == 0) - { - tp += MIO_SIZEOF(struct in_addr*); - saw_xdigit = 0; - break; - } - - return -1; - } - - if (saw_xdigit) - { - if (tp + MIO_SIZEOF(mio_uint16_t) > endp) return -1; - *tp++ = (mio_uint8_t)(val >> 8) & 0xff; - *tp++ = (mio_uint8_t)val & 0xff; - } - if (colonp != MIO_NULL) - { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - mio_oow_t n = tp - colonp; - mio_oow_t i; - - for (i = 1; i <= n; i++) - { - endp[-i] = colonp[n - i]; - colonp[n - i] = 0; - } - tp = endp; - } - - if (tp != endp) return -1; - - return 0; -} -#endif - - -static int str_to_sockaddr (mio_t* mio, const char_t* str, mio_oow_t len, sockaddr_t* nwad) -{ - const char_t* p; - const char_t* end; - cstr_t tmp; - - p = str; - end = str + len; - - if (p >= end) - { - mio_seterrbfmt (mio, MIO_EINVAL, "blank address"); - return -1; - } - - MIO_MEMSET (nwad, 0, MIO_SIZEOF(*nwad)); - -#if defined(AF_UNIX) - if (*p == '/' && len >= 2) - { - #if defined(CHAR_T_IS_BCH) - mio_copy_bcstr (nwad->un.sun_path, MIO_COUNTOF(nwad->un.sun_path), str); - #else - mio_oow_t dstlen; - - dstlen = MIO_COUNTOF(nwad->un.sun_path) - 1; - if (mio_convutobchars(mio, p, &len, nwad->un.sun_path, &dstlen) <= -1) - { - mio_seterrbfmt (mio, MIO_EINVAL, "unable to convert encoding"); - return -1; - } - nwad->un.sun_path[dstlen] = '\0'; - #endif - nwad->un.sun_family = AF_UNIX; - return 0; - } -#endif - -#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) - if (*p == '[') - { - /* IPv6 address */ - tmp.ptr = (char_t*)++p; /* skip [ and remember the position */ - while (p < end && *p != '%' && *p != ']') p++; - - if (p >= end) goto no_rbrack; - - tmp.len = p - tmp.ptr; - if (*p == '%') - { - /* handle scope id */ - mio_uint32_t x; - - p++; /* skip % */ - - if (p >= end) - { - /* premature end */ - mio_seterrbfmt (mio, MIO_EINVAL, "scope id blank"); - return -1; - } - - if (*p >= '0' && *p <= '9') - { - /* numeric scope id */ - nwad->in6.sin6_scope_id = 0; - do - { - x = nwad->in6.sin6_scope_id * 10 + (*p - '0'); - if (x < nwad->in6.sin6_scope_id) - { - mio_seterrbfmt (mio, MIO_EINVAL, "scope id too large"); - return -1; /* overflow */ - } - nwad->in6.sin6_scope_id = x; - p++; - } - while (p < end && *p >= '0' && *p <= '9'); - } - else - { -#if 0 -TODO: - /* interface name as a scope id? */ - const char_t* stmp = p; - unsigned int index; - do p++; while (p < end && *p != ']'); - if (mio_nwifwcsntoindex (stmp, p - stmp, &index) <= -1) return -1; - tmpad.u.in6.scope = index; -#endif - } - - if (p >= end || *p != ']') goto no_rbrack; - } - p++; /* skip ] */ - - if (str_to_ipv6(tmp.ptr, tmp.len, &nwad->in6.sin6_addr) <= -1) goto unrecog; - nwad->in6.sin6_family = AF_INET6; - } - else - { -#endif - /* IPv4 address */ - tmp.ptr = (char_t*)p; - while (p < end && *p != ':') p++; - tmp.len = p - tmp.ptr; - - if (str_to_ipv4(tmp.ptr, tmp.len, &nwad->in4.sin_addr) <= -1) - { - #if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) - /* check if it is an IPv6 address not enclosed in []. - * the port number can't be specified in this format. */ - if (p >= end || *p != ':') - { - /* without :, it can't be an ipv6 address */ - goto unrecog; - } - - - while (p < end && *p != '%') p++; - tmp.len = p - tmp.ptr; - - if (str_to_ipv6(tmp.ptr, tmp.len, &nwad->in6.sin6_addr) <= -1) goto unrecog; - - if (p < end && *p == '%') - { - /* handle scope id */ - mio_uint32_t x; - - p++; /* skip % */ - - if (p >= end) - { - /* premature end */ - mio_seterrbfmt (mio, MIO_EINVAL, "scope id blank"); - return -1; - } - - if (*p >= '0' && *p <= '9') - { - /* numeric scope id */ - nwad->in6.sin6_scope_id = 0; - do - { - x = nwad->in6.sin6_scope_id * 10 + (*p - '0'); - if (x < nwad->in6.sin6_scope_id) - { - mio_seterrbfmt (mio, MIO_EINVAL, "scope id too large"); - return -1; /* overflow */ - } - nwad->in6.sin6_scope_id = x; - p++; - } - while (p < end && *p >= '0' && *p <= '9'); - } - else - { -#if 0 -TODO - /* interface name as a scope id? */ - const char_t* stmp = p; - unsigned int index; - do p++; while (p < end); - if (mio_nwifwcsntoindex(stmp, p - stmp, &index) <= -1) return -1; - nwad->in6.sin6_scope_id = index; -#endif - } - } - - if (p < end) goto unrecog; /* some gargage after the end? */ - - nwad->in6.sin6_family = AF_INET6; - return 0; - #else - goto unrecog; - #endif - } - - nwad->in4.sin_family = AF_INET; -#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) - } -#endif - - if (p < end && *p == ':') - { - /* port number */ - mio_uint32_t port = 0; - - p++; /* skip : */ - - tmp.ptr = (char_t*)p; - while (p < end && *p >= '0' && *p <= '9') - { - port = port * 10 + (*p - '0'); - p++; - } - - tmp.len = p - tmp.ptr; - if (tmp.len <= 0 || tmp.len >= 6 || - port > MIO_TYPE_MAX(mio_uint16_t)) - { - mio_seterrbfmt (mio, MIO_EINVAL, "port number blank or too large"); - return -1; - } - - #if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) - if (nwad->in4.sin_family == AF_INET) - nwad->in4.sin_port = mio_hton16(port); - else - nwad->in6.sin6_port = mio_hton16(port); - #else - nwad->in4.sin_port = mio_hton16(port); - #endif - } - - return 0; - - -unrecog: - mio_seterrbfmt (mio, MIO_EINVAL, "unrecognized address"); - return -1; - -no_rbrack: - mio_seterrbfmt (mio, MIO_EINVAL, "missing right bracket"); - return -1; -} diff --git a/mio/lib/skad.c b/mio/lib/skad.c new file mode 100644 index 0000000..e8c2c06 --- /dev/null +++ b/mio/lib/skad.c @@ -0,0 +1,1001 @@ +/* + * $Id$ + * + Copyright (c) 2006-2019 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 "mio-skad.h" +#include "mio-prv.h" + +#include +#include +#if defined(HAVE_NETINET_IN_H) +# include +#endif +#if defined(HAVE_SYS_UN_H) +# include +#endif +#if defined(HAVE_NETPACKET_PACKET_H) +# include +#endif +#if defined(HAVE_NET_IF_DL_H) +# include +#endif + +union mio_skad_alt_t +{ + struct sockaddr sa; +#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN > 0) + struct sockaddr_in in4; +#endif +#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) + struct sockaddr_in6 in6; +#endif +#if (MIO_SIZEOF_STRUCT_SOCKADDR_LL > 0) + struct sockaddr_ll ll; +#endif +#if (MIO_SIZEOF_STRUCT_SOCKADDR_UN > 0) + struct sockaddr_un un; +#endif +}; +typedef union mio_skad_alt_t mio_skad_alt_t; + + +static int str_to_ipv4 (const mio_ooch_t* str, mio_oow_t len, struct in_addr* inaddr) +{ + const mio_ooch_t* end; + int dots = 0, digits = 0; + mio_uint32_t acc = 0, addr = 0; + mio_ooch_t c; + + end = str + len; + + do + { + if (str >= end) + { + if (dots < 3 || digits == 0) return -1; + addr = (addr << 8) | acc; + break; + } + + c = *str++; + + if (c >= '0' && c <= '9') + { + if (digits > 0 && acc == 0) return -1; + acc = acc * 10 + (c - '0'); + if (acc > 255) return -1; + digits++; + } + else if (c == '.') + { + if (dots >= 3 || digits == 0) return -1; + addr = (addr << 8) | acc; + dots++; acc = 0; digits = 0; + } + else return -1; + } + while (1); + + inaddr->s_addr = mio_hton32(addr); + return 0; + +} + +#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) +static int str_to_ipv6 (const mio_ooch_t* src, mio_oow_t len, struct in6_addr* inaddr) +{ + mio_uint8_t* tp, * endp, * colonp; + const mio_ooch_t* curtok; + mio_ooch_t ch; + int saw_xdigit; + unsigned int val; + const mio_ooch_t* src_end; + + src_end = src + len; + + MIO_MEMSET (inaddr, 0, MIO_SIZEOF(*inaddr)); + tp = &inaddr->s6_addr[0]; + endp = &inaddr->s6_addr[MIO_COUNTOF(inaddr->s6_addr)]; + colonp = MIO_NULL; + + /* Leading :: requires some special handling. */ + if (src < src_end && *src == ':') + { + src++; + if (src >= src_end || *src != ':') return -1; + } + + curtok = src; + saw_xdigit = 0; + val = 0; + + while (src < src_end) + { + int v1; + + ch = *src++; + + if (ch >= '0' && ch <= '9') + v1 = ch - '0'; + else if (ch >= 'A' && ch <= 'F') + v1 = ch - 'A' + 10; + else if (ch >= 'a' && ch <= 'f') + v1 = ch - 'a' + 10; + else v1 = -1; + if (v1 >= 0) + { + val <<= 4; + val |= v1; + if (val > 0xffff) return -1; + saw_xdigit = 1; + continue; + } + + if (ch == ':') + { + 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++ = (mio_uint8_t)(val >> 8) & 0xff; + *tp++ = (mio_uint8_t)val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + + if (ch == '.' && ((tp + MIO_SIZEOF(struct in_addr)) <= endp) && + str_to_ipv4(curtok, src_end - curtok, (struct in_addr*)tp) == 0) + { + tp += MIO_SIZEOF(struct in_addr*); + saw_xdigit = 0; + break; + } + + return -1; + } + + if (saw_xdigit) + { + if (tp + MIO_SIZEOF(mio_uint16_t) > endp) return -1; + *tp++ = (mio_uint8_t)(val >> 8) & 0xff; + *tp++ = (mio_uint8_t)val & 0xff; + } + if (colonp != MIO_NULL) + { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + mio_oow_t n = tp - colonp; + mio_oow_t i; + + for (i = 1; i <= n; i++) + { + endp[-i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + + if (tp != endp) return -1; + + return 0; +} +#endif + +int mio_oocharstoskad (mio_t* mio, const mio_ooch_t* str, mio_oow_t len, mio_skad_t* _skad) +{ + mio_skad_alt_t* skad = (mio_skad_alt_t*)_skad; + const mio_ooch_t* p; + const mio_ooch_t* end; + mio_oocs_t tmp; + + p = str; + end = str + len; + + if (p >= end) + { + mio_seterrbfmt (mio, MIO_EINVAL, "blank address"); + return -1; + } + + MIO_MEMSET (skad, 0, MIO_SIZEOF(*skad)); + +#if defined(AF_UNIX) + if (*p == '/' && len >= 2) + { + #if defined(MIO_OOCH_IS_BCH) + mio_copy_bcstr (skad->un.sun_path, MIO_COUNTOF(skad->un.sun_path), str); + #else + mio_oow_t dstlen; + dstlen = MIO_COUNTOF(skad->un.sun_path) - 1; + if (mio_convutobchars(mio, p, &len, skad->un.sun_path, &dstlen) <= -1) return -1; + skad->un.sun_path[dstlen] = '\0'; + #endif + skad->un.sun_family = AF_UNIX; + return 0; + } +#endif + +#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) + if (*p == '[') + { + /* IPv6 address */ + tmp.ptr = (mio_ooch_t*)++p; /* skip [ and remember the position */ + while (p < end && *p != '%' && *p != ']') p++; + + if (p >= end) goto no_rbrack; + + tmp.len = p - tmp.ptr; + if (*p == '%') + { + /* handle scope id */ + mio_uint32_t x; + + p++; /* skip % */ + + if (p >= end) + { + /* premature end */ + mio_seterrbfmt (mio, MIO_EINVAL, "scope id blank"); + return -1; + } + + if (*p >= '0' && *p <= '9') + { + /* numeric scope id */ + skad->in6.sin6_scope_id = 0; + do + { + x = skad->in6.sin6_scope_id * 10 + (*p - '0'); + if (x < skad->in6.sin6_scope_id) + { + mio_seterrbfmt (mio, MIO_EINVAL, "scope id too large"); + return -1; /* overflow */ + } + skad->in6.sin6_scope_id = x; + p++; + } + while (p < end && *p >= '0' && *p <= '9'); + } + else + { + /* interface name as a scope id? */ + const mio_ooch_t* stmp = p; + unsigned int index; + do p++; while (p < end && *p != ']'); +/* TODO if (mio_ucharstoifindex(mio, stmp, p - stmp, &index) <= -1) return -1; */ + skad->in6.sin6_scope_id = index; + } + + if (p >= end || *p != ']') goto no_rbrack; + } + p++; /* skip ] */ + + if (str_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog; + skad->in6.sin6_family = AF_INET6; + } + else + { +#endif + /* IPv4 address */ + tmp.ptr = (mio_ooch_t*)p; + while (p < end && *p != ':') p++; + tmp.len = p - tmp.ptr; + + if (str_to_ipv4(tmp.ptr, tmp.len, &skad->in4.sin_addr) <= -1) + { + #if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) + /* check if it is an IPv6 address not enclosed in []. + * the port number can't be specified in this format. */ + if (p >= end || *p != ':') + { + /* without :, it can't be an ipv6 address */ + goto unrecog; + } + + + while (p < end && *p != '%') p++; + tmp.len = p - tmp.ptr; + + if (str_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog; + + if (p < end && *p == '%') + { + /* handle scope id */ + mio_uint32_t x; + + p++; /* skip % */ + + if (p >= end) + { + /* premature end */ + mio_seterrbfmt (mio, MIO_EINVAL, "scope id blank"); + return -1; + } + + if (*p >= '0' && *p <= '9') + { + /* numeric scope id */ + skad->in6.sin6_scope_id = 0; + do + { + x = skad->in6.sin6_scope_id * 10 + (*p - '0'); + if (x < skad->in6.sin6_scope_id) + { + mio_seterrbfmt (mio, MIO_EINVAL, "scope id too large"); + return -1; /* overflow */ + } + skad->in6.sin6_scope_id = x; + p++; + } + while (p < end && *p >= '0' && *p <= '9'); + } + else + { + /* interface name as a scope id? */ + const mio_ooch_t* stmp = p; + unsigned int index; + do p++; while (p < end); +/* TODO if (mio_ucharstoifindex(mio, stmp, p - stmp, &index) <= -1) return -1;*/ + skad->in6.sin6_scope_id = index; + } + } + + if (p < end) goto unrecog; /* some gargage after the end? */ + + skad->in6.sin6_family = AF_INET6; + return 0; + #else + goto unrecog; + #endif + } + + skad->in4.sin_family = AF_INET; +#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) + } +#endif + + if (p < end && *p == ':') + { + /* port number */ + mio_uint32_t port = 0; + + p++; /* skip : */ + + tmp.ptr = (mio_ooch_t*)p; + while (p < end && *p >= '0' && *p <= '9') + { + port = port * 10 + (*p - '0'); + p++; + } + + tmp.len = p - tmp.ptr; + if (tmp.len <= 0 || tmp.len >= 6 || + port > MIO_TYPE_MAX(mio_uint16_t)) + { + mio_seterrbfmt (mio, MIO_EINVAL, "port number blank or too large"); + return -1; + } + + #if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) + if (skad->in4.sin_family == AF_INET) + skad->in4.sin_port = mio_hton16(port); + else + skad->in6.sin6_port = mio_hton16(port); + #else + skad->in4.sin_port = mio_hton16(port); + #endif + } + + return 0; + +unrecog: + mio_seterrbfmt (mio, MIO_EINVAL, "unrecognized address"); + return -1; + +no_rbrack: + mio_seterrbfmt (mio, MIO_EINVAL, "missing right bracket"); + return -1; +} + + +/* ---------------------------------------------------------- */ + + +#define __BTOA(type_t,b,p,end) \ + do { \ + type_t* sp = p; \ + do { \ + if (p >= end) { \ + if (p == sp) break; \ + if (p - sp > 1) p[-2] = p[-1]; \ + p[-1] = (b % 10) + '0'; \ + } \ + else *p++ = (b % 10) + '0'; \ + b /= 10; \ + } while (b > 0); \ + if (p - sp > 1) { \ + type_t t = sp[0]; \ + sp[0] = p[-1]; \ + p[-1] = t; \ + } \ + } while (0); + +#define __ADDDOT(p, end) \ + do { \ + if (p >= end) break; \ + *p++ = '.'; \ + } while (0) + +/* ---------------------------------------------------------- */ + +static mio_oow_t ip4addr_to_ucstr (const struct in_addr* ipad, mio_uch_t* buf, mio_oow_t size) +{ + mio_uint8_t b; + mio_uch_t* p, * end; + mio_uint32_t ip; + + if (size <= 0) return 0; + + ip = ipad->s_addr; + + p = buf; + end = buf + size - 1; + +#if defined(MIO_ENDIAN_BIG) + b = (ip >> 24) & 0xFF; __BTOA (mio_uch_t, b, p, end); __ADDDOT (p, end); + b = (ip >> 16) & 0xFF; __BTOA (mio_uch_t, b, p, end); __ADDDOT (p, end); + b = (ip >> 8) & 0xFF; __BTOA (mio_uch_t, b, p, end); __ADDDOT (p, end); + b = (ip >> 0) & 0xFF; __BTOA (mio_uch_t, b, p, end); +#elif defined(MIO_ENDIAN_LITTLE) + b = (ip >> 0) & 0xFF; __BTOA (mio_uch_t, b, p, end); __ADDDOT (p, end); + b = (ip >> 8) & 0xFF; __BTOA (mio_uch_t, b, p, end); __ADDDOT (p, end); + b = (ip >> 16) & 0xFF; __BTOA (mio_uch_t, b, p, end); __ADDDOT (p, end); + b = (ip >> 24) & 0xFF; __BTOA (mio_uch_t, b, p, end); +#else +# error Unknown Endian +#endif + + *p = '\0'; + return p - buf; +} + + +static mio_oow_t ip6addr_to_ucstr (const struct in6_addr* ipad, mio_uch_t* buf, mio_oow_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 (MIO_SIZEOF(ipad->s6_addr) / MIO_SIZEOF(mio_uint16_t)) + + mio_uch_t tmp[MIO_COUNTOF("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")], *tp; + struct { int base, len; } best, cur; + mio_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. + */ + MIO_MEMSET (words, 0, MIO_SIZEOF(words)); + for (i = 0; i < MIO_SIZEOF(ipad->s6_addr); i++) + words[i / 2] |= (ipad->s6_addr[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + best.len = 0; + cur.base = -1; + cur.len = 0; + + 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++ = ':'; + continue; + } + + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) *tp++ = ':'; + + /* 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))) + { + struct in_addr ip4ad; + MIO_MEMCPY (&ip4ad.s_addr, ipad->s6_addr + 12, MIO_SIZEOF(ip4ad.s_addr)); + tp += ip4addr_to_ucstr(&ip4ad, tp, MIO_COUNTOF(tmp) - (tp - tmp)); + break; + } + +/* TODO tp += mio_fmt_uintmax_to_ucstr(tp, MIO_COUNTOF(tmp) - (tp - tmp), words[i], 16, 0, '\0', MIO_NULL); */ + } + + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == IP6ADDR_NWORDS) *tp++ = ':'; + *tp++ = '\0'; + + return mio_copy_ucstr(buf, size, tmp); + +#undef IP6ADDR_NWORDS +} + + +mio_oow_t mio_skadtoucstr (mio_t* mio, const mio_skad_t* _skad, mio_uch_t* buf, mio_oow_t len, int flags) +{ + const mio_skad_alt_t* skad = (const mio_skad_alt_t*)_skad; + mio_oow_t xlen = 0; + + /* unsupported types will result in an empty string */ + + switch (mio_skad_family(_skad)) + { + case MIO_AF_INET: + if (flags & MIO_SKAD_TO_BCSTR_ADDR) + { + if (xlen + 1 >= len) goto done; + xlen += ip4addr_to_ucstr(&skad->in4.sin_addr, buf, len); + } + + if (flags & MIO_SKAD_TO_BCSTR_PORT) + { + if (!(flags & MIO_SKAD_TO_BCSTR_ADDR) || skad->in4.sin_port != 0) + { + if (flags & MIO_SKAD_TO_BCSTR_ADDR) + { + if (xlen + 1 >= len) goto done; + buf[xlen++] = ':'; + } + + if (xlen + 1 >= len) goto done; +/* TODO xlen += mio_fmt_uintmax_to_ucstr(&buf[xlen], len - xlen, mio_ntoh16(skad->in4.sin_port), 10, 0, '\0', MIO_NULL); */ + } + } + break; + + case MIO_AF_INET6: + if (flags & MIO_SKAD_TO_BCSTR_PORT) + { + if (!(flags & MIO_SKAD_TO_BCSTR_ADDR) || skad->in6.sin6_port != 0) + { + if (flags & MIO_SKAD_TO_BCSTR_ADDR) + { + if (xlen + 1 >= len) goto done; + buf[xlen++] = '['; + } + } + } + + if (flags & MIO_SKAD_TO_BCSTR_ADDR) + { + if (xlen + 1 >= len) goto done; + xlen += ip6addr_to_ucstr(&skad->in6.sin6_addr, &buf[xlen], len - xlen); + + if (skad->in6.sin6_scope_id != 0) + { + int tmp; + + if (xlen + 1 >= len) goto done; + buf[xlen++] = '%'; + + if (xlen + 1 >= len) goto done; + +/* TODO tmp = mio_ifindextoucstr(mio, skad->in6.sin6_scope_id, &buf[xlen], len - xlen);*/ + if (tmp <= -1) + { +/* TODO xlen += mio_fmt_uintmax_to_ucstr(&buf[xlen], len - xlen, skad->in6.sin6_scope_id, 10, 0, '\0', MIO_NULL); */ + } + else xlen += tmp; + } + } + + if (flags & MIO_SKAD_TO_BCSTR_PORT) + { + if (!(flags & MIO_SKAD_TO_BCSTR_ADDR) || skad->in6.sin6_port != 0) + { + if (flags & MIO_SKAD_TO_BCSTR_ADDR) + { + if (xlen + 1 >= len) goto done; + buf[xlen++] = ']'; + + if (xlen + 1 >= len) goto done; + buf[xlen++] = ':'; + } + + if (xlen + 1 >= len) goto done; +/* TODO xlen += mio_fmt_uintmax_to_ucstr(&buf[xlen], len - xlen, mio_ntoh16(skad->in6.sin6_port), 10, 0, '\0', MIO_NULL); */ + } + } + + break; + + case MIO_AF_UNIX: + if (flags & MIO_SKAD_TO_BCSTR_ADDR) + { + if (xlen + 1 >= len) goto done; + buf[xlen++] = '@'; + + if (xlen + 1 >= len) goto done; + else + { + mio_oow_t mbslen, wcslen = len - xlen; + mio_convbtoucstr (mio, skad->un.sun_path, &mbslen, &buf[xlen], &wcslen, 1); + /* i don't care about conversion errors */ + xlen += wcslen; + } + } + + break; + } + +done: + if (xlen < len) buf[xlen] = '\0'; + return xlen; +} + +/* ---------------------------------------------------------- */ + +static mio_oow_t ip4addr_to_bcstr (const struct in_addr* ipad, mio_bch_t* buf, mio_oow_t size) +{ + mio_uint8_t b; + mio_bch_t* p, * end; + mio_uint32_t ip; + + if (size <= 0) return 0; + + ip = ipad->s_addr; + + p = buf; + end = buf + size - 1; + +#if defined(MIO_ENDIAN_BIG) + b = (ip >> 24) & 0xFF; __BTOA (mio_bch_t, b, p, end); __ADDDOT (p, end); + b = (ip >> 16) & 0xFF; __BTOA (mio_bch_t, b, p, end); __ADDDOT (p, end); + b = (ip >> 8) & 0xFF; __BTOA (mio_bch_t, b, p, end); __ADDDOT (p, end); + b = (ip >> 0) & 0xFF; __BTOA (mio_bch_t, b, p, end); +#elif defined(MIO_ENDIAN_LITTLE) + b = (ip >> 0) & 0xFF; __BTOA (mio_bch_t, b, p, end); __ADDDOT (p, end); + b = (ip >> 8) & 0xFF; __BTOA (mio_bch_t, b, p, end); __ADDDOT (p, end); + b = (ip >> 16) & 0xFF; __BTOA (mio_bch_t, b, p, end); __ADDDOT (p, end); + b = (ip >> 24) & 0xFF; __BTOA (mio_bch_t, b, p, end); +#else +# error Unknown Endian +#endif + + *p = '\0'; + return p - buf; +} + + +static mio_oow_t ip6addr_to_bcstr (const struct in6_addr* ipad, mio_bch_t* buf, mio_oow_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 (MIO_SIZEOF(ipad->s6_addr) / MIO_SIZEOF(mio_uint16_t)) + + mio_bch_t tmp[MIO_COUNTOF("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")], *tp; + struct { int base, len; } best, cur; + mio_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. + */ + MIO_MEMSET (words, 0, MIO_SIZEOF(words)); + for (i = 0; i < MIO_SIZEOF(ipad->s6_addr); i++) + words[i / 2] |= (ipad->s6_addr[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + best.len = 0; + cur.base = -1; + cur.len = 0; + + 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++ = ':'; + continue; + } + + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) *tp++ = ':'; + + /* 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))) + { + struct in_addr ip4ad; + MIO_MEMCPY (&ip4ad.s_addr, ipad->s6_addr + 12, MIO_SIZEOF(ip4ad.s_addr)); + tp += ip4addr_to_bcstr(&ip4ad, tp, MIO_COUNTOF(tmp) - (tp - tmp)); + break; + } + +/* TODO: tp += mio_fmt_uintmax_to_bcstr(tp, MIO_COUNTOF(tmp) - (tp - tmp), words[i], 16, 0, '\0', MIO_NULL); */ + } + + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == IP6ADDR_NWORDS) *tp++ = ':'; + *tp++ = '\0'; + + return mio_copy_bcstr(buf, size, tmp); + +#undef IP6ADDR_NWORDS +} + + +mio_oow_t mio_skadtobcstr (mio_t* mio, const mio_skad_t* _skad, mio_bch_t* buf, mio_oow_t len, int flags) +{ + const mio_skad_alt_t* skad = (const mio_skad_alt_t*)_skad; + mio_oow_t xlen = 0; + + /* unsupported types will result in an empty string */ + + switch (mio_skad_family(_skad)) + { + case MIO_AF_INET: + if (flags & MIO_SKAD_TO_BCSTR_ADDR) + { + if (xlen + 1 >= len) goto done; + xlen += ip4addr_to_bcstr(&skad->in4.sin_addr, buf, len); + } + + if (flags & MIO_SKAD_TO_BCSTR_PORT) + { + if (!(flags & MIO_SKAD_TO_BCSTR_ADDR) || skad->in4.sin_port != 0) + { + if (flags & MIO_SKAD_TO_BCSTR_ADDR) + { + if (xlen + 1 >= len) goto done; + buf[xlen++] = ':'; + } + + if (xlen + 1 >= len) goto done; +/* xlen += mio_fmt_uintmax_to_bcstr(&buf[xlen], len - xlen, mio_ntoh16(skad->in4.sin_port), 10, 0, '\0', MIO_NULL);*/ + } + } + break; + + case MIO_AF_INET6: + if (flags & MIO_SKAD_TO_BCSTR_PORT) + { + if (!(flags & MIO_SKAD_TO_BCSTR_ADDR) || skad->in6.sin6_port != 0) + { + if (flags & MIO_SKAD_TO_BCSTR_ADDR) + { + if (xlen + 1 >= len) goto done; + buf[xlen++] = '['; + } + } + } + + if (flags & MIO_SKAD_TO_BCSTR_ADDR) + { + + if (xlen + 1 >= len) goto done; + xlen += ip6addr_to_bcstr(&skad->in6.sin6_addr, &buf[xlen], len - xlen); + + if (skad->in6.sin6_scope_id != 0) + { + int tmp; + + if (xlen + 1 >= len) goto done; + buf[xlen++] = '%'; + + if (xlen + 1 >= len) goto done; + + /* TODO tmp = mio_ifindextobcstr(mio, skad->in6.sin6_scope_id, &buf[xlen], len - xlen);*/ + if (tmp <= -1) + { +/* TODO xlen += mio_fmt_uintmax_to_bcstr(&buf[xlen], len - xlen, skad->in6.sin6_scope_id, 10, 0, '\0', MIO_NULL); */ + } + else xlen += tmp; + } + } + + if (flags & MIO_SKAD_TO_BCSTR_PORT) + { + if (!(flags & MIO_SKAD_TO_BCSTR_ADDR) || skad->in6.sin6_port != 0) + { + if (flags & MIO_SKAD_TO_BCSTR_ADDR) + { + if (xlen + 1 >= len) goto done; + buf[xlen++] = ']'; + + if (xlen + 1 >= len) goto done; + buf[xlen++] = ':'; + } + + if (xlen + 1 >= len) goto done; +/* xlen += mio_fmt_uintmax_to_bcstr(&buf[xlen], len - xlen, mio_ntoh16(skad->in6.sin6_port), 10, 0, '\0', MIO_NULL); */ + } + } + + break; + + case MIO_AF_UNIX: + if (flags & MIO_SKAD_TO_BCSTR_ADDR) + { + if (xlen + 1 >= len) goto done; + buf[xlen++] = '@'; + + if (xlen + 1 >= len) goto done; + xlen += mio_copy_bcstr(&buf[xlen], len - xlen, skad->un.sun_path); +#if 0 + if (xlen + 1 >= len) goto done; + else + { + mio_oow_t wcslen, mbslen = len - xlen; + mio_convutobcstr (mio, skad->un.sun_path, &wcslen, &buf[xlen], &mbslen); + /* i don't care about conversion errors */ + xlen += mbslen; + } +#endif + } + + break; + } + +done: + if (xlen < len) buf[xlen] = '\0'; + return xlen; +} + + +/* ------------------------------------------------------------------------- */ + + +int mio_skad_family (const mio_skad_t* _skad) +{ + const mio_skad_alt_t* skad = (const mio_skad_alt_t*)_skad; + /*MIO_STATIC_ASSERT (MIO_SIZEOF(*_skad) >= MIO_SIZEOF(*skad));*/ + return skad->sa.sa_family; +} + +int mio_skad_size (const mio_skad_t* _skad) +{ + const mio_skad_alt_t* skad = (const mio_skad_alt_t*)_skad; + /*MIO_STATIC_ASSERT (MIO_SIZEOF(*_skad) >= MIO_SIZEOF(*skad));*/ + + switch (skad->sa.sa_family) + { + #if defined(AF_INET) && (MIO_SIZEOF_STRUCT_SOCKADDR_IN > 0) + case AF_INET: return MIO_SIZEOF(struct sockaddr_in); + #endif + #if defined(AF_INET6) && (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0) + case AF_INET6: return MIO_SIZEOF(struct sockaddr_in6); + #endif + #if defined(AF_PACKET) && (MIO_SIZEOF_STRUCT_SOCKADDR_LL > 0) + case AF_PACKET: return MIO_SIZEOF(struct sockaddr_ll); + #endif + #if defined(AF_UNIX) && (MIO_SIZEOF_STRUCT_SOCKADDR_UN > 0) + case AF_UNIX: return MIO_SIZEOF(struct sockaddr_un); + #endif + } + + return 0; +} + +void mio_clear_skad (mio_skad_t* _skad) +{ + mio_skad_alt_t* skad = (mio_skad_alt_t*)_skad; + /*MIO_STATIC_ASSERT (MIO_SIZEOF(*_skad) >= MIO_SIZEOF(*skad));*/ + MIO_MEMSET (skad, 0, MIO_SIZEOF(*skad)); + skad->sa.sa_family = MIO_AF_UNSPEC; +} diff --git a/mio/lib/utl.c b/mio/lib/utl.c index ab8521c..1a455f4 100644 --- a/mio/lib/utl.c +++ b/mio/lib/utl.c @@ -1025,12 +1025,12 @@ int mio_conv_ucstr_to_utf8 (const mio_uch_t* ucs, mio_oow_t* ucslen, mio_bch_t* /* ----------------------------------------------------------------------- */ -int mio_convbtouchars (mio_t* mio, const mio_bch_t* bcs, mio_oow_t* bcslen, mio_uch_t* ucs, mio_oow_t* ucslen) +int mio_convbtouchars (mio_t* mio, const mio_bch_t* bcs, mio_oow_t* bcslen, mio_uch_t* ucs, mio_oow_t* ucslen, int all) { /* length bound */ int n; - n = mio_conv_bchars_to_uchars_with_cmgr(bcs, bcslen, ucs, ucslen, mio_getcmgr(mio), 0); + n = mio_conv_bchars_to_uchars_with_cmgr(bcs, bcslen, ucs, ucslen, mio_getcmgr(mio), all); if (n <= -1) { @@ -1056,12 +1056,12 @@ int mio_convutobchars (mio_t* mio, const mio_uch_t* ucs, mio_oow_t* ucslen, mio_ return n; } -int mio_convbtoucstr (mio_t* mio, const mio_bch_t* bcs, mio_oow_t* bcslen, mio_uch_t* ucs, mio_oow_t* ucslen) +int mio_convbtoucstr (mio_t* mio, const mio_bch_t* bcs, mio_oow_t* bcslen, mio_uch_t* ucs, mio_oow_t* ucslen, int all) { /* null-terminated. */ int n; - n = mio_conv_bcstr_to_ucstr_with_cmgr(bcs, bcslen, ucs, ucslen, mio_getcmgr(mio), 0); + n = mio_conv_bcstr_to_ucstr_with_cmgr(bcs, bcslen, ucs, ucslen, mio_getcmgr(mio), all); if (n <= -1) { @@ -1088,13 +1088,13 @@ int mio_convutobcstr (mio_t* mio, const mio_uch_t* ucs, mio_oow_t* ucslen, mio_b /* ----------------------------------------------------------------------- */ -MIO_INLINE mio_uch_t* mio_dupbtoucharswithheadroom (mio_t* mio, mio_oow_t headroom_bytes, const mio_bch_t* bcs, mio_oow_t bcslen, mio_oow_t* ucslen) +MIO_INLINE mio_uch_t* mio_dupbtoucharswithheadroom (mio_t* mio, mio_oow_t headroom_bytes, const mio_bch_t* bcs, mio_oow_t bcslen, mio_oow_t* ucslen, int all) { mio_oow_t inlen, outlen; mio_uch_t* ptr; inlen = bcslen; - if (mio_convbtouchars(mio, bcs, &inlen, MIO_NULL, &outlen) <= -1) + if (mio_convbtouchars(mio, bcs, &inlen, MIO_NULL, &outlen, all) <= -1) { /* note it's also an error if no full conversion is made in this function */ return MIO_NULL; @@ -1106,7 +1106,7 @@ MIO_INLINE mio_uch_t* mio_dupbtoucharswithheadroom (mio_t* mio, mio_oow_t headro inlen = bcslen; ptr = (mio_uch_t*)((mio_oob_t*)ptr + headroom_bytes); - mio_convbtouchars (mio, bcs, &inlen, ptr, &outlen); + mio_convbtouchars (mio, bcs, &inlen, ptr, &outlen, all); /* mio_convbtouchars() doesn't null-terminate the target. * but in mio_dupbtouchars(), i allocate space. so i don't mind @@ -1116,9 +1116,9 @@ MIO_INLINE mio_uch_t* mio_dupbtoucharswithheadroom (mio_t* mio, mio_oow_t headro return ptr; } -mio_uch_t* mio_dupbtouchars (mio_t* mio, const mio_bch_t* bcs, mio_oow_t bcslen, mio_oow_t* ucslen) +mio_uch_t* mio_dupbtouchars (mio_t* mio, const mio_bch_t* bcs, mio_oow_t bcslen, mio_oow_t* ucslen, int all) { - return mio_dupbtoucharswithheadroom (mio, 0, bcs, bcslen, ucslen); + return mio_dupbtoucharswithheadroom (mio, 0, bcs, bcslen, ucslen, all); } MIO_INLINE mio_bch_t* mio_duputobcharswithheadroom (mio_t* mio, mio_oow_t headroom_bytes, const mio_uch_t* ucs, mio_oow_t ucslen, mio_oow_t* bcslen) @@ -1153,12 +1153,12 @@ mio_bch_t* mio_duputobchars (mio_t* mio, const mio_uch_t* ucs, mio_oow_t ucslen, /* ----------------------------------------------------------------------- */ -MIO_INLINE mio_uch_t* mio_dupbtoucstrwithheadroom (mio_t* mio, mio_oow_t headroom_bytes, const mio_bch_t* bcs, mio_oow_t* ucslen) +MIO_INLINE mio_uch_t* mio_dupbtoucstrwithheadroom (mio_t* mio, mio_oow_t headroom_bytes, const mio_bch_t* bcs, mio_oow_t* ucslen, int all) { mio_oow_t inlen, outlen; mio_uch_t* ptr; - if (mio_convbtoucstr(mio, bcs, &inlen, MIO_NULL, &outlen) <= -1) + if (mio_convbtoucstr(mio, bcs, &inlen, MIO_NULL, &outlen, all) <= -1) { /* note it's also an error if no full conversion is made in this function */ return MIO_NULL; @@ -1168,14 +1168,14 @@ MIO_INLINE mio_uch_t* mio_dupbtoucstrwithheadroom (mio_t* mio, mio_oow_t headroo ptr = (mio_uch_t*)mio_allocmem(mio, headroom_bytes + (outlen * MIO_SIZEOF(mio_uch_t))); if (!ptr) return MIO_NULL; - mio_convbtoucstr (mio, bcs, &inlen, ptr, &outlen); + mio_convbtoucstr (mio, bcs, &inlen, ptr, &outlen, all); if (ucslen) *ucslen = outlen; return ptr; } -mio_uch_t* mio_dupbtoucstr (mio_t* mio, const mio_bch_t* bcs, mio_oow_t* ucslen) +mio_uch_t* mio_dupbtoucstr (mio_t* mio, const mio_bch_t* bcs, mio_oow_t* ucslen, int all) { - return mio_dupbtoucstrwithheadroom (mio, 0, bcs, ucslen); + return mio_dupbtoucstrwithheadroom (mio, 0, bcs, ucslen, all); } MIO_INLINE mio_bch_t* mio_duputobcstrwithheadroom (mio_t* mio, mio_oow_t headroom_bytes, const mio_uch_t* ucs, mio_oow_t* bcslen)