masqmail
diff src/header.c @ 0:08114f7dcc23
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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/header.c Fri Sep 26 17:05:23 2008 +0200 1.3 @@ -0,0 +1,259 @@ 1.4 +/* MasqMail 1.5 + Copyright (C) 2000 Oliver Kurth 1.6 + 1.7 + This program is free software; you can redistribute it and/or modify 1.8 + it under the terms of the GNU General Public License as published by 1.9 + the Free Software Foundation; either version 2 of the License, or 1.10 + (at your option) any later version. 1.11 + 1.12 + This program is distributed in the hope that it will be useful, 1.13 + but WITHOUT ANY WARRANTY; without even the implied warranty of 1.14 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.15 + GNU General Public License for more details. 1.16 + 1.17 + You should have received a copy of the GNU General Public License 1.18 + along with this program; if not, write to the Free Software 1.19 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 1.20 +*/ 1.21 +#include "masqmail.h" 1.22 + 1.23 +header_name header_names[] = 1.24 +{ 1.25 + { "From", HEAD_FROM, }, 1.26 + { "Sender", HEAD_SENDER, }, 1.27 + { "To", HEAD_TO, }, 1.28 + { "Cc", HEAD_CC, }, 1.29 + { "Bcc", HEAD_BCC, }, 1.30 + { "Date", HEAD_DATE, }, 1.31 + { "Message-Id", HEAD_MESSAGE_ID, }, 1.32 + { "Reply-To", HEAD_REPLY_TO, }, 1.33 + { "Subject", HEAD_SUBJECT, }, 1.34 + { "Return-Path", HEAD_RETURN_PATH, }, 1.35 + { "Envelope-To", HEAD_ENVELOPE_TO, }, 1.36 + { "Received", HEAD_RECEIVED }, 1.37 +}; 1.38 + 1.39 +/* this was borrowed from exim and slightly changed */ 1.40 +gchar *rec_timestamp() 1.41 +{ 1.42 + static gchar buf[64]; 1.43 + int len; 1.44 + 1.45 + time_t now = time(NULL); 1.46 + struct tm *t = localtime(&now); 1.47 + 1.48 + int diff_hour, diff_min; 1.49 + struct tm local; 1.50 + struct tm *gmt; 1.51 + 1.52 + memcpy(&local, t, sizeof(struct tm)); 1.53 + gmt = gmtime(&now); 1.54 + diff_min = 60*(local.tm_hour - gmt->tm_hour) + local.tm_min - gmt->tm_min; 1.55 + if (local.tm_year != gmt->tm_year) 1.56 + diff_min += (local.tm_year > gmt->tm_year)? 1440 : -1440; 1.57 + else if (local.tm_yday != gmt->tm_yday) 1.58 + diff_min += (local.tm_yday > gmt->tm_yday)? 1440 : -1440; 1.59 + diff_hour = diff_min/60; 1.60 + diff_min = abs(diff_min - diff_hour*60); 1.61 + 1.62 + len = strftime(buf, sizeof(buf), "%a, ", &local); 1.63 + g_snprintf(buf + len, sizeof(buf) - len, "%02d ", local.tm_mday); 1.64 + len += strlen(buf + len); 1.65 + len += strftime(buf + len, sizeof(buf) - len, "%b %Y %H:%M:%S", &local); 1.66 + g_snprintf(buf + len, sizeof(buf) - len, " %+03d%02d", diff_hour, diff_min); 1.67 + 1.68 + return buf; 1.69 +} 1.70 + 1.71 +/* finds list of headers matching id 1.72 + if id == HEAD_UNKNOWN and header == NULL finds all unknown headers 1.73 + else finds all headers matching header 1.74 +*/ 1.75 +GList *find_header(GList *hdr_list, header_id id, gchar *hdr_str) 1.76 +{ 1.77 + GList *found_list = NULL; 1.78 + GList *node; 1.79 + 1.80 + if((id != HEAD_UNKNOWN) || (hdr_str == NULL)){ 1.81 + foreach(hdr_list, node){ 1.82 + header *hdr = (header *)(node->data); 1.83 + if(hdr->id == id) 1.84 + found_list = g_list_append(found_list, hdr); 1.85 + } 1.86 + }else{ 1.87 + foreach(hdr_list, node){ 1.88 + header *hdr = (header *)(node->data); 1.89 + gchar buf[64], *q = buf, *p = hdr->header; 1.90 + 1.91 + while(*p != ':' && q < buf+63 && *p) *(q++) = *(p++); 1.92 + *q = 0; 1.93 + 1.94 + if(strcasecmp(buf, hdr_str) == 0) 1.95 + found_list = g_list_append(found_list, hdr); 1.96 + } 1.97 + } 1.98 + return found_list; 1.99 +} 1.100 + 1.101 +void header_unfold(header *hdr) 1.102 +{ 1.103 + gchar *tmp_hdr = g_malloc(strlen(hdr->header)); 1.104 + gchar *p = hdr->header, *q = tmp_hdr; 1.105 + gboolean flag = FALSE; 1.106 + 1.107 + while(*p){ 1.108 + if(*p != '\n') 1.109 + *(q++) = *p; 1.110 + else 1.111 + flag = TRUE; 1.112 + p++; 1.113 + } 1.114 + *(q++) = '\n'; 1.115 + 1.116 + if(flag){ 1.117 + gchar *new_hdr; 1.118 + 1.119 + g_free(hdr->header); 1.120 + new_hdr = g_strdup(tmp_hdr); 1.121 + g_free(tmp_hdr); 1.122 + hdr->value = new_hdr + (hdr->value - hdr->header); 1.123 + hdr->header = new_hdr; 1.124 + } 1.125 +} 1.126 + 1.127 +#define MAX_HDR_LEN 72 1.128 +void header_fold(header *hdr) 1.129 +{ 1.130 + gint len = strlen(hdr->header); 1.131 + gchar *p, *q; 1.132 + /* size is probably overestimated, but so we are on the safe side */ 1.133 + gchar *tmp_hdr = g_malloc(len + 2*len/MAX_HDR_LEN); 1.134 + 1.135 + p = hdr->header; 1.136 + q = tmp_hdr; 1.137 + 1.138 + if(p[len-1] == '\n') 1.139 + p[len-1] = 0; 1.140 + 1.141 + while(*p){ 1.142 + gint i,l; 1.143 + gchar *pp; 1.144 + 1.145 + /* look forward and find potential break points */ 1.146 + i = 0; l = -1; 1.147 + pp = p; 1.148 + while(*pp && (i < MAX_HDR_LEN)){ 1.149 + if((*pp == ' ') || (*pp == '\t')) 1.150 + l = i; 1.151 + pp++; 1.152 + i++; 1.153 + } 1.154 + if(!*pp) l = pp-p; /* take rest, if EOS found */ 1.155 + 1.156 + if(l == -1){ 1.157 + /* no potential break point was found within MAX_HDR_LEN 1.158 + so advance further until the next */ 1.159 + while(*pp && *pp != ' ' && *pp != '\t'){ 1.160 + pp++; 1.161 + i++; 1.162 + } 1.163 + l = i; 1.164 + } 1.165 + 1.166 + /* copy */ 1.167 + i = 0; 1.168 + while(i < l){ 1.169 + *(q++) = *(p++); 1.170 + i++; 1.171 + } 1.172 + *(q++) = '\n'; 1.173 + *(q++) = *(p++); /* this is either space, tab or 0 */ 1.174 + } 1.175 + { 1.176 + gchar *new_hdr; 1.177 + 1.178 + g_free(hdr->header); 1.179 + new_hdr = g_strdup(tmp_hdr); 1.180 + g_free(tmp_hdr); 1.181 + hdr->value = new_hdr + (hdr->value - hdr->header); 1.182 + hdr->header = new_hdr; 1.183 + } 1.184 +} 1.185 + 1.186 +header *create_header(header_id id, gchar *fmt, ...) 1.187 +{ 1.188 + gchar *p; 1.189 + header *hdr; 1.190 + va_list args; 1.191 + va_start(args, fmt); 1.192 + 1.193 + if((hdr = g_malloc(sizeof(header)))){ 1.194 + 1.195 + hdr->id = id; 1.196 + hdr->header = g_strdup_vprintf(fmt, args); 1.197 + hdr->value = NULL; 1.198 + 1.199 + p = hdr->header; 1.200 + while(*p && *p != ':') p++; 1.201 + if(*p) 1.202 + hdr->value = p+1; 1.203 + } 1.204 + 1.205 + va_end(args); 1.206 + return hdr; 1.207 +} 1.208 + 1.209 +void destroy_header(header *hdr) 1.210 +{ 1.211 + if(hdr){ 1.212 + if(hdr->header) g_free(hdr->header); 1.213 + g_free(hdr); 1.214 + } 1.215 +} 1.216 + 1.217 +header *copy_header(header *hdr) 1.218 +{ 1.219 + header *new_hdr = NULL; 1.220 + 1.221 + if(hdr){ 1.222 + if((new_hdr = g_malloc(sizeof(header)))){ 1.223 + new_hdr->id = hdr->id; 1.224 + new_hdr->header = g_strdup(hdr->header); 1.225 + new_hdr->value = new_hdr->header + (hdr->value - hdr->header); 1.226 + } 1.227 + } 1.228 + return new_hdr; 1.229 +} 1.230 + 1.231 +header *get_header(gchar *line) 1.232 +{ 1.233 + gchar *p = line; 1.234 + gchar buf[64], *q = buf; 1.235 + gint i; 1.236 + header *hdr; 1.237 + 1.238 + while(*p && (*p != ':') && (q < buf+63)) *(q++) = *(p++); 1.239 + *q = 0; 1.240 + 1.241 + if(*p != ':') return NULL; 1.242 + 1.243 + hdr = g_malloc(sizeof(header)); 1.244 + 1.245 + hdr->value = NULL; 1.246 + p++; 1.247 + 1.248 + while(*p && (*p == ' ' || *p == '\t')) p++; 1.249 + hdr->value = p; 1.250 + 1.251 + for(i = 0; i < HEAD_NUM_IDS; i++){ 1.252 + if(strcasecmp(header_names[i].header, buf) == 0) 1.253 + break; 1.254 + } 1.255 + hdr->id = (header_id)i; 1.256 + hdr->header = g_strdup(line); 1.257 + hdr->value = hdr->header + (hdr->value - line); 1.258 + 1.259 + DEBUG(4) debugf("header: %d = %s", hdr->id, hdr->header); 1.260 + 1.261 + return hdr; 1.262 +}