5752071 [rkeene@sledge /home/rkeene/devel/old/tcl]$ cat -n dyndns-server.tcl
   1: #!/usr/bin/tcl -n
   2: set DIRECTORY "/var/named/dyn"
   3: set passfile "$DIRECTORY/passwd"
   4: set PORT 32766
   5: set HOSTNAME [id host]
   6: set VERSION "0.2.1-Tcl"
   7: set USERFILE "$DIRECTORY/\$user.zone"
   8: set SUFIX ".dyn.n-f-d.com.  600"
   9: set INCLUDESFILE "$DIRECTORY/dynamic_ips.conf"
  10: set SERIALFILE "$DIRECTORY/serial.conf"
  11: set HEADERFILE "$DIRECTORY/header.conf"
  12: set USER "dns"
  13: set GROUP "dns"
  14: 
  15: 
  16: proc DoHUP {} {
  17:   global passfile
  18:   loadpasswords $passfile
  19: }
  20: 
  21: proc loadpasswords {passfile} {
  22:   global passwords
  23:   catch { unset passwords }
  24:   catch {
  25:     set passId [open $passfile r]
  26:   }
  27:   if {![info exists passId]} {
  28:     puts "Could not read passwd file ($passfile)"
  29:     exit
  30:   }
  31:   while {![eof $passId]} {
  32:     gets $passId ln
  33:     if {[llength $ln]==2 && [string index $ln 0]!="#"} { 
  34:       set passwords([lindex $ln 0]) [lindex $ln 1]
  35:     }
  36:   }
  37:   return
  38: }
  39: 
  40: proc putsock {sockId text} {
  41:   puts $sockId $text
  42:   flush $sockId
  43: }
  44: 
  45: proc crypt {pass} {
  46:   return $pass
  47: }
  48: 
  49: proc CreateIncludes {} {
  50:   global INCLUDESFILE DIRECTORY USERFILE HEADERFILE SERIALFILE passwords serial
  51:   catch {
  52:     set fileId [open $INCLUDESFILE w]
  53:   }
  54:   if {![info exists fileId]} { return 0 }
  55:   catch { set headId [open $HEADERFILE r] }
  56:   if {[info exists headId]} {
  57:     set serId [open $SERIALFILE r]
  58:     gets $serId serial
  59:     close $serId
  60:     while {![eof $headId]} {
  61:       gets $headId ln
  62:       catch { 
  63:         puts $fileId [subst $ln]
  64:       }
  65:     }
  66:     close $headId
  67:   }
  68:   foreach user [array names passwords] {
  69:     set file [subst $USERFILE]
  70:     puts $fileId "\$include \"$file\";"
  71:   }
  72:   close $fileId
  73:   return 1
  74: }
  75: 
  76: proc updateIP {user ip} {
  77:   global USERFILE SUFIX SERIALFILE
  78:   set wrk [split $ip .]
  79:   if {[llength $wrk]!=4} { return 0}
  80:   set ip ""
  81:   for {set i 0} {$i<4} {incr i} {
  82:     set tmp [lindex $wrk $i]
  83:     if {$tmp>254 || $tmp<0} { return 0 }
  84:     if {[catch { set tmp [expr $tmp/1] }]} { return 0 }
  85:     set ip "$ip.$tmp"
  86:   }
  87:   set ip [string range $ip 1 end]
  88:   catch {
  89:     set fileId [open [subst $USERFILE] r]
  90:   }
  91:   set newstring "$user$SUFIX  IN  A $ip"
  92:   if {[info exists fileId]} {
  93:     gets $fileId ln
  94:     if {$ln==$newstring} { return -1 }
  95:     close $fileId
  96:     unset fileId
  97:   }
  98:   catch { 
  99:     set fileId [open [subst $USERFILE] w]
 100:   }
 101:   if {![info exists fileId]} { return 0 }
 102:   puts $fileId $newstring
 103:   close $fileId
 104:   CreateIncludes
 105:   unset fileId
 106:   catch {
 107:     set fileId [open $SERIALFILE r]
 108:   }
 109:   gets $fileId ln
 110:   close $fileId
 111:   set fileId [open $SERIALFILE w]
 112:   puts $fileId [expr $ln +1]
 113:   close $fileId
 114:   exec /bin/killall -HUP named
 115:   return 1
 116: }
 117: 
 118: 
 119: proc GotConnection {sockId addr port} {
 120:   global passwords HOSTNAME VERSION
 121:   if {[fork]!=0} {
 122:     close $sockId
 123:     wait
 124:     return
 125:   }
 126:   if {[fork]!=0} { exit }
 127:   putsock $sockId "220 $HOSTNAME NFD-DYNDNS $VERSION Ready."
 128:   set state 0
 129:   while {![eof $sockId]} {
 130:     set cmd ""
 131:     set arg ""
 132:     gets $sockId ln
 133:     catch {
 134:       set cmd [string tolower [lindex $ln 0]]
 135:       set arg [lindex $ln 1]
 136:     }
 137:     switch -- $cmd {
 138:       "user" {
 139:         set username [string tolower $arg]
 140:         set state 1
 141:         putsock $sockId "331 Password Required"
 142:         flush $sockId
 143:       }
 144:       "pass" {
 145:         if {$state==1} {
 146:           set password [crypt $arg]
 147:           if {[info exists passwords($username)]} {
 148:             if {$passwords($username)==$password} { set fail 0 } else { set fail 1 }
 149:           } else {
 150:             set fail 1
 151:           }
 152:           if {!$fail} {
 153:             putsock $sockId "230 Password Accepted"
 154:             set state 2
 155:           } else {
 156:             putsock $sockId "530 Login incorrect"
 157:           }
 158:         } else {
 159:           putsock $sockid "503 Send USER first"
 160:         }
 161:       }
 162:       "seti" {
 163:         if {$state==2} {
 164:           if {[updateIP $username $arg]!=0} {
 165:             putsock $sockId "220 Updated"
 166:           } else {
 167:             putsock $sockId "420 Database Error"
 168:           }
 169:         } else {
 170:           putsock $sockId "530 Login with USER and PASS"
 171:         }
 172:       }
 173:       "quit" {
 174:         putsock $sockId "221 Bye."
 175:         close $sockId
 176:         exit
 177:       }
 178:       default {
 179:         putsock $sockId "500 '[string toupper $cmd]': Command not recognized."
 180:       }
 181:     }
 182:   }
 183:   exit
 184: }
 185: 
 186: id group $GROUP
 187: id user $USER
 188: loadpasswords $passfile
 189: signal trap SIGHUP DoHUP
 190: if {[fork]!=0} { exit }
 191: socket -server GotConnection $PORT
 192: vwait forever
5752072 [rkeene@sledge /home/rkeene/devel/old/tcl]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2001-03-23 22:29:08