Exemple #1
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);
}
static int dorw(struct rfc2045 *p)
{
/* WTF STATIC??? */ int seen_mime=0;
char	buf[256];
int	c;
int	bcnt;

	if (fseek(fdin, p->startpos, SEEK_SET) == -1)	return (-1);
	if (p->parent)
	{
		seen_mime=1;
		if (rwmime(p))	return (-1);
	}
	while (fgets(buf, sizeof(buf), fdin))
	{
		if (buf[0] == '\n')	break;

		if (RFC2045_ISMIME1DEF(p->mime_version) &&
			strncasecmp(buf, "mime-version:", 13) == 0 &&
			!seen_mime)
		{
			seen_mime=1;
			rwmime(p);
			if (strchr(buf, '\n') == NULL)
				while ((c=getc(fdin)) >= 0 && c != '\n')
					;
			while ((c=getc(fdin)) >= 0 && c != '\n' && isspace(c))
				while ((c=getc(fdin)) >= 0 && c != '\n')
					;
			if (c >= 0)	ungetc(c, fdin);
			continue;
		}

		if (!RFC2045_ISMIME1DEF(p->mime_version) || (
			strncasecmp(buf, "mime-version:", 13) &&
			strncasecmp(buf, "content-type:", 13) &&
			strncasecmp(buf, "content-transfer-encoding:", 26))
			)
		{
			do
			{
				do
				{
					if (fdout_add(buf, strlen(buf)))
						return (-1);
				} while (strchr(buf, '\n') == NULL &&
					fgets(buf, sizeof(buf), fdin));

				c=getc(fdin);
				if (c >= 0)	ungetc(c, fdin);
			} while (c >= 0 && c != '\n' && isspace(c) &&
				    fgets(buf, sizeof(buf), fdin));
		}
		else
			while ( (c=getc(fdin)) >= 0 &&
				(ungetc(c, fdin), c) != '\n' && isspace(c))
			{
				while (fgets(buf, sizeof(buf), fdin) &&
					strchr(buf, '\n') == NULL)
					;
			}
	}
	if (RFC2045_ISMIME1DEF(p->mime_version))
	{
		if (!seen_mime)
			if (rwmime(p))	return (-1);

		if (!p->firstpart && p->rw_transfer_encoding)
			if (fdout_autoconverted(p->content_transfer_encoding,
				p->rw_transfer_encoding))	return (-1);
	}

	if (fdout_add("\n", 1))	return (-1);
	if (fseek(fdin, p->startbody, SEEK_SET) == -1)	return (-1);

	/* For non-multipart section, just print the body */

	if (!p->firstpart)
	{
	off_t	ps=p->startbody;
	int	convmode=0;

		if (p->rw_transfer_encoding)
		{
			if ( strcasecmp(p->rw_transfer_encoding,
				"quoted-printable") == 0)
				convmode=RFC2045_RW_7BIT;
			else
				convmode=RFC2045_RW_8BIT;
		}

		conv_err=0;
		if (convmode == RFC2045_RW_7BIT)
		{
			qpe_start();
			rfc2045_cdecode_start(p, &qpe_do, 0);
		}

		if (convmode == RFC2045_RW_8BIT)
		{
			rfc2045_cdecode_start(p, &do_8bit, 0);
		}

		while (ps < p->endbody)
		{
		int	n;

			if (p->endbody - ps > sizeof(buf))
				n=sizeof(buf);
			else	n=p->endbody-ps;
			n=fread(buf, 1, n, fdin);
			if (n <= 0)	return (-1);
			if (convmode)
				rfc2045_cdecode(p, buf, n);
			else	if (fdout_add(buf, n))	conv_err=1;
			ps += n;
			if (conv_err)	break;
		}
		if (convmode == RFC2045_RW_7BIT)
		{
			rfc2045_cdecode_end(p);
			qpe_end();
		}
		if (convmode == RFC2045_RW_8BIT)
		{
			rfc2045_cdecode_end(p);
		}
		if (conv_err)	return (-1);
		return (0);
	}

	bcnt=rw_boundary_cnt;

	/* Sam 8/30/99 fix - handle message/rfc822:

            --boundary
            Content-Type: message/rfc822

         --><-- we're here, DON'T add RFC2045MIMEMSG and rest of crap here
	*/
	if (p->firstpart->next == 0)
	{
	int	rc;

		p->firstpart->parent=0;
		rc=dorw(p->firstpart);
		p->firstpart->parent=p;
		return (rc);
	}

	if (fdout_add(RFC2045MIMEMSG, sizeof(RFC2045MIMEMSG)-1))
		return (-1);
	for (p=p->firstpart; p; p=p->next)
	{
		if (p->isdummy)	continue;
		sprintf(buf, "\n--%s-%d\n", rw_boundary_root, bcnt);
		if (fdout_add(buf, strlen(buf)))	return (-1);
		if (dorw(p) != 0)	return(-1);
	}
	sprintf(buf, "\n--%s-%d--\n", rw_boundary_root, bcnt);
	if (fdout_add(buf, strlen(buf)))	return (-1);
	return (0);
}