lenny@crapbox ~ $ bash -x -v psd p#!/bin/bash## Profile-sync-daemon by graysky <graysky AT archlinux DOT us># 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.12user=$(id -un)id -un++ id -un+ user=lennyHOME="$(getent passwd $user | cut -d: -f6)"getent passwd $user | cut -d: -f6++ getent passwd lenny++ cut -d: -f6+ HOME=/home/lennyXDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"+ XDG_CONFIG_HOME=/home/lenny/.configPSDCONFDIR="$XDG_CONFIG_HOME/psd"+ PSDCONFDIR=/home/lenny/.config/psdPSDCONF="$PSDCONFDIR/psd.conf"+ PSDCONF=/home/lenny/.config/psd/psd.confSHAREDIR="/usr/share/psd"+ SHAREDIR=/usr/share/psdif [[ ! -d "$SHAREDIR" ]]; then echo -e " Missing ${BLU}$SHAREDIR${NRM}${BLD} - reinstall the package to use profile-sync-daemon." exit 1fi+ [[ ! -d /usr/share/psd ]]# Setup check for config fileif [[ -f "$PSDCONF" ]]; then . $PSDCONFelif [[ -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" ]] && . $PSDCONFelse 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 fifi+ [[ -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 fifi+ [[ -f '' ]]# all supported browsersALL_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 valueif [[ -n "$XDG_RUNTIME_DIR" ]]; then VOLATILE="$XDG_RUNTIME_DIR"else [[ -z "$VOLATILE" ]] && VOLATILE="/tmp"fi+ [[ -n /run/user/1000 ]]+ VOLATILE=/run/user/1000PID_FILE="$VOLATILE/psd.pid"+ PID_FILE=/run/user/1000/psd.pid# simple function to determine user intent rather than using a null valuecase "${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=yescase "${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 modinfoif [[ $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=23fi+ [[ 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=23if [[ -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=23fi+ [[ -z 23 ]]# get distro name# first try os-releaseif [[ -f /etc/os-release ]]; then source /etc/os-release if [[ -n "$PRETTY_NAME" ]]; then distro="$PRETTY_NAME" elif [[ -n "$NAME" ]]; then distro="$NAME" fielse # 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= fifi+ [[ -f /etc/os-release ]]+ source /etc/os-releaseNAME="Arch Linux"++ NAME='Arch Linux'ID=arch++ ID=archPRETTY_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 <action> 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/<browser>/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/lennyid -g $user++ id -g lenny+ group=100+ unset profileArr+ unset DIRArr+ unset PSNAME+ . /usr/share/psd/browsers/firefoxif [[ -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 donefi++ [[ -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+1check_suffix=1++ check_suffix=1+ suffix_needed firefox+ browser=firefox+ unset check_suffix+ . /usr/share/psd/browsers/firefoxif [[ -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 donefi++ [[ -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+1check_suffix=1++ check_suffix=1+ [[ -n 1 ]] ]][ -z /home/lenny/.mozilla/firefox/Profiles/8p0y5880.defaultecho ${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/lennyid -g $user++ id -g lenny+ group=100+ unset profileArr+ unset DIRArr+ unset PSNAME+ . /usr/share/psd/browsers/firefoxif [[ -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 donefi++ [[ -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+1check_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.defaultdate +%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=activesystemctl --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/lennyid -g $user++ id -g lenny+ group=100+ unset profileArr+ unset DIRArr+ unset PSNAME+ . /usr/share/psd/browsers/firefoxif [[ -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 donefi++ [[ -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+1check_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/firefoxif [[ -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 donefi++ [[ -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+1check_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.defaultexit 0+ exit 0