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@0: header_name header_names[] = meillo@0: { meillo@0: { "From", HEAD_FROM, }, meillo@0: { "Sender", HEAD_SENDER, }, meillo@0: { "To", HEAD_TO, }, meillo@0: { "Cc", HEAD_CC, }, meillo@0: { "Bcc", HEAD_BCC, }, meillo@0: { "Date", HEAD_DATE, }, meillo@0: { "Message-Id", HEAD_MESSAGE_ID, }, meillo@0: { "Reply-To", HEAD_REPLY_TO, }, meillo@0: { "Subject", HEAD_SUBJECT, }, meillo@0: { "Return-Path", HEAD_RETURN_PATH, }, meillo@0: { "Envelope-To", HEAD_ENVELOPE_TO, }, meillo@0: { "Received", HEAD_RECEIVED }, meillo@0: }; meillo@0: meillo@0: /* this was borrowed from exim and slightly changed */ meillo@0: gchar *rec_timestamp() meillo@0: { meillo@0: static gchar buf[64]; meillo@0: int len; meillo@0: meillo@0: time_t now = time(NULL); meillo@0: struct tm *t = localtime(&now); meillo@0: meillo@0: int diff_hour, diff_min; meillo@0: struct tm local; meillo@0: struct tm *gmt; meillo@0: meillo@0: memcpy(&local, t, sizeof(struct tm)); meillo@0: gmt = gmtime(&now); meillo@0: diff_min = 60*(local.tm_hour - gmt->tm_hour) + local.tm_min - gmt->tm_min; meillo@0: if (local.tm_year != gmt->tm_year) meillo@0: diff_min += (local.tm_year > gmt->tm_year)? 1440 : -1440; meillo@0: else if (local.tm_yday != gmt->tm_yday) meillo@0: diff_min += (local.tm_yday > gmt->tm_yday)? 1440 : -1440; meillo@0: diff_hour = diff_min/60; meillo@0: diff_min = abs(diff_min - diff_hour*60); meillo@0: meillo@0: len = strftime(buf, sizeof(buf), "%a, ", &local); meillo@0: g_snprintf(buf + len, sizeof(buf) - len, "%02d ", local.tm_mday); meillo@0: len += strlen(buf + len); meillo@0: len += strftime(buf + len, sizeof(buf) - len, "%b %Y %H:%M:%S", &local); meillo@0: g_snprintf(buf + len, sizeof(buf) - len, " %+03d%02d", diff_hour, diff_min); meillo@0: meillo@0: 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@0: GList *find_header(GList *hdr_list, header_id id, gchar *hdr_str) meillo@0: { meillo@0: GList *found_list = NULL; meillo@0: GList *node; meillo@0: meillo@0: if((id != HEAD_UNKNOWN) || (hdr_str == NULL)){ meillo@0: foreach(hdr_list, node){ meillo@0: header *hdr = (header *)(node->data); meillo@0: if(hdr->id == id) meillo@0: found_list = g_list_append(found_list, hdr); meillo@0: } meillo@0: }else{ meillo@0: foreach(hdr_list, node){ meillo@0: header *hdr = (header *)(node->data); meillo@0: gchar buf[64], *q = buf, *p = hdr->header; meillo@0: meillo@0: while(*p != ':' && q < buf+63 && *p) *(q++) = *(p++); meillo@0: *q = 0; meillo@0: meillo@0: if(strcasecmp(buf, hdr_str) == 0) meillo@0: found_list = g_list_append(found_list, hdr); meillo@0: } meillo@0: } meillo@0: return found_list; meillo@0: } meillo@0: meillo@0: void header_unfold(header *hdr) meillo@0: { meillo@0: gchar *tmp_hdr = g_malloc(strlen(hdr->header)); meillo@0: gchar *p = hdr->header, *q = tmp_hdr; meillo@0: gboolean flag = FALSE; meillo@0: meillo@0: while(*p){ meillo@0: if(*p != '\n') meillo@0: *(q++) = *p; meillo@0: else meillo@0: flag = TRUE; meillo@0: p++; meillo@0: } meillo@0: *(q++) = '\n'; meillo@0: meillo@0: if(flag){ meillo@0: gchar *new_hdr; meillo@0: meillo@0: g_free(hdr->header); meillo@0: new_hdr = g_strdup(tmp_hdr); meillo@0: g_free(tmp_hdr); meillo@0: hdr->value = new_hdr + (hdr->value - hdr->header); meillo@0: hdr->header = new_hdr; meillo@0: } meillo@0: } meillo@0: meillo@0: #define MAX_HDR_LEN 72 meillo@0: void header_fold(header *hdr) meillo@0: { meillo@0: gint len = strlen(hdr->header); meillo@0: gchar *p, *q; meillo@0: /* size is probably overestimated, but so we are on the safe side */ meillo@0: gchar *tmp_hdr = g_malloc(len + 2*len/MAX_HDR_LEN); meillo@0: meillo@0: p = hdr->header; meillo@0: q = tmp_hdr; meillo@0: meillo@0: if(p[len-1] == '\n') meillo@0: p[len-1] = 0; meillo@0: meillo@0: while(*p){ meillo@0: gint i,l; meillo@0: gchar *pp; meillo@0: meillo@0: /* look forward and find potential break points */ meillo@0: i = 0; l = -1; meillo@0: pp = p; meillo@0: while(*pp && (i < MAX_HDR_LEN)){ meillo@0: if((*pp == ' ') || (*pp == '\t')) meillo@0: l = i; meillo@0: pp++; meillo@0: i++; meillo@0: } meillo@0: if(!*pp) l = pp-p; /* take rest, if EOS found */ meillo@0: meillo@0: if(l == -1){ meillo@0: /* no potential break point was found within MAX_HDR_LEN meillo@0: so advance further until the next */ meillo@0: while(*pp && *pp != ' ' && *pp != '\t'){ meillo@0: pp++; meillo@0: i++; meillo@0: } meillo@0: l = i; meillo@0: } meillo@0: meillo@0: /* copy */ meillo@0: i = 0; meillo@0: while(i < l){ meillo@0: *(q++) = *(p++); meillo@0: i++; meillo@0: } meillo@0: *(q++) = '\n'; meillo@0: *(q++) = *(p++); /* this is either space, tab or 0 */ meillo@0: } meillo@0: { meillo@0: gchar *new_hdr; meillo@0: meillo@0: g_free(hdr->header); meillo@0: new_hdr = g_strdup(tmp_hdr); meillo@0: g_free(tmp_hdr); meillo@0: hdr->value = new_hdr + (hdr->value - hdr->header); meillo@0: hdr->header = new_hdr; meillo@0: } meillo@0: } meillo@0: meillo@0: header *create_header(header_id id, gchar *fmt, ...) meillo@0: { meillo@0: gchar *p; meillo@0: header *hdr; meillo@0: va_list args; meillo@0: va_start(args, fmt); meillo@0: meillo@0: if((hdr = g_malloc(sizeof(header)))){ meillo@0: meillo@0: hdr->id = id; meillo@0: hdr->header = g_strdup_vprintf(fmt, args); meillo@0: hdr->value = NULL; meillo@0: meillo@0: p = hdr->header; meillo@0: while(*p && *p != ':') p++; meillo@0: if(*p) meillo@0: hdr->value = p+1; meillo@0: } meillo@0: meillo@0: va_end(args); meillo@0: return hdr; meillo@0: } meillo@0: meillo@0: void destroy_header(header *hdr) meillo@0: { meillo@0: if(hdr){ meillo@0: if(hdr->header) g_free(hdr->header); meillo@0: g_free(hdr); meillo@0: } meillo@0: } meillo@0: meillo@0: header *copy_header(header *hdr) meillo@0: { meillo@0: header *new_hdr = NULL; meillo@0: meillo@0: if(hdr){ meillo@0: if((new_hdr = g_malloc(sizeof(header)))){ meillo@0: new_hdr->id = hdr->id; meillo@0: new_hdr->header = g_strdup(hdr->header); meillo@0: new_hdr->value = new_hdr->header + (hdr->value - hdr->header); meillo@0: } meillo@0: } meillo@0: return new_hdr; meillo@0: } meillo@0: meillo@0: header *get_header(gchar *line) meillo@0: { meillo@0: gchar *p = line; meillo@0: gchar buf[64], *q = buf; meillo@0: gint i; meillo@0: header *hdr; meillo@0: meillo@0: while(*p && (*p != ':') && (q < buf+63)) *(q++) = *(p++); meillo@0: *q = 0; meillo@0: meillo@0: if(*p != ':') return NULL; meillo@0: meillo@0: hdr = g_malloc(sizeof(header)); meillo@0: meillo@0: hdr->value = NULL; meillo@0: p++; meillo@0: meillo@0: while(*p && (*p == ' ' || *p == '\t')) p++; meillo@0: hdr->value = p; meillo@0: meillo@0: for(i = 0; i < HEAD_NUM_IDS; i++){ meillo@0: if(strcasecmp(header_names[i].header, buf) == 0) meillo@0: break; meillo@0: } meillo@0: hdr->id = (header_id)i; meillo@0: hdr->header = g_strdup(line); meillo@0: hdr->value = hdr->header + (hdr->value - line); meillo@0: meillo@0: DEBUG(4) debugf("header: %d = %s", hdr->id, hdr->header); meillo@0: meillo@0: return hdr; meillo@0: }