70 BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); |
82 BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); |
71 *retval = NULL; |
83 *retval = NULL; |
72 return(retval); |
84 return(retval); |
73 } /* __PHYSFS_platformDetectAvailableCDs */ |
85 } /* __PHYSFS_platformDetectAvailableCDs */ |
74 |
86 |
75 #else |
87 |
76 |
88 #elif (defined PHYSFS_DARWIN) /* "Big Nasty." */ |
77 |
89 /* |
78 #ifdef PHYSFS_HAVE_SYS_UCRED_H |
90 * Code based on sample from Apple Developer Connection: |
|
91 * http://developer.apple.com/samplecode/Sample_Code/Devices_and_Hardware/Disks/VolumeToBSDNode/VolumeToBSDNode.c.htm |
|
92 */ |
|
93 |
|
94 static int darwinIsWholeMedia(io_service_t service) |
|
95 { |
|
96 int retval = 0; |
|
97 CFTypeRef wholeMedia; |
|
98 |
|
99 if (!IOObjectConformsTo(service, kIOMediaClass)) |
|
100 return(0); |
|
101 |
|
102 wholeMedia = IORegistryEntryCreateCFProperty(service, |
|
103 CFSTR(kIOMediaWholeKey), |
|
104 kCFAllocatorDefault, 0); |
|
105 if (wholeMedia == NULL) |
|
106 return(0); |
|
107 |
|
108 retval = CFBooleanGetValue(wholeMedia); |
|
109 CFRelease(wholeMedia); |
|
110 |
|
111 return retval; |
|
112 } /* darwinIsWholeMedia */ |
|
113 |
|
114 |
|
115 static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort) |
|
116 { |
|
117 int retval = 0; |
|
118 CFMutableDictionaryRef matchingDict; |
|
119 kern_return_t rc; |
|
120 io_iterator_t iter; |
|
121 io_service_t service; |
|
122 |
|
123 if ((matchingDict = IOBSDNameMatching(masterPort, 0, bsdName)) == NULL) |
|
124 return(0); |
|
125 |
|
126 rc = IOServiceGetMatchingServices(masterPort, matchingDict, &iter); |
|
127 if ((rc != KERN_SUCCESS) || (!iter)) |
|
128 return(0); |
|
129 |
|
130 service = IOIteratorNext(iter); |
|
131 IOObjectRelease(iter); |
|
132 if (!service) |
|
133 return(0); |
|
134 |
|
135 rc = IORegistryEntryCreateIterator(service, kIOServicePlane, |
|
136 kIORegistryIterateRecursively | kIORegistryIterateParents, &iter); |
|
137 |
|
138 if (!iter) |
|
139 return(0); |
|
140 |
|
141 if (rc != KERN_SUCCESS) |
|
142 { |
|
143 IOObjectRelease(iter); |
|
144 return(0); |
|
145 } /* if */ |
|
146 |
|
147 IOObjectRetain(service); /* add an extra object reference... */ |
|
148 |
|
149 do |
|
150 { |
|
151 if (darwinIsWholeMedia(service)) |
|
152 { |
|
153 if ( (IOObjectConformsTo(service, kIOCDMediaClass)) || |
|
154 (IOObjectConformsTo(service, kIODVDMediaClass)) ) |
|
155 { |
|
156 retval = 1; |
|
157 } /* if */ |
|
158 } /* if */ |
|
159 IOObjectRelease(service); |
|
160 } while ((service = IOIteratorNext(iter)) && (!retval)); |
|
161 |
|
162 IOObjectRelease(iter); |
|
163 IOObjectRelease(service); |
|
164 |
|
165 return(retval); |
|
166 } /* darwinIsMountedDisc */ |
|
167 |
|
168 |
|
169 char **__PHYSFS_platformDetectAvailableCDs(void) |
|
170 { |
|
171 const char *devPrefix = "/dev/"; |
|
172 int prefixLen = strlen(devPrefix); |
|
173 mach_port_t masterPort = 0; |
|
174 char **retval = (char **) malloc(sizeof (char *)); |
|
175 int cd_count = 1; /* We count the NULL entry. */ |
|
176 struct statfs *mntbufp; |
|
177 int i, mounts; |
|
178 |
|
179 retval[0] = NULL; |
|
180 |
|
181 if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS) |
|
182 return(retval); |
|
183 |
|
184 mounts = getmntinfo(&mntbufp, MNT_WAIT); /* NOT THREAD SAFE! */ |
|
185 for (i = 0; i < mounts; i++) |
|
186 { |
|
187 char *dev = mntbufp[i].f_mntfromname; |
|
188 char *mnt = mntbufp[i].f_mntonname; |
|
189 if (strncmp(dev, devPrefix, prefixLen) != 0) /* a virtual device? */ |
|
190 continue; |
|
191 |
|
192 dev += prefixLen; |
|
193 if (darwinIsMountedDisc(dev, masterPort)) |
|
194 { |
|
195 char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1)); |
|
196 if (tmp) |
|
197 { |
|
198 retval = tmp; |
|
199 retval[cd_count - 1] = (char *) malloc(strlen(mnt) + 1); |
|
200 if (retval[cd_count - 1]) |
|
201 { |
|
202 strcpy(retval[cd_count - 1], mnt); |
|
203 cd_count++; |
|
204 } /* if */ |
|
205 } /* if */ |
|
206 } /* if */ |
|
207 } /* for */ |
|
208 |
|
209 retval[cd_count - 1] = NULL; |
|
210 return(retval); |
|
211 } /* __PHYSFS_platformDetectAvailableCDs */ |
|
212 |
|
213 #elif (defined PHYSFS_HAVE_SYS_UCRED_H) |
79 |
214 |
80 char **__PHYSFS_platformDetectAvailableCDs(void) |
215 char **__PHYSFS_platformDetectAvailableCDs(void) |
81 { |
216 { |
82 char **retval = (char **) malloc(sizeof (char *)); |
217 char **retval = (char **) malloc(sizeof (char *)); |
83 int cd_count = 1; /* We count the NULL entry. */ |
218 int cd_count = 1; /* We count the NULL entry. */ |
264 { |
394 { |
265 usleep( 10 * 1000 ); /* don't care if it fails. */ |
395 usleep( 10 * 1000 ); /* don't care if it fails. */ |
266 } /* __PHYSFS_platformTimeslice */ |
396 } /* __PHYSFS_platformTimeslice */ |
267 |
397 |
268 |
398 |
269 #if defined(__MACH__) && defined(__APPLE__) |
399 #if PHYSFS_DARWIN |
270 /* |
400 /* |
271 * This function is only for OSX. The problem is that Apple's applications |
401 * This function is only for OSX. The problem is that Apple's applications |
272 * can actually be directory structures with the actual executable nested |
402 * can actually be directory structures with the actual executable nested |
273 * several levels down. PhysFS computes the base directory from the Unix |
403 * several levels down. PhysFS computes the base directory from the Unix |
274 * executable, but this may not be the correct directory. Apple tries to |
404 * executable, but this may not be the correct directory. Apple tries to |
312 char *found_ptr = NULL; |
442 char *found_ptr = NULL; |
313 char *tempbuf = NULL; |
443 char *tempbuf = NULL; |
314 int i; |
444 int i; |
315 |
445 |
316 /* Calloc will place the \0 character in the proper place for us */ |
446 /* Calloc will place the \0 character in the proper place for us */ |
|
447 /* !!! FIXME: Can we stack-allocate this? --ryan. */ |
317 tempbuf = (char*)calloc( (strlen(path)+1), sizeof(char) ); |
448 tempbuf = (char*)calloc( (strlen(path)+1), sizeof(char) ); |
318 /* Unlike other Unix filesystems, HFS is case insensitive |
449 /* Unlike other Unix filesystems, HFS is case insensitive |
319 * It wouldn be nice to use strcasestr, but it doesn't seem |
450 * It wouldn be nice to use strcasestr, but it doesn't seem |
320 * to be available in the OSX gcc library right now. |
451 * to be available in the OSX gcc library right now. |
321 * So we should make a lower case copy of the path to |
452 * So we should make a lower case copy of the path to |