atnds_test.c

This extended example shows how to convert AFTN address to the corresponding AMHS form, and vice versa. The example also makes use of DSAPI to connect to the directory and manipulate directory data.

To compile this example on Unix machines:

cc -c -I/opt/isode/include/isode/ds/atnds/ -I/opt/isode/include
      -I/opt/isode/include/h

To link this example on Unix machines:

cc -o atnds_test atnds_test.o -L/opt/isode/lib \
    -latnds -ldua -lisode -libase -lmdldap -lmdlber -lssl -lcrypto
/* Copyright (c) 2004-2010, Isode Limited, London, England.
* All rights reserved.
*
* Acquisition and use of this software and related materials for any
* purpose requires a written licence agreement from Isode Limited,
* or a written licence from an organisation licenced by Isode Limited
* to grant such a licence.
*
*/
/*
* atnds_test.c
*
* Test functions of ATNds C library.
*
*/
/*
*
* @VERSION@
*/
#include <stdio.h>
#include <string.h>
DS_Session *ds;
static int read_atn_user (const char *prog, DS_DN *user_dn);
static const char underline[] =
"----------------------------------------------------------------";
static void usage(const char *prog)
{
fprintf( stderr, "Usage: %s "
"[-call presentation-address] "
"[-dn registry-dn] "
"[-read] "
"[-nodn] "
"[-inverse] "
"[-verbose] "
"aftn/caas/xf-address\n", prog );
}
int main( int argc, char *argv[] )
{
const char *call_addr = "Internet=localhost+19999";
const char *registry_dn_str = "o=Isode-MD-Register";
int read_entry = 0;
int inverse = 0;
int verbose = 0;
int reverse = 0;
int show_dn = 1;
int arg = 1;
DS_DN *registry_dn;
DS_DN *user_dn;
char *orbuf = NULL;
size_t orbuf_len;
DS_Indication *di = NULL;
DS_Status status;
DS_ErrorType t;
DS_ErrorValue v;
char *dnbuf;
size_t dnbuf_len;
char aftnbuf[9];
/* Avoid getopt() as it doesn't exist everywhere */
while ( arg < argc && argv[arg][0] == '-' ) {
if ( strncmp( argv[arg], "-call", strlen( argv[arg] ) ) == 0 ) {
if ( arg + 1 <= argc ) {
call_addr = argv[arg + 1];
arg += 2;
continue;
}
}
if ( strncmp( argv[arg], "-dn", strlen( argv[arg] ) ) == 0 ) {
if ( arg + 1 <= argc ) {
registry_dn_str = argv[arg + 1];
arg += 2;
continue;
}
}
if ( strncmp( argv[arg], "-nodn", strlen( argv[arg] ) ) == 0 ) {
show_dn = 0;
arg++;
continue;
}
if ( strncmp( argv[arg], "-read", strlen( argv[arg] ) ) == 0 ) {
read_entry = 1;
arg++;
continue;
}
if ( strncmp( argv[arg], "-inverse", strlen( argv[arg] ) ) == 0 ) {
inverse = 1;
arg++;
continue;
}
if ( strncmp( argv[arg], "-verbose", strlen( argv[arg] ) ) == 0 ) {
verbose = 1;
arg++;
continue;
}
if ( strncmp( argv[arg], "-reverse", strlen( argv[arg] ) ) == 0 ) {
reverse = 1;
arg++;
continue;
}
usage( argv[0] );
return 1;
}
/* argv[arg] should be the address to convert */
if ( arg != argc - 1 ) {
usage( argv[0] );
return 1;
}
/* Initialize the DUA library. */
if ( verbose ) {
printf( "\nTEST: initializing DUA library %s.\n", call_addr );
printf( "%s\n", underline );
}
status = DS_Initialize();
if ( status != DS_E_NOERROR ) {
fprintf( stderr, "%s: couldn't initialize DUA library\n", argv[0] );
return status;
}
/* Attempt to bind." */
if ( verbose ) {
printf( "\nTEST: bind (to %s)\n", call_addr );
printf( "%s\n", underline );
}
status = DS_Session_New( call_addr, 0, &ds );
if ( status != DS_E_NOERROR ) {
fprintf( stderr, "%s: failed to create session\n", argv[0] );
return 1;
}
status = DS_BindAnonymousSync( ds, NULL, &di );
if ( ! ( DS_Indication_GetErrorCodes( di, &t, &v ) == DS_E_NOERROR &&
t == DS_E_SUCCESS ) )
status = DS_E_DSOPFAILED;
DS_Indication_Delete( di );
if ( status != DS_E_NOERROR ) {
DS_UnbindSync( &ds );
fprintf( stderr, "%s: couldn't bind to directory\n", argv[0] );
return 1;
}
if ( verbose ) {
printf( "SUCCESS: bound to directory\n" );
}
/* Convert string registry DN to DSAPI DN structure. */
status = DS_String2DN( registry_dn_str, &registry_dn );
if ( status != DS_E_NOERROR ) {
fprintf ( stderr, "%s: error converting DN (%s)\n", argv[0],
registry_dn_str );
return DS_E_BADDN;
}
if ( verbose ) {
printf( "\nTEST: convert to X.400 (%s)\n", argv[arg] );
}
if (!reverse) {
status = ATNds_AFTN2AMHS( ds, registry_dn, argv[arg],
&orbuf, &orbuf_len, &user_dn );
if ( verbose ) {
printf( "%s\n", underline );
}
if ( status != DS_E_NOERROR ) {
switch ( status ) {
case DS_E_NOTFOUND:
fprintf( stderr, "%s: conversion data not found "
"in the ATN directory\n", argv[0] );
return status;
default:
fprintf ( stderr, "%s: conversion failed "
"(%d - no error message available)\n", argv[0], status );
return status;
}
}
if ( verbose ) {
printf( "SUCCESS: conversion succeeded.\n" );
printf( "DETAIL: O/R address is %s\n\n", orbuf );
} else {
printf( "X.400 = %s\n", orbuf );
}
if ( user_dn != NULL ) {
status = DS_DN2String( user_dn, &dnbuf, &dnbuf_len );
if ( status != DS_E_NOERROR ) {
fprintf( stderr, "%s: failed to parse aMHSUser entry DN\n",
argv[0] );
} else {
if ( verbose ) {
printf( "DETAIL: aMHSUser entry DN is %s.\n", dnbuf );
} else if ( show_dn ) {
printf( "User DN = %s\n", dnbuf );
}
ATNds_free( dnbuf );
}
DS_DN_Delete( user_dn );
} else {
if ( verbose ) {
printf( "DETAIL: no aMHSUser entry DN could be computed.\n");
}
}
/* Return now unless we want to do the inverse mapping. */
if ( inverse == 0 ) {
ATNds_free( ( void * ) orbuf );
DS_DN_Delete( registry_dn );
return 0;
}
}
/* Perform inverse conversion. */
if ( verbose ) {
printf( "\nTEST: performing inverse conversion\n(from %s)\n", orbuf );
printf( "%s\n", underline );
}
status = ATNds_AMHS2AFTN( ds, registry_dn, (reverse) ? argv[arg] : orbuf, aftnbuf, &user_dn );
if (orbuf != NULL)
ATNds_free( ( void * ) orbuf );
if ( status != DS_E_NOERROR ) {
DS_DN_Delete( registry_dn );
switch ( status ) {
case DS_E_NOTFOUND:
fprintf( stderr, "%s: conversion data not available\n", argv[0] );
return status;
default:
fprintf ( stderr, "%s: conversion failed "
"(%d - no error message available)\n", argv[0], status );
return status;
}
}
if ( verbose ) {
printf( "SUCCESS: conversion succeeded.\n" );
printf( "DETAIL: AFTN address is %s\n", aftnbuf );
} else {
printf( "AFTN (inverse) = %s\n", aftnbuf );
}
if ( user_dn != NULL ) {
status = DS_DN2String( user_dn, &dnbuf, &dnbuf_len );
if ( status != DS_E_NOERROR ) {
fprintf( stderr, "%s: failed to display aMHSUser entry DN\n",
argv[0] );
} else {
if ( verbose ) {
printf( "DETAIL: aMHSUser entry DN is %s.\n", dnbuf );
} else if ( show_dn ) {
printf( "User DN (inverse) = %s\n", dnbuf );
}
ATNds_free( dnbuf );
}
if ( read_entry )
read_atn_user( argv[0], user_dn );
DS_DN_Delete( user_dn );
} else {
if ( verbose ) {
printf( "DETAIL: no aMHSUser entry DN could be computed.\n");
}
}
/* Clean up. */
DS_DN_Delete( registry_dn );
/* Unbind from the DSA */
DS_UnbindSync( &ds );
/* All tests done. */
return 0;
}
static int
read_atn_user ( const char *prog, DS_DN *user_dn ) {
DS_Indication *di = NULL;
const DS_EntryList *el;
const DS_Entry *e;
const DS_AttrList *al;
const DS_Attr *a;
DS_ErrorType t;
DS_ErrorValue v;
DS_ErrorType type_p;
int status;
status = DS_ReadSync( ds, user_dn, NULL, NULL, &di );
if ( status != DS_E_NOERROR ) {
if ( di != NULL ) {
DS_Indication_GetStatus ( di, &type_p ) ;
DS_Indication_Delete ( di );
if ( type_p == DS_E_NAME ) {
fprintf( stderr, "%s: No DSA entry for this ATN User entry\n",
prog );
return 0;
}
}
fprintf( stderr, "%s: Failed to read ATN User entry (status=%d)\n",
prog, status );
return 1;
}
if ( ! ( DS_Indication_GetErrorCodes( di, &t, &v ) == DS_E_NOERROR && t == DS_E_SUCCESS ) ) {
return 1;
}
status = DS_Indication_GetEntryList( di, &el );
if ( status != DS_E_NOERROR ) {
DS_Indication_Delete ( di );
fprintf( stderr, "%s: Failed to read ATN User entry Indication\n",
prog );
return 2;
}
e = DS_EntryList_GetFirst( el );
status = DS_Entry_GetAttrList( e, &al );
if ( status != DS_E_NOERROR ) {
DS_Indication_Delete ( di );
fprintf( stderr, "%s: Failed to read attribute list for "
"ATN User entry\n", prog );
return 3;
}
for ( a = DS_AttrList_GetFirst( al );
a != NULL;
a = DS_AttrList_GetNext( a ) ) {
const char *name;
const DS_AttrValList *vl;
const DS_AttrVal *av;
DS_Attr_GetTypeName( a, &name );
/* Don't free name */
status = DS_Attr_GetValueList( a, &vl );
if ( status != DS_E_NOERROR ) {
DS_Indication_Delete ( di );
fprintf( stderr, "%s: Failed to read attribute values for "
"ATN User entry\n", prog );
return 4;
}
for ( av = DS_AttrValList_GetFirst( vl );
av != NULL;
av = DS_AttrValList_GetNext( av ) ) {
const char *val_str;
size_t val_len;
status = DS_AttrVal_GetStringPointer( av, &val_str, &val_len );
if ( status == DS_E_NOERROR )
printf( "%s: %s\n", name, val_str );
else
printf( "%s: (No string value)\n", name );
/* Don't free val_str */
}
}
DS_Indication_Delete ( di );
return 0;
}