Re: netinfo header files on Panther
Re: netinfo header files on Panther
- Subject: Re: netinfo header files on Panther
- From: Stéphane Sudre <email@hidden>
- Date: Sun, 17 Jul 2005 12:39:27 +0200
On vendredi, juillet 15, 2005, at 10:55 PM, Chris Vitale wrote:
Hello,
Since new users are not added to /etc/passwd I doubted that the
standard
C password functions would work. I thought I'd have to use Apple's
fancy pants APIs. getpwent worked just fine.
In case you can stand Objective-C:
#import <Cocoa/Cocoa.h>
#include <DNSServiceDiscovery/DNSServiceDiscovery.h>
#include <DirectoryService/DirServices.h>
#include <DirectoryService/DirServicesUtils.h>
#include <DirectoryService/DirServicesConst.h>
@interface PBDirectoryServicesManager : NSObject
{
tDirReference directoryServicesReference_;
tDataBufferPtr dataBuffer_;
tDirNodeReference localNodeReference_;
NSMutableDictionary * usersCache_;
NSMutableDictionary * groupsCache_;
}
+ (PBDirectoryServicesManager *) defaultManager;
- (void) _buildCaches;
- (void) increaseDataBuffer;
- (NSMutableDictionary *) _dictionaryWithLocalRef:(tDirNodeReference)
inReference data:(tDataBufferPtr) inData count:(unsigned long) inCount;
- (NSMutableArray *) usersArray;
- (NSMutableArray *) groupsArray;
- (NSString *) userAccountForUID:(int) inUID;
- (NSString *) groupForGID:(int) inGID;
@end
------8<------------8<-------------8<-------------
#import "PBDirectoryServicesManager.h"
const long PBDS_BUFFER_SIZE = 8192;
@implementation PBDirectoryServicesManager
+ (PBDirectoryServicesManager *) defaultManager
{
static PBDirectoryServicesManager * sDSManager=nil;
if (sDSManager==nil)
{
sDSManager=[PBDirectoryServicesManager new];
[sDSManager _buildCaches];
}
return sDSManager;
}
- (id) init
{
self=[super init];
if (self!=nil)
{
tDirStatus tStatus;
tStatus = dsOpenDirService(&directoryServicesReference_);
if (tStatus == eDSNoErr)
{
dataBuffer_ =
dsDataBufferAllocate(directoryServicesReference_, PBDS_BUFFER_SIZE );
if (dataBuffer_!=NULL)
{
unsigned long tDirectoryNodeCount;
unsigned long tDirectoryNodeIndex;
long error;
char * tDirectoryNodePath;
tDirectoryNodeCount=0;
tDirectoryNodePath=NULL;
do
{
error =
dsFindDirNodes(directoryServicesReference_,dataBuffer_,NULL,eDSLocalNode
Names,&tDirectoryNodeCount,NULL);
if (error == eDSBufferTooSmall)
{
[self increaseDataBuffer];
}
}
while (error == eDSBufferTooSmall);
if ( error == eDSNoErr )
{
if (tDirectoryNodeCount!= 0)
{
tDataList * tDirectoryName;
tDirectoryName =
dsDataListAllocate(directoryServicesReference_);
if (tDirectoryName!=NULL)
{
for (tDirectoryNodeIndex =
1;(tDirectoryNodeIndex <= tDirectoryNodeCount) && (error == eDSNoErr);
tDirectoryNodeIndex++ )
{
error =
dsGetDirNodeName(directoryServicesReference_,dataBuffer_,tDirectoryNodeI
ndex, &tDirectoryName );
if ( error == eDSNoErr )
{
tDirectoryNodePath =
dsGetPathFromList(directoryServicesReference_,tDirectoryName, "/" );
if (tDirectoryNodePath!= NULL)
{
dsDataListDeallocate(directoryServicesReference_, tDirectoryName );
break;
}
else
{
NSLog(@"[PBDirectoryServicesUtilities.m:70 dsGetPathFromList failed");
}
}
}
}
else
{
NSLog(@"[PBDirectoryServicesUtilities.m:77
dsDataListAllocate failed");
error = 1;
}
}
}
if (tDirectoryNodePath!=NULL)
{
long error = eDSNoErr;
tDataList * tNodeList;
tNodeList =
dsBuildFromPath(directoryServicesReference_,tDirectoryNodePath, "/" );
if ( tNodeList != NULL )
{
error = dsOpenDirNode(
directoryServicesReference_, tNodeList, &localNodeReference_);
dsDataListDeallocate(directoryServicesReference_,tNodeList);
if (error==eDSNoErr)
{
return self;
}
}
}
}
dsCloseDirService(directoryServicesReference_);
}
return nil;
}
return self;
}
- (void) dealloc
{
if (localNodeReference_!=NULL)
{
dsCloseDirNode(localNodeReference_);
}
if (dataBuffer_!=NULL)
{
dsDataBufferDeAllocate(directoryServicesReference_,dataBuffer_);
}
if (directoryServicesReference_!=NULL)
{
dsCloseDirService(directoryServicesReference_);
}
}
#pragma mark -
- (void) increaseDataBuffer
{
unsigned long tBufferSize = dataBuffer_->fBufferSize;
dsDataBufferDeAllocate(directoryServicesReference_, dataBuffer_);
dataBuffer_=dsDataBufferAllocate( directoryServicesReference_,
tBufferSize*2 );
}
#pragma mark -
- (void) _buildCaches
{
long error = eDSNoErr;
unsigned long tRecordCount;
tContextData context = NULL;
tDataList * tRecordName;
// Users
tRecordCount=0;
tRecordName =
dsBuildListFromStrings(directoryServicesReference_,kDSRecordsAll,NULL);
if (tRecordName != NULL)
{
tDataList * tRecordType;
tRecordType =
dsBuildListFromStrings(directoryServicesReference_,kDSStdRecordTypeUsers
,NULL);
if (tRecordType!=NULL)
{
tDataList * tAttributesType;
// We're interesting by the uid and account name
tAttributesType =
dsBuildListFromStrings(directoryServicesReference_, kDS1AttrUniqueID,
NULL);
if (tAttributesType!=NULL)
{
do
{
error =
dsGetRecordList(localNodeReference_,dataBuffer_,tRecordName,eDSExact,tRe
cordType,tAttributesType,0,&tRecordCount,&context);
if ( error == eDSNoErr )
{
usersCache_=[[self
_dictionaryWithLocalRef:localNodeReference_ data:dataBuffer_
count:tRecordCount] retain];
if (usersCache_==nil)
{
error=eUndefinedError;
}
}
else if ( error == eDSBufferTooSmall )
{
[self increaseDataBuffer];
}
}
while (((error == eDSNoErr) && (context != NULL)) ||
(error == eDSBufferTooSmall) );
dsDataListDeallocate(directoryServicesReference_,tAttributesType);
}
dsDataListDeallocate(directoryServicesReference_,tRecordType);
}
dsDataListDeallocate(directoryServicesReference_, tRecordName );
}
// Groups
error = eDSNoErr;
context = NULL;
tRecordCount=0;
tRecordName =
dsBuildListFromStrings(directoryServicesReference_,kDSRecordsAll,NULL);
if (tRecordName != NULL)
{
tDataList * tRecordType;
tRecordType =
dsBuildListFromStrings(directoryServicesReference_,kDSStdRecordTypeGroup
s,NULL);
if (tRecordType!=NULL)
{
tDataList * tAttributesType;
// We're interesting by the gid and group name
tAttributesType =
dsBuildListFromStrings(directoryServicesReference_,
kDS1AttrPrimaryGroupID, NULL);
if (tAttributesType!=NULL)
{
do
{
error =
dsGetRecordList(localNodeReference_,dataBuffer_,tRecordName,eDSExact,tRe
cordType,tAttributesType,0,&tRecordCount,&context);
if ( error == eDSNoErr )
{
groupsCache_=[[self
_dictionaryWithLocalRef:localNodeReference_ data:dataBuffer_
count:tRecordCount] retain];
if (groupsCache_==nil)
{
error=eUndefinedError;
}
}
else if ( error == eDSBufferTooSmall )
{
[self increaseDataBuffer];
}
}
while (((error == eDSNoErr) && (context != NULL)) ||
(error == eDSBufferTooSmall) );
dsDataListDeallocate(directoryServicesReference_,tAttributesType);
}
dsDataListDeallocate(directoryServicesReference_,tRecordType);
}
dsDataListDeallocate(directoryServicesReference_, tRecordName );
}
}
- (NSMutableDictionary *) _dictionaryWithLocalRef:(tDirNodeReference)
inReference data:(tDataBufferPtr) inData count:(unsigned long) inCount
{
NSMutableDictionary * nMutableDictionary=nil;
unsigned long i;
long error;
tAttributeEntry * attributeEntryPtr = NULL;
tAttributeValueEntry * valueEntryPtr = NULL;
error = eDSNoErr;
nMutableDictionary=[NSMutableDictionary
dictionaryWithCapacity:inCount];
for (i = 1; (i <= inCount) && (error == eDSNoErr);i++)
{
tAttributeListRef attributeListRef = 0;
tRecordEntry * recordEntryPtr = NULL;
error = dsGetRecordEntry(inReference, inData, i,
&attributeListRef, &recordEntryPtr);
if ( error == eDSNoErr && recordEntryPtr!=NULL)
{
char * tRecordName=NULL;
unsigned long j;
error = dsGetRecordNameFromEntry( recordEntryPtr,
&tRecordName );
if (error==eDSNoErr && tRecordName!=NULL)
{
for (j = 1; (j <=
recordEntryPtr->fRecordAttributeCount) && (error == eDSNoErr);j++)
{
tAttributeValueListRef valueRef = 0;
error = dsGetAttributeEntry(inReference,inData,
attributeListRef, j, &valueRef, &attributeEntryPtr);
if (error == eDSNoErr && attributeEntryPtr)
{
unsigned long k;
for (k = 1; (k <=
attributeEntryPtr->fAttributeValueCount) && (error == eDSNoErr);k++)
{
error =
dsGetAttributeValue(inReference,inData,k,valueRef,&valueEntryPtr);
if ( error == eDSNoErr &&
valueEntryPtr!=NULL)
{
[nMutableDictionary setObject:[NSString
stringWithUTF8String:tRecordName] forKey:[NSNumber
numberWithInt:atoi(valueEntryPtr->fAttributeValueData.fBufferData)]];
dsDeallocAttributeValueEntry(directoryServicesReference_,valueEntryPtr
);
valueEntryPtr = NULL;
break;
}
else
{
// A COMPLETER
}
}
dsDeallocAttributeEntry(directoryServicesReference_,attributeEntryPtr);
attributeEntryPtr = NULL;
dsCloseAttributeValueList(valueRef);
valueRef = 0;
}
else
{
// A COMPLETER
}
}
free(tRecordName);
}
dsDeallocRecordEntry(directoryServicesReference_,recordEntryPtr);
recordEntryPtr = NULL;
dsCloseAttributeList(attributeListRef);
}
else
{
// A COMPLETER
}
}
return nMutableDictionary;
}
- (NSMutableArray *) usersArray
{
NSMutableArray * tMutableArray=nil;
int tCount;
tCount=[usersCache_ count];
tMutableArray=[NSMutableArray arrayWithCapacity:tCount];
if (tMutableArray!=nil && tCount>0)
{
NSEnumerator * tKeyEnumerator;
NSNumber * tKey;
tKeyEnumerator=[usersCache_ keyEnumerator];
while (tKey=[tKeyEnumerator nextObject])
{
NSDictionary * tDictionary;
tDictionary=[NSDictionary
dictionaryWithObjectsAndKeys:[usersCache_ objectForKey:tKey],@"Name",
tKey,@"ID",
nil];
[tMutableArray addObject:tDictionary];
}
}
return tMutableArray;
}
- (NSMutableArray *) groupsArray
{
NSMutableArray * tMutableArray=nil;
int tCount;
tCount=[groupsCache_ count];
tMutableArray=[NSMutableArray arrayWithCapacity:tCount];
if (tMutableArray!=nil && tCount>0)
{
NSEnumerator * tKeyEnumerator;
NSNumber * tKey;
tKeyEnumerator=[groupsCache_ keyEnumerator];
while (tKey=[tKeyEnumerator nextObject])
{
NSDictionary * tDictionary;
tDictionary=[NSDictionary
dictionaryWithObjectsAndKeys:[groupsCache_ objectForKey:tKey],@"Name",
tKey,@"ID",
nil];
[tMutableArray addObject:tDictionary];
}
}
return tMutableArray;
}
- (NSString *) userAccountForUID:(int) inUID
{
return [usersCache_ objectForKey:[NSNumber numberWithInt:inUID]];
}
- (NSString *) groupForGID:(int) inGID
{
return [groupsCache_ objectForKey:[NSNumber numberWithInt:inGID]];
}
@end
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden