Beispiel #1
0
void
mail_free(struct mail *m)
{
	if (m->attach != NULL)
		attach_free(m->attach);
	if (m->tags != NULL)
		strb_destroy(&m->tags);
	ARRAY_FREE(&m->wrapped);
	m->wrapchar = '\0';

	if (m->auxfree != NULL && m->auxdata != NULL)
		m->auxfree(m->auxdata);
}
Beispiel #2
0
void
attach_free(struct attach *atr)
{
	struct attach	*at;

	while (!TAILQ_EMPTY(&atr->children)) {
		at = TAILQ_FIRST(&atr->children);
		TAILQ_REMOVE(&atr->children, at, entry);
		attach_free(at);
	}

	if (atr->type != NULL)
		xfree(atr->type);
	if (atr->name != NULL)
		xfree(atr->name);
	xfree(atr);
}
Beispiel #3
0
struct attach *
attach_get(struct mail *m, char **ptr, size_t *len, const char *b, int *last)
{
	struct attach	*atr, *at;
	char		*name = NULL, *b2 = NULL;
	size_t		 bl, bl2;
	int		 last2;
	u_int		 n;

	bl = strlen(b);

	atr = xmalloc(sizeof *atr);
	memset(atr, 0, sizeof *atr);
	TAILQ_INIT(&atr->children);

	atr->data = *ptr - m->data;

	while (*ptr != NULL) {
		if (*len >= 13 && strncasecmp(*ptr, "content-type:", 13) == 0)
			break;
		line_next(m, ptr, len);
	}
	if (*ptr == NULL)
		goto error;

	atr->type = attach_type(m, *ptr, "name", &name);
	if (atr->type == NULL) {
		if (name != NULL)
			xfree(name);
		goto error;
	}
	atr->name = name;

	if (strncasecmp(atr->type, "multipart/", 10) != 0) {
		/* Skip the remaining headers. */
		while (*ptr != NULL && *len > 1)
			line_next(m, ptr, len);
		if (*ptr == NULL)
			goto error;

		atr->body = *ptr - m->data;
		for (;;) {
			line_next(m, ptr, len);
			if (*ptr == NULL)
				break;
			if (*len < 3 || (*ptr)[0] != '-' || (*ptr)[1] != '-')
				continue;

			if (*len - 5 == bl && strncmp(*ptr + 2, b, bl) == 0 &&
			    strncmp(*ptr + bl + 2, "--", 2) == 0) {
				*last = 1;
				break;
			}
			if (*len - 3 == bl && strncmp(*ptr + 2, b, bl) == 0)
				break;
		}
		if (*ptr == NULL)
			goto error;

		atr->size = *ptr - m->data - atr->data;
	} else {
		/* XXX avoid doing this twice. */
		xfree(atr->type);
		atr->type = attach_type(m, *ptr, "boundary", &b2);
		if (b2 == NULL)
			goto error;
		bl2 = strlen(b2);

		/* Find the first boundary. */
		while (*ptr != NULL) {
			if ((*ptr)[0] == '-' && (*ptr)[1] == '-') {
				if (*len - 3 == bl2 &&
				    strncmp(*ptr + 2, b2, bl2) == 0)
					break;
			}
			line_next(m, ptr, len);
		}
		if (ptr == NULL)
			goto error;

		/* Now iterate over the rest. */
		last2 = 0;
		n = 0;
		while (*ptr != NULL && !last2) {
			at = attach_get(m, ptr, len, b2, &last2);
			if (at == NULL)
				goto error;
			at->idx = n++;
			at->parent = atr;
			TAILQ_INSERT_TAIL(&atr->children, at, entry);
		}

		/* And skip on to the end of the multipart. */
		while (*ptr != NULL) {
			if ((*ptr)[0] == '-' && (*ptr)[1] == '-') {
				if (*len - 5 == bl2 &&
				    strncmp(*ptr + 2, b2, bl2) == 0)
					break;
			}
			line_next(m, ptr, len);
		}
		if (*ptr == NULL)
			goto error;
		line_next(m, ptr, len);

		xfree(b2);
	}

	return (atr);

error:
	if (b2 != NULL)
		xfree(b2);

	attach_free(atr);
	return (NULL);
}
Beispiel #4
0
struct attach *
attach_build(struct mail *m)
{
	struct attach	*atr = NULL, *at;
	char		*hdr, *ptr, *b = NULL, *type;
	size_t		 len, bl;
	int		 last;
	u_int		 n;

	hdr = find_header(m, "content-type", &len, 0);
	if (hdr == NULL)
		return (NULL);

	type = attach_type(m, hdr, "boundary", &b);
	if (type == NULL || b == NULL) {
		if (type != NULL)
			xfree(type);
		goto error;
	}
	if (strncasecmp(type, "multipart/", 10) != 0) {
		xfree(type);
		goto error;
	}
	bl = strlen(b);

	atr = xmalloc(sizeof *atr);
	memset(atr, 0, sizeof *atr);
	TAILQ_INIT(&atr->children);
	atr->type = type;

	/* Find the first boundary. */
	line_init(m, &ptr, &len);
	while (ptr != NULL) {
		if (ptr[0] == '-' && ptr[1] == '-') {
			if (len - 3 == bl && strncmp(ptr + 2, b, bl) == 0)
				break;
		}
		line_next(m, &ptr, &len);
	}
	if (ptr == NULL)
		goto error;

	/* Now iterate over the rest. */
	last = 0;
	n = 0;
	while (ptr != NULL && !last) {
		if (ptr[0] == '-' && ptr[1] == '-') {
			if (len - 5 == bl && strncmp(ptr + 2, b, bl) == 0)
				break;
		}

		at = attach_get(m, &ptr, &len, b, &last);
		if (at == NULL)
			goto error;
		at->idx = n++;
		at->parent = atr;
		TAILQ_INSERT_TAIL(&atr->children, at, entry);
	}
	if (ptr == NULL)
		goto error;

	xfree(b);
	return (atr);

error:
	if (atr != NULL)
		attach_free(atr);

	if (b != NULL)
		xfree(b);
	return (NULL);
}