]> Pileus Git - ~andy/fetchmail/blobdiff - servport.c
Complete Dominik's name.
[~andy/fetchmail] / servport.c
index 0cc9fa887993b7f7b80670b314daf1e3b0362a87..0a12c640446b35dfa42e8e1405367db85784be84 100644 (file)
@@ -1,16 +1,18 @@
 /** \file servport.c Resolve service name to port number.
  * \author Matthias Andree
- * \date 2005
+ * \date 2005 - 2006
  *
  * 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 <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
 #include <netdb.h>
 #if defined(HAVE_NETINET_IN_H)
 #include <netinet/in.h>
 #ifdef HAVE_ARPA_INET_H
 #include <arpa/inet.h>
 #endif
+#include <sys/socket.h>
 
 int servport(const char *service) {
-    int port;
+    int port, e;
     unsigned long u;
     char *end;
 
@@ -34,20 +37,37 @@ int servport(const char *service) {
     errno = 0;
     u = strtoul(service, &end, 10);
     if (errno || end[strspn(end, POSIX_space)] != '\0') {
-       struct servent *se;
+       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;
 
-       se = getservbyname(service, "tcp");
-       if (se == NULL) {
-           endservent();
+       memset(&hints, 0, sizeof hints);
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_STREAM;
+       hints.ai_protocol = IPPROTO_TCP;
+       e = fm_getaddrinfo(NULL, service, &hints, &res);
+       if (e) {
+           report(stderr, GT_("getaddrinfo(NULL, \"%s\") error: %s\n"),
+                   service, gai_strerror(e));
            goto err;
        } else {
-           port = ntohs(se->s_port);
-           endservent();
+           switch(res->ai_addr->sa_family) {
+               case AF_INET:
+                   port = ntohs(((struct sockaddr_in *)res->ai_addr)->sin_port);
+               break;
+#ifdef AF_INET6
+               case AF_INET6:
+                   port = ntohs(((struct sockaddr_in6 *)res->ai_addr)->sin6_port);
+               break;
+#endif
+               default:
+                   fm_freeaddrinfo(res);
+                   goto err;
+           }
+           fm_freeaddrinfo(res);
        }
     } else {
        if (u == 0 || u > 65535)
@@ -57,7 +77,8 @@ int servport(const char *service) {
 
     return port;
 err:
-    report(stderr, GT_("Cannot resolve service %s to port.  Please specify the service as decimal port number.\n"), service);
+    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 */