Index: trunk/pxeconfig/changelog
===================================================================
--- trunk/pxeconfig/changelog	(revision 2)
+++ trunk/pxeconfig/changelog	(revision 2)
@@ -0,0 +1,6 @@
+Always edit this file when changes are commited:
+
+$Log: changelog,v $
+Revision 1.1  2002/02/18 15:02:00  sscpbas
+Initial revision
+
Index: trunk/pxeconfig/hexls.py
===================================================================
--- trunk/pxeconfig/hexls.py	(revision 2)
+++ trunk/pxeconfig/hexls.py	(revision 2)
@@ -0,0 +1,45 @@
+#! /usr/bin/env python
+'''
+hexls.py - Lists directory contents, but converts the hexadecimal IP numbers
+to dotted decimal notation (so you can at least see what you're doing..!!)
+
+Author: Walter de Jong <walter@sara.nl>
+Date:   January 2002
+
+CVS info 
+  $Date: 2002/02/18 15:02:00 $ 
+  $Revision: 1.1 $
+'''
+
+import os
+import string
+import re
+
+def hexls(path):
+	'''list directory, convert hexadecimal to dotted decimal'''
+
+	regexp = re.compile('[' + string.hexdigits + ']+')
+	for f in os.listdir(path):
+		if regexp.match(f) and len(f) == 8:
+			digit1 = string.atoi(f[:2], 16)
+			digit2 = string.atoi(f[2:4], 16)
+			digit3 = string.atoi(f[4:6], 16)
+			digit4 = string.atoi(f[6:], 16)
+
+			print '%s => %d.%d.%d.%d' % (f, digit1, digit2, digit3, digit4)
+		else:
+			if f[0] != '.':
+				print f
+
+
+if __name__ == '__main__':
+	import sys
+
+	if len(sys.argv) > 1:
+		for dir in sys.argv[1:]:
+			hexls(dir)
+	else:
+		hexls('.')
+
+# EOB
+
Index: trunk/pxeconfig/pxeconfig
===================================================================
--- trunk/pxeconfig/pxeconfig	(revision 2)
+++ trunk/pxeconfig/pxeconfig	(revision 2)
@@ -0,0 +1,182 @@
+#!/usr/bin/env python
+#
+# Author: Bas van der Vlies <basv@sara.nl>
+# Date  : 16 February 2002
+#
+# Tester: Walter de Jong <walter@sara.nl>
+#
+# CVS info
+#  $Date: 2002/02/18 15:02:00 $
+#  $Revision: 1.1 $
+#
+"""
+With this program you can configure which PXE configuration file
+to use when a node boots. The programm will ask the following questions:
+  1) Network address (Class C-network address only)
+  2) Starting nummber
+  3) Ending number
+  4) Which PXE config file to use. 
+
+For example, if the answers are: 
+  1) 10.168.44
+  2) 2
+  3) 4
+  4) default.node_install
+
+Then the result is that is create symbolic links in /tftpboot/pxelinux.cfg:
+  0AA82C02 ----> default.node_install
+  0AA82C03 ----> default.node_install
+  0AA82C04 ----> default.node_install
+"""
+
+import string
+import sys
+import os
+import glob
+
+# DEBUG
+#
+DEBUG=0
+
+# Constants
+#
+PXE_CONFIG_DIR='/tftpboot/pxelinux.cfg'
+NADDR=0
+PXEFILE=1
+START=2
+END=3
+
+def choice_pxe_configfile():
+  """
+  Let user choice which pxeconfig file to use.
+  """
+
+  os.chdir(PXE_CONFIG_DIR)
+
+  # Try to determine to which default file point to and 
+  # if exists remove it from te list.
+  #
+  try:
+    default_file = os.readlink('default')
+  except OSError:
+    default_file = None
+    pass
+
+  files = glob.glob('default.*')
+  if not files:
+    print 'There are no pxe config files starting with: default.'
+    sys.exit(1)
+
+  if default_file:
+    files.remove(default_file)
+ 
+
+  print 'Which pxe config file must we use: ?' 
+  i = 1   
+  for file in files:
+    print "%d : %s" %(i,file)
+    i = i +1
+
+  while 1:
+    index = raw_input('Choice a number: ')
+    try:
+      index = int(index)
+    except ValueError:
+      index = len(files) + 1
+
+    # Is the user smart enough to select
+    # the right value
+    #
+    if 0 < index <= len(files): break
+
+  return files[index-1]
+
+def create_links(list):
+  """
+  Create the links in the PXE_CONFIG_DIR,
+    list : A list containing: network hex addres, pxe config file, 
+           start number, end number
+  """
+  os.chdir(PXE_CONFIG_DIR)
+  naddr = list[NADDR]
+  pxe_filename = list[PXEFILE]
+  for i in range(list[START], list[END]+1):
+    haddr = '%s%02X' %(naddr, i)
+    if DEBUG:
+      print 'linking %s to %s' %(haddr, pxe_filename)
+    os.symlink(pxe_filename, haddr)
+
+
+def check_network(net):
+  """
+  This function check if the give network is a Class C-network and will
+  convert the network address to a hex address if true.
+  """
+  d = string.split(net, '.')
+
+  if len(d) != 3:
+    print('Only C-class nerwork addresses are supported!!!')
+    sys.exit(1)
+
+  # Check if we have valid network values
+  r = ''
+  for i in d:
+    i = check_number(i)
+    r = '%s%02X' %(r,i)
+
+  if DEBUG:
+    print r
+
+  return r
+
+def check_number(number):
+  """
+  This functions checks if the input is between 0 < number < 255:
+     number : is a string
+  """
+  try:
+    n = int(number)
+  except ValueError, detail:
+    print detail
+    sys.exit(1)
+
+  if 0 <= n <= 255:
+    return n
+  else:
+    print '%s is not a valid number, must be between 0 and 255' %number
+    sys.exit(1)
+
+def interactive():
+
+  iptable = {}
+
+  print __doc__
+
+  network = raw_input('Give network addres (xxx.xxx.xxx): ') 
+  naddr = check_network(network)
+
+  start = raw_input('Starting number: ') 
+  start = check_number(start)
+
+  end = raw_input('Ending number: ') 
+  end = check_number(end)
+
+  pxe_filename = choice_pxe_configfile()
+
+  iptable[network] = []
+  iptable[network].append(naddr)
+  iptable[network].append(pxe_filename)
+  iptable[network].append(int(start))
+  iptable[network].append(int(end))
+
+
+  for net in iptable.keys():
+    if DEBUG:
+      print net, iptable[net]    
+    create_links(iptable[net])
+
+def main():
+  interactive()
+
+if __name__ == '__main__':
+  main()
Index: trunk/pxeconfig/pxeconfigd
===================================================================
--- trunk/pxeconfig/pxeconfigd	(revision 2)
+++ trunk/pxeconfig/pxeconfigd	(revision 2)
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+"""
+Author: Bas van der Vlies <basv@sara.nl>
+Date  : 12 February 2002
+Desc. : This script is used to control how a node is booted with PXE
+        enabled network cards. The PC boots starts and fetch a pxe
+        config file which tells how the PC must boot. This daemon
+        enables a client to remove his pxe-config file. It then uses
+        the DEFAULT one. 
+          
+        Note:
+          This server can ONLY be started from inetd.
+
+CVS info
+  $Date: 2002/02/18 15:02:00 $
+  $Revision: 1.1 $
+"""
+import time
+import socket
+import sys
+import os
+import string
+import syslog
+
+# DEBUG
+#
+DEBUG=1
+
+# Some Global Constants
+#
+BUFSIZE=4096
+STDIN=0
+STDOUT=1
+
+PXE_CONF_DIR = '/tftpboot/pxelinux.cfg'
+
+# Give the current time
+#
+def now():
+    return time.ctime(time.time())
+
+
+def remove_link(filename):
+  """This removes the pxe config filename for the host that is connected:
+      filename : string
+  """
+
+  file = os.path.join(PXE_CONF_DIR, filename)
+
+  if DEBUG:
+    print 'file = %s' %file
+
+  if not os.path.exists(file): return
+
+  if os.path.islink(file): 
+    try:
+      os.unlink(file)
+      syslog.openlog("pxeconfigd")
+      syslog.syslog(syslog.LOG_INFO, file)
+      syslog.closelog()
+    except OSError:
+      err_msg = "No permission at directory: %s" %PXE_CONF_DIR
+      os.write(STDOUT, err_msg)
+      sys.exit(1)
+
+# This function handles the client connection. It closes
+# the connection if there is no data
+#
+def handleConnection():
+  """Determines which host connects to the server
+  """
+
+  # Determine client address
+  # 
+  try:
+    client_addr = socket.fromfd(sys.stdin.fileno(), socket.AF_INET, 
+                          socket.SOCK_STREAM)
+    client_ip = client_addr.getpeername()[0] 
+
+  except socket.error, detail:
+    print "pxeconfigd can only be started from inetd!!!"
+    sys.exit(1)
+
+
+  # translate ip address ---> hex address
+  #
+  d = string.split(client_ip, '.')
+  client_haddr = '%02X%02X%02X%02X' %(int(d[0]), int(d[1]), int(d[2]), int(d[3]))
+
+  if DEBUG:
+    print 'ip = %s, hex = %s' %(client_ip, client_haddr)
+
+  remove_link(client_haddr)
+  sys.exit(0)
+
+
+def server():
+  """Start the daemon
+  """
+
+  if not os.path.isdir(PXE_CONF_DIR):
+    os.write(STDOUT, "PXE booting is not configured")
+    sys.exit(1)
+
+  handleConnection()
+
+if __name__ == '__main__':
+  server()
