Skip to content

Commit 7e8ccda

Browse files
committed
Initial commit
1 parent a98c8da commit 7e8ccda

1 file changed

Lines changed: 182 additions & 0 deletions

File tree

src/user-defaults

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
#!/bin/bash
2+
3+
## region ############################################## Static Variables
4+
5+
binDefaults="/usr/bin/defaults"
6+
binReload="/System/Library/PrivateFrameworks/SystemAdministration.framework/Resources/activateSettings"
7+
version="1.0"
8+
9+
## endregion ########################################### End Static Variables
10+
11+
## region ############################################## Functions
12+
13+
function normalizeValue() {
14+
local val
15+
16+
val=$1
17+
18+
case "$val" in
19+
1 | yes | TRUE | True | true ) val="-bool true" ;;
20+
0 | no | FALSE | False | false ) val="-bool false" ;;
21+
esac
22+
23+
echo "$val" && return 0
24+
}
25+
26+
function output::usage() {
27+
local help
28+
help=$(defaults help)
29+
echo "$help" | tail -n + 1 | head -n 2
30+
echo "Command line interface to a specific user's defaults. Automatically refreshes defaults after writing."
31+
echo "Syntax:"
32+
echo ""
33+
echo "'defaults-user' -version Displays the version number"
34+
echo "'defaults-user' -help Displays this help"
35+
echo "'defaults-user' [ -currentHost | -host <hostname> ] [ -user <username> ] [ -quiet ] followed by one of the following:"
36+
echo ""
37+
echo "$help" | tail -n +6 | head -n 22
38+
echo "<user> is a valid macOS user. If not specified, the currently logged in console user will be used."
39+
echo " Exits with an error if no user is specified and no user is logged in."
40+
echo ""
41+
echo "$help" | tail -n +28
42+
echo ""
43+
echo "If no value type is specified, the -bool flag is automatically added for boolean-like values."
44+
echo ""
45+
}
46+
47+
function output::version() {
48+
echo "user-defaults v${version}"
49+
}
50+
51+
# /*!
52+
# Public: Shows the username of the current console user, if any is logged in.
53+
# */
54+
function user::console() {
55+
echo "show State:/Users/ConsoleUser" | /usr/sbin/scutil | /usr/bin/awk '/Name :/ && ! /loginwindow/ { print $3 }'
56+
}
57+
58+
59+
function _isJamf() {
60+
local cName firstCharFirstArg
61+
cName=$(/usr/sbin/scutil --get ComputerName)
62+
firstCharFirstArg=$(/usr/bin/printf '%s' "$1" | /usr/bin/cut -c 1)
63+
if [ "$firstCharFirstArg" == "/" ] && [ "$2" == "$cName" ]; then
64+
return 0
65+
else
66+
return 1
67+
fi
68+
}
69+
70+
## endregion ########################################### End Functions
71+
72+
## region ############################################## Jamf Detection & Argument Shifting
73+
74+
if _isJamf "$@"; then
75+
# shellcheck disable=SC2034
76+
jamfMountPoint="$1"
77+
# shellcheck disable=SC2034
78+
jamfHostName="$2"
79+
# shellcheck disable=SC2034
80+
jamfUser="$3"
81+
targetUser="$jamfUser"
82+
# Remove Jamf Arguments
83+
shift 3
84+
# Blank first Output Line for Prettier Jamf Logs
85+
echo ""
86+
fi
87+
88+
## endregion ########################################### End Jamf Detection and Arg Shifting
89+
90+
## region ############################################## Argument Handling
91+
92+
isQuiet=false
93+
isType=false
94+
args=()
95+
while [ "$1" != "" ]; do
96+
# See if user specified a type
97+
case "$1" in
98+
-string | -data | -int | -integer | -float | -bool | -boolean | -date ) isType=true; isSingle=true ;;
99+
-array | -array-add | -dict | -dict-add ) isType=true; isSingle=false ;;
100+
esac
101+
102+
# Check for our added flags
103+
case "$1" in
104+
-u | -user | --user ) targetUser="$2"; shift;;
105+
-q | -quiet | --quiet ) isQuiet=true; ;;
106+
-currentHost ) host="current"; ;;
107+
-host ) host="$2"; shift;;
108+
-h | --help | help ) output::usage; exit;; # quit and show usage
109+
--version ) output::version; exit;; # quit and show usage
110+
* ) args+=("$1") # if no match, add it to the positional args
111+
esac
112+
shift # move to next kv pair
113+
done
114+
115+
## endregion ########################################### End Argument Handling
116+
117+
## region ############################################## Main Code
118+
119+
prefix="sudo -u $targetUser"
120+
action="${args[0]}"
121+
122+
if [ "$action" == "write" ] && $isSingle; then
123+
# Get Particulars
124+
domain="${args[1]}"
125+
key="${args[2]}"
126+
if $isType; then
127+
type="${args[3]}"
128+
value="${args[4]}"
129+
else
130+
type=""
131+
value=$(normalizeValue "${args[3]}")
132+
fi
133+
134+
# Normalize Domain
135+
if [ "$domain" == ".GlobalPreferences" ]; then
136+
domain="-g"
137+
fi
138+
139+
command=("$prefix" "$binDefaults" "write" "$host" "$domain" "$key" "$type" "$value")
140+
else
141+
# Here we are just prefixing
142+
command=("$prefix" "$binDefaults" "$host")
143+
for arg in "${args[@]}"
144+
do
145+
command+=("$arg")
146+
done
147+
fi
148+
149+
# Build the normalized command
150+
commandStr=""
151+
for part in "${command[@]}"; do
152+
if [ -n "$part" ]; then
153+
if [ -n "$commandStr" ]; then
154+
commandStr="$commandStr $part"
155+
else
156+
commandStr="$part"
157+
fi
158+
fi
159+
done
160+
161+
# Output if Applicable
162+
if $isQuiet; then
163+
if $commandStr /dev/null 2>&1; then
164+
if echo "$action" | grep -q 'write\|array\|array-add\|dict\|dict-add'; then
165+
$prefix $binReload -u
166+
fi
167+
168+
exit 0
169+
fi
170+
else
171+
if $commandStr; then
172+
if echo "$action" | grep -q 'write\|array\|array-add\|dict\|dict-add'; then
173+
$prefix $binReload -u
174+
fi
175+
176+
exit 0
177+
else
178+
exit $?
179+
fi
180+
fi
181+
182+
## endregion ########################################### End Main Code

0 commit comments

Comments
 (0)