migrated some files from cmn to si

This commit is contained in:
2016-04-28 15:29:28 +00:00
parent 49d3dcfeda
commit 9cb6c963fa
48 changed files with 792 additions and 775 deletions

View File

@ -24,15 +24,12 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <qse/types.h>
#include <qse/macros.h>
#include <qse/io/sio.h>
#include <qse/cmn/str.h>
#include "mem.h"
#if defined(HAVE_EXECINFO_H)
# include <execinfo.h>
# include <stdlib.h>
# include <qse/cmn/str.h>
#endif
#if defined(_WIN32)
@ -90,8 +87,10 @@ void qse_assert_failed (
{
qse_char_t tmp[1024];
DWORD written;
static qse_char_t* static_header = QSE_T("=[ASSERTION FAILURE]===========================================================\r\n");
static qse_char_t* static_footer = QSE_T("===============================================================================\r\n");
WriteConsole (stderr, QSE_T("[ASSERTION FAILURE]\r\n"), 21, &written, QSE_NULL);
WriteConsole (stderr, static_header, qse_strlen(static_header), &written, QSE_NULL);
qse_strxfmt (tmp, QSE_COUNTOF(tmp), QSE_T("[FILE %s LINE %lu]\r\n"), file, (unsigned long)line);
WriteConsole (stderr, tmp, qse_strlen(tmp), &written, QSE_NULL);
@ -106,13 +105,17 @@ void qse_assert_failed (
WriteConsole (stderr, desc, qse_strlen(desc), &written, QSE_NULL);
WriteConsole (stderr, QSE_T("\r\n"), 2, &written, QSE_NULL);
}
WriteConsole (stderr, static_header, qse_strlen(static_footer), &written, QSE_NULL);
}
#elif defined(__OS2__)
HFILE stderr = (HFILE)2;
ULONG written;
qse_mchar_t tmp[1024];
static qse_mchar_t* static_header = QSE_MT("=[ASSERTION FAILURE]===========================================================\r\n");
static qse_mchar_t* static_footer = QSE_MT("===============================================================================\r\n");
DosWrite (stderr, QSE_T("[ASSERTION FAILURE]\r\n"), 21, &written);
DosWrite (stderr, static_header, qse_mbslen(static_header), &written);
#if defined(QSE_CHAR_IS_MCHAR)
qse_mbsxfmt (tmp, QSE_COUNTOF(tmp), QSE_MT("FILE %hs LINE %lu\r\n"), file, (unsigned long)line);
@ -137,12 +140,15 @@ void qse_assert_failed (
#endif
DosWrite (stderr, tmp, qse_mbslen(tmp), &written);
}
DosWrite (stderr, static_footer, qse_mbslen(static_footer), &written);
#elif defined(__DOS__)
int stderr = 2;
qse_mchar_t tmp[1024];
static qse_mchar_t* static_header = QSE_MT("=[ASSERTION FAILURE]===========================================================\r\n");
static qse_mchar_t* static_footer = QSE_MT("===============================================================================\r\n");
write (stderr, QSE_T("[ASSERTION FAILURE]\r\n"), 21);
write (stderr, static_header, qse_mbslen(static_header));
#if defined(QSE_CHAR_IS_MCHAR)
qse_mbsxfmt (tmp, QSE_COUNTOF(tmp), QSE_MT("FILE %hs LINE %lu\r\n"), file, (unsigned long)line);
@ -168,6 +174,7 @@ void qse_assert_failed (
write (stderr, tmp, qse_mbslen(tmp));
}
write (stderr, static_footer, qse_mbslen(static_footer));
#elif defined(macintosh)
/* note 'desc' is not used for macintosh at this moment.
@ -202,9 +209,8 @@ void qse_assert_failed (
#else
static qse_mchar_t* static_msg[] =
static qse_mchar_t* oops_msg[] =
{
QSE_MT("=[ASSERTION FAILURE]============================================================\n"),
QSE_MT(" __ \n"),
QSE_MT(" _____ _____ _____ _____| |\n"),
QSE_MT("| | | _ | __| |\n"),
@ -212,8 +218,9 @@ void qse_assert_failed (
QSE_MT("|_____|_____|__| |_____|__|\n"),
QSE_MT(" \n")
};
static qse_mchar_t* static_bthdr = QSE_MT("=[BACKTRACES]===================================================================\n");
static qse_mchar_t* static_footer= QSE_MT("================================================================================\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");
qse_mchar_t tmp[1024];
qse_size_t i;
@ -224,9 +231,11 @@ void qse_assert_failed (
char** btsyms;
#endif
for (i = 0; i < QSE_COUNTOF(static_msg); i++)
write (2, static_header, qse_mbslen(static_header));
for (i = 0; i < QSE_COUNTOF(oops_msg); i++)
{
write (2, static_msg[i], qse_mbslen(static_msg[i]));
write (2, oops_msg[i], qse_mbslen(oops_msg[i]));
}
#if defined(QSE_CHAR_IS_MCHAR)

View File

@ -538,7 +538,7 @@ static int reset_to_path (qse_dir_t* dir, const qse_char_t* path)
{
qse_wchar_t* wptr;
QSE_ASSERT (dir->flags & QSE_DIR_WCSPTH);
QSE_ASSERT (dir->flags & QSE_DIR_WCSPATH);
wptr = make_wcsdos_path (dir, (const qse_wchar_t*)path);
if (wptr == QSE_NULL) return -1;

View File

@ -26,10 +26,10 @@
#include <qse/cmn/nwad.h>
#include <qse/cmn/hton.h>
#include <qse/cmn/nwif.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)

View File

@ -1,767 +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/nwif.h>
#include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h>
#include <qse/io/sio.h>
#include "mem.h"
#if defined(_WIN32)
# include <winsock2.h>
# include <ws2tcpip.h>
/*# include <iphlpapi.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__)
/* TODO: */
#else
# include "syscall.h"
# include <sys/socket.h>
# include <netinet/in.h>
# if defined(HAVE_SYS_IOCTL_H)
# include <sys/ioctl.h>
# endif
# if defined(HAVE_NET_IF_H)
# include <net/if.h>
# endif
# if defined(HAVE_NET_IF_DL_H)
# include <net/if_dl.h>
# endif
# if defined(HAVE_SYS_SOCKIO_H)
# include <sys/sockio.h>
# endif
# if defined(HAVE_IFADDRS_H)
# include <ifaddrs.h>
# endif
# if defined(HAVE_SYS_SYSCTL_H)
# include <sys/sysctl.h>
# endif
# if defined(HAVE_SYS_STROPTS_H)
# include <sys/stropts.h> /* stream options */
# endif
# if defined(HAVE_SYS_MACSTAT_H)
# include <sys/macstat.h>
# endif
# if defined(HAVE_LINUX_ETHTOOL_H)
# include <linux/ethtool.h>
# endif
# if defined(HAVE_LINUX_SOCKIOS_H)
# include <linux/sockios.h>
# endif
#endif
/*
#if defined(HAVE_NET_IF_DL_H)
# include <net/if_dl.h>
#endif
#ifndef SIOCGLIFHWADDR
#define SIOCGLIFHWADDR _IOWR('i', 192, struct lifreq)
#endif
struct lifreq lif;
memset(&lif, 0, sizeof(lif));
strlcpy(lif.lifr_name, ifname, sizeof(lif.lifr_name));
if (ioctl(sock, SIOCGLIFHWADDR, &lif) != -1) {
struct sockaddr_dl *sp;
sp = (struct sockaddr_dl *)&lif.lifr_addr;
memcpy(buf, &sp->sdl_data[0], sp->sdl_alen);
return sp->sdl_alen;
}
*/
#if 0
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && \
defined(HAVE_STRUCT_LIFCONF) && defined(HAVE_STRUCT_LIFREQ)
static int get_nwifs (qse_mmgr_t* mmgr, int s, int f, qse_xptl_t* nwifs)
{
struct lifnum ifn;
struct lifconf ifc;
qse_xptl_t b;
qse_size_t ifcount;
ifcount = 0;
b.ptr = QSE_NULL;
b.len = 0;
do
{
ifn.lifn_family = f;
ifn.lifn_flags = 0;
if (ioctl (s, SIOCGLIFNUM, &ifn) <= -1) goto oops;
if (b.ptr)
{
/* b.ptr won't be QSE_NULL when retrying */
if (ifn.lifn_count <= ifcount) break;
}
/* +1 for extra space to leave empty
* if SIOCGLIFCONF returns the same number of
* intefaces as SIOCLIFNUM */
b.len = (ifn.lifn_count + 1) * QSE_SIZEOF(struct lifreq);
b.ptr = QSE_MMGR_ALLOC (mmgr, b.len);
if (b.ptr == QSE_NULL) goto oops;
ifc.lifc_family = f;
ifc.lifc_flags = 0;
ifc.lifc_len = b.len;
ifc.lifc_buf = b.ptr;
if (ioctl (s, SIOCGLIFCONF, &ifc) <= -1) goto oops;
ifcount = ifc.lifc_len / QSE_SIZEOF(struct lifreq);
}
while (ifcount > ifn.lifn_count);
/* the while condition above is for checking if
* the buffer got full. when it's full, there is a chance
* that there are more interfaces. */
nwifs->ptr = b.ptr;
nwifs->len = ifcount;
return 0;
oops:
if (b.ptr) QSE_MMGR_FREE (mmgr, b.ptr);
return -1;
}
#endif
#endif
#if 0
static void free_nwifcfg (qse_mmgr_t* mmgr, qse_nwifcfg_node_t* cfg)
{
qse_nwifcfg_node_t* cur;
while (cfg)
{
cur = cfg;
cfg = cur->next;
if (cur->name) QSE_MMGR_FREE (mmgr, cur->name);
QSE_MMGR_FREE (mmgr, cur);
}
}
int qse_getnwifcfg (qse_nwifcfg_t* cfg)
{
#if defined(SIOCGLIFCONF)
struct lifreq* ifr, ifrbuf;
qse_size_t i;
int s, f;
int s4 = -1;
int s6 = -1;
qse_xptl_t nwifs = { QSE_NULL, 0 };
qse_nwifcfg_node_t* head = QSE_NULL;
qse_nwifcfg_node_t* tmp;
QSE_ASSERT (cfg->mmgr != QSE_NULL);
#if defined(AF_INET) || defined(AF_INET6)
#if defined(AF_INET)
s4 = socket (AF_INET, SOCK_DGRAM, 0);
if (s4 <= -1) goto oops;
#endif
#if defined(AF_INET6)
s6 = socket (AF_INET6, SOCK_DGRAM, 0);
if (s6 <= -1) goto oops;
#endif
#else
/* no implementation */
goto oops;
#endif
if (get_nwifs (cfg->mmgr, s4, AF_UNSPEC, &nwifs) <= -1) goto oops;
ifr = nwifs.ptr;
for (i = 0; i < nwifs.len; i++, ifr++)
{
f = ifr->lifr_addr.ss_family;
if (f == AF_INET) s = s4;
else if (f == AF_INET6) s = s6;
else continue;
tmp = QSE_MMGR_ALLOC (cfg->mmgr, QSE_SIZEOF(*tmp));
if (tmp == QSE_NULL) goto oops;
QSE_MEMSET (tmp, 0, QSE_SIZEOF(*tmp));
tmp->next = head;
head = tmp;
#if defined(QSE_CHAR_IS_MCHAR)
head->name = qse_mbsdup (ifr->lifr_name, cfg->mmgr);
#else
head->name = qse_mbstowcsdup (ifr->lifr_name, QSE_NULL, cfg->mmgr);
#endif
if (head->name == QSE_NULL) goto oops;
qse_skadtonwad (&ifr->lifr_addr, &head->addr);
qse_mbsxcpy (ifrbuf.lifr_name, QSE_SIZEOF(ifrbuf.lifr_name), ifr->lifr_name);
if (ioctl (s, SIOCGLIFFLAGS, &ifrbuf) <= -1) goto oops;
if (ifrbuf.lifr_flags & IFF_UP) head->flags |= QSE_NWIFCFG_UP;
if (ifrbuf.lifr_flags & IFF_BROADCAST)
{
if (ioctl (s, SIOCGLIFBRDADDR, &ifrbuf) <= -1) goto oops;
qse_skadtonwad (&ifrbuf.lifr_addr, &head->bcast);
head->flags |= QSE_NWIFCFG_BCAST;
}
if (ifrbuf.lifr_flags & IFF_POINTOPOINT)
{
if (ioctl (s, SIOCGLIFDSTADDR, &ifrbuf) <= -1) goto oops;
qse_skadtonwad (&ifrbuf.lifr_addr, &head->ptop);
head->flags |= QSE_NWIFCFG_PTOP;
}
if (ioctl (s, SIOCGLIFINDEX, &ifrbuf) <= -1) goto oops;
head->index = ifrbuf.lifr_index;
if (ioctl (s, SIOCGLIFNETMASK, &ifrbuf) <= -1) goto oops;
qse_skadtonwad (&ifrbuf.lifr_addr, &head->mask);
}
QSE_MMGR_FREE (cfg->mmgr, nwifs.ptr);
close (s6);
close (s4);
cfg->list = head;
return 0;
oops:
if (head) free_nwifcfg (cfg->mmgr, head);
if (nwifs.ptr) QSE_MMGR_FREE (cfg->mmgr, nwifs.ptr);
if (s6 >= 0) close (s6);
if (s4 >= 0) close (s4);
return -1;
#else
/* TODO */
return QSE_NULL;
#endif
}
void qse_freenwifcfg (qse_nwifcfg_t* cfg)
{
free_nwifcfg (cfg->mmgr, cfg->list);
cfg->list = QSE_NULL;
}
#endif
#if defined(__linux)
static void read_proc_net_if_inet6 (qse_nwifcfg_t* cfg, struct ifreq* ifr)
{
/*
*
* # cat /proc/net/if_inet6
* 00000000000000000000000000000001 01 80 10 80 lo
* +------------------------------+ ++ ++ ++ ++ ++
* | | | | | |
* 1 2 3 4 5 6
*
* 1. IPv6 address displayed in 32 hexadecimal chars without colons as separator
* 2. Netlink device number (interface index) in hexadecimal (see “ip addr” , too)
* 3. Prefix length in hexadecimal
* 4. Scope value (see kernel source “ include/net/ipv6.h” and “net/ipv6/addrconf.c” for more)
* 5. Interface flags (see “include/linux/rtnetlink.h” and “net/ipv6/addrconf.c” for more)
* 6. Device name
*/
qse_sio_t* sio;
qse_mchar_t line[128];
qse_mchar_t* ptr, * ptr2;
qse_ssize_t len;
qse_mcstr_t tok[6];
int count, index;
/* TODO */
sio = qse_sio_open (QSE_MMGR_GETDFL(), 0,
QSE_T("/proc/net/if_inet6"), QSE_SIO_IGNOREMBWCERR | QSE_SIO_READ);
if (sio)
{
while (1)
{
len = qse_sio_getmbs (sio, line, QSE_COUNTOF(line));
if (len <= 0) break;
count = 0;
ptr = line;
while (ptr && count < 6)
{
ptr2 = qse_mbsxtok (ptr, len, QSE_MT(" \t"), &tok[count]);
len -= ptr2 - ptr;
ptr = ptr2;
count++;
}
if (count >= 6)
{
index = qse_mbsxtoi (tok[1].ptr, tok[1].len, 16);
if (index == cfg->index)
{
int ti;
if (qse_mbshextobin (tok[0].ptr, tok[0].len, cfg->addr.u.in6.addr.value, QSE_COUNTOF(cfg->addr.u.in6.addr.value)) <= -1) break;
/* tok[3] is the scope type, not the actual scope.
* i leave this code for reference only.
cfg->addr.u.in6.scope = qse_mbsxtoi (tok[3].ptr, tok[3].len, 16); */
cfg->addr.type = QSE_NWAD_IN6;
ti = qse_mbsxtoi (tok[2].ptr, tok[0].len, 16);
qse_prefixtoip6ad (ti, &cfg->mask.u.in6.addr);
cfg->mask.type = QSE_NWAD_IN6;
goto done;
}
}
}
done:
qse_sio_close (sio);
}
}
#endif
static int get_nwifcfg (int s, qse_nwifcfg_t* cfg, struct ifreq* ifr)
{
#if defined(_WIN32)
return -1;
#elif defined(__OS2__)
return -1;
#elif defined(__DOS__)
return -1;
#elif defined(SIOCGLIFADDR) && defined(SIOCGLIFINDEX) && \
defined(HAVE_STRUCT_LIFCONF) && defined(HAVE_STRUCT_LIFREQ)
/* opensolaris */
struct lifreq lifrbuf;
qse_size_t ml, wl;
QSE_MEMSET (&lifrbuf, 0, QSE_SIZEOF(lifrbuf));
qse_mbsxcpy (lifrbuf.lifr_name, QSE_SIZEOF(lifrbuf.lifr_name), ifr->ifr_name);
if (ioctl (s, SIOCGLIFINDEX, &lifrbuf) <= -1) return -1;
cfg->index = lifrbuf.lifr_index;
if (ioctl (s, SIOCGLIFFLAGS, &lifrbuf) <= -1) return -1;
cfg->flags = 0;
if (lifrbuf.lifr_flags & IFF_UP) cfg->flags |= QSE_NWIFCFG_UP;
if (lifrbuf.lifr_flags & IFF_RUNNING) cfg->flags |= QSE_NWIFCFG_RUNNING;
if (lifrbuf.lifr_flags & IFF_BROADCAST) cfg->flags |= QSE_NWIFCFG_BCAST;
if (lifrbuf.lifr_flags & IFF_POINTOPOINT) cfg->flags |= QSE_NWIFCFG_PTOP;
if (ioctl (s, SIOCGLIFMTU, &lifrbuf) <= -1) return -1;
cfg->mtu = lifrbuf.lifr_mtu;
qse_clearnwad (&cfg->addr, QSE_NWAD_NX);
qse_clearnwad (&cfg->mask, QSE_NWAD_NX);
qse_clearnwad (&cfg->bcast, QSE_NWAD_NX);
qse_clearnwad (&cfg->ptop, QSE_NWAD_NX);
QSE_MEMSET (cfg->ethw, 0, QSE_SIZEOF(cfg->ethw));
if (ioctl (s, SIOCGLIFADDR, &lifrbuf) >= 0)
qse_skadtonwad (&lifrbuf.lifr_addr, &cfg->addr);
if (ioctl (s, SIOCGLIFNETMASK, &lifrbuf) >= 0)
qse_skadtonwad (&lifrbuf.lifr_addr, &cfg->mask);
if ((cfg->flags & QSE_NWIFCFG_BCAST) &&
ioctl (s, SIOCGLIFBRDADDR, &lifrbuf) >= 0)
{
qse_skadtonwad (&lifrbuf.lifr_broadaddr, &cfg->bcast);
}
if ((cfg->flags & QSE_NWIFCFG_PTOP) &&
ioctl (s, SIOCGLIFDSTADDR, &lifrbuf) >= 0)
{
qse_skadtonwad (&lifrbuf.lifr_dstaddr, &cfg->ptop);
}
#if defined(SIOCGENADDR)
{
if (ioctl (s, SIOCGENADDR, ifr) >= 0 &&
QSE_SIZEOF(ifr->ifr_enaddr) >= QSE_SIZEOF(cfg->ethw))
{
QSE_MEMCPY (cfg->ethw, ifr->ifr_enaddr, QSE_SIZEOF(cfg->ethw));
}
/* TODO: try DLPI if SIOCGENADDR fails... */
}
#endif
return 0;
#elif defined(SIOCGLIFADDR) && defined(HAVE_STRUCT_IF_LADDRREQ) && !defined(SIOCGLIFINDEX)
/* freebsd */
qse_size_t ml, wl;
#if defined(SIOCGIFINDEX)
if (ioctl (s, SIOCGIFINDEX, ifr) <= -1) return -1;
#if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX)
cfg->index = ifr->ifr_ifindex;
#else
cfg->index = ifr->ifr_index;
#endif
#else
cfg->index = 0;
#endif
if (ioctl (s, SIOCGIFFLAGS, ifr) <= -1) return -1;
cfg->flags = 0;
if (ifr->ifr_flags & IFF_UP) cfg->flags |= QSE_NWIFCFG_UP;
if (ifr->ifr_flags & IFF_RUNNING) cfg->flags |= QSE_NWIFCFG_RUNNING;
if (ifr->ifr_flags & IFF_BROADCAST) cfg->flags |= QSE_NWIFCFG_BCAST;
if (ifr->ifr_flags & IFF_POINTOPOINT) cfg->flags |= QSE_NWIFCFG_PTOP;
if (ioctl (s, SIOCGIFMTU, ifr) <= -1) return -1;
#if defined(HAVE_STRUCT_IFREQ_IFR_MTU)
cfg->mtu = ifr->ifr_mtu;
#else
/* well, this is a bit dirty. but since all these are unions,
* the name must not really matter. some OSes just omitts defining
* the MTU field */
cfg->mtu = ifr->ifr_metric;
#endif
qse_clearnwad (&cfg->addr, QSE_NWAD_NX);
qse_clearnwad (&cfg->mask, QSE_NWAD_NX);
qse_clearnwad (&cfg->bcast, QSE_NWAD_NX);
qse_clearnwad (&cfg->ptop, QSE_NWAD_NX);
QSE_MEMSET (cfg->ethw, 0, QSE_SIZEOF(cfg->ethw));
if (cfg->type == QSE_NWIFCFG_IN6)
{
struct if_laddrreq iflrbuf;
QSE_MEMSET (&iflrbuf, 0, QSE_SIZEOF(iflrbuf));
qse_mbsxcpy (iflrbuf.iflr_name, QSE_SIZEOF(iflrbuf.iflr_name), ifr->ifr_name);
if (ioctl (s, SIOCGLIFADDR, &iflrbuf) >= 0)
{
qse_skadtonwad (&iflrbuf.addr, &cfg->addr);
cfg->mask.type = QSE_NWAD_IN6;
qse_prefixtoip6ad (iflrbuf.prefixlen, &cfg->mask.u.in6.addr);
if (cfg->flags & QSE_NWIFCFG_PTOP)
qse_skadtonwad (&iflrbuf.dstaddr, &cfg->ptop);
}
}
else
{
if (ioctl (s, SIOCGIFADDR, ifr) >= 0)
qse_skadtonwad (&ifr->ifr_addr, &cfg->addr);
if (ioctl (s, SIOCGIFNETMASK, ifr) >= 0)
qse_skadtonwad (&ifr->ifr_addr, &cfg->mask);
if ((cfg->flags & QSE_NWIFCFG_BCAST) &&
ioctl (s, SIOCGIFBRDADDR, ifr) >= 0)
{
qse_skadtonwad (&ifr->ifr_broadaddr, &cfg->bcast);
}
if ((cfg->flags & QSE_NWIFCFG_PTOP) &&
ioctl (s, SIOCGIFDSTADDR, ifr) >= 0)
{
qse_skadtonwad (&ifr->ifr_dstaddr, &cfg->ptop);
}
}
#if defined(CTL_NET) && defined(AF_ROUTE) && defined(AF_LINK)
{
int mib[6];
size_t len;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
mib[5] = cfg->index;
if (sysctl (mib, QSE_COUNTOF(mib), QSE_NULL, &len, QSE_NULL, 0) >= 0)
{
qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
void* buf;
buf = QSE_MMGR_ALLOC (mmgr, len);
if (buf)
{
if (sysctl (mib, QSE_COUNTOF(mib), buf, &len, QSE_NULL, 0) >= 0)
{
struct sockaddr_dl* sadl;
sadl = ((struct if_msghdr*)buf + 1);
/* i don't really care if it's really ethernet
* so long as the data is long enough */
if (sadl->sdl_alen >= QSE_COUNTOF(cfg->ethw))
QSE_MEMCPY (cfg->ethw, LLADDR(sadl), QSE_SIZEOF(cfg->ethw));
}
QSE_MMGR_FREE (mmgr, buf);
}
}
}
#endif
return 0;
#elif defined(SIOCGIFADDR)
#if defined(SIOCGIFINDEX)
if (ioctl (s, SIOCGIFINDEX, ifr) <= -1) return -1;
#if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX)
cfg->index = ifr->ifr_ifindex;
#else
cfg->index = ifr->ifr_index;
#endif
#else
cfg->index = 0;
#endif
if (ioctl (s, SIOCGIFFLAGS, ifr) <= -1) return -1;
cfg->flags = 0;
if (ifr->ifr_flags & IFF_UP) cfg->flags |= QSE_NWIFCFG_UP;
if (ifr->ifr_flags & IFF_RUNNING) cfg->flags |= QSE_NWIFCFG_RUNNING;
if (ifr->ifr_flags & IFF_BROADCAST) cfg->flags |= QSE_NWIFCFG_BCAST;
if (ifr->ifr_flags & IFF_POINTOPOINT) cfg->flags |= QSE_NWIFCFG_PTOP;
if (ioctl (s, SIOCGIFMTU, ifr) <= -1) return -1;
#if defined(HAVE_STRUCT_IFREQ_IFR_MTU)
cfg->mtu = ifr->ifr_mtu;
#else
/* well, this is a bit dirty. but since all these are unions,
* the name must not really matter. SCO just omits defining
* the MTU field, and uses ifr_metric instead */
cfg->mtu = ifr->ifr_metric;
#endif
qse_clearnwad (&cfg->addr, QSE_NWAD_NX);
qse_clearnwad (&cfg->mask, QSE_NWAD_NX);
qse_clearnwad (&cfg->bcast, QSE_NWAD_NX);
qse_clearnwad (&cfg->ptop, QSE_NWAD_NX);
QSE_MEMSET (cfg->ethw, 0, QSE_SIZEOF(cfg->ethw));
if (ioctl (s, SIOCGIFADDR, ifr) >= 0)
qse_skadtonwad (&ifr->ifr_addr, &cfg->addr);
if (ioctl (s, SIOCGIFNETMASK, ifr) >= 0)
qse_skadtonwad (&ifr->ifr_addr, &cfg->mask);
#if defined(__linux)
if (cfg->addr.type == QSE_NWAD_NX && cfg->mask.type == QSE_NWAD_NX && cfg->type == QSE_NWIFCFG_IN6)
{
/* access /proc/net/if_inet6 */
read_proc_net_if_inet6 (cfg, ifr);
}
#endif
if ((cfg->flags & QSE_NWIFCFG_BCAST) &&
ioctl (s, SIOCGIFBRDADDR, ifr) >= 0)
{
qse_skadtonwad (&ifr->ifr_broadaddr, &cfg->bcast);
}
if ((cfg->flags & QSE_NWIFCFG_PTOP) &&
ioctl (s, SIOCGIFDSTADDR, ifr) >= 0)
{
qse_skadtonwad (&ifr->ifr_dstaddr, &cfg->ptop);
}
#if defined(SIOCGIFHWADDR)
if (ioctl (s, SIOCGIFHWADDR, ifr) >= 0)
{
QSE_MEMCPY (cfg->ethw, ifr->ifr_hwaddr.sa_data, QSE_SIZEOF(cfg->ethw));
}
#elif defined(MACIOC_GETADDR)
{
/* sco openserver
* use the streams interface to get the hardware address.
*/
int strfd;
/*qse_mchar_t devname[QSE_COUNTOF(ifr->ifr_name) + 5 + 1] = QSE_MT("/dev/");*/
qse_mchar_t devname[QSE_COUNTOF(ifr->ifr_name) + 5 + 1];
qse_mbscpy (devname, QSE_MT("/dev/"));
qse_mbscpy (&devname[5], ifr->ifr_name);
if ((strfd = QSE_OPEN (devname, O_RDONLY, 0)) >= 0)
{
qse_uint8_t buf[QSE_SIZEOF(cfg->ethw)];
struct strioctl strioc;
strioc.ic_cmd = MACIOC_GETADDR;
strioc.ic_timout = -1;
strioc.ic_len = QSE_SIZEOF (buf);
strioc.ic_dp = buf;
if (ioctl (strfd, I_STR, (char *) &strioc) >= 0)
QSE_MEMCPY (cfg->ethw, buf, QSE_SIZEOF(cfg->ethw));
QSE_CLOSE (strfd);
}
}
#endif
return 0;
#else
/* TODO */
return -1;
#endif
}
static void get_moreinfo (int s, qse_nwifcfg_t* cfg, struct ifreq* ifr)
{
#if defined(ETHTOOL_GLINK)
{
/* get link status */
struct ethtool_value ev;
QSE_MEMSET (&ev, 0, QSE_SIZEOF(ev));
ev.cmd= ETHTOOL_GLINK;
ifr->ifr_data = &ev;
if (ioctl (s, SIOCETHTOOL,ifr) >= 0)
cfg->flags |= ev.data? QSE_NWIFCFG_LINKUP: QSE_NWIFCFG_LINKDOWN;
}
#endif
#if 0
#if defined(ETHTOOL_GSTATS)
{
/* get link statistics */
struct ethtool_drvinfo drvinfo;
drvinfo.cmd = ETHTOOL_GDRVINFO;
ifr->ifr_data = &drvinfo;
if (ioctl (s, SIOCETHTOOL, ifr) >= 0)
{
struct ethtool_stats *stats;
qse_uint8_t buf[1000]; /* TODO: make this dynamic according to drvinfo.n_stats */
stats = buf;
stats->cmd = ETHTOOL_GSTATS;
stats->n_stats = drvinfo.n_stats * QSE_SIZEOF(stats->data[0]);
ifr->ifr_data = (caddr_t) stats;
if (ioctl (s, SIOCETHTOOL, ifr) >= 0)
{
for (i = 0; i < drvinfo.n_stats; i++)
{
qse_printf (QSE_T(">>> %llu \n"), stats->data[i]);
}
}
}
}
#endif
#endif
}
/* TOOD: consider how to handle multiple IPv6 addresses on a single interfce.
* consider how to get IPv4 addresses on an aliased interface? so mutliple ipv4 addresses */
int qse_getnwifcfg (qse_nwifcfg_t* cfg)
{
#if defined(_WIN32)
/* TODO */
return -1;
#elif defined(__OS2__)
/* TODO */
return -1;
#elif defined(__DOS__)
/* TODO */
return -1;
#else
int x = -1, s = -1;
struct ifreq ifr;
qse_size_t ml, wl;
if (cfg->type == QSE_NWIFCFG_IN4)
{
#if defined(AF_INET)
s = socket (AF_INET, SOCK_DGRAM, 0);
#endif
}
else if (cfg->type == QSE_NWIFCFG_IN6)
{
#if defined(AF_INET6)
s = socket (AF_INET6, SOCK_DGRAM, 0);
#endif
}
if (s <= -1) return -1;
if (cfg->name[0] == QSE_T('\0')&& cfg->index >= 1)
{
/* TODO: support lookup by ifindex */
}
QSE_MEMSET (&ifr, 0, sizeof(ifr));
#if defined(QSE_CHAR_IS_MCHAR)
qse_mbsxcpy (ifr.ifr_name, QSE_SIZEOF(ifr.ifr_name), cfg->name);
#else
ml = QSE_COUNTOF(ifr.ifr_name);
if (qse_wcstombs (cfg->name, &wl, ifr.ifr_name, &ml) <= -1) goto oops;
#endif
x = get_nwifcfg (s, cfg, &ifr);
if (x >= 0) get_moreinfo (s, cfg, &ifr);
oops:
QSE_CLOSE (s);
return x;
#endif
}

View File

@ -1,559 +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/nwif.h>
#include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h>
#include "mem.h"
#if defined(_WIN32)
/* TODO: */
#elif defined(__OS2__)
/* TODO: */
#elif defined(__DOS__)
/* TODO: */
#else
# include "syscall.h"
# include <sys/socket.h>
# if defined(HAVE_SYS_IOCTL_H)
# include <sys/ioctl.h>
# endif
# if defined(HAVE_NET_IF_H)
# include <net/if.h>
# endif
# if defined(HAVE_SYS_SOCKIO_H)
# include <sys/sockio.h>
# endif
# if !defined(IF_NAMESIZE)
# define IF_NAMESIZE 63
# endif
#endif
#if defined(_SCO_DS)
static int get_sco_ifconf (struct ifconf* ifc)
{
/* SCO doesn't have have any IFINDEX thing.
* i emultate it using IFCONF */
int h, num;
struct ifreq* ifr;
h = socket (AF_INET, SOCK_DGRAM, 0);
if (h <= -1) return -1;
ifc->ifc_len = 0;
ifc->ifc_buf = QSE_NULL;
#if defined(SIOCGIFANUM)
if (ioctl (h, SIOCGIFANUM, &num) <= -1) goto oops;
#else
if (ioctl (h, SIOCGIFNUM, &num) <= -1) goto oops;
#endif
/* sco needs reboot when you add an network interface.
* it should be safe not to consider the case when the interface
* is added after SIOCGIFANUM above.
* another thing to note is that SIOCGIFCONF ends with segfault
* if the buffer is not large enough unlike some other OSes
* like opensolaris which truncates the configuration. */
ifc->ifc_len = num * QSE_SIZEOF(*ifr);
ifc->ifc_buf = QSE_MMGR_ALLOC (QSE_MMGR_GETDFL(), ifc->ifc_len);
if (ifc->ifc_buf == QSE_NULL) goto oops;
if (ioctl (h, SIOCGIFCONF, ifc) <= -1) goto oops;
QSE_CLOSE (h); h = -1;
return 0;
oops:
if (ifc->ifc_buf) QSE_MMGR_FREE (QSE_MMGR_GETDFL(), ifc->ifc_buf);
if (h >= 0) QSE_CLOSE (h);
return -1;
}
static QSE_INLINE void free_sco_ifconf (struct ifconf* ifc)
{
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), ifc->ifc_buf);
}
#endif
int qse_nwifmbstoindex (const qse_mchar_t* ptr, unsigned int* index)
{
#if defined(_WIN32)
/* TODO: */
return -1;
#elif defined(__OS2__)
/* TODO: */
return -1;
#elif defined(__DOS__)
/* TODO: */
return -1;
#elif defined(SIOCGIFINDEX)
int h, x;
qse_size_t len;
struct ifreq ifr;
h = socket (AF_INET, SOCK_DGRAM, 0);
if (h <= -1) return -1;
QSE_MEMSET (&ifr, 0, QSE_SIZEOF(ifr));
len = qse_mbsxcpy (ifr.ifr_name, QSE_COUNTOF(ifr.ifr_name), ptr);
if (ptr[len] != QSE_MT('\0')) return -1; /* name too long */
x = ioctl (h, SIOCGIFINDEX, &ifr);
QSE_CLOSE (h);
if (x >= 0)
{
#if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX)
*index = ifr.ifr_ifindex;
#else
*index = ifr.ifr_index;
#endif
}
return x;
#elif defined(HAVE_IF_NAMETOINDEX)
qse_mchar_t tmp[IF_NAMESIZE + 1];
qse_size_t len;
unsigned int tmpidx;
len = qse_mbsxcpy (tmp, QSE_COUNTOF(tmp), ptr);
if (ptr[len] != QSE_MT('\0')) return -1; /* name too long */
tmpidx = if_nametoindex (tmp);
if (tmpidx == 0) return -1;
*index = tmpidx;
return 0;
#elif defined(_SCO_DS)
struct ifconf ifc;
int num, i;
if (get_sco_ifconf (&ifc) <= -1) return -1;
num = ifc.ifc_len / QSE_SIZEOF(struct ifreq);
for (i = 0; i < num; i++)
{
if (qse_mbscmp (ptr, ifc.ifc_req[i].ifr_name) == 0)
{
free_sco_ifconf (&ifc);
*index = i + 1;
return 0;
}
}
free_sco_ifconf (&ifc);
return -1;
#else
return -1;
#endif
}
int qse_nwifmbsntoindex (const qse_mchar_t* ptr, qse_size_t len, unsigned int* index)
{
#if defined(_WIN32)
/* TODO: */
return -1;
#elif defined(__OS2__)
/* TODO: */
return -1;
#elif defined(__DOS__)
/* TODO: */
return -1;
#elif defined(SIOCGIFINDEX)
int h, x;
struct ifreq ifr;
h = socket (AF_INET, SOCK_DGRAM, 0);
if (h <= -1) return -1;
QSE_MEMSET (&ifr, 0, QSE_SIZEOF(ifr));
if (qse_mbsxncpy (ifr.ifr_name, QSE_COUNTOF(ifr.ifr_name), ptr, len) < len) return -1; /* name too long */
x = ioctl (h, SIOCGIFINDEX, &ifr);
QSE_CLOSE (h);
if (x >= 0)
{
#if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX)
*index = ifr.ifr_ifindex;
#else
*index = ifr.ifr_index;
#endif
}
return x;
#elif defined(HAVE_IF_NAMETOINDEX)
qse_mchar_t tmp[IF_NAMESIZE + 1];
unsigned int tmpidx;
if (qse_mbsxncpy (tmp, QSE_COUNTOF(tmp), ptr, len) < len) return -1;
tmpidx = if_nametoindex (tmp);
if (tmpidx == 0) return -1;
*index = tmpidx;
return 0;
#elif defined(_SCO_DS)
struct ifconf ifc;
int num, i;
if (get_sco_ifconf (&ifc) <= -1) return -1;
num = ifc.ifc_len / QSE_SIZEOF(struct ifreq);
for (i = 0; i < num; i++)
{
if (qse_mbsxcmp (ptr, len, ifc.ifc_req[i].ifr_name) == 0)
{
free_sco_ifconf (&ifc);
*index = i + 1;
return 0;
}
}
free_sco_ifconf (&ifc);
return -1;
#else
return -1;
#endif
}
int qse_nwifwcstoindex (const qse_wchar_t* ptr, unsigned int* index)
{
#if defined(_WIN32)
/* TODO: */
return -1;
#elif defined(__OS2__)
/* TODO: */
return -1;
#elif defined(__DOS__)
/* TODO: */
return -1;
#elif defined(SIOCGIFINDEX)
int h, x;
struct ifreq ifr;
qse_size_t wl, ml;
h = socket (AF_INET, SOCK_DGRAM, 0);
if (h <= -1) return -1;
ml = QSE_COUNTOF(ifr.ifr_name);
if (qse_wcstombs (ptr, &wl, ifr.ifr_name, &ml) <= -1) return -1;
x = ioctl (h, SIOCGIFINDEX, &ifr);
QSE_CLOSE (h);
if (x >= 0)
{
#if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX)
*index = ifr.ifr_ifindex;
#else
*index = ifr.ifr_index;
#endif
}
return x;
#elif defined(HAVE_IF_NAMETOINDEX)
qse_mchar_t tmp[IF_NAMESIZE + 1];
qse_size_t wl, ml;
unsigned int tmpidx;
ml = QSE_COUNTOF(tmp);
if (qse_wcstombs (ptr, &wl, tmp, &ml) <= -1) return -1;
tmpidx = if_nametoindex (tmp);
if (tmpidx == 0) return -1;
*index = tmpidx;
return 0;
#elif defined(SIOCGIFCONF) && (defined(SIOCGIFANUM) || defined(SIOCGIFNUM))
struct ifconf ifc;
int num, i;
qse_mchar_t tmp[IF_NAMESIZE + 1];
qse_size_t wl, ml;
ml = QSE_COUNTOF(tmp);
if (qse_wcstombs (ptr, &wl, tmp, &ml) <= -1) return -1;
if (get_sco_ifconf (&ifc) <= -1) return -1;
num = ifc.ifc_len / QSE_SIZEOF(struct ifreq);
for (i = 0; i < num; i++)
{
if (qse_mbscmp (tmp, ifc.ifc_req[i].ifr_name) == 0)
{
free_sco_ifconf (&ifc);
*index = i + 1;
return 0;
}
}
free_sco_ifconf (&ifc);
return -1;
#else
return -1;
#endif
}
int qse_nwifwcsntoindex (const qse_wchar_t* ptr, qse_size_t len, unsigned int* index)
{
#if defined(_WIN32)
/* TODO: */
return -1;
#elif defined(__OS2__)
/* TODO: */
return -1;
#elif defined(__DOS__)
/* TODO: */
return -1;
#elif defined(SIOCGIFINDEX)
int h, x;
struct ifreq ifr;
qse_size_t wl, ml;
h = socket (AF_INET, SOCK_DGRAM, 0);
if (h <= -1) return -1;
wl = len; ml = QSE_COUNTOF(ifr.ifr_name) - 1;
if (qse_wcsntombsn (ptr, &wl, ifr.ifr_name, &ml) <= -1) return -1;
ifr.ifr_name[ml] = QSE_MT('\0');
x = ioctl (h, SIOCGIFINDEX, &ifr);
QSE_CLOSE (h);
if (x >= 0)
{
#if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX)
*index = ifr.ifr_ifindex;
#else
*index = ifr.ifr_index;
#endif
}
return x;
#elif defined(HAVE_IF_NAMETOINDEX)
qse_mchar_t tmp[IF_NAMESIZE + 1];
qse_size_t wl, ml;
unsigned int tmpidx;
wl = len; ml = QSE_COUNTOF(tmp) - 1;
if (qse_wcsntombsn (ptr, &wl, tmp, &ml) <= -1) return -1;
tmp[ml] = QSE_MT('\0');
tmpidx = if_nametoindex (tmp);
if (tmpidx == 0) return -1;
*index = tmpidx;
return 0;
#elif defined(SIOCGIFCONF) && (defined(SIOCGIFANUM) || defined(SIOCGIFNUM))
struct ifconf ifc;
int num, i;
qse_mchar_t tmp[IF_NAMESIZE + 1];
qse_size_t wl, ml;
wl = len; ml = QSE_COUNTOF(tmp) - 1;
if (qse_wcsntombsn (ptr, &wl, tmp, &ml) <= -1) return -1;
tmp[ml] = QSE_MT('\0');
if (get_sco_ifconf (&ifc) <= -1) return -1;
num = ifc.ifc_len / QSE_SIZEOF(struct ifreq);
for (i = 0; i < num; i++)
{
if (qse_mbscmp (tmp, ifc.ifc_req[i].ifr_name) == 0)
{
free_sco_ifconf (&ifc);
*index = i + 1;
return 0;
}
}
free_sco_ifconf (&ifc);
return -1;
#else
return -1;
#endif
}
/* ---------------------------------------------------------- */
int qse_nwifindextombs (unsigned int index, qse_mchar_t* buf, qse_size_t len)
{
#if defined(_WIN32)
/* TODO: */
return -1;
#elif defined(__OS2__)
/* TODO: */
return -1;
#elif defined(__DOS__)
/* TODO: */
return -1;
#elif defined(SIOCGIFNAME)
int h, x;
struct ifreq ifr;
h = socket (AF_INET, SOCK_DGRAM, 0);
if (h <= -1) return -1;
QSE_MEMSET (&ifr, 0, QSE_SIZEOF(ifr));
#if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX)
ifr.ifr_ifindex = index;
#else
ifr.ifr_index = index;
#endif
x = ioctl (h, SIOCGIFNAME, &ifr);
QSE_CLOSE (h);
return (x <= -1)? -1: qse_mbsxcpy (buf, len, ifr.ifr_name);
#elif defined(HAVE_IF_INDEXTONAME)
qse_mchar_t tmp[IF_NAMESIZE + 1];
if (if_indextoname (index, tmp) == QSE_NULL) return -1;
return qse_mbsxcpy (buf, len, tmp);
#elif defined(SIOCGIFCONF) && (defined(SIOCGIFANUM) || defined(SIOCGIFNUM))
struct ifconf ifc;
qse_size_t ml;
int num;
if (index <= 0) return -1;
if (get_sco_ifconf (&ifc) <= -1) return -1;
num = ifc.ifc_len / QSE_SIZEOF(struct ifreq);
if (index > num)
{
free_sco_ifconf (&ifc);
return -1;
}
ml = qse_mbsxcpy (buf, len, ifc.ifc_req[index - 1].ifr_name);
free_sco_ifconf (&ifc);
return ml;
#else
return -1;
#endif
}
int qse_nwifindextowcs (unsigned int index, qse_wchar_t* buf, qse_size_t len)
{
#if defined(_WIN32)
/* TODO: */
return -1;
#elif defined(__OS2__)
/* TODO: */
return -1;
#elif defined(__DOS__)
/* TODO: */
return -1;
#elif defined(SIOCGIFNAME)
int h, x;
struct ifreq ifr;
qse_size_t wl, ml;
h = socket (AF_INET, SOCK_DGRAM, 0);
if (h <= -1) return -1;
QSE_MEMSET (&ifr, 0, QSE_SIZEOF(ifr));
#if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX)
ifr.ifr_ifindex = index;
#else
ifr.ifr_index = index;
#endif
x = ioctl (h, SIOCGIFNAME, &ifr);
QSE_CLOSE (h);
if (x <= -1) return -1;
wl = len;
x = qse_mbstowcs (ifr.ifr_name, &ml, buf, &wl);
if (x == -2 && wl > 1) buf[wl - 1] = QSE_WT('\0');
else if (x != 0) return -1;
return wl;
#elif defined(HAVE_IF_INDEXTONAME)
qse_mchar_t tmp[IF_NAMESIZE + 1];
qse_size_t ml, wl;
int x;
if (if_indextoname (index, tmp) == QSE_NULL) return -1;
wl = len;
x = qse_mbstowcs (tmp, &ml, buf, &wl);
if (x == -2 && wl > 1) buf[wl - 1] = QSE_WT('\0');
else if (x != 0) return -1;
return wl;
#elif defined(SIOCGIFCONF) && (defined(SIOCGIFANUM) || defined(SIOCGIFNUM))
struct ifconf ifc;
qse_size_t wl, ml;
int num, x;
if (index <= 0) return -1;
if (get_sco_ifconf (&ifc) <= -1) return -1;
num = ifc.ifc_len / QSE_SIZEOF(struct ifreq);
if (index > num)
{
free_sco_ifconf (&ifc);
return -1;
}
wl = len;
x = qse_mbstowcs (ifc.ifc_req[index - 1].ifr_name, &ml, buf, &wl);
free_sco_ifconf (&ifc);
if (x == -2 && wl > 1) buf[wl - 1] = QSE_WT('\0');
else if (x != 0) return -1;
return wl;
#else
return -1;
#endif
}