
# This code creates the ICEM CFD Manager.
#
# Copyright (c) 1993 - 1996 Pacific Marketing and Consulting, Inc,
#       and ICEM Systems, GmbH.  All rights reserved.
# Author:  Wayne A. Christopher, wayne@icemcfd.com

proc get_config_lock {config} {
    global config_lock env gui_name
    
    if {[info exists env(USER)] && ($env(USER) != "")} {
	set user_name $env(USER)
    } else {
	set user_name [cmd_whoami]
    }
    set host_name [cmd_uname_n]
    
    if [info exists config_lock] release_config_lock
    
    if ![file writable mulcad/$config] {
	mess "The directory mulcad/$config is not writable by you, so no\
		locking will be done.  You will probably encounter other\
		problems also unless you fix the permissions.\n" red
	return 1
    }
    
    set config_lock mulcad/$config/config_lock
    
    if [file exists $config_lock] {
	# not if [catch {open $config_lock "WRONLY CREAT EXCL TRUNC"} fp]
	# The lock file already exists.
	if [catch {open $config_lock r} fp] {
	    infomsg "The advisory $gui_name(conf) lock could not be opened --\
		it is probably unreadable by this user."
	    set pid unknown
	    set user unknown
	    set host unknown
	} else {
	    
	    set stuff [read $fp]
	    close $fp
	    
	    set pid [lindex $stuff 0]
	    set user [lindex $stuff 1]
	    set host [lindex $stuff 2]
	}
	set check 1
	if {($host_name == $host) && ($pid != "unknown") && \
		![process_exists $pid]} {
	    infomsg "Warning: lock file found (pid $pid, user $user,\
		    host $host), but icemcfd is no longer running. \
		    It probably terminated abnormally.  Overriding lock."
	    set check 0
	}
	
	if $check {
	    set message \
		"The $gui_name(conf) \"$config\" has been locked by user\
		\"$user\", running icemcfd with process ID $pid on machine\
		 \"$host\".  You can:\n\
		 1) Override the lock,\n\
		 2) Open the $gui_name(conf) without overriding the lock, or\n\
		 3) Cancel the Open $gui_name(Conf) operation.\n\
		 If you pick 1 or 2 you should be careful not to write the\
		 same data at the same time in more than one session."
	    
	    switch [tk_dialog .lock "Lock problem" $message "" 0 \
		    Cancel Open Override] {
		0 {
		    infomsg "Warning: not opening $gui_name(conf)."
		    return 0
		}
		1 {
		    infomsg "$gui_name(Conf) opened without locking."
		    return 1
		}
		2 { # Just fall through.
		}
	    }
	}
	cmd_rm $config_lock
	if [catch {open $config_lock w} fp] {
	    error "Can't create $gui_name(conf) lock -- the mulcad/$config\
		    directory is probably not writable by you."
	}
    } else {
	set fp [open $config_lock w]
    }
    infomsg "Acquiring lock on $gui_name(conf) \"$config\""
    puts $fp "[pid] $user_name $host_name"
    close $fp
    return 1
}

proc process_exists {pid} {
    global is_win
    
    if $is_win {
	# who knows
	return 1
    } else {
	return [expr ![catch {exec [get_path ps] -p $pid}]]
    }
}

proc release_config_lock {} {
    global config_lock gui_name
    
    if ![info exists config_lock] {
	# errormsg "Error: can't release lock: no lock held."
	return
    }
    
    set dirs [split $config_lock /]
    set name [lindex $dirs [expr {[llength $dirs] - 2}]]
    
    if ![file exists $config_lock] {
	errormsg "Error: can't release lock for $gui_name(conf) \"$name\" --\
		the lock file is missing."
	return
    }
    
    set fp [open $config_lock r]
    set stuff [read $fp]
    close $fp
    
    if {[pid] != [lindex $stuff 0]} {
	infomsg "Error: Can't release lock for $gui_name(conf) \"$name\" --\
		the lock has been overridden by another process:\
		user [lindex $stuff 1], process ID [lindex $stuff 0],\
		on machine \"[lindex $stuff 2]\"."
	return
    }
    
    infomsg "Releasing lock on $gui_name(conf) \"$name\""
    cmd_rm $config_lock
    unset config_lock
}

proc unset_config_lock {} {
    global config_lock
    catch {unset config_lock}
}
