The example program below shows the use of communications APIs to retrieve and display the names of the default (managing) system, along with all the systems that are configured in the active environment.
/******************************************************************* * * Module: * GETSYS.C * * Purpose: * This module is used to demonstrate how an application might use the * Communication API's. In this example, these APIs are used to get * and display the list of all configured systems. The user can then * select one, and that system's connection properties (the attributes * of the created system object) are displayed. All Client Access * services are then checked for connectabliity, and the results displayed. * * Usage Notes: * * Include CWBCO.H, CWBCOSYS.H, and CWBSV.H * Link with CWBAPI.LIB * * IBM grants you a nonexclusive license to use this as an example * from which you can generate similar function tailored to your own * specific needs. This sample is provided in the form of source * material which you may change and use. * If you change the source, it is recommended that you first copy the * source to a different directory. This will ensure that your changes * are preserved when the tool kit contents are changed by IBM. * * DISCLAIMER * ---------- * * This sample code is provided by IBM for illustrative purposes only. * These examples have not been thoroughly tested under all conditions. * IBM, therefore, cannot guarantee or imply reliability, * serviceability, or function of these programs. All programs * contained herein are provided to you "AS IS" without any warranties * of any kind. ALL WARRANTIES, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, ARE EXPRESSLY DISCLAIMED. * * Your license to this sample code provides you no right or licenses to * any IBM patents. IBM has no obligation to defend or indemnify against * any claim of infringement, including but not limited to: patents, * copyright, trade secret, or intellectual property rights of any kind. * * * * * * COPYRIGHT * --------- * 5722-XE1 (C) Copyright IBM CORP. 1996, 2004 * All rights reserved. * US Government Users Restricted Rights - * Use, duplication or disclosure restricted * by GSA ADP Schedule Contract with IBM Corp. * Licensed Material - Property of IBM * * *******************************************************************/ #include windows.h #include stdio.h #include "cwbsv.h" /* Service APIs for retrieving any FAILURE messages */ #include "cwbco.h" /* Comm APIs for enumerating systems configured */ #include "cwbcosys.h" /* Comm APIs for creating and using system objects */ #define SUCCESS (0) #define FAILURE (1) /* * Arrays of attribute description strings, for human-readable * display of these values. */ char* valModeStr[2] = { "CWBCO_VALIDATE_IF_NECESSARY" , "CWBCO_VALIDATE_ALWAYS" } ; char* promptModeStr[3] = { "CWBCO_PROMPT_IF_NECESSARY" , "CWBCO_PROMPT_ALWAYS" , "CWBCO_PROMPT_NEVER" } ; char* dfltUserModeStr[4] = { "CWBCO_DEFAULT_USER_MODE_NOT_SET" , "CWBCO_DEFAULT_USER_USE" , "CWBCO_DEFAULT_USER_IGNORE" , "CWBCO_DEFAULT_USER_USEWINLOGON", "CWBCO_DEFAULT_USER_USE_KERBEROS" } ; char* IPALModeStr[6] = { "CWBCO_IPADDR_LOOKUP_ALWAYS" , "CWBCO_IPADDR_LOOKUP_1HOUR" , "CWBCO_IPADDR_LOOKUP_1DAY" , "CWBCO_IPADDR_LOOKUP_1WEEK" , "CWBCO_IPADDR_LOOKUP_NEVER" , "CWBCO_IPADDR_LOOKUP_AFTER_STARTUP" } ; char* portLookupModeStr[3] = { "CWBCO_PORT_LOOKUP_SERVER" , "CWBCO_PORT_LOOKUP_LOCAL" , "CWBCO_PORT_LOOKUP_STANDARD" } ; char* cwbBoolStr[2] = { "False", "True" } ; /* NOTE! The corresponding service CONSTANT integers start * at 1, NOT at 0; that is why the dummy "FAILURE" value * was added at position 0. */ char* serviceStr[15] = { "CWBCO_SERVICE_THISISABADSERVICE!", "CWBCO_SERVICE_CENTRAL" , "CWBCO_SERVICE_NETFILE" , "CWBCO_SERVICE_NETPRINT" , "CWBCO_SERVICE_DATABASE" , "CWBCO_SERVICE_ODBC" , "CWBCO_SERVICE_DATAQUEUES" , "CWBCO_SERVICE_REMOTECMD" , "CWBCO_SERVICE_SECURITY" , "CWBCO_SERVICE_DDM" , "", /* not used */ "", /* not used */ "CWBCO_SERVICE_WEB_ADMIN" , "CWBCO_SERVICE_TELNET" , "CWBCO_SERVICE_MGMT_CENTRAL" } ; /* * Node in a singly-linked list to hold a pointer * to a system name. Note that the creator of an * instance of this node must allocate the space to * hold the system name himself, only a pointer is * supplied here. */ typedef struct sysListNodeStruct SYSLISTNODE, *PSYSLISTNODE; struct sysListNodeStruct { char* sysName; cwbCO_SysHandle hSys; PSYSLISTNODE next; } ; /**************************************************************************** * Add a system name to the list of configured systems we will keep around. ****************************************************************************/ UINT addSystemToList( char* sysName, SYSLISTNODE** ppSysList ) { SYSLISTNODE* pNewSys; char* pNewSysName; pNewSys = (SYSLISTNODE*) malloc (sizeof( SYSLISTNODE )); if ( pNewSys == NULL ) { return FAILURE; } pNewSysName = (char*) malloc (strlen( sysName ) + 1 ); if ( pNewSysName == NULL ) { free (pNewSys); return FAILURE; } strcpy( pNewSysName, sysName ); pNewSys->sysName = pNewSysName; pNewSys->hSys = 0; /* delay creating sys object until needed */ pNewSys->next = *ppSysList; *ppSysList = pNewSys; return SUCCESS; } /**************************************************************************** * Clear the list of system names and clean up used storage. ****************************************************************************/ void clearList( SYSLISTNODE* pSysList ) { PSYSLISTNODE pCur, pNext; pCur = pSysList; while ( pCur != NULL ) { pNext = pCur->next; free (pCur->sysName); free (pCur); pCur = pNext; } } /**************************************************************************** * Retrieve and display Client Access FAILURE messages. ****************************************************************************/ void reportCAErrors( cwbSV_ErrHandle hErrs ) { ULONG msgCount; UINT apiRC; UINT i; char msgText[ 200 ]; /* 200 is big enuf to hold most msgs */ ULONG bufLen = sizeof( msgText ); /* holds size of msgText buffer */ ULONG lenNeeded; /* to hold length of buf needed */ apiRC = cwbSV_GetErrCount( hErrs, &msgCount ); if ( CWB_OK != apiRC ) { printf( "Failed to get message count, cwbSV_GetErrCount rc=%u\n", apiRC ); if ( ( CWB_INVALID_POINTER == apiRC ) || ( CWB_INVALID_HANDLE == apiRC ) ) { printf( " --> likely a programming FAILURE!\n"); } return; } bufLen = sizeof( msgText ); for ( i=1; i<=msgCount; i++ ) { apiRC = cwbSV_GetErrTextIndexed(hErrs, i, msgText, bufLen, &lenNeeded); if ( ( CWB_OK == apiRC ) || ( CWB_BUFFER_OVERFLOW == apiRC ) ) /* if truncated, that's ok */ { printf( "CA FAILURE #%u: %s\n", i, msgText ); } else { printf( "CA FAILURE #%u unuvailable, cwbSV_GetErrTextIndexed rc=%u\n", i, apiRC ); } } } /**************************************************************************** * Build the list of systems as it is currently configured in Client * Access. ****************************************************************************/ UINT buildSysList( SYSLISTNODE** ppSysList ) { cwbSV_ErrHandle hErrs; cwbCO_SysListHandle hList; char sysName[ CWBCO_MAX_SYS_NAME + 1 ]; ULONG bufSize = sizeof( sysName ); ULONG needed; UINT apiRC; UINT myRC = SUCCESS; UINT rc = SUCCESS; /* Create a FAILURE handle so that, in case of FAILURE, we can * retrieve and display the messages (if any) associated with * the failure. */ apiRC = cwbSV_CreateErrHandle( &hErrs ); if ( CWB_OK != apiRC ) { /* Failed to create a FAILURE handle, use NULL instead. * This means we'll not be able to get at FAILURE messages. */ hErrs = 0; } apiRC = cwbCO_CreateSysListHandle( *hList, hErrs ); if ( CWB_OK != apiRC ) { printf( "Failure to get a handle to the system list.\n" ); reportCAErrors( hErrs ); myRC = FAILURE; } /* Get each successive system name and add the system to our * internal list for later use. */ while ( ( CWB_OK == apiRC ) && ( myRC == SUCCESS ) ) { apiRC = cwbCO_GetNextSysName( hList, sysName, bufSize, &needed ); /* Note that since the sysName buffer is as large as it will * ever need to be, we don't check specifically for the return * code CWB_BUFFER_OVERFLOW. We could instead choose to use a * smaller buffer, and if CWB_BUFFER_OVERFLOW were returned, * allocate one large enough and call cwbCO_GetNextSysName * again. */ if ( CWB_OK == apiRC ) { myRC = addSystemToList( sysName, ppSysList ); if ( myRC != SUCCESS ) { printf( "Failure to add the next system name to the list.\n"); } } else if ( CWBCO_END_OF_LIST != apiRC ) { printf( "Failed to get the next system name.\n" ); myRC = FAILURE; } } /* end while (to build a list of system names) */ /* * Free the FAILURE handle if one was created */ if ( hErrs != 0 ) /* (non-NULL if it was successfully created) */ { apiRC = cwbSV_DeleteErrHandle( hErrs ); if ( CWB_INVALID_HANDLE == apiRC ) { printf("Failure: FAILURE handle invalid, could not delete!\n"); myRC = FAILURE; } } return myRC; } /**************************************************************************** * Get a system object given an index into our list of systems. ****************************************************************************/ UINT getSystemObject( UINT sysNum, SYSLISTNODE* pSysList, cwbCO_SysHandle* phSys ) { SYSLISTNODE* pCur; UINT myRC, apiRC; pCur = pSysList; for ( ; sysNum > 1; sysNum-- ) { /* We have come to the end of the list without finding * the system requested, break out of loop and set FAILURE rc. */ if ( NULL == pCur ) { myRC = FAILURE; break; } pCur = pCur->next; } /* If we're at a real system node, continue */ if ( NULL != pCur ) { /* We're at the node/sysname of the user's choice. If no * Client Access "system object" has yet been created for this * system, create one. Pass back the one for the selected system. */ if ( 0 == pCur->hSys ) { apiRC = cwbCO_CreateSystem( pCur->sysName, &(pCur->hSys) ); if ( CWB_OK != apiRC ) { printf( "Failed to create system object, cwbCO_CreateSystem rc = %u\n", apiRC ); myRC = FAILURE; } } *phSys = pCur->hSys; } return myRC; } /**************************************************************************** * Allow the user to select a system from the list we have. ****************************************************************************/ UINT selectSystem( UINT* pNumSelected, SYSLISTNODE* pSysList, BOOL refreshList ) { UINT myRC = SUCCESS; SYSLISTNODE* pCur; UINT sysNum, numSystems; char choiceStr[ 20 ]; /* If the user wants the list refreshed, clear any existing list * so we can rebuilt it from scratch. */ if ( refreshList ) { clearList( pSysList ); pSysList = NULL; } /* If the list of system names is NULL (no list exists), build * the list of systems using Client Access APIs. */ if ( NULL == pSysList ) { myRC = buildSysList( &pSysList ); if ( SUCCESS != myRC ) { *pNumSelected = 0; printf( "Failed to build sys list, cannot select a system.\n"); } } if ( SUCCESS == myRC ) { printf( "-------------------------------------------- \n" ); printf( "The list of systems configured is as follows:\n" ); printf( "-------------------------------------------- \n" ); for ( sysNum = 1, pCur = pSysList; pCur != NULL; sysNum++, pCur = pCur->next ) { printf( " %u) %s\n", sysNum, pCur->sysName ); } numSystems = sysNum - 1; printf( "Enter the number of the system of your choice:\n"); gets( choiceStr ); *pNumSelected = atoi( choiceStr ); if ( *pNumSelected > numSystems ) { printf( "Invalid selection, there are only %u systems configured.\n"); *pNumSelected = 0; myRC = FAILURE; } } return myRC; } /**************************************************************************** * Display a single attribute and its value, or a failing return code * if one occurred when trying to look it up. ****************************************************************************/ void dspAttr( char* label, char* attrVal, UINT lookupRC, BOOL* pCanBeModified, UINT canBeModifiedRC ) { if ( CWB_OK == lookupRC ) { printf( "%25s : %-30s ", label, attrVal ); if ( CWB_OK == canBeModifiedRC ) { if ( pCanBeModified != NULL ) { printf( "%s\n", cwbBoolStr[ *pCanBeModified ] ); } else { printf( "(N/A)\n" ); } } else { printf( "(Error, rc=%u)\n", canBeModifiedRC ); } } else { printf( "%30s : (Error, rc=%u)\n", label, lookupRC ); } } /**************************************************************************** * * Load the host/version string into the buffer specified. The * buffer passed in must be at least 7 bytes long! A pointer to * the buffer itself is passed back so that the output from this * function can be used directly as a parameter. * ****************************************************************************/ char* hostVerModeDescr( ULONG ver, ULONG rel, char* verRelBuf ) { char* nextChar = verRelBuf; if ( verRelBuf != NULL ) { *nextChar++ = 'v'; if ( ver < 10 ) { *nextChar++ = '0' + (char)ver; } else { *nextChar++ = '?'; *nextChar++ = '?'; } *nextChar++ = 'r'; if ( rel < 10 ) { *nextChar++ = '0' + (char)rel; } else { *nextChar++ = '?'; *nextChar++ = '?'; } *nextChar = '\0'; } return verRelBuf; } /**************************************************************************** * Display all attributes of the system whose index in the passed list * is passed in. ****************************************************************************/ void dspSysAttrs( SYSLISTNODE* pSysList, UINT sysNum ) { cwbCO_SysHandle hSys; UINT rc; char sysName[ CWBCO_MAX_SYS_NAME + 1 ]; char IPAddr[ CWBCO_MAX_IP_ADDRESS + 1 ]; ULONG bufLen, IPAddrLen; ULONG IPAddrBufLen; UINT apiRC, apiRC2; cwbCO_ValidateMode valMode; cwbCO_DefaultUserMode dfltUserMode; cwbCO_PromptMode promptMode; cwbCO_PortLookupMode portLookupMode; cwbCO_IPAddressLookupMode IPALMode; ULONG ver, rel; char verRelBuf[ 10 ]; ULONG verRelBufLen; cwb_Boolean isSecSoc; cwb_Boolean canModify; IPAddrBufLen = sizeof( IPAddr ); verRelBufLen = sizeof( verRelBuf ); rc = getSystemObject( sysNum, pSysList, &hSys ); if ( rc == FAILURE ) { printf( "Failed to get system object for selected system.\n"); return; } printf("\n\n"); printf("-----------------------------------------------------------\n"); printf(" S y s t e m A t t r i b u t e s \n"); printf("-----------------------------------------------------------\n"); printf("\n"); printf( "%25s : %-30s %s\n", "Attribute", "Value", "Modifiable" ); printf( "%25s : %-30s %s\n", "---------", "-----", "----------" ); printf("\n"); apiRC = cwbCO_GetSystemName( hSys, sysName, &bufLen ); dspAttr( "System Name", sysName, apiRC, NULL, 0 ); apiRC = cwbCO_GetIPAddress( hSys, IPAddr, &IPAddrLen ); dspAttr( "IP Address", IPAddr, apiRC, NULL, 0 ); apiRC = cwbCO_GetHostVersionEx( hSys, &ver, &rel ); dspAttr( "Host Version/Release", hostVerModeDescr( ver, rel, verRelBuf ), apiRC, NULL, 0 ); apiRC = cwbCO_IsSecureSockets( hSys, &isSecSoc ); apiRC2 = cwbCO_CanModifyUseSecureSockets( hSys, &canModify ); dspAttr( "Secure Sockets In Use", cwbBoolStr[ isSecSoc ], apiRC, &canModify, apiRC2 ); apiRC = cwbCO_GetValidateMode( hSys, &valMode ); canModify = CWB_TRUE; dspAttr( "Validate Mode", valModeStr[ valMode ], apiRC, &canModify, 0 ); apiRC = cwbCO_GetDefaultUserMode( hSys, &dfltUserMode ); apiRC2 = cwbCO_CanModifyDefaultUserMode( hSys, &canModify ); dspAttr( "Default User Mode", dfltUserModeStr[ dfltUserMode ], apiRC, &canModify, apiRC2 ); apiRC = cwbCO_GetPromptMode( hSys, &promptMode ); canModify = CWB_TRUE; dspAttr( "Prompt Mode", promptModeStr[ promptMode ], apiRC, &canModify, 0 ); apiRC = cwbCO_GetPortLookupMode( hSys, &prtLookupMode ); apiRC2 = cwbCO_CanModifyPortLookupMode( hSys, &canModify ); dspAttr( "Port Lookup Mode", portLookupModeStr[ portLookupMode ], apiRC, &canModify, apiRC2 ); apiRC = cwbCO_GetIPAddressLookupMode( hSys, &IPALMode ); apiRC2 = cwbCO_CanModifyIPAddressLookupMode( hSys, &canModify ); dspAttr( "IP Address Lookup Mode", IPALModeStr[ IPALMode ], apiRC, &canModify, apiRC2 ); printf("\n\n"); } /**************************************************************************** * Display connectability to all Client Access services that are * possible to connect to. ****************************************************************************/ void dspConnectability( PSYSLISTNODE pSysList, UINT sysNum ) { UINT rc; UINT apiRC; cwbCO_Service service; cwbCO_SysHandle hSys; rc = getSystemObject( sysNum, pSysList, &hSys ); if ( rc == FAILURE ) { printf( "Failed to get system object for selected system.\n"); } else { printf("\n\n"); printf("-----------------------------------------------------------\n"); printf(" S y s t e m S e r v i c e s S t a t u s \n"); printf("-----------------------------------------------------------\n"); for ( service=(cwbCO_Service)1; service <= CWBCO_SERVICE_MGMT_CENTRAL; service++ ) { apiRC = cwbCO_Verify( hSys, service, 0 ); // 0=no err handle printf(" Service '%s': ", serviceStr[ service ] ); if ( apiRC == CWB_OK ) { printf("CONNECTABLE\n"); } else { printf("CONNECT TEST FAILED, rc = %u\n", apiRC ); } } } printf("\n"); } /**************************************************************************** * MAIN PROGRAM BODY ****************************************************************************/ void main(void) { PSYSLISTNODE pSysList = NULL; UINT numSelected; UINT rc; char choiceStr[10]; UINT choice; rc = buildSysList( &pSysList ); if ( SUCCESS != rc ) { printf( "Failure to build the system list, exiting.\n\n"); exit( FAILURE ); } do { printf( "Select one of the following options:\n" ); printf( " (1) Display current system attributes\n"); printf( " (2) Display service connectability for a system\n"); printf( " (3) Refresh the list of systems\n" ); printf( " (9) Quit\n" ); gets( choiceStr ); choice = atoi( choiceStr ); switch ( choice ) { // ---- Display current system attributes --------------- case 1 : { rc = selectSystem( &numSelected, pSysList, FALSE ); if ( SUCCESS == rc ) { dspSysAttrs( pSysList, numSelected ); } break; } // ---- Display service connectability for a system ----- case 2 : { rc = selectSystem( &numSelected, pSysList, FALSE ); if ( SUCCESS == rc ) { dspConnectability( pSysList, numSelected ); } break; } // ---- Refresh the list of systems --------------------- case 3 : { clearList( pSysList ); pSysList = NULL; rc = buildSysList( &pSysList ); break; } // ---- Quit -------------------------------------------- case 9 : { printf("Ending the program!\n"); break; } default : { printf("Invalid choice. Please make a different selection.\n"); } } } while ( choice != 9 ); /* Cleanup the list, we're done */ clearList( pSysList ); pSysList = NULL; printf( "\nEnd of program.\n\n" ); }