home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 March B / SCO_CASTOR4RRT.iso / inet / root.2 / usr / lib / scoadmin / netosa / ftpOsa / ftpOsa~
Text File  |  1998-08-19  |  99KB  |  3,817 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_FTPOSA_MSGS SCO_FTPOSA_MSGS
  24. proc SCO_FTPOSA_MSGS {} {}
  25. global SCO_FTPOSA_MSGS
  26. set SCO_FTPOSA_MSGS(@catalog@) {ftpOsa.cat@sa 1}
  27. set SCO_FTPOSA_MSGS(ERR_CONFIG) {1 {Configuration error}}
  28. set SCO_FTPOSA_MSGS(ERR_SYNTAX) {2 {Syntax error in configuration file ftpaccess near : %1s}}
  29. set SCO_FTPOSA_MSGS(ERR_BUG_ERR) {3 {Syntax error in configuration file}}
  30. set SCO_FTPOSA_MSGS(ERR_OPEN_SHUTDOWN_FILE) {4 {Unable to open shutdown file}}
  31. set SCO_FTPOSA_MSGS(ERR_SHUTDOWN_SYNTAX) {5 {Syntax error in shutdown file %1s}}
  32. set SCO_FTPOSA_MSGS(ERR_SHUTDOWN_SYNTAX2) {6 {Syntax error in shutdown file %1$s near : %2$s}}
  33. set SCO_FTPOSA_MSGS(ERR_ANON_CREATE) {7 {Failed to create the anonymous FTP user account}}
  34. set SCO_FTPOSA_MSGS(ERR_ANON_MODIFY) {8 {Failed to modify the anonymous FTP user account}}
  35. set SCO_FTPOSA_MSGS(ERR_ANON_MODIFY_AGED) {9 {Failed to modify the anonymous FTP user account\nUser ID has not aged sufficently, choose another.}}
  36. set SCO_FTPOSA_MSGS(ERR_ANON_DELETE) {10 {Failed to delete the anonymous FTP user account}}
  37. set SCO_FTPOSA_MSGS(ERR_ANON_INVALID_ACTION) {11 {Invalid action on anonymous FTP user account}}
  38. set sco_ftpShutdown_CDT(attributes) {
  39.     {
  40.         year
  41.         {
  42.             { validOperations {get replace} }
  43.             { validFilters {} }
  44.             { dataType single }
  45.         }
  46.     }
  47.     {
  48.         month
  49.         {
  50.             { validOperations {get replace} }
  51.             { validFilters {} }
  52.             { dataType single }
  53.         }
  54.     }
  55.     {
  56.         day
  57.         {
  58.             { validOperations {get replace} }
  59.             { validFilters {} }
  60.             { dataType single }
  61.         }
  62.     }
  63.     {
  64.         deny_offset
  65.         {
  66.             { validOperations {get replace} }
  67.             { validFilters {} }
  68.             { dataType single }
  69.             { description HHMM }
  70.         }
  71.     }
  72.     {
  73.         disc_offset
  74.         {
  75.             { validOperations {get replace} }
  76.             { validFilters {} }
  77.             { dataType single }
  78.             { description HHMM }
  79.         }
  80.     }
  81.     {
  82.         stext
  83.         {
  84.             { validOperations {get replace} }
  85.             { validFilters {} }
  86.             { dataType single }
  87.             { description {Shutdown message. A list of lists, where one list corresponds to one line.} }
  88.         }
  89.     }
  90.     {
  91.         hour
  92.         {
  93.             { validOperations {get replace} }
  94.             { validFilters {} }
  95.             { dataType single }
  96.         }
  97.     }
  98.     {
  99.         minute
  100.         {
  101.             { validOperations {get replace} }
  102.             { validFilters {} }
  103.             { dataType single }
  104.         }
  105.     }
  106. }
  107. set sco_ftpShutdown_CDT(groups) {}
  108. set sco_ftpShutdown_CDT(operations) {
  109.     {
  110.         get
  111.         {
  112.             { granularity perObject }
  113.             { function ftpShutdown_get }
  114.         }
  115.     }
  116.     {
  117.         replace
  118.         {
  119.             { granularity perObject }
  120.             { function ftpShutdown_create }
  121.         }
  122.     }
  123.     {
  124.         delete
  125.         {
  126.             { function ftpShutdown_delete }
  127.             { granularity perObject }
  128.         }
  129.     }
  130.     {
  131.         create
  132.         {
  133.             { function ftpShutdown_create }
  134.             { granularity perObject }
  135.         }
  136.     }
  137.     {
  138.         action
  139.         {
  140.             { function ftpShutdown_action }
  141.             { granularity perObject }
  142.         }
  143.     }
  144. }
  145. set sco_ftpShutdown_CDT(class) {sco ftpShutdown}
  146. set sco_ftpShutdown_CDT(superior) {}
  147. set sco_ftpShutdown_CDT(subordinates) {}
  148. set sco_ftpDenyHost_CDT(attributes) {
  149.     {
  150.         host
  151.         {
  152.             { validOperations {get replace} }
  153.             { validFilters {} }
  154.             { dataType single }
  155.         }
  156.     }
  157.     {
  158.         file
  159.         {
  160.             { validOperations {get replace} }
  161.             { validFilters {} }
  162.             { dataType single }
  163.         }
  164.     }
  165. }
  166. set sco_ftpDenyHost_CDT(groups) {}
  167. set sco_ftpDenyHost_CDT(operations) {
  168.     {
  169.         get
  170.         {
  171.             { granularity perAttribute }
  172.             { function ftpDenyHost_get }
  173.         }
  174.     }
  175.     {
  176.         replace
  177.         {
  178.             { granularity perObject }
  179.             { function ftpDenyHost_replace }
  180.         }
  181.     }
  182.     {
  183.         create
  184.         {
  185.             { function ftpDenyHost_create }
  186.             { granularity perObject }
  187.         }
  188.     }
  189.     {
  190.         delete
  191.         {
  192.             { function ftpDenyHost_delete }
  193.             { granularity perObject }
  194.         }
  195.     }
  196.     {
  197.         list
  198.         {
  199.             { granularity perObject }
  200.             { function ftpDenyHost_list }
  201.         }
  202.     }
  203. }
  204. set sco_ftpDenyHost_CDT(class) {sco ftpDenyHost}
  205. set sco_ftpDenyHost_CDT(superior) {sco ftp}
  206. set sco_ftpDenyHost_CDT(subordinates) {{sco ftpDenyHost}}
  207. set sco_ftpVirtual_CDT(attributes) {
  208.     {
  209.         address
  210.         {
  211.             { validOperations {get} }
  212.             { validFilters {} }
  213.             { dataType single }
  214.         }
  215.     }
  216.     {
  217.         banner
  218.         {
  219.             { validOperations {get replace} }
  220.             { validFilters {} }
  221.             { dataType single }
  222.         }
  223.     }
  224.     {
  225.         root
  226.         {
  227.             { validOperations {get replace} }
  228.             { validFilters {} }
  229.             { dataType single }
  230.         }
  231.     }
  232.     {
  233.         logfile
  234.         {
  235.             { validOperations {get replace} }
  236.             { validFilters {} }
  237.             { dataType single }
  238.         }
  239.     }
  240. }
  241. set sco_ftpVirtual_CDT(groups) {}
  242. set sco_ftpVirtual_CDT(operations) {
  243.     {
  244.         delete
  245.         {
  246.             { function ftpVirtual_delete }
  247.             { granularity perObject }
  248.         }
  249.     }
  250.     {
  251.         list
  252.         {
  253.             { granularity perObject }
  254.             { function ftpVirtual_list }
  255.         }
  256.     }
  257.     {
  258.         replace
  259.         {
  260.             { granularity perObject }
  261.             { function ftpVirtual_replace }
  262.         }
  263.     }
  264.     {
  265.         get
  266.         {
  267.             { granularity perAttribute }
  268.             { function ftpVirtual_get }
  269.         }
  270.     }
  271.     {
  272.         create
  273.         {
  274.             { function ftpVirtual_create }
  275.             { granularity perObject }
  276.         }
  277.     }
  278. }
  279. set sco_ftpVirtual_CDT(class) {sco ftpVirtual}
  280. set sco_ftpVirtual_CDT(superior) {sco ftp}
  281. set sco_ftpVirtual_CDT(subordinates) {{sco ftpVirtual}}
  282. set sco_ftpMessage_CDT(attributes) {
  283.     {
  284.         file
  285.         {
  286.             { validOperations {get replace} }
  287.             { validFilters {} }
  288.             { dataType single }
  289.             { description {path to message file} }
  290.         }
  291.     }
  292.     {
  293.         type
  294.         {
  295.             { validOperations {get replace} }
  296.             { validFilters {} }
  297.             { dataType single }
  298.             { description {type of message
  299. (readme or message)} }
  300.         }
  301.     }
  302.     {
  303.         when
  304.         {
  305.             { validOperations {get replace} }
  306.             { validFilters {} }
  307.             { dataType single }
  308.             { description {when to display message} }
  309.         }
  310.     }
  311.     {
  312.         class
  313.         {
  314.             { validOperations {get replace} }
  315.             { validFilters {} }
  316.             { dataType single }
  317.             { description {only display readme to members of this class} }
  318.         }
  319.     }
  320. }
  321. set sco_ftpMessage_CDT(groups) {}
  322. set sco_ftpMessage_CDT(operations) {
  323.     {
  324.         get
  325.         {
  326.             { granularity perAttribute }
  327.             { function ftpMessage_get }
  328.         }
  329.     }
  330.     {
  331.         replace
  332.         {
  333.             { granularity perObject }
  334.             { function ftpMessage_replace }
  335.         }
  336.     }
  337.     {
  338.         create
  339.         {
  340.             { function ftpMessage_create }
  341.             { granularity perObject }
  342.         }
  343.     }
  344.     {
  345.         delete
  346.         {
  347.             { function ftpMessage_delete }
  348.             { granularity perObject }
  349.         }
  350.     }
  351.     {
  352.         list
  353.         {
  354.             { granularity perObject }
  355.             { function ftpMessage_list }
  356.         }
  357.     }
  358. }
  359. set sco_ftpMessage_CDT(class) {sco ftpMessage}
  360. set sco_ftpMessage_CDT(superior) {sco ftp}
  361. set sco_ftpMessage_CDT(subordinates) {{sco ftpMessage}}
  362. set sco_ftpAccess_CDT(attributes) {
  363.     {
  364.         home
  365.         {
  366.             { validOperations {get replace} }
  367.             { validFilters {} }
  368.             { dataType single }
  369.         }
  370.     }
  371.     {
  372.         dir
  373.         {
  374.             { validOperations {get replace} }
  375.             { validFilters {} }
  376.             { dataType single }
  377.         }
  378.     }
  379.     {
  380.         upload
  381.         {
  382.             { validOperations {get replace} }
  383.             { validFilters {} }
  384.             { dataType single }
  385.             { syntax boolean }
  386.         }
  387.     }
  388.     {
  389.         owner
  390.         {
  391.             { validOperations {get replace} }
  392.             { validFilters {} }
  393.             { dataType single }
  394.         }
  395.     }
  396.     {
  397.         group
  398.         {
  399.             { validOperations {get replace} }
  400.             { validFilters {} }
  401.             { dataType single }
  402.         }
  403.     }
  404.     {
  405.         mode
  406.         {
  407.             { validOperations {get replace} }
  408.             { validFilters {} }
  409.             { dataType single }
  410.         }
  411.     }
  412.     {
  413.         subdirs
  414.         {
  415.             { validOperations {get replace} }
  416.             { validFilters {} }
  417.             { dataType single }
  418.             { syntax boolean }
  419.         }
  420.     }
  421. }
  422. set sco_ftpAccess_CDT(groups) {}
  423. set sco_ftpAccess_CDT(operations) {
  424.     {
  425.         get
  426.         {
  427.             { granularity perAttribute }
  428.             { function ftpAccess_get }
  429.         }
  430.     }
  431.     {
  432.         replace
  433.         {
  434.             { granularity perObject }
  435.             { function ftpAccess_replace }
  436.         }
  437.     }
  438.     {
  439.         create
  440.         {
  441.             { function ftpAccess_create }
  442.             { granularity perObject }
  443.         }
  444.     }
  445.     {
  446.         delete
  447.         {
  448.             { function ftpAccess_delete }
  449.             { granularity perObject }
  450.         }
  451.     }
  452.     {
  453.         list
  454.         {
  455.             { granularity perObject }
  456.             { function ftpAccess_list }
  457.         }
  458.     }
  459. }
  460. set sco_ftpAccess_CDT(class) {sco ftpAccess}
  461. set sco_ftpAccess_CDT(superior) {sco ftp}
  462. set sco_ftpAccess_CDT(subordinates) {{sco ftpAccess}}
  463. set sco_ftpLog_CDT(attributes) {
  464.     {
  465.         current_time
  466.         {
  467.             { validOperations get }
  468.             { validFilters {} }
  469.             { dataType single }
  470.         }
  471.     }
  472.     {
  473.         transfer_time
  474.         {
  475.             { validOperations get }
  476.             { validFilters {} }
  477.             { dataType single }
  478.         }
  479.     }
  480.     {
  481.         remote_host
  482.         {
  483.             { validOperations get }
  484.             { validFilters {} }
  485.             { dataType single }
  486.         }
  487.     }
  488.     {
  489.         file_size
  490.         {
  491.             { validOperations get }
  492.             { validFilters {} }
  493.             { dataType single }
  494.         }
  495.     }
  496.     {
  497.         filename
  498.         {
  499.             { validOperations get }
  500.             { validFilters {} }
  501.             { dataType single }
  502.         }
  503.     }
  504.     {
  505.         transfer_type
  506.         {
  507.             { validOperations get }
  508.             { validFilters {} }
  509.             { dataType single }
  510.         }
  511.     }
  512.     {
  513.         action
  514.         {
  515.             { validOperations get }
  516.             { validFilters {} }
  517.             { dataType single }
  518.         }
  519.     }
  520.     {
  521.         direction
  522.         {
  523.             { validOperations get }
  524.             { validFilters {} }
  525.             { dataType single }
  526.         }
  527.     }
  528.     {
  529.         access_mode
  530.         {
  531.             { validOperations get }
  532.             { validFilters {} }
  533.             { dataType single }
  534.         }
  535.     }
  536.     {
  537.         username
  538.         {
  539.             { validOperations get }
  540.             { validFilters {} }
  541.             { dataType single }
  542.         }
  543.     }
  544.     {
  545.         service_name
  546.         {
  547.             { validOperations get }
  548.             { validFilters {} }
  549.             { dataType single }
  550.         }
  551.     }
  552.     {
  553.         auth_method
  554.         {
  555.             { validOperations get }
  556.             { validFilters {} }
  557.             { dataType single }
  558.         }
  559.     }
  560.     {
  561.         user_id
  562.         {
  563.             { validOperations get }
  564.             { validFilters {} }
  565.             { dataType single }
  566.         }
  567.     }
  568.     {
  569.         domain
  570.         {
  571.             { validOperations get }
  572.             { validFilters {} }
  573.             { dataType single }
  574.             { description {address of virtual domain or localhost} }
  575.         }
  576.     }
  577. }
  578. set sco_ftpLog_CDT(groups) {}
  579. set sco_ftpLog_CDT(operations) {
  580.     {
  581.         get
  582.         {
  583.             { granularity perObject }
  584.             { function ftpLog_get }
  585.         }
  586.     }
  587.     {
  588.         action
  589.         {
  590.             { function ftpLog_action }
  591.             { granularity perObject }
  592.         }
  593.     }
  594. }
  595. set sco_ftpLog_CDT(class) {sco ftpLog}
  596. set sco_ftpLog_CDT(superior) {}
  597. set sco_ftpLog_CDT(subordinates) {}
  598. set sco_ftpAnon_CDT(attributes) {
  599.     {
  600.         home
  601.         {
  602.             { validOperations {get replace} }
  603.             { validFilters {} }
  604.             { dataType single }
  605.         }
  606.     }
  607.     {
  608.         uid
  609.         {
  610.             { validOperations {get replace} }
  611.             { validFilters {} }
  612.             { dataType single }
  613.         }
  614.     }
  615. }
  616. set sco_ftpAnon_CDT(groups) {}
  617. set sco_ftpAnon_CDT(operations) {
  618.     {
  619.         get
  620.         {
  621.             { granularity perAttribute }
  622.             { function ftpAnon_get }
  623.         }
  624.     }
  625.     {
  626.         replace
  627.         {
  628.             { granularity perObject }
  629.             { function ftpAnon_replace }
  630.         }
  631.     }
  632.     {
  633.         action
  634.         {
  635.             { function ftpAnon_action }
  636.             { granularity perObject }
  637.         }
  638.     }
  639. }
  640. set sco_ftpAnon_CDT(class) {sco ftpAnon}
  641. set sco_ftpAnon_CDT(superior) {}
  642. set sco_ftpAnon_CDT(subordinates) {}
  643. set sco_ftpAnonHome_CDT(attributes) {}
  644. set sco_ftpAnonHome_CDT(groups) {}
  645. set sco_ftpAnonHome_CDT(operations) {
  646.     {
  647.         action
  648.         {
  649.             { function ftpAnonHome_action }
  650.             { granularity perObject }
  651.         }
  652.     }
  653. }
  654. set sco_ftpAnonHome_CDT(class) {sco ftpAnonHome}
  655. set sco_ftpAnonHome_CDT(superior) {}
  656. set sco_ftpAnonHome_CDT(subordinates) {}
  657. set sco_ftpLimit_CDT(attributes) {
  658.     {
  659.         limitID
  660.         {
  661.             { validOperations {get replace} }
  662.             { validFilters {} }
  663.             { dataType single }
  664.         }
  665.     }
  666.     {
  667.         class
  668.         {
  669.             { validOperations {get replace} }
  670.             { validFilters {} }
  671.             { dataType single }
  672.         }
  673.     }
  674.     {
  675.         users
  676.         {
  677.             { validOperations {get replace} }
  678.             { validFilters {} }
  679.             { dataType single }
  680.         }
  681.     }
  682.     {
  683.         times
  684.         {
  685.             { validOperations {get replace} }
  686.             { validFilters {} }
  687.             { dataType single }
  688.         }
  689.     }
  690.     {
  691.         file
  692.         {
  693.             { validOperations {get replace} }
  694.             { validFilters {} }
  695.             { dataType single }
  696.         }
  697.     }
  698. }
  699. set sco_ftpLimit_CDT(groups) {}
  700. set sco_ftpLimit_CDT(operations) {
  701.     {
  702.         get
  703.         {
  704.             { granularity perAttribute }
  705.             { function ftpLimit_get }
  706.         }
  707.     }
  708.     {
  709.         replace
  710.         {
  711.             { granularity perObject }
  712.             { function ftpLimit_replace }
  713.         }
  714.     }
  715.     {
  716.         delete
  717.         {
  718.             { function ftpLimit_delete }
  719.             { granularity perObject }
  720.         }
  721.     }
  722.     {
  723.         create
  724.         {
  725.             { function ftpLimit_create }
  726.             { granularity perObject }
  727.         }
  728.     }
  729.     {
  730.         list
  731.         {
  732.             { granularity perObject }
  733.             { function ftpLimit_list }
  734.         }
  735.     }
  736. }
  737. set sco_ftpLimit_CDT(class) {sco ftpLimit}
  738. set sco_ftpLimit_CDT(superior) {sco ftp}
  739. set sco_ftpLimit_CDT(subordinates) {{sco ftpLimit}}
  740. set sco_ftpDenyUser_CDT(attributes) {
  741.     {
  742.         denied
  743.         {
  744.             { validOperations {get replace} }
  745.             { validFilters {} }
  746.             { dataType single }
  747.         }
  748.     }
  749.     {
  750.         user
  751.         {
  752.             { validOperations {get replace} }
  753.             { validFilters {} }
  754.             { dataType single }
  755.         }
  756.     }
  757. }
  758. set sco_ftpDenyUser_CDT(groups) {}
  759. set sco_ftpDenyUser_CDT(operations) {
  760.     {
  761.         get
  762.         {
  763.             { granularity perAttribute }
  764.             { function ftpDenyUser_get }
  765.         }
  766.     }
  767.     {
  768.         replace
  769.         {
  770.             { granularity perObject }
  771.             { function ftpDenyUser_replace }
  772.         }
  773.     }
  774.     {
  775.         create
  776.         {
  777.             { function ftpDenyUser_create }
  778.             { granularity perObject }
  779.         }
  780.     }
  781.     {
  782.         delete
  783.         {
  784.             { function ftpDenyUser_delete }
  785.             { granularity perObject }
  786.         }
  787.     }
  788.     {
  789.         list
  790.         {
  791.             { granularity perObject }
  792.             { function ftpDenyUser_list }
  793.         }
  794.     }
  795. }
  796. set sco_ftpDenyUser_CDT(class) {sco ftpDenyUser}
  797. set sco_ftpDenyUser_CDT(superior) {sco ftp}
  798. set sco_ftpDenyUser_CDT(subordinates) {{sco ftpDenyUser}}
  799. set sco_ftp_CDT(attributes) {
  800.     {
  801.         guestgroup
  802.         {
  803.             { validOperations {get replace} }
  804.             { validFilters {} }
  805.             { dataType set }
  806.         }
  807.     }
  808.     {
  809.         loginfails
  810.         {
  811.             { validOperations {get replace} }
  812.             { validFilters {} }
  813.             { dataType single }
  814.         }
  815.     }
  816.     {
  817.         private
  818.         {
  819.             { validOperations {get replace} }
  820.             { validFilters {} }
  821.             { dataType single }
  822.         }
  823.     }
  824.     {
  825.         email
  826.         {
  827.             { validOperations {get replace} }
  828.             { validFilters {} }
  829.             { dataType single }
  830.         }
  831.     }
  832.     {
  833.         log_commands
  834.         {
  835.             { validOperations {get replace} }
  836.             { validFilters {} }
  837.             { dataType set }
  838.         }
  839.     }
  840.     {
  841.         log_incoming
  842.         {
  843.             { validOperations {get replace} }
  844.             { validFilters {} }
  845.             { dataType set }
  846.         }
  847.     }
  848.     {
  849.         log_outgoing
  850.         {
  851.             { validOperations {get replace} }
  852.             { validFilters {} }
  853.             { dataType set }
  854.         }
  855.     }
  856.     {
  857.         shutdown
  858.         {
  859.             { validOperations {get replace} }
  860.             { validFilters {} }
  861.             { dataType single }
  862.         }
  863.     }
  864.     {
  865.         chmod
  866.         {
  867.             { validOperations {get replace} }
  868.             { validFilters {} }
  869.             { dataType set }
  870.         }
  871.     }
  872.     {
  873.         delete
  874.         {
  875.             { validOperations {get replace} }
  876.             { validFilters {} }
  877.             { dataType set }
  878.         }
  879.     }
  880.     {
  881.         overwrite
  882.         {
  883.             { validOperations {get replace} }
  884.             { validFilters {} }
  885.             { dataType set }
  886.         }
  887.     }
  888.     {
  889.         passwd_check
  890.         {
  891.             { validOperations {get replace} }
  892.             { validFilters {} }
  893.             { dataType single }
  894.         }
  895.     }
  896.     {
  897.         banner
  898.         {
  899.             { validOperations {get replace} }
  900.             { validFilters {} }
  901.             { dataType single }
  902.         }
  903.     }
  904.     {
  905.         timeout
  906.         {
  907.             { validOperations {get replace} }
  908.             { validFilters {} }
  909.             { dataType single }
  910.             { description {session timeout} }
  911.         }
  912.     }
  913.     {
  914.         maxtime
  915.         {
  916.             { validOperations {get replace} }
  917.             { validFilters {} }
  918.             { dataType single }
  919.             { description {max session timeout} }
  920.         }
  921.     }
  922. }
  923. set sco_ftp_CDT(groups) {}
  924. set sco_ftp_CDT(operations) {
  925.     {
  926.         get
  927.         {
  928.             { granularity perAttribute }
  929.             { function ftp_get }
  930.         }
  931.     }
  932.     {
  933.         replace
  934.         {
  935.             { granularity perAttribute }
  936.             { function ftp_replace }
  937.         }
  938.     }
  939.     {
  940.         list
  941.         {
  942.             { granularity perObject }
  943.             { function ftp_list }
  944.         }
  945.     }
  946.     {
  947.         action
  948.         {
  949.             { function ftp_action }
  950.             { granularity perObject }
  951.         }
  952.     }
  953. }
  954. set sco_ftp_CDT(class) {sco ftp}
  955. set sco_ftp_CDT(superior) {sco ftp}
  956. set sco_ftp_CDT(subordinates) {{sco ftpDenyHost} {sco ftpVirtual} {sco ftpMessage} {sco ftpAccess} {sco ftpLimit} {sco ftpDenyUser} {sco ftpClass}}
  957. set sco_ftpClass_CDT(attributes) {
  958.     {
  959.         typeList
  960.         {
  961.             { validOperations {get replace} }
  962.             { validFilters {} }
  963.             { dataType set }
  964.         }
  965.     }
  966.     {
  967.         addrList
  968.         {
  969.             { validOperations {get replace} }
  970.             { validFilters {} }
  971.             { dataType set }
  972.         }
  973.     }
  974.     {
  975.         autogroup
  976.         {
  977.             { validOperations {get replace} }
  978.             { validFilters {} }
  979.             { dataType single }
  980.         }
  981.     }
  982. }
  983. set sco_ftpClass_CDT(groups) {}
  984. set sco_ftpClass_CDT(operations) {
  985.     {
  986.         get
  987.         {
  988.             { granularity perAttribute }
  989.             { function ftpClass_get }
  990.         }
  991.     }
  992.     {
  993.         replace
  994.         {
  995.             { granularity perObject }
  996.             { function ftpClass_replace }
  997.         }
  998.     }
  999.     {
  1000.         create
  1001.         {
  1002.             { function ftpClass_create }
  1003.             { granularity perObject }
  1004.         }
  1005.     }
  1006.     {
  1007.         delete
  1008.         {
  1009.             { function ftpClass_delete }
  1010.             { granularity perObject }
  1011.         }
  1012.     }
  1013.     {
  1014.         list
  1015.         {
  1016.             { granularity perObject }
  1017.             { function ftpClass_list }
  1018.         }
  1019.     }
  1020. }
  1021. set sco_ftpClass_CDT(class) {sco ftpClass}
  1022. set sco_ftpClass_CDT(superior) {sco ftp}
  1023. set sco_ftpClass_CDT(subordinates) {{sco ftpClass}}
  1024. proc copy_file {oldname newname} {
  1025.     global isOwner
  1026.     if {![file isfile $oldname]} {
  1027.         return 0
  1028.     }
  1029.     if {$isOwner} {
  1030.         CallNonStdCmd /sbin/tfadmin "cpfile $oldname $newname" SCO_FTPOSA_ERR_CONFIG errStack
  1031.     } else {
  1032.         CallNonStdCmd /bin/cp "$oldname $newname" SCO_FTPOSA_ERR_CONFIG errStack
  1033.     }
  1034.     return 0
  1035. }
  1036. proc move_file {oldname newname} {
  1037.     global isOwner
  1038.     if {![file isfile $oldname]} {
  1039.         return 0
  1040.     }
  1041.     if {$isOwner} {
  1042.         CallNonStdCmd /sbin/tfadmin "cpfile $oldname $newname" SCO_FTPOSA_ERR_CONFIG errStack
  1043.         CallNonStdCmd /sbin/tfadmin "swUser root /bin/rm -f $oldname" SCO_FTPOSA_ERR_CONFIG errStack
  1044.     } else {
  1045.         CallNonStdCmd /bin/cp "$oldname $newname" SCO_FTPOSA_ERR_CONFIG errStack
  1046.         CallNonStdCmd /bin/rm "-f $oldname" SCO_FTPOSA_ERR_CONFIG errStack
  1047.     }
  1048.     return 0
  1049. }
  1050. proc backup_file {name} {
  1051.     copy_file $name $name-
  1052. }
  1053. proc log:exists { path } {
  1054.     return [expr {[file exists $path] && [file readable $path]}]
  1055. }
  1056. proc logRead {} {
  1057.     global ftp_log ftp_virtual ftp_Logfile ftp_Loglen ftp_Logmask isOwner
  1058.     set active_logs ""
  1059.     if {[log:exists $ftp_Logfile]} {
  1060.         if {$isOwner} {
  1061.             if {! [catch {open "|/sbin/tfadmin readfile $ftp_Logfile" r} fd(primary)]} {
  1062.                 set active_logs primary
  1063.                 set active_files(primary) $ftp_Logfile
  1064.             }
  1065.         } else {
  1066.             if {! [catch {open $ftp_Logfile r} fd(primary)]} {
  1067.                 set active_logs primary
  1068.                 set active_files(primary) $ftp_Logfile
  1069.             }
  1070.         }
  1071.     }
  1072.     if {[info exists ftp_virtual]} {
  1073.         foreach domain [array names ftp_virtual] {
  1074.             keylget ftp_virtual($domain) logfile filename
  1075.             if {$filename == ""} {
  1076.                 continue
  1077.             }
  1078.             if {[log:exists $filename]} {
  1079.                 if {$isOwner} {
  1080.                     if {[catch {open "|/sbin/tfadmin readfile $filename" r} fd($domain)]} {
  1081.                         continue
  1082.                     }
  1083.                 } else {
  1084.                     if {[catch {open $filename r} fd($domain)]} {
  1085.                         continue
  1086.                     }
  1087.                 }
  1088.                 lappend active_logs $domain
  1089.                 set active_files($domain) $filename
  1090.             }
  1091.         }
  1092.     }
  1093.     set active_logs [intersect $active_logs $ftp_Logmask]
  1094.     if {[lempty active_logs]} {
  1095.         return {}
  1096.     }
  1097.     set ftp_log {}
  1098.     set need_lines $active_logs
  1099.     while {![lempty $active_logs]} {
  1100.         foreach log $need_lines {
  1101.             if {[gets $fd($log) line($log)] == -1} {
  1102.                 close $fd($log)
  1103.                 lvarpop active_logs [lsearch $active_logs $log]
  1104.             } else {
  1105.                 set rec_time [lrange $line($log) 0 4]
  1106.                 set timestamp($log) [convertclock "$rec_time"]
  1107.             }
  1108.         }
  1109.         if {[lempty $active_logs]} {
  1110.             break
  1111.         }
  1112.         set need_lines ""
  1113.         set least_log [lindex $active_logs 0]
  1114.         set least_timestamp $timestamp($least_log)
  1115.         foreach log $active_logs {
  1116.             if {$timestamp($log) < $least_timestamp} {
  1117.                 set least_log $log
  1118.                 set least_timestamp $timestamp($log)
  1119.             }
  1120.         }
  1121.         if {$least_log != ""} {
  1122.             set need_lines $least_log
  1123.             set fields $line($least_log)
  1124.             set rec {}
  1125.             keylset rec domain        $least_log
  1126.             keylset rec current_time  [lrange $fields 0 4]
  1127.             keylset rec transfer_time [lindex $fields 5]
  1128.             keylset rec remote_host   [lindex $fields 6]
  1129.             keylset rec file_size     [lindex $fields 7]
  1130.             keylset rec filename      [lindex $fields 8]
  1131.             keylset rec transfer_type [lindex $fields 9]
  1132.             keylset rec action          [lindex $fields 10]
  1133.             keylset rec direction     [lindex $fields 11]
  1134.             keylset rec access_mode   [lindex $fields 12]
  1135.             keylset rec username      [lindex $fields 13]
  1136.             keylset rec service_name  [lindex $fields 14]
  1137.             keylset rec auth_method   [lindex $fields 15]
  1138.             keylset rec user_id       [lindex $fields 16]
  1139.             lappend ftp_log $rec
  1140.             if {$ftp_Loglen > 0 && [llength $ftp_log] >= $ftp_Loglen} {
  1141.                 lvarpop ftp_log
  1142.             }
  1143.         } else {
  1144.             error "there are log files but no next record"
  1145.         }
  1146.     }
  1147. }
  1148. proc setup_ftp_scancontexts {} {
  1149.     global ftp_scontext
  1150.     set ftp_scontext [scancontext create]
  1151.     scanmatch $ftp_scontext {^} {
  1152.         global ftp_lines ftp_lineindexes
  1153.         set lineindex $matchInfo(handle).$matchInfo(linenum)
  1154.         lappend ftp_lineindexes $lineindex
  1155.         set ftp_lines($lineindex) $matchInfo(line)
  1156.     }
  1157.     scanmatch $ftp_scontext {(^[     ]*;)|(^[     ]*$)|(^[     ]*#)} {
  1158.         continue
  1159.     }
  1160.     scanmatch -nocase $ftp_scontext {^[     ]*loginfails[     $]} {
  1161.         global ftp_loginfails
  1162.         if {[llength $matchInfo(line)] < 2} {
  1163.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1164.         } else {
  1165.             set ftp_loginfails($lineindex) [lindex $matchInfo(line) 1]
  1166.         }
  1167.         continue
  1168.     }
  1169.     scanmatch -nocase $ftp_scontext {^[     ]*private[     $]} {
  1170.         global ftp_private
  1171.         if {[llength $matchInfo(line)] < 2} {
  1172.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1173.         } else {
  1174.             set ftp_private($lineindex) [lindex $matchInfo(line) 1]
  1175.         }
  1176.         continue
  1177.     }
  1178.     scanmatch -nocase $ftp_scontext {^[     ]*banner[     $]} {
  1179.         global ftp_banner
  1180.         if {[llength $matchInfo(line)] < 2} {
  1181.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1182.         } else {
  1183.             set ftp_banner($lineindex) [lindex $matchInfo(line) 1]
  1184.         }
  1185.         continue
  1186.     }
  1187.     scanmatch -nocase $ftp_scontext {^[     ]*email[     $]} {
  1188.         global ftp_email
  1189.         if {[llength $matchInfo(line)] < 2} {
  1190.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1191.         } else {
  1192.             set ftp_email($lineindex) [lindex $matchInfo(line) 1]
  1193.         }
  1194.         continue
  1195.     }
  1196.     scanmatch -nocase $ftp_scontext {^[     ]*shutdown[     $]} {
  1197.         global ftp_shutdown
  1198.         if {[llength $matchInfo(line)] < 2} {
  1199.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1200.         } else {
  1201.             set ftp_shutdown($lineindex) [lindex $matchInfo(line) 1]
  1202.         }
  1203.         continue
  1204.     }
  1205.     scanmatch -nocase $ftp_scontext {^[     ]*virtual[     $]} {
  1206.         global ftp_virtual ftp_virtual_lines
  1207.         set line $matchInfo(line)
  1208.         if {[llength $line] < 4} {
  1209.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1210.             continue
  1211.         }
  1212.         set address [lindex $line 1]
  1213.         set token [lindex $line 2]
  1214.         set path [lindex $line 3]
  1215.         if {[lsearch [list root type banner logfile] $token] == -1} {
  1216.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1217.             continue
  1218.         }
  1219.         if [info exists ftp_virtual($address)] {
  1220.             set record $ftp_virtual($address)
  1221.             set record_lines $ftp_virtual_lines($address)
  1222.         } else {
  1223.             set record {{banner ""} {root ""} {logfile ""}}
  1224.             set record_lines {{banner ""} {root ""} {logfile ""}}
  1225.         }
  1226.         keylset record_lines $token $lineindex
  1227.         keylset record $token $path
  1228.         set ftp_virtual_lines($address) $record_lines
  1229.         set ftp_virtual($address) $record
  1230.         continue
  1231.     }
  1232.     scanmatch -nocase $ftp_scontext {^[     ]*class[     $]} {
  1233.         global ftp_classes
  1234.         set line $matchInfo(line)
  1235.         if {[llength $line] < 4} {
  1236.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1237.             continue
  1238.         }
  1239.         set class [lindex $line 1]
  1240.         if [info exists ftp_classes($class)] {
  1241.             set record $ftp_classes($class)
  1242.             keylget record lines lines
  1243.             lappend lines $lineindex
  1244.             keylset record lines $lines
  1245.         } else {
  1246.             set record {}
  1247.             keylset record groups {}
  1248.             keylset record lines $lineindex
  1249.         }
  1250.         keylset record typelist [split [lindex $line 2] ","]
  1251.         keylset record addrs [lrange $line 3 end]
  1252.         set ftp_classes($class) $record
  1253.         continue
  1254.     }
  1255.     scanmatch -nocase $ftp_scontext {^[     ]*autogroup[     $]} {
  1256.         global ftp_classes
  1257.         set line $matchInfo(line)
  1258.         if {[llength $line] < 3} {
  1259.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1260.             continue
  1261.         }
  1262.         foreach class [lrange $line 2 end] {
  1263.             if [info exists ftp_classes($class)] {
  1264.                 set record $ftp_classes($class)
  1265.                 keylget record groups groups
  1266.                 lappend groups [lindex $line 1]
  1267.                 keylset record groups $groups
  1268.                 keylget record lines lines
  1269.                 lappend lines $lineindex
  1270.                 keylset record lines $lines
  1271.             } else {
  1272.                 set record {}
  1273.                 keylset record lines $lineindex
  1274.                 keylset record typelist {}
  1275.                 keylset record addrs {}
  1276.                 keylset record groups [lindex $line 1]
  1277.             }
  1278.             set ftp_classes($class) $record
  1279.         }
  1280.     }
  1281.     scanmatch -nocase $ftp_scontext {^[     ]*deny[     $]} {
  1282.         global ftp_deny_hosts
  1283.         if { ! [regsub {;.*$} $matchInfo(line) {} line]} {
  1284.             set line $matchInfo(line)
  1285.         }
  1286.         if {[llength $line] < 2} {
  1287.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1288.             continue
  1289.         }
  1290.         set ftp_deny_hosts($lineindex) [lrange $line 1 end]
  1291.         continue
  1292.     }
  1293.     scanmatch -nocase $ftp_scontext {^[     ]*guestgroup[     $]} {
  1294.         global ftp_guestgroup
  1295.         if { ! [regsub {;.*$} $matchInfo(line) {} line]} {
  1296.             set line $matchInfo(line)
  1297.         }
  1298.         if {[llength $line] < 2} {
  1299.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1300.             continue
  1301.         }
  1302.         set ftp_guestgroup($lineindex) [lrange $line 1 end]
  1303.         continue
  1304.     }
  1305.     scanmatch -nocase $ftp_scontext {^[     ]*limit[     $]} {
  1306.         global ftp_limit limit_index
  1307.         if { ! [regsub {;.*$} $matchInfo(line) {} line$]} {
  1308.             set line $matchInfo(line)
  1309.         }
  1310.         set l [llength $line]
  1311.         if {$l < 4} {
  1312.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1313.             continue
  1314.         }
  1315.         set ftp_limit($lineindex) "$limit_index [lrange $line 1 end]"
  1316.         incr limit_index
  1317.         continue
  1318.     }
  1319.     scanmatch -nocase $ftp_scontext {^[     ]*readme[     ]} {
  1320.         global ftp_message
  1321.         if { ! [regsub {;.*$} $matchInfo(line) {} line]} {
  1322.             set line $matchInfo(line)
  1323.         }
  1324.         if {[llength $line] < 2} {
  1325.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1326.             continue
  1327.         }
  1328.         set file [lindex $line 1]
  1329.         set when [lindex $line 2]
  1330.         if {($when == {}) || ($when == "login")} {
  1331.             set when "LOGIN"
  1332.         } else {
  1333.             regsub -nocase "^cwd=" $when "" when
  1334.         }
  1335.         set class [lrange $line 3 [llength $line]]
  1336.         set ftp_message($lineindex) [list README_$when $when $file $class]
  1337.         continue
  1338.     }
  1339.     scanmatch -nocase $ftp_scontext {^[     ]*message[     $]} {
  1340.         global ftp_message
  1341.         if { ! [regsub {;.*$} $matchInfo(line) {} line]} {
  1342.             set line $matchInfo(line)
  1343.         }
  1344.         if {[llength $line] < 2} {
  1345.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1346.             continue
  1347.         }
  1348.         set file [lindex $line 1]
  1349.         set when [lindex $line 2]
  1350.         if {($when == {}) || ($when == "login")} {
  1351.             set when "LOGIN"
  1352.         } else {
  1353.             regsub -nocase "^cwd=" $when "" when
  1354.         }
  1355.         set class [lrange $line 3 [llength $line]]
  1356.         set ftp_message($lineindex) [list MESSAGE_$when $when $file $class]
  1357.         continue
  1358.     }
  1359.     scanmatch -nocase $ftp_scontext {^[     ]*log[     $]} {
  1360.         global ftp_log_commands ftp_log_incoming ftp_log_outgoing
  1361.         if { ! [regsub {;.*$} $matchInfo(line) {} line]} {
  1362.             set line $matchInfo(line)
  1363.         }
  1364.         if {[lindex $line 1] == "commands"} {
  1365.             if {[llength $line] < 2} {
  1366.                 ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1367.                 continue
  1368.             }
  1369.             set typelist [split [lindex $line 2] ","]
  1370.             set ftp_log_commands($lineindex) $typelist
  1371.         } else {
  1372.             if {[llength $line] < 3} {
  1373.                 ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1374.                 continue
  1375.             }
  1376.             set typelist [split [lindex $line 2] ","]
  1377.             set directions [split [lindex $line 3] ","]
  1378.             foreach dir $directions {
  1379.                 if {$dir == "inbound"} {
  1380.                     set ftp_log_incoming($lineindex) $typelist
  1381.                 } else {
  1382.                     set ftp_log_outgoing($lineindex) $typelist
  1383.                 }
  1384.             }
  1385.         }
  1386.         continue
  1387.     }
  1388.     scanmatch -nocase $ftp_scontext {^[     ]*chmod[     $]} {
  1389.         global ftp_chmod
  1390.         if { ! [regsub {;.*$} $matchInfo(line) {} line]} {
  1391.             set line $matchInfo(line)
  1392.         }
  1393.         if {[llength $line] < 3} {
  1394.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1395.             continue
  1396.         }
  1397.         set typelist [split [lindex $line 2] ","]
  1398.         set ftp_chmod($lineindex) "[lindex $line 1] $typelist"
  1399.         continue
  1400.     }
  1401.     scanmatch -nocase $ftp_scontext {^[     ]*delete[     $]} {
  1402.         global ftp_delete
  1403.         if { ! [regsub {;.*$} $matchInfo(line) {} line]} {
  1404.             set line $matchInfo(line)
  1405.         }
  1406.         if {[llength $line] < 3} {
  1407.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1408.             continue
  1409.         }
  1410.         set typelist [split [lindex $line 2] ","]
  1411.         set ftp_delete($lineindex) "[lindex $line 1] $typelist"
  1412.         continue
  1413.     }
  1414.     scanmatch -nocase $ftp_scontext {^[     ]*overwrite[     $]} {
  1415.         global ftp_overwrite
  1416.         if { ! [regsub {;.*$} $matchInfo(line) {} line]} {
  1417.             set line $matchInfo(line)
  1418.         }
  1419.         if {[llength $line] < 3} {
  1420.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1421.             continue
  1422.         }
  1423.         set typelist [split [lindex $line 2] ","]
  1424.         set ftp_overwrite($lineindex) "[lindex $line 1] $typelist"
  1425.         continue
  1426.     }
  1427.     scanmatch -nocase $ftp_scontext {^[     ]*passwd-check[     $]} {
  1428.         global ftp_passwd_check
  1429.         if { ! [regsub {;.*$} $matchInfo(line) {} line]} {
  1430.             set line $matchInfo(line)
  1431.         }
  1432.         if {[llength $line] < 2} {
  1433.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1434.             continue
  1435.         }
  1436.         if {[llength $line] == 2} {
  1437.             lappend line "warn"
  1438.         }
  1439.         set ftp_passwd_check($lineindex) [lrange $line 1 end]
  1440.         continue
  1441.     }
  1442.     scanmatch -nocase $ftp_scontext {^[     ]*upload[     $]} {
  1443.         global ftp_access ftp_access_index
  1444.         if { ! [regsub {;.*$} $matchInfo(line) {} line]} {
  1445.             set line $matchInfo(line)
  1446.         }
  1447.         set l [llength $line]
  1448.         if {$l < 4} {
  1449.             ErrorPush {} 1 SCO_FTPOSA_ERR_SYNTAX "$matchInfo(line)"
  1450.             continue
  1451.         }
  1452.         set home     [lindex $line 1]
  1453.         set dir      [lindex $line 2]
  1454.         set uploads  [string tolower [lindex $line 3]]
  1455.         if {$l > 5} {
  1456.             set owner [lindex $line 4]
  1457.             set group [lindex $line 5]
  1458.         } else {
  1459.             set owner ""
  1460.             set group ""
  1461.         }
  1462.         if {$l > 6} {
  1463.             set mode [lindex $line 6]
  1464.         } else {
  1465.             set mode ""
  1466.         }
  1467.         if {$l > 7 || $l == 5} {
  1468.             set subdirs [string tolower [lindex $line end]]
  1469.             if {![cequal $subdirs dirs] && ![cequal $subdirs nodirs]} {
  1470.                 set subdirs nodirs
  1471.             }
  1472.         } else {
  1473.             set subdirs nodirs
  1474.         }
  1475.         set ftp_access($lineindex) [list $ftp_access_index $home $dir $uploads $owner $group $mode $subdirs]
  1476.         incr ftp_access_index
  1477.         continue
  1478.     }
  1479. }
  1480. proc ftp_addline {before line} {
  1481.     global ftp_lines ftp_lineindexes ftp_newindex_ftpaccess ftp_modified_ftpaccess
  1482.     if {$before == "end"} {
  1483.         if {[catch {llength $ftp_lineindexes} index]} {
  1484.             set index 0
  1485.         }
  1486.     } else {
  1487.         if {[catch {llength $ftp_lineindexes} index]} {
  1488.             set index 0
  1489.         } else {
  1490.             if {[set index [lsearch $ftp_lineindexes $before]] == -1} {
  1491.                 ErrorPush {} 1 SCO_FTPOSA_ERR_BUG_ERR
  1492.                 return
  1493.             }
  1494.         }
  1495.     }
  1496.     set newindex new.$ftp_newindex_ftpaccess
  1497.     if {[catch {llength $ftp_lineindexes} index]} {
  1498.         set ftp_lineindexes $newindex
  1499.     } else {
  1500.         set ftp_lineindexes [linsert $ftp_lineindexes $index $newindex]
  1501.     }
  1502.     set ftp_lines($newindex) $line
  1503.     incr ftp_newindex_ftpaccess
  1504.     set ftp_modified_ftpaccess 1
  1505.     return $newindex
  1506. }
  1507. proc ftp_rmline {line} {
  1508.     global ftp_lineindexes ftp_modified_ftpaccess
  1509.     if {[set index [lsearch -exact $ftp_lineindexes $line]] == -1} {
  1510.         ErrorPush {} 1 SCO_FTPOSA_ERR_BUG_ERR
  1511.         return
  1512.     }
  1513.     lvarpop ftp_lineindexes $index
  1514.     set ftp_modified_ftpaccess 1
  1515. }
  1516. proc list_guestgroup {} {
  1517.     global ftp_guestgroup
  1518.     if [catch {array names ftp_guestgroup} linelist] {
  1519.         return {}
  1520.     }
  1521.     set result "" 
  1522.     foreach line [lsort $linelist] {
  1523.         lappend result $ftp_guestgroup($line)
  1524.     }
  1525.     return $result
  1526. }
  1527. proc rm_guestgroup {group} {
  1528.     global ftp_guestgroup ftp_lines ftp_modified_ftpaccess
  1529.     if [catch {array names ftp_guestgroup} linelist] {
  1530.         return
  1531.     }
  1532.     foreach line $linelist {
  1533.         set grouplist $ftp_guestgroup($line)
  1534.         loop index 0 [llength $grouplist] {
  1535.             if {[lindex $grouplist $index] == $group} {
  1536.                 break
  1537.             }
  1538.         }
  1539.         if {[lindex $grouplist $index] != $group} {
  1540.             continue
  1541.         }
  1542.         if {[llength $grouplist] == 1} {
  1543.             unset ftp_guestgroup($line)
  1544.             ftp_rmline $line
  1545.         } else {
  1546.             lvarpop ftp_guestgroup($line) $index
  1547.             incr index
  1548.             lvarpop ftp_lines($line) $index
  1549.             set ftp_modified_ftpaccess 1
  1550.         }
  1551.     }
  1552. }
  1553. proc add_guestgroup {value} {
  1554.     global ftp_guestgroup
  1555.     set index [ftp_addline end "guestgroup $value"]
  1556.     set ftp_guestgroup($index) $value
  1557. }
  1558. proc get_loginfails {} {
  1559.     global ftp_loginfails
  1560.     if [catch {array names ftp_loginfails} linelist] {
  1561.         return {}
  1562.     }
  1563.     if {[lempty $linelist]} {
  1564.         return {}
  1565.     }
  1566.     set result $ftp_loginfails([lindex $linelist 0])
  1567.     return $result
  1568. }
  1569. proc rm_loginfails {} {
  1570.         global ftp_loginfails
  1571.         if [catch {array names ftp_loginfails} linelist] {
  1572.             return {}
  1573.         }
  1574.         foreach line $linelist {
  1575.             unset ftp_loginfails($line)
  1576.             ftp_rmline $line
  1577.         }
  1578. }
  1579. proc set_loginfails {value} {
  1580.     global ftp_loginfails
  1581.     set line "loginfails    $value"
  1582.     set index [ftp_addline end $line]
  1583.     set ftp_loginfails($index) $value
  1584. }
  1585. proc get_private {} {
  1586.     global ftp_private
  1587.     if [catch {array names ftp_private} linelist] {
  1588.         return {}
  1589.     }
  1590.     if {[lempty $linelist]} {
  1591.         return {}
  1592.     }
  1593.     set result $ftp_private([lindex $linelist 0])
  1594.     return $result
  1595. }
  1596. proc rm_private {} {
  1597.     global ftp_private
  1598.     if [catch {array names ftp_private} linelist] {
  1599.         return {}
  1600.     }
  1601.     if {[lempty $linelist]} {
  1602.         return {}
  1603.     }
  1604.     foreach line $linelist {
  1605.         unset ftp_private($line)
  1606.         ftp_rmline $line
  1607.     }
  1608. }
  1609. proc set_private {value} {
  1610.     global ftp_private
  1611.     set line "private    $value"
  1612.     set index [ftp_addline end $line]
  1613.     set ftp_private($index) $value
  1614. }
  1615. proc get_email {} {
  1616.     global ftp_email
  1617.     if [catch {array names ftp_email} linelist] {
  1618.         return {}
  1619.     }
  1620.     if {[lempty $linelist]} {
  1621.         return {}
  1622.     }
  1623.     set result $ftp_email([lindex $linelist 0])
  1624.     return $result
  1625. }
  1626. proc rm_email {} {
  1627.     global ftp_email
  1628.     if [catch {array names ftp_email} linelist] {
  1629.         return {}
  1630.     }
  1631.     if {[lempty $linelist]} {
  1632.         return {}
  1633.     }
  1634.     foreach line $linelist {
  1635.         unset ftp_email($line)
  1636.         ftp_rmline $line
  1637.     }
  1638. }
  1639. proc set_email {value} {
  1640.     global ftp_email
  1641.     set line "email    $value"
  1642.     set index [ftp_addline end $line]
  1643.     set ftp_email($index) $value
  1644. }
  1645. proc write_inetd_conf {} {
  1646.     global inetd_conf_lines ftp_ConfigDir isOwner
  1647.     if {[catch {array names inetd_conf_lines} indices]} {
  1648.         return -1
  1649.     }
  1650.     set indices [lsort -integer $indices]
  1651.     set inetd_conf_file $ftp_ConfigDir/inetd.conf
  1652.     backup_file $inetd_conf_file
  1653.     if {$isOwner} {
  1654.         if {[catch {open "|/sbin/tfadmin writefile $inetd_conf_file" w} fd]} {
  1655.             catch {exec /sbin/tfadmin cpfile $inetd_conf_file- $inetd_conf_file}
  1656.             return -1
  1657.         }
  1658.     } else {
  1659.         if {[catch {open $inetd_conf_file w} fd]} {
  1660.             catch {exec /bin/cp $inetd_conf_file- $inetd_conf_file}
  1661.             return -1
  1662.         }
  1663.     }
  1664.     foreach index $indices {
  1665.         puts $fd $inetd_conf_lines($index)
  1666.     }
  1667.     close $fd
  1668. }
  1669. proc read_inetd_conf {} {
  1670.     global inetd_conf_lines ftp_ConfigDir isOwner
  1671.     catch {unset inetd_conf_lines}
  1672.     set inetd_conf_file $ftp_ConfigDir/inetd.conf
  1673.     if {$isOwner} {
  1674.         if {[catch {open "|/sbin/tfadmin readfile inetd_conf_file" r} fd]} {
  1675.             return -1
  1676.         }
  1677.     } else {
  1678.         if {[catch {open $inetd_conf_file r} fd]} {
  1679.             return -1
  1680.         }
  1681.     }
  1682.     set lineindex 0
  1683.     set ftp_index -1
  1684.     set sc [scancontext create]
  1685.     scanmatch $sc {^ftp[     ].*$} {
  1686.         set ftp_index $lineindex
  1687.     }
  1688.     scanmatch $sc  {.*} {
  1689.         set inetd_conf_lines($lineindex) $matchInfo(line)
  1690.         incr lineindex
  1691.         continue
  1692.     }
  1693.     scanfile $sc $fd
  1694.     close $fd
  1695.     scancontext delete $sc
  1696.     return $ftp_index
  1697. }
  1698. proc get_inetd_conf {what {hasArg 0}} {
  1699.     global inetd_conf_lines
  1700.     set ftp_index [read_inetd_conf]
  1701.     if {$ftp_index == -1} {
  1702.         return { 0 }
  1703.     }
  1704.     if {[llength $inetd_conf_lines($ftp_index)] < 7} {
  1705.         return { 0 }
  1706.     }
  1707.     set args [lrange $inetd_conf_lines($ftp_index) 7 end]
  1708.     set len_args [llength $args]
  1709.     for {set index 0} {$index < $len_args} {incr index} {
  1710.         set next_index [expr $index + 1]
  1711.         if {[cequal [lindex $args $index] "$what"]} {
  1712.             if {$hasArg && $next_index < $len_args} {
  1713.                 return [list 1 [lindex $args $next_index]]
  1714.             } elseif {$hasArg} {
  1715.                 return { 0 }
  1716.             } else {
  1717.                 return { 1 }
  1718.             }
  1719.         }
  1720.     }    
  1721.     return { 0 }
  1722. }
  1723. proc poke_inetd_conf {} {
  1724.     global inetd_path isOwner
  1725.     if {[catch {open "|/bin/ps -e -opid -oargs" r} fd]} {
  1726.         return
  1727.     }
  1728.     set pid_list {}
  1729.     while {! [eof $fd]} {
  1730.         gets $fd line
  1731.         set pid [lindex $line 0]
  1732.         set com [lindex $line 1]
  1733.         if {$com == $inetd_path} {
  1734.             lappend pid_list $pid
  1735.         }
  1736.     }
  1737.     foreach pid $pid_list {    
  1738.         if {$isOwner} {
  1739.             catch {exec /sbin/tfadmin kill 1 $pid}
  1740.         } else {
  1741.             catch {kill 1 $pid}
  1742.         }
  1743.     }
  1744. }
  1745. proc set_inetd_conf {what {hasArg 0} {isAdd 1} {value ""}} {
  1746.     global inetd_conf_lines
  1747.     set ftp_index [read_inetd_conf]
  1748.     if {$ftp_index == -1} {
  1749.         return 0
  1750.     }
  1751.     if {[llength $inetd_conf_lines($ftp_index)] < 7} {
  1752.         return 0
  1753.     }
  1754.     set pre_args [lrange $inetd_conf_lines($ftp_index) 0 6]
  1755.     set args [lrange $inetd_conf_lines($ftp_index) 7 end]
  1756.     set len_args [llength $args]
  1757.     for {set index 0} {$index < $len_args} {incr index} {
  1758.         set next_index [expr $index + 1]
  1759.         if {[cequal [lindex $args $index] "$what"]} {
  1760.             if {$hasArg && $next_index < $len_args} {
  1761.                 if {$isAdd} {
  1762.                     lvarpop args $next_index $value
  1763.                 } else {
  1764.                     lvarpop args $next_index
  1765.                     lvarpop args $index
  1766.                 }
  1767.                 set inetd_conf_lines($ftp_index) [concat $pre_args $args]
  1768.                 write_inetd_conf
  1769.                 return 1
  1770.             } elseif {$hasArg} {
  1771.                 if {$isAdd} {
  1772.                     lappend args $value
  1773.                 } else {
  1774.                     lvarpop args $index
  1775.                 }
  1776.                 set inetd_conf_lines($ftp_index) [concat $pre_args $args]
  1777.                 write_inetd_conf
  1778.                 return 1
  1779.             } else {
  1780.                 if {$isAdd} {
  1781.                 } else {
  1782.                     lvarpop args $index
  1783.                 }
  1784.                 set inetd_conf_lines($ftp_index) [concat $pre_args $args]
  1785.                 write_inetd_conf
  1786.                 return 1
  1787.             }
  1788.         }
  1789.     }    
  1790.     if {$isAdd} {
  1791.         lappend args $what
  1792.         if {$hasArg} {
  1793.             lappend args $value
  1794.         }
  1795.     }
  1796.     set inetd_conf_lines($ftp_index) [concat $pre_args $args]
  1797.     write_inetd_conf
  1798.     return 1
  1799. }
  1800. proc OSA:get_banner {} {
  1801.     global ftp_banner
  1802.     if [catch {array names ftp_banner} linelist] {
  1803.         return {}
  1804.     }
  1805.     if {[lempty $linelist]} {
  1806.         return {}
  1807.     }
  1808.     set result $ftp_banner([lindex $linelist 0])
  1809.     return $result
  1810. }
  1811. proc rm_banner {} {
  1812.     global ftp_banner
  1813.     if [catch {array names ftp_banner} linelist] {
  1814.         return {}
  1815.     }
  1816.     if {[lempty $linelist]} {
  1817.         return {}
  1818.     }
  1819.     foreach line $linelist {
  1820.         unset ftp_banner($line)
  1821.         ftp_rmline $line
  1822.     }
  1823. }
  1824. proc set_banner {value} {
  1825.     global ftp_banner
  1826.     set line "banner    $value"
  1827.     set index [ftp_addline end $line]
  1828.     set ftp_banner($index) $value
  1829. }
  1830. proc list_log_commands {} {
  1831.     global ftp_log_commands
  1832.     if [catch {array names ftp_log_commands} linelist] {
  1833.         return {}
  1834.     }
  1835.     set result {}
  1836.     foreach line [lsort $linelist] {
  1837.         set result [concat $result $ftp_log_commands($line)]
  1838.     }
  1839.     return $result
  1840. }
  1841. proc rm_log_commands {type} {
  1842.     global ftp_log_commands ftp_lines ftp_modified_ftpaccess
  1843.     if [catch {array names ftp_log_commands} linelist] {
  1844.         return
  1845.     }
  1846.     foreach line $linelist {
  1847.         set typelist $ftp_log_commands($line)
  1848.         loop index 0 [llength $typelist] {
  1849.             if {[lindex $typelist $index] == $type} {
  1850.                 break
  1851.             }
  1852.         }
  1853.         if {[lindex $typelist $index] != $type} {
  1854.             continue
  1855.         }
  1856.         if {[llength $typelist] == 1} {
  1857.             unset ftp_log_commands($line)
  1858.             ftp_rmline $line
  1859.         } else {
  1860.             lvarpop ftp_log_commands($line) $index
  1861.             incr index
  1862.             lvarpop ftp_lines($line) $index
  1863.             set ftp_modified_ftpaccess 1
  1864.         }
  1865.     }
  1866. }
  1867. proc add_log_commands {value} {
  1868.     global ftp_log_commands
  1869.     set index [ftp_addline end "log commands $value"]
  1870.     set ftp_log_commands($index) $value
  1871. }
  1872. proc list_log_incoming {} {
  1873.     global ftp_log_incoming
  1874.     if [catch {array names ftp_log_incoming} linelist] {
  1875.         return {}
  1876.     }
  1877.     set result {}
  1878.     foreach line [lsort $linelist] {
  1879.         set result [concat $result $ftp_log_incoming($line)]
  1880.     }
  1881.     return $result
  1882. }
  1883. proc rm_log_incoming {value} {
  1884.     global ftp_log_incoming ftp_log_outgoing ftp_lines ftp_modified_ftpaccess
  1885.     if [catch {array names ftp_log_incoming} linelist] {
  1886.         return
  1887.     }
  1888.     foreach line $linelist {
  1889.         set typelist $ftp_log_incoming($line)
  1890.         set found 0
  1891.         loop index 0 [llength $typelist] {
  1892.             if {[lindex $typelist $index] == $value} {
  1893.                 set found 1
  1894.                 break
  1895.             }
  1896.         }
  1897.         if {$found} {
  1898.                 if [info exists ftp_log_outgoing($line)] {
  1899.                 set newindex [ftp_addline end "log transfers $typelist outbound"]
  1900.                 set ftp_log_outgoing($newindex) $typelist
  1901.                 unset ftp_log_outgoing($line)
  1902.             }
  1903.             if {[llength $typelist] == 1} {
  1904.                 unset ftp_log_incoming($line)
  1905.                 ftp_rmline $line
  1906.             } else {
  1907.                 lvarpop ftp_log_incoming($line) $index
  1908.                 incr index
  1909.                 set ftp_lines($line) "log transfers $ftp_log_incoming($line) inbound"
  1910.                 set ftp_modified_ftpaccess 1
  1911.             }
  1912.         }
  1913.     }
  1914. }
  1915. proc add_log_incoming {value} {
  1916.     global ftp_log_incoming
  1917.     set index [ftp_addline end "log transfers $value inbound"]
  1918.     set ftp_log_incoming($index) "$value"
  1919. }
  1920. proc list_log_outgoing {} {
  1921.     global ftp_log_outgoing
  1922.     if [catch {array names ftp_log_outgoing} linelist] {
  1923.         return {}
  1924.     }
  1925.     set result {}
  1926.     foreach line [lsort $linelist] {
  1927.         set result [concat $result $ftp_log_outgoing($line)]
  1928.     }
  1929.     return $result
  1930. }
  1931. proc rm_log_outgoing {value} {
  1932.     global ftp_log_incoming ftp_log_outgoing ftp_lines ftp_modified_ftpaccess
  1933.     if [catch {array names ftp_log_outgoing} linelist] {
  1934.         return
  1935.     }
  1936.     foreach line $linelist {
  1937.         set typelist $ftp_log_outgoing($line)
  1938.         set found 0
  1939.         loop index 0 [llength $typelist] {
  1940.             if {[lindex $typelist $index] == $value} {
  1941.                 set found 1
  1942.                 break
  1943.             }
  1944.         }
  1945.         if {$found} {
  1946.                 if [info exists ftp_log_incoming($line)] {
  1947.                 set newindex [ftp_addline end "log transfers $typelist inbound"]
  1948.                 set ftp_log_incoming($newindex) $typelist
  1949.                 unset ftp_log_incoming($line)
  1950.             }
  1951.             if {[llength $typelist] == 1} {
  1952.                 unset ftp_log_outgoing($line)
  1953.                 ftp_rmline $line
  1954.             } else {
  1955.                 lvarpop ftp_log_outgoing($line) $index
  1956.                 incr index
  1957.                 set ftp_lines($line) "log transfers $ftp_log_outgoing($line) outbound"
  1958.                 set ftp_modified_ftpaccess 1
  1959.             }
  1960.         }
  1961.     }
  1962. }
  1963. proc add_log_outgoing {value} {
  1964.     global ftp_log_outgoing
  1965.     set index [ftp_addline end "log transfers $value outbound"]
  1966.     set ftp_log_outgoing($index) "$value"
  1967. }
  1968. proc get_shutdown {} {
  1969.     global ftp_shutdown
  1970.     if [catch {array names ftp_shutdown} linelist] {
  1971.         return {}
  1972.     }
  1973.     if {[lempty $linelist]} {
  1974.         return {}
  1975.     }
  1976.     set result $ftp_shutdown([lindex $linelist 0])
  1977.     return $result
  1978. }
  1979. proc rm_shutdown {} {
  1980.     global ftp_shutdown
  1981.     if [catch {array names ftp_shutdown} linelist] {
  1982.         return {}
  1983.     }
  1984.     foreach line $linelist {
  1985.         unset ftp_shutdown($line)
  1986.         ftp_rmline $line
  1987.     }
  1988. }
  1989. proc set_shutdown {value} {
  1990.     global ftp_shutdown
  1991.     set line "shutdown    $value"
  1992.     set index [ftp_addline end $line]
  1993.     set ftp_shutdown($index) $value
  1994. }
  1995. proc list_chmod {} {
  1996.     global ftp_chmod
  1997.     if [catch {array names ftp_chmod} linelist] {
  1998.         return {}
  1999.     }
  2000.     set result "anonymous real guest"
  2001.     foreach line [lsort $linelist] {
  2002.         set type  [lindex $ftp_chmod($line) 0]
  2003.         set users [lrange $ftp_chmod($line) 1 end]
  2004.         if {$type == "no"} {
  2005.             set result [lindex [intersect3 $result $users] 0]
  2006.         }
  2007.     }
  2008.     return $result
  2009. }
  2010. proc rm_chmod {value} {
  2011.     global ftp_chmod ftp_lines ftp_modified_ftpaccess
  2012.     if [catch {array names ftp_chmod} linelist] {
  2013.         set index [ftp_addline end "chmod no $value"]
  2014.         set ftp_chmod($index) "no $value"
  2015.         return
  2016.     }
  2017.     foreach line $linelist {
  2018.         set type  [lindex $ftp_chmod($line) 0]
  2019.         set users [lrange $ftp_chmod($line) 1 end]
  2020.         set found 0
  2021.         loop index 0 [llength $users] {
  2022.             if {([lindex $users $index] == $value) && ($type == "yes")} {
  2023.                 set found 1
  2024.                 break
  2025.             }
  2026.         }
  2027.         if {$found} {
  2028.             if {[llength $users] == 1} {
  2029.                 unset ftp_chmod($line)
  2030.                 ftp_rmline $line
  2031.             } else {
  2032.                 lvarpop ftp_chmod($line) $index
  2033.                 incr index
  2034.                 lvarpop ftp_lines($line) $index
  2035.                 set ftp_modified_ftpaccess 1
  2036.             }
  2037.         }
  2038.     }
  2039.     set index [ftp_addline end "chmod no $value"]
  2040.     set ftp_chmod($index) "no $value"
  2041. }
  2042. proc add_chmod {value} {
  2043.     global ftp_chmod
  2044.     if [catch {array names ftp_chmod} linelist] {
  2045.         set index [ftp_addline end "chmod yes $value"]
  2046.         set ftp_chmod($index) "yes $value"
  2047.     } else {
  2048.         set found 0
  2049.         foreach line [lsort $linelist] {
  2050.             set type  [lindex $ftp_chmod($line) 0]
  2051.             set users [lrange $ftp_chmod($line) 1 end]
  2052.             set found 0
  2053.             loop index 0 [llength $users] {
  2054.                 if {($type == "no") && ([lindex $users $index] == $value)} {
  2055.                     set found 1
  2056.                     break
  2057.                 }
  2058.             }
  2059.             if {$found} {
  2060.                 if {[llength $users] == 1} {
  2061.                     unset ftp_chmod($line)
  2062.                     ftp_rmline $line
  2063.                 } else {
  2064.                     lvarpop ftp_chmod($line) $index
  2065.                     incr index
  2066.                     lvarpop ftp_lines($line) $index
  2067.                     set ftp_modified_ftpaccess 1
  2068.                 }
  2069.             }
  2070.         }
  2071.         set index [ftp_addline end "chmod yes $value"]
  2072.         set ftp_chmod($index) "yes $value"
  2073.     }
  2074. }
  2075. proc list_delete {} {
  2076.     global ftp_delete
  2077.     if [catch {array names ftp_delete} linelist] {
  2078.         return {}
  2079.     }
  2080.     set result "anonymous real guest"
  2081.     foreach line [lsort $linelist] {
  2082.         set type  [lindex $ftp_delete($line) 0]
  2083.         set users [lrange $ftp_delete($line) 1 end]
  2084.         if {$type == "no"} {
  2085.             set result [lindex [intersect3 $result $users] 0]
  2086.         }
  2087.     }
  2088.     return $result
  2089. }
  2090. proc rm_delete {value} {
  2091.     global ftp_delete ftp_lines ftp_modified_ftpaccess
  2092.     if [catch {array names ftp_delete} linelist] {
  2093.         set index [ftp_addline end "delete no $value"]
  2094.         set ftp_delete($index) "no $value"
  2095.         return
  2096.     }
  2097.     foreach line $linelist {
  2098.         set type  [lindex $ftp_delete($line) 0]
  2099.         set users [lrange $ftp_delete($line) 1 end]
  2100.         set found 0
  2101.         loop index 0 [llength $users] {
  2102.             if {([lindex $users $index] == $value) && ($type == "yes")} {
  2103.                 set found 1
  2104.                 break
  2105.             }
  2106.         }
  2107.         if {$found} {
  2108.             if {[llength $users] == 1} {
  2109.                 unset ftp_delete($line)
  2110.                 ftp_rmline $line
  2111.             } else {
  2112.                 lvarpop ftp_delete($line) $index
  2113.                 incr index
  2114.                 lvarpop ftp_lines($line) $index
  2115.                 set ftp_modified_ftpaccess 1
  2116.             }
  2117.         }
  2118.     }
  2119.     set index [ftp_addline end "delete no $value"]
  2120.     set ftp_delete($index) "no $value"
  2121. }
  2122. proc add_delete {value} {
  2123.     global ftp_delete ftp_lines ftp_modified_ftpaccess
  2124.     if [catch {array names ftp_delete} linelist] {
  2125.         set index [ftp_addline end "delete yes $value"]
  2126.         set ftp_delete($index) "yes $value"
  2127.     } else {
  2128.         set found 0
  2129.         foreach line [lsort $linelist] {
  2130.             set type  [lindex $ftp_delete($line) 0]
  2131.             set users [lrange $ftp_delete($line) 1 end]
  2132.             set found 0
  2133.             loop index 0 [llength $users] {
  2134.                 if {($type == "no") && ([lindex $users $index] == $value)} {
  2135.                     set found 1
  2136.                     break
  2137.                 }
  2138.             }
  2139.             if {$found} {
  2140.                 if {[llength $users] == 1} {
  2141.                     unset ftp_delete($line)
  2142.                     ftp_rmline $line
  2143.                 } else {
  2144.                     lvarpop ftp_delete($line) $index
  2145.                     incr index
  2146.                     lvarpop ftp_lines($line) $index
  2147.                     set ftp_modified_ftpaccess 1
  2148.                 }
  2149.             }
  2150.         }
  2151.         set index [ftp_addline end "delete yes $value"]
  2152.         set ftp_delete($index) "yes $value"
  2153.     }
  2154. }
  2155. proc list_overwrite {} {
  2156.     global ftp_overwrite
  2157.     if [catch {array names ftp_overwrite} linelist] {
  2158.         return {}
  2159.     }
  2160.     set result "anonymous real guest"
  2161.     foreach line [lsort $linelist] {
  2162.         set type  [lindex $ftp_overwrite($line) 0]
  2163.         set users [lrange $ftp_overwrite($line) 1 end]
  2164.         if {$type == "no"} {
  2165.             set result [lindex [intersect3 $result $users] 0]
  2166.         }
  2167.     }
  2168.     return $result
  2169. }
  2170. proc rm_overwrite {value} {
  2171.     global ftp_overwrite ftp_lines ftp_modified_ftpaccess
  2172.     if [catch {array names ftp_overwrite} linelist] {
  2173.         set index [ftp_addline end "overwrite no $value"]
  2174.         set ftp_overwrite($index) "no $value"
  2175.         return
  2176.     }
  2177.     foreach line $linelist {
  2178.         set type  [lindex $ftp_overwrite($line) 0]
  2179.         set users [lrange $ftp_overwrite($line) 1 end]
  2180.         set found 0
  2181.         loop index 0 [llength $users] {
  2182.             if {([lindex $users $index] == $value) && ($type == "yes")} {
  2183.                 set found 1
  2184.                 break
  2185.             }
  2186.         }
  2187.         if {$found} {
  2188.             if {[llength $users] == 1} {
  2189.                 unset ftp_overwrite($line)
  2190.                 ftp_rmline $line
  2191.             } else {
  2192.                 lvarpop ftp_overwrite($line) $index
  2193.                 incr index
  2194.                 lvarpop ftp_lines($line) $index
  2195.                 set ftp_modified_ftpaccess 1
  2196.             }
  2197.         }
  2198.     }
  2199.     set index [ftp_addline end "overwrite no $value"]
  2200.     set ftp_overwrite($index) "no $value"
  2201. }
  2202. proc add_overwrite {value} {
  2203.     global ftp_overwrite ftp_lines ftp_modified_ftpaccess
  2204.     if [catch {array names ftp_overwrite} linelist] {
  2205.         set index [ftp_addline end "overwrite yes $value"]
  2206.         set ftp_overwrite($index) "yes $value"
  2207.     } else {
  2208.         set found 0
  2209.         foreach line [lsort $linelist] {
  2210.             set type  [lindex $ftp_overwrite($line) 0]
  2211.             set users [lrange $ftp_overwrite($line) 1 end]
  2212.             set found 0
  2213.             loop index 0 [llength $users] {
  2214.                 if {($type == "no") && ([lindex $users $index] == $value)} {
  2215.                     set found 1
  2216.                     break
  2217.                 }
  2218.             }
  2219.             if {$found} {
  2220.                 if {[llength $users] == 1} {
  2221.                     unset ftp_overwrite($line)
  2222.                     ftp_rmline $line
  2223.                 } else {
  2224.                     lvarpop ftp_overwrite($line) $index
  2225.                     incr index
  2226.                     lvarpop ftp_lines($line) $index
  2227.                     set ftp_modified_ftpaccess 1
  2228.                 }
  2229.             }
  2230.         }
  2231.         set index [ftp_addline end "overwrite yes $value"]
  2232.         set ftp_overwrite($index) "yes $value"
  2233.     }
  2234. }
  2235. proc get_passwd_check {} {
  2236.     global ftp_passwd_check
  2237.     if [catch {array names ftp_passwd_check} linelist] {
  2238.         return {}
  2239.     }
  2240.     if {[lempty $linelist]} {
  2241.         return {}
  2242.     }
  2243.     set result $ftp_passwd_check([lindex $linelist 0])
  2244.     return $result
  2245. }
  2246. proc rm_passwd_check {} {
  2247.     global ftp_passwd_check
  2248.     if [catch {array names ftp_passwd_check} linelist] {
  2249.         return {}
  2250.     }
  2251.     foreach line $linelist {
  2252.         unset ftp_passwd_check($line)
  2253.         ftp_rmline $line
  2254.     }
  2255. }
  2256. proc set_passwd_check {value} {
  2257.     global ftp_passwd_check
  2258.     set line "passwd-check    $value"
  2259.     set index [ftp_addline end $line]
  2260.     set ftp_passwd_check($index) $value
  2261. }
  2262. proc find_deny {name} {
  2263.     global ftp_deny_hosts
  2264.     if [catch {array names ftp_deny_hosts} linelist] {
  2265.         return {}
  2266.     }
  2267.     foreach line $linelist {
  2268.         if {[lindex $ftp_deny_hosts($line) 0] == $name} {
  2269.             return $line
  2270.         }
  2271.     }
  2272.     return {}
  2273. }
  2274. proc get_denyfile {name} {
  2275.     global ftp_deny_hosts
  2276.     if {[set line [find_deny $name]] == {} } {
  2277.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$name"
  2278.     }
  2279.     return [lindex $ftp_deny_hosts($line) 1]
  2280. }
  2281. proc find_access {name} {
  2282.     global ftp_access
  2283.     if [catch {array names ftp_access} linelist] {
  2284.         return {}
  2285.     }
  2286.     foreach line $linelist {
  2287.         if {[lindex $ftp_access($line) 0] == $name} {
  2288.             return $line
  2289.         }
  2290.     }
  2291.     return {}
  2292. }
  2293. proc find_limit {name} {
  2294.     global ftp_limit
  2295.     if [catch {array names ftp_limit} linelist] {
  2296.         return {}
  2297.     }
  2298.     foreach line $linelist {
  2299.         if {[lindex $ftp_limit($line) 0] == $name} {
  2300.             return $line
  2301.         }
  2302.     }
  2303.     return {}
  2304. }
  2305. proc find_message {name} {
  2306.     global ftp_message
  2307.     if [catch {array names ftp_message} linelist] {
  2308.         return {}
  2309.     }
  2310.     foreach line $linelist {
  2311.         if {[lindex $ftp_message($line) 0] == "$name"} {
  2312.             return $line
  2313.         }
  2314.     }
  2315.     return {}
  2316. }
  2317. proc ftp_readfile_ftpaccess {} {
  2318.     global ftp_scontext ftp_modified_ftpaccess ftp_newindex_ftpaccess 
  2319.     global ftp_ConfigDir limit_index isOwner
  2320.     set file $ftp_ConfigDir/ftpaccess
  2321.     set limit_index 0
  2322.     if {$isOwner} {
  2323.         if {![catch {open "|/sbin/tfadmin readfile $file" r} infile]} {
  2324.             scanfile $ftp_scontext $infile
  2325.             close $infile
  2326.         }
  2327.     } else {
  2328.         if {![catch {open $file r} infile]} {
  2329.             scanfile $ftp_scontext $infile
  2330.             close $infile
  2331.         }
  2332.     }
  2333.     set ftp_modified_ftpaccess 0
  2334.     set ftp_newindex_ftpaccess 0
  2335. }
  2336. proc ftp_writefile_ftpaccess {} {
  2337.     global ftp_modified_ftpaccess ftp_lines ftp_lineindexes ftp_ConfigDir
  2338.     global isOwner
  2339.     set file $ftp_ConfigDir/ftpaccess
  2340.     if {!$ftp_modified_ftpaccess} {
  2341.         return
  2342.     }
  2343.     backup_file $file
  2344.     if {$isOwner} {
  2345.         if [catch {open "|/sbin/tfadmin writefile $file" w} outfile] {
  2346.             ErrorPush {} 1 SCO_FTPOSA_ERR_CONFIG
  2347.             return
  2348.         }
  2349.     } else {
  2350.         if [catch {open $file w} outfile] {
  2351.             ErrorPush {} 1 SCO_FTPOSA_ERR_CONFIG
  2352.             return
  2353.         }
  2354.     }
  2355.     foreach line $ftp_lineindexes {
  2356.         puts $outfile $ftp_lines($line)
  2357.     }
  2358.     close $outfile
  2359.     set ftp_modified_ftpaccess 0
  2360. }
  2361. proc ftp_readfile_ftpusers {} {
  2362.     global ftp_modified_ftpusers ftp_ConfigDir ftp_deny_users 
  2363.     global isOwner ftp_ftpusers_comments
  2364.     set file $ftp_ConfigDir/ftpusers
  2365.     if {$isOwner} {
  2366.         if {[catch {open "|/sbin/tfadmin readfile $file" r} infile]} {
  2367.             set ftp_modified_ftpusers 0
  2368.             return
  2369.         }
  2370.     } else {
  2371.         if {[catch {open $file r} infile]} {
  2372.             set ftp_modified_ftpusers 0
  2373.             return
  2374.         }
  2375.     }
  2376.     while {! [eof $infile]} {
  2377.         gets $infile user
  2378.         if {[csubstr $user 0 1] == "#"} {
  2379.             lappend ftp_ftpusers_comments $user
  2380.         } elseif {[set user [string trim $user]] == ""} {
  2381.             continue
  2382.         } else {
  2383.             set ftp_deny_users($user) yes
  2384.         }
  2385.     }
  2386.     close $infile
  2387.     set ftp_modified_ftpusers 0
  2388. }
  2389. proc ftp_writefile_ftpusers {} {
  2390.     global ftp_modified_ftpusers ftp_ConfigDir ftp_deny_users
  2391.     global isOwner ftp_ftpusers_comments
  2392.     set file $ftp_ConfigDir/ftpusers
  2393.     if {! $ftp_modified_ftpusers} {
  2394.         return
  2395.     }
  2396.     backup_file $file
  2397.     if {$isOwner} {
  2398.         if {[catch {open "|/sbin/tfadmin writefile $file" w} outfile]} {
  2399.             ErrorPush {} 1 SCO_FTPOSA_ERR_CONFIG
  2400.             return
  2401.         }
  2402.     } else {
  2403.         if {[catch {open $file w} outfile]} {
  2404.             ErrorPush {} 1 SCO_FTPOSA_ERR_CONFIG
  2405.             return
  2406.         }
  2407.     }
  2408.     if {[info exists ftp_ftpusers_comments]} {
  2409.         foreach line $ftp_ftpusers_comments {
  2410.             puts $outfile $line
  2411.         }
  2412.     }
  2413.     if {! [catch {array names ftp_deny_users} users]} {
  2414.         foreach user $users {
  2415.             if {$ftp_deny_users($user) == "yes"} {
  2416.                 puts $outfile $user
  2417.             }
  2418.         }
  2419.     }
  2420.     close $outfile
  2421.     set ftp_modified_ftpusers 0
  2422. }
  2423. proc ftp_init {} {
  2424.     global ftp_ConfigDir ftp_log ftp_OsaDir ftp_Logfile
  2425.     global ftp_Loglen ftp_Logmask inetd_path ageduid_file
  2426.     global ftp_access_index isOwner
  2427.     set isOwner [isOwner]
  2428.     set ftp_access_index 0
  2429.     set ftp_log {}
  2430.     set ftp_Loglen 0
  2431.     set ftp_Logmask ""
  2432.     set ftp_ConfigDir /etc/inet
  2433.     set ftp_OsaDir /usr/lib/scoadmin/netosa
  2434.     set ftp_Logfile /var/adm/xferlog
  2435.     set ftp_Default /var/ftp
  2436.     set inetd_path /usr/sbin/inetd
  2437.     if {![file exists $ftp_Default]} {
  2438.         if {$isOwner} {
  2439.             exec /sbin/tfadmin swUser root /bin/mkdir -p $ftp_Default
  2440.         } else {
  2441.             mkdir -path $ftp_Default
  2442.         }
  2443.     }
  2444.     setup_ftp_scancontexts
  2445.     ftp_readfile_ftpaccess 
  2446.     ftp_readfile_ftpusers
  2447.     ftp_readshutdownfile
  2448. }
  2449. proc ftp_get {class object refObject op subOp data attr attrValueList osaData} {
  2450.     switch -exact $attr {
  2451.         timeout {
  2452.             set result [get_inetd_conf "-t" 1]
  2453.             if {[lindex $result 0] == 1} {
  2454.                 set result [lindex $result 1]
  2455.             } else {
  2456.                 set result "900"
  2457.             }
  2458.         }
  2459.         maxtime {
  2460.             set result [get_inetd_conf "-T" 1]
  2461.             if {[lindex $result 0] == 1} {
  2462.                 set result [lindex $result 1]
  2463.             } else {
  2464.                 set result "7200"
  2465.             }
  2466.         }
  2467.         guestgroup {
  2468.             set result [list_guestgroup]
  2469.         }
  2470.         loginfails {
  2471.             set result [get_loginfails]
  2472.         }
  2473.         private {
  2474.             set result [get_private]
  2475.         }
  2476.         email {
  2477.             set result [get_email]
  2478.         }
  2479.         banner {
  2480.             set result [OSA:get_banner]
  2481.         }
  2482.         log_commands {
  2483.             set result [list_log_commands]
  2484.         }
  2485.         log_incoming {
  2486.             set result [list_log_incoming]
  2487.         }
  2488.         log_outgoing {
  2489.             set result [list_log_outgoing]
  2490.         }
  2491.         shutdown {
  2492.             set result [get_shutdown]
  2493.         }
  2494.         chmod {
  2495.             set result [list_chmod]
  2496.         }
  2497.         delete {
  2498.             set result [list_delete]
  2499.         }
  2500.         overwrite {
  2501.             set result [list_overwrite]
  2502.         }
  2503.         passwd_check {
  2504.             set result [get_passwd_check]
  2505.         }
  2506.         default {
  2507.             ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE [list "$attr" "$class"]
  2508.         }
  2509.     }
  2510.     return [list [list $attr $result]]
  2511. }
  2512. proc ftp_replace {class object refObject op subOp data attr attrValueList osaData} {
  2513.     set value [keylget attrValueList $attr]
  2514.     switch -exact $attr {
  2515.         timeout {
  2516.             if {$value != ""} {
  2517.                 set_inetd_conf "-t" 1 1 $value
  2518.             } else {
  2519.                 set_inetd_conf "-t" 1 0 
  2520.             }
  2521.         }
  2522.         maxtime {
  2523.             if {$value != ""} {
  2524.                 set_inetd_conf "-T" 1 1 $value
  2525.             } else {
  2526.                 set_inetd_conf "-T" 1 0
  2527.             }
  2528.         }
  2529.         guestgroup {
  2530.             foreach group [list_guestgroup] {
  2531.                 rm_guestgroup $group
  2532.             }
  2533.             foreach group $value {
  2534.                 add_guestgroup $group
  2535.             }
  2536.             writeGuestShutdownFile
  2537.         }
  2538.         loginfails {
  2539.             rm_loginfails
  2540.             if {$value != {}} {
  2541.                 set_loginfails $value
  2542.             }
  2543.         }
  2544.         private {
  2545.             rm_private
  2546.             if {$value != {}} {
  2547.                 set_private $value
  2548.             }
  2549.         }
  2550.         email {
  2551.             rm_email
  2552.             if {$value != {}} {set_email $value}
  2553.         }
  2554.         banner {
  2555.             rm_banner
  2556.             if {$value != {}} {set_banner $value}
  2557.         }
  2558.         log_commands {
  2559.             foreach type [list_log_commands] {
  2560.                 rm_log_commands $type
  2561.             }
  2562.             foreach type $value {
  2563.                 add_log_commands $type
  2564.             }
  2565.         }
  2566.         log_incoming {
  2567.             foreach type [list_log_incoming] {
  2568.                 rm_log_incoming $type
  2569.             }
  2570.             foreach type $value {
  2571.                 add_log_incoming $type
  2572.             }
  2573.         }
  2574.         log_outgoing {
  2575.             foreach type [list_log_outgoing] {
  2576.                 rm_log_outgoing $type
  2577.             }
  2578.             foreach type $value {
  2579.                 add_log_outgoing $type
  2580.             }
  2581.         }
  2582.         shutdown {
  2583.             rm_shutdown
  2584.             if {$value != {}} {set_shutdown $value}
  2585.         }
  2586.         chmod {
  2587.             foreach type [list_chmod] {
  2588.                 rm_chmod $type
  2589.             }
  2590.             foreach type $value {
  2591.                 add_chmod $type
  2592.             }
  2593.         }
  2594.         delete {
  2595.             foreach type [list_delete] {
  2596.                 rm_delete $type
  2597.             }
  2598.             foreach type $value {
  2599.                 add_delete $type
  2600.             }
  2601.         }
  2602.         overwrite {
  2603.             foreach type [list_overwrite] {
  2604.                 rm_overwrite $type
  2605.             }
  2606.             foreach type $value {
  2607.                 add_overwrite $type
  2608.             }
  2609.         }
  2610.         passwd_check {
  2611.             rm_passwd_check
  2612.             set_passwd_check $value
  2613.         }
  2614.         default {
  2615.             ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE [list "$attr" "$class"]
  2616.         }
  2617.     }
  2618.     ftp_writefile_ftpaccess
  2619.     set attrs [keylkeys attrValueList]
  2620.     if {([lsearch $attrs timeout] != -1 || [lsearch $attrs maxtime] != -1) && [cequal $attr [lindex $attrs end]]} {
  2621.         poke_inetd_conf
  2622.     }
  2623. }
  2624. proc ftp:File_Action_ListFiles {dir} {
  2625.     set fileList {}
  2626.     if {[catch {glob $dir} dirContents]} {
  2627.         return ""
  2628.     }
  2629.     foreach entry $dirContents {
  2630.         if {![file isdirectory $entry]} {
  2631.             lappend fileList $entry
  2632.         }
  2633.     }
  2634.     return $fileList
  2635. }
  2636. proc ftp:File_Action_ListDirs {dir} {
  2637.     set dirList {}
  2638.     if {[catch {glob $dir} dirContents]} {
  2639.         return ""
  2640.     }
  2641.     foreach entry $dirContents {
  2642.         if {[file isdirectory $entry]} {
  2643.             lappend dirList $entry
  2644.         }
  2645.     }
  2646.     return $dirList
  2647. }
  2648. proc ftp_action {class object refObject op subOp data attr attrValueList osaData} {
  2649.     switch $subOp {
  2650.         listFiles    { return [ftp:File_Action_ListFiles $object] }
  2651.         listDirs    { return [ftp:File_Action_ListDirs $object] }
  2652.         default     { ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ACTION $subOp }
  2653.     }
  2654.     return
  2655. }
  2656. proc ftpClass_list {class object refObject op subOp data attr attrValueList osaData} {
  2657.     global ftp_classes
  2658.     if [catch {array names ftp_classes} classes] {
  2659.         return {}
  2660.     } else {
  2661.         return $classes
  2662.     }
  2663. }
  2664. proc ftpClass_get {class object refObject op subOp data attr attrValueList osaData} {
  2665.     global ftp_classes
  2666.     if {! [info exists ftp_classes($object)]} {
  2667.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  2668.     }
  2669.     set objrec $ftp_classes($object)
  2670.     switch -exact $attr {
  2671.         typeList  { set result [keylget objrec typelist] }
  2672.         addrList  { set result [keylget objrec addrs] }
  2673.         autogroup { set result [keylget objrec groups] }
  2674.         default   { ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE [list "$attr"]}
  2675.     }
  2676.     return [list [list $attr $result]]
  2677. }
  2678. proc ftpClass_replace {class object refObject op subOp data attr attrValueList osaData} {
  2679.     global ftp_classes ftp_lines ftp_modified_ftpaccess
  2680.     if {! [info exists ftp_classes($object)]} {
  2681.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  2682.     }
  2683.     set objrec $ftp_classes($object)
  2684.     keylget attrValueList typeList  typelist
  2685.     keylget attrValueList addrList  addrlist
  2686.     keylget attrValueList autogroup groups
  2687.     keylset objrec typelist $typelist
  2688.     keylset objrec addrs    $addrlist
  2689.     keylset objrec groups   $groups
  2690.     keylget objrec lines lines
  2691.     foreach line $lines {
  2692.         ftp_rmline $line
  2693.     }
  2694.     set line "class $object [join $typelist ,] $addrlist"
  2695.     set index [ftp_addline end $line]
  2696.     lappend newlines $index
  2697.     foreach group $groups {
  2698.         set line "autogroup $group $object"
  2699.         set index [ftp_addline end $line]
  2700.         lappend newlines $index
  2701.     }
  2702.     keylset objrec lines $newlines
  2703.     set ftp_classes($object) $objrec
  2704.     set ftp_modified_ftpaccess 1
  2705.     ftp_writefile_ftpaccess
  2706. }
  2707. proc ftpClass_create {class object refObject op subOp data attr attrValueList osaData} {
  2708.     global ftp_classes 
  2709.     if [info exists ftp_classes($object)] {
  2710.             ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE "$object"
  2711.     }
  2712.     keylget attrValueList typeList  typelist
  2713.     keylget attrValueList addrList  addrlist
  2714.     keylget attrValueList autogroup groups
  2715.     keylset objrec typelist $typelist
  2716.     keylset objrec addrs    $addrlist
  2717.     keylset objrec groups   $groups
  2718.     set line "class $object [join $typelist ,] $addrlist"
  2719.     set index [ftp_addline end $line]
  2720.     lappend newlines $index
  2721.     foreach group $groups {
  2722.         set line "autogroup $group $object"
  2723.         set index [ftp_addline end $line]
  2724.         lappend newlines $index
  2725.     }
  2726.     keylset objrec lines $newlines
  2727.     set ftp_classes($object) $objrec
  2728.     ftp_writefile_ftpaccess
  2729.     return 1
  2730. }
  2731. proc ftpClass_delete {class object refObject op subOp data attr attrValueList osaData} {
  2732.     global ftp_classes
  2733.     if {! [info exists ftp_classes($object)]} {
  2734.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  2735.     }
  2736.     set objrec $ftp_classes($object)
  2737.     keylget objrec lines lines
  2738.     foreach line $lines {
  2739.         ftp_rmline $line
  2740.     }
  2741.     unset ftp_classes($object)
  2742.     ftp_writefile_ftpaccess
  2743.     return 1
  2744. }
  2745. proc ftpLimit_list {class object refObject op subOp data attr attrValueList osaData} {
  2746.     global ftp_limit
  2747.     if [catch {array names ftp_limit} linelist] {
  2748.         return {}
  2749.     }
  2750.     set result {}
  2751.     foreach line [lsort $linelist] {
  2752.         lappend result [lindex $ftp_limit($line) 0]
  2753.     }
  2754.     return $result
  2755. }
  2756. proc ftpLimit_get {class object refObject op subOp data attr attrValueList osaData} {
  2757.     global ftp_limit
  2758.     if {[set line [find_limit $object]] == {} } {
  2759.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  2760.     }
  2761.     set objdef $ftp_limit($line)
  2762.     switch -exact $attr {
  2763.         limitID   { set result $object }
  2764.         class   { set result [lindex $objdef 1] }
  2765.         users   { set result [lindex $objdef 2] }
  2766.         times   { set result [lindex $objdef 3] }
  2767.         file    { set result [lindex $objdef 4] }
  2768.         default { ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE [list "$attr" "$limitID"]}
  2769.     }
  2770.     return [list [list $attr $result]]
  2771. }
  2772. proc ftpLimit_replace {class object refObject op subOp data attr attrValueList osaData} {
  2773.     global ftp_limit ftp_lines ftp_modified_ftpaccess
  2774.     if {[set line [find_limit $object]] == {} } {
  2775.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  2776.     }
  2777.     keylget attrValueList limitID limitID
  2778.     keylget attrValueList class class
  2779.     keylget attrValueList users users
  2780.     keylget attrValueList times times
  2781.     keylget attrValueList file  file
  2782.     set ftp_limit($line) [lreplace $ftp_limit($line) 0 0 $limitID]
  2783.     set ftp_limit($line) [lreplace $ftp_limit($line) 1 1 $class]
  2784.     set ftp_limit($line) [lreplace $ftp_limit($line) 2 2 $users]
  2785.     set ftp_limit($line) [lreplace $ftp_limit($line) 3 3 $times]
  2786.     if {[llength $ftp_limit($line)] > 4} {
  2787.         set ftp_limit($line) [lreplace $ftp_limit($line) 4 4 $file]
  2788.     } else {
  2789.         set ftp_limit($line) [linsert $ftp_limit($line) 4 $file]
  2790.     }
  2791.     set ftp_lines($line) "limit $class $users $times $file"
  2792.     set ftp_modified_ftpaccess 1
  2793.     ftp_writefile_ftpaccess
  2794. }
  2795. proc ftpLimit_delete {class object refObject op subOp data attr attrValueList osaData} {
  2796.     global ftp_limit
  2797.     if {[set line [find_limit $object]] == {} } {
  2798.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  2799.     }
  2800.     unset ftp_limit($line)
  2801.     ftp_rmline $line
  2802.     ftp_writefile_ftpaccess
  2803.     return 1
  2804. }
  2805. proc ftpLimit_create {class object refObject op subOp data attr attrValueList osaData} {
  2806.     global ftp_limit
  2807.     if {[find_limit $object] != {}} {
  2808.         ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE "$object"
  2809.     }
  2810.     if [catch {set class [keylget attrValueList class]}] {
  2811.         error "need class attribute"
  2812.     }
  2813.     if [catch {set users [keylget attrValueList users]}] {
  2814.         error "need users attribute"
  2815.     }
  2816.     if [catch {set times [keylget attrValueList times]}] {
  2817.         error "need times attribute"
  2818.     }
  2819.     if [catch {set file [keylget attrValueList file]}] {
  2820.         error "need file attribute"
  2821.     }
  2822.     set line "limit $class $users $times $file"
  2823.     set index [ftp_addline end $line]
  2824.     set ftp_limit($index) "$object [lrange $line 1 end]"
  2825.     ftp_writefile_ftpaccess
  2826.     return 1
  2827. }
  2828. proc ftpAccess_list {class object refObject op subOp data attr attrValueList osaData} {
  2829.     global ftp_access
  2830.     if [catch {array names ftp_access} linelist] {
  2831.         return {}
  2832.     }
  2833.     set result {}
  2834.     foreach line [lsort $linelist] {
  2835.         lappend result [lindex $ftp_access($line) 0]
  2836.     }
  2837.     return $result
  2838. }
  2839. proc ftpAccess_get {class object refObject op subOp data attr attrValueList osaData} {
  2840.     global ftp_access
  2841.     if {[set line [find_access $object]] == {} } {
  2842.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  2843.     }
  2844.     set objdef $ftp_access($line)
  2845.     switch -exact $attr {
  2846.         home    { set result [lindex $objdef 1] }
  2847.         dir     { set result [lindex $objdef 2] }
  2848.         upload  { set result [lindex $objdef 3] }
  2849.         owner   { set result [lindex $objdef 4] }
  2850.         group   { set result [lindex $objdef 5] }
  2851.         mode    { set result [lindex $objdef 6] }
  2852.         subdirs { set result [lindex $objdef 7] }
  2853.         default { ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE [list "$attr" "$class"]}
  2854.     }
  2855.     return [list [list $attr $result]]
  2856. }
  2857. proc ftpAccess_replace {class object refObject op subOp data attr attrValueList osaData} {
  2858.     global ftp_access ftp_lines ftp_modified_ftpaccess
  2859.     if {[set line [find_access $object]] == {} } {
  2860.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  2861.     }
  2862.     keylget attrValueList dir     dir
  2863.     keylget attrValueList home    home
  2864.     keylget attrValueList upload  upload
  2865.     keylget attrValueList owner   owner
  2866.     keylget attrValueList group   group
  2867.     keylget attrValueList mode    mode
  2868.     keylget attrValueList subdirs subdirs
  2869.     set ftp_access($line) [lreplace $ftp_access($line) 1 1 $home]
  2870.     set ftp_access($line) [lreplace $ftp_access($line) 2 2 $dir]
  2871.     set ftp_access($line) [lreplace $ftp_access($line) 3 3 $upload]
  2872.     set ftp_access($line) [lreplace $ftp_access($line) 4 4 $owner]
  2873.     set ftp_access($line) [lreplace $ftp_access($line) 5 5 $group]
  2874.     set ftp_access($line) [lreplace $ftp_access($line) 6 6 $mode]
  2875.     set ftp_access($line) [lreplace $ftp_access($line) 7 7 $subdirs]
  2876.     set ftp_lines($line) "upload $home $dir $upload $owner $group $mode $subdirs"
  2877.     set ftp_modified_ftpaccess 1
  2878.     ftp_writefile_ftpaccess
  2879. }
  2880. proc ftpAccess_create {class object refObject op subOp data attr attrValueList osaData} {
  2881.     global ftp_access ftp_access_index
  2882.     if {[find_access $object] != {}} {
  2883.         ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE "$object"
  2884.     }
  2885.     if [catch {set upload [keylget attrValueList upload]}] {
  2886.         error "need upload attribute"
  2887.     }
  2888.     keylget attrValueList home home
  2889.     keylget attrValueList dir dir
  2890.     set owner {}
  2891.     set group {}
  2892.     set mode {}
  2893.     set subdirs {}
  2894.     if {$upload == "yes"} {
  2895.         if [catch {set owner [keylget attrValueList owner]}] {
  2896.             error "need owner attribute"
  2897.         }
  2898.         if [catch {set group [keylget attrValueList group]}] {
  2899.             error "need group attribute"
  2900.         }
  2901.         if [catch {set mode [keylget attrValueList mode]}] {
  2902.             error "need mode attribute"
  2903.         }
  2904.     } 
  2905.     keylget attrValueList subdirs subdirs
  2906.     set line "upload $home $dir $upload $owner $group $mode $subdirs"
  2907.     set index [ftp_addline end $line]
  2908.     set object $ftp_access_index
  2909.     incr ftp_access_index
  2910.     set ftp_access($index) [list $object $home $dir $upload $owner $group $mode $subdirs]
  2911.     ftp_writefile_ftpaccess
  2912.     return $object
  2913. }
  2914. proc ftpAccess_delete {class object refObject op subOp data attr attrValueList osaData} {
  2915.     global ftp_access
  2916.     if {[set line [find_access $object]] == {} } {
  2917.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  2918.     }
  2919.     unset ftp_access($line)
  2920.     ftp_rmline $line
  2921.     ftp_writefile_ftpaccess
  2922.     return 1
  2923. }
  2924. proc ftpMessage_list {class object refObject op subOp data attr attrValueList osaData} {
  2925.     global ftp_message
  2926.     if [catch {array names ftp_message} linelist] {
  2927.         return {}
  2928.     }
  2929.     set result {}
  2930.     foreach line [lsort $linelist] {
  2931.         lappend result [lindex $ftp_message($line) 0]
  2932.     }
  2933.     return $result
  2934. }
  2935. proc ftpMessage_get {class object refObject op subOp data attr attrValueList osaData} {
  2936.     global ftp_message
  2937.     if {[set line [find_message $object]] == {} } {
  2938.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  2939.     }
  2940.     set objdef $ftp_message($line)
  2941.     switch -exact $attr {
  2942.         type { 
  2943.                 if [string match "README_*" $object] {
  2944.                     set result "README"
  2945.                 } else {
  2946.                     set result "MESSAGE"
  2947.                 }
  2948.             }
  2949.         when { set result [lindex $objdef 1] }
  2950.         file { set result [lindex $objdef 2] }
  2951.         class { 
  2952.                 set result [lindex $objdef 3]
  2953.             }
  2954.         default { ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE [list "$attr" "$class"]}
  2955.     }
  2956.     return [list [list $attr $result]]
  2957. }
  2958. proc ftpMessage_replace {class object refObject op subOp data attr attrValueList osaData} {
  2959.     global ftp_message ftp_lines ftp_modified_ftpaccess
  2960.     if {[set line [find_message $object]] == {} } {
  2961.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  2962.     }
  2963.     keylget attrValueList type  type
  2964.     keylget attrValueList when  when
  2965.     keylget attrValueList file  file
  2966.     keylget attrValueList class  class
  2967.     set ftp_message($line) [lreplace $ftp_message($line) 1 1 $when]
  2968.     set ftp_message($line) [lreplace $ftp_message($line) 2 2 $file]
  2969.     set ftp_message($line) [lreplace $ftp_message($line) 3 3 $class]
  2970.     if {[string tolower $when] != "login"} {
  2971.         set newline "[string tolower $type] $file cwd=$when $class"
  2972.     } else {
  2973.         set newline "[string tolower $type] $file $when $class"
  2974.     }
  2975.     set ftp_lines($line) $newline
  2976.     set ftp_modified_ftpaccess 1
  2977.     ftp_writefile_ftpaccess
  2978. }
  2979. proc ftpMessage_create {class object refObject op subOp data attr attrValueList osaData} {
  2980.     global ftp_message
  2981.     if [catch {set type [keylget attrValueList type]}] {
  2982.         error "need type attribute"
  2983.     }
  2984.     set when  "LOGIN"
  2985.     keylget attrValueList when when
  2986.     set object "${type}_$when"
  2987.     if {[find_message $object] != {}} {
  2988.         ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE "$object"
  2989.     }
  2990.     if [catch {set file [keylget attrValueList file]}] {
  2991.         error "need file attribute"
  2992.     }
  2993.     set class ""
  2994.     keylget attrValueList class class
  2995.     if {[string tolower $when] != "login"} {
  2996.         set line "[string tolower $type] $file cwd=$when $class"
  2997.     } else {
  2998.         set line "[string tolower $type] $file $when $class"
  2999.     }
  3000.     set index [ftp_addline end $line]
  3001.     set ftp_message($index) [list $object $when $file $class]
  3002.     ftp_writefile_ftpaccess
  3003.     return 1
  3004. }
  3005. proc ftpMessage_delete {class object refObject op subOp data attr attrValueList osaData} {
  3006.     global ftp_message
  3007.     if {[set line [find_message $object]] == {} } {
  3008.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  3009.     }
  3010.     unset ftp_message($line)
  3011.     ftp_rmline $line
  3012.     ftp_writefile_ftpaccess
  3013.     return 1
  3014. }
  3015. ######################################################################
  3016. proc ftpDenyHost_list {class object refObject op subOp data attr attrValueList osaData} {
  3017.     global ftp_deny_hosts
  3018.     if [catch {array names ftp_deny_hosts} linelist] {
  3019.         return {}
  3020.     }
  3021.     set result {}
  3022.     foreach line [lsort $linelist] {
  3023.         lappend result [lindex $ftp_deny_hosts($line) 0]
  3024.     }
  3025.     return $result
  3026. }
  3027. proc ftpDenyHost_get {class object refObject op subOp data attr attrValueList osaData} {
  3028.     switch -exact $attr {
  3029.         host { set result $object }
  3030.         file { set result [get_denyfile $object] }
  3031.         default { ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE [list "$attr" "$class"]}
  3032.     }
  3033.     return [list [list $attr $result]]
  3034. }
  3035. proc ftpDenyHost_replace {class object refObject op subOp data attr attrValueList osaData} {
  3036.     global ftp_deny_hosts ftp_lines ftp_modified_ftpaccess
  3037.     if {[set line [find_deny $object]] == {} } {
  3038.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  3039.     }
  3040.     keylget attrValueList host  host
  3041.     keylget attrValueList file  file
  3042.     set ftp_deny_hosts($line) [lreplace $ftp_deny_hosts($line) 0 0 $host]
  3043.     if {[llength $ftp_deny_hosts($line)] > 1} {
  3044.         set ftp_deny_hosts($line) [lreplace $ftp_deny_hosts($line) 1 1 $file]
  3045.     } else {
  3046.         set ftp_deny_hosts($line) [linsert $ftp_deny_hosts($line) 1 $file]
  3047.     }
  3048.     set ftp_lines($line) "deny $host $file"
  3049.     set ftp_modified_ftpaccess 1
  3050.     ftp_writefile_ftpaccess
  3051. }
  3052. proc ftpDenyHost_create {class object refObject op subOp data attr attrValueList osaData} {
  3053.     global ftp_deny_hosts ftp_modified_ftpaccess
  3054.     if {[find_deny $object] != {}} {
  3055.         ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE "$object"
  3056.     }
  3057.     if [catch {set file [keylget attrValueList file]}] {
  3058.         error "need file attribute"
  3059.     }
  3060.     set line "deny $object $file"
  3061.     set index [ftp_addline end $line]
  3062.     set ftp_deny_hosts($index) [lrange $line 1 end]
  3063.     set ftp_modified_ftpaccess 1
  3064.     ftp_writefile_ftpaccess
  3065.     return 1
  3066. }
  3067. proc ftpDenyHost_delete {class object refObject op subOp data attr attrValueList osaData} {
  3068.     global ftp_deny_hosts ftp_modified_ftpaccess
  3069.     if {[set line [find_deny $object]] == {} } {
  3070.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  3071.     }
  3072.     unset ftp_deny_hosts($line)
  3073.     ftp_rmline $line
  3074.     set ftp_modified_ftpaccess 1
  3075.     ftp_writefile_ftpaccess
  3076.     return 1
  3077. }
  3078. ######################################################################
  3079. proc ftpDenyUser_list {class object refObject op subOp data attr attrValueList osaData} {
  3080.     global ftp_deny_users
  3081.     if {[catch {array names ftp_deny_users} users]} {
  3082.         return {}
  3083.     }
  3084.     return $users
  3085. }
  3086. proc ftpDenyUser_get {class object refObject op subOp data attr attrValueList osaData} {
  3087.     global ftp_deny_users
  3088.     if [catch {set denied $ftp_deny_users($object)}] {
  3089.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  3090.     }
  3091.     switch -exact $attr {
  3092.         user   { set result $object }
  3093.         denied { set result $ftp_deny_users($object) }
  3094.         default   { ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE [list "$attr" "$class"]}
  3095.     }
  3096.     return [list [list $attr $result]]
  3097. }
  3098. proc ftpDenyUser_replace {class object refObject op subOp data attr attrValueList osaData} {
  3099.     global ftp_deny_host ftp_modified_ftpusers
  3100.     if [catch {set denied $ftp_deny_users($object)}] {
  3101.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  3102.     }
  3103.     if [catch {keylget attrValueList denied denied}] {
  3104.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE [list "$object" "$class"]
  3105.     }
  3106.     if {$denied != "yes" && $denied != "no"} {
  3107.         ErrorPush {} 1 SCO_OSA_ERR_PROCESSING_FAILURE_ON_ATTRIBUTE "$object"
  3108.     }
  3109.     set ftp_deny_host($object) $denied
  3110.     set ftp_modified_ftpusers 1
  3111.     ftp_writefile_ftpusers
  3112.     return {}
  3113. }
  3114. proc ftpDenyUser_create {class object refObject op subOp data attr attrValueList osaData} {
  3115.     global ftp_deny_users ftp_modified_ftpusers
  3116.     if [catch {array names ftp_deny_users} users] {
  3117.         set users {}
  3118.     }
  3119.     if {[lsearch $users $object] != -1} {
  3120.         ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE "$object"
  3121.     }
  3122.     if [catch {set denied [keylget attrValueList denied]}] {
  3123.         set denied yes
  3124.     }
  3125.     if {$denied != "yes" && $denied != "no"} {
  3126.         ErrorPush {} 1 SCO_OSA_ERR_PROCESSING_FAILURE_ON_ATTRIBUTE "$object"
  3127.     }
  3128.     set ftp_deny_users($object) $denied
  3129.     set ftp_modified_ftpusers 1
  3130.     ftp_writefile_ftpusers
  3131.     return 1
  3132. }
  3133. proc ftpDenyUser_delete {class object refObject op subOp data attr attrValueList osaData} {
  3134.     global ftp_deny_users ftp_modified_ftpusers
  3135.     if [catch {array names ftp_deny_users} users] {
  3136.         set users {}
  3137.     }
  3138.     if {[lsearch $users $object] == -1} {
  3139.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  3140.     }
  3141.     unset ftp_deny_users($object)
  3142.     set ftp_modified_ftpusers 1
  3143.     ftp_writefile_ftpusers
  3144.     return 1
  3145. }
  3146. ######################################################################
  3147. proc virtual_do_mkdir {what where} {
  3148.     global isOwner 
  3149.     switch -exact $what {
  3150.         root {
  3151.             set dir $where
  3152.             set bas ""
  3153.         }
  3154.         banner -
  3155.         logfile {
  3156.             set dir [file dirname $where]
  3157.             set bas [file tail $where]
  3158.         }
  3159.         default {
  3160.             set dir ""
  3161.             set bas ""
  3162.         }
  3163.     }
  3164.     if {$dir != "" && ![file exists $dir]} {    
  3165.         if {$isOwner} {
  3166.             exec /sbin/tfadmin swUser root /bin/mkdir -p $dir
  3167.         } else {
  3168.             mkdir -path $dir
  3169.         }
  3170.     }
  3171. }
  3172. proc ftpVirtual_list {class object refObject op subOp data attr attrValueList osaData} {
  3173.     global ftp_virtual
  3174.     if [catch {array names ftp_virtual} addresses] {
  3175.         return {}
  3176.     } else {
  3177.         return $addresses
  3178.     }
  3179. }
  3180. proc ftpVirtual_get {class object refObject op subOp data attr attrValueList osaData} {
  3181.     global ftp_virtual ftp_virtual_lines
  3182.     if {[catch {set record $ftp_virtual($object)}]} {
  3183.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  3184.     }
  3185.     switch -exact $attr {
  3186.         address { set result $object }
  3187.         logfile { set result [keylget record logfile] }
  3188.         banner  { set result [keylget record banner] }
  3189.         root    { set result [keylget record root] }
  3190.         default { ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE [list "$attr" "$class"] }
  3191.     }
  3192.     return [list [list $attr $result]]
  3193. }
  3194. proc ftpVirtual_replace {class object refObject op subOp data attr attrValueList osaData} {
  3195.     global ftp_virtual ftp_virtual_lines ftp_modified_ftpaccess ftp_lines
  3196.     if {[catch {set record $ftp_virtual($object)}]} {
  3197.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  3198.     }
  3199.     set record_lines $ftp_virtual_lines($object)
  3200.     set last_line end
  3201.     foreach rec_attr [keylkeys record_lines] {
  3202.         keylget record_lines $rec_attr line
  3203.         if {$line != ""} {
  3204.             set last_line $line
  3205.         }
  3206.     }
  3207.     if {[lsearch [keylkeys attrValueList] root] == -1} {
  3208.         set rootChanged 0
  3209.     } else {
  3210.         set rootChanged 1
  3211.     }
  3212.     foreach bmip_attr [keylkeys attrValueList] {
  3213.         if {[catch {keylget record $bmip_attr rec_attrValue}]} {    
  3214.             ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE [list "$bmip_attr $class"]
  3215.         }
  3216.         keylget record_lines $bmip_attr rec_attrLine
  3217.         keylget attrValueList $bmip_attr bmip_attrValue
  3218.         if {$bmip_attrValue == ""} {
  3219.             if {$rec_attrValue == ""} {
  3220.             } else {
  3221.                 ftp_rmline $rec_attrLine
  3222.                 keylset record $bmip_attr ""
  3223.                 keylset record_lines $bmip_attr ""
  3224.             }
  3225.         } else {
  3226.             if {$rec_attrValue == ""} {
  3227.                 set line [ftp_addline $last_line "virtual $object $bmip_attr $bmip_attrValue"]
  3228.                 keylset record $bmip_attr $bmip_attrValue
  3229.                 keylset record_lines $bmip_attr $line
  3230.                 virtual_do_mkdir $bmip_attr $bmip_attrValue
  3231.             } else {
  3232.                 set ftp_lines($rec_attrLine) "virtual $object $bmip_attr $bmip_attrValue"
  3233.                 keylset record $bmip_attr $bmip_attrValue
  3234.                 virtual_do_mkdir $bmip_attr $bmip_attrValue
  3235.             }
  3236.         }
  3237.     }
  3238.     set ftp_virtual($object) $record
  3239.     set ftp_virtual_lines($object) $record_lines
  3240.     if {$rootChanged} {
  3241.         writeVirtualShutdownFile $object
  3242.     }
  3243.     set ftp_modified_ftpaccess 1
  3244.     ftp_writefile_ftpaccess
  3245.     return {}
  3246. }
  3247. proc ftpVirtual_create {class object refObject op subOp data attr attrValueList osaData} {
  3248.     global ftp_virtual ftp_modified_ftpaccess ftp_lines ftp_virtual_lines
  3249.     if [catch {array names ftp_virtual} addresses] {
  3250.         set addresses {}
  3251.     }
  3252.     if {[lsearch $addresses $object] != -1} {
  3253.         ErrorPush {} 1 SCO_OSA_ERR_DUPLICATE_MANAGED_OBJECT_INSTANCE "$object"
  3254.     }
  3255.     set record {{banner ""} {logfile ""} {root ""}}
  3256.     set record_lines {{banner ""} {logfile ""} {root ""}}
  3257.     foreach bmip_attr [keylkeys attrValueList] {
  3258.         if [catch {set bmip_attrValue [keylget attrValueList $bmip_attr]}] {
  3259.             ErrorPush {} 1 SCO_OSA_ERR_PROCESSING_FAILURE_ON_ATTRIBUTE "$object"
  3260.         }
  3261.         if {[lsearch [keylkeys record] $bmip_attr] == -1} {
  3262.             ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE [list "$bmip_attr $class"]
  3263.         }
  3264.         if {$bmip_attrValue == ""} {
  3265.             continue
  3266.         }
  3267.         keylset record $bmip_attr $bmip_attrValue
  3268.         set line [ftp_addline end "virtual $object $bmip_attr $bmip_attrValue"]
  3269.         keylset record_lines $bmip_attr $line
  3270.         virtual_do_mkdir $bmip_attr $bmip_attrValue
  3271.     }
  3272.     set ftp_virtual($object) $record
  3273.     set ftp_virtual_lines($object) $record_lines
  3274.     writeVirtualShutdownFile $object
  3275.     set ftp_modified_ftpaccess 1
  3276.     ftp_writefile_ftpaccess
  3277.     return 1
  3278. }
  3279. proc ftpVirtual_delete {class object refObject op subOp data attr attrValueList osaData} {
  3280.     global ftp_virtual ftp_modified_ftpaccess ftp_lines ftp_virtual_lines
  3281.     if [catch {array names ftp_virtual} addresses] {
  3282.         set addresses {}
  3283.     }
  3284.     if {[lsearch $addresses $object] == -1} {
  3285.         ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE "$object"
  3286.     }
  3287.     set record_lines $ftp_virtual_lines($object)
  3288.     foreach rec_attr [keylkeys record_lines] {
  3289.         set rec_attrValue [keylget record_lines $rec_attr]
  3290.         if {$rec_attrValue != ""} {
  3291.             ftp_rmline $rec_attrValue
  3292.         }
  3293.     }
  3294.     unset ftp_virtual($object)
  3295.     unset ftp_virtual_lines($object)
  3296.     set ftp_modified_ftpaccess 1
  3297.     ftp_writefile_ftpaccess
  3298.     return 1
  3299. }
  3300. proc writeVirtualShutdownFile {{objects ""}} {
  3301.     global ftp_virtual isOwner
  3302.     set filename [get_shutdown]
  3303.     if {[cequal $filename ""]} {    
  3304.         return
  3305.     }
  3306.     if {![info exist ftp_virtual]} {    
  3307.         return
  3308.     }
  3309.     if {[cequal $objects ""]} {
  3310.         set objects [array names ftp_virtual]
  3311.     }
  3312.     foreach object $objects {
  3313.         keylget ftp_virtual($object) root root
  3314.         set dir [file dirname $root/$filename]
  3315.         if {$isOwner} {
  3316.             catch {exec /sbin/tfadmin swUser root /bin/mkdir -p $dir}
  3317.             exec /sbin/tfadmin cpfile $filename $root/$filename
  3318.         } else {
  3319.             catch {mkdir -path $dir}
  3320.             exec /bin/cp $filename $root/$filename
  3321.         }
  3322.     }
  3323. }
  3324. proc writeGuestShutdownFile {{objects ""}} {
  3325.     global ftp_guestgroup isOwner
  3326.     set filename [get_shutdown]
  3327.     if {[cequal $filename ""]} {    
  3328.         return
  3329.     }
  3330.     if {[cequal $objects ""]} {
  3331.         set objects [list_guestgroup]
  3332.     }
  3333.     set pw_info [SaGetPwEnts]
  3334.     foreach user [keylkeys pw_info] {
  3335.         keylget pw_info $user.pw_gid group
  3336.         keylget pw_info $user.pw_dir root
  3337.         if {[lsearch $objects $group] == -1} {
  3338.             continue
  3339.         }
  3340.         set dir [file dirname $root/$filename]
  3341.         if {$isOwner} {
  3342.             catch {exec /sbin/tfadmin swUser root /bin/mkdir -p $dir}
  3343.             exec /sbin/tfadmin cpfile $filename $root/$filename
  3344.         } else {
  3345.             catch {mkdir -path $dir}
  3346.             exec /bin/cp $filename $root/$filename
  3347.         }
  3348.     }
  3349. }
  3350. proc writeAnonShutdownFile {} {
  3351.     global ftp_virtual isOwner
  3352.     set filename [get_shutdown]
  3353.     if {[cequal $filename ""]} {    
  3354.         return
  3355.     }
  3356.     set pw_info [SaGetPwEnts]
  3357.     set ftp_info ""
  3358.     keylget pw_info ftp ftp_info
  3359.     set root ""
  3360.     keylget ftp_info pw_dir root
  3361.     if {[cequal $root ""]} {
  3362.         return
  3363.     }
  3364.     set dir [file dirname $root/$filename]
  3365.     if {$isOwner} {
  3366.         catch {exec /sbin/tfadmin swUser root /bin/mkdir -p $dir}
  3367.         exec /sbin/tfadmin cpfile $filename $root/$filename
  3368.     } else {
  3369.         catch {mkdir -path $dir}
  3370.         exec /bin/cp $filename $root/$filename
  3371.     }
  3372. }
  3373. ######################################################################
  3374. proc ftpLog_get {class object refObject op subOp data attr attrValueList osaData} {
  3375.     global ftp_log
  3376.     logRead 
  3377.     if {$attrValueList == {}} {
  3378.         set attrValueList { domain current_time transfer_time remote_host \
  3379.             file_size filename transfer_type action \
  3380.             direction access_mode username \
  3381.             service_name auth_method user_id }
  3382.     }
  3383.     set results {}
  3384.     foreach entry $ftp_log {
  3385.         set rec {}
  3386.         foreach attr $attrValueList {
  3387.             keylset rec $attr [keylget entry $attr]
  3388.         }
  3389.         lappend results $rec
  3390.     }
  3391.     return $results
  3392. }
  3393. proc ftpLog_action {class object refObject op subOp data attr attrValueList osaData} {
  3394.     global ftp_Loglen ftp_Logmask
  3395.     switch $subOp {
  3396.         length {
  3397.             set num [lindex $data 0]
  3398.             if {[ctype digit $num] && ($num >= 0)} {
  3399.                 set ftp_Loglen $num
  3400.             }
  3401.         }
  3402.         mask {
  3403.             set ftp_Logmask $data
  3404.         }
  3405.         default     { ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ACTION $subOp }
  3406.     }
  3407.     return
  3408. }
  3409. ############################################################
  3410. proc OSA:get_ftp_info {field} {
  3411.     global Main 
  3412.     if {[catch {SaGetPwEnts} pw_ents]} {
  3413.         return 
  3414.     }
  3415.     if {[catch {keylget pw_ents ftp} ftp_ent]} {
  3416.         return 
  3417.     }
  3418.     return [keylget ftp_ent $field]
  3419. }
  3420. proc OSA:set_ftp_info {what {home ""} {uid ""}} {
  3421.     global errorCode isOwner
  3422.     set opti "-i"
  3423.     set optU "-U"
  3424.     set optn "-n 0"
  3425.     if {$home != ""} {
  3426.         set home "-d $home"
  3427.     }
  3428.     switch -exact $what {
  3429.         create {
  3430.             if {$uid != ""} {
  3431.                 set uid "-u $uid $opti"
  3432.             }
  3433.             if {$isOwner} {
  3434.                 catch {exec /sbin/tfadmin swUser root /bin/mkdir -p $home}
  3435.                 set com "/sbin/tfadmin useradd -g 1 -s /bin/true -c \"Anonymous FTP\" $home $uid ftp"
  3436.             } else {
  3437.                 catch {exec /bin/mkdir -p $home}
  3438.                 set com "/usr/sbin/useradd -g 1 -s /bin/true -c \"Anonymous FTP\" $home $uid ftp"
  3439.             }
  3440.             set err SCO_FTPOSA_ERR_ANON_CREATE
  3441.         }
  3442.         modify {
  3443.             if {$uid != ""} {
  3444.                 set uid "-u $uid $optU"
  3445.             }
  3446.             if {$isOwner} {
  3447.                 catch {exec /sbin/tfadmin swUser root /bin/mkdir -p $home}
  3448.                 set com "/sbin/tfadmin usermod $home $uid ftp"
  3449.             } else {
  3450.                 catch {exec /bin/mkdir -p $home}
  3451.                 set com "/usr/sbin/usermod $home $uid ftp"
  3452.             }
  3453.             set err SCO_FTPOSA_ERR_ANON_MODIFY
  3454.         }
  3455.         delete {
  3456.             if {$isOwner} {
  3457.                 set com "/sbin/tfadmin userdel $optn ftp"
  3458.             } else {
  3459.                 set com "/usr/sbin/userdel $optn ftp"
  3460.             }
  3461.             set err SCO_FTPOSA_ERR_ANON_DELETE
  3462.         }
  3463.         default {
  3464.             set res 1
  3465.             set err SCO_FTPOSA_ERR_ANON_INVALID_ACTION
  3466.         }
  3467.     }
  3468.     set com "exec $com"
  3469.     set rc 0
  3470.     if {[catch {eval $com} out]} {
  3471.         if {[cequal $what "modify"] && [lindex $errorCode 2] == 4} {
  3472.             set err SCO_FTPOSA_ERR_ANON_MODIFY_AGED
  3473.         }
  3474.         ErrorPush {} 1 $err
  3475.     }
  3476. }
  3477. proc ftpAnon_get {class object refObject op subOp data attr attrValueList osaData} {
  3478.     switch $attr {
  3479.         home    { set result [OSA:get_ftp_info pw_dir]}
  3480.         uid     { set result [OSA:get_ftp_info pw_uid]}
  3481.         default { ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ATTRIBUTE [list "$attr" "$class"] }
  3482.     }
  3483.     return [list [list $attr $result]]
  3484. }
  3485. proc ftpAnon_replace {class object refObject op subOp data attr attrValueList osaData} {
  3486.     set ftp_home [OSA:get_ftp_info pw_dir]
  3487.     set ftp_uid [OSA:get_ftp_info pw_uid]
  3488.     if {[catch {keylget attrValueList home} attr_home]} {
  3489.         set attr_home ""
  3490.     }
  3491.     if {[catch {keylget attrValueList uid} attr_uid]} {
  3492.         set attr_uid ""
  3493.     }
  3494.     if {$ftp_home != "" && $ftp_uid != "" && ($attr_home != "" || $attr_uid != "")} {
  3495.         if {$attr_home == ""} {
  3496.             set attr_home $ftp_home
  3497.         }
  3498.         if {$attr_uid == ""} {
  3499.             set attr_uid $ftp_uid
  3500.         }
  3501.         if {$attr_home != $ftp_home || $attr_uid != $ftp_uid} {
  3502.             OSA:set_ftp_info modify $attr_home $attr_uid
  3503.         }
  3504.     } elseif {$ftp_home != "" && $ftp_uid != ""} {
  3505.         OSA:set_ftp_info delete
  3506.     } elseif {$attr_home != "" && $attr_uid != ""} {
  3507.         OSA:set_ftp_info create $attr_home $attr_uid
  3508.     } elseif {$attr_home != "" || $attr_uid != ""} {
  3509.         ErrorPush {} 1 SCO_FTPOSA_ERR_ANON_INVALID_ACTION
  3510.     } else {
  3511.     }
  3512.     return 
  3513. }
  3514. proc ftpAnon_action {class object refObject op subOp data attr attrValueList osaData} {
  3515.     switch $subOp {
  3516.         ageduid    { set result [get_ageduid]}
  3517.         default { ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ACTION $subOp }
  3518.     }
  3519.     return $result
  3520. }
  3521. proc get_ageduid {} {
  3522.     global isOwner
  3523.     if {![file exists /etc/security/ia/ageduid]} {
  3524.         return
  3525.     }
  3526.     if {$isOwner} {
  3527.         set fd [open "| /sbin/tfadmin readfile /etc/security/ia/ageduid" r]
  3528.     } else {
  3529.         set fd [open "/etc/security/ia/ageduid" r]
  3530.     }
  3531.     set uids ""
  3532.     while {! [eof $fd]} {
  3533.         gets $fd line
  3534.         set line [split $line ":"]
  3535.         if {[lindex $line 0] != ""} {
  3536.             lappend uids [lindex $line 0]
  3537.         }
  3538.     }
  3539.     close $fd
  3540.     return [lrmdups $uids]
  3541. }
  3542. ############################################################
  3543. proc ftp_readshutdownfile {} {
  3544.     readShutdownFile 
  3545. }
  3546. proc isValidShutdownData {keep} {
  3547.     global ftp_shutdown_data
  3548.     set valid 1
  3549.     set year        $ftp_shutdown_data(year)
  3550.     set month       $ftp_shutdown_data(month)
  3551.     set day         $ftp_shutdown_data(day)
  3552.     set hour        $ftp_shutdown_data(hour)
  3553.     set minute      $ftp_shutdown_data(minute)
  3554.     set deny_offset $ftp_shutdown_data(deny_offset)
  3555.     set disc_offset $ftp_shutdown_data(disc_offset)
  3556.     if {$year < 1970 || $year > 2036 || \
  3557.                         $month < 0 || $month > 11 || \
  3558.                         $day < 1 || $day > 31 || \
  3559.                         $hour < 0 || $hour > 23 || \
  3560.                         $minute < 0 || $minute > 59} {
  3561.         set year   [fmtclock [getclock] "%Y"]
  3562.         set month  [expr [fmtclock [getclock] "%m"] - 1]
  3563.         set day    [fmtclock [getclock] "%d"]
  3564.         set hour   [fmtclock [getclock] "%H"]
  3565.         set minute [fmtclock [getclock] "%M"] 
  3566.         set valid 0
  3567.     }
  3568.     if {[clength $deny_offset] != 4} {
  3569.         set deny_offset 0030
  3570.         set valid 0
  3571.     }
  3572.     set h [crange $deny_offset 0 1]
  3573.     set m [crange $deny_offset 2 3]
  3574.     if {$h < 0 || $h > 23} {
  3575.         set h 01
  3576.         set valid 0
  3577.     }
  3578.     if {$m < 0 || $m > 49} {
  3579.         set m 00
  3580.         set valid 0
  3581.     }
  3582.     set deny_offset ${h}${m}
  3583.     if {[clength $disc_offset] != 4} {
  3584.         set disc_offset 0010
  3585.         set valid 0
  3586.     }
  3587.     set h [crange $disc_offset 0 1]
  3588.     set m [crange $disc_offset 2 3]
  3589.     if {$h < 0 || $h > 23} {
  3590.         set h 01
  3591.         set valid 0
  3592.     }
  3593.     if {$m < 0 || $m > 49} {
  3594.         set m 00
  3595.         set valid 0
  3596.     }
  3597.     set disc_offset ${h}${m}
  3598.     if {$keep} {
  3599.         set ftp_shutdown_data(year)        $year
  3600.         set ftp_shutdown_data(month)       $month
  3601.         set ftp_shutdown_data(day)         $day
  3602.         set ftp_shutdown_data(hour)        $hour
  3603.         set ftp_shutdown_data(minute)      $minute
  3604.         set ftp_shutdown_data(deny_offset) $deny_offset
  3605.         set ftp_shutdown_data(disc_offset) $disc_offset
  3606.     }
  3607.     return $valid
  3608. }
  3609. proc isShutdownFileModified {} {
  3610.     global ftp_shutdown_data
  3611.     set filename [get_shutdown]
  3612.     if {![file exists $filename]} {
  3613.         return TRUE
  3614.     }
  3615.     if {[file mtime $filename] != $ftp_shutdown_data(MTIME)} {
  3616.         return TRUE
  3617.     }
  3618.     return FALSE
  3619. }
  3620. proc readShutdownFile {} {
  3621.     global ftp_shutdown_data isOwner
  3622.     set filename [get_shutdown]
  3623.     set ftp_shutdown_data(year)        9999
  3624.     set ftp_shutdown_data(month)       0
  3625.     set ftp_shutdown_data(day)         0
  3626.     set ftp_shutdown_data(hour)        0
  3627.     set ftp_shutdown_data(minute)      0
  3628.     set ftp_shutdown_data(deny_offset) 0
  3629.     set ftp_shutdown_data(disc_offset) 0
  3630.     set ftp_shutdown_data(stext)       "" 
  3631.     set ftp_shutdown_data(STATE)       enabled
  3632.     set ftp_shutdown_data(MTIME)       0
  3633.     if {$isOwner} {
  3634.         if {[catch {open "|/sbin/tfadmin readfile $filename" r} fd]} {
  3635.             return SCO_FTPOSA_ERR_OPEN_SHUTDOWN_FILE
  3636.         }
  3637.     } else {
  3638.         if {[catch {open $filename r} fd]} {
  3639.             return SCO_FTPOSA_ERR_OPEN_SHUTDOWN_FILE
  3640.         }
  3641.     }
  3642.     set stime [lgets $fd]
  3643.     set stext "[read $fd]"
  3644.     close $fd
  3645.     if {[llength $stime] == 7} {
  3646.         set ftp_shutdown_data(year)        [lindex $stime 0]
  3647.         set ftp_shutdown_data(month)       [lindex $stime 1]
  3648.         set ftp_shutdown_data(day)         [lindex $stime 2]
  3649.         set ftp_shutdown_data(hour)        [lindex $stime 3]
  3650.         set ftp_shutdown_data(minute)      [lindex $stime 4]
  3651.         set ftp_shutdown_data(deny_offset) [lindex $stime 5]
  3652.         set ftp_shutdown_data(disc_offset) [lindex $stime 6]
  3653.     }
  3654.     set ftp_shutdown_data(stext)       $stext
  3655.     if {! [isValidShutdownData 0]} {
  3656.         set ftp_shutdown_data(year) 9999
  3657.     }
  3658.     if {$ftp_shutdown_data(year) == 9999} {
  3659.         set ftp_shutdown_data(STATE) enabled
  3660.     } else {
  3661.         set ftp_shutdown_data(STATE) disabled
  3662.     }
  3663. }
  3664. proc writeShutdownFile {} {
  3665.     global ftp_shutdown_data isOwner
  3666.     set filename [get_shutdown]
  3667.     if {$isOwner} {
  3668.         if {[catch {open "|/sbin/tfadmin writefile $filename" w} fd]} {
  3669.             return SCO_FTPOSA_ERR_OPEN_SHUTDOWN_FILE
  3670.         }
  3671.     } else {
  3672.         if {[catch {open $filename w} fd]} {
  3673.             return SCO_FTPOSA_ERR_OPEN_SHUTDOWN_FILE
  3674.         }
  3675.     }
  3676.     if {$ftp_shutdown_data(STATE) == "enabled"} {
  3677.         set ftp_shutdown_data(year) 9999
  3678.         puts $fd ""
  3679.     } else {
  3680.         puts $fd "$ftp_shutdown_data(year) $ftp_shutdown_data(month) $ftp_shutdown_data(day) $ftp_shutdown_data(hour) $ftp_shutdown_data(minute) $ftp_shutdown_data(deny_offset) $ftp_shutdown_data(disc_offset)"
  3681.     }
  3682.     puts $fd $ftp_shutdown_data(stext) 
  3683.     close $fd
  3684.     set ftp_shutdown_data(MTIME) [file mtime $filename]
  3685.     writeAnonShutdownFile
  3686.     writeVirtualShutdownFile
  3687.     writeGuestShutdownFile
  3688. }
  3689. proc ftpShutdown_create {class object refObject op subOp data attr attrValueList osaData} {
  3690.     global ftp_shutdown_data
  3691.     foreach attr [keylkeys attrValueList] {
  3692.         set ftp_shutdown_data($attr) "[keylget attrValueList $attr]"
  3693.     }
  3694.     set ftp_shutdown_data(STATE) disabled
  3695.     writeShutdownFile
  3696.     return $attrValueList
  3697. }
  3698. proc ftpShutdown_delete {class object refObject op subOp data attr attrValueList osaData} {
  3699.     global ftp_shutdown_data
  3700.     set ftp_shutdown_data(STATE) enabled 
  3701.     writeShutdownFile
  3702.     return {}
  3703. }
  3704. proc ftpShutdown_get {class object refObject op subOp data attr attrValueList osaData} {
  3705.     global ftp_shutdown_data
  3706.     set results {}
  3707.     foreach attr $attrValueList {
  3708.         keylset results $attr "$ftp_shutdown_data($attr)"
  3709.     }
  3710.     return $results
  3711. }
  3712. proc ftpShutdown_action {class object refObject op subOp data attr attrValueList osaData} {
  3713.     switch $subOp {
  3714.         server_state  { return [OSA:getServerState]}
  3715.         default { ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ACTION $subOp }
  3716.     }
  3717.     return ""
  3718. }
  3719. proc offset2time {offset} {
  3720.     set h [crange $offset 0 1]
  3721.     set m [crange $offset 2 3]
  3722.     return [expr $h * 3600 + $m * 60]
  3723. }
  3724. proc OSA:getServerState {} {
  3725.     global ftp_shutdown_data
  3726.     set results {{server unknown} {shutdown unknown}}
  3727.     keylset results server $ftp_shutdown_data(STATE)
  3728.     if {[isShutdownFileModified]} {
  3729.         readShutdownFile
  3730.     }
  3731.     if {$ftp_shutdown_data(STATE) == "disabled"} {
  3732.         set shutdown_time [convertclock "$ftp_shutdown_data(hour):$ftp_shutdown_data(minute) [expr 1 + $ftp_shutdown_data(month)]/$ftp_shutdown_data(day)/$ftp_shutdown_data(year)"]
  3733.         set deny_time [offset2time $ftp_shutdown_data(deny_offset)]
  3734.         set disc_time [offset2time $ftp_shutdown_data(disc_offset)]
  3735.         set now [getclock]
  3736.         if {$now < $shutdown_time-$deny_time} {
  3737.             keylset results shutdown scheduled
  3738.         } elseif {$now >= $shutdown_time-$deny_time && $now < $shutdown_time-$disc_time} {
  3739.             keylset results shutdown deny
  3740.         } elseif {$now >= $shutdown_time-$disc_time && $now < $shutdown_time} {
  3741.             keylset results shutdown disc
  3742.         } elseif {$now >= $shutdown_time} {
  3743.             keylset results shutdown complete
  3744.         }
  3745.     } else {
  3746.         keylset results shutdown none
  3747.     }
  3748.     return $results
  3749. }
  3750. ############################################################
  3751. proc execute_anonhome {args} {
  3752.     global ftp_OsaDir isOwner
  3753.     set args [join $args]
  3754.     if {$isOwner} {
  3755.         set com "exec /sbin/tfadmin swUser root $ftp_OsaDir/anonhome $args"
  3756.     } else {
  3757.         set com "exec $ftp_OsaDir/anonhome $args"
  3758.     }
  3759.     if {[catch {eval "$com"} output]} {
  3760.         return ""
  3761.     }
  3762.     return $output
  3763. }
  3764. proc report_anonhome {args} {
  3765.     global ftp_OsaDir
  3766.     set args [lindex $args 0]
  3767.     set filename [lindex $args 0]
  3768.     set report [lindex $args 1]
  3769.     if {[catch {open "$filename" a} fd]} {
  3770.         ErrorPush {} 1 SCO_OSA_ERR_PROCESSING_FAILURE
  3771.         return 1
  3772.     }
  3773.     puts $fd $report
  3774.     puts $fd "----------------------------------------"
  3775.     close $fd
  3776.     return
  3777. }
  3778. proc ftpAnonHome_action {class object refObject op subOp data attr attrValueList osaData} {
  3779.     global isOwner
  3780.     set result ""
  3781.     switch $subOp {
  3782.         execute {
  3783.             set result [execute_anonhome $data]
  3784.         }
  3785.         shutdown {
  3786.             set root $object
  3787.             set filename [get_shutdown]
  3788.             set dir [file dirname $root/$filename]
  3789.             if {$isOwner} {
  3790.                 catch {exec /sbin/tfadmin swUser root /bin/mkdir -p $dir}
  3791.                 exec /sbin/tfadmin cpfile $filename $root/$filename
  3792.             } else {
  3793.                 catch {mkdir -path $dir}
  3794.                 exec /bin/cp $filename $root/$filename
  3795.             }
  3796.             set result ""
  3797.         }
  3798.         report  { set result [report_anonhome $data] }
  3799.         default { ErrorPush {} 1 SCO_OSA_ERR_NO_SUCH_ACTION $subOp }
  3800.     }
  3801.     return $result
  3802. }
  3803. ############################################################
  3804. ftp_init
  3805. OFBinding sco_ftp_CDT
  3806. OFBinding sco_ftpClass_CDT
  3807. OFBinding sco_ftpLimit_CDT
  3808. OFBinding sco_ftpAccess_CDT
  3809. OFBinding sco_ftpMessage_CDT
  3810. OFBinding sco_ftpDenyHost_CDT
  3811. OFBinding sco_ftpDenyUser_CDT
  3812. OFBinding sco_ftpLog_CDT
  3813. OFBinding sco_ftpShutdown_CDT
  3814. OFBinding sco_ftpVirtual_CDT
  3815. OFBinding sco_ftpAnon_CDT
  3816. OFBinding sco_ftpAnonHome_CDT
  3817.