lenny@crapbox ~ $ bash -x -v psd p #!/bin/bash # # Profile-sync-daemon by graysky # Inspired by some code originally written by Colin Verot # # needed for debian 8.x [[ -h /sbin ]] || PATH=$PATH:/sbin + [[ -h /sbin ]] BLD="\e[01m" + BLD='\e[01m' RED="\e[01;31m" + RED='\e[01;31m' GRN="\e[01;32m" + GRN='\e[01;32m' BLU="\e[01;34m" + BLU='\e[01;34m' NRM="\e[00m" + NRM='\e[00m' VERS="6.12" + VERS=6.12 user=$(id -un) id -un ++ id -un + user=lenny HOME="$(getent passwd $user | cut -d: -f6)" getent passwd $user | cut -d: -f6 ++ getent passwd lenny ++ cut -d: -f6 + HOME=/home/lenny XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" + XDG_CONFIG_HOME=/home/lenny/.config PSDCONFDIR="$XDG_CONFIG_HOME/psd" + PSDCONFDIR=/home/lenny/.config/psd PSDCONF="$PSDCONFDIR/psd.conf" + PSDCONF=/home/lenny/.config/psd/psd.conf SHAREDIR="/usr/share/psd" + SHAREDIR=/usr/share/psd if [[ ! -d "$SHAREDIR" ]]; then echo -e " Missing ${BLU}$SHAREDIR${NRM}${BLD} - reinstall the package to use profile-sync-daemon." exit 1 fi + [[ ! -d /usr/share/psd ]] # Setup check for config file if [[ -f "$PSDCONF" ]]; then . $PSDCONF elif [[ -d "$HOME/.psd" ]]; then # first check to see if a legacy ~/.psd is present and then move it to the # new location mkdir -p "$PSDCONFDIR" rsync -ax "$HOME/.psd/" "$PSDCONFDIR/" rm -rf "$HOME/.psd" echo " The use of $HOME/.psd is deprecated. Existing config has been moved to $PSDCONFDIR" # source it again retaining any user options [[ -f "$PSDCONF" ]] && . $PSDCONF else mkdir -p "$PSDCONFDIR" if [[ -f "$SHAREDIR/psd.conf" ]]; then cp "$SHAREDIR/psd.conf" "$PSDCONFDIR" echo -e " First time running psd so please edit ${BLU}$PSDCONF${NRM}${BLD} to your liking and run again."${NRM} exit 0 fi fi + [[ -f /home/lenny/.config/psd/psd.conf ]] + . /home/lenny/.config/psd/psd.conf # # $XDG_HOME_CONFIG/psd/psd.conf # # For documentation, refer to the psd man page or the wiki page # https://wiki.archlinux.org/index.php/Profile-sync-daemon ## NOTE the following: ## To protect data from corruption, in the event that you do make an edit while ## psd is active, any changes made will be applied the next time you start psd. # Uncomment and set to "yes" to use overlayfs instead of a full copy to reduce # the memory costs and to improve sync/unsync operations. Note that your kernel # MUST have this module available in order to use this mode # USE_OVERLAYFS="yes" ++ USE_OVERLAYFS=yes # List browsers separated by spaces to include in the sync. Useful if you do not # wish to have all possible browser profiles sync'ed which is the default if # this variable is left commented. # # Possible values: # chromium # chromium-dev # conkeror.mozdev.org # epiphany # firefox # firefox-trunk # google-chrome # google-chrome-beta # google-chrome-unstable # heftig-aurora # icecat # inox # luakit # midori # opera # opera-beta # opera-developer # opera-legacy # otter-browser # qupzilla # palemoon # rekonq # seamonkey # vivaldi # vivaldi-snapshot # BROWSERS="firefox" ++ BROWSERS=firefox # Define where browser profiles will reside in tmpfs if $XDG_RUNTIME_DIR isn't # defined. This location must be mounted to tmpfs and MUST have permissions # of at least 700. # Use NO trailing backslash! # # Suggested locations based on distro defaults: # Arch Linux/Chakra, Fedora, and Gentoo leave this commented out # Debian 8+ use a setting of "/dev/shm" # Ubuntu 15.05+ use "/dev/shm" #VOLATILE="/tmp" # Uncomment and set to "no" to completely disable the crash recovery feature. # # The default is to create crash recovery backups if the system is ungracefully # powered-down due to a kernel panic, hitting the reset switch, battery going # dead, etc. Some users keep very diligent backups and don't care to have this # feature enabled. #USE_BACKUPS="yes" # if psd is active, source the snapshot of psd.conf preferentially # version 6.03 renames this file so if older version is running then # rotate the old name to the new one [[ -f "$PSDCONFDIR/.$user@$(hostname).pid.conf" ]] && mv "$PSDCONFDIR/.$user@$(hostname).pid.conf" "$PSDCONFDIR/.psd.conf" hostname ++ hostname + [[ -f /home/lenny/.config/psd/.lenny@crapbox.pid.conf ]] if [[ -f "$PID_FILE" ]]; then if [[ -f "$PSDCONFDIR/.psd.conf" ]]; then PSDCONF="$PSDCONFDIR/.psd.conf" unset USE_OVERLAYFS BROWSERS VOLATILE USE_BACKUPS . $PSDCONF fi fi + [[ -f '' ]] # all supported browsers ALL_BROWSERS=( $(ls "${SHAREDIR}/browsers/") ) + ALL_BROWSERS=($(ls "${SHAREDIR}/browsers/")) ls "${SHAREDIR}/browsers/" ++ ls /usr/share/psd/browsers/ BROWSERS=${BROWSERS:-"${ALL_BROWSERS[@]}"} + BROWSERS=firefox # prefer using $XDG_RUNTIME_DIR for VOLATILE but fall-back to config value if [[ -n "$XDG_RUNTIME_DIR" ]]; then VOLATILE="$XDG_RUNTIME_DIR" else [[ -z "$VOLATILE" ]] && VOLATILE="/tmp" fi + [[ -n /run/user/1000 ]] + VOLATILE=/run/user/1000 PID_FILE="$VOLATILE/psd.pid" + PID_FILE=/run/user/1000/psd.pid # simple function to determine user intent rather than using a null value case "${USE_OVERLAYFS,,}" in y|yes|true|t|on|1|enabled|enable|use) OLFS=1 ;; *) OLFS=0 ;; esac + case "${USE_OVERLAYFS,,}" in + OLFS=1 # since the default for this one is a yes, need to force a null value to yes [[ -z "${USE_BACKUPS,,}" ]] && USE_BACKUPS="yes" + [[ -z '' ]] + USE_BACKUPS=yes case "${USE_BACKUPS,,}" in y|yes|true|t|on|1|enabled|enable|use) CRRE=1 ;; *) CRRE=0 ;; esac + case "${USE_BACKUPS,,}" in + CRRE=1 # determine is we are using overlayfs (v22 and below) or overlay (v23 and above) # since mount should call modprobe on invocation, check to see if either # module is in the tree using modinfo if [[ $OLFS -eq 1 ]]; then # first check to see if either is hardcoded into the kernel # and of course prefer version 23 [[ $(grep -ciE "overlayfs$" /proc/filesystems) -eq 1 ]] && OLFSVER=22 [[ $(grep -ciE "overlay$" /proc/filesystems) -eq 1 ]] && OLFSVER=23 fi + [[ 1 -eq 1 ]] grep -ciE "overlayfs$" /proc/filesystems ++ grep -ciE 'overlayfs$' /proc/filesystems + [[ 0 -eq 1 ]] grep -ciE "overlay$" /proc/filesystems ++ grep -ciE 'overlay$' /proc/filesystems + [[ 1 -eq 1 ]] + OLFSVER=23 if [[ -z $OLFSVER ]]; then # if neither is hardcoded, see if either module is available modinfo overlayfs &>/dev/null [[ $? -eq 0 ]] && OLFSVER=22 modinfo overlay &>/dev/null [[ $? -eq 0 ]] && OLFSVER=23 fi + [[ -z 23 ]] # get distro name # first try os-release if [[ -f /etc/os-release ]]; then source /etc/os-release if [[ -n "$PRETTY_NAME" ]]; then distro="$PRETTY_NAME" elif [[ -n "$NAME" ]]; then distro="$NAME" fi else # if not os-release try issue if [[ -n $(sed 's| \\.*$||' /etc/issue | head -n 1) ]]; then distro="$(sed 's| \\.*$||' /etc/issue | head -n 1)" else # fuck it distro= fi fi + [[ -f /etc/os-release ]] + source /etc/os-release NAME="Arch Linux" ++ NAME='Arch Linux' ID=arch ++ ID=arch PRETTY_NAME="Arch Linux" ++ PRETTY_NAME='Arch Linux' ANSI_COLOR="0;36" ++ ANSI_COLOR='0;36' HOME_URL="https://www.archlinux.org/" ++ HOME_URL=https://www.archlinux.org/ SUPPORT_URL="https://bbs.archlinux.org/" ++ SUPPORT_URL=https://bbs.archlinux.org/ BUG_REPORT_URL="https://bugs.archlinux.org/" ++ BUG_REPORT_URL=https://bugs.archlinux.org/ + [[ -n Arch Linux ]] + distro='Arch Linux' header() { [[ -z "$distro" ]] && echo -e "${BLD}Profile-sync-daemon v$VERS"${NRM} || echo -e "${BLD}Profile-sync-daemon v$VERS${NRM}${BLD} on $distro"${NRM} echo } dep_check() { # checks for dependencies and that psd.conf is setup correctly command -v rsync >/dev/null 2>&1 || { echo -e " ${BLD}I require rsync but it's not installed. ${RED}Aborting!"${NRM} >&2; exit 1; } command -v modinfo >/dev/null 2>&1 || { echo -e " ${BLD}I require modinfo but it's not installed. ${RED}Aborting!"${NRM} >&2; exit 1; } command -v awk >/dev/null 2>&1 || { echo -e " ${BLD}I require awk but it's not installed. ${RED}Aborting!"${NRM} >&2; exit 1; } if [[ $OLFS -eq 1 ]]; then [[ $OLFSVER -ge 22 ]] || { youare=$(logname) echo -e " ${BLD}Your kernel requires either the ${BLU}overlay${NRM}${BLD} or ${BLU}overlayfs${NRM}${BLD} module to use"${NRM} echo -e " ${BLD}to use psd's in overlay mode. Cannot find either in your kernel so compile it in and"${NRM} echo -e " ${BLD}try again or remove the option from ${BLU}$PSDCONF${NRM}${BLD}. ${RED}Aborting!"${NRM} >&2; exit 1;} fi if [[ -f /etc/psd.conf ]]; then echo -e "${BLD} This version of psd does not support /etc/psd.conf since it runs as your user."${NRM} echo -e "${BLD} Recommend that you remove /etc/psd.conf and run it in systemd's user mode:"${NRM} echo -e "${BLD} systemd --user psd.service"${NRM} exit 1 fi } config_check() { if [[ $OLFS -eq 1 ]]; then # user must have sudo rights to call /usr/bin/mount # and /usr/bin/umount to use overlay mode sudo -kn psd-overlay-helper &>/dev/null [[ $? -ne 0 ]] && FAILCODE=1 if [[ $FAILCODE -ne 0 ]]; then echo -e "${BLD}${RED} ERROR!"${NRM} echo -e " ${BLD}User $user needs sudo access to ${BLU}/usr/bin/mount${NRM}${BLD} and to ${BLU}/usr/bin/umount"${NRM} echo -e " ${BLD}in order to use psd in overlayfs mode."${NRM} echo echo -e " ${BLD}Fix this by adding the following line to ${BLU}/etc/sudoers${NRM}${BLD} to enable this functionality:"${NRM} echo -e " ${BLD}$user ALL=(ALL) NOPASSWD: /usr/bin/psd-overlay-helper"${NRM} exit 1 fi fi for browser in $(echo "$BROWSERS"); do if [[ ! -f "$SHAREDIR/browsers/$browser" ]]; then # user defined an invalid browser echo -e " ${BLD}${RED}$browser${NRM}${BLD} is not a supported browser. Check config file for typos: ${NRM}${BLU}$PSDCONF"${NRM} exit 1 fi done } ungraceful_state_check() { # if the machine was ungracefully shutdown then the backup will be # on the filesystem and the link to tmpfs will be on the filesystem # but the contents will be empty we need to simply remove the link # and rotate the backup into place local browser for browser in $BROWSERS; do load_env_for "$browser" for item in "${DIRArr[@]}"; do DIR="$item" BACKUP="$item-backup" # all is well so continue [[ -e "$DIR/.flagged" ]] && continue NOW=$(date +%Y%m%d_%H%M%S) if [[ -h "$DIR" ]]; then echo "Ungraceful state detected for $DIR so fixing" unlink "$DIR" fi if [[ -d "$BACKUP" ]]; then if [[ $CRRE -eq 1 ]]; then opts="-a --reflink=auto" cp $opts "$BACKUP" "$BACKUP-crashrecovery-$NOW" fi mv "$BACKUP" "$DIR" fi done done } cleanup() { local browser for browser in $BROWSERS; do load_env_for "$browser" for item in "${DIRArr[@]}"; do DIR="$item" CRASHArr=("$item"-backup-crashrecovery*) if ls ${CRASHArr[@]} &> /dev/null; then echo -e ${BLD}"Deleting ${#CRASHArr[@]} crashrecovery dir(s) for profile ${BLU}$DIR"${NRM} for backup in "${CRASHArr[@]}"; do echo -e ${BLD}${RED}" $backup"${NRM} rm -rf "$backup" done unset CRASHArr else echo -e ${BLD}"Found no crashrecovery dirs for: ${BLU}$DIR${NRM}${BLD}"${NRM} fi echo done done } load_env_for() { browser="$1" homedir=$HOME group="$(id -g $user)" ### Arrays # profileArr is transient used to store profile paths parsed from # firefox and aurora unset profileArr # DIRArr is a full path corrected for both relative and absolute paths # reset global variables and arrays unset DIRArr unset PSNAME . "$SHAREDIR/browsers/$browser" } running_check() { # check for browsers running and refuse to start if so # without this cannot guarantee profile integrity local browser for browser in $BROWSERS; do load_env_for "$browser" [[ -z "$PSNAME" ]] && continue if pgrep -u "$user" "$PSNAME" &>/dev/null; then echo "Refusing to start; $browser is running by $user!" exit 1 fi done } suffix_needed() { browser=$1 unset check_suffix . "$SHAREDIR/browsers/$browser" [[ -n "$check_suffix" ]] } dup_check() { # only for firefox, icecat, seamonkey, palemoon, and aurora # the LAST directory in the profile MUST be unique # make sure there are no duplicates in ~/.mozilla//profiles.ini local browser for browser in $BROWSERS; do load_env_for "$browser" if suffix_needed "$browser"; then # nothing to check [[ -z "${DIRArr[@]}" ]] && continue # browser is on system so check profiles # # check that the LAST DIRECTORY in the full path is unique unique_count=$(echo ${DIRArr[@]##*/} | sed 's/ /\n/g' | sort -u | wc -l) # no problems so do nothing [[ ${#DIRArr[@]##*/} -eq $unique_count ]] && continue echo -e " ${RED}Error: ${NRM}${BLD}dup profile for ${GRN}$browser${NRM}${BLD} detected. See psd manpage, correct, and try again."${NRM} # clip of the 'heftig-' to give correct path [[ "$browser" = "heftig-aurora" ]] && browser="${browser##*-}" profile_ini="$homedir/.mozilla/$browser/profiles.ini" [[ "$browser" = "palemoon" ]] && profile_ini="$homedir/.moonchild productions/pale moon/profiles.ini" echo -e " ${BLD}Must have unique last directories in ${BLU}${profile_ini}${NRM}${BLD} to use psd."${NRM} exit 1 fi done } kill_browsers() { # check for browsers running and kill them to safely sync/unsync # without this cannot guarantee profile integrity local browser for browser in $BROWSERS; do load_env_for "$browser" local x=1 while [[ $x -le 60 ]]; do [[ -n "$PSNAME" ]] || break pgrep -u "$user" "$PSNAME" &>/dev/null || break if [[ $x -le 5 ]]; then pkill -SIGTERM -u "$user" "$PSNAME" else pkill -SIGKILL -u "$user" "$PSNAME" fi x=$(( $x + 1 )) sleep .05 done done } do_sync_for() { browser=$1 load_env_for "$browser" for item in "${DIRArr[@]}"; do DIR="$item" BACKUP="$item-backup" suffix= if suffix_needed "$browser"; then suffix="-${item##*/}" fi TMP="$VOLATILE/$user-$browser$suffix" TMPRW="$VOLATILE/$user-$browser${suffix}-rw" TMPWK="$VOLATILE/.$user-$browser${suffix}" local REPORT # make tmpfs container if [[ -d "$DIR" ]]; then # retain permissions on sync target PREFIXP=$(stat -c %a "$DIR") [[ -r "$TMP" ]] || install -dm$PREFIXP --owner=$user --group=$group "$TMP" if [[ $OLFS -eq 1 ]]; then if [[ $OLFSVER -eq 23 ]]; then [[ -r "$TMPRW" ]] || install -dm$PREFIXP --owner=$user --group=$group "$TMPRW" [[ -r "$TMPWK" ]] || install -dm$PREFIXP --owner=$user --group=$group "$TMPWK" elif [[ $OLFSVER -eq 22 ]]; then [[ -r "$TMPRW" ]] || install -dm$PREFIXP --owner=$user --group=$group "$TMPRW" fi fi # backup target and link to tmpfs container if [[ $(readlink "$DIR") != "$TMP" ]]; then mv "$DIR" "$BACKUP" # refuse to start browser while initial sync ln -s /dev/null "$DIR" fi # sync the tmpfs targets to the disc if [[ -e "$DIR"/.flagged ]]; then REPORT="resync" rsync -aX --delete-after --inplace --no-whole-file --exclude .flagged "$DIR/" "$BACKUP/" else # initial sync REPORT="sync" if [[ $OLFS -eq 1 ]]; then sudo psd-overlay-helper -v "$OLFSVER" -l "$BACKUP" -u "$TMPRW" -w "$TMPWK" -d "$TMP" mountup if [[ $? -ne 0 ]]; then echo -e "Error in trying to mount $TMP - this should not happen!" exit 1 fi else # keep user from launching browser while rsync is active rsync -aX --inplace --no-whole-file "$BACKUP/" "$TMP" fi # now browser can start [[ $(readlink "$DIR") = "/dev/null" ]] && unlink "$DIR" ln -s "$TMP" "$DIR" chown -h $user:$group "$DIR" touch "$DIR/.flagged" fi echo -e "${BLD}$browser $REPORT successful"${NRM} else if [[ ! -d "$homedir" ]] ; then echo -e "${RED}$DIR does not exist! Is /home unmounted?${NRM}" >&2 exit 1 elif [[ -d "$BACKUP" ]] ; then echo -e "${RED}$DIR does not exist or is a broken symlink! Is $VOLATILE unmounted?${NRM}" >&2 exit 1 fi fi done } do_sync() { touch "$PID_FILE" # make a snapshot of psd.conf and redefine its location to this snapshot # while psd is running to keep any edits made to the "live" psd.conf from # potentially orphaning the snapshot copies thus preserving the data [[ -f "$PSDCONFDIR/.psd.conf" ]] || cp "$PSDCONF" "$PSDCONFDIR/.psd.conf" local browser for browser in $BROWSERS; do do_sync_for $browser & done systemd-notify --ready --status="Waiting sync for ${browser}..." wait } do_unsync() { rm -f "$PID_FILE" "$PSDCONFDIR/.psd.conf" local browser for browser in $BROWSERS; do load_env_for "$browser" for item in "${DIRArr[@]}"; do DIR="$item" BACKUP="$item-backup" suffix= if suffix_needed "$browser"; then suffix="-${item##*/}" fi TMP="$VOLATILE/$user-$browser$suffix" TMPRW="$VOLATILE/$user-$browser${suffix}-rw" TMPWK="$VOLATILE/.$user-$browser${suffix}" # check if user has browser profile if [[ -h "$DIR" ]]; then unlink "$DIR" # this assumes that the backup is always updated so # be sure to invoke a sync before an unsync # # restore original dirtree [[ -d "$BACKUP" ]] && mv "$BACKUP" "$DIR" if [[ $OLFS -eq 1 ]] && mountpoint -q "$TMP"; then sudo psd-overlay-helper -d "$TMP" mountdown && rm -rf "$TMP" "$TMPRW" "$TMPWK" fi [[ -d "$TMP" ]] && rm -rf "$TMP" echo -e "${BLD}$browser unsync successful"${NRM} else if [[ ! -d "$homedir" ]] ; then echo -e "${RED}$DIR does not exist! Is /home unmounted?${NRM}" >&2 exit 1 fi fi done done } parse() { if [[ -f /usr/lib/systemd/user/psd.service ]]; then # running systemd psd_state=$(systemctl --user is-active psd) resync_state=$(systemctl --user is-active psd-resync.timer) [[ "$psd_state" = "active" ]] && psd_color="${GRN}" || psd_color="${RED}" [[ "$resync_state" = "active" ]] && resync_color="${GRN}" || resync_color="${RED}" echo -e " ${BLD}Systemd service is currently ${psd_color}$psd_state${NRM}${BLD}."${NRM} echo -e " ${BLD}Systemd resync-timer is currently ${resync_color}$resync_state${NRM}${BLD}."${NRM} else # using other init system + cron job for resync [[ "$resync_state" = "present" ]] && resync_color=${GRN} || resync_color=${RED} echo -e " ${BLD}Daemon pid file is $([[ -f $PID_FILE ]] && echo -e ${GRN}present${NRM}${BLD} || echo -e ${RED}not present${NRM}${BLD})."${NRM} echo -e " ${BLD}Resync cronjob is ${resync_color}${resync_state}${NRM}${BLD}."${NRM} fi [[ $OLFS -eq 1 ]] && echo -e "${BLD} Overlayfs v$OLFSVER is currently ${GRN}active${NRM}${BLD}."${NRM} || echo -e "${BLD} Overlayfs technology is currently ${RED}inactive${NRM}${BLD}."${NRM} echo echo -e "${BLD}Psd will manage the following per ${BLU}${PSDCONF}${NRM}${BLD}:"${NRM} echo local browser for browser in $BROWSERS; do load_env_for "$browser" for item in "${DIRArr[@]}"; do DIR="$item" BACKUP="$item-backup" suffix= if suffix_needed "$browser"; then suffix="-${item##*/}" fi TMPRW="$VOLATILE/$user-$browser${suffix}-rw" if [[ -d "$DIR" ]]; then # first count up any crashrecovery dirs ls "$item"-backup-crashrecovery* &>/dev/null [[ $? -eq 0 ]] && CRASHArr=("$item"-backup-crashrecovery*) # get permissions on profile dir and be smart about it since symlinks are all 777 [[ -f $PID_FILE ]] && TRUEP=$(stat -c %a "$BACKUP") || TRUEP=$(stat -c %a "$DIR") # since $XDG_RUNTIME_DIR is 700 by default so pass on by if [[ "$VOLATILE" = "$XDG_RUNTIME_DIR" ]]; then warn= else # using something other than $XDG_RUNTIME_DIR so check for privacy [[ $TRUEP -ne 700 ]] && warn=1 fi # profile dir size psize=$(du -Lh --max-depth=0 "$DIR" 2>/dev/null | awk '{ print $1 }') echo -en " ${BLD}browser/psname:" echo -e "$(tput cr)$(tput cuf 17) $browser/$PSNAME"${NRM} echo -en " ${BLD}owner/group id:" echo -e "$(tput cr)$(tput cuf 17) $user/$group"${NRM} echo -en " ${BLD}sync target:" echo -e "$(tput cr)$(tput cuf 17) ${BLU}$DIR"${NRM} if [[ $warn -eq 1 ]]; then echo -e "$(tput cr)$(tput cuf 17) ${RED} Permissions are $TRUEP on this profile."${NRM} echo -e "$(tput cr)$(tput cuf 17) ${RED} Recommend a setting of 700 for increased privacy!"${NRM} warn= fi echo -en " ${BLD}tmpfs dir:" echo -e "$(tput cr)$(tput cuf 17) ${GRN}$VOLATILE/$user-$browser$suffix"${NRM} echo -en " ${BLD}profile size:" echo -e "$(tput cr)$(tput cuf 17) $psize"${NRM} if [[ $OLFS -eq 1 ]]; then rwsize=$(du -Lh --max-depth=0 "$TMPRW" 2>/dev/null | awk '{ print $1 }') echo -en " ${BLD}overlayfs size:" echo -e "$(tput cr)$(tput cuf 17) $rwsize"${NRM} fi echo -en " ${BLD}recovery dirs:" if [[ "${#CRASHArr[@]}" -eq 0 ]]; then echo -e "$(tput cr)$(tput cuf 17) none"${NRM} else echo -e "$(tput cr)$(tput cuf 17) ${RED}${#CRASHArr[@]}${NRM}${BLD} <- delete with the c option"${NRM} for backup in "${CRASHArr[@]}"; do psize=$(du -Lh --max-depth=0 "$backup" 2>/dev/null | awk '{ print $1 }') echo -en " ${BLD} dir path/size:" echo -e "$(tput cr)$(tput cuf 17) ${BLU}$backup ${NRM}${BLD}($psize)"${NRM} done fi unset CRASHArr echo fi done done } case "$1" in p|P|Parse|parse|Preview|preview|debug) dep_check config_check dup_check ungraceful_state_check header parse ;; c|C|clean|Clean) dep_check config_check dup_check header cleanup ;; sync|resync) if [[ -f $PID_FILE ]]; then do_sync else dep_check config_check dup_check running_check ungraceful_state_check do_sync fi ;; unsync) if [[ -f $PID_FILE ]]; then do_sync kill_browsers do_unsync fi ;; *) header echo -e " ${BLD}$0 ${NRM}${GRN}[option]${NRM}" echo -e " ${BLD} ${NRM}${GRN}preview${NRM}${BLD} Parse config file (${NRM}${BLU}${PSDCONF}${NRM}${BLD}) to see which profiles will be managed."${NRM} echo -e " ${BLD} ${NRM}${GRN}clean${NRM}${BLD} Clean (delete without prompting) ALL crashrecovery dirs for all profiles."${NRM} echo echo -e " ${BLD}It is ${RED}HIGHLY DISCOURAGED${NRM}${BLD} to directly call $0 to sync, resync, or to unsync."${NRM} echo if [[ -f /usr/lib/systemd/user/psd.service ]]; then echo -e " ${BLD}Instead, use systemd to start/stop profile-sync-daemon."${NRM} echo echo -e " ${BLD}systemctl --user ${NRM}${GRN}[option]${NRM}${BLD} psd psd-resync"${NRM} echo -e " ${BLD} ${NRM}${GRN}start${NRM}${BLD} Turn on daemon; make symlinks and actively manage targets in tmpfs."${NRM} echo -e " ${BLD} ${NRM}${GRN}stop${NRM}${BLD} Turn off daemon; remove symlinks and rotate tmpfs data back to disc."${NRM} echo -e " ${BLD} ${NRM}${GRN}enable${NRM}${BLD} Autostart daemon when system comes up."${NRM} echo -e " ${BLD} ${NRM}${GRN}disable${NRM}${BLD} Remove daemon from the list of autostart daemons."${NRM} elif [[ -f /etc/init.d/psd ]]; then echo -e " ${BLD}Instead, use the init system to start/stop profile-sync-daemon."${NRM} echo echo -e " ${BLD}sudo service psd ${NRM}${GRN}[option]${NRM}${BLD} or /etc/init.d/psd ${NRM}${GRN}[option]"${NRM} echo -e " ${BLD} ${NRM}${GRN}start${NRM}${BLD} Turn on daemon; make symlinks and actively manage targets in tmpfs."${NRM} echo -e " ${BLD} ${NRM}${GRN}stop${NRM}${BLD} Turn off daemon; remove symlinks and rotate tmpfs data back to disc."${NRM} fi ;; esac + case "$1" in + dep_check + command -v rsync + command -v modinfo + command -v awk + [[ 1 -eq 1 ]] + [[ 23 -ge 22 ]] + [[ -f /etc/psd.conf ]] + config_check + [[ 1 -eq 1 ]] + sudo -kn psd-overlay-helper + [[ 0 -ne 0 ]] + [[ '' -ne 0 ]] echo "$BROWSERS" ++ echo firefox + for browser in '$(echo "$BROWSERS")' + [[ ! -f /usr/share/psd/browsers/firefox ]] + dup_check + local browser + for browser in '$BROWSERS' + load_env_for firefox + browser=firefox + homedir=/home/lenny id -g $user ++ id -g lenny + group=100 + unset profileArr + unset DIRArr + unset PSNAME + . /usr/share/psd/browsers/firefox if [[ -d $homedir/.mozilla/firefox ]]; then profileArr=( $(grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//') ) index=0 PSNAME="$browser" for profileItem in ${profileArr[@]}; do if [[ $(echo $profileItem | cut -c1) = "/" ]]; then # path is not relative DIRArr[index]="$profileItem" else # we need to append the default path to give a # fully qualified path DIRArr[index]="$homedir/.mozilla/firefox/$profileItem" fi index=$index+1 done fi ++ [[ -d /home/lenny/.mozilla/firefox ]] ++ profileArr=($(grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//')) grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//' +++ grep '[P,p]ath=' /home/lenny/.mozilla/firefox/profiles.ini +++ sed 's/[P,p]ath=//' ++ index=0 ++ PSNAME=firefox ++ for profileItem in '${profileArr[@]}' echo $profileItem | cut -c1 +++ echo $'Profiles/8p0y5880.default\r' +++ cut -c1 ++ [[ P = \/ ]] ++ DIRArr[index]=$'/home/lenny/.mozilla/firefox/Profiles/8p0y5880.default\r' ++ index=0+1 check_suffix=1 ++ check_suffix=1 + suffix_needed firefox + browser=firefox + unset check_suffix + . /usr/share/psd/browsers/firefox if [[ -d $homedir/.mozilla/firefox ]]; then profileArr=( $(grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//') ) index=0 PSNAME="$browser" for profileItem in ${profileArr[@]}; do if [[ $(echo $profileItem | cut -c1) = "/" ]]; then # path is not relative DIRArr[index]="$profileItem" else # we need to append the default path to give a # fully qualified path DIRArr[index]="$homedir/.mozilla/firefox/$profileItem" fi index=$index+1 done fi ++ [[ -d /home/lenny/.mozilla/firefox ]] ++ profileArr=($(grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//')) grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//' +++ sed 's/[P,p]ath=//' +++ grep '[P,p]ath=' /home/lenny/.mozilla/firefox/profiles.ini ++ index=0 ++ PSNAME=firefox ++ for profileItem in '${profileArr[@]}' echo $profileItem | cut -c1 +++ cut -c1 +++ echo $'Profiles/8p0y5880.default\r' ++ [[ P = \/ ]] ++ DIRArr[index]=$'/home/lenny/.mozilla/firefox/Profiles/8p0y5880.default\r' ++ index=0+1 check_suffix=1 ++ check_suffix=1 + [[ -n 1 ]] ]][ -z /home/lenny/.mozilla/firefox/Profiles/8p0y5880.default echo ${DIRArr[@]##*/} | sed 's/ /\n/g' | sort -u | wc -l ++ echo $'8p0y5880.default\r' ++ sort -u ++ wc -l ++ sed 's/ /\n/g' + unique_count=1 + [[ 1 -eq 1 ]] + continue + ungraceful_state_check + local browser + for browser in '$BROWSERS' + load_env_for firefox + browser=firefox + homedir=/home/lenny id -g $user ++ id -g lenny + group=100 + unset profileArr + unset DIRArr + unset PSNAME + . /usr/share/psd/browsers/firefox if [[ -d $homedir/.mozilla/firefox ]]; then profileArr=( $(grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//') ) index=0 PSNAME="$browser" for profileItem in ${profileArr[@]}; do if [[ $(echo $profileItem | cut -c1) = "/" ]]; then # path is not relative DIRArr[index]="$profileItem" else # we need to append the default path to give a # fully qualified path DIRArr[index]="$homedir/.mozilla/firefox/$profileItem" fi index=$index+1 done fi ++ [[ -d /home/lenny/.mozilla/firefox ]] ++ profileArr=($(grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//')) grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//' +++ grep '[P,p]ath=' /home/lenny/.mozilla/firefox/profiles.ini +++ sed 's/[P,p]ath=//' ++ index=0 ++ PSNAME=firefox ++ for profileItem in '${profileArr[@]}' echo $profileItem | cut -c1 +++ echo $'Profiles/8p0y5880.default\r' +++ cut -c1 ++ [[ P = \/ ]] ++ DIRArr[index]=$'/home/lenny/.mozilla/firefox/Profiles/8p0y5880.default\r' ++ index=0+1 check_suffix=1 ++ check_suffix=1 + for item in '"${DIRArr[@]}"' + DIR=$'/home/lenny/.mozilla/firefox/Profiles/8p0y5880.default\r' + BACKUP=$'/home/lenny/.mozilla/firefox/Profiles/8p0y5880.default\r-backup' /.flagged ]]e/lenny/.mozilla/firefox/Profiles/8p0y5880.default date +%Y%m%d_%H%M%S ++ date +%Y%m%d_%H%M%S + NOW=20151018_224959 ]][ -h /home/lenny/.mozilla/firefox/Profiles/8p0y5880.default -backup ]]ome/lenny/.mozilla/firefox/Profiles/8p0y5880.default + header + [[ -z Arch Linux ]] + echo -e '\e[01mProfile-sync-daemon v6.12\e[00m\e[01m on Arch Linux\e[00m' Profile-sync-daemon v6.12 on Arch Linux + echo + parse + [[ -f /usr/lib/systemd/user/psd.service ]] systemctl --user is-active psd ++ systemctl --user is-active psd + psd_state=active systemctl --user is-active psd-resync.timer ++ systemctl --user is-active psd-resync.timer + resync_state=active + [[ active = \a\c\t\i\v\e ]] + psd_color='\e[01;32m' + [[ active = \a\c\t\i\v\e ]] + resync_color='\e[01;32m' + echo -e ' \e[01mSystemd service is currently \e[01;32mactive\e[00m\e[01m.\e[00m' Systemd service is currently active. + echo -e ' \e[01mSystemd resync-timer is currently \e[01;32mactive\e[00m\e[01m.\e[00m' Systemd resync-timer is currently active. + [[ 1 -eq 1 ]] + echo -e '\e[01m Overlayfs v23 is currently \e[01;32mactive\e[00m\e[01m.\e[00m' Overlayfs v23 is currently active. + echo + echo -e '\e[01mPsd will manage the following per \e[01;34m/home/lenny/.config/psd/psd.conf\e[00m\e[01m:\e[00m' Psd will manage the following per /home/lenny/.config/psd/psd.conf: + echo + local browser + for browser in '$BROWSERS' + load_env_for firefox + browser=firefox + homedir=/home/lenny id -g $user ++ id -g lenny + group=100 + unset profileArr + unset DIRArr + unset PSNAME + . /usr/share/psd/browsers/firefox if [[ -d $homedir/.mozilla/firefox ]]; then profileArr=( $(grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//') ) index=0 PSNAME="$browser" for profileItem in ${profileArr[@]}; do if [[ $(echo $profileItem | cut -c1) = "/" ]]; then # path is not relative DIRArr[index]="$profileItem" else # we need to append the default path to give a # fully qualified path DIRArr[index]="$homedir/.mozilla/firefox/$profileItem" fi index=$index+1 done fi ++ [[ -d /home/lenny/.mozilla/firefox ]] ++ profileArr=($(grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//')) grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//' +++ grep '[P,p]ath=' /home/lenny/.mozilla/firefox/profiles.ini +++ sed 's/[P,p]ath=//' ++ index=0 ++ PSNAME=firefox ++ for profileItem in '${profileArr[@]}' echo $profileItem | cut -c1 +++ echo $'Profiles/8p0y5880.default\r' +++ cut -c1 ++ [[ P = \/ ]] ++ DIRArr[index]=$'/home/lenny/.mozilla/firefox/Profiles/8p0y5880.default\r' ++ index=0+1 check_suffix=1 ++ check_suffix=1 + for item in '"${DIRArr[@]}"' + DIR=$'/home/lenny/.mozilla/firefox/Profiles/8p0y5880.default\r' + BACKUP=$'/home/lenny/.mozilla/firefox/Profiles/8p0y5880.default\r-backup' + suffix= + suffix_needed firefox + browser=firefox + unset check_suffix + . /usr/share/psd/browsers/firefox if [[ -d $homedir/.mozilla/firefox ]]; then profileArr=( $(grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//') ) index=0 PSNAME="$browser" for profileItem in ${profileArr[@]}; do if [[ $(echo $profileItem | cut -c1) = "/" ]]; then # path is not relative DIRArr[index]="$profileItem" else # we need to append the default path to give a # fully qualified path DIRArr[index]="$homedir/.mozilla/firefox/$profileItem" fi index=$index+1 done fi ++ [[ -d /home/lenny/.mozilla/firefox ]] ++ profileArr=($(grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//')) grep '[P,p]'ath= $homedir/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//' +++ grep '[P,p]ath=' /home/lenny/.mozilla/firefox/profiles.ini +++ sed 's/[P,p]ath=//' ++ index=0 ++ PSNAME=firefox ++ for profileItem in '${profileArr[@]}' echo $profileItem | cut -c1 +++ echo $'Profiles/8p0y5880.default\r' +++ cut -c1 ++ [[ P = \/ ]] ++ DIRArr[index]=$'/home/lenny/.mozilla/firefox/Profiles/8p0y5880.default\r' ++ index=0+1 check_suffix=1 ++ check_suffix=1 + [[ -n 1 ]] + suffix=$'-8p0y5880.default\r' + TMPRW=$'/run/user/1000/lenny-firefox-8p0y5880.default\r-rw' ]][ -d /home/lenny/.mozilla/firefox/Profiles/8p0y5880.default exit 0 + exit 0