1214152Sed#define _GNU_SOURCE 2214152Sed#include "lookup.h" 3214152Sed#include <errno.h> 4214152Sed#include <inttypes.h> 5222656Sed#include <netdb.h> 6222656Sed#include <netinet/in.h> 7214152Sed#include <string.h> 8214152Sed#include <sys/socket.h> 9214152Sed 10214152Sed#define ALIGN \ 11214152Sed (sizeof(struct { \ 12214152Sed char a; \ 13214152Sed char* b; \ 14214152Sed }) - \ 15214152Sed sizeof(char*)) 16229135Sed 17214152Sedint getservbyname_r(const char* name, const char* prots, struct servent* se, char* buf, 18214152Sed size_t buflen, struct servent** res) { 19214152Sed struct service servs[MAXSERVS]; 20214152Sed int cnt, proto, align; 21214152Sed 22214152Sed /* Align buffer */ 23214152Sed align = -(uintptr_t)buf & (ALIGN - 1); 24214152Sed if (buflen < 2 * sizeof(char*) + align) 25214152Sed return ERANGE; 26214152Sed buf += align; 27214152Sed 28214152Sed if (!prots) 29214152Sed proto = 0; 30229135Sed else if (!strcmp(prots, "tcp")) 31214152Sed proto = IPPROTO_TCP; 32214152Sed else if (!strcmp(prots, "udp")) 33229135Sed proto = IPPROTO_UDP; 34214152Sed else 35229135Sed return EINVAL; 36229135Sed 37229135Sed cnt = __lookup_serv(servs, name, proto, 0, 0); 38229135Sed if (cnt < 0) 39229135Sed switch (cnt) { 40229135Sed case EAI_MEMORY: 41214152Sed case EAI_SYSTEM: 42214152Sed return ENOMEM; 43229135Sed default: 44214152Sed return ENOENT; 45229135Sed } 46229135Sed 47229135Sed se->s_name = (char*)name; 48229135Sed se->s_aliases = (void*)buf; 49229135Sed se->s_aliases[0] = se->s_name; 50229135Sed se->s_aliases[1] = 0; 51214152Sed se->s_port = htons(servs[0].port); 52214152Sed se->s_proto = (char*)(servs[0].proto == IPPROTO_TCP ? "tcp" : "udp"); 53229135Sed 54229135Sed *res = se; 55214152Sed return 0; 56229135Sed} 57229135Sed