Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | /* * Copyright (c) 1999 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@ */ #import <libc.h> #import <stdio.h> #import <stdlib.h> #import <NSSystemDirectories.h> // Names of directories; index into this with NSSearchPathDirectory - 1 #define numDirs 14 static const struct { unsigned char invalidDomainMask; // Domains in which this dir does not appear unsigned char alternateDomainMask; // Domains in which this dir uses the alternate domain path const char *dirPath; } dirInfo[numDirs] = { {0, 0, "Applications"}, {0, 0, "Applications/Demos"}, {0, 0, "Developer/Applications"}, {0, 0, "Applications/Utilities"}, {0, 0x8, "Library"}, // Uses alternate form in System domain {0, 0, "Developer"}, {0x9, 0, "Users"}, // Not valid in the System and User domains {0, 0x8, "Library/Documentation"}, // Uses alternate form in System domain {0xe, 0, "Documents"}, // Only valid in user domain {0x7, 0, "Library/CoreServices"}, // Only valid in System domain {0xe, 0, "Documents/Autosaved"}, // Only valid in user domain; not public API yet {0xe, 0, "Desktop"}, // Only valid in user domain {0, 0, "Library/Caches"}, {0, 0, "Library/Application Support"} }; // Unpublicized values for NSSearchPathDirectory enum { NSAutosavedDocumentsDirectory = 11 }; // Ordered list of where to find applications in each domain (the numbers are NSSearchPathDirectory) #define numApplicationDirs 4 static const char applicationDirs[numApplicationDirs] = {1, 4, 3, 2}; // Ordered list of where to find resources in each domain (the numbers are NSSearchPathDirectory) #define numLibraryDirs 2 static const char libraryDirs[numLibraryDirs] = {5, 6}; // Names of domains; index into this log2(domainMask). If the search path ordering is ever changed, then we need an indirection (as the domainMask values cannot be changed). #define numDomains 4 static const struct { char needsRootPrepended; const char *domainPath; const char *alternateDomainPath; } domainInfo[numDomains] = { {0, "~", "~"}, {1, "", ""}, {1, "/Network", "/Network"}, {1, "", "/System"} }; #define invalidDomains 0x00 // some domains may be invalid on non-Mach systems NSSearchPathEnumerationState NSStartSearchPathEnumeration(NSSearchPathDirectory dir, NSSearchPathDomainMask domainMask) { // The state is AABBCCCC, where // AA is the dir(s) requested // BB is the current state of dirs (if AA < 100, then this is always 0; otherwise it goes up to number of dirs) // CCCC is the domains requested // the state always contains the next item; if CCCC is 0, then we're done domainMask = domainMask & ((1 << numDomains) - 1) & ~invalidDomains; // Just leave useful bits in there if (dir != NSAllLibrariesDirectory && dir != NSLibraryDirectory && dir != NSUserDirectory && dir != NSDocumentationDirectory && (domainMask & NSLocalDomainMask) && (domainMask & NSSystemDomainMask)) domainMask = domainMask & ~NSSystemDomainMask; // Hack to avoid duplication return (((unsigned int)dir) << 24) + ((unsigned int)domainMask); } NSSearchPathEnumerationState NSGetNextSearchPathEnumeration(NSSearchPathEnumerationState state, char *path) { static const char *nextRoot = NULL; unsigned dir = (state >> 24) & 0xff; unsigned dirState = (state >> 16) & 0xff; unsigned domainMask = state & 0xffff; unsigned int curDomain; // The current domain we're at... unsigned int curDir = 0; // The current dir... do { if (domainMask == 0) return 0; // Looks like we're done for (curDomain = 0; curDomain < numDomains; curDomain++) if ((domainMask & (1 << curDomain))) break; // Determine directory if (dir < NSAllApplicationsDirectory) { // One directory per domain, simple... curDir = dir; } else { // Can return multiple directories for each domain if (dir == NSAllApplicationsDirectory) { curDir = applicationDirs[dirState]; if (++dirState == numApplicationDirs) dirState = 0; } else if (dir == NSAllLibrariesDirectory) { curDir = libraryDirs[dirState]; if (++dirState == numLibraryDirs) dirState = 0; } } if (dirState == 0) domainMask &= ~(1 << curDomain); // If necessary, jump to next domain } while ((dirInfo[curDir - 1].invalidDomainMask & (1 << curDomain))); // If invalid, try again... // Get NEXT_ROOT, if necessary. if (domainInfo[curDomain].needsRootPrepended && nextRoot == 0) { nextRoot = getenv("NEXT_ROOT"); if (nextRoot == NULL) { nextRoot = ""; } else { strcpy(malloc(strlen(nextRoot) + 1), nextRoot); // Be safe... } } snprintf(path, PATH_MAX, "%s%s/%s", domainInfo[curDomain].needsRootPrepended ? nextRoot : "", (dirInfo[curDir - 1].alternateDomainMask & (1 << curDomain)) ? domainInfo[curDomain].alternateDomainPath : domainInfo[curDomain].domainPath, dirInfo[curDir - 1].dirPath); return (dir << 24) + (dirState << 16) + domainMask; } |