home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 March B / SCO_CASTOR4RRT.iso / inet / root.2 / usr / lib / scoadmin / netosa / dhcpOsa / dhcpOsa~
Text File  |  1998-08-19  |  56KB  |  1,996 lines

  1.  
  2. # Copyright (c) 1992-1998 The Santa Cruz Operation, Inc.. All Rights Reserved. 
  3. #                                                                         
  4. #        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF THE               
  5. #                   SANTA CRUZ OPERATION INC.                             
  6. #                                                                         
  7. #   The copyright notice above does not evidence any actual or intended   
  8. #   publication of such source code.                                      
  9.  
  10. #******************************************************************************
  11. #
  12. #    Copyright (C) 1992-1998 The Santa Cruz Operation, Inc.
  13. #        All Rights Reserved.
  14. #
  15. #    The information in this file is provided for the exclusive use of
  16. #    the licensees of The Santa Cruz Operation, Inc.  Such users have the
  17. #    right to use, modify, and incorporate this code into other products
  18. #    for purposes authorized by the license agreement provided they include
  19. #    this notice and the associated copyright notice with any such product.
  20. #    The information in this file is provided "AS IS" without warranty.
  21. #
  22. #===============================================================================
  23. #@package: SCO_DHCPOSA_MSGS SCO_DHCPOSA_MSGS
  24. proc SCO_DHCPOSA_MSGS {} {}
  25. global SCO_DHCPOSA_MSGS
  26. set SCO_DHCPOSA_MSGS(@catalog@) {dhcpOsa.cat@sa 1}
  27. set SCO_DHCPOSA_MSGS(ERR_NO_OPT_FILE) {1 {Cannot open option configuration file: %1$s}}
  28. set SCO_DHCPOSA_MSGS(ERR_WRITE_PERMISSION) {2 {Cannot write to %1$s}}
  29. set SCO_DHCPOSA_MSGS(ERR_WRITE_BACKUP) {3 {Backup of %1$s failed}}
  30. set SCO_DHCPOSA_MSGS(ERR_OPEN) {4 {Failed to open %1$s}}
  31. set SCO_DHCPOSA_MSGS(ERR_NO_DEFINITION) {5 {Configuration error: option %1$d is only valid when defined as part of a %2$d definition.}}
  32. set SCO_DHCPOSA_MSGS(ERR_INVALID_DEFINITION) {6 {Configuration error: %1$s definition option %2$s defined for %3$s definition}}
  33. set SCO_DHCPOSA_MSGS(ERR_INVALID_CLIENT_IP) {7 {Configuration error: invalid ip address %1$s}}
  34. set SCO_DHCPOSA_MSGS(ERR_UNEXPECTED_OPTION) {8 {Configuration error: Unexpected definition for option %1$s}}
  35. set SCO_DHCPOSA_MSGS(ERR_READ_PERMISSION) {9 {Cannot read %1$s}}
  36. set SCO_DHCPOSA_MSGS(ERR_UNEXPECTED_DEFINITION) {10 {Configuration error: unexpected start of %1$s definition when a %2$s definition has already been started.}}
  37. set SCO_DHCPOSA_MSGS(ERR_INVALID_SUBNET) {11 {Invalid IP address %1$s for subnet definition}}
  38. set SCO_DHCPOSA_MSGS(ERR_DEF_EXISTS) {12 {A %1$s definition already exists for %2$s.}}
  39. set SCO_DHCPOSA_MSGS(ERR_UNEXPECTED_ARRAY) {13 {Configuration error: Unexpected array definition %1$s}}
  40. set SCO_DHCPOSA_MSGS(ERR_DEF_TERMINATION) {14 {Configuration error: Unexpected definition termination}}
  41. set SCO_DHCPOSA_MSGS(ERR_ARRAY_TERMINATION) {15 {Configuration error: Unexpected array termination}}
  42. set SCO_DHCPOSA_MSGS(ERR_INVALID_OPTION_TYPE) {16 {Configuration error: The option %1$s must be a decimal number - %2$s.}}
  43. set SCO_DHCPOSA_MSGS(ERR_INVALID_OPTION_RANGE) {17 {Configuration error: The option %1$s must be in the range 128 to 254 - %2$s.}}
  44. set SCO_DHCPOSA_MSGS(ERR_OPTION_BOOLEAN_VALUE) {18 {Configuration error: The option %1$s should be a boolean value - %2$s}}
  45. set SCO_DHCPOSA_MSGS(ERR_NO_FILE) {19 {File %1$s does not exist}}
  46. set SCO_DHCPOSA_MSGS(ERR_CONFIG) {20 {Configuration error: the format of the file %1$s is not correct}}
  47. set SCO_DHCPOSA_MSGS(ERR_UNIX) {21 %s}
  48. set SCO_DHCPOSA_MSGS(ERR_SACADM_STOP) {22 {sacadm failed to stop %1$s}}
  49. set SCO_DHCPOSA_MSGS(ERR_SACADM_START) {23 {sacadm failed to start %1$s}}
  50. set sco_dhcpVendorClass_CDT(attributes) {
  51.     {
  52.         options
  53.         {
  54.             { validOperations {get add remove} }
  55.             { validFilters {} }
  56.             { dataType set }
  57.         }
  58.     }
  59. }
  60. set sco_dhcpVendorClass_CDT(groups) {}
  61. set sco_dhcpVendorClass_CDT(operations) {
  62.     {
  63.         get
  64.         {
  65.             { granularity perObject }
  66.             { function dhcpVendorClass_get }
  67.         }
  68.     }
  69.     {
  70.         add
  71.         {
  72.             { granularity perObject }
  73.             { function dhcpVendorClass_add }
  74.         }
  75.     }
  76.     {
  77.         remove
  78.         {
  79.             { granularity perObject }
  80.             { function dhcpVendorClass_remove }
  81.         }
  82.     }
  83.     {
  84.         list
  85.         {
  86.             { granularity perObject }
  87.             { function dhcpVendorClass_list }
  88.         }
  89.     }
  90. }
  91. set sco_dhcpVendorClass_CDT(class) {sco dhcpVendorClass}
  92. set sco_dhcpVendorClass_CDT(superior) {sco dhcpVendorClass}
  93. set sco_dhcpVendorClass_CDT(subordinates) {{sco dhcpVendorClass}}
  94. set sco_dhcpServer_CDT(attributes) {
  95.     {
  96.         options
  97.         {
  98.             { validOperations {get add remove} }
  99.             { validFilters {} }
  100.             { dataType set }
  101.         }
  102.     }
  103. }
  104. set sco_dhcpServer_CDT(groups) {}
  105. set sco_dhcpServer_CDT(operations) {
  106.     {
  107.         get
  108.         {
  109.             { granularity perObject }
  110.             { function dhcpServer_get }
  111.         }
  112.     }
  113.     {
  114.         add
  115.         {
  116.             { granularity perObject }
  117.             { function dhcpServer_add }
  118.         }
  119.     }
  120.     {
  121.         remove
  122.         {
  123.             { granularity perObject }
  124.             { function dhcpServer_remove }
  125.         }
  126.     }
  127.     {
  128.         list
  129.         {
  130.             { granularity perObject }
  131.             { function dhcpServer_list }
  132.         }
  133.     }
  134. }
  135. set sco_dhcpServer_CDT(class) {sco dhcpServer}
  136. set sco_dhcpServer_CDT(superior) {sco dhcpServer}
  137. set sco_dhcpServer_CDT(subordinates) {{sco dhcpServer}}
  138. set sco_dhcpGlobal_CDT(attributes) {
  139.     {
  140.         options
  141.         {
  142.             { validOperations {get add remove} }
  143.             { validFilters {} }
  144.             { dataType set }
  145.         }
  146.     }
  147. }
  148. set sco_dhcpGlobal_CDT(groups) {}
  149. set sco_dhcpGlobal_CDT(operations) {
  150.     {
  151.         get
  152.         {
  153.             { granularity perObject }
  154.             { function dhcpGlobal_get }
  155.         }
  156.     }
  157.     {
  158.         add
  159.         {
  160.             { granularity perObject }
  161.             { function dhcpGlobal_add }
  162.         }
  163.     }
  164.     {
  165.         remove
  166.         {
  167.             { granularity perObject }
  168.             { function dhcpGlobal_remove }
  169.         }
  170.     }
  171.     {
  172.         list
  173.         {
  174.             { granularity perObject }
  175.             { function dhcpGlobal_list }
  176.         }
  177.     }
  178. }
  179. set sco_dhcpGlobal_CDT(class) {sco dhcpGlobal}
  180. set sco_dhcpGlobal_CDT(superior) {sco dhcpGlobal}
  181. set sco_dhcpGlobal_CDT(subordinates) {{sco dhcpGlobal}}
  182. set sco_dhcpOption_CDT(attributes) {
  183.     {
  184.         options
  185.         {
  186.             { validOperations {get add remove} }
  187.             { validFilters {} }
  188.             { dataType set }
  189.         }
  190.     }
  191. }
  192. set sco_dhcpOption_CDT(groups) {}
  193. set sco_dhcpOption_CDT(operations) {
  194.     {
  195.         get
  196.         {
  197.             { granularity perObject }
  198.             { function dhcpOption_get }
  199.         }
  200.     }
  201.     {
  202.         add
  203.         {
  204.             { granularity perObject }
  205.             { function dhcpOption_add }
  206.         }
  207.     }
  208.     {
  209.         remove
  210.         {
  211.             { granularity perObject }
  212.             { function dhcpOption_remove }
  213.         }
  214.     }
  215.     {
  216.         list
  217.         {
  218.             { granularity perObject }
  219.             { function dhcpOption_list }
  220.         }
  221.     }
  222. }
  223. set sco_dhcpOption_CDT(class) {sco dhcpOption}
  224. set sco_dhcpOption_CDT(superior) {sco dhcpOption}
  225. set sco_dhcpOption_CDT(subordinates) {{sco dhcpOption}}
  226. set sco_dhcpUserClass_CDT(attributes) {
  227.     {
  228.         options
  229.         {
  230.             { validOperations {get add remove} }
  231.             { validFilters {} }
  232.             { dataType set }
  233.         }
  234.     }
  235. }
  236. set sco_dhcpUserClass_CDT(groups) {}
  237. set sco_dhcpUserClass_CDT(operations) {
  238.     {
  239.         get
  240.         {
  241.             { granularity perObject }
  242.             { function dhcpUserClass_get }
  243.         }
  244.     }
  245.     {
  246.         add
  247.         {
  248.             { granularity perObject }
  249.             { function dhcpUserClass_add }
  250.         }
  251.     }
  252.     {
  253.         remove
  254.         {
  255.             { granularity perObject }
  256.             { function dhcpUserClass_remove }
  257.         }
  258.     }
  259.     {
  260.         list
  261.         {
  262.             { granularity perObject }
  263.             { function dhcpUserClass_list }
  264.         }
  265.     }
  266. }
  267. set sco_dhcpUserClass_CDT(class) {sco dhcpUserClass}
  268. set sco_dhcpUserClass_CDT(superior) {sco dhcpUserClass}
  269. set sco_dhcpUserClass_CDT(subordinates) {{sco dhcpUserClass}}
  270. set sco_dhcpClient_CDT(attributes) {
  271.     {
  272.         options
  273.         {
  274.             { validOperations {get add remove} }
  275.             { validFilters {} }
  276.             { dataType set }
  277.         }
  278.     }
  279. }
  280. set sco_dhcpClient_CDT(groups) {}
  281. set sco_dhcpClient_CDT(operations) {
  282.     {
  283.         get
  284.         {
  285.             { granularity perObject }
  286.             { function dhcpClient_get }
  287.         }
  288.     }
  289.     {
  290.         add
  291.         {
  292.             { granularity perObject }
  293.             { function dhcpClient_add }
  294.         }
  295.     }
  296.     {
  297.         remove
  298.         {
  299.             { granularity perObject }
  300.             { function dhcpClient_remove }
  301.         }
  302.     }
  303.     {
  304.         list
  305.         {
  306.             { granularity perObject }
  307.             { function dhcpClient_list }
  308.         }
  309.     }
  310. }
  311. set sco_dhcpClient_CDT(class) {sco dhcpClient}
  312. set sco_dhcpClient_CDT(superior) {sco dhcpClient}
  313. set sco_dhcpClient_CDT(subordinates) {{sco dhcpClient}}
  314. set sco_dhcpStandard_CDT(attributes) {
  315.     {
  316.         options
  317.         {
  318.             { validOperations {get add remove} }
  319.             { validFilters {} }
  320.             { dataType set }
  321.         }
  322.     }
  323. }
  324. set sco_dhcpStandard_CDT(groups) {}
  325. set sco_dhcpStandard_CDT(operations) {
  326.     {
  327.         get
  328.         {
  329.             { granularity perObject }
  330.             { function dhcpStandard_get }
  331.         }
  332.     }
  333.     {
  334.         add
  335.         {
  336.             { granularity perObject }
  337.             { function dhcpStandard_add }
  338.         }
  339.     }
  340.     {
  341.         remove
  342.         {
  343.             { granularity perObject }
  344.             { function dhcpStandard_remove }
  345.         }
  346.     }
  347.     {
  348.         list
  349.         {
  350.             { granularity perObject }
  351.             { function dhcpStandard_list }
  352.         }
  353.     }
  354. }
  355. set sco_dhcpStandard_CDT(class) {sco dhcpStandard}
  356. set sco_dhcpStandard_CDT(superior) {sco dhcpStandard}
  357. set sco_dhcpStandard_CDT(subordinates) {{sco dhcpStandard}}
  358. set sco_dhcpSubnet_CDT(attributes) {
  359.     {
  360.         options
  361.         {
  362.             { validOperations {get add remove} }
  363.             { validFilters {} }
  364.             { dataType set }
  365.         }
  366.     }
  367. }
  368. set sco_dhcpSubnet_CDT(groups) {}
  369. set sco_dhcpSubnet_CDT(operations) {
  370.     {
  371.         get
  372.         {
  373.             { granularity perObject }
  374.             { function dhcpSubnet_get }
  375.         }
  376.     }
  377.     {
  378.         add
  379.         {
  380.             { granularity perObject }
  381.             { function dhcpSubnet_add }
  382.         }
  383.     }
  384.     {
  385.         remove
  386.         {
  387.             { granularity perObject }
  388.             { function dhcpSubnet_remove }
  389.         }
  390.     }
  391.     {
  392.         list
  393.         {
  394.             { granularity perObject }
  395.             { function dhcpSubnet_list }
  396.         }
  397.     }
  398. }
  399. set sco_dhcpSubnet_CDT(class) {sco dhcpSubnet}
  400. set sco_dhcpSubnet_CDT(superior) {sco dhcpSubnet}
  401. set sco_dhcpSubnet_CDT(subordinates) {{sco dhcpSubnet}}
  402. #@package: lineman lm_construct lm_destruct \
  403.     lm_addLine lm_remLine lm_isValidIndex lm_getLine lm_putLine \
  404.     lm_firstIndex lm_nextIndex lm_prevIndex lm_numLines
  405. ##################################################
  406. proc lm_construct {} {
  407.     global lm_gen lm_indices lm_next
  408.     if {![info exists lm_gen]} {
  409.         set lm_gen 0
  410.     }
  411.     set lmh $lm_gen
  412.     incr lm_gen
  413.     set lm_indices($lmh) ""
  414.     set lm_next($lmh) 1
  415.     return $lmh
  416. }
  417. proc lm_destruct {lmh} {
  418.     global lm_indices
  419.     foreach index $lm_indices($lmh) {
  420.         lm_remLine $lmh $index
  421.     }
  422. }
  423. proc lm_addLine {lmh where line} {
  424.     global lm_indices lm_lines lm_next
  425.     set new_index new_${lmh}_$lm_next($lmh)
  426.     incr lm_next($lmh)
  427.     set lm_lines($new_index) $line
  428.     if {[cequal $where end]} {
  429.         set pos $where
  430.     } else {
  431.         set pos [lsearch $lm_indices($lmh) $where]
  432.         if {$pos == -1} {
  433.             set pos end
  434.         }
  435.     }
  436.     set lm_indices($lmh) [linsert $lm_indices($lmh) $pos $new_index]
  437.     return $new_index
  438. }
  439. proc lm_remLine {lmh index} {
  440.     global lm_indices lm_lines
  441.     set pos [lsearch $lm_indices($lmh) $index]
  442.     if {$pos == -1} {
  443.         return 1
  444.     }
  445.     unset lm_lines($index)
  446.     lvarpop lm_indices($lmh) $pos
  447.     return 0
  448. }
  449. proc lm_isValidIndex {lmh index} {
  450.     global lm_indices
  451.     set pos [lsearch $lm_indices($lmh) $index]
  452.     if {$pos == -1} {
  453.         return 0
  454.     }
  455.     return 1
  456. }
  457. proc lm_getLine {lmh index} {
  458.     global lm_indices lm_lines
  459.     set pos [lsearch $lm_indices($lmh) $index]
  460.     if {$pos == -1} {
  461.         return ""
  462.     }
  463.     return $lm_lines($index)
  464. }
  465. proc lm_putLine {lmh index line} {
  466.     global lm_indices lm_lines
  467.     set pos [lsearch $lm_indices($lmh) $index]
  468.     if {$pos == -1} {
  469.         return "" 
  470.     }
  471.     set lm_lines($index) $line
  472.     return $lm_lines($index)
  473. }
  474. proc lm_firstIndex {lmh} {
  475.     global lm_indices
  476.     if {[lempty $lm_indices($lmh)]} {
  477.         return -1
  478.     }
  479.     return [lindex $lm_indices($lmh) 0]
  480. }
  481. proc lm_nextIndex {lmh index} {
  482.     global lm_indices
  483.     set pos [lsearch $lm_indices($lmh) $index]
  484.     if {$pos == -1} {
  485.         return $pos
  486.     }
  487.     incr pos
  488.     if {$pos >= [llength $lm_indices($lmh)]} {
  489.         return -1
  490.     }
  491.     return [lindex $lm_indices($lmh) $pos]
  492. }
  493. proc lm_prevIndex {lmh index} {
  494.     global lm_indices
  495.     set pos [lsearch $lm_indices($lmh) $index]
  496.     if {$pos == -1} {
  497.         return $pos
  498.     }
  499.     incr pos -1
  500.     if {$pos < 0} {
  501.         return -1
  502.     }
  503.     return [lindex $lm_indices($lmh) $pos]
  504. }
  505. proc lm_numLines {lmh} {
  506.     global lm_indices
  507.     return [llength $lm_indices($lnh)]
  508. }
  509. ##################################################
  510. #@packend
  511. proc checkIPaddr {addr} {
  512.     if { [lempty $addr] } {
  513.     return 0
  514.     }
  515.     set match [regsub {^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$} $addr \
  516.            {\1 \2 \3 \4} octets]
  517.     if { ! $match } {
  518.     return 0
  519.     } else {
  520.     foreach octet $octets {
  521.         if { $octet < 0 || $octet > 255 } {
  522.         return 0
  523.         }
  524.     }
  525.     }
  526.     return 1
  527. }
  528. proc checkIPwidgetCB {form cbs} {
  529.     set value  [keylget cbs value]
  530.     set widget [keylget cbs widget]
  531.     set a_addr [VxGetVar $form a_addr]
  532.     set b_addr [VxGetVar $form b_addr]
  533.     set c_addr [VxGetVar $form c_addr]
  534.     set d_addr [VxGetVar $form d_addr]
  535.     set userCheckIPwidget [VxGetVar $form userCheckIPwidget]
  536.     set skip 0
  537.     set length [string length $value]
  538.     if {$length == 0} {
  539.     return
  540.     }
  541.     if {$length >= 3} {
  542.     set skip 1
  543.     }
  544.     if {[string range $value [expr $length - 1] end] == "."} {
  545.     set skip 1
  546.     set value [string range $value 0 [expr $length - 2]]
  547.     VtSetValues $widget -value $value
  548.     }
  549.     if {![ctype digit $value]} then {
  550.     VtBeep
  551.     VtSetValues $widget -value ""
  552.     return
  553.     }
  554.     if {$value < 0 || $value > 255} then {
  555.     VtBeep
  556.     VtSetValues $widget -value ""
  557.     return
  558.     }
  559.     if {$skip} then {
  560.     if {$widget == $a_addr} {VtSetFocus $b_addr}
  561.     if {$widget == $b_addr} {VtSetFocus $c_addr}
  562.     if {$widget == $c_addr} {VtSetFocus $d_addr}
  563.     }
  564.     if {[string length $userCheckIPwidget]} {
  565.     $userCheckIPwidget $cbs
  566.     }
  567. }
  568. proc getIPwidgetValue {widget} {
  569.     set a_addr [VxGetVar $widget a_addr]
  570.     set b_addr [VxGetVar $widget b_addr]
  571.     set c_addr [VxGetVar $widget c_addr]
  572.     set d_addr [VxGetVar $widget d_addr]
  573.     set value "[VtGetValues $a_addr -value]"
  574.     append value "."
  575.     append value "[VtGetValues $b_addr -value]"
  576.     append value "."
  577.     append value "[VtGetValues $c_addr -value]"
  578.     append value "."
  579.     append value "[VtGetValues $d_addr -value]"
  580.     return $value
  581. }
  582. proc setIPwidgetValue {widget value} {
  583.     set a_addr [VxGetVar $widget a_addr]
  584.     set b_addr [VxGetVar $widget b_addr]
  585.     set c_addr [VxGetVar $widget c_addr]
  586.     set d_addr [VxGetVar $widget d_addr]
  587.     set values [split $value "."]
  588.     VtSetValues $a_addr -value [lindex $values 0]
  589.     VtSetValues $b_addr -value [lindex $values 1]
  590.     VtSetValues $c_addr -value [lindex $values 2]
  591.     VtSetValues $d_addr -value [lindex $values 3]
  592.     VtSetFocus    $a_addr
  593. }
  594. proc createIPwidget {form value shortHelp {userCheckIPwidget {}}} {
  595.     set values [split $value "."]
  596.     set a_addr [VtText $form.a -columns 3 \
  597.         -value [lindex $values 0] \
  598.         -callback "SaSetFocus next" \
  599.         -valueChangedCallback "checkIPwidgetCB $form" \
  600.         -shortHelpCallback SaShortHelpCB \
  601.         -shortHelpString "[IntlLocalizeMsg $shortHelp]" ]
  602.     set a_label [VtLabel $form.al -label "." \
  603.         -leftOffset 0 \
  604.         -leftSide $a_addr -alignTop $a_addr]
  605.     set b_addr [VtText $form.b -columns 3 \
  606.         -value [lindex $values 1] \
  607.         -callback "SaSetFocus next" \
  608.         -valueChangedCallback "checkIPwidgetCB $form" \
  609.         -leftOffset 0 \
  610.         -leftSide $a_label -alignTop $a_label \
  611.         -shortHelpCallback SaShortHelpCB \
  612.         -shortHelpString "[IntlLocalizeMsg $shortHelp]" ]
  613.     set b_label [VtLabel $form.bl -label "." \
  614.         -leftOffset 0 \
  615.         -leftSide $b_addr -alignTop $b_addr]
  616.     set c_addr [VtText $form.c -columns 3 \
  617.         -value [lindex $values 2] \
  618.         -callback "SaSetFocus next" \
  619.         -valueChangedCallback "checkIPwidgetCB $form" \
  620.         -leftOffset 0 \
  621.         -leftSide $b_label -alignTop $b_label \
  622.         -shortHelpCallback SaShortHelpCB \
  623.         -shortHelpString "[IntlLocalizeMsg $shortHelp]" ]
  624.     set c_label [VtLabel $form.cl -label "." \
  625.         -leftOffset 0 \
  626.         -leftSide $c_addr -alignTop $c_addr]
  627.     set d_addr [VtText $form.d -columns 3 \
  628.         -value [lindex $values 3] \
  629.         -callback "SaSetFocus next" \
  630.         -valueChangedCallback "checkIPwidgetCB $form" \
  631.         -leftSide $c_label -alignTop $c_label \
  632.         -leftOffset 0 \
  633.         -shortHelpCallback SaShortHelpCB \
  634.         -shortHelpString "[IntlLocalizeMsg $shortHelp]" ]
  635.     VxSetVar $form a_addr $a_addr
  636.     VxSetVar $form b_addr $b_addr
  637.     VxSetVar $form c_addr $c_addr
  638.     VxSetVar $form d_addr $d_addr
  639.     VxSetVar $form userCheckIPwidget $userCheckIPwidget
  640. }
  641. ##################################################
  642. ##################################################
  643. proc dhcp:init_standard_opts {} {
  644.     global DHCP_OPTS_FILE standard_list
  645.     if {![owner file readable $DHCP_OPTS_FILE]} {
  646.     ErrorPush {} 1 SCO_DHCPOSA_ERR_NO_OPT_FILE $DHCP_OPTS_FILE
  647.     return
  648.     }
  649.     if {[info exists standard_list]} {
  650.     unset standard_list
  651.     }
  652.     net:for_file entry $DHCP_OPTS_FILE {
  653.     if {[cindex $entry 0] == "#" || \
  654.         [cindex $entry 0] == "" || \
  655.         [cindex $entry 0] == "\n"} {
  656.         continue
  657.     }
  658.     set code    [lindex $entry 0]
  659.     set name    [lindex $entry 1] 
  660.     set comment [lindex $entry 2]
  661.     set type [lindex $entry 3] 
  662.     if {[crange $type 0 0] == "+"} {
  663.         set array 1
  664.         set type [crange $type 1 end]
  665.     } else {
  666.         set array 0
  667.     }
  668.     set default [lindex $entry 4]
  669.     keylset option code    $code 
  670.     keylset option comment $comment
  671.     keylset option type    $type
  672.     keylset option array   $array 
  673.     keylset option default $default 
  674.     set standard_list($name) $option
  675.     }
  676.     return
  677. } ;# init_standard_opts
  678. proc dhcp:write {} {
  679.     global DHCP_CONF_FILE dhcp_lmh dhcp_lmi
  680.     if {[owner file exists $DHCP_CONF_FILE]} {
  681.     if {![owner file writable $DHCP_CONF_FILE]} {
  682.         ErrorPush {} 1 SCO_DHCPOSA_ERR_WRITE_PERMISSION \
  683.         "$DHCP_CONF_FILE"
  684.         return
  685.     }
  686.     if {[catch {owner exec /bin/cp $DHCP_CONF_FILE ${DHCP_CONF_FILE}-}]} {
  687.         ErrorPush {} 1 SCO_DHCPOSA_ERR_WRITE_BACKUP "$DHCP_CONF_FILE"
  688.         return
  689.     }
  690.     set inet_add 0
  691.     } else {
  692.     set inet_add 1
  693.     }
  694.     if {[catch {ownerOpen writefile $DHCP_CONF_FILE w} fd]} {
  695.     ErrorPush {} 1 SCO_DHCPOSA_ERR_OPEN "$DHCP_CONF_FILE"
  696.     return
  697.     }
  698.     set lmi [lm_firstIndex $dhcp_lmh]
  699.     if {$lmi == -1} {
  700.         close $fd
  701.     owner unlink -nocomplain $DHCP_CONF_FILE
  702.     ErrorCatch {} 1 "dhcp:inet_remove_entry" ret
  703.     } else {
  704.     while {$lmi != -1} {
  705.         puts $fd [lm_getLine $dhcp_lmh $lmi]
  706.         set lmi [lm_nextIndex $dhcp_lmh $lmi]
  707.     }
  708.         close $fd
  709.     if {$inet_add} {
  710.         ErrorCatch {} 1 "dhcp:inet_add_entry" ret
  711.     }
  712.     }
  713. } ;# dhcp:write
  714. proc ServerGetDefaultInfo {} {
  715.     keylset entry lease_res       600
  716.     keylset entry lease_pad       1
  717.     keylset entry address_probe   true
  718.     keylset entry option_overload false
  719.     return $entry
  720. } ;# ServerGetDefaultInfo
  721. proc ServerAddDefault {serverInfo} {
  722.     set serverDefault [ServerGetDefaultInfo]
  723.     set defaultKeys [keylkeys serverDefault]
  724.     set keys [keylkeys serverInfo]
  725.     set results [intersect3 $defaultKeys $keys]
  726.     set unused [lindex $results 0]
  727.     foreach key $unused {
  728.     keylset serverInfo $key [keylget serverDefault $key]
  729.     }
  730.     return $serverInfo
  731. } ;# ServerAddDefault
  732. proc ServerRemDefault {serverInfo} {
  733.     set serverDefault [ServerGetDefaultInfo]
  734.     set defaultKeys [keylkeys serverDefault]
  735.     set keys [keylkeys serverInfo]
  736.     set results [intersect3 $defaultKeys $keys]
  737.     set used [lindex $results 1]
  738.     foreach key $used {
  739.     keylget serverDefault $key defValue
  740.     keylget serverInfo $key value
  741.     if {[cequal $value $defValue]} {
  742.         keyldel serverInfo $key
  743.     }
  744.     }
  745.     return $serverInfo
  746. } ;# ServerRemDefault
  747. proc dhcp:comment_get_option {type tag parameter line lmi} {
  748.     global subnet_list       subnet_lmi
  749.     global client_list       client_lmi
  750.     global user_class_list   user_class_lmi
  751.     global vendor_class_list vendor_class_lmi
  752.     global global_list       global_lmi
  753.     global option_list         option_lmi
  754.     if {![cequal comment $parameter]} {  
  755.     return 0
  756.     }
  757.     set entryTypes [list subnet client user_class vendor_class global option]
  758.     if {$type == 0} {
  759.     ErrorPush {} 1 SCO_DHCPOSA_ERR_NO_DEFINITION "$parameter valid" 
  760.     return -1
  761.     } 
  762.     if {[lsearch $entryTypes $type] == -1} {
  763.     ErrorPush {} 1 SCO_DHCPOSA_ERR_UNEXPECTED_OPTION "$parameter"
  764.     return -1
  765.     }
  766.     regexp {^[     ]*comment[     ]+([^     ].*)} $line tmp value 
  767.     set def_list [format %s_list(%s) $type $tag]
  768.     set def_lmi  [format %s_lmi(%s) $type $tag]
  769.     set entry [set $def_list]
  770.     keylset entry $parameter $value
  771.     set $def_list $entry
  772.     lappend $def_lmi $lmi
  773.     return 1
  774. } ;# dhcp:comment_get_option
  775. proc dhcp:subnet_get_options {type tag parameter value lmi} {
  776.     global subnet_list subnet_lmi
  777.     if {[lsearch [list mask pool lease_dflt lease_max t1 t2] $parameter] \
  778.     == -1} {  
  779.     return 0
  780.     }
  781.     if {$type == 0} {
  782.     ErrorPush {} 1 SCO_DHCPOSA_ERR_NO_DEFINITION "$parameter subnet"
  783.     return -1
  784.     } 
  785.     if {![cequal $type subnet]} {
  786.     ErrorPush {} 1 SCO_DHCPOSA_ERR_INVALID_DEFINITION "subnet mask \
  787.         $type" 
  788.     return -1
  789.     }
  790.     switch $parameter {
  791.     mask {
  792.     }
  793.     pool {
  794.     }
  795.     lease_dflt {
  796.     }
  797.     lease_max {
  798.     }
  799.     t1 {
  800.     }
  801.     t2 {
  802.     }
  803.     }
  804.     set entry $subnet_list($tag) 
  805.     keylset entry $parameter $value
  806.     set subnet_list($tag) $entry
  807.     lappend subnet_lmi($tag) $lmi
  808.     return 1
  809. } ;# dhcp:subnet_get_options
  810. proc dhcp:client_get_options {type tag parameter value lmi} {
  811.     global client_list client_lmi
  812.     if {[lsearch [list ip_address] $parameter] == -1} {  
  813.     return 0
  814.     }
  815.     if {$type == 0} {
  816.     ErrorPush {} 1 SCO_DHCPOSA_ERR_NO_DEFINITION "$parameter client"
  817.     return -1
  818.     } 
  819.     if {![cequal $type client]} {
  820.     ErrorPush {} 1 SCO_DHCPOSA_ERR_INVALID_DEFINITION "client mask \
  821.         $type" 
  822.     return -1
  823.     }
  824.     switch $parameter {
  825.     ip_address {
  826.         if {![checkIPaddr $value]} {
  827.         ErrorPush {} 1 SCO_DHCPOSA_ERR_INVALID_CLIENT_IP "$value"
  828.         return -1
  829.         }
  830.     }
  831.     }
  832.     set entry $client_list($tag)
  833.     keylset entry $parameter $value
  834.     set client_list($tag) $entry
  835.     lappend client_lmi($tag) $lmi
  836.     return 1
  837. } ;# dhcp:client_get_options
  838. proc dhcp:option_get_options {type tag parameter line lmi} {
  839.     global option_list option_lmi
  840.     if {[lsearch [list name type min_val max_val min_length max_length] \
  841.     $parameter] == -1} {  
  842.     return 0
  843.     }
  844.     if {$type == 0} {
  845.     ErrorPush {} 1 SCO_DHCPOSA_ERR_NO_DEFINITION "$parameter option"
  846.     return -1
  847.     } 
  848.     if {![cequal $type option]} {
  849.     return 0 
  850.     }
  851.     switch $parameter {
  852.     type {
  853.         set type  {}
  854.         set array {}
  855.             regexp {^[     ]*type[     ]*([^     ]*)[     ]*([^     ]*)} $line \
  856.         tmp type array
  857.         if {[string length $array]} {
  858.         set value "$type $array"
  859.         } else {
  860.         set value $type
  861.         }
  862.     }
  863.     name       -
  864.     min_val       - 
  865.     max_val       - 
  866.     min_length - 
  867.     max_length {
  868.             regexp {^[     ]*([^     ]*)[     ]*([^     ]*)[     ]*} $line tmp \
  869.         ptmp value
  870.     }
  871.     }
  872.     set entry $option_list($tag)
  873.     keylset entry $parameter $value 
  874.     set option_list($tag) $entry
  875.     lappend option_lmi($tag) $lmi
  876.     return 1
  877. } ;# dhcp:option_get_options
  878. proc dhcp:server_get_options {type tag parameter value lmi} {
  879.     global server_list server_lmi
  880.     if {[lsearch [list name option_overload lease_res lease_pad address_probe] \
  881.     $parameter] == -1} {  
  882.     return 0
  883.     }
  884.     if {$type == 0} {
  885.     ErrorPush {} 1 SCO_DHCPOSA_ERR_NO_DEFINITION "$parameter server"
  886.     return -1
  887.     } 
  888.     if {![cequal $type server]} {
  889.     ErrorPush {} 1 SCO_DHCPOSA_ERR_INVALID_DEFINITION "server $parameter \
  890.         $type"
  891.     return -1 
  892.     }
  893.     switch $parameter {
  894.     option_overload -
  895.     address_probe {
  896.         if {![cequal $value true] && ![cequal $value false]} {
  897.         ErrorPush {} 1 SCO_DHCPOSA_ERR_OPTION_BOOLEAN_VALUE \
  898.         "$parameter $value"
  899.         return -1 
  900.         }
  901.     }
  902.     default {
  903.         if {![ctype digit $value]} {
  904.         ErrorPush {} 1 SCO_DHCPOSA_ERR_INVALID_OPTION_TYPE \
  905.         "$parameter $value"
  906.         return -1 
  907.         }
  908.     }
  909.     }
  910.     set entry $server_list($tag)
  911.     keylset entry $parameter $value 
  912.     set server_list($tag) $entry
  913.     lappend server_lmi($tag) $lmi
  914.     return 1
  915. } ;# dhcp:server_get_options
  916. proc dhcp:standard_get_options {type tag parameter value lmi} {
  917.     global subnet_list       subnet_lmi
  918.     global client_list       client_lmi
  919.     global user_class_list   user_class_lmi
  920.     global vendor_class_list vendor_class_lmi
  921.     global global_list       global_lmi
  922.     global standard_list     standard_lmi
  923.     set standardOpts [array names standard_list]
  924.     if {[lsearch $standardOpts $parameter] == -1} {  
  925.     return 0
  926.     }
  927.     set entryTypes [list subnet client user_class vendor_class global]
  928.     if {$type == 0} {
  929.     ErrorPush {} 1 SCO_DHCPOSA_ERR_NO_DEFINITION "$parameter valid" 
  930.     return -1
  931.     } 
  932.     if {[lsearch $entryTypes $type] == -1} {
  933.     ErrorPush {} 1 SCO_DHCPOSA_ERR_UNEXPECTED_OPTION "$parameter"
  934.     return -1
  935.     }
  936.     set std_list [format %s_list(%s) $type $tag]
  937.     set std_lmi  [format %s_lmi(%s) $type $tag]
  938.     set entry [set $std_list]
  939.     keylset entry $parameter $value
  940.     set $std_list $entry
  941.     lappend $std_lmi $lmi
  942.     return 1
  943. } ;# dhcp:standard_get_options
  944. proc dhcp:user_get_options {type tag parameter value lmi} {
  945.     global subnet_list       subnet_lmi
  946.     global client_list       client_lmi
  947.     global user_class_list   user_class_lmi
  948.     global vendor_class_list vendor_class_lmi
  949.     global global_list       global_lmi
  950.     global option_list       option_lmi
  951.     if {![regexp {option([0-9]*)} $parameter t_all code]} {
  952.     return 0
  953.     }
  954.     if [info exists option_list] {
  955.     set options [array names option_list]
  956.     } else {
  957.     set options {}
  958.     }
  959.     if {[lsearch $options $code] == -1} {
  960.     return 0
  961.     }
  962.     set entryTypes [list subnet client user_class vendor_class global]
  963.     if {$type == 0} {
  964.     ErrorPush {} 1 SCO_DHCPOSA_ERR_NO_DEFINITION "$parameter valid" 
  965.     return -1
  966.     } 
  967.     if {[lsearch $entryTypes $type] == -1} {
  968.     ErrorPush {} 1 SCO_DHCPOSA_ERR_UNEXPECTED_OPTION "$parameter"
  969.     return -1
  970.     }
  971.     set std_list [format %s_list(%s) $type $tag]
  972.     set std_lmi  [format %s_lmi(%s) $type $tag]
  973.     set entry [set $std_list]
  974.     keylset entry $parameter $value
  975.     set $std_list $entry
  976.     lappend $std_lmi $lmi
  977.     return 1
  978. } ;# dhcp:user_get_options
  979. proc dhcp:read {} {
  980.     global DHCP_CONF_FILE dhcp_lmh
  981.     global client_list       client_lmi
  982.     global global_list       global_lmi
  983.     global option_list       option_lmi
  984.     global server_list         server_lmi
  985.     global subnet_list       subnet_lmi 
  986.     global user_class_list   user_class_lmi
  987.     global vendor_class_list vendor_class_lmi
  988.     global standard_list
  989.     if {[info exists subnet_list]} {
  990.     unset subnet_list
  991.     }
  992.     if {[info exists subnet_lmi]} {
  993.     unset subnet_lmi
  994.     }
  995.     set dhcp_lmh [lm_construct]
  996.     set defType   {}
  997.     set defTag    {}
  998.     set arrayType {}
  999.     if {![owner file exists $DHCP_CONF_FILE]} {
  1000.     return
  1001.     }
  1002.     if {![owner file readable $DHCP_CONF_FILE]} {
  1003.     ErrorPush {} 1 SCO_DHCPOSA_ERR_READ_PERMISSION "$DHCP_CONF_FILE"
  1004.     return
  1005.     }
  1006.     if {[catch {ownerOpen readfile $DHCP_CONF_FILE r} fd]} {
  1007.     ErrorPush {} 1 SCO_DHCPOSA_ERR_OPEN "$DHCP_CONF_FILE"
  1008.     return
  1009.     }
  1010.     set sc [scancontext create]
  1011.     scanmatch $sc {^.*} {
  1012.     set lmi [lm_addLine $dhcp_lmh end "$matchInfo(line)"]
  1013.     }
  1014.     scanmatch $sc {^[    ]*$} {
  1015.     continue
  1016.     }
  1017.     scanmatch $sc {^[    ]*#.*$} {
  1018.     continue
  1019.     }
  1020.     set entryTypes [list client global option server subnet user_class \
  1021.     vendor_class]
  1022.     scanmatch $sc {\{[     ]*$} {
  1023.     set line $matchInfo(line)
  1024.     regexp \
  1025.         {^[     ]*([a-z_0-9]*)[     ]*([^     ]*)[     ]*([^     ]*)[     ]*} \
  1026.         $line tmp type tag var
  1027.     if {[lsearch $entryTypes $type] != -1} {
  1028.         if {[string length $defType]} {
  1029.         ErrorPush {} 1 SCO_DHCPOSA_ERR_UNEXPECTED_DEFINITION "$type \
  1030.             $defType"
  1031.         return
  1032.         } else {
  1033.         set defType $type 
  1034.         }
  1035.         set entry {}
  1036.         switch $type {
  1037.         client {
  1038.             if {[cequal opaque $tag]} {
  1039.             set defTag [string trim $var "\""]
  1040.                 keylset entry identifier_type opaque
  1041.             } else {
  1042.             set defTag [format "%s_%s" $tag $var]
  1043.                 keylset entry identifier_type hardware
  1044.             }
  1045.         }
  1046.         global {
  1047.             set defTag global
  1048.         }
  1049.         option {
  1050.             if {![ctype digit $tag]} {
  1051.             ErrorPush {} 1 SCO_DHCPOSA_ERR_INVALID_OPTION_TYPE \
  1052.                 "code $defTag"
  1053.             return
  1054.             }
  1055.             if {$tag < 128 || $tag > 254} {
  1056.             ErrorPush {} 1 SCO_DHCPOSA_ERR_INVALID_OPTION_RANGE \
  1057.                 "code $defTag"
  1058.             }
  1059.             set defTag $tag
  1060.         }
  1061.         server {
  1062.             set defTag server
  1063.         }
  1064.         subnet {
  1065.             set defTag  $tag
  1066.             if {![checkIPaddr $defTag]} {
  1067.             ErrorPush {} 1 SCO_DHCPOSA_ERR_INVALID_SUBNET "$defTag"
  1068.             return
  1069.             }
  1070.         }
  1071.         user_class {
  1072.             set defTag [string trim $tag "\""]
  1073.         }
  1074.         vendor_class {
  1075.             set defTag [string trim $tag "\""]
  1076.         }
  1077.         }
  1078.         set list [format %s_list $type]
  1079.         if {[info exists $list] && \
  1080.         [lsearch [array names $list] $defTag] != -1} {
  1081.         ErrorPush {} 1 SCO_DHCPOSA_ERR_DEF_EXISTS "$defType $defTag"
  1082.         return
  1083.         } else {
  1084.         set list_entry [format %s_list(%s) $defType $defTag]
  1085.         set lmi_entry  [format %s_lmi(%s)  $defType $defTag]
  1086.         set $list_entry $entry 
  1087.         lappend $lmi_entry $lmi
  1088.         }
  1089.     } else {
  1090.         if {![string length $defType] || \
  1091.         [lsearch $entryTypes $defType] == -1 ||
  1092.         ![string length $defTag]} {
  1093.         ErrorPush {} 1 SCO_DHCPOSA_ERR_UNEXPECTED_ARRAY "$type" 
  1094.         return
  1095.         } 
  1096.         set standardOpts [array names standard_list]
  1097.         if [info exists option_list] {
  1098.         set userOpts [array names option_list] 
  1099.         } else {
  1100.         set userOpts {}
  1101.         }
  1102.         set found 0
  1103.         if {[regexp {option([0-9]*)} $type t_all code]} {
  1104.         if {[lsearch $userOpts $code] != -1} {  
  1105.             set found 1
  1106.         }
  1107.         }
  1108.         if {!$found && [lsearch $standardOpts $type] == -1} {
  1109.         ErrorPush {} 1 SCO_DHCPOSA_ERR_UNEXPECTED_ARRAY "$type" 
  1110.         return
  1111.         }
  1112.         set arrayType  $type
  1113.         set array_list {}
  1114.         lappend array_lmi $lmi 
  1115.     }
  1116.     continue
  1117.     }
  1118.     scanmatch $sc {^[     ]*\}[     ]*$} {
  1119.     if {![string length $defType] || ![info exists tag]} {
  1120.         ErrorPush {} 1 SCO_DHCPOSA_ERR_DEF_TERMINATION
  1121.         return
  1122.     }
  1123.     if {[string length $arrayType]} {
  1124.         if {![info exists array_list] || ![info exists array_lmi]} {
  1125.         ErrorPush {} 1 SCO_DHCPOSA_ERR_ARRAY_TERMINATION
  1126.         return
  1127.         }
  1128.         set list_entry [format %s_list(%s) $defType $defTag]
  1129.         set lmi_entry  [format %s_lmi(%s)  $defType $defTag]
  1130.         set entry [set $list_entry]
  1131.         keylset entry $arrayType $array_list
  1132.         set $list_entry $entry
  1133.         lappend array_lmi $lmi
  1134.         set $lmi_entry [concat [set $lmi_entry] $array_lmi]
  1135.         set arrayType {}
  1136.     } else {
  1137.         set lmi_entry  [format %s_lmi(%s)  $defType $defTag]
  1138.         lappend $lmi_entry $lmi
  1139.         set defType {} 
  1140.         set defTag  {}
  1141.     }
  1142.     continue
  1143.     }
  1144.     scanmatch $sc {^[     ]*([^     ]*)[     ]*([^     ]*)[     ]*} {
  1145.         set line    $matchInfo(line)
  1146.     set parameter    $matchInfo(submatch0)
  1147.     set value    $matchInfo(submatch1)
  1148.     if {[dhcp:comment_get_option $defType $defTag $parameter $line $lmi]} {
  1149.         continue
  1150.     } 
  1151.     if {[dhcp:subnet_get_options $defType $defTag $parameter $value $lmi]} {
  1152.         continue
  1153.     } 
  1154.     if {[dhcp:client_get_options $defType $defTag $parameter $value $lmi]} {
  1155.         continue
  1156.     }
  1157.     if {[dhcp:option_get_options $defType $defTag $parameter $line $lmi]} {
  1158.         continue
  1159.     } 
  1160.     if {[dhcp:standard_get_options $defType $defTag $parameter $value \
  1161.         $lmi]} {
  1162.         continue
  1163.     }
  1164.     if {[dhcp:user_get_options $defType $defTag $parameter $value \
  1165.         $lmi]} {
  1166.         continue
  1167.     }
  1168.     if {[dhcp:server_get_options $defType $defTag $parameter $value \
  1169.         $lmi]} {
  1170.         continue
  1171.     }
  1172.     if {[string length $arrayType]} {
  1173.         set array_list [concat $array_list $line]
  1174.         lappend array_lmi  $lmi
  1175.         continue
  1176.     }
  1177.     }
  1178.     scanfile $sc $fd
  1179.     close $fd
  1180.     scancontext delete $sc
  1181. } ;# dhcp:read
  1182. proc dhcp:defAdd {type object optionList} {
  1183.     global dhcp_lmh 
  1184.     global client_lmi       client_list
  1185.     global global_lmi       global_list
  1186.     global option_lmi       option_list
  1187.     global server_lmi        server_list
  1188.     global subnet_lmi       subnet_list
  1189.     global user_class_lmi   user_class_list
  1190.     global vendor_class_lmi vendor_class_list
  1191.     if {![llength $optionList]} {
  1192.     return 0
  1193.     }
  1194.     switch $type {
  1195.     client {
  1196.         if {[keylget optionList identifier_type identifier_type]} {
  1197.         keyldel optionList identifier_type
  1198.         if {[cequal $identifier_type opaque]} {
  1199.             set id  "$type opaque \"$object\""
  1200.         } elseif {[cequal $identifier_type hardware]} {
  1201.             lassign [split "$object" _] hwtype hwaddr
  1202.             set id "$type $hwtype $hwaddr"
  1203.         } else {
  1204.             return -1
  1205.         }
  1206.         } else {
  1207.         return -1
  1208.         }
  1209.     }
  1210.     global {
  1211.         set id global
  1212.     }
  1213.     option {
  1214.         set id "$type $object"
  1215.     }
  1216.     server {
  1217.         set id server 
  1218.         set optionList [ServerRemDefault $optionList]
  1219.         if {![llength $optionList]} {
  1220.         return 0
  1221.         }
  1222.     }
  1223.     subnet {
  1224.         set id "$type $object"
  1225.     }
  1226.     user_class    -
  1227.     vendor_class {
  1228.         set id  "$type \"$object\""
  1229.     }
  1230.     default {
  1231.         return -1
  1232.     }
  1233.     }
  1234.     set def_lmi  [format "%s_lmi(%s)"  $type $object]
  1235.     set def_list [format "%s_list(%s)" $type $object]
  1236.     set $def_lmi [lm_addLine $dhcp_lmh end "$id {"]
  1237.     foreach option [keylkeys optionList] {
  1238.     keylget optionList $option valueList
  1239.     set length [llength $valueList]
  1240.     if {$length == 0} {
  1241.         continue
  1242.     } elseif {[llength $valueList] == 1 || [cequal $option comment] ||
  1243.         [cequal $option name] || [cequal $option type]} {
  1244.         lappend $def_lmi [lm_addLine $dhcp_lmh end "\t$option $valueList"]
  1245.     } else {
  1246.         lappend $def_lmi [lm_addLine $dhcp_lmh end "\t$option {"]
  1247.         foreach value $valueList {
  1248.         lappend $def_lmi [lm_addLine $dhcp_lmh end "\t$value"]
  1249.         }
  1250.         lappend $def_lmi [lm_addLine $dhcp_lmh end "\t}"]
  1251.     }
  1252.     }
  1253.     lappend $def_lmi [lm_addLine $dhcp_lmh end "}"]
  1254.     set $def_list $optionList
  1255.     return 1
  1256. } ;# dhcp:defAdd 
  1257. proc dhcp:defRemove {type object {item {}}} {
  1258.     global dhcp_lmh 
  1259.     global client_lmi       client_list
  1260.     global global_lmi       global_list
  1261.     global option_lmi       option_list
  1262.     global server_lmi       server_list
  1263.     global subnet_lmi       subnet_list
  1264.     global user_class_lmi   user_class_list
  1265.     global vendor_class_lmi vendor_class_list
  1266.     set defTypes [list client global option server subnet user_class \
  1267.     vendor_class] 
  1268.     if {[lsearch $defTypes $type] == -1} {
  1269.     return
  1270.     }
  1271.     set def_lmi  [format "%s_lmi(%s)"  $type $object]
  1272.     set def_list [format "%s_list(%s)" $type $object]
  1273.     set lmi_entry [set $def_lmi]
  1274.     set itemLen   [string length $item]
  1275.     if {$itemLen} {
  1276.     set keys [keylkeys $def_list]
  1277.     set index [lsearch $keys $item]
  1278.     lvarpop $def_list $index
  1279.     set lmi [lvarpop $def_lmi [incr index]]
  1280.     lm_remLine $dhcp_lmh $lmi
  1281.     }
  1282.     set keys [keylkeys $def_list]
  1283.     if {!$itemLen || ![llength $keys]} {
  1284.     foreach lmi $lmi_entry {
  1285.         lm_remLine $dhcp_lmh $lmi
  1286.     }
  1287.     unset $def_lmi
  1288.     unset $def_list 
  1289.     }
  1290. } ;# dhcp:defRemove
  1291. proc dhcp:inet_read {} {
  1292.     global INET_CONF_FILE inet_lmh
  1293.     global un_boot_list boot_list 
  1294.     global un_boot_alt_list boot_alt_list
  1295.     set inet_lmh [lm_construct]
  1296.     if {![owner file exists $INET_CONF_FILE]} {
  1297.     ErrorPush {} 1 SCO_DHCPOSA_ERR_NO_FILE "$INET_CONF_FILE"
  1298.     return
  1299.     }
  1300.     if {![owner file readable $INET_CONF_FILE]} {
  1301.     ErrorPush {} 1 SCO_DHCPOSA_ERR_READ_PERMISSION "$INET_CONF_FILE"
  1302.     return
  1303.     }
  1304.     if {[catch {ownerOpen readfile $INET_CONF_FILE r} fd]} {
  1305.     ErrorPush {} 1 SCO_DHCPOSA_ERR_OPEN "$INET_CONF_FILE"
  1306.     return
  1307.     }
  1308.     set sc [scancontext create]
  1309.     scanmatch $sc {^.*} {
  1310.     set lmi [lm_addLine $inet_lmh end "$matchInfo(line)"]
  1311.     }
  1312.     scanmatch $sc {^[    ]*$} {
  1313.     continue
  1314.     }
  1315.     scanmatch $sc {^[     ]*#bootps-alt[     ]*} {
  1316.     set line $matchInfo(line)
  1317.     set un_boot_alt_list($lmi) $line
  1318.     continue
  1319.     }
  1320.     scanmatch $sc {^[     ]*bootps-alt[     ]*} {
  1321.     set line $matchInfo(line)
  1322.     if {[info exists boot_alt_list]} {
  1323.         ErrorPush {} 1 SCO_DHCPOSA_ERR_CONFIG "$INET_CONF_FILE"
  1324.         return
  1325.     } else {
  1326.         set boot_alt_list($lmi) $line 
  1327.     }
  1328.     continue
  1329.     }
  1330.     scanmatch $sc {^[     ]*#bootps[     ]*} {
  1331.     set line $matchInfo(line)
  1332.     set un_boot_list($lmi) $line
  1333.     continue
  1334.     }
  1335.     scanmatch $sc {^[     ]*bootps[     ]*} {
  1336.     set line $matchInfo(line)
  1337.     if {[info exists boot_list]} {
  1338.         ErrorPush {} 1 SCO_DHCPOSA_ERR_CONFIG "$INET_CONF_FILE"
  1339.         return
  1340.     } else {
  1341.         set boot_list($lmi) $line 
  1342.     }
  1343.     continue
  1344.     }
  1345.     scanfile $sc $fd
  1346.     close $fd
  1347.     scancontext delete $sc
  1348. } ;# dhcp:inet_read
  1349. proc dhcp:inet_write {} {
  1350.     global INET_CONF_FILE inet_lmh
  1351.     global un_boot_list boot_list 
  1352.     global un_boot_alt_list boot_alt_list
  1353.     if {[owner file exists $INET_CONF_FILE]} {
  1354.     if {![owner file writable $INET_CONF_FILE]} {
  1355.         ErrorPush {} 1 SCO_DHCPOSA_ERR_WRITE_PERMISSION \
  1356.         "$INET_CONF_FILE"
  1357.         return
  1358.     }
  1359.     if {[catch {owner exec /bin/cp $INET_CONF_FILE ${INET_CONF_FILE}-}]} {
  1360.         ErrorPush {} 1 SCO_DHCPOSA_ERR_WRITE_BACKUP "$INET_CONF_FILE"
  1361.         return
  1362.     }
  1363.     }
  1364.     if {[catch {ownerOpen writefile $INET_CONF_FILE w} fd]} {
  1365.     ErrorPush {} 1 SCO_DHCPOSA_ERR_OPEN "$INET_CONF_FILE"
  1366.     return
  1367.     }
  1368.     set lmi [lm_firstIndex $inet_lmh]
  1369.     while {$lmi != -1} {
  1370.     puts $fd [lm_getLine $inet_lmh $lmi]
  1371.     set lmi [lm_nextIndex $inet_lmh $lmi]
  1372.     }
  1373.     close $fd
  1374.     ErrorCatch {} 1 "dhcp:inet_restart" ret
  1375. } ;# dhcp:inet_write
  1376. proc dhcp:inet_add_bootp_entry {} {
  1377.     global inet_lmh
  1378.     global un_boot_list boot_list
  1379.     set indexList [array names un_boot_list]
  1380.     set found 0
  1381.     foreach index $indexList {
  1382.     set line $un_boot_list($index)
  1383.     set name [lindex $line 6]
  1384.     if {![string compare $name "in.dhcpd"]} {
  1385.         set args [lrange $line 7 end]
  1386.         if {[lsearch $args "-b"] == -1} {
  1387.         lvarpop line 0 "bootps"
  1388.         set found 1
  1389.         break    
  1390.         } 
  1391.     }
  1392.     }
  1393.     if {!$found} {
  1394.     set line "bootps dgram/i udp wait root /usr/sbin/in.dhcpd in.dhcpd"
  1395.     }
  1396.     set lmi [lm_addLine $inet_lmh end $line]
  1397.     set boot_list($lmi) $line 
  1398. } ;# dhcp:inet_add_bootp_entry
  1399. proc dhcp:inet_add_bootp_alt_entry {{bootp_line {}}} {
  1400.     global inet_lmh
  1401.     global un_boot_list boot_list
  1402.     global un_boot_alt_list boot_alt_list
  1403.     set indexList [array names un_boot_list]
  1404.     set found 0
  1405.     foreach index $indexList {
  1406.     set line $un_boot_list($index)
  1407.     set name [lindex $line 6]
  1408.     if {![string compare $name "in.dhcpd"]} {
  1409.         set args [lrange $line 7 end]
  1410.         if {[lsearch $args "-b"] != -1} {
  1411.         lvarpop line 0 "bootps"
  1412.         set found 1
  1413.         break    
  1414.         } 
  1415.     }
  1416.     }
  1417.     if {!$found} {
  1418.     set line "bootps dgram/i udp wait root /usr/sbin/in.dhcpd in.dhcpd -b bootps-alt"
  1419.     }
  1420.     set lmi [lm_addLine $inet_lmh end $line]
  1421.     set boot_list($lmi) $line 
  1422.     if {[info exists bootp_line] && [llength $bootp_line]} {
  1423.     set line $bootp_line
  1424.     lvarpop line 0 "bootps-alt"
  1425.     set args [lrange $line 7 end]
  1426.     if {[lsearch $args "-S"] == -1} {
  1427.         lappend line "-S"
  1428.     }
  1429.     set found 1
  1430.     } else {
  1431.     set indexList [array names un_boot_alt_list]
  1432.     set found 0
  1433.     foreach index $indexList {
  1434.         set line $un_boot_alt_list($index)
  1435.         set name [lindex $line 6]
  1436.         if {![string compare $name "in.bootpd"]} {
  1437.         set args [lrange $line 7 end]
  1438.         if {[lsearch $args "-S"] != -1} {
  1439.             lvarpop line 0 "bootps-alt"
  1440.             set found 1
  1441.             break    
  1442.         } 
  1443.         }
  1444.     }
  1445.     }
  1446.     if {!$found} {
  1447.     set line "bootps-alt dgram udp wait root /usr/sbin/in.bootpd in.bootpd -S"
  1448.     }
  1449.     set lmi [lm_addLine $inet_lmh end $line]
  1450.     set boot_alt_list($lmi) $line 
  1451. } ;# dhcp:inet_add_bootp_alt_entry
  1452. proc dhcp:inet_add_entry {} {
  1453.     global INET_CONF_FILE inet_lmh
  1454.     global un_boot_list boot_list 
  1455.     global un_boot_alt_list boot_alt_list
  1456.     if {[info exists boot_list] && [info exists boot_alt_list]} {
  1457.     return
  1458.     } elseif {[info exists boot_list]} {
  1459.     set lmi_list [array names boot_list]
  1460.     set length [llength $lmi_list]
  1461.     if {$length == 0} {
  1462.         dhcp:inet_add_bootp_entry
  1463.     } elseif {$length != 1}  {
  1464.         ErrorPush {} 1 SCO_DHCPOSA_ERR_CONFIG "$INET_CONF_FILE"
  1465.         return
  1466.     } else {
  1467.         set lmi  [lindex $lmi_list 0]
  1468.         set line $boot_list($lmi)
  1469.         set name [lindex $line 6]
  1470.         if {![string compare $name "in.dhcpd"]} {
  1471.         return
  1472.         } elseif {![string compare $name "in.bootpd"]} {
  1473.         lm_remLine $inet_lmh $lmi
  1474.         unset boot_list($lmi)
  1475.         dhcp:inet_add_bootp_alt_entry $line
  1476.         } else {
  1477.         ErrorPush {} 1 SCO_DHCPOSA_ERR_CONFIG "$INET_CONF_FILE"
  1478.         return
  1479.         }
  1480.     }
  1481.     } elseif {[info exists boot_alt_list]} {
  1482.     ErrorPush {} 1 SCO_DHCPOSA_ERR_CONFIG "$INET_CONF_FILE"
  1483.     return
  1484.     } else {
  1485.     dhcp:inet_add_bootp_entry
  1486.     }
  1487.     ErrorCatch {} 1 "dhcp:inet_write" ret
  1488. } ;# dhcp:inet_add_entry
  1489. proc dhcp:inet_remove_bootp_entry {type} {
  1490.     global inet_lmh un_boot_list boot_list 
  1491.     set lmi_list [array names boot_list]
  1492.     set length [llength $lmi_list]
  1493.     if {$length == 1} {
  1494.     set lmi [lindex $lmi_list 0]
  1495.     set line $boot_list($lmi)
  1496.     set name [lindex $line 6]
  1497.     if {![string compare $name $type]} {
  1498.         lm_remLine $inet_lmh $lmi
  1499.         unset boot_list($lmi)
  1500.     }
  1501.     } elseif {$length != 0} {
  1502.     return -1 
  1503.     }
  1504.     return 0 
  1505. } ;# dhcp:inet_remove_bootp_entry
  1506. proc dhcp:inet_remove_bootp_alt_entry {} {
  1507.     global inet_lmh un_boot_alt_list boot_alt_list
  1508.     set lmi_list [array names boot_alt_list]
  1509.     set length [llength $lmi_list]
  1510.     if {$length == 1} {
  1511.     set lmi [lindex $lmi_list 0]
  1512.     set line $boot_alt_list($lmi)
  1513.     set name [lindex $line 6]
  1514.     if {![string compare $name "in.bootpd"]} {
  1515.         lm_remLine $inet_lmh $lmi
  1516.         unset boot_alt_list($lmi)
  1517.         lvarpop line 0 "bootps"
  1518.         set index [lsearch $line "-S"]
  1519.         if {$index > 6} {
  1520.         lvarpop line $index
  1521.         } 
  1522.             set lmi [lm_addLine $inet_lmh end $line]
  1523.         set boot_list($lmi) $line 
  1524.     }
  1525.     } elseif {$length != 0} {
  1526.     return -1
  1527.     }
  1528.     return 0
  1529. } ;# dhcp:inet_remove_bootp_alt_entry
  1530. proc dhcp:inet_remove_entry {} {
  1531.     global INET_CONF_FILE inet_lmh
  1532.     global un_boot_list boot_list 
  1533.     global un_boot_alt_list boot_alt_list
  1534.     if {[info exists boot_list] && [info exists boot_alt_list]} {
  1535.     if {[dhcp:inet_remove_bootp_entry "in.dhcpd"] < 0} {
  1536.         ErrorPush {} 1 SCO_DHCPOSA_ERR_CONFIG "$INET_CONF_FILE"
  1537.     }
  1538.     if {[dhcp:inet_remove_bootp_alt_entry] < 0} {
  1539.         ErrorPush {} 1 SCO_DHCPOSA_ERR_CONFIG "$INET_CONF_FILE"
  1540.     }
  1541.     } elseif {[info exists boot_list]} {
  1542.     if {[dhcp:inet_remove_bootp_entry "in.dhcpd"] < 0} {
  1543.         ErrorPush {} 1 SCO_DHCPOSA_ERR_CONFIG "$INET_CONF_FILE"
  1544.     }
  1545.     } else {
  1546.     return
  1547.     }
  1548.     ErrorCatch {} 1 "dhcp:inet_write" ret
  1549. } ;# dhcp:inet_remove_entry
  1550. proc dhcp:inet_restart {} {
  1551.     OwnerCallNonStdCmd /usr/sbin/sacadm "-k -p inetd" \
  1552.     SCO_DHCPOSA_ERR_UNIX errStack SCO_DHCPOSA_ERR_SACADM_STOP "inet"]
  1553.     if {[info exists errStack] && [string length $errStack]} {
  1554.     ErrorThrow errStack
  1555.     return
  1556.     } 
  1557.     OwnerCallNonStdCmd /usr/sbin/sacadm "-s -p inetd" \
  1558.     SCO_DHCPOSA_ERR_UNIX errStack SCO_DHCPOSA_ERR_SACADM_START "inet"]
  1559.     if {[info exists errStack] && [string length $errStack]} {
  1560.     ErrorThrow errStack
  1561.     return
  1562.     } 
  1563. }
  1564. proc dhcp:init {} {
  1565.     global OS DHCP_CONF_FILE DHCP_OPTS_FILE INET_CONF_FILE option_list
  1566.     if {[catch {exec /bin/uname -r} OS]} {
  1567.     set OS 4
  1568.     }
  1569.     switch -exact $OS {
  1570.     3.2 {
  1571.         set SA_LIB_DIR /etc/sysadm.d/lib
  1572.         set CONFIG_DIR /etc
  1573.     }
  1574.     default {
  1575.         set SA_LIB_DIR /usr/lib
  1576.         set CONFIG_DIR /etc/inet
  1577.     }
  1578.     } 
  1579.     loadlibindex ${SA_LIB_DIR}/sysadm.tlib
  1580.     set DHCP_CONF_FILE ${CONFIG_DIR}/dhcpd.conf
  1581.     set DHCP_OPTS_FILE ${CONFIG_DIR}/dhcp.opts
  1582.     set INET_CONF_FILE ${CONFIG_DIR}/inetd.conf
  1583.     dhcp:init_standard_opts
  1584.     dhcp:read
  1585.     dhcp:inet_read
  1586. } ;# dhcp:init
  1587. proc dhcpSubnet_get {class object refObject op subOp data attr attrValueList osaData} {
  1588.     global subnet_list
  1589.     set result {}
  1590.     if {![info exists subnet_list] || \
  1591.     [lsearch [array names subnet_list] $object] == -1} {
  1592.     ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE \
  1593.         [list $object]
  1594.     }
  1595.     foreach attr [keylkeys attrValueList $attr] {
  1596.     switch -exact $attr {
  1597.         options {
  1598.         keylset result options $subnet_list($object)
  1599.         }
  1600.         default {
  1601.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE \
  1602.             [list $attr] [list $class]
  1603.         }
  1604.     }
  1605.     }
  1606.     return $result
  1607. }
  1608. proc dhcpSubnet_add {class object refObject op subOp data attr attrValueList osaData} {
  1609.     global subnet_list
  1610.     if {[info exists subnet_list] && \
  1611.     [lsearch [array names subnet_list] $object] != -1} {
  1612.     ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE \
  1613.         [list $object]
  1614.     return
  1615.     }
  1616.     keylget attrValueList options options
  1617.     dhcp:defAdd subnet $object $options
  1618.     dhcp:write
  1619.     return
  1620. }
  1621. proc dhcpSubnet_remove {class object refObject op subOp data attr attrValueList osaData} {
  1622.     global subnet_list 
  1623.     if {![info exists subnet_list] || \
  1624.     [lsearch [array names subnet_list] $object] == -1} {
  1625.     ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE [list $object]
  1626.     return
  1627.     }
  1628.     dhcp:defRemove subnet $object
  1629.     dhcp:write
  1630. }
  1631. proc dhcpSubnet_list {class object refObject op subOp data attr attrValueList osaData} {
  1632.     global subnet_list 
  1633.     set names {}
  1634.     if {[info exists subnet_list]} {
  1635.     set names [array names subnet_list]
  1636.     }
  1637.     return $names
  1638. }
  1639. proc dhcpClient_get {class object refObject op subOp data attr attrValueList osaData} {
  1640.     global client_list
  1641.     set result {}
  1642.     if {![info exists client_list] || \
  1643.     [lsearch [array names client_list] $object] == -1} {
  1644.     ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE \
  1645.         [list $object]
  1646.     }
  1647.     foreach attr [keylkeys attrValueList $attr] {
  1648.     switch -exact $attr {
  1649.         options {
  1650.         keylset result options $client_list($object)
  1651.         }
  1652.         default {
  1653.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE \
  1654.             [list $attr] [list $class]
  1655.         }
  1656.     }
  1657.     }
  1658.     return $result
  1659. }
  1660. proc dhcpClient_add {class object refObject op subOp data attr attrValueList osaData} {
  1661.     global client_list
  1662.     if {[info exists client_list] && \
  1663.     [lsearch [array names client_list] $object] != -1} {
  1664.     ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE \
  1665.         [list $object]
  1666.     return
  1667.     }
  1668.     keylget attrValueList options options
  1669.     dhcp:defAdd client $object $options
  1670.     dhcp:write
  1671. }
  1672. proc dhcpClient_remove {class object refObject op subOp data attr attrValueList osaData} {
  1673.     global client_list 
  1674.     if {![info exists client_list] || \
  1675.     [lsearch [array names client_list] $object] == -1} {
  1676.     ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE [list $object]
  1677.     return
  1678.     }
  1679.     dhcp:defRemove client $object
  1680.     dhcp:write
  1681. }
  1682. proc dhcpClient_list {class object refObject op subOp data attr attrValueList osaData} {
  1683.     global client_list 
  1684.     set names {}
  1685.     if {[info exists client_list]} {
  1686.     set names [array names client_list]
  1687.     }
  1688.     return $names
  1689. }
  1690. proc dhcpUserClass_get {class object refObject op subOp data attr attrValueList osaData} {
  1691.     global user_class_list
  1692.     set result {}
  1693.     if {![info exists user_class_list] || \
  1694.     [lsearch [array names user_class_list] $object] == -1} {
  1695.     ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE \
  1696.         [list $object]
  1697.     }
  1698.     foreach attr [keylkeys attrValueList $attr] {
  1699.     switch -exact $attr {
  1700.         options {
  1701.         keylset result options $user_class_list($object)
  1702.         }
  1703.         default {
  1704.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE \
  1705.             [list $attr] [list $class]
  1706.         }
  1707.     }
  1708.     }
  1709.     return $result
  1710. }
  1711. proc dhcpUserClass_add {class object refObject op subOp data attr attrValueList osaData} {
  1712.     global user_class_list
  1713.     if {[info exists user_class_list] && \
  1714.     [lsearch [array names user_class_list] $object] != -1} {
  1715.     ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE \
  1716.         [list $object]
  1717.     return
  1718.     }
  1719.     keylget attrValueList options options
  1720.     dhcp:defAdd user_class $object $options
  1721.     dhcp:write
  1722. }
  1723. proc dhcpUserClass_remove {class object refObject op subOp data attr attrValueList osaData} {
  1724.     global user_class_list 
  1725.     if {![info exists user_class_list] || \
  1726.     [lsearch [array names user_class_list] $object] == -1} {
  1727.     ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE [list $object]
  1728.     return
  1729.     }
  1730.     dhcp:defRemove user_class $object
  1731.     dhcp:write
  1732. }
  1733. proc dhcpUserClass_list {class object refObject op subOp data attr attrValueList osaData} {
  1734.     global user_class_list 
  1735.     set names {}
  1736.     if {[info exists user_class_list]} {
  1737.     set names [array names user_class_list]
  1738.     }
  1739.     return $names
  1740. }
  1741. proc dhcpVendorClass_get {class object refObject op subOp data attr attrValueList osaData} {
  1742.     global vendor_class_list
  1743.     set result {}
  1744.     if {![info exists vendor_class_list] || \
  1745.     [lsearch [array names vendor_class_list] $object] == -1} {
  1746.     ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE \
  1747.         [list $object]
  1748.     }
  1749.     foreach attr [keylkeys attrValueList $attr] {
  1750.     switch -exact $attr {
  1751.         options {
  1752.         keylset result options $vendor_class_list($object)
  1753.         }
  1754.         default {
  1755.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE \
  1756.             [list $attr] [list $class]
  1757.         }
  1758.     }
  1759.     }
  1760.     return $result
  1761. }
  1762. proc dhcpVendorClass_add {class object refObject op subOp data attr attrValueList osaData} {
  1763.     global vendor_class_list
  1764.     if {[info exists vendor_class_list] && \
  1765.     [lsearch [array names vendor_class_list] $object] != -1} {
  1766.     ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE \
  1767.         [list $object]
  1768.     return
  1769.     }
  1770.     keylget attrValueList options options
  1771.     dhcp:defAdd vendor_class $object $options
  1772.     dhcp:write
  1773. }
  1774. proc dhcpVendorClass_remove {class object refObject op subOp data attr attrValueList osaData} {
  1775.     global vendor_class_list 
  1776.     if {![info exists vendor_class_list] || \
  1777.     [lsearch [array names vendor_class_list] $object] == -1} {
  1778.     ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE [list $object]
  1779.     return
  1780.     }
  1781.     dhcp:defRemove vendor_class $object
  1782.     dhcp:write
  1783. }
  1784. proc dhcpVendorClass_list {class object refObject op subOp data attr attrValueList osaData} {
  1785.     global vendor_class_list 
  1786.     set names {}
  1787.     if {[info exists vendor_class_list]} {
  1788.     set names [array names vendor_class_list]
  1789.     }
  1790.     return $names
  1791. }
  1792. proc dhcpOption_get {class object refObject op subOp data attr attrValueList osaData} {
  1793.     global option_list
  1794.     set result {}
  1795.     if {![info exists option_list] || \
  1796.     [lsearch [array names option_list] $object] == -1} {
  1797.     ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE \
  1798.         [list $object]
  1799.     }
  1800.     foreach attr [keylkeys attrValueList $attr] {
  1801.     switch -exact $attr {
  1802.         options {
  1803.         keylset result options $option_list($object)
  1804.         }
  1805.         default {
  1806.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE \
  1807.             [list $attr] [list $class]
  1808.         }
  1809.     }
  1810.     }
  1811.     return $result
  1812. }
  1813. proc dhcpOption_add {class object refObject op subOp data attr attrValueList osaData} {
  1814.     global option_list
  1815.     if {[info exists option_list] && \
  1816.     [lsearch [array names option_list] $object] != -1} {
  1817.     ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE \
  1818.         [list $object]
  1819.     return
  1820.     }
  1821.     keylget attrValueList options options
  1822.     dhcp:defAdd option $object $options
  1823.     dhcp:write
  1824. }
  1825. proc dhcpOption_remove {class object refObject op subOp data attr attrValueList osaData} {
  1826.     global option_list 
  1827.     if {![info exists option_list] || \
  1828.     [lsearch [array names option_list] $object] == -1} {
  1829.     ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE [list $object]
  1830.     return
  1831.     }
  1832.     dhcp:defRemove option $object
  1833.     dhcp:write
  1834. }
  1835. proc dhcpOption_list {class object refObject op subOp data attr attrValueList osaData} {
  1836.     global option_list 
  1837.     set names {}
  1838.     if {[info exists option_list]} {
  1839.     set names [array names option_list]
  1840.     }
  1841.     return $names
  1842. }
  1843. proc dhcpGlobal_get {class object refObject op subOp data attr attrValueList osaData} {
  1844.     global global_list
  1845.     set result {}
  1846.     if {![info exists global_list] || \
  1847.     [lsearch [array names global_list] $object] == -1} {
  1848.     ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE \
  1849.         [list $object]
  1850.     }
  1851.     foreach attr [keylkeys attrValueList $attr] {
  1852.     switch -exact $attr {
  1853.         options {
  1854.         keylset result options $global_list($object)
  1855.         }
  1856.         default {
  1857.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE \
  1858.             [list $attr] [list $class]
  1859.         }
  1860.     }
  1861.     }
  1862.     return $result
  1863. }
  1864. proc dhcpGlobal_add {class object refObject op subOp data attr attrValueList osaData} {
  1865.     global global_list
  1866.     if {[info exists global_list] && \
  1867.     [lsearch [array names global_list] $object] != -1} {
  1868.     ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE \
  1869.         [list $object]
  1870.     return
  1871.     }
  1872.     keylget attrValueList options options
  1873.     dhcp:defAdd global $object $options
  1874.     dhcp:write
  1875. }
  1876. proc dhcpGlobal_remove {class object refObject op subOp data attr attrValueList osaData} {
  1877.     global global_list 
  1878.     if {![info exists global_list] || \
  1879.     [lsearch [array names global_list] $object] == -1} {
  1880.     return
  1881.     }
  1882.     if {[keylget attrValueList options options]} {
  1883.     foreach key [keylkeys options] {
  1884.         dhcp:defRemove global $object $key
  1885.     }
  1886.     } else {
  1887.     dhcp:defRemove global $object
  1888.     }
  1889.     dhcp:write
  1890. }
  1891. proc dhcpGlobal_list {class object refObject op subOp data attr attrValueList osaData} {
  1892.     global global_list 
  1893.     set names {}
  1894.     if {[info exists global_list]} {
  1895.     set names [array names global_list]
  1896.     }
  1897.     return $names
  1898. }
  1899. proc dhcpStandard_get {class object refObject op subOp data attr attrValueList osaData} {
  1900.     global standard_list
  1901.     set result {}
  1902.     if {![info exists standard_list] || \
  1903.     [lsearch [array names standard_list] $object] == -1} {
  1904.     ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE \
  1905.         [list $object]
  1906.     } else {
  1907.     foreach attr [keylkeys attrValueList $attr] {
  1908.         switch -exact $attr {
  1909.         options {
  1910.             keylset result options $standard_list($object) 
  1911.         }
  1912.         default {
  1913.             ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE \
  1914.             [list $attr] [list $class]
  1915.         }
  1916.         }
  1917.     }
  1918.     }
  1919.     return $result
  1920. }
  1921. proc dhcpStandard_add {class object refObject op subOp data attr attrValueList osaData} {
  1922. }
  1923. proc dhcpStandard_remove {class object refObject op subOp data attr attrValueList osaData} {
  1924. }
  1925. proc dhcpStandard_list {class object refObject op subOp data attr attrValueList osaData} {
  1926.     global standard_list 
  1927.     set names {}
  1928.     if {[info exists standard_list]} {
  1929.     set names [array names standard_list]
  1930.     }
  1931.     return $names
  1932. }
  1933. proc dhcpServer_get {class object refObject op subOp data attr attrValueList osaData} {
  1934.     global server_list
  1935.     set result {}
  1936.     if {![cequal $object server]} {
  1937.     ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE \
  1938.         [list $object]
  1939.     }
  1940.     if {![info exists server_list] || \
  1941.     [lsearch [array names server_list] $object] == -1} {
  1942.     set serverInfo {}
  1943.     } else {
  1944.     set serverInfo $server_list($object)
  1945.     }
  1946.     foreach attr [keylkeys attrValueList $attr] {
  1947.     switch -exact $attr {
  1948.         options {
  1949.         keylset result options \
  1950.             [ServerAddDefault $serverInfo]
  1951.         }
  1952.         default {
  1953.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE \
  1954.             [list $attr] [list $class]
  1955.         }
  1956.     }
  1957.     }
  1958.     return $result
  1959. }
  1960. proc dhcpServer_add {class object refObject op subOp data attr attrValueList osaData} {
  1961.     global server_list
  1962.     if {[info exists server_list] && \
  1963.     [lsearch [array names server_list] $object] != -1} {
  1964.     ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE \
  1965.         [list $object]
  1966.     return -1
  1967.     }
  1968.     keylget attrValueList options options
  1969.     set ret [dhcp:defAdd server $object $options]
  1970.     if {$ret > 0} {
  1971.     dhcp:write
  1972.     }
  1973.     return $ret
  1974. }
  1975. proc dhcpServer_remove {class object refObject op subOp data attr attrValueList osaData} {
  1976.     global server_list 
  1977.     if {![info exists server_list] || \
  1978.     [lsearch [array names server_list] $object] == -1} {
  1979.     return
  1980.     }
  1981.     dhcp:defRemove server $object
  1982.     dhcp:write
  1983. }
  1984. proc dhcpServer_list {class object refObject op subOp data attr attrValueList osaData} {
  1985.     return server 
  1986. }
  1987. OFBinding sco_dhcpSubnet_CDT
  1988. OFBinding sco_dhcpClient_CDT
  1989. OFBinding sco_dhcpUserClass_CDT
  1990. OFBinding sco_dhcpVendorClass_CDT
  1991. OFBinding sco_dhcpOption_CDT
  1992. OFBinding sco_dhcpGlobal_CDT
  1993. OFBinding sco_dhcpStandard_CDT
  1994. OFBinding sco_dhcpServer_CDT
  1995. dhcp:init
  1996.