Return-Path: oskin
Delivery-Date: Wed Feb 24 11:35:06 1999
Return-Path: <cyrill@econ.krasnoyarsk.su>
Received: from relay.macomnet.ru
	by fetchmail-4.6.5 POP3
	for <oskin/localhost> (single-drop); Wed, 24 Feb 1999 11:35:06 MSK
Received: from relay1.krasnet.ru (relay1.krasnet.ru [193.125.44.91] (may be forged))
	by ns.macomnet.ru (8.9.1a/8.9.1) with ESMTP id LAA22710
	for <oskin@macomnet.ru>; Wed, 24 Feb 1999 11:31:29 +0300 (MSK)
Received: from post.krasnet.ru (post.krasnet.ru [193.125.44.81])
	by relay1.krasnet.ru (8.8.8/8.8.8) with ESMTP id PAA07948
	for <oskin@macomnet.ru>; Wed, 24 Feb 1999 15:30:00 -0700 (GMT)
Received: (from uucp@localhost)
	by post.krasnet.ru (8.8.8/8.8.8) with UUCP id PAA29202
	for oskin@macomnet.ru; Wed, 24 Feb 1999 15:29:17 +0700 (KRS)
Received: from ecnts2.intranet
	by ecfbsd2.intranet (8.9.1/8.9.1) with ESMTP id PAA09398
	for <oskin@macomnet.ru>; Wed, 24 Feb 1999 15:21:43 +0700 (KRS)
Received: by ecnts2.intranet with Internet Mail Service (5.5.1960.3)
	id <FL66X97Y>; Wed, 24 Feb 1999 15:26:07 +0700
Message-ID: <81A26FBBEB25D211BFA200A0C99CF0E80D46@ecnts2.intranet>
From: Феньев Кирилл Александрович <cyrill@econ.krasnoyarsk.su>
To: oskin@macomnet.ru
Subject: mkftnhdr.c
Date: Wed, 24 Feb 1999 15:26:05 +0700
MIME-Version: 1.0
X-Mailer: Internet Mail Service (5.5.1960.3)
Content-Type: text/plain;
	charset="KOI8-R"
Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from quoted-printable to 8bit by ecfbsd2.intranet id PAA09398
X-UIDL: 9ee4f841ae8ed2afea9cf2c49de12f28


 Здравствуйте,

 Имею наглость предложить свой патч к ifmail'у. :)
Смысл в декодировании заголовков вида '=?koi8-r?...?=',
порождаемых некоторыми mail/news клиентами.

 === Cut ===
--- mkftnhdr.c.orig	Tue Feb 16 20:00:06 1999
+++ mkftnhdr.c	Wed Feb 24 14:20:04 1999
@@ -30,6 +30,129 @@
 extern unsigned INT16 crc(char *);
 extern int flagset(char *);
 
+#ifdef DECODE_HEADERS
+void convert_header_7bit_to_8bit(char *s)
+{
+#define DECODE_HEX(x) (isdigit(x)!=0?((x)-48):(((x)&0xDF)-55))
+
+/* static const char BASE64_ALPHABET[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                     "abcdefghijklmnopqrstuvwxyz"
+                                     "0123456789+/"; */
+
+ static const char UNBASE64_ALPHABET[]={"\x3E\xFF\xFF\xFF\x3F"
+                                        "\x34\x35\x36\x37\x38"
+                                        "\x39\x3A\x3B\x3C\x3D"
+                                        "\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+                                        "\x00\x01\x02\x03\x04"
+                                        "\x05\x06\x07\x08\x09"
+                                        "\x0A\x0B\x0C\x0D\x0E"
+                                        "\x0F\x10\x11\x12\x13"
+                                        "\x14\x15\x16\x17\x18\x19"
+                                        "\xFF\xFF\xFF\xFF\xFF\xFF"
+                                        "\x1A\x1B\x1C\x1D\x1E"
+                                        "\x1F\x20\x21\x22\x23"
+                                        "\x24\x25\x26\x27\x28"
+                                        "\x29\x2A\x2B\x2C\x2D"
+                                        "\x2E\x2F\x30\x31\x32\x33"};
+ char *p=s, *p1;
+ char ts[10];
+ int i,j;
+
+ if ( strlen(s)<14 ) return;
+
+ strncpy(ts, s, 9); ts[9]=0; i=0;
+ while ( ts[i]!=0 )
+       {if ( ts[i]>64 && ts[i]<91 ) ts[i]|=0x20; i++;}
+
+ if ( strcmp(ts, "=?koi8-r?")!=0 ) return;
+
+ ts[0]=s[9]; s+=11;
+
+ if ( (ts[0]|0x20)=='q' )
+    {
+     /* decode quote-printable */
+
+     while ( (*s)!=0 && (*s)!='?' )
+           {
+            if ( ((*s)=='=' && s[1]!=0)
+                 &&
+                 (isxdigit(s[1])!=0 && isxdigit(s[2])!=0) )
+               {
+                (*p)=(DECODE_HEX(s[1])<<4)+DECODE_HEX(s[2]);
+                s+=2;
+               }
+            else
+               if ( (*s)=='_' )
+                  (*p)=' ';
+               else
+                  (*p)=(*s);
+
+            p++; s++;
+           }
+    }
+ else 
+ if ( (ts[0]|0x20)=='b' )
+    {
+     /* decode base64 */
+
+     union
+     {
+      char items[4];
+      INT32 all;
+     } base64_packet;
+     char unbase64_data[3];
+
+     i=j=0; base64_packet.all=0;
+     while ( (*s)!=0 && (*s)!='?' )
+           {
+            if ( (*s)>43 && (*s)<123 && UNBASE64_ALPHABET[(*s)-43]!=((char)-1) )
+               {
+                base64_packet.items[i]=UNBASE64_ALPHABET[(*s)-43];
+
+                if ( (*s)=='=' ) j++;
+
+                if ( i==3 )
+                   {
+                    unbase64_data[0]=(base64_packet.items[0]<<2)|
+                                     (base64_packet.items[1]>>4);
+                    unbase64_data[1]=(base64_packet.items[1]<<4)|
+                                     (base64_packet.items[2]>>2);
+                    unbase64_data[2]=(base64_packet.items[2]<<6)|
+                                     (base64_packet.items[3]);
+
+                    j=3-j;
+                    for (i=0;i<j;i++) {(*p)=unbase64_data[i]; p++;}
+
+                    i=j=0; base64_packet.all=0;
+                   }
+                else
+                   i++;
+               }
+            else
+               {
+                (*p)=(*s);
+                 p++;
+               }
+
+            s++;
+           }
+    }
+
+ if ( s[0]=='?' && s[1]=='=' )
+    {
+     if ( (p1=strchr(s+2, '='))!=NULL )
+        {
+         i=0;
+         do {(*p)=(*p1); p++; p1++; i++;} while ( (*(p-1))!=0 );
+
+         convert_header_7bit_to_8bit(p-i);
+        }
+     else
+        (*p)=0; /*if ( s[2]==0 ) (*p)=0;*/
+    }
+}
+#endif
+
 int ftnmsgid(msgid,s,n)
 char *msgid;
 char **s;
@@ -245,6 +368,10 @@
 		}
 	}
 	if (*freename == '\0') freename=rfcfrom;
+
+#ifdef DECODE_HEADERS
+    convert_header_7bit_to_8bit(freename);
+#endif
 
 	if (newsmode) debug(3,"FROM: %s <%s>",freename,rfcfrom);
 	else loginf("from: %s <%s>",freename,rfcfrom);
@@ -301,7 +428,12 @@
 	p=hdr("Subject",msg);
 	if (p)
 	{
-		while (isspace(*p)) p++;
+		while (isspace(*p)) p++;
+
+#ifdef DECODE_HEADERS
+    convert_header_7bit_to_8bit(p);
+#endif
+
 		tmsg->subj=xstrcpy(p);
 		if (*(p=tmsg->subj+strlen(tmsg->subj)-1) == '\n')
*p='\0';
 		if (strlen(tmsg->subj) > MAXSUBJ)
tmsg->subj[MAXSUBJ]='\0';
 === Cut ===

 Ну, и соответственно, в config добавить описание опции:

# define -DDECODE_HEADERS - convert '=?koi8-r?...?=' strings in headers
#                           of messages from Inet to plain text




                                                   Феньев Кирилл
