OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/mac/mac_util.h" | 5 #include "base/mac/mac_util.h" |
6 | 6 |
7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
8 #import <IOKit/IOKitLib.h> | 8 #import <IOKit/IOKitLib.h> |
9 #include <errno.h> | 9 #include <errno.h> |
10 #include <stddef.h> | 10 #include <stddef.h> |
11 #include <string.h> | 11 #include <string.h> |
12 #include <sys/utsname.h> | 12 #include <sys/utsname.h> |
13 #include <sys/xattr.h> | 13 #include <sys/xattr.h> |
14 | 14 |
15 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
| 16 #include "base/files/file_util.h" |
16 #include "base/logging.h" | 17 #include "base/logging.h" |
17 #include "base/mac/bundle_locations.h" | 18 #include "base/mac/bundle_locations.h" |
18 #include "base/mac/foundation_util.h" | 19 #include "base/mac/foundation_util.h" |
19 #include "base/mac/mac_logging.h" | 20 #include "base/mac/mac_logging.h" |
20 #include "base/mac/scoped_cftyperef.h" | 21 #include "base/mac/scoped_cftyperef.h" |
21 #include "base/mac/scoped_ioobject.h" | 22 #include "base/mac/scoped_ioobject.h" |
22 #include "base/mac/scoped_nsobject.h" | 23 #include "base/mac/scoped_nsobject.h" |
23 #include "base/mac/sdk_forward_declarations.h" | 24 #include "base/mac/sdk_forward_declarations.h" |
24 #include "base/strings/string_number_conversions.h" | 25 #include "base/strings/string_number_conversions.h" |
25 #include "base/strings/string_piece.h" | 26 #include "base/strings/string_piece.h" |
26 #include "base/strings/sys_string_conversions.h" | 27 #include "base/strings/sys_string_conversions.h" |
27 | 28 |
| 29 extern "C" { |
| 30 |
| 31 Boolean GetDYLDEntryPointWithImage(const char *path, const char *unused, |
| 32 const char *symbol, void **addr); |
| 33 |
| 34 } |
| 35 |
28 namespace base { | 36 namespace base { |
29 namespace mac { | 37 namespace mac { |
30 | 38 |
31 namespace { | 39 namespace { |
32 | 40 |
33 // The current count of outstanding requests for full screen mode from browser | 41 // The current count of outstanding requests for full screen mode from browser |
34 // windows, plugins, etc. | 42 // windows, plugins, etc. |
35 int g_full_screen_requests[kNumFullScreenModes] = { 0 }; | 43 int g_full_screen_requests[kNumFullScreenModes] = { 0 }; |
36 | 44 |
37 // Sets the appropriate application presentation option based on the current | 45 // Sets the appropriate application presentation option based on the current |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 | 206 |
199 DCHECK_GT(g_full_screen_requests[from_mode], 0); | 207 DCHECK_GT(g_full_screen_requests[from_mode], 0); |
200 DCHECK_GE(g_full_screen_requests[to_mode], 0); | 208 DCHECK_GE(g_full_screen_requests[to_mode], 0); |
201 g_full_screen_requests[from_mode] = | 209 g_full_screen_requests[from_mode] = |
202 std::max(g_full_screen_requests[from_mode] - 1, 0); | 210 std::max(g_full_screen_requests[from_mode] - 1, 0); |
203 g_full_screen_requests[to_mode] = | 211 g_full_screen_requests[to_mode] = |
204 std::max(g_full_screen_requests[to_mode] + 1, 1); | 212 std::max(g_full_screen_requests[to_mode] + 1, 1); |
205 SetUIMode(); | 213 SetUIMode(); |
206 } | 214 } |
207 | 215 |
| 216 namespace { |
| 217 |
| 218 void statlog(const FilePath& file_path) { |
| 219 char buf[2048]; |
| 220 strncpy(buf, file_path.value().c_str(), sizeof(buf)); |
| 221 buf[sizeof(buf)-1] = '\0'; |
| 222 |
| 223 while (buf[0] && buf[1]) { |
| 224 struct stat st; |
| 225 if (!stat(buf, &st)) { |
| 226 LOG(ERROR) << "Stat " << buf |
| 227 << " st_mode 0x" << std::oct << st.st_mode << std::dec |
| 228 << " st_uid " << st.st_uid |
| 229 << " st_gid " << st.st_gid |
| 230 << " st_flags " << st.st_flags; |
| 231 } else { |
| 232 PLOG(ERROR) << "Stat on " << buf; |
| 233 } |
| 234 |
| 235 char* slash = rindex(buf, '/'); |
| 236 *slash = '\0'; |
| 237 } |
| 238 } |
| 239 |
| 240 void LogThings(CFURLRef path_url, const FilePath& file_path) { |
| 241 ScopedCFTypeRef<CFURLRef> uc(CFURLCopyAbsoluteURL(path_url)); |
| 242 LOG(ERROR) << "copy url " << uc.get(); |
| 243 |
| 244 LOG(ERROR) << "geteuid() " << geteuid(); |
| 245 |
| 246 ScopedCFTypeRef<CFStringRef> fsp( |
| 247 CFURLCopyFileSystemPath(path_url, kCFURLPOSIXPathStyle)); |
| 248 LOG(ERROR) << "string copy " << fsp.get(); |
| 249 |
| 250 void* md_item_create_addr = NULL; |
| 251 Boolean rc = GetDYLDEntryPointWithImage( |
| 252 "/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.fra
mework/Metadata", |
| 253 NULL, "MDItemCreate", &md_item_create_addr); |
| 254 LOG(ERROR) << "GetDYLDEntryPointWithImage(MDItemCreate) rc " << (int)rc << " a
ddr " << (void*)md_item_create_addr; |
| 255 LOG(ERROR) << "MDItemCreate addr " << (void*)&MDItemCreate; |
| 256 |
| 257 statlog(file_path); |
| 258 |
| 259 ScopedCFTypeRef<MDItemRef> m( |
| 260 MDItemCreate(NULL, fsp)); |
| 261 LOG(ERROR) << "MDItemCreate() " << m.get(); |
| 262 |
| 263 typedef OSStatus (*MDItemSetAttribute_type)(MDItemRef, CFStringRef, |
| 264 CFTypeRef); |
| 265 MDItemSetAttribute_type md_item_set_attribute_func = NULL; |
| 266 rc = GetDYLDEntryPointWithImage( |
| 267 "/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.fra
mework/Metadata", |
| 268 NULL, "MDItemSetAttribute", (void**)&md_item_set_attribute_func); |
| 269 LOG(ERROR) << "GetDYLDEntryPointWithImage(MDItemSetAttribute) rc " << (int)rc
<< " addr " << (void*)md_item_set_attribute_func; |
| 270 |
| 271 int irc = md_item_set_attribute_func( |
| 272 m, CFSTR("com_apple_backup_excludeItem"), CFSTR("com.apple.backupd")); |
| 273 LOG(ERROR) << "md_item_set_attribute_func() " << irc; |
| 274 |
| 275 // http://www.liquidx.net/blog/2005/09/30/metadata-spotlight-possible/ |
| 276 // int MDItemSetAttribute(MDItemRef item, CFStringRef attribute, CFTypeRef val
ue); |
| 277 |
| 278 char attr[1024]; |
| 279 const char kExcludeAttrName[] = "com.apple.metadata:com_apple_backup_excludeIt
em"; |
| 280 ssize_t len = getxattr(file_path.value().c_str(), kExcludeAttrName, attr, size
of(attr), 0, 0); |
| 281 LOG(ERROR) << "getxattr() len " << len; |
| 282 } |
| 283 |
| 284 } // namespace |
| 285 |
208 bool SetFileBackupExclusion(const FilePath& file_path) { | 286 bool SetFileBackupExclusion(const FilePath& file_path) { |
| 287 #if 0 |
| 288 char kExcludeAttr[] = { |
| 289 0x62, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x30, 0x30, 0x5F, 0x10, 0x11, 0x63, 0x6F
, 0x6D, 0x2E, 0x61, |
| 290 0x70, 0x70, 0x6C, 0x65, 0x2E, 0x62, 0x61, 0x63, 0x6B, 0x75, 0x70, 0x64, 0x08
, 0x00, 0x00, 0x00, |
| 291 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
, 0x00, 0x00, 0x00, |
| 292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C
, |
| 293 }; |
| 294 const char kExcludeAttrName[] = "com.apple.metadata:com_apple_backup_excludeIt
em"; |
| 295 int status = setxattr(file_path.value().c_str(), kExcludeAttrName, kExcludeAtt
r, sizeof(kExcludeAttr), 0, 0); |
| 296 if (status != 0) { |
| 297 PLOG(ERROR) << "setting attribute"; |
| 298 return false; |
| 299 } |
| 300 |
| 301 char attr[1024]; |
| 302 ssize_t len = getxattr(file_path.value().c_str(), kExcludeAttrName, attr, size
of(attr), 0, 0); |
| 303 if (len < 0) { |
| 304 PLOG(ERROR) << "getting attribute"; |
| 305 return false; |
| 306 } |
| 307 LOG(ERROR) << "len " << len; |
| 308 |
| 309 char namebuf[2048]; |
| 310 len = listxattr(file_path.value().c_str(), namebuf, sizeof(namebuf), 0); |
| 311 if (len < 0) { |
| 312 PLOG(ERROR) << "getting attribute"; |
| 313 return false; |
| 314 } |
| 315 char* b = namebuf; |
| 316 namebuf[sizeof(namebuf)-1] = '\0'; |
| 317 for (ssize_t i = 0; i < len; ) { |
| 318 LOG(ERROR) << "item " << (b+i); |
| 319 i += strlen(b+i) + 1; |
| 320 } |
| 321 return true; |
| 322 #else |
209 NSString* file_path_ns = | 323 NSString* file_path_ns = |
210 [NSString stringWithUTF8String:file_path.value().c_str()]; | 324 [NSString stringWithUTF8String:file_path.value().c_str()]; |
211 NSURL* file_url = [NSURL fileURLWithPath:file_path_ns]; | 325 NSURL* file_url = [NSURL fileURLWithPath:file_path_ns]; |
212 | 326 |
213 // When excludeByPath is true the application must be running with root | 327 // When excludeByPath is true the application must be running with root |
214 // privileges (admin for 10.6 and earlier) but the URL does not have to | 328 // privileges (admin for 10.6 and earlier) but the URL does not have to |
215 // already exist. When excludeByPath is false the URL must already exist but | 329 // already exist. When excludeByPath is false the URL must already exist but |
216 // can be used in non-root (or admin as above) mode. We use false so that | 330 // can be used in non-root (or admin as above) mode. We use false so that |
217 // non-root (or admin) users don't get their TimeMachine drive filled up with | 331 // non-root (or admin) users don't get their TimeMachine drive filled up with |
218 // unnecessary backups. | 332 // unnecessary backups. |
| 333 LogThings(base::mac::NSToCFCast(file_url), file_path); |
219 OSStatus os_err = | 334 OSStatus os_err = |
220 CSBackupSetItemExcluded(base::mac::NSToCFCast(file_url), TRUE, FALSE); | 335 CSBackupSetItemExcluded(base::mac::NSToCFCast(file_url), TRUE, FALSE); |
221 if (os_err != noErr) { | 336 if (os_err != noErr) { |
222 OSSTATUS_DLOG(WARNING, os_err) | 337 OSSTATUS_DLOG(WARNING, os_err) |
223 << "Failed to set backup exclusion for file '" | 338 << "Failed to set backup exclusion for file '" |
224 << file_path.value().c_str() << "'"; | 339 << file_path.value().c_str() << "'"; |
| 340 CHECK(base::PathExists(file_path)); |
| 341 |
| 342 CFStringRef r = CFURLGetString(base::mac::NSToCFCast(file_url)); |
| 343 const char* cs = CFStringGetCStringPtr(r, kCFStringEncodingUTF8); |
| 344 CHECK(cs); |
| 345 OSSTATUS_DLOG(WARNING, os_err) |
| 346 << "Failed to set backup exclusion for file '" |
| 347 << cs << "'"; |
| 348 #if 0 |
| 349 os_err = |
| 350 CSBackupSetItemExcluded(base::mac::NSToCFCast(file_url), 1, 0); |
| 351 if (os_err != noErr) { |
| 352 OSSTATUS_DLOG(WARNING, os_err) |
| 353 << "Failed to set backup exclusion for file '" |
| 354 << file_path.value().c_str() << "'"; |
| 355 os_err = |
| 356 CSBackupSetItemExcluded(base::mac::NSToCFCast(file_url), 1, 1); |
| 357 if (os_err != noErr) { |
| 358 OSSTATUS_DLOG(WARNING, os_err) |
| 359 << "Failed to set backup exclusion for file '" |
| 360 << file_path.value().c_str() << "'"; |
| 361 os_err = |
| 362 CSBackupSetItemExcluded(base::mac::NSToCFCast(file_url), 0, 0); |
| 363 if (os_err != noErr) { |
| 364 OSSTATUS_DLOG(WARNING, os_err) |
| 365 << "Failed to set backup exclusion for file '" |
| 366 << file_path.value().c_str() << "'"; |
| 367 } |
| 368 } |
| 369 } |
| 370 #endif |
225 } | 371 } |
226 return os_err == noErr; | 372 return os_err == noErr; |
| 373 #endif |
227 } | 374 } |
228 | 375 |
229 bool CheckLoginItemStatus(bool* is_hidden) { | 376 bool CheckLoginItemStatus(bool* is_hidden) { |
230 ScopedCFTypeRef<LSSharedFileListItemRef> item(GetLoginItemForApp()); | 377 ScopedCFTypeRef<LSSharedFileListItemRef> item(GetLoginItemForApp()); |
231 if (!item.get()) | 378 if (!item.get()) |
232 return false; | 379 return false; |
233 | 380 |
234 if (is_hidden) | 381 if (is_hidden) |
235 *is_hidden = IsHiddenLoginItem(item); | 382 *is_hidden = IsHiddenLoginItem(item); |
236 | 383 |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 StringPiece(begin + comma_loc + 1, ident.end()), &minor_tmp)) | 619 StringPiece(begin + comma_loc + 1, ident.end()), &minor_tmp)) |
473 return false; | 620 return false; |
474 *type = ident.substr(0, number_loc); | 621 *type = ident.substr(0, number_loc); |
475 *major = major_tmp; | 622 *major = major_tmp; |
476 *minor = minor_tmp; | 623 *minor = minor_tmp; |
477 return true; | 624 return true; |
478 } | 625 } |
479 | 626 |
480 } // namespace mac | 627 } // namespace mac |
481 } // namespace base | 628 } // namespace base |
OLD | NEW |