Mercurial > masqmail-0.2
view 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 source
/* 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; }