I would like to get a code review from some of the C Board experts. This is a working example of my code, so this is not a do my work for me scenario. However, I would like to know if there are any glaring errors in my logic, and if there is anything at could or should be done better--as I am not a professional C programmer.

If this is not the proper forum to post such an item, just let me know and the maintainer can move or remove as desired. For those that find this interesting and / or useful please take an use. For those that would like to expand the code base, please do and share with the rest of us in the forum.

hbainfo.h
Code:
include <alloca.h>
#include <ctype.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sysexits.h>   /* System Defined Exit Codes */

#if defined(_AIX)
# define AIX
#endif

#if defined(hpux) || defined(__hpux)
# define HPUX
#endif

#ifdef AIX
# include <sys/hbaapi.h>
#endif

#ifdef HPUX
# include <snia_common.h>
#endif

#ifdef __linux__
# include "hbaapi.h"
# include "vendorhbaapi.h"
#endif


#ifndef HBAINFO_H_
#define HBAINFO_H_

/*
 * The HBA_PORTSPEED_[n]GBIT may not be included in some of the older hbaapi.h
 * include files--adding them for compatibility. Oh and, don't ask me why the
 * values are not sequential because I do not have an answer other than the
 * order that they were added by the maintainers of hbaapi.
 */
# ifndef HBA_PORTSPEED_UNKNOWN
#   define HBA_PORTSPEED_UNKNOWN  0
# endif
# ifndef HBA_PORTSPEED_1GBIT
#   define HBA_PORTSPEED_1GBIT    1
# endif
# ifndef HBA_PORTSPEED_2GBIT
#   define HBA_PORTSPEED_2GBIT    2
# endif
# ifndef HBA_PORTSPEED_4GBIT
#   define HBA_PORTSPEED_4GBIT    8
# endif
# ifndef HBA_PORTSPEED_8GBIT
#   define HBA_PORTSPEED_8GBIT    16
# endif
# ifndef HBA_PORTSPEED_10GBIT
#   define HBA_PORTSPEED_10GBIT   4
# endif

# define MAX_HBA      128
# define MAX_HBA_NAME 256
# define WWN_SIZE     128
# define NO_SUPP      "Not_Supported"
# define REC_SEP      "*************************************************************"

/* PROTOTYPES */
void        get_systopo_hbainfo                 (int);
void        WWN2Cstring                         (char*,HBA_WWN*);
void        WWN2string                          (char*,HBA_WWN*);
char        *squeeze                            (char*);

/* HBA Routines */
int         hba_load_library                    (void);
int         hba_free_library                    (void);
HBA_UINT32  hba_get_number_of_adapters          (void);
int         hba_get_adapter_name                (int,char*);
HBA_HANDLE  hba_open_adapter                    (char*);
void        hba_close_adapter                   (HBA_HANDLE);

void        hba_print_port_speed                (HBA_UINT32,HBA_UINT32,HBA_UINT32);
int         hba_print_adapter_attributes        (char*,HBA_HANDLE,HBA_UINT32);
int         hba_print_port_attributes           (char*,HBA_HANDLE,HBA_UINT32);
int         hba_print_fcp_target_mapping        (char*,HBA_HANDLE,HBA_UINT32);

void        hba_status_check                    (HBA_STATUS,char*);
void        hba_fcp_target_mapping_status_check (HBA_STATUS,char*);

#endif /* HBAINFO_H_ */[/FONT]

hbainfo.c
Code:

#include "hbainfo.h"
int DEBUG = 0;

void WWN2Cstring(char *dst, HBA_WWN *WWN) {
/*
 ============================================================================
 Name       : WWN2Cstring
 Description: transform the WWN into a colon separated string.
 Notes      :
 Input      : (1) pointer to destination buffer
            : (2) pointer to wwn structure
 ============================================================================
 */
  snprintf( dst, 24, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
            WWN->wwn[0],  WWN->wwn[1],  WWN->wwn[2],  WWN->wwn[3],
            WWN->wwn[4],  WWN->wwn[5],  WWN->wwn[6],  WWN->wwn[7] );
}

void WWN2string(char *dst, HBA_WWN *WWN) {
/*
 ============================================================================
 Name       : WWN2string
 Description: transform the WWN into a standard string.
 Notes      :
 Input      : (1) pointer to destination buffer
            : (2) pointer to wwn structure
 ============================================================================
 */
  snprintf( dst, 24, "%02x%02x%02x%02x%02x%02x%02x%02x",
            WWN->wwn[0],  WWN->wwn[1],  WWN->wwn[2],  WWN->wwn[3],
            WWN->wwn[4],  WWN->wwn[5],  WWN->wwn[6],  WWN->wwn[7] );
}

char *squeeze(char *str) {
/*
 ============================================================================
 Name       : squeeze
 Description: replace double whitespace and control characters with a single
              space.
 ============================================================================
 */
  int r = 0, w = 0;
  while (str[r]) {
    if (isspace((int)str[r]) || iscntrl((int)str[r])) {
      if (w > 0 && !isspace((int)str[w-1])) { str[w++] = ' '; }
    } else {
      str[w++] = str[r];
    }
    r++;
  }
  str[w] = '\0';

  return ( str );
}

void hba_status_check ( HBA_STATUS status, char *msg ){
/*
 ============================================================================
 Name       : hba_status_check
 Description: print the common HBA return status.
 Notes      : It is not the responsibily of this function to set or change
            : the return value in any way--just display what happened.
 Input      : (1) HBA status return code
            : (2) Calling function message
 ============================================================================
*/
  switch ( status ) {
    case HBA_STATUS_OK:
      ( void )fprintf( stderr, "debug: [%s]: successful\n", msg );
      break;
    case HBA_STATUS_ERROR:
      ( void )fprintf( stderr, "debug: [%s]: unspecified error occurred that prevented the retrieval of the HBA information\n", msg );
      break;
    case HBA_STATUS_ERROR_NOT_SUPPORTED:
      ( void )fprintf( stderr, "debug: [%s]: Function not supported\n", msg );
      break;
    case HBA_STATUS_ERROR_INVALID_HANDLE:
      ( void )fprintf( stderr, "debug: [%s]: Invalid handle\n", msg );
      break;
    case HBA_STATUS_ERROR_ARG:
      ( void )fprintf( stderr, "debug: [%s]: Bad argument\n", msg );
      break;
    case HBA_STATUS_ERROR_ILLEGAL_WWN:
      ( void )fprintf( stderr, "debug: [%s]: Worldwide name not recognized\n", msg );
      break;
    case HBA_STATUS_ERROR_ILLEGAL_INDEX:
      ( void )fprintf( stderr, "debug: [%s]: Index not recognized\n", msg );
      break;
    case HBA_STATUS_ERROR_MORE_DATA:
      ( void )fprintf( stderr, "debug: [%s]: Larger buffer required.\n", msg );
      break;
    case HBA_STATUS_ERROR_STALE_DATA:
      ( void )fprintf( stderr, "debug: [%s]: Information has changed since the last refresh operation\n", msg );
      break;
    case HBA_STATUS_SCSI_CHECK_CONDITION:
      ( void )fprintf( stderr, "debug: [%s]: SCSI Check Condition reported\n", msg );
      break;
    case HBA_STATUS_ERROR_BUSY:
      ( void )fprintf( stderr, "debug: [%s]: Adapter busy or reserved, retry might be required\n", msg );
      break;
    case HBA_STATUS_ERROR_TRY_AGAIN:
      ( void )fprintf( stderr, "debug: [%s]: Request timed out, retry might be required\n", msg );
      break;
    case HBA_STATUS_ERROR_UNAVAILABLE:
      ( void )fprintf( stderr, "debug: [%s]: Referenced HBA has been removed or deactivated\n", msg );
      break;
    case HBA_STATUS_ERROR_ELS_REJECT:
      ( void )fprintf( stderr, "debug: [%s]: The requested ELS was rejected by the local adapter\n", msg );
      break;
    case HBA_STATUS_ERROR_INVALID_LUN:
      ( void )fprintf( stderr, "debug: [%s]: The specified LUN is not provided by the specified adapter\n", msg );
      break;
    case HBA_STATUS_ERROR_INCOMPATIBLE:
      ( void )fprintf( stderr, "debug: [%s]: An incompatibility has been detected\n", msg );
      break;
    case HBA_STATUS_ERROR_AMBIGUOUS_WWN:
      ( void )fprintf( stderr, "debug: [%s]: Multiple adapters have a matching worldwide name (WWN)\n", msg );
      break;
    case HBA_STATUS_ERROR_LOCAL_BUS:
      ( void )fprintf( stderr, "debug: [%s]: A persistent binding request included a bad local SCSI bus number\n", msg );
      break;
    case HBA_STATUS_ERROR_LOCAL_TARGET:
      ( void )fprintf( stderr, "debug: [%s]: A persistent binding request included a bad local SCSI target number\n", msg );
      break;
    case HBA_STATUS_ERROR_LOCAL_LUN:
      ( void )fprintf( stderr, "debug: [%s]: A persistent binding request included a bad local SCSI LUN\n", msg );
      break;
    case HBA_STATUS_ERROR_LOCAL_SCSIID_BOUND:
      ( void )fprintf( stderr, "debug: [%s]: A persistent binding set request included a local SCSI ID that was already bound\n", msg );
      break;
    case HBA_STATUS_ERROR_TARGET_FCID:
      ( void )fprintf( stderr, "debug: [%s]: A persistent binding request included an invalid FCP target FCID\n", msg );
      break;
    case HBA_STATUS_ERROR_TARGET_NODE_WWN:
      ( void )fprintf( stderr, "debug: [%s]: A persistent binding request included a bad FCP target node WWN\n", msg );
      break;
    case HBA_STATUS_ERROR_TARGET_PORT_WWN:
      ( void )fprintf( stderr, "debug: [%s]: A persistent binding request included a bad FCP target port WWN\n", msg );
      break;
    case HBA_STATUS_ERROR_TARGET_LUN:
      ( void )fprintf( stderr, "debug: [%s]: A persistent binding request included an FCP LUN that the target does not recognize\n", msg );
      break;
    case HBA_STATUS_ERROR_TARGET_LUID:
      ( void )fprintf( stderr, "debug: [%s]: A persistent binding request contained an undefined or otherwise inaccessible logical unit unique identifier\n", msg );
      break;
    case HBA_STATUS_ERROR_NO_SUCH_BINDING:
      ( void )fprintf( stderr, "debug: [%s]: A persistent binding remove request contained a binding which did not match a binding established by the specified port\n", msg );
      break;
    case HBA_STATUS_ERROR_NOT_A_TARGET:
      ( void )fprintf( stderr, "debug: [%s]: A SCSI command was sent to an Nx_Port that was not a SCSI target port\n", msg );
      break;
    case HBA_STATUS_ERROR_UNSUPPORTED_FC4:
      ( void )fprintf( stderr, "debug: [%s]: A request was made concerning an unsupported FC-4 protocol\n", msg );
      break;
    case HBA_STATUS_ERROR_INCAPABLE:
      ( void )fprintf( stderr, "debug: [%s]: A request was made to enable unimplemented capabilities for a port\n", msg );
      break;
    case HBA_STATUS_ERROR_TARGET_BUSY:
      ( void )fprintf( stderr, "debug: [%s]: Executing the requested SCSI command would cause a SCSI overlapped command condition\n", msg );
      break;
    default:
      ( void )fprintf( stderr, "debug: [%s]: unknown status code: %d\n", msg, status );
      break;
  }
}

void hba_fcp_target_mapping_status_check ( HBA_STATUS status, char *msg ) {
/*
 ============================================================================
 Name       : hba_fcp_target_mapping_status_check
 Description: print the fiber channel port mappings return status.
 Notes      : It is not the responsibily of this function to set or change
            : the return value in any way--just display what happened.
 Input      : (1) HBA status return code
            : (2) Calling function message
 ============================================================================
*/
  switch ( status ) {
    case HBA_STATUS_OK:
      ( void )fprintf( stderr, "debug: [%s]: successful\n", msg );
      break;
    case HBA_STATUS_ERROR_MORE_DATA:
      ( void )fprintf( stderr, "debug: [%s]: buffer space is insufficient to hold all of the target mappings\n", msg );
      break;
    case HBA_STATUS_ERROR_ILLEGAL_WWN:    /* V2 Only */
      ( void )fprintf( stderr, "debug: [%s]: HBA referenced by HBA Handle does not contain a port with a name of hbaPortWWN\n", msg );
      break;
    case HBA_STATUS_ERROR_NOT_SUPPORTED:  /* V2 Only */
      ( void )fprintf( stderr, "debug: [%s]: HBA referenced by HbaHandle does not support target mapping\n", msg );
      break;
    case HBA_STATUS_ERROR:
      ( void )fprintf( stderr, "debug: [%s]: unspecified error occurred that prevented the retrieval of the mapping information\n", msg );
      break;
    default:
      ( void )fprintf( stderr, "debug: [%s]: unknown status code: %d\n", msg, status );
      break;
  }
}

int hba_load_library( void ) {
/*
 ============================================================================
 Name       : hba_load_library
 Description: load (open) the hba library.
 Notes      :
 Input      : void
 ============================================================================
*/
  HBA_STATUS status;
  status = HBA_LoadLibrary();
  if ( DEBUG ) { hba_status_check( status, "HBA_LoadLibrary" ); }
  return ( status == HBA_STATUS_OK ) ? 0 : -1;
}

int hba_free_library( void ) {
/*
 ============================================================================
 Name       : hba_free_library
 Description: free (unload) the hba library
 Notes      :
 Input      : void
 ============================================================================
*/
  HBA_STATUS status;
  status = HBA_FreeLibrary();
  if ( DEBUG ) hba_status_check( status, "HBA_FreeLibrary" );
  return ( status == HBA_STATUS_OK ) ? 0 : -1;
}

HBA_UINT32 hba_get_number_of_adapters( void ) {
/*
 ============================================================================
 Name       : hba_get_number_of_adapters
 Description: get the number of adapters
 Notes      :
 Input      : void
 ============================================================================
*/
  return ( HBA_GetNumberOfAdapters() );
}

int hba_get_adapter_name(int adapter_number, char *adapter_name) {
/*
 ============================================================================
 Name       : hba_get_adapter_name
 Description: get the HBA adapter name
 Notes      :
 Input      : (1) current adapter number
            : (2) pointer to adapter name
 ============================================================================
*/
  HBA_STATUS status;
  status = HBA_GetAdapterName( adapter_number, adapter_name );
  if ( DEBUG ) { hba_status_check( status, "HBA_GetAdapterName" ); }

  if ( ( status != HBA_STATUS_OK ) ||
       ( strlen(adapter_name) == 0 ) ) {
    if ( DEBUG )
      ( void )fprintf( stderr, "debug: failed HBA_GetAdapterName for adapter number %d\n", adapter_number );
    return ( -1 );
  }
  return ( 0 );

}

HBA_HANDLE hba_open_adapter(char *adapter_name) {
/*
 ============================================================================
 Name       : hba_open_adapter
 Description: open an HBA adapter
 Notes      : If successful, the HBA_OpenAdapter subroutine returns an
              HBA_HANDLE with a value greater than 0. If unsuccessful,
              the subroutine returns a 0.
 Input      : (1) pointer to current adapter name.
 ============================================================================
*/
  HBA_HANDLE adapter_handle = HBA_OpenAdapter( adapter_name );

  if ( ( adapter_handle == HBA_HANDLE_INVALID ) && ( DEBUG ) )
    ( void )fprintf( stderr, "debug: [HBA_OpenAdapter]: failed HBA_OpenAdapter for adapter %s\n", adapter_name );
  return ( adapter_handle );
}

void hba_close_adapter(HBA_HANDLE adapter_handle) {
/*
 ============================================================================
 Name       : hba_close_adapter
 Description: close an open adapter handle
 Notes      :
 Input      : (1) open (non-zero) adapter handle
 ============================================================================
*/
  if ( adapter_handle != HBA_HANDLE_INVALID )
    HBA_CloseAdapter( adapter_handle );
}

int hba_print_adapter_attributes(char *adapter_name, HBA_HANDLE adapter_handle, HBA_UINT32 hba) {
/*
 ============================================================================
 Name       : hba_print_adapter_attributes
 Description: print the HBA adapter attributes
 Notes      : this function uses alloca--never use free against an alloca.
            : remember that alloca allocates to the stack and is automatically
            : cleaned at program termination.
 Input      : (1) pointer to adapter name
            : (2) open adapter handle
            : (3) current hba number
 ============================================================================
*/
  HBA_STATUS status;

  /* initialize the adapter attributes structure */
  HBA_ADAPTERATTRIBUTES adapter_attributes;
  memset( &adapter_attributes, 0, sizeof( HBA_ADAPTERATTRIBUTES ) );

  status = HBA_GetAdapterAttributes( adapter_handle, &adapter_attributes );
  if ( DEBUG ) { hba_status_check( status, "HBA_GetAdapterAttributes" ); }
  if ( status != HBA_STATUS_OK ) { return ( -1 ); }

  char *wwn = ( char * )alloca( WWN_SIZE );
  if ( wwn == NULL ) {
    if ( DEBUG )
      ( void )fprintf( stderr, "debug: failed to allocate memory for WWN\n" );
    hba_close_adapter( adapter_handle );
    hba_free_library();
    exit ( EX_OSERR );
  }
  WWN2Cstring( wwn, &adapter_attributes.NodeWWN );

  /* Print the results */
  ( void )fprintf( stdout, "%s\n", REC_SEP );
  ( void )fprintf( stdout, "hba.%d.Name = %s\n",              hba, adapter_name );
  ( void )fprintf( stdout, "hba.%d.Manufacturer = %s\n",      hba,
            ( strlen(adapter_attributes.Manufacturer) == 0 )
            ? NO_SUPP : adapter_attributes.Manufacturer );
  ( void )fprintf( stdout, "hba.%d.SerialNumber = %s\n",      hba,
            ( strlen( adapter_attributes.SerialNumber ) == 0 )
            ? NO_SUPP : adapter_attributes.SerialNumber );
  ( void )fprintf( stdout, "hba.%d.Model = %s\n",             hba,
            ( strlen(adapter_attributes.Model) == 0 )
            ? NO_SUPP : adapter_attributes.Model );
  ( void )fprintf( stdout, "hba.%d.Description = %s\n",       hba,
            ( strlen(adapter_attributes.ModelDescription) == 0 )
            ? NO_SUPP : adapter_attributes.ModelDescription );
  ( void )fprintf( stdout, "hba.%d.SymbolicName = %s\n",      hba,
            ( strlen(adapter_attributes.NodeSymbolicName) == 0 )
            ? NO_SUPP : adapter_attributes.NodeSymbolicName );
  ( void )fprintf( stdout, "hba.%d.HardwareVersion = %s\n",   hba,
            ( strlen(adapter_attributes.HardwareVersion) == 0 )
            ? NO_SUPP : adapter_attributes.HardwareVersion );
  ( void )fprintf( stdout, "hba.%d.DriverVersion = %s\n",     hba,
            ( strlen(adapter_attributes.DriverVersion) == 0 )
            ? NO_SUPP : adapter_attributes.DriverVersion );
  ( void )fprintf( stdout, "hba.%d.OptionROMVersion = %s\n",  hba,
            ( strlen(adapter_attributes.OptionROMVersion) == 0 )
            ? NO_SUPP : adapter_attributes.OptionROMVersion );
  ( void )fprintf( stdout, "hba.%d.FirmwareVersion = %s\n",   hba,
            ( strlen(adapter_attributes.FirmwareVersion) == 0 )
            ? NO_SUPP : adapter_attributes.FirmwareVersion );
  ( void )fprintf( stdout, "hba.%d.DriverName = %s\n",        hba,
            ( strlen(adapter_attributes.DriverName) == 0 )
            ? NO_SUPP : adapter_attributes.DriverName );
  ( void )fprintf( stdout, "hba.%d.NumberOfPorts = %d\n",     hba,
            adapter_attributes.NumberOfPorts );
  ( void )fprintf( stdout, "hba.%d.NodeWWN = %s\n",           hba,
            ( strlen(wwn) == 0 ) ? NO_SUPP : wwn );

  /* Clean-up and Return */
  return ( 0 );
}

void hba_print_port_speed ( HBA_UINT32 hba, HBA_UINT32 port, HBA_UINT32 speed ) {

  if ( DEBUG ){ ( void )fprintf( stderr, "debug: [PortSpeed]: port_attributes.PortSpeed value: %d\n", speed ); }

  switch( speed ) {
    case HBA_PORTSPEED_UNKNOWN:
      ( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "UNKNOWN" );
      break;

    case HBA_PORTSPEED_1GBIT:
      ( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "1 Gigabit" );
      break;

    case HBA_PORTSPEED_2GBIT:
      ( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "2 Gigabit" );
      break;

    case HBA_PORTSPEED_4GBIT:
      ( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "4 Gigabit" );
      break;

    case HBA_PORTSPEED_8GBIT:
      ( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "8 Gigabit" );
      break;

    case HBA_PORTSPEED_10GBIT:
      ( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "10 Gigabit" );
      break;

    case HBA_PORTSPEED_NOT_NEGOTIATED:
      ( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "Not Negotiated" );
      break;
    default:
      ( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "ERROR" );
      break;
  }

}

int hba_print_port_attributes(char *adapter_name, HBA_HANDLE adapter_handle, HBA_UINT32 hba) {
/*
 ============================================================================
 Name       : hba_print_port_attributes
 Description: print the HBA port attributes.
 Notes      : this function uses alloca--never use free against an alloca.
            : remember that alloca allocates to the stack and is automatically
            : cleaned at program termination.
 Input      : (1) pointer to adapter name
            : (2) open adapter handle
            : (3) current hba number
 ============================================================================
*/
  HBA_STATUS status;

  /* initialize the adapter attributes structure */
  HBA_ADAPTERATTRIBUTES adapter_attributes;
  memset( &adapter_attributes, 0, sizeof( HBA_ADAPTERATTRIBUTES ) );

  /* get the adapter attributes */
  status = HBA_GetAdapterAttributes( adapter_handle, &adapter_attributes );
  if ( DEBUG ) { hba_status_check( status, "HBA_GetAdapterAttributes" ); }
  if ( status != HBA_STATUS_OK ) { return ( -1 ); }

  HBA_UINT32 port;
  HBA_PORTATTRIBUTES port_attributes;
  memset(&port_attributes, 0, sizeof(HBA_PORTATTRIBUTES));

  char *fwwn = ( char * )alloca( WWN_SIZE );
  char *nwwn = ( char * )alloca( WWN_SIZE );
  char *pwwn = ( char * )alloca( WWN_SIZE );
  if ( ( fwwn == NULL ) || ( pwwn == NULL ) || ( nwwn == NULL ) ) {
    if ( DEBUG )
      ( void )fprintf( stderr, "debug: failed to allocate memory for WWN\n" );
    hba_close_adapter( adapter_handle );
    hba_free_library();
    exit ( EX_OSERR );
  }

  for ( port = 0; port < adapter_attributes.NumberOfPorts; port++ ) {

    status = HBA_GetAdapterPortAttributes( adapter_handle, port, &port_attributes );
    if ( DEBUG ) { hba_status_check( status, "HBA_GetAdapterPortAttributes" ); }
    if ( status != HBA_STATUS_OK ) { continue; }

    WWN2Cstring( fwwn, &port_attributes.FabricName );
    WWN2Cstring( nwwn, &port_attributes.NodeWWN );
    WWN2Cstring( pwwn, &port_attributes.PortWWN );

    ( void )fprintf( stdout, "hba.%d.port.%d.FabricName = %s\n",    hba, port, fwwn );
    ( void )fprintf( stdout, "hba.%d.port.%d.NodeWWN = %s\n",       hba, port, nwwn );
    ( void )fprintf( stdout, "hba.%d.port.%d.PortWWN = %s\n",       hba, port, pwwn );
    hba_print_port_speed( hba, port, port_attributes.PortSpeed );

  }

  /* Clean-up and Return */
  return ( 0 );
}

int hba_print_fcp_target_mapping(char *adapter_name, HBA_HANDLE adapter_handle, HBA_UINT32 hba){
/*
 ============================================================================
 Name       : hba_print_fcp_target_mapping
 Description: print the fiber channel port mappings.
 Notes      : this function uses malloc and free.
            : this function uses alloca--never use free against an alloca.
            : remember that alloca allocates to the stack and is automatically
            : cleaned at program termination.
 Input      : (1) pointer to adapter name
            : (2) open adapter handle
            : (3) current hba number
 ============================================================================
*/
  HBA_STATUS status;

  /* initialize the target map(s) structures */
  HBA_FCPTARGETMAPPING  fcp_target_map;
  PHBA_FCPTARGETMAPPING fcp_target_maps;
  memset( &fcp_target_map, 0, sizeof( HBA_FCPTARGETMAPPING ) );

  char *pwwn = ( char * )alloca( WWN_SIZE );
  char *nwwn = ( char * )alloca( WWN_SIZE );
  if ( ( pwwn == NULL ) || ( nwwn == NULL ) ) {
    if ( DEBUG )
      ( void )fprintf( stderr, "debug: failed to allocate memory for WWN\n" );
    hba_close_adapter( adapter_handle );
    hba_free_library();
    exit ( EX_OSERR );
  }

  fcp_target_map.NumberOfEntries = 1;
  status = HBA_GetFcpTargetMapping( adapter_handle, &fcp_target_map );
  if ( DEBUG ) { hba_fcp_target_mapping_status_check( status, "HBA_GetFcpTargetMapping" ); }

  if ( status == HBA_STATUS_ERROR_MORE_DATA ) {
    /* there are more entries, allocate memory and get the data */
    if ( fcp_target_map.NumberOfEntries > 0 ) {

      HBA_UINT32 mapsize = fcp_target_map.NumberOfEntries;
      fcp_target_maps = ( PHBA_FCPTARGETMAPPING )malloc( ( mapsize ) * sizeof( HBA_FCPTARGETMAPPING ) );

      if (fcp_target_maps) {

      memset( fcp_target_maps, 0, ( mapsize )*sizeof( HBA_FCPTARGETMAPPING ) );
        fcp_target_maps->NumberOfEntries = mapsize;

        status = HBA_GetFcpTargetMapping( adapter_handle, fcp_target_maps );
        if ( DEBUG ) { hba_fcp_target_mapping_status_check( status, "HBA_GetFcpTargetMapping" ); }

        if ( status != HBA_STATUS_OK ) {
          if ( fcp_target_maps != NULL ) { free( fcp_target_maps ); fcp_target_maps = NULL; }
          return ( -1 );
        }

        ( void )fprintf( stdout, "hba.%d.NumberOfLUNs = %d\n", hba, fcp_target_maps->NumberOfEntries );

        int lun;
        for ( lun = 0; lun < fcp_target_maps->NumberOfEntries; lun++ ) {

          /* Display the information */
          WWN2Cstring( pwwn, &fcp_target_maps->entry[lun].FcpId.PortWWN );
          WWN2Cstring( nwwn, &fcp_target_maps->entry[lun].FcpId.NodeWWN );
          ( void )fprintf( stdout, "hba.%d.lun_mapping.NodeWWN.%s.PortWWN.%s.BusNumber.%d.TargetNumber.%d.OSLun.%d.OSDeviceName.%s\n",
                    hba, nwwn, pwwn,
                    fcp_target_maps->entry[lun].ScsiId.ScsiBusNumber,
                    fcp_target_maps->entry[lun].ScsiId.ScsiTargetNumber,
                    fcp_target_maps->entry[lun].ScsiId.ScsiOSLun,
                    ( strlen( fcp_target_maps->entry[lun].ScsiId.OSDeviceName ) > 0 )
                        ? fcp_target_maps->entry[lun].ScsiId.OSDeviceName : NO_SUPP );

        }

      } else {
        /* memory allocation failed. clean-up and exit */
        if ( DEBUG )
          ( void )fprintf( stderr, "debug: failed to allocate memory for PHBA_FCPTARGETMAPPING\n" );

        if( fcp_target_maps != NULL ) { free(fcp_target_maps); fcp_target_maps = NULL; }
        hba_close_adapter( adapter_handle );
        hba_free_library();
        exit (EX_OSERR);
      }
      /* we have no entries. clean-up what has been allocated */
      if ( fcp_target_maps != NULL ) { free( fcp_target_maps ); fcp_target_maps = NULL; }
    }

  } else {
    /* there are either no adapters or we have an error */
    if ( status != HBA_STATUS_OK ) {
      if ( DEBUG ) { hba_fcp_target_mapping_status_check( status, "HBA_GetFcpTargetMapping" ); }
      return ( -1 );
    }

    ( void )fprintf( stdout, "hba.%d.NumberOfLUNs = %d\n", hba, fcp_target_map.NumberOfEntries );

  }

  /* Clean-up and Return */
  return ( 0 );
}

void get_systopo_hbainfo(int debug) {
/*
 ============================================================================
 Name       : get_systopo_hbainfo
 Description: obtain and print the requested HBA information.
 Notes      : this function uses alloca--never use free against an alloca.
            : remember that alloca allocates to the stack and is automatically
            : cleaned at program termination.
 Input      : (1) integer value for debug (0 = off, 1 = on)
 ============================================================================
 */

  DEBUG = debug;

  if ( (hba_load_library()) == -1 ) { exit ( EX_UNAVAILABLE ); }
  HBA_UINT32 adapter_count = hba_get_number_of_adapters();
  ( void )fprintf( stdout, "hba.total.count = %d\n", adapter_count );

  HBA_STATUS status;
  HBA_UINT32 hba;
  HBA_HANDLE adapter_handle = 0;

  for ( hba = 0; hba < adapter_count; hba++ ) {

    /* Allocate and Initialize the adapter name */
    char *adapter_name = ( char * )alloca( MAX_HBA_NAME );
    if ( adapter_name == NULL ) {
      if ( DEBUG )
        ( void )fprintf( stderr, "debug: failed to allocate memory for adapter_name\n" );

      if ( adapter_handle > 0 ) { hba_close_adapter(adapter_handle); }
      hba_free_library();
      exit ( EX_OSERR );
    }

    /* Get the current hba adapter name */
    if ( ( status = hba_get_adapter_name( hba, adapter_name ) ) == -1 ){ continue; }

    /* Close existing adapter handle before opening a new one */
    if ( adapter_handle != HBA_HANDLE_INVALID ) { hba_close_adapter( adapter_handle ); }
    HBA_HANDLE adapter_handle = hba_open_adapter( adapter_name );
    if ( adapter_handle == HBA_HANDLE_INVALID ) { continue; }

    /* Get and print the HBA information */
    if ( ( status = hba_print_adapter_attributes(adapter_name, adapter_handle, hba ) )  == -1 ){ continue; }
    if ( ( status = hba_print_port_attributes(adapter_name, adapter_handle, hba ) )     == -1 ){ continue; }
    if ( ( status = hba_print_fcp_target_mapping(adapter_name, adapter_handle, hba ) )  == -1 ){ continue; }

  }

  /* Clean-up and Return */
  if ( adapter_handle != HBA_HANDLE_INVALID ) { hba_close_adapter( adapter_handle ); }
  hba_free_library();

}

main.c (down and dirty):
Code:
#include <stdio.h>
#include <stdlib.h>
#include "hbainfo.h"

int main(void) {
  get_systopo_hbainfo(0);
  return (0);
}