Fix the problems:
1) clmprint returns 0 for the error case.
2) clmprint does not handle invalid inputs.
3) clmprint does not deal with non-member node.
---
 src/clm/tools/Makefile    |  18 +++++
 src/clm/tools/clm_print.c | 191 +++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 182 insertions(+), 27 deletions(-)
 create mode 100644 src/clm/tools/Makefile

diff --git a/src/clm/tools/Makefile b/src/clm/tools/Makefile
new file mode 100644
index 0000000..1e39957
--- /dev/null
+++ b/src/clm/tools/Makefile
@@ -0,0 +1,18 @@
+#      -*- OpenSAF  -*-
+#
+# Copyright Ericsson AB 2017 - All Rights Reserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+# under the GNU Lesser General Public License Version 2.1, February 1999.
+# The complete license can be accessed from the following location:
+# http://opensource.org/licenses/lgpl-license.php
+# See the Copying file included with the OpenSAF distribution for full
+# licensing terms.
+#
+# Author(s): Ericsson AB
+#
+
+all:
+       $(MAKE) -C ../../.. bin/clmprint
diff --git a/src/clm/tools/clm_print.c b/src/clm/tools/clm_print.c
index eb01d3e..f44aee2 100644
--- a/src/clm/tools/clm_print.c
+++ b/src/clm/tools/clm_print.c
@@ -1,6 +1,7 @@
 /*      -*- OpenSAF  -*-
  *
  * Copyright (C) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
@@ -59,9 +60,9 @@ static char *clm_step[] = {
 
 static void print_node(const SaClmClusterNodeT_4 *clusterNode)
 {
-       printf("====Node Info for nodeId: %u========================>\n",
+       printf("\n====Node Info for nodeId: %u========================>\n",
                        clusterNode->nodeId);
-       printf("  Node Id                    : %u(%x)\n",
+       printf("  Node Id                    : %u(0x%x)\n",
                        clusterNode->nodeId, clusterNode->nodeId);
        printf("  Address Family             : %s\n",
                        clusterNode->nodeAddress.family == 1
@@ -84,6 +85,7 @@ static void print_node(const SaClmClusterNodeT_4 *clusterNode)
                        clusterNode->bootTimestamp);
        printf("  Initial View Number        : %llu\n",
                        clusterNode->initialViewNumber);
+       printf("<=======================================================\n\n");
 }
 
 static void  clm_node_get_callback(SaInvocationT invocation,
@@ -133,7 +135,6 @@ static void clm_track_callback(const 
SaClmClusterNotificationBufferT_4
                print_node(&notificationBuffer->notification[i].clusterNode);
                printf("  Change                     : %s\n",
                clm_change[notificationBuffer->notification[i].clusterChange]);
-               printf("<================================================\n\n");
        }
 
        if ((step == SA_CLM_CHANGE_VALIDATE) || (step == SA_CLM_CHANGE_START)) {
@@ -217,6 +218,93 @@ static void clm_dispatch(void)
                        exit(EXIT_SUCCESS);
        }
 }
+
+/*
+ * Exit the program with EXIT_FAILURE if passing invalid options,
+ * update the output `bit_mask` otherwise.
+ */
+static void validate_option(const char opt, uint32_t *bit_mask)
+{
+       enum mask_position {
+               OPT_HELP,
+               OPT_NODEGET,
+               OPT_ASYNCGET,
+               OPT_TRACK,
+               OPT_BTRACK,
+               OPT_TIMEOUT
+       };
+
+       switch (opt) {
+       case 'n':
+               if ((*bit_mask >> OPT_NODEGET) & 1) {
+                       fprintf(stderr, "error - duplicated options!\n");
+                       exit(EXIT_FAILURE);
+               }
+
+               if ((*bit_mask) && (*bit_mask ^ (1 << OPT_TIMEOUT))) {
+                       fprintf(stderr, "error - multiple options!\n");
+                       exit(EXIT_FAILURE);
+               }
+
+               *bit_mask |= (1 << OPT_NODEGET);
+               break;
+
+       case 'a':
+               if ((*bit_mask >> OPT_ASYNCGET) & 1) {
+                       fprintf(stderr, "error - duplicated options!\n");
+                       exit(EXIT_FAILURE);
+               }
+
+               if ((*bit_mask) && (*bit_mask ^ (1 << OPT_TIMEOUT))) {
+                       fprintf(stderr, "error - multiple options!\n");
+                       exit(EXIT_FAILURE);
+               }
+
+               *bit_mask |= (1 << OPT_ASYNCGET);
+               break;
+
+       case 'b':
+               if ((*bit_mask >> OPT_BTRACK) & 1) {
+                       fprintf(stderr, "error - duplicated options!\n");
+                       exit(EXIT_FAILURE);
+               }
+
+               if ((*bit_mask) && (*bit_mask ^ (1 << OPT_TIMEOUT))) {
+                       fprintf(stderr, "error - multiple options!\n");
+                       exit(EXIT_FAILURE);
+               }
+
+               *bit_mask |= (1 << OPT_BTRACK);
+               break;
+
+       case 'm':
+               if ((*bit_mask >> OPT_TRACK) & 1) {
+                       fprintf(stderr, "error - duplicated options!\n");
+                       exit(EXIT_FAILURE);
+               }
+
+               if ((*bit_mask) && (*bit_mask ^ (1 << OPT_TIMEOUT))) {
+                       fprintf(stderr, "error - multiple options!\n");
+                       exit(EXIT_FAILURE);
+               }
+
+               *bit_mask |= (1 << OPT_TRACK);
+               break;
+
+       case 't':
+               if ((*bit_mask >> OPT_TIMEOUT) & 1) {
+                       fprintf(stderr, "error - duplicated options!\n");
+                       exit(EXIT_FAILURE);
+               }
+
+               *bit_mask |= (1 << OPT_TIMEOUT);
+               break;
+
+       default:
+               break;
+       }
+}
+
 int main(int argc, char *argv[])
 {
        SaClmClusterNotificationT_4 clusterNotification[SIZE_NOTIFICATIONS];
@@ -228,6 +316,7 @@ int main(int argc, char *argv[])
        int c;
        char *ptr = NULL, *tmp_optarg = NULL;
        SaClmNodeIdT node_id = SA_CLM_LOCAL_NODE_ID;
+       uint32_t bit_mask = 0;
 
        is_cbk_received = false;
 
@@ -251,6 +340,9 @@ int main(int argc, char *argv[])
                if (c == -1)
                        break;
 
+               /* Terminate the program if passing invalid options */
+               validate_option(c, &bit_mask);
+
                switch (c) {
                case 'n':
                case 'a':
@@ -259,15 +351,25 @@ int main(int argc, char *argv[])
                                if ((argv[optind] != NULL) &&
                                                (argv[optind][0] != '-')) {
                                        node_id = strtoul(argv[optind], &ptr, 
0);
+                                       if (argv[optind][0] == '\0' || *ptr != 
'\0') {
+                                               fprintf(stderr, "error - input 
wrong data format!\n");
+                                               exit(EXIT_FAILURE);
+                                       }
                                        ++optind;
                                }
-                       } else
+                       } else {
                                node_id = strtoul(optarg, &ptr, 0);
-                       printf("node_id:%u(%x)\n", node_id, node_id);
+                               if (*optarg == '\0' || *ptr != '\0') {
+                                       fprintf(stderr, "error - input wrong 
data format!\n");
+                                       exit(EXIT_FAILURE);
+                               }
+                       }
                        break;
+
                case 'b':
                        mychar = c;
                        break;
+
                case 'm':
                        mychar = c;
                        if (optarg == NULL) {
@@ -311,19 +413,28 @@ int main(int argc, char *argv[])
                                exit(EXIT_FAILURE);
                        }
                        break;
+
                case 't':
-                       timeout = atoi(optarg) * 1000;
+                       timeout = strtoul(optarg, &ptr, 0);
+                       if (*optarg == '\0' || *ptr != '\0') {
+                               fprintf(stderr, "error: input wrong data 
format!\n");
+                               exit(EXIT_FAILURE);
+                       }
+                       timeout = timeout * 1000;
                        break;
+
                case 'h':
                        usage(basename(argv[0]));
                        exit(EXIT_SUCCESS);
                        break;
+
                default:
                        printf("Try '%s --help' for more information\n", 
argv[0]);
                        exit(EXIT_FAILURE);
                        break;
                }
        }
+
        rc = saClmInitialize_4(&clm_handle, &clm_callbacks, &clm_version);
        if (rc != SA_AIS_OK) {
                fprintf(stderr, "error - clmprint:: saClmInitialize_4 failed, 
rc = %d\n", rc);
@@ -335,53 +446,80 @@ int main(int argc, char *argv[])
                fprintf(stderr, "error - clmprint:: saClmSelectionObjectGet 
failed, rc = %d\n", rc);
                exit(EXIT_FAILURE);
        }
+
        clm_fds[0].fd = clm_selobject;
        clm_fds[0].events = POLLIN;
        switch (mychar) {
        case 'n':
                rc = saClmClusterNodeGet_4(clm_handle, node_id,
                                ((timeout == -1) ? (TIME_OUT) : timeout), 
&clusterNode);
-               if (rc != SA_AIS_OK) {
+               if (rc == SA_AIS_ERR_NOT_EXIST) {
+                       fprintf(stdout, "Node id 0x%x is not in cluster 
membership\n", node_id);
+                       exit(EXIT_SUCCESS);
+               } else if (rc == SA_AIS_ERR_UNAVAILABLE) {
+                       fprintf(stdout, "error - invoking clmprint from 
non-member node\n");
+                       exit(EXIT_FAILURE);
+               } else if (rc != SA_AIS_OK) {
                        fprintf(stderr, "error - clmprint:: 
saClmClusterNodeGet_4 failed, rc = %d\n", rc);
-               } else  {
-                       printf("\n");
-                       print_node(&clusterNode);
-                       
printf("<=======================================================\n\n");
+                       exit(EXIT_FAILURE);
                }
+
+               print_node(&clusterNode);
                break;
+
        case 'a':
                rc = saClmClusterNodeGetAsync(clm_handle, INVOCATION_ID, 
node_id);
-               if (rc != SA_AIS_OK)
+               if (rc == SA_AIS_ERR_NOT_EXIST) {
+                       fprintf(stdout, "Node id 0x%x is not in cluster 
membership\n", node_id);
+                       exit(EXIT_SUCCESS);
+               } else if (rc == SA_AIS_ERR_UNAVAILABLE) {
+                       fprintf(stdout, "error - invoking clmprint from 
non-member node\n");
+                       exit(EXIT_FAILURE);
+               } else if (rc != SA_AIS_OK) {
                        fprintf(stderr, "error - clmprint :: 
saClmClusterNodeGetAsync failed, rc = %d\n", rc);
-               else
-                       clm_dispatch();
+                       exit(EXIT_FAILURE);
+               }
+
+               clm_dispatch();
                break;
+
        case 'b':
                clusterNotificationBuffer.numberOfItems = SIZE_NOTIFICATIONS;
                rc = saClmClusterTrack_4(clm_handle, SA_TRACK_CURRENT, 
&clusterNotificationBuffer);
-               if (rc != SA_AIS_OK) {
+               if (rc == SA_AIS_ERR_UNAVAILABLE) {
+                       fprintf(stdout, "error - invoking clmprint from 
non-member node\n");
+                       exit(EXIT_FAILURE);
+               } else if (rc != SA_AIS_OK) {
                        fprintf(stderr, "error - clmprint:: saClmClusterTrack_4 
failed, rc = %d\n", rc);
-               } else {
-                       printf("\nnumberOfItems = %d\n\n", 
clusterNotificationBuffer.numberOfItems);
-                       for (uint32_t i = 0; i < 
clusterNotificationBuffer.numberOfItems; i++) {
-                               
print_node(&clusterNotificationBuffer.notification[i].clusterNode);
-                               printf("  Change                     : %s\n",
-                                               
clm_change[clusterNotificationBuffer.notification[i].clusterChange]);
-                               
printf("<===================================================\n\n");
-                       }
+                       exit(EXIT_FAILURE);
+               }
+
+               printf("\nnumberOfItems = %d\n\n", 
clusterNotificationBuffer.numberOfItems);
+               for (uint32_t i = 0; i < 
clusterNotificationBuffer.numberOfItems; i++) {
+                       
print_node(&clusterNotificationBuffer.notification[i].clusterNode);
+                       printf("  Change                     : %s\n",
+                              
clm_change[clusterNotificationBuffer.notification[i].clusterChange]);
                }
                break;
+
        case 'm':
                rc = saClmClusterTrack_4(clm_handle, trackFlags, NULL);
-               if (rc != SA_AIS_OK)
+               if (rc == SA_AIS_ERR_UNAVAILABLE) {
+                       fprintf(stdout, "error - invoking clmprint from 
non-member node\n");
+                       exit(EXIT_FAILURE);
+               } else if (rc != SA_AIS_OK) {
                        fprintf(stderr, "error - clmprint:: saClmClusterTrack_4 
failed, rc = %d\n", rc);
-               else
-                       clm_dispatch();
+                       exit(EXIT_FAILURE);
+               }
+
+               clm_dispatch();
                break;
+
        default:
                usage(basename(argv[0]));
                break;
        }
+
        rc = saClmFinalize(clm_handle);
        if (rc != SA_AIS_OK) {
                fprintf(stderr, "error - clmprint:: saClmFinalize failed, rc = 
%d\n", rc);
@@ -389,4 +527,3 @@ int main(int argc, char *argv[])
        }
        return 0;
 }
-
-- 
1.9.1


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to