Chameleon Applications

Chameleon Applications Svn Source Tree

Root/ChameleonPrefPane/Sources/property_list.cpp

Source at commit 1 created 14 years 3 months ago.
By rekursor, inital import of beta6
1/*
2 * property_list.cpp
3 *
4 * Created by Rekursor on 1/17/10.
5 *
6 */
7
8#include "property_list.h"
9#include <string.h>
10
11/****************************************************************************/
12/**
13 * Simple parsing and splitting args function, does handle env. vars
14 */
15static void parseArgs(const char * args, const char* argv[], int argvlen)
16{
17// Create a list of args fron the space delimited args parameters
18int n=0;
19if (args && *args)
20{
21bool skipSpaces = true;
22bool prevCharwasDelim =false;
23char * buf = strdup(args);
24char lastPriorityDelim=' ';
25
26printf("Parsing <%s>\n", args);
27
28int k=0;
29for (int i=0; i< strlen(args); i++)
30{
31switch (args[i])
32{
33case ' ': case '\t':
34if(!skipSpaces) {
35buf[k++]=args[i];
36}
37else {
38prevCharwasDelim = true; // // keep a track of delim to further split tokens
39}
40break;
41case '\0':
42case '\'':
43case '"':
44if (!skipSpaces &&lastPriorityDelim!=args[i])
45{ // consider the imbricated delim as a simple char
46buf[k++]=args[i];
47break;
48}
49
50if (!skipSpaces) // end of priority substr
51{
52skipSpaces = true;
53lastPriorityDelim=' ';
54buf[k]='\0';
55argv[n++]=strdup(buf); // copy the priority substr
56k=0; // reset the buf index for next token
57buf[0]='\0';
58}
59else
60{ // start of priority substr
61skipSpaces=false;
62lastPriorityDelim=args[i];
63if(k>0) // previous string to store first
64{
65buf[k++]='\0'; // finish the substr
66argv[n++]=strdup(buf); // copy the substr
67k=0; // rest the index for next token
68buf[0]='\0';
69}
70//if (args[i] !='\0') buf[k++] = args[i]; // start the new priority substr
71}
72break;
73default: // non delimiters chars
74if(skipSpaces && prevCharwasDelim)
75{
76if(k>0) // a previous substr was before the space
77{ // store previous token
78buf[k++]='\0'; // finish the substr
79argv[n++]=strdup(buf); // copy the substr
80k=0; // rest the index for next token
81buf[0]='\0';
82}
83}
84prevCharwasDelim = false;
85buf[k++]=args[i];
86break;
87}
88}
89
90if(*buf)
91{
92buf[k]='\0';
93argv[n++]=strdup(buf); // copy the last buffer
94}
95free((void*) buf);
96}
97argv[n]=NULL;
98}
99
100/****************************************************************************/
101 bool executePrivilegedCmd(AuthorizationRef auth,
102 const char* pathToTool,
103 const char* args,
104 AuthorizationFlags flags)
105{
106const char * argv[16];
107
108parseArgs(args, argv, sizeof(argv)/sizeof(const char*));
109
110// Execute Cmd
111OSStatus status = AuthorizationExecuteWithPrivileges(auth, pathToTool,flags, (char**)argv, NULL);
112
113
114// Cleanup mem
115for (int i=0; argv[i]; i++) free ((void*) argv[i]);
116
117 return status ? false : true;
118}
119
120
121/****************************************************************************/
122/**
123 * Write a property list from a file
124 */
125bool WritePropertyListToFile( CFPropertyListRef propertyList, CFURLRef fileURL )
126{
127CFDataRef xmlData;
128Boolean status;
129SInt32 errorCode;
130
131// Convert the property list into XML data.
132xmlData = CFPropertyListCreateXMLData( kCFAllocatorDefault, propertyList );
133
134// Write the XML data to the file.
135status = CFURLWriteDataAndPropertiesToResource (
136fileURL, // URL to use
137xmlData, // data to write
138NULL,
139&errorCode);
140CFRelease(xmlData);
141
142return status ? true: false;
143}
144
145/****************************************************************************/
146/**
147 * Read a property list from a file
148 */
149static CFPropertyListRef CreatePropertyListFromFile( CFURLRef fileURL, CFStringRef * errorString ) {
150CFPropertyListRef propertyList;
151CFDataRef resourceData;
152Boolean status;
153SInt32 errorCode;
154
155// Read the XML file.
156status = CFURLCreateDataAndPropertiesFromResource(
157 kCFAllocatorDefault,
158 fileURL,
159 &resourceData, // place to put file data
160 NULL,
161 NULL,
162 &errorCode);
163if (!status) return NULL;
164
165// Reconstitute the dictionary using the XML data.
166propertyList = CFPropertyListCreateFromXMLData( kCFAllocatorDefault,
167 resourceData,
168 kCFPropertyListMutableContainersAndLeaves,
169 errorString);
170
171
172CFRelease( resourceData );
173return propertyList;
174}
175
176/****************************************************************************/
177static void show(CFStringRef formatString, ...) {
178 CFStringRef resultString;
179 CFDataRef data;
180 va_list argList;
181
182 va_start(argList, formatString);
183 resultString = CFStringCreateWithFormatAndArguments(NULL, NULL, formatString, argList);
184 va_end(argList);
185
186 data = CFStringCreateExternalRepresentation(NULL, resultString, CFStringGetSystemEncoding(), '?');
187
188 if (data != NULL) {
189 printf ("%.*s\n\n", (int)CFDataGetLength(data), CFDataGetBytePtr(data));
190 CFRelease(data);
191 }
192
193 CFRelease(resultString);
194}
195/****************************************************************************/
196/*
197 * Always return a valid static const string, if the CFSTR is not valid, then we return ""
198 */
199static const char * CfsToCs(CFStringRef inRef)
200{
201static char buffer[512]="";
202if(CFStringGetFileSystemRepresentation (inRef, buffer, sizeof(buffer)))
203 return buffer;
204return "";
205}
206
207/****************************************************************************/
208/**
209 * Creates a PropertyList Incstance
210 */
211PropertyList::~PropertyList()
212{
213if (_CFURLRef) CFRelease(_CFURLRef);
214if (_proplistRef) CFRelease(_proplistRef);
215
216}
217
218/****************************************************************************/
219/**
220 * Open a properlist from a path name
221 */
222bool PropertyList::open(const char * path, CFStringRef * errorString, AuthorizationRef auth, AuthorizationFlags flags)
223{
224bool ret = false;
225
226if (!path || !*path) return false;
227
228if (auth)
229{ // give write temporary write rights to the file
230std::string args = " 0777 "+ _propFilePath;
231if(!executePrivilegedCmd(auth, "/bin/chmod", args.c_str(), flags))
232return false;
233}
234
235_propFilePath = path;
236
237CFStringRef cfPath = CFStringCreateWithCString (kCFAllocatorDefault, path, kCFStringEncodingUTF8);
238CFURLRef inURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault,
239cfPath,
240kCFURLPOSIXPathStyle, // interpret as POSIX path
241false ); // is it a directory?
242CFRelease(cfPath);
243if (_CFURLRef) CFRelease(_CFURLRef);
244_CFURLRef = inURL;
245
246if (_CFURLRef)
247{
248_proplistRef = CreatePropertyListFromFile(inURL, errorString);
249
250if (_proplistRef)
251ret= true;
252}
253if (auth)
254{ // give write temporary write rights to the file
255std::string args = " 0644 "+ _propFilePath;
256if(!executePrivilegedCmd(auth, "/bin/chmod", args.c_str(), flags))
257ret= false;
258}
259
260return ret;
261}
262
263/****************************************************************************/
264/**
265 * Save the current property list
266 */
267bool PropertyList::save(AuthorizationRef auth, AuthorizationFlags flags)
268{
269bool ret=false;
270if (auth)
271{ // give write temporary write rights to the file
272std::string args = " 0777 "+ _propFilePath;
273if(!executePrivilegedCmd(auth, "/bin/chmod", args.c_str(), flags))
274return false;
275}
276if (_proplistRef && _CFURLRef)
277ret= WritePropertyListToFile(_proplistRef,_CFURLRef);
278if (auth)
279{ // give write temporary write rights to the file
280std::string args = " 0644 "+ _propFilePath;
281if(!executePrivilegedCmd(auth, "/bin/chmod", args.c_str(), flags))
282return false;
283}
284return ret;
285}
286
287/****************************************************************************/
288/**
289 * Extract a sring value from a property list key,
290 * value returned is not owned by caller, copy it necessary.
291 */
292const char * PropertyList::getStringForKey(const char *key)
293{
294if (!_proplistRef) return 0;
295CFDictionaryRef myDict =
296(CFGetTypeID(_proplistRef) == CFDictionaryGetTypeID()) ? (CFDictionaryRef) _proplistRef : NULL;
297CFStringRef cfKey = CFStringCreateWithCString (kCFAllocatorDefault, key, kCFStringEncodingUTF8);
298CFStringRef myString;
299
300if (myDict && CFDictionaryGetValueIfPresent(myDict, cfKey, (const void **) &myString))
301{
302// show(CFSTR("Key '%@' found , value = <%@>\n"), cfKey, !myString ? CFSTR("") : myString);
303CFRelease(cfKey);
304return CfsToCs(myString);
305}
306
307if(cfKey) CFRelease(cfKey);
308return NULL;
309}
310/****************************************************************************/
311/**
312 * replace a sring value from a property list key,
313 * value returned is not owned by caller, copy it necessary.
314 */
315bool PropertyList::setStringForKey(const char *key, const char * value)
316{
317if (!_proplistRef) return false;
318bool ret = false;
319CFMutableDictionaryRef myDict =
320(CFGetTypeID(_proplistRef) == CFDictionaryGetTypeID()) ? (CFMutableDictionaryRef) _proplistRef : NULL;
321CFStringRef cfKey = CFStringCreateWithCString (kCFAllocatorDefault, key, kCFStringEncodingUTF8);
322CFStringRef myString = CFStringCreateWithCString (kCFAllocatorDefault, value, kCFStringEncodingUTF8);
323
324if (myDict) {
325CFDictionaryReplaceValue(myDict, cfKey, myString);
326ret=true;
327}
328if(cfKey) CFRelease(cfKey);
329if(myString) CFRelease(myString);
330return ret;
331}
332
333

Archive Download this file

Revision: 1