]> git.saurik.com Git - apple/configd.git/blob - Plugins/ATconfig/cfManager.c
configd-136.1.tar.gz
[apple/configd.git] / Plugins / ATconfig / cfManager.c
1 /*
2 * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * Modification History
26 *
27 * July 17, 2000 Allan Nathanson <ajn@apple.com>
28 * - initial revision
29 */
30
31
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36
37 #include "cfManager.h"
38
39
40 #ifdef NOTNOW
41 /*
42 * Opens a configuration file and returns a CFArrayRef consisting
43 * of a CFStringRef for each line.
44 */
45 __private_extern__
46 CFArrayRef
47 configRead(const char *path)
48 {
49 int fd;
50 struct stat statBuf;
51 CFMutableDataRef data;
52 CFStringRef str;
53 CFArrayRef config = NULL;
54
55 fd = open(path, O_RDONLY, 0644);
56 if (fd < 0) {
57 goto done;
58 }
59 if (fstat(fd, &statBuf) < 0) {
60 goto done;
61 }
62 if ((statBuf.st_mode & S_IFMT) != S_IFREG) {
63 goto done;
64 }
65
66 data = CFDataCreateMutable(NULL, statBuf.st_size);
67 CFDataSetLength(data, statBuf.st_size);
68 if(read(fd, (void *)CFDataGetMutableBytePtr(data), statBuf.st_size) != statBuf.st_size) {
69 CFRelease(data);
70 goto done;
71 }
72
73 str = CFStringCreateFromExternalRepresentation(NULL, data, kCFStringEncodingMacRoman);
74 CFRelease(data);
75
76 config = CFStringCreateArrayBySeparatingStrings(NULL, str, CFSTR("\n"));
77 CFRelease(str);
78
79 done:
80
81 if (fd >= 0) {
82 close(fd);
83 }
84 if (config == NULL) {
85 CFMutableArrayRef emptyConfig;
86
87 /* pretend that we found an empty file */
88 emptyConfig = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
89 CFArrayAppendValue(emptyConfig, CFSTR(""));
90 config = (CFArrayRef)emptyConfig;
91 }
92 return config;
93 }
94 #endif /* NOTNOW */
95
96 /*
97 * Writes a new configuration file with the contents of a CFArrayRef. Each
98 * element of the array is a CFStringRef.
99 */
100 __private_extern__
101 void
102 configWrite(const char *path, CFArrayRef config)
103 {
104 CFStringRef str;
105 CFDataRef data;
106 int fd = -1;
107 int len;
108
109 str = CFStringCreateByCombiningStrings(NULL, config, CFSTR("\n"));
110 data = CFStringCreateExternalRepresentation(NULL, str, kCFStringEncodingMacRoman, '.');
111 CFRelease(str);
112
113 fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0644);
114 if (fd < 0) {
115 goto done;
116 }
117
118 len = CFDataGetLength(data);
119 if (len) {
120 (void)write(fd, CFDataGetBytePtr(data), len);
121 }
122
123 done:
124
125 if (fd >= 0)
126 close(fd);
127 CFRelease(data);
128 return;
129 }
130
131
132 #ifdef NOTNOW
133 __private_extern__
134 void
135 configSet(CFMutableArrayRef config, CFStringRef key, CFStringRef value)
136 {
137 CFMutableStringRef pref;
138 CFIndex configLen = CFArrayGetCount(config);
139 CFIndex i;
140 CFIndex n;
141 CFMutableStringRef newValue;
142 CFRange range;
143 CFStringRef specialChars = CFSTR(" \"'$!|\\<>`{}[]");
144 boolean_t mustQuote = FALSE;
145
146 /* create search prefix */
147 pref = CFStringCreateMutableCopy(NULL, 0, key);
148 CFStringAppend(pref, CFSTR("="));
149
150 /*
151 * create new / replacement value
152 *
153 * Note: Since the configuration file may be processed by a
154 * shell script we need to ensure that, if needed, the
155 * string is properly quoted.
156 */
157 newValue = CFStringCreateMutableCopy(NULL, 0, value);
158
159 n = CFStringGetLength(specialChars);
160 for (i = 0; i < n; i++) {
161 CFStringRef specialChar;
162
163 specialChar = CFStringCreateWithSubstring(NULL, specialChars, CFRangeMake(i, 1));
164 range = CFStringFind(newValue, specialChar, 0);
165 CFRelease(specialChar);
166 if (range.location != kCFNotFound) {
167 /* this string has at least one special character */
168 mustQuote = TRUE;
169 break;
170 }
171 }
172
173 if (mustQuote) {
174 CFStringRef charsToQuote = CFSTR("\\\"$`");
175
176 /*
177 * in addition to quoting the entire string we also need to escape the
178 * space " " and backslash "\" characters
179 */
180 n = CFStringGetLength(charsToQuote);
181 for (i = 0; i < n; i++) {
182 CFStringRef quoteChar;
183 CFArrayRef matches;
184
185 quoteChar = CFStringCreateWithSubstring(NULL, charsToQuote, CFRangeMake(i, 1));
186 range = CFRangeMake(0, CFStringGetLength(newValue));
187 matches = CFStringCreateArrayWithFindResults(NULL,
188 newValue,
189 quoteChar,
190 range,
191 0);
192 CFRelease(quoteChar);
193
194 if (matches) {
195 CFIndex j = CFArrayGetCount(matches);
196
197 while (--j >= 0) {
198 const CFRange *range;
199
200 range = CFArrayGetValueAtIndex(matches, j);
201 CFStringInsert(newValue, range->location, CFSTR("\\"));
202 }
203 CFRelease(matches);
204 }
205 }
206
207 CFStringInsert(newValue, 0, CFSTR("\""));
208 CFStringAppend(newValue, CFSTR("\""));
209 }
210
211 /* locate existing key */
212 for (i = 0; i < configLen; i++) {
213 if (CFStringHasPrefix(CFArrayGetValueAtIndex(config, i), pref)) {
214 break;
215 }
216 }
217
218 CFStringAppend(pref, newValue);
219 CFRelease(newValue);
220 if (i < configLen) {
221 /* if replacing an existing entry */
222 CFArraySetValueAtIndex(config, i, pref);
223 } else {
224 /*
225 * if new entry, insert it just prior to the last (emtpy)
226 * array element.
227 */
228 CFArrayInsertValueAtIndex(config, configLen-1, pref);
229 }
230 CFRelease(pref);
231
232 return;
233 }
234
235
236 __private_extern__
237 void
238 configRemove(CFMutableArrayRef config, CFStringRef key)
239 {
240 CFMutableStringRef pref;
241 CFIndex configLen = CFArrayGetCount(config);
242 CFIndex i;
243
244 /* create search prefix */
245 pref = CFStringCreateMutableCopy(NULL, 0, key);
246 CFStringAppend(pref, CFSTR("="));
247
248 /* locate existing key */
249 for (i = 0; i < configLen; i++) {
250 if (CFStringHasPrefix(CFArrayGetValueAtIndex(config, i), pref)) {
251 /* entry found, remove it */
252 CFArrayRemoveValueAtIndex(config, i);
253 break;
254 }
255 }
256
257 CFRelease(pref);
258 return;
259 }
260 #endif /* NOTNOW */