/** \file servport.c Resolve service name to port number. * \author Matthias Andree * \date 2005 * * Copyright (C) 2005 by Matthias Andree * For license terms, see the file COPYING in this directory. */ #include "fetchmail.h" #include "getaddrinfo.h" #include "i18n.h" #include #include #include #include #include #if defined(HAVE_NETINET_IN_H) #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #include int servport(const char *service) { int port; unsigned long u; char *end; if (service == 0) return -1; /* * Check if the service is a number. If so, convert it. * If it isn't a number, call getservbyname to resolve it. */ errno = 0; u = strtoul(service, &end, 10); if (errno || end[strspn(end, POSIX_space)] != '\0') { struct addrinfo hints, *res; /* hardcode kpop to port 1109 as per fetchmail(1) * manual page, it's not a IANA registered service */ if (strcmp(service, "kpop") == 0) return 1109; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if (getaddrinfo(NULL, service, &hints, &res)) { goto err; } else { switch(res->ai_addr->sa_family) { case AF_INET: port = ntohs(((struct sockaddr_in *)res->ai_addr)->sin_port); #ifdef AF_INET6 case AF_INET6: port = ntohs(((struct sockaddr_in6 *)res->ai_addr)->sin6_port); #endif default: goto err; } freeaddrinfo(res); } } else { if (u == 0 || u > 65535) goto err; port = u; } return port; err: report(stderr, GT_("Cannot resolve service %s to port number.\n"), service); report(stderr, GT_("Please specify the service as decimal port number.\n")); return -1; } /* end of servport.c */