CVSROOT:        /cvs/cluster
Module name:    cluster
Changes by:     [EMAIL PROTECTED]       2007-10-08 16:43:21

Modified files:
        ccs/lib        : ccs.h libccs.c 

Log message:
        add new function to libccs:
        * ccs_lookup_nodename
        * @cd: ccs descriptor
        * @nodename: node name string
        * @retval: pointer to location to assign the result, if found
        *
        * This function takes any valid representation (FQDN, non-qualified
        * hostname, IP address, IPv6 address) of a node's name and finds its
        * canonical name (per cluster.conf). This function will find the primary
        * node name if passed a node's "altname" or any valid representation
        * of it.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/ccs/lib/ccs.h.diff?cvsroot=cluster&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/ccs/lib/libccs.c.diff?cvsroot=cluster&r1=1.10&r2=1.11

--- cluster/ccs/lib/ccs.h       2005/01/13 16:19:08     1.4
+++ cluster/ccs/lib/ccs.h       2007/10/08 16:43:21     1.5
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -20,5 +20,6 @@
 int ccs_set(int desc, const char *path, char *val);
 int ccs_get_state(int desc, char **cw_path, char **prev_query);
 int ccs_set_state(int desc, const char *cw_path, int reset_query);
+int ccs_lookup_nodename(int desc, const char *nodename, char **rtn);
 
 #endif /*  __CCS_DOT_H__ */
--- cluster/ccs/lib/libccs.c    2006/01/11 16:00:55     1.10
+++ cluster/ccs/lib/libccs.c    2007/10/08 16:43:21     1.11
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -17,6 +17,8 @@
 #include <sys/un.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <netdb.h>
+#include <ctype.h>
 #include <errno.h>
 
 #include "log.h" /* Libraries should not print - so only use log_dbg */
@@ -623,3 +625,175 @@
   EXIT("ccs_set_state");
   return error;
 }
+
+/**
+ * ccs_lookup_nodename
+ * @cd: ccs descriptor
+ * @nodename: node name string
+ * @retval: pointer to location to assign the result, if found
+ *
+ * This function takes any valid representation (FQDN, non-qualified
+ * hostname, IP address, IPv6 address) of a node's name and finds its
+ * canonical name (per cluster.conf). This function will find the primary
+ * node name if passed a node's "altname" or any valid representation
+ * of it.
+ *
+ * Returns: 0 on success, < 0 on failure
+ */
+int ccs_lookup_nodename(int cd, const char *nodename, char **retval) {
+       char path[256];
+       char host_only[128];
+       char *str;
+       char *p;
+       int error;
+       int ret;
+       unsigned int i;
+       size_t nodename_len;
+       struct addrinfo hints;
+
+       if (nodename == NULL)
+               return (-1);
+
+       nodename_len = strlen(nodename);
+       ret = snprintf(path, sizeof(path),
+                       "/cluster/clusternodes/[EMAIL PROTECTED]"%s\"]/@name", 
nodename);
+       if (ret < 0 || (size_t) ret >= sizeof(path))
+               return (-ENOSPC);
+
+       str = NULL;
+       error = ccs_get(cd, path, &str);
+       if (!error) {
+               *retval = str;
+               return (0);
+       }
+
+       if (nodename_len >= sizeof(host_only))
+               return (-ENOSPC);
+
+       /* Try just the hostname */
+       strcpy(host_only, nodename);
+       p = strchr(host_only, '.');
+       if (p != NULL) {
+               *p = '\0';
+
+               ret = snprintf(path, sizeof(path),
+                               "/cluster/clusternodes/[EMAIL 
PROTECTED]"%s\"]/@name",
+                               host_only);
+               if (ret < 0 || (size_t) ret >= sizeof(path))
+                       return (-ENOSPC);
+
+               str = NULL;
+               error = ccs_get(cd, path, &str);
+               if (!error) {
+                       *retval = str;
+                       return (0);
+               }
+       }
+
+       memset(&hints, 0, sizeof(hints));
+       if (strchr(nodename, ':') != NULL)
+               hints.ai_family = AF_INET6;
+       else if (isdigit(nodename[nodename_len - 1]))
+               hints.ai_family = AF_INET;
+       else
+               hints.ai_family = AF_UNSPEC;
+
+       /*
+       ** Try to match against each clusternode in cluster.conf.
+       */
+       for (i = 1 ; ; i++) {
+               const char *pathstr = NULL;
+               char canonical_name[128];
+               unsigned int altcnt;
+
+               ret = snprintf(path, sizeof(path),
+                               "/cluster/clusternodes/clusternode[%u]/@name", 
i);
+               if (ret < 0 || (size_t) ret >= sizeof(path))
+                       continue;
+
+               for (altcnt = 0 ; ; altcnt++) {
+                       size_t len;
+                       struct addrinfo *ai = NULL;
+                       char cur_node[128];
+
+                       if (altcnt != 0) {
+                               ret = snprintf(path, sizeof(path), pathstr, i, 
altcnt);
+                               if (ret < 0 || (size_t) ret >= sizeof(path))
+                                       continue;
+                       }
+
+                       str = NULL;
+                       error = ccs_get(cd, path, &str);
+                       if (error || !str) {
+                               if (altcnt == 0)
+                                       goto out_fail;
+                               break;
+                       }
+
+                       if (altcnt == 0) {
+                               if (strlen(str) >= sizeof(canonical_name)) {
+                                       free(str);
+                                       return (-ENOSPC);
+                               }
+                               strcpy(canonical_name, str);
+                       }
+
+                       if (strlen(str) >= sizeof(cur_node)) {
+                               free(str);
+                               return (-ENOSPC);
+                       }
+
+                       strcpy(cur_node, str);
+
+                       p = strchr(cur_node, '.');
+                       if (p != NULL)
+                               len = p - cur_node;
+                       else
+                               len = strlen(cur_node);
+
+                       if (strlen(host_only) == len &&
+                               !strncasecmp(host_only, cur_node, len))
+                       {
+                               free(str);
+                               *retval = strdup(canonical_name);
+                               if (*retval == NULL)
+                                       return (-ENOMEM);
+                               return (0);
+                       }
+
+                       if (getaddrinfo(str, NULL, &hints, &ai) == 0) {
+                               struct addrinfo *cur;
+
+                               for (cur = ai ; cur != NULL ; cur = 
cur->ai_next) {
+                                       char hostbuf[512];
+                                       if (getnameinfo(cur->ai_addr, 
cur->ai_addrlen,
+                                                       hostbuf, 
sizeof(hostbuf),
+                                                       NULL, 0,
+                                                       hints.ai_family != 
AF_UNSPEC ? NI_NUMERICHOST : 0))
+                                       {
+                                               continue;
+                                       }
+
+                                       if (!strcasecmp(hostbuf, nodename)) {
+                                               freeaddrinfo(ai);
+                                               free(str);
+                                               *retval = 
strdup(canonical_name);
+                                               if (*retval == NULL)
+                                                       return (-ENOMEM);
+                                               return (0);
+                                       }
+                               }
+                               freeaddrinfo(ai);
+                       }
+
+                       free(str);
+
+                       /* Try any altnames */
+                       pathstr = 
"/cluster/clusternodes/clusternode[%u]/altname[%u]/@name";
+               }
+       }
+
+out_fail:
+       *retval = NULL;
+       return (-1);
+}

Reply via email to