home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 March B / SCO_CASTOR4RRT.iso / scoadmin / root.3 / etc / mail / admin / aliases / aliases~
Text File  |  1998-08-19  |  79KB  |  2,468 lines

  1. #!/bin/osavtcl
  2. #******************************************************************************
  3. #
  4. #    Copyright (C) 1993-1997 The Santa Cruz Operation, Inc.
  5. #        All Rights Reserved.
  6. #
  7. #    The information in this file is provided for the exclusive use of
  8. #    the licensees of The Santa Cruz Operation, Inc.  Such users have the
  9. #    right to use, modify, and incorporate this code into other products
  10. #    for purposes authorized by the license agreement provided they include
  11. #    this notice and the associated copyright notice with any such product.
  12. #    The information in this file is provided "AS IS" without warranty.
  13. #
  14. #===============================================================================
  15. loadlibindex /usr/lib/sysadm.tlib
  16. proc SCO_MAIL_ADMIN_ALIAS_MSGS {} {}
  17. global SCO_MAIL_ADMIN_ALIAS_MSGS
  18. set SCO_MAIL_ADMIN_ALIAS_MSGS(@catalog@) {alias.cat@mail 1}
  19. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELPBOOK) {1 aliases}
  20. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_SAVE_CONFIRM_TITLE) {2 {Save Changes?}}
  21. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_SAVE_CONFIRM_QUERY) {3 {Do you wish to save the changes made?}}
  22. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_SAVE_CONFIRM_PB_YES) {4 { Yes }}
  23. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_SAVE_CONFIRM_PB_NO) {5 {  No  }}
  24. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_SAVE_CONFIRM_PB_CANCEL) {6 Cancel}
  25. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_STATUS_BOX_TITLE) {7 Information}
  26. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_TITLE) {8 {Alias File %1$s}}
  27. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_FILE_DOESNT_EXIST) {9 {File does not exist}}
  28. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_DIRECTORY) {10 {\"%1$s\" is a directory, not a file}}
  29. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_SEARCH) {11 Search:}
  30. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_SEARCH) {12 {Type the first few letters of a name to search for}}
  31. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_NAME) {13 {Alias names cannot contain \" \", \":\" or \",\" characters.}}
  32. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_READING) {14 {Reading alias configuration.\nPlease wait...}}
  33. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_SAVING) {15 {Saving alias configuration.\nPlease wait...}}
  34. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_REMOVE) {16 {Really remove %1$s \"%2$s\"?}}
  35. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_ALIAS) {17 alias}
  36. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MEMBER) {18 member}
  37. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_REMOVE_MEMBERS) {19 {Really remove all the selected members?}}
  38. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_NONAMES) {20 {The alias must have both a name and at least one member}}
  39. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_DUPLICATE) {21 {An alias with that name already exists}}
  40. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_NO_REDIR) {22 {You must specify a mail redirection address}}
  41. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_ADD_TITLE) {23 {Add Alias}}
  42. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MFY_TITLE) {24 {Modify Alias \"%1$s\"}}
  43. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_ADD_NAME) {25 Name}
  44. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_ADD_MEMBERS_TITLE) {26 {Name list}}
  45. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_ADD_MEMBERS) {27 Members}
  46. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_NOMEMBERS) {28 {You must add at least one member}}
  47. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MEMBER_TITLE) {29 {Add Member}}
  48. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MEMBER_ADD) {30 {Member(s) to add to \"%1$s\"?}}
  49. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MEMBER_ADD_INST) {31 {(Enter names separated with spaces)}}
  50. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_LAST_MEMBER) {32 {You cannot remove the last member of\nan alias.  Delete the alias instead.\n}}
  51. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_LIST_TITLE) {33 Aliases}
  52. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MEMBERS_TITLE) {34 Members}
  53. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MENU_LABEL) {35 Aliases}
  54. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MENU_MNEM) {36 A}
  55. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MENU_ADD_LABEL) {37 Add...}
  56. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MENU_ADD_MNEM) {38 A}
  57. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MENU_REMOVE_LABEL) {39 Remove}
  58. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MENU_REMOVE_MNEM) {40 R}
  59. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MENU_MODIFY_LABEL) {41 Modify...}
  60. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MENU_MODIFY_MNEM) {42 M}
  61. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MENU_SAVE_LABEL) {43 Save}
  62. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MENU_SAVE_MNEM) {44 S}
  63. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MENU_EXIT_LABEL) {45 Exit}
  64. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MENU_EXIT_MNEM) {46 x}
  65. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MEMB_MENU_LABEL) {47 Members}
  66. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MEMB_MENU_MNEM) {48 M}
  67. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MEMB_MENU_ADD) {49 Add...}
  68. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MEMB_MENU_ADD_MNEM) {50 A}
  69. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MEMB_MENU_REMOVE) {51 Remove}
  70. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_MEMB_MENU_REMOVE_MNEM) {52 R}
  71. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USERS_MENU_LABEL) {53 Users}
  72. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USERS_MENU_MNEM) {54 U}
  73. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USERS_MENU_SUB) {55 Subscribe...}
  74. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USERS_MENU_SUB_MNEM) {56 S}
  75. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USERS_MENU_RET) {57 Retire...}
  76. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USERS_MENU_RET_MNEM) {58 R}
  77. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_ADD_PB) {59 { Add name(s) }}
  78. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_REMOVE_PB) {60 { Remove }}
  79. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_EDIT_PB) {61 { Edit }}
  80. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_SELECT_PB) {62 { Select name... }}
  81. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_ADD_TYPE) {63 {Enter name(s):}}
  82. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USER_SELECT_TITLE) {64 {Select User(s)}}
  83. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USER_LIST_TITLE) {65 {Select one or more users:}}
  84. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USER_SELECT_PB) {66 Select...}
  85. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USER_SUB_TITLE) {67 {Subscribe user %1$s}}
  86. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USER_SUB_INST) {68 {Select aliases for %1$s to join:}}
  87. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USER_SUB_INST_SPACE) {69 {Select aliases for '%1$s' to join:}}
  88. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USER_SUB_ADD_PB) {70 {   ADD >>}}
  89. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USER_SUB_RMV_PB) {71 {<< REMOVE}}
  90. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USER_SUB_SYSLIST) {72 {System aliases}}
  91. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USER_SUB_ULIST) {73 {Aliases %1$s subscribes to}}
  92. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USER_RET_TITLE) {74 {Remove User %1$s}}
  93. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USER_RET_INST) {75 {This removes user %1$s from all aliases in\n%2$s.\n}}
  94. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_USER_RET_REDIR) {76 {Redirect mail for %1$s to:}}
  95. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_USAGE) {77 {Usage: aliases -f [dbm:|btree:|hash:|implicit:]filename\n\t[-h hostname]\n\t[-a alias:member[,member...]] [-d alias[,alias...]]\n\t[-s user:alias[,alias...]] [-S user[,user...]]\n\t[-r user:alias[,alias...]] [-R user[,user...]]}}
  96. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_MISSING_ADD_ARG) {78 {Missing recipient list argument for -a option}}
  97. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_MISSING_FILE_OPT) {79 {Missing filename argument}}
  98. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_UNKNOWN_ARG) {80 {Unknown option \"%1$s\"}}
  99. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_UNKNOWN_CLASS) {81 {Unknown database class \"%1$s\" specified in -f argument}}
  100. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_MENU_ALIASES) {82 {Add and Remove aliases, Save, Quit}}
  101. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_MENU_ALIASES_ADD) {83 {Add an alias to the system}}
  102. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_MENU_ALIASES_RMV) {84 {Remove the selected alias from the system}}
  103. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_MENU_ALIASES_MFY) {85 {Modify the selected alias}}
  104. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_MENU_ALIASES_SAVE) {86 {Save any changes}}
  105. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_MENU_ALIASES_QUIT) {87 {Exit this program}}
  106. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_MENU_MEMBERS) {88 {Add and Remove members}}
  107. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_MENU_MEMBERS_ADD) {89 {Add a member to the selected alias to the system}}
  108. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_MENU_MEMBERS_RMV) {90 {Remove the selected member from the selected alias}}
  109. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_ALIAS_ADD_NAME) {91 {Type the name of the alias you wish to create}}
  110. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_ALIAS_ADD_MEMBERS) {92 {The list of members for the alias}}
  111. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_ALIASES_LIST) {93 {The list of aliases in file %1$s}}
  112. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_MEMBERS_LIST) {94 {The list of members of a selected alias}}
  113. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_ALIAS_ADD_PB) {95 {Press to add typed names(s) to list}}
  114. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_ALIAS_REM_PB) {96 {Press to remove selected names(s)}}
  115. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_ALIAS_EDIT_PB) {97 {Press to edit selected names(s)}}
  116. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_ALIAS_SEL_PB) {98 {Press to select names from a list}}
  117. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_ALIAS_ADD_TYPE) {99 {Type name(s) to be added, separated by spaces}}
  118. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_MENU_USERS) {100 {Subscribe or Retire users}}
  119. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_MENU_USERS_SUB) {101 {Subscribe user(s) to aliases}}
  120. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_MENU_USERS_RET) {102 {Retire user(s)}}
  121. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_USER_SUB_SYSLIST) {103 {Aliases in file %1$s}}
  122. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_USER_SUB_ADD_PB) {104 {Moves the selected alias(es) to the user's subscription list}}
  123. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_USER_SUB_RMV_PB) {105 {Removes the selected alias(es) back to the system list}}
  124. set SCO_MAIL_ADMIN_ALIAS_MSGS(MSG_HELP_USER_SUB_ULIST) {106 {The aliases that the user will subscribe to}}
  125. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_CANT_SAVE) {107 {aliases: Unable to save: %1$s}}
  126. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_NEWALIASES) {108 {aliases: Unable to compile alias database: %1$s}}
  127. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_CANT_LOAD) {109 {Failed to load alias file:\n%1$s}}
  128. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_WRITE) {110 {Failed to write alias file:\n%1$s}}
  129. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_DB) {111 {Failed to create alias database:\n%1$s}}
  130. set SCO_MAIL_ADMIN_ALIAS_MSGS(ERR_NONSTDCMD) {112 %s}
  131. proc ConfigFile:Open {} {
  132.     global Config_next
  133.     if {![info exists Config_next]} {
  134.     set Config_next 0
  135.     }
  136.     set file "config$Config_next"
  137.     incr Config_next
  138.     upvar #0 Config_${file}_next file_next
  139.     set file_next "1.0"
  140.     return $file
  141. }
  142. proc ConfigFile:Close {file} {
  143.     upvar #0 Config_$file fileList
  144.     upvar #0 Config_${file}_next file_next
  145.     unset file_next
  146.     foreach line [ConfigFile:GetList $file] {
  147.     unset fileList($line)
  148.     }
  149. }
  150. proc ConfigFile:Compare {line1 line2} {
  151.     set subLine1 [ctoken line1 "."]
  152.     set subLine2 [ctoken line2 "."]
  153.     if {$subLine1 == "" && $subLine2 == ""} {
  154.     return 0
  155.     } elseif {$subLine1 == ""} {
  156.     return -1
  157.     }  elseif {$subLine2 == ""} {
  158.     return 1
  159.     } elseif {$subLine1 < $subLine2} {
  160.     return -1
  161.     } elseif {$subLine1 > $subLine2} {
  162.     return 1
  163.     } else {
  164.     set line1 [string trimleft $line1 "."]
  165.     set line2 [string trimleft $line2 "."]
  166.     return [ConfigFile:Compare $line1 $line2]
  167.     }
  168. }
  169. proc ConfigFile:ReplaceLine {file line type id dataVar} {
  170.     upvar #0 Config_$file fileList
  171.     upvar #0 Config_${file}_next file_next
  172.     upvar $dataVar data
  173.     keylset fileList($line) type $type
  174.     keylset fileList($line) data $data
  175.     keylset fileList($line) id $id
  176.     if {[ConfigFile:Compare $line $file_next] == 1} {
  177.     set temp $line
  178.     set file_next [ctoken temp "."]
  179.     incr file_next
  180.     set file_next "${file_next}.0"
  181.     }
  182. }
  183. proc ConfigFile:AppendLine {file line type id dataVar} {
  184.     upvar #0 Config_$file fileList
  185.     upvar #0 Config_${file}_next file_next
  186.     upvar $dataVar data
  187.     if {$line == -1} {
  188.     set line $file_next
  189.     set temp [ctoken file_next "."]
  190.     incr temp
  191.     set file_next "${temp}.0"
  192.     } else {
  193.     set found 0
  194.     set left [ctoken line "."]
  195.     set right [ctoken line "."]
  196.     if {$right == "0"} {
  197.         set tryNext $left
  198.         incr tryNext
  199.         set tryNext "${tryNext}.0"
  200.         if {![info exists fileList($tryNext)]} { 
  201.         set found 1
  202.         }
  203.     }
  204.     if {!$found} {
  205.         set lastDigit [cindex $right end]
  206.         if {$lastDigit < 9} {
  207.             incr lastDigit
  208.             set tryNext "${left}.[csubstr $right 0 end]${lastDigit}"
  209.             if {![info exists fileList($tryNext)]} {
  210.             set found 1
  211.             }    
  212.         }
  213.     }
  214.     if {!$found} {
  215.         set leadingZeros ""
  216.         set tryNext "${left}.${right}.1"
  217.         while {[info exists fileList($tryNext)]} {
  218.         set leadingZeros "${leadingZeros}.0"
  219.         set tryNext "${left}.${right}${leadingZeros}.1"
  220.         }
  221.     }
  222.     set line $tryNext
  223.     }
  224.     keylset fileList($line) type $type
  225.     keylset fileList($line) id $id
  226.     keylset fileList($line) data $data
  227.     if {[string compare $line $file_next] == 1} {
  228.     set temp $line
  229.     set file_next [ctoken temp "."]
  230.     incr file_next
  231.     set file_next "${file_next}.0"
  232.     }
  233.     return $line
  234. }
  235. proc ConfigFile:GetLine {file line typeVar idVar dataVar} {
  236.     upvar #0 Config_$file fileList
  237.     upvar $typeVar type
  238.     upvar $idVar id
  239.     upvar $dataVar data
  240.     if {![info exists fileList($line)]} {
  241.     set type {}
  242.     set id {}
  243.     set data {}
  244.     return -1
  245.     }
  246.     keylget fileList($line) type type
  247.     keylget fileList($line) id id
  248.     keylget fileList($line) data data
  249.     return 0
  250. }
  251. proc ConfigFile:RemoveLine {file line} {
  252.     upvar #0 Config_$file fileList
  253.     if {![info exists fileList($line)]} {
  254.     # already gone
  255.     return
  256.     }
  257.     unset fileList($line)
  258. }
  259. proc ConfigFile:GetList {file} {
  260.     upvar #0 Config_$file fileList
  261.     if {![info exists fileList]} {
  262.     return {}
  263.     }
  264.     return [lsort -command ConfigFile:Compare [array names fileList]]
  265. }
  266. proc Table:ProcessLine {fileID type id data} {
  267.     global Table_lastType Table_lastID
  268.     set lineNum [ConfigFile:AppendLine $fileID -1 $type $id data]
  269.     if {[Table:GetOption $fileID makelower] != {}} {
  270.     set id [string tolower $id]
  271.     }
  272.     case $type {
  273.     CONTINUATION {
  274.         set type $Table_lastType
  275.         set id $Table_lastID
  276.     }
  277.     COMMENT {
  278.     }
  279.     default {
  280.         set Table_lastType $type
  281.         set Table_lastID $id
  282.     }
  283.     }
  284.     if {$id != {}} {
  285.     upvar #0 Table_${fileID}_$type typeList
  286.     lappend typeList($id) $lineNum
  287.     }
  288. }
  289. proc Table:Read {fileName callBack mode} {
  290.     global Table_info
  291.     if {[info exists Table_info($fileName.ID)]} {
  292.     return $Table_info($fileName.ID)
  293.     }
  294.     set fileID [ConfigFile:Open]
  295.     set Table_info($fileID.mode) $mode
  296.     if {![file exists $fileName]} {
  297.     return $fileID
  298.     }
  299.     set fp [open $fileName r]
  300.     set Table_info($fileName.ID) $fileID
  301.     set Table_info($fileID.fileName) $fileName
  302.     eval $callBack $fileID $fp
  303.     close $fp
  304.     return $fileID
  305. }
  306. proc Table:Write {fileID {fileName {}} {callBack {}}} {
  307.     global Table_info
  308.     if {[info exists Table_info($fileID.deferred)]} {
  309.     return
  310.     }
  311.     if {![info exists Table_info($fileID.modified)] && $fileName == {}} {
  312.     return
  313.     }
  314.     if {$callBack == {}} {
  315.     set callBack $Table_info($fileID.writeCB)
  316.     }
  317.     if {$fileName == {}} {
  318.     set fileName $Table_info($fileID.fileName)
  319.     set clearModified 1
  320.     } else {
  321.     set clearModified 0
  322.     }
  323.     #
  324.     # If the file exists, make sure the new file has the
  325.     # same owner and perms.  Otherwise, make sure the
  326.     # parent directory exists.
  327.     #
  328.     if {[file exists $fileName]} {
  329.     file stat $fileName info
  330.     set Table_info($fileID.uid) $info(uid)
  331.     set Table_info($fileID.gid) $info(gid)
  332.     set Table_info($fileID.mode) $info(mode)
  333.     } else {
  334.     set directory [file dirname $fileName]
  335.     set oldUmask [umask]
  336.     umask 0222
  337.     if {![file isdirectory $directory]} {
  338.         mkdir -path $directory
  339.     }
  340.     umask $oldUmask
  341.     }
  342.     set fp [open ${fileName}.new w]
  343.     chmod $Table_info($fileID.mode) ${fileName}.new
  344.     if {[info exists Table_info($fileID.uid)]} {
  345.     chown [list $Table_info($fileID.uid) $Table_info($fileID.gid)] \
  346.         ${fileName}.new
  347.     }
  348.     foreach line [ConfigFile:GetList $fileID] {
  349.     if {[ConfigFile:GetLine $fileID $line type id data] != 0} {
  350.         continue
  351.     }
  352.     eval "$callBack $fileID $fp {$type} {$id} {$data}"
  353.     }
  354.     close $fp
  355.     if {[file exists $fileName]} {
  356.     unlink $fileName
  357.     }
  358.     frename ${fileName}.new $fileName
  359.     if {$clearModified} {
  360.     unset Table_info($fileID.modified)
  361.     }
  362. }
  363. proc Table:Open {fileName readCB writeCB {mode 0666}} {
  364.     global Table_info
  365.     set fileID [Table:Read $fileName $readCB $mode]
  366.     set Table_info($fileID.fileName) $fileName
  367.     set Table_info($fileID.readCB) $readCB
  368.     set Table_info($fileID.writeCB) $writeCB
  369.     set Table_info($fileName.ID) $fileID
  370.     return $fileID
  371. }
  372. proc Table:Close {fileID {fileName {}}} {
  373.     global Table_info
  374.     if {![info exists Table_info($fileID.fileName)]} {
  375.     return
  376.     }
  377.     if {[info exists Table_info($fileID.deferred)]} {
  378.     unset Table_info($fileID.deferred)
  379.     }
  380.     Table:Write $fileID $fileName $Table_info($fileID.writeCB)
  381.     if {$fileName == {}} {
  382.     set fileName $Table_info($fileID.fileName)
  383.     }
  384.     unset Table_info($fileID.fileName)
  385.     unset Table_info($fileName.ID)
  386.     ConfigFile:Close $fileID
  387. }
  388. proc Table:CloseNoWrite {fileID {fileName {}}} {
  389.     global Table_info
  390.     if {![info exists Table_info($fileID.fileName)]} {
  391.     return
  392.     }
  393.     if {[info exists Table_info($fileID.deferred)]} {
  394.     unset Table_info($fileID.deferred)
  395.     }
  396.     if {$fileName == {}} {
  397.     set fileName $Table_info($fileID.fileName)
  398.     }
  399.     unset Table_info($fileID.fileName)
  400.     unset Table_info($fileName.ID)
  401.     ConfigFile:Close $fileID
  402. }
  403. proc Table:DeferWrites {fileID} {
  404.     global Table_info
  405.     set Table_info($fileID.deferred) 1
  406. }
  407. proc Table:ForceWrites {fileID} {
  408.     global Table_info
  409.     if {[info exists Table_info($fileID.deferred)]} {
  410.     unset Table_info($fileID.deferred)
  411.     }
  412.     set Table_info($fileID.modified) 1
  413. proc Table:SetOption {fileID option {value 1}} {
  414.     global Table_options
  415.     set Table_options($fileID.$option) $value
  416. }
  417. proc Table:HasOption {fileID option} {
  418.     return [info exists Table_options($fileID.$option)]
  419. }
  420. proc Table:GetOption {fileID option} {
  421.     global Table_options
  422.     if {![info exists Table_options($fileID.$option)]} {
  423.     return {}
  424.     }
  425.     return $Table_options($fileID.$option)
  426. }
  427. proc Table:Modified {fileID} {
  428.     global Table_info
  429.     if {[info exists Table_info($fileID.modified)]} {
  430.     return $Table_info($fileID.modified)
  431.     } else {
  432.     return 0
  433.     }
  434. }
  435. proc Table:GetLineList {fileID type {idList {}}} {
  436.     upvar #0 Table_${fileID}_$type typeList
  437.     if {![info exists typeList]} {
  438.     return {}
  439.     }
  440.     if {$idList == {}} {
  441.     set idList [array names typeList]
  442.     }
  443.     set lineList {}
  444.     foreach id $idList {
  445.     if {[info exists typeList($id)]} {
  446.         append lineList " $typeList($id)"
  447.     }
  448.     }
  449.     return [lsort -command ConfigFile:Compare $lineList]
  450. }
  451. proc Table:Get {fileID type id {separator {}}} {
  452.     upvar #0 Table_${fileID}_$type typeList
  453.     if {[Table:GetOption $fileID makelower] != {}} {
  454.     set id [string tolower $id]
  455.     }
  456.     set value {}
  457.     if {![info exists typeList($id)]} {
  458.     return $value
  459.     }
  460.     set numLines [llength [Table:GetLineList $fileID $type $id]]
  461.     set thisLine 1
  462.     foreach line $typeList($id) {
  463.     ConfigFile:GetLine $fileID $line dummy dummy data
  464.     if {$thisLine == $numLines} {
  465.         append value "$data"
  466.     } else {
  467.         set data [string trim $data "$separator"]
  468.         append value "$data$separator"
  469.     }
  470.     incr thisLine
  471.     }
  472.     set value [string trimleft $value $separator]
  473.     return $value
  474. }
  475. proc Table:Set {fileID type id data} {
  476.     upvar #0 Table_${fileID}_${type} typeList
  477.     global Table_info
  478.     global Table_lastType Table_lastID
  479.     set name $id
  480.     if {[Table:GetOption $fileID makelower] != {}} {
  481.     set id [string tolower $id]
  482.     }
  483.     if {[info exists typeList($id)]} {
  484.     foreach line $typeList($id) {
  485.         ConfigFile:RemoveLine $fileID $line
  486.     }
  487.     set line [lindex $typeList($id) 0]
  488.     unset typeList($id)
  489.     } else {
  490.     if {[set lineList [Table:GetLineList $fileID $type]] != {}} {
  491.         set line [lindex $lineList end]
  492.     } else {
  493.         if {[Table:GetOption $fileID newFirst] == 1} {
  494.         set line 0
  495.         } else {
  496.         set line -1
  497.         }
  498.     }
  499.     }
  500.     lappend typeList($id) [ConfigFile:AppendLine $fileID $line \
  501.     $type $name data]
  502.     set Table_lastType $type
  503.     set Table_lastID $id
  504.     set Table_info($fileID.modified) 1
  505. }
  506. proc Table:Unset {fileID type id} {
  507.     upvar #0 Table_${fileID}_$type typeList
  508.     global Table_info
  509.     if {[Table:GetOption $fileID makelower] != {}} {
  510.     set id [string tolower $id]
  511.     }
  512.     if {![info exists typeList($id)]} {
  513.     return
  514.     }
  515.     foreach line $typeList($id) {
  516.     ConfigFile:RemoveLine $fileID $line
  517.     }
  518.     unset typeList($id)
  519.     set Table_info($fileID.modified) 1
  520. }
  521. proc Table:AppendLine {fileID type id value {line {}}} {
  522.     global Table_lastType Table_lastID
  523.     global Table_info
  524.     if {$type == "CONTINUATION"} {
  525.     upvar #0 Table_${fileID}_$Table_lastType typeList
  526.     } else {
  527.     upvar #0 Table_${fileID}_$type typeList
  528.     }
  529.     if {[Table:GetOption $fileID makelower] != {}} {
  530.     set id [string tolower $id]
  531.     }
  532.     if {$line == ""} {
  533.     if {[info exists typeList($id)]} {
  534.         set line [lindex $typeList($id) end]
  535.     } else {
  536.         if {[set lineList [Table:GetLineList $fileID $type]] == {}} {
  537.         set line [lindex $lineList end]
  538.         } else {
  539.         if {[Table:GetOption $fileID newFirst] == 1} {
  540.             set line 0
  541.         } else {
  542.             set line -1
  543.         }
  544.         }
  545.     }
  546.     }
  547.     if {$type == "CONTINUATION"} {
  548.     lappend typeList($id) \
  549.         [ConfigFile:AppendLine $fileID $line $type {} value]
  550.     } else {
  551.     lappend typeList($id) \
  552.         [ConfigFile:AppendLine $fileID $line $type $id value]
  553.     }
  554.     set Table_info($fileID.modified) 1
  555. }
  556. proc Table:RemoveLine {fileID type id deleteLine} {
  557.     upvar #0 Table_${fileID}_$type typeList
  558.     global Table_info
  559.     if {[Table:GetOption $fileID makelower] != {}} {
  560.     set id [string tolower $id]
  561.     }
  562.     if {![info exists typeList($id)]} {
  563.     return
  564.     }
  565.     set index 0
  566.     foreach line $typeList($id) {
  567.     if {$line == $deleteLine} {
  568.         lvarpop typeList($id) $index
  569.         ConfigFile:RemoveLine $fileID $line
  570.         break
  571.     }
  572.     incr index
  573.     }
  574.     set Table_info($fileID.modified) 1
  575. }
  576. proc Table:ReplaceLine {fileID type replaceLine id data} {
  577.     global Table_info
  578.     upvar #0 Table_${fileID}_$type typeList
  579.     if {[ConfigFile:GetLine $fileID $replaceLine oldType oldId oldData] == 0} {
  580.     if {$oldId != ""} {
  581.             upvar #0 Table_${fileID}_$oldType oldTypeList
  582.         set index [lsearch -exact $oldTypeList($oldId) $replaceLine]
  583.         if {$index != -1} {
  584.         lvarpop oldTypeList($oldId) $index
  585.         if {[lempty $oldTypeList($oldId)]} {
  586.             unset oldTypeList($oldId)
  587.         }
  588.         }
  589.     }
  590.     }
  591.     ConfigFile:ReplaceLine $fileID $replaceLine $type $id data
  592.     if {$id != ""} {
  593.     if {![info exists typeList($id)]} {
  594.         set typeList($id) {}
  595.     }
  596.     lappend typeList($id) $replaceLine
  597.     }
  598.     set Table_info($fileID.modified) 1
  599. }
  600. proc Table:List {fileID type {ordered 0}} {
  601.     upvar #0 Table_${fileID}_$type typeList
  602.     if {![info exists typeList]} {
  603.     return {}
  604.     }
  605.     if {[Table:GetOption $fileID makelower] == {} && $ordered == 0} {
  606.     return [array names typeList]
  607.     }
  608.     #
  609.     # We have to go get the original ids from before they were converted 
  610.     # to lower case, or they want the ids in the order they appear anyway.
  611.     #
  612.     set returnList {}
  613.     foreach line [Table:GetLineList $fileID $type] {
  614.     ConfigFile:GetLine $fileID $line dummy id dummy
  615.     append returnList " $id"
  616.     }
  617.     return [string trimleft $returnList]
  618. }
  619. set Alias_MaxLine    80
  620. proc Alias:ReadCB {fileID fp} {
  621.     set context [scancontext create]
  622.     scanmatch $context {^(#.*|[     ]*)$} {
  623.     Table:ProcessLine $fileID COMMENT {} $matchInfo(line)
  624.     continue
  625.     }
  626.     scanmatch $context {^([^:     ]+):(.*)} {
  627.     Table:ProcessLine $fileID alias $matchInfo(submatch0) \
  628.         $matchInfo(submatch1)
  629.     }
  630.     scanmatch $context {^[     ]+[^     ]+} {
  631.     Table:ProcessLine $fileID CONTINUATION {} $matchInfo(line)
  632.     }
  633.     scanmatch $context {
  634.     Table:ProcessLine $fileID COMMENT {} $matchInfo(line)
  635.     }
  636.     scanfile $context $fp
  637.     scancontext delete $context
  638. }
  639. proc Alias:WriteCB {fileID fp type id data} {
  640.     case $type {
  641.     alias {
  642.         if {$id != {}} {
  643.         puts $fp "$id:" nonewline
  644.         }
  645.         puts $fp $data
  646.     }
  647.     default {
  648.         puts $fp $data
  649.     }
  650.     }
  651. }
  652. proc Alias:Open {fileName {mode 0644}} {
  653.     return [Table:Open $fileName Alias:ReadCB Alias:WriteCB $mode]
  654. }
  655. proc Alias:Write {fileID {fileName {}}} {
  656.     return [Table:Write $fileID $fileName]
  657. }
  658. proc Alias:Close {fileID} {
  659.     return [Table:Close $fileID]
  660. }
  661. proc Alias:DeferWrites {fileID} {
  662.     return [Table:DeferWrites $fileID]
  663. }
  664. proc Alias:ForceWrites {fileID} {
  665.     return [Table:ForceWrites $fileID]
  666. }
  667. proc Alias:Get {fileID id} {
  668.     set value [Table:Get $fileID alias $id]
  669.     set result {}
  670.     # alias recipients are separated by commas--
  671.     # but a recipient may be a quoted string which also has a comma
  672.     while {[clength $value] > 0} {
  673.     set thisToken [ctoken value ","]
  674.     set numQuotes [expr [llength [split $thisToken "\""]] - 1]
  675.     if {[fmod $numQuotes 2] == 1.0} {
  676.         set restOfQuotedPart [ctoken value "\""]
  677.         append thisToken $restOfQuotedPart
  678.         append thisToken [ctoken value ","]
  679.     }
  680.     set recipient [string trim $thisToken]
  681.     if {[clength $recipient] > 0} {
  682.         lappend result $recipient
  683.     }
  684.     }
  685.     return $result
  686. }
  687. proc Alias:Set {fileID id value} {
  688.     global Alias_MaxLine
  689.     set data " [lvarpop value],"
  690.     # for first line, add length of alias name, plus 1 for the colon,
  691.     # plus length of $data
  692.     set length [expr [string length $data] + [string length $id] + 1]
  693.     set first 1
  694.     foreach word $value {
  695.     set wordLen [string length $word]
  696.     if {[expr "$length + $wordLen + 2"] <= $Alias_MaxLine} {
  697.         append data " $word,"
  698.         set length [expr "$length + $wordLen + 2"]
  699.     } else {
  700.         if {$first} {
  701.         Table:Set $fileID alias $id $data
  702.         } else {
  703.         # if this isn't the first line, append as a continued line
  704.         Table:AppendLine $fileID CONTINUATION $id $data
  705.         }
  706.         set first 0
  707.         set data "\t${word},"
  708.         set length [expr "$wordLen + 9"]
  709.     }
  710.     }
  711.     set data [string trimright $data ","]
  712.     if {$first} {
  713.     return [Table:Set $fileID alias $id $data]
  714.     } else {
  715.     return [Table:AppendLine $fileID CONTINUATION $id $data]
  716.     }
  717. }
  718. proc Alias:Unset {fileID id} {
  719.     return [Table:Unset $fileID alias $id]
  720. }
  721. proc Alias:List {fileID} {
  722.     return [Table:List $fileID alias]
  723. }
  724. proc Alias:AddValue {fileID id addValue} {
  725.     set currentValue [Alias:Get $fileID $id]
  726.     if {[lempty $currentValue]} {
  727.     set newValue $addValue
  728.     } else {
  729.     set newValue [union $currentValue $addValue]
  730.     }
  731.     return [Alias:Set $fileID $id $newValue]
  732. }
  733. proc Alias:RemoveValue {fileID id removeValue} {
  734.     set currentValue [Alias:Get $fileID $id]
  735.     set newValue [lindex [intersect3 $currentValue $removeValue] 0]
  736.     if {[lempty $newValue]} {
  737.     return [Alias:Unset $fileID $id]
  738.     } else {
  739.     return [Alias:Set $fileID $id $newValue]
  740.     }
  741. }
  742. proc Alias:Modified {fileID} {
  743.     return [Table:Modified $fileID]
  744. }
  745. proc Alias:IsMember {fileID id recipient} {
  746.     set members [Alias:Get $fileID $id]
  747.     if {[lempty [lmatch -exact $members $recipient]]} {
  748.     return 0
  749.     } else {
  750.     return 1
  751.     }
  752. }
  753. proc Alias:Memberships {fileID recipient} {
  754.     set result {}
  755.     foreach alias [Alias:List $fileID] {
  756.     if {[Alias:IsMember $fileID $alias $recipient]} {
  757.         lappend result $alias
  758.     }
  759.     }
  760.     return $result
  761. }
  762. set MA_ALIAS_FILEID -1
  763. set MA_ALIAS_FILENAME ""
  764. set MA_ALIAS_CLASS NONE
  765. set MA_ALIAS_DATABASE_CLASSES [list dbm btree hash implicit NONE]
  766. set MA_ALIAS_MANAGED_HOST "localhost"
  767. set MA_ALIAS_SENDMAILCF /etc/mail/sendmailcf.factory
  768. set MA_ALIAS_NEWALIASES /etc/mail/newaliases
  769. proc SaSetFocusUnlock { what cbs } {
  770.     SaSetFocus $what $cbs
  771.     VtUnLock
  772. }
  773. proc GetUsers {} {
  774.     global MA_ALIAS_MANAGED_HOST
  775.     # SaUsersGet should already sort the users
  776.     return [SaUsersGet $MA_ALIAS_MANAGED_HOST]
  777. }
  778. proc NameErr { parent } {
  779.     VtShow\
  780.         [VtErrorDialog $parent.eb -ok\
  781.             -message [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_NAME]]
  782. }
  783. set MyStatusCurID "*not*a*form*id*"
  784. set MyStatusCurForm ""
  785. proc MyStatusBox { id what } {
  786.     global MyStatusCurID MyStatusCurForm
  787.     if {$what == "-close"} {
  788.         if {$id == $MyStatusCurID} {
  789.             VtDestroyDialog $MyStatusCurForm
  790.             VtUnLock -once
  791.             set MyStatusCurID "*not*a*form*id*"
  792.         } else {
  793.             error "MyStatusBox: $id not the current form"
  794.         }
  795.         return
  796.     }
  797.     if {$id == $MyStatusCurID} {
  798.         set label [VxGetVar $MyStatusCurForm "label"]
  799.         VtSetValues $label -label "$what"
  800.         return
  801.     }
  802.     if {$MyStatusCurID != "*not*a*form*id*"} {
  803.         error "MyStatusBox: another status box already being displayed"
  804.         return
  805.     }
  806.     set MyStatusCurID $id
  807.     #VtLock
  808.     set MyStatusCurForm\
  809.         [VtFormDialog $id\
  810.             -title [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_STATUS_BOX_TITLE]]
  811.     set label\
  812.         [VtLabel $MyStatusCurForm.Label\
  813.             -label $what\
  814.             -rightSide FORM\
  815.             -bottomSide FORM]
  816.     VxSetVar $MyStatusCurForm "label" $label
  817.     VtShow $MyStatusCurForm
  818.     VtLock
  819. }
  820. proc SaveCB { cbs {doUnlock 1}} {
  821.     global MA_ALIAS_FILEID MA_ALIAS_FILENAME MA_ALIAS_CLASS
  822.     global MA_ALIAS_SENDMAILCF MA_ALIAS_NEWALIASES
  823.     global mainForm errorInfo
  824.     MyStatusBox $mainForm.savebox [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_SAVING]
  825.     # We want to save whether there have been modifications or not
  826.     Alias:ForceWrites $MA_ALIAS_FILEID
  827.     if {[ErrorCatch errStack 0 { Alias:Write $MA_ALIAS_FILEID } errmsg] != 0} {
  828.         MyStatusBox $mainForm.savebox -close
  829.         SaDisplayErrorInfo $mainForm.ErrorWrite [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_WRITE $MA_ALIAS_FILENAME] noHelp
  830.         if {$doUnlock} {
  831.             VtUnLock
  832.         }
  833.         return 0
  834.     }
  835.     # the newaliases command doesn't work if the alias file specified in
  836.     # the command line is not a full pathname
  837.     if {[cindex $MA_ALIAS_FILENAME 0] != "/"} {
  838.         set MA_ALIAS_FILENAME "[pwd]/${MA_ALIAS_FILENAME}"
  839.     }
  840.     if {$MA_ALIAS_CLASS == "NONE"} {
  841.         set cmd \
  842.         "exec $MA_ALIAS_NEWALIASES -oA${MA_ALIAS_FILENAME} -C${MA_ALIAS_SENDMAILCF} >& /dev/null"
  843.     } else {
  844.         set cmd \
  845.         "exec $MA_ALIAS_NEWALIASES -oA${MA_ALIAS_CLASS}:${MA_ALIAS_FILENAME} -C${MA_ALIAS_SENDMAILCF} >& /dev/null"
  846.     }
  847.     if {[ErrorCatch errStack 0 $cmd errmsg] != 0} {
  848.         MyStatusBox $mainForm.savebox -close
  849.         SaDisplayErrorInfo $mainForm.ErrorDB [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_DB ${MA_ALIAS_FILENAME}.db] noHelp
  850.         if {$doUnlock} {
  851.             VtUnLock
  852.         }
  853.         return 0
  854.     }
  855.     MyStatusBox $mainForm.savebox -close
  856.     if {$doUnlock} {
  857.         VtUnLock
  858.     }
  859.     return 1
  860. }
  861. proc quitCB { cbs } {
  862.     quit
  863. }
  864. proc quit {} {
  865.     VtUnLock
  866.     VtClose
  867.     exit
  868. }
  869. proc _saveConCB { which cbs } {
  870.     set parent [keylget cbs "dialog"]
  871.     set callback [VxGetVar $parent "callback"]
  872.     VtDestroyDialog $parent
  873.     $callback $which
  874. }
  875. proc saveConfirm { wname callback } {
  876.     set isCharm [VtInfo -charm]
  877.     set dlog\
  878.         [VtFormDialog $wname\
  879.             -okLabel [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_SAVE_CONFIRM_PB_YES]\
  880.             -okCallback {_saveConCB "save"}\
  881.             -autoLock _saveConCB\
  882.             -applyLabel [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_SAVE_CONFIRM_PB_NO]\
  883.             -applyCallback {_saveConCB "discard"}\
  884.             -cancelLabel\
  885.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_SAVE_CONFIRM_PB_CANCEL]\
  886.             -cancelCallback {_saveConCB "cancel"}\
  887.             -wmCloseCallback {_saveConCB "cancel"}\
  888.             -title [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_SAVE_CONFIRM_TITLE]]
  889.     VxSetVar $dlog "callback" $callback
  890.     VtLabel $dlog.label\
  891.         -rightSide FORM\
  892.         -font medBoldFont\
  893.         -label "\n[IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_SAVE_CONFIRM_QUERY]\n"
  894.     VtShow $dlog
  895. }
  896. proc saveConfirmCB { action } {
  897.     if { $action == "cancel"} {
  898.         VtUnLock
  899.         return
  900.     }
  901.     if { $action == "save"} {
  902.         if {![SaveCB {} 0]} {
  903.             VtUnLock
  904.             return
  905.         }
  906.     }
  907.     quit
  908. }
  909. proc CloseCB { cbs } {
  910.     global MA_ALIAS_FILEID
  911.     if {[Alias:Modified $MA_ALIAS_FILEID]} {
  912.         set parent [keylget cbs "dialog"]
  913.         saveConfirm $parent.savebox saveConfirmCB
  914.         VtUnLock
  915.         return
  916.     }
  917.     quit
  918. }
  919. proc ConfirmRemoval { what names okCB remove } {
  920.     global    mainForm
  921.     if {[llength $names] > 1} {
  922.         set msg [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_REMOVE_MEMBERS]
  923.     } else {
  924.         set msg\
  925.           [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_REMOVE [list $what $names]]
  926.     }
  927.     if {"$remove" == "alias"} {
  928.         set formname $mainForm.iboxAlias
  929.     } else {
  930.         set formname $mainForm.iboxMember
  931.     }
  932.     VtShow [VtQuestionDialog $formname\
  933.                 -okCallback $okCB -autoLock $okCB -message $msg]
  934. }
  935. set _UserSelPBCallback "<null>"
  936. proc _UserSelPBDone { what cbs } {
  937.     global _UserSelPBCallback
  938.     set parent [keylget cbs "dialog"]
  939.     if {$what == "OK"} {
  940.         set userSelectList [VxGetVar $parent "userSelectList"]
  941.         set users [VtListGetSelectedItem $userSelectList -byItemList]
  942.     } else {
  943.         set users {}
  944.     }
  945.     VtDestroyDialog $parent
  946.     if {$_UserSelPBCallback != "<null>" && ![lempty $users]} {
  947.         set routine [lvarpop _UserSelPBCallback]
  948.         eval $routine [list $users] $_UserSelPBCallback [list $cbs]
  949.     }
  950.     VtUnLock
  951. }
  952. proc UserSelectPBCB { callbackName cbs } {
  953.     global _UserSelPBCallback
  954.     set parent [keylget cbs "dialog"]
  955.     set _UserSelPBCallback $callbackName
  956.     set userSelForm\
  957.         [VtFormDialog $parent.userSelForm\
  958.             -help\
  959.             -okCallback { _UserSelPBDone OK }\
  960.             -autoLock _UserSelPBDone\
  961.             -cancelCallback { _UserSelPBDone Cancel }\
  962.             -wmCloseCallback { _UserSelPBDone Cancel }\
  963.             -title [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USER_SELECT_TITLE]]
  964.     set userSelectList\
  965.         [VxList $userSelForm.userSelectList\
  966.             -rightSide FORM\
  967.             -bottomSide FORM\
  968.             -title [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USER_LIST_TITLE]\
  969.             -itemList [GetUsers]\
  970.             -MOTIF_selection EXTENDED\
  971.             -CHARM_selection MULTIPLE\
  972.             -rows 10\
  973.             -columns 20]
  974.     VxSetVar $userSelForm "userSelectList" $userSelectList
  975.     VtSetFocus $userSelectList
  976.     VtShowDialog $userSelForm
  977.     VtUnLock
  978. }
  979. set _UserSelCallback "<null>"
  980. proc _UserSelDone { what cbs } {
  981.     global _UserSelCallback
  982.     set parent [keylget cbs "dialog"]
  983.     if {$what == "OK"} {
  984.         set userSelectText [VxGetVar $parent "userSelectText"]
  985.         set users [alias_recipients_parse \
  986.             [VtGetValues $userSelectText -value] " "]
  987.     } else {
  988.         set users {}
  989.     }
  990.     VtDestroyDialog $parent
  991.     if {$_UserSelCallback != "<null>"} {
  992.         set routine [lvarpop _UserSelCallback]
  993.         eval $routine [list $users] $_UserSelCallback [list $cbs]
  994.     }
  995.     VtUnLock
  996. }
  997. proc _UserSelectInsCB { userList parent cbs } {
  998.     set userSelectText [VxGetVar $parent "userSelectText"]
  999.         set currentList [alias_recipients_parse \
  1000.         [VtGetValues $userSelectText -value] " "]
  1001.     if {$currentList == ""} {
  1002.         set newValue $userList
  1003.     } else {
  1004.         set newList [lrmdups [concat $currentList $userList]]
  1005.         set newValue [alias_list_to_string $newList]
  1006.     }
  1007.     VtSetValues $userSelectText \
  1008.         -value $newValue
  1009.     VtSetValues $userSelectText \
  1010.         -xmArgs [list XmNcursorPosition [clength $newValue]]
  1011.     VtSetFocus $userSelectText
  1012.     VtUnLock
  1013. }
  1014. proc UserSelectCB { callbackName cbs } {
  1015.     global _UserSelCallback
  1016.     set parent [keylget cbs "dialog"]
  1017.     set _UserSelCallback $callbackName
  1018.     set userSelDlg\
  1019.         [VtFormDialog $parent.userSelDlg\
  1020.             -help\
  1021.             -okCallback {_UserSelDone OK}\
  1022.             -autoLock _UserSelDone\
  1023.             -cancelCallback {_UserSelDone Cancel}\
  1024.             -wmCloseCallback {_UserSelDone Cancel}\
  1025.             -title [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USER_SELECT_TITLE]]
  1026.     set selForm\
  1027.         [VtForm $userSelDlg.selForm\
  1028.             -topSide FORM\
  1029.             -bottomSide NONE\
  1030.             -leftSide FORM\
  1031.             -rightSide FORM\
  1032.             -MOTIF_marginHeight 5 -marginWidth 0]
  1033.     set label\
  1034.         [VtLabel $selForm.label\
  1035.             -topSide FORM\
  1036.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USER_LIST_TITLE]\
  1037.             -labelLeft]
  1038.     set userSelectButton\
  1039.         [VtPushButton $selForm.userSelectPB\
  1040.             -topSide $label\
  1041.             -bottomSide FORM\
  1042.             -leftSide NONE\
  1043.             -rightSide FORM\
  1044.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USER_SELECT_PB]\
  1045.             -callback\
  1046.                 [list UserSelectPBCB [list _UserSelectInsCB $userSelDlg]]\
  1047.             -autoLock UserSelectPBCB]
  1048.     VxSetVar $userSelDlg "userSelectButton" $userSelectButton
  1049.     set userSelectText\
  1050.         [VxText $selForm.userSelectText\
  1051.             -topSide $label\
  1052.             -bottomSide FORM\
  1053.             -leftSide FORM\
  1054.             -rightSide $userSelectButton\
  1055.             -columns 30 \
  1056.             -callback {SaSetFocusUnlock next} \
  1057.             -autoLock SaSetFocusUnlock]
  1058.     VxSetVar $userSelDlg "userSelectText" $userSelectText
  1059.     set okButton [VtGetValues $userSelDlg -ok]
  1060.     SaSetFocusList $userSelDlg [list $userSelectText $okButton]
  1061.     VtShowDialog $userSelDlg
  1062.     VtSetFocus $userSelectText
  1063.     VtUnLock
  1064. }
  1065. proc aliasAddOK { isOK cbs } {
  1066.     global MA_ALIAS_FILEID
  1067.     global    curAlias
  1068.     set parent [keylget cbs "dialog"]
  1069.     set func [VxGetVar $parent "func"]
  1070.     if { $isOK } {
  1071.         aliasAddTypeCB $cbs 0        ;# In case the user forgot to press [Add]
  1072.         set newName [VxGetVar $parent "newName"]
  1073.         set newMembers [VxGetVar $parent "newMembers"]
  1074.         set name [VtGetValues $newName -value]
  1075.         set new [VtListGetItem $newMembers -all]
  1076.         if {$name == "" || $new == ""} {
  1077.             VtShow\
  1078.               [VtErrorDialog $parent.eb -ok -help\
  1079.                 -message [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_NONAMES]]
  1080.             VtUnLock
  1081.             return
  1082.         }
  1083.         if {[regexp {[:,     ]}  $name]} {
  1084.             NameErr $parent
  1085.             VtUnLock
  1086.             return
  1087.         }
  1088.         set aliasList [string tolower [Alias:List $MA_ALIAS_FILEID]]
  1089.         if { ( $func == "add" || \
  1090.                [string tolower $curAlias] != [string tolower $name] ) \
  1091.            && [lsearch $aliasList [string tolower $name]] != -1} {
  1092.             VtShow\
  1093.               [VtErrorDialog $parent.eb -ok -help\
  1094.                 -message [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_DUPLICATE]]
  1095.             VtUnLock
  1096.             return
  1097.         }
  1098.         if {$func == "add"} {
  1099.             Alias:Set $MA_ALIAS_FILEID $name $new
  1100.         } else {
  1101.             Alias:Unset $MA_ALIAS_FILEID $curAlias
  1102.             Alias:Set $MA_ALIAS_FILEID $name $new
  1103.         }
  1104.     }
  1105.     VtDestroyDialog $parent
  1106.     if { $isOK } {
  1107.         # Display new list
  1108.         aliasRedrawList $name
  1109.     }
  1110.     VtUnLock
  1111. }
  1112. proc aliasAddSelectCB { userList parent cbs } {
  1113.     set listWidget [VxGetVar $parent "newMembers"]
  1114.     set newList [lrmdups [concat [VtListGetItem $listWidget -all] $userList]]
  1115.     VtListSetItem $listWidget -itemList $newList
  1116.     VtListSelectItem $listWidget -itemList $userList
  1117.     SaListShowSelectedItem $listWidget
  1118.     aliasAddListCB $parent $cbs
  1119. }
  1120. proc aliasAddSelect { cbs } {
  1121.     set parent [keylget cbs "dialog"]
  1122.     UserSelectPBCB [list aliasAddSelectCB $parent] $cbs
  1123.     VtUnLock
  1124. }
  1125. proc aliasAddRem { cbs } {
  1126.     set parent [keylget cbs "dialog"]
  1127.     set newMembers [VxGetVar $parent "newMembers"]
  1128.     set posnList [VtListGetSelectedItem $newMembers -byPositionList]
  1129.     if {$posnList != 0} {
  1130.         set numAll [llength [VtListGetItem $newMembers -all]]
  1131.         VtListDeleteItem $newMembers -positionList $posnList
  1132.         set numLeft [llength [VtListGetItem $newMembers -all]]
  1133.         if {$numLeft > 0} {
  1134.             set first [lindex $posnList 0]
  1135.             set last [lindex $posnList end]
  1136.             set removed [llength $posnList]
  1137.             if {[expr $last - $first + 1] == $removed} {
  1138.                 set contiguous 1
  1139.             } else {
  1140.                 set contiguous 0
  1141.             }
  1142.             if {$last == $numAll && $contiguous} {
  1143.                 # select the one above
  1144.                 VtListSelectItem $newMembers -position [expr $first - 1]
  1145.             } else {
  1146.                 # select the item that was after the first
  1147.                 # deleted (same position number as first
  1148.                 # deleted was)
  1149.                 VtListSelectItem $newMembers -position $first
  1150.             }
  1151.             SaListShowSelectedItem $newMembers
  1152.         }
  1153.     }
  1154.     VtUnLock
  1155. }
  1156. proc aliasAddTypeCB { cbs {doUnlock 1} } {
  1157.     set parent [keylget cbs "dialog"]
  1158.     set textWidget [VxGetVar $parent "typeMembers"]
  1159.     set listWidget [VxGetVar $parent "newMembers"]
  1160.     set userList [alias_recipients_parse \
  1161.         [VtGetValues $textWidget -value] " "]
  1162.     if {![lempty $userList]} {
  1163.         set newList [lrmdups [concat [VtListGetItem $listWidget -all] $userList]]
  1164.         VtListSetItem $listWidget -itemList $newList
  1165.         positionList $listWidget [lindex [lsort $userList] 0]
  1166.         VtListSelectItem $listWidget -itemList $userList
  1167.         VtSetValues $textWidget -value {}
  1168.         aliasAddListCB $parent $cbs
  1169.     }
  1170.     if {$doUnlock} {
  1171.         VtUnLock
  1172.     }
  1173. }
  1174. proc aliasAddListCB { parent cbs } {
  1175.     VtUnLock
  1176. }
  1177. proc aliasAddEdit { cbs } {
  1178.     set parent [keylget cbs "dialog"]
  1179.     set typeMembers [VxGetVar $parent "typeMembers"]
  1180.     set listWidget [VxGetVar $parent "newMembers"]
  1181.     # Get the selected names
  1182.     set selList [VtListGetSelectedItem $listWidget -byItemList]
  1183.     if {![lempty $selList]} {
  1184.         set selString [alias_list_to_string $selList]
  1185.         # Put them into the text widget
  1186.         VtSetValues $typeMembers\
  1187.             -value $selString
  1188.         VtSetValues $typeMembers\
  1189.             -xmArgs [list \
  1190.                 XmNcursorPosition \
  1191.                 [string length $selString]]
  1192.         # Then remove them from the list
  1193.         aliasAddRem $cbs
  1194.     }
  1195.     VtUnLock
  1196. }
  1197. proc positionList { listWidget prefix {deSelect 0} } {
  1198.     set itemList [VtListGetItem $listWidget -all]
  1199.     set listCB [VxGetVar $listWidget "callback"]
  1200.     if {$prefix != ""} {
  1201.         # recipient names can have backslash, so need to
  1202.         # double them before the search
  1203.         regsub -all {\\} $prefix {\\\\} prefix
  1204.         set pos [lsearch -glob $itemList "${prefix}*"]
  1205.         if {$pos != -1} {
  1206.             set rows [VtGetValues $listWidget -rows]
  1207.             set mpos [expr $pos - ($rows / 2)]
  1208.             if {$mpos < 1} {
  1209.                 set mpos 1
  1210.             }
  1211.             VtSetValues $listWidget -topItemPosition $mpos
  1212.             if {$deSelect} {
  1213.                 VtListDeselectItem $listWidget -all
  1214.             }
  1215.             VtListSelectItem $listWidget -position [expr $pos + 1]
  1216.             if {$listCB != ""} {
  1217.                 $listCB 0 {}
  1218.             }
  1219.         }
  1220.     }
  1221. }
  1222. proc aliasJumpCB { listWidget cbs } {
  1223.     set prefix [keylget cbs "value"]
  1224.     positionList $listWidget $prefix 1
  1225.     VtUnLock
  1226. }
  1227. proc aliasAdd { func cbs } {
  1228.     global MA_ALIAS_FILEID
  1229.     global    isCharm curAlias
  1230.     set parent [keylget cbs "dialog"]
  1231.     if {$func == "add"} {
  1232.         set title  [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_ADD_TITLE]
  1233.     } else {
  1234.         set title [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MFY_TITLE $curAlias]
  1235.     }
  1236.     set aliasAddForm\
  1237.         [VtFormDialog $parent.aliasAddForm\
  1238.             -title "$title"\
  1239.             -help\
  1240.             -okCallback {aliasAddOK 1}\
  1241.             -autoLock aliasAddOK\
  1242.             -cancelCallback {aliasAddOK 0}\
  1243.             -wmCloseCallback {aliasAddOK 0}]
  1244.     SaCharmSetMaxFormDimensions $aliasAddForm 1
  1245.     VxSetVar $aliasAddForm "func" $func
  1246.     if {$func == "add"} {
  1247.         set value ""
  1248.     } else {
  1249.         set value $curAlias
  1250.     }
  1251.     set newName\
  1252.         [VxText $aliasAddForm.newName\
  1253.             -topSide FORM\
  1254.             -leftSide FORM\
  1255.             -rightSide FORM\
  1256.             -title [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_ADD_NAME]\
  1257.             -shortHelpCallback SaShortHelpCB\
  1258.             -shortHelpString\
  1259.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_ALIAS_ADD_NAME]\
  1260.             -activateCallback {SaSetFocusUnlock next}\
  1261.             -autoLock SaSetFocusUnlock\
  1262.             -value $value\
  1263.             -columns 30]
  1264.     VxSetVar $aliasAddForm "newName" $newName
  1265.     set newNameForm [VxGetVar $newName "form"]
  1266.     if {$isCharm} {
  1267.         VtLabel $aliasAddForm.blank1 -label " "
  1268.     }
  1269.     VtLabel $aliasAddForm.newLabel\
  1270.         -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_ADD_MEMBERS]
  1271.     set newForm [VtForm $aliasAddForm.newForm\
  1272.                     -leftSide FORM\
  1273.                     -rightSide FORM\
  1274.                     -borderWidth 1]
  1275.     set typeMembers\
  1276.         [VxText $newForm.typeMembers\
  1277.             -topSide FORM\
  1278.             -leftSide FORM\
  1279.             -rightSide FORM\
  1280.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_ADD_TYPE]\
  1281.             -shortHelpCallback SaShortHelpCB\
  1282.             -shortHelpString\
  1283.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_ALIAS_ADD_TYPE]\
  1284.             -activateCallback aliasAddTypeCB\
  1285.             -autoLock aliasAddTypeCB]
  1286.     set typeMembersForm [VxGetVar $typeMembers "form"]
  1287.     VxSetVar $aliasAddForm "typeMembers" $typeMembers
  1288.     VtSetValues $typeMembers -rightSide NONE
  1289.     set addPB\
  1290.         [VtPushButton $typeMembersForm.add\
  1291.             -topSide FORM\
  1292.             -bottomSide FORM\
  1293.             -rightSide FORM\
  1294.             -leftSide NONE\
  1295.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_ADD_PB]\
  1296.             -shortHelpCallback SaShortHelpCB\
  1297.             -shortHelpString\
  1298.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_ALIAS_ADD_PB]\
  1299.             -callback aliasAddTypeCB\
  1300.             -autoLock aliasAddTypeCB]
  1301.     VxSetVar $aliasAddForm "addPB" $addPB
  1302.     VtSetValues $typeMembers -rightSide $addPB
  1303.     if {$func == "add"} {
  1304.         set items {}
  1305.     } else {
  1306.         set items [lsort [Alias:Get $MA_ALIAS_FILEID $curAlias]]
  1307.     }
  1308.     VtLabel $newForm.newMembersLabel\
  1309.         -topSide $typeMembersForm\
  1310.         -leftSide FORM\
  1311.         -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_ADD_MEMBERS_TITLE]
  1312.     set listForm\
  1313.         [VtForm $newForm.newMembers\
  1314.             -leftSide FORM\
  1315.             -rightSide FORM\
  1316.             -bottomSide FORM\
  1317.             -marginWidth 0\
  1318.             -marginHeight 0]
  1319.     set listJumpForm\
  1320.         [VtForm $listForm.newMembers\
  1321.             -leftSide FORM\
  1322.             -rightSide FORM\
  1323.             -bottomSide FORM\
  1324.             -marginWidth 0\
  1325.             -marginHeight 0]
  1326.     set newMembers\
  1327.         [VtList $listJumpForm.newMembers\
  1328.             -topSide FORM\
  1329.             -bottomSide NONE\
  1330.             -leftSide FORM\
  1331.             -rightSide FORM\
  1332.             -shortHelpCallback SaShortHelpCB\
  1333.             -shortHelpString\
  1334.               [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_ALIAS_ADD_MEMBERS]\
  1335.             -callback [list aliasAddListCB $aliasAddForm]\
  1336.             -autoLock aliasAddListCB\
  1337.             -MOTIF_rows 4 -CHARM_rows 10\
  1338.             -columns 25\
  1339.             -scrollBar 1\
  1340.             -itemList $items\
  1341.             -MOTIF_selection EXTENDED\
  1342.             -CHARM_selection MULTIPLE]
  1343.     VxSetVar $aliasAddForm "newMembers" $newMembers
  1344.     VxSetVar $newMembers "callback" {}
  1345.     set jumpbox\
  1346.         [VxText $listJumpForm.jumpbox\
  1347.             -topSide NONE\
  1348.             -bottomSide FORM\
  1349.             -leftSide FORM\
  1350.             -rightSide FORM\
  1351.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_SEARCH]\
  1352.             -shortHelpCallback SaShortHelpCB\
  1353.             -shortHelpString\
  1354.               [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_SEARCH]\
  1355.             -valueChangedCallback [list aliasJumpCB $newMembers]\
  1356.             -autoLock aliasJumpCB]
  1357.     set jumpboxForm [VxGetVar $jumpbox "form"]
  1358.     VtSetValues $newMembers -bottomSide $jumpboxForm
  1359.     set pbForm [VtRowColumn $listForm.pbForm\
  1360.                 -topSide FORM\
  1361.                 -bottomSide FORM\
  1362.                 -rightSide FORM\
  1363.                 -leftSide NONE\
  1364.                 -vertical]
  1365.     VtSetValues $listJumpForm -rightSide $pbForm
  1366.     set selectPB\
  1367.         [VtPushButton $pbForm.select\
  1368.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_SELECT_PB]\
  1369.             -shortHelpCallback SaShortHelpCB\
  1370.             -shortHelpString\
  1371.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_ALIAS_SEL_PB]\
  1372.             -callback aliasAddSelect\
  1373.             -autoLock aliasAddSelect]
  1374.     VxSetVar $aliasAddForm "selectPB" $selectPB
  1375.     set removePB\
  1376.         [VtPushButton $pbForm.remove\
  1377.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_REMOVE_PB]\
  1378.             -shortHelpCallback SaShortHelpCB\
  1379.             -shortHelpString\
  1380.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_ALIAS_REM_PB]\
  1381.             -callback aliasAddRem\
  1382.             -autoLock aliasAddRem]
  1383.     VxSetVar $aliasAddForm "removePB" $removePB
  1384.     VtSetValues $removePB -leftOffset -[expr [VtGetValues $removePB -width] / 2]
  1385.     set editPB\
  1386.         [VtPushButton $pbForm.edit\
  1387.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_EDIT_PB]\
  1388.             -shortHelpCallback SaShortHelpCB\
  1389.             -shortHelpString\
  1390.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_ALIAS_EDIT_PB]\
  1391.             -callback aliasAddEdit\
  1392.             -autoLock aliasAddEdit]
  1393.     VxSetVar $aliasAddForm "editPB" $editPB
  1394.     VtSetValues $editPB -leftOffset -[expr [VtGetValues $editPB -width] / 2]
  1395.   # Now, pile things on the bottom of the form, in reverse order:
  1396.     set statusbar [SaStatusBar $aliasAddForm.StatusBar]
  1397.     set sep [VtSeparator $aliasAddForm._\
  1398.                 -rightSide FORM -rightOffset 0\
  1399.                 -leftSide FORM -leftOffset 0\
  1400.                 -bottomSide $statusbar -bottomOffset 0\
  1401.                 -topSide NONE]
  1402.     VtSetValues $newForm -bottomSide $sep
  1403.     VtShow $aliasAddForm
  1404.     SaSetFocusList $aliasAddForm [list $newName $typeMembers]
  1405.     SaSetTabGroups $aliasAddForm\
  1406.         [list $newName $typeMembers $addPB $newMembers $pbForm $jumpbox]
  1407.     VtSetFocus $newName
  1408.     VtUnLock
  1409. }
  1410. proc aliasRemoveCB { cbs } {
  1411.     global MA_ALIAS_FILEID
  1412.     global curAlias members aliasList
  1413.     Alias:Unset $MA_ALIAS_FILEID $curAlias
  1414.     # Update lists
  1415.     set selected [VtListGetSelectedItem $aliasList]
  1416.     VtListDeleteItem $aliasList -position $selected
  1417.     set numItems [llength [VtListGetItem $aliasList -all]]
  1418.     if {$numItems > 0} {
  1419.         if {$selected <= $numItems} {
  1420.             VtListSelectItem $aliasList \
  1421.                 -position $selected
  1422.             SaListShowSelectedItem $aliasList
  1423.         } else {
  1424.             VtListSelectItem $aliasList \
  1425.                 -position [expr $selected - 1]
  1426.         }
  1427.     }
  1428.         AliasCB 1 {} 0
  1429.     VtUnLock
  1430. }
  1431. proc aliasRemove { cbs } {
  1432.     global curAlias
  1433.     ConfirmRemoval [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_ALIAS]\
  1434.                     $curAlias aliasRemoveCB alias
  1435.     VtUnLock
  1436. }
  1437. proc memberAddOK { isOK cbs } {
  1438.     global MA_ALIAS_FILEID
  1439.     global curAlias members
  1440.     global memberList
  1441.     set parent [keylget cbs "dialog"]
  1442.     if { $isOK } {
  1443.         set newMembers [VxGetVar $parent "newMembers"]
  1444.         set new [alias_recipients_parse \
  1445.             [VtGetValues $newMembers -value] " "]
  1446.         if {$new == ""} {
  1447.             VtShow\
  1448.               [VtErrorDialog $parent.eb -ok -help\
  1449.                 -message [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_NOMEMBERS]]
  1450.             VtSetFocus $newMembers
  1451.             VtUnLock
  1452.             return
  1453.         }
  1454.         set alias $curAlias
  1455.         Alias:AddValue $MA_ALIAS_FILEID $alias $new
  1456.     }
  1457.     VtDestroyDialog $parent
  1458.     if { $isOK } {
  1459.         # Display new list
  1460.         set alias $curAlias
  1461.         set members [lsort [Alias:Get $MA_ALIAS_FILEID $alias]]
  1462.         VtListSetItem $memberList -itemList $members
  1463.         VtListSelectItem $memberList -itemList $new
  1464.         SaListShowSelectedItem $memberList
  1465.         MemberCB 1 {}
  1466.     }
  1467.     VtUnLock
  1468. }
  1469. proc memberAddSelectCB { userList parent cbs } {
  1470.     set textWidget [VxGetVar $parent "newMembers"]
  1471.     set oldList [alias_recipients_parse \
  1472.         [VtGetValues $textWidget -value] " "]
  1473.     set newList [lrmdups [concat $oldList $userList]]
  1474.     set newString [alias_list_to_string $newList]
  1475.     VtSetValues $textWidget \
  1476.         -value $newString
  1477.     VtSetValues $textWidget \
  1478.         -xmArgs [list XmNcursorPosition [clength $newString]]
  1479.     VtSetFocus $textWidget
  1480. }
  1481. proc memberAddSelect { cbs } {
  1482.     set parent [keylget cbs "dialog"]
  1483.     UserSelectPBCB [list memberAddSelectCB $parent] $cbs
  1484.     VtUnLock
  1485. }
  1486. proc memberAdd { cbs } {
  1487.     global curAlias
  1488.     set parent [keylget cbs "dialog"]
  1489.     set memberAddForm\
  1490.         [VtFormDialog $parent.memberAddForm\
  1491.             -title [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MEMBER_TITLE]\
  1492.             -help\
  1493.             -okCallback {memberAddOK 1}\
  1494.             -autoLock memberAddOK\
  1495.             -cancelCallback {memberAddOK 0}]
  1496.     set textLabel\
  1497.         [VtLabel $memberAddForm.textLabel\
  1498.             -label [IntlLocalizeMsg\
  1499.                 SCO_MAIL_ADMIN_ALIAS_MSG_MEMBER_ADD $curAlias]\
  1500.             -topSide FORM\
  1501.             -bottomSide NONE\
  1502.             -labelLeft]
  1503.     set selectForm\
  1504.         [VtForm $memberAddForm.selectForm\
  1505.             -topSide $textLabel\
  1506.             -leftSide FORM\
  1507.             -rightSide FORM\
  1508.             -bottomSide NONE\
  1509.             -marginHeight 0 -marginWidth 0]
  1510.     set selectPB\
  1511.         [VtPushButton $selectForm.selectPB\
  1512.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_SELECT_PB]\
  1513.             -topSide FORM -MOTIF_topOffset 0\
  1514.             -bottomSide FORM -MOTIF_bottomOffset 18\
  1515.             -leftSide NONE\
  1516.             -rightSide FORM\
  1517.             -callback memberAddSelect\
  1518.             -autoLock memberAddSelect]
  1519.     set newMembers\
  1520.         [VxText $selectForm.newMembers\
  1521.             -topSide FORM\
  1522.             -bottomSide FORM\
  1523.             -leftSide FORM\
  1524.             -rightSide $selectPB\
  1525.             -columns 50\
  1526.             -activateCallback {SaSetFocusUnlock next}\
  1527.             -autoLock SaSetFocusUnlock\
  1528.             -horizontalScrollBar 1]
  1529.     VxSetVar $memberAddForm "newMembers" $newMembers
  1530.     set label\
  1531.         [VtLabel $memberAddForm.label\
  1532.             -topSide $selectForm\
  1533.             -bottomSide NONE\
  1534.             -leftSide FORM\
  1535.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MEMBER_ADD_INST]]
  1536.     VtShow $memberAddForm
  1537.     SaSetFocusList $memberAddForm [list \
  1538.         $newMembers \
  1539.         [VtGetValues $memberAddForm -ok]]
  1540.     VtSetFocus $newMembers
  1541.     VtUnLock
  1542. }
  1543. proc memberRemoveCB { cbs } {
  1544.     global MA_ALIAS_FILEID
  1545.     global curAlias
  1546.     global memberList
  1547.     set alias $curAlias
  1548.     set selMembers [VtListGetSelectedItem $memberList -byItemList]
  1549.     set numAll [llength [VtListGetItem $memberList -all]]
  1550.     Alias:RemoveValue $MA_ALIAS_FILEID $alias $selMembers
  1551.     # Display new list
  1552.     set selPositions [VtListGetSelectedItem $memberList -byPositionList]
  1553.     VtListDeleteItem $memberList -positionList $selPositions
  1554.     set numLeft [llength [VtListGetItem $memberList -all]]
  1555.     if {$numLeft > 0} {
  1556.         set first [lindex $selPositions 0]
  1557.         set last [lindex $selPositions end]
  1558.         set deleted [llength $selPositions]
  1559.         if {[expr $last - $first + 1] == $deleted} {
  1560.             set contiguous 1
  1561.         } else {
  1562.             set contiguous 0
  1563.         }
  1564.         if {$last == $numAll && $contiguous} {
  1565.             # select the one above
  1566.             VtListSelectItem $memberList -position [expr $first - 1]
  1567.         } else {
  1568.             # select the item that was after the first deleted
  1569.             # (same position number as first deleted was)
  1570.             VtListSelectItem $memberList -position $first
  1571.         }
  1572.         SaListShowSelectedItem $memberList
  1573.     }
  1574.     MemberCB 1 {} 0
  1575.     VtUnLock
  1576. }
  1577. proc memberRemove { cbs } {
  1578.     global MA_ALIAS_FILEID
  1579.     global mainForm memberList
  1580.     global curAlias
  1581.     set alias $curAlias
  1582.     set size [llength [Alias:Get $MA_ALIAS_FILEID $alias]]
  1583.     if {$size <= 1} {
  1584.         # Only allow member deletion if more than one member left
  1585.         VtShow\
  1586.           [VtErrorDialog $mainForm.eb -ok -help\
  1587.             -message [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_LAST_MEMBER]]
  1588.         VtUnLock
  1589.         return
  1590.     }
  1591.     set selMembers [VtListGetSelectedItem $memberList -byItemList]
  1592.     ConfirmRemoval [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MEMBER]\
  1593.                     $selMembers memberRemoveCB member
  1594.     VtUnLock
  1595. }
  1596. proc userSubscribe { userName {aliasList {}} } {
  1597.     global MA_ALIAS_FILEID
  1598.     # Since userName could be a quoted string (as in pipe to a program)
  1599.     set addList [list $userName]
  1600.     if {[lempty $aliasList]} {
  1601.         set allAliases [Alias:List $MA_ALIAS_FILEID]
  1602.         foreach alias $allAliases {
  1603.             Alias:AddValue $MA_ALIAS_FILEID $alias $addList
  1604.         }
  1605.     } else {
  1606.         foreach alias $aliasList {
  1607.             Alias:AddValue $MA_ALIAS_FILEID $alias $addList
  1608.         }
  1609.     }
  1610. }
  1611. proc usersSubscribeCB { userList cbs } {
  1612.     global list_o_users
  1613.     set list_o_users $userList
  1614.     usersSubscribeScreen
  1615. }
  1616. proc usersSubscribeDone { isOK cbs } {
  1617.     global MA_ALIAS_FILEID
  1618.     global    curAlias mainForm list_o_users user
  1619.     set parent [keylget cbs "dialog"]
  1620.     if {$isOK} {
  1621.         set sysListBox [VxGetVar $parent "sysList"]
  1622.         set userListBox [VxGetVar $parent "userList"]
  1623.         # First, go through all aliases *not* on the user's list 
  1624.         # and remove her
  1625.         set sysList [VtListGetItem $sysListBox -all]
  1626.         if {![lempty $sysList]} {
  1627.             userRemove $user $sysList
  1628.         }
  1629.         # Then, loop through the selected list and put her on
  1630.         set userList [VtListGetItem $userListBox -all]
  1631.         if {![lempty $userList]} {
  1632.             userSubscribe $user $userList
  1633.         }
  1634.         # Cause the current member list to be redrawn, just in case
  1635.         AliasCB 0 {} 0
  1636.     }
  1637.     VtDestroyDialog $parent
  1638.     if {![lempty $list_o_users]} {
  1639.         usersSubscribeScreen
  1640.     }
  1641.     VtUnLock
  1642. }
  1643. proc usersSubAdd { cbs } {
  1644.     set parent [keylget cbs "dialog"]
  1645.     set sysListBox [VxGetVar $parent "sysList"]
  1646.     set userListBox [VxGetVar $parent "userList"]
  1647.     set addList [VtListGetSelectedItem $sysListBox -byItemList]
  1648.     set userList [VtListGetItem $userListBox -all]
  1649.     VtSetValues $userListBox -itemList [lsort [concat $addList $userList]]
  1650.     VtListDeleteItem $sysListBox -itemList $addList
  1651.     VtUnLock
  1652. }
  1653. proc usersSubRem { cbs } {
  1654.     set parent [keylget cbs "dialog"]
  1655.     set sysListBox [VxGetVar $parent "sysList"]
  1656.     set userListBox [VxGetVar $parent "userList"]
  1657.     set remList [VtListGetSelectedItem $userListBox -byItemList]
  1658.     set sysList [VtListGetItem $sysListBox -all]
  1659.     VtSetValues $sysListBox -itemList [lsort [concat $remList $sysList]]
  1660.     VtListDeleteItem $userListBox -itemList $remList
  1661.     VtUnLock
  1662. }
  1663. proc usersSubscribeScreen {} {
  1664.     global MA_ALIAS_FILEID MA_ALIAS_FILENAME
  1665.     global mainForm list_o_users user
  1666.     if {[lempty $list_o_users]} {
  1667.         return
  1668.     }
  1669.     VtLock
  1670.     set parent $mainForm
  1671.     set user [lvarpop list_o_users]
  1672.     set userString [list $user]
  1673.     set title [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USER_SUB_TITLE $userString]
  1674.     set subForm\
  1675.         [VtFormDialog $parent.subform\
  1676.             -title $title\
  1677.             -help\
  1678.             -okCallback {usersSubscribeDone 1}\
  1679.             -autoLock usersSubscribeDone\
  1680.             -cancelCallback {usersSubscribeDone 0}]
  1681.     set label\
  1682.       [VtLabel $subForm.inst\
  1683.         -font largeBoldFont\
  1684.         -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USER_SUB_INST $userString]]
  1685.     set label [VtSeparator -horizontal -rightSide FORM]
  1686.     set bForm\
  1687.         [VtRowColumn $subForm.bForm\
  1688.             -MOTIF_topOffset 50\
  1689.             -CHARM_topOffset 5\
  1690.             -leftSide 50\
  1691.             -vertical]
  1692.     set add\
  1693.         [VtPushButton $bForm.add\
  1694.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USER_SUB_ADD_PB]\
  1695.             -shortHelpCallback SaShortHelpCB\
  1696.             -shortHelpString\
  1697.               [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_USER_SUB_ADD_PB]\
  1698.             -callback usersSubAdd\
  1699.             -autoLock usersSubAdd]
  1700.     set remove\
  1701.         [VtPushButton $bForm.remove\
  1702.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USER_SUB_RMV_PB]\
  1703.             -shortHelpCallback SaShortHelpCB\
  1704.             -shortHelpString\
  1705.               [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_USER_SUB_RMV_PB]\
  1706.             -callback usersSubRem\
  1707.             -autoLock usersSubRem]
  1708.     set offset [expr [VtGetValues $add -width] / 2 + 10]    ;# 10 for border
  1709.     VtSetValues $bForm -leftOffset -$offset
  1710.     set sysList\
  1711.         [VxList $subForm.sysList\
  1712.             -topSide $label\
  1713.             -leftSide FORM\
  1714.             -rightSide $bForm\
  1715.             -title [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USER_SUB_SYSLIST]\
  1716.             -shortHelpCallback SaShortHelpCB\
  1717.             -shortHelpString\
  1718.               [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_USER_SUB_SYSLIST $MA_ALIAS_FILENAME]\
  1719.             -itemList [lsort [Alias:List $MA_ALIAS_FILEID]]\
  1720.             -MOTIF_selection EXTENDED\
  1721.             -CHARM_selection MULTIPLE\
  1722.             -rows 10]
  1723.     set sysListForm [VxGetVar $sysList "form"]
  1724.     VxSetVar $subForm "sysList" $sysList
  1725.     set title [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USER_SUB_ULIST $userString]
  1726.     set userList\
  1727.         [VxList $subForm.userList\
  1728.             -topSide $label\
  1729.             -leftSide $bForm\
  1730.             -rightSide FORM\
  1731.             -title $title\
  1732.             -shortHelpCallback SaShortHelpCB\
  1733.             -shortHelpString\
  1734.               [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_USER_SUB_ULIST]\
  1735.             -MOTIF_selection EXTENDED\
  1736.             -CHARM_selection MULTIPLE\
  1737.             -rows 10]
  1738.     set userListForm [VxGetVar $userList "form"]
  1739.     VxSetVar $subForm "userList" $userList
  1740.     set statusBar [SaStatusBar $subForm.StatusBar 0]
  1741.     VtSetValues $sysListForm -bottomSide $statusBar
  1742.     VtSetValues $userListForm -bottomSide $statusBar
  1743.     VtShow $subForm
  1744.     # Now find all aliases this user is a member of, and "ADD >>" them...
  1745.     set subList {}
  1746.     foreach alias [Alias:Memberships $MA_ALIAS_FILEID $user] {
  1747.         lappend subList $alias
  1748.     }
  1749.     if {![lempty $subList]} {
  1750.         # Select all items we found...
  1751.         VtListSelectItem $sysList -itemList $subList
  1752.         # NOW push the button, Max...
  1753.         keylset cbs "dialog" $subForm
  1754.         usersSubAdd $cbs
  1755.     }
  1756.     VtUnLock
  1757. }
  1758. proc userRemove { userName {aliasList {}} } {
  1759.     global MA_ALIAS_FILEID
  1760.     # Since userName could be a quoted string (as in pipe to a program)
  1761.     set removeList [list $userName]
  1762.     if {[llength $aliasList] == 0} {
  1763.         foreach alias [Alias:Memberships $MA_ALIAS_FILEID $userName] {
  1764.             Alias:RemoveValue $MA_ALIAS_FILEID $alias $removeList
  1765.         }
  1766.     } else {
  1767.         foreach alias $aliasList {
  1768.             Alias:RemoveValue $MA_ALIAS_FILEID $alias $removeList
  1769.         }
  1770.     }
  1771. }
  1772. proc usersRetireDone { isOK cbs } {
  1773.     global MA_ALIAS_FILEID
  1774.     global mainForm list_o_users user
  1775.     set parent [keylget cbs "dialog"]
  1776.     if {$isOK} {
  1777.         set redir [VxGetVar $parent "redir"]
  1778.         set doRedirection [VtGetValues $redir -value]
  1779.         set redirAlias [VxGetVar $parent "redirAlias"]
  1780.         set addrList [alias_recipients_parse \
  1781.             [VtGetValues $redirAlias -value] " "]
  1782.         # Check the redirection name(s)
  1783.         if {$doRedirection && [lempty $addrList]} {
  1784.             VtShow\
  1785.               [VtErrorDialog $parent.eb -ok\
  1786.                 -message [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_NO_REDIR]]
  1787.             VtUnLock
  1788.             VtSetFocus $redirAlias
  1789.             return
  1790.         }
  1791.         # Remove the user from all aliases and lists...
  1792.         userRemove $user
  1793.         # Redirect the user's mail, as if requested...
  1794.         if {$doRedirection} {
  1795.             Alias:Set $MA_ALIAS_FILEID $user $addrList
  1796.         }
  1797.         # Cause all lists to be redrawn, just in case they changed
  1798.         aliasRedrawList $user
  1799.     }
  1800.     VtDestroyDialog $parent
  1801.     if {![lempty $list_o_users]} {
  1802.         usersRetireScreen
  1803.     }
  1804.     VtUnLock
  1805. }
  1806. proc usersRetireCB { userList cbs } {
  1807.     global list_o_users
  1808.     set list_o_users $userList
  1809.     usersRetireScreen
  1810. }
  1811. proc usersRetCheckCB { cbs } {
  1812.     set parent [keylget cbs "dialog"]
  1813.     set value [keylget cbs "value"]
  1814.     set redir [VxGetVar $parent "redir"]
  1815.     set redirAlias [VxGetVar $parent "redirAlias"]
  1816.     if {$value == $redir } {
  1817.         VtSet $redirAlias -sensitive 1
  1818.         VtSetFocus $redirAlias
  1819.     } else {
  1820.         VtSet $redirAlias -sensitive 0
  1821.     }
  1822.     VtUnLock
  1823. }
  1824. proc usersRetireScreen {} {
  1825.     global mainForm list_o_users user tailorLoaded MA_ALIAS_FILENAME
  1826.     if {[lempty $list_o_users]} {
  1827.         return
  1828.     }
  1829.     VtLock
  1830.     set parent $mainForm
  1831.     set user [lvarpop list_o_users]
  1832.     set focusList {}
  1833.     # $user may be a quoted string (as in a pipe to program)
  1834.     # so want to make a list of $user before IntlLocalizeMsg
  1835.     set title [IntlLocalizeMsg \
  1836.         SCO_MAIL_ADMIN_ALIAS_MSG_USER_RET_TITLE [list $user]]
  1837.     set retireForm\
  1838.         [VtFormDialog $parent.retireForm\
  1839.             -title $title\
  1840.             -help\
  1841.             -okCallback {usersRetireDone 1}\
  1842.             -autoLock usersRetireDone\
  1843.             -cancelCallback {usersRetireDone 0}]
  1844.     set label\
  1845.       [VtLabel $retireForm.label\
  1846.         -rightSide FORM\
  1847.         -font medBoldFont\
  1848.         -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USER_RET_INST\
  1849.                 [list $user $MA_ALIAS_FILENAME]]]
  1850.     set sep [VtSeparator -horizontal -topSide $label -rightSide FORM]
  1851.     set cbox\
  1852.         [VtCheckBox $retireForm.cbox\
  1853.             -topSide $sep\
  1854.             -leftSide FORM\
  1855.             -callback usersRetCheckCB\
  1856.             -autoLock usersRetCheckCB]
  1857.     lappend focusList $cbox
  1858.     set redir\
  1859.                 [VtToggleButton $cbox.redir\
  1860.                         -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USER_RET_REDIR [list $user]]]
  1861.     VxSetVar $retireForm "redir" $redir
  1862.     set redirAlias\
  1863.         [VtText $retireForm.redirAlias\
  1864.             -rightSide FORM\
  1865.             -bottomSide FORM\
  1866.             -callback {SaSetFocus next}]
  1867.     VxSetVar $retireForm "redirAlias" $redirAlias
  1868.     VtSetSensitive $redirAlias 0
  1869.     lappend focusList $redirAlias
  1870.     set okButton [VtGetValues $retireForm -ok]
  1871.     lappend focusList $okButton
  1872.     if {[regexp {[:,     ]} $user] || [cequal [cindex $user 0] "\\"]} {
  1873.         VtSetSensitive $redir 0
  1874.     }
  1875.     VtShow $retireForm
  1876.     SaSetFocusList $retireForm $focusList
  1877.     SaSetTabGroups $retireForm $focusList
  1878.     VtSetFocus $redir
  1879.     VtUnLock
  1880. }
  1881. proc MemberCB { clearSearch cbs {doUnlock 1}} {
  1882.     global memberList meRmv membSearch
  1883.     set curMember [lindex [VtListGetSelectedItem $memberList -byItemList] 0]
  1884.     if { $curMember == "" } {
  1885.         VtSetSensitive $meRmv 0
  1886.     } else {
  1887.         VtSetSensitive $meRmv 1
  1888.     }
  1889.     if {$clearSearch} {
  1890.         VtSetValues $membSearch -value ""
  1891.     }
  1892.     if {$doUnlock} {
  1893.         VtUnLock
  1894.     }
  1895. }
  1896. proc AliasCB { clearSearch cbs {doUnlock 1}} {
  1897.     global MA_ALIAS_FILEID
  1898.     global curAlias members
  1899.     global aliasList memberList alMfy alRmv meAdd meRmv usSub usRet aliasSearch
  1900.     if {[lempty [VtListGetItem $aliasList -all]]} {
  1901.         set curAlias ""
  1902.     } else {
  1903.         set selItem [lindex [VtListGetSelectedItem $aliasList -byItemList] 0]
  1904.         set curAlias [string trim [lindex $selItem 0]]
  1905.     }
  1906.     if {$curAlias == ""} {
  1907.         set members {}
  1908.         VtSetSensitive $alRmv 0
  1909.         VtSetSensitive $alMfy 0
  1910.         VtSetSensitive $meAdd 0
  1911.         VtSetSensitive $usSub 0
  1912.         VtSetSensitive $usRet 0
  1913.     } else {
  1914.         set members [lsort [Alias:Get $MA_ALIAS_FILEID $curAlias]]
  1915.         VtSetSensitive $alMfy 1
  1916.         VtSetSensitive $alRmv 1
  1917.         VtSetSensitive $meAdd 1
  1918.         VtSetSensitive $usSub 1
  1919.         VtSetSensitive $usRet 1
  1920.     }
  1921.     VtSetSensitive $meRmv 0
  1922.     VtListSetItem $memberList -itemList $members
  1923.     if {![lempty $members]} {
  1924.         VtListSelectItem $memberList -position 1
  1925.         MemberCB 1 {} 0
  1926.     }
  1927.     if {$clearSearch} {
  1928.         VtSetValues $aliasSearch -value ""
  1929.     }
  1930.     if {$doUnlock} {
  1931.         VtUnLock
  1932.     }
  1933. }
  1934. proc aliasRedrawList { itemToSelect } {
  1935.     global MA_ALIAS_FILEID
  1936.     global aliasList
  1937.     global Bypass Public ALIAS LIST
  1938.     set aliasLines {}
  1939.     set aliases [lsort [Alias:List $MA_ALIAS_FILEID]]
  1940.     set aliasLines $aliases
  1941.     VtSetValues $aliasList -itemList $aliasLines
  1942.     if {![lempty $aliases]} {
  1943.         if {$itemToSelect == ""} {
  1944.             VtListSelectItem $aliasList -position 1
  1945.         } else {
  1946.             set pos [expr {[lsearch $aliases $itemToSelect] + 1}]
  1947.             if {$pos == 0} {
  1948.                 set pos 1
  1949.             }
  1950.             VtListSelectItem $aliasList -position $pos
  1951.             # Now position the item to the middle (or as close as we can)
  1952.             set offset [expr [VtGetValues $aliasList -rows] / 2]
  1953.             incr pos -$offset
  1954.             if {$pos < 1} {
  1955.                 set pos 1
  1956.             }
  1957.             VtSetValues $aliasList -topItemPosition $pos
  1958.         }
  1959.     }
  1960.     AliasCB 1 {} 0
  1961. }
  1962. proc mainErrorCB { cbs } {
  1963.     VtUnLock
  1964.     VtClose
  1965.     exit 1
  1966. }
  1967. proc alias_load {} {
  1968.     global MA_ALIAS_FILENAME MA_ALIAS_FILEID 
  1969.     global mainForm MyStatusCurID errorInfo
  1970.     set cmd "Alias:Open $MA_ALIAS_FILENAME"
  1971.     if {[ErrorCatch errStack 0 $cmd result] != 0} {
  1972.         if {"$mainForm" == ""} {
  1973.             puts stderr [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_CANT_LOAD $MA_ALIAS_FILENAME]
  1974.             puts stderr $result
  1975.             exit 1
  1976.         } else {
  1977.             SaDisplayErrorInfo $mainForm.ErrorLoad [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_CANT_LOAD $MA_ALIAS_FILENAME] noHelp quitCB
  1978.                 }
  1979.     } else {
  1980.         set MA_ALIAS_FILEID $result
  1981.     }
  1982. }
  1983. proc alias_list_to_string {memberList} {
  1984.     set memberString ""
  1985.     if {![lempty $memberList]} {
  1986.         set memberString [lvarpop memberList]
  1987.         foreach member $memberList {
  1988.             append memberString " $member"
  1989.         }
  1990.     }
  1991.     return $memberString
  1992. }
  1993. proc alias_recipients_parse {recipients {separator {}}} {
  1994.     set result {}
  1995.     if {$separator == ""} {
  1996.         set separator ","
  1997.     }
  1998.     # need to trim separators on the ends, otherwise
  1999.     # null list items will be created
  2000.     set recipients [string trim $recipients $separator]
  2001.     while {[clength $recipients] > 0} {
  2002.         set thisToken [ctoken recipients $separator]
  2003.         # Spaces are allowed between the ":include:" and filename,
  2004.         # which we must anticipate if the separator is also a space.
  2005.         if {[regexp {^:include:$} $thisToken] && \
  2006.             $separator == " "} {
  2007.             set filepath [ctoken recipients $separator]
  2008.             append thisToken $filepath
  2009.         }
  2010.         # If there is an un-matched quote, then we need to grab
  2011.         # text through the next quote.
  2012.         set numQuotes [expr [llength [split $thisToken "\""]] - 1]
  2013.         if {[fmod $numQuotes 2] == 1.0} {
  2014.             set restOfQuotedPart [ctoken recipients "\""]
  2015.             append thisToken $restOfQuotedPart
  2016.             append thisToken [ctoken recipients $separator]
  2017.         }
  2018.         lappend result [string trim $thisToken]
  2019.     }
  2020.     return $result
  2021. }
  2022. proc alias_sub_ret_parse {argument} {
  2023.     set user {}
  2024.     set aliases {}
  2025.     if {[regexp {^(:include:.*):(.*)$} $argument match \
  2026.         recipientName aliasNames]} {
  2027.         set user $recipientName 
  2028.         set aliases [translit "," " " $aliasNames]
  2029.     } else {
  2030.         set thisToken [ctoken argument ":"]
  2031.         if {[regexp {^[     ]+$} $thisToken]} {
  2032.             set thisToken ""
  2033.         }
  2034.         set numQuotes [expr [llength [split $thisToken "\""]] - 1]
  2035.         if {[fmod $numQuotes 2] == 1.0} {
  2036.             set restOfQuotedPart [ctoken argument "\""]
  2037.             append thisToken "${restOfQuotedPart}"
  2038.             append thisToken [ctoken argument ":"]
  2039.         }
  2040.         set user $thisToken
  2041.         set aliases [translit "," " " [crange $argument 1 len]]
  2042.     }
  2043.     return [list $user $aliases]
  2044. }
  2045. ErrorTopLevelCatch {
  2046.     global MA_ALIAS_FILENAME MA_ALIAS_CLASS MA_ALIAS_FILEID
  2047.     global MA_ALIAS_SENDMAILCF MA_ALIAS_NEWALIASES MA_ALIAS_MANAGED_HOST
  2048.     global argc optarg optind
  2049.     set ADD 0
  2050.     set DELETE 0
  2051.     set RETIRE 0
  2052.     set SUBSCRIBE 0
  2053.     set add_aliases {}
  2054.     set delete_aliases {}
  2055.     set retire_users {}
  2056.     set subscribe_users {}
  2057.     set mainForm ""
  2058.     # scan for commandline flags
  2059.     set argc [llength $argv]
  2060.     if {$argc == 0} {
  2061.         puts stderr [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_USAGE]
  2062.         exit 1
  2063.     }
  2064.     while {[set opt [getopt $argc $argv "a:d:f:h:R:r:S:s:"]] != -1} {
  2065.         switch $opt {
  2066.         f {
  2067.             set beforeColon [ctoken optarg ":"]
  2068.             if {$optarg == ""} {
  2069.                 set MA_ALIAS_FILENAME [string trim $beforeColon]
  2070.                 set MA_ALIAS_CLASS NONE
  2071.             } else {
  2072.                 set MA_ALIAS_FILENAME \
  2073.                     [string trim [ctoken optarg ":"]]
  2074.                 set MA_ALIAS_CLASS [string trim $beforeColon]
  2075.             }
  2076.         }
  2077.         h {
  2078.             set MA_ALIAS_MANAGED_HOST $optarg
  2079.         }
  2080.         a {
  2081.             set aliasName [ctoken optarg ":"]
  2082.             set aliasRecipients \
  2083.                 [alias_recipients_parse [crange $optarg 1 len]]
  2084.             if {[lempty $aliasRecipients]} {
  2085.                 puts stderr [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_MISSING_ADD_ARG]
  2086.                 puts stderr [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_USAGE]
  2087.                 exit 1
  2088.             }
  2089.             lappend add_aliases [list $aliasName $aliasRecipients]
  2090.             set ADD 1
  2091.         }
  2092.         d {
  2093.             set delete_aliases [union $delete_aliases \
  2094.                         [translit "," " " $optarg]]
  2095.             set DELETE 1
  2096.         }
  2097.         s {
  2098.             set retVal [alias_sub_ret_parse $optarg]
  2099.             if {[clength [lindex $retVal 0]] == 0 || \
  2100.                 [lempty [lindex $retVal 1]]} {
  2101.                 puts stderr [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_USAGE]
  2102.                 exit 1
  2103.             }
  2104.             lappend subscribe_users $retVal
  2105.             set SUBSCRIBE 1
  2106.         }
  2107.         S {
  2108.             set userList [alias_recipients_parse $optarg]
  2109.             foreach user $userList {
  2110.                 lappend subscribe_users [list $user {}]
  2111.             }
  2112.             set SUBSCRIBE 1
  2113.         }
  2114.         r {
  2115.             set retVal [alias_sub_ret_parse $optarg]
  2116.             if {[clength [lindex $retVal 0]] == 0 || \
  2117.                 [lempty [lindex $retVal 1]]} {
  2118.                 puts stderr [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_USAGE]
  2119.                 exit 1
  2120.             }
  2121.             lappend retire_users $retVal
  2122.             set RETIRE 1
  2123.         }
  2124.         R {
  2125.             set userList [alias_recipients_parse $optarg]
  2126.             foreach user $userList {
  2127.                 lappend retire_users [list $user {}]
  2128.             }
  2129.             set RETIRE 1
  2130.         }
  2131.         ? {
  2132.             puts stderr [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_USAGE]
  2133.             exit 1
  2134.         }
  2135.         }
  2136.     }
  2137.     # process commandline arguments
  2138.     set optCount [expr "$argc - $optind"]
  2139.     if {$optCount > 0} {
  2140.         puts stderr [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_USAGE]
  2141.         exit 1
  2142.     }
  2143.     if {"$MA_ALIAS_FILENAME" == ""} {
  2144.         puts stderr [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_USAGE]
  2145.         exit 1
  2146.     }
  2147.     if {$ADD || $DELETE || $RETIRE || $SUBSCRIBE} {
  2148.         if {[file isdirectory $MA_ALIAS_FILENAME]} {
  2149.             puts stderr [IntlLocalizeMsg \
  2150.                 SCO_MAIL_ADMIN_ALIAS_ERR_DIRECTORY $MA_ALIAS_FILENAME]
  2151.             puts stderr [IntlLocalizeMsg \
  2152.                 SCO_MAIL_ADMIN_ALIAS_ERR_USAGE]
  2153.             exit 1
  2154.         }
  2155.         if {[lsearch -exact $MA_ALIAS_DATABASE_CLASSES \
  2156.             $MA_ALIAS_CLASS] == -1} {
  2157.             puts stderr [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_UNKNOWN_CLASS $MA_ALIAS_CLASS]
  2158.             puts stderr [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_USAGE]
  2159.             exit 1
  2160.         }
  2161.         alias_load
  2162.         foreach newAlias $add_aliases {
  2163.             set aliasName [lindex $newAlias 0]
  2164.             set aliasRecipients [lindex $newAlias 1]
  2165.             Alias:Set $MA_ALIAS_FILEID $aliasName $aliasRecipients
  2166.         }
  2167.         foreach delAlias $delete_aliases {
  2168.             Alias:Unset $MA_ALIAS_FILEID $delAlias
  2169.         }
  2170.         foreach subscriber $subscribe_users {
  2171.             set userName [lindex $subscriber 0]
  2172.             set aliasNames [lindex $subscriber 1]
  2173.             userSubscribe $userName $aliasNames
  2174.         }
  2175.         foreach retiree $retire_users {
  2176.             set userName [lindex $retiree 0]
  2177.             set aliasNames [lindex $retiree 1]
  2178.             userRemove $userName $aliasNames
  2179.         }
  2180.         if {[Alias:Modified $MA_ALIAS_FILEID]} {
  2181.             if {[ErrorCatch errStack 0 \
  2182.                 {Alias:Close $MA_ALIAS_FILEID} errmsg] != 0} {
  2183.                 puts stderr [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_CANT_SAVE $MA_ALIAS_FILENAME]
  2184.                 puts stderr $errmsg
  2185.                 exit 1
  2186.                 }
  2187.             if {[cindex $MA_ALIAS_FILENAME 0] != "/"} {
  2188.                 set MA_ALIAS_FILENAME "[pwd]/${MA_ALIAS_FILENAME}"
  2189.             }
  2190.             if {$MA_ALIAS_CLASS == "NONE"} {
  2191.                 set cmd  "exec $MA_ALIAS_NEWALIASES -oA${MA_ALIAS_FILENAME} -C${MA_ALIAS_SENDMAILCF} >& /dev/null"
  2192.             } else {
  2193.                 set cmd "exec $MA_ALIAS_NEWALIASES -oA${MA_ALIAS_CLASS}:${MA_ALIAS_FILENAME} -C${MA_ALIAS_SENDMAILCF} >& /dev/null"
  2194.             }
  2195.             if {[catch $cmd errmsg] != 0} {
  2196.                 puts stderr [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_NEWALIASES "${MA_ALIAS_FILENAME}.db"]
  2197.                 puts stderr $errmsg
  2198.                 exit 1
  2199.             }
  2200.         }
  2201.         exit 0
  2202.     }
  2203.     set app [VtOpen aliases [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELPBOOK]]
  2204.     VtSetAppValues $app\
  2205.         -errorCallback {SaUnexpectedErrorCB mainErrorCB}
  2206.     set isCharm [VtInfo -charm]
  2207.     set mainForm\
  2208.         [VtFormDialog $app.form1\
  2209.             -marginWidth 0\
  2210.             -title [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_TITLE $MA_ALIAS_FILENAME]\
  2211.             -wmCloseCallback CloseCB\
  2212.             -wmShadowThickness 0\
  2213.             -autoLock {CloseCB aliasError}]
  2214.     SaCharmSetMaxFormDimensions $mainForm
  2215.     #-----
  2216.     set menubar\
  2217.         [VtMenuBar $mainForm.menubar\
  2218.             -helpMenuItemList [list \
  2219.             ON_CONTEXT \
  2220.             ON_WINDOW \
  2221.             ON_KEYS \
  2222.             INDEX \
  2223.             ON_HELP]]
  2224.     set aliasesMenu\
  2225.         [VtPulldown $menubar.aliases\
  2226.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MENU_LABEL]\
  2227.             -mnemonic [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MENU_MNEM]\
  2228.             -shortHelpCallback SaShortHelpCB\
  2229.             -shortHelpString\
  2230.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_MENU_ALIASES]]
  2231.       set alAdd\
  2232.          [VtPushButton $aliasesMenu.alAdd\
  2233.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MENU_ADD_LABEL]\
  2234.             -mnemonic [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MENU_ADD_MNEM]\
  2235.             -callback {aliasAdd add}\
  2236.             -autoLock aliasAdd\
  2237.             -shortHelpCallback SaShortHelpCB\
  2238.             -shortHelpString\
  2239.                [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_MENU_ALIASES_ADD]]
  2240.       set alRmv\
  2241.         [VtPushButton $aliasesMenu.alRmv\
  2242.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MENU_REMOVE_LABEL]\
  2243.             -mnemonic [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MENU_REMOVE_MNEM]\
  2244.             -shortHelpCallback SaShortHelpCB\
  2245.             -shortHelpString\
  2246.                [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_MENU_ALIASES_RMV]\
  2247.             -callback aliasRemove\
  2248.             -autoLock aliasRemove]
  2249.        VtSetSensitive alRmv 0
  2250.       set alMfy\
  2251.         [VtPushButton $aliasesMenu.alMfy\
  2252.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MENU_MODIFY_LABEL]\
  2253.             -mnemonic [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MENU_MODIFY_MNEM]\
  2254.             -shortHelpCallback SaShortHelpCB\
  2255.             -shortHelpString\
  2256.               [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_MENU_ALIASES_MFY]\
  2257.             -callback {aliasAdd modify}\
  2258.             -autoLock aliasAdd]
  2259.        VtSetSensitive alMfy 0
  2260.       VtSeparator $aliasesMenu._1
  2261.       set alSave\
  2262.         [VtPushButton $aliasesMenu.save\
  2263.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MENU_SAVE_LABEL]\
  2264.             -mnemonic [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MENU_SAVE_MNEM]\
  2265.             -shortHelpCallback SaShortHelpCB\
  2266.             -shortHelpString\
  2267.               [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_MENU_ALIASES_SAVE]\
  2268.             -callback SaveCB\
  2269.             -autoLock SaveCB]
  2270.       VtSeparator $aliasesMenu._2
  2271.      set alQuit\
  2272.         [VtPushButton $aliasesMenu.quit\
  2273.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MENU_EXIT_LABEL]\
  2274.             -mnemonic [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MENU_EXIT_MNEM]\
  2275.             -shortHelpCallback SaShortHelpCB\
  2276.             -shortHelpString\
  2277.               [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_MENU_ALIASES_QUIT]\
  2278.             -callback CloseCB\
  2279.             -autoLock CloseCB]
  2280.     set membersMenu\
  2281.         [VtPulldown $menubar.members\
  2282.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MEMB_MENU_LABEL]\
  2283.             -mnemonic [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MEMB_MENU_MNEM]\
  2284.             -shortHelpCallback SaShortHelpCB\
  2285.             -shortHelpString\
  2286.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_MENU_MEMBERS]]
  2287.       set meAdd\
  2288.         [VtPushButton $membersMenu.meAdd\
  2289.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MEMB_MENU_ADD]\
  2290.             -mnemonic [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MEMB_MENU_ADD_MNEM]\
  2291.             -shortHelpCallback SaShortHelpCB\
  2292.             -shortHelpString\
  2293.               [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_MENU_MEMBERS_ADD]\
  2294.             -callback memberAdd\
  2295.             -autoLock memberAdd]
  2296.       VtSetSensitive $meAdd 0
  2297.       set meRmv\
  2298.         [VtPushButton $membersMenu.meRmv\
  2299.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MEMB_MENU_REMOVE]\
  2300.             -mnemonic [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MEMB_MENU_REMOVE_MNEM]\
  2301.             -shortHelpCallback SaShortHelpCB\
  2302.             -shortHelpString\
  2303.               [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_MENU_MEMBERS_RMV]\
  2304.             -callback memberRemove\
  2305.             -autoLock memberRemove]
  2306.       VtSetSensitive $meRmv 0
  2307.     set usersMenu\
  2308.         [VtPulldown $menubar.users\
  2309.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USERS_MENU_LABEL]\
  2310.             -mnemonic [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USERS_MENU_MNEM]\
  2311.             -shortHelpCallback SaShortHelpCB\
  2312.             -shortHelpString\
  2313.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_MENU_USERS]]
  2314.       set usSub\
  2315.         [VtPushButton $usersMenu.usSub\
  2316.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USERS_MENU_SUB]\
  2317.             -mnemonic [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USERS_MENU_SUB_MNEM]\
  2318.             -shortHelpCallback SaShortHelpCB\
  2319.             -shortHelpString\
  2320.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_MENU_USERS_SUB]\
  2321.             -callback {UserSelectCB usersSubscribeCB}\
  2322.             -autoLock UserSelectCB]
  2323.       VtSetSensitive $usSub 0
  2324.       set usRet\
  2325.         [VtPushButton $usersMenu.usRet\
  2326.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USERS_MENU_RET]\
  2327.             -mnemonic [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_USERS_MENU_RET_MNEM]\
  2328.             -shortHelpCallback SaShortHelpCB\
  2329.             -shortHelpString\
  2330.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_MENU_USERS_RET]\
  2331.             -callback {UserSelectCB usersRetireCB}\
  2332.             -autoLock UserSelectCB]
  2333.       VtSetSensitive $usRet 0
  2334.     #-----
  2335.     VtLabel $mainForm.aliasLabel\
  2336.         -MOTIF_leftOffset 10\
  2337.         -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_LIST_TITLE]
  2338.     set aliasListForm\
  2339.         [VtForm $mainForm.aliasForm\
  2340.             -topOffset 0\
  2341.             -MOTIF_leftOffset 10\
  2342.             -leftSide FORM\
  2343.             -borderWidth 1]
  2344.     set aliasList\
  2345.         [VtList $aliasListForm.aliasList\
  2346.             -rightSide FORM\
  2347.             -shortHelpCallback SaShortHelpCB\
  2348.             -shortHelpString [IntlLocalizeMsg \
  2349.                 SCO_MAIL_ADMIN_ALIAS_MSG_HELP_ALIASES_LIST \
  2350.                 $MA_ALIAS_FILENAME]\
  2351.             -rows 10\
  2352.             -scrollBar 1\
  2353.             -callback {AliasCB 1}\
  2354.             -autoLock AliasCB\
  2355.             -defaultCallback {aliasAdd modify}\
  2356.             -autoLock aliasAdd]
  2357.     VxSetVar $aliasList "callback" "AliasCB"
  2358.     set aliasSearch\
  2359.         [VxText $aliasListForm.aliasSearch\
  2360.             -topSide NONE\
  2361.             -leftSide FORM\
  2362.             -rightSide FORM\
  2363.             -bottomSide FORM\
  2364.             -shortHelpCallback SaShortHelpCB\
  2365.             -shortHelpString\
  2366.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_SEARCH]\
  2367.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_SEARCH]\
  2368.             -valueChangedCallback [list aliasJumpCB $aliasList]\
  2369.             -autoLock aliasJumpCB]
  2370.     set aliasSearchForm [VxGetVar $aliasSearch "form"]
  2371.     VtSetValues $aliasList -bottomSide $aliasSearchForm
  2372.     set members {}
  2373.     set memberListForm\
  2374.         [VtForm $mainForm.memberListForm\
  2375.             -topSide $menubar\
  2376.             -leftSide $aliasListForm\
  2377.             -MOTIF_leftOffset 15\
  2378.             -rightSide FORM\
  2379.             -MOTIF_rightOffset 10\
  2380.             -marginWidth 0\
  2381.             -marginHeight 0]
  2382.     VtLabel $memberListForm.memberLabel\
  2383.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_MEMBERS_TITLE]
  2384.     set memberListInnerForm\
  2385.         [VtForm $memberListForm.memberInnerForm\
  2386.             -topOffset 0\
  2387.             -borderWidth 1\
  2388.             -rightSide FORM\
  2389.             -bottomSide FORM]
  2390.     set memberList\
  2391.         [VtList $memberListInnerForm.memberList\
  2392.             -rightSide FORM\
  2393.             -shortHelpCallback SaShortHelpCB\
  2394.             -shortHelpString\
  2395.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_MEMBERS_LIST]\
  2396.             -itemList $members\
  2397.             -MOTIF_selection EXTENDED\
  2398.             -CHARM_selection MULTIPLE\
  2399.             -rows 10\
  2400.             -scrollBar 1\
  2401.             -MOTIF_columns 25\
  2402.             -CHARM_columns 20\
  2403.             -callback {MemberCB 1}\
  2404.             -autoLock MemberCB\
  2405.             -defaultCallback {aliasAdd modify}]
  2406.     VxSetVar $memberList "callback" "MemberCB"
  2407.     set membSearch\
  2408.          [VxText $memberListInnerForm.membSearch\
  2409.             -topSide NONE\
  2410.             -leftSide FORM\
  2411.             -rightSide FORM\
  2412.             -bottomSide FORM\
  2413.             -shortHelpCallback SaShortHelpCB\
  2414.             -shortHelpString\
  2415.                 [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_HELP_SEARCH]\
  2416.             -label [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_SEARCH]\
  2417.             -columns 5\
  2418.             -valueChangedCallback [list aliasJumpCB $memberList]\
  2419.             -autoLock aliasJumpCB]
  2420.     set membSearchForm [VxGetVar $membSearch "form"]
  2421.     VtSetValues $memberList -bottomSide $membSearchForm
  2422.     set statusBar [SaStatusBar $mainForm.StatusBar 1]
  2423.     VtSetValues $aliasListForm \
  2424.         -bottomSide $statusBar \
  2425.         -MOTIF_bottomOffset 10
  2426.     VtSetValues $memberListForm \
  2427.         -bottomSide $statusBar \
  2428.         -MOTIF_bottomOffset 10
  2429.     VtShow $mainForm
  2430.     if {[lsearch -exact $MA_ALIAS_DATABASE_CLASSES $MA_ALIAS_CLASS] == -1} {
  2431.         set errorDlg [VtErrorDialog $mainForm.error1 -ok \
  2432.             -message "[IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_UNKNOWN_CLASS $MA_ALIAS_CLASS]\n[IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_ERR_USAGE]"\
  2433.             -okCallback quitCB \
  2434.             -autoLock quitCB]
  2435.         VtShow $errorDlg
  2436.     } elseif {[file exists $MA_ALIAS_FILENAME] && \
  2437.           [file isdirectory $MA_ALIAS_FILENAME]} {
  2438.         set errorDlg [VtErrorDialog $mainForm.error2 -ok \
  2439.             -message [IntlLocalizeMsg \
  2440.                 SCO_MAIL_ADMIN_ALIAS_ERR_DIRECTORY \
  2441.                 $MA_ALIAS_FILENAME] \
  2442.             -okCallback quitCB \
  2443.             -autoLock quitCB]
  2444.         VtShow $errorDlg
  2445.     } elseif {! [file exists $MA_ALIAS_FILENAME]} {
  2446.         set dialog [VtInformationDialog $mainForm.exist \
  2447.             -message [IntlLocalizeMsg \
  2448.                 SCO_MAIL_ADMIN_ALIAS_MSG_FILE_DOESNT_EXIST] \
  2449.             -ok]
  2450.         VtShow $dialog
  2451.         alias_load
  2452.     } else {
  2453.         MyStatusBox $mainForm.loadbox\
  2454.             [IntlLocalizeMsg SCO_MAIL_ADMIN_ALIAS_MSG_READING]
  2455.         set loadTime [time alias_load]
  2456.         set redrawTime [time [list aliasRedrawList ""]]
  2457.         set totalTime \
  2458.             [expr [ctoken loadTime " "] + [ctoken redrawTime " "]]
  2459.         if {$totalTime < 2000000} {
  2460.             sleep 2
  2461.         }
  2462.         MyStatusBox $mainForm.loadbox -close
  2463.     }
  2464.     #-----
  2465.     VtMainLoop
  2466. } "Alias Client"
  2467.