#include <stdio.h>
#include <stdlib.h>
#include <DirectoryService/DirectoryService.h>
#ifndef bool
typedef enum { false = 0, true = 1 } bool;
#endif /* bool */
// 32k buffer
#define BUFFERSIZE 32 * 1024
int main( int argc, char *argv[] )
{
int ret = 0 ;
long dirStatus = eDSNoErr ;
tDirReference dirRef = 0 ;
tDirNodeReference nodeRef = 0 ;
const char *nodePath = (argc > 1 ? argv[1] : "/Local/Default" );
tDataListPtr nodeName = NULL ;
tDataList recNames, recTypes, attrTypes ;
tDataBufferPtr dataBuffer = NULL;
unsigned long recCount = 0 ;
tContextData recContext = NULL ;
// open OD
dirStatus = dsOpenDirService( &dirRef );
if( dirStatus != eDSNoErr ) goto errexit ;
// open node
nodeName = dsBuildFromPath( dirRef, nodePath, "/" );
if( nodeName == NULL )
{
fprintf( stderr, "name buffer allocate error\n") ;
ret = 1;
goto toexit;
}
dirStatus = dsOpenDirNode( dirRef, nodeName, &nodeRef );
if( dirStatus != eDSNoErr ) goto errexit ;
// allocate buffer
dataBuffer = dsDataBufferAllocate( dirRef, BUFFERSIZE );
if( dataBuffer == NULL ) // allocate error
{
fprintf( stderr, "data buffer allocate error\n") ;
ret = 1;
goto toexit;
}
// make query
dirStatus = dsBuildListFromStringsAlloc( dirRef, &recNames, kDSRecordsAll, NULL );
if( dirStatus != eDSNoErr ) goto errexit ;
dirStatus = dsBuildListFromStringsAlloc( dirRef, &recTypes, kDSStdRecordTypeUsers, NULL );
if( dirStatus != eDSNoErr ) goto errexit ;
dirStatus = dsBuildListFromStringsAlloc( dirRef, &attrTypes, kDSAttributesAll, NULL );
if( dirStatus != eDSNoErr ) goto errexit ;
do {
int i, j, k;
tAttributeListRef attrListRef = 0 ;
tRecordEntry *recEntryPtr = NULL ;
tAttributeValueListRef valueListRef = 0 ;
tAttributeEntry *attrEntryPtr = NULL ;
tAttributeValueEntry *valueEntryPtr = NULL ;
dirStatus = dsGetRecordList( nodeRef,
dataBuffer,
&recNames,
eDSExact,
&recTypes,
&attrTypes,
false,
&recCount,
&recContext );
if( dirStatus != eDSNoErr ) goto errexit ;
for( i = 1 ; i <= recCount; i++ )
{
dirStatus = dsGetRecordEntry( nodeRef, dataBuffer, i, &attrListRef, &recEntryPtr );
if( dirStatus != eDSNoErr ) goto errexit ; // BUG: has memory-leak
printf("RecordNumber: %d\n\n", i );
for( j = 1 ; j <= recEntryPtr->fRecordAttributeCount ; j ++ )
{
dirStatus = dsGetAttributeEntry( nodeRef, dataBuffer, attrListRef, j, &valueListRef, &attrEntryPtr );
if( dirStatus != eDSNoErr ) goto errexit ; // BUG: has memory-leak
printf(" --------------------------------------------\n" );
printf(" Attribute %d : %s:\n", j, attrEntryPtr->fAttributeSignature.fBufferData );
for( k = 1 ; k <= attrEntryPtr->fAttributeValueCount ; k ++ )
{
dirStatus = dsGetAttributeValue( nodeRef, dataBuffer, k, valueListRef, &valueEntryPtr );
printf(" Value %d : %s \n", k,valueEntryPtr->fAttributeValueData.fBufferData );
dsDeallocAttributeValueEntry( dirRef, valueEntryPtr );
}
dsDeallocAttributeEntry( dirRef, attrEntryPtr );
}
dsDeallocRecordEntry( dirRef, recEntryPtr );
printf("\n------------------------------------------------\n" );
}
}while( recContext != NULL );
goto toexit;
errexit:
ret = 1;
fprintf( stderr, "errocode = %d\n", dirStatus );
toexit:
if( recContext != NULL )
dsReleaseContinueData( dirRef, recContext );
if( dataBuffer != NULL )
dsDataBufferDeAllocate( dirRef, dataBuffer );
if( nodeRef != 0 )
dsCloseDirNode( nodeRef );
if( dirRef != 0 )
dsCloseDirService( dirRef );
exit(ret);
}