meillo@0: /* MasqMail meillo@0: Copyright (C) 2000 Oliver Kurth meillo@0: meillo@0: This program is free software; you can redistribute it and/or modify meillo@0: it under the terms of the GNU General Public License as published by meillo@0: the Free Software Foundation; either version 2 of the License, or meillo@0: (at your option) any later version. meillo@0: meillo@0: This program is distributed in the hope that it will be useful, meillo@0: but WITHOUT ANY WARRANTY; without even the implied warranty of meillo@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the meillo@0: GNU General Public License for more details. meillo@0: meillo@0: You should have received a copy of the GNU General Public License meillo@0: along with this program; if not, write to the Free Software meillo@0: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. meillo@0: */ meillo@0: #include "masqmail.h" meillo@0: meillo@10: header_name header_names[] = { meillo@10: {"From", HEAD_FROM,} meillo@10: , meillo@10: {"Sender", HEAD_SENDER,} meillo@10: , meillo@10: {"To", HEAD_TO,} meillo@10: , meillo@10: {"Cc", HEAD_CC,} meillo@10: , meillo@10: {"Bcc", HEAD_BCC,} meillo@10: , meillo@10: {"Date", HEAD_DATE,} meillo@10: , meillo@10: {"Message-Id", HEAD_MESSAGE_ID,} meillo@10: , meillo@10: {"Reply-To", HEAD_REPLY_TO,} meillo@10: , meillo@10: {"Subject", HEAD_SUBJECT,} meillo@10: , meillo@10: {"Return-Path", HEAD_RETURN_PATH,} meillo@10: , meillo@10: {"Envelope-To", HEAD_ENVELOPE_TO,} meillo@10: , meillo@10: {"Received", HEAD_RECEIVED} meillo@10: , meillo@0: }; meillo@0: meillo@0: /* this was borrowed from exim and slightly changed */ meillo@10: gchar* meillo@10: rec_timestamp() meillo@0: { meillo@10: static gchar buf[64]; meillo@10: int len; meillo@0: meillo@10: time_t now = time(NULL); meillo@10: struct tm *t = localtime(&now); meillo@0: meillo@10: int diff_hour, diff_min; meillo@10: struct tm local; meillo@10: struct tm *gmt; meillo@0: meillo@10: memcpy(&local, t, sizeof(struct tm)); meillo@10: gmt = gmtime(&now); meillo@10: diff_min = 60 * (local.tm_hour - gmt->tm_hour) + local.tm_min - gmt->tm_min; meillo@10: if (local.tm_year != gmt->tm_year) meillo@10: diff_min += (local.tm_year > gmt->tm_year) ? 1440 : -1440; meillo@10: else if (local.tm_yday != gmt->tm_yday) meillo@10: diff_min += (local.tm_yday > gmt->tm_yday) ? 1440 : -1440; meillo@10: diff_hour = diff_min / 60; meillo@10: diff_min = abs(diff_min - diff_hour * 60); meillo@0: meillo@10: len = strftime(buf, sizeof(buf), "%a, ", &local); meillo@10: g_snprintf(buf + len, sizeof(buf) - len, "%02d ", local.tm_mday); meillo@10: len += strlen(buf + len); meillo@10: len += strftime(buf + len, sizeof(buf) - len, "%b %Y %H:%M:%S", &local); meillo@10: g_snprintf(buf + len, sizeof(buf) - len, " %+03d%02d", diff_hour, diff_min); meillo@10: meillo@10: return buf; meillo@0: } meillo@0: meillo@0: /* finds list of headers matching id meillo@0: if id == HEAD_UNKNOWN and header == NULL finds all unknown headers meillo@0: else finds all headers matching header meillo@0: */ meillo@10: GList* meillo@10: find_header(GList * hdr_list, header_id id, gchar * hdr_str) meillo@0: { meillo@10: GList *found_list = NULL; meillo@10: GList *node; meillo@0: meillo@10: if ((id != HEAD_UNKNOWN) || (hdr_str == NULL)) { meillo@10: foreach(hdr_list, node) { meillo@10: header *hdr = (header *) (node->data); meillo@10: if (hdr->id == id) meillo@10: found_list = g_list_append(found_list, hdr); meillo@10: } meillo@10: } else { meillo@10: foreach(hdr_list, node) { meillo@10: header *hdr = (header *) (node->data); meillo@10: gchar buf[64], *q = buf, *p = hdr->header; meillo@10: meillo@10: while (*p != ':' && q < buf + 63 && *p) meillo@10: *(q++) = *(p++); meillo@10: *q = 0; meillo@10: meillo@10: if (strcasecmp(buf, hdr_str) == 0) meillo@10: found_list = g_list_append(found_list, hdr); meillo@10: } meillo@10: } meillo@10: return found_list; meillo@0: } meillo@0: meillo@10: void meillo@10: header_unfold(header * hdr) meillo@0: { meillo@10: gchar *tmp_hdr = g_malloc(strlen(hdr->header)); meillo@10: gchar *p = hdr->header, *q = tmp_hdr; meillo@10: gboolean flag = FALSE; meillo@0: meillo@10: while (*p) { meillo@10: if (*p != '\n') meillo@10: *(q++) = *p; meillo@10: else meillo@10: flag = TRUE; meillo@10: p++; meillo@10: } meillo@10: *(q++) = '\n'; meillo@0: meillo@10: if (flag) { meillo@10: gchar *new_hdr; meillo@0: meillo@10: g_free(hdr->header); meillo@10: new_hdr = g_strdup(tmp_hdr); meillo@10: g_free(tmp_hdr); meillo@10: hdr->value = new_hdr + (hdr->value - hdr->header); meillo@10: hdr->header = new_hdr; meillo@10: } meillo@0: } meillo@0: meillo@0: #define MAX_HDR_LEN 72 meillo@10: void meillo@10: header_fold(header * hdr) meillo@0: { meillo@10: gint len = strlen(hdr->header); meillo@10: gchar *p, *q; meillo@10: /* size is probably overestimated, but so we are on the safe side */ meillo@10: gchar *tmp_hdr = g_malloc(len + 2 * len / MAX_HDR_LEN); meillo@0: meillo@10: p = hdr->header; meillo@10: q = tmp_hdr; meillo@0: meillo@10: if (p[len - 1] == '\n') meillo@10: p[len - 1] = 0; meillo@0: meillo@10: while (*p) { meillo@10: gint i, l; meillo@10: gchar *pp; meillo@0: meillo@10: /* look forward and find potential break points */ meillo@10: i = 0; meillo@10: l = -1; meillo@10: pp = p; meillo@10: while (*pp && (i < MAX_HDR_LEN)) { meillo@10: if ((*pp == ' ') || (*pp == '\t')) meillo@10: l = i; meillo@10: pp++; meillo@10: i++; meillo@10: } meillo@10: if (!*pp) meillo@10: l = pp - p; /* take rest, if EOS found */ meillo@0: meillo@10: if (l == -1) { meillo@10: /* no potential break point was found within MAX_HDR_LEN so advance further until the next */ meillo@10: while (*pp && *pp != ' ' && *pp != '\t') { meillo@10: pp++; meillo@10: i++; meillo@10: } meillo@10: l = i; meillo@10: } meillo@10: meillo@10: /* copy */ meillo@10: i = 0; meillo@10: while (i < l) { meillo@10: *(q++) = *(p++); meillo@10: i++; meillo@10: } meillo@10: *(q++) = '\n'; meillo@10: *(q++) = *(p++); /* this is either space, tab or 0 */ meillo@10: } meillo@10: { meillo@10: gchar *new_hdr; meillo@10: meillo@10: g_free(hdr->header); meillo@10: new_hdr = g_strdup(tmp_hdr); meillo@10: g_free(tmp_hdr); meillo@10: hdr->value = new_hdr + (hdr->value - hdr->header); meillo@10: hdr->header = new_hdr; meillo@10: } meillo@0: } meillo@0: meillo@10: header* meillo@10: create_header(header_id id, gchar * fmt, ...) meillo@0: { meillo@10: gchar *p; meillo@10: header *hdr; meillo@10: va_list args; meillo@10: va_start(args, fmt); meillo@0: meillo@10: if ((hdr = g_malloc(sizeof(header)))) { meillo@0: meillo@10: hdr->id = id; meillo@10: hdr->header = g_strdup_vprintf(fmt, args); meillo@10: hdr->value = NULL; meillo@0: meillo@10: p = hdr->header; meillo@10: while (*p && *p != ':') meillo@10: p++; meillo@10: if (*p) meillo@10: hdr->value = p + 1; meillo@10: } meillo@0: meillo@10: va_end(args); meillo@10: return hdr; meillo@0: } meillo@0: meillo@10: void meillo@10: destroy_header(header * hdr) meillo@0: { meillo@10: if (hdr) { meillo@10: if (hdr->header) meillo@10: g_free(hdr->header); meillo@10: g_free(hdr); meillo@10: } meillo@0: } meillo@0: meillo@10: header* meillo@10: copy_header(header * hdr) meillo@0: { meillo@10: header *new_hdr = NULL; meillo@0: meillo@10: if (hdr) { meillo@10: if ((new_hdr = g_malloc(sizeof(header)))) { meillo@10: new_hdr->id = hdr->id; meillo@10: new_hdr->header = g_strdup(hdr->header); meillo@10: new_hdr->value = new_hdr->header + (hdr->value - hdr->header); meillo@10: } meillo@10: } meillo@10: return new_hdr; meillo@0: } meillo@0: meillo@10: header* meillo@10: get_header(gchar * line) meillo@0: { meillo@10: gchar *p = line; meillo@10: gchar buf[64], *q = buf; meillo@10: gint i; meillo@10: header *hdr; meillo@0: meillo@10: while (*p && (*p != ':') && (q < buf + 63)) meillo@10: *(q++) = *(p++); meillo@10: *q = 0; meillo@0: meillo@10: if (*p != ':') meillo@10: return NULL; meillo@0: meillo@10: hdr = g_malloc(sizeof(header)); meillo@0: meillo@10: hdr->value = NULL; meillo@10: p++; meillo@0: meillo@10: while (*p && (*p == ' ' || *p == '\t')) meillo@10: p++; meillo@10: hdr->value = p; meillo@0: meillo@10: for (i = 0; i < HEAD_NUM_IDS; i++) { meillo@10: if (strcasecmp(header_names[i].header, buf) == 0) meillo@10: break; meillo@10: } meillo@10: hdr->id = (header_id) i; meillo@10: hdr->header = g_strdup(line); meillo@10: hdr->value = hdr->header + (hdr->value - line); meillo@10: meillo@10: DEBUG(4) debugf("header: %d = %s", hdr->id, hdr->header); meillo@10: meillo@10: return hdr; meillo@0: }