# NOTE:
-# our .zprofile is expensive, so we keep track of what has been run already,
-# and only set up what is necessary. additionally, we want to ensure that our
-# environment is set up as early as possible, so we also source .zprofile in
-# .zshenv for new non-login shells.
+# our .zprofile can be expensive, so we keep track of what has been run
+# already, and only set up what is necessary. additionally, we want to ensure
+# that our environment is set up as early as possible, so we also source
+# .zprofile in .zshenv for new non-login shells.
#
# these issues are handled by using these methods:
# * the parent shell that starts the user's session after logging in to some
# broken—in all 3 of these cases the best choice is remove it.
p=$(basename $x)
if {[[ -v _sev_gpg_forward_clean || $$ == $p ]] ||
- ! kill -0 $p 2>/dev/null} {
+ ! kill -0 $p 2>/dev/null} {
find $x -mindepth 1 -maxdepth 1 | while {read -r y} {
# XXX: real dirs will stop unlink, consider it a feature
unlink $y
# NOTE: same rationale as above
p=${$(basename $x)#.session.}
if {[[ -v _sev_tmp_clean || $$ == $p ]] ||
- ! kill -0 $p 2>/dev/null} {
+ ! kill -0 $p 2>/dev/null} {
rm -rf $x
}
}
### lang
export CHARSET=${CHARSET:-UTF-8}
export LANG=${LANG:-en_US.UTF-8}
-export LC_CTYPE=${LC_TYPE:-$LANG}
### path
# NOTE: we utilize the fact that unique arrays keep the first occurrence and
typeset -U path fpath
# add as many generic paths as possible to keep the order we want
# NOTE: /usr/{local,pkg,games} are unix/bsdisms
- # XXX: PREFIX not validated, non-posix but Termux uses it
+ # XXX: PREFIX not validated, non-posix but Termux uses it, maybe others
+ # XXX: XDG specifies ~/.local/bin as the only user-writable dir for
+ # executables, but we specify more; technically this is against spec
syspath=("$path[@]")
- path=(~/{s,}bin
+ path=(~/{.local/,}{s,}bin
{~/.local,{$PREFIX,}{,/opt,/usr{,/local,pkg}}}/sbin
{~/.local,{$PREFIX,}{,/opt,/usr{,/local,pkg}}}/bin
/usr/{X11R{7,6}/bin,games})
export _sev_setup_path=
}
+### xdg local dir
+# NOTE: need this for tmp, so confirm it exists.
+# XXX: perms are not specified for XDG dirs except runtime, but I think 760
+# makes the most sense. shouldn't break anything since no one else should
+# be poking around in our dir.
+[[ -e ~/.local ]] || mkdir -m760 ~/.local
+
### tmp
# NOTE: specs say that POSIX tmp and XDG runtime directories should exist
# until the last session is logged out (POSIX can exist for longer).
# toplevel session (i.e. SHLVL=1). this should placate most applications,
# though it is not expressly spec compliant.
if [[ ! -v _sev_tmp ]] {
- _sev_tmp=~/tmp
- # create personal tmp dir
+ _sev_tmp=~/.local/tmp
+ # NOTE: race condition/remove in use files
+ [[ -h $_sev_tmp ]] && unlink $_sev_tmp 2>/dev/null
t=${TMPDIR:-${TEMP:-${TMP:-/tmp}}}/.home-$LOGNAME
- [[ ! -e $t ]] && mkdir -m700 $t 2>/dev/null
+ # create personal tmp dir under system tmp
+ [[ -e $t ]] || mkdir -m700 $t 2>/dev/null
if [[ ! -d $t ]] {
[[ -o interactive ]] &&
- print -P "%F{red}!!! Can't create tmpdir $t%f"
- # fallback bare directories
- [[ -h $_sev_tmp ]] && unlink $_sev_tmp 2>/dev/null
- [[ ! -e $_sev_tmp ]] && mkdir -m700 $_sev_tmp 2>/dev/null
+ print -P "%F{orange}*** Can't create TMPDIR $t, using $_sev_tmp%f"
+ # fallback bare directory
+ [[ -e $_sev_tmp ]] || mkdir -m700 $_sev_tmp 2>/dev/null
+ if [[ ! -d $_sev_tmp ]] {
+ [[ -o interactive ]] &&
+ print -P "%F{red}!!! No usable TMPDIR%f"
+ unset _sev_tmp
+ } else {
+ t=$_sev_tmp
+ }
+ } elif [[ -e $_sev_tmp ]] {
+ [[ -o interactive ]] &&
+ print -P "%F{orange}*** $_sev_tmp occluded, can't link to TMPDIR $t%f"
+ _sev_tmp=$t
+ } else {
+ ln -s $t $_sev_tmp 2>/dev/null
+ }
+ if [[ -v _sev_tmp ]] {
+ # ensure dir is clean
+ _sev_zcleanup tmp
+ # finally create our subdir for this session
+ t=$_sev_tmp/.session.$$
+ if ! mkdir -m700 $t 2>/dev/null; then
+ [[ -o interactive ]] &&
+ print -P "%F{red}!!! Can't create session subdir $t, using $_sev_tmp%f"
+ t=$_sev_tmp
+ fi
+ export _sev_tmp TMPDIR=$t TEMP=$t TMP=$t
+ unset t
}
- # link home tmp for convenience if there isn't anything meaningful there
- [[ -h $_sev_tmp || ! -e $_sev_tmp ]] && ln -sfn $t $_sev_tmp 2>/dev/null
- export _sev_tmp=$(realpath $_sev_tmp)
- # ensure dir is clean
- _sev_zcleanup tmp
- # finally create our subdir for this session
- h=$_sev_tmp/.session.$$
- mkdir -m700 $h 2>/dev/null
- export TMPDIR=$h TEMP=$h TMP=$h
- unset t h
}
### xdg
if [[ ! -v _sev_setup_xdg ]] {
- # merge with any existing dirs and remove duplicates using unique arrays
+ ## merge with any existing dirs and remove duplicates using unique arrays
+ # NOTE: we are accepting whatever value might be set for CONFIG and DATA;
+ # if it wasn't set, we just use default and leave it unset
# NOTE: include and then remove CONFIG_HOME and DATA_HOME to ensure they
# are not present in the array if it was added before we got to it
- typeset -UT XDG_CONFIG_DIRS xdg_config_dirs
- export XDG_CONFIG_HOME=~/etc
- mkdir $XDG_CONFIG_HOME 2>/dev/null
- xdg_config_dirs=($XDG_CONFIG_HOME ~/.config
- {/opt,/usr/local,/usr/pkg,}/etc/xdg
- "${XDG_CONFIG_DIRS:+${xdg_config_dirs[@]}}")
- export XDG_CONFIG_DIRS=${XDG_CONFIG_DIRS#$XDG_CONFIG_HOME}
-
typeset -UT XDG_DATA_DIRS xdg_data_dirs
- export XDG_DATA_HOME=~/share
- mkdir $XDG_DATA_HOME 2>/dev/null
- xdg_data_dirs=($XDG_DATA_HOME ~/.local/share
- /{opt,usr/local,usr/pkg,usr}/share
+ if [[ -v XDG_DATA_HOME ]] {
+ export XDG_DATA_HOME
+ } elif [[ ! -e ~/.local/share ]] {
+ mkdir -m760 ~/.local/share
+ }
+ xdg_data_dirs=($XDG_DATA_HOME /{opt,usr/local,usr/pkg,usr}/share
"${XDG_DATA_DIRS:+${xdg_data_dirs[@]}}")
- export XDG_DATA_DIRS=${XDG_DATA_DIRS#$XDG_DATA_HOME}
+ # XXX: if colons are not escaped, could remove unintended part of string
+ export XDG_DATA_DIRS=${XDG_DATA_DIRS#$XDG_DATA_HOME:}
- mkdir ~/var 2>/dev/null
- export XDG_STATE_HOME=~/var/lib
- mkdir $XDG_STATE_HOME 2>/dev/null
+ typeset -UT XDG_CONFIG_DIRS xdg_config_dirs
+ if [[ -v XDG_CONFIG_HOME ]] {
+ export XDG_CONFIG_HOME
+ } elif [[ ! -e ~/.config ]] {
+ mkdir -m760 ~/.config
+ }
+ # I am of the belief .local should follow FHS /usr/local...
+ [[ -e ~/.local/etc ]] || ln -s ~/.config ~/.local/etc
+ xdg_config_dirs=($XDG_CONFIG_HOME ${XDG_CONFIG_DIRS:+"$xdg_config_dirs[@]"}
+ {/opt,/usr/local,/usr/pkg,}/etc/xdg)
+ # XXX: if colons are not escaped, could remove unintended part of string
+ export XDG_CONFIG_DIRS=${XDG_CONFIG_DIRS#$XDG_CONFIG_HOME:}
- if [[ -v _sev_tmp ]] {
- export XDG_CACHE_HOME=$_sev_tmp/.xdg.cache
- mkdir $XDG_CACHE_HOME 2>/dev/null
+ if [[ -v XDG_STATE_HOME ]] {
+ export XDG_STATE_HOME
+ } elif [[ ! -e ~/.local/state ]] {
+ mkdir -m760 ~/.local/state
+ }
- export XDG_RUNTIME_DIR=$TMPDIR/.xdg.runtime
- # same as in tmpdir creation, ensure it doesn't exist
- if [[ -h $XDG_RUNTIME_DIR ]]; then
- unlink $XDG_RUNTIME_DIR 2>/dev/null
- elif [[ -e $XDG_RUNTIME_DIR ]]; then
- rm -rf $XDG_RUNTIME_DIR 2>/dev/null
- fi
- mkdir -m700 $XDG_RUNTIME_DIR 2>/dev/null
+ if [[ ! -v XDG_CACHE_HOME ]] {
+ if [[ -v _sev_tmp ]] {
+ export XDG_CACHE_HOME=$_sev_tmp/.xdg.cache
+ [[ -e $XDG_CACHE_HOME ]] || mkdir -m700 $XDG_CACHE_HOME
+ } elif [[ ! -e ~/.cache ]] {
+ mkdir -m700 ~/.cache
+ }
+ }
+
+ # make runtime dir in our session-specific tmpdir
+ export XDG_RUNTIME_DIR=$TMPDIR/.xdg.runtime
+ # same as in tmpdir creation, ensure dir doesn't exist
+ if [[ -h $XDG_RUNTIME_DIR ]] {
+ unlink $XDG_RUNTIME_DIR 2>/dev/null
+ } elif [[ -e $XDG_RUNTIME_DIR ]] {
+ rm -rf $XDG_RUNTIME_DIR 2>/dev/null
}
+ mkdir -m700 $XDG_RUNTIME_DIR 2>/dev/null
# source user dirs after other vars
[[ -e $XDG_CONFIG_HOME/user-dirs.dirs ]] &&
### gpg home
if [[ ! -v GNUPGHOME ]] {
- export GNUPGHOME=~/etc/gnupg
+ export GNUPGHOME=${XDG_CONFIG_HOME:-~/.config}/gnupg
if [[ -d ~/.gnupg ]] {
- mv ~/.gnupg ~/etc/gnupg
+ mv ~/.gnupg ${XDG_CONFIG_HOME:-~/.config}/gnupg
}
}
# remote host before opening a shell, so that we can have the host
# communicate back to the client where it wants a socket created or ask
# the host if the path the client wants to use is writable. however, this
-# would open up too many edge cases where it wouldn't work or be clunky
-# (e.g. asking for password twice) to make it worth it.
+# would open up too many edge cases where it wouldn't work or be too
+# clunky (e.g. asking for password twice) to make it worth it.
function _gpg_socketpath {
# dirs are percent-encoded: https://stackoverflow.com/a/64312099
echo ${1//(#b)%([[:xdigit:]](#c2))/${(#):-0x$match[1]}}
}
if [[ ! -v _sev_setup_gpg_forward && -v commands[gpg] ]] {
+ # XXX: assuming /tmo exists and is writable on destination
export _GNUPG_SOCK_DEST_BASE=/tmp/.gpg-agent-forward
export _GNUPG_SOCK_DEST_EXT=$(date +%s).$RANDOM
export _GNUPG_SOCK_DEST=$_GNUPG_SOCK_DEST_BASE.$_GNUPG_SOCK_DEST_EXT
}
### gpg agent
-if [[ -v commands[gpg-connect-agent] && ( ! -v _sev_setup_gpgagent ||
- ( -v _sev_first_display && -z $_sev_first_display ) ) ]] {
+if [[ -v commands[gpg-connect-agent] &&
+ ( ! -v _sev_setup_gpgagent || -v _sev_refresh_gpgagent ) ]] {
# avoid printing if we have already set up tty before
[[ ! -v _sev_setup_gpgagent && -o interactive ]] && p=true || p=false
if {$p} {
}
export _sev_setup_gpgagent=
}
- unset p
+ unset p _sev_refresh_gpgagent
}
### ssh agent
### load site-specific
-if [[ -f ~/.zprofile.local ]] { source ~/.zprofile.local }
+if [[ -f ${ZDOTDIR:-~}/.zprofile.local ]] { source ${ZDOTDIR:-~}/.zprofile.local }
# vim: et sts=4 sw=4 ts=8 tw=79