]> git.saurik.com Git - apple/libc.git/blob - gen/NSSystemDirectories.c
Libc-594.1.4.tar.gz
[apple/libc.git] / gen / NSSystemDirectories.c
1 /*
2 * Copyright (c) 1999, 2008 Apple 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 #include <NSSystemDirectories.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/param.h>
27 #include <unistd.h>
28
29 #define NSUserDomainIndex 0
30 #define NSLocalDomainIndex 1
31 #define NSNetworkDomainIndex 2
32 #define NSSystemDomainIndex 3
33
34 #define numDomains (NSSystemDomainIndex + 1)
35 #define DomainMask ((1 << numDomains) - 1)
36
37 #define addNextRoot(x) (*(x) == '/' || *(x) == 0)
38
39 #define Network "/Network"
40 #define System "/System"
41 #define Tilde "~"
42
43 #define NSApplicationDirectoryBase "/Applications"
44 #define NSDemoApplicationDirectoryBase "/Applications/Demos"
45 #define NSDeveloperApplicationDirectoryBase "/Developer/Applications"
46 #define NSAdminApplicationDirectoryBase "/Applications/Utilities"
47 #define NSLibraryDirectoryBase "/Library"
48 #define NSDeveloperDirectoryBase "/Developer"
49 #define NSUserDirectoryBase "/Users"
50 #define NSDocumentationDirectoryBase "/Library/Documentation"
51 #define NSDocumentDirectoryBase "/Documents"
52 #define NSCoreServiceDirectoryBase "/Library/CoreServices"
53 #define NSAutosavedDocumentsDirectoryBase "/Library/Autosave Information"
54 #define NSDesktopDirectoryBase "/Desktop"
55 #define NSCachesDirectoryBase "/Library/Caches"
56 #define NSInputMethodsDirectoryBase "/Library/Input Methods"
57 #define NSMoviesDirectoryBase "/Movies"
58 #define NSMusicDirectoryBase "/Music"
59 #define NSPicturesDirectoryBase "/Pictures"
60 #define NSPrinterDescriptionDirectoryBase "/Library/Printers/PPDs"
61 #define NSSharedPublicDirectoryBase "/Public"
62 #define NSPreferencePanesDirectoryBase "/Library/PreferencePanes"
63 #define NSApplicationSupportDirectoryBase "/Library/Application Support"
64 #define NSDownloadsDirectoryBase "/Downloads"
65
66 static const char * const prefixAll[] = {
67 Tilde,
68 "",
69 Network,
70 ""
71 };
72 static const char * const prefixAllSystem[] = {
73 Tilde,
74 "",
75 Network,
76 System
77 };
78 static const char * const prefixNoUserSystem[] = {
79 NULL,
80 "",
81 Network,
82 NULL
83 };
84 static const char * const prefixNoNetwork[] = {
85 Tilde,
86 "",
87 NULL,
88 System
89 };
90 static const char * const prefixSystemOnly[] = {
91 NULL,
92 NULL,
93 NULL,
94 System
95 };
96 static const char * const prefixUserOnly[] = {
97 Tilde,
98 NULL,
99 NULL,
100 NULL
101 };
102
103 static const char * const _prefixNetwork4[] = {
104 Network,
105 Network,
106 Network,
107 Network
108 };
109 static const char * const _prefixNone4[] = {
110 "",
111 "",
112 "",
113 ""
114 };
115 static const char * const _prefixTilde4[] = {
116 Tilde,
117 Tilde,
118 Tilde,
119 Tilde
120 };
121 static const char * const * const prefixAllApplicationsDirectory[] = {
122 _prefixTilde4,
123 _prefixNone4,
124 _prefixNetwork4,
125 _prefixNone4
126 };
127 static const char * const baseAllApplicationsDirectory[] = {
128 NSApplicationDirectoryBase,
129 NSAdminApplicationDirectoryBase,
130 NSDeveloperApplicationDirectoryBase,
131 NSDemoApplicationDirectoryBase
132 };
133
134 static const char * const _prefixNetwork2[] = {
135 Network,
136 Network
137 };
138 static const char * const _prefixNone2[] = {
139 "",
140 ""
141 };
142 static const char * const _prefixSystemNone2[] = {
143 System,
144 ""
145 };
146 static const char * const _prefixTilde2[] = {
147 Tilde,
148 Tilde
149 };
150 static const char * const * const prefixAllLibrariesDirectory[] = {
151 _prefixTilde2,
152 _prefixNone2,
153 _prefixNetwork2,
154 _prefixSystemNone2
155 };
156 static const char * const baseAllLibrariesDirectory[] = {
157 NSLibraryDirectoryBase,
158 NSDeveloperDirectoryBase
159 };
160
161 // The dirInfo table drives path creation
162 static struct {
163 int pathsPerDomain;
164 const void * const * const prefix;
165 const void * const base;
166 } dirInfo[] = {
167 { // NSApplicationDirectory
168 1,
169 (const void * const * const)prefixAll,
170 (const void * const)NSApplicationDirectoryBase
171 },
172 { // NSDemoApplicationDirectory
173 1,
174 (const void * const * const)prefixAll,
175 (const void * const)NSDemoApplicationDirectoryBase
176 },
177 { // NSDeveloperApplicationDirectory
178 1,
179 (const void * const * const)prefixAll,
180 (const void * const)NSDeveloperApplicationDirectoryBase
181 },
182 { // NSAdminApplicationDirectory
183 1,
184 (const void * const * const)prefixAll,
185 (const void * const)NSAdminApplicationDirectoryBase
186 },
187 { // NSLibraryDirectory
188 1,
189 (const void * const * const)prefixAllSystem,
190 (const void * const)NSLibraryDirectoryBase
191 },
192 { // NSDeveloperDirectory
193 1,
194 (const void * const * const)prefixAll,
195 (const void * const)NSDeveloperDirectoryBase
196 },
197 { // NSUserDirectory
198 1,
199 (const void * const * const)prefixNoUserSystem,
200 (const void * const)NSUserDirectoryBase
201 },
202 { // NSDocumentationDirectory
203 1,
204 (const void * const * const)prefixAllSystem,
205 (const void * const)NSDocumentationDirectoryBase
206 },
207 { // NSDocumentDirectory
208 1,
209 (const void * const * const)prefixUserOnly,
210 (const void * const)NSDocumentDirectoryBase
211 },
212 { // NSCoreServiceDirectory
213 1,
214 (const void * const * const)prefixSystemOnly,
215 (const void * const)NSCoreServiceDirectoryBase
216 },
217 { // NSAutosavedInformationDirectory
218 1,
219 (const void * const * const)prefixUserOnly,
220 (const void * const)NSAutosavedDocumentsDirectoryBase
221 },
222 { // NSDesktopDirectory
223 1,
224 (const void * const * const)prefixUserOnly,
225 (const void * const)NSDesktopDirectoryBase
226 },
227 { // NSCachesDirectory
228 1,
229 (const void * const * const)prefixAll,
230 (const void * const)NSCachesDirectoryBase
231 },
232 { // NSApplicationSupportDirectory
233 1,
234 (const void * const * const)prefixAll,
235 (const void * const)NSApplicationSupportDirectoryBase
236 },
237 { // NSDownloadsDirectory
238 1,
239 (const void * const * const)prefixUserOnly,
240 (const void * const)NSDownloadsDirectoryBase
241 },
242 { // NSInputMethodsDirectory
243 1,
244 (const void * const * const)prefixAll,
245 (const void * const)NSInputMethodsDirectoryBase
246 },
247 { // NSMoviesDirectory
248 1,
249 (const void * const * const)prefixUserOnly,
250 (const void * const)NSMoviesDirectoryBase
251 },
252 { // NSMusicDirectory
253 1,
254 (const void * const * const)prefixUserOnly,
255 (const void * const)NSMusicDirectoryBase
256 },
257 { // NSPicturesDirectory
258 1,
259 (const void * const * const)prefixUserOnly,
260 (const void * const)NSPicturesDirectoryBase
261 },
262 { // NSPrinterDescriptionDirectory
263 1,
264 (const void * const * const)prefixSystemOnly,
265 (const void * const)NSPrinterDescriptionDirectoryBase
266 },
267 { // NSSharedPublicDirectory
268 1,
269 (const void * const * const)prefixUserOnly,
270 (const void * const)NSSharedPublicDirectoryBase
271 },
272 { // NSPreferencePanesDirectory
273 1,
274 (const void * const * const)prefixNoNetwork,
275 (const void * const)NSPreferencePanesDirectoryBase
276 },
277 { // NSAllApplicationsDirectory
278 4,
279 (const void * const * const)prefixAllApplicationsDirectory,
280 (const void * const)baseAllApplicationsDirectory
281 },
282 { // NSAllLibrariesDirectory
283 2,
284 (const void * const * const)prefixAllLibrariesDirectory,
285 (const void * const)baseAllLibrariesDirectory
286 }
287 };
288
289 #define Index(dir) (((dir) >= NSApplicationDirectory && (dir) <= NSPreferencePanesDirectory) ? ((dir) - 1) : (((dir) >= NSAllApplicationsDirectory && (dir) <= NSAllLibrariesDirectory) ? ((dir) - NSAllApplicationsDirectory + NSPreferencePanesDirectory) : -1))
290
291 #define invalidDomains 0x00 // some domains may be invalid on non-Mach systems
292 #define ByteMask 0xff
293 #define DirShift 24
294 #define IndexShift 16
295
296 NSSearchPathEnumerationState NSStartSearchPathEnumeration(NSSearchPathDirectory dir, NSSearchPathDomainMask domainMask) {
297 // The state is AABBCCCC, where
298 // AA is the dir(s) requested
299 // BB is the current state of dirs (if AA < 100, then this is always 0; otherwise it goes up to number of dirs)
300 // CCCC is the domains requested
301 // the state always contains the next item; if CCCC is 0, then we're done
302 int i;
303
304 if((i = Index(dir)) < 0) {
305 return 0;
306 }
307 domainMask = domainMask & DomainMask & ~invalidDomains; // Just leave useful bits in there
308
309 // Trim Duplicates - This assumes the compiler generates a single address
310 // for multiple occurrences of the same literal strings.
311 if ((domainMask & (NSLocalDomainMask | NSSystemDomainMask)) == (NSLocalDomainMask | NSSystemDomainMask) && dirInfo[i].prefix[NSLocalDomainIndex] == dirInfo[i].prefix[NSSystemDomainIndex]) {
312 domainMask &= ~NSSystemDomainMask;
313 }
314
315 return (dir << DirShift) + domainMask;
316 }
317
318 NSSearchPathEnumerationState NSGetNextSearchPathEnumeration(NSSearchPathEnumerationState state, char *path) {
319 static const char *nextRoot = NULL;
320 int dir = (state >> DirShift) & ByteMask;
321 int domainMask = state & DomainMask;
322 int domain, i, n;
323 const char *prefix, *base;
324
325 if ((i = Index(dir)) < 0 || (domain = ffs(domainMask)) == 0)
326 return 0;
327 domain--; // adjust to zero-based index
328
329 if ((n = dirInfo[i].pathsPerDomain) == 1) {
330 const char * const *p = (const char * const *)dirInfo[i].prefix;
331 for (;;) { // loop, skipping over invalid domains (prefix is NULL)
332 domainMask &= ~(1 << domain);
333 if ((prefix = p[domain]) != NULL) {
334 break;
335 }
336 if ((domain = ffs(domainMask)) == 0) {
337 return 0;
338 }
339 domain--; // adjust to zero-based index
340 }
341 base = (const char *)dirInfo[i].base;
342 state = (dir << DirShift) + domainMask;
343 } else { // multiple paths per domain
344 const char * const **p = (const char * const **)dirInfo[i].prefix;
345 const char * const *b = (const char * const *)dirInfo[i].base;
346 int dirIndex = (state >> IndexShift) & ByteMask;
347
348 if (dirIndex >= n) { // done with the current domain, go to the next
349 domainMask &= ~(1 << domain);
350 if ((domain = ffs(domainMask)) == 0) {
351 return 0;
352 }
353 domain--; // adjust to zero-based index
354 dirIndex = 0;
355 }
356 prefix = p[domain][dirIndex];
357 base = b[dirIndex];
358 state = (dir << DirShift) + (++dirIndex << IndexShift) + domainMask;
359 }
360
361 if (addNextRoot(prefix)) {
362 if (nextRoot == NULL) { // Get NEXT_ROOT
363 if (!issetugid() && (nextRoot = getenv("NEXT_ROOT")) != NULL) {
364 nextRoot = strdup(nextRoot);
365 }
366 if (nextRoot == NULL) {
367 nextRoot = "";
368 }
369 }
370 strlcpy(path, nextRoot, PATH_MAX);
371 } else {
372 *path = 0;
373 }
374 strlcat(path, prefix, PATH_MAX);
375 strlcat(path, base, PATH_MAX);
376
377 return state;
378 }