void rewrite(struct rfc2045 *p, int rwmode) { rfc2045_ac_check(p, rwmode); if (rfc2045_rewrite(p, fileno(stdin), fileno(stdout), "reformime (" RFC2045PKG " " RFC2045VER ")")) { perror("reformime"); exit(1); } }
int SubmitFile::MessageEnd(unsigned rcptnum, int iswhitelisted, int filter_enabled) { int is8bit=0, dorewrite=0, rwmode=0; const char *mime=getenv("MIME"); unsigned n; struct stat stat_buf; if (sizelimit && bytecount > sizelimit) { std::cout << "523 Message length (" << sizelimit << " bytes) exceeds administrative limit." << std::endl << std::flush; return (1); } if (diskfull) { std::cout << "431 Mail system full." << std::endl << std::flush; return (1); } if (spamtrap_flag) { std::cout << "550 Spam refused." << std::endl << std::flush; return (1); } if (rwrfcptr->rfcviolation & RFC2045_ERR2COMPLEX) { std::cout << "550 Message MIME complexity exceeds the policy maximum." << std::endl << std::flush; return (1); } datfile << std::flush; if (datfile.fail()) clog_msg_errno(); ctlfile << std::flush; if (ctlfile.fail()) clog_msg_errno(); /* Run global filters for this message */ std::string dfile=namefile("D", 0); if (!mime || strcmp(mime, "none")) { if (mime && strcmp(mime, "7bit") == 0) { rwmode=RFC2045_RW_7BIT; is8bit=0; } if (mime && strcmp(mime, "8bit") == 0) rwmode=RFC2045_RW_8BIT; if (rfc2045_ac_check(rwrfcptr, rwmode)) dorewrite=1; } else (void)rfc2045_ac_check(rwrfcptr, 0); if (rwrfcptr->has8bitchars) is8bit=1; unlink(namefile("D", 1).c_str()); // Might be the GDBM file // if receipients read from headers. if (dorewrite) { int fd1=dup(datfile.fd()); int fd2; if (fd1 < 0) clog_msg_errno(); datfile.close(); if (datfile.fail()) clog_msg_errno(); if ((fd2=open(namefile("D", 1).c_str(), O_RDWR|O_CREAT|O_TRUNC, PERMISSION)) < 0) clog_msg_errno(); if (call_rfc2045_rewrite(rwrfcptr, fd1, fd2, PACKAGE " " VERSION)) { clog_msg_errno(); std::cout << "431 Mail system full." << std::endl << std::flush; return (1); } close(fd1); #if EXPLICITSYNC fsync(fd2); #endif fstat(fd2, &stat_buf); close(fd2); std::string p=namefile("D", 0); unlink(p.c_str()); if (rename(namefile("D", 1).c_str(), p.c_str()) != 0) clog_msg_errno(); } else { datfile.sync(); #if EXPLICITSYNC fsync(datfile.fd()); #endif fstat(datfile.fd(), &stat_buf); datfile.close(); if (datfile.fail()) clog_msg_errno(); } if (is8bit) { ctlfile << COMCTLFILE_8BIT << "\n" << std::flush; closectl(); if (num_control_files_created > 1) { for (n=1; n < num_control_files_created; n++) { std::string p=namefile("C", n); int nfd=open(p.c_str(), O_WRONLY | O_APPEND); if (nfd < 0) clog_msg_errno(); ctlfile.fd(nfd); ctlfile << COMCTLFILE_8BIT << "\n" << std::flush; if (ctlfile.fail()) clog_msg_errno(); #if EXPLICITSYNC ctlfile.sync(); fsync(ctlfile.fd()); #endif ctlfile.close(); if (ctlfile.fail()) clog_msg_errno(); } } } else { closectl(); } SubmitFile *voidp=this; if (filter_enabled && run_filter(dfile.c_str(), num_control_files_created, iswhitelisted, &SubmitFile::get_msgid_for_filtering, &voidp)) return (1); std::string cfile=namefile("C", 0); for (n=2; n <= num_control_files_created; n++) { if (link(dfile.c_str(), namefile("D", n).c_str()) != 0) clog_msg_errno(); } std::string okmsg("250 Ok. "); okmsg += basemsgid; int hasxerror=datafilter(dfile.c_str(), rcptnum, okmsg.c_str()); current_submit_file=0; if (num_control_files_created == 1) { if (rename(name1stctlfile().c_str(), cfile.c_str()) != 0) clog_msg_errno(); } else { if (rename(namefile("C", 1).c_str(), cfile.c_str()) != 0) clog_msg_errno(); } if (!hasxerror) { #if EXPLICITDIRSYNC size_t p=cfile.rfind('/'); if (p != std::string::npos) { std::string dir=cfile.substr(0, p); int fd=open(dir.c_str(), O_RDONLY); if (fd >= 0) { fsync(fd); close(fd); } } #endif std::cout << okmsg << std::endl << std::flush; } trigger(TRIGGER_NEWMSG); return (0); }
int rfc2045_ac_check(struct rfc2045 *p, int rwmode) { int flag=0; /* Flag - rewriting suggested */ struct rfc2045 *c; int hasnon7bit=p->has8bitchars; /* hasnon7bit: 8bit chars in this section or subsections */ const char *te; int is8bitte; for (c=p->firstpart; c; c=c->next) if (!c->isdummy) { if (rfc2045_ac_check(c, rwmode)) flag=1; if (strcmp(c->content_transfer_encoding, "7bit") && strcmp(c->content_transfer_encoding, "quoted-printable")) hasnon7bit=1; if (c->has8bitchars) p->has8bitchars=1; } if (RFC2045_ISMIME1DEF(p->mime_version) && !p->content_type) { if ((p->content_type=strdup("text/plain")) == 0) rfc2045_enomem(); if (p->mime_version) { flag=1; } } if (RFC2045_ISMIME1DEF(p->mime_version) && !rfc2045_getattr(p->content_type_attr, "charset") && strncasecmp(p->content_type, "text/", 5) == 0) { rfc2045_setattr(&p->content_type_attr, "charset", rfc2045_getdefaultcharset()); if (p->mime_version && p->firstpart == 0 /* sam - don't trigger rewrites on changes to multipart headers */ ) { flag=1; } } if (RFC2045_ISMIME1DEF(p->mime_version) && !p->content_transfer_encoding) { if ((p->content_transfer_encoding=strdup( hasnon7bit ? "8bit":"7bit")) == 0) rfc2045_enomem(); if (p->mime_version && p->firstpart == 0 /* sam - don't trigger rewrites on changes to multipart headers */ ) { flag=1; } } #if 0 if (RFC2045_ISMIME1DEF(p->mime_version) && strncmp(p->content_type, "text/", 5) == 0 && !hasnon7bit && strcmp(p->content_transfer_encoding, "7bit")) { if (p->mime_version) { flag=1; } } #endif if (RFC2045_ISMIME1DEF(p->mime_version)) { /* Check for conversions */ te=p->content_transfer_encoding; is8bitte=strcasecmp(te, "base64") && strcasecmp(te, "quoted-printable") && strcasecmp(te, "7bit"); /* 8 bit contents */ if (is8bitte && !p->has8bitchars && !p->haslongline) { if (p->rw_transfer_encoding) free(p->rw_transfer_encoding); if ((p->rw_transfer_encoding=strdup("7bit")) == 0) rfc2045_enomem(); flag=1; is8bitte=0; } if (rwmode == RFC2045_RW_7BIT && (is8bitte || p->haslongline)) { if (p->rw_transfer_encoding) free(p->rw_transfer_encoding); if ((p->rw_transfer_encoding=strdup("quoted-printable")) == 0) rfc2045_enomem(); flag=1; } else if (rwmode == RFC2045_RW_8BIT && strcasecmp(te, "quoted-printable") == 0 && !p->haslongline) { if (p->rw_transfer_encoding) free(p->rw_transfer_encoding); if ((p->rw_transfer_encoding=strdup(hasnon7bit ? "8bit":"7bit")) == 0) rfc2045_enomem(); flag=1; } } if (!p->mime_version) { if ((p->mime_version=strdup("1.0")) == 0) rfc2045_enomem(); } return (flag); }