jaromail

a commandline tool to easily and privately handle your e-mail
git clone git://parazyd.org/jaromail.git
Log | Files | Refs | Submodules | README

locking (3740B)


      1 #!/usr/bin/env zsh
      2 #
      3 # Jaro Mail, your humble and faithful electronic postman
      4 #
      5 # a tool to easily and privately handle your e-mail communication
      6 #
      7 # Copyleft (C) 2010-2015 Denis Roio <jaromil@dyne.org>
      8 #
      9 # This source  code is free  software; you can redistribute  it and/or
     10 # modify it under the terms of  the GNU Public License as published by
     11 # the Free  Software Foundation; either  version 3 of the  License, or
     12 # (at your option) any later version.
     13 #
     14 # This source code is distributed in  the hope that it will be useful,
     15 # but  WITHOUT ANY  WARRANTY;  without even  the  implied warranty  of
     16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     17 # Please refer to the GNU Public License for more details.
     18 #
     19 # You should have received a copy of the GNU Public License along with
     20 # this source code; if not, write to:
     21 # Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     22 
     23 
     24 lock() {
     25     fn "lock $*"
     26     _file=$1
     27     # can't use ckreq as that returns error on file empty
     28     [[ -r "$_file" ]] || {
     29         error "cannot unlock, file not existing: $_file"
     30         return 1 }
     31 
     32     if helper.isfound dotlock; then
     33         dotlock=`command -v dotlock`
     34     else
     35         dotlock="${WORKDIR}/bin/dotlock"
     36     fi
     37 
     38     ${dotlock} "$_file"
     39     res=$?
     40     case $res in
     41 	1) error "Cannot lock non existing file: $_file"
     42 	    return 1 ;;
     43 	3) error "Locked file in use: $_file"
     44 
     45 	    pidcheck "$1"
     46 	    return 3 ;;
     47 
     48 	5) error "Lock is impossible on: $_file"
     49 	    return 5 ;;
     50 	# success
     51 	0) print "$$" > "$_file.pid"
     52 	    return 0 ;;
     53 
     54 	*) error "Unknown error locking: $res"
     55 	    return 1 ;;
     56     esac
     57 }
     58 
     59 newlock() { # lock file, create if not existing
     60     fn "newlock $*"
     61     _file="$1"
     62 
     63     touch "$_file"
     64     chmod 600 "$_file"
     65     lock "$_file"
     66 }
     67 
     68 pidcheck() { # check if lock belongs to us
     69     fn "pidcheck $@"
     70     _pid="$1"
     71     req=(_pid)
     72     ckreq || return 1
     73 
     74     if [ -r "${_pid}.pid" ]; then
     75         
     76 	lockpid="`cat ${_pid}.pid`"
     77 	func "pidcheck: $lockpid"
     78 	if [[ "$$" = "$lockpid" ]]; then
     79 	    func "${_pid} lock belongs to us"
     80 	else
     81             
     82 	    error "Unlock attempt by multiple processes on `basename $_pid`"
     83 	    [[ "$FORCE" = "1" ]] || {
     84                 _prun=1
     85 		while [ "$_prun" = "1" ]; do
     86                     [[ $global_quit = 1 ]] && { break }
     87 		    for p in `ps ax | awk '{ print $_pid }'`; do
     88 			{ test "$p" = "$lockpid" } && { break }
     89 		    done
     90 		    if [ "$p" = "$lockpid" ]; then
     91 			act "Owner (${lockpid}) still running, waiting release..."
     92 			sleep 1; 
     93                         continue
     94 		    else
     95 			act "Owner (${lockpid}) not running, taking over the lock"
     96 			rm -f "${_pid}.pid"; print "$$" > "${_pid}.pid"
     97 			_prun=0
     98 		    fi
     99 		done
    100 	    }
    101 	    act "left behind by $lockpid - we ($$) will take over"
    102             
    103 	fi
    104         
    105     else # pid file doesn't exists
    106 	func "no pid file found for: $_pid"
    107 	func "we will take it over"
    108 	print "$$" > "${_pid}.pid"
    109     fi
    110     return 0
    111 }
    112 
    113 unlock() {
    114     fn "unlock $*"
    115     _file="$1"
    116     # can't use ckreq as that returns error on file empty
    117     [[ -r "$_file" ]] || {
    118         error "cannot unlock, file not existing: $_file"
    119         return 1 }
    120 
    121     pidcheck "$_file"
    122     [[ $? = 0 ]] || { return 1 }
    123     
    124     ${WORKDIR}/bin/dotlock -u "$_file"
    125     [[ $? = 0 ]] || {
    126 	    rm -f "${_file}.lock"
    127 	    [[ $? = 0 ]] || { error "Unable to unlock: $_file"; return 1 }
    128     }
    129     [[ -r "${_file}.pid" ]] && { rm -f "${_file}.pid" }
    130     return 0
    131 }
    132 
    133 unlink() { # delete a file that we are locking
    134     fn "unlink $*"
    135     _file="$1"
    136     # can't use ckreq as that returns error on file empty
    137     [[ -r "$_file" ]] || {
    138         error "cannot unlock, file not existing: $_file"
    139         return 1 }
    140 
    141     unlock "$_file"
    142     ${=rm} "$_file"
    143     func "$_file removed"
    144 }