/* * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /*! * @header CPluginHandler */ #include #include #include #include "CPluginHandler.h" #include "CPlugInList.h" #include "ServerControl.h" #include "DirServiceMain.h" #include "CString.h" #include "COSUtils.h" #include "CLog.h" #include "CServerPlugin.h" // -------------------------------------------------------------------------------- // * Globals // -------------------------------------------------------------------------------- #warning VERIFY the version string for the static plugins before each software release //KW not clear we use the version string for anything yet in a static plugin //static plugin name and version strings static const char *sStaticPluginList[ kNumStaticPlugins ][ 2 ] = { { "Configure", "1.6" }, { "NetInfo", "1.6" }, { "LDAPv3", "1.6.3" }, { "Search", "1.6.1" } }; //-------------------------------------------------------------------------------------------------- // * CPluginHandler() // //-------------------------------------------------------------------------------------------------- CPluginHandler::CPluginHandler ( void ) : CInternalDispatchThread(kTSPlugInHndlrThread) { fThreadSignature = kTSPlugInHndlrThread; } // CPluginHandler //-------------------------------------------------------------------------------------------------- // * ~CPluginHandler() // //-------------------------------------------------------------------------------------------------- CPluginHandler::~CPluginHandler() { } // ~CPluginHandler //-------------------------------------------------------------------------------------------------- // * StartThread() // //-------------------------------------------------------------------------------------------------- void CPluginHandler::StartThread ( void ) { if ( this == nil ) throw((sInt32)eMemoryError); this->Resume(); } // StartThread //-------------------------------------------------------------------------------------------------- // * StopThread() // //-------------------------------------------------------------------------------------------------- void CPluginHandler::StopThread ( void ) { if ( this == nil ) throw((sInt32)eMemoryError); // Check that the current thread context is not our thread context // SignalIf_( this->IsCurrent() ); SetThreadRunState( kThreadStop ); // Tell our thread to stop } // StopThread //-------------------------------------------------------------------------------------------------- // * ThreadMain() // //-------------------------------------------------------------------------------------------------- long CPluginHandler::ThreadMain ( void ) { uInt32 uiPluginCnt = 0; uiPluginCnt = LoadPlugins(); if ( uiPluginCnt == 0 ) { //SRVRLOG( kLogApplication, "*** WARNING: No Plugins loaded ***" ); ERRORLOG( kLogApplication, "*** WARNING: No Plugins loaded ***" ); } else { DBGLOG1( kLogApplication, "%d Plugins loaded or processed.", uiPluginCnt ); DBGLOG( kLogApplication, "Initializing plugins." ); gPlugins->InitPlugIns(); } return( 0 ); } // ThreadMain //-------------------------------------------------------------------------------------------------- // * LoadPlugins () // //-------------------------------------------------------------------------------------------------- sInt32 CPluginHandler::LoadPlugins ( void ) { sInt32 status = eDSNoErr; uInt32 uiCount = 0; CString cSubPath( COSUtils::GetStringFromList( kAppStringsListID, kStrPlugInsFolder ) ); CString cOtherSubPath( COSUtils::GetStringFromList( kAppStringsListID, kStrOtherPlugInsFolder ) ); CString cPlugExt( COSUtils::GetStringFromList( kAppStringsListID, kStrPluginExtension ) ); CFStringRef sType = nil; char string [ PATH_MAX ]; //process the static plugin modules for (uInt32 iPlugin = 0; iPlugin < kNumStaticPlugins; iPlugin++) { status = CServerPlugin::ProcessStaticPlugin( sStaticPluginList[iPlugin][0], sStaticPluginList[iPlugin][1]); if (status == eDSNoErr) { uiCount++; } } //KW now we need to know which plugins are lazily loaded and which //are required now to be loaded //Retrieve all the Apple developed plugins sType = ::CFStringCreateWithCString( kCFAllocatorDefault, cPlugExt.GetData(), kCFStringEncodingMacRoman ); CFURLRef urlPath = 0; CFStringRef sBase, sPath; CFArrayRef aBundles; // Append the subpath. sBase = CFSTR( "/System/Library" ); sPath = ::CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@/%s" ), sBase, cSubPath.GetData() ); sBase = nil; ::CFStringGetCString( sPath, string, sizeof( string ), kCFStringEncodingMacRoman ); DBGLOG( kLogApplication, "Checking for plugins in:" ); DBGLOG1( kLogApplication, " %s", string ); // Convert it back into a CFURL. urlPath = ::CFURLCreateWithFileSystemPath( kCFAllocatorDefault, sPath, kCFURLPOSIXPathStyle, true ); ::CFRelease( sPath ); sPath = nil; // Enumerate all the plugins in this system directory. aBundles = ::CFBundleCopyResourceURLsOfTypeInDirectory( urlPath, sType, NULL ); ::CFRelease( urlPath ); urlPath = nil; if ( aBundles != nil ) { register CFIndex bundleCount = CFArrayGetCount( aBundles ); for ( register CFIndex j = 0; j < bundleCount; ++j ) { status = CServerPlugin::ProcessURL( (CFURLRef)::CFArrayGetValueAtIndex( aBundles, j ) ); if ( status == eDSNoErr ) { uiCount++; } else SRVRLOG( kLogApplication, "\tError loading plugin, see DirectoryService.error.log for details" ); } ::CFRelease( aBundles ); aBundles = nil; } if ( sType != nil ) { ::CFRelease( sType ); sType = nil; } //Now retrieve any Third party developed plugins sType = ::CFStringCreateWithCString( kCFAllocatorDefault, cPlugExt.GetData(), kCFStringEncodingMacRoman ); // Append the subpath. sBase = CFSTR( "/Library" ); sPath = ::CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@/%s" ), sBase, cOtherSubPath.GetData() ); sBase = nil; ::CFStringGetCString( sPath, string, sizeof( string ), kCFStringEncodingMacRoman ); DBGLOG( kLogApplication, "Checking for plugins in:" ); DBGLOG1( kLogApplication, " %s", string ); // Convert it back into a CFURL. urlPath = ::CFURLCreateWithFileSystemPath( kCFAllocatorDefault, sPath, kCFURLPOSIXPathStyle, true ); ::CFRelease( sPath ); sPath = nil; // Enumerate all the plugins in this system directory. aBundles = ::CFBundleCopyResourceURLsOfTypeInDirectory( urlPath, sType, NULL ); ::CFRelease( urlPath ); urlPath = nil; if ( aBundles != nil ) { register CFIndex j = ::CFArrayGetCount( aBundles ); while ( j-- ) { status = CServerPlugin::ProcessURL( (CFURLRef)::CFArrayGetValueAtIndex( aBundles, j ) ); if ( status == eDSNoErr ) { uiCount++; } else SRVRLOG( kLogApplication, "\tError loading 3rd party plugin, see DirectoryService.error.log for details" ); } ::CFRelease( aBundles ); aBundles = nil; } if ( sType != nil ) { ::CFRelease( sType ); sType = nil; } return( uiCount ); } // LoadPlugins