Example #1
0
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);
	}
}
Example #2
0
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);
}
Example #3
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);
}