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