--- ./dspam.orig/src/dspam.c	2009-12-08 12:51:22.000000000 +0300
+++ ./dspam/src/dspam.c	2009-12-08 20:08:18.934813615 +0300
@@ -807,48 +807,50 @@
     char data[128];
     FILE *fout;
 
     switch (CTX->result) {
       case DSR_ISSPAM:
         strcpy(data, "Spam");
         break;
       default:
         strcpy(data, "Innocent");
         break;
     }
 
     if (ATX->sockfd) {
       fout = ATX->sockfd;
       ATX->sockfd_output = 1;
     }
     else {
       fout = stdout;
     }
 
-    fprintf(fout, "X-DSPAM-Result: %s; result=\"%s\"; class=\"%s\"; "
-                  "probability=%01.4f; confidence=%02.2f; signature=%s\n",
-           CTX->username,
-           data,
-           CTX->class,
-           CTX->probability,
-           CTX->confidence,
-           (ATX->signature[0]) ? ATX->signature : "N/A");
+/* koc patch BEGIN 
+ *  fprintf(fout, "X-DSPAM-Result: %s; result=\"%s\"; class=\"%s\"; "
+ *                 "probability=%01.4f; confidence=%02.2f; signature=%s\n",
+ *         CTX->username,
+ *         data,
+ *         CTX->class,
+ *         CTX->probability,
+ *         CTX->confidence,
+ *         (ATX->signature[0]) ? ATX->signature : "N/A");
+ */
   }
 
   ATX->learned = CTX->learned;
   if (result_string)
     *result_string = strdup(CTX->class);
 
 RETURN:
   if (have_signature) {
     if (ATX->SIG.data != NULL) {
       free(ATX->SIG.data);
       ATX->SIG.data = NULL;
     }
   }
   ATX->signature[0] = 0;
   nt_destroy (ATX->inoc_users);
   nt_destroy (ATX->classify_users);
   if (CTX) {
     if (CTX->signature == &ATX->SIG) {
       CTX->signature = NULL;
     } else if (CTX->signature != NULL) {
@@ -938,46 +940,51 @@
 
   if (
     (USE_LMTP || USE_SMTP) && ! (ATX->flags & DAF_STDOUT) &&
     (!(result == DSR_ISSPAM &&
        _ds_read_attribute(agent_config, "QuarantineAgent") &&
        ATX->PTX && !strcmp(_ds_pref_val(ATX->PTX, "spamAction"), "quarantine")))
   )
   {
     return deliver_socket(ATX, message, (USE_LMTP) ? DDP_LMTP : DDP_SMTP);
   }
 #endif
 
   if (message == NULL)
     return EINVAL;
 
   /* If we're delivering to stdout, we need to provide a classification for
    * use by client/daemon setups where the client needs to know the result
    * in order to support broken returnCodes.s
    */
 
-  if (ATX->sockfd && ATX->flags & DAF_STDOUT)
-    fprintf(stream, "X-Daemon-Classification: %s\n",
-                     (result == DSR_ISSPAM) ? "SPAM" : "INNOCENT");
-
+/* koc patch BEGIN 
+ *
+ *  if (ATX->sockfd && ATX->flags & DAF_STDOUT)
+ *    fprintf(stream, "X-Daemon-Classification: %s\n",
+ *                     (result == DSR_ISSPAM) ? "SPAM" : "INNOCENT");
+ */
   if (mailer_args == NULL) {
-    fputs (message, stream);
+
+/* koc patch BEGIN
+ *  fputs (message, stream); 
+ */
     return 0;
   }
 
   /* Prepare local mailer args and interpolate all special symbols */
 
   args[0] = 0;
   margs = strdup (mailer_args);
   mmargs = margs;
   arg = strsep (&margs, " ");
   while (arg != NULL)
   {
     char a[256], b[256];
 
     /* Destination user */
 
     if (!strcmp (arg, "$u") || !strcmp (arg, "\\$u") ||
         !strcmp (arg, "%u") || !strcmp(arg, "\\%u"))
     {
       strlcpy(a, username, sizeof(a));
     }
@@ -1897,40 +1904,43 @@
 
       if (_ds_match_attribute(agent_config, "Broken", "returnCodes")) {
         if (result == DSR_ISSPAM)
           retcode = 99;
       }
 
       /*
        * Classify Only
        */
 
       if (ATX->operating_mode == DSM_CLASSIFY)
       {
         node_nt = c_nt_next (ATX->users, &c_nt);
         _ds_pref_free(ATX->PTX);
         free(ATX->PTX);
         ATX->PTX = NULL;
         buffer_destroy(parse_message);
         free(presult);
         presult = NULL;
         i++;
+	/* koc patch BEGIN */
+	fprintf(fout, ".\n");
+	/* END */
         continue;
       }
 
       /*
        * Classify and Process
        */
 
       /* Innocent */
 
       if (result != DSR_ISSPAM)
       {
         int deliver = 1;
 
         /* Processing Error */
 
         if (result != DSR_ISINNOCENT        &&
             ATX->classification != DSR_NONE &&
             ATX->classification != DSR_NONE)
         {
           deliver = 0;
@@ -3037,169 +3047,288 @@
 
 /*
  * add_xdspam_headers(DSPAM_CTX *CTX, AGENT_CTX *ATX)
  *
  * DESCRIPTION
  *   Add X-DSPAM headers to the message being processed
  *
  * INPUT ARGUMENTS
  *   CTX          DSPAM context containing message and results
  *   ATX          Agent context defining processing behavior
  *
  * RETURN VALUES
  *   returns 0 on success, standard errors on failure
  */
 
 
 int add_xdspam_headers(DSPAM_CTX *CTX, AGENT_CTX *ATX) {
   struct nt_node *node_nt;
   struct nt_c c_nt;
 
+/* koc patch BEGIN */
+  char *chead;
+  FILE *fout;
+/* END */
+
   node_nt = c_nt_first (CTX->message->components, &c_nt);
   if (node_nt != NULL)
   {
     ds_message_part_t block = node_nt->ptr;
     struct nt_node *node_ft;
     struct nt_c c_ft;
     if (block != NULL && block->headers != NULL)
     {
       ds_header_t head;
       char data[10240];
       char scratch[128];
 
+/* koc patch BEGIN */
+      if (ATX->sockfd) {
+          fout = ATX->sockfd;
+          ATX->sockfd_output = 1;
+      }
+      else {
+          fout = stdout;
+      }
+
+      if ((chead = (char *)calloc(sizeof(char), 1)) == NULL) {
+         LOG (LOG_CRIT, "Create header error: Cannot allocate memory");
+         fprintf(fout, "X-DSPAM-Error: Cannot allocate memory\n");
+         return 0;
+      }
+/* END */
+
       snprintf(data, sizeof(data), "%s: %s",
         (CTX->source == DSS_ERROR) ? "X-DSPAM-Reclassified" : "X-DSPAM-Result",
         CTX->class);
 
       head = _ds_create_header_field(data);
       if (head != NULL)
       {
 #ifdef VERBOSE
         LOGDEBUG ("appending header %s: %s", head->heading, head->data);
 #endif
+
+/* koc patch BEGIN */
+        if ((chead = (char *) realloc (chead, strlen(chead)+strlen(head->heading)+strlen(head->data)+5)) == NULL) {
+            LOG (LOG_CRIT, "Create header error: Cannot allocate memory");
+            fprintf(fout, "X-DSPAM-Error: Cannot allocate memory\n");
+            if (chead) free(chead);
+            return 0;
+        }
+        chead = strcat (chead, head->heading);
+        chead = strcat (chead, ": ");
+        chead = strcat (chead, head->data);
+        chead = strcat (chead, "\\n");
+/* END */
+
         nt_add (block->headers, (void *) head);
       }
       else {
         LOG (LOG_CRIT, ERR_MEM_ALLOC);
       }
 
       if (CTX->source == DSS_NONE) {
         char buf[27];
         time_t t = time(NULL);
         ctime_r(&t, buf);
         chomp(buf);
         snprintf(data, sizeof(data), "X-DSPAM-Processed: %s", buf);
         head = _ds_create_header_field(data);
         if (head != NULL)
         {
 #ifdef VERBOSE
           LOGDEBUG("appending header %s: %s", head->heading, head->data);
 #endif
+
+/* koc patch BEGIN */
+        if ((chead = (char *) realloc (chead, strlen(chead)+strlen(head->heading)+strlen(head->data)+5)) == NULL) {
+            LOG (LOG_CRIT, "Create header error: Cannot allocate memory");
+            fprintf(fout, "X-DSPAM-Error: Cannot allocate memory\n");
+            if (chead) free(chead);
+            return 0;
+        }
+        chead = strcat (chead, head->heading);
+        chead = strcat (chead, ": ");
+        chead = strcat (chead, head->data);
+        chead = strcat (chead, "\\n");
+/* END */                                                 
+
           nt_add(block->headers, (void *) head);
         }
         else
           LOG (LOG_CRIT, ERR_MEM_ALLOC);
       }
 
       if (CTX->source != DSS_ERROR) {
         snprintf(data, sizeof(data), "X-DSPAM-Confidence: %01.4f",
                  CTX->confidence);
         head = _ds_create_header_field(data);
         if (head != NULL)
         {
 #ifdef VERBOSE
           LOGDEBUG("appending header %s: %s", head->heading, head->data);
 #endif
+
+/* koc patch BEGIN */
+        if ((chead = (char *) realloc (chead, strlen(chead)+strlen(head->heading)+strlen(head->data)+5)) == NULL) {
+            LOG (LOG_CRIT, "Create header error: Cannot allocate memory");
+            fprintf(fout, "X-DSPAM-Error: Cannot allocate memory\n");
+            if (chead) free(chead);
+            return 0;
+        }
+        chead = strcat (chead, head->heading);
+        chead = strcat (chead, ": ");
+        chead = strcat (chead, head->data);
+        chead = strcat (chead, "\\n");
+/* END */
+
           nt_add(block->headers, (void *) head);
         }
         else
           LOG (LOG_CRIT, ERR_MEM_ALLOC);
 
         if (_ds_match_attribute(agent_config, "ImprobabilityDrive", "on"))
         {
           float probability = CTX->confidence;
           char *as;
           if (probability > 0.999999)
             probability = 0.999999;
           if (CTX->result == DSR_ISINNOCENT) {
             as = "spam";
           } else {
             as = "ham";
           }
           snprintf(data, sizeof(data), "X-DSPAM-Improbability: 1 in %.0f "
             "chance of being %s",
             1.0+(100*(probability / (1-probability))), as);
           head = _ds_create_header_field(data);
           if (head != NULL)
           {
 #ifdef VERBOSE
             LOGDEBUG("appending header %s: %s", head->heading, head->data);
 #endif
+
+/* koc patch BEGIN */
+        if ((chead = (char *) realloc (chead, strlen(chead)+strlen(head->heading)+strlen(head->data)+5)) == NULL) {
+            LOG (LOG_CRIT, "Create header error: Cannot allocate memory");
+            fprintf(fout, "X-DSPAM-Error: Cannot allocate memory\n");
+            if (chead) free(chead);
+            return 0;
+        }
+        chead = strcat (chead, head->heading);
+        chead = strcat (chead, ": ");
+        chead = strcat (chead, head->data);
+        chead = strcat (chead, "\\n");
+/* END */                                                 
+
             nt_add(block->headers, (void *) head);
           }
           else
             LOG (LOG_CRIT, ERR_MEM_ALLOC);
         }
 
 
         snprintf(data, sizeof(data), "X-DSPAM-Probability: %01.4f",
                  CTX->probability);
 
         head = _ds_create_header_field(data);
         if (head != NULL)
         {
 #ifdef VERBOSE
           LOGDEBUG ("appending header %s: %s", head->heading, head->data);
 #endif
+
+/* koc patch BEGIN */
+        if ((chead = (char *) realloc (chead, strlen(chead)+strlen(head->heading)+strlen(head->data)+5)) == NULL) {
+            LOG (LOG_CRIT, "Create header error: Cannot allocate memory");
+            fprintf(fout, "X-DSPAM-Error: Cannot allocate memory\n");
+            if (chead) free(chead);
+            return 0;
+        }
+        chead = strcat (chead, head->heading);
+        chead = strcat (chead, ": ");
+        chead = strcat (chead, head->data);
+        chead = strcat (chead, "\\n");
+/* END */
+
             nt_add (block->headers, (void *) head);
         }
         else
           LOG (LOG_CRIT, ERR_MEM_ALLOC);
 
         if (CTX->training_mode != DST_NOTRAIN && ATX->signature[0] != 0) {
           snprintf(data, sizeof(data), "X-DSPAM-Signature: %s", ATX->signature);
 
           head = _ds_create_header_field(data);
           if (head != NULL)
           {
             if (strlen(ATX->signature)<5)
             {
               LOGDEBUG("WARNING: Signature not generated, or invalid");
             }
 #ifdef VERBOSE
             LOGDEBUG ("appending header %s: %s", head->heading, head->data);
 #endif
+
+/* koc patch BEGIN */
+        if ((chead = (char *) realloc (chead, strlen(chead)+strlen(head->heading)+strlen(head->data)+5)) == NULL) {
+            LOG (LOG_CRIT, "Create header error: Cannot allocate memory");
+            fprintf(fout, "X-DSPAM-Error: Cannot allocate memory\n");
+            if (chead) free(chead);
+            return 0;
+        }
+        chead = strcat (chead, head->heading);
+        chead = strcat (chead, ": ");
+        chead = strcat (chead, head->data);
+        chead = strcat (chead, "\\n");
+/* END */
+
             nt_add (block->headers, (void *) head);
           }
           else
             LOG (LOG_CRIT, ERR_MEM_ALLOC);
         }
 
         if (CTX->result == DSR_ISSPAM && (ATX->managed_group[0] || (_ds_pref_val(ATX->PTX, "localStore")[0])))
         {
           snprintf(data, sizeof(data), "X-DSPAM-User: %s", CTX->username);
           head = _ds_create_header_field(data);
           if (head != NULL)
           {
 #ifdef VERBOSE
             LOGDEBUG ("appending header %s: %s", head->heading, head->data);
 #endif
+
+/* koc patch BEGIN */
+        if ((chead = (char *) realloc (chead, strlen(chead)+strlen(head->heading)+strlen(head->data)+5)) == NULL) {
+            LOG (LOG_CRIT, "Create header error: Cannot allocate memory");
+            fprintf(fout, "X-DSPAM-Error: Cannot allocate memory\n");
+            if (chead) free(chead);
+            return 0;
+        }
+        chead = strcat (chead, head->heading);
+        chead = strcat (chead, ": ");
+        chead = strcat (chead, head->data);
+        chead = strcat (chead, "\\n");
+/* END */                                                 
+
               nt_add (block->headers, (void *) head);
           }
           else
             LOG (LOG_CRIT, ERR_MEM_ALLOC);
         }
 
         if (!strcmp(_ds_pref_val(ATX->PTX, "showFactors"), "on")) {
 
           if (CTX->factors != NULL) {
             snprintf(data, sizeof(data), "X-DSPAM-Factors: %d",
                      CTX->factors->items);
             node_ft = c_nt_first(CTX->factors, &c_ft);
             while(node_ft != NULL) {
               struct dspam_factor *f = (struct dspam_factor *) node_ft->ptr;
               if (f) {
 	        char *s, *t;
                 strlcat(data, ",\n\t", sizeof(data));
 		s = f->token_name;
 		t = scratch;
 		while (*s && t < scratch + sizeof(scratch) - 16)
@@ -3207,40 +3336,48 @@
 		    *t++ = *s++;
 		  else
 		    t += sprintf(t, "%%%02x", (unsigned char) *s++);
 		snprintf(t, 15, ", %2.5f", f->value);
                 strlcat(data, scratch, sizeof(data));
               }
               node_ft = c_nt_next(CTX->factors, &c_ft);
             }
             head = _ds_create_header_field(data);
             if (head != NULL)
             {
 #ifdef VERBOSE
               LOGDEBUG("appending header %s: %s", head->heading, head->data);
 #endif
               nt_add(block->headers, (void *) head);
             }
           }
         }
 
       } /* CTX->source != DSS_ERROR */
+
+/* koc patch BEGIN */
+      if (strlen(chead) > 3 ) {
+          fprintf(fout, "%s\n", chead);
+      }
+      if (chead) free(chead);
+/* END */
+
     }
   }
   return 0;
 }
 
 /*
  * embed_msgtag(DSPAM_CTX *CTX, AGENT_CTX *ATX)
  *
  * DESCRIPTION
  *   Embed a message tag
  *
  * INPUT ARGUMENTS
  *   CTX          DSPAM context containing the message
  *   ATX          Agent context defining processing behavior
  *
  * RETURN VALUES
  *   returns 0 on success, standard errors on failure
  */
 
 int embed_msgtag(DSPAM_CTX *CTX, AGENT_CTX *ATX) {
