Implement user-level logging from MSC.app. Addresses #884.

This commit is contained in:
Greg Neagle
2018-12-13 14:24:31 -08:00
parent dbf1b560c8
commit f60564583c
@@ -8,13 +8,87 @@
import Foundation
let MSULOGDIR = "/Users/Shared/.com.googlecode.munki.ManagedSoftwareUpdate.logs"
// TO-DO: eliminate these global vars
var MSULOGFILE = ""
var MSULOGENABLED = false
var MSUDEBUGLOGENABLED = false
func is_safe_to_use(_ pathname: String) -> Bool {
// Returns true if we can open this file and it is a regular file owned by us
// mostly C functions since this a port from Python
var safe = false
let fref = open(UnsafePointer(pathname), O_RDWR | O_CREAT | O_NOFOLLOW, 0x0600)
if fref != -1 {
var st = stat()
if fstat(fref, UnsafeMutablePointer<stat>(&st)) == 0 {
safe = ((st.st_mode & S_IFREG) != 0) && (st.st_uid == getuid())
}
close(fref)
}
return safe
}
func setup_logging() {
// stub
if pref("MSUDebugLogEnabled") as? Bool ?? false {
MSUDEBUGLOGENABLED = true
}
if pref("MSULogEnabled") as? Bool ?? false {
MSULOGENABLED = true
}
if !(MSULOGENABLED) {
return
}
let username = NSUserName()
if !(FileManager.default.fileExists(atPath: MSULOGDIR)) {
do {
try FileManager.default.createDirectory(atPath: MSULOGDIR, withIntermediateDirectories: true, attributes: [FileAttributeKey.posixPermissions: 0x1777])
} catch {
NSLog("Could not create %@: %@", MSULOGDIR, "\(error)")
return
}
}
var pathIsDir = ObjCBool(false)
let msuLogDirExists = FileManager.default.fileExists(atPath: MSULOGDIR, isDirectory: &pathIsDir)
if !msuLogDirExists {
NSLog("%@ doesn't exist.", MSULOGDIR)
return
} else if pathIsDir.boolValue == false {
NSLog("%@ is not a directory", MSULOGDIR)
return
}
// try to set our preferred permissions
do {
try FileManager.default.setAttributes([FileAttributeKey.posixPermissions: 0x1777], ofItemAtPath: MSULOGDIR)
} catch {
// do nothing
}
// find a safe log file to write to for this user
var filename = NSString.path(withComponents: [MSULOGDIR, "\(username).log"])
//make sure we can write to this; that it's owned by us, and not writable by group or other
for _ in 0..<10 {
if is_safe_to_use(filename) {
MSULOGFILE = filename
return
}
NSLog("Not safe to use %@ for logging", filename)
filename = NSString.path(withComponents: [MSULOGDIR, "(\(username)_\(arc4random()).log"])
}
NSLog("Could not set up user-level logging for %@", username)
}
func msc_log(_ source: String, _ event: String, msg: String = "") {
// stub
print("\(source): \(event) \(msg)")
// Log an event from a source.
if MSULOGFILE != "" {
let logString = "\(source): \(event) \(msg)\n"
if let logData = logString.data(using: String.Encoding.utf8) {
if let fh = FileHandle(forUpdatingAtPath: MSULOGFILE) {
let _ = fh.seekToEndOfFile()
fh.write(logData)
}
}
}
}
func msc_debug_log(_ logMessage: String) {