void write_message(rc_t status) { readfunc_t rf = NULL; /* assignment to quench warning */ void *rfarg = 0; /* assignment to quench warning */ textdata_t *text; bool seen_subj = false; build_spam_header(); if (!passthrough) { write_spam_info(); } else { eol = NULL; /* initialize */ rf = read_mem; text = textblock_head(); rfarg = &text; seen_subj = write_header(status, rf, rfarg); if (!seen_subj) { if (status == RC_SPAM && spam_subject_tag != NULL) (void) fprintf(fpo, "Subject: %s%s", spam_subject_tag, eol); if (status == RC_UNSURE && unsure_subject_tag != NULL) (void) fprintf(fpo, "Subject: %s%s", unsure_subject_tag, eol); } write_body(rf, rfarg); if (verbose || Rtable) { if (fflush(fpo) || ferror(fpo)) cleanup_exit(EX_ERROR, 1); } } return; }
void write_message(rc_t status) { ssize_t rd; readfunc_t rf = NULL; /* assignment to quench warning */ void *rfarg = 0; /* assignment to quench warning */ char *out; textdata_t *text; int seen_subj = 0; if (passthrough) { int hadlf = 1; int bogolen = strlen(spam_header_name); const char *subjstr = "Subject:"; int subjlen = strlen(subjstr); /* initialize */ switch (passmode) { case PASS_MEM: rf = read_mem; text = textblock_head(); rfarg = &text; break; case PASS_SEEK: rf = read_seek; rfarg = fpin; rewind(rfarg); break; default: abort(); } /* print headers */ while ((rd = rf(&out, rfarg)) > 0) { /* skip over spam_header ("X-Bogosity:") lines */ while (rd >= bogolen && memcmp(out, spam_header_name, bogolen) == 0) { while (((rd = rf(&out, rfarg)) > 0) && (out[0] == ' ' || out[0] == '\t') ) /* empty loop */ ; } /* detect end of headers */ if (is_eol(out, rd) || is_hb_delim(out, rd, have_body)) /* check for non-empty blank line */ break; /* rewrite "Subject: " line */ if (status == RC_SPAM && rd >= subjlen && spam_subject_tag != NULL && strncasecmp(out, subjstr, subjlen) == 0) { (void) fprintf(fpo, "%.*s %s", subjlen, out, spam_subject_tag); if (out[subjlen] != ' ') fputc(' ', fpo); (void) fwrite(out + subjlen, 1, rd - subjlen, fpo); seen_subj = 1; continue; } hadlf = (out[rd-1] == '\n'); (void) fwrite(out, 1, rd, fpo); if (ferror(fpo)) cleanup_exit(2, 1); } if (!hadlf) fputc('\n', fpo); } if (passthrough || verbose || terse) { typedef char *formatter(char *buff, size_t size); formatter *fcn = terse ? format_terse : format_header; char buff[256]; /* print spam-status at the end of the header * then mark the beginning of the message body */ (*fcn)(buff, sizeof(buff)); fputs (buff, fpo); fputs ("\n", fpo); } if (verbose || passthrough || Rtable) { verbose += passthrough; print_stats( stdout ); verbose -= passthrough; } if (passthrough && !seen_subj && status == RC_SPAM && spam_subject_tag != NULL) { (void) fprintf(fpo, "Subject: %s\n", spam_subject_tag); } if (passthrough) { int hadlf = 1; /* If the message terminated early (without body or blank * line between header and body), enforce a blank line to * prevent anything past us from choking. */ (void)fputc('\n', fpo); /* print body */ while ((rd = rf(&out, rfarg)) > 0) { (void) fwrite(out, 1, rd, fpo); hadlf = (out[rd-1] == '\n'); if (ferror(fpo)) cleanup_exit(2, 1); } if (!hadlf) fputc('\n', fpo); if (fflush(fpo) || ferror(fpo) || (fpo != stdout && fclose(fpo))) { cleanup_exit(2, 1); } } }