#!/usr/local/bin/dptcl -f
#
##########################################################################
# globals
##########################################################################
# list of managed people
set people {}
# list of locked people
set locks {}
# detailed lock info
set lock_info() {}
# port to use

######## *EDIT* ########
set lib_dir /usr/local/lib/abwesenheit

source $lib_dir/config.tcl

set month_names {spacer January February March April May June July August September October November December}

set log_file "${data_dir}/absence.log"
if {$language == "german"} {
	set holiday_file "${data_dir}/.feiertage";      # holidays
	set messe_file "${data_dir}/.messen";           # computer show dates
} else {
	set holiday_file "${data_dir}/.holidays";	# holidays
	set messe_file "${data_dir}/.tradeshows";	# computer show dates
}
set hostname [exec /bin/hostname]
set daynames {Sunday Monday Tuesday Wednesday Thursday Friday Saturday}
set cell_binding {}
set data_file_extension "WB_DATA"
set rev_cell_binding() ""
set virgin_biglist {}
#set num_cells 120
#set debug 1
set debug 0
set lock_serial 1
set shutdown 0
set client_list {}

##########################################################################

##########################################################################
# routines ...
##########################################################################

proc ZeroPersonLists {} {
  global people virgin_biglist biglist
  foreach person $people {
    set biglist($person) "$virgin_biglist"
  }
}

proc odd {int} {
  if {[expr $int % 2]} {
    return 1
  }
  return 0
}
proc ServerAddPerson {list} {
  global add_change people person_info armed_person_change person_reservations
  global virgin_biglist person_mtime client_list debug updated_info

  set person [lindex $list 0]
  set person_reservations($person) ""
  set biglist($person) "$virgin_biglist"
  set person_mtime($person) [exec date]
  if {[lsearch $people $person] == -1} {
    lappend people $person
    set people [lsort $people]
    set person_info($person) "$list"
    WritePersonFile $person
    LogIt "{added new person $person}"
    if {$debug} {puts "client_list=$client_list."}
    foreach client $client_list {
      lappend updated_info($client) "init"
    }
    return 1
  } else {
    return 0
  }
}

proc ServerDeletePerson {person} {
  global people client_list updated_info data_file_extension data_dir

  set pos [lsearch $people $person]
  if {$pos != -1} {
    set people [lreplace $people $pos $pos]
    foreach client $client_list {
      lappend updated_info($client) "init"
    }
    set filename "$data_dir/${person}.${data_file_extension}"
    #exec rm $filename
    exec mv $filename ${filename}.deleted
  }
}

proc UsernameExists {un} {
  set ret [exec echo "echo ~$un" | ksh -p]
  if {$ret == "~$un"} {
    return 0
  }
  return 1
}
##########################################
proc list {} {
  global locks
  puts $locks
}
########################################
# debug ...
########################################
proc PrintLocks {} {
  global locks lock_info
  puts "LOCKS=$locks\n---------- lock_info -------------"
  foreach name [array names lock_info] {
    puts "lock_info($name) = [lindex $lock_info($name) 0]"
  }
}
########################################
# try to get lock
########################################
proc RequestLock {person client} {
  global locks lock_info people debug lock_serial shutdown

  if {$shutdown} {
    return "error server shutting down..."
  }
  if {$debug} {puts -nonewline "$client requested lock for $person ... "}
  if {[lsearch $people $person] == -1} {
    return "error no such person"
  }
  if {[lsearch $locks $person] != -1} {
    if {$debug} {puts "already locked by [lindex $lock_info($person) 0]"}
    return "failure [lindex $lock_info($person) 0]"
  }
  lappend locks $person
  incr lock_serial
  set lock_info($person) "{$client} {$lock_serial}"
  if {$debug} {puts "success"}
  dp_after 150000 LockTimeout $person $client $lock_serial
  #dp_after 25000 LockTimeout $person $client $lock_serial
  return "success"
}

########################################
# release lock
########################################
proc ReleaseLock {person client} {
  global locks lock_info debug shutdown

  if {$debug} {puts "$client releasing lock on $person"}
  set ret [lsearch $locks $person]
  if {$ret == -1} {
    return "error person not locked"
  } elseif {[lindex $lock_info($person) 0] != $client} {
    return "error person not locked by $client"
  }
  set locks [lreplace $locks $ret $ret]
  #if {$shutdown} {if {$locks == ""} {exit}}
  set lock_info($person) {}
  return "success"
}

proc GetDataDir {} {
  global data_dir
  return "$data_dir"
}

proc Mail {recipient subject contents} {
  global mail_cmd

  set fid [open "|$mail_cmd -s \"$subject\" $recipient" w]
  foreach line $contents {
    puts $fid "$line"
  }
  close $fid
}

proc SignOn {un} {
  global client_list debug minutes_arr minutes

  set count 2
  set client $un
  while {[lsearch $client_list $client] != -1} {
    set client "${un}${count}"
    incr count
  }
  if {$debug} {puts "$client signed on"}
  lappend client_list $client
  set minutes_arr($client) $minutes
  return "$client"
}

proc SignOff {user} {
  global client_list debug

  if {$debug} {puts "$user signed off"}
  set ret [lsearch $client_list $user]
  if {$ret != -1} {
    set client_list [lreplace $client_list $ret $ret]
  }
}

proc ServerUpdatePerson {person info list client} {
  global person_reservations person_info person_mtime lock_info debug

  if {$debug} {
    puts "$client updating person list for $person"
    puts "newinfo=\[$info\]"
    puts "newlist=\[$list\]"
  }
  if {[lindex $lock_info($person) 0] != "$client"} {
    return "NOTLOCKED $person not locked by $client"
    if {$debug} {puts "UpdatePersonList: NOTLOCKED"}
  }
  if {$info != ""} {
    if {$debug} {puts "UpdatePersonList: stammdaten info changed"}
    set person_info($person) "$info"
  }
  #if {$debug} {puts "UpdatePersonList: reservation info changed"}
  set person_reservations($person) "$list"
  WritePersonFile $person
  set person_mtime($person) [exec date]
  UpdateChangedInfo $person $client
  return "success"
}
 
proc LogIt {message} {
  global today log_file
#  puts " -- LogIt --"
  set fileid [open $log_file a]
  puts -nonewline $fileid "\[$today\] "
  foreach line $message {
    puts $fileid "$line"
  }
  close $fileid
}

proc LoadHolidays {} {
  global holidays holiday_file debug

  set holidays ""
  if {[file exist $holiday_file]} {
    set fid [open $holiday_file r]
    while {[gets $fid line] != -1} {
      if {![regexp {^#} $line]} {
        set type [lindex $line 0]
        set date [lindex $line 1]
        if {[scan $date "%d/%d/%d" day month year] == 3} {
          set desc [lindex $line 2]
          lappend holidays "$day/$month/$year {$desc} $type"
        }
      }
    }
    close $fid
  }
  #if {$debug} {puts "holidays=$holidays"}
}

proc LoadMessen {} {
  global messen messe_file
  set messen ""
  if {[file exist $messe_file]} {
    set fid [open $messe_file r]
    while {[gets $fid line] != -1} {
      if {(![regexp {^#} $line])&&
          ([scan $line "%d/%d/%d %s\n" day month year desc] == 4)} {
        set desc [lindex $line 1]
        lappend messen "$day/$month/$year {$desc}"
        # debug
	# puts "LoadMessen: got $day $month $year {$desc}"
      }
    }
    close $fid
  }
}

proc GetHoliday {cell} {
  global holidays cell_binding debug

  set binding [lindex $cell_binding $cell]
  set tmp "[lindex $binding 0]/[lindex $binding 1]/[lindex $binding 2]"
  #if {$debug} {puts "GetHoliday: cell=$cell, tmp=$tmp."}
  foreach holiday $holidays {
    if {$tmp == [lindex $holiday 0]} {
        return "{[lindex $holiday 1]} {[lindex $holiday 2]}"
    }
  }
  puts "ERROR: GetHoliday: cell=$cell, holidays=$holidays, holiday_list=$holiday_list"
}

proc GetMesse {cell} {
  global messen cell_binding
  set binding [lindex $cell_binding $cell]
  set tmp "[lindex $binding 0]/[lindex $binding 1]/[lindex $binding 2]"
  foreach messe $messen {
    if {$tmp == [lindex $messe 0]} {
        return [lindex $messe 1]
    }
  }
  puts "ERROR: GetMesse: cell=$cell, messen=$messen, messe_list=$messe_list"
}

proc IsHoliday {cell} {
  global cell_binding holidays holiday_list debug

  set tmp "[lindex $cell 0]/[lindex $cell 1]/[lindex $cell 2]"
  foreach holiday $holidays {
    #if {$debug} {puts "IsHoliday: cell=$tmp, holiday=[lindex $holiday 0]."}
    if {"$tmp" == "[lindex $holiday 0]"} {
      return 1
    }
  }
  return 0
}

proc IsMesse {cell} {
  global cell_binding messen messe_list

  set tmp "[lindex $cell 0]/[lindex $cell 1]/[lindex $cell 2]"
  foreach messe $messen {
    if {$tmp == [lindex $messe 0]} {
      return 1
    }
  }
  return 0
}

proc MonthDays {month year} {
  set m_l "31 28 31 30 31 30 31 31 30 31 30 31"
  if {($month == 2) && ([expr $year / 4] == [expr ${year}.0 / 4.0])} {
    return 29
  }
  return [lindex $m_l [expr $month - 1]]
}

proc SetDateVars {} {
  global week_num weekday_num monthday_num month_num year_num today
  global month_names
  set week_num [string trimleft [exec date +%U] 0]
  set weekday_num [exec date +%w]
  set monthday_num [string trimleft [exec date +%d] 0]
  set month_num [string trimleft [exec date +%m] 0]
  set year_num [exec date +%y]
  set today "${monthday_num}-[string toupper\
    [string range [lindex $month_names $month_num] 0 2]]-${year_num}"
}


proc Truncate {foo} {
  regsub {\..*} "$foo" {} tmp
  return "$tmp"
}

proc GetRealName {username} {
  global hostname
  if {$username == "jmh"} {
    return "Holzer"
  }
  if {$user_lookup == "LOCAL"} {
    # if you're not using YP, then do it this way...
    set pwline [exec grep $username /etc/passwd]
  } else {
    # otherwise do it this way YP
    set pwline [exec ypcat passwd | grep $username]
  }
  set gecos [lindex [split $pwline {:}] 4]
  set fullname [lindex [split $gecos {,}] 0]
  return [lindex $fullname [expr [llength $fullname] - 1]]
}

proc Convert {code halfcell} {
  global cell_binding weekday_num daynames month_names daynames
  #puts "Convert: halfcell=$halfcell"
  set cell [expr $halfcell / 2]
  set binding [lindex $cell_binding $cell]
  set half [expr "[odd ${halfcell}] ? {afternoon} : {morning}"]
  set halfgerm [expr "[odd ${halfcell}] ? {Nachmittag} : {Vormittag}"]
  set dayofmonth [lindex $binding 0]
  set monthnum [lindex $binding 1]
  set year [lindex $binding 2]
  set month [lindex $month_names $monthnum]
  set vmsmonth [string toupper [string range $month 0 2]]
  set dayofweeknum [expr ($weekday_num + $dayofmonth) % 7]
  set dayname [lindex $daynames $dayofweeknum]
  switch $code {
    monthnum     {set answer $monthnum}
    month        {set answer $month}
    dayofmonth   {set answer $dayofmonth}
    halfnum      {set answer [odd $halfcell]}
    halfword     {set answer $half}
    dayofweeknum {set answer $dayofweeknum}
    dayname      {set answer $dayname}
    nicedate     {set answer "${month} $dayofmonth, $half"}
    secdate      {set answer [format "%d/%d/%d %s" $dayofmonth $monthnum \
                  $year $halfgerm]}
    file_format  {set answer [format "%d/%d/%d/%d" $dayofmonth $monthnum \
                  $year [odd $halfcell]]}
    vmsdate	 {set answer "${dayofmonth}-${vmsmonth}-${year}"}
  }
  return $answer
}

proc OldCellBind {} {
  global cell_binding month_num monthday_num year_num
  global num_cells num_halfcells rev_cell_binding holiday_list
  global holidays messen messe_list debug

  #puts "DBG: CellBind"
  set num_halfcells [expr $num_cells * 2]
  set count 0
  set cell_binding ""
  set holiday_list ""
  set messe_list ""
  set year $year_num
  set curr_month $month_num
  set curr_day_of_month $monthday_num
  set tmp [expr $num_cells * 4]
  #puts "DBG: num_cells=$num_cells, count=$count, tmp=$tmp"
  while {$count < $tmp} {
    lappend cell_binding "$curr_day_of_month $curr_month $year"
    if {[IsHoliday "$curr_day_of_month $curr_month $year"]} {
      lappend holiday_list "_${count}_"
    } elseif {[IsMesse "$curr_day_of_month $curr_month $year"]} {
      lappend messe_list "_${count}_"
    }
    set rev_cell_binding(${curr_day_of_month}_${curr_month}_$year) $count
    incr curr_day_of_month
    if {$curr_day_of_month > [MonthDays $curr_month $year]} {
      if {$curr_month == 12} {
        set curr_month 1
        incr year
      } else {
        incr curr_month
      }
      set curr_day_of_month 1
    }
    incr count
  }
  if {$debug} {puts "holiday_list=$holiday_list."}
}

proc CellBind {} {
  global cell_binding month_num monthday_num year_num
  global num_cells num_halfcells rev_cell_binding holiday_list
  global messen messe_list debug

  #puts "DBG: CellBind"
  set num_halfcells [expr $num_cells * 2]
  set count 0
  set cell_binding ""
  set year $year_num
  set curr_month $month_num
  set curr_day_of_month $monthday_num
  set tmp [expr $num_cells * 4]
  #puts "DBG: num_cells=$num_cells, count=$count, tmp=$tmp"
  while {$count < $tmp} {
    lappend cell_binding "$curr_day_of_month $curr_month $year"
    set rev_cell_binding(${curr_day_of_month}_${curr_month}_$year) $count
    incr curr_day_of_month
    if {$curr_day_of_month > [MonthDays $curr_month $year]} {
      if {$curr_month == 12} {
        set curr_month 1
        incr year
      } else {
        incr curr_month
      }
      set curr_day_of_month 1
    }
    incr count
  }
  CreateLists
  if {$debug} {puts "holiday_list=$holiday_list."}
}

proc CreateLists {} {
  global cell_binding num_cells num_halfcells rev_cell_binding holiday_list
  global holidays messen messe_list debug month_num year_num monthday_num

  if {$debug} {puts "%% CreateLists ..."; flush stdout}
  set count 0
  set curr_month $month_num
  set year $year_num
  set curr_day_of_month $monthday_num
  set holiday_list ""
  set messe_list ""
  set tmp [expr $num_cells * 4]
  while {$count < $tmp} {
    if {[IsHoliday "$curr_day_of_month $curr_month $year"]} {
      lappend holiday_list "_${count}_"
    } elseif {[IsMesse "$curr_day_of_month $curr_month $year"]} {
      lappend messe_list "_${count}_"
    }
    incr curr_day_of_month
    if {$curr_day_of_month > [MonthDays $curr_month $year]} {
      if {$curr_month == 12} {
        set curr_month 1
        incr year
      } else {
        incr curr_month
      }
      set curr_day_of_month 1
    }
    incr count
  }
}

proc FindPeople {} {
  global data_dir data_file_extension people person_mtime debug

  set people ""
  cd $data_dir
  set list {}
  catch {set list [glob *.$data_file_extension]}
  foreach tmp $list {
    regsub {\..*$} $tmp {} person
    lappend people $person
    set person_mtime($person) [exec date]
  }
  set people [lsort $people]
  if {$debug} {puts "people: $people"}
}

proc CheckDate {} {
  global weekday_num
  set tmp [fmtclock [convertclock now] %w]
  if {$tmp != $weekday_num} {
    SetDateVars
    Init
    return 1
  }
  return 0
}

proc ReadAllPeople {} {
  global people
  foreach person $people {
    ReadPersonFile $person
  }
}

proc ReadPersonFile {person} {
  global person_reservations person_info data_file_extension debug
  global data_dir

  if {$debug} {puts "reading person file for $person"}
  set phone ""
  set address ""
  set person_reservations($person) ""
  set filename "$data_dir/${person}.${data_file_extension}"
  set file_id [open $filename "r"]
  while {[gets $file_id line] != -1} {
    set label [lindex $line 0]
    set contents [lindex $line 1]
    switch $label {
      person   {
        if {$person != $contents} {
          puts "person in data file doesn't match filename for person $person"
          puts "bailing..."
          exit
        }
      }
      phone {set phone $contents}
      address  {set address $contents}
      res      {
        set tmp "[ConvertFromFileRes $contents]"
        #if {$debug} {puts "got \"$tmp\" from ConvertFromFileRes"}
        if {$tmp != ""} {
          lappend person_reservations($person) "$tmp"
        }
      }
      default  {puts "junk in data file: $contents"}
    }
  }
  close $file_id
  set person_info($person) "{$person} {$phone} {$address}"
}

proc ConvertFromFileRes {list} {
  global debug

  #if {$debug} {puts "ConvertFromFileRes: list=$list"}
  set tag [lindex $list 0]
  set start_date [lindex $list 1]
  set end_date [lindex $list 2]
  set cust [lindex $list 3]
  set sonst [lindex $list 4]
  set fone [lindex $list 5]
  # DEBUG
  # puts "ConvertFromFileRes: fone=$fone"
  set start_halfcell [ConvertFromFileDate $start_date]
  set end_halfcell [ConvertFromFileDate $end_date]
  if {($end_halfcell ==  -1)||($start_halfcell == -1)||($end_halfcell == {})} {
    return {}
  }
  if {$start_halfcell == ""} {
    set start_halfcell 0
  }
  return "{$tag} {$start_halfcell} {$end_halfcell} {$cust} {$sonst} {$fone}"
}

proc ConvertFromFileDate {file_date} {
  global debug

  #if {$debug} {puts "ConvertFromFileDate: $file_date"}
  global month_num year_num monthday_num cell_binding num_cells year_num
  global rev_cell_binding log_file
  if {[scan $file_date "%d/%d/%d/%d" day month year half] != 4} {
    puts "error trying to convert $file_date to internal format"
    LogErr "ConvertFromFileDate: error converting $file_date to internal format"
    return {-1}
  }
  if {$year > 1900} {set year [expr $year - 1900]}
  if {$year < $year_num} {return {}}
  if {($year == $year_num)&&(($month < $month_num) ||
      (($month == $month_num) && ($day < $monthday_num)))} {
    #if {$debug} {puts "ConvertFromFileDate: returning nil"}
    return {}
  }
  if {[catch {set cell [set rev_cell_binding(${day}_${month}_$year)]}]} {
    LogErr "ConvertFromFileDate: file_date=$file_date (rev_cell_binding)"
    puts "Error, see $log_file"
    return {-1}
  } else {
    return [expr ($cell * 2) + $half]
  }
}

proc LogErr {message} {
  global username today log_file
  set fileid [open $log_file a]
  puts $fileid "ERROR: \[$today\] $username $message"
  close $fileid
}

proc WritePersonFile {person} {
  global person_info person_reservations data_file_extension debug

  if {$debug} {puts "WritePersonFile: $person"}
  set filename "${person}.${data_file_extension}"
  set file_id [open $filename w 0660]
  puts $file_id "person {$person}"
  puts $file_id "phone {[lindex $person_info($person) 1]}"
  puts $file_id "address {[lindex $person_info($person) 2]}"
  catch {
    foreach ent $person_reservations($person) {
      if {$debug} {puts "WritePersonFile: res=$ent"}
      puts $file_id "res {[ConvertToFileRes $ent]}"
    }
  }
  close $file_id
  #if {$chgrp == "chgrp"} {chgrp staff $filename}
}

proc ConvertToFileRes {list} {
#  puts "ConvertToFileRes: list=$list"
  set tag [lindex $list 0]
  set start_date [Convert file_format [lindex $list 1]]
  set end_date   [Convert file_format [lindex $list 2]]
  set cust       [lindex $list 3]
  set sonst      [lindex $list 4]
  set fone       [lindex $list 5]
  return "{$tag} {$start_date} {$end_date} {$cust} {$sonst} {$fone}"
}

proc UpdateBiglists {} {
  global people
  foreach person $people {
    UpdatePersonBiglist $person
  }
}

proc UpdatePersonBiglist {person} {
  global person_reservations biglist virgin_biglist num_halfcells
  set biglist($person) "$virgin_biglist"
  foreach entry $person_reservations($person) {
    set tag [lindex $entry 0]
    set start [lindex $entry 1]
    set end [lindex $entry 2]
    set count $start
    while {($count < $num_halfcells)&&($count <= $end)} {
      set biglist($person) [lreplace $biglist($person) $count $count $tag]
      incr count
    }
  }
}
proc InitVirginBiglist {} {
  global virgin_biglist num_cells
  set count 0
  while {$count < [expr $num_cells * 2]} {
    lappend virgin_biglist 0
    incr count
  }
}

proc GetModTime {person} {
  global person_mtime
  return $person_mtime($person)
}

proc LockTimeout {person client serial} {
  global lock_info debug

  if {$debug} {
    puts "LockTimeout: lock_info(person) = [lindex $lock_info($person) 0]"
    puts "             lock_info(serial) = [lindex $lock_info($person) 1]"
    puts "             person = $person"
    puts "             serial = $serial"
  }
  if {([lindex $lock_info($person) 0] != "$client")||
      ([lindex $lock_info($person) 1] != $serial)} {
    return
  }
  if {$debug} {puts "lock on $person by $client automagically removed"}
  ReleaseLock $person $client
}

proc ServerRequestUpdates {client} {
  global client_list updated_info updated_people any_cmd debug
  global files_updated client_last_request minutes minutes_arr

  set minutes_arr($client) $minutes
  set people ""
  set info ""
  set cmd ""

  catch {set people $updated_people($client)}
  catch {set info $updated_info($client)}
  catch {set cmd $any_cmd($client)}
  if {$debug} {puts "$client request changed info, returning: $info, $people"}
  set updated_people($client) {}
  set updated_info($client) {}
  return "{$info} {$people} {$cmd}"
}

proc KillClients {} {
  global client_list updated_info debug

  if {$debug} {puts "KillClients called"}
  foreach client $client_list {
    lappend updated_info($client) "die"
  }
}

proc ServerAnyCmd {cmd} {
  global any_cmd client_list

  foreach client $client_list {
    lappend any_cmd($client) $cmd
  }
}

proc GetMinutes {} {
  global minutes client_list minutes_arr debug

  #
  # get day of year, hour, minute, and second
  #
  set list [exec date "+{%j} {%H} {%M} {%S}"]
  set day	[lindex $list 0]
  set hour	[lindex $list 1]
  set minute	[lindex $list 2]
  #set second	[lindex $list 3]
  regsub {^0*([1-9][0-9]*)$} $day {\1} day
  regsub {^0*([1-9][0-9]*)$} $hour {\1} hour
  regsub {^0*([1-9][0-9]*)$} $minute {\1} minute
  set minutes [expr $day * 1440 + $hour * 60 + $minute]
  foreach client $client_list {
    if {[expr $minutes - $minutes_arr($client)] > 15} {
      if {$debug} {puts "Server initiated SignOff of client $client..."}
      SignOff $client
      #set i [lsearch $client_list $client]
      #set client_list [lreplace $client_list $i $i]
    }
  }
  DetectChanges
  dp_after 60000 GetMinutes
}

proc ForceInit {} {
  global updated_info client_list

  foreach client $client_list {
    lappend updated_info($client) "init"
  }
}

proc DetectChanges {} {
  global updated_info messe_mtime holiday_mtime debug month_names
  global holiday_file messe_file client_list
  global holiday_file messe_file today

  set tmp_monthday_num [string trimleft [exec date +%d] 0]
  set tmp_year_num [exec date +%y]
  set tmp_month_num [string trimleft [exec date +%m] 0]
  set tmp_today "${tmp_monthday_num}-[string toupper\
    [string range [lindex $month_names $tmp_month_num] 0 2]]-${tmp_year_num}"

  if {$today != $tmp_today} {
    DateChange
    foreach client $client_list {
      lappend updated_info($client) "init"
    }
  }
  if {([GetFileMtime $holiday_file] != $holiday_mtime)||
      ([GetFileMtime $messe_file] != $messe_mtime)} {
    LoadHolidays
    LoadMessen
    set holiday_mtime [GetFileMtime $holiday_file]
    set messe_mtime [GetFileMtime $messe_file]
    if {$debug} {puts "-- holiday/messe file changed --"}
    foreach client $client_list {
      lappend updated_info($client) "messe_holiday"
    }
    CreateLists
  }
}

proc GetFileMtime {file} {
  if {[catch {file stat $file statvar}]} {
    return -1
  }
  return $statvar(mtime)
}

proc UpdateChangedInfo {person ignore_client} {
  global client_list updated_people debug

  if {$debug} {puts "adding $person to updated_people lists"}
  foreach client $client_list {
    if {$client != $ignore_client} {
      lappend updated_people($client) $person
    }
  }
}

proc Shutdown {} {
  global shutdown locks debug
  
  set shutdown 1
  if {$locks != ""} {
    if {$debug} {puts "waiting for all locks to be given up ..."}
    dp_after 5000 Shutdown
    return
  }
  if {$debug} {puts "shutting down."}
  exit
}

proc DateChange {} {
  SetDateVars
  CellBind
  FindPeople
  ReadAllPeople
  UpdateBiglists
}

proc ServerGetRevCellBinding {string} {
  global rev_cell_binding

  set ret "error"
  catch {set ret [set rev_cell_binding($string)]}
  return "$ret"
}

#######################################################################
proc Init {} {
  global people ygap starty num_cells cwidth_pix xgap debug
  global holiday_file messe_file holiday_mtime messe_mtime

  SetDateVars
  if {$debug} {puts "%% loading holidays ..."; flush stdout}
  LoadHolidays
  if {$debug} {puts "%% loading messen ..."; flush stdout}
  LoadMessen
  if {$debug} {puts "%% cellbind ..."; flush stdout}
  CellBind
  InitVirginBiglist
  if {$debug} {puts "%% FindPeople ..."; flush stdout}
  FindPeople
  ReadAllPeople
  UpdateBiglists
  set holiday_mtime [GetFileMtime $holiday_file]
  set messe_mtime [GetFileMtime $messe_file]
}
#######################################################################
# initial sanity check
if {([catch {file stat $data_dir sc_tmp}]) || ($sc_tmp(type) != "directory")} {
  puts "$data_dir doesn't exist or isn't a directory"
  exit
}
if {$debug} {puts "%% starting initializations..."; flush stdout}
Init
GetMinutes
if {$debug} {puts "minutes=$minutes"}
puts "%% running %% [exec date]"; flush stdout
dp_MakeRPCServer $rpc_port
