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