diff --git a/porting/liteos_a/user/src/network/ent.c b/porting/liteos_a/user/src/network/ent.c index e8f840ede5d7b0d6d3c6d9bc2c064d974089bb82..65131e2d68a4b71fae15579947eeac500d8fb0cd 100644 --- a/porting/liteos_a/user/src/network/ent.c +++ b/porting/liteos_a/user/src/network/ent.c @@ -1,27 +1,219 @@ -#include -#include +#define _BSD_SOURCE +#include +#include +#include +#include +#include +#include -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__); - return 0; + if (hd == NULL) { + 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__); - return 0; + if (hd == NULL) { + 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) { - 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); -weak_alias(endhostent, endnetent); +static int getnetent_resolv() +{ + 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 diff --git a/porting/liteos_a/user/src/network/ether.c b/porting/liteos_a/user/src/network/ether.c index e3d295107dbcd269e870999922431ca8bddc9385..28cde3929f3d31832e28d70cf4fbee693cea37b5 100644 --- a/porting/liteos_a/user/src/network/ether.c +++ b/porting/liteos_a/user/src/network/ether.c @@ -1,7 +1,11 @@ #include #include #include -#include +#include +#include + +#define ETHER_FILE_PATH "/etc/ethers" +#define BUFFER_SIZE 200 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) { 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__); - return -1; + char buf[BUFFER_SIZE], *ch, *ptr = NULL; + 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) -{ - unsupported_api(__FUNCTION__); +int ether_ntohost(char *hostname, const struct ether_addr *addr) +{ + 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; } -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; } diff --git a/porting/liteos_a/user/src/network/gethostbyaddr.c b/porting/liteos_a/user/src/network/gethostbyaddr.c index 03fdaf84074e3fd14ab0d0766540e9378fb2db4c..598e2241a9f808e8ecafb72e24d7d6959cb49a28 100644 --- a/porting/liteos_a/user/src/network/gethostbyaddr.c +++ b/porting/liteos_a/user/src/network/gethostbyaddr.c @@ -3,7 +3,6 @@ #include #include #include -#include 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; struct hostent *res; int err; - unsupported_api(__FUNCTION__); do { free(h); h = malloc(size+=size+1); diff --git a/porting/liteos_a/user/src/network/gethostbyaddr_r.c b/porting/liteos_a/user/src/network/gethostbyaddr_r.c index ce4e3f67778798bcb8a8869ad40c4021f6db1777..2c3cd7088320139439029ff3eceb7c0edf80474d 100644 --- a/porting/liteos_a/user/src/network/gethostbyaddr_r.c +++ b/porting/liteos_a/user/src/network/gethostbyaddr_r.c @@ -6,7 +6,6 @@ #include #include #include -#include int gethostbyaddr_r(const void *a, socklen_t l, int af, struct hostent *h, char *buf, size_t buflen, @@ -20,7 +19,6 @@ int gethostbyaddr_r(const void *a, socklen_t l, int af, int i; *res = 0; - unsupported_api(__FUNCTION__); /* Load address argument into sockaddr structure */ 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); diff --git a/porting/liteos_a/user/src/network/gethostbyname_r.c b/porting/liteos_a/user/src/network/gethostbyname_r.c index c89d6f2ecd2e72a0ab3c25510ed05eef9eea667c..cd8725417377284696d75344e8e679e14ae9cb7b 100644 --- a/porting/liteos_a/user/src/network/gethostbyname_r.c +++ b/porting/liteos_a/user/src/network/gethostbyname_r.c @@ -2,12 +2,10 @@ #include #include -#include int gethostbyname_r(const char *name, struct hostent *h, char *buf, size_t buflen, struct hostent **res, int *err) { - unsupported_api(__FUNCTION__); return gethostbyname2_r(name, AF_INET, h, buf, buflen, res, err); } diff --git a/porting/liteos_a/user/src/network/getifaddrs.c b/porting/liteos_a/user/src/network/getifaddrs.c index 09088957d1bf43213eb963ac90cca8c4de4ffa88..144bd1715573396595579db290bb014f9b6b598b 100644 --- a/porting/liteos_a/user/src/network/getifaddrs.c +++ b/porting/liteos_a/user/src/network/getifaddrs.c @@ -7,10 +7,12 @@ #include #include #include -#include +#include #include "netlink.h" +#include #define IFADDRS_HASH_SIZE 64 +#define MAX_IF_NO 10 /* getifaddrs() reports hardware addresses with PF_PACKET that implies * struct sockaddr_ll. But e.g. Infiniband socket address length is @@ -47,11 +49,17 @@ struct ifaddrs_ctx { void freeifaddrs(struct ifaddrs *ifp) { - struct ifaddrs *n; + struct ifaddrs *tmp = NULL; 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); - ifp = n; + ifp = tmp; } } @@ -205,14 +213,85 @@ static int netlink_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) 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) { - struct ifaddrs_ctx _ctx, *ctx = &_ctx; - int r; - unsupported_api(__FUNCTION__); - memset(ctx, 0, sizeof *ctx); - r = __rtnetlink_enumerate(AF_UNSPEC, AF_UNSPEC, netlink_msg_to_ifaddr, ctx); - if (r == 0) *ifap = &ctx->first->ifa; - else freeifaddrs(&ctx->first->ifa); - return r; + if (ifap == NULL) { + errno = EINVAL; + return -1; + } + + int fd, ifno, ret; + struct ifreq ifr[MAX_IF_NO]; + 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; } + diff --git a/porting/liteos_a/user/src/network/getnameinfo.c b/porting/liteos_a/user/src/network/getnameinfo.c index 9734c0c2591493f08da8e3e9ef97f3885d340cdb..f77e73ade89dea90bf427458468e678b80b5217b 100644 --- a/porting/liteos_a/user/src/network/getnameinfo.c +++ b/porting/liteos_a/user/src/network/getnameinfo.c @@ -9,7 +9,6 @@ #include #include #include -#include #include "lookup.h" #include "stdio_impl.h" @@ -130,7 +129,6 @@ int getnameinfo(const struct sockaddr *restrict sa, socklen_t sl, unsigned char *a; unsigned scopeid; - unsupported_api(__FUNCTION__); switch (af) { case AF_INET: a = (void *)&((struct sockaddr_in *)sa)->sin_addr; diff --git a/porting/liteos_a/user/src/network/getservbyname.c b/porting/liteos_a/user/src/network/getservbyname.c index fb721bfda5be0fc71acc7664e1668702175e98fb..dd3037678c278536ce51cf6f296fc512175e7322 100644 --- a/porting/liteos_a/user/src/network/getservbyname.c +++ b/porting/liteos_a/user/src/network/getservbyname.c @@ -1,13 +1,11 @@ #define _GNU_SOURCE #include -#include struct servent *getservbyname(const char *name, const char *prots) { static struct servent se; static char *buf[2]; struct servent *res; - unsupported_api(__FUNCTION__); if (getservbyname_r(name, prots, &se, (void *)buf, sizeof buf, &res)) return 0; return &se; diff --git a/porting/liteos_a/user/src/network/getservbyname_r.c b/porting/liteos_a/user/src/network/getservbyname_r.c index 3f03930e508dd8f2b0428e48395e096edf2b3b1e..cad6317ab84243e5bc8de3a1d8ce17eb4a688a5e 100644 --- a/porting/liteos_a/user/src/network/getservbyname_r.c +++ b/porting/liteos_a/user/src/network/getservbyname_r.c @@ -7,7 +7,6 @@ #include #include #include "lookup.h" -#include #define ALIGN (sizeof(struct { char a; char *b; }) - sizeof(char *)) @@ -18,7 +17,6 @@ int getservbyname_r(const char *name, const char *prots, int cnt, proto, align; *res = 0; - unsupported_api(__FUNCTION__); /* Don't treat numeric port number strings as service records. */ char *end = ""; diff --git a/porting/liteos_a/user/src/network/getservbyport.c b/porting/liteos_a/user/src/network/getservbyport.c index 9aaeab0f0d9dde5ca00bfd767698b4e37ad1b34e..c9ecbb11c869ccd1acb8a47bb039c45400870623 100644 --- a/porting/liteos_a/user/src/network/getservbyport.c +++ b/porting/liteos_a/user/src/network/getservbyport.c @@ -1,13 +1,11 @@ #define _GNU_SOURCE #include -#include struct servent *getservbyport(int port, const char *prots) { static struct servent se; static long buf[32/sizeof(long)]; struct servent *res; - unsupported_api(__FUNCTION__); if (getservbyport_r(port, prots, &se, (void *)buf, sizeof buf, &res)) return 0; return &se; diff --git a/porting/liteos_a/user/src/network/getservbyport_r.c b/porting/liteos_a/user/src/network/getservbyport_r.c index 18cfd6a72f378e867bad74586f32b1fc5b8990fb..65b239fd33f1585ba1dcdfd70ed3f65e2cf11b4a 100644 --- a/porting/liteos_a/user/src/network/getservbyport_r.c +++ b/porting/liteos_a/user/src/network/getservbyport_r.c @@ -6,7 +6,6 @@ #include #include #include -#include int getservbyport_r(int port, const char *prots, struct servent *se, char *buf, size_t buflen, struct servent **res) @@ -16,7 +15,6 @@ int getservbyport_r(int port, const char *prots, .sin_family = AF_INET, .sin_port = port, }; - unsupported_api(__FUNCTION__); if (!prots) { int r = getservbyport_r(port, "tcp", se, buf, buflen, res); @@ -53,7 +51,6 @@ int getservbyport_r(int port, const char *prots, case 0: break; } - /* A numeric port string is not a service record. */ if (strtol(buf, 0, 10)==ntohs(port)) return ENOENT; diff --git a/porting/liteos_a/user/src/network/if_indextoname.c b/porting/liteos_a/user/src/network/if_indextoname.c index d4fb019ce6382c0b098c701645ce900f44724cd0..e862ba476e5c06ce43921696408edd0c1becbe15 100644 --- a/porting/liteos_a/user/src/network/if_indextoname.c +++ b/porting/liteos_a/user/src/network/if_indextoname.c @@ -4,15 +4,13 @@ #include #include #include -#include #include "syscall.h" char *if_indextoname(unsigned index, char *name) { struct ifreq ifr; 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; ifr.ifr_ifindex = index; r = ioctl(fd, SIOCGIFNAME, &ifr); __syscall(SYS_close, fd); diff --git a/porting/liteos_a/user/src/network/if_nametoindex.c b/porting/liteos_a/user/src/network/if_nametoindex.c index 6447fe0980e814b2d994463dc43afec29a389096..52cb1c2599077790e7c350abddc8f2aedb609fa2 100644 --- a/porting/liteos_a/user/src/network/if_nametoindex.c +++ b/porting/liteos_a/user/src/network/if_nametoindex.c @@ -3,15 +3,14 @@ #include #include #include -#include #include "syscall.h" unsigned if_nametoindex(const char *name) { struct ifreq ifr; 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); r = ioctl(fd, SIOCGIFINDEX, &ifr); __syscall(SYS_close, fd); diff --git a/porting/liteos_a/user/src/network/netname.c b/porting/liteos_a/user/src/network/netname.c index 1351b688d802ae2de1728039764749cde5c32fbd..d11d7b00b0371a6fffb18f8b904932f1ade49e9b 100644 --- a/porting/liteos_a/user/src/network/netname.c +++ b/porting/liteos_a/user/src/network/netname.c @@ -1,15 +1,41 @@ #include -#include +#include -struct netent *getnetbyaddr(uint32_t net, int type) -{ - unsupported_api(__FUNCTION__); - return 0; +struct netent *getnetbyaddr(uint32_t net, int addrtype) +{ + struct netent *ne = NULL; + 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__); - return 0; + struct netent *ne = NULL; + 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; } diff --git a/porting/liteos_a/user/src/network/proto.c b/porting/liteos_a/user/src/network/proto.c index f5b7db45a539c09e456806749654d3d679d4d7fd..c4fd34efb0ad4883133573dc090b1b7692f5b012 100644 --- a/porting/liteos_a/user/src/network/proto.c +++ b/porting/liteos_a/user/src/network/proto.c @@ -1,6 +1,5 @@ #include #include -#include /* do we really need all these?? */ @@ -46,7 +45,6 @@ static const unsigned char protos[] = { void endprotoent(void) { - unsupported_api(__FUNCTION__); idx = 0; } diff --git a/porting/liteos_a/user/src/network/serv.c b/porting/liteos_a/user/src/network/serv.c index f7e4f209b353500d99d658e2c3db18b290713a56..38f000721699d4cb76df6f45907bc424a34b119c 100644 --- a/porting/liteos_a/user/src/network/serv.c +++ b/porting/liteos_a/user/src/network/serv.c @@ -1,18 +1,110 @@ -#include -#include +#define _BSD_SOURCE +#include +#include +#include +#include +#include -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) { - unsupported_api(__FUNCTION__); - return 0; + if (sd == NULL) { + 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