diff -ruN mailfix/mailfix.module ../modules/mailfix/mailfix.module
--- mailfix/mailfix.module	2009-04-10 17:22:27.000000000 +1000
+++ ../modules/mailfix/mailfix.module	2009-09-25 19:52:38.000000000 +1000
@@ -30,6 +30,13 @@
 } // mailfix_help
 
 /**
+ * Implementation of hook_perm().
+ */
+function mailfix_perm() {
+  return array('administer mailfix', 'edit own mailfix settings');
+}
+
+/**
  * Implementation of hook_menu().
  */
 function mailfix_menu() {
@@ -83,20 +90,22 @@
  * Implementation of hook_user().
  */
 function mailfix_user($op, &$edit, &$user, $category = NULL) {
-  if (user_access('administer users')) {
-    switch ($op) {
-      case 'view':
-        return mailfix_view_user($user);
-      case 'form':
+  switch ($op) {
+    case 'view':
+      return mailfix_view_user($user);
+    case 'form':
+      if ($category == 'account')
         return mailfix_form_user($user);
-      case 'insert':
-      case 'update':
+    case 'insert':
+    case 'update':
+      if ($category == 'account')
         return mailfix_verify_user($edit, $user);
-      case 'delete':
+    case 'delete':
+      if (user_access('administer users')) {
         // Delete from {mailfix_users} table
         db_query('DELETE FROM {mailfix_users} WHERE uid = %d', $user->uid);
-        break;
-    }
+      }
+      break;
   }
 } // mailfix_user
 
@@ -109,6 +118,11 @@
  *    User object passed by reference.
  */
 function mailfix_verify_user(&$edit, &$user) {
+  if (!user_access('administer users')) {
+    _mailfix_set_user(&$edit, &$user);
+    return;
+  }
+
   // If mail address has been changed we must update mailfix_users record
   if (!empty($edit['mail'])) {
     $domain_id = _mailfix_verify_domain($edit['mail']);
@@ -182,11 +196,13 @@
  * @see mailfix_form_user()
  */
 function mailfix_form_user_validate($form, &$form_state) {
-  if ($form_state['values']['quota'] < 0) {
-    form_set_error('mail storage quota', t('The mail storage quota must be a positive value.'));
-  }
-  if (!is_numeric($form_state['values']['quota'])) {
-    form_set_error('mail storage quota', t('The mail storage quota must be an integer value. Provided value: %quota', array('%quota' => $form_state['values']['quota'])));
+  if (user_access('administer users')) {
+    if ($form_state['values']['quota'] < 0) {
+      form_set_error('mail storage quota', t('The mail storage quota must be a positive value.'));
+    }
+    if (!is_numeric($form_state['values']['quota'])) {
+      form_set_error('mail storage quota', t('The mail storage quota must be an integer value. Provided value: %quota', array('%quota' => $form_state['values']['quota'])));
+    }
   }
   // forward field is not required, thus validate only if filled
   if (!empty($form_state['values']['forward'])) { 
@@ -206,40 +222,42 @@
       $form_state['values']['forward'] = implode(",", $emails);
     }
   }
-  // incoming_bcc field is not required, thus validate only if filled
-  if (!empty($form_state['values']['incoming_bcc'])) { 
-    // incoming_bcc field is received as 1 address per line
-    $emails = explode("\n", $form_state['values']['incoming_bcc']);
-    $isvalid = TRUE;
-    foreach ($emails as &$email) {  // by reference as some cleanup may apply
-      $email = trim($email);
-      if (!valid_email_address($email)) {
-        $isvalid = FALSE;
+  if (user_access('administer users')) {
+    // incoming_bcc field is not required, thus validate only if filled
+    if (!empty($form_state['values']['incoming_bcc'])) { 
+      // incoming_bcc field is received as 1 address per line
+      $emails = explode("\n", $form_state['values']['incoming_bcc']);
+      $isvalid = TRUE;
+      foreach ($emails as &$email) {  // by reference as some cleanup may apply
+        $email = trim($email);
+        if (!valid_email_address($email)) {
+          $isvalid = FALSE;
+        }
       }
-    }
-    if (!$isvalid) {  // one or more illegal emai addresses
-      form_set_error('incoming BCC email recipients', t('The specified Incoming BCC destination(s) contains illegal email address(es). Spaces or any other special characters except dash (-) and underscore (_) are not allowed. If multiple recipients are specified, you must define one email address per line.'));
-    }
-    else { // clean addresses, thus forward field must be prepared as comma delimited string
-      $form_state['values']['incoming_bcc'] = implode(",", $emails);
-    }
-  }
-  // outgoing_bcc field is not required, thus validate only if filled
-  if (!empty($form_state['values']['outgoing_bcc'])) { 
-    // outgoing_bcc field is received as 1 address per line
-    $emails = explode("\n", $form_state['values']['outgoing_bcc']);
-    $isvalid = TRUE;
-    foreach ($emails as &$email) {  // by reference as some cleanup may apply
-      $email = trim($email);
-      if (!valid_email_address($email)) {
-        $isvalid = FALSE;
+      if (!$isvalid) {  // one or more illegal emai addresses
+        form_set_error('incoming BCC email recipients', t('The specified Incoming BCC destination(s) contains illegal email address(es). Spaces or any other special characters except dash (-) and underscore (_) are not allowed. If multiple recipients are specified, you must define one email address per line.'));
+      }
+      else { // clean addresses, thus forward field must be prepared as comma delimited string
+        $form_state['values']['incoming_bcc'] = implode(",", $emails);
       }
     }
-    if (!$isvalid) {  // one or more illegal emai addresses
-      form_set_error('outgoing BCC email recipients', t('The specified Outgoing BCC destination(s) contains illegal email address(es). Spaces or any other special characters except dash (-) and underscore (_) are not allowed. If multiple recipients are specified, you must define one email address per line.'));
-    }
-    else { // clean addresses, thus forward field must be prepared as comma delimited string
-      $form_state['values']['outgoing_bcc'] = implode(",", $emails);
+    // outgoing_bcc field is not required, thus validate only if filled
+    if (!empty($form_state['values']['outgoing_bcc'])) { 
+      // outgoing_bcc field is received as 1 address per line
+      $emails = explode("\n", $form_state['values']['outgoing_bcc']);
+      $isvalid = TRUE;
+      foreach ($emails as &$email) {  // by reference as some cleanup may apply
+        $email = trim($email);
+        if (!valid_email_address($email)) {
+          $isvalid = FALSE;
+        }
+      }
+      if (!$isvalid) {  // one or more illegal emai addresses
+        form_set_error('outgoing BCC email recipients', t('The specified Outgoing BCC destination(s) contains illegal email address(es). Spaces or any other special characters except dash (-) and underscore (_) are not allowed. If multiple recipients are specified, you must define one email address per line.'));
+      }
+      else { // clean addresses, thus forward field must be prepared as comma delimited string
+        $form_state['values']['outgoing_bcc'] = implode(",", $emails);
+      }
     }
   }
 } //  mailfix_form_user_validate
@@ -253,26 +271,36 @@
   $fields = array();
   if (_mailfix_get_user($user) == 1) {
     // Create the outer content
-    $fields['mailfix'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Mailfix Settings'),
-      '#description' => t('<p>If you <em>update</em> an account\'s e-mail, the Mailfix module will drop any existing Mailfix profile. Then it will verify if the new address matches a registered domain. If a match is found, a Mailfix profile will be created with domain\'s default settings. If no match is found, no Mailfix profile will be created.</p><p>If you <em>block</em> an account, it will stop receiveing mails and BCC monitoring will be turned off. However, if the <em>forward</em> field is set, incoming mails can still be forwarded to someone else (e.g. a supervisor).</p><p>If you <em>delete</em> an account, the associated Mailfix profile will be deleted as well.</p>'),
-    );
+    if (user_access('administer users')) {
+      $fields['mailfix'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Mailfix Settings'),
+        '#description' => t('<p>If you <em>update</em> an account\'s e-mail, the Mailfix module will drop any existing Mailfix profile. Then it will verify if the new address matches a registered domain. If a match is found, a Mailfix profile will be created with domain\'s default settings. If no match is found, no Mailfix profile will be created.</p><p>If you <em>block</em> an account, it will stop receiveing mails and BCC monitoring will be turned off. However, if the <em>forward</em> field is set, incoming mails can still be forwarded to someone else (e.g. a supervisor).</p><p>If you <em>delete</em> an account, the associated Mailfix profile will be deleted as well.</p>'),
+      );
+    } else {
+      $fields['mailfix'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Mail Settings'),
+        '#description' => t('You can control where email to your account should be sent. If you have not configured your email to be forwarded, it will be stored on the crca server. You can then retrieve the email using a client like Outlook, from the server mail.crca.org.au, using the same username and password you have for the website. Email may be sent by setting your client up to use SMTP on the same server, port 2525 (you need to use your username and password in sending email). Webmail is available via <a href="http://mail.crca.org.au">mail.crca.org.au</a>.'),
+      );
+    }
     // Mailfix settings
-    $fields['mailfix']['domain_name'] = array(
-      '#type' => 'item',
-      '#title' => t('Mail domain'),
-      '#value' => $user->mailfix['domain_name'],
-    );
-    $fields['mailfix']['quota'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Quota limit'),
-      '#description' => t('This is the quota limit for %username in bytes. Useful information: 1kB = 1024 bytes, 1MB = 1048576 bytes, 1GB = 1073741824 bytes', array('%username' => $user->name)),
-      '#default_value' => $user->mailfix['quota'],
-      '#maxlength' => 19,  // MySQL bigint max unsigned value: 9223372036854775808
-      '#size' => 20,  
-      '#required' => TRUE, 
-    );
+    if (user_access('administer users')) {
+      $fields['mailfix']['domain_name'] = array(
+        '#type' => 'item',
+         '#title' => t('Mail domain'),
+        '#value' => $user->mailfix['domain_name'],
+      );
+      $fields['mailfix']['quota'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Quota limit'),
+        '#description' => t('This is the quota limit for %username in bytes. Useful information: 1kB = 1024 bytes, 1MB = 1048576 bytes, 1GB = 1073741824 bytes', array('%username' => $user->name)),
+        '#default_value' => $user->mailfix['quota'],
+        '#maxlength' => 19,  // MySQL bigint max unsigned value: 9223372036854775808
+        '#size' => 20,  
+        '#required' => TRUE, 
+      );
+    }
     $fields['mailfix']['forward'] = array(
       '#title' => t('Forward destination(s)'),
       '#description' => t('If defined, incoming mails will no longer be delivered to %email. Instead, they will be forwarded to given destination(s). You can specify multiple recipients (one per line). Automatic forwarding is useful in scenarios such as vacations, temporary leave or disabled accounts.', array('%email' => $user->mail)),
@@ -281,29 +309,31 @@
       '#default_value' => str_replace(",", "\n", $user->mailfix['forward']),
       '#required' => FALSE, 
     );
-    $fields['mailfix']['silent_bcc'] = array(
-      '#type' => 'fieldset',
-      '#collapsible' => TRUE,
-      '#collapsed' => TRUE,
-      '#title' => t('Silent BCC Monitoring'),
-      '#description' => t('You can specify silent monitoring of incoming and outgoing messages for this account. Silent monitoring is useful to audit activity of specific users. You can specify multiple recipients (one per line).'),
-    );
-    $fields['mailfix']['silent_bcc']['incoming_bcc'] = array(
-      '#title' => t('Incoming messages'),
-      '#description' => t('If defined, any incoming mail for %email will be copied as <acronym title="Blind Carbon Copy">BCC</acronym> to given destinations.', array('%email' => $user->mail)),
-      '#type' => 'textarea',
-      '#rows' => 3, 
-      '#default_value' => str_replace(",", "\n", $user->mailfix['incoming_bcc']),
-      '#required' => FALSE, 
-    );
-    $fields['mailfix']['silent_bcc']['outgoing_bcc'] = array(
-      '#title' => t('Outgoing messages'),
-      '#description' => t('If defined, any outgoing mail from %email will be copied as <acronym title="Blind Carbon Copy">BCC</acronym> to given destinations.', array('%email' => $user->mail)),
-      '#type' => 'textarea',
-      '#rows' => 3, 
-      '#default_value' => str_replace(",", "\n", $user->mailfix['outgoing_bcc']),
-      '#required' => FALSE, 
-    );
+    if (user_access('administer users')) {
+      $fields['mailfix']['silent_bcc'] = array(
+        '#type' => 'fieldset',
+        '#collapsible' => TRUE,
+        '#collapsed' => TRUE,
+        '#title' => t('Silent BCC Monitoring'),
+        '#description' => t('You can specify silent monitoring of incoming and outgoing messages for this account. Silent monitoring is useful to audit activity of specific users. You can specify multiple recipients (one per line).'),
+      );
+      $fields['mailfix']['silent_bcc']['incoming_bcc'] = array(
+        '#title' => t('Incoming messages'),
+        '#description' => t('If defined, any incoming mail for %email will be copied as <acronym title="Blind Carbon Copy">BCC</acronym> to given destinations.', array('%email' => $user->mail)),
+        '#type' => 'textarea',
+        '#rows' => 3, 
+        '#default_value' => str_replace(",", "\n", $user->mailfix['incoming_bcc']),
+        '#required' => FALSE, 
+      );
+      $fields['mailfix']['silent_bcc']['outgoing_bcc'] = array(
+        '#title' => t('Outgoing messages'),
+        '#description' => t('If defined, any outgoing mail from %email will be copied as <acronym title="Blind Carbon Copy">BCC</acronym> to given destinations.', array('%email' => $user->mail)),
+        '#type' => 'textarea',
+        '#rows' => 3, 
+        '#default_value' => str_replace(",", "\n", $user->mailfix['outgoing_bcc']),
+        '#required' => FALSE, 
+      );
+    }
     $fields['#validate'][] = 'mailfix_form_user_validate';
   }
   return $fields;
@@ -327,18 +357,30 @@
       '#attributes' => array('class' => 'user-mailfix'),
       //'#weight' => -5,
       '#title' => t('Mailfix Settings'),
-    );
-    // Display summary of mailfix settings
-    $user->content['mailfix']['domain_name'] = array(
-      '#type' => 'user_profile_item',     // another core themable hook
-      '#title' => t('Mail domain'),
-      '#value' => $user->mailfix['domain_name'],
-    );
-    $user->content['mailfix']['quota'] = array(
-      '#type' => 'user_profile_item',     // another core themable hook
-      '#title' => t('Quota limit'),
-      '#value' => ($user->mailfix['quota'] == 0) ? t('unlimited') : format_size($user->mailfix['quota']),
-    );
+      );
+
+      $user->content['mailfix']['info'] = array(
+        '#type' => 'user_profile_item',     // another core themable hook
+        //'#title' => t('Quota limit'),
+        '#weight' => -5,
+        '#value' => empty($user->mailfix['forward']) ? t('Your email is being stored on the CRCA server. You can retrieve it using a client like Outlook, from the server mail.crca.org.au, using the same username and password you have for the website. Email may be sent by setting your client up to use SMTP on the same server, port 2525 (you need to use your username and password in sending email). Webmail is available via <a href="http://mail.crca.org.au">mail.crca.org.au</a>.') : t('Email is being forwarded to the address(es) below.'),
+      );
+    if (user_access('administer users')) {
+      // Display summary of mailfix settings
+      $user->content['mailfix']['domain_name'] = array(
+        '#type' => 'user_profile_item',     // another core themable hook
+        '#title' => t('Mail domain'),
+        '#value' => $user->mailfix['domain_name'],
+      );
+    }
+    // The quota is irrelevant if mail is being forwarded.
+    if (empty($user->mailfix['forward'])) {
+      $user->content['mailfix']['quota'] = array(
+        '#type' => 'user_profile_item',     // another core themable hook
+        '#title' => t('Quota limit'),
+        '#value' => ($user->mailfix['quota'] == 0) ? t('unlimited') : format_size($user->mailfix['quota']),
+      );
+    }
     if (!empty($user->mailfix['forward'])) {
       $user->content['mailfix']['forward'] = array(
         '#type' => 'user_profile_item',
@@ -346,19 +388,21 @@
         '#value' => $user->mailfix['forward'],
       );
     }
-    if (!empty($user->mailfix['incoming_bcc'])) {
-      $user->content['mailfix']['incoming_bcc'] = array(
-        '#type' => 'user_profile_item',
-        '#title' => t('BCC incoming mail to'),
-        '#value' => $user->mailfix['incoming_bcc'],
-      );
-    }
-    if (!empty($user->mailfix['outgoing_bcc'])) {
-      $user->content['mailfix']['outgoing_bcc'] = array(
-        '#type' => 'user_profile_item',
-        '#title' => t('BCC outgoing mail to'),
-        '#value' => $user->mailfix['outgoing_bcc'],
-      );
+    if (user_access('administer users')) {
+      if (!empty($user->mailfix['incoming_bcc'])) {
+        $user->content['mailfix']['incoming_bcc'] = array(
+          '#type' => 'user_profile_item',
+          '#title' => t('BCC incoming mail to'),
+          '#value' => $user->mailfix['incoming_bcc'],
+        );
+      }
+      if (!empty($user->mailfix['outgoing_bcc'])) {
+        $user->content['mailfix']['outgoing_bcc'] = array(
+          '#type' => 'user_profile_item',
+          '#title' => t('BCC outgoing mail to'),
+          '#value' => $user->mailfix['outgoing_bcc'],
+        );
+      }
     }
   }
 } // mailfix_view_user
@@ -377,14 +421,23 @@
     .'WHERE u.uid = %d ';
   $found = 0;
   if ($result = db_fetch_object(db_query($sql, $user->uid))) {
-    $user->mailfix = array(
-      'domain_id' => $result->domain_id,
-      'domain_name' => $result->domain_name,
-      'quota' => $result->quota,
-      'forward' => $result->forward,
-      'incoming_bcc' => $result->incoming_bcc,
-      'outgoing_bcc' => $result->outgoing_bcc,
-    );
+    if (user_access('administer users')) {
+      $user->mailfix = array(
+        'domain_id' => $result->domain_id,
+        'domain_name' => $result->domain_name,
+        'quota' => $result->quota,
+        'forward' => $result->forward,
+        'incoming_bcc' => $result->incoming_bcc,
+        'outgoing_bcc' => $result->outgoing_bcc,
+      );
+    } else {
+      $user->mailfix = array(
+        'domain_id' => $result->domain_id,
+        'domain_name' => $result->domain_name,
+        'quota' => $result->quota,
+        'forward' => $result->forward,
+      );
+    }
     $found = 1;
   };
   return $found;
@@ -396,12 +449,25 @@
  * @param object $user
  *    User object passed by reference to include mailfix settings.
  */
-function _mailfix_set_user(&$edit) {
-  db_query("DELETE FROM {mailfix_users} WHERE uid = %d", $edit['uid']);
+function _mailfix_set_user(&$edit, &$user) {
+  $sql = 'SELECT u.uid, u.domain_id, u.quota, u.forward, u.incoming_bcc, u.outgoing_bcc, d.domain_name '
+    .'FROM {mailfix_domains} d JOIN {mailfix_users} u ON d.domain_id = u.domain_id '
+    .'WHERE u.uid = %d ';
+  $found = 0;
+  if ($result = db_fetch_object(db_query($sql, $user->uid))) {
+    $found = 1;
+    if (!user_access('administer users')) {
+      $edit['domain_id'] = $result->domain_id;
+      $edit['quota'] = $result->quota;
+      $edit['incoming_bcc'] = $result->incoming_bcc;
+      $edit['outgoing_bcc'] = $result->outgoing_bcc;
+    }
+  }
+  db_query("DELETE FROM {mailfix_users} WHERE uid = %d", $user->uid);
   db_query("INSERT INTO {mailfix_users} (uid, domain_id, quota, forward, incoming_bcc, outgoing_bcc) "
     ."VALUES (%d, %d, %d, '%s', '%s', '%s')", 
     array( 
-      $edit['uid'],
+      $user->uid,
       $edit['domain_id'],
       $edit['quota'],
       $edit['forward'],
@@ -409,4 +475,15 @@
       $edit['outgoing_bcc'],
     )
   );
+      watchdog(
+        'mailfix', 
+        'Mailfix profile for %user_name set. Forwarding: %fwd, BCC monitoring: %bcc', 
+        array(
+          '%user_name' => $user->name,
+          '%fwd' => (empty($edit['forward']) ? t('no') : $edit['forward']),
+          '%bcc' => ((empty($edit['incoming_bcc']) || empty($edit['outgoing_bcc'])) ? t('no') : t('yes')),
+        ), 
+        WATCHDOG_NOTICE, 
+        l('view', 'admin/user/user/'. $user->uid)
+      );
 }
