diff options
| -rw-r--r-- | mailman_lib.php | 222 |
1 files changed, 159 insertions, 63 deletions
diff --git a/mailman_lib.php b/mailman_lib.php index ee96094..5a9f2f5 100644 --- a/mailman_lib.php +++ b/mailman_lib.php @@ -1,5 +1,5 @@ <?php -// $Header: /cvsroot/bitweaver/_bit_util/mailman_lib.php,v 1.2 2008/04/30 17:19:02 wjames5 Exp $ +// $Header: /cvsroot/bitweaver/_bit_util/mailman_lib.php,v 1.3 2008/10/03 17:43:07 nickpalmer Exp $ // Copyright (c) bitweaver Group // All Rights Reserved. // Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. @@ -10,8 +10,6 @@ * * @date created 2008-APR-06 * @author wjames <will@tekimaki.com> spider <spider@viovio.com> -* @version -* @class BitGroup */ function mailman_verify_list( $pListName ) { @@ -29,7 +27,10 @@ function mailman_verify_list( $pListName ) { function mailman_list_lists() { $ret = array(); - if( $output = mailman_command( 'list_lists' ) ) { + if( $ret_code = mailman_command( 'list_lists', $output) ) { + mailman_fatal(tra('Unable to list lists.'), $ret_code); + } + else { foreach( $output as $o ) { if( strpos( $o, '-' ) ) { list( $name, $desc ) = split( '-', $o ); @@ -44,7 +45,8 @@ function mailman_list_lists() { function mailman_list_members( $pListName ) { $ret = array(); $options = escapeshellarg( $pListName ); - if( $output = mailman_command( 'list_members', $options ) ) { + if( $ret = mailman_command( 'list_members', $output, $options ) ) { + // mailman_fatal(tra('Unable to get members for list: ').$pListName, $ret); } return( $output ); } @@ -58,28 +60,56 @@ function mailman_newlist( $pParamHash ) { $options .= ' '.escapeshellarg( $pParamHash['listadmin-addr'] ).' '; $options .= ' '.escapeshellarg( $pParamHash['admin-password'] ).' '; - $output = mailman_command( 'newlist', $options ); + if( $ret = mailman_command( 'newlist', $output, $options ) ) { + mailman_fatal(tra('Unable to create list: ').$pParamHash['listname'], $ret); + } $newList = $pParamHash['listname']; - $newAliases = "## $newList mailing list -$newList: \"|/usr/lib/mailman/mail/mailman post $newList\" -$newList-admin: \"|/usr/lib/mailman/mail/mailman admin $newList\" -$newList-bounces: \"|/usr/lib/mailman/mail/mailman bounces $newList\" -$newList-confirm: \"|/usr/lib/mailman/mail/mailman confirm $newList\" -$newList-join: \"|/usr/lib/mailman/mail/mailman join $newList\" -$newList-leave: \"|/usr/lib/mailman/mail/mailman leave $newList\" -$newList-owner: \"|/usr/lib/mailman/mail/mailman owner $newList\" -$newList-request: \"|/usr/lib/mailman/mail/mailman request $newList\" -$newList-subscribe: \"|/usr/lib/mailman/mail/mailman subscribe $newList\" -$newList-unsubscribe: \"|/usr/lib/mailman/mail/mailman unsubscribe $newList\""; + $mailman = mailman_get_mailman_command(); + $newAliases = " +## $newList mailing list +$newList: \"|$mailman post $newList\" +$newList-admin: \"|$mailman admin $newList\" +$newList-bounces: \"|$mailman bounces $newList\" +$newList-confirm: \"|$mailman confirm $newList\" +$newList-join: \"|$mailman join $newList\" +$newList-leave: \"|$mailman leave $newList\" +$newList-owner: \"|$mailman owner $newList\" +$newList-request: \"|$mailman request $newList\" +$newList-subscribe: \"|$mailman subscribe $newList\" +$newList-unsubscribe: \"|$mailman unsubscribe $newList\""; - if( $fh = fopen( '/etc/aliases', 'a' ) ) { - fwrite( $fh, $newAliases ); - fclose( $fh ); - exec( 'newaliases' ); + // Make sure we unlock the semaphore + ignore_user_abort(true); + // Get a lock. flock is not reliable (NFS, FAT, etc) + // so we use a semaphore instead. + $sem_key = ftok(mailman_get_aliases_file(), 'm'); + if( $sem_key != -1 ) { + // Get the semaphore + $sem = sem_get($sem_key); + if( $sem ) { + if( sem_acquire($sem) ) { + if( $fh = fopen( mailman_get_aliases_file(), 'a' ) ) { + fwrite( $fh, $newAliases ); + fclose( $fh ); + mailman_newalias(); + } else { + $error = "Could not open /etc/aliases for appending."; + } + if( !sem_release($sem) ) { + $error = "Error releasing a sempahore."; + } + } else { + $error = "Unable to aquire a semaphore."; + } + } else { + $error = "Unable to get a semaphore."; + } } else { - $error = "Could not open /etc/aliases for appending."; + $error = "Couldn't create semaphore key."; } + // Let the user cancel again + ignore_user_abort(false); } return $error; } @@ -90,7 +120,7 @@ function mailman_remove_member( $pListName, $pEmail ) { $cmd = "echo ".escapeshellarg( $pEmail )." | $fullCommand -f - ".escapeshellarg( $pListName ); exec( $cmd, $ret ); } else { - bit_log_error( tra( 'Groups mailman command failed' ).' (remove_members) '.tra( 'File not found' ).': '.$fullCommand ); + bit_log_error( 'Groups mailman command failed (remove_members) File not found: '.$fullCommand ); } } @@ -100,13 +130,15 @@ function mailman_addmember( $pListName, $pEmail ) { $cmd = "echo ".escapeshellarg( $pEmail )." | $fullCommand -r - ".escapeshellarg( $pListName ); exec( $cmd, $ret ); } else { - bit_log_error( tra( 'Groups mailman command failed' ).' (add_members) '.tra( 'File not found' ).': '.$fullCommand ); + bit_log_error( 'Groups mailman command failed (add_members) File not found: '.$fullCommand ); } } function mailman_findmember( $pListName, $pEmail ) { $options = ' -l '.escapeshellarg( $pListName ).' '.escapeshellarg( $pEmail ); - $output = mailman_command( 'find_member', $options ); + if( $ret = mailman_command( 'find_member', $output, $options ) ) { + mailman_fatal(tra('Unable to find member in list: ').$pListName, $ret); + } return $output; } @@ -114,68 +146,132 @@ function mailman_rmlist( $pListName ) { $error = NULL; if( mailman_verify_list( $pListName ) ) { $options = ' -a '.escapeshellarg( $pListName ); - $output = mailman_command( 'rmlist', $options ); + if( $ret = mailman_command( 'rmlist', $output, $options ) ) { + mailman_fatal(tra('Unable to remove list: ').$pListName, $ret); + } $newList = $pListName; - $aliasesLines = array( -"## $newList mailing list" => TRUE, -"$newList" => "\"|/usr/lib/mailman/mail/mailman post $newList\"", -"$newList-admin" => "\"|/usr/lib/mailman/mail/mailman admin $newList\"", -"$newList-bounces" => "\"|/usr/lib/mailman/mail/mailman bounces $newList\"", -"$newList-confirm" => "\"|/usr/lib/mailman/mail/mailman confirm $newList\"", -"$newList-join" => "\"|/usr/lib/mailman/mail/mailman join $newList\"", -"$newList-leave" => "\"|/usr/lib/mailman/mail/mailman leave $newList\"", -"$newList-owner" => "\"|/usr/lib/mailman/mail/mailman owner $newList\"", -"$newList-request" => "\"|/usr/lib/mailman/mail/mailman request $newList\"", -"$newList-subscribe" => "\"|/usr/lib/mailman/mail/mailman subscribe $newList\"", -"$newList-unsubscribe" => "\"|/usr/lib/mailman/mail/mailman unsubscribe $newList\"" ); - if( $fh = fopen( '/etc/aliases', 'r+' ) ) { - // cull out all aliase lines for the mailing list and rewrite the file - $newContents = ''; - while( $line = fgets( $fh ) ) { - @list( $alias, $value ) = split( ':', $line ); - $alias = trim( $alias ); - if( empty( $aliasesLines[$alias] ) ) { - $newContents .= $line; - } - } - fclose( $fh ); + $mailman = mailman_get_mailman_command(); - // reopen file truncating to zero length - $fh = fopen( '/etc/aliases', 'w' ); - if( empty( $newContents ) ) { - $error = "Empty aliases for /etc/aliases"; - } elseif( !fwrite( $fh, $newContents ) ) { - $error = "Could not write new /etc/aliases"; + $aliasesLines = array( + "## $newList mailing list", + "$newList", + "$newList-admin", + "$newList-bounces", + "$newList-confirm", + "$newList-join", + "$newList-leave", + "$newList-owner", + "$newList-request", + "$newList-subscribe", + "$newList-unsubscribe" + ); + // Make sure we unlock the semaphore + ignore_user_abort(true); + // Get a lock. flock is not reliable (NFS, FAT, etc) + // so we use a semaphore instead. + $sem_key = ftok(mailman_get_aliases_file(), 'm'); + if( $sem_key != -1 ) { + // Get the semaphore + $sem = sem_get($sem_key); + if( $sem ) { + if( sem_acquire($sem) ) { + if( $fh = fopen( mailman_get_aliases_file(), 'r+' ) ) { + // cull out all aliase lines for the mailing list and rewrite the file + $newContents = ''; + while( $line = fgets( $fh ) ) { + @list( $alias, $value ) = split( ':', $line ); + $alias = trim( $alias ); + if( !in_array($alias, $aliasesLines) ) { + $newContents .= $line; + } + } + + // Truncate the file + if( ftruncate($fh, 0) != 1) { + $error = "Unable to truncate /etc/aliases"; + } else { + if( !rewind($fh) ) { + $error = "Unable to seek /etc/aliases"; + } + else { + if( empty( $newContents ) ) { + $error = "Empty aliases for /etc/aliases"; + } elseif( !fwrite( $fh, $newContents ) ) { + $error = "Could not write new /etc/aliases"; + } + } + } + + fclose( $fh ); + mailman_newalias(); + } else { + $error = "Could not open /etc/aliases for appending."; + } + + if( !sem_release($sem) ) { + $error = "Error releasing a sempahore."; + } + } else { + $error = "Unable to aquire a semaphore."; + } + } else { + $error = "Unable to get a semaphore."; } - fclose( $fh ); - exec( 'newaliases' ); } else { - $error = "Could not open /etc/aliases for appending."; + $error = "Couldn't create semaphore key."; } + // Let the user cancel again + ignore_user_abort(false); } return $error; } -function mailman_command( $pCommand, $pOptions=NULL ) { +function mailman_newalias() { + global $gBitSystem; + exec( $gBitSystem->getConfig('server_newaliases_cmd', '/usr/bin/newaliases' )); +} + +function mailman_get_aliases_file() { + global $gBitSystem; + return $gBitSystem->getConfig('server_aliases_file', '/etc/aliases'); +} + +function mailman_command( $pCommand, &$output, $pOptions=NULL ) { $ret = NULL; if( $fullCommand = mailman_get_command( $pCommand ) ) { $cmd = $fullCommand.' '.$pOptions; if( !defined( 'IS_LIVE' ) || !IS_LIVE ) { bit_log_error( 'mailman LOG: '.$cmd ); } - exec( $cmd, $ret ); + exec( $cmd, $output, $ret_code ); + if( $ret_code ) { + bit_log_error('Error running command: '. $cmd . ' Command returned: '.$ret_code); + } } else { - bit_log_error( tra( 'Groups mailman command failed' ).' ('.$pCommand.') '.tra( 'File not found' ).': '.$fullCommand ); + bit_log_error( 'Groups mailman command failed ('.$pCommand.'): File not found: '.$fullCommand ); } - return $ret; + return $ret_code; +} + +function mailman_fatal($pMessage, $pRetCode) { + global $gBitSystem; + $gBitSystem->fatalError($pMessage.tra(' Command returned: ').$pRetCode); + die; +} + +function mailman_get_mailman_command() { + global $gBitSystem; + $mailman = $gBitSystem->getConfig( 'server_mailman_cmd', '/usr/lib/mailman/mail/mailman' ); + return $mailman; } function mailman_get_command( $pCommand ) { global $gBitSystem; $ret = NULL; - $fullCommand = $gBitSystem->getConfig( 'server_mailman_bin' ).'/'.$pCommand; + // Support for legacy configurations + $fullCommand = $gBitSystem->getConfig( 'server_mailman_bin' ) .'/'.$pCommand; $fullCommand = str_replace( '//', '/', $fullCommand ); if( file_exists( $fullCommand ) ) { $ret = $fullCommand; |
