From: Феньев Кирилл Александрович <cyrill@econ.krasnoyarsk.su>
To: "'oskin@macomnet.ru'" <oskin@macomnet.ru>
Subject: new decode_headers
Date: Fri, 9 Jul 1999 12:54:26 +0800


   Привет,

   Хочу поправить свой патч декодирующий строчки
 '=?koi8-r?...?=' в заголовках. Ошибка вкралась как
 обычно, глупая и малозаметная. :)
   Положи пожалуйста вместо того, что лежит сейчас на
 ftp://oskin.macomnet.ru/pub/linux/fido/.

WBR,
Cyrill

P.S. Этот вариант для os-p7.

 === Cut ===
--- mkftnhdr.c.os-p7	Fri Jul  9 11:58:32 1999
+++ mkftnhdr.c.os-p7+	Fri Jul  9 12:25:11 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)>42 && (*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;
@@ -254,6 +377,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);
 
@@ -310,6 +437,11 @@
 	if (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 ===


