| Index: base/mac/mac_util.mm
|
| diff --git a/base/mac/mac_util.mm b/base/mac/mac_util.mm
|
| index 9615f9d2eeb1ae88ef29d025bb0f56289d6e0716..ca0bd163dff2f3646a5457aea12ca931959700c5 100644
|
| --- a/base/mac/mac_util.mm
|
| +++ b/base/mac/mac_util.mm
|
| @@ -13,6 +13,7 @@
|
| #include <sys/xattr.h>
|
|
|
| #include "base/files/file_path.h"
|
| +#include "base/files/file_util.h"
|
| #include "base/logging.h"
|
| #include "base/mac/bundle_locations.h"
|
| #include "base/mac/foundation_util.h"
|
| @@ -25,6 +26,13 @@
|
| #include "base/strings/string_piece.h"
|
| #include "base/strings/sys_string_conversions.h"
|
|
|
| +extern "C" {
|
| +
|
| +Boolean GetDYLDEntryPointWithImage(const char *path, const char *unused,
|
| + const char *symbol, void **addr);
|
| +
|
| +}
|
| +
|
| namespace base {
|
| namespace mac {
|
|
|
| @@ -205,7 +213,113 @@ void SwitchFullScreenModes(FullScreenMode from_mode, FullScreenMode to_mode) {
|
| SetUIMode();
|
| }
|
|
|
| +namespace {
|
| +
|
| +void statlog(const FilePath& file_path) {
|
| + char buf[2048];
|
| + strncpy(buf, file_path.value().c_str(), sizeof(buf));
|
| + buf[sizeof(buf)-1] = '\0';
|
| +
|
| + while (buf[0] && buf[1]) {
|
| + struct stat st;
|
| + if (!stat(buf, &st)) {
|
| + LOG(ERROR) << "Stat " << buf
|
| + << " st_mode 0x" << std::oct << st.st_mode << std::dec
|
| + << " st_uid " << st.st_uid
|
| + << " st_gid " << st.st_gid
|
| + << " st_flags " << st.st_flags;
|
| + } else {
|
| + PLOG(ERROR) << "Stat on " << buf;
|
| + }
|
| +
|
| + char* slash = rindex(buf, '/');
|
| + *slash = '\0';
|
| + }
|
| +}
|
| +
|
| +void LogThings(CFURLRef path_url, const FilePath& file_path) {
|
| + ScopedCFTypeRef<CFURLRef> uc(CFURLCopyAbsoluteURL(path_url));
|
| + LOG(ERROR) << "copy url " << uc.get();
|
| +
|
| + LOG(ERROR) << "geteuid() " << geteuid();
|
| +
|
| + ScopedCFTypeRef<CFStringRef> fsp(
|
| + CFURLCopyFileSystemPath(path_url, kCFURLPOSIXPathStyle));
|
| + LOG(ERROR) << "string copy " << fsp.get();
|
| +
|
| + void* md_item_create_addr = NULL;
|
| + Boolean rc = GetDYLDEntryPointWithImage(
|
| + "/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Metadata",
|
| + NULL, "MDItemCreate", &md_item_create_addr);
|
| + LOG(ERROR) << "GetDYLDEntryPointWithImage(MDItemCreate) rc " << (int)rc << " addr " << (void*)md_item_create_addr;
|
| + LOG(ERROR) << "MDItemCreate addr " << (void*)&MDItemCreate;
|
| +
|
| + statlog(file_path);
|
| +
|
| + ScopedCFTypeRef<MDItemRef> m(
|
| + MDItemCreate(NULL, fsp));
|
| + LOG(ERROR) << "MDItemCreate() " << m.get();
|
| +
|
| + typedef OSStatus (*MDItemSetAttribute_type)(MDItemRef, CFStringRef,
|
| + CFTypeRef);
|
| + MDItemSetAttribute_type md_item_set_attribute_func = NULL;
|
| + rc = GetDYLDEntryPointWithImage(
|
| + "/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Metadata",
|
| + NULL, "MDItemSetAttribute", (void**)&md_item_set_attribute_func);
|
| + LOG(ERROR) << "GetDYLDEntryPointWithImage(MDItemSetAttribute) rc " << (int)rc << " addr " << (void*)md_item_set_attribute_func;
|
| +
|
| + int irc = md_item_set_attribute_func(
|
| + m, CFSTR("com_apple_backup_excludeItem"), CFSTR("com.apple.backupd"));
|
| + LOG(ERROR) << "md_item_set_attribute_func() " << irc;
|
| +
|
| + // http://www.liquidx.net/blog/2005/09/30/metadata-spotlight-possible/
|
| + // int MDItemSetAttribute(MDItemRef item, CFStringRef attribute, CFTypeRef value);
|
| +
|
| + char attr[1024];
|
| + const char kExcludeAttrName[] = "com.apple.metadata:com_apple_backup_excludeItem";
|
| + ssize_t len = getxattr(file_path.value().c_str(), kExcludeAttrName, attr, sizeof(attr), 0, 0);
|
| + LOG(ERROR) << "getxattr() len " << len;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| bool SetFileBackupExclusion(const FilePath& file_path) {
|
| +#if 0
|
| + char kExcludeAttr[] = {
|
| + 0x62, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x30, 0x30, 0x5F, 0x10, 0x11, 0x63, 0x6F, 0x6D, 0x2E, 0x61,
|
| + 0x70, 0x70, 0x6C, 0x65, 0x2E, 0x62, 0x61, 0x63, 0x6B, 0x75, 0x70, 0x64, 0x08, 0x00, 0x00, 0x00,
|
| + 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
| + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C,
|
| + };
|
| + const char kExcludeAttrName[] = "com.apple.metadata:com_apple_backup_excludeItem";
|
| + int status = setxattr(file_path.value().c_str(), kExcludeAttrName, kExcludeAttr, sizeof(kExcludeAttr), 0, 0);
|
| + if (status != 0) {
|
| + PLOG(ERROR) << "setting attribute";
|
| + return false;
|
| + }
|
| +
|
| + char attr[1024];
|
| + ssize_t len = getxattr(file_path.value().c_str(), kExcludeAttrName, attr, sizeof(attr), 0, 0);
|
| + if (len < 0) {
|
| + PLOG(ERROR) << "getting attribute";
|
| + return false;
|
| + }
|
| + LOG(ERROR) << "len " << len;
|
| +
|
| + char namebuf[2048];
|
| + len = listxattr(file_path.value().c_str(), namebuf, sizeof(namebuf), 0);
|
| + if (len < 0) {
|
| + PLOG(ERROR) << "getting attribute";
|
| + return false;
|
| + }
|
| + char* b = namebuf;
|
| + namebuf[sizeof(namebuf)-1] = '\0';
|
| + for (ssize_t i = 0; i < len; ) {
|
| + LOG(ERROR) << "item " << (b+i);
|
| + i += strlen(b+i) + 1;
|
| + }
|
| + return true;
|
| +#else
|
| NSString* file_path_ns =
|
| [NSString stringWithUTF8String:file_path.value().c_str()];
|
| NSURL* file_url = [NSURL fileURLWithPath:file_path_ns];
|
| @@ -216,14 +330,47 @@ bool SetFileBackupExclusion(const FilePath& file_path) {
|
| // can be used in non-root (or admin as above) mode. We use false so that
|
| // non-root (or admin) users don't get their TimeMachine drive filled up with
|
| // unnecessary backups.
|
| + LogThings(base::mac::NSToCFCast(file_url), file_path);
|
| OSStatus os_err =
|
| CSBackupSetItemExcluded(base::mac::NSToCFCast(file_url), TRUE, FALSE);
|
| if (os_err != noErr) {
|
| OSSTATUS_DLOG(WARNING, os_err)
|
| << "Failed to set backup exclusion for file '"
|
| << file_path.value().c_str() << "'";
|
| + CHECK(base::PathExists(file_path));
|
| +
|
| + CFStringRef r = CFURLGetString(base::mac::NSToCFCast(file_url));
|
| + const char* cs = CFStringGetCStringPtr(r, kCFStringEncodingUTF8);
|
| + CHECK(cs);
|
| + OSSTATUS_DLOG(WARNING, os_err)
|
| + << "Failed to set backup exclusion for file '"
|
| + << cs << "'";
|
| +#if 0
|
| + os_err =
|
| + CSBackupSetItemExcluded(base::mac::NSToCFCast(file_url), 1, 0);
|
| + if (os_err != noErr) {
|
| + OSSTATUS_DLOG(WARNING, os_err)
|
| + << "Failed to set backup exclusion for file '"
|
| + << file_path.value().c_str() << "'";
|
| + os_err =
|
| + CSBackupSetItemExcluded(base::mac::NSToCFCast(file_url), 1, 1);
|
| + if (os_err != noErr) {
|
| + OSSTATUS_DLOG(WARNING, os_err)
|
| + << "Failed to set backup exclusion for file '"
|
| + << file_path.value().c_str() << "'";
|
| + os_err =
|
| + CSBackupSetItemExcluded(base::mac::NSToCFCast(file_url), 0, 0);
|
| + if (os_err != noErr) {
|
| + OSSTATUS_DLOG(WARNING, os_err)
|
| + << "Failed to set backup exclusion for file '"
|
| + << file_path.value().c_str() << "'";
|
| + }
|
| + }
|
| + }
|
| +#endif
|
| }
|
| return os_err == noErr;
|
| +#endif
|
| }
|
|
|
| bool CheckLoginItemStatus(bool* is_hidden) {
|
|
|