1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
10 #include <sys/types.h>
11 #include <sys/sysctl.h>
12 #include "CoreFoundation/CoreFoundation.h"
13 #include "CoreServices/CoreServices.h"
14 #include "Carbon/Carbon.h"
16 // This file is a copy and paste from existing methods from
17 // libxul. This is intentional because this interpose
18 // library does not link with libxul.
23 const char *strB
; // NOT null-terminated, can be a null pointer
28 char *extraD
; // null-terminated
32 * Parse a version part into a number and "extra text".
34 * @returns A pointer to the next versionpart, or null if none.
37 ParseVP(char *part
, VersionPart
&result
)
42 result
.strB
= nullptr;
45 result
.extraD
= nullptr;
50 dot
= strchr(part
, '.');
54 if (part
[0] == '*' && part
[1] == '\0') {
55 result
.numA
= INT32_MAX
;
59 result
.numA
= strtol(part
, const_cast<char**>(&result
.strB
), 10);
63 result
.strB
= nullptr;
67 if (result
.strB
[0] == '+') {
68 static const char kPre
[] = "pre";
72 result
.strBlen
= sizeof(kPre
) - 1;
75 const char *numstart
= strpbrk(result
.strB
, "0123456789+-");
77 result
.strBlen
= strlen(result
.strB
);
80 result
.strBlen
= numstart
- result
.strB
;
82 result
.numC
= strtol(numstart
, &result
.extraD
, 10);
84 result
.extraD
= nullptr;
100 // compare two null-terminated strings, which may be null pointers
102 ns_strcmp(const char *str1
, const char *str2
)
104 // any string is *before* no string
111 return strcmp(str1
, str2
);
114 // compare two length-specified string, which may be null pointers
116 ns_strnncmp(const char *str1
, uint32_t len1
, const char *str2
, uint32_t len2
)
118 // any string is *before* no string
125 for (; len1
&& len2
; --len1
, --len2
, ++str1
, ++str2
) {
134 return len2
== 0 ? 0 : -1;
139 // compare two int32_t
141 ns_cmp(int32_t n1
, int32_t n2
)
150 * Compares two VersionParts
153 CompareVP(VersionPart
&v1
, VersionPart
&v2
)
155 int32_t r
= ns_cmp(v1
.numA
, v2
.numA
);
159 r
= ns_strnncmp(v1
.strB
, v1
.strBlen
, v2
.strB
, v2
.strBlen
);
163 r
= ns_cmp(v1
.numC
, v2
.numC
);
167 return ns_strcmp(v1
.extraD
, v2
.extraD
);
170 /* this is intentionally not static so that we don't end up making copies
173 NS_CompareVersions(const char *A
, const char *B
)
175 char *A2
= strdup(A
);
179 char *B2
= strdup(B
);
186 char *a
= A2
, *b
= B2
;
194 result
= CompareVP(va
, vb
);
213 mib
[1] = KERN_OSRELEASE
;
214 // we won't support versions greater than 10.7.99
215 char release
[sizeof("10.7.99")];
216 size_t len
= sizeof(release
);
217 // sysctl will return ENOMEM if the release string is longer than sizeof(release)
218 int ret
= sysctl(mib
, 2, release
, &len
, nullptr, 0);
219 // we only want to trigger this on OS X 10.6, on versions 10.6.8 or newer
220 // Darwin version 10 corresponds to OS X version 10.6, version 11 is 10.7
221 // http://en.wikipedia.org/wiki/Darwin_(operating_system)#Release_history
222 if (ret
== 0 && NS_CompareVersions(release
, "10.8.0") >= 0 && NS_CompareVersions(release
, "11") < 0) {
223 CFBundleRef mainBundle
= CFBundleGetMainBundle();
225 CFRetain(mainBundle
);
227 CFStringRef bundleID
= CFBundleGetIdentifier(mainBundle
);
231 CFMutableDictionaryRef dict
= (CFMutableDictionaryRef
)CFBundleGetInfoDictionary(mainBundle
);
232 CFDictionarySetValue(dict
, CFSTR("CFBundleIdentifier"), CFSTR("org.mozilla.firefox"));
234 // Trigger a load of the quirks table for org.mozilla.firefox.
235 // We use different function on 32/64bit because of how the APIs
236 // behave to force a call to GetBugsForOurBundleIDFromCoreservicesd.
238 ProcessSerialNumber psn
;
239 ::GetCurrentProcess(&psn
);
242 ::Gestalt(gestaltSystemVersionMajor
, &major
);
245 // restore the original id
246 dict
= (CFMutableDictionaryRef
)CFBundleGetInfoDictionary(mainBundle
);
247 CFDictionarySetValue(dict
, CFSTR("CFBundleIdentifier"), bundleID
);
251 CFRelease(mainBundle
);
256 #endif //MacQuirks_h__