1*c9945492SAndroid Build Coastguard Worker #define _GNU_SOURCE
2*c9945492SAndroid Build Coastguard Worker #include <sys/socket.h>
3*c9945492SAndroid Build Coastguard Worker #include <netinet/in.h>
4*c9945492SAndroid Build Coastguard Worker #include <netdb.h>
5*c9945492SAndroid Build Coastguard Worker #include <inttypes.h>
6*c9945492SAndroid Build Coastguard Worker #include <errno.h>
7*c9945492SAndroid Build Coastguard Worker #include <string.h>
8*c9945492SAndroid Build Coastguard Worker #include <stdlib.h>
9*c9945492SAndroid Build Coastguard Worker #include "lookup.h"
10*c9945492SAndroid Build Coastguard Worker
11*c9945492SAndroid Build Coastguard Worker #define ALIGN (sizeof(struct { char a; char *b; }) - sizeof(char *))
12*c9945492SAndroid Build Coastguard Worker
getservbyname_r(const char * name,const char * prots,struct servent * se,char * buf,size_t buflen,struct servent ** res)13*c9945492SAndroid Build Coastguard Worker int getservbyname_r(const char *name, const char *prots,
14*c9945492SAndroid Build Coastguard Worker struct servent *se, char *buf, size_t buflen, struct servent **res)
15*c9945492SAndroid Build Coastguard Worker {
16*c9945492SAndroid Build Coastguard Worker struct service servs[MAXSERVS];
17*c9945492SAndroid Build Coastguard Worker int cnt, proto, align;
18*c9945492SAndroid Build Coastguard Worker
19*c9945492SAndroid Build Coastguard Worker *res = 0;
20*c9945492SAndroid Build Coastguard Worker
21*c9945492SAndroid Build Coastguard Worker /* Don't treat numeric port number strings as service records. */
22*c9945492SAndroid Build Coastguard Worker char *end = "";
23*c9945492SAndroid Build Coastguard Worker strtoul(name, &end, 10);
24*c9945492SAndroid Build Coastguard Worker if (!*end) return ENOENT;
25*c9945492SAndroid Build Coastguard Worker
26*c9945492SAndroid Build Coastguard Worker /* Align buffer */
27*c9945492SAndroid Build Coastguard Worker align = -(uintptr_t)buf & ALIGN-1;
28*c9945492SAndroid Build Coastguard Worker if (buflen < 2*sizeof(char *)+align)
29*c9945492SAndroid Build Coastguard Worker return ERANGE;
30*c9945492SAndroid Build Coastguard Worker buf += align;
31*c9945492SAndroid Build Coastguard Worker
32*c9945492SAndroid Build Coastguard Worker if (!prots) proto = 0;
33*c9945492SAndroid Build Coastguard Worker else if (!strcmp(prots, "tcp")) proto = IPPROTO_TCP;
34*c9945492SAndroid Build Coastguard Worker else if (!strcmp(prots, "udp")) proto = IPPROTO_UDP;
35*c9945492SAndroid Build Coastguard Worker else return EINVAL;
36*c9945492SAndroid Build Coastguard Worker
37*c9945492SAndroid Build Coastguard Worker cnt = __lookup_serv(servs, name, proto, 0, 0);
38*c9945492SAndroid Build Coastguard Worker if (cnt<0) switch (cnt) {
39*c9945492SAndroid Build Coastguard Worker case EAI_MEMORY:
40*c9945492SAndroid Build Coastguard Worker case EAI_SYSTEM:
41*c9945492SAndroid Build Coastguard Worker return ENOMEM;
42*c9945492SAndroid Build Coastguard Worker default:
43*c9945492SAndroid Build Coastguard Worker return ENOENT;
44*c9945492SAndroid Build Coastguard Worker }
45*c9945492SAndroid Build Coastguard Worker
46*c9945492SAndroid Build Coastguard Worker se->s_name = (char *)name;
47*c9945492SAndroid Build Coastguard Worker se->s_aliases = (void *)buf;
48*c9945492SAndroid Build Coastguard Worker se->s_aliases[0] = se->s_name;
49*c9945492SAndroid Build Coastguard Worker se->s_aliases[1] = 0;
50*c9945492SAndroid Build Coastguard Worker se->s_port = htons(servs[0].port);
51*c9945492SAndroid Build Coastguard Worker se->s_proto = servs[0].proto == IPPROTO_TCP ? "tcp" : "udp";
52*c9945492SAndroid Build Coastguard Worker
53*c9945492SAndroid Build Coastguard Worker *res = se;
54*c9945492SAndroid Build Coastguard Worker return 0;
55*c9945492SAndroid Build Coastguard Worker }
56