masqmail

changeset 303:3e3c280ca5b2

replaced header_fold() with a better implementation
author markus schnalke <meillo@marmaro.de>
date Thu, 09 Dec 2010 18:01:46 -0300
parents 2ffcd38ccf53
children d5ce2ba71e7b
files src/accept.c src/header.c src/masqmail.h
diffstat 3 files changed, 66 insertions(+), 61 deletions(-) [+]
line diff
     1.1 --- a/src/accept.c	Thu Dec 09 17:50:25 2010 -0300
     1.2 +++ b/src/accept.c	Thu Dec 09 18:01:46 2010 -0300
     1.3 @@ -362,7 +362,7 @@
     1.4  
     1.5  	if (g_list_length(msg->rcpt_list) == 1) {
     1.6  		address *addr = (address *) (g_list_first(msg->rcpt_list)->data);
     1.7 -		for_string = g_strdup_printf("\n\tfor %s", addr_string(addr));
     1.8 +		for_string = g_strdup_printf(" for %s", addr_string(addr));
     1.9  	}
    1.10  
    1.11  	if (!msg->received_host) {
    1.12 @@ -390,7 +390,7 @@
    1.13  		    msg->uid, for_string ? for_string : "", rec_timestamp());
    1.14  #endif
    1.15  	}
    1.16 -	header_fold(hdr);
    1.17 +	header_fold(hdr, 78);
    1.18  	msg->hdr_list = g_list_prepend(msg->hdr_list, hdr);
    1.19  
    1.20  	if (for_string)
     2.1 --- a/src/header.c	Thu Dec 09 17:50:25 2010 -0300
     2.2 +++ b/src/header.c	Thu Dec 09 18:01:46 2010 -0300
     2.3 @@ -128,78 +128,83 @@
     2.4          *(dest++) = '\0';
     2.5  }
     2.6  
     2.7 -#define MAX_HDR_LEN 72
     2.8 +/*
     2.9 +   fold the header at maxlen chars (newline excluded)
    2.10 +   (We exclude the newline because the RFCs deal with it this way)
    2.11 +*/
    2.12  void
    2.13 -header_fold(header * hdr)
    2.14 +header_fold(header* hdr, unsigned int maxlen)
    2.15  {
    2.16 -	gint len = strlen(hdr->header);
    2.17 -	gchar *p, *q;
    2.18 -	gchar *tmp_hdr;
    2.19 +	int len = strlen(hdr->header);
    2.20 +	char* src = hdr->header;
    2.21 +	char* dest;
    2.22 +	char* tmp;
    2.23 +	char* p;
    2.24  	int valueoffset;
    2.25  
    2.26 -	if (len < MAX_HDR_LEN) {
    2.27 +	if (len <= maxlen) {
    2.28  		/* we don't need to do anything */
    2.29  		return;
    2.30  	}
    2.31  
    2.32 -	/* the position in hdr->header where the value part starts */
    2.33 +	/* strip trailing whitespace */
    2.34 +	for (p=src+len-1; *p==' '||*p=='\t'||*p=='\n'; p--) {
    2.35 +		*p = '\0';
    2.36 +		len--;
    2.37 +		printf("  trailing whitespace\n");
    2.38 +	}
    2.39 +	printf("stripped len: %d\n", len);
    2.40 +
    2.41 +	/* FIXME: would be nice to have a better size calculation */
    2.42 +	/* (the current size + what we insert as break, twice as often as
    2.43 +	    we have breaks in the optimal case) */
    2.44 +	tmp = malloc(len + 2 * (len/maxlen) * strlen("\n\t"));
    2.45 +	dest = tmp;
    2.46 +
    2.47 +	/* the position in hdr->header where the value part start */
    2.48  	valueoffset = hdr->value - hdr->header;
    2.49  
    2.50 -	/* TODO: size is only calculated roughly */
    2.51 -	/* size is probably overestimated, but so we are on the safe side */
    2.52 -	/* (as much as we already have + chars inserted per break * number
    2.53 -	    of breaks + some more) */
    2.54 -	tmp_hdr = g_malloc(len + 2 * (len/MAX_HDR_LEN) + 10);
    2.55 +	while (strlen(src) > maxlen) {
    2.56 +		int i, l;
    2.57 +		char *pp;
    2.58  
    2.59 -	p = hdr->header;
    2.60 -	q = tmp_hdr;
    2.61 +		for (pp=src+maxlen; pp>src; pp--) {
    2.62 +			if (*pp==' ' || *pp=='\t' || *p=='\n') {
    2.63 +				break;
    2.64 +			}
    2.65 +		}
    2.66 +			
    2.67 +		if (src == pp) {
    2.68 +			/* no potential break point was found within
    2.69 +			   maxlen so advance further until the next */
    2.70 +			for (pp=src+maxlen; *pp; pp++) {
    2.71 +				if (*pp==' ' || *pp=='\t' || *p=='\n') {
    2.72 +					break;
    2.73 +				}
    2.74 +			}
    2.75 +		}
    2.76 +		if (!*pp) {
    2.77 +			break;
    2.78 +		}
    2.79  
    2.80 -	if (p[len - 1] == '\n') {
    2.81 -		p[len - 1] = '\0';
    2.82 +		memcpy(dest, src, pp-src);
    2.83 +		dest += pp-src;
    2.84 +		*(dest++) = '\n';
    2.85 +		*(dest++) = '\t';
    2.86 +		while (*pp == ' ' || *pp == '\t' || *p=='\n') {
    2.87 +			pp++;
    2.88 +		}
    2.89 +		src = pp;
    2.90 +	}
    2.91 +	memcpy(dest, src, strlen(src));
    2.92 +	dest += strlen(src);
    2.93 +
    2.94 +	if (*(dest-1) != '\n') {
    2.95 +		*dest = '\n';
    2.96 +		*(dest+1) = '\0';
    2.97  	}
    2.98  
    2.99 -	while (*p) {
   2.100 -		gint i, l;
   2.101 -		gchar *pp;
   2.102 -
   2.103 -		/* look forward and find potential break points */
   2.104 -		i = 0;
   2.105 -		l = -1;
   2.106 -		pp = p;
   2.107 -		while (*pp && (i < MAX_HDR_LEN)) {
   2.108 -			if ((*pp == ' ') || (*pp == '\t')) {
   2.109 -				l = i;
   2.110 -			}
   2.111 -			pp++;
   2.112 -			i++;
   2.113 -		}
   2.114 -		if (!*pp) {
   2.115 -			l = pp - p;  /* take rest, if EOS found */
   2.116 -		}
   2.117 -
   2.118 -		if (l == -1) {
   2.119 -			/* no potential break point was found within
   2.120 -			   MAX_HDR_LEN so advance further until the next */
   2.121 -			while (*pp && *pp != ' ' && *pp != '\t') {
   2.122 -				pp++;
   2.123 -				i++;
   2.124 -			}
   2.125 -			l = i;
   2.126 -		}
   2.127 -
   2.128 -		/* copy */
   2.129 -		i = 0;
   2.130 -		while (i < l) {
   2.131 -			*(q++) = *(p++);
   2.132 -			i++;
   2.133 -		}
   2.134 -		*(q++) = '\n';
   2.135 -		*(q++) = *(p++);  /* this is either space, tab or 0 */
   2.136 -		/* *(q++) = '\t'; */
   2.137 -	}
   2.138 -
   2.139 -	g_free(hdr->header);
   2.140 -	hdr->header = tmp_hdr;
   2.141 +	hdr->header = tmp;
   2.142  	hdr->value = hdr->header + valueoffset;
   2.143  }
   2.144  
     3.1 --- a/src/masqmail.h	Thu Dec 09 17:50:25 2010 -0300
     3.2 +++ b/src/masqmail.h	Thu Dec 09 18:01:46 2010 -0300
     3.3 @@ -404,7 +404,7 @@
     3.4  gchar *rec_timestamp();
     3.5  GList *find_header(GList * hdr_list, header_id id, gchar * hdr_str);
     3.6  void header_unfold(header * hdr);
     3.7 -void header_fold(header * hdr);
     3.8 +void header_fold(header * hdr, unsigned int maxlen);
     3.9  header *create_header(header_id id, gchar * fmt, ...);
    3.10  void destroy_header(header * hdr);
    3.11  header *copy_header(header * hdr);