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); }
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); }
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); }
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); }