未验证 提交 7fd425ba 编写于 作者: O openharmony_ci 提交者: Gitee

!184 Fix : musl库net模块中新增API

Merge pull request !184 from yinjiaming/yjm-musl-net-20211125
#include <netdb.h> #define _BSD_SOURCE
#include <unsupported_api.h> #include<netdb.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<arpa/inet.h>
#include<errno.h>
void sethostent(int x) #define HOST_FILE_PATH "/etc/hosts"
#define NET_FILE_PATH "/etc/networks"
#define BUFFER_SIZE 200
#define INET_ADDR_LEN 4
#define INET6_ADDR_LEN 16
#define MAX_ALIAS_NO 10
#define MAX_ADDR_NO 10
#define MAX_NAME_LEN 20
#define MAX_ALIAS_LEN 20
struct hostdata {
FILE *hostf;
int stayopen;
struct hostent he;
char buf[BUFFER_SIZE];
char *addr[MAX_ADDR_NO + 1];
char addr_list[MAX_ADDR_NO + 1][INET6_ADDR_LEN + 1];
char *aliases[MAX_ALIAS_NO + 1];
};
struct netdata {
FILE *netf;
int stayopen;
struct netent ne;
char buf[BUFFER_SIZE];
char *aliases[MAX_ALIAS_NO + 1];
};
static struct hostdata *hd = NULL;
static struct netdata *nd = NULL;
static int gethostent_resolv()
{ {
unsupported_api(__FUNCTION__); char *ch, *ptr = NULL;
if (hd->buf[0] == '#')
return -1;
ch = strchr(hd->buf, '#');
if (ch)
*ch = '\0';
ch = strtok_r(hd->buf, " \t\n", &ptr);
if (!ch)
return -1;
if (inet_pton(AF_INET, ch, hd->addr_list[0]) == 1) {
hd->he.h_addrtype = AF_INET;
hd->he.h_length = INET_ADDR_LEN;
hd->addr_list[0][INET_ADDR_LEN] = '\0';
} else if (inet_pton(AF_INET6, ch, hd->addr_list[0]) == 1) {
hd->he.h_addrtype = AF_INET6;
hd->he.h_length = INET6_ADDR_LEN;
hd->addr_list[0][INET6_ADDR_LEN] = '\0';
} else {
return -1;
}
hd->addr[0] = hd->addr_list[0];
hd->addr[1] = NULL;
hd->he.h_addr_list = hd->addr;
ch = strtok_r(NULL, " \t\n", &ptr);
if (!ch)
return -1;
hd->he.h_name = ch;
int i = 0;
while (i < MAX_ALIAS_NO) {
ch = strtok_r(NULL, " \t\n", &ptr);
hd->aliases[i++] = ch;
}
hd->aliases[MAX_ALIAS_NO] = NULL;
hd->he.h_aliases = hd->aliases;
return 0;
} }
struct hostent *gethostent() struct hostent *gethostent(void)
{ {
unsupported_api(__FUNCTION__); if (hd == NULL) {
return 0; if ((hd = malloc(sizeof(struct hostdata))) == NULL) {
h_errno = NO_RECOVERY;
return NULL;
}
hd->hostf = NULL;
hd->stayopen = 0;
}
if (!hd->hostf && !(hd->hostf = fopen(HOST_FILE_PATH, "r"))) {
h_errno = NO_RECOVERY;
free(hd);
hd =NULL;
return NULL;
}
do {
if (!fgets(hd->buf, BUFFER_SIZE, hd->hostf)) {
h_errno = HOST_NOT_FOUND;
return NULL;
}
} while (gethostent_resolv());
return &(hd->he);
} }
struct netent *getnetent() void sethostent(int stayopen)
{ {
unsupported_api(__FUNCTION__); if (hd == NULL) {
return 0; if ((hd = malloc(sizeof(struct hostdata))) == NULL) {
h_errno = NO_RECOVERY;
return;
}
hd->hostf = NULL;
}
if (hd->hostf == NULL)
hd->hostf = fopen(NET_FILE_PATH, "r");
else
rewind(hd->hostf);
hd->stayopen = stayopen;
} }
void endhostent(void) void endhostent(void)
{ {
unsupported_api(__FUNCTION__); if (hd == NULL)
return;
if (hd->stayopen == 0) {
if (hd->hostf != NULL)
fclose(hd->hostf);
free(hd);
hd = NULL;
}
} }
weak_alias(sethostent, setnetent); static int getnetent_resolv()
weak_alias(endhostent, endnetent); {
if (nd->buf[0] == '#')
return -1;
char *ch, *ptr = NULL;
ch = strchr(nd->buf, '#');
if (ch)
*ch = '\0';
ch = strtok_r(nd->buf, " \t\n", &ptr);
if (!ch)
return -1;
nd->ne.n_name = ch;
nd->ne.n_addrtype = AF_INET;
ch = strtok_r(NULL, " \t\n", &ptr);
if (!ch)
return -1;
nd->ne.n_net = inet_network(ch);
int i = 0;
while ((ch = strtok_r(NULL, " \t\n", &ptr)) != NULL && i < MAX_ALIAS_NO) {
nd->aliases[i++] = ch;
}
nd->aliases[i] = NULL;
nd->ne.n_aliases = nd->aliases;
return 0;
}
struct netent *getnetent(void)
{
if (nd == NULL) {
if ((nd = malloc(sizeof(struct netdata))) == NULL) {
errno = ENOMEM;
return NULL;
}
nd->netf = NULL;
nd->stayopen = 0;
}
if (nd->netf == NULL && (nd->netf = fopen(NET_FILE_PATH, "r")) == NULL) {
errno = ENOENT;
free(nd);
nd = NULL;
return NULL;
}
while (1) {
if (fgets(nd->buf, BUFFER_SIZE, nd->netf) == NULL)
break;
if (getnetent_resolv() == 0)
return &(nd->ne);
}
return NULL;
}
void setnetent(int stayopen)
{
if (nd == NULL) {
if ((nd = malloc(sizeof(struct netdata))) == NULL) {
errno = ENOMEM;
return;
}
nd->netf = NULL;
}
if (nd->netf == NULL)
nd->netf = fopen(NET_FILE_PATH, "r");
else
rewind(nd->netf);
nd->stayopen = stayopen;
}
void endnetent(void)
{
if (nd == NULL)
return;
if (!nd->stayopen) {
if (nd->netf != NULL)
fclose(nd->netf);
free(nd);
nd = NULL;
}
}
\ No newline at end of file
#include <stdlib.h> #include <stdlib.h>
#include <netinet/ether.h> #include <netinet/ether.h>
#include <stdio.h> #include <stdio.h>
#include <unsupported_api.h> #include <string.h>
#include <errno.h>
#define ETHER_FILE_PATH "/etc/ethers"
#define BUFFER_SIZE 200
struct ether_addr *ether_aton_r (const char *x, struct ether_addr *p_a) struct ether_addr *ether_aton_r (const char *x, struct ether_addr *p_a)
{ {
...@@ -43,20 +47,97 @@ char *ether_ntoa (const struct ether_addr *p_a) { ...@@ -43,20 +47,97 @@ char *ether_ntoa (const struct ether_addr *p_a) {
return ether_ntoa_r (p_a, x); return ether_ntoa_r (p_a, x);
} }
int ether_line(const char *l, struct ether_addr *e, char *hostname) int ether_line(const char *line, struct ether_addr *addr, char *hostname)
{ {
unsupported_api(__FUNCTION__); char buf[BUFFER_SIZE], *ch, *ptr = NULL;
return -1; if (line[0] == '#') {
errno = EINVAL;
return -1;
}
strcpy(buf, line);
ch = strchr(buf, '#');
if (ch)
*ch = '\0';
ch = strtok_r(buf, " \t\n", &ptr);
ch = strtok_r(NULL, " \t\n", &ptr);
if (ch == NULL) {
errno = EINVAL;
return -1;
}
strcpy(hostname, ch);
unsigned int ret;
ch = &buf[0];
for (int i = 0; i < 6; i++) {
ch = strtok_r(ch, ":", &ptr);
if (ch == NULL || sscanf(ch, "%x", &ret) != 1) {
errno = EINVAL;
return -1;
}
addr->ether_addr_octet[i] = (uint8_t)ret;
ch = NULL;
}
return 0;
} }
int ether_ntohost(char *hostname, const struct ether_addr *e) int ether_ntohost(char *hostname, const struct ether_addr *addr)
{ {
unsupported_api(__FUNCTION__); FILE *f = NULL;
char buf[BUFFER_SIZE + 1];
char temp_name[BUFFER_SIZE];
struct ether_addr *temp_addr;
if (!(f = fopen(ETHER_FILE_PATH, "r")))
return ENOENT;
temp_addr = (struct ether_addr *)malloc(sizeof(struct ether_addr));
if (temp_addr == NULL) {
fclose(f);
return ENOMEM;
}
while (fgets(buf, BUFFER_SIZE, f)) {
if (ether_line(buf, temp_addr, temp_name) != 0)
continue;
if (memcmp(addr, temp_addr, 6) == 0) {
strcpy(hostname, temp_name);
free(temp_addr);
fclose(f);
return 0;
}
}
free(temp_addr);
fclose(f);
return -1; return -1;
} }
int ether_hostton(const char *hostname, struct ether_addr *e)
int ether_hostton(const char *hostname, struct ether_addr *addr)
{ {
unsupported_api(__FUNCTION__); FILE *f = NULL;
char buf[BUFFER_SIZE + 1];
char temp_name[BUFFER_SIZE];
struct ether_addr *temp_addr;
temp_addr = (struct ether_addr *)malloc(sizeof(struct ether_addr));
if (temp_addr == NULL)
return ENOMEM;
if (!(f = fopen(ETHER_FILE_PATH, "r"))) {
free(temp_addr);
return ENOENT;
}
while (fgets(buf, BUFFER_SIZE, f)) {
if (ether_line(buf, temp_addr, temp_name) != 0)
continue;
if (strcmp(hostname, temp_name) == 0) {
memcpy(addr, temp_addr, 6);
free(temp_addr);
fclose(f);
return 0;
}
}
free(temp_addr);
fclose(f);
return -1; return -1;
} }
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
#include <netdb.h> #include <netdb.h>
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <unsupported_api.h>
struct hostent *gethostbyaddr(const void *a, socklen_t l, int af) struct hostent *gethostbyaddr(const void *a, socklen_t l, int af)
{ {
...@@ -11,7 +10,6 @@ struct hostent *gethostbyaddr(const void *a, socklen_t l, int af) ...@@ -11,7 +10,6 @@ struct hostent *gethostbyaddr(const void *a, socklen_t l, int af)
size_t size = 63; size_t size = 63;
struct hostent *res; struct hostent *res;
int err; int err;
unsupported_api(__FUNCTION__);
do { do {
free(h); free(h);
h = malloc(size+=size+1); h = malloc(size+=size+1);
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <errno.h> #include <errno.h>
#include <inttypes.h> #include <inttypes.h>
#include <unsupported_api.h>
int gethostbyaddr_r(const void *a, socklen_t l, int af, int gethostbyaddr_r(const void *a, socklen_t l, int af,
struct hostent *h, char *buf, size_t buflen, struct hostent *h, char *buf, size_t buflen,
...@@ -20,7 +19,6 @@ int gethostbyaddr_r(const void *a, socklen_t l, int af, ...@@ -20,7 +19,6 @@ int gethostbyaddr_r(const void *a, socklen_t l, int af,
int i; int i;
*res = 0; *res = 0;
unsupported_api(__FUNCTION__);
/* Load address argument into sockaddr structure */ /* Load address argument into sockaddr structure */
if (af==AF_INET6 && l==16) memcpy(&sa.sin6.sin6_addr, a, 16); if (af==AF_INET6 && l==16) memcpy(&sa.sin6.sin6_addr, a, 16);
else if (af==AF_INET && l==4) memcpy(&sa.sin.sin_addr, a, 4); else if (af==AF_INET && l==4) memcpy(&sa.sin.sin_addr, a, 4);
......
...@@ -2,12 +2,10 @@ ...@@ -2,12 +2,10 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <netdb.h> #include <netdb.h>
#include <unsupported_api.h>
int gethostbyname_r(const char *name, int gethostbyname_r(const char *name,
struct hostent *h, char *buf, size_t buflen, struct hostent *h, char *buf, size_t buflen,
struct hostent **res, int *err) struct hostent **res, int *err)
{ {
unsupported_api(__FUNCTION__);
return gethostbyname2_r(name, AF_INET, h, buf, buflen, res, err); return gethostbyname2_r(name, AF_INET, h, buf, buflen, res, err);
} }
...@@ -7,10 +7,12 @@ ...@@ -7,10 +7,12 @@
#include <syscall.h> #include <syscall.h>
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <unsupported_api.h> #include <sys/ioctl.h>
#include "netlink.h" #include "netlink.h"
#include<stdio.h>
#define IFADDRS_HASH_SIZE 64 #define IFADDRS_HASH_SIZE 64
#define MAX_IF_NO 10
/* getifaddrs() reports hardware addresses with PF_PACKET that implies /* getifaddrs() reports hardware addresses with PF_PACKET that implies
* struct sockaddr_ll. But e.g. Infiniband socket address length is * struct sockaddr_ll. But e.g. Infiniband socket address length is
...@@ -47,11 +49,17 @@ struct ifaddrs_ctx { ...@@ -47,11 +49,17 @@ struct ifaddrs_ctx {
void freeifaddrs(struct ifaddrs *ifp) void freeifaddrs(struct ifaddrs *ifp)
{ {
struct ifaddrs *n; struct ifaddrs *tmp = NULL;
while (ifp) { while (ifp) {
n = ifp->ifa_next; if (!ifp->ifa_name)
free(ifp);
if (!ifp->ifa_addr)
free(ifp->ifa_addr);
if (!ifp->ifa_netmask)
free(ifp->ifa_netmask);
tmp = ifp->ifa_next;
free(ifp); free(ifp);
ifp = n; ifp = tmp;
} }
} }
...@@ -205,14 +213,85 @@ static int netlink_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) ...@@ -205,14 +213,85 @@ static int netlink_msg_to_ifaddr(void *pctx, struct nlmsghdr *h)
return 0; return 0;
} }
static struct ifaddrs* ifaddrs_init()
{
struct ifaddrs *ifa = NULL;
ifa = malloc(sizeof(struct ifaddrs));
if (!ifa)
return NULL;
ifa->ifa_name = malloc(sizeof(char) *(IF_NAMESIZE + 1));
ifa->ifa_addr = malloc(sizeof(struct sockaddr));
ifa->ifa_netmask = malloc(sizeof(struct sockaddr));
ifa->ifa_next = NULL;
if (!ifa->ifa_name || !ifa->ifa_addr || !ifa->ifa_netmask) {
free(ifa->ifa_name);
free(ifa->ifa_addr);
free(ifa->ifa_netmask);
free(ifa);
return NULL;
}
return ifa;
}
int getifaddrs(struct ifaddrs **ifap) int getifaddrs(struct ifaddrs **ifap)
{ {
struct ifaddrs_ctx _ctx, *ctx = &_ctx; if (ifap == NULL) {
int r; errno = EINVAL;
unsupported_api(__FUNCTION__); return -1;
memset(ctx, 0, sizeof *ctx); }
r = __rtnetlink_enumerate(AF_UNSPEC, AF_UNSPEC, netlink_msg_to_ifaddr, ctx);
if (r == 0) *ifap = &ctx->first->ifa; int fd, ifno, ret;
else freeifaddrs(&ctx->first->ifa); struct ifreq ifr[MAX_IF_NO];
return r; struct ifconf ifconfig;
struct ifaddrs *ifstart = NULL;
ifconfig.ifc_buf = ifr;
ifconfig.ifc_len = sizeof(ifr);
if ((fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0)) < 0)
return -1;
if (ioctl(fd, SIOCGIFCONF, &ifconfig) < 0)
goto error;
if (ifconfig.ifc_len % sizeof(struct ifreq)) {
errno = EINVAL;
goto error;
}
ifno = ifconfig.ifc_len / sizeof(struct ifreq);
if (!(ifstart = ifaddrs_init())) {
errno = ENOMEM;
goto error;
}
struct ifaddrs *ifa = ifstart;
for (int i = 0; i < ifno; i++) {
memcpy(ifa->ifa_name, ifr[i].ifr_name, IF_NAMESIZE);
ifa->ifa_name[IF_NAMESIZE] = '\0';
memcpy(ifa->ifa_addr, &ifr[i].ifr_addr, sizeof(struct sockaddr));
if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) < 0)
goto error;
memcpy(ifa->ifa_netmask, &ifr[i].ifr_netmask, sizeof(struct sockaddr));
if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) < 0)
goto error;
ifa->ifa_flags = ifr[i].ifr_flags;
if (i < ifno - 1) {
ifa->ifa_next = ifaddrs_init();
if (!ifa->ifa_next) {
errno = ENOMEM;
goto error;
}
ifa = ifa->ifa_next;
}
}
*ifap = ifstart;
return 0;
error:
freeifaddrs(ifstart);
__syscall(SYS_close, fd);
return -1;
} }
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include <net/if.h> #include <net/if.h>
#include <ctype.h> #include <ctype.h>
#include <resolv.h> #include <resolv.h>
#include <unsupported_api.h>
#include "lookup.h" #include "lookup.h"
#include "stdio_impl.h" #include "stdio_impl.h"
...@@ -130,7 +129,6 @@ int getnameinfo(const struct sockaddr *restrict sa, socklen_t sl, ...@@ -130,7 +129,6 @@ int getnameinfo(const struct sockaddr *restrict sa, socklen_t sl,
unsigned char *a; unsigned char *a;
unsigned scopeid; unsigned scopeid;
unsupported_api(__FUNCTION__);
switch (af) { switch (af) {
case AF_INET: case AF_INET:
a = (void *)&((struct sockaddr_in *)sa)->sin_addr; a = (void *)&((struct sockaddr_in *)sa)->sin_addr;
......
#define _GNU_SOURCE #define _GNU_SOURCE
#include <netdb.h> #include <netdb.h>
#include <unsupported_api.h>
struct servent *getservbyname(const char *name, const char *prots) struct servent *getservbyname(const char *name, const char *prots)
{ {
static struct servent se; static struct servent se;
static char *buf[2]; static char *buf[2];
struct servent *res; struct servent *res;
unsupported_api(__FUNCTION__);
if (getservbyname_r(name, prots, &se, (void *)buf, sizeof buf, &res)) if (getservbyname_r(name, prots, &se, (void *)buf, sizeof buf, &res))
return 0; return 0;
return &se; return &se;
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "lookup.h" #include "lookup.h"
#include <unsupported_api.h>
#define ALIGN (sizeof(struct { char a; char *b; }) - sizeof(char *)) #define ALIGN (sizeof(struct { char a; char *b; }) - sizeof(char *))
...@@ -18,7 +17,6 @@ int getservbyname_r(const char *name, const char *prots, ...@@ -18,7 +17,6 @@ int getservbyname_r(const char *name, const char *prots,
int cnt, proto, align; int cnt, proto, align;
*res = 0; *res = 0;
unsupported_api(__FUNCTION__);
/* Don't treat numeric port number strings as service records. */ /* Don't treat numeric port number strings as service records. */
char *end = ""; char *end = "";
......
#define _GNU_SOURCE #define _GNU_SOURCE
#include <netdb.h> #include <netdb.h>
#include <unsupported_api.h>
struct servent *getservbyport(int port, const char *prots) struct servent *getservbyport(int port, const char *prots)
{ {
static struct servent se; static struct servent se;
static long buf[32/sizeof(long)]; static long buf[32/sizeof(long)];
struct servent *res; struct servent *res;
unsupported_api(__FUNCTION__);
if (getservbyport_r(port, prots, &se, (void *)buf, sizeof buf, &res)) if (getservbyport_r(port, prots, &se, (void *)buf, sizeof buf, &res))
return 0; return 0;
return &se; return &se;
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <unsupported_api.h>
int getservbyport_r(int port, const char *prots, int getservbyport_r(int port, const char *prots,
struct servent *se, char *buf, size_t buflen, struct servent **res) struct servent *se, char *buf, size_t buflen, struct servent **res)
...@@ -16,7 +15,6 @@ int getservbyport_r(int port, const char *prots, ...@@ -16,7 +15,6 @@ int getservbyport_r(int port, const char *prots,
.sin_family = AF_INET, .sin_family = AF_INET,
.sin_port = port, .sin_port = port,
}; };
unsupported_api(__FUNCTION__);
if (!prots) { if (!prots) {
int r = getservbyport_r(port, "tcp", se, buf, buflen, res); int r = getservbyport_r(port, "tcp", se, buf, buflen, res);
...@@ -53,7 +51,6 @@ int getservbyport_r(int port, const char *prots, ...@@ -53,7 +51,6 @@ int getservbyport_r(int port, const char *prots,
case 0: case 0:
break; break;
} }
/* A numeric port string is not a service record. */ /* A numeric port string is not a service record. */
if (strtol(buf, 0, 10)==ntohs(port)) return ENOENT; if (strtol(buf, 0, 10)==ntohs(port)) return ENOENT;
......
...@@ -4,15 +4,13 @@ ...@@ -4,15 +4,13 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <unsupported_api.h>
#include "syscall.h" #include "syscall.h"
char *if_indextoname(unsigned index, char *name) char *if_indextoname(unsigned index, char *name)
{ {
struct ifreq ifr; struct ifreq ifr;
int fd, r; int fd, r;
unsupported_api(__FUNCTION__); if ((fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0;
if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0;
ifr.ifr_ifindex = index; ifr.ifr_ifindex = index;
r = ioctl(fd, SIOCGIFNAME, &ifr); r = ioctl(fd, SIOCGIFNAME, &ifr);
__syscall(SYS_close, fd); __syscall(SYS_close, fd);
......
...@@ -3,15 +3,14 @@ ...@@ -3,15 +3,14 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <string.h> #include <string.h>
#include <unsupported_api.h>
#include "syscall.h" #include "syscall.h"
unsigned if_nametoindex(const char *name) unsigned if_nametoindex(const char *name)
{ {
struct ifreq ifr; struct ifreq ifr;
int fd, r; int fd, r;
unsupported_api(__FUNCTION__);
if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0; if ((fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0;
strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
r = ioctl(fd, SIOCGIFINDEX, &ifr); r = ioctl(fd, SIOCGIFINDEX, &ifr);
__syscall(SYS_close, fd); __syscall(SYS_close, fd);
......
#include <netdb.h> #include <netdb.h>
#include <unsupported_api.h> #include <string.h>
struct netent *getnetbyaddr(uint32_t net, int type) struct netent *getnetbyaddr(uint32_t net, int addrtype)
{ {
unsupported_api(__FUNCTION__); struct netent *ne = NULL;
return 0; setnetent(1);
while (1) {
ne = getnetent();
if (!ne)
break;
if (ne->n_net == net && ne->n_addrtype == addrtype) {
setnetent(0);
endnetent();
return ne;
}
}
setnetent(0);
endnetent();
return NULL;
} }
struct netent *getnetbyname(const char *name) struct netent *getnetbyname(const char *netname)
{ {
unsupported_api(__FUNCTION__); struct netent *ne = NULL;
return 0; setnetent(1);
while (1) {
ne = getnetent();
if (!ne)
break;
if (strcmp(ne->n_name, netname) == 0) {
setnetent(0);
endnetent();
return ne;
}
}
setnetent(0);
endnetent();
return NULL;
} }
#include <netdb.h> #include <netdb.h>
#include <string.h> #include <string.h>
#include <unsupported_api.h>
/* do we really need all these?? */ /* do we really need all these?? */
...@@ -46,7 +45,6 @@ static const unsigned char protos[] = { ...@@ -46,7 +45,6 @@ static const unsigned char protos[] = {
void endprotoent(void) void endprotoent(void)
{ {
unsupported_api(__FUNCTION__);
idx = 0; idx = 0;
} }
......
#include <netdb.h> #define _BSD_SOURCE
#include <unsupported_api.h> #include<netdb.h>
#include<errno.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
void endservent(void) #define SERV_FILE_PATH "/etc/services"
#define BUFFER_SIZE 200
#define MAX_PORT 65535
#define MAX_ALIAS_NO 10
struct servdata
{ {
unsupported_api(__FUNCTION__); FILE *servf;
} int stayopen;
struct servent se;
char buf[BUFFER_SIZE];
char *alias_list[MAX_ALIAS_NO + 1];
};
static struct servdata *sd = NULL;
void setservent(int stayopen) static int servent_resolv()
{ {
unsupported_api(__FUNCTION__); if (sd->buf[0] == '#')
return -1;
char *ch, *temp, *ptr = NULL;
ch = strchr(sd->buf, '#');
if (ch)
*ch = '\0';
ch = strtok_r(sd->buf, " \t\n", &ptr);
temp = strtok_r(NULL, " \t\n", &ptr);
if (!ch || !temp)
return -1;
sd->se.s_name = ch;
ch = strchr(temp, '/');
if (ch == NULL)
return -1;
*ch++ = '\0';
sd->se.s_port = atoi(temp);
if (sd->se.s_port < 1 || sd->se.s_port > MAX_PORT)
return -1;
sd->se.s_port = htons(sd->se.s_port);
if (strcmp(ch, "tcp") != 0 && strcmp(ch, "udp") != 0)
return -1;
sd->se.s_proto = ch;
int i = 0;
while (i < MAX_ALIAS_NO) {
ch = strtok_r(NULL, " \t\n", &ptr);
sd->alias_list[i++] = ch;
}
sd->alias_list[MAX_ALIAS_NO] = NULL;
sd->se.s_aliases = sd->alias_list;
return 0;
} }
struct servent *getservent(void) struct servent *getservent(void)
{ {
unsupported_api(__FUNCTION__); if (sd == NULL) {
return 0; if ((sd = malloc(sizeof(struct servdata))) == NULL) {
errno = ENOMEM;
return NULL;
}
sd->servf = NULL;
sd->stayopen = 0;
}
if (!sd->servf && !(sd->servf = fopen(SERV_FILE_PATH, "r"))) {
errno = ENOENT;
free(sd);
sd = NULL;
return NULL;
}
do {
if (!fgets(sd->buf, BUFFER_SIZE - 1, sd->servf)) {
errno = EINVAL;
return NULL;
}
} while (servent_resolv());
return &(sd->se);
} }
void endservent(void)
{
if (sd == NULL)
return;
if (sd->stayopen == 0) {
if (sd->servf != NULL)
fclose(sd->servf);
free(sd);
sd = NULL;
}
}
void setservent(int stayopen)
{
if (sd == NULL) {
if ((sd = malloc(sizeof(struct servdata))) == NULL) {
errno = ENOMEM;
return;
}
sd->servf = NULL;
}
if (!sd->servf)
sd->servf = fopen(SERV_FILE_PATH, "r");
else
rewind(sd->servf);
sd->stayopen = stayopen;
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册