[CalendarServer-changes] [3914] PyOpenDirectory/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Mar 23 18:47:17 PDT 2009


Revision: 3914
          http://trac.macosforge.org/projects/calendarserver/changeset/3914
Author:   cdaboo at apple.com
Date:     2009-03-23 18:47:17 -0700 (Mon, 23 Mar 2009)
Log Message:
-----------
New API to get the list of currently configured nodes.

Modified Paths:
--------------
    PyOpenDirectory/trunk/pysrc/opendirectory.py
    PyOpenDirectory/trunk/src/CDirectoryService.cpp
    PyOpenDirectory/trunk/src/CDirectoryService.h
    PyOpenDirectory/trunk/src/PythonWrapper.cpp
    PyOpenDirectory/trunk/support/test.cpp
    PyOpenDirectory/trunk/test.py

Modified: PyOpenDirectory/trunk/pysrc/opendirectory.py
===================================================================
--- PyOpenDirectory/trunk/pysrc/opendirectory.py	2009-03-23 18:09:15 UTC (rev 3913)
+++ PyOpenDirectory/trunk/pysrc/opendirectory.py	2009-03-24 01:47:17 UTC (rev 3914)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -27,6 +27,14 @@
         C{None} on failure.
     """
 
+def listNodes(obj):
+    """
+    List all the nodes current configured in Open Directory.
+
+    @param obj: C{object} the object obtained from an odInit call.
+    @return: C{list} containing a C{str} for each configured node.
+    """
+    
 def listAllRecordsWithAttributes(obj, recordType, attributes, count=0):
     """
     List records in Open Directory, and return key attributes for each one.

Modified: PyOpenDirectory/trunk/src/CDirectoryService.cpp
===================================================================
--- PyOpenDirectory/trunk/src/CDirectoryService.cpp	2009-03-23 18:09:15 UTC (rev 3913)
+++ PyOpenDirectory/trunk/src/CDirectoryService.cpp	2009-03-24 01:47:17 UTC (rev 3914)
@@ -2,7 +2,7 @@
  * A class that wraps high-level Directory Service calls needed by the
  * CalDAV server.
  **
- * Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2006-2009 Apple Inc. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -71,6 +71,36 @@
     mNodeName = NULL;
 }
 
+// ListNodes
+//
+// List all the nodes in the directory.
+//
+// @return: CFMutableArrayRef composed of CFStringRef for each node.
+//
+CFMutableArrayRef CDirectoryService::ListNodes(bool using_python)
+{
+    try
+    {
+        StPythonThreadState threading(using_python);
+		
+        // Get list
+        return _ListNodes();
+    }
+    catch(CDirectoryServiceException& dserror)
+    {
+		if (using_python)
+			dserror.SetPythonException();
+        return NULL;
+    }
+    catch(...)
+    {
+        CDirectoryServiceException dserror;
+		if (using_python)
+	        dserror.SetPythonException();
+        return NULL;
+    }
+}
+
 // ListAllRecordsWithAttributes
 //
 // Get specific attributes for one or more user records in the directory.
@@ -190,6 +220,83 @@
 
 #pragma mark -----Private API
 
+// _ListNodes
+//
+// List all the nodes in the directory.
+//
+// @return: CFMutableArrayRef composed of CFStringRef for each node.
+//
+CFMutableArrayRef CDirectoryService::_ListNodes()
+{
+    CFMutableArrayRef result = NULL;
+    tContextData context = NULL;
+	
+    try
+    {
+        // Make sure we have a valid directory service
+        OpenService();
+		
+        // We need a buffer for what comes next
+        CreateBuffer();
+		
+        result = ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+
+        do
+        {
+            // List all the appropriate records
+			UInt32 nodeCount = 0;
+            tDirStatus err;
+            do
+            {
+                err = ::dsGetDirNodeList(mDir, mData, &nodeCount, &context);
+                if (err == eDSBufferTooSmall)
+                    ReallocBuffer();
+            } while(err == eDSBufferTooSmall);
+            ThrowIfDSErr(err);
+            for(UInt32 i = 1; i <= nodeCount; i++)
+            {
+                // Get the record entry
+				tDataListPtr nodeData = NULL;
+                ThrowIfDSErr(::dsGetDirNodeName(mDir, mData, i, &nodeData));
+
+				char* nodePath = ::dsGetPathFromList(mDir, nodeData, "/");
+				if (nodePath != NULL)
+				{
+					CFStringUtil strvalue(nodePath);
+					::CFArrayAppendValue(result, strvalue.get());
+					::free(nodePath);
+					nodePath = NULL;
+				}
+
+				::dsDataListDeallocate(mDir, nodeData);
+				::free(nodeData);
+				
+            }
+        } while (context != NULL); // Loop until all data has been obtained.
+			
+        RemoveBuffer();
+        CloseService();
+    }
+    catch(CDirectoryServiceException& dsStatus)
+    {
+        // Cleanup
+        if (context != NULL)
+            ::dsReleaseContinueData(mDir, context);
+
+        RemoveBuffer();
+        CloseService();
+		
+        if (result != NULL)
+        {
+            ::CFRelease(result);
+            result = NULL;
+        }
+        throw;
+    }
+	
+    return result;
+}
+
 // _ListAllRecordsWithAttributes
 //
 // Get specific attributes for records of a specified type in the directory.

Modified: PyOpenDirectory/trunk/src/CDirectoryService.h
===================================================================
--- PyOpenDirectory/trunk/src/CDirectoryService.h	2009-03-23 18:09:15 UTC (rev 3913)
+++ PyOpenDirectory/trunk/src/CDirectoryService.h	2009-03-24 01:47:17 UTC (rev 3914)
@@ -2,7 +2,7 @@
  * A class that wraps high-level Directory Service calls needed by the
  * CalDAV server.
  **
- * Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2006-2009 Apple Inc. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,6 +31,8 @@
     CDirectoryService(const char* nodename);
     virtual ~CDirectoryService();
 
+    CFMutableArrayRef ListNodes(bool using_python=true);
+
     CFMutableArrayRef ListAllRecordsWithAttributes(CFArrayRef recordTypes, CFDictionaryRef attributes, UInt32 maxRecordCount=0, bool using_python=true);
     CFMutableArrayRef QueryRecordsWithAttribute(const char* attr, const char* value, int matchType, bool casei, CFArrayRef recordTypes, CFDictionaryRef attributes, UInt32 maxRecordCount=0, bool using_python=true);
     CFMutableArrayRef QueryRecordsWithAttributes(const char* query, bool casei, CFArrayRef recordTypes, CFDictionaryRef attributes, UInt32 maxRecordCount=0, bool using_python=true);
@@ -64,6 +66,8 @@
     tDataBufferPtr        mData;
     UInt32                mDataSize;
 
+    CFMutableArrayRef _ListNodes();
+
     CFMutableArrayRef _ListAllRecordsWithAttributes(CFArrayRef recordTypes, CFArrayRef names, CFDictionaryRef attrs, UInt32 maxRecordCount);
     CFMutableArrayRef _QueryRecordsWithAttributes(const char* attr, const char* value, int matchType, const char* compound, bool casei, CFArrayRef recordTypes, CFDictionaryRef attrs, UInt32 maxRecordCount);
 

Modified: PyOpenDirectory/trunk/src/PythonWrapper.cpp
===================================================================
--- PyOpenDirectory/trunk/src/PythonWrapper.cpp	2009-03-23 18:09:15 UTC (rev 3913)
+++ PyOpenDirectory/trunk/src/PythonWrapper.cpp	2009-03-24 01:47:17 UTC (rev 3914)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2006-2009 Apple Inc. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -633,19 +633,58 @@
 }
 
 /*
-def listAllRecordsWithAttributes(obj, recordType, attributes, count=0):
-    """
-    List records in Open Directory, and return key attributes for each one. The attributes
-    can be a C{str} for the attribute name, or a C{tuple} or C{list} where the first C{str}
-    is the attribute name, and the second C{str} is an encoding type, either "str" or "base64".
+ def listNodes(obj):
+	 """
+	 List all the nodes currently configured in Open Directory.
 
-    @param obj: C{object} the object obtained from an odInit call.
-    @param recordType: C{str}, C{tuple} or C{list} containing the OD record types to lookup.
-    @param attributes: C{list} or C{tuple} containing the attributes to return for each record.
-	@param count: C{int} maximum number of records to return (zero returns all).
-    @return: C{dict} containing a C{dict} of attributes for each record found,
-        or C{None} otherwise.
+	 @param obj: C{object} the object obtained from an odInit call.
+	 @return: C{list} containing a C{str} for each configured node.
+	 """
  */
+extern "C" PyObject *listNodes(PyObject *self, PyObject *args)
+{
+    PyObject* pyds;
+    if (!PyArg_ParseTuple(args, "O", &pyds) || !PyCObject_Check(pyds))
+    {
+        PyErr_SetObject(ODException_class, Py_BuildValue("((s:i))", "DirectoryServices listNodes: could not parse arguments", 0));
+        return NULL;
+    }
+
+    CDirectoryServiceManager* dsmgr = static_cast<CDirectoryServiceManager*>(PyCObject_AsVoidPtr(pyds));
+    if (dsmgr != NULL)
+    {
+        std::auto_ptr<CDirectoryService> ds(dsmgr->GetService());
+        CFMutableArrayRef results = NULL;
+        results = ds->ListNodes();
+        if (results != NULL)
+        {
+            PyObject* result = CFArrayToPyList(results);
+            CFRelease(results);
+
+            return result;
+        }
+    }
+    else
+        PyErr_SetObject(ODException_class, Py_BuildValue("((s:i))", "DirectoryServices listNodes: invalid directory service argument", 0));
+
+    return NULL;
+}
+
+/*
+ def listAllRecordsWithAttributes(obj, recordType, attributes, count=0):
+	 """
+	 List records in Open Directory, and return key attributes for each one. The attributes
+	 can be a C{str} for the attribute name, or a C{tuple} or C{list} where the first C{str}
+	 is the attribute name, and the second C{str} is an encoding type, either "str" or "base64".
+
+	 @param obj: C{object} the object obtained from an odInit call.
+	 @param recordType: C{str}, C{tuple} or C{list} containing the OD record types to lookup.
+	 @param attributes: C{list} or C{tuple} containing the attributes to return for each record.
+	 @param count: C{int} maximum number of records to return (zero returns all).
+	 @return: C{dict} containing a C{dict} of attributes for each record found,
+	 or C{None} otherwise.
+	 """
+ */
 extern "C" PyObject *listAllRecordsWithAttributes(PyObject *self, PyObject *args)
 {
 	return _listAllRecordsWithAttributes(self, args, false);
@@ -860,6 +899,8 @@
 static PyMethodDef ODMethods[] = {
     {"odInit",  odInit, METH_VARARGS,
         "Initialize the Open Directory system."},
+    {"listNodes",  listNodes, METH_VARARGS,
+        "List all the nodes currently configured in Open Directory."},
     {"listAllRecordsWithAttributes",  listAllRecordsWithAttributes, METH_VARARGS,
         "List all records of the specified type in Open Directory, returning requested attributes."},
     {"queryRecordsWithAttribute",  queryRecordsWithAttribute, METH_VARARGS,

Modified: PyOpenDirectory/trunk/support/test.cpp
===================================================================
--- PyOpenDirectory/trunk/support/test.cpp	2009-03-23 18:09:15 UTC (rev 3913)
+++ PyOpenDirectory/trunk/support/test.cpp	2009-03-24 01:47:17 UTC (rev 3914)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2006-2009 Apple Inc. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -44,6 +44,30 @@
 	CDirectoryService* dir = new CDirectoryService("/Search");
 	CDirectoryServiceAuth* authdir = new CDirectoryServiceAuth();
 
+	CFMutableArrayRef data = dir->ListNodes(false);
+	if (data != NULL)
+	{
+		printf("\n*** Nodes: %d ***\n", CFArrayGetCount(data));
+		for(CFIndex i = 0; i < CFArrayGetCount(data); i++)
+		{
+			CFStringRef str = (CFStringRef)CFArrayGetValueAtIndex(data, i);
+			const char* bytes = CFStringGetCStringPtr(str, kCFStringEncodingUTF8);
+			
+			if (bytes == NULL)
+			{
+				char localBuffer[256];
+				Boolean success;
+				success = CFStringGetCString(str, localBuffer, 256, kCFStringEncodingUTF8);
+				printf("%d: %s\n", i, localBuffer);
+			}
+			else
+			{
+				printf("%d: %s\n", i, (const char*)bytes);
+			}
+		}
+		CFRelease(data);
+	}
+
 #if 1
 #if 0
 	CFStringRef attrs[3];

Modified: PyOpenDirectory/trunk/test.py
===================================================================
--- PyOpenDirectory/trunk/test.py	2009-03-23 18:09:15 UTC (rev 3913)
+++ PyOpenDirectory/trunk/test.py	2009-03-24 01:47:17 UTC (rev 3914)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -25,6 +25,15 @@
 	else:
 		print "OK odInit"
 
+	def listNodes():
+		l = opendirectory.listNodes(ref)
+		if l is None:
+			print "Failed to list nodes"
+		else:
+			print "\nlistNodes number of results = %d" % (len(l),)
+			for n in l:
+				print "Node: %s" % n
+	
 	def listUsers():
 		d = opendirectory.listAllRecordsWithAttributes(ref, dsattributes.kDSStdRecordTypeUsers,
 													   (
@@ -351,6 +360,7 @@
 		else:
 			print "Failed to authenticate user"
 	
+	listNodes()
 	listUsers()
 	listGroups()
 	listComputers()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090323/89ec7600/attachment-0001.html>


More information about the calendarserver-changes mailing list