7 # postmulti(1) contract:
10 # postmulti-script -e <edit_command>
16 # MAIL_CONFIG - config_directory of primary instance
17 # command_directory - From primary instance
18 # daemon_directory - From primary instance
19 # config_directroy - config_directory of target instance
20 # queue_directory - queue_directory of target instance
21 # data_directory - data_directory of target instance
23 # Create, destroy, import and deport:
25 # multi_instance_directories - New value for primary instance
27 # Create, import and assign (unset == nochange, "-" == clear):
29 # multi_instance_group - New value for target instance
30 # multi_instance_name - New value for target instance
32 : ${MAIL_CONFIG:?"do not invoke this command directly"}
33 : ${command_directory:?"do not invoke this command directly"}
34 : ${daemon_directory:?"do not invoke this command directly"}
36 USAGE
="$0 -e create|destroy|import|deport|enable|disable|assign|init"
37 usage
() { echo "$0: Error: Usage: $USAGE" >&2; exit 1; }
39 TAG
="$MAIL_LOGTAG/postmulti-script"
40 fatal
() { postlog
-p fatal
-t "$TAG" "$1"; exit 1; }
48 alt
=`postconf -h alternate_config_directories` ||
return 1
50 shift $# # Needed on SunOS where bare "set --" is NOP!
51 IFS
="$IFS,"; set -- $alt; IFS
="$BACKUP_IFS"
54 # Portability: SunOS "sh" needs 'in "$@"' for one-line for-loop.
55 for d
in "$@"; do [ "$d" = "$dir" ] && found
=1 || keep
="$keep $d"; done
57 set -- "multi_instance_directories = $multi_instance_directories"
60 add
) test -n "$found" ||
61 set -- "$@" "alternate_config_directories =$keep $dir";;
62 del
) test -n "$found" &&
63 set -- "$@" "alternate_config_directories =$keep";;
64 *) return 1;; # XXX: Internal error
66 postconf
-e "$@" ||
return 1
70 # Set the instance name and group
72 test -n "$multi_instance_name" && {
73 test "$multi_instance_name" = "-" && multi_instance_name
=
74 set -- "$@" "multi_instance_name = $multi_instance_name"
76 test -n "$multi_instance_group" && {
77 test "$multi_instance_group" = "-" && multi_instance_group
=
78 set -- "$@" "multi_instance_group = $multi_instance_group"
80 test $# -eq 0 || postconf
-c "$config_directory" -e "$@" ||
return 1
83 # Process command-line options and parameter settings. Work around
84 # brain damaged shells. "IFS=value command" should not make the
85 # IFS=value setting permanent. But some broken standard allows it.
90 while getopts ":e:" opt
97 shift `expr $OPTIND - 1`
99 # Check for valid action and required instance name
101 create|import|destroy|deport|
enable|disable|assign|init
) ;;
104 test $# -eq 0 || usage
109 'multi_instance_wrapper = ${command_directory}/postmulti -p --' \
110 'multi_instance_enable = yes'
114 : ${config_directory:?"Invalid empty target instance config_directory"}
119 # Atomically install stock main.cf/master.cf files. We install the
120 # master.cf file last. Once it is present the instance is complete.
122 test -f $config_directory/main.cf
-a \
123 -f $config_directory/master.cf ||
{
125 test "$action" = "create" ||
{
126 test -f $config_directory/main.cf ||
127 fatal
"'$config_directory' lacks a main.cf file"
128 test -f $config_directory/master.cf ||
129 fatal
"'$config_directory' lacks a master.cf file"
132 # Create instance-specific directories
134 test -d $config_directory ||
135 { (umask 022; mkdir
-p $config_directory) ||
exit 1; }
136 test -d $queue_directory ||
137 { (umask 022; mkdir
-p $queue_directory) ||
exit 1; }
138 test -d $data_directory ||
139 { (umask 077; mkdir
-p $data_directory) ||
exit 1; }
141 tmpdir
=$config_directory/.tmp
142 (umask 077; mkdir
-p $tmpdir) ||
exit 1
143 cp -p $daemon_directory/main.cf
$tmpdir/main.cf ||
exit 1
145 # Shared install parameters are cloned from user-specified values in
146 # the default instance, but only if explicitly set there. Otherwise,
147 # they are commented out in the new main.cf file.
163 shift $# # Needed on SunOS where bare "set --" is NOP!
165 for p
in $SHARED_PARAMETERS; do
166 val
=`postconf -nh $p` ||
exit 1
167 test -n "$val" && { set -- "$@" "$p = $val"; continue; }
168 comment_out
="$comment_out $p"
171 # First comment-out any parameters that take default values
172 test -n "$comment_out" && {
173 postconf
-c $tmpdir -# $comment_out || exit 1
176 # Now add instance-specific and non-default values.
177 # By default, disable inet services and local submission
180 postconf
-c $tmpdir -e \
181 "queue_directory = $queue_directory" \
182 "data_directory = $data_directory" \
183 "authorized_submit_users =" \
184 "master_service_disable = inet" \
188 cp -p $daemon_directory/master.cf
$tmpdir/master.cf ||
exit 1
189 mv $tmpdir/main.cf
$config_directory/main.cf ||
exit 1
190 mv $tmpdir/master.cf
$config_directory/master.cf ||
exit 1
191 rmdir $tmpdir 2>/dev
/null
194 # Set instance name and group
196 assign_names ||
exit 1
198 # Update multi_instance_directories
199 # and drop from alternate_config_directories
201 # XXX: Must happen before set-permissions below, otherwise instance
202 # is treated as a non-slave instance by post-install via postfix(1).
204 update_cfdirs del
$config_directory ||
exit 1
206 # Update permissions of private files. Verifies existence of
207 # queue_directory and data_directory, ...
209 # XXX: Must happen after instance list updates above, otherwise instance
210 # is treated as a non-slave instance by post-install via postfix(1).
212 postfix
-c $config_directory set-permissions ||
exit 1
216 # Deporting an already deleted instance?
218 [ -f "$config_directory/main.cf" ] ||
{
219 update_cfdirs del
$config_directory
223 postfix
-c "$config_directory" status
>/dev
/null
2>&1 &&
224 fatal
"Instance '$config_directory' is not stopped"
226 # Update multi_instance_directories
227 # and add to alternate_config_directories
229 update_cfdirs add
$config_directory ||
exit 1
234 # "postmulti -e destroy" will remove an entire instance only when
235 # invoked immediately after "postmulti -e create" (i.e. before
236 # other files are added to the instance). We delete only known
237 # safe names without "/".
239 QUEUE_SUBDIRS
="active bounce corrupt defer deferred flush hold \
240 incoming maildrop pid private public saved trace"
242 WARN
="postlog -p warn -t $TAG"
244 # Locate the target instance
246 [ -f "$config_directory/main.cf" ] ||
247 fatal
"$config_directory/main.cf file not found"
249 postfix
-c "$config_directory" status
>/dev
/null
2>&1 &&
250 fatal
"Instance '$config_directory' is not stopped"
252 # Update multi_instance directories
253 # and also (just in case) drop from alternate_config_directories
255 $DEBUG update_cfdirs del
"$config_directory" ||
exit 1
257 # XXX: Internal "postfix /some/cmd" interface.
259 postfix
-c "$config_directory" /bin
/sh
-c "
260 for q in $QUEUE_SUBDIRS
262 $DEBUG rmdir -- \$q ||
263 $WARN \`pwd\`/\$q: please verify contents and remove by hand
267 postfix
-c "$config_directory" /bin
/sh
-c "
268 for dir in \$data_directory \$queue_directory
270 $DEBUG rmdir -- \$dir ||
271 $WARN \$dir: please verify contents and remove by hand
275 # In the configuration directory remove just the main.cf and master.cf
277 $DEBUG rm -f -- "$config_directory/master.cf" "$config_directory/main.cf" 2>/dev
/null
278 $DEBUG rmdir -- "$config_directory" ||
279 $WARN $config_directory: please verify contents and remove by hand
283 postconf
-c "$config_directory" -e \
284 "multi_instance_enable = yes" ||
exit 1;;
286 postconf
-c "$config_directory" -e \
287 "multi_instance_enable = no" ||
exit 1;;
289 assign_names ||
exit 1;;