static char rcsid[] = "@(#)$Id: id_phrase.c,v 1.11 2006/07/01 07:37:48 hurtta Exp $"; /****************************************************************************** * The Elm (ME+) Mail System - $Revision: 1.11 $ $State: Exp $ * * Author: Kari Hurtta (was hurtta+elm@ozone.FMI.FI) *****************************************************************************/ #include "headers.h" DEBUG_VAR(Debug,__FILE__,"header"); static unsigned char *s2us P_((char *str)); static unsigned char *s2us(str) char *str; { return (unsigned char *)str; } void zero_id_phrase(P) struct id_phrase *P; { P->id = NULL; P->text = NULL; } void free_id_phrase(P) struct id_phrase *P; { if (P->id) free(P->id); P->id = NULL; if (P->text) free_string(&(P->text)); } int check_8bit_id_phrase(P) struct id_phrase *P; { if (P->id && check_8bit_str(P->id)) return TRUE; if (P->text && !can_ascii_string(P->text)) return TRUE; return FALSE; } int check_8bit_string(P) struct string *P; { if (!P) return FALSE; if (!can_ascii_string(P)) return TRUE; return FALSE; } int check_8bit_str (str) char *str; { char *s; for (s = str; *s; s++) if (*s & 0x80) return HAVE_8BIT; return 0; } static void do_simple_wrapping1 P_((out_state_t *mailer, long *pos, char *s, int top_encoding, int lim)); static void do_simple_wrapping1(mailer, pos, s, top_encoding,lim) out_state_t *mailer; long *pos; char *s; int top_encoding; int lim; { long POS = *pos; char *c; char *d; #define LEN (out_state_ftell(mailer)-POS) #define WRAP print_EOLN(mailer,top_encoding), \ (POS = out_state_ftell(mailer)), state_putc(' ',mailer) for (c = s; *c != '\0'; c=d) { if (*c == '\n' || (whitespace(*c) && (LEN > lim-5))) { WRAP; DPRINT(Debug,9,(&Debug,"[WRAP]\n ")); c++; d = c; } else if (whitespace(*c)) { int len; char *e; for (d = c+1; '\0' != *d; d++) { if (*d == '\n' || whitespace(*d)) break; } len = d-c; if (len + LEN > lim-2 && LEN > 0) { WRAP; DPRINT(Debug,9,(&Debug,"[WRAP > %d]\n ",lim-2)); /* replace space with folding */ c++; } for (e = c; e < d; e++) { state_putc(*e,mailer); DPRINT(Debug,9,(&Debug,"%c",*e)); } } else { state_putc(*c,mailer); DPRINT(Debug,9,(&Debug,"%c",*c)); c++; d = c; } } *pos = POS; } static void do_simple_wrapping P_((out_state_t *mailer, long *pos, char *s, int top_encoding)); static void do_simple_wrapping(mailer, pos, s, top_encoding) out_state_t *mailer; long *pos; char *s; int top_encoding; { do_simple_wrapping1(mailer,pos,s,top_encoding,79); } void write_id_phrase_header (mailer,hdr_name,P, top_encoding, enmime, hdr_charset) out_state_t *mailer; CONST char *hdr_name; struct id_phrase * P; int top_encoding; int enmime; charset_t hdr_charset; { long POS = out_state_ftell(mailer); char *c; if (!P -> id && !P -> text) { DPRINT(Debug,9, (&Debug,"write_id_phrase_header: (%s) -- NONE\n", hdr_name)); return; } state_puts(hdr_name,mailer); state_puts(": ",mailer); DPRINT(Debug,9,(&Debug, "write_id_phrase_header: (enmime=%d) %s: \n", enmime,hdr_name)); DPRINT(Debug,9,(&Debug, "write_id_phrase_header: %s:",hdr_name)); if (P->id) { state_puts(P->id,mailer); DPRINT(Debug,9,(&Debug, "%s",P->id)); } if (P->text) { int X = 0; if (string_len(P->text) && 0x0020 == give_unicode_from_string(P->text,0)) { if ((LEN > 60)) { WRAP; DPRINT(Debug,9,(&Debug, "[WRAP]\n ")); } else { state_putc(' ',mailer); DPRINT(Debug,9,(&Debug," ")); } X = 1; } while (string_len(P->text) > X) { int x = X; struct string * temp = clip_from_string(P->text,&X,900); char * s = string_to_hdr(HDR_PHRASE,temp, hdr_charset,enmime,NULL); DPRINT(Debug,9,(&Debug,"{phrase quoted=%s}\n",s)); DPRINT(Debug,9,(&Debug,"\n [%d..%d] ",x,X)); do_simple_wrapping(mailer,&POS,s, top_encoding); free(s); free_string(&temp); } } print_EOLN(mailer,top_encoding); DPRINT(Debug,9,(&Debug,"[EOLN]\n")); } void write_string_header (mailer,hdr_name,P, top_encoding, enmime, hdr_charset) out_state_t *mailer; CONST char *hdr_name; struct string * P; int top_encoding; int enmime; charset_t hdr_charset; { long POS = out_state_ftell(mailer); char *c; int X = 0; uint16 was_delim = 0; state_puts(hdr_name,mailer); state_puts(": ",mailer); DPRINT(Debug,9, (&Debug, "write_string_header: (enmime=%d) %s: \n", enmime,hdr_name)); DPRINT(Debug,9, (&Debug, "write_string_header: %s:",hdr_name)); while (string_len(P) > X) { int x = X; if (x > 0) { WRAP; DPRINT(Debug,9,(&Debug, "[WRAP]\n ")); } if (long_encoded_headers) { int slen = LEN; struct string * temp = NULL; char *s; int was_encoded = 0; while (string_len(P) > X) { int new_x = X; struct string *word = NULL; int len1; uint16 delim = 0; len1 = get_word_from_string(P,&word,&new_x,0,s2us(" "),&delim); if (len1 < 1) { /* This handles case where there is no conversion to unicode available */ DPRINT(Debug,9, (&Debug, " <>",new_x)); free_string(&word); break; } if (slen + len1 > 70) { free_string(&word); break; } /* Caching delim causes effectively that it is not stored on encoded -> non-encoded transition -- that avoid double space after decoding */ if (was_delim) { if (!temp) temp = new_string(P->string_type); add_unicode_to_string(temp,1,&was_delim); was_delim = 0; } append_string(&temp,word); free_string(&word); slen += len1; /* Includes delim */ was_delim = delim; X = new_x; } if (!temp) { X = x; goto failure; } s = string_to_hdr(HDR_TEXT,temp, hdr_charset,enmime,&was_encoded); DPRINT(Debug,9, (&Debug,"{text encoded=%s}\n",s)); DPRINT(Debug,9, (&Debug,"\n [%d..%d] ",x,X)); /* Hack -- remove extra space (if not encoded) also from raw output */ if (' ' == *s) do_simple_wrapping1(mailer,&POS,s+1,top_encoding,900); else do_simple_wrapping1(mailer,&POS,s,top_encoding,900); /* Remove extra space if just not encoded result */ if (!was_encoded) was_delim = 0; free(s); free_string(&temp); } else { struct string * temp; char * s; failure: temp = clip_from_string(P,&X,900); s = string_to_hdr(HDR_TEXT,temp, hdr_charset,enmime,NULL); DPRINT(Debug,9, (&Debug,"{text encoded=%s}\n",s)); DPRINT(Debug,9, (&Debug,"\n [%d..%d] ",x,X)); do_simple_wrapping(mailer,&POS,s, top_encoding); free(s); free_string(&temp); } } print_EOLN(mailer,top_encoding); DPRINT(Debug,9, (&Debug,"[EOLN]\n")); } #undef LEN #undef WRAP /* * Local Variables: * mode:c * c-basic-offset:4 * buffer-file-coding-system: iso-8859-1 * End: */