[imp] A patch which solves my fetchmail problem...

W. Tasin tasin at fhm.edu
Thu Jun 26 07:10:24 PDT 2003


Hello,

I send you a patch, which reduces the memory consumption of fetchmail 
and increases the preformance on large mailboxes and large mails.

With this patch mailbodies will only be read from the server, if they 
are up to be fetched. I included also a conf-option to set up the 
maximal size of a mail to be fetched. If the mail exeeds this value a 
notification will be given to the user.

HTH .. it does for me...

Ciao

Walter

-- 
oohhh sveglia.... il mondo e' ammalato, ma x colpa di chi.........
(Zucchero)
:-------W._Tasin,_FB_04,_FHM-------------------PGP-KeyID:0x7961A645---:
<Key-Fingerprint: 1610 835F 0080 32F4 6140  6CF7 A7D0 44CD 7961A645>
<http://wwwkeys.pgp.net:11371/pks/lookup?op=index&search=0x7961A645&fingerprint=on>

-------------- next part --------------
--- config/conf.xml	Wed Jun 11 09:20:49 2003
+++ config/conf.xml	Thu Jun 26 14:14:12 2003
@@ -81,8 +81,9 @@
         Fetchmail Settings
    </configheader>
    <configboolean name="show_account_colors" desc="Should we display colors for messages fetched from other accounts in the mailbox index? This is a performance hit, but may be okay on smaller installations.">false</configboolean>
+   <configstring name="size_limit" desc="What is the maximum total size of mails to be fetched (in bytes). Please remember you need more than the double of this value for 'memory_limit' in php.ini? Set this value to 0 for no limit.">4000000</configstring>
  </configsection>
- 
+
  <configsection name="msg">
    <configheader>
         Message Settings
--- lib/Fetchmail.php	Tue Jun 17 09:53:49 2003
+++ lib/Fetchmail.php	Thu Jun 26 15:04:45 2003
@@ -405,6 +405,41 @@
     }
 
     /**
+     * Gets the mailbody and calls the custom filter function.
+     * and does some other corrections
+     *
+     * @access private
+     *
+     * @return string corrected content of the mail
+     */
+    function _getMailBody($mail_socket, $index, $header)
+    {
+       global $conf;
+
+       $acctcolor = $this->_params['acctcolor'];
+       if (!empty($acctcolor)) {
+          $header = rtrim($header) . "\nX-color: $acctcolor\n";
+       }
+
+       $mail_source = $header . "\n" . @imap_body($mail_socket, $index, FT_PEEK);
+
+       /* If there is a user defined function, call it with the
+          current message as an argument. */
+       if ($conf['hooks']['fetchmail_filter']) {
+          include_once HORDE_BASE . '/config/hooks.php';
+          if (function_exists('_imp_hook_fetchmail_filter')) {
+              $mail_source = call_user_func('_imp_hook_fetchmail_filter', $mail_source);
+          }
+       }
+
+       /* Make absolutely sure there are no bare newlines. */
+       $mail_source = preg_replace("|([^\r])\n|", "\\1\r\n", $mail_source);
+       $mail_source = str_replace("\n\n", "\n\r\n", $mail_source);
+
+       return $mail_source;
+    }
+
+    /**
      * Gets the mail using the data in this object.
      *
      * @access public
@@ -414,7 +449,7 @@
      */
     function getMail()
     {
-        global $conf, $imp;
+        global $conf, $imp, $notification;
 
         $mail_socket = false;
         $protocols = array();
@@ -452,79 +487,86 @@
         $newmailbox = IMP::ServerString() . $this->_params['lmailbox'];
 
         if ($num_msgs > 0) {
+
+            require_once HORDE_BASE . '/lib/MIME.php';
             $this->_numMsgs = 0;
             for ($index = 1; $index <= $num_msgs; $index++) {
                 /* Get the flags so we can set it back to unseen */
                 $h = @imap_headerinfo($mail_socket, $index);
-                $acctcolor = $this->_params['acctcolor'];
-
+                $hinfo = @imap_fetch_overview($mail_socket, $index);
                 /* Get the message */
                 $mail_source = @imap_fetchheader($mail_socket, $index);
-                if (!empty($acctcolor)) {
-                    $mail_source = rtrim($mail_source) . "\nX-color: $acctcolor\n";
-                }
-                $mail_source = $mail_source . "\n" . @imap_body($mail_socket, $index, FT_PEEK);
-
-                /* If there is a user defined function, call it with the
-                   current message as an argument. */
-                if ($conf['hooks']['fetchmail_filter']) {
-                    include_once HORDE_BASE . '/config/hooks.php';
-                    if (function_exists('_imp_hook_fetchmail_filter')) {
-                        $mail_source = call_user_func('_imp_hook_fetchmail_filter', $mail_source);
-                    }
-                }
-
-                /* Make absolutely sure there are no bare newlines. */
-                $mail_source = preg_replace("|([^\r])\n|", "\\1\r\n", $mail_source);
-                $mail_source = str_replace("\n\n", "\n\r\n", $mail_source);
+
 
                 if ($this->_params['base_protocol'] == 'POP3') {
                     if (($this->_params['onlynew'] &&
-                         (($h->Recent == 'N') || ($h->Unseen == 'U')) &&
-                         ($h->Deleted != 'D')) ||
-                        (!$this->_params['onlynew'] && ($h->Deleted != 'D'))) {
-                        /* Append to the server */
-                        if (@imap_append($imp['stream'], $newmailbox, $mail_source)) {
-                            $this->_numMsgs++;
-
-                            /* Remove the mail if 'del' is set */
-                            if ($this->_params['del']) {
-                                if (!@imap_delete($mail_socket, $index)) {
-                                    @imap_close($mail_socket);
-                                    return PEAR::raiseError(_("An error occurred when deleting messages from server"));
-                                }
-                            }
-                        }
-                    }
-                } else {
-                    /* If fetch only new messages, unseen, not deleted or
-                       fetch all but deleted */
-                    if (($this->_params['onlynew'] &&
-                         (($h->Recent == 'N') || ($h->Unseen == 'U')) &&
-                         ($h->Deleted != 'D')) ||
+                        (($h->Recent == 'N') || ($h->Unseen == 'U')) &&
+                        ($h->Deleted != 'D')) ||
                         (!$this->_params['onlynew'] && ($h->Deleted != 'D'))) {
-                        /* Append to the server */
-                        if (@imap_append($imp['stream'], $newmailbox, $mail_source)) {
-                            $this->_numMsgs++;
-
-                            /* Mark message seen if 'markseen' is set */
-                            if ($this->_params['markseen']) {
-                                if (!@imap_setflag_full($mail_socket, $index, "\\Seen")) {
-                                    @imap_close($mail_socket);
-                                    return PEAR::raiseError(_("An error occurred when setting the messages seen from server"));
-                                }
-                            }
-
-                            /* Remove the mail if $delete is set */
-                            if ($this->_params['del']) {
-                                if (!@imap_delete($mail_socket, $index)) {
-                                    @imap_close($mail_socket);
-                                    return PEAR::raiseError(_("An error occurred when deleting messages from server"));
+                           if ($conf['fetchmail']['size_limit']!=0 && $hinfo[0]->size>$conf['fetchmail']['size_limit'])
+                           {
+                             $notification->push(sprintf(_("The message \"%s\" from \"%s\" (%d bytes) exeeds fetch size limit."),
+                                          MIME::Decode($hinfo[0]->subject), MIME::Decode($hinfo[0]->from), $hinfo[0]->size),
+                                          'horde.warning');
+                           }
+                           else
+                           {
+                             /* get the complete message */
+                             $mail_source = $this->_getMailBody($mail_socket, $index, $mail_source);
+                             /* Append to the server */
+                             if (@imap_append($imp['stream'], $newmailbox, $mail_source)) {
+                                $this->_numMsgs++;
+
+                                /* Remove the mail if 'del' is set */
+                                if ($this->_params['del']) {
+                                   if (!@imap_delete($mail_socket, $index)) {
+                                      @imap_close($mail_socket);
+                                      return PEAR::raiseError(_("An error occurred when deleting messages from server"));
+                                   }
                                 }
-                            }
-                        }
-                    }
-                }
+                             }
+                           }
+                      }
+                  } else {
+                      /* If fetch only new messages, unseen, not deleted or
+                         fetch all but deleted */
+                      if (($this->_params['onlynew'] &&
+                           (($h->Recent == 'N') || ($h->Unseen == 'U')) &&
+                           ($h->Deleted != 'D')) ||
+                          (!$this->_params['onlynew'] && ($h->Deleted != 'D'))) {
+                           if ($conf['fetchmail']['size_limit']!=0 && $hinfo[0]->size>$conf['fetchmail']['size_limit'])
+                           {
+                              $notification->push(sprintf(_("The message \"%s\" from \"%s\" (%d bytes) exeeds fetch size limit."),
+                                          MIME::Decode($hinfo[0]->subject), MIME::Decode($hinfo[0]->from), $hinfo[0]->size),
+                                          'horde.warning');
+                           }
+                           else
+                           {
+                              /* get the complete message */
+                              $mail_source = $this->_getMailBody($mail_socket, $index, $mail_source);
+                              /* Append to the server */
+                              if (@imap_append($imp['stream'], $newmailbox, $mail_source)) {
+                                  $this->_numMsgs++;
+
+                                  /* Mark message seen if 'markseen' is set */
+                                  if ($this->_params['markseen']) {
+                                      if (!@imap_setflag_full($mail_socket, $index, "\\Seen")) {
+                                          @imap_close($mail_socket);
+                                          return PEAR::raiseError(_("An error occurred when setting the messages seen from server"));
+                                      }
+                                  }
+
+                                  /* Remove the mail if $delete is set */
+                                  if ($this->_params['del']) {
+                                      if (!@imap_delete($mail_socket, $index)) {
+                                          @imap_close($mail_socket);
+                                          return PEAR::raiseError(_("An error occurred when deleting messages from server"));
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                  }
             }
 
             if ($this->_params['del']) {


More information about the imp mailing list