Hi, In message <_A3476@delegate-en.ML_> on 08/31/06(01:23:48) I wrote: |In message <_A3475@delegate-en.ML_> on 08/31/06(00:37:08) I wrote: | | |Delegate strips away all the spaces and sends then only 0E0D0A. | | |The client wait for 0D0A0E0D0A as EOF-mark, | | |so after 60 sec he has a timeout and disconnects the session. | | | |The problem is caused because DeleGate uses fgets() and fputs() to | |get and put the message on POP. | |A simple workaround to escape the problem is encoding '\0' into | |0xC0 0x80 (or \300\200, UTF-8 string which represents zero) at | |the input, and decoding it at the output. It can be done like the | |enclosed patch (a patch to be applied to DeleGate/9.2.4-pre19). | |Sorry, I found that the patch is not enough for POP, and encoding |a character into multi-bytes might cause another problem on the |buffer boundary. |So just ignoring '\0' might be the practical workaround as the |enclosed patch. I released 9.2.4-pre20 with the workaround. It simply ignores '\0' in a messege by default. You can test to relay '\0' as is with an option MIMECONV="zero:utf8" Cheers, Yutaka -- 9 9 Yutaka Sato <pfqcabdyi-mxhgu44gz33w.ml@delegate.org> http://delegate.org/y.sato/ ( ~ ) National Institute of Advanced Industrial Science and Technology _< >_ 1-1-4 Umezono, Tsukuba, Ibaraki, 305-8568 Japan Do the more with the less -- B. Fuller diff -cr delegate9.2.4-pre19/include/ystring.h delegate9.2.4-pre20/include/ystring.h *** delegate9.2.4-pre19/include/ystring.h Wed Aug 9 10:23:12 2006 --- delegate9.2.4-pre20/include/ystring.h Thu Aug 31 08:36:58 2006 *************** *** 228,233 **** --- 228,248 ---- int Xfprintf(FILE *fp,PCStr(fmt),...); #define fprintf Xfprintf + extern int FGSZ_flags; + #define FGSZ_ISSET 1 + #define FGSZ_NONE 2 + #define FGSZ_KILL 4 + #define FGSZ_UTF8 8 + + #ifdef DOFGSZ + #undef fgets + #undef fputs + const char *fgetsZ(PVStr(str),int siz,FILE *fp); + int fputsZ(PCStr(str),FILE *fp); + #define fgets(s,z,f) fgetsZ(AVStr(s),z,f) + #define fputs(s,f) fputsZ(s,f) + #endif + /* #ifdef __cplusplus class CString { diff -cr delegate9.2.4-pre19/mimekit/mime.c delegate9.2.4-pre20/mimekit/mime.c *** delegate9.2.4-pre19/mimekit/mime.c Wed Aug 23 17:46:50 2006 --- delegate9.2.4-pre20/mimekit/mime.c Thu Aug 31 09:41:58 2006 *************** *** 19,24 **** --- 19,25 ---- 950312 encode/decode parts in a multipart message //////////////////////////////////////////////////////////////////////#*/ + #define DOFGSZ #include "mime.h" #ifdef MIMEKIT #define strid_alloc(s) stralloc(s) *************** *** 157,162 **** --- 158,173 ---- MIME_CONV &= ~C_ENCODE(C_HEAD_SPENC); else if( streq(spec,"charcode") ) MIME_CONV = C_DECODE(C_CHAR)|C_ENCODE(C_CHAR); + else + if( streq(spec,"zero:none") ){ + FGSZ_flags = FGSZ_NONE; + }else + if( streq(spec,"zero:utf8") ){ + FGSZ_flags = FGSZ_UTF8; + }else + if( streq(spec,"zero:kill") ){ + FGSZ_flags = FGSZ_KILL; + } else syslog_ERROR("#### ERROR: unknown MIMECONV=%s\n",spec); return 0; } *************** *** 598,604 **** --- 609,618 ---- } skipping = 0; + /* wordscanY(hp,AVStr(cur_field),sizeof(cur_field),"^: \t\r\n"); + */ + wordscanY(hp,AVStr(cur_field),sizeof(cur_field),"^: \300\t\r\n"); conv_field = strncasecmp(hp,"Subject:",8) == 0 || strncasecmp(hp,"From:",5) == 0; *************** *** 910,916 **** --- 924,936 ---- if( tmpa == NULL ) return -1; if( leng == 0 ) + { + if( out_thru && rcode != MP_EOR ){ + /* it is put already */ + truncVStr(endline); + } goto EXIT; + } /* guess the end-of-line character(string) of the message ... */ if( beol = strpbrk(tmpa,"\r\n") ){ diff -cr delegate9.2.4-pre19/mimekit/rfc822.c delegate9.2.4-pre20/mimekit/rfc822.c *** delegate9.2.4-pre19/mimekit/rfc822.c Thu May 4 03:11:12 2006 --- delegate9.2.4-pre20/mimekit/rfc822.c Thu Aug 31 08:23:54 2006 *************** *** 19,24 **** --- 19,25 ---- 950312 encode/decode parts in a multipart message 951029 extracted from mime.c of DeleGate //////////////////////////////////////////////////////////////////////#*/ + #define DOFGSZ #include "mime.h" char *nextField(PCStr(field),int ignEOH); void RFC822_strip_lwsp(PCStr(src),PVStr(dst),int size); diff -cr delegate9.2.4-pre19/rary/String.c delegate9.2.4-pre20/rary/String.c *** delegate9.2.4-pre19/rary/String.c Wed Aug 9 22:52:47 2006 --- delegate9.2.4-pre20/rary/String.c Thu Aug 31 09:23:58 2006 *************** *** 2280,2282 **** --- 2280,2329 ---- ((char*)str)[len0-i] = ch; /**/ } } + + /* represent zero in UTF-8 {0xC0 0x80} without string terminator '\0' */ + int FGSZ_flags = FGSZ_KILL; + const char *fgetsZ(PVStr(str),int siz,FILE *fp){ + int ch; + refQStr(sp,str); + const char *sx; + + sx = &str[siz-2]; + for( sp = str; sp < sx; ){ + ch = getc(fp); + if( ch == EOF ) + break; + if( ch == 0 ){ + if( FGSZ_flags & FGSZ_KILL ){ + }else + if( FGSZ_flags & FGSZ_UTF8 ){ + setVStrPtrInc(sp,0xC0); + setVStrPtrInc(sp,0x80); + }else{ + setVStrPtrInc(sp,ch); + } + }else{ + setVStrPtrInc(sp,ch); + if( ch == '\n' ) + break; + } + } + setVStrEnd(sp,0); + if( sp == str && feof(fp) ) + return NULL; + return str; + } + int fputsZ(PCStr(str),FILE *fp){ + const unsigned char *sp; + unsigned char ch; + + for( sp = (const unsigned char*)str; ch = *sp; sp++ ){ + if( (FGSZ_flags & FGSZ_UTF8) && ch == 0xC0 && sp[1] == 0x80 ){ + putc(0,fp); + sp++; + }else{ + putc(ch,fp); + } + } + return 0; + }