Skip to content

Instantly share code, notes, and snippets.

@clburlison
Created July 20, 2018 14:16
Show Gist options
  • Save clburlison/e482d5b1d48da651bb2615056c4da974 to your computer and use it in GitHub Desktop.
Save clburlison/e482d5b1d48da651bb2615056c4da974 to your computer and use it in GitHub Desktop.
2018 Dallas Apple Meetup
package main // import "gitlab.com/clburlison/cfprefs"
// Huge credits to Tom Burgin (bur) & Victor Vrantchan (groob)
import (
"fmt"
"unsafe"
"reflect"
)
/*
#cgo LDFLAGS: -framework CoreFoundation
#include <CoreFoundation/CoreFoundation.h>
*/
import "C"
// Convert a Go string to a CFString
// Make sure to release the CFString when finished
func stringToCFString(s string) C.CFStringRef {
return C.CFStringCreateWithCString(C.kCFAllocatorDefault, C.CString(s), C.kCFStringEncodingUTF8)
}
// Convert a CFString to a Go string
func cfstringToString(s C.CFStringRef) string {
return C.GoString(C.CFStringGetCStringPtr(s, C.kCFStringEncodingUTF8))
}
// Convert a CFBoolean to a Go bool
func cfbooleanToBoolean(s C.CFBooleanRef) bool {
// fmt.Println(reflect.TypeOf(C.CFBooleanGetValue(s)))
if C.CFBooleanGetValue(s) == 1 {
return true
}
return false
}
// Convert a CFData to a Go byte
func cfdataToData(s C.CFDataRef) []uint8 {
d := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(s)), C.int(C.CFDataGetLength(s)))
return d
}
// CFPreferencesCopyAppValue - Return a value from a preference
func CFPreferencesCopyAppValue(key string, domain string) interface{} {
k := stringToCFString(key)
defer release(C.CFTypeRef(k))
d := stringToCFString(domain)
defer release(C.CFTypeRef(d))
if ret := C.CFPreferencesCopyAppValue(k, d); ret != 0 && C.CFGetTypeID(ret) == C.CFStringGetTypeID() {
defer release(ret)
return cfstringToString(C.CFStringRef(ret))
}
if ret := C.CFPreferencesCopyAppValue(k, d); ret != 0 && C.CFGetTypeID(ret) == C.CFBooleanGetTypeID() {
defer release(ret)
return cfbooleanToBoolean(C.CFBooleanRef(ret))
}
if ret := C.CFPreferencesCopyAppValue(k, d); ret != 0 && C.CFGetTypeID(ret) == C.CFDataGetTypeID() {
defer release(ret)
return cfdataToData(C.CFDataRef(ret))
}
return ""
}
func release(ref C.CFTypeRef) {
if ref != 0 {
C.CFRelease(ref)
}
}
func main() {
fmt.Printf("%s\n", CFPreferencesCopyAppValue("aData", "com.clburlison.test"))
fmt.Printf("%s\n", reflect.TypeOf(CFPreferencesCopyAppValue("aData", "com.clburlison.test")))
fmt.Printf("%v\n", CFPreferencesCopyAppValue("aString", "com.clburlison.test"))
fmt.Printf("%s\n", reflect.TypeOf(CFPreferencesCopyAppValue("aString", "com.clburlison.test")))
fmt.Printf("%v\n", CFPreferencesCopyAppValue("aBool", "com.clburlison.test"))
fmt.Printf("%s\n", reflect.TypeOf(CFPreferencesCopyAppValue("aBool", "com.clburlison.test")))
}
#!/usr/bin/python
from Foundation import CFPreferencesCopyAppValue
aData = CFPreferencesCopyAppValue("aData", "com.clburlison.test")
print(aData)
print(type(aData))
aString = CFPreferencesCopyAppValue("aString", "com.clburlison.test")
print(aString)
print(type(aString))
aBool = CFPreferencesCopyAppValue("aBool", "com.clburlison.test")
print(aBool)
print(type(aBool))
#!/usr/bin/python
import subprocess
import binascii
cmd = [
"defaults",
"read",
"com.clburlison.test",
"aData",
]
out = subprocess.check_output(cmd).strip("\n<>").replace(" ", "")
print(binascii.unhexlify(out))
print(type(out))
cmd = [
"defaults",
"read",
"com.clburlison.test",
"aString",
]
out = subprocess.check_output(cmd)
print(out.strip("\n"))
print(type(out))
cmd = [
"defaults",
"read",
"com.clburlison.test",
"aBool",
]
out = subprocess.check_output(cmd)
print(out.strip("\n"))
print(type(out))
#!/bin/bash
out=$(defaults read com.clburlison.test aData)
hexdump=$(echo $out | tr -d '\n<> ')
echo $hexdump | xxd -ps -r
echo ''
out=$(defaults read-type com.clburlison.test aData)
echo $out
out=$(defaults read com.clburlison.test aString)
echo $out
out=$(defaults read-type com.clburlison.test aString)
echo $out
out=$(defaults read com.clburlison.test aBool)
echo $out
out=$(defaults read-type com.clburlison.test aBool)
echo $out
#!/usr/bin/python
# Yes I am being lazy and shelling out to defaults :shrug:
import binascii
import subprocess
# If you wanted to read from a file you could use the following
# filename = "somefile_here"
# with open(filename, 'rb') as f:
# content = f.read()
content = "asdlfkjasldfihaisygdfkhjawekuyrg1uyg23bkja89c7gd6aikuwherbuy1f46879y8ohjahvsdftya8gisuhdkfbvwuatef87aiuhsdfbyaus687d9f8hubhagsvdufyguihabhsdgvfy78uhabsgvdhfuyiuohjkbgvc123guybhjkijgo897s6tyvg"
hexdata = binascii.hexlify(content)
cmd = [
"defaults",
"write",
"com.clburlison.test",
"aData",
"-data",
hexdata
]
subprocess.check_output(cmd)
cmd = [
"defaults",
"write",
"com.clburlison.test",
"aString",
"-string",
"Hello World"
]
subprocess.check_output(cmd)
cmd = [
"defaults",
"write",
"com.clburlison.test",
"aBool",
"-bool",
"FALSE"
]
subprocess.check_output(cmd)
cmd = [
"defaults",
"write",
"com.clburlison.test",
"aInt",
"-integer",
"0"
]
subprocess.check_output(cmd)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment