1/*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19//
20// MDSPrefs.cpp
21//
22
23#include "MDSPrefs.h"
24#include <CoreFoundation/CFPreferences.h>
25#include <stdlib.h>
26
27// Construct the preferences object and read the current preference settings.
28
29MDSPrefs::MDSPrefs()
30    :	mPluginFolders(NULL)
31{
32    if (!readPathFromPrefs() && !readPathFromEnv())
33        useDefaultPath();
34}
35
36// Destroy the preferences object.
37
38MDSPrefs::~MDSPrefs()
39{
40    if (mPluginFolders)
41        CFRelease(mPluginFolders);
42}
43
44// Obtain the plugin path from a preferences file. Returns true on success of false
45// if no prefs could be found.
46
47bool
48MDSPrefs::readPathFromPrefs()
49{
50    static const CFStringRef kPrefsSuite = CFSTR("com.apple.mds");
51    static const CFStringRef kPluginPathKey = CFSTR("securityPluginPath");
52
53    bool result = true;
54
55    CFPreferencesAddSuitePreferencesToApp(kCFPreferencesCurrentApplication, kPrefsSuite);
56
57    CFPropertyListRef value;
58    value = CFPreferencesCopyAppValue(kPluginPathKey, kCFPreferencesCurrentApplication);
59
60    if (CFGetTypeID(value) != CFArrayGetTypeID())
61		// the prefs object is not an array, so fail
62		result = false;
63
64	else {
65        // make sure that all array elements are strings
66
67		CFArrayRef array = (CFArrayRef) value;
68		int numItems = CFArrayGetCount(array);
69		for (int i = 0; i < numItems; i++)
70			if (CFGetTypeID(CFArrayGetValueAtIndex(array, i)) != CFStringGetTypeID()) {
71				result = false;
72				break;
73			}
74	}
75
76	if (result)
77        mPluginFolders = (CFArrayRef) value;
78	else
79        CFRelease(value);
80
81    return result;
82}
83
84bool
85MDSPrefs::readPathFromEnv()
86{
87    static const char *kPluginPathEnv = "MDSPATH";
88    static const CFStringRef kSeparator = CFSTR(":");
89
90    char *envValue = getenv(kPluginPathEnv);
91    if (envValue) {
92        CFStringRef path = CFStringCreateWithCString(NULL, envValue, kCFStringEncodingUTF8);
93
94        mPluginFolders = CFStringCreateArrayBySeparatingStrings(NULL, path, kSeparator);
95
96        CFRelease(path);
97        return true;
98    }
99
100    return false;
101}
102
103void
104MDSPrefs::useDefaultPath()
105{
106    static const CFStringRef kDefaultPluginPath = CFSTR("/System/Library/Security");
107
108    mPluginFolders = CFArrayCreate(NULL, (const void **) &kDefaultPluginPath, 1, &kCFTypeArrayCallBacks);
109}
110
111// Retrieve the elements of the plugin path.
112
113int
114MDSPrefs::getNumberOfPluginFolders() const
115{
116    if (mPluginFolders)
117        return CFArrayGetCount(mPluginFolders);
118
119    return 0;
120}
121
122const char *
123MDSPrefs::getPluginFolder(int index)
124{
125    if (mPluginFolders) {
126        int numValues = CFArrayGetCount(mPluginFolders);
127        if (index >= 0 && index < numValues) {
128            CFStringRef value = (CFStringRef) CFArrayGetValueAtIndex(mPluginFolders, index);
129            if (value) {
130                // we have to copy the string since it may be using a different native
131                // encoding than the one we want. the copy is put in a temporary buffer,
132                // so its lifetime is limited to the next call to getPluginFolder() or to
133                // the destruction of the MDSPrefs object. Very long paths will silently fail.
134
135                if (CFStringGetCString(value, mTempBuffer, kTempBufferSize, kCFStringEncodingUTF8))
136                    return mTempBuffer;
137            }
138        }
139    }
140
141    return NULL;
142}
143
144