/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* 61haes_r714 src/43haes/usr/sbin/cluster/clstat/xclstat.c 1.20 */ /* */ /* Licensed Materials - Property of IBM */ /* */ /* Restricted Materials of IBM */ /* */ /* COPYRIGHT International Business Machines Corp. 1990,2009 */ /* All Rights Reserved */ /* */ /* US Government Users Restricted Rights - Use, duplication or */ /* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ /* */ /* IBM_PROLOG_END_TAG */ static char xclstat_c_sccsid[] = "@(#)46 1.20 src/43haes/usr/sbin/cluster/clstat/xclstat.c, hacmp.clstat, 61haes_r714 2/11/09 07:40:30"; /* * COMPONENT_NAME: CLSTAT * * FUNCTIONS: SetOffset * Usage * Xmain * clstat_init * create_bottom * create_helptext * create_nodemap * create_textbuf * create_top * delWidgetByLabel * freeWidgetList * getWidgetByLabel * getWidgetByTag * getWidgetTag * setWidgetTag * help * highlight * mkdatestr * nextCluster * prevCluster * putWidget * quit * quitPopup * refreshMap * title * unHighlight * viewNode * * ORIGINS: 27 * * * (C) COPYRIGHT International Business Machines Corp. 1990,1994 * All Rights Reserved * Licensed Materials - Property of IBM * US Government Users Restricted Rights - Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Needed to get XtClassname */ #include #include #include #include #include #include #include #include #ifdef SUPPORT_EDITRES #include #endif #include "cluster.h" #include "clinfo.h" #include "xclstat.h" #ifdef SUPPORT_DMALLOC #include "dmalloc.h" #endif /* ILS */ #include #include #include "utilities_msg.h" #define MSGSTR(Num, Str) catgets((nl_catd)get_catd("utilities.cat"), CLSTAT_MSG_SET, Num, Str) #ifndef lint #endif char *progname; /* Forward decl */ int compareNetifs(); int compareNodemap(); void copyNodemap(); void resetNodemap(); static nl_catd get_catd(char *); static char *create_textbuf (int, int); /* globals */ int CL_cid = 0; int CL_nid = 0; static struct cl_cluster *clusterMap; /* new cluster information */ static struct cl_node *pNodeMap; /* new node info */ static int ALLSERVICES = 0; Arg xargv[64]; Cardinal xargc; XtActionsRec viewNodeAction[]= { {"viewNode", viewNode} }; XtActionsRec prevClusterAction[]= { {"prevCluster", prevCluster} }; XtActionsRec nextClusterAction[]= { {"nextCluster", nextCluster} }; XtActionsRec quitAction[]= { {"quit", quit} }; XtActionsRec helpAction[]= { {"help", help} }; XtActionsRec quitPopupAction[]= { {"quitPopup", quitPopup} }; XtActionsRec titleAction[]= { {"title", title} }; String viewNodeTable = ":viewNode(%s)"; String prevClusterTable = ":prevCluster()"; String nextClusterTable = ":nextCluster()"; String quitTable = ":quit()"; String helpTable = ":help()"; String quitPopupTable = ":quitPopup(%s)"; String titleTable = ":title()"; /* ** Application resources */ static struct clstatRes appRes; #define SetOffset(n,f) (appResourceList[n].resource_offset = \ ((Cardinal)&appRes.f - (Cardinal)&appRes)) XtResource appResourceList[] = { {XtNbackground, XtCBackground, XtRPixel, sizeof (Pixel), 0, XtRString, XtExtdefaultbackground}, {XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel), 0, XtRString, XtExtdefaultforeground}, {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof (Dimension), 0, XtRString, "1"}, {XtNreverseVideo, XtCReverseVideo, XtRBool, sizeof (Bool), 0, XtRString, XtEfalse}, {"upColor", "UpColor", XtRPixel, sizeof (Pixel), 0, XtRString, "#00FF00"}, {"downColor", "DownColor", XtRPixel, sizeof (Pixel), 0, XtRString, "#FF0000"}, {"fluxColor", "FluxColor", XtRPixel, sizeof (Pixel), 0, XtRString, "#00FFFF"}, {"refreshInterval", "RefreshInterval", XtRInt, sizeof(int), 0, XtRString, "100"}, {"helpFile", "HelpFile", XtRString, sizeof(String), 0, XtRString, "/usr/lpp/cluster/man/clstat.1"} }; Boolean XtIsWidgetValid(Widget w) { /* NULL widget passed */ if (! w) return(False); /* Non widget passed or widget struct corrupt */ if (w != w->core.self) return(False); /* widget is marked for destruction */ if (w->core.being_destroyed) return(False); return(True); } String XtClassName (Widget w) { if (XtIsWidgetValid(w)) return(XtClass(w)->core_class.class_name); else return(NULL); } int main (int argc, char **argv) { int opt; extern int optind; extern char *optarg; int clusterid = 0; char *clustername = (char *)NULL; int debug_level = 1; int info_level = 0; int rflagn = 1; Widget topLevel; Widget frame; Pixel save_pix; XColor color; XVisualInfo *visp, vistemp; int visnum; (void) setlocale(LC_ALL, ""); progname = strrchr (argv[0], '/'); if ((char *)NULL == progname) progname = argv[0]; else progname++; (void) dbprint_init (DBPRINT_FILE, 0, 0, 0, progname); (void) dbprint_set_file (getenv ("XCLSTAT_LOGFILE"), stderr); while (EOF != (opt = getopt (argc, argv, "sc:n:D:I:r:"))) { switch (opt) { case 'c': ATOI (optarg, clusterid); break; case 'n': clustername = optarg; break; case 'D': ATOI (optarg, debug_level); break; case 'I': ATOI (optarg, info_level); break; case 'r': ATOI (optarg, appRes.cr_refreshInterval); rflagn = 0; break; case 's': ALLSERVICES = 1; break; default: Usage (); break; } } (void) dbprint_set_levels (debug_level, 0, info_level); /* Create the topLevel widget, parent to everyone. */ topLevel = XtInitialize (progname, "Xclstat", 0, 0, 0, 0); putWidget ("topLevel", topLevel); #ifdef SUPPORT_EDITRES XtAddEventHandler(topLevel, (EventMask) 0, True, (XtEventHandler) _XEditResCheckMessages, NULL); #endif /* set offsets */ SetOffset (0, cr_background); SetOffset (1, cr_foreground); SetOffset (2, cr_borderWidth); SetOffset (3, cr_reverseVideo); SetOffset (4, cr_upColor); SetOffset (5, cr_downColor); SetOffset (6, cr_fluxColor); if(rflagn) { SetOffset (7, cr_refreshInterval); } SetOffset (8, cr_helpFile); xargc = 0; XtGetApplicationResources (topLevel, &appRes, appResourceList, XtNumber(appResourceList), xargv, xargc); if (appRes.cr_reverseVideo) { save_pix = appRes.cr_foreground; appRes.cr_foreground = appRes.cr_background; appRes.cr_background = save_pix; } vistemp.visual = DefaultVisualOfScreen(DefaultScreenOfDisplay(XtDisplay(topLevel))); vistemp.visualid = XVisualIDFromVisual(vistemp.visual); visp = XGetVisualInfo(XtDisplay(topLevel), VisualIDMask, &vistemp, &visnum); if((visp->class == StaticGray) || (visp->class == GrayScale)) { XParseColor(XtDisplay(topLevel), DefaultColormapOfScreen(DefaultScreenOfDisplay(XtDisplay(topLevel))), "gray80", &color); XAllocColor(XtDisplay(topLevel), DefaultColormapOfScreen(DefaultScreenOfDisplay(XtDisplay(topLevel))), &color); appRes.cr_downColor = color.pixel; XParseColor(XtDisplay(topLevel), DefaultColormapOfScreen(DefaultScreenOfDisplay(XtDisplay(topLevel))), "gray30", &color); XAllocColor(XtDisplay(topLevel), DefaultColormapOfScreen(DefaultScreenOfDisplay(XtDisplay(topLevel))), &color); appRes.cr_upColor = color.pixel; XParseColor(XtDisplay(topLevel), DefaultColormapOfScreen(DefaultScreenOfDisplay(XtDisplay(topLevel))), "gray50", &color); XAllocColor(XtDisplay(topLevel), DefaultColormapOfScreen(DefaultScreenOfDisplay(XtDisplay(topLevel))), &color); appRes.cr_fluxColor = color.pixel; } if (appRes.cr_refreshInterval <= 0) { appRes.cr_refreshInterval = 100; } /* initialize clinfo library and determine cluster ID of cluster to monitor. */ if(0 != clstat_init (clusterid, clustername)) exit (-1); /* set icon name */ xargc = 0; XtSetValues (topLevel, xargv, xargc); /* top level form widget */ xargc = 0; frame = XtCreateWidget ("frame", xmFormWidgetClass, topLevel, xargv, xargc); putWidget ("frame", frame); create_top (frame); create_nodemap (frame); create_bottom (frame); XtManageChild (frame); XtRealizeWidget (topLevel); refreshMap (NULL, NULL, FALSE); XtMainLoop(); } /* ** |--------------------------------------| ** | | ** | |--------------------------------| | ** | | PREV | CLUSTER NAME: ID | NEXT | | ** | |--------------------------------| | ** | | ** |--------------------------------------| **/ void create_top (Widget parent) { char title[128]; Widget topControl; Widget prevButton; Widget titleLabel; Widget nextButton; /* control panel */ xargc = 0; topControl = XtCreateManagedWidget ("topControl", xmFormWidgetClass, parent, xargv, xargc); putWidget ("topControl", topControl); /* prev button */ xargc = 0; XtSetArg (xargv[xargc], XmNuserData, strdup("prevButton")); xargc++; prevButton = XtCreateManagedWidget ("prevButton", xmLabelWidgetClass, topControl, xargv, xargc); putWidget ("prevButton", prevButton); XtAddActions (prevClusterAction, XtNumber(prevClusterAction)); XtAugmentTranslations (prevButton, XtParseTranslationTable(prevClusterTable)); XtAddEventHandler (prevButton, EnterWindowMask, FALSE, highlight, NULL); XtAddEventHandler (prevButton, LeaveWindowMask, FALSE, unHighlight, NULL); /* cluster name and id */ xargc = 0; titleLabel = XtCreateManagedWidget ("titleLabel", xmLabelWidgetClass, topControl, xargv, xargc); putWidget ("titleLabel", titleLabel); XtAddActions (titleAction, XtNumber(titleAction)); XtAugmentTranslations (titleLabel, XtParseTranslationTable(titleTable)); /* next button */ xargc = 0; XtSetArg (xargv[xargc], XmNuserData, strdup("nextButton")); xargc++; nextButton = XtCreateManagedWidget ("nextButton", xmLabelWidgetClass, topControl, xargv, xargc); putWidget ("nextButton", nextButton); XtAddActions (nextClusterAction, XtNumber(nextClusterAction)); XtAugmentTranslations (nextButton, XtParseTranslationTable(nextClusterTable)); XtAddEventHandler (nextButton, EnterWindowMask, FALSE, highlight, NULL); XtAddEventHandler (nextButton, LeaveWindowMask, FALSE, unHighlight, NULL); return; } /* ** |------------------------------| ** | | ** | |------------------------| | ** | | 1 | 2 | 3 | 4 | 5 | | ** | |------------------------| | ** | | 6 | 7 | 8 | 9 | 10 | | ** | |------------------------| | ** | | 11 | 12 | 13 | 14 | 15 | | ** | |------------------------| | ** | | ** |------------------------------| */ void create_nodemap (Widget parent) { int top; int bottom; int left; int right; int rows; int section; int n; char label[128]; char TableBuf [128]; Widget nodeMap; Widget entry; xargc = 0; nodeMap = XtCreateManagedWidget ("nodeMap", xmFormWidgetClass, parent, xargv, xargc); putWidget ("nodeMap", nodeMap); rows = 1; while (CL_MAXNODES > (rows * rows)) rows++; section = 100/rows; for (n = 0; n < CL_MAXNODES; n++) { ITOA (n, label); top = (section * (n/rows)) + 1; bottom = (section * (n/rows)) + section - 1; left = (section * (n%rows)) + 1; right = (section * (n%rows)) + section - 1; xargc = 0; XtSetArg (xargv[xargc], XmNtopPosition, top); xargc++; XtSetArg (xargv[xargc], XmNbottomPosition, bottom); xargc++; XtSetArg (xargv[xargc], XmNleftPosition, left); xargc++; XtSetArg (xargv[xargc], XmNrightPosition, right); xargc++; XtSetArg (xargv[xargc], XmNuserData, strdup(label)); xargc++; entry = XtCreateManagedWidget (label, xmLabelWidgetClass, nodeMap, xargv, xargc); putWidget (label, entry); XtAddActions (viewNodeAction, XtNumber(viewNodeAction)); (void) sprintf (TableBuf, viewNodeTable, label); XtAugmentTranslations (entry, XtParseTranslationTable(TableBuf)); XtAddEventHandler (entry, EnterWindowMask, FALSE, highlight, NULL); XtAddEventHandler (entry, LeaveWindowMask, FALSE, unHighlight, NULL); } return; } /* ** |--------------------------------------------| ** | | ** | |--------------------------------------| | ** | | quitButton | dateWindow | helpButton | | ** | |--------------------------------------| | ** | | ** |--------------------------------------------| */ void create_bottom (Widget parent) { Widget bottomControl; Widget quitButton; Widget dateLabel; Widget helpButton; xargc = 0; bottomControl = XtCreateManagedWidget("bottomControl", xmFormWidgetClass, parent, xargv, xargc); putWidget ("bottomControl", bottomControl); xargc = 0; XtSetArg (xargv[xargc], XmNuserData, strdup("quitButton")); xargc++; quitButton = XtCreateManagedWidget("quitButton", xmLabelWidgetClass, bottomControl, xargv, xargc); putWidget ("quitButton", quitButton); XtAddActions (quitAction, XtNumber(quitAction)); XtAugmentTranslations (quitButton, XtParseTranslationTable(quitTable)); XtAddEventHandler (quitButton, EnterWindowMask, FALSE, highlight, NULL); XtAddEventHandler (quitButton, LeaveWindowMask, FALSE, unHighlight, NULL); xargc = 0; dateLabel = XtCreateManagedWidget("dateLabel", xmLabelWidgetClass, bottomControl, xargv, xargc); putWidget ("dateLabel", dateLabel); xargc = 0; XtSetArg (xargv[xargc], XmNuserData, strdup("helpButton")); xargc++; helpButton = XtCreateManagedWidget("helpButton", xmLabelWidgetClass, bottomControl, xargv, xargc); putWidget ("helpButton", helpButton); XtAddActions (helpAction, XtNumber(helpAction)); XtAugmentTranslations (helpButton, XtParseTranslationTable(helpTable)); XtAddEventHandler (helpButton, EnterWindowMask, FALSE, highlight, NULL); XtAddEventHandler (helpButton, LeaveWindowMask, FALSE, unHighlight, NULL); return; } /* * NAME: create_textbuf * * Format a text buffer with the node, interface and resource group information * for a specific cluster and node. * * NOTE: it is the caller's responsibility to free the storage alloced here * * Arguments * clusterid - desired cluster * index - index of node withing map * * Returns * A formatted char buffer */ static char *create_textbuf (int clusterid, int index) { int i; int clstatus; struct cl_node *nodebuf; int nbr_groups; int nbr_nodes; int tnode, tif; char textBuf[4096]; char *bufp; char primaryNodeName[CL_MAXNAMELEN]; static struct cl_group *groupmap; static int group_map_alloced = 0; if (group_map_alloced ==0) { cl_alloc_groupmap(&groupmap); group_map_alloced = 1; } memset(textBuf, '\0', 4096); nodebuf = &pNodeMap[index]; bufp = textBuf; (void) sprintf(bufp, "%s %s\n", MSGSTR(CLSTAT_NODE,"\nCluster Node"), nodebuf->cln_nodename); bufp += strlen(bufp); if (CLS_UP == nodebuf->cln_state) { (void) sprintf(bufp, MSGSTR(CLSTAT_STATE_STRING, "State = %s\n"), MSGSTR(CLSTAT_STATE_UP, "UP")); } else if (CLS_DOWN == nodebuf->cln_state) { (void) sprintf(bufp, MSGSTR(CLSTAT_STATE_STRING, "State = %s\n"), MSGSTR(CLSTAT_STATE_DOWN, "DOWN")); } else if (CLS_JOINING == nodebuf->cln_state) { (void) sprintf(bufp, MSGSTR(CLSTAT_STATE_STRING, "State = %s\n"), MSGSTR(CLSTAT_STATE_JOINING, "JOINING")); } else if (CLS_LEAVING == nodebuf->cln_state) { (void) sprintf(bufp, MSGSTR(CLSTAT_STATE_STRING, "State = %s\n"), MSGSTR(CLSTAT_STATE_LEAVING, "LEAVING")); } bufp += strlen(bufp); for (i = 0; nodebuf->cln_nif > i; i++) { /* only display boot and standby here (service will be displayed below) */ if ((nodebuf->cln_if[i].cli_role != CL_INT_ROLE_BOOT && nodebuf->cln_if[i].cli_role != CL_INT_ROLE_STANDBY)) continue; (void) sprintf (bufp, MSGSTR(CLSTAT_NAME_ADDRESS, "\nname: %s (%s)\naddress: %s\n"), nodebuf->cln_if[i].cli_name, get_state(nodebuf->cln_if[i].cli_state), inet_ntoa (nodebuf->cln_if[i].cli_addr.sin_addr.s_addr)); bufp += strlen(bufp); } /* * We have displayed the all the boot interfaces, now look * for any service labels which may be up on this node. * Note that we look at all services on all nodes since * there could be a takeover label currently on this node. */ nbr_nodes = cl_getnodemap(clusterid, pNodeMap); for(tnode=0; tnode < nbr_nodes; tnode++) { for(tif=0; tifcln_nodeid) || (pNodeMap[tnode].cln_if[tif].cli_active_nodeid == nodebuf->cln_nodeid)) { /* its active on this node, but only display once if its shared. We cant rely on the role of service/shared unfortunately because ipat via aliasing treats both equally - instead we will look for it on the local node and skip displaying it here */ if (ifs_is_shared(pNodeMap, nbr_nodes, &pNodeMap[tnode].cln_if[tif]) && tnode != index) continue; (void) sprintf (bufp, MSGSTR(CLSTAT_NAME_ADDRESS, "\nname: %s (%s)\naddress: %s\n"), pNodeMap[tnode].cln_if[tif].cli_name, get_state(pNodeMap[tnode].cln_if[tif].cli_state), inet_ntoa (pNodeMap[tnode].cln_if[tif].cli_addr.sin_addr.s_addr)); bufp += strlen(bufp); } } /* for tif */ } /* for tnode */ nbr_groups = cl_getgroupmap(clusterid, groupmap); dbprintf (20, "create_textbuf: cl_getgroupmap returned %d groups\n", nbr_groups); if(nbr_groups > 0 && nbr_groups < CL_MAXGROUPS) { for(i=0; icln_nodeid)) { sprintf(bufp, MSGSTR(CLSTAT_RESOURCE_GROUP, "\nResource Group: %s\tState: %s\n"), groupmap[i].clg_name, resourceStateStr(&groupmap[i], nodebuf->cln_nodeid)); dbprintf (20, "adding [%s] to textBuf\n",bufp); bufp += strlen(bufp); } } } dbprintf (20, "create_textbuf: %s", textBuf); return (strdup (textBuf)); } void refreshMap (Widget widget, caddr_t closure, int timerfired) { int c, i, j; int n; int clstatus; int numClusters; int num_nodes; static int first_time = 1; char date[CL_MAXNAMELEN]; char label[CL_MAXNAMELEN]; char title[CL_MAXNAMELEN]; char *bufp; char **oldNodes; struct cl_cluster clusterBuf; /* new cluster information buffer */ struct cl_node nodebuf; /* new node information buffer */ static char oldDate [32]; /* date currently displayed in window */ static int refreshTimer = -1; /* timer set flag -1 = no */ Widget nodeMapParent; WidgetList wl; int nw; Pixel defBgColor; XmString str; Widget w; /* * initialize the array of old nodes */ if (0 == (oldNodes = (char **)malloc(CL_MAXNODES * sizeof(char *)))) { exit (-1); } for (n = 0; n < CL_MAXNODES; n++) { oldNodes[n] = (char *)NULL; } /* * always allocate memory for the "new" map, newMap */ if (first_time) { cl_alloc_clustermap(&clusterMap); cl_alloc_nodemap(&pNodeMap); if (clusterMap == (struct cl_cluster *)NULL || pNodeMap == (struct cl_node *)NULL) { dbprintf (0, "refreshMap: cl_alloc problem.\n"); exit (-1); } first_time = 0; } /* * if this call was not caused by the timer going off clear it so there are * no interruptions */ if (-1 != refreshTimer && ! timerfired) XtRemoveTimeOut (refreshTimer); refreshTimer = -1; /* * update the date in the xclstat window if necessary */ (void) mkdatestr (date); if (0 != mbscmp (oldDate, date)) { w = NULL; w = getWidgetByLabel ("dateLabel"); if (w != NULL) { xargc = 0; str = XmStringCreate (date, XmSTRING_DEFAULT_CHARSET); XtSetArg (xargv[xargc], XmNlabelString, str); xargc++; XtSetValues (w, xargv, xargc); XmStringFree(str); mbscpy (oldDate, date); } } /* * read in the cluster specific information, name, id, state.. */ clstatus = cl_getcluster (CL_cid, & clusterBuf); if (CLE_OK != clstatus) { strcpy (clusterBuf.clc_name, "NoName"); dbprintf (10, "refreshMap: cl_getcluster (%d): %s.\n", CL_cid, cl_errmsg(clstatus)); } /* * always update the cluster information */ xargc = 0; memset(title, '\0', CL_MAXNAMELEN); (void) sprintf (title, "%s: %d", clusterBuf.clc_name, CL_cid); str = XmStringCreate (title, XmSTRING_DEFAULT_CHARSET); XtSetArg (xargv[xargc], XmNlabelString, str); xargc++; if (CLSS_STABLE == clusterBuf.clc_substate) { XtSetArg(xargv[xargc], XmNbackground, appRes.cr_upColor); xargc++; } else if (CLSS_UNSTABLE == clusterBuf.clc_substate) { XtSetArg(xargv[xargc], XmNbackground, appRes.cr_fluxColor); xargc++; } else if (CLSS_RECONFIG == clusterBuf.clc_substate) { XtSetArg(xargv[xargc], XmNbackground, appRes.cr_fluxColor); xargc++; } else { XtSetArg(xargv[xargc], XmNbackground, appRes.cr_downColor); xargc++; } w = getWidgetByLabel ("titleLabel"); if (w != NULL) { XtSetValues (getWidgetByLabel ("titleLabel"), xargv, xargc); setWidgetTag("titleLabel", title); XmStringFree(str); } /* * read in the list of nodes from the new map and compare them with the old * map, the only thing compared here is the state of the node, and if there * are any differences copy the new information to the current. */ num_nodes = cl_getnodemap(CL_cid, pNodeMap); /* If we make it here, node info changed. Update all nodes. */ for (n = 0; n < num_nodes; n++) { ITOA (n, label); strcpy(title, pNodeMap[n].cln_nodename); xargc = 0; if (CLS_UP == pNodeMap[n].cln_state) { XtSetArg (xargv[xargc], XmNbackground, appRes.cr_upColor); xargc++; } else if (CLS_DOWN == pNodeMap[n].cln_state) { XtSetArg (xargv[xargc], XmNbackground, appRes.cr_downColor); xargc++; } else if ((CLS_LEAVING == pNodeMap[n].cln_state) || (CLS_JOINING == pNodeMap[n].cln_state)) { XtSetArg(xargv[xargc], XmNbackground, appRes.cr_fluxColor); xargc++; } else { XtSetArg (xargv[xargc], XmNbackground, appRes.cr_background); xargc++; } str = XmStringCreate (title, XmSTRING_DEFAULT_CHARSET); XtSetArg (xargv[xargc], XmNlabelString, str); xargc++; if (getWidgetByLabel(label) == (Widget)NULL) { printf("clstat internal error. Can't get widget with label %s.\n", label); exit(-1); } XtSetValues(getWidgetByLabel(label), xargv, xargc); getWidgetTag(label, &oldNodes[n]); setWidgetTag(label, title); XmStringFree(str); } /* end for each node */ /* * Blank out any remaining nodes that may be set from a previous * cluster map */ nodeMapParent = getWidgetByLabel("nodeMap"); if (nodeMapParent == (Widget)NULL) { printf("clstat internal error. Can't get nodeMapParent widget.\n"); exit (0); } XtVaGetValues (nodeMapParent, XmNnumChildren, &nw, XmNchildren, &wl, XmNbackground, &defBgColor, NULL); str = XmStringCreateSimple (""); for (j = n; j < nw; j++) { XtVaSetValues (wl[j], XmNbackground, defBgColor, XmNlabelString, str, NULL); ITOA (j, label); getWidgetTag(label, &oldNodes[j]); setWidgetTag(label, (char *)NULL); } XmStringFree(str); /* * remove the interface windows for the nodes that have been deleted */ for (n = 0; ((n < nw) && ((char *)NULL != oldNodes[n])); n++) { if ((char *)NULL == getWidgetByTag(oldNodes[n])) { (void) sprintf (label, "%dNode%s", CL_cid, oldNodes[n]); while ((char *)NULL != getWidgetByTag(label)) { delWidgetByTag(label); } } free (oldNodes[n]); } free ((char*)oldNodes); /* * update all the interface windows */ numClusters = cl_getclusters(clusterMap); for (c = 0; c < numClusters; c++) { for (n = 0; n < num_nodes; n++) { (void) sprintf (label, "%dtext%s", clusterMap[c].clc_clusterid, pNodeMap[n].cln_nodename); if ((Widget)NULL != getWidgetByLabel (label)) { bufp = create_textbuf (clusterMap[c].clc_clusterid, n); /* pNodeMap[n].cln_nodename); */ if ((char *)NULL == bufp) { dbperror (0, "refreshMap: malloc"); } else { XmTextSetString (getWidgetByLabel (label), bufp); free (bufp); } } } } refreshTimer = XtAddTimeOut (appRes.cr_refreshInterval*100, refreshMap, TRUE); return; } /* end refreshMap */ struct widgetList *widgetHead = (struct widgetList *)NULL; void putWidget (char *label, Widget widget) { struct widgetList *newp; newp = (struct widgetList*) malloc (sizeof (struct widgetList)); if ((struct widgetList *)NULL == newp) { dbperror (0, "malloc"); return; } dbprintf(10, "putWidget: adding widget XtName=%s XtClass=%s label=%s widget=%08X list=%08X\n", XtName(widget), XtClassName(widget), label, widget, newp); /* insert at top of list */ newp->wl_label = strdup (label); newp->wl_widget = widget; newp->wl_tag = (char *)NULL; newp->wl_next = widgetHead; widgetHead = newp; return; } Widget getWidgetByLabel (char *label) { struct widgetList *currp; for (currp = widgetHead; currp != (struct widgetList *)NULL; currp = currp->wl_next) { if (0 == strcmp (label, currp->wl_label)) return (currp->wl_widget); } dbprintf (10, "getWidgetByLabel: widget %s not found.\n", label); return (NULL); } Widget getWidgetByTag (char *tag) { struct widgetList *currp; for (currp = widgetHead; currp != (struct widgetList *)NULL; currp = currp->wl_next) { if (0 == strcmp (tag, currp->wl_tag)) return (currp->wl_widget); } dbprintf (10, "getWidgetByTag: widget %s not found.\n", tag); return (NULL); } void setWidgetTag (char *label, char *tag) { struct widgetList *currp; dbprintf(20, "setWidgetTag: set widget %s tag to %s\n", label, tag); for (currp = widgetHead; currp != (struct widgetList *)NULL; currp = currp->wl_next) { if (0 == strcmp (label, currp->wl_label)) { if ((char *)NULL != currp->wl_tag) { free ((char*)currp->wl_tag); } if ((char *)NULL == (currp->wl_tag = strdup (tag))) { dbprintf(30, "setWidgetTag: strdup failed\n"); } return; } } dbprintf (10, "setWidgetTag: widget %s not found.\n", label); return; } void getWidgetTag (char *label, char **tag) { struct widgetList *currp; dbprintf(20, "getWidgetTag: get title for widget %s\n", label); for (currp = widgetHead; currp != (struct widgetList *)NULL; currp = currp->wl_next) { if (0 == strcmp (label, currp->wl_label)) { if ((char *)NULL == (*tag = strdup(currp->wl_tag))) { dbprintf(30, "getWidgetTag: strdup failed\n"); } return; } } dbprintf (10, "getWidgetTag: widget %s not found.\n", label); *tag = NULL; return; } #ifdef SUPPORT_DELETE_BY_LABEL void delWidgetByLabel (char *label) { struct widgetList *prevp; struct widgetList *currp; dbprintf(10, "delWidgetByLabel: deleting widgets with label %s\n", label); prevp = (struct widgetList *)NULL; currp = widgetHead; while ((struct widgetList *)NULL != currp) { if (0 == strcmp (label, currp->wl_label)) { if (prevp == (struct widgetList *)NULL) { widgetHead = currp->wl_next; } else { prevp->wl_next = currp->wl_next; } dbprintf(20, "delWidgetByLabel: deleting widget %s with tag %s\n", currp->wl_label, currp->wl_tag); free (currp->wl_label); free (currp->wl_tag); XtDestroyWidget (currp->wl_widget); free ((char*)currp); return; } prevp = currp; currp = currp->wl_next; } dbprintf (10, "delWidgetByLabel: widget %s not found.\n", label); return; } /* end delWidgetByLabel */ #endif /* * A crash occurs when CRASH is defined. I'm unsure whether this is the * correct behavior or not for the compiler. Also, if the code is compiled * with -g crashes do not occur. * * It appears that when *str is not set to NULL a previous value is being * taken from the stack as an assignment. The end result is that the toplevel * widget for the entire application gets destroyed, which in turn destroys * every widget in the tree. After that, all is lost... * * #define CRASH * */ void delWidgetByTag (char *tag) { struct widgetList *prevp; struct widgetList *currp; #ifdef CRASH char *str; #else char *str = NULL; #endif dbprintf(10, "delWidgetByTag: searching for widget with tag=%s str=<%s>\n", tag, str); #ifdef CRASH if (strlen(str) != 0) { printf("\n\n<<<<<=====>>>>>strlen(str) is %d <%s>\n\n\n",strlen(str),str); } #endif prevp = (struct widgetList *)NULL; currp = widgetHead; while ((struct widgetList *)NULL != currp) { if (0 == strcmp (tag, currp->wl_tag)) { if (prevp == (struct widgetList *)NULL) { widgetHead = currp->wl_next; } else { prevp->wl_next = currp->wl_next; } dbprintf(15, "delWidgetByTag: deleting widget label=%s tag=%s XtName=%s XtClass=%s widget=%08X list=%08X\n", currp->wl_label, currp->wl_tag, XtName(currp->wl_widget), XtClassName(currp->wl_widget), currp->wl_widget, currp); #ifdef CRASH if (strlen(str) != 0) { printf("strlen(str) is %d <%s>\n",strlen(str),str); } #endif xargc = 0; XtSetArg(xargv[xargc], XmNuserData, &str); xargc++; #ifdef CRASH if (strlen(str) != 0) { printf("strlen(str) is %d <%s>\n",strlen(str),str); } #endif XtGetValues(currp->wl_widget,xargv,xargc); #ifdef CRASH if (strlen(str) != 0) { printf("strlen(str) is %d <%s>\n",strlen(str),str); } #endif dbprintf(20, "delWidgetByTag: delete XmNuserData - %s <%s>\n", XtName(currp->wl_widget), str); #ifdef CRASH if (strlen(str) != 0) { printf("strlen(str) is %d <%s>\n",strlen(str),str); } #endif if (str != NULL && *str != NULL) { free(str); } free(currp->wl_label); free(currp->wl_tag); XtDestroyWidget (currp->wl_widget); free((char*)currp); return; } prevp = currp; currp = currp->wl_next; } dbprintf (10, "delWidgetByTag: widget %s not found.\n", tag); return; } /* end delWidgetByTag */ void freeWidgetList () { struct widgetList *savep; while ((struct widgetList *)NULL != widgetHead) { savep = widgetHead->wl_next; if (widgetHead->wl_label) free (widgetHead->wl_label); if (widgetHead->wl_tag) free (widgetHead->wl_tag); XtDestroyWidget (widgetHead->wl_widget); free ((char*)widgetHead); widgetHead = savep; } return; } void prevCluster (Widget widget, XEvent *event, char **params, int *num_params) { int i; int start, end; int numClusters; struct cl_cluster *clusterMap; if (cl_alloc_clustermap(&clusterMap) == -1) { dbprintf (0, "prevCluster: cl_alloc problem.\n"); exit (-1); } numClusters = cl_getclusters (clusterMap); if (0 < numClusters) { for (i = numClusters - 1; i >= 0; i--) { if (CL_cid == clusterMap[i].clc_clusterid) { end = i; start = end == 0 ? (numClusters - 1) : (end - 1); break; } } if (0 > i) { end = 0; start = numClusters - 1; CL_cid = clusterMap[start].clc_clusterid; } for (i = start; end != i; i = i == 0 ? (numClusters - 1) : (i - 1)) { if (CLS_UP == clusterMap[i].clc_state) { CL_cid = clusterMap[i].clc_clusterid; refreshMap (NULL, NULL, FALSE); cl_free_clustermap(clusterMap); return; } } } dbprintf (10, "prevCluster: no previous cluster defined.\n"); cl_free_clustermap(clusterMap); return; } void nextCluster (Widget widget, XEvent *event, char **params, int *num_params) { int i; int start, end; int numClusters; struct cl_cluster *clusterMap; if (cl_alloc_clustermap(&clusterMap) == -1) { dbprintf (0, "nextCluster: cl_alloc problem.\n"); exit (-1); } numClusters = cl_getclusters (clusterMap); if (0 < numClusters) { for (i = 0; i < numClusters; i++) { if (CL_cid == clusterMap[i].clc_clusterid) { end = i; start = end == (numClusters - 1) ? 0 : (end + 1); break; } } if (i == numClusters) { end = numClusters - 1; start = 0; CL_cid = clusterMap[start].clc_clusterid; } for (i = start; end != i; i = i == (numClusters - 1) ? 0 : (i + 1)) { if (CLS_UP == clusterMap[i].clc_state) { CL_cid = clusterMap[i].clc_clusterid; refreshMap (NULL, NULL, FALSE); cl_free_clustermap(clusterMap); return; } } } dbprintf (10, "nextCluster: no next cluster defined.\n"); cl_free_clustermap(clusterMap); return; } void viewNode (Widget widget, XEvent *event, char **params, int *num_params) { int clstatus; char shellLabel[64]; char frameLabel[64]; char scrollLabel[64]; char textLabel[64]; char quitLabel[64]; char name[64]; char tmp[64]; char label[64]; int nodeid; char tableBuf[64]; char *nodename; char *bufp; int i, nbr_nodes; Widget nodeShell; Widget nodeFrame; Widget nodeScroll; Widget nodeText; Widget nodeQuit; Widget w; dbprintf(10, ">>>viewNode: entering viewNode()\n"); strcpy(label, params[0]); getWidgetTag(label, &nodename); /* find the node index from the name */ nbr_nodes = cl_getnodemap(CL_cid, pNodeMap); for (i = 0; i < nbr_nodes; i++) if (!strcmp(nodename, pNodeMap[i].cln_nodename)) break; /* if already created just popit up */ (void) sprintf (shellLabel, "%dNode%s", CL_cid, nodename); nodeShell = getWidgetByLabel (shellLabel); if((Widget)NULL != nodeShell) { XtPopup (nodeShell, XtGrabNone); XtMapWidget (nodeShell); free (nodename); return; } /* format variable strings */ (void) sprintf (name, "%s: %d, %s", progname, CL_cid, nodename); (void) sprintf (frameLabel, "%dframe%s", CL_cid, nodename); (void) sprintf (scrollLabel, "%dscroll%s", CL_cid, nodename); (void) sprintf (textLabel, "%dtext%s", CL_cid, nodename); (void) sprintf (quitLabel, "%dquit%s", CL_cid, nodename); /* create the data for this node */ bufp = create_textbuf (CL_cid, i); if ((char *)NULL == bufp) { dbprintf(20, "viewNode: error from create_textbuf()\n"); free (nodename); return; } xargc = 0; XtSetArg (xargv[xargc], XmNtitle, name); xargc++; XtSetArg (xargv[xargc], XmNiconName, name); xargc++; nodeShell = XtCreatePopupShell ("nodeShell", wmShellWidgetClass, getWidgetByLabel("frame"), xargv, xargc); putWidget (shellLabel, nodeShell); setWidgetTag (shellLabel, shellLabel); nodeFrame = XtCreateWidget ("nodeFrame", xmFormWidgetClass, nodeShell, NULL, 0); putWidget (frameLabel, nodeFrame); setWidgetTag (frameLabel, shellLabel); nodeScroll = XtCreateManagedWidget ("nodeScroll", xmScrolledWindowWidgetClass, nodeFrame, NULL, 0); putWidget (scrollLabel, nodeScroll); setWidgetTag (scrollLabel, shellLabel); nodeText = XtCreateManagedWidget ("nodeText", xmTextWidgetClass, nodeScroll, NULL, 0); putWidget (textLabel, nodeText); setWidgetTag (textLabel, shellLabel); XmTextSetString (nodeText, bufp); xargc=0; XtSetArg (xargv[xargc], XmNuserData, strdup(quitLabel)); xargc++; nodeQuit = XtCreateManagedWidget ("nodeQuit", xmLabelWidgetClass, nodeFrame, xargv, xargc); putWidget (quitLabel, nodeQuit); setWidgetTag (quitLabel, shellLabel); XtAddActions (quitPopupAction, XtNumber(quitPopupAction)); (void) sprintf (tableBuf, quitPopupTable, shellLabel); XtAugmentTranslations (nodeQuit, XtParseTranslationTable(tableBuf)); dbprintf(10, "viewNode: nodeQuit=%08X %s %s\n",nodeQuit, XtName(nodeQuit), quitLabel); XtAddEventHandler (nodeQuit, EnterWindowMask, FALSE, highlight, NULL); XtAddEventHandler (nodeQuit, LeaveWindowMask, FALSE, unHighlight, NULL); XtManageChild (nodeFrame); XtRealizeWidget (nodeShell); XtPopup (nodeShell, XtGrabNone); free (bufp); free (nodename); return; } void quit (Widget widget, XEvent *event, char **params, int *num_params) { freeWidgetList (); exit (0); } void title (Widget widget, XEvent *event, char **params, int *num_params) { refreshMap (NULL, NULL, FALSE); return; } void quitPopup (Widget widget, XEvent *event, char **params, int *num_params) { dbprintf(10, "quitPopup: quiting pop up widget <%s>\n", params[0]); XtPopdown (getWidgetByLabel (params[0])); while ((char *)NULL != getWidgetByTag(params[0])) { delWidgetByTag(params[0]); } return; } void help (Widget widget, XEvent *event, char **params, int *num_params) { char name [64]; char tableBuf[64]; char *bufp; Widget helpShell; Widget helpFrame; Widget helpText; Widget helpScroll; Widget helpQuit; /* if already created just popit up */ helpShell = getWidgetByLabel ("helpShell"); if((Widget)NULL != helpShell) { XtPopup (helpShell, XtGrabNone); return; } bufp = create_helptext (appRes.cr_helpFile); if (bufp == (char *)NULL) { return; } xargc = 0; helpShell = XtCreatePopupShell ("helpShell", wmShellWidgetClass, getWidgetByLabel("frame"), xargv, xargc); putWidget ("helpShell", helpShell); (void) sprintf (name, "%s: help window", progname); xargc = 0; XtSetArg (xargv[xargc], XmNtitle, name); xargc++; XtSetArg (xargv[xargc], XmNiconName, name); xargc++; XtSetValues (helpShell, xargv, xargc); xargc = 0; helpFrame = XtCreateWidget ("helpFrame", xmFormWidgetClass, helpShell, xargv, xargc); putWidget ("helpFrame", helpFrame); xargc = 0; helpScroll = XtCreateManagedWidget ("helpScroll", xmScrolledWindowWidgetClass, helpFrame, xargv, xargc); putWidget ("helpScroll", helpScroll); xargc = 0; helpText = XtCreateManagedWidget ("helpText", xmTextWidgetClass, helpScroll, xargv, xargc); putWidget ("helpText", helpText); XmTextSetString (helpText, bufp); xargc = 0; XtSetArg (xargv[xargc], XmNuserData, strdup("helpQuit")); xargc++; helpQuit = XtCreateManagedWidget ("helpQuit", xmLabelWidgetClass, helpFrame, xargv, xargc); putWidget ("helpQuit", helpQuit); XtAddActions (quitPopupAction, XtNumber(quitPopupAction)); (void) sprintf (tableBuf, quitPopupTable, "helpShell"); XtAugmentTranslations (helpQuit, XtParseTranslationTable(tableBuf)); XtAddEventHandler (helpQuit, EnterWindowMask, FALSE, highlight, NULL); XtAddEventHandler (helpQuit, LeaveWindowMask, FALSE, unHighlight, NULL); XtManageChild (helpFrame); XtRealizeWidget (helpShell); XtPopup (helpShell, XtGrabNone); free (bufp); return; } int clstat_init (int clusterid, char *clustername) { int c; int counter = 0; int clstatus; FILE* fp; char *returnval=NULL; char check_main_mib[512]="grep \"^VACM_VIEW *defaultView *internet.*- *included *-\" /etc/snmpdv3.conf 2>/dev/null"; char check_sub_mib[512]="grep \"^VACM_VIEW *defaultView *1.3.6.1.4.1.2.3.1.2.1.5 *- *included *-\" /etc/snmpdv3.conf 2>/dev/null"; char output_array[512]; char search_string[15]="VACM_VIEW"; struct cl_cluster *clmap; clstatus = cl_initialize (); if (CLE_OK != clstatus) { dbprintf (0, "%s: cl_initialize (): %s\n", progname, cl_errmsg(clstatus)); return (-1); } if ((char *)NULL != clustername) { clstatus = cl_getclusterid (clustername); if (0 > clstatus) { dbprintf (0, "%s: cl_getclusterid(%s): %s\n", progname, clustername, cl_errmsg(clstatus)); return (-1); } CL_cid = clstatus; } else if (0 != clusterid) { if (! ISUPCLUSTER (clusterid)) { dbprintf (0, "%d: Is not up or is an invalid cluster id.\n", clusterid); return (-1); } CL_cid = clusterid; } else { if(cl_alloc_clustermap(&clmap) == -1) { dbprintf (0, "clstat_init: cl_alloc problem.\n"); return(-1); } clstatus = cl_getclusters (clmap); if (0 > clstatus) { printf(MSGSTR(CLSTAT_CHECK_CLINFO_1, "Failed retrieving cluster information.\n\n\ There are a number of possible causes:\n\ clinfoES or snmpd subsystems are not active.\n\ snmp is unresponsive.\n\ snmp is not configured correctly.\n\ Cluster services are not active on any nodes.\n\n\ Refer to the HACMP Administration Guide for more information.\n")); cl_free_clustermap(clmap); #ifdef SNMP_CONF_CHECK output_array[0]=0; fp = popen(check_main_mib,"r"); if(fp == NULL) { return (-1); } else { returnval = fgets(output_array,512,fp); if (returnval != NULL) { /* Entry found so return */ pclose(fp); return (-1); } pclose(fp); fp = popen(check_sub_mib,"r"); if(fp == NULL) { return (-1); } else { returnval = NULL; output_array[0]=0; returnval = fgets(output_array,512,fp); if (returnval != NULL) { pclose(fp); return (-1); } dbprintf (0, "\nInternet MIB tree not enabled. Please refer the PowerHA \nreadme file for more information on how to enable it.\n"); pclose(fp); } } #endif return (-1); } /* set to first up, if none up set to first defined. */ for (c = 0; CL_MAXCLUSTERS > c; c++) { if (CLS_UP == clmap[c].clc_state) { CL_cid = clmap[c].clc_clusterid; break; } if (0 == CL_cid && ISDEFCLUSTER(clmap[c])) CL_cid = clmap[c].clc_clusterid; } cl_free_clustermap(clmap); } return (0); } void Usage () { fprintf(stderr, MSGSTR(CLSTAT_XUSAGE, "Usage: %s [-D debug_level] [-c Id | -n name] [-r #] [-s]\nWhere,\n"), progname); fprintf(stderr, MSGSTR(CLSTAT_xD_OPT, "\t-D debug_level Debug Level.\n")); fprintf(stderr, MSGSTR(CLSTAT_xc_OPT, "\t-c Id Cluster Id.\n")); fprintf(stderr, MSGSTR(CLSTAT_xn_OPT, "\t-n name Cluster name.\n")); fprintf(stderr, MSGSTR(CLSTAT_xr_OPT, "\t-r # Refresh interval in 10th of seconds.\n")); fprintf(stderr, MSGSTR(CLSTAT_xs_OPT, "\t-s Display both up and down service labels.\n")); exit (0); } size_t mkdatestr (char *date) { time_t curtime; size_t rc; curtime = time(0); rc = strftime(date, CL_MAXNAMELEN, nl_langinfo(D_T_FMT), (struct tm *)localtime(&curtime)); return rc; } #define THICK 3 void highlight (Widget widget, char *client, XEvent *event) { Position x, y; Dimension width, height; char *name; if (EnterNotify == event->type) { xargc = 0; XtSetArg (xargv[xargc], XmNuserData, &name); xargc++; XtGetValues(widget,xargv,xargc); xargc = 0; XtSetArg (xargv[xargc], XmNwidth, &width); xargc++; XtSetArg (xargv[xargc], XmNheight, &height); xargc++; XtSetArg (xargv[xargc], XmNx, &x); xargc++; XtSetArg (xargv[xargc], XmNy, &y); xargc++; XtGetValues (getWidgetByLabel(name), xargv, xargc); XtConfigureWidget (getWidgetByLabel(name), x, y, width - THICK, height - THICK, appRes.cr_borderWidth + THICK); dbprintf (20, "highlight: %s border increased by %d\n", name, THICK); } return; } void unHighlight (Widget widget, char *client, XEvent *event) { Position x, y; Dimension width, height; char *name; if (LeaveNotify == event->type) { xargc = 0; XtSetArg (xargv[xargc], XmNuserData, &name); xargc++; XtGetValues(widget,xargv,xargc); xargc = 0; XtSetArg (xargv[xargc], XmNwidth, &width); xargc++; XtSetArg (xargv[xargc], XmNheight, &height); xargc++; XtSetArg (xargv[xargc], XmNx, &x); xargc++; XtSetArg (xargv[xargc], XmNy, &y); xargc++; XtGetValues (getWidgetByLabel(name), xargv, xargc); XtConfigureWidget (getWidgetByLabel(name), x, y, width + THICK, height + THICK, appRes.cr_borderWidth); dbprintf (20, "unHighlight: %s border reset to %d\n", client, appRes.cr_borderWidth); } return; } char * create_helptext (char *helpfile) { int rcode; char *bufp; int fd; struct stat stbuf; if (-1 == stat (helpfile, &stbuf)) { dbprintf (0, "create_helptext: stat: "); dbperror (0, helpfile); return (NULL); } fd = open (helpfile, O_RDONLY); if (-1 == fd) { dbprintf (0, "create_helptext: open: "); dbperror (0, helpfile); return (NULL); } bufp = (char*)malloc (stbuf.st_size); if ((char *)NULL == bufp) { dbperror (0, "create_helptext: malloc"); return (NULL); } rcode = read (fd, bufp, stbuf.st_size); close (fd); if (stbuf.st_size != rcode) { dbprintf (0, "create_helptext: read: "); dbperror (0, helpfile); free (bufp); return (NULL); } return (bufp); } /* * Name: get_catd * * Description: return catalog file desciptor for the named catalog * * * Arguments: catalog name * * Return: file descriptor handle or CATD_ERR * * Global data affectec: none * */ static nl_catd get_catd(char *name) { nl_catd cat_id; if (! name || strlen (name) == 0) return(CATD_ERR); (void) setlocale(LC_ALL, ""); cat_id = catopen(name, 0); return(cat_id); }