#!/bin/bash ffoo import inigrep ffoo import pretty ffoo import sync __zleep_user_part() { saturnin iam undocking slock & } __zleep_try_umount() { local mp=$1 mountpoint -q $mp || return 0 umount $mp || return 1 mount | grep $mp && return 1 return 0 } __zleep_try_umount_all() { local mp for mp in $(inigrep -p iam.mounting.point); do __zleep_try_umount $mp || return 1 done return 0 } __zleep_sudo_part() { wait_until -d 5 -t 30 __zleep_try_umount_all || die "unable to unmount drives" pm-suspend } __zleep_sudo_part_started() { # i.e. password prompt went ok test -e $ZLEEP_ON_ROOT rv=$? debug -v rv return $rv } __zleep_user_part_done() { ! test -e $ZLEEP_ON_USER rv=$? debug -v rv return $rv } __zleep_min_path() { echo -n $(sudo env | grep ^PATH) echo -n : echo -n $(dirname $(which ffoom)) echo -n : echo -n $(dirname $(which saturnin)) } zleep() { # # Put the host on sleep # # We need to # # 1. authenticate # 2. start user's part in the background -- mainly slock # 3. start root's part -- put system on sleep (unmount, suspend) # # This is solved by forking with sudo, and waiting for user part to indicate # it has finished. That way, we can ensure that suspend happens *after* the # screen has been locked, and at the same time we leave authentication part # on sudo. # if test -z "$ZLEEP_ON_USER"; ## we are parent (running as normal user) then ZLEEP_ON_USER=$(mktemp) ZLEEP_ON_ROOT=$(mktemp -u) SUDO_PATH=$(__zleep_min_path) # needed while bins are still under local debug -v ZLEEP_ON_USER ZLEEP_ON_ROOT SUDO_PATH sudo env \ ZLEEP_ON_ROOT=$ZLEEP_ON_ROOT \ ZLEEP_ON_USER=$ZLEEP_ON_USER \ PATH=$SUDO_PATH \ saturnin iam zleeping & wait_until -t 60 __zleep_sudo_part_started # i.e. password prompt done __zleep_user_part rm -f $ZLEEP_ON_USER else ## we are child (running as root) touch $ZLEEP_ON_ROOT test $(id -u) -eq 0 || die "must be root" wait_until __zleep_user_part_done || die "timeout waiting for parent" __zleep_sudo_part rm -f $ZLEEP_ON_ROOT return $? fi }